@raquezha/notrace 0.1.1 → 0.2.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.
- package/CHANGELOG.md +18 -0
- package/dist/notrace/index.d.ts +34 -0
- package/dist/notrace/index.js +144 -118
- package/dist/notrace/report-app/__tests__/analytics.test.d.ts +1 -0
- package/dist/notrace/report-app/__tests__/analytics.test.js +35 -0
- package/dist/notrace/report-app/__tests__/card.test.d.ts +1 -0
- package/dist/notrace/report-app/__tests__/card.test.js +26 -0
- package/dist/notrace/report-app/__tests__/event.test.d.ts +1 -0
- package/dist/notrace/report-app/__tests__/event.test.js +20 -0
- package/dist/notrace/report-app/__tests__/format.test.d.ts +1 -0
- package/dist/notrace/report-app/__tests__/format.test.js +41 -0
- package/dist/notrace/report-app/__tests__/report.test.d.ts +1 -0
- package/dist/notrace/report-app/__tests__/report.test.js +31 -0
- package/dist/notrace/report-app/analytics.d.ts +3 -0
- package/dist/notrace/report-app/analytics.js +78 -0
- package/dist/notrace/report-app/client.d.ts +2 -0
- package/dist/notrace/report-app/client.js +105 -0
- package/dist/notrace/report-app/components/card.d.ts +4 -0
- package/dist/notrace/report-app/components/card.js +36 -0
- package/dist/notrace/report-app/components/dashboard.d.ts +1 -0
- package/dist/notrace/report-app/components/dashboard.js +16 -0
- package/dist/notrace/report-app/components/event.d.ts +5 -0
- package/dist/notrace/report-app/components/event.js +42 -0
- package/dist/notrace/report-app/components/message.d.ts +2 -0
- package/dist/notrace/report-app/components/message.js +43 -0
- package/dist/notrace/report-app/dashboard-report.d.ts +1 -0
- package/dist/notrace/report-app/dashboard-report.js +6 -0
- package/dist/notrace/report-app/escape.d.ts +1 -0
- package/dist/notrace/report-app/escape.js +10 -0
- package/dist/notrace/report-app/format.d.ts +13 -0
- package/dist/notrace/report-app/format.js +102 -0
- package/dist/notrace/report-app/report.d.ts +1 -0
- package/dist/notrace/report-app/report.js +29 -0
- package/dist/notrace/report-app/shell.d.ts +5 -0
- package/dist/notrace/report-app/shell.js +19 -0
- package/dist/notrace/report-app/styles.d.ts +1 -0
- package/dist/notrace/report-app/styles.js +431 -0
- package/dist/notrace/report-app/types.d.ts +28 -0
- package/dist/notrace/report-app/types.js +1 -0
- package/extensions/notrace/__tests__/ghost-session.test.ts +103 -0
- package/extensions/notrace/__tests__/helpers.ts +11 -0
- package/extensions/notrace/__tests__/lock-race.test.ts +176 -0
- package/extensions/notrace/__tests__/usage-normalization.test.ts +80 -0
- package/extensions/notrace/index.ts +160 -124
- package/extensions/notrace/report-app/__tests__/analytics.test.ts +41 -0
- package/extensions/notrace/report-app/__tests__/card.test.ts +29 -0
- package/extensions/notrace/report-app/__tests__/event.test.ts +23 -0
- package/extensions/notrace/report-app/__tests__/format.test.ts +46 -0
- package/extensions/notrace/report-app/__tests__/report.test.ts +33 -0
- package/extensions/notrace/report-app/analytics.ts +79 -0
- package/extensions/notrace/report-app/client.ts +106 -0
- package/extensions/notrace/report-app/components/card.ts +38 -0
- package/extensions/notrace/report-app/components/dashboard.ts +17 -0
- package/extensions/notrace/report-app/components/event.ts +39 -0
- package/extensions/notrace/report-app/components/message.ts +39 -0
- package/extensions/notrace/report-app/dashboard-report.ts +7 -0
- package/extensions/notrace/report-app/escape.ts +10 -0
- package/extensions/notrace/report-app/format.ts +107 -0
- package/extensions/notrace/report-app/report.ts +33 -0
- package/extensions/notrace/report-app/shell.ts +24 -0
- package/extensions/notrace/report-app/styles.ts +431 -0
- package/extensions/notrace/report-app/types.ts +35 -0
- package/package.json +4 -2
- package/templates/dashboard.sample.html +103 -63
- package/templates/dashboard.sample.json +73 -10
- package/templates/render-samples.mjs +119 -1
- package/templates/session.sample.html +125 -168
- package/templates/session.sample.json +66 -7
- package/templates/sessions/019ed2ee-1000-76ee-b353-000000000001/notrace.html +125 -163
- package/templates/sessions/019ed2ee-1000-76ee-b353-000000000001/notrace.json +50 -0
- package/templates/sessions/019ed2ee-1001-76ee-b353-000000000002/notrace.html +125 -162
- package/templates/sessions/019ed2ee-1001-76ee-b353-000000000002/notrace.json +50 -0
- package/templates/sessions/019ed2ee-1002-76ee-b353-000000000003/notrace.html +125 -163
- package/templates/sessions/019ed2ee-1002-76ee-b353-000000000003/notrace.json +50 -0
- package/templates/sessions/019ed2ee-massive/notrace.html +498 -0
- package/templates/sessions/019ed2ee-massive/notrace.json +14660 -0
- package/tsconfig.json +1 -1
- package/dist/notrace/renderer.d.ts +0 -4
- package/dist/notrace/renderer.js +0 -800
- package/extensions/notrace/renderer.ts +0 -810
|
@@ -1,12 +1,4 @@
|
|
|
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">
|
|
6
|
-
<title>notrace</title>
|
|
7
|
-
<link rel="icon" href="data:image/svg+xml,%3Csvg%20width%3D%22100%22%20height%3D%22100%22%20viewBox%3D%220%200%20100%20100%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20role%3D%22img%22%3E%3Ctitle%3Enotrace%20logo%20mark%3C%2Ftitle%3E%3Cdesc%3EA%20wave%20that%20smooths%20into%20a%20flat%20line%2C%20then%20fades%20into%20dots%20%E2%80%94%20color%20shifts%20from%20trace%20orange%20to%20no%20cream%20as%20it%20dissolves.%3C%2Fdesc%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22fadeGrad%22%20x1%3D%220%25%22%20y1%3D%220%25%22%20x2%3D%22100%25%22%20y2%3D%220%25%22%3E%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22%23E2754A%22%2F%3E%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22%23EDE2D2%22%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Cg%20id%3D%22trace-icon%22%3E%3Cpath%20d%3D%22M6%2C50%20C16%2C18%2026%2C18%2036%2C50%20C46%2C82%2054%2C82%2060%2C50%20C64%2C30%2068%2C30%2071%2C50%22%20fill%3D%22none%22%20stroke%3D%22url(%23fadeGrad)%22%20stroke-width%3D%224%22%20stroke-linecap%3D%22round%22%2F%3E%3Cline%20x1%3D%2274%22%20y1%3D%2250%22%20x2%3D%2279%22%20y2%3D%2250%22%20stroke%3D%22%23D9C9B5%22%20stroke-width%3D%224%22%20stroke-linecap%3D%22round%22%20stroke-opacity%3D%220.6%22%2F%3E%3Ccircle%20cx%3D%2285%22%20cy%3D%2250%22%20r%3D%222.2%22%20fill%3D%22%23D9C9B5%22%20opacity%3D%220.5%22%2F%3E%3Ccircle%20cx%3D%2290%22%20cy%3D%2250%22%20r%3D%221.4%22%20fill%3D%22%23EDE2D2%22%20opacity%3D%220.32%22%2F%3E%3Ccircle%20cx%3D%2294%22%20cy%3D%2250%22%20r%3D%220.9%22%20fill%3D%22%23EDE2D2%22%20opacity%3D%220.15%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E">
|
|
8
|
-
<style>
|
|
9
|
-
:root {
|
|
1
|
+
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>notrace</title><link rel="icon" href="data:image/svg+xml,%3Csvg%20width%3D%22100%22%20height%3D%22100%22%20viewBox%3D%220%200%20100%20100%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20role%3D%22img%22%3E%3Ctitle%3Enotrace%20logo%20mark%3C%2Ftitle%3E%3Cdesc%3EA%20wave%20that%20smooths%20into%20a%20flat%20line%2C%20then%20fades%20into%20dots%20%E2%80%94%20color%20shifts%20from%20trace%20orange%20to%20no%20cream%20as%20it%20dissolves.%3C%2Fdesc%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22fadeGrad%22%20x1%3D%220%25%22%20y1%3D%220%25%22%20x2%3D%22100%25%22%20y2%3D%220%25%22%3E%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22%23E2754A%22%2F%3E%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22%23EDE2D2%22%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Cg%20id%3D%22trace-icon%22%3E%3Cpath%20d%3D%22M6%2C50%20C16%2C18%2026%2C18%2036%2C50%20C46%2C82%2054%2C82%2060%2C50%20C64%2C30%2068%2C30%2071%2C50%22%20fill%3D%22none%22%20stroke%3D%22url(%23fadeGrad)%22%20stroke-width%3D%224%22%20stroke-linecap%3D%22round%22%2F%3E%3Cline%20x1%3D%2274%22%20y1%3D%2250%22%20x2%3D%2279%22%20y2%3D%2250%22%20stroke%3D%22%23D9C9B5%22%20stroke-width%3D%224%22%20stroke-linecap%3D%22round%22%20stroke-opacity%3D%220.6%22%2F%3E%3Ccircle%20cx%3D%2285%22%20cy%3D%2250%22%20r%3D%222.2%22%20fill%3D%22%23D9C9B5%22%20opacity%3D%220.5%22%2F%3E%3Ccircle%20cx%3D%2290%22%20cy%3D%2250%22%20r%3D%221.4%22%20fill%3D%22%23EDE2D2%22%20opacity%3D%220.32%22%2F%3E%3Ccircle%20cx%3D%2294%22%20cy%3D%2250%22%20r%3D%220.9%22%20fill%3D%22%23EDE2D2%22%20opacity%3D%220.15%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"><style>:root {
|
|
10
2
|
--bg: #0c0b0a;
|
|
11
3
|
--panel: rgba(255,255,255,0.04);
|
|
12
4
|
--panel-strong: rgba(255,255,255,0.06);
|
|
@@ -55,6 +47,30 @@
|
|
|
55
47
|
gap: 16px;
|
|
56
48
|
align-items: start;
|
|
57
49
|
}
|
|
50
|
+
.hero-split {
|
|
51
|
+
display: grid;
|
|
52
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
53
|
+
gap: 16px;
|
|
54
|
+
align-items: start;
|
|
55
|
+
}
|
|
56
|
+
.hero-right {
|
|
57
|
+
display: grid;
|
|
58
|
+
gap: 12px;
|
|
59
|
+
justify-items: end;
|
|
60
|
+
min-width: 0;
|
|
61
|
+
}
|
|
62
|
+
.hero-session {
|
|
63
|
+
display: grid;
|
|
64
|
+
gap: 4px;
|
|
65
|
+
text-align: right;
|
|
66
|
+
min-width: 0;
|
|
67
|
+
}
|
|
68
|
+
.hero-meta {
|
|
69
|
+
display: flex;
|
|
70
|
+
flex-wrap: wrap;
|
|
71
|
+
gap: 8px;
|
|
72
|
+
justify-content: flex-end;
|
|
73
|
+
}
|
|
58
74
|
.brand { margin-bottom: 10px; }
|
|
59
75
|
.brand-link {
|
|
60
76
|
display: inline-flex;
|
|
@@ -133,11 +149,52 @@
|
|
|
133
149
|
border: 1px solid var(--border);
|
|
134
150
|
border-radius: 18px;
|
|
135
151
|
padding: 18px;
|
|
152
|
+
min-width: 0;
|
|
136
153
|
}
|
|
137
154
|
.metric-card small { display: block; color: var(--accent); text-transform: uppercase; letter-spacing: 0.08em; font-size: 0.72rem; font-weight: 700; }
|
|
138
|
-
.metric-card strong { display: block; margin-top: 8px; font-size: 1.55rem; }
|
|
155
|
+
.metric-card strong { display: block; margin-top: 8px; font-size: clamp(1rem, 2vw, 1.55rem); overflow-wrap: anywhere; }
|
|
139
156
|
.panel { padding: 0; overflow: hidden; }
|
|
140
157
|
.section-title { margin: 0; padding: 20px 22px; border-bottom: 1px solid var(--border); font-size: 1rem; }
|
|
158
|
+
.summary-pills { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
|
|
159
|
+
.kv-grid {
|
|
160
|
+
display: grid;
|
|
161
|
+
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
|
162
|
+
gap: 16px;
|
|
163
|
+
}
|
|
164
|
+
.kv-card {
|
|
165
|
+
background: rgba(0,0,0,0.18);
|
|
166
|
+
border: 1px solid var(--border);
|
|
167
|
+
border-radius: 16px;
|
|
168
|
+
padding: 16px;
|
|
169
|
+
}
|
|
170
|
+
.kv-title {
|
|
171
|
+
font-size: 0.72rem;
|
|
172
|
+
text-transform: uppercase;
|
|
173
|
+
color: var(--accent);
|
|
174
|
+
font-weight: 700;
|
|
175
|
+
letter-spacing: 0.08em;
|
|
176
|
+
margin-bottom: 10px;
|
|
177
|
+
}
|
|
178
|
+
.kv-list { display: grid; gap: 8px; }
|
|
179
|
+
.kv-row { display: flex; justify-content: space-between; gap: 12px; align-items: start; }
|
|
180
|
+
.kv-key { color: var(--muted); }
|
|
181
|
+
.kv-value { color: var(--text); text-align: right; word-break: break-word; }
|
|
182
|
+
.tiny-breakdown {
|
|
183
|
+
margin-top: -10px;
|
|
184
|
+
margin-bottom: 8px;
|
|
185
|
+
color: var(--muted);
|
|
186
|
+
font-size: 0.82rem;
|
|
187
|
+
display: flex;
|
|
188
|
+
flex-wrap: wrap;
|
|
189
|
+
gap: 8px 14px;
|
|
190
|
+
}
|
|
191
|
+
.tiny-breakdown strong { color: var(--text); font-size: inherit; font-weight: 600; }
|
|
192
|
+
.collapsible { margin-top: 24px; }
|
|
193
|
+
.collapsible > summary { list-style: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 18px 22px; font-size: 1rem; font-weight: 700; }
|
|
194
|
+
.collapsible > summary::-webkit-details-marker { display: none; }
|
|
195
|
+
.collapsible > summary:hover { background: rgba(255,255,255,0.02); }
|
|
196
|
+
.collapsible > summary::after { content: "▾"; color: var(--muted); font-size: 0.9rem; }
|
|
197
|
+
.collapsible:not([open]) > summary::after { content: "▸"; }
|
|
141
198
|
.empty { padding: 32px 22px; color: var(--muted); }
|
|
142
199
|
table { width: 100%; border-collapse: collapse; }
|
|
143
200
|
th, td { padding: 14px 18px; text-align: left; border-bottom: 1px solid var(--border); vertical-align: top; }
|
|
@@ -279,6 +336,8 @@
|
|
|
279
336
|
margin: 0;
|
|
280
337
|
background: transparent;
|
|
281
338
|
border: none;
|
|
339
|
+
max-height: 400px;
|
|
340
|
+
overflow-y: auto;
|
|
282
341
|
}
|
|
283
342
|
.footer-note {
|
|
284
343
|
margin-top: 22px;
|
|
@@ -333,61 +392,43 @@
|
|
|
333
392
|
border-color: rgba(216,132,98,0.45);
|
|
334
393
|
background: var(--accent-soft);
|
|
335
394
|
}
|
|
395
|
+
.back-to-top {
|
|
396
|
+
position: fixed;
|
|
397
|
+
right: 20px;
|
|
398
|
+
bottom: 20px;
|
|
399
|
+
z-index: 20;
|
|
400
|
+
display: inline-flex;
|
|
401
|
+
align-items: center;
|
|
402
|
+
gap: 8px;
|
|
403
|
+
padding: 10px 14px;
|
|
404
|
+
border: 1px solid var(--border);
|
|
405
|
+
border-radius: 999px;
|
|
406
|
+
background: rgba(12,11,10,0.88);
|
|
407
|
+
color: var(--text);
|
|
408
|
+
text-decoration: none;
|
|
409
|
+
box-shadow: var(--shadow);
|
|
410
|
+
backdrop-filter: blur(10px);
|
|
411
|
+
opacity: 0;
|
|
412
|
+
pointer-events: none;
|
|
413
|
+
transform: translateY(8px);
|
|
414
|
+
transition: opacity 160ms ease, transform 160ms ease, border-color 120ms ease, background 120ms ease;
|
|
415
|
+
}
|
|
416
|
+
.back-to-top.visible {
|
|
417
|
+
opacity: 1;
|
|
418
|
+
pointer-events: auto;
|
|
419
|
+
transform: translateY(0);
|
|
420
|
+
}
|
|
421
|
+
.back-to-top:hover { border-color: rgba(216,132,98,0.45); background: rgba(216,132,98,0.12); }
|
|
336
422
|
.container { padding: 20px 14px 48px; }
|
|
337
423
|
.hero { padding: 20px; }
|
|
338
|
-
.hero-top { grid-template-columns: 1fr; }
|
|
339
|
-
.meta { justify-content: flex-start; margin-top: 8px; }
|
|
340
|
-
.
|
|
424
|
+
.hero-top, .hero-split { grid-template-columns: 1fr; }
|
|
425
|
+
.meta, .hero-meta { justify-content: flex-start; margin-top: 8px; }
|
|
426
|
+
.hero-right, .hero-session { justify-items: start; text-align: left; }
|
|
427
|
+
.wordmark { width: min(280px, 100%); height: auto; }
|
|
428
|
+
.metrics { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); }
|
|
341
429
|
th:nth-child(5), td:nth-child(5) { display: none; }
|
|
342
430
|
.event summary { align-items: flex-start; }
|
|
343
|
-
}
|
|
344
|
-
</style>
|
|
345
|
-
</head>
|
|
346
|
-
<body><div class="container">
|
|
347
|
-
<section class="hero">
|
|
348
|
-
<div class="hero-split">
|
|
349
|
-
<a class="brand-link" href="index.html"><svg class="wordmark" viewBox="0 0 420 138" aria-label="notrace" role="img" xmlns="http://www.w3.org/2000/svg">
|
|
350
|
-
<defs>
|
|
351
|
-
<linearGradient id="fadeGrad" x1="0%" y1="0%" x2="100%" y2="0%">
|
|
352
|
-
<stop offset="0%" stop-color="#E2754A"/>
|
|
353
|
-
<stop offset="100%" stop-color="#EDE2D2"/>
|
|
354
|
-
</linearGradient>
|
|
355
|
-
</defs>
|
|
356
|
-
<g id="trace-icon" transform="translate(1 -18) scale(0.93)">
|
|
357
|
-
<path d="M6,50 C16,18 26,18 36,50 C46,82 54,82 60,50 C64,30 68,30 71,50"
|
|
358
|
-
fill="none" stroke="url(#fadeGrad)" stroke-width="4" stroke-linecap="round"/>
|
|
359
|
-
<line x1="74" y1="50" x2="79" y2="50" stroke="#D9C9B5" stroke-width="4" stroke-linecap="round" stroke-opacity="0.6"/>
|
|
360
|
-
<circle cx="85" cy="50" r="2.2" fill="#D9C9B5" opacity="0.5"/>
|
|
361
|
-
<circle cx="90" cy="50" r="1.4" fill="#EDE2D2" opacity="0.32"/>
|
|
362
|
-
<circle cx="94" cy="50" r="0.9" fill="#EDE2D2" opacity="0.15"/>
|
|
363
|
-
</g>
|
|
364
|
-
<text x="0" y="114" fill="#ECE3DA" style="fill:#ECE3DA" font-family="Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif" font-size="96" font-weight="900" letter-spacing="-7">no</text>
|
|
365
|
-
<text x="82" y="114" fill="#d88462" font-family="Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif" font-size="96" font-weight="900" letter-spacing="-7">trace</text>
|
|
366
|
-
</svg></a>
|
|
367
|
-
<div class="hero-right">
|
|
368
|
-
<div class="hero-session">
|
|
369
|
-
<strong style="color: var(--text); font-weight: 500;">Global Index</strong>
|
|
370
|
-
<span style="color: var(--muted);">Machine-wide session evidence.</span>
|
|
371
|
-
</div>
|
|
372
|
-
<div class="hero-meta">
|
|
373
|
-
<span class="hero-pill">3 sessions</span>
|
|
374
|
-
</div>
|
|
375
|
-
</div>
|
|
376
|
-
</div>
|
|
377
|
-
<div class="metrics">
|
|
378
|
-
<div class="metric-card"><small>Sessions</small><strong>3</strong></div>
|
|
379
|
-
<div class="metric-card"><small>Total Tokens</small><strong>15,174</strong></div>
|
|
380
|
-
<div class="metric-card"><small>Total Cost</small><strong>$0.08050</strong></div>
|
|
381
|
-
</div>
|
|
382
|
-
</section>
|
|
383
|
-
<section class="panel">
|
|
384
|
-
<h2 class="section-title">Session Reports</h2>
|
|
385
|
-
<table data-dashboard-table><thead><tr><th class="col-index sortable-head"><button class="sort-btn" data-sort-key="index"><span class="sort-label">#</span><span class="sort-state">↓</span></button></th><th>Session</th><th>Project</th><th class="sortable-head"><button class="sort-btn" data-sort-key="workflow"><span class="sort-label">Workflow</span><span class="sort-state"></span></button></th><th class="sortable-head"><button class="sort-btn" data-sort-key="started"><span class="sort-label">Started</span><span class="sort-state"></span></button></th><th>Task</th><th class="sortable-head num-cell"><button class="sort-btn" data-sort-key="tokens"><span class="sort-label">Tokens</span><span class="sort-state"></span></button></th><th class="sortable-head num-cell"><button class="sort-btn" data-sort-key="cost"><span class="sort-label">Cost</span><span class="sort-state"></span></button></th></tr></thead><tbody>
|
|
386
|
-
<tr data-index="3" data-workflow="Generic" data-started="1781691240000" data-tokens="5910" data-cost="0.0334"><td class="index-cell">3</td><td><a class="session-link" href="sessions/019ed2ee-1002-76ee-b353-000000000003/notrace.html"><strong>019ed2ee</strong><span class="session-sub">019ed2ee-1002-76ee-b353-000000000003</span></a></td><td><span class="hero-pill">Unknown</span></td><td><span class="workflow-pill workflow-generic">Generic</span></td><td><div class="date-cell"><strong>2026-06-17</strong><span>18:14</span></div></td><td>General session</td><td class="num-cell">5,910</td><td class="num-cell">$0.03340</td></tr><tr data-index="2" data-workflow="Research" data-started="1781689020000" data-tokens="5754" data-cost="0.0267"><td class="index-cell">2</td><td><a class="session-link" href="sessions/019ed2ee-1001-76ee-b353-000000000002/notrace.html"><strong>019ed2ee</strong><span class="session-sub">019ed2ee-1001-76ee-b353-000000000002</span></a></td><td><span class="hero-pill">Unknown</span></td><td><span class="workflow-pill workflow-research">Research</span></td><td><div class="date-cell"><strong>2026-06-17</strong><span>17:37</span></div></td><td>Branch topic-02</td><td class="num-cell">5,754</td><td class="num-cell">$0.02670</td></tr><tr data-index="1" data-workflow="RPIV" data-started="1781686800000" data-tokens="3510" data-cost="0.0204"><td class="index-cell">1</td><td><a class="session-link" href="sessions/019ed2ee-1000-76ee-b353-000000000001/notrace.html"><strong>019ed2ee</strong><span class="session-sub">019ed2ee-1000-76ee-b353-000000000001</span></a></td><td><span class="hero-pill">Unknown</span></td><td><span class="workflow-pill workflow-rpiv">RPIV</span></td><td><div class="date-cell"><strong>2026-06-17</strong><span>17:00</span></div></td><td>NR-101</td><td class="num-cell">3,510</td><td class="num-cell">$0.02040</td></tr>
|
|
387
|
-
</tbody></table>
|
|
388
|
-
</section>
|
|
389
|
-
<footer class="footer-note minimal">notrace • raquezha 2026</footer>
|
|
390
|
-
</div><script>(() => {
|
|
431
|
+
}</style></head><body><div class="container"><section class="hero"><div class="hero-split"><a class="brand-link" href="index.html"><svg class="wordmark" viewBox="0 0 420 138" aria-label="notrace" role="img" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="fadeGrad" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stop-color="#E2754A"/><stop offset="100%" stop-color="#EDE2D2"/></linearGradient></defs><g id="trace-icon" transform="translate(1 -18) scale(0.93)"><path d="M6,50 C16,18 26,18 36,50 C46,82 54,82 60,50 C64,30 68,30 71,50" fill="none" stroke="url(#fadeGrad)" stroke-width="4" stroke-linecap="round"/><line x1="74" y1="50" x2="79" y2="50" stroke="#D9C9B5" stroke-width="4" stroke-linecap="round" stroke-opacity="0.6"/><circle cx="85" cy="50" r="2.2" fill="#D9C9B5" opacity="0.5"/><circle cx="90" cy="50" r="1.4" fill="#EDE2D2" opacity="0.32"/><circle cx="94" cy="50" r="0.9" fill="#EDE2D2" opacity="0.15"/></g><text x="0" y="114" fill="#ECE3DA" style="fill:#ECE3DA" font-family="Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif" font-size="96" font-weight="900" letter-spacing="-7">no</text><text x="82" y="114" fill="#d88462" font-family="Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif" font-size="96" font-weight="900" letter-spacing="-7">trace</text></svg></a><div class="hero-right"><div class="hero-session"><strong style="color: var(--text); font-weight: 500;">Global Index</strong><span style="color: var(--muted);">Machine-wide session evidence.</span></div><div class="hero-meta"><span class="hero-pill">4 sessions</span></div></div></div><div class="metrics"><div class="metric-card"><small>Sessions</small><strong>4</strong></div><div class="metric-card"><small>Total Tokens</small><strong>5,115,174</strong></div><div class="metric-card"><small>Total Cost</small><strong>$75.58050</strong></div></div></section><section class="panel"><h2 class="section-title">Session Reports</h2><table data-dashboard-table><thead><tr><th class="col-index sortable-head"><button class="sort-btn" data-sort-key="index"><span class="sort-label">#</span><span class="sort-state">↓</span></button></th><th>Session</th><th>Project</th><th class="sortable-head"><button class="sort-btn" data-sort-key="workflow"><span class="sort-label">Workflow</span><span class="sort-state"></span></button></th><th class="sortable-head"><button class="sort-btn" data-sort-key="started"><span class="sort-label">Started</span><span class="sort-state"></span></button></th><th>Task</th><th class="sortable-head num-cell"><button class="sort-btn" data-sort-key="tokens"><span class="sort-label">Tokens</span><span class="sort-state"></span></button></th><th class="sortable-head num-cell"><button class="sort-btn" data-sort-key="cost"><span class="sort-label">Cost</span><span class="sort-state"></span></button></th></tr></thead><tbody><tr data-index="4" data-workflow="Generic" data-started="1781784000000" data-tokens="5100000" data-cost="75.5"><td class="index-cell">4</td><td><a class="session-link" href="sessions/019ed2ee-massive/notrace.html"><strong>019ed2ee</strong><span class="session-sub">019ed2ee-massive</span></a></td><td><span class="hero-pill">Unknown</span></td><td><span class="workflow-pill workflow-generic">Generic</span></td><td><div class="date-cell"><strong>2026-06-18</strong><span>20:00</span></div></td><td>test-massive</td><td class="num-cell">5,100,000</td><td class="num-cell">$75.50000</td></tr><tr data-index="3" data-workflow="Generic" data-started="1781691240000" data-tokens="5910" data-cost="0.0334"><td class="index-cell">3</td><td><a class="session-link" href="sessions/019ed2ee-1002-76ee-b353-000000000003/notrace.html"><strong>019ed2ee</strong><span class="session-sub">019ed2ee-1002-76ee-b353-000000000003</span></a></td><td><span class="hero-pill">Unknown</span></td><td><span class="workflow-pill workflow-generic">Generic</span></td><td><div class="date-cell"><strong>2026-06-17</strong><span>18:14</span></div></td><td>General session</td><td class="num-cell">5,910</td><td class="num-cell">$0.03340</td></tr><tr data-index="2" data-workflow="Research" data-started="1781689020000" data-tokens="5754" data-cost="0.0267"><td class="index-cell">2</td><td><a class="session-link" href="sessions/019ed2ee-1001-76ee-b353-000000000002/notrace.html"><strong>019ed2ee</strong><span class="session-sub">019ed2ee-1001-76ee-b353-000000000002</span></a></td><td><span class="hero-pill">Unknown</span></td><td><span class="workflow-pill workflow-research">Research</span></td><td><div class="date-cell"><strong>2026-06-17</strong><span>17:37</span></div></td><td>Branch topic-02</td><td class="num-cell">5,754</td><td class="num-cell">$0.02670</td></tr><tr data-index="1" data-workflow="RPIV" data-started="1781686800000" data-tokens="3510" data-cost="0.0204"><td class="index-cell">1</td><td><a class="session-link" href="sessions/019ed2ee-1000-76ee-b353-000000000001/notrace.html"><strong>019ed2ee</strong><span class="session-sub">019ed2ee-1000-76ee-b353-000000000001</span></a></td><td><span class="hero-pill">Unknown</span></td><td><span class="workflow-pill workflow-rpiv">RPIV</span></td><td><div class="date-cell"><strong>2026-06-17</strong><span>17:00</span></div></td><td>NR-101</td><td class="num-cell">3,510</td><td class="num-cell">$0.02040</td></tr></tbody></table></section><footer class="footer-note minimal">notrace • raquezha 2026</footer></div><script>(() => {
|
|
391
432
|
const table = document.querySelector('[data-dashboard-table]');
|
|
392
433
|
if (!table) return;
|
|
393
434
|
const tbody = table.querySelector('tbody');
|
|
@@ -439,5 +480,4 @@
|
|
|
439
480
|
});
|
|
440
481
|
|
|
441
482
|
sortBy(currentKey);
|
|
442
|
-
})();</script></body>
|
|
443
|
-
</html>
|
|
483
|
+
})();</script></body></html>
|
|
@@ -13,9 +13,16 @@
|
|
|
13
13
|
"dir": "/repo/.workflow/tasks/NR-101"
|
|
14
14
|
},
|
|
15
15
|
"conditions": {
|
|
16
|
-
"models": [
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
"models": [
|
|
17
|
+
"gpt-5.4"
|
|
18
|
+
],
|
|
19
|
+
"providers": [
|
|
20
|
+
"openai"
|
|
21
|
+
],
|
|
22
|
+
"extensions": [
|
|
23
|
+
"notrace",
|
|
24
|
+
"noheadroom"
|
|
25
|
+
]
|
|
19
26
|
},
|
|
20
27
|
"activity": {
|
|
21
28
|
"turnCount": 4,
|
|
@@ -49,9 +56,15 @@
|
|
|
49
56
|
"dir": null
|
|
50
57
|
},
|
|
51
58
|
"conditions": {
|
|
52
|
-
"models": [
|
|
53
|
-
|
|
54
|
-
|
|
59
|
+
"models": [
|
|
60
|
+
"claude-sonnet-4"
|
|
61
|
+
],
|
|
62
|
+
"providers": [
|
|
63
|
+
"anthropic"
|
|
64
|
+
],
|
|
65
|
+
"extensions": [
|
|
66
|
+
"notrace"
|
|
67
|
+
]
|
|
55
68
|
},
|
|
56
69
|
"activity": {
|
|
57
70
|
"turnCount": 5,
|
|
@@ -85,9 +98,16 @@
|
|
|
85
98
|
"dir": null
|
|
86
99
|
},
|
|
87
100
|
"conditions": {
|
|
88
|
-
"models": [
|
|
89
|
-
|
|
90
|
-
|
|
101
|
+
"models": [
|
|
102
|
+
"gemini-3.5-flash"
|
|
103
|
+
],
|
|
104
|
+
"providers": [
|
|
105
|
+
"google"
|
|
106
|
+
],
|
|
107
|
+
"extensions": [
|
|
108
|
+
"notrace",
|
|
109
|
+
"noheadroom"
|
|
110
|
+
]
|
|
91
111
|
},
|
|
92
112
|
"activity": {
|
|
93
113
|
"turnCount": 6,
|
|
@@ -108,6 +128,49 @@
|
|
|
108
128
|
"html": "sessions/019ed2ee-1002-76ee-b353-000000000003/notrace.html",
|
|
109
129
|
"record": "sessions/019ed2ee-1002-76ee-b353-000000000003/notrace.json"
|
|
110
130
|
}
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"sessionId": "019ed2ee-massive",
|
|
134
|
+
"startedAt": "2026-06-18T12:00:00.000Z",
|
|
135
|
+
"endedAt": "2026-06-18T13:00:00.000Z",
|
|
136
|
+
"captureMode": "full",
|
|
137
|
+
"task": {
|
|
138
|
+
"workflow": "chaos",
|
|
139
|
+
"id": "test-massive",
|
|
140
|
+
"path": null,
|
|
141
|
+
"dir": null
|
|
142
|
+
},
|
|
143
|
+
"conditions": {
|
|
144
|
+
"models": [
|
|
145
|
+
"claude-opus",
|
|
146
|
+
"gpt-4-turbo"
|
|
147
|
+
],
|
|
148
|
+
"providers": [
|
|
149
|
+
"multi"
|
|
150
|
+
],
|
|
151
|
+
"extensions": [
|
|
152
|
+
"notrace"
|
|
153
|
+
]
|
|
154
|
+
},
|
|
155
|
+
"activity": {
|
|
156
|
+
"turnCount": 50,
|
|
157
|
+
"llmCallCount": 50,
|
|
158
|
+
"toolCallCount": 250,
|
|
159
|
+
"toolErrorCount": 0,
|
|
160
|
+
"durationMs": 3600000,
|
|
161
|
+
"totals": {
|
|
162
|
+
"inputTokens": 5000000,
|
|
163
|
+
"outputTokens": 100000,
|
|
164
|
+
"cacheReadTokens": 0,
|
|
165
|
+
"cacheWriteTokens": 0,
|
|
166
|
+
"totalTokens": 5100000,
|
|
167
|
+
"totalCostUsd": 75.5
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
"artifacts": {
|
|
171
|
+
"html": "sessions/019ed2ee-massive/notrace.html",
|
|
172
|
+
"record": "sessions/019ed2ee-massive/notrace.json"
|
|
173
|
+
}
|
|
111
174
|
}
|
|
112
175
|
]
|
|
113
|
-
}
|
|
176
|
+
}
|
|
@@ -1,25 +1,143 @@
|
|
|
1
1
|
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
-
import { generateDashboardHtml
|
|
4
|
+
import { generateDashboardHtml } from "../dist/notrace/report-app/dashboard-report.js";
|
|
5
|
+
import { generateHtmlReport } from "../dist/notrace/report-app/report.js";
|
|
5
6
|
|
|
6
7
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
7
8
|
const dashboardData = JSON.parse(readFileSync(path.join(here, "dashboard.sample.json"), "utf8"));
|
|
8
9
|
const sessionData = JSON.parse(readFileSync(path.join(here, "session.sample.json"), "utf8"));
|
|
9
10
|
const repositoryName = dashboardData.repositoryName || sessionData.repository?.name || "nothing";
|
|
10
11
|
|
|
12
|
+
function createRng(seed = 42) {
|
|
13
|
+
let state = seed >>> 0;
|
|
14
|
+
return () => {
|
|
15
|
+
state = (state * 1664525 + 1013904223) >>> 0;
|
|
16
|
+
return state / 0x100000000;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
11
20
|
writeFileSync(path.join(here, "dashboard.sample.html"), generateDashboardHtml(dashboardData.sessions, { repositoryName }));
|
|
12
21
|
writeFileSync(path.join(here, "session.sample.html"), generateHtmlReport(sessionData));
|
|
13
22
|
|
|
14
23
|
for (const session of dashboardData.sessions) {
|
|
15
24
|
const htmlPath = path.join(here, session.artifacts.html);
|
|
16
25
|
const recordPath = path.join(here, session.artifacts.record);
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
let sessionEvents = sessionData.events;
|
|
29
|
+
if (session.sessionId === "019ed2ee-massive") {
|
|
30
|
+
sessionEvents = [];
|
|
31
|
+
let ts = 1781705100000;
|
|
32
|
+
|
|
33
|
+
const random = createRng(20260703);
|
|
34
|
+
// Model profiles
|
|
35
|
+
const profiles = [
|
|
36
|
+
{ id: "claude-3-5-sonnet", provider: "anthropic", weight: 60, costPerMIn: 3.0, costPerMOut: 15.0 },
|
|
37
|
+
{ id: "gpt-4o", provider: "openai", weight: 30, costPerMIn: 5.0, costPerMOut: 15.0 },
|
|
38
|
+
{ id: "claude-3-opus", provider: "anthropic", weight: 5, costPerMIn: 15.0, costPerMOut: 75.0 },
|
|
39
|
+
{ id: "gemini-1.5-pro", provider: "google", weight: 5, costPerMIn: 3.5, costPerMOut: 10.5 }
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
function pickModel() {
|
|
43
|
+
const r = random() * 100;
|
|
44
|
+
let sum = 0;
|
|
45
|
+
for (const p of profiles) {
|
|
46
|
+
sum += p.weight;
|
|
47
|
+
if (r <= sum) return p;
|
|
48
|
+
}
|
|
49
|
+
return profiles[0];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
let baseContext = 4000;
|
|
53
|
+
let contextGrowth = 1.05;
|
|
54
|
+
|
|
55
|
+
let totalIn = 0;
|
|
56
|
+
let totalOut = 0;
|
|
57
|
+
let totalCost = 0;
|
|
58
|
+
let toolCalls = 0;
|
|
59
|
+
|
|
60
|
+
for (let i = 0; i < 140; i++) {
|
|
61
|
+
const model = pickModel();
|
|
62
|
+
|
|
63
|
+
// Context grows naturally as session goes on, with jitter
|
|
64
|
+
baseContext = Math.min(180000, baseContext * contextGrowth);
|
|
65
|
+
let inputTokens = Math.floor(baseContext * (0.8 + random() * 0.4));
|
|
66
|
+
let outputTokens = Math.floor(random() * 800) + 50;
|
|
67
|
+
|
|
68
|
+
// Sometimes Opus reads massive contexts
|
|
69
|
+
if (model.id === "claude-3-opus") inputTokens += 100000;
|
|
70
|
+
// Sometimes Gemini reads huge cache
|
|
71
|
+
if (model.id === "gemini-1.5-pro") inputTokens += 200000;
|
|
72
|
+
|
|
73
|
+
let callCost = (inputTokens / 1_000_000) * model.costPerMIn + (outputTokens / 1_000_000) * model.costPerMOut;
|
|
74
|
+
|
|
75
|
+
totalIn += inputTokens;
|
|
76
|
+
totalOut += outputTokens;
|
|
77
|
+
totalCost += callCost;
|
|
78
|
+
|
|
79
|
+
sessionEvents.push({
|
|
80
|
+
type: "llm_completion",
|
|
81
|
+
model: model.id,
|
|
82
|
+
provider: model.provider,
|
|
83
|
+
inputPayload: { messages: [{role: "user", content: "Organic simulated context..."}] },
|
|
84
|
+
outputContent: "Simulated output generation phase.",
|
|
85
|
+
usage: {
|
|
86
|
+
input: inputTokens,
|
|
87
|
+
output: outputTokens,
|
|
88
|
+
totalTokens: inputTokens + outputTokens,
|
|
89
|
+
cost: { total: callCost }
|
|
90
|
+
},
|
|
91
|
+
timestamp: ts
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
ts += 2000 + random() * 15000; // LLM think time
|
|
95
|
+
|
|
96
|
+
// Generate 0 to 12 tool calls
|
|
97
|
+
const toolsToRun = Math.floor(Math.pow(random(), 1.5) * 12);
|
|
98
|
+
for (let j = 0; j < toolsToRun; j++) {
|
|
99
|
+
toolCalls++;
|
|
100
|
+
const toolName = random() > 0.3 ? "bash" : "read_file";
|
|
101
|
+
const isErr = random() > 0.92;
|
|
102
|
+
|
|
103
|
+
sessionEvents.push({
|
|
104
|
+
type: "tool_start",
|
|
105
|
+
toolName: toolName,
|
|
106
|
+
args: { param: "simulated_arg" },
|
|
107
|
+
timestamp: ts
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
ts += 100 + random() * 3000; // Tool execution time
|
|
111
|
+
|
|
112
|
+
sessionEvents.push({
|
|
113
|
+
type: "tool_end",
|
|
114
|
+
toolName: toolName,
|
|
115
|
+
result: isErr ? { error: "Simulated execution error" } : { stdout: "Success", exitCode: 0 },
|
|
116
|
+
isError: isErr,
|
|
117
|
+
timestamp: ts
|
|
118
|
+
});
|
|
119
|
+
ts += 1000 + random() * 2000; // Wait before next tool
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Update dashboard metadata to match the random generation
|
|
124
|
+
session.activity.llmCallCount = 140;
|
|
125
|
+
session.activity.toolCallCount = toolCalls;
|
|
126
|
+
session.activity.totals.inputTokens = totalIn;
|
|
127
|
+
session.activity.totals.outputTokens = totalOut;
|
|
128
|
+
session.activity.totals.totalTokens = totalIn + totalOut;
|
|
129
|
+
session.activity.totals.totalCostUsd = totalCost;
|
|
130
|
+
}
|
|
131
|
+
|
|
17
132
|
const sessionPage = {
|
|
133
|
+
|
|
18
134
|
...sessionData,
|
|
19
135
|
traceId: session.sessionId,
|
|
136
|
+
events: sessionEvents,
|
|
20
137
|
session: {
|
|
21
138
|
...sessionData.session,
|
|
22
139
|
id: session.sessionId,
|
|
140
|
+
|
|
23
141
|
startedAt: session.startedAt,
|
|
24
142
|
endedAt: session.endedAt,
|
|
25
143
|
durationMs: session.activity?.durationMs ?? sessionData.session?.durationMs ?? 0,
|