Convert your Claude transcripts to markdown and post them as a gist.
Find a file
2026-08-22 10:45:51 +02:00
.gitignore feat: initial version with gist support 2026-08-22 10:45:51 +02:00
.golangci.yml feat: initial version with gist support 2026-08-22 10:45:51 +02:00
convert.go feat: initial version with gist support 2026-08-22 10:45:51 +02:00
convert_test.go feat: initial version with gist support 2026-08-22 10:45:51 +02:00
gist.go feat: initial version with gist support 2026-08-22 10:45:51 +02:00
gist_test.go feat: initial version with gist support 2026-08-22 10:45:51 +02:00
go.mod feat: initial version with gist support 2026-08-22 10:45:51 +02:00
main.go feat: initial version with gist support 2026-08-22 10:45:51 +02:00
README.md feat: initial version with gist support 2026-08-22 10:45:51 +02:00
record.go feat: initial version with gist support 2026-08-22 10:45:51 +02:00

claude2md

Convert a Claude Code session .jsonl transcript to readable Markdown.

Session logs live in ~/.claude/projects/<slugged-cwd>/<session-id>.jsonl.

Install

go install code.bas.es/marcus/claude2md@latest

Or build in-tree: go build -o claude2md .

Usage

claude2md ~/.claude/projects/-home-marcus-Source-springchick/<session-id>.jsonl
claude2md -o transcript.md session.jsonl
claude2md --no-thinking --max-result 500 session.jsonl -o short.md
cat session.jsonl | claude2md - > out.md

Default output path is the input with .md instead of .jsonl. - means stdin/stdout.

Flag Default Meaning
-o <input>.md Output file; - for stdout
-images <output>-images/ Directory for extracted images
-no-images off Leave placeholders instead of writing image files
-no-thinking off Omit thinking blocks
-no-tools off Omit tool calls and their results
-max-result 2000 Truncate tool inputs/results to N chars (0 = unlimited)
-q off No summary line on stderr
-gist off Publish as a secret gist, images included; prints the URL
-gist-public off Make that gist public instead
-gist-desc Claude Code transcript — <file> Gist description
-gist-open off Open the gist in a browser

Publishing to a gist

claude2md -gist session.jsonl                      # secret gist, prints URL
claude2md -gist -gist-public -no-thinking s.jsonl  # public, no thinking blocks
claude2md -gist -o keep.md session.jsonl           # publish and keep a local copy

Secret by default — transcripts carry source, paths, and command output. Secret only means unguessable, not private: anyone with the URL can read it.

Needs the gist CLI, logged in via gist --login. The gist API is text-only, so images cannot go through it; when a transcript has screenshots claude2md also needs git with push access to git@gist.github.com (the same SSH key as GitHub). It then:

  1. creates the gist with a stub,
  2. clones its git remote, commits the markdown plus every image, pushes,
  3. links the images at gist.githubusercontent.com/<user>/<id>/raw/<name>.

If the owner is missing from the returned URL, gh api user supplies it. Without images only step 1 runs, and neither git nor gh is needed.

Nothing is written locally in -gist mode unless you pass -o; images go to a temp dir that is removed on exit.

Output shape

  • ## 👤 User / ## 🤖 Assistant headings with local-time stamps.
  • Records that stream one assistant response (shared requestId) collapse under a single heading.
  • Thinking blocks and tool results go in <details> so the conversation reads straight through.
  • Tool results attach to the call that produced them rather than appearing as user turns.
  • Base64 images are written out as files and linked; they are the bulk of a transcript's size (a 17 MB .jsonl is typically ~350 KB of Markdown plus a few MB of screenshots).
  • Bookkeeping records (mode, ai-title, attachment, file-history-*, …) are dropped.