teernisse c20652924d Extract shared JSONL parsing helpers for parser parity
Introduce three shared helpers in session-parser.ts that both the full
parser and the lightweight metadata extractor can use:

- forEachJsonlLine(content, onLine): Iterates JSONL lines with consistent
  malformed-line handling. Skips invalid JSON lines identically to how
  parseSessionContent handles them. Returns parse error count for diagnostics.

- countMessagesForLine(parsed): Returns the number of messages a single
  JSONL line expands into, using the same classification rules as the
  full parser. User arrays expand tool_result and text blocks; assistant
  arrays expand thinking, text, and tool_use.

- classifyLine(parsed): Classifies a parsed line into one of 8 types
  (user, assistant, system, progress, summary, file_snapshot, queue, other).

The internal extractMessages() function now uses these shared helpers,
ensuring no behavior change while enabling the upcoming metadata extraction
service to reuse the same logic. This guarantees list counts can never drift
from detail-view counts, regardless of future parser changes.

Test coverage includes:
- Malformed line handling parity with full parser
- Parse error counting for truncated/corrupted files
- countMessagesForLine output matches extractMessages().length
- Edge cases: empty files, progress events, array content expansion

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-28 00:52:41 -05:00

Session Viewer

Browse, filter, redact, and export Claude Code sessions as self-contained HTML files.

Session Viewer reads session data from ~/.claude/projects/ and presents it in a dark-themed web interface with full-text search, message filtering, sensitive data redaction, and one-click HTML export.

Quick Start

# Install dependencies
npm install

# Run in development mode (starts both server and client with hot reload)
npm run dev

# Or run from the CLI entry point (opens browser automatically)
node bin/session-viewer.js

The API server runs on http://localhost:3848 and the Vite dev server on http://localhost:3847 (proxying API requests to the backend).

Features

Session Navigation

  • Project grouping -- Sessions are organized by their originating project directory.
  • Session metadata -- Each session displays its summary, first prompt, message count, duration, and last-modified date.
  • Sorted by recency -- Most recently modified sessions appear first.

Message Display

  • Nine message categories -- user_message, assistant_text, thinking, tool_call, tool_result, system_message, hook_progress, file_snapshot, and summary, each with a distinct color indicator.
  • Collapsible sections -- Thinking blocks, tool calls, and tool results collapse by default to reduce noise.
  • Diff rendering -- Git-style diffs are auto-detected and rendered with line-level syntax coloring.
  • Code blocks -- Fenced code blocks display a language label and a copy-to-clipboard button.
  • Time gap indicators -- Gaps of more than five minutes between messages are shown as labeled dividers.
  • Hash anchor links -- Each message has a copyable anchor link (#msg-{uuid}) for deep linking.
  • Full-text search across message content and tool input.
  • Match cycling -- Navigate between matches with Enter/Shift+Enter or Ctrl+G/Ctrl+Shift+G.
  • Match counter -- Displays current position and total matches (e.g., "3/12").
  • Minimap -- A scrollbar overlay shows match positions as yellow ticks with a viewport indicator. Click a tick to jump to that match.
  • Dimming -- Non-matching messages are visually dimmed while search is active.
  • Keyboard shortcut -- Press / to focus the search bar; Escape to clear and blur.

Filtering

  • Category toggles -- Show or hide any of the nine message categories. Thinking and hook progress are hidden by default.
  • Filters compose with search -- Category filters and search operate independently.

Redaction

  • Manual redaction -- Click the eye icon on any message to select it, then confirm to redact. Redacted messages are replaced by a visual divider.
  • Auto-redaction -- Toggle automatic detection of sensitive data (API keys, tokens, secrets, PII) using 37 regex patterns derived from gitleaks. Matching content is replaced with [REDACTED] inline.
  • Export-aware -- Both manual and auto-redaction states are respected during export.

Export

  • Self-contained HTML -- Export the current session view as a standalone HTML file with embedded CSS and syntax highlighting.
  • Respects filters -- The export includes only visible messages and applies the current redaction state.
  • Clean filenames -- Output files are named session-{id}.html with sanitized IDs.

Architecture

src/
  client/          React + Vite frontend
    components/    UI components (SessionList, SessionViewer, MessageBubble, etc.)
    hooks/         useSession, useFilters
    lib/           Markdown rendering, sensitive redactor, types, utilities
    styles/        CSS custom properties, Tailwind, design tokens
  server/          Express backend
    routes/        /api/sessions, /api/export
    services/      Session discovery, JSONL parser, HTML exporter
  shared/          Types shared between client and server
bin/               CLI entry point
tests/
  unit/            Vitest unit tests
  e2e/             Playwright end-to-end tests
  fixtures/        Test data

Tech Stack

Layer Technology
Frontend React 18, Tailwind CSS, Vite
Backend Express 4, Node.js
Markdown marked + marked-highlight + highlight.js
Testing Vitest (unit), Playwright (e2e)
Language TypeScript (strict mode)

API Endpoints

Method Path Description
GET /api/health Health check
GET /api/sessions List all sessions (30s server cache)
GET /api/sessions/:id Get session detail with parsed messages
POST /api/export Generate self-contained HTML export

Scripts

Script Description
npm run dev Start server + client with hot reload
npm run build TypeScript compile + Vite production build
npm run test Run unit tests (Vitest)
npm run test:e2e Run end-to-end tests (Playwright)
npm run typecheck TypeScript type checking
npm run lint ESLint

Configuration

Variable Default Description
PORT 3848 API server port
SESSION_VIEWER_OPEN_BROWSER unset Set to 1 to auto-open browser on start

Security

  • Path traversal protection -- Session discovery validates all paths stay within ~/.claude/projects/.
  • HTML escaping -- All user content is escaped before interpolation in exports.
  • Filename sanitization -- Export filenames strip non-alphanumeric characters.
  • Localhost binding -- Both the API server and Vite dev server bind to 127.0.0.1 only.
Description
No description provided
Readme 499 KiB
Languages
TypeScript 84.7%
HTML 8.8%
CSS 5%
JavaScript 1.5%