Files
makelore/.project-docs/30-worklog/tasks/20260823-pi-chat-timeline-c8f31a62.md
T

11 KiB
Raw Blame History

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: 54d8bb2e4a
  • 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.