loki-mode 5.55.1 → 5.56.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/app-runner.sh +33 -5
- package/autonomy/completion-council.sh +2 -1
- package/autonomy/hooks/quality-gate.sh +0 -1
- package/autonomy/hooks/session-init.sh +3 -3
- package/autonomy/hooks/store-episode.sh +0 -1
- package/autonomy/issue-parser.sh +0 -2
- package/autonomy/sandbox.sh +29 -14
- package/autonomy/telemetry.sh +1 -1
- package/autonomy/voice.sh +0 -1
- package/dashboard/__init__.py +1 -1
- package/dashboard/static/index.html +578 -111
- package/docs/INSTALLATION.md +1 -1
- package/learning/suggest.sh +0 -8
- package/mcp/__init__.py +1 -1
- package/package.json +1 -1
|
@@ -562,6 +562,10 @@
|
|
|
562
562
|
<svg viewBox="0 0 24 24"><path d="M4 14h6v6H4z" fill="none" stroke="currentColor" stroke-width="2"/><path d="M14 4h6v6h-6z" fill="none" stroke="currentColor" stroke-width="2"/><path d="M17 10v4h-4" fill="none" stroke="currentColor" stroke-width="2"/><path d="M7 14v-4h4" fill="none" stroke="currentColor" stroke-width="2"/></svg>
|
|
563
563
|
Migration
|
|
564
564
|
</button>
|
|
565
|
+
<button class="nav-link" data-section="analytics" id="nav-analytics">
|
|
566
|
+
<svg viewBox="0 0 24 24"><line x1="18" y1="20" x2="18" y2="10" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><line x1="12" y1="20" x2="12" y2="4" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><line x1="6" y1="20" x2="6" y2="14" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
|
|
567
|
+
Analytics
|
|
568
|
+
</button>
|
|
565
569
|
</nav>
|
|
566
570
|
|
|
567
571
|
<div class="sidebar-footer">
|
|
@@ -687,6 +691,14 @@
|
|
|
687
691
|
</div>
|
|
688
692
|
<loki-migration-dashboard id="migration-dashboard"></loki-migration-dashboard>
|
|
689
693
|
</div>
|
|
694
|
+
|
|
695
|
+
<!-- Analytics -->
|
|
696
|
+
<div class="section-page" id="page-analytics">
|
|
697
|
+
<div class="section-page-header">
|
|
698
|
+
<h2 class="section-page-title">Analytics</h2>
|
|
699
|
+
</div>
|
|
700
|
+
<loki-analytics id="analytics-dashboard"></loki-analytics>
|
|
701
|
+
</div>
|
|
690
702
|
</main>
|
|
691
703
|
</div>
|
|
692
704
|
|
|
@@ -710,6 +722,7 @@
|
|
|
710
722
|
<div class="shortcut-row"><span class="shortcut-desc">Context</span><span class="shortcut-keys"><kbd class="shortcut-key">9</kbd></span></div>
|
|
711
723
|
<div class="shortcut-row"><span class="shortcut-desc">Notifications</span><span class="shortcut-keys"><kbd class="shortcut-key">0</kbd></span></div>
|
|
712
724
|
<div class="shortcut-row"><span class="shortcut-desc">Migration</span><span class="shortcut-keys"><kbd class="shortcut-key">m</kbd></span></div>
|
|
725
|
+
<div class="shortcut-row"><span class="shortcut-desc">Analytics</span><span class="shortcut-keys"><kbd class="shortcut-key">a</kbd></span></div>
|
|
713
726
|
</div>
|
|
714
727
|
<div class="shortcuts-group">
|
|
715
728
|
<div class="shortcuts-group-title">Session</div>
|
|
@@ -729,8 +742,8 @@
|
|
|
729
742
|
|
|
730
743
|
<!-- Inlined JavaScript Bundle -->
|
|
731
744
|
<script>
|
|
732
|
-
var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropertyDescriptor;var $t=Object.getOwnPropertyNames;var Et=Object.prototype.hasOwnProperty;var Ct=(c,t,e)=>t in c?st(c,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):c[t]=e;var St=(c,t)=>{for(var e in t)st(c,e,{get:t[e],enumerable:!0})},Tt=(c,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of $t(t))!Et.call(c,a)&&a!==e&&st(c,a,{get:()=>t[a],enumerable:!(i=wt(t,a))||i.enumerable});return c};var At=c=>Tt(st({},"__esModule",{value:!0}),c);var w=(c,t,e)=>Ct(c,typeof t!="symbol"?t+"":t,e);var Ut={};St(Ut,{ANIMATION:()=>T,ARIA_PATTERNS:()=>nt,ApiEvents:()=>l,BASE_STYLES:()=>B,BREAKPOINTS:()=>rt,COMMON_STYLES:()=>ut,KEYBOARD_SHORTCUTS:()=>ot,KeyboardHandler:()=>P,LokiApiClient:()=>R,LokiAppStatus:()=>V,LokiChecklistViewer:()=>K,LokiCheckpointViewer:()=>W,LokiContextTracker:()=>Q,LokiCostDashboard:()=>Y,LokiCouncilDashboard:()=>J,LokiElement:()=>p,LokiLearningDashboard:()=>G,LokiLogStream:()=>N,LokiMemoryBrowser:()=>q,LokiMigrationDashboard:()=>it,LokiNotificationCenter:()=>X,LokiOverview:()=>j,LokiPromptOptimizer:()=>tt,LokiQualityScore:()=>et,LokiSessionControl:()=>O,LokiSessionDiff:()=>Z,LokiState:()=>F,LokiTaskBoard:()=>U,LokiTheme:()=>D,RADIUS:()=>S,SPACING:()=>E,STATE_CHANGE_EVENT:()=>ct,THEMES:()=>k,THEME_VARIABLES:()=>lt,TYPOGRAPHY:()=>b,UnifiedThemeManager:()=>m,VERSION:()=>Ft,Z_INDEX:()=>A,createApiClient:()=>vt,createStore:()=>mt,generateThemeCSS:()=>f,generateTokensCSS:()=>H,getApiClient:()=>u,getState:()=>z,init:()=>jt});var k={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)"}},E={xs:"4px",sm:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"32px","3xl":"48px"},S={none:"0",sm:"2px",md:"4px",lg:"5px",xl:"5px",full:"9999px"},b={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"}},T={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)"}},rt={sm:"640px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},A={base:"0",dropdown:"100",sticky:"200",modal:"300",popover:"400",tooltip:"500",toast:"600"},ot={"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"]}},nt={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 f(c){let t=k[c];return t?Object.entries(t).map(([e,i])=>`${e}: ${i};`).join(`
|
|
733
|
-
`):""}function
|
|
745
|
+
var LokiDashboard=(()=>{var rt=Object.defineProperty;var $t=Object.getOwnPropertyDescriptor;var Et=Object.getOwnPropertyNames;var Ct=Object.prototype.hasOwnProperty;var Tt=(c,t,e)=>t in c?rt(c,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):c[t]=e;var St=(c,t)=>{for(var e in t)rt(c,e,{get:t[e],enumerable:!0})},At=(c,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of Et(t))!Ct.call(c,a)&&a!==e&&rt(c,a,{get:()=>t[a],enumerable:!(i=$t(t,a))||i.enumerable});return c};var Lt=c=>At(rt({},"__esModule",{value:!0}),c);var w=(c,t,e)=>Tt(c,typeof t!="symbol"?t+"":t,e);var qt={};St(qt,{ANIMATION:()=>S,ARIA_PATTERNS:()=>lt,ApiEvents:()=>d,BASE_STYLES:()=>B,BREAKPOINTS:()=>ot,COMMON_STYLES:()=>gt,KEYBOARD_SHORTCUTS:()=>nt,KeyboardHandler:()=>P,LokiAnalytics:()=>at,LokiApiClient:()=>M,LokiAppStatus:()=>K,LokiChecklistViewer:()=>V,LokiCheckpointViewer:()=>Y,LokiContextTracker:()=>Q,LokiCostDashboard:()=>W,LokiCouncilDashboard:()=>G,LokiElement:()=>p,LokiLearningDashboard:()=>J,LokiLogStream:()=>N,LokiMemoryBrowser:()=>q,LokiMigrationDashboard:()=>it,LokiNotificationCenter:()=>X,LokiOverview:()=>j,LokiPromptOptimizer:()=>tt,LokiQualityScore:()=>et,LokiSessionControl:()=>O,LokiSessionDiff:()=>Z,LokiState:()=>F,LokiTaskBoard:()=>U,LokiTheme:()=>D,RADIUS:()=>T,SPACING:()=>E,STATE_CHANGE_EVENT:()=>pt,THEMES:()=>_,THEME_VARIABLES:()=>dt,TYPOGRAPHY:()=>k,UnifiedThemeManager:()=>b,VERSION:()=>Ot,Z_INDEX:()=>A,createApiClient:()=>mt,createStore:()=>bt,generateThemeCSS:()=>x,generateTokensCSS:()=>R,getApiClient:()=>g,getState:()=>z,init:()=>Nt});var _={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)"}},E={xs:"4px",sm:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"32px","3xl":"48px"},T={none:"0",sm:"2px",md:"4px",lg:"5px",xl:"5px",full:"9999px"},k={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"}},S={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)"}},ot={sm:"640px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},A={base:"0",dropdown:"100",sticky:"200",modal:"300",popover:"400",tooltip:"500",toast:"600"},nt={"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"]}},lt={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 x(c){let t=_[c];return t?Object.entries(t).map(([e,i])=>`${e}: ${i};`).join(`
|
|
746
|
+
`):""}function R(){return`
|
|
734
747
|
/* Spacing */
|
|
735
748
|
--loki-space-xs: ${E.xs};
|
|
736
749
|
--loki-space-sm: ${E.sm};
|
|
@@ -741,32 +754,32 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
741
754
|
--loki-space-3xl: ${E["3xl"]};
|
|
742
755
|
|
|
743
756
|
/* Border Radius */
|
|
744
|
-
--loki-radius-none: ${
|
|
745
|
-
--loki-radius-sm: ${
|
|
746
|
-
--loki-radius-md: ${
|
|
747
|
-
--loki-radius-lg: ${
|
|
748
|
-
--loki-radius-xl: ${
|
|
749
|
-
--loki-radius-full: ${
|
|
757
|
+
--loki-radius-none: ${T.none};
|
|
758
|
+
--loki-radius-sm: ${T.sm};
|
|
759
|
+
--loki-radius-md: ${T.md};
|
|
760
|
+
--loki-radius-lg: ${T.lg};
|
|
761
|
+
--loki-radius-xl: ${T.xl};
|
|
762
|
+
--loki-radius-full: ${T.full};
|
|
750
763
|
|
|
751
764
|
/* Typography */
|
|
752
|
-
--loki-font-sans: ${
|
|
753
|
-
--loki-font-serif: ${
|
|
754
|
-
--loki-font-mono: ${
|
|
755
|
-
--loki-text-xs: ${
|
|
756
|
-
--loki-text-sm: ${
|
|
757
|
-
--loki-text-base: ${
|
|
758
|
-
--loki-text-md: ${
|
|
759
|
-
--loki-text-lg: ${
|
|
760
|
-
--loki-text-xl: ${
|
|
761
|
-
--loki-text-2xl: ${
|
|
762
|
-
--loki-text-3xl: ${
|
|
765
|
+
--loki-font-sans: ${k.fontFamily.sans};
|
|
766
|
+
--loki-font-serif: ${k.fontFamily.serif};
|
|
767
|
+
--loki-font-mono: ${k.fontFamily.mono};
|
|
768
|
+
--loki-text-xs: ${k.fontSize.xs};
|
|
769
|
+
--loki-text-sm: ${k.fontSize.sm};
|
|
770
|
+
--loki-text-base: ${k.fontSize.base};
|
|
771
|
+
--loki-text-md: ${k.fontSize.md};
|
|
772
|
+
--loki-text-lg: ${k.fontSize.lg};
|
|
773
|
+
--loki-text-xl: ${k.fontSize.xl};
|
|
774
|
+
--loki-text-2xl: ${k.fontSize["2xl"]};
|
|
775
|
+
--loki-text-3xl: ${k.fontSize["3xl"]};
|
|
763
776
|
|
|
764
777
|
/* Animation */
|
|
765
|
-
--loki-duration-fast: ${
|
|
766
|
-
--loki-duration-normal: ${
|
|
767
|
-
--loki-duration-slow: ${
|
|
768
|
-
--loki-easing-default: ${
|
|
769
|
-
--loki-transition: ${
|
|
778
|
+
--loki-duration-fast: ${S.duration.fast};
|
|
779
|
+
--loki-duration-normal: ${S.duration.normal};
|
|
780
|
+
--loki-duration-slow: ${S.duration.slow};
|
|
781
|
+
--loki-easing-default: ${S.easing.default};
|
|
782
|
+
--loki-transition: ${S.duration.normal} ${S.easing.default};
|
|
770
783
|
|
|
771
784
|
/* Z-Index */
|
|
772
785
|
--loki-z-dropdown: ${A.dropdown};
|
|
@@ -1056,20 +1069,20 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
1056
1069
|
}
|
|
1057
1070
|
|
|
1058
1071
|
/* Responsive utilities */
|
|
1059
|
-
@media (max-width: ${
|
|
1072
|
+
@media (max-width: ${ot.md}) {
|
|
1060
1073
|
.hide-mobile { display: none !important; }
|
|
1061
1074
|
}
|
|
1062
1075
|
|
|
1063
|
-
@media (min-width: ${
|
|
1076
|
+
@media (min-width: ${ot.md}) {
|
|
1064
1077
|
.hide-desktop { display: none !important; }
|
|
1065
1078
|
}
|
|
1066
|
-
`,
|
|
1079
|
+
`,m=class m{static detectContext(){return typeof acquireVsCodeApi<"u"||document.body.classList.contains("vscode-body")||getComputedStyle(document.documentElement).getPropertyValue("--vscode-editor-background")?"vscode":document.documentElement.dataset.lokiContext==="cli"?"cli":"browser"}static detectVSCodeTheme(){let t=document.body;if(t.classList.contains("vscode-high-contrast"))return"high-contrast";if(t.classList.contains("vscode-dark"))return"dark";if(t.classList.contains("vscode-light"))return"light";let e=getComputedStyle(document.documentElement).getPropertyValue("--vscode-editor-background");if(e){let i=e.match(/\d+/g);if(i)return(parseInt(i[0])*299+parseInt(i[1])*587+parseInt(i[2])*114)/1e3>128?"light":"dark"}return null}static getTheme(){if(m.detectContext()==="vscode"){let i=m.detectVSCodeTheme();return i==="high-contrast"?"high-contrast":i==="dark"?"vscode-dark":"vscode-light"}let e=localStorage.getItem(m.STORAGE_KEY);return e&&_[e]?e:window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}static setTheme(t){if(!_[t]){console.warn(`Unknown theme: ${t}`);return}localStorage.setItem(m.STORAGE_KEY,t),document.documentElement.setAttribute("data-loki-theme",t),window.dispatchEvent(new CustomEvent("loki-theme-change",{detail:{theme:t,context:m.detectContext()}}))}static toggle(){let t=m.getTheme(),e;return t.includes("dark")||t==="high-contrast"?e=t.startsWith("vscode")?"vscode-light":"light":e=t.startsWith("vscode")?"vscode-dark":"dark",m.setTheme(e),e}static getVariables(t=null){let e=t||m.getTheme();return _[e]||_.light}static generateCSS(t=null){let e=t||m.getTheme();return`
|
|
1067
1080
|
:host {
|
|
1068
|
-
${
|
|
1069
|
-
${
|
|
1081
|
+
${x(e)}
|
|
1082
|
+
${R()}
|
|
1070
1083
|
}
|
|
1071
1084
|
${B}
|
|
1072
|
-
`}static init(){let t=
|
|
1085
|
+
`}static init(){let t=m.getTheme();document.documentElement.setAttribute("data-loki-theme",t),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",()=>{localStorage.getItem(m.STORAGE_KEY)||m.setTheme(m.getTheme())}),m.detectContext()==="vscode"&&new MutationObserver(()=>{let i=m.getTheme();document.documentElement.setAttribute("data-loki-theme",i),window.dispatchEvent(new CustomEvent("loki-theme-change",{detail:{theme:i,context:"vscode"}}))}).observe(document.body,{attributes:!0,attributeFilter:["class"]})}};w(m,"STORAGE_KEY","loki-theme"),w(m,"CONTEXT_KEY","loki-context");var b=m,P=class{constructor(){this._handlers=new Map,this._enabled=!0}register(t,e){let i=nt[t];if(!i){console.warn(`Unknown keyboard action: ${t}`);return}this._handlers.set(t,{shortcut:i,handler:e})}unregister(t){this._handlers.delete(t)}setEnabled(t){this._enabled=t}handleEvent(t){if(!this._enabled)return!1;for(let[e,{shortcut:i,handler:a}]of this._handlers)if(this._matchesShortcut(t,i))return t.preventDefault(),t.stopPropagation(),a(t),!0;return!1}_matchesShortcut(t,e){let i=t.key.toLowerCase(),a=e.modifiers||[];if(i!==e.key.toLowerCase())return!1;let s=a.includes("Ctrl")||a.includes("Meta"),r=a.includes("Shift"),o=a.includes("Alt"),n=(t.ctrlKey||t.metaKey)===s,l=t.shiftKey===r,h=t.altKey===o;return n&&l&&h}attach(t){this._boundHandler||(this._boundHandler=e=>this.handleEvent(e)),t.addEventListener("keydown",this._boundHandler)}detach(t){this._boundHandler&&t.removeEventListener("keydown",this._boundHandler)}};var dt={light:{"--loki-bg-primary":"#FFFEFB","--loki-bg-secondary":"#F8F4F0","--loki-bg-tertiary":"#ECEAE3","--loki-bg-card":"#ffffff","--loki-bg-hover":"#F3EFE9","--loki-accent":"#553DE9","--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-border":"#ECEAE3","--loki-border-light":"#C5C0B1","--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-transition":"0.2s cubic-bezier(0.4, 0, 0.2, 1)"},dark:{"--loki-bg-primary":"#1A0F2E","--loki-bg-secondary":"#140B24","--loki-bg-tertiary":"#251842","--loki-bg-card":"#1F1338","--loki-bg-hover":"#2A1F4A","--loki-accent":"#7B6BF0","--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-border":"#2A1F3E","--loki-border-light":"#3D3060","--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-transition":"0.2s cubic-bezier(0.4, 0, 0.2, 1)"}},gt=`
|
|
1073
1086
|
:host {
|
|
1074
1087
|
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
|
1075
1088
|
line-height: 1.5;
|
|
@@ -1165,49 +1178,49 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
1165
1178
|
::-webkit-scrollbar-track { background: var(--loki-bg-primary); }
|
|
1166
1179
|
::-webkit-scrollbar-thumb { background: var(--loki-border); border-radius: 3px; }
|
|
1167
1180
|
::-webkit-scrollbar-thumb:hover { background: var(--loki-border-light); }
|
|
1168
|
-
`,I=class I{static getTheme(){return
|
|
1169
|
-
`)}static applyToElement(t,e=null){let i=I.getVariables(e);for(let[a,s]of Object.entries(i))t.style.setProperty(a,s)}static init(){
|
|
1181
|
+
`,I=class I{static getTheme(){return b.getTheme()}static setTheme(t){b.setTheme(t)}static toggle(){return b.toggle()}static getVariables(t=null){let e=t||I.getTheme();return _[e]||dt[e]||dt.light}static toCSSString(t=null){let e=t||I.getTheme();if(_[e])return x(e);let i=I.getVariables(e);return Object.entries(i).map(([a,s])=>`${a}: ${s};`).join(`
|
|
1182
|
+
`)}static applyToElement(t,e=null){let i=I.getVariables(e);for(let[a,s]of Object.entries(i))t.style.setProperty(a,s)}static init(){b.init()}static detectContext(){return b.detectContext()}static getAvailableThemes(){return Object.keys(_)}};w(I,"STORAGE_KEY","loki-theme");var D=I,p=class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}),this._theme=D.getTheme(),this._themeChangeHandler=this._onThemeChange.bind(this),this._keyboardHandler=new P}connectedCallback(){window.addEventListener("loki-theme-change",this._themeChangeHandler),this._applyTheme(),this._setupKeyboardHandling(),this.render()}disconnectedCallback(){window.removeEventListener("loki-theme-change",this._themeChangeHandler),this._keyboardHandler.detach(this)}_onThemeChange(t){this._theme=t.detail.theme,this._applyTheme(),this.onThemeChange&&this.onThemeChange(this._theme)}_applyTheme(){D.applyToElement(this.shadowRoot.host,this._theme),this.setAttribute("data-loki-theme",this._theme)}_setupKeyboardHandling(){this._keyboardHandler.attach(this)}registerShortcut(t,e){this._keyboardHandler.register(t,e)}getBaseStyles(){return`
|
|
1170
1183
|
/* Design tokens */
|
|
1171
1184
|
:host {
|
|
1172
|
-
${
|
|
1185
|
+
${R()}
|
|
1173
1186
|
}
|
|
1174
1187
|
|
|
1175
1188
|
/* Light theme (default) */
|
|
1176
1189
|
:host {
|
|
1177
|
-
${
|
|
1190
|
+
${x("light")}
|
|
1178
1191
|
}
|
|
1179
1192
|
|
|
1180
1193
|
/* Dark theme via system preference */
|
|
1181
1194
|
@media (prefers-color-scheme: dark) {
|
|
1182
1195
|
:host {
|
|
1183
|
-
${
|
|
1196
|
+
${x("dark")}
|
|
1184
1197
|
}
|
|
1185
1198
|
}
|
|
1186
1199
|
|
|
1187
1200
|
/* Explicit theme attributes */
|
|
1188
1201
|
:host([theme="dark"]),
|
|
1189
1202
|
:host([data-loki-theme="dark"]) {
|
|
1190
|
-
${
|
|
1203
|
+
${x("dark")}
|
|
1191
1204
|
}
|
|
1192
1205
|
|
|
1193
1206
|
:host([theme="light"]),
|
|
1194
1207
|
:host([data-loki-theme="light"]) {
|
|
1195
|
-
${
|
|
1208
|
+
${x("light")}
|
|
1196
1209
|
}
|
|
1197
1210
|
|
|
1198
1211
|
:host([theme="high-contrast"]),
|
|
1199
1212
|
:host([data-loki-theme="high-contrast"]) {
|
|
1200
|
-
${
|
|
1213
|
+
${x("high-contrast")}
|
|
1201
1214
|
}
|
|
1202
1215
|
|
|
1203
1216
|
:host([theme="vscode-light"]),
|
|
1204
1217
|
:host([data-loki-theme="vscode-light"]) {
|
|
1205
|
-
${
|
|
1218
|
+
${x("vscode-light")}
|
|
1206
1219
|
}
|
|
1207
1220
|
|
|
1208
1221
|
:host([theme="vscode-dark"]),
|
|
1209
1222
|
:host([data-loki-theme="vscode-dark"]) {
|
|
1210
|
-
${
|
|
1223
|
+
${x("vscode-dark")}
|
|
1211
1224
|
}
|
|
1212
1225
|
|
|
1213
1226
|
/* Reduced motion preference */
|
|
@@ -1222,7 +1235,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
1222
1235
|
}
|
|
1223
1236
|
|
|
1224
1237
|
${B}
|
|
1225
|
-
`}getAriaPattern(t){return nt[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 L={realtime:1e3,normal:2e3,background:5e3,offline:1e4},gt={vscode:L.normal,browser:L.realtime,cli:L.background},ht={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},l={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"},C=class C extends EventTarget{static getInstance(t={}){let e=t.baseUrl||ht.baseUrl;return C._instances.has(e)||C._instances.set(e,new C(t)),C._instances.get(e)}static clearInstances(){C._instances.forEach(t=>t.disconnect()),C._instances.clear()}constructor(t={}){super(),this.config={...ht,...t},this._ws=null,this._connected=!1,this._pollInterval=null,this._reconnectTimeout=null,this._cache=new Map,this._cacheTimeout=5e3,this._vscodeApi=null,this._context=this._detectContext(),this._currentPollInterval=gt[this._context]||L.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 L}_setupAdaptivePolling(){typeof document>"u"||(this._visibilityChangeHandler=()=>{document.hidden?this._setPollInterval(L.background):this._setPollInterval(gt[this._context]||L.normal)},document.addEventListener("visibilitychange",this._visibilityChangeHandler))}_setPollInterval(t){this._currentPollInterval=t,this._pollInterval&&(this.stopPolling(),this.startPolling(null,t))}setPollMode(t){let e=L[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(l.STATUS_UPDATE,e.data);break;case"updateTasks":this._emit(l.TASK_UPDATED,e.data);break;case"taskCreated":this._emit(l.TASK_CREATED,e.data);break;case"taskDeleted":this._emit(l.TASK_DELETED,e.data);break;case"projectCreated":this._emit(l.PROJECT_CREATED,e.data);break;case"projectUpdated":this._emit(l.PROJECT_UPDATED,e.data);break;case"agentUpdate":this._emit(l.AGENT_UPDATE,e.data);break;case"logMessage":this._emit(l.LOG_MESSAGE,e.data);break;case"memoryUpdate":this._emit(l.MEMORY_UPDATE,e.data);break;case"connected":this._connected=!0,this._emit(l.CONNECTED,e.data);break;case"disconnected":this._connected=!1,this._emit(l.DISCONNECTED,e.data);break;case"error":this._emit(l.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._emit(l.CONNECTED),t()},this._ws.onclose=()=>{this._connected=!1,this._emit(l.DISCONNECTED),this._scheduleReconnect()},this._ws.onerror=i=>{this._emit(l.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(){this._reconnectTimeout||(this._reconnectTimeout=setTimeout(()=>{this._reconnectTimeout=null,this.connect().catch(()=>{})},this.config.retryDelay))}_handleMessage(t){let i={connected:l.CONNECTED,status_update:l.STATUS_UPDATE,task_created:l.TASK_CREATED,task_updated:l.TASK_UPDATED,task_deleted:l.TASK_DELETED,task_moved:l.TASK_UPDATED,project_created:l.PROJECT_CREATED,project_updated:l.PROJECT_UPDATED,agent_update:l.AGENT_UPDATE,log:l.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,headers:{"Content-Type":"application/json",...e.headers}});if(clearTimeout(s),!r.ok){let o=await r.json().catch(()=>({detail:r.statusText}));throw new Error(o.detail||`HTTP ${r.status}`)}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 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 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`);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(l.STATUS_UPDATE,s),this._vscodeApi&&this.postToVSCode("pollSuccess",{timestamp:Date.now()})}catch(s){this._connected=!1,this._emit(l.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)}};w(C,"_instances",new Map);var R=C;function vt(c={}){return new R(c)}function u(c={}){return R.getInstance(c)}var ct="loki-state-change",dt={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}},$=class $ extends EventTarget{static getInstance(){return $._instance||($._instance=new $),$._instance}constructor(){super(),this._state=this._loadState(),this._subscribers=new Map,this._batchUpdates=[],this._batchTimeout=null}_loadState(){try{let t=localStorage.getItem($.STORAGE_KEY);if(t){let e=JSON.parse(t);return this._mergeState(dt,e)}}catch(t){console.warn("Failed to load state from localStorage:",t)}return{...dt}}_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($.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(ct,{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(d){console.error("State subscriber error:",d)}}}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=dt;for(let a of e)i=i?.[a];this.set(t,i)}else this._state={...dt},this._saveState(),this.dispatchEvent(new CustomEvent(ct,{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)}};w($,"STORAGE_KEY","loki-dashboard-state"),w($,"_instance",null);var F=$;function z(){return F.getInstance()}function mt(c){let t=z();return{get:()=>t.get(c),set:e=>t.set(c,e),subscribe:e=>t.subscribe(c,e)}}var j=class extends p{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()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(l.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(l.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(l.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=u({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(l.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(l.CONNECTED,this._connectedHandler),this._api.addEventListener(l.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){try{let[t,e,i,a,s]=await Promise.allSettled([this._api.getStatus(),this._api.getChecklistSummary(),this._api.getAppRunnerStatus(),this._api.getPlaywrightResults(),this._api.getCouncilGate()]);t.status==="fulfilled"?this._updateFromStatus(t.value):(this._data.connected=!1,this._data.status="offline"),e.status==="fulfilled"&&(this._checklistSummary=e.value?.summary||null),i.status==="fulfilled"&&(this._appRunnerStatus=i.value),a.status==="fulfilled"&&(this._playwrightResults=a.value),s.status==="fulfilled"&&(this._gateStatus=s.value),this.render()}catch{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`
|
|
1238
|
+
`}getAriaPattern(t){return lt[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 L={realtime:1e3,normal:2e3,background:5e3,offline:1e4},ht={vscode:L.normal,browser:L.realtime,cli:L.background},vt={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},d={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"},C=class C extends EventTarget{static getInstance(t={}){let e=t.baseUrl||vt.baseUrl;return C._instances.has(e)||C._instances.set(e,new C(t)),C._instances.get(e)}static clearInstances(){C._instances.forEach(t=>t.disconnect()),C._instances.clear()}constructor(t={}){super(),this.config={...vt,...t},this._ws=null,this._connected=!1,this._pollInterval=null,this._reconnectTimeout=null,this._cache=new Map,this._cacheTimeout=5e3,this._vscodeApi=null,this._context=this._detectContext(),this._currentPollInterval=ht[this._context]||L.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 L}_setupAdaptivePolling(){typeof document>"u"||(this._visibilityChangeHandler=()=>{document.hidden?this._setPollInterval(L.background):this._setPollInterval(ht[this._context]||L.normal)},document.addEventListener("visibilitychange",this._visibilityChangeHandler))}_setPollInterval(t){this._currentPollInterval=t,this._pollInterval&&(this.stopPolling(),this.startPolling(null,t))}setPollMode(t){let e=L[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(d.STATUS_UPDATE,e.data);break;case"updateTasks":this._emit(d.TASK_UPDATED,e.data);break;case"taskCreated":this._emit(d.TASK_CREATED,e.data);break;case"taskDeleted":this._emit(d.TASK_DELETED,e.data);break;case"projectCreated":this._emit(d.PROJECT_CREATED,e.data);break;case"projectUpdated":this._emit(d.PROJECT_UPDATED,e.data);break;case"agentUpdate":this._emit(d.AGENT_UPDATE,e.data);break;case"logMessage":this._emit(d.LOG_MESSAGE,e.data);break;case"memoryUpdate":this._emit(d.MEMORY_UPDATE,e.data);break;case"connected":this._connected=!0,this._emit(d.CONNECTED,e.data);break;case"disconnected":this._connected=!1,this._emit(d.DISCONNECTED,e.data);break;case"error":this._emit(d.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._emit(d.CONNECTED),t()},this._ws.onclose=()=>{this._connected=!1,this._emit(d.DISCONNECTED),this._scheduleReconnect()},this._ws.onerror=i=>{this._emit(d.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(){this._reconnectTimeout||(this._reconnectTimeout=setTimeout(()=>{this._reconnectTimeout=null,this.connect().catch(()=>{})},this.config.retryDelay))}_handleMessage(t){let i={connected:d.CONNECTED,status_update:d.STATUS_UPDATE,task_created:d.TASK_CREATED,task_updated:d.TASK_UPDATED,task_deleted:d.TASK_DELETED,task_moved:d.TASK_UPDATED,project_created:d.PROJECT_CREATED,project_updated:d.PROJECT_UPDATED,agent_update:d.AGENT_UPDATE,log:d.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,headers:{"Content-Type":"application/json",...e.headers}});if(clearTimeout(s),!r.ok){let o=await r.json().catch(()=>({detail:r.statusText}));throw new Error(o.detail||`HTTP ${r.status}`)}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 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 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`);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(d.STATUS_UPDATE,s),this._vscodeApi&&this.postToVSCode("pollSuccess",{timestamp:Date.now()})}catch(s){this._connected=!1,this._emit(d.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)}};w(C,"_instances",new Map);var M=C;function mt(c={}){return new M(c)}function g(c={}){return M.getInstance(c)}var pt="loki-state-change",ct={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}},$=class $ extends EventTarget{static getInstance(){return $._instance||($._instance=new $),$._instance}constructor(){super(),this._state=this._loadState(),this._subscribers=new Map,this._batchUpdates=[],this._batchTimeout=null}_loadState(){try{let t=localStorage.getItem($.STORAGE_KEY);if(t){let e=JSON.parse(t);return this._mergeState(ct,e)}}catch(t){console.warn("Failed to load state from localStorage:",t)}return{...ct}}_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($.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(pt,{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=ct;for(let a of e)i=i?.[a];this.set(t,i)}else this._state={...ct},this._saveState(),this.dispatchEvent(new CustomEvent(pt,{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)}};w($,"STORAGE_KEY","loki-dashboard-state"),w($,"_instance",null);var F=$;function z(){return F.getInstance()}function bt(c){let t=z();return{get:()=>t.get(c),set:e=>t.set(c,e),subscribe:e=>t.subscribe(c,e)}}var j=class extends p{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()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(d.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(d.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(d.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(d.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(d.CONNECTED,this._connectedHandler),this._api.addEventListener(d.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){try{let[t,e,i,a,s]=await Promise.allSettled([this._api.getStatus(),this._api.getChecklistSummary(),this._api.getAppRunnerStatus(),this._api.getPlaywrightResults(),this._api.getCouncilGate()]);t.status==="fulfilled"?this._updateFromStatus(t.value):(this._data.connected=!1,this._data.status="offline"),e.status==="fulfilled"&&(this._checklistSummary=e.value?.summary||null),i.status==="fulfilled"&&(this._appRunnerStatus=i.value),a.status==="fulfilled"&&(this._playwrightResults=a.value),s.status==="fulfilled"&&(this._gateStatus=s.value),this.render()}catch{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`
|
|
1226
1239
|
<div class="overview-card">
|
|
1227
1240
|
<div class="card-label">App Runner</div>
|
|
1228
1241
|
<div class="card-value small-text">--</div>
|
|
@@ -1289,7 +1302,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
1289
1302
|
PASSED
|
|
1290
1303
|
</div>
|
|
1291
1304
|
</div>
|
|
1292
|
-
`}render(){let t=this._getStatusDotClass(),e=this._escapeHtml((this._data.status||"OFFLINE").toUpperCase()),i=this._escapeHtml(this._data.phase||"--"),a=this._escapeHtml(this._data.iteration!=null?String(this._data.iteration):"0"),s=this._escapeHtml((this._data.provider||"CLAUDE").toUpperCase()),r=this._escapeHtml(String(this._data.running_agents||0)),o=this._escapeHtml(this._data.pending_tasks!=null?`${this._data.pending_tasks} pending`:"--"),n=this._escapeHtml(this._formatUptime(this._data.uptime_seconds)),
|
|
1305
|
+
`}render(){let t=this._getStatusDotClass(),e=this._escapeHtml((this._data.status||"OFFLINE").toUpperCase()),i=this._escapeHtml(this._data.phase||"--"),a=this._escapeHtml(this._data.iteration!=null?String(this._data.iteration):"0"),s=this._escapeHtml((this._data.provider||"CLAUDE").toUpperCase()),r=this._escapeHtml(String(this._data.running_agents||0)),o=this._escapeHtml(this._data.pending_tasks!=null?`${this._data.pending_tasks} pending`:"--"),n=this._escapeHtml(this._formatUptime(this._data.uptime_seconds)),l=this._escapeHtml((this._data.complexity||"STANDARD").toUpperCase());this.shadowRoot.innerHTML=`
|
|
1293
1306
|
<style>
|
|
1294
1307
|
${this.getBaseStyles()}
|
|
1295
1308
|
|
|
@@ -1461,11 +1474,11 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
1461
1474
|
|
|
1462
1475
|
<div class="overview-card">
|
|
1463
1476
|
<div class="card-label">Complexity</div>
|
|
1464
|
-
<div class="card-value small-text">${
|
|
1477
|
+
<div class="card-value small-text">${l}</div>
|
|
1465
1478
|
</div>
|
|
1466
1479
|
</div>
|
|
1467
1480
|
</div>
|
|
1468
|
-
`}};customElements.get("loki-overview")||customElements.define("loki-overview",j);var
|
|
1481
|
+
`}};customElements.get("loki-overview")||customElements.define("loki-overview",j);var It=[{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)"}];var U=class extends p{static get observedAttributes(){return["api-url","project-id","theme","readonly"]}constructor(){super(),this._tasks=[],this._loading=!0,this._error=null,this._draggedTask=null,this._api=null,this._state=z()}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadTasks()}disconnectedCallback(){super.disconnectedCallback(),this._api&&(this._api.removeEventListener(d.TASK_CREATED,this._onTaskEvent),this._api.removeEventListener(d.TASK_UPDATED,this._onTaskEvent),this._api.removeEventListener(d.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(d.TASK_CREATED,this._onTaskEvent),this._api.removeEventListener(d.TASK_UPDATED,this._onTaskEvent),this._api.removeEventListener(d.TASK_DELETED,this._onTaskEvent)),this._onTaskEvent=()=>this._loadTasks(),this._api.addEventListener(d.TASK_CREATED,this._onTaskEvent),this._api.addEventListener(d.TASK_UPDATED,this._onTaskEvent),this._api.addEventListener(d.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._tasks.filter(e=>e.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)}}}_openAddTaskModal(t="pending"){this.dispatchEvent(new CustomEvent("add-task",{detail:{status:t}}))}_openTaskDetail(t){this.dispatchEvent(new CustomEvent("task-click",{detail:{task:t}}))}render(){let t=`
|
|
1469
1482
|
<style>
|
|
1470
1483
|
${this.getBaseStyles()}
|
|
1471
1484
|
|
|
@@ -1704,7 +1717,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
1704
1717
|
</style>
|
|
1705
1718
|
`,e=a=>{switch(a){case"pending":return'<circle cx="12" cy="12" r="10"/>';case"in_progress":return'<path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/>';case"review":return'<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/>';case"done":return'<path d="M22 11.08V12a10 10 0 11-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/>';default:return'<circle cx="12" cy="12" r="10"/>'}},i;if(this._loading)i='<div class="loading">Loading tasks...</div>';else if(this._error&&this._tasks.length===0)i=`<div class="error">Error: ${this._error}</div>`;else{let a=this.hasAttribute("readonly");i=`
|
|
1706
1719
|
<div class="kanban-board">
|
|
1707
|
-
${
|
|
1720
|
+
${It.map(s=>{let r=this._getTasksByStatus(s.status);return`
|
|
1708
1721
|
<div class="kanban-column" data-status="${s.status}">
|
|
1709
1722
|
<div class="kanban-column-header">
|
|
1710
1723
|
<span class="kanban-column-title">
|
|
@@ -1760,7 +1773,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
1760
1773
|
</div>
|
|
1761
1774
|
${i}
|
|
1762
1775
|
</div>
|
|
1763
|
-
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("refresh-btn");t&&t.addEventListener("click",()=>this._loadTasks()),this.shadowRoot.querySelectorAll(".add-task-btn").forEach(e=>{e.addEventListener("click",()=>{this._openAddTaskModal(e.dataset.status)})}),this.shadowRoot.querySelectorAll(".task-card").forEach(e=>{let i=e.dataset.taskId,a=this._tasks.find(s=>s.id.toString()===i);a&&(e.addEventListener("click",()=>this._openTaskDetail(a)),e.addEventListener("keydown",s=>{s.key==="Enter"||s.key===" "?(s.preventDefault(),this._openTaskDetail(a)):(s.key==="ArrowDown"||s.key==="ArrowUp")&&(s.preventDefault(),this._navigateTaskCards(e,s.key==="ArrowDown"?"next":"prev"))}),e.classList.contains("draggable")&&(e.addEventListener("dragstart",s=>this._handleDragStart(s,a)),e.addEventListener("dragend",s=>this._handleDragEnd(s))))}),this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(e=>{e.addEventListener("dragover",i=>this._handleDragOver(i)),e.addEventListener("dragenter",i=>this._handleDragEnter(i)),e.addEventListener("dragleave",i=>this._handleDragLeave(i)),e.addEventListener("drop",i=>this._handleDrop(i,e.dataset.status))})}_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",U);var O=class extends p{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=z(),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(
|
|
1776
|
+
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("refresh-btn");t&&t.addEventListener("click",()=>this._loadTasks()),this.shadowRoot.querySelectorAll(".add-task-btn").forEach(e=>{e.addEventListener("click",()=>{this._openAddTaskModal(e.dataset.status)})}),this.shadowRoot.querySelectorAll(".task-card").forEach(e=>{let i=e.dataset.taskId,a=this._tasks.find(s=>s.id.toString()===i);a&&(e.addEventListener("click",()=>this._openTaskDetail(a)),e.addEventListener("keydown",s=>{s.key==="Enter"||s.key===" "?(s.preventDefault(),this._openTaskDetail(a)):(s.key==="ArrowDown"||s.key==="ArrowUp")&&(s.preventDefault(),this._navigateTaskCards(e,s.key==="ArrowDown"?"next":"prev"))}),e.classList.contains("draggable")&&(e.addEventListener("dragstart",s=>this._handleDragStart(s,a)),e.addEventListener("dragend",s=>this._handleDragEnd(s))))}),this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(e=>{e.addEventListener("dragover",i=>this._handleDragOver(i)),e.addEventListener("dragenter",i=>this._handleDragEnter(i)),e.addEventListener("dragleave",i=>this._handleDragLeave(i)),e.addEventListener("drop",i=>this._handleDrop(i,e.dataset.status))})}_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",U);var O=class extends p{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=z(),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(d.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(d.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(d.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(d.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(d.CONNECTED,this._connectedHandler),this._api.addEventListener(d.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`}_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{await this._api.pauseSession(),this._status.mode="paused",this.render()}catch(t){console.error("Failed to pause session:",t)}this.dispatchEvent(new CustomEvent("session-pause",{detail:this._status}))}async _triggerResume(){try{await this._api.resumeSession(),this._status.mode="running",this.render()}catch(t){console.error("Failed to resume session:",t)}this.dispatchEvent(new CustomEvent("session-resume",{detail:this._status}))}async _triggerStop(){try{await this._api.stopSession(),this._status.mode="stopped",this.render()}catch(t){console.error("Failed to stop session:",t)}this.dispatchEvent(new CustomEvent("session-stop",{detail:this._status}))}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=`
|
|
1764
1777
|
<style>
|
|
1765
1778
|
${this.getBaseStyles()}
|
|
1766
1779
|
|
|
@@ -2039,9 +2052,9 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
2039
2052
|
`;this.shadowRoot.innerHTML=`
|
|
2040
2053
|
${r}
|
|
2041
2054
|
${t?o:n}
|
|
2042
|
-
`,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",O);var
|
|
2055
|
+
`,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",O);var ft={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"}},N=class extends p{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(d.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(d.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()}`);if(!a.ok)return;let r=(await a.text()).split(`
|
|
2043
2056
|
`);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(`
|
|
2044
|
-
`),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=
|
|
2057
|
+
`),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=ft[i.level]||ft.info;return`
|
|
2045
2058
|
<div class="log-line">
|
|
2046
2059
|
<span class="timestamp">${this._escapeHtml(i.timestamp)}</span>
|
|
2047
2060
|
<span class="level" style="color: ${a.color}">[${this._escapeHtml(a.label)}]</span>
|
|
@@ -2240,7 +2253,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
2240
2253
|
${this._logs.length} lines (${this._getFilteredLogs().length} shown)
|
|
2241
2254
|
</div>
|
|
2242
2255
|
</div>
|
|
2243
|
-
`,this._attachEventListeners(),this._renderLogs()}_attachEventListeners(){let t=this.shadowRoot.getElementById("filter-input"),e=this.shadowRoot.getElementById("level-select"),i=this.shadowRoot.getElementById("auto-scroll-btn"),a=this.shadowRoot.getElementById("clear-btn"),s=this.shadowRoot.getElementById("download-btn");t&&(t.value=this._filter,t.addEventListener("input",r=>this._setFilter(r.target.value))),e&&(e.value=this._levelFilter,e.addEventListener("change",r=>this._setLevelFilter(r.target.value))),i&&i.addEventListener("click",()=>this._toggleAutoScroll()),a&&a.addEventListener("click",()=>this._clearLogs()),s&&s.addEventListener("click",()=>this._downloadLogs())}addLog(t,e="info"){this._addLog({message:t,level:e,timestamp:new Date().toLocaleTimeString()})}clear(){this._clearLogs()}};customElements.get("loki-log-stream")||customElements.define("loki-log-stream",N);var
|
|
2256
|
+
`,this._attachEventListeners(),this._renderLogs()}_attachEventListeners(){let t=this.shadowRoot.getElementById("filter-input"),e=this.shadowRoot.getElementById("level-select"),i=this.shadowRoot.getElementById("auto-scroll-btn"),a=this.shadowRoot.getElementById("clear-btn"),s=this.shadowRoot.getElementById("download-btn");t&&(t.value=this._filter,t.addEventListener("input",r=>this._setFilter(r.target.value))),e&&(e.value=this._levelFilter,e.addEventListener("change",r=>this._setLevelFilter(r.target.value))),i&&i.addEventListener("click",()=>this._toggleAutoScroll()),a&&a.addEventListener("click",()=>this._clearLogs()),s&&s.addEventListener("click",()=>this._downloadLogs())}addLog(t,e="info"){this._addLog({message:t,level:e,timestamp:new Date().toLocaleTimeString()})}clear(){this._clearLogs()}};customElements.get("loki-log-stream")||customElements.define("loki-log-stream",N);var Dt=[{id:"summary",label:"Summary",icon:"M4 6h16M4 12h16M4 18h16"},{id:"episodes",label:"Episodes",icon:"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"},{id:"patterns",label:"Patterns",icon:"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"},{id:"skills",label:"Skills",icon:"M13 10V3L4 14h7v7l9-11h-7z"}],q=class extends p{static get observedAttributes(){return["api-url","theme","tab"]}constructor(){super(),this._activeTab="summary",this._loading=!1,this._error=null,this._api=null,this._summary=null,this._episodes=[],this._patterns=[],this._skills=[],this._tokenEconomics=null,this._selectedItem=null,this._lastFocusedElement=null}connectedCallback(){super.connectedCallback(),this._activeTab=this.getAttribute("tab")||"summary",this._setupApi(),this._loadData()}attributeChangedCallback(t,e,i){if(e!==i)switch(t){case"api-url":this._api&&(this._api.baseUrl=i,this._loadData());break;case"theme":this._applyTheme();break;case"tab":this._setTab(i);break}}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _loadData(){this._loading=!0,this._error=null,this.render();try{this._summary=await this._api.getMemorySummary().catch(()=>null),this._tokenEconomics=await this._api.getTokenEconomics().catch(()=>null),await this._loadTabData()}catch(t){this._error=t.message||"Failed to load memory data"}this._loading=!1,this.render()}async _loadTabData(){switch(this._activeTab){case"episodes":this._episodes=await this._api.listEpisodes({limit:50}).catch(()=>[]);break;case"patterns":this._patterns=await this._api.listPatterns().catch(()=>[]);break;case"skills":this._skills=await this._api.listSkills().catch(()=>[]);break}}_setTab(t){this._activeTab!==t&&(this._activeTab=t,this._selectedItem=null,this._loadTabData().then(()=>this.render()))}async _selectEpisode(t){try{this._lastFocusedElement=this.shadowRoot.activeElement,this._selectedItem=await this._api.getEpisode(t),this.dispatchEvent(new CustomEvent("episode-select",{detail:this._selectedItem})),this.render(),this._focusDetailPanel()}catch(e){console.error("Failed to load episode:",e)}}async _selectPattern(t){try{this._lastFocusedElement=this.shadowRoot.activeElement,this._selectedItem=await this._api.getPattern(t),this.dispatchEvent(new CustomEvent("pattern-select",{detail:this._selectedItem})),this.render(),this._focusDetailPanel()}catch(e){console.error("Failed to load pattern:",e)}}async _selectSkill(t){try{this._lastFocusedElement=this.shadowRoot.activeElement,this._selectedItem=await this._api.getSkill(t),this.dispatchEvent(new CustomEvent("skill-select",{detail:this._selectedItem})),this.render(),this._focusDetailPanel()}catch(e){console.error("Failed to load skill:",e)}}_focusDetailPanel(){requestAnimationFrame(()=>{let t=this.shadowRoot.getElementById("close-detail");t&&t.focus()})}_closeDetail(){this._selectedItem=null,this.render(),this._lastFocusedElement&&requestAnimationFrame(()=>{this._lastFocusedElement.focus(),this._lastFocusedElement=null})}async _triggerConsolidation(){try{let t=await this._api.consolidateMemory(24);alert(`Consolidation complete:
|
|
2244
2257
|
- Patterns created: ${t.patternsCreated}
|
|
2245
2258
|
- Patterns merged: ${t.patternsMerged}
|
|
2246
2259
|
- Episodes processed: ${t.episodesProcessed}`),this._loadData()}catch(t){alert("Consolidation failed: "+t.message)}}_renderSummary(){if(!this._summary)return'<div class="empty-state">No memory data available</div>';let{episodic:t,semantic:e,procedural:i,tokenEconomics:a}=this._summary;return`
|
|
@@ -2918,7 +2931,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
2918
2931
|
<span class="browser-title">Memory System</span>
|
|
2919
2932
|
</div>
|
|
2920
2933
|
<div class="tabs" role="tablist" aria-label="Memory browser sections">
|
|
2921
|
-
${
|
|
2934
|
+
${Dt.map((i,a)=>`
|
|
2922
2935
|
<button class="tab ${this._activeTab===i.id?"active":""}"
|
|
2923
2936
|
data-tab="${i.id}"
|
|
2924
2937
|
role="tab"
|
|
@@ -2935,12 +2948,12 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
2935
2948
|
${e}
|
|
2936
2949
|
</div>
|
|
2937
2950
|
</div>
|
|
2938
|
-
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.querySelectorAll(".tab");t.forEach((s,r)=>{s.addEventListener("click",()=>this._setTab(s.dataset.tab)),s.addEventListener("keydown",o=>{if(o.key==="ArrowRight"||o.key==="ArrowLeft"){o.preventDefault();let n=Array.from(t),
|
|
2951
|
+
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.querySelectorAll(".tab");t.forEach((s,r)=>{s.addEventListener("click",()=>this._setTab(s.dataset.tab)),s.addEventListener("keydown",o=>{if(o.key==="ArrowRight"||o.key==="ArrowLeft"){o.preventDefault();let n=Array.from(t),l=o.key==="ArrowRight"?(r+1)%n.length:(r-1+n.length)%n.length;n[l].focus(),this._setTab(n[l].dataset.tab)}})}),this.shadowRoot.querySelectorAll(".item-card").forEach(s=>{s.addEventListener("click",()=>this._handleItemClick(s)),s.addEventListener("keydown",r=>{r.key==="Enter"||r.key===" "?(r.preventDefault(),this._handleItemClick(s)):(r.key==="ArrowDown"||r.key==="ArrowUp")&&(r.preventDefault(),this._navigateItemCards(s,r.key==="ArrowDown"?"next":"prev"))})});let e=this.shadowRoot.getElementById("close-detail");e&&e.addEventListener("click",()=>this._closeDetail());let i=this.shadowRoot.getElementById("consolidate-btn");i&&i.addEventListener("click",()=>this._triggerConsolidation());let a=this.shadowRoot.getElementById("refresh-btn");a&&a.addEventListener("click",()=>this._loadData())}_handleItemClick(t){let e=t.dataset.id;switch(t.dataset.type){case"episode":this._selectEpisode(e);break;case"pattern":this._selectPattern(e);break;case"skill":this._selectSkill(e);break}}_navigateItemCards(t,e){let i=Array.from(this.shadowRoot.querySelectorAll(".item-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-memory-browser")||customElements.define("loki-memory-browser",q);var zt=[{id:"1h",label:"1 Hour",hours:1},{id:"24h",label:"24 Hours",hours:24},{id:"7d",label:"7 Days",hours:168},{id:"30d",label:"30 Days",hours:720}],Pt=[{id:"all",label:"All Signals"},{id:"user_preference",label:"User Preferences"},{id:"error_pattern",label:"Error Patterns"},{id:"success_pattern",label:"Success Patterns"},{id:"tool_efficiency",label:"Tool Efficiency"},{id:"context_relevance",label:"Context Relevance"}],Mt=[{id:"all",label:"All Sources"},{id:"cli",label:"CLI"},{id:"api",label:"API"},{id:"vscode",label:"VS Code"},{id:"mcp",label:"MCP"},{id:"dashboard",label:"Dashboard"}],J=class extends p{static get observedAttributes(){return["api-url","theme","time-range","signal-type","source"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._timeRange="7d",this._signalType="all",this._source="all",this._metrics=null,this._trends=null,this._signals=[],this._selectedMetric=null}connectedCallback(){super.connectedCallback(),this._timeRange=this.getAttribute("time-range")||"7d",this._signalType=this.getAttribute("signal-type")||"all",this._source=this.getAttribute("source")||"all",this._setupApi(),this._loadData()}attributeChangedCallback(t,e,i){if(e!==i)switch(t){case"api-url":this._api&&(this._api.baseUrl=i,this._loadData());break;case"theme":this._applyTheme();break;case"time-range":this._timeRange=i,this._loadData();break;case"signal-type":this._signalType=i,this._loadData();break;case"source":this._source=i,this._loadData();break}}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _loadData(){this._loading=!0,this._error=null,this.render();try{let t={timeRange:this._timeRange,signalType:this._signalType!=="all"?this._signalType:void 0,source:this._source!=="all"?this._source:void 0},[e,i,a]=await Promise.all([this._api.getLearningMetrics(t).catch(()=>null),this._api.getLearningTrends(t).catch(()=>null),this._api.getLearningSignals({...t,limit:50}).catch(()=>[])]);this._metrics=e,this._trends=i,this._signals=a||[]}catch(t){this._error=t.message||"Failed to load learning data"}this._loading=!1,this.render()}_setFilter(t,e){switch(t){case"timeRange":this._timeRange=e,this.setAttribute("time-range",e);break;case"signalType":this._signalType=e,this.setAttribute("signal-type",e);break;case"source":this._source=e,this.setAttribute("source",e);break}this.dispatchEvent(new CustomEvent("filter-change",{detail:{timeRange:this._timeRange,signalType:this._signalType,source:this._source}})),this._loadData()}_selectMetric(t,e){this._selectedMetric={type:t,item:e},this.dispatchEvent(new CustomEvent("metric-select",{detail:{type:t,item:e}})),this.render()}_closeDetail(){this._selectedMetric=null,this.render()}_formatNumber(t){return t>=1e6?(t/1e6).toFixed(1)+"M":t>=1e3?(t/1e3).toFixed(1)+"K":t?.toString()||"0"}_formatPercent(t){return(t*100).toFixed(1)+"%"}_formatDuration(t){return t<60?t.toFixed(0)+"s":t<3600?(t/60).toFixed(1)+"m":(t/3600).toFixed(1)+"h"}_escapeHtml(t){if(!t)return"";let e=document.createElement("div");return e.textContent=t,e.innerHTML}_renderFilters(){return`
|
|
2939
2952
|
<div class="filters">
|
|
2940
2953
|
<div class="filter-group">
|
|
2941
2954
|
<label>Time Range</label>
|
|
2942
2955
|
<select id="time-range-select" class="filter-select">
|
|
2943
|
-
${
|
|
2956
|
+
${zt.map(t=>`
|
|
2944
2957
|
<option value="${t.id}" ${this._timeRange===t.id?"selected":""}>${t.label}</option>
|
|
2945
2958
|
`).join("")}
|
|
2946
2959
|
</select>
|
|
@@ -2948,7 +2961,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
2948
2961
|
<div class="filter-group">
|
|
2949
2962
|
<label>Signal Type</label>
|
|
2950
2963
|
<select id="signal-type-select" class="filter-select">
|
|
2951
|
-
${
|
|
2964
|
+
${Pt.map(t=>`
|
|
2952
2965
|
<option value="${t.id}" ${this._signalType===t.id?"selected":""}>${t.label}</option>
|
|
2953
2966
|
`).join("")}
|
|
2954
2967
|
</select>
|
|
@@ -2956,7 +2969,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
2956
2969
|
<div class="filter-group">
|
|
2957
2970
|
<label>Source</label>
|
|
2958
2971
|
<select id="source-select" class="filter-select">
|
|
2959
|
-
${
|
|
2972
|
+
${Mt.map(t=>`
|
|
2960
2973
|
<option value="${t.id}" ${this._source===t.id?"selected":""}>${t.label}</option>
|
|
2961
2974
|
`).join("")}
|
|
2962
2975
|
</select>
|
|
@@ -3038,7 +3051,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
3038
3051
|
</div>
|
|
3039
3052
|
</div>
|
|
3040
3053
|
</div>
|
|
3041
|
-
`}_renderTrendChart(){if(!this._trends||!this._trends.dataPoints||this._trends.dataPoints.length===0)return'<div class="chart-empty">No trend data available</div>';let{dataPoints:t,maxValue:e}=this._trends,i=120,a=400,s=20,r=t.map((n,
|
|
3054
|
+
`}_renderTrendChart(){if(!this._trends||!this._trends.dataPoints||this._trends.dataPoints.length===0)return'<div class="chart-empty">No trend data available</div>';let{dataPoints:t,maxValue:e}=this._trends,i=120,a=400,s=20,r=t.map((n,l)=>{let h=s+l/(t.length-1||1)*(a-s*2),u=i-s-n.count/(e||1)*(i-s*2);return`${h},${u}`}).join(" "),o=`${s},${i-s} ${r} ${a-s},${i-s}`;return`
|
|
3042
3055
|
<div class="trend-chart">
|
|
3043
3056
|
<div class="chart-header">
|
|
3044
3057
|
<span class="chart-title">Signal Volume Over Time</span>
|
|
@@ -3056,7 +3069,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
3056
3069
|
<polyline points="${r}" fill="none" stroke="var(--loki-accent)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
3057
3070
|
|
|
3058
3071
|
<!-- Data points -->
|
|
3059
|
-
${t.map((n,
|
|
3072
|
+
${t.map((n,l)=>{let h=s+l/(t.length-1||1)*(a-s*2),u=i-s-n.count/(e||1)*(i-s*2);return`<circle cx="${h}" cy="${u}" r="3" fill="var(--loki-accent)" />`}).join("")}
|
|
3060
3073
|
</svg>
|
|
3061
3074
|
<div class="chart-labels">
|
|
3062
3075
|
${t.length>0?`
|
|
@@ -3947,7 +3960,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
3947
3960
|
${e}
|
|
3948
3961
|
</div>
|
|
3949
3962
|
</div>
|
|
3950
|
-
`,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,
|
|
3963
|
+
`,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",J);var Ht=[{id:"overview",label:"Overview"},{id:"decisions",label:"Decision Log"},{id:"convergence",label:"Convergence"},{id:"agents",label:"Agents"}],G=class extends p{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=`
|
|
3951
3964
|
<style>${this.getBaseStyles()}${this._getStyles()}</style>
|
|
3952
3965
|
<div class="council-dashboard">
|
|
3953
3966
|
<div class="council-header">
|
|
@@ -3961,7 +3974,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
3961
3974
|
</div>
|
|
3962
3975
|
|
|
3963
3976
|
<div class="tabs">
|
|
3964
|
-
${
|
|
3977
|
+
${Ht.map(e=>`
|
|
3965
3978
|
<button
|
|
3966
3979
|
class="tab ${this._activeTab===e.id?"active":""}"
|
|
3967
3980
|
data-tab="${e.id}"
|
|
@@ -4115,7 +4128,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
4115
4128
|
</div>
|
|
4116
4129
|
`).join("")}
|
|
4117
4130
|
</div>
|
|
4118
|
-
`;return this._pendingRaf=requestAnimationFrame(()=>{this._pendingRaf=null;let e=this.shadowRoot;e&&e.querySelectorAll(".agent-card[data-agent-index]").forEach(i=>{let a=parseInt(i.dataset.agentIndex,10),s=this._agents[a];s&&(i.addEventListener("click",()=>this._selectAgent(s)),i.querySelectorAll("[data-action]").forEach(r=>{r.addEventListener("click",o=>{o.stopPropagation();let n=r.dataset.action,
|
|
4131
|
+
`;return this._pendingRaf=requestAnimationFrame(()=>{this._pendingRaf=null;let e=this.shadowRoot;e&&e.querySelectorAll(".agent-card[data-agent-index]").forEach(i=>{let a=parseInt(i.dataset.agentIndex,10),s=this._agents[a];s&&(i.addEventListener("click",()=>this._selectAgent(s)),i.querySelectorAll("[data-action]").forEach(r=>{r.addEventListener("click",o=>{o.stopPropagation();let n=r.dataset.action,l=r.dataset.agentId;n==="pause"?this._pauseAgent(l):n==="kill"?this._killAgent(l):n==="resume"&&this._resumeAgent(l)})}))})}),t}_formatTime(t){if(!t)return"";try{return new Date(t).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}catch{return t}}_getStyles(){return`
|
|
4119
4132
|
:host {
|
|
4120
4133
|
display: block;
|
|
4121
4134
|
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
|
|
@@ -4534,7 +4547,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
4534
4547
|
color: var(--loki-error);
|
|
4535
4548
|
font-size: 12px;
|
|
4536
4549
|
}
|
|
4537
|
-
`}};customElements.get("loki-council-dashboard")||customElements.define("loki-council-dashboard",
|
|
4550
|
+
`}};customElements.get("loki-council-dashboard")||customElements.define("loki-council-dashboard",G);var kt={critical:0,major:1,minor:2},Rt={critical:"var(--loki-status-error, #ef4444)",major:"var(--loki-status-warning, #f59e0b)",minor:"var(--loki-text-muted, #71717a)"},V=class extends p{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`
|
|
4538
4551
|
.checklist-viewer {
|
|
4539
4552
|
padding: 16px;
|
|
4540
4553
|
font-family: var(--loki-font-family, system-ui, -apple-system, sans-serif);
|
|
@@ -4823,15 +4836,15 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
4823
4836
|
</div>
|
|
4824
4837
|
${i?`<div class="category-body">${this._renderItems(a)}</div>`:""}
|
|
4825
4838
|
</div>
|
|
4826
|
-
`}).join(""):this._renderEmpty()}_renderItems(t){return t?.length?[...t].sort((i,a)=>(
|
|
4839
|
+
`}).join(""):this._renderEmpty()}_renderItems(t){return t?.length?[...t].sort((i,a)=>(kt[i.priority]??2)-(kt[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=Rt[s],o=i.verification||[],n=this._getWaiverForItem(i.id),l=!!n,h=i.status==="failing"&&(s==="critical"||s==="major"),u=l?`<span class="item-waived-badge" title="${this._escapeHtml(n.reason||"No reason provided")}">WAIVED</span>`:"",v="";return h&&(l?v=`<button class="waiver-btn waiver-btn-unwaive" data-unwaive-id="${this._escapeHtml(i.id)}">Unwaive</button>`:v=`<button class="waiver-btn" data-waive-id="${this._escapeHtml(i.id)}">Waive</button>`),`
|
|
4827
4840
|
<div class="item">
|
|
4828
4841
|
<div class="item-status ${a}"></div>
|
|
4829
4842
|
<div class="item-title">${this._escapeHtml(i.title||i.id||"?")}</div>
|
|
4830
4843
|
<span class="item-priority" style="color:${r};border:1px solid ${r}">${s}</span>
|
|
4844
|
+
${u}
|
|
4831
4845
|
${v}
|
|
4832
|
-
${x}
|
|
4833
4846
|
<div class="verification-dots">
|
|
4834
|
-
${o.map(
|
|
4847
|
+
${o.map(f=>`<div class="v-dot ${f.passed===!0?"v-dot-pass":f.passed===!1?"v-dot-fail":"v-dot-pending"}" title="${this._escapeHtml(f.type||"")}"></div>`).join("")}
|
|
4835
4848
|
</div>
|
|
4836
4849
|
</div>
|
|
4837
4850
|
`}).join(""):'<div class="item" style="color:var(--loki-text-muted)">No items</div>'}_renderEmpty(){return`
|
|
@@ -4839,7 +4852,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
4839
4852
|
<p>Checklist not initialized</p>
|
|
4840
4853
|
<p class="hint">The PRD checklist will be created during the first iteration when a PRD is provided.</p>
|
|
4841
4854
|
</div>
|
|
4842
|
-
`}_attachEventListeners(){let t=this.shadowRoot;t&&(t.querySelectorAll(".category-header[data-category]").forEach(e=>{e.addEventListener("click",()=>this._toggleCategory(e.dataset.category))}),t.querySelectorAll("button[data-waive-id]").forEach(e=>{e.addEventListener("click",i=>{i.stopPropagation(),this._waiveItem(e.dataset.waiveId)})}),t.querySelectorAll("button[data-unwaive-id]").forEach(e=>{e.addEventListener("click",i=>{i.stopPropagation(),this._unwaiveItem(e.dataset.unwaiveId)})}))}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}};customElements.define("loki-checklist-viewer",
|
|
4855
|
+
`}_attachEventListeners(){let t=this.shadowRoot;t&&(t.querySelectorAll(".category-header[data-category]").forEach(e=>{e.addEventListener("click",()=>this._toggleCategory(e.dataset.category))}),t.querySelectorAll("button[data-waive-id]").forEach(e=>{e.addEventListener("click",i=>{i.stopPropagation(),this._waiveItem(e.dataset.waiveId)})}),t.querySelectorAll("button[data-unwaive-id]").forEach(e=>{e.addEventListener("click",i=>{i.stopPropagation(),this._unwaiveItem(e.dataset.unwaiveId)})}))}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}};customElements.define("loki-checklist-viewer",V);var xt={not_initialized:{color:"var(--loki-text-muted, #71717a)",label:"Not Started",pulse:!1},starting:{color:"var(--loki-yellow, #ca8a04)",label:"Starting...",pulse:!0},running:{color:"var(--loki-green, #16a34a)",label:"Running",pulse:!0},stale:{color:"var(--loki-yellow, #ca8a04)",label:"Stale",pulse:!1},completed:{color:"var(--loki-text-muted, #a1a1aa)",label:"Completed",pulse:!1},failed:{color:"var(--loki-red, #dc2626)",label:"Failed",pulse:!1},crashed:{color:"var(--loki-red, #dc2626)",label:"Crashed",pulse:!1},stopped:{color:"var(--loki-text-muted, #a1a1aa)",label:"Stopped",pulse:!1},unknown:{color:"var(--loki-text-muted, #71717a)",label:"Unknown",pulse:!1}},K=class extends p{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._pollInterval=null,this._status=null,this._logs=[],this._lastDataHash=null,this._lastLogsHash=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)}async _loadData(){try{let[t,e]=await Promise.all([this._api.getAppRunnerStatus(),this._api.getAppRunnerLogs()]),i=JSON.stringify({status:t?.status,port:t?.port,restarts:t?.restart_count,url:t?.url}),a=JSON.stringify(e?.lines?.slice(-5)||[]),s=a!==this._lastLogsHash;if(i===this._lastDataHash&&!s)return;this._lastDataHash=i,this._lastLogsHash=a,this._status=t,this._logs=e?.lines||[],this._error=null,this.render(),this._scrollLogsToBottom()}catch(t){this._error||(this._error=`Failed to load app status: ${t.message}`,this.render())}}_scrollLogsToBottom(){let t=this.shadowRoot;if(!t)return;let e=t.querySelector(".log-area");e&&(e.scrollTop=e.scrollHeight)}async _handleRestart(){try{await this._api.restartApp(),this._loadData()}catch(t){this._error=`Restart failed: ${t.message}`,this.render()}}async _handleStop(){try{await this._api.stopApp(),this._loadData()}catch(t){this._error=`Stop failed: ${t.message}`,this.render()}}_formatUptime(t){if(!t)return"--";let e=new Date(t),a=Math.floor((new Date-e)/1e3);if(a<60)return`${a}s`;if(a<3600)return`${Math.floor(a/60)}m ${a%60}s`;let s=Math.floor(a/3600),r=Math.floor(a%3600/60);return`${s}h ${r}m`}_isValidUrl(t){if(!t)return!1;try{let e=new URL(t);return e.protocol==="http:"||e.protocol==="https:"}catch{return!1}}_getStyles(){return`
|
|
4843
4856
|
.app-status {
|
|
4844
4857
|
padding: 16px;
|
|
4845
4858
|
font-family: var(--loki-font-family, system-ui, -apple-system, sans-serif);
|
|
@@ -5015,7 +5028,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
5015
5028
|
${i?"":this._renderEmpty()}
|
|
5016
5029
|
${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
|
|
5017
5030
|
</div>
|
|
5018
|
-
`,this._attachEventListeners()}_renderStatusBadge(t){let e=t?.status||"not_initialized",i=
|
|
5031
|
+
`,this._attachEventListeners()}_renderStatusBadge(t){let e=t?.status||"not_initialized",i=xt[e]||xt.not_initialized;return`
|
|
5019
5032
|
<span class="status-badge" style="background: color-mix(in srgb, ${i.color} 15%, transparent); color: ${i.color}">
|
|
5020
5033
|
<span class="status-dot ${i.pulse?"pulse":""}" style="background: ${i.color}"></span>
|
|
5021
5034
|
${this._escapeHtml(i.label)}
|
|
@@ -5040,7 +5053,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
5040
5053
|
</div>
|
|
5041
5054
|
<div class="status-row">
|
|
5042
5055
|
<span class="status-label">Uptime</span>
|
|
5043
|
-
<span class="status-value">${this._formatUptime(t.started_at)}</span>
|
|
5056
|
+
<span class="status-value">${t.status==="running"||t.status==="stale"?this._formatUptime(t.started_at):"--"}</span>
|
|
5044
5057
|
</div>
|
|
5045
5058
|
${t.status==="crashed"&&t.error?`
|
|
5046
5059
|
<div class="status-row" style="margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--loki-border, #e4e4e7);">
|
|
@@ -5065,7 +5078,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
5065
5078
|
<p>App runner not started</p>
|
|
5066
5079
|
<p class="hint">App runner will start after the first successful build iteration.</p>
|
|
5067
5080
|
</div>
|
|
5068
|
-
`}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.querySelector('[data-action="restart"]'),i=t.querySelector('[data-action="stop"]');e&&e.addEventListener("click",()=>this._handleRestart()),i&&i.addEventListener("click",()=>this._handleStop())}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}};customElements.define("loki-app-status",
|
|
5081
|
+
`}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.querySelector('[data-action="restart"]'),i=t.querySelector('[data-action="stop"]');e&&e.addEventListener("click",()=>this._handleRestart()),i&&i.addEventListener("click",()=>this._handleStop())}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}};customElements.define("loki-app-status",K);var Bt={opus:{input:5,output:25,label:"Opus 4.6",provider:"claude"},sonnet:{input:3,output:15,label:"Sonnet 4.5",provider:"claude"},haiku:{input:1,output:5,label:"Haiku 4.5",provider:"claude"},"gpt-5.3-codex":{input:1.5,output:12,label:"GPT-5.3 Codex",provider:"codex"},"gemini-3-pro":{input:1.25,output:10,label:"Gemini 3 Pro",provider:"gemini"},"gemini-3-flash":{input:.1,output:.4,label:"Gemini 3 Flash",provider:"gemini"}},W=class extends p{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data={total_input_tokens:0,total_output_tokens:0,estimated_cost_usd:0,by_phase:{},by_model:{},budget_limit:null,budget_used:0,budget_remaining:null,connected:!1},this._api=null,this._pollInterval=null,this._modelPricing={...Bt}}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadPricing(),this._loadCost(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadCost()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _loadPricing(){try{let t=await this._api.getPricing();if(t&&t.models){let e={};for(let[i,a]of Object.entries(t.models))e[i]={input:a.input,output:a.output,label:a.label||i,provider:a.provider||"unknown"};this._modelPricing=e,this._pricingSource=t.source||"api",this._pricingDate=t.updated||"",this._activeProvider=t.provider||"claude",this.render()}}catch{}}async _loadCost(){try{let t=await this._api.getCost();this._updateFromCost(t)}catch{this._data.connected=!1,this.render()}}_updateFromCost(t){t&&(this._data={...this._data,connected:!0,total_input_tokens:t.total_input_tokens||0,total_output_tokens:t.total_output_tokens||0,estimated_cost_usd:t.estimated_cost_usd||0,by_phase:t.by_phase||{},by_model:t.by_model||{},budget_limit:t.budget_limit,budget_used:t.budget_used||0,budget_remaining:t.budget_remaining},this.render())}_startPolling(){this._pollInterval=setInterval(async()=>{try{let t=await this._api.getCost();this._updateFromCost(t)}catch{this._data.connected=!1,this.render()}},5e3),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadCost(),this._pollInterval=setInterval(async()=>{try{let t=await this._api.getCost();this._updateFromCost(t)}catch{this._data.connected=!1,this.render()}},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)}_formatTokens(t){return!t||t===0?"0":t>=1e6?(t/1e6).toFixed(2)+"M":t>=1e3?(t/1e3).toFixed(1)+"K":String(t)}_formatUSD(t){return!t||t===0?"$0.00":t<.01?"<$0.01":"$"+t.toFixed(2)}_getBudgetPercent(){return!this._data.budget_limit||this._data.budget_limit<=0?0:Math.min(100,this._data.budget_used/this._data.budget_limit*100)}_getBudgetStatusClass(){let t=this._getBudgetPercent();return t>=90?"critical":t>=70?"warning":"ok"}_renderPhaseRows(){let t=this._data.by_phase;return!t||Object.keys(t).length===0?'<tr><td colspan="4" class="empty-cell">No phase data yet</td></tr>':Object.entries(t).map(([e,i])=>{let a=i.input_tokens||0,s=i.output_tokens||0,r=i.cost_usd||0;return`
|
|
5069
5082
|
<tr>
|
|
5070
5083
|
<td class="phase-name">${this._escapeHTML(e)}</td>
|
|
5071
5084
|
<td class="mono-cell">${this._formatTokens(a)}</td>
|
|
@@ -5468,7 +5481,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
5468
5481
|
</div>
|
|
5469
5482
|
</div>
|
|
5470
5483
|
</div>
|
|
5471
|
-
`}};customElements.get("loki-cost-dashboard")||customElements.define("loki-cost-dashboard",
|
|
5484
|
+
`}};customElements.get("loki-cost-dashboard")||customElements.define("loki-cost-dashboard",W);var Y=class extends p{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._checkpoints=[],this._pollInterval=null,this._lastDataHash=null,this._showCreateForm=!1,this._creating=!1,this._rollingBack=!1,this._rollbackTarget=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)}async _loadData(){try{let[e]=await Promise.allSettled([this._api._get("/api/checkpoints?limit=50")]);e.status==="fulfilled"&&(this._checkpoints=Array.isArray(e.value)?e.value:e.value?.checkpoints||[]),this._error=null}catch(e){this._error=e.message}let t=JSON.stringify({c:this._checkpoints,e:this._error});t!==this._lastDataHash&&(this._lastDataHash=t,this.render())}async _createCheckpoint(){let t=this.shadowRoot.getElementById("checkpoint-message"),e=t?t.value.trim():"";if(e){this._creating=!0,this.render();try{await this._api._post("/api/checkpoints",{message:e}),this._showCreateForm=!1,this._creating=!1,this.dispatchEvent(new CustomEvent("checkpoint-action",{detail:{action:"create",message:e},bubbles:!0})),this._lastDataHash=null,await this._loadData()}catch(i){this._creating=!1,this._error=`Failed to create checkpoint: ${i.message}`,this.render()}}}async _rollbackCheckpoint(t){if(!this._rollingBack){this._rollingBack=!0,this.render();try{await this._api._post(`/api/checkpoints/${t}/rollback`),this._rollbackTarget=null,this.dispatchEvent(new CustomEvent("checkpoint-action",{detail:{action:"rollback",checkpointId:t},bubbles:!0})),this._lastDataHash=null,await this._loadData()}catch(e){this._rollbackTarget=null,this._error=`Failed to rollback: ${e.message}`}finally{this._rollingBack=!1,this.render()}}}_toggleCreateForm(){this._showCreateForm=!this._showCreateForm,this._rollbackTarget=null,this.render()}_confirmRollback(t){this._rollbackTarget=t,this.render()}_cancelRollback(){this._rollbackTarget=null,this.render()}_formatRelativeTime(t){if(!t)return"";try{let e=Date.now(),i=new Date(t).getTime(),a=Math.floor((e-i)/1e3);return a<60?`${a}s ago`:a<3600?`${Math.floor(a/60)}m ago`:a<86400?`${Math.floor(a/3600)}h ago`:`${Math.floor(a/86400)}d ago`}catch{return this._escapeHTML(t)}}render(){let t=this.shadowRoot;if(!t)return;let e=this._checkpoints.length;t.innerHTML=`
|
|
5472
5485
|
<style>${this.getBaseStyles()}${this._getStyles()}</style>
|
|
5473
5486
|
<div class="checkpoint-viewer">
|
|
5474
5487
|
<div class="checkpoint-header">
|
|
@@ -5755,7 +5768,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
5755
5768
|
color: var(--loki-red);
|
|
5756
5769
|
font-size: 12px;
|
|
5757
5770
|
}
|
|
5758
|
-
`}};customElements.get("loki-checkpoint-viewer")||customElements.define("loki-checkpoint-viewer",
|
|
5771
|
+
`}};customElements.get("loki-checkpoint-viewer")||customElements.define("loki-checkpoint-viewer",Y);var Q=class extends p{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data=null,this._connected=!1,this._activeTab="gauge",this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadContext(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadContext()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _loadContext(){try{let t=this.getAttribute("api-url")||window.location.origin,e=await fetch(t+"/api/context");e.ok&&(this._data=await e.json(),this._connected=!0)}catch{this._connected=!1}this.render()}_startPolling(){this._pollInterval=setInterval(()=>{this._loadContext()},5e3),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadContext(),this._pollInterval=setInterval(()=>this._loadContext(),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)}_setTab(t){this._activeTab=t,this.render()}_formatTokens(t){return!t||t===0?"0":t>=1e6?(t/1e6).toFixed(2)+"M":t>=1e3?(t/1e3).toFixed(1)+"K":String(t)}_formatUSD(t){return!t||t===0?"$0.00":t<.01?"<$0.01":"$"+t.toFixed(2)}_escapeHTML(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getGaugeColor(t){return t>80?"var(--loki-red)":t>=60?"var(--loki-yellow)":"var(--loki-green)"}_getGaugeColorClass(t){return t>80?"gauge-red":t>=60?"gauge-yellow":"gauge-green"}_renderGaugeTab(){let t=this._data?.current||{},e=this._data?.totals||{},i=t.context_window_pct||0,a=this._getGaugeColor(i),s=this._getGaugeColorClass(i),r=70,o=2*Math.PI*r,n=o-i/100*o;return`
|
|
5759
5772
|
<div class="gauge-tab">
|
|
5760
5773
|
<div class="gauge-container">
|
|
5761
5774
|
<svg class="gauge-svg" viewBox="0 0 180 180" aria-label="Context window usage: ${i.toFixed(1)}%">
|
|
@@ -5830,14 +5843,14 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
5830
5843
|
</div>
|
|
5831
5844
|
</div>
|
|
5832
5845
|
</div>
|
|
5833
|
-
`}_renderTimelineTab(){let t=this._data?.per_iteration||[],e=this._data?.compactions||[];if(t.length===0)return'<div class="empty-state">No iteration data yet</div>';let i=Math.max(...t.map(r=>(r.input_tokens||0)+(r.output_tokens||0)+(r.cache_read_tokens||0)+(r.cache_creation_tokens||0))),a=new Set(e.map(r=>r.at_iteration)),s="";for(let r of t){let o=(r.input_tokens||0)+(r.output_tokens||0)+(r.cache_read_tokens||0)+(r.cache_creation_tokens||0),n=i>0?o/i*100:0,
|
|
5846
|
+
`}_renderTimelineTab(){let t=this._data?.per_iteration||[],e=this._data?.compactions||[];if(t.length===0)return'<div class="empty-state">No iteration data yet</div>';let i=Math.max(...t.map(r=>(r.input_tokens||0)+(r.output_tokens||0)+(r.cache_read_tokens||0)+(r.cache_creation_tokens||0))),a=new Set(e.map(r=>r.at_iteration)),s="";for(let r of t){let o=(r.input_tokens||0)+(r.output_tokens||0)+(r.cache_read_tokens||0)+(r.cache_creation_tokens||0),n=i>0?o/i*100:0,l=r.compacted===!0;a.has(r.iteration)&&(s+=`
|
|
5834
5847
|
<div class="timeline-compaction-row">
|
|
5835
5848
|
<div class="compaction-line"></div>
|
|
5836
5849
|
<span class="compaction-label">Context Compacted</span>
|
|
5837
5850
|
<div class="compaction-line"></div>
|
|
5838
5851
|
</div>
|
|
5839
5852
|
`),s+=`
|
|
5840
|
-
<div class="timeline-row ${
|
|
5853
|
+
<div class="timeline-row ${l?"compacted":""}">
|
|
5841
5854
|
<div class="timeline-iter">#${r.iteration}</div>
|
|
5842
5855
|
<div class="timeline-bar-container">
|
|
5843
5856
|
<div class="timeline-bar" style="width: ${n.toFixed(1)}%"></div>
|
|
@@ -5868,14 +5881,14 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
5868
5881
|
<div class="legend-item"><span class="legend-swatch swatch-cache-read"></span> Cache Read</div>
|
|
5869
5882
|
<div class="legend-item"><span class="legend-swatch swatch-cache-create"></span> Cache Creation</div>
|
|
5870
5883
|
</div>
|
|
5871
|
-
`,a="";for(let s of t){let r=s.input_tokens||0,o=s.output_tokens||0,n=s.cache_read_tokens||0,
|
|
5884
|
+
`,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,h=r+o+n+l,u=e>0?r/e*100:0,v=e>0?o/e*100:0,f=e>0?n/e*100:0,H=e>0?l/e*100:0;a+=`
|
|
5872
5885
|
<div class="breakdown-row">
|
|
5873
5886
|
<div class="breakdown-iter">#${s.iteration}</div>
|
|
5874
5887
|
<div class="breakdown-bar-container">
|
|
5875
|
-
<div class="breakdown-bar bar-input" style="width: ${
|
|
5876
|
-
<div class="breakdown-bar bar-output" style="width: ${
|
|
5877
|
-
<div class="breakdown-bar bar-cache-read" style="width: ${
|
|
5878
|
-
<div class="breakdown-bar bar-cache-create" style="width: ${
|
|
5888
|
+
<div class="breakdown-bar bar-input" style="width: ${u.toFixed(1)}%"></div>
|
|
5889
|
+
<div class="breakdown-bar bar-output" style="width: ${v.toFixed(1)}%"></div>
|
|
5890
|
+
<div class="breakdown-bar bar-cache-read" style="width: ${f.toFixed(1)}%"></div>
|
|
5891
|
+
<div class="breakdown-bar bar-cache-create" style="width: ${H.toFixed(1)}%"></div>
|
|
5879
5892
|
</div>
|
|
5880
5893
|
<div class="breakdown-cost">${this._formatUSD(s.cost_usd)}</div>
|
|
5881
5894
|
</div>
|
|
@@ -6278,7 +6291,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
6278
6291
|
|
|
6279
6292
|
${t}
|
|
6280
6293
|
</div>
|
|
6281
|
-
`,this.shadowRoot.querySelectorAll(".tab").forEach(e=>{e.addEventListener("click",()=>{this._setTab(e.dataset.tab)})})}};customElements.get("loki-context-tracker")||customElements.define("loki-context-tracker",Q);var
|
|
6294
|
+
`,this.shadowRoot.querySelectorAll(".tab").forEach(e=>{e.addEventListener("click",()=>{this._setTab(e.dataset.tab)})})}};customElements.get("loki-context-tracker")||customElements.define("loki-context-tracker",Q);var ut={critical:"var(--loki-red, #ef4444)",warning:"var(--loki-yellow, #eab308)",info:"var(--loki-blue, #3b82f6)"},X=class extends p{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._notifications=[],this._triggers=[],this._summary={},this._connected=!1,this._activeTab="feed",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"}),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)}}_escapeHTML(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getSeverityColor(t){return ut[t]||ut.info}_switchTab(t){this._activeTab=t,this.render()}_bindEvents(){let t=this.shadowRoot;t.querySelectorAll(".tab").forEach(i=>{i.addEventListener("click",()=>{this._switchTab(i.dataset.tab)})}),t.querySelectorAll(".ack-btn").forEach(i=>{i.addEventListener("click",()=>{this._acknowledgeNotification(i.dataset.id)})});let e=t.querySelector(".ack-all-btn");e&&e.addEventListener("click",()=>{this._acknowledgeAll()}),t.querySelectorAll(".toggle input").forEach(i=>{i.addEventListener("change",()=>{this._toggleTrigger(i.dataset.triggerId,i.checked)})})}_renderSummaryBar(){let t=this._summary.total||0,e=this._summary.unacknowledged||0,i=this._summary.critical||0;return`
|
|
6282
6295
|
<div class="summary-row">
|
|
6283
6296
|
<div class="summary-grid">
|
|
6284
6297
|
<div class="summary-card">
|
|
@@ -6291,7 +6304,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
6291
6304
|
</div>
|
|
6292
6305
|
<div class="summary-card">
|
|
6293
6306
|
<div class="card-label">Critical</div>
|
|
6294
|
-
<div class="card-value" style="color: ${
|
|
6307
|
+
<div class="card-value" style="color: ${ut.critical}">${i}</div>
|
|
6295
6308
|
</div>
|
|
6296
6309
|
</div>
|
|
6297
6310
|
${e>0?`
|
|
@@ -6653,7 +6666,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
6653
6666
|
</div>
|
|
6654
6667
|
`:""}
|
|
6655
6668
|
</div>
|
|
6656
|
-
`,this._bindEvents()}};customElements.get("loki-notification-center")||customElements.define("loki-notification-center",X);var Z=class extends p{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data=null,this._error=null,this._loading=!0,this._api=null,this._pollInterval=null,this._expandedDecisions=new Set}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=
|
|
6669
|
+
`,this._bindEvents()}};customElements.get("loki-notification-center")||customElements.define("loki-notification-center",X);var Z=class extends p{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data=null,this._error=null,this._loading=!0,this._api=null,this._pollInterval=null,this._expandedDecisions=new Set}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{this._data=await this._api._get("/api/session-diff"),this._error=null}catch(t){this._error=t.message,this._data=null}this._loading=!1,this.render()}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),3e4)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_toggleDecision(t){this._expandedDecisions.has(t)?this._expandedDecisions.delete(t):this._expandedDecisions.add(t),this.render()}render(){let t=`
|
|
6657
6670
|
${this.getBaseStyles()}
|
|
6658
6671
|
|
|
6659
6672
|
:host {
|
|
@@ -6868,19 +6881,19 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
6868
6881
|
<div class="highlights-section">
|
|
6869
6882
|
<div class="section-label">Highlights</div>
|
|
6870
6883
|
<ul class="highlight-list">
|
|
6871
|
-
${s.map(
|
|
6884
|
+
${s.map(l=>`<li class="highlight-item">${this._escapeHtml(l)}</li>`).join("")}
|
|
6872
6885
|
</ul>
|
|
6873
6886
|
</div>
|
|
6874
6887
|
`);let n="";r.length>0&&(n=`
|
|
6875
6888
|
<div class="decisions-section">
|
|
6876
6889
|
<div class="section-label">Decisions</div>
|
|
6877
|
-
${r.map((
|
|
6890
|
+
${r.map((l,h)=>{let u=this._expandedDecisions.has(h);return`
|
|
6878
6891
|
<div class="decision-item">
|
|
6879
|
-
<button class="decision-header" data-index="${
|
|
6880
|
-
<span class="decision-arrow ${
|
|
6881
|
-
${this._escapeHtml(
|
|
6892
|
+
<button class="decision-header" data-index="${h}">
|
|
6893
|
+
<span class="decision-arrow ${u?"expanded":""}">▶</span>
|
|
6894
|
+
${this._escapeHtml(l.title||l.decision||"Decision")}
|
|
6882
6895
|
</button>
|
|
6883
|
-
${
|
|
6896
|
+
${u?`<div class="decision-reasoning">${this._escapeHtml(l.reasoning||l.rationale||"No reasoning provided")}</div>`:""}
|
|
6884
6897
|
</div>
|
|
6885
6898
|
`}).join("")}
|
|
6886
6899
|
</div>
|
|
@@ -6915,7 +6928,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
6915
6928
|
${o}
|
|
6916
6929
|
${n}
|
|
6917
6930
|
</div>
|
|
6918
|
-
`,this.shadowRoot.querySelectorAll(".decision-header").forEach(
|
|
6931
|
+
`,this.shadowRoot.querySelectorAll(".decision-header").forEach(l=>{l.addEventListener("click",()=>{this._toggleDecision(parseInt(l.dataset.index))})})}};customElements.get("loki-session-diff")||customElements.define("loki-session-diff",Z);var tt=class extends p{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data=null,this._error=null,this._loading=!0,this._optimizing=!1,this._api=null,this._pollInterval=null,this._expandedChanges=new Set}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{this._data=await this._api._get("/api/prompt-versions"),this._error=null}catch(t){this._error=t.message,this._data=null}this._loading=!1,this.render()}async _triggerOptimize(){if(!this._optimizing){this._optimizing=!0,this.render();try{await this._api._post("/api/prompt-optimize?dry_run=false",{}),await this._loadData()}catch(t){this._error=t.message}this._optimizing=!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,"""):""}_formatTime(t){if(!t)return"--";try{let e=new Date(t),a=new Date-e,s=Math.floor(a/6e4);if(s<1)return"Just now";if(s<60)return`${s}m ago`;let r=Math.floor(s/60);return r<24?`${r}h ago`:`${Math.floor(r/24)}d ago`}catch{return"--"}}_toggleChange(t){this._expandedChanges.has(t)?this._expandedChanges.delete(t):this._expandedChanges.add(t),this.render()}render(){let t=`
|
|
6919
6932
|
${this.getBaseStyles()}
|
|
6920
6933
|
|
|
6921
6934
|
:host {
|
|
@@ -7128,13 +7141,13 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
7128
7141
|
`;return}let e=this._data||{},i=e.version!=null?e.version:"--",a=this._formatTime(e.last_optimized),s=e.failures_analyzed!=null?e.failures_analyzed:"--",r=e.changes||[],o="";r.length>0&&(o=`
|
|
7129
7142
|
<div class="changes-section">
|
|
7130
7143
|
<div class="section-label">Changes</div>
|
|
7131
|
-
${r.map((
|
|
7144
|
+
${r.map((l,h)=>{let u=this._expandedChanges.has(h);return`
|
|
7132
7145
|
<div class="change-item">
|
|
7133
|
-
<button class="change-header" data-index="${
|
|
7134
|
-
<span class="change-arrow ${
|
|
7135
|
-
${this._escapeHtml(
|
|
7146
|
+
<button class="change-header" data-index="${h}">
|
|
7147
|
+
<span class="change-arrow ${u?"expanded":""}">▶</span>
|
|
7148
|
+
${this._escapeHtml(l.description||l.title||"Change")}
|
|
7136
7149
|
</button>
|
|
7137
|
-
${
|
|
7150
|
+
${u?`<div class="change-rationale">${this._escapeHtml(l.rationale||l.reasoning||"No rationale provided")}</div>`:""}
|
|
7138
7151
|
</div>
|
|
7139
7152
|
`}).join("")}
|
|
7140
7153
|
</div>
|
|
@@ -7166,10 +7179,10 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
7166
7179
|
|
|
7167
7180
|
${o}
|
|
7168
7181
|
</div>
|
|
7169
|
-
`;let n=this.shadowRoot.getElementById("optimize-btn");n&&n.addEventListener("click",()=>this._triggerOptimize()),this.shadowRoot.querySelectorAll(".change-header").forEach(
|
|
7182
|
+
`;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",tt);var et=class extends p{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(h=>typeof h=="number"?h:h.score||0),i=Math.min(...e),s=Math.max(...e)-i||1,r=120,o=32,n=2,l=e.map((h,u)=>{let v=n+u/(e.length-1)*(r-n*2),f=n+(1-(h-i)/s)*(o-n*2);return`${v},${f}`}).join(" ");return`
|
|
7170
7183
|
<svg width="${r}" height="${o}" viewBox="0 0 ${r} ${o}" class="sparkline">
|
|
7171
|
-
<polyline points="${
|
|
7172
|
-
<circle cx="${
|
|
7184
|
+
<polyline points="${l}" fill="none" stroke="var(--loki-accent)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
7185
|
+
<circle cx="${l.split(" ").pop().split(",")[0]}" cy="${l.split(" ").pop().split(",")[1]}" r="2.5" fill="var(--loki-accent)"/>
|
|
7173
7186
|
</svg>
|
|
7174
7187
|
`}render(){let t=`
|
|
7175
7188
|
${this.getBaseStyles()}
|
|
@@ -7463,15 +7476,15 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
7463
7476
|
</div>
|
|
7464
7477
|
<div class="empty-state">No quality data available</div>
|
|
7465
7478
|
</div>
|
|
7466
|
-
`;return}let e=this._data||{},i=e.score!=null?Math.round(e.score):0,{grade:a,color:s}=this._getGrade(i),r=e.categories||{},o=e.findings||{},n=["security","code_quality","compliance","best_practices"],
|
|
7479
|
+
`;return}let e=this._data||{},i=e.score!=null?Math.round(e.score):0,{grade:a,color:s}=this._getGrade(i),r=e.categories||{},o=e.findings||{},n=["security","code_quality","compliance","best_practices"],l={security:"Security",code_quality:"Code Quality",compliance:"Compliance",best_practices:"Best Practices"},h=n.map(y=>{let st=r[y]!=null?Math.round(r[y]):0,wt=st>=80?"var(--loki-success)":st>=60?"var(--loki-warning)":"var(--loki-error)";return`
|
|
7467
7480
|
<div class="category-item">
|
|
7468
|
-
<span class="category-name">${
|
|
7481
|
+
<span class="category-name">${l[y]||y}</span>
|
|
7469
7482
|
<div class="progress-bar">
|
|
7470
|
-
<div class="progress-fill" style="width:${
|
|
7483
|
+
<div class="progress-fill" style="width:${st}%;background:${wt};"></div>
|
|
7471
7484
|
</div>
|
|
7472
|
-
<span class="category-score">${
|
|
7485
|
+
<span class="category-score">${st}</span>
|
|
7473
7486
|
</div>
|
|
7474
|
-
`}).join(""),
|
|
7487
|
+
`}).join(""),v=[{key:"critical",cls:"finding-critical",label:"Critical"},{key:"major",cls:"finding-major",label:"Major"},{key:"minor",cls:"finding-minor",label:"Minor"},{key:"info",cls:"finding-info",label:"Info"}].filter(y=>(o[y.key]||0)>0).map(y=>`<span class="finding-badge ${y.cls}">${y.label}: ${o[y.key]}</span>`).join(""),f=this._renderSparkline(this._history);this.shadowRoot.innerHTML=`
|
|
7475
7488
|
<style>${t}</style>
|
|
7476
7489
|
<div class="quality-container">
|
|
7477
7490
|
<div class="quality-header">
|
|
@@ -7487,32 +7500,32 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
7487
7500
|
<div class="score-number">${i}</div>
|
|
7488
7501
|
<span class="grade-badge" style="background:${s};color:#fff;">${a}</span>
|
|
7489
7502
|
</div>
|
|
7490
|
-
${
|
|
7503
|
+
${f?`
|
|
7491
7504
|
<div class="sparkline-container">
|
|
7492
7505
|
<span class="sparkline-label">Trend (last ${this._history.length})</span>
|
|
7493
|
-
${
|
|
7506
|
+
${f}
|
|
7494
7507
|
</div>
|
|
7495
7508
|
`:""}
|
|
7496
7509
|
</div>
|
|
7497
7510
|
|
|
7498
7511
|
<div class="categories-section">
|
|
7499
7512
|
<div class="section-label">Categories</div>
|
|
7500
|
-
${
|
|
7513
|
+
${h}
|
|
7501
7514
|
</div>
|
|
7502
7515
|
|
|
7503
|
-
${
|
|
7516
|
+
${v?`
|
|
7504
7517
|
<div class="findings-section">
|
|
7505
7518
|
<div class="section-label">Findings</div>
|
|
7506
|
-
<div class="findings-row">${
|
|
7519
|
+
<div class="findings-row">${v}</div>
|
|
7507
7520
|
</div>
|
|
7508
7521
|
`:""}
|
|
7509
7522
|
</div>
|
|
7510
|
-
`;let
|
|
7523
|
+
`;let H=this.shadowRoot.getElementById("scan-btn");H&&H.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-score")||customElements.define("loki-quality-score",et);var _t=["understand","guardrail","migrate","verify"],yt={understand:"Understand",guardrail:"Guardrail",migrate:"Migrate",verify:"Verify"},Ft={understand:"#5b9bd5",guardrail:"#e8b84a",migrate:"#5bb870",verify:"#5bc8c8"},it=class extends p{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=_t.indexOf(t);return e>=0?e:0}_renderPhaseBar(t,e){let i=e||[];return _t.map(a=>{let s=i.includes(a),r=a===t,o=Ft[a],n=s?"1":r?"0.7":"0.2",l=this._getPhaseIcon(a,t,e);return`
|
|
7511
7524
|
<div class="phase-segment">
|
|
7512
7525
|
<div class="phase-bar-fill" style="background:${o};opacity:${n};"></div>
|
|
7513
7526
|
<div class="phase-label">
|
|
7514
|
-
<span class="phase-icon">${
|
|
7515
|
-
${
|
|
7527
|
+
<span class="phase-icon">${l}</span>
|
|
7528
|
+
${yt[a]}
|
|
7516
7529
|
</div>
|
|
7517
7530
|
</div>
|
|
7518
7531
|
`}).join("")}_renderFeatureStats(t){if(!t)return"";let e=t.passing||0,i=t.total||0,a=i>0?Math.round(e/i*100):0,s=a>=80?"var(--loki-success)":a>=50?"var(--loki-warning)":"var(--loki-error)";return`
|
|
@@ -7903,7 +7916,7 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
7903
7916
|
</div>
|
|
7904
7917
|
<div class="meta-item">
|
|
7905
7918
|
<span class="meta-label">Phase</span>
|
|
7906
|
-
<span>${
|
|
7919
|
+
<span>${yt[o]||this._escapeHtml(o)}</span>
|
|
7907
7920
|
</div>
|
|
7908
7921
|
</div>
|
|
7909
7922
|
|
|
@@ -7930,7 +7943,454 @@ var LokiDashboard=(()=>{var st=Object.defineProperty;var wt=Object.getOwnPropert
|
|
|
7930
7943
|
<div class="section-label">Migrations</div>
|
|
7931
7944
|
${this._renderMigrationList()}
|
|
7932
7945
|
</div>
|
|
7933
|
-
`}};customElements.get("loki-migration-dashboard")||customElements.define("loki-migration-dashboard",it);var
|
|
7946
|
+
`}};customElements.get("loki-migration-dashboard")||customElements.define("loki-migration-dashboard",it);var jt={opus:"claude",sonnet:"claude",haiku:"claude",claude:"claude",gpt:"codex",codex:"codex",gemini:"gemini"};function Ut(c){let t=(c||"").toLowerCase();for(let[e,i]of Object.entries(jt))if(t.includes(e))return i;return"unknown"}var at=class extends p{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._api=null,this._pollInterval=null,this._activeTab="heatmap",this._activity=[],this._tools=[],this._cost={},this._context={},this._trends=[],this._toolTimeRange="7d",this._connected=!1}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())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _fetchActivity(){let t=this._api.baseUrl||window.location.origin,e=await fetch(`${t}/api/activity?limit=1000`);if(!e.ok)throw new Error(`Activity API ${e.status}`);return e.json()}async _loadData(){if(!this.isConnected)return;let t=await Promise.allSettled([this._fetchActivity(),this._api.getToolEfficiency(50),this._api.getCost(),this._api.getContext(),this._api.getLearningTrends({timeRange:this._toolTimeRange})]);if(t[0].status==="fulfilled"&&(this._activity=t[0].value||[]),t[1].status==="fulfilled"&&(this._tools=t[1].value||[]),t[2].status==="fulfilled"&&(this._cost=t[2].value||{}),t[3].status==="fulfilled"&&(this._context=t[3].value||{}),t[4].status==="fulfilled"){let e=t[4].value||{};this._trends=Array.isArray(e)?e:e.dataPoints||[]}this._connected=t.some(e=>e.status==="fulfilled"),this.render()}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),3e4),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadData(),this._pollInterval=setInterval(()=>this._loadData(),3e4))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null)}_computeHeatmap(){let t={},e=Array.isArray(this._activity)?this._activity:[];for(let h of e){let u=h.timestamp||h.ts||h.created_at;if(!u)continue;let v=new Date(u);if(isNaN(v.getTime()))continue;let f=v.toISOString().slice(0,10);t[f]=(t[f]||0)+1}let i=new Date;i.setHours(0,0,0,0);let a=i.getDay(),s=new Date(i),r=new Date(i);r.setDate(r.getDate()-(52*7+a));let o=[],n=new Date(r),l=0;for(;n<=s;){let h=n.toISOString().slice(0,10),u=t[h]||0;u>l&&(l=u),o.push({date:h,count:u,day:n.getDay()}),n.setDate(n.getDate()+1)}return{cells:o,maxCount:l}}_getHeatmapLevel(t,e){if(t===0||e===0)return 0;let i=t/e;return i<=.25?1:i<=.5?2:i<=.75?3:4}_renderHeatmap(){let{cells:t,maxCount:e}=this._computeHeatmap(),i=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],a=["","Mon","","Wed","","Fri",""],s=[],r=-1,o=0;for(let u=0;u<t.length;u++){t[u].day===0&&o++;let v=new Date(t[u].date).getMonth();v!==r&&(s.push({month:i[v],col:Math.max(o,1)}),r=v)}let n=s.map(u=>`<span class="heatmap-month" style="grid-column: ${u.col}">${u.month}</span>`).join(""),l=t.map(u=>`<div class="heatmap-cell level-${this._getHeatmapLevel(u.count,e)}" title="${u.date}: ${u.count} activities"></div>`).join(""),h=a.map(u=>`<span class="heatmap-day-label">${u}</span>`).join("");return`
|
|
7947
|
+
<div class="heatmap-container">
|
|
7948
|
+
<div class="heatmap-months">${n}</div>
|
|
7949
|
+
<div class="heatmap-body">
|
|
7950
|
+
<div class="heatmap-day-labels">${h}</div>
|
|
7951
|
+
<div class="heatmap-grid">${l}</div>
|
|
7952
|
+
</div>
|
|
7953
|
+
<div class="heatmap-legend">
|
|
7954
|
+
<span class="heatmap-legend-label">Less</span>
|
|
7955
|
+
<div class="heatmap-cell level-0"></div>
|
|
7956
|
+
<div class="heatmap-cell level-1"></div>
|
|
7957
|
+
<div class="heatmap-cell level-2"></div>
|
|
7958
|
+
<div class="heatmap-cell level-3"></div>
|
|
7959
|
+
<div class="heatmap-cell level-4"></div>
|
|
7960
|
+
<span class="heatmap-legend-label">More</span>
|
|
7961
|
+
</div>
|
|
7962
|
+
</div>
|
|
7963
|
+
`}_computeToolUsage(){let t=Array.isArray(this._tools)?this._tools:[],e={};for(let i of t){let a=i.tool||i.name||i.tool_name||i.data&&i.data.tool_name||"unknown",s=i.count??i.calls??i.frequency??(i.data&&i.data.count)??1;e[a]=(e[a]||0)+s}return Object.entries(e).sort((i,a)=>a[1]-i[1]).slice(0,15)}_renderToolUsage(){let t=this._computeToolUsage(),e=t.length>0?t[0][1]:0;if(t.length===0)return'<div class="empty-state">No tool usage data available</div>';let i=`
|
|
7964
|
+
<div class="tool-filter">
|
|
7965
|
+
<select class="tool-time-select" id="tool-time-range">
|
|
7966
|
+
<option value="1h" ${this._toolTimeRange==="1h"?"selected":""}>Last hour</option>
|
|
7967
|
+
<option value="24h" ${this._toolTimeRange==="24h"?"selected":""}>Last 24h</option>
|
|
7968
|
+
<option value="7d" ${this._toolTimeRange==="7d"?"selected":""}>Last 7 days</option>
|
|
7969
|
+
<option value="30d" ${this._toolTimeRange==="30d"?"selected":""}>Last 30 days</option>
|
|
7970
|
+
</select>
|
|
7971
|
+
</div>
|
|
7972
|
+
`,a=t.map(([s,r])=>{let o=e>0?r/e*100:0;return`
|
|
7973
|
+
<div class="tool-row">
|
|
7974
|
+
<span class="tool-name" title="${this._esc(s)}">${this._esc(s)}</span>
|
|
7975
|
+
<div class="tool-bar-track">
|
|
7976
|
+
<div class="tool-bar-fill" style="width: ${o.toFixed(1)}%"></div>
|
|
7977
|
+
</div>
|
|
7978
|
+
<span class="tool-count">${r}</span>
|
|
7979
|
+
</div>
|
|
7980
|
+
`}).join("");return i+'<div class="tool-bars">'+a+"</div>"}_computeVelocity(){let t=this._context||{},e=t.per_iteration||t.iterations||[],i=Array.isArray(e)&&e.length>0?e.length:t.totals&&t.totals.iterations_tracked||t.total_iterations||0,a=0;if(Array.isArray(e)&&e.length>=2){let o=e.map(n=>new Date(n.timestamp||n.started_at||n.ts).getTime()).filter(n=>!isNaN(n)).sort((n,l)=>n-l);if(o.length>=2){let n=(o[o.length-1]-o[0])/36e5;n>0&&(a=o.length/n)}}let s=[],r=Array.isArray(this._trends)?this._trends:[];if(r.length>0)for(let o of r.slice(-24))s.push(o.count??o.value??0);else if(Array.isArray(e)&&e.length>0){let o={};for(let l of e){let h=l.timestamp||l.started_at||l.ts;if(!h)continue;let v=new Date(h).toISOString().slice(0,13);o[v]=(o[v]||0)+1}let n=Object.keys(o).sort().slice(-24);for(let l of n)s.push(o[l])}return{iterPerHour:a,totalIterations:i,hourlyBuckets:s}}_renderVelocity(){let{iterPerHour:t,totalIterations:e,hourlyBuckets:i}=this._computeVelocity(),a=Math.max(1,...i),s=i.length>0?i.map(r=>{let o=r/a*100;return`<div class="spark-bar" style="height: ${Math.max(2,o)}%" title="${r}"></div>`}).join(""):'<div class="empty-state" style="padding: 12px">No trend data</div>';return`
|
|
7981
|
+
<div class="velocity-cards">
|
|
7982
|
+
<div class="velocity-card">
|
|
7983
|
+
<div class="velocity-label">Iterations / Hour</div>
|
|
7984
|
+
<div class="velocity-value">${t.toFixed(1)}</div>
|
|
7985
|
+
</div>
|
|
7986
|
+
<div class="velocity-card">
|
|
7987
|
+
<div class="velocity-label">Total Iterations</div>
|
|
7988
|
+
<div class="velocity-value">${e}</div>
|
|
7989
|
+
</div>
|
|
7990
|
+
</div>
|
|
7991
|
+
<div class="sparkline-container">
|
|
7992
|
+
<div class="sparkline-label">Activity Trend (hourly)</div>
|
|
7993
|
+
<div class="sparkline">${s}</div>
|
|
7994
|
+
</div>
|
|
7995
|
+
`}_computeProviders(){let t=this._cost.by_model||{},e={};for(let[r,o]of Object.entries(t)){let n=Ut(r);e[n]||(e[n]={cost:0,tokens:0,iterations:0,models:[]});let l=o.cost_usd||0,h=(o.input_tokens||0)+(o.output_tokens||0);e[n].cost+=l,e[n].tokens+=h,e[n].models.push(r)}let a=(this._context.totals||{}).iterations_tracked||this._context.total_iterations||this._context.iteration||0,s=this._cost.estimated_cost_usd||0;for(let r of Object.values(e))if(s>0&&a>0){let o=r.cost/s;r.iterations=Math.round(o*a)}return e}_renderProviders(){let t=this._computeProviders(),e={claude:{label:"Claude",color:"var(--loki-accent)"},codex:{label:"Codex",color:"var(--loki-success)"},gemini:{label:"Gemini",color:"var(--loki-info)"},unknown:{label:"Other",color:"var(--loki-text-muted)"}},i=Object.entries(t);return i.length===0?'<div class="empty-state">No provider data available. Start a session to see cross-provider comparison.</div>':`
|
|
7996
|
+
<div class="provider-grid">
|
|
7997
|
+
${i.map(([a,s])=>{let r=e[a]||e.unknown,o=s.iterations>0?(s.cost/s.iterations).toFixed(4):"--",n=s.iterations>0?Math.round(s.tokens/s.iterations).toLocaleString():"--";return`
|
|
7998
|
+
<div class="provider-card">
|
|
7999
|
+
<div class="provider-accent" style="background: ${r.color}"></div>
|
|
8000
|
+
<div class="provider-body">
|
|
8001
|
+
<div class="provider-name">${r.label}</div>
|
|
8002
|
+
<div class="provider-stat">
|
|
8003
|
+
<span class="provider-stat-label">Total Cost</span>
|
|
8004
|
+
<span class="provider-stat-value">${s.cost>0?"$"+s.cost.toFixed(2):"$0.00"}</span>
|
|
8005
|
+
</div>
|
|
8006
|
+
<div class="provider-stat">
|
|
8007
|
+
<span class="provider-stat-label">Cost / Iteration</span>
|
|
8008
|
+
<span class="provider-stat-value">${o!=="--"?"$"+o:o}</span>
|
|
8009
|
+
</div>
|
|
8010
|
+
<div class="provider-stat">
|
|
8011
|
+
<span class="provider-stat-label">Tokens / Iteration</span>
|
|
8012
|
+
<span class="provider-stat-value">${n}</span>
|
|
8013
|
+
</div>
|
|
8014
|
+
<div class="provider-stat">
|
|
8015
|
+
<span class="provider-stat-label">Total Tokens</span>
|
|
8016
|
+
<span class="provider-stat-value">${s.tokens.toLocaleString()}</span>
|
|
8017
|
+
</div>
|
|
8018
|
+
<div class="provider-models">${s.models.map(l=>this._esc(l)).join(", ")}</div>
|
|
8019
|
+
</div>
|
|
8020
|
+
</div>
|
|
8021
|
+
`}).join("")}
|
|
8022
|
+
</div>
|
|
8023
|
+
`}_esc(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"):""}_handleTabClick(t){let e=t.target.closest("[data-tab]");e&&(this._activeTab=e.dataset.tab,this.render())}_handleTimeRangeChange(t){this._toolTimeRange=t.target.value,this._loadData()}render(){let t=[{id:"heatmap",label:"Activity",icon:'<svg viewBox="0 0 24 24"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg>'},{id:"tools",label:"Tools",icon:'<svg viewBox="0 0 24 24"><path d="M14.7 6.3a1 1 0 000 1.4l1.6 1.6a1 1 0 001.4 0l3.77-3.77a6 6 0 01-7.94 7.94l-6.91 6.91a2.12 2.12 0 01-3-3l6.91-6.91a6 6 0 017.94-7.94l-3.76 3.76z"/></svg>'},{id:"velocity",label:"Velocity",icon:'<svg viewBox="0 0 24 24"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>'},{id:"providers",label:"Providers",icon:'<svg viewBox="0 0 24 24"><line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/></svg>'}],e="";switch(this._activeTab){case"heatmap":e=this._renderHeatmap();break;case"tools":e=this._renderToolUsage();break;case"velocity":e=this._renderVelocity();break;case"providers":e=this._renderProviders();break}this.shadowRoot.innerHTML=`
|
|
8024
|
+
<style>
|
|
8025
|
+
${this.getBaseStyles()}
|
|
8026
|
+
|
|
8027
|
+
:host { display: block; }
|
|
8028
|
+
|
|
8029
|
+
.analytics-container {
|
|
8030
|
+
display: flex;
|
|
8031
|
+
flex-direction: column;
|
|
8032
|
+
gap: 16px;
|
|
8033
|
+
}
|
|
8034
|
+
|
|
8035
|
+
/* Tab bar */
|
|
8036
|
+
.tab-bar {
|
|
8037
|
+
display: flex;
|
|
8038
|
+
gap: 2px;
|
|
8039
|
+
background: var(--loki-bg-secondary);
|
|
8040
|
+
border-radius: 8px;
|
|
8041
|
+
padding: 3px;
|
|
8042
|
+
}
|
|
8043
|
+
|
|
8044
|
+
.tab-btn {
|
|
8045
|
+
display: flex;
|
|
8046
|
+
align-items: center;
|
|
8047
|
+
gap: 6px;
|
|
8048
|
+
padding: 8px 14px;
|
|
8049
|
+
border: none;
|
|
8050
|
+
border-radius: 6px;
|
|
8051
|
+
background: transparent;
|
|
8052
|
+
color: var(--loki-text-muted);
|
|
8053
|
+
font-family: inherit;
|
|
8054
|
+
font-size: 13px;
|
|
8055
|
+
font-weight: 500;
|
|
8056
|
+
cursor: pointer;
|
|
8057
|
+
transition: all 0.15s ease;
|
|
8058
|
+
}
|
|
8059
|
+
|
|
8060
|
+
.tab-btn:hover {
|
|
8061
|
+
color: var(--loki-text-primary);
|
|
8062
|
+
background: var(--loki-bg-hover);
|
|
8063
|
+
}
|
|
8064
|
+
|
|
8065
|
+
.tab-btn.active {
|
|
8066
|
+
color: var(--loki-accent);
|
|
8067
|
+
background: var(--loki-bg-card);
|
|
8068
|
+
box-shadow: 0 1px 3px rgba(0,0,0,0.06);
|
|
8069
|
+
}
|
|
8070
|
+
|
|
8071
|
+
.tab-btn svg {
|
|
8072
|
+
width: 14px;
|
|
8073
|
+
height: 14px;
|
|
8074
|
+
stroke: currentColor;
|
|
8075
|
+
stroke-width: 2;
|
|
8076
|
+
fill: none;
|
|
8077
|
+
flex-shrink: 0;
|
|
8078
|
+
}
|
|
8079
|
+
|
|
8080
|
+
.tab-content {
|
|
8081
|
+
background: var(--loki-bg-card);
|
|
8082
|
+
border: 1px solid var(--loki-border);
|
|
8083
|
+
border-radius: 8px;
|
|
8084
|
+
padding: 20px;
|
|
8085
|
+
min-height: 200px;
|
|
8086
|
+
}
|
|
8087
|
+
|
|
8088
|
+
.empty-state {
|
|
8089
|
+
text-align: center;
|
|
8090
|
+
padding: 32px 16px;
|
|
8091
|
+
color: var(--loki-text-muted);
|
|
8092
|
+
font-size: 13px;
|
|
8093
|
+
}
|
|
8094
|
+
|
|
8095
|
+
.offline-notice {
|
|
8096
|
+
text-align: center;
|
|
8097
|
+
padding: 20px;
|
|
8098
|
+
color: var(--loki-text-muted);
|
|
8099
|
+
font-size: 12px;
|
|
8100
|
+
}
|
|
8101
|
+
|
|
8102
|
+
/* ---------- Heatmap ---------- */
|
|
8103
|
+
.heatmap-container {
|
|
8104
|
+
overflow-x: auto;
|
|
8105
|
+
}
|
|
8106
|
+
|
|
8107
|
+
.heatmap-months {
|
|
8108
|
+
display: grid;
|
|
8109
|
+
grid-auto-flow: column;
|
|
8110
|
+
grid-auto-columns: 14px;
|
|
8111
|
+
gap: 2px;
|
|
8112
|
+
margin-left: 34px;
|
|
8113
|
+
margin-bottom: 4px;
|
|
8114
|
+
font-size: 10px;
|
|
8115
|
+
color: var(--loki-text-muted);
|
|
8116
|
+
}
|
|
8117
|
+
|
|
8118
|
+
.heatmap-body {
|
|
8119
|
+
display: flex;
|
|
8120
|
+
gap: 4px;
|
|
8121
|
+
}
|
|
8122
|
+
|
|
8123
|
+
.heatmap-day-labels {
|
|
8124
|
+
display: grid;
|
|
8125
|
+
grid-template-rows: repeat(7, 14px);
|
|
8126
|
+
gap: 2px;
|
|
8127
|
+
font-size: 10px;
|
|
8128
|
+
color: var(--loki-text-muted);
|
|
8129
|
+
line-height: 14px;
|
|
8130
|
+
text-align: right;
|
|
8131
|
+
width: 30px;
|
|
8132
|
+
flex-shrink: 0;
|
|
8133
|
+
}
|
|
8134
|
+
|
|
8135
|
+
.heatmap-grid {
|
|
8136
|
+
display: grid;
|
|
8137
|
+
grid-template-rows: repeat(7, 14px);
|
|
8138
|
+
grid-auto-flow: column;
|
|
8139
|
+
grid-auto-columns: 14px;
|
|
8140
|
+
gap: 2px;
|
|
8141
|
+
}
|
|
8142
|
+
|
|
8143
|
+
.heatmap-cell {
|
|
8144
|
+
width: 12px;
|
|
8145
|
+
height: 12px;
|
|
8146
|
+
border-radius: 2px;
|
|
8147
|
+
transition: opacity 0.15s;
|
|
8148
|
+
}
|
|
8149
|
+
|
|
8150
|
+
.heatmap-cell.level-0 { background: var(--loki-bg-tertiary); }
|
|
8151
|
+
.heatmap-cell.level-1 { background: var(--loki-accent); opacity: 0.25; }
|
|
8152
|
+
.heatmap-cell.level-2 { background: var(--loki-accent); opacity: 0.50; }
|
|
8153
|
+
.heatmap-cell.level-3 { background: var(--loki-accent); opacity: 0.75; }
|
|
8154
|
+
.heatmap-cell.level-4 { background: var(--loki-accent); opacity: 1.0; }
|
|
8155
|
+
|
|
8156
|
+
.heatmap-legend {
|
|
8157
|
+
display: flex;
|
|
8158
|
+
align-items: center;
|
|
8159
|
+
gap: 4px;
|
|
8160
|
+
margin-top: 10px;
|
|
8161
|
+
margin-left: 34px;
|
|
8162
|
+
}
|
|
8163
|
+
|
|
8164
|
+
.heatmap-legend .heatmap-cell {
|
|
8165
|
+
width: 12px;
|
|
8166
|
+
height: 12px;
|
|
8167
|
+
}
|
|
8168
|
+
|
|
8169
|
+
.heatmap-legend-label {
|
|
8170
|
+
font-size: 10px;
|
|
8171
|
+
color: var(--loki-text-muted);
|
|
8172
|
+
}
|
|
8173
|
+
|
|
8174
|
+
/* ---------- Tool Usage ---------- */
|
|
8175
|
+
.tool-filter {
|
|
8176
|
+
margin-bottom: 12px;
|
|
8177
|
+
}
|
|
8178
|
+
|
|
8179
|
+
.tool-time-select {
|
|
8180
|
+
padding: 5px 10px;
|
|
8181
|
+
background: var(--loki-bg-tertiary);
|
|
8182
|
+
border: 1px solid var(--loki-border);
|
|
8183
|
+
border-radius: 6px;
|
|
8184
|
+
font-size: 12px;
|
|
8185
|
+
font-family: inherit;
|
|
8186
|
+
color: var(--loki-text-primary);
|
|
8187
|
+
cursor: pointer;
|
|
8188
|
+
}
|
|
8189
|
+
|
|
8190
|
+
.tool-bars {
|
|
8191
|
+
display: flex;
|
|
8192
|
+
flex-direction: column;
|
|
8193
|
+
gap: 6px;
|
|
8194
|
+
}
|
|
8195
|
+
|
|
8196
|
+
.tool-row {
|
|
8197
|
+
display: grid;
|
|
8198
|
+
grid-template-columns: 140px 1fr 50px;
|
|
8199
|
+
align-items: center;
|
|
8200
|
+
gap: 10px;
|
|
8201
|
+
}
|
|
8202
|
+
|
|
8203
|
+
.tool-name {
|
|
8204
|
+
font-size: 12px;
|
|
8205
|
+
font-family: 'JetBrains Mono', monospace;
|
|
8206
|
+
color: var(--loki-text-primary);
|
|
8207
|
+
white-space: nowrap;
|
|
8208
|
+
overflow: hidden;
|
|
8209
|
+
text-overflow: ellipsis;
|
|
8210
|
+
}
|
|
8211
|
+
|
|
8212
|
+
.tool-bar-track {
|
|
8213
|
+
height: 8px;
|
|
8214
|
+
background: var(--loki-bg-tertiary);
|
|
8215
|
+
border-radius: 4px;
|
|
8216
|
+
overflow: hidden;
|
|
8217
|
+
}
|
|
8218
|
+
|
|
8219
|
+
.tool-bar-fill {
|
|
8220
|
+
height: 100%;
|
|
8221
|
+
background: var(--loki-accent);
|
|
8222
|
+
border-radius: 4px;
|
|
8223
|
+
transition: width 0.3s ease;
|
|
8224
|
+
}
|
|
8225
|
+
|
|
8226
|
+
.tool-count {
|
|
8227
|
+
font-size: 12px;
|
|
8228
|
+
font-family: 'JetBrains Mono', monospace;
|
|
8229
|
+
color: var(--loki-text-muted);
|
|
8230
|
+
text-align: right;
|
|
8231
|
+
}
|
|
8232
|
+
|
|
8233
|
+
/* ---------- Velocity ---------- */
|
|
8234
|
+
.velocity-cards {
|
|
8235
|
+
display: grid;
|
|
8236
|
+
grid-template-columns: repeat(2, 1fr);
|
|
8237
|
+
gap: 12px;
|
|
8238
|
+
margin-bottom: 16px;
|
|
8239
|
+
}
|
|
8240
|
+
|
|
8241
|
+
.velocity-card {
|
|
8242
|
+
background: var(--loki-bg-secondary);
|
|
8243
|
+
border: 1px solid var(--loki-border-light);
|
|
8244
|
+
border-radius: 6px;
|
|
8245
|
+
padding: 16px;
|
|
8246
|
+
}
|
|
8247
|
+
|
|
8248
|
+
.velocity-label {
|
|
8249
|
+
font-size: 10px;
|
|
8250
|
+
font-weight: 600;
|
|
8251
|
+
text-transform: uppercase;
|
|
8252
|
+
letter-spacing: 0.05em;
|
|
8253
|
+
color: var(--loki-text-muted);
|
|
8254
|
+
margin-bottom: 6px;
|
|
8255
|
+
}
|
|
8256
|
+
|
|
8257
|
+
.velocity-value {
|
|
8258
|
+
font-size: 28px;
|
|
8259
|
+
font-weight: 600;
|
|
8260
|
+
font-family: 'JetBrains Mono', monospace;
|
|
8261
|
+
color: var(--loki-accent);
|
|
8262
|
+
line-height: 1.2;
|
|
8263
|
+
}
|
|
8264
|
+
|
|
8265
|
+
.sparkline-container {
|
|
8266
|
+
background: var(--loki-bg-secondary);
|
|
8267
|
+
border: 1px solid var(--loki-border-light);
|
|
8268
|
+
border-radius: 6px;
|
|
8269
|
+
padding: 16px;
|
|
8270
|
+
}
|
|
8271
|
+
|
|
8272
|
+
.sparkline-label {
|
|
8273
|
+
font-size: 10px;
|
|
8274
|
+
font-weight: 600;
|
|
8275
|
+
text-transform: uppercase;
|
|
8276
|
+
letter-spacing: 0.05em;
|
|
8277
|
+
color: var(--loki-text-muted);
|
|
8278
|
+
margin-bottom: 10px;
|
|
8279
|
+
}
|
|
8280
|
+
|
|
8281
|
+
.sparkline {
|
|
8282
|
+
display: flex;
|
|
8283
|
+
align-items: flex-end;
|
|
8284
|
+
gap: 2px;
|
|
8285
|
+
height: 60px;
|
|
8286
|
+
}
|
|
8287
|
+
|
|
8288
|
+
.spark-bar {
|
|
8289
|
+
flex: 1;
|
|
8290
|
+
min-width: 4px;
|
|
8291
|
+
background: var(--loki-accent);
|
|
8292
|
+
border-radius: 2px 2px 0 0;
|
|
8293
|
+
opacity: 0.7;
|
|
8294
|
+
transition: opacity 0.15s;
|
|
8295
|
+
}
|
|
8296
|
+
|
|
8297
|
+
.spark-bar:hover {
|
|
8298
|
+
opacity: 1;
|
|
8299
|
+
}
|
|
8300
|
+
|
|
8301
|
+
/* ---------- Provider Comparison ---------- */
|
|
8302
|
+
.provider-grid {
|
|
8303
|
+
display: grid;
|
|
8304
|
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
8305
|
+
gap: 12px;
|
|
8306
|
+
}
|
|
8307
|
+
|
|
8308
|
+
.provider-card {
|
|
8309
|
+
background: var(--loki-glass-bg);
|
|
8310
|
+
backdrop-filter: blur(12px) saturate(1.3);
|
|
8311
|
+
-webkit-backdrop-filter: blur(12px) saturate(1.3);
|
|
8312
|
+
border: 1px solid var(--loki-glass-border);
|
|
8313
|
+
border-radius: 8px;
|
|
8314
|
+
overflow: hidden;
|
|
8315
|
+
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
|
8316
|
+
}
|
|
8317
|
+
|
|
8318
|
+
.provider-card:hover {
|
|
8319
|
+
transform: translateY(-2px);
|
|
8320
|
+
box-shadow: var(--loki-glass-shadow);
|
|
8321
|
+
}
|
|
8322
|
+
|
|
8323
|
+
.provider-accent {
|
|
8324
|
+
height: 3px;
|
|
8325
|
+
width: 100%;
|
|
8326
|
+
}
|
|
8327
|
+
|
|
8328
|
+
.provider-body {
|
|
8329
|
+
padding: 16px;
|
|
8330
|
+
}
|
|
8331
|
+
|
|
8332
|
+
.provider-name {
|
|
8333
|
+
font-size: 16px;
|
|
8334
|
+
font-weight: 600;
|
|
8335
|
+
color: var(--loki-text-primary);
|
|
8336
|
+
margin-bottom: 12px;
|
|
8337
|
+
}
|
|
8338
|
+
|
|
8339
|
+
.provider-stat {
|
|
8340
|
+
display: flex;
|
|
8341
|
+
justify-content: space-between;
|
|
8342
|
+
align-items: center;
|
|
8343
|
+
padding: 4px 0;
|
|
8344
|
+
}
|
|
8345
|
+
|
|
8346
|
+
.provider-stat-label {
|
|
8347
|
+
font-size: 11px;
|
|
8348
|
+
color: var(--loki-text-muted);
|
|
8349
|
+
}
|
|
8350
|
+
|
|
8351
|
+
.provider-stat-value {
|
|
8352
|
+
font-size: 12px;
|
|
8353
|
+
font-family: 'JetBrains Mono', monospace;
|
|
8354
|
+
font-weight: 500;
|
|
8355
|
+
color: var(--loki-text-primary);
|
|
8356
|
+
}
|
|
8357
|
+
|
|
8358
|
+
.provider-models {
|
|
8359
|
+
margin-top: 10px;
|
|
8360
|
+
padding-top: 8px;
|
|
8361
|
+
border-top: 1px solid var(--loki-border-light);
|
|
8362
|
+
font-size: 10px;
|
|
8363
|
+
font-family: 'JetBrains Mono', monospace;
|
|
8364
|
+
color: var(--loki-text-muted);
|
|
8365
|
+
}
|
|
8366
|
+
|
|
8367
|
+
@media (max-width: 600px) {
|
|
8368
|
+
.tool-row {
|
|
8369
|
+
grid-template-columns: 100px 1fr 40px;
|
|
8370
|
+
}
|
|
8371
|
+
.velocity-cards {
|
|
8372
|
+
grid-template-columns: 1fr;
|
|
8373
|
+
}
|
|
8374
|
+
.tab-btn span { display: none; }
|
|
8375
|
+
}
|
|
8376
|
+
</style>
|
|
8377
|
+
|
|
8378
|
+
<div class="analytics-container">
|
|
8379
|
+
${this._connected?"":'<div class="offline-notice">Connecting to analytics API...</div>'}
|
|
8380
|
+
|
|
8381
|
+
<div class="tab-bar">
|
|
8382
|
+
${t.map(a=>`
|
|
8383
|
+
<button class="tab-btn ${this._activeTab===a.id?"active":""}" data-tab="${a.id}" aria-label="${a.label}">
|
|
8384
|
+
${a.icon}<span>${a.label}</span>
|
|
8385
|
+
</button>
|
|
8386
|
+
`).join("")}
|
|
8387
|
+
</div>
|
|
8388
|
+
|
|
8389
|
+
<div class="tab-content">
|
|
8390
|
+
${e}
|
|
8391
|
+
</div>
|
|
8392
|
+
</div>
|
|
8393
|
+
`,this.shadowRoot.querySelectorAll("[data-tab]").forEach(a=>{a.addEventListener("click",s=>this._handleTabClick(s))});let i=this.shadowRoot.getElementById("tool-time-range");i&&i.addEventListener("change",a=>this._handleTimeRangeChange(a))}};customElements.get("loki-analytics")||customElements.define("loki-analytics",at);var Ot="1.3.0";function Nt(c={}){return c.theme?b.setTheme(c.theme):c.autoDetectContext!==!1?b.init():D.init(),c.apiUrl&&g({baseUrl:c.apiUrl}),{theme:b.getTheme(),context:b.detectContext()}}return Lt(qt);})();
|
|
7934
8394
|
|
|
7935
8395
|
|
|
7936
8396
|
// Initialize dashboard when DOM is ready
|
|
@@ -7989,7 +8449,8 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
7989
8449
|
'session-diff',
|
|
7990
8450
|
'prompt-optimizer',
|
|
7991
8451
|
'quality-score',
|
|
7992
|
-
'migration-dashboard'
|
|
8452
|
+
'migration-dashboard',
|
|
8453
|
+
'analytics-dashboard'
|
|
7993
8454
|
];
|
|
7994
8455
|
components.forEach(function(id) {
|
|
7995
8456
|
var el = document.getElementById(id);
|
|
@@ -8073,7 +8534,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
8073
8534
|
document.addEventListener('keydown', function(e) {
|
|
8074
8535
|
if ((e.metaKey || e.ctrlKey) && ((e.key >= '1' && e.key <= '9') || e.key === '0')) {
|
|
8075
8536
|
e.preventDefault();
|
|
8076
|
-
var sections = ['overview', 'insights', 'prd-checklist', 'app-runner', 'council', 'quality', 'cost', 'checkpoint', 'context', 'notifications', 'migration'];
|
|
8537
|
+
var sections = ['overview', 'insights', 'prd-checklist', 'app-runner', 'council', 'quality', 'cost', 'checkpoint', 'context', 'notifications', 'migration', 'analytics'];
|
|
8077
8538
|
var idx = e.key === '0' ? 9 : parseInt(e.key) - 1;
|
|
8078
8539
|
if (idx < sections.length) switchSection(sections[idx]);
|
|
8079
8540
|
}
|
|
@@ -8133,6 +8594,12 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
8133
8594
|
switchSection('migration');
|
|
8134
8595
|
break;
|
|
8135
8596
|
|
|
8597
|
+
// Analytics page
|
|
8598
|
+
case 'a':
|
|
8599
|
+
e.preventDefault();
|
|
8600
|
+
switchSection('analytics');
|
|
8601
|
+
break;
|
|
8602
|
+
|
|
8136
8603
|
// Help overlay
|
|
8137
8604
|
case '?':
|
|
8138
8605
|
e.preventDefault();
|