transcript-viewer 0.10.0__tar.gz → 0.11.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. transcript_viewer-0.10.0/README.md → transcript_viewer-0.11.0/PKG-INFO +27 -0
  2. transcript_viewer-0.10.0/PKG-INFO → transcript_viewer-0.11.0/README.md +14 -13
  3. transcript_viewer-0.11.0/design/Anchor.dc.html +297 -0
  4. transcript_viewer-0.11.0/design/Dense.dc.html +395 -0
  5. transcript_viewer-0.11.0/design/Hover.dc.html +271 -0
  6. transcript_viewer-0.11.0/design/Main.dc.html +529 -0
  7. transcript_viewer-0.11.0/design/Quiet.dc.html +253 -0
  8. transcript_viewer-0.11.0/design/canvas.json +61 -0
  9. transcript_viewer-0.11.0/design/delegation-timeline.html +10394 -0
  10. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/pyproject.toml +2 -2
  11. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/src/transcript_viewer/page.html +391 -2
  12. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/tests/page.test.js +178 -1
  13. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/uv.lock +5 -5
  14. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/.coverage +0 -0
  15. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/.github/workflows/publish.yml +0 -0
  16. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/.github/workflows/test.yml +0 -0
  17. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/.gitignore +0 -0
  18. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/src/transcript_viewer/__init__.py +0 -0
  19. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/src/transcript_viewer/ai.py +0 -0
  20. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/src/transcript_viewer/cli.py +0 -0
  21. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/src/transcript_viewer/config.py +0 -0
  22. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/src/transcript_viewer/corpus.py +0 -0
  23. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/src/transcript_viewer/fetch.py +0 -0
  24. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/src/transcript_viewer/library.py +0 -0
  25. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/src/transcript_viewer/store.py +0 -0
  26. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/src/transcript_viewer/viewer.py +0 -0
  27. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/tests/fixtures/big-command.json +0 -0
  28. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/tests/test_ai.py +0 -0
  29. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/tests/test_cli.py +0 -0
  30. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/tests/test_config.py +0 -0
  31. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/tests/test_corpus.py +0 -0
  32. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/tests/test_fetch.py +0 -0
  33. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/tests/test_library.py +0 -0
  34. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/tests/test_page.py +0 -0
  35. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/tests/test_readme.py +0 -0
  36. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/tests/test_store.py +0 -0
  37. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/tests/test_stream.py +0 -0
  38. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/tests/test_style.py +0 -0
  39. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/tests/test_tidiness.py +0 -0
  40. {transcript_viewer-0.10.0 → transcript_viewer-0.11.0}/tests/test_viewer.py +0 -0
@@ -1,3 +1,16 @@
1
+ Metadata-Version: 2.5
2
+ Name: transcript-viewer
3
+ Version: 0.11.0
4
+ Summary: Browse agent transcripts in a local, dependency-free web viewer.
5
+ License: MIT
6
+ Requires-Python: >=3.12
7
+ Requires-Dist: atif-make>=0.7.1
8
+ Provides-Extra: ai
9
+ Requires-Dist: anthropic>=0.40; extra == 'ai'
10
+ Provides-Extra: parquet
11
+ Requires-Dist: atif-make[parquet]>=0.5.0; extra == 'parquet'
12
+ Description-Content-Type: text/markdown
13
+
1
14
  # transcript-viewer
2
15
 
3
16
  Browse agent transcripts in a local web viewer — what Claude Code, Codex and
@@ -166,6 +179,20 @@ If that directory is still there, the first run moves it to
166
179
  `~/.transcript-viewer` — index, annotations and stored keys together — and says
167
180
  so. Nothing is left behind and nothing is copied twice.
168
181
 
182
+ A run that delegated shows a **timeline** above its steps: one lane per
183
+ subagent, laid out on the clock. It exists for the one thing a nested box
184
+ cannot say — that two subagents were running at the same moment, which 25 pairs
185
+ in the corpus this was built against were. Clicking a lane opens the box the
186
+ transcript already has for it rather than showing the same thing twice.
187
+
188
+ Where a session spans days but holds hours of work — one runs 10.3 days and
189
+ contains 5.3 hours, with 31 gaps over an hour — the quiet stretches are skipped
190
+ so the work is legible, and both the count and the total skipped are stated on
191
+ the axis. A short subagent keeps a clickable minimum width, so where a bar is at
192
+ that floor its width is not its duration; the card carries the real one. A
193
+ transcript with no timestamps lays the same lanes out by step instead and says
194
+ so, and one that delegated nothing shows no timeline at all.
195
+
169
196
  **Clear library** above the tree forgets every session at once, after saying
170
197
  how many and what it will touch. Files are left alone by the same rule as a
171
198
  single removal — only copies the viewer made itself are deleted — and stored
@@ -1,16 +1,3 @@
1
- Metadata-Version: 2.5
2
- Name: transcript-viewer
3
- Version: 0.10.0
4
- Summary: Browse agent transcripts in a local, dependency-free web viewer.
5
- License: MIT
6
- Requires-Python: >=3.12
7
- Requires-Dist: atif-make>=0.7.0
8
- Provides-Extra: ai
9
- Requires-Dist: anthropic>=0.40; extra == 'ai'
10
- Provides-Extra: parquet
11
- Requires-Dist: atif-make[parquet]>=0.5.0; extra == 'parquet'
12
- Description-Content-Type: text/markdown
13
-
14
1
  # transcript-viewer
15
2
 
16
3
  Browse agent transcripts in a local web viewer — what Claude Code, Codex and
@@ -179,6 +166,20 @@ If that directory is still there, the first run moves it to
179
166
  `~/.transcript-viewer` — index, annotations and stored keys together — and says
180
167
  so. Nothing is left behind and nothing is copied twice.
181
168
 
169
+ A run that delegated shows a **timeline** above its steps: one lane per
170
+ subagent, laid out on the clock. It exists for the one thing a nested box
171
+ cannot say — that two subagents were running at the same moment, which 25 pairs
172
+ in the corpus this was built against were. Clicking a lane opens the box the
173
+ transcript already has for it rather than showing the same thing twice.
174
+
175
+ Where a session spans days but holds hours of work — one runs 10.3 days and
176
+ contains 5.3 hours, with 31 gaps over an hour — the quiet stretches are skipped
177
+ so the work is legible, and both the count and the total skipped are stated on
178
+ the axis. A short subagent keeps a clickable minimum width, so where a bar is at
179
+ that floor its width is not its duration; the card carries the real one. A
180
+ transcript with no timestamps lays the same lanes out by step instead and says
181
+ so, and one that delegated nothing shows no timeline at all.
182
+
182
183
  **Clear library** above the tree forgets every session at once, after saying
183
184
  how many and what it will touch. Files are left alone by the same rule as a
184
185
  single removal — only copies the viewer made itself are deleted — and stored
@@ -0,0 +1,297 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <script src="./support.js"></script>
6
+ </head>
7
+ <body>
8
+ <x-dc>
9
+ <helmet>
10
+ <link
11
+ rel="stylesheet"
12
+ href="https://fonts.googleapis.com/css2?family=Newsreader:opsz,wght@6..72,400;6..72,600&family=IBM+Plex+Mono:wght@400;500;600&display=swap"
13
+ />
14
+ <style>
15
+ .root {
16
+ --bg: #18161c;
17
+ --surface: #232028;
18
+ --panel: #1d1b22;
19
+ --ink: #eae4d8;
20
+ --muted: #948d80;
21
+ --line: #332f3a;
22
+ --accent: #d3894b;
23
+ --soft: rgba(211, 137, 75, 0.13);
24
+ --hl: rgba(211, 137, 75, 0.25);
25
+ --dim: var(--muted);
26
+ --faint: var(--muted);
27
+ --sunk: var(--bg);
28
+ --shadow:
29
+ 0 1px 2px rgba(0, 0, 0, 0.4), 0 10px 30px rgba(0, 0, 0, 0.45);
30
+ --font-ui: "Helvetica Neue", Helvetica, Arial, sans-serif;
31
+ --font-serif: Newsreader, Georgia, serif;
32
+ --font-mono: "IBM Plex Mono", ui-monospace, monospace;
33
+ }
34
+ body {
35
+ margin: 0;
36
+ font-family: var(--font-ui);
37
+ }
38
+ a {
39
+ color: #d3894b;
40
+ }
41
+ a:hover {
42
+ color: #b0522a;
43
+ }
44
+ .bar {
45
+ position: absolute;
46
+ top: 4px;
47
+ height: 14px;
48
+ border-radius: 3px;
49
+ background: var(--accent);
50
+ opacity: 0.85;
51
+ }
52
+ .rule {
53
+ position: absolute;
54
+ left: 0;
55
+ right: 0;
56
+ top: 11px;
57
+ height: 1px;
58
+ background: var(--line);
59
+ }
60
+ </style>
61
+ </helmet>
62
+
63
+ <div
64
+ class="root"
65
+ style="
66
+ background: var(--bg);
67
+ color: var(--ink);
68
+ font-family: var(--font-ui);
69
+ width: 900px;
70
+ min-height: 560px;
71
+ box-sizing: border-box;
72
+ padding: 22px;
73
+ "
74
+ >
75
+ <div
76
+ style="
77
+ display: flex;
78
+ align-items: baseline;
79
+ gap: 12px;
80
+ margin-bottom: 10px;
81
+ "
82
+ >
83
+ <h2
84
+ style="
85
+ margin: 0;
86
+ font: 600 15px var(--font-serif);
87
+ letter-spacing: -0.01em;
88
+ "
89
+ >
90
+ Delegation
91
+ </h2>
92
+ <span style="font: 11px var(--font-mono); color: var(--muted)"
93
+ >a lane and the step that started it</span
94
+ >
95
+ </div>
96
+
97
+ <!-- The chart, with one lane picked out -->
98
+ <div
99
+ style="
100
+ border: 1px solid var(--line);
101
+ border-radius: 9px;
102
+ background: var(--panel);
103
+ padding: 14px 16px 12px;
104
+ "
105
+ >
106
+ <sc-for list="{{lanes}}" as="lane" hint-placeholder-count="3">
107
+ <div
108
+ style="display:grid;grid-template-columns:150px 1fr;gap:0 12px;align-items:center;
109
+ padding:2px 0;opacity:{{lane.dim}}"
110
+ >
111
+ <div style="display: flex; align-items: baseline; gap: 7px">
112
+ <span
113
+ style="
114
+ color: var(--accent);
115
+ font-weight: 700;
116
+ font-size: 11px;
117
+ "
118
+ >⤷</span
119
+ >
120
+ <span style="font: 12px var(--font-mono); color: var(--accent)"
121
+ >{{lane.kind}}</span
122
+ >
123
+ </div>
124
+ <div style="position: relative; height: 22px">
125
+ <div class="rule"></div>
126
+ <span
127
+ class="bar"
128
+ style="left:{{lane.at}};width:{{lane.w}}"
129
+ ></span>
130
+ <span
131
+ style="position:absolute;top:2px;left:{{lane.at}};font:10px var(--font-mono);
132
+ color:var(--accent);margin-left:-46px;opacity:{{lane.tagOn}}"
133
+ >step 128</span
134
+ >
135
+ </div>
136
+ </div>
137
+ </sc-for>
138
+ </div>
139
+
140
+ <!-- The leader: the chart and the transcript are the same run, so the tie is
141
+ drawn rather than described. -->
142
+ <div style="position: relative; height: 34px; margin-left: 162px">
143
+ <span
144
+ style="
145
+ position: absolute;
146
+ left: 24%;
147
+ top: 0;
148
+ bottom: 8px;
149
+ width: 1px;
150
+ background: var(--accent);
151
+ opacity: 0.5;
152
+ "
153
+ ></span>
154
+ <span
155
+ style="
156
+ position: absolute;
157
+ left: 24%;
158
+ bottom: 2px;
159
+ width: 7px;
160
+ height: 7px;
161
+ border-radius: 999px;
162
+ background: var(--accent);
163
+ margin-left: -3px;
164
+ "
165
+ ></span>
166
+ </div>
167
+
168
+ <!-- The step, exactly as the transcript draws it, with the delegation inside -->
169
+ <div
170
+ style="
171
+ position: relative;
172
+ margin: 0 0 10px 46px;
173
+ padding: 9px 15px 11px;
174
+ border-left: 2px solid var(--ink);
175
+ border-radius: 0 9px 9px 0;
176
+ background: var(--panel);
177
+ "
178
+ >
179
+ <div
180
+ style="
181
+ font: 10px var(--font-mono);
182
+ color: var(--faint);
183
+ margin-bottom: 5px;
184
+ "
185
+ >
186
+ 128 · agent · 09:41:06 · claude-opus-5
187
+ </div>
188
+ <div style="font-size: 13.5px; line-height: 1.55; margin-bottom: 9px">
189
+ I'll look for everywhere the theme is applied before changing the
190
+ token.
191
+ </div>
192
+
193
+ <!-- the existing .branch component, unchanged: 1px accent, radius 9, ⤷ -->
194
+ <div
195
+ style="
196
+ border: 1px solid var(--accent);
197
+ border-radius: 9px;
198
+ background: var(--panel);
199
+ overflow: hidden;
200
+ "
201
+ >
202
+ <div
203
+ style="
204
+ padding: 9px 12px;
205
+ font-size: 12.5px;
206
+ display: flex;
207
+ gap: 9px;
208
+ align-items: center;
209
+ color: var(--accent);
210
+ "
211
+ >
212
+ <span style="font-weight: 700">⤷</span>
213
+ <b style="font-weight: 700">Explore</b>
214
+ <span
215
+ style="
216
+ color: var(--dim);
217
+ font-weight: 400;
218
+ overflow: hidden;
219
+ text-overflow: ellipsis;
220
+ white-space: nowrap;
221
+ "
222
+ >find every place the theme is set</span
223
+ >
224
+ <span
225
+ style="
226
+ border: 1px solid var(--accent);
227
+ border-radius: 999px;
228
+ padding: 1px 7px;
229
+ font-size: 10px;
230
+ color: var(--accent);
231
+ white-space: nowrap;
232
+ "
233
+ >12 steps</span
234
+ >
235
+ <span
236
+ style="
237
+ border: 1px solid var(--line);
238
+ border-radius: 999px;
239
+ padding: 1px 7px;
240
+ font-size: 10px;
241
+ color: var(--dim);
242
+ white-space: nowrap;
243
+ margin-left: auto;
244
+ "
245
+ >
246
+ 4m 12s
247
+ </span>
248
+ <span
249
+ style="
250
+ font: 10px var(--font-mono);
251
+ color: var(--faint);
252
+ white-space: nowrap;
253
+ "
254
+ >
255
+ in timeline
256
+ </span>
257
+ </div>
258
+ </div>
259
+ </div>
260
+
261
+ <div
262
+ style="
263
+ font-size: 11.5px;
264
+ color: var(--faint);
265
+ line-height: 1.5;
266
+ padding-left: 46px;
267
+ "
268
+ >
269
+ The tie runs both ways: a lane carries the step number that started
270
+ it, and the step keeps the box it always had, now also saying how long
271
+ the subagent took and offering the way back out to the timeline.
272
+ </div>
273
+ </div>
274
+ </x-dc>
275
+
276
+ <script data-dc-script data-props="{}">
277
+ class Component extends DCLogic {
278
+ renderVals() {
279
+ const raw = [
280
+ { kind: "Explore", at: 6, end: 14, on: false },
281
+ { kind: "Explore", at: 24, end: 33, on: true },
282
+ { kind: "general-purpose", at: 38, end: 41, on: false },
283
+ ];
284
+ return {
285
+ lanes: raw.map((r) => ({
286
+ kind: r.kind,
287
+ at: r.at + "%",
288
+ w: r.end - r.at + "%",
289
+ dim: r.on ? "1" : ".45",
290
+ tagOn: r.on ? "1" : "0",
291
+ })),
292
+ };
293
+ }
294
+ }
295
+ </script>
296
+ </body>
297
+ </html>