loki-mode 7.12.0 → 7.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -704,6 +704,10 @@
704
704
  <svg viewBox="0 0 24 24"><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
705
705
  Escalations
706
706
  </button>
707
+ <button class="nav-link" data-section="wiki" id="nav-wiki">
708
+ <svg viewBox="0 0 24 24"><path d="M4 19.5A2.5 2.5 0 016.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 014 19.5v-15A2.5 2.5 0 016.5 2z"/></svg>
709
+ Wiki
710
+ </button>
707
711
  </nav>
708
712
 
709
713
  <div class="sidebar-footer">
@@ -1152,6 +1156,14 @@
1152
1156
  </div>
1153
1157
  <loki-escalations id="escalations-panel"></loki-escalations>
1154
1158
  </div>
1159
+
1160
+ <!-- Wiki: auto-generated cited codebase wiki + Q&A (R5) -->
1161
+ <div class="section-page" id="page-wiki">
1162
+ <div class="section-page-header">
1163
+ <h2 class="section-page-title">Wiki</h2>
1164
+ </div>
1165
+ <loki-wiki-browser id="wiki-browser"></loki-wiki-browser>
1166
+ </div>
1155
1167
  </main>
1156
1168
  </div>
1157
1169
 
@@ -1196,7 +1208,7 @@
1196
1208
 
1197
1209
  <!-- Inlined JavaScript Bundle -->
1198
1210
  <script>
1199
- var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropertyDescriptor;var ie=Object.getOwnPropertyNames;var se=Object.prototype.hasOwnProperty;var re=(d,t,e)=>t in d?wt(d,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):d[t]=e;var oe=(d,t)=>{for(var e in t)wt(d,e,{get:t[e],enumerable:!0})},ne=(d,t,e,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of ie(t))!se.call(d,i)&&i!==e&&wt(d,i,{get:()=>t[i],enumerable:!(a=ae(t,i))||a.enumerable});return d};var le=d=>ne(wt({},"__esModule",{value:!0}),d);var C=(d,t,e)=>re(d,typeof t!="symbol"?t+"":t,e);var Be={};oe(Be,{ANIMATION:()=>L,ARIA_PATTERNS:()=>Ct,ApiEvents:()=>v,BASE_STYLES:()=>U,BREAKPOINTS:()=>$t,COMMON_STYLES:()=>Pt,KEYBOARD_SHORTCUTS:()=>Et,KeyboardHandler:()=>P,LokiActivityStream:()=>ht,LokiAgentLeaderboard:()=>kt,LokiAnalytics:()=>ot,LokiApiClient:()=>M,LokiApiKeys:()=>pt,LokiAppStatus:()=>Q,LokiAuditViewer:()=>ct,LokiChecklistViewer:()=>W,LokiCheckpointViewer:()=>Z,LokiContextTracker:()=>tt,LokiCostDashboard:()=>X,LokiCostWaterfall:()=>ft,LokiCouncilDashboard:()=>Y,LokiCouncilTranscripts:()=>yt,LokiElement:()=>h,LokiEscalations:()=>_t,LokiLearningDashboard:()=>V,LokiLogStream:()=>G,LokiManagedMemoryPanel:()=>xt,LokiMemoryBrowser:()=>K,LokiMemoryGraph:()=>bt,LokiMigrationDashboard:()=>rt,LokiNotificationCenter:()=>et,LokiOverview:()=>O,LokiPipelineView:()=>mt,LokiPromptOptimizer:()=>it,LokiProviderHealth:()=>gt,LokiQualityGates:()=>nt,LokiQualityScore:()=>st,LokiRarvTimeline:()=>lt,LokiRunManager:()=>dt,LokiSessionControl:()=>J,LokiSessionDiff:()=>at,LokiState:()=>N,LokiTaskBoard:()=>q,LokiTenantSwitcher:()=>ut,LokiTheme:()=>R,RADIUS:()=>I,SPACING:()=>A,STATE_CHANGE_EVENT:()=>Tt,THEMES:()=>E,THEME_VARIABLES:()=>St,TYPOGRAPHY:()=>y,UnifiedThemeManager:()=>_,VERSION:()=>He,Z_INDEX:()=>D,createApiClient:()=>jt,createStore:()=>Ut,generateThemeCSS:()=>$,generateTokensCSS:()=>j,getApiClient:()=>g,getState:()=>B,init:()=>Re});var E={light:{"--loki-bg-primary":"#FFFEFB","--loki-bg-secondary":"#F8F4F0","--loki-bg-tertiary":"#ECEAE3","--loki-bg-card":"#ffffff","--loki-bg-hover":"#F3EFE9","--loki-bg-active":"#E6E2DA","--loki-bg-overlay":"rgba(32, 21, 21, 0.5)","--loki-accent":"#553DE9","--loki-accent-hover":"#4432c4","--loki-accent-active":"#3828a0","--loki-accent-light":"#7B6BF0","--loki-accent-muted":"rgba(85, 61, 233, 0.10)","--loki-text-primary":"#201515","--loki-text-secondary":"#36342E","--loki-text-muted":"#939084","--loki-text-disabled":"#C5C0B1","--loki-text-inverse":"#ffffff","--loki-border":"#ECEAE3","--loki-border-light":"#C5C0B1","--loki-border-focus":"#553DE9","--loki-success":"#1FC5A8","--loki-success-muted":"rgba(31, 197, 168, 0.12)","--loki-warning":"#D4A03C","--loki-warning-muted":"rgba(212, 160, 60, 0.12)","--loki-error":"#C45B5B","--loki-error-muted":"rgba(196, 91, 91, 0.12)","--loki-info":"#2F71E3","--loki-info-muted":"rgba(47, 113, 227, 0.12)","--loki-green":"#1FC5A8","--loki-green-muted":"rgba(31, 197, 168, 0.12)","--loki-yellow":"#D4A03C","--loki-yellow-muted":"rgba(212, 160, 60, 0.12)","--loki-red":"#C45B5B","--loki-red-muted":"rgba(196, 91, 91, 0.12)","--loki-blue":"#2F71E3","--loki-blue-muted":"rgba(47, 113, 227, 0.12)","--loki-purple":"#553DE9","--loki-purple-muted":"rgba(85, 61, 233, 0.10)","--loki-opus":"#d97706","--loki-sonnet":"#553DE9","--loki-haiku":"#1FC5A8","--loki-shadow-sm":"0 1px 2px rgba(32, 21, 21, 0.04)","--loki-shadow-md":"0 4px 6px rgba(32, 21, 21, 0.06)","--loki-shadow-lg":"0 10px 15px rgba(32, 21, 21, 0.08)","--loki-shadow-focus":"0 0 0 3px rgba(85, 61, 233, 0.25)"},dark:{"--loki-bg-primary":"#1A0F2E","--loki-bg-secondary":"#140B24","--loki-bg-tertiary":"#251842","--loki-bg-card":"#1F1338","--loki-bg-hover":"#2A1F4A","--loki-bg-active":"#352A55","--loki-bg-overlay":"rgba(20, 11, 36, 0.85)","--loki-accent":"#7B6BF0","--loki-accent-hover":"#9488F5","--loki-accent-active":"#6258D0","--loki-accent-light":"#9488F5","--loki-accent-muted":"rgba(123, 107, 240, 0.18)","--loki-text-primary":"#F0ECF8","--loki-text-secondary":"#C0B8D0","--loki-text-muted":"#8B7FA8","--loki-text-disabled":"#5A4E78","--loki-text-inverse":"#1A0F2E","--loki-border":"#2A1F3E","--loki-border-light":"#3D3060","--loki-border-focus":"#7B6BF0","--loki-success":"#2ED8B6","--loki-success-muted":"rgba(46, 216, 182, 0.18)","--loki-warning":"#E8B84A","--loki-warning-muted":"rgba(232, 184, 74, 0.18)","--loki-error":"#E07070","--loki-error-muted":"rgba(224, 112, 112, 0.18)","--loki-info":"#5A9CF5","--loki-info-muted":"rgba(90, 156, 245, 0.18)","--loki-green":"#2ED8B6","--loki-green-muted":"rgba(46, 216, 182, 0.18)","--loki-yellow":"#E8B84A","--loki-yellow-muted":"rgba(232, 184, 74, 0.18)","--loki-red":"#E07070","--loki-red-muted":"rgba(224, 112, 112, 0.18)","--loki-blue":"#5A9CF5","--loki-blue-muted":"rgba(90, 156, 245, 0.18)","--loki-purple":"#9488F5","--loki-purple-muted":"rgba(148, 136, 245, 0.18)","--loki-opus":"#f59e0b","--loki-sonnet":"#7B6BF0","--loki-haiku":"#2ED8B6","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.4)","--loki-shadow-md":"0 4px 12px rgba(0, 0, 0, 0.5)","--loki-shadow-lg":"0 10px 25px rgba(0, 0, 0, 0.6)","--loki-shadow-focus":"0 0 0 3px rgba(123, 107, 240, 0.30)"},"high-contrast":{"--loki-bg-primary":"#000000","--loki-bg-secondary":"#0a0a0a","--loki-bg-tertiary":"#141414","--loki-bg-card":"#0a0a0a","--loki-bg-hover":"#1a1a1a","--loki-bg-active":"#242424","--loki-bg-overlay":"rgba(0, 0, 0, 0.9)","--loki-accent":"#c084fc","--loki-accent-hover":"#d8b4fe","--loki-accent-active":"#e9d5ff","--loki-accent-light":"#d8b4fe","--loki-accent-muted":"rgba(192, 132, 252, 0.25)","--loki-text-primary":"#ffffff","--loki-text-secondary":"#e0e0e0","--loki-text-muted":"#b0b0b0","--loki-text-disabled":"#666666","--loki-text-inverse":"#000000","--loki-border":"#ffffff","--loki-border-light":"#cccccc","--loki-border-focus":"#c084fc","--loki-success":"#4ade80","--loki-success-muted":"rgba(74, 222, 128, 0.25)","--loki-warning":"#fde047","--loki-warning-muted":"rgba(253, 224, 71, 0.25)","--loki-error":"#f87171","--loki-error-muted":"rgba(248, 113, 113, 0.25)","--loki-info":"#60a5fa","--loki-info-muted":"rgba(96, 165, 250, 0.25)","--loki-green":"#4ade80","--loki-green-muted":"rgba(74, 222, 128, 0.25)","--loki-yellow":"#fde047","--loki-yellow-muted":"rgba(253, 224, 71, 0.25)","--loki-red":"#f87171","--loki-red-muted":"rgba(248, 113, 113, 0.25)","--loki-blue":"#60a5fa","--loki-blue-muted":"rgba(96, 165, 250, 0.25)","--loki-purple":"#c084fc","--loki-purple-muted":"rgba(192, 132, 252, 0.25)","--loki-opus":"#fbbf24","--loki-sonnet":"#818cf8","--loki-haiku":"#34d399","--loki-shadow-sm":"none","--loki-shadow-md":"none","--loki-shadow-lg":"none","--loki-shadow-focus":"0 0 0 3px #c084fc"},"vscode-light":{"--loki-bg-primary":"var(--vscode-editor-background, #ffffff)","--loki-bg-secondary":"var(--vscode-sideBar-background, #f3f3f3)","--loki-bg-tertiary":"var(--vscode-input-background, #ffffff)","--loki-bg-card":"var(--vscode-editor-background, #ffffff)","--loki-bg-hover":"var(--vscode-list-hoverBackground, #e8e8e8)","--loki-bg-active":"var(--vscode-list-activeSelectionBackground, #0060c0)","--loki-bg-overlay":"rgba(0, 0, 0, 0.4)","--loki-accent":"var(--vscode-focusBorder, #0066cc)","--loki-accent-hover":"var(--vscode-button-hoverBackground, #0055aa)","--loki-accent-active":"var(--vscode-button-background, #007acc)","--loki-accent-light":"var(--vscode-focusBorder, #0066cc)","--loki-accent-muted":"var(--vscode-editor-selectionBackground, rgba(0, 102, 204, 0.2))","--loki-text-primary":"var(--vscode-foreground, #333333)","--loki-text-secondary":"var(--vscode-descriptionForeground, #717171)","--loki-text-muted":"var(--vscode-disabledForeground, #a0a0a0)","--loki-text-disabled":"var(--vscode-disabledForeground, #cccccc)","--loki-text-inverse":"var(--vscode-button-foreground, #ffffff)","--loki-border":"var(--vscode-widget-border, #c8c8c8)","--loki-border-light":"var(--vscode-widget-border, #e0e0e0)","--loki-border-focus":"var(--vscode-focusBorder, #0066cc)","--loki-success":"var(--vscode-testing-iconPassed, #388a34)","--loki-success-muted":"rgba(56, 138, 52, 0.15)","--loki-warning":"var(--vscode-editorWarning-foreground, #bf8803)","--loki-warning-muted":"rgba(191, 136, 3, 0.15)","--loki-error":"var(--vscode-errorForeground, #e51400)","--loki-error-muted":"rgba(229, 20, 0, 0.15)","--loki-info":"var(--vscode-editorInfo-foreground, #1a85ff)","--loki-info-muted":"rgba(26, 133, 255, 0.15)","--loki-green":"var(--vscode-testing-iconPassed, #388a34)","--loki-green-muted":"rgba(56, 138, 52, 0.15)","--loki-yellow":"var(--vscode-editorWarning-foreground, #bf8803)","--loki-yellow-muted":"rgba(191, 136, 3, 0.15)","--loki-red":"var(--vscode-errorForeground, #e51400)","--loki-red-muted":"rgba(229, 20, 0, 0.15)","--loki-blue":"var(--vscode-editorInfo-foreground, #1a85ff)","--loki-blue-muted":"rgba(26, 133, 255, 0.15)","--loki-purple":"#9333ea","--loki-purple-muted":"rgba(147, 51, 234, 0.15)","--loki-opus":"#d97706","--loki-sonnet":"#4f46e5","--loki-haiku":"#059669","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.05)","--loki-shadow-md":"0 2px 4px rgba(0, 0, 0, 0.1)","--loki-shadow-lg":"0 4px 8px rgba(0, 0, 0, 0.15)","--loki-shadow-focus":"0 0 0 2px var(--vscode-focusBorder, #0066cc)"},"vscode-dark":{"--loki-bg-primary":"var(--vscode-editor-background, #1e1e1e)","--loki-bg-secondary":"var(--vscode-sideBar-background, #252526)","--loki-bg-tertiary":"var(--vscode-input-background, #3c3c3c)","--loki-bg-card":"var(--vscode-editor-background, #1e1e1e)","--loki-bg-hover":"var(--vscode-list-hoverBackground, #2a2d2e)","--loki-bg-active":"var(--vscode-list-activeSelectionBackground, #094771)","--loki-bg-overlay":"rgba(0, 0, 0, 0.6)","--loki-accent":"var(--vscode-focusBorder, #007fd4)","--loki-accent-hover":"var(--vscode-button-hoverBackground, #1177bb)","--loki-accent-active":"var(--vscode-button-background, #0e639c)","--loki-accent-light":"var(--vscode-focusBorder, #007fd4)","--loki-accent-muted":"var(--vscode-editor-selectionBackground, rgba(0, 127, 212, 0.25))","--loki-text-primary":"var(--vscode-foreground, #cccccc)","--loki-text-secondary":"var(--vscode-descriptionForeground, #9d9d9d)","--loki-text-muted":"var(--vscode-disabledForeground, #6b6b6b)","--loki-text-disabled":"var(--vscode-disabledForeground, #4d4d4d)","--loki-text-inverse":"var(--vscode-button-foreground, #ffffff)","--loki-border":"var(--vscode-widget-border, #454545)","--loki-border-light":"var(--vscode-widget-border, #5a5a5a)","--loki-border-focus":"var(--vscode-focusBorder, #007fd4)","--loki-success":"var(--vscode-testing-iconPassed, #89d185)","--loki-success-muted":"rgba(137, 209, 133, 0.2)","--loki-warning":"var(--vscode-editorWarning-foreground, #cca700)","--loki-warning-muted":"rgba(204, 167, 0, 0.2)","--loki-error":"var(--vscode-errorForeground, #f48771)","--loki-error-muted":"rgba(244, 135, 113, 0.2)","--loki-info":"var(--vscode-editorInfo-foreground, #75beff)","--loki-info-muted":"rgba(117, 190, 255, 0.2)","--loki-green":"var(--vscode-testing-iconPassed, #89d185)","--loki-green-muted":"rgba(137, 209, 133, 0.2)","--loki-yellow":"var(--vscode-editorWarning-foreground, #cca700)","--loki-yellow-muted":"rgba(204, 167, 0, 0.2)","--loki-red":"var(--vscode-errorForeground, #f48771)","--loki-red-muted":"rgba(244, 135, 113, 0.2)","--loki-blue":"var(--vscode-editorInfo-foreground, #75beff)","--loki-blue-muted":"rgba(117, 190, 255, 0.2)","--loki-purple":"#c084fc","--loki-purple-muted":"rgba(192, 132, 252, 0.2)","--loki-opus":"#f59e0b","--loki-sonnet":"#818cf8","--loki-haiku":"#34d399","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.3)","--loki-shadow-md":"0 2px 4px rgba(0, 0, 0, 0.4)","--loki-shadow-lg":"0 4px 8px rgba(0, 0, 0, 0.5)","--loki-shadow-focus":"0 0 0 2px var(--vscode-focusBorder, #007fd4)"}},A={xs:"4px",sm:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"32px","3xl":"48px"},I={none:"0",sm:"2px",md:"4px",lg:"5px",xl:"5px",full:"9999px"},y={fontFamily:{sans:"'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif",serif:"'DM Serif Display', Georgia, 'Times New Roman', serif",mono:"'JetBrains Mono', 'Fira Code', 'SF Mono', Menlo, monospace"},fontSize:{xs:"10px",sm:"11px",base:"12px",md:"13px",lg:"14px",xl:"16px","2xl":"18px","3xl":"24px"},fontWeight:{normal:"400",medium:"500",semibold:"600",bold:"700"},lineHeight:{tight:"1.25",normal:"1.5",relaxed:"1.75"}},L={duration:{fast:"100ms",normal:"200ms",slow:"300ms",slower:"500ms"},easing:{default:"cubic-bezier(0.4, 0, 0.2, 1)",in:"cubic-bezier(0.4, 0, 1, 1)",out:"cubic-bezier(0, 0, 0.2, 1)",bounce:"cubic-bezier(0.68, -0.55, 0.265, 1.55)"}},$t={sm:"640px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},D={base:"0",dropdown:"100",sticky:"200",modal:"300",popover:"400",tooltip:"500",toast:"600"},Et={"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"]}},Ct={button:{role:"button",tabIndex:0},tablist:{role:"tablist"},tab:{role:"tab",ariaSelected:!1,tabIndex:-1},tabpanel:{role:"tabpanel",tabIndex:0},list:{role:"list"},listitem:{role:"listitem"},livePolite:{ariaLive:"polite",ariaAtomic:!0},liveAssertive:{ariaLive:"assertive",ariaAtomic:!0},dialog:{role:"dialog",ariaModal:!0},alertdialog:{role:"alertdialog",ariaModal:!0},status:{role:"status",ariaLive:"polite"},alert:{role:"alert",ariaLive:"assertive"},log:{role:"log",ariaLive:"polite",ariaRelevant:"additions"}};function $(d){let t=E[d];return t?Object.entries(t).map(([e,a])=>`${e}: ${a};`).join(`
1211
+ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropertyDescriptor;var se=Object.getOwnPropertyNames;var re=Object.prototype.hasOwnProperty;var oe=(d,t,e)=>t in d?$t(d,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):d[t]=e;var ne=(d,t)=>{for(var e in t)$t(d,e,{get:t[e],enumerable:!0})},le=(d,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of se(t))!re.call(d,a)&&a!==e&&$t(d,a,{get:()=>t[a],enumerable:!(i=ae(t,a))||i.enumerable});return d};var de=d=>le($t({},"__esModule",{value:!0}),d);var C=(d,t,e)=>oe(d,typeof t!="symbol"?t+"":t,e);var Me={};ne(Me,{ANIMATION:()=>L,ARIA_PATTERNS:()=>St,ApiEvents:()=>m,BASE_STYLES:()=>U,BREAKPOINTS:()=>Et,COMMON_STYLES:()=>Mt,KEYBOARD_SHORTCUTS:()=>Ct,KeyboardHandler:()=>P,LokiActivityStream:()=>ut,LokiAgentLeaderboard:()=>kt,LokiAnalytics:()=>ot,LokiApiClient:()=>M,LokiApiKeys:()=>pt,LokiAppStatus:()=>Q,LokiAuditViewer:()=>ct,LokiChecklistViewer:()=>W,LokiCheckpointViewer:()=>Z,LokiContextTracker:()=>tt,LokiCostDashboard:()=>X,LokiCostWaterfall:()=>ft,LokiCouncilDashboard:()=>Y,LokiCouncilTranscripts:()=>yt,LokiElement:()=>h,LokiEscalations:()=>_t,LokiLearningDashboard:()=>V,LokiLogStream:()=>G,LokiManagedMemoryPanel:()=>xt,LokiMemoryBrowser:()=>K,LokiMemoryGraph:()=>bt,LokiMigrationDashboard:()=>rt,LokiNotificationCenter:()=>et,LokiOverview:()=>O,LokiPipelineView:()=>vt,LokiPromptOptimizer:()=>at,LokiProviderHealth:()=>gt,LokiQualityGates:()=>nt,LokiQualityScore:()=>st,LokiRarvTimeline:()=>lt,LokiRunManager:()=>dt,LokiSessionControl:()=>J,LokiSessionDiff:()=>it,LokiState:()=>N,LokiTaskBoard:()=>q,LokiTenantSwitcher:()=>ht,LokiTheme:()=>R,LokiWikiBrowser:()=>wt,RADIUS:()=>I,SPACING:()=>A,STATE_CHANGE_EVENT:()=>It,THEMES:()=>E,THEME_VARIABLES:()=>At,TYPOGRAPHY:()=>y,UnifiedThemeManager:()=>_,VERSION:()=>Be,Z_INDEX:()=>D,createApiClient:()=>Ut,createStore:()=>Nt,generateThemeCSS:()=>$,generateTokensCSS:()=>j,getApiClient:()=>g,getState:()=>B,init:()=>Pe});var E={light:{"--loki-bg-primary":"#FFFEFB","--loki-bg-secondary":"#F8F4F0","--loki-bg-tertiary":"#ECEAE3","--loki-bg-card":"#ffffff","--loki-bg-hover":"#F3EFE9","--loki-bg-active":"#E6E2DA","--loki-bg-overlay":"rgba(32, 21, 21, 0.5)","--loki-accent":"#553DE9","--loki-accent-hover":"#4432c4","--loki-accent-active":"#3828a0","--loki-accent-light":"#7B6BF0","--loki-accent-muted":"rgba(85, 61, 233, 0.10)","--loki-text-primary":"#201515","--loki-text-secondary":"#36342E","--loki-text-muted":"#939084","--loki-text-disabled":"#C5C0B1","--loki-text-inverse":"#ffffff","--loki-border":"#ECEAE3","--loki-border-light":"#C5C0B1","--loki-border-focus":"#553DE9","--loki-success":"#1FC5A8","--loki-success-muted":"rgba(31, 197, 168, 0.12)","--loki-warning":"#D4A03C","--loki-warning-muted":"rgba(212, 160, 60, 0.12)","--loki-error":"#C45B5B","--loki-error-muted":"rgba(196, 91, 91, 0.12)","--loki-info":"#2F71E3","--loki-info-muted":"rgba(47, 113, 227, 0.12)","--loki-green":"#1FC5A8","--loki-green-muted":"rgba(31, 197, 168, 0.12)","--loki-yellow":"#D4A03C","--loki-yellow-muted":"rgba(212, 160, 60, 0.12)","--loki-red":"#C45B5B","--loki-red-muted":"rgba(196, 91, 91, 0.12)","--loki-blue":"#2F71E3","--loki-blue-muted":"rgba(47, 113, 227, 0.12)","--loki-purple":"#553DE9","--loki-purple-muted":"rgba(85, 61, 233, 0.10)","--loki-opus":"#d97706","--loki-sonnet":"#553DE9","--loki-haiku":"#1FC5A8","--loki-shadow-sm":"0 1px 2px rgba(32, 21, 21, 0.04)","--loki-shadow-md":"0 4px 6px rgba(32, 21, 21, 0.06)","--loki-shadow-lg":"0 10px 15px rgba(32, 21, 21, 0.08)","--loki-shadow-focus":"0 0 0 3px rgba(85, 61, 233, 0.25)"},dark:{"--loki-bg-primary":"#1A0F2E","--loki-bg-secondary":"#140B24","--loki-bg-tertiary":"#251842","--loki-bg-card":"#1F1338","--loki-bg-hover":"#2A1F4A","--loki-bg-active":"#352A55","--loki-bg-overlay":"rgba(20, 11, 36, 0.85)","--loki-accent":"#7B6BF0","--loki-accent-hover":"#9488F5","--loki-accent-active":"#6258D0","--loki-accent-light":"#9488F5","--loki-accent-muted":"rgba(123, 107, 240, 0.18)","--loki-text-primary":"#F0ECF8","--loki-text-secondary":"#C0B8D0","--loki-text-muted":"#8B7FA8","--loki-text-disabled":"#5A4E78","--loki-text-inverse":"#1A0F2E","--loki-border":"#2A1F3E","--loki-border-light":"#3D3060","--loki-border-focus":"#7B6BF0","--loki-success":"#2ED8B6","--loki-success-muted":"rgba(46, 216, 182, 0.18)","--loki-warning":"#E8B84A","--loki-warning-muted":"rgba(232, 184, 74, 0.18)","--loki-error":"#E07070","--loki-error-muted":"rgba(224, 112, 112, 0.18)","--loki-info":"#5A9CF5","--loki-info-muted":"rgba(90, 156, 245, 0.18)","--loki-green":"#2ED8B6","--loki-green-muted":"rgba(46, 216, 182, 0.18)","--loki-yellow":"#E8B84A","--loki-yellow-muted":"rgba(232, 184, 74, 0.18)","--loki-red":"#E07070","--loki-red-muted":"rgba(224, 112, 112, 0.18)","--loki-blue":"#5A9CF5","--loki-blue-muted":"rgba(90, 156, 245, 0.18)","--loki-purple":"#9488F5","--loki-purple-muted":"rgba(148, 136, 245, 0.18)","--loki-opus":"#f59e0b","--loki-sonnet":"#7B6BF0","--loki-haiku":"#2ED8B6","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.4)","--loki-shadow-md":"0 4px 12px rgba(0, 0, 0, 0.5)","--loki-shadow-lg":"0 10px 25px rgba(0, 0, 0, 0.6)","--loki-shadow-focus":"0 0 0 3px rgba(123, 107, 240, 0.30)"},"high-contrast":{"--loki-bg-primary":"#000000","--loki-bg-secondary":"#0a0a0a","--loki-bg-tertiary":"#141414","--loki-bg-card":"#0a0a0a","--loki-bg-hover":"#1a1a1a","--loki-bg-active":"#242424","--loki-bg-overlay":"rgba(0, 0, 0, 0.9)","--loki-accent":"#c084fc","--loki-accent-hover":"#d8b4fe","--loki-accent-active":"#e9d5ff","--loki-accent-light":"#d8b4fe","--loki-accent-muted":"rgba(192, 132, 252, 0.25)","--loki-text-primary":"#ffffff","--loki-text-secondary":"#e0e0e0","--loki-text-muted":"#b0b0b0","--loki-text-disabled":"#666666","--loki-text-inverse":"#000000","--loki-border":"#ffffff","--loki-border-light":"#cccccc","--loki-border-focus":"#c084fc","--loki-success":"#4ade80","--loki-success-muted":"rgba(74, 222, 128, 0.25)","--loki-warning":"#fde047","--loki-warning-muted":"rgba(253, 224, 71, 0.25)","--loki-error":"#f87171","--loki-error-muted":"rgba(248, 113, 113, 0.25)","--loki-info":"#60a5fa","--loki-info-muted":"rgba(96, 165, 250, 0.25)","--loki-green":"#4ade80","--loki-green-muted":"rgba(74, 222, 128, 0.25)","--loki-yellow":"#fde047","--loki-yellow-muted":"rgba(253, 224, 71, 0.25)","--loki-red":"#f87171","--loki-red-muted":"rgba(248, 113, 113, 0.25)","--loki-blue":"#60a5fa","--loki-blue-muted":"rgba(96, 165, 250, 0.25)","--loki-purple":"#c084fc","--loki-purple-muted":"rgba(192, 132, 252, 0.25)","--loki-opus":"#fbbf24","--loki-sonnet":"#818cf8","--loki-haiku":"#34d399","--loki-shadow-sm":"none","--loki-shadow-md":"none","--loki-shadow-lg":"none","--loki-shadow-focus":"0 0 0 3px #c084fc"},"vscode-light":{"--loki-bg-primary":"var(--vscode-editor-background, #ffffff)","--loki-bg-secondary":"var(--vscode-sideBar-background, #f3f3f3)","--loki-bg-tertiary":"var(--vscode-input-background, #ffffff)","--loki-bg-card":"var(--vscode-editor-background, #ffffff)","--loki-bg-hover":"var(--vscode-list-hoverBackground, #e8e8e8)","--loki-bg-active":"var(--vscode-list-activeSelectionBackground, #0060c0)","--loki-bg-overlay":"rgba(0, 0, 0, 0.4)","--loki-accent":"var(--vscode-focusBorder, #0066cc)","--loki-accent-hover":"var(--vscode-button-hoverBackground, #0055aa)","--loki-accent-active":"var(--vscode-button-background, #007acc)","--loki-accent-light":"var(--vscode-focusBorder, #0066cc)","--loki-accent-muted":"var(--vscode-editor-selectionBackground, rgba(0, 102, 204, 0.2))","--loki-text-primary":"var(--vscode-foreground, #333333)","--loki-text-secondary":"var(--vscode-descriptionForeground, #717171)","--loki-text-muted":"var(--vscode-disabledForeground, #a0a0a0)","--loki-text-disabled":"var(--vscode-disabledForeground, #cccccc)","--loki-text-inverse":"var(--vscode-button-foreground, #ffffff)","--loki-border":"var(--vscode-widget-border, #c8c8c8)","--loki-border-light":"var(--vscode-widget-border, #e0e0e0)","--loki-border-focus":"var(--vscode-focusBorder, #0066cc)","--loki-success":"var(--vscode-testing-iconPassed, #388a34)","--loki-success-muted":"rgba(56, 138, 52, 0.15)","--loki-warning":"var(--vscode-editorWarning-foreground, #bf8803)","--loki-warning-muted":"rgba(191, 136, 3, 0.15)","--loki-error":"var(--vscode-errorForeground, #e51400)","--loki-error-muted":"rgba(229, 20, 0, 0.15)","--loki-info":"var(--vscode-editorInfo-foreground, #1a85ff)","--loki-info-muted":"rgba(26, 133, 255, 0.15)","--loki-green":"var(--vscode-testing-iconPassed, #388a34)","--loki-green-muted":"rgba(56, 138, 52, 0.15)","--loki-yellow":"var(--vscode-editorWarning-foreground, #bf8803)","--loki-yellow-muted":"rgba(191, 136, 3, 0.15)","--loki-red":"var(--vscode-errorForeground, #e51400)","--loki-red-muted":"rgba(229, 20, 0, 0.15)","--loki-blue":"var(--vscode-editorInfo-foreground, #1a85ff)","--loki-blue-muted":"rgba(26, 133, 255, 0.15)","--loki-purple":"#9333ea","--loki-purple-muted":"rgba(147, 51, 234, 0.15)","--loki-opus":"#d97706","--loki-sonnet":"#4f46e5","--loki-haiku":"#059669","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.05)","--loki-shadow-md":"0 2px 4px rgba(0, 0, 0, 0.1)","--loki-shadow-lg":"0 4px 8px rgba(0, 0, 0, 0.15)","--loki-shadow-focus":"0 0 0 2px var(--vscode-focusBorder, #0066cc)"},"vscode-dark":{"--loki-bg-primary":"var(--vscode-editor-background, #1e1e1e)","--loki-bg-secondary":"var(--vscode-sideBar-background, #252526)","--loki-bg-tertiary":"var(--vscode-input-background, #3c3c3c)","--loki-bg-card":"var(--vscode-editor-background, #1e1e1e)","--loki-bg-hover":"var(--vscode-list-hoverBackground, #2a2d2e)","--loki-bg-active":"var(--vscode-list-activeSelectionBackground, #094771)","--loki-bg-overlay":"rgba(0, 0, 0, 0.6)","--loki-accent":"var(--vscode-focusBorder, #007fd4)","--loki-accent-hover":"var(--vscode-button-hoverBackground, #1177bb)","--loki-accent-active":"var(--vscode-button-background, #0e639c)","--loki-accent-light":"var(--vscode-focusBorder, #007fd4)","--loki-accent-muted":"var(--vscode-editor-selectionBackground, rgba(0, 127, 212, 0.25))","--loki-text-primary":"var(--vscode-foreground, #cccccc)","--loki-text-secondary":"var(--vscode-descriptionForeground, #9d9d9d)","--loki-text-muted":"var(--vscode-disabledForeground, #6b6b6b)","--loki-text-disabled":"var(--vscode-disabledForeground, #4d4d4d)","--loki-text-inverse":"var(--vscode-button-foreground, #ffffff)","--loki-border":"var(--vscode-widget-border, #454545)","--loki-border-light":"var(--vscode-widget-border, #5a5a5a)","--loki-border-focus":"var(--vscode-focusBorder, #007fd4)","--loki-success":"var(--vscode-testing-iconPassed, #89d185)","--loki-success-muted":"rgba(137, 209, 133, 0.2)","--loki-warning":"var(--vscode-editorWarning-foreground, #cca700)","--loki-warning-muted":"rgba(204, 167, 0, 0.2)","--loki-error":"var(--vscode-errorForeground, #f48771)","--loki-error-muted":"rgba(244, 135, 113, 0.2)","--loki-info":"var(--vscode-editorInfo-foreground, #75beff)","--loki-info-muted":"rgba(117, 190, 255, 0.2)","--loki-green":"var(--vscode-testing-iconPassed, #89d185)","--loki-green-muted":"rgba(137, 209, 133, 0.2)","--loki-yellow":"var(--vscode-editorWarning-foreground, #cca700)","--loki-yellow-muted":"rgba(204, 167, 0, 0.2)","--loki-red":"var(--vscode-errorForeground, #f48771)","--loki-red-muted":"rgba(244, 135, 113, 0.2)","--loki-blue":"var(--vscode-editorInfo-foreground, #75beff)","--loki-blue-muted":"rgba(117, 190, 255, 0.2)","--loki-purple":"#c084fc","--loki-purple-muted":"rgba(192, 132, 252, 0.2)","--loki-opus":"#f59e0b","--loki-sonnet":"#818cf8","--loki-haiku":"#34d399","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.3)","--loki-shadow-md":"0 2px 4px rgba(0, 0, 0, 0.4)","--loki-shadow-lg":"0 4px 8px rgba(0, 0, 0, 0.5)","--loki-shadow-focus":"0 0 0 2px var(--vscode-focusBorder, #007fd4)"}},A={xs:"4px",sm:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"32px","3xl":"48px"},I={none:"0",sm:"2px",md:"4px",lg:"5px",xl:"5px",full:"9999px"},y={fontFamily:{sans:"'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif",serif:"'DM Serif Display', Georgia, 'Times New Roman', serif",mono:"'JetBrains Mono', 'Fira Code', 'SF Mono', Menlo, monospace"},fontSize:{xs:"10px",sm:"11px",base:"12px",md:"13px",lg:"14px",xl:"16px","2xl":"18px","3xl":"24px"},fontWeight:{normal:"400",medium:"500",semibold:"600",bold:"700"},lineHeight:{tight:"1.25",normal:"1.5",relaxed:"1.75"}},L={duration:{fast:"100ms",normal:"200ms",slow:"300ms",slower:"500ms"},easing:{default:"cubic-bezier(0.4, 0, 0.2, 1)",in:"cubic-bezier(0.4, 0, 1, 1)",out:"cubic-bezier(0, 0, 0.2, 1)",bounce:"cubic-bezier(0.68, -0.55, 0.265, 1.55)"}},Et={sm:"640px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},D={base:"0",dropdown:"100",sticky:"200",modal:"300",popover:"400",tooltip:"500",toast:"600"},Ct={"navigation.nextItem":{key:"ArrowDown",modifiers:[]},"navigation.prevItem":{key:"ArrowUp",modifiers:[]},"navigation.nextSection":{key:"Tab",modifiers:[]},"navigation.prevSection":{key:"Tab",modifiers:["Shift"]},"navigation.confirm":{key:"Enter",modifiers:[]},"navigation.cancel":{key:"Escape",modifiers:[]},"action.refresh":{key:"r",modifiers:["Meta"]},"action.search":{key:"k",modifiers:["Meta"]},"action.save":{key:"s",modifiers:["Meta"]},"action.close":{key:"w",modifiers:["Meta"]},"theme.toggle":{key:"d",modifiers:["Meta","Shift"]},"task.create":{key:"n",modifiers:["Meta"]},"task.complete":{key:"Enter",modifiers:["Meta"]},"view.toggleLogs":{key:"l",modifiers:["Meta","Shift"]},"view.toggleMemory":{key:"m",modifiers:["Meta","Shift"]}},St={button:{role:"button",tabIndex:0},tablist:{role:"tablist"},tab:{role:"tab",ariaSelected:!1,tabIndex:-1},tabpanel:{role:"tabpanel",tabIndex:0},list:{role:"list"},listitem:{role:"listitem"},livePolite:{ariaLive:"polite",ariaAtomic:!0},liveAssertive:{ariaLive:"assertive",ariaAtomic:!0},dialog:{role:"dialog",ariaModal:!0},alertdialog:{role:"alertdialog",ariaModal:!0},status:{role:"status",ariaLive:"polite"},alert:{role:"alert",ariaLive:"assertive"},log:{role:"log",ariaLive:"polite",ariaRelevant:"additions"}};function $(d){let t=E[d];return t?Object.entries(t).map(([e,i])=>`${e}: ${i};`).join(`
1200
1212
  `):""}function j(){return`
1201
1213
  /* Spacing */
1202
1214
  --loki-space-xs: ${A.xs};
@@ -1523,20 +1535,20 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
1523
1535
  }
1524
1536
 
1525
1537
  /* Responsive utilities */
1526
- @media (max-width: ${$t.md}) {
1538
+ @media (max-width: ${Et.md}) {
1527
1539
  .hide-mobile { display: none !important; }
1528
1540
  }
1529
1541
 
1530
- @media (min-width: ${$t.md}) {
1542
+ @media (min-width: ${Et.md}) {
1531
1543
  .hide-desktop { display: none !important; }
1532
1544
  }
1533
- `,k=class k{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 a=e.match(/\d+/g);if(a)return(parseInt(a[0])*299+parseInt(a[1])*587+parseInt(a[2])*114)/1e3>128?"light":"dark"}return null}static getTheme(){if(k.detectContext()==="vscode"){let a=k.detectVSCodeTheme();return a==="high-contrast"?"high-contrast":a==="dark"?"vscode-dark":"vscode-light"}let e=localStorage.getItem(k.STORAGE_KEY);return e&&E[e]?e:window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}static setTheme(t){if(!E[t]){console.warn(`Unknown theme: ${t}`);return}localStorage.setItem(k.STORAGE_KEY,t),document.documentElement.setAttribute("data-loki-theme",t),window.dispatchEvent(new CustomEvent("loki-theme-change",{detail:{theme:t,context:k.detectContext()}}))}static toggle(){let t=k.getTheme(),e;return t.includes("dark")||t==="high-contrast"?e=t.startsWith("vscode")?"vscode-light":"light":e=t.startsWith("vscode")?"vscode-dark":"dark",k.setTheme(e),e}static getVariables(t=null){let e=t||k.getTheme();return E[e]||E.light}static generateCSS(t=null){let e=t||k.getTheme();return`
1545
+ `,k=class k{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(k.detectContext()==="vscode"){let i=k.detectVSCodeTheme();return i==="high-contrast"?"high-contrast":i==="dark"?"vscode-dark":"vscode-light"}let e=localStorage.getItem(k.STORAGE_KEY);return e&&E[e]?e:window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}static setTheme(t){if(!E[t]){console.warn(`Unknown theme: ${t}`);return}localStorage.setItem(k.STORAGE_KEY,t),document.documentElement.setAttribute("data-loki-theme",t),window.dispatchEvent(new CustomEvent("loki-theme-change",{detail:{theme:t,context:k.detectContext()}}))}static toggle(){let t=k.getTheme(),e;return t.includes("dark")||t==="high-contrast"?e=t.startsWith("vscode")?"vscode-light":"light":e=t.startsWith("vscode")?"vscode-dark":"dark",k.setTheme(e),e}static getVariables(t=null){let e=t||k.getTheme();return E[e]||E.light}static generateCSS(t=null){let e=t||k.getTheme();return`
1534
1546
  :host {
1535
1547
  ${$(e)}
1536
1548
  ${j()}
1537
1549
  }
1538
1550
  ${U}
1539
- `}static init(){let t=k.getTheme();document.documentElement.setAttribute("data-loki-theme",t),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",()=>{localStorage.getItem(k.STORAGE_KEY)||k.setTheme(k.getTheme())}),k.detectContext()==="vscode"&&new MutationObserver(()=>{let a=k.getTheme();document.documentElement.setAttribute("data-loki-theme",a),window.dispatchEvent(new CustomEvent("loki-theme-change",{detail:{theme:a,context:"vscode"}}))}).observe(document.body,{attributes:!0,attributeFilter:["class"]})}};C(k,"STORAGE_KEY","loki-theme"),C(k,"CONTEXT_KEY","loki-context");var _=k,P=class{constructor(){this._handlers=new Map,this._enabled=!0}register(t,e){let a=Et[t];if(!a){console.warn(`Unknown keyboard action: ${t}`);return}this._handlers.set(t,{shortcut:a,handler:e})}unregister(t){this._handlers.delete(t)}setEnabled(t){this._enabled=t}handleEvent(t){if(!this._enabled)return!1;for(let[e,{shortcut:a,handler:i}]of this._handlers)if(this._matchesShortcut(t,a))return t.preventDefault(),t.stopPropagation(),i(t),!0;return!1}_matchesShortcut(t,e){let a=t.key.toLowerCase(),i=e.modifiers||[];if(a!==e.key.toLowerCase())return!1;let s=i.includes("Ctrl")||i.includes("Meta"),r=i.includes("Shift"),o=i.includes("Alt"),n=(t.ctrlKey||t.metaKey)===s,l=t.shiftKey===r,c=t.altKey===o;return n&&l&&c}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 St={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)"}},Pt=`
1551
+ `}static init(){let t=k.getTheme();document.documentElement.setAttribute("data-loki-theme",t),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",()=>{localStorage.getItem(k.STORAGE_KEY)||k.setTheme(k.getTheme())}),k.detectContext()==="vscode"&&new MutationObserver(()=>{let i=k.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"]})}};C(k,"STORAGE_KEY","loki-theme"),C(k,"CONTEXT_KEY","loki-context");var _=k,P=class{constructor(){this._handlers=new Map,this._enabled=!0}register(t,e){let i=Ct[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,c=t.altKey===o;return n&&l&&c}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 At={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)"}},Mt=`
1540
1552
  :host {
1541
1553
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
1542
1554
  line-height: 1.5;
@@ -1632,8 +1644,8 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
1632
1644
  ::-webkit-scrollbar-track { background: var(--loki-bg-primary); }
1633
1645
  ::-webkit-scrollbar-thumb { background: var(--loki-border); border-radius: 3px; }
1634
1646
  ::-webkit-scrollbar-thumb:hover { background: var(--loki-border-light); }
1635
- `,H=class H{static getTheme(){return _.getTheme()}static setTheme(t){_.setTheme(t)}static toggle(){return _.toggle()}static getVariables(t=null){let e=t||H.getTheme();return E[e]||St[e]||St.light}static toCSSString(t=null){let e=t||H.getTheme();if(E[e])return $(e);let a=H.getVariables(e);return Object.entries(a).map(([i,s])=>`${i}: ${s};`).join(`
1636
- `)}static applyToElement(t,e=null){let a=H.getVariables(e);for(let[i,s]of Object.entries(a))t.style.setProperty(i,s)}static init(){_.init()}static detectContext(){return _.detectContext()}static getAvailableThemes(){return Object.keys(E)}};C(H,"STORAGE_KEY","loki-theme");var R=H,h=class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}),this._theme=R.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(){R.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`
1647
+ `,H=class H{static getTheme(){return _.getTheme()}static setTheme(t){_.setTheme(t)}static toggle(){return _.toggle()}static getVariables(t=null){let e=t||H.getTheme();return E[e]||At[e]||At.light}static toCSSString(t=null){let e=t||H.getTheme();if(E[e])return $(e);let i=H.getVariables(e);return Object.entries(i).map(([a,s])=>`${a}: ${s};`).join(`
1648
+ `)}static applyToElement(t,e=null){let i=H.getVariables(e);for(let[a,s]of Object.entries(i))t.style.setProperty(a,s)}static init(){_.init()}static detectContext(){return _.detectContext()}static getAvailableThemes(){return Object.keys(E)}};C(H,"STORAGE_KEY","loki-theme");var R=H,h=class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}),this._theme=R.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(){R.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`
1637
1649
  /* Design tokens */
1638
1650
  :host {
1639
1651
  ${j()}
@@ -1689,15 +1701,15 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
1689
1701
  }
1690
1702
 
1691
1703
  ${U}
1692
- `}getAriaPattern(t){return Ct[t]||{}}applyAriaPattern(t,e){let a=this.getAriaPattern(e);for(let[i,s]of Object.entries(a))if(i==="role")t.setAttribute("role",s);else{let r=i.replace(/([A-Z])/g,"-$1").toLowerCase();t.setAttribute(r,s)}}render(){}};var z={realtime:1e3,normal:2e3,background:5e3,offline:1e4},Mt={vscode:z.normal,browser:z.realtime,cli:z.background},Ft={baseUrl:typeof window<"u"?window.location.origin:"http://localhost:57374",wsUrl:typeof window<"u"?`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/ws`:"ws://localhost:57374/ws",pollInterval:2e3,timeout:1e4,retryAttempts:3,retryDelay:1e3},v={CONNECTED:"api:connected",DISCONNECTED:"api:disconnected",ERROR:"api:error",STATUS_UPDATE:"api:status-update",TASK_CREATED:"api:task-created",TASK_UPDATED:"api:task-updated",TASK_DELETED:"api:task-deleted",PROJECT_CREATED:"api:project-created",PROJECT_UPDATED:"api:project-updated",AGENT_UPDATE:"api:agent-update",LOG_MESSAGE:"api:log-message",MEMORY_UPDATE:"api:memory-update",CHECKLIST_UPDATE:"api:checklist-update"},T=class T extends EventTarget{static getInstance(t={}){let e=t.baseUrl||Ft.baseUrl;return T._instances.has(e)||T._instances.set(e,new T(t)),T._instances.get(e)}static clearInstances(){T._instances.forEach(t=>t.disconnect()),T._instances.clear()}constructor(t={}){super(),this.config={...Ft,...t},this._ws=null,this._connected=!1,this._pollInterval=null,this._reconnectTimeout=null,this._reconnectAttempts=0,this._maxReconnectAttempts=20,this._cache=new Map,this._cacheTimeout=5e3,this._vscodeApi=null,this._context=this._detectContext(),this._currentPollInterval=Mt[this._context]||z.normal,this._visibilityChangeHandler=null,this._messageHandler=null,this._setupAdaptivePolling(),this._setupVSCodeBridge()}_detectContext(){return typeof acquireVsCodeApi<"u"?"vscode":typeof window<"u"&&window.location?"browser":"cli"}get context(){return this._context}static get POLL_INTERVALS(){return z}_setupAdaptivePolling(){typeof document>"u"||(this._visibilityChangeHandler=()=>{document.hidden?this._setPollInterval(z.background):this._setPollInterval(Mt[this._context]||z.normal)},document.addEventListener("visibilitychange",this._visibilityChangeHandler))}_setPollInterval(t){this._currentPollInterval=t,this._pollInterval&&(this.stopPolling(),this.startPolling(null,t))}setPollMode(t){let e=z[t];e&&this._setPollInterval(e)}_setupVSCodeBridge(){if(!(typeof acquireVsCodeApi>"u")){try{this._vscodeApi=acquireVsCodeApi()}catch{console.warn("VS Code API already acquired or unavailable");return}this._messageHandler=t=>{let e=t.data;if(!(!e||!e.type))switch(e.type){case"updateStatus":this._emit(v.STATUS_UPDATE,e.data);break;case"updateTasks":this._emit(v.TASK_UPDATED,e.data);break;case"taskCreated":this._emit(v.TASK_CREATED,e.data);break;case"taskDeleted":this._emit(v.TASK_DELETED,e.data);break;case"projectCreated":this._emit(v.PROJECT_CREATED,e.data);break;case"projectUpdated":this._emit(v.PROJECT_UPDATED,e.data);break;case"agentUpdate":this._emit(v.AGENT_UPDATE,e.data);break;case"logMessage":this._emit(v.LOG_MESSAGE,e.data);break;case"memoryUpdate":this._emit(v.MEMORY_UPDATE,e.data);break;case"connected":this._connected=!0,this._emit(v.CONNECTED,e.data);break;case"disconnected":this._connected=!1,this._emit(v.DISCONNECTED,e.data);break;case"error":this._emit(v.ERROR,e.data);break;case"setPollMode":this.setPollMode(e.data.mode);break;default:this._emit(`api:${e.type}`,e.data)}},window.addEventListener("message",this._messageHandler)}}get isVSCode(){return this._context==="vscode"}postToVSCode(t,e={}){this._vscodeApi&&this._vscodeApi.postMessage({type:t,data:e})}requestRefresh(){this.postToVSCode("requestRefresh")}notifyVSCode(t,e={}){this.postToVSCode("userAction",{action:t,...e})}get baseUrl(){return this.config.baseUrl}set baseUrl(t){this.config.baseUrl=t,this.config.wsUrl=t.replace(/^http/,"ws")+"/ws"}get isConnected(){return this._connected}async connect(){if(!(this._ws&&this._ws.readyState===WebSocket.OPEN))return new Promise((t,e)=>{try{this._ws=new WebSocket(this.config.wsUrl),this._ws.onopen=()=>{this._connected=!0,this._reconnectAttempts=0,this._emit(v.CONNECTED),t()},this._ws.onclose=()=>{this._connected=!1,this._emit(v.DISCONNECTED),this._scheduleReconnect()},this._ws.onerror=a=>{this._emit(v.ERROR,{error:a}),e(a)},this._ws.onmessage=a=>{try{let i=JSON.parse(a.data);this._handleMessage(i)}catch(i){console.error("Failed to parse WebSocket message:",i)}}}catch(a){e(a)}})}disconnect(){this._ws&&(this._ws.close(),this._ws=null),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._reconnectTimeout&&(clearTimeout(this._reconnectTimeout),this._reconnectTimeout=null),this._connected=!1,this._cleanupGlobalListeners()}_cleanupGlobalListeners(){this._visibilityChangeHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this._visibilityChangeHandler),this._visibilityChangeHandler=null),this._messageHandler&&typeof window<"u"&&(window.removeEventListener("message",this._messageHandler),this._messageHandler=null)}destroy(){this.disconnect()}_scheduleReconnect(){if(this._reconnectTimeout)return;if(this._reconnectAttempts>=this._maxReconnectAttempts){console.warn("WebSocket max reconnect attempts reached, giving up"),this._emit(v.ERROR,{error:"Max reconnect attempts reached"});return}let t=Math.min(this.config.retryDelay*Math.pow(2,this._reconnectAttempts),3e4);this._reconnectAttempts++,this._reconnectTimeout=setTimeout(()=>{this._reconnectTimeout=null,this.connect().catch(()=>{})},t)}_handleMessage(t){if(t.type==="ping"){this._ws&&this._ws.readyState===WebSocket.OPEN&&this._ws.send(JSON.stringify({type:"pong"}));return}let a={connected:v.CONNECTED,status_update:v.STATUS_UPDATE,task_created:v.TASK_CREATED,task_updated:v.TASK_UPDATED,task_deleted:v.TASK_DELETED,task_moved:v.TASK_UPDATED,project_created:v.PROJECT_CREATED,project_updated:v.PROJECT_UPDATED,agent_update:v.AGENT_UPDATE,log:v.LOG_MESSAGE}[t.type]||`api:${t.type}`;this._emit(a,t.data)}_emit(t,e={}){this.dispatchEvent(new CustomEvent(t,{detail:e}))}async _request(t,e={}){let a=`${this.config.baseUrl}${t}`,i=new AbortController,s=setTimeout(()=>i.abort(),this.config.timeout);try{let r=await fetch(a,{...e,signal:i.signal,credentials:"include",headers:{"Content-Type":"application/json",...e.headers}});if(clearTimeout(s),!r.ok){let o=await r.text().catch(()=>""),n=r.statusText||`HTTP ${r.status}`;if(o)try{let l=JSON.parse(o);n=l.detail||l.error||l.message||n}catch{n=o.length>200?o.slice(0,200)+"...":o}throw new Error(n)}return r.status===204?null:await r.json()}catch(r){throw clearTimeout(s),r.name==="AbortError"?new Error("Request timeout"):r}}async _get(t,e=!1){if(e&&this._cache.has(t)){let i=this._cache.get(t);if(Date.now()-i.timestamp<this._cacheTimeout)return i.data}let a=await this._request(t);return e&&this._cache.set(t,{data:a,timestamp:Date.now()}),a}async _post(t,e){return this._request(t,{method:"POST",body:JSON.stringify(e)})}async _put(t,e){return this._request(t,{method:"PUT",body:JSON.stringify(e)})}async _delete(t){return this._request(t,{method:"DELETE"})}async get(t){return this._get(t)}async getStatus(){return this._get("/api/status")}async healthCheck(){return this._get("/health")}async listProjects(t=null){let e=t?`?status=${t}`:"";return this._get(`/api/projects${e}`)}async getProject(t){return this._get(`/api/projects/${t}`)}async createProject(t){return this._post("/api/projects",t)}async updateProject(t,e){return this._put(`/api/projects/${t}`,e)}async deleteProject(t){return this._delete(`/api/projects/${t}`)}async listTasks(t={}){let e=new URLSearchParams;t.projectId&&e.append("project_id",t.projectId),t.status&&e.append("status",t.status),t.priority&&e.append("priority",t.priority);let a=e.toString()?`?${e}`:"";return this._get(`/api/tasks${a}`)}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,a){return this._post(`/api/tasks/${t}/move`,{status:e,position:a})}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,a=5){return this._post("/api/memory/retrieve",{query:t,taskType:e,topK:a})}async consolidateMemory(t=24){return this._post("/api/memory/consolidate",{sinceHours:t})}async getTokenEconomics(){return this._get("/api/memory/economics")}async searchMemory(t,e="all",a=20){let i=new URLSearchParams({q:t,collection:e,limit:String(a)});return this._get(`/api/memory/search?${i}`)}async getMemoryStats(){return this._get("/api/memory/stats",!0)}async listRegisteredProjects(t=!1){return this._get(`/api/registry/projects?include_inactive=${t}`)}async registerProject(t,e=null,a=null){return this._post("/api/registry/projects",{path:t,name:e,alias:a})}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 a=e.toString()?`?${e}`:"";return this._get(`/api/learning/metrics${a}`)}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 a=e.toString()?`?${e}`:"";return this._get(`/api/learning/trends${a}`)}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 a=e.toString()?`?${e}`:"";return this._get(`/api/learning/signals${a}`)}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 a=new URLSearchParams;t&&a.set("severity",t),e&&a.set("unread_only","true");let i=a.toString();return this._get("/api/notifications"+(i?"?"+i:""))}async getNotificationTriggers(){return this._get("/api/notifications/triggers")}async updateNotificationTriggers(t){return this._put("/api/notifications/triggers",{triggers:t})}async acknowledgeNotification(t){return this._post("/api/notifications/"+encodeURIComponent(t)+"/acknowledge",{})}async pauseSession(){return this._post("/api/control/pause",{})}async resumeSession(){return this._post("/api/control/resume",{})}async stopSession(){return this._post("/api/control/stop",{})}async getLogs(t=100){return this._get(`/api/logs?lines=${t}`)}async getChecklist(){return this._get("/api/checklist")}async getChecklistSummary(){return this._get("/api/checklist/summary")}async getPrdObservations(){let t=await fetch(`${this.baseUrl}/api/prd-observations`,{credentials:"include"});if(!t.ok)throw new Error(`HTTP ${t.status}`);return t.text()}async getChecklistWaivers(){return this._get("/api/checklist/waivers")}async addChecklistWaiver(t,e,a="dashboard"){return this._post("/api/checklist/waivers",{item_id:t,reason:e,waived_by:a})}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 a=async()=>{try{let s=await this.getStatus();this._connected=!0,this._pollCallback&&this._pollCallback(s),this._emit(v.STATUS_UPDATE,s),this._vscodeApi&&this.postToVSCode("pollSuccess",{timestamp:Date.now()})}catch(s){this._connected=!1,this._emit(v.ERROR,{error:s}),this._vscodeApi&&this.postToVSCode("pollError",{error:s.message})}};a();let i=e||this._currentPollInterval||this.config.pollInterval;this._pollInterval=setInterval(a,i)}stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}};C(T,"_instances",new Map);var M=T;function jt(d={}){return new M(d)}function g(d={}){return M.getInstance(d)}var Tt="loki-state-change",At={ui:{theme:"light",sidebarCollapsed:!1,activeSection:"kanban",terminalAutoScroll:!0},session:{connected:!1,lastSync:null,mode:"offline",phase:null,iteration:null},localTasks:[],cache:{projects:[],tasks:[],agents:[],memory:null,lastFetch:null},preferences:{pollInterval:2e3,notifications:!0,soundEnabled:!1}},S=class S extends EventTarget{static getInstance(){return S._instance||(S._instance=new S),S._instance}constructor(){super(),this._state=this._loadState(),this._subscribers=new Map,this._batchUpdates=[],this._batchTimeout=null}_loadState(){try{let t=localStorage.getItem(S.STORAGE_KEY);if(t){let e=JSON.parse(t);return this._mergeState(At,e)}}catch(t){console.warn("Failed to load state from localStorage:",t)}return{...At}}_mergeState(t,e){let a={...t};for(let i of Object.keys(e))i in t&&typeof t[i]=="object"&&!Array.isArray(t[i])?a[i]=this._mergeState(t[i],e[i]):a[i]=e[i];return a}_saveState(){try{let t={ui:this._state.ui,localTasks:this._state.localTasks,preferences:this._state.preferences};localStorage.setItem(S.STORAGE_KEY,JSON.stringify(t))}catch(t){console.warn("Failed to save state to localStorage:",t)}}get(t=null){if(!t)return{...this._state};let e=t.split("."),a=this._state;for(let i of e){if(a==null)return;a=a[i]}return a}set(t,e,a=!0){let i=t.split("."),s=i.pop(),r=this._state;for(let n of i)n in r||(r[n]={}),r=r[n];let o=r[s];r[s]=e,a&&this._saveState(),this._notifyChange(t,e,o)}update(t,e=!0){let a=[];for(let[i,s]of Object.entries(t)){let r=this.get(i);this.set(i,s,!1),a.push({path:i,value:s,oldValue:r})}e&&this._saveState();for(let i of a)this._notifyChange(i.path,i.value,i.oldValue)}_notifyChange(t,e,a){this.dispatchEvent(new CustomEvent(Tt,{detail:{path:t,value:e,oldValue:a}}));let i=this._subscribers.get(t)||[];for(let r of i)try{r(e,a,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 a=this._subscribers.get(t),i=a.indexOf(e);i>-1&&a.splice(i,1)}}reset(t=null){if(t){let e=t.split("."),a=At;for(let i of e)a=a?.[i];this.set(t,a)}else this._state={...At},this._saveState(),this.dispatchEvent(new CustomEvent(Tt,{detail:{path:null,value:this._state,oldValue:null}}))}addLocalTask(t){let e=this.get("localTasks")||[],a={id:`local-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,createdAt:new Date().toISOString(),status:"pending",...t};return this.set("localTasks",[...e,a]),a}updateLocalTask(t,e){let a=this.get("localTasks")||[],i=a.findIndex(r=>r.id===t);if(i===-1)return null;let s={...a[i],...e,updatedAt:new Date().toISOString()};return a[i]=s,this.set("localTasks",[...a]),s}deleteLocalTask(t){let e=this.get("localTasks")||[];this.set("localTasks",e.filter(a=>a.id!==t))}moveLocalTask(t,e,a=null){let s=(this.get("localTasks")||[]).find(r=>r.id===t);return s?this.updateLocalTask(t,{status:e,position:a??s.position}):null}updateSession(t){this.update(Object.fromEntries(Object.entries(t).map(([e,a])=>[`session.${e}`,a])),!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")||[],a=(this.get("localTasks")||[]).map(i=>({...i,isLocal:!0}));return[...t,...a]}getTasksByStatus(t){return this.getMergedTasks().filter(e=>e.status===t)}};C(S,"STORAGE_KEY","loki-dashboard-state"),C(S,"_instance",null);var N=S;function B(){return N.getInstance()}function Ut(d){let t=B();return{get:()=>t.get(d),set:e=>t.set(d,e),subscribe:e=>t.subscribe(d,e)}}var O=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data={status:"offline",phase:null,iteration:null,provider:null,running_agents:0,pending_tasks:null,uptime_seconds:0,complexity:null,connected:!1},this._api=null,this._pollInterval=null,this._statusUpdateHandler=null,this._connectedHandler=null,this._disconnectedHandler=null,this._checklistSummary=null,this._appRunnerStatus=null,this._playwrightResults=null,this._gateStatus=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._startPolling(),this._api.connect().catch(()=>{})}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._loadAbortController&&(this._loadAbortController.abort(),this._loadAbortController=null),this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(v.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(v.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(v.DISCONNECTED,this._disconnectedHandler))}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadStatus()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t}),this._statusUpdateHandler=e=>this._updateFromStatus(e.detail),this._connectedHandler=()=>{this._data.connected=!0,this.render()},this._disconnectedHandler=()=>{this._data.connected=!1,this._data.status="offline",this.render()},this._api.addEventListener(v.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(v.CONNECTED,this._connectedHandler),this._api.addEventListener(v.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){this._loadAbortController&&this._loadAbortController.abort(),this._loadAbortController=new AbortController;let{signal:t}=this._loadAbortController;try{let[e,a,i,s,r]=await Promise.allSettled([this._api.getStatus(),this._api.getChecklistSummary(),this._api.getAppRunnerStatus(),this._api.getPlaywrightResults(),this._api.getCouncilGate()]);if(t.aborted)return;e.status==="fulfilled"?this._updateFromStatus(e.value):(this._data.connected=!1,this._data.status="offline"),a.status==="fulfilled"&&(this._checklistSummary=a.value?.summary||null),i.status==="fulfilled"&&(this._appRunnerStatus=i.value),s.status==="fulfilled"&&(this._playwrightResults=s.value),r.status==="fulfilled"&&(this._gateStatus=r.value),this.render()}catch{if(t.aborted)return;this._data.connected=!1,this._data.status="offline",this.render()}}_updateFromStatus(t){t&&(this._data={...this._data,connected:!0,status:t.status||"offline",phase:t.phase||null,iteration:t.iteration!=null?t.iteration:null,provider:t.provider||null,running_agents:t.running_agents||0,pending_tasks:t.pending_tasks!=null?t.pending_tasks:null,uptime_seconds:t.uptime_seconds||0,complexity:t.complexity||null})}_startPolling(){this._pollInterval=setInterval(async()=>{try{await this._loadStatus()}catch{this._data.connected=!1,this._data.status="offline",this.render()}},5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_formatUptime(t){if(!t||t<0)return"--";let e=Math.floor(t/3600),a=Math.floor(t%3600/60),i=Math.floor(t%60);return e>0?`${e}h ${a}m`:a>0?`${a}m ${i}s`:`${i}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`
1704
+ `}getAriaPattern(t){return St[t]||{}}applyAriaPattern(t,e){let i=this.getAriaPattern(e);for(let[a,s]of Object.entries(i))if(a==="role")t.setAttribute("role",s);else{let r=a.replace(/([A-Z])/g,"-$1").toLowerCase();t.setAttribute(r,s)}}render(){}};var z={realtime:1e3,normal:2e3,background:5e3,offline:1e4},Ft={vscode:z.normal,browser:z.realtime,cli:z.background},jt={baseUrl:typeof window<"u"?window.location.origin:"http://localhost:57374",wsUrl:typeof window<"u"?`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/ws`:"ws://localhost:57374/ws",pollInterval:2e3,timeout:1e4,retryAttempts:3,retryDelay:1e3},m={CONNECTED:"api:connected",DISCONNECTED:"api:disconnected",ERROR:"api:error",STATUS_UPDATE:"api:status-update",TASK_CREATED:"api:task-created",TASK_UPDATED:"api:task-updated",TASK_DELETED:"api:task-deleted",PROJECT_CREATED:"api:project-created",PROJECT_UPDATED:"api:project-updated",AGENT_UPDATE:"api:agent-update",LOG_MESSAGE:"api:log-message",MEMORY_UPDATE:"api:memory-update",CHECKLIST_UPDATE:"api:checklist-update"},T=class T extends EventTarget{static getInstance(t={}){let e=t.baseUrl||jt.baseUrl;return T._instances.has(e)||T._instances.set(e,new T(t)),T._instances.get(e)}static clearInstances(){T._instances.forEach(t=>t.disconnect()),T._instances.clear()}constructor(t={}){super(),this.config={...jt,...t},this._ws=null,this._connected=!1,this._pollInterval=null,this._reconnectTimeout=null,this._reconnectAttempts=0,this._maxReconnectAttempts=20,this._cache=new Map,this._cacheTimeout=5e3,this._vscodeApi=null,this._context=this._detectContext(),this._currentPollInterval=Ft[this._context]||z.normal,this._visibilityChangeHandler=null,this._messageHandler=null,this._setupAdaptivePolling(),this._setupVSCodeBridge()}_detectContext(){return typeof acquireVsCodeApi<"u"?"vscode":typeof window<"u"&&window.location?"browser":"cli"}get context(){return this._context}static get POLL_INTERVALS(){return z}_setupAdaptivePolling(){typeof document>"u"||(this._visibilityChangeHandler=()=>{document.hidden?this._setPollInterval(z.background):this._setPollInterval(Ft[this._context]||z.normal)},document.addEventListener("visibilitychange",this._visibilityChangeHandler))}_setPollInterval(t){this._currentPollInterval=t,this._pollInterval&&(this.stopPolling(),this.startPolling(null,t))}setPollMode(t){let e=z[t];e&&this._setPollInterval(e)}_setupVSCodeBridge(){if(!(typeof acquireVsCodeApi>"u")){try{this._vscodeApi=acquireVsCodeApi()}catch{console.warn("VS Code API already acquired or unavailable");return}this._messageHandler=t=>{let e=t.data;if(!(!e||!e.type))switch(e.type){case"updateStatus":this._emit(m.STATUS_UPDATE,e.data);break;case"updateTasks":this._emit(m.TASK_UPDATED,e.data);break;case"taskCreated":this._emit(m.TASK_CREATED,e.data);break;case"taskDeleted":this._emit(m.TASK_DELETED,e.data);break;case"projectCreated":this._emit(m.PROJECT_CREATED,e.data);break;case"projectUpdated":this._emit(m.PROJECT_UPDATED,e.data);break;case"agentUpdate":this._emit(m.AGENT_UPDATE,e.data);break;case"logMessage":this._emit(m.LOG_MESSAGE,e.data);break;case"memoryUpdate":this._emit(m.MEMORY_UPDATE,e.data);break;case"connected":this._connected=!0,this._emit(m.CONNECTED,e.data);break;case"disconnected":this._connected=!1,this._emit(m.DISCONNECTED,e.data);break;case"error":this._emit(m.ERROR,e.data);break;case"setPollMode":this.setPollMode(e.data.mode);break;default:this._emit(`api:${e.type}`,e.data)}},window.addEventListener("message",this._messageHandler)}}get isVSCode(){return this._context==="vscode"}postToVSCode(t,e={}){this._vscodeApi&&this._vscodeApi.postMessage({type:t,data:e})}requestRefresh(){this.postToVSCode("requestRefresh")}notifyVSCode(t,e={}){this.postToVSCode("userAction",{action:t,...e})}get baseUrl(){return this.config.baseUrl}set baseUrl(t){this.config.baseUrl=t,this.config.wsUrl=t.replace(/^http/,"ws")+"/ws"}get isConnected(){return this._connected}async connect(){if(!(this._ws&&this._ws.readyState===WebSocket.OPEN))return new Promise((t,e)=>{try{this._ws=new WebSocket(this.config.wsUrl),this._ws.onopen=()=>{this._connected=!0,this._reconnectAttempts=0,this._emit(m.CONNECTED),t()},this._ws.onclose=()=>{this._connected=!1,this._emit(m.DISCONNECTED),this._scheduleReconnect()},this._ws.onerror=i=>{this._emit(m.ERROR,{error:i}),e(i)},this._ws.onmessage=i=>{try{let a=JSON.parse(i.data);this._handleMessage(a)}catch(a){console.error("Failed to parse WebSocket message:",a)}}}catch(i){e(i)}})}disconnect(){this._ws&&(this._ws.close(),this._ws=null),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._reconnectTimeout&&(clearTimeout(this._reconnectTimeout),this._reconnectTimeout=null),this._connected=!1,this._cleanupGlobalListeners()}_cleanupGlobalListeners(){this._visibilityChangeHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this._visibilityChangeHandler),this._visibilityChangeHandler=null),this._messageHandler&&typeof window<"u"&&(window.removeEventListener("message",this._messageHandler),this._messageHandler=null)}destroy(){this.disconnect()}_scheduleReconnect(){if(this._reconnectTimeout)return;if(this._reconnectAttempts>=this._maxReconnectAttempts){console.warn("WebSocket max reconnect attempts reached, giving up"),this._emit(m.ERROR,{error:"Max reconnect attempts reached"});return}let t=Math.min(this.config.retryDelay*Math.pow(2,this._reconnectAttempts),3e4);this._reconnectAttempts++,this._reconnectTimeout=setTimeout(()=>{this._reconnectTimeout=null,this.connect().catch(()=>{})},t)}_handleMessage(t){if(t.type==="ping"){this._ws&&this._ws.readyState===WebSocket.OPEN&&this._ws.send(JSON.stringify({type:"pong"}));return}let i={connected:m.CONNECTED,status_update:m.STATUS_UPDATE,task_created:m.TASK_CREATED,task_updated:m.TASK_UPDATED,task_deleted:m.TASK_DELETED,task_moved:m.TASK_UPDATED,project_created:m.PROJECT_CREATED,project_updated:m.PROJECT_UPDATED,agent_update:m.AGENT_UPDATE,log:m.LOG_MESSAGE}[t.type]||`api:${t.type}`;this._emit(i,t.data)}_emit(t,e={}){this.dispatchEvent(new CustomEvent(t,{detail:e}))}async _request(t,e={}){let i=`${this.config.baseUrl}${t}`,a=new AbortController,s=setTimeout(()=>a.abort(),this.config.timeout);try{let r=await fetch(i,{...e,signal:a.signal,credentials:"include",headers:{"Content-Type":"application/json",...e.headers}});if(clearTimeout(s),!r.ok){let o=await r.text().catch(()=>""),n=r.statusText||`HTTP ${r.status}`;if(o)try{let l=JSON.parse(o);n=l.detail||l.error||l.message||n}catch{n=o.length>200?o.slice(0,200)+"...":o}throw new Error(n)}return r.status===204?null:await r.json()}catch(r){throw clearTimeout(s),r.name==="AbortError"?new Error("Request timeout"):r}}async _get(t,e=!1){if(e&&this._cache.has(t)){let a=this._cache.get(t);if(Date.now()-a.timestamp<this._cacheTimeout)return a.data}let i=await this._request(t);return e&&this._cache.set(t,{data:i,timestamp:Date.now()}),i}async _post(t,e){return this._request(t,{method:"POST",body:JSON.stringify(e)})}async _put(t,e){return this._request(t,{method:"PUT",body:JSON.stringify(e)})}async _delete(t){return this._request(t,{method:"DELETE"})}async get(t){return this._get(t)}async getStatus(){return this._get("/api/status")}async healthCheck(){return this._get("/health")}async listProjects(t=null){let e=t?`?status=${t}`:"";return this._get(`/api/projects${e}`)}async getProject(t){return this._get(`/api/projects/${t}`)}async createProject(t){return this._post("/api/projects",t)}async updateProject(t,e){return this._put(`/api/projects/${t}`,e)}async deleteProject(t){return this._delete(`/api/projects/${t}`)}async listTasks(t={}){let e=new URLSearchParams;t.projectId&&e.append("project_id",t.projectId),t.status&&e.append("status",t.status),t.priority&&e.append("priority",t.priority);let i=e.toString()?`?${e}`:"";return this._get(`/api/tasks${i}`)}async getTask(t){return this._get(`/api/tasks/${t}`)}async createTask(t){return this._post("/api/tasks",t)}async updateTask(t,e){return this._put(`/api/tasks/${t}`,e)}async moveTask(t,e,i){return this._post(`/api/tasks/${t}/move`,{status:e,position:i})}async deleteTask(t){return this._delete(`/api/tasks/${t}`)}async getMemorySummary(){return this._get("/api/memory/summary",!0)}async getMemoryIndex(){return this._get("/api/memory/index",!0)}async getMemoryTimeline(){return this._get("/api/memory/timeline")}async listEpisodes(t={}){let e=new URLSearchParams(t).toString();return this._get(`/api/memory/episodes${e?"?"+e:""}`)}async getEpisode(t){return this._get(`/api/memory/episodes/${t}`)}async listPatterns(t={}){let e=new URLSearchParams(t).toString();return this._get(`/api/memory/patterns${e?"?"+e:""}`)}async getPattern(t){return this._get(`/api/memory/patterns/${t}`)}async listSkills(){return this._get("/api/memory/skills")}async getSkill(t){return this._get(`/api/memory/skills/${t}`)}async retrieveMemories(t,e=null,i=5){return this._post("/api/memory/retrieve",{query:t,taskType:e,topK:i})}async consolidateMemory(t=24){return this._post("/api/memory/consolidate",{sinceHours:t})}async getTokenEconomics(){return this._get("/api/memory/economics")}async searchMemory(t,e="all",i=20){let a=new URLSearchParams({q:t,collection:e,limit:String(i)});return this._get(`/api/memory/search?${a}`)}async getMemoryStats(){return this._get("/api/memory/stats",!0)}async listRegisteredProjects(t=!1){return this._get(`/api/registry/projects?include_inactive=${t}`)}async registerProject(t,e=null,i=null){return this._post("/api/registry/projects",{path:t,name:e,alias:i})}async discoverProjects(t=3){return this._get(`/api/registry/discover?max_depth=${t}`)}async syncRegistry(){return this._post("/api/registry/sync",{})}async getCrossProjectTasks(t=null){let e=t?`?project_ids=${t.join(",")}`:"";return this._get(`/api/registry/tasks${e}`)}async getLearningMetrics(t={}){let e=new URLSearchParams;t.timeRange&&e.append("timeRange",t.timeRange),t.signalType&&e.append("signalType",t.signalType),t.source&&e.append("source",t.source);let i=e.toString()?`?${e}`:"";return this._get(`/api/learning/metrics${i}`)}async getLearningTrends(t={}){let e=new URLSearchParams;t.timeRange&&e.append("timeRange",t.timeRange),t.signalType&&e.append("signalType",t.signalType),t.source&&e.append("source",t.source);let i=e.toString()?`?${e}`:"";return this._get(`/api/learning/trends${i}`)}async getLearningSignals(t={}){let e=new URLSearchParams;t.timeRange&&e.append("timeRange",t.timeRange),t.signalType&&e.append("signalType",t.signalType),t.source&&e.append("source",t.source),t.limit&&e.append("limit",String(t.limit)),t.offset&&e.append("offset",String(t.offset));let i=e.toString()?`?${e}`:"";return this._get(`/api/learning/signals${i}`)}async getLatestAggregation(){return this._get("/api/learning/aggregation")}async triggerAggregation(t={}){return this._post("/api/learning/aggregate",t)}async getAggregatedPreferences(t=20){return this._get(`/api/learning/preferences?limit=${t}`)}async getAggregatedErrors(t=20){return this._get(`/api/learning/errors?limit=${t}`)}async getAggregatedSuccessPatterns(t=20){return this._get(`/api/learning/success?limit=${t}`)}async getToolEfficiency(t=20){return this._get(`/api/learning/tools?limit=${t}`)}async getCost(){return this._get("/api/cost")}async getPricing(){return this._get("/api/pricing")}async getCouncilState(){return this._get("/api/council/state")}async getCouncilVerdicts(t=20){return this._get(`/api/council/verdicts?limit=${t}`)}async getCouncilConvergence(){return this._get("/api/council/convergence")}async getCouncilReport(){return this._get("/api/council/report")}async forceCouncilReview(){return this._post("/api/council/force-review",{})}async getContext(){return this._get("/api/context")}async getNotifications(t,e){let i=new URLSearchParams;t&&i.set("severity",t),e&&i.set("unread_only","true");let a=i.toString();return this._get("/api/notifications"+(a?"?"+a:""))}async getNotificationTriggers(){return this._get("/api/notifications/triggers")}async updateNotificationTriggers(t){return this._put("/api/notifications/triggers",{triggers:t})}async acknowledgeNotification(t){return this._post("/api/notifications/"+encodeURIComponent(t)+"/acknowledge",{})}async pauseSession(){return this._post("/api/control/pause",{})}async resumeSession(){return this._post("/api/control/resume",{})}async stopSession(){return this._post("/api/control/stop",{})}async getLogs(t=100){return this._get(`/api/logs?lines=${t}`)}async getChecklist(){return this._get("/api/checklist")}async getChecklistSummary(){return this._get("/api/checklist/summary")}async getPrdObservations(){let t=await fetch(`${this.baseUrl}/api/prd-observations`,{credentials:"include"});if(!t.ok)throw new Error(`HTTP ${t.status}`);return t.text()}async getChecklistWaivers(){return this._get("/api/checklist/waivers")}async addChecklistWaiver(t,e,i="dashboard"){return this._post("/api/checklist/waivers",{item_id:t,reason:e,waived_by:i})}async removeChecklistWaiver(t){return this._delete(`/api/checklist/waivers/${encodeURIComponent(t)}`)}async getCouncilGate(){return this._get("/api/council/gate")}async getAppRunnerStatus(){return this._get("/api/app-runner/status")}async getAppRunnerLogs(t=100){return this._get(`/api/app-runner/logs?lines=${t}`)}async restartApp(){return this._post("/api/control/app-restart",{})}async stopApp(){return this._post("/api/control/app-stop",{})}async getPlaywrightResults(){return this._get("/api/playwright/results")}async getPlaywrightScreenshot(){return this._get("/api/playwright/screenshot")}startPolling(t,e=null){if(this._pollInterval)return;this._pollCallback=t;let i=async()=>{try{let s=await this.getStatus();this._connected=!0,this._pollCallback&&this._pollCallback(s),this._emit(m.STATUS_UPDATE,s),this._vscodeApi&&this.postToVSCode("pollSuccess",{timestamp:Date.now()})}catch(s){this._connected=!1,this._emit(m.ERROR,{error:s}),this._vscodeApi&&this.postToVSCode("pollError",{error:s.message})}};i();let a=e||this._currentPollInterval||this.config.pollInterval;this._pollInterval=setInterval(i,a)}stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}};C(T,"_instances",new Map);var M=T;function Ut(d={}){return new M(d)}function g(d={}){return M.getInstance(d)}var It="loki-state-change",Tt={ui:{theme:"light",sidebarCollapsed:!1,activeSection:"kanban",terminalAutoScroll:!0},session:{connected:!1,lastSync:null,mode:"offline",phase:null,iteration:null},localTasks:[],cache:{projects:[],tasks:[],agents:[],memory:null,lastFetch:null},preferences:{pollInterval:2e3,notifications:!0,soundEnabled:!1}},S=class S extends EventTarget{static getInstance(){return S._instance||(S._instance=new S),S._instance}constructor(){super(),this._state=this._loadState(),this._subscribers=new Map,this._batchUpdates=[],this._batchTimeout=null}_loadState(){try{let t=localStorage.getItem(S.STORAGE_KEY);if(t){let e=JSON.parse(t);return this._mergeState(Tt,e)}}catch(t){console.warn("Failed to load state from localStorage:",t)}return{...Tt}}_mergeState(t,e){let i={...t};for(let a of Object.keys(e))a in t&&typeof t[a]=="object"&&!Array.isArray(t[a])?i[a]=this._mergeState(t[a],e[a]):i[a]=e[a];return i}_saveState(){try{let t={ui:this._state.ui,localTasks:this._state.localTasks,preferences:this._state.preferences};localStorage.setItem(S.STORAGE_KEY,JSON.stringify(t))}catch(t){console.warn("Failed to save state to localStorage:",t)}}get(t=null){if(!t)return{...this._state};let e=t.split("."),i=this._state;for(let a of e){if(i==null)return;i=i[a]}return i}set(t,e,i=!0){let a=t.split("."),s=a.pop(),r=this._state;for(let n of a)n in r||(r[n]={}),r=r[n];let o=r[s];r[s]=e,i&&this._saveState(),this._notifyChange(t,e,o)}update(t,e=!0){let i=[];for(let[a,s]of Object.entries(t)){let r=this.get(a);this.set(a,s,!1),i.push({path:a,value:s,oldValue:r})}e&&this._saveState();for(let a of i)this._notifyChange(a.path,a.value,a.oldValue)}_notifyChange(t,e,i){this.dispatchEvent(new CustomEvent(It,{detail:{path:t,value:e,oldValue:i}}));let a=this._subscribers.get(t)||[];for(let r of a)try{r(e,i,t)}catch(o){console.error("State subscriber error:",o)}let s=t.split(".");for(;s.length>1;){s.pop();let r=s.join("."),o=this._subscribers.get(r)||[];for(let n of o)try{n(this.get(r),null,r)}catch(l){console.error("State subscriber error:",l)}}}subscribe(t,e){return this._subscribers.has(t)||this._subscribers.set(t,[]),this._subscribers.get(t).push(e),()=>{let i=this._subscribers.get(t),a=i.indexOf(e);a>-1&&i.splice(a,1)}}reset(t=null){if(t){let e=t.split("."),i=Tt;for(let a of e)i=i?.[a];this.set(t,i)}else this._state={...Tt},this._saveState(),this.dispatchEvent(new CustomEvent(It,{detail:{path:null,value:this._state,oldValue:null}}))}addLocalTask(t){let e=this.get("localTasks")||[],i={id:`local-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,createdAt:new Date().toISOString(),status:"pending",...t};return this.set("localTasks",[...e,i]),i}updateLocalTask(t,e){let i=this.get("localTasks")||[],a=i.findIndex(r=>r.id===t);if(a===-1)return null;let s={...i[a],...e,updatedAt:new Date().toISOString()};return i[a]=s,this.set("localTasks",[...i]),s}deleteLocalTask(t){let e=this.get("localTasks")||[];this.set("localTasks",e.filter(i=>i.id!==t))}moveLocalTask(t,e,i=null){let s=(this.get("localTasks")||[]).find(r=>r.id===t);return s?this.updateLocalTask(t,{status:e,position:i??s.position}):null}updateSession(t){this.update(Object.fromEntries(Object.entries(t).map(([e,i])=>[`session.${e}`,i])),!1)}updateCache(t){this.update({"cache.projects":t.projects??this.get("cache.projects"),"cache.tasks":t.tasks??this.get("cache.tasks"),"cache.agents":t.agents??this.get("cache.agents"),"cache.memory":t.memory??this.get("cache.memory"),"cache.lastFetch":new Date().toISOString()},!1)}getMergedTasks(){let t=this.get("cache.tasks")||[],i=(this.get("localTasks")||[]).map(a=>({...a,isLocal:!0}));return[...t,...i]}getTasksByStatus(t){return this.getMergedTasks().filter(e=>e.status===t)}};C(S,"STORAGE_KEY","loki-dashboard-state"),C(S,"_instance",null);var N=S;function B(){return N.getInstance()}function Nt(d){let t=B();return{get:()=>t.get(d),set:e=>t.set(d,e),subscribe:e=>t.subscribe(d,e)}}var O=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data={status:"offline",phase:null,iteration:null,provider:null,running_agents:0,pending_tasks:null,uptime_seconds:0,complexity:null,connected:!1},this._api=null,this._pollInterval=null,this._statusUpdateHandler=null,this._connectedHandler=null,this._disconnectedHandler=null,this._checklistSummary=null,this._appRunnerStatus=null,this._playwrightResults=null,this._gateStatus=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._startPolling(),this._api.connect().catch(()=>{})}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._loadAbortController&&(this._loadAbortController.abort(),this._loadAbortController=null),this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(m.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(m.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(m.DISCONNECTED,this._disconnectedHandler))}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadStatus()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t}),this._statusUpdateHandler=e=>this._updateFromStatus(e.detail),this._connectedHandler=()=>{this._data.connected=!0,this.render()},this._disconnectedHandler=()=>{this._data.connected=!1,this._data.status="offline",this.render()},this._api.addEventListener(m.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(m.CONNECTED,this._connectedHandler),this._api.addEventListener(m.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){this._loadAbortController&&this._loadAbortController.abort(),this._loadAbortController=new AbortController;let{signal:t}=this._loadAbortController;try{let[e,i,a,s,r]=await Promise.allSettled([this._api.getStatus(),this._api.getChecklistSummary(),this._api.getAppRunnerStatus(),this._api.getPlaywrightResults(),this._api.getCouncilGate()]);if(t.aborted)return;e.status==="fulfilled"?this._updateFromStatus(e.value):(this._data.connected=!1,this._data.status="offline"),i.status==="fulfilled"&&(this._checklistSummary=i.value?.summary||null),a.status==="fulfilled"&&(this._appRunnerStatus=a.value),s.status==="fulfilled"&&(this._playwrightResults=s.value),r.status==="fulfilled"&&(this._gateStatus=r.value),this.render()}catch{if(t.aborted)return;this._data.connected=!1,this._data.status="offline",this.render()}}_updateFromStatus(t){t&&(this._data={...this._data,connected:!0,status:t.status||"offline",phase:t.phase||null,iteration:t.iteration!=null?t.iteration:null,provider:t.provider||null,running_agents:t.running_agents||0,pending_tasks:t.pending_tasks!=null?t.pending_tasks:null,uptime_seconds:t.uptime_seconds||0,complexity:t.complexity||null})}_startPolling(){this._pollInterval=setInterval(async()=>{try{await this._loadStatus()}catch{this._data.connected=!1,this._data.status="offline",this.render()}},5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_formatUptime(t){if(!t||t<0)return"--";let e=Math.floor(t/3600),i=Math.floor(t%3600/60),a=Math.floor(t%60);return e>0?`${e}h ${i}m`:i>0?`${i}m ${a}s`:`${a}s`}_getStatusDotClass(){switch(this._data.status){case"running":case"autonomous":return"active";case"paused":return"paused";case"stopped":return"stopped";case"error":return"error";default:return"offline"}}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_renderAppRunnerCard(){let t=this._appRunnerStatus;if(!t||t.status==="not_initialized")return`
1693
1705
  <div class="overview-card">
1694
1706
  <div class="card-label">App Runner</div>
1695
1707
  <div class="card-value small-text">${this._data.status==="running"||this._data.status==="autonomous"?"Waiting...":"Not started"}</div>
1696
1708
  </div>
1697
- `;let a={running:"var(--loki-green, #22c55e)",starting:"var(--loki-yellow, #f59e0b)",crashed:"var(--loki-red, #ef4444)",stopped:"var(--loki-text-muted, #a1a1aa)"}[t.status]||"var(--loki-text-muted)",i=t.status==="running"?"active":t.status==="crashed"?"error":"offline",s=(t.status||"unknown").toUpperCase(),r=t.port?`:${t.port}`:"",o=t.url&&typeof t.url=="string"?t.url:null;!o&&t.port&&t.status==="running"&&(o=`http://localhost:${t.port}`);let n=`
1709
+ `;let i={running:"var(--loki-green, #22c55e)",starting:"var(--loki-yellow, #f59e0b)",crashed:"var(--loki-red, #ef4444)",stopped:"var(--loki-text-muted, #a1a1aa)"}[t.status]||"var(--loki-text-muted)",a=t.status==="running"?"active":t.status==="crashed"?"error":"offline",s=(t.status||"unknown").toUpperCase(),r=t.port?`:${t.port}`:"",o=t.url&&typeof t.url=="string"?t.url:null;!o&&t.port&&t.status==="running"&&(o=`http://localhost:${t.port}`);let n=`
1698
1710
  <div class="card-label">App Runner${o?' <span style="font-size:10px;color:var(--loki-text-muted);">(click to open)</span>':""}</div>
1699
1711
  <div class="card-value small-text">
1700
- <span class="status-dot ${i}"></span>
1712
+ <span class="status-dot ${a}"></span>
1701
1713
  ${s}${r}
1702
1714
  </div>
1703
1715
  ${t.method?`<div style="font-size:10px;color:var(--loki-text-muted);margin-top:2px;">${this._escapeHtml(t.method)}</div>`:""}
@@ -1716,12 +1728,12 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
1716
1728
  <div class="card-label">Verification</div>
1717
1729
  <div class="card-value small-text">${this._data.status==="running"||this._data.status==="autonomous"?"Pending":"Not run"}</div>
1718
1730
  </div>
1719
- `;let e=t.passed===!0,a=e?"var(--loki-green, #22c55e)":"var(--loki-red, #ef4444)",i=e?"PASSED":"FAILED",s=e?"active":"error",r=t.checks||{},o=Object.values(r).filter(n=>!n).length;return`
1731
+ `;let e=t.passed===!0,i=e?"var(--loki-green, #22c55e)":"var(--loki-red, #ef4444)",a=e?"PASSED":"FAILED",s=e?"active":"error",r=t.checks||{},o=Object.values(r).filter(n=>!n).length;return`
1720
1732
  <div class="overview-card">
1721
1733
  <div class="card-label">Verification</div>
1722
1734
  <div class="card-value small-text">
1723
1735
  <span class="status-dot ${s}"></span>
1724
- ${i}
1736
+ ${a}
1725
1737
  </div>
1726
1738
  ${!e&&o>0?`<div style="font-size:10px;color:var(--loki-red,#ef4444);margin-top:2px;">${o} check(s) failed</div>`:""}
1727
1739
  </div>
@@ -1730,12 +1742,12 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
1730
1742
  <div class="card-label">Spec Progress</div>
1731
1743
  <div class="card-value small-text">${this._data.status==="running"||this._data.status==="autonomous"?"Analyzing spec...":"No checklist"}</div>
1732
1744
  </div>
1733
- `;let e=Math.round(t.verified/t.total*100),a=t.failing>0?"var(--loki-yellow, #f59e0b)":"var(--loki-green, #22c55e)";return`
1745
+ `;let e=Math.round(t.verified/t.total*100),i=t.failing>0?"var(--loki-yellow, #f59e0b)":"var(--loki-green, #22c55e)";return`
1734
1746
  <div class="overview-card">
1735
1747
  <div class="card-label">Spec Progress</div>
1736
1748
  <div class="card-value small-text">${t.verified}/${t.total} (${e}%)</div>
1737
1749
  <div class="mini-progress" style="margin-top:4px;height:4px;background:var(--loki-bg-secondary,#e4e4e7);border-radius:2px;overflow:hidden;">
1738
- <div style="width:${e}%;height:100%;background:${a};transition:width 0.3s;"></div>
1750
+ <div style="width:${e}%;height:100%;background:${i};transition:width 0.3s;"></div>
1739
1751
  </div>
1740
1752
  ${t.failing?`<div style="font-size:10px;color:var(--loki-red,#ef4444);margin-top:2px;">${t.failing} failing</div>`:""}
1741
1753
  </div>
@@ -1764,7 +1776,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
1764
1776
  PASSED
1765
1777
  </div>
1766
1778
  </div>
1767
- `}render(){let t=this._getStatusDotClass(),e=this._escapeHtml((this._data.status||"OFFLINE").toUpperCase()),a=this._escapeHtml(this._data.phase||"--"),i=this._escapeHtml(this._data.iteration!=null?String(this._data.iteration):"0"),s=this._escapeHtml((this._data.provider||"CLAUDE").toUpperCase()),r=this._data.status==="running"||this._data.status==="autonomous",o=this._data.running_agents||0,n=r&&o===0?"Sequential":this._escapeHtml(String(o)),l=this._escapeHtml(this._data.pending_tasks!=null?`${this._data.pending_tasks} pending`:r?"Inline":"--"),c=this._escapeHtml(this._formatUptime(this._data.uptime_seconds)),p=this._escapeHtml((this._data.complexity||"STANDARD").toUpperCase());this.shadowRoot.innerHTML=`
1779
+ `}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._data.status==="running"||this._data.status==="autonomous",o=this._data.running_agents||0,n=r&&o===0?"Sequential":this._escapeHtml(String(o)),l=this._escapeHtml(this._data.pending_tasks!=null?`${this._data.pending_tasks} pending`:r?"Inline":"--"),c=this._escapeHtml(this._formatUptime(this._data.uptime_seconds)),p=this._escapeHtml((this._data.complexity||"STANDARD").toUpperCase());this.shadowRoot.innerHTML=`
1768
1780
  <style>
1769
1781
  ${this.getBaseStyles()}
1770
1782
 
@@ -1898,12 +1910,12 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
1898
1910
 
1899
1911
  <div class="overview-card">
1900
1912
  <div class="card-label">Phase</div>
1901
- <div class="card-value small-text">${a}</div>
1913
+ <div class="card-value small-text">${i}</div>
1902
1914
  </div>
1903
1915
 
1904
1916
  <div class="overview-card">
1905
1917
  <div class="card-label">Iteration</div>
1906
- <div class="card-value">${i}</div>
1918
+ <div class="card-value">${a}</div>
1907
1919
  </div>
1908
1920
 
1909
1921
  <div class="overview-card">
@@ -1940,15 +1952,15 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
1940
1952
  </div>
1941
1953
  </div>
1942
1954
  </div>
1943
- `}};customElements.get("loki-overview")||customElements.define("loki-overview",O);var de=[{id:"pending",label:"Pending",status:"pending",color:"var(--loki-text-muted)"},{id:"in_progress",label:"In Progress",status:"in_progress",color:"var(--loki-blue)"},{id:"review",label:"In Review",status:"review",color:"var(--loki-purple)"},{id:"done",label:"Completed",status:"done",color:"var(--loki-green)"}],q=class extends h{static get observedAttributes(){return["api-url","project-id","theme","readonly"]}constructor(){super(),this._tasks=[],this._loading=!0,this._error=null,this._draggedTask=null,this._selectedTask=null,this._expandedCards=new Set,this._selectedTasks=new Set,this._bulkMode=!1,this._activeFilter="all",this._api=null,this._state=B()}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadTasks()}disconnectedCallback(){super.disconnectedCallback(),this._api&&(this._api.removeEventListener(v.TASK_CREATED,this._onTaskEvent),this._api.removeEventListener(v.TASK_UPDATED,this._onTaskEvent),this._api.removeEventListener(v.TASK_DELETED,this._onTaskEvent))}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadTasks()),t==="project-id"&&this._loadTasks(),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t}),this._onTaskEvent&&(this._api.removeEventListener(v.TASK_CREATED,this._onTaskEvent),this._api.removeEventListener(v.TASK_UPDATED,this._onTaskEvent),this._api.removeEventListener(v.TASK_DELETED,this._onTaskEvent)),this._onTaskEvent=()=>this._loadTasks(),this._api.addEventListener(v.TASK_CREATED,this._onTaskEvent),this._api.addEventListener(v.TASK_UPDATED,this._onTaskEvent),this._api.addEventListener(v.TASK_DELETED,this._onTaskEvent)}async _loadTasks(){this._loading=!0,this._error=null,this.render();try{let t=this.getAttribute("project-id"),e=t?{projectId:parseInt(t)}:{};this._tasks=await this._api.listTasks(e);let a=this._state.get("localTasks")||[];a.length>0&&(this._tasks=[...this._tasks,...a.map(i=>({...i,isLocal:!0}))]),this._state.update({"cache.tasks":this._tasks},!1)}catch(t){this._error=t.message,this._tasks=(this._state.get("localTasks")||[]).map(e=>({...e,isLocal:!0}))}this._loading=!1,this.render()}_getTasksByStatus(t){return this._getFilteredTasks().filter(a=>a.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 a=this._draggedTask.id,i=this._tasks.find(r=>r.id===a);if(!i)return;let s=i.status;if(s!==e){i.status=e,this.render();try{i.isLocal?this._state.moveLocalTask(a,e):await this._api.moveTask(a,e,0),this.dispatchEvent(new CustomEvent("task-moved",{detail:{taskId:a,oldStatus:s,newStatus:e}}))}catch(r){i.status=s,this.render(),console.error("Failed to move task:",r)}}}_toggleCardExpand(t){this._expandedCards.has(t)?this._expandedCards.delete(t):this._expandedCards.add(t),this.render()}_toggleTaskSelection(t,e){e&&e.stopPropagation(),this._selectedTasks.has(t)?this._selectedTasks.delete(t):this._selectedTasks.add(t),this.render()}_toggleBulkMode(){this._bulkMode=!this._bulkMode,this._bulkMode||this._selectedTasks.clear(),this.render()}async _bulkMove(t){let e=[...this._selectedTasks];for(let a of e){let i=this._tasks.find(s=>String(s.id)===String(a));if(i&&i.status!==t)try{i.isLocal?this._state.moveLocalTask(a,t):await this._api.moveTask(a,t,0),i.status=t}catch(s){console.error("Failed to bulk move task:",a,s)}}this._selectedTasks.clear(),this._bulkMode=!1,this.render(),this._loadTasks()}async _bulkDelete(){let t=[...this._selectedTasks];for(let e of t)try{await this._api.deleteTask(e)}catch(a){console.error("Failed to delete task:",e,a)}this._selectedTasks.clear(),this._bulkMode=!1,this._loadTasks()}_setFilter(t){this._activeFilter=t,this.render()}_getFilteredTasks(){let t=[...this._tasks],e=new Date,a=new Date(e.getFullYear(),e.getMonth(),e.getDate()),i=new Date(a.getTime()-7*24*60*60*1e3);switch(this._activeFilter){case"today":t=t.filter(s=>{let r=s.created_at?new Date(s.created_at):null;return r&&r>=a});break;case"this-week":t=t.filter(s=>{let r=s.created_at?new Date(s.created_at):null;return r&&r>=i});break;case"running":t=t.filter(s=>s.status==="in_progress");break;case"failed":t=t.filter(s=>s.status==="failed"||s.status==="error");break;default:break}return t}_openAddTaskModal(t="pending"){this.dispatchEvent(new CustomEvent("add-task",{detail:{status:t}}))}_openTaskDetail(t){this._selectedTask=t,this.render(),this.dispatchEvent(new CustomEvent("task-click",{detail:{task:t}}))}_closeTaskDetail(){this._selectedTask=null,this.render()}_renderMarkdown(t){if(!t)return"";let e=this._escapeHtml(String(t));return e=e.replace(/```([\s\S]*?)```/g,(a,i)=>`<pre class="md-code">${i.trim()}</pre>`),e=e.replace(/`([^`\n]+)`/g,'<code class="md-inline-code">$1</code>'),e=e.replace(/^###\s+(.+)$/gm,'<h4 class="md-h4">$1</h4>'),e=e.replace(/^##\s+(.+)$/gm,'<h3 class="md-h3">$1</h3>'),e=e.replace(/^#\s+(.+)$/gm,'<h2 class="md-h2">$1</h2>'),e=e.replace(/\*\*([^*\n]+)\*\*/g,"<strong>$1</strong>"),e=e.replace(/(^|[^*])\*([^*\n]+)\*/g,"$1<em>$2</em>"),e=e.replace(/(?:^|\n)((?:[-*]\s+.+(?:\n|$))+)/g,(a,i)=>`
1944
- <ul class="md-list">${i.trim().split(/\n/).map(r=>r.replace(/^[-*]\s+/,"")).map(r=>`<li>${r}</li>`).join("")}</ul>`),e=e.split(/\n{2,}/).map(a=>/^<(h\d|ul|ol|pre)/.test(a.trim())?a:`<p class="md-p">${a.replace(/\n/g,"<br>")}</p>`).join(""),e}_formatTimestamp(t){if(!t)return"";try{let e=new Date(t);return isNaN(e.getTime())?this._escapeHtml(String(t)):e.toLocaleString()}catch{return this._escapeHtml(String(t))}}_phaseClass(t){let e=String(t||"").toLowerCase();return["reason","plan","planning"].includes(e)?"phase-reason":["act","execute","execution","implement"].includes(e)?"phase-act":["reflect","review"].includes(e)?"phase-reflect":["verify","test","gate"].includes(e)?"phase-verify":"phase-default"}_logLevelClass(t){let e=String(t||"info").toLowerCase();return e==="error"||e==="fatal"?"log-error":e==="warn"||e==="warning"?"log-warn":e==="debug"||e==="trace"?"log-debug":"log-info"}_renderTaskDetailModal(t){if(!t)return"";let e=(t.priority||"medium").toLowerCase(),a=e.charAt(0).toUpperCase()+e.slice(1),i=t.status||"pending",s=i.replace(/_/g," ").replace(/\b\w/g,m=>m.toUpperCase()),r=t.metadata||{},o=t.acceptance_criteria||[],n=t.context_files||[],l=t.specification||"",c=t.description||"",p=Array.isArray(t.notes)?t.notes:[],u=Array.isArray(t.logs)?t.logs:[],b=t.full_content||"";return`
1955
+ `}};customElements.get("loki-overview")||customElements.define("loki-overview",O);var ce=[{id:"pending",label:"Pending",status:"pending",color:"var(--loki-text-muted)"},{id:"in_progress",label:"In Progress",status:"in_progress",color:"var(--loki-blue)"},{id:"review",label:"In Review",status:"review",color:"var(--loki-purple)"},{id:"done",label:"Completed",status:"done",color:"var(--loki-green)"}],q=class extends h{static get observedAttributes(){return["api-url","project-id","theme","readonly"]}constructor(){super(),this._tasks=[],this._loading=!0,this._error=null,this._draggedTask=null,this._selectedTask=null,this._expandedCards=new Set,this._selectedTasks=new Set,this._bulkMode=!1,this._activeFilter="all",this._api=null,this._state=B()}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadTasks()}disconnectedCallback(){super.disconnectedCallback(),this._api&&(this._api.removeEventListener(m.TASK_CREATED,this._onTaskEvent),this._api.removeEventListener(m.TASK_UPDATED,this._onTaskEvent),this._api.removeEventListener(m.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(m.TASK_CREATED,this._onTaskEvent),this._api.removeEventListener(m.TASK_UPDATED,this._onTaskEvent),this._api.removeEventListener(m.TASK_DELETED,this._onTaskEvent)),this._onTaskEvent=()=>this._loadTasks(),this._api.addEventListener(m.TASK_CREATED,this._onTaskEvent),this._api.addEventListener(m.TASK_UPDATED,this._onTaskEvent),this._api.addEventListener(m.TASK_DELETED,this._onTaskEvent)}async _loadTasks(){this._loading=!0,this._error=null,this.render();try{let t=this.getAttribute("project-id"),e=t?{projectId:parseInt(t)}:{};this._tasks=await this._api.listTasks(e);let i=this._state.get("localTasks")||[];i.length>0&&(this._tasks=[...this._tasks,...i.map(a=>({...a,isLocal:!0}))]),this._state.update({"cache.tasks":this._tasks},!1)}catch(t){this._error=t.message,this._tasks=(this._state.get("localTasks")||[]).map(e=>({...e,isLocal:!0}))}this._loading=!1,this.render()}_getTasksByStatus(t){return this._getFilteredTasks().filter(i=>i.status?.toLowerCase().replace(/-/g,"_")===t)}_handleDragStart(t,e){this.hasAttribute("readonly")||(this._draggedTask=e,t.target.classList.add("dragging"),t.dataTransfer.effectAllowed="move",t.dataTransfer.setData("text/plain",e.id.toString()))}_handleDragEnd(t){t.target.classList.remove("dragging"),this._draggedTask=null,this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(e=>{e.classList.remove("drag-over")})}_handleDragOver(t){t.preventDefault(),t.dataTransfer.dropEffect="move"}_handleDragEnter(t){t.preventDefault(),t.currentTarget.classList.add("drag-over")}_handleDragLeave(t){t.currentTarget.contains(t.relatedTarget)||t.currentTarget.classList.remove("drag-over")}async _handleDrop(t,e){if(t.preventDefault(),t.currentTarget.classList.remove("drag-over"),!this._draggedTask||this.hasAttribute("readonly"))return;let i=this._draggedTask.id,a=this._tasks.find(r=>r.id===i);if(!a)return;let s=a.status;if(s!==e){a.status=e,this.render();try{a.isLocal?this._state.moveLocalTask(i,e):await this._api.moveTask(i,e,0),this.dispatchEvent(new CustomEvent("task-moved",{detail:{taskId:i,oldStatus:s,newStatus:e}}))}catch(r){a.status=s,this.render(),console.error("Failed to move task:",r)}}}_toggleCardExpand(t){this._expandedCards.has(t)?this._expandedCards.delete(t):this._expandedCards.add(t),this.render()}_toggleTaskSelection(t,e){e&&e.stopPropagation(),this._selectedTasks.has(t)?this._selectedTasks.delete(t):this._selectedTasks.add(t),this.render()}_toggleBulkMode(){this._bulkMode=!this._bulkMode,this._bulkMode||this._selectedTasks.clear(),this.render()}async _bulkMove(t){let e=[...this._selectedTasks];for(let i of e){let a=this._tasks.find(s=>String(s.id)===String(i));if(a&&a.status!==t)try{a.isLocal?this._state.moveLocalTask(i,t):await this._api.moveTask(i,t,0),a.status=t}catch(s){console.error("Failed to bulk move task:",i,s)}}this._selectedTasks.clear(),this._bulkMode=!1,this.render(),this._loadTasks()}async _bulkDelete(){let t=[...this._selectedTasks];for(let e of t)try{await this._api.deleteTask(e)}catch(i){console.error("Failed to delete task:",e,i)}this._selectedTasks.clear(),this._bulkMode=!1,this._loadTasks()}_setFilter(t){this._activeFilter=t,this.render()}_getFilteredTasks(){let t=[...this._tasks],e=new Date,i=new Date(e.getFullYear(),e.getMonth(),e.getDate()),a=new Date(i.getTime()-7*24*60*60*1e3);switch(this._activeFilter){case"today":t=t.filter(s=>{let r=s.created_at?new Date(s.created_at):null;return r&&r>=i});break;case"this-week":t=t.filter(s=>{let r=s.created_at?new Date(s.created_at):null;return r&&r>=a});break;case"running":t=t.filter(s=>s.status==="in_progress");break;case"failed":t=t.filter(s=>s.status==="failed"||s.status==="error");break;default:break}return t}_openAddTaskModal(t="pending"){this.dispatchEvent(new CustomEvent("add-task",{detail:{status:t}}))}_openTaskDetail(t){this._selectedTask=t,this.render(),this.dispatchEvent(new CustomEvent("task-click",{detail:{task:t}}))}_closeTaskDetail(){this._selectedTask=null,this.render()}_renderMarkdown(t){if(!t)return"";let e=this._escapeHtml(String(t));return e=e.replace(/```([\s\S]*?)```/g,(i,a)=>`<pre class="md-code">${a.trim()}</pre>`),e=e.replace(/`([^`\n]+)`/g,'<code class="md-inline-code">$1</code>'),e=e.replace(/^###\s+(.+)$/gm,'<h4 class="md-h4">$1</h4>'),e=e.replace(/^##\s+(.+)$/gm,'<h3 class="md-h3">$1</h3>'),e=e.replace(/^#\s+(.+)$/gm,'<h2 class="md-h2">$1</h2>'),e=e.replace(/\*\*([^*\n]+)\*\*/g,"<strong>$1</strong>"),e=e.replace(/(^|[^*])\*([^*\n]+)\*/g,"$1<em>$2</em>"),e=e.replace(/(?:^|\n)((?:[-*]\s+.+(?:\n|$))+)/g,(i,a)=>`
1956
+ <ul class="md-list">${a.trim().split(/\n/).map(r=>r.replace(/^[-*]\s+/,"")).map(r=>`<li>${r}</li>`).join("")}</ul>`),e=e.split(/\n{2,}/).map(i=>/^<(h\d|ul|ol|pre)/.test(i.trim())?i:`<p class="md-p">${i.replace(/\n/g,"<br>")}</p>`).join(""),e}_formatTimestamp(t){if(!t)return"";try{let e=new Date(t);return isNaN(e.getTime())?this._escapeHtml(String(t)):e.toLocaleString()}catch{return this._escapeHtml(String(t))}}_phaseClass(t){let e=String(t||"").toLowerCase();return["reason","plan","planning"].includes(e)?"phase-reason":["act","execute","execution","implement"].includes(e)?"phase-act":["reflect","review"].includes(e)?"phase-reflect":["verify","test","gate"].includes(e)?"phase-verify":"phase-default"}_logLevelClass(t){let e=String(t||"info").toLowerCase();return e==="error"||e==="fatal"?"log-error":e==="warn"||e==="warning"?"log-warn":e==="debug"||e==="trace"?"log-debug":"log-info"}_renderTaskDetailModal(t){if(!t)return"";let e=(t.priority||"medium").toLowerCase(),i=e.charAt(0).toUpperCase()+e.slice(1),a=t.status||"pending",s=a.replace(/_/g," ").replace(/\b\w/g,v=>v.toUpperCase()),r=t.metadata||{},o=t.acceptance_criteria||[],n=t.context_files||[],l=t.specification||"",c=t.description||"",p=Array.isArray(t.notes)?t.notes:[],u=Array.isArray(t.logs)?t.logs:[],b=t.full_content||"";return`
1945
1957
  <div class="modal-overlay" id="task-detail-overlay">
1946
1958
  <div class="modal-container">
1947
1959
  <div class="modal-header">
1948
1960
  <div class="modal-header-left">
1949
1961
  <span class="task-id">${t.isLocal?"LOCAL":"#"+this._escapeHtml(String(t.id))}</span>
1950
- <span class="task-priority ${e}">${a}</span>
1951
- <span class="task-status-badge ${i}">${s}</span>
1962
+ <span class="task-priority ${e}">${i}</span>
1963
+ <span class="task-status-badge ${a}">${s}</span>
1952
1964
  </div>
1953
1965
  <button class="modal-close" id="modal-close-btn" aria-label="Close">&times;</button>
1954
1966
  </div>
@@ -1958,9 +1970,9 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
1958
1970
  <div class="modal-section">
1959
1971
  <h3 class="modal-section-title">Metadata</h3>
1960
1972
  <div class="meta-grid">
1961
- ${Object.entries(r).map(([m,f])=>`
1973
+ ${Object.entries(r).map(([v,f])=>`
1962
1974
  <div class="meta-cell">
1963
- <span class="meta-label">${this._escapeHtml(m.replace(/_/g," "))}</span>
1975
+ <span class="meta-label">${this._escapeHtml(v.replace(/_/g," "))}</span>
1964
1976
  <span class="meta-value">${this._escapeHtml(String(f))}</span>
1965
1977
  </div>
1966
1978
  `).join("")}
@@ -1986,7 +1998,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
1986
1998
  <div class="modal-section">
1987
1999
  <h3 class="modal-section-title">Acceptance Criteria</h3>
1988
2000
  <ul class="criteria-checklist" role="list">
1989
- ${o.map(m=>{let f=m&&typeof m=="object",x=f?m.text||m.title||"":m,w=f?!!m.done:!1;return`<li class="criteria-item">
2001
+ ${o.map(v=>{let f=v&&typeof v=="object",x=f?v.text||v.title||"":v,w=f?!!v.done:!1;return`<li class="criteria-item">
1990
2002
  <span class="criteria-checkbox ${w?"checked":""}" aria-hidden="true">${w?"&#10003;":""}</span>
1991
2003
  <span class="criteria-text ${w?"done":""}">${this._escapeHtml(String(x))}</span>
1992
2004
  </li>`}).join("")}
@@ -1998,7 +2010,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
1998
2010
  <div class="modal-section">
1999
2011
  <h3 class="modal-section-title">Notes</h3>
2000
2012
  <ul class="notes-timeline" role="list">
2001
- ${p.map(m=>{let f=this._formatTimestamp(m&&m.timestamp),x=m&&m.author?this._escapeHtml(String(m.author)):"unknown",w=m&&m.body?this._escapeHtml(String(m.body)):"";return`<li class="note-entry">
2013
+ ${p.map(v=>{let f=this._formatTimestamp(v&&v.timestamp),x=v&&v.author?this._escapeHtml(String(v.author)):"unknown",w=v&&v.body?this._escapeHtml(String(v.body)):"";return`<li class="note-entry">
2002
2014
  <div class="note-meta">
2003
2015
  <span class="note-author">${x}</span>
2004
2016
  ${f?`<span class="note-time">${f}</span>`:""}
@@ -2014,11 +2026,11 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
2014
2026
  <h3 class="modal-section-title">Logs</h3>
2015
2027
  <div class="logs-scroll">
2016
2028
  <ul class="logs-timeline" role="list">
2017
- ${u.map(m=>{let f=this._formatTimestamp(m&&m.timestamp),x=m&&m.iteration!==void 0&&m.iteration!==null?`i${this._escapeHtml(String(m.iteration))}`:"",w=m&&m.phase?String(m.phase):"",Zt=this._phaseClass(w),te=this._logLevelClass(m&&m.level),ee=m&&m.message?this._escapeHtml(String(m.message)):"";return`<li class="log-entry ${te}">
2029
+ ${u.map(v=>{let f=this._formatTimestamp(v&&v.timestamp),x=v&&v.iteration!==void 0&&v.iteration!==null?`i${this._escapeHtml(String(v.iteration))}`:"",w=v&&v.phase?String(v.phase):"",te=this._phaseClass(w),ee=this._logLevelClass(v&&v.level),ie=v&&v.message?this._escapeHtml(String(v.message)):"";return`<li class="log-entry ${ee}">
2018
2030
  ${f?`<span class="log-time">${f}</span>`:""}
2019
2031
  ${x?`<span class="log-iter">${x}</span>`:""}
2020
- ${w?`<span class="log-phase ${Zt}">${this._escapeHtml(w)}</span>`:""}
2021
- <span class="log-message">${ee}</span>
2032
+ ${w?`<span class="log-phase ${te}">${this._escapeHtml(w)}</span>`:""}
2033
+ <span class="log-message">${ie}</span>
2022
2034
  </li>`}).join("")}
2023
2035
  </ul>
2024
2036
  </div>
@@ -2029,7 +2041,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
2029
2041
  <div class="modal-section">
2030
2042
  <h3 class="modal-section-title">Context Files</h3>
2031
2043
  <ul class="context-files-list">
2032
- ${n.map(m=>`<li class="mono">${this._escapeHtml(m)}</li>`).join("")}
2044
+ ${n.map(v=>`<li class="mono">${this._escapeHtml(v)}</li>`).join("")}
2033
2045
  </ul>
2034
2046
  </div>
2035
2047
  `:""}
@@ -2894,13 +2906,13 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
2894
2906
  display: block;
2895
2907
  }
2896
2908
  </style>
2897
- `,e=i=>{switch(i){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"/>'}},a;if(this._loading)a='<div class="loading">Loading tasks...</div>';else if(this._error&&this._tasks.length===0)a=`<div class="error">Error: ${this._escapeHtml(this._error)}</div>`;else{let i=this.hasAttribute("readonly"),s=[{id:"all",label:"All"},{id:"today",label:"Today"},{id:"this-week",label:"This Week"},{id:"running",label:"Running"},{id:"failed",label:"Failed"}],r=o=>{if(!o.assigned_agent_id&&!o.agent_type)return"";let n=(o.agent_type||"").toLowerCase(),l="AG",c="default",p="idle",u=`Agent #${o.assigned_agent_id||"?"}`;return n.includes("architect")||n==="ar"?(l="AR",c="architect",u="Architect"):n.includes("develop")||n==="dv"?(l="DV",c="developer",u="Developer"):n.includes("test")||n==="ts"?(l="TS",c="tester",u="Tester"):(n.includes("review")||n==="rv")&&(l="RV",c="reviewer",u="Reviewer"),o.status==="in_progress"&&(p="active"),(o.status==="failed"||o.status==="error")&&(p="failed"),`
2909
+ `,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._escapeHtml(this._error)}</div>`;else{let a=this.hasAttribute("readonly"),s=[{id:"all",label:"All"},{id:"today",label:"Today"},{id:"this-week",label:"This Week"},{id:"running",label:"Running"},{id:"failed",label:"Failed"}],r=o=>{if(!o.assigned_agent_id&&!o.agent_type)return"";let n=(o.agent_type||"").toLowerCase(),l="AG",c="default",p="idle",u=`Agent #${o.assigned_agent_id||"?"}`;return n.includes("architect")||n==="ar"?(l="AR",c="architect",u="Architect"):n.includes("develop")||n==="dv"?(l="DV",c="developer",u="Developer"):n.includes("test")||n==="ts"?(l="TS",c="tester",u="Tester"):(n.includes("review")||n==="rv")&&(l="RV",c="reviewer",u="Reviewer"),o.status==="in_progress"&&(p="active"),(o.status==="failed"||o.status==="error")&&(p="failed"),`
2898
2910
  <div class="agent-avatar ${c}">
2899
2911
  ${l}
2900
2912
  <span class="agent-status-dot ${p}"></span>
2901
2913
  <span class="agent-tooltip">${this._escapeHtml(u)}</span>
2902
2914
  </div>
2903
- `};a=`
2915
+ `};i=`
2904
2916
  <div class="filter-bar">
2905
2917
  <span class="filter-label">Filter:</span>
2906
2918
  ${s.map(o=>`
@@ -2918,7 +2930,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
2918
2930
  `:""}
2919
2931
 
2920
2932
  <div class="kanban-board">
2921
- ${de.map(o=>{let n=this._getTasksByStatus(o.status);return`
2933
+ ${ce.map(o=>{let n=this._getTasksByStatus(o.status);return`
2922
2934
  <div class="kanban-column" data-status="${o.status}">
2923
2935
  <div class="kanban-column-header">
2924
2936
  <span class="kanban-column-title">
@@ -2932,12 +2944,12 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
2932
2944
  <div class="kanban-tasks" data-status="${o.status}">
2933
2945
  ${n.length===0?'<div class="empty-column">No tasks</div>':""}
2934
2946
  ${n.map(l=>{let c=String(l.id||""),p=this._expandedCards.has(c),u=this._selectedTasks.has(c);return`
2935
- <div class="task-card ${!i&&!l.fromServer?"draggable":""} ${l.isLocal?"local":""} ${p?"expanded":""} ${u?"selected":""}"
2947
+ <div class="task-card ${!a&&!l.fromServer?"draggable":""} ${l.isLocal?"local":""} ${p?"expanded":""} ${u?"selected":""}"
2936
2948
  data-task-id="${this._escapeHtml(c)}"
2937
2949
  tabindex="0"
2938
2950
  role="button"
2939
2951
  aria-label="Task: ${this._escapeHtml(l.title||"Untitled")}, ${this._escapeHtml(String(l.priority||"medium"))} priority"
2940
- ${!i&&!l.fromServer?'draggable="true"':""}>
2952
+ ${!a&&!l.fromServer?'draggable="true"':""}>
2941
2953
  <div class="task-card-header">
2942
2954
  <div style="display:flex;align-items:center;gap:6px;">
2943
2955
  ${this._bulkMode?`<div class="task-checkbox ${u?"checked":""}" data-check-id="${this._escapeHtml(c)}"></div>`:""}
@@ -2970,7 +2982,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
2970
2982
  </div>
2971
2983
  `}).join("")}
2972
2984
  </div>
2973
- ${!i&&o.status==="pending"?`
2985
+ ${!a&&o.status==="pending"?`
2974
2986
  <button class="add-task-btn" data-status="${o.status}" aria-label="Add new task to ${o.label}">+ Add Task</button>
2975
2987
  `:""}
2976
2988
  </div>
@@ -2999,10 +3011,10 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
2999
3011
  </button>
3000
3012
  </div>
3001
3013
  </div>
3002
- ${a}
3014
+ ${i}
3003
3015
  </div>
3004
3016
  ${this._selectedTask?this._renderTaskDetailModal(this._selectedTask):""}
3005
- `,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("refresh-btn");t&&t.addEventListener("click",()=>this._loadTasks());let e=this.shadowRoot.getElementById("bulk-toggle-btn");e&&e.addEventListener("click",()=>this._toggleBulkMode()),this.shadowRoot.querySelectorAll(".filter-pill").forEach(s=>{s.addEventListener("click",()=>this._setFilter(s.dataset.filter))}),this.shadowRoot.querySelectorAll(".bulk-btn").forEach(s=>{s.addEventListener("click",()=>{let r=s.dataset.bulkAction;r==="delete"?this._bulkDelete():this._bulkMove(r)})}),this.shadowRoot.querySelectorAll(".add-task-btn").forEach(s=>{s.addEventListener("click",()=>{this._openAddTaskModal(s.dataset.status)})}),this.shadowRoot.querySelectorAll(".task-checkbox").forEach(s=>{s.addEventListener("click",r=>{r.stopPropagation(),this._toggleTaskSelection(s.dataset.checkId,r)})}),this.shadowRoot.querySelectorAll(".expand-toggle").forEach(s=>{s.addEventListener("click",r=>{r.stopPropagation(),this._toggleCardExpand(s.dataset.expandId)})}),this.shadowRoot.querySelectorAll(".task-card").forEach(s=>{let r=s.dataset.taskId,o=this._tasks.find(n=>n.id.toString()===r);o&&(s.addEventListener("click",n=>{if(this._bulkMode){this._toggleTaskSelection(r,n);return}this._openTaskDetail(o)}),s.addEventListener("keydown",n=>{n.key==="Enter"||n.key===" "?(n.preventDefault(),this._bulkMode?this._toggleTaskSelection(r,n):this._openTaskDetail(o)):(n.key==="ArrowDown"||n.key==="ArrowUp")&&(n.preventDefault(),this._navigateTaskCards(s,n.key==="ArrowDown"?"next":"prev"))}),s.classList.contains("draggable")&&(s.addEventListener("dragstart",n=>this._handleDragStart(n,o)),s.addEventListener("dragend",n=>this._handleDragEnd(n))))}),this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(s=>{s.addEventListener("dragover",r=>this._handleDragOver(r)),s.addEventListener("dragenter",r=>this._handleDragEnter(r)),s.addEventListener("dragleave",r=>this._handleDragLeave(r)),s.addEventListener("drop",r=>this._handleDrop(r,s.dataset.status))});let a=this.shadowRoot.getElementById("modal-close-btn");a&&a.addEventListener("click",()=>this._closeTaskDetail());let i=this.shadowRoot.getElementById("task-detail-overlay");i&&i.addEventListener("click",s=>{s.target===i&&this._closeTaskDetail()})}_escapeHtml(t){let e=document.createElement("div");return e.textContent=t,e.innerHTML}_navigateTaskCards(t,e){let a=Array.from(this.shadowRoot.querySelectorAll(".task-card")),i=a.indexOf(t);if(i===-1)return;let s=e==="next"?i+1:i-1;s>=0&&s<a.length&&a[s].focus()}};customElements.get("loki-task-board")||customElements.define("loki-task-board",q);var J=class extends h{static get observedAttributes(){return["api-url","theme","compact"]}constructor(){super(),this._status={mode:"offline",phase:null,iteration:null,complexity:null,connected:!1,version:null,uptime:0,activeAgents:0,pendingTasks:0},this._api=null,this._state=B(),this._statusUpdateHandler=null,this._connectedHandler=null,this._disconnectedHandler=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(v.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(v.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(v.DISCONNECTED,this._disconnectedHandler))}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadStatus()),t==="theme"&&this._applyTheme(),t==="compact"&&this.render())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t}),this._statusUpdateHandler=e=>this._updateFromStatus(e.detail),this._connectedHandler=()=>{this._status.connected=!0,this.render()},this._disconnectedHandler=()=>{this._status.connected=!1,this._status.mode="offline",this.render()},this._api.addEventListener(v.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(v.CONNECTED,this._connectedHandler),this._api.addEventListener(v.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){try{let t=await this._api.getStatus();this._updateFromStatus(t)}catch{this._status.connected=!1,this._status.mode="offline",this.render()}}_updateFromStatus(t){t&&(this._status={...this._status,connected:!0,mode:t.status||"running",version:t.version,uptime:t.uptime_seconds||0,activeAgents:t.running_agents||0,pendingTasks:t.pending_tasks||0,phase:t.phase,iteration:t.iteration,complexity:t.complexity},this._state.updateSession({connected:!0,mode:this._status.mode,lastSync:new Date().toISOString()}),this.render())}_startPolling(){this._ownPollInterval=setInterval(async()=>{try{let t=await this._api.getStatus();this._updateFromStatus(t)}catch{this._status.connected=!1,this._status.mode="offline",this.render()}},3e3)}_stopPolling(){this._ownPollInterval&&(clearInterval(this._ownPollInterval),this._ownPollInterval=null)}_formatUptime(t){if(!t||t<0)return"--";let e=Math.floor(t/3600),a=Math.floor(t%3600/60),i=Math.floor(t%60);return e>0?`${e}h ${a}m`:a>0?`${a}m ${i}s`:`${i}s`}_escapeHtml(t){let e=document.createElement("div");return e.textContent=String(t??""),e.innerHTML}_getStatusClass(){switch(this._status.mode){case"running":case"autonomous":return"active";case"paused":return"paused";case"stopped":return"stopped";case"error":return"error";default:return"offline"}}_getStatusLabel(){switch(this._status.mode){case"running":case"autonomous":return"AUTONOMOUS";case"paused":return"PAUSED";case"stopped":return"STOPPED";case"error":return"ERROR";default:return"OFFLINE"}}_triggerStart(){this.dispatchEvent(new CustomEvent("session-start",{detail:this._status}))}async _triggerPause(){try{let t=await this._api.pauseSession();if(t&&t.error)throw new Error(t.error);this._status.mode="paused",this.render(),this.dispatchEvent(new CustomEvent("session-pause",{detail:this._status}))}catch(t){console.error("Failed to pause session:",t),this.render()}}async _triggerResume(){try{let t=await this._api.resumeSession();if(t&&t.error)throw new Error(t.error);this._status.mode="running",this.render(),this.dispatchEvent(new CustomEvent("session-resume",{detail:this._status}))}catch(t){console.error("Failed to resume session:",t),this.render()}}async _triggerStop(){try{let t=await this._api.stopSession();if(t&&t.error)throw new Error(t.error);this._status.mode="stopped",this.render(),this.dispatchEvent(new CustomEvent("session-stop",{detail:this._status}))}catch(t){console.error("Failed to stop session:",t),this.render()}}render(){let t=this.hasAttribute("compact"),e=this._getStatusClass(),a=this._getStatusLabel(),i=["running","autonomous"].includes(this._status.mode),s=this._status.mode==="paused",r=`
3017
+ `,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("refresh-btn");t&&t.addEventListener("click",()=>this._loadTasks());let e=this.shadowRoot.getElementById("bulk-toggle-btn");e&&e.addEventListener("click",()=>this._toggleBulkMode()),this.shadowRoot.querySelectorAll(".filter-pill").forEach(s=>{s.addEventListener("click",()=>this._setFilter(s.dataset.filter))}),this.shadowRoot.querySelectorAll(".bulk-btn").forEach(s=>{s.addEventListener("click",()=>{let r=s.dataset.bulkAction;r==="delete"?this._bulkDelete():this._bulkMove(r)})}),this.shadowRoot.querySelectorAll(".add-task-btn").forEach(s=>{s.addEventListener("click",()=>{this._openAddTaskModal(s.dataset.status)})}),this.shadowRoot.querySelectorAll(".task-checkbox").forEach(s=>{s.addEventListener("click",r=>{r.stopPropagation(),this._toggleTaskSelection(s.dataset.checkId,r)})}),this.shadowRoot.querySelectorAll(".expand-toggle").forEach(s=>{s.addEventListener("click",r=>{r.stopPropagation(),this._toggleCardExpand(s.dataset.expandId)})}),this.shadowRoot.querySelectorAll(".task-card").forEach(s=>{let r=s.dataset.taskId,o=this._tasks.find(n=>n.id.toString()===r);o&&(s.addEventListener("click",n=>{if(this._bulkMode){this._toggleTaskSelection(r,n);return}this._openTaskDetail(o)}),s.addEventListener("keydown",n=>{n.key==="Enter"||n.key===" "?(n.preventDefault(),this._bulkMode?this._toggleTaskSelection(r,n):this._openTaskDetail(o)):(n.key==="ArrowDown"||n.key==="ArrowUp")&&(n.preventDefault(),this._navigateTaskCards(s,n.key==="ArrowDown"?"next":"prev"))}),s.classList.contains("draggable")&&(s.addEventListener("dragstart",n=>this._handleDragStart(n,o)),s.addEventListener("dragend",n=>this._handleDragEnd(n))))}),this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(s=>{s.addEventListener("dragover",r=>this._handleDragOver(r)),s.addEventListener("dragenter",r=>this._handleDragEnter(r)),s.addEventListener("dragleave",r=>this._handleDragLeave(r)),s.addEventListener("drop",r=>this._handleDrop(r,s.dataset.status))});let i=this.shadowRoot.getElementById("modal-close-btn");i&&i.addEventListener("click",()=>this._closeTaskDetail());let a=this.shadowRoot.getElementById("task-detail-overlay");a&&a.addEventListener("click",s=>{s.target===a&&this._closeTaskDetail()})}_escapeHtml(t){let e=document.createElement("div");return e.textContent=t,e.innerHTML}_navigateTaskCards(t,e){let i=Array.from(this.shadowRoot.querySelectorAll(".task-card")),a=i.indexOf(t);if(a===-1)return;let s=e==="next"?a+1:a-1;s>=0&&s<i.length&&i[s].focus()}};customElements.get("loki-task-board")||customElements.define("loki-task-board",q);var J=class extends h{static get observedAttributes(){return["api-url","theme","compact"]}constructor(){super(),this._status={mode:"offline",phase:null,iteration:null,complexity:null,connected:!1,version:null,uptime:0,activeAgents:0,pendingTasks:0},this._api=null,this._state=B(),this._statusUpdateHandler=null,this._connectedHandler=null,this._disconnectedHandler=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(m.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(m.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(m.DISCONNECTED,this._disconnectedHandler))}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadStatus()),t==="theme"&&this._applyTheme(),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(m.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(m.CONNECTED,this._connectedHandler),this._api.addEventListener(m.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){try{let t=await this._api.getStatus();this._updateFromStatus(t)}catch{this._status.connected=!1,this._status.mode="offline",this.render()}}_updateFromStatus(t){t&&(this._status={...this._status,connected:!0,mode:t.status||"running",version:t.version,uptime:t.uptime_seconds||0,activeAgents:t.running_agents||0,pendingTasks:t.pending_tasks||0,phase:t.phase,iteration:t.iteration,complexity:t.complexity},this._state.updateSession({connected:!0,mode:this._status.mode,lastSync:new Date().toISOString()}),this.render())}_startPolling(){this._ownPollInterval=setInterval(async()=>{try{let t=await this._api.getStatus();this._updateFromStatus(t)}catch{this._status.connected=!1,this._status.mode="offline",this.render()}},3e3)}_stopPolling(){this._ownPollInterval&&(clearInterval(this._ownPollInterval),this._ownPollInterval=null)}_formatUptime(t){if(!t||t<0)return"--";let e=Math.floor(t/3600),i=Math.floor(t%3600/60),a=Math.floor(t%60);return e>0?`${e}h ${i}m`:i>0?`${i}m ${a}s`:`${a}s`}_escapeHtml(t){let e=document.createElement("div");return e.textContent=String(t??""),e.innerHTML}_getStatusClass(){switch(this._status.mode){case"running":case"autonomous":return"active";case"paused":return"paused";case"stopped":return"stopped";case"error":return"error";default:return"offline"}}_getStatusLabel(){switch(this._status.mode){case"running":case"autonomous":return"AUTONOMOUS";case"paused":return"PAUSED";case"stopped":return"STOPPED";case"error":return"ERROR";default:return"OFFLINE"}}_triggerStart(){this.dispatchEvent(new CustomEvent("session-start",{detail:this._status}))}async _triggerPause(){try{let t=await this._api.pauseSession();if(t&&t.error)throw new Error(t.error);this._status.mode="paused",this.render(),this.dispatchEvent(new CustomEvent("session-pause",{detail:this._status}))}catch(t){console.error("Failed to pause session:",t),this.render()}}async _triggerResume(){try{let t=await this._api.resumeSession();if(t&&t.error)throw new Error(t.error);this._status.mode="running",this.render(),this.dispatchEvent(new CustomEvent("session-resume",{detail:this._status}))}catch(t){console.error("Failed to resume session:",t),this.render()}}async _triggerStop(){try{let t=await this._api.stopSession();if(t&&t.error)throw new Error(t.error);this._status.mode="stopped",this.render(),this.dispatchEvent(new CustomEvent("session-stop",{detail:this._status}))}catch(t){console.error("Failed to stop session:",t),this.render()}}render(){let t=this.hasAttribute("compact"),e=this._getStatusClass(),i=this._getStatusLabel(),a=["running","autonomous"].includes(this._status.mode),s=this._status.mode==="paused",r=`
3006
3018
  <style>
3007
3019
  ${this.getBaseStyles()}
3008
3020
 
@@ -3190,7 +3202,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
3190
3202
  <div class="status-row">
3191
3203
  <span class="status-value">
3192
3204
  <span class="status-dot ${e}"></span>
3193
- ${a}
3205
+ ${i}
3194
3206
  </span>
3195
3207
  </div>
3196
3208
  <div class="control-buttons" role="group" aria-label="Session controls">
@@ -3200,12 +3212,12 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
3200
3212
  Resume
3201
3213
  </button>
3202
3214
  `:`
3203
- <button class="control-btn pause" id="pause-btn" aria-label="Pause session" ${i?"":"disabled"}>
3215
+ <button class="control-btn pause" id="pause-btn" aria-label="Pause session" ${a?"":"disabled"}>
3204
3216
  <svg viewBox="0 0 24 24" aria-hidden="true"><rect x="6" y="4" width="4" height="16"/><rect x="14" y="4" width="4" height="16"/></svg>
3205
3217
  Pause
3206
3218
  </button>
3207
3219
  `}
3208
- <button class="control-btn stop" id="stop-btn" aria-label="Stop session" ${!i&&!s?"disabled":""}>
3220
+ <button class="control-btn stop" id="stop-btn" aria-label="Stop session" ${!a&&!s?"disabled":""}>
3209
3221
  <svg viewBox="0 0 24 24" aria-hidden="true"><rect x="4" y="4" width="16" height="16" rx="2"/></svg>
3210
3222
  Stop
3211
3223
  </button>
@@ -3219,7 +3231,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
3219
3231
  <span class="status-label">Mode</span>
3220
3232
  <span class="status-value">
3221
3233
  <span class="status-dot ${e}"></span>
3222
- ${a}
3234
+ ${i}
3223
3235
  </span>
3224
3236
  </div>
3225
3237
 
@@ -3250,12 +3262,12 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
3250
3262
  Resume
3251
3263
  </button>
3252
3264
  `:`
3253
- <button class="control-btn pause" id="pause-btn" aria-label="Pause session" ${i?"":"disabled"}>
3265
+ <button class="control-btn pause" id="pause-btn" aria-label="Pause session" ${a?"":"disabled"}>
3254
3266
  <svg viewBox="0 0 24 24" aria-hidden="true"><rect x="6" y="4" width="4" height="16"/><rect x="14" y="4" width="4" height="16"/></svg>
3255
3267
  Pause
3256
3268
  </button>
3257
3269
  `}
3258
- <button class="control-btn stop" id="stop-btn" aria-label="Stop session" ${!i&&!s?"disabled":""}>
3270
+ <button class="control-btn stop" id="stop-btn" aria-label="Stop session" ${!a&&!s?"disabled":""}>
3259
3271
  <svg viewBox="0 0 24 24" aria-hidden="true"><rect x="4" y="4" width="16" height="16" rx="2"/></svg>
3260
3272
  Stop
3261
3273
  </button>
@@ -3281,13 +3293,13 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
3281
3293
  `;this.shadowRoot.innerHTML=`
3282
3294
  ${r}
3283
3295
  ${t?o:n}
3284
- `,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("pause-btn"),e=this.shadowRoot.getElementById("resume-btn"),a=this.shadowRoot.getElementById("stop-btn"),i=this.shadowRoot.getElementById("start-btn");t&&t.addEventListener("click",()=>this._triggerPause()),e&&e.addEventListener("click",()=>this._triggerResume()),a&&a.addEventListener("click",()=>this._triggerStop()),i&&i.addEventListener("click",()=>this._triggerStart())}};customElements.get("loki-session-control")||customElements.define("loki-session-control",J);var Nt={info:{color:"var(--loki-blue)",label:"INFO"},success:{color:"var(--loki-green)",label:"SUCCESS"},warning:{color:"var(--loki-yellow)",label:"WARN"},error:{color:"var(--loki-red)",label:"ERROR"},step:{color:"var(--loki-purple)",label:"STEP"},agent:{color:"var(--loki-accent)",label:"AGENT"},debug:{color:"var(--loki-text-muted)",label:"DEBUG"}},G=class extends h{static get observedAttributes(){return["api-url","max-lines","auto-scroll","theme","log-file"]}constructor(){super(),this._logs=[],this._maxLines=500,this._autoScroll=!0,this._filter="",this._levelFilter="all",this._api=null,this._pollInterval=null,this._logMessageHandler=null}connectedCallback(){super.connectedCallback(),this._maxLines=parseInt(this.getAttribute("max-lines"))||500,this._autoScroll=this.hasAttribute("auto-scroll"),this._setupApi(),this._startLogPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopLogPolling(),this._api&&this._logMessageHandler&&this._api.removeEventListener(v.LOG_MESSAGE,this._logMessageHandler)}attributeChangedCallback(t,e,a){if(e!==a)switch(t){case"api-url":this._api&&(this._api.baseUrl=a);break;case"max-lines":this._maxLines=parseInt(a)||500,this._trimLogs(),this.render();break;case"auto-scroll":this._autoScroll=this.hasAttribute("auto-scroll"),this.render();break;case"theme":this._applyTheme();break}}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t}),this._logMessageHandler=e=>this._addLog(e.detail),this._api.addEventListener(v.LOG_MESSAGE,this._logMessageHandler)}_startLogPolling(){let t=this.getAttribute("log-file");t?this._pollLogFile(t):this._pollApiLogs()}async _pollApiLogs(){let t=0,e=async()=>{try{let a=await this._api.getLogs(200);if(Array.isArray(a)&&a.length>t){let i=a.slice(t);for(let s of i)s.message&&s.message.trim()&&this._addLog({message:s.message,level:s.level||"info",timestamp:s.timestamp||new Date().toLocaleTimeString()});t=a.length}}catch{}};e(),this._apiPollInterval=setInterval(e,2e3)}async _pollLogFile(t){let e=0,a=async()=>{try{let i=await fetch(`${t}?t=${Date.now()}`,{credentials:"include"});if(!i.ok)return;let r=(await i.text()).split(`
3285
- `);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{}};a(),this._pollInterval=setInterval(a,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 a=t.match(/^(\d{2}:\d{2}:\d{2})\s+(\w+)\s+(.+)$/);return a?{timestamp:a[1],level:a[2].toLowerCase(),message:a[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(`
3286
- `),e=new Blob([t],{type:"text/plain"}),a=URL.createObjectURL(e),i=document.createElement("a");i.href=a,i.download=`loki-logs-${new Date().toISOString().split("T")[0]}.txt`,i.click(),URL.revokeObjectURL(a)}_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(a=>{let i=Nt[a.level]||Nt.info;return`
3296
+ `,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("pause-btn"),e=this.shadowRoot.getElementById("resume-btn"),i=this.shadowRoot.getElementById("stop-btn"),a=this.shadowRoot.getElementById("start-btn");t&&t.addEventListener("click",()=>this._triggerPause()),e&&e.addEventListener("click",()=>this._triggerResume()),i&&i.addEventListener("click",()=>this._triggerStop()),a&&a.addEventListener("click",()=>this._triggerStart())}};customElements.get("loki-session-control")||customElements.define("loki-session-control",J);var Ot={info:{color:"var(--loki-blue)",label:"INFO"},success:{color:"var(--loki-green)",label:"SUCCESS"},warning:{color:"var(--loki-yellow)",label:"WARN"},error:{color:"var(--loki-red)",label:"ERROR"},step:{color:"var(--loki-purple)",label:"STEP"},agent:{color:"var(--loki-accent)",label:"AGENT"},debug:{color:"var(--loki-text-muted)",label:"DEBUG"}},G=class extends h{static get observedAttributes(){return["api-url","max-lines","auto-scroll","theme","log-file"]}constructor(){super(),this._logs=[],this._maxLines=500,this._autoScroll=!0,this._filter="",this._levelFilter="all",this._api=null,this._pollInterval=null,this._logMessageHandler=null}connectedCallback(){super.connectedCallback(),this._maxLines=parseInt(this.getAttribute("max-lines"))||500,this._autoScroll=this.hasAttribute("auto-scroll"),this._setupApi(),this._startLogPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopLogPolling(),this._api&&this._logMessageHandler&&this._api.removeEventListener(m.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(m.LOG_MESSAGE,this._logMessageHandler)}_startLogPolling(){let t=this.getAttribute("log-file");t?this._pollLogFile(t):this._pollApiLogs()}async _pollApiLogs(){let t=0,e=async()=>{try{let i=await this._api.getLogs(200);if(Array.isArray(i)&&i.length>t){let a=i.slice(t);for(let s of a)s.message&&s.message.trim()&&this._addLog({message:s.message,level:s.level||"info",timestamp:s.timestamp||new Date().toLocaleTimeString()});t=i.length}}catch{}};e(),this._apiPollInterval=setInterval(e,2e3)}async _pollLogFile(t){let e=0,i=async()=>{try{let a=await fetch(`${t}?t=${Date.now()}`,{credentials:"include"});if(!a.ok)return;let r=(await a.text()).split(`
3297
+ `);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(`
3298
+ `),e=new Blob([t],{type:"text/plain"}),i=URL.createObjectURL(e),a=document.createElement("a");a.href=i,a.download=`loki-logs-${new Date().toISOString().split("T")[0]}.txt`,a.click(),URL.revokeObjectURL(i)}_setFilter(t){this._filter=t.toLowerCase(),this._renderLogs()}_setLevelFilter(t){this._levelFilter=t,this._renderLogs()}_getFilteredLogs(){return this._logs.filter(t=>!(this._levelFilter!=="all"&&t.level!==this._levelFilter||this._filter&&!t.message.toLowerCase().includes(this._filter)))}_renderLogs(){let t=this.shadowRoot.getElementById("log-output");if(!t)return;let e=this._getFilteredLogs();if(e.length===0){t.innerHTML='<div class="log-empty">No log output yet. Terminal will update when Loki Mode is running.</div>';return}t.innerHTML=e.map(i=>{let a=Ot[i.level]||Ot.info;return`
3287
3299
  <div class="log-line">
3288
- <span class="timestamp">${this._escapeHtml(a.timestamp)}</span>
3289
- <span class="level" style="color: ${i.color}">[${this._escapeHtml(i.label)}]</span>
3290
- <span class="message">${this._escapeHtml(a.message)}</span>
3300
+ <span class="timestamp">${this._escapeHtml(i.timestamp)}</span>
3301
+ <span class="level" style="color: ${a.color}">[${this._escapeHtml(a.label)}]</span>
3302
+ <span class="message">${this._escapeHtml(i.message)}</span>
3291
3303
  </div>
3292
3304
  `}).join(""),this._autoScroll&&this._scrollToBottom()}_escapeHtml(t){let e=document.createElement("div");return e.textContent=t,e.innerHTML}render(){let t=`
3293
3305
  <style>
@@ -3482,7 +3494,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
3482
3494
  ${this._logs.length} lines (${this._getFilteredLogs().length} shown)
3483
3495
  </div>
3484
3496
  </div>
3485
- `,this._attachEventListeners(),this._renderLogs()}_attachEventListeners(){let t=this.shadowRoot.getElementById("filter-input"),e=this.shadowRoot.getElementById("level-select"),a=this.shadowRoot.getElementById("auto-scroll-btn"),i=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))),a&&a.addEventListener("click",()=>this._toggleAutoScroll()),i&&i.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",G);var ce=[{id:"summary",label:"Summary",icon:"M4 6h16M4 12h16M4 18h16"},{id:"search",label:"Search",icon:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"},{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"}],K=class extends h{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._stats=null,this._episodes=[],this._patterns=[],this._skills=[],this._tokenEconomics=null,this._selectedItem=null,this._lastFocusedElement=null,this._searchQuery="",this._searchCollection="all",this._searchResults=[],this._searchLoading=!1,this._searchError=null}connectedCallback(){super.connectedCallback(),this._activeTab=this.getAttribute("tab")||"summary",this._setupApi(),this._loadData()}attributeChangedCallback(t,e,a){if(e!==a)switch(t){case"api-url":this._api&&(this._api.baseUrl=a,this._loadData());break;case"theme":this._applyTheme();break;case"tab":this._setTab(a);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,e,a]=await Promise.allSettled([this._api.getMemorySummary(),this._api.getTokenEconomics(),this._api.getMemoryStats()]);this._summary=t.status==="fulfilled"?t.value:null,this._tokenEconomics=e.status==="fulfilled"?e.value:null,this._stats=a.status==="fulfilled"?a.value: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:
3497
+ `,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",G);var pe=[{id:"summary",label:"Summary",icon:"M4 6h16M4 12h16M4 18h16"},{id:"search",label:"Search",icon:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"},{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"}],K=class extends h{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._stats=null,this._episodes=[],this._patterns=[],this._skills=[],this._tokenEconomics=null,this._selectedItem=null,this._lastFocusedElement=null,this._searchQuery="",this._searchCollection="all",this._searchResults=[],this._searchLoading=!1,this._searchError=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{let[t,e,i]=await Promise.allSettled([this._api.getMemorySummary(),this._api.getTokenEconomics(),this._api.getMemoryStats()]);this._summary=t.status==="fulfilled"?t.value:null,this._tokenEconomics=e.status==="fulfilled"?e.value:null,this._stats=i.status==="fulfilled"?i.value: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:
3486
3498
  - Patterns created: ${t.patternsCreated}
3487
3499
  - Patterns merged: ${t.patternsMerged}
3488
3500
  - Episodes processed: ${t.episodesProcessed}`),this._loadData()}catch(t){alert("Consolidation failed: "+t.message)}}async _executeSearch(){let t=this._searchQuery.trim();if(t){this._searchLoading=!0,this._searchError=null,this.render();try{let e=await this._api.searchMemory(t,this._searchCollection,20);this._searchResults=e.results||[]}catch(e){this._searchError=e.message||"Search failed",this._searchResults=[]}this._searchLoading=!1,this.render(),requestAnimationFrame(()=>{let e=this.shadowRoot.getElementById("memory-search-input");e&&e.focus()})}}_renderSearch(){let t=["all","episodes","patterns","skills"];return`
@@ -3524,7 +3536,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
3524
3536
  `:!this._searchLoading&&this._searchQuery?'<div class="empty-state">No results found</div>':""}
3525
3537
  ${this._searchQuery?"":'<div class="empty-state">Enter a query to search across all memory layers using full-text search</div>'}
3526
3538
  </div>
3527
- `}_renderSummary(){if(!this._summary)return'<div class="empty-state">No memory data available</div>';let{episodic:t,semantic:e,procedural:a,tokenEconomics:i}=this._summary;return`
3539
+ `}_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`
3528
3540
  <div class="summary-grid">
3529
3541
  <div class="summary-card">
3530
3542
  <div class="summary-card-header">
@@ -3557,13 +3569,13 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
3557
3569
  <div class="summary-card">
3558
3570
  <div class="summary-card-header">
3559
3571
  <span class="summary-card-title">Procedural Memory</span>
3560
- <span class="summary-card-count">${a?.skills||0}</span>
3572
+ <span class="summary-card-count">${i?.skills||0}</span>
3561
3573
  </div>
3562
3574
  <div class="summary-card-detail">
3563
3575
  Learned skills and procedures
3564
3576
  </div>
3565
3577
  <div class="memory-bar">
3566
- <div class="memory-bar-fill procedural" style="width: ${Math.min((a?.skills||0)/100*100,100)}%"></div>
3578
+ <div class="memory-bar-fill procedural" style="width: ${Math.min((i?.skills||0)/100*100,100)}%"></div>
3567
3579
  </div>
3568
3580
  </div>
3569
3581
 
@@ -4343,8 +4355,8 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
4343
4355
  font-size: 12px;
4344
4356
  }
4345
4357
  </style>
4346
- `,e;if(this._loading)e='<div class="loading">Loading memory data...</div>';else if(this._error)e=`<div class="error-state">Error: ${this._escapeHtml(this._error)}</div>`;else{let a;switch(this._activeTab){case"summary":a=this._renderSummary();break;case"search":a=this._renderSearch();break;case"episodes":a=this._renderEpisodes();break;case"patterns":a=this._renderPatterns();break;case"skills":a=this._renderSkills();break;default:a=this._renderSummary()}e=`
4347
- <div class="content-main">${a}</div>
4358
+ `,e;if(this._loading)e='<div class="loading">Loading memory data...</div>';else if(this._error)e=`<div class="error-state">Error: ${this._escapeHtml(this._error)}</div>`;else{let i;switch(this._activeTab){case"summary":i=this._renderSummary();break;case"search":i=this._renderSearch();break;case"episodes":i=this._renderEpisodes();break;case"patterns":i=this._renderPatterns();break;case"skills":i=this._renderSkills();break;default:i=this._renderSummary()}e=`
4359
+ <div class="content-main">${i}</div>
4348
4360
  ${this._renderDetail()}
4349
4361
  `}this.shadowRoot.innerHTML=`
4350
4362
  ${t}
@@ -4353,16 +4365,16 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
4353
4365
  <span class="browser-title">Memory System</span>
4354
4366
  </div>
4355
4367
  <div class="tabs" role="tablist" aria-label="Memory browser sections">
4356
- ${ce.map((a,i)=>`
4357
- <button class="tab ${this._activeTab===a.id?"active":""}"
4358
- data-tab="${a.id}"
4368
+ ${pe.map((i,a)=>`
4369
+ <button class="tab ${this._activeTab===i.id?"active":""}"
4370
+ data-tab="${i.id}"
4359
4371
  role="tab"
4360
- id="tab-${a.id}"
4361
- aria-selected="${this._activeTab===a.id}"
4362
- aria-controls="tabpanel-${a.id}"
4363
- tabindex="${this._activeTab===a.id?"0":"-1"}">
4364
- <svg viewBox="0 0 24 24" aria-hidden="true"><path d="${a.icon}"/></svg>
4365
- ${a.label}
4372
+ id="tab-${i.id}"
4373
+ aria-selected="${this._activeTab===i.id}"
4374
+ aria-controls="tabpanel-${i.id}"
4375
+ tabindex="${this._activeTab===i.id?"0":"-1"}">
4376
+ <svg viewBox="0 0 24 24" aria-hidden="true"><path d="${i.icon}"/></svg>
4377
+ ${i.label}
4366
4378
  </button>
4367
4379
  `).join("")}
4368
4380
  </div>
@@ -4370,12 +4382,12 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
4370
4382
  ${e}
4371
4383
  </div>
4372
4384
  </div>
4373
- `,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.querySelectorAll(".tab");t.forEach((n,l)=>{n.addEventListener("click",()=>this._setTab(n.dataset.tab)),n.addEventListener("keydown",c=>{if(c.key==="ArrowRight"||c.key==="ArrowLeft"){c.preventDefault();let p=Array.from(t),u=c.key==="ArrowRight"?(l+1)%p.length:(l-1+p.length)%p.length;p[u].focus(),this._setTab(p[u].dataset.tab)}})}),this.shadowRoot.querySelectorAll(".item-card").forEach(n=>{n.addEventListener("click",()=>this._handleItemClick(n)),n.addEventListener("keydown",l=>{l.key==="Enter"||l.key===" "?(l.preventDefault(),this._handleItemClick(n)):(l.key==="ArrowDown"||l.key==="ArrowUp")&&(l.preventDefault(),this._navigateItemCards(n,l.key==="ArrowDown"?"next":"prev"))})});let e=this.shadowRoot.getElementById("close-detail");e&&e.addEventListener("click",()=>this._closeDetail());let a=this.shadowRoot.getElementById("consolidate-btn");a&&a.addEventListener("click",()=>this._triggerConsolidation());let i=this.shadowRoot.getElementById("refresh-btn");i&&i.addEventListener("click",()=>this._loadData());let s=this.shadowRoot.getElementById("memory-search-input"),r=this.shadowRoot.getElementById("search-btn"),o=this.shadowRoot.getElementById("memory-search-collection");s&&(s.addEventListener("keydown",n=>{n.key==="Enter"&&(n.preventDefault(),this._searchQuery=s.value,this._executeSearch())}),s.addEventListener("input",n=>{this._searchQuery=n.target.value})),r&&r.addEventListener("click",()=>{let n=this.shadowRoot.getElementById("memory-search-input");n&&(this._searchQuery=n.value),this._executeSearch()}),o&&o.addEventListener("change",n=>{this._searchCollection=n.target.value})}_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 a=Array.from(this.shadowRoot.querySelectorAll(".item-card")),i=a.indexOf(t);if(i===-1)return;let s=e==="next"?i+1:i-1;s>=0&&s<a.length&&a[s].focus()}};customElements.get("loki-memory-browser")||customElements.define("loki-memory-browser",K);var pe=[{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}],ue=[{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"}],he=[{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"}],V=class extends h{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,a){if(e!==a)switch(t){case"api-url":this._api&&(this._api.baseUrl=a,this._loadData());break;case"theme":this._applyTheme();break;case"time-range":this._timeRange=a,this._loadData();break;case"signal-type":this._signalType=a,this._loadData();break;case"source":this._source=a,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,a,i]=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=a,this._signals=i||[]}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`
4385
+ `,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.querySelectorAll(".tab");t.forEach((n,l)=>{n.addEventListener("click",()=>this._setTab(n.dataset.tab)),n.addEventListener("keydown",c=>{if(c.key==="ArrowRight"||c.key==="ArrowLeft"){c.preventDefault();let p=Array.from(t),u=c.key==="ArrowRight"?(l+1)%p.length:(l-1+p.length)%p.length;p[u].focus(),this._setTab(p[u].dataset.tab)}})}),this.shadowRoot.querySelectorAll(".item-card").forEach(n=>{n.addEventListener("click",()=>this._handleItemClick(n)),n.addEventListener("keydown",l=>{l.key==="Enter"||l.key===" "?(l.preventDefault(),this._handleItemClick(n)):(l.key==="ArrowDown"||l.key==="ArrowUp")&&(l.preventDefault(),this._navigateItemCards(n,l.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());let s=this.shadowRoot.getElementById("memory-search-input"),r=this.shadowRoot.getElementById("search-btn"),o=this.shadowRoot.getElementById("memory-search-collection");s&&(s.addEventListener("keydown",n=>{n.key==="Enter"&&(n.preventDefault(),this._searchQuery=s.value,this._executeSearch())}),s.addEventListener("input",n=>{this._searchQuery=n.target.value})),r&&r.addEventListener("click",()=>{let n=this.shadowRoot.getElementById("memory-search-input");n&&(this._searchQuery=n.value),this._executeSearch()}),o&&o.addEventListener("change",n=>{this._searchCollection=n.target.value})}_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",K);var he=[{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}],ue=[{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"}],ge=[{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"}],V=class extends h{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`
4374
4386
  <div class="filters">
4375
4387
  <div class="filter-group">
4376
4388
  <label>Time Range</label>
4377
4389
  <select id="time-range-select" class="filter-select">
4378
- ${pe.map(t=>`
4390
+ ${he.map(t=>`
4379
4391
  <option value="${t.id}" ${this._timeRange===t.id?"selected":""}>${t.label}</option>
4380
4392
  `).join("")}
4381
4393
  </select>
@@ -4391,7 +4403,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
4391
4403
  <div class="filter-group">
4392
4404
  <label>Source</label>
4393
4405
  <select id="source-select" class="filter-select">
4394
- ${he.map(t=>`
4406
+ ${ge.map(t=>`
4395
4407
  <option value="${t.id}" ${this._source===t.id?"selected":""}>${t.label}</option>
4396
4408
  `).join("")}
4397
4409
  </select>
@@ -4404,7 +4416,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
4404
4416
  Refresh
4405
4417
  </button>
4406
4418
  </div>
4407
- `}_renderSummaryCards(){if(!this._metrics)return'<div class="empty-state">No metrics available</div>';let{totalSignals:t,signalsByType:e,signalsBySource:a,aggregation:i}=this._metrics;return`
4419
+ `}_renderSummaryCards(){if(!this._metrics)return'<div class="empty-state">No metrics available</div>';let{totalSignals:t,signalsByType:e,signalsBySource:i,aggregation:a}=this._metrics;return`
4408
4420
  <div class="summary-cards">
4409
4421
  <div class="summary-card">
4410
4422
  <div class="summary-card-header">
@@ -4425,11 +4437,11 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
4425
4437
  <div class="summary-card">
4426
4438
  <div class="summary-card-header">
4427
4439
  <span class="summary-card-title">Sources</span>
4428
- <span class="summary-card-count">${Object.keys(a||{}).length}</span>
4440
+ <span class="summary-card-count">${Object.keys(i||{}).length}</span>
4429
4441
  </div>
4430
4442
  <div class="summary-card-detail">Signal sources active</div>
4431
4443
  <div class="signal-breakdown">
4432
- ${Object.entries(a||{}).map(([s,r])=>`
4444
+ ${Object.entries(i||{}).map(([s,r])=>`
4433
4445
  <div class="breakdown-item">
4434
4446
  <span class="breakdown-label source-badge ${s}">${s}</span>
4435
4447
  <span class="breakdown-value">${this._formatNumber(r)}</span>
@@ -4441,21 +4453,21 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
4441
4453
  <div class="summary-card">
4442
4454
  <div class="summary-card-header">
4443
4455
  <span class="summary-card-title">Patterns Found</span>
4444
- <span class="summary-card-count">${this._formatNumber((i?.preferences?.length||0)+(i?.error_patterns?.length||0)+(i?.success_patterns?.length||0))}</span>
4456
+ <span class="summary-card-count">${this._formatNumber((a?.preferences?.length||0)+(a?.error_patterns?.length||0)+(a?.success_patterns?.length||0))}</span>
4445
4457
  </div>
4446
4458
  <div class="summary-card-detail">Aggregated learnings</div>
4447
4459
  <div class="pattern-counts">
4448
4460
  <div class="pattern-count">
4449
4461
  <span class="pattern-icon preferences">P</span>
4450
- <span>${i?.preferences?.length||0} Preferences</span>
4462
+ <span>${a?.preferences?.length||0} Preferences</span>
4451
4463
  </div>
4452
4464
  <div class="pattern-count">
4453
4465
  <span class="pattern-icon errors">E</span>
4454
- <span>${i?.error_patterns?.length||0} Errors</span>
4466
+ <span>${a?.error_patterns?.length||0} Errors</span>
4455
4467
  </div>
4456
4468
  <div class="pattern-count">
4457
4469
  <span class="pattern-icon success">S</span>
4458
- <span>${i?.success_patterns?.length||0} Success</span>
4470
+ <span>${a?.success_patterns?.length||0} Success</span>
4459
4471
  </div>
4460
4472
  </div>
4461
4473
  </div>
@@ -4473,16 +4485,16 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
4473
4485
  </div>
4474
4486
  </div>
4475
4487
  </div>
4476
- `}_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,a=120,i=400,s=20,r=t.map((n,l)=>{let c=s+l/(t.length-1||1)*(i-s*2),p=a-s-n.count/(e||1)*(a-s*2);return`${c},${p}`}).join(" "),o=`${s},${a-s} ${r} ${i-s},${a-s}`;return`
4488
+ `}_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 c=s+l/(t.length-1||1)*(a-s*2),p=i-s-n.count/(e||1)*(i-s*2);return`${c},${p}`}).join(" "),o=`${s},${i-s} ${r} ${a-s},${i-s}`;return`
4477
4489
  <div class="trend-chart">
4478
4490
  <div class="chart-header">
4479
4491
  <span class="chart-title">Signal Volume Over Time</span>
4480
4492
  <span class="chart-subtitle">${this._trends.period}</span>
4481
4493
  </div>
4482
- <svg class="chart-svg" viewBox="0 0 ${i} ${a}">
4494
+ <svg class="chart-svg" viewBox="0 0 ${a} ${i}">
4483
4495
  <!-- Grid lines -->
4484
- <line x1="${s}" y1="${s}" x2="${s}" y2="${a-s}" stroke="var(--loki-border)" stroke-width="1"/>
4485
- <line x1="${s}" y1="${a-s}" x2="${i-s}" y2="${a-s}" stroke="var(--loki-border)" stroke-width="1"/>
4496
+ <line x1="${s}" y1="${s}" x2="${s}" y2="${i-s}" stroke="var(--loki-border)" stroke-width="1"/>
4497
+ <line x1="${s}" y1="${i-s}" x2="${a-s}" y2="${i-s}" stroke="var(--loki-border)" stroke-width="1"/>
4486
4498
 
4487
4499
  <!-- Area fill -->
4488
4500
  <polygon points="${o}" fill="var(--loki-accent-muted)" />
@@ -4491,7 +4503,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
4491
4503
  <polyline points="${r}" fill="none" stroke="var(--loki-accent)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
4492
4504
 
4493
4505
  <!-- Data points -->
4494
- ${t.map((n,l)=>{let c=s+l/(t.length-1||1)*(i-s*2),p=a-s-n.count/(e||1)*(a-s*2);return`<circle cx="${c}" cy="${p}" r="3" fill="var(--loki-accent)" />`}).join("")}
4506
+ ${t.map((n,l)=>{let c=s+l/(t.length-1||1)*(a-s*2),p=i-s-n.count/(e||1)*(i-s*2);return`<circle cx="${c}" cy="${p}" r="3" fill="var(--loki-accent)" />`}).join("")}
4495
4507
  </svg>
4496
4508
  <div class="chart-labels">
4497
4509
  ${t.length>0?`
@@ -4500,7 +4512,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
4500
4512
  `:""}
4501
4513
  </div>
4502
4514
  </div>
4503
- `}_renderTopLists(){if(!this._metrics?.aggregation)return"";let{preferences:t,error_patterns:e,success_patterns:a,tool_efficiencies:i}=this._metrics.aggregation;return`
4515
+ `}_renderTopLists(){if(!this._metrics?.aggregation)return"";let{preferences:t,error_patterns:e,success_patterns:i,tool_efficiencies:a}=this._metrics.aggregation;return`
4504
4516
  <div class="top-lists">
4505
4517
  <!-- User Preferences -->
4506
4518
  <div class="top-list">
@@ -4550,10 +4562,10 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
4550
4562
  <div class="top-list">
4551
4563
  <div class="list-header">
4552
4564
  <span class="list-title">Success Patterns</span>
4553
- <span class="list-count">${a?.length||0}</span>
4565
+ <span class="list-count">${i?.length||0}</span>
4554
4566
  </div>
4555
4567
  <div class="list-items" role="list">
4556
- ${(a||[]).slice(0,5).map(s=>`
4568
+ ${(i||[]).slice(0,5).map(s=>`
4557
4569
  <div class="list-item success-item" data-type="success_pattern" data-id="${s.pattern_name}" tabindex="0" role="listitem">
4558
4570
  <div class="item-main">
4559
4571
  <span class="item-key">${this._escapeHtml(s.pattern_name)}</span>
@@ -4572,10 +4584,10 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
4572
4584
  <div class="top-list">
4573
4585
  <div class="list-header">
4574
4586
  <span class="list-title">Tool Efficiency Rankings</span>
4575
- <span class="list-count">${i?.length||0}</span>
4587
+ <span class="list-count">${a?.length||0}</span>
4576
4588
  </div>
4577
4589
  <div class="list-items" role="list">
4578
- ${(i||[]).slice(0,5).map((s,r)=>`
4590
+ ${(a||[]).slice(0,5).map((s,r)=>`
4579
4591
  <div class="list-item tool-item" data-type="tool_efficiency" data-id="${s.tool_name}" tabindex="0" role="listitem">
4580
4592
  <div class="item-rank">#${r+1}</div>
4581
4593
  <div class="item-main">
@@ -4598,11 +4610,11 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
4598
4610
  <span class="signals-count">${this._signals.length}</span>
4599
4611
  </div>
4600
4612
  <div class="signals-list">
4601
- ${this._signals.slice(0,10).map(t=>{let e=t.data||{},a=t.type||"unknown",i=e.action||t.action||a,s=e.source||t.source||"-",r=e.outcome||t.outcome||"-",o=t.timestamp?new Date(t.timestamp).toLocaleTimeString():"-";return`
4613
+ ${this._signals.slice(0,10).map(t=>{let e=t.data||{},i=t.type||"unknown",a=e.action||t.action||i,s=e.source||t.source||"-",r=e.outcome||t.outcome||"-",o=t.timestamp?new Date(t.timestamp).toLocaleTimeString():"-";return`
4602
4614
  <div class="signal-item">
4603
- <div class="signal-type ${a}">${a.replace("_"," ")}</div>
4615
+ <div class="signal-type ${i}">${i.replace("_"," ")}</div>
4604
4616
  <div class="signal-content">
4605
- <span class="signal-action">${this._escapeHtml(i)}</span>
4617
+ <span class="signal-action">${this._escapeHtml(a)}</span>
4606
4618
  <span class="signal-source">${s}</span>
4607
4619
  </div>
4608
4620
  <div class="signal-meta">
@@ -4612,7 +4624,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
4612
4624
  </div>`}).join("")}
4613
4625
  </div>
4614
4626
  </div>
4615
- `}_renderDetailPanel(){if(!this._selectedMetric)return"";let{type:t,item:e}=this._selectedMetric,a="";switch(t){case"preference":a=`
4627
+ `}_renderDetailPanel(){if(!this._selectedMetric)return"";let{type:t,item:e}=this._selectedMetric,i="";switch(t){case"preference":i=`
4616
4628
  <div class="detail-row">
4617
4629
  <span class="detail-label">Preference Key</span>
4618
4630
  <span class="detail-value">${this._escapeHtml(e.preference_key)}</span>
@@ -4633,11 +4645,11 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
4633
4645
  <div class="detail-section">
4634
4646
  <div class="detail-label">Alternatives Rejected</div>
4635
4647
  <ul class="detail-list">
4636
- ${e.alternatives_rejected.map(i=>`<li>${this._escapeHtml(i)}</li>`).join("")}
4648
+ ${e.alternatives_rejected.map(a=>`<li>${this._escapeHtml(a)}</li>`).join("")}
4637
4649
  </ul>
4638
4650
  </div>
4639
4651
  `:""}
4640
- `;break;case"error_pattern":a=`
4652
+ `;break;case"error_pattern":i=`
4641
4653
  <div class="detail-row">
4642
4654
  <span class="detail-label">Error Type</span>
4643
4655
  <span class="detail-value">${this._escapeHtml(e.error_type)}</span>
@@ -4650,7 +4662,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
4650
4662
  <div class="detail-section">
4651
4663
  <div class="detail-label">Common Messages</div>
4652
4664
  <ul class="detail-list">
4653
- ${e.common_messages.map(i=>`<li>${this._escapeHtml(i)}</li>`).join("")}
4665
+ ${e.common_messages.map(a=>`<li>${this._escapeHtml(a)}</li>`).join("")}
4654
4666
  </ul>
4655
4667
  </div>
4656
4668
  `:""}
@@ -4658,11 +4670,11 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
4658
4670
  <div class="detail-section">
4659
4671
  <div class="detail-label">Known Resolutions</div>
4660
4672
  <ul class="detail-list success">
4661
- ${e.resolutions.map(i=>`<li>${this._escapeHtml(i)}</li>`).join("")}
4673
+ ${e.resolutions.map(a=>`<li>${this._escapeHtml(a)}</li>`).join("")}
4662
4674
  </ul>
4663
4675
  </div>
4664
4676
  `:""}
4665
- `;break;case"success_pattern":a=`
4677
+ `;break;case"success_pattern":i=`
4666
4678
  <div class="detail-row">
4667
4679
  <span class="detail-label">Pattern Name</span>
4668
4680
  <span class="detail-value">${this._escapeHtml(e.pattern_name)}</span>
@@ -4675,11 +4687,11 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
4675
4687
  <div class="detail-section">
4676
4688
  <div class="detail-label">Common Actions</div>
4677
4689
  <ol class="detail-list numbered">
4678
- ${e.common_actions.map(i=>`<li>${this._escapeHtml(i)}</li>`).join("")}
4690
+ ${e.common_actions.map(a=>`<li>${this._escapeHtml(a)}</li>`).join("")}
4679
4691
  </ol>
4680
4692
  </div>
4681
4693
  `:""}
4682
- `;break;case"tool_efficiency":a=`
4694
+ `;break;case"tool_efficiency":i=`
4683
4695
  <div class="detail-row">
4684
4696
  <span class="detail-label">Tool Name</span>
4685
4697
  <span class="detail-value">${this._escapeHtml(e.tool_name)}</span>
@@ -4704,22 +4716,22 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
4704
4716
  <div class="detail-section">
4705
4717
  <div class="detail-label">Alternative Tools</div>
4706
4718
  <div class="tag-list">
4707
- ${e.alternative_tools.map(i=>`<span class="tag">${this._escapeHtml(i)}</span>`).join("")}
4719
+ ${e.alternative_tools.map(a=>`<span class="tag">${this._escapeHtml(a)}</span>`).join("")}
4708
4720
  </div>
4709
4721
  </div>
4710
4722
  `:""}
4711
4723
  `;break}return`
4712
4724
  <div class="detail-panel">
4713
4725
  <div class="detail-header">
4714
- <h3>${t.replace("_"," ").replace(/\b\w/g,i=>i.toUpperCase())}</h3>
4726
+ <h3>${t.replace("_"," ").replace(/\b\w/g,a=>a.toUpperCase())}</h3>
4715
4727
  <button class="close-btn" id="close-detail">&times;</button>
4716
4728
  </div>
4717
4729
  <div class="detail-body">
4718
- ${a}
4730
+ ${i}
4719
4731
  <div class="detail-row">
4720
4732
  <span class="detail-label">Sources</span>
4721
4733
  <div class="source-tags">
4722
- ${(e.sources||[]).map(i=>`<span class="source-badge ${i}">${i}</span>`).join("")}
4734
+ ${(e.sources||[]).map(a=>`<span class="source-badge ${a}">${a}</span>`).join("")}
4723
4735
  </div>
4724
4736
  </div>
4725
4737
  <div class="detail-row">
@@ -5382,7 +5394,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
5382
5394
  ${e}
5383
5395
  </div>
5384
5396
  </div>
5385
- `,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 a=this.shadowRoot.getElementById("source-select");a&&a.addEventListener("change",r=>this._setFilter("source",r.target.value));let i=this.shadowRoot.getElementById("refresh-btn");i&&i.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(a=>a.preference_key===e);case"error_pattern":return this._metrics.aggregation.error_patterns?.find(a=>a.error_type===e);case"success_pattern":return this._metrics.aggregation.success_patterns?.find(a=>a.pattern_name===e);case"tool_efficiency":return this._metrics.aggregation.tool_efficiencies?.find(a=>a.tool_name===e);default:return null}}};customElements.get("loki-learning-dashboard")||customElements.define("loki-learning-dashboard",V);var ge=[{id:"overview",label:"Overview"},{id:"decisions",label:"Decision Log"},{id:"convergence",label:"Convergence"},{id:"agents",label:"Agents"}],Y=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._activeTab="overview",this._pollInterval=null,this._councilState=null,this._verdicts=[],this._convergence=[],this._agents=[],this._selectedAgent=null,this._lastDataHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,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,a,i,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),a.status==="fulfilled"&&(this._verdicts=a.value.verdicts||[]),i.status==="fulfilled"&&(this._convergence=i.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=`
5397
+ `,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("time-range-select");t&&t.addEventListener("change",r=>this._setFilter("timeRange",r.target.value));let e=this.shadowRoot.getElementById("signal-type-select");e&&e.addEventListener("change",r=>this._setFilter("signalType",r.target.value));let i=this.shadowRoot.getElementById("source-select");i&&i.addEventListener("change",r=>this._setFilter("source",r.target.value));let a=this.shadowRoot.getElementById("refresh-btn");a&&a.addEventListener("click",()=>this._loadData());let s=this.shadowRoot.getElementById("close-detail");s&&s.addEventListener("click",()=>this._closeDetail()),this.shadowRoot.querySelectorAll(".list-item").forEach(r=>{r.addEventListener("click",()=>{let o=r.dataset.type,n=r.dataset.id,l=this._findItemData(o,n);l&&this._selectMetric(o,l)}),r.addEventListener("keydown",o=>{(o.key==="Enter"||o.key===" ")&&(o.preventDefault(),r.click())})})}_findItemData(t,e){if(!this._metrics?.aggregation)return null;switch(t){case"preference":return this._metrics.aggregation.preferences?.find(i=>i.preference_key===e);case"error_pattern":return this._metrics.aggregation.error_patterns?.find(i=>i.error_type===e);case"success_pattern":return this._metrics.aggregation.success_patterns?.find(i=>i.pattern_name===e);case"tool_efficiency":return this._metrics.aggregation.tool_efficiencies?.find(i=>i.tool_name===e);default:return null}}};customElements.get("loki-learning-dashboard")||customElements.define("loki-learning-dashboard",V);var ve=[{id:"overview",label:"Overview"},{id:"decisions",label:"Decision Log"},{id:"convergence",label:"Convergence"},{id:"agents",label:"Agents"}],Y=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._activeTab="overview",this._pollInterval=null,this._councilState=null,this._verdicts=[],this._convergence=[],this._agents=[],this._selectedAgent=null,this._lastDataHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),3e3),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadData(),this._pollInterval=setInterval(()=>this._loadData(),3e3))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null),this._pendingRaf&&(cancelAnimationFrame(this._pendingRaf),this._pendingRaf=null)}async _loadData(){try{let[e,i,a,s]=await Promise.allSettled([this._api._get("/api/council/state"),this._api._get("/api/council/verdicts"),this._api._get("/api/council/convergence"),this._api._get("/api/agents")]);e.status==="fulfilled"&&(this._councilState=e.value),i.status==="fulfilled"&&(this._verdicts=i.value.verdicts||[]),a.status==="fulfilled"&&(this._convergence=a.value.dataPoints||[]),s.status==="fulfilled"&&(this._agents=Array.isArray(s.value)?s.value:[]),this._error=null}catch(e){this._error=e.message}let t=JSON.stringify({s:this._councilState,v:this._verdicts,c:this._convergence,a:this._agents,e:this._error});t!==this._lastDataHash&&(this._lastDataHash=t,this.render())}async _forceReview(){try{await this._api._post("/api/council/force-review"),this.dispatchEvent(new CustomEvent("council-action",{detail:{action:"force-review"},bubbles:!0}))}catch(t){this._error=`Failed to force review: ${t.message}`,this.render()}}async _killAgent(t){if(confirm(`Kill agent ${t}?`))try{await this._api._post(`/api/agents/${t}/kill`),this.dispatchEvent(new CustomEvent("council-action",{detail:{action:"kill-agent",agentId:t},bubbles:!0})),await this._loadData()}catch(e){this._error=`Failed to kill agent: ${e.message}`,this.render()}}async _pauseAgent(t){try{await this._api._post(`/api/agents/${t}/pause`),await this._loadData()}catch(e){this._error=`Failed to pause agent: ${e.message}`,this.render()}}async _resumeAgent(t){try{await this._api._post(`/api/agents/${t}/resume`),await this._loadData()}catch(e){this._error=`Failed to resume agent: ${e.message}`,this.render()}}_setTab(t){this._activeTab=t,this.render()}_selectAgent(t){this._selectedAgent=this._selectedAgent?.id===t.id?null:t,this.render()}render(){let t=this.shadowRoot;t&&(this._pendingRaf&&(cancelAnimationFrame(this._pendingRaf),this._pendingRaf=null),t.innerHTML=`
5386
5398
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
5387
5399
  <div class="council-dashboard">
5388
5400
  <div class="council-header">
@@ -5396,7 +5408,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
5396
5408
  </div>
5397
5409
 
5398
5410
  <div class="tabs">
5399
- ${ge.map(e=>`
5411
+ ${ve.map(e=>`
5400
5412
  <button
5401
5413
  class="tab ${this._activeTab===e.id?"active":""}"
5402
5414
  data-tab="${e.id}"
@@ -5410,7 +5422,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
5410
5422
 
5411
5423
  ${this._error?`<div class="error-banner">${this._error}</div>`:""}
5412
5424
  </div>
5413
- `,this._attachEventListeners())}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.getElementById("force-review-btn");e&&e.addEventListener("click",()=>this._forceReview()),t.querySelectorAll(".tab[data-tab]").forEach(a=>{a.addEventListener("click",()=>this._setTab(a.dataset.tab))})}_renderTabContent(){switch(this._activeTab){case"overview":return this._renderOverview();case"decisions":return this._renderDecisions();case"convergence":return this._renderConvergence();case"agents":return this._renderAgents();default:return""}}_renderOverview(){let t=this._councilState||{},e=t.consecutive_no_change||0,a=t.done_signals||0,i=t.total_votes||0,s=t.approve_votes||0,r=this._verdicts.length>0?this._verdicts[this._verdicts.length-1]:null,o=this._agents.filter(n=>n.alive).length;return`
5425
+ `,this._attachEventListeners())}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.getElementById("force-review-btn");e&&e.addEventListener("click",()=>this._forceReview()),t.querySelectorAll(".tab[data-tab]").forEach(i=>{i.addEventListener("click",()=>this._setTab(i.dataset.tab))})}_renderTabContent(){switch(this._activeTab){case"overview":return this._renderOverview();case"decisions":return this._renderDecisions();case"convergence":return this._renderConvergence();case"agents":return this._renderAgents();default:return""}}_renderOverview(){let t=this._councilState||{},e=t.consecutive_no_change||0,i=t.done_signals||0,a=t.total_votes||0,s=t.approve_votes||0,r=this._verdicts.length>0?this._verdicts[this._verdicts.length-1]:null,o=this._agents.filter(n=>n.alive).length;return`
5414
5426
  <div class="overview-grid">
5415
5427
  <div class="stat-card">
5416
5428
  <div class="stat-label">Council Status</div>
@@ -5420,7 +5432,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
5420
5432
  </div>
5421
5433
  <div class="stat-card">
5422
5434
  <div class="stat-label">Total Votes Cast</div>
5423
- <div class="stat-value">${i}</div>
5435
+ <div class="stat-value">${a}</div>
5424
5436
  <div class="stat-sub">${s} approved</div>
5425
5437
  </div>
5426
5438
  <div class="stat-card">
@@ -5430,7 +5442,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
5430
5442
  </div>
5431
5443
  <div class="stat-card">
5432
5444
  <div class="stat-label">Done Signals</div>
5433
- <div class="stat-value ${a>=2?"text-green":""}">${a}</div>
5445
+ <div class="stat-value ${i>=2?"text-green":""}">${i}</div>
5434
5446
  <div class="stat-sub">from agent output</div>
5435
5447
  </div>
5436
5448
  <div class="stat-card">
@@ -5455,12 +5467,12 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
5455
5467
  </div>
5456
5468
  </div>
5457
5469
  `:""}
5458
- `}_renderConvergenceBar(){let t=this._convergence.slice(-20);if(t.length===0)return'<span class="text-muted">No data</span>';let e=Math.max(...t.map(a=>a.files_changed),1);return`
5470
+ `}_renderConvergenceBar(){let t=this._convergence.slice(-20);if(t.length===0)return'<span class="text-muted">No data</span>';let e=Math.max(...t.map(i=>i.files_changed),1);return`
5459
5471
  <div class="bar-chart">
5460
- ${t.map(a=>{let i=Math.max(4,a.files_changed/e*60),s=a.no_change_streak>0;return`
5461
- <div class="bar-wrapper" title="Iter ${a.iteration}: ${a.files_changed} files changed">
5462
- <div class="bar ${s?"bar-stagnant":"bar-active"}" style="height: ${i}px"></div>
5463
- <div class="bar-label">${a.iteration}</div>
5472
+ ${t.map(i=>{let a=Math.max(4,i.files_changed/e*60),s=i.no_change_streak>0;return`
5473
+ <div class="bar-wrapper" title="Iter ${i.iteration}: ${i.files_changed} files changed">
5474
+ <div class="bar ${s?"bar-stagnant":"bar-active"}" style="height: ${a}px"></div>
5475
+ <div class="bar-label">${i.iteration}</div>
5464
5476
  </div>
5465
5477
  `}).join("")}
5466
5478
  </div>
@@ -5517,9 +5529,9 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
5517
5529
  </div>
5518
5530
  `}_renderAgents(){if(this._agents.length===0)return'<div class="empty-state">No agents registered.</div>';let t=`
5519
5531
  <div class="agents-list">
5520
- ${this._agents.map((e,a)=>`
5532
+ ${this._agents.map((e,i)=>`
5521
5533
  <div class="agent-card ${this._selectedAgent?.id===e.id?"agent-selected":""}"
5522
- data-agent-index="${a}">
5534
+ data-agent-index="${i}">
5523
5535
  <div class="agent-header">
5524
5536
  <span class="agent-name">${e.name||e.id||"Unknown"}</span>
5525
5537
  <span class="agent-status ${e.alive?"status-alive":"status-dead"}">
@@ -5550,7 +5562,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
5550
5562
  </div>
5551
5563
  `).join("")}
5552
5564
  </div>
5553
- `;return this._pendingRaf=requestAnimationFrame(()=>{this._pendingRaf=null;let e=this.shadowRoot;e&&e.querySelectorAll(".agent-card[data-agent-index]").forEach(a=>{let i=parseInt(a.dataset.agentIndex,10),s=this._agents[i];s&&(a.addEventListener("click",()=>this._selectAgent(s)),a.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`
5565
+ `;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`
5554
5566
  :host {
5555
5567
  display: block;
5556
5568
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
@@ -5969,7 +5981,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
5969
5981
  color: var(--loki-error);
5970
5982
  font-size: 12px;
5971
5983
  }
5972
- `}};customElements.get("loki-council-dashboard")||customElements.define("loki-council-dashboard",Y);var Ot={critical:0,major:1,minor:2},me={critical:"var(--loki-status-error, #ef4444)",major:"var(--loki-status-warning, #f59e0b)",minor:"var(--loki-text-muted, #71717a)"},W=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._pollInterval=null,this._checklist=null,this._waivers=[],this._expandedCategories=new Set,this._lastDataHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,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)]),a=JSON.stringify(e),i=JSON.stringify(t)+a;if(i===this._lastDataHash)return;this._lastDataHash=i,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(a){this._error=`Failed to add waiver: ${a.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`
5984
+ `}};customElements.get("loki-council-dashboard")||customElements.define("loki-council-dashboard",Y);var qt={critical:0,major:1,minor:2},me={critical:"var(--loki-status-error, #ef4444)",major:"var(--loki-status-warning, #f59e0b)",minor:"var(--loki-text-muted, #71717a)"},W=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._pollInterval=null,this._checklist=null,this._waivers=[],this._expandedCategories=new Set,this._lastDataHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),5e3),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadData(),this._pollInterval=setInterval(()=>this._loadData(),5e3))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null)}async _loadData(){try{let[t,e]=await Promise.all([this._api.getChecklist(),this._api.getChecklistWaivers().catch(()=>null)]),i=JSON.stringify(e),a=JSON.stringify(t)+i;if(a===this._lastDataHash)return;this._lastDataHash=a,this._checklist=t,this._waivers=e&&e.waivers?e.waivers.filter(s=>s.active):[],this._error=null,this.render()}catch(t){this._error=`Failed to load checklist: ${t.message}`,this.render()}}_isItemWaived(t){return this._waivers.some(e=>e.item_id===t)}_getWaiverForItem(t){return this._waivers.find(e=>e.item_id===t)||null}async _waiveItem(t){let e=window.prompt("Enter reason for waiving this item:");if(e)try{await this._api.addChecklistWaiver(t,e),this._lastDataHash=null,await this._loadData()}catch(i){this._error=`Failed to add waiver: ${i.message}`,this.render()}}async _unwaiveItem(t){try{await this._api.removeChecklistWaiver(t),this._lastDataHash=null,await this._loadData()}catch(e){this._error=`Failed to remove waiver: ${e.message}`,this.render()}}_toggleCategory(t){this._expandedCategories.has(t)?this._expandedCategories.delete(t):this._expandedCategories.add(t),this.render()}_getStyles(){return`
5973
5985
  .checklist-viewer {
5974
5986
  padding: 16px;
5975
5987
  font-family: var(--loki-font-family, system-ui, -apple-system, sans-serif);
@@ -6217,16 +6229,16 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
6217
6229
  border-radius: 4px;
6218
6230
  font-size: 12px;
6219
6231
  }
6220
- `}_getUnwaivedCriticalFailures(){if(!this._checklist?.categories)return[];let t=[];for(let e of this._checklist.categories)for(let a of e.items||[])a.status==="failing"&&a.priority==="critical"&&!this._isItemWaived(a.id)&&t.push(a);return t}_renderGateBanner(){let t=this._getUnwaivedCriticalFailures();return t.length>0?`<div class="gate-banner gate-blocked">COUNCIL GATE: BLOCKED - ${t.length} critical item${t.length!==1?"s":""} must be verified or waived before completion</div>`:'<div class="gate-banner gate-passed">COUNCIL GATE: PASSED - No blocking critical failures</div>'}render(){let t=this.shadowRoot;if(!t)return;let e=this._checklist,a=e&&e.status!=="not_initialized"&&e.categories?.length>0;t.innerHTML=`
6232
+ `}_getUnwaivedCriticalFailures(){if(!this._checklist?.categories)return[];let t=[];for(let e of this._checklist.categories)for(let i of e.items||[])i.status==="failing"&&i.priority==="critical"&&!this._isItemWaived(i.id)&&t.push(i);return t}_renderGateBanner(){let t=this._getUnwaivedCriticalFailures();return t.length>0?`<div class="gate-banner gate-blocked">COUNCIL GATE: BLOCKED - ${t.length} critical item${t.length!==1?"s":""} must be verified or waived before completion</div>`:'<div class="gate-banner gate-passed">COUNCIL GATE: PASSED - No blocking critical failures</div>'}render(){let t=this.shadowRoot;if(!t)return;let e=this._checklist,i=e&&e.status!=="not_initialized"&&e.categories?.length>0;t.innerHTML=`
6221
6233
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
6222
6234
  <div class="checklist-viewer">
6223
6235
  <div class="checklist-header">
6224
6236
  <h2 class="title">Spec Checklist</h2>
6225
- ${a?this._renderBadges(e.summary):""}
6237
+ ${i?this._renderBadges(e.summary):""}
6226
6238
  </div>
6227
- ${a?this._renderGateBanner():""}
6228
- ${a?this._renderProgress(e.summary):""}
6229
- ${a?this._renderCategories(e.categories):this._renderEmpty()}
6239
+ ${i?this._renderGateBanner():""}
6240
+ ${i?this._renderProgress(e.summary):""}
6241
+ ${i?this._renderCategories(e.categories):this._renderEmpty()}
6230
6242
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
6231
6243
  </div>
6232
6244
  `,this._attachEventListeners()}_renderBadges(t){if(!t)return"";let e=this._waivers.length;return`
@@ -6236,32 +6248,32 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
6236
6248
  ${e?`<span class="badge badge-waived">${e} waived</span>`:""}
6237
6249
  ${t.pending?`<span class="badge badge-pending">${t.pending} pending</span>`:""}
6238
6250
  </div>
6239
- `}_renderProgress(t){if(!t||!t.total)return"";let e=t.verified/t.total*100,a=t.failing/t.total*100;return`
6251
+ `}_renderProgress(t){if(!t||!t.total)return"";let e=t.verified/t.total*100,i=t.failing/t.total*100;return`
6240
6252
  <div class="progress-container">
6241
6253
  <div class="progress-bar">
6242
6254
  <div class="progress-verified" style="width: ${e}%"></div>
6243
- <div class="progress-failing" style="width: ${a}%"></div>
6255
+ <div class="progress-failing" style="width: ${i}%"></div>
6244
6256
  </div>
6245
6257
  <div class="progress-label">
6246
6258
  <span>${t.verified}/${t.total} verified | ${t.failing||0} failing | ${this._waivers.length} waived | ${t.pending||0} pending</span>
6247
6259
  <span>${Math.round(e)}%</span>
6248
6260
  </div>
6249
6261
  </div>
6250
- `}_renderCategories(t){return t?.length?t.map(e=>{let a=this._expandedCategories.has(e.name),i=e.items||[],s=i.filter(o=>o.status==="verified").length,r=i.filter(o=>o.status==="failing").length;return`
6262
+ `}_renderCategories(t){return t?.length?t.map(e=>{let i=this._expandedCategories.has(e.name),a=e.items||[],s=a.filter(o=>o.status==="verified").length,r=a.filter(o=>o.status==="failing").length;return`
6251
6263
  <div class="category">
6252
6264
  <div class="category-header" data-category="${this._escapeHtml(e.name)}">
6253
6265
  <div>
6254
6266
  <span class="category-name">${this._escapeHtml(e.name)}</span>
6255
- <span class="category-stats">${s}/${i.length} verified${r?`, ${r} failing`:""}</span>
6267
+ <span class="category-stats">${s}/${a.length} verified${r?`, ${r} failing`:""}</span>
6256
6268
  </div>
6257
- <span class="category-arrow ${a?"expanded":""}">&#9654;</span>
6269
+ <span class="category-arrow ${i?"expanded":""}">&#9654;</span>
6258
6270
  </div>
6259
- ${a?`<div class="category-body">${this._renderItems(i)}</div>`:""}
6271
+ ${i?`<div class="category-body">${this._renderItems(a)}</div>`:""}
6260
6272
  </div>
6261
- `}).join(""):this._renderEmpty()}_renderItems(t){return t?.length?[...t].sort((a,i)=>(Ot[a.priority]??2)-(Ot[i.priority]??2)).map(a=>{let i=a.status==="verified"?"status-verified":a.status==="failing"?"status-failing":"status-pending",s=["critical","major","minor"].includes(a.priority)?a.priority:"minor",r=me[s],o=a.verification||[],n=this._getWaiverForItem(a.id),l=!!n,c=a.status==="failing"&&(s==="critical"||s==="major"),p=l?`<span class="item-waived-badge" title="${this._escapeHtml(n.reason||"No reason provided")}">WAIVED</span>`:"",u="";return c&&(l?u=`<button class="waiver-btn waiver-btn-unwaive" data-unwaive-id="${this._escapeHtml(a.id)}">Unwaive</button>`:u=`<button class="waiver-btn" data-waive-id="${this._escapeHtml(a.id)}">Waive</button>`),`
6273
+ `}).join(""):this._renderEmpty()}_renderItems(t){return t?.length?[...t].sort((i,a)=>(qt[i.priority]??2)-(qt[a.priority]??2)).map(i=>{let a=i.status==="verified"?"status-verified":i.status==="failing"?"status-failing":"status-pending",s=["critical","major","minor"].includes(i.priority)?i.priority:"minor",r=me[s],o=i.verification||[],n=this._getWaiverForItem(i.id),l=!!n,c=i.status==="failing"&&(s==="critical"||s==="major"),p=l?`<span class="item-waived-badge" title="${this._escapeHtml(n.reason||"No reason provided")}">WAIVED</span>`:"",u="";return c&&(l?u=`<button class="waiver-btn waiver-btn-unwaive" data-unwaive-id="${this._escapeHtml(i.id)}">Unwaive</button>`:u=`<button class="waiver-btn" data-waive-id="${this._escapeHtml(i.id)}">Waive</button>`),`
6262
6274
  <div class="item">
6263
- <div class="item-status ${i}"></div>
6264
- <div class="item-title">${this._escapeHtml(a.title||a.id||"?")}</div>
6275
+ <div class="item-status ${a}"></div>
6276
+ <div class="item-title">${this._escapeHtml(i.title||i.id||"?")}</div>
6265
6277
  <span class="item-priority" style="color:${r};border:1px solid ${r}">${s}</span>
6266
6278
  ${p}
6267
6279
  ${u}
@@ -6274,7 +6286,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
6274
6286
  <p><strong>No checklist data yet.</strong></p>
6275
6287
  <p class="hint">The spec checklist is generated during the first iteration. Start a session with <code>loki start ./spec.md</code> (PRD files also accepted) -- groups and items will appear here as the session progresses and can be expanded for details.</p>
6276
6288
  </div>
6277
- `}_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",a=>{a.stopPropagation(),this._waiveItem(e.dataset.waiveId)})}),t.querySelectorAll("button[data-unwaive-id]").forEach(e=>{e.addEventListener("click",a=>{a.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",W);var qt={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}},Q=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._pollInterval=null,this._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,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,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()]),a=JSON.stringify({status:t?.status,port:t?.port,restarts:t?.restart_count,url:t?.url}),i=JSON.stringify(e?.lines?.slice(-5)||[]),s=i!==this._lastLogsHash;if(a===this._lastDataHash&&!s)return;this._lastDataHash=a,this._lastLogsHash=i,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),i=Math.floor((new Date-e)/1e3);if(i<60)return`${i}s`;if(i<3600)return`${Math.floor(i/60)}m ${i%60}s`;let s=Math.floor(i/3600),r=Math.floor(i%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`
6289
+ `}_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",W);var Jt={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}},Q=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._pollInterval=null,this._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`
6278
6290
  .app-status {
6279
6291
  padding: 16px;
6280
6292
  font-family: var(--loki-font-family, system-ui, -apple-system, sans-serif);
@@ -6435,7 +6447,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
6435
6447
  border-radius: 4px;
6436
6448
  font-size: 12px;
6437
6449
  }
6438
- `}render(){let t=this.shadowRoot;if(!t)return;let e=this._status,a=e&&e.status&&e.status!=="not_initialized";t.innerHTML=`
6450
+ `}render(){let t=this.shadowRoot;if(!t)return;let e=this._status,i=e&&e.status&&e.status!=="not_initialized";t.innerHTML=`
6439
6451
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
6440
6452
  <div class="app-status">
6441
6453
  <div class="header">
@@ -6443,19 +6455,19 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
6443
6455
  <h2 class="title">App Runner</h2>
6444
6456
  ${this._renderStatusBadge(e)}
6445
6457
  </div>
6446
- ${a?this._renderActions(e):""}
6458
+ ${i?this._renderActions(e):""}
6447
6459
  </div>
6448
- ${a?this._renderStatusCard(e):""}
6449
- ${a&&this._logs.length>0?this._renderLogs():""}
6450
- ${a?"":this._renderEmpty()}
6460
+ ${i?this._renderStatusCard(e):""}
6461
+ ${i&&this._logs.length>0?this._renderLogs():""}
6462
+ ${i?"":this._renderEmpty()}
6451
6463
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
6452
6464
  </div>
6453
- `,this._attachEventListeners()}_renderStatusBadge(t){let e=t?.status||"not_initialized",a=qt[e]||qt.not_initialized;return`
6454
- <span class="status-badge" style="background: color-mix(in srgb, ${a.color} 15%, transparent); color: ${a.color}">
6455
- <span class="status-dot ${a.pulse?"pulse":""}" style="background: ${a.color}"></span>
6456
- ${this._escapeHtml(a.label)}
6465
+ `,this._attachEventListeners()}_renderStatusBadge(t){let e=t?.status||"not_initialized",i=Jt[e]||Jt.not_initialized;return`
6466
+ <span class="status-badge" style="background: color-mix(in srgb, ${i.color} 15%, transparent); color: ${i.color}">
6467
+ <span class="status-dot ${i.pulse?"pulse":""}" style="background: ${i.color}"></span>
6468
+ ${this._escapeHtml(i.label)}
6457
6469
  </span>
6458
- `}_renderStatusCard(t){let a=this._isValidUrl(t.url)?`<a href="${this._escapeHtml(t.url)}" target="_blank" rel="noopener noreferrer">${this._escapeHtml(t.url)}</a>`:this._escapeHtml(t.url||"--");return`
6470
+ `}_renderStatusCard(t){let i=this._isValidUrl(t.url)?`<a href="${this._escapeHtml(t.url)}" target="_blank" rel="noopener noreferrer">${this._escapeHtml(t.url)}</a>`:this._escapeHtml(t.url||"--");return`
6459
6471
  <div class="status-card">
6460
6472
  <div class="status-row">
6461
6473
  <span class="status-label">Method</span>
@@ -6467,7 +6479,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
6467
6479
  </div>
6468
6480
  <div class="status-row">
6469
6481
  <span class="status-label">URL</span>
6470
- <span class="status-value">${a}</span>
6482
+ <span class="status-value">${i}</span>
6471
6483
  </div>
6472
6484
  <div class="status-row">
6473
6485
  <span class="status-label">Restarts</span>
@@ -6490,27 +6502,27 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
6490
6502
  <div class="log-area">${t.length>0?t.map(e=>this._escapeHtml(e)).join(`
6491
6503
  `):'<span class="log-empty">No log output yet</span>'}</div>
6492
6504
  </div>
6493
- `}_renderActions(t){let e=t.status==="running"||t.status==="crashed"||t.status==="stopped",a=t.status==="running"||t.status==="starting";return`
6505
+ `}_renderActions(t){let e=t.status==="running"||t.status==="crashed"||t.status==="stopped",i=t.status==="running"||t.status==="starting";return`
6494
6506
  <div class="actions">
6495
6507
  <button class="btn" data-action="restart" ${e?"":"disabled"}>Restart</button>
6496
- <button class="btn btn-danger" data-action="stop" ${a?"":"disabled"}>Stop</button>
6508
+ <button class="btn btn-danger" data-action="stop" ${i?"":"disabled"}>Stop</button>
6497
6509
  </div>
6498
6510
  `}_renderEmpty(){return`
6499
6511
  <div class="empty-state">
6500
6512
  <p>App runner not started</p>
6501
6513
  <p class="hint">App runner will start after the first successful build iteration.</p>
6502
6514
  </div>
6503
- `}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.querySelector('[data-action="restart"]'),a=t.querySelector('[data-action="stop"]');e&&e.addEventListener("click",()=>this._handleRestart()),a&&a.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",Q);var ve={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"}},X=class extends h{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={...ve}}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadPricing(),this._loadCost(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,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[a,i]of Object.entries(t.models))e[a]={input:i.input,output:i.output,label:i.label||a,provider:i.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,a])=>{let i=a.input_tokens||0,s=a.output_tokens||0,r=a.cost_usd||0;return`
6515
+ `}_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",Q);var be={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"}},X=class extends h{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={...be}}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`
6504
6516
  <tr>
6505
6517
  <td class="phase-name">${this._escapeHTML(e)}</td>
6506
- <td class="mono-cell">${this._formatTokens(i)}</td>
6518
+ <td class="mono-cell">${this._formatTokens(a)}</td>
6507
6519
  <td class="mono-cell">${this._formatTokens(s)}</td>
6508
6520
  <td class="mono-cell cost-cell">${this._formatUSD(r)}</td>
6509
6521
  </tr>
6510
- `}).join("")}_renderModelRows(){let t=this._data.by_model;return!t||Object.keys(t).length===0?'<tr><td colspan="4" class="empty-cell">No model data yet</td></tr>':Object.entries(t).map(([e,a])=>{let i=a.input_tokens||0,s=a.output_tokens||0,r=a.cost_usd||0;return`
6522
+ `}).join("")}_renderModelRows(){let t=this._data.by_model;return!t||Object.keys(t).length===0?'<tr><td colspan="4" class="empty-cell">No model 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`
6511
6523
  <tr>
6512
6524
  <td class="model-name">${this._escapeHTML(e)}</td>
6513
- <td class="mono-cell">${this._formatTokens(i)}</td>
6525
+ <td class="mono-cell">${this._formatTokens(a)}</td>
6514
6526
  <td class="mono-cell">${this._formatTokens(s)}</td>
6515
6527
  <td class="mono-cell cost-cell">${this._formatUSD(r)}</td>
6516
6528
  </tr>
@@ -6524,7 +6536,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
6524
6536
  </div>
6525
6537
  <div class="budget-not-set">No budget configured</div>
6526
6538
  </div>
6527
- `;let t=this._getBudgetPercent(),e=this._getBudgetStatusClass(),a=this._data.budget_remaining!=null?this._formatUSD(this._data.budget_remaining):this._formatUSD(this._data.budget_limit-this._data.budget_used);return`
6539
+ `;let t=this._getBudgetPercent(),e=this._getBudgetStatusClass(),i=this._data.budget_remaining!=null?this._formatUSD(this._data.budget_remaining):this._formatUSD(this._data.budget_limit-this._data.budget_used);return`
6528
6540
  <div class="budget-section">
6529
6541
  <div class="section-header">
6530
6542
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
@@ -6537,11 +6549,11 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
6537
6549
  </div>
6538
6550
  <div class="budget-details">
6539
6551
  <span class="budget-used">${this._formatUSD(this._data.budget_used)} used</span>
6540
- <span class="budget-remaining">${a} remaining</span>
6552
+ <span class="budget-remaining">${i} remaining</span>
6541
6553
  <span class="budget-limit">of ${this._formatUSD(this._data.budget_limit)}</span>
6542
6554
  </div>
6543
6555
  </div>
6544
- `}_getRARVTier(t){if(t==null)return null;switch(t%4){case 0:return"opus";case 1:return"sonnet";case 2:return"sonnet";case 3:return"haiku";default:return"sonnet"}}_getPricingColorClass(t,e){if(e.tier==="planning")return"opus";if(e.tier==="development")return"sonnet";if(e.tier==="fast")return"haiku";if(e.iteration!=null)return this._getRARVTier(e.iteration)||"";let a=(t||"").toLowerCase();return a.includes("opus")?"opus":a.includes("sonnet")?"sonnet":a.includes("haiku")?"haiku":e.provider==="codex"||a.includes("gpt")||a.includes("codex")?"codex":""}_escapeHTML(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}render(){let t=this._data.total_input_tokens+this._data.total_output_tokens;this.shadowRoot.innerHTML=`
6556
+ `}_getRARVTier(t){if(t==null)return null;switch(t%4){case 0:return"opus";case 1:return"sonnet";case 2:return"sonnet";case 3:return"haiku";default:return"sonnet"}}_getPricingColorClass(t,e){if(e.tier==="planning")return"opus";if(e.tier==="development")return"sonnet";if(e.tier==="fast")return"haiku";if(e.iteration!=null)return this._getRARVTier(e.iteration)||"";let i=(t||"").toLowerCase();return i.includes("opus")?"opus":i.includes("sonnet")?"sonnet":i.includes("haiku")?"haiku":e.provider==="codex"||i.includes("gpt")||i.includes("codex")?"codex":""}_escapeHTML(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}render(){let t=this._data.total_input_tokens+this._data.total_output_tokens;this.shadowRoot.innerHTML=`
6545
6557
  <style>
6546
6558
  ${this.getBaseStyles()}
6547
6559
 
@@ -6894,15 +6906,15 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
6894
6906
  ${this._pricingDate?`<span class="pricing-meta">Updated: ${this._escapeHTML(this._pricingDate)}</span>`:""}
6895
6907
  </div>
6896
6908
  <div class="pricing-grid">
6897
- ${Object.entries(this._modelPricing).map(([e,a])=>`
6909
+ ${Object.entries(this._modelPricing).map(([e,i])=>`
6898
6910
  <div class="pricing-item">
6899
- <div class="pricing-model ${this._getPricingColorClass(e,a)}">${a.label||e}</div>
6900
- <div class="pricing-rates">In: $${Number(a.input??0).toFixed(2)} / Out: $${Number(a.output??0).toFixed(2)}</div>
6911
+ <div class="pricing-model ${this._getPricingColorClass(e,i)}">${i.label||e}</div>
6912
+ <div class="pricing-rates">In: $${Number(i.input??0).toFixed(2)} / Out: $${Number(i.output??0).toFixed(2)}</div>
6901
6913
  </div>`).join("")}
6902
6914
  </div>
6903
6915
  </div>
6904
6916
  </div>
6905
- `}};customElements.get("loki-cost-dashboard")||customElements.define("loki-cost-dashboard",X);var Z=class extends h{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,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,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(a){this._creating=!1,this._error=`Failed to create checkpoint: ${a.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(),a=new Date(t).getTime(),i=Math.floor((e-a)/1e3);return i<60?`${i}s ago`:i<3600?`${Math.floor(i/60)}m ago`:i<86400?`${Math.floor(i/3600)}h ago`:`${Math.floor(i/86400)}d ago`}catch{return this._escapeHTML(t)}}render(){let t=this.shadowRoot;if(!t)return;let e=this._checkpoints.length;t.innerHTML=`
6917
+ `}};customElements.get("loki-cost-dashboard")||customElements.define("loki-cost-dashboard",X);var Z=class extends h{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=`
6906
6918
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
6907
6919
  <div class="checkpoint-viewer">
6908
6920
  <div class="checkpoint-header">
@@ -6920,7 +6932,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
6920
6932
  <div class="checkpoint-list">
6921
6933
  ${this._loading?'<div class="loading-state">Loading checkpoints...</div>':""}
6922
6934
  ${!this._loading&&e===0?'<div class="empty-state">No checkpoints yet. Create one to save the current state.</div>':""}
6923
- ${this._checkpoints.map(a=>this._renderCheckpointCard(a)).join("")}
6935
+ ${this._checkpoints.map(i=>this._renderCheckpointCard(i)).join("")}
6924
6936
  </div>
6925
6937
 
6926
6938
  ${this._error?`<div class="error-banner">${this._escapeHTML(this._error)}</div>`:""}
@@ -6939,7 +6951,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
6939
6951
  ${this._creating?"Creating...":"Save"}
6940
6952
  </button>
6941
6953
  </div>
6942
- `}_renderCheckpointCard(t){let e=t.git_sha?t.git_sha.substring(0,7):"",a=t.files_count||(Array.isArray(t.files)?t.files.length:0),i=this._rollbackTarget===t.id,s=t.iteration!=null?`Iter ${t.iteration}`:"",r=t.provider||"",o=t.phase||"",n=t.git_branch||"",l=[s,r,o].filter(Boolean);return`
6954
+ `}_renderCheckpointCard(t){let e=t.git_sha?t.git_sha.substring(0,7):"",i=t.files_count||(Array.isArray(t.files)?t.files.length:0),a=this._rollbackTarget===t.id,s=t.iteration!=null?`Iter ${t.iteration}`:"",r=t.provider||"",o=t.phase||"",n=t.git_branch||"",l=[s,r,o].filter(Boolean);return`
6943
6955
  <div class="checkpoint-card" data-checkpoint-id="${this._escapeHTML(t.id)}">
6944
6956
  <div class="card-header">
6945
6957
  <div class="header-tags">
@@ -6951,13 +6963,13 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
6951
6963
  <div class="card-body">
6952
6964
  <p class="checkpoint-message">${this._escapeHTML(t.message||"Checkpoint")}</p>
6953
6965
  <div class="card-meta">
6954
- ${a>0?`<span class="meta-item">${a} file${a!==1?"s":""}</span>`:""}
6966
+ ${i>0?`<span class="meta-item">${i} file${i!==1?"s":""}</span>`:""}
6955
6967
  ${n?`<span class="meta-item mono">${this._escapeHTML(n)}</span>`:""}
6956
6968
  <span class="meta-item mono">${this._escapeHTML(t.id)}</span>
6957
6969
  </div>
6958
6970
  </div>
6959
6971
  <div class="card-actions">
6960
- ${i?`
6972
+ ${a?`
6961
6973
  <span class="rollback-confirm-text">Rollback to this checkpoint?</span>
6962
6974
  <button class="btn btn-sm btn-danger" data-action="confirm-rollback" data-id="${this._escapeHTML(t.id)}">Confirm</button>
6963
6975
  <button class="btn btn-sm" data-action="cancel-rollback">Cancel</button>
@@ -6966,7 +6978,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
6966
6978
  `}
6967
6979
  </div>
6968
6980
  </div>
6969
- `}_escapeHTML(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.getElementById("create-btn");e&&e.addEventListener("click",()=>this._toggleCreateForm());let a=t.getElementById("submit-create-btn");a&&a.addEventListener("click",()=>this._createCheckpoint());let i=t.getElementById("checkpoint-message");i&&(i.addEventListener("keydown",s=>{s.key==="Enter"&&!this._creating&&(s.preventDefault(),this._createCheckpoint())}),requestAnimationFrame(()=>i.focus())),t.querySelectorAll("[data-action]").forEach(s=>{s.addEventListener("click",r=>{r.stopPropagation();let o=s.dataset.action,n=s.dataset.id;o==="rollback"?this._confirmRollback(n):o==="confirm-rollback"?this._rollbackCheckpoint(n):o==="cancel-rollback"&&this._cancelRollback()})})}_getStyles(){return`
6981
+ `}_escapeHTML(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.getElementById("create-btn");e&&e.addEventListener("click",()=>this._toggleCreateForm());let i=t.getElementById("submit-create-btn");i&&i.addEventListener("click",()=>this._createCheckpoint());let a=t.getElementById("checkpoint-message");a&&(a.addEventListener("keydown",s=>{s.key==="Enter"&&!this._creating&&(s.preventDefault(),this._createCheckpoint())}),requestAnimationFrame(()=>a.focus())),t.querySelectorAll("[data-action]").forEach(s=>{s.addEventListener("click",r=>{r.stopPropagation();let o=s.dataset.action,n=s.dataset.id;o==="rollback"?this._confirmRollback(n):o==="confirm-rollback"?this._rollbackCheckpoint(n):o==="cancel-rollback"&&this._cancelRollback()})})}_getStyles(){return`
6970
6982
  :host {
6971
6983
  display: block;
6972
6984
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
@@ -7210,10 +7222,10 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
7210
7222
  color: var(--loki-red);
7211
7223
  font-size: 12px;
7212
7224
  }
7213
- `}};customElements.get("loki-checkpoint-viewer")||customElements.define("loki-checkpoint-viewer",Z);var tt=class extends h{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,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,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||{},a=t.context_window_pct||0,i=this._getGaugeColor(a),s=this._getGaugeColorClass(a),r=70,o=2*Math.PI*r,n=o-a/100*o;return`
7225
+ `}};customElements.get("loki-checkpoint-viewer")||customElements.define("loki-checkpoint-viewer",Z);var tt=class extends h{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`
7214
7226
  <div class="gauge-tab">
7215
7227
  <div class="gauge-container">
7216
- <svg class="gauge-svg" viewBox="0 0 180 180" aria-label="Context window usage: ${a.toFixed(1)}%">
7228
+ <svg class="gauge-svg" viewBox="0 0 180 180" aria-label="Context window usage: ${i.toFixed(1)}%">
7217
7229
  <circle
7218
7230
  class="gauge-bg"
7219
7231
  cx="90" cy="90" r="${r}"
@@ -7225,7 +7237,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
7225
7237
  class="gauge-ring ${s}"
7226
7238
  cx="90" cy="90" r="${r}"
7227
7239
  fill="none"
7228
- stroke="${i}"
7240
+ stroke="${a}"
7229
7241
  stroke-width="12"
7230
7242
  stroke-linecap="round"
7231
7243
  stroke-dasharray="${o}"
@@ -7235,7 +7247,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
7235
7247
  <text class="gauge-pct" x="90" y="85" text-anchor="middle"
7236
7248
  fill="var(--loki-text-primary)" font-size="28" font-weight="600"
7237
7249
  font-family="'JetBrains Mono', monospace">
7238
- ${a.toFixed(1)}%
7250
+ ${i.toFixed(1)}%
7239
7251
  </text>
7240
7252
  <text class="gauge-label" x="90" y="108" text-anchor="middle"
7241
7253
  fill="var(--loki-text-muted)" font-size="11">
@@ -7285,7 +7297,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
7285
7297
  </div>
7286
7298
  </div>
7287
7299
  </div>
7288
- `}_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 a=Math.max(...t.map(r=>(r.input_tokens||0)+(r.output_tokens||0)+(r.cache_read_tokens||0)+(r.cache_creation_tokens||0))),i=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=a>0?o/a*100:0,l=r.compacted===!0;i.has(r.iteration)&&(s+=`
7300
+ `}_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+=`
7289
7301
  <div class="timeline-compaction-row">
7290
7302
  <div class="compaction-line"></div>
7291
7303
  <span class="compaction-label">Context Compacted</span>
@@ -7316,21 +7328,21 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
7316
7328
  </div>
7317
7329
  ${s}
7318
7330
  </div>
7319
- `}_renderBreakdownTab(){let t=this._data?.per_iteration||[];if(t.length===0)return'<div class="empty-state">No iteration data yet</div>';let e=Math.max(...t.map(s=>(s.input_tokens||0)+(s.output_tokens||0)+(s.cache_read_tokens||0)+(s.cache_creation_tokens||0))),a=`
7331
+ `}_renderBreakdownTab(){let t=this._data?.per_iteration||[];if(t.length===0)return'<div class="empty-state">No iteration data yet</div>';let e=Math.max(...t.map(s=>(s.input_tokens||0)+(s.output_tokens||0)+(s.cache_read_tokens||0)+(s.cache_creation_tokens||0))),i=`
7320
7332
  <div class="breakdown-legend">
7321
7333
  <div class="legend-item"><span class="legend-swatch swatch-input"></span> Input</div>
7322
7334
  <div class="legend-item"><span class="legend-swatch swatch-output"></span> Output</div>
7323
7335
  <div class="legend-item"><span class="legend-swatch swatch-cache-read"></span> Cache Read</div>
7324
7336
  <div class="legend-item"><span class="legend-swatch swatch-cache-create"></span> Cache Creation</div>
7325
7337
  </div>
7326
- `,i="";for(let s of t){let r=s.input_tokens||0,o=s.output_tokens||0,n=s.cache_read_tokens||0,l=s.cache_creation_tokens||0,c=r+o+n+l,p=e>0?r/e*100:0,u=e>0?o/e*100:0,b=e>0?n/e*100:0,m=e>0?l/e*100:0;i+=`
7338
+ `,a="";for(let s of t){let r=s.input_tokens||0,o=s.output_tokens||0,n=s.cache_read_tokens||0,l=s.cache_creation_tokens||0,c=r+o+n+l,p=e>0?r/e*100:0,u=e>0?o/e*100:0,b=e>0?n/e*100:0,v=e>0?l/e*100:0;a+=`
7327
7339
  <div class="breakdown-row">
7328
7340
  <div class="breakdown-iter">#${s.iteration}</div>
7329
7341
  <div class="breakdown-bar-container">
7330
7342
  <div class="breakdown-bar bar-input" style="width: ${p.toFixed(1)}%"></div>
7331
7343
  <div class="breakdown-bar bar-output" style="width: ${u.toFixed(1)}%"></div>
7332
7344
  <div class="breakdown-bar bar-cache-read" style="width: ${b.toFixed(1)}%"></div>
7333
- <div class="breakdown-bar bar-cache-create" style="width: ${m.toFixed(1)}%"></div>
7345
+ <div class="breakdown-bar bar-cache-create" style="width: ${v.toFixed(1)}%"></div>
7334
7346
  </div>
7335
7347
  <div class="breakdown-cost">${this._formatUSD(s.cost_usd)}</div>
7336
7348
  </div>
@@ -7344,8 +7356,8 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
7344
7356
  </svg>
7345
7357
  <span class="section-title">Token Type Breakdown</span>
7346
7358
  </div>
7347
- ${a}
7348
7359
  ${i}
7360
+ ${a}
7349
7361
  </div>
7350
7362
  `}render(){let t=this._activeTab==="gauge"?this._renderGaugeTab():this._activeTab==="timeline"?this._renderTimelineTab():this._renderBreakdownTab();this.shadowRoot.innerHTML=`
7351
7363
  <style>
@@ -7733,7 +7745,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
7733
7745
 
7734
7746
  ${t}
7735
7747
  </div>
7736
- `,this.shadowRoot.querySelectorAll(".tab").forEach(e=>{e.addEventListener("click",()=>{this._setTab(e.dataset.tab)})})}};customElements.get("loki-context-tracker")||customElements.define("loki-context-tracker",tt);var Lt={critical:"var(--loki-red, #ef4444)",warning:"var(--loki-yellow, #eab308)",info:"var(--loki-blue, #3b82f6)",success:"var(--loki-green, #1FC5A8)"},Jt={build:{label:"Build",icon:"B"},quality:{label:"Quality",icon:"Q"},system:{label:"System",icon:"S"},security:{label:"Security",icon:"!"}},et=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._notifications=[],this._triggers=[],this._summary={},this._connected=!1,this._activeTab="feed",this._categoryFilter="all",this._panelOpen=!0,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._loadNotifications(),this._loadTriggers(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){e!==a&&(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 a=await e.json();this._notifications=a.notifications||[],this._summary=a.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 a=await e.json();this._triggers=a.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 _unacknowledgeNotification(t){let e=this.getAttribute("api-url")||window.location.origin;await fetch(e+"/api/notifications/"+encodeURIComponent(t)+"/unacknowledge",{method:"POST"}),this._loadNotifications()}async _acknowledgeAll(){let t=this.getAttribute("api-url")||window.location.origin,e=this._notifications.filter(a=>!a.acknowledged);for(let a of e)await fetch(t+"/api/notifications/"+encodeURIComponent(a.id)+"/acknowledge",{method:"POST"});this._loadNotifications()}async _toggleTrigger(t,e){let a=this.getAttribute("api-url")||window.location.origin,i=this._triggers.map(s=>s.id===t?{...s,enabled:e}:s);await fetch(a+"/api/notifications/triggers",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({triggers:i})}),this._triggers=i,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),i=new Date-e,s=Math.floor(i/1e3),r=Math.floor(s/60),o=Math.floor(r/60),n=Math.floor(o/24);return s<60?s+"s ago":r<60?r+"m ago":o<24?o+"h ago":n<7?n+"d ago":e.toLocaleDateString()}catch{return String(t)}}_getTimeGroup(t){if(!t)return"Other";try{let e=new Date(t),a=new Date,i=new Date(a.getFullYear(),a.getMonth(),a.getDate()),s=new Date(i);s.setDate(s.getDate()-1);let r=new Date(i);return r.setDate(r.getDate()-7),e>=i?"Today":e>=s?"Yesterday":e>=r?"This Week":"Earlier"}catch{return"Other"}}_escapeHTML(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getSeverityColor(t){return Lt[t]||Lt.info}_getCategory(t){return t.category||t.type||"system"}_switchTab(t){this._activeTab=t,this.render()}_setCategoryFilter(t){this._categoryFilter=t,this.render()}_togglePanel(){this._panelOpen=!this._panelOpen,this.render()}_bindEvents(){let t=this.shadowRoot;t.querySelectorAll(".tab").forEach(i=>{i.addEventListener("click",()=>{this._switchTab(i.dataset.tab)})}),t.querySelectorAll(".cat-btn").forEach(i=>{i.addEventListener("click",()=>{this._setCategoryFilter(i.dataset.cat)})}),t.querySelectorAll(".ack-btn").forEach(i=>{i.addEventListener("click",s=>{s.stopPropagation(),this._acknowledgeNotification(i.dataset.id)})}),t.querySelectorAll(".unread-btn").forEach(i=>{i.addEventListener("click",s=>{s.stopPropagation(),this._unacknowledgeNotification(i.dataset.id)})});let e=t.querySelector(".ack-all-btn");e&&e.addEventListener("click",()=>{this._acknowledgeAll()});let a=t.querySelector(".bell-icon");a&&a.addEventListener("click",()=>{this._togglePanel()}),t.querySelectorAll(".toggle input").forEach(i=>{i.addEventListener("change",()=>{this._toggleTrigger(i.dataset.triggerId,i.checked)})}),t.querySelectorAll(".dismiss-btn").forEach(i=>{i.addEventListener("click",s=>{s.stopPropagation(),this._acknowledgeNotification(i.dataset.id)})})}_renderBellIcon(){let t=this._summary.unacknowledged||0;return`
7748
+ `,this.shadowRoot.querySelectorAll(".tab").forEach(e=>{e.addEventListener("click",()=>{this._setTab(e.dataset.tab)})})}};customElements.get("loki-context-tracker")||customElements.define("loki-context-tracker",tt);var Dt={critical:"var(--loki-red, #ef4444)",warning:"var(--loki-yellow, #eab308)",info:"var(--loki-blue, #3b82f6)",success:"var(--loki-green, #1FC5A8)"},Gt={build:{label:"Build",icon:"B"},quality:{label:"Quality",icon:"Q"},system:{label:"System",icon:"S"},security:{label:"Security",icon:"!"}},et=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._notifications=[],this._triggers=[],this._summary={},this._connected=!1,this._activeTab="feed",this._categoryFilter="all",this._panelOpen=!0,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._loadNotifications(),this._loadTriggers(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&(this._loadNotifications(),this._loadTriggers()),t==="theme"&&this._applyTheme())}async _loadNotifications(){try{let t=this.getAttribute("api-url")||window.location.origin,e=await fetch(t+"/api/notifications");if(e.ok){let i=await e.json();this._notifications=i.notifications||[],this._summary=i.summary||{},this._connected=!0}}catch{this._connected=!1}this.render()}async _loadTriggers(){try{let t=this.getAttribute("api-url")||window.location.origin,e=await fetch(t+"/api/notifications/triggers");if(e.ok){let i=await e.json();this._triggers=i.triggers||[]}}catch{}}async _acknowledgeNotification(t){let e=this.getAttribute("api-url")||window.location.origin;await fetch(e+"/api/notifications/"+encodeURIComponent(t)+"/acknowledge",{method:"POST"}),this._loadNotifications()}async _unacknowledgeNotification(t){let e=this.getAttribute("api-url")||window.location.origin;await fetch(e+"/api/notifications/"+encodeURIComponent(t)+"/unacknowledge",{method:"POST"}),this._loadNotifications()}async _acknowledgeAll(){let t=this.getAttribute("api-url")||window.location.origin,e=this._notifications.filter(i=>!i.acknowledged);for(let i of e)await fetch(t+"/api/notifications/"+encodeURIComponent(i.id)+"/acknowledge",{method:"POST"});this._loadNotifications()}async _toggleTrigger(t,e){let i=this.getAttribute("api-url")||window.location.origin,a=this._triggers.map(s=>s.id===t?{...s,enabled:e}:s);await fetch(i+"/api/notifications/triggers",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({triggers:a})}),this._triggers=a,this.render()}_startPolling(){this._pollInterval=setInterval(()=>{this._loadNotifications(),this._loadTriggers()},5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_formatTime(t){if(!t)return"";try{let e=new Date(t),a=new Date-e,s=Math.floor(a/1e3),r=Math.floor(s/60),o=Math.floor(r/60),n=Math.floor(o/24);return s<60?s+"s ago":r<60?r+"m ago":o<24?o+"h ago":n<7?n+"d ago":e.toLocaleDateString()}catch{return String(t)}}_getTimeGroup(t){if(!t)return"Other";try{let e=new Date(t),i=new Date,a=new Date(i.getFullYear(),i.getMonth(),i.getDate()),s=new Date(a);s.setDate(s.getDate()-1);let r=new Date(a);return r.setDate(r.getDate()-7),e>=a?"Today":e>=s?"Yesterday":e>=r?"This Week":"Earlier"}catch{return"Other"}}_escapeHTML(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getSeverityColor(t){return Dt[t]||Dt.info}_getCategory(t){return t.category||t.type||"system"}_switchTab(t){this._activeTab=t,this.render()}_setCategoryFilter(t){this._categoryFilter=t,this.render()}_togglePanel(){this._panelOpen=!this._panelOpen,this.render()}_bindEvents(){let t=this.shadowRoot;t.querySelectorAll(".tab").forEach(a=>{a.addEventListener("click",()=>{this._switchTab(a.dataset.tab)})}),t.querySelectorAll(".cat-btn").forEach(a=>{a.addEventListener("click",()=>{this._setCategoryFilter(a.dataset.cat)})}),t.querySelectorAll(".ack-btn").forEach(a=>{a.addEventListener("click",s=>{s.stopPropagation(),this._acknowledgeNotification(a.dataset.id)})}),t.querySelectorAll(".unread-btn").forEach(a=>{a.addEventListener("click",s=>{s.stopPropagation(),this._unacknowledgeNotification(a.dataset.id)})});let e=t.querySelector(".ack-all-btn");e&&e.addEventListener("click",()=>{this._acknowledgeAll()});let i=t.querySelector(".bell-icon");i&&i.addEventListener("click",()=>{this._togglePanel()}),t.querySelectorAll(".toggle input").forEach(a=>{a.addEventListener("change",()=>{this._toggleTrigger(a.dataset.triggerId,a.checked)})}),t.querySelectorAll(".dismiss-btn").forEach(a=>{a.addEventListener("click",s=>{s.stopPropagation(),this._acknowledgeNotification(a.dataset.id)})})}_renderBellIcon(){let t=this._summary.unacknowledged||0;return`
7737
7749
  <div class="bell-container">
7738
7750
  <button class="bell-icon" title="${t} unread notifications">
7739
7751
  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
@@ -7743,7 +7755,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
7743
7755
  ${t>0?`<span class="badge">${t>99?"99+":t}</span>`:""}
7744
7756
  </button>
7745
7757
  </div>
7746
- `}_renderSummaryBar(){let t=this._summary.total||0,e=this._summary.unacknowledged||0,a=this._summary.critical||0;return`
7758
+ `}_renderSummaryBar(){let t=this._summary.total||0,e=this._summary.unacknowledged||0,i=this._summary.critical||0;return`
7747
7759
  <div class="summary-row">
7748
7760
  <div class="summary-grid">
7749
7761
  <div class="summary-card">
@@ -7756,7 +7768,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
7756
7768
  </div>
7757
7769
  <div class="summary-card">
7758
7770
  <div class="card-label">Critical</div>
7759
- <div class="card-value" style="color: ${Lt.critical}">${a}</div>
7771
+ <div class="card-value" style="color: ${Dt.critical}">${i}</div>
7760
7772
  </div>
7761
7773
  </div>
7762
7774
  ${e>0?`
@@ -7765,9 +7777,9 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
7765
7777
  </div>
7766
7778
  `}_renderCategoryFilter(){return`
7767
7779
  <div class="category-bar">
7768
- ${["all","build","quality","system","security"].map(e=>{let a=this._categoryFilter===e,i=e==="all"?"All":Jt[e]?.label||e;return`<button class="cat-btn ${a?"active":""}" data-cat="${e}">${i}</button>`}).join("")}
7780
+ ${["all","build","quality","system","security"].map(e=>{let i=this._categoryFilter===e,a=e==="all"?"All":Gt[e]?.label||e;return`<button class="cat-btn ${i?"active":""}" data-cat="${e}">${a}</button>`}).join("")}
7769
7781
  </div>
7770
- `}_renderNotificationList(){let t=[...this._notifications].sort((s,r)=>new Date(r.timestamp)-new Date(s.timestamp));if(this._categoryFilter!=="all"&&(t=t.filter(s=>this._getCategory(s)===this._categoryFilter)),t.length===0)return'<div class="empty-state">No notifications</div>';let e={};for(let s of t){let r=this._getTimeGroup(s.timestamp);e[r]||(e[r]=[]),e[r].push(s)}let a=["Today","Yesterday","This Week","Earlier","Other"],i="";for(let s of a)!e[s]||e[s].length===0||(i+=`<div class="time-group-label">${s}</div>`,i+=e[s].map(r=>{let o=r.acknowledged,n=this._getSeverityColor(r.severity),l=this._getCategory(r),c=Jt[l]||{label:l,icon:"?"};return`
7782
+ `}_renderNotificationList(){let t=[...this._notifications].sort((s,r)=>new Date(r.timestamp)-new Date(s.timestamp));if(this._categoryFilter!=="all"&&(t=t.filter(s=>this._getCategory(s)===this._categoryFilter)),t.length===0)return'<div class="empty-state">No notifications</div>';let e={};for(let s of t){let r=this._getTimeGroup(s.timestamp);e[r]||(e[r]=[]),e[r].push(s)}let i=["Today","Yesterday","This Week","Earlier","Other"],a="";for(let s of i)!e[s]||e[s].length===0||(a+=`<div class="time-group-label">${s}</div>`,a+=e[s].map(r=>{let o=r.acknowledged,n=this._getSeverityColor(r.severity),l=this._getCategory(r),c=Gt[l]||{label:l,icon:"?"};return`
7771
7783
  <div class="notif-row ${o?"acknowledged":""}">
7772
7784
  <span class="severity-dot" style="background: ${n};" title="${this._escapeHTML(r.severity)}"></span>
7773
7785
  <span class="cat-icon" title="${c.label}">${c.icon}</span>
@@ -7779,7 +7791,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
7779
7791
  <button class="dismiss-btn" data-id="${this._escapeHTML(r.id)}" title="Dismiss">&#10005;</button>
7780
7792
  </span>
7781
7793
  </div>
7782
- `}).join(""));return i}_renderTriggerList(){return this._triggers.length===0?'<div class="empty-state">No triggers configured</div>':this._triggers.map(t=>{let e=this._getSeverityColor(t.severity),a=t.threshold_pct!=null?`Threshold: ${t.threshold_pct}%`:t.pattern||"";return`
7794
+ `}).join(""));return a}_renderTriggerList(){return this._triggers.length===0?'<div class="empty-state">No triggers configured</div>':this._triggers.map(t=>{let e=this._getSeverityColor(t.severity),i=t.threshold_pct!=null?`Threshold: ${t.threshold_pct}%`:t.pattern||"";return`
7783
7795
  <div class="trigger-row">
7784
7796
  <label class="toggle">
7785
7797
  <input type="checkbox" data-trigger-id="${this._escapeHTML(t.id)}" ${t.enabled?"checked":""}>
@@ -7788,7 +7800,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
7788
7800
  <span class="trigger-name">${this._escapeHTML(t.id)}</span>
7789
7801
  <span class="trigger-badge type-badge">${this._escapeHTML(t.type||"custom")}</span>
7790
7802
  <span class="trigger-badge severity-badge" style="background: ${e}; color: #fff;">${this._escapeHTML(t.severity||"info")}</span>
7791
- ${a?`<span class="trigger-info">${this._escapeHTML(a)}</span>`:""}
7803
+ ${i?`<span class="trigger-info">${this._escapeHTML(i)}</span>`:""}
7792
7804
  </div>
7793
7805
  `}).join("")}render(){this.shadowRoot.innerHTML=`
7794
7806
  <style>
@@ -8250,7 +8262,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
8250
8262
  `:""}
8251
8263
  `:""}
8252
8264
  </div>
8253
- `,this._bindEvents()}};customElements.get("loki-notification-center")||customElements.define("loki-notification-center",et);var at=class extends h{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,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,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=`
8265
+ `,this._bindEvents()}};customElements.get("loki-notification-center")||customElements.define("loki-notification-center",et);var it=class extends h{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=`
8254
8266
  ${this.getBaseStyles()}
8255
8267
 
8256
8268
  :host {
@@ -8461,7 +8473,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
8461
8473
  </div>
8462
8474
  <div class="empty-state">No session diff available</div>
8463
8475
  </div>
8464
- `;return}let e=this._data||{},a=this._escapeHtml(e.period||"--"),i=e.counts||{},s=e.highlights||[],r=e.decisions||[],o="";s.length>0&&(o=`
8476
+ `;return}let e=this._data||{},i=this._escapeHtml(e.period||"--"),a=e.counts||{},s=e.highlights||[],r=e.decisions||[],o="";s.length>0&&(o=`
8465
8477
  <div class="highlights-section">
8466
8478
  <div class="section-label">Highlights</div>
8467
8479
  <ul class="highlight-list">
@@ -8487,32 +8499,32 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
8487
8499
  <div class="diff-header">
8488
8500
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 013 3L7 19l-4 1 1-4L16.5 3.5z"/></svg>
8489
8501
  <span class="diff-title">Session Resume</span>
8490
- <span class="diff-period">${a}</span>
8502
+ <span class="diff-period">${i}</span>
8491
8503
  </div>
8492
8504
 
8493
8505
  <div class="summary-grid">
8494
8506
  <div class="summary-item">
8495
8507
  <div class="summary-label">Created</div>
8496
- <div class="summary-value">${i.tasks_created!=null?i.tasks_created:"--"}</div>
8508
+ <div class="summary-value">${a.tasks_created!=null?a.tasks_created:"--"}</div>
8497
8509
  </div>
8498
8510
  <div class="summary-item">
8499
8511
  <div class="summary-label">Completed</div>
8500
- <div class="summary-value">${i.tasks_completed!=null?i.tasks_completed:"--"}</div>
8512
+ <div class="summary-value">${a.tasks_completed!=null?a.tasks_completed:"--"}</div>
8501
8513
  </div>
8502
8514
  <div class="summary-item">
8503
8515
  <div class="summary-label">Blocked</div>
8504
- <div class="summary-value">${i.tasks_blocked!=null?i.tasks_blocked:"--"}</div>
8516
+ <div class="summary-value">${a.tasks_blocked!=null?a.tasks_blocked:"--"}</div>
8505
8517
  </div>
8506
8518
  <div class="summary-item">
8507
8519
  <div class="summary-label">Errors</div>
8508
- <div class="summary-value ${(i.errors||0)>0?"error-count":""}">${i.errors!=null?i.errors:"--"}</div>
8520
+ <div class="summary-value ${(a.errors||0)>0?"error-count":""}">${a.errors!=null?a.errors:"--"}</div>
8509
8521
  </div>
8510
8522
  </div>
8511
8523
 
8512
8524
  ${o}
8513
8525
  ${n}
8514
8526
  </div>
8515
- `,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",at);var it=class extends h{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,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,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),i=new Date-e,s=Math.floor(i/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=`
8527
+ `,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",it);var at=class extends h{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=`
8516
8528
  ${this.getBaseStyles()}
8517
8529
 
8518
8530
  :host {
@@ -8722,7 +8734,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
8722
8734
  </div>
8723
8735
  <div class="empty-state">No prompt optimization data available</div>
8724
8736
  </div>
8725
- `;return}let e=this._data||{},a=e.version!=null?e.version:"--",i=this._formatTime(e.last_optimized),s=e.failures_analyzed!=null?e.failures_analyzed:"--",r=e.changes||[],o="";r.length>0&&(o=`
8737
+ `;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=`
8726
8738
  <div class="changes-section">
8727
8739
  <div class="section-label">Changes</div>
8728
8740
  ${r.map((l,c)=>{let p=this._expandedChanges.has(c);return`
@@ -8749,11 +8761,11 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
8749
8761
  <div class="info-grid">
8750
8762
  <div class="info-item">
8751
8763
  <div class="info-label">Version</div>
8752
- <div class="info-value">v${this._escapeHtml(String(a))}</div>
8764
+ <div class="info-value">v${this._escapeHtml(String(i))}</div>
8753
8765
  </div>
8754
8766
  <div class="info-item">
8755
8767
  <div class="info-label">Last Optimized</div>
8756
- <div class="info-value muted">${this._escapeHtml(i)}</div>
8768
+ <div class="info-value muted">${this._escapeHtml(a)}</div>
8757
8769
  </div>
8758
8770
  <div class="info-item">
8759
8771
  <div class="info-label">Failures Analyzed</div>
@@ -8763,7 +8775,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
8763
8775
 
8764
8776
  ${o}
8765
8777
  </div>
8766
- `;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",it);var st=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data=null,this._history=[],this._error=null,this._loading=!0,this._scanning=!1,this._rigourAvailable=!0,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,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 a=t.value;a&&a.error&&a.error.includes("not installed")?(this._rigourAvailable=!1,this._data=null):(this._rigourAvailable=!0,this._data=a),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 a=e.value;this._history=Array.isArray(a)?a.slice(-10):(a.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(c=>typeof c=="number"?c:c.score||0),a=Math.min(...e),s=Math.max(...e)-a||1,r=120,o=32,n=2,l=e.map((c,p)=>{let u=n+p/(e.length-1)*(r-n*2),b=n+(1-(c-a)/s)*(o-n*2);return`${u},${b}`}).join(" ");return`
8778
+ `;let n=this.shadowRoot.getElementById("optimize-btn");n&&n.addEventListener("click",()=>this._triggerOptimize()),this.shadowRoot.querySelectorAll(".change-header").forEach(l=>{l.addEventListener("click",()=>{this._toggleChange(parseInt(l.dataset.index))})})}};customElements.get("loki-prompt-optimizer")||customElements.define("loki-prompt-optimizer",at);var st=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data=null,this._history=[],this._error=null,this._loading=!0,this._scanning=!1,this._rigourAvailable=!0,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _loadData(){try{let[t,e]=await Promise.allSettled([this._api._get("/api/quality-score"),this._api._get("/api/quality-score/history")]);if(t.status==="fulfilled"){let i=t.value;i&&i.error&&i.error.includes("not installed")?(this._rigourAvailable=!1,this._data=null):(this._rigourAvailable=!0,this._data=i),this._error=null}else(t.reason?.message||"").includes("404")?(this._rigourAvailable=!1,this._data=null,this._error=null):(this._error="Failed to load quality score",this._data=null);if(e.status==="fulfilled"){let i=e.value;this._history=Array.isArray(i)?i.slice(-10):(i.scores||[]).slice(-10)}}catch(t){this._error=t.message,this._data=null}this._loading=!1,this.render()}async _triggerScan(){if(!this._scanning){this._scanning=!0,this.render();try{await this._api._post("/api/quality-scan",{}),await this._loadData()}catch(t){this._error=t.message}this._scanning=!1,this.render()}}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),6e4)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_escapeHtml(t){return t?String(t).replace(/&/g,"&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(c=>typeof c=="number"?c:c.score||0),i=Math.min(...e),s=Math.max(...e)-i||1,r=120,o=32,n=2,l=e.map((c,p)=>{let u=n+p/(e.length-1)*(r-n*2),b=n+(1-(c-i)/s)*(o-n*2);return`${u},${b}`}).join(" ");return`
8767
8779
  <svg width="${r}" height="${o}" viewBox="0 0 ${r} ${o}" class="sparkline">
8768
8780
  <polyline points="${l}" fill="none" stroke="var(--loki-accent)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
8769
8781
  <circle cx="${l.split(" ").pop().split(",")[0]}" cy="${l.split(" ").pop().split(",")[1]}" r="2.5" fill="var(--loki-accent)"/>
@@ -9060,7 +9072,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
9060
9072
  </div>
9061
9073
  <div class="empty-state">No quality data available</div>
9062
9074
  </div>
9063
- `;return}let e=this._data||{},a=e.score!=null?Math.round(e.score):0,{grade:i,color:s}=this._getGrade(a),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"},c=n.map(f=>{let x=r[f]!=null?Math.round(r[f]):0,w=x>=80?"var(--loki-success)":x>=60?"var(--loki-warning)":"var(--loki-error)";return`
9075
+ `;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"},c=n.map(f=>{let x=r[f]!=null?Math.round(r[f]):0,w=x>=80?"var(--loki-success)":x>=60?"var(--loki-warning)":"var(--loki-error)";return`
9064
9076
  <div class="category-item">
9065
9077
  <span class="category-name">${l[f]||f}</span>
9066
9078
  <div class="progress-bar">
@@ -9081,8 +9093,8 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
9081
9093
 
9082
9094
  <div class="score-section">
9083
9095
  <div class="score-display">
9084
- <div class="score-number">${a}</div>
9085
- <span class="grade-badge" style="background:${s};color:#fff;">${i}</span>
9096
+ <div class="score-number">${i}</div>
9097
+ <span class="grade-badge" style="background:${s};color:#fff;">${a}</span>
9086
9098
  </div>
9087
9099
  ${b?`
9088
9100
  <div class="sparkline-container">
@@ -9104,43 +9116,43 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
9104
9116
  </div>
9105
9117
  `:""}
9106
9118
  </div>
9107
- `;let m=this.shadowRoot.getElementById("scan-btn");m&&m.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-score")||customElements.define("loki-quality-score",st);var Gt=["understand","guardrail","migrate","verify"],Kt={understand:"Understand",guardrail:"Guardrail",migrate:"Migrate",verify:"Verify"},be={understand:"#5b9bd5",guardrail:"#e8b84a",migrate:"#5bb870",verify:"#5bc8c8"},rt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._migration=null,this._migrations=[],this._loading=!0,this._error=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._fetchMigrations(),this._pollInterval=setInterval(()=>this._fetchData(),15e3)}disconnectedCallback(){super.disconnectedCallback(),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,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(a=>a.status==="in_progress"||a.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,a){return(a||[]).includes(t)?"[x]":t===e?"[>]":"[ ]"}_getPhaseIndex(t){let e=Gt.indexOf(t);return e>=0?e:0}_renderPhaseBar(t,e){let a=e||[];return Gt.map(i=>{let s=a.includes(i),r=i===t,o=be[i],n=s?"1":r?"0.7":"0.2",l=this._getPhaseIcon(i,t,e);return`
9119
+ `;let v=this.shadowRoot.getElementById("scan-btn");v&&v.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-score")||customElements.define("loki-quality-score",st);var Kt=["understand","guardrail","migrate","verify"],Vt={understand:"Understand",guardrail:"Guardrail",migrate:"Migrate",verify:"Verify"},fe={understand:"#5b9bd5",guardrail:"#e8b84a",migrate:"#5bb870",verify:"#5bc8c8"},rt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._migration=null,this._migrations=[],this._loading=!0,this._error=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._fetchMigrations(),this._pollInterval=setInterval(()=>this._fetchData(),15e3)}disconnectedCallback(){super.disconnectedCallback(),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._fetchMigrations()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _fetchMigrations(){try{let t=await this._api._get("/api/migration/list");this._migrations=Array.isArray(t)?t:t.migrations||[],this._error=null;let e=this._migrations.find(i=>i.status==="in_progress"||i.status==="active");e?await this._fetchStatus(e.migration_id||e.id):this._migration=null}catch(t){this._error=t.message,this._migrations=[],this._migration=null}this._loading=!1,this.render()}async _fetchStatus(t){try{this._migration=await this._api._get(`/api/migration/${encodeURIComponent(t)}/status`),this._error=null}catch(e){this._error=e.message}}async _fetchData(){let t=this._migration&&(this._migration.migration_id||this._migration.id);t?(await this._fetchStatus(t),this.render()):await this._fetchMigrations()}_escapeHtml(t){return t?String(t).replace(/&/g,"&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=Kt.indexOf(t);return e>=0?e:0}_renderPhaseBar(t,e){let i=e||[];return Kt.map(a=>{let s=i.includes(a),r=a===t,o=fe[a],n=s?"1":r?"0.7":"0.2",l=this._getPhaseIcon(a,t,e);return`
9108
9120
  <div class="phase-segment">
9109
9121
  <div class="phase-bar-fill" style="background:${o};opacity:${n};"></div>
9110
9122
  <div class="phase-label">
9111
9123
  <span class="phase-icon">${l}</span>
9112
- ${Kt[i]}
9124
+ ${Vt[a]}
9113
9125
  </div>
9114
9126
  </div>
9115
- `}).join("")}_renderFeatureStats(t){if(!t)return"";let e=t.passing||0,a=t.total||0,i=a>0?Math.round(e/a*100):0,s=i>=80?"var(--loki-success)":i>=50?"var(--loki-warning)":"var(--loki-error)";return`
9127
+ `}).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`
9116
9128
  <div class="stat-card">
9117
9129
  <div class="stat-header">Feature Tracking</div>
9118
- <div class="stat-value">${e} / ${a}</div>
9119
- <div class="stat-pct">${i}% passing</div>
9130
+ <div class="stat-value">${e} / ${i}</div>
9131
+ <div class="stat-pct">${a}% passing</div>
9120
9132
  <div class="progress-bar">
9121
- <div class="progress-fill" style="width:${i}%;background:${s};"></div>
9133
+ <div class="progress-fill" style="width:${a}%;background:${s};"></div>
9122
9134
  </div>
9123
9135
  </div>
9124
- `}_renderStepProgress(t){if(!t)return"";let e=t.current||0,a=t.total||0,i=a>0?Math.round(e/a*100):0;return`
9136
+ `}_renderStepProgress(t){if(!t)return"";let e=t.current||0,i=t.total||0,a=i>0?Math.round(e/i*100):0;return`
9125
9137
  <div class="stat-card">
9126
9138
  <div class="stat-header">Step Progress</div>
9127
- <div class="stat-value">${e} / ${a}</div>
9128
- <div class="stat-pct">${i}% complete</div>
9139
+ <div class="stat-value">${e} / ${i}</div>
9140
+ <div class="stat-pct">${a}% complete</div>
9129
9141
  <div class="progress-bar">
9130
- <div class="progress-fill" style="width:${i}%;background:var(--loki-accent);"></div>
9142
+ <div class="progress-fill" style="width:${a}%;background:var(--loki-accent);"></div>
9131
9143
  </div>
9132
9144
  </div>
9133
- `}_renderSeamSummary(t){if(!t)return"";let e=t.total||0,a=t.high||0,i=t.medium||0,s=t.low||0;return`
9145
+ `}_renderSeamSummary(t){if(!t)return"";let e=t.total||0,i=t.high||0,a=t.medium||0,s=t.low||0;return`
9134
9146
  <div class="stat-card">
9135
9147
  <div class="stat-header">Seam Summary</div>
9136
9148
  <div class="stat-value">${e} seams</div>
9137
9149
  <div class="seam-breakdown">
9138
- <span class="seam-badge seam-high">High: ${a}</span>
9139
- <span class="seam-badge seam-medium">Med: ${i}</span>
9150
+ <span class="seam-badge seam-high">High: ${i}</span>
9151
+ <span class="seam-badge seam-medium">Med: ${a}</span>
9140
9152
  <span class="seam-badge seam-low">Low: ${s}</span>
9141
9153
  </div>
9142
9154
  </div>
9143
- `}_renderCheckpoint(t){if(!t)return"";let e=t.timestamp?new Date(t.timestamp).toLocaleString():"--",a=this._escapeHtml(t.step_id||t.stepId||"--");return`
9155
+ `}_renderCheckpoint(t){if(!t)return"";let e=t.timestamp?new Date(t.timestamp).toLocaleString():"--",i=this._escapeHtml(t.step_id||t.stepId||"--");return`
9144
9156
  <div class="checkpoint-section">
9145
9157
  <div class="section-label">Last Checkpoint</div>
9146
9158
  <div class="checkpoint-row">
@@ -9149,7 +9161,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
9149
9161
  </div>
9150
9162
  <div class="checkpoint-row">
9151
9163
  <span class="checkpoint-label">Step:</span>
9152
- <span class="checkpoint-value mono">${a}</span>
9164
+ <span class="checkpoint-value mono">${i}</span>
9153
9165
  </div>
9154
9166
  </div>
9155
9167
  `}_renderMigrationList(){return this._migrations.length===0?'<div class="empty-state">No migrations found</div>':`
@@ -9157,10 +9169,10 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
9157
9169
  <thead>
9158
9170
  <tr><th>ID</th><th>Migration</th><th>Status</th></tr>
9159
9171
  </thead>
9160
- <tbody>${this._migrations.map(e=>{let a=this._escapeHtml(e.migration_id||e.id||"--"),i=this._escapeHtml(e.source||"--"),s=this._escapeHtml(e.target||"--"),r=this._escapeHtml(e.status||"--"),o=e.status==="completed"?"status-done":e.status==="failed"?"status-failed":"status-pending";return`
9172
+ <tbody>${this._migrations.map(e=>{let i=this._escapeHtml(e.migration_id||e.id||"--"),a=this._escapeHtml(e.source||"--"),s=this._escapeHtml(e.target||"--"),r=this._escapeHtml(e.status||"--"),o=e.status==="completed"?"status-done":e.status==="failed"?"status-failed":"status-pending";return`
9161
9173
  <tr>
9162
- <td class="mono">${a}</td>
9163
- <td>${i} -> ${s}</td>
9174
+ <td class="mono">${i}</td>
9175
+ <td>${a} -> ${s}</td>
9164
9176
  <td><span class="status-badge ${o}">${r}</span></td>
9165
9177
  </tr>
9166
9178
  `}).join("")}</tbody>
@@ -9477,13 +9489,13 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
9477
9489
  </div>
9478
9490
  <div class="empty-state">No migration data available</div>
9479
9491
  </div>
9480
- `;return}if(this._migration){let a=this._migration,i=this._escapeHtml(a.migration_id||a.id||"--"),s=this._escapeHtml(a.source||"--"),r=this._escapeHtml(a.target||"--"),o=a.current_phase||a.phase||"understand",n=a.completed_phases||[];this.shadowRoot.innerHTML=`
9492
+ `;return}if(this._migration){let i=this._migration,a=this._escapeHtml(i.migration_id||i.id||"--"),s=this._escapeHtml(i.source||"--"),r=this._escapeHtml(i.target||"--"),o=i.current_phase||i.phase||"understand",n=i.completed_phases||[];this.shadowRoot.innerHTML=`
9481
9493
  <style>${t}</style>
9482
9494
  <div class="migration-container">
9483
9495
  <div class="migration-header">
9484
9496
  ${e}
9485
9497
  <span class="migration-title">Migration Dashboard</span>
9486
- <span class="migration-id">${i}</span>
9498
+ <span class="migration-id">${a}</span>
9487
9499
  </div>
9488
9500
 
9489
9501
  <div class="meta-row">
@@ -9500,7 +9512,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
9500
9512
  </div>
9501
9513
  <div class="meta-item">
9502
9514
  <span class="meta-label">Phase</span>
9503
- <span>${Kt[o]||this._escapeHtml(o)}</span>
9515
+ <span>${Vt[o]||this._escapeHtml(o)}</span>
9504
9516
  </div>
9505
9517
  </div>
9506
9518
 
@@ -9510,12 +9522,12 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
9510
9522
  </div>
9511
9523
 
9512
9524
  <div class="stats-grid">
9513
- ${this._renderFeatureStats(a.features)}
9514
- ${this._renderStepProgress(a.steps)}
9515
- ${this._renderSeamSummary(a.seams)}
9525
+ ${this._renderFeatureStats(i.features)}
9526
+ ${this._renderStepProgress(i.steps)}
9527
+ ${this._renderSeamSummary(i.seams)}
9516
9528
  </div>
9517
9529
 
9518
- ${this._renderCheckpoint(a.last_checkpoint||a.checkpoint)}
9530
+ ${this._renderCheckpoint(i.last_checkpoint||i.checkpoint)}
9519
9531
  </div>
9520
9532
  `;return}this.shadowRoot.innerHTML=`
9521
9533
  <style>${t}</style>
@@ -9527,7 +9539,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
9527
9539
  <div class="section-label">Migrations</div>
9528
9540
  ${this._renderMigrationList()}
9529
9541
  </div>
9530
- `}};customElements.get("loki-migration-dashboard")||customElements.define("loki-migration-dashboard",rt);var fe=[["claude-opus","claude"],["claude-sonnet","claude"],["claude-haiku","claude"],["opus","claude"],["sonnet","claude"],["haiku","claude"],["claude","claude"],["gpt-4","codex"],["gpt-5","codex"],["gpt","codex"],["codex","codex"],["o1","codex"],["o3","codex"],["cline","cline"],["aider","aider"]];function ke(d){if(d==null)return null;switch(d%4){case 0:return{tier:"planning",model:"opus",provider:"claude"};case 1:return{tier:"development",model:"sonnet",provider:"claude"};case 2:return{tier:"development",model:"sonnet",provider:"claude"};case 3:return{tier:"fast",model:"haiku",provider:"claude"};default:return{tier:"development",model:"sonnet",provider:"claude"}}}function xe(d,t){if(t!=null){let a=ke(t);if(a)return a.provider}let e=(d||"").toLowerCase();for(let[a,i]of fe)if(e.includes(a))return i;return"unknown"}var ot=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._api=null,this._pollInterval=null,this._activeTab="heatmap",this._activity=[],this._tools=[],this._cost={},this._context={},this._trends=[],this._toolTimeRange="7d",this._connected=!1,this._loading=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){e!==a&&t==="api-url"&&this._api&&(this._api.baseUrl=a,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=new AbortController,a=setTimeout(()=>e.abort(),1e4);try{let i=await fetch(`${t}/api/activity?limit=1000`,{signal:e.signal});if(clearTimeout(a),!i.ok)throw new Error(`Activity API ${i.status}`);return i.json()}catch(i){throw clearTimeout(a),i}}async _loadData(){if(!(!this.isConnected||this._loading)){this._loading=!0;try{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()}finally{this._loading=!1}}}_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 c of e){let p=c.timestamp||c.ts||c.created_at;if(!p)continue;let u=new Date(p);if(isNaN(u.getTime()))continue;let b=this._localDateKey(u);t[b]=(t[b]||0)+1}let a=new Date;a.setHours(0,0,0,0);let i=a.getDay(),s=new Date(a),r=new Date(a);r.setDate(r.getDate()-(52*7+i));let o=[],n=new Date(r),l=0;for(;n<=s;){let c=this._localDateKey(n),p=t[c]||0;p>l&&(l=p),o.push({date:c,count:p,day:n.getDay()}),n.setDate(n.getDate()+1)}return{cells:o,maxCount:l}}_getHeatmapLevel(t,e){if(t===0||e===0)return 0;let a=t/e;return a<=.25?1:a<=.5?2:a<=.75?3:4}_renderHeatmap(){let{cells:t,maxCount:e}=this._computeHeatmap(),a=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],i=["","Mon","","Wed","","Fri",""],s=[],r=-1,o=-1;for(let p=0;p<t.length;p++){t[p].day===0&&o++;let u=new Date(t[p].date).getMonth();u!==r&&(s.push({month:a[u],col:Math.max(o,1)}),r=u)}let n=s.map(p=>`<span class="heatmap-month" style="grid-column: ${p.col}">${p.month}</span>`).join(""),l=t.map(p=>`<div class="heatmap-cell level-${this._getHeatmapLevel(p.count,e)}" title="${p.date}: ${p.count} activities"></div>`).join(""),c=i.map(p=>`<span class="heatmap-day-label">${p}</span>`).join("");return`
9542
+ `}};customElements.get("loki-migration-dashboard")||customElements.define("loki-migration-dashboard",rt);var ke=[["claude-opus","claude"],["claude-sonnet","claude"],["claude-haiku","claude"],["opus","claude"],["sonnet","claude"],["haiku","claude"],["claude","claude"],["gpt-4","codex"],["gpt-5","codex"],["gpt","codex"],["codex","codex"],["o1","codex"],["o3","codex"],["cline","cline"],["aider","aider"]];function xe(d){if(d==null)return null;switch(d%4){case 0:return{tier:"planning",model:"opus",provider:"claude"};case 1:return{tier:"development",model:"sonnet",provider:"claude"};case 2:return{tier:"development",model:"sonnet",provider:"claude"};case 3:return{tier:"fast",model:"haiku",provider:"claude"};default:return{tier:"development",model:"sonnet",provider:"claude"}}}function _e(d,t){if(t!=null){let i=xe(t);if(i)return i.provider}let e=(d||"").toLowerCase();for(let[i,a]of ke)if(e.includes(i))return a;return"unknown"}var ot=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._api=null,this._pollInterval=null,this._activeTab="heatmap",this._activity=[],this._tools=[],this._cost={},this._context={},this._trends=[],this._toolTimeRange="7d",this._connected=!1,this._loading=!1}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=new AbortController,i=setTimeout(()=>e.abort(),1e4);try{let a=await fetch(`${t}/api/activity?limit=1000`,{signal:e.signal});if(clearTimeout(i),!a.ok)throw new Error(`Activity API ${a.status}`);return a.json()}catch(a){throw clearTimeout(i),a}}async _loadData(){if(!(!this.isConnected||this._loading)){this._loading=!0;try{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()}finally{this._loading=!1}}}_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 c of e){let p=c.timestamp||c.ts||c.created_at;if(!p)continue;let u=new Date(p);if(isNaN(u.getTime()))continue;let b=this._localDateKey(u);t[b]=(t[b]||0)+1}let i=new Date;i.setHours(0,0,0,0);let a=i.getDay(),s=new Date(i),r=new Date(i);r.setDate(r.getDate()-(52*7+a));let o=[],n=new Date(r),l=0;for(;n<=s;){let c=this._localDateKey(n),p=t[c]||0;p>l&&(l=p),o.push({date:c,count:p,day:n.getDay()}),n.setDate(n.getDate()+1)}return{cells:o,maxCount:l}}_getHeatmapLevel(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=-1;for(let p=0;p<t.length;p++){t[p].day===0&&o++;let u=new Date(t[p].date).getMonth();u!==r&&(s.push({month:i[u],col:Math.max(o,1)}),r=u)}let n=s.map(p=>`<span class="heatmap-month" style="grid-column: ${p.col}">${p.month}</span>`).join(""),l=t.map(p=>`<div class="heatmap-cell level-${this._getHeatmapLevel(p.count,e)}" title="${p.date}: ${p.count} activities"></div>`).join(""),c=a.map(p=>`<span class="heatmap-day-label">${p}</span>`).join("");return`
9531
9543
  <div class="heatmap-container">
9532
9544
  <div class="heatmap-months">${n}</div>
9533
9545
  <div class="heatmap-body">
@@ -9544,15 +9556,15 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
9544
9556
  <span class="heatmap-legend-label">More</span>
9545
9557
  </div>
9546
9558
  </div>
9547
- `}_computeToolUsage(){let t=Array.isArray(this._tools)?this._tools:[],e={};for(let a of t){let i=a.tool||a.name||a.tool_name||a.data&&a.data.tool_name||"unknown",s=a.count??a.calls??a.frequency??(a.data&&a.data.count)??1;e[i]=(e[i]||0)+s}return Object.entries(e).sort((a,i)=>i[1]-a[1]).slice(0,15)}_renderToolUsage(){let t=this._computeToolUsage(),e=t.length>0?t[0][1]:0;return t.length===0?'<div class="empty-state">No tool usage data available</div>':'<div class="tool-bars">'+t.map(([i,s])=>{let r=e>0?s/e*100:0;return`
9559
+ `}_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;return t.length===0?'<div class="empty-state">No tool usage data available</div>':'<div class="tool-bars">'+t.map(([a,s])=>{let r=e>0?s/e*100:0;return`
9548
9560
  <div class="tool-row">
9549
- <span class="tool-name" title="${this._esc(i)}">${this._esc(i)}</span>
9561
+ <span class="tool-name" title="${this._esc(a)}">${this._esc(a)}</span>
9550
9562
  <div class="tool-bar-track">
9551
9563
  <div class="tool-bar-fill" style="width: ${r.toFixed(1)}%"></div>
9552
9564
  </div>
9553
9565
  <span class="tool-count">${s}</span>
9554
9566
  </div>
9555
- `}).join("")+"</div>"}_computeVelocity(){let t=this._context||{},e=t.per_iteration||t.iterations||[],a=Array.isArray(e)&&e.length>0?e.length:t.totals&&t.totals.iterations_tracked||t.total_iterations||0,i=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&&(i=Math.max(o.length-1,1)/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 c=l.timestamp||l.started_at||l.ts;if(!c)continue;let u=new Date(c).toISOString().slice(0,13);o[u]=(o[u]||0)+1}let n=Object.keys(o).sort().slice(-24);for(let l of n)s.push(o[l])}return{iterPerHour:i,totalIterations:a,hourlyBuckets:s}}_renderVelocity(){let{iterPerHour:t,totalIterations:e,hourlyBuckets:a}=this._computeVelocity(),i=Math.max(1,...a),s=a.length>0?a.map(o=>{let n=o/i*100;return`<div class="spark-bar" style="height: ${Math.max(2,n)}%" title="${o}"></div>`}).join(""):'<div class="empty-state" style="padding: 12px">No trend data</div>';return`
9567
+ `}).join("")+"</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=Math.max(o.length-1,1)/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 c=l.timestamp||l.started_at||l.ts;if(!c)continue;let u=new Date(c).toISOString().slice(0,13);o[u]=(o[u]||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(o=>{let n=o/a*100;return`<div class="spark-bar" style="height: ${Math.max(2,n)}%" title="${o}"></div>`}).join(""):'<div class="empty-state" style="padding: 12px">No trend data</div>';return`
9556
9568
  ${`
9557
9569
  <div class="tool-filter">
9558
9570
  <select class="tool-time-select" id="tool-time-range">
@@ -9577,9 +9589,9 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
9577
9589
  <div class="sparkline-label">Activity Trend (hourly)</div>
9578
9590
  <div class="sparkline">${s}</div>
9579
9591
  </div>
9580
- `}_computeProviders(){let t=this._cost.by_model||{},e={};for(let[r,o]of Object.entries(t)){let n=xe(r);e[n]||(e[n]={cost:0,tokens:0,iterations:0,models:[]});let l=o.cost_usd||0,c=(o.input_tokens||0)+(o.output_tokens||0);e[n].cost+=l,e[n].tokens+=c,e[n].models.push(r)}let i=(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&&i>0){let o=r.cost/s;r.iterations=Math.round(o*i)}return e}_renderProviders(){let t=this._computeProviders(),e={claude:{label:"Claude",color:"var(--loki-accent)"},codex:{label:"Codex",color:"var(--loki-success)"},cline:{label:"Cline",color:"var(--loki-info)"},aider:{label:"Aider",color:"var(--loki-blue)"},unknown:{label:"Other",color:"var(--loki-text-muted)"}},a=Object.entries(t);return a.length===0?'<div class="empty-state">No provider data available. Start a session to see cross-provider comparison.</div>':`
9592
+ `}_computeProviders(){let t=this._cost.by_model||{},e={};for(let[r,o]of Object.entries(t)){let n=_e(r);e[n]||(e[n]={cost:0,tokens:0,iterations:0,models:[]});let l=o.cost_usd||0,c=(o.input_tokens||0)+(o.output_tokens||0);e[n].cost+=l,e[n].tokens+=c,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)"},cline:{label:"Cline",color:"var(--loki-info)"},aider:{label:"Aider",color:"var(--loki-blue)"},unknown:{label:"Other",color:"var(--loki-text-muted)"}},i=Object.entries(t);return i.length===0?'<div class="empty-state">No provider data available. Start a session to see cross-provider comparison.</div>':`
9581
9593
  <div class="provider-grid">
9582
- ${a.map(([i,s])=>{let r=e[i]||e.unknown,o=s.iterations>0?(s.cost/s.iterations).toFixed(4):"--",n=s.iterations>0?Math.round(s.tokens/s.iterations).toLocaleString():"--";return`
9594
+ ${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`
9583
9595
  <div class="provider-card">
9584
9596
  <div class="provider-accent" style="background: ${r.color}"></div>
9585
9597
  <div class="provider-body">
@@ -9964,9 +9976,9 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
9964
9976
  ${this._connected?"":'<div class="offline-notice">Connecting to analytics API...</div>'}
9965
9977
 
9966
9978
  <div class="tab-bar">
9967
- ${t.map(i=>`
9968
- <button class="tab-btn ${this._activeTab===i.id?"active":""}" data-tab="${i.id}" aria-label="${i.label}">
9969
- ${i.icon}<span>${i.label}</span>
9979
+ ${t.map(a=>`
9980
+ <button class="tab-btn ${this._activeTab===a.id?"active":""}" data-tab="${a.id}" aria-label="${a.label}">
9981
+ ${a.icon}<span>${a.label}</span>
9970
9982
  </button>
9971
9983
  `).join("")}
9972
9984
  </div>
@@ -9975,7 +9987,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
9975
9987
  ${e}
9976
9988
  </div>
9977
9989
  </div>
9978
- `,this.shadowRoot.querySelectorAll("[data-tab]").forEach(i=>{i.addEventListener("click",s=>this._handleTabClick(s))});let a=this.shadowRoot.getElementById("tool-time-range");a&&a.addEventListener("change",i=>this._handleTimeRangeChange(i))}};customElements.get("loki-analytics")||customElements.define("loki-analytics",ot);var Vt={pass:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"PASS"},fail:{color:"var(--loki-red, #ef4444)",bg:"var(--loki-red-muted, rgba(239, 68, 68, 0.15))",label:"FAIL"},pending:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"PENDING"}};function _e(d){if(!d)return"Never";try{return new Date(d).toLocaleString([],{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return"Unknown"}}function ye(d){if(!d||d.length===0)return{pass:0,fail:0,pending:0,total:0};let t={pass:0,fail:0,pending:0,total:d.length};for(let e of d){let a=(e.status||"pending").toLowerCase();a==="pass"?t.pass++:a==="fail"?t.fail++:t.pending++}return t}var nt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._gates=[],this._pollInterval=null,this._lastDataHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,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(),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)}async _loadData(){try{this._loading=!0;let t=await this._api._get("/api/council/gate"),e=t?.gates||t||[],a=JSON.stringify(e);if(a===this._lastDataHash)return;this._lastDataHash=a,this._gates=Array.isArray(e)?e:[],this._error=null}catch(t){this._error||(this._error=`Failed to load quality gates: ${t.message}`)}finally{this._loading=!1}this.render()}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
9990
+ `,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",ot);var Yt={pass:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"PASS"},fail:{color:"var(--loki-red, #ef4444)",bg:"var(--loki-red-muted, rgba(239, 68, 68, 0.15))",label:"FAIL"},pending:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"PENDING"}};function ye(d){if(!d)return"Never";try{return new Date(d).toLocaleString([],{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return"Unknown"}}function we(d){if(!d||d.length===0)return{pass:0,fail:0,pending:0,total:0};let t={pass:0,fail:0,pending:0,total:d.length};for(let e of d){let i=(e.status||"pending").toLowerCase();i==="pass"?t.pass++:i==="fail"?t.fail++:t.pending++}return t}var nt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._gates=[],this._pollInterval=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(),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)}async _loadData(){try{this._loading=!0;let t=await this._api._get("/api/council/gate"),e=t?.gates||t||[],i=JSON.stringify(e);if(i===this._lastDataHash)return;this._lastDataHash=i,this._gates=Array.isArray(e)?e:[],this._error=null}catch(t){this._error||(this._error=`Failed to load quality gates: ${t.message}`)}finally{this._loading=!1}this.render()}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
9979
9991
  :host {
9980
9992
  display: block;
9981
9993
  }
@@ -10106,28 +10118,28 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
10106
10118
  color: var(--loki-text-muted, #939084);
10107
10119
  font-size: 13px;
10108
10120
  }
10109
- `}render(){let t=this.shadowRoot;if(!t)return;let e=this._gates,a=ye(e),i;this._loading&&e.length===0?i='<div class="loading">Loading quality gates...</div>':e.length===0?i='<div class="empty-state"><strong>No gate results yet.</strong> Quality gates run automatically between RARV iterations during an active session. Start a session with <code>loki start ./prd.md</code> to see results here. You can also run gates manually with <code>loki review</code>.</div>':i=`<div class="gates-grid">${e.map(o=>{let n=(o.status||"pending").toLowerCase(),l=Vt[n]||Vt.pending;return`
10121
+ `}render(){let t=this.shadowRoot;if(!t)return;let e=this._gates,i=we(e),a;this._loading&&e.length===0?a='<div class="loading">Loading quality gates...</div>':e.length===0?a='<div class="empty-state"><strong>No gate results yet.</strong> Quality gates run automatically between RARV iterations during an active session. Start a session with <code>loki start ./prd.md</code> to see results here. You can also run gates manually with <code>loki review</code>.</div>':a=`<div class="gates-grid">${e.map(o=>{let n=(o.status||"pending").toLowerCase(),l=Yt[n]||Yt.pending;return`
10110
10122
  <div class="gate-card status-${n}">
10111
10123
  <div class="gate-header">
10112
10124
  <span class="gate-name">${this._escapeHtml(o.name||"Unnamed Gate")}</span>
10113
10125
  <span class="gate-badge" style="background: ${l.bg}; color: ${l.color};">${l.label}</span>
10114
10126
  </div>
10115
10127
  ${o.description?`<div class="gate-description">${this._escapeHtml(o.description)}</div>`:""}
10116
- <div class="gate-meta">Last checked: ${_e(o.last_checked||o.lastChecked)}</div>
10128
+ <div class="gate-meta">Last checked: ${ye(o.last_checked||o.lastChecked)}</div>
10117
10129
  </div>
10118
- `}).join("")}</div>`;let s=a.total>0?`
10130
+ `}).join("")}</div>`;let s=i.total>0?`
10119
10131
  <div class="summary">
10120
10132
  <span class="summary-item">
10121
10133
  <span class="summary-dot" style="background: var(--loki-green, #22c55e)"></span>
10122
- ${a.pass} Pass
10134
+ ${i.pass} Pass
10123
10135
  </span>
10124
10136
  <span class="summary-item">
10125
10137
  <span class="summary-dot" style="background: var(--loki-red, #ef4444)"></span>
10126
- ${a.fail} Fail
10138
+ ${i.fail} Fail
10127
10139
  </span>
10128
10140
  <span class="summary-item">
10129
10141
  <span class="summary-dot" style="background: var(--loki-yellow, #eab308)"></span>
10130
- ${a.pending} Pending
10142
+ ${i.pending} Pending
10131
10143
  </span>
10132
10144
  </div>
10133
10145
  `:"";t.innerHTML=`
@@ -10137,10 +10149,10 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
10137
10149
  <h2 class="title">Quality Gates</h2>
10138
10150
  ${s}
10139
10151
  </div>
10140
- ${i}
10152
+ ${a}
10141
10153
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
10142
10154
  </div>
10143
- `}};customElements.get("loki-quality-gates")||customElements.define("loki-quality-gates",nt);var F={reason:{color:"var(--loki-blue, #3b82f6)",label:"Reason",description:"Analyzing requirements and planning approach"},act:{color:"var(--loki-green, #22c55e)",label:"Act",description:"Implementing changes and executing tasks"},reflect:{color:"var(--loki-purple, #a78bfa)",label:"Reflect",description:"Reviewing results and evaluating quality"},verify:{color:"var(--loki-yellow, #eab308)",label:"Verify",description:"Running tests and validating correctness"}},Dt=["reason","act","reflect","verify"];function It(d){if(d==null||d<0)return"--";if(d<1e3)return`${d}ms`;let t=Math.floor(d/1e3);if(t<60)return`${t}s`;let e=Math.floor(t/60),a=t%60;if(e<60)return`${e}m ${a}s`;let i=Math.floor(e/60),s=e%60;return`${i}h ${s}m`}function we(d){if(!d||d.length===0)return[];let t=d.reduce((e,a)=>e+(a.duration_ms||0),0);return t===0?d.map(e=>({phase:e.phase,pct:100/d.length,duration:0})):d.map(e=>({phase:e.phase,pct:(e.duration_ms||0)/t*100,duration:e.duration_ms||0}))}function $e(d){return d==null?"--":d>=1e6?(d/1e6).toFixed(1)+"M":d>=1e3?(d/1e3).toFixed(1)+"K":String(d)}var lt=class extends h{static get observedAttributes(){return["run-id","api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._timeline=null,this._pollInterval=null,this._selectedPhase=null,this._cycleHistory=[]}get runId(){let t=this.getAttribute("run-id");return t?parseInt(t,10):null}set runId(t){t!=null?this.setAttribute("run-id",String(t)):this.removeAttribute("run-id")}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadData()),t==="run-id"&&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(){let t=this.runId;if(t==null){this._timeline=null,this.render();return}try{this._loading=!0;let e=await this._api._get(`/api/v2/runs/${t}/timeline`);this._timeline=e,this._cycleHistory=e.history||[],this._error=null}catch(e){e.message&&(e.message.includes("404")||e.message.includes("Not Found"))?(this._timeline=null,this._error=null):this._error=`Failed to load timeline: ${e.message}`}finally{this._loading=!1}this.render()}_selectPhase(t){this._selectedPhase=this._selectedPhase===t?null:t,this.render()}_bindEvents(){let t=this.shadowRoot;t.querySelectorAll(".phase-segment-interactive").forEach(e=>{e.addEventListener("click",()=>{this._selectPhase(e.dataset.phase)})}),t.querySelectorAll(".legend-item-interactive").forEach(e=>{e.addEventListener("click",()=>{this._selectPhase(e.dataset.phase)})}),t.querySelectorAll(".close-detail").forEach(e=>{e.addEventListener("click",a=>{a.stopPropagation(),this._selectedPhase=null,this.render()})})}_getStyles(){return`
10155
+ `}};customElements.get("loki-quality-gates")||customElements.define("loki-quality-gates",nt);var F={reason:{color:"var(--loki-blue, #3b82f6)",label:"Reason",description:"Analyzing requirements and planning approach"},act:{color:"var(--loki-green, #22c55e)",label:"Act",description:"Implementing changes and executing tasks"},reflect:{color:"var(--loki-purple, #a78bfa)",label:"Reflect",description:"Reviewing results and evaluating quality"},verify:{color:"var(--loki-yellow, #eab308)",label:"Verify",description:"Running tests and validating correctness"}},zt=["reason","act","reflect","verify"];function Lt(d){if(d==null||d<0)return"--";if(d<1e3)return`${d}ms`;let t=Math.floor(d/1e3);if(t<60)return`${t}s`;let e=Math.floor(t/60),i=t%60;if(e<60)return`${e}m ${i}s`;let a=Math.floor(e/60),s=e%60;return`${a}h ${s}m`}function $e(d){if(!d||d.length===0)return[];let t=d.reduce((e,i)=>e+(i.duration_ms||0),0);return t===0?d.map(e=>({phase:e.phase,pct:100/d.length,duration:0})):d.map(e=>({phase:e.phase,pct:(e.duration_ms||0)/t*100,duration:e.duration_ms||0}))}function Ee(d){return d==null?"--":d>=1e6?(d/1e6).toFixed(1)+"M":d>=1e3?(d/1e3).toFixed(1)+"K":String(d)}var lt=class extends h{static get observedAttributes(){return["run-id","api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._timeline=null,this._pollInterval=null,this._selectedPhase=null,this._cycleHistory=[]}get runId(){let t=this.getAttribute("run-id");return t?parseInt(t,10):null}set runId(t){t!=null?this.setAttribute("run-id",String(t)):this.removeAttribute("run-id")}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==="run-id"&&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(){let t=this.runId;if(t==null){this._timeline=null,this.render();return}try{this._loading=!0;let e=await this._api._get(`/api/v2/runs/${t}/timeline`);this._timeline=e,this._cycleHistory=e.history||[],this._error=null}catch(e){e.message&&(e.message.includes("404")||e.message.includes("Not Found"))?(this._timeline=null,this._error=null):this._error=`Failed to load timeline: ${e.message}`}finally{this._loading=!1}this.render()}_selectPhase(t){this._selectedPhase=this._selectedPhase===t?null:t,this.render()}_bindEvents(){let t=this.shadowRoot;t.querySelectorAll(".phase-segment-interactive").forEach(e=>{e.addEventListener("click",()=>{this._selectPhase(e.dataset.phase)})}),t.querySelectorAll(".legend-item-interactive").forEach(e=>{e.addEventListener("click",()=>{this._selectPhase(e.dataset.phase)})}),t.querySelectorAll(".close-detail").forEach(e=>{e.addEventListener("click",i=>{i.stopPropagation(),this._selectedPhase=null,this.render()})})}_getStyles(){return`
10144
10156
  :host {
10145
10157
  display: block;
10146
10158
  }
@@ -10425,14 +10437,14 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
10425
10437
  color: var(--loki-text-muted, #939084);
10426
10438
  font-size: 13px;
10427
10439
  }
10428
- `}_renderPlaceholderTimeline(){let t=Dt.map(a=>{let i=F[a];return`<div class="phase-segment-interactive"
10429
- data-phase="${a}"
10430
- style="width: 25%; background: ${i.color}; opacity: 0.3;"
10431
- title="${i.label}: awaiting data">
10432
- ${i.label}
10433
- </div>`}).join(""),e=Dt.map(a=>{let i=F[a];return`<div class="legend-item-interactive" data-phase="${a}">
10434
- <span class="legend-dot" style="background: ${i.color}; opacity: 0.4;"></span>
10435
- <span class="legend-label">${i.label}</span>
10440
+ `}_renderPlaceholderTimeline(){let t=zt.map(i=>{let a=F[i];return`<div class="phase-segment-interactive"
10441
+ data-phase="${i}"
10442
+ style="width: 25%; background: ${a.color}; opacity: 0.3;"
10443
+ title="${a.label}: awaiting data">
10444
+ ${a.label}
10445
+ </div>`}).join(""),e=zt.map(i=>{let a=F[i];return`<div class="legend-item-interactive" data-phase="${i}">
10446
+ <span class="legend-dot" style="background: ${a.color}; opacity: 0.4;"></span>
10447
+ <span class="legend-label">${a.label}</span>
10436
10448
  <span class="legend-duration">--</span>
10437
10449
  </div>`}).join("");return`
10438
10450
  <div class="empty-state" style="padding: 0; text-align: left;">
@@ -10442,7 +10454,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
10442
10454
  RARV phases will populate as the session progresses
10443
10455
  </div>
10444
10456
  </div>
10445
- `}_renderPhaseDetail(t){let e=F[t];if(!e)return"";let i=(this._timeline?.phases||[]).find(s=>s.phase===t);return`
10457
+ `}_renderPhaseDetail(t){let e=F[t];if(!e)return"";let a=(this._timeline?.phases||[]).find(s=>s.phase===t);return`
10446
10458
  <div class="phase-detail">
10447
10459
  <div class="detail-header">
10448
10460
  <div class="detail-title">
@@ -10455,38 +10467,38 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
10455
10467
  <div class="detail-metrics">
10456
10468
  <div class="detail-metric">
10457
10469
  <span class="detail-metric-label">Time Spent</span>
10458
- <span class="detail-metric-value">${It(i?.duration_ms)}</span>
10470
+ <span class="detail-metric-value">${Lt(a?.duration_ms)}</span>
10459
10471
  </div>
10460
10472
  <div class="detail-metric">
10461
10473
  <span class="detail-metric-label">Tokens Used</span>
10462
- <span class="detail-metric-value">${$e(i?.tokens_used)}</span>
10474
+ <span class="detail-metric-value">${Ee(a?.tokens_used)}</span>
10463
10475
  </div>
10464
10476
  <div class="detail-metric">
10465
10477
  <span class="detail-metric-label">Quality</span>
10466
- <span class="detail-metric-value">${i?.quality_score!=null?i.quality_score.toFixed(1):"--"}</span>
10478
+ <span class="detail-metric-value">${a?.quality_score!=null?a.quality_score.toFixed(1):"--"}</span>
10467
10479
  </div>
10468
10480
  <div class="detail-metric">
10469
10481
  <span class="detail-metric-label">Actions</span>
10470
- <span class="detail-metric-value">${i?.action_count!=null?i.action_count:"--"}</span>
10482
+ <span class="detail-metric-value">${a?.action_count!=null?a.action_count:"--"}</span>
10471
10483
  </div>
10472
10484
  </div>
10473
10485
  </div>
10474
- `}_renderCycleHistory(){if(this._cycleHistory.length===0)return"";let e=this._cycleHistory.slice(-8).map((a,i)=>`<div class="history-cycle">${Dt.map(r=>{let o=a.phases?.find(p=>p.phase===r),n=F[r],l=o?.status||"pending",c=l==="complete"?"0.8":l==="active"?"1":"0.3";return`<div class="history-dot" style="background: ${n.color}; opacity: ${c};"
10475
- title="Cycle ${i+1}: ${n.label} - ${It(o?.duration_ms)}"></div>`}).join("")}</div>`).join('<div class="history-separator"></div>');return`
10486
+ `}_renderCycleHistory(){if(this._cycleHistory.length===0)return"";let e=this._cycleHistory.slice(-8).map((i,a)=>`<div class="history-cycle">${zt.map(r=>{let o=i.phases?.find(p=>p.phase===r),n=F[r],l=o?.status||"pending",c=l==="complete"?"0.8":l==="active"?"1":"0.3";return`<div class="history-dot" style="background: ${n.color}; opacity: ${c};"
10487
+ title="Cycle ${a+1}: ${n.label} - ${Lt(o?.duration_ms)}"></div>`}).join("")}</div>`).join('<div class="history-separator"></div>');return`
10476
10488
  <div class="cycle-history">
10477
10489
  <div class="history-label">Past Cycles (${this._cycleHistory.length} total)</div>
10478
10490
  <div class="history-cycles">${e}</div>
10479
10491
  </div>
10480
- `}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}render(){let t=this.shadowRoot;if(!t)return;let e=this.runId,a=this._timeline,i=a?.phases||[],s=a?.current_phase||null,r=we(i),o;if(this._loading&&!a)o='<div class="loading">Loading timeline...</div>';else if(e==null)o=this._renderPlaceholderTimeline();else if(i.length===0)o=this._renderPlaceholderTimeline();else{let n=r.map(u=>{let b=F[u.phase]||{color:"var(--loki-text-muted)",label:u.phase},m=s===u.phase,f=this._selectedPhase===u.phase;return`<div class="phase-segment-interactive ${m?"current":""} ${f?"selected":""}"
10492
+ `}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}render(){let t=this.shadowRoot;if(!t)return;let e=this.runId,i=this._timeline,a=i?.phases||[],s=i?.current_phase||null,r=$e(a),o;if(this._loading&&!i)o='<div class="loading">Loading timeline...</div>';else if(e==null)o=this._renderPlaceholderTimeline();else if(a.length===0)o=this._renderPlaceholderTimeline();else{let n=r.map(u=>{let b=F[u.phase]||{color:"var(--loki-text-muted)",label:u.phase},v=s===u.phase,f=this._selectedPhase===u.phase;return`<div class="phase-segment-interactive ${v?"current":""} ${f?"selected":""}"
10481
10493
  data-phase="${u.phase}"
10482
10494
  style="width: ${Math.max(u.pct,2)}%; background: ${b.color};"
10483
- title="${b.label}: ${It(u.duration)}">
10495
+ title="${b.label}: ${Lt(u.duration)}">
10484
10496
  ${u.pct>12?b.label:""}
10485
- </div>`}).join(""),l=i.map(u=>{let b=F[u.phase]||{color:"var(--loki-text-muted)",label:u.phase},m=s===u.phase;return`<div class="legend-item-interactive ${this._selectedPhase===u.phase?"selected":""}" data-phase="${u.phase}">
10497
+ </div>`}).join(""),l=a.map(u=>{let b=F[u.phase]||{color:"var(--loki-text-muted)",label:u.phase},v=s===u.phase;return`<div class="legend-item-interactive ${this._selectedPhase===u.phase?"selected":""}" data-phase="${u.phase}">
10486
10498
  <span class="legend-dot" style="background: ${b.color}"></span>
10487
10499
  <span class="legend-label">${b.label}</span>
10488
- <span class="legend-duration">${It(u.duration_ms)}</span>
10489
- ${m?'<span class="phase-current-tag">ACTIVE</span>':""}
10500
+ <span class="legend-duration">${Lt(u.duration_ms)}</span>
10501
+ ${v?'<span class="phase-current-tag">ACTIVE</span>':""}
10490
10502
  </div>`}).join(""),c=this._selectedPhase?this._renderPhaseDetail(this._selectedPhase):"",p=this._renderCycleHistory();o=`
10491
10503
  <div class="timeline-bar">${n}</div>
10492
10504
  <div class="legend">${l}</div>
@@ -10502,7 +10514,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
10502
10514
  ${o}
10503
10515
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
10504
10516
  </div>
10505
- `,this._bindEvents()}};customElements.get("loki-rarv-timeline")||customElements.define("loki-rarv-timeline",lt);var Yt={running:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"Running"},completed:{color:"var(--loki-blue, #3b82f6)",bg:"var(--loki-blue-muted, rgba(59, 130, 246, 0.15))",label:"Completed"},failed:{color:"var(--loki-red, #ef4444)",bg:"var(--loki-red-muted, rgba(239, 68, 68, 0.15))",label:"Failed"},cancelled:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"Cancelled"},pending:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Pending"},queued:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Queued"}};function Ee(d,t,e){let a=d;if(a==null&&t){let l=new Date(t).getTime();a=(e?new Date(e).getTime():Date.now())-l}if(a==null||a<0)return"--";if(a<1e3)return`${a}ms`;let i=Math.floor(a/1e3);if(i<60)return`${i}s`;let s=Math.floor(i/60),r=i%60;if(s<60)return`${s}m ${r}s`;let o=Math.floor(s/60),n=s%60;return`${o}h ${n}m`}function Ce(d){if(!d)return"--";try{return new Date(d).toLocaleString([],{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return String(d)}}var dt=class extends h{static get observedAttributes(){return["api-url","project-id","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._runs=[],this._pollInterval=null,this._lastDataHash=null}get projectId(){let t=this.getAttribute("project-id");return t?parseInt(t,10):null}set projectId(t){t!=null?this.setAttribute("project-id",String(t)):this.removeAttribute("project-id")}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadData()),t==="project-id"&&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=this.projectId,e=t!=null?`?project_id=${t}`:"",a=await this._api._get(`/api/v2/runs${e}`),i=a?.runs||a||[],s=JSON.stringify(i);if(s===this._lastDataHash)return;this._lastDataHash=s,this._runs=Array.isArray(i)?i:[],this._error=null}catch(t){this._error||(this._error=`Failed to load runs: ${t.message}`)}finally{this._loading=!1}this.render()}async _cancelRun(t){try{await this._api._post(`/api/v2/runs/${t}/cancel`),await this._loadData()}catch(e){this._error=`Cancel failed: ${e.message}`,this.render()}}async _replayRun(t){try{await this._api._post(`/api/v2/runs/${t}/replay`),await this._loadData()}catch(e){this._error=`Replay failed: ${e.message}`,this.render()}}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
10517
+ `,this._bindEvents()}};customElements.get("loki-rarv-timeline")||customElements.define("loki-rarv-timeline",lt);var Wt={running:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"Running"},completed:{color:"var(--loki-blue, #3b82f6)",bg:"var(--loki-blue-muted, rgba(59, 130, 246, 0.15))",label:"Completed"},failed:{color:"var(--loki-red, #ef4444)",bg:"var(--loki-red-muted, rgba(239, 68, 68, 0.15))",label:"Failed"},cancelled:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"Cancelled"},pending:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Pending"},queued:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Queued"}};function Ce(d,t,e){let i=d;if(i==null&&t){let l=new Date(t).getTime();i=(e?new Date(e).getTime():Date.now())-l}if(i==null||i<0)return"--";if(i<1e3)return`${i}ms`;let a=Math.floor(i/1e3);if(a<60)return`${a}s`;let s=Math.floor(a/60),r=a%60;if(s<60)return`${s}m ${r}s`;let o=Math.floor(s/60),n=s%60;return`${o}h ${n}m`}function Se(d){if(!d)return"--";try{return new Date(d).toLocaleString([],{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return String(d)}}var dt=class extends h{static get observedAttributes(){return["api-url","project-id","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._runs=[],this._pollInterval=null,this._lastDataHash=null}get projectId(){let t=this.getAttribute("project-id");return t?parseInt(t,10):null}set projectId(t){t!=null?this.setAttribute("project-id",String(t)):this.removeAttribute("project-id")}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==="project-id"&&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=this.projectId,e=t!=null?`?project_id=${t}`:"",i=await this._api._get(`/api/v2/runs${e}`),a=i?.runs||i||[],s=JSON.stringify(a);if(s===this._lastDataHash)return;this._lastDataHash=s,this._runs=Array.isArray(a)?a:[],this._error=null}catch(t){this._error||(this._error=`Failed to load runs: ${t.message}`)}finally{this._loading=!1}this.render()}async _cancelRun(t){try{await this._api._post(`/api/v2/runs/${t}/cancel`),await this._loadData()}catch(e){this._error=`Cancel failed: ${e.message}`,this.render()}}async _replayRun(t){try{await this._api._post(`/api/v2/runs/${t}/replay`),await this._loadData()}catch(e){this._error=`Replay failed: ${e.message}`,this.render()}}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
10506
10518
  :host {
10507
10519
  display: block;
10508
10520
  }
@@ -10655,13 +10667,13 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
10655
10667
  color: var(--loki-text-muted, #939084);
10656
10668
  margin-bottom: 8px;
10657
10669
  }
10658
- `}render(){let t=this.shadowRoot;if(!t)return;let e=this._runs,a;if(this._loading&&e.length===0)a='<div class="loading">Loading runs...</div>';else if(e.length===0)a='<div class="empty-state">No runs found.</div>';else{let i=e.map(s=>{let r=(s.status||"pending").toLowerCase(),o=Yt[r]||Yt.pending,n=r==="running",l=r==="completed"||r==="failed"||r==="cancelled",c=Ee(s.duration_ms,s.started_at,s.ended_at);return`
10670
+ `}render(){let t=this.shadowRoot;if(!t)return;let e=this._runs,i;if(this._loading&&e.length===0)i='<div class="loading">Loading runs...</div>';else if(e.length===0)i='<div class="empty-state">No runs found.</div>';else{let a=e.map(s=>{let r=(s.status||"pending").toLowerCase(),o=Wt[r]||Wt.pending,n=r==="running",l=r==="completed"||r==="failed"||r==="cancelled",c=Ce(s.duration_ms,s.started_at,s.ended_at);return`
10659
10671
  <tr>
10660
10672
  <td><span class="run-id">#${s.id}</span></td>
10661
10673
  <td>${this._escapeHtml(s.project_name||s.project||(s.project_id?`Project #${s.project_id}`:"--"))}</td>
10662
10674
  <td><span class="status-badge" style="background: ${o.bg}; color: ${o.color};">${o.label}</span></td>
10663
10675
  <td>${this._escapeHtml(s.trigger||s.trigger_type||"--")}</td>
10664
- <td>${Ce(s.started_at)}</td>
10676
+ <td>${Se(s.started_at)}</td>
10665
10677
  <td>${c}</td>
10666
10678
  <td>
10667
10679
  <div class="actions-cell">
@@ -10670,7 +10682,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
10670
10682
  </div>
10671
10683
  </td>
10672
10684
  </tr>
10673
- `}).join("");a=`
10685
+ `}).join("");i=`
10674
10686
  <div class="run-count">${e.length} runs</div>
10675
10687
  <div class="runs-table-wrapper">
10676
10688
  <table>
@@ -10685,7 +10697,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
10685
10697
  <th>Actions</th>
10686
10698
  </tr>
10687
10699
  </thead>
10688
- <tbody>${i}</tbody>
10700
+ <tbody>${a}</tbody>
10689
10701
  </table>
10690
10702
  </div>
10691
10703
  `}t.innerHTML=`
@@ -10695,10 +10707,10 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
10695
10707
  <h2 class="title">Run Manager</h2>
10696
10708
  <button class="btn btn-refresh" id="refresh-btn">Refresh</button>
10697
10709
  </div>
10698
- ${a}
10710
+ ${i}
10699
10711
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
10700
10712
  </div>
10701
- `,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.getElementById("refresh-btn");e&&e.addEventListener("click",()=>this._loadData()),t.querySelectorAll('[data-action="cancel"]').forEach(a=>{a.addEventListener("click",()=>this._cancelRun(a.dataset.runId))}),t.querySelectorAll('[data-action="replay"]').forEach(a=>{a.addEventListener("click",()=>this._replayRun(a.dataset.runId))})}};customElements.get("loki-run-manager")||customElements.define("loki-run-manager",dt);function Se(d){if(!d)return"--";try{return new Date(d).toLocaleString([],{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit"})}catch{return String(d)}}function Ae(d){let t=new URLSearchParams;for(let[a,i]of Object.entries(d))i!=null&&i!==""&&t.set(a,String(i));let e=t.toString();return e?`?${e}`:""}var ct=class extends h{static get observedAttributes(){return["api-url","limit","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._entries=[],this._verifyResult=null,this._verifying=!1,this._filters={action:"",resource:"",dateFrom:"",dateTo:""}}get limit(){let t=this.getAttribute("limit");return t?parseInt(t,10):50}set limit(t){this.setAttribute("limit",String(t))}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData()}disconnectedCallback(){super.disconnectedCallback()}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadData()),t==="limit"&&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._loading=!0,this.render();let t={limit:this.limit,action:this._filters.action,resource:this._filters.resource,date_from:this._filters.dateFrom,date_to:this._filters.dateTo},e=Ae(t),a=await this._api._get(`/api/v2/audit${e}`);this._entries=a?.entries||a||[],this._error=null}catch(t){this._error=`Failed to load audit log: ${t.message}`}finally{this._loading=!1}this.render()}async _verifyIntegrity(){try{this._verifying=!0,this._verifyResult=null,this.render();let t=await this._api._get("/api/v2/audit/verify");this._verifyResult=t}catch(t){this._verifyResult={valid:!1,error:t.message}}finally{this._verifying=!1}this.render()}_onFilterChange(t,e){this._filters[t]=e,this._loadData()}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
10713
+ `,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.getElementById("refresh-btn");e&&e.addEventListener("click",()=>this._loadData()),t.querySelectorAll('[data-action="cancel"]').forEach(i=>{i.addEventListener("click",()=>this._cancelRun(i.dataset.runId))}),t.querySelectorAll('[data-action="replay"]').forEach(i=>{i.addEventListener("click",()=>this._replayRun(i.dataset.runId))})}};customElements.get("loki-run-manager")||customElements.define("loki-run-manager",dt);function Ae(d){if(!d)return"--";try{return new Date(d).toLocaleString([],{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit"})}catch{return String(d)}}function Te(d){let t=new URLSearchParams;for(let[i,a]of Object.entries(d))a!=null&&a!==""&&t.set(i,String(a));let e=t.toString();return e?`?${e}`:""}var ct=class extends h{static get observedAttributes(){return["api-url","limit","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._entries=[],this._verifyResult=null,this._verifying=!1,this._filters={action:"",resource:"",dateFrom:"",dateTo:""}}get limit(){let t=this.getAttribute("limit");return t?parseInt(t,10):50}set limit(t){this.setAttribute("limit",String(t))}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData()}disconnectedCallback(){super.disconnectedCallback()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="limit"&&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._loading=!0,this.render();let t={limit:this.limit,action:this._filters.action,resource:this._filters.resource,date_from:this._filters.dateFrom,date_to:this._filters.dateTo},e=Te(t),i=await this._api._get(`/api/v2/audit${e}`);this._entries=i?.entries||i||[],this._error=null}catch(t){this._error=`Failed to load audit log: ${t.message}`}finally{this._loading=!1}this.render()}async _verifyIntegrity(){try{this._verifying=!0,this._verifyResult=null,this.render();let t=await this._api._get("/api/v2/audit/verify");this._verifyResult=t}catch(t){this._verifyResult={valid:!1,error:t.message}}finally{this._verifying=!1}this.render()}_onFilterChange(t,e){this._filters[t]=e,this._loadData()}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
10702
10714
  :host {
10703
10715
  display: block;
10704
10716
  }
@@ -10912,19 +10924,19 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
10912
10924
  color: var(--loki-text-muted, #939084);
10913
10925
  margin-bottom: 8px;
10914
10926
  }
10915
- `}_getStatusClass(t){if(!t)return"status-warning";let e=t.toLowerCase();return e==="success"||e==="ok"||e==="pass"?"status-success":e==="failure"||e==="error"||e==="fail"?"status-failure":"status-warning"}render(){let t=this.shadowRoot;if(!t)return;let e=this._entries,a="";if(this._verifyResult){let s=this._verifyResult.valid!==!1;a=`
10927
+ `}_getStatusClass(t){if(!t)return"status-warning";let e=t.toLowerCase();return e==="success"||e==="ok"||e==="pass"?"status-success":e==="failure"||e==="error"||e==="fail"?"status-failure":"status-warning"}render(){let t=this.shadowRoot;if(!t)return;let e=this._entries,i="";if(this._verifyResult){let s=this._verifyResult.valid!==!1;i=`
10916
10928
  <div class="verify-result ${s?"verify-valid":"verify-invalid"}">
10917
10929
  ${s?"[VALID] Audit chain integrity verified.":`[TAMPERED] ${this._escapeHtml(this._verifyResult.error||"Integrity check failed.")}`}
10918
10930
  </div>
10919
- `}let i;if(this._loading&&e.length===0)i='<div class="loading">Loading audit log...</div>';else if(e.length===0)i='<div class="empty-state">No audit entries found matching filters.</div>';else{let s=e.map(r=>`
10931
+ `}let a;if(this._loading&&e.length===0)a='<div class="loading">Loading audit log...</div>';else if(e.length===0)a='<div class="empty-state">No audit entries found matching filters.</div>';else{let s=e.map(r=>`
10920
10932
  <tr>
10921
- <td>${Se(r.timestamp)}</td>
10933
+ <td>${Ae(r.timestamp)}</td>
10922
10934
  <td>${this._escapeHtml(r.action||"--")}</td>
10923
10935
  <td>${this._escapeHtml(r.resource||r.resource_type||"--")}</td>
10924
10936
  <td>${this._escapeHtml(r.user||r.actor||"--")}</td>
10925
10937
  <td><span class="status-badge ${this._getStatusClass(r.status)}">${this._escapeHtml(r.status||"unknown")}</span></td>
10926
10938
  </tr>
10927
- `).join("");i=`
10939
+ `).join("");a=`
10928
10940
  <div class="entry-count">${e.length} entries</div>
10929
10941
  <div class="audit-table-wrapper">
10930
10942
  <table>
@@ -10978,11 +10990,11 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
10978
10990
  </div>
10979
10991
  </div>
10980
10992
 
10981
- ${a}
10982
10993
  ${i}
10994
+ ${a}
10983
10995
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
10984
10996
  </div>
10985
- `,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.getElementById("verify-btn");e&&e.addEventListener("click",()=>this._verifyIntegrity());let a=t.getElementById("refresh-btn");a&&a.addEventListener("click",()=>this._loadData());let i=t.getElementById("filter-action");i&&i.addEventListener("change",n=>this._onFilterChange("action",n.target.value));let s=t.getElementById("filter-resource");s&&s.addEventListener("change",n=>this._onFilterChange("resource",n.target.value));let r=t.getElementById("filter-date-from");r&&r.addEventListener("change",n=>this._onFilterChange("dateFrom",n.target.value));let o=t.getElementById("filter-date-to");o&&o.addEventListener("change",n=>this._onFilterChange("dateTo",n.target.value))}};customElements.get("loki-audit-viewer")||customElements.define("loki-audit-viewer",ct);function Wt(d){if(!d)return"Never";try{return new Date(d).toLocaleString([],{month:"short",day:"numeric",year:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return String(d)}}var pt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._keys=[],this._showCreateForm=!1,this._newToken=null,this._confirmDeleteId=null,this._rotateKeyId=null,this._rotateGracePeriod="24",this._createName="",this._createRole="read",this._createExpiration=""}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData()}disconnectedCallback(){super.disconnectedCallback()}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,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._loading=!0,this.render();let t=await this._api._get("/api/v2/api-keys");this._keys=Array.isArray(t)?t:t?.keys||[],this._error=null}catch(t){this._error=`Failed to load API keys: ${t.message}`}finally{this._loading=!1}this.render()}async _createKey(){if(!this._createName.trim()){this._error="Key name is required.",this.render();return}try{let t={name:this._createName.trim(),role:this._createRole};this._createExpiration&&(t.expiration=this._createExpiration);let e=await this._api._post("/api/v2/api-keys",t);this._newToken=e?.token||e?.key||null,this._showCreateForm=!1,this._createName="",this._createRole="read",this._createExpiration="",this._error=null,await this._loadData()}catch(t){this._error=`Create failed: ${t.message}`,this.render()}}async _rotateKey(t){try{let e={grace_period_hours:parseInt(this._rotateGracePeriod,10)||24},a=await this._api._post(`/api/v2/api-keys/${t}/rotate`,e);this._newToken=a?.token||a?.key||null,this._rotateKeyId=null,this._error=null,await this._loadData()}catch(e){this._error=`Rotate failed: ${e.message}`,this.render()}}async _deleteKey(t){try{await this._api._delete(`/api/v2/api-keys/${t}`),this._confirmDeleteId=null,this._error=null,await this._loadData()}catch(e){this._error=`Delete failed: ${e.message}`,this._confirmDeleteId=null,this.render()}}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
10997
+ `,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.getElementById("verify-btn");e&&e.addEventListener("click",()=>this._verifyIntegrity());let i=t.getElementById("refresh-btn");i&&i.addEventListener("click",()=>this._loadData());let a=t.getElementById("filter-action");a&&a.addEventListener("change",n=>this._onFilterChange("action",n.target.value));let s=t.getElementById("filter-resource");s&&s.addEventListener("change",n=>this._onFilterChange("resource",n.target.value));let r=t.getElementById("filter-date-from");r&&r.addEventListener("change",n=>this._onFilterChange("dateFrom",n.target.value));let o=t.getElementById("filter-date-to");o&&o.addEventListener("change",n=>this._onFilterChange("dateTo",n.target.value))}};customElements.get("loki-audit-viewer")||customElements.define("loki-audit-viewer",ct);function Qt(d){if(!d)return"Never";try{return new Date(d).toLocaleString([],{month:"short",day:"numeric",year:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return String(d)}}var pt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._keys=[],this._showCreateForm=!1,this._newToken=null,this._confirmDeleteId=null,this._rotateKeyId=null,this._rotateGracePeriod="24",this._createName="",this._createRole="read",this._createExpiration=""}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData()}disconnectedCallback(){super.disconnectedCallback()}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._loading=!0,this.render();let t=await this._api._get("/api/v2/api-keys");this._keys=Array.isArray(t)?t:t?.keys||[],this._error=null}catch(t){this._error=`Failed to load API keys: ${t.message}`}finally{this._loading=!1}this.render()}async _createKey(){if(!this._createName.trim()){this._error="Key name is required.",this.render();return}try{let t={name:this._createName.trim(),role:this._createRole};this._createExpiration&&(t.expiration=this._createExpiration);let e=await this._api._post("/api/v2/api-keys",t);this._newToken=e?.token||e?.key||null,this._showCreateForm=!1,this._createName="",this._createRole="read",this._createExpiration="",this._error=null,await this._loadData()}catch(t){this._error=`Create failed: ${t.message}`,this.render()}}async _rotateKey(t){try{let e={grace_period_hours:parseInt(this._rotateGracePeriod,10)||24},i=await this._api._post(`/api/v2/api-keys/${t}/rotate`,e);this._newToken=i?.token||i?.key||null,this._rotateKeyId=null,this._error=null,await this._loadData()}catch(e){this._error=`Rotate failed: ${e.message}`,this.render()}}async _deleteKey(t){try{await this._api._delete(`/api/v2/api-keys/${t}`),this._confirmDeleteId=null,this._error=null,await this._loadData()}catch(e){this._error=`Delete failed: ${e.message}`,this._confirmDeleteId=null,this.render()}}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
10986
10998
  :host {
10987
10999
  display: block;
10988
11000
  }
@@ -11288,14 +11300,14 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
11288
11300
  color: var(--loki-text-muted, #939084);
11289
11301
  font-size: 13px;
11290
11302
  }
11291
- `}render(){let t=this.shadowRoot;if(!t)return;let e=this._keys,a="";this._newToken&&(a=`
11303
+ `}render(){let t=this.shadowRoot;if(!t)return;let e=this._keys,i="";this._newToken&&(i=`
11292
11304
  <div class="new-token-banner">
11293
11305
  <div class="new-token-label">API Key Created</div>
11294
11306
  <div class="new-token-warning">Copy this token now. It will not be shown again.</div>
11295
11307
  <div class="new-token-value">${this._escapeHtml(this._newToken)}</div>
11296
11308
  <button class="new-token-dismiss" id="dismiss-token">Dismiss</button>
11297
11309
  </div>
11298
- `);let i="";this._showCreateForm&&(i=`
11310
+ `);let a="";this._showCreateForm&&(a=`
11299
11311
  <div class="create-form">
11300
11312
  <div class="form-title">Create New API Key</div>
11301
11313
  <div class="form-row">
@@ -11361,8 +11373,8 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
11361
11373
  <tr>
11362
11374
  <td><span class="key-name">${this._escapeHtml(o.name||"Unnamed")}</span></td>
11363
11375
  <td><span class="key-role">${this._escapeHtml(o.role||o.scopes||"--")}</span></td>
11364
- <td>${Wt(o.created_at||o.created)}</td>
11365
- <td>${Wt(o.last_used_at||o.last_used)}</td>
11376
+ <td>${Qt(o.created_at||o.created)}</td>
11377
+ <td>${Qt(o.last_used_at||o.last_used)}</td>
11366
11378
  <td><span class="${c}">${this._escapeHtml(l)}</span></td>
11367
11379
  <td><div class="actions-cell">${b}</div></td>
11368
11380
  </tr>
@@ -11376,12 +11388,12 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
11376
11388
  <h2 class="title">API Keys</h2>
11377
11389
  ${this._showCreateForm?"":'<button class="btn btn-primary" id="show-create">Create Key</button>'}
11378
11390
  </div>
11379
- ${a}
11380
11391
  ${i}
11392
+ ${a}
11381
11393
  ${s}
11382
11394
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
11383
11395
  </div>
11384
- `,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.getElementById("show-create");e&&e.addEventListener("click",()=>{this._showCreateForm=!0,this.render()});let a=t.getElementById("dismiss-token");a&&a.addEventListener("click",()=>{this._newToken=null,this.render()});let i=t.getElementById("submit-create");i&&i.addEventListener("click",()=>{let r=t.getElementById("create-name"),o=t.getElementById("create-role"),n=t.getElementById("create-expiration");this._createName=r?.value||"",this._createRole=o?.value||"read",this._createExpiration=n?.value||"",this._createKey()});let s=t.getElementById("cancel-create");s&&s.addEventListener("click",()=>{this._showCreateForm=!1,this.render()}),t.querySelectorAll('[data-action="delete"]').forEach(r=>{r.addEventListener("click",()=>{this._confirmDeleteId=r.dataset.keyId,this.render()})}),t.querySelectorAll('[data-action="confirm-delete"]').forEach(r=>{r.addEventListener("click",()=>{this._deleteKey(r.dataset.keyId)})}),t.querySelectorAll('[data-action="cancel-delete"]').forEach(r=>{r.addEventListener("click",()=>{this._confirmDeleteId=null,this.render()})}),t.querySelectorAll('[data-action="rotate"]').forEach(r=>{r.addEventListener("click",()=>{this._rotateKeyId=r.dataset.keyId,this.render()})}),t.querySelectorAll('[data-action="confirm-rotate"]').forEach(r=>{r.addEventListener("click",()=>{let o=t.getElementById(`rotate-grace-${r.dataset.keyId}`);this._rotateGracePeriod=o?.value||"24",this._rotateKey(r.dataset.keyId)})}),t.querySelectorAll('[data-action="cancel-rotate"]').forEach(r=>{r.addEventListener("click",()=>{this._rotateKeyId=null,this.render()})})}};customElements.get("loki-api-keys")||customElements.define("loki-api-keys",pt);function Te(d){return d?d.slug&&d.name?`${d.name} (${d.slug})`:d.name||d.slug||"Unknown":"Unknown"}var ut=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._tenants=[],this._selectedTenantId=null,this._dropdownOpen=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._outsideClickHandler=t=>{this._dropdownOpen&&!this.contains(t.target)&&(this._dropdownOpen=!1,this.render())},document.addEventListener("click",this._outsideClickHandler)}disconnectedCallback(){super.disconnectedCallback(),this._outsideClickHandler&&(document.removeEventListener("click",this._outsideClickHandler),this._outsideClickHandler=null)}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,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._loading=!0;let t=await this._api._get("/api/v2/tenants");this._tenants=Array.isArray(t)?t:t?.tenants||[],this._error=null}catch(t){this._error=`Failed to load tenants: ${t.message}`}finally{this._loading=!1}this.render()}_toggleDropdown(){this._dropdownOpen=!this._dropdownOpen,this.render()}_selectTenant(t,e){this._selectedTenantId=t,this._dropdownOpen=!1,this.render(),this.dispatchEvent(new CustomEvent("tenant-changed",{detail:{tenantId:t,tenantName:e},bubbles:!0,composed:!0}))}_getSelectedTenant(){return this._selectedTenantId==null?null:this._tenants.find(t=>(t.id||t.slug)===this._selectedTenantId)||null}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
11396
+ `,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.getElementById("show-create");e&&e.addEventListener("click",()=>{this._showCreateForm=!0,this.render()});let i=t.getElementById("dismiss-token");i&&i.addEventListener("click",()=>{this._newToken=null,this.render()});let a=t.getElementById("submit-create");a&&a.addEventListener("click",()=>{let r=t.getElementById("create-name"),o=t.getElementById("create-role"),n=t.getElementById("create-expiration");this._createName=r?.value||"",this._createRole=o?.value||"read",this._createExpiration=n?.value||"",this._createKey()});let s=t.getElementById("cancel-create");s&&s.addEventListener("click",()=>{this._showCreateForm=!1,this.render()}),t.querySelectorAll('[data-action="delete"]').forEach(r=>{r.addEventListener("click",()=>{this._confirmDeleteId=r.dataset.keyId,this.render()})}),t.querySelectorAll('[data-action="confirm-delete"]').forEach(r=>{r.addEventListener("click",()=>{this._deleteKey(r.dataset.keyId)})}),t.querySelectorAll('[data-action="cancel-delete"]').forEach(r=>{r.addEventListener("click",()=>{this._confirmDeleteId=null,this.render()})}),t.querySelectorAll('[data-action="rotate"]').forEach(r=>{r.addEventListener("click",()=>{this._rotateKeyId=r.dataset.keyId,this.render()})}),t.querySelectorAll('[data-action="confirm-rotate"]').forEach(r=>{r.addEventListener("click",()=>{let o=t.getElementById(`rotate-grace-${r.dataset.keyId}`);this._rotateGracePeriod=o?.value||"24",this._rotateKey(r.dataset.keyId)})}),t.querySelectorAll('[data-action="cancel-rotate"]').forEach(r=>{r.addEventListener("click",()=>{this._rotateKeyId=null,this.render()})})}};customElements.get("loki-api-keys")||customElements.define("loki-api-keys",pt);function Ie(d){return d?d.slug&&d.name?`${d.name} (${d.slug})`:d.name||d.slug||"Unknown":"Unknown"}var ht=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._tenants=[],this._selectedTenantId=null,this._dropdownOpen=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._outsideClickHandler=t=>{this._dropdownOpen&&!this.contains(t.target)&&(this._dropdownOpen=!1,this.render())},document.addEventListener("click",this._outsideClickHandler)}disconnectedCallback(){super.disconnectedCallback(),this._outsideClickHandler&&(document.removeEventListener("click",this._outsideClickHandler),this._outsideClickHandler=null)}attributeChangedCallback(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._loading=!0;let t=await this._api._get("/api/v2/tenants");this._tenants=Array.isArray(t)?t:t?.tenants||[],this._error=null}catch(t){this._error=`Failed to load tenants: ${t.message}`}finally{this._loading=!1}this.render()}_toggleDropdown(){this._dropdownOpen=!this._dropdownOpen,this.render()}_selectTenant(t,e){this._selectedTenantId=t,this._dropdownOpen=!1,this.render(),this.dispatchEvent(new CustomEvent("tenant-changed",{detail:{tenantId:t,tenantName:e},bubbles:!0,composed:!0}))}_getSelectedTenant(){return this._selectedTenantId==null?null:this._tenants.find(t=>(t.id||t.slug)===this._selectedTenantId)||null}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
11385
11397
  :host {
11386
11398
  display: inline-block;
11387
11399
  position: relative;
@@ -11515,7 +11527,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
11515
11527
  color: var(--loki-text-muted, #939084);
11516
11528
  font-size: 12px;
11517
11529
  }
11518
- `}render(){let t=this.shadowRoot;if(!t)return;let e=this._getSelectedTenant(),a=e?Te(e):"All Tenants",i=this._dropdownOpen,s="";if(i){let r;if(this._loading)r='<div class="loading-text">Loading tenants...</div>';else if(this._error)r=`<div class="error-text">${this._escapeHtml(this._error)}</div>`;else{let o=this._selectedTenantId==null;r=`
11530
+ `}render(){let t=this.shadowRoot;if(!t)return;let e=this._getSelectedTenant(),i=e?Ie(e):"All Tenants",a=this._dropdownOpen,s="";if(a){let r;if(this._loading)r='<div class="loading-text">Loading tenants...</div>';else if(this._error)r=`<div class="error-text">${this._escapeHtml(this._error)}</div>`;else{let o=this._selectedTenantId==null;r=`
11519
11531
  <button class="dropdown-item all-tenants ${o?"selected":""}" data-tenant-id="">
11520
11532
  <span class="tenant-name">All Tenants</span>
11521
11533
  ${o?'<span class="check-mark">*</span>':""}
@@ -11534,13 +11546,13 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
11534
11546
  `}s=`<div class="dropdown">${r}</div>`}t.innerHTML=`
11535
11547
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
11536
11548
  <div class="tenant-switcher">
11537
- <button class="trigger ${i?"open":""}" id="trigger-btn">
11538
- <span class="trigger-label">${this._escapeHtml(a)}</span>
11539
- <span class="trigger-icon ${i?"open":""}">&#9660;</span>
11549
+ <button class="trigger ${a?"open":""}" id="trigger-btn">
11550
+ <span class="trigger-label">${this._escapeHtml(i)}</span>
11551
+ <span class="trigger-icon ${a?"open":""}">&#9660;</span>
11540
11552
  </button>
11541
11553
  ${s}
11542
11554
  </div>
11543
- `,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.getElementById("trigger-btn");e&&e.addEventListener("click",a=>{a.stopPropagation(),this._toggleDropdown()}),t.querySelectorAll(".dropdown-item").forEach(a=>{a.addEventListener("click",i=>{i.stopPropagation();let s=a.dataset.tenantId||null,r=a.dataset.tenantName||null;this._selectTenant(s||null,r||"All Tenants")})})}};customElements.get("loki-tenant-switcher")||customElements.define("loki-tenant-switcher",ut);var zt={info:{color:"var(--loki-blue, #2F71E3)",label:"INFO",icon:"i"},success:{color:"var(--loki-green, #1FC5A8)",label:"OK",icon:"+"},warning:{color:"var(--loki-yellow, #D4A03C)",label:"WARN",icon:"!"},error:{color:"var(--loki-red, #C45B5B)",label:"ERR",icon:"x"}},Ie=100,ht=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._items=[],this._filter="all",this._api=null,this._pollInterval=null,this._paused=!1,this._lastTimestamp=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,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)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let t=await this._api._get("/api/v2/activity"),e=t.events||t.activities||[];if(e.length>0){let a=e.filter(i=>!this._lastTimestamp||new Date(i.timestamp)>new Date(this._lastTimestamp)).map(i=>({id:i.id||crypto.randomUUID(),timestamp:i.timestamp||new Date().toISOString(),message:i.message||i.description||"",severity:i.severity||i.level||"info",source:i.source||i.component||"",isNew:!0}));a.length>0&&(this._items=[...a,...this._items].slice(0,Ie),this._lastTimestamp=a[0].timestamp,setTimeout(()=>{this._items.forEach(i=>i.isNew=!1)},600))}}catch{this._items.length===0&&(this._items=this._getDemoItems())}this.render()}_getDemoItems(){let t=Date.now();return[{id:"1",timestamp:new Date(t-2e3).toISOString(),message:"Build iteration #12 started",severity:"info",source:"runner"},{id:"2",timestamp:new Date(t-5e3).toISOString(),message:"Code review passed (3/3 reviewers)",severity:"success",source:"review"},{id:"3",timestamp:new Date(t-8e3).toISOString(),message:"Context window at 78% capacity",severity:"warning",source:"context"},{id:"4",timestamp:new Date(t-12e3).toISOString(),message:"Test suite completed: 42/42 passed",severity:"success",source:"testing"},{id:"5",timestamp:new Date(t-15e3).toISOString(),message:"RARV cycle: Verify phase complete",severity:"info",source:"rarv"}]}_formatTime(t){if(!t)return"";try{return new Date(t).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})}catch{return""}}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getFilteredItems(){return this._filter==="all"?this._items:this._items.filter(t=>t.severity===this._filter)}_setFilter(t){this._filter=t,this.render()}_bindEvents(){let t=this.shadowRoot;t.querySelectorAll(".filter-btn").forEach(a=>{a.addEventListener("click",()=>{this._setFilter(a.dataset.filter)})});let e=t.querySelector(".activity-feed");e&&(e.addEventListener("mouseenter",()=>{this._paused=!0}),e.addEventListener("mouseleave",()=>{this._paused=!1}))}_getStyles(){return`
11555
+ `,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.getElementById("trigger-btn");e&&e.addEventListener("click",i=>{i.stopPropagation(),this._toggleDropdown()}),t.querySelectorAll(".dropdown-item").forEach(i=>{i.addEventListener("click",a=>{a.stopPropagation();let s=i.dataset.tenantId||null,r=i.dataset.tenantName||null;this._selectTenant(s||null,r||"All Tenants")})})}};customElements.get("loki-tenant-switcher")||customElements.define("loki-tenant-switcher",ht);var Ht={info:{color:"var(--loki-blue, #2F71E3)",label:"INFO",icon:"i"},success:{color:"var(--loki-green, #1FC5A8)",label:"OK",icon:"+"},warning:{color:"var(--loki-yellow, #D4A03C)",label:"WARN",icon:"!"},error:{color:"var(--loki-red, #C45B5B)",label:"ERR",icon:"x"}},Le=100,ut=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._items=[],this._filter="all",this._api=null,this._pollInterval=null,this._paused=!1,this._lastTimestamp=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(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)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let t=await this._api._get("/api/v2/activity"),e=t.events||t.activities||[];if(e.length>0){let i=e.filter(a=>!this._lastTimestamp||new Date(a.timestamp)>new Date(this._lastTimestamp)).map(a=>({id:a.id||crypto.randomUUID(),timestamp:a.timestamp||new Date().toISOString(),message:a.message||a.description||"",severity:a.severity||a.level||"info",source:a.source||a.component||"",isNew:!0}));i.length>0&&(this._items=[...i,...this._items].slice(0,Le),this._lastTimestamp=i[0].timestamp,setTimeout(()=>{this._items.forEach(a=>a.isNew=!1)},600))}}catch{this._items.length===0&&(this._items=this._getDemoItems())}this.render()}_getDemoItems(){let t=Date.now();return[{id:"1",timestamp:new Date(t-2e3).toISOString(),message:"Build iteration #12 started",severity:"info",source:"runner"},{id:"2",timestamp:new Date(t-5e3).toISOString(),message:"Code review passed (3/3 reviewers)",severity:"success",source:"review"},{id:"3",timestamp:new Date(t-8e3).toISOString(),message:"Context window at 78% capacity",severity:"warning",source:"context"},{id:"4",timestamp:new Date(t-12e3).toISOString(),message:"Test suite completed: 42/42 passed",severity:"success",source:"testing"},{id:"5",timestamp:new Date(t-15e3).toISOString(),message:"RARV cycle: Verify phase complete",severity:"info",source:"rarv"}]}_formatTime(t){if(!t)return"";try{return new Date(t).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})}catch{return""}}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getFilteredItems(){return this._filter==="all"?this._items:this._items.filter(t=>t.severity===this._filter)}_setFilter(t){this._filter=t,this.render()}_bindEvents(){let t=this.shadowRoot;t.querySelectorAll(".filter-btn").forEach(i=>{i.addEventListener("click",()=>{this._setFilter(i.dataset.filter)})});let e=t.querySelector(".activity-feed");e&&(e.addEventListener("mouseenter",()=>{this._paused=!0}),e.addEventListener("mouseleave",()=>{this._paused=!1}))}_getStyles(){return`
11544
11556
  :host {
11545
11557
  display: block;
11546
11558
  }
@@ -11726,7 +11738,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
11726
11738
  ::-webkit-scrollbar-track { background: var(--loki-bg-primary, #FFFEFB); }
11727
11739
  ::-webkit-scrollbar-thumb { background: var(--loki-border, #ECEAE3); border-radius: 3px; }
11728
11740
  ::-webkit-scrollbar-thumb:hover { background: var(--loki-border-light, #C5C0B1); }
11729
- `}render(){let t=this.shadowRoot;if(!t)return;let e=this._getFilteredItems(),i=["all","info","success","warning","error"].map(r=>{let o=this._filter===r,n=r==="all"?"All":zt[r]?.label||r;return`<button class="filter-btn ${o?"active":""}" data-filter="${r}">${n}</button>`}).join(""),s;if(e.length===0?s='<div class="empty-state">No activity to display</div>':s=e.map(r=>{let o=zt[r.severity]||zt.info;return`
11741
+ `}render(){let t=this.shadowRoot;if(!t)return;let e=this._getFilteredItems(),a=["all","info","success","warning","error"].map(r=>{let o=this._filter===r,n=r==="all"?"All":Ht[r]?.label||r;return`<button class="filter-btn ${o?"active":""}" data-filter="${r}">${n}</button>`}).join(""),s;if(e.length===0?s='<div class="empty-state">No activity to display</div>':s=e.map(r=>{let o=Ht[r.severity]||Ht.info;return`
11730
11742
  <div class="activity-item ${r.isNew?"new-item":""}">
11731
11743
  <div class="severity-band" style="background: ${o.color};"></div>
11732
11744
  <div class="item-content">
@@ -11741,13 +11753,13 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
11741
11753
  <div class="stream-container">
11742
11754
  <div class="header">
11743
11755
  <h3 class="title">Activity Stream <span class="count-badge">${this._items.length}</span></h3>
11744
- <div class="filter-bar">${i}</div>
11756
+ <div class="filter-bar">${a}</div>
11745
11757
  </div>
11746
11758
  <div class="activity-feed">
11747
11759
  ${s}
11748
11760
  </div>
11749
11761
  </div>
11750
- `,this._bindEvents(),!this._paused){let r=t.querySelector(".activity-feed");r&&(r.scrollTop=0)}}};customElements.get("loki-activity-stream")||customElements.define("loki-activity-stream",ht);var Le={claude:{initial:"C",color:"#553DE9",bgColor:"rgba(85, 61, 233, 0.12)"},codex:{initial:"X",color:"#1FC5A8",bgColor:"rgba(31, 197, 168, 0.12)"},cline:{initial:"L",color:"#D4A03C",bgColor:"rgba(212, 160, 60, 0.12)"},aider:{initial:"A",color:"#C45B5B",bgColor:"rgba(196, 91, 91, 0.12)"}},Qt={healthy:"var(--loki-green, #1FC5A8)",degraded:"var(--loki-yellow, #D4A03C)",down:"var(--loki-red, #C45B5B)",unknown:"var(--loki-text-muted, #939084)"},gt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._providers=[],this._expandedProvider=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,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(),1e4)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let t=await this._api._get("/api/v2/providers/health");this._providers=t.providers||[]}catch{this._providers.length===0&&(this._providers=this._getDemoData())}this.render()}_getDemoData(){return[{name:"claude",status:"healthy",latency_ms:245,tokens_used:125400,model:"claude-opus-4-7",api_version:"v1",rate_limit:{remaining:45,limit:50},cost_usd:3.42},{name:"codex",status:"degraded",latency_ms:890,tokens_used:45200,model:"gpt-5.3-codex",api_version:"v1",rate_limit:{remaining:12,limit:60},cost_usd:.87},{name:"cline",status:"healthy",latency_ms:320,tokens_used:78600,model:"cline-default",api_version:"v1",rate_limit:{remaining:55,limit:60},cost_usd:1.15}]}_formatTokens(t){return t==null?"--":t>=1e6?(t/1e6).toFixed(1)+"M":t>=1e3?(t/1e3).toFixed(1)+"K":String(t)}_formatLatency(t){return t==null?"--":t<1e3?t+"ms":(t/1e3).toFixed(1)+"s"}_formatCost(t){return t==null?"--":"$"+t.toFixed(2)}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_toggleExpand(t){this._expandedProvider=this._expandedProvider===t?null:t,this.render()}_bindEvents(){this.shadowRoot.querySelectorAll(".provider-card").forEach(e=>{e.addEventListener("click",()=>{this._toggleExpand(e.dataset.provider)})})}_getStyles(){return`
11762
+ `,this._bindEvents(),!this._paused){let r=t.querySelector(".activity-feed");r&&(r.scrollTop=0)}}};customElements.get("loki-activity-stream")||customElements.define("loki-activity-stream",ut);var De={claude:{initial:"C",color:"#553DE9",bgColor:"rgba(85, 61, 233, 0.12)"},codex:{initial:"X",color:"#1FC5A8",bgColor:"rgba(31, 197, 168, 0.12)"},cline:{initial:"L",color:"#D4A03C",bgColor:"rgba(212, 160, 60, 0.12)"},aider:{initial:"A",color:"#C45B5B",bgColor:"rgba(196, 91, 91, 0.12)"}},Xt={healthy:"var(--loki-green, #1FC5A8)",degraded:"var(--loki-yellow, #D4A03C)",down:"var(--loki-red, #C45B5B)",unknown:"var(--loki-text-muted, #939084)"},gt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._providers=[],this._expandedProvider=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(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(),1e4)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let t=await this._api._get("/api/v2/providers/health");this._providers=t.providers||[]}catch{this._providers.length===0&&(this._providers=this._getDemoData())}this.render()}_getDemoData(){return[{name:"claude",status:"healthy",latency_ms:245,tokens_used:125400,model:"claude-opus-4-7",api_version:"v1",rate_limit:{remaining:45,limit:50},cost_usd:3.42},{name:"codex",status:"degraded",latency_ms:890,tokens_used:45200,model:"gpt-5.3-codex",api_version:"v1",rate_limit:{remaining:12,limit:60},cost_usd:.87},{name:"cline",status:"healthy",latency_ms:320,tokens_used:78600,model:"cline-default",api_version:"v1",rate_limit:{remaining:55,limit:60},cost_usd:1.15}]}_formatTokens(t){return t==null?"--":t>=1e6?(t/1e6).toFixed(1)+"M":t>=1e3?(t/1e3).toFixed(1)+"K":String(t)}_formatLatency(t){return t==null?"--":t<1e3?t+"ms":(t/1e3).toFixed(1)+"s"}_formatCost(t){return t==null?"--":"$"+t.toFixed(2)}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_toggleExpand(t){this._expandedProvider=this._expandedProvider===t?null:t,this.render()}_bindEvents(){this.shadowRoot.querySelectorAll(".provider-card").forEach(e=>{e.addEventListener("click",()=>{this._toggleExpand(e.dataset.provider)})})}_getStyles(){return`
11751
11763
  :host {
11752
11764
  display: block;
11753
11765
  }
@@ -11926,41 +11938,41 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
11926
11938
  border: 1px solid var(--loki-border, #ECEAE3);
11927
11939
  border-radius: 5px;
11928
11940
  }
11929
- `}render(){let t=this.shadowRoot;if(!t)return;let e;this._providers.length===0?e='<div class="empty-state">No provider data available</div>':e=`<div class="provider-grid">${this._providers.map(a=>{let i=Le[a.name]||{initial:(a.name??"?").charAt(0).toUpperCase(),color:"#939084",bgColor:"rgba(147, 144, 132, 0.12)"},s=Qt[a.status]||Qt.unknown,r=this._expandedProvider===a.name,o=a.rate_limit?a.rate_limit.remaining/a.rate_limit.limit*100:100,n=o>50?"var(--loki-green)":o>20?"var(--loki-yellow)":"var(--loki-red)";return`
11930
- <div class="provider-card ${r?"expanded":""}" data-provider="${this._escapeHtml(a.name)}">
11941
+ `}render(){let t=this.shadowRoot;if(!t)return;let e;this._providers.length===0?e='<div class="empty-state">No provider data available</div>':e=`<div class="provider-grid">${this._providers.map(i=>{let a=De[i.name]||{initial:(i.name??"?").charAt(0).toUpperCase(),color:"#939084",bgColor:"rgba(147, 144, 132, 0.12)"},s=Xt[i.status]||Xt.unknown,r=this._expandedProvider===i.name,o=i.rate_limit?i.rate_limit.remaining/i.rate_limit.limit*100:100,n=o>50?"var(--loki-green)":o>20?"var(--loki-yellow)":"var(--loki-red)";return`
11942
+ <div class="provider-card ${r?"expanded":""}" data-provider="${this._escapeHtml(i.name)}">
11931
11943
  <div class="card-header">
11932
- <div class="provider-icon" style="background: ${i.bgColor}; color: ${i.color};">${i.initial}</div>
11933
- <span class="provider-name">${this._escapeHtml(a.name)}</span>
11934
- <div class="status-dot ${a.status==="healthy"?"pulse":""}" style="background: ${s};" title="${this._escapeHtml(a.status)}"></div>
11944
+ <div class="provider-icon" style="background: ${a.bgColor}; color: ${a.color};">${a.initial}</div>
11945
+ <span class="provider-name">${this._escapeHtml(i.name)}</span>
11946
+ <div class="status-dot ${i.status==="healthy"?"pulse":""}" style="background: ${s};" title="${this._escapeHtml(i.status)}"></div>
11935
11947
  </div>
11936
11948
  <div class="card-metrics">
11937
11949
  <div class="metric">
11938
11950
  <span class="metric-label">Latency</span>
11939
- <span class="metric-value">${this._formatLatency(a.latency_ms)}</span>
11951
+ <span class="metric-value">${this._formatLatency(i.latency_ms)}</span>
11940
11952
  </div>
11941
11953
  <div class="metric">
11942
11954
  <span class="metric-label">Tokens</span>
11943
- <span class="metric-value">${this._formatTokens(a.tokens_used)}</span>
11955
+ <span class="metric-value">${this._formatTokens(i.tokens_used)}</span>
11944
11956
  </div>
11945
11957
  </div>
11946
11958
  ${r?`
11947
11959
  <div class="expand-details">
11948
11960
  <div class="detail-row">
11949
11961
  <span class="detail-label">Model</span>
11950
- <span class="detail-value">${this._escapeHtml(a.model||"--")}</span>
11962
+ <span class="detail-value">${this._escapeHtml(i.model||"--")}</span>
11951
11963
  </div>
11952
11964
  <div class="detail-row">
11953
11965
  <span class="detail-label">API Version</span>
11954
- <span class="detail-value">${this._escapeHtml(a.api_version||"--")}</span>
11966
+ <span class="detail-value">${this._escapeHtml(i.api_version||"--")}</span>
11955
11967
  </div>
11956
11968
  <div class="detail-row">
11957
11969
  <span class="detail-label">Cost</span>
11958
- <span class="detail-value">${this._formatCost(a.cost_usd)}</span>
11970
+ <span class="detail-value">${this._formatCost(i.cost_usd)}</span>
11959
11971
  </div>
11960
11972
  <div class="detail-row">
11961
11973
  <span class="detail-label">Rate Limit</span>
11962
- <span class="detail-value">${a.rate_limit?a.rate_limit.remaining+"/"+a.rate_limit.limit:"--"}</span>
11963
- ${a.rate_limit?`
11974
+ <span class="detail-value">${i.rate_limit?i.rate_limit.remaining+"/"+i.rate_limit.limit:"--"}</span>
11975
+ ${i.rate_limit?`
11964
11976
  <div class="rate-limit-bar">
11965
11977
  <div class="rate-limit-fill" style="width: ${o}%; background: ${n};"></div>
11966
11978
  </div>
@@ -11978,7 +11990,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
11978
11990
  </div>
11979
11991
  ${e}
11980
11992
  </div>
11981
- `,this._bindEvents()}};customElements.get("loki-provider-health")||customElements.define("loki-provider-health",gt);var Ht=[{id:"planning",label:"Planning",icon:"P"},{id:"scaffolding",label:"Scaffolding",icon:"S"},{id:"implementation",label:"Implementation",icon:"I"},{id:"testing",label:"Testing",icon:"T"},{id:"review",label:"Review",icon:"R"},{id:"deploy",label:"Deploy",icon:"D"}],Rt={waiting:{color:"var(--loki-text-muted, #939084)",bgColor:"var(--loki-bg-tertiary, #ECEAE3)",label:"Waiting"},active:{color:"var(--loki-accent, #553DE9)",bgColor:"var(--loki-accent-muted, rgba(85, 61, 233, 0.10))",label:"Active"},complete:{color:"var(--loki-green, #1FC5A8)",bgColor:"var(--loki-green-muted, rgba(31, 197, 168, 0.12))",label:"Complete"},failed:{color:"var(--loki-red, #C45B5B)",bgColor:"var(--loki-red-muted, rgba(196, 91, 91, 0.12))",label:"Failed"}},mt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._stages=[],this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let t=await this._api._get("/api/v2/pipeline/status");this._stages=t.stages||[]}catch{this._stages.length===0&&(this._stages=this._getDemoData())}this.render()}_getDemoData(){return[{id:"planning",status:"complete",errors:0,duration_ms:12500},{id:"scaffolding",status:"complete",errors:0,duration_ms:8300},{id:"implementation",status:"active",errors:0,duration_ms:45e3},{id:"testing",status:"waiting",errors:0,duration_ms:null},{id:"review",status:"waiting",errors:0,duration_ms:null},{id:"deploy",status:"waiting",errors:0,duration_ms:null}]}_getStageData(t){return this._stages.find(e=>e.id===t)||{id:t,status:"waiting",errors:0}}_formatDuration(t){if(t==null||t<0)return"";if(t<1e3)return t+"ms";let e=Math.floor(t/1e3);if(e<60)return e+"s";let a=Math.floor(e/60),i=e%60;return a+"m "+i+"s"}_getStyles(){return`
11993
+ `,this._bindEvents()}};customElements.get("loki-provider-health")||customElements.define("loki-provider-health",gt);var Rt=[{id:"planning",label:"Planning",icon:"P"},{id:"scaffolding",label:"Scaffolding",icon:"S"},{id:"implementation",label:"Implementation",icon:"I"},{id:"testing",label:"Testing",icon:"T"},{id:"review",label:"Review",icon:"R"},{id:"deploy",label:"Deploy",icon:"D"}],Bt={waiting:{color:"var(--loki-text-muted, #939084)",bgColor:"var(--loki-bg-tertiary, #ECEAE3)",label:"Waiting"},active:{color:"var(--loki-accent, #553DE9)",bgColor:"var(--loki-accent-muted, rgba(85, 61, 233, 0.10))",label:"Active"},complete:{color:"var(--loki-green, #1FC5A8)",bgColor:"var(--loki-green-muted, rgba(31, 197, 168, 0.12))",label:"Complete"},failed:{color:"var(--loki-red, #C45B5B)",bgColor:"var(--loki-red-muted, rgba(196, 91, 91, 0.12))",label:"Failed"}},vt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._stages=[],this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let t=await this._api._get("/api/v2/pipeline/status");this._stages=t.stages||[]}catch{this._stages.length===0&&(this._stages=this._getDemoData())}this.render()}_getDemoData(){return[{id:"planning",status:"complete",errors:0,duration_ms:12500},{id:"scaffolding",status:"complete",errors:0,duration_ms:8300},{id:"implementation",status:"active",errors:0,duration_ms:45e3},{id:"testing",status:"waiting",errors:0,duration_ms:null},{id:"review",status:"waiting",errors:0,duration_ms:null},{id:"deploy",status:"waiting",errors:0,duration_ms:null}]}_getStageData(t){return this._stages.find(e=>e.id===t)||{id:t,status:"waiting",errors:0}}_formatDuration(t){if(t==null||t<0)return"";if(t<1e3)return t+"ms";let e=Math.floor(t/1e3);if(e<60)return e+"s";let i=Math.floor(e/60),a=e%60;return i+"m "+a+"s"}_getStyles(){return`
11982
11994
  :host {
11983
11995
  display: block;
11984
11996
  }
@@ -12141,22 +12153,22 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
12141
12153
  border-radius: 50%;
12142
12154
  flex-shrink: 0;
12143
12155
  }
12144
- `}render(){let t=this.shadowRoot;if(!t)return;let e=Ht.map((i,s)=>{let r=this._getStageData(i.id),o=Rt[r.status]||Rt.waiting,n=r.status==="complete",l=r.status==="active",c=r.status==="failed",p=n?'<span class="stage-check">&#10003;</span>':c?'<span class="stage-check">&#10007;</span>':i.icon,u=`
12156
+ `}render(){let t=this.shadowRoot;if(!t)return;let e=Rt.map((a,s)=>{let r=this._getStageData(a.id),o=Bt[r.status]||Bt.waiting,n=r.status==="complete",l=r.status==="active",c=r.status==="failed",p=n?'<span class="stage-check">&#10003;</span>':c?'<span class="stage-check">&#10007;</span>':a.icon,u=`
12145
12157
  <div class="stage-node">
12146
12158
  <div class="stage-circle ${l?"active":""}"
12147
12159
  style="background: ${o.bgColor}; color: ${o.color}; border: 2px solid ${o.color};">
12148
12160
  ${p}
12149
12161
  </div>
12150
- <span class="stage-label">${i.label}</span>
12162
+ <span class="stage-label">${a.label}</span>
12151
12163
  ${r.duration_ms?`<span class="stage-duration">${this._formatDuration(r.duration_ms)}</span>`:""}
12152
12164
  ${r.errors>0?`<span class="stage-error-count">${r.errors} error${r.errors>1?"s":""}</span>`:""}
12153
12165
  </div>
12154
- `;if(s<Ht.length-1){let b=this._getStageData(Ht[s+1].id),m=n,f=l||n&&(b.status==="active"||b.status==="waiting");return u+`
12166
+ `;if(s<Rt.length-1){let b=this._getStageData(Rt[s+1].id),v=n,f=l||n&&(b.status==="active"||b.status==="waiting");return u+`
12155
12167
  <div class="connector">
12156
- <div class="connector-line ${m?"completed":l?"active":"pending"}"></div>
12168
+ <div class="connector-line ${v?"completed":l?"active":"pending"}"></div>
12157
12169
  ${l?'<div class="flow-dot"></div>':""}
12158
12170
  </div>
12159
- `}return u}).join(""),a=Object.entries(Rt).map(([i,s])=>`<div class="legend-item">
12171
+ `}return u}).join(""),i=Object.entries(Bt).map(([a,s])=>`<div class="legend-item">
12160
12172
  <div class="legend-dot" style="background: ${s.color};"></div>
12161
12173
  <span>${s.label}</span>
12162
12174
  </div>`).join("");t.innerHTML=`
@@ -12169,16 +12181,16 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
12169
12181
  ${e}
12170
12182
  </div>
12171
12183
  <div class="status-legend">
12172
- ${a}
12184
+ ${i}
12173
12185
  </div>
12174
12186
  </div>
12175
- `}};customElements.get("loki-pipeline-view")||customElements.define("loki-pipeline-view",mt);var vt={episode:{color:"var(--loki-blue, #2F71E3)",shape:"circle",label:"Episode"},pattern:{color:"var(--loki-green, #1FC5A8)",shape:"square",label:"Pattern"},skill:{color:"var(--loki-purple, #553DE9)",shape:"diamond",label:"Skill"}};function De(d,t,e){let a=t/2,i=e/2,s=Math.min(a,i)*.65,r=d.length;return d.map((o,n)=>{let l=2*Math.PI*n/r-Math.PI/2,c=o.importance||.5,p=s*(.5+c*.5);return{...o,x:a+p*Math.cos(l),y:i+p*Math.sin(l)}})}var bt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._nodes=[],this._edges=[],this._selectedNode=null,this._api=null,this._pollInterval=null,this._graphWidth=600,this._graphHeight=400}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),15e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let t=await this._api._get("/api/v2/memory/graph");this._nodes=t.nodes||[],this._edges=t.edges||[]}catch{if(this._nodes.length===0){let t=this._getDemoData();this._nodes=t.nodes,this._edges=t.edges}}this.render()}_getDemoData(){return{nodes:[{id:"ep1",type:"episode",label:"Build iteration #12",importance:.8,details:"Completed scaffolding and initial implementation"},{id:"ep2",type:"episode",label:"Code review #5",importance:.6,details:"Quality gate passed with 3/3 approval"},{id:"ep3",type:"episode",label:"Test failure #3",importance:.7,details:"Integration test timeout resolved"},{id:"pt1",type:"pattern",label:"Error recovery",importance:.9,details:"Retry with exponential backoff pattern"},{id:"pt2",type:"pattern",label:"API design",importance:.7,details:"REST endpoint naming conventions"},{id:"pt3",type:"pattern",label:"Test structure",importance:.5,details:"Arrange-Act-Assert with setup helpers"},{id:"sk1",type:"skill",label:"Playwright E2E",importance:.85,details:"Browser automation test writing"},{id:"sk2",type:"skill",label:"FastAPI routing",importance:.6,details:"Python API server development"}],edges:[{source:"ep1",target:"pt1",strength:.8},{source:"ep1",target:"sk1",strength:.6},{source:"ep2",target:"pt2",strength:.9},{source:"ep3",target:"pt1",strength:.7},{source:"ep3",target:"pt3",strength:.5},{source:"pt1",target:"sk2",strength:.4},{source:"pt2",target:"sk2",strength:.7},{source:"pt3",target:"sk1",strength:.6}]}}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_selectNode(t){this._selectedNode=this._selectedNode===t?null:t,this.render()}_bindEvents(){let t=this.shadowRoot;t.querySelectorAll(".graph-node").forEach(e=>{e.addEventListener("click",()=>{this._selectNode(e.dataset.nodeId)})}),t.querySelectorAll(".close-detail").forEach(e=>{e.addEventListener("click",()=>{this._selectedNode=null,this.render()})})}_renderNodeShape(t,e,a){let i=vt[t.type]||vt.episode,s=10+(t.importance||.5)*16,r=this._selectedNode===t.id,o=r?"var(--loki-accent, #553DE9)":i.color,n=r?3:1.5,l=this._selectedNode&&!r?.4:1,c;switch(i.shape){case"square":c=`<rect x="${e-s/2}" y="${a-s/2}" width="${s}" height="${s}"
12176
- rx="3" fill="${i.color}" fill-opacity="0.2" stroke="${o}" stroke-width="${n}" opacity="${l}" />`;break;case"diamond":{let u=s/2;c=`<polygon points="${e},${a-u} ${e+u},${a} ${e},${a+u} ${e-u},${a}"
12177
- fill="${i.color}" fill-opacity="0.2" stroke="${o}" stroke-width="${n}" opacity="${l}" />`;break}default:c=`<circle cx="${e}" cy="${a}" r="${s/2}" fill="${i.color}" fill-opacity="0.2"
12178
- stroke="${o}" stroke-width="${n}" opacity="${l}" />`}let p=`<text x="${e}" y="${a+s/2+14}" text-anchor="middle" font-size="10"
12187
+ `}};customElements.get("loki-pipeline-view")||customElements.define("loki-pipeline-view",vt);var mt={episode:{color:"var(--loki-blue, #2F71E3)",shape:"circle",label:"Episode"},pattern:{color:"var(--loki-green, #1FC5A8)",shape:"square",label:"Pattern"},skill:{color:"var(--loki-purple, #553DE9)",shape:"diamond",label:"Skill"}};function ze(d,t,e){let i=t/2,a=e/2,s=Math.min(i,a)*.65,r=d.length;return d.map((o,n)=>{let l=2*Math.PI*n/r-Math.PI/2,c=o.importance||.5,p=s*(.5+c*.5);return{...o,x:i+p*Math.cos(l),y:a+p*Math.sin(l)}})}var bt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._nodes=[],this._edges=[],this._selectedNode=null,this._api=null,this._pollInterval=null,this._graphWidth=600,this._graphHeight=400}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),15e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let t=await this._api._get("/api/v2/memory/graph");this._nodes=t.nodes||[],this._edges=t.edges||[]}catch{if(this._nodes.length===0){let t=this._getDemoData();this._nodes=t.nodes,this._edges=t.edges}}this.render()}_getDemoData(){return{nodes:[{id:"ep1",type:"episode",label:"Build iteration #12",importance:.8,details:"Completed scaffolding and initial implementation"},{id:"ep2",type:"episode",label:"Code review #5",importance:.6,details:"Quality gate passed with 3/3 approval"},{id:"ep3",type:"episode",label:"Test failure #3",importance:.7,details:"Integration test timeout resolved"},{id:"pt1",type:"pattern",label:"Error recovery",importance:.9,details:"Retry with exponential backoff pattern"},{id:"pt2",type:"pattern",label:"API design",importance:.7,details:"REST endpoint naming conventions"},{id:"pt3",type:"pattern",label:"Test structure",importance:.5,details:"Arrange-Act-Assert with setup helpers"},{id:"sk1",type:"skill",label:"Playwright E2E",importance:.85,details:"Browser automation test writing"},{id:"sk2",type:"skill",label:"FastAPI routing",importance:.6,details:"Python API server development"}],edges:[{source:"ep1",target:"pt1",strength:.8},{source:"ep1",target:"sk1",strength:.6},{source:"ep2",target:"pt2",strength:.9},{source:"ep3",target:"pt1",strength:.7},{source:"ep3",target:"pt3",strength:.5},{source:"pt1",target:"sk2",strength:.4},{source:"pt2",target:"sk2",strength:.7},{source:"pt3",target:"sk1",strength:.6}]}}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_selectNode(t){this._selectedNode=this._selectedNode===t?null:t,this.render()}_bindEvents(){let t=this.shadowRoot;t.querySelectorAll(".graph-node").forEach(e=>{e.addEventListener("click",()=>{this._selectNode(e.dataset.nodeId)})}),t.querySelectorAll(".close-detail").forEach(e=>{e.addEventListener("click",()=>{this._selectedNode=null,this.render()})})}_renderNodeShape(t,e,i){let a=mt[t.type]||mt.episode,s=10+(t.importance||.5)*16,r=this._selectedNode===t.id,o=r?"var(--loki-accent, #553DE9)":a.color,n=r?3:1.5,l=this._selectedNode&&!r?.4:1,c;switch(a.shape){case"square":c=`<rect x="${e-s/2}" y="${i-s/2}" width="${s}" height="${s}"
12188
+ rx="3" fill="${a.color}" fill-opacity="0.2" stroke="${o}" stroke-width="${n}" opacity="${l}" />`;break;case"diamond":{let u=s/2;c=`<polygon points="${e},${i-u} ${e+u},${i} ${e},${i+u} ${e-u},${i}"
12189
+ fill="${a.color}" fill-opacity="0.2" stroke="${o}" stroke-width="${n}" opacity="${l}" />`;break}default:c=`<circle cx="${e}" cy="${i}" r="${s/2}" fill="${a.color}" fill-opacity="0.2"
12190
+ stroke="${o}" stroke-width="${n}" opacity="${l}" />`}let p=`<text x="${e}" y="${i+s/2+14}" text-anchor="middle" font-size="10"
12179
12191
  font-family="Inter, sans-serif" fill="var(--loki-text-secondary, #36342E)" opacity="${l}">${this._escapeHtml(t.label)}</text>`;return`<g class="graph-node" data-node-id="${this._escapeHtml(t.id)}" style="cursor: pointer;">
12180
12192
  ${c}${p}
12181
- </g>`}_renderEdge(t,e){let a=e.find(n=>n.id===t.source),i=e.find(n=>n.id===t.target);if(!a||!i)return"";let s=(t.strength||1)<.6,r=this._selectedNode?t.source===this._selectedNode||t.target===this._selectedNode?.8:.15:.4,o=s?'stroke-dasharray="4 4"':"";return`<line x1="${a.x}" y1="${a.y}" x2="${i.x}" y2="${i.y}"
12193
+ </g>`}_renderEdge(t,e){let i=e.find(n=>n.id===t.source),a=e.find(n=>n.id===t.target);if(!i||!a)return"";let s=(t.strength||1)<.6,r=this._selectedNode?t.source===this._selectedNode||t.target===this._selectedNode?.8:.15:.4,o=s?'stroke-dasharray="4 4"':"";return`<line x1="${i.x}" y1="${i.y}" x2="${a.x}" y2="${a.y}"
12182
12194
  stroke="var(--loki-border-light, #C5C0B1)" stroke-width="1.5" opacity="${r}" ${o} />`}_getStyles(){return`
12183
12195
  :host {
12184
12196
  display: block;
@@ -12333,7 +12345,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
12333
12345
  </div>
12334
12346
  <div class="empty-state">No memory entries to visualize</div>
12335
12347
  </div>
12336
- `;return}let e=this._graphWidth,a=this._graphHeight,i=De(this._nodes,e,a),s=this._edges.map(l=>this._renderEdge(l,i)).join(""),r=i.map(l=>this._renderNodeShape(l,l.x,l.y)).join(""),o="";if(this._selectedNode){let l=this._nodes.find(c=>c.id===this._selectedNode);if(l){let c=vt[l.type]||vt.episode;o=`
12348
+ `;return}let e=this._graphWidth,i=this._graphHeight,a=ze(this._nodes,e,i),s=this._edges.map(l=>this._renderEdge(l,a)).join(""),r=a.map(l=>this._renderNodeShape(l,l.x,l.y)).join(""),o="";if(this._selectedNode){let l=this._nodes.find(c=>c.id===this._selectedNode);if(l){let c=mt[l.type]||mt.episode;o=`
12337
12349
  <div class="detail-panel">
12338
12350
  <div class="detail-header">
12339
12351
  <span class="detail-title">${this._escapeHtml(l.label)}</span>
@@ -12342,7 +12354,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
12342
12354
  </div>
12343
12355
  <div class="detail-body">${this._escapeHtml(l.details||"No details available")}</div>
12344
12356
  </div>
12345
- `}}let n=Object.entries(vt).map(([,l])=>{let c;return l.shape==="circle"?c=`<div class="legend-circle" style="border-color: ${l.color};"></div>`:l.shape==="square"?c=`<div class="legend-square" style="border-color: ${l.color};"></div>`:c=`<div class="legend-diamond" style="border-color: ${l.color};"></div>`,`<div class="legend-item">
12357
+ `}}let n=Object.entries(mt).map(([,l])=>{let c;return l.shape==="circle"?c=`<div class="legend-circle" style="border-color: ${l.color};"></div>`:l.shape==="square"?c=`<div class="legend-square" style="border-color: ${l.color};"></div>`:c=`<div class="legend-diamond" style="border-color: ${l.color};"></div>`,`<div class="legend-item">
12346
12358
  <div class="legend-shape">${c}</div>
12347
12359
  <span>${l.label}</span>
12348
12360
  </div>`}).join("");t.innerHTML=`
@@ -12352,7 +12364,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
12352
12364
  <h3 class="title">Memory Network</h3>
12353
12365
  </div>
12354
12366
  <div class="graph-wrap">
12355
- <svg class="graph-svg" viewBox="0 0 ${e} ${a}" xmlns="http://www.w3.org/2000/svg">
12367
+ <svg class="graph-svg" viewBox="0 0 ${e} ${i}" xmlns="http://www.w3.org/2000/svg">
12356
12368
  ${s}
12357
12369
  ${r}
12358
12370
  </svg>
@@ -12360,7 +12372,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
12360
12372
  </div>
12361
12373
  <div class="legend">${n}</div>
12362
12374
  </div>
12363
- `,this._bindEvents()}};customElements.get("loki-memory-graph")||customElements.define("loki-memory-graph",bt);var Bt={planning:{color:"var(--loki-blue, #2F71E3)",label:"Planning"},building:{color:"var(--loki-green, #1FC5A8)",label:"Building"},implementation:{color:"var(--loki-green, #1FC5A8)",label:"Building"},testing:{color:"var(--loki-purple, #553DE9)",label:"Testing"},review:{color:"var(--loki-yellow, #D4A03C)",label:"Review"},overhead:{color:"var(--loki-text-muted, #939084)",label:"Overhead"}},ft=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._phases=[],this._budget=null,this._totalCost=0,this._hoveredPhase=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,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(),1e4)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let t=await this._api._get("/api/v2/cost/breakdown");this._phases=t.phases||[],this._budget=t.budget_usd||null,this._totalCost=t.total_usd||this._phases.reduce((e,a)=>e+(a.cost_usd||0),0)}catch{this._phases.length===0&&(this._phases=this._getDemoData(),this._budget=10,this._totalCost=this._phases.reduce((t,e)=>t+e.cost_usd,0))}this.render()}_getDemoData(){return[{phase:"planning",cost_usd:.85,tokens:12400},{phase:"building",cost_usd:3.2,tokens:68500},{phase:"testing",cost_usd:1.45,tokens:31200},{phase:"review",cost_usd:.9,tokens:18800},{phase:"overhead",cost_usd:.35,tokens:5600}]}_formatCost(t){return t==null?"--":"$"+t.toFixed(2)}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_bindEvents(){this.shadowRoot.querySelectorAll(".waterfall-bar").forEach(e=>{e.addEventListener("mouseenter",()=>{this._hoveredPhase=e.dataset.phase,this._updateTooltip(e)}),e.addEventListener("mouseleave",()=>{this._hoveredPhase=null,this._hideTooltip()})})}_updateTooltip(t){let e=this.shadowRoot.querySelector(".tooltip");if(!e)return;let a=this._phases.find(o=>o.phase===this._hoveredPhase);if(!a)return;let i=Bt[a.phase]||{label:a.phase};e.innerHTML=`<strong>${i.label}</strong>: ${this._formatCost(a.cost_usd)}`,e.style.display="block";let s=t.getBoundingClientRect(),r=this.shadowRoot.querySelector(".chart-area").getBoundingClientRect();e.style.left=s.left-r.left+s.width/2+"px",e.style.top=s.top-r.top-30+"px"}_hideTooltip(){let t=this.shadowRoot.querySelector(".tooltip");t&&(t.style.display="none")}_getStyles(){return`
12375
+ `,this._bindEvents()}};customElements.get("loki-memory-graph")||customElements.define("loki-memory-graph",bt);var Pt={planning:{color:"var(--loki-blue, #2F71E3)",label:"Planning"},building:{color:"var(--loki-green, #1FC5A8)",label:"Building"},implementation:{color:"var(--loki-green, #1FC5A8)",label:"Building"},testing:{color:"var(--loki-purple, #553DE9)",label:"Testing"},review:{color:"var(--loki-yellow, #D4A03C)",label:"Review"},overhead:{color:"var(--loki-text-muted, #939084)",label:"Overhead"}},ft=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._phases=[],this._budget=null,this._totalCost=0,this._hoveredPhase=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),1e4)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let t=await this._api._get("/api/v2/cost/breakdown");this._phases=t.phases||[],this._budget=t.budget_usd||null,this._totalCost=t.total_usd||this._phases.reduce((e,i)=>e+(i.cost_usd||0),0)}catch{this._phases.length===0&&(this._phases=this._getDemoData(),this._budget=10,this._totalCost=this._phases.reduce((t,e)=>t+e.cost_usd,0))}this.render()}_getDemoData(){return[{phase:"planning",cost_usd:.85,tokens:12400},{phase:"building",cost_usd:3.2,tokens:68500},{phase:"testing",cost_usd:1.45,tokens:31200},{phase:"review",cost_usd:.9,tokens:18800},{phase:"overhead",cost_usd:.35,tokens:5600}]}_formatCost(t){return t==null?"--":"$"+t.toFixed(2)}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_bindEvents(){this.shadowRoot.querySelectorAll(".waterfall-bar").forEach(e=>{e.addEventListener("mouseenter",()=>{this._hoveredPhase=e.dataset.phase,this._updateTooltip(e)}),e.addEventListener("mouseleave",()=>{this._hoveredPhase=null,this._hideTooltip()})})}_updateTooltip(t){let e=this.shadowRoot.querySelector(".tooltip");if(!e)return;let i=this._phases.find(o=>o.phase===this._hoveredPhase);if(!i)return;let a=Pt[i.phase]||{label:i.phase};e.innerHTML=`<strong>${a.label}</strong>: ${this._formatCost(i.cost_usd)}`,e.style.display="block";let s=t.getBoundingClientRect(),r=this.shadowRoot.querySelector(".chart-area").getBoundingClientRect();e.style.left=s.left-r.left+s.width/2+"px",e.style.top=s.top-r.top-30+"px"}_hideTooltip(){let t=this.shadowRoot.querySelector(".tooltip");t&&(t.style.display="none")}_getStyles(){return`
12364
12376
  :host {
12365
12377
  display: block;
12366
12378
  }
@@ -12550,7 +12562,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
12550
12562
  </div>
12551
12563
  <div class="empty-state">No cost data available</div>
12552
12564
  </div>
12553
- `;return}let e=Math.max(...this._phases.map(l=>l.cost_usd||0),.01),a=160,i=this._budget?Math.max(e,this._budget):e,s=this._budget?this._budget/i*a:null,r=this._phases.map(l=>{let c=Bt[l.phase]||{color:"var(--loki-text-muted)",label:l.phase},p=(l.cost_usd||0)/i*a,u=this._hoveredPhase===l.phase;return`
12565
+ `;return}let e=Math.max(...this._phases.map(l=>l.cost_usd||0),.01),i=160,a=this._budget?Math.max(e,this._budget):e,s=this._budget?this._budget/a*i:null,r=this._phases.map(l=>{let c=Pt[l.phase]||{color:"var(--loki-text-muted)",label:l.phase},p=(l.cost_usd||0)/a*i,u=this._hoveredPhase===l.phase;return`
12554
12566
  <div class="bar-group">
12555
12567
  <span class="bar-value">${this._formatCost(l.cost_usd)}</span>
12556
12568
  <div class="waterfall-bar" data-phase="${this._escapeHtml(l.phase)}"
@@ -12562,7 +12574,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
12562
12574
  <div class="budget-line" style="bottom: ${s+40}px;">
12563
12575
  <span class="budget-label">Budget: ${this._formatCost(this._budget)}</span>
12564
12576
  </div>
12565
- `:"",n=this._phases.map(l=>{let c=Bt[l.phase]||{color:"var(--loki-text-muted)",label:l.phase},p=this._totalCost>0?(l.cost_usd/this._totalCost*100).toFixed(0):0;return`<div class="summary-item">
12577
+ `:"",n=this._phases.map(l=>{let c=Pt[l.phase]||{color:"var(--loki-text-muted)",label:l.phase},p=this._totalCost>0?(l.cost_usd/this._totalCost*100).toFixed(0):0;return`<div class="summary-item">
12566
12578
  <div class="summary-dot" style="background: ${c.color};"></div>
12567
12579
  <span class="summary-label">${c.label}</span>
12568
12580
  <span class="summary-value">${this._formatCost(l.cost_usd)} (${p}%)</span>
@@ -12584,7 +12596,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
12584
12596
  </div>
12585
12597
  </div>
12586
12598
  </div>
12587
- `,this._bindEvents()}};customElements.get("loki-cost-waterfall")||customElements.define("loki-cost-waterfall",ft);var ze={1:{bg:"rgba(212, 160, 60, 0.15)",border:"#D4A03C",label:"1st"},2:{bg:"rgba(147, 144, 132, 0.15)",border:"#939084",label:"2nd"},3:{bg:"rgba(196, 130, 91, 0.15)",border:"#C4825B",label:"3rd"}},kt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._agents=[],this._expandedAgent=null,this._api=null,this._pollInterval=null,this._previousRanks={}}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,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(),1e4)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let e=(await this._api._get("/api/v2/agents/leaderboard")).agents||[],a={};e.forEach((i,s)=>{a[i.type||i.name]=s+1}),this._previousRanks={...this._currentRanks||{}},this._currentRanks=a,this._agents=e}catch{this._agents.length===0&&(this._agents=this._getDemoData(),this._currentRanks={},this._agents.forEach((t,e)=>{this._currentRanks[t.type]=e+1}),this._previousRanks={})}this.render()}_getDemoData(){return[{type:"code-generator",name:"Code Generator",tasks:24,quality:9.2,speed:"fast",cost_usd:2.4},{type:"test-writer",name:"Test Writer",tasks:18,quality:9,speed:"fast",cost_usd:1.2},{type:"code-reviewer",name:"Code Reviewer",tasks:15,quality:8.8,speed:"medium",cost_usd:1.8},{type:"architect",name:"Architect",tasks:8,quality:9.5,speed:"slow",cost_usd:3.1},{type:"debugger",name:"Debugger",tasks:12,quality:8.5,speed:"fast",cost_usd:.95},{type:"doc-writer",name:"Documentation",tasks:10,quality:8.3,speed:"fast",cost_usd:.6}]}_getRankChange(t){let e=this._currentRanks?.[t],a=this._previousRanks?.[t];return e==null||a==null?0:a-e}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_toggleAgent(t){this._expandedAgent=this._expandedAgent===t?null:t,this.render()}_bindEvents(){this.shadowRoot.querySelectorAll(".agent-row").forEach(e=>{e.addEventListener("click",()=>{this._toggleAgent(e.dataset.agent)})})}_getQualityColor(t){return t>=9?"var(--loki-green, #1FC5A8)":t>=8?"var(--loki-blue, #2F71E3)":t>=7?"var(--loki-yellow, #D4A03C)":"var(--loki-red, #C45B5B)"}_getSpeedLabel(t){return t==="fast"?{label:"Fast",color:"var(--loki-green, #1FC5A8)"}:t==="medium"?{label:"Medium",color:"var(--loki-yellow, #D4A03C)"}:{label:"Slow",color:"var(--loki-red, #C45B5B)"}}_getStyles(){return`
12599
+ `,this._bindEvents()}};customElements.get("loki-cost-waterfall")||customElements.define("loki-cost-waterfall",ft);var He={1:{bg:"rgba(212, 160, 60, 0.15)",border:"#D4A03C",label:"1st"},2:{bg:"rgba(147, 144, 132, 0.15)",border:"#939084",label:"2nd"},3:{bg:"rgba(196, 130, 91, 0.15)",border:"#C4825B",label:"3rd"}},kt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._agents=[],this._expandedAgent=null,this._api=null,this._pollInterval=null,this._previousRanks={}}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(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(),1e4)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let e=(await this._api._get("/api/v2/agents/leaderboard")).agents||[],i={};e.forEach((a,s)=>{i[a.type||a.name]=s+1}),this._previousRanks={...this._currentRanks||{}},this._currentRanks=i,this._agents=e}catch{this._agents.length===0&&(this._agents=this._getDemoData(),this._currentRanks={},this._agents.forEach((t,e)=>{this._currentRanks[t.type]=e+1}),this._previousRanks={})}this.render()}_getDemoData(){return[{type:"code-generator",name:"Code Generator",tasks:24,quality:9.2,speed:"fast",cost_usd:2.4},{type:"test-writer",name:"Test Writer",tasks:18,quality:9,speed:"fast",cost_usd:1.2},{type:"code-reviewer",name:"Code Reviewer",tasks:15,quality:8.8,speed:"medium",cost_usd:1.8},{type:"architect",name:"Architect",tasks:8,quality:9.5,speed:"slow",cost_usd:3.1},{type:"debugger",name:"Debugger",tasks:12,quality:8.5,speed:"fast",cost_usd:.95},{type:"doc-writer",name:"Documentation",tasks:10,quality:8.3,speed:"fast",cost_usd:.6}]}_getRankChange(t){let e=this._currentRanks?.[t],i=this._previousRanks?.[t];return e==null||i==null?0:i-e}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_toggleAgent(t){this._expandedAgent=this._expandedAgent===t?null:t,this.render()}_bindEvents(){this.shadowRoot.querySelectorAll(".agent-row").forEach(e=>{e.addEventListener("click",()=>{this._toggleAgent(e.dataset.agent)})})}_getQualityColor(t){return t>=9?"var(--loki-green, #1FC5A8)":t>=8?"var(--loki-blue, #2F71E3)":t>=7?"var(--loki-yellow, #D4A03C)":"var(--loki-red, #C45B5B)"}_getSpeedLabel(t){return t==="fast"?{label:"Fast",color:"var(--loki-green, #1FC5A8)"}:t==="medium"?{label:"Medium",color:"var(--loki-yellow, #D4A03C)"}:{label:"Slow",color:"var(--loki-red, #C45B5B)"}}_getStyles(){return`
12588
12600
  :host {
12589
12601
  display: block;
12590
12602
  }
@@ -12797,33 +12809,33 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
12797
12809
  </div>
12798
12810
  <div class="empty-state">No agent performance data available</div>
12799
12811
  </div>
12800
- `;return}let e=this._agents.map((a,i)=>{let s=i+1,r=ze[s],o=a.type||a.name,n=this._getRankChange(o),l=this._expandedAgent===o,c=this._getQualityColor(a.quality),p=this._getSpeedLabel(a.speed),u=(a.quality||0)/10*100,b;r?b=`<div class="rank-badge" style="background: ${r.bg}; color: ${r.border};">${s}</div>`:b=`<span class="rank-number" style="color: var(--loki-text-muted);">${s}</span>`;let m="";n>0?m=`<span class="rank-change rank-up">+${n}</span>`:n<0&&(m=`<span class="rank-change rank-down">${n}</span>`);let f=l?`
12812
+ `;return}let e=this._agents.map((i,a)=>{let s=a+1,r=He[s],o=i.type||i.name,n=this._getRankChange(o),l=this._expandedAgent===o,c=this._getQualityColor(i.quality),p=this._getSpeedLabel(i.speed),u=(i.quality||0)/10*100,b;r?b=`<div class="rank-badge" style="background: ${r.bg}; color: ${r.border};">${s}</div>`:b=`<span class="rank-number" style="color: var(--loki-text-muted);">${s}</span>`;let v="";n>0?v=`<span class="rank-change rank-up">+${n}</span>`:n<0&&(v=`<span class="rank-change rank-down">${n}</span>`);let f=l?`
12801
12813
  <div class="agent-detail">
12802
12814
  <div class="detail-metric">
12803
12815
  <span class="detail-label">Total Cost</span>
12804
- <span class="detail-value">$${(a.cost_usd||0).toFixed(2)}</span>
12816
+ <span class="detail-value">$${(i.cost_usd||0).toFixed(2)}</span>
12805
12817
  </div>
12806
12818
  <div class="detail-metric">
12807
12819
  <span class="detail-label">Avg Time/Task</span>
12808
- <span class="detail-value">${a.avg_time||"--"}</span>
12820
+ <span class="detail-value">${i.avg_time||"--"}</span>
12809
12821
  </div>
12810
12822
  <div class="detail-metric">
12811
12823
  <span class="detail-label">Success Rate</span>
12812
- <span class="detail-value">${a.success_rate!=null?a.success_rate+"%":"--"}</span>
12824
+ <span class="detail-value">${i.success_rate!=null?i.success_rate+"%":"--"}</span>
12813
12825
  </div>
12814
12826
  </div>
12815
12827
  `:"";return`
12816
12828
  <div class="agent-row ${s<=3?"top-3":""}" data-agent="${this._escapeHtml(o)}"
12817
12829
  style="${r?"border-left-color: "+r.border+";":""}">
12818
- <div class="rank-cell">${b}${m}</div>
12830
+ <div class="rank-cell">${b}${v}</div>
12819
12831
  <div class="agent-name-cell">
12820
- <span class="agent-name">${this._escapeHtml(a.name||a.type)}</span>
12821
- <span class="agent-type">${this._escapeHtml(a.type||"")}</span>
12832
+ <span class="agent-name">${this._escapeHtml(i.name||i.type)}</span>
12833
+ <span class="agent-type">${this._escapeHtml(i.type||"")}</span>
12822
12834
  </div>
12823
- <div class="metric-cell">${a.tasks||0}</div>
12835
+ <div class="metric-cell">${i.tasks||0}</div>
12824
12836
  <div class="metric-cell">
12825
12837
  <div class="quality-score">
12826
- <span style="color: ${c};">${(a.quality||0).toFixed(1)}</span>
12838
+ <span style="color: ${c};">${(i.quality||0).toFixed(1)}</span>
12827
12839
  <div class="quality-bar"><div class="quality-fill" style="width: ${u}%; background: ${c};"></div></div>
12828
12840
  </div>
12829
12841
  </div>
@@ -12850,12 +12862,12 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
12850
12862
  ${e}
12851
12863
  </div>
12852
12864
  </div>
12853
- `,this._bindEvents()}};customElements.get("loki-agent-leaderboard")||customElements.define("loki-agent-leaderboard",kt);var Xt=50,xt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._api=null,this._statusLoading=!1,this._statusError=null,this._status=null,this._eventsLoading=!1,this._eventsError=null,this._events=[],this._eventsSource=null,this._eventsCount=0,this._lookupId="",this._lookupLoading=!1,this._lookupError=null,this._lookupResult=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){if(e!==a)switch(t){case"api-url":this._api&&(this._api.baseUrl=a,this._loadStatus());break;case"theme":this._applyTheme(),this.render();break}}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_stopPolling(){}async _loadStatus(){this._statusLoading=!0,this._statusError=null,this.render();try{this._status=await this._api.get("/api/managed/status")}catch(t){this._statusError=t&&t.message?t.message:"Failed to load managed status",this._status=null}finally{this._statusLoading=!1}this._status&&this._status.enabled?await this._loadEvents():this.render()}async _loadEvents(t=Xt){this._eventsLoading=!0,this._eventsError=null,this.render();try{let e=await this._api.get("/api/managed/events?limit="+encodeURIComponent(t));Array.isArray(e)?(this._events=e,this._eventsCount=e.length,this._eventsSource=null):e&&typeof e=="object"?(this._events=Array.isArray(e.events)?e.events:[],this._eventsCount=typeof e.count=="number"?e.count:this._events.length,this._eventsSource=e.source||null):(this._events=[],this._eventsCount=0,this._eventsSource=null)}catch(e){this._eventsError=e&&e.message?e.message:"Failed to load managed events",this._events=[],this._eventsCount=0,this._eventsSource=null}finally{this._eventsLoading=!1,this.render()}}async _lookupMemoryVersion(){let t=(this._lookupId||"").trim();if(!t){this._lookupError="Enter a memory ID to look up",this._lookupResult=null,this.render();return}this._lookupLoading=!0,this._lookupError=null,this._lookupResult=null,this.render();try{let e="/api/managed/memory_versions/"+encodeURIComponent(t);this._lookupResult=await this._api.get(e)}catch(e){this._lookupError=e&&e.message?e.message:"Failed to load memory versions",this._lookupResult=null}finally{this._lookupLoading=!1,this.render()}}_onLookupInput(t){this._lookupId=t&&t.target?t.target.value:""}_onLookupKeyDown(t){t&&t.key==="Enter"&&(t.preventDefault(),this._lookupMemoryVersion())}_attachEventHandlers(){let t=this.shadowRoot;if(!t)return;let e=t.querySelector("#refresh-status-btn");e&&e.addEventListener("click",()=>this._loadStatus());let a=t.querySelector("#refresh-events-btn");a&&a.addEventListener("click",()=>this._loadEvents());let i=t.querySelector("#lookup-input");i&&(i.addEventListener("input",r=>this._onLookupInput(r)),i.addEventListener("keydown",r=>this._onLookupKeyDown(r)));let s=t.querySelector("#lookup-btn");s&&s.addEventListener("click",()=>this._lookupMemoryVersion())}_escapeHtml(t){return t==null?"":String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}_formatTimestamp(t){if(!t)return"";let e;return typeof t=="number"?e=new Date(t>1e12?t:t*1e3):e=new Date(t),Number.isNaN(e.getTime())?String(t):e.toISOString().replace("T"," ").replace(/\.\d+Z$/,"Z")}_renderStatusSection(){if(this._statusLoading)return'<div class="status-row muted">Loading managed memory status...</div>';if(this._statusError)return`
12865
+ `,this._bindEvents()}};customElements.get("loki-agent-leaderboard")||customElements.define("loki-agent-leaderboard",kt);var Zt=50,xt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._api=null,this._statusLoading=!1,this._statusError=null,this._status=null,this._eventsLoading=!1,this._eventsError=null,this._events=[],this._eventsSource=null,this._eventsCount=0,this._lookupId="",this._lookupLoading=!1,this._lookupError=null,this._lookupResult=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){if(e!==i)switch(t){case"api-url":this._api&&(this._api.baseUrl=i,this._loadStatus());break;case"theme":this._applyTheme(),this.render();break}}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_stopPolling(){}async _loadStatus(){this._statusLoading=!0,this._statusError=null,this.render();try{this._status=await this._api.get("/api/managed/status")}catch(t){this._statusError=t&&t.message?t.message:"Failed to load managed status",this._status=null}finally{this._statusLoading=!1}this._status&&this._status.enabled?await this._loadEvents():this.render()}async _loadEvents(t=Zt){this._eventsLoading=!0,this._eventsError=null,this.render();try{let e=await this._api.get("/api/managed/events?limit="+encodeURIComponent(t));Array.isArray(e)?(this._events=e,this._eventsCount=e.length,this._eventsSource=null):e&&typeof e=="object"?(this._events=Array.isArray(e.events)?e.events:[],this._eventsCount=typeof e.count=="number"?e.count:this._events.length,this._eventsSource=e.source||null):(this._events=[],this._eventsCount=0,this._eventsSource=null)}catch(e){this._eventsError=e&&e.message?e.message:"Failed to load managed events",this._events=[],this._eventsCount=0,this._eventsSource=null}finally{this._eventsLoading=!1,this.render()}}async _lookupMemoryVersion(){let t=(this._lookupId||"").trim();if(!t){this._lookupError="Enter a memory ID to look up",this._lookupResult=null,this.render();return}this._lookupLoading=!0,this._lookupError=null,this._lookupResult=null,this.render();try{let e="/api/managed/memory_versions/"+encodeURIComponent(t);this._lookupResult=await this._api.get(e)}catch(e){this._lookupError=e&&e.message?e.message:"Failed to load memory versions",this._lookupResult=null}finally{this._lookupLoading=!1,this.render()}}_onLookupInput(t){this._lookupId=t&&t.target?t.target.value:""}_onLookupKeyDown(t){t&&t.key==="Enter"&&(t.preventDefault(),this._lookupMemoryVersion())}_attachEventHandlers(){let t=this.shadowRoot;if(!t)return;let e=t.querySelector("#refresh-status-btn");e&&e.addEventListener("click",()=>this._loadStatus());let i=t.querySelector("#refresh-events-btn");i&&i.addEventListener("click",()=>this._loadEvents());let a=t.querySelector("#lookup-input");a&&(a.addEventListener("input",r=>this._onLookupInput(r)),a.addEventListener("keydown",r=>this._onLookupKeyDown(r)));let s=t.querySelector("#lookup-btn");s&&s.addEventListener("click",()=>this._lookupMemoryVersion())}_escapeHtml(t){return t==null?"":String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}_formatTimestamp(t){if(!t)return"";let e;return typeof t=="number"?e=new Date(t>1e12?t:t*1e3):e=new Date(t),Number.isNaN(e.getTime())?String(t):e.toISOString().replace("T"," ").replace(/\.\d+Z$/,"Z")}_renderStatusSection(){if(this._statusLoading)return'<div class="status-row muted">Loading managed memory status...</div>';if(this._statusError)return`
12854
12866
  <div class="error-banner" role="alert">
12855
12867
  <strong>Status error:</strong>
12856
12868
  <span>${this._escapeHtml(this._statusError)}</span>
12857
12869
  </div>
12858
- `;if(!this._status)return'<div class="status-row muted">No managed memory status available.</div>';let t=!!this._status.enabled,e=this._status.parent_flag,a=this._status.child_flags,i=this._status.beta_header,s=this._status.last_fallback_ts,r=a&&typeof a=="object"?Object.entries(a).map(([o,n])=>`${this._escapeHtml(o)}=${this._escapeHtml(n)}`).join(", "):a==null?"":String(a);return`
12870
+ `;if(!this._status)return'<div class="status-row muted">No managed memory status available.</div>';let t=!!this._status.enabled,e=this._status.parent_flag,i=this._status.child_flags,a=this._status.beta_header,s=this._status.last_fallback_ts,r=i&&typeof i=="object"?Object.entries(i).map(([o,n])=>`${this._escapeHtml(o)}=${this._escapeHtml(n)}`).join(", "):i==null?"":String(i);return`
12859
12871
  <div class="status-grid">
12860
12872
  <div class="status-cell">
12861
12873
  <div class="status-label">Enabled</div>
@@ -12871,7 +12883,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
12871
12883
  </div>
12872
12884
  <div class="status-cell">
12873
12885
  <div class="status-label">Beta header</div>
12874
- <div class="status-value mono">${this._escapeHtml(i||"-")}</div>
12886
+ <div class="status-value mono">${this._escapeHtml(a||"-")}</div>
12875
12887
  </div>
12876
12888
  <div class="status-cell">
12877
12889
  <div class="status-label">Last fallback</div>
@@ -12892,9 +12904,9 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
12892
12904
  <strong>Events error:</strong>
12893
12905
  <span>${this._escapeHtml(this._eventsError)}</span>
12894
12906
  </div>
12895
- `;if(!this._events.length)return'<div class="events-empty muted">No managed memory events recorded yet.</div>';let t=this._events.map(a=>{let i=this._formatTimestamp(a&&(a.ts||a.timestamp||a.time)),s=a&&(a.type||a.event_type||a.kind||"event"),r=a&&(a.memory_id||a.memoryId||a.id||""),o=a&&(a.summary||a.message||a.detail||""),n=typeof o=="string"?o:JSON.stringify(o);return`
12907
+ `;if(!this._events.length)return'<div class="events-empty muted">No managed memory events recorded yet.</div>';let t=this._events.map(i=>{let a=this._formatTimestamp(i&&(i.ts||i.timestamp||i.time)),s=i&&(i.type||i.event_type||i.kind||"event"),r=i&&(i.memory_id||i.memoryId||i.id||""),o=i&&(i.summary||i.message||i.detail||""),n=typeof o=="string"?o:JSON.stringify(o);return`
12896
12908
  <tr>
12897
- <td class="mono nowrap">${this._escapeHtml(i)}</td>
12909
+ <td class="mono nowrap">${this._escapeHtml(a)}</td>
12898
12910
  <td><span class="badge">${this._escapeHtml(s)}</span></td>
12899
12911
  <td class="mono">${this._escapeHtml(r)}</td>
12900
12912
  <td>${this._escapeHtml(n)}</td>
@@ -12922,7 +12934,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
12922
12934
  <strong>Lookup error:</strong>
12923
12935
  <span>${this._escapeHtml(this._lookupError)}</span>
12924
12936
  </div>
12925
- `;else if(this._lookupResult!==null&&this._lookupResult!==void 0){let a;try{a=JSON.stringify(this._lookupResult,null,2)}catch{a=String(this._lookupResult)}t=`<pre class="lookup-result mono">${this._escapeHtml(a)}</pre>`}return`
12937
+ `;else if(this._lookupResult!==null&&this._lookupResult!==void 0){let i;try{i=JSON.stringify(this._lookupResult,null,2)}catch{i=String(this._lookupResult)}t=`<pre class="lookup-result mono">${this._escapeHtml(i)}</pre>`}return`
12926
12938
  <div class="lookup-controls">
12927
12939
  <input
12928
12940
  id="lookup-input"
@@ -13229,7 +13241,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
13229
13241
  ${e?`
13230
13242
  <div class="section">
13231
13243
  <div class="panel-header">
13232
- <h3 class="section-title">Recent events (limit ${Xt})</h3>
13244
+ <h3 class="section-title">Recent events (limit ${Zt})</h3>
13233
13245
  <button id="refresh-events-btn" class="btn" type="button">Refresh events</button>
13234
13246
  </div>
13235
13247
  ${this._renderEventsSection()}
@@ -13241,7 +13253,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
13241
13253
  </div>
13242
13254
  `:this._statusError?"":this._renderDisabledNotice()}
13243
13255
  </div>
13244
- `,this._attachEventHandlers()}};customElements.get("loki-managed-memory-panel")||customElements.define("loki-managed-memory-panel",xt);var _t=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._items=[],this._loading=!1,this._error=null,this._activeFile=null,this._activeBody=null,this._activeBodyError=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadList(),this._pollInterval=setInterval(()=>this._loadList(),1e4)}disconnectedCallback(){super.disconnectedCallback(),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadList()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||(typeof window<"u"?window.location.origin:"");this._api=g({baseUrl:t})}async _loadList(){this._loading=!0,this._error=null;try{let t=await this._api.get("/api/escalations");this._items=Array.isArray(t&&t.escalations)?t.escalations:[]}catch(t){this._error=t&&t.message?t.message:String(t),this._items=[]}finally{this._loading=!1,this.render()}}async _openFile(t){this._activeFile=t,this._activeBody=null,this._activeBodyError=null,this.render();try{let e=(this._api.baseUrl||"")+"/api/escalations/"+encodeURIComponent(t),a=await fetch(e,{credentials:"include"});if(!a.ok)throw new Error("HTTP "+a.status);this._activeBody=await a.text()}catch(e){this._activeBodyError=e&&e.message?e.message:String(e)}this.render()}_closeFile(){this._activeFile=null,this._activeBody=null,this._activeBodyError=null,this.render()}_formatSize(t){return typeof t!="number"?"--":t<1024?t+" B":t<1024*1024?(t/1024).toFixed(1)+" KB":(t/(1024*1024)).toFixed(1)+" MB"}_formatDate(t){if(!t)return"--";try{let e=new Date(t);return isNaN(e.getTime())?t:e.toLocaleString()}catch{return t}}_escapeHtml(t){return t==null?"":String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}render(){let t=this.shadowRoot||this;if(!t)return;let e=`
13256
+ `,this._attachEventHandlers()}};customElements.get("loki-managed-memory-panel")||customElements.define("loki-managed-memory-panel",xt);var _t=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._items=[],this._loading=!1,this._error=null,this._activeFile=null,this._activeBody=null,this._activeBodyError=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadList(),this._pollInterval=setInterval(()=>this._loadList(),1e4)}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._loadList()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||(typeof window<"u"?window.location.origin:"");this._api=g({baseUrl:t})}async _loadList(){this._loading=!0,this._error=null;try{let t=await this._api.get("/api/escalations");this._items=Array.isArray(t&&t.escalations)?t.escalations:[]}catch(t){this._error=t&&t.message?t.message:String(t),this._items=[]}finally{this._loading=!1,this.render()}}async _openFile(t){this._activeFile=t,this._activeBody=null,this._activeBodyError=null,this.render();try{let e=(this._api.baseUrl||"")+"/api/escalations/"+encodeURIComponent(t),i=await fetch(e,{credentials:"include"});if(!i.ok)throw new Error("HTTP "+i.status);this._activeBody=await i.text()}catch(e){this._activeBodyError=e&&e.message?e.message:String(e)}this.render()}_closeFile(){this._activeFile=null,this._activeBody=null,this._activeBodyError=null,this.render()}_formatSize(t){return typeof t!="number"?"--":t<1024?t+" B":t<1024*1024?(t/1024).toFixed(1)+" KB":(t/(1024*1024)).toFixed(1)+" MB"}_formatDate(t){if(!t)return"--";try{let e=new Date(t);return isNaN(e.getTime())?t:e.toLocaleString()}catch{return t}}_escapeHtml(t){return t==null?"":String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}render(){let t=this.shadowRoot||this;if(!t)return;let e=`
13245
13257
  <style>
13246
13258
  :host { display: block; }
13247
13259
  .esc-wrapper {
@@ -13311,7 +13323,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
13311
13323
  border-radius: 4px;
13312
13324
  }
13313
13325
  </style>
13314
- `,a="";this._loading&&this._items.length===0?a='<div class="esc-empty">Loading escalations...</div>':this._error?a='<div class="esc-error">Failed to load escalations: '+this._escapeHtml(this._error)+"</div>":!this._items||this._items.length===0?a='<div class="esc-empty">Escalations: no events yet. Handoff/escalation markdown documents written by the runner under .loki/escalations/ will appear here.</div>':a='<div class="esc-list">'+this._items.map(n=>{let l=this._escapeHtml(n.filename||""),c=this._escapeHtml(this._formatSize(n.size_bytes)),p=this._escapeHtml(this._formatDate(n.modified_at));return'<div class="esc-item" data-filename="'+l+'"><span class="esc-name">'+l+'</span><span class="esc-meta">'+c+" &middot; "+p+"</span></div>"}).join("")+"</div>";let i="";if(this._activeFile){let o=this._escapeHtml(this._activeFile),n;this._activeBodyError?n='<div class="esc-error">Failed to load: '+this._escapeHtml(this._activeBodyError)+"</div>":this._activeBody===null?n='<div class="esc-body">Loading '+o+"...</div>":n='<div class="esc-body">'+this._escapeHtml(this._activeBody)+"</div>",i='<div class="esc-viewer"><div class="esc-viewer-header"><span class="esc-name">'+o+'</span><button class="esc-close-btn" data-action="close">Close</button></div>'+n+"</div>"}t.innerHTML=e+'<div class="esc-wrapper"><div class="esc-explain">Handoff/escalation documents written under .loki/escalations/. Click an entry to view its contents.</div>'+a+i+"</div>",t.querySelectorAll(".esc-item").forEach(o=>{o.addEventListener("click",()=>{let n=o.getAttribute("data-filename");n&&this._openFile(n)})});let r=t.querySelector('.esc-close-btn[data-action="close"]');r&&r.addEventListener("click",()=>this._closeFile())}};typeof customElements<"u"&&!customElements.get("loki-escalations")&&customElements.define("loki-escalations",_t);var yt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._transcripts=[],this._hookEvents=[],this._loading=!1,this._error=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._load(),this._pollInterval=setInterval(()=>this._load(),3e4)}disconnectedCallback(){super.disconnectedCallback(),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,this._load()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||(typeof window<"u"?window.location.origin:"");this._api=g({baseUrl:t})}async _load(){this._loading=!0,this._error=null;try{let t=await this._api.get("/api/council/transcripts?limit=10");this._transcripts=Array.isArray(t&&t.transcripts)?t.transcripts:[]}catch(t){this._error=t&&t.message?t.message:String(t),this._transcripts=[]}try{let t=await this._api.get("/api/council/transcripts?limit=20&type_prefix=claude_hook_");this._hookEvents=Array.isArray(t&&t.hook_events)?t.hook_events:[]}catch{this._hookEvents=[]}finally{this._loading=!1,this.render()}}_escapeHtml(t){return t==null?"":String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}_formatTimestamp(t){if(!t)return"--";try{let e=new Date(t);return isNaN(e.getTime())?t:e.toLocaleString()}catch{return t}}_truncate(t,e){if(!t)return"";let a=String(t);return a.length>e?a.slice(0,e)+"...":a}_verdictBadgeHtml(t){let e=String(t||"").toUpperCase();return e==="APPROVE"?'<span class="ct-badge ct-badge-approve">APPROVE</span>':e==="REJECT"?'<span class="ct-badge ct-badge-reject">REJECT</span>':e==="CANNOT_VALIDATE"?'<span class="ct-badge ct-badge-cannot">CANNOT_VALIDATE</span>':'<span class="ct-badge ct-badge-unknown">'+this._escapeHtml(e||"UNKNOWN")+"</span>"}_outcomeBadgeHtml(t){let e=String(t||"").toUpperCase();return e==="APPROVED"?'<span class="ct-badge ct-badge-approve">APPROVED</span>':e==="REJECTED"?'<span class="ct-badge ct-badge-reject">REJECTED</span>':e==="BLOCKED_BY_GATE"?'<span class="ct-badge ct-badge-blocked">BLOCKED BY GATE</span>':'<span class="ct-badge ct-badge-unknown">'+this._escapeHtml(e||"UNKNOWN")+"</span>"}_voterRowHtml(t,e){let a=t.is_contrarian===!0,i=a&&e===!0,s="ct-voter-row";a&&(s+=" ct-voter-contrarian"),i&&(s+=" ct-voter-flipped");let r=this._escapeHtml(t.name||"unknown"),o=this._verdictBadgeHtml(t.verdict),n=this._escapeHtml(this._truncate(t.reasoning,300)),l="",c="";i?(l='<span class="ct-badge ct-badge-override">OVERRIDE</span>',c=`<div class="ct-flip-caption">Devil's Advocate flipped this outcome</div>`):a&&t.triggered&&(l=`<span class="ct-badge ct-badge-da">DEVIL'S ADVOCATE</span>`);let p="";a&&Array.isArray(t.challenges)&&t.challenges.length>0&&(p='<ul class="ct-challenges">'+t.challenges.map(m=>"<li>"+this._escapeHtml(String(m))+"</li>").join("")+"</ul>");let u="";return Array.isArray(t.issues)&&t.issues.length>0&&(u='<ul class="ct-issues">'+t.issues.map(m=>{let f=this._escapeHtml(m.severity||""),x=this._escapeHtml(m.description||"");return'<li><span class="ct-issue-sev ct-issue-sev-'+f.toLowerCase()+'">'+f+"</span> "+x+"</li>"}).join("")+"</ul>"),'<div class="'+s+'"><div class="ct-voter-header"><span class="ct-voter-name">'+r+"</span>"+o+l+"</div>"+(n?'<div class="ct-voter-reason">'+n+"</div>":"")+p+u+c+"</div>"}_transcriptCardHtml(t){let e=this._escapeHtml(String(t.iteration||"--")),a=this._escapeHtml(this._formatTimestamp(t.timestamp)),i=this._escapeHtml(this._truncate(t.task_or_prd,200)),s=this._outcomeBadgeHtml(t.outcome),r=Array.isArray(t.voters)?t.voters:[],o=r.filter(m=>!m.is_contrarian),n=r.filter(m=>m.is_contrarian),l=o.map(m=>this._voterRowHtml(m,!1)).join(""),c="";t.contrarian_triggered&&(c='<div class="ct-contrarian-section"><div class="ct-section-label">Anti-Sycophancy Check</div>'+n.map(f=>this._voterRowHtml(f,t.contrarian_flipped)).join("")+"</div>");let p=typeof t.approve_count=="number"?t.approve_count:"--",u=typeof t.reject_count=="number"?t.reject_count:"--",b=typeof t.threshold=="number"?t.threshold:"--";return'<div class="ct-card"><div class="ct-card-header"><div class="ct-card-meta"><span class="ct-iter-label">Iteration '+e+'</span><span class="ct-ts">'+a+"</span></div>"+s+"</div>"+(i?'<div class="ct-prd-preview">'+i+"</div>":"")+'<div class="ct-tally">Approve: '+p+" &middot; Reject: "+u+" &middot; Threshold: "+b+'</div><div class="ct-voters">'+l+"</div>"+c+"</div>"}render(){let t=this.shadowRoot||this;if(!t)return;let e=`
13326
+ `,i="";this._loading&&this._items.length===0?i='<div class="esc-empty">Loading escalations...</div>':this._error?i='<div class="esc-error">Failed to load escalations: '+this._escapeHtml(this._error)+"</div>":!this._items||this._items.length===0?i='<div class="esc-empty">Escalations: no events yet. Handoff/escalation markdown documents written by the runner under .loki/escalations/ will appear here.</div>':i='<div class="esc-list">'+this._items.map(n=>{let l=this._escapeHtml(n.filename||""),c=this._escapeHtml(this._formatSize(n.size_bytes)),p=this._escapeHtml(this._formatDate(n.modified_at));return'<div class="esc-item" data-filename="'+l+'"><span class="esc-name">'+l+'</span><span class="esc-meta">'+c+" &middot; "+p+"</span></div>"}).join("")+"</div>";let a="";if(this._activeFile){let o=this._escapeHtml(this._activeFile),n;this._activeBodyError?n='<div class="esc-error">Failed to load: '+this._escapeHtml(this._activeBodyError)+"</div>":this._activeBody===null?n='<div class="esc-body">Loading '+o+"...</div>":n='<div class="esc-body">'+this._escapeHtml(this._activeBody)+"</div>",a='<div class="esc-viewer"><div class="esc-viewer-header"><span class="esc-name">'+o+'</span><button class="esc-close-btn" data-action="close">Close</button></div>'+n+"</div>"}t.innerHTML=e+'<div class="esc-wrapper"><div class="esc-explain">Handoff/escalation documents written under .loki/escalations/. Click an entry to view its contents.</div>'+i+a+"</div>",t.querySelectorAll(".esc-item").forEach(o=>{o.addEventListener("click",()=>{let n=o.getAttribute("data-filename");n&&this._openFile(n)})});let r=t.querySelector('.esc-close-btn[data-action="close"]');r&&r.addEventListener("click",()=>this._closeFile())}};typeof customElements<"u"&&!customElements.get("loki-escalations")&&customElements.define("loki-escalations",_t);var yt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._transcripts=[],this._hookEvents=[],this._loading=!1,this._error=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._load(),this._pollInterval=setInterval(()=>this._load(),3e4)}disconnectedCallback(){super.disconnectedCallback(),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._load()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||(typeof window<"u"?window.location.origin:"");this._api=g({baseUrl:t})}async _load(){this._loading=!0,this._error=null;try{let t=await this._api.get("/api/council/transcripts?limit=10");this._transcripts=Array.isArray(t&&t.transcripts)?t.transcripts:[]}catch(t){this._error=t&&t.message?t.message:String(t),this._transcripts=[]}try{let t=await this._api.get("/api/council/transcripts?limit=20&type_prefix=claude_hook_");this._hookEvents=Array.isArray(t&&t.hook_events)?t.hook_events:[]}catch{this._hookEvents=[]}finally{this._loading=!1,this.render()}}_escapeHtml(t){return t==null?"":String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}_formatTimestamp(t){if(!t)return"--";try{let e=new Date(t);return isNaN(e.getTime())?t:e.toLocaleString()}catch{return t}}_truncate(t,e){if(!t)return"";let i=String(t);return i.length>e?i.slice(0,e)+"...":i}_verdictBadgeHtml(t){let e=String(t||"").toUpperCase();return e==="APPROVE"?'<span class="ct-badge ct-badge-approve">APPROVE</span>':e==="REJECT"?'<span class="ct-badge ct-badge-reject">REJECT</span>':e==="CANNOT_VALIDATE"?'<span class="ct-badge ct-badge-cannot">CANNOT_VALIDATE</span>':'<span class="ct-badge ct-badge-unknown">'+this._escapeHtml(e||"UNKNOWN")+"</span>"}_outcomeBadgeHtml(t){let e=String(t||"").toUpperCase();return e==="APPROVED"?'<span class="ct-badge ct-badge-approve">APPROVED</span>':e==="REJECTED"?'<span class="ct-badge ct-badge-reject">REJECTED</span>':e==="BLOCKED_BY_GATE"?'<span class="ct-badge ct-badge-blocked">BLOCKED BY GATE</span>':'<span class="ct-badge ct-badge-unknown">'+this._escapeHtml(e||"UNKNOWN")+"</span>"}_voterRowHtml(t,e){let i=t.is_contrarian===!0,a=i&&e===!0,s="ct-voter-row";i&&(s+=" ct-voter-contrarian"),a&&(s+=" ct-voter-flipped");let r=this._escapeHtml(t.name||"unknown"),o=this._verdictBadgeHtml(t.verdict),n=this._escapeHtml(this._truncate(t.reasoning,300)),l="",c="";a?(l='<span class="ct-badge ct-badge-override">OVERRIDE</span>',c=`<div class="ct-flip-caption">Devil's Advocate flipped this outcome</div>`):i&&t.triggered&&(l=`<span class="ct-badge ct-badge-da">DEVIL'S ADVOCATE</span>`);let p="";i&&Array.isArray(t.challenges)&&t.challenges.length>0&&(p='<ul class="ct-challenges">'+t.challenges.map(v=>"<li>"+this._escapeHtml(String(v))+"</li>").join("")+"</ul>");let u="";return Array.isArray(t.issues)&&t.issues.length>0&&(u='<ul class="ct-issues">'+t.issues.map(v=>{let f=this._escapeHtml(v.severity||""),x=this._escapeHtml(v.description||"");return'<li><span class="ct-issue-sev ct-issue-sev-'+f.toLowerCase()+'">'+f+"</span> "+x+"</li>"}).join("")+"</ul>"),'<div class="'+s+'"><div class="ct-voter-header"><span class="ct-voter-name">'+r+"</span>"+o+l+"</div>"+(n?'<div class="ct-voter-reason">'+n+"</div>":"")+p+u+c+"</div>"}_transcriptCardHtml(t){let e=this._escapeHtml(String(t.iteration||"--")),i=this._escapeHtml(this._formatTimestamp(t.timestamp)),a=this._escapeHtml(this._truncate(t.task_or_prd,200)),s=this._outcomeBadgeHtml(t.outcome),r=Array.isArray(t.voters)?t.voters:[],o=r.filter(v=>!v.is_contrarian),n=r.filter(v=>v.is_contrarian),l=o.map(v=>this._voterRowHtml(v,!1)).join(""),c="";t.contrarian_triggered&&(c='<div class="ct-contrarian-section"><div class="ct-section-label">Anti-Sycophancy Check</div>'+n.map(f=>this._voterRowHtml(f,t.contrarian_flipped)).join("")+"</div>");let p=typeof t.approve_count=="number"?t.approve_count:"--",u=typeof t.reject_count=="number"?t.reject_count:"--",b=typeof t.threshold=="number"?t.threshold:"--";return'<div class="ct-card"><div class="ct-card-header"><div class="ct-card-meta"><span class="ct-iter-label">Iteration '+e+'</span><span class="ct-ts">'+i+"</span></div>"+s+"</div>"+(a?'<div class="ct-prd-preview">'+a+"</div>":"")+'<div class="ct-tally">Approve: '+p+" &middot; Reject: "+u+" &middot; Threshold: "+b+'</div><div class="ct-voters">'+l+"</div>"+c+"</div>"}render(){let t=this.shadowRoot||this;if(!t)return;let e=`
13315
13327
  <style>
13316
13328
  :host { display: block; margin-top: 24px; }
13317
13329
  .ct-wrapper {
@@ -13480,7 +13492,59 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
13480
13492
  .ct-badge-da { background: #fdf3d4; color: #8a6c0e; }
13481
13493
  .ct-badge-unknown { background: var(--bg-secondary, #F8F4F0); color: var(--text-muted, #939084); }
13482
13494
  </style>
13483
- `,a="";this._loading&&this._transcripts.length===0?a='<div class="ct-empty">Loading council transcripts...</div>':this._error?a='<div class="ct-error">Failed to load transcripts: '+this._escapeHtml(this._error)+"</div>":!this._transcripts||this._transcripts.length===0?a='<div class="ct-empty">No council rounds recorded yet -- transcripts appear after the first iteration vote.</div>':a='<div class="ct-list">'+this._transcripts.map(s=>this._transcriptCardHtml(s)).join("")+"</div>",t.innerHTML=e+'<div class="ct-wrapper"><h3 class="ct-heading">Council Transcripts</h3><div class="ct-explain">Per-iteration voting records from .loki/council/transcripts/. Polls every 30 seconds.</div>'+a+this._hookEventsHtml()+"</div>"}_hookEventsHtml(){let t=Array.isArray(this._hookEvents)?this._hookEvents:[],e;return t.length===0?e='<div class="ct-empty">No live tool activity yet -- Claude hook events stream here while a run is active.</div>':e='<div class="ct-voters">'+t.slice(0,20).map(i=>{let s=this._escapeHtml(i.type||i.event||"event"),r=this._escapeHtml(this._formatTimestamp(i.timestamp||i.ts)),o=this._escapeHtml(this._truncate(i.tool||i.message||i.summary||(i.data?JSON.stringify(i.data):""),120));return'<div class="ct-voter-row"><span class="ct-iter-label">'+s+'</span> <span class="ct-ts">'+r+"</span>"+(o?'<div class="ct-prd-preview">'+o+"</div>":"")+"</div>"}).join("")+"</div>",'<h3 class="ct-heading" style="margin-top:24px;">Live Tool Activity</h3><div class="ct-explain">Claude hook events (PreToolUse / PostToolUse / Stop) streamed from .loki/events.jsonl. Lets you watch background tool calls as they run.</div>'+e}};typeof customElements<"u"&&!customElements.get("loki-council-transcripts")&&customElements.define("loki-council-transcripts",yt);var He="1.4.0";function Re(d={}){return d.theme?_.setTheme(d.theme):d.autoDetectContext!==!1?_.init():R.init(),d.apiUrl&&g({baseUrl:d.apiUrl}),{theme:_.getTheme(),context:_.detectContext()}}return le(Be);})();
13495
+ `,i="";this._loading&&this._transcripts.length===0?i='<div class="ct-empty">Loading council transcripts...</div>':this._error?i='<div class="ct-error">Failed to load transcripts: '+this._escapeHtml(this._error)+"</div>":!this._transcripts||this._transcripts.length===0?i='<div class="ct-empty">No council rounds recorded yet -- transcripts appear after the first iteration vote.</div>':i='<div class="ct-list">'+this._transcripts.map(s=>this._transcriptCardHtml(s)).join("")+"</div>",t.innerHTML=e+'<div class="ct-wrapper"><h3 class="ct-heading">Council Transcripts</h3><div class="ct-explain">Per-iteration voting records from .loki/council/transcripts/. Polls every 30 seconds.</div>'+i+this._hookEventsHtml()+"</div>"}_hookEventsHtml(){let t=Array.isArray(this._hookEvents)?this._hookEvents:[],e;return t.length===0?e='<div class="ct-empty">No live tool activity yet -- Claude hook events stream here while a run is active.</div>':e='<div class="ct-voters">'+t.slice(0,20).map(a=>{let s=this._escapeHtml(a.type||a.event||"event"),r=this._escapeHtml(this._formatTimestamp(a.timestamp||a.ts)),o=this._escapeHtml(this._truncate(a.tool||a.message||a.summary||(a.data?JSON.stringify(a.data):""),120));return'<div class="ct-voter-row"><span class="ct-iter-label">'+s+'</span> <span class="ct-ts">'+r+"</span>"+(o?'<div class="ct-prd-preview">'+o+"</div>":"")+"</div>"}).join("")+"</div>",'<h3 class="ct-heading" style="margin-top:24px;">Live Tool Activity</h3><div class="ct-explain">Claude hook events (PreToolUse / PostToolUse / Stop) streamed from .loki/events.jsonl. Lets you watch background tool calls as they run.</div>'+e}};typeof customElements<"u"&&!customElements.get("loki-council-transcripts")&&customElements.define("loki-council-transcripts",yt);var Re=[{id:"overview",label:"Overview"},{id:"architecture",label:"Architecture"},{id:"modules",label:"Key Modules"},{id:"data-flow",label:"Data Flow"},{id:"ask",label:"Ask"}],wt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._activeTab="overview",this._loading=!1,this._error=null,this._api=null,this._meta=null,this._sectionCache={},this._question="",this._answer=null,this._asking=!1,this._askError=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadMeta()}attributeChangedCallback(t,e,i){t==="api-url"&&this._api&&(this._api.baseUrl=i)}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _loadMeta(){this._loading=!0,this._error=null,this.render();try{this._meta=await this._api._get("/api/wiki")}catch(t){this._error=t&&t.message?t.message:"Failed to load wiki"}finally{this._loading=!1,this.render()}}async _loadSection(t){if(this._sectionCache[t])return this._sectionCache[t];try{let e=await this._api._get(`/api/wiki/${encodeURIComponent(t)}`);return this._sectionCache[t]=e,e}catch(e){return this._sectionCache[t]={error:e&&e.message||"load failed"},this._sectionCache[t]}}async _selectTab(t){this._activeTab=t,(t==="architecture"||t==="modules"||t==="data-flow")&&(this.render(),await this._loadSection(t)),this.render()}async _ask(){let t=(this._question||"").trim();if(t){this._asking=!0,this._askError=null,this._answer=null,this.render();try{this._answer=await this._api._post("/api/wiki/ask",{question:t})}catch(e){this._askError=e&&e.message?e.message:"Ask failed"}finally{this._asking=!1,this.render()}}}_esc(t){return String(t??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}_renderCitations(t){return!t||!t.length?"":`<div class="cites"><strong>Sources:</strong><ul>${t.map(i=>`<li><code>${this._esc(i.file)}:${this._esc(i.line)}</code></li>`).join("")}</ul></div>`}_renderOverview(){let t=this._meta;if(!t||!t.generated)return`<div class="empty">
13496
+ <p>No wiki has been generated for this project yet.</p>
13497
+ <p>Run <code>loki wiki generate</code> to build a cited codebase wiki.</p>
13498
+ </div>`;let e=(t.sections||[]).map(i=>`<li>${this._esc(i.title)} <span class="dim">(${this._esc(i.citation_count)} citations)</span></li>`).join("");return`<div class="overview">
13499
+ <p><strong>${this._esc(t.project||"Project")}</strong> wiki -
13500
+ ${this._esc(t.file_count||0)} source files indexed.</p>
13501
+ <p class="dim">Generated: ${this._esc(t.generated_at||"unknown")}</p>
13502
+ <ul>${e}</ul>
13503
+ </div>`}_renderSection(t){let e=this._sectionCache[t];return e?e.error?`<div class="error">${this._esc(e.error)}</div>`:`<div class="section">
13504
+ <h3>${this._esc(e.title)}</h3>
13505
+ <pre class="body">${this._esc(e.body)}</pre>
13506
+ ${this._renderCitations(e.citations)}
13507
+ </div>`:'<div class="empty">Loading...</div>'}_renderAsk(){let t="";if(this._asking)t='<div class="empty">Searching the codebase...</div>';else if(this._askError)t=`<div class="error">${this._esc(this._askError)}</div>`;else if(this._answer){let e=this._answer.note?`<p class="dim">${this._esc(this._answer.note)}</p>`:"";t=`<div class="answer">
13508
+ <pre class="body">${this._esc(this._answer.answer||"")}</pre>
13509
+ ${e}
13510
+ ${this._renderCitations(this._answer.citations)}
13511
+ </div>`}return`<div class="ask">
13512
+ <div class="ask-row">
13513
+ <input id="wiki-q" type="text" placeholder="Ask about this codebase..."
13514
+ value="${this._esc(this._question)}" />
13515
+ <button id="wiki-ask-btn">Ask</button>
13516
+ </div>
13517
+ <p class="dim">Answers are grounded in the indexed codebase and cite real file:line locations.</p>
13518
+ ${t}
13519
+ </div>`}_renderBody(){if(this._loading)return'<div class="empty">Loading wiki...</div>';if(this._error)return`<div class="error">${this._esc(this._error)}</div>`;switch(this._activeTab){case"overview":return this._renderOverview();case"architecture":return this._renderSection("architecture");case"modules":return this._renderSection("modules");case"data-flow":return this._renderSection("data-flow");case"ask":return this._renderAsk();default:return this._renderOverview()}}render(){if(!this.shadowRoot)return;let t=Re.map(a=>`<button class="tab ${a.id===this._activeTab?"active":""}"
13520
+ data-tab="${a.id}">${this._esc(a.label)}</button>`).join("");this.shadowRoot.innerHTML=`
13521
+ <style>
13522
+ :host { display: block; font-family: var(--loki-font, system-ui, sans-serif);
13523
+ color: var(--loki-fg, #1a1a1a); }
13524
+ .tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--loki-border, #ddd);
13525
+ margin-bottom: 12px; flex-wrap: wrap; }
13526
+ .tab { background: none; border: none; padding: 8px 14px; cursor: pointer;
13527
+ font-size: 0.9rem; color: var(--loki-fg-dim, #666); border-bottom: 2px solid transparent; }
13528
+ .tab.active { color: var(--loki-accent, #2563eb); border-bottom-color: var(--loki-accent, #2563eb); }
13529
+ .body { white-space: pre-wrap; word-break: break-word; font-family: inherit;
13530
+ background: var(--loki-bg-alt, #f6f8fa); padding: 12px; border-radius: 6px; }
13531
+ .cites { margin-top: 10px; font-size: 0.85rem; }
13532
+ .cites ul { margin: 4px 0 0; padding-left: 18px; }
13533
+ code { font-family: ui-monospace, monospace; font-size: 0.85em;
13534
+ background: var(--loki-bg-alt, #eef); padding: 1px 4px; border-radius: 3px; }
13535
+ .dim { color: var(--loki-fg-dim, #888); }
13536
+ .empty, .error { padding: 16px; }
13537
+ .error { color: var(--loki-danger, #c00); }
13538
+ .ask-row { display: flex; gap: 8px; margin-bottom: 8px; }
13539
+ #wiki-q { flex: 1; padding: 8px; border: 1px solid var(--loki-border, #ccc);
13540
+ border-radius: 6px; font-size: 0.9rem; }
13541
+ #wiki-ask-btn { padding: 8px 16px; border: none; border-radius: 6px;
13542
+ background: var(--loki-accent, #2563eb); color: #fff; cursor: pointer; }
13543
+ h3 { margin-top: 0; }
13544
+ </style>
13545
+ <div class="tabs">${t}</div>
13546
+ <div class="content">${this._renderBody()}</div>
13547
+ `,this.shadowRoot.querySelectorAll(".tab").forEach(a=>{a.addEventListener("click",()=>this._selectTab(a.dataset.tab))});let e=this.shadowRoot.getElementById("wiki-q");e&&(e.addEventListener("input",a=>{this._question=a.target.value}),e.addEventListener("keydown",a=>{a.key==="Enter"&&this._ask()}));let i=this.shadowRoot.getElementById("wiki-ask-btn");i&&i.addEventListener("click",()=>this._ask())}};customElements.get("loki-wiki-browser")||customElements.define("loki-wiki-browser",wt);var Be="1.4.0";function Pe(d={}){return d.theme?_.setTheme(d.theme):d.autoDetectContext!==!1?_.init():R.init(),d.apiUrl&&g({baseUrl:d.apiUrl}),{theme:_.getTheme(),context:_.detectContext()}}return de(Me);})();
13484
13548
 
13485
13549
 
13486
13550
  // Initialize dashboard when DOM is ready
@@ -13623,7 +13687,8 @@ document.addEventListener('DOMContentLoaded', function() {
13623
13687
  'migration-dashboard',
13624
13688
  'analytics-dashboard',
13625
13689
  'escalations-panel',
13626
- 'council-transcripts'
13690
+ 'council-transcripts',
13691
+ 'wiki-browser'
13627
13692
  ];
13628
13693
  components.forEach(function(id) {
13629
13694
  var el = document.getElementById(id);