Chat History Viewer
Read your AI agent's session logs the way they were meant to be read.
A VS Code extension that turns raw .jsonl agent transcripts into a clean,
inspectable, searchable conversation — with first-class support for
sub-agent linking and side-by-side multi-session comparison on a
shared timeline.
Install ·
Features ·
Getting started ·
Configuration ·
FAQ
Why?
If you've ever opened an AI agent's chat-history .jsonl file in a plain
editor, you've seen this:
{"id":"chatcmpl-abc","parentId":"...","timestamp":1782133268740,"type":"function_call",
"providerData":{"messageId":"…","model":"…","argumentsDisplayText":"subagent_type: …"},
"callId":"tooluse_x9fHWvn496nS0JPI4QYdiB","name":"Read","arguments":"{\"file_path\": …}",
"sessionId":"…","cwd":"…"}
…one giant unreadable line per message, sub-agent calls scattered across
sibling files, no way to tell which assistant turn produced which tool call.
Chat History Viewer parses these files, normalizes them into a uniform
conversation model, and renders them as messages — with markdown, tool
arguments, sub-agent links, and a timeline view for multi-session debugging.
Features
🧵 Single-session view
- Per-message inspection: type · timestamp · id · role · tool name ·
tool arguments — all visible at a glance, click an id to copy.
- Markdown rendering for assistant text and tool results, with
auto-collapse of long blocks and an inline expand/collapse toggle.
- Bulk selection & hide: tick messages, hide them to declutter, then
Show hidden / Restore all to bring them back.
- Type filter chips (USER, ASSISTANT, TOOL CALL, TOOL RESULT, SNAPSHOT,
OTHER) and a free-text search across id / text / tool name / arguments.
- Search with context: when you find a match, ±N surrounding messages
are kept visible so you can read the up- and down-stream conversation
without losing the filter. Adjustable from "match only" up to "all".
- Raw JSON drawer on every message for when you really need to dig in.
- Full IME support — Chinese / Japanese / Korean input works correctly
in the filter box.
🔗 Sub-agent linking
When an Agent tool invokes a sub-agent, the viewer detects the link via
three independent channels and resolves the sub-agent's .jsonl file. Click
▶ Open sub-agent on the tool call and the sub-session opens as a new
tab, with breadcrumbs back to the parent.
📊 Side-by-side compare mode
Open N sessions as columns sharing a single time axis. Messages from
every session interleave in real chronological order, with idle gaps
collapsed into compact ↕ gap 12m separators so you can see who was doing
what while another session waited.
time col1: main col2: planner col3: vision-reader
10:01:23 user: 帮我...
10:01:25 assistant: ok…
10:01:30 ▶ Agent ─────────▶ … ·
10:01:42 user: … ·
10:01:55 assistant: … ·
↕ gap 4m
10:05:31 tool_result · user: 截图描述
10:05:48 assistant: … · assistant: …
Two entry points:
- Command palette → Chat History: Compare Multiple Sessions…
- Explorer: select several
.jsonl files, right-click →
Chat History: Compare as Side-by-Side
Once you're in compare mode, clicking a ▶ Open sub-agent link appends
the sub-agent as a new column to the right so you can watch parent and
child agents collaborate on the same timeline.
Out of the box this extension parses CodeBuddy / Claude-Code style
JSONL transcripts. Support for additional formats (Cursor sessions,
OpenAI Assistants logs, …) is on the roadmap.
Install
- From a
.vsix (recommended for now):
code --install-extension chat-history-viewer-<version>.vsix
- Or, search "Chat History Viewer" in the VS Code Extensions view
(publisher:
devoszhang).
Getting started
Open a single session
Three ways, pick whichever is closest to where you are:
| Where you are |
How to open |
.jsonl file in the Explorer |
Right-click → Chat History: Open Current File |
.jsonl file already open in the editor |
Editor title bar → same command, or the Reopen Editor With… menu and pick Chat History Viewer |
| Nowhere in particular |
⌘⇧P / Ctrl+Shift+P → Chat History: Open JSONL… |
Compare multiple sessions
- Command palette: Chat History: Compare Multiple Sessions…, then
multi-select the files in the dialog.
- Or, multi-select
.jsonl files in the Explorer (Ctrl/Cmd + click),
right-click, Chat History: Compare as Side-by-Side.
File layout convention
The default parser expects sub-agent files to live next to the parent:
<dir>/<session>.jsonl
<dir>/<session>/subagents/agent-XXXX.jsonl
Sub-agent references are detected via three independent channels (most
specific wins):
providerData.toolResult.subAgent.sessionId on a function_call_result
- Trailing
[Agent ID: agent-xxxx] text inside the tool output
Agent tool calls with arguments.subagent_type (provides the label;
id is resolved from the matching result)
Configuration
| Setting |
Default |
Description |
chatHistoryViewer.markdownCollapseThresholdLines |
12 |
Collapse a rendered message when it exceeds this many lines. |
chatHistoryViewer.markdownCollapseThresholdChars |
600 |
Collapse a message when its raw text exceeds this many characters. |
FAQ
Q. My .jsonl file is huge (10MB+). Will this hang VS Code?
No — the parser is streaming-friendly and the webview keeps the original
records in memory but only renders visible messages. Files in the 100k-line
range render in well under a second.
Q. Can I edit messages in this view?
No, this is a read-only viewer. The original .jsonl is never written to.
Use open source in the toolbar to jump to the raw file if you need to
edit.
Q. The Chinese / Japanese / Korean filename in the tab is showing
%E9%9C%80...?
Fixed in 0.1.0 — file basenames are URL-decoded before being displayed.
Q. Does compare mode work with sub-agents?
Yes, and it's where compare mode shines. Open a parent session, switch to
compare view via the tab bar's ⇆ button, then click any ▶ Open sub-agent
to append it as a new column.
Roadmap
- Proportional timeline mode (row height ∝ real time elapsed)
- Column-width drag handles in compare mode
- Export filtered conversation to Markdown
- Built-in parsers for Cursor and OpenAI Assistants logs
License
Released under the MIT License. See the LICENSE file shipped with
the extension for the full text.
© devoszhang