loki-mode 7.17.1 → 7.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +2 -2
- package/VERSION +1 -1
- package/dashboard/__init__.py +1 -1
- package/dashboard/server.py +8 -1
- package/dashboard/static/cost.html +41 -5
- package/dashboard/static/index.html +97 -54
- package/dashboard/static/proofs.html +41 -5
- package/dashboard/static/trust.html +44 -5
- package/docs/INSTALLATION.md +1 -1
- package/loki-ts/dist/loki.js +2 -2
- package/mcp/__init__.py +1 -1
- package/package.json +1 -1
|
@@ -340,8 +340,8 @@
|
|
|
340
340
|
cursor: pointer;
|
|
341
341
|
}
|
|
342
342
|
.project-stop-row button:hover:not(:disabled) {
|
|
343
|
-
border-color:
|
|
344
|
-
color:
|
|
343
|
+
border-color: var(--loki-error);
|
|
344
|
+
color: var(--loki-error);
|
|
345
345
|
}
|
|
346
346
|
.project-stop-row button:disabled {
|
|
347
347
|
opacity: 0.6;
|
|
@@ -591,18 +591,18 @@
|
|
|
591
591
|
}
|
|
592
592
|
|
|
593
593
|
/* USAGE.md markdown render styles */
|
|
594
|
-
.usage-md { max-height: 480px; overflow: auto; padding: 12px; background: var(--loki-bg-secondary, #
|
|
595
|
-
.usage-md h1 { font-size: 1.35rem; font-weight: 600; margin: 0.75em 0 0.4em; border-bottom: 1px solid var(--loki-border,
|
|
594
|
+
.usage-md { max-height: 480px; overflow: auto; padding: 12px; background: var(--loki-bg-secondary, #F2F0EB); border-radius: 4px; color: var(--loki-text-primary, #1A1614); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; font-size: 13px; line-height: 1.6; }
|
|
595
|
+
.usage-md h1 { font-size: 1.35rem; font-weight: 600; margin: 0.75em 0 0.4em; border-bottom: 1px solid var(--loki-border, rgba(0,0,0,0.08)); padding-bottom: 4px; }
|
|
596
596
|
.usage-md h2 { font-size: 1.15rem; font-weight: 600; margin: 0.75em 0 0.4em; }
|
|
597
597
|
.usage-md h3 { font-size: 1rem; font-weight: 600; margin: 0.65em 0 0.3em; }
|
|
598
598
|
.usage-md p { margin: 0.4em 0; }
|
|
599
599
|
.usage-md ul, .usage-md ol { margin: 0.4em 0 0.4em 1.5em; padding: 0; }
|
|
600
600
|
.usage-md li { margin: 0.15em 0; }
|
|
601
|
-
.usage-md pre { background: var(--loki-bg-tertiary, #
|
|
601
|
+
.usage-md pre { background: var(--loki-bg-tertiary, #E8E5DE); border: 1px solid var(--loki-border, rgba(0,0,0,0.08)); border-radius: 4px; padding: 10px 12px; overflow-x: auto; margin: 0.5em 0; }
|
|
602
602
|
.usage-md pre code { font-family: 'JetBrains Mono', 'Fira Code', monospace; font-size: 11.5px; background: none; padding: 0; white-space: pre; }
|
|
603
|
-
.usage-md code { font-family: 'JetBrains Mono', 'Fira Code', monospace; font-size: 11.5px; background: var(--loki-bg-tertiary, #
|
|
603
|
+
.usage-md code { font-family: 'JetBrains Mono', 'Fira Code', monospace; font-size: 11.5px; background: var(--loki-bg-tertiary, #E8E5DE); padding: 1px 4px; border-radius: 3px; }
|
|
604
604
|
.usage-md blockquote { border-left: 3px solid var(--loki-accent, #553de9); margin: 0.5em 0; padding: 4px 12px; color: var(--loki-text-secondary, #888); }
|
|
605
|
-
.usage-md hr { border: none; border-top: 1px solid var(--loki-border,
|
|
605
|
+
.usage-md hr { border: none; border-top: 1px solid var(--loki-border, rgba(0,0,0,0.08)); margin: 0.75em 0; }
|
|
606
606
|
.usage-md strong { font-weight: 600; }
|
|
607
607
|
.usage-md em { font-style: italic; }
|
|
608
608
|
.usage-md a { color: var(--loki-accent, #553de9); text-decoration: none; }
|
|
@@ -757,7 +757,7 @@
|
|
|
757
757
|
<h3 style="font-family: 'DM Serif Display', Georgia, serif; font-size: 1.15rem; font-weight: 400; color: var(--loki-text-primary); margin-bottom: 12px;">Memory</h3>
|
|
758
758
|
<loki-memory-browser id="memory-browser" tab="summary"></loki-memory-browser>
|
|
759
759
|
<!-- v7.7.21 token economics tile: hit rate + tokens + top patterns -->
|
|
760
|
-
<div id="memory-economics-tile" style="margin-top: 12px; background: var(--loki-bg-card,
|
|
760
|
+
<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;">
|
|
761
761
|
<div style="font-size: 11px; color: var(--loki-text-muted, #888); margin-bottom: 8px;">Token Economics</div>
|
|
762
762
|
<div id="memory-economics-metrics" style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; font-size: 13px;">
|
|
763
763
|
<div><span style="color: var(--loki-text-muted, #888);">Hit rate</span><br><strong id="econ-hit-rate">--</strong></div>
|
|
@@ -808,11 +808,11 @@
|
|
|
808
808
|
</div>
|
|
809
809
|
<div>
|
|
810
810
|
<h3 style="font-family: 'DM Serif Display', Georgia, serif; font-size: 1.15rem; font-weight: 400; color: var(--loki-text-primary); margin-bottom: 12px;">Memory Files</h3>
|
|
811
|
-
<div id="memory-files-panel" style="background: var(--loki-bg-card,
|
|
811
|
+
<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;">
|
|
812
812
|
<div style="display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px;" id="memory-files-tabs"></div>
|
|
813
813
|
<div style="display: grid; grid-template-columns: minmax(220px, 320px) 1fr; gap: 12px; min-height: 280px;">
|
|
814
|
-
<div id="memory-files-list" style="border: 1px solid var(--loki-border,
|
|
815
|
-
<div id="memory-files-viewer" style="border: 1px solid var(--loki-border,
|
|
814
|
+
<div id="memory-files-list" style="border: 1px solid var(--loki-border, rgba(0,0,0,0.08)); border-radius: 4px; padding: 8px; max-height: 480px; overflow-y: auto; font-size: 12px;">Loading...</div>
|
|
815
|
+
<div id="memory-files-viewer" style="border: 1px solid var(--loki-border, rgba(0,0,0,0.08)); border-radius: 4px; padding: 12px; max-height: 480px; overflow: auto; font-family: 'JetBrains Mono', monospace; font-size: 12px; white-space: pre-wrap; word-break: break-word; color: var(--loki-text-primary, #1A1614);">Select a file to view its contents.</div>
|
|
816
816
|
</div>
|
|
817
817
|
</div>
|
|
818
818
|
<script>
|
|
@@ -836,7 +836,7 @@
|
|
|
836
836
|
function renderTabs(){
|
|
837
837
|
tabsEl.innerHTML = TYPES.map(function(t){
|
|
838
838
|
var active = t.id === state.type;
|
|
839
|
-
return '<button data-type="' + t.id + '" style="padding: 5px 10px; font-size: 11px; border-radius: 4px; border: 1px solid ' + (active ? 'var(--loki-accent, #553de9)' : 'var(--loki-border,
|
|
839
|
+
return '<button data-type="' + t.id + '" style="padding: 5px 10px; font-size: 11px; border-radius: 4px; border: 1px solid ' + (active ? 'var(--loki-accent, #553de9)' : 'var(--loki-border, rgba(0,0,0,0.08))') + '; background: ' + (active ? 'var(--loki-accent, #553de9)' : 'transparent') + '; color: ' + (active ? '#fff' : 'var(--loki-text-primary, #1A1614)') + '; cursor: pointer;">' + esc(t.label) + '</button>';
|
|
840
840
|
}).join('');
|
|
841
841
|
Array.prototype.forEach.call(tabsEl.querySelectorAll('button'), function(b){
|
|
842
842
|
b.addEventListener('click', function(){ loadType(b.getAttribute('data-type')); });
|
|
@@ -893,7 +893,7 @@
|
|
|
893
893
|
<!-- v7.7.1 F-1 follow-up: How to Run (USAGE.md) -->
|
|
894
894
|
<div>
|
|
895
895
|
<h3 style="font-family: 'DM Serif Display', Georgia, serif; font-size: 1.15rem; font-weight: 400; color: var(--loki-text-primary); margin-bottom: 12px;">How to Run (USAGE.md)</h3>
|
|
896
|
-
<div id="usage-doc-panel" style="background: var(--loki-bg-card,
|
|
896
|
+
<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;">
|
|
897
897
|
<div id="usage-doc-meta" style="font-size: 11px; color: var(--loki-text-muted, #888); margin-bottom: 8px;">Loading...</div>
|
|
898
898
|
<div id="usage-doc-content" class="usage-md"></div>
|
|
899
899
|
</div>
|
|
@@ -1116,7 +1116,7 @@
|
|
|
1116
1116
|
<h2 class="section-page-title">Trust Trajectory</h2>
|
|
1117
1117
|
</div>
|
|
1118
1118
|
<iframe id="trust-frame" title="Trust trajectory" src="about:blank"
|
|
1119
|
-
style="width:100%;height:calc(100vh - 160px);border:0;border-radius:8px;background
|
|
1119
|
+
style="width:100%;height:calc(100vh - 160px);border:0;border-radius:8px;background:var(--loki-bg-primary);"></iframe>
|
|
1120
1120
|
</div>
|
|
1121
1121
|
|
|
1122
1122
|
<!-- Checkpoints -->
|
|
@@ -1218,7 +1218,7 @@
|
|
|
1218
1218
|
|
|
1219
1219
|
<!-- Inlined JavaScript Bundle -->
|
|
1220
1220
|
<script>
|
|
1221
|
-
var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropertyDescriptor;var se=Object.getOwnPropertyNames;var re=Object.prototype.hasOwnProperty;var oe=(d,t,e)=>t in d?$t(d,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):d[t]=e;var ne=(d,t)=>{for(var e in t)$t(d,e,{get:t[e],enumerable:!0})},le=(d,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of se(t))!re.call(d,a)&&a!==e&&$t(d,a,{get:()=>t[a],enumerable:!(i=ae(t,a))||i.enumerable});return d};var de=d=>le($t({},"__esModule",{value:!0}),d);var C=(d,t,e)=>oe(d,typeof t!="symbol"?t+"":t,e);var Me={};ne(Me,{ANIMATION:()=>L,ARIA_PATTERNS:()=>St,ApiEvents:()=>m,BASE_STYLES:()=>U,BREAKPOINTS:()=>Et,COMMON_STYLES:()=>Mt,KEYBOARD_SHORTCUTS:()=>Ct,KeyboardHandler:()=>P,LokiActivityStream:()=>ut,LokiAgentLeaderboard:()=>kt,LokiAnalytics:()=>ot,LokiApiClient:()=>M,LokiApiKeys:()=>pt,LokiAppStatus:()=>Q,LokiAuditViewer:()=>ct,LokiChecklistViewer:()=>W,LokiCheckpointViewer:()=>Z,LokiContextTracker:()=>tt,LokiCostDashboard:()=>X,LokiCostWaterfall:()=>ft,LokiCouncilDashboard:()=>Y,LokiCouncilTranscripts:()=>yt,LokiElement:()=>h,LokiEscalations:()=>_t,LokiLearningDashboard:()=>V,LokiLogStream:()=>G,LokiManagedMemoryPanel:()=>xt,LokiMemoryBrowser:()=>K,LokiMemoryGraph:()=>bt,LokiMigrationDashboard:()=>rt,LokiNotificationCenter:()=>et,LokiOverview:()=>O,LokiPipelineView:()=>vt,LokiPromptOptimizer:()=>at,LokiProviderHealth:()=>gt,LokiQualityGates:()=>nt,LokiQualityScore:()=>st,LokiRarvTimeline:()=>lt,LokiRunManager:()=>dt,LokiSessionControl:()=>J,LokiSessionDiff:()=>it,LokiState:()=>N,LokiTaskBoard:()=>q,LokiTenantSwitcher:()=>ht,LokiTheme:()=>R,LokiWikiBrowser:()=>wt,RADIUS:()=>I,SPACING:()=>A,STATE_CHANGE_EVENT:()=>It,THEMES:()=>E,THEME_VARIABLES:()=>At,TYPOGRAPHY:()=>y,UnifiedThemeManager:()=>_,VERSION:()=>Be,Z_INDEX:()=>D,createApiClient:()=>Ut,createStore:()=>Nt,generateThemeCSS:()=>$,generateTokensCSS:()=>j,getApiClient:()=>g,getState:()=>B,init:()=>Pe});var E={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":"#7B6BF0","--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":"#7B6BF0","--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":"#7B6BF0","--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":"#7B6BF0","--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)"}},A={xs:"4px",sm:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"32px","3xl":"48px"},I={none:"0",sm:"2px",md:"4px",lg:"5px",xl:"5px",full:"9999px"},y={fontFamily:{sans:"'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif",serif:"'DM Serif Display', 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"}},L={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)"}},Et={sm:"640px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},D={base:"0",dropdown:"100",sticky:"200",modal:"300",popover:"400",tooltip:"500",toast:"600"},Ct={"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"]}},St={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 $(d){let t=E[d];return t?Object.entries(t).map(([e,i])=>`${e}: ${i};`).join(`
|
|
1221
|
+
var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropertyDescriptor;var se=Object.getOwnPropertyNames;var re=Object.prototype.hasOwnProperty;var oe=(d,t,e)=>t in d?$t(d,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):d[t]=e;var ne=(d,t)=>{for(var e in t)$t(d,e,{get:t[e],enumerable:!0})},le=(d,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of se(t))!re.call(d,a)&&a!==e&&$t(d,a,{get:()=>t[a],enumerable:!(i=ae(t,a))||i.enumerable});return d};var de=d=>le($t({},"__esModule",{value:!0}),d);var C=(d,t,e)=>oe(d,typeof t!="symbol"?t+"":t,e);var Me={};ne(Me,{ANIMATION:()=>L,ARIA_PATTERNS:()=>St,ApiEvents:()=>v,BASE_STYLES:()=>U,BREAKPOINTS:()=>Et,COMMON_STYLES:()=>Mt,KEYBOARD_SHORTCUTS:()=>Ct,KeyboardHandler:()=>P,LokiActivityStream:()=>ut,LokiAgentLeaderboard:()=>kt,LokiAnalytics:()=>ot,LokiApiClient:()=>M,LokiApiKeys:()=>pt,LokiAppStatus:()=>Q,LokiAuditViewer:()=>ct,LokiChecklistViewer:()=>W,LokiCheckpointViewer:()=>Z,LokiContextTracker:()=>tt,LokiCostDashboard:()=>X,LokiCostWaterfall:()=>ft,LokiCouncilDashboard:()=>Y,LokiCouncilTranscripts:()=>yt,LokiElement:()=>h,LokiEscalations:()=>_t,LokiLearningDashboard:()=>V,LokiLogStream:()=>G,LokiManagedMemoryPanel:()=>xt,LokiMemoryBrowser:()=>K,LokiMemoryGraph:()=>bt,LokiMigrationDashboard:()=>rt,LokiNotificationCenter:()=>et,LokiOverview:()=>O,LokiPipelineView:()=>mt,LokiPromptOptimizer:()=>at,LokiProviderHealth:()=>gt,LokiQualityGates:()=>nt,LokiQualityScore:()=>st,LokiRarvTimeline:()=>lt,LokiRunManager:()=>dt,LokiSessionControl:()=>J,LokiSessionDiff:()=>it,LokiState:()=>N,LokiTaskBoard:()=>q,LokiTenantSwitcher:()=>ht,LokiTheme:()=>R,LokiWikiBrowser:()=>wt,RADIUS:()=>I,SPACING:()=>A,STATE_CHANGE_EVENT:()=>It,THEMES:()=>E,THEME_VARIABLES:()=>At,TYPOGRAPHY:()=>y,UnifiedThemeManager:()=>_,VERSION:()=>Be,Z_INDEX:()=>D,createApiClient:()=>Ut,createStore:()=>Nt,generateThemeCSS:()=>$,generateTokensCSS:()=>j,getApiClient:()=>g,getState:()=>B,init:()=>Pe});var E={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":"#7B6BF0","--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":"#7B6BF0","--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":"#7B6BF0","--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":"#7B6BF0","--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)"}},A={xs:"4px",sm:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"32px","3xl":"48px"},I={none:"0",sm:"2px",md:"4px",lg:"5px",xl:"5px",full:"9999px"},y={fontFamily:{sans:"'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif",serif:"'DM Serif Display', 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"}},L={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)"}},Et={sm:"640px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},D={base:"0",dropdown:"100",sticky:"200",modal:"300",popover:"400",tooltip:"500",toast:"600"},Ct={"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"]}},St={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 $(d){let t=E[d];return t?Object.entries(t).map(([e,i])=>`${e}: ${i};`).join(`
|
|
1222
1222
|
`):""}function j(){return`
|
|
1223
1223
|
/* Spacing */
|
|
1224
1224
|
--loki-space-xs: ${A.xs};
|
|
@@ -1711,7 +1711,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
1711
1711
|
}
|
|
1712
1712
|
|
|
1713
1713
|
${U}
|
|
1714
|
-
`}getAriaPattern(t){return St[t]||{}}applyAriaPattern(t,e){let i=this.getAriaPattern(e);for(let[a,s]of Object.entries(i))if(a==="role")t.setAttribute("role",s);else{let r=a.replace(/([A-Z])/g,"-$1").toLowerCase();t.setAttribute(r,s)}}render(){}};var z={realtime:1e3,normal:2e3,background:5e3,offline:1e4},Ft={vscode:z.normal,browser:z.realtime,cli:z.background},jt={baseUrl:typeof window<"u"?window.location.origin:"http://localhost:57374",wsUrl:typeof window<"u"?`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/ws`:"ws://localhost:57374/ws",pollInterval:2e3,timeout:1e4,retryAttempts:3,retryDelay:1e3},m={CONNECTED:"api:connected",DISCONNECTED:"api:disconnected",ERROR:"api:error",STATUS_UPDATE:"api:status-update",TASK_CREATED:"api:task-created",TASK_UPDATED:"api:task-updated",TASK_DELETED:"api:task-deleted",PROJECT_CREATED:"api:project-created",PROJECT_UPDATED:"api:project-updated",AGENT_UPDATE:"api:agent-update",LOG_MESSAGE:"api:log-message",MEMORY_UPDATE:"api:memory-update",CHECKLIST_UPDATE:"api:checklist-update"},T=class T extends EventTarget{static getInstance(t={}){let e=t.baseUrl||jt.baseUrl;return T._instances.has(e)||T._instances.set(e,new T(t)),T._instances.get(e)}static clearInstances(){T._instances.forEach(t=>t.disconnect()),T._instances.clear()}constructor(t={}){super(),this.config={...jt,...t},this._ws=null,this._connected=!1,this._pollInterval=null,this._reconnectTimeout=null,this._reconnectAttempts=0,this._maxReconnectAttempts=20,this._cache=new Map,this._cacheTimeout=5e3,this._vscodeApi=null,this._context=this._detectContext(),this._currentPollInterval=Ft[this._context]||z.normal,this._visibilityChangeHandler=null,this._messageHandler=null,this._setupAdaptivePolling(),this._setupVSCodeBridge()}_detectContext(){return typeof acquireVsCodeApi<"u"?"vscode":typeof window<"u"&&window.location?"browser":"cli"}get context(){return this._context}static get POLL_INTERVALS(){return z}_setupAdaptivePolling(){typeof document>"u"||(this._visibilityChangeHandler=()=>{document.hidden?this._setPollInterval(z.background):this._setPollInterval(Ft[this._context]||z.normal)},document.addEventListener("visibilitychange",this._visibilityChangeHandler))}_setPollInterval(t){this._currentPollInterval=t,this._pollInterval&&(this.stopPolling(),this.startPolling(null,t))}setPollMode(t){let e=z[t];e&&this._setPollInterval(e)}_setupVSCodeBridge(){if(!(typeof acquireVsCodeApi>"u")){try{this._vscodeApi=acquireVsCodeApi()}catch{console.warn("VS Code API already acquired or unavailable");return}this._messageHandler=t=>{let e=t.data;if(!(!e||!e.type))switch(e.type){case"updateStatus":this._emit(m.STATUS_UPDATE,e.data);break;case"updateTasks":this._emit(m.TASK_UPDATED,e.data);break;case"taskCreated":this._emit(m.TASK_CREATED,e.data);break;case"taskDeleted":this._emit(m.TASK_DELETED,e.data);break;case"projectCreated":this._emit(m.PROJECT_CREATED,e.data);break;case"projectUpdated":this._emit(m.PROJECT_UPDATED,e.data);break;case"agentUpdate":this._emit(m.AGENT_UPDATE,e.data);break;case"logMessage":this._emit(m.LOG_MESSAGE,e.data);break;case"memoryUpdate":this._emit(m.MEMORY_UPDATE,e.data);break;case"connected":this._connected=!0,this._emit(m.CONNECTED,e.data);break;case"disconnected":this._connected=!1,this._emit(m.DISCONNECTED,e.data);break;case"error":this._emit(m.ERROR,e.data);break;case"setPollMode":this.setPollMode(e.data.mode);break;default:this._emit(`api:${e.type}`,e.data)}},window.addEventListener("message",this._messageHandler)}}get isVSCode(){return this._context==="vscode"}postToVSCode(t,e={}){this._vscodeApi&&this._vscodeApi.postMessage({type:t,data:e})}requestRefresh(){this.postToVSCode("requestRefresh")}notifyVSCode(t,e={}){this.postToVSCode("userAction",{action:t,...e})}get baseUrl(){return this.config.baseUrl}set baseUrl(t){this.config.baseUrl=t,this.config.wsUrl=t.replace(/^http/,"ws")+"/ws"}get isConnected(){return this._connected}async connect(){if(!(this._ws&&this._ws.readyState===WebSocket.OPEN))return new Promise((t,e)=>{try{this._ws=new WebSocket(this.config.wsUrl),this._ws.onopen=()=>{this._connected=!0,this._reconnectAttempts=0,this._emit(m.CONNECTED),t()},this._ws.onclose=()=>{this._connected=!1,this._emit(m.DISCONNECTED),this._scheduleReconnect()},this._ws.onerror=i=>{this._emit(m.ERROR,{error:i}),e(i)},this._ws.onmessage=i=>{try{let a=JSON.parse(i.data);this._handleMessage(a)}catch(a){console.error("Failed to parse WebSocket message:",a)}}}catch(i){e(i)}})}disconnect(){this._ws&&(this._ws.close(),this._ws=null),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._reconnectTimeout&&(clearTimeout(this._reconnectTimeout),this._reconnectTimeout=null),this._connected=!1,this._cleanupGlobalListeners()}_cleanupGlobalListeners(){this._visibilityChangeHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this._visibilityChangeHandler),this._visibilityChangeHandler=null),this._messageHandler&&typeof window<"u"&&(window.removeEventListener("message",this._messageHandler),this._messageHandler=null)}destroy(){this.disconnect()}_scheduleReconnect(){if(this._reconnectTimeout)return;if(this._reconnectAttempts>=this._maxReconnectAttempts){console.warn("WebSocket max reconnect attempts reached, giving up"),this._emit(m.ERROR,{error:"Max reconnect attempts reached"});return}let t=Math.min(this.config.retryDelay*Math.pow(2,this._reconnectAttempts),3e4);this._reconnectAttempts++,this._reconnectTimeout=setTimeout(()=>{this._reconnectTimeout=null,this.connect().catch(()=>{})},t)}_handleMessage(t){if(t.type==="ping"){this._ws&&this._ws.readyState===WebSocket.OPEN&&this._ws.send(JSON.stringify({type:"pong"}));return}let i={connected:m.CONNECTED,status_update:m.STATUS_UPDATE,task_created:m.TASK_CREATED,task_updated:m.TASK_UPDATED,task_deleted:m.TASK_DELETED,task_moved:m.TASK_UPDATED,project_created:m.PROJECT_CREATED,project_updated:m.PROJECT_UPDATED,agent_update:m.AGENT_UPDATE,log:m.LOG_MESSAGE}[t.type]||`api:${t.type}`;this._emit(i,t.data)}_emit(t,e={}){this.dispatchEvent(new CustomEvent(t,{detail:e}))}async _request(t,e={}){let i=`${this.config.baseUrl}${t}`,a=new AbortController,s=setTimeout(()=>a.abort(),this.config.timeout);try{let r=await fetch(i,{...e,signal:a.signal,credentials:"include",headers:{"Content-Type":"application/json",...e.headers}});if(clearTimeout(s),!r.ok){let o=await r.text().catch(()=>""),n=r.statusText||`HTTP ${r.status}`;if(o)try{let l=JSON.parse(o);n=l.detail||l.error||l.message||n}catch{n=o.length>200?o.slice(0,200)+"...":o}throw new Error(n)}return r.status===204?null:await r.json()}catch(r){throw clearTimeout(s),r.name==="AbortError"?new Error("Request timeout"):r}}async _get(t,e=!1){if(e&&this._cache.has(t)){let a=this._cache.get(t);if(Date.now()-a.timestamp<this._cacheTimeout)return a.data}let i=await this._request(t);return e&&this._cache.set(t,{data:i,timestamp:Date.now()}),i}async _post(t,e){return this._request(t,{method:"POST",body:JSON.stringify(e)})}async _put(t,e){return this._request(t,{method:"PUT",body:JSON.stringify(e)})}async _delete(t){return this._request(t,{method:"DELETE"})}async get(t){return this._get(t)}async getStatus(){return this._get("/api/status")}async healthCheck(){return this._get("/health")}async listProjects(t=null){let e=t?`?status=${t}`:"";return this._get(`/api/projects${e}`)}async getProject(t){return this._get(`/api/projects/${t}`)}async createProject(t){return this._post("/api/projects",t)}async updateProject(t,e){return this._put(`/api/projects/${t}`,e)}async deleteProject(t){return this._delete(`/api/projects/${t}`)}async listTasks(t={}){let e=new URLSearchParams;t.projectId&&e.append("project_id",t.projectId),t.status&&e.append("status",t.status),t.priority&&e.append("priority",t.priority);let i=e.toString()?`?${e}`:"";return this._get(`/api/tasks${i}`)}async getTask(t){return this._get(`/api/tasks/${t}`)}async createTask(t){return this._post("/api/tasks",t)}async updateTask(t,e){return this._put(`/api/tasks/${t}`,e)}async moveTask(t,e,i){return this._post(`/api/tasks/${t}/move`,{status:e,position:i})}async deleteTask(t){return this._delete(`/api/tasks/${t}`)}async getMemorySummary(){return this._get("/api/memory/summary",!0)}async getMemoryIndex(){return this._get("/api/memory/index",!0)}async getMemoryTimeline(){return this._get("/api/memory/timeline")}async listEpisodes(t={}){let e=new URLSearchParams(t).toString();return this._get(`/api/memory/episodes${e?"?"+e:""}`)}async getEpisode(t){return this._get(`/api/memory/episodes/${t}`)}async listPatterns(t={}){let e=new URLSearchParams(t).toString();return this._get(`/api/memory/patterns${e?"?"+e:""}`)}async getPattern(t){return this._get(`/api/memory/patterns/${t}`)}async listSkills(){return this._get("/api/memory/skills")}async getSkill(t){return this._get(`/api/memory/skills/${t}`)}async retrieveMemories(t,e=null,i=5){return this._post("/api/memory/retrieve",{query:t,taskType:e,topK:i})}async consolidateMemory(t=24){return this._post("/api/memory/consolidate",{sinceHours:t})}async getTokenEconomics(){return this._get("/api/memory/economics")}async searchMemory(t,e="all",i=20){let a=new URLSearchParams({q:t,collection:e,limit:String(i)});return this._get(`/api/memory/search?${a}`)}async getMemoryStats(){return this._get("/api/memory/stats",!0)}async listRegisteredProjects(t=!1){return this._get(`/api/registry/projects?include_inactive=${t}`)}async registerProject(t,e=null,i=null){return this._post("/api/registry/projects",{path:t,name:e,alias:i})}async discoverProjects(t=3){return this._get(`/api/registry/discover?max_depth=${t}`)}async syncRegistry(){return this._post("/api/registry/sync",{})}async getCrossProjectTasks(t=null){let e=t?`?project_ids=${t.join(",")}`:"";return this._get(`/api/registry/tasks${e}`)}async getLearningMetrics(t={}){let e=new URLSearchParams;t.timeRange&&e.append("timeRange",t.timeRange),t.signalType&&e.append("signalType",t.signalType),t.source&&e.append("source",t.source);let i=e.toString()?`?${e}`:"";return this._get(`/api/learning/metrics${i}`)}async getLearningTrends(t={}){let e=new URLSearchParams;t.timeRange&&e.append("timeRange",t.timeRange),t.signalType&&e.append("signalType",t.signalType),t.source&&e.append("source",t.source);let i=e.toString()?`?${e}`:"";return this._get(`/api/learning/trends${i}`)}async getLearningSignals(t={}){let e=new URLSearchParams;t.timeRange&&e.append("timeRange",t.timeRange),t.signalType&&e.append("signalType",t.signalType),t.source&&e.append("source",t.source),t.limit&&e.append("limit",String(t.limit)),t.offset&&e.append("offset",String(t.offset));let i=e.toString()?`?${e}`:"";return this._get(`/api/learning/signals${i}`)}async getLatestAggregation(){return this._get("/api/learning/aggregation")}async triggerAggregation(t={}){return this._post("/api/learning/aggregate",t)}async getAggregatedPreferences(t=20){return this._get(`/api/learning/preferences?limit=${t}`)}async getAggregatedErrors(t=20){return this._get(`/api/learning/errors?limit=${t}`)}async getAggregatedSuccessPatterns(t=20){return this._get(`/api/learning/success?limit=${t}`)}async getToolEfficiency(t=20){return this._get(`/api/learning/tools?limit=${t}`)}async getCost(){return this._get("/api/cost")}async getPricing(){return this._get("/api/pricing")}async getCouncilState(){return this._get("/api/council/state")}async getCouncilVerdicts(t=20){return this._get(`/api/council/verdicts?limit=${t}`)}async getCouncilConvergence(){return this._get("/api/council/convergence")}async getCouncilReport(){return this._get("/api/council/report")}async forceCouncilReview(){return this._post("/api/council/force-review",{})}async getContext(){return this._get("/api/context")}async getNotifications(t,e){let i=new URLSearchParams;t&&i.set("severity",t),e&&i.set("unread_only","true");let a=i.toString();return this._get("/api/notifications"+(a?"?"+a:""))}async getNotificationTriggers(){return this._get("/api/notifications/triggers")}async updateNotificationTriggers(t){return this._put("/api/notifications/triggers",{triggers:t})}async acknowledgeNotification(t){return this._post("/api/notifications/"+encodeURIComponent(t)+"/acknowledge",{})}async pauseSession(){return this._post("/api/control/pause",{})}async resumeSession(){return this._post("/api/control/resume",{})}async stopSession(){return this._post("/api/control/stop",{})}async getLogs(t=100){return this._get(`/api/logs?lines=${t}`)}async getChecklist(){return this._get("/api/checklist")}async getChecklistSummary(){return this._get("/api/checklist/summary")}async getPrdObservations(){let t=await fetch(`${this.baseUrl}/api/prd-observations`,{credentials:"include"});if(!t.ok)throw new Error(`HTTP ${t.status}`);return t.text()}async getChecklistWaivers(){return this._get("/api/checklist/waivers")}async addChecklistWaiver(t,e,i="dashboard"){return this._post("/api/checklist/waivers",{item_id:t,reason:e,waived_by:i})}async removeChecklistWaiver(t){return this._delete(`/api/checklist/waivers/${encodeURIComponent(t)}`)}async getCouncilGate(){return this._get("/api/council/gate")}async getAppRunnerStatus(){return this._get("/api/app-runner/status")}async getAppRunnerLogs(t=100){return this._get(`/api/app-runner/logs?lines=${t}`)}async restartApp(){return this._post("/api/control/app-restart",{})}async stopApp(){return this._post("/api/control/app-stop",{})}async getPlaywrightResults(){return this._get("/api/playwright/results")}async getPlaywrightScreenshot(){return this._get("/api/playwright/screenshot")}startPolling(t,e=null){if(this._pollInterval)return;this._pollCallback=t;let i=async()=>{try{let s=await this.getStatus();this._connected=!0,this._pollCallback&&this._pollCallback(s),this._emit(m.STATUS_UPDATE,s),this._vscodeApi&&this.postToVSCode("pollSuccess",{timestamp:Date.now()})}catch(s){this._connected=!1,this._emit(m.ERROR,{error:s}),this._vscodeApi&&this.postToVSCode("pollError",{error:s.message})}};i();let a=e||this._currentPollInterval||this.config.pollInterval;this._pollInterval=setInterval(i,a)}stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}};C(T,"_instances",new Map);var M=T;function Ut(d={}){return new M(d)}function g(d={}){return M.getInstance(d)}var It="loki-state-change",Tt={ui:{theme:"light",sidebarCollapsed:!1,activeSection:"kanban",terminalAutoScroll:!0},session:{connected:!1,lastSync:null,mode:"offline",phase:null,iteration:null},localTasks:[],cache:{projects:[],tasks:[],agents:[],memory:null,lastFetch:null},preferences:{pollInterval:2e3,notifications:!0,soundEnabled:!1}},S=class S extends EventTarget{static getInstance(){return S._instance||(S._instance=new S),S._instance}constructor(){super(),this._state=this._loadState(),this._subscribers=new Map,this._batchUpdates=[],this._batchTimeout=null}_loadState(){try{let t=localStorage.getItem(S.STORAGE_KEY);if(t){let e=JSON.parse(t);return this._mergeState(Tt,e)}}catch(t){console.warn("Failed to load state from localStorage:",t)}return{...Tt}}_mergeState(t,e){let i={...t};for(let a of Object.keys(e))a in t&&typeof t[a]=="object"&&!Array.isArray(t[a])?i[a]=this._mergeState(t[a],e[a]):i[a]=e[a];return i}_saveState(){try{let t={ui:this._state.ui,localTasks:this._state.localTasks,preferences:this._state.preferences};localStorage.setItem(S.STORAGE_KEY,JSON.stringify(t))}catch(t){console.warn("Failed to save state to localStorage:",t)}}get(t=null){if(!t)return{...this._state};let e=t.split("."),i=this._state;for(let a of e){if(i==null)return;i=i[a]}return i}set(t,e,i=!0){let a=t.split("."),s=a.pop(),r=this._state;for(let n of a)n in r||(r[n]={}),r=r[n];let o=r[s];r[s]=e,i&&this._saveState(),this._notifyChange(t,e,o)}update(t,e=!0){let i=[];for(let[a,s]of Object.entries(t)){let r=this.get(a);this.set(a,s,!1),i.push({path:a,value:s,oldValue:r})}e&&this._saveState();for(let a of i)this._notifyChange(a.path,a.value,a.oldValue)}_notifyChange(t,e,i){this.dispatchEvent(new CustomEvent(It,{detail:{path:t,value:e,oldValue:i}}));let a=this._subscribers.get(t)||[];for(let r of a)try{r(e,i,t)}catch(o){console.error("State subscriber error:",o)}let s=t.split(".");for(;s.length>1;){s.pop();let r=s.join("."),o=this._subscribers.get(r)||[];for(let n of o)try{n(this.get(r),null,r)}catch(l){console.error("State subscriber error:",l)}}}subscribe(t,e){return this._subscribers.has(t)||this._subscribers.set(t,[]),this._subscribers.get(t).push(e),()=>{let i=this._subscribers.get(t),a=i.indexOf(e);a>-1&&i.splice(a,1)}}reset(t=null){if(t){let e=t.split("."),i=Tt;for(let a of e)i=i?.[a];this.set(t,i)}else this._state={...Tt},this._saveState(),this.dispatchEvent(new CustomEvent(It,{detail:{path:null,value:this._state,oldValue:null}}))}addLocalTask(t){let e=this.get("localTasks")||[],i={id:`local-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,createdAt:new Date().toISOString(),status:"pending",...t};return this.set("localTasks",[...e,i]),i}updateLocalTask(t,e){let i=this.get("localTasks")||[],a=i.findIndex(r=>r.id===t);if(a===-1)return null;let s={...i[a],...e,updatedAt:new Date().toISOString()};return i[a]=s,this.set("localTasks",[...i]),s}deleteLocalTask(t){let e=this.get("localTasks")||[];this.set("localTasks",e.filter(i=>i.id!==t))}moveLocalTask(t,e,i=null){let s=(this.get("localTasks")||[]).find(r=>r.id===t);return s?this.updateLocalTask(t,{status:e,position:i??s.position}):null}updateSession(t){this.update(Object.fromEntries(Object.entries(t).map(([e,i])=>[`session.${e}`,i])),!1)}updateCache(t){this.update({"cache.projects":t.projects??this.get("cache.projects"),"cache.tasks":t.tasks??this.get("cache.tasks"),"cache.agents":t.agents??this.get("cache.agents"),"cache.memory":t.memory??this.get("cache.memory"),"cache.lastFetch":new Date().toISOString()},!1)}getMergedTasks(){let t=this.get("cache.tasks")||[],i=(this.get("localTasks")||[]).map(a=>({...a,isLocal:!0}));return[...t,...i]}getTasksByStatus(t){return this.getMergedTasks().filter(e=>e.status===t)}};C(S,"STORAGE_KEY","loki-dashboard-state"),C(S,"_instance",null);var N=S;function B(){return N.getInstance()}function Nt(d){let t=B();return{get:()=>t.get(d),set:e=>t.set(d,e),subscribe:e=>t.subscribe(d,e)}}var O=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data={status:"offline",phase:null,iteration:null,provider:null,running_agents:0,pending_tasks:null,uptime_seconds:0,complexity:null,connected:!1},this._api=null,this._pollInterval=null,this._statusUpdateHandler=null,this._connectedHandler=null,this._disconnectedHandler=null,this._checklistSummary=null,this._appRunnerStatus=null,this._playwrightResults=null,this._gateStatus=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._startPolling(),this._api.connect().catch(()=>{})}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._loadAbortController&&(this._loadAbortController.abort(),this._loadAbortController=null),this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(m.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(m.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(m.DISCONNECTED,this._disconnectedHandler))}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadStatus()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t}),this._statusUpdateHandler=e=>this._updateFromStatus(e.detail),this._connectedHandler=()=>{this._data.connected=!0,this.render()},this._disconnectedHandler=()=>{this._data.connected=!1,this._data.status="offline",this.render()},this._api.addEventListener(m.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(m.CONNECTED,this._connectedHandler),this._api.addEventListener(m.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){this._loadAbortController&&this._loadAbortController.abort(),this._loadAbortController=new AbortController;let{signal:t}=this._loadAbortController;try{let[e,i,a,s,r]=await Promise.allSettled([this._api.getStatus(),this._api.getChecklistSummary(),this._api.getAppRunnerStatus(),this._api.getPlaywrightResults(),this._api.getCouncilGate()]);if(t.aborted)return;e.status==="fulfilled"?this._updateFromStatus(e.value):(this._data.connected=!1,this._data.status="offline"),i.status==="fulfilled"&&(this._checklistSummary=i.value?.summary||null),a.status==="fulfilled"&&(this._appRunnerStatus=a.value),s.status==="fulfilled"&&(this._playwrightResults=s.value),r.status==="fulfilled"&&(this._gateStatus=r.value),this.render()}catch{if(t.aborted)return;this._data.connected=!1,this._data.status="offline",this.render()}}_updateFromStatus(t){t&&(this._data={...this._data,connected:!0,status:t.status||"offline",phase:t.phase||null,iteration:t.iteration!=null?t.iteration:null,provider:t.provider||null,running_agents:t.running_agents||0,pending_tasks:t.pending_tasks!=null?t.pending_tasks:null,uptime_seconds:t.uptime_seconds||0,complexity:t.complexity||null})}_startPolling(){this._pollInterval=setInterval(async()=>{try{await this._loadStatus()}catch{this._data.connected=!1,this._data.status="offline",this.render()}},5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_formatUptime(t){if(!t||t<0)return"--";let e=Math.floor(t/3600),i=Math.floor(t%3600/60),a=Math.floor(t%60);return e>0?`${e}h ${i}m`:i>0?`${i}m ${a}s`:`${a}s`}_getStatusDotClass(){switch(this._data.status){case"running":case"autonomous":return"active";case"paused":return"paused";case"stopped":return"stopped";case"error":return"error";default:return"offline"}}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_renderAppRunnerCard(){let t=this._appRunnerStatus;if(!t||t.status==="not_initialized")return`
|
|
1714
|
+
`}getAriaPattern(t){return St[t]||{}}applyAriaPattern(t,e){let i=this.getAriaPattern(e);for(let[a,s]of Object.entries(i))if(a==="role")t.setAttribute("role",s);else{let r=a.replace(/([A-Z])/g,"-$1").toLowerCase();t.setAttribute(r,s)}}render(){}};var z={realtime:1e3,normal:2e3,background:5e3,offline:1e4},Ft={vscode:z.normal,browser:z.realtime,cli:z.background},jt={baseUrl:typeof window<"u"?window.location.origin:"http://localhost:57374",wsUrl:typeof window<"u"?`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/ws`:"ws://localhost:57374/ws",pollInterval:2e3,timeout:1e4,retryAttempts:3,retryDelay:1e3},v={CONNECTED:"api:connected",DISCONNECTED:"api:disconnected",ERROR:"api:error",STATUS_UPDATE:"api:status-update",TASK_CREATED:"api:task-created",TASK_UPDATED:"api:task-updated",TASK_DELETED:"api:task-deleted",PROJECT_CREATED:"api:project-created",PROJECT_UPDATED:"api:project-updated",AGENT_UPDATE:"api:agent-update",LOG_MESSAGE:"api:log-message",MEMORY_UPDATE:"api:memory-update",CHECKLIST_UPDATE:"api:checklist-update"},T=class T extends EventTarget{static getInstance(t={}){let e=t.baseUrl||jt.baseUrl;return T._instances.has(e)||T._instances.set(e,new T(t)),T._instances.get(e)}static clearInstances(){T._instances.forEach(t=>t.disconnect()),T._instances.clear()}constructor(t={}){super(),this.config={...jt,...t},this._ws=null,this._connected=!1,this._pollInterval=null,this._reconnectTimeout=null,this._reconnectAttempts=0,this._maxReconnectAttempts=20,this._cache=new Map,this._cacheTimeout=5e3,this._vscodeApi=null,this._context=this._detectContext(),this._currentPollInterval=Ft[this._context]||z.normal,this._visibilityChangeHandler=null,this._messageHandler=null,this._setupAdaptivePolling(),this._setupVSCodeBridge()}_detectContext(){return typeof acquireVsCodeApi<"u"?"vscode":typeof window<"u"&&window.location?"browser":"cli"}get context(){return this._context}static get POLL_INTERVALS(){return z}_setupAdaptivePolling(){typeof document>"u"||(this._visibilityChangeHandler=()=>{document.hidden?this._setPollInterval(z.background):this._setPollInterval(Ft[this._context]||z.normal)},document.addEventListener("visibilitychange",this._visibilityChangeHandler))}_setPollInterval(t){this._currentPollInterval=t,this._pollInterval&&(this.stopPolling(),this.startPolling(null,t))}setPollMode(t){let e=z[t];e&&this._setPollInterval(e)}_setupVSCodeBridge(){if(!(typeof acquireVsCodeApi>"u")){try{this._vscodeApi=acquireVsCodeApi()}catch{console.warn("VS Code API already acquired or unavailable");return}this._messageHandler=t=>{let e=t.data;if(!(!e||!e.type))switch(e.type){case"updateStatus":this._emit(v.STATUS_UPDATE,e.data);break;case"updateTasks":this._emit(v.TASK_UPDATED,e.data);break;case"taskCreated":this._emit(v.TASK_CREATED,e.data);break;case"taskDeleted":this._emit(v.TASK_DELETED,e.data);break;case"projectCreated":this._emit(v.PROJECT_CREATED,e.data);break;case"projectUpdated":this._emit(v.PROJECT_UPDATED,e.data);break;case"agentUpdate":this._emit(v.AGENT_UPDATE,e.data);break;case"logMessage":this._emit(v.LOG_MESSAGE,e.data);break;case"memoryUpdate":this._emit(v.MEMORY_UPDATE,e.data);break;case"connected":this._connected=!0,this._emit(v.CONNECTED,e.data);break;case"disconnected":this._connected=!1,this._emit(v.DISCONNECTED,e.data);break;case"error":this._emit(v.ERROR,e.data);break;case"setPollMode":this.setPollMode(e.data.mode);break;default:this._emit(`api:${e.type}`,e.data)}},window.addEventListener("message",this._messageHandler)}}get isVSCode(){return this._context==="vscode"}postToVSCode(t,e={}){this._vscodeApi&&this._vscodeApi.postMessage({type:t,data:e})}requestRefresh(){this.postToVSCode("requestRefresh")}notifyVSCode(t,e={}){this.postToVSCode("userAction",{action:t,...e})}get baseUrl(){return this.config.baseUrl}set baseUrl(t){this.config.baseUrl=t,this.config.wsUrl=t.replace(/^http/,"ws")+"/ws"}get isConnected(){return this._connected}async connect(){if(!(this._ws&&this._ws.readyState===WebSocket.OPEN))return new Promise((t,e)=>{try{this._ws=new WebSocket(this.config.wsUrl),this._ws.onopen=()=>{this._connected=!0,this._reconnectAttempts=0,this._emit(v.CONNECTED),t()},this._ws.onclose=()=>{this._connected=!1,this._emit(v.DISCONNECTED),this._scheduleReconnect()},this._ws.onerror=i=>{this._emit(v.ERROR,{error:i}),e(i)},this._ws.onmessage=i=>{try{let a=JSON.parse(i.data);this._handleMessage(a)}catch(a){console.error("Failed to parse WebSocket message:",a)}}}catch(i){e(i)}})}disconnect(){this._ws&&(this._ws.close(),this._ws=null),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._reconnectTimeout&&(clearTimeout(this._reconnectTimeout),this._reconnectTimeout=null),this._connected=!1,this._cleanupGlobalListeners()}_cleanupGlobalListeners(){this._visibilityChangeHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this._visibilityChangeHandler),this._visibilityChangeHandler=null),this._messageHandler&&typeof window<"u"&&(window.removeEventListener("message",this._messageHandler),this._messageHandler=null)}destroy(){this.disconnect()}_scheduleReconnect(){if(this._reconnectTimeout)return;if(this._reconnectAttempts>=this._maxReconnectAttempts){console.warn("WebSocket max reconnect attempts reached, giving up"),this._emit(v.ERROR,{error:"Max reconnect attempts reached"});return}let t=Math.min(this.config.retryDelay*Math.pow(2,this._reconnectAttempts),3e4);this._reconnectAttempts++,this._reconnectTimeout=setTimeout(()=>{this._reconnectTimeout=null,this.connect().catch(()=>{})},t)}_handleMessage(t){if(t.type==="ping"){this._ws&&this._ws.readyState===WebSocket.OPEN&&this._ws.send(JSON.stringify({type:"pong"}));return}let i={connected:v.CONNECTED,status_update:v.STATUS_UPDATE,task_created:v.TASK_CREATED,task_updated:v.TASK_UPDATED,task_deleted:v.TASK_DELETED,task_moved:v.TASK_UPDATED,project_created:v.PROJECT_CREATED,project_updated:v.PROJECT_UPDATED,agent_update:v.AGENT_UPDATE,log:v.LOG_MESSAGE}[t.type]||`api:${t.type}`;this._emit(i,t.data)}_emit(t,e={}){this.dispatchEvent(new CustomEvent(t,{detail:e}))}async _request(t,e={}){let i=`${this.config.baseUrl}${t}`,a=new AbortController,s=e&&typeof e.timeout=="number"?e.timeout:this.config.timeout,r=setTimeout(()=>a.abort(),s);try{let o=await fetch(i,{...e,signal:a.signal,credentials:"include",headers:{"Content-Type":"application/json",...e.headers}});if(clearTimeout(r),!o.ok){let n=await o.text().catch(()=>""),l=o.statusText||`HTTP ${o.status}`;if(n)try{let c=JSON.parse(n);l=c.detail||c.error||c.message||l}catch{l=n.length>200?n.slice(0,200)+"...":n}throw new Error(l)}return o.status===204?null:await o.json()}catch(o){throw clearTimeout(r),o.name==="AbortError"?new Error("Request timeout"):o}}async _get(t,e=!1){if(e&&this._cache.has(t)){let a=this._cache.get(t);if(Date.now()-a.timestamp<this._cacheTimeout)return a.data}let i=await this._request(t);return e&&this._cache.set(t,{data:i,timestamp:Date.now()}),i}async _post(t,e,i={}){return this._request(t,{method:"POST",body:JSON.stringify(e),...i})}async _put(t,e){return this._request(t,{method:"PUT",body:JSON.stringify(e)})}async _delete(t){return this._request(t,{method:"DELETE"})}async get(t){return this._get(t)}async getStatus(){return this._get("/api/status")}async healthCheck(){return this._get("/health")}async listProjects(t=null){let e=t?`?status=${t}`:"";return this._get(`/api/projects${e}`)}async getProject(t){return this._get(`/api/projects/${t}`)}async createProject(t){return this._post("/api/projects",t)}async updateProject(t,e){return this._put(`/api/projects/${t}`,e)}async deleteProject(t){return this._delete(`/api/projects/${t}`)}async listTasks(t={}){let e=new URLSearchParams;t.projectId&&e.append("project_id",t.projectId),t.status&&e.append("status",t.status),t.priority&&e.append("priority",t.priority);let i=e.toString()?`?${e}`:"";return this._get(`/api/tasks${i}`)}async getTask(t){return this._get(`/api/tasks/${t}`)}async createTask(t){return this._post("/api/tasks",t)}async updateTask(t,e){return this._put(`/api/tasks/${t}`,e)}async moveTask(t,e,i){return this._post(`/api/tasks/${t}/move`,{status:e,position:i})}async deleteTask(t){return this._delete(`/api/tasks/${t}`)}async getMemorySummary(){return this._get("/api/memory/summary",!0)}async getMemoryIndex(){return this._get("/api/memory/index",!0)}async getMemoryTimeline(){return this._get("/api/memory/timeline")}async listEpisodes(t={}){let e=new URLSearchParams(t).toString();return this._get(`/api/memory/episodes${e?"?"+e:""}`)}async getEpisode(t){return this._get(`/api/memory/episodes/${t}`)}async listPatterns(t={}){let e=new URLSearchParams(t).toString();return this._get(`/api/memory/patterns${e?"?"+e:""}`)}async getPattern(t){return this._get(`/api/memory/patterns/${t}`)}async listSkills(){return this._get("/api/memory/skills")}async getSkill(t){return this._get(`/api/memory/skills/${t}`)}async retrieveMemories(t,e=null,i=5){return this._post("/api/memory/retrieve",{query:t,taskType:e,topK:i},{timeout:3e4})}async consolidateMemory(t=24){return this._post("/api/memory/consolidate",{sinceHours:t},{timeout:12e4})}async getTokenEconomics(){return this._get("/api/memory/economics")}async searchMemory(t,e="all",i=20){let a=new URLSearchParams({q:t,collection:e,limit:String(i)});return this._get(`/api/memory/search?${a}`)}async getMemoryStats(){return this._get("/api/memory/stats",!0)}async listRegisteredProjects(t=!1){return this._get(`/api/registry/projects?include_inactive=${t}`)}async registerProject(t,e=null,i=null){return this._post("/api/registry/projects",{path:t,name:e,alias:i})}async discoverProjects(t=3){return this._get(`/api/registry/discover?max_depth=${t}`)}async syncRegistry(){return this._post("/api/registry/sync",{},{timeout:45e3})}async getCrossProjectTasks(t=null){let e=t?`?project_ids=${t.join(",")}`:"";return this._get(`/api/registry/tasks${e}`)}async getLearningMetrics(t={}){let e=new URLSearchParams;t.timeRange&&e.append("timeRange",t.timeRange),t.signalType&&e.append("signalType",t.signalType),t.source&&e.append("source",t.source);let i=e.toString()?`?${e}`:"";return this._get(`/api/learning/metrics${i}`)}async getLearningTrends(t={}){let e=new URLSearchParams;t.timeRange&&e.append("timeRange",t.timeRange),t.signalType&&e.append("signalType",t.signalType),t.source&&e.append("source",t.source);let i=e.toString()?`?${e}`:"";return this._get(`/api/learning/trends${i}`)}async getLearningSignals(t={}){let e=new URLSearchParams;t.timeRange&&e.append("timeRange",t.timeRange),t.signalType&&e.append("signalType",t.signalType),t.source&&e.append("source",t.source),t.limit&&e.append("limit",String(t.limit)),t.offset&&e.append("offset",String(t.offset));let i=e.toString()?`?${e}`:"";return this._get(`/api/learning/signals${i}`)}async getLatestAggregation(){return this._get("/api/learning/aggregation")}async triggerAggregation(t={}){return this._post("/api/learning/aggregate",t,{timeout:6e4})}async getAggregatedPreferences(t=20){return this._get(`/api/learning/preferences?limit=${t}`)}async getAggregatedErrors(t=20){return this._get(`/api/learning/errors?limit=${t}`)}async getAggregatedSuccessPatterns(t=20){return this._get(`/api/learning/success?limit=${t}`)}async getToolEfficiency(t=20){return this._get(`/api/learning/tools?limit=${t}`)}async getCost(){return this._get("/api/cost")}async getPricing(){return this._get("/api/pricing")}async getCouncilState(){return this._get("/api/council/state")}async getCouncilVerdicts(t=20){return this._get(`/api/council/verdicts?limit=${t}`)}async getCouncilConvergence(){return this._get("/api/council/convergence")}async getCouncilReport(){return this._get("/api/council/report")}async forceCouncilReview(){return this._post("/api/council/force-review",{})}async getContext(){return this._get("/api/context")}async getNotifications(t,e){let i=new URLSearchParams;t&&i.set("severity",t),e&&i.set("unread_only","true");let a=i.toString();return this._get("/api/notifications"+(a?"?"+a:""))}async getNotificationTriggers(){return this._get("/api/notifications/triggers")}async updateNotificationTriggers(t){return this._put("/api/notifications/triggers",{triggers:t})}async acknowledgeNotification(t){return this._post("/api/notifications/"+encodeURIComponent(t)+"/acknowledge",{})}async pauseSession(){return this._post("/api/control/pause",{})}async resumeSession(){return this._post("/api/control/resume",{})}async stopSession(){return this._post("/api/control/stop",{})}async getLogs(t=100){return this._get(`/api/logs?lines=${t}`)}async getChecklist(){return this._get("/api/checklist")}async getChecklistSummary(){return this._get("/api/checklist/summary")}async getPrdObservations(){let t=await fetch(`${this.baseUrl}/api/prd-observations`,{credentials:"include"});if(!t.ok)throw new Error(`HTTP ${t.status}`);return t.text()}async getChecklistWaivers(){return this._get("/api/checklist/waivers")}async addChecklistWaiver(t,e,i="dashboard"){return this._post("/api/checklist/waivers",{item_id:t,reason:e,waived_by:i})}async removeChecklistWaiver(t){return this._delete(`/api/checklist/waivers/${encodeURIComponent(t)}`)}async getCouncilGate(){return this._get("/api/council/gate")}async getAppRunnerStatus(){return this._get("/api/app-runner/status")}async getAppRunnerLogs(t=100){return this._get(`/api/app-runner/logs?lines=${t}`)}async restartApp(){return this._post("/api/control/app-restart",{})}async stopApp(){return this._post("/api/control/app-stop",{})}async getPlaywrightResults(){return this._get("/api/playwright/results")}async getPlaywrightScreenshot(){return this._get("/api/playwright/screenshot")}startPolling(t,e=null){if(this._pollInterval)return;this._pollCallback=t;let i=async()=>{try{let s=await this.getStatus();this._connected=!0,this._pollCallback&&this._pollCallback(s),this._emit(v.STATUS_UPDATE,s),this._vscodeApi&&this.postToVSCode("pollSuccess",{timestamp:Date.now()})}catch(s){this._connected=!1,this._emit(v.ERROR,{error:s}),this._vscodeApi&&this.postToVSCode("pollError",{error:s.message})}};i();let a=e||this._currentPollInterval||this.config.pollInterval;this._pollInterval=setInterval(i,a)}stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}};C(T,"_instances",new Map);var M=T;function Ut(d={}){return new M(d)}function g(d={}){return M.getInstance(d)}var It="loki-state-change",Tt={ui:{theme:"light",sidebarCollapsed:!1,activeSection:"kanban",terminalAutoScroll:!0},session:{connected:!1,lastSync:null,mode:"offline",phase:null,iteration:null},localTasks:[],cache:{projects:[],tasks:[],agents:[],memory:null,lastFetch:null},preferences:{pollInterval:2e3,notifications:!0,soundEnabled:!1}},S=class S extends EventTarget{static getInstance(){return S._instance||(S._instance=new S),S._instance}constructor(){super(),this._state=this._loadState(),this._subscribers=new Map,this._batchUpdates=[],this._batchTimeout=null}_loadState(){try{let t=localStorage.getItem(S.STORAGE_KEY);if(t){let e=JSON.parse(t);return this._mergeState(Tt,e)}}catch(t){console.warn("Failed to load state from localStorage:",t)}return{...Tt}}_mergeState(t,e){let i={...t};for(let a of Object.keys(e))a in t&&typeof t[a]=="object"&&!Array.isArray(t[a])?i[a]=this._mergeState(t[a],e[a]):i[a]=e[a];return i}_saveState(){try{let t={ui:this._state.ui,localTasks:this._state.localTasks,preferences:this._state.preferences};localStorage.setItem(S.STORAGE_KEY,JSON.stringify(t))}catch(t){console.warn("Failed to save state to localStorage:",t)}}get(t=null){if(!t)return{...this._state};let e=t.split("."),i=this._state;for(let a of e){if(i==null)return;i=i[a]}return i}set(t,e,i=!0){let a=t.split("."),s=a.pop(),r=this._state;for(let n of a)n in r||(r[n]={}),r=r[n];let o=r[s];r[s]=e,i&&this._saveState(),this._notifyChange(t,e,o)}update(t,e=!0){let i=[];for(let[a,s]of Object.entries(t)){let r=this.get(a);this.set(a,s,!1),i.push({path:a,value:s,oldValue:r})}e&&this._saveState();for(let a of i)this._notifyChange(a.path,a.value,a.oldValue)}_notifyChange(t,e,i){this.dispatchEvent(new CustomEvent(It,{detail:{path:t,value:e,oldValue:i}}));let a=this._subscribers.get(t)||[];for(let r of a)try{r(e,i,t)}catch(o){console.error("State subscriber error:",o)}let s=t.split(".");for(;s.length>1;){s.pop();let r=s.join("."),o=this._subscribers.get(r)||[];for(let n of o)try{n(this.get(r),null,r)}catch(l){console.error("State subscriber error:",l)}}}subscribe(t,e){return this._subscribers.has(t)||this._subscribers.set(t,[]),this._subscribers.get(t).push(e),()=>{let i=this._subscribers.get(t),a=i.indexOf(e);a>-1&&i.splice(a,1)}}reset(t=null){if(t){let e=t.split("."),i=Tt;for(let a of e)i=i?.[a];this.set(t,i)}else this._state={...Tt},this._saveState(),this.dispatchEvent(new CustomEvent(It,{detail:{path:null,value:this._state,oldValue:null}}))}addLocalTask(t){let e=this.get("localTasks")||[],i={id:`local-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,createdAt:new Date().toISOString(),status:"pending",...t};return this.set("localTasks",[...e,i]),i}updateLocalTask(t,e){let i=this.get("localTasks")||[],a=i.findIndex(r=>r.id===t);if(a===-1)return null;let s={...i[a],...e,updatedAt:new Date().toISOString()};return i[a]=s,this.set("localTasks",[...i]),s}deleteLocalTask(t){let e=this.get("localTasks")||[];this.set("localTasks",e.filter(i=>i.id!==t))}moveLocalTask(t,e,i=null){let s=(this.get("localTasks")||[]).find(r=>r.id===t);return s?this.updateLocalTask(t,{status:e,position:i??s.position}):null}updateSession(t){this.update(Object.fromEntries(Object.entries(t).map(([e,i])=>[`session.${e}`,i])),!1)}updateCache(t){this.update({"cache.projects":t.projects??this.get("cache.projects"),"cache.tasks":t.tasks??this.get("cache.tasks"),"cache.agents":t.agents??this.get("cache.agents"),"cache.memory":t.memory??this.get("cache.memory"),"cache.lastFetch":new Date().toISOString()},!1)}getMergedTasks(){let t=this.get("cache.tasks")||[],i=(this.get("localTasks")||[]).map(a=>({...a,isLocal:!0}));return[...t,...i]}getTasksByStatus(t){return this.getMergedTasks().filter(e=>e.status===t)}};C(S,"STORAGE_KEY","loki-dashboard-state"),C(S,"_instance",null);var N=S;function B(){return N.getInstance()}function Nt(d){let t=B();return{get:()=>t.get(d),set:e=>t.set(d,e),subscribe:e=>t.subscribe(d,e)}}var O=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data={status:"offline",phase:null,iteration:null,provider:null,running_agents:0,pending_tasks:null,uptime_seconds:0,complexity:null,connected:!1},this._api=null,this._pollInterval=null,this._statusUpdateHandler=null,this._connectedHandler=null,this._disconnectedHandler=null,this._checklistSummary=null,this._appRunnerStatus=null,this._playwrightResults=null,this._gateStatus=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._startPolling(),this._api.connect().catch(()=>{})}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._loadAbortController&&(this._loadAbortController.abort(),this._loadAbortController=null),this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(v.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(v.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(v.DISCONNECTED,this._disconnectedHandler))}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadStatus()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t}),this._statusUpdateHandler=e=>this._updateFromStatus(e.detail),this._connectedHandler=()=>{this._data.connected=!0,this.render()},this._disconnectedHandler=()=>{this._data.connected=!1,this._data.status="offline",this.render()},this._api.addEventListener(v.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(v.CONNECTED,this._connectedHandler),this._api.addEventListener(v.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){this._loadAbortController&&this._loadAbortController.abort(),this._loadAbortController=new AbortController;let{signal:t}=this._loadAbortController;try{let[e,i,a,s,r]=await Promise.allSettled([this._api.getStatus(),this._api.getChecklistSummary(),this._api.getAppRunnerStatus(),this._api.getPlaywrightResults(),this._api.getCouncilGate()]);if(t.aborted)return;e.status==="fulfilled"?this._updateFromStatus(e.value):(this._data.connected=!1,this._data.status="offline"),i.status==="fulfilled"&&(this._checklistSummary=i.value?.summary||null),a.status==="fulfilled"&&(this._appRunnerStatus=a.value),s.status==="fulfilled"&&(this._playwrightResults=s.value),r.status==="fulfilled"&&(this._gateStatus=r.value),this.render()}catch{if(t.aborted)return;this._data.connected=!1,this._data.status="offline",this.render()}}_updateFromStatus(t){t&&(this._data={...this._data,connected:!0,status:t.status||"offline",phase:t.phase||null,iteration:t.iteration!=null?t.iteration:null,provider:t.provider||null,running_agents:t.running_agents||0,pending_tasks:t.pending_tasks!=null?t.pending_tasks:null,uptime_seconds:t.uptime_seconds||0,complexity:t.complexity||null})}_startPolling(){this._pollInterval=setInterval(async()=>{try{await this._loadStatus()}catch{this._data.connected=!1,this._data.status="offline",this.render()}},5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_formatUptime(t){if(!t||t<0)return"--";let e=Math.floor(t/3600),i=Math.floor(t%3600/60),a=Math.floor(t%60);return e>0?`${e}h ${i}m`:i>0?`${i}m ${a}s`:`${a}s`}_getStatusDotClass(){switch(this._data.status){case"running":case"autonomous":return"active";case"paused":return"paused";case"stopped":return"stopped";case"error":return"error";default:return"offline"}}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_renderAppRunnerCard(){let t=this._appRunnerStatus;if(!t||t.status==="not_initialized")return`
|
|
1715
1715
|
<div class="overview-card">
|
|
1716
1716
|
<div class="card-label">App Runner</div>
|
|
1717
1717
|
<div class="card-value small-text">${this._data.status==="running"||this._data.status==="autonomous"?"Waiting...":"Not started"}</div>
|
|
@@ -1962,8 +1962,8 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
1962
1962
|
</div>
|
|
1963
1963
|
</div>
|
|
1964
1964
|
</div>
|
|
1965
|
-
`}};customElements.get("loki-overview")||customElements.define("loki-overview",O);var ce=[{id:"pending",label:"Pending",status:"pending",color:"var(--loki-text-muted)"},{id:"in_progress",label:"In Progress",status:"in_progress",color:"var(--loki-blue)"},{id:"review",label:"In Review",status:"review",color:"var(--loki-purple)"},{id:"done",label:"Completed",status:"done",color:"var(--loki-green)"}],q=class extends h{static get observedAttributes(){return["api-url","project-id","theme","readonly"]}constructor(){super(),this._tasks=[],this._loading=!0,this._error=null,this._draggedTask=null,this._selectedTask=null,this._expandedCards=new Set,this._selectedTasks=new Set,this._bulkMode=!1,this._activeFilter="all",this._api=null,this._state=B()}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadTasks()}disconnectedCallback(){super.disconnectedCallback(),this._api&&(this._api.removeEventListener(
|
|
1966
|
-
<ul class="md-list">${a.trim().split(/\n/).map(r=>r.replace(/^[-*]\s+/,"")).map(r=>`<li>${r}</li>`).join("")}</ul>`),e=e.split(/\n{2,}/).map(i=>/^<(h\d|ul|ol|pre)/.test(i.trim())?i:`<p class="md-p">${i.replace(/\n/g,"<br>")}</p>`).join(""),e}_formatTimestamp(t){if(!t)return"";try{let e=new Date(t);return isNaN(e.getTime())?this._escapeHtml(String(t)):e.toLocaleString()}catch{return this._escapeHtml(String(t))}}_phaseClass(t){let e=String(t||"").toLowerCase();return["reason","plan","planning"].includes(e)?"phase-reason":["act","execute","execution","implement"].includes(e)?"phase-act":["reflect","review"].includes(e)?"phase-reflect":["verify","test","gate"].includes(e)?"phase-verify":"phase-default"}_logLevelClass(t){let e=String(t||"info").toLowerCase();return e==="error"||e==="fatal"?"log-error":e==="warn"||e==="warning"?"log-warn":e==="debug"||e==="trace"?"log-debug":"log-info"}_renderTaskDetailModal(t){if(!t)return"";let e=(t.priority||"medium").toLowerCase(),i=e.charAt(0).toUpperCase()+e.slice(1),a=t.status||"pending",s=a.replace(/_/g," ").replace(/\b\w/g,
|
|
1965
|
+
`}};customElements.get("loki-overview")||customElements.define("loki-overview",O);var ce=[{id:"pending",label:"Pending",status:"pending",color:"var(--loki-text-muted)"},{id:"in_progress",label:"In Progress",status:"in_progress",color:"var(--loki-blue)"},{id:"review",label:"In Review",status:"review",color:"var(--loki-purple)"},{id:"done",label:"Completed",status:"done",color:"var(--loki-green)"}],q=class extends h{static get observedAttributes(){return["api-url","project-id","theme","readonly"]}constructor(){super(),this._tasks=[],this._loading=!0,this._error=null,this._draggedTask=null,this._selectedTask=null,this._expandedCards=new Set,this._selectedTasks=new Set,this._bulkMode=!1,this._activeFilter="all",this._api=null,this._state=B()}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadTasks()}disconnectedCallback(){super.disconnectedCallback(),this._api&&(this._api.removeEventListener(v.TASK_CREATED,this._onTaskEvent),this._api.removeEventListener(v.TASK_UPDATED,this._onTaskEvent),this._api.removeEventListener(v.TASK_DELETED,this._onTaskEvent))}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadTasks()),t==="project-id"&&this._loadTasks(),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t}),this._onTaskEvent&&(this._api.removeEventListener(v.TASK_CREATED,this._onTaskEvent),this._api.removeEventListener(v.TASK_UPDATED,this._onTaskEvent),this._api.removeEventListener(v.TASK_DELETED,this._onTaskEvent)),this._onTaskEvent=()=>this._loadTasks(),this._api.addEventListener(v.TASK_CREATED,this._onTaskEvent),this._api.addEventListener(v.TASK_UPDATED,this._onTaskEvent),this._api.addEventListener(v.TASK_DELETED,this._onTaskEvent)}async _loadTasks(){this._loading=!0,this._error=null,this.render();try{let t=this.getAttribute("project-id"),e=t?{projectId:parseInt(t)}:{};this._tasks=await this._api.listTasks(e);let i=this._state.get("localTasks")||[];i.length>0&&(this._tasks=[...this._tasks,...i.map(a=>({...a,isLocal:!0}))]),this._state.update({"cache.tasks":this._tasks},!1)}catch(t){this._error=t.message,this._tasks=(this._state.get("localTasks")||[]).map(e=>({...e,isLocal:!0}))}this._loading=!1,this.render()}_getTasksByStatus(t){return this._getFilteredTasks().filter(i=>i.status?.toLowerCase().replace(/-/g,"_")===t)}_handleDragStart(t,e){this.hasAttribute("readonly")||(this._draggedTask=e,t.target.classList.add("dragging"),t.dataTransfer.effectAllowed="move",t.dataTransfer.setData("text/plain",e.id.toString()))}_handleDragEnd(t){t.target.classList.remove("dragging"),this._draggedTask=null,this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(e=>{e.classList.remove("drag-over")})}_handleDragOver(t){t.preventDefault(),t.dataTransfer.dropEffect="move"}_handleDragEnter(t){t.preventDefault(),t.currentTarget.classList.add("drag-over")}_handleDragLeave(t){t.currentTarget.contains(t.relatedTarget)||t.currentTarget.classList.remove("drag-over")}async _handleDrop(t,e){if(t.preventDefault(),t.currentTarget.classList.remove("drag-over"),!this._draggedTask||this.hasAttribute("readonly"))return;let i=this._draggedTask.id,a=this._tasks.find(r=>r.id===i);if(!a)return;let s=a.status;if(s!==e){a.status=e,this.render();try{a.isLocal?this._state.moveLocalTask(i,e):await this._api.moveTask(i,e,0),this.dispatchEvent(new CustomEvent("task-moved",{detail:{taskId:i,oldStatus:s,newStatus:e}}))}catch(r){a.status=s,this.render(),console.error("Failed to move task:",r)}}}_toggleCardExpand(t){this._expandedCards.has(t)?this._expandedCards.delete(t):this._expandedCards.add(t),this.render()}_toggleTaskSelection(t,e){e&&e.stopPropagation(),this._selectedTasks.has(t)?this._selectedTasks.delete(t):this._selectedTasks.add(t),this.render()}_toggleBulkMode(){this._bulkMode=!this._bulkMode,this._bulkMode||this._selectedTasks.clear(),this.render()}async _bulkMove(t){let e=[...this._selectedTasks];for(let i of e){let a=this._tasks.find(s=>String(s.id)===String(i));if(a&&a.status!==t)try{a.isLocal?this._state.moveLocalTask(i,t):await this._api.moveTask(i,t,0),a.status=t}catch(s){console.error("Failed to bulk move task:",i,s)}}this._selectedTasks.clear(),this._bulkMode=!1,this.render(),this._loadTasks()}async _bulkDelete(){let t=[...this._selectedTasks];for(let e of t)try{await this._api.deleteTask(e)}catch(i){console.error("Failed to delete task:",e,i)}this._selectedTasks.clear(),this._bulkMode=!1,this._loadTasks()}_setFilter(t){this._activeFilter=t,this.render()}_getFilteredTasks(){let t=[...this._tasks],e=new Date,i=new Date(e.getFullYear(),e.getMonth(),e.getDate()),a=new Date(i.getTime()-7*24*60*60*1e3);switch(this._activeFilter){case"today":t=t.filter(s=>{let r=s.created_at?new Date(s.created_at):null;return r&&r>=i});break;case"this-week":t=t.filter(s=>{let r=s.created_at?new Date(s.created_at):null;return r&&r>=a});break;case"running":t=t.filter(s=>s.status==="in_progress");break;case"failed":t=t.filter(s=>s.status==="failed"||s.status==="error");break;default:break}return t}_openAddTaskModal(t="pending"){this.dispatchEvent(new CustomEvent("add-task",{detail:{status:t}}))}_openTaskDetail(t){this._selectedTask=t,this.render(),this.dispatchEvent(new CustomEvent("task-click",{detail:{task:t}}))}_closeTaskDetail(){this._selectedTask=null,this.render()}_renderMarkdown(t){if(!t)return"";let e=this._escapeHtml(String(t));return e=e.replace(/```([\s\S]*?)```/g,(i,a)=>`<pre class="md-code">${a.trim()}</pre>`),e=e.replace(/`([^`\n]+)`/g,'<code class="md-inline-code">$1</code>'),e=e.replace(/^###\s+(.+)$/gm,'<h4 class="md-h4">$1</h4>'),e=e.replace(/^##\s+(.+)$/gm,'<h3 class="md-h3">$1</h3>'),e=e.replace(/^#\s+(.+)$/gm,'<h2 class="md-h2">$1</h2>'),e=e.replace(/\*\*([^*\n]+)\*\*/g,"<strong>$1</strong>"),e=e.replace(/(^|[^*])\*([^*\n]+)\*/g,"$1<em>$2</em>"),e=e.replace(/(?:^|\n)((?:[-*]\s+.+(?:\n|$))+)/g,(i,a)=>`
|
|
1966
|
+
<ul class="md-list">${a.trim().split(/\n/).map(r=>r.replace(/^[-*]\s+/,"")).map(r=>`<li>${r}</li>`).join("")}</ul>`),e=e.split(/\n{2,}/).map(i=>/^<(h\d|ul|ol|pre)/.test(i.trim())?i:`<p class="md-p">${i.replace(/\n/g,"<br>")}</p>`).join(""),e}_formatTimestamp(t){if(!t)return"";try{let e=new Date(t);return isNaN(e.getTime())?this._escapeHtml(String(t)):e.toLocaleString()}catch{return this._escapeHtml(String(t))}}_phaseClass(t){let e=String(t||"").toLowerCase();return["reason","plan","planning"].includes(e)?"phase-reason":["act","execute","execution","implement"].includes(e)?"phase-act":["reflect","review"].includes(e)?"phase-reflect":["verify","test","gate"].includes(e)?"phase-verify":"phase-default"}_logLevelClass(t){let e=String(t||"info").toLowerCase();return e==="error"||e==="fatal"?"log-error":e==="warn"||e==="warning"?"log-warn":e==="debug"||e==="trace"?"log-debug":"log-info"}_renderTaskDetailModal(t){if(!t)return"";let e=(t.priority||"medium").toLowerCase(),i=e.charAt(0).toUpperCase()+e.slice(1),a=t.status||"pending",s=a.replace(/_/g," ").replace(/\b\w/g,m=>m.toUpperCase()),r=t.metadata||{},o=t.acceptance_criteria||[],n=t.context_files||[],l=t.specification||"",c=t.description||"",p=Array.isArray(t.notes)?t.notes:[],u=Array.isArray(t.logs)?t.logs:[],b=t.full_content||"";return`
|
|
1967
1967
|
<div class="modal-overlay" id="task-detail-overlay">
|
|
1968
1968
|
<div class="modal-container">
|
|
1969
1969
|
<div class="modal-header">
|
|
@@ -1980,9 +1980,9 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
1980
1980
|
<div class="modal-section">
|
|
1981
1981
|
<h3 class="modal-section-title">Metadata</h3>
|
|
1982
1982
|
<div class="meta-grid">
|
|
1983
|
-
${Object.entries(r).map(([
|
|
1983
|
+
${Object.entries(r).map(([m,f])=>`
|
|
1984
1984
|
<div class="meta-cell">
|
|
1985
|
-
<span class="meta-label">${this._escapeHtml(
|
|
1985
|
+
<span class="meta-label">${this._escapeHtml(m.replace(/_/g," "))}</span>
|
|
1986
1986
|
<span class="meta-value">${this._escapeHtml(String(f))}</span>
|
|
1987
1987
|
</div>
|
|
1988
1988
|
`).join("")}
|
|
@@ -2008,7 +2008,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
2008
2008
|
<div class="modal-section">
|
|
2009
2009
|
<h3 class="modal-section-title">Acceptance Criteria</h3>
|
|
2010
2010
|
<ul class="criteria-checklist" role="list">
|
|
2011
|
-
${o.map(
|
|
2011
|
+
${o.map(m=>{let f=m&&typeof m=="object",x=f?m.text||m.title||"":m,w=f?!!m.done:!1;return`<li class="criteria-item">
|
|
2012
2012
|
<span class="criteria-checkbox ${w?"checked":""}" aria-hidden="true">${w?"✓":""}</span>
|
|
2013
2013
|
<span class="criteria-text ${w?"done":""}">${this._escapeHtml(String(x))}</span>
|
|
2014
2014
|
</li>`}).join("")}
|
|
@@ -2020,7 +2020,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
2020
2020
|
<div class="modal-section">
|
|
2021
2021
|
<h3 class="modal-section-title">Notes</h3>
|
|
2022
2022
|
<ul class="notes-timeline" role="list">
|
|
2023
|
-
${p.map(
|
|
2023
|
+
${p.map(m=>{let f=this._formatTimestamp(m&&m.timestamp),x=m&&m.author?this._escapeHtml(String(m.author)):"unknown",w=m&&m.body?this._escapeHtml(String(m.body)):"";return`<li class="note-entry">
|
|
2024
2024
|
<div class="note-meta">
|
|
2025
2025
|
<span class="note-author">${x}</span>
|
|
2026
2026
|
${f?`<span class="note-time">${f}</span>`:""}
|
|
@@ -2036,7 +2036,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
2036
2036
|
<h3 class="modal-section-title">Logs</h3>
|
|
2037
2037
|
<div class="logs-scroll">
|
|
2038
2038
|
<ul class="logs-timeline" role="list">
|
|
2039
|
-
${u.map(
|
|
2039
|
+
${u.map(m=>{let f=this._formatTimestamp(m&&m.timestamp),x=m&&m.iteration!==void 0&&m.iteration!==null?`i${this._escapeHtml(String(m.iteration))}`:"",w=m&&m.phase?String(m.phase):"",te=this._phaseClass(w),ee=this._logLevelClass(m&&m.level),ie=m&&m.message?this._escapeHtml(String(m.message)):"";return`<li class="log-entry ${ee}">
|
|
2040
2040
|
${f?`<span class="log-time">${f}</span>`:""}
|
|
2041
2041
|
${x?`<span class="log-iter">${x}</span>`:""}
|
|
2042
2042
|
${w?`<span class="log-phase ${te}">${this._escapeHtml(w)}</span>`:""}
|
|
@@ -2051,7 +2051,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
2051
2051
|
<div class="modal-section">
|
|
2052
2052
|
<h3 class="modal-section-title">Context Files</h3>
|
|
2053
2053
|
<ul class="context-files-list">
|
|
2054
|
-
${n.map(
|
|
2054
|
+
${n.map(m=>`<li class="mono">${this._escapeHtml(m)}</li>`).join("")}
|
|
2055
2055
|
</ul>
|
|
2056
2056
|
</div>
|
|
2057
2057
|
`:""}
|
|
@@ -3024,7 +3024,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
3024
3024
|
${i}
|
|
3025
3025
|
</div>
|
|
3026
3026
|
${this._selectedTask?this._renderTaskDetailModal(this._selectedTask):""}
|
|
3027
|
-
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("refresh-btn");t&&t.addEventListener("click",()=>this._loadTasks());let e=this.shadowRoot.getElementById("bulk-toggle-btn");e&&e.addEventListener("click",()=>this._toggleBulkMode()),this.shadowRoot.querySelectorAll(".filter-pill").forEach(s=>{s.addEventListener("click",()=>this._setFilter(s.dataset.filter))}),this.shadowRoot.querySelectorAll(".bulk-btn").forEach(s=>{s.addEventListener("click",()=>{let r=s.dataset.bulkAction;r==="delete"?this._bulkDelete():this._bulkMove(r)})}),this.shadowRoot.querySelectorAll(".add-task-btn").forEach(s=>{s.addEventListener("click",()=>{this._openAddTaskModal(s.dataset.status)})}),this.shadowRoot.querySelectorAll(".task-checkbox").forEach(s=>{s.addEventListener("click",r=>{r.stopPropagation(),this._toggleTaskSelection(s.dataset.checkId,r)})}),this.shadowRoot.querySelectorAll(".expand-toggle").forEach(s=>{s.addEventListener("click",r=>{r.stopPropagation(),this._toggleCardExpand(s.dataset.expandId)})}),this.shadowRoot.querySelectorAll(".task-card").forEach(s=>{let r=s.dataset.taskId,o=this._tasks.find(n=>n.id.toString()===r);o&&(s.addEventListener("click",n=>{if(this._bulkMode){this._toggleTaskSelection(r,n);return}this._openTaskDetail(o)}),s.addEventListener("keydown",n=>{n.key==="Enter"||n.key===" "?(n.preventDefault(),this._bulkMode?this._toggleTaskSelection(r,n):this._openTaskDetail(o)):(n.key==="ArrowDown"||n.key==="ArrowUp")&&(n.preventDefault(),this._navigateTaskCards(s,n.key==="ArrowDown"?"next":"prev"))}),s.classList.contains("draggable")&&(s.addEventListener("dragstart",n=>this._handleDragStart(n,o)),s.addEventListener("dragend",n=>this._handleDragEnd(n))))}),this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(s=>{s.addEventListener("dragover",r=>this._handleDragOver(r)),s.addEventListener("dragenter",r=>this._handleDragEnter(r)),s.addEventListener("dragleave",r=>this._handleDragLeave(r)),s.addEventListener("drop",r=>this._handleDrop(r,s.dataset.status))});let i=this.shadowRoot.getElementById("modal-close-btn");i&&i.addEventListener("click",()=>this._closeTaskDetail());let a=this.shadowRoot.getElementById("task-detail-overlay");a&&a.addEventListener("click",s=>{s.target===a&&this._closeTaskDetail()})}_escapeHtml(t){let e=document.createElement("div");return e.textContent=t,e.innerHTML}_navigateTaskCards(t,e){let i=Array.from(this.shadowRoot.querySelectorAll(".task-card")),a=i.indexOf(t);if(a===-1)return;let s=e==="next"?a+1:a-1;s>=0&&s<i.length&&i[s].focus()}};customElements.get("loki-task-board")||customElements.define("loki-task-board",q);var J=class extends h{static get observedAttributes(){return["api-url","theme","compact"]}constructor(){super(),this._status={mode:"offline",phase:null,iteration:null,complexity:null,connected:!1,version:null,uptime:0,activeAgents:0,pendingTasks:0},this._api=null,this._state=B(),this._statusUpdateHandler=null,this._connectedHandler=null,this._disconnectedHandler=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(
|
|
3027
|
+
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("refresh-btn");t&&t.addEventListener("click",()=>this._loadTasks());let e=this.shadowRoot.getElementById("bulk-toggle-btn");e&&e.addEventListener("click",()=>this._toggleBulkMode()),this.shadowRoot.querySelectorAll(".filter-pill").forEach(s=>{s.addEventListener("click",()=>this._setFilter(s.dataset.filter))}),this.shadowRoot.querySelectorAll(".bulk-btn").forEach(s=>{s.addEventListener("click",()=>{let r=s.dataset.bulkAction;r==="delete"?this._bulkDelete():this._bulkMove(r)})}),this.shadowRoot.querySelectorAll(".add-task-btn").forEach(s=>{s.addEventListener("click",()=>{this._openAddTaskModal(s.dataset.status)})}),this.shadowRoot.querySelectorAll(".task-checkbox").forEach(s=>{s.addEventListener("click",r=>{r.stopPropagation(),this._toggleTaskSelection(s.dataset.checkId,r)})}),this.shadowRoot.querySelectorAll(".expand-toggle").forEach(s=>{s.addEventListener("click",r=>{r.stopPropagation(),this._toggleCardExpand(s.dataset.expandId)})}),this.shadowRoot.querySelectorAll(".task-card").forEach(s=>{let r=s.dataset.taskId,o=this._tasks.find(n=>n.id.toString()===r);o&&(s.addEventListener("click",n=>{if(this._bulkMode){this._toggleTaskSelection(r,n);return}this._openTaskDetail(o)}),s.addEventListener("keydown",n=>{n.key==="Enter"||n.key===" "?(n.preventDefault(),this._bulkMode?this._toggleTaskSelection(r,n):this._openTaskDetail(o)):(n.key==="ArrowDown"||n.key==="ArrowUp")&&(n.preventDefault(),this._navigateTaskCards(s,n.key==="ArrowDown"?"next":"prev"))}),s.classList.contains("draggable")&&(s.addEventListener("dragstart",n=>this._handleDragStart(n,o)),s.addEventListener("dragend",n=>this._handleDragEnd(n))))}),this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(s=>{s.addEventListener("dragover",r=>this._handleDragOver(r)),s.addEventListener("dragenter",r=>this._handleDragEnter(r)),s.addEventListener("dragleave",r=>this._handleDragLeave(r)),s.addEventListener("drop",r=>this._handleDrop(r,s.dataset.status))});let i=this.shadowRoot.getElementById("modal-close-btn");i&&i.addEventListener("click",()=>this._closeTaskDetail());let a=this.shadowRoot.getElementById("task-detail-overlay");a&&a.addEventListener("click",s=>{s.target===a&&this._closeTaskDetail()})}_escapeHtml(t){let e=document.createElement("div");return e.textContent=t,e.innerHTML}_navigateTaskCards(t,e){let i=Array.from(this.shadowRoot.querySelectorAll(".task-card")),a=i.indexOf(t);if(a===-1)return;let s=e==="next"?a+1:a-1;s>=0&&s<i.length&&i[s].focus()}};customElements.get("loki-task-board")||customElements.define("loki-task-board",q);var J=class extends h{static get observedAttributes(){return["api-url","theme","compact"]}constructor(){super(),this._status={mode:"offline",phase:null,iteration:null,complexity:null,connected:!1,version:null,uptime:0,activeAgents:0,pendingTasks:0},this._api=null,this._state=B(),this._statusUpdateHandler=null,this._connectedHandler=null,this._disconnectedHandler=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(v.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(v.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(v.DISCONNECTED,this._disconnectedHandler))}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadStatus()),t==="theme"&&this._applyTheme(),t==="compact"&&this.render())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t}),this._statusUpdateHandler=e=>this._updateFromStatus(e.detail),this._connectedHandler=()=>{this._status.connected=!0,this.render()},this._disconnectedHandler=()=>{this._status.connected=!1,this._status.mode="offline",this.render()},this._api.addEventListener(v.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(v.CONNECTED,this._connectedHandler),this._api.addEventListener(v.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){try{let t=await this._api.getStatus();this._updateFromStatus(t)}catch{this._status.connected=!1,this._status.mode="offline",this.render()}}_updateFromStatus(t){t&&(this._status={...this._status,connected:!0,mode:t.status||"running",version:t.version,uptime:t.uptime_seconds||0,activeAgents:t.running_agents||0,pendingTasks:t.pending_tasks||0,phase:t.phase,iteration:t.iteration,complexity:t.complexity},this._state.updateSession({connected:!0,mode:this._status.mode,lastSync:new Date().toISOString()}),this.render())}_startPolling(){this._ownPollInterval=setInterval(async()=>{try{let t=await this._api.getStatus();this._updateFromStatus(t)}catch{this._status.connected=!1,this._status.mode="offline",this.render()}},3e3)}_stopPolling(){this._ownPollInterval&&(clearInterval(this._ownPollInterval),this._ownPollInterval=null)}_formatUptime(t){if(!t||t<0)return"--";let e=Math.floor(t/3600),i=Math.floor(t%3600/60),a=Math.floor(t%60);return e>0?`${e}h ${i}m`:i>0?`${i}m ${a}s`:`${a}s`}_escapeHtml(t){let e=document.createElement("div");return e.textContent=String(t??""),e.innerHTML}_getStatusClass(){switch(this._status.mode){case"running":case"autonomous":return"active";case"paused":return"paused";case"stopped":return"stopped";case"error":return"error";default:return"offline"}}_getStatusLabel(){switch(this._status.mode){case"running":case"autonomous":return"AUTONOMOUS";case"paused":return"PAUSED";case"stopped":return"STOPPED";case"error":return"ERROR";default:return"OFFLINE"}}_triggerStart(){this.dispatchEvent(new CustomEvent("session-start",{detail:this._status}))}async _triggerPause(){try{let t=await this._api.pauseSession();if(t&&t.error)throw new Error(t.error);this._status.mode="paused",this.render(),this.dispatchEvent(new CustomEvent("session-pause",{detail:this._status}))}catch(t){console.error("Failed to pause session:",t),this.render()}}async _triggerResume(){try{let t=await this._api.resumeSession();if(t&&t.error)throw new Error(t.error);this._status.mode="running",this.render(),this.dispatchEvent(new CustomEvent("session-resume",{detail:this._status}))}catch(t){console.error("Failed to resume session:",t),this.render()}}async _triggerStop(){try{let t=await this._api.stopSession();if(t&&t.error)throw new Error(t.error);this._status.mode="stopped",this.render(),this.dispatchEvent(new CustomEvent("session-stop",{detail:this._status}))}catch(t){console.error("Failed to stop session:",t),this.render()}}render(){let t=this.hasAttribute("compact"),e=this._getStatusClass(),i=this._getStatusLabel(),a=["running","autonomous"].includes(this._status.mode),s=this._status.mode==="paused",r=`
|
|
3028
3028
|
<style>
|
|
3029
3029
|
${this.getBaseStyles()}
|
|
3030
3030
|
|
|
@@ -3303,7 +3303,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
3303
3303
|
`;this.shadowRoot.innerHTML=`
|
|
3304
3304
|
${r}
|
|
3305
3305
|
${t?o:n}
|
|
3306
|
-
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("pause-btn"),e=this.shadowRoot.getElementById("resume-btn"),i=this.shadowRoot.getElementById("stop-btn"),a=this.shadowRoot.getElementById("start-btn");t&&t.addEventListener("click",()=>this._triggerPause()),e&&e.addEventListener("click",()=>this._triggerResume()),i&&i.addEventListener("click",()=>this._triggerStop()),a&&a.addEventListener("click",()=>this._triggerStart())}};customElements.get("loki-session-control")||customElements.define("loki-session-control",J);var Ot={info:{color:"var(--loki-blue)",label:"INFO"},success:{color:"var(--loki-green)",label:"SUCCESS"},warning:{color:"var(--loki-yellow)",label:"WARN"},error:{color:"var(--loki-red)",label:"ERROR"},step:{color:"var(--loki-purple)",label:"STEP"},agent:{color:"var(--loki-accent)",label:"AGENT"},debug:{color:"var(--loki-text-muted)",label:"DEBUG"}},G=class extends h{static get observedAttributes(){return["api-url","max-lines","auto-scroll","theme","log-file"]}constructor(){super(),this._logs=[],this._maxLines=500,this._autoScroll=!0,this._filter="",this._levelFilter="all",this._api=null,this._pollInterval=null,this._logMessageHandler=null}connectedCallback(){super.connectedCallback(),this._maxLines=parseInt(this.getAttribute("max-lines"))||500,this._autoScroll=this.hasAttribute("auto-scroll"),this._setupApi(),this._startLogPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopLogPolling(),this._api&&this._logMessageHandler&&this._api.removeEventListener(
|
|
3306
|
+
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("pause-btn"),e=this.shadowRoot.getElementById("resume-btn"),i=this.shadowRoot.getElementById("stop-btn"),a=this.shadowRoot.getElementById("start-btn");t&&t.addEventListener("click",()=>this._triggerPause()),e&&e.addEventListener("click",()=>this._triggerResume()),i&&i.addEventListener("click",()=>this._triggerStop()),a&&a.addEventListener("click",()=>this._triggerStart())}};customElements.get("loki-session-control")||customElements.define("loki-session-control",J);var Ot={info:{color:"var(--loki-blue)",label:"INFO"},success:{color:"var(--loki-green)",label:"SUCCESS"},warning:{color:"var(--loki-yellow)",label:"WARN"},error:{color:"var(--loki-red)",label:"ERROR"},step:{color:"var(--loki-purple)",label:"STEP"},agent:{color:"var(--loki-accent)",label:"AGENT"},debug:{color:"var(--loki-text-muted)",label:"DEBUG"}},G=class extends h{static get observedAttributes(){return["api-url","max-lines","auto-scroll","theme","log-file"]}constructor(){super(),this._logs=[],this._maxLines=500,this._autoScroll=!0,this._filter="",this._levelFilter="all",this._api=null,this._pollInterval=null,this._logMessageHandler=null}connectedCallback(){super.connectedCallback(),this._maxLines=parseInt(this.getAttribute("max-lines"))||500,this._autoScroll=this.hasAttribute("auto-scroll"),this._setupApi(),this._startLogPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopLogPolling(),this._api&&this._logMessageHandler&&this._api.removeEventListener(v.LOG_MESSAGE,this._logMessageHandler)}attributeChangedCallback(t,e,i){if(e!==i)switch(t){case"api-url":this._api&&(this._api.baseUrl=i);break;case"max-lines":this._maxLines=parseInt(i)||500,this._trimLogs(),this.render();break;case"auto-scroll":this._autoScroll=this.hasAttribute("auto-scroll"),this.render();break;case"theme":this._applyTheme();break}}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t}),this._logMessageHandler=e=>this._addLog(e.detail),this._api.addEventListener(v.LOG_MESSAGE,this._logMessageHandler)}_startLogPolling(){let t=this.getAttribute("log-file");t?this._pollLogFile(t):this._pollApiLogs()}async _pollApiLogs(){let t=0,e=async()=>{try{let i=await this._api.getLogs(200);if(Array.isArray(i)&&i.length>t){let a=i.slice(t);for(let s of a)s.message&&s.message.trim()&&this._addLog({message:s.message,level:s.level||"info",timestamp:s.timestamp||new Date().toLocaleTimeString()});t=i.length}}catch{}};e(),this._apiPollInterval=setInterval(e,2e3)}async _pollLogFile(t){let e=0,i=async()=>{try{let a=await fetch(`${t}?t=${Date.now()}`,{credentials:"include"});if(!a.ok)return;let r=(await a.text()).split(`
|
|
3307
3307
|
`);if(r.length>e){let o=r.slice(e);for(let n of o)n.trim()&&this._addLog(this._parseLine(n));e=r.length}}catch{}};i(),this._pollInterval=setInterval(i,1e3)}_stopLogPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._apiPollInterval&&(clearInterval(this._apiPollInterval),this._apiPollInterval=null)}_parseLine(t){let e=t.match(/^\[([^\]]+)\]\s*\[([^\]]+)\]\s*(.+)$/);if(e)return{timestamp:e[1],level:e[2].toLowerCase(),message:e[3]};let i=t.match(/^(\d{2}:\d{2}:\d{2})\s+(\w+)\s+(.+)$/);return i?{timestamp:i[1],level:i[2].toLowerCase(),message:i[3]}:{timestamp:new Date().toLocaleTimeString(),level:"info",message:t}}_addLog(t){if(!t)return;let e={id:Date.now()+Math.random(),timestamp:t.timestamp||new Date().toLocaleTimeString(),level:(t.level||"info").toLowerCase(),message:t.message||t};this._logs.push(e),this._trimLogs(),this.dispatchEvent(new CustomEvent("log-received",{detail:e})),this._renderLogs(),this._autoScroll&&this._scrollToBottom()}_trimLogs(){this._logs.length>this._maxLines&&(this._logs=this._logs.slice(-this._maxLines))}_clearLogs(){this._logs=[],this.dispatchEvent(new CustomEvent("logs-cleared")),this._renderLogs()}_toggleAutoScroll(){this._autoScroll=!this._autoScroll,this.render(),this._autoScroll&&this._scrollToBottom()}_scrollToBottom(){requestAnimationFrame(()=>{let t=this.shadowRoot.getElementById("log-output");t&&(t.scrollTop=t.scrollHeight)})}_downloadLogs(){let t=this._logs.map(s=>`[${s.timestamp}] [${s.level.toUpperCase()}] ${s.message}`).join(`
|
|
3308
3308
|
`),e=new Blob([t],{type:"text/plain"}),i=URL.createObjectURL(e),a=document.createElement("a");a.href=i,a.download=`loki-logs-${new Date().toISOString().split("T")[0]}.txt`,a.click(),URL.revokeObjectURL(i)}_setFilter(t){this._filter=t.toLowerCase(),this._renderLogs()}_setLevelFilter(t){this._levelFilter=t,this._renderLogs()}_getFilteredLogs(){return this._logs.filter(t=>!(this._levelFilter!=="all"&&t.level!==this._levelFilter||this._filter&&!t.message.toLowerCase().includes(this._filter)))}_renderLogs(){let t=this.shadowRoot.getElementById("log-output");if(!t)return;let e=this._getFilteredLogs();if(e.length===0){t.innerHTML='<div class="log-empty">No log output yet. Terminal will update when Loki Mode is running.</div>';return}t.innerHTML=e.map(i=>{let a=Ot[i.level]||Ot.info;return`
|
|
3309
3309
|
<div class="log-line">
|
|
@@ -5404,7 +5404,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
5404
5404
|
${e}
|
|
5405
5405
|
</div>
|
|
5406
5406
|
</div>
|
|
5407
|
-
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("time-range-select");t&&t.addEventListener("change",r=>this._setFilter("timeRange",r.target.value));let e=this.shadowRoot.getElementById("signal-type-select");e&&e.addEventListener("change",r=>this._setFilter("signalType",r.target.value));let i=this.shadowRoot.getElementById("source-select");i&&i.addEventListener("change",r=>this._setFilter("source",r.target.value));let a=this.shadowRoot.getElementById("refresh-btn");a&&a.addEventListener("click",()=>this._loadData());let s=this.shadowRoot.getElementById("close-detail");s&&s.addEventListener("click",()=>this._closeDetail()),this.shadowRoot.querySelectorAll(".list-item").forEach(r=>{r.addEventListener("click",()=>{let o=r.dataset.type,n=r.dataset.id,l=this._findItemData(o,n);l&&this._selectMetric(o,l)}),r.addEventListener("keydown",o=>{(o.key==="Enter"||o.key===" ")&&(o.preventDefault(),r.click())})})}_findItemData(t,e){if(!this._metrics?.aggregation)return null;switch(t){case"preference":return this._metrics.aggregation.preferences?.find(i=>i.preference_key===e);case"error_pattern":return this._metrics.aggregation.error_patterns?.find(i=>i.error_type===e);case"success_pattern":return this._metrics.aggregation.success_patterns?.find(i=>i.pattern_name===e);case"tool_efficiency":return this._metrics.aggregation.tool_efficiencies?.find(i=>i.tool_name===e);default:return null}}};customElements.get("loki-learning-dashboard")||customElements.define("loki-learning-dashboard",V);var
|
|
5407
|
+
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("time-range-select");t&&t.addEventListener("change",r=>this._setFilter("timeRange",r.target.value));let e=this.shadowRoot.getElementById("signal-type-select");e&&e.addEventListener("change",r=>this._setFilter("signalType",r.target.value));let i=this.shadowRoot.getElementById("source-select");i&&i.addEventListener("change",r=>this._setFilter("source",r.target.value));let a=this.shadowRoot.getElementById("refresh-btn");a&&a.addEventListener("click",()=>this._loadData());let s=this.shadowRoot.getElementById("close-detail");s&&s.addEventListener("click",()=>this._closeDetail()),this.shadowRoot.querySelectorAll(".list-item").forEach(r=>{r.addEventListener("click",()=>{let o=r.dataset.type,n=r.dataset.id,l=this._findItemData(o,n);l&&this._selectMetric(o,l)}),r.addEventListener("keydown",o=>{(o.key==="Enter"||o.key===" ")&&(o.preventDefault(),r.click())})})}_findItemData(t,e){if(!this._metrics?.aggregation)return null;switch(t){case"preference":return this._metrics.aggregation.preferences?.find(i=>i.preference_key===e);case"error_pattern":return this._metrics.aggregation.error_patterns?.find(i=>i.error_type===e);case"success_pattern":return this._metrics.aggregation.success_patterns?.find(i=>i.pattern_name===e);case"tool_efficiency":return this._metrics.aggregation.tool_efficiencies?.find(i=>i.tool_name===e);default:return null}}};customElements.get("loki-learning-dashboard")||customElements.define("loki-learning-dashboard",V);var me=[{id:"overview",label:"Overview"},{id:"decisions",label:"Decision Log"},{id:"convergence",label:"Convergence"},{id:"agents",label:"Agents"}],Y=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._activeTab="overview",this._pollInterval=null,this._councilState=null,this._verdicts=[],this._convergence=[],this._agents=[],this._selectedAgent=null,this._lastDataHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),3e3),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadData(),this._pollInterval=setInterval(()=>this._loadData(),3e3))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null),this._pendingRaf&&(cancelAnimationFrame(this._pendingRaf),this._pendingRaf=null)}async _loadData(){try{let[e,i,a,s]=await Promise.allSettled([this._api._get("/api/council/state"),this._api._get("/api/council/verdicts"),this._api._get("/api/council/convergence"),this._api._get("/api/agents")]);e.status==="fulfilled"&&(this._councilState=e.value),i.status==="fulfilled"&&(this._verdicts=i.value.verdicts||[]),a.status==="fulfilled"&&(this._convergence=a.value.dataPoints||[]),s.status==="fulfilled"&&(this._agents=Array.isArray(s.value)?s.value:[]),this._error=null}catch(e){this._error=e.message}let t=JSON.stringify({s:this._councilState,v:this._verdicts,c:this._convergence,a:this._agents,e:this._error});t!==this._lastDataHash&&(this._lastDataHash=t,this.render())}async _forceReview(){try{await this._api._post("/api/council/force-review"),this.dispatchEvent(new CustomEvent("council-action",{detail:{action:"force-review"},bubbles:!0}))}catch(t){this._error=`Failed to force review: ${t.message}`,this.render()}}async _killAgent(t){if(confirm(`Kill agent ${t}?`))try{await this._api._post(`/api/agents/${t}/kill`),this.dispatchEvent(new CustomEvent("council-action",{detail:{action:"kill-agent",agentId:t},bubbles:!0})),await this._loadData()}catch(e){this._error=`Failed to kill agent: ${e.message}`,this.render()}}async _pauseAgent(t){try{await this._api._post(`/api/agents/${t}/pause`),await this._loadData()}catch(e){this._error=`Failed to pause agent: ${e.message}`,this.render()}}async _resumeAgent(t){try{await this._api._post(`/api/agents/${t}/resume`),await this._loadData()}catch(e){this._error=`Failed to resume agent: ${e.message}`,this.render()}}_setTab(t){this._activeTab=t,this.render()}_selectAgent(t){this._selectedAgent=this._selectedAgent?.id===t.id?null:t,this.render()}render(){let t=this.shadowRoot;t&&(this._pendingRaf&&(cancelAnimationFrame(this._pendingRaf),this._pendingRaf=null),t.innerHTML=`
|
|
5408
5408
|
<style>${this.getBaseStyles()}${this._getStyles()}</style>
|
|
5409
5409
|
<div class="council-dashboard">
|
|
5410
5410
|
<div class="council-header">
|
|
@@ -5418,7 +5418,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
5418
5418
|
</div>
|
|
5419
5419
|
|
|
5420
5420
|
<div class="tabs">
|
|
5421
|
-
${
|
|
5421
|
+
${me.map(e=>`
|
|
5422
5422
|
<button
|
|
5423
5423
|
class="tab ${this._activeTab===e.id?"active":""}"
|
|
5424
5424
|
data-tab="${e.id}"
|
|
@@ -5991,7 +5991,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
5991
5991
|
color: var(--loki-error);
|
|
5992
5992
|
font-size: 12px;
|
|
5993
5993
|
}
|
|
5994
|
-
`}};customElements.get("loki-council-dashboard")||customElements.define("loki-council-dashboard",Y);var qt={critical:0,major:1,minor:2},
|
|
5994
|
+
`}};customElements.get("loki-council-dashboard")||customElements.define("loki-council-dashboard",Y);var qt={critical:0,major:1,minor:2},ve={critical:"var(--loki-status-error, #ef4444)",major:"var(--loki-status-warning, #f59e0b)",minor:"var(--loki-text-muted, #71717a)"},W=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._pollInterval=null,this._checklist=null,this._waivers=[],this._expandedCategories=new Set,this._lastDataHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),5e3),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadData(),this._pollInterval=setInterval(()=>this._loadData(),5e3))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null)}async _loadData(){try{let[t,e]=await Promise.all([this._api.getChecklist(),this._api.getChecklistWaivers().catch(()=>null)]),i=JSON.stringify(e),a=JSON.stringify(t)+i;if(a===this._lastDataHash)return;this._lastDataHash=a,this._checklist=t,this._waivers=e&&e.waivers?e.waivers.filter(s=>s.active):[],this._error=null,this.render()}catch(t){this._error=`Failed to load checklist: ${t.message}`,this.render()}}_isItemWaived(t){return this._waivers.some(e=>e.item_id===t)}_getWaiverForItem(t){return this._waivers.find(e=>e.item_id===t)||null}async _waiveItem(t){let e=window.prompt("Enter reason for waiving this item:");if(e)try{await this._api.addChecklistWaiver(t,e),this._lastDataHash=null,await this._loadData()}catch(i){this._error=`Failed to add waiver: ${i.message}`,this.render()}}async _unwaiveItem(t){try{await this._api.removeChecklistWaiver(t),this._lastDataHash=null,await this._loadData()}catch(e){this._error=`Failed to remove waiver: ${e.message}`,this.render()}}_toggleCategory(t){this._expandedCategories.has(t)?this._expandedCategories.delete(t):this._expandedCategories.add(t),this.render()}_getStyles(){return`
|
|
5995
5995
|
.checklist-viewer {
|
|
5996
5996
|
padding: 16px;
|
|
5997
5997
|
font-family: var(--loki-font-family, system-ui, -apple-system, sans-serif);
|
|
@@ -6280,7 +6280,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
6280
6280
|
</div>
|
|
6281
6281
|
${i?`<div class="category-body">${this._renderItems(a)}</div>`:""}
|
|
6282
6282
|
</div>
|
|
6283
|
-
`}).join(""):this._renderEmpty()}_renderItems(t){return t?.length?[...t].sort((i,a)=>(qt[i.priority]??2)-(qt[a.priority]??2)).map(i=>{let a=i.status==="verified"?"status-verified":i.status==="failing"?"status-failing":"status-pending",s=["critical","major","minor"].includes(i.priority)?i.priority:"minor",r=
|
|
6283
|
+
`}).join(""):this._renderEmpty()}_renderItems(t){return t?.length?[...t].sort((i,a)=>(qt[i.priority]??2)-(qt[a.priority]??2)).map(i=>{let a=i.status==="verified"?"status-verified":i.status==="failing"?"status-failing":"status-pending",s=["critical","major","minor"].includes(i.priority)?i.priority:"minor",r=ve[s],o=i.verification||[],n=this._getWaiverForItem(i.id),l=!!n,c=i.status==="failing"&&(s==="critical"||s==="major"),p=l?`<span class="item-waived-badge" title="${this._escapeHtml(n.reason||"No reason provided")}">WAIVED</span>`:"",u="";return c&&(l?u=`<button class="waiver-btn waiver-btn-unwaive" data-unwaive-id="${this._escapeHtml(i.id)}">Unwaive</button>`:u=`<button class="waiver-btn" data-waive-id="${this._escapeHtml(i.id)}">Waive</button>`),`
|
|
6284
6284
|
<div class="item">
|
|
6285
6285
|
<div class="item-status ${a}"></div>
|
|
6286
6286
|
<div class="item-title">${this._escapeHtml(i.title||i.id||"?")}</div>
|
|
@@ -7356,14 +7356,14 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
7356
7356
|
<div class="legend-item"><span class="legend-swatch swatch-cache-read"></span> Cache Read</div>
|
|
7357
7357
|
<div class="legend-item"><span class="legend-swatch swatch-cache-create"></span> Cache Creation</div>
|
|
7358
7358
|
</div>
|
|
7359
|
-
`,a="";for(let s of t){let r=s.input_tokens||0,o=s.output_tokens||0,n=s.cache_read_tokens||0,l=s.cache_creation_tokens||0,c=r+o+n+l,p=e>0?r/e*100:0,u=e>0?o/e*100:0,b=e>0?n/e*100:0,
|
|
7359
|
+
`,a="";for(let s of t){let r=s.input_tokens||0,o=s.output_tokens||0,n=s.cache_read_tokens||0,l=s.cache_creation_tokens||0,c=r+o+n+l,p=e>0?r/e*100:0,u=e>0?o/e*100:0,b=e>0?n/e*100:0,m=e>0?l/e*100:0;a+=`
|
|
7360
7360
|
<div class="breakdown-row">
|
|
7361
7361
|
<div class="breakdown-iter">#${s.iteration}</div>
|
|
7362
7362
|
<div class="breakdown-bar-container">
|
|
7363
7363
|
<div class="breakdown-bar bar-input" style="width: ${p.toFixed(1)}%"></div>
|
|
7364
7364
|
<div class="breakdown-bar bar-output" style="width: ${u.toFixed(1)}%"></div>
|
|
7365
7365
|
<div class="breakdown-bar bar-cache-read" style="width: ${b.toFixed(1)}%"></div>
|
|
7366
|
-
<div class="breakdown-bar bar-cache-create" style="width: ${
|
|
7366
|
+
<div class="breakdown-bar bar-cache-create" style="width: ${m.toFixed(1)}%"></div>
|
|
7367
7367
|
</div>
|
|
7368
7368
|
<div class="breakdown-cost">${this._formatUSD(s.cost_usd)}</div>
|
|
7369
7369
|
</div>
|
|
@@ -7766,7 +7766,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
7766
7766
|
|
|
7767
7767
|
${t}
|
|
7768
7768
|
</div>
|
|
7769
|
-
`,this.shadowRoot.querySelectorAll(".tab").forEach(e=>{e.addEventListener("click",()=>{this._setTab(e.dataset.tab)})})}};customElements.get("loki-context-tracker")||customElements.define("loki-context-tracker",tt);var Dt={critical:"var(--loki-red, #ef4444)",warning:"var(--loki-yellow, #eab308)",info:"var(--loki-blue, #3b82f6)",success:"var(--loki-green, #1FC5A8)"},Gt={build:{label:"Build",icon:"B"},quality:{label:"Quality",icon:"Q"},system:{label:"System",icon:"S"},security:{label:"Security",icon:"!"}},et=class extends h{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(t,e,i){e!==i&&(t==="api-url"&&(this._loadNotifications(),this._loadTriggers()),t==="theme"&&this._applyTheme())}async _loadNotifications(){try{let t=this.getAttribute("api-url")||window.location.origin,e=await fetch(t+"/api/notifications");if(e.ok){let i=await e.json();this._notifications=i.notifications||[],this._summary=i.summary||{},this._connected=!0}}catch{this._connected=!1}this.render()}async _loadTriggers(){try{let t=this.getAttribute("api-url")||window.location.origin,e=await fetch(t+"/api/notifications/triggers");if(e.ok){let i=await e.json();this._triggers=i.triggers||[]}}catch{}}async _acknowledgeNotification(t){let e=this.getAttribute("api-url")||window.location.origin;await fetch(e+"/api/notifications/"+encodeURIComponent(t)+"/acknowledge",{method:"POST"})
|
|
7769
|
+
`,this.shadowRoot.querySelectorAll(".tab").forEach(e=>{e.addEventListener("click",()=>{this._setTab(e.dataset.tab)})})}};customElements.get("loki-context-tracker")||customElements.define("loki-context-tracker",tt);var Dt={critical:"var(--loki-red, #ef4444)",warning:"var(--loki-yellow, #eab308)",info:"var(--loki-blue, #3b82f6)",success:"var(--loki-green, #1FC5A8)"},Gt={build:{label:"Build",icon:"B"},quality:{label:"Quality",icon:"Q"},system:{label:"System",icon:"S"},security:{label:"Security",icon:"!"}},et=class extends h{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(t,e,i){e!==i&&(t==="api-url"&&(this._loadNotifications(),this._loadTriggers()),t==="theme"&&this._applyTheme())}async _loadNotifications(){try{let t=this.getAttribute("api-url")||window.location.origin,e=await fetch(t+"/api/notifications");if(e.ok){let i=await e.json();this._notifications=i.notifications||[],this._summary=i.summary||{},this._connected=!0}}catch{this._connected=!1}this.render()}async _loadTriggers(){try{let t=this.getAttribute("api-url")||window.location.origin,e=await fetch(t+"/api/notifications/triggers");if(e.ok){let i=await e.json();this._triggers=i.triggers||[]}}catch{}}async _acknowledgeNotification(t){let e=this.getAttribute("api-url")||window.location.origin;try{await fetch(e+"/api/notifications/"+encodeURIComponent(t)+"/acknowledge",{method:"POST"})}catch{}this._loadNotifications()}async _unacknowledgeNotification(t){let e=this.getAttribute("api-url")||window.location.origin;await fetch(e+"/api/notifications/"+encodeURIComponent(t)+"/unacknowledge",{method:"POST"}),this._loadNotifications()}async _acknowledgeAll(){let t=this.getAttribute("api-url")||window.location.origin,e=this._notifications.filter(i=>!i.acknowledged);for(let i of e)await fetch(t+"/api/notifications/"+encodeURIComponent(i.id)+"/acknowledge",{method:"POST"});this._loadNotifications()}async _toggleTrigger(t,e){let i=this.getAttribute("api-url")||window.location.origin,a=this._triggers.map(s=>s.id===t?{...s,enabled:e}: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._pollInterval=setInterval(()=>{this._loadNotifications(),this._loadTriggers()},5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_formatTime(t){if(!t)return"";try{let e=new Date(t),a=new Date-e,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":e.toLocaleDateString()}catch{return String(t)}}_getTimeGroup(t){if(!t)return"Other";try{let e=new Date(t),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),e>=a?"Today":e>=s?"Yesterday":e>=r?"This Week":"Earlier"}catch{return"Other"}}_escapeHTML(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getSeverityColor(t){return Dt[t]||Dt.info}_getCategory(t){return t.category||t.type||"system"}_switchTab(t){this._activeTab=t,this.render()}_setCategoryFilter(t){this._categoryFilter=t,this.render()}_togglePanel(){this._panelOpen=!this._panelOpen,this.render()}_bindEvents(){let t=this.shadowRoot;t.querySelectorAll(".tab").forEach(a=>{a.addEventListener("click",()=>{this._switchTab(a.dataset.tab)})}),t.querySelectorAll(".cat-btn").forEach(a=>{a.addEventListener("click",()=>{this._setCategoryFilter(a.dataset.cat)})}),t.querySelectorAll(".ack-btn").forEach(a=>{a.addEventListener("click",s=>{s.stopPropagation(),this._acknowledgeNotification(a.dataset.id)})}),t.querySelectorAll(".unread-btn").forEach(a=>{a.addEventListener("click",s=>{s.stopPropagation(),this._unacknowledgeNotification(a.dataset.id)})});let e=t.querySelector(".ack-all-btn");e&&e.addEventListener("click",()=>{this._acknowledgeAll()});let i=t.querySelector(".bell-icon");i&&i.addEventListener("click",()=>{this._togglePanel()}),t.querySelectorAll(".toggle input").forEach(a=>{a.addEventListener("change",()=>{this._toggleTrigger(a.dataset.triggerId,a.checked)})}),t.querySelectorAll(".dismiss-btn").forEach(a=>{a.addEventListener("click",s=>{s.stopPropagation(),this._acknowledgeNotification(a.dataset.id)})})}_renderBellIcon(){let t=this._summary.unacknowledged||0;return`
|
|
7770
7770
|
<div class="bell-container">
|
|
7771
7771
|
<button class="bell-icon" title="${t} unread notifications">
|
|
7772
7772
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
@@ -8796,7 +8796,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
8796
8796
|
|
|
8797
8797
|
${o}
|
|
8798
8798
|
</div>
|
|
8799
|
-
`;let n=this.shadowRoot.getElementById("optimize-btn");n&&n.addEventListener("click",()=>this._triggerOptimize()),this.shadowRoot.querySelectorAll(".change-header").forEach(l=>{l.addEventListener("click",()=>{this._toggleChange(parseInt(l.dataset.index))})})}};customElements.get("loki-prompt-optimizer")||customElements.define("loki-prompt-optimizer",at);var st=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data=null,this._history=[],this._error=null,this._loading=!0,this._scanning=!1,this._rigourAvailable=!0,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _loadData(){try{let[t,e]=await Promise.allSettled([this._api._get("/api/quality-score"),this._api._get("/api/quality-score/history")]);if(t.status==="fulfilled"){let i=t.value;i&&i.error&&i.error.includes("not installed")?(this._rigourAvailable=!1,this._data=null):(this._rigourAvailable=!0,this._data=i),this._error=null}else(t.reason?.message||"").includes("404")?(this._rigourAvailable=!1,this._data=null,this._error=null):(this._error="Failed to load quality score",this._data=null);if(e.status==="fulfilled"){let i=e.value;this._history=Array.isArray(i)?i.slice(-10):(i.scores||[]).slice(-10)}}catch(t){this._error=t.message,this._data=null}this._loading=!1,this.render()}async _triggerScan(){if(!this._scanning){this._scanning=!0,this.render();try{await this._api._post("/api/quality-scan",{}),await this._loadData()}catch(t){this._error=t.message}this._scanning=!1,this.render()}}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),6e4)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getGrade(t){return t>=90?{grade:"A",color:"var(--loki-success)"}:t>=80?{grade:"B",color:"var(--loki-success)"}:t>=70?{grade:"C",color:"var(--loki-warning)"}:t>=60?{grade:"D",color:"var(--loki-warning)"}:{grade:"F",color:"var(--loki-error)"}}_renderSparkline(t){if(!t||t.length<2)return"";let e=t.map(c=>typeof c=="number"?c:c.score||0),i=Math.min(...e),s=Math.max(...e)-i||1,r=120,o=32,n=2,l=e.map((c,p)=>{let u=n+p/(e.length-1)*(r-n*2),b=n+(1-(c-i)/s)*(o-n*2);return`${u},${b}`}).join(" ");return`
|
|
8799
|
+
`;let n=this.shadowRoot.getElementById("optimize-btn");n&&n.addEventListener("click",()=>this._triggerOptimize()),this.shadowRoot.querySelectorAll(".change-header").forEach(l=>{l.addEventListener("click",()=>{this._toggleChange(parseInt(l.dataset.index))})})}};customElements.get("loki-prompt-optimizer")||customElements.define("loki-prompt-optimizer",at);var st=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data=null,this._history=[],this._error=null,this._loading=!0,this._scanning=!1,this._rigourAvailable=!0,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _loadData(){try{let[t,e]=await Promise.allSettled([this._api._get("/api/quality-score"),this._api._get("/api/quality-score/history")]);if(t.status==="fulfilled"){let i=t.value;i&&i.error&&i.error.includes("not installed")?(this._rigourAvailable=!1,this._data=null):(this._rigourAvailable=!0,this._data=i),this._error=null}else(t.reason?.message||"").includes("404")?(this._rigourAvailable=!1,this._data=null,this._error=null):(this._error="Failed to load quality score",this._data=null);if(e.status==="fulfilled"){let i=e.value;this._history=Array.isArray(i)?i.slice(-10):(i.scores||[]).slice(-10)}}catch(t){this._error=t.message,this._data=null}this._loading=!1,this.render()}async _triggerScan(){if(!this._scanning){this._scanning=!0,this.render();try{await this._api._post("/api/quality-scan",{},{timeout:3e5}),await this._loadData()}catch(t){this._error=t.message}this._scanning=!1,this.render()}}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),6e4)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getGrade(t){return t>=90?{grade:"A",color:"var(--loki-success)"}:t>=80?{grade:"B",color:"var(--loki-success)"}:t>=70?{grade:"C",color:"var(--loki-warning)"}:t>=60?{grade:"D",color:"var(--loki-warning)"}:{grade:"F",color:"var(--loki-error)"}}_renderSparkline(t){if(!t||t.length<2)return"";let e=t.map(c=>typeof c=="number"?c:c.score||0),i=Math.min(...e),s=Math.max(...e)-i||1,r=120,o=32,n=2,l=e.map((c,p)=>{let u=n+p/(e.length-1)*(r-n*2),b=n+(1-(c-i)/s)*(o-n*2);return`${u},${b}`}).join(" ");return`
|
|
8800
8800
|
<svg width="${r}" height="${o}" viewBox="0 0 ${r} ${o}" class="sparkline">
|
|
8801
8801
|
<polyline points="${l}" fill="none" stroke="var(--loki-accent)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
8802
8802
|
<circle cx="${l.split(" ").pop().split(",")[0]}" cy="${l.split(" ").pop().split(",")[1]}" r="2.5" fill="var(--loki-accent)"/>
|
|
@@ -9137,7 +9137,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
9137
9137
|
</div>
|
|
9138
9138
|
`:""}
|
|
9139
9139
|
</div>
|
|
9140
|
-
`;let
|
|
9140
|
+
`;let m=this.shadowRoot.getElementById("scan-btn");m&&m.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-score")||customElements.define("loki-quality-score",st);var Kt=["understand","guardrail","migrate","verify"],Vt={understand:"Understand",guardrail:"Guardrail",migrate:"Migrate",verify:"Verify"},fe={understand:"#5b9bd5",guardrail:"#e8b84a",migrate:"#5bb870",verify:"#5bc8c8"},rt=class extends h{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._pollInterval=setInterval(()=>this._fetchData(),15e3)}disconnectedCallback(){super.disconnectedCallback(),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._fetchMigrations()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _fetchMigrations(){try{let t=await this._api._get("/api/migration/list");this._migrations=Array.isArray(t)?t:t.migrations||[],this._error=null;let e=this._migrations.find(i=>i.status==="in_progress"||i.status==="active");e?await this._fetchStatus(e.migration_id||e.id):this._migration=null}catch(t){this._error=t.message,this._migrations=[],this._migration=null}this._loading=!1,this.render()}async _fetchStatus(t){try{this._migration=await this._api._get(`/api/migration/${encodeURIComponent(t)}/status`),this._error=null}catch(e){this._error=e.message}}async _fetchData(){let t=this._migration&&(this._migration.migration_id||this._migration.id);t?(await this._fetchStatus(t),this.render()):await this._fetchMigrations()}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"):""}_getPhaseIcon(t,e,i){return(i||[]).includes(t)?"[x]":t===e?"[>]":"[ ]"}_getPhaseIndex(t){let e=Kt.indexOf(t);return e>=0?e:0}_renderPhaseBar(t,e){let i=e||[];return Kt.map(a=>{let s=i.includes(a),r=a===t,o=fe[a],n=s?"1":r?"0.7":"0.2",l=this._getPhaseIcon(a,t,e);return`
|
|
9141
9141
|
<div class="phase-segment">
|
|
9142
9142
|
<div class="phase-bar-fill" style="background:${o};opacity:${n};"></div>
|
|
9143
9143
|
<div class="phase-label">
|
|
@@ -10510,16 +10510,16 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
10510
10510
|
<div class="history-label">Past Cycles (${this._cycleHistory.length} total)</div>
|
|
10511
10511
|
<div class="history-cycles">${e}</div>
|
|
10512
10512
|
</div>
|
|
10513
|
-
`}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}render(){let t=this.shadowRoot;if(!t)return;let e=this.runId,i=this._timeline,a=i?.phases||[],s=i?.current_phase||null,r=$e(a),o;if(this._loading&&!i)o='<div class="loading">Loading timeline...</div>';else if(e==null)o=this._renderPlaceholderTimeline();else if(a.length===0)o=this._renderPlaceholderTimeline();else{let n=r.map(u=>{let b=F[u.phase]||{color:"var(--loki-text-muted)",label:u.phase},
|
|
10513
|
+
`}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}render(){let t=this.shadowRoot;if(!t)return;let e=this.runId,i=this._timeline,a=i?.phases||[],s=i?.current_phase||null,r=$e(a),o;if(this._loading&&!i)o='<div class="loading">Loading timeline...</div>';else if(e==null)o=this._renderPlaceholderTimeline();else if(a.length===0)o=this._renderPlaceholderTimeline();else{let n=r.map(u=>{let b=F[u.phase]||{color:"var(--loki-text-muted)",label:u.phase},m=s===u.phase,f=this._selectedPhase===u.phase;return`<div class="phase-segment-interactive ${m?"current":""} ${f?"selected":""}"
|
|
10514
10514
|
data-phase="${u.phase}"
|
|
10515
10515
|
style="width: ${Math.max(u.pct,2)}%; background: ${b.color};"
|
|
10516
10516
|
title="${b.label}: ${Lt(u.duration)}">
|
|
10517
10517
|
${u.pct>12?b.label:""}
|
|
10518
|
-
</div>`}).join(""),l=a.map(u=>{let b=F[u.phase]||{color:"var(--loki-text-muted)",label:u.phase},
|
|
10518
|
+
</div>`}).join(""),l=a.map(u=>{let b=F[u.phase]||{color:"var(--loki-text-muted)",label:u.phase},m=s===u.phase;return`<div class="legend-item-interactive ${this._selectedPhase===u.phase?"selected":""}" data-phase="${u.phase}">
|
|
10519
10519
|
<span class="legend-dot" style="background: ${b.color}"></span>
|
|
10520
10520
|
<span class="legend-label">${b.label}</span>
|
|
10521
10521
|
<span class="legend-duration">${Lt(u.duration_ms)}</span>
|
|
10522
|
-
${
|
|
10522
|
+
${m?'<span class="phase-current-tag">ACTIVE</span>':""}
|
|
10523
10523
|
</div>`}).join(""),c=this._selectedPhase?this._renderPhaseDetail(this._selectedPhase):"",p=this._renderCycleHistory();o=`
|
|
10524
10524
|
<div class="timeline-bar">${n}</div>
|
|
10525
10525
|
<div class="legend">${l}</div>
|
|
@@ -12011,7 +12011,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
12011
12011
|
</div>
|
|
12012
12012
|
${e}
|
|
12013
12013
|
</div>
|
|
12014
|
-
`,this._bindEvents()}};customElements.get("loki-provider-health")||customElements.define("loki-provider-health",gt);var Rt=[{id:"planning",label:"Planning",icon:"P"},{id:"scaffolding",label:"Scaffolding",icon:"S"},{id:"implementation",label:"Implementation",icon:"I"},{id:"testing",label:"Testing",icon:"T"},{id:"review",label:"Review",icon:"R"},{id:"deploy",label:"Deploy",icon:"D"}],Bt={waiting:{color:"var(--loki-text-muted, #939084)",bgColor:"var(--loki-bg-tertiary, #ECEAE3)",label:"Waiting"},active:{color:"var(--loki-accent, #553DE9)",bgColor:"var(--loki-accent-muted, rgba(85, 61, 233, 0.10))",label:"Active"},complete:{color:"var(--loki-green, #1FC5A8)",bgColor:"var(--loki-green-muted, rgba(31, 197, 168, 0.12))",label:"Complete"},failed:{color:"var(--loki-red, #C45B5B)",bgColor:"var(--loki-red-muted, rgba(196, 91, 91, 0.12))",label:"Failed"}},
|
|
12014
|
+
`,this._bindEvents()}};customElements.get("loki-provider-health")||customElements.define("loki-provider-health",gt);var Rt=[{id:"planning",label:"Planning",icon:"P"},{id:"scaffolding",label:"Scaffolding",icon:"S"},{id:"implementation",label:"Implementation",icon:"I"},{id:"testing",label:"Testing",icon:"T"},{id:"review",label:"Review",icon:"R"},{id:"deploy",label:"Deploy",icon:"D"}],Bt={waiting:{color:"var(--loki-text-muted, #939084)",bgColor:"var(--loki-bg-tertiary, #ECEAE3)",label:"Waiting"},active:{color:"var(--loki-accent, #553DE9)",bgColor:"var(--loki-accent-muted, rgba(85, 61, 233, 0.10))",label:"Active"},complete:{color:"var(--loki-green, #1FC5A8)",bgColor:"var(--loki-green-muted, rgba(31, 197, 168, 0.12))",label:"Complete"},failed:{color:"var(--loki-red, #C45B5B)",bgColor:"var(--loki-red-muted, rgba(196, 91, 91, 0.12))",label:"Failed"}},mt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._stages=[],this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let t=await this._api._get("/api/v2/pipeline/status");this._stages=t.stages||[]}catch{this._stages.length===0&&(this._stages=this._getDemoData())}this.render()}_getDemoData(){return[{id:"planning",status:"complete",errors:0,duration_ms:12500},{id:"scaffolding",status:"complete",errors:0,duration_ms:8300},{id:"implementation",status:"active",errors:0,duration_ms:45e3},{id:"testing",status:"waiting",errors:0,duration_ms:null},{id:"review",status:"waiting",errors:0,duration_ms:null},{id:"deploy",status:"waiting",errors:0,duration_ms:null}]}_getStageData(t){return this._stages.find(e=>e.id===t)||{id:t,status:"waiting",errors:0}}_formatDuration(t){if(t==null||t<0)return"";if(t<1e3)return t+"ms";let e=Math.floor(t/1e3);if(e<60)return e+"s";let i=Math.floor(e/60),a=e%60;return i+"m "+a+"s"}_getStyles(){return`
|
|
12015
12015
|
:host {
|
|
12016
12016
|
display: block;
|
|
12017
12017
|
}
|
|
@@ -12184,9 +12184,9 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
12184
12184
|
${r.duration_ms?`<span class="stage-duration">${this._formatDuration(r.duration_ms)}</span>`:""}
|
|
12185
12185
|
${r.errors>0?`<span class="stage-error-count">${r.errors} error${r.errors>1?"s":""}</span>`:""}
|
|
12186
12186
|
</div>
|
|
12187
|
-
`;if(s<Rt.length-1){let b=this._getStageData(Rt[s+1].id),
|
|
12187
|
+
`;if(s<Rt.length-1){let b=this._getStageData(Rt[s+1].id),m=n,f=l||n&&(b.status==="active"||b.status==="waiting");return u+`
|
|
12188
12188
|
<div class="connector">
|
|
12189
|
-
<div class="connector-line ${
|
|
12189
|
+
<div class="connector-line ${m?"completed":l?"active":"pending"}"></div>
|
|
12190
12190
|
${l?'<div class="flow-dot"></div>':""}
|
|
12191
12191
|
</div>
|
|
12192
12192
|
`}return u}).join(""),i=Object.entries(Bt).map(([a,s])=>`<div class="legend-item">
|
|
@@ -12205,7 +12205,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
12205
12205
|
${i}
|
|
12206
12206
|
</div>
|
|
12207
12207
|
</div>
|
|
12208
|
-
`}};customElements.get("loki-pipeline-view")||customElements.define("loki-pipeline-view",
|
|
12208
|
+
`}};customElements.get("loki-pipeline-view")||customElements.define("loki-pipeline-view",mt);var vt={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 ze(d,t,e){let i=t/2,a=e/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 bt=class extends h{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(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),15e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let t=await this._api._get("/api/v2/memory/graph");this._nodes=t.nodes||[],this._edges=t.edges||[]}catch{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(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_selectNode(t){this._selectedNode=this._selectedNode===t?null:t,this.render()}_bindEvents(){let t=this.shadowRoot;t.querySelectorAll(".graph-node").forEach(e=>{e.addEventListener("click",()=>{this._selectNode(e.dataset.nodeId)})}),t.querySelectorAll(".close-detail").forEach(e=>{e.addEventListener("click",()=>{this._selectedNode=null,this.render()})})}_renderNodeShape(t,e,i){let a=vt[t.type]||vt.episode,s=10+(t.importance||.5)*16,r=this._selectedNode===t.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="${e-s/2}" y="${i-s/2}" width="${s}" height="${s}"
|
|
12209
12209
|
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="${e},${i-u} ${e+u},${i} ${e},${i+u} ${e-u},${i}"
|
|
12210
12210
|
fill="${a.color}" fill-opacity="0.2" stroke="${o}" stroke-width="${n}" opacity="${l}" />`;break}default:c=`<circle cx="${e}" cy="${i}" r="${s/2}" fill="${a.color}" fill-opacity="0.2"
|
|
12211
12211
|
stroke="${o}" stroke-width="${n}" opacity="${l}" />`}let p=`<text x="${e}" y="${i+s/2+14}" text-anchor="middle" font-size="10"
|
|
@@ -12366,7 +12366,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
12366
12366
|
</div>
|
|
12367
12367
|
<div class="empty-state">No memory entries to visualize</div>
|
|
12368
12368
|
</div>
|
|
12369
|
-
`;return}let e=this._graphWidth,i=this._graphHeight,a=ze(this._nodes,e,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=
|
|
12369
|
+
`;return}let e=this._graphWidth,i=this._graphHeight,a=ze(this._nodes,e,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=vt[l.type]||vt.episode;o=`
|
|
12370
12370
|
<div class="detail-panel">
|
|
12371
12371
|
<div class="detail-header">
|
|
12372
12372
|
<span class="detail-title">${this._escapeHtml(l.label)}</span>
|
|
@@ -12375,7 +12375,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
12375
12375
|
</div>
|
|
12376
12376
|
<div class="detail-body">${this._escapeHtml(l.details||"No details available")}</div>
|
|
12377
12377
|
</div>
|
|
12378
|
-
`}}let n=Object.entries(
|
|
12378
|
+
`}}let n=Object.entries(vt).map(([,l])=>{let c;return l.shape==="circle"?c=`<div class="legend-circle" style="border-color: ${l.color};"></div>`:l.shape==="square"?c=`<div class="legend-square" style="border-color: ${l.color};"></div>`:c=`<div class="legend-diamond" style="border-color: ${l.color};"></div>`,`<div class="legend-item">
|
|
12379
12379
|
<div class="legend-shape">${c}</div>
|
|
12380
12380
|
<span>${l.label}</span>
|
|
12381
12381
|
</div>`}).join("");t.innerHTML=`
|
|
@@ -12830,7 +12830,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
12830
12830
|
</div>
|
|
12831
12831
|
<div class="empty-state">No agent performance data available</div>
|
|
12832
12832
|
</div>
|
|
12833
|
-
`;return}let e=this._agents.map((i,a)=>{let s=a+1,r=He[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,b;r?b=`<div class="rank-badge" style="background: ${r.bg}; color: ${r.border};">${s}</div>`:b=`<span class="rank-number" style="color: var(--loki-text-muted);">${s}</span>`;let
|
|
12833
|
+
`;return}let e=this._agents.map((i,a)=>{let s=a+1,r=He[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,b;r?b=`<div class="rank-badge" style="background: ${r.bg}; color: ${r.border};">${s}</div>`:b=`<span class="rank-number" style="color: var(--loki-text-muted);">${s}</span>`;let m="";n>0?m=`<span class="rank-change rank-up">+${n}</span>`:n<0&&(m=`<span class="rank-change rank-down">${n}</span>`);let f=l?`
|
|
12834
12834
|
<div class="agent-detail">
|
|
12835
12835
|
<div class="detail-metric">
|
|
12836
12836
|
<span class="detail-label">Total Cost</span>
|
|
@@ -12848,7 +12848,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
12848
12848
|
`:"";return`
|
|
12849
12849
|
<div class="agent-row ${s<=3?"top-3":""}" data-agent="${this._escapeHtml(o)}"
|
|
12850
12850
|
style="${r?"border-left-color: "+r.border+";":""}">
|
|
12851
|
-
<div class="rank-cell">${b}${
|
|
12851
|
+
<div class="rank-cell">${b}${m}</div>
|
|
12852
12852
|
<div class="agent-name-cell">
|
|
12853
12853
|
<span class="agent-name">${this._escapeHtml(i.name||i.type)}</span>
|
|
12854
12854
|
<span class="agent-type">${this._escapeHtml(i.type||"")}</span>
|
|
@@ -13344,7 +13344,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
13344
13344
|
border-radius: 4px;
|
|
13345
13345
|
}
|
|
13346
13346
|
</style>
|
|
13347
|
-
`,i="";this._loading&&this._items.length===0?i='<div class="esc-empty">Loading escalations...</div>':this._error?i='<div class="esc-error">Failed to load escalations: '+this._escapeHtml(this._error)+"</div>":!this._items||this._items.length===0?i='<div class="esc-empty">Escalations: no events yet. Handoff/escalation markdown documents written by the runner under .loki/escalations/ will appear here.</div>':i='<div class="esc-list">'+this._items.map(n=>{let l=this._escapeHtml(n.filename||""),c=this._escapeHtml(this._formatSize(n.size_bytes)),p=this._escapeHtml(this._formatDate(n.modified_at));return'<div class="esc-item" data-filename="'+l+'"><span class="esc-name">'+l+'</span><span class="esc-meta">'+c+" · "+p+"</span></div>"}).join("")+"</div>";let a="";if(this._activeFile){let o=this._escapeHtml(this._activeFile),n;this._activeBodyError?n='<div class="esc-error">Failed to load: '+this._escapeHtml(this._activeBodyError)+"</div>":this._activeBody===null?n='<div class="esc-body">Loading '+o+"...</div>":n='<div class="esc-body">'+this._escapeHtml(this._activeBody)+"</div>",a='<div class="esc-viewer"><div class="esc-viewer-header"><span class="esc-name">'+o+'</span><button class="esc-close-btn" data-action="close">Close</button></div>'+n+"</div>"}t.innerHTML=e+'<div class="esc-wrapper"><div class="esc-explain">Handoff/escalation documents written under .loki/escalations/. Click an entry to view its contents.</div>'+i+a+"</div>",t.querySelectorAll(".esc-item").forEach(o=>{o.addEventListener("click",()=>{let n=o.getAttribute("data-filename");n&&this._openFile(n)})});let r=t.querySelector('.esc-close-btn[data-action="close"]');r&&r.addEventListener("click",()=>this._closeFile())}};typeof customElements<"u"&&!customElements.get("loki-escalations")&&customElements.define("loki-escalations",_t);var yt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._transcripts=[],this._hookEvents=[],this._loading=!1,this._error=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._load(),this._pollInterval=setInterval(()=>this._load(),3e4)}disconnectedCallback(){super.disconnectedCallback(),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._load()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||(typeof window<"u"?window.location.origin:"");this._api=g({baseUrl:t})}async _load(){this._loading=!0,this._error=null;try{let t=await this._api.get("/api/council/transcripts?limit=10");this._transcripts=Array.isArray(t&&t.transcripts)?t.transcripts:[]}catch(t){this._error=t&&t.message?t.message:String(t),this._transcripts=[]}try{let t=await this._api.get("/api/council/transcripts?limit=20&type_prefix=claude_hook_");this._hookEvents=Array.isArray(t&&t.hook_events)?t.hook_events:[]}catch{this._hookEvents=[]}finally{this._loading=!1,this.render()}}_escapeHtml(t){return t==null?"":String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}_formatTimestamp(t){if(!t)return"--";try{let e=new Date(t);return isNaN(e.getTime())?t:e.toLocaleString()}catch{return t}}_truncate(t,e){if(!t)return"";let i=String(t);return i.length>e?i.slice(0,e)+"...":i}_verdictBadgeHtml(t){let e=String(t||"").toUpperCase();return e==="APPROVE"?'<span class="ct-badge ct-badge-approve">APPROVE</span>':e==="REJECT"?'<span class="ct-badge ct-badge-reject">REJECT</span>':e==="CANNOT_VALIDATE"?'<span class="ct-badge ct-badge-cannot">CANNOT_VALIDATE</span>':'<span class="ct-badge ct-badge-unknown">'+this._escapeHtml(e||"UNKNOWN")+"</span>"}_outcomeBadgeHtml(t){let e=String(t||"").toUpperCase();return e==="APPROVED"?'<span class="ct-badge ct-badge-approve">APPROVED</span>':e==="REJECTED"?'<span class="ct-badge ct-badge-reject">REJECTED</span>':e==="BLOCKED_BY_GATE"?'<span class="ct-badge ct-badge-blocked">BLOCKED BY GATE</span>':'<span class="ct-badge ct-badge-unknown">'+this._escapeHtml(e||"UNKNOWN")+"</span>"}_voterRowHtml(t,e){let i=t.is_contrarian===!0,a=i&&e===!0,s="ct-voter-row";i&&(s+=" ct-voter-contrarian"),a&&(s+=" ct-voter-flipped");let r=this._escapeHtml(t.name||"unknown"),o=this._verdictBadgeHtml(t.verdict),n=this._escapeHtml(this._truncate(t.reasoning,300)),l="",c="";a?(l='<span class="ct-badge ct-badge-override">OVERRIDE</span>',c=`<div class="ct-flip-caption">Devil's Advocate flipped this outcome</div>`):i&&t.triggered&&(l=`<span class="ct-badge ct-badge-da">DEVIL'S ADVOCATE</span>`);let p="";i&&Array.isArray(t.challenges)&&t.challenges.length>0&&(p='<ul class="ct-challenges">'+t.challenges.map(
|
|
13347
|
+
`,i="";this._loading&&this._items.length===0?i='<div class="esc-empty">Loading escalations...</div>':this._error?i='<div class="esc-error">Failed to load escalations: '+this._escapeHtml(this._error)+"</div>":!this._items||this._items.length===0?i='<div class="esc-empty">Escalations: no events yet. Handoff/escalation markdown documents written by the runner under .loki/escalations/ will appear here.</div>':i='<div class="esc-list">'+this._items.map(n=>{let l=this._escapeHtml(n.filename||""),c=this._escapeHtml(this._formatSize(n.size_bytes)),p=this._escapeHtml(this._formatDate(n.modified_at));return'<div class="esc-item" data-filename="'+l+'"><span class="esc-name">'+l+'</span><span class="esc-meta">'+c+" · "+p+"</span></div>"}).join("")+"</div>";let a="";if(this._activeFile){let o=this._escapeHtml(this._activeFile),n;this._activeBodyError?n='<div class="esc-error">Failed to load: '+this._escapeHtml(this._activeBodyError)+"</div>":this._activeBody===null?n='<div class="esc-body">Loading '+o+"...</div>":n='<div class="esc-body">'+this._escapeHtml(this._activeBody)+"</div>",a='<div class="esc-viewer"><div class="esc-viewer-header"><span class="esc-name">'+o+'</span><button class="esc-close-btn" data-action="close">Close</button></div>'+n+"</div>"}t.innerHTML=e+'<div class="esc-wrapper"><div class="esc-explain">Handoff/escalation documents written under .loki/escalations/. Click an entry to view its contents.</div>'+i+a+"</div>",t.querySelectorAll(".esc-item").forEach(o=>{o.addEventListener("click",()=>{let n=o.getAttribute("data-filename");n&&this._openFile(n)})});let r=t.querySelector('.esc-close-btn[data-action="close"]');r&&r.addEventListener("click",()=>this._closeFile())}};typeof customElements<"u"&&!customElements.get("loki-escalations")&&customElements.define("loki-escalations",_t);var yt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._transcripts=[],this._hookEvents=[],this._loading=!1,this._error=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._load(),this._pollInterval=setInterval(()=>this._load(),3e4)}disconnectedCallback(){super.disconnectedCallback(),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._load()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||(typeof window<"u"?window.location.origin:"");this._api=g({baseUrl:t})}async _load(){this._loading=!0,this._error=null;try{let t=await this._api.get("/api/council/transcripts?limit=10");this._transcripts=Array.isArray(t&&t.transcripts)?t.transcripts:[]}catch(t){this._error=t&&t.message?t.message:String(t),this._transcripts=[]}try{let t=await this._api.get("/api/council/transcripts?limit=20&type_prefix=claude_hook_");this._hookEvents=Array.isArray(t&&t.hook_events)?t.hook_events:[]}catch{this._hookEvents=[]}finally{this._loading=!1,this.render()}}_escapeHtml(t){return t==null?"":String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}_formatTimestamp(t){if(!t)return"--";try{let e=new Date(t);return isNaN(e.getTime())?t:e.toLocaleString()}catch{return t}}_truncate(t,e){if(!t)return"";let i=String(t);return i.length>e?i.slice(0,e)+"...":i}_verdictBadgeHtml(t){let e=String(t||"").toUpperCase();return e==="APPROVE"?'<span class="ct-badge ct-badge-approve">APPROVE</span>':e==="REJECT"?'<span class="ct-badge ct-badge-reject">REJECT</span>':e==="CANNOT_VALIDATE"?'<span class="ct-badge ct-badge-cannot">CANNOT_VALIDATE</span>':'<span class="ct-badge ct-badge-unknown">'+this._escapeHtml(e||"UNKNOWN")+"</span>"}_outcomeBadgeHtml(t){let e=String(t||"").toUpperCase();return e==="APPROVED"?'<span class="ct-badge ct-badge-approve">APPROVED</span>':e==="REJECTED"?'<span class="ct-badge ct-badge-reject">REJECTED</span>':e==="BLOCKED_BY_GATE"?'<span class="ct-badge ct-badge-blocked">BLOCKED BY GATE</span>':'<span class="ct-badge ct-badge-unknown">'+this._escapeHtml(e||"UNKNOWN")+"</span>"}_voterRowHtml(t,e){let i=t.is_contrarian===!0,a=i&&e===!0,s="ct-voter-row";i&&(s+=" ct-voter-contrarian"),a&&(s+=" ct-voter-flipped");let r=this._escapeHtml(t.name||"unknown"),o=this._verdictBadgeHtml(t.verdict),n=this._escapeHtml(this._truncate(t.reasoning,300)),l="",c="";a?(l='<span class="ct-badge ct-badge-override">OVERRIDE</span>',c=`<div class="ct-flip-caption">Devil's Advocate flipped this outcome</div>`):i&&t.triggered&&(l=`<span class="ct-badge ct-badge-da">DEVIL'S ADVOCATE</span>`);let p="";i&&Array.isArray(t.challenges)&&t.challenges.length>0&&(p='<ul class="ct-challenges">'+t.challenges.map(m=>"<li>"+this._escapeHtml(String(m))+"</li>").join("")+"</ul>");let u="";return Array.isArray(t.issues)&&t.issues.length>0&&(u='<ul class="ct-issues">'+t.issues.map(m=>{let f=this._escapeHtml(m.severity||""),x=this._escapeHtml(m.description||"");return'<li><span class="ct-issue-sev ct-issue-sev-'+f.toLowerCase()+'">'+f+"</span> "+x+"</li>"}).join("")+"</ul>"),'<div class="'+s+'"><div class="ct-voter-header"><span class="ct-voter-name">'+r+"</span>"+o+l+"</div>"+(n?'<div class="ct-voter-reason">'+n+"</div>":"")+p+u+c+"</div>"}_transcriptCardHtml(t){let e=this._escapeHtml(String(t.iteration||"--")),i=this._escapeHtml(this._formatTimestamp(t.timestamp)),a=this._escapeHtml(this._truncate(t.task_or_prd,200)),s=this._outcomeBadgeHtml(t.outcome),r=Array.isArray(t.voters)?t.voters:[],o=r.filter(m=>!m.is_contrarian),n=r.filter(m=>m.is_contrarian),l=o.map(m=>this._voterRowHtml(m,!1)).join(""),c="";t.contrarian_triggered&&(c='<div class="ct-contrarian-section"><div class="ct-section-label">Anti-Sycophancy Check</div>'+n.map(f=>this._voterRowHtml(f,t.contrarian_flipped)).join("")+"</div>");let p=typeof t.approve_count=="number"?t.approve_count:"--",u=typeof t.reject_count=="number"?t.reject_count:"--",b=typeof t.threshold=="number"?t.threshold:"--";return'<div class="ct-card"><div class="ct-card-header"><div class="ct-card-meta"><span class="ct-iter-label">Iteration '+e+'</span><span class="ct-ts">'+i+"</span></div>"+s+"</div>"+(a?'<div class="ct-prd-preview">'+a+"</div>":"")+'<div class="ct-tally">Approve: '+p+" · Reject: "+u+" · Threshold: "+b+'</div><div class="ct-voters">'+l+"</div>"+c+"</div>"}render(){let t=this.shadowRoot||this;if(!t)return;let e=`
|
|
13348
13348
|
<style>
|
|
13349
13349
|
:host { display: block; margin-top: 24px; }
|
|
13350
13350
|
.ct-wrapper {
|
|
@@ -13513,7 +13513,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
13513
13513
|
.ct-badge-da { background: #fdf3d4; color: #8a6c0e; }
|
|
13514
13514
|
.ct-badge-unknown { background: var(--bg-secondary, #F8F4F0); color: var(--text-muted, #939084); }
|
|
13515
13515
|
</style>
|
|
13516
|
-
`,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 council rounds recorded yet -- transcripts appear after the first iteration vote.</div>':i='<div class="ct-list">'+this._transcripts.map(s=>this._transcriptCardHtml(s)).join("")+"</div>",t.innerHTML=e+'<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 t=Array.isArray(this._hookEvents)?this._hookEvents:[],e;return t.length===0?e='<div class="ct-empty">No live tool activity yet -- Claude hook events stream here while a run is active.</div>':e='<div class="ct-voters">'+t.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>'+e}};typeof customElements<"u"&&!customElements.get("loki-council-transcripts")&&customElements.define("loki-council-transcripts",yt);var Re=[{id:"overview",label:"Overview"},{id:"architecture",label:"Architecture"},{id:"modules",label:"Key Modules"},{id:"data-flow",label:"Data Flow"},{id:"ask",label:"Ask"}],wt=class extends h{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._sectionCache={},this._question="",this._answer=null,this._asking=!1,this._askError=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadMeta()}attributeChangedCallback(t,e,i){t==="api-url"&&this._api&&(this._api.baseUrl=i)}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _loadMeta(){this._loading=!0,this._error=null,this.render();try{this._meta=await this._api._get("/api/wiki")}catch(t){this._error=t&&t.message?t.message:"Failed to load wiki"}finally{this._loading=!1,this.render()}}async _loadSection(t){if(this._sectionCache[t])return this._sectionCache[t];try{let e=await this._api._get(`/api/wiki/${encodeURIComponent(t)}`);return this._sectionCache[t]=e,e}catch(e){return this._sectionCache[t]={error:e&&e.message||"load failed"},this._sectionCache[t]}}async _selectTab(t){this._activeTab=t,
|
|
13516
|
+
`,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 council rounds recorded yet -- transcripts appear after the first iteration vote.</div>':i='<div class="ct-list">'+this._transcripts.map(s=>this._transcriptCardHtml(s)).join("")+"</div>",t.innerHTML=e+'<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 t=Array.isArray(this._hookEvents)?this._hookEvents:[],e;return t.length===0?e='<div class="ct-empty">No live tool activity yet -- Claude hook events stream here while a run is active.</div>':e='<div class="ct-voters">'+t.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>'+e}};typeof customElements<"u"&&!customElements.get("loki-council-transcripts")&&customElements.define("loki-council-transcripts",yt);var Re=[{id:"overview",label:"Overview"},{id:"architecture",label:"Architecture"},{id:"modules",label:"Key Modules"},{id:"data-flow",label:"Data Flow"},{id:"ask",label:"Ask"}],wt=class extends h{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._sectionCache={},this._question="",this._answer=null,this._asking=!1,this._askError=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadMeta()}attributeChangedCallback(t,e,i){t==="api-url"&&this._api&&(this._api.baseUrl=i)}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _loadMeta(){this._loading=!0,this._error=null,this.render();try{this._meta=await this._api._get("/api/wiki")}catch(t){this._error=t&&t.message?t.message:"Failed to load wiki"}finally{this._loading=!1,this.render();let t=this._activeTab;this._meta&&this._meta.generated&&(t==="architecture"||t==="modules"||t==="data-flow")&&!this._sectionCache[t]&&this._loadSection(t).then(()=>this.render())}}async _loadSection(t){if(this._sectionCache[t])return this._sectionCache[t];try{let e=await this._api._get(`/api/wiki/${encodeURIComponent(t)}`);return this._sectionCache[t]=e,e}catch(e){return this._sectionCache[t]={error:e&&e.message||"load failed"},this._sectionCache[t]}}async _selectTab(t){this._activeTab=t,t==="architecture"||t==="modules"||t==="data-flow"?this._meta&&this._meta.generated?(this.render(),await this._loadSection(t)):this.render():this.render()}async _ask(){let t=(this._question||"").trim();if(t){this._asking=!0,this._askError=null,this._answer=null,this.render();try{this._answer=await this._api._post("/api/wiki/ask",{question:t},{timeout:2e5})}catch(e){this._askError=e&&e.message?e.message:"Ask failed"}finally{this._asking=!1,this.render()}}}_esc(t){return String(t??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}_renderCitations(t){return!t||!t.length?"":`<div class="cites"><strong>Sources:</strong><ul>${t.map(i=>`<li><code>${this._esc(i.file)}:${this._esc(i.line)}</code></li>`).join("")}</ul></div>`}_renderOverview(){let t=this._meta;if(!t||!t.generated)return`<div class="empty">
|
|
13517
13517
|
<p>No wiki has been generated for this project yet.</p>
|
|
13518
13518
|
<p>Run <code>loki wiki generate</code> to build a cited codebase wiki.</p>
|
|
13519
13519
|
</div>`;let e=(t.sections||[]).map(i=>`<li>${this._esc(i.title)} <span class="dim">(${this._esc(i.citation_count)} citations)</span></li>`).join("");return`<div class="overview">
|
|
@@ -13521,7 +13521,10 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
13521
13521
|
${this._esc(t.file_count||0)} source files indexed.</p>
|
|
13522
13522
|
<p class="dim">Generated: ${this._esc(t.generated_at||"unknown")}</p>
|
|
13523
13523
|
<ul>${e}</ul>
|
|
13524
|
-
</div>`}_renderSection(t){
|
|
13524
|
+
</div>`}_renderSection(t){if(!this._meta||!this._meta.generated)return`<div class="empty">
|
|
13525
|
+
<p>No wiki generated yet.</p>
|
|
13526
|
+
<p>Run <code>loki wiki generate</code> to build a cited codebase wiki.</p>
|
|
13527
|
+
</div>`;let e=this._sectionCache[t];return e?e.error?`<div class="error">${this._esc(e.error)}</div>`:`<div class="section">
|
|
13525
13528
|
<h3>${this._esc(e.title)}</h3>
|
|
13526
13529
|
<pre class="body">${this._esc(e.body)}</pre>
|
|
13527
13530
|
${this._renderCitations(e.citations)}
|
|
@@ -13660,6 +13663,25 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
13660
13663
|
var sunIcon = document.getElementById('theme-icon-sun');
|
|
13661
13664
|
var moonIcon = document.getElementById('theme-icon-moon');
|
|
13662
13665
|
|
|
13666
|
+
// Resolve the active theme to a plain 'dark'|'light' for the iframe pages
|
|
13667
|
+
// (trust/cost/proofs), which live in separate documents and cannot read the
|
|
13668
|
+
// SPA's data-loki-theme attribute. v7.18.0.
|
|
13669
|
+
function lokiResolvedTheme() {
|
|
13670
|
+
var theme = LokiDashboard.UnifiedThemeManager.getTheme();
|
|
13671
|
+
return (theme.includes('dark') || theme === 'high-contrast') ? 'dark' : 'light';
|
|
13672
|
+
}
|
|
13673
|
+
|
|
13674
|
+
// Keep the trust iframe's theme in sync with the SPA toggle. If the frame is
|
|
13675
|
+
// already loaded, re-point its src with the new ?theme= so its palette flips
|
|
13676
|
+
// with the SPA instead of clashing.
|
|
13677
|
+
function syncTrustFrameTheme() {
|
|
13678
|
+
var tframe = document.getElementById('trust-frame');
|
|
13679
|
+
if (!tframe) return;
|
|
13680
|
+
var cur = tframe.getAttribute('src') || '';
|
|
13681
|
+
if (!cur || cur === 'about:blank') return; // not opened yet; opens with theme
|
|
13682
|
+
tframe.src = '/trust?theme=' + lokiResolvedTheme();
|
|
13683
|
+
}
|
|
13684
|
+
|
|
13663
13685
|
function updateThemeUI() {
|
|
13664
13686
|
var theme = LokiDashboard.UnifiedThemeManager.getTheme();
|
|
13665
13687
|
var isDark = theme.includes('dark') || theme === 'high-contrast';
|
|
@@ -13670,15 +13692,32 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
13670
13692
|
|
|
13671
13693
|
themeToggle.addEventListener('click', function() {
|
|
13672
13694
|
LokiDashboard.UnifiedThemeManager.toggle();
|
|
13673
|
-
updateThemeUI
|
|
13695
|
+
// updateThemeUI + syncTrustFrameTheme run via the loki-theme-change
|
|
13696
|
+
// listener below (toggle() dispatches it), so we do NOT call them here too
|
|
13697
|
+
// -- a direct call would re-point the trust iframe src twice per toggle.
|
|
13674
13698
|
});
|
|
13675
13699
|
|
|
13676
13700
|
window.addEventListener('loki-theme-change', function() {
|
|
13677
13701
|
updateThemeUI();
|
|
13702
|
+
syncTrustFrameTheme();
|
|
13678
13703
|
});
|
|
13679
13704
|
|
|
13680
13705
|
updateThemeUI();
|
|
13681
13706
|
|
|
13707
|
+
// Carry the SPA theme to the full-page standalone views (cost/proofs) opened
|
|
13708
|
+
// via direct links, so a user who toggled Dark gets a matching page instead
|
|
13709
|
+
// of an OS-default one. Updated on click so it always reflects the current
|
|
13710
|
+
// toggle state. v7.18.0.
|
|
13711
|
+
function lokiThemeHref(base) {
|
|
13712
|
+
return base + (base.indexOf('?') >= 0 ? '&' : '?') + 'theme=' + lokiResolvedTheme();
|
|
13713
|
+
}
|
|
13714
|
+
var costLink = document.getElementById('budget-banner-link');
|
|
13715
|
+
if (costLink) {
|
|
13716
|
+
costLink.addEventListener('click', function () {
|
|
13717
|
+
costLink.setAttribute('href', lokiThemeHref('/cost'));
|
|
13718
|
+
});
|
|
13719
|
+
}
|
|
13720
|
+
|
|
13682
13721
|
// API URL configuration - auto-detect from current server
|
|
13683
13722
|
var apiUrlInput = document.getElementById('api-url');
|
|
13684
13723
|
var connectBtn = document.getElementById('connect-btn');
|
|
@@ -13819,12 +13858,15 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
13819
13858
|
pageEl.classList.add('active');
|
|
13820
13859
|
}
|
|
13821
13860
|
// R4: lazy-load the trust panel iframe on first open (avoids a fetch on
|
|
13822
|
-
// every page that the user never visits).
|
|
13861
|
+
// every page that the user never visits). The iframe is a separate
|
|
13862
|
+
// document and cannot see the SPA's manual data-loki-theme toggle, so we
|
|
13863
|
+
// pass the resolved theme as a query param (?theme=dark|light); the
|
|
13864
|
+
// standalone page reads it and matches. v7.18.0.
|
|
13823
13865
|
if (sectionId === 'trust') {
|
|
13824
13866
|
var tframe = document.getElementById('trust-frame');
|
|
13825
13867
|
if (tframe && (!tframe.src || tframe.src === 'about:blank' ||
|
|
13826
13868
|
tframe.getAttribute('src') === 'about:blank')) {
|
|
13827
|
-
tframe.src = '/trust';
|
|
13869
|
+
tframe.src = '/trust?theme=' + lokiResolvedTheme();
|
|
13828
13870
|
}
|
|
13829
13871
|
}
|
|
13830
13872
|
// Update nav active state
|
|
@@ -13946,11 +13988,12 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
13946
13988
|
apiUrlInput.select();
|
|
13947
13989
|
break;
|
|
13948
13990
|
|
|
13949
|
-
// Theme toggle
|
|
13991
|
+
// Theme toggle. updateThemeUI + syncTrustFrameTheme run via the
|
|
13992
|
+
// loki-theme-change listener (toggle() dispatches it); do not call them
|
|
13993
|
+
// here too, or the trust iframe re-points twice per toggle.
|
|
13950
13994
|
case 't':
|
|
13951
13995
|
e.preventDefault();
|
|
13952
13996
|
LokiDashboard.UnifiedThemeManager.toggle();
|
|
13953
|
-
updateThemeUI();
|
|
13954
13997
|
break;
|
|
13955
13998
|
|
|
13956
13999
|
// Session controls
|