feat(chat,board): historicalToUnified + scripted-stream replay + standalone TicketCardView#1460
Conversation
…edChatMessage[] helper [preview:none]
…rdView - scripted-stream: buildStreamFrames + useScriptedStream (mock-SSE replay of a HistoricalMessage[], moved out of the hub so any consumer can drive a previewMode chat from a canned conversation) - extract TicketCardBody + TicketCardView (the real board ticket-card design, standalone, no useSortable/dnd) so it renders from static props off-board [preview:none]
📝 WalkthroughWalkthroughAdds deterministic scripted chat playback and historical-message conversion helpers, and refactors board ticket cards into reusable body and static-view components while preserving draggable behavior and adapting approval callbacks. ChangesChat playback and historical conversion
Ticket card composition
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant HistoricalMessage
participant buildStreamFrames
participant useScriptedStream
participant ChatSurface
HistoricalMessage->>buildStreamFrames: historical messages
buildStreamFrames->>useScriptedStream: StreamFrame array
useScriptedStream->>ChatSurface: current frame after delayMs
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
openframe-frontend-core/src/components/chat/utils/scripted-stream.ts (1)
63-111: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd unit tests for
buildStreamFrames.This pure function has several branches (user vs. assistant turns, thinking-pause gating, per-token streaming, tool/approval segment pop-in, empty-message fallback) and an explicitly documented invariant (frame-count determinism for a stable prefix) that's easy to regress silently. Worth covering with deterministic unit tests, especially the tokenize-reconstruction and prefix-stability guarantees.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@openframe-frontend-core/src/components/chat/utils/scripted-stream.ts` around lines 63 - 111, Add deterministic unit tests covering buildStreamFrames for user and assistant turns, thinking-pause gating, per-token text streaming with tokenize reconstruction, tool/approval segment pop-in, and the empty-message fallback. Include assertions for frame-count determinism when extending a stable message prefix, and verify each frame’s messages, phase, typing, and delayMs values without changing the implementation.openframe-frontend-core/src/components/features/board/ticket-card.tsx (1)
50-51: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
showNewMessagecomputation is duplicated across three components.The same
!!ticket.hasNewMessage && !!columnColorexpression is recomputed independently here, inTicketCardView(Line 148), and inTicketCard(Line 191). Extracting a small shared helper would prevent future drift if the condition ever changes.♻️ Suggested helper extraction
+function shouldShowNewMessage(ticket: BoardTicket, columnColor?: string): boolean { + return !!ticket.hasNewMessage && !!columnColor +} + export function TicketCardBody({ ticket, columnColor, renderAssignSlot, onApprove, onReject }: TicketCardBodyProps) { - const showNewMessage = !!ticket.hasNewMessage && !!columnColor + const showNewMessage = shouldShowNewMessage(ticket, columnColor)Apply the same replacement at Line 148 (
TicketCardView) and Line 191 (TicketCard).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@openframe-frontend-core/src/components/features/board/ticket-card.tsx` around lines 50 - 51, Extract the shared showNewMessage condition into a small helper and replace the duplicated expressions in the current component plus TicketCardView and TicketCard. Ensure all three call sites use the helper while preserving the existing boolean behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@openframe-frontend-core/src/components/chat/utils/scripted-stream.ts`:
- Around line 63-111: Add deterministic unit tests covering buildStreamFrames
for user and assistant turns, thinking-pause gating, per-token text streaming
with tokenize reconstruction, tool/approval segment pop-in, and the
empty-message fallback. Include assertions for frame-count determinism when
extending a stable message prefix, and verify each frame’s messages, phase,
typing, and delayMs values without changing the implementation.
In `@openframe-frontend-core/src/components/features/board/ticket-card.tsx`:
- Around line 50-51: Extract the shared showNewMessage condition into a small
helper and replace the duplicated expressions in the current component plus
TicketCardView and TicketCard. Ensure all three call sites use the helper while
preserving the existing boolean behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: f2fc5d9d-42c8-4246-a74e-bce97a50a89c
📒 Files selected for processing (7)
openframe-frontend-core/src/components/chat/hooks/index.tsopenframe-frontend-core/src/components/chat/hooks/use-nats-chat-adapter.tsopenframe-frontend-core/src/components/chat/hooks/use-scripted-stream.tsopenframe-frontend-core/src/components/chat/utils/index.tsopenframe-frontend-core/src/components/chat/utils/scripted-stream.tsopenframe-frontend-core/src/components/features/board/index.tsopenframe-frontend-core/src/components/features/board/ticket-card.tsx
What
Lib primitives backing the multi-platform-hub hero agent demos (hub #848), extracted so the hub carries no duplicated chat/ticket logic. (Supersedes the changes that were on the already-merged #1459 branch — this is a fresh PR off current
main.)Changes
historicalToUnified(use-nats-chat-adapter.ts) — one-callHistoricalMessage[]→UnifiedChatMessage[](rehydrate + unified-map + identity re-attach), so a host replaying a stored conversation doesn't hand-roll the two-step.utils/scripted-stream.ts+hooks/use-scripted-stream.ts) —buildStreamFramesturns aHistoricalMessage[]into mock-SSE playback frames (thinking → token-by-token → tool/approval → idle);useScriptedStreamis the playback clock. Moved out of the hub so any consumer (marketing heroes, docs, tours) can drive apreviewModechat from a canned conversation.TicketCardView/TicketCardBody(board/ticket-card.tsx) — extracted the real board ticket-card design into a presentational component with nouseSortable/dnd dependency, so/tickets?viewMode=board's exact card renders standalone from static props (off-board embeds, hero mocks).TicketCard(draggable) now composesTicketCardBody; behavior unchanged.Notes
TicketCard's public API and rendering are unchanged.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Improvements