Turn your Claude Code chat history (JSONL logs) into a clean, searchable visual panel — offline, zero dependencies.
Claude Code stores your conversations as raw JSONL files. Code Chat Viewer turns them into polished, self-contained HTML pages plus an interactive dashboard to search, sort, filter and browse your whole history. Pure Python standard library — nothing to install.
Note
Project status: maintenance mode. v2.7.0 is expected to be the last feature release of Code Chat Viewer; future updates, if any, will be limited to fixes and compatibility adjustments. Its successor, a new app built on a more capable stack, is in the design phase — this repository will be marked as deprecated once it is available.
A — Standalone (no Claude Code needed)
- Download or clone this repo
- Double-click
scripts/manager.py— the first run asks a few quick questions and writes the config for you, then builds the dashboard and opens it in your browser - Next time, just double-click and pick from the menu: Normal (only changed chats), Force (rebuild all), BTW (all your
/btwquestions in one page), Audit (format check after a Claude Code update), Reconfigure or Check updates
B — As a Claude Code skill
- Clone into
~/.claude/skills/(global) or a project's.claude/skills/ - Ask Claude Code "set up the chat visualizer" — it finds your chats, walks you through the config, and generates everything
Latest version: Download latest - Always up-to-date (direct download of main)
Version 2.7.0: Download v2.7.0.zip - Stable release
Or browse all Releases
Claude Code does everything for you. This skill is designed to work directly with Claude Code CLI (Anthropic's command-line tool for developers, not the web interface). Once installed, Claude Code will:
- Detect your Claude Code chat files automatically
- Ask your preferences through interactive setup
- Create the configuration file for you
- Generate HTML visualizations for all your chats
- Build an interactive dashboard to browse them
- Organize chats by activity (active, short, archived) — if you want
No manual configuration needed. Just install the skill and ask Claude Code to visualize your chats.
Option A: Per-project (affects only one project)
Copy the skill folder into your project's .claude/skills/ directory:
# From your project root
mkdir -p .claude/skills
cd .claude/skills
git clone https://github.com/oskar-gm/code-chat-viewer.gitOption B: Global (affects all your Claude Code projects)
Copy the skill folder into your user-level .claude/skills/ directory:
# Global installation
mkdir -p ~/.claude/skills
cd ~/.claude/skills
git clone https://github.com/oskar-gm/code-chat-viewer.gitThen ask Claude Code: "Visualize my Claude Code chats" or "Set up the chat visualizer".
- First time: Claude Code reads
SKILL.md, detects your chat files, asks your preferences, createsconfig.json - Next times: Claude Code reads
config.jsonand runs the manager — no questions asked - To update settings: pick [5] Reconfigure in the menu (guided setup / edit the file / via Claude Code), or ask Claude Code "Reconfigure CCV". Check for new releases anytime with [6] Check updates
The skill uses two files:
| File | Purpose |
|---|---|
config.example.json |
Template with defaults (always present, shareable) |
config.json |
Your personalized settings (gitignored, created by Claude Code) |
Configurable options:
| Setting | Default | Description |
|---|---|---|
| Source path | ~/.claude/projects |
Where your JSONL chat files are |
| Output folder | ~/Code Chat Viewer |
Where HTML files and dashboard are saved |
| Dashboard filename | CCV-Dashboard.html |
Name of the interactive index |
| Time format | 12h |
Message/timestamp clock: 12h (AM/PM) or 24h |
| Agent chats | Included (>3KB) | Include sub-agent conversations |
| Agent min size | 3 KB | Minimum agent file size to include |
| Compaction agents | Excluded | Also include the internal /compact summarizer sub-chats |
| Shorts | Enabled | Separate small inactive chats into subfolder |
| Shorts max size | 40 KB | Maximum HTML size to classify as short |
| Archive | Enabled | Separate old inactive chats into subfolder |
| Inactive days | 5 | Days without activity before organizing |
Environment variables (take precedence over config.json):
| Variable | Overrides | Description |
|---|---|---|
CODE_CHAT_VIEWER_DIR |
Output folder | Alternative output directory for the dashboard and HTML files |
Local customization (optional): if a gitignored custom/ folder exists in the repo root, its dashboard.css and dashboard.js files are embedded into the generated dashboard — a simple extension point for personal tweaks (extra buttons, filters, themes) that never touch the codebase.
- Terminal-style aesthetics inspired by VS Code
- User messages with light blue background
- Assistant responses with light green background
- Collapsible thinking and tool blocks (collapsed by default, full content on expand); long blocks scroll within half the window, always with a single level of scroll (Edit/Write panes and compact parts keep their own cap)
- Real-time conversation filter
- Responsive fullscreen layout with compact spacing
- Multi-mode message navigation: All, User, or Assistant messages with color-coded highlights, plus first/last message buttons next to ▲/▼
- Keyboard shortcuts: N (next) / P (previous) for fast navigation
- Smart scroll: centers short messages, pins long messages to top
- Dashboard state persistence (sort, filters, search, columns) via localStorage
- Security-safe HTML rendering (escaped tool parameters)
- Interactive dashboard with sortable table, full-text search, exclude filter, and category filters
- Full chat names visible on hover and searchable even when truncated; with "Search names only" unchecked, the search covers the whole row (UUID, project, branch…)
- Permanent UUID column in the dashboard, with a copy button for quick session ID access
- Recap and First prompt collapsible sub-rows in the dashboard (optional, searchable, sort-aware)
- Select mode to delete chats from the dashboard: generates a ready-to-copy trash/permanent command for your OS
- Output folder override via the
CODE_CHAT_VIEWER_DIRenvironment variable - Batch generation with incremental updates (only regenerates changed chats)
- Accurate timestamps and message counts read directly from JSONL files
- Automatic filtering of snapshot-only entries (Claude Code's undo system)
- Configurable chat organization (active, shorts, archived)
- Dashboard link in every chat for easy navigation back
- Embedded favicon and header icon (self-contained, no external files needed)
- Auto-opens dashboard in browser after generation
- Smart message rendering: commands, compact blocks, task notifications, user responses with Q&A and markdown previews, user rejections with feedback, inline user comments
- Edit / MultiEdit diff view: old_string vs new_string side-by-side inside the tool-use box (dark/light theme toggle)
- Write tool view: full-width collapsible block with blue accent, visually consistent with Edit's
new_stringside. Shared collapsible structure: theEdits/Writestoggle expands/collapses both at once /btwqueries injected inline in each chat (from~/.claude/history.jsonl): user-style messages with Claude cream styling and a subtle English disclaimer next to[USER]noting that Claude doesn't persist the answer. Counter in the stats bar- Full date in message timestamps (
YYYY-MM-DD), with configurable 12h (AM/PM, default) or 24h time - BTW Queries view (
[3]in interactive menu or--btwflag): aggregates every/btwquery you've issued from~/.claude/history.jsonlinto a standalonebtw.htmlnext to the dashboard. Queries grouped by chat (collapsed by default), singleExpand all / Collapse alltoggle, real-time filter that auto-expands matching sessions - One-click expand/collapse for all Edit and Write blocks in the chat
- Color-coded navigation highlights per message type (blue/green/purple/amber/red)
- CLI flags:
--name,--current,--only,--force,--btw,--auditfor targeted operations - Chat title displayed in HTML header (resolved from session metadata, including AI-generated title as fallback above first prompt)
- Chat UUID displayed on the right side of the header, with selectable text and a one-click SVG copy button
- Interactive menu for manual execution (Normal, Force, BTW, Audit, Reconfigure, Check updates)
- Full interactive setup with all options configurable
- Scan progress indicator with summary
- Header buttons: Feedback (opens GitHub Issues) and Latest release (check for updates)
- App version shown in the header
- Windows-friendly: scripts pause on double-click (no instant close)
- Images rendered in a modal/lightbox:
image-type content shows as an "Open image" link (with media type and file size); clicking opens the image in a full-screen overlay (X button, ESC, or click outside to close; responsivemax 92vw/88vh). The base64 data is embedded in the HTML and loaded as a blob URL to avoid browser navigation restrictions - System markers formatted inline:
<system-reminder>content displayed in orange (without the tags);[Request interrupted by user]displayed with a soft red background and red text - Redundant twin messages hidden: the textual twin of an image (
[Image: source: …]) and of a tool rejection ([Request interrupted by user for tool use]) are suppressed, since the image and the[REJECTED]block already represent those events - Dashboard toolbar redesigned: a Search toggle button shows/hides the search row (search + exclude inputs) with memory when hidden; a scope selector ("Search names only", on by default) limits search to the chat name or searches the full row when unchecked; a Clear button resets all saved state (selection, filters, columns, expanded rows, search); responsive at two breakpoints (Search/Clear separate from Filter+Columns at ≤1000px; Filter separates from Columns at ≤680px)
- Format Audit (
[4]in interactive menu or--auditflag): scans recent chats against the catalog of known message/content types and generates aCCV-Audit <date>.htmlreport, opened automatically on completion. Useful for detecting JSONL format changes after a Claude Code update - Cleaner First prompt and chat names: non-real messages (caveats, slash commands, command output, task notifications) no longer leak into the dashboard's First prompt or chat name — they are skipped when reading the first real user message (fixes chats that start with a compact)
- Inline images: when the user's text references a pasted image with an
[Image #N]marker, the marker itself becomes a clickable chip that opens the image in the modal (mapped by paste order) — no separate "Open image" button for those - Assistant metadata order: model name first, then the date/time in bold so it stands out, then the branch
- Conversation rewinds surfaced: when you rewind the conversation (retry a prompt, dropping what came after), the abandoned point shows as a teal one-line marker —
↺ Rewind · N messages back · «destination»— with a Go button that scrolls up to where the conversation resumed. Real rewinds only (tool-only forks and auto-saved snapshots are ignored); N is the on-screen distance to the destination ("just above" when it sits right over the marker) - Copy button on every message: an always-visible, low-key icon at the top-right of each message that copies its text (turns into a green check on success, or a red cross if the browser refuses the copy)
- "Messages only" filter: a checkbox next to the conversation filter that hides everything except user/assistant messages with real text (tools, thinking, compacts, snapshots…); combines with the text filter
- Stats bar shows a real Rewinds count (replaces the old raw Snapshots count)
- Chat header shows the creation date labelled
Created:, in a format tied to the time setting (24h → DD/MM/YYYY, 12h → MM/DD/YYYY) - Edit/Write diff theme toggle clarified: the button previews the current theme (dark while the diff is dark, cream once light) and its label states the action ("Switch to light/dark")
- Forked chats: a chat branched off another session opens with a banner linking to the origin session through the dashboard (
CCV-Dashboard.html#open=<session>), which knows where every chat lives; if the origin has no page, the dashboard says so - Agent chat links ("↗ open chat" on agent-completed notices) also go through the dashboard, so they keep working when chats move between folders
- Tool result headers open from the keyboard too (Enter/Space)
- Dashboard: text columns (Name, Project, Category, UUID, Branch) sort A→Z on the first click; a Shorts or Archived category switched off in the config stays visible, with its filter and help text, while its folder still holds chats
- More faithful rendering: internal bookkeeping entries that Claude Code writes into the log (request caches, costs, progress…) are no longer shown or counted as messages, and a message that merely quotes a system marker keeps its text
- Problems made visible instead of breaking the chat: a log line that can't be read shows as a red
CCV parse errorblock, and a message that fails to render as a redCCV render errorblock - Model switches mid-answer shown as
[Model fallback: A → B]; attached PDFs named as[Document: PDF «title» · N KB]
Chat viewer:
- First/last message buttons next to ▲/▼; navigation now works out its position from the page layout, so it stays reliable in long chats
- Forked chats open with a banner linking to their origin session, and agent chat links work the same way: both go through the dashboard (
CCV-Dashboard.html#open=<session>), so they keep working when chats move between folders - Long blocks scroll within half the window, always with a single level of scroll
- Tool result headers open from the keyboard (Enter/Space); copy buttons show a red cross if the browser refuses the copy
/btwquestions appear at their real moment in the conversation (their timestamps were compared as text, which misplaced many of them)- Problems show up instead of breaking the chat: an unreadable log line appears as a red
CCV parse errorblock, a message that fails to render as a redCCV render errorblock, and a failed run no longer replaces an existing page - More faithful rendering: internal bookkeeping entries that Claude Code writes into the log (request caches, costs, progress…) are no longer shown or counted as messages; a message that merely quotes a system marker keeps its text; messages re-emitted after a rewind appear once; and rewind Go buttons only point to messages present on the page
- Model switches mid-answer shown as
[Model fallback: A → B]; attached PDFs named as[Document: PDF «title» · N KB] - The conversation filter waits until you stop typing; compact blocks use native collapsibles
Dashboard:
- Agent chats no longer go missing (a truncated key hid most of them)
- Deep links:
CCV-Dashboard.html#open=<session>opens a chat wherever it currently lives, or says so if it has no page - Text columns (Name, Project, Category, UUID, Branch) sort A→Z on the first click; a Shorts or Archived category switched off in the config stays visible while its folder still holds chats
- Compacts are recognized with the same criterion as in the chat page
- Optional local customization: a gitignored
custom/folder withdashboard.css/dashboard.jsis embedded into the dashboard
Manager:
--only "chat id"regenerates just that chat (UUID, hash prefix or name) and opens it, without a full scan- Reconfigure keeps the settings it doesn't ask about and saves the config where it was found
--currentonly picks the project of a folder that really contains the current one- A fresh install is no longer told to rebuild with Force
- A stray non-UTF-8 byte in a log no longer aborts the run, and Check updates handles version tags with suffixes
Fixes and hardening:
- Five values taken from the logs are now HTML-escaped (they were inserted as-is)
- An empty Shorts/Archived folder name in the config can no longer delete generated pages
- Removed a Python 3.12-only syntax (present since v2.3.0) that kept the scripts from starting on earlier Python versions; tested on Python 3.13
- The catalog of known message and content types follows the current Claude Code log format
Quality:
- Test suite expanded from 230 to 284 tests, now also running the pages' JavaScript (copy buttons, N/P keys, the loading-screen fail-safe, dashboard deep links) under Node
- README, SKILL and CONTRIBUTING aligned with the code, in both languages
Manager menu:
- [5] Reconfigure — change settings without deleting
config.jsonby hand: guided re-setup (shows the current values and asks before overwriting), openconfig.jsonin your editor, or do it via Claude Code - [6] Check updates — checks GitHub for a newer release on demand (the tool stays offline otherwise); flags a new stable version (published ≥72h ago) with shortcuts to the release page or update instructions
- Menu grouped visually (generate · views · utilities); the close countdown can now go back to the menu (type anything + Enter), not just close immediately
- Standalone setup also asks for the time format (12h/24h) now, matching the Claude Code setup
Chat viewer:
- Conversation rewinds surfaced: real rewinds show as a one-line teal marker
↺ Rewind · N messages back · «destination»with a Go button to where the conversation resumed (tool-only forks and auto-saved snapshots ignored; "just above" when the destination sits right over the marker) - Inline images:
[Image #N]markers in the text become clickable chips that open the image in the modal (mapped by paste order) - Image modal/lightbox:
image-type content opens in a full-screen overlay (X / ESC / click-out), decoded to a blob URL; shows media type and size - System markers formatted inline:
<system-reminder>in orange (tags stripped),[Request interrupted by user]in soft red - Redundant twin messages hidden (the textual twin of an image and of a tool rejection)
- Copy button on every message (always visible, green check on copy)
- "Messages only" filter next to the conversation filter (keeps user/assistant text only; combines with the text filter)
- Assistant metadata: model first, then the date/time in bold
- Creation date in the header (
Created:), formatted per the time setting (24h → DD/MM/YYYY, 12h → MM/DD/YYYY) - Message separator redrawn as an adaptive CSS line (no horizontal scroll on narrow windows)
- Stats bar shows a real Rewinds count (was a raw Snapshots count)
- Clearer Edit/Write diff theme toggle (previews the current theme; label states the action)
- Chat title falls back to the AI-generated title (above the first prompt, below
/renameand summary) - AskUserQuestion answers redesigned: the question with its header as a chip, the offered options with the chosen one highlighted (and its description), free-text "Other" answers shown verbatim, plus multi-select and notes — built from the structured result, robust to wording changes
- State remembered across refreshes (per chat): it survives F5/back-forward, but reopening the chat starts clean (the navigation type is detected, reliable even though sessionStorage persists on file://). It keeps the scroll position, Edit/Write diff theme, the user/bot/all selector, search + "Messages only", and which Edit/Write blocks are open (thinking and other non-button foldables reset closed by design). A brief loading overlay hides the restore jump
- Agent chats are marked: a chat opened from a sub-agent shows an "AGENT CHAT" chip in its header, and "agent completed" notices name which agent ran (
subagent_type · description) and link to its chat (new tab) when its HTML exists - Commands sent with "!" (Claude Code's bash prompt) render as
! cmdin red, with their stdout/stderr shown cleanly
Accessibility:
- WCAG AA contrast on the rewind block (teal text and the Go button)
- Image modal: the close button sits on a translucent disc with a text-shadow (legible over any image), a 44×44 hit area and a visible focus ring; the modal is a proper
role="dialog"+aria-modalwith a focus trap and focus returned to the trigger on close
Dashboard:
- Toolbar redesign: a Search toggle, a scope selector ("Search names only"), and a Clear button that resets all saved state; responsive at two breakpoints
- Select mode persists across a refresh (the individual delete marks do not — transient on purpose)
- Agent chats: sub-chats launched by the Task tool (under
<session>/subagents/) show via an "Agents" toggle in the View group (off by default), with a count in the stats bar. Each carries an AGENT badge and is nested under its invoking chat with a subtle└─connector (in invocation order, kept glued when sorting); its name issubagent_type · description(e.g. "Auditor · Audit the login"). Orphan agents (invoker not generated) are grouped in a collapsible block at the end. Compaction agents and context-ref forks are filtered out - Sticky table header (no gap on scroll); the BTW and Audit views moved to a "+" menu (same tab, shared header/footer and "← Back to Dashboard"); the Audit report has a "Delete this report" button; the BTW view is refreshed on every run
- Version-aware: after a minor/major update the script recommends a Force rebuild — everything re-renders consistently with the new version (applying all fixes)
- Format Audit (
[4]/--audit): scans recent chats for format anomalies and writes aCCV-Audit <date>.htmlreport — handy after a Claude Code update - Cleaner First prompt and chat names: non-real messages (caveats, commands, output, task notifications) no longer leak in
Setup:
- First-time setup now asks for
time_format(12h/24h), which also sets the header date format
Quality:
- pytest test suite in
tests/covering parsing, rendering, chat generation, dashboard utilities and regressions (synthetic fixtures) - Robustness fixes: defensive parsing for string-serialized tool inputs (AskUserQuestion / MultiEdit) and non-string timestamps
Fixes:
- BTW view: footer pinned to the bottom; the project column now reflects each chat's working directory (matching the dashboard) instead of the folder name
- Image modal overlay lightened (55%) so the conversation shows through behind the opened image
- Queued messages (sent while Claude was working) now render instead of silently disappearing
- AskUserQuestion answers are recognised again after Claude Code changed the result wording
- Failed background-agent notifications shown in red
- Non-consecutive
[Image #N]markers (e.g. #1 + #3) map to the right image instead of dropping it - Uniform vertical spacing inside Edit/Write tool blocks (matches the generic tool and thinking blocks)
- Rewind Go button reaches compact-summary destinations and destinations hidden by an active filter (it clears the filter first); a visible toast appears if a target can't be located
- user/bot/all jumps now start from the current scroll position (reliable after a native Ctrl+F or manual scroll)
Dashboard:
- Recap + First prompt as collapsible sub-rows under each chat (off by default, toggles in Columns): the chat's last obtainable summary and the full first user message; searchable, glued to their row when sorting, persisted in localStorage — inspired by @marccane (#2)
- Select & delete: a Select mode with per-row checkboxes and a select-all-visible master; the Delete modal lists the affected chats and generates a ready-to-copy command (PowerShell / macOS / Linux tabs) that removes each chat's HTML and original
.jsonl— to trash by default, permanent via toggle — inspired by @marccane (#2) - Universal column sorting: every column is sortable except the link icon (Size by real byte size, UUID alphabetical)
General:
CODE_CHAT_VIEWER_DIRenvironment variable: alternative output folder, takes precedence overconfig.json— co-authored with @marccane (#2)
Chat viewer:
- Edit / MultiEdit diff view:
old_stringandnew_stringrendered side-by-side inside the tool-use box, with red/green color coding. Dark theme by default, Light theme toggle in the search bar - Write tool view: full-width collapsible block with blue accent, visually consistent with Edit's
new_stringside. The sharedEdits/Writestoggle expands/collapses both at once - One-click expand/collapse for all Edit and Write blocks
- Chat UUID in header: full session UUID on the right side of the terminal header, with selectable text and a one-click SVG copy button (visual confirmation on copy)
/btwqueries injected inline in each chat (from~/.claude/history.jsonl): user-style messages with Claude cream styling and a subtle disclaimer noting Claude doesn't persist the answer. Counter in the stats bar- User rejections (
[REJECTED]with feedback, coral/red) and inline user comments ([USER COMMENT], amber) - Color-coded navigation highlight for rejections (red), alongside user/assistant/compact/response
- Full date in message timestamps (
YYYY-MM-DD), with configurable 12h (AM/PM, default) or 24h time - More compact chat view: reduced padding, margins and font sizes throughout, with a refactored tool-result wrapper (same look, less vertical space)
- Header buttons reworked (chat and dashboard): Feedback now opens GitHub Issues, and a new Latest release button links to the newest release to check for updates
- App version shown in the header (chat and dashboard)
Dashboard:
- Full-text search across complete chat names and UUIDs (not just the visible truncated text); full names visible on hover
- UUID copy button for quick session ID access, and
UUIDpromoted to a permanent column BTWcolumn (optional, off by default, sortable): per-chat/btwcount- BTW Queries view (
[3]in the interactive menu or--btwflag): aggregates every/btwquery from~/.claude/history.jsonlinto a standalonebtw.html, grouped by chat, with an Expand/Collapse all toggle and a real-time filter - Table layout rework: fixed column widths, flexible Name column with a sane minimum, horizontal scroll only when the visible columns don't fit, and overflow-proof cells (no more phantom blank space)
Fixes:
- Snapshot entries (
[Snapshot saved: ...]) now honor the search filter — previously they stayed visible regardless of the query - Special user blocks (responses, rejections, comments) correctly filter as user messages in navigation
Chat viewer:
- Smart rendering: commands (
[COMMAND]), compact blocks (collapsible, purple), task notifications (color by status), user responses (amber Q&A with markdown previews) - Color-coded navigation highlights per message type: blue (user), green (assistant), purple (compact), amber (user response)
- Dashboard exclude filter: hide rows by text (complementary to search)
- CLI flags:
--current(auto-detect session),--name(search by name),--force(regenerate all) - Chat title displayed in HTML header (resolved from session metadata)
- Interactive mode selection (normal/force) for manual execution
Fixes:
- Summary counter now correctly detects summaries embedded in user messages
- Windows
\r\nline endings no longer cause extra spacing in HTML output - All HTML variables properly escaped (XSS hardening)
- Bare
exceptclauses replaced with specific exception types - Duplicate CSS rules consolidated
- Unused imports and dead code removed
Chat viewer:
- Collapsible thinking blocks with first-line preview (collapsed by default)
- Collapsible tool-use blocks with full content (no more 100-char truncation)
- Multi-mode message navigation: All (gradient icon), User (blue), Assistant (green)
- Keyboard shortcuts: N (next) and P (previous) for message navigation
- Color-coded highlight animation: blue for user, green for assistant messages
- Smart scroll: centers short messages, pins long messages to top
- Compact layout: reduced padding, margins, line-height throughout
- Compact empty lines for denser content display
- Messages that only contain thinking/tool blocks are skipped during navigation
Dashboard:
- State persistence via localStorage (5h TTL): remembers sort order, filters, search, visible columns
- Accurate timestamps: always checks JSONL file modification time (sessions-index.json can be stale)
- Real message counts extracted directly from JSONL files
- JSONL enrichment for non-indexed chats (project, branch, first prompt, message count)
- Automatic filtering of file-history-snapshot entries (Claude Code's undo system)
- Orphan HTML cleanup when snapshot-only chats are detected
Fixes:
- Dashboard filter state now correctly persists (selector bug fixed)
- Message content vertically centered in containers (removed leading whitespace)
- Dashboard now displays custom titles set via
/renamefor all chats, including those not indexed in sessions-index.json
Features:
- Fullscreen edge-to-edge layout (no borders or shadows)
- User message navigation with prev/next buttons and position counter
- Scroll synchronization for navigation counter
- Highlight animation when navigating to a message
- Local timezone conversion for timestamps
- Smart output filename generation (Chat YYYY-MM-DD HH-MM hash.html)
- Stats bar shows chat date instead of generation time
- Chat Manager: batch generation, organization, and interactive dashboard
- Full interactive setup: all options configurable with sensible defaults
- Organized output: Chats/ subfolder with Shorts/ and Archived/ subfolders
- Embedded favicon (dark, visible on browser tabs) and header icon (light)
- Auto-opens dashboard in browser after generation
- Scan progress indicator with file count summary
- Dashboard navigation: every chat includes a "Back to Dashboard" link
- Built-in feedback button in header and footer
- Conversation filter (replaces generic search)
- Windows double-click support: scripts pause before closing
- Rebranded from "Claude Code Visualizer" to "Code Chat Viewer"
Fixes:
- Security: HTML-escaped tool_use parameters to prevent DOM injection
- Filtered out "(no content)" ghost messages from Claude Code internals
- CSS specificity: User messages correctly display with blue styling
- Unknown type elements styled correctly within user messages
- Instant scroll navigation (replaced smooth scrolling)
- Reduced IntersectionObserver reactivation delay to 100ms
- Consistent header sizing between chat pages and dashboard
You do not need Claude Code to use this tool. Both scripts work standalone with Python — tested on Python 3.13 (earlier versions are not verified).
Convert a single chat:
python scripts/visualizer.py path/to/chat.jsonl output.htmlBatch generation with dashboard:
python scripts/manager.pyOn the first run there's no config.json yet, so the manager launches an interactive setup — it asks where your Claude Code chats are (and a few options) and writes config.json for you. No manual editing needed. After that it just reads config.json. (You can still pre-create it from the template with cp config.example.json config.json if you prefer.)
CLI flags:
python scripts/manager.py --name "search terms" # Open a specific chat by name
python scripts/manager.py --current # Open the current session (auto-detect from CWD)
python scripts/manager.py --current path/to/chat.jsonl # Open the chat of that JSONL file
python scripts/manager.py --only "chat id" # Regenerate ONLY that chat (UUID/hash/name) and open it
python scripts/manager.py --force # Regenerate ALL chats
python scripts/manager.py --btw # Build btw.html with all your /btw questions
python scripts/manager.py --audit 50 # Check the 50 most recent chats for format changes (or: all)
python scripts/manager.py --force --name "my chat" # Combine flags--only works with main chats (by UUID, hash prefix or name); agent sub-chats open from the dashboard.
On Windows, you can also double-click scripts/manager.py: the console offers the menu (Normal, Force, BTW, Audit, Reconfigure, Check updates) and, when it finishes, closes after a 60-second countdown (Enter closes it at once; type anything + Enter to go back to the menu).
code-chat-viewer/
├── scripts/
│ ├── visualizer.py # Core: JSONL to HTML converter
│ └── manager.py # Orchestrator: batch generation + dashboard
├── tests/ # pytest suite (parsing, rendering, dashboard, regressions)
├── assets/ # README screenshots
├── icon.png # Project icon (embedded as base64 in output)
├── config.example.json # Configuration template
├── config.json # Your settings (gitignored, created by setup)
├── custom/ # Optional local dashboard tweaks (gitignored)
├── SKILL.md # Claude Code skill instructions
├── README.md # This file
├── CONTRIBUTING.md # Contribution guidelines
├── CODE_OF_CONDUCT.md # Code of conduct
└── LICENSE # MIT License
~/Code Chat Viewer/ # Output root (configurable)
├── CCV-Dashboard.html # Interactive dashboard
└── Chats/ # Generated HTML files
├── Chat 2026-01-30 ...html # Active chats
├── Shorts/ # Small inactive chats (if enabled)
└── Archived/ # Old inactive chats (if enabled)
Claude Code stores chat logs in JSONL format at:
- Windows:
%USERPROFILE%\.claude\projects\ - Linux/Mac:
~/.claude/projects/
One subfolder per project. Each chat file is named with a UUID (e.g., c5f2a3e1-1234-5678-9abc-def012345678.jsonl); agent sub-chats live under <chat-uuid>/subagents/.
- User messages: Blue (
#0066CC) with light blue background (#F8FBFF) - Assistant messages: Green (
#10893E) with light green background (#FAFFF8) - Commands: Blue (
#0066CC) with[COMMAND]label and deeper blue background (#EBF2FF) - User responses: Amber (
#D97706) with Q&A layout, markdown previews, and[USER RESPONSE]label - User rejections: Coral/red (
#DC2626) with[REJECTED]label and user feedback when provided (#FFF1F2background) - User comments: Amber (
#D97706) with[USER COMMENT]label for inline comments on accepted actions - Compact blocks: Purple (
#8B5CF6) collapsible blocks grouping summary + pre-compact output - Task notifications: Color-coded by status — green (completed), red (failed), blue (in progress), gray (other)
- Tool results: Orange (
#FF6B00) with gray background (#F8F8F8) - Thinking blocks: White background with subtle gray border and shadow
- Tool use blocks: Dark gray (
#48484A) with light text (#E8E8E8) - System reminders (
<system-reminder>): Orange text, tags stripped - User interruptions (
[Request interrupted by user]): Soft red background with red text
Contributions are welcome! Please read CONTRIBUTING.md for details on our code of conduct and the process for submitting pull requests.
This project is licensed under the MIT License - see the LICENSE file for details.
Attribution Requirements:
- Keep the LICENSE file intact
- Credit the original author: Óscar González Martín
- Link to the original repository: https://github.com/oskar-gm/code-chat-viewer
- State any modifications made
Óscar González Martín
- Website: nucleoia.es
- Email: oscar@nucleoia.es
- GitHub: @oskar-gm
- LinkedIn: oscar-gonz
If you find this project useful, please:
- Star the repository
- Report bugs via Issues
- Suggest improvements
- Share with others
For questions, suggestions, or bug reports:
- Email: oscar@nucleoia.es
- GitHub Issues: Report here
Note
Estado del proyecto: en mantenimiento. La v2.7.0 será previsiblemente la última versión con novedades de Code Chat Viewer; las próximas actualizaciones, si las hay, se limitarán a correcciones y ajustes de compatibilidad. Su sucesora, una nueva aplicación con un stack más completo, está en fase de diseño — este repositorio se marcará como obsoleto cuando esté disponible.
Claude Code guarda tus conversaciones como archivos JSONL en crudo. Code Chat Viewer los convierte en páginas HTML pulidas y autónomas, más un panel interactivo para buscar, ordenar, filtrar y navegar todo tu historial. Solo biblioteca estándar de Python — nada que instalar.
A — Standalone (sin Claude Code)
- Descarga o clona este repo
- Doble clic en
scripts/manager.py— la primera vez te hace unas preguntas rápidas y crea la configuración por ti, luego genera el panel y lo abre en tu navegador - Las siguientes veces, doble clic y eliges en el menú: Normal (solo los chats modificados), Force (regenerar todo), BTW (todas tus preguntas
/btwen una página), Audit (comprobación del formato tras actualizar Claude Code), Reconfigure o Check updates
B — Como skill de Claude Code
- Clona en
~/.claude/skills/(global) o en.claude/skills/de un proyecto - Pide a Claude Code "configura el visualizador de chats" — detecta tus chats, te guía por la configuración y genera todo
Claude Code lo hace todo por ti. Esta skill está diseñada para funcionar directamente con Claude Code CLI (la herramienta de línea de comandos de Anthropic para desarrolladores, no la interfaz web). Una vez instalada, Claude Code:
- Detecta tus archivos de chat de Claude Code automáticamente
- Pregunta tus preferencias mediante un setup interactivo
- Crea el archivo de configuración por ti
- Genera visualizaciones HTML de todos tus chats
- Construye un panel interactivo para navegarlos
- Organiza los chats por actividad (activos, cortos, archivados) — si quieres
Sin configuración manual. Solo instala la skill y pide a Claude Code que visualice tus chats.
Opción A: Por proyecto (afecta solo a un proyecto)
Copia la carpeta de la skill en el directorio .claude/skills/ de tu proyecto:
# Desde la raíz de tu proyecto
mkdir -p .claude/skills
cd .claude/skills
git clone https://github.com/oskar-gm/code-chat-viewer.gitOpción B: Global (afecta a todos tus proyectos de Claude Code)
Copia la carpeta de la skill en tu directorio .claude/skills/ a nivel de usuario:
# Instalación global
mkdir -p ~/.claude/skills
cd ~/.claude/skills
git clone https://github.com/oskar-gm/code-chat-viewer.gitLuego pide a Claude Code: "Visualiza mis chats de Claude Code" o "Configura el visualizador de chats".
- Primera vez: Claude Code lee
SKILL.md, detecta tus archivos de chat, pregunta tus preferencias, creaconfig.json - Siguientes veces: Claude Code lee
config.jsony ejecuta el manager — sin preguntas - Para cambiar ajustes: usa [5] Reconfigure en el menú (setup guiado / editar el archivo / vía Claude Code), o pide a Claude Code "Reconfigura CCV". Comprueba nuevas versiones cuando quieras con [6] Check updates
La skill usa dos archivos:
| Archivo | Propósito |
|---|---|
config.example.json |
Plantilla con valores por defecto (siempre presente, compartible) |
config.json |
Tu configuración personalizada (en gitignore, creada por Claude Code) |
Opciones configurables:
| Ajuste | Por defecto | Descripción |
|---|---|---|
| Ruta origen | ~/.claude/projects |
Dónde están tus archivos JSONL |
| Carpeta de salida | ~/Code Chat Viewer |
Dónde se guardan los HTML y el panel |
| Nombre del panel | CCV-Dashboard.html |
Nombre del archivo índice interactivo |
| Formato de hora | 12h |
Reloj de los timestamps: 12h (AM/PM) o 24h |
| Chats de agentes | Incluidos (>3KB) | Incluir conversaciones de sub-agentes |
| Tamaño mín. agente | 3 KB | Tamaño mínimo de agente para incluir |
| Agentes de compactación | Excluidos | Incluir también los sub-chats internos del resumidor de /compact |
| Shorts | Activado | Separar chats pequeños inactivos en subcarpeta |
| Tamaño máx. short | 40 KB | Tamaño máximo de HTML para clasificar como short |
| Archivo | Activado | Separar chats inactivos antiguos en subcarpeta |
| Días de inactividad | 5 | Días sin actividad antes de organizar |
Variables de entorno (tienen precedencia sobre config.json):
| Variable | Sobrescribe | Descripción |
|---|---|---|
CODE_CHAT_VIEWER_DIR |
Carpeta de salida | Directorio de salida alternativo para el panel y los HTML |
Personalización local (opcional): si existe una carpeta custom/ (en gitignore) en la raíz del repo, sus archivos dashboard.css y dashboard.js se embeben en el panel generado — un punto de extensión sencillo para ajustes personales (botones extra, filtros, temas) que nunca tocan el código del proyecto.
- Estética estilo terminal inspirada en VS Code
- Mensajes de usuario con fondo azul claro
- Respuestas del asistente con fondo verde claro
- Bloques de thinking y tool colapsables (plegados por defecto, contenido completo al expandir); los bloques largos hacen scroll dentro de media ventana, siempre con un solo nivel de scroll (los paneles de Edit/Write y las partes del compact conservan su propio tope)
- Filtro de conversación en tiempo real
- Layout fullscreen responsive con espaciado compacto
- Navegación multi-modo: mensajes de Todos, Usuario o Asistente con resaltado por color, más botones de primer y último mensaje junto a ▲/▼
- Atajos de teclado: N (siguiente) / P (anterior) para navegación rápida
- Scroll inteligente: centra mensajes cortos, fija al inicio los largos
- Persistencia de estado del dashboard (orden, filtros, búsqueda, columnas) vía localStorage
- Renderizado HTML seguro (parámetros de herramientas escapados)
- Panel interactivo con tabla ordenable, búsqueda de texto completo, filtro de exclusión y filtros por categoría
- Nombres de chats completos visibles en hover y buscables aunque estén truncados; con «Search names only» desmarcado, la búsqueda abarca toda la fila (UUID, proyecto, rama…)
- Columna UUID permanente en el dashboard, con botón de copiar para acceso rápido al ID de sesión
- Sub-filas desplegables Recap y First prompt en el dashboard (opcionales, con búsqueda y orden integrados)
- Modo selección para borrar chats desde el dashboard: genera un comando listo para copiar (papelera/permanente) según tu sistema
- Carpeta de salida configurable con la variable de entorno
CODE_CHAT_VIEWER_DIR - Generación por lotes con actualizaciones incrementales (solo regenera chats modificados)
- Timestamps y conteos de mensajes precisos leídos directamente de archivos JSONL
- Filtrado automático de entradas snapshot-only (sistema de undo de Claude Code)
- Organización configurable de chats (activos, cortos, archivados)
- Enlace al panel en cada chat para volver fácilmente
- Favicon e icono de cabecera embebidos (autocontenido, sin archivos externos)
- Apertura automática del panel en el navegador tras la generación
- Renderizado inteligente de mensajes: comandos, bloques compact, notificaciones de tareas, respuestas de usuario con Q&A y previews de markdown, rechazos de usuario con feedback, comentarios inline del usuario
- Vista diff para Edit / MultiEdit: old_string vs new_string en dos columnas dentro del recuadro tool-use (toggle de tema claro/oscuro)
- Vista del tool Write: bloque colapsable full-width con acento azul, visualmente coherente con el
new_stringde Edit. Estructura compartida: el toggleEdits/Writesexpande/colapsa ambos a la vez - Consultas
/btwinyectadas inline en cada chat (desde~/.claude/history.jsonl): pseudo-mensajes de usuario con estética crema Claude y disclaimer sutil en inglés junto a[USER]indicando que Claude no persiste la respuesta. Contador en la barra de estadísticas - Fecha completa en los timestamps de mensajes (
YYYY-MM-DD), con hora configurable 12h (AM/PM, por defecto) o 24h - Vista BTW Queries (
[3]en el menú interactivo o flag--btw): agrega todas las consultas/btwque has hecho desde~/.claude/history.jsonlen unbtw.htmlstandalone junto al dashboard. Consultas agrupadas por chat (colapsadas por defecto), botón únicoExpand all / Collapse all, filtro en tiempo real que auto-expande sesiones con matches - Expandir/contraer todos los bloques Edit y Write con un clic
- Resaltado de navegación por color según tipo de mensaje (azul/verde/morado/ámbar/rojo)
- Flags CLI:
--name,--current,--only,--force,--btw,--auditpara operaciones dirigidas - Título del chat en el header del HTML (resuelto desde metadatos de sesión, incluyendo el título generado por IA como fallback por encima del primer prompt)
- UUID del chat en el lado derecho del header, con texto seleccionable y botón SVG de copia con un clic
- Menú interactivo en ejecución manual (Normal, Force, BTW, Audit, Reconfigure, Check updates)
- Setup interactivo completo con todas las opciones configurables
- Indicador de progreso del escaneo con resumen
- Botones del header: Feedback (abre los Issues de GitHub) y Latest release (comprobar actualizaciones)
- Versión de la app visible en el header
- Compatible con Windows: los scripts se pausan al hacer doble clic (sin cierre instantáneo)
- Imágenes renderizadas en modal/lightbox: el contenido de tipo
imagese muestra como enlace "Open image" (con tipo y peso); al hacer clic se abre en un overlay a pantalla completa (botón X, ESC o clic fuera para cerrar; responsivemax 92vw/88vh). El base64 queda embebido en el HTML y se carga como blob URL para evitar restricciones del navegador - Marcadores del sistema formateados inline: el contenido de
<system-reminder>se muestra en naranja (sin las etiquetas);[Request interrupted by user]aparece con fondo rojo suave y texto rojo - Mensajes gemelos redundantes ocultos: el gemelo textual de una imagen (
[Image: source: …]) y el de un rechazo de tool ([Request interrupted by user for tool use]) se suprimen, ya que la imagen y el bloque[REJECTED]representan esos eventos - Toolbar del dashboard rediseñada: botón Search (toggle) que despliega/oculta la fila de búsqueda (inputs buscar + excluir) con memoria al ocultar; selector de ámbito ("Search names only", marcado por defecto) que limita la búsqueda al nombre del chat o busca en toda la fila al desmarcarlo; botón Clear que resetea todo el estado guardado (selección, filtros, columnas, desplegables, búsqueda); responsive en dos breakpoints (Search/Clear se separan de Filter+Columns en ≤1000px; Filter se separa de Columns en ≤680px)
- Format Audit (
[4]en el menú interactivo o flag--audit): escanea chats recientes contra el catálogo de tipos conocidos y genera un informeCCV-Audit <fecha>.html, abriéndolo automáticamente al terminar. Útil para detectar cambios de formato JSONL tras actualizar Claude Code - First prompt y nombres de chat más limpios: los mensajes no-reales (caveats, comandos, salida de comandos, notificaciones de tareas) ya no se cuelan en el First prompt ni en el nombre del chat del dashboard — se saltan al leer el primer mensaje real del usuario (corrige los chats que empiezan con un compact)
- Imágenes inline: cuando el texto del usuario referencia una imagen pegada con un marcador
[Image #N], el propio marcador se convierte en un chip clicable que abre la imagen en el modal (mapeado por orden de pegado) — sin botón "Open image" separado para esas - Orden del metadata del asistente: primero el modelo, luego la fecha/hora en negrita para que destaque, luego la rama
- Rewinds de conversación visibles: cuando retrocedes la conversación (reintentas un prompt y descartas lo posterior), el punto abandonado se muestra como un marcador teal de una línea —
↺ Rewind · N messages back · «destino»— con un botón Go que sube hasta donde se reanudó. Solo rewinds reales (se ignoran los forks de solo herramientas y los snapshots automáticos); N es la distancia visual al destino ("just above" cuando queda justo encima del marcador) - Botón de copiar en cada mensaje: un icono discreto siempre visible arriba a la derecha de cada mensaje que copia su texto (✓ verde al copiar, o un aspa roja si el navegador rechaza la copia)
- Filtro "Messages only": checkbox junto al filtro de conversación que oculta todo salvo mensajes de usuario/asistente con texto real (tools, thinking, compacts, snapshots…); se combina con el filtro de texto
- La barra de estadísticas muestra un contador real de Rewinds (sustituye al antiguo conteo bruto de Snapshots)
- El header del chat muestra la fecha de creación etiquetada
Created:, en un formato ligado al ajuste de hora (24h → DD/MM/YYYY, 12h → MM/DD/YYYY) - Toggle de tema de diffs Edit/Write clarificado: el botón previsualiza el tema actual (oscuro mientras el diff está oscuro, crema cuando está claro) y su etiqueta indica la acción ("Switch to light/dark")
- Chats bifurcados: un chat que nace de otra sesión abre con un aviso que enlaza a la sesión de origen a través del panel (
CCV-Dashboard.html#open=<sesión>), que sabe dónde vive cada chat; si el origen no tiene página, el panel lo indica - Los enlaces al chat de un agente ("↗ open chat" en los avisos de agente terminado) también pasan por el panel, así que siguen funcionando cuando los chats cambian de carpeta
- Las cabeceras de los resultados de herramientas también se abren con el teclado (Intro/Espacio)
- Dashboard: las columnas de texto (Name, Project, Category, UUID, Branch) ordenan de la A a la Z en el primer clic; una categoría Shorts o Archived desactivada en la configuración sigue visible, con su filtro y su ayuda, mientras su carpeta tenga chats
- Renderizado más fiel: las entradas internas de contabilidad que Claude Code escribe en el log (cachés de peticiones, costes, progreso…) ya no se muestran ni cuentan como mensajes, y un mensaje que solo cita una marca del sistema conserva su texto
- Los problemas se ven en vez de romper el chat: una línea del historial que no se puede leer sale como un bloque rojo
CCV parse error, y un mensaje que no se puede pintar, como un bloque rojoCCV render error - Los cambios de modelo a mitad de respuesta se muestran como
[Model fallback: A → B], y los PDF adjuntos se nombran como[Document: PDF «título» · N KB]
Visor de chats:
- Botones de primer y último mensaje junto a ▲/▼; la navegación calcula ahora su posición a partir del diseño de la página, así que es fiable también en chats largos
- Los chats bifurcados abren con un aviso que enlaza a su sesión de origen, y los enlaces a chats de agente funcionan igual: ambos pasan por el panel (
CCV-Dashboard.html#open=<sesión>), así que siguen funcionando cuando los chats cambian de carpeta - Los bloques largos hacen scroll dentro de media ventana, siempre con un solo nivel de scroll
- Las cabeceras de los resultados de herramientas se abren con el teclado (Intro/Espacio); los botones de copiar muestran un aspa roja si el navegador rechaza la copia
- Las preguntas
/btwaparecen en su momento real de la conversación (sus fechas se comparaban como texto, y muchas quedaban fuera de sitio) - Los problemas se ven en vez de romper el chat: una línea del historial que no se puede leer sale como un bloque rojo
CCV parse error, un mensaje que no se puede pintar, como un bloque rojoCCV render error, y una ejecución fallida ya no sustituye una página existente - Renderizado más fiel: las entradas internas de contabilidad que Claude Code escribe en el log (cachés de peticiones, costes, progreso…) ya no se muestran ni cuentan como mensajes; un mensaje que solo cita una marca del sistema conserva su texto; los mensajes que un rewind vuelve a emitir aparecen una sola vez; y los botones Go de los rewinds solo apuntan a mensajes presentes en la página
- Los cambios de modelo a mitad de respuesta se muestran como
[Model fallback: A → B], y los PDF adjuntos se nombran como[Document: PDF «título» · N KB] - El filtro de conversación espera a que termines de escribir; los bloques compact usan desplegables nativos
Dashboard:
- Los chats de agente ya no desaparecen (una clave truncada escondía la mayoría)
- Enlaces directos:
CCV-Dashboard.html#open=<sesión>abre un chat esté donde esté, o avisa si no tiene página - Las columnas de texto (Name, Project, Category, UUID, Branch) ordenan de la A a la Z en el primer clic; una categoría Shorts o Archived desactivada en la configuración sigue visible mientras su carpeta tenga chats
- Los compacts se reconocen con el mismo criterio que en la página del chat
- Personalización local opcional: una carpeta
custom/(en gitignore) condashboard.css/dashboard.jsse embebe en el panel
Manager:
--only "id del chat"regenera solo ese chat (UUID, prefijo de hash o nombre) y lo abre, sin escanear todo- Reconfigure conserva los ajustes que no pregunta y guarda la configuración donde estaba
--currentsolo toma el proyecto de una carpeta que de verdad contiene la actual- Una instalación nueva ya no recibe la recomendación de regenerar con Force
- Un byte que no es UTF-8 en un log ya no aborta la ejecución, y Check updates admite etiquetas de versión con sufijo
Correcciones y robustez:
- Cinco valores tomados de los logs se escapan ahora en el HTML (se insertaban tal cual)
- Una carpeta Shorts/Archived con nombre vacío en la configuración ya no puede borrar las páginas generadas
- Eliminada una sintaxis exclusiva de Python 3.12 (presente desde la v2.3.0) que impedía arrancar los scripts en versiones anteriores de Python; probado con Python 3.13
- El catálogo de tipos de mensaje y de contenido conocidos sigue el formato actual del log de Claude Code
Calidad:
- La suite pasa de 230 a 284 tests y ejecuta ahora también el JavaScript de las páginas (botones de copiar, teclas N/P, la red de seguridad de la pantalla de carga, enlaces directos del panel) con Node
- README, SKILL y CONTRIBUTING alineados con el código, en los dos idiomas
Menú del manager:
- [5] Reconfigure — cambia los ajustes sin borrar
config.jsona mano: re-setup guiado (muestra los valores actuales y pide confirmación antes de sobrescribir), abrirconfig.jsonen tu editor, o hacerlo vía Claude Code - [6] Check updates — comprueba en GitHub si hay una versión más reciente, bajo demanda (la herramienta sigue siendo offline el resto del tiempo); avisa de una versión nueva estable (publicada hace ≥72h) con atajos a la página del release o a las instrucciones de actualización
- Menú agrupado visualmente (generar · vistas · utilidades); el countdown de cierre permite volver al menú (escribir algo + Enter), no solo cerrar directo
- El setup standalone ahora también pregunta el formato de hora (12h/24h), igual que el setup vía Claude Code
Visor de chats:
- Rewinds de conversación visibles: los rewinds reales se muestran como un marcador teal de una línea
↺ Rewind · N messages back · «destino»con un botón Go que lleva a donde se reanudó la conversación (se ignoran los forks de solo herramientas y los snapshots automáticos; "just above" cuando el destino queda justo encima del marcador) - Imágenes inline: los marcadores
[Image #N]del texto se convierten en chips clicables que abren la imagen en el modal (mapeado por orden de pegado) - Modal/lightbox de imágenes: el contenido de tipo
imagese abre en un overlay a pantalla completa (X / ESC / clic fuera), decodificado a blob URL; muestra tipo y peso - Marcadores del sistema formateados inline:
<system-reminder>en naranja (sin etiquetas),[Request interrupted by user]en rojo suave - Mensajes gemelos redundantes ocultos (el gemelo textual de una imagen y el de un rechazo de tool)
- Botón de copiar en cada mensaje (siempre visible, ✓ verde al copiar)
- Filtro "Messages only" junto al filtro de conversación (mantiene solo texto de usuario/asistente; se combina con el filtro de texto)
- Metadata del asistente: primero el modelo, luego la fecha/hora en negrita
- Fecha de creación en el header (
Created:), con formato ligado al ajuste de hora (24h → DD/MM/YYYY, 12h → MM/DD/YYYY) - Separador entre mensajes rediseñado como línea CSS adaptable (sin scroll horizontal en ventanas estrechas)
- La barra de estadísticas muestra un contador real de Rewinds (antes un conteo bruto de Snapshots)
- Toggle de tema de diffs Edit/Write más claro (previsualiza el tema actual; la etiqueta indica la acción)
- El título del chat recurre al título generado por IA (por encima del primer prompt, por debajo de
/renamey el summary) - Respuesta de AskUserQuestion rediseñada: la pregunta con su header como chip, las opciones ofrecidas con la elegida resaltada (y su descripción), las respuestas libres de "Other" mostradas tal cual, además de multi-select y notas — construido desde el resultado estructurado, robusto a cambios de wording
- Estado recordado entre refrescos (por chat): sobrevive a F5/atrás-adelante pero al reabrir el chat empieza limpio (se detecta el tipo de navegación, fiable aunque sessionStorage persista en file://). Guarda scroll, tema de los diffs Edit/Write, el selector user/bot/all, búsqueda + "Messages only" y qué bloques Edit/Write quedan abiertos (thinking y demás desplegables no-botón se resetean cerrados a propósito). Un breve overlay de carga oculta el salto de la restauración
- Los chats de agente se marcan: un chat abierto desde un subagente muestra un chip "AGENT CHAT" en su header, y los avisos de "agent completed" nombran qué agente corrió (
subagent_type · description) y enlazan a su chat (pestaña nueva) si su HTML existe - Los comandos enviados con "!" (el prompt bash de Claude Code) se renderizan como
! cmden rojo, con su stdout/stderr limpio
Accesibilidad:
- Contraste WCAG AA en el bloque de rewind (texto teal y botón Go)
- Modal de imagen: el botón de cerrar va sobre un disco translúcido con text-shadow (legible sobre cualquier imagen), área táctil 44×44 y anillo de foco visible; el modal es un
role="dialog"+aria-modalcon focus-trap y el foco vuelve al disparador al cerrar
Dashboard:
- Rediseño de la toolbar: botón Search (toggle), selector de ámbito ("Search names only") y botón Clear que resetea todo el estado guardado; responsive en dos breakpoints
- El modo Select se mantiene tras un refresco (las marcas de borrado individuales no — son transitorias a propósito)
- Chats de agente: los sub-chats lanzados por la herramienta Task (en
<sesión>/subagents/) se muestran con un toggle "Agents" en el grupo View (desactivado por defecto), con un contador en la barra de estado. Cada uno lleva un badge AGENT y se anida bajo su chat invocador con un conector└─sutil (en orden de invocación, pegado al ordenar); su nombre essubagent_type · description(ej. "Auditor · Auditar el login"). Los agentes huérfanos (invocador no generado) se agrupan en un desplegable al final. Los agentes de compactación y los fork de contexto se filtran - Cabecera de tabla fija (sticky, sin hueco al hacer scroll); las vistas BTW y Audit pasan a un menú "+" (misma pestaña, con header/footer compartido y enlace "← Back to Dashboard"); el informe de Audit tiene un botón "Delete this report"; la vista BTW se regenera en cada ejecución
- Consciente de la versión: tras una actualización minor/major el script recomienda un Force — todo se re-renderiza de forma consistente con la nueva versión (aplicando todos los fixes)
- Format Audit (
[4]/--audit): escanea chats recientes en busca de anomalías de formato y genera un informeCCV-Audit <fecha>.html— útil tras actualizar Claude Code - First prompt y nombres de chat más limpios: los mensajes no-reales (caveats, comandos, salida, notificaciones de tareas) ya no se cuelan
Setup:
- El setup inicial ahora pregunta
time_format(12h/24h), que además fija el formato de fecha del header
Calidad:
- Suite de tests pytest en
tests/que cubre parseo, renderizado, generación de chats, utilidades del dashboard y regresiones (fixtures sintéticas) - Correcciones de robustez: parseo defensivo de inputs de tools serializados como string (AskUserQuestion / MultiEdit) y timestamps no-string
Correcciones:
- Vista BTW: footer anclado al fondo; la columna de proyecto refleja ahora el directorio de trabajo de cada chat (igual que el dashboard) en vez del nombre de la carpeta
- Overlay del modal de imagen aclarado (55%) para que la conversación se intuya tras la imagen abierta
- Los mensajes en cola (enviados mientras Claude trabajaba) ahora se renderizan en vez de desaparecer en silencio
- Las respuestas de AskUserQuestion se reconocen de nuevo tras el cambio de wording del resultado en Claude Code
- Las notificaciones de agente en segundo plano fallido se muestran en rojo
- Los marcadores
[Image #N]no consecutivos (p. ej. #1 + #3) mapean a su imagen en vez de perderla - Espaciado vertical uniforme dentro de los bloques de tool Edit/Write (igual que el tool genérico y los bloques thinking)
- El botón Go del rewind alcanza destinos compact-summary y destinos ocultos por un filtro activo (limpia el filtro primero); aparece un toast visible si un destino no se localiza
- Los saltos user/bot/all parten ahora de la posición de scroll actual (fiable tras un Ctrl+F nativo o scroll manual)
Dashboard:
- Recap + First prompt como sub-filas desplegables bajo cada chat (desactivadas por defecto, toggles en Columns): el último resumen obtenible del chat y el primer mensaje íntegro; con búsqueda, pegadas a su fila al ordenar y persistidas en localStorage — inspirado en @marccane (#2)
- Selección y borrado: modo Select con checkboxes por fila y maestro marcar/desmarcar visibles; el modal Delete lista los chats afectados y genera un comando listo para copiar (pestañas PowerShell / macOS / Linux) que elimina el HTML y el
.jsonloriginal de cada chat — a papelera por defecto, permanente con el toggle — inspirado en @marccane (#2) - Ordenación universal de columnas: todas ordenables salvo el icono de enlace (Size por tamaño real en bytes, UUID alfabética)
General:
- Variable de entorno
CODE_CHAT_VIEWER_DIR: carpeta de salida alternativa, con precedencia sobreconfig.json— coautoría con @marccane (#2)
Visor de chats:
- Vista diff para Edit / MultiEdit:
old_stringynew_stringen dos columnas dentro del recuadro tool-use, con codificación de color rojo/verde. Tema oscuro por defecto y toggle de tema claro en la barra de búsqueda - Vista del tool Write: bloque colapsable full-width con acento azul, coherente con el
new_stringde Edit. El toggle compartidoEdits/Writesexpande/colapsa ambos a la vez - Expandir/contraer todos los bloques Edit y Write con un clic
- UUID del chat en el header: UUID completo de la sesión a la derecha del header del terminal, con texto seleccionable y botón SVG de copia con un clic (confirmación visual al copiar)
- Consultas
/btwinyectadas inline en cada chat (desde~/.claude/history.jsonl): pseudo-mensajes de usuario con estética crema Claude y un disclaimer sutil indicando que Claude no persiste la respuesta. Contador en la barra de estadísticas - Rechazos de usuario (
[REJECTED]con feedback, coral/rojo) y comentarios inline ([USER COMMENT], ámbar) - Resaltado de navegación por color para rechazos (rojo), junto a usuario/asistente/compact/respuesta
- Fecha completa en los timestamps de mensajes (
YYYY-MM-DD), con hora configurable 12h (AM/PM, por defecto) o 24h - Vista de chat más compacta: paddings, márgenes y tamaños de fuente reducidos en todo el visor, con el wrapper de tool-result refactorizado (mismo aspecto, menos espacio vertical)
- Botones del header rehechos (chat y dashboard): Feedback ahora abre los Issues de GitHub, y un nuevo botón Latest release lleva a la última versión para comprobar actualizaciones
- Versión de la app visible en el header (chat y dashboard)
Dashboard:
- Búsqueda de texto completo en nombres y UUIDs completos (no solo el texto truncado visible); nombres completos visibles en hover
- Botón de copiar UUID para acceso rápido al ID de sesión, y columna
UUIDahora permanente - Columna
BTW(opcional, desmarcada por defecto, ordenable): conteo de/btwpor chat - Vista BTW Queries (
[3]en el menú interactivo o flag--btw): agrega todas las consultas/btwdesde~/.claude/history.jsonlen unbtw.htmlstandalone, agrupadas por chat, con botón Expand/Collapse all y filtro en tiempo real - Layout de la tabla rehecho: anchos de columna fijos, columna Name flexible con mínimo razonable, scroll horizontal solo cuando las columnas visibles no caben y celdas a prueba de desbordes (adiós al espacio en blanco fantasma)
Correcciones:
- Las entradas snapshot (
[Snapshot saved: ...]) ahora respetan el filtro de búsqueda — antes permanecían visibles independientemente de lo buscado - Bloques especiales de usuario (respuestas, rechazos, comentarios) se filtran correctamente como mensajes de usuario en navegación
Visor de chats:
- Renderizado inteligente: comandos (
[COMMAND]), bloques compact (colapsables, morado), notificaciones de tareas (color por estado), respuestas de usuario (ámbar con Q&A y previews de markdown) - Resaltado de navegación por color según tipo: azul (usuario), verde (asistente), morado (compact), ámbar (respuesta)
- Filtro de exclusión en dashboard: ocultar filas por texto (complementario a la búsqueda)
- Flags CLI:
--current(auto-detectar sesión),--name(buscar por nombre),--force(regenerar todo) - Título del chat en el header del HTML (resuelto desde metadatos de sesión)
- Selección de modo interactiva (normal/force) en ejecución manual
Correcciones:
- Contador de summaries ahora detecta correctamente los summaries embebidos en mensajes de usuario
- Los saltos de línea
\r\nde Windows ya no causan espaciado extra en el HTML - Todas las variables HTML correctamente escapadas (protección XSS)
- Cláusulas
exceptgenéricas reemplazadas por excepciones específicas - Reglas CSS duplicadas consolidadas
- Imports no usados y código muerto eliminados
Visor de chats:
- Bloques de thinking colapsables con vista previa de la primera línea (plegados por defecto)
- Bloques de tool-use colapsables con contenido completo (sin truncar a 100 caracteres)
- Navegación multi-modo: Todos (icono degradado), Usuario (azul), Asistente (verde)
- Atajos de teclado: N (siguiente) y P (anterior) para navegar mensajes
- Animación de resaltado por color: azul para usuario, verde para asistente
- Scroll inteligente: centra mensajes cortos, fija al inicio los largos
- Layout compacto: reducidos padding, márgenes y line-height en todo el visor
- Líneas vacías compactas para una visualización más densa
- Los mensajes que solo contienen thinking/tools se saltan en la navegación
Dashboard:
- Persistencia de estado vía localStorage (5h TTL): recuerda orden, filtros, búsqueda y columnas visibles
- Timestamps precisos: siempre verifica el mtime del JSONL (sessions-index.json puede estar obsoleto)
- Conteos de mensajes reales extraídos directamente de archivos JSONL
- Enriquecimiento JSONL para chats no indexados (proyecto, rama, primer prompt, conteo de mensajes)
- Filtrado automático de entradas file-history-snapshot (sistema de undo de Claude Code)
- Limpieza de HTMLs huérfanos al detectar chats solo de snapshots
Correcciones:
- El estado de los filtros del dashboard ahora se guarda correctamente (bug de selector corregido)
- Contenido de mensajes centrado verticalmente en contenedores (eliminado espacio blanco inicial)
- El dashboard ahora muestra los títulos personalizados asignados con
/renameen todos los chats, incluyendo los no indexados en sessions-index.json
Funcionalidades:
- Layout fullscreen edge-to-edge sin bordes ni sombras
- Navegación por mensajes de usuario con botones prev/next y contador de posición
- Sincronización de scroll para el contador de navegación
- Animación de resaltado al navegar a un mensaje
- Conversión a zona horaria local para timestamps
- Generación inteligente de nombres de archivo (Chat YYYY-MM-DD HH-MM hash.html)
- La barra de estadísticas muestra fecha del chat en lugar de la de generación
- Chat Manager: generación por lotes, organización y panel interactivo
- Setup interactivo completo: todas las opciones configurables con defaults razonables
- Salida organizada: subcarpeta Chats/ con subcarpetas Shorts/ y Archived/
- Favicon embebido (oscuro, visible en pestañas del navegador) e icono de cabecera (claro)
- Apertura automática del panel en el navegador tras la generación
- Indicador de progreso del escaneo con resumen de archivos
- Navegación al panel: cada chat incluye un enlace "Volver al Dashboard"
- Botón de feedback integrado en encabezado y pie de página
- Filtro de conversación (reemplaza búsqueda genérica)
- Soporte para doble clic en Windows: los scripts se pausan antes de cerrarse
- Renombrado de "Claude Code Visualizer" a "Code Chat Viewer"
Correcciones:
- Seguridad: parámetros de tool_use escapados en HTML para prevenir inyección DOM
- Filtrado de mensajes fantasma "(no content)" de los internos de Claude Code
- Especificidad CSS: los mensajes de usuario se muestran correctamente en azul
- Estilos de tipos desconocidos corregidos dentro de mensajes de usuario
- Navegación instantánea (reemplazado smooth scrolling)
- Delay de reactivación de IntersectionObserver reducido a 100ms
- Tamaño de encabezado consistente entre las páginas de chat y el panel
No necesitas Claude Code para usar esta herramienta. Ambos scripts funcionan de forma independiente con Python — probados con Python 3.13 (las versiones anteriores no están verificadas).
Convertir un chat individual:
python scripts/visualizer.py ruta/al/chat.jsonl salida.htmlGeneración por lotes con panel:
python scripts/manager.pyEn la primera ejecución no hay config.json todavía, así que el manager lanza un setup interactivo — te pregunta dónde están tus chats de Claude Code (y algunas opciones) y crea config.json por ti. Sin editar nada a mano. Después solo lee config.json. (Si lo prefieres, puedes pre-crearlo desde la plantilla con cp config.example.json config.json.)
Flags CLI:
python scripts/manager.py --name "términos" # Abrir un chat específico por nombre
python scripts/manager.py --current # Abrir la sesión actual (auto-detecta desde CWD)
python scripts/manager.py --current ruta/al/chat.jsonl # Abrir el chat de ese archivo JSONL
python scripts/manager.py --only "id del chat" # Regenerar SOLO ese chat (UUID/hash/nombre) y abrirlo
python scripts/manager.py --force # Regenerar TODOS los chats
python scripts/manager.py --btw # Generar btw.html con todas tus preguntas /btw
python scripts/manager.py --audit 50 # Revisar el formato de los 50 chats más recientes (o: all)
python scripts/manager.py --force --name "mi chat" # Combinar flags--only funciona con los chats principales (por UUID, prefijo de hash o nombre); los sub-chats de agente se abren desde el panel.
En Windows, también puedes hacer doble clic en scripts/manager.py: la consola ofrece el menú (Normal, Force, BTW, Audit, Reconfigure, Check updates) y, al terminar, se cierra tras una cuenta atrás de 60 segundos (Enter la cierra al momento; escribe algo + Enter para volver al menú).
code-chat-viewer/
├── scripts/
│ ├── visualizer.py # Core: conversor JSONL a HTML
│ └── manager.py # Orquestador: generación por lotes + panel
├── tests/ # Suite pytest (parseo, render, panel, regresiones)
├── assets/ # Capturas del README
├── icon.png # Icono del proyecto (embebido como base64 en la salida)
├── config.example.json # Plantilla de configuración
├── config.json # Tu configuración (en gitignore, creada por setup)
├── custom/ # Ajustes locales opcionales del panel (en gitignore)
├── SKILL.md # Instrucciones de la skill para Claude Code
├── README.md # Este archivo
├── CONTRIBUTING.md # Guía de contribución
├── CODE_OF_CONDUCT.md # Código de conducta
└── LICENSE # Licencia MIT
~/Code Chat Viewer/ # Raíz de salida (configurable)
├── CCV-Dashboard.html # Panel interactivo
└── Chats/ # Archivos HTML generados
├── Chat 2026-01-30 ...html # Chats activos
├── Shorts/ # Chats pequeños inactivos (si está activado)
└── Archived/ # Chats inactivos antiguos (si está activado)
Claude Code almacena los logs de chat en formato JSONL en:
- Windows:
%USERPROFILE%\.claude\projects\ - Linux/Mac:
~/.claude/projects/
Una subcarpeta por proyecto. Cada archivo de chat tiene un nombre UUID (ej: c5f2a3e1-1234-5678-9abc-def012345678.jsonl); los sub-chats de agente están en <uuid-del-chat>/subagents/.
- Mensajes de usuario: Azul (
#0066CC) con fondo azul claro (#F8FBFF) - Mensajes del asistente: Verde (
#10893E) con fondo verde claro (#FAFFF8) - Comandos: Azul (
#0066CC) con etiqueta[COMMAND]y fondo azul más marcado (#EBF2FF) - Respuestas del usuario: Ámbar (
#D97706) con layout Q&A, previews de markdown y etiqueta[USER RESPONSE] - Rechazos del usuario: Coral/rojo (
#DC2626) con etiqueta[REJECTED]y feedback del usuario cuando se proporciona (fondo#FFF1F2) - Comentarios del usuario: Ámbar (
#D97706) con etiqueta[USER COMMENT]para comentarios inline en acciones aceptadas - Bloques compact: Morado (
#8B5CF6) colapsables agrupando summary + salida pre-compact - Notificaciones de tareas: Color por estado — verde (completada), rojo (fallida), azul (en progreso), gris (otro)
- Resultados de herramientas: Naranja (
#FF6B00) con fondo gris (#F8F8F8) - Bloques de pensamiento: Fondo blanco con borde gris sutil y sombra
- Bloques tool use: Gris oscuro (
#48484A) con texto claro (#E8E8E8) - System reminders (
<system-reminder>): Texto naranja, etiquetas eliminadas - Interrupciones del usuario (
[Request interrupted by user]): Fondo rojo suave con texto rojo
Las contribuciones son bienvenidas. Por favor lee CONTRIBUTING.md para detalles sobre nuestro código de conducta y el proceso para enviar pull requests.
Este proyecto está licenciado bajo la Licencia MIT - ver el archivo LICENSE para más detalles.
Requisitos de atribución:
- Mantener el archivo LICENSE intacto
- Acreditar al autor original: Óscar González Martín
- Enlazar al repositorio original: https://github.com/oskar-gm/code-chat-viewer
- Indicar cualquier modificación realizada
Óscar González Martín
- Sitio web: nucleoia.es
- Email: oscar@nucleoia.es
- GitHub: @oskar-gm
- LinkedIn: oscar-gonz
Si este proyecto te resulta útil, por favor:
- Dale una estrella al repositorio
- Reporta bugs vía Issues
- Sugiere mejoras
- Compártelo con otros
Para preguntas, sugerencias o reportar bugs:
- Email: oscar@nucleoia.es
- GitHub Issues: Reportar aquí
© 2025-2026 Óscar González Martín. All rights reserved under MIT License.




