@jefuriiij/synthra 0.1.0 → 0.1.2
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/dist/cli/index.js +765 -36
- package/dist/cli/index.js.map +1 -1
- package/dist/dashboard/index.js +762 -34
- package/dist/dashboard/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -18,7 +18,7 @@ var init_package = __esm({
|
|
|
18
18
|
"package.json"() {
|
|
19
19
|
package_default = {
|
|
20
20
|
name: "@jefuriiij/synthra",
|
|
21
|
-
version: "0.1.
|
|
21
|
+
version: "0.1.2",
|
|
22
22
|
publishConfig: {
|
|
23
23
|
access: "public"
|
|
24
24
|
},
|
|
@@ -83,6 +83,7 @@ var init_package = __esm({
|
|
|
83
83
|
});
|
|
84
84
|
|
|
85
85
|
// src/cli/index.ts
|
|
86
|
+
init_package();
|
|
86
87
|
import sade from "sade";
|
|
87
88
|
import { resolve as resolve4 } from "path";
|
|
88
89
|
|
|
@@ -455,28 +456,39 @@ var public_default = `<!doctype html>
|
|
|
455
456
|
|
|
456
457
|
<main>
|
|
457
458
|
<section>
|
|
458
|
-
<h2>
|
|
459
|
+
<h2>
|
|
460
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3v18h18"/><path d="M7 14l4-4 4 4 5-5"/></svg>
|
|
461
|
+
Global totals
|
|
462
|
+
<span class="muted">(all projects)</span>
|
|
463
|
+
</h2>
|
|
459
464
|
<div class="cards" id="cards"></div>
|
|
460
465
|
</section>
|
|
461
466
|
|
|
462
467
|
<section>
|
|
463
|
-
<h2>
|
|
468
|
+
<h2>
|
|
469
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>
|
|
470
|
+
Projects
|
|
471
|
+
</h2>
|
|
464
472
|
<div class="projects" id="projects"></div>
|
|
465
473
|
<p class="empty hidden" id="projects-empty">No projects registered yet. Run <code>syn .</code> in any project to add it.</p>
|
|
466
474
|
</section>
|
|
467
475
|
|
|
468
476
|
<section>
|
|
469
|
-
<h2>
|
|
477
|
+
<h2>
|
|
478
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
|
|
479
|
+
Recent calls
|
|
480
|
+
<span class="muted">(across all projects)</span>
|
|
481
|
+
</h2>
|
|
470
482
|
<table id="turns">
|
|
471
483
|
<thead>
|
|
472
484
|
<tr>
|
|
473
485
|
<th>Time</th>
|
|
474
486
|
<th>Project</th>
|
|
475
487
|
<th>Model</th>
|
|
476
|
-
<th class="num">Input</th>
|
|
477
|
-
<th class="num">Output</th>
|
|
478
|
-
<th class="num">Cache R / W</th>
|
|
479
|
-
<th class="num">Cost</th>
|
|
488
|
+
<th class="num"><span class="has-tooltip" data-tooltip="New (uncached) tokens you sent to Claude this turn. Usually small \u2014 most of the conversation comes from cache.">Input <span class="help-icon">i</span></span></th>
|
|
489
|
+
<th class="num"><span class="has-tooltip" data-tooltip="Tokens Claude generated in its response. The most expensive line item \u2014 ~5\xD7 the input rate on Opus.">Output <span class="help-icon">i</span></span></th>
|
|
490
|
+
<th class="num"><span class="has-tooltip" data-tooltip="Cache read / cache write. Reads (~10% of input rate) reuse prior context; writes (~125% of input rate) save new context for future turns.">Cache R / W <span class="help-icon">i</span></span></th>
|
|
491
|
+
<th class="num"><span class="has-tooltip" data-tooltip="Approximate USD cost for this turn \u2014 input \xD7 rate + output \xD7 5\xD7rate + cache_read \xD7 0.1\xD7rate + cache_write \xD7 1.25\xD7rate, using the turn's model.">Cost <span class="help-icon">i</span></span></th>
|
|
480
492
|
</tr>
|
|
481
493
|
</thead>
|
|
482
494
|
<tbody></tbody>
|
|
@@ -485,14 +497,17 @@ var public_default = `<!doctype html>
|
|
|
485
497
|
</section>
|
|
486
498
|
|
|
487
499
|
<section>
|
|
488
|
-
<h2>
|
|
500
|
+
<h2>
|
|
501
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
|
|
502
|
+
Recent gate decisions
|
|
503
|
+
</h2>
|
|
489
504
|
<table id="gates">
|
|
490
505
|
<thead>
|
|
491
506
|
<tr>
|
|
492
507
|
<th>Time</th>
|
|
493
508
|
<th>Project</th>
|
|
494
509
|
<th>Tool</th>
|
|
495
|
-
<th>Decision</th>
|
|
510
|
+
<th><span class="has-tooltip" data-tooltip="ALLOW = Synthra let the tool call through. BLOCK = Synthra intercepted it because the graph already had high-confidence context \u2014 Claude should use graph_continue instead.">Decision <span class="help-icon">i</span></span></th>
|
|
496
511
|
<th>Query</th>
|
|
497
512
|
</tr>
|
|
498
513
|
</thead>
|
|
@@ -503,11 +518,42 @@ var public_default = `<!doctype html>
|
|
|
503
518
|
</main>
|
|
504
519
|
|
|
505
520
|
<footer>
|
|
506
|
-
<span>Token
|
|
507
|
-
<span class="muted">Cost figures are approximate \u2014
|
|
521
|
+
<span>Synthra Token Dashboard \xB7 live polling every 2s</span>
|
|
522
|
+
<span class="muted">Cost figures are approximate \u2014 based on published Anthropic rates.</span>
|
|
508
523
|
</footer>
|
|
509
524
|
|
|
510
525
|
<script>
|
|
526
|
+
// Inline SVG icons. Each is a stroke-based icon, currentColor for the
|
|
527
|
+
// stroke, designed to inherit color from the parent's CSS.
|
|
528
|
+
const ICONS = {
|
|
529
|
+
dollar: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/></svg>',
|
|
530
|
+
chat: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>',
|
|
531
|
+
arrowDown: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><polyline points="19 12 12 19 5 12"/></svg>',
|
|
532
|
+
arrowUp: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="19" x2="12" y2="5"/><polyline points="5 12 12 5 19 12"/></svg>',
|
|
533
|
+
refresh: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/></svg>',
|
|
534
|
+
save: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg>',
|
|
535
|
+
folder: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>',
|
|
536
|
+
shield: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>',
|
|
537
|
+
trending: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 6 13.5 15.5 8.5 10.5 1 18"/><polyline points="17 6 23 6 23 12"/></svg>',
|
|
538
|
+
ban: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="4.93" y1="4.93" x2="19.07" y2="19.07"/></svg>',
|
|
539
|
+
};
|
|
540
|
+
|
|
541
|
+
// Classify a model name into a family for color-coding.
|
|
542
|
+
function modelFamily(model) {
|
|
543
|
+
if (!model) return 'unknown';
|
|
544
|
+
const m = model.toLowerCase();
|
|
545
|
+
if (m === '<synthetic>') return 'unknown';
|
|
546
|
+
if (m.includes('opus')) return 'opus';
|
|
547
|
+
if (m.includes('sonnet')) return 'sonnet';
|
|
548
|
+
if (m.includes('haiku')) return 'haiku';
|
|
549
|
+
return 'unknown';
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
function modelLabel(model) {
|
|
553
|
+
if (!model || model === '<synthetic>') return model === '<synthetic>' ? 'synthetic' : 'unknown';
|
|
554
|
+
return model;
|
|
555
|
+
}
|
|
556
|
+
|
|
511
557
|
const $ = (sel) => document.querySelector(sel);
|
|
512
558
|
const cardsEl = $("#cards");
|
|
513
559
|
const projectsEl = $("#projects");
|
|
@@ -550,23 +596,84 @@ var public_default = `<!doctype html>
|
|
|
550
596
|
}
|
|
551
597
|
}
|
|
552
598
|
|
|
599
|
+
// Definitions for the global-totals cards. Each: label, value-source key,
|
|
600
|
+
// icon, optional class (accent | money), tooltip text.
|
|
601
|
+
function cardConfigs(g) {
|
|
602
|
+
return [
|
|
603
|
+
{
|
|
604
|
+
label: "Total cost",
|
|
605
|
+
value: fmtCost(g.estimated_cost_usd),
|
|
606
|
+
icon: ICONS.dollar,
|
|
607
|
+
cls: "money",
|
|
608
|
+
tooltip: "Approximate USD cost across all projects. Computed from per-model pricing (Opus, Sonnet, Haiku) applied to each turn's input/output/cache. Tilde everywhere \u2014 real cost depends on Anthropic's current rates.",
|
|
609
|
+
},
|
|
610
|
+
{
|
|
611
|
+
label: "Turns",
|
|
612
|
+
value: fmt(g.total_turns),
|
|
613
|
+
icon: ICONS.chat,
|
|
614
|
+
tooltip: "Total number of back-and-forth exchanges with Claude across all projects. One turn = you send a message, Claude responds.",
|
|
615
|
+
},
|
|
616
|
+
{
|
|
617
|
+
label: "Input",
|
|
618
|
+
value: fmt(g.total_input_tokens),
|
|
619
|
+
icon: ICONS.arrowDown,
|
|
620
|
+
tooltip: "New (uncached) tokens sent to Claude across all turns. Usually small \u2014 most of the conversation comes from cache.",
|
|
621
|
+
},
|
|
622
|
+
{
|
|
623
|
+
label: "Output",
|
|
624
|
+
value: fmt(g.total_output_tokens),
|
|
625
|
+
icon: ICONS.arrowUp,
|
|
626
|
+
tooltip: "Tokens Claude generated in responses. The most expensive line item per turn (~5\xD7 input rate on Opus).",
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
label: "Cache read",
|
|
630
|
+
value: fmt(g.total_cache_read),
|
|
631
|
+
icon: ICONS.refresh,
|
|
632
|
+
tooltip: "Tokens read from Claude's prompt cache \u2014 conversation history, system prompt, Synthra's pack. Cheap: ~10% of the input rate. The bulk of every long session.",
|
|
633
|
+
},
|
|
634
|
+
{
|
|
635
|
+
label: "Cache write",
|
|
636
|
+
value: fmt(g.total_cache_create),
|
|
637
|
+
icon: ICONS.save,
|
|
638
|
+
tooltip: "Tokens newly added to the prompt cache so future turns can read them cheaply. Premium-priced (~125% of input) but pays back over the rest of the session.",
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
label: "Projects",
|
|
642
|
+
value: fmt(g.project_count),
|
|
643
|
+
icon: ICONS.folder,
|
|
644
|
+
tooltip: "Projects that have ever run \`syn .\` on this machine. Tracked in ~/.synthra/projects.json.",
|
|
645
|
+
},
|
|
646
|
+
{
|
|
647
|
+
label: "Blocked Grep / Glob",
|
|
648
|
+
value: fmt(g.blocked_count),
|
|
649
|
+
icon: ICONS.shield,
|
|
650
|
+
cls: "accent",
|
|
651
|
+
tooltip: "PreToolUse hook intercepts: Synthra blocked these Grep/Glob calls because the graph already had high-confidence context for the query. Claude pivots to graph_continue or graph_read instead.",
|
|
652
|
+
},
|
|
653
|
+
{
|
|
654
|
+
label: "Tokens saved",
|
|
655
|
+
value: fmt(g.estimated_tokens_saved),
|
|
656
|
+
icon: ICONS.trending,
|
|
657
|
+
cls: "accent",
|
|
658
|
+
tooltip: "Estimated tokens avoided by blocking exploratory Grep/Glob calls. Calculated as blocks \xD7 500 \u2014 conservative; under-counts the cache thrash you also avoid.",
|
|
659
|
+
},
|
|
660
|
+
];
|
|
661
|
+
}
|
|
662
|
+
|
|
553
663
|
function renderCards(g) {
|
|
554
664
|
cardsEl.innerHTML = "";
|
|
555
|
-
const
|
|
556
|
-
{ label: "Total cost", value: fmtCost(g.estimated_cost_usd), accent: true },
|
|
557
|
-
{ label: "Turns", value: fmt(g.total_turns) },
|
|
558
|
-
{ label: "Input", value: fmt(g.total_input_tokens) },
|
|
559
|
-
{ label: "Output", value: fmt(g.total_output_tokens) },
|
|
560
|
-
{ label: "Cache read", value: fmt(g.total_cache_read) },
|
|
561
|
-
{ label: "Cache write", value: fmt(g.total_cache_create) },
|
|
562
|
-
{ label: "Projects", value: fmt(g.project_count) },
|
|
563
|
-
{ label: "Blocked Grep / Glob", value: fmt(g.blocked_count), accent: true },
|
|
564
|
-
{ label: "Tokens saved", value: fmt(g.estimated_tokens_saved), accent: true },
|
|
565
|
-
];
|
|
566
|
-
for (const c of cards) {
|
|
665
|
+
for (const c of cardConfigs(g)) {
|
|
567
666
|
const el = document.createElement("div");
|
|
568
|
-
el.className = "card" + (c.
|
|
569
|
-
el.innerHTML =
|
|
667
|
+
el.className = "card" + (c.cls ? " " + c.cls : "");
|
|
668
|
+
el.innerHTML =
|
|
669
|
+
'<div class="card-head">' +
|
|
670
|
+
'<div class="card-label has-tooltip" data-tooltip="' + c.tooltip.replace(/"/g, '"') + '">' +
|
|
671
|
+
c.label +
|
|
672
|
+
' <span class="help-icon">i</span>' +
|
|
673
|
+
'</div>' +
|
|
674
|
+
'<span class="card-icon">' + c.icon + '</span>' +
|
|
675
|
+
'</div>' +
|
|
676
|
+
'<div class="card-value">' + c.value + '</div>';
|
|
570
677
|
cardsEl.appendChild(el);
|
|
571
678
|
}
|
|
572
679
|
}
|
|
@@ -587,7 +694,7 @@ var public_default = `<!doctype html>
|
|
|
587
694
|
row.className = "project-row";
|
|
588
695
|
row.innerHTML =
|
|
589
696
|
'<div class="project-name">' +
|
|
590
|
-
'<strong>' + p.name + '</strong>' +
|
|
697
|
+
'<strong>' + ICONS.folder + p.name + '</strong>' +
|
|
591
698
|
'<code class="project-path">' + p.path + '</code>' +
|
|
592
699
|
'</div>' +
|
|
593
700
|
'<div class="project-stats">' +
|
|
@@ -609,15 +716,12 @@ var public_default = `<!doctype html>
|
|
|
609
716
|
}
|
|
610
717
|
turnsEmpty.classList.add("hidden");
|
|
611
718
|
for (const t of turns) {
|
|
719
|
+
const family = modelFamily(t.model);
|
|
612
720
|
const tr = document.createElement("tr");
|
|
613
|
-
const modelCell =
|
|
614
|
-
t.model && t.model !== "<synthetic>"
|
|
615
|
-
? "<code>" + t.model + "</code>"
|
|
616
|
-
: '<span class="muted">' + (t.model === "<synthetic>" ? "synthetic" : "unknown") + "</span>";
|
|
617
721
|
tr.innerHTML =
|
|
618
722
|
"<td>" + fmtTs(t.ts) + "</td>" +
|
|
619
723
|
"<td><code>" + t.project_name + "</code></td>" +
|
|
620
|
-
|
|
724
|
+
'<td><span class="model-pill ' + family + '">' + modelLabel(t.model) + "</span></td>" +
|
|
621
725
|
'<td class="num">' + fmtFull(t.input) + "</td>" +
|
|
622
726
|
'<td class="num">' + fmtFull(t.output) + "</td>" +
|
|
623
727
|
'<td class="num">' + fmt(t.cache_read) + " / " + fmt(t.cache_create) + "</td>" +
|
|
@@ -635,12 +739,16 @@ var public_default = `<!doctype html>
|
|
|
635
739
|
gatesEmpty.classList.add("hidden");
|
|
636
740
|
for (const g of gates) {
|
|
637
741
|
const tr = document.createElement("tr");
|
|
638
|
-
const
|
|
742
|
+
const isBlock = g.decision === "block";
|
|
743
|
+
const cls = isBlock ? "decision-block" : "decision-allow";
|
|
744
|
+
const label = isBlock
|
|
745
|
+
? '<span class="' + cls + '">' + ICONS.ban + ' BLOCK</span>'
|
|
746
|
+
: '<span class="' + cls + '">ALLOW</span>';
|
|
639
747
|
tr.innerHTML =
|
|
640
748
|
"<td>" + fmtTs(g.ts) + "</td>" +
|
|
641
749
|
"<td><code>" + g.project_name + "</code></td>" +
|
|
642
750
|
"<td><code>" + g.tool + "</code></td>" +
|
|
643
|
-
|
|
751
|
+
"<td>" + label + "</td>" +
|
|
644
752
|
"<td><code>" + (g.query || "") + "</code></td>";
|
|
645
753
|
gatesBody.appendChild(tr);
|
|
646
754
|
}
|
|
@@ -674,7 +782,628 @@ var public_default = `<!doctype html>
|
|
|
674
782
|
`;
|
|
675
783
|
|
|
676
784
|
// src/dashboard/public/style.css
|
|
677
|
-
var style_default =
|
|
785
|
+
var style_default = `/* Synthra token dashboard \u2014 palette per project brief.
|
|
786
|
+
Base: cream-on-near-black, dark-red borders, hot-pink highlights.
|
|
787
|
+
Plus: money green for dollar amounts, per-family model colors,
|
|
788
|
+
subtle dot grid + top glow background, tooltip system, icons. */
|
|
789
|
+
|
|
790
|
+
:root {
|
|
791
|
+
/* Brand */
|
|
792
|
+
--color-heading: #ECEBD8;
|
|
793
|
+
--color-body: #EDECD9;
|
|
794
|
+
--color-bg: #000000;
|
|
795
|
+
--color-surface: #140009;
|
|
796
|
+
--color-surface-raised: #1E000D;
|
|
797
|
+
--color-border: #4D0020;
|
|
798
|
+
--color-accent: #FF0073;
|
|
799
|
+
--color-accent-darker: #EB006A;
|
|
800
|
+
--color-form-bg: #2E0014;
|
|
801
|
+
--color-muted: rgba(237, 236, 217, 0.55);
|
|
802
|
+
--color-very-muted: rgba(237, 236, 217, 0.35);
|
|
803
|
+
--color-block: #FF0073;
|
|
804
|
+
--color-allow: #ECEBD8;
|
|
805
|
+
|
|
806
|
+
/* Money green \u2014 used everywhere a $ amount appears */
|
|
807
|
+
--color-money: #36E596;
|
|
808
|
+
--color-money-darker: #00B85F;
|
|
809
|
+
--color-money-bg: rgba(54, 229, 150, 0.08);
|
|
810
|
+
|
|
811
|
+
/* Per-family model colors */
|
|
812
|
+
--color-model-opus: #C9A2FF;
|
|
813
|
+
--color-model-sonnet: #6BD0FF;
|
|
814
|
+
--color-model-haiku: #7BFFC7;
|
|
815
|
+
|
|
816
|
+
/* Background layering */
|
|
817
|
+
--bg-dot-color: rgba(237, 236, 217, 0.045);
|
|
818
|
+
--bg-glow-color: rgba(255, 0, 115, 0.07);
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
* {
|
|
822
|
+
box-sizing: border-box;
|
|
823
|
+
margin: 0;
|
|
824
|
+
padding: 0;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
html, body {
|
|
828
|
+
background-color: var(--color-bg);
|
|
829
|
+
color: var(--color-body);
|
|
830
|
+
font-family:
|
|
831
|
+
ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI",
|
|
832
|
+
system-ui, sans-serif;
|
|
833
|
+
font-size: 14px;
|
|
834
|
+
line-height: 1.5;
|
|
835
|
+
min-height: 100vh;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
/* Body becomes a flex column so main can grow + header/footer stay sticky
|
|
839
|
+
at the natural top/bottom of the viewport. */
|
|
840
|
+
body {
|
|
841
|
+
display: flex;
|
|
842
|
+
flex-direction: column;
|
|
843
|
+
min-height: 100vh;
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
main {
|
|
847
|
+
flex: 1;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
/* Layered backdrop: dot grid + soft pink glow at the top.
|
|
851
|
+
Both are fixed so they don't repeat as you scroll. */
|
|
852
|
+
body {
|
|
853
|
+
background-image:
|
|
854
|
+
radial-gradient(ellipse 70% 40% at 50% 0%, var(--bg-glow-color), transparent 70%),
|
|
855
|
+
radial-gradient(circle at 1px 1px, var(--bg-dot-color) 1px, transparent 0);
|
|
856
|
+
background-size: 100% 100%, 22px 22px;
|
|
857
|
+
background-attachment: fixed;
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
code, .num, table, .project-path {
|
|
861
|
+
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
header {
|
|
865
|
+
display: flex;
|
|
866
|
+
align-items: center;
|
|
867
|
+
gap: 1.5rem;
|
|
868
|
+
padding: 1.1rem 2rem;
|
|
869
|
+
background: linear-gradient(180deg, rgba(20, 0, 9, 0.7), rgba(20, 0, 9, 0.4));
|
|
870
|
+
backdrop-filter: blur(8px);
|
|
871
|
+
border-bottom: 1px solid var(--color-border);
|
|
872
|
+
position: sticky;
|
|
873
|
+
top: 0;
|
|
874
|
+
z-index: 5;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
header .brand {
|
|
878
|
+
display: flex;
|
|
879
|
+
align-items: baseline;
|
|
880
|
+
gap: 0.75rem;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
header h1 {
|
|
884
|
+
color: var(--color-heading);
|
|
885
|
+
font-size: 1.35rem;
|
|
886
|
+
font-weight: 700;
|
|
887
|
+
letter-spacing: 0.02em;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
header .tag {
|
|
891
|
+
color: var(--color-muted);
|
|
892
|
+
font-size: 0.78rem;
|
|
893
|
+
text-transform: uppercase;
|
|
894
|
+
letter-spacing: 0.1em;
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
header .meta {
|
|
898
|
+
margin-left: auto;
|
|
899
|
+
display: flex;
|
|
900
|
+
align-items: center;
|
|
901
|
+
gap: 0.75rem;
|
|
902
|
+
font-size: 0.78rem;
|
|
903
|
+
font-family: ui-monospace, monospace;
|
|
904
|
+
color: var(--color-muted);
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
header .active-project {
|
|
908
|
+
max-width: 480px;
|
|
909
|
+
white-space: nowrap;
|
|
910
|
+
overflow: hidden;
|
|
911
|
+
text-overflow: ellipsis;
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
main {
|
|
915
|
+
padding: 2rem;
|
|
916
|
+
display: flex;
|
|
917
|
+
flex-direction: column;
|
|
918
|
+
gap: 2rem;
|
|
919
|
+
max-width: 1400px;
|
|
920
|
+
margin: 0 auto;
|
|
921
|
+
width: 100%;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
section {
|
|
925
|
+
display: flex;
|
|
926
|
+
flex-direction: column;
|
|
927
|
+
gap: 0.85rem;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
h2 {
|
|
931
|
+
color: var(--color-heading);
|
|
932
|
+
font-size: 0.85rem;
|
|
933
|
+
font-weight: 600;
|
|
934
|
+
letter-spacing: 0.08em;
|
|
935
|
+
text-transform: uppercase;
|
|
936
|
+
display: flex;
|
|
937
|
+
align-items: center;
|
|
938
|
+
gap: 0.5rem;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
h2 svg {
|
|
942
|
+
width: 14px;
|
|
943
|
+
height: 14px;
|
|
944
|
+
opacity: 0.5;
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
h2 .muted {
|
|
948
|
+
color: var(--color-very-muted);
|
|
949
|
+
font-size: 0.78rem;
|
|
950
|
+
font-weight: 400;
|
|
951
|
+
letter-spacing: 0.06em;
|
|
952
|
+
text-transform: none;
|
|
953
|
+
margin-left: 0.5rem;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
/* ============================================================
|
|
957
|
+
Cards row (Global totals)
|
|
958
|
+
============================================================ */
|
|
959
|
+
|
|
960
|
+
.cards {
|
|
961
|
+
display: grid;
|
|
962
|
+
grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
|
|
963
|
+
gap: 0.7rem;
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
.card {
|
|
967
|
+
position: relative;
|
|
968
|
+
background: var(--color-surface);
|
|
969
|
+
border: 1px solid var(--color-border);
|
|
970
|
+
border-radius: 8px;
|
|
971
|
+
padding: 0.95rem 1rem 0.85rem;
|
|
972
|
+
transition: transform 120ms ease, border-color 120ms ease;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
.card:hover {
|
|
976
|
+
transform: translateY(-1px);
|
|
977
|
+
border-color: rgba(77, 0, 32, 0.85);
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
.card.accent {
|
|
981
|
+
background: var(--color-surface-raised);
|
|
982
|
+
border-color: var(--color-accent);
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
.card.money {
|
|
986
|
+
background: linear-gradient(180deg, var(--color-money-bg), transparent 80%), var(--color-surface);
|
|
987
|
+
border-color: var(--color-money-darker);
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
.card.money:hover {
|
|
991
|
+
border-color: var(--color-money);
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
.card-head {
|
|
995
|
+
display: flex;
|
|
996
|
+
align-items: center;
|
|
997
|
+
justify-content: space-between;
|
|
998
|
+
gap: 0.5rem;
|
|
999
|
+
margin-bottom: 0.4rem;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
.card-label {
|
|
1003
|
+
color: var(--color-muted);
|
|
1004
|
+
font-size: 0.66rem;
|
|
1005
|
+
text-transform: uppercase;
|
|
1006
|
+
letter-spacing: 0.09em;
|
|
1007
|
+
display: flex;
|
|
1008
|
+
align-items: center;
|
|
1009
|
+
gap: 0.35rem;
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
.card-icon {
|
|
1013
|
+
width: 14px;
|
|
1014
|
+
height: 14px;
|
|
1015
|
+
color: var(--color-muted);
|
|
1016
|
+
opacity: 0.65;
|
|
1017
|
+
flex-shrink: 0;
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
.card.accent .card-icon { color: var(--color-accent); opacity: 0.85; }
|
|
1021
|
+
.card.money .card-icon { color: var(--color-money); opacity: 0.85; }
|
|
1022
|
+
|
|
1023
|
+
.card-value {
|
|
1024
|
+
color: var(--color-heading);
|
|
1025
|
+
font-family: ui-monospace, monospace;
|
|
1026
|
+
font-size: 1.5rem;
|
|
1027
|
+
font-weight: 600;
|
|
1028
|
+
letter-spacing: -0.01em;
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
.card.accent .card-value { color: var(--color-accent); }
|
|
1032
|
+
.card.money .card-value { color: var(--color-money); }
|
|
1033
|
+
|
|
1034
|
+
/* ============================================================
|
|
1035
|
+
Tooltip (data-tooltip on .has-tooltip)
|
|
1036
|
+
============================================================ */
|
|
1037
|
+
|
|
1038
|
+
.has-tooltip {
|
|
1039
|
+
position: relative;
|
|
1040
|
+
cursor: help;
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
.has-tooltip::before,
|
|
1044
|
+
.has-tooltip::after {
|
|
1045
|
+
position: absolute;
|
|
1046
|
+
pointer-events: none;
|
|
1047
|
+
opacity: 0;
|
|
1048
|
+
transition: opacity 150ms ease, transform 150ms ease;
|
|
1049
|
+
z-index: 100;
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
.has-tooltip::after {
|
|
1053
|
+
content: attr(data-tooltip);
|
|
1054
|
+
bottom: calc(100% + 10px);
|
|
1055
|
+
left: 50%;
|
|
1056
|
+
transform: translate(-50%, 4px);
|
|
1057
|
+
background: var(--color-surface-raised);
|
|
1058
|
+
color: var(--color-body);
|
|
1059
|
+
border: 1px solid var(--color-border);
|
|
1060
|
+
border-radius: 6px;
|
|
1061
|
+
padding: 0.6rem 0.75rem;
|
|
1062
|
+
font-size: 0.74rem;
|
|
1063
|
+
font-weight: 400;
|
|
1064
|
+
text-transform: none;
|
|
1065
|
+
letter-spacing: 0;
|
|
1066
|
+
white-space: normal;
|
|
1067
|
+
width: 260px;
|
|
1068
|
+
text-align: left;
|
|
1069
|
+
line-height: 1.45;
|
|
1070
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.7);
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
.has-tooltip::before {
|
|
1074
|
+
content: "";
|
|
1075
|
+
bottom: calc(100% + 4px);
|
|
1076
|
+
left: 50%;
|
|
1077
|
+
transform: translate(-50%, 4px);
|
|
1078
|
+
border: 6px solid transparent;
|
|
1079
|
+
border-top-color: var(--color-border);
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
.has-tooltip:hover::after,
|
|
1083
|
+
.has-tooltip:hover::before {
|
|
1084
|
+
opacity: 1;
|
|
1085
|
+
transform: translate(-50%, 0);
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
/* Small \u24D8 icon used to indicate tooltips */
|
|
1089
|
+
.help-icon {
|
|
1090
|
+
display: inline-flex;
|
|
1091
|
+
align-items: center;
|
|
1092
|
+
justify-content: center;
|
|
1093
|
+
width: 13px;
|
|
1094
|
+
height: 13px;
|
|
1095
|
+
border-radius: 50%;
|
|
1096
|
+
border: 1px solid var(--color-muted);
|
|
1097
|
+
color: var(--color-muted);
|
|
1098
|
+
font-size: 9px;
|
|
1099
|
+
font-weight: 600;
|
|
1100
|
+
font-family: ui-sans-serif, sans-serif;
|
|
1101
|
+
line-height: 1;
|
|
1102
|
+
cursor: help;
|
|
1103
|
+
user-select: none;
|
|
1104
|
+
transition: color 120ms, border-color 120ms;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
.has-tooltip:hover .help-icon {
|
|
1108
|
+
border-color: var(--color-accent);
|
|
1109
|
+
color: var(--color-accent);
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
.card.money .has-tooltip:hover .help-icon { border-color: var(--color-money); color: var(--color-money); }
|
|
1113
|
+
|
|
1114
|
+
/* ============================================================
|
|
1115
|
+
Projects list
|
|
1116
|
+
============================================================ */
|
|
1117
|
+
|
|
1118
|
+
.projects {
|
|
1119
|
+
display: flex;
|
|
1120
|
+
flex-direction: column;
|
|
1121
|
+
gap: 0.6rem;
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
.project-row {
|
|
1125
|
+
display: grid;
|
|
1126
|
+
grid-template-columns: minmax(220px, 1fr) auto;
|
|
1127
|
+
grid-template-rows: auto auto;
|
|
1128
|
+
gap: 0.6rem 1.25rem;
|
|
1129
|
+
align-items: center;
|
|
1130
|
+
background: var(--color-surface);
|
|
1131
|
+
border: 1px solid var(--color-border);
|
|
1132
|
+
border-radius: 8px;
|
|
1133
|
+
padding: 0.9rem 1.2rem;
|
|
1134
|
+
transition: background 120ms ease;
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
.project-row:hover {
|
|
1138
|
+
background: var(--color-surface-raised);
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
.project-name {
|
|
1142
|
+
display: flex;
|
|
1143
|
+
flex-direction: column;
|
|
1144
|
+
gap: 0.15rem;
|
|
1145
|
+
overflow: hidden;
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
.project-name strong {
|
|
1149
|
+
color: var(--color-heading);
|
|
1150
|
+
font-size: 0.95rem;
|
|
1151
|
+
font-weight: 600;
|
|
1152
|
+
display: flex;
|
|
1153
|
+
align-items: center;
|
|
1154
|
+
gap: 0.4rem;
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
.project-name strong svg {
|
|
1158
|
+
width: 13px;
|
|
1159
|
+
height: 13px;
|
|
1160
|
+
opacity: 0.65;
|
|
1161
|
+
color: var(--color-muted);
|
|
1162
|
+
flex-shrink: 0;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
.project-name .project-path {
|
|
1166
|
+
color: var(--color-very-muted);
|
|
1167
|
+
font-size: 0.72rem;
|
|
1168
|
+
white-space: nowrap;
|
|
1169
|
+
overflow: hidden;
|
|
1170
|
+
text-overflow: ellipsis;
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
.project-stats {
|
|
1174
|
+
display: flex;
|
|
1175
|
+
gap: 1.6rem;
|
|
1176
|
+
justify-self: end;
|
|
1177
|
+
text-align: right;
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
.stat {
|
|
1181
|
+
display: flex;
|
|
1182
|
+
flex-direction: column;
|
|
1183
|
+
gap: 0.15rem;
|
|
1184
|
+
min-width: 70px;
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
.stat-value {
|
|
1188
|
+
color: var(--color-heading);
|
|
1189
|
+
font-family: ui-monospace, monospace;
|
|
1190
|
+
font-size: 0.95rem;
|
|
1191
|
+
font-weight: 600;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
.stat-value.cost {
|
|
1195
|
+
color: var(--color-money);
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
.stat-label {
|
|
1199
|
+
color: var(--color-muted);
|
|
1200
|
+
font-size: 0.66rem;
|
|
1201
|
+
text-transform: uppercase;
|
|
1202
|
+
letter-spacing: 0.08em;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
.bar {
|
|
1206
|
+
grid-column: 1 / -1;
|
|
1207
|
+
height: 3px;
|
|
1208
|
+
background: var(--color-form-bg);
|
|
1209
|
+
border-radius: 2px;
|
|
1210
|
+
overflow: hidden;
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1213
|
+
.bar-fill {
|
|
1214
|
+
height: 100%;
|
|
1215
|
+
background: linear-gradient(90deg, var(--color-accent-darker), var(--color-accent));
|
|
1216
|
+
border-radius: 2px;
|
|
1217
|
+
transition: width 400ms ease;
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
/* ============================================================
|
|
1221
|
+
Tables
|
|
1222
|
+
============================================================ */
|
|
1223
|
+
|
|
1224
|
+
table {
|
|
1225
|
+
width: 100%;
|
|
1226
|
+
border-collapse: collapse;
|
|
1227
|
+
font-size: 0.83rem;
|
|
1228
|
+
background: var(--color-surface);
|
|
1229
|
+
border: 1px solid var(--color-border);
|
|
1230
|
+
border-radius: 8px;
|
|
1231
|
+
overflow: hidden;
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
table thead th {
|
|
1235
|
+
text-align: left;
|
|
1236
|
+
color: var(--color-muted);
|
|
1237
|
+
text-transform: uppercase;
|
|
1238
|
+
font-size: 0.66rem;
|
|
1239
|
+
letter-spacing: 0.08em;
|
|
1240
|
+
font-weight: 600;
|
|
1241
|
+
padding: 0.65rem 0.85rem;
|
|
1242
|
+
border-bottom: 1px solid var(--color-border);
|
|
1243
|
+
background: var(--color-surface);
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
table thead th.num {
|
|
1247
|
+
text-align: right;
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
table thead th .has-tooltip {
|
|
1251
|
+
display: inline-flex;
|
|
1252
|
+
align-items: center;
|
|
1253
|
+
gap: 0.3rem;
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
table tbody td {
|
|
1257
|
+
padding: 0.55rem 0.85rem;
|
|
1258
|
+
border-bottom: 1px solid rgba(77, 0, 32, 0.4);
|
|
1259
|
+
color: var(--color-body);
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
table tbody td.num {
|
|
1263
|
+
text-align: right;
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
table tbody td.cost {
|
|
1267
|
+
color: var(--color-money);
|
|
1268
|
+
font-weight: 600;
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
table tbody tr:last-child td {
|
|
1272
|
+
border-bottom: none;
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
table tbody tr:hover {
|
|
1276
|
+
background: var(--color-surface-raised);
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
/* ============================================================
|
|
1280
|
+
Model pills \u2014 color-coded by family
|
|
1281
|
+
============================================================ */
|
|
1282
|
+
|
|
1283
|
+
.model-pill {
|
|
1284
|
+
display: inline-block;
|
|
1285
|
+
padding: 0.1rem 0.5rem;
|
|
1286
|
+
border-radius: 3px;
|
|
1287
|
+
background: var(--color-form-bg);
|
|
1288
|
+
font-family: ui-monospace, monospace;
|
|
1289
|
+
font-size: 0.82em;
|
|
1290
|
+
border: 1px solid transparent;
|
|
1291
|
+
color: var(--color-body);
|
|
1292
|
+
white-space: nowrap;
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
.model-pill.opus {
|
|
1296
|
+
color: var(--color-model-opus);
|
|
1297
|
+
border-color: rgba(201, 162, 255, 0.3);
|
|
1298
|
+
background: rgba(201, 162, 255, 0.08);
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
.model-pill.sonnet {
|
|
1302
|
+
color: var(--color-model-sonnet);
|
|
1303
|
+
border-color: rgba(107, 208, 255, 0.3);
|
|
1304
|
+
background: rgba(107, 208, 255, 0.08);
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
.model-pill.haiku {
|
|
1308
|
+
color: var(--color-model-haiku);
|
|
1309
|
+
border-color: rgba(123, 255, 199, 0.3);
|
|
1310
|
+
background: rgba(123, 255, 199, 0.08);
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
.model-pill.unknown {
|
|
1314
|
+
color: var(--color-muted);
|
|
1315
|
+
font-style: italic;
|
|
1316
|
+
border-color: rgba(237, 236, 217, 0.15);
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
/* Existing inline code in tables (project name, etc.) */
|
|
1320
|
+
code {
|
|
1321
|
+
color: var(--color-heading);
|
|
1322
|
+
background: var(--color-form-bg);
|
|
1323
|
+
padding: 0.1rem 0.4rem;
|
|
1324
|
+
border-radius: 3px;
|
|
1325
|
+
font-size: 0.85em;
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
/* ============================================================
|
|
1329
|
+
Decisions (allow / block)
|
|
1330
|
+
============================================================ */
|
|
1331
|
+
|
|
1332
|
+
.decision-block {
|
|
1333
|
+
color: var(--color-block);
|
|
1334
|
+
font-weight: 700;
|
|
1335
|
+
text-transform: uppercase;
|
|
1336
|
+
font-size: 0.72rem;
|
|
1337
|
+
letter-spacing: 0.06em;
|
|
1338
|
+
display: inline-flex;
|
|
1339
|
+
align-items: center;
|
|
1340
|
+
gap: 0.3rem;
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
.decision-block svg {
|
|
1344
|
+
width: 11px;
|
|
1345
|
+
height: 11px;
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
.decision-allow {
|
|
1349
|
+
color: var(--color-allow);
|
|
1350
|
+
opacity: 0.7;
|
|
1351
|
+
text-transform: uppercase;
|
|
1352
|
+
font-size: 0.72rem;
|
|
1353
|
+
letter-spacing: 0.06em;
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
.empty {
|
|
1357
|
+
color: var(--color-muted);
|
|
1358
|
+
font-style: italic;
|
|
1359
|
+
padding: 1rem;
|
|
1360
|
+
background: var(--color-surface);
|
|
1361
|
+
border: 1px dashed var(--color-border);
|
|
1362
|
+
border-radius: 8px;
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
.hidden {
|
|
1366
|
+
display: none;
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
footer {
|
|
1370
|
+
display: flex;
|
|
1371
|
+
justify-content: space-between;
|
|
1372
|
+
align-items: center;
|
|
1373
|
+
padding: 0.85rem 2rem;
|
|
1374
|
+
background: linear-gradient(0deg, rgba(20, 0, 9, 0.7), rgba(20, 0, 9, 0.4));
|
|
1375
|
+
backdrop-filter: blur(8px);
|
|
1376
|
+
border-top: 1px solid var(--color-border);
|
|
1377
|
+
color: var(--color-muted);
|
|
1378
|
+
font-size: 0.72rem;
|
|
1379
|
+
font-family: ui-monospace, monospace;
|
|
1380
|
+
position: sticky;
|
|
1381
|
+
bottom: 0;
|
|
1382
|
+
z-index: 5;
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
footer .muted {
|
|
1386
|
+
color: var(--color-very-muted);
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
.dot {
|
|
1390
|
+
width: 8px;
|
|
1391
|
+
height: 8px;
|
|
1392
|
+
border-radius: 50%;
|
|
1393
|
+
background: var(--color-muted);
|
|
1394
|
+
transition: background 200ms ease, box-shadow 200ms ease;
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
.dot.live {
|
|
1398
|
+
background: var(--color-money);
|
|
1399
|
+
box-shadow: 0 0 8px var(--color-money-darker);
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
.dot.dead {
|
|
1403
|
+
background: var(--color-border);
|
|
1404
|
+
box-shadow: none;
|
|
1405
|
+
}
|
|
1406
|
+
`;
|
|
678
1407
|
|
|
679
1408
|
// src/dashboard/server.ts
|
|
680
1409
|
var FALLBACK_RANGE = 9;
|
|
@@ -4170,7 +4899,7 @@ async function spawnClaude(bin, opts) {
|
|
|
4170
4899
|
}
|
|
4171
4900
|
|
|
4172
4901
|
// src/cli/index.ts
|
|
4173
|
-
var VERSION =
|
|
4902
|
+
var VERSION = package_default.version;
|
|
4174
4903
|
function printReadyBanner(info) {
|
|
4175
4904
|
log.info("");
|
|
4176
4905
|
log.info(` \u2705 scanned ${info.scan.parsed} files \xB7 ${info.scan.symbolCount} symbols \xB7 ${info.scan.edgeCount} edges`);
|