@agenttrace-io/dashboard 0.1.9 → 0.2.1

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 (3) hide show
  1. package/LICENSE +21 -0
  2. package/package.json +10 -10
  3. package/public/index.html +269 -111
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AgentTrace contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenttrace-io/dashboard",
3
- "version": "0.1.9",
3
+ "version": "0.2.1",
4
4
  "description": "Local web dashboard for AgentTrace — view runs, traces, costs, and stats",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -30,19 +30,19 @@
30
30
  "dist",
31
31
  "public"
32
32
  ],
33
- "scripts": {
34
- "build": "tsc -p tsconfig.json",
35
- "dev": "tsc -p tsconfig.json --watch",
36
- "test": "vitest run --config ../../vitest.config.ts packages/dashboard",
37
- "start": "node dist/index.js",
38
- "dashboard": "node dist/index.js"
39
- },
40
33
  "dependencies": {
41
34
  "express": "^5.2.1",
42
- "@agenttrace-io/sdk": "workspace:*"
35
+ "@agenttrace-io/sdk": "0.2.1"
43
36
  },
44
37
  "devDependencies": {
45
38
  "@types/express": "^5.0.6",
46
39
  "jsdom": "^29.1.1"
40
+ },
41
+ "scripts": {
42
+ "build": "tsc -p tsconfig.json",
43
+ "dev": "tsc -p tsconfig.json --watch",
44
+ "test": "vitest run --config ../../vitest.config.ts packages/dashboard",
45
+ "start": "node dist/index.js",
46
+ "dashboard": "node dist/index.js"
47
47
  }
48
- }
48
+ }
package/public/index.html CHANGED
@@ -4,87 +4,181 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>AgentTrace • Dashboard</title>
7
- <link rel="stylesheet" href="style.css" />
8
7
  <link rel="icon" href="favicon.svg" type="image/svg+xml" />
8
+
9
+ <!-- Tailwind for a modern, mainstream look (consistent with the new landing page) -->
10
+ <script src="https://cdn.tailwindcss.com"></script>
11
+ <link rel="stylesheet" href="style.css" />
12
+
13
+ <style>
14
+ /* Light overrides + modern polish on top of existing system */
15
+ body {
16
+ font-family:
17
+ 'Inter',
18
+ system_ui,
19
+ -apple-system,
20
+ BlinkMacSystemFont,
21
+ 'Segoe UI',
22
+ Roboto,
23
+ sans-serif;
24
+ }
25
+ .font-display {
26
+ font-family: 'Space Grotesk', 'Inter', system_ui, sans-serif;
27
+ font-feature-settings: 'ss01';
28
+ }
29
+
30
+ /* Make the existing dense UI feel more premium and spacious */
31
+ .container {
32
+ max-width: 1280px;
33
+ }
34
+
35
+ .stat-card {
36
+ transition:
37
+ transform 0.2s cubic-bezier(0.4, 0, 0.2, 1),
38
+ box-shadow 0.2s;
39
+ }
40
+ .stat-card:hover {
41
+ transform: translateY(-2px);
42
+ box-shadow:
43
+ 0 10px 15px -3px rgb(0 0 0 / 0.1),
44
+ 0 4px 6px -4px rgb(0 0 0 / 0.1);
45
+ }
46
+
47
+ .run-item,
48
+ .trace-item {
49
+ transition: all 0.1s ease;
50
+ }
51
+
52
+ .panel {
53
+ transition: box-shadow 0.2s;
54
+ }
55
+
56
+ .panel:hover {
57
+ box-shadow:
58
+ 0 4px 6px -1px rgb(0 0 0 / 0.1),
59
+ 0 2px 4px -2px rgb(0 0 0 / 0.1);
60
+ }
61
+
62
+ /* Better trace tree visual hint */
63
+ .trace-item {
64
+ position: relative;
65
+ }
66
+
67
+ /* Modern topbar */
68
+ .topbar {
69
+ background: rgba(17, 18, 23, 0.95);
70
+ backdrop-filter: blur(12px);
71
+ }
72
+
73
+ .brand h1 {
74
+ letter-spacing: -0.5px;
75
+ }
76
+
77
+ /* Make filters and toolbar feel like the landing page */
78
+ .filter-btn.active,
79
+ .date-btn.active {
80
+ background-color: #6366f1;
81
+ color: white;
82
+ border-color: #6366f1;
83
+ }
84
+ </style>
9
85
  </head>
10
- <body>
11
- <header class="topbar">
12
- <div class="topbar-inner">
13
- <div class="brand">
14
- <svg
15
- class="brand-logo"
16
- width="22"
17
- height="22"
18
- viewBox="0 0 24 24"
19
- fill="none"
20
- aria-hidden="true"
21
- >
22
- <circle cx="12" cy="12" r="9" stroke="#3b82f6" stroke-width="2" />
23
- <path
24
- d="M8 12l3 3 5-5"
25
- stroke="#3b82f6"
26
- stroke-width="2"
27
- stroke-linecap="round"
28
- stroke-linejoin="round"
29
- />
30
- </svg>
31
- <div>
32
- <h1>AgentTrace</h1>
33
- <span class="subtitle">Local Observability</span>
86
+ <body class="bg-[#0a0b0f] text-[#e6e8f0]">
87
+ <!-- Modern Top Nav (matches new landing page aesthetic) -->
88
+ <header class="topbar border-b border-[#252a34] sticky top-0 z-50">
89
+ <div class="max-w-[1280px] mx-auto px-6">
90
+ <div class="flex h-14 items-center justify-between">
91
+ <div class="flex items-center gap-x-3">
92
+ <div class="flex items-center gap-x-2.5">
93
+ <div
94
+ class="w-7 h-7 rounded-xl bg-gradient-to-br from-indigo-500 to-violet-500 flex items-center justify-center"
95
+ >
96
+ <span class="text-white text-[15px] font-semibold tracking-tighter">A</span>
97
+ </div>
98
+ <div class="flex items-baseline gap-x-1.5">
99
+ <span class="font-semibold text-xl tracking-tighter">AgentTrace</span>
100
+ <span class="text-[10px] font-medium text-[#8a90a0] tracking-[1px] uppercase"
101
+ >Dashboard</span
102
+ >
103
+ </div>
104
+ </div>
105
+ <span
106
+ id="version-badge"
107
+ class="text-[10px] px-2 py-px rounded-full border border-[#252a34] text-[#8a90a0]"
108
+ >v0.1.9</span
109
+ >
34
110
  </div>
35
- </div>
36
- <div class="top-actions">
37
- <button
38
- id="refresh-btn"
39
- class="btn btn-secondary"
40
- title="Refresh data (R)"
41
- aria-label="Refresh data"
42
- >
43
- <svg
44
- width="14"
45
- height="14"
46
- viewBox="0 0 24 24"
47
- fill="none"
48
- stroke="currentColor"
49
- stroke-width="2.5"
50
- aria-hidden="true"
111
+
112
+ <div class="flex items-center gap-x-2">
113
+ <button
114
+ id="refresh-btn"
115
+ class="inline-flex items-center gap-x-2 rounded-xl border border-[#252a34] bg-[#111217] px-3.5 py-1.5 text-sm font-medium hover:bg-[#161a21] transition-colors"
116
+ title="Refresh data (R)"
51
117
  >
52
- <path
53
- d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.66 0 3-1.34 3-3"
54
- />
55
- </svg>
56
- Refresh
57
- </button>
58
- <a href="/usage" class="btn btn-secondary" title="View live usage stats">Usage</a>
59
- <div class="export-group">
60
- <button id="export-json-btn" class="btn btn-secondary" title="Export as JSON">
61
- JSON
118
+ <svg
119
+ width="14"
120
+ height="14"
121
+ viewBox="0 0 24 24"
122
+ fill="none"
123
+ stroke="currentColor"
124
+ stroke-width="2.5"
125
+ >
126
+ <path
127
+ d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.66 0 3-1.34 3-3"
128
+ />
129
+ </svg>
130
+ <span>Refresh</span>
62
131
  </button>
63
- <button id="export-csv-btn" class="btn btn-secondary" title="Export as CSV">CSV</button>
132
+
133
+ <a
134
+ href="/usage"
135
+ class="inline-flex items-center rounded-xl border border-[#252a34] bg-[#111217] px-3.5 py-1.5 text-sm font-medium hover:bg-[#161a21] transition-colors"
136
+ >
137
+ Usage
138
+ </a>
139
+
140
+ <div class="flex rounded-xl border border-[#252a34] overflow-hidden">
141
+ <button
142
+ id="export-json-btn"
143
+ class="px-3 py-1.5 text-sm hover:bg-[#161a21] border-r border-[#252a34]"
144
+ >
145
+ JSON
146
+ </button>
147
+ <button id="export-csv-btn" class="px-3 py-1.5 text-sm hover:bg-[#161a21]">
148
+ CSV
149
+ </button>
150
+ </div>
151
+
152
+ <a
153
+ href="https://github.com/Klepsiphron/agenttrace"
154
+ target="_blank"
155
+ class="inline-flex items-center gap-x-2 rounded-xl border border-[#252a34] bg-[#111217] px-3.5 py-1.5 text-sm font-medium hover:bg-[#161a21] transition-colors"
156
+ >
157
+ GitHub
158
+ </a>
64
159
  </div>
65
- <span class="version" id="version-badge">v0.1.0</span>
66
160
  </div>
67
161
  </div>
68
162
  </header>
69
163
 
70
- <main class="container">
164
+ <main class="max-w-[1280px] mx-auto px-6 py-6">
71
165
  <!-- Stats -->
72
- <section class="section" aria-label="Summary statistics">
73
- <div class="stats-grid" id="stats">
74
- <!-- Populated by JS -->
75
- <div class="stat-card">
166
+ <section class="mb-6" aria-label="Summary statistics">
167
+ <div class="grid grid-cols-2 md:grid-cols-4 gap-4" id="stats">
168
+ <!-- JS populated stat cards (kept same structure for app.js) -->
169
+ <div class="stat-card rounded-3xl border border-[#252a34] bg-[#111217] p-5">
76
170
  <div class="skeleton skeleton-stat"></div>
77
171
  <div class="skeleton skeleton-line" style="width: 60%"></div>
78
172
  </div>
79
- <div class="stat-card">
173
+ <div class="stat-card rounded-3xl border border-[#252a34] bg-[#111217] p-5">
80
174
  <div class="skeleton skeleton-stat"></div>
81
175
  <div class="skeleton skeleton-line" style="width: 60%"></div>
82
176
  </div>
83
- <div class="stat-card">
177
+ <div class="stat-card rounded-3xl border border-[#252a34] bg-[#111217] p-5">
84
178
  <div class="skeleton skeleton-stat"></div>
85
179
  <div class="skeleton skeleton-line" style="width: 60%"></div>
86
180
  </div>
87
- <div class="stat-card">
181
+ <div class="stat-card rounded-3xl border border-[#252a34] bg-[#111217] p-5">
88
182
  <div class="skeleton skeleton-stat"></div>
89
183
  <div class="skeleton skeleton-line" style="width: 60%"></div>
90
184
  </div>
@@ -92,54 +186,90 @@
92
186
  </section>
93
187
 
94
188
  <!-- Burn rate + Top Agents -->
95
- <div class="side-by-side">
96
- <div class="burn-card" aria-label="Token burn rate">
97
- <div class="burn-label">Token Burn Rate</div>
98
- <div class="burn-value" id="burn-tokens">— t/min</div>
99
- <div class="burn-sub" id="burn-cost">— cost/hr</div>
189
+ <div class="grid grid-cols-1 lg:grid-cols-2 gap-4 mb-6">
190
+ <div
191
+ class="burn-card rounded-3xl border border-[#252a34] bg-[#111217] p-5"
192
+ aria-label="Token burn rate"
193
+ >
194
+ <div class="burn-label text-xs uppercase tracking-widest text-[#8a90a0] mb-1">
195
+ Token Burn Rate (last hour)
196
+ </div>
197
+ <div class="burn-value text-3xl font-semibold tabular-nums" id="burn-tokens">— t/min</div>
198
+ <div class="burn-sub text-sm text-[#8a90a0]" id="burn-cost">— cost/hr</div>
100
199
  </div>
101
- <div class="top-agents" aria-label="Top agents by cost">
102
- <h3>Top Agents</h3>
103
- <div id="top-agents-list" class="top-agents-list">
104
- <div class="empty small">Loading…</div>
200
+
201
+ <div
202
+ class="top-agents rounded-3xl border border-[#252a34] bg-[#111217] p-5"
203
+ aria-label="Top agents by cost"
204
+ >
205
+ <div class="text-xs uppercase tracking-widest text-[#8a90a0] mb-3">
206
+ Top Agents by Cost
105
207
  </div>
208
+ <div id="top-agents-list" class="top-agents-list text-sm"></div>
106
209
  </div>
107
210
  </div>
108
211
 
109
- <!-- Filters / Toolbar -->
110
- <section class="toolbar" aria-label="Filter and search runs">
212
+ <!-- Filters -->
213
+ <div class="flex flex-wrap items-center gap-3 mb-4" aria-label="Filter and search runs">
111
214
  <input
112
215
  type="text"
113
216
  id="search-input"
114
- class="search-input"
217
+ class="search-input w-full sm:w-72 rounded-2xl border border-[#252a34] bg-[#111217] px-4 py-2 text-sm placeholder:text-[#8a90a0] focus:border-[#6366f1] focus:outline-none"
115
218
  placeholder="Search runs by name…"
116
- aria-label="Search runs by name"
117
219
  />
118
- <div class="filter-group" id="status-filters" role="group" aria-label="Filter by status">
119
- <button class="filter-btn active" data-status="all" aria-pressed="true">All</button>
120
- <button class="filter-btn" data-status="success" aria-pressed="false">Success</button>
121
- <button class="filter-btn" data-status="failure" aria-pressed="false">Failure</button>
122
- <button class="filter-btn" data-status="running" aria-pressed="false">Running</button>
220
+
221
+ <div
222
+ class="filter-group flex rounded-2xl border border-[#252a34] bg-[#111217] overflow-hidden text-sm"
223
+ id="status-filters"
224
+ role="group"
225
+ >
226
+ <button class="filter-btn active px-4 py-1.5" data-status="all">All</button>
227
+ <button class="filter-btn px-4 py-1.5" data-status="success">Success</button>
228
+ <button class="filter-btn px-4 py-1.5" data-status="failure">Failure</button>
229
+ <button class="filter-btn px-4 py-1.5" data-status="running">Running</button>
123
230
  </div>
124
- <div class="date-range" id="date-range" role="group" aria-label="Date range">
125
- <button class="date-btn active" data-range="all">All</button>
126
- <button class="date-btn" data-range="1h">1h</button>
127
- <button class="date-btn" data-range="today">Today</button>
128
- <button class="date-btn" data-range="week">Week</button>
231
+
232
+ <div
233
+ class="date-range flex rounded-2xl border border-[#252a34] bg-[#111217] overflow-hidden text-sm"
234
+ id="date-range"
235
+ role="group"
236
+ >
237
+ <button class="date-btn active px-3.5 py-1.5" data-range="all">All</button>
238
+ <button class="date-btn px-3.5 py-1.5" data-range="1h">1h</button>
239
+ <button class="date-btn px-3.5 py-1.5" data-range="today">Today</button>
240
+ <button class="date-btn px-3.5 py-1.5" data-range="week">Week</button>
129
241
  </div>
130
- <div class="toolbar-spacer"></div>
131
- <div class="status-hint" id="auto-refresh-hint">
242
+
243
+ <div class="flex-1"></div>
244
+
245
+ <div class="text-xs text-[#8a90a0]" id="auto-refresh-hint">
132
246
  Auto-refreshes every 5s • <span id="runs-total">0</span> total
133
247
  </div>
134
- </section>
248
+ </div>
135
249
 
136
250
  <!-- Runs List -->
137
- <section class="panel" aria-labelledby="runs-heading">
138
- <div class="panel-header">
139
- <h2 id="runs-heading">Recent Agent Runs</h2>
140
- <span id="runs-count" class="count-badge">0 runs</span>
251
+ <section
252
+ class="panel rounded-3xl border border-[#252a34] bg-[#111217] overflow-hidden mb-4"
253
+ aria-labelledby="runs-heading"
254
+ >
255
+ <div
256
+ class="panel-header flex items-center justify-between px-5 py-3 border-b border-[#252a34] bg-[#161a21]"
257
+ >
258
+ <h2 id="runs-heading" class="font-semibold text-base tracking-tight">
259
+ Recent Agent Runs
260
+ </h2>
261
+ <span
262
+ id="runs-count"
263
+ class="count-badge text-xs px-3 py-0.5 rounded-full border border-[#252a34] bg-[#0a0b0f] text-[#8a90a0]"
264
+ >0 runs</span
265
+ >
141
266
  </div>
142
- <div id="runs-list" class="runs-list" aria-live="polite" role="list">
267
+ <div
268
+ id="runs-list"
269
+ class="runs-list divide-y divide-[#252a34]"
270
+ aria-live="polite"
271
+ role="list"
272
+ >
143
273
  <!-- Populated by JS -->
144
274
  </div>
145
275
  </section>
@@ -147,47 +277,75 @@
147
277
  <!-- Traces -->
148
278
  <section
149
279
  id="traces-section"
150
- class="panel"
280
+ class="panel rounded-3xl border border-[#252a34] bg-[#111217] overflow-hidden mb-4"
151
281
  style="display: none"
152
282
  aria-labelledby="traces-heading"
153
283
  >
154
- <div class="panel-header">
155
- <h2 id="traces-heading">
156
- Traces for <span id="selected-run-name" class="run-name"></span>
284
+ <div
285
+ class="panel-header flex items-center justify-between px-5 py-3 border-b border-[#252a34] bg-[#161a21]"
286
+ >
287
+ <h2 id="traces-heading" class="font-semibold text-base tracking-tight">
288
+ Traces for
289
+ <span id="selected-run-name" class="run-name font-mono text-[#a5b4fc]"></span>
157
290
  </h2>
158
- <span id="traces-count" class="count-badge">0 traces</span>
291
+ <span
292
+ id="traces-count"
293
+ class="count-badge text-xs px-3 py-0.5 rounded-full border border-[#252a34] bg-[#0a0b0f] text-[#8a90a0]"
294
+ >0 traces</span
295
+ >
159
296
  </div>
160
- <div id="traces-list" class="traces-list" role="list"></div>
297
+ <div id="traces-list" class="traces-list divide-y divide-[#252a34]" role="list"></div>
161
298
  </section>
162
299
 
163
300
  <!-- Trace Details -->
164
301
  <section
165
302
  id="details-section"
166
- class="panel"
303
+ class="panel rounded-3xl border border-[#252a34] bg-[#111217] overflow-hidden"
167
304
  style="display: none"
168
305
  aria-labelledby="details-heading"
169
306
  >
170
- <div class="panel-header">
171
- <h2 id="details-heading">Trace Details</h2>
172
- <button id="close-details-btn" class="btn btn-ghost" aria-label="Close details (Esc)">
173
- Close
307
+ <div
308
+ class="panel-header flex items-center justify-between px-5 py-3 border-b border-[#252a34] bg-[#161a21]"
309
+ >
310
+ <h2 id="details-heading" class="font-semibold text-base tracking-tight">Trace Details</h2>
311
+ <button
312
+ id="close-details-btn"
313
+ class="text-sm text-[#8a90a0] hover:text-white px-3 py-1 rounded-xl border border-[#252a34] hover:bg-[#161a21]"
314
+ >
315
+ Close
174
316
  </button>
175
317
  </div>
176
- <div id="trace-details" class="trace-details"></div>
318
+ <div id="trace-details" class="trace-details p-5"></div>
177
319
  </section>
178
320
  </main>
179
321
 
180
- <footer class="footer">
181
- <span
182
- >AgentTrace data lives on disk •
183
- <a href="https://github.com/Klepsiphron/agenttrace" target="_blank" rel="noopener"
184
- >GitHub</a
185
- ></span
322
+ <footer class="max-w-[1280px] mx-auto px-6 pb-8 text-center text-xs text-[#8a90a0]">
323
+ Data lives entirely on your machine in SQLite •
324
+ <a href="https://github.com/Klepsiphron/agenttrace" target="_blank" class="hover:text-white"
325
+ >GitHub</a
186
326
  >
187
327
  </footer>
188
328
 
189
- <div id="toast-container" class="toast-container" aria-live="polite"></div>
329
+ <div id="toast-container" class="fixed bottom-5 right-5 z-[200] flex flex-col gap-2"></div>
190
330
 
191
331
  <script src="app.js"></script>
332
+
333
+ <script>
334
+ // Tailwind config to match the new landing page aesthetic
335
+ function initTailwind() {
336
+ if (window.tailwind) {
337
+ window.tailwind.config = {
338
+ theme: {
339
+ extend: {
340
+ fontFamily: {
341
+ display: ['Space Grotesk', 'Inter', 'system-ui', 'sans-serif'],
342
+ },
343
+ },
344
+ },
345
+ };
346
+ }
347
+ }
348
+ initTailwind();
349
+ </script>
192
350
  </body>
193
351
  </html>