Convert local Codex session archives from ~/.codex/sessions into readable Markdown transcripts.
The converter reads a Codex .jsonl session file and renders:
- user messages
- Codex messages
- shell commands run
- command status, exit code, and captured output
This is useful when you want a readable record of a Codex session after restarting your machine, resuming a session, or closing the TUI.
Here's an example of working on some changes on Codex Convos itself.
Below you can see part of the exported conversation, Codex comments in yellow, user comments in blue.
It collapses low value read/discovery "noise" commands (such as sed, rg etc) which it uses to read files and those are then viewable by expanding the section.
Other more useful commands to view are not shown in a collapsed area.
codex_session_to_markdown.py: converts one Codex session.jsonlfile into Markdownlist-codex-convos.sh: prints the 10 most recent Codex session.jsonlfilesget-codex-convo.sh: exports a chosen session, or the newest one by defaultconvos/: default output directory for generated Markdown transcripts
- Python 3
- Codex CLI sessions already present under
~/.codex/sessions fzfif you want the interactivegetccselector function
The scripts are intended to work on both Linux and macOS.
--openprefers Google Chrome on both platforms and falls back to the platform default opener if Chrome is unavailable- the
getccshell helper below is written to work inzshas well asbash
Add this to your shell config, for example ~/.bashrc or ~/.zshrc and change ~/Projects/codex-convos as needed:
function getcc() {
local repo=~/Projects/codex-convos
local selected
local convo_path
selected="$("$repo/list-codex-convos.sh" | fzf --ansi --no-sort --layout=reverse-list --delimiter=$'\t' --with-nth=1)" || return 1
[[ -n "$selected" ]] || return 1
convo_path="${selected##*$'\t'}"
"$repo/get-codex-convo.sh" --open "$convo_path"
}After reloading your shell:
getccThat shows the 10 most recent session files in fzf, lets you choose one, then exports it to:
~/Projects/codex-convos/convos/<same-session-name>.md
The fzf list is newest-first, with the newest session at the top and initially selected. The orange timestamp shown is the session file's modified time, so the displayed order matches the sort order. Each entry is shown like:
12th Apr @ 14:59:32 : When I do this and that...
On selecting one of the Codex conversations it converts it to Markdown and opens it in Chrome.
Export the newest available session file:
~/Projects/codex-convos/get-codex-convo.shConvert a specific session file:
~/Projects/codex-convos/get-codex-convo.sh \
~/.codex/sessions/2026/04/11/<filename>.jsonlExport a session and open the generated Markdown in Chrome:
~/Projects/codex-convos/get-codex-convo.sh --open \
~/.codex/sessions/2026/04/11/<filename>.jsonlList the 10 newest session files with a readable label and the underlying path:
~/Projects/codex-convos/list-codex-convos.shIf you want direct control of the underlying Python converter, it still works:
python3 ~/Projects/codex-convos/codex_session_to_markdown.py \
~/.codex/sessions/2026/04/11/<filename>.jsonl \
-o ~/Projects/codex-convos/convos/session.mdYou can also skip command history and export only the conversation:
python3 ~/Projects/codex-convos/codex_session_to_markdown.py \
~/.codex/sessions/2026/04/11/<filename>.jsonl \
--skip-commands \
-o ~/Projects/codex-convos/convos/session.md