feat: implement PI core chat timeline
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
# Task: Implement PI-120 core chat and first-conversation UX
|
||||
|
||||
## Identity
|
||||
|
||||
- Task ID: 20260823-pi-chat-timeline-c8f31a62
|
||||
- Mode: Feature
|
||||
- Branch: codex/20260823-pi-chat-timeline-c8f31a62-pi-chat-timeline
|
||||
- Worktree: D:\Datas\OthersProjects\makelore-pi-chat-timeline-c8f31a62
|
||||
- Base commit: 54d8bb2e4a6f1a7dd857827659e60d1b4a1fb6f5
|
||||
- Owner: codex-root
|
||||
- Status: In Progress
|
||||
|
||||
## Scope
|
||||
|
||||
- Implement `PI-120 — Core Chat and first-Conversation UX` on cumulative
|
||||
PI-110 delivery HEAD `54d8bb2`.
|
||||
- Add a vendor-neutral `CodingChatPanel` composition, first-Conversation
|
||||
metadata selection/creation, core Composer, and memoized timeline renderers
|
||||
for message/thinking/tool/compaction/boundary nodes.
|
||||
- Bind the page exclusively to `/api/coding/*` Renderer facades and the
|
||||
PI-110 Conversation store, including optimistic prompt acceptance,
|
||||
preparing/queued/running/error/recovery states, draft continuity, and
|
||||
hidden-Conversation render isolation.
|
||||
- Add focused component/performance coverage and the first-prompt Electron E2E.
|
||||
Do not implement PI-130 feature-complete controls or PI-140 legacy removal.
|
||||
|
||||
## Intent And Constraints
|
||||
|
||||
- The exact Ready Frontier is `{PI-120}`. PI-110 is Done at audit HEAD
|
||||
`934ba02` and cumulative delivery HEAD `54d8bb2`; PI-130 remains locked until
|
||||
this ticket is accepted.
|
||||
- Textarea editability depends only on an active project, an enabled Agent,
|
||||
and the absence of a project destruction/migration transition. It never
|
||||
depends on worker/runtime/metadata loading, provider latency, diagnostics,
|
||||
another Conversation, or the current Conversation run state.
|
||||
- Conversation creation is local metadata only. Snapshot/prewarm is lazy and
|
||||
Conversation-scoped; preparation beyond ten seconds becomes a recoverable
|
||||
error while the draft stays editable.
|
||||
- A send immediately creates one stable optimistic user node. HTTP 202 is only
|
||||
acceptance; later provider/tool failure never removes the accepted user
|
||||
message, and uncertain delivery is never silently resent.
|
||||
- Renderer components must use granular PI-110 selectors and memoized blocks.
|
||||
Hidden Conversation streaming cannot rerender the selected timeline;
|
||||
cumulative tool output replaces rather than appends duplicate content.
|
||||
- Do not read `src/stores/opencode.ts`, call `/api/opencode`, import Pi/OpenCode
|
||||
wire types, or mechanically rename the legacy 4k-line panel. The old panel
|
||||
remains only as PI-140 removal residue after the new page composition takes
|
||||
ownership.
|
||||
- PI-130 still owns model/thinking controls, steer/follow-up queue controls,
|
||||
compaction/retry/context actions, interactions, subagent graph, changes/files/
|
||||
browser/skills/commands, and Conversation archive/fork/title/unread UI.
|
||||
- The planner amended the attachment contract: `POST /api/coding/attachments`
|
||||
accepts one bounded image binary and returns only `{attachmentId,mime,byteLength}`;
|
||||
authenticated `GET /api/coding/attachments/:id/content` returns raw bytes.
|
||||
Upload happens only on Send, each local variant has one in-flight/result, and
|
||||
Renderer state/protocol keep references rather than base64.
|
||||
- The planner selected public `patch-batch` delivery only. Main retains private
|
||||
single-patch envelopes and original seq, batches per Conversation/generation
|
||||
for 16–33 ms with bounded early flush, and cancels an old generation's pending
|
||||
batch. Renderer validates the full batch and folds it in one Zustand
|
||||
transaction; malformed/gapped batches recover only their target.
|
||||
- Real Provider remains Explicitly Waived / Accepted Risk with
|
||||
`realTurnVerified=false`. macOS x64/arm64 remains deferred to mandatory
|
||||
PI-150. Neither is Pass evidence. No subagents are authorized.
|
||||
|
||||
## Project Context Loaded
|
||||
|
||||
- Task identity: `20260823-pi-chat-timeline-c8f31a62`, feature mode, isolated
|
||||
branch/worktree above, exact base
|
||||
`54d8bb2e4a6f1a7dd857827659e60d1b4a1fb6f5`.
|
||||
- Concurrent Task Gate passed. The only semantically adjacent planning task,
|
||||
`20260820-partner-create-model-parity-c83d`, still has undefined scope and no
|
||||
claimed files. The canonical main integration task is Blocked and is not a
|
||||
write target; all other planning owners are unrelated Canvas/Robot/Learning
|
||||
or read-only scopes.
|
||||
- Planning Gate inputs read: memory index, active task record, project
|
||||
positioning/current state/decision/system/architecture/domain documents,
|
||||
PI-100/105/110 completion records, exact PI-120 ticket and PI-130 boundary,
|
||||
and relevant `UX-*`, `REN-*`, API, performance and recovery Spec sections.
|
||||
- Canonical positioning and project-level success fields are placeholders and
|
||||
the integrated memory still describes the legacy OpenCode UI. Repository
|
||||
guidance plus the planner-owned Pi Spec/tickets and reviewed cumulative code
|
||||
are authoritative for this feature branch.
|
||||
- Confirmed seams: schema-v2 project/config/Conversation routes already provide
|
||||
local-only metadata; PI-110 provides the typed Snapshot/prompt/SSE facade,
|
||||
shared reducer, per-Conversation store, optimistic identity, target-only
|
||||
recovery, and granular selectors. The current Chat page still imports the
|
||||
legacy `OpencodeChatPanel` and is the cutover seam.
|
||||
- No accepted ADR conflicts with this ticket. The attachment transport gap is
|
||||
recorded above and has been escalated to the planner instead of silently
|
||||
inventing a route.
|
||||
- Gate result: Passed.
|
||||
|
||||
## Plan
|
||||
|
||||
1. Add the minimal vendor-neutral project/config/Conversation Renderer facade
|
||||
and metadata store needed to load the active project, enabled Agents and
|
||||
Conversations without touching the legacy OpenCode store.
|
||||
2. Build a small `CodingChatPanel` composition and switch the Chat page to it;
|
||||
make first-Conversation selection/creation local-only and keep Textarea
|
||||
readiness independent of snapshot/runtime preparation.
|
||||
3. Implement focused Composer submission/recovery UI over the PI-110 draft and
|
||||
optimistic request lifecycle, including preparing/queued/running/error
|
||||
status without a page-wide loading gate.
|
||||
4. Implement memoized/windowed message, thinking, tool, compaction and boundary
|
||||
blocks that update only the selected target and keep large/cumulative output
|
||||
bounded; apply the planner's attachment ruling without expanding PI-130.
|
||||
5. Add red-capable first-Conversation, core Chat, optimistic failure,
|
||||
hidden-Conversation/render-count and 100 KB performance fixtures, plus the
|
||||
first-prompt Electron E2E; then run focused/full validation, build,
|
||||
documentation gates and planner review.
|
||||
|
||||
## Outcome
|
||||
|
||||
- Replaced the Chat page composition with a vendor-neutral `CodingChatPanel`
|
||||
backed only by `/api/coding/*` facades. It loads active project/config/local
|
||||
Conversation metadata, auto-creates the first local Conversation, and keeps
|
||||
the Composer editable while runtime Snapshot preparation is held.
|
||||
- Added text/image Composer behavior, stable optimistic user nodes, distinct
|
||||
preparing/accepted/running/uncertain/error/recovery feedback, Enter/Shift+Enter
|
||||
and IME handling, Send-time single-flight image upload, and authenticated
|
||||
object-URL previews without base64 state or protocol payloads.
|
||||
- Added a memoized/windowed timeline for message, Markdown, thinking, tool,
|
||||
compaction, boundary and notice nodes. Hidden Conversation batches leave the
|
||||
selected timeline selector stable; cumulative tool output is replaced rather
|
||||
than duplicated.
|
||||
- Added Main-owned attachment binary routes/IPC transport and public Snapshot +
|
||||
`patch-batch` SSE delivery. Main batches at 24 ms by default with item/byte
|
||||
early-flush bounds; Renderer atomically rejects malformed/gapped batches,
|
||||
buffers during target recovery, trims Snapshot-covered items and replays only
|
||||
a strict continuous tail.
|
||||
- Fixed a supported concurrency defect exposed by the full suite: the Pi
|
||||
Session Registry now reuses one Conversation store per project, serializing
|
||||
simultaneous first bindings instead of racing writes to the same metadata
|
||||
file.
|
||||
- Synchronized `README.md` with the current Pi core Chat, first-Conversation,
|
||||
batch and attachment behavior. PI-130 feature controls and PI-140 legacy
|
||||
removal remain outside this task.
|
||||
|
||||
## Verification
|
||||
|
||||
- `pnpm exec vitest run tests/unit/coding-workspace-store.test.ts tests/unit/coding-projects-facade.test.ts tests/unit/coding-attachments-facade.test.ts tests/unit/coding-attachments-routes.test.ts tests/unit/coding-chat-panel.test.tsx tests/unit/coding-conversation-timeline.test.tsx tests/unit/coding-conversations-store.test.tsx tests/unit/coding-core-routes.test.ts tests/unit/host-api.test.ts tests/unit/host-api-proxy.test.ts`: passed, 10 files / 68 tests before the final malformed-batch and Session Registry regression additions.
|
||||
- `pnpm exec vitest run tests/unit/pi-session-registry.test.ts tests/unit/pi-conversation-runtime.test.ts tests/unit/coding-conversations-store.test.tsx tests/unit/coding-chat-panel.test.tsx`: passed, 4 files / 25 tests.
|
||||
- `pnpm test`: passed, 217 files / 2303 passed / 2 skipped. The final run is green after fixing the same-project parallel Session Registry write race and stabilizing the AI Hardware async query at its actual loading boundary.
|
||||
- `pnpm run typecheck`: passed.
|
||||
- `pnpm run lint:check`: passed with 0 errors and six unchanged warnings in `ExecutionGraphCard`, `Home`, and `Makelore`.
|
||||
- `pnpm run build:vite`: passed; existing Vite dynamic-import and chunk-size warnings remain.
|
||||
- `pnpm exec playwright test tests/e2e/pi-coding-first-chat.spec.ts`: passed, 1/1.
|
||||
- `pnpm exec playwright test tests/e2e/pi-coding-first-chat.spec.ts --repeat-each=20 --workers=1`: passed, 20/20 fresh-userData runs. Every sample asserted Composer editability below 500 ms while runtime Snapshot was held, so the measured sample p95 is below the locked 500 ms budget; the same fixture verifies optimistic prompt visibility and HTTP 202 acceptance without a real Provider.
|
||||
- `git diff --check`: passed; only repository line-ending conversion notices were printed.
|
||||
- Real Provider remains **Explicitly Waived / Accepted Risk** with
|
||||
`realTurnVerified=false`; no Provider Account, credential isolation,
|
||||
protocol-specific endpoint, rate-limit or real concurrency behavior is
|
||||
claimed as Pass.
|
||||
- macOS x64/arm64 execution remains user-deferred to mandatory `PI-150`; no
|
||||
macOS Pass is claimed.
|
||||
|
||||
## Follow-ups
|
||||
|
||||
- PI-130 owns Conversation model/thinking controls, steer/follow-up queue,
|
||||
compaction/retry/context controls, interactions, subagents, changes/files,
|
||||
browser, skills/commands, and archive/fork/title/unread UI.
|
||||
- PI-140 owns removal of legacy OpenCode runtime/routes/dependencies/UI/tests
|
||||
and migration notice.
|
||||
- PI-150 must run final packaged cross-platform proof, including the deferred
|
||||
macOS x64/arm64 matrix. Real Provider qualification remains explicitly waived
|
||||
unless the user changes that decision.
|
||||
|
||||
## Promotion Candidates
|
||||
|
||||
- Preserve the public Snapshot + `patch-batch` hard-cut contract and the
|
||||
target-only recovery semantics in the planner-owned Pi Spec/tickets after
|
||||
implementation review.
|
||||
- Preserve the explicit attachment upload/read Host contract, Send-time
|
||||
single-flight rule, and reference-only Renderer state in the planner-owned
|
||||
Pi Spec/tickets after implementation review.
|
||||
Reference in New Issue
Block a user