From 65eea5f1777feeb25193080dda25d2d53e51bdc4 Mon Sep 17 00:00:00 2001 From: leedermix-arch Date: Fri, 25 Sep 2026 04:07:57 +0000 Subject: [PATCH] Render user prompts as plain text Prompts often contain pasted code or config, where # starts a comment rather than a heading. Show them as typed, with whitespace preserved, both on the transcript pages and in the index. Assistant text is still rendered as Markdown. Closes #35 --- src/claude_code_transcripts/__init__.py | 26 ++++++++-- ...enerateHtml.test_generates_index_html.html | 11 +++-- ...rateHtml.test_generates_page_001_html.html | 11 +++-- ...rateHtml.test_generates_page_002_html.html | 3 +- ...SessionFile.test_jsonl_generates_html.html | 5 +- tests/test_generate_html.py | 48 +++++++++++++++++++ 6 files changed, 87 insertions(+), 17 deletions(-) diff --git a/src/claude_code_transcripts/__init__.py b/src/claude_code_transcripts/__init__.py index e4854a3b..8e8a81f8 100644 --- a/src/claude_code_transcripts/__init__.py +++ b/src/claude_code_transcripts/__init__.py @@ -704,6 +704,17 @@ def render_markdown_text(text): return markdown.markdown(text, extensions=["fenced_code", "tables"]) +def render_user_text(text): + """Render a user prompt as the plain text that was typed. + + Prompts often contain pasted code or config, where # starts a comment + rather than a heading, so they are not rendered as Markdown. + """ + if not text: + return "" + return f'

{html.escape(text)}

' + + def is_json_like(text): if not text or not isinstance(text, str): return False @@ -840,14 +851,20 @@ def render_content_block(block): return format_json(block) +def render_user_content_block(block): + if isinstance(block, dict) and block.get("type") == "text": + return _macros.user_content(render_user_text(block.get("text", ""))) + return render_content_block(block) + + def render_user_message_content(message_data): content = message_data.get("content", "") if isinstance(content, str): if is_json_like(content): return _macros.user_content(format_json(content)) - return _macros.user_content(render_markdown_text(content)) + return _macros.user_content(render_user_text(content)) elif isinstance(content, list): - return "".join(render_content_block(block) for block in content) + return "".join(render_user_content_block(block) for block in content) return f"

{html.escape(str(content))}

" @@ -1046,6 +1063,7 @@ def render_message(log_type, message_json, timestamp): code { background: rgba(0,0,0,0.08); padding: 2px 6px; border-radius: 4px; font-size: 0.9em; } pre code { background: none; padding: 0; } .user-content { margin: 0; } +.user-text { margin: 0; white-space: pre-wrap; } .truncatable { position: relative; } .truncatable.truncated .truncatable-content { max-height: 200px; overflow: hidden; } .truncatable.truncated::after { content: ''; position: absolute; bottom: 32px; left: 0; right: 0; height: 60px; background: linear-gradient(to bottom, transparent, var(--card-bg)); pointer-events: none; } @@ -1413,7 +1431,7 @@ def generate_html(json_path, output_dir, github_repo=None): page_num = (i // PROMPTS_PER_PAGE) + 1 msg_id = make_msg_id(conv["timestamp"]) link = f"page-{page_num:03d}.html#{msg_id}" - rendered_content = render_markdown_text(conv["user_text"]) + rendered_content = render_user_text(conv["user_text"]) # Collect all messages including from subsequent continuation conversations # This ensures long_texts from continuations appear with the original prompt @@ -1887,7 +1905,7 @@ def generate_html_from_session_data(session_data, output_dir, github_repo=None): page_num = (i // PROMPTS_PER_PAGE) + 1 msg_id = make_msg_id(conv["timestamp"]) link = f"page-{page_num:03d}.html#{msg_id}" - rendered_content = render_markdown_text(conv["user_text"]) + rendered_content = render_user_text(conv["user_text"]) # Collect all messages including from subsequent continuation conversations # This ensures long_texts from continuations appear with the original prompt diff --git a/tests/__snapshots__/test_generate_html/TestGenerateHtml.test_generates_index_html.html b/tests/__snapshots__/test_generate_html/TestGenerateHtml.test_generates_index_html.html index 693c48ff..ef3c9396 100644 --- a/tests/__snapshots__/test_generate_html/TestGenerateHtml.test_generates_index_html.html +++ b/tests/__snapshots__/test_generate_html/TestGenerateHtml.test_generates_index_html.html @@ -79,6 +79,7 @@ code { background: rgba(0,0,0,0.08); padding: 2px 6px; border-radius: 4px; font-size: 0.9em; } pre code { background: none; padding: 0; } .user-content { margin: 0; } +.user-text { margin: 0; white-space: pre-wrap; } .truncatable { position: relative; } .truncatable.truncated .truncatable-content { max-height: 200px; overflow: hidden; } .truncatable.truncated::after { content: ''; position: absolute; bottom: 32px; left: 0; right: 0; height: 60px; background: linear-gradient(to bottom, transparent, var(--card-bg)); pointer-events: none; } @@ -166,15 +167,15 @@

Claude Code transcript

5 prompts · 33 messages · 12 tool calls · 2 commits · 2 pages

-
#1

Create a simple Python function to add two numbers

3 bash · 1 write · 1 todo + -
#2

Now edit the file to add a subtract function

1 glob · 1 edit · 1 grep + -
#3

Run the tests again

1 bash + -
#4

Fix the issue and commit

1 edit · 1 bash + -
#5

Add a multiply function too

1 edit + diff --git a/tests/__snapshots__/test_generate_html/TestGenerateHtml.test_generates_page_001_html.html b/tests/__snapshots__/test_generate_html/TestGenerateHtml.test_generates_page_001_html.html index cdc794bd..539af06d 100644 --- a/tests/__snapshots__/test_generate_html/TestGenerateHtml.test_generates_page_001_html.html +++ b/tests/__snapshots__/test_generate_html/TestGenerateHtml.test_generates_page_001_html.html @@ -79,6 +79,7 @@ code { background: rgba(0,0,0,0.08); padding: 2px 6px; border-radius: 4px; font-size: 0.9em; } pre code { background: none; padding: 0; } .user-content { margin: 0; } +.user-text { margin: 0; white-space: pre-wrap; } .truncatable { position: relative; } .truncatable.truncated .truncatable-content { max-height: 200px; overflow: hidden; } .truncatable.truncated::after { content: ''; position: absolute; bottom: 32px; left: 0; right: 0; height: 60px; background: linear-gradient(to bottom, transparent, var(--card-bg)); pointer-events: none; } @@ -158,7 +159,7 @@

Claude C
-

Create a simple Python function to add two numbers

+

Create a simple Python function to add two numbers

Thinking

The user wants a simple addition function. I should: 1. Create the function @@ -208,7 +209,7 @@

Claude C To github.com:example/project.git def5678..abc1234 main -> main

-

Now edit the file to add a subtract function

+

Now edit the file to add a subtract function

⚙ Glob
{
   "pattern": "**/*.py",
@@ -241,7 +242,7 @@ 

Claude C }

/project/math_utils.py:6:def subtract(a: int, b: int) -> int:
-

Run the tests again

+

Run the tests again

$ Bash
@@ -260,7 +261,7 @@

Claude C return 42

-

Fix the issue and commit

+

Fix the issue and commit

✏️ Edit test_math.py (replace all)
/project/tests/test_math.py
@@ -279,7 +280,7 @@

Claude C

Done! The subtract function is now working and committed.

Session continuation summary
-

This is a session continuation summary from a previous context. The user was working on a math utilities library.

+

This is a session continuation summary from a previous context. The user was working on a math utilities library.

✏️ Edit math_utils.py
/project/math_utils.py
diff --git a/tests/__snapshots__/test_generate_html/TestParseSessionFile.test_jsonl_generates_html.html b/tests/__snapshots__/test_generate_html/TestParseSessionFile.test_jsonl_generates_html.html index e83424ab..b6a9cfdb 100644 --- a/tests/__snapshots__/test_generate_html/TestParseSessionFile.test_jsonl_generates_html.html +++ b/tests/__snapshots__/test_generate_html/TestParseSessionFile.test_jsonl_generates_html.html @@ -79,6 +79,7 @@ code { background: rgba(0,0,0,0.08); padding: 2px 6px; border-radius: 4px; font-size: 0.9em; } pre code { background: none; padding: 0; } .user-content { margin: 0; } +.user-text { margin: 0; white-space: pre-wrap; } .truncatable { position: relative; } .truncatable.truncated .truncatable-content { max-height: 200px; overflow: hidden; } .truncatable.truncated::after { content: ''; position: absolute; bottom: 32px; left: 0; right: 0; height: 60px; background: linear-gradient(to bottom, transparent, var(--card-bg)); pointer-events: none; } @@ -165,9 +166,9 @@

Claude Code transcript

2 prompts · 7 messages · 2 tool calls · 1 commits · 1 pages

-
#1

Create a hello world function

1 write · 1 bash +
abc1234
Add hello function
- +