codex-transcript-viewer 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- codex_transcript_viewer-0.4.0/.gitignore +8 -0
- codex_transcript_viewer-0.4.0/CHANGELOG.md +42 -0
- codex_transcript_viewer-0.4.0/LICENSE +21 -0
- codex_transcript_viewer-0.4.0/PKG-INFO +122 -0
- codex_transcript_viewer-0.4.0/README.md +100 -0
- codex_transcript_viewer-0.4.0/pyproject.toml +39 -0
- codex_transcript_viewer-0.4.0/scripts/audit_sessions.py +536 -0
- codex_transcript_viewer-0.4.0/scripts/visual_review.py +155 -0
- codex_transcript_viewer-0.4.0/src/codex_transcript_viewer/__init__.py +0 -0
- codex_transcript_viewer-0.4.0/src/codex_transcript_viewer/cli.py +81 -0
- codex_transcript_viewer-0.4.0/src/codex_transcript_viewer/formatting.py +23 -0
- codex_transcript_viewer-0.4.0/src/codex_transcript_viewer/html_builder.py +769 -0
- codex_transcript_viewer-0.4.0/src/codex_transcript_viewer/markdown.py +156 -0
- codex_transcript_viewer-0.4.0/src/codex_transcript_viewer/parser.py +1204 -0
- codex_transcript_viewer-0.4.0/src/codex_transcript_viewer/style.css +589 -0
- codex_transcript_viewer-0.4.0/src/codex_transcript_viewer/viewer.js +63 -0
- codex_transcript_viewer-0.4.0/tests/test_audit_sessions.py +137 -0
- codex_transcript_viewer-0.4.0/tests/test_custom_tools.py +56 -0
- codex_transcript_viewer-0.4.0/tests/test_exec_status.py +71 -0
- codex_transcript_viewer-0.4.0/tests/test_html_builder.py +54 -0
- codex_transcript_viewer-0.4.0/tests/test_image_budget.py +45 -0
- codex_transcript_viewer-0.4.0/tests/test_inherited_history.py +82 -0
- codex_transcript_viewer-0.4.0/tests/test_markdown.py +104 -0
- codex_transcript_viewer-0.4.0/tests/test_null_payload_fields.py +106 -0
- codex_transcript_viewer-0.4.0/tests/test_output_cap.py +37 -0
- codex_transcript_viewer-0.4.0/tests/test_parser_dedup_density.py +214 -0
- codex_transcript_viewer-0.4.0/tests/test_parser_reconciliation_edge_cases.py +127 -0
- codex_transcript_viewer-0.4.0/tests/test_parser_stream_reconciliation.py +175 -0
- codex_transcript_viewer-0.4.0/tests/test_prompt_images.py +133 -0
- codex_transcript_viewer-0.4.0/tests/test_session_events.py +239 -0
- codex_transcript_viewer-0.4.0/tests/test_session_meta.py +20 -0
- codex_transcript_viewer-0.4.0/tests/test_tool_output_shapes.py +90 -0
- codex_transcript_viewer-0.4.0/tests/test_tool_search.py +44 -0
- codex_transcript_viewer-0.4.0/tests/test_tool_status.py +56 -0
- codex_transcript_viewer-0.4.0/tests/test_unrecognized_records.py +57 -0
- codex_transcript_viewer-0.4.0/tests/test_user_prompts.py +174 -0
- codex_transcript_viewer-0.4.0/tests/test_web_search.py +45 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
- The viewer is on PyPI: `uv tool install codex-transcript-viewer`, `pipx install codex-transcript-viewer`, or `uvx codex-transcript-viewer <session.jsonl>` to run it once.
|
|
6
|
+
- Markdown tables render as tables, and links work. Web links open in a new tab; links to local files show their label, with the full path on hover. Bare `https://` addresses become links too.
|
|
7
|
+
- Formatting no longer leaks into code: `**` inside a code block stays as written.
|
|
8
|
+
- Sessions with malformed records no longer crash the parser. A fuzz of every record type turned up ten such spots.
|
|
9
|
+
- Tests run on GitHub Actions for Python 3.11 through 3.14.
|
|
10
|
+
|
|
11
|
+
## 0.3.0
|
|
12
|
+
|
|
13
|
+
- Goals set with `/goal` show up, with their objective and each status change (complete, paused, blocked, out of budget). Codex logs the goal again after nearly every step, so only real changes are kept.
|
|
14
|
+
- Generated images render, along with the prompt the model used. They count toward the `--max-image-mb` budget.
|
|
15
|
+
- Hook messages, review start and result markers, and errors like a usage limit now appear. A review's findings are listed when no reply repeats them.
|
|
16
|
+
- Reasoning headings no longer repeat. Newer models restate a turn's earlier headings every time they add one, which made about a quarter of the headings in recent sessions duplicates.
|
|
17
|
+
- Record types that carry nothing to show (guardian approvals, subagent status, voice sessions, undo) are skipped quietly instead of being reported as unrecognized.
|
|
18
|
+
|
|
19
|
+
## 0.2.2
|
|
20
|
+
|
|
21
|
+
- 0.2.1 only fixed some of the doubled final answers. Older sessions also log a final answer without its memory citations or proposed plan, and those copies still showed as commentary. They're gone now, along with a doubled last message in older and plan-mode turns.
|
|
22
|
+
- `scripts/audit_sessions.py` checks the viewer against real sessions for duplicated or missing entries, and `scripts/visual_review.py` screenshots one session per format. Run over about 8,500 sessions, both come back clean.
|
|
23
|
+
|
|
24
|
+
## 0.2.1
|
|
25
|
+
|
|
26
|
+
- Older sessions no longer show each final answer twice. Codex also logged final answers as commentary, and the viewer kept that copy.
|
|
27
|
+
- The README screenshot shows the current viewer.
|
|
28
|
+
|
|
29
|
+
## 0.2.0
|
|
30
|
+
|
|
31
|
+
It's been a while since I updated this, and Codex has changed a lot in the meantime, so these fixes are long overdue. Newer sessions were missing most of what actually happened.
|
|
32
|
+
|
|
33
|
+
- Prompts show up again. Codex 0.135 and later store them as `item_completed` records, which the viewer never read. Injected context like the environment block, AGENTS.md and skill text stays out. Thanks to joebb97, who opened #3, and to khoi for reporting it.
|
|
34
|
+
- Tool calls now render in full, including code-mode `exec`, `apply_patch`, web searches and tool searches. The viewer colors each result by its real exit status. khoi contributed the name/value grid for tool parameters.
|
|
35
|
+
- Tool screenshots render as images. The viewer used to dump them into the page as raw base64, which is why some pages hit 36 MB. It now embeds up to 25 MB of images per page. New flags: `--max-image-mb`, `--no-images`, `--max-output-chars`.
|
|
36
|
+
- Duplicate messages no longer slip through when tool calls sit between the two copies, and the Answers filter finds every final answer.
|
|
37
|
+
- Subagent threads show the agent and its parent thread. History copied from the parent sits in a collapsed block.
|
|
38
|
+
- The viewer prints record types it doesn't recognize to stderr, so the next Codex format change shows up right away.
|
|
39
|
+
|
|
40
|
+
## 0.1.0
|
|
41
|
+
|
|
42
|
+
First release.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Colin Mason
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: codex-transcript-viewer
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Convert Codex CLI JSONL session transcripts to self-contained HTML viewers
|
|
5
|
+
Project-URL: Homepage, https://github.com/masonc15/codex-transcript-viewer
|
|
6
|
+
Project-URL: Issues, https://github.com/masonc15/codex-transcript-viewer/issues
|
|
7
|
+
Project-URL: Changelog, https://github.com/masonc15/codex-transcript-viewer/blob/main/CHANGELOG.md
|
|
8
|
+
Author: Colin Mason
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: codex,html,jsonl,openai,transcript,viewer
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
+
Classifier: Topic :: Software Development
|
|
19
|
+
Classifier: Topic :: Utilities
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
# codex-transcript-viewer
|
|
24
|
+
|
|
25
|
+
Converts Codex CLI JSONL session transcripts into single-file HTML viewers with sidebar navigation, search, and filtering. No external dependencies. Just open the `.html` in any browser.
|
|
26
|
+
|
|
27
|
+

|
|
28
|
+
|
|
29
|
+
See the [full demo](https://github.com/masonc15/codex-transcript-viewer/blob/main/docs/demo.md) for more screenshots and a walkthrough of every feature.
|
|
30
|
+
|
|
31
|
+
## Install
|
|
32
|
+
|
|
33
|
+
It's on PyPI, so install it with uv or pipx, or run it once without installing anything:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
uv tool install codex-transcript-viewer
|
|
37
|
+
pipx install codex-transcript-viewer
|
|
38
|
+
uvx codex-transcript-viewer <session.jsonl>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
For the latest unreleased changes, install straight from GitHub:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
uv tool install git+https://github.com/masonc15/codex-transcript-viewer.git
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
To hack on it, clone the repo and install from the checkout instead, or run it without installing:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
git clone https://github.com/masonc15/codex-transcript-viewer.git
|
|
51
|
+
uv tool install ./codex-transcript-viewer
|
|
52
|
+
uv run --directory ./codex-transcript-viewer codex-transcript-viewer <session.jsonl>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Usage
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
codex-transcript-viewer <session.jsonl> [output.html]
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
If you omit the output path it writes `<input-stem>.html` in the current directory.
|
|
62
|
+
|
|
63
|
+
Codex stores sessions as JSONL files under `~/.codex/sessions/`. Find one and point the tool at it:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
codex-transcript-viewer ~/.codex/sessions/2026/02/18/rollout-2026-02-18T10-06-22-019c7149.jsonl
|
|
67
|
+
open rollout-2026-02-18T10-06-22-019c7149.html
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Images are embedded, so the page stays a single file. Images you attached to a prompt are always included, taken from the copy saved in the session log, since the original file is often a temp file that's long gone. Screenshots returned by tools are embedded until they add up to 25 MB, after which the rest show as placeholders and a note at the top says how many were left out. `--max-image-mb N` changes that budget (0 means no limit), and `--no-images` replaces every image with a labelled placeholder, which is handy when you want a small page or would rather not share what was on your screen.
|
|
71
|
+
|
|
72
|
+
Tool output text is embedded in full. Codex already trims what the model sees to roughly 200K characters, so the viewer's own `--max-output-chars` guard (default 250,000, 0 to disable) only kicks in for something pathological.
|
|
73
|
+
|
|
74
|
+
If the log contains record types the viewer doesn't know about, it says so on stderr after writing the page, which usually means Codex changed its format.
|
|
75
|
+
|
|
76
|
+
## What the viewer shows
|
|
77
|
+
|
|
78
|
+
The page has a sticky sidebar with a searchable event tree on the left and the transcript on the right. Your prompts get a green border, with any attached images shown as thumbnails you can click to enlarge. Final answers sit on a faint green background, commentary is italic with a muted border, and reasoning summaries are gray. Each tool call shows its command or arguments, and its result is colored by what actually happened: green when the exit code was 0, red when it failed, and neutral when the log doesn't record a status, so nothing looks successful by accident. Long outputs expand on click. Markdown in prompts and answers renders, tables included; web links open in a new tab, and links to local files show their full path on hover. Generated images show up as the result of their `image_generation` call, next to the prompt the model used. Turn starts, aborts, rollbacks and token counts show up as dim system lines.
|
|
79
|
+
|
|
80
|
+
Some things Codex only sends to the model, so the viewer shows them as their own highlighted entries: the objective and status changes of a `/goal`, text a hook sent back (a rejected plan, for example), review start and result markers, and errors such as hitting a usage limit. A review's findings appear in full when no reply repeats them. Newer models repeat the turn's earlier reasoning headings each time they add one, so each heading is shown once, at the point it first appeared.
|
|
81
|
+
|
|
82
|
+
The sidebar filters are Default, No tools, User, Answers and All. On narrow screens the sidebar tucks behind a hamburger menu.
|
|
83
|
+
|
|
84
|
+
Subagent threads are labelled with the agent's name and parent thread. When a subagent was forked with its parent's conversation, the copied turns are folded into a collapsed block at the top instead of being shown as if the subagent wrote them.
|
|
85
|
+
|
|
86
|
+
## Supported sessions
|
|
87
|
+
|
|
88
|
+
Both session formats Codex has used are handled: the older one, where prompts are `user_message` events (seen through CLI 0.125), and the newer one, where they're `item_completed` records (CLI 0.135 and later). Tool calls cover plain function calls, code-mode `exec` and `apply_patch` custom tools, web searches, tool searches and image generation.
|
|
89
|
+
|
|
90
|
+
## Limitations
|
|
91
|
+
|
|
92
|
+
The transcript is an activity log, so rolled-back turns stay inline with a banner rather than disappearing. The filters hide sidebar entries, not the transcript itself.
|
|
93
|
+
|
|
94
|
+
## Development
|
|
95
|
+
|
|
96
|
+
Run the tests with `PYTHONPATH=src python3 -m unittest discover -s tests`. GitHub Actions runs them on Python 3.11 through 3.14 for every push and pull request, and also builds the package and converts a small session with the installed wheel. The tests use synthetic records, so they only cover the shapes someone thought to write down.
|
|
97
|
+
|
|
98
|
+
Before a release, run `python3 scripts/audit_sessions.py` over your real sessions (it reads `~/.codex/sessions` and `~/.codex/archived_sessions` by default, or any paths you give it). For every session it checks that no text shows twice in a turn, that the visible prompts, messages and reasoning match what the raw records say should be there, and that every pair of record kinds sharing text is covered by a dedup rule. None of these compare against an earlier run of the viewer, so an old bug can't hide in the baseline. `--tar -` reads sessions from a tar stream, which is handy for an archive on another machine.
|
|
99
|
+
|
|
100
|
+
Then run `uv run --with playwright python scripts/visual_review.py --from-audit report.json`, using the report from `audit_sessions.py --json report.json`. It renders one session per format, fails if two kinds of entry in the same role repeat each other, and saves sidebar screenshots to look over. Both scripts print session text, so keep their output out of the repository.
|
|
101
|
+
|
|
102
|
+
Publishing a GitHub release uploads that version to PyPI. The release tag has to match the version in `pyproject.toml`.
|
|
103
|
+
|
|
104
|
+
## Credits
|
|
105
|
+
|
|
106
|
+
Inspired by the HTML session export in [pi](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent), a coding agent by [@badlogic](https://github.com/badlogic).
|
|
107
|
+
|
|
108
|
+
## Project structure
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
src/codex_transcript_viewer/
|
|
112
|
+
parser.py - JSONL parsing and event extraction
|
|
113
|
+
markdown.py - lightweight markdown-to-HTML conversion
|
|
114
|
+
formatting.py - timestamp formatting helpers
|
|
115
|
+
html_builder.py - assembles the final HTML from events
|
|
116
|
+
style.css - all CSS for the viewer
|
|
117
|
+
viewer.js - sidebar filtering and navigation
|
|
118
|
+
cli.py - command-line entry point
|
|
119
|
+
scripts/
|
|
120
|
+
audit_sessions.py - checks the parser against real sessions
|
|
121
|
+
visual_review.py - renders sessions and screenshots the sidebar
|
|
122
|
+
```
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# codex-transcript-viewer
|
|
2
|
+
|
|
3
|
+
Converts Codex CLI JSONL session transcripts into single-file HTML viewers with sidebar navigation, search, and filtering. No external dependencies. Just open the `.html` in any browser.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
See the [full demo](https://github.com/masonc15/codex-transcript-viewer/blob/main/docs/demo.md) for more screenshots and a walkthrough of every feature.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
It's on PyPI, so install it with uv or pipx, or run it once without installing anything:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
uv tool install codex-transcript-viewer
|
|
15
|
+
pipx install codex-transcript-viewer
|
|
16
|
+
uvx codex-transcript-viewer <session.jsonl>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
For the latest unreleased changes, install straight from GitHub:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
uv tool install git+https://github.com/masonc15/codex-transcript-viewer.git
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
To hack on it, clone the repo and install from the checkout instead, or run it without installing:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
git clone https://github.com/masonc15/codex-transcript-viewer.git
|
|
29
|
+
uv tool install ./codex-transcript-viewer
|
|
30
|
+
uv run --directory ./codex-transcript-viewer codex-transcript-viewer <session.jsonl>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
codex-transcript-viewer <session.jsonl> [output.html]
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
If you omit the output path it writes `<input-stem>.html` in the current directory.
|
|
40
|
+
|
|
41
|
+
Codex stores sessions as JSONL files under `~/.codex/sessions/`. Find one and point the tool at it:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
codex-transcript-viewer ~/.codex/sessions/2026/02/18/rollout-2026-02-18T10-06-22-019c7149.jsonl
|
|
45
|
+
open rollout-2026-02-18T10-06-22-019c7149.html
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Images are embedded, so the page stays a single file. Images you attached to a prompt are always included, taken from the copy saved in the session log, since the original file is often a temp file that's long gone. Screenshots returned by tools are embedded until they add up to 25 MB, after which the rest show as placeholders and a note at the top says how many were left out. `--max-image-mb N` changes that budget (0 means no limit), and `--no-images` replaces every image with a labelled placeholder, which is handy when you want a small page or would rather not share what was on your screen.
|
|
49
|
+
|
|
50
|
+
Tool output text is embedded in full. Codex already trims what the model sees to roughly 200K characters, so the viewer's own `--max-output-chars` guard (default 250,000, 0 to disable) only kicks in for something pathological.
|
|
51
|
+
|
|
52
|
+
If the log contains record types the viewer doesn't know about, it says so on stderr after writing the page, which usually means Codex changed its format.
|
|
53
|
+
|
|
54
|
+
## What the viewer shows
|
|
55
|
+
|
|
56
|
+
The page has a sticky sidebar with a searchable event tree on the left and the transcript on the right. Your prompts get a green border, with any attached images shown as thumbnails you can click to enlarge. Final answers sit on a faint green background, commentary is italic with a muted border, and reasoning summaries are gray. Each tool call shows its command or arguments, and its result is colored by what actually happened: green when the exit code was 0, red when it failed, and neutral when the log doesn't record a status, so nothing looks successful by accident. Long outputs expand on click. Markdown in prompts and answers renders, tables included; web links open in a new tab, and links to local files show their full path on hover. Generated images show up as the result of their `image_generation` call, next to the prompt the model used. Turn starts, aborts, rollbacks and token counts show up as dim system lines.
|
|
57
|
+
|
|
58
|
+
Some things Codex only sends to the model, so the viewer shows them as their own highlighted entries: the objective and status changes of a `/goal`, text a hook sent back (a rejected plan, for example), review start and result markers, and errors such as hitting a usage limit. A review's findings appear in full when no reply repeats them. Newer models repeat the turn's earlier reasoning headings each time they add one, so each heading is shown once, at the point it first appeared.
|
|
59
|
+
|
|
60
|
+
The sidebar filters are Default, No tools, User, Answers and All. On narrow screens the sidebar tucks behind a hamburger menu.
|
|
61
|
+
|
|
62
|
+
Subagent threads are labelled with the agent's name and parent thread. When a subagent was forked with its parent's conversation, the copied turns are folded into a collapsed block at the top instead of being shown as if the subagent wrote them.
|
|
63
|
+
|
|
64
|
+
## Supported sessions
|
|
65
|
+
|
|
66
|
+
Both session formats Codex has used are handled: the older one, where prompts are `user_message` events (seen through CLI 0.125), and the newer one, where they're `item_completed` records (CLI 0.135 and later). Tool calls cover plain function calls, code-mode `exec` and `apply_patch` custom tools, web searches, tool searches and image generation.
|
|
67
|
+
|
|
68
|
+
## Limitations
|
|
69
|
+
|
|
70
|
+
The transcript is an activity log, so rolled-back turns stay inline with a banner rather than disappearing. The filters hide sidebar entries, not the transcript itself.
|
|
71
|
+
|
|
72
|
+
## Development
|
|
73
|
+
|
|
74
|
+
Run the tests with `PYTHONPATH=src python3 -m unittest discover -s tests`. GitHub Actions runs them on Python 3.11 through 3.14 for every push and pull request, and also builds the package and converts a small session with the installed wheel. The tests use synthetic records, so they only cover the shapes someone thought to write down.
|
|
75
|
+
|
|
76
|
+
Before a release, run `python3 scripts/audit_sessions.py` over your real sessions (it reads `~/.codex/sessions` and `~/.codex/archived_sessions` by default, or any paths you give it). For every session it checks that no text shows twice in a turn, that the visible prompts, messages and reasoning match what the raw records say should be there, and that every pair of record kinds sharing text is covered by a dedup rule. None of these compare against an earlier run of the viewer, so an old bug can't hide in the baseline. `--tar -` reads sessions from a tar stream, which is handy for an archive on another machine.
|
|
77
|
+
|
|
78
|
+
Then run `uv run --with playwright python scripts/visual_review.py --from-audit report.json`, using the report from `audit_sessions.py --json report.json`. It renders one session per format, fails if two kinds of entry in the same role repeat each other, and saves sidebar screenshots to look over. Both scripts print session text, so keep their output out of the repository.
|
|
79
|
+
|
|
80
|
+
Publishing a GitHub release uploads that version to PyPI. The release tag has to match the version in `pyproject.toml`.
|
|
81
|
+
|
|
82
|
+
## Credits
|
|
83
|
+
|
|
84
|
+
Inspired by the HTML session export in [pi](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent), a coding agent by [@badlogic](https://github.com/badlogic).
|
|
85
|
+
|
|
86
|
+
## Project structure
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
src/codex_transcript_viewer/
|
|
90
|
+
parser.py - JSONL parsing and event extraction
|
|
91
|
+
markdown.py - lightweight markdown-to-HTML conversion
|
|
92
|
+
formatting.py - timestamp formatting helpers
|
|
93
|
+
html_builder.py - assembles the final HTML from events
|
|
94
|
+
style.css - all CSS for the viewer
|
|
95
|
+
viewer.js - sidebar filtering and navigation
|
|
96
|
+
cli.py - command-line entry point
|
|
97
|
+
scripts/
|
|
98
|
+
audit_sessions.py - checks the parser against real sessions
|
|
99
|
+
visual_review.py - renders sessions and screenshots the sidebar
|
|
100
|
+
```
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "codex-transcript-viewer"
|
|
3
|
+
version = "0.4.0"
|
|
4
|
+
description = "Convert Codex CLI JSONL session transcripts to self-contained HTML viewers"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
license = "MIT"
|
|
8
|
+
license-files = ["LICENSE"]
|
|
9
|
+
authors = [{ name = "Colin Mason" }]
|
|
10
|
+
keywords = ["codex", "openai", "transcript", "jsonl", "html", "viewer"]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 4 - Beta",
|
|
13
|
+
"Environment :: Console",
|
|
14
|
+
"Intended Audience :: Developers",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
18
|
+
"Topic :: Software Development",
|
|
19
|
+
"Topic :: Utilities",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[project.urls]
|
|
23
|
+
Homepage = "https://github.com/masonc15/codex-transcript-viewer"
|
|
24
|
+
Issues = "https://github.com/masonc15/codex-transcript-viewer/issues"
|
|
25
|
+
Changelog = "https://github.com/masonc15/codex-transcript-viewer/blob/main/CHANGELOG.md"
|
|
26
|
+
|
|
27
|
+
[project.scripts]
|
|
28
|
+
codex-transcript-viewer = "codex_transcript_viewer.cli:main"
|
|
29
|
+
|
|
30
|
+
[build-system]
|
|
31
|
+
requires = ["hatchling>=1.27"]
|
|
32
|
+
build-backend = "hatchling.build"
|
|
33
|
+
|
|
34
|
+
[tool.hatch.build.targets.wheel]
|
|
35
|
+
packages = ["src/codex_transcript_viewer"]
|
|
36
|
+
|
|
37
|
+
# List the sdist contents so local-only files (plans, notes) never ship.
|
|
38
|
+
[tool.hatch.build.targets.sdist]
|
|
39
|
+
include = ["src", "tests", "scripts", "README.md", "CHANGELOG.md", "LICENSE", "pyproject.toml"]
|