loki-mode 9.17.0 → 9.18.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/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/issue-providers.sh +0 -24
- package/autonomy/lib/agent_readiness.py +1 -79
- package/autonomy/lib/outcome_ledger.py +0 -122
- package/autonomy/lib/proof-generator.py +4 -71
- package/autonomy/lib/verdict.py +4 -25
- package/autonomy/loki +444 -264
- package/autonomy/notify.sh +1 -70
- package/autonomy/queue-consumer.sh +18 -290
- package/autonomy/run.sh +280 -189
- package/autonomy/trigger-server.py +518 -17
- package/autonomy/verify.sh +100 -12
- package/bin/loki +7 -1
- package/completions/_loki +0 -3
- package/completions/loki.bash +2 -2
- package/dashboard/__init__.py +1 -1
- package/dashboard/server.py +1 -168
- package/dashboard/static/index.html +222 -249
- package/docs/COMPETITIVE-SCORECARD.md +38 -0
- package/docs/COMPETITOR-DEPLOYMENT-MODELS.md +475 -0
- package/docs/DEPLOYMENT.md +542 -0
- package/docs/STALE-STATE-AUDIT.md +174 -0
- package/docs/VERIFICATION-COST.md +46 -166
- package/loki-ts/dist/loki.js +311 -305
- package/mcp/__init__.py +1 -1
- package/mcp/_sdk_loader.py +0 -25
- package/package.json +1 -1
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/autonomy/lib/gate_policy.py +0 -166
- package/docs/QUEUE-OPERATIONS.md +0 -107
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<title>Loki Mode Dashboard</title>
|
|
9
9
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
10
10
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
11
|
-
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
|
11
|
+
<link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,500;9..144,600&family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
|
12
12
|
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' width='32' height='32'><rect width='512' height='512' rx='118' fill='%23553DE9'/><path d='M152 405 L242 120' fill='none' stroke='%23FFFEFB' stroke-width='28' stroke-linecap='round'/><path d='M360 405 L270 120' fill='none' stroke='%23FFFEFB' stroke-width='28' stroke-linecap='round'/><path d='M242 120 Q256 86 270 120' fill='none' stroke='%23FFFEFB' stroke-width='28' stroke-linecap='round'/><circle cx='256' cy='295' r='20' fill='%231FC5A8'/></svg>">
|
|
13
13
|
<style>
|
|
14
14
|
/* Autonomi Design Language. Light-grey ground is the default (founder-
|
|
@@ -36,52 +36,6 @@
|
|
|
36
36
|
--loki-glass-bg: rgba(255, 255, 255, 0.7);
|
|
37
37
|
--loki-glass-border: rgba(255, 255, 255, 0.4);
|
|
38
38
|
--loki-glass-shadow: 0 4px 24px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04);
|
|
39
|
-
|
|
40
|
-
/* Aliases for tokens components consume but no theme defined.
|
|
41
|
-
33 var(--loki-*) names were referenced with a hardcoded fallback and
|
|
42
|
-
never declared, so they resolved to their LIGHT-mode literal in every
|
|
43
|
-
theme -- e.g. loki-checklist-viewer.js used --loki-status-success and
|
|
44
|
-
rendered #22c55e on a dark background while --loki-success was #2ED8B6.
|
|
45
|
-
Each alias points at a token this theme already defines, so it tracks
|
|
46
|
-
the theme instead of freezing one palette. */
|
|
47
|
-
--loki-accent-active: var(--loki-accent-hover);
|
|
48
|
-
--loki-info-muted: color-mix(in srgb, var(--loki-info, #2F71E3) 15%, transparent);
|
|
49
|
-
--loki-text: var(--loki-text-primary);
|
|
50
|
-
--loki-status-success: var(--loki-success);
|
|
51
|
-
--loki-status-warning: var(--loki-warning);
|
|
52
|
-
--loki-status-error: var(--loki-error);
|
|
53
|
-
--loki-success-muted: color-mix(in srgb, var(--loki-success) 15%, transparent);
|
|
54
|
-
--loki-warning-muted: color-mix(in srgb, var(--loki-warning) 15%, transparent);
|
|
55
|
-
--loki-error-muted: color-mix(in srgb, var(--loki-error) 15%, transparent);
|
|
56
|
-
--loki-red-muted: color-mix(in srgb, var(--loki-error) 15%, transparent);
|
|
57
|
-
--loki-green-muted: color-mix(in srgb, var(--loki-success) 15%, transparent);
|
|
58
|
-
--loki-yellow-muted: color-mix(in srgb, var(--loki-warning) 15%, transparent);
|
|
59
|
-
--loki-blue-muted: color-mix(in srgb, var(--loki-info, #2F71E3) 15%, transparent);
|
|
60
|
-
--loki-purple-muted: color-mix(in srgb, var(--loki-accent) 15%, transparent);
|
|
61
|
-
--loki-accent-muted: color-mix(in srgb, var(--loki-accent) 15%, transparent);
|
|
62
|
-
--loki-accent-light: var(--loki-accent-hover);
|
|
63
|
-
--loki-red: var(--loki-error);
|
|
64
|
-
--loki-red-bg: color-mix(in srgb, var(--loki-error) 12%, transparent);
|
|
65
|
-
--loki-green: var(--loki-success);
|
|
66
|
-
--loki-yellow: var(--loki-warning);
|
|
67
|
-
--loki-amber: var(--loki-warning);
|
|
68
|
-
--loki-blue: var(--loki-info, #2F71E3);
|
|
69
|
-
--loki-purple: var(--loki-accent);
|
|
70
|
-
--loki-bg-subtle: var(--loki-bg-secondary);
|
|
71
|
-
--loki-bg-overlay: var(--loki-bg-card);
|
|
72
|
-
--loki-bg-code: var(--loki-bg-tertiary);
|
|
73
|
-
--loki-code-bg: var(--loki-bg-tertiary);
|
|
74
|
-
--loki-text-inverse: var(--loki-bg-primary);
|
|
75
|
-
--loki-border-focus: var(--loki-accent);
|
|
76
|
-
--loki-shadow-focus: 0 0 0 3px var(--loki-accent-glow);
|
|
77
|
-
--loki-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06);
|
|
78
|
-
--loki-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.10);
|
|
79
|
-
--loki-font-family: var(--loki-font-sans, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif);
|
|
80
|
-
/* Model tiers keep a fixed hue so a tier is recognisable across themes. */
|
|
81
|
-
--loki-opus: var(--loki-accent);
|
|
82
|
-
--loki-sonnet: var(--loki-info, #2F71E3);
|
|
83
|
-
--loki-haiku: var(--loki-success);
|
|
84
|
-
|
|
85
39
|
--loki-transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
86
40
|
}
|
|
87
41
|
|
|
@@ -106,52 +60,6 @@
|
|
|
106
60
|
--loki-glass-bg: rgba(255, 255, 255, 0.7);
|
|
107
61
|
--loki-glass-border: rgba(255, 255, 255, 0.4);
|
|
108
62
|
--loki-glass-shadow: 0 4px 24px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04);
|
|
109
|
-
|
|
110
|
-
/* Aliases for tokens components consume but no theme defined.
|
|
111
|
-
33 var(--loki-*) names were referenced with a hardcoded fallback and
|
|
112
|
-
never declared, so they resolved to their LIGHT-mode literal in every
|
|
113
|
-
theme -- e.g. loki-checklist-viewer.js used --loki-status-success and
|
|
114
|
-
rendered #22c55e on a dark background while --loki-success was #2ED8B6.
|
|
115
|
-
Each alias points at a token this theme already defines, so it tracks
|
|
116
|
-
the theme instead of freezing one palette. */
|
|
117
|
-
--loki-accent-active: var(--loki-accent-hover);
|
|
118
|
-
--loki-info-muted: color-mix(in srgb, var(--loki-info, #2F71E3) 15%, transparent);
|
|
119
|
-
--loki-text: var(--loki-text-primary);
|
|
120
|
-
--loki-status-success: var(--loki-success);
|
|
121
|
-
--loki-status-warning: var(--loki-warning);
|
|
122
|
-
--loki-status-error: var(--loki-error);
|
|
123
|
-
--loki-success-muted: color-mix(in srgb, var(--loki-success) 15%, transparent);
|
|
124
|
-
--loki-warning-muted: color-mix(in srgb, var(--loki-warning) 15%, transparent);
|
|
125
|
-
--loki-error-muted: color-mix(in srgb, var(--loki-error) 15%, transparent);
|
|
126
|
-
--loki-red-muted: color-mix(in srgb, var(--loki-error) 15%, transparent);
|
|
127
|
-
--loki-green-muted: color-mix(in srgb, var(--loki-success) 15%, transparent);
|
|
128
|
-
--loki-yellow-muted: color-mix(in srgb, var(--loki-warning) 15%, transparent);
|
|
129
|
-
--loki-blue-muted: color-mix(in srgb, var(--loki-info, #2F71E3) 15%, transparent);
|
|
130
|
-
--loki-purple-muted: color-mix(in srgb, var(--loki-accent) 15%, transparent);
|
|
131
|
-
--loki-accent-muted: color-mix(in srgb, var(--loki-accent) 15%, transparent);
|
|
132
|
-
--loki-accent-light: var(--loki-accent-hover);
|
|
133
|
-
--loki-red: var(--loki-error);
|
|
134
|
-
--loki-red-bg: color-mix(in srgb, var(--loki-error) 12%, transparent);
|
|
135
|
-
--loki-green: var(--loki-success);
|
|
136
|
-
--loki-yellow: var(--loki-warning);
|
|
137
|
-
--loki-amber: var(--loki-warning);
|
|
138
|
-
--loki-blue: var(--loki-info, #2F71E3);
|
|
139
|
-
--loki-purple: var(--loki-accent);
|
|
140
|
-
--loki-bg-subtle: var(--loki-bg-secondary);
|
|
141
|
-
--loki-bg-overlay: var(--loki-bg-card);
|
|
142
|
-
--loki-bg-code: var(--loki-bg-tertiary);
|
|
143
|
-
--loki-code-bg: var(--loki-bg-tertiary);
|
|
144
|
-
--loki-text-inverse: var(--loki-bg-primary);
|
|
145
|
-
--loki-border-focus: var(--loki-accent);
|
|
146
|
-
--loki-shadow-focus: 0 0 0 3px var(--loki-accent-glow);
|
|
147
|
-
--loki-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06);
|
|
148
|
-
--loki-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.10);
|
|
149
|
-
--loki-font-family: var(--loki-font-sans, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif);
|
|
150
|
-
/* Model tiers keep a fixed hue so a tier is recognisable across themes. */
|
|
151
|
-
--loki-opus: var(--loki-accent);
|
|
152
|
-
--loki-sonnet: var(--loki-info, #2F71E3);
|
|
153
|
-
--loki-haiku: var(--loki-success);
|
|
154
|
-
|
|
155
63
|
}
|
|
156
64
|
|
|
157
65
|
[data-loki-theme="dark"] {
|
|
@@ -175,52 +83,6 @@
|
|
|
175
83
|
--loki-glass-bg: rgba(23, 22, 28, 0.7);
|
|
176
84
|
--loki-glass-border: rgba(255, 255, 255, 0.08);
|
|
177
85
|
--loki-glass-shadow: 0 4px 24px rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.12);
|
|
178
|
-
|
|
179
|
-
/* Aliases for tokens components consume but no theme defined.
|
|
180
|
-
33 var(--loki-*) names were referenced with a hardcoded fallback and
|
|
181
|
-
never declared, so they resolved to their LIGHT-mode literal in every
|
|
182
|
-
theme -- e.g. loki-checklist-viewer.js used --loki-status-success and
|
|
183
|
-
rendered #22c55e on a dark background while --loki-success was #2ED8B6.
|
|
184
|
-
Each alias points at a token this theme already defines, so it tracks
|
|
185
|
-
the theme instead of freezing one palette. */
|
|
186
|
-
--loki-accent-active: var(--loki-accent-hover);
|
|
187
|
-
--loki-info-muted: color-mix(in srgb, var(--loki-info, #2F71E3) 15%, transparent);
|
|
188
|
-
--loki-text: var(--loki-text-primary);
|
|
189
|
-
--loki-status-success: var(--loki-success);
|
|
190
|
-
--loki-status-warning: var(--loki-warning);
|
|
191
|
-
--loki-status-error: var(--loki-error);
|
|
192
|
-
--loki-success-muted: color-mix(in srgb, var(--loki-success) 15%, transparent);
|
|
193
|
-
--loki-warning-muted: color-mix(in srgb, var(--loki-warning) 15%, transparent);
|
|
194
|
-
--loki-error-muted: color-mix(in srgb, var(--loki-error) 15%, transparent);
|
|
195
|
-
--loki-red-muted: color-mix(in srgb, var(--loki-error) 15%, transparent);
|
|
196
|
-
--loki-green-muted: color-mix(in srgb, var(--loki-success) 15%, transparent);
|
|
197
|
-
--loki-yellow-muted: color-mix(in srgb, var(--loki-warning) 15%, transparent);
|
|
198
|
-
--loki-blue-muted: color-mix(in srgb, var(--loki-info, #2F71E3) 15%, transparent);
|
|
199
|
-
--loki-purple-muted: color-mix(in srgb, var(--loki-accent) 15%, transparent);
|
|
200
|
-
--loki-accent-muted: color-mix(in srgb, var(--loki-accent) 15%, transparent);
|
|
201
|
-
--loki-accent-light: var(--loki-accent-hover);
|
|
202
|
-
--loki-red: var(--loki-error);
|
|
203
|
-
--loki-red-bg: color-mix(in srgb, var(--loki-error) 12%, transparent);
|
|
204
|
-
--loki-green: var(--loki-success);
|
|
205
|
-
--loki-yellow: var(--loki-warning);
|
|
206
|
-
--loki-amber: var(--loki-warning);
|
|
207
|
-
--loki-blue: var(--loki-info, #2F71E3);
|
|
208
|
-
--loki-purple: var(--loki-accent);
|
|
209
|
-
--loki-bg-subtle: var(--loki-bg-secondary);
|
|
210
|
-
--loki-bg-overlay: var(--loki-bg-card);
|
|
211
|
-
--loki-bg-code: var(--loki-bg-tertiary);
|
|
212
|
-
--loki-code-bg: var(--loki-bg-tertiary);
|
|
213
|
-
--loki-text-inverse: var(--loki-bg-primary);
|
|
214
|
-
--loki-border-focus: var(--loki-accent);
|
|
215
|
-
--loki-shadow-focus: 0 0 0 3px var(--loki-accent-glow);
|
|
216
|
-
--loki-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06);
|
|
217
|
-
--loki-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.10);
|
|
218
|
-
--loki-font-family: var(--loki-font-sans, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif);
|
|
219
|
-
/* Model tiers keep a fixed hue so a tier is recognisable across themes. */
|
|
220
|
-
--loki-opus: var(--loki-accent);
|
|
221
|
-
--loki-sonnet: var(--loki-info, #2F71E3);
|
|
222
|
-
--loki-haiku: var(--loki-success);
|
|
223
|
-
|
|
224
86
|
}
|
|
225
87
|
|
|
226
88
|
* {
|
|
@@ -349,7 +211,7 @@
|
|
|
349
211
|
}
|
|
350
212
|
|
|
351
213
|
.logo-brand {
|
|
352
|
-
font-family:
|
|
214
|
+
font-family: 'Fraunces', Georgia, serif;
|
|
353
215
|
font-size: 22px;
|
|
354
216
|
font-weight: 400;
|
|
355
217
|
color: var(--loki-text-primary);
|
|
@@ -986,7 +848,7 @@
|
|
|
986
848
|
}
|
|
987
849
|
|
|
988
850
|
.section-page-title {
|
|
989
|
-
font-family:
|
|
851
|
+
font-family: 'Fraunces', Georgia, serif;
|
|
990
852
|
font-size: 1.8rem;
|
|
991
853
|
font-weight: 400;
|
|
992
854
|
color: var(--loki-text-primary);
|
|
@@ -1029,7 +891,7 @@
|
|
|
1029
891
|
}
|
|
1030
892
|
.first-run-hero__icon svg { width: 22px; height: 22px; }
|
|
1031
893
|
.first-run-hero__title {
|
|
1032
|
-
font-family:
|
|
894
|
+
font-family: 'Fraunces', Georgia, serif;
|
|
1033
895
|
font-size: 1.5rem;
|
|
1034
896
|
font-weight: 400;
|
|
1035
897
|
color: var(--loki-text-primary);
|
|
@@ -1458,11 +1320,19 @@
|
|
|
1458
1320
|
</div>
|
|
1459
1321
|
<div style="display: grid; gap: 24px;">
|
|
1460
1322
|
<div>
|
|
1461
|
-
<h3 style="font-family:
|
|
1323
|
+
<h3 style="font-family: 'Fraunces', Georgia, serif; font-size: 1.15rem; font-weight: 400; color: var(--loki-text-primary); margin-bottom: 12px;">Logs</h3>
|
|
1462
1324
|
<loki-log-stream id="log-stream" auto-scroll max-lines="500"></loki-log-stream>
|
|
1463
1325
|
</div>
|
|
1326
|
+
<!-- LEARNINGS. /api/learnings held real records with a rootCause,
|
|
1327
|
+
a fix and a preventInFuture, and had no UI consumer -- the
|
|
1328
|
+
system was learning from its runs and never showing anyone
|
|
1329
|
+
what it learned. Hidden until data arrives. -->
|
|
1330
|
+
<div id="learnings-panel" style="display:none;">
|
|
1331
|
+
<h3 style="font-family: var(--loki-font-family, 'Inter', system-ui, -apple-system, sans-serif); font-size: 1.15rem; font-weight: 400; color: var(--loki-text-primary); margin-bottom: 12px;">What this build learned</h3>
|
|
1332
|
+
<div id="learnings-list"></div>
|
|
1333
|
+
</div>
|
|
1464
1334
|
<div>
|
|
1465
|
-
<h3 style="font-family:
|
|
1335
|
+
<h3 style="font-family: 'Fraunces', Georgia, serif; font-size: 1.15rem; font-weight: 400; color: var(--loki-text-primary); margin-bottom: 12px;">Memory</h3>
|
|
1466
1336
|
<loki-memory-browser id="memory-browser" tab="summary"></loki-memory-browser>
|
|
1467
1337
|
<!-- v7.7.21 token economics tile: hit rate + tokens + top patterns -->
|
|
1468
1338
|
<div id="memory-economics-tile" style="margin-top: 12px; background: var(--loki-bg-card, rgba(255,255,255,0.72)); border: 1px solid var(--loki-border, rgba(0,0,0,0.08)); border-radius: 5px; padding: 12px;">
|
|
@@ -1515,7 +1385,7 @@
|
|
|
1515
1385
|
</script>
|
|
1516
1386
|
</div>
|
|
1517
1387
|
<div>
|
|
1518
|
-
<h3 style="font-family:
|
|
1388
|
+
<h3 style="font-family: 'Fraunces', Georgia, serif; font-size: 1.15rem; font-weight: 400; color: var(--loki-text-primary); margin-bottom: 12px;">Memory Files</h3>
|
|
1519
1389
|
<div id="memory-files-panel" style="background: var(--loki-bg-card, rgba(255,255,255,0.72)); border: 1px solid var(--loki-border, rgba(0,0,0,0.08)); border-radius: 5px; padding: 12px;">
|
|
1520
1390
|
<div style="display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px;" id="memory-files-tabs"></div>
|
|
1521
1391
|
<div style="display: grid; grid-template-columns: minmax(220px, 320px) 1fr; gap: 12px; min-height: 280px;">
|
|
@@ -1595,12 +1465,12 @@
|
|
|
1595
1465
|
</script>
|
|
1596
1466
|
</div>
|
|
1597
1467
|
<div>
|
|
1598
|
-
<h3 style="font-family:
|
|
1468
|
+
<h3 style="font-family: 'Fraunces', Georgia, serif; font-size: 1.15rem; font-weight: 400; color: var(--loki-text-primary); margin-bottom: 12px;">Learning Metrics</h3>
|
|
1599
1469
|
<loki-learning-dashboard id="learning-dashboard" time-range="7d"></loki-learning-dashboard>
|
|
1600
1470
|
</div>
|
|
1601
1471
|
<!-- v7.7.1 F-1 follow-up: How to Run (USAGE.md) -->
|
|
1602
1472
|
<div>
|
|
1603
|
-
<h3 style="font-family:
|
|
1473
|
+
<h3 style="font-family: 'Fraunces', Georgia, serif; font-size: 1.15rem; font-weight: 400; color: var(--loki-text-primary); margin-bottom: 12px;">How to Run (USAGE.md)</h3>
|
|
1604
1474
|
<div id="usage-doc-panel" style="background: var(--loki-bg-card, rgba(255,255,255,0.72)); border: 1px solid var(--loki-border, rgba(0,0,0,0.08)); border-radius: 5px; padding: 12px;">
|
|
1605
1475
|
<div id="usage-doc-meta" style="font-size: 11px; color: var(--loki-text-muted, #888); margin-bottom: 8px;">Loading...</div>
|
|
1606
1476
|
<div id="usage-doc-content" class="usage-md"></div>
|
|
@@ -1813,6 +1683,13 @@
|
|
|
1813
1683
|
<div class="section-page-header">
|
|
1814
1684
|
<h2 class="section-page-title">Cost</h2>
|
|
1815
1685
|
</div>
|
|
1686
|
+
<!-- SPEND CAP. /api/budget reports budget_limit, and it ships NULL:
|
|
1687
|
+
there is no automatic spend stop. Nothing in the UI said so, and
|
|
1688
|
+
the only place that fact surfaced was a bill. Shown ALWAYS, not
|
|
1689
|
+
just when a cap exists, because "no cap" is the state a user most
|
|
1690
|
+
needs to know about. -->
|
|
1691
|
+
<div id="budget-banner" style="display:none;margin-bottom:12px;padding:10px 12px;
|
|
1692
|
+
border:1px solid var(--loki-border);border-radius:6px;font-size:12px;"></div>
|
|
1816
1693
|
<loki-cost-dashboard id="cost-dashboard"></loki-cost-dashboard>
|
|
1817
1694
|
</div>
|
|
1818
1695
|
|
|
@@ -1823,8 +1700,18 @@
|
|
|
1823
1700
|
<div class="section-page-header">
|
|
1824
1701
|
<h2 class="section-page-title">Trust Trajectory</h2>
|
|
1825
1702
|
</div>
|
|
1703
|
+
<!-- EVIDENCE RECEIPTS. /api/proofs served 9 receipts with verdict,
|
|
1704
|
+
file count and an HTML view, and NOTHING in the dashboard read it
|
|
1705
|
+
-- only /api/proofs/summary (the header badge) was consumed. The
|
|
1706
|
+
receipt is the thing we ask users to check; it was unreachable
|
|
1707
|
+
from the UI. -->
|
|
1708
|
+
<div id="receipts-panel" style="margin-bottom:16px;display:none;">
|
|
1709
|
+
<h3 style="font-size:13px;font-weight:600;margin:0 0 8px;">Evidence receipts</h3>
|
|
1710
|
+
<div id="receipts-list"></div>
|
|
1711
|
+
<div id="receipts-note" style="font-size:11px;color:var(--loki-text-muted);margin-top:8px;"></div>
|
|
1712
|
+
</div>
|
|
1826
1713
|
<iframe id="trust-frame" title="Trust trajectory" src="about:blank"
|
|
1827
|
-
style="width:100%;height:calc(100vh -
|
|
1714
|
+
style="width:100%;height:calc(100vh - 260px);border:0;border-radius:8px;background:var(--loki-bg-primary);"></iframe>
|
|
1828
1715
|
</div>
|
|
1829
1716
|
|
|
1830
1717
|
<!-- Checkpoints -->
|
|
@@ -1957,7 +1844,7 @@
|
|
|
1957
1844
|
|
|
1958
1845
|
<!-- Inlined JavaScript Bundle -->
|
|
1959
1846
|
<script>
|
|
1960
|
-
var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropertyDescriptor;var Dt=Object.getOwnPropertyNames;var Ht=Object.prototype.hasOwnProperty;var Mt=(d,e,t)=>e in d?Be(d,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):d[e]=t;var Rt=(d,e)=>{for(var t in e)Be(d,t,{get:e[t],enumerable:!0})},Pt=(d,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of Dt(e))!Ht.call(d,a)&&a!==t&&Be(d,a,{get:()=>e[a],enumerable:!(i=zt(e,a))||i.enumerable});return d};var Bt=d=>Pt(Be({},"__esModule",{value:!0}),d);var S=(d,e,t)=>Mt(d,typeof e!="symbol"?e+"":e,t);var fi={};Rt(fi,{ANIMATION:()=>P,ARIA_PATTERNS:()=>Ue,ApiEvents:()=>f,BASE_STYLES:()=>W,BREAKPOINTS:()=>Ie,COMMON_STYLES:()=>ot,KEYBOARD_SHORTCUTS:()=>je,KeyboardHandler:()=>O,LokiActivityStream:()=>$e,LokiAgentLeaderboard:()=>Le,LokiAnalytics:()=>ve,LokiApiClient:()=>J,LokiApiKeys:()=>ye,LokiAppPreview:()=>ne,LokiAppStatus:()=>oe,LokiAuditViewer:()=>_e,LokiChecklistViewer:()=>re,LokiCheckpointViewer:()=>de,LokiContextTracker:()=>ce,LokiCostDashboard:()=>le,LokiCostWaterfall:()=>Te,LokiCouncilDashboard:()=>se,LokiCouncilTranscripts:()=>He,LokiElement:()=>v,LokiEscalations:()=>De,LokiFleet:()=>xe,LokiLearningDashboard:()=>ae,LokiLogStream:()=>te,LokiManagedMemoryPanel:()=>ze,LokiMascotPresence:()=>Pe,LokiMemoryBrowser:()=>ie,LokiMemoryGraph:()=>Ae,LokiMigrationDashboard:()=>me,LokiNotificationCenter:()=>pe,LokiOverview:()=>X,LokiPipelineView:()=>Ce,LokiPromptOptimizer:()=>ue,LokiProviderHealth:()=>Ee,LokiQualityGates:()=>fe,LokiQualityScore:()=>ge,LokiRarvTimeline:()=>be,LokiRunManager:()=>ke,LokiSessionControl:()=>ee,LokiSessionDiff:()=>he,LokiSpecPanel:()=>Re,LokiState:()=>Q,LokiTaskBoard:()=>Z,LokiTenantSwitcher:()=>we,LokiTheme:()=>U,LokiWikiBrowser:()=>Me,MARKDOWN_STYLES:()=>L,RADIUS:()=>R,SPACING:()=>z,STATE_CHANGE_EVENT:()=>Je,THEMES:()=>A,THEME_VARIABLES:()=>Oe,TYPOGRAPHY:()=>$,UnifiedThemeManager:()=>w,VERSION:()=>mi,Z_INDEX:()=>B,createApiClient:()=>dt,createStore:()=>ct,escapeHtml:()=>Ge,generateThemeCSS:()=>E,generateTokensCSS:()=>Y,getApiClient:()=>h,getState:()=>N,init:()=>vi,renderMarkdown:()=>C});var A={light:{"--loki-bg-primary":"#FFFEFB","--loki-bg-secondary":"#F8F4F0","--loki-bg-tertiary":"#ECEAE3","--loki-bg-card":"#ffffff","--loki-bg-hover":"#F3EFE9","--loki-bg-active":"#E6E2DA","--loki-bg-overlay":"rgba(32, 21, 21, 0.5)","--loki-accent":"#553DE9","--loki-accent-hover":"#4432c4","--loki-accent-active":"#3828a0","--loki-accent-light":"#553de9","--loki-accent-muted":"rgba(85, 61, 233, 0.10)","--loki-text-primary":"#201515","--loki-text-secondary":"#36342E","--loki-text-muted":"#939084","--loki-text-disabled":"#C5C0B1","--loki-text-inverse":"#ffffff","--loki-border":"#ECEAE3","--loki-border-light":"#C5C0B1","--loki-border-focus":"#553DE9","--loki-success":"#1FC5A8","--loki-success-muted":"rgba(31, 197, 168, 0.12)","--loki-warning":"#D4A03C","--loki-warning-muted":"rgba(212, 160, 60, 0.12)","--loki-error":"#C45B5B","--loki-error-muted":"rgba(196, 91, 91, 0.12)","--loki-info":"#2F71E3","--loki-info-muted":"rgba(47, 113, 227, 0.12)","--loki-green":"#1FC5A8","--loki-green-muted":"rgba(31, 197, 168, 0.12)","--loki-yellow":"#D4A03C","--loki-yellow-muted":"rgba(212, 160, 60, 0.12)","--loki-red":"#C45B5B","--loki-red-muted":"rgba(196, 91, 91, 0.12)","--loki-blue":"#2F71E3","--loki-blue-muted":"rgba(47, 113, 227, 0.12)","--loki-purple":"#553DE9","--loki-purple-muted":"rgba(85, 61, 233, 0.10)","--loki-opus":"#d97706","--loki-sonnet":"#553DE9","--loki-haiku":"#1FC5A8","--loki-shadow-sm":"0 1px 2px rgba(32, 21, 21, 0.04)","--loki-shadow-md":"0 4px 6px rgba(32, 21, 21, 0.06)","--loki-shadow-lg":"0 10px 15px rgba(32, 21, 21, 0.08)","--loki-shadow-focus":"0 0 0 3px rgba(85, 61, 233, 0.25)"},dark:{"--loki-bg-primary":"#1A0F2E","--loki-bg-secondary":"#140B24","--loki-bg-tertiary":"#251842","--loki-bg-card":"#1F1338","--loki-bg-hover":"#2A1F4A","--loki-bg-active":"#352A55","--loki-bg-overlay":"rgba(20, 11, 36, 0.85)","--loki-accent":"#553de9","--loki-accent-hover":"#9488F5","--loki-accent-active":"#6258D0","--loki-accent-light":"#9488F5","--loki-accent-muted":"rgba(123, 107, 240, 0.18)","--loki-text-primary":"#F0ECF8","--loki-text-secondary":"#C0B8D0","--loki-text-muted":"#8B7FA8","--loki-text-disabled":"#5A4E78","--loki-text-inverse":"#1A0F2E","--loki-border":"#2A1F3E","--loki-border-light":"#3D3060","--loki-border-focus":"#553de9","--loki-success":"#2ED8B6","--loki-success-muted":"rgba(46, 216, 182, 0.18)","--loki-warning":"#E8B84A","--loki-warning-muted":"rgba(232, 184, 74, 0.18)","--loki-error":"#E07070","--loki-error-muted":"rgba(224, 112, 112, 0.18)","--loki-info":"#5A9CF5","--loki-info-muted":"rgba(90, 156, 245, 0.18)","--loki-green":"#2ED8B6","--loki-green-muted":"rgba(46, 216, 182, 0.18)","--loki-yellow":"#E8B84A","--loki-yellow-muted":"rgba(232, 184, 74, 0.18)","--loki-red":"#E07070","--loki-red-muted":"rgba(224, 112, 112, 0.18)","--loki-blue":"#5A9CF5","--loki-blue-muted":"rgba(90, 156, 245, 0.18)","--loki-purple":"#9488F5","--loki-purple-muted":"rgba(148, 136, 245, 0.18)","--loki-opus":"#f59e0b","--loki-sonnet":"#553de9","--loki-haiku":"#2ED8B6","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.4)","--loki-shadow-md":"0 4px 12px rgba(0, 0, 0, 0.5)","--loki-shadow-lg":"0 10px 25px rgba(0, 0, 0, 0.6)","--loki-shadow-focus":"0 0 0 3px rgba(123, 107, 240, 0.30)"},"high-contrast":{"--loki-bg-primary":"#000000","--loki-bg-secondary":"#0a0a0a","--loki-bg-tertiary":"#141414","--loki-bg-card":"#0a0a0a","--loki-bg-hover":"#1a1a1a","--loki-bg-active":"#242424","--loki-bg-overlay":"rgba(0, 0, 0, 0.9)","--loki-accent":"#c084fc","--loki-accent-hover":"#d8b4fe","--loki-accent-active":"#e9d5ff","--loki-accent-light":"#d8b4fe","--loki-accent-muted":"rgba(192, 132, 252, 0.25)","--loki-text-primary":"#ffffff","--loki-text-secondary":"#e0e0e0","--loki-text-muted":"#b0b0b0","--loki-text-disabled":"#666666","--loki-text-inverse":"#000000","--loki-border":"#ffffff","--loki-border-light":"#cccccc","--loki-border-focus":"#c084fc","--loki-success":"#4ade80","--loki-success-muted":"rgba(74, 222, 128, 0.25)","--loki-warning":"#fde047","--loki-warning-muted":"rgba(253, 224, 71, 0.25)","--loki-error":"#f87171","--loki-error-muted":"rgba(248, 113, 113, 0.25)","--loki-info":"#60a5fa","--loki-info-muted":"rgba(96, 165, 250, 0.25)","--loki-green":"#4ade80","--loki-green-muted":"rgba(74, 222, 128, 0.25)","--loki-yellow":"#fde047","--loki-yellow-muted":"rgba(253, 224, 71, 0.25)","--loki-red":"#f87171","--loki-red-muted":"rgba(248, 113, 113, 0.25)","--loki-blue":"#60a5fa","--loki-blue-muted":"rgba(96, 165, 250, 0.25)","--loki-purple":"#c084fc","--loki-purple-muted":"rgba(192, 132, 252, 0.25)","--loki-opus":"#fbbf24","--loki-sonnet":"#818cf8","--loki-haiku":"#34d399","--loki-shadow-sm":"none","--loki-shadow-md":"none","--loki-shadow-lg":"none","--loki-shadow-focus":"0 0 0 3px #c084fc"},"vscode-light":{"--loki-bg-primary":"var(--vscode-editor-background, #ffffff)","--loki-bg-secondary":"var(--vscode-sideBar-background, #f3f3f3)","--loki-bg-tertiary":"var(--vscode-input-background, #ffffff)","--loki-bg-card":"var(--vscode-editor-background, #ffffff)","--loki-bg-hover":"var(--vscode-list-hoverBackground, #e8e8e8)","--loki-bg-active":"var(--vscode-list-activeSelectionBackground, #0060c0)","--loki-bg-overlay":"rgba(0, 0, 0, 0.4)","--loki-accent":"var(--vscode-focusBorder, #0066cc)","--loki-accent-hover":"var(--vscode-button-hoverBackground, #0055aa)","--loki-accent-active":"var(--vscode-button-background, #007acc)","--loki-accent-light":"var(--vscode-focusBorder, #0066cc)","--loki-accent-muted":"var(--vscode-editor-selectionBackground, rgba(0, 102, 204, 0.2))","--loki-text-primary":"var(--vscode-foreground, #333333)","--loki-text-secondary":"var(--vscode-descriptionForeground, #717171)","--loki-text-muted":"var(--vscode-disabledForeground, #a0a0a0)","--loki-text-disabled":"var(--vscode-disabledForeground, #cccccc)","--loki-text-inverse":"var(--vscode-button-foreground, #ffffff)","--loki-border":"var(--vscode-widget-border, #c8c8c8)","--loki-border-light":"var(--vscode-widget-border, #e0e0e0)","--loki-border-focus":"var(--vscode-focusBorder, #0066cc)","--loki-success":"var(--vscode-testing-iconPassed, #388a34)","--loki-success-muted":"rgba(56, 138, 52, 0.15)","--loki-warning":"var(--vscode-editorWarning-foreground, #bf8803)","--loki-warning-muted":"rgba(191, 136, 3, 0.15)","--loki-error":"var(--vscode-errorForeground, #e51400)","--loki-error-muted":"rgba(229, 20, 0, 0.15)","--loki-info":"var(--vscode-editorInfo-foreground, #1a85ff)","--loki-info-muted":"rgba(26, 133, 255, 0.15)","--loki-green":"var(--vscode-testing-iconPassed, #388a34)","--loki-green-muted":"rgba(56, 138, 52, 0.15)","--loki-yellow":"var(--vscode-editorWarning-foreground, #bf8803)","--loki-yellow-muted":"rgba(191, 136, 3, 0.15)","--loki-red":"var(--vscode-errorForeground, #e51400)","--loki-red-muted":"rgba(229, 20, 0, 0.15)","--loki-blue":"var(--vscode-editorInfo-foreground, #1a85ff)","--loki-blue-muted":"rgba(26, 133, 255, 0.15)","--loki-purple":"#9333ea","--loki-purple-muted":"rgba(147, 51, 234, 0.15)","--loki-opus":"#d97706","--loki-sonnet":"#4f46e5","--loki-haiku":"#059669","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.05)","--loki-shadow-md":"0 2px 4px rgba(0, 0, 0, 0.1)","--loki-shadow-lg":"0 4px 8px rgba(0, 0, 0, 0.15)","--loki-shadow-focus":"0 0 0 2px var(--vscode-focusBorder, #0066cc)"},"vscode-dark":{"--loki-bg-primary":"var(--vscode-editor-background, #1e1e1e)","--loki-bg-secondary":"var(--vscode-sideBar-background, #252526)","--loki-bg-tertiary":"var(--vscode-input-background, #3c3c3c)","--loki-bg-card":"var(--vscode-editor-background, #1e1e1e)","--loki-bg-hover":"var(--vscode-list-hoverBackground, #2a2d2e)","--loki-bg-active":"var(--vscode-list-activeSelectionBackground, #094771)","--loki-bg-overlay":"rgba(0, 0, 0, 0.6)","--loki-accent":"var(--vscode-focusBorder, #007fd4)","--loki-accent-hover":"var(--vscode-button-hoverBackground, #1177bb)","--loki-accent-active":"var(--vscode-button-background, #0e639c)","--loki-accent-light":"var(--vscode-focusBorder, #007fd4)","--loki-accent-muted":"var(--vscode-editor-selectionBackground, rgba(0, 127, 212, 0.25))","--loki-text-primary":"var(--vscode-foreground, #cccccc)","--loki-text-secondary":"var(--vscode-descriptionForeground, #9d9d9d)","--loki-text-muted":"var(--vscode-disabledForeground, #6b6b6b)","--loki-text-disabled":"var(--vscode-disabledForeground, #4d4d4d)","--loki-text-inverse":"var(--vscode-button-foreground, #ffffff)","--loki-border":"var(--vscode-widget-border, #454545)","--loki-border-light":"var(--vscode-widget-border, #5a5a5a)","--loki-border-focus":"var(--vscode-focusBorder, #007fd4)","--loki-success":"var(--vscode-testing-iconPassed, #89d185)","--loki-success-muted":"rgba(137, 209, 133, 0.2)","--loki-warning":"var(--vscode-editorWarning-foreground, #cca700)","--loki-warning-muted":"rgba(204, 167, 0, 0.2)","--loki-error":"var(--vscode-errorForeground, #f48771)","--loki-error-muted":"rgba(244, 135, 113, 0.2)","--loki-info":"var(--vscode-editorInfo-foreground, #75beff)","--loki-info-muted":"rgba(117, 190, 255, 0.2)","--loki-green":"var(--vscode-testing-iconPassed, #89d185)","--loki-green-muted":"rgba(137, 209, 133, 0.2)","--loki-yellow":"var(--vscode-editorWarning-foreground, #cca700)","--loki-yellow-muted":"rgba(204, 167, 0, 0.2)","--loki-red":"var(--vscode-errorForeground, #f48771)","--loki-red-muted":"rgba(244, 135, 113, 0.2)","--loki-blue":"var(--vscode-editorInfo-foreground, #75beff)","--loki-blue-muted":"rgba(117, 190, 255, 0.2)","--loki-purple":"#c084fc","--loki-purple-muted":"rgba(192, 132, 252, 0.2)","--loki-opus":"#f59e0b","--loki-sonnet":"#818cf8","--loki-haiku":"#34d399","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.3)","--loki-shadow-md":"0 2px 4px rgba(0, 0, 0, 0.4)","--loki-shadow-lg":"0 4px 8px rgba(0, 0, 0, 0.5)","--loki-shadow-focus":"0 0 0 2px var(--vscode-focusBorder, #007fd4)"}},z={xs:"4px",sm:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"32px","3xl":"48px"},R={none:"0",sm:"2px",md:"4px",lg:"5px",xl:"5px",full:"9999px"},$={fontFamily:{sans:"'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif",serif:"'Fraunces', Georgia, 'Times New Roman', serif",mono:"'JetBrains Mono', 'Fira Code', 'SF Mono', Menlo, monospace"},fontSize:{xs:"10px",sm:"11px",base:"12px",md:"13px",lg:"14px",xl:"16px","2xl":"18px","3xl":"24px"},fontWeight:{normal:"400",medium:"500",semibold:"600",bold:"700"},lineHeight:{tight:"1.25",normal:"1.5",relaxed:"1.75"}},P={duration:{fast:"100ms",normal:"200ms",slow:"300ms",slower:"500ms"},easing:{default:"cubic-bezier(0.4, 0, 0.2, 1)",in:"cubic-bezier(0.4, 0, 1, 1)",out:"cubic-bezier(0, 0, 0.2, 1)",bounce:"cubic-bezier(0.68, -0.55, 0.265, 1.55)"}},Ie={sm:"640px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},B={base:"0",dropdown:"100",sticky:"200",modal:"300",popover:"400",tooltip:"500",toast:"600"},je={"navigation.nextItem":{key:"ArrowDown",modifiers:[]},"navigation.prevItem":{key:"ArrowUp",modifiers:[]},"navigation.nextSection":{key:"Tab",modifiers:[]},"navigation.prevSection":{key:"Tab",modifiers:["Shift"]},"navigation.confirm":{key:"Enter",modifiers:[]},"navigation.cancel":{key:"Escape",modifiers:[]},"action.refresh":{key:"r",modifiers:["Meta"]},"action.search":{key:"k",modifiers:["Meta"]},"action.save":{key:"s",modifiers:["Meta"]},"action.close":{key:"w",modifiers:["Meta"]},"theme.toggle":{key:"d",modifiers:["Meta","Shift"]},"task.create":{key:"n",modifiers:["Meta"]},"task.complete":{key:"Enter",modifiers:["Meta"]},"view.toggleLogs":{key:"l",modifiers:["Meta","Shift"]},"view.toggleMemory":{key:"m",modifiers:["Meta","Shift"]}},Ue={button:{role:"button",tabIndex:0},tablist:{role:"tablist"},tab:{role:"tab",ariaSelected:!1,tabIndex:-1},tabpanel:{role:"tabpanel",tabIndex:0},list:{role:"list"},listitem:{role:"listitem"},livePolite:{ariaLive:"polite",ariaAtomic:!0},liveAssertive:{ariaLive:"assertive",ariaAtomic:!0},dialog:{role:"dialog",ariaModal:!0},alertdialog:{role:"alertdialog",ariaModal:!0},status:{role:"status",ariaLive:"polite"},alert:{role:"alert",ariaLive:"assertive"},log:{role:"log",ariaLive:"polite",ariaRelevant:"additions"}};function E(d){let e=A[d];return e?Object.entries(e).map(([t,i])=>`${t}: ${i};`).join(`
|
|
1847
|
+
var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropertyDescriptor;var Dt=Object.getOwnPropertyNames;var Ht=Object.prototype.hasOwnProperty;var Mt=(d,e,t)=>e in d?Be(d,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):d[e]=t;var Rt=(d,e)=>{for(var t in e)Be(d,t,{get:e[t],enumerable:!0})},Pt=(d,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of Dt(e))!Ht.call(d,a)&&a!==t&&Be(d,a,{get:()=>e[a],enumerable:!(i=zt(e,a))||i.enumerable});return d};var Bt=d=>Pt(Be({},"__esModule",{value:!0}),d);var S=(d,e,t)=>Mt(d,typeof e!="symbol"?e+"":e,t);var vi={};Rt(vi,{ANIMATION:()=>P,ARIA_PATTERNS:()=>Ue,ApiEvents:()=>f,BASE_STYLES:()=>W,BREAKPOINTS:()=>Ie,COMMON_STYLES:()=>ot,KEYBOARD_SHORTCUTS:()=>je,KeyboardHandler:()=>O,LokiActivityStream:()=>$e,LokiAgentLeaderboard:()=>Le,LokiAnalytics:()=>ve,LokiApiClient:()=>J,LokiApiKeys:()=>ye,LokiAppPreview:()=>ne,LokiAppStatus:()=>oe,LokiAuditViewer:()=>_e,LokiChecklistViewer:()=>re,LokiCheckpointViewer:()=>de,LokiContextTracker:()=>ce,LokiCostDashboard:()=>le,LokiCostWaterfall:()=>Te,LokiCouncilDashboard:()=>se,LokiCouncilTranscripts:()=>He,LokiElement:()=>v,LokiEscalations:()=>De,LokiFleet:()=>xe,LokiLearningDashboard:()=>ae,LokiLogStream:()=>te,LokiManagedMemoryPanel:()=>ze,LokiMascotPresence:()=>Pe,LokiMemoryBrowser:()=>ie,LokiMemoryGraph:()=>Ae,LokiMigrationDashboard:()=>me,LokiNotificationCenter:()=>pe,LokiOverview:()=>X,LokiPipelineView:()=>Ce,LokiPromptOptimizer:()=>ue,LokiProviderHealth:()=>Ee,LokiQualityGates:()=>fe,LokiQualityScore:()=>ge,LokiRarvTimeline:()=>be,LokiRunManager:()=>ke,LokiSessionControl:()=>ee,LokiSessionDiff:()=>he,LokiSpecPanel:()=>Re,LokiState:()=>Q,LokiTaskBoard:()=>Z,LokiTenantSwitcher:()=>we,LokiTheme:()=>U,LokiWikiBrowser:()=>Me,MARKDOWN_STYLES:()=>L,RADIUS:()=>R,SPACING:()=>z,STATE_CHANGE_EVENT:()=>Je,THEMES:()=>A,THEME_VARIABLES:()=>Oe,TYPOGRAPHY:()=>$,UnifiedThemeManager:()=>w,VERSION:()=>gi,Z_INDEX:()=>B,createApiClient:()=>dt,createStore:()=>ct,escapeHtml:()=>Ge,generateThemeCSS:()=>E,generateTokensCSS:()=>Y,getApiClient:()=>h,getState:()=>N,init:()=>mi,renderMarkdown:()=>C});var A={light:{"--loki-bg-primary":"#FFFEFB","--loki-bg-secondary":"#F8F4F0","--loki-bg-tertiary":"#ECEAE3","--loki-bg-card":"#ffffff","--loki-bg-hover":"#F3EFE9","--loki-bg-active":"#E6E2DA","--loki-bg-overlay":"rgba(32, 21, 21, 0.5)","--loki-accent":"#553DE9","--loki-accent-hover":"#4432c4","--loki-accent-active":"#3828a0","--loki-accent-light":"#553de9","--loki-accent-muted":"rgba(85, 61, 233, 0.10)","--loki-text-primary":"#201515","--loki-text-secondary":"#36342E","--loki-text-muted":"#939084","--loki-text-disabled":"#C5C0B1","--loki-text-inverse":"#ffffff","--loki-border":"#ECEAE3","--loki-border-light":"#C5C0B1","--loki-border-focus":"#553DE9","--loki-success":"#1FC5A8","--loki-success-muted":"rgba(31, 197, 168, 0.12)","--loki-warning":"#D4A03C","--loki-warning-muted":"rgba(212, 160, 60, 0.12)","--loki-error":"#C45B5B","--loki-error-muted":"rgba(196, 91, 91, 0.12)","--loki-info":"#2F71E3","--loki-info-muted":"rgba(47, 113, 227, 0.12)","--loki-green":"#1FC5A8","--loki-green-muted":"rgba(31, 197, 168, 0.12)","--loki-yellow":"#D4A03C","--loki-yellow-muted":"rgba(212, 160, 60, 0.12)","--loki-red":"#C45B5B","--loki-red-muted":"rgba(196, 91, 91, 0.12)","--loki-blue":"#2F71E3","--loki-blue-muted":"rgba(47, 113, 227, 0.12)","--loki-purple":"#553DE9","--loki-purple-muted":"rgba(85, 61, 233, 0.10)","--loki-opus":"#d97706","--loki-sonnet":"#553DE9","--loki-haiku":"#1FC5A8","--loki-shadow-sm":"0 1px 2px rgba(32, 21, 21, 0.04)","--loki-shadow-md":"0 4px 6px rgba(32, 21, 21, 0.06)","--loki-shadow-lg":"0 10px 15px rgba(32, 21, 21, 0.08)","--loki-shadow-focus":"0 0 0 3px rgba(85, 61, 233, 0.25)"},dark:{"--loki-bg-primary":"#1A0F2E","--loki-bg-secondary":"#140B24","--loki-bg-tertiary":"#251842","--loki-bg-card":"#1F1338","--loki-bg-hover":"#2A1F4A","--loki-bg-active":"#352A55","--loki-bg-overlay":"rgba(20, 11, 36, 0.85)","--loki-accent":"#553de9","--loki-accent-hover":"#9488F5","--loki-accent-active":"#6258D0","--loki-accent-light":"#9488F5","--loki-accent-muted":"rgba(123, 107, 240, 0.18)","--loki-text-primary":"#F0ECF8","--loki-text-secondary":"#C0B8D0","--loki-text-muted":"#8B7FA8","--loki-text-disabled":"#5A4E78","--loki-text-inverse":"#1A0F2E","--loki-border":"#2A1F3E","--loki-border-light":"#3D3060","--loki-border-focus":"#553de9","--loki-success":"#2ED8B6","--loki-success-muted":"rgba(46, 216, 182, 0.18)","--loki-warning":"#E8B84A","--loki-warning-muted":"rgba(232, 184, 74, 0.18)","--loki-error":"#E07070","--loki-error-muted":"rgba(224, 112, 112, 0.18)","--loki-info":"#5A9CF5","--loki-info-muted":"rgba(90, 156, 245, 0.18)","--loki-green":"#2ED8B6","--loki-green-muted":"rgba(46, 216, 182, 0.18)","--loki-yellow":"#E8B84A","--loki-yellow-muted":"rgba(232, 184, 74, 0.18)","--loki-red":"#E07070","--loki-red-muted":"rgba(224, 112, 112, 0.18)","--loki-blue":"#5A9CF5","--loki-blue-muted":"rgba(90, 156, 245, 0.18)","--loki-purple":"#9488F5","--loki-purple-muted":"rgba(148, 136, 245, 0.18)","--loki-opus":"#f59e0b","--loki-sonnet":"#553de9","--loki-haiku":"#2ED8B6","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.4)","--loki-shadow-md":"0 4px 12px rgba(0, 0, 0, 0.5)","--loki-shadow-lg":"0 10px 25px rgba(0, 0, 0, 0.6)","--loki-shadow-focus":"0 0 0 3px rgba(123, 107, 240, 0.30)"},"high-contrast":{"--loki-bg-primary":"#000000","--loki-bg-secondary":"#0a0a0a","--loki-bg-tertiary":"#141414","--loki-bg-card":"#0a0a0a","--loki-bg-hover":"#1a1a1a","--loki-bg-active":"#242424","--loki-bg-overlay":"rgba(0, 0, 0, 0.9)","--loki-accent":"#c084fc","--loki-accent-hover":"#d8b4fe","--loki-accent-active":"#e9d5ff","--loki-accent-light":"#d8b4fe","--loki-accent-muted":"rgba(192, 132, 252, 0.25)","--loki-text-primary":"#ffffff","--loki-text-secondary":"#e0e0e0","--loki-text-muted":"#b0b0b0","--loki-text-disabled":"#666666","--loki-text-inverse":"#000000","--loki-border":"#ffffff","--loki-border-light":"#cccccc","--loki-border-focus":"#c084fc","--loki-success":"#4ade80","--loki-success-muted":"rgba(74, 222, 128, 0.25)","--loki-warning":"#fde047","--loki-warning-muted":"rgba(253, 224, 71, 0.25)","--loki-error":"#f87171","--loki-error-muted":"rgba(248, 113, 113, 0.25)","--loki-info":"#60a5fa","--loki-info-muted":"rgba(96, 165, 250, 0.25)","--loki-green":"#4ade80","--loki-green-muted":"rgba(74, 222, 128, 0.25)","--loki-yellow":"#fde047","--loki-yellow-muted":"rgba(253, 224, 71, 0.25)","--loki-red":"#f87171","--loki-red-muted":"rgba(248, 113, 113, 0.25)","--loki-blue":"#60a5fa","--loki-blue-muted":"rgba(96, 165, 250, 0.25)","--loki-purple":"#c084fc","--loki-purple-muted":"rgba(192, 132, 252, 0.25)","--loki-opus":"#fbbf24","--loki-sonnet":"#818cf8","--loki-haiku":"#34d399","--loki-shadow-sm":"none","--loki-shadow-md":"none","--loki-shadow-lg":"none","--loki-shadow-focus":"0 0 0 3px #c084fc"},"vscode-light":{"--loki-bg-primary":"var(--vscode-editor-background, #ffffff)","--loki-bg-secondary":"var(--vscode-sideBar-background, #f3f3f3)","--loki-bg-tertiary":"var(--vscode-input-background, #ffffff)","--loki-bg-card":"var(--vscode-editor-background, #ffffff)","--loki-bg-hover":"var(--vscode-list-hoverBackground, #e8e8e8)","--loki-bg-active":"var(--vscode-list-activeSelectionBackground, #0060c0)","--loki-bg-overlay":"rgba(0, 0, 0, 0.4)","--loki-accent":"var(--vscode-focusBorder, #0066cc)","--loki-accent-hover":"var(--vscode-button-hoverBackground, #0055aa)","--loki-accent-active":"var(--vscode-button-background, #007acc)","--loki-accent-light":"var(--vscode-focusBorder, #0066cc)","--loki-accent-muted":"var(--vscode-editor-selectionBackground, rgba(0, 102, 204, 0.2))","--loki-text-primary":"var(--vscode-foreground, #333333)","--loki-text-secondary":"var(--vscode-descriptionForeground, #717171)","--loki-text-muted":"var(--vscode-disabledForeground, #a0a0a0)","--loki-text-disabled":"var(--vscode-disabledForeground, #cccccc)","--loki-text-inverse":"var(--vscode-button-foreground, #ffffff)","--loki-border":"var(--vscode-widget-border, #c8c8c8)","--loki-border-light":"var(--vscode-widget-border, #e0e0e0)","--loki-border-focus":"var(--vscode-focusBorder, #0066cc)","--loki-success":"var(--vscode-testing-iconPassed, #388a34)","--loki-success-muted":"rgba(56, 138, 52, 0.15)","--loki-warning":"var(--vscode-editorWarning-foreground, #bf8803)","--loki-warning-muted":"rgba(191, 136, 3, 0.15)","--loki-error":"var(--vscode-errorForeground, #e51400)","--loki-error-muted":"rgba(229, 20, 0, 0.15)","--loki-info":"var(--vscode-editorInfo-foreground, #1a85ff)","--loki-info-muted":"rgba(26, 133, 255, 0.15)","--loki-green":"var(--vscode-testing-iconPassed, #388a34)","--loki-green-muted":"rgba(56, 138, 52, 0.15)","--loki-yellow":"var(--vscode-editorWarning-foreground, #bf8803)","--loki-yellow-muted":"rgba(191, 136, 3, 0.15)","--loki-red":"var(--vscode-errorForeground, #e51400)","--loki-red-muted":"rgba(229, 20, 0, 0.15)","--loki-blue":"var(--vscode-editorInfo-foreground, #1a85ff)","--loki-blue-muted":"rgba(26, 133, 255, 0.15)","--loki-purple":"#9333ea","--loki-purple-muted":"rgba(147, 51, 234, 0.15)","--loki-opus":"#d97706","--loki-sonnet":"#4f46e5","--loki-haiku":"#059669","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.05)","--loki-shadow-md":"0 2px 4px rgba(0, 0, 0, 0.1)","--loki-shadow-lg":"0 4px 8px rgba(0, 0, 0, 0.15)","--loki-shadow-focus":"0 0 0 2px var(--vscode-focusBorder, #0066cc)"},"vscode-dark":{"--loki-bg-primary":"var(--vscode-editor-background, #1e1e1e)","--loki-bg-secondary":"var(--vscode-sideBar-background, #252526)","--loki-bg-tertiary":"var(--vscode-input-background, #3c3c3c)","--loki-bg-card":"var(--vscode-editor-background, #1e1e1e)","--loki-bg-hover":"var(--vscode-list-hoverBackground, #2a2d2e)","--loki-bg-active":"var(--vscode-list-activeSelectionBackground, #094771)","--loki-bg-overlay":"rgba(0, 0, 0, 0.6)","--loki-accent":"var(--vscode-focusBorder, #007fd4)","--loki-accent-hover":"var(--vscode-button-hoverBackground, #1177bb)","--loki-accent-active":"var(--vscode-button-background, #0e639c)","--loki-accent-light":"var(--vscode-focusBorder, #007fd4)","--loki-accent-muted":"var(--vscode-editor-selectionBackground, rgba(0, 127, 212, 0.25))","--loki-text-primary":"var(--vscode-foreground, #cccccc)","--loki-text-secondary":"var(--vscode-descriptionForeground, #9d9d9d)","--loki-text-muted":"var(--vscode-disabledForeground, #6b6b6b)","--loki-text-disabled":"var(--vscode-disabledForeground, #4d4d4d)","--loki-text-inverse":"var(--vscode-button-foreground, #ffffff)","--loki-border":"var(--vscode-widget-border, #454545)","--loki-border-light":"var(--vscode-widget-border, #5a5a5a)","--loki-border-focus":"var(--vscode-focusBorder, #007fd4)","--loki-success":"var(--vscode-testing-iconPassed, #89d185)","--loki-success-muted":"rgba(137, 209, 133, 0.2)","--loki-warning":"var(--vscode-editorWarning-foreground, #cca700)","--loki-warning-muted":"rgba(204, 167, 0, 0.2)","--loki-error":"var(--vscode-errorForeground, #f48771)","--loki-error-muted":"rgba(244, 135, 113, 0.2)","--loki-info":"var(--vscode-editorInfo-foreground, #75beff)","--loki-info-muted":"rgba(117, 190, 255, 0.2)","--loki-green":"var(--vscode-testing-iconPassed, #89d185)","--loki-green-muted":"rgba(137, 209, 133, 0.2)","--loki-yellow":"var(--vscode-editorWarning-foreground, #cca700)","--loki-yellow-muted":"rgba(204, 167, 0, 0.2)","--loki-red":"var(--vscode-errorForeground, #f48771)","--loki-red-muted":"rgba(244, 135, 113, 0.2)","--loki-blue":"var(--vscode-editorInfo-foreground, #75beff)","--loki-blue-muted":"rgba(117, 190, 255, 0.2)","--loki-purple":"#c084fc","--loki-purple-muted":"rgba(192, 132, 252, 0.2)","--loki-opus":"#f59e0b","--loki-sonnet":"#818cf8","--loki-haiku":"#34d399","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.3)","--loki-shadow-md":"0 2px 4px rgba(0, 0, 0, 0.4)","--loki-shadow-lg":"0 4px 8px rgba(0, 0, 0, 0.5)","--loki-shadow-focus":"0 0 0 2px var(--vscode-focusBorder, #007fd4)"}},z={xs:"4px",sm:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"32px","3xl":"48px"},R={none:"0",sm:"2px",md:"4px",lg:"5px",xl:"5px",full:"9999px"},$={fontFamily:{sans:"'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif",serif:"'Fraunces', Georgia, 'Times New Roman', serif",mono:"'JetBrains Mono', 'Fira Code', 'SF Mono', Menlo, monospace"},fontSize:{xs:"10px",sm:"11px",base:"12px",md:"13px",lg:"14px",xl:"16px","2xl":"18px","3xl":"24px"},fontWeight:{normal:"400",medium:"500",semibold:"600",bold:"700"},lineHeight:{tight:"1.25",normal:"1.5",relaxed:"1.75"}},P={duration:{fast:"100ms",normal:"200ms",slow:"300ms",slower:"500ms"},easing:{default:"cubic-bezier(0.4, 0, 0.2, 1)",in:"cubic-bezier(0.4, 0, 1, 1)",out:"cubic-bezier(0, 0, 0.2, 1)",bounce:"cubic-bezier(0.68, -0.55, 0.265, 1.55)"}},Ie={sm:"640px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},B={base:"0",dropdown:"100",sticky:"200",modal:"300",popover:"400",tooltip:"500",toast:"600"},je={"navigation.nextItem":{key:"ArrowDown",modifiers:[]},"navigation.prevItem":{key:"ArrowUp",modifiers:[]},"navigation.nextSection":{key:"Tab",modifiers:[]},"navigation.prevSection":{key:"Tab",modifiers:["Shift"]},"navigation.confirm":{key:"Enter",modifiers:[]},"navigation.cancel":{key:"Escape",modifiers:[]},"action.refresh":{key:"r",modifiers:["Meta"]},"action.search":{key:"k",modifiers:["Meta"]},"action.save":{key:"s",modifiers:["Meta"]},"action.close":{key:"w",modifiers:["Meta"]},"theme.toggle":{key:"d",modifiers:["Meta","Shift"]},"task.create":{key:"n",modifiers:["Meta"]},"task.complete":{key:"Enter",modifiers:["Meta"]},"view.toggleLogs":{key:"l",modifiers:["Meta","Shift"]},"view.toggleMemory":{key:"m",modifiers:["Meta","Shift"]}},Ue={button:{role:"button",tabIndex:0},tablist:{role:"tablist"},tab:{role:"tab",ariaSelected:!1,tabIndex:-1},tabpanel:{role:"tabpanel",tabIndex:0},list:{role:"list"},listitem:{role:"listitem"},livePolite:{ariaLive:"polite",ariaAtomic:!0},liveAssertive:{ariaLive:"assertive",ariaAtomic:!0},dialog:{role:"dialog",ariaModal:!0},alertdialog:{role:"alertdialog",ariaModal:!0},status:{role:"status",ariaLive:"polite"},alert:{role:"alert",ariaLive:"assertive"},log:{role:"log",ariaLive:"polite",ariaRelevant:"additions"}};function E(d){let e=A[d];return e?Object.entries(e).map(([t,i])=>`${t}: ${i};`).join(`
|
|
1961
1848
|
`):""}function Y(){return`
|
|
1962
1849
|
/* Spacing */
|
|
1963
1850
|
--loki-space-xs: ${z.xs};
|
|
@@ -6539,14 +6426,13 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
6539
6426
|
`:""}
|
|
6540
6427
|
`}_renderConvergenceBar(){let e=this._convergence.slice(-20);if(e.length===0)return'<span class="text-muted">No data</span>';let t=Math.max(...e.map(i=>i.files_changed),1);return`
|
|
6541
6428
|
<div class="bar-chart">
|
|
6542
|
-
${e.map(i=>{let a=Math.max(4,i.files_changed/t*60),s=i.no_change_streak>0
|
|
6543
|
-
<div class="bar-wrapper" title="${
|
|
6544
|
-
<div class="bar ${s?"bar-stagnant":"bar-active"}" style="height: ${a}px"
|
|
6545
|
-
<div class="bar-label">${i.iteration}
|
|
6429
|
+
${e.map(i=>{let a=Math.max(4,i.files_changed/t*60),s=i.no_change_streak>0;return`
|
|
6430
|
+
<div class="bar-wrapper" title="Iter ${i.iteration}: ${i.files_changed} files changed">
|
|
6431
|
+
<div class="bar ${s?"bar-stagnant":"bar-active"}" style="height: ${a}px"></div>
|
|
6432
|
+
<div class="bar-label">${i.iteration}</div>
|
|
6546
6433
|
</div>
|
|
6547
6434
|
`}).join("")}
|
|
6548
6435
|
</div>
|
|
6549
|
-
${e.some(i=>i.no_change_streak>0)?'<div class="bar-chart-legend">* hatched = stagnant (no files changed)</div>':""}
|
|
6550
6436
|
`}_renderDecisions(){return this._verdicts.length===0?`<div class="empty-state">No review decisions yet. The council checks for completion every ${this._councilState?.check_interval||5} build steps.</div>`:`
|
|
6551
6437
|
<div class="decision-list">
|
|
6552
6438
|
${this._verdicts.slice().reverse().map(e=>`
|
|
@@ -6858,19 +6744,6 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
6858
6744
|
|
|
6859
6745
|
.bar-stagnant {
|
|
6860
6746
|
background: var(--loki-warning-muted);
|
|
6861
|
-
/* Second, non-colour channel: diagonal hatch distinguishes stagnant
|
|
6862
|
-
bars from active ones in greyscale and for colourblind users. */
|
|
6863
|
-
background-image: repeating-linear-gradient(
|
|
6864
|
-
45deg,
|
|
6865
|
-
transparent 0 3px,
|
|
6866
|
-
var(--loki-warning) 3px 5px
|
|
6867
|
-
);
|
|
6868
|
-
}
|
|
6869
|
-
|
|
6870
|
-
.bar-chart-legend {
|
|
6871
|
-
font-size: 9px;
|
|
6872
|
-
color: var(--loki-text-muted);
|
|
6873
|
-
margin-top: 6px;
|
|
6874
6747
|
}
|
|
6875
6748
|
|
|
6876
6749
|
.bar-label {
|
|
@@ -7216,17 +7089,9 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
7216
7089
|
flex-shrink: 0;
|
|
7217
7090
|
}
|
|
7218
7091
|
.v-dot {
|
|
7219
|
-
width:
|
|
7220
|
-
height:
|
|
7092
|
+
width: 6px;
|
|
7093
|
+
height: 6px;
|
|
7221
7094
|
border-radius: 50%;
|
|
7222
|
-
display: inline-flex;
|
|
7223
|
-
align-items: center;
|
|
7224
|
-
justify-content: center;
|
|
7225
|
-
font-size: 9px;
|
|
7226
|
-
font-weight: 700;
|
|
7227
|
-
line-height: 1;
|
|
7228
|
-
font-family: 'JetBrains Mono', monospace;
|
|
7229
|
-
color: var(--loki-text-inverse, #ffffff);
|
|
7230
7095
|
}
|
|
7231
7096
|
.v-dot-pass { background: var(--loki-status-success, #22c55e); }
|
|
7232
7097
|
.v-dot-fail { background: var(--loki-status-error, #ef4444); }
|
|
@@ -7303,12 +7168,12 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
7303
7168
|
}
|
|
7304
7169
|
.gate-blocked {
|
|
7305
7170
|
background: rgba(239, 68, 68, 0.1);
|
|
7306
|
-
border-left: 3px solid
|
|
7171
|
+
border-left: 3px solid #ef4444;
|
|
7307
7172
|
color: #fca5a5;
|
|
7308
7173
|
}
|
|
7309
7174
|
.gate-passed {
|
|
7310
7175
|
background: rgba(34, 197, 94, 0.1);
|
|
7311
|
-
border-left: 3px solid
|
|
7176
|
+
border-left: 3px solid #22c55e;
|
|
7312
7177
|
color: #86efac;
|
|
7313
7178
|
}
|
|
7314
7179
|
|
|
@@ -7370,7 +7235,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
7370
7235
|
${p}
|
|
7371
7236
|
${u}
|
|
7372
7237
|
<div class="verification-dots">
|
|
7373
|
-
${o.map(m
|
|
7238
|
+
${o.map(m=>`<div class="v-dot ${m.passed===!0?"v-dot-pass":m.passed===!1?"v-dot-fail":"v-dot-pending"}" title="${this._escapeHtml(m.type||"")}"></div>`).join("")}
|
|
7374
7239
|
</div>
|
|
7375
7240
|
</div>
|
|
7376
7241
|
`}).join(""):'<div class="item" style="color:var(--loki-text-muted)">No items</div>'}_renderEmpty(){return`
|
|
@@ -7626,7 +7491,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
7626
7491
|
.btn { padding: 6px 12px; font-size: 13px; border-radius: 6px; border: 1px solid var(--loki-border, #e4e4e7); background: var(--loki-bg-subtle, #f4f4f5); color: var(--loki-text-primary, #201515); cursor: pointer; }
|
|
7627
7492
|
.btn:hover:not(:disabled) { background: var(--loki-bg-hover, #e4e4e7); }
|
|
7628
7493
|
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
|
|
7629
|
-
.btn-primary { background: var(--loki-accent, #2563eb); color:
|
|
7494
|
+
.btn-primary { background: var(--loki-accent, #2563eb); color: #fff; border-color: var(--loki-accent, #2563eb); }
|
|
7630
7495
|
/* Per-service tab strip. Rendered only when more than one service is
|
|
7631
7496
|
exposed; a single service shows no tabs (unchanged behavior). */
|
|
7632
7497
|
.service-tabs { display: flex; gap: 4px; margin-top: 12px; flex-wrap: wrap; border-bottom: 1px solid var(--loki-border, #e4e4e7); }
|
|
@@ -7814,10 +7679,9 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
7814
7679
|
<span class="section-title">Budget</span>
|
|
7815
7680
|
</div>
|
|
7816
7681
|
<div class="budget-bar-container">
|
|
7817
|
-
<div class="budget-bar ${t}" style="width: ${e.toFixed(1)}%"
|
|
7682
|
+
<div class="budget-bar ${t}" style="width: ${e.toFixed(1)}%"></div>
|
|
7818
7683
|
</div>
|
|
7819
7684
|
<div class="budget-details">
|
|
7820
|
-
<span class="budget-status budget-status-${t}">${t.toUpperCase()}</span>
|
|
7821
7685
|
<span class="budget-used">${this._formatUSD(this._data.budget_used)} used</span>
|
|
7822
7686
|
<span class="budget-remaining">${a} remaining</span>
|
|
7823
7687
|
<span class="budget-limit">of ${this._formatUSD(this._data.budget_limit)}</span>
|
|
@@ -8005,17 +7869,6 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
8005
7869
|
background: var(--loki-red);
|
|
8006
7870
|
}
|
|
8007
7871
|
|
|
8008
|
-
/* Text badge repeats the bar's threshold state so it is not
|
|
8009
|
-
conveyed by the bar colour alone. */
|
|
8010
|
-
.budget-status {
|
|
8011
|
-
font-weight: 700;
|
|
8012
|
-
letter-spacing: 0.04em;
|
|
8013
|
-
}
|
|
8014
|
-
|
|
8015
|
-
.budget-status-ok { color: var(--loki-green); }
|
|
8016
|
-
.budget-status-warning { color: var(--loki-yellow); }
|
|
8017
|
-
.budget-status-critical { color: var(--loki-red); }
|
|
8018
|
-
|
|
8019
7872
|
.budget-details {
|
|
8020
7873
|
display: flex;
|
|
8021
7874
|
justify-content: space-between;
|
|
@@ -9045,7 +8898,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
9045
8898
|
|
|
9046
8899
|
${e}
|
|
9047
8900
|
</div>
|
|
9048
|
-
`,this.shadowRoot.querySelectorAll(".tab").forEach(t=>{t.addEventListener("click",()=>{this._setTab(t.dataset.tab)})})}};customElements.get("loki-context-tracker")||customElements.define("loki-context-tracker",ce);var Qe={critical:"var(--loki-red, #ef4444)",warning:"var(--loki-yellow, #eab308)",info:"var(--loki-blue, #3b82f6)",success:"var(--loki-green, #1FC5A8)"},
|
|
8901
|
+
`,this.shadowRoot.querySelectorAll(".tab").forEach(t=>{t.addEventListener("click",()=>{this._setTab(t.dataset.tab)})})}};customElements.get("loki-context-tracker")||customElements.define("loki-context-tracker",ce);var Qe={critical:"var(--loki-red, #ef4444)",warning:"var(--loki-yellow, #eab308)",info:"var(--loki-blue, #3b82f6)",success:"var(--loki-green, #1FC5A8)"},vt={build:{label:"Build",icon:"B"},quality:{label:"Quality",icon:"Q"},system:{label:"System",icon:"S"},security:{label:"Security",icon:"!"}},pe=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._notifications=[],this._triggers=[],this._summary={},this._connected=!1,this._activeTab="feed",this._categoryFilter="all",this._panelOpen=!0,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._loadNotifications(),this._loadTriggers(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&(this._loadNotifications(),this._loadTriggers()),e==="theme"&&this._applyTheme())}async _loadNotifications(){try{let e=this.getAttribute("api-url")||window.location.origin,t=await fetch(e+"/api/notifications");if(t.ok){let i=await t.json();this._notifications=i.notifications||[],this._summary=i.summary||{},this._connected=!0}}catch{this._connected=!1}this.render()}async _loadTriggers(){try{let e=this.getAttribute("api-url")||window.location.origin,t=await fetch(e+"/api/notifications/triggers");if(t.ok){let i=await t.json();this._triggers=i.triggers||[]}}catch{}}async _acknowledgeNotification(e){let t=this.getAttribute("api-url")||window.location.origin;try{await fetch(t+"/api/notifications/"+encodeURIComponent(e)+"/acknowledge",{method:"POST"})}catch{}this._loadNotifications()}async _unacknowledgeNotification(e){let t=this.getAttribute("api-url")||window.location.origin;await fetch(t+"/api/notifications/"+encodeURIComponent(e)+"/unacknowledge",{method:"POST"}),this._loadNotifications()}async _acknowledgeAll(){let e=this.getAttribute("api-url")||window.location.origin,t=this._notifications.filter(i=>!i.acknowledged);for(let i of t)await fetch(e+"/api/notifications/"+encodeURIComponent(i.id)+"/acknowledge",{method:"POST"});this._loadNotifications()}async _toggleTrigger(e,t){let i=this.getAttribute("api-url")||window.location.origin,a=this._triggers.map(s=>s.id===e?{...s,enabled:t}:s);await fetch(i+"/api/notifications/triggers",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({triggers:a})}),this._triggers=a,this.render()}_startPolling(){this._poll=b({loadFn:()=>{this._loadNotifications(),this._loadTriggers()},intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_formatTime(e){if(!e)return"";try{let t=new Date(e),a=new Date-t,s=Math.floor(a/1e3),r=Math.floor(s/60),o=Math.floor(r/60),n=Math.floor(o/24);return s<60?s+"s ago":r<60?r+"m ago":o<24?o+"h ago":n<7?n+"d ago":t.toLocaleDateString()}catch{return String(e)}}_getTimeGroup(e){if(!e)return"Other";try{let t=new Date(e),i=new Date,a=new Date(i.getFullYear(),i.getMonth(),i.getDate()),s=new Date(a);s.setDate(s.getDate()-1);let r=new Date(a);return r.setDate(r.getDate()-7),t>=a?"Today":t>=s?"Yesterday":t>=r?"This Week":"Earlier"}catch{return"Other"}}_escapeHTML(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getSeverityColor(e){return Qe[e]||Qe.info}_getCategory(e){return e.category||e.type||"system"}_switchTab(e){this._activeTab=e,this.render()}_setCategoryFilter(e){this._categoryFilter=e,this.render()}_togglePanel(){this._panelOpen=!this._panelOpen,this.render()}_bindEvents(){let e=this.shadowRoot;e.querySelectorAll(".tab").forEach(a=>{a.addEventListener("click",()=>{this._switchTab(a.dataset.tab)})}),e.querySelectorAll(".cat-btn").forEach(a=>{a.addEventListener("click",()=>{this._setCategoryFilter(a.dataset.cat)})}),e.querySelectorAll(".ack-btn").forEach(a=>{a.addEventListener("click",s=>{s.stopPropagation(),this._acknowledgeNotification(a.dataset.id)})}),e.querySelectorAll(".unread-btn").forEach(a=>{a.addEventListener("click",s=>{s.stopPropagation(),this._unacknowledgeNotification(a.dataset.id)})});let t=e.querySelector(".ack-all-btn");t&&t.addEventListener("click",()=>{this._acknowledgeAll()});let i=e.querySelector(".bell-icon");i&&i.addEventListener("click",()=>{this._togglePanel()}),e.querySelectorAll(".toggle input").forEach(a=>{a.addEventListener("change",()=>{this._toggleTrigger(a.dataset.triggerId,a.checked)})}),e.querySelectorAll(".dismiss-btn").forEach(a=>{a.addEventListener("click",s=>{s.stopPropagation(),this._acknowledgeNotification(a.dataset.id)})})}_renderBellIcon(){let e=this._summary.unacknowledged||0;return`
|
|
9049
8902
|
<div class="bell-container">
|
|
9050
8903
|
<button class="bell-icon" title="${e} unread notifications">
|
|
9051
8904
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
@@ -9081,8 +8934,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
9081
8934
|
</div>
|
|
9082
8935
|
`}_renderNotificationList(){let e=[...this._notifications].sort((s,r)=>new Date(r.timestamp)-new Date(s.timestamp));if(this._categoryFilter!=="all"&&(e=e.filter(s=>this._getCategory(s)===this._categoryFilter)),e.length===0)return'<div class="empty-state">No notifications</div>';let t={};for(let s of e){let r=this._getTimeGroup(s.timestamp);t[r]||(t[r]=[]),t[r].push(s)}let i=["Today","Yesterday","This Week","Earlier","Other"],a="";for(let s of i)!t[s]||t[s].length===0||(a+=`<div class="time-group-label">${s}</div>`,a+=t[s].map(r=>{let o=r.acknowledged,n=this._getSeverityColor(r.severity),l=this._getCategory(r),c=vt[l]||{label:l,icon:"?"};return`
|
|
9083
8936
|
<div class="notif-row ${o?"acknowledged":""}">
|
|
9084
|
-
<span class="severity-dot" style="background: ${n};"
|
|
9085
|
-
<span class="severity-text">${this._escapeHTML(Kt[r.severity]||String(r.severity??"unknown"))}</span>
|
|
8937
|
+
<span class="severity-dot" style="background: ${n};" title="${this._escapeHTML(r.severity)}"></span>
|
|
9086
8938
|
<span class="cat-icon" title="${this._escapeHTML(c.label)}">${c.icon}</span>
|
|
9087
8939
|
<span class="notif-time">${this._formatTime(r.timestamp)}</span>
|
|
9088
8940
|
<span class="notif-message">${this._escapeHTML(r.message)}</span>
|
|
@@ -9339,15 +9191,6 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
9339
9191
|
flex-shrink: 0;
|
|
9340
9192
|
}
|
|
9341
9193
|
|
|
9342
|
-
.severity-text {
|
|
9343
|
-
font-size: 9px;
|
|
9344
|
-
font-weight: 700;
|
|
9345
|
-
letter-spacing: 0.04em;
|
|
9346
|
-
color: var(--loki-text-muted);
|
|
9347
|
-
flex-shrink: 0;
|
|
9348
|
-
width: 30px;
|
|
9349
|
-
}
|
|
9350
|
-
|
|
9351
9194
|
.cat-icon {
|
|
9352
9195
|
width: 22px;
|
|
9353
9196
|
height: 22px;
|
|
@@ -10523,7 +10366,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
10523
10366
|
</div>
|
|
10524
10367
|
`:""}
|
|
10525
10368
|
</div>
|
|
10526
|
-
`;let x=this.shadowRoot.getElementById("scan-btn");x&&x.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-score")||customElements.define("loki-quality-score",ge);var ft=["understand","guardrail","migrate","verify"],bt={understand:"Understand",guardrail:"Guardrail",migrate:"Migrate",verify:"Verify"},
|
|
10369
|
+
`;let x=this.shadowRoot.getElementById("scan-btn");x&&x.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-score")||customElements.define("loki-quality-score",ge);var ft=["understand","guardrail","migrate","verify"],bt={understand:"Understand",guardrail:"Guardrail",migrate:"Migrate",verify:"Verify"},Kt={understand:"#5b9bd5",guardrail:"#e8b84a",migrate:"#5bb870",verify:"#5bc8c8"},me=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._migration=null,this._migrations=[],this._loading=!0,this._error=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._fetchMigrations(),this._poll=b({loadFn:()=>this._fetchData(),intervalMs:15e3,element:this,immediate:!1})}disconnectedCallback(){super.disconnectedCallback(),this._poll&&(this._poll.stop(),this._poll=null)}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._fetchMigrations()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _fetchMigrations(){let e=this._api;try{let t=await e._get("/api/migration/list");if(e!==this._api)return;this._migrations=Array.isArray(t)?t:t.migrations||[],this._error=null;let i=this._migrations.find(a=>a.status==="in_progress"||a.status==="active");if(i){if(await this._fetchStatus(i.migration_id||i.id),e!==this._api)return}else this._migration=null}catch(t){if(e!==this._api)return;this._error=t.message,this._migrations=[],this._migration=null}this._loading=!1,this.render()}async _fetchStatus(e){let t=this._api;try{let i=await t._get(`/api/migration/${encodeURIComponent(e)}/status`);if(t!==this._api)return;this._migration=i,this._error=null}catch(i){if(t!==this._api)return;this._error=i.message}}async _fetchData(){let e=this._api,t=this._migration&&(this._migration.migration_id||this._migration.id);if(t){if(await this._fetchStatus(t),e!==this._api)return;this.render()}else await this._fetchMigrations()}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"):""}_getPhaseIcon(e,t,i){return(i||[]).includes(e)?"[x]":e===t?"[>]":"[ ]"}_getPhaseIndex(e){let t=ft.indexOf(e);return t>=0?t:0}_renderPhaseBar(e,t){let i=t||[];return ft.map(a=>{let s=i.includes(a),r=a===e,o=Kt[a],n=s?"1":r?"0.7":"0.2",l=this._getPhaseIcon(a,e,t);return`
|
|
10527
10370
|
<div class="phase-segment">
|
|
10528
10371
|
<div class="phase-bar-fill" style="background:${o};opacity:${n};"></div>
|
|
10529
10372
|
<div class="phase-label">
|
|
@@ -10946,7 +10789,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
10946
10789
|
<div class="section-label">Migrations</div>
|
|
10947
10790
|
${this._renderMigrationList()}
|
|
10948
10791
|
</div>
|
|
10949
|
-
`}};customElements.get("loki-migration-dashboard")||customElements.define("loki-migration-dashboard",me);var
|
|
10792
|
+
`}};customElements.get("loki-migration-dashboard")||customElements.define("loki-migration-dashboard",me);var Vt=[["claude-opus","claude"],["claude-sonnet","claude"],["claude-haiku","claude"],["opus","claude"],["sonnet","claude"],["haiku","claude"],["claude","claude"],["gpt-4","codex"],["gpt-5","codex"],["gpt","codex"],["codex","codex"],["o1","codex"],["o3","codex"],["cline","cline"],["aider","aider"]];function Yt(d){if(d==null)return null;switch(d%4){case 0:return{tier:"planning",model:"opus",provider:"claude"};case 1:return{tier:"development",model:"sonnet",provider:"claude"};case 2:return{tier:"development",model:"sonnet",provider:"claude"};case 3:return{tier:"fast",model:"haiku",provider:"claude"};default:return{tier:"development",model:"sonnet",provider:"claude"}}}function Wt(d,e){if(e!=null){let i=Yt(e);if(i)return i.provider}let t=(d||"").toLowerCase();for(let[i,a]of Vt)if(t.includes(i))return a;return"unknown"}var ve=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._api=null,this._pollInterval=null,this._activeTab="heatmap",this._activity=[],this._tools=[],this._cost={},this._context={},this._trends=[],this._toolTimeRange="7d",this._connected=!1,this._loading=!1,this._loadedOnce=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _fetchActivity(e=this._api){let t=e.baseUrl||window.location.origin,i=new AbortController,a=setTimeout(()=>i.abort(),1e4);try{let s=await fetch(`${t}/api/activity?limit=1000`,{signal:i.signal});if(clearTimeout(a),!s.ok)throw new Error(`Activity API ${s.status}`);return s.json()}catch(s){throw clearTimeout(a),s}}async _loadData(){if(!this.isConnected||this._loading)return;let e=this._api;this._loading=!0;try{let t=await Promise.allSettled([this._fetchActivity(e),e.getToolEfficiency(50),e.getCost(),e.getContext(),e.getLearningTrends({timeRange:this._toolTimeRange})]);if(e!==this._api)return;if(t[0].status==="fulfilled"&&(this._activity=t[0].value||[]),t[1].status==="fulfilled"&&(this._tools=t[1].value||[]),t[2].status==="fulfilled"&&(this._cost=t[2].value||{}),t[3].status==="fulfilled"&&(this._context=t[3].value||{}),t[4].status==="fulfilled"){let i=t[4].value||{};this._trends=Array.isArray(i)?i:i.dataPoints||[]}this._connected=t.some(i=>i.status==="fulfilled"),this._loadedOnce=!0,this.render()}finally{this._loading=!1}}_hasAnyData(){let e=Array.isArray(this._activity)?this._activity.length:0,t=Array.isArray(this._tools)?this._tools.length:0,i=this._cost&&this._cost.by_model?Object.keys(this._cost.by_model).length:0,a=this._context||{},r=(a.totals||{}).iterations_tracked||a.total_iterations||a.iteration||0;return e>0||t>0||i>0||r>0}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_computeHeatmap(){let e={},t=Array.isArray(this._activity)?this._activity:[];for(let c of t){let p=c.timestamp||c.ts||c.created_at;if(!p)continue;let u=new Date(p);if(isNaN(u.getTime()))continue;let m=this._localDateKey(u);e[m]=(e[m]||0)+1}let i=new Date;i.setHours(0,0,0,0);let a=i.getDay(),s=new Date(i),r=new Date(i);r.setDate(r.getDate()-(52*7+a));let o=[],n=new Date(r),l=0;for(;n<=s;){let c=this._localDateKey(n),p=e[c]||0;p>l&&(l=p),o.push({date:c,count:p,day:n.getDay()}),n.setDate(n.getDate()+1)}return{cells:o,maxCount:l}}_getHeatmapLevel(e,t){if(e===0||t===0)return 0;let i=e/t;return i<=.25?1:i<=.5?2:i<=.75?3:4}_renderHeatmap(){let{cells:e,maxCount:t}=this._computeHeatmap(),i=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],a=["","Mon","","Wed","","Fri",""],s=[],r=-1,o=-1;for(let p=0;p<e.length;p++){e[p].day===0&&o++;let u=new Date(e[p].date).getMonth();u!==r&&(s.push({month:i[u],col:Math.max(o,1)}),r=u)}let n=s.map(p=>`<span class="heatmap-month" style="grid-column: ${p.col}">${p.month}</span>`).join(""),l=e.map(p=>`<div class="heatmap-cell level-${this._getHeatmapLevel(p.count,t)}" title="${p.date}: ${p.count} activities"></div>`).join(""),c=a.map(p=>`<span class="heatmap-day-label">${p}</span>`).join("");return`
|
|
10950
10793
|
<div class="heatmap-container">
|
|
10951
10794
|
<div class="heatmap-months">${n}</div>
|
|
10952
10795
|
<div class="heatmap-body">
|
|
@@ -10996,7 +10839,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
10996
10839
|
<div class="sparkline-label">Activity Trend (hourly)</div>
|
|
10997
10840
|
<div class="sparkline">${s}</div>
|
|
10998
10841
|
</div>
|
|
10999
|
-
`}_computeProviders(){let e=this._cost.by_model||{},t={};for(let[r,o]of Object.entries(e)){let n=
|
|
10842
|
+
`}_computeProviders(){let e=this._cost.by_model||{},t={};for(let[r,o]of Object.entries(e)){let n=Wt(r);t[n]||(t[n]={cost:0,tokens:0,iterations:0,models:[]});let l=o.cost_usd||0,c=(o.input_tokens||0)+(o.output_tokens||0);t[n].cost+=l,t[n].tokens+=c,t[n].models.push(r)}let a=(this._context.totals||{}).iterations_tracked||this._context.total_iterations||this._context.iteration||0,s=this._cost.estimated_cost_usd||0;for(let r of Object.values(t))if(s>0&&a>0){let o=r.cost/s;r.iterations=Math.round(o*a)}return t}_renderProviders(){let e=this._computeProviders(),t={claude:{label:"Claude",color:"var(--loki-accent)"},codex:{label:"Codex",color:"var(--loki-success)"},cline:{label:"Cline",color:"var(--loki-info)"},aider:{label:"Aider",color:"var(--loki-blue)"},unknown:{label:"Other",color:"var(--loki-text-muted)"}},i=Object.entries(e);return i.length===0?'<div class="empty-state">No provider activity yet. Start a build to compare providers side by side.</div>':`
|
|
11000
10843
|
<div class="provider-grid">
|
|
11001
10844
|
${i.map(([a,s])=>{let r=t[a]||t.unknown,o=s.iterations>0?(s.cost/s.iterations).toFixed(4):"--",n=s.iterations>0?Math.round(s.tokens/s.iterations).toLocaleString():"--";return`
|
|
11002
10845
|
<div class="provider-card">
|
|
@@ -11499,7 +11342,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
11499
11342
|
</div>
|
|
11500
11343
|
`}
|
|
11501
11344
|
</div>
|
|
11502
|
-
`,this.shadowRoot.querySelectorAll("[data-tab]").forEach(l=>{l.addEventListener("click",c=>this._handleTabClick(c))});let r=this.shadowRoot.getElementById("tool-time-range");r&&r.addEventListener("change",l=>this._handleTimeRangeChange(l));let o=this.shadowRoot.getElementById("analytics-retry-btn");o&&o.addEventListener("click",()=>this._loadData());let n=this.shadowRoot.getElementById("analytics-overview-btn");n&&n.addEventListener("click",()=>this._navigateToOverview())}_navigateToOverview(){this.dispatchEvent(new CustomEvent("loki-navigate",{detail:{view:"overview"},bubbles:!0,composed:!0}))}};customElements.get("loki-analytics")||customElements.define("loki-analytics",ve);var kt={pass:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"PASS"},fail:{color:"var(--loki-red, #ef4444)",bg:"var(--loki-red-muted, rgba(239, 68, 68, 0.15))",label:"FAIL"},pending:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"PENDING"}};function
|
|
11345
|
+
`,this.shadowRoot.querySelectorAll("[data-tab]").forEach(l=>{l.addEventListener("click",c=>this._handleTabClick(c))});let r=this.shadowRoot.getElementById("tool-time-range");r&&r.addEventListener("change",l=>this._handleTimeRangeChange(l));let o=this.shadowRoot.getElementById("analytics-retry-btn");o&&o.addEventListener("click",()=>this._loadData());let n=this.shadowRoot.getElementById("analytics-overview-btn");n&&n.addEventListener("click",()=>this._navigateToOverview())}_navigateToOverview(){this.dispatchEvent(new CustomEvent("loki-navigate",{detail:{view:"overview"},bubbles:!0,composed:!0}))}};customElements.get("loki-analytics")||customElements.define("loki-analytics",ve);var kt={pass:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"PASS"},fail:{color:"var(--loki-red, #ef4444)",bg:"var(--loki-red-muted, rgba(239, 68, 68, 0.15))",label:"FAIL"},pending:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"PENDING"}};function Qt(d){if(!d)return"Never";try{return new Date(d).toLocaleString([],{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return"Unknown"}}function Xt(d){if(!d||d.length===0)return{pass:0,fail:0,pending:0,total:0};let e={pass:0,fail:0,pending:0,total:d.length};for(let t of d){let i=(t.status||"pending").toLowerCase();i==="pass"?e.pass++:i==="fail"?e.fail++:e.pending++}return e}var fe=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._gates=[],this._evidence={blocked:!1},this._policy=null,this._pollInterval=null,this._lastDataHash=null,this._scanning=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_policyLine(e){if(!Array.isArray(this._policy)||!e)return"";let i={"Static Analysis":"static_analysis","Test Suite":"test_coverage","Blind Code Review":"code_review","Anti-Sycophancy":"anti_sycophancy","Mock Integrity":"mock_integrity","Test Mutation":"mutation_integrity","Documentation Coverage":"doc_coverage","Magic Modules Debate":"magic_debate"}[e];if(!i)return"";let a=this._policy.find(l=>l&&l.gate===i);if(!a||!a.mode)return"";let s=a.mode==="blocking",r=a.audit_hits===null||a.audit_hits===void 0?"not measured":`${a.audit_hits} hit${a.audit_hits===1?"":"s"}`,o=s?"BLOCKS":"advisory",n=!s&&a.promote_with?` -- promote with ${this._escapeHtml(a.promote_with)}`:"";return`<div class="gate-meta gate-policy">${o} · ${r}${n}</div>`}async _loadData(){let e=this._api;try{this._loading=!0;let t=await e._get("/api/council/gate");if(e!==this._api)return;let i=t?.gates||t||[],a=t?.evidence||{blocked:!1},s=null;try{let o=await e._get("/api/gate-policy");if(e!==this._api)return;s=Array.isArray(o?.gates)?o.gates:null}catch{s=null}let r=JSON.stringify({gates:i,evidence:a,policy:s});if(r===this._lastDataHash)return;this._lastDataHash=r,this._gates=Array.isArray(i)?i:[],this._evidence=a,this._policy=s,this._error=null}catch(t){if(e!==this._api)return;this._error||(this._error=`Failed to load quality gates: ${t.message}`)}finally{this._loading=!1}this.render()}async _triggerScan(){if(this._scanning)return;let e=this._api;this._scanning=!0,this.render();try{if(await e._post("/api/quality-scan",{},{timeout:3e5}),e!==this._api)return;this._lastDataHash=null,await this._loadData()}catch(t){if(e!==this._api)return;this._error=`Quality scan failed: ${t.message}`}finally{this._scanning=!1,this.render()}}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getStyles(){return`
|
|
11503
11346
|
:host {
|
|
11504
11347
|
display: block;
|
|
11505
11348
|
}
|
|
@@ -11759,7 +11602,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
11759
11602
|
color: var(--loki-text-muted, #939084);
|
|
11760
11603
|
font-size: 13px;
|
|
11761
11604
|
}
|
|
11762
|
-
`}render(){let e=this.shadowRoot;if(!e)return;let t=this._gates,i=
|
|
11605
|
+
`}render(){let e=this.shadowRoot;if(!e)return;let t=this._gates,i=Xt(t),a='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg>',s;this._loading&&t.length===0?s='<div class="loading">Loading quality gates...</div>':t.length===0?s=`
|
|
11763
11606
|
<div class="es">
|
|
11764
11607
|
<div class="es-icon">${a}</div>
|
|
11765
11608
|
<div class="es-title">No gate results yet</div>
|
|
@@ -11774,7 +11617,8 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
11774
11617
|
<span class="gate-badge" style="background: ${m.bg}; color: ${m.color};">${m.label}</span>
|
|
11775
11618
|
</div>
|
|
11776
11619
|
${p.description?`<div class="gate-description">${this._escapeHtml(p.description)}</div>`:""}
|
|
11777
|
-
<div class="gate-meta">Last checked: ${
|
|
11620
|
+
<div class="gate-meta">Last checked: ${Qt(p.last_checked||p.lastChecked)}</div>
|
|
11621
|
+
${this._policyLine(p.name)}
|
|
11778
11622
|
</div>
|
|
11779
11623
|
`}).join("")}</div>`;let r="",o=this._evidence||{};if(o.blocked){let c={empty_diff:"No changes were shipped (empty diff vs run start).",tests_red:"Tests ran and were red.",empty_diff_and_tests_red:"No changes shipped and tests were red.",no_evidence_of_completion:"No evidence of completion."},p=o.error?this._escapeHtml(o.error):c[o.reason]||this._escapeHtml(o.reason||"Completion blocked."),u=Array.isArray(o.failures)?o.failures:[],m=u.length?`<ul class="evidence-failures">${u.map(g=>`<li>${this._escapeHtml(g)}</li>`).join("")}</ul>`:"";r=`
|
|
11780
11624
|
<div class="evidence-banner">
|
|
@@ -11809,7 +11653,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
11809
11653
|
${s}
|
|
11810
11654
|
${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
|
|
11811
11655
|
</div>
|
|
11812
|
-
`;let l=e.getElementById("gates-scan-btn");l&&l.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-gates")||customElements.define("loki-quality-gates",fe);var G={reason:{color:"var(--loki-blue, #3b82f6)",label:"Reason",description:"Analyzing requirements and planning approach"},act:{color:"var(--loki-green, #22c55e)",label:"Act",description:"Implementing changes and executing tasks"},reflect:{color:"var(--loki-purple, #a78bfa)",label:"Reflect",description:"Reviewing results and evaluating quality"},verify:{color:"var(--loki-yellow, #eab308)",label:"Verify",description:"Running tests and validating correctness"}},Xe=["reason","act","reflect","verify"];function Ve(d){if(d==null||d<0)return"--";if(d<1e3)return`${d}ms`;let e=Math.floor(d/1e3);if(e<60)return`${e}s`;let t=Math.floor(e/60),i=e%60;if(t<60)return`${t}m ${i}s`;let a=Math.floor(t/60),s=t%60;return`${a}h ${s}m`}function
|
|
11656
|
+
`;let l=e.getElementById("gates-scan-btn");l&&l.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-gates")||customElements.define("loki-quality-gates",fe);var G={reason:{color:"var(--loki-blue, #3b82f6)",label:"Reason",description:"Analyzing requirements and planning approach"},act:{color:"var(--loki-green, #22c55e)",label:"Act",description:"Implementing changes and executing tasks"},reflect:{color:"var(--loki-purple, #a78bfa)",label:"Reflect",description:"Reviewing results and evaluating quality"},verify:{color:"var(--loki-yellow, #eab308)",label:"Verify",description:"Running tests and validating correctness"}},Xe=["reason","act","reflect","verify"];function Ve(d){if(d==null||d<0)return"--";if(d<1e3)return`${d}ms`;let e=Math.floor(d/1e3);if(e<60)return`${e}s`;let t=Math.floor(e/60),i=e%60;if(t<60)return`${t}m ${i}s`;let a=Math.floor(t/60),s=t%60;return`${a}h ${s}m`}function Zt(d){if(!d||d.length===0)return[];let e=d.reduce((t,i)=>t+(i.duration_ms||0),0);return e===0?d.map(t=>({phase:t.phase,pct:100/d.length,duration:0})):d.map(t=>({phase:t.phase,pct:(t.duration_ms||0)/e*100,duration:t.duration_ms||0}))}function ei(d){return d==null?"--":d>=1e6?(d/1e6).toFixed(1)+"M":d>=1e3?(d/1e3).toFixed(1)+"K":String(d)}var be=class extends v{static get observedAttributes(){return["run-id","api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._timeline=null,this._pollInterval=null,this._selectedPhase=null,this._cycleHistory=[]}get runId(){let e=this.getAttribute("run-id");return e?parseInt(e,10):null}set runId(e){e!=null?this.setAttribute("run-id",String(e)):this.removeAttribute("run-id")}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="run-id"&&this._loadData(),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this.runId;if(e==null){this._timeline=null,this.render();return}let t=this._api;try{this._loading=!0;let i=await t._get(`/api/v2/runs/${e}/timeline`);if(t!==this._api)return;this._timeline=i,this._cycleHistory=i.history||[],this._error=null}catch(i){if(t!==this._api)return;i.message&&(i.message.includes("404")||i.message.includes("Not Found"))?(this._timeline=null,this._error=null):this._error=`Failed to load timeline: ${i.message}`}finally{this._loading=!1}this.render()}_selectPhase(e){this._selectedPhase=this._selectedPhase===e?null:e,this.render()}_bindEvents(){let e=this.shadowRoot;e.querySelectorAll(".phase-segment-interactive").forEach(t=>{t.addEventListener("click",()=>{this._selectPhase(t.dataset.phase)})}),e.querySelectorAll(".legend-item-interactive").forEach(t=>{t.addEventListener("click",()=>{this._selectPhase(t.dataset.phase)})}),e.querySelectorAll(".close-detail").forEach(t=>{t.addEventListener("click",i=>{i.stopPropagation(),this._selectedPhase=null,this.render()})})}_getStyles(){return`
|
|
11813
11657
|
:host {
|
|
11814
11658
|
display: block;
|
|
11815
11659
|
}
|
|
@@ -12128,7 +11972,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
12128
11972
|
</div>
|
|
12129
11973
|
<div class="detail-metric">
|
|
12130
11974
|
<span class="detail-metric-label">Tokens Used</span>
|
|
12131
|
-
<span class="detail-metric-value">${
|
|
11975
|
+
<span class="detail-metric-value">${ei(a?.tokens_used)}</span>
|
|
12132
11976
|
</div>
|
|
12133
11977
|
<div class="detail-metric">
|
|
12134
11978
|
<span class="detail-metric-label">Quality</span>
|
|
@@ -12146,7 +11990,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
12146
11990
|
<div class="history-label">Past Cycles (${this._cycleHistory.length} total)</div>
|
|
12147
11991
|
<div class="history-cycles">${t}</div>
|
|
12148
11992
|
</div>
|
|
12149
|
-
`}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}render(){let e=this.shadowRoot;if(!e)return;let t=this.runId,i=this._timeline,a=i?.phases||[],s=i?.current_phase||null,r=
|
|
11993
|
+
`}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}render(){let e=this.shadowRoot;if(!e)return;let t=this.runId,i=this._timeline,a=i?.phases||[],s=i?.current_phase||null,r=Zt(a),o;if(this._loading&&!i)o='<div class="loading">Loading timeline...</div>';else if(t==null)o=this._renderPlaceholderTimeline();else if(a.length===0)o=this._renderPlaceholderTimeline();else{let n=r.map(u=>{let m=G[u.phase]||{color:"var(--loki-text-muted)",label:u.phase},g=s===u.phase,x=this._selectedPhase===u.phase;return`<div class="phase-segment-interactive ${g?"current":""} ${x?"selected":""}"
|
|
12150
11994
|
data-phase="${u.phase}"
|
|
12151
11995
|
style="width: ${Math.max(u.pct,2)}%; background: ${m.color};"
|
|
12152
11996
|
title="${m.label}: ${Ve(u.duration)}">
|
|
@@ -12171,7 +12015,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
12171
12015
|
${o}
|
|
12172
12016
|
${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
|
|
12173
12017
|
</div>
|
|
12174
|
-
`,this._bindEvents()}};customElements.get("loki-rarv-timeline")||customElements.define("loki-rarv-timeline",be);function xt(d){if(!d||typeof d!="object")return null;let e=d.freshness_s;return typeof e!="number"||!Number.isFinite(e)||e<0?null:e}function _t(d){if(!Array.isArray(d))return null;let e=null;for(let t of d){let i=xt(t);i!==null&&(e===null||i<e)&&(e=i)}return e}function yt(d={}){let{payload:e=null,receivedAtMs:t=null,nowMs:i=Date.now(),staleAfterS:a=120}=d,s=xt(e),r=null,o="none";return s!==null?(r=s,o="server"):typeof t=="number"&&Number.isFinite(t)&&(r=Math.max(0,Math.floor((i-t)/1e3)),o="client"),{known:r!==null,ageS:r,source:o,isStale:r===null?null:r>=a,staleAfterS:a}}function
|
|
12018
|
+
`,this._bindEvents()}};customElements.get("loki-rarv-timeline")||customElements.define("loki-rarv-timeline",be);function xt(d){if(!d||typeof d!="object")return null;let e=d.freshness_s;return typeof e!="number"||!Number.isFinite(e)||e<0?null:e}function _t(d){if(!Array.isArray(d))return null;let e=null;for(let t of d){let i=xt(t);i!==null&&(e===null||i<e)&&(e=i)}return e}function yt(d={}){let{payload:e=null,receivedAtMs:t=null,nowMs:i=Date.now(),staleAfterS:a=120}=d,s=xt(e),r=null,o="none";return s!==null?(r=s,o="server"):typeof t=="number"&&Number.isFinite(t)&&(r=Math.max(0,Math.floor((i-t)/1e3)),o="client"),{known:r!==null,ageS:r,source:o,isStale:r===null?null:r>=a,staleAfterS:a}}function ti(d){if(!d||!d.known||typeof d.ageS!="number")return"unknown";let e=d.ageS;return e<60?`${e}s ago`:e<3600?`${Math.floor(e/60)}m ago`:e<86400?`${Math.floor(e/3600)}h ago`:`${Math.floor(e/86400)}d ago`}function Ze(d){if(!d||!d.known)return"Data age unknown";let e=d.source==="client"?" (receive time)":"",t=d.isStale?" - STALE":"";return`Updated ${ti(d)}${e}${t}`}var wt={running:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"Running"},completed:{color:"var(--loki-blue, #3b82f6)",bg:"var(--loki-blue-muted, rgba(59, 130, 246, 0.15))",label:"Completed"},failed:{color:"var(--loki-red, #ef4444)",bg:"var(--loki-red-muted, rgba(239, 68, 68, 0.15))",label:"Failed"},cancelled:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"Cancelled"},pending:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Pending"},queued:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Queued"},building:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"Building"},bootstrap:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"Bootstrap"},complete:{color:"var(--loki-blue, #3b82f6)",bg:"var(--loki-blue-muted, rgba(59, 130, 246, 0.15))",label:"Completed"},stopped:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"Stopped"},paused:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"Paused"},unknown:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Unknown"}};function ii(d,e,t){let i=d;if(i==null&&e){let l=new Date(e).getTime();i=(t?new Date(t).getTime():Date.now())-l}if(i==null||i<0)return"--";if(i<1e3)return`${i}ms`;let a=Math.floor(i/1e3);if(a<60)return`${a}s`;let s=Math.floor(a/60),r=a%60;if(s<60)return`${s}m ${r}s`;let o=Math.floor(s/60),n=s%60;return`${o}h ${n}m`}function ai(d){if(!d)return"--";try{return new Date(d).toLocaleString([],{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return String(d)}}var ke=class extends v{static get observedAttributes(){return["api-url","project-id","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._runs=[],this._pollInterval=null,this._lastDataHash=null,this._emptyReason=null,this._source=null,this._freshPayload=null,this._changedAtMs=null}_freshness(){let e=t=>{if(!t)return!1;if(t.current===!0)return!0;let i=String(t.status||"").toLowerCase();return i==="running"||i==="in_progress"||i==="active"};return yt({payload:this._freshPayload,receivedAtMs:this._changedAtMs,staleAfterS:this._runs.some(e)?void 0:1/0})}_renderFreshness(){let e=this.shadowRoot&&this.shadowRoot.getElementById("freshness");if(!e)return;let t=this._freshness();e.className=`freshness ${t.known?t.isStale?"is-stale":"":"is-unknown"}`,e.dataset.source=t.source,e.dataset.stale=t.isStale===null?"unknown":String(t.isStale),e.textContent=Ze(t)}get projectId(){let e=this.getAttribute("project-id");return e?parseInt(e,10):null}set projectId(e){e!=null?this.setAttribute("project-id",String(e)):this.removeAttribute("project-id")}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="project-id"&&this._loadData(),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=this.projectId,i=t!=null?`?project_id=${t}`:"",a=await e._get(`/api/v2/runs${i}`);if(e!==this._api)return;let s=a?.runs||a||[],r=Array.isArray(s)?s:[];this._freshPayload=a&&typeof a=="object"&&!Array.isArray(a)&&"freshness_s"in a?a:{freshness_s:_t(r)};let o=JSON.stringify(s),n=o!==this._lastDataHash||!!this._error;n&&(this._lastDataHash=o,this._runs=r,this._changedAtMs=Date.now()),this._emptyReason=a&&!Array.isArray(a)&&a.reason||null,this._source=a&&!Array.isArray(a)&&a.source||null,this._error=null,this._loading=!1,n?this.render():this._renderFreshness();return}catch(t){if(e!==this._api)return;this._error||(this._error=`Failed to load runs: ${t.message}`)}finally{this._loading=!1}this.render()}async _cancelRun(e){try{await this._api._post(`/api/v2/runs/${e}/cancel`),await this._loadData()}catch(t){this._error=`Cancel failed: ${t.message}`,this.render()}}async _replayRun(e){try{await this._api._post(`/api/v2/runs/${e}/replay`),await this._loadData()}catch(t){this._error=`Replay failed: ${t.message}`,this.render()}}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getStyles(){return`
|
|
12175
12019
|
:host {
|
|
12176
12020
|
display: block;
|
|
12177
12021
|
}
|
|
@@ -12345,13 +12189,13 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
12345
12189
|
align-items: center;
|
|
12346
12190
|
gap: 10px;
|
|
12347
12191
|
}
|
|
12348
|
-
`}render(){let e=this.shadowRoot;if(!e)return;let t=this._runs,i;if(this._loading&&t.length===0)i='<div class="loading">Loading runs...</div>';else if(this._error&&t.length===0)i=`<div class="empty-state error-state" role="status" aria-live="polite">Could not load runs.<div class="error-state-detail">${this._escapeHtml(this._error)}</div></div>`;else if(t.length===0){let r=this._emptyReason?`<div class="empty-reason">${this._escapeHtml(this._emptyReason)}</div>`:'<div class="empty-reason">The server did not state a reason.</div>',o=this._source?`<div class="empty-source">Read from: ${this._escapeHtml(Array.isArray(this._source)?this._source.join(", "):this._source)}</div>`:"";i=`<div class="empty-state" role="status" aria-live="polite">No runs found.${r}${o}</div>`}else{let r=t.map(o=>{let n=(o.status||"pending").toLowerCase(),l=wt[n]||wt.pending,c=n==="running",p=n==="completed"||n==="failed"||n==="cancelled",u=
|
|
12192
|
+
`}render(){let e=this.shadowRoot;if(!e)return;let t=this._runs,i;if(this._loading&&t.length===0)i='<div class="loading">Loading runs...</div>';else if(this._error&&t.length===0)i=`<div class="empty-state error-state" role="status" aria-live="polite">Could not load runs.<div class="error-state-detail">${this._escapeHtml(this._error)}</div></div>`;else if(t.length===0){let r=this._emptyReason?`<div class="empty-reason">${this._escapeHtml(this._emptyReason)}</div>`:'<div class="empty-reason">The server did not state a reason.</div>',o=this._source?`<div class="empty-source">Read from: ${this._escapeHtml(Array.isArray(this._source)?this._source.join(", "):this._source)}</div>`:"";i=`<div class="empty-state" role="status" aria-live="polite">No runs found.${r}${o}</div>`}else{let r=t.map(o=>{let n=(o.status||"pending").toLowerCase(),l=wt[n]||wt.pending,c=n==="running",p=n==="completed"||n==="failed"||n==="cancelled",u=ii(o.duration_ms,o.started_at,o.ended_at);return`
|
|
12349
12193
|
<tr>
|
|
12350
12194
|
<td><span class="run-id">#${o.id}</span></td>
|
|
12351
12195
|
<td>${this._escapeHtml(o.project_name||o.project||(o.project_id?`Project #${o.project_id}`:"--"))}</td>
|
|
12352
12196
|
<td><span class="status-badge" style="background: ${l.bg}; color: ${l.color};">${l.label}</span></td>
|
|
12353
12197
|
<td>${this._escapeHtml(o.trigger||o.trigger_type||"--")}</td>
|
|
12354
|
-
<td>${
|
|
12198
|
+
<td>${ai(o.started_at)}</td>
|
|
12355
12199
|
<td>${u}</td>
|
|
12356
12200
|
<td>
|
|
12357
12201
|
<div class="actions-cell">
|
|
@@ -12391,7 +12235,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
12391
12235
|
${i}
|
|
12392
12236
|
${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
|
|
12393
12237
|
</div>
|
|
12394
|
-
`,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("refresh-btn");t&&t.addEventListener("click",()=>this._loadData()),e.querySelectorAll('[data-action="cancel"]').forEach(i=>{i.addEventListener("click",()=>this._cancelRun(i.dataset.runId))}),e.querySelectorAll('[data-action="replay"]').forEach(i=>{i.addEventListener("click",()=>this._replayRun(i.dataset.runId))})}};customElements.get("loki-run-manager")||customElements.define("loki-run-manager",ke);var $t={running:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"Running"},stopped:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"Stopped"},active:{color:"var(--loki-blue, #3b82f6)",bg:"var(--loki-blue-muted, rgba(59, 130, 246, 0.15))",label:"Idle"},missing:{color:"var(--loki-red, #ef4444)",bg:"var(--loki-red-muted, rgba(239, 68, 68, 0.15))",label:"Missing"},unknown:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Unknown"}};function
|
|
12238
|
+
`,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("refresh-btn");t&&t.addEventListener("click",()=>this._loadData()),e.querySelectorAll('[data-action="cancel"]').forEach(i=>{i.addEventListener("click",()=>this._cancelRun(i.dataset.runId))}),e.querySelectorAll('[data-action="replay"]').forEach(i=>{i.addEventListener("click",()=>this._replayRun(i.dataset.runId))})}};customElements.get("loki-run-manager")||customElements.define("loki-run-manager",ke);var $t={running:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"Running"},stopped:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"Stopped"},active:{color:"var(--loki-blue, #3b82f6)",bg:"var(--loki-blue-muted, rgba(59, 130, 246, 0.15))",label:"Idle"},missing:{color:"var(--loki-red, #ef4444)",bg:"var(--loki-red-muted, rgba(239, 68, 68, 0.15))",label:"Missing"},unknown:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Unknown"}};function si(d){if(d==null||d<0)return"--";if(d<60)return`${d}s`;let e=Math.floor(d/60),t=d%60;if(e<60)return`${e}m ${t}s`;let i=Math.floor(e/60),a=e%60;return`${i}h ${a}m`}function Et(d){return d==null||isNaN(d)?"$0.00":`$${Number(d).toFixed(2)}`}var xe=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!0,this._error=null,this._api=null,this._runs=[],this._summary=null,this._pollInterval=null,this._lastDataHash=null,this._emptyReason=null,this._source=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let[t,i]=await Promise.all([e._get("/api/fleet/runs"),e._get("/api/fleet/summary")]);if(e!==this._api)return;let a=Array.isArray(t)?t:t?.runs||[],s=JSON.stringify({runs:a,summaryResp:i});if(s===this._lastDataHash&&!this._error)return;this._lastDataHash=s,this._runs=Array.isArray(a)?a:[],this._summary=i||null,this._emptyReason=t&&!Array.isArray(t)&&t.reason||null,this._source=t&&!Array.isArray(t)&&t.source||null,this._error=null}catch(t){if(e!==this._api)return;this._emptyReason=null,this._source=null,this._error||(this._error=`Failed to load fleet: ${t.message}`)}finally{this._loading=!1}this.render()}async _cancelRun(e){if(e&&!(typeof confirm=="function"&&!confirm(`Cancel build "${e}"? This stops the running build.`)))try{await this._api._post(`/api/fleet/runs/${encodeURIComponent(e)}/cancel`),this._lastDataHash=null,await this._loadData()}catch(t){this._error=`Cancel failed: ${t.message}`,this.render()}}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getStyles(){return`
|
|
12395
12239
|
:host { display: block; }
|
|
12396
12240
|
|
|
12397
12241
|
.fleet {
|
|
@@ -12606,7 +12450,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
12606
12450
|
<div class="error-state-detail">${this._escapeHtml(this._error)}</div>
|
|
12607
12451
|
<div class="error-state-hint">This is a read failure, not an empty fleet. Builds may be running.</div>
|
|
12608
12452
|
</div>
|
|
12609
|
-
`;else if(t.length===0){let a=this._emptyReason?`<div class="empty-reason">${this._escapeHtml(this._emptyReason)}</div>`:'<div class="empty-reason">The server did not state a reason, so an unreadable registry is indistinguishable from an idle one here.</div>',s=this._source?`<div class="empty-source">Source: ${this._escapeHtml(Array.isArray(this._source)?this._source.join(", "):String(this._source))}</div>`:"";i=`<div class="empty-state">No registered builds. Run <code>loki start</code> in a project to populate the fleet.${a}${s}</div>`}else{let a=t.map(s=>{let r=(s.status||"unknown").toLowerCase(),o=$t[r]||$t.unknown,n=s.running===!0,l=
|
|
12453
|
+
`;else if(t.length===0){let a=this._emptyReason?`<div class="empty-reason">${this._escapeHtml(this._emptyReason)}</div>`:'<div class="empty-reason">The server did not state a reason, so an unreadable registry is indistinguishable from an idle one here.</div>',s=this._source?`<div class="empty-source">Source: ${this._escapeHtml(Array.isArray(this._source)?this._source.join(", "):String(this._source))}</div>`:"";i=`<div class="empty-state">No registered builds. Run <code>loki start</code> in a project to populate the fleet.${a}${s}</div>`}else{let a=t.map(s=>{let r=(s.status||"unknown").toLowerCase(),o=$t[r]||$t.unknown,n=s.running===!0,l=si(s.duration_seconds),c=s.iteration!=null?s.iteration:0,p=s.phase?this._escapeHtml(s.phase):"--";return`
|
|
12610
12454
|
<tr>
|
|
12611
12455
|
<td>
|
|
12612
12456
|
<div class="project-name">${this._escapeHtml(s.name||"project")}</div>
|
|
@@ -12655,7 +12499,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
12655
12499
|
${i}
|
|
12656
12500
|
${this._error&&t.length>0?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
|
|
12657
12501
|
</div>
|
|
12658
|
-
`,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("refresh-btn");t&&t.addEventListener("click",()=>{this._lastDataHash=null,this._loadData()}),e.querySelectorAll('[data-action="cancel"]').forEach(i=>{i.addEventListener("click",()=>this._cancelRun(i.dataset.id))})}};customElements.get("loki-fleet")||customElements.define("loki-fleet",xe);function
|
|
12502
|
+
`,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("refresh-btn");t&&t.addEventListener("click",()=>{this._lastDataHash=null,this._loadData()}),e.querySelectorAll('[data-action="cancel"]').forEach(i=>{i.addEventListener("click",()=>this._cancelRun(i.dataset.id))})}};customElements.get("loki-fleet")||customElements.define("loki-fleet",xe);function ri(d){if(!d)return"--";try{return new Date(d).toLocaleString([],{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit"})}catch{return String(d)}}function oi(d){let e=new URLSearchParams;for(let[i,a]of Object.entries(d))a!=null&&a!==""&&e.set(i,String(a));let t=e.toString();return t?`?${t}`:""}var _e=class extends v{static get observedAttributes(){return["api-url","limit","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._entries=[],this._emptyReason=null,this._verifyResult=null,this._verifying=!1,this._filters={action:"",resource:"",dateFrom:"",dateTo:""}}get limit(){let e=this.getAttribute("limit");return e?parseInt(e,10):50}set limit(e){this.setAttribute("limit",String(e))}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData()}disconnectedCallback(){super.disconnectedCallback()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="limit"&&this._loadData(),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){let e=this._api;try{this._loading=!0,this.render();let t={limit:this.limit,action:this._filters.action,resource:this._filters.resource,date_from:this._filters.dateFrom,date_to:this._filters.dateTo},i=oi(t),a=await e._get(`/api/v2/audit${i}`);if(e!==this._api)return;this._entries=a?.entries||a||[],this._emptyReason=a&&!Array.isArray(a)&&a.reason||null,this._error=null}catch(t){if(e!==this._api)return;this._emptyReason=null,this._error=`Failed to load audit log: ${t.message}`}finally{this._loading=!1}this.render()}async _verifyIntegrity(){let e=this._api;try{this._verifying=!0,this._verifyResult=null,this.render();let t=await e._get("/api/v2/audit/verify");if(e!==this._api)return;this._verifyResult=t}catch(t){if(e!==this._api)return;this._verifyResult={valid:!1,error:t.message}}finally{this._verifying=!1}this.render()}_onFilterChange(e,t){this._filters[e]=t,this._loadData()}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getStyles(){return`
|
|
12659
12503
|
:host {
|
|
12660
12504
|
display: block;
|
|
12661
12505
|
}
|
|
@@ -12918,7 +12762,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
12918
12762
|
</div>
|
|
12919
12763
|
`;else if(t.length===0)a=`<div class="empty-state">No audit entries found matching filters.${this._emptyReason?`<div class="empty-reason">${this._escapeHtml(this._emptyReason)}</div>`:'<div class="empty-reason">The server did not state a reason.</div>'}</div>`;else{let s=t.map(r=>`
|
|
12920
12764
|
<tr>
|
|
12921
|
-
<td>${
|
|
12765
|
+
<td>${ri(r.timestamp)}</td>
|
|
12922
12766
|
<td>${this._escapeHtml(r.action||"--")}</td>
|
|
12923
12767
|
<td>${this._escapeHtml(r.resource||r.resource_type||"--")}</td>
|
|
12924
12768
|
<td>${this._escapeHtml(r.user||r.actor||"--")}</td>
|
|
@@ -13381,7 +13225,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
13381
13225
|
${s}
|
|
13382
13226
|
${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
|
|
13383
13227
|
</div>
|
|
13384
|
-
`,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("show-create");t&&t.addEventListener("click",()=>{this._showCreateForm=!0,this.render()});let i=e.getElementById("dismiss-token");i&&i.addEventListener("click",()=>{this._newToken=null,this.render()});let a=e.getElementById("submit-create");a&&a.addEventListener("click",()=>{let r=e.getElementById("create-name"),o=e.getElementById("create-role"),n=e.getElementById("create-expiration");this._createName=r?.value||"",this._createRole=o?.value||"read",this._createExpiration=n?.value||"",this._createKey()});let s=e.getElementById("cancel-create");s&&s.addEventListener("click",()=>{this._showCreateForm=!1,this.render()}),e.querySelectorAll('[data-action="delete"]').forEach(r=>{r.addEventListener("click",()=>{this._confirmDeleteId=r.dataset.keyId,this.render()})}),e.querySelectorAll('[data-action="confirm-delete"]').forEach(r=>{r.addEventListener("click",()=>{this._deleteKey(r.dataset.keyId)})}),e.querySelectorAll('[data-action="cancel-delete"]').forEach(r=>{r.addEventListener("click",()=>{this._confirmDeleteId=null,this.render()})}),e.querySelectorAll('[data-action="rotate"]').forEach(r=>{r.addEventListener("click",()=>{this._rotateKeyId=r.dataset.keyId,this.render()})}),e.querySelectorAll('[data-action="confirm-rotate"]').forEach(r=>{r.addEventListener("click",()=>{let o=e.getElementById(`rotate-grace-${r.dataset.keyId}`);this._rotateGracePeriod=o?.value||"24",this._rotateKey(r.dataset.keyId)})}),e.querySelectorAll('[data-action="cancel-rotate"]').forEach(r=>{r.addEventListener("click",()=>{this._rotateKeyId=null,this.render()})})}};customElements.get("loki-api-keys")||customElements.define("loki-api-keys",ye);function
|
|
13228
|
+
`,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("show-create");t&&t.addEventListener("click",()=>{this._showCreateForm=!0,this.render()});let i=e.getElementById("dismiss-token");i&&i.addEventListener("click",()=>{this._newToken=null,this.render()});let a=e.getElementById("submit-create");a&&a.addEventListener("click",()=>{let r=e.getElementById("create-name"),o=e.getElementById("create-role"),n=e.getElementById("create-expiration");this._createName=r?.value||"",this._createRole=o?.value||"read",this._createExpiration=n?.value||"",this._createKey()});let s=e.getElementById("cancel-create");s&&s.addEventListener("click",()=>{this._showCreateForm=!1,this.render()}),e.querySelectorAll('[data-action="delete"]').forEach(r=>{r.addEventListener("click",()=>{this._confirmDeleteId=r.dataset.keyId,this.render()})}),e.querySelectorAll('[data-action="confirm-delete"]').forEach(r=>{r.addEventListener("click",()=>{this._deleteKey(r.dataset.keyId)})}),e.querySelectorAll('[data-action="cancel-delete"]').forEach(r=>{r.addEventListener("click",()=>{this._confirmDeleteId=null,this.render()})}),e.querySelectorAll('[data-action="rotate"]').forEach(r=>{r.addEventListener("click",()=>{this._rotateKeyId=r.dataset.keyId,this.render()})}),e.querySelectorAll('[data-action="confirm-rotate"]').forEach(r=>{r.addEventListener("click",()=>{let o=e.getElementById(`rotate-grace-${r.dataset.keyId}`);this._rotateGracePeriod=o?.value||"24",this._rotateKey(r.dataset.keyId)})}),e.querySelectorAll('[data-action="cancel-rotate"]').forEach(r=>{r.addEventListener("click",()=>{this._rotateKeyId=null,this.render()})})}};customElements.get("loki-api-keys")||customElements.define("loki-api-keys",ye);function ni(d){return d?d.slug&&d.name?`${d.name} (${d.slug})`:d.name||d.slug||"Unknown":"Unknown"}var we=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._tenants=[],this._selectedTenantId=null,this._dropdownOpen=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._outsideClickHandler=e=>{this._dropdownOpen&&!this.contains(e.target)&&(this._dropdownOpen=!1,this.render())},document.addEventListener("click",this._outsideClickHandler)}disconnectedCallback(){super.disconnectedCallback(),this._outsideClickHandler&&(document.removeEventListener("click",this._outsideClickHandler),this._outsideClickHandler=null)}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){let e=this._api;try{this._loading=!0;let t=await e._get("/api/v2/tenants");if(e!==this._api)return;this._tenants=Array.isArray(t)?t:t?.tenants||[],this._error=null}catch(t){if(e!==this._api)return;this._error=`Failed to load tenants: ${t.message}`}finally{this._loading=!1}this.render()}_toggleDropdown(){this._dropdownOpen=!this._dropdownOpen,this.render()}_selectTenant(e,t){this._selectedTenantId=e,this._dropdownOpen=!1,this.render(),this.dispatchEvent(new CustomEvent("tenant-changed",{detail:{tenantId:e,tenantName:t},bubbles:!0,composed:!0}))}_getSelectedTenant(){return this._selectedTenantId==null?null:this._tenants.find(e=>(e.id||e.slug)===this._selectedTenantId)||null}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getStyles(){return`
|
|
13385
13229
|
:host {
|
|
13386
13230
|
display: inline-block;
|
|
13387
13231
|
position: relative;
|
|
@@ -13515,7 +13359,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
13515
13359
|
color: var(--loki-text-muted, #939084);
|
|
13516
13360
|
font-size: 12px;
|
|
13517
13361
|
}
|
|
13518
|
-
`}render(){let e=this.shadowRoot;if(!e)return;let t=this._getSelectedTenant(),i=t?
|
|
13362
|
+
`}render(){let e=this.shadowRoot;if(!e)return;let t=this._getSelectedTenant(),i=t?ni(t):"All Tenants",a=this._dropdownOpen,s="";if(a){let r;if(this._loading)r='<div class="loading-text">Loading tenants...</div>';else if(this._error)r=`<div class="error-text">${this._escapeHtml(this._error)}</div>`;else{let o=this._selectedTenantId==null;r=`
|
|
13519
13363
|
<button class="dropdown-item all-tenants ${o?"selected":""}" data-tenant-id="">
|
|
13520
13364
|
<span class="tenant-name">All Tenants</span>
|
|
13521
13365
|
${o?'<span class="check-mark">*</span>':""}
|
|
@@ -13540,7 +13384,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
13540
13384
|
</button>
|
|
13541
13385
|
${s}
|
|
13542
13386
|
</div>
|
|
13543
|
-
`,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("trigger-btn");t&&t.addEventListener("click",i=>{i.stopPropagation(),this._toggleDropdown()}),e.querySelectorAll(".dropdown-item").forEach(i=>{i.addEventListener("click",a=>{a.stopPropagation();let s=i.dataset.tenantId||null,r=i.dataset.tenantName||null;this._selectTenant(s||null,r||"All Tenants")})})}};customElements.get("loki-tenant-switcher")||customElements.define("loki-tenant-switcher",we);var et={info:{color:"var(--loki-blue, #2F71E3)",label:"INFO",icon:"i"},success:{color:"var(--loki-green, #1FC5A8)",label:"OK",icon:"+"},warning:{color:"var(--loki-yellow, #D4A03C)",label:"WARN",icon:"!"},error:{color:"var(--loki-red, #C45B5B)",label:"ERR",icon:"x"}},
|
|
13387
|
+
`,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("trigger-btn");t&&t.addEventListener("click",i=>{i.stopPropagation(),this._toggleDropdown()}),e.querySelectorAll(".dropdown-item").forEach(i=>{i.addEventListener("click",a=>{a.stopPropagation();let s=i.dataset.tenantId||null,r=i.dataset.tenantName||null;this._selectTenant(s||null,r||"All Tenants")})})}};customElements.get("loki-tenant-switcher")||customElements.define("loki-tenant-switcher",we);var et={info:{color:"var(--loki-blue, #2F71E3)",label:"INFO",icon:"i"},success:{color:"var(--loki-green, #1FC5A8)",label:"OK",icon:"+"},warning:{color:"var(--loki-yellow, #D4A03C)",label:"WARN",icon:"!"},error:{color:"var(--loki-red, #C45B5B)",label:"ERR",icon:"x"}},li=100,$e=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._items=[],this._filter="all",this._api=null,this._pollInterval=null,this._paused=!1,this._lastTimestamp=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/v2/activity");if(e!==this._api)return;let i=t.events||t.activities||[];if(i.length>0){let a=i.filter(s=>!this._lastTimestamp||new Date(s.timestamp)>new Date(this._lastTimestamp)).map(s=>({id:s.id||crypto.randomUUID(),timestamp:s.timestamp||new Date().toISOString(),message:s.message||s.description||"",severity:s.severity||s.level||"info",source:s.source||s.component||"",isNew:!0}));a.length>0&&(this._items=[...a,...this._items].slice(0,li),this._lastTimestamp=a[0].timestamp,setTimeout(()=>{this._items.forEach(s=>s.isNew=!1)},600))}}catch{if(e!==this._api)return;this._items.length===0&&(this._items=this._getDemoItems())}this.render()}_getDemoItems(){let e=Date.now();return[{id:"1",timestamp:new Date(e-2e3).toISOString(),message:"Build iteration #12 started",severity:"info",source:"runner"},{id:"2",timestamp:new Date(e-5e3).toISOString(),message:"Code review passed (3/3 reviewers)",severity:"success",source:"review"},{id:"3",timestamp:new Date(e-8e3).toISOString(),message:"Context window at 78% capacity",severity:"warning",source:"context"},{id:"4",timestamp:new Date(e-12e3).toISOString(),message:"Test suite completed: 42/42 passed",severity:"success",source:"testing"},{id:"5",timestamp:new Date(e-15e3).toISOString(),message:"Verify step complete: changes checked",severity:"info",source:"rarv"}]}_formatTime(e){if(!e)return"";try{return new Date(e).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})}catch{return""}}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getFilteredItems(){return this._filter==="all"?this._items:this._items.filter(e=>e.severity===this._filter)}_setFilter(e){this._filter=e,this.render()}_bindEvents(){let e=this.shadowRoot;e.querySelectorAll(".filter-btn").forEach(i=>{i.addEventListener("click",()=>{this._setFilter(i.dataset.filter)})});let t=e.querySelector(".activity-feed");t&&(t.addEventListener("mouseenter",()=>{this._paused=!0}),t.addEventListener("mouseleave",()=>{this._paused=!1}))}_getStyles(){return`
|
|
13544
13388
|
:host {
|
|
13545
13389
|
display: block;
|
|
13546
13390
|
}
|
|
@@ -13747,7 +13591,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
13747
13591
|
${s}
|
|
13748
13592
|
</div>
|
|
13749
13593
|
</div>
|
|
13750
|
-
`,this._bindEvents(),!this._paused){let r=e.querySelector(".activity-feed");r&&(r.scrollTop=0)}}};customElements.get("loki-activity-stream")||customElements.define("loki-activity-stream",$e);var
|
|
13594
|
+
`,this._bindEvents(),!this._paused){let r=e.querySelector(".activity-feed");r&&(r.scrollTop=0)}}};customElements.get("loki-activity-stream")||customElements.define("loki-activity-stream",$e);var di={claude:{initial:"C",color:"#553DE9",bgColor:"rgba(85, 61, 233, 0.12)"},codex:{initial:"X",color:"#1FC5A8",bgColor:"rgba(31, 197, 168, 0.12)"},cline:{initial:"L",color:"#D4A03C",bgColor:"rgba(212, 160, 60, 0.12)"},aider:{initial:"A",color:"#C45B5B",bgColor:"rgba(196, 91, 91, 0.12)"}},St={healthy:"var(--loki-green, #1FC5A8)",degraded:"var(--loki-yellow, #D4A03C)",down:"var(--loki-red, #C45B5B)",unknown:"var(--loki-text-muted, #939084)"},Ee=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._providers=[],this._expandedProvider=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:1e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/v2/providers/health");if(e!==this._api)return;this._providers=t.providers||[]}catch{if(e!==this._api)return;this._providers.length===0&&(this._providers=this._getDemoData())}this.render()}_getDemoData(){return[{name:"claude",status:"healthy",latency_ms:245,tokens_used:125400,model:"claude-opus-4-7",api_version:"v1",rate_limit:{remaining:45,limit:50},cost_usd:3.42},{name:"codex",status:"degraded",latency_ms:890,tokens_used:45200,model:"gpt-5.3-codex",api_version:"v1",rate_limit:{remaining:12,limit:60},cost_usd:.87},{name:"cline",status:"healthy",latency_ms:320,tokens_used:78600,model:"cline-default",api_version:"v1",rate_limit:{remaining:55,limit:60},cost_usd:1.15}]}_formatTokens(e){return Ne(e)}_formatLatency(e){return st(e)}_formatCost(e){return I(e)}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_toggleExpand(e){this._expandedProvider=this._expandedProvider===e?null:e,this.render()}_bindEvents(){this.shadowRoot.querySelectorAll(".provider-card").forEach(t=>{t.addEventListener("click",()=>{this._toggleExpand(t.dataset.provider)})})}_getStyles(){return`
|
|
13751
13595
|
:host {
|
|
13752
13596
|
display: block;
|
|
13753
13597
|
}
|
|
@@ -13824,16 +13668,6 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
13824
13668
|
flex: 1;
|
|
13825
13669
|
}
|
|
13826
13670
|
|
|
13827
|
-
/* Visible status word: the dot's title was hover-only and so invisible
|
|
13828
|
-
on touch devices and to screen readers. */
|
|
13829
|
-
.status-text {
|
|
13830
|
-
font-size: 10px;
|
|
13831
|
-
text-transform: uppercase;
|
|
13832
|
-
letter-spacing: 0.04em;
|
|
13833
|
-
color: var(--loki-text-muted);
|
|
13834
|
-
flex-shrink: 0;
|
|
13835
|
-
}
|
|
13836
|
-
|
|
13837
13671
|
.status-dot {
|
|
13838
13672
|
width: 10px;
|
|
13839
13673
|
height: 10px;
|
|
@@ -13936,13 +13770,12 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
13936
13770
|
border: 1px solid var(--loki-border, #ECEAE3);
|
|
13937
13771
|
border-radius: 5px;
|
|
13938
13772
|
}
|
|
13939
|
-
`}render(){let e=this.shadowRoot;if(!e)return;let t;this._providers.length===0?t='<div class="empty-state">Provider status will appear once a build starts.</div>':t=`<div class="provider-grid">${this._providers.map(i=>{let a=
|
|
13773
|
+
`}render(){let e=this.shadowRoot;if(!e)return;let t;this._providers.length===0?t='<div class="empty-state">Provider status will appear once a build starts.</div>':t=`<div class="provider-grid">${this._providers.map(i=>{let a=di[i.name]||{initial:(i.name??"?").charAt(0).toUpperCase(),color:"#939084",bgColor:"rgba(147, 144, 132, 0.12)"},s=St[i.status]||St.unknown,r=this._expandedProvider===i.name,o=i.rate_limit?i.rate_limit.remaining/i.rate_limit.limit*100:100,n=o>50?"var(--loki-green)":o>20?"var(--loki-yellow)":"var(--loki-red)";return`
|
|
13940
13774
|
<div class="provider-card ${r?"expanded":""}" data-provider="${this._escapeHtml(i.name)}">
|
|
13941
13775
|
<div class="card-header">
|
|
13942
13776
|
<div class="provider-icon" style="background: ${a.bgColor}; color: ${a.color};">${a.initial}</div>
|
|
13943
13777
|
<span class="provider-name">${this._escapeHtml(i.name)}</span>
|
|
13944
|
-
<
|
|
13945
|
-
<div class="status-dot ${i.status==="healthy"?"pulse":""}" style="background: ${s};" role="img" aria-label="Status: ${this._escapeHtml(i.status??"unknown")}" title="${this._escapeHtml(i.status??"unknown")}"></div>
|
|
13778
|
+
<div class="status-dot ${i.status==="healthy"?"pulse":""}" style="background: ${s};" title="${this._escapeHtml(i.status)}"></div>
|
|
13946
13779
|
</div>
|
|
13947
13780
|
<div class="card-metrics">
|
|
13948
13781
|
<div class="metric">
|
|
@@ -14183,7 +14016,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
14183
14016
|
${i}
|
|
14184
14017
|
</div>
|
|
14185
14018
|
</div>
|
|
14186
|
-
`}};customElements.get("loki-pipeline-view")||customElements.define("loki-pipeline-view",Ce);var Se={episode:{color:"var(--loki-blue, #2F71E3)",shape:"circle",label:"Episode"},pattern:{color:"var(--loki-green, #1FC5A8)",shape:"square",label:"Pattern"},skill:{color:"var(--loki-purple, #553DE9)",shape:"diamond",label:"Skill"}};function
|
|
14019
|
+
`}};customElements.get("loki-pipeline-view")||customElements.define("loki-pipeline-view",Ce);var Se={episode:{color:"var(--loki-blue, #2F71E3)",shape:"circle",label:"Episode"},pattern:{color:"var(--loki-green, #1FC5A8)",shape:"square",label:"Pattern"},skill:{color:"var(--loki-purple, #553DE9)",shape:"diamond",label:"Skill"}};function ci(d,e,t){let i=e/2,a=t/2,s=Math.min(i,a)*.65,r=d.length;return d.map((o,n)=>{let l=2*Math.PI*n/r-Math.PI/2,c=o.importance||.5,p=s*(.5+c*.5);return{...o,x:i+p*Math.cos(l),y:a+p*Math.sin(l)}})}var Ae=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._nodes=[],this._edges=[],this._selectedNode=null,this._api=null,this._pollInterval=null,this._graphWidth=600,this._graphHeight=400}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:15e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/v2/memory/graph");if(e!==this._api)return;this._nodes=t.nodes||[],this._edges=t.edges||[]}catch{if(e!==this._api)return;if(this._nodes.length===0){let t=this._getDemoData();this._nodes=t.nodes,this._edges=t.edges}}this.render()}_getDemoData(){return{nodes:[{id:"ep1",type:"episode",label:"Build iteration #12",importance:.8,details:"Completed scaffolding and initial implementation"},{id:"ep2",type:"episode",label:"Code review #5",importance:.6,details:"Quality gate passed with 3/3 approval"},{id:"ep3",type:"episode",label:"Test failure #3",importance:.7,details:"Integration test timeout resolved"},{id:"pt1",type:"pattern",label:"Error recovery",importance:.9,details:"Retry with exponential backoff pattern"},{id:"pt2",type:"pattern",label:"API design",importance:.7,details:"REST endpoint naming conventions"},{id:"pt3",type:"pattern",label:"Test structure",importance:.5,details:"Arrange-Act-Assert with setup helpers"},{id:"sk1",type:"skill",label:"Playwright E2E",importance:.85,details:"Browser automation test writing"},{id:"sk2",type:"skill",label:"FastAPI routing",importance:.6,details:"Python API server development"}],edges:[{source:"ep1",target:"pt1",strength:.8},{source:"ep1",target:"sk1",strength:.6},{source:"ep2",target:"pt2",strength:.9},{source:"ep3",target:"pt1",strength:.7},{source:"ep3",target:"pt3",strength:.5},{source:"pt1",target:"sk2",strength:.4},{source:"pt2",target:"sk2",strength:.7},{source:"pt3",target:"sk1",strength:.6}]}}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_selectNode(e){this._selectedNode=this._selectedNode===e?null:e,this.render()}_bindEvents(){let e=this.shadowRoot;e.querySelectorAll(".graph-node").forEach(t=>{t.addEventListener("click",()=>{this._selectNode(t.dataset.nodeId)})}),e.querySelectorAll(".close-detail").forEach(t=>{t.addEventListener("click",()=>{this._selectedNode=null,this.render()})})}_renderNodeShape(e,t,i){let a=Se[e.type]||Se.episode,s=10+(e.importance||.5)*16,r=this._selectedNode===e.id,o=r?"var(--loki-accent, #553DE9)":a.color,n=r?3:1.5,l=this._selectedNode&&!r?.4:1,c;switch(a.shape){case"square":c=`<rect x="${t-s/2}" y="${i-s/2}" width="${s}" height="${s}"
|
|
14187
14020
|
rx="3" fill="${a.color}" fill-opacity="0.2" stroke="${o}" stroke-width="${n}" opacity="${l}" />`;break;case"diamond":{let u=s/2;c=`<polygon points="${t},${i-u} ${t+u},${i} ${t},${i+u} ${t-u},${i}"
|
|
14188
14021
|
fill="${a.color}" fill-opacity="0.2" stroke="${o}" stroke-width="${n}" opacity="${l}" />`;break}default:c=`<circle cx="${t}" cy="${i}" r="${s/2}" fill="${a.color}" fill-opacity="0.2"
|
|
14189
14022
|
stroke="${o}" stroke-width="${n}" opacity="${l}" />`}let p=`<text x="${t}" y="${i+s/2+14}" text-anchor="middle" font-size="10"
|
|
@@ -14344,7 +14177,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
14344
14177
|
</div>
|
|
14345
14178
|
<div class="empty-state">No memory entries to visualize</div>
|
|
14346
14179
|
</div>
|
|
14347
|
-
`;return}let t=this._graphWidth,i=this._graphHeight,a=
|
|
14180
|
+
`;return}let t=this._graphWidth,i=this._graphHeight,a=ci(this._nodes,t,i),s=this._edges.map(l=>this._renderEdge(l,a)).join(""),r=a.map(l=>this._renderNodeShape(l,l.x,l.y)).join(""),o="";if(this._selectedNode){let l=this._nodes.find(c=>c.id===this._selectedNode);if(l){let c=Se[l.type]||Se.episode;o=`
|
|
14348
14181
|
<div class="detail-panel">
|
|
14349
14182
|
<div class="detail-header">
|
|
14350
14183
|
<span class="detail-title">${this._escapeHtml(l.label)}</span>
|
|
@@ -14595,7 +14428,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
14595
14428
|
</div>
|
|
14596
14429
|
</div>
|
|
14597
14430
|
</div>
|
|
14598
|
-
`,this._bindEvents()}};customElements.get("loki-cost-waterfall")||customElements.define("loki-cost-waterfall",Te);var
|
|
14431
|
+
`,this._bindEvents()}};customElements.get("loki-cost-waterfall")||customElements.define("loki-cost-waterfall",Te);var pi={1:{bg:"rgba(212, 160, 60, 0.15)",border:"#D4A03C",label:"1st"},2:{bg:"rgba(147, 144, 132, 0.15)",border:"#939084",label:"2nd"},3:{bg:"rgba(196, 130, 91, 0.15)",border:"#C4825B",label:"3rd"}},Le=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._agents=[],this._expandedAgent=null,this._api=null,this._pollInterval=null,this._previousRanks={}}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:1e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/v2/agents/leaderboard");if(e!==this._api)return;let i=t.agents||[],a={};i.forEach((s,r)=>{a[s.type||s.name]=r+1}),this._previousRanks={...this._currentRanks||{}},this._currentRanks=a,this._agents=i}catch{if(e!==this._api)return;this._agents.length===0&&(this._agents=this._getDemoData(),this._currentRanks={},this._agents.forEach((t,i)=>{this._currentRanks[t.type]=i+1}),this._previousRanks={})}this.render()}_getDemoData(){return[{type:"code-generator",name:"Code Generator",tasks:24,quality:9.2,speed:"fast",cost_usd:2.4},{type:"test-writer",name:"Test Writer",tasks:18,quality:9,speed:"fast",cost_usd:1.2},{type:"code-reviewer",name:"Code Reviewer",tasks:15,quality:8.8,speed:"medium",cost_usd:1.8},{type:"architect",name:"Architect",tasks:8,quality:9.5,speed:"slow",cost_usd:3.1},{type:"debugger",name:"Debugger",tasks:12,quality:8.5,speed:"fast",cost_usd:.95},{type:"doc-writer",name:"Documentation",tasks:10,quality:8.3,speed:"fast",cost_usd:.6}]}_getRankChange(e){let t=this._currentRanks?.[e],i=this._previousRanks?.[e];return t==null||i==null?0:i-t}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_toggleAgent(e){this._expandedAgent=this._expandedAgent===e?null:e,this.render()}_bindEvents(){this.shadowRoot.querySelectorAll(".agent-row").forEach(t=>{t.addEventListener("click",()=>{this._toggleAgent(t.dataset.agent)})})}_getQualityColor(e){return e>=9?"var(--loki-green, #1FC5A8)":e>=8?"var(--loki-blue, #2F71E3)":e>=7?"var(--loki-yellow, #D4A03C)":"var(--loki-red, #C45B5B)"}_getSpeedLabel(e){return e==="fast"?{label:"Fast",color:"var(--loki-green, #1FC5A8)"}:e==="medium"?{label:"Medium",color:"var(--loki-yellow, #D4A03C)"}:{label:"Slow",color:"var(--loki-red, #C45B5B)"}}_getStyles(){return`
|
|
14599
14432
|
:host {
|
|
14600
14433
|
display: block;
|
|
14601
14434
|
}
|
|
@@ -14808,7 +14641,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
14808
14641
|
</div>
|
|
14809
14642
|
<div class="empty-state">No agent performance data available</div>
|
|
14810
14643
|
</div>
|
|
14811
|
-
`;return}let t=this._agents.map((i,a)=>{let s=a+1,r=
|
|
14644
|
+
`;return}let t=this._agents.map((i,a)=>{let s=a+1,r=pi[s],o=i.type||i.name,n=this._getRankChange(o),l=this._expandedAgent===o,c=this._getQualityColor(i.quality),p=this._getSpeedLabel(i.speed),u=(i.quality??0)/10*100,m;r?m=`<div class="rank-badge" style="background: ${r.bg}; color: ${r.border};">${s}</div>`:m=`<span class="rank-number" style="color: var(--loki-text-muted);">${s}</span>`;let g="";n>0?g=`<span class="rank-change rank-up">+${n}</span>`:n<0&&(g=`<span class="rank-change rank-down">${n}</span>`);let x=l?`
|
|
14812
14645
|
<div class="agent-detail">
|
|
14813
14646
|
<div class="detail-metric">
|
|
14814
14647
|
<span class="detail-label">Total Cost</span>
|
|
@@ -15336,7 +15169,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
15336
15169
|
color: var(--text-primary, #201515);
|
|
15337
15170
|
}
|
|
15338
15171
|
.ct-heading {
|
|
15339
|
-
font-family:
|
|
15172
|
+
font-family: 'Fraunces', Georgia, serif;
|
|
15340
15173
|
font-size: 1.15rem;
|
|
15341
15174
|
font-weight: 400;
|
|
15342
15175
|
color: var(--loki-text-primary, #201515);
|
|
@@ -15493,11 +15326,11 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
15493
15326
|
.ct-badge-reject { background: #fde8e8; color: #C45B5B; }
|
|
15494
15327
|
.ct-badge-cannot { background: #fdf3d4; color: #8a6c0e; }
|
|
15495
15328
|
.ct-badge-blocked { background: #ede8fd; color: #5b3dc4; }
|
|
15496
|
-
.ct-badge-override { background:
|
|
15329
|
+
.ct-badge-override { background: #C45B5B; color: #ffffff; }
|
|
15497
15330
|
.ct-badge-da { background: #fdf3d4; color: #8a6c0e; }
|
|
15498
15331
|
.ct-badge-unknown { background: var(--bg-secondary, #F8F4F0); color: var(--text-muted, #939084); }
|
|
15499
15332
|
</style>
|
|
15500
|
-
`,i="";this._loading&&this._transcripts.length===0?i='<div class="ct-empty">Loading council transcripts...</div>':this._error?i='<div class="ct-error">Failed to load transcripts: '+this._escapeHtml(this._error)+"</div>":!this._transcripts||this._transcripts.length===0?i='<div class="ct-empty">No review rounds recorded yet. Transcripts appear after the first completion vote.</div>':i='<div class="ct-list">'+this._transcripts.map(s=>this._transcriptCardHtml(s)).join("")+"</div>",e.innerHTML=t+'<div class="ct-wrapper"><h3 class="ct-heading">Council Transcripts</h3><div class="ct-explain">Per-iteration voting records from .loki/council/transcripts/. Polls every 30 seconds.</div>'+i+this._hookEventsHtml()+"</div>"}_hookEventsHtml(){let e=Array.isArray(this._hookEvents)?this._hookEvents:[],t;return e.length===0?t='<div class="ct-empty">No live tool activity yet -- Claude hook events stream here while a run is active.</div>':t='<div class="ct-voters">'+e.slice(0,20).map(a=>{let s=this._escapeHtml(a.type||a.event||"event"),r=this._escapeHtml(this._formatTimestamp(a.timestamp||a.ts)),o=this._escapeHtml(this._truncate(a.tool||a.message||a.summary||(a.data?JSON.stringify(a.data):""),120));return'<div class="ct-voter-row"><span class="ct-iter-label">'+s+'</span> <span class="ct-ts">'+r+"</span>"+(o?'<div class="ct-prd-preview">'+o+"</div>":"")+"</div>"}).join("")+"</div>",'<h3 class="ct-heading" style="margin-top:24px;">Live Tool Activity</h3><div class="ct-explain">Claude hook events (PreToolUse / PostToolUse / Stop) streamed from .loki/events.jsonl. Lets you watch background tool calls as they run.</div>'+t}};typeof customElements<"u"&&!customElements.get("loki-council-transcripts")&&customElements.define("loki-council-transcripts",He);var
|
|
15333
|
+
`,i="";this._loading&&this._transcripts.length===0?i='<div class="ct-empty">Loading council transcripts...</div>':this._error?i='<div class="ct-error">Failed to load transcripts: '+this._escapeHtml(this._error)+"</div>":!this._transcripts||this._transcripts.length===0?i='<div class="ct-empty">No review rounds recorded yet. Transcripts appear after the first completion vote.</div>':i='<div class="ct-list">'+this._transcripts.map(s=>this._transcriptCardHtml(s)).join("")+"</div>",e.innerHTML=t+'<div class="ct-wrapper"><h3 class="ct-heading">Council Transcripts</h3><div class="ct-explain">Per-iteration voting records from .loki/council/transcripts/. Polls every 30 seconds.</div>'+i+this._hookEventsHtml()+"</div>"}_hookEventsHtml(){let e=Array.isArray(this._hookEvents)?this._hookEvents:[],t;return e.length===0?t='<div class="ct-empty">No live tool activity yet -- Claude hook events stream here while a run is active.</div>':t='<div class="ct-voters">'+e.slice(0,20).map(a=>{let s=this._escapeHtml(a.type||a.event||"event"),r=this._escapeHtml(this._formatTimestamp(a.timestamp||a.ts)),o=this._escapeHtml(this._truncate(a.tool||a.message||a.summary||(a.data?JSON.stringify(a.data):""),120));return'<div class="ct-voter-row"><span class="ct-iter-label">'+s+'</span> <span class="ct-ts">'+r+"</span>"+(o?'<div class="ct-prd-preview">'+o+"</div>":"")+"</div>"}).join("")+"</div>",'<h3 class="ct-heading" style="margin-top:24px;">Live Tool Activity</h3><div class="ct-explain">Claude hook events (PreToolUse / PostToolUse / Stop) streamed from .loki/events.jsonl. Lets you watch background tool calls as they run.</div>'+t}};typeof customElements<"u"&&!customElements.get("loki-council-transcripts")&&customElements.define("loki-council-transcripts",He);var hi=[{id:"overview",label:"Overview"},{id:"architecture",label:"Architecture"},{id:"modules",label:"Key Modules"},{id:"data-flow",label:"Data Flow"},{id:"ask",label:"Ask"}],Me=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._activeTab="overview",this._loading=!1,this._error=null,this._api=null,this._meta=null,this._metaPromise=null,this._sectionCache={},this._sectionState={},this._question="",this._answer=null,this._asking=!1,this._askError=null,this._mermaid=null,this._mermaidPromise=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadMeta()}disconnectedCallback(){super.disconnectedCallback&&super.disconnectedCallback(),this._disconnected=!0}attributeChangedCallback(e,t,i){e==="api-url"&&this._api&&(this._api=h({baseUrl:i}))}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_loadMeta(){this._loading=!0,this._error=null,this.render();let e=this._api;return this._metaPromise=(async()=>{try{let t=await e._get("/api/wiki");if(e!==this._api)return;this._meta=t}catch(t){if(e!==this._api)return;this._error=t&&t.message?t.message:"Failed to load wiki"}finally{this._loading=!1,this.render()}})(),this._metaPromise}async _loadSection(e){if(this._sectionCache[e])return this._sectionState[e]=this._sectionCache[e].error?"error":"loaded",this._sectionCache[e];this._sectionState[e]="loading";let t=this._api;try{let i=await t._get(`/api/wiki/${encodeURIComponent(e)}`);return t!==this._api?this._sectionCache[e]||{error:"stale"}:(this._sectionCache[e]=i,this._sectionState[e]=i&&i.error?"error":"loaded",i)}catch(i){if(t!==this._api)return this._sectionCache[e]||{error:"stale"};let a={error:i&&i.message||"load failed"};return this._sectionCache[e]=a,this._sectionState[e]="error",a}}async _selectTab(e){if(this._activeTab=e,e!=="architecture"&&e!=="modules"&&e!=="data-flow"){this.render();return}if(this._sectionCache[e]){this.render();return}if(this._sectionState[e]="loading",this.render(),this._metaPromise)try{await this._metaPromise}catch{}if(!(this._disconnected||this._activeTab!==e)){if(!this._meta||!this._meta.generated){delete this._sectionState[e],this.render();return}await this._loadSection(e),!(this._disconnected||this._activeTab!==e)&&this.render()}}_ensureMermaid(){return this._mermaid?Promise.resolve(this._mermaid):this._mermaidPromise?this._mermaidPromise:(this._mermaidPromise=(async()=>{try{if(typeof window<"u"&&window.mermaid)return this._mermaid=window.mermaid,this._mermaid;if(typeof window>"u"||typeof document>"u")return null;let t=`${this._api&&this._api.baseUrl||window.location.origin}/assets/mermaid.min.js`;return await new Promise((i,a)=>{let s=document.querySelector("script[data-loki-mermaid]");if(s){s.addEventListener("load",i,{once:!0}),s.addEventListener("error",a,{once:!0}),window.mermaid&&i();return}let r=document.createElement("script");r.src=t,r.async=!0,r.setAttribute("data-loki-mermaid","1"),r.addEventListener("load",i,{once:!0}),r.addEventListener("error",()=>a(new Error("mermaid load failed")),{once:!0}),document.head.appendChild(r)}),this._mermaid=typeof window<"u"&&window.mermaid||null,this._mermaid}catch{return null}})(),this._mermaidPromise)}async _maybeRenderDiagram(e){let t=this._sectionCache[e],i=this._diagramSource(t);if(!i)return;let a;try{a=await this._ensureMermaid()}catch{a=null}if(!(!a||this._disconnected||this._activeTab!==e))try{a.initialize({startOnLoad:!1,securityLevel:"strict",theme:this._mermaidTheme(),flowchart:{htmlLabels:!1,useMaxWidth:!0},deterministicIds:!0}),typeof a.parse=="function"&&await a.parse(i);let s=`wiki-mmd-${e}-${Date.now()}`,r=await a.render(s,i),o=r&&(r.svg||r);if(typeof o!="string"||o.indexOf("<svg")===-1||this._disconnected||this._activeTab!==e||!this.shadowRoot)return;let n=this.shadowRoot.getElementById("wiki-diagram");n&&(n.innerHTML=o)}catch{}}_mermaidTheme(){return(this.getAttribute("theme")||typeof document<"u"&&document.documentElement.getAttribute("data-loki-theme")||"").toLowerCase().includes("dark")?"dark":"neutral"}async _ask(){let e=(this._question||"").trim();if(!e)return;this._asking=!0,this._askError=null,this._answer=null,this.render();let t=this._api;try{let i=await t._post("/api/wiki/ask",{question:e},{timeout:2e5});if(t!==this._api)return;this._answer=i}catch(i){if(t!==this._api)return;this._askError=i&&i.message?i.message:"Ask failed"}finally{this._asking=!1,this.render()}}_esc(e){return String(e??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}_renderCitations(e){return!e||!e.length?"":`<div class="cites"><strong>Sources:</strong><ul>${e.map(i=>`<li><code>${this._esc(i.file)}:${this._esc(i.line)}</code></li>`).join("")}</ul></div>`}_renderNotGenerated(){return`<div class="es">
|
|
15501
15334
|
<div class="es-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg></div>
|
|
15502
15335
|
<div class="es-title">No wiki generated yet</div>
|
|
15503
15336
|
<div class="es-desc">Generate a cited codebase wiki to browse architecture, modules, and data flow. Every section links to real file:line locations.</div>
|
|
@@ -15536,7 +15369,7 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
15536
15369
|
<div class="es-title">Couldn't load wiki</div>
|
|
15537
15370
|
<div class="es-desc">${this._esc(e)}</div>
|
|
15538
15371
|
<button class="es-cta" id="wiki-retry-btn">Retry</button>
|
|
15539
|
-
</div>`}_renderBody(){if(this._loading)return'<div class="es-loading"><span class="es-spinner"></span> Loading wiki...</div>';if(this._error)return this._renderError(this._error);switch(this._activeTab){case"overview":return this._renderOverview();case"architecture":return this._renderSection("architecture");case"modules":return this._renderSection("modules");case"data-flow":return this._renderSection("data-flow");case"ask":return this._renderAsk();default:return this._renderOverview()}}render(){if(!this.shadowRoot)return;let e=
|
|
15372
|
+
</div>`}_renderBody(){if(this._loading)return'<div class="es-loading"><span class="es-spinner"></span> Loading wiki...</div>';if(this._error)return this._renderError(this._error);switch(this._activeTab){case"overview":return this._renderOverview();case"architecture":return this._renderSection("architecture");case"modules":return this._renderSection("modules");case"data-flow":return this._renderSection("data-flow");case"ask":return this._renderAsk();default:return this._renderOverview()}}render(){if(!this.shadowRoot)return;let e=hi.map(o=>`<button class="tab ${o.id===this._activeTab?"active":""}"
|
|
15540
15373
|
data-tab="${o.id}">${this._esc(o.label)}</button>`).join("");this.shadowRoot.innerHTML=`
|
|
15541
15374
|
<style>
|
|
15542
15375
|
${this.getBaseStyles()}
|
|
@@ -15756,13 +15589,13 @@ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropert
|
|
|
15756
15589
|
</style>
|
|
15757
15590
|
<div class="active-wrap">${this._renderActive()}</div>
|
|
15758
15591
|
${this._error||this._spec&&this._spec.type==="none"?"":this._renderHistory()}
|
|
15759
|
-
`;let e=this.shadowRoot.getElementById("spec-retry-btn");e&&e.addEventListener("click",()=>this._load());let t=this.shadowRoot.getElementById("hist-toggle");t&&t.addEventListener("click",()=>{this._historyOpen=!this._historyOpen,this.render()})}};customElements.get("loki-spec-panel")||customElements.define("loki-spec-panel",Re);(function(){"use strict";if(typeof window>"u"||typeof customElements>"u")return;var d={open:'<circle cx="178" cy="214" r="7" class="fillInk"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="180.5" cy="211.5" r="2" class="fillHi"/><circle cx="246.5" cy="211.5" r="2" class="fillHi"/>',happy:'<path class="ink" d="M171 216c4-6 10-6 14 0"/><path class="ink" d="M237 216c4-6 10-6 14 0"/>',lookUp:'<circle cx="178" cy="214" r="7" class="fillInk"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="180" cy="210" r="2.4" class="fillHi"/><circle cx="246" cy="210" r="2.4" class="fillHi"/>',wide:'<circle cx="178" cy="213" r="8.5" class="fillInk"/><circle cx="244" cy="213" r="8.5" class="fillInk"/><circle cx="181" cy="210" r="2.6" class="fillHi"/><circle cx="247" cy="210" r="2.6" class="fillHi"/>',focused:'<path class="inkBold" d="M170 214h16"/><path class="inkBold" d="M236 214h16"/>',closed:'<path class="ink" d="M170 214c4 5 10 5 14 0"/><path class="ink" d="M236 214c4 5 10 5 14 0"/>',worried:'<circle cx="178" cy="216" r="6" class="fillInk"/><circle cx="244" cy="216" r="6" class="fillInk"/><circle cx="180" cy="213.5" r="1.8" class="fillHi"/><circle cx="246" cy="213.5" r="1.8" class="fillHi"/>',wink:'<path class="ink" d="M171 214c4-5 10-5 14 0"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="246.5" cy="211.5" r="2" class="fillHi"/>'},e={none:"",raised:'<path class="inkThin" d="M168 198c5-3 12-3 17 0"/><path class="inkThin" d="M237 198c5-3 12-3 17 0"/>',furrow:'<path class="inkThin" d="M168 199l16 3"/><path class="inkThin" d="M254 199l-16 3"/>',worried:'<path class="inkThin" d="M168 201l16-4"/><path class="inkThin" d="M254 201l-16-4"/>'},t={smile:'<path class="ink" d="M192 244c12 12 26 12 38 0"/>',openSmile:'<path class="fillInk" d="M194 243c8 16 26 16 34 0c-10 6-24 6-34 0z"/>',flat:'<path class="ink" d="M198 248h26"/>',o:'<ellipse cx="211" cy="248" rx="6" ry="7" class="ink"/>',frown:'<path class="ink" d="M192 250c12-12 26-12 38 0"/>',soft:'<path class="ink" d="M196 246c9 7 19 7 28 0"/>',proud:'<path class="ink" d="M194 245c10 9 24 9 32 -2"/>'},i={none:"",wave:'<g class="prop-wave"><path class="ink" d="M318 250c14-2 26 6 28 20"/><circle cx="348" cy="276" r="9" class="fillPaper ink"/></g>',zzz:'<g class="ink prop-zzz"><text x="300" y="150" class="zzz z1">z</text><text x="322" y="128" class="zzz z2">z</text><text x="344" y="110" class="zzz z3">z</text></g>',thoughtDots:'<g class="prop-think"><circle cx="300" cy="170" r="4" class="fillInk d1"/><circle cx="316" cy="150" r="5.5" class="fillInk d2"/><circle cx="336" cy="126" r="7" class="fillInk d3"/></g>',magnifier:'<g class="prop-magnifier"><circle cx="332" cy="250" r="18" class="fillGlass ink"/><path class="inkBold" d="M345 263l16 16"/><path class="inkThin" d="M325 244a10 10 0 0 1 8 4"/></g>',check:'<g class="prop-check"><circle cx="332" cy="246" r="17" class="fillSeal"/><path class="checkMark" d="M324 246l6 6 11 -13"/></g>',confetti:'<g class="prop-confetti"><rect x="110" y="120" width="7" height="7" class="fillInk c1" transform="rotate(20 113 123)"/><rect x="300" y="110" width="7" height="7" class="fillGlow c2" transform="rotate(-15 303 113)"/><rect x="140" y="96" width="6" height="6" class="fillSeal c3"/><circle cx="330" cy="150" r="4" class="fillInk c4"/><circle cx="96" cy="170" r="4" class="fillGlow c5"/><rect x="270" y="140" width="6" height="6" class="fillInk c6" transform="rotate(40 273 143)"/><path class="inkViolet c7" d="M210 92l0 12M204 98l12 0"/></g>',parcel:'<g class="prop-parcel"><rect x="316" y="244" width="40" height="34" rx="3" class="fillPaper ink"/><path class="ink" d="M316 256h40"/><path class="inkViolet" d="M336 244v34"/></g>',spinner:'<g class="prop-spinner"><path class="inkBold spin" d="M332 230a20 20 0 1 1 -14 6"/></g>'},a={idle:{eyes:"open",mouth:"smile",motion:"breathe",label:"Loki, resting",blink:!0},happy:{eyes:"happy",mouth:"smile",motion:"bob",label:"Loki, happy"},thinking:{eyes:"lookUp",brow:"raised",mouth:"flat",prop:"thoughtDots",motion:"wiggle",label:"Loki, thinking"},building:{eyes:"focused",brow:"furrow",mouth:"flat",motion:"work",label:"Loki, building"},reviewing:{eyes:"focused",brow:"furrow",mouth:"soft",prop:"magnifier",motion:"inspect",label:"Loki, reviewing the work"},verifying:{eyes:"open",mouth:"soft",prop:"check",motion:"bob",label:"Loki, verifying",blink:!0},celebrating:{eyes:"wide",mouth:"openSmile",prop:"confetti",motion:"bounce",label:"Loki, celebrating a verified result"},proud:{eyes:"happy",mouth:"proud",prop:"check",motion:"bob",label:"Loki, proud"},waving:{eyes:"wink",mouth:"smile",prop:"wave",motion:"wave",label:"Loki, waving hello"},sleeping:{eyes:"closed",mouth:"soft",prop:"zzz",motion:"sleep",label:"Loki, sleeping"},concerned:{eyes:"worried",brow:"worried",mouth:"frown",motion:"shake",label:"Loki, something went wrong"},shipping:{eyes:"happy",mouth:"smile",prop:"parcel",motion:"launch",label:"Loki, shipping"},loading:{eyes:"open",mouth:"flat",prop:"spinner",motion:"breathe",label:"Loki, loading",blink:!0},curious:{eyes:"lookUp",brow:"raised",mouth:"o",prop:"thoughtDots",motion:"tilt",label:"Loki, curious"},blinking:{eyes:"open",mouth:"smile",motion:"breathe",label:"Loki",blink:!0},walking:{eyes:"open",mouth:"soft",motion:"walk",label:"Loki, walking",blink:!0},running:{eyes:"focused",mouth:"soft",motion:"run",label:"Loki, running"}},s="idle";function r(){return'<g class="legs"><path class="ink leg legL" d="M168 318v18"/><path class="ink foot footL" d="M158 336h20"/><path class="ink leg legR" d="M252 318v18"/><path class="ink foot footR" d="M242 336h20"/></g>'}function o(u,m,g){return m&&Object.prototype.hasOwnProperty.call(u,m)?u[m]:g||""}function n(u){var m=u.blink?" blink":"";return'<svg class="figure" viewBox="0 0 420 380" aria-hidden="true" focusable="false"><ellipse cx="210" cy="338" rx="120" ry="16" class="fillInkWash"/><g class="creature">'+r()+'<path class="fillPaper ink" d="M120 132c0-22 16-36 40-37 38-2 82-2 120 0 24 1 40 15 40 38v118c0 24-16 39-41 40-40 2-78 2-118 0-25-1-41-16-41-40z"/><path class="inkThin" d="M124 168c54-4 118-4 172 0"/><circle cx="146" cy="150" r="4.5" class="inkViolet"/><circle cx="164" cy="150" r="4.5" class="inkThinDot"/><circle cx="182" cy="150" r="4.5" class="inkThinDot"/><circle cx="170" cy="232" r="9" class="fillGlow"/><circle cx="252" cy="232" r="9" class="fillGlow"/>'+o(e,u.brow,"")+'<g class="eyes'+m+'">'+o(d,u.eyes,d.open)+"</g>"+o(t,u.mouth,t.smile)+'<path class="inkViolet" d="M150 280h120"/><path class="inkThin" d="M150 296h84"/>'+o(i,u.prop,"")+"</g></svg>"}var l=[":host{display:inline-block;line-height:0;","--lm-ink:var(--color-ink,#553de9);","--lm-ink-wash:var(--color-ink-wash,rgba(85,61,233,0.08));","--lm-text:var(--color-text,#201515);","--lm-paper:var(--color-paper-card,#fffdf8);","--lm-glow:var(--color-glow,#e8a33d);","--lm-glow-wash:var(--color-glow-wash,rgba(232,163,61,0.14));","--lm-seal:var(--color-seal,#1f8a52);","}",".figure{display:block;width:100%;height:auto;overflow:visible}",".ink{fill:none;stroke:var(--lm-text);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}",".inkBold{fill:none;stroke:var(--lm-text);stroke-width:3.4;stroke-linecap:round;stroke-linejoin:round}",".inkThin{fill:none;stroke:var(--lm-text);stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}",".inkThinDot{fill:none;stroke:var(--lm-text);stroke-width:1.6}",".inkViolet{fill:none;stroke:var(--lm-ink);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}",".fillPaper{fill:var(--lm-paper)}",".fillInk{fill:var(--lm-ink)}",".fillInkWash{fill:var(--lm-ink-wash)}",".fillGlow{fill:var(--lm-glow)}",".fillSeal{fill:var(--lm-seal)}",".fillGlass{fill:rgba(85,61,233,0.06)}",".fillHi{fill:var(--lm-paper)}",".prop-wave .fillPaper{fill:var(--lm-paper)}",".checkMark{fill:none;stroke:#fff;stroke-width:3.2;stroke-linecap:round;stroke-linejoin:round}",".zzz{font:600 26px var(--font-sans,system-ui,sans-serif);fill:var(--lm-ink)}",".m-breathe .creature{transform-box:fill-box;transform-origin:center;animation:lm-breathe 4.5s ease-in-out infinite}","@keyframes lm-breathe{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-2px) scale(1.012)}}",".m-bob .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-bob 2.2s ease-in-out infinite}","@keyframes lm-bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-7px)}}",".m-bounce .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-bounce 0.9s cubic-bezier(.3,.7,.4,1) infinite}","@keyframes lm-bounce{0%,100%{transform:translateY(0) scaleY(1)}30%{transform:translateY(-22px) scaleY(1.05)}55%{transform:translateY(0) scaleY(.94)}70%{transform:translateY(-6px)}}",".m-wiggle .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-wiggle 3s ease-in-out infinite}","@keyframes lm-wiggle{0%,100%{transform:rotate(-1.5deg)}50%{transform:rotate(1.5deg)}}",".m-tilt .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-tilt 3.4s ease-in-out infinite}","@keyframes lm-tilt{0%,100%{transform:rotate(-4deg)}50%{transform:rotate(4deg)}}",".m-work .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-work 0.7s ease-in-out infinite}","@keyframes lm-work{0%,100%{transform:translateX(0) rotate(0)}25%{transform:translateX(-1.5px) rotate(-1deg)}75%{transform:translateX(1.5px) rotate(1deg)}}",".m-inspect .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-inspect 3.2s ease-in-out infinite}","@keyframes lm-inspect{0%,100%{transform:translate(0,0)}50%{transform:translate(6px,-2px)}}",".m-inspect .prop-magnifier{transform-box:fill-box;transform-origin:332px 250px;animation:lm-inspect-mag 3.2s ease-in-out infinite}","@keyframes lm-inspect-mag{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(4px,4px) scale(1.08)}}",".m-shake .creature{transform-box:fill-box;transform-origin:center;animation:lm-shake 0.5s ease-in-out infinite}","@keyframes lm-shake{0%,100%{transform:translateX(0)}25%{transform:translateX(-4px)}75%{transform:translateX(4px)}}",".m-launch .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-launch 1.6s ease-in-out infinite}","@keyframes lm-launch{0%{transform:translateY(0)}40%{transform:translateY(-3px)}70%{transform:translateY(-14px) rotate(-2deg)}100%{transform:translateY(0)}}",".m-wave .creature{transform-box:fill-box;transform-origin:center;animation:lm-breathe 4.5s ease-in-out infinite}",".m-sleep .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-sleep 5.5s ease-in-out infinite}","@keyframes lm-sleep{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-1px) scale(1.02)}}",".prop-wave{transform-box:fill-box;transform-origin:50% 100%;animation:lm-sway 1.1s ease-in-out infinite}","@keyframes lm-sway{0%,100%{transform:rotate(-8deg)}50%{transform:rotate(14deg)}}",".prop-think .d1{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite}",".prop-think .d2{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite .3s}",".prop-think .d3{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite .6s}","@keyframes lm-rise{0%{opacity:.2;transform:translateY(4px) scale(.7)}50%{opacity:1;transform:translateY(0) scale(1)}100%{opacity:.2;transform:translateY(-4px) scale(.7)}}",".zzz{opacity:0;transform-box:fill-box;transform-origin:center}",".prop-zzz .z1{animation:lm-zfloat 3s ease-in-out infinite}",".prop-zzz .z2{animation:lm-zfloat 3s ease-in-out infinite 1s}",".prop-zzz .z3{animation:lm-zfloat 3s ease-in-out infinite 2s}","@keyframes lm-zfloat{0%{opacity:0;transform:translateY(6px) scale(.7)}40%{opacity:1}100%{opacity:0;transform:translateY(-16px) scale(1.1)}}",".spin{transform-box:fill-box;transform-origin:332px 250px;animation:lm-spin 1s linear infinite}","@keyframes lm-spin{to{transform:rotate(360deg)}}",".prop-confetti>*{transform-box:fill-box;transform-origin:center;animation:lm-confetti 1.4s ease-in infinite}",".prop-confetti .c2{animation-delay:.15s}.prop-confetti .c3{animation-delay:.3s}",".prop-confetti .c4{animation-delay:.45s}.prop-confetti .c5{animation-delay:.2s}",".prop-confetti .c6{animation-delay:.5s}.prop-confetti .c7{animation-delay:.1s}","@keyframes lm-confetti{0%{opacity:0;transform:translateY(0) rotate(0)}20%{opacity:1}100%{opacity:0;transform:translateY(34px) rotate(180deg)}}",".prop-check{transform-box:fill-box;transform-origin:332px 246px;animation:lm-pop 2.4s ease-in-out infinite}","@keyframes lm-pop{0%,70%,100%{transform:scale(1)}80%{transform:scale(1.18)}}",".m-launch .prop-parcel{transform-box:fill-box;transform-origin:center;animation:lm-bob 1.6s ease-in-out infinite}",".m-walk .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-walkbody 0.8s ease-in-out infinite}","@keyframes lm-walkbody{0%,100%{transform:translateY(0) rotate(-1deg)}50%{transform:translateY(-4px) rotate(1deg)}}",".m-walk .legL{transform-box:fill-box;transform-origin:168px 318px;animation:lm-legswing 0.8s ease-in-out infinite}",".m-walk .footL{transform-box:fill-box;transform-origin:168px 336px;animation:lm-legswing 0.8s ease-in-out infinite}",".m-walk .legR{transform-box:fill-box;transform-origin:252px 318px;animation:lm-legswing 0.8s ease-in-out infinite .4s}",".m-walk .footR{transform-box:fill-box;transform-origin:252px 336px;animation:lm-legswing 0.8s ease-in-out infinite .4s}","@keyframes lm-legswing{0%,100%{transform:rotate(-16deg)}50%{transform:rotate(16deg)}}",".m-run .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-runbody 0.42s ease-in-out infinite}","@keyframes lm-runbody{0%,100%{transform:translateY(0) rotate(-4deg)}50%{transform:translateY(-7px) rotate(2deg)}}",".m-run .legL{transform-box:fill-box;transform-origin:168px 318px;animation:lm-runleg 0.42s ease-in-out infinite}",".m-run .footL{transform-box:fill-box;transform-origin:168px 336px;animation:lm-runleg 0.42s ease-in-out infinite}",".m-run .legR{transform-box:fill-box;transform-origin:252px 318px;animation:lm-runleg 0.42s ease-in-out infinite .21s}",".m-run .footR{transform-box:fill-box;transform-origin:252px 336px;animation:lm-runleg 0.42s ease-in-out infinite .21s}","@keyframes lm-runleg{0%,100%{transform:rotate(-30deg)}50%{transform:rotate(30deg)}}",".eyes.blink{transform-box:fill-box;transform-origin:center;animation:lm-blink 6s steps(1,end) infinite}","@keyframes lm-blink{0%,92%,100%{transform:scaleY(1)}95%{transform:scaleY(.1)}}","@media (prefers-reduced-motion: reduce){",".figure *{animation:none !important}",".eyes.blink{transform:scaleY(1) !important}",".zzz{opacity:1}",".prop-confetti>*{opacity:1}",".prop-think .d1,.prop-think .d2,.prop-think .d3{opacity:1}","}"].join("");function c(u){var m=parseFloat(u);return!isFinite(m)||m<=0?132:m<16?16:m>1024?1024:m}var p=function(){function u(){return class extends HTMLElement{static get observedAttributes(){return["emotion","size","motion"]}constructor(){super(),this.attachShadow({mode:"open"}),this._styleEl=document.createElement("style"),this._styleEl.textContent=l,this._wrap=document.createElement("div"),this._wrap.className="lm-root",this.shadowRoot.appendChild(this._styleEl),this.shadowRoot.appendChild(this._wrap)}connectedCallback(){this._render()}attributeChangedCallback(){this.shadowRoot&&this._render()}_render(){var g=(this.getAttribute("emotion")||s).toLowerCase(),x=a[g]||a[s],k=(this.getAttribute("motion")||x.motion||"breathe").toLowerCase(),_=c(this.getAttribute("size")||"132");this.style.width=_+"px",this.setAttribute("role","img"),this.setAttribute("aria-label",x.label||"Loki"),this._wrap.className="lm-root m-"+k,this._wrap.innerHTML=n(x)}}}return customElements.get("loki-mascot")||customElements.define("loki-mascot",u()),customElements.get("loki-mascot")}();try{p.emotions=Object.keys(a),p.getEmotion=function(u){var m=(u||s).toLowerCase(),g=a[m]||a[s];return Object.assign({name:m},g)},p.renderStandaloneSVG=function(u){var m=p.getEmotion(u),g=m.motion||"breathe",x=l.replace(":host{","svg.loki-figure{"),k=n(m).replace('<svg class="figure"','<svg xmlns="http://www.w3.org/2000/svg" class="figure loki-figure m-'+g+'" role="img" aria-label="'+(m.label||"Loki")+'"').replace('aria-hidden="true" focusable="false"','focusable="false"');return k.replace("</svg>","<style>"+x+"</style></svg>")}}catch{}})();function gi(d){switch((d||"").toLowerCase()){case"running":case"autonomous":return"building";case"paused":return"sleeping";default:return"idle"}}var Pe=class extends HTMLElement{static get observedAttributes(){return["api-url","size"]}constructor(){super(),this.attachShadow({mode:"open"}),this._status="idle",this._api=null,this._statusHandler=null,this._discHandler=null,this._poll=null}connectedCallback(){this._setupApi(),this._loadStatus(),this._startPolling(),this.render()}disconnectedCallback(){this._poll&&(this._poll.stop(),this._poll=null),this._teardownApiListeners()}_teardownApiListeners(){this._api&&(this._statusHandler&&this._api.removeEventListener(f.STATUS_UPDATE,this._statusHandler),this._discHandler&&this._api.removeEventListener(f.DISCONNECTED,this._discHandler))}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._teardownApiListeners(),this._setupApi(),this._loadStatus()),e==="size"&&this.render())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e}),this._statusHandler=t=>this._updateFromStatus(t.detail),this._discHandler=()=>{this._status="offline",this.render()},this._api.addEventListener(f.STATUS_UPDATE,this._statusHandler),this._api.addEventListener(f.DISCONNECTED,this._discHandler)}_startPolling(){this._poll=b({loadFn:()=>this._loadStatus(),intervalMs:1e4,sectionId:null,immediate:!1})}async _loadStatus(){let e=this._api;try{let t=await e.getStatus();if(e!==this._api)return;this._updateFromStatus(t)}catch{if(e!==this._api)return;this._status="offline",this.render()}}_updateFromStatus(e){if(!e)return;let t=e.status||"idle";t!==this._status&&(this._status=t,this.render())}render(){if(!this.shadowRoot)return;let e=this.getAttribute("size")||"34",t=gi(this._status);this.shadowRoot.innerHTML=`
|
|
15592
|
+
`;let e=this.shadowRoot.getElementById("spec-retry-btn");e&&e.addEventListener("click",()=>this._load());let t=this.shadowRoot.getElementById("hist-toggle");t&&t.addEventListener("click",()=>{this._historyOpen=!this._historyOpen,this.render()})}};customElements.get("loki-spec-panel")||customElements.define("loki-spec-panel",Re);(function(){"use strict";if(typeof window>"u"||typeof customElements>"u")return;var d={open:'<circle cx="178" cy="214" r="7" class="fillInk"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="180.5" cy="211.5" r="2" class="fillHi"/><circle cx="246.5" cy="211.5" r="2" class="fillHi"/>',happy:'<path class="ink" d="M171 216c4-6 10-6 14 0"/><path class="ink" d="M237 216c4-6 10-6 14 0"/>',lookUp:'<circle cx="178" cy="214" r="7" class="fillInk"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="180" cy="210" r="2.4" class="fillHi"/><circle cx="246" cy="210" r="2.4" class="fillHi"/>',wide:'<circle cx="178" cy="213" r="8.5" class="fillInk"/><circle cx="244" cy="213" r="8.5" class="fillInk"/><circle cx="181" cy="210" r="2.6" class="fillHi"/><circle cx="247" cy="210" r="2.6" class="fillHi"/>',focused:'<path class="inkBold" d="M170 214h16"/><path class="inkBold" d="M236 214h16"/>',closed:'<path class="ink" d="M170 214c4 5 10 5 14 0"/><path class="ink" d="M236 214c4 5 10 5 14 0"/>',worried:'<circle cx="178" cy="216" r="6" class="fillInk"/><circle cx="244" cy="216" r="6" class="fillInk"/><circle cx="180" cy="213.5" r="1.8" class="fillHi"/><circle cx="246" cy="213.5" r="1.8" class="fillHi"/>',wink:'<path class="ink" d="M171 214c4-5 10-5 14 0"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="246.5" cy="211.5" r="2" class="fillHi"/>'},e={none:"",raised:'<path class="inkThin" d="M168 198c5-3 12-3 17 0"/><path class="inkThin" d="M237 198c5-3 12-3 17 0"/>',furrow:'<path class="inkThin" d="M168 199l16 3"/><path class="inkThin" d="M254 199l-16 3"/>',worried:'<path class="inkThin" d="M168 201l16-4"/><path class="inkThin" d="M254 201l-16-4"/>'},t={smile:'<path class="ink" d="M192 244c12 12 26 12 38 0"/>',openSmile:'<path class="fillInk" d="M194 243c8 16 26 16 34 0c-10 6-24 6-34 0z"/>',flat:'<path class="ink" d="M198 248h26"/>',o:'<ellipse cx="211" cy="248" rx="6" ry="7" class="ink"/>',frown:'<path class="ink" d="M192 250c12-12 26-12 38 0"/>',soft:'<path class="ink" d="M196 246c9 7 19 7 28 0"/>',proud:'<path class="ink" d="M194 245c10 9 24 9 32 -2"/>'},i={none:"",wave:'<g class="prop-wave"><path class="ink" d="M318 250c14-2 26 6 28 20"/><circle cx="348" cy="276" r="9" class="fillPaper ink"/></g>',zzz:'<g class="ink prop-zzz"><text x="300" y="150" class="zzz z1">z</text><text x="322" y="128" class="zzz z2">z</text><text x="344" y="110" class="zzz z3">z</text></g>',thoughtDots:'<g class="prop-think"><circle cx="300" cy="170" r="4" class="fillInk d1"/><circle cx="316" cy="150" r="5.5" class="fillInk d2"/><circle cx="336" cy="126" r="7" class="fillInk d3"/></g>',magnifier:'<g class="prop-magnifier"><circle cx="332" cy="250" r="18" class="fillGlass ink"/><path class="inkBold" d="M345 263l16 16"/><path class="inkThin" d="M325 244a10 10 0 0 1 8 4"/></g>',check:'<g class="prop-check"><circle cx="332" cy="246" r="17" class="fillSeal"/><path class="checkMark" d="M324 246l6 6 11 -13"/></g>',confetti:'<g class="prop-confetti"><rect x="110" y="120" width="7" height="7" class="fillInk c1" transform="rotate(20 113 123)"/><rect x="300" y="110" width="7" height="7" class="fillGlow c2" transform="rotate(-15 303 113)"/><rect x="140" y="96" width="6" height="6" class="fillSeal c3"/><circle cx="330" cy="150" r="4" class="fillInk c4"/><circle cx="96" cy="170" r="4" class="fillGlow c5"/><rect x="270" y="140" width="6" height="6" class="fillInk c6" transform="rotate(40 273 143)"/><path class="inkViolet c7" d="M210 92l0 12M204 98l12 0"/></g>',parcel:'<g class="prop-parcel"><rect x="316" y="244" width="40" height="34" rx="3" class="fillPaper ink"/><path class="ink" d="M316 256h40"/><path class="inkViolet" d="M336 244v34"/></g>',spinner:'<g class="prop-spinner"><path class="inkBold spin" d="M332 230a20 20 0 1 1 -14 6"/></g>'},a={idle:{eyes:"open",mouth:"smile",motion:"breathe",label:"Loki, resting",blink:!0},happy:{eyes:"happy",mouth:"smile",motion:"bob",label:"Loki, happy"},thinking:{eyes:"lookUp",brow:"raised",mouth:"flat",prop:"thoughtDots",motion:"wiggle",label:"Loki, thinking"},building:{eyes:"focused",brow:"furrow",mouth:"flat",motion:"work",label:"Loki, building"},reviewing:{eyes:"focused",brow:"furrow",mouth:"soft",prop:"magnifier",motion:"inspect",label:"Loki, reviewing the work"},verifying:{eyes:"open",mouth:"soft",prop:"check",motion:"bob",label:"Loki, verifying",blink:!0},celebrating:{eyes:"wide",mouth:"openSmile",prop:"confetti",motion:"bounce",label:"Loki, celebrating a verified result"},proud:{eyes:"happy",mouth:"proud",prop:"check",motion:"bob",label:"Loki, proud"},waving:{eyes:"wink",mouth:"smile",prop:"wave",motion:"wave",label:"Loki, waving hello"},sleeping:{eyes:"closed",mouth:"soft",prop:"zzz",motion:"sleep",label:"Loki, sleeping"},concerned:{eyes:"worried",brow:"worried",mouth:"frown",motion:"shake",label:"Loki, something went wrong"},shipping:{eyes:"happy",mouth:"smile",prop:"parcel",motion:"launch",label:"Loki, shipping"},loading:{eyes:"open",mouth:"flat",prop:"spinner",motion:"breathe",label:"Loki, loading",blink:!0},curious:{eyes:"lookUp",brow:"raised",mouth:"o",prop:"thoughtDots",motion:"tilt",label:"Loki, curious"},blinking:{eyes:"open",mouth:"smile",motion:"breathe",label:"Loki",blink:!0},walking:{eyes:"open",mouth:"soft",motion:"walk",label:"Loki, walking",blink:!0},running:{eyes:"focused",mouth:"soft",motion:"run",label:"Loki, running"}},s="idle";function r(){return'<g class="legs"><path class="ink leg legL" d="M168 318v18"/><path class="ink foot footL" d="M158 336h20"/><path class="ink leg legR" d="M252 318v18"/><path class="ink foot footR" d="M242 336h20"/></g>'}function o(u,m,g){return m&&Object.prototype.hasOwnProperty.call(u,m)?u[m]:g||""}function n(u){var m=u.blink?" blink":"";return'<svg class="figure" viewBox="0 0 420 380" aria-hidden="true" focusable="false"><ellipse cx="210" cy="338" rx="120" ry="16" class="fillInkWash"/><g class="creature">'+r()+'<path class="fillPaper ink" d="M120 132c0-22 16-36 40-37 38-2 82-2 120 0 24 1 40 15 40 38v118c0 24-16 39-41 40-40 2-78 2-118 0-25-1-41-16-41-40z"/><path class="inkThin" d="M124 168c54-4 118-4 172 0"/><circle cx="146" cy="150" r="4.5" class="inkViolet"/><circle cx="164" cy="150" r="4.5" class="inkThinDot"/><circle cx="182" cy="150" r="4.5" class="inkThinDot"/><circle cx="170" cy="232" r="9" class="fillGlow"/><circle cx="252" cy="232" r="9" class="fillGlow"/>'+o(e,u.brow,"")+'<g class="eyes'+m+'">'+o(d,u.eyes,d.open)+"</g>"+o(t,u.mouth,t.smile)+'<path class="inkViolet" d="M150 280h120"/><path class="inkThin" d="M150 296h84"/>'+o(i,u.prop,"")+"</g></svg>"}var l=[":host{display:inline-block;line-height:0;","--lm-ink:var(--color-ink,#553de9);","--lm-ink-wash:var(--color-ink-wash,rgba(85,61,233,0.08));","--lm-text:var(--color-text,#201515);","--lm-paper:var(--color-paper-card,#fffdf8);","--lm-glow:var(--color-glow,#e8a33d);","--lm-glow-wash:var(--color-glow-wash,rgba(232,163,61,0.14));","--lm-seal:var(--color-seal,#1f8a52);","}",".figure{display:block;width:100%;height:auto;overflow:visible}",".ink{fill:none;stroke:var(--lm-text);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}",".inkBold{fill:none;stroke:var(--lm-text);stroke-width:3.4;stroke-linecap:round;stroke-linejoin:round}",".inkThin{fill:none;stroke:var(--lm-text);stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}",".inkThinDot{fill:none;stroke:var(--lm-text);stroke-width:1.6}",".inkViolet{fill:none;stroke:var(--lm-ink);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}",".fillPaper{fill:var(--lm-paper)}",".fillInk{fill:var(--lm-ink)}",".fillInkWash{fill:var(--lm-ink-wash)}",".fillGlow{fill:var(--lm-glow)}",".fillSeal{fill:var(--lm-seal)}",".fillGlass{fill:rgba(85,61,233,0.06)}",".fillHi{fill:var(--lm-paper)}",".prop-wave .fillPaper{fill:var(--lm-paper)}",".checkMark{fill:none;stroke:#fff;stroke-width:3.2;stroke-linecap:round;stroke-linejoin:round}",".zzz{font:600 26px var(--font-sans,system-ui,sans-serif);fill:var(--lm-ink)}",".m-breathe .creature{transform-box:fill-box;transform-origin:center;animation:lm-breathe 4.5s ease-in-out infinite}","@keyframes lm-breathe{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-2px) scale(1.012)}}",".m-bob .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-bob 2.2s ease-in-out infinite}","@keyframes lm-bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-7px)}}",".m-bounce .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-bounce 0.9s cubic-bezier(.3,.7,.4,1) infinite}","@keyframes lm-bounce{0%,100%{transform:translateY(0) scaleY(1)}30%{transform:translateY(-22px) scaleY(1.05)}55%{transform:translateY(0) scaleY(.94)}70%{transform:translateY(-6px)}}",".m-wiggle .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-wiggle 3s ease-in-out infinite}","@keyframes lm-wiggle{0%,100%{transform:rotate(-1.5deg)}50%{transform:rotate(1.5deg)}}",".m-tilt .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-tilt 3.4s ease-in-out infinite}","@keyframes lm-tilt{0%,100%{transform:rotate(-4deg)}50%{transform:rotate(4deg)}}",".m-work .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-work 0.7s ease-in-out infinite}","@keyframes lm-work{0%,100%{transform:translateX(0) rotate(0)}25%{transform:translateX(-1.5px) rotate(-1deg)}75%{transform:translateX(1.5px) rotate(1deg)}}",".m-inspect .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-inspect 3.2s ease-in-out infinite}","@keyframes lm-inspect{0%,100%{transform:translate(0,0)}50%{transform:translate(6px,-2px)}}",".m-inspect .prop-magnifier{transform-box:fill-box;transform-origin:332px 250px;animation:lm-inspect-mag 3.2s ease-in-out infinite}","@keyframes lm-inspect-mag{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(4px,4px) scale(1.08)}}",".m-shake .creature{transform-box:fill-box;transform-origin:center;animation:lm-shake 0.5s ease-in-out infinite}","@keyframes lm-shake{0%,100%{transform:translateX(0)}25%{transform:translateX(-4px)}75%{transform:translateX(4px)}}",".m-launch .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-launch 1.6s ease-in-out infinite}","@keyframes lm-launch{0%{transform:translateY(0)}40%{transform:translateY(-3px)}70%{transform:translateY(-14px) rotate(-2deg)}100%{transform:translateY(0)}}",".m-wave .creature{transform-box:fill-box;transform-origin:center;animation:lm-breathe 4.5s ease-in-out infinite}",".m-sleep .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-sleep 5.5s ease-in-out infinite}","@keyframes lm-sleep{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-1px) scale(1.02)}}",".prop-wave{transform-box:fill-box;transform-origin:50% 100%;animation:lm-sway 1.1s ease-in-out infinite}","@keyframes lm-sway{0%,100%{transform:rotate(-8deg)}50%{transform:rotate(14deg)}}",".prop-think .d1{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite}",".prop-think .d2{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite .3s}",".prop-think .d3{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite .6s}","@keyframes lm-rise{0%{opacity:.2;transform:translateY(4px) scale(.7)}50%{opacity:1;transform:translateY(0) scale(1)}100%{opacity:.2;transform:translateY(-4px) scale(.7)}}",".zzz{opacity:0;transform-box:fill-box;transform-origin:center}",".prop-zzz .z1{animation:lm-zfloat 3s ease-in-out infinite}",".prop-zzz .z2{animation:lm-zfloat 3s ease-in-out infinite 1s}",".prop-zzz .z3{animation:lm-zfloat 3s ease-in-out infinite 2s}","@keyframes lm-zfloat{0%{opacity:0;transform:translateY(6px) scale(.7)}40%{opacity:1}100%{opacity:0;transform:translateY(-16px) scale(1.1)}}",".spin{transform-box:fill-box;transform-origin:332px 250px;animation:lm-spin 1s linear infinite}","@keyframes lm-spin{to{transform:rotate(360deg)}}",".prop-confetti>*{transform-box:fill-box;transform-origin:center;animation:lm-confetti 1.4s ease-in infinite}",".prop-confetti .c2{animation-delay:.15s}.prop-confetti .c3{animation-delay:.3s}",".prop-confetti .c4{animation-delay:.45s}.prop-confetti .c5{animation-delay:.2s}",".prop-confetti .c6{animation-delay:.5s}.prop-confetti .c7{animation-delay:.1s}","@keyframes lm-confetti{0%{opacity:0;transform:translateY(0) rotate(0)}20%{opacity:1}100%{opacity:0;transform:translateY(34px) rotate(180deg)}}",".prop-check{transform-box:fill-box;transform-origin:332px 246px;animation:lm-pop 2.4s ease-in-out infinite}","@keyframes lm-pop{0%,70%,100%{transform:scale(1)}80%{transform:scale(1.18)}}",".m-launch .prop-parcel{transform-box:fill-box;transform-origin:center;animation:lm-bob 1.6s ease-in-out infinite}",".m-walk .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-walkbody 0.8s ease-in-out infinite}","@keyframes lm-walkbody{0%,100%{transform:translateY(0) rotate(-1deg)}50%{transform:translateY(-4px) rotate(1deg)}}",".m-walk .legL{transform-box:fill-box;transform-origin:168px 318px;animation:lm-legswing 0.8s ease-in-out infinite}",".m-walk .footL{transform-box:fill-box;transform-origin:168px 336px;animation:lm-legswing 0.8s ease-in-out infinite}",".m-walk .legR{transform-box:fill-box;transform-origin:252px 318px;animation:lm-legswing 0.8s ease-in-out infinite .4s}",".m-walk .footR{transform-box:fill-box;transform-origin:252px 336px;animation:lm-legswing 0.8s ease-in-out infinite .4s}","@keyframes lm-legswing{0%,100%{transform:rotate(-16deg)}50%{transform:rotate(16deg)}}",".m-run .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-runbody 0.42s ease-in-out infinite}","@keyframes lm-runbody{0%,100%{transform:translateY(0) rotate(-4deg)}50%{transform:translateY(-7px) rotate(2deg)}}",".m-run .legL{transform-box:fill-box;transform-origin:168px 318px;animation:lm-runleg 0.42s ease-in-out infinite}",".m-run .footL{transform-box:fill-box;transform-origin:168px 336px;animation:lm-runleg 0.42s ease-in-out infinite}",".m-run .legR{transform-box:fill-box;transform-origin:252px 318px;animation:lm-runleg 0.42s ease-in-out infinite .21s}",".m-run .footR{transform-box:fill-box;transform-origin:252px 336px;animation:lm-runleg 0.42s ease-in-out infinite .21s}","@keyframes lm-runleg{0%,100%{transform:rotate(-30deg)}50%{transform:rotate(30deg)}}",".eyes.blink{transform-box:fill-box;transform-origin:center;animation:lm-blink 6s steps(1,end) infinite}","@keyframes lm-blink{0%,92%,100%{transform:scaleY(1)}95%{transform:scaleY(.1)}}","@media (prefers-reduced-motion: reduce){",".figure *{animation:none !important}",".eyes.blink{transform:scaleY(1) !important}",".zzz{opacity:1}",".prop-confetti>*{opacity:1}",".prop-think .d1,.prop-think .d2,.prop-think .d3{opacity:1}","}"].join("");function c(u){var m=parseFloat(u);return!isFinite(m)||m<=0?132:m<16?16:m>1024?1024:m}var p=function(){function u(){return class extends HTMLElement{static get observedAttributes(){return["emotion","size","motion"]}constructor(){super(),this.attachShadow({mode:"open"}),this._styleEl=document.createElement("style"),this._styleEl.textContent=l,this._wrap=document.createElement("div"),this._wrap.className="lm-root",this.shadowRoot.appendChild(this._styleEl),this.shadowRoot.appendChild(this._wrap)}connectedCallback(){this._render()}attributeChangedCallback(){this.shadowRoot&&this._render()}_render(){var g=(this.getAttribute("emotion")||s).toLowerCase(),x=a[g]||a[s],k=(this.getAttribute("motion")||x.motion||"breathe").toLowerCase(),_=c(this.getAttribute("size")||"132");this.style.width=_+"px",this.setAttribute("role","img"),this.setAttribute("aria-label",x.label||"Loki"),this._wrap.className="lm-root m-"+k,this._wrap.innerHTML=n(x)}}}return customElements.get("loki-mascot")||customElements.define("loki-mascot",u()),customElements.get("loki-mascot")}();try{p.emotions=Object.keys(a),p.getEmotion=function(u){var m=(u||s).toLowerCase(),g=a[m]||a[s];return Object.assign({name:m},g)},p.renderStandaloneSVG=function(u){var m=p.getEmotion(u),g=m.motion||"breathe",x=l.replace(":host{","svg.loki-figure{"),k=n(m).replace('<svg class="figure"','<svg xmlns="http://www.w3.org/2000/svg" class="figure loki-figure m-'+g+'" role="img" aria-label="'+(m.label||"Loki")+'"').replace('aria-hidden="true" focusable="false"','focusable="false"');return k.replace("</svg>","<style>"+x+"</style></svg>")}}catch{}})();function ui(d){switch((d||"").toLowerCase()){case"running":case"autonomous":return"building";case"paused":return"sleeping";default:return"idle"}}var Pe=class extends HTMLElement{static get observedAttributes(){return["api-url","size"]}constructor(){super(),this.attachShadow({mode:"open"}),this._status="idle",this._api=null,this._statusHandler=null,this._discHandler=null,this._poll=null}connectedCallback(){this._setupApi(),this._loadStatus(),this._startPolling(),this.render()}disconnectedCallback(){this._poll&&(this._poll.stop(),this._poll=null),this._teardownApiListeners()}_teardownApiListeners(){this._api&&(this._statusHandler&&this._api.removeEventListener(f.STATUS_UPDATE,this._statusHandler),this._discHandler&&this._api.removeEventListener(f.DISCONNECTED,this._discHandler))}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._teardownApiListeners(),this._setupApi(),this._loadStatus()),e==="size"&&this.render())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e}),this._statusHandler=t=>this._updateFromStatus(t.detail),this._discHandler=()=>{this._status="offline",this.render()},this._api.addEventListener(f.STATUS_UPDATE,this._statusHandler),this._api.addEventListener(f.DISCONNECTED,this._discHandler)}_startPolling(){this._poll=b({loadFn:()=>this._loadStatus(),intervalMs:1e4,sectionId:null,immediate:!1})}async _loadStatus(){let e=this._api;try{let t=await e.getStatus();if(e!==this._api)return;this._updateFromStatus(t)}catch{if(e!==this._api)return;this._status="offline",this.render()}}_updateFromStatus(e){if(!e)return;let t=e.status||"idle";t!==this._status&&(this._status=t,this.render())}render(){if(!this.shadowRoot)return;let e=this.getAttribute("size")||"34",t=ui(this._status);this.shadowRoot.innerHTML=`
|
|
15760
15593
|
<style>
|
|
15761
15594
|
:host { display: inline-flex; align-items: center; line-height: 0; }
|
|
15762
15595
|
loki-mascot { display: inline-block; }
|
|
15763
15596
|
</style>
|
|
15764
15597
|
<loki-mascot emotion="${t}" size="${e}"></loki-mascot>
|
|
15765
|
-
`}};customElements.get("loki-mascot-presence")||customElements.define("loki-mascot-presence",Pe);var
|
|
15598
|
+
`}};customElements.get("loki-mascot-presence")||customElements.define("loki-mascot-presence",Pe);var gi="1.4.0";function mi(d={}){return d.theme?w.setTheme(d.theme):d.autoDetectContext!==!1?w.init():U.init(),d.apiUrl&&h({baseUrl:d.apiUrl}),{theme:w.getTheme(),context:w.detectContext()}}return Bt(vi);})();
|
|
15766
15599
|
|
|
15767
15600
|
|
|
15768
15601
|
// Initialize dashboard when DOM is ready
|
|
@@ -16214,6 +16047,143 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
16214
16047
|
badge.classList.add('show');
|
|
16215
16048
|
}
|
|
16216
16049
|
|
|
16050
|
+
// SPEND CAP STATE. budget_limit is NULL by default -- LOKI_BUDGET_LIMIT
|
|
16051
|
+
// ships unset, so a long run has no automatic stop. That is a defensible
|
|
16052
|
+
// default (a run killed at a threshold the user never chose is worse), but
|
|
16053
|
+
// it must not be INVISIBLE: today the only place it surfaced was a bill.
|
|
16054
|
+
//
|
|
16055
|
+
// Renders the no-cap state as prominently as a cap, and names the variable
|
|
16056
|
+
// that sets one. Never invents a number: an unknown current cost reads
|
|
16057
|
+
// "not measured", not $0.00.
|
|
16058
|
+
window.loadBudget = function () {
|
|
16059
|
+
var el = document.getElementById('budget-banner');
|
|
16060
|
+
if (!el) return;
|
|
16061
|
+
fetch('/api/budget', { headers: { 'Accept': 'application/json' } })
|
|
16062
|
+
.then(function (r) { return r.ok ? r.json() : null; })
|
|
16063
|
+
.then(function (d) {
|
|
16064
|
+
if (!d) return;
|
|
16065
|
+
var lim = d.budget_limit;
|
|
16066
|
+
var cur = d.current_cost;
|
|
16067
|
+
var curTxt = (cur === null || cur === undefined) ? 'not measured'
|
|
16068
|
+
: ('$' + Number(cur).toFixed(2));
|
|
16069
|
+
if (lim === null || lim === undefined) {
|
|
16070
|
+
el.style.borderColor = 'var(--loki-warning)';
|
|
16071
|
+
el.innerHTML = '<strong>No spend cap set.</strong> This run will not stop on cost. '
|
|
16072
|
+
+ 'Spent so far: ' + curTxt + '. '
|
|
16073
|
+
+ 'Set one with <code>LOKI_BUDGET_LIMIT=<usd></code>.';
|
|
16074
|
+
} else if (d.exceeded) {
|
|
16075
|
+
el.style.borderColor = 'var(--loki-error)';
|
|
16076
|
+
el.innerHTML = '<strong>Budget exceeded.</strong> Cap $' + Number(lim).toFixed(2)
|
|
16077
|
+
+ ', spent ' + curTxt + '.';
|
|
16078
|
+
} else {
|
|
16079
|
+
var rem = (d.remaining === null || d.remaining === undefined)
|
|
16080
|
+
? 'not measured' : ('$' + Number(d.remaining).toFixed(2));
|
|
16081
|
+
el.style.borderColor = 'var(--loki-border)';
|
|
16082
|
+
el.innerHTML = 'Spend cap $' + Number(lim).toFixed(2)
|
|
16083
|
+
+ '. Spent ' + curTxt + ', remaining ' + rem + '.';
|
|
16084
|
+
}
|
|
16085
|
+
el.style.display = 'block';
|
|
16086
|
+
})
|
|
16087
|
+
.catch(function () { /* leave hidden */ });
|
|
16088
|
+
};
|
|
16089
|
+
|
|
16090
|
+
// LEARNINGS. What the build learned from its own gate failures.
|
|
16091
|
+
//
|
|
16092
|
+
// /api/learnings held real records -- rootCause, fix, preventInFuture --
|
|
16093
|
+
// with no UI consumer. The system was learning from its runs and showing
|
|
16094
|
+
// nobody, which makes the memory unfalsifiable: a user cannot correct a
|
|
16095
|
+
// learning they cannot see. Devin's "misleading knowledge" surface is the
|
|
16096
|
+
// same idea and the reason it is worth showing.
|
|
16097
|
+
//
|
|
16098
|
+
// Renders the record's OWN words. Nothing is summarised or re-derived: a
|
|
16099
|
+
// paraphrased root cause is a second claim about a claim.
|
|
16100
|
+
window.loadLearnings = function () {
|
|
16101
|
+
var panel = document.getElementById('learnings-panel');
|
|
16102
|
+
var list = document.getElementById('learnings-list');
|
|
16103
|
+
if (!panel || !list) return;
|
|
16104
|
+
fetch('/api/learnings', { headers: { 'Accept': 'application/json' } })
|
|
16105
|
+
.then(function (r) { return r.ok ? r.json() : null; })
|
|
16106
|
+
.then(function (d) {
|
|
16107
|
+
if (!d) return;
|
|
16108
|
+
var rows = Array.isArray(d) ? d : (d.learnings || []);
|
|
16109
|
+
if (!rows.length) return; // nothing learned yet: say nothing
|
|
16110
|
+
rows = rows.slice().reverse().slice(0, 8);
|
|
16111
|
+
var html = '';
|
|
16112
|
+
for (var i = 0; i < rows.length; i++) {
|
|
16113
|
+
var x = rows[i] || {};
|
|
16114
|
+
var when = x.timestamp ? String(x.timestamp).slice(0, 16).replace('T', ' ') : '-';
|
|
16115
|
+
var iter = (x.iteration === null || x.iteration === undefined) ? '-' : ('iter ' + x.iteration);
|
|
16116
|
+
html += '<div style="padding:8px;border-bottom:1px solid var(--loki-border);font-size:12px;">'
|
|
16117
|
+
+ '<div style="display:flex;gap:10px;color:var(--loki-text-muted);margin-bottom:4px;">'
|
|
16118
|
+
+ '<span>' + when + '</span><span>' + iter + '</span>'
|
|
16119
|
+
+ '<span>' + String(x.trigger || 'unknown trigger') + '</span></div>'
|
|
16120
|
+
+ '<div style="margin-bottom:3px;"><strong>cause:</strong> '
|
|
16121
|
+
+ String(x.rootCause || 'not recorded') + '</div>'
|
|
16122
|
+
+ (x.fix ? '<div style="margin-bottom:3px;"><strong>fix:</strong> ' + String(x.fix) + '</div>' : '')
|
|
16123
|
+
+ (x.preventInFuture ? '<div style="color:var(--loki-text-muted);"><strong>prevent:</strong> '
|
|
16124
|
+
+ String(x.preventInFuture) + '</div>' : '')
|
|
16125
|
+
+ '</div>';
|
|
16126
|
+
}
|
|
16127
|
+
list.innerHTML = html;
|
|
16128
|
+
panel.style.display = 'block';
|
|
16129
|
+
})
|
|
16130
|
+
.catch(function () { /* leave hidden */ });
|
|
16131
|
+
};
|
|
16132
|
+
|
|
16133
|
+
// RECEIPT LIST. Fetched on demand when the Trust section opens, not on a
|
|
16134
|
+
// timer: it is a history view, and polling it would spend a request every
|
|
16135
|
+
// 30s on data that only changes when a run finishes.
|
|
16136
|
+
//
|
|
16137
|
+
// Every field rendered comes straight from the receipt. Nothing is derived,
|
|
16138
|
+
// and an absent value renders as "-" rather than a zero or a guess -- a
|
|
16139
|
+
// fabricated 0 cost or a blank verdict read as "clean" is the exact false
|
|
16140
|
+
// green the receipt exists to prevent.
|
|
16141
|
+
window.loadReceipts = function () {
|
|
16142
|
+
var panel = document.getElementById('receipts-panel');
|
|
16143
|
+
var list = document.getElementById('receipts-list');
|
|
16144
|
+
var note = document.getElementById('receipts-note');
|
|
16145
|
+
if (!panel || !list) return;
|
|
16146
|
+
fetch('/api/proofs', { headers: { 'Accept': 'application/json' } })
|
|
16147
|
+
.then(function (r) { return r.ok ? r.json() : null; })
|
|
16148
|
+
.then(function (d) {
|
|
16149
|
+
if (!d) return; // endpoint absent: leave hidden
|
|
16150
|
+
var rows = Array.isArray(d) ? d : (d.proofs || d.receipts || []);
|
|
16151
|
+
if (!rows.length) return; // no receipts yet: say nothing
|
|
16152
|
+
rows = rows.slice().reverse().slice(0, 10);
|
|
16153
|
+
var html = '';
|
|
16154
|
+
for (var i = 0; i < rows.length; i++) {
|
|
16155
|
+
var x = rows[i] || {};
|
|
16156
|
+
var verdict = x.headline || x.final_verdict || 'UNKNOWN';
|
|
16157
|
+
var verified = /^VERIFIED/i.test(verdict);
|
|
16158
|
+
var col = verified ? 'var(--loki-success)' : 'var(--loki-text-muted)';
|
|
16159
|
+
var files = (x.files_changed === null || x.files_changed === undefined)
|
|
16160
|
+
? '-' : String(x.files_changed);
|
|
16161
|
+
var cost = (x.cost_usd === null || x.cost_usd === undefined)
|
|
16162
|
+
? '-' : ('$' + Number(x.cost_usd).toFixed(2));
|
|
16163
|
+
var when = x.generated_at ? String(x.generated_at).slice(0, 16).replace('T', ' ') : '-';
|
|
16164
|
+
var link = x.has_html
|
|
16165
|
+
? ('<a href="/api/proofs/' + encodeURIComponent(x.run_id || '') + '/html"'
|
|
16166
|
+
+ ' target="_blank" rel="noopener" style="color:var(--loki-accent);">open</a>')
|
|
16167
|
+
: '<span style="color:var(--loki-text-muted);">no html</span>';
|
|
16168
|
+
html += '<div style="display:flex;gap:12px;align-items:center;padding:6px 8px;'
|
|
16169
|
+
+ 'border-bottom:1px solid var(--loki-border);font-size:12px;">'
|
|
16170
|
+
+ '<span style="color:' + col + ';font-weight:600;min-width:130px;">'
|
|
16171
|
+
+ String(verdict).slice(0, 22) + '</span>'
|
|
16172
|
+
+ '<span style="color:var(--loki-text-muted);min-width:120px;">' + when + '</span>'
|
|
16173
|
+
+ '<span style="min-width:90px;">' + files + ' files</span>'
|
|
16174
|
+
+ '<span style="min-width:70px;">' + cost + '</span>'
|
|
16175
|
+
+ link + '</div>';
|
|
16176
|
+
}
|
|
16177
|
+
list.innerHTML = html;
|
|
16178
|
+
if (note) {
|
|
16179
|
+
note.textContent = 'Newest first. "open" renders the receipt itself. '
|
|
16180
|
+
+ 'Re-check any of them: loki proof verify <run-id>';
|
|
16181
|
+
}
|
|
16182
|
+
panel.style.display = 'block';
|
|
16183
|
+
})
|
|
16184
|
+
.catch(function () { /* leave hidden: no receipt surface is better than a wrong one */ });
|
|
16185
|
+
};
|
|
16186
|
+
|
|
16217
16187
|
function poll() {
|
|
16218
16188
|
fetch('/api/proofs/summary', { headers: { 'Accept': 'application/json' } })
|
|
16219
16189
|
.then(function (r) { return r.ok ? r.json() : null; })
|
|
@@ -16258,7 +16228,10 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
16258
16228
|
// document and cannot see the SPA's manual data-loki-theme toggle, so we
|
|
16259
16229
|
// pass the resolved theme as a query param (?theme=dark|light); the
|
|
16260
16230
|
// standalone page reads it and matches. v7.18.0.
|
|
16231
|
+
if (sectionId === 'insights') { loadLearnings(); }
|
|
16232
|
+
if (sectionId === 'cost') { loadBudget(); }
|
|
16261
16233
|
if (sectionId === 'trust') {
|
|
16234
|
+
loadReceipts();
|
|
16262
16235
|
var tframe = document.getElementById('trust-frame');
|
|
16263
16236
|
if (tframe && (!tframe.src || tframe.src === 'about:blank' ||
|
|
16264
16237
|
tframe.getAttribute('src') === 'about:blank')) {
|