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.
@@ -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 H(){return`
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: ${S.none};
745
- --loki-radius-sm: ${S.sm};
746
- --loki-radius-md: ${S.md};
747
- --loki-radius-lg: ${S.lg};
748
- --loki-radius-xl: ${S.xl};
749
- --loki-radius-full: ${S.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: ${b.fontFamily.sans};
753
- --loki-font-serif: ${b.fontFamily.serif};
754
- --loki-font-mono: ${b.fontFamily.mono};
755
- --loki-text-xs: ${b.fontSize.xs};
756
- --loki-text-sm: ${b.fontSize.sm};
757
- --loki-text-base: ${b.fontSize.base};
758
- --loki-text-md: ${b.fontSize.md};
759
- --loki-text-lg: ${b.fontSize.lg};
760
- --loki-text-xl: ${b.fontSize.xl};
761
- --loki-text-2xl: ${b.fontSize["2xl"]};
762
- --loki-text-3xl: ${b.fontSize["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: ${T.duration.fast};
766
- --loki-duration-normal: ${T.duration.normal};
767
- --loki-duration-slow: ${T.duration.slow};
768
- --loki-easing-default: ${T.easing.default};
769
- --loki-transition: ${T.duration.normal} ${T.easing.default};
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: ${rt.md}) {
1072
+ @media (max-width: ${ot.md}) {
1060
1073
  .hide-mobile { display: none !important; }
1061
1074
  }
1062
1075
 
1063
- @media (min-width: ${rt.md}) {
1076
+ @media (min-width: ${ot.md}) {
1064
1077
  .hide-desktop { display: none !important; }
1065
1078
  }
1066
- `,h=class h{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(h.detectContext()==="vscode"){let i=h.detectVSCodeTheme();return i==="high-contrast"?"high-contrast":i==="dark"?"vscode-dark":"vscode-light"}let e=localStorage.getItem(h.STORAGE_KEY);return e&&k[e]?e:window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}static setTheme(t){if(!k[t]){console.warn(`Unknown theme: ${t}`);return}localStorage.setItem(h.STORAGE_KEY,t),document.documentElement.setAttribute("data-loki-theme",t),window.dispatchEvent(new CustomEvent("loki-theme-change",{detail:{theme:t,context:h.detectContext()}}))}static toggle(){let t=h.getTheme(),e;return t.includes("dark")||t==="high-contrast"?e=t.startsWith("vscode")?"vscode-light":"light":e=t.startsWith("vscode")?"vscode-dark":"dark",h.setTheme(e),e}static getVariables(t=null){let e=t||h.getTheme();return k[e]||k.light}static generateCSS(t=null){let e=t||h.getTheme();return`
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
- ${f(e)}
1069
- ${H()}
1081
+ ${x(e)}
1082
+ ${R()}
1070
1083
  }
1071
1084
  ${B}
1072
- `}static init(){let t=h.getTheme();document.documentElement.setAttribute("data-loki-theme",t),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",()=>{localStorage.getItem(h.STORAGE_KEY)||h.setTheme(h.getTheme())}),h.detectContext()==="vscode"&&new MutationObserver(()=>{let i=h.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(h,"STORAGE_KEY","loki-theme"),w(h,"CONTEXT_KEY","loki-context");var m=h,P=class{constructor(){this._handlers=new Map,this._enabled=!0}register(t,e){let i=ot[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,d=t.shiftKey===r,g=t.altKey===o;return n&&d&&g}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 lt={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)"}},ut=`
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 m.getTheme()}static setTheme(t){m.setTheme(t)}static toggle(){return m.toggle()}static getVariables(t=null){let e=t||I.getTheme();return k[e]||lt[e]||lt.light}static toCSSString(t=null){let e=t||I.getTheme();if(k[e])return f(e);let i=I.getVariables(e);return Object.entries(i).map(([a,s])=>`${a}: ${s};`).join(`
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(){m.init()}static detectContext(){return m.detectContext()}static getAvailableThemes(){return Object.keys(k)}};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`
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
- ${H()}
1185
+ ${R()}
1173
1186
  }
1174
1187
 
1175
1188
  /* Light theme (default) */
1176
1189
  :host {
1177
- ${f("light")}
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
- ${f("dark")}
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
- ${f("dark")}
1203
+ ${x("dark")}
1191
1204
  }
1192
1205
 
1193
1206
  :host([theme="light"]),
1194
1207
  :host([data-loki-theme="light"]) {
1195
- ${f("light")}
1208
+ ${x("light")}
1196
1209
  }
1197
1210
 
1198
1211
  :host([theme="high-contrast"]),
1199
1212
  :host([data-loki-theme="high-contrast"]) {
1200
- ${f("high-contrast")}
1213
+ ${x("high-contrast")}
1201
1214
  }
1202
1215
 
1203
1216
  :host([theme="vscode-light"]),
1204
1217
  :host([data-loki-theme="vscode-light"]) {
1205
- ${f("vscode-light")}
1218
+ ${x("vscode-light")}
1206
1219
  }
1207
1220
 
1208
1221
  :host([theme="vscode-dark"]),
1209
1222
  :host([data-loki-theme="vscode-dark"]) {
1210
- ${f("vscode-dark")}
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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_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)),d=this._escapeHtml((this._data.complexity||"STANDARD").toUpperCase());this.shadowRoot.innerHTML=`
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">${d}</div>
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 Lt=[{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(l.TASK_CREATED,this._onTaskEvent),this._api.removeEventListener(l.TASK_UPDATED,this._onTaskEvent),this._api.removeEventListener(l.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=u({baseUrl:t}),this._onTaskEvent&&(this._api.removeEventListener(l.TASK_CREATED,this._onTaskEvent),this._api.removeEventListener(l.TASK_UPDATED,this._onTaskEvent),this._api.removeEventListener(l.TASK_DELETED,this._onTaskEvent)),this._onTaskEvent=()=>this._loadTasks(),this._api.addEventListener(l.TASK_CREATED,this._onTaskEvent),this._api.addEventListener(l.TASK_UPDATED,this._onTaskEvent),this._api.addEventListener(l.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=`
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
- ${Lt.map(s=>{let r=this._getTasksByStatus(s.status);return`
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(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(),t==="compact"&&this.render())}_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._status.connected=!0,this.render()},this._disconnectedHandler=()=>{this._status.connected=!1,this._status.mode="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=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=`
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 bt={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(l.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=u({baseUrl:t}),this._logMessageHandler=e=>this._addLog(e.detail),this._api.addEventListener(l.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(`
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=bt[i.level]||bt.info;return`
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 It=[{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=u({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:
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
- ${It.map((i,a)=>`
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),d=o.key==="ArrowRight"?(r+1)%n.length:(r-1+n.length)%n.length;n[d].focus(),this._setTab(n[d].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 Dt=[{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}],zt=[{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"}],Pt=[{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"}],G=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=u({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`
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
- ${Dt.map(t=>`
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
- ${zt.map(t=>`
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
- ${Pt.map(t=>`
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,d)=>{let g=s+d/(t.length-1||1)*(a-s*2),v=i-s-n.count/(e||1)*(i-s*2);return`${g},${v}`}).join(" "),o=`${s},${i-s} ${r} ${a-s},${i-s}`;return`
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,d)=>{let g=s+d/(t.length-1||1)*(a-s*2),v=i-s-n.count/(e||1)*(i-s*2);return`<circle cx="${g}" cy="${v}" r="3" fill="var(--loki-accent)" />`}).join("")}
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,d=this._findItemData(o,n);d&&this._selectMetric(o,d)}),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",G);var Rt=[{id:"overview",label:"Overview"},{id:"decisions",label:"Decision Log"},{id:"convergence",label:"Convergence"},{id:"agents",label:"Agents"}],J=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=u({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=`
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
- ${Rt.map(e=>`
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,d=r.dataset.agentId;n==="pause"?this._pauseAgent(d):n==="kill"?this._killAgent(d):n==="resume"&&this._resumeAgent(d)})}))})}),t}_formatTime(t){if(!t)return"";try{return new Date(t).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}catch{return t}}_getStyles(){return`
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",J);var ft={critical:0,major:1,minor:2},Mt={critical:"var(--loki-status-error, #ef4444)",major:"var(--loki-status-warning, #f59e0b)",minor:"var(--loki-text-muted, #71717a)"},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._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=u({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`
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)=>(ft[i.priority]??2)-(ft[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=Mt[s],o=i.verification||[],n=this._getWaiverForItem(i.id),d=!!n,g=i.status==="failing"&&(s==="critical"||s==="major"),v=d?`<span class="item-waived-badge" title="${this._escapeHtml(n.reason||"No reason provided")}">WAIVED</span>`:"",x="";return g&&(d?x=`<button class="waiver-btn waiver-btn-unwaive" data-unwaive-id="${this._escapeHtml(i.id)}">Unwaive</button>`:x=`<button class="waiver-btn" data-waive-id="${this._escapeHtml(i.id)}">Waive</button>`),`
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(_=>`<div class="v-dot ${_.passed===!0?"v-dot-pass":_.passed===!1?"v-dot-fail":"v-dot-pending"}" title="${this._escapeHtml(_.type||"")}"></div>`).join("")}
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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}};customElements.define("loki-checklist-viewer",K);var kt={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}},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._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=u({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`
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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}};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=kt[e]||kt.not_initialized;return`
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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}};customElements.define("loki-app-status",V);var Ht={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"}},Y=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={...Ht}}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=u({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`
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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}};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",Y);var W=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=u({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=`
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",W);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=u({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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_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`
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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_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,d=r.compacted===!0;a.has(r.iteration)&&(s+=`
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 ${d?"compacted":""}">
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,d=s.cache_creation_tokens||0,g=r+o+n+d,v=e>0?r/e*100:0,x=e>0?o/e*100:0,_=e>0?n/e*100:0,M=e>0?d/e*100:0;a+=`
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: ${v.toFixed(1)}%"></div>
5876
- <div class="breakdown-bar bar-output" style="width: ${x.toFixed(1)}%"></div>
5877
- <div class="breakdown-bar bar-cache-read" style="width: ${_.toFixed(1)}%"></div>
5878
- <div class="breakdown-bar bar-cache-create" style="width: ${M.toFixed(1)}%"></div>
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 pt={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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getSeverityColor(t){return pt[t]||pt.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`
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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_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: ${pt.critical}">${i}</div>
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=u({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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_toggleDecision(t){this._expandedDecisions.has(t)?this._expandedDecisions.delete(t):this._expandedDecisions.add(t),this.render()}render(){let t=`
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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_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(d=>`<li class="highlight-item">${this._escapeHtml(d)}</li>`).join("")}
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((d,g)=>{let v=this._expandedDecisions.has(g);return`
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="${g}">
6880
- <span class="decision-arrow ${v?"expanded":""}">&#9654;</span>
6881
- ${this._escapeHtml(d.title||d.decision||"Decision")}
6892
+ <button class="decision-header" data-index="${h}">
6893
+ <span class="decision-arrow ${u?"expanded":""}">&#9654;</span>
6894
+ ${this._escapeHtml(l.title||l.decision||"Decision")}
6882
6895
  </button>
6883
- ${v?`<div class="decision-reasoning">${this._escapeHtml(d.reasoning||d.rationale||"No reasoning provided")}</div>`:""}
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(d=>{d.addEventListener("click",()=>{this._toggleDecision(parseInt(d.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=u({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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_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=`
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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_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((d,g)=>{let v=this._expandedChanges.has(g);return`
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="${g}">
7134
- <span class="change-arrow ${v?"expanded":""}">&#9654;</span>
7135
- ${this._escapeHtml(d.description||d.title||"Change")}
7146
+ <button class="change-header" data-index="${h}">
7147
+ <span class="change-arrow ${u?"expanded":""}">&#9654;</span>
7148
+ ${this._escapeHtml(l.description||l.title||"Change")}
7136
7149
  </button>
7137
- ${v?`<div class="change-rationale">${this._escapeHtml(d.rationale||d.reasoning||"No rationale provided")}</div>`:""}
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(d=>{d.addEventListener("click",()=>{this._toggleChange(parseInt(d.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=u({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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_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(g=>typeof g=="number"?g:g.score||0),i=Math.min(...e),s=Math.max(...e)-i||1,r=120,o=32,n=2,d=e.map((g,v)=>{let x=n+v/(e.length-1)*(r-n*2),_=n+(1-(g-i)/s)*(o-n*2);return`${x},${_}`}).join(" ");return`
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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_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="${d}" fill="none" stroke="var(--loki-accent)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
7172
- <circle cx="${d.split(" ").pop().split(",")[0]}" cy="${d.split(" ").pop().split(",")[1]}" r="2.5" fill="var(--loki-accent)"/>
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"],d={security:"Security",code_quality:"Code Quality",compliance:"Compliance",best_practices:"Best Practices"},g=n.map(y=>{let at=r[y]!=null?Math.round(r[y]):0,yt=at>=80?"var(--loki-success)":at>=60?"var(--loki-warning)":"var(--loki-error)";return`
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">${d[y]||y}</span>
7481
+ <span class="category-name">${l[y]||y}</span>
7469
7482
  <div class="progress-bar">
7470
- <div class="progress-fill" style="width:${at}%;background:${yt};"></div>
7483
+ <div class="progress-fill" style="width:${st}%;background:${wt};"></div>
7471
7484
  </div>
7472
- <span class="category-score">${at}</span>
7485
+ <span class="category-score">${st}</span>
7473
7486
  </div>
7474
- `}).join(""),x=[{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(""),_=this._renderSparkline(this._history);this.shadowRoot.innerHTML=`
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
- ${g}
7513
+ ${h}
7501
7514
  </div>
7502
7515
 
7503
- ${x?`
7516
+ ${v?`
7504
7517
  <div class="findings-section">
7505
7518
  <div class="section-label">Findings</div>
7506
- <div class="findings-row">${x}</div>
7519
+ <div class="findings-row">${v}</div>
7507
7520
  </div>
7508
7521
  `:""}
7509
7522
  </div>
7510
- `;let M=this.shadowRoot.getElementById("scan-btn");M&&M.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-score")||customElements.define("loki-quality-score",et);var xt=["understand","guardrail","migrate","verify"],_t={understand:"Understand",guardrail:"Guardrail",migrate:"Migrate",verify:"Verify"},Bt={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=u({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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;"):""}_getPhaseIcon(t,e,i){return(i||[]).includes(t)?"[x]":t===e?"[>]":"[ ]"}_getPhaseIndex(t){let e=xt.indexOf(t);return e>=0?e:0}_renderPhaseBar(t,e){let i=e||[];return xt.map(a=>{let s=i.includes(a),r=a===t,o=Bt[a],n=s?"1":r?"0.7":"0.2",d=this._getPhaseIcon(a,t,e);return`
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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;"):""}_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">${d}</span>
7515
- ${_t[a]}
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>${_t[o]||this._escapeHtml(o)}</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 Ft="1.3.0";function jt(c={}){return c.theme?m.setTheme(c.theme):c.autoDetectContext!==!1?m.init():D.init(),c.apiUrl&&u({baseUrl:c.apiUrl}),{theme:m.getTheme(),context:m.detectContext()}}return At(Ut);})();
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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;"):""}_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();