feat: conversation view v2 — structured chat transcript with TUI styling - #53
Conversation
| } | ||
|
|
||
| // ── Main conversation view ─────────────────────────────────────────────────── | ||
|
|
There was a problem hiding this comment.
🟡 Warning
Problem: Hardcoded white text color rgba(255,255,255,0.92) is invisible in the daylight theme. Same issue with the rgba(255,255,255,0.22) background — a white overlay on a light background produces no visible contrast.
Why it matters: Any user on the daylight theme sees a blank user turn — the prompt text disappears entirely.
Suggested fix:
function UserTurn({ turn }: { turn: Turn }) {
const theme = useStore((s) => s.theme);
const page = THEMES[theme].page;
const green = THEMES[theme].terminal.green;
// Use theme-aware background and text color instead of hardcoded white
const userTurnBg = theme === "daylight" ? "rgba(0,0,0,0.06)" : "rgba(255,255,255,0.22)";
const userTextColor = page.fg;
...
return (
<div className="-mx-4 px-4 py-0.5" style={{ background: userTurnBg }}>
...
<span ... style={{ color: userTextColor, fontFamily: "..." }}>| for (const dir of dirs) { | ||
| const jsonlPath = join(projectsDir, dir, `${sessionId}.jsonl`); | ||
| try { | ||
| readFileSync(jsonlPath, { flag: "r" }); |
There was a problem hiding this comment.
🟢 Suggestion
Problem: readFileSync(jsonlPath, { flag: "r" }) reads the entire file just to check whether it exists. For a large session JSONL, this is wasteful — it reads potentially megabytes of data into memory and immediately discards it, once per project directory.
Why it matters: On a machine with many Claude projects and large sessions, this existence probe can be visibly slow. The file then gets read again a few lines later.
Suggested fix:
import { existsSync, readdirSync, readFileSync } from "node:fs";
// Replace the inner try/catch probe:
if (existsSync(jsonlPath)) {
return jsonlPath;
}
nox-0x
left a comment
There was a problem hiding this comment.
Clean implementation — ClaudeCodeParser is well-structured, the tool pairing logic is solid, and the ANSI renderer is a nice touch. Two issues flagged: UserTurn hardcodes white text/background colors that disappear in the daylight theme, and findSessionFile uses readFileSync as an existence probe (wasteful). Neither blocks the dark-theme path where this will primarily be used.
Adds a conversation view toggle (terminal ↔ conversation) to the dashboard. Reads Claude Code JSONL session files and renders them as a readable chat UI. - packages/core: ClaudeCodeParser, RenderItem/Turn types, SessionParser interface - packages/server: /api/conversation/:sessionId endpoint - packages/dashboard: ConversationView with markdown, syntax highlighting, diffs - Tool calls as collapsible blocks with input/output - Edit tool diffs rendered inline (red/green) - Thinking blocks collapsible - Compaction events rendered as a divider with token count - Auto-scroll to bottom on session switch
…tion view - Render ANSI escape codes in assistant messages with proper color mapping - Mark API/auth error messages (isApiErrorMessage) with red text styling - Filter out "No response requested." noise from assistant text blocks - Add isError field to TextItem type and propagate from parser - User turn: highlight background tint + Berkeley Mono font preference - Sidechain blocks: stronger border opacity + subtle background tint - Tighten prose-tui line-height and paragraph margins - Increase space-y between turns from 2 → 4 for readability Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
49a2fe3 to
da5984c
Compare
| @@ -1,6 +1,9 @@ | |||
| export * from "./parsers/claude-code"; | |||
| export * from "./parsers/claude-code"; | |||
There was a problem hiding this comment.
🔴 Critical
Problem: Three duplicate export * lines were added — ./parsers/claude-code, ./types/parser, and ./types/render are each exported twice from this barrel file.
Why it matters: TypeScript will emit TS2300: Duplicate identifier errors for every re-exported name (e.g. TextItem, ToolCallItem, ParsedSession, etc.). The package will fail to compile entirely.
Suggested fix:
// Keep exactly one copy of each line — remove the three `+` lines that duplicate existing exports:
export * from "./parsers/claude-code";
export * from "./types/events";
export * from "./types/parser";
export * from "./types/provider";
export * from "./types/render";
export * from "./types/session";
nox-0x
left a comment
There was a problem hiding this comment.
Three duplicate export * lines in packages/core/src/index.ts will cause TS2300: Duplicate identifier compile errors across the entire package — the build will fail before any of the conversation view features are reachable. Quick fix: drop lines 2, 5, and 8 (the three added duplicates). The parser changes and isError field additions are solid; just needs the barrel file cleaned up.
Summary
Adds a full Conversation View to the dashboard — a structured chat transcript panel that renders Claude Code sessions as a readable TUI-style thread.
ClaudeCodeParserextracts turns from JSONL session files into typed render items (text, tool calls, thinking blocks, results)isApiErrorMessageentries (e.g. "Not logged in") rendered in red with mono font›prompt glyph"No response requested."text blocks and local-command injection tags from user messagesChanges
packages/core/src/parsers/claude-code.tsisApiErrorMessage/errorfields on assistant entries; filter "No response requested." noise; fix regex to strip all occurrencespackages/core/src/types/render.tsisError?: booleantoTextItempackages/dashboard/src/components/conversation/ConversationView.tsxAnsiText), error text color, user-turn background tint, sidechain border/tint, spacing tweakspackages/dashboard/src/index.cssTest plan
🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com