Skip to content

feat: conversation view v2 — structured chat transcript with TUI styling - #53

Merged
aterrylu merged 3 commits into
mainfrom
terry/conversation-view-v2
Mar 24, 2026
Merged

feat: conversation view v2 — structured chat transcript with TUI styling#53
aterrylu merged 3 commits into
mainfrom
terry/conversation-view-v2

Conversation

@aterrylu

Copy link
Copy Markdown
Owner

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.

  • Structured parser: ClaudeCodeParser extracts turns from JSONL session files into typed render items (text, tool calls, thinking blocks, results)
  • TUI flat style: Dark theme with distinct user/assistant styling, no heavy borders — clean terminal aesthetic
  • Sub-agent (sidechain) support: Nested agent calls rendered with a colored left border + subtle background tint
  • ANSI color rendering: Assistant messages with ANSI escape codes are decoded and rendered with proper colors
  • API error styling: isApiErrorMessage entries (e.g. "Not logged in") rendered in red with mono font
  • User turn polish: Highlight background tint, Berkeley Mono font preference, prompt glyph
  • Noise filtering: Strips "No response requested." text blocks and local-command injection tags from user messages

Changes

File What changed
packages/core/src/parsers/claude-code.ts isApiErrorMessage/error fields on assistant entries; filter "No response requested." noise; fix regex to strip all occurrences
packages/core/src/types/render.ts Add isError?: boolean to TextItem
packages/dashboard/src/components/conversation/ConversationView.tsx ANSI renderer (AnsiText), error text color, user-turn background tint, sidechain border/tint, spacing tweaks
packages/dashboard/src/index.css Tighten prose-tui line-height (1.6→1.45) and paragraph margins

Test plan

  • Open a session with tool calls — verify tool blocks render with summary line
  • Open a session with sub-agent calls — verify sidechain indent + border
  • Open a session that has ANSI output — verify colors render correctly
  • Open a session with an auth error — verify red error styling
  • Verify "No response requested." no longer appears in any assistant message

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com

}

// ── Main conversation view ───────────────────────────────────────────────────

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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" });

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 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 nox-0x left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

aterrylu and others added 3 commits March 23, 2026 20:34
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>
@aterrylu
aterrylu force-pushed the terry/conversation-view-v2 branch from 49a2fe3 to da5984c Compare March 24, 2026 03:35
@aterrylu
aterrylu merged commit 3c95532 into main Mar 24, 2026
1 check passed
@aterrylu
aterrylu deleted the terry/conversation-view-v2 branch March 24, 2026 03:37
@@ -1,6 +1,9 @@
export * from "./parsers/claude-code";
export * from "./parsers/claude-code";

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 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 nox-0x left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants