{"id":50887855,"url":"https://github.com/chezou/chat2html","last_synced_at":"2026-06-15T18:32:37.665Z","repository":{"id":352926732,"uuid":"1217250612","full_name":"chezou/chat2html","owner":"chezou","description":"Share-conscious HTML exporter for Claude/Codex conversations","archived":false,"fork":false,"pushed_at":"2026-04-28T17:31:04.000Z","size":1865,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-04T02:18:26.573Z","etag":null,"topics":["claude","claude-code","cli","python","uv"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chezou.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-21T17:40:55.000Z","updated_at":"2026-04-28T17:25:18.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/chezou/chat2html","commit_stats":null,"previous_names":["chezou/chat2html"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/chezou/chat2html","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chezou%2Fchat2html","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chezou%2Fchat2html/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chezou%2Fchat2html/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chezou%2Fchat2html/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chezou","download_url":"https://codeload.github.com/chezou/chat2html/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chezou%2Fchat2html/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34376122,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-15T02:00:07.085Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["claude","claude-code","cli","python","uv"],"created_at":"2026-06-15T18:32:36.632Z","updated_at":"2026-06-15T18:32:37.646Z","avatar_url":"https://github.com/chezou.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# chat2html\n\nShare-conscious HTML exporter for AI coding-assistant conversations (Claude and Codex).\n\n## Why chat2html?\n\n- **Four formats, one tool** — Auto-detects Claude Code JSONL, claude.ai exports, claude-chat-exporter Markdown, and OpenAI Codex CLI JSONL.\n- **Safer sharing defaults** — Tool results are omitted and OAuth URLs (with `state`, `code`, `token`, callback paths) are redacted by default. Use `--full` only when you need the full picture for yourself.\n- **Self-contained output** — One HTML file with light/dark themes, syntax highlighting, and collapsible thinking blocks and long pastes.\n- **Zero install** — `uvx chat2html session.jsonl`.\n\n## Supported input formats (auto-detected)\n\n1. **claude.ai export** (`conversations.json` / `.jsonl`)\n   - Downloadable from Settings → Privacy → Export data (inside the ZIP).\n   - Contains multiple conversations — pick them by listing, searching, or index.\n\n2. **Claude Code session** (`~/.claude/projects/\u003cproj\u003e/*.jsonl`)\n   - Line-based logs with `type` / `uuid` / `sessionId`.\n   - Renders tool-use history (Bash / Read / Edit / Agent, etc.).\n   - `thinking` blocks and long `tool_result` outputs are collapsed into `\u003cdetails\u003e`.\n\n3. **claude-chat-exporter.js Markdown** (`.md`)\n   - See \u003chttps://github.com/agarwalvishal/claude-chat-exporter\u003e.\n   - Uses `## Human (date):` / `## Claude:` headers.\n\n4. **OpenAI Codex CLI session** (`~/.codex/sessions/*.jsonl`)\n   - Line-based logs with top-level `{timestamp, type, payload}`.\n   - Renders user / assistant text, `function_call` + `function_call_output` pairs (e.g. `exec_command`), and `custom_tool_call` (e.g. `apply_patch`).\n   - Encrypted reasoning is omitted; visible `reasoning.summary` is rendered as a `thinking` block.\n\n## Quickstart\n\nRun directly from PyPI with `uv` — no install required:\n\n```sh\nuvx chat2html session.jsonl\n```\n\nThe examples below use `chat2html` as shorthand for the command above.\n\n## Usage\n\n```sh\n# Auto-detect format (Claude Code JSONL / Markdown)\nchat2html session.jsonl\nchat2html conversation.md\nchat2html session.jsonl -o out.html\n\n# claude.ai export: list conversations\nchat2html conversations.json\n\n# claude.ai export: search by title\nchat2html conversations.json -s \"API\"\n\n# claude.ai export: convert by index\nchat2html conversations.json -i 0,3,7 -d out/\n\n# claude.ai export: convert all\nchat2html conversations.json --all -d out/\n\n# Batch multiple files (Markdown / Claude Code JSONL)\nchat2html a.md b.jsonl -d out/\n\n# Directory: pick logs interactively from a TUI list\nchat2html ~/.claude/projects/myproj -d out/\n\n# Directory: convert everything underneath without the picker\nchat2html ~/.codex/sessions/2026/04 --all -d out/\n```\n\n### Directory mode (TUI picker)\n\n\u003cimg src=\"assets/chat2html_screen.gif\" alt=\"chat2html directory mode TUI picker demo\" width=\"700\" /\u003e\n\nPass a directory and chat2html will walk it for `.md` / `.jsonl` files,\ndrop anything that isn't a supported chat log, and show a multi-select\nlist (↑↓ to move, Space / `x` to toggle, Enter to confirm, Esc / `q` to\nquit). Entries are sorted newest-first by mtime, with a one-line\npreview of the first user message (housekeeping slash-commands like\n`/clear` are skipped so they don't become the preview text). Combine\nwith `--all` to skip the picker and convert every log under the\ndirectory.\n\nPress `Tab` in the picker to cycle the column focus through three\nmodes: balanced view, filename-focused (drop the preview, expand the\nname to its relative path under the walk root so `proj-a/session.jsonl`\nand `proj-b/session.jsonl` are distinguishable), and snippet-focused\n(drop the filename to read more of the first user message — the\npreview cache holds up to ~250 characters).\n\nTwo safety caps keep the picker manageable when pointed at a deep tree\nlike `~/.claude` or `~/.codex`:\n\n- `--depth N` — max recursion depth from the given root\n  (`0` = root only, default `5`).\n- `--max-files N` — cap the list at the N most-recent files\n  (`0` = no cap, default `200`). When entries are dropped, a notice is\n  printed to stderr.\n\n## Options\n\n| Option | Description |\n| --- | --- |\n| `-o`, `--output` | Output file path (single conversation only). |\n| `-d`, `--outdir` | Output directory. |\n| `-s`, `--search` | Search conversations by title (claude.ai export). |\n| `-i`, `--index` | Comma-separated indices to convert (claude.ai export, e.g. `0,2,5`). |\n| `--all` | Convert all conversations (claude.ai export) or every log under a directory (directory mode). |\n| `--depth N` | Directory mode: max recursion depth from the given root (`0` = root only, default: `5`). |\n| `--max-files N` | Directory mode: cap the picker list at the N most-recent files (`0` = no cap, default: `200`). |\n| `--lang {ja,en}` | Output language (default: `en`). |\n| `--full` | Show full tool input/output. By default, `tool_result` is omitted and `tool_use` only shows description-like fields for safer sharing. OAuth-related URLs are always masked, even with `--full`. |\n\n## ⚠️ What chat2html does NOT protect against\n\nchat2html redacts OAuth URLs and omits tool results by default, but it is **not a general-purpose secret scrubber**. Before sharing any output, you should still review it for:\n\n- API keys and tokens (e.g., `sk-ant-...`, `ghp_...`) that may appear in tool inputs or assistant text\n- Personal file paths (`/Users/yourname/...`, `C:\\Users\\...`)\n- Internal hostnames, repository names, or IP addresses\n- PII in pasted content (emails, phone numbers, etc.)\n- Long pastes are collapsed into `\u003cdetails\u003e` but **still present in the HTML source** — they're hidden visually, not removed.\n\nIf you need stronger guarantees, consider running a secret scanner (e.g., `gitleaks`, `trufflehog`) on the output before sharing.\n\n### Extra safety: scan the output before sharing\n\nchat2html does not detect arbitrary secrets like API keys or tokens embedded in conversation content. If you're sharing with a wide audience, pipe the output through a dedicated secret scanner:\n\n- **[gitleaks](https://github.com/gitleaks/gitleaks)** — `gitleaks dir out.html -v`\n- **[trufflehog](https://github.com/trufflesecurity/trufflehog)** — `trufflehog filesystem out.html`\n\nBoth are open-source CLIs available via Homebrew and most package managers.\n\n## Development\n\n```sh\nuv sync --all-groups        # install runtime + dev dependencies\nuv run pytest               # run the test suite\nuv run ruff check .         # lint\nuv run ruff format .        # auto-format\nuv run pre-commit install   # install the git hook (one-time per clone)\n```\n\n`pre-commit` runs `ruff` (lint + format) and a few hygiene checks\n(trailing whitespace, EOF newline, TOML/YAML syntax, large-file guard)\non every commit; see `.pre-commit-config.yaml`. CI runs `ruff check`,\n`ruff format --check`, and `pytest` on every push and PR\n(see `.github/workflows/ci.yml`).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchezou%2Fchat2html","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchezou%2Fchat2html","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchezou%2Fchat2html/lists"}