Convert Claude Code and Codex session files (JSON or JSONL) to clean, mobile-friendly HTML pages with pagination.
Example transcript produced using this tool.
Read A new way to extract detailed transcripts from Claude Code for background on this project.
Install this tool using uv (installs the llm-transcripts command):
uv tool install claude-code-transcriptsOr run it without installing:
uvx --from claude-code-transcripts llm-transcripts --helpTo make the command available globally from this repo checkout:
uv tool install --editable .If llm-transcripts is not found, ensure your tool bin directory is on PATH
(usually ~/.local/bin on macOS/Linux):
export PATH="$HOME/.local/bin:$PATH"Alternative:
pipx install -e .This tool converts Claude Code or Codex session files into browseable multi-page HTML transcripts.
Select an agent by passing it before the command, or set LLM_AGENT:
llm-transcripts claude local
llm-transcripts codex local
# Or set once for all commands
export LLM_AGENT=claude
llm-transcripts localExamples below assume LLM_AGENT is set; otherwise pass the agent first (e.g., llm-transcripts codex local).
There are six commands available:
local(default) - select from local sessions (~/.claude/projectsor~/.codex/sessions)web- select from web sessions via the Claude API (Claude only)json- convert a specific JSON or JSONL session fileall- convert all local sessions to a browsable HTML archivereindex- rebuild the local SQLite conversations indexserve- start the local search API and web UI
The quickest way to view a recent local session:
LLM_AGENT=claude llm-transcriptsThis shows an interactive picker to select a session, generates HTML, and opens it in your default browser.
All commands support these options:
-o, --output DIRECTORY- output directory (default: writes to temp dir and opens browser)-a, --output-auto- auto-name output subdirectory based on session ID or filename--repo OWNER/NAME- GitHub repo for commit links (auto-detected from git push output if not specified)--open- open the generatedindex.htmlin your default browser (default if no-ospecified)--gist- upload the generated HTML files to a GitHub Gist and output a preview URL--json- include the original session file in the output directory
The generated output includes:
index.html- an index page with a timeline of prompts and commitspage-001.html,page-002.html, etc. - paginated transcript pages
Local sessions are stored as JSONL files in ~/.claude/projects (Claude) or ~/.codex/sessions (Codex). Run with no arguments to select from recent sessions:
llm-transcripts
# or explicitly:
llm-transcripts localUse --limit to control how many sessions are shown (default: 10):
llm-transcripts local --limit 20Start the local web UI and search API:
export LLM_AGENT=claude
llm-transcripts serveIf you haven't set LLM_AGENT, pass the agent first (for example, llm-transcripts codex serve).
Then open the UI in your browser:
http://127.0.0.1:3010/The index page supports ?sort=created|published. You can customize the host/port or source directory:
llm-transcripts serve --host 0.0.0.0 --port 4000 --source ~/.claude/projectsImport sessions directly from the Claude API:
# Interactive session picker
llm-transcripts web
# Import a specific session by ID
llm-transcripts web SESSION_ID
# Import and publish to gist
llm-transcripts web SESSION_ID --gistWeb sessions are only available for the Claude agent.
On macOS, API credentials are automatically retrieved from your keychain (requires being logged into Claude Code). On other platforms, provide --token and --org-uuid manually.
Use the --gist option to automatically upload your transcript to a GitHub Gist and get a shareable preview URL:
llm-transcripts --gist
llm-transcripts web --gist
llm-transcripts json session.json --gistThis will output something like:
Gist: https://gist.github.com/username/abc123def456
Preview: https://gisthost.github.io/?abc123def456/index.html
Files: /var/folders/.../session-id
The preview URL uses gisthost.github.io to render your HTML gist. The tool automatically injects JavaScript to fix relative links when served through gisthost.
Combine with -o to keep a local copy:
llm-transcripts json session.json -o ./my-transcript --gistRequirements: The --gist option requires the GitHub CLI (gh) to be installed and authenticated (gh auth login).
Use -a/--output-auto to automatically create a subdirectory named after the session:
# Creates ./session_ABC123/ subdirectory
llm-transcripts web SESSION_ABC123 -a
# Creates ./transcripts/session_ABC123/ subdirectory
llm-transcripts web SESSION_ABC123 -o ./transcripts -aUse the --json option to include the original session file in the output directory:
llm-transcripts json session.json -o ./my-transcript --jsonThis will output:
JSON: ./my-transcript/session_ABC.json (245.3 KB)
This is useful for archiving the source data alongside the HTML output.
Convert a specific session file directly:
llm-transcripts json session.json -o output-directory/
llm-transcripts json session.jsonl --openThis works with JSONL files in ~/.claude/projects/ or ~/.codex/sessions/ and JSON session files extracted from Claude Code for web.
The json command can take a URL to a JSON or JSONL file as an alternative to a path on disk.
Convert all your local sessions to a browsable HTML archive:
llm-transcripts allThis creates a directory structure with:
- A master index listing all projects
- Per-project pages listing sessions
- Individual session transcripts
Options:
-s, --source DIRECTORY- source directory (default:~/.claude/projectsor~/.codex/sessions)-o, --output DIRECTORY- output directory (default:./claude-archiveor./codex-archive)--include-agents- include agent session files (excluded by default)--dry-run- show what would be converted without creating files--open- open the generated archive in your default browser-q, --quiet- suppress all output except errors
Examples:
# Preview what would be converted
llm-transcripts all --dry-run
# Convert all sessions and open in browser
llm-transcripts all --open
# Convert to a specific directory
llm-transcripts all -o ./my-archive
# Include agent sessions
llm-transcripts all --include-agentsRun everything from the repo root using uv:
# install dev dependencies
uv sync --dev
# run tests
uv run pytest
# run the CLI from source
uv run llm-transcripts --help
# format code
uv run black .