klaude-code 1.2.6__py3-none-any.whl

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.
Files changed (167) hide show
  1. klaude_code/__init__.py +0 -0
  2. klaude_code/cli/__init__.py +1 -0
  3. klaude_code/cli/main.py +298 -0
  4. klaude_code/cli/runtime.py +331 -0
  5. klaude_code/cli/session_cmd.py +80 -0
  6. klaude_code/command/__init__.py +43 -0
  7. klaude_code/command/clear_cmd.py +20 -0
  8. klaude_code/command/command_abc.py +92 -0
  9. klaude_code/command/diff_cmd.py +138 -0
  10. klaude_code/command/export_cmd.py +86 -0
  11. klaude_code/command/help_cmd.py +51 -0
  12. klaude_code/command/model_cmd.py +43 -0
  13. klaude_code/command/prompt-dev-docs-update.md +56 -0
  14. klaude_code/command/prompt-dev-docs.md +46 -0
  15. klaude_code/command/prompt-init.md +45 -0
  16. klaude_code/command/prompt_command.py +69 -0
  17. klaude_code/command/refresh_cmd.py +43 -0
  18. klaude_code/command/registry.py +110 -0
  19. klaude_code/command/status_cmd.py +111 -0
  20. klaude_code/command/terminal_setup_cmd.py +252 -0
  21. klaude_code/config/__init__.py +11 -0
  22. klaude_code/config/config.py +177 -0
  23. klaude_code/config/list_model.py +162 -0
  24. klaude_code/config/select_model.py +67 -0
  25. klaude_code/const/__init__.py +133 -0
  26. klaude_code/core/__init__.py +0 -0
  27. klaude_code/core/agent.py +165 -0
  28. klaude_code/core/executor.py +485 -0
  29. klaude_code/core/manager/__init__.py +19 -0
  30. klaude_code/core/manager/agent_manager.py +127 -0
  31. klaude_code/core/manager/llm_clients.py +42 -0
  32. klaude_code/core/manager/llm_clients_builder.py +49 -0
  33. klaude_code/core/manager/sub_agent_manager.py +86 -0
  34. klaude_code/core/prompt.py +89 -0
  35. klaude_code/core/prompts/prompt-claude-code.md +98 -0
  36. klaude_code/core/prompts/prompt-codex.md +331 -0
  37. klaude_code/core/prompts/prompt-gemini.md +43 -0
  38. klaude_code/core/prompts/prompt-subagent-explore.md +27 -0
  39. klaude_code/core/prompts/prompt-subagent-oracle.md +23 -0
  40. klaude_code/core/prompts/prompt-subagent-webfetch.md +46 -0
  41. klaude_code/core/prompts/prompt-subagent.md +8 -0
  42. klaude_code/core/reminders.py +445 -0
  43. klaude_code/core/task.py +237 -0
  44. klaude_code/core/tool/__init__.py +75 -0
  45. klaude_code/core/tool/file/__init__.py +0 -0
  46. klaude_code/core/tool/file/apply_patch.py +492 -0
  47. klaude_code/core/tool/file/apply_patch_tool.md +1 -0
  48. klaude_code/core/tool/file/apply_patch_tool.py +204 -0
  49. klaude_code/core/tool/file/edit_tool.md +9 -0
  50. klaude_code/core/tool/file/edit_tool.py +274 -0
  51. klaude_code/core/tool/file/multi_edit_tool.md +42 -0
  52. klaude_code/core/tool/file/multi_edit_tool.py +199 -0
  53. klaude_code/core/tool/file/read_tool.md +14 -0
  54. klaude_code/core/tool/file/read_tool.py +326 -0
  55. klaude_code/core/tool/file/write_tool.md +8 -0
  56. klaude_code/core/tool/file/write_tool.py +146 -0
  57. klaude_code/core/tool/memory/__init__.py +0 -0
  58. klaude_code/core/tool/memory/memory_tool.md +16 -0
  59. klaude_code/core/tool/memory/memory_tool.py +462 -0
  60. klaude_code/core/tool/memory/skill_loader.py +245 -0
  61. klaude_code/core/tool/memory/skill_tool.md +24 -0
  62. klaude_code/core/tool/memory/skill_tool.py +97 -0
  63. klaude_code/core/tool/shell/__init__.py +0 -0
  64. klaude_code/core/tool/shell/bash_tool.md +43 -0
  65. klaude_code/core/tool/shell/bash_tool.py +123 -0
  66. klaude_code/core/tool/shell/command_safety.py +363 -0
  67. klaude_code/core/tool/sub_agent_tool.py +83 -0
  68. klaude_code/core/tool/todo/__init__.py +0 -0
  69. klaude_code/core/tool/todo/todo_write_tool.md +182 -0
  70. klaude_code/core/tool/todo/todo_write_tool.py +121 -0
  71. klaude_code/core/tool/todo/update_plan_tool.md +3 -0
  72. klaude_code/core/tool/todo/update_plan_tool.py +104 -0
  73. klaude_code/core/tool/tool_abc.py +25 -0
  74. klaude_code/core/tool/tool_context.py +106 -0
  75. klaude_code/core/tool/tool_registry.py +78 -0
  76. klaude_code/core/tool/tool_runner.py +252 -0
  77. klaude_code/core/tool/truncation.py +170 -0
  78. klaude_code/core/tool/web/__init__.py +0 -0
  79. klaude_code/core/tool/web/mermaid_tool.md +21 -0
  80. klaude_code/core/tool/web/mermaid_tool.py +76 -0
  81. klaude_code/core/tool/web/web_fetch_tool.md +8 -0
  82. klaude_code/core/tool/web/web_fetch_tool.py +159 -0
  83. klaude_code/core/turn.py +220 -0
  84. klaude_code/llm/__init__.py +21 -0
  85. klaude_code/llm/anthropic/__init__.py +3 -0
  86. klaude_code/llm/anthropic/client.py +221 -0
  87. klaude_code/llm/anthropic/input.py +200 -0
  88. klaude_code/llm/client.py +49 -0
  89. klaude_code/llm/input_common.py +239 -0
  90. klaude_code/llm/openai_compatible/__init__.py +3 -0
  91. klaude_code/llm/openai_compatible/client.py +211 -0
  92. klaude_code/llm/openai_compatible/input.py +109 -0
  93. klaude_code/llm/openai_compatible/tool_call_accumulator.py +80 -0
  94. klaude_code/llm/openrouter/__init__.py +3 -0
  95. klaude_code/llm/openrouter/client.py +200 -0
  96. klaude_code/llm/openrouter/input.py +160 -0
  97. klaude_code/llm/openrouter/reasoning_handler.py +209 -0
  98. klaude_code/llm/registry.py +22 -0
  99. klaude_code/llm/responses/__init__.py +3 -0
  100. klaude_code/llm/responses/client.py +216 -0
  101. klaude_code/llm/responses/input.py +167 -0
  102. klaude_code/llm/usage.py +109 -0
  103. klaude_code/protocol/__init__.py +4 -0
  104. klaude_code/protocol/commands.py +21 -0
  105. klaude_code/protocol/events.py +163 -0
  106. klaude_code/protocol/llm_param.py +147 -0
  107. klaude_code/protocol/model.py +287 -0
  108. klaude_code/protocol/op.py +89 -0
  109. klaude_code/protocol/op_handler.py +28 -0
  110. klaude_code/protocol/sub_agent.py +348 -0
  111. klaude_code/protocol/tools.py +15 -0
  112. klaude_code/session/__init__.py +4 -0
  113. klaude_code/session/export.py +624 -0
  114. klaude_code/session/selector.py +76 -0
  115. klaude_code/session/session.py +474 -0
  116. klaude_code/session/templates/export_session.html +1434 -0
  117. klaude_code/trace/__init__.py +3 -0
  118. klaude_code/trace/log.py +168 -0
  119. klaude_code/ui/__init__.py +91 -0
  120. klaude_code/ui/core/__init__.py +1 -0
  121. klaude_code/ui/core/display.py +103 -0
  122. klaude_code/ui/core/input.py +71 -0
  123. klaude_code/ui/core/stage_manager.py +55 -0
  124. klaude_code/ui/modes/__init__.py +1 -0
  125. klaude_code/ui/modes/debug/__init__.py +1 -0
  126. klaude_code/ui/modes/debug/display.py +36 -0
  127. klaude_code/ui/modes/exec/__init__.py +1 -0
  128. klaude_code/ui/modes/exec/display.py +63 -0
  129. klaude_code/ui/modes/repl/__init__.py +51 -0
  130. klaude_code/ui/modes/repl/clipboard.py +152 -0
  131. klaude_code/ui/modes/repl/completers.py +429 -0
  132. klaude_code/ui/modes/repl/display.py +60 -0
  133. klaude_code/ui/modes/repl/event_handler.py +375 -0
  134. klaude_code/ui/modes/repl/input_prompt_toolkit.py +198 -0
  135. klaude_code/ui/modes/repl/key_bindings.py +170 -0
  136. klaude_code/ui/modes/repl/renderer.py +281 -0
  137. klaude_code/ui/renderers/__init__.py +0 -0
  138. klaude_code/ui/renderers/assistant.py +21 -0
  139. klaude_code/ui/renderers/common.py +8 -0
  140. klaude_code/ui/renderers/developer.py +158 -0
  141. klaude_code/ui/renderers/diffs.py +215 -0
  142. klaude_code/ui/renderers/errors.py +16 -0
  143. klaude_code/ui/renderers/metadata.py +190 -0
  144. klaude_code/ui/renderers/sub_agent.py +71 -0
  145. klaude_code/ui/renderers/thinking.py +39 -0
  146. klaude_code/ui/renderers/tools.py +551 -0
  147. klaude_code/ui/renderers/user_input.py +65 -0
  148. klaude_code/ui/rich/__init__.py +1 -0
  149. klaude_code/ui/rich/live.py +65 -0
  150. klaude_code/ui/rich/markdown.py +308 -0
  151. klaude_code/ui/rich/quote.py +34 -0
  152. klaude_code/ui/rich/searchable_text.py +71 -0
  153. klaude_code/ui/rich/status.py +240 -0
  154. klaude_code/ui/rich/theme.py +274 -0
  155. klaude_code/ui/terminal/__init__.py +1 -0
  156. klaude_code/ui/terminal/color.py +244 -0
  157. klaude_code/ui/terminal/control.py +147 -0
  158. klaude_code/ui/terminal/notifier.py +107 -0
  159. klaude_code/ui/terminal/progress_bar.py +87 -0
  160. klaude_code/ui/utils/__init__.py +1 -0
  161. klaude_code/ui/utils/common.py +108 -0
  162. klaude_code/ui/utils/debouncer.py +42 -0
  163. klaude_code/version.py +163 -0
  164. klaude_code-1.2.6.dist-info/METADATA +178 -0
  165. klaude_code-1.2.6.dist-info/RECORD +167 -0
  166. klaude_code-1.2.6.dist-info/WHEEL +4 -0
  167. klaude_code-1.2.6.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,1434 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Klaude Code - $first_user_message</title>
7
+ <link
8
+ rel="icon"
9
+ href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%230851b2%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22><polyline points=%2216 18 22 12 16 6%22></polyline><polyline points=%228 6 2 12 8 18%22></polyline></svg>"
10
+ />
11
+ <link
12
+ href="https://cdn.jsdelivr.net/npm/@fontsource/iosevka/400.css"
13
+ rel="stylesheet"
14
+ />
15
+ <link
16
+ href="https://cdn.jsdelivr.net/npm/@fontsource/iosevka/500.css"
17
+ rel="stylesheet"
18
+ />
19
+ <link
20
+ href="https://cdn.jsdelivr.net/npm/@fontsource/iosevka/800.css"
21
+ rel="stylesheet"
22
+ />
23
+ <link
24
+ href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;700&family=IBM+Plex+Sans:wght@400;500;700&display=swap"
25
+ rel="stylesheet"
26
+ />
27
+ <style>
28
+ :root {
29
+ --bg-body: #ededed;
30
+ --bg-container: #f0f0f0;
31
+ --bg-card: #f0f0f0;
32
+ --border: #c8c8c8;
33
+ --text: #111111;
34
+ --text-dim: #64748b;
35
+ --accent: #0851b2;
36
+ --accent-dim: rgba(8, 145, 178, 0.08);
37
+ --success: #15803d;
38
+ --error: #dc2626;
39
+ --bg-error: #ffebee;
40
+ --bg-code: #f3f3f3;
41
+ --fg-inline-code: #4f4fc7;
42
+ --font-mono: "Iosevka", "SF Mono", Menlo, monospace;
43
+ --font-markdown-mono: "IBM Plex Mono", Menlo, monospace;
44
+ --font-markdown: "IBM Plex Sans", system-ui, sans-serif;
45
+ --font-weight-bold: 800;
46
+ --font-size-xs: 13px;
47
+ --font-size-sm: 14px;
48
+ --font-size-base: 15px;
49
+ --font-size-lg: 16px;
50
+ --spacing-xs: 4px;
51
+ --spacing-sm: 8px;
52
+ --spacing-md: 12px;
53
+ --spacing-lg: 16px;
54
+ --spacing-xl: 24px;
55
+ --radius-sm: 4px;
56
+ --radius-md: 6px;
57
+ }
58
+
59
+ * {
60
+ margin: 0;
61
+ padding: 0;
62
+ box-sizing: border-box;
63
+ }
64
+
65
+ body {
66
+ background-color: var(--bg-body);
67
+ color: var(--text);
68
+ font-family: var(--font-mono);
69
+ font-feature-settings: "ss18";
70
+ line-height: 1.6;
71
+ font-size: var(--font-size-lg);
72
+ -webkit-font-smoothing: antialiased;
73
+ }
74
+
75
+ .container {
76
+ max-width: 960px;
77
+ margin: 0 auto;
78
+ padding: 20px;
79
+ }
80
+
81
+ /* Header */
82
+ .header {
83
+ margin-bottom: 24px;
84
+ padding-bottom: 16px;
85
+ border-bottom: 1px solid var(--border);
86
+ }
87
+
88
+ .header h1 {
89
+ font-size: 20px;
90
+ font-weight: var(--font-weight-bold);
91
+ margin-bottom: 16px;
92
+ color: var(--text);
93
+ display: inline-block;
94
+ }
95
+
96
+ .meta-grid {
97
+ display: grid;
98
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
99
+ gap: 16px;
100
+ }
101
+
102
+ .meta-item {
103
+ display: flex;
104
+ flex-direction: column;
105
+ gap: 4px;
106
+ }
107
+
108
+ .meta-label {
109
+ font-size: var(--font-size-sm);
110
+ font-weight: var(--font-weight-bold);
111
+ text-transform: uppercase;
112
+ color: var(--text-dim);
113
+ }
114
+
115
+ .meta-value {
116
+ font-family: var(--font-mono);
117
+ font-size: var(--font-size-base);
118
+ color: var(--text);
119
+ overflow: hidden;
120
+ text-overflow: ellipsis;
121
+ white-space: nowrap;
122
+ }
123
+
124
+ /* Components - Collapsible sections */
125
+ details.collapsible-section {
126
+ background: transparent;
127
+ margin-bottom: 4px;
128
+ }
129
+
130
+ details.collapsible-section:last-of-type {
131
+ margin-bottom: 16px;
132
+ }
133
+
134
+ details.collapsible-section > summary {
135
+ padding: 4px 0;
136
+ font-family: var(--font-mono);
137
+ font-size: var(--font-size-sm);
138
+ text-transform: uppercase;
139
+ font-weight: var(--font-weight-bold);
140
+ cursor: pointer;
141
+ user-select: none;
142
+ list-style: none;
143
+ display: flex;
144
+ align-items: center;
145
+ gap: 8px;
146
+ min-height: 24px;
147
+ line-height: 1.2;
148
+ color: var(--text-dim);
149
+ transition: color 0.2s;
150
+ }
151
+
152
+ details.collapsible-section > summary:hover,
153
+ details.collapsible-section[open] > summary {
154
+ color: var(--text);
155
+ }
156
+
157
+ details.collapsible-section > summary::-webkit-details-marker {
158
+ display: none;
159
+ }
160
+ details.collapsible-section > summary::before {
161
+ content: "[+]";
162
+ color: var(--accent);
163
+ font-family: var(--font-mono);
164
+ margin-right: 4px;
165
+ display: inline-block;
166
+ min-width: 24px;
167
+ }
168
+ details.collapsible-section[open] > summary::before {
169
+ content: "[-]";
170
+ }
171
+
172
+ details.collapsible-section > .details-content {
173
+ padding: 8px 0 16px 24px;
174
+ font-size: var(--font-size-sm);
175
+ color: var(--text-dim);
176
+ overflow-x: auto;
177
+ border-left: 1px solid var(--border);
178
+ margin-left: 10px;
179
+ }
180
+
181
+ /* Messages */
182
+ .message-stream {
183
+ display: block;
184
+ }
185
+
186
+ .message-group {
187
+ display: flex;
188
+ flex-direction: column;
189
+ gap: 6px;
190
+ margin-bottom: 16px;
191
+ }
192
+
193
+ .message-header {
194
+ display: flex;
195
+ justify-content: space-between;
196
+ align-items: center;
197
+ margin-bottom: 4px;
198
+ }
199
+
200
+ .message-header .role-label {
201
+ margin-bottom: 0;
202
+ }
203
+
204
+ .role-label {
205
+ font-size: var(--font-size-sm);
206
+ font-weight: var(--font-weight-bold);
207
+ text-transform: uppercase;
208
+ margin-bottom: 4px;
209
+ color: var(--text-dim);
210
+ display: flex;
211
+ align-items: center;
212
+ gap: 8px;
213
+ width: 100%;
214
+ }
215
+ .message-header .role-label {
216
+ width: auto;
217
+ }
218
+ .role-label.user {
219
+ color: var(--accent);
220
+ }
221
+ .role-label.assistant {
222
+ color: var(--success);
223
+ }
224
+
225
+ details.developer-message {
226
+ background: transparent;
227
+ margin-bottom: 4px;
228
+ }
229
+
230
+ details.developer-message > summary {
231
+ padding: 4px 0;
232
+ font-family: var(--font-mono);
233
+ font-size: var(--font-size-xs);
234
+ text-transform: uppercase;
235
+ font-weight: var(--font-weight-bold);
236
+ cursor: pointer;
237
+ user-select: none;
238
+ list-style: none;
239
+ display: flex;
240
+ align-items: center;
241
+ gap: 8px;
242
+ min-height: 24px;
243
+ line-height: 1.2;
244
+ color: var(--text-dim);
245
+ transition: color 0.2s;
246
+ }
247
+
248
+ details.developer-message > summary:hover,
249
+ details.developer-message[open] > summary {
250
+ color: var(--text);
251
+ }
252
+
253
+ details.developer-message > summary::-webkit-details-marker {
254
+ display: none;
255
+ }
256
+ details.developer-message > summary::before {
257
+ content: "[+]";
258
+ color: var(--accent);
259
+ font-family: var(--font-mono);
260
+ margin-right: 4px;
261
+ display: inline-block;
262
+ min-width: 24px;
263
+ }
264
+ details.developer-message[open] > summary::before {
265
+ content: "[-]";
266
+ }
267
+
268
+ details.developer-message > .details-content {
269
+ padding: 8px 0 16px 24px;
270
+ font-size: var(--font-size-xs);
271
+ color: var(--text-dim);
272
+ overflow-x: auto;
273
+ border-left: 1px solid var(--border);
274
+ margin-left: 10px;
275
+ }
276
+
277
+ details.developer-message.gap-below {
278
+ margin-bottom: 16px;
279
+ }
280
+
281
+ .message-content {
282
+ background: var(--bg-card);
283
+ border: 1px solid var(--border);
284
+ border-radius: var(--radius-md);
285
+ padding: 20px;
286
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.03);
287
+ font-size: var(--font-size-base);
288
+ }
289
+ .assistant-message {
290
+ display: flex;
291
+ flex-direction: column;
292
+ gap: 8px;
293
+ }
294
+ .assistant-toolbar {
295
+ display: flex;
296
+ justify-content: flex-end;
297
+ align-items: center;
298
+ }
299
+ .raw-toggle {
300
+ border: 1px solid var(--border);
301
+ background: transparent;
302
+ color: var(--text-dim);
303
+ font-family: var(--font-mono);
304
+ font-size: var(--font-size-xs);
305
+ text-transform: uppercase;
306
+ padding: 2px 10px;
307
+ border-radius: 999px;
308
+ cursor: pointer;
309
+ transition: color 0.2s, border-color 0.2s, background 0.2s;
310
+ font-weight: var(--font-weight-bold);
311
+ }
312
+ .raw-toggle:hover {
313
+ color: var(--text);
314
+ border-color: var(--accent);
315
+ }
316
+ .raw-toggle.active {
317
+ color: var(--accent);
318
+ border-color: var(--accent);
319
+ background: var(--accent-dim);
320
+ }
321
+
322
+ .copy-raw-btn {
323
+ margin-left: 8px;
324
+ border: 1px solid var(--border);
325
+ background: transparent;
326
+ color: var(--text-dim);
327
+ font-family: var(--font-mono);
328
+ font-size: var(--font-size-xs);
329
+ text-transform: uppercase;
330
+ padding: 2px 10px;
331
+ border-radius: 999px;
332
+ cursor: pointer;
333
+ transition: color 0.2s, border-color 0.2s, background 0.2s;
334
+ font-weight: var(--font-weight-bold);
335
+ }
336
+ .copy-raw-btn:hover {
337
+ color: var(--text);
338
+ border-color: var(--accent);
339
+ }
340
+
341
+ .copy-mermaid-btn {
342
+ border: 1px solid var(--border);
343
+ background: transparent;
344
+ color: var(--text-dim);
345
+ font-family: var(--font-mono);
346
+ font-size: var(--font-size-xs);
347
+ text-transform: uppercase;
348
+ padding: 2px 10px;
349
+ border-radius: 999px;
350
+ cursor: pointer;
351
+ transition: color 0.2s, border-color 0.2s, background 0.2s;
352
+ font-weight: var(--font-weight-bold);
353
+ }
354
+ .copy-mermaid-btn:hover {
355
+ color: var(--text);
356
+ border-color: var(--accent);
357
+ }
358
+
359
+ .assistant-rendered {
360
+ width: 100%;
361
+ }
362
+ .assistant-raw {
363
+ display: none;
364
+ font-family: var(--font-mono);
365
+ font-size: var(--font-size-base);
366
+ white-space: pre-wrap;
367
+ background: var(--bg-body);
368
+ border: 1px dashed var(--border);
369
+ border-radius: var(--radius-sm);
370
+ padding: 20px;
371
+ }
372
+ .assistant-message.show-raw .assistant-rendered {
373
+ display: none;
374
+ }
375
+ .assistant-message.show-raw .assistant-raw {
376
+ display: block;
377
+ }
378
+
379
+ .message-content.user {
380
+ background: transparent;
381
+ border: none;
382
+ border-radius: 0;
383
+ padding: 0;
384
+ box-shadow: none;
385
+ font-weight: var(--font-weight-bold);
386
+ font-family: var(--font-markdown);
387
+ }
388
+
389
+ .thinking-block {
390
+ margin-top: 8px;
391
+ margin-bottom: 16px;
392
+ padding: 12px 16px;
393
+ border-left: 2px solid var(--border);
394
+ color: var(--text-dim);
395
+ font-style: italic;
396
+ font-size: var(--font-size-sm);
397
+ background: var(--bg-body);
398
+ }
399
+ .thinking-block.markdown-body p {
400
+ margin-bottom: 8px;
401
+ }
402
+ .thinking-block.markdown-body p:last-child {
403
+ margin-bottom: 0;
404
+ }
405
+
406
+ /* Response Metadata */
407
+ .response-metadata {
408
+ margin: 8px 0 16px 0;
409
+ padding: 0;
410
+ font-family: var(--font-mono);
411
+ font-size: var(--font-size-xs);
412
+ color: var(--text-dim);
413
+ border-left: 2px solid transparent;
414
+ }
415
+ .metadata-line {
416
+ display: flex;
417
+ flex-wrap: wrap;
418
+ gap: 6px;
419
+ align-items: center;
420
+ line-height: 1.4;
421
+ }
422
+ .metadata-model {
423
+ font-weight: var(--font-weight-bold);
424
+ color: var(--text);
425
+ }
426
+ .metadata-provider {
427
+ opacity: 0.8;
428
+ }
429
+ .metadata-stat {
430
+ white-space: nowrap;
431
+ }
432
+ .metadata-divider {
433
+ color: var(--border);
434
+ margin: 0 2px;
435
+ }
436
+
437
+ /* Tool Calls */
438
+ .tool-call {
439
+ margin-top: 16px;
440
+ margin-bottom: 16px;
441
+ border: 1px solid var(--border);
442
+ border-radius: var(--radius-md);
443
+ overflow: hidden;
444
+ font-size: var(--font-size-base);
445
+ }
446
+
447
+ .tool-header {
448
+ padding: 8px 12px;
449
+ background: var(--bg-container);
450
+ border-bottom: 1px solid var(--border);
451
+ display: flex;
452
+ justify-content: space-between;
453
+ align-items: center;
454
+ font-family: var(--font-mono);
455
+ }
456
+
457
+ .tool-name {
458
+ font-weight: var(--font-weight-bold);
459
+ color: var(--accent);
460
+ }
461
+ .tool-id {
462
+ color: var(--text-dim);
463
+ font-size: var(--font-size-xs);
464
+ }
465
+
466
+ .tool-header-right {
467
+ display: flex;
468
+ align-items: center;
469
+ gap: 8px;
470
+ }
471
+
472
+ .timestamp {
473
+ font-family: var(--font-mono);
474
+ font-size: var(--font-size-xs);
475
+ color: var(--text-dim);
476
+ margin-left: auto;
477
+ font-weight: normal;
478
+ }
479
+
480
+ .assistant-toolbar .timestamp {
481
+ margin-right: 8px;
482
+ }
483
+
484
+ .tool-args {
485
+ padding: 12px;
486
+ background: var(--bg-body);
487
+ font-family: var(--font-mono);
488
+ color: var(--text-dim);
489
+ overflow-x: auto;
490
+ white-space: pre-wrap;
491
+ font-size: var(--font-size-sm);
492
+ }
493
+
494
+ /* Collapsible tool-args */
495
+ details.tool-args-collapsible {
496
+ padding: 0;
497
+ background: var(--bg-body);
498
+ }
499
+ details.tool-args-collapsible > summary {
500
+ padding: 8px 12px;
501
+ font-family: var(--font-mono);
502
+ font-size: var(--font-size-xs);
503
+ text-transform: uppercase;
504
+ font-weight: var(--font-weight-bold);
505
+ cursor: pointer;
506
+ user-select: none;
507
+ list-style: none;
508
+ display: flex;
509
+ align-items: center;
510
+ gap: 8px;
511
+ color: var(--text-dim);
512
+ transition: color 0.2s;
513
+ }
514
+ details.tool-args-collapsible > summary:hover,
515
+ details.tool-args-collapsible[open] > summary {
516
+ color: var(--text);
517
+ }
518
+ details.tool-args-collapsible > summary::-webkit-details-marker {
519
+ display: none;
520
+ }
521
+ details.tool-args-collapsible > summary::before {
522
+ content: "[+]";
523
+ color: var(--accent);
524
+ font-family: var(--font-mono);
525
+ display: inline-block;
526
+ min-width: 24px;
527
+ }
528
+ details.tool-args-collapsible[open] > summary::before {
529
+ content: "[-]";
530
+ }
531
+ details.tool-args-collapsible > .tool-args-content {
532
+ padding: 12px;
533
+ font-family: var(--font-mono);
534
+ color: var(--text-dim);
535
+ overflow-x: auto;
536
+ white-space: pre-wrap;
537
+ font-size: var(--font-size-sm);
538
+ border-top: 1px dashed var(--border);
539
+ }
540
+
541
+ .tool-result {
542
+ border-top: 1px solid var(--border);
543
+ padding: 12px;
544
+ font-size: var(--font-size-sm);
545
+ }
546
+ .tool-result .full-text,
547
+ .tool-result .preview-text,
548
+ .tool-result pre,
549
+ .tool-result code {
550
+ font-size: var(--font-size-sm);
551
+ }
552
+
553
+ .tool-result.success {
554
+ background: var(--bg-card);
555
+ color: var(--text);
556
+ }
557
+ .tool-result.error {
558
+ background: var(--bg-error);
559
+ color: var(--error);
560
+ }
561
+ .tool-result.pending {
562
+ background: var(--bg-body);
563
+ color: var(--text-dim);
564
+ }
565
+
566
+ /* Sub Agent Result */
567
+ .subagent-result-container {
568
+ display: flex;
569
+ flex-direction: column;
570
+ gap: 8px;
571
+ margin-top: 8px;
572
+ }
573
+
574
+ .subagent-toolbar {
575
+ display: flex;
576
+ justify-content: flex-end;
577
+ align-items: center;
578
+ margin-bottom: 4px;
579
+ }
580
+
581
+ .subagent-content {
582
+ width: 100%;
583
+ }
584
+
585
+ .subagent-raw {
586
+ display: none;
587
+ font-family: var(--font-mono);
588
+ font-size: var(--font-size-base);
589
+ white-space: pre-wrap;
590
+ background: var(--bg-body);
591
+ border: 1px dashed var(--border);
592
+ border-radius: var(--radius-sm);
593
+ padding: 20px;
594
+ }
595
+
596
+ .subagent-content.show-raw .subagent-rendered {
597
+ display: none;
598
+ }
599
+ .subagent-content.show-raw .subagent-raw {
600
+ display: block;
601
+ }
602
+
603
+ /* Markdown Elements */
604
+ .markdown-body {
605
+ font-family: var(--font-markdown);
606
+ line-height: 1.5;
607
+ }
608
+ .markdown-body hr {
609
+ height: 0;
610
+ margin: 24px 0;
611
+ border: none;
612
+ border-top: 1px solid var(--border);
613
+ }
614
+ .markdown-body pre {
615
+ background: var(--bg-code);
616
+ padding: 16px;
617
+ border-radius: var(--radius-md);
618
+ overflow-x: auto;
619
+ margin: 12px 0;
620
+ border: 1px solid var(--border);
621
+ }
622
+ .markdown-body code {
623
+ font-family: var(--font-markdown-mono);
624
+ color: var(--fg-inline-code);
625
+ font-size: var(--font-size-sm);
626
+ padding: 2px 4px;
627
+ border-radius: var(--radius-sm);
628
+ }
629
+ .markdown-body pre code {
630
+ background: transparent;
631
+ padding: 0;
632
+ border-radius: 0;
633
+ }
634
+ .markdown-body pre code.hljs {
635
+ background: transparent;
636
+ }
637
+ .markdown-body p {
638
+ margin-bottom: 12px;
639
+ }
640
+ .markdown-body > *:first-child {
641
+ margin-top: 0;
642
+ }
643
+ .markdown-body > *:last-child {
644
+ margin-bottom: 0;
645
+ }
646
+ .markdown-body ul,
647
+ .markdown-body ol {
648
+ margin-bottom: 12px;
649
+ padding-left: 1.5rem;
650
+ list-style-position: outside;
651
+ }
652
+ .markdown-body ul ul,
653
+ .markdown-body ol ul,
654
+ .markdown-body ul ol,
655
+ .markdown-body ol ol {
656
+ margin-left: 1rem;
657
+ }
658
+
659
+ /* Diff View */
660
+ .diff-view {
661
+ font-family: var(--font-mono);
662
+ background: var(--bg-code);
663
+ padding: 12px;
664
+ border-radius: var(--radius-md);
665
+ overflow-x: auto;
666
+ border: 1px solid var(--border);
667
+ }
668
+ .diff-line {
669
+ white-space: pre;
670
+ }
671
+ .diff-plus {
672
+ color: #166534;
673
+ background: #e7f5e9;
674
+ display: block;
675
+ }
676
+ .diff-minus {
677
+ color: #991b1b;
678
+ background: #ffebee;
679
+ display: block;
680
+ }
681
+ .diff-ctx {
682
+ color: var(--text-dim);
683
+ opacity: 0.7;
684
+ display: block;
685
+ }
686
+
687
+ /* Collapsible Diff View */
688
+ details.diff-collapsible {
689
+ background: transparent;
690
+ margin-top: 8px;
691
+ }
692
+ details.diff-collapsible > summary {
693
+ padding: 4px 0;
694
+ font-family: var(--font-mono);
695
+ font-size: var(--font-size-xs);
696
+ text-transform: uppercase;
697
+ font-weight: var(--font-weight-bold);
698
+ cursor: pointer;
699
+ user-select: none;
700
+ list-style: none;
701
+ display: flex;
702
+ align-items: center;
703
+ gap: 8px;
704
+ color: var(--text-dim);
705
+ transition: color 0.2s;
706
+ }
707
+ details.diff-collapsible > summary:hover,
708
+ details.diff-collapsible[open] > summary {
709
+ color: var(--text);
710
+ }
711
+ details.diff-collapsible > summary::-webkit-details-marker {
712
+ display: none;
713
+ }
714
+ details.diff-collapsible > summary::before {
715
+ content: "[+]";
716
+ color: var(--accent);
717
+ font-family: var(--font-mono);
718
+ display: inline-block;
719
+ min-width: 24px;
720
+ }
721
+ details.diff-collapsible[open] > summary::before {
722
+ content: "[-]";
723
+ }
724
+ details.diff-collapsible > .diff-view {
725
+ margin-top: 8px;
726
+ }
727
+
728
+ .footer {
729
+ margin-top: 60px;
730
+ text-align: center;
731
+ color: var(--text-dim);
732
+ font-size: var(--font-size-sm);
733
+ border-top: 1px solid var(--border);
734
+ padding-top: 24px;
735
+ }
736
+
737
+ .footer-link {
738
+ color: inherit;
739
+ text-decoration: none;
740
+ font-weight: 600;
741
+ transition: color 0.2s;
742
+ }
743
+
744
+ .footer-link:hover {
745
+ color: var(--accent);
746
+ }
747
+
748
+ .expandable {
749
+ cursor: pointer;
750
+ }
751
+ .expandable.expanded {
752
+ cursor: auto;
753
+ }
754
+ .expandable .full-text {
755
+ display: none;
756
+ }
757
+ .expandable .collapse-hint {
758
+ display: none;
759
+ }
760
+ .expandable.expanded .preview-text {
761
+ display: none;
762
+ }
763
+ .expandable.expanded .expand-hint {
764
+ display: none;
765
+ }
766
+ .expandable.expanded .full-text {
767
+ display: block;
768
+ }
769
+ .expandable.expanded .collapse-hint {
770
+ display: block;
771
+ cursor: pointer;
772
+ color: var(--accent);
773
+ font-size: var(--font-size-xs);
774
+ margin-top: 4px;
775
+ border-top: 1px dashed var(--border);
776
+ padding-top: 4px;
777
+ }
778
+ .expand-hint {
779
+ font-size: var(--font-size-xs);
780
+ color: var(--accent);
781
+ margin-top: 4px;
782
+ }
783
+
784
+ /* Todo List */
785
+ .todo-list {
786
+ display: flex;
787
+ flex-direction: column;
788
+ gap: 6px;
789
+ }
790
+ .todo-item {
791
+ display: flex;
792
+ gap: 8px;
793
+ font-family: var(--font-mono);
794
+ font-size: var(--font-size-sm);
795
+ line-height: 1.5;
796
+ align-items: flex-start;
797
+ }
798
+ .todo-bullet {
799
+ flex-shrink: 0;
800
+ font-size: 10px;
801
+ line-height: 1.5;
802
+ opacity: 0.7;
803
+ }
804
+ .todo-item.status-completed {
805
+ color: var(--text-dim);
806
+ text-decoration: line-through;
807
+ }
808
+ .todo-item.status-in_progress {
809
+ color: var(--success);
810
+ font-weight: 500;
811
+ }
812
+ .todo-item.status-pending {
813
+ color: var(--text-dim);
814
+ }
815
+
816
+ /* Scroll to Bottom Button */
817
+ .scroll-btn {
818
+ position: fixed;
819
+ bottom: 24px;
820
+ right: 24px;
821
+ width: 40px;
822
+ height: 40px;
823
+ border-radius: 50%;
824
+ background: var(--bg-card);
825
+ border: 1px solid var(--border);
826
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
827
+ color: var(--text-dim);
828
+ display: flex;
829
+ align-items: center;
830
+ justify-content: center;
831
+ cursor: pointer;
832
+ opacity: 0;
833
+ visibility: hidden;
834
+ transform: translateY(10px);
835
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
836
+ z-index: 100;
837
+ }
838
+
839
+ .scroll-btn:hover {
840
+ color: var(--accent);
841
+ border-color: var(--accent);
842
+ transform: translateY(-2px);
843
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
844
+ }
845
+
846
+ .scroll-btn.visible {
847
+ opacity: 1;
848
+ visibility: visible;
849
+ transform: translateY(0);
850
+ }
851
+
852
+ /* Tool details in Available Tools section */
853
+ .tool-details {
854
+ margin-bottom: 2px;
855
+ }
856
+ .tool-details summary {
857
+ color: var(--accent);
858
+ font-weight: 500;
859
+ text-transform: none;
860
+ letter-spacing: normal;
861
+ cursor: pointer;
862
+ user-select: none;
863
+ list-style: none;
864
+ display: flex;
865
+ align-items: center;
866
+ gap: 8px;
867
+ }
868
+ .tool-details summary::-webkit-details-marker {
869
+ display: none;
870
+ }
871
+ .tool-details summary:hover {
872
+ color: var(--text);
873
+ }
874
+ .tool-details summary::before {
875
+ content: "[+]";
876
+ min-width: 24px;
877
+ display: inline-block;
878
+ }
879
+ .tool-details[open] summary::before {
880
+ content: "[-]";
881
+ }
882
+ .tool-description {
883
+ white-space: pre-wrap;
884
+ font-size: var(--font-size-sm);
885
+ }
886
+ .tool-params {
887
+ margin-top: 12px;
888
+ padding-top: 8px;
889
+ border-top: 1px dashed var(--border);
890
+ }
891
+ .tool-params-title {
892
+ font-size: var(--font-size-xs);
893
+ font-weight: var(--font-weight-bold);
894
+ text-transform: uppercase;
895
+ color: var(--text-dim);
896
+ margin-bottom: 8px;
897
+ }
898
+ .tool-param {
899
+ margin-bottom: 8px;
900
+ padding-left: 12px;
901
+ font-size: var(--font-size-sm);
902
+ }
903
+ .tool-param-name {
904
+ color: var(--success);
905
+ font-weight: 500;
906
+ }
907
+ .tool-param-type {
908
+ color: var(--text-dim);
909
+ }
910
+ .tool-param-required {
911
+ color: var(--error);
912
+ margin-left: 4px;
913
+ }
914
+ .tool-param-desc {
915
+ color: var(--text-dim);
916
+ font-size: var(--font-size-sm);
917
+ margin-top: 2px;
918
+ }
919
+ /* TOC Sidebar */
920
+ .toc-sidebar {
921
+ position: fixed;
922
+ top: 33vh;
923
+ left: 20px;
924
+ width: 220px;
925
+ bottom: 33vh;
926
+ overflow-y: auto;
927
+ padding-right: 12px;
928
+ /* Vertical padding to offset mask */
929
+ padding-top: 30px;
930
+ padding-bottom: 30px;
931
+ display: none;
932
+ scrollbar-width: none;
933
+ z-index: 100;
934
+ /* Linear mask for fading edges */
935
+ -webkit-mask-image: linear-gradient(
936
+ to bottom,
937
+ transparent 0%,
938
+ black 30px,
939
+ black calc(100% - 30px),
940
+ transparent 100%
941
+ );
942
+ mask-image: linear-gradient(
943
+ to bottom,
944
+ transparent 0%,
945
+ black 30px,
946
+ black calc(100% - 30px),
947
+ transparent 100%
948
+ );
949
+ }
950
+
951
+ .toc-sidebar::-webkit-scrollbar {
952
+ display: none;
953
+ }
954
+
955
+ /* Show TOC on wide screens */
956
+ @media (min-width: 1400px) {
957
+ .toc-sidebar {
958
+ display: block;
959
+ }
960
+ }
961
+
962
+ .toc-item {
963
+ display: block;
964
+ padding: 3px 10px;
965
+ margin-bottom: 1px;
966
+ font-family: var(--font-mono);
967
+ font-size: 12px;
968
+ line-height: 1.3;
969
+ color: var(--text-dim);
970
+ text-decoration: none;
971
+ cursor: pointer;
972
+ transition: all 0.2s;
973
+ white-space: nowrap;
974
+ overflow: hidden;
975
+ text-overflow: ellipsis;
976
+ border-radius: 4px;
977
+ }
978
+
979
+ .toc-item:hover {
980
+ color: var(--text);
981
+ background: rgba(0, 0, 0, 0.03);
982
+ }
983
+
984
+ .toc-item.active {
985
+ color: var(--text);
986
+ background: var(--bg-card);
987
+ font-weight: bold;
988
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
989
+ }
990
+ </style>
991
+ </head>
992
+ <body>
993
+ <div id="toc-sidebar" class="toc-sidebar"></div>
994
+ <div class="container">
995
+ <div class="header">
996
+ <h1>Klaude Code</h1>
997
+ <div class="meta-grid">
998
+ <div class="meta-item">
999
+ <span class="meta-label">First Message</span>
1000
+ <span class="meta-value" title="$first_user_message"
1001
+ >$first_user_message</span
1002
+ >
1003
+ </div>
1004
+ <div class="meta-item">
1005
+ <span class="meta-label">Model</span>
1006
+ <span class="meta-value">$model_name</span>
1007
+ </div>
1008
+ <div class="meta-item">
1009
+ <span class="meta-label">Updated</span>
1010
+ <span class="meta-value">$session_updated</span>
1011
+ </div>
1012
+ <div class="meta-item">
1013
+ <span class="meta-label">Directory</span>
1014
+ <span class="meta-value" title="$work_dir_full">$work_dir</span>
1015
+ </div>
1016
+ </div>
1017
+ </div>
1018
+
1019
+ <details class="collapsible-section">
1020
+ <summary>System Prompt</summary>
1021
+ <div
1022
+ class="details-content system-prompt-content"
1023
+ style="font-family: var(--font-mono); white-space: pre-wrap"
1024
+ >
1025
+ $system_prompt
1026
+ </div>
1027
+ </details>
1028
+
1029
+ <details class="collapsible-section">
1030
+ <summary>Available Tools</summary>
1031
+ <div class="details-content">$tools_html</div>
1032
+ </details>
1033
+
1034
+ <div class="message-stream">$messages_html</div>
1035
+
1036
+ <div class="footer">
1037
+ Generated by
1038
+ <a
1039
+ href="https://github.com/inspirepan/klaude-code"
1040
+ class="footer-link"
1041
+ target="_blank"
1042
+ >klaude-code</a
1043
+ >
1044
+ &bull; $footer_time &bull; $total_messages messages
1045
+ </div>
1046
+ </div>
1047
+
1048
+ <div id="scroll-btn" class="scroll-btn" title="Scroll to bottom">
1049
+ <svg
1050
+ xmlns="http://www.w3.org/2000/svg"
1051
+ width="20"
1052
+ height="20"
1053
+ viewBox="0 0 24 24"
1054
+ fill="none"
1055
+ stroke="currentColor"
1056
+ stroke-width="2"
1057
+ stroke-linecap="round"
1058
+ stroke-linejoin="round"
1059
+ >
1060
+ <line x1="12" y1="5" x2="12" y2="19"></line>
1061
+ <polyline points="19 12 12 19 5 12"></polyline>
1062
+ </svg>
1063
+ </div>
1064
+
1065
+ <link
1066
+ rel="stylesheet"
1067
+ href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/styles/github.min.css"
1068
+ />
1069
+ <script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/highlight.min.js"></script>
1070
+ <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
1071
+ <script type="module">
1072
+ import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs";
1073
+ mermaid.initialize({
1074
+ startOnLoad: true,
1075
+ theme: "neutral",
1076
+ fontFamily: '"Iosevka", "SF Mono", Menlo, monospace',
1077
+ });
1078
+ </script>
1079
+ <script>
1080
+ // Markdown rendering and Syntax Highlighting
1081
+ document.querySelectorAll(".markdown-content").forEach((el) => {
1082
+ const raw = el.dataset.raw;
1083
+ if (raw && window.marked) {
1084
+ // 1. Render Markdown
1085
+ el.innerHTML = window.marked.parse(raw);
1086
+
1087
+ // 2. Apply Syntax Highlighting to generated code blocks
1088
+ if (window.hljs) {
1089
+ el.querySelectorAll("pre code").forEach((block) => {
1090
+ hljs.highlightElement(block);
1091
+ });
1092
+ }
1093
+ }
1094
+ });
1095
+
1096
+ // Expandable tool outputs
1097
+ document.querySelectorAll(".expandable").forEach((el) => {
1098
+ el.addEventListener("click", (e) => {
1099
+ if (!el.classList.contains("expanded")) {
1100
+ el.classList.add("expanded");
1101
+ } else if (e.target.classList.contains("collapse-hint")) {
1102
+ el.classList.remove("expanded");
1103
+ }
1104
+ });
1105
+ });
1106
+
1107
+ // Assistant raw toggle
1108
+ document.querySelectorAll(".assistant-message-group").forEach((group) => {
1109
+ const toggle = group.querySelector(".raw-toggle");
1110
+ const copyBtn = group.querySelector(".copy-raw-btn");
1111
+ const block = group.querySelector(".assistant-message");
1112
+ const rendered = block
1113
+ ? block.querySelector(".assistant-rendered")
1114
+ : null;
1115
+ const raw = block ? block.querySelector(".assistant-raw") : null;
1116
+
1117
+ // Copy button logic
1118
+ if (copyBtn && rendered) {
1119
+ copyBtn.addEventListener("click", async (e) => {
1120
+ e.stopPropagation();
1121
+ const rawContent = rendered.dataset.raw;
1122
+ if (!rawContent) return;
1123
+
1124
+ try {
1125
+ // Decode HTML entities for copy
1126
+ const textarea = document.createElement("textarea");
1127
+ textarea.innerHTML = rawContent;
1128
+ const decoded = textarea.value;
1129
+
1130
+ await navigator.clipboard.writeText(decoded);
1131
+
1132
+ // Visual feedback
1133
+ const originalText = copyBtn.textContent;
1134
+ copyBtn.textContent = "Copied!";
1135
+ copyBtn.style.color = "var(--success)";
1136
+ copyBtn.style.borderColor = "var(--success)";
1137
+
1138
+ setTimeout(() => {
1139
+ copyBtn.textContent = originalText;
1140
+ copyBtn.style.color = "";
1141
+ copyBtn.style.borderColor = "";
1142
+ }, 2000);
1143
+ } catch (err) {
1144
+ console.error("Failed to copy:", err);
1145
+ copyBtn.textContent = "Error";
1146
+ copyBtn.style.color = "var(--error)";
1147
+ setTimeout(() => {
1148
+ copyBtn.textContent = "Copy";
1149
+ copyBtn.style.color = "";
1150
+ }, 2000);
1151
+ }
1152
+ });
1153
+ }
1154
+
1155
+ if (!toggle || !rendered || !raw) {
1156
+ return;
1157
+ }
1158
+
1159
+ const setState = (showRaw) => {
1160
+ block.classList.toggle("show-raw", showRaw);
1161
+ toggle.classList.toggle("active", showRaw);
1162
+ toggle.setAttribute("aria-pressed", String(showRaw));
1163
+ toggle.textContent = showRaw ? "Markdown" : "Raw";
1164
+ };
1165
+
1166
+ toggle.addEventListener("click", (event) => {
1167
+ event.stopPropagation();
1168
+ const nextState = !block.classList.contains("show-raw");
1169
+ setState(nextState);
1170
+ });
1171
+ });
1172
+
1173
+ // Subagent raw toggle
1174
+ document
1175
+ .querySelectorAll(".subagent-result-container")
1176
+ .forEach((group) => {
1177
+ const toggle = group.querySelector(".raw-toggle");
1178
+ const copyBtn = group.querySelector(".copy-raw-btn");
1179
+ const block = group.querySelector(".subagent-content");
1180
+ const rendered = block
1181
+ ? block.querySelector(".subagent-rendered")
1182
+ : null;
1183
+ const raw = block ? block.querySelector(".subagent-raw") : null;
1184
+
1185
+ // Copy button logic
1186
+ if (copyBtn && rendered) {
1187
+ copyBtn.addEventListener("click", async (e) => {
1188
+ e.stopPropagation();
1189
+ const rawContent = rendered.dataset.raw;
1190
+ if (!rawContent) return;
1191
+
1192
+ try {
1193
+ const textarea = document.createElement("textarea");
1194
+ textarea.innerHTML = rawContent;
1195
+ const decoded = textarea.value;
1196
+
1197
+ await navigator.clipboard.writeText(decoded);
1198
+
1199
+ const originalText = copyBtn.textContent;
1200
+ copyBtn.textContent = "Copied!";
1201
+ copyBtn.style.color = "var(--success)";
1202
+ copyBtn.style.borderColor = "var(--success)";
1203
+
1204
+ setTimeout(() => {
1205
+ copyBtn.textContent = originalText;
1206
+ copyBtn.style.color = "";
1207
+ copyBtn.style.borderColor = "";
1208
+ }, 2000);
1209
+ } catch (err) {
1210
+ console.error("Failed to copy:", err);
1211
+ copyBtn.textContent = "Error";
1212
+ copyBtn.style.color = "var(--error)";
1213
+ setTimeout(() => {
1214
+ copyBtn.textContent = "Copy";
1215
+ copyBtn.style.color = "";
1216
+ }, 2000);
1217
+ }
1218
+ });
1219
+ }
1220
+
1221
+ if (!toggle || !rendered || !raw) {
1222
+ return;
1223
+ }
1224
+
1225
+ const setState = (showRaw) => {
1226
+ block.classList.toggle("show-raw", showRaw);
1227
+ toggle.classList.toggle("active", showRaw);
1228
+ toggle.setAttribute("aria-pressed", String(showRaw));
1229
+ toggle.textContent = showRaw ? "Markdown" : "Raw";
1230
+ };
1231
+
1232
+ toggle.addEventListener("click", (event) => {
1233
+ event.stopPropagation();
1234
+ const nextState = !block.classList.contains("show-raw");
1235
+ setState(nextState);
1236
+ });
1237
+ });
1238
+
1239
+ // Mermaid copy button
1240
+ document.querySelectorAll(".copy-mermaid-btn").forEach((btn) => {
1241
+ btn.addEventListener("click", async (e) => {
1242
+ e.stopPropagation();
1243
+ const rawContent = btn.dataset.code;
1244
+ if (!rawContent) return;
1245
+
1246
+ try {
1247
+ const textarea = document.createElement("textarea");
1248
+ textarea.innerHTML = rawContent;
1249
+ const decoded = textarea.value;
1250
+
1251
+ await navigator.clipboard.writeText(decoded);
1252
+
1253
+ const originalText = btn.textContent;
1254
+ btn.textContent = "Copied!";
1255
+ btn.style.color = "var(--success)";
1256
+ btn.style.borderColor = "var(--success)";
1257
+
1258
+ setTimeout(() => {
1259
+ btn.textContent = originalText;
1260
+ btn.style.color = "";
1261
+ btn.style.borderColor = "";
1262
+ }, 2000);
1263
+ } catch (err) {
1264
+ console.error("Failed to copy:", err);
1265
+ btn.textContent = "Error";
1266
+ btn.style.color = "var(--error)";
1267
+ setTimeout(() => {
1268
+ btn.textContent = "Copy Code";
1269
+ btn.style.color = "";
1270
+ }, 2000);
1271
+ }
1272
+ });
1273
+ });
1274
+
1275
+ // Scroll to bottom button
1276
+ const scrollBtn = document.getElementById("scroll-btn");
1277
+
1278
+ function updateScrollBtn() {
1279
+ // Show button if we are not at the bottom
1280
+ const isAtBottom =
1281
+ window.innerHeight + window.scrollY >=
1282
+ document.body.offsetHeight - 100;
1283
+ if (isAtBottom) {
1284
+ scrollBtn.classList.remove("visible");
1285
+ } else {
1286
+ scrollBtn.classList.add("visible");
1287
+ }
1288
+ }
1289
+
1290
+ window.addEventListener("scroll", updateScrollBtn);
1291
+ window.addEventListener("resize", updateScrollBtn);
1292
+ updateScrollBtn(); // Initial check
1293
+
1294
+ scrollBtn.addEventListener("click", () => {
1295
+ window.scrollTo({
1296
+ top: document.body.scrollHeight,
1297
+ behavior: "smooth",
1298
+ });
1299
+ });
1300
+
1301
+ // TOC Logic
1302
+ document.addEventListener("DOMContentLoaded", () => {
1303
+ const tocSidebar = document.getElementById("toc-sidebar");
1304
+ if (!tocSidebar) return;
1305
+
1306
+ const sections = [];
1307
+ let userCount = 0;
1308
+ let assistantCount = 0;
1309
+
1310
+ // 1. System Prompt
1311
+ const sysPrompt = document.querySelector(
1312
+ ".collapsible-section summary"
1313
+ );
1314
+ if (sysPrompt && sysPrompt.textContent.includes("System Prompt")) {
1315
+ const details = sysPrompt.parentElement;
1316
+ details.id = details.id || "section-system-prompt";
1317
+ sections.push({
1318
+ id: details.id,
1319
+ label: "System Prompt",
1320
+ el: details,
1321
+ });
1322
+ }
1323
+
1324
+ // 2. Messages and Tools
1325
+ const stream = document.querySelector(".message-stream");
1326
+ if (stream) {
1327
+ // Use a Walker to find top-level relevant items if structure is complex
1328
+ // But assuming flat children of message-stream based on CSS
1329
+ Array.from(stream.children).forEach((child) => {
1330
+ let label = null;
1331
+ let idPrefix = "section";
1332
+
1333
+ if (child.classList.contains("message-group")) {
1334
+ const roleLabel = child.querySelector(".role-label");
1335
+ if (roleLabel) {
1336
+ if (roleLabel.classList.contains("user")) {
1337
+ userCount++;
1338
+ label = `USER $${userCount}`;
1339
+ idPrefix = "user";
1340
+ } else if (roleLabel.classList.contains("assistant")) {
1341
+ assistantCount++;
1342
+ label = `ASSISTANT $${assistantCount}`;
1343
+ idPrefix = "assistant";
1344
+ } else {
1345
+ label = roleLabel.textContent.trim();
1346
+ }
1347
+ }
1348
+ } else if (child.classList.contains("tool-call")) {
1349
+ const toolName = child.querySelector(".tool-name");
1350
+ if (toolName) {
1351
+ label = toolName.textContent.trim();
1352
+ idPrefix = "tool";
1353
+ } else {
1354
+ label = "Tool";
1355
+ }
1356
+ }
1357
+
1358
+ if (label) {
1359
+ child.id =
1360
+ child.id ||
1361
+ `$${idPrefix}-$${Math.random().toString(36).substr(2, 9)}`;
1362
+ sections.push({ id: child.id, label: label, el: child });
1363
+ }
1364
+ });
1365
+ }
1366
+
1367
+ // Render TOC
1368
+ sections.forEach((section) => {
1369
+ const item = document.createElement("div");
1370
+ item.className = "toc-item";
1371
+ item.textContent = section.label;
1372
+ item.dataset.target = section.id;
1373
+ item.addEventListener("click", () => {
1374
+ section.el.scrollIntoView({ behavior: "smooth", block: "start" });
1375
+ });
1376
+ tocSidebar.appendChild(item);
1377
+ });
1378
+
1379
+ // Scroll Spy with throttling
1380
+ let ticking = false;
1381
+ const offset = 150; // Pixel offset for "active" area
1382
+
1383
+ function updateActiveSection() {
1384
+ let currentId = sections.length > 0 ? sections[0].id : null;
1385
+ const scrollY = window.scrollY;
1386
+
1387
+ // We look for the last section that has passed the top threshold (+ offset)
1388
+ for (let i = 0; i < sections.length; i++) {
1389
+ const el = sections[i].el;
1390
+ // If element top is above the "active line" (scrollY + offset)
1391
+ if (el.offsetTop <= scrollY + offset) {
1392
+ currentId = sections[i].id;
1393
+ } else {
1394
+ // Since sections are ordered by position, we can stop once we find one below the line
1395
+ break;
1396
+ }
1397
+ }
1398
+
1399
+ // Update UI
1400
+ document.querySelectorAll(".toc-item").forEach((item) => {
1401
+ const isActive = item.dataset.target === currentId;
1402
+ if (item.classList.contains("active") !== isActive) {
1403
+ item.classList.toggle("active", isActive);
1404
+ if (isActive) {
1405
+ // Auto-scroll sidebar to visible
1406
+ const sidebarRect = tocSidebar.getBoundingClientRect();
1407
+ const itemRect = item.getBoundingClientRect();
1408
+ // Check if item is out of view in sidebar (accounting for mask)
1409
+ if (
1410
+ itemRect.top < sidebarRect.top + 40 ||
1411
+ itemRect.bottom > sidebarRect.bottom - 40
1412
+ ) {
1413
+ item.scrollIntoView({ behavior: "smooth", block: "center" });
1414
+ }
1415
+ }
1416
+ }
1417
+ });
1418
+
1419
+ ticking = false;
1420
+ }
1421
+
1422
+ window.addEventListener("scroll", () => {
1423
+ if (!ticking) {
1424
+ window.requestAnimationFrame(updateActiveSection);
1425
+ ticking = true;
1426
+ }
1427
+ });
1428
+
1429
+ // Initial update
1430
+ updateActiveSection();
1431
+ });
1432
+ </script>
1433
+ </body>
1434
+ </html>