@raquezha/notrace 0.0.7 → 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.
- package/CHANGELOG.md +14 -0
- package/dist/notrace/adapters.js +4 -1
- package/dist/notrace/index.js +41 -13
- package/dist/notrace/renderer.js +140 -21
- package/extensions/notrace/adapters.ts +4 -1
- package/extensions/notrace/index.ts +38 -15
- package/extensions/notrace/renderer.ts +137 -21
- package/package.json +1 -1
- package/templates/dashboard.sample.html +58 -14
- package/templates/session.sample.html +51 -9
- package/templates/sessions/019ed2ee-1000-76ee-b353-000000000001/notrace.html +51 -9
- package/templates/sessions/019ed2ee-1001-76ee-b353-000000000002/notrace.html +51 -9
- package/templates/sessions/019ed2ee-1002-76ee-b353-000000000003/notrace.html +51 -9
|
@@ -259,7 +259,7 @@ function shell(title: string, body: string, script = ""): string {
|
|
|
259
259
|
align-items: center;
|
|
260
260
|
margin-top: 16px;
|
|
261
261
|
}
|
|
262
|
-
.pill, .workflow-pill, .sort-btn {
|
|
262
|
+
.pill, .workflow-pill, .sort-btn, .export-btn {
|
|
263
263
|
display: inline-flex;
|
|
264
264
|
align-items: center;
|
|
265
265
|
gap: 6px;
|
|
@@ -272,7 +272,7 @@ function shell(title: string, body: string, script = ""): string {
|
|
|
272
272
|
font-size: 0.86rem;
|
|
273
273
|
font-weight: 600;
|
|
274
274
|
}
|
|
275
|
-
.metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(
|
|
275
|
+
.metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(135px, 1fr)); gap: 16px; margin: 24px 0; }
|
|
276
276
|
.metric-card {
|
|
277
277
|
background: var(--panel-strong);
|
|
278
278
|
border: 1px solid var(--border);
|
|
@@ -391,7 +391,42 @@ function shell(title: string, body: string, script = ""): string {
|
|
|
391
391
|
.msg-role { font-size: 0.78rem; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; }
|
|
392
392
|
.msg.user .msg-role { color: #8ec5ff; }
|
|
393
393
|
.msg.assistant .msg-role { color: var(--accent); }
|
|
394
|
-
.msg-content { padding: 14px;
|
|
394
|
+
.msg-content { padding: 14px; }
|
|
395
|
+
.chat-text {
|
|
396
|
+
white-space: pre-wrap;
|
|
397
|
+
word-break: break-word;
|
|
398
|
+
font-size: 0.95rem;
|
|
399
|
+
line-height: 1.6;
|
|
400
|
+
margin-bottom: 12px;
|
|
401
|
+
}
|
|
402
|
+
.chat-text:last-child { margin-bottom: 0; }
|
|
403
|
+
.chat-tool-use {
|
|
404
|
+
background: rgba(0,0,0,0.3);
|
|
405
|
+
border: 1px solid var(--border);
|
|
406
|
+
border-radius: 8px;
|
|
407
|
+
overflow: hidden;
|
|
408
|
+
margin-bottom: 12px;
|
|
409
|
+
}
|
|
410
|
+
.chat-tool-use:last-child { margin-bottom: 0; }
|
|
411
|
+
.chat-tool-header {
|
|
412
|
+
background: rgba(255,255,255,0.04);
|
|
413
|
+
padding: 8px 12px;
|
|
414
|
+
font-size: 0.8rem;
|
|
415
|
+
font-family: "SFMono-Regular", ui-monospace, Menlo, Monaco, Consolas, monospace;
|
|
416
|
+
color: #8ec5ff;
|
|
417
|
+
border-bottom: 1px solid var(--border);
|
|
418
|
+
display: flex;
|
|
419
|
+
align-items: center;
|
|
420
|
+
gap: 8px;
|
|
421
|
+
}
|
|
422
|
+
.chat-tool-body {
|
|
423
|
+
padding: 12px;
|
|
424
|
+
margin: 0;
|
|
425
|
+
background: transparent;
|
|
426
|
+
border: none;
|
|
427
|
+
max-height: 400px;
|
|
428
|
+
overflow-y: auto;
|
|
429
|
+
}
|
|
395
430
|
.footer-note {
|
|
396
431
|
margin-top: 22px;
|
|
397
432
|
color: var(--muted);
|
|
@@ -436,7 +471,15 @@ function shell(title: string, body: string, script = ""): string {
|
|
|
436
471
|
color: var(--text);
|
|
437
472
|
border-bottom-color: rgba(236,227,218,0.45);
|
|
438
473
|
}
|
|
439
|
-
|
|
474
|
+
.export-btn {
|
|
475
|
+
cursor: pointer;
|
|
476
|
+
transition: color 120ms ease, border-color 120ms ease, background 120ms ease;
|
|
477
|
+
}
|
|
478
|
+
.export-btn:hover, .export-btn.copied {
|
|
479
|
+
color: var(--text);
|
|
480
|
+
border-color: rgba(216,132,98,0.45);
|
|
481
|
+
background: var(--accent-soft);
|
|
482
|
+
}
|
|
440
483
|
.container { padding: 20px 14px 48px; }
|
|
441
484
|
.hero { padding: 20px; }
|
|
442
485
|
.hero-top { grid-template-columns: 1fr; }
|
|
@@ -451,8 +494,26 @@ function shell(title: string, body: string, script = ""): string {
|
|
|
451
494
|
</html>`;
|
|
452
495
|
}
|
|
453
496
|
|
|
454
|
-
function copyButton(value: string, label: string): string {
|
|
455
|
-
return `<button class="
|
|
497
|
+
function copyButton(value: string, label: string, className = "copy-btn"): string {
|
|
498
|
+
return `<button class="${escapeHtml(className)}" type="button" data-copy-value="${escapeHtml(value)}" aria-label="Copy ${escapeHtml(label)}" title="Copy ${escapeHtml(label)}"><svg width="14" height="14" viewBox="0 0 24 24" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></button>`;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
function exportButton(data: any): string {
|
|
502
|
+
const payload = JSON.stringify({
|
|
503
|
+
kind: "notrace-export",
|
|
504
|
+
traceId: data.traceId,
|
|
505
|
+
repository: data.repository?.name,
|
|
506
|
+
branch: data.repository?.branch,
|
|
507
|
+
task: data.task,
|
|
508
|
+
metrics: data.activity?.totals,
|
|
509
|
+
summary: data.telemetry?.extensions?.noheadroom?.summary,
|
|
510
|
+
events: (data.events || []).filter((e: any) => e.type === "llm_completion").map((e: any) => ({
|
|
511
|
+
model: e.model,
|
|
512
|
+
input: e.inputPayload?.messages,
|
|
513
|
+
output: e.outputContent
|
|
514
|
+
}))
|
|
515
|
+
});
|
|
516
|
+
return `<button class="export-btn" type="button" data-copy-value="${escapeHtml(payload)}" title="Copy session data for LLM/Agent context"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg><span>Export</span></button>`;
|
|
456
517
|
}
|
|
457
518
|
|
|
458
519
|
function copyScript(): string {
|
|
@@ -493,9 +554,61 @@ function renderJsonBlock(title: string, value: unknown): string {
|
|
|
493
554
|
return `<section class="block"><h4>${escapeHtml(title)}</h4><pre>${escapeHtml(typeof value === "string" ? value : JSON.stringify(value, null, 2))}</pre></section>`;
|
|
494
555
|
}
|
|
495
556
|
|
|
557
|
+
function renderToolUseHtml(name: string, input: any): string {
|
|
558
|
+
const parsedInput = typeof input === "string" ? (() => { try { return JSON.parse(input); } catch { return input; } })() : input;
|
|
559
|
+
return `<div class="chat-tool-use"><div class="chat-tool-header"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"></path></svg> ${escapeHtml(name)}</div><pre class="chat-tool-body">${escapeHtml(typeof parsedInput === 'string' ? parsedInput : JSON.stringify(parsedInput, null, 2))}</pre></div>`;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
function renderToolResultHtml(id: string, content: any): string {
|
|
563
|
+
return `<div class="chat-tool-use"><div class="chat-tool-header" style="color: var(--muted);"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 10 4 15 9 20"></polyline><path d="M20 4v7a4 4 0 0 1-4 4H4"></path></svg> Tool Result: ${escapeHtml(id)}</div><pre class="chat-tool-body">${escapeHtml(typeof content === 'string' ? content : JSON.stringify(content, null, 2))}</pre></div>`;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
function renderUniversalMessageContent(m: any): string {
|
|
567
|
+
if (!m) return "";
|
|
568
|
+
let html = "";
|
|
569
|
+
|
|
570
|
+
// 1. Handle string content or Anthropic/Pi blocks
|
|
571
|
+
if (typeof m.content === "string" && m.content.trim()) {
|
|
572
|
+
html += `<div class="chat-text">${escapeHtml(m.content)}</div>`;
|
|
573
|
+
} else if (Array.isArray(m.content)) {
|
|
574
|
+
html += m.content.map((block: any) => {
|
|
575
|
+
if (!block) return "";
|
|
576
|
+
if (block.type === "text") return `<div class="chat-text">${escapeHtml(block.text)}</div>`;
|
|
577
|
+
if (block.type === "tool_use") return renderToolUseHtml(block.name, block.input);
|
|
578
|
+
if (block.type === "tool_result") return renderToolResultHtml(block.tool_use_id || "unknown", block.content);
|
|
579
|
+
return `<pre class="chat-tool-body">${escapeHtml(JSON.stringify(block, null, 2))}</pre>`;
|
|
580
|
+
}).join("");
|
|
581
|
+
} else if (m.content && typeof m.content === "object") {
|
|
582
|
+
html += `<pre class="chat-tool-body">${escapeHtml(JSON.stringify(m.content, null, 2))}</pre>`;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// 2. Handle OpenAI/Codex tool_calls (attached to message, not in content)
|
|
586
|
+
if (Array.isArray(m.tool_calls)) {
|
|
587
|
+
html += m.tool_calls.map((tc: any) => {
|
|
588
|
+
if (tc.type === "function" && tc.function) {
|
|
589
|
+
return renderToolUseHtml(tc.function.name, tc.function.arguments);
|
|
590
|
+
}
|
|
591
|
+
return "";
|
|
592
|
+
}).join("");
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
// 3. Handle OpenAI legacy function_call
|
|
596
|
+
if (m.function_call) {
|
|
597
|
+
html += renderToolUseHtml(m.function_call.name, m.function_call.arguments);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// 4. Handle OpenAI tool result (message role is "tool")
|
|
601
|
+
if (m.role === "tool" && !html.includes("chat-tool-result")) {
|
|
602
|
+
// If it was just a string, it rendered above. Wrap it in a tool result block instead.
|
|
603
|
+
html = renderToolResultHtml(m.tool_call_id || m.name || "unknown", m.content);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
return html || `<div class="empty">Empty message</div>`;
|
|
607
|
+
}
|
|
608
|
+
|
|
496
609
|
function renderMessages(messages: any[] | undefined): string {
|
|
497
610
|
if (!messages?.length) return "";
|
|
498
|
-
return `<section class="block"><h4>Input Messages</h4>${messages.map(m => `<div class="msg ${escapeHtml(m?.role || "unknown")}"><div class="msg-head"><span class="msg-role">${escapeHtml(m?.role || "unknown")}</span></div><div class="msg-content">${
|
|
611
|
+
return `<section class="block"><h4>Input Messages</h4>${messages.map(m => `<div class="msg ${escapeHtml(m?.role || "unknown")}"><div class="msg-head"><span class="msg-role">${escapeHtml(m?.role || "unknown")}</span></div><div class="msg-content">${renderUniversalMessageContent(m)}</div></div>`).join("")}</section>`;
|
|
499
612
|
}
|
|
500
613
|
|
|
501
614
|
function eventBadgeClass(ev: any): string {
|
|
@@ -518,12 +631,12 @@ function renderEventCard(ev: any): string {
|
|
|
518
631
|
if (ev.errorMessage) {
|
|
519
632
|
sections.push(renderJsonBlock("Error Message", ev.errorMessage));
|
|
520
633
|
}
|
|
521
|
-
sections.push(
|
|
634
|
+
sections.push(`<section class="block"><h4>Output</h4><div class="msg-content">${renderUniversalMessageContent({ content: ev.outputContent })}</div></section>`);
|
|
522
635
|
if (ev.usage) sections.push(renderJsonBlock("Usage", ev.usage));
|
|
523
636
|
} else if (ev.type === "tool_start") {
|
|
524
|
-
sections.push(
|
|
637
|
+
sections.push(`<section class="block"><h4>Arguments</h4><div class="msg-content"><div class="chat-tool-use"><div class="chat-tool-header"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"></path></svg> Execution Input</div><pre class="chat-tool-body">${escapeHtml(typeof ev.args === 'string' ? ev.args : JSON.stringify(ev.args, null, 2))}</pre></div></div></section>`);
|
|
525
638
|
} else if (ev.type === "tool_end") {
|
|
526
|
-
sections.push(
|
|
639
|
+
sections.push(`<section class="block"><h4>${ev.isError ? "Error Result" : "Result"}</h4><div class="msg-content"><div class="chat-tool-use" style="${ev.isError ? 'border-color: rgba(239,127,127,0.3);' : ''}"><div class="chat-tool-header" style="${ev.isError ? 'color: var(--err);' : 'color: var(--muted);'}"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 10 4 15 9 20"></polyline><path d="M20 4v7a4 4 0 0 1-4 4H4"></path></svg> Execution Output</div><pre class="chat-tool-body">${escapeHtml(typeof ev.result === 'string' ? ev.result : JSON.stringify(ev.result, null, 2))}</pre></div></div></section>`);
|
|
527
640
|
} else {
|
|
528
641
|
sections.push(renderJsonBlock("Event", ev));
|
|
529
642
|
}
|
|
@@ -600,17 +713,19 @@ export function generateDashboardHtml(sessions: any[], options: any = {}): strin
|
|
|
600
713
|
const reversed = sessions.slice().reverse();
|
|
601
714
|
const totalCost = sessions.reduce((sum, s) => sum + Number(s.activity?.totals?.totalCostUsd || 0), 0);
|
|
602
715
|
const totalTokens = sessions.reduce((sum, s) => sum + Number(s.activity?.totals?.totalTokens || 0), 0);
|
|
603
|
-
const repositoryName = resolveRepoName(options);
|
|
604
716
|
const homeHref = options?.indexHref || "index.html";
|
|
605
717
|
const body = `<div class="container">
|
|
606
718
|
<section class="hero">
|
|
607
|
-
<div class="hero-
|
|
608
|
-
<
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
719
|
+
<div class="hero-split">
|
|
720
|
+
<a class="brand-link" href="${escapeHtml(homeHref)}">${wordmarkSvg()}</a>
|
|
721
|
+
<div class="hero-right">
|
|
722
|
+
<div class="hero-session">
|
|
723
|
+
<strong style="color: var(--text); font-weight: 500;">Global Index</strong>
|
|
724
|
+
<span style="color: var(--muted);">Machine-wide session evidence.</span>
|
|
725
|
+
</div>
|
|
726
|
+
<div class="hero-meta">
|
|
727
|
+
<span class="hero-pill">${sessions.length} sessions</span>
|
|
728
|
+
</div>
|
|
614
729
|
</div>
|
|
615
730
|
</div>
|
|
616
731
|
<div class="metrics">
|
|
@@ -621,14 +736,14 @@ export function generateDashboardHtml(sessions: any[], options: any = {}): strin
|
|
|
621
736
|
</section>
|
|
622
737
|
<section class="panel">
|
|
623
738
|
<h2 class="section-title">Session Reports</h2>
|
|
624
|
-
${reversed.length ? `<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 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>
|
|
739
|
+
${reversed.length ? `<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>
|
|
625
740
|
${reversed.map((s, index) => {
|
|
626
|
-
const link = s.artifacts.html.startsWith(".notrace/") ? s.artifacts.html.substring(9) : s.artifacts.html;
|
|
741
|
+
const link = s.artifacts?.html ? (s.artifacts.html.startsWith(".notrace/") ? s.artifacts.html.substring(9) : s.artifacts.html) : "#";
|
|
627
742
|
const workflow = s.task?.workflow || "generic";
|
|
628
743
|
const workflowLabel = workflowDisplayName(workflow);
|
|
629
744
|
const tokens = Number(s.activity?.totals?.totalTokens || 0);
|
|
630
745
|
const cost = Number(s.activity?.totals?.totalCostUsd || 0);
|
|
631
|
-
return `<tr data-index="${reversed.length - index}" data-workflow="${escapeHtml(workflowLabel)}" data-started="${parseDate(s.startedAt)?.getTime() || 0}" data-tokens="${tokens}" data-cost="${cost}"><td class="index-cell">${reversed.length - index}</td><td><a class="session-link" href="${escapeHtml(link)}"><strong>${escapeHtml(String(s.sessionId).slice(0, 8))}</strong><span class="session-sub">${escapeHtml(String(s.sessionId))}</span></a></td><td><span class="workflow-pill ${workflowClassName(workflow)}">${escapeHtml(workflowLabel)}</span></td><td>${formatDateCell(s.startedAt)}</td><td>${escapeHtml(taskDisplay(s))}</td><td class="num-cell">${tokens.toLocaleString()}</td><td class="num-cell">${formatUsd(cost)}</td></tr>`;
|
|
746
|
+
return `<tr data-index="${reversed.length - index}" data-workflow="${escapeHtml(workflowLabel)}" data-started="${parseDate(s.startedAt)?.getTime() || 0}" data-tokens="${tokens}" data-cost="${cost}"><td class="index-cell">${reversed.length - index}</td><td><a class="session-link" href="${escapeHtml(link)}"><strong>${escapeHtml(String(s.sessionId).slice(0, 8))}</strong><span class="session-sub">${escapeHtml(String(s.sessionId))}</span></a></td><td><span class="hero-pill">${escapeHtml(s.repositoryName || "Unknown")}</span></td><td><span class="workflow-pill ${workflowClassName(workflow)}">${escapeHtml(workflowLabel)}</span></td><td>${formatDateCell(s.startedAt)}</td><td>${escapeHtml(taskDisplay(s))}</td><td class="num-cell">${tokens.toLocaleString()}</td><td class="num-cell">${formatUsd(cost)}</td></tr>`;
|
|
632
747
|
}).join("")}
|
|
633
748
|
</tbody></table>` : `<div class="empty">No sessions yet. Run Pi with notrace enabled. New reports appear here.</div>`}
|
|
634
749
|
</section>
|
|
@@ -652,6 +767,7 @@ export function generateHtmlReport(data: any): string {
|
|
|
652
767
|
<span class="pill">${escapeHtml(resolveRepoName(data))}</span>
|
|
653
768
|
<span class="pill">Started ${formatDateLong(data.session?.startedAt)}</span>
|
|
654
769
|
<span class="pill">Mode: ${escapeHtml(data.captureMode || "full")}</span>
|
|
770
|
+
${exportButton(data)}
|
|
655
771
|
</div>
|
|
656
772
|
</div>
|
|
657
773
|
<div class="metrics">
|
package/package.json
CHANGED
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
align-items: center;
|
|
115
115
|
margin-top: 16px;
|
|
116
116
|
}
|
|
117
|
-
.pill, .workflow-pill, .sort-btn {
|
|
117
|
+
.pill, .workflow-pill, .sort-btn, .export-btn {
|
|
118
118
|
display: inline-flex;
|
|
119
119
|
align-items: center;
|
|
120
120
|
gap: 6px;
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
font-size: 0.86rem;
|
|
128
128
|
font-weight: 600;
|
|
129
129
|
}
|
|
130
|
-
.metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(
|
|
130
|
+
.metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(135px, 1fr)); gap: 16px; margin: 24px 0; }
|
|
131
131
|
.metric-card {
|
|
132
132
|
background: var(--panel-strong);
|
|
133
133
|
border: 1px solid var(--border);
|
|
@@ -246,7 +246,40 @@
|
|
|
246
246
|
.msg-role { font-size: 0.78rem; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; }
|
|
247
247
|
.msg.user .msg-role { color: #8ec5ff; }
|
|
248
248
|
.msg.assistant .msg-role { color: var(--accent); }
|
|
249
|
-
.msg-content { padding: 14px;
|
|
249
|
+
.msg-content { padding: 14px; }
|
|
250
|
+
.chat-text {
|
|
251
|
+
white-space: pre-wrap;
|
|
252
|
+
word-break: break-word;
|
|
253
|
+
font-size: 0.95rem;
|
|
254
|
+
line-height: 1.6;
|
|
255
|
+
margin-bottom: 12px;
|
|
256
|
+
}
|
|
257
|
+
.chat-text:last-child { margin-bottom: 0; }
|
|
258
|
+
.chat-tool-use {
|
|
259
|
+
background: rgba(0,0,0,0.3);
|
|
260
|
+
border: 1px solid var(--border);
|
|
261
|
+
border-radius: 8px;
|
|
262
|
+
overflow: hidden;
|
|
263
|
+
margin-bottom: 12px;
|
|
264
|
+
}
|
|
265
|
+
.chat-tool-use:last-child { margin-bottom: 0; }
|
|
266
|
+
.chat-tool-header {
|
|
267
|
+
background: rgba(255,255,255,0.04);
|
|
268
|
+
padding: 8px 12px;
|
|
269
|
+
font-size: 0.8rem;
|
|
270
|
+
font-family: "SFMono-Regular", ui-monospace, Menlo, Monaco, Consolas, monospace;
|
|
271
|
+
color: #8ec5ff;
|
|
272
|
+
border-bottom: 1px solid var(--border);
|
|
273
|
+
display: flex;
|
|
274
|
+
align-items: center;
|
|
275
|
+
gap: 8px;
|
|
276
|
+
}
|
|
277
|
+
.chat-tool-body {
|
|
278
|
+
padding: 12px;
|
|
279
|
+
margin: 0;
|
|
280
|
+
background: transparent;
|
|
281
|
+
border: none;
|
|
282
|
+
}
|
|
250
283
|
.footer-note {
|
|
251
284
|
margin-top: 22px;
|
|
252
285
|
color: var(--muted);
|
|
@@ -291,7 +324,15 @@
|
|
|
291
324
|
color: var(--text);
|
|
292
325
|
border-bottom-color: rgba(236,227,218,0.45);
|
|
293
326
|
}
|
|
294
|
-
|
|
327
|
+
.export-btn {
|
|
328
|
+
cursor: pointer;
|
|
329
|
+
transition: color 120ms ease, border-color 120ms ease, background 120ms ease;
|
|
330
|
+
}
|
|
331
|
+
.export-btn:hover, .export-btn.copied {
|
|
332
|
+
color: var(--text);
|
|
333
|
+
border-color: rgba(216,132,98,0.45);
|
|
334
|
+
background: var(--accent-soft);
|
|
335
|
+
}
|
|
295
336
|
.container { padding: 20px 14px 48px; }
|
|
296
337
|
.hero { padding: 20px; }
|
|
297
338
|
.hero-top { grid-template-columns: 1fr; }
|
|
@@ -304,9 +345,8 @@
|
|
|
304
345
|
</head>
|
|
305
346
|
<body><div class="container">
|
|
306
347
|
<section class="hero">
|
|
307
|
-
<div class="hero-
|
|
308
|
-
<
|
|
309
|
-
<div class="brand"><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">
|
|
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">
|
|
310
350
|
<defs>
|
|
311
351
|
<linearGradient id="fadeGrad" x1="0%" y1="0%" x2="100%" y2="0%">
|
|
312
352
|
<stop offset="0%" stop-color="#E2754A"/>
|
|
@@ -323,11 +363,15 @@
|
|
|
323
363
|
</g>
|
|
324
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>
|
|
325
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>
|
|
326
|
-
</svg></a
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
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>
|
|
331
375
|
</div>
|
|
332
376
|
</div>
|
|
333
377
|
<div class="metrics">
|
|
@@ -338,8 +382,8 @@
|
|
|
338
382
|
</section>
|
|
339
383
|
<section class="panel">
|
|
340
384
|
<h2 class="section-title">Session Reports</h2>
|
|
341
|
-
<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 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>
|
|
342
|
-
<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="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="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="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>
|
|
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>
|
|
343
387
|
</tbody></table>
|
|
344
388
|
</section>
|
|
345
389
|
<footer class="footer-note minimal">notrace • raquezha 2026</footer>
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
align-items: center;
|
|
115
115
|
margin-top: 16px;
|
|
116
116
|
}
|
|
117
|
-
.pill, .workflow-pill, .sort-btn {
|
|
117
|
+
.pill, .workflow-pill, .sort-btn, .export-btn {
|
|
118
118
|
display: inline-flex;
|
|
119
119
|
align-items: center;
|
|
120
120
|
gap: 6px;
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
font-size: 0.86rem;
|
|
128
128
|
font-weight: 600;
|
|
129
129
|
}
|
|
130
|
-
.metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(
|
|
130
|
+
.metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(135px, 1fr)); gap: 16px; margin: 24px 0; }
|
|
131
131
|
.metric-card {
|
|
132
132
|
background: var(--panel-strong);
|
|
133
133
|
border: 1px solid var(--border);
|
|
@@ -246,7 +246,40 @@
|
|
|
246
246
|
.msg-role { font-size: 0.78rem; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; }
|
|
247
247
|
.msg.user .msg-role { color: #8ec5ff; }
|
|
248
248
|
.msg.assistant .msg-role { color: var(--accent); }
|
|
249
|
-
.msg-content { padding: 14px;
|
|
249
|
+
.msg-content { padding: 14px; }
|
|
250
|
+
.chat-text {
|
|
251
|
+
white-space: pre-wrap;
|
|
252
|
+
word-break: break-word;
|
|
253
|
+
font-size: 0.95rem;
|
|
254
|
+
line-height: 1.6;
|
|
255
|
+
margin-bottom: 12px;
|
|
256
|
+
}
|
|
257
|
+
.chat-text:last-child { margin-bottom: 0; }
|
|
258
|
+
.chat-tool-use {
|
|
259
|
+
background: rgba(0,0,0,0.3);
|
|
260
|
+
border: 1px solid var(--border);
|
|
261
|
+
border-radius: 8px;
|
|
262
|
+
overflow: hidden;
|
|
263
|
+
margin-bottom: 12px;
|
|
264
|
+
}
|
|
265
|
+
.chat-tool-use:last-child { margin-bottom: 0; }
|
|
266
|
+
.chat-tool-header {
|
|
267
|
+
background: rgba(255,255,255,0.04);
|
|
268
|
+
padding: 8px 12px;
|
|
269
|
+
font-size: 0.8rem;
|
|
270
|
+
font-family: "SFMono-Regular", ui-monospace, Menlo, Monaco, Consolas, monospace;
|
|
271
|
+
color: #8ec5ff;
|
|
272
|
+
border-bottom: 1px solid var(--border);
|
|
273
|
+
display: flex;
|
|
274
|
+
align-items: center;
|
|
275
|
+
gap: 8px;
|
|
276
|
+
}
|
|
277
|
+
.chat-tool-body {
|
|
278
|
+
padding: 12px;
|
|
279
|
+
margin: 0;
|
|
280
|
+
background: transparent;
|
|
281
|
+
border: none;
|
|
282
|
+
}
|
|
250
283
|
.footer-note {
|
|
251
284
|
margin-top: 22px;
|
|
252
285
|
color: var(--muted);
|
|
@@ -291,7 +324,15 @@
|
|
|
291
324
|
color: var(--text);
|
|
292
325
|
border-bottom-color: rgba(236,227,218,0.45);
|
|
293
326
|
}
|
|
294
|
-
|
|
327
|
+
.export-btn {
|
|
328
|
+
cursor: pointer;
|
|
329
|
+
transition: color 120ms ease, border-color 120ms ease, background 120ms ease;
|
|
330
|
+
}
|
|
331
|
+
.export-btn:hover, .export-btn.copied {
|
|
332
|
+
color: var(--text);
|
|
333
|
+
border-color: rgba(216,132,98,0.45);
|
|
334
|
+
background: var(--accent-soft);
|
|
335
|
+
}
|
|
295
336
|
.container { padding: 20px 14px 48px; }
|
|
296
337
|
.hero { padding: 20px; }
|
|
297
338
|
.hero-top { grid-template-columns: 1fr; }
|
|
@@ -329,6 +370,7 @@
|
|
|
329
370
|
<span class="pill">nothing</span>
|
|
330
371
|
<span class="pill">Started 2026-06-17 22:05</span>
|
|
331
372
|
<span class="pill">Mode: full</span>
|
|
373
|
+
<button class="export-btn" type="button" data-copy-value="{"kind":"notrace-export","traceId":"019ed2ee-5252-76ee-b353-ad925a6bad31","repository":"nothing","task":{"workflow":"research","id":"branch:main","path":null,"dir":null},"metrics":{"inputTokens":3120,"outputTokens":179,"cacheReadTokens":0,"cacheWriteTokens":0,"totalTokens":3299,"totalCostUsd":0.02064},"summary":"compressed 24,110 to 18,332 tokens; saved 5,778 tokens across 3 tool results","events":[{"model":"claude-sonnet-4","input":[{"role":"user","content":"Polish notrace HTML output and unify dashboard/session design."}],"output":"Found renderer split. Will move both pages to one shared shell and standardize styles."}]}" title="Copy session data for LLM/Agent context"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg><span>Export</span></button>
|
|
332
374
|
</div>
|
|
333
375
|
</div>
|
|
334
376
|
<div class="metrics">
|
|
@@ -423,9 +465,9 @@
|
|
|
423
465
|
</div>
|
|
424
466
|
<span class="event-time">22:05:04</span>
|
|
425
467
|
</summary>
|
|
426
|
-
<div class="event-body"><div class="stack"><section class="block"><h4>Arguments</h4><pre>{
|
|
468
|
+
<div class="event-body"><div class="stack"><section class="block"><h4>Arguments</h4><div class="msg-content"><div class="chat-tool-use"><div class="chat-tool-header"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"></path></svg> Execution Input</div><pre class="chat-tool-body">{
|
|
427
469
|
"command": "find packages/notrace -maxdepth 3 -type f"
|
|
428
|
-
}</pre></section></div></div>
|
|
470
|
+
}</pre></div></div></section></div></div>
|
|
429
471
|
</details><details class="event">
|
|
430
472
|
<summary>
|
|
431
473
|
<div class="event-main">
|
|
@@ -434,11 +476,11 @@
|
|
|
434
476
|
</div>
|
|
435
477
|
<span class="event-time">22:05:05</span>
|
|
436
478
|
</summary>
|
|
437
|
-
<div class="event-body"><div class="stack"><section class="block"><h4>Result</h4><pre>{
|
|
479
|
+
<div class="event-body"><div class="stack"><section class="block"><h4>Result</h4><div class="msg-content"><div class="chat-tool-use" style=""><div class="chat-tool-header" style="color: var(--muted);"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 10 4 15 9 20"></polyline><path d="M20 4v7a4 4 0 0 1-4 4H4"></path></svg> Execution Output</div><pre class="chat-tool-body">{
|
|
438
480
|
"stdout": "packages/notrace/extensions/notrace/index.ts\npackages/notrace/extensions/notrace/renderer.ts\npackages/notrace/package.json",
|
|
439
481
|
"stderr": "",
|
|
440
482
|
"exitCode": 0
|
|
441
|
-
}</pre></section></div></div>
|
|
483
|
+
}</pre></div></div></section></div></div>
|
|
442
484
|
</details><details class="event">
|
|
443
485
|
<summary>
|
|
444
486
|
<div class="event-main">
|
|
@@ -447,7 +489,7 @@
|
|
|
447
489
|
</div>
|
|
448
490
|
<span class="event-time">22:05:11</span>
|
|
449
491
|
</summary>
|
|
450
|
-
<div class="event-body"><div class="stack"><section class="block"><h4>Input Messages</h4><div class="msg user"><div class="msg-head"><span class="msg-role">user</span></div><div class="msg-content">Polish notrace HTML output and unify dashboard/session design.</div></div></section><section class="block"><h4>Output</h4><
|
|
492
|
+
<div class="event-body"><div class="stack"><section class="block"><h4>Input Messages</h4><div class="msg user"><div class="msg-head"><span class="msg-role">user</span></div><div class="msg-content"><div class="chat-text">Polish notrace HTML output and unify dashboard/session design.</div></div></div></section><section class="block"><h4>Output</h4><div class="msg-content"><div class="chat-text">Found renderer split. Will move both pages to one shared shell and standardize styles.</div></div></section><section class="block"><h4>Usage</h4><pre>{
|
|
451
493
|
"input": 2140,
|
|
452
494
|
"output": 116,
|
|
453
495
|
"cacheRead": 0,
|