transcript-viewer 0.1.0

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 (34) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +154 -0
  4. data/assets/dark.json +85 -0
  5. data/assets/template.css +1078 -0
  6. data/lib/transcript_viewer/configuration.rb +17 -0
  7. data/lib/transcript_viewer/page.rb +42 -0
  8. data/lib/transcript_viewer/renderer.rb +367 -0
  9. data/lib/transcript_viewer/support.rb +38 -0
  10. data/lib/transcript_viewer/templates/app.html.erb +10 -0
  11. data/lib/transcript_viewer/templates/assistant_block.html.erb +10 -0
  12. data/lib/transcript_viewer/templates/compaction.html.erb +3 -0
  13. data/lib/transcript_viewer/templates/entry.html.erb +3 -0
  14. data/lib/transcript_viewer/templates/fetch_tool_table.html.erb +1 -0
  15. data/lib/transcript_viewer/templates/fork_bar.html.erb +1 -0
  16. data/lib/transcript_viewer/templates/hamburger.html.erb +3 -0
  17. data/lib/transcript_viewer/templates/header.html.erb +5 -0
  18. data/lib/transcript_viewer/templates/info_item.html.erb +1 -0
  19. data/lib/transcript_viewer/templates/main_content.html.erb +11 -0
  20. data/lib/transcript_viewer/templates/message_entry.html.erb +8 -0
  21. data/lib/transcript_viewer/templates/message_tree_content.html.erb +2 -0
  22. data/lib/transcript_viewer/templates/script.html.erb +80 -0
  23. data/lib/transcript_viewer/templates/server_tool_use.html.erb +4 -0
  24. data/lib/transcript_viewer/templates/session.html.erb +13 -0
  25. data/lib/transcript_viewer/templates/sidebar.html.erb +1 -0
  26. data/lib/transcript_viewer/templates/tool_call.html.erb +6 -0
  27. data/lib/transcript_viewer/templates/tree_content.html.erb +2 -0
  28. data/lib/transcript_viewer/templates/tree_node.html.erb +4 -0
  29. data/lib/transcript_viewer/tool_execution.rb +74 -0
  30. data/lib/transcript_viewer/tool_template_registry.rb +67 -0
  31. data/lib/transcript_viewer/version.rb +5 -0
  32. data/lib/transcript_viewer/view.rb +475 -0
  33. data/lib/transcript_viewer.rb +47 -0
  34. metadata +76 -0
@@ -0,0 +1,1078 @@
1
+ :root {
2
+ {{THEME_VARS}}
3
+ --body-bg: {{BODY_BG}};
4
+ --container-bg: {{CONTAINER_BG}};
5
+ --info-bg: {{INFO_BG}};
6
+ }
7
+
8
+ * { margin: 0; padding: 0; box-sizing: border-box; }
9
+
10
+ :root {
11
+ --line-height: 18px; /* 12px font * 1.5 */
12
+ --sidebar-width: 400px;
13
+ --sidebar-min-width: 240px;
14
+ --sidebar-max-width: 840px;
15
+ --sidebar-resizer-width: 6px;
16
+ }
17
+
18
+ html {
19
+ scroll-behavior: smooth;
20
+ }
21
+
22
+ @media (prefers-reduced-motion: reduce) {
23
+ html {
24
+ scroll-behavior: auto;
25
+ }
26
+ }
27
+
28
+ body {
29
+ font-family: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono', monospace;
30
+ font-size: 12px;
31
+ line-height: var(--line-height);
32
+ color: var(--text);
33
+ background: var(--body-bg);
34
+ }
35
+
36
+ body.sidebar-resizing {
37
+ cursor: col-resize;
38
+ user-select: none;
39
+ }
40
+
41
+ #app {
42
+ display: flex;
43
+ min-height: 100vh;
44
+ }
45
+
46
+ /* Sidebar */
47
+ #sidebar {
48
+ width: var(--sidebar-width);
49
+ min-width: var(--sidebar-width);
50
+ max-width: var(--sidebar-width);
51
+ background: var(--container-bg);
52
+ flex-shrink: 0;
53
+ display: flex;
54
+ flex-direction: column;
55
+ position: sticky;
56
+ top: 0;
57
+ height: 100vh;
58
+ border-right: 1px solid var(--dim);
59
+ }
60
+
61
+ #sidebar-resizer {
62
+ width: var(--sidebar-resizer-width);
63
+ flex-shrink: 0;
64
+ position: sticky;
65
+ top: 0;
66
+ height: 100vh;
67
+ cursor: col-resize;
68
+ touch-action: none;
69
+ background: transparent;
70
+ border-right: 1px solid transparent;
71
+ }
72
+
73
+ #sidebar-resizer:hover,
74
+ body.sidebar-resizing #sidebar-resizer {
75
+ background: var(--selectedBg);
76
+ border-right-color: var(--dim);
77
+ }
78
+
79
+ .sidebar-header {
80
+ padding: 8px 12px;
81
+ flex-shrink: 0;
82
+ }
83
+
84
+ .sidebar-controls {
85
+ padding: 8px 8px 4px 8px;
86
+ }
87
+
88
+ .sidebar-search {
89
+ width: 100%;
90
+ box-sizing: border-box;
91
+ padding: 4px 8px;
92
+ font-size: 11px;
93
+ font-family: inherit;
94
+ background: var(--body-bg);
95
+ color: var(--text);
96
+ border: 1px solid var(--dim);
97
+ border-radius: 3px;
98
+ }
99
+
100
+ .sidebar-filters {
101
+ display: flex;
102
+ padding: 4px 8px 8px 8px;
103
+ gap: 4px;
104
+ align-items: center;
105
+ flex-wrap: wrap;
106
+ }
107
+
108
+ .sidebar-search:focus {
109
+ outline: none;
110
+ border-color: var(--accent);
111
+ }
112
+
113
+ .sidebar-search::placeholder {
114
+ color: var(--muted);
115
+ }
116
+
117
+ .filter-btn {
118
+ padding: 3px 8px;
119
+ font-size: 10px;
120
+ font-family: inherit;
121
+ background: transparent;
122
+ color: var(--muted);
123
+ border: 1px solid var(--dim);
124
+ border-radius: 3px;
125
+ cursor: pointer;
126
+ }
127
+
128
+ .filter-btn:hover {
129
+ color: var(--text);
130
+ border-color: var(--text);
131
+ }
132
+
133
+ .filter-btn.active {
134
+ background: var(--accent);
135
+ color: var(--body-bg);
136
+ border-color: var(--accent);
137
+ }
138
+
139
+ .sidebar-close {
140
+ display: none;
141
+ padding: 3px 8px;
142
+ font-size: 12px;
143
+ font-family: inherit;
144
+ background: transparent;
145
+ color: var(--muted);
146
+ border: 1px solid var(--dim);
147
+ border-radius: 3px;
148
+ cursor: pointer;
149
+ margin-left: auto;
150
+ }
151
+
152
+ .sidebar-close:hover {
153
+ color: var(--text);
154
+ border-color: var(--text);
155
+ }
156
+
157
+ .tree-container {
158
+ flex: 1;
159
+ overflow: auto;
160
+ padding: 4px 0;
161
+ }
162
+
163
+ .tree-node {
164
+ padding: 0 8px;
165
+ cursor: pointer;
166
+ display: flex;
167
+ align-items: baseline;
168
+ font-size: 11px;
169
+ line-height: 13px;
170
+ white-space: nowrap;
171
+ text-decoration: none;
172
+ }
173
+
174
+ .tree-node:hover {
175
+ background: var(--selectedBg);
176
+ }
177
+
178
+ .tree-node.active {
179
+ background: var(--selectedBg);
180
+ }
181
+
182
+ .tree-node.active .tree-content {
183
+ font-weight: bold;
184
+ }
185
+
186
+ .tree-prefix {
187
+ color: var(--muted);
188
+ flex-shrink: 0;
189
+ font-family: monospace;
190
+ white-space: pre;
191
+ }
192
+
193
+ .tree-marker {
194
+ color: var(--accent);
195
+ flex-shrink: 0;
196
+ }
197
+
198
+ .tree-content {
199
+ color: var(--text);
200
+ }
201
+
202
+ .tree-role-user {
203
+ color: var(--accent);
204
+ }
205
+
206
+ .tree-role-assistant {
207
+ color: var(--success);
208
+ }
209
+
210
+ .tree-role-tool {
211
+ color: var(--muted);
212
+ }
213
+
214
+ .tree-muted {
215
+ color: var(--muted);
216
+ }
217
+
218
+ .tree-error {
219
+ color: var(--error);
220
+ }
221
+
222
+ .tree-compaction {
223
+ color: var(--borderAccent);
224
+ }
225
+
226
+ .tree-fork-boundary {
227
+ color: var(--warning);
228
+ font-weight: bold;
229
+ }
230
+
231
+ .tree-branch-summary {
232
+ color: var(--warning);
233
+ }
234
+
235
+ .tree-custom-message {
236
+ color: var(--customMessageLabel);
237
+ }
238
+
239
+ .tree-status {
240
+ padding: 4px 12px;
241
+ font-size: 10px;
242
+ color: var(--muted);
243
+ flex-shrink: 0;
244
+ }
245
+
246
+ /* Main content */
247
+ #content {
248
+ flex: 1;
249
+ min-width: 0;
250
+ overflow-y: auto;
251
+ padding: var(--line-height) calc(var(--line-height) * 2);
252
+ display: flex;
253
+ flex-direction: column;
254
+ align-items: center;
255
+ }
256
+
257
+ #content > * {
258
+ width: 100%;
259
+ max-width: 800px;
260
+ }
261
+
262
+ /* Help bar */
263
+ .help-bar {
264
+ font-size: 11px;
265
+ color: var(--warning);
266
+ margin-bottom: var(--line-height);
267
+ display: flex;
268
+ align-items: center;
269
+ justify-content: space-between;
270
+ flex-wrap: wrap;
271
+ gap: 12px;
272
+ }
273
+
274
+ .help-hint {
275
+ flex: 1 1 240px;
276
+ }
277
+
278
+ .help-actions {
279
+ display: flex;
280
+ align-items: center;
281
+ flex-wrap: wrap;
282
+ gap: 8px;
283
+ }
284
+
285
+ .header-toggle-btn,
286
+ .download-json-btn {
287
+ font-size: 10px;
288
+ padding: 2px 8px;
289
+ background: var(--container-bg);
290
+ border: 1px solid var(--border);
291
+ border-radius: 3px;
292
+ color: var(--text);
293
+ cursor: pointer;
294
+ font-family: inherit;
295
+ }
296
+
297
+ .header-toggle-btn:hover,
298
+ .download-json-btn:hover {
299
+ background: var(--hover);
300
+ border-color: var(--borderAccent);
301
+ }
302
+
303
+ /* Header */
304
+ .header {
305
+ background: var(--container-bg);
306
+ border-radius: 4px;
307
+ padding: var(--line-height);
308
+ margin-bottom: var(--line-height);
309
+ }
310
+
311
+ .header h1 {
312
+ font-size: 12px;
313
+ font-weight: bold;
314
+ color: var(--borderAccent);
315
+ margin-bottom: var(--line-height);
316
+ }
317
+
318
+ .header-info {
319
+ display: flex;
320
+ flex-direction: column;
321
+ gap: 0;
322
+ font-size: 11px;
323
+ }
324
+
325
+ .info-item {
326
+ color: var(--dim);
327
+ display: flex;
328
+ align-items: baseline;
329
+ }
330
+
331
+ .info-label {
332
+ font-weight: 600;
333
+ margin-right: 8px;
334
+ min-width: 100px;
335
+ }
336
+
337
+ .info-value {
338
+ color: var(--text);
339
+ flex: 1;
340
+ }
341
+
342
+ .forked-transcript-bar {
343
+ background: var(--container-bg);
344
+ border: 1px solid var(--border);
345
+ border-radius: 4px;
346
+ color: var(--text);
347
+ font-size: 11px;
348
+ margin-bottom: var(--line-height);
349
+ padding: calc(var(--line-height) / 2) var(--line-height);
350
+ display: flex;
351
+ align-items: center;
352
+ justify-content: space-between;
353
+ gap: 12px;
354
+ }
355
+
356
+ /* Messages */
357
+ #messages {
358
+ display: flex;
359
+ flex-direction: column;
360
+ gap: var(--line-height);
361
+ }
362
+
363
+ .message-timestamp {
364
+ font-size: 10px;
365
+ color: var(--dim);
366
+ opacity: 0.8;
367
+ }
368
+
369
+ .user-message {
370
+ background: var(--userMessageBg);
371
+ color: var(--userMessageText);
372
+ padding: var(--line-height);
373
+ border-radius: 4px;
374
+ position: relative;
375
+ }
376
+
377
+ .assistant-message {
378
+ padding: 0;
379
+ position: relative;
380
+ }
381
+
382
+ /* Copy link button - appears on hover */
383
+ .copy-link-btn {
384
+ position: absolute;
385
+ top: 8px;
386
+ right: 8px;
387
+ width: 28px;
388
+ height: 28px;
389
+ padding: 6px;
390
+ background: var(--container-bg);
391
+ border: 1px solid var(--dim);
392
+ border-radius: 4px;
393
+ color: var(--muted);
394
+ cursor: pointer;
395
+ opacity: 0;
396
+ transition: opacity 0.15s, background 0.15s, color 0.15s;
397
+ display: flex;
398
+ align-items: center;
399
+ justify-content: center;
400
+ z-index: 10;
401
+ }
402
+
403
+ .user-message:hover .copy-link-btn,
404
+ .assistant-message:hover .copy-link-btn {
405
+ opacity: 1;
406
+ }
407
+
408
+ .copy-link-btn:hover {
409
+ background: var(--accent);
410
+ color: var(--body-bg);
411
+ border-color: var(--accent);
412
+ }
413
+
414
+ .copy-link-btn.copied {
415
+ background: var(--success, #22c55e);
416
+ color: white;
417
+ border-color: var(--success, #22c55e);
418
+ }
419
+
420
+ /* Highlight effect for deep-linked messages */
421
+ .user-message.highlight,
422
+ .assistant-message.highlight,
423
+ .user-message:target,
424
+ .assistant-message:target,
425
+ .compaction:target {
426
+ animation: highlight-pulse 2s ease-out;
427
+ }
428
+
429
+ @keyframes highlight-pulse {
430
+ 0% {
431
+ box-shadow: 0 0 0 3px var(--accent);
432
+ }
433
+ 100% {
434
+ box-shadow: 0 0 0 0 transparent;
435
+ }
436
+ }
437
+
438
+ .assistant-message > .message-timestamp {
439
+ padding-left: var(--line-height);
440
+ }
441
+
442
+ .assistant-text {
443
+ padding: var(--line-height);
444
+ padding-bottom: 0;
445
+ }
446
+
447
+ .message-timestamp + .assistant-text,
448
+ .message-timestamp + .thinking-block {
449
+ padding-top: 0;
450
+ }
451
+
452
+ .thinking-block + .assistant-text {
453
+ padding-top: 0;
454
+ }
455
+
456
+ body.hide-thinking .thinking-block {
457
+ display: none;
458
+ }
459
+
460
+ body.hide-tools .tool-execution {
461
+ display: none;
462
+ }
463
+
464
+ body.hide-tools .assistant-text + .tool-execution {
465
+ margin-top: 0;
466
+ }
467
+
468
+ .header-toggle-btn.active {
469
+ background: var(--accent);
470
+ color: var(--body-bg);
471
+ border-color: var(--accent);
472
+ }
473
+
474
+ .thinking-text {
475
+ padding: var(--line-height);
476
+ color: var(--thinkingText);
477
+ font-style: italic;
478
+ white-space: pre-wrap;
479
+ }
480
+
481
+ .message-timestamp + .thinking-block .thinking-text,
482
+ .message-timestamp + .thinking-block .thinking-collapsed {
483
+ padding-top: 0;
484
+ }
485
+
486
+ .thinking-collapsed {
487
+ display: none;
488
+ padding: var(--line-height);
489
+ color: var(--thinkingText);
490
+ font-style: italic;
491
+ }
492
+
493
+ /* Tool execution */
494
+ .tool-execution {
495
+ padding: var(--line-height);
496
+ border-radius: 4px;
497
+ }
498
+
499
+ .tool-execution + .tool-execution {
500
+ margin-top: var(--line-height);
501
+ }
502
+
503
+ .assistant-text + .tool-execution {
504
+ margin-top: var(--line-height);
505
+ }
506
+
507
+ .tool-execution.pending { background: var(--toolPendingBg); }
508
+ .tool-execution.success { background: var(--toolSuccessBg); }
509
+ .tool-execution.error { background: var(--toolErrorBg); }
510
+
511
+ .tool-header, .tool-name {
512
+ font-weight: bold;
513
+ }
514
+
515
+ .tool-path {
516
+ color: var(--accent);
517
+ word-break: break-all;
518
+ }
519
+
520
+ .line-numbers {
521
+ color: var(--warning);
522
+ }
523
+
524
+ .line-count {
525
+ color: var(--dim);
526
+ }
527
+
528
+ .tool-command {
529
+ font-weight: bold;
530
+ white-space: pre-wrap;
531
+ word-wrap: break-word;
532
+ overflow-wrap: break-word;
533
+ word-break: break-word;
534
+ }
535
+
536
+ .tool-output {
537
+ margin-top: var(--line-height);
538
+ color: var(--toolOutput);
539
+ word-wrap: break-word;
540
+ overflow-wrap: break-word;
541
+ word-break: break-word;
542
+ font-family: inherit;
543
+ overflow-x: auto;
544
+ }
545
+
546
+ .tool-output > div,
547
+ .output-preview,
548
+ .output-full {
549
+ margin: 0;
550
+ padding: 0;
551
+ line-height: var(--line-height);
552
+ }
553
+
554
+ .tool-output pre {
555
+ margin: 0;
556
+ padding: 0;
557
+ font-family: inherit;
558
+ color: inherit;
559
+ white-space: pre-wrap;
560
+ word-wrap: break-word;
561
+ overflow-wrap: break-word;
562
+ }
563
+
564
+ .tool-output code {
565
+ padding: 0;
566
+ background: none;
567
+ color: var(--text);
568
+ }
569
+
570
+ .fetch-tool-result table {
571
+ border-collapse: collapse;
572
+ min-width: 100%;
573
+ font-family: inherit;
574
+ color: inherit;
575
+ background: transparent;
576
+ }
577
+
578
+ .fetch-tool-result th,
579
+ .fetch-tool-result td {
580
+ padding: 0 calc(var(--line-height) / 2);
581
+ border: 1px solid currentColor;
582
+ background: transparent;
583
+ text-align: left;
584
+ vertical-align: top;
585
+ white-space: nowrap;
586
+ }
587
+
588
+ .fetch-tool-result th {
589
+ color: inherit;
590
+ font-weight: bold;
591
+ }
592
+
593
+ .tool-output.expandable {
594
+ cursor: pointer;
595
+ }
596
+
597
+ .tool-output.expandable:hover {
598
+ opacity: 0.9;
599
+ }
600
+
601
+ .tool-output.expandable .output-full {
602
+ display: none;
603
+ }
604
+
605
+ .tool-output.expandable.expanded .output-preview {
606
+ display: none;
607
+ }
608
+
609
+ .tool-output.expandable.expanded .output-full {
610
+ display: block;
611
+ }
612
+
613
+ .ansi-line {
614
+ white-space: pre-wrap;
615
+ }
616
+
617
+ .tool-images {
618
+ }
619
+
620
+ .tool-image {
621
+ max-width: 100%;
622
+ max-height: 500px;
623
+ border-radius: 4px;
624
+ margin: var(--line-height) 0;
625
+ }
626
+
627
+ .expand-hint {
628
+ color: var(--toolOutput);
629
+ }
630
+
631
+ /* Diff */
632
+ .tool-diff {
633
+ font-size: 11px;
634
+ overflow-x: auto;
635
+ white-space: pre;
636
+ }
637
+
638
+ .diff-added { color: var(--toolDiffAdded); }
639
+ .diff-removed { color: var(--toolDiffRemoved); }
640
+ .diff-context { color: var(--toolDiffContext); }
641
+
642
+ /* Model change */
643
+ .model-change {
644
+ padding: 0 var(--line-height);
645
+ color: var(--dim);
646
+ font-size: 11px;
647
+ }
648
+
649
+ .model-name {
650
+ color: var(--borderAccent);
651
+ font-weight: bold;
652
+ }
653
+
654
+ /* Compaction / Branch Summary - matches customMessage colors from TUI */
655
+ .compaction {
656
+ background: var(--customMessageBg);
657
+ border-radius: 4px;
658
+ padding: var(--line-height);
659
+ cursor: pointer;
660
+ }
661
+
662
+ .compaction-label {
663
+ color: var(--customMessageLabel);
664
+ font-weight: bold;
665
+ }
666
+
667
+ .compaction-collapsed {
668
+ color: var(--customMessageText);
669
+ }
670
+
671
+ .compaction-content {
672
+ display: none;
673
+ color: var(--customMessageText);
674
+ white-space: pre-wrap;
675
+ margin-top: var(--line-height);
676
+ }
677
+
678
+ .compaction.expanded .compaction-collapsed {
679
+ display: none;
680
+ }
681
+
682
+ .compaction.expanded .compaction-content {
683
+ display: block;
684
+ }
685
+
686
+ /* System prompt */
687
+ .system-prompt {
688
+ background: var(--customMessageBg);
689
+ padding: var(--line-height);
690
+ border-radius: 4px;
691
+ margin-bottom: var(--line-height);
692
+ }
693
+
694
+ .system-prompt.expandable {
695
+ cursor: pointer;
696
+ }
697
+
698
+ .system-prompt-header {
699
+ font-weight: bold;
700
+ color: var(--customMessageLabel);
701
+ }
702
+
703
+ .system-prompt-preview {
704
+ color: var(--customMessageText);
705
+ white-space: pre-wrap;
706
+ word-wrap: break-word;
707
+ font-size: 11px;
708
+ margin-top: var(--line-height);
709
+ }
710
+
711
+ .system-prompt-expand-hint {
712
+ color: var(--muted);
713
+ font-style: italic;
714
+ margin-top: 4px;
715
+ }
716
+
717
+ .system-prompt-full {
718
+ display: none;
719
+ color: var(--customMessageText);
720
+ white-space: pre-wrap;
721
+ word-wrap: break-word;
722
+ font-size: 11px;
723
+ margin-top: var(--line-height);
724
+ }
725
+
726
+ .system-prompt.expanded .system-prompt-preview,
727
+ .system-prompt.expanded .system-prompt-expand-hint {
728
+ display: none;
729
+ }
730
+
731
+ .system-prompt.expanded .system-prompt-full {
732
+ display: block;
733
+ }
734
+
735
+ .system-prompt.provider-prompt {
736
+ border-left: 3px solid var(--warning);
737
+ }
738
+
739
+ .system-prompt-note {
740
+ font-size: 10px;
741
+ font-style: italic;
742
+ color: var(--muted);
743
+ margin-top: 4px;
744
+ }
745
+
746
+ /* Tools list */
747
+ .tools-list {
748
+ background: var(--customMessageBg);
749
+ padding: var(--line-height);
750
+ border-radius: 4px;
751
+ margin-bottom: var(--line-height);
752
+ }
753
+
754
+ .tools-header {
755
+ font-weight: bold;
756
+ color: var(--customMessageLabel);
757
+ margin-bottom: var(--line-height);
758
+ }
759
+
760
+ .tool-item {
761
+ font-size: 11px;
762
+ }
763
+
764
+ .tool-item-name {
765
+ font-weight: bold;
766
+ color: var(--text);
767
+ }
768
+
769
+ .tool-item-desc {
770
+ color: var(--dim);
771
+ }
772
+
773
+ .tool-params-hint {
774
+ color: var(--muted);
775
+ font-style: italic;
776
+ }
777
+
778
+ .tool-item:has(.tool-params-hint) {
779
+ cursor: pointer;
780
+ }
781
+
782
+ .tool-params-hint::after {
783
+ content: '[click to show parameters]';
784
+ }
785
+
786
+ .tool-item.params-expanded .tool-params-hint::after {
787
+ content: '[hide parameters]';
788
+ }
789
+
790
+ .tool-params-content {
791
+ display: none;
792
+ margin-top: 4px;
793
+ margin-left: 12px;
794
+ padding-left: 8px;
795
+ border-left: 1px solid var(--dim);
796
+ }
797
+
798
+ .tool-item.params-expanded .tool-params-content {
799
+ display: block;
800
+ }
801
+
802
+ .tool-param {
803
+ margin-bottom: 4px;
804
+ font-size: 11px;
805
+ }
806
+
807
+ .tool-param-name {
808
+ font-weight: bold;
809
+ color: var(--text);
810
+ }
811
+
812
+ .tool-param-type {
813
+ color: var(--dim);
814
+ font-style: italic;
815
+ }
816
+
817
+ .tool-param-required {
818
+ color: var(--warning, #e8a838);
819
+ font-size: 10px;
820
+ }
821
+
822
+ .tool-param-optional {
823
+ color: var(--dim);
824
+ font-size: 10px;
825
+ }
826
+
827
+ .tool-param-desc {
828
+ color: var(--dim);
829
+ margin-left: 8px;
830
+ }
831
+
832
+ /* Hook/custom messages */
833
+ .hook-message {
834
+ background: var(--customMessageBg);
835
+ color: var(--customMessageText);
836
+ padding: var(--line-height);
837
+ border-radius: 4px;
838
+ }
839
+
840
+ .hook-type {
841
+ color: var(--customMessageLabel);
842
+ font-weight: bold;
843
+ }
844
+
845
+ /* Branch summary */
846
+ .branch-summary {
847
+ background: var(--customMessageBg);
848
+ padding: var(--line-height);
849
+ border-radius: 4px;
850
+ }
851
+
852
+ .branch-summary-header {
853
+ font-weight: bold;
854
+ color: var(--borderAccent);
855
+ }
856
+
857
+ /* Error */
858
+ .error-text {
859
+ color: var(--error);
860
+ padding: 0 var(--line-height);
861
+ }
862
+ .tool-error {
863
+ color: var(--error);
864
+ }
865
+
866
+ /* Images */
867
+ .message-images {
868
+ margin-bottom: 12px;
869
+ }
870
+
871
+ .message-image {
872
+ max-width: 100%;
873
+ max-height: 400px;
874
+ border-radius: 4px;
875
+ margin: var(--line-height) 0;
876
+ }
877
+
878
+ /* Markdown content */
879
+ .markdown-content h1,
880
+ .markdown-content h2,
881
+ .markdown-content h3,
882
+ .markdown-content h4,
883
+ .markdown-content h5,
884
+ .markdown-content h6 {
885
+ color: var(--mdHeading);
886
+ margin: var(--line-height) 0 0 0;
887
+ font-weight: bold;
888
+ }
889
+
890
+ .markdown-content h1 { font-size: 1em; }
891
+ .markdown-content h2 { font-size: 1em; }
892
+ .markdown-content h3 { font-size: 1em; }
893
+ .markdown-content h4 { font-size: 1em; }
894
+ .markdown-content h5 { font-size: 1em; }
895
+ .markdown-content h6 { font-size: 1em; }
896
+ .markdown-content p { margin: 0; }
897
+ .markdown-content p + p { margin-top: var(--line-height); }
898
+
899
+ .markdown-content a {
900
+ color: var(--mdLink);
901
+ text-decoration: underline;
902
+ }
903
+
904
+ .markdown-content code {
905
+ background: rgba(128, 128, 128, 0.2);
906
+ color: var(--mdCode);
907
+ padding: 0 4px;
908
+ border-radius: 3px;
909
+ font-family: inherit;
910
+ }
911
+
912
+ .markdown-content pre {
913
+ background: transparent;
914
+ margin: var(--line-height) 0;
915
+ overflow-x: auto;
916
+ }
917
+
918
+ .markdown-content pre code {
919
+ display: block;
920
+ background: none;
921
+ color: var(--text);
922
+ }
923
+
924
+ .markdown-content blockquote {
925
+ border-left: 3px solid var(--mdQuoteBorder);
926
+ padding-left: var(--line-height);
927
+ margin: var(--line-height) 0;
928
+ color: var(--mdQuote);
929
+ font-style: italic;
930
+ }
931
+
932
+ .markdown-content ul,
933
+ .markdown-content ol {
934
+ margin: var(--line-height) 0;
935
+ padding-left: calc(var(--line-height) * 2);
936
+ }
937
+
938
+ .markdown-content li { margin: 0; }
939
+ .markdown-content li::marker { color: var(--mdListBullet); }
940
+
941
+ .markdown-content hr {
942
+ border: none;
943
+ border-top: 1px solid var(--mdHr);
944
+ margin: var(--line-height) 0;
945
+ }
946
+
947
+ .markdown-content table {
948
+ border-collapse: collapse;
949
+ margin: 0.5em 0;
950
+ width: 100%;
951
+ }
952
+
953
+ .markdown-content th,
954
+ .markdown-content td {
955
+ border: 1px solid var(--mdCodeBlockBorder);
956
+ padding: 6px 10px;
957
+ text-align: left;
958
+ }
959
+
960
+ .markdown-content th {
961
+ background: rgba(128, 128, 128, 0.1);
962
+ font-weight: bold;
963
+ }
964
+
965
+ .markdown-content img {
966
+ max-width: 100%;
967
+ border-radius: 4px;
968
+ }
969
+
970
+ /* Syntax highlighting */
971
+ .hljs { background: transparent; color: var(--text); }
972
+ .hljs-comment, .hljs-quote { color: var(--syntaxComment); }
973
+ .hljs-keyword, .hljs-selector-tag { color: var(--syntaxKeyword); }
974
+ .hljs-number, .hljs-literal { color: var(--syntaxNumber); }
975
+ .hljs-string, .hljs-doctag { color: var(--syntaxString); }
976
+ /* Function names: hljs v11 uses .hljs-title.function_ compound class */
977
+ .hljs-function, .hljs-title, .hljs-title.function_, .hljs-section, .hljs-name { color: var(--syntaxFunction); }
978
+ /* Types: hljs v11 uses .hljs-title.class_ for class names */
979
+ .hljs-type, .hljs-class, .hljs-title.class_, .hljs-built_in { color: var(--syntaxType); }
980
+ .hljs-attr, .hljs-variable, .hljs-variable.language_, .hljs-params, .hljs-property { color: var(--syntaxVariable); }
981
+ .hljs-meta, .hljs-meta .hljs-keyword, .hljs-meta .hljs-string { color: var(--syntaxKeyword); }
982
+ .hljs-operator { color: var(--syntaxOperator); }
983
+ .hljs-punctuation { color: var(--syntaxPunctuation); }
984
+ .hljs-subst { color: var(--text); }
985
+
986
+ /* Footer */
987
+ .footer {
988
+ margin-top: 48px;
989
+ padding: 20px;
990
+ text-align: center;
991
+ color: var(--dim);
992
+ font-size: 10px;
993
+ }
994
+
995
+ /* Mobile */
996
+ #hamburger {
997
+ display: none;
998
+ position: fixed;
999
+ top: 10px;
1000
+ left: 10px;
1001
+ z-index: 100;
1002
+ padding: 3px 8px;
1003
+ font-size: 12px;
1004
+ font-family: inherit;
1005
+ background: transparent;
1006
+ color: var(--muted);
1007
+ border: 1px solid var(--dim);
1008
+ border-radius: 3px;
1009
+ cursor: pointer;
1010
+ }
1011
+
1012
+ #hamburger:hover {
1013
+ color: var(--text);
1014
+ border-color: var(--text);
1015
+ }
1016
+
1017
+
1018
+
1019
+ #sidebar-overlay {
1020
+ display: none;
1021
+ position: fixed;
1022
+ top: 0;
1023
+ left: 0;
1024
+ right: 0;
1025
+ bottom: 0;
1026
+ background: rgba(0, 0, 0, 0.5);
1027
+ z-index: 98;
1028
+ }
1029
+
1030
+ @media (max-width: 900px) {
1031
+ #sidebar {
1032
+ position: fixed;
1033
+ left: 0;
1034
+ width: min(var(--sidebar-width), 100vw);
1035
+ min-width: min(var(--sidebar-width), 100vw);
1036
+ max-width: min(var(--sidebar-width), 100vw);
1037
+ top: 0;
1038
+ bottom: 0;
1039
+ height: 100vh;
1040
+ z-index: 99;
1041
+ transform: translateX(-100%);
1042
+ transition: transform 0.3s;
1043
+ }
1044
+
1045
+ #sidebar.open {
1046
+ transform: translateX(0);
1047
+ }
1048
+
1049
+ #sidebar-resizer {
1050
+ display: none;
1051
+ }
1052
+
1053
+ #sidebar-overlay.open {
1054
+ display: block;
1055
+ }
1056
+
1057
+ #hamburger {
1058
+ display: block;
1059
+ }
1060
+
1061
+ .sidebar-close {
1062
+ display: block;
1063
+ }
1064
+
1065
+ #content {
1066
+ padding: var(--line-height) 16px;
1067
+ }
1068
+
1069
+ #content > * {
1070
+ max-width: 100%;
1071
+ }
1072
+ }
1073
+
1074
+ @media print {
1075
+ #sidebar, #sidebar-resizer, #sidebar-toggle { display: none !important; }
1076
+ body { background: white; color: black; }
1077
+ #content { max-width: none; }
1078
+ }