Skip to content

Commit f167416

Browse files
authored
Merge pull request #6 from ShlomoStept/fix/phase2-ui-regressions
Fix Phase 2 UI regressions and complete remaining items
2 parents 5490fd4 + ab65c8d commit f167416

20 files changed

+3754
-812
lines changed

src/claude_code_transcripts/__init__.py

Lines changed: 847 additions & 176 deletions
Large diffs are not rendered by default.

src/claude_code_transcripts/templates/macros.html

Lines changed: 103 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,17 @@
4646
{%- endif %}
4747
{% endmacro %}
4848

49-
{# Todo list #}
50-
{% macro todo_list(todos, tool_id) %}
51-
<div class="todo-list" data-tool-id="{{ tool_id }}"><div class="todo-header"><span class="todo-header-icon"></span> Task List</div><ul class="todo-items">
49+
{# Todo list - input_json_html is pre-rendered JSON so needs |safe #}
50+
{% macro todo_list(todos, input_json_html, tool_id) %}
51+
<div class="todo-list" data-tool-id="{{ tool_id }}">
52+
<div class="todo-header"><span class="todo-header-icon"></span> Task List
53+
<div class="view-toggle" role="tablist">
54+
<button class="view-toggle-tab active" role="tab" data-view="markdown">Markdown</button>
55+
<button class="view-toggle-tab" role="tab" data-view="json">JSON</button>
56+
</div>
57+
</div>
58+
<div class="view-markdown">
59+
<ul class="todo-items">
5260
{%- for todo in todos -%}
5361
{%- set status = todo.status|default('pending') -%}
5462
{%- set content = todo.content|default('') -%}
@@ -64,63 +72,115 @@
6472
{%- endif -%}
6573
<li class="todo-item {{ status_class }}"><span class="todo-icon">{{ icon }}</span><span class="todo-content">{{ content }}</span></li>
6674
{%- endfor -%}
67-
</ul></div>
75+
</ul>
76+
</div>
77+
<div class="view-json">
78+
{{ input_json_html|safe }}
79+
</div>
80+
</div>
6881
{%- endmacro %}
6982

70-
{# Write tool - content is pre-highlighted so needs |safe #}
71-
{% macro write_tool(file_path, content, tool_id) %}
83+
{# Write tool - content is pre-highlighted so needs |safe, input_json_html is pre-rendered JSON so needs |safe #}
84+
{% macro write_tool(file_path, content, input_json_html, tool_id) %}
7285
{%- set filename = file_path.split('/')[-1] if '/' in file_path else file_path -%}
7386
<div class="file-tool write-tool" data-tool-id="{{ tool_id }}">
74-
<div class="file-tool-header write-header"><span class="file-tool-icon">📝</span> Write <span class="file-tool-path">{{ filename }}</span></div>
87+
<div class="file-tool-header write-header"><span class="file-tool-icon">📝</span> Write <span class="file-tool-path">{{ filename }}</span>
88+
<div class="view-toggle" role="tablist">
89+
<button class="view-toggle-tab active" role="tab" data-view="markdown">Markdown</button>
90+
<button class="view-toggle-tab" role="tab" data-view="json">JSON</button>
91+
</div>
92+
</div>
93+
<div class="view-markdown">
7594
<div class="file-tool-fullpath">{{ file_path }}</div>
7695
<div class="truncatable"><div class="truncatable-content"><pre class="file-content highlight">{{ content|safe }}</pre></div><button class="expand-btn">Show more</button></div>
7796
</div>
97+
<div class="view-json">
98+
{{ input_json_html|safe }}
99+
</div>
100+
</div>
78101
{%- endmacro %}
79102

80-
{# Edit tool - old/new strings are pre-highlighted so need |safe #}
81-
{% macro edit_tool(file_path, old_string, new_string, replace_all, tool_id) %}
103+
{# Edit tool - old/new strings are pre-highlighted so need |safe, input_json_html is pre-rendered JSON so needs |safe #}
104+
{% macro edit_tool(file_path, old_string, new_string, replace_all, input_json_html, tool_id) %}
82105
{%- set filename = file_path.split('/')[-1] if '/' in file_path else file_path -%}
83106
<div class="file-tool edit-tool" data-tool-id="{{ tool_id }}">
84-
<div class="file-tool-header edit-header"><span class="file-tool-icon">✏️</span> Edit <span class="file-tool-path">{{ filename }}</span>{% if replace_all %} <span class="edit-replace-all">(replace all)</span>{% endif %}</div>
107+
<div class="file-tool-header edit-header"><span class="file-tool-icon">✏️</span> Edit <span class="file-tool-path">{{ filename }}</span>{% if replace_all %} <span class="edit-replace-all">(replace all)</span>{% endif %}
108+
<div class="view-toggle" role="tablist">
109+
<button class="view-toggle-tab active" role="tab" data-view="markdown">Markdown</button>
110+
<button class="view-toggle-tab" role="tab" data-view="json">JSON</button>
111+
</div>
112+
</div>
113+
<div class="view-markdown">
85114
<div class="file-tool-fullpath">{{ file_path }}</div>
86115
<div class="truncatable"><div class="truncatable-content">
87116
<div class="edit-section edit-old"><div class="edit-label"></div><pre class="edit-content highlight">{{ old_string|safe }}</pre></div>
88117
<div class="edit-section edit-new"><div class="edit-label">+</div><pre class="edit-content highlight">{{ new_string|safe }}</pre></div>
89118
</div><button class="expand-btn">Show more</button></div>
90119
</div>
120+
<div class="view-json">
121+
{{ input_json_html|safe }}
122+
</div>
123+
</div>
91124
{%- endmacro %}
92125

93-
{# Bash tool #}
94-
{% macro bash_tool(command, description, tool_id) %}
126+
{# Bash tool - description_html is pre-rendered markdown so needs |safe, input_json_html is pre-rendered JSON so needs |safe #}
127+
{% macro bash_tool(command, description_html, input_json_html, tool_id) %}
95128
<div class="tool-use bash-tool" data-tool-id="{{ tool_id }}">
96-
<div class="tool-header"><span class="tool-icon">$</span> Bash</div>
97-
{%- if description %}
98-
<div class="tool-description">{{ description }}</div>
129+
<div class="tool-header"><span class="tool-call-label"><span class="call-icon"></span> Call</span><span class="tool-icon">$</span> Bash
130+
<div class="view-toggle" role="tablist">
131+
<button class="view-toggle-tab active" role="tab" data-view="markdown">Markdown</button>
132+
<button class="view-toggle-tab" role="tab" data-view="json">JSON</button>
133+
</div>
134+
</div>
135+
<div class="view-markdown">
136+
{%- if description_html %}
137+
<div class="tool-description">{{ description_html|safe }}</div>
99138
{%- endif -%}
100139
<div class="truncatable"><div class="truncatable-content"><pre class="bash-command">{{ command }}</pre></div><button class="expand-btn">Show more</button></div>
101140
</div>
141+
<div class="view-json">
142+
{{ input_json_html|safe }}
143+
</div>
144+
</div>
102145
{%- endmacro %}
103146

104-
{# Generic tool use - input_json is pre-formatted so needs |safe #}
105-
{% macro tool_use(tool_name, description, input_json, tool_id) %}
106-
<div class="tool-use" data-tool-id="{{ tool_id }}"><div class="tool-header"><span class="tool-icon"></span> {{ tool_name }}</div>
107-
{%- if description -%}
108-
<div class="tool-description">{{ description }}</div>
147+
{# Generic tool use - description_html, input_markdown_html, input_json_html are pre-rendered so need |safe #}
148+
{% macro tool_use(tool_name, tool_icon, description_html, input_markdown_html, input_json_html, tool_id) %}
149+
<div class="tool-use" data-tool-id="{{ tool_id }}"><div class="tool-header"><span class="tool-call-label"><span class="call-icon"></span> Call</span><span class="tool-icon">{{ tool_icon }}</span> {{ tool_name }}<div class="view-toggle" role="tablist"><button class="view-toggle-tab active" role="tab" aria-selected="true" data-view="markdown">Markdown</button><button class="view-toggle-tab" role="tab" aria-selected="false" data-view="json">JSON</button></div></div>
150+
{%- if description_html -%}
151+
<div class="tool-description">{{ description_html|safe }}</div>
109152
{%- endif -%}
110-
<div class="truncatable"><div class="truncatable-content"><pre class="json">{{ input_json }}</pre></div><button class="expand-btn">Show more</button></div></div>
153+
<div class="truncatable"><div class="truncatable-content"><div class="view-markdown tool-input-rendered">{{ input_markdown_html|safe }}</div><div class="view-json tool-input-rendered">{{ input_json_html|safe }}</div></div><button class="expand-btn">Show more</button></div></div>
111154
{%- endmacro %}
112155

113-
{# Tool result - content_html is pre-rendered so needs |safe #}
114-
{% macro tool_result(content_html, is_error) %}
156+
{# Tool result - content_markdown_html and content_json_html are pre-rendered so need |safe #}
157+
{% macro tool_result(content_markdown_html, content_json_html, is_error) %}
115158
{%- set error_class = ' tool-error' if is_error else '' -%}
116-
<div class="tool-result{{ error_class }}"><div class="truncatable"><div class="truncatable-content">{{ content_html|safe }}</div><button class="expand-btn">Show more</button></div></div>
159+
<div class="tool-result{{ error_class }}"><div class="tool-result-header"><span class="tool-result-label">{% if is_error %}<span class="result-icon"></span> Error{% else %}<span class="result-icon"></span> Result{% endif %}</span><div class="view-toggle" role="tablist"><button class="view-toggle-tab active" role="tab" aria-selected="true" data-view="markdown">Markdown</button><button class="view-toggle-tab" role="tab" aria-selected="false" data-view="json">JSON</button></div></div><div class="truncatable"><div class="truncatable-content"><div class="view-markdown">{{ content_markdown_html|safe }}</div><div class="view-json">{{ content_json_html|safe }}</div></div><button class="expand-btn">Show more</button></div></div>
117160
{%- endmacro %}
118161

119162
{# Tool pair wrapper - tool_use_html/tool_result_html are pre-rendered #}
120163
{% macro tool_pair(tool_use_html, tool_result_html) %}
121164
<div class="tool-pair">{{ tool_use_html|safe }}{{ tool_result_html|safe }}</div>
122165
{%- endmacro %}
123166

167+
{# Collapsible cell wrapper for message sections #}
168+
{% macro cell(cell_type, label, content_html, open_by_default=false, count=0, raw_content="") %}
169+
<details class="cell {{ cell_type }}-cell"{% if open_by_default %} open{% endif %}>
170+
<summary class="cell-header">
171+
<span class="cell-label">{{ label }}{% if count %} ({{ count }}){% endif %}</span>
172+
{% if cell_type == 'tools' %}
173+
<div class="view-toggle cell-view-toggle" role="tablist">
174+
<button class="view-toggle-tab active" role="tab" data-view="markdown">All Markdown</button>
175+
<button class="view-toggle-tab" role="tab" data-view="json">All JSON</button>
176+
</div>
177+
{% endif %}
178+
<button class="cell-copy-btn" aria-label="Copy {{ label }}" tabindex="0"{% if raw_content %} data-copy-content="{{ raw_content | e }}"{% endif %}>Copy</button>
179+
</summary>
180+
<div class="cell-content">{{ content_html|safe }}</div>
181+
</details>
182+
{%- endmacro %}
183+
124184
{# Thinking block - content_html is pre-rendered markdown so needs |safe #}
125185
{% macro thinking(content_html) %}
126186
<div class="thinking"><div class="thinking-label">Thinking</div>{{ content_html|safe }}</div>
@@ -151,9 +211,25 @@
151211
{%- endif %}
152212
{%- endmacro %}
153213

154-
{# Message wrapper - content_html is pre-rendered so needs |safe #}
155-
{% macro message(role_class, role_label, msg_id, timestamp, content_html) %}
156-
<div class="message {{ role_class }}" id="{{ msg_id }}"><div class="message-header"><span class="role-label">{{ role_label }}</span><a href="#{{ msg_id }}" class="timestamp-link"><time datetime="{{ timestamp }}" data-timestamp="{{ timestamp }}">{{ timestamp }}</time></a></div><div class="message-content">{{ content_html|safe }}</div></div>
214+
{# Message metadata subsection #}
215+
{% macro metadata(char_count, token_estimate, tool_counts) %}
216+
<details class="message-metadata">
217+
<summary>Metadata</summary>
218+
<div class="metadata-content">
219+
<div class="metadata-item"><span class="metadata-label">Chars:</span><span class="metadata-value">{{ char_count }}</span></div>
220+
<div class="metadata-item"><span class="metadata-label">Tokens:</span><span class="metadata-value">~{{ token_estimate }}</span></div>
221+
{%- if tool_counts %}
222+
{%- for tool_name, count in tool_counts.items() %}
223+
<div class="metadata-item"><span class="metadata-label">{{ tool_name }}:</span><span class="metadata-value">{{ count }}</span></div>
224+
{%- endfor %}
225+
{%- endif %}
226+
</div>
227+
</details>
228+
{%- endmacro %}
229+
230+
{# Message wrapper - content_html is pre-rendered so needs |safe, metadata_html is optional #}
231+
{% macro message(role_class, role_label, msg_id, timestamp, content_html, metadata_html="") %}
232+
<div class="message {{ role_class }}" id="{{ msg_id }}"><div class="message-header"><span class="role-label">{{ role_label }}</span><a href="#{{ msg_id }}" class="timestamp-link"><time datetime="{{ timestamp }}" data-timestamp="{{ timestamp }}">{{ timestamp }}</time></a></div>{{ metadata_html|safe }}<div class="message-content">{{ content_html|safe }}</div></div>
157233
{%- endmacro %}
158234

159235
{# Continuation wrapper - content_html is pre-rendered so needs |safe #}

0 commit comments

Comments
 (0)