ecd63cd1c31771da9639711bd16184a9add6a76d
4 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
| ecd63cd1c3 |
Add React client: session browser, message viewer, filters, search, redaction, export
Full React 18 client application for interactive session browsing: app.tsx: - Root component orchestrating session list, viewer, filters, search, redaction controls, and export — wires together useSession and useFilters hooks - Keyboard navigation: j/k or arrow keys for message focus, Escape to clear search and redaction selection, "/" to focus search input - Derives filtered messages, match count, visible UUIDs, and category counts via useMemo to avoid render-time side effects hooks/useSession.ts: - Manages session list and detail fetching state (loading, error, data) with useCallback-wrapped fetch functions - Auto-loads session list on mount hooks/useFilters.ts: - Category filter state with toggle, set-all, and preset support - Text search with debounced query propagation - Manual redaction workflow: select messages, confirm to move to redacted set, undo individual or all redactions, select-all-visible - Auto-redact toggle for the sensitive-redactor module - Returns memoized object to prevent unnecessary re-renders components/SessionList.tsx: - Two-phase navigation: project list → session list within a project - Groups sessions by project, shows session count and latest modified date per project, auto-drills into the correct project when a session is selected externally - Formats project directory names back to paths (leading dash → /) components/SessionViewer.tsx: - Renders filtered messages with redacted dividers inserted where manually redacted messages were removed from the visible sequence - Loading spinner, empty state for no session / no filter matches - Scrolls focused message into view via ref components/MessageBubble.tsx: - Renders individual messages with category-specific Tailwind border and background colors - Markdown rendering via marked + highlight.js, with search term highlighting that splits HTML tags to avoid corrupting attributes - Click-to-select for manual redaction, visual selection indicator - Auto-redact mode applies sensitive-redactor to content before render - dangerouslySetInnerHTML is safe here: content is from local user-owned JSONL files, not untrusted external input components/FilterPanel.tsx: - Checkbox list for all 9 message categories with auto-redact toggle components/SearchBar.tsx: - Debounced text input (200ms) with match count display - "/" keyboard shortcut to focus, × button to clear components/ExportButton.tsx: - POSTs current session + visible/redacted UUIDs + auto-redact flag to /api/export, downloads the returned HTML blob as a file components/RedactedDivider.tsx: - Dashed-line visual separator indicating redacted content gap lib/types.ts: - Re-exports shared types via @shared path alias for client imports lib/constants.ts: - Tailwind CSS class mappings per message category (border + bg colors) lib/markdown.ts: - Configured marked + highlight.js instance with search highlighting that operates on text segments only (preserves HTML tags intact) styles/main.css: - Tailwind base/components/utilities, custom scrollbar, highlight.js overrides, search highlight mark, redaction selection outline, message dimming for non-matching search results index.html + main.tsx: - Vite entry point mounting React app into #root with StrictMode Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> |
|||
| 090d69a97a |
Add Express server: session discovery, JSONL parser, HTML exporter, API routes
Server-side implementation for reading, parsing, and exporting Claude
Code session logs:
session-discovery.ts:
- Walks ~/.claude/projects/ directories, reads sessions-index.json from
each project folder, supports both the current {version, entries}
format and the legacy raw array format
- Aggregates sessions across all projects, sorted by most recently
modified first
- Gracefully handles missing directories, corrupt index files, and
missing entries
session-parser.ts:
- Parses Claude Code JSONL session files line-by-line into normalized
ParsedMessage objects
- Handles the full real-world format: type="user" (string or
ContentBlock array content), type="assistant" (text, thinking,
tool_use blocks), type="progress" (hook events with structured data
fields), type="summary" (summary text field), type="file-history-
snapshot", and silently skips type="system" (turn_duration metadata)
and type="queue-operation" (internal)
- Detects <system-reminder> tags in user messages and reclassifies them
as system_message category
- Resilient to malformed JSONL lines (skips with continue, no crash)
html-exporter.ts:
- Generates self-contained HTML exports with no external dependencies —
all CSS (layout, category-specific colors, syntax highlighting) is
inlined in a <style> block
- Dark theme (GitHub dark palette) with category-specific left border
colors and backgrounds matching the Claude Code aesthetic
- Renders markdown content via marked + highlight.js with syntax
highlighting, inserts "content redacted" dividers where redacted
messages were removed
- Outputs a complete <!DOCTYPE html> document with session metadata
header (project name, date, message count)
routes/sessions.ts:
- GET /api/sessions — returns all discovered sessions with 30-second
in-memory cache to avoid re-scanning the filesystem on every request
- GET /api/sessions/:id — looks up session by ID from cache, parses
the JSONL file, returns parsed messages
routes/export.ts:
- POST /api/export — accepts ExportRequest body, validates required
fields, generates HTML via the exporter, returns as a downloadable
attachment with sanitized filename
index.ts:
- Express app factory (createApp) with 50MB JSON body limit, health
check endpoint, session and export routers, and static file serving
for the built client
- Dual-bind to localhost and Tailscale IP (100.84.4.113) for local +
tailnet access, with optional browser-open on startup via
SESSION_VIEWER_OPEN_BROWSER env var
- Auto-start guard: only calls startServer() when run directly, not
when imported by tests
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|||
| c4e15bf082 |
Add shared type definitions and sensitive content redactor
Shared module consumed by both the Express server and the React client: types.ts: - ParsedMessage: the normalized message unit (uuid, category, content, toolName, toolInput, timestamp, rawIndex) that the parser emits and every downstream consumer (viewer, filter, export) operates on - MessageCategory: 9-value union covering user_message, assistant_text, thinking, tool_call, tool_result, system_message, hook_progress, file_snapshot, and summary - SessionEntry / SessionListResponse / SessionDetailResponse / ExportRequest: API contract types for the sessions list, session detail, and HTML export endpoints - ALL_CATEGORIES, CATEGORY_LABELS, DEFAULT_HIDDEN_CATEGORIES: constants for the filter panel UI and presets (thinking + hook_progress hidden by default) sensitive-redactor.ts: - 34 regex patterns derived from gitleaks production config, organized into Tier 1 (known secret formats: AWS, GitHub, GitLab, OpenAI, Anthropic, HuggingFace, Perplexity, Stripe, Slack, SendGrid, Twilio, GCP, Azure AD, Heroku, npm, PyPI, Sentry, JWT, PEM private keys, generic API key assignments) and Tier 2 (PII/system info: home directory paths, connection strings, URLs with credentials, email addresses, IPv4 addresses, Bearer tokens, env var secret assignments) - Keyword pre-filtering: each pattern declares keywords that must appear in the text before the expensive regex is evaluated, following the gitleaks performance optimization approach - False-positive allowlists: example/test email domains, localhost/ documentation IPs (RFC 5737), noreply@anthropic.com - Pure functions: redactSensitiveContent returns {sanitized, count, categories}, redactString returns just the string, redactMessage returns a new ParsedMessage with content and toolInput redacted Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> |
|||
| 7e15c36e2f |
Add project scaffolding and build configuration
Initialize the session-viewer project — a tool for browsing, filtering, redacting, and exporting Claude Code session logs as self-contained HTML. Scaffolding includes: - package.json with Express server + React client dual-stack setup, dev/build/test/lint/typecheck scripts, and a CLI bin entry point - TypeScript configs: base tsconfig.json (ESNext, bundler resolution, strict, react-jsx) and tsconfig.server.json extending it for the Express server compilation target - Vite config: React plugin, Tailscale-aware dev server on :3847 with API proxy to :3848, client build output to dist/client - Vitest config: node environment, test discovery from tests/unit and src/client/components - ESLint flat config: typescript-eslint recommended, unused-vars with underscore exception - Tailwind CSS config scoped to src/client, PostCSS with autoprefixer - Playwright config: Chromium-only E2E against dev server - bin/session-viewer.js: CLI entry point that re-execs via tsx with browser-open flag Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> |