There are three ways to get a conversation out of Claude Code, depending on whether you want something to read, something to keep, or something a script can use.
1. The built-in way: /export
Inside the session you want:
/exportThis opens a menu to copy the conversation to your clipboard or save it as a plain-text file, with messages and tool output rendered so a person can read them. To skip the menu and write straight to a file:
/export auth-refactor-notes.txtThis is the right choice for pasting into a doc, a pull request description, or a ticket.
2. For a script: ask the session directly
To get structured output from a session, including one you're not in, ask it a question in headless mode:
claude -p --resume <session-id> --output-format json "summarize what we changed and why" | jq -r '.result'You get the answer plus the session ID, usage and cost as JSON. This is the method Anthropic recommends for scripts, because it doesn't depend on the transcript file format.
3. Any session to Markdown
Every session is saved as JSON lines at ~/.claude/projects/<project>/<session-id>.jsonl. This script converts one to Markdown: your prompts and Claude's replies, with tool calls noted in one line each. It skips anything it doesn't recognize, so a format change degrades it instead of breaking it.
#!/usr/bin/env python3
"""Convert a Claude Code session transcript (.jsonl) to Markdown. Usage: to_md.py <session.jsonl> > out.md"""
import json, sys
for line in open(sys.argv[1], errors="ignore"):
try:
d = json.loads(line)
except ValueError:
continue
msg = d.get("message") or {}
role, content = msg.get("role"), msg.get("content")
if d.get("isSidechain") or role not in ("user", "assistant"):
continue
if isinstance(content, str):
print(f"## {'You' if role == 'user' else 'Claude'}\n\n{content}\n")
continue
for block in content or []:
kind = block.get("type")
if kind == "text" and block.get("text", "").strip():
print(f"## {'You' if role == 'user' else 'Claude'}\n\n{block['text']}\n")
elif kind == "tool_use":
target = (block.get("input") or {}).get("file_path") or (block.get("input") or {}).get("command", "")
print(f"> Tool: {block.get('name')} {str(target)[:120]}\n")Find the file for a session with:
find ~/.claude/projects -name '*.jsonl' -mtime -2Two cautions:
- The format is internal. Anthropic says so in the docs, and it changes between versions. Treat any parser as best effort.
- Transcripts are deleted after 30 days by default. Export anything you want to keep before then, or raise
cleanupPeriodDays. See why Claude Code sessions disappear.
Which one to use
| You want | Use |
|---|---|
| To paste a conversation somewhere | /export |
| A summary or answer from an old session | claude -p --resume <id> |
| A full, readable archive of many sessions | The Markdown script, run over ~/.claude/projects |
If what you actually want is the record of your work rather than the raw conversation, Shabash keeps every session, groups them into threads per project, and writes up what shipped with links back to the sessions it came from.