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
.jsonlfiles, 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.
� Supported formats
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
.jsonlfiles in the Explorer (Ctrl/Cmd+ click), right-click, Chat History: Compare as Side-by-Side.
File layout convention
The default parser locates sub-agent transcripts by probing several common on-disk layouts, in this order, until one matches:
<dir>/<session>.jsonl # parent
<dir>/<session>/subagents/agent-XXXX.jsonl # canonical
<dir>/<session>/agent-XXXX.jsonl # flattened (newer)
<dir>/subagents/agent-XXXX.jsonl # shared sibling dir
<dir>/agent-XXXX.jsonl # flat sibling
Sub-agent references are detected via three independent channels (most specific wins):
providerData.toolResult.subAgent.sessionIdon afunction_call_result- Trailing
[Agent ID: agent-xxxx]text inside the tool output Agenttool calls witharguments.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