loki-mode 7.18.3 → 7.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1218,7 +1218,7 @@
1218
1218
 
1219
1219
  <!-- Inlined JavaScript Bundle -->
1220
1220
  <script>
1221
- var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropertyDescriptor;var se=Object.getOwnPropertyNames;var re=Object.prototype.hasOwnProperty;var oe=(d,t,e)=>t in d?$t(d,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):d[t]=e;var ne=(d,t)=>{for(var e in t)$t(d,e,{get:t[e],enumerable:!0})},le=(d,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of se(t))!re.call(d,a)&&a!==e&&$t(d,a,{get:()=>t[a],enumerable:!(i=ae(t,a))||i.enumerable});return d};var de=d=>le($t({},"__esModule",{value:!0}),d);var C=(d,t,e)=>oe(d,typeof t!="symbol"?t+"":t,e);var Me={};ne(Me,{ANIMATION:()=>L,ARIA_PATTERNS:()=>St,ApiEvents:()=>v,BASE_STYLES:()=>U,BREAKPOINTS:()=>Et,COMMON_STYLES:()=>Mt,KEYBOARD_SHORTCUTS:()=>Ct,KeyboardHandler:()=>P,LokiActivityStream:()=>ut,LokiAgentLeaderboard:()=>kt,LokiAnalytics:()=>ot,LokiApiClient:()=>M,LokiApiKeys:()=>pt,LokiAppStatus:()=>Q,LokiAuditViewer:()=>ct,LokiChecklistViewer:()=>W,LokiCheckpointViewer:()=>Z,LokiContextTracker:()=>tt,LokiCostDashboard:()=>X,LokiCostWaterfall:()=>ft,LokiCouncilDashboard:()=>Y,LokiCouncilTranscripts:()=>yt,LokiElement:()=>h,LokiEscalations:()=>_t,LokiLearningDashboard:()=>V,LokiLogStream:()=>G,LokiManagedMemoryPanel:()=>xt,LokiMemoryBrowser:()=>K,LokiMemoryGraph:()=>bt,LokiMigrationDashboard:()=>rt,LokiNotificationCenter:()=>et,LokiOverview:()=>O,LokiPipelineView:()=>mt,LokiPromptOptimizer:()=>at,LokiProviderHealth:()=>gt,LokiQualityGates:()=>nt,LokiQualityScore:()=>st,LokiRarvTimeline:()=>lt,LokiRunManager:()=>dt,LokiSessionControl:()=>J,LokiSessionDiff:()=>it,LokiState:()=>N,LokiTaskBoard:()=>q,LokiTenantSwitcher:()=>ht,LokiTheme:()=>R,LokiWikiBrowser:()=>wt,RADIUS:()=>I,SPACING:()=>A,STATE_CHANGE_EVENT:()=>It,THEMES:()=>E,THEME_VARIABLES:()=>At,TYPOGRAPHY:()=>y,UnifiedThemeManager:()=>_,VERSION:()=>Be,Z_INDEX:()=>D,createApiClient:()=>Ut,createStore:()=>Nt,generateThemeCSS:()=>$,generateTokensCSS:()=>j,getApiClient:()=>g,getState:()=>B,init:()=>Pe});var E={light:{"--loki-bg-primary":"#FFFEFB","--loki-bg-secondary":"#F8F4F0","--loki-bg-tertiary":"#ECEAE3","--loki-bg-card":"#ffffff","--loki-bg-hover":"#F3EFE9","--loki-bg-active":"#E6E2DA","--loki-bg-overlay":"rgba(32, 21, 21, 0.5)","--loki-accent":"#553DE9","--loki-accent-hover":"#4432c4","--loki-accent-active":"#3828a0","--loki-accent-light":"#7B6BF0","--loki-accent-muted":"rgba(85, 61, 233, 0.10)","--loki-text-primary":"#201515","--loki-text-secondary":"#36342E","--loki-text-muted":"#939084","--loki-text-disabled":"#C5C0B1","--loki-text-inverse":"#ffffff","--loki-border":"#ECEAE3","--loki-border-light":"#C5C0B1","--loki-border-focus":"#553DE9","--loki-success":"#1FC5A8","--loki-success-muted":"rgba(31, 197, 168, 0.12)","--loki-warning":"#D4A03C","--loki-warning-muted":"rgba(212, 160, 60, 0.12)","--loki-error":"#C45B5B","--loki-error-muted":"rgba(196, 91, 91, 0.12)","--loki-info":"#2F71E3","--loki-info-muted":"rgba(47, 113, 227, 0.12)","--loki-green":"#1FC5A8","--loki-green-muted":"rgba(31, 197, 168, 0.12)","--loki-yellow":"#D4A03C","--loki-yellow-muted":"rgba(212, 160, 60, 0.12)","--loki-red":"#C45B5B","--loki-red-muted":"rgba(196, 91, 91, 0.12)","--loki-blue":"#2F71E3","--loki-blue-muted":"rgba(47, 113, 227, 0.12)","--loki-purple":"#553DE9","--loki-purple-muted":"rgba(85, 61, 233, 0.10)","--loki-opus":"#d97706","--loki-sonnet":"#553DE9","--loki-haiku":"#1FC5A8","--loki-shadow-sm":"0 1px 2px rgba(32, 21, 21, 0.04)","--loki-shadow-md":"0 4px 6px rgba(32, 21, 21, 0.06)","--loki-shadow-lg":"0 10px 15px rgba(32, 21, 21, 0.08)","--loki-shadow-focus":"0 0 0 3px rgba(85, 61, 233, 0.25)"},dark:{"--loki-bg-primary":"#1A0F2E","--loki-bg-secondary":"#140B24","--loki-bg-tertiary":"#251842","--loki-bg-card":"#1F1338","--loki-bg-hover":"#2A1F4A","--loki-bg-active":"#352A55","--loki-bg-overlay":"rgba(20, 11, 36, 0.85)","--loki-accent":"#7B6BF0","--loki-accent-hover":"#9488F5","--loki-accent-active":"#6258D0","--loki-accent-light":"#9488F5","--loki-accent-muted":"rgba(123, 107, 240, 0.18)","--loki-text-primary":"#F0ECF8","--loki-text-secondary":"#C0B8D0","--loki-text-muted":"#8B7FA8","--loki-text-disabled":"#5A4E78","--loki-text-inverse":"#1A0F2E","--loki-border":"#2A1F3E","--loki-border-light":"#3D3060","--loki-border-focus":"#7B6BF0","--loki-success":"#2ED8B6","--loki-success-muted":"rgba(46, 216, 182, 0.18)","--loki-warning":"#E8B84A","--loki-warning-muted":"rgba(232, 184, 74, 0.18)","--loki-error":"#E07070","--loki-error-muted":"rgba(224, 112, 112, 0.18)","--loki-info":"#5A9CF5","--loki-info-muted":"rgba(90, 156, 245, 0.18)","--loki-green":"#2ED8B6","--loki-green-muted":"rgba(46, 216, 182, 0.18)","--loki-yellow":"#E8B84A","--loki-yellow-muted":"rgba(232, 184, 74, 0.18)","--loki-red":"#E07070","--loki-red-muted":"rgba(224, 112, 112, 0.18)","--loki-blue":"#5A9CF5","--loki-blue-muted":"rgba(90, 156, 245, 0.18)","--loki-purple":"#9488F5","--loki-purple-muted":"rgba(148, 136, 245, 0.18)","--loki-opus":"#f59e0b","--loki-sonnet":"#7B6BF0","--loki-haiku":"#2ED8B6","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.4)","--loki-shadow-md":"0 4px 12px rgba(0, 0, 0, 0.5)","--loki-shadow-lg":"0 10px 25px rgba(0, 0, 0, 0.6)","--loki-shadow-focus":"0 0 0 3px rgba(123, 107, 240, 0.30)"},"high-contrast":{"--loki-bg-primary":"#000000","--loki-bg-secondary":"#0a0a0a","--loki-bg-tertiary":"#141414","--loki-bg-card":"#0a0a0a","--loki-bg-hover":"#1a1a1a","--loki-bg-active":"#242424","--loki-bg-overlay":"rgba(0, 0, 0, 0.9)","--loki-accent":"#c084fc","--loki-accent-hover":"#d8b4fe","--loki-accent-active":"#e9d5ff","--loki-accent-light":"#d8b4fe","--loki-accent-muted":"rgba(192, 132, 252, 0.25)","--loki-text-primary":"#ffffff","--loki-text-secondary":"#e0e0e0","--loki-text-muted":"#b0b0b0","--loki-text-disabled":"#666666","--loki-text-inverse":"#000000","--loki-border":"#ffffff","--loki-border-light":"#cccccc","--loki-border-focus":"#c084fc","--loki-success":"#4ade80","--loki-success-muted":"rgba(74, 222, 128, 0.25)","--loki-warning":"#fde047","--loki-warning-muted":"rgba(253, 224, 71, 0.25)","--loki-error":"#f87171","--loki-error-muted":"rgba(248, 113, 113, 0.25)","--loki-info":"#60a5fa","--loki-info-muted":"rgba(96, 165, 250, 0.25)","--loki-green":"#4ade80","--loki-green-muted":"rgba(74, 222, 128, 0.25)","--loki-yellow":"#fde047","--loki-yellow-muted":"rgba(253, 224, 71, 0.25)","--loki-red":"#f87171","--loki-red-muted":"rgba(248, 113, 113, 0.25)","--loki-blue":"#60a5fa","--loki-blue-muted":"rgba(96, 165, 250, 0.25)","--loki-purple":"#c084fc","--loki-purple-muted":"rgba(192, 132, 252, 0.25)","--loki-opus":"#fbbf24","--loki-sonnet":"#818cf8","--loki-haiku":"#34d399","--loki-shadow-sm":"none","--loki-shadow-md":"none","--loki-shadow-lg":"none","--loki-shadow-focus":"0 0 0 3px #c084fc"},"vscode-light":{"--loki-bg-primary":"var(--vscode-editor-background, #ffffff)","--loki-bg-secondary":"var(--vscode-sideBar-background, #f3f3f3)","--loki-bg-tertiary":"var(--vscode-input-background, #ffffff)","--loki-bg-card":"var(--vscode-editor-background, #ffffff)","--loki-bg-hover":"var(--vscode-list-hoverBackground, #e8e8e8)","--loki-bg-active":"var(--vscode-list-activeSelectionBackground, #0060c0)","--loki-bg-overlay":"rgba(0, 0, 0, 0.4)","--loki-accent":"var(--vscode-focusBorder, #0066cc)","--loki-accent-hover":"var(--vscode-button-hoverBackground, #0055aa)","--loki-accent-active":"var(--vscode-button-background, #007acc)","--loki-accent-light":"var(--vscode-focusBorder, #0066cc)","--loki-accent-muted":"var(--vscode-editor-selectionBackground, rgba(0, 102, 204, 0.2))","--loki-text-primary":"var(--vscode-foreground, #333333)","--loki-text-secondary":"var(--vscode-descriptionForeground, #717171)","--loki-text-muted":"var(--vscode-disabledForeground, #a0a0a0)","--loki-text-disabled":"var(--vscode-disabledForeground, #cccccc)","--loki-text-inverse":"var(--vscode-button-foreground, #ffffff)","--loki-border":"var(--vscode-widget-border, #c8c8c8)","--loki-border-light":"var(--vscode-widget-border, #e0e0e0)","--loki-border-focus":"var(--vscode-focusBorder, #0066cc)","--loki-success":"var(--vscode-testing-iconPassed, #388a34)","--loki-success-muted":"rgba(56, 138, 52, 0.15)","--loki-warning":"var(--vscode-editorWarning-foreground, #bf8803)","--loki-warning-muted":"rgba(191, 136, 3, 0.15)","--loki-error":"var(--vscode-errorForeground, #e51400)","--loki-error-muted":"rgba(229, 20, 0, 0.15)","--loki-info":"var(--vscode-editorInfo-foreground, #1a85ff)","--loki-info-muted":"rgba(26, 133, 255, 0.15)","--loki-green":"var(--vscode-testing-iconPassed, #388a34)","--loki-green-muted":"rgba(56, 138, 52, 0.15)","--loki-yellow":"var(--vscode-editorWarning-foreground, #bf8803)","--loki-yellow-muted":"rgba(191, 136, 3, 0.15)","--loki-red":"var(--vscode-errorForeground, #e51400)","--loki-red-muted":"rgba(229, 20, 0, 0.15)","--loki-blue":"var(--vscode-editorInfo-foreground, #1a85ff)","--loki-blue-muted":"rgba(26, 133, 255, 0.15)","--loki-purple":"#9333ea","--loki-purple-muted":"rgba(147, 51, 234, 0.15)","--loki-opus":"#d97706","--loki-sonnet":"#4f46e5","--loki-haiku":"#059669","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.05)","--loki-shadow-md":"0 2px 4px rgba(0, 0, 0, 0.1)","--loki-shadow-lg":"0 4px 8px rgba(0, 0, 0, 0.15)","--loki-shadow-focus":"0 0 0 2px var(--vscode-focusBorder, #0066cc)"},"vscode-dark":{"--loki-bg-primary":"var(--vscode-editor-background, #1e1e1e)","--loki-bg-secondary":"var(--vscode-sideBar-background, #252526)","--loki-bg-tertiary":"var(--vscode-input-background, #3c3c3c)","--loki-bg-card":"var(--vscode-editor-background, #1e1e1e)","--loki-bg-hover":"var(--vscode-list-hoverBackground, #2a2d2e)","--loki-bg-active":"var(--vscode-list-activeSelectionBackground, #094771)","--loki-bg-overlay":"rgba(0, 0, 0, 0.6)","--loki-accent":"var(--vscode-focusBorder, #007fd4)","--loki-accent-hover":"var(--vscode-button-hoverBackground, #1177bb)","--loki-accent-active":"var(--vscode-button-background, #0e639c)","--loki-accent-light":"var(--vscode-focusBorder, #007fd4)","--loki-accent-muted":"var(--vscode-editor-selectionBackground, rgba(0, 127, 212, 0.25))","--loki-text-primary":"var(--vscode-foreground, #cccccc)","--loki-text-secondary":"var(--vscode-descriptionForeground, #9d9d9d)","--loki-text-muted":"var(--vscode-disabledForeground, #6b6b6b)","--loki-text-disabled":"var(--vscode-disabledForeground, #4d4d4d)","--loki-text-inverse":"var(--vscode-button-foreground, #ffffff)","--loki-border":"var(--vscode-widget-border, #454545)","--loki-border-light":"var(--vscode-widget-border, #5a5a5a)","--loki-border-focus":"var(--vscode-focusBorder, #007fd4)","--loki-success":"var(--vscode-testing-iconPassed, #89d185)","--loki-success-muted":"rgba(137, 209, 133, 0.2)","--loki-warning":"var(--vscode-editorWarning-foreground, #cca700)","--loki-warning-muted":"rgba(204, 167, 0, 0.2)","--loki-error":"var(--vscode-errorForeground, #f48771)","--loki-error-muted":"rgba(244, 135, 113, 0.2)","--loki-info":"var(--vscode-editorInfo-foreground, #75beff)","--loki-info-muted":"rgba(117, 190, 255, 0.2)","--loki-green":"var(--vscode-testing-iconPassed, #89d185)","--loki-green-muted":"rgba(137, 209, 133, 0.2)","--loki-yellow":"var(--vscode-editorWarning-foreground, #cca700)","--loki-yellow-muted":"rgba(204, 167, 0, 0.2)","--loki-red":"var(--vscode-errorForeground, #f48771)","--loki-red-muted":"rgba(244, 135, 113, 0.2)","--loki-blue":"var(--vscode-editorInfo-foreground, #75beff)","--loki-blue-muted":"rgba(117, 190, 255, 0.2)","--loki-purple":"#c084fc","--loki-purple-muted":"rgba(192, 132, 252, 0.2)","--loki-opus":"#f59e0b","--loki-sonnet":"#818cf8","--loki-haiku":"#34d399","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.3)","--loki-shadow-md":"0 2px 4px rgba(0, 0, 0, 0.4)","--loki-shadow-lg":"0 4px 8px rgba(0, 0, 0, 0.5)","--loki-shadow-focus":"0 0 0 2px var(--vscode-focusBorder, #007fd4)"}},A={xs:"4px",sm:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"32px","3xl":"48px"},I={none:"0",sm:"2px",md:"4px",lg:"5px",xl:"5px",full:"9999px"},y={fontFamily:{sans:"'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif",serif:"'DM Serif Display', Georgia, 'Times New Roman', serif",mono:"'JetBrains Mono', 'Fira Code', 'SF Mono', Menlo, monospace"},fontSize:{xs:"10px",sm:"11px",base:"12px",md:"13px",lg:"14px",xl:"16px","2xl":"18px","3xl":"24px"},fontWeight:{normal:"400",medium:"500",semibold:"600",bold:"700"},lineHeight:{tight:"1.25",normal:"1.5",relaxed:"1.75"}},L={duration:{fast:"100ms",normal:"200ms",slow:"300ms",slower:"500ms"},easing:{default:"cubic-bezier(0.4, 0, 0.2, 1)",in:"cubic-bezier(0.4, 0, 1, 1)",out:"cubic-bezier(0, 0, 0.2, 1)",bounce:"cubic-bezier(0.68, -0.55, 0.265, 1.55)"}},Et={sm:"640px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},D={base:"0",dropdown:"100",sticky:"200",modal:"300",popover:"400",tooltip:"500",toast:"600"},Ct={"navigation.nextItem":{key:"ArrowDown",modifiers:[]},"navigation.prevItem":{key:"ArrowUp",modifiers:[]},"navigation.nextSection":{key:"Tab",modifiers:[]},"navigation.prevSection":{key:"Tab",modifiers:["Shift"]},"navigation.confirm":{key:"Enter",modifiers:[]},"navigation.cancel":{key:"Escape",modifiers:[]},"action.refresh":{key:"r",modifiers:["Meta"]},"action.search":{key:"k",modifiers:["Meta"]},"action.save":{key:"s",modifiers:["Meta"]},"action.close":{key:"w",modifiers:["Meta"]},"theme.toggle":{key:"d",modifiers:["Meta","Shift"]},"task.create":{key:"n",modifiers:["Meta"]},"task.complete":{key:"Enter",modifiers:["Meta"]},"view.toggleLogs":{key:"l",modifiers:["Meta","Shift"]},"view.toggleMemory":{key:"m",modifiers:["Meta","Shift"]}},St={button:{role:"button",tabIndex:0},tablist:{role:"tablist"},tab:{role:"tab",ariaSelected:!1,tabIndex:-1},tabpanel:{role:"tabpanel",tabIndex:0},list:{role:"list"},listitem:{role:"listitem"},livePolite:{ariaLive:"polite",ariaAtomic:!0},liveAssertive:{ariaLive:"assertive",ariaAtomic:!0},dialog:{role:"dialog",ariaModal:!0},alertdialog:{role:"alertdialog",ariaModal:!0},status:{role:"status",ariaLive:"polite"},alert:{role:"alert",ariaLive:"assertive"},log:{role:"log",ariaLive:"polite",ariaRelevant:"additions"}};function $(d){let t=E[d];return t?Object.entries(t).map(([e,i])=>`${e}: ${i};`).join(`
1221
+ var LokiDashboard=(()=>{var $e=Object.defineProperty;var at=Object.getOwnPropertyDescriptor;var st=Object.getOwnPropertyNames;var rt=Object.prototype.hasOwnProperty;var ot=(d,e,t)=>e in d?$e(d,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):d[e]=t;var nt=(d,e)=>{for(var t in e)$e(d,t,{get:e[t],enumerable:!0})},lt=(d,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of st(e))!rt.call(d,a)&&a!==t&&$e(d,a,{get:()=>e[a],enumerable:!(i=at(e,a))||i.enumerable});return d};var dt=d=>lt($e({},"__esModule",{value:!0}),d);var C=(d,e,t)=>ot(d,typeof e!="symbol"?e+"":e,t);var Mt={};nt(Mt,{ANIMATION:()=>L,ARIA_PATTERNS:()=>Se,ApiEvents:()=>v,BASE_STYLES:()=>U,BREAKPOINTS:()=>Ee,COMMON_STYLES:()=>Me,KEYBOARD_SHORTCUTS:()=>Ce,KeyboardHandler:()=>P,LokiActivityStream:()=>ue,LokiAgentLeaderboard:()=>ke,LokiAnalytics:()=>oe,LokiApiClient:()=>M,LokiApiKeys:()=>pe,LokiAppStatus:()=>Q,LokiAuditViewer:()=>ce,LokiChecklistViewer:()=>W,LokiCheckpointViewer:()=>Z,LokiContextTracker:()=>ee,LokiCostDashboard:()=>X,LokiCostWaterfall:()=>fe,LokiCouncilDashboard:()=>Y,LokiCouncilTranscripts:()=>ye,LokiElement:()=>u,LokiEscalations:()=>_e,LokiLearningDashboard:()=>V,LokiLogStream:()=>G,LokiManagedMemoryPanel:()=>xe,LokiMemoryBrowser:()=>K,LokiMemoryGraph:()=>be,LokiMigrationDashboard:()=>re,LokiNotificationCenter:()=>te,LokiOverview:()=>O,LokiPipelineView:()=>me,LokiPromptOptimizer:()=>ae,LokiProviderHealth:()=>ge,LokiQualityGates:()=>ne,LokiQualityScore:()=>se,LokiRarvTimeline:()=>le,LokiRunManager:()=>de,LokiSessionControl:()=>J,LokiSessionDiff:()=>ie,LokiState:()=>N,LokiTaskBoard:()=>q,LokiTenantSwitcher:()=>he,LokiTheme:()=>R,LokiWikiBrowser:()=>we,RADIUS:()=>I,SPACING:()=>A,STATE_CHANGE_EVENT:()=>Ie,THEMES:()=>E,THEME_VARIABLES:()=>Ae,TYPOGRAPHY:()=>y,UnifiedThemeManager:()=>_,VERSION:()=>Bt,Z_INDEX:()=>D,createApiClient:()=>Ue,createStore:()=>Ne,generateThemeCSS:()=>$,generateTokensCSS:()=>j,getApiClient:()=>g,getState:()=>B,init:()=>Pt});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)"}},Ee={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"},Ce={"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"]}},Se={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 e=E[d];return e?Object.entries(e).map(([t,i])=>`${t}: ${i};`).join(`
1222
1222
  `):""}function j(){return`
1223
1223
  /* Spacing */
1224
1224
  --loki-space-xs: ${A.xs};
@@ -1545,20 +1545,20 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
1545
1545
  }
1546
1546
 
1547
1547
  /* Responsive utilities */
1548
- @media (max-width: ${Et.md}) {
1548
+ @media (max-width: ${Ee.md}) {
1549
1549
  .hide-mobile { display: none !important; }
1550
1550
  }
1551
1551
 
1552
- @media (min-width: ${Et.md}) {
1552
+ @media (min-width: ${Ee.md}) {
1553
1553
  .hide-desktop { display: none !important; }
1554
1554
  }
1555
- `,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`
1555
+ `,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 e=document.body;if(e.classList.contains("vscode-high-contrast"))return"high-contrast";if(e.classList.contains("vscode-dark"))return"dark";if(e.classList.contains("vscode-light"))return"light";let t=getComputedStyle(document.documentElement).getPropertyValue("--vscode-editor-background");if(t){let i=t.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 t=localStorage.getItem(k.STORAGE_KEY);return t&&E[t]?t:window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}static setTheme(e){if(!E[e]){console.warn(`Unknown theme: ${e}`);return}localStorage.setItem(k.STORAGE_KEY,e),document.documentElement.setAttribute("data-loki-theme",e),window.dispatchEvent(new CustomEvent("loki-theme-change",{detail:{theme:e,context:k.detectContext()}}))}static toggle(){let e=k.getTheme(),t;return e.includes("dark")||e==="high-contrast"?t=e.startsWith("vscode")?"vscode-light":"light":t=e.startsWith("vscode")?"vscode-dark":"dark",k.setTheme(t),t}static getVariables(e=null){let t=e||k.getTheme();return E[t]||E.light}static generateCSS(e=null){let t=e||k.getTheme();return`
1556
1556
  :host {
1557
- ${$(e)}
1557
+ ${$(t)}
1558
1558
  ${j()}
1559
1559
  }
1560
1560
  ${U}
1561
- `}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=`
1561
+ `}static init(){let e=k.getTheme();document.documentElement.setAttribute("data-loki-theme",e),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(e,t){let i=Ce[e];if(!i){console.warn(`Unknown keyboard action: ${e}`);return}this._handlers.set(e,{shortcut:i,handler:t})}unregister(e){this._handlers.delete(e)}setEnabled(e){this._enabled=e}handleEvent(e){if(!this._enabled)return!1;for(let[t,{shortcut:i,handler:a}]of this._handlers)if(this._matchesShortcut(e,i))return e.preventDefault(),e.stopPropagation(),a(e),!0;return!1}_matchesShortcut(e,t){let i=e.key.toLowerCase(),a=t.modifiers||[];if(i!==t.key.toLowerCase())return!1;let s=a.includes("Ctrl")||a.includes("Meta"),r=a.includes("Shift"),o=a.includes("Alt"),n=(e.ctrlKey||e.metaKey)===s,l=e.shiftKey===r,c=e.altKey===o;return n&&l&&c}attach(e){this._boundHandler||(this._boundHandler=t=>this.handleEvent(t)),e.addEventListener("keydown",this._boundHandler)}detach(e){this._boundHandler&&e.removeEventListener("keydown",this._boundHandler)}};var Ae={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)"}},Me=`
1562
1562
  :host {
1563
1563
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
1564
1564
  line-height: 1.5;
@@ -1654,8 +1654,8 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
1654
1654
  ::-webkit-scrollbar-track { background: var(--loki-bg-primary); }
1655
1655
  ::-webkit-scrollbar-thumb { background: var(--loki-border); border-radius: 3px; }
1656
1656
  ::-webkit-scrollbar-thumb:hover { background: var(--loki-border-light); }
1657
- `,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(`
1658
- `)}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`
1657
+ `,H=class H{static getTheme(){return _.getTheme()}static setTheme(e){_.setTheme(e)}static toggle(){return _.toggle()}static getVariables(e=null){let t=e||H.getTheme();return E[t]||Ae[t]||Ae.light}static toCSSString(e=null){let t=e||H.getTheme();if(E[t])return $(t);let i=H.getVariables(t);return Object.entries(i).map(([a,s])=>`${a}: ${s};`).join(`
1658
+ `)}static applyToElement(e,t=null){let i=H.getVariables(t);for(let[a,s]of Object.entries(i))e.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,u=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(e){this._theme=e.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(e,t){this._keyboardHandler.register(e,t)}getBaseStyles(){return`
1659
1659
  /* Design tokens */
1660
1660
  :host {
1661
1661
  ${j()}
@@ -1711,18 +1711,18 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
1711
1711
  }
1712
1712
 
1713
1713
  ${U}
1714
- `}getAriaPattern(t){return St[t]||{}}applyAriaPattern(t,e){let i=this.getAriaPattern(e);for(let[a,s]of Object.entries(i))if(a==="role")t.setAttribute("role",s);else{let r=a.replace(/([A-Z])/g,"-$1").toLowerCase();t.setAttribute(r,s)}}render(){}};var z={realtime:1e3,normal:2e3,background:5e3,offline:1e4},Ft={vscode:z.normal,browser:z.realtime,cli:z.background},jt={baseUrl:typeof window<"u"?window.location.origin:"http://localhost:57374",wsUrl:typeof window<"u"?`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/ws`:"ws://localhost:57374/ws",pollInterval:2e3,timeout:1e4,retryAttempts:3,retryDelay:1e3},v={CONNECTED:"api:connected",DISCONNECTED:"api:disconnected",ERROR:"api:error",STATUS_UPDATE:"api:status-update",TASK_CREATED:"api:task-created",TASK_UPDATED:"api:task-updated",TASK_DELETED:"api:task-deleted",PROJECT_CREATED:"api:project-created",PROJECT_UPDATED:"api:project-updated",AGENT_UPDATE:"api:agent-update",LOG_MESSAGE:"api:log-message",MEMORY_UPDATE:"api:memory-update",CHECKLIST_UPDATE:"api:checklist-update"},T=class T extends EventTarget{static getInstance(t={}){let e=t.baseUrl||jt.baseUrl;return T._instances.has(e)||T._instances.set(e,new T(t)),T._instances.get(e)}static clearInstances(){T._instances.forEach(t=>t.disconnect()),T._instances.clear()}constructor(t={}){super(),this.config={...jt,...t},this._ws=null,this._connected=!1,this._pollInterval=null,this._reconnectTimeout=null,this._reconnectAttempts=0,this._maxReconnectAttempts=20,this._cache=new Map,this._cacheTimeout=5e3,this._vscodeApi=null,this._context=this._detectContext(),this._currentPollInterval=Ft[this._context]||z.normal,this._visibilityChangeHandler=null,this._messageHandler=null,this._setupAdaptivePolling(),this._setupVSCodeBridge()}_detectContext(){return typeof acquireVsCodeApi<"u"?"vscode":typeof window<"u"&&window.location?"browser":"cli"}get context(){return this._context}static get POLL_INTERVALS(){return z}_setupAdaptivePolling(){typeof document>"u"||(this._visibilityChangeHandler=()=>{document.hidden?this._setPollInterval(z.background):this._setPollInterval(Ft[this._context]||z.normal)},document.addEventListener("visibilitychange",this._visibilityChangeHandler))}_setPollInterval(t){this._currentPollInterval=t,this._pollInterval&&(this.stopPolling(),this.startPolling(null,t))}setPollMode(t){let e=z[t];e&&this._setPollInterval(e)}_setupVSCodeBridge(){if(!(typeof acquireVsCodeApi>"u")){try{this._vscodeApi=acquireVsCodeApi()}catch{console.warn("VS Code API already acquired or unavailable");return}this._messageHandler=t=>{let e=t.data;if(!(!e||!e.type))switch(e.type){case"updateStatus":this._emit(v.STATUS_UPDATE,e.data);break;case"updateTasks":this._emit(v.TASK_UPDATED,e.data);break;case"taskCreated":this._emit(v.TASK_CREATED,e.data);break;case"taskDeleted":this._emit(v.TASK_DELETED,e.data);break;case"projectCreated":this._emit(v.PROJECT_CREATED,e.data);break;case"projectUpdated":this._emit(v.PROJECT_UPDATED,e.data);break;case"agentUpdate":this._emit(v.AGENT_UPDATE,e.data);break;case"logMessage":this._emit(v.LOG_MESSAGE,e.data);break;case"memoryUpdate":this._emit(v.MEMORY_UPDATE,e.data);break;case"connected":this._connected=!0,this._emit(v.CONNECTED,e.data);break;case"disconnected":this._connected=!1,this._emit(v.DISCONNECTED,e.data);break;case"error":this._emit(v.ERROR,e.data);break;case"setPollMode":this.setPollMode(e.data.mode);break;default:this._emit(`api:${e.type}`,e.data)}},window.addEventListener("message",this._messageHandler)}}get isVSCode(){return this._context==="vscode"}postToVSCode(t,e={}){this._vscodeApi&&this._vscodeApi.postMessage({type:t,data:e})}requestRefresh(){this.postToVSCode("requestRefresh")}notifyVSCode(t,e={}){this.postToVSCode("userAction",{action:t,...e})}get baseUrl(){return this.config.baseUrl}set baseUrl(t){this.config.baseUrl=t,this.config.wsUrl=t.replace(/^http/,"ws")+"/ws"}get isConnected(){return this._connected}async connect(){if(!(this._ws&&this._ws.readyState===WebSocket.OPEN))return new Promise((t,e)=>{try{this._ws=new WebSocket(this.config.wsUrl),this._ws.onopen=()=>{this._connected=!0,this._reconnectAttempts=0,this._emit(v.CONNECTED),t()},this._ws.onclose=()=>{this._connected=!1,this._emit(v.DISCONNECTED),this._scheduleReconnect()},this._ws.onerror=i=>{this._emit(v.ERROR,{error:i}),e(i)},this._ws.onmessage=i=>{try{let a=JSON.parse(i.data);this._handleMessage(a)}catch(a){console.error("Failed to parse WebSocket message:",a)}}}catch(i){e(i)}})}disconnect(){this._ws&&(this._ws.close(),this._ws=null),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._reconnectTimeout&&(clearTimeout(this._reconnectTimeout),this._reconnectTimeout=null),this._connected=!1,this._cleanupGlobalListeners()}_cleanupGlobalListeners(){this._visibilityChangeHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this._visibilityChangeHandler),this._visibilityChangeHandler=null),this._messageHandler&&typeof window<"u"&&(window.removeEventListener("message",this._messageHandler),this._messageHandler=null)}destroy(){this.disconnect()}_scheduleReconnect(){if(this._reconnectTimeout)return;if(this._reconnectAttempts>=this._maxReconnectAttempts){console.warn("WebSocket max reconnect attempts reached, giving up"),this._emit(v.ERROR,{error:"Max reconnect attempts reached"});return}let t=Math.min(this.config.retryDelay*Math.pow(2,this._reconnectAttempts),3e4);this._reconnectAttempts++,this._reconnectTimeout=setTimeout(()=>{this._reconnectTimeout=null,this.connect().catch(()=>{})},t)}_handleMessage(t){if(t.type==="ping"){this._ws&&this._ws.readyState===WebSocket.OPEN&&this._ws.send(JSON.stringify({type:"pong"}));return}let i={connected:v.CONNECTED,status_update:v.STATUS_UPDATE,task_created:v.TASK_CREATED,task_updated:v.TASK_UPDATED,task_deleted:v.TASK_DELETED,task_moved:v.TASK_UPDATED,project_created:v.PROJECT_CREATED,project_updated:v.PROJECT_UPDATED,agent_update:v.AGENT_UPDATE,log:v.LOG_MESSAGE}[t.type]||`api:${t.type}`;this._emit(i,t.data)}_emit(t,e={}){this.dispatchEvent(new CustomEvent(t,{detail:e}))}async _request(t,e={}){let i=`${this.config.baseUrl}${t}`,a=new AbortController,s=e&&typeof e.timeout=="number"?e.timeout:this.config.timeout,r=setTimeout(()=>a.abort(),s);try{let o=await fetch(i,{...e,signal:a.signal,credentials:"include",headers:{"Content-Type":"application/json",...e.headers}});if(clearTimeout(r),!o.ok){let n=await o.text().catch(()=>""),l=o.statusText||`HTTP ${o.status}`;if(n)try{let c=JSON.parse(n);l=c.detail||c.error||c.message||l}catch{l=n.length>200?n.slice(0,200)+"...":n}throw new Error(l)}return o.status===204?null:await o.json()}catch(o){throw clearTimeout(r),o.name==="AbortError"?new Error("Request timeout"):o}}async _get(t,e=!1){if(e&&this._cache.has(t)){let a=this._cache.get(t);if(Date.now()-a.timestamp<this._cacheTimeout)return a.data}let i=await this._request(t);return e&&this._cache.set(t,{data:i,timestamp:Date.now()}),i}async _post(t,e,i={}){return this._request(t,{method:"POST",body:JSON.stringify(e),...i})}async _put(t,e){return this._request(t,{method:"PUT",body:JSON.stringify(e)})}async _delete(t){return this._request(t,{method:"DELETE"})}async get(t){return this._get(t)}async getStatus(){return this._get("/api/status")}async healthCheck(){return this._get("/health")}async listProjects(t=null){let e=t?`?status=${t}`:"";return this._get(`/api/projects${e}`)}async getProject(t){return this._get(`/api/projects/${t}`)}async createProject(t){return this._post("/api/projects",t)}async updateProject(t,e){return this._put(`/api/projects/${t}`,e)}async deleteProject(t){return this._delete(`/api/projects/${t}`)}async listTasks(t={}){let e=new URLSearchParams;t.projectId&&e.append("project_id",t.projectId),t.status&&e.append("status",t.status),t.priority&&e.append("priority",t.priority);let i=e.toString()?`?${e}`:"";return this._get(`/api/tasks${i}`)}async getTask(t){return this._get(`/api/tasks/${t}`)}async createTask(t){return this._post("/api/tasks",t)}async updateTask(t,e){return this._put(`/api/tasks/${t}`,e)}async moveTask(t,e,i){return this._post(`/api/tasks/${t}/move`,{status:e,position:i})}async deleteTask(t){return this._delete(`/api/tasks/${t}`)}async getMemorySummary(){return this._get("/api/memory/summary",!0)}async getMemoryIndex(){return this._get("/api/memory/index",!0)}async getMemoryTimeline(){return this._get("/api/memory/timeline")}async listEpisodes(t={}){let e=new URLSearchParams(t).toString();return this._get(`/api/memory/episodes${e?"?"+e:""}`)}async getEpisode(t){return this._get(`/api/memory/episodes/${t}`)}async listPatterns(t={}){let e=new URLSearchParams(t).toString();return this._get(`/api/memory/patterns${e?"?"+e:""}`)}async getPattern(t){return this._get(`/api/memory/patterns/${t}`)}async listSkills(){return this._get("/api/memory/skills")}async getSkill(t){return this._get(`/api/memory/skills/${t}`)}async retrieveMemories(t,e=null,i=5){return this._post("/api/memory/retrieve",{query:t,taskType:e,topK:i},{timeout:3e4})}async consolidateMemory(t=24){return this._post("/api/memory/consolidate",{sinceHours:t},{timeout:12e4})}async getTokenEconomics(){return this._get("/api/memory/economics")}async searchMemory(t,e="all",i=20){let a=new URLSearchParams({q:t,collection:e,limit:String(i)});return this._get(`/api/memory/search?${a}`)}async getMemoryStats(){return this._get("/api/memory/stats",!0)}async listRegisteredProjects(t=!1){return this._get(`/api/registry/projects?include_inactive=${t}`)}async registerProject(t,e=null,i=null){return this._post("/api/registry/projects",{path:t,name:e,alias:i})}async discoverProjects(t=3){return this._get(`/api/registry/discover?max_depth=${t}`)}async syncRegistry(){return this._post("/api/registry/sync",{},{timeout:45e3})}async getCrossProjectTasks(t=null){let e=t?`?project_ids=${t.join(",")}`:"";return this._get(`/api/registry/tasks${e}`)}async getLearningMetrics(t={}){let e=new URLSearchParams;t.timeRange&&e.append("timeRange",t.timeRange),t.signalType&&e.append("signalType",t.signalType),t.source&&e.append("source",t.source);let i=e.toString()?`?${e}`:"";return this._get(`/api/learning/metrics${i}`)}async getLearningTrends(t={}){let e=new URLSearchParams;t.timeRange&&e.append("timeRange",t.timeRange),t.signalType&&e.append("signalType",t.signalType),t.source&&e.append("source",t.source);let i=e.toString()?`?${e}`:"";return this._get(`/api/learning/trends${i}`)}async getLearningSignals(t={}){let e=new URLSearchParams;t.timeRange&&e.append("timeRange",t.timeRange),t.signalType&&e.append("signalType",t.signalType),t.source&&e.append("source",t.source),t.limit&&e.append("limit",String(t.limit)),t.offset&&e.append("offset",String(t.offset));let i=e.toString()?`?${e}`:"";return this._get(`/api/learning/signals${i}`)}async getLatestAggregation(){return this._get("/api/learning/aggregation")}async triggerAggregation(t={}){return this._post("/api/learning/aggregate",t,{timeout:6e4})}async getAggregatedPreferences(t=20){return this._get(`/api/learning/preferences?limit=${t}`)}async getAggregatedErrors(t=20){return this._get(`/api/learning/errors?limit=${t}`)}async getAggregatedSuccessPatterns(t=20){return this._get(`/api/learning/success?limit=${t}`)}async getToolEfficiency(t=20){return this._get(`/api/learning/tools?limit=${t}`)}async getCost(){return this._get("/api/cost")}async getPricing(){return this._get("/api/pricing")}async getCouncilState(){return this._get("/api/council/state")}async getCouncilVerdicts(t=20){return this._get(`/api/council/verdicts?limit=${t}`)}async getCouncilConvergence(){return this._get("/api/council/convergence")}async getCouncilReport(){return this._get("/api/council/report")}async forceCouncilReview(){return this._post("/api/council/force-review",{})}async getContext(){return this._get("/api/context")}async getNotifications(t,e){let i=new URLSearchParams;t&&i.set("severity",t),e&&i.set("unread_only","true");let a=i.toString();return this._get("/api/notifications"+(a?"?"+a:""))}async getNotificationTriggers(){return this._get("/api/notifications/triggers")}async updateNotificationTriggers(t){return this._put("/api/notifications/triggers",{triggers:t})}async acknowledgeNotification(t){return this._post("/api/notifications/"+encodeURIComponent(t)+"/acknowledge",{})}async pauseSession(){return this._post("/api/control/pause",{})}async resumeSession(){return this._post("/api/control/resume",{})}async stopSession(){return this._post("/api/control/stop",{})}async getLogs(t=100){return this._get(`/api/logs?lines=${t}`)}async getChecklist(){return this._get("/api/checklist")}async getChecklistSummary(){return this._get("/api/checklist/summary")}async getPrdObservations(){let t=await fetch(`${this.baseUrl}/api/prd-observations`,{credentials:"include"});if(!t.ok)throw new Error(`HTTP ${t.status}`);return t.text()}async getChecklistWaivers(){return this._get("/api/checklist/waivers")}async addChecklistWaiver(t,e,i="dashboard"){return this._post("/api/checklist/waivers",{item_id:t,reason:e,waived_by:i})}async removeChecklistWaiver(t){return this._delete(`/api/checklist/waivers/${encodeURIComponent(t)}`)}async getCouncilGate(){return this._get("/api/council/gate")}async getAppRunnerStatus(){return this._get("/api/app-runner/status")}async getAppRunnerLogs(t=100){return this._get(`/api/app-runner/logs?lines=${t}`)}async restartApp(){return this._post("/api/control/app-restart",{})}async stopApp(){return this._post("/api/control/app-stop",{})}async getPlaywrightResults(){return this._get("/api/playwright/results")}async getPlaywrightScreenshot(){return this._get("/api/playwright/screenshot")}startPolling(t,e=null){if(this._pollInterval)return;this._pollCallback=t;let i=async()=>{try{let s=await this.getStatus();this._connected=!0,this._pollCallback&&this._pollCallback(s),this._emit(v.STATUS_UPDATE,s),this._vscodeApi&&this.postToVSCode("pollSuccess",{timestamp:Date.now()})}catch(s){this._connected=!1,this._emit(v.ERROR,{error:s}),this._vscodeApi&&this.postToVSCode("pollError",{error:s.message})}};i();let a=e||this._currentPollInterval||this.config.pollInterval;this._pollInterval=setInterval(i,a)}stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}};C(T,"_instances",new Map);var M=T;function Ut(d={}){return new M(d)}function g(d={}){return M.getInstance(d)}var It="loki-state-change",Tt={ui:{theme:"light",sidebarCollapsed:!1,activeSection:"kanban",terminalAutoScroll:!0},session:{connected:!1,lastSync:null,mode:"offline",phase:null,iteration:null},localTasks:[],cache:{projects:[],tasks:[],agents:[],memory:null,lastFetch:null},preferences:{pollInterval:2e3,notifications:!0,soundEnabled:!1}},S=class S extends EventTarget{static getInstance(){return S._instance||(S._instance=new S),S._instance}constructor(){super(),this._state=this._loadState(),this._subscribers=new Map,this._batchUpdates=[],this._batchTimeout=null}_loadState(){try{let t=localStorage.getItem(S.STORAGE_KEY);if(t){let e=JSON.parse(t);return this._mergeState(Tt,e)}}catch(t){console.warn("Failed to load state from localStorage:",t)}return{...Tt}}_mergeState(t,e){let i={...t};for(let a of Object.keys(e))a in t&&typeof t[a]=="object"&&!Array.isArray(t[a])?i[a]=this._mergeState(t[a],e[a]):i[a]=e[a];return i}_saveState(){try{let t={ui:this._state.ui,localTasks:this._state.localTasks,preferences:this._state.preferences};localStorage.setItem(S.STORAGE_KEY,JSON.stringify(t))}catch(t){console.warn("Failed to save state to localStorage:",t)}}get(t=null){if(!t)return{...this._state};let e=t.split("."),i=this._state;for(let a of e){if(i==null)return;i=i[a]}return i}set(t,e,i=!0){let a=t.split("."),s=a.pop(),r=this._state;for(let n of a)n in r||(r[n]={}),r=r[n];let o=r[s];r[s]=e,i&&this._saveState(),this._notifyChange(t,e,o)}update(t,e=!0){let i=[];for(let[a,s]of Object.entries(t)){let r=this.get(a);this.set(a,s,!1),i.push({path:a,value:s,oldValue:r})}e&&this._saveState();for(let a of i)this._notifyChange(a.path,a.value,a.oldValue)}_notifyChange(t,e,i){this.dispatchEvent(new CustomEvent(It,{detail:{path:t,value:e,oldValue:i}}));let a=this._subscribers.get(t)||[];for(let r of a)try{r(e,i,t)}catch(o){console.error("State subscriber error:",o)}let s=t.split(".");for(;s.length>1;){s.pop();let r=s.join("."),o=this._subscribers.get(r)||[];for(let n of o)try{n(this.get(r),null,r)}catch(l){console.error("State subscriber error:",l)}}}subscribe(t,e){return this._subscribers.has(t)||this._subscribers.set(t,[]),this._subscribers.get(t).push(e),()=>{let i=this._subscribers.get(t),a=i.indexOf(e);a>-1&&i.splice(a,1)}}reset(t=null){if(t){let e=t.split("."),i=Tt;for(let a of e)i=i?.[a];this.set(t,i)}else this._state={...Tt},this._saveState(),this.dispatchEvent(new CustomEvent(It,{detail:{path:null,value:this._state,oldValue:null}}))}addLocalTask(t){let e=this.get("localTasks")||[],i={id:`local-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,createdAt:new Date().toISOString(),status:"pending",...t};return this.set("localTasks",[...e,i]),i}updateLocalTask(t,e){let i=this.get("localTasks")||[],a=i.findIndex(r=>r.id===t);if(a===-1)return null;let s={...i[a],...e,updatedAt:new Date().toISOString()};return i[a]=s,this.set("localTasks",[...i]),s}deleteLocalTask(t){let e=this.get("localTasks")||[];this.set("localTasks",e.filter(i=>i.id!==t))}moveLocalTask(t,e,i=null){let s=(this.get("localTasks")||[]).find(r=>r.id===t);return s?this.updateLocalTask(t,{status:e,position:i??s.position}):null}updateSession(t){this.update(Object.fromEntries(Object.entries(t).map(([e,i])=>[`session.${e}`,i])),!1)}updateCache(t){this.update({"cache.projects":t.projects??this.get("cache.projects"),"cache.tasks":t.tasks??this.get("cache.tasks"),"cache.agents":t.agents??this.get("cache.agents"),"cache.memory":t.memory??this.get("cache.memory"),"cache.lastFetch":new Date().toISOString()},!1)}getMergedTasks(){let t=this.get("cache.tasks")||[],i=(this.get("localTasks")||[]).map(a=>({...a,isLocal:!0}));return[...t,...i]}getTasksByStatus(t){return this.getMergedTasks().filter(e=>e.status===t)}};C(S,"STORAGE_KEY","loki-dashboard-state"),C(S,"_instance",null);var N=S;function B(){return N.getInstance()}function Nt(d){let t=B();return{get:()=>t.get(d),set:e=>t.set(d,e),subscribe:e=>t.subscribe(d,e)}}var O=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data={status:"offline",phase:null,iteration:null,provider:null,running_agents:0,pending_tasks:null,uptime_seconds:0,complexity:null,connected:!1},this._api=null,this._pollInterval=null,this._statusUpdateHandler=null,this._connectedHandler=null,this._disconnectedHandler=null,this._checklistSummary=null,this._appRunnerStatus=null,this._playwrightResults=null,this._gateStatus=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._startPolling(),this._api.connect().catch(()=>{})}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._loadAbortController&&(this._loadAbortController.abort(),this._loadAbortController=null),this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(v.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(v.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(v.DISCONNECTED,this._disconnectedHandler))}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadStatus()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t}),this._statusUpdateHandler=e=>this._updateFromStatus(e.detail),this._connectedHandler=()=>{this._data.connected=!0,this.render()},this._disconnectedHandler=()=>{this._data.connected=!1,this._data.status="offline",this.render()},this._api.addEventListener(v.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(v.CONNECTED,this._connectedHandler),this._api.addEventListener(v.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){this._loadAbortController&&this._loadAbortController.abort(),this._loadAbortController=new AbortController;let{signal:t}=this._loadAbortController;try{let[e,i,a,s,r]=await Promise.allSettled([this._api.getStatus(),this._api.getChecklistSummary(),this._api.getAppRunnerStatus(),this._api.getPlaywrightResults(),this._api.getCouncilGate()]);if(t.aborted)return;e.status==="fulfilled"?this._updateFromStatus(e.value):(this._data.connected=!1,this._data.status="offline"),i.status==="fulfilled"&&(this._checklistSummary=i.value?.summary||null),a.status==="fulfilled"&&(this._appRunnerStatus=a.value),s.status==="fulfilled"&&(this._playwrightResults=s.value),r.status==="fulfilled"&&(this._gateStatus=r.value),this.render()}catch{if(t.aborted)return;this._data.connected=!1,this._data.status="offline",this.render()}}_updateFromStatus(t){t&&(this._data={...this._data,connected:!0,status:t.status||"offline",phase:t.phase||null,iteration:t.iteration!=null?t.iteration:null,provider:t.provider||null,running_agents:t.running_agents||0,pending_tasks:t.pending_tasks!=null?t.pending_tasks:null,uptime_seconds:t.uptime_seconds||0,complexity:t.complexity||null})}_startPolling(){this._pollInterval=setInterval(async()=>{try{await this._loadStatus()}catch{this._data.connected=!1,this._data.status="offline",this.render()}},5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_formatUptime(t){if(!t||t<0)return"--";let e=Math.floor(t/3600),i=Math.floor(t%3600/60),a=Math.floor(t%60);return e>0?`${e}h ${i}m`:i>0?`${i}m ${a}s`:`${a}s`}_getStatusDotClass(){switch(this._data.status){case"running":case"autonomous":return"active";case"paused":return"paused";case"stopped":return"stopped";case"error":return"error";default:return"offline"}}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_renderAppRunnerCard(){let t=this._appRunnerStatus;if(!t||t.status==="not_initialized")return`
1714
+ `}getAriaPattern(e){return Se[e]||{}}applyAriaPattern(e,t){let i=this.getAriaPattern(t);for(let[a,s]of Object.entries(i))if(a==="role")e.setAttribute("role",s);else{let r=a.replace(/([A-Z])/g,"-$1").toLowerCase();e.setAttribute(r,s)}}render(){}};var z={realtime:1e3,normal:2e3,background:5e3,offline:1e4},Fe={vscode:z.normal,browser:z.realtime,cli:z.background},je={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(e={}){let t=e.baseUrl||je.baseUrl;return T._instances.has(t)||T._instances.set(t,new T(e)),T._instances.get(t)}static clearInstances(){T._instances.forEach(e=>e.disconnect()),T._instances.clear()}constructor(e={}){super(),this.config={...je,...e},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=Fe[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(Fe[this._context]||z.normal)},document.addEventListener("visibilitychange",this._visibilityChangeHandler))}_setPollInterval(e){this._currentPollInterval=e,this._pollInterval&&(this.stopPolling(),this.startPolling(null,e))}setPollMode(e){let t=z[e];t&&this._setPollInterval(t)}_setupVSCodeBridge(){if(!(typeof acquireVsCodeApi>"u")){try{this._vscodeApi=acquireVsCodeApi()}catch{console.warn("VS Code API already acquired or unavailable");return}this._messageHandler=e=>{let t=e.data;if(!(!t||!t.type))switch(t.type){case"updateStatus":this._emit(v.STATUS_UPDATE,t.data);break;case"updateTasks":this._emit(v.TASK_UPDATED,t.data);break;case"taskCreated":this._emit(v.TASK_CREATED,t.data);break;case"taskDeleted":this._emit(v.TASK_DELETED,t.data);break;case"projectCreated":this._emit(v.PROJECT_CREATED,t.data);break;case"projectUpdated":this._emit(v.PROJECT_UPDATED,t.data);break;case"agentUpdate":this._emit(v.AGENT_UPDATE,t.data);break;case"logMessage":this._emit(v.LOG_MESSAGE,t.data);break;case"memoryUpdate":this._emit(v.MEMORY_UPDATE,t.data);break;case"connected":this._connected=!0,this._emit(v.CONNECTED,t.data);break;case"disconnected":this._connected=!1,this._emit(v.DISCONNECTED,t.data);break;case"error":this._emit(v.ERROR,t.data);break;case"setPollMode":this.setPollMode(t.data.mode);break;default:this._emit(`api:${t.type}`,t.data)}},window.addEventListener("message",this._messageHandler)}}get isVSCode(){return this._context==="vscode"}postToVSCode(e,t={}){this._vscodeApi&&this._vscodeApi.postMessage({type:e,data:t})}requestRefresh(){this.postToVSCode("requestRefresh")}notifyVSCode(e,t={}){this.postToVSCode("userAction",{action:e,...t})}get baseUrl(){return this.config.baseUrl}set baseUrl(e){this.config.baseUrl=e,this.config.wsUrl=e.replace(/^http/,"ws")+"/ws"}get isConnected(){return this._connected}async connect(){if(!(this._ws&&this._ws.readyState===WebSocket.OPEN))return new Promise((e,t)=>{try{this._ws=new WebSocket(this.config.wsUrl),this._ws.onopen=()=>{this._connected=!0,this._reconnectAttempts=0,this._emit(v.CONNECTED),e()},this._ws.onclose=()=>{this._connected=!1,this._emit(v.DISCONNECTED),this._scheduleReconnect()},this._ws.onerror=i=>{this._emit(v.ERROR,{error:i}),t(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){t(i)}})}disconnect(){this._ws&&(this._ws.close(),this._ws=null),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._reconnectTimeout&&(clearTimeout(this._reconnectTimeout),this._reconnectTimeout=null),this._connected=!1,this._cleanupGlobalListeners()}_cleanupGlobalListeners(){this._visibilityChangeHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this._visibilityChangeHandler),this._visibilityChangeHandler=null),this._messageHandler&&typeof window<"u"&&(window.removeEventListener("message",this._messageHandler),this._messageHandler=null)}destroy(){this.disconnect()}_scheduleReconnect(){if(this._reconnectTimeout)return;if(this._reconnectAttempts>=this._maxReconnectAttempts){console.warn("WebSocket max reconnect attempts reached, giving up"),this._emit(v.ERROR,{error:"Max reconnect attempts reached"});return}let e=Math.min(this.config.retryDelay*Math.pow(2,this._reconnectAttempts),3e4);this._reconnectAttempts++,this._reconnectTimeout=setTimeout(()=>{this._reconnectTimeout=null,this.connect().catch(()=>{})},e)}_handleMessage(e){if(e.type==="ping"){this._ws&&this._ws.readyState===WebSocket.OPEN&&this._ws.send(JSON.stringify({type:"pong"}));return}let i={connected:v.CONNECTED,status_update:v.STATUS_UPDATE,task_created:v.TASK_CREATED,task_updated:v.TASK_UPDATED,task_deleted:v.TASK_DELETED,task_moved:v.TASK_UPDATED,project_created:v.PROJECT_CREATED,project_updated:v.PROJECT_UPDATED,agent_update:v.AGENT_UPDATE,log:v.LOG_MESSAGE}[e.type]||`api:${e.type}`;this._emit(i,e.data)}_emit(e,t={}){this.dispatchEvent(new CustomEvent(e,{detail:t}))}async _request(e,t={}){let i=`${this.config.baseUrl}${e}`,a=new AbortController,s=t&&typeof t.timeout=="number"?t.timeout:this.config.timeout,r=setTimeout(()=>a.abort(),s);try{let o=await fetch(i,{...t,signal:a.signal,credentials:"include",headers:{"Content-Type":"application/json",...t.headers}});if(clearTimeout(r),!o.ok){let n=await o.text().catch(()=>""),l=o.statusText||`HTTP ${o.status}`;if(n)try{let c=JSON.parse(n);l=c.detail||c.error||c.message||l}catch{l=n.length>200?n.slice(0,200)+"...":n}throw new Error(l)}return o.status===204?null:await o.json()}catch(o){throw clearTimeout(r),o.name==="AbortError"?new Error("Request timeout"):o}}async _get(e,t=!1){if(t&&this._cache.has(e)){let a=this._cache.get(e);if(Date.now()-a.timestamp<this._cacheTimeout)return a.data}let i=await this._request(e);return t&&this._cache.set(e,{data:i,timestamp:Date.now()}),i}async _post(e,t,i={}){return this._request(e,{method:"POST",body:JSON.stringify(t),...i})}async _put(e,t){return this._request(e,{method:"PUT",body:JSON.stringify(t)})}async _delete(e){return this._request(e,{method:"DELETE"})}async get(e){return this._get(e)}async getStatus(){return this._get("/api/status")}async healthCheck(){return this._get("/health")}async listProjects(e=null){let t=e?`?status=${e}`:"";return this._get(`/api/projects${t}`)}async getProject(e){return this._get(`/api/projects/${e}`)}async createProject(e){return this._post("/api/projects",e)}async updateProject(e,t){return this._put(`/api/projects/${e}`,t)}async deleteProject(e){return this._delete(`/api/projects/${e}`)}async listTasks(e={}){let t=new URLSearchParams;e.projectId&&t.append("project_id",e.projectId),e.status&&t.append("status",e.status),e.priority&&t.append("priority",e.priority);let i=t.toString()?`?${t}`:"";return this._get(`/api/tasks${i}`)}async getTask(e){return this._get(`/api/tasks/${e}`)}async createTask(e){return this._post("/api/tasks",e)}async updateTask(e,t){return this._put(`/api/tasks/${e}`,t)}async moveTask(e,t,i){return this._post(`/api/tasks/${e}/move`,{status:t,position:i})}async deleteTask(e){return this._delete(`/api/tasks/${e}`)}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(e={}){let t=new URLSearchParams(e).toString();return this._get(`/api/memory/episodes${t?"?"+t:""}`)}async getEpisode(e){return this._get(`/api/memory/episodes/${e}`)}async listPatterns(e={}){let t=new URLSearchParams(e).toString();return this._get(`/api/memory/patterns${t?"?"+t:""}`)}async getPattern(e){return this._get(`/api/memory/patterns/${e}`)}async listSkills(){return this._get("/api/memory/skills")}async getSkill(e){return this._get(`/api/memory/skills/${e}`)}async retrieveMemories(e,t=null,i=5){return this._post("/api/memory/retrieve",{query:e,taskType:t,topK:i},{timeout:3e4})}async consolidateMemory(e=24){return this._post("/api/memory/consolidate",{sinceHours:e},{timeout:12e4})}async getTokenEconomics(){return this._get("/api/memory/economics")}async searchMemory(e,t="all",i=20){let a=new URLSearchParams({q:e,collection:t,limit:String(i)});return this._get(`/api/memory/search?${a}`)}async getMemoryStats(){return this._get("/api/memory/stats",!0)}async listRegisteredProjects(e=!1){return this._get(`/api/registry/projects?include_inactive=${e}`)}async registerProject(e,t=null,i=null){return this._post("/api/registry/projects",{path:e,name:t,alias:i})}async discoverProjects(e=3){return this._get(`/api/registry/discover?max_depth=${e}`)}async syncRegistry(){return this._post("/api/registry/sync",{},{timeout:45e3})}async getCrossProjectTasks(e=null){let t=e?`?project_ids=${e.join(",")}`:"";return this._get(`/api/registry/tasks${t}`)}async getLearningMetrics(e={}){let t=new URLSearchParams;e.timeRange&&t.append("timeRange",e.timeRange),e.signalType&&t.append("signalType",e.signalType),e.source&&t.append("source",e.source);let i=t.toString()?`?${t}`:"";return this._get(`/api/learning/metrics${i}`)}async getLearningTrends(e={}){let t=new URLSearchParams;e.timeRange&&t.append("timeRange",e.timeRange),e.signalType&&t.append("signalType",e.signalType),e.source&&t.append("source",e.source);let i=t.toString()?`?${t}`:"";return this._get(`/api/learning/trends${i}`)}async getLearningSignals(e={}){let t=new URLSearchParams;e.timeRange&&t.append("timeRange",e.timeRange),e.signalType&&t.append("signalType",e.signalType),e.source&&t.append("source",e.source),e.limit&&t.append("limit",String(e.limit)),e.offset&&t.append("offset",String(e.offset));let i=t.toString()?`?${t}`:"";return this._get(`/api/learning/signals${i}`)}async getLatestAggregation(){return this._get("/api/learning/aggregation")}async triggerAggregation(e={}){return this._post("/api/learning/aggregate",e,{timeout:6e4})}async getAggregatedPreferences(e=20){return this._get(`/api/learning/preferences?limit=${e}`)}async getAggregatedErrors(e=20){return this._get(`/api/learning/errors?limit=${e}`)}async getAggregatedSuccessPatterns(e=20){return this._get(`/api/learning/success?limit=${e}`)}async getToolEfficiency(e=20){return this._get(`/api/learning/tools?limit=${e}`)}async getCost(){return this._get("/api/cost")}async getPricing(){return this._get("/api/pricing")}async getCouncilState(){return this._get("/api/council/state")}async getCouncilVerdicts(e=20){return this._get(`/api/council/verdicts?limit=${e}`)}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(e,t){let i=new URLSearchParams;e&&i.set("severity",e),t&&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(e){return this._put("/api/notifications/triggers",{triggers:e})}async acknowledgeNotification(e){return this._post("/api/notifications/"+encodeURIComponent(e)+"/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(e=100){return this._get(`/api/logs?lines=${e}`)}async getChecklist(){return this._get("/api/checklist")}async getChecklistSummary(){return this._get("/api/checklist/summary")}async getPrdObservations(){let e=await fetch(`${this.baseUrl}/api/prd-observations`,{credentials:"include"});if(!e.ok)throw new Error(`HTTP ${e.status}`);return e.text()}async getChecklistWaivers(){return this._get("/api/checklist/waivers")}async addChecklistWaiver(e,t,i="dashboard"){return this._post("/api/checklist/waivers",{item_id:e,reason:t,waived_by:i})}async removeChecklistWaiver(e){return this._delete(`/api/checklist/waivers/${encodeURIComponent(e)}`)}async getCouncilGate(){return this._get("/api/council/gate")}async getAppRunnerStatus(){return this._get("/api/app-runner/status")}async getAppRunnerLogs(e=100){return this._get(`/api/app-runner/logs?lines=${e}`)}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(e,t=null){if(this._pollInterval)return;this._pollCallback=e;let i=async()=>{try{let s=await this.getStatus();this._connected=!0,this._pollCallback&&this._pollCallback(s),this._emit(v.STATUS_UPDATE,s),this._vscodeApi&&this.postToVSCode("pollSuccess",{timestamp:Date.now()})}catch(s){this._connected=!1,this._emit(v.ERROR,{error:s}),this._vscodeApi&&this.postToVSCode("pollError",{error:s.message})}};i();let a=t||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 Ue(d={}){return new M(d)}function g(d={}){return M.getInstance(d)}var Ie="loki-state-change",Te={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 e=localStorage.getItem(S.STORAGE_KEY);if(e){let t=JSON.parse(e);return this._mergeState(Te,t)}}catch(e){console.warn("Failed to load state from localStorage:",e)}return{...Te}}_mergeState(e,t){let i={...e};for(let a of Object.keys(t))a in e&&typeof e[a]=="object"&&!Array.isArray(e[a])?i[a]=this._mergeState(e[a],t[a]):i[a]=t[a];return i}_saveState(){try{let e={ui:this._state.ui,localTasks:this._state.localTasks,preferences:this._state.preferences};localStorage.setItem(S.STORAGE_KEY,JSON.stringify(e))}catch(e){console.warn("Failed to save state to localStorage:",e)}}get(e=null){if(!e)return{...this._state};let t=e.split("."),i=this._state;for(let a of t){if(i==null)return;i=i[a]}return i}set(e,t,i=!0){let a=e.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]=t,i&&this._saveState(),this._notifyChange(e,t,o)}update(e,t=!0){let i=[];for(let[a,s]of Object.entries(e)){let r=this.get(a);this.set(a,s,!1),i.push({path:a,value:s,oldValue:r})}t&&this._saveState();for(let a of i)this._notifyChange(a.path,a.value,a.oldValue)}_notifyChange(e,t,i){this.dispatchEvent(new CustomEvent(Ie,{detail:{path:e,value:t,oldValue:i}}));let a=this._subscribers.get(e)||[];for(let r of a)try{r(t,i,e)}catch(o){console.error("State subscriber error:",o)}let s=e.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(e,t){return this._subscribers.has(e)||this._subscribers.set(e,[]),this._subscribers.get(e).push(t),()=>{let i=this._subscribers.get(e),a=i.indexOf(t);a>-1&&i.splice(a,1)}}reset(e=null){if(e){let t=e.split("."),i=Te;for(let a of t)i=i?.[a];this.set(e,i)}else this._state={...Te},this._saveState(),this.dispatchEvent(new CustomEvent(Ie,{detail:{path:null,value:this._state,oldValue:null}}))}addLocalTask(e){let t=this.get("localTasks")||[],i={id:`local-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,createdAt:new Date().toISOString(),status:"pending",...e};return this.set("localTasks",[...t,i]),i}updateLocalTask(e,t){let i=this.get("localTasks")||[],a=i.findIndex(r=>r.id===e);if(a===-1)return null;let s={...i[a],...t,updatedAt:new Date().toISOString()};return i[a]=s,this.set("localTasks",[...i]),s}deleteLocalTask(e){let t=this.get("localTasks")||[];this.set("localTasks",t.filter(i=>i.id!==e))}moveLocalTask(e,t,i=null){let s=(this.get("localTasks")||[]).find(r=>r.id===e);return s?this.updateLocalTask(e,{status:t,position:i??s.position}):null}updateSession(e){this.update(Object.fromEntries(Object.entries(e).map(([t,i])=>[`session.${t}`,i])),!1)}updateCache(e){this.update({"cache.projects":e.projects??this.get("cache.projects"),"cache.tasks":e.tasks??this.get("cache.tasks"),"cache.agents":e.agents??this.get("cache.agents"),"cache.memory":e.memory??this.get("cache.memory"),"cache.lastFetch":new Date().toISOString()},!1)}getMergedTasks(){let e=this.get("cache.tasks")||[],i=(this.get("localTasks")||[]).map(a=>({...a,isLocal:!0}));return[...e,...i]}getTasksByStatus(e){return this.getMergedTasks().filter(t=>t.status===e)}};C(S,"STORAGE_KEY","loki-dashboard-state"),C(S,"_instance",null);var N=S;function B(){return N.getInstance()}function Ne(d){let e=B();return{get:()=>e.get(d),set:t=>e.set(d,t),subscribe:t=>e.subscribe(d,t)}}var O=class extends u{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(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadStatus()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e}),this._statusUpdateHandler=t=>this._updateFromStatus(t.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:e}=this._loadAbortController;try{let[t,i,a,s,r]=await Promise.allSettled([this._api.getStatus(),this._api.getChecklistSummary(),this._api.getAppRunnerStatus(),this._api.getPlaywrightResults(),this._api.getCouncilGate()]);if(e.aborted)return;t.status==="fulfilled"?this._updateFromStatus(t.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(e.aborted)return;this._data.connected=!1,this._data.status="offline",this.render()}}_updateFromStatus(e){e&&(this._data={...this._data,connected:!0,status:e.status||"offline",phase:e.phase||null,iteration:e.iteration!=null?e.iteration:null,provider:e.provider||null,running_agents:e.running_agents||0,pending_tasks:e.pending_tasks!=null?e.pending_tasks:null,uptime_seconds:e.uptime_seconds||0,complexity:e.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(e){if(!e||e<0)return"--";let t=Math.floor(e/3600),i=Math.floor(e%3600/60),a=Math.floor(e%60);return t>0?`${t}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(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_renderAppRunnerCard(){let e=this._appRunnerStatus;if(!e||e.status==="not_initialized")return`
1715
1715
  <div class="overview-card">
1716
1716
  <div class="card-label">App Runner</div>
1717
1717
  <div class="card-value small-text">${this._data.status==="running"||this._data.status==="autonomous"?"Waiting...":"Not started"}</div>
1718
1718
  </div>
1719
- `;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=`
1719
+ `;let i={running:"var(--loki-green, #22c55e)",starting:"var(--loki-yellow, #f59e0b)",crashed:"var(--loki-red, #ef4444)",stopped:"var(--loki-text-muted, #a1a1aa)"}[e.status]||"var(--loki-text-muted)",a=e.status==="running"?"active":e.status==="crashed"?"error":"offline",s=(e.status||"unknown").toUpperCase(),r=e.port?`:${e.port}`:"",o=e.url&&typeof e.url=="string"?e.url:null;!o&&e.port&&e.status==="running"&&(o=`http://localhost:${e.port}`);let n=`
1720
1720
  <div class="card-label">App Runner${o?' <span style="font-size:10px;color:var(--loki-text-muted);">(click to open)</span>':""}</div>
1721
1721
  <div class="card-value small-text">
1722
1722
  <span class="status-dot ${a}"></span>
1723
1723
  ${s}${r}
1724
1724
  </div>
1725
- ${t.method?`<div style="font-size:10px;color:var(--loki-text-muted);margin-top:2px;">${this._escapeHtml(t.method)}</div>`:""}
1725
+ ${e.method?`<div style="font-size:10px;color:var(--loki-text-muted);margin-top:2px;">${this._escapeHtml(e.method)}</div>`:""}
1726
1726
  `;return o?`
1727
1727
  <a class="overview-card overview-card-link" href="${this._escapeHtml(o)}" target="_blank" rel="noopener noreferrer"
1728
1728
  style="text-decoration:none;color:inherit;display:block;cursor:pointer;"
@@ -1733,50 +1733,50 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
1733
1733
  <div class="overview-card">
1734
1734
  ${n}
1735
1735
  </div>
1736
- `}_renderPlaywrightCard(){let t=this._playwrightResults;if(!t||t==="null"||!t.verified_at)return`
1736
+ `}_renderPlaywrightCard(){let e=this._playwrightResults;if(!e||e==="null"||!e.verified_at)return`
1737
1737
  <div class="overview-card">
1738
1738
  <div class="card-label">Verification</div>
1739
1739
  <div class="card-value small-text">${this._data.status==="running"||this._data.status==="autonomous"?"Pending":"Not run"}</div>
1740
1740
  </div>
1741
- `;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`
1741
+ `;let t=e.passed===!0,i=t?"var(--loki-green, #22c55e)":"var(--loki-red, #ef4444)",a=t?"PASSED":"FAILED",s=t?"active":"error",r=e.checks||{},o=Object.values(r).filter(n=>!n).length;return`
1742
1742
  <div class="overview-card">
1743
1743
  <div class="card-label">Verification</div>
1744
1744
  <div class="card-value small-text">
1745
1745
  <span class="status-dot ${s}"></span>
1746
1746
  ${a}
1747
1747
  </div>
1748
- ${!e&&o>0?`<div style="font-size:10px;color:var(--loki-red,#ef4444);margin-top:2px;">${o} check(s) failed</div>`:""}
1748
+ ${!t&&o>0?`<div style="font-size:10px;color:var(--loki-red,#ef4444);margin-top:2px;">${o} check(s) failed</div>`:""}
1749
1749
  </div>
1750
- `}_renderChecklistCard(){let t=this._checklistSummary;if(!t||!t.total)return`
1750
+ `}_renderChecklistCard(){let e=this._checklistSummary;if(!e||!e.total)return`
1751
1751
  <div class="overview-card">
1752
1752
  <div class="card-label">Spec Progress</div>
1753
1753
  <div class="card-value small-text">${this._data.status==="running"||this._data.status==="autonomous"?"Analyzing spec...":"No checklist"}</div>
1754
1754
  </div>
1755
- `;let e=Math.round(t.verified/t.total*100),i=t.failing>0?"var(--loki-yellow, #f59e0b)":"var(--loki-green, #22c55e)";return`
1755
+ `;let t=Math.round(e.verified/e.total*100),i=e.failing>0?"var(--loki-yellow, #f59e0b)":"var(--loki-green, #22c55e)";return`
1756
1756
  <div class="overview-card">
1757
1757
  <div class="card-label">Spec Progress</div>
1758
- <div class="card-value small-text">${t.verified}/${t.total} (${e}%)</div>
1758
+ <div class="card-value small-text">${e.verified}/${e.total} (${t}%)</div>
1759
1759
  <div class="mini-progress" style="margin-top:4px;height:4px;background:var(--loki-bg-secondary,#e4e4e7);border-radius:2px;overflow:hidden;">
1760
- <div style="width:${e}%;height:100%;background:${i};transition:width 0.3s;"></div>
1760
+ <div style="width:${t}%;height:100%;background:${i};transition:width 0.3s;"></div>
1761
1761
  </div>
1762
- ${t.failing?`<div style="font-size:10px;color:var(--loki-red,#ef4444);margin-top:2px;">${t.failing} failing</div>`:""}
1762
+ ${e.failing?`<div style="font-size:10px;color:var(--loki-red,#ef4444);margin-top:2px;">${e.failing} failing</div>`:""}
1763
1763
  </div>
1764
- `}_renderCouncilGateCard(){let t=this._gateStatus;if(!t||!t.status){let e=this._data.status==="running"||this._data.status==="autonomous";return`
1764
+ `}_renderCouncilGateCard(){let e=this._gateStatus;if(!e||!e.status){let t=this._data.status==="running"||this._data.status==="autonomous";return`
1765
1765
  <div class="overview-card">
1766
1766
  <div class="card-label">Council Gate</div>
1767
1767
  <div class="card-value small-text">
1768
- <span class="status-dot ${e?"paused":"offline"}"></span>
1769
- ${e?"Pending review":"Not evaluated"}
1768
+ <span class="status-dot ${t?"paused":"offline"}"></span>
1769
+ ${t?"Pending review":"Not evaluated"}
1770
1770
  </div>
1771
1771
  </div>
1772
- `}if(t.status==="blocked"){let e=t.critical_failures||0;return`
1772
+ `}if(e.status==="blocked"){let t=e.critical_failures||0;return`
1773
1773
  <div class="overview-card">
1774
1774
  <div class="card-label">Council Gate</div>
1775
1775
  <div class="card-value small-text">
1776
1776
  <span class="status-dot error"></span>
1777
1777
  BLOCKED
1778
1778
  </div>
1779
- ${e>0?`<div style="font-size:10px;color:var(--loki-red,#ef4444);margin-top:2px;">${e} critical failure${e!==1?"s":""}</div>`:""}
1779
+ ${t>0?`<div style="font-size:10px;color:var(--loki-red,#ef4444);margin-top:2px;">${t} critical failure${t!==1?"s":""}</div>`:""}
1780
1780
  </div>
1781
1781
  `}return`
1782
1782
  <div class="overview-card">
@@ -1786,7 +1786,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
1786
1786
  PASSED
1787
1787
  </div>
1788
1788
  </div>
1789
- `}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=`
1789
+ `}render(){let e=this._getStatusDotClass(),t=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=`
1790
1790
  <style>
1791
1791
  ${this.getBaseStyles()}
1792
1792
 
@@ -1913,8 +1913,8 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
1913
1913
  <div class="overview-card">
1914
1914
  <div class="card-label">Session</div>
1915
1915
  <div class="card-value">
1916
- <span class="status-dot ${t}"></span>
1917
- ${e}
1916
+ <span class="status-dot ${e}"></span>
1917
+ ${t}
1918
1918
  </div>
1919
1919
  </div>
1920
1920
 
@@ -1962,19 +1962,19 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
1962
1962
  </div>
1963
1963
  </div>
1964
1964
  </div>
1965
- `}};customElements.get("loki-overview")||customElements.define("loki-overview",O);var ce=[{id:"pending",label:"Pending",status:"pending",color:"var(--loki-text-muted)"},{id:"in_progress",label:"In Progress",status:"in_progress",color:"var(--loki-blue)"},{id:"review",label:"In Review",status:"review",color:"var(--loki-purple)"},{id:"done",label:"Completed",status:"done",color:"var(--loki-green)"}],q=class extends h{static get observedAttributes(){return["api-url","project-id","theme","readonly"]}constructor(){super(),this._tasks=[],this._loading=!0,this._error=null,this._draggedTask=null,this._selectedTask=null,this._expandedCards=new Set,this._selectedTasks=new Set,this._bulkMode=!1,this._activeFilter="all",this._api=null,this._state=B()}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadTasks()}disconnectedCallback(){super.disconnectedCallback(),this._api&&(this._api.removeEventListener(v.TASK_CREATED,this._onTaskEvent),this._api.removeEventListener(v.TASK_UPDATED,this._onTaskEvent),this._api.removeEventListener(v.TASK_DELETED,this._onTaskEvent))}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadTasks()),t==="project-id"&&this._loadTasks(),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t}),this._onTaskEvent&&(this._api.removeEventListener(v.TASK_CREATED,this._onTaskEvent),this._api.removeEventListener(v.TASK_UPDATED,this._onTaskEvent),this._api.removeEventListener(v.TASK_DELETED,this._onTaskEvent)),this._onTaskEvent=()=>this._loadTasks(),this._api.addEventListener(v.TASK_CREATED,this._onTaskEvent),this._api.addEventListener(v.TASK_UPDATED,this._onTaskEvent),this._api.addEventListener(v.TASK_DELETED,this._onTaskEvent)}async _loadTasks(){this._loading=!0,this._error=null,this.render();try{let t=this.getAttribute("project-id"),e=t?{projectId:parseInt(t)}:{};this._tasks=await this._api.listTasks(e);let i=this._state.get("localTasks")||[];i.length>0&&(this._tasks=[...this._tasks,...i.map(a=>({...a,isLocal:!0}))]),this._state.update({"cache.tasks":this._tasks},!1)}catch(t){this._error=t.message,this._tasks=(this._state.get("localTasks")||[]).map(e=>({...e,isLocal:!0}))}this._loading=!1,this.render()}_getTasksByStatus(t){return this._getFilteredTasks().filter(i=>i.status?.toLowerCase().replace(/-/g,"_")===t)}_handleDragStart(t,e){this.hasAttribute("readonly")||(this._draggedTask=e,t.target.classList.add("dragging"),t.dataTransfer.effectAllowed="move",t.dataTransfer.setData("text/plain",e.id.toString()))}_handleDragEnd(t){t.target.classList.remove("dragging"),this._draggedTask=null,this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(e=>{e.classList.remove("drag-over")})}_handleDragOver(t){t.preventDefault(),t.dataTransfer.dropEffect="move"}_handleDragEnter(t){t.preventDefault(),t.currentTarget.classList.add("drag-over")}_handleDragLeave(t){t.currentTarget.contains(t.relatedTarget)||t.currentTarget.classList.remove("drag-over")}async _handleDrop(t,e){if(t.preventDefault(),t.currentTarget.classList.remove("drag-over"),!this._draggedTask||this.hasAttribute("readonly"))return;let i=this._draggedTask.id,a=this._tasks.find(r=>r.id===i);if(!a)return;let s=a.status;if(s!==e){a.status=e,this.render();try{a.isLocal?this._state.moveLocalTask(i,e):await this._api.moveTask(i,e,0),this.dispatchEvent(new CustomEvent("task-moved",{detail:{taskId:i,oldStatus:s,newStatus:e}}))}catch(r){a.status=s,this.render(),console.error("Failed to move task:",r)}}}_toggleCardExpand(t){this._expandedCards.has(t)?this._expandedCards.delete(t):this._expandedCards.add(t),this.render()}_toggleTaskSelection(t,e){e&&e.stopPropagation(),this._selectedTasks.has(t)?this._selectedTasks.delete(t):this._selectedTasks.add(t),this.render()}_toggleBulkMode(){this._bulkMode=!this._bulkMode,this._bulkMode||this._selectedTasks.clear(),this.render()}async _bulkMove(t){let e=[...this._selectedTasks];for(let i of e){let a=this._tasks.find(s=>String(s.id)===String(i));if(a&&a.status!==t)try{a.isLocal?this._state.moveLocalTask(i,t):await this._api.moveTask(i,t,0),a.status=t}catch(s){console.error("Failed to bulk move task:",i,s)}}this._selectedTasks.clear(),this._bulkMode=!1,this.render(),this._loadTasks()}async _bulkDelete(){let t=[...this._selectedTasks];for(let e of t)try{await this._api.deleteTask(e)}catch(i){console.error("Failed to delete task:",e,i)}this._selectedTasks.clear(),this._bulkMode=!1,this._loadTasks()}_setFilter(t){this._activeFilter=t,this.render()}_getFilteredTasks(){let t=[...this._tasks],e=new Date,i=new Date(e.getFullYear(),e.getMonth(),e.getDate()),a=new Date(i.getTime()-7*24*60*60*1e3);switch(this._activeFilter){case"today":t=t.filter(s=>{let r=s.created_at?new Date(s.created_at):null;return r&&r>=i});break;case"this-week":t=t.filter(s=>{let r=s.created_at?new Date(s.created_at):null;return r&&r>=a});break;case"running":t=t.filter(s=>s.status==="in_progress");break;case"failed":t=t.filter(s=>s.status==="failed"||s.status==="error");break;default:break}return t}_openAddTaskModal(t="pending"){this.dispatchEvent(new CustomEvent("add-task",{detail:{status:t}}))}_openTaskDetail(t){this._selectedTask=t,this.render(),this.dispatchEvent(new CustomEvent("task-click",{detail:{task:t}}))}_closeTaskDetail(){this._selectedTask=null,this.render()}_renderMarkdown(t){if(!t)return"";let e=this._escapeHtml(String(t));return e=e.replace(/```([\s\S]*?)```/g,(i,a)=>`<pre class="md-code">${a.trim()}</pre>`),e=e.replace(/`([^`\n]+)`/g,'<code class="md-inline-code">$1</code>'),e=e.replace(/^###\s+(.+)$/gm,'<h4 class="md-h4">$1</h4>'),e=e.replace(/^##\s+(.+)$/gm,'<h3 class="md-h3">$1</h3>'),e=e.replace(/^#\s+(.+)$/gm,'<h2 class="md-h2">$1</h2>'),e=e.replace(/\*\*([^*\n]+)\*\*/g,"<strong>$1</strong>"),e=e.replace(/(^|[^*])\*([^*\n]+)\*/g,"$1<em>$2</em>"),e=e.replace(/(?:^|\n)((?:[-*]\s+.+(?:\n|$))+)/g,(i,a)=>`
1966
- <ul class="md-list">${a.trim().split(/\n/).map(r=>r.replace(/^[-*]\s+/,"")).map(r=>`<li>${r}</li>`).join("")}</ul>`),e=e.split(/\n{2,}/).map(i=>/^<(h\d|ul|ol|pre)/.test(i.trim())?i:`<p class="md-p">${i.replace(/\n/g,"<br>")}</p>`).join(""),e}_formatTimestamp(t){if(!t)return"";try{let e=new Date(t);return isNaN(e.getTime())?this._escapeHtml(String(t)):e.toLocaleString()}catch{return this._escapeHtml(String(t))}}_phaseClass(t){let e=String(t||"").toLowerCase();return["reason","plan","planning"].includes(e)?"phase-reason":["act","execute","execution","implement"].includes(e)?"phase-act":["reflect","review"].includes(e)?"phase-reflect":["verify","test","gate"].includes(e)?"phase-verify":"phase-default"}_logLevelClass(t){let e=String(t||"info").toLowerCase();return e==="error"||e==="fatal"?"log-error":e==="warn"||e==="warning"?"log-warn":e==="debug"||e==="trace"?"log-debug":"log-info"}_renderTaskDetailModal(t){if(!t)return"";let e=(t.priority||"medium").toLowerCase(),i=e.charAt(0).toUpperCase()+e.slice(1),a=t.status||"pending",s=a.replace(/_/g," ").replace(/\b\w/g,m=>m.toUpperCase()),r=t.metadata||{},o=t.acceptance_criteria||[],n=t.context_files||[],l=t.specification||"",c=t.description||"",p=Array.isArray(t.notes)?t.notes:[],u=Array.isArray(t.logs)?t.logs:[],b=t.full_content||"";return`
1965
+ `}};customElements.get("loki-overview")||customElements.define("loki-overview",O);var ct=[{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 u{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(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadTasks()),e==="project-id"&&this._loadTasks(),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e}),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 e=this.getAttribute("project-id"),t=e?{projectId:parseInt(e)}:{};this._tasks=await this._api.listTasks(t);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(e){this._error=e.message,this._tasks=(this._state.get("localTasks")||[]).map(t=>({...t,isLocal:!0}))}this._loading=!1,this.render()}_getTasksByStatus(e){return this._getFilteredTasks().filter(i=>i.status?.toLowerCase().replace(/-/g,"_")===e)}_handleDragStart(e,t){this.hasAttribute("readonly")||(this._draggedTask=t,e.target.classList.add("dragging"),e.dataTransfer.effectAllowed="move",e.dataTransfer.setData("text/plain",t.id.toString()))}_handleDragEnd(e){e.target.classList.remove("dragging"),this._draggedTask=null,this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(t=>{t.classList.remove("drag-over")})}_handleDragOver(e){e.preventDefault(),e.dataTransfer.dropEffect="move"}_handleDragEnter(e){e.preventDefault(),e.currentTarget.classList.add("drag-over")}_handleDragLeave(e){e.currentTarget.contains(e.relatedTarget)||e.currentTarget.classList.remove("drag-over")}async _handleDrop(e,t){if(e.preventDefault(),e.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!==t){a.status=t,this.render();try{a.isLocal?this._state.moveLocalTask(i,t):await this._api.moveTask(i,t,0),this.dispatchEvent(new CustomEvent("task-moved",{detail:{taskId:i,oldStatus:s,newStatus:t}}))}catch(r){a.status=s,this.render(),console.error("Failed to move task:",r)}}}_toggleCardExpand(e){this._expandedCards.has(e)?this._expandedCards.delete(e):this._expandedCards.add(e),this.render()}_toggleTaskSelection(e,t){t&&t.stopPropagation(),this._selectedTasks.has(e)?this._selectedTasks.delete(e):this._selectedTasks.add(e),this.render()}_toggleBulkMode(){this._bulkMode=!this._bulkMode,this._bulkMode||this._selectedTasks.clear(),this.render()}async _bulkMove(e){let t=[...this._selectedTasks];for(let i of t){let a=this._tasks.find(s=>String(s.id)===String(i));if(a&&a.status!==e)try{a.isLocal?this._state.moveLocalTask(i,e):await this._api.moveTask(i,e,0),a.status=e}catch(s){console.error("Failed to bulk move task:",i,s)}}this._selectedTasks.clear(),this._bulkMode=!1,this.render(),this._loadTasks()}async _bulkDelete(){let e=[...this._selectedTasks];for(let t of e)try{await this._api.deleteTask(t)}catch(i){console.error("Failed to delete task:",t,i)}this._selectedTasks.clear(),this._bulkMode=!1,this._loadTasks()}_setFilter(e){this._activeFilter=e,this.render()}_getFilteredTasks(){let e=[...this._tasks],t=new Date,i=new Date(t.getFullYear(),t.getMonth(),t.getDate()),a=new Date(i.getTime()-7*24*60*60*1e3);switch(this._activeFilter){case"today":e=e.filter(s=>{let r=s.created_at?new Date(s.created_at):null;return r&&r>=i});break;case"this-week":e=e.filter(s=>{let r=s.created_at?new Date(s.created_at):null;return r&&r>=a});break;case"running":e=e.filter(s=>s.status==="in_progress");break;case"failed":e=e.filter(s=>s.status==="failed"||s.status==="error");break;default:break}return e}_openAddTaskModal(e="pending"){this.dispatchEvent(new CustomEvent("add-task",{detail:{status:e}}))}_openTaskDetail(e){this._selectedTask=e,this.render(),this.dispatchEvent(new CustomEvent("task-click",{detail:{task:e}}))}_closeTaskDetail(){this._selectedTask=null,this.render()}_renderMarkdown(e){if(!e)return"";let t=this._escapeHtml(String(e));return t=t.replace(/```([\s\S]*?)```/g,(i,a)=>`<pre class="md-code">${a.trim()}</pre>`),t=t.replace(/`([^`\n]+)`/g,'<code class="md-inline-code">$1</code>'),t=t.replace(/^###\s+(.+)$/gm,'<h4 class="md-h4">$1</h4>'),t=t.replace(/^##\s+(.+)$/gm,'<h3 class="md-h3">$1</h3>'),t=t.replace(/^#\s+(.+)$/gm,'<h2 class="md-h2">$1</h2>'),t=t.replace(/\*\*([^*\n]+)\*\*/g,"<strong>$1</strong>"),t=t.replace(/(^|[^*])\*([^*\n]+)\*/g,"$1<em>$2</em>"),t=t.replace(/(?:^|\n)((?:[-*]\s+.+(?:\n|$))+)/g,(i,a)=>`
1966
+ <ul class="md-list">${a.trim().split(/\n/).map(r=>r.replace(/^[-*]\s+/,"")).map(r=>`<li>${r}</li>`).join("")}</ul>`),t=t.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(""),t}_formatTimestamp(e){if(!e)return"";try{let t=new Date(e);return isNaN(t.getTime())?this._escapeHtml(String(e)):t.toLocaleString()}catch{return this._escapeHtml(String(e))}}_phaseClass(e){let t=String(e||"").toLowerCase();return["reason","plan","planning"].includes(t)?"phase-reason":["act","execute","execution","implement"].includes(t)?"phase-act":["reflect","review"].includes(t)?"phase-reflect":["verify","test","gate"].includes(t)?"phase-verify":"phase-default"}_logLevelClass(e){let t=String(e||"info").toLowerCase();return t==="error"||t==="fatal"?"log-error":t==="warn"||t==="warning"?"log-warn":t==="debug"||t==="trace"?"log-debug":"log-info"}_renderTaskDetailModal(e){if(!e)return"";let t=(e.priority||"medium").toLowerCase(),i=t.charAt(0).toUpperCase()+t.slice(1),a=e.status||"pending",s=a.replace(/_/g," ").replace(/\b\w/g,m=>m.toUpperCase()),r=e.metadata||{},o=e.acceptance_criteria||[],n=e.context_files||[],l=e.specification||"",c=e.description||"",p=Array.isArray(e.notes)?e.notes:[],h=Array.isArray(e.logs)?e.logs:[],b=e.full_content||"";return`
1967
1967
  <div class="modal-overlay" id="task-detail-overlay">
1968
1968
  <div class="modal-container">
1969
1969
  <div class="modal-header">
1970
1970
  <div class="modal-header-left">
1971
- <span class="task-id">${t.isLocal?"LOCAL":"#"+this._escapeHtml(String(t.id))}</span>
1972
- <span class="task-priority ${e}">${i}</span>
1971
+ <span class="task-id">${e.isLocal?"LOCAL":"#"+this._escapeHtml(String(e.id))}</span>
1972
+ <span class="task-priority ${t}">${i}</span>
1973
1973
  <span class="task-status-badge ${a}">${s}</span>
1974
1974
  </div>
1975
1975
  <button class="modal-close" id="modal-close-btn" aria-label="Close">&times;</button>
1976
1976
  </div>
1977
- <h2 class="modal-title">${this._escapeHtml(t.title||"Untitled")}</h2>
1977
+ <h2 class="modal-title">${this._escapeHtml(e.title||"Untitled")}</h2>
1978
1978
 
1979
1979
  ${Object.keys(r).length>0?`
1980
1980
  <div class="modal-section">
@@ -2031,16 +2031,16 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
2031
2031
  </div>
2032
2032
  `:""}
2033
2033
 
2034
- ${u.length>0?`
2034
+ ${h.length>0?`
2035
2035
  <div class="modal-section">
2036
2036
  <h3 class="modal-section-title">Logs</h3>
2037
2037
  <div class="logs-scroll">
2038
2038
  <ul class="logs-timeline" role="list">
2039
- ${u.map(m=>{let f=this._formatTimestamp(m&&m.timestamp),x=m&&m.iteration!==void 0&&m.iteration!==null?`i${this._escapeHtml(String(m.iteration))}`:"",w=m&&m.phase?String(m.phase):"",te=this._phaseClass(w),ee=this._logLevelClass(m&&m.level),ie=m&&m.message?this._escapeHtml(String(m.message)):"";return`<li class="log-entry ${ee}">
2039
+ ${h.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):"",et=this._phaseClass(w),tt=this._logLevelClass(m&&m.level),it=m&&m.message?this._escapeHtml(String(m.message)):"";return`<li class="log-entry ${tt}">
2040
2040
  ${f?`<span class="log-time">${f}</span>`:""}
2041
2041
  ${x?`<span class="log-iter">${x}</span>`:""}
2042
- ${w?`<span class="log-phase ${te}">${this._escapeHtml(w)}</span>`:""}
2043
- <span class="log-message">${ie}</span>
2042
+ ${w?`<span class="log-phase ${et}">${this._escapeHtml(w)}</span>`:""}
2043
+ <span class="log-message">${it}</span>
2044
2044
  </li>`}).join("")}
2045
2045
  </ul>
2046
2046
  </div>
@@ -2063,29 +2063,29 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
2063
2063
  </div>
2064
2064
  `:""}
2065
2065
 
2066
- ${t.user_story?`
2066
+ ${e.user_story?`
2067
2067
  <div class="modal-section">
2068
2068
  <h3 class="modal-section-title">User Story</h3>
2069
- <div class="modal-prose">${this._escapeHtml(t.user_story)}</div>
2069
+ <div class="modal-prose">${this._escapeHtml(e.user_story)}</div>
2070
2070
  </div>
2071
2071
  `:""}
2072
2072
 
2073
- ${t.source?`
2073
+ ${e.source?`
2074
2074
  <div class="modal-section">
2075
2075
  <h3 class="modal-section-title">Source</h3>
2076
- <div class="modal-prose"><code>${this._escapeHtml(t.source)}</code></div>
2076
+ <div class="modal-prose"><code>${this._escapeHtml(e.source)}</code></div>
2077
2077
  </div>
2078
2078
  `:""}
2079
2079
 
2080
- ${t.type?`
2080
+ ${e.type?`
2081
2081
  <div class="modal-footer">
2082
- <span class="task-type">${this._escapeHtml(t.type)}</span>
2083
- ${t.assigned_agent_id?`<span class="meta-value">Agent #${t.assigned_agent_id}</span>`:""}
2082
+ <span class="task-type">${this._escapeHtml(e.type)}</span>
2083
+ ${e.assigned_agent_id?`<span class="meta-value">Agent #${e.assigned_agent_id}</span>`:""}
2084
2084
  </div>
2085
2085
  `:""}
2086
2086
  </div>
2087
2087
  </div>
2088
- `}render(){let t=`
2088
+ `}render(){let e=`
2089
2089
  <style>
2090
2090
  ${this.getBaseStyles()}
2091
2091
 
@@ -2916,11 +2916,11 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
2916
2916
  display: block;
2917
2917
  }
2918
2918
  </style>
2919
- `,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"),`
2919
+ `,t=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",h=`Agent #${o.assigned_agent_id||"?"}`;return n.includes("architect")||n==="ar"?(l="AR",c="architect",h="Architect"):n.includes("develop")||n==="dv"?(l="DV",c="developer",h="Developer"):n.includes("test")||n==="ts"?(l="TS",c="tester",h="Tester"):(n.includes("review")||n==="rv")&&(l="RV",c="reviewer",h="Reviewer"),o.status==="in_progress"&&(p="active"),(o.status==="failed"||o.status==="error")&&(p="failed"),`
2920
2920
  <div class="agent-avatar ${c}">
2921
2921
  ${l}
2922
2922
  <span class="agent-status-dot ${p}"></span>
2923
- <span class="agent-tooltip">${this._escapeHtml(u)}</span>
2923
+ <span class="agent-tooltip">${this._escapeHtml(h)}</span>
2924
2924
  </div>
2925
2925
  `};i=`
2926
2926
  <div class="filter-bar">
@@ -2940,12 +2940,12 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
2940
2940
  `:""}
2941
2941
 
2942
2942
  <div class="kanban-board">
2943
- ${ce.map(o=>{let n=this._getTasksByStatus(o.status);return`
2943
+ ${ct.map(o=>{let n=this._getTasksByStatus(o.status);return`
2944
2944
  <div class="kanban-column" data-status="${o.status}">
2945
2945
  <div class="kanban-column-header">
2946
2946
  <span class="kanban-column-title">
2947
2947
  <svg class="column-icon" viewBox="0 0 24 24" style="color: ${o.color}">
2948
- ${e(o.status)}
2948
+ ${t(o.status)}
2949
2949
  </svg>
2950
2950
  ${o.label}
2951
2951
  </span>
@@ -2953,8 +2953,8 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
2953
2953
  </div>
2954
2954
  <div class="kanban-tasks" data-status="${o.status}">
2955
2955
  ${n.length===0?'<div class="empty-column">No tasks</div>':""}
2956
- ${n.map(l=>{let c=String(l.id||""),p=this._expandedCards.has(c),u=this._selectedTasks.has(c);return`
2957
- <div class="task-card ${!a&&!l.fromServer?"draggable":""} ${l.isLocal?"local":""} ${p?"expanded":""} ${u?"selected":""}"
2956
+ ${n.map(l=>{let c=String(l.id||""),p=this._expandedCards.has(c),h=this._selectedTasks.has(c);return`
2957
+ <div class="task-card ${!a&&!l.fromServer?"draggable":""} ${l.isLocal?"local":""} ${p?"expanded":""} ${h?"selected":""}"
2958
2958
  data-task-id="${this._escapeHtml(c)}"
2959
2959
  tabindex="0"
2960
2960
  role="button"
@@ -2962,7 +2962,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
2962
2962
  ${!a&&!l.fromServer?'draggable="true"':""}>
2963
2963
  <div class="task-card-header">
2964
2964
  <div style="display:flex;align-items:center;gap:6px;">
2965
- ${this._bulkMode?`<div class="task-checkbox ${u?"checked":""}" data-check-id="${this._escapeHtml(c)}"></div>`:""}
2965
+ ${this._bulkMode?`<div class="task-checkbox ${h?"checked":""}" data-check-id="${this._escapeHtml(c)}"></div>`:""}
2966
2966
  <span class="task-id">${l.isLocal?"LOCAL":"#"+this._escapeHtml(c)}</span>
2967
2967
  </div>
2968
2968
  <div style="display:flex;align-items:center;gap:6px;">
@@ -2999,7 +2999,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
2999
2999
  `}).join("")}
3000
3000
  </div>
3001
3001
  `}this.shadowRoot.innerHTML=`
3002
- ${t}
3002
+ ${e}
3003
3003
  <div class="board-container">
3004
3004
  <div class="board-header">
3005
3005
  <h2 class="board-title">Task Queue</h2>
@@ -3024,7 +3024,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
3024
3024
  ${i}
3025
3025
  </div>
3026
3026
  ${this._selectedTask?this._renderTaskDetailModal(this._selectedTask):""}
3027
- `,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("refresh-btn");t&&t.addEventListener("click",()=>this._loadTasks());let e=this.shadowRoot.getElementById("bulk-toggle-btn");e&&e.addEventListener("click",()=>this._toggleBulkMode()),this.shadowRoot.querySelectorAll(".filter-pill").forEach(s=>{s.addEventListener("click",()=>this._setFilter(s.dataset.filter))}),this.shadowRoot.querySelectorAll(".bulk-btn").forEach(s=>{s.addEventListener("click",()=>{let r=s.dataset.bulkAction;r==="delete"?this._bulkDelete():this._bulkMove(r)})}),this.shadowRoot.querySelectorAll(".add-task-btn").forEach(s=>{s.addEventListener("click",()=>{this._openAddTaskModal(s.dataset.status)})}),this.shadowRoot.querySelectorAll(".task-checkbox").forEach(s=>{s.addEventListener("click",r=>{r.stopPropagation(),this._toggleTaskSelection(s.dataset.checkId,r)})}),this.shadowRoot.querySelectorAll(".expand-toggle").forEach(s=>{s.addEventListener("click",r=>{r.stopPropagation(),this._toggleCardExpand(s.dataset.expandId)})}),this.shadowRoot.querySelectorAll(".task-card").forEach(s=>{let r=s.dataset.taskId,o=this._tasks.find(n=>n.id.toString()===r);o&&(s.addEventListener("click",n=>{if(this._bulkMode){this._toggleTaskSelection(r,n);return}this._openTaskDetail(o)}),s.addEventListener("keydown",n=>{n.key==="Enter"||n.key===" "?(n.preventDefault(),this._bulkMode?this._toggleTaskSelection(r,n):this._openTaskDetail(o)):(n.key==="ArrowDown"||n.key==="ArrowUp")&&(n.preventDefault(),this._navigateTaskCards(s,n.key==="ArrowDown"?"next":"prev"))}),s.classList.contains("draggable")&&(s.addEventListener("dragstart",n=>this._handleDragStart(n,o)),s.addEventListener("dragend",n=>this._handleDragEnd(n))))}),this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(s=>{s.addEventListener("dragover",r=>this._handleDragOver(r)),s.addEventListener("dragenter",r=>this._handleDragEnter(r)),s.addEventListener("dragleave",r=>this._handleDragLeave(r)),s.addEventListener("drop",r=>this._handleDrop(r,s.dataset.status))});let i=this.shadowRoot.getElementById("modal-close-btn");i&&i.addEventListener("click",()=>this._closeTaskDetail());let a=this.shadowRoot.getElementById("task-detail-overlay");a&&a.addEventListener("click",s=>{s.target===a&&this._closeTaskDetail()})}_escapeHtml(t){let e=document.createElement("div");return e.textContent=t,e.innerHTML}_navigateTaskCards(t,e){let i=Array.from(this.shadowRoot.querySelectorAll(".task-card")),a=i.indexOf(t);if(a===-1)return;let s=e==="next"?a+1:a-1;s>=0&&s<i.length&&i[s].focus()}};customElements.get("loki-task-board")||customElements.define("loki-task-board",q);var J=class extends h{static get observedAttributes(){return["api-url","theme","compact"]}constructor(){super(),this._status={mode:"offline",phase:null,iteration:null,complexity:null,connected:!1,version:null,uptime:0,activeAgents:0,pendingTasks:0},this._api=null,this._state=B(),this._statusUpdateHandler=null,this._connectedHandler=null,this._disconnectedHandler=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(v.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(v.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(v.DISCONNECTED,this._disconnectedHandler))}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadStatus()),t==="theme"&&this._applyTheme(),t==="compact"&&this.render())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t}),this._statusUpdateHandler=e=>this._updateFromStatus(e.detail),this._connectedHandler=()=>{this._status.connected=!0,this.render()},this._disconnectedHandler=()=>{this._status.connected=!1,this._status.mode="offline",this.render()},this._api.addEventListener(v.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(v.CONNECTED,this._connectedHandler),this._api.addEventListener(v.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){try{let t=await this._api.getStatus();this._updateFromStatus(t)}catch{this._status.connected=!1,this._status.mode="offline",this.render()}}_updateFromStatus(t){t&&(this._status={...this._status,connected:!0,mode:t.status||"running",version:t.version,uptime:t.uptime_seconds||0,activeAgents:t.running_agents||0,pendingTasks:t.pending_tasks||0,phase:t.phase,iteration:t.iteration,complexity:t.complexity},this._state.updateSession({connected:!0,mode:this._status.mode,lastSync:new Date().toISOString()}),this.render())}_startPolling(){this._ownPollInterval=setInterval(async()=>{try{let t=await this._api.getStatus();this._updateFromStatus(t)}catch{this._status.connected=!1,this._status.mode="offline",this.render()}},3e3)}_stopPolling(){this._ownPollInterval&&(clearInterval(this._ownPollInterval),this._ownPollInterval=null)}_formatUptime(t){if(!t||t<0)return"--";let e=Math.floor(t/3600),i=Math.floor(t%3600/60),a=Math.floor(t%60);return e>0?`${e}h ${i}m`:i>0?`${i}m ${a}s`:`${a}s`}_escapeHtml(t){let e=document.createElement("div");return e.textContent=String(t??""),e.innerHTML}_getStatusClass(){switch(this._status.mode){case"running":case"autonomous":return"active";case"paused":return"paused";case"stopped":return"stopped";case"error":return"error";default:return"offline"}}_getStatusLabel(){switch(this._status.mode){case"running":case"autonomous":return"AUTONOMOUS";case"paused":return"PAUSED";case"stopped":return"STOPPED";case"error":return"ERROR";default:return"OFFLINE"}}_triggerStart(){this.dispatchEvent(new CustomEvent("session-start",{detail:this._status}))}async _triggerPause(){try{let t=await this._api.pauseSession();if(t&&t.error)throw new Error(t.error);this._status.mode="paused",this.render(),this.dispatchEvent(new CustomEvent("session-pause",{detail:this._status}))}catch(t){console.error("Failed to pause session:",t),this.render()}}async _triggerResume(){try{let t=await this._api.resumeSession();if(t&&t.error)throw new Error(t.error);this._status.mode="running",this.render(),this.dispatchEvent(new CustomEvent("session-resume",{detail:this._status}))}catch(t){console.error("Failed to resume session:",t),this.render()}}async _triggerStop(){try{let t=await this._api.stopSession();if(t&&t.error)throw new Error(t.error);this._status.mode="stopped",this.render(),this.dispatchEvent(new CustomEvent("session-stop",{detail:this._status}))}catch(t){console.error("Failed to stop session:",t),this.render()}}render(){let t=this.hasAttribute("compact"),e=this._getStatusClass(),i=this._getStatusLabel(),a=["running","autonomous"].includes(this._status.mode),s=this._status.mode==="paused",r=`
3027
+ `,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot.getElementById("refresh-btn");e&&e.addEventListener("click",()=>this._loadTasks());let t=this.shadowRoot.getElementById("bulk-toggle-btn");t&&t.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(e){let t=document.createElement("div");return t.textContent=e,t.innerHTML}_navigateTaskCards(e,t){let i=Array.from(this.shadowRoot.querySelectorAll(".task-card")),a=i.indexOf(e);if(a===-1)return;let s=t==="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 u{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(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadStatus()),e==="theme"&&this._applyTheme(),e==="compact"&&this.render())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e}),this._statusUpdateHandler=t=>this._updateFromStatus(t.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 e=await this._api.getStatus();this._updateFromStatus(e)}catch{this._status.connected=!1,this._status.mode="offline",this.render()}}_updateFromStatus(e){e&&(this._status={...this._status,connected:!0,mode:e.status||"running",version:e.version,uptime:e.uptime_seconds||0,activeAgents:e.running_agents||0,pendingTasks:e.pending_tasks||0,phase:e.phase,iteration:e.iteration,complexity:e.complexity},this._state.updateSession({connected:!0,mode:this._status.mode,lastSync:new Date().toISOString()}),this.render())}_startPolling(){this._ownPollInterval=setInterval(async()=>{try{let e=await this._api.getStatus();this._updateFromStatus(e)}catch{this._status.connected=!1,this._status.mode="offline",this.render()}},3e3)}_stopPolling(){this._ownPollInterval&&(clearInterval(this._ownPollInterval),this._ownPollInterval=null)}_formatUptime(e){if(!e||e<0)return"--";let t=Math.floor(e/3600),i=Math.floor(e%3600/60),a=Math.floor(e%60);return t>0?`${t}h ${i}m`:i>0?`${i}m ${a}s`:`${a}s`}_escapeHtml(e){let t=document.createElement("div");return t.textContent=String(e??""),t.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 e=await this._api.pauseSession();if(e&&e.error)throw new Error(e.error);this._status.mode="paused",this.render(),this.dispatchEvent(new CustomEvent("session-pause",{detail:this._status}))}catch(e){console.error("Failed to pause session:",e),this.render()}}async _triggerResume(){try{let e=await this._api.resumeSession();if(e&&e.error)throw new Error(e.error);this._status.mode="running",this.render(),this.dispatchEvent(new CustomEvent("session-resume",{detail:this._status}))}catch(e){console.error("Failed to resume session:",e),this.render()}}async _triggerStop(){try{let e=await this._api.stopSession();if(e&&e.error)throw new Error(e.error);this._status.mode="stopped",this.render(),this.dispatchEvent(new CustomEvent("session-stop",{detail:this._status}))}catch(e){console.error("Failed to stop session:",e),this.render()}}render(){let e=this.hasAttribute("compact"),t=this._getStatusClass(),i=this._getStatusLabel(),a=["running","autonomous"].includes(this._status.mode),s=this._status.mode==="paused",r=`
3028
3028
  <style>
3029
3029
  ${this.getBaseStyles()}
3030
3030
 
@@ -3211,7 +3211,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
3211
3211
  <div class="control-panel compact">
3212
3212
  <div class="status-row">
3213
3213
  <span class="status-value">
3214
- <span class="status-dot ${e}"></span>
3214
+ <span class="status-dot ${t}"></span>
3215
3215
  ${i}
3216
3216
  </span>
3217
3217
  </div>
@@ -3240,7 +3240,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
3240
3240
  <div class="status-row">
3241
3241
  <span class="status-label">Mode</span>
3242
3242
  <span class="status-value">
3243
- <span class="status-dot ${e}"></span>
3243
+ <span class="status-dot ${t}"></span>
3244
3244
  ${i}
3245
3245
  </span>
3246
3246
  </div>
@@ -3302,16 +3302,16 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
3302
3302
  </div>
3303
3303
  `;this.shadowRoot.innerHTML=`
3304
3304
  ${r}
3305
- ${t?o:n}
3306
- `,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("pause-btn"),e=this.shadowRoot.getElementById("resume-btn"),i=this.shadowRoot.getElementById("stop-btn"),a=this.shadowRoot.getElementById("start-btn");t&&t.addEventListener("click",()=>this._triggerPause()),e&&e.addEventListener("click",()=>this._triggerResume()),i&&i.addEventListener("click",()=>this._triggerStop()),a&&a.addEventListener("click",()=>this._triggerStart())}};customElements.get("loki-session-control")||customElements.define("loki-session-control",J);var Ot={info:{color:"var(--loki-blue)",label:"INFO"},success:{color:"var(--loki-green)",label:"SUCCESS"},warning:{color:"var(--loki-yellow)",label:"WARN"},error:{color:"var(--loki-red)",label:"ERROR"},step:{color:"var(--loki-purple)",label:"STEP"},agent:{color:"var(--loki-accent)",label:"AGENT"},debug:{color:"var(--loki-text-muted)",label:"DEBUG"}},G=class extends h{static get observedAttributes(){return["api-url","max-lines","auto-scroll","theme","log-file"]}constructor(){super(),this._logs=[],this._maxLines=500,this._autoScroll=!0,this._filter="",this._levelFilter="all",this._api=null,this._pollInterval=null,this._logMessageHandler=null}connectedCallback(){super.connectedCallback(),this._maxLines=parseInt(this.getAttribute("max-lines"))||500,this._autoScroll=this.hasAttribute("auto-scroll"),this._setupApi(),this._startLogPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopLogPolling(),this._api&&this._logMessageHandler&&this._api.removeEventListener(v.LOG_MESSAGE,this._logMessageHandler)}attributeChangedCallback(t,e,i){if(e!==i)switch(t){case"api-url":this._api&&(this._api.baseUrl=i);break;case"max-lines":this._maxLines=parseInt(i)||500,this._trimLogs(),this.render();break;case"auto-scroll":this._autoScroll=this.hasAttribute("auto-scroll"),this.render();break;case"theme":this._applyTheme();break}}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t}),this._logMessageHandler=e=>this._addLog(e.detail),this._api.addEventListener(v.LOG_MESSAGE,this._logMessageHandler)}_startLogPolling(){let t=this.getAttribute("log-file");t?this._pollLogFile(t):this._pollApiLogs()}async _pollApiLogs(){let t=0,e=async()=>{try{let i=await this._api.getLogs(200);if(Array.isArray(i)&&i.length>t){let a=i.slice(t);for(let s of a)s.message&&s.message.trim()&&this._addLog({message:s.message,level:s.level||"info",timestamp:s.timestamp||new Date().toLocaleTimeString()});t=i.length}}catch{}};e(),this._apiPollInterval=setInterval(e,2e3)}async _pollLogFile(t){let e=0,i=async()=>{try{let a=await fetch(`${t}?t=${Date.now()}`,{credentials:"include"});if(!a.ok)return;let r=(await a.text()).split(`
3307
- `);if(r.length>e){let o=r.slice(e);for(let n of o)n.trim()&&this._addLog(this._parseLine(n));e=r.length}}catch{}};i(),this._pollInterval=setInterval(i,1e3)}_stopLogPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._apiPollInterval&&(clearInterval(this._apiPollInterval),this._apiPollInterval=null)}_parseLine(t){let e=t.match(/^\[([^\]]+)\]\s*\[([^\]]+)\]\s*(.+)$/);if(e)return{timestamp:e[1],level:e[2].toLowerCase(),message:e[3]};let i=t.match(/^(\d{2}:\d{2}:\d{2})\s+(\w+)\s+(.+)$/);return i?{timestamp:i[1],level:i[2].toLowerCase(),message:i[3]}:{timestamp:new Date().toLocaleTimeString(),level:"info",message:t}}_addLog(t){if(!t)return;let e={id:Date.now()+Math.random(),timestamp:t.timestamp||new Date().toLocaleTimeString(),level:(t.level||"info").toLowerCase(),message:t.message||t};this._logs.push(e),this._trimLogs(),this.dispatchEvent(new CustomEvent("log-received",{detail:e})),this._renderLogs(),this._autoScroll&&this._scrollToBottom()}_trimLogs(){this._logs.length>this._maxLines&&(this._logs=this._logs.slice(-this._maxLines))}_clearLogs(){this._logs=[],this.dispatchEvent(new CustomEvent("logs-cleared")),this._renderLogs()}_toggleAutoScroll(){this._autoScroll=!this._autoScroll,this.render(),this._autoScroll&&this._scrollToBottom()}_scrollToBottom(){requestAnimationFrame(()=>{let t=this.shadowRoot.getElementById("log-output");t&&(t.scrollTop=t.scrollHeight)})}_downloadLogs(){let t=this._logs.map(s=>`[${s.timestamp}] [${s.level.toUpperCase()}] ${s.message}`).join(`
3308
- `),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`
3305
+ ${e?o:n}
3306
+ `,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot.getElementById("pause-btn"),t=this.shadowRoot.getElementById("resume-btn"),i=this.shadowRoot.getElementById("stop-btn"),a=this.shadowRoot.getElementById("start-btn");e&&e.addEventListener("click",()=>this._triggerPause()),t&&t.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 Oe={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 u{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(e,t,i){if(t!==i)switch(e){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 e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e}),this._logMessageHandler=t=>this._addLog(t.detail),this._api.addEventListener(v.LOG_MESSAGE,this._logMessageHandler)}_startLogPolling(){let e=this.getAttribute("log-file");e?this._pollLogFile(e):this._pollApiLogs()}async _pollApiLogs(){let e=0,t=async()=>{try{let i=await this._api.getLogs(200);if(Array.isArray(i)&&i.length>e){let a=i.slice(e);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()});e=i.length}}catch{}};t(),this._apiPollInterval=setInterval(t,2e3)}async _pollLogFile(e){let t=0,i=async()=>{try{let a=await fetch(`${e}?t=${Date.now()}`,{credentials:"include"});if(!a.ok)return;let r=(await a.text()).split(`
3307
+ `);if(r.length>t){let o=r.slice(t);for(let n of o)n.trim()&&this._addLog(this._parseLine(n));t=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(e){let t=e.match(/^\[([^\]]+)\]\s*\[([^\]]+)\]\s*(.+)$/);if(t)return{timestamp:t[1],level:t[2].toLowerCase(),message:t[3]};let i=e.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:e}}_addLog(e){if(!e)return;let t={id:Date.now()+Math.random(),timestamp:e.timestamp||new Date().toLocaleTimeString(),level:(e.level||"info").toLowerCase(),message:e.message||e};this._logs.push(t),this._trimLogs(),this.dispatchEvent(new CustomEvent("log-received",{detail:t})),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 e=this.shadowRoot.getElementById("log-output");e&&(e.scrollTop=e.scrollHeight)})}_downloadLogs(){let e=this._logs.map(s=>`[${s.timestamp}] [${s.level.toUpperCase()}] ${s.message}`).join(`
3308
+ `),t=new Blob([e],{type:"text/plain"}),i=URL.createObjectURL(t),a=document.createElement("a");a.href=i,a.download=`loki-logs-${new Date().toISOString().split("T")[0]}.txt`,a.click(),URL.revokeObjectURL(i)}_setFilter(e){this._filter=e.toLowerCase(),this._renderLogs()}_setLevelFilter(e){this._levelFilter=e,this._renderLogs()}_getFilteredLogs(){return this._logs.filter(e=>!(this._levelFilter!=="all"&&e.level!==this._levelFilter||this._filter&&!e.message.toLowerCase().includes(this._filter)))}_renderLogs(){let e=this.shadowRoot.getElementById("log-output");if(!e)return;let t=this._getFilteredLogs();if(t.length===0){e.innerHTML='<div class="log-empty">No log output yet. Terminal will update when Loki Mode is running.</div>';return}e.innerHTML=t.map(i=>{let a=Oe[i.level]||Oe.info;return`
3309
3309
  <div class="log-line">
3310
3310
  <span class="timestamp">${this._escapeHtml(i.timestamp)}</span>
3311
3311
  <span class="level" style="color: ${a.color}">[${this._escapeHtml(a.label)}]</span>
3312
3312
  <span class="message">${this._escapeHtml(i.message)}</span>
3313
3313
  </div>
3314
- `}).join(""),this._autoScroll&&this._scrollToBottom()}_escapeHtml(t){let e=document.createElement("div");return e.textContent=t,e.innerHTML}render(){let t=`
3314
+ `}).join(""),this._autoScroll&&this._scrollToBottom()}_escapeHtml(e){let t=document.createElement("div");return t.textContent=e,t.innerHTML}render(){let e=`
3315
3315
  <style>
3316
3316
  ${this.getBaseStyles()}
3317
3317
 
@@ -3469,7 +3469,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
3469
3469
  .log-output::-webkit-scrollbar-thumb:hover { background: var(--loki-text-muted); }
3470
3470
  </style>
3471
3471
  `;this.shadowRoot.innerHTML=`
3472
- ${t}
3472
+ ${e}
3473
3473
  <div class="terminal-container">
3474
3474
  <div class="terminal-header">
3475
3475
  <div class="terminal-title">
@@ -3504,10 +3504,10 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
3504
3504
  ${this._logs.length} lines (${this._getFilteredLogs().length} shown)
3505
3505
  </div>
3506
3506
  </div>
3507
- `,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:
3508
- - Patterns created: ${t.patternsCreated}
3509
- - Patterns merged: ${t.patternsMerged}
3510
- - 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`
3507
+ `,this._attachEventListeners(),this._renderLogs()}_attachEventListeners(){let e=this.shadowRoot.getElementById("filter-input"),t=this.shadowRoot.getElementById("level-select"),i=this.shadowRoot.getElementById("auto-scroll-btn"),a=this.shadowRoot.getElementById("clear-btn"),s=this.shadowRoot.getElementById("download-btn");e&&(e.value=this._filter,e.addEventListener("input",r=>this._setFilter(r.target.value))),t&&(t.value=this._levelFilter,t.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(e,t="info"){this._addLog({message:e,level:t,timestamp:new Date().toLocaleTimeString()})}clear(){this._clearLogs()}};customElements.get("loki-log-stream")||customElements.define("loki-log-stream",G);var pt=[{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 u{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(e,t,i){if(t!==i)switch(e){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 e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}async _loadData(){this._loading=!0,this._error=null,this.render();try{let[e,t,i]=await Promise.allSettled([this._api.getMemorySummary(),this._api.getTokenEconomics(),this._api.getMemoryStats()]);this._summary=e.status==="fulfilled"?e.value:null,this._tokenEconomics=t.status==="fulfilled"?t.value:null,this._stats=i.status==="fulfilled"?i.value:null,await this._loadTabData()}catch(e){this._error=e.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(e){this._activeTab!==e&&(this._activeTab=e,this._selectedItem=null,this._loadTabData().then(()=>this.render()))}async _selectEpisode(e){try{this._lastFocusedElement=this.shadowRoot.activeElement,this._selectedItem=await this._api.getEpisode(e),this.dispatchEvent(new CustomEvent("episode-select",{detail:this._selectedItem})),this.render(),this._focusDetailPanel()}catch(t){console.error("Failed to load episode:",t)}}async _selectPattern(e){try{this._lastFocusedElement=this.shadowRoot.activeElement,this._selectedItem=await this._api.getPattern(e),this.dispatchEvent(new CustomEvent("pattern-select",{detail:this._selectedItem})),this.render(),this._focusDetailPanel()}catch(t){console.error("Failed to load pattern:",t)}}async _selectSkill(e){try{this._lastFocusedElement=this.shadowRoot.activeElement,this._selectedItem=await this._api.getSkill(e),this.dispatchEvent(new CustomEvent("skill-select",{detail:this._selectedItem})),this.render(),this._focusDetailPanel()}catch(t){console.error("Failed to load skill:",t)}}_focusDetailPanel(){requestAnimationFrame(()=>{let e=this.shadowRoot.getElementById("close-detail");e&&e.focus()})}_closeDetail(){this._selectedItem=null,this.render(),this._lastFocusedElement&&requestAnimationFrame(()=>{this._lastFocusedElement.focus(),this._lastFocusedElement=null})}async _triggerConsolidation(){try{let e=await this._api.consolidateMemory(24);alert(`Consolidation complete:
3508
+ - Patterns created: ${e.patternsCreated}
3509
+ - Patterns merged: ${e.patternsMerged}
3510
+ - Episodes processed: ${e.episodesProcessed}`),this._loadData()}catch(e){alert("Consolidation failed: "+e.message)}}async _executeSearch(){let e=this._searchQuery.trim();if(e){this._searchLoading=!0,this._searchError=null,this.render();try{let t=await this._api.searchMemory(e,this._searchCollection,20);this._searchResults=t.results||[]}catch(t){this._searchError=t.message||"Search failed",this._searchResults=[]}this._searchLoading=!1,this.render(),requestAnimationFrame(()=>{let t=this.shadowRoot.getElementById("memory-search-input");t&&t.focus()})}}_renderSearch(){let e=["all","episodes","patterns","skills"];return`
3511
3511
  <div class="search-panel">
3512
3512
  <div class="search-bar">
3513
3513
  <input type="text" id="memory-search-input" class="search-input"
@@ -3515,7 +3515,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
3515
3515
  value="${this._escapeHtml(this._searchQuery)}"
3516
3516
  aria-label="Search memory">
3517
3517
  <select id="memory-search-collection" class="search-select" aria-label="Collection filter">
3518
- ${t.map(e=>`<option value="${e}" ${this._searchCollection===e?"selected":""}>${e}</option>`).join("")}
3518
+ ${e.map(t=>`<option value="${t}" ${this._searchCollection===t?"selected":""}>${t}</option>`).join("")}
3519
3519
  </select>
3520
3520
  <button class="btn btn-primary" id="search-btn" ${this._searchLoading?"disabled":""}>
3521
3521
  ${this._searchLoading?"Searching...":"Search"}
@@ -3527,18 +3527,18 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
3527
3527
  <span>${this._searchResults.length} result${this._searchResults.length!==1?"s":""} for "${this._escapeHtml(this._searchQuery)}"</span>
3528
3528
  </div>
3529
3529
  <div class="item-list" role="list" aria-label="Search results">
3530
- ${this._searchResults.map(e=>`
3530
+ ${this._searchResults.map(t=>`
3531
3531
  <div class="item-card search-result" tabindex="0" role="listitem"
3532
- aria-label="${this._escapeHtml(e.collection||"unknown")}: ${this._escapeHtml(e.snippet||e.id)}">
3532
+ aria-label="${this._escapeHtml(t.collection||"unknown")}: ${this._escapeHtml(t.snippet||t.id)}">
3533
3533
  <div class="item-header">
3534
- <span class="item-category">${this._escapeHtml(e.collection||"unknown")}</span>
3535
- <span class="item-id mono">${this._escapeHtml(e.id||"")}</span>
3534
+ <span class="item-category">${this._escapeHtml(t.collection||"unknown")}</span>
3535
+ <span class="item-id mono">${this._escapeHtml(t.id||"")}</span>
3536
3536
  </div>
3537
- <div class="item-title">${this._escapeHtml(e.snippet||e.id||"")}</div>
3537
+ <div class="item-title">${this._escapeHtml(t.snippet||t.id||"")}</div>
3538
3538
  <div class="item-meta">
3539
- ${e.rank!=null?`<span>Rank: ${e.rank}</span>`:""}
3540
- ${e.category?`<span>${this._escapeHtml(e.category)}</span>`:""}
3541
- ${e.timestamp?`<span>${new Date(e.timestamp).toLocaleString()}</span>`:""}
3539
+ ${t.rank!=null?`<span>Rank: ${t.rank}</span>`:""}
3540
+ ${t.category?`<span>${this._escapeHtml(t.category)}</span>`:""}
3541
+ ${t.timestamp?`<span>${new Date(t.timestamp).toLocaleString()}</span>`:""}
3542
3542
  </div>
3543
3543
  </div>
3544
3544
  `).join("")}
@@ -3546,33 +3546,33 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
3546
3546
  `:!this._searchLoading&&this._searchQuery?'<div class="empty-state">No results found</div>':""}
3547
3547
  ${this._searchQuery?"":'<div class="empty-state">Enter a query to search across all memory layers using full-text search</div>'}
3548
3548
  </div>
3549
- `}_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`
3549
+ `}_renderSummary(){if(!this._summary)return'<div class="empty-state">No memory data available</div>';let{episodic:e,semantic:t,procedural:i,tokenEconomics:a}=this._summary;return`
3550
3550
  <div class="summary-grid">
3551
3551
  <div class="summary-card">
3552
3552
  <div class="summary-card-header">
3553
3553
  <span class="summary-card-title">Episodic Memory</span>
3554
- <span class="summary-card-count">${t?.count||0}</span>
3554
+ <span class="summary-card-count">${e?.count||0}</span>
3555
3555
  </div>
3556
3556
  <div class="summary-card-detail">
3557
3557
  Specific interaction traces and outcomes
3558
3558
  </div>
3559
- ${t?.latestDate?`<div class="summary-card-meta">Latest: ${new Date(t.latestDate).toLocaleDateString()}</div>`:""}
3559
+ ${e?.latestDate?`<div class="summary-card-meta">Latest: ${new Date(e.latestDate).toLocaleDateString()}</div>`:""}
3560
3560
  <div class="memory-bar">
3561
- <div class="memory-bar-fill episodic" style="width: ${Math.min((t?.count||0)/100*100,100)}%"></div>
3561
+ <div class="memory-bar-fill episodic" style="width: ${Math.min((e?.count||0)/100*100,100)}%"></div>
3562
3562
  </div>
3563
3563
  </div>
3564
3564
 
3565
3565
  <div class="summary-card">
3566
3566
  <div class="summary-card-header">
3567
3567
  <span class="summary-card-title">Semantic Memory</span>
3568
- <span class="summary-card-count">${e?.patterns||0}</span>
3568
+ <span class="summary-card-count">${t?.patterns||0}</span>
3569
3569
  </div>
3570
3570
  <div class="summary-card-detail">
3571
3571
  Generalized patterns and anti-patterns
3572
3572
  </div>
3573
- <div class="summary-card-meta">Anti-patterns: ${e?.antiPatterns||0}</div>
3573
+ <div class="summary-card-meta">Anti-patterns: ${t?.antiPatterns||0}</div>
3574
3574
  <div class="memory-bar">
3575
- <div class="memory-bar-fill semantic" style="width: ${Math.min((e?.patterns||0)/100*100,100)}%"></div>
3575
+ <div class="memory-bar-fill semantic" style="width: ${Math.min((t?.patterns||0)/100*100,100)}%"></div>
3576
3576
  </div>
3577
3577
  </div>
3578
3578
 
@@ -3679,94 +3679,94 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
3679
3679
  </div>
3680
3680
  `}_renderEpisodes(){return this._episodes.length===0?'<div class="empty-state">No episodes recorded yet</div>':`
3681
3681
  <div class="item-list" role="list" aria-label="Episodes list">
3682
- ${this._episodes.map(t=>`
3683
- <div class="item-card" data-id="${t.id}" data-type="episode" tabindex="0" role="listitem" aria-label="Episode ${t.id}: ${this._escapeHtml(t.taskId||"Task")}, outcome ${t.outcome||"unknown"}">
3682
+ ${this._episodes.map(e=>`
3683
+ <div class="item-card" data-id="${e.id}" data-type="episode" tabindex="0" role="listitem" aria-label="Episode ${e.id}: ${this._escapeHtml(e.taskId||"Task")}, outcome ${e.outcome||"unknown"}">
3684
3684
  <div class="item-header">
3685
- <span class="item-id mono">${t.id}</span>
3686
- <span class="item-outcome ${t.outcome?.toLowerCase()}">${t.outcome||"unknown"}</span>
3685
+ <span class="item-id mono">${e.id}</span>
3686
+ <span class="item-outcome ${e.outcome?.toLowerCase()}">${e.outcome||"unknown"}</span>
3687
3687
  </div>
3688
- <div class="item-title">${this._escapeHtml(t.taskId||"Task")}</div>
3688
+ <div class="item-title">${this._escapeHtml(e.taskId||"Task")}</div>
3689
3689
  <div class="item-meta">
3690
- <span>${t.agent||"unknown agent"}</span>
3691
- <span>${t.phase||"unknown phase"}</span>
3692
- <span>${new Date(t.timestamp).toLocaleString()}</span>
3690
+ <span>${e.agent||"unknown agent"}</span>
3691
+ <span>${e.phase||"unknown phase"}</span>
3692
+ <span>${new Date(e.timestamp).toLocaleString()}</span>
3693
3693
  </div>
3694
3694
  </div>
3695
3695
  `).join("")}
3696
3696
  </div>
3697
3697
  `}_renderPatterns(){return this._patterns.length===0?'<div class="empty-state">No patterns discovered yet</div>':`
3698
3698
  <div class="item-list" role="list" aria-label="Patterns list">
3699
- ${this._patterns.map(t=>`
3700
- <div class="item-card" data-id="${t.id}" data-type="pattern" tabindex="0" role="listitem" aria-label="Pattern: ${this._escapeHtml(t.pattern)}, ${(t.confidence*100).toFixed(0)} percent confidence">
3699
+ ${this._patterns.map(e=>`
3700
+ <div class="item-card" data-id="${e.id}" data-type="pattern" tabindex="0" role="listitem" aria-label="Pattern: ${this._escapeHtml(e.pattern)}, ${(e.confidence*100).toFixed(0)} percent confidence">
3701
3701
  <div class="item-header">
3702
- <span class="item-category">${t.category||"general"}</span>
3703
- <span class="confidence-badge">${(t.confidence*100).toFixed(0)}%</span>
3702
+ <span class="item-category">${e.category||"general"}</span>
3703
+ <span class="confidence-badge">${(e.confidence*100).toFixed(0)}%</span>
3704
3704
  </div>
3705
- <div class="item-title">${this._escapeHtml(t.pattern)}</div>
3705
+ <div class="item-title">${this._escapeHtml(e.pattern)}</div>
3706
3706
  <div class="item-meta">
3707
- <span>Used ${t.usageCount||0} times</span>
3707
+ <span>Used ${e.usageCount||0} times</span>
3708
3708
  </div>
3709
3709
  </div>
3710
3710
  `).join("")}
3711
3711
  </div>
3712
3712
  `}_renderSkills(){return this._skills.length===0?'<div class="empty-state">No skills learned yet</div>':`
3713
3713
  <div class="item-list" role="list" aria-label="Skills list">
3714
- ${this._skills.map(t=>`
3715
- <div class="item-card" data-id="${t.id}" data-type="skill" tabindex="0" role="listitem" aria-label="Skill: ${this._escapeHtml(t.name)}">
3714
+ ${this._skills.map(e=>`
3715
+ <div class="item-card" data-id="${e.id}" data-type="skill" tabindex="0" role="listitem" aria-label="Skill: ${this._escapeHtml(e.name)}">
3716
3716
  <div class="item-header">
3717
- <span class="item-id mono">${t.id}</span>
3717
+ <span class="item-id mono">${e.id}</span>
3718
3718
  </div>
3719
- <div class="item-title">${this._escapeHtml(t.name)}</div>
3720
- <div class="item-description">${this._escapeHtml(t.description||"")}</div>
3719
+ <div class="item-title">${this._escapeHtml(e.name)}</div>
3720
+ <div class="item-description">${this._escapeHtml(e.description||"")}</div>
3721
3721
  </div>
3722
3722
  `).join("")}
3723
3723
  </div>
3724
- `}_renderDetail(){if(!this._selectedItem)return"";let t=this._selectedItem;return t.actionLog!==void 0?`
3724
+ `}_renderDetail(){if(!this._selectedItem)return"";let e=this._selectedItem;return e.actionLog!==void 0?`
3725
3725
  <div class="detail-panel">
3726
3726
  <div class="detail-header">
3727
- <h3>Episode: ${t.id}</h3>
3727
+ <h3>Episode: ${e.id}</h3>
3728
3728
  <button class="close-btn" id="close-detail">&times;</button>
3729
3729
  </div>
3730
3730
  <div class="detail-body">
3731
3731
  <div class="detail-row">
3732
3732
  <span class="detail-label">Task</span>
3733
- <span class="detail-value">${t.taskId||"--"}</span>
3733
+ <span class="detail-value">${e.taskId||"--"}</span>
3734
3734
  </div>
3735
3735
  <div class="detail-row">
3736
3736
  <span class="detail-label">Agent</span>
3737
- <span class="detail-value">${t.agent||"--"}</span>
3737
+ <span class="detail-value">${e.agent||"--"}</span>
3738
3738
  </div>
3739
3739
  <div class="detail-row">
3740
3740
  <span class="detail-label">Phase</span>
3741
- <span class="detail-value">${t.phase||"--"}</span>
3741
+ <span class="detail-value">${e.phase||"--"}</span>
3742
3742
  </div>
3743
3743
  <div class="detail-row">
3744
3744
  <span class="detail-label">Outcome</span>
3745
- <span class="detail-value outcome ${t.outcome?.toLowerCase()}">${t.outcome||"--"}</span>
3745
+ <span class="detail-value outcome ${e.outcome?.toLowerCase()}">${e.outcome||"--"}</span>
3746
3746
  </div>
3747
3747
  <div class="detail-row">
3748
3748
  <span class="detail-label">Duration</span>
3749
- <span class="detail-value">${t.durationSeconds||0}s</span>
3749
+ <span class="detail-value">${e.durationSeconds||0}s</span>
3750
3750
  </div>
3751
3751
  <div class="detail-row">
3752
3752
  <span class="detail-label">Tokens Used</span>
3753
- <span class="detail-value">${t.tokensUsed?.toLocaleString()||0}</span>
3753
+ <span class="detail-value">${e.tokensUsed?.toLocaleString()||0}</span>
3754
3754
  </div>
3755
- ${t.goal?`
3755
+ ${e.goal?`
3756
3756
  <div class="detail-section">
3757
3757
  <div class="detail-label">Goal</div>
3758
- <div class="detail-content">${this._escapeHtml(t.goal)}</div>
3758
+ <div class="detail-content">${this._escapeHtml(e.goal)}</div>
3759
3759
  </div>
3760
3760
  `:""}
3761
- ${t.actionLog?.length?`
3761
+ ${e.actionLog?.length?`
3762
3762
  <div class="detail-section">
3763
- <div class="detail-label">Action Log (${t.actionLog.length})</div>
3763
+ <div class="detail-label">Action Log (${e.actionLog.length})</div>
3764
3764
  <div class="action-log">
3765
- ${t.actionLog.map(e=>`
3765
+ ${e.actionLog.map(t=>`
3766
3766
  <div class="action-entry">
3767
- <span class="action-time">+${e.t}s</span>
3768
- <span class="action-type">${e.action}</span>
3769
- <span class="action-target">${this._escapeHtml(e.target)}</span>
3767
+ <span class="action-time">+${t.t}s</span>
3768
+ <span class="action-type">${t.action}</span>
3769
+ <span class="action-target">${this._escapeHtml(t.target)}</span>
3770
3770
  </div>
3771
3771
  `).join("")}
3772
3772
  </div>
@@ -3774,89 +3774,89 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
3774
3774
  `:""}
3775
3775
  </div>
3776
3776
  </div>
3777
- `:t.conditions!==void 0?`
3777
+ `:e.conditions!==void 0?`
3778
3778
  <div class="detail-panel">
3779
3779
  <div class="detail-header">
3780
- <h3>Pattern: ${t.id}</h3>
3780
+ <h3>Pattern: ${e.id}</h3>
3781
3781
  <button class="close-btn" id="close-detail">&times;</button>
3782
3782
  </div>
3783
3783
  <div class="detail-body">
3784
3784
  <div class="detail-row">
3785
3785
  <span class="detail-label">Category</span>
3786
- <span class="detail-value">${t.category||"general"}</span>
3786
+ <span class="detail-value">${e.category||"general"}</span>
3787
3787
  </div>
3788
3788
  <div class="detail-row">
3789
3789
  <span class="detail-label">Confidence</span>
3790
- <span class="detail-value">${(t.confidence*100).toFixed(0)}%</span>
3790
+ <span class="detail-value">${(e.confidence*100).toFixed(0)}%</span>
3791
3791
  </div>
3792
3792
  <div class="detail-row">
3793
3793
  <span class="detail-label">Usage Count</span>
3794
- <span class="detail-value">${t.usageCount||0}</span>
3794
+ <span class="detail-value">${e.usageCount||0}</span>
3795
3795
  </div>
3796
3796
  <div class="detail-section">
3797
3797
  <div class="detail-label">Pattern</div>
3798
- <div class="detail-content">${this._escapeHtml(t.pattern)}</div>
3798
+ <div class="detail-content">${this._escapeHtml(e.pattern)}</div>
3799
3799
  </div>
3800
- ${t.conditions?.length?`
3800
+ ${e.conditions?.length?`
3801
3801
  <div class="detail-section">
3802
3802
  <div class="detail-label">Conditions</div>
3803
3803
  <ul class="detail-list">
3804
- ${t.conditions.map(e=>`<li>${this._escapeHtml(e)}</li>`).join("")}
3804
+ ${e.conditions.map(t=>`<li>${this._escapeHtml(t)}</li>`).join("")}
3805
3805
  </ul>
3806
3806
  </div>
3807
3807
  `:""}
3808
- ${t.correctApproach?`
3808
+ ${e.correctApproach?`
3809
3809
  <div class="detail-section">
3810
3810
  <div class="detail-label">Correct Approach</div>
3811
- <div class="detail-content success">${this._escapeHtml(t.correctApproach)}</div>
3811
+ <div class="detail-content success">${this._escapeHtml(e.correctApproach)}</div>
3812
3812
  </div>
3813
3813
  `:""}
3814
- ${t.incorrectApproach?`
3814
+ ${e.incorrectApproach?`
3815
3815
  <div class="detail-section">
3816
3816
  <div class="detail-label">Incorrect Approach</div>
3817
- <div class="detail-content error">${this._escapeHtml(t.incorrectApproach)}</div>
3817
+ <div class="detail-content error">${this._escapeHtml(e.incorrectApproach)}</div>
3818
3818
  </div>
3819
3819
  `:""}
3820
3820
  </div>
3821
3821
  </div>
3822
- `:t.steps!==void 0?`
3822
+ `:e.steps!==void 0?`
3823
3823
  <div class="detail-panel">
3824
3824
  <div class="detail-header">
3825
- <h3>Skill: ${t.name}</h3>
3825
+ <h3>Skill: ${e.name}</h3>
3826
3826
  <button class="close-btn" id="close-detail">&times;</button>
3827
3827
  </div>
3828
3828
  <div class="detail-body">
3829
3829
  <div class="detail-section">
3830
3830
  <div class="detail-label">Description</div>
3831
- <div class="detail-content">${this._escapeHtml(t.description)}</div>
3831
+ <div class="detail-content">${this._escapeHtml(e.description)}</div>
3832
3832
  </div>
3833
- ${t.prerequisites?.length?`
3833
+ ${e.prerequisites?.length?`
3834
3834
  <div class="detail-section">
3835
3835
  <div class="detail-label">Prerequisites</div>
3836
3836
  <ul class="detail-list">
3837
- ${t.prerequisites.map(e=>`<li>${this._escapeHtml(e)}</li>`).join("")}
3837
+ ${e.prerequisites.map(t=>`<li>${this._escapeHtml(t)}</li>`).join("")}
3838
3838
  </ul>
3839
3839
  </div>
3840
3840
  `:""}
3841
- ${t.steps?.length?`
3841
+ ${e.steps?.length?`
3842
3842
  <div class="detail-section">
3843
3843
  <div class="detail-label">Steps</div>
3844
3844
  <ol class="detail-list numbered">
3845
- ${t.steps.map(e=>`<li>${this._escapeHtml(e)}</li>`).join("")}
3845
+ ${e.steps.map(t=>`<li>${this._escapeHtml(t)}</li>`).join("")}
3846
3846
  </ol>
3847
3847
  </div>
3848
3848
  `:""}
3849
- ${t.exitCriteria?.length?`
3849
+ ${e.exitCriteria?.length?`
3850
3850
  <div class="detail-section">
3851
3851
  <div class="detail-label">Exit Criteria</div>
3852
3852
  <ul class="detail-list">
3853
- ${t.exitCriteria.map(e=>`<li>${this._escapeHtml(e)}</li>`).join("")}
3853
+ ${e.exitCriteria.map(t=>`<li>${this._escapeHtml(t)}</li>`).join("")}
3854
3854
  </ul>
3855
3855
  </div>
3856
3856
  `:""}
3857
3857
  </div>
3858
3858
  </div>
3859
- `:""}_escapeHtml(t){if(!t)return"";let e=document.createElement("div");return e.textContent=t,e.innerHTML}render(){let t=`
3859
+ `:""}_escapeHtml(e){if(!e)return"";let t=document.createElement("div");return t.textContent=e,t.innerHTML}render(){let e=`
3860
3860
  <style>
3861
3861
  ${this.getBaseStyles()}
3862
3862
 
@@ -4365,17 +4365,17 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
4365
4365
  font-size: 12px;
4366
4366
  }
4367
4367
  </style>
4368
- `,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=`
4368
+ `,t;if(this._loading)t='<div class="loading">Loading memory data...</div>';else if(this._error)t=`<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()}t=`
4369
4369
  <div class="content-main">${i}</div>
4370
4370
  ${this._renderDetail()}
4371
4371
  `}this.shadowRoot.innerHTML=`
4372
- ${t}
4372
+ ${e}
4373
4373
  <div class="memory-browser">
4374
4374
  <div class="browser-header">
4375
4375
  <span class="browser-title">Memory System</span>
4376
4376
  </div>
4377
4377
  <div class="tabs" role="tablist" aria-label="Memory browser sections">
4378
- ${pe.map((i,a)=>`
4378
+ ${pt.map((i,a)=>`
4379
4379
  <button class="tab ${this._activeTab===i.id?"active":""}"
4380
4380
  data-tab="${i.id}"
4381
4381
  role="tab"
@@ -4389,32 +4389,32 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
4389
4389
  `).join("")}
4390
4390
  </div>
4391
4391
  <div class="browser-content" role="tabpanel" id="tabpanel-${this._activeTab}" aria-labelledby="tab-${this._activeTab}">
4392
- ${e}
4392
+ ${t}
4393
4393
  </div>
4394
4394
  </div>
4395
- `,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`
4395
+ `,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot.querySelectorAll(".tab");e.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(e),h=c.key==="ArrowRight"?(l+1)%p.length:(l-1+p.length)%p.length;p[h].focus(),this._setTab(p[h].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 t=this.shadowRoot.getElementById("close-detail");t&&t.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(e){let t=e.dataset.id;switch(e.dataset.type){case"episode":this._selectEpisode(t);break;case"pattern":this._selectPattern(t);break;case"skill":this._selectSkill(t);break}}_navigateItemCards(e,t){let i=Array.from(this.shadowRoot.querySelectorAll(".item-card")),a=i.indexOf(e);if(a===-1)return;let s=t==="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 ht=[{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}],ut=[{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"}],gt=[{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 u{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(e,t,i){if(t!==i)switch(e){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 e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}async _loadData(){this._loading=!0,this._error=null,this.render();try{let e={timeRange:this._timeRange,signalType:this._signalType!=="all"?this._signalType:void 0,source:this._source!=="all"?this._source:void 0},[t,i,a]=await Promise.all([this._api.getLearningMetrics(e).catch(()=>null),this._api.getLearningTrends(e).catch(()=>null),this._api.getLearningSignals({...e,limit:50}).catch(()=>[])]);this._metrics=t,this._trends=i,this._signals=a||[]}catch(e){this._error=e.message||"Failed to load learning data"}this._loading=!1,this.render()}_setFilter(e,t){switch(e){case"timeRange":this._timeRange=t,this.setAttribute("time-range",t);break;case"signalType":this._signalType=t,this.setAttribute("signal-type",t);break;case"source":this._source=t,this.setAttribute("source",t);break}this.dispatchEvent(new CustomEvent("filter-change",{detail:{timeRange:this._timeRange,signalType:this._signalType,source:this._source}})),this._loadData()}_selectMetric(e,t){this._selectedMetric={type:e,item:t},this.dispatchEvent(new CustomEvent("metric-select",{detail:{type:e,item:t}})),this.render()}_closeDetail(){this._selectedMetric=null,this.render()}_formatNumber(e){return e>=1e6?(e/1e6).toFixed(1)+"M":e>=1e3?(e/1e3).toFixed(1)+"K":e?.toString()||"0"}_formatPercent(e){return(e*100).toFixed(1)+"%"}_formatDuration(e){return e<60?e.toFixed(0)+"s":e<3600?(e/60).toFixed(1)+"m":(e/3600).toFixed(1)+"h"}_escapeHtml(e){if(!e)return"";let t=document.createElement("div");return t.textContent=e,t.innerHTML}_renderFilters(){return`
4396
4396
  <div class="filters">
4397
4397
  <div class="filter-group">
4398
4398
  <label>Time Range</label>
4399
4399
  <select id="time-range-select" class="filter-select">
4400
- ${he.map(t=>`
4401
- <option value="${t.id}" ${this._timeRange===t.id?"selected":""}>${t.label}</option>
4400
+ ${ht.map(e=>`
4401
+ <option value="${e.id}" ${this._timeRange===e.id?"selected":""}>${e.label}</option>
4402
4402
  `).join("")}
4403
4403
  </select>
4404
4404
  </div>
4405
4405
  <div class="filter-group">
4406
4406
  <label>Signal Type</label>
4407
4407
  <select id="signal-type-select" class="filter-select">
4408
- ${ue.map(t=>`
4409
- <option value="${t.id}" ${this._signalType===t.id?"selected":""}>${t.label}</option>
4408
+ ${ut.map(e=>`
4409
+ <option value="${e.id}" ${this._signalType===e.id?"selected":""}>${e.label}</option>
4410
4410
  `).join("")}
4411
4411
  </select>
4412
4412
  </div>
4413
4413
  <div class="filter-group">
4414
4414
  <label>Source</label>
4415
4415
  <select id="source-select" class="filter-select">
4416
- ${ge.map(t=>`
4417
- <option value="${t.id}" ${this._source===t.id?"selected":""}>${t.label}</option>
4416
+ ${gt.map(e=>`
4417
+ <option value="${e.id}" ${this._source===e.id?"selected":""}>${e.label}</option>
4418
4418
  `).join("")}
4419
4419
  </select>
4420
4420
  </div>
@@ -4426,16 +4426,16 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
4426
4426
  Refresh
4427
4427
  </button>
4428
4428
  </div>
4429
- `}_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`
4429
+ `}_renderSummaryCards(){if(!this._metrics)return'<div class="empty-state">No metrics available</div>';let{totalSignals:e,signalsByType:t,signalsBySource:i,aggregation:a}=this._metrics;return`
4430
4430
  <div class="summary-cards">
4431
4431
  <div class="summary-card">
4432
4432
  <div class="summary-card-header">
4433
4433
  <span class="summary-card-title">Total Signals</span>
4434
- <span class="summary-card-count">${this._formatNumber(t||0)}</span>
4434
+ <span class="summary-card-count">${this._formatNumber(e||0)}</span>
4435
4435
  </div>
4436
4436
  <div class="summary-card-detail">Learning signals collected</div>
4437
4437
  <div class="signal-breakdown">
4438
- ${Object.entries(e||{}).map(([s,r])=>`
4438
+ ${Object.entries(t||{}).map(([s,r])=>`
4439
4439
  <div class="breakdown-item">
4440
4440
  <span class="breakdown-label">${s.replace("_"," ")}</span>
4441
4441
  <span class="breakdown-value">${this._formatNumber(r)}</span>
@@ -4495,7 +4495,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
4495
4495
  </div>
4496
4496
  </div>
4497
4497
  </div>
4498
- `}_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`
4498
+ `}_renderTrendChart(){if(!this._trends||!this._trends.dataPoints||this._trends.dataPoints.length===0)return'<div class="chart-empty">No trend data available</div>';let{dataPoints:e,maxValue:t}=this._trends,i=120,a=400,s=20,r=e.map((n,l)=>{let c=s+l/(e.length-1||1)*(a-s*2),p=i-s-n.count/(t||1)*(i-s*2);return`${c},${p}`}).join(" "),o=`${s},${i-s} ${r} ${a-s},${i-s}`;return`
4499
4499
  <div class="trend-chart">
4500
4500
  <div class="chart-header">
4501
4501
  <span class="chart-title">Signal Volume Over Time</span>
@@ -4513,25 +4513,25 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
4513
4513
  <polyline points="${r}" fill="none" stroke="var(--loki-accent)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
4514
4514
 
4515
4515
  <!-- Data points -->
4516
- ${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("")}
4516
+ ${e.map((n,l)=>{let c=s+l/(e.length-1||1)*(a-s*2),p=i-s-n.count/(t||1)*(i-s*2);return`<circle cx="${c}" cy="${p}" r="3" fill="var(--loki-accent)" />`}).join("")}
4517
4517
  </svg>
4518
4518
  <div class="chart-labels">
4519
- ${t.length>0?`
4520
- <span class="chart-label-start">${t[0].label}</span>
4521
- <span class="chart-label-end">${t[t.length-1].label}</span>
4519
+ ${e.length>0?`
4520
+ <span class="chart-label-start">${e[0].label}</span>
4521
+ <span class="chart-label-end">${e[e.length-1].label}</span>
4522
4522
  `:""}
4523
4523
  </div>
4524
4524
  </div>
4525
- `}_renderTopLists(){if(!this._metrics?.aggregation)return"";let{preferences:t,error_patterns:e,success_patterns:i,tool_efficiencies:a}=this._metrics.aggregation;return`
4525
+ `}_renderTopLists(){if(!this._metrics?.aggregation)return"";let{preferences:e,error_patterns:t,success_patterns:i,tool_efficiencies:a}=this._metrics.aggregation;return`
4526
4526
  <div class="top-lists">
4527
4527
  <!-- User Preferences -->
4528
4528
  <div class="top-list">
4529
4529
  <div class="list-header">
4530
4530
  <span class="list-title">Top User Preferences</span>
4531
- <span class="list-count">${t?.length||0}</span>
4531
+ <span class="list-count">${e?.length||0}</span>
4532
4532
  </div>
4533
4533
  <div class="list-items" role="list">
4534
- ${(t||[]).slice(0,5).map(s=>`
4534
+ ${(e||[]).slice(0,5).map(s=>`
4535
4535
  <div class="list-item" data-type="preference" data-id="${s.preference_key}" tabindex="0" role="listitem">
4536
4536
  <div class="item-main">
4537
4537
  <span class="item-key">${this._escapeHtml(s.preference_key)}</span>
@@ -4550,10 +4550,10 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
4550
4550
  <div class="top-list">
4551
4551
  <div class="list-header">
4552
4552
  <span class="list-title">Common Error Patterns</span>
4553
- <span class="list-count">${e?.length||0}</span>
4553
+ <span class="list-count">${t?.length||0}</span>
4554
4554
  </div>
4555
4555
  <div class="list-items" role="list">
4556
- ${(e||[]).slice(0,5).map(s=>`
4556
+ ${(t||[]).slice(0,5).map(s=>`
4557
4557
  <div class="list-item error-item" data-type="error_pattern" data-id="${s.error_type}" tabindex="0" role="listitem">
4558
4558
  <div class="item-main">
4559
4559
  <span class="item-key">${this._escapeHtml(s.error_type)}</span>
@@ -4620,7 +4620,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
4620
4620
  <span class="signals-count">${this._signals.length}</span>
4621
4621
  </div>
4622
4622
  <div class="signals-list">
4623
- ${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`
4623
+ ${this._signals.slice(0,10).map(e=>{let t=e.data||{},i=e.type||"unknown",a=t.action||e.action||i,s=t.source||e.source||"-",r=t.outcome||e.outcome||"-",o=e.timestamp?new Date(e.timestamp).toLocaleTimeString():"-";return`
4624
4624
  <div class="signal-item">
4625
4625
  <div class="signal-type ${i}">${i.replace("_"," ")}</div>
4626
4626
  <div class="signal-content">
@@ -4634,106 +4634,106 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
4634
4634
  </div>`}).join("")}
4635
4635
  </div>
4636
4636
  </div>
4637
- `}_renderDetailPanel(){if(!this._selectedMetric)return"";let{type:t,item:e}=this._selectedMetric,i="";switch(t){case"preference":i=`
4637
+ `}_renderDetailPanel(){if(!this._selectedMetric)return"";let{type:e,item:t}=this._selectedMetric,i="";switch(e){case"preference":i=`
4638
4638
  <div class="detail-row">
4639
4639
  <span class="detail-label">Preference Key</span>
4640
- <span class="detail-value">${this._escapeHtml(e.preference_key)}</span>
4640
+ <span class="detail-value">${this._escapeHtml(t.preference_key)}</span>
4641
4641
  </div>
4642
4642
  <div class="detail-row">
4643
4643
  <span class="detail-label">Preferred Value</span>
4644
- <span class="detail-value">${this._escapeHtml(String(e.preferred_value))}</span>
4644
+ <span class="detail-value">${this._escapeHtml(String(t.preferred_value))}</span>
4645
4645
  </div>
4646
4646
  <div class="detail-row">
4647
4647
  <span class="detail-label">Frequency</span>
4648
- <span class="detail-value">${e.frequency} occurrences</span>
4648
+ <span class="detail-value">${t.frequency} occurrences</span>
4649
4649
  </div>
4650
4650
  <div class="detail-row">
4651
4651
  <span class="detail-label">Confidence</span>
4652
- <span class="detail-value">${this._formatPercent(e.confidence)}</span>
4652
+ <span class="detail-value">${this._formatPercent(t.confidence)}</span>
4653
4653
  </div>
4654
- ${e.alternatives_rejected?.length?`
4654
+ ${t.alternatives_rejected?.length?`
4655
4655
  <div class="detail-section">
4656
4656
  <div class="detail-label">Alternatives Rejected</div>
4657
4657
  <ul class="detail-list">
4658
- ${e.alternatives_rejected.map(a=>`<li>${this._escapeHtml(a)}</li>`).join("")}
4658
+ ${t.alternatives_rejected.map(a=>`<li>${this._escapeHtml(a)}</li>`).join("")}
4659
4659
  </ul>
4660
4660
  </div>
4661
4661
  `:""}
4662
4662
  `;break;case"error_pattern":i=`
4663
4663
  <div class="detail-row">
4664
4664
  <span class="detail-label">Error Type</span>
4665
- <span class="detail-value">${this._escapeHtml(e.error_type)}</span>
4665
+ <span class="detail-value">${this._escapeHtml(t.error_type)}</span>
4666
4666
  </div>
4667
4667
  <div class="detail-row">
4668
4668
  <span class="detail-label">Resolution Rate</span>
4669
- <span class="detail-value">${this._formatPercent(e.resolution_rate)}</span>
4669
+ <span class="detail-value">${this._formatPercent(t.resolution_rate)}</span>
4670
4670
  </div>
4671
- ${e.common_messages?.length?`
4671
+ ${t.common_messages?.length?`
4672
4672
  <div class="detail-section">
4673
4673
  <div class="detail-label">Common Messages</div>
4674
4674
  <ul class="detail-list">
4675
- ${e.common_messages.map(a=>`<li>${this._escapeHtml(a)}</li>`).join("")}
4675
+ ${t.common_messages.map(a=>`<li>${this._escapeHtml(a)}</li>`).join("")}
4676
4676
  </ul>
4677
4677
  </div>
4678
4678
  `:""}
4679
- ${e.resolutions?.length?`
4679
+ ${t.resolutions?.length?`
4680
4680
  <div class="detail-section">
4681
4681
  <div class="detail-label">Known Resolutions</div>
4682
4682
  <ul class="detail-list success">
4683
- ${e.resolutions.map(a=>`<li>${this._escapeHtml(a)}</li>`).join("")}
4683
+ ${t.resolutions.map(a=>`<li>${this._escapeHtml(a)}</li>`).join("")}
4684
4684
  </ul>
4685
4685
  </div>
4686
4686
  `:""}
4687
4687
  `;break;case"success_pattern":i=`
4688
4688
  <div class="detail-row">
4689
4689
  <span class="detail-label">Pattern Name</span>
4690
- <span class="detail-value">${this._escapeHtml(e.pattern_name)}</span>
4690
+ <span class="detail-value">${this._escapeHtml(t.pattern_name)}</span>
4691
4691
  </div>
4692
4692
  <div class="detail-row">
4693
4693
  <span class="detail-label">Avg Duration</span>
4694
- <span class="detail-value">${this._formatDuration(e.avg_duration_seconds)}</span>
4694
+ <span class="detail-value">${this._formatDuration(t.avg_duration_seconds)}</span>
4695
4695
  </div>
4696
- ${e.common_actions?.length?`
4696
+ ${t.common_actions?.length?`
4697
4697
  <div class="detail-section">
4698
4698
  <div class="detail-label">Common Actions</div>
4699
4699
  <ol class="detail-list numbered">
4700
- ${e.common_actions.map(a=>`<li>${this._escapeHtml(a)}</li>`).join("")}
4700
+ ${t.common_actions.map(a=>`<li>${this._escapeHtml(a)}</li>`).join("")}
4701
4701
  </ol>
4702
4702
  </div>
4703
4703
  `:""}
4704
4704
  `;break;case"tool_efficiency":i=`
4705
4705
  <div class="detail-row">
4706
4706
  <span class="detail-label">Tool Name</span>
4707
- <span class="detail-value">${this._escapeHtml(e.tool_name)}</span>
4707
+ <span class="detail-value">${this._escapeHtml(t.tool_name)}</span>
4708
4708
  </div>
4709
4709
  <div class="detail-row">
4710
4710
  <span class="detail-label">Usage Count</span>
4711
- <span class="detail-value">${e.usage_count}</span>
4711
+ <span class="detail-value">${t.usage_count}</span>
4712
4712
  </div>
4713
4713
  <div class="detail-row">
4714
4714
  <span class="detail-label">Success Rate</span>
4715
- <span class="detail-value">${this._formatPercent(e.success_rate)}</span>
4715
+ <span class="detail-value">${this._formatPercent(t.success_rate)}</span>
4716
4716
  </div>
4717
4717
  <div class="detail-row">
4718
4718
  <span class="detail-label">Avg Execution Time</span>
4719
- <span class="detail-value">${Number(e.avg_execution_time_ms??0).toFixed(0)}ms</span>
4719
+ <span class="detail-value">${Number(t.avg_execution_time_ms??0).toFixed(0)}ms</span>
4720
4720
  </div>
4721
4721
  <div class="detail-row">
4722
4722
  <span class="detail-label">Total Tokens</span>
4723
- <span class="detail-value">${this._formatNumber(e.total_tokens_used)}</span>
4723
+ <span class="detail-value">${this._formatNumber(t.total_tokens_used)}</span>
4724
4724
  </div>
4725
- ${e.alternative_tools?.length?`
4725
+ ${t.alternative_tools?.length?`
4726
4726
  <div class="detail-section">
4727
4727
  <div class="detail-label">Alternative Tools</div>
4728
4728
  <div class="tag-list">
4729
- ${e.alternative_tools.map(a=>`<span class="tag">${this._escapeHtml(a)}</span>`).join("")}
4729
+ ${t.alternative_tools.map(a=>`<span class="tag">${this._escapeHtml(a)}</span>`).join("")}
4730
4730
  </div>
4731
4731
  </div>
4732
4732
  `:""}
4733
4733
  `;break}return`
4734
4734
  <div class="detail-panel">
4735
4735
  <div class="detail-header">
4736
- <h3>${t.replace("_"," ").replace(/\b\w/g,a=>a.toUpperCase())}</h3>
4736
+ <h3>${e.replace("_"," ").replace(/\b\w/g,a=>a.toUpperCase())}</h3>
4737
4737
  <button class="close-btn" id="close-detail">&times;</button>
4738
4738
  </div>
4739
4739
  <div class="detail-body">
@@ -4741,20 +4741,20 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
4741
4741
  <div class="detail-row">
4742
4742
  <span class="detail-label">Sources</span>
4743
4743
  <div class="source-tags">
4744
- ${(e.sources||[]).map(a=>`<span class="source-badge ${a}">${a}</span>`).join("")}
4744
+ ${(t.sources||[]).map(a=>`<span class="source-badge ${a}">${a}</span>`).join("")}
4745
4745
  </div>
4746
4746
  </div>
4747
4747
  <div class="detail-row">
4748
4748
  <span class="detail-label">First Seen</span>
4749
- <span class="detail-value">${e.first_seen?new Date(e.first_seen).toLocaleDateString():"--"}</span>
4749
+ <span class="detail-value">${t.first_seen?new Date(t.first_seen).toLocaleDateString():"--"}</span>
4750
4750
  </div>
4751
4751
  <div class="detail-row">
4752
4752
  <span class="detail-label">Last Seen</span>
4753
- <span class="detail-value">${e.last_seen?new Date(e.last_seen).toLocaleDateString():"--"}</span>
4753
+ <span class="detail-value">${t.last_seen?new Date(t.last_seen).toLocaleDateString():"--"}</span>
4754
4754
  </div>
4755
4755
  </div>
4756
4756
  </div>
4757
- `}render(){let t=`
4757
+ `}render(){let e=`
4758
4758
  <style>
4759
4759
  ${this.getBaseStyles()}
4760
4760
 
@@ -5378,7 +5378,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
5378
5378
  font-size: 12px;
5379
5379
  }
5380
5380
  </style>
5381
- `,e;this._loading?e='<div class="loading">Loading learning metrics...</div>':this._error?e=`<div class="error-state">Error: ${this._error}</div>`:e=`
5381
+ `,t;this._loading?t='<div class="loading">Loading learning metrics...</div>':this._error?t=`<div class="error-state">Error: ${this._error}</div>`:t=`
5382
5382
  <div class="content-main">
5383
5383
  ${this._renderSummaryCards()}
5384
5384
  ${this._renderTrendChart()}
@@ -5387,7 +5387,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
5387
5387
  </div>
5388
5388
  ${this._renderDetailPanel()}
5389
5389
  `,this.shadowRoot.innerHTML=`
5390
- ${t}
5390
+ ${e}
5391
5391
  <div class="learning-dashboard">
5392
5392
  <div class="dashboard-header">
5393
5393
  <span class="dashboard-title">
@@ -5401,10 +5401,10 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
5401
5401
  </div>
5402
5402
  ${this._renderFilters()}
5403
5403
  <div class="dashboard-content">
5404
- ${e}
5404
+ ${t}
5405
5405
  </div>
5406
5406
  </div>
5407
- `,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("time-range-select");t&&t.addEventListener("change",r=>this._setFilter("timeRange",r.target.value));let e=this.shadowRoot.getElementById("signal-type-select");e&&e.addEventListener("change",r=>this._setFilter("signalType",r.target.value));let i=this.shadowRoot.getElementById("source-select");i&&i.addEventListener("change",r=>this._setFilter("source",r.target.value));let a=this.shadowRoot.getElementById("refresh-btn");a&&a.addEventListener("click",()=>this._loadData());let s=this.shadowRoot.getElementById("close-detail");s&&s.addEventListener("click",()=>this._closeDetail()),this.shadowRoot.querySelectorAll(".list-item").forEach(r=>{r.addEventListener("click",()=>{let o=r.dataset.type,n=r.dataset.id,l=this._findItemData(o,n);l&&this._selectMetric(o,l)}),r.addEventListener("keydown",o=>{(o.key==="Enter"||o.key===" ")&&(o.preventDefault(),r.click())})})}_findItemData(t,e){if(!this._metrics?.aggregation)return null;switch(t){case"preference":return this._metrics.aggregation.preferences?.find(i=>i.preference_key===e);case"error_pattern":return this._metrics.aggregation.error_patterns?.find(i=>i.error_type===e);case"success_pattern":return this._metrics.aggregation.success_patterns?.find(i=>i.pattern_name===e);case"tool_efficiency":return this._metrics.aggregation.tool_efficiencies?.find(i=>i.tool_name===e);default:return null}}};customElements.get("loki-learning-dashboard")||customElements.define("loki-learning-dashboard",V);var me=[{id:"overview",label:"Overview"},{id:"decisions",label:"Decision Log"},{id:"convergence",label:"Convergence"},{id:"agents",label:"Agents"}],Y=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._activeTab="overview",this._pollInterval=null,this._councilState=null,this._verdicts=[],this._convergence=[],this._agents=[],this._selectedAgent=null,this._lastDataHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),3e3),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadData(),this._pollInterval=setInterval(()=>this._loadData(),3e3))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null),this._pendingRaf&&(cancelAnimationFrame(this._pendingRaf),this._pendingRaf=null)}async _loadData(){try{let[e,i,a,s]=await Promise.allSettled([this._api._get("/api/council/state"),this._api._get("/api/council/verdicts"),this._api._get("/api/council/convergence"),this._api._get("/api/agents")]);e.status==="fulfilled"&&(this._councilState=e.value),i.status==="fulfilled"&&(this._verdicts=i.value.verdicts||[]),a.status==="fulfilled"&&(this._convergence=a.value.dataPoints||[]),s.status==="fulfilled"&&(this._agents=Array.isArray(s.value)?s.value:[]),this._error=null}catch(e){this._error=e.message}let t=JSON.stringify({s:this._councilState,v:this._verdicts,c:this._convergence,a:this._agents,e:this._error});t!==this._lastDataHash&&(this._lastDataHash=t,this.render())}async _forceReview(){try{await this._api._post("/api/council/force-review"),this.dispatchEvent(new CustomEvent("council-action",{detail:{action:"force-review"},bubbles:!0}))}catch(t){this._error=`Failed to force review: ${t.message}`,this.render()}}async _killAgent(t){if(confirm(`Kill agent ${t}?`))try{await this._api._post(`/api/agents/${t}/kill`),this.dispatchEvent(new CustomEvent("council-action",{detail:{action:"kill-agent",agentId:t},bubbles:!0})),await this._loadData()}catch(e){this._error=`Failed to kill agent: ${e.message}`,this.render()}}async _pauseAgent(t){try{await this._api._post(`/api/agents/${t}/pause`),await this._loadData()}catch(e){this._error=`Failed to pause agent: ${e.message}`,this.render()}}async _resumeAgent(t){try{await this._api._post(`/api/agents/${t}/resume`),await this._loadData()}catch(e){this._error=`Failed to resume agent: ${e.message}`,this.render()}}_setTab(t){this._activeTab=t,this.render()}_selectAgent(t){this._selectedAgent=this._selectedAgent?.id===t.id?null:t,this.render()}render(){let t=this.shadowRoot;t&&(this._pendingRaf&&(cancelAnimationFrame(this._pendingRaf),this._pendingRaf=null),t.innerHTML=`
5407
+ `,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot.getElementById("time-range-select");e&&e.addEventListener("change",r=>this._setFilter("timeRange",r.target.value));let t=this.shadowRoot.getElementById("signal-type-select");t&&t.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(e,t){if(!this._metrics?.aggregation)return null;switch(e){case"preference":return this._metrics.aggregation.preferences?.find(i=>i.preference_key===t);case"error_pattern":return this._metrics.aggregation.error_patterns?.find(i=>i.error_type===t);case"success_pattern":return this._metrics.aggregation.success_patterns?.find(i=>i.pattern_name===t);case"tool_efficiency":return this._metrics.aggregation.tool_efficiencies?.find(i=>i.tool_name===t);default:return null}}};customElements.get("loki-learning-dashboard")||customElements.define("loki-learning-dashboard",V);var mt=[{id:"overview",label:"Overview"},{id:"decisions",label:"Decision Log"},{id:"convergence",label:"Convergence"},{id:"agents",label:"Agents"}],Y=class extends u{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(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_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[t,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")]);t.status==="fulfilled"&&(this._councilState=t.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(t){this._error=t.message}let e=JSON.stringify({s:this._councilState,v:this._verdicts,c:this._convergence,a:this._agents,e:this._error});e!==this._lastDataHash&&(this._lastDataHash=e,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(e){this._error=`Failed to force review: ${e.message}`,this.render()}}async _killAgent(e){if(confirm(`Kill agent ${e}?`))try{await this._api._post(`/api/agents/${e}/kill`),this.dispatchEvent(new CustomEvent("council-action",{detail:{action:"kill-agent",agentId:e},bubbles:!0})),await this._loadData()}catch(t){this._error=`Failed to kill agent: ${t.message}`,this.render()}}async _pauseAgent(e){try{await this._api._post(`/api/agents/${e}/pause`),await this._loadData()}catch(t){this._error=`Failed to pause agent: ${t.message}`,this.render()}}async _resumeAgent(e){try{await this._api._post(`/api/agents/${e}/resume`),await this._loadData()}catch(t){this._error=`Failed to resume agent: ${t.message}`,this.render()}}_setTab(e){this._activeTab=e,this.render()}_selectAgent(e){this._selectedAgent=this._selectedAgent?.id===e.id?null:e,this.render()}render(){let e=this.shadowRoot;e&&(this._pendingRaf&&(cancelAnimationFrame(this._pendingRaf),this._pendingRaf=null),e.innerHTML=`
5408
5408
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
5409
5409
  <div class="council-dashboard">
5410
5410
  <div class="council-header">
@@ -5418,11 +5418,11 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
5418
5418
  </div>
5419
5419
 
5420
5420
  <div class="tabs">
5421
- ${me.map(e=>`
5421
+ ${mt.map(t=>`
5422
5422
  <button
5423
- class="tab ${this._activeTab===e.id?"active":""}"
5424
- data-tab="${e.id}"
5425
- >${e.label}</button>
5423
+ class="tab ${this._activeTab===t.id?"active":""}"
5424
+ data-tab="${t.id}"
5425
+ >${t.label}</button>
5426
5426
  `).join("")}
5427
5427
  </div>
5428
5428
 
@@ -5432,12 +5432,12 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
5432
5432
 
5433
5433
  ${this._error?`<div class="error-banner">${this._error}</div>`:""}
5434
5434
  </div>
5435
- `,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`
5435
+ `,this._attachEventListeners())}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("force-review-btn");t&&t.addEventListener("click",()=>this._forceReview()),e.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 e=this._councilState||{},t=e.consecutive_no_change||0,i=e.done_signals||0,a=e.total_votes||0,s=e.approve_votes||0,r=this._verdicts.length>0?this._verdicts[this._verdicts.length-1]:null,o=this._agents.filter(n=>n.alive).length;return`
5436
5436
  <div class="overview-grid">
5437
5437
  <div class="stat-card">
5438
5438
  <div class="stat-label">Council Status</div>
5439
- <div class="stat-value ${t.enabled!==!1?"text-green":"text-muted"}">
5440
- ${t.enabled!==!1?"Monitoring":"Disabled"}
5439
+ <div class="stat-value ${e.enabled!==!1?"text-green":"text-muted"}">
5440
+ ${e.enabled!==!1?"Monitoring":"Disabled"}
5441
5441
  </div>
5442
5442
  </div>
5443
5443
  <div class="stat-card">
@@ -5447,7 +5447,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
5447
5447
  </div>
5448
5448
  <div class="stat-card">
5449
5449
  <div class="stat-label">Stagnation Streak</div>
5450
- <div class="stat-value ${e>=3?"text-warn":""}">${e}</div>
5450
+ <div class="stat-value ${t>=3?"text-warn":""}">${t}</div>
5451
5451
  <div class="stat-sub">consecutive no-change</div>
5452
5452
  </div>
5453
5453
  <div class="stat-card">
@@ -5477,9 +5477,9 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
5477
5477
  </div>
5478
5478
  </div>
5479
5479
  `:""}
5480
- `}_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`
5480
+ `}_renderConvergenceBar(){let e=this._convergence.slice(-20);if(e.length===0)return'<span class="text-muted">No data</span>';let t=Math.max(...e.map(i=>i.files_changed),1);return`
5481
5481
  <div class="bar-chart">
5482
- ${t.map(i=>{let a=Math.max(4,i.files_changed/e*60),s=i.no_change_streak>0;return`
5482
+ ${e.map(i=>{let a=Math.max(4,i.files_changed/t*60),s=i.no_change_streak>0;return`
5483
5483
  <div class="bar-wrapper" title="Iter ${i.iteration}: ${i.files_changed} files changed">
5484
5484
  <div class="bar ${s?"bar-stagnant":"bar-active"}" style="height: ${a}px"></div>
5485
5485
  <div class="bar-label">${i.iteration}</div>
@@ -5488,18 +5488,18 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
5488
5488
  </div>
5489
5489
  `}_renderDecisions(){return this._verdicts.length===0?`<div class="empty-state">No council decisions yet. The council convenes every ${this._councilState?.check_interval||5} iterations.</div>`:`
5490
5490
  <div class="decision-list">
5491
- ${this._verdicts.slice().reverse().map(t=>`
5492
- <div class="decision-card ${t.result==="APPROVED"?"decision-approved":"decision-rejected"}">
5491
+ ${this._verdicts.slice().reverse().map(e=>`
5492
+ <div class="decision-card ${e.result==="APPROVED"?"decision-approved":"decision-rejected"}">
5493
5493
  <div class="decision-header">
5494
- <span class="decision-result ${t.result==="APPROVED"?"text-green":"text-warn"}">
5495
- ${t.result}
5494
+ <span class="decision-result ${e.result==="APPROVED"?"text-green":"text-warn"}">
5495
+ ${e.result}
5496
5496
  </span>
5497
- <span class="decision-iter">Iteration ${t.iteration}</span>
5498
- <span class="decision-time">${this._formatTime(t.timestamp)}</span>
5497
+ <span class="decision-iter">Iteration ${e.iteration}</span>
5498
+ <span class="decision-time">${this._formatTime(e.timestamp)}</span>
5499
5499
  </div>
5500
5500
  <div class="decision-votes">
5501
- <span class="vote-approve">${t.approve} Approve</span>
5502
- <span class="vote-reject">${t.reject} Reject</span>
5501
+ <span class="vote-approve">${e.approve} Approve</span>
5502
+ <span class="vote-reject">${e.reject} Reject</span>
5503
5503
  </div>
5504
5504
  </div>
5505
5505
  `).join("")}
@@ -5525,45 +5525,45 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
5525
5525
  </tr>
5526
5526
  </thead>
5527
5527
  <tbody>
5528
- ${this._convergence.slice().reverse().map(t=>`
5529
- <tr class="${t.no_change_streak>=3?"row-warn":""}">
5530
- <td>${t.iteration}</td>
5531
- <td>${t.files_changed}</td>
5532
- <td>${t.no_change_streak}</td>
5533
- <td>${t.done_signals}</td>
5528
+ ${this._convergence.slice().reverse().map(e=>`
5529
+ <tr class="${e.no_change_streak>=3?"row-warn":""}">
5530
+ <td>${e.iteration}</td>
5531
+ <td>${e.files_changed}</td>
5532
+ <td>${e.no_change_streak}</td>
5533
+ <td>${e.done_signals}</td>
5534
5534
  </tr>
5535
5535
  `).join("")}
5536
5536
  </tbody>
5537
5537
  </table>
5538
5538
  </div>
5539
5539
  </div>
5540
- `}_renderAgents(){if(this._agents.length===0)return'<div class="empty-state">No agents registered.</div>';let t=`
5540
+ `}_renderAgents(){if(this._agents.length===0)return'<div class="empty-state">No agents registered.</div>';let e=`
5541
5541
  <div class="agents-list">
5542
- ${this._agents.map((e,i)=>`
5543
- <div class="agent-card ${this._selectedAgent?.id===e.id?"agent-selected":""}"
5542
+ ${this._agents.map((t,i)=>`
5543
+ <div class="agent-card ${this._selectedAgent?.id===t.id?"agent-selected":""}"
5544
5544
  data-agent-index="${i}">
5545
5545
  <div class="agent-header">
5546
- <span class="agent-name">${e.name||e.id||"Unknown"}</span>
5547
- <span class="agent-status ${e.alive?"status-alive":"status-dead"}">
5548
- ${e.alive?"Running":"Stopped"}
5546
+ <span class="agent-name">${t.name||t.id||"Unknown"}</span>
5547
+ <span class="agent-status ${t.alive?"status-alive":"status-dead"}">
5548
+ ${t.alive?"Running":"Stopped"}
5549
5549
  </span>
5550
5550
  </div>
5551
5551
  <div class="agent-meta">
5552
- ${e.type?`<span class="agent-type">${e.type}</span>`:""}
5553
- ${e.pid?`<span class="agent-pid">PID: ${e.pid}</span>`:""}
5554
- ${e.task?`<span class="agent-task">Task: ${e.task}</span>`:""}
5552
+ ${t.type?`<span class="agent-type">${t.type}</span>`:""}
5553
+ ${t.pid?`<span class="agent-pid">PID: ${t.pid}</span>`:""}
5554
+ ${t.task?`<span class="agent-task">Task: ${t.task}</span>`:""}
5555
5555
  </div>
5556
- ${this._selectedAgent?.id===e.id?`
5556
+ ${this._selectedAgent?.id===t.id?`
5557
5557
  <div class="agent-actions">
5558
- ${e.alive?`
5559
- <button class="btn btn-sm btn-warn" data-action="pause" data-agent-id="${e.id||e.name}">
5558
+ ${t.alive?`
5559
+ <button class="btn btn-sm btn-warn" data-action="pause" data-agent-id="${t.id||t.name}">
5560
5560
  Pause
5561
5561
  </button>
5562
- <button class="btn btn-sm btn-danger" data-action="kill" data-agent-id="${e.id||e.name}">
5562
+ <button class="btn btn-sm btn-danger" data-action="kill" data-agent-id="${t.id||t.name}">
5563
5563
  Kill
5564
5564
  </button>
5565
5565
  `:`
5566
- <button class="btn btn-sm btn-primary" data-action="resume" data-agent-id="${e.id||e.name}">
5566
+ <button class="btn btn-sm btn-primary" data-action="resume" data-agent-id="${t.id||t.name}">
5567
5567
  Resume
5568
5568
  </button>
5569
5569
  `}
@@ -5572,7 +5572,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
5572
5572
  </div>
5573
5573
  `).join("")}
5574
5574
  </div>
5575
- `;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`
5575
+ `;return this._pendingRaf=requestAnimationFrame(()=>{this._pendingRaf=null;let t=this.shadowRoot;t&&t.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)})}))})}),e}_formatTime(e){if(!e)return"";try{return new Date(e).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}catch{return e}}_getStyles(){return`
5576
5576
  :host {
5577
5577
  display: block;
5578
5578
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
@@ -5991,7 +5991,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
5991
5991
  color: var(--loki-error);
5992
5992
  font-size: 12px;
5993
5993
  }
5994
- `}};customElements.get("loki-council-dashboard")||customElements.define("loki-council-dashboard",Y);var qt={critical:0,major:1,minor:2},ve={critical:"var(--loki-status-error, #ef4444)",major:"var(--loki-status-warning, #f59e0b)",minor:"var(--loki-text-muted, #71717a)"},W=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._pollInterval=null,this._checklist=null,this._waivers=[],this._expandedCategories=new Set,this._lastDataHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),5e3),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadData(),this._pollInterval=setInterval(()=>this._loadData(),5e3))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null)}async _loadData(){try{let[t,e]=await Promise.all([this._api.getChecklist(),this._api.getChecklistWaivers().catch(()=>null)]),i=JSON.stringify(e),a=JSON.stringify(t)+i;if(a===this._lastDataHash)return;this._lastDataHash=a,this._checklist=t,this._waivers=e&&e.waivers?e.waivers.filter(s=>s.active):[],this._error=null,this.render()}catch(t){this._error=`Failed to load checklist: ${t.message}`,this.render()}}_isItemWaived(t){return this._waivers.some(e=>e.item_id===t)}_getWaiverForItem(t){return this._waivers.find(e=>e.item_id===t)||null}async _waiveItem(t){let e=window.prompt("Enter reason for waiving this item:");if(e)try{await this._api.addChecklistWaiver(t,e),this._lastDataHash=null,await this._loadData()}catch(i){this._error=`Failed to add waiver: ${i.message}`,this.render()}}async _unwaiveItem(t){try{await this._api.removeChecklistWaiver(t),this._lastDataHash=null,await this._loadData()}catch(e){this._error=`Failed to remove waiver: ${e.message}`,this.render()}}_toggleCategory(t){this._expandedCategories.has(t)?this._expandedCategories.delete(t):this._expandedCategories.add(t),this.render()}_getStyles(){return`
5994
+ `}};customElements.get("loki-council-dashboard")||customElements.define("loki-council-dashboard",Y);var qe={critical:0,major:1,minor:2},vt={critical:"var(--loki-status-error, #ef4444)",major:"var(--loki-status-warning, #f59e0b)",minor:"var(--loki-text-muted, #71717a)"},W=class extends u{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(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_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[e,t]=await Promise.all([this._api.getChecklist(),this._api.getChecklistWaivers().catch(()=>null)]),i=JSON.stringify(t),a=JSON.stringify(e)+i;if(a===this._lastDataHash)return;this._lastDataHash=a,this._checklist=e,this._waivers=t&&t.waivers?t.waivers.filter(s=>s.active):[],this._error=null,this.render()}catch(e){this._error=`Failed to load checklist: ${e.message}`,this.render()}}_isItemWaived(e){return this._waivers.some(t=>t.item_id===e)}_getWaiverForItem(e){return this._waivers.find(t=>t.item_id===e)||null}async _waiveItem(e){let t=window.prompt("Enter reason for waiving this item:");if(t)try{await this._api.addChecklistWaiver(e,t),this._lastDataHash=null,await this._loadData()}catch(i){this._error=`Failed to add waiver: ${i.message}`,this.render()}}async _unwaiveItem(e){try{await this._api.removeChecklistWaiver(e),this._lastDataHash=null,await this._loadData()}catch(t){this._error=`Failed to remove waiver: ${t.message}`,this.render()}}_toggleCategory(e){this._expandedCategories.has(e)?this._expandedCategories.delete(e):this._expandedCategories.add(e),this.render()}_getStyles(){return`
5995
5995
  .checklist-viewer {
5996
5996
  padding: 16px;
5997
5997
  font-family: var(--loki-font-family, system-ui, -apple-system, sans-serif);
@@ -6239,54 +6239,54 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
6239
6239
  border-radius: 4px;
6240
6240
  font-size: 12px;
6241
6241
  }
6242
- `}_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=`
6242
+ `}_getUnwaivedCriticalFailures(){if(!this._checklist?.categories)return[];let e=[];for(let t of this._checklist.categories)for(let i of t.items||[])i.status==="failing"&&i.priority==="critical"&&!this._isItemWaived(i.id)&&e.push(i);return e}_renderGateBanner(){let e=this._getUnwaivedCriticalFailures();return e.length>0?`<div class="gate-banner gate-blocked">COUNCIL GATE: BLOCKED - ${e.length} critical item${e.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 e=this.shadowRoot;if(!e)return;let t=this._checklist,i=t&&t.status!=="not_initialized"&&t.categories?.length>0;e.innerHTML=`
6243
6243
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
6244
6244
  <div class="checklist-viewer">
6245
6245
  <div class="checklist-header">
6246
6246
  <h2 class="title">Spec Checklist</h2>
6247
- ${i?this._renderBadges(e.summary):""}
6247
+ ${i?this._renderBadges(t.summary):""}
6248
6248
  </div>
6249
6249
  ${i?this._renderGateBanner():""}
6250
- ${i?this._renderProgress(e.summary):""}
6251
- ${i?this._renderCategories(e.categories):this._renderEmpty()}
6250
+ ${i?this._renderProgress(t.summary):""}
6251
+ ${i?this._renderCategories(t.categories):this._renderEmpty()}
6252
6252
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
6253
6253
  </div>
6254
- `,this._attachEventListeners()}_renderBadges(t){if(!t)return"";let e=this._waivers.length;return`
6254
+ `,this._attachEventListeners()}_renderBadges(e){if(!e)return"";let t=this._waivers.length;return`
6255
6255
  <div class="summary-badges">
6256
- ${t.verified?`<span class="badge badge-verified">${t.verified} verified</span>`:""}
6257
- ${t.failing?`<span class="badge badge-failing">${t.failing} failing</span>`:""}
6258
- ${e?`<span class="badge badge-waived">${e} waived</span>`:""}
6259
- ${t.pending?`<span class="badge badge-pending">${t.pending} pending</span>`:""}
6256
+ ${e.verified?`<span class="badge badge-verified">${e.verified} verified</span>`:""}
6257
+ ${e.failing?`<span class="badge badge-failing">${e.failing} failing</span>`:""}
6258
+ ${t?`<span class="badge badge-waived">${t} waived</span>`:""}
6259
+ ${e.pending?`<span class="badge badge-pending">${e.pending} pending</span>`:""}
6260
6260
  </div>
6261
- `}_renderProgress(t){if(!t||!t.total)return"";let e=t.verified/t.total*100,i=t.failing/t.total*100;return`
6261
+ `}_renderProgress(e){if(!e||!e.total)return"";let t=e.verified/e.total*100,i=e.failing/e.total*100;return`
6262
6262
  <div class="progress-container">
6263
6263
  <div class="progress-bar">
6264
- <div class="progress-verified" style="width: ${e}%"></div>
6264
+ <div class="progress-verified" style="width: ${t}%"></div>
6265
6265
  <div class="progress-failing" style="width: ${i}%"></div>
6266
6266
  </div>
6267
6267
  <div class="progress-label">
6268
- <span>${t.verified}/${t.total} verified | ${t.failing||0} failing | ${this._waivers.length} waived | ${t.pending||0} pending</span>
6269
- <span>${Math.round(e)}%</span>
6268
+ <span>${e.verified}/${e.total} verified | ${e.failing||0} failing | ${this._waivers.length} waived | ${e.pending||0} pending</span>
6269
+ <span>${Math.round(t)}%</span>
6270
6270
  </div>
6271
6271
  </div>
6272
- `}_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`
6272
+ `}_renderCategories(e){return e?.length?e.map(t=>{let i=this._expandedCategories.has(t.name),a=t.items||[],s=a.filter(o=>o.status==="verified").length,r=a.filter(o=>o.status==="failing").length;return`
6273
6273
  <div class="category">
6274
- <div class="category-header" data-category="${this._escapeHtml(e.name)}">
6274
+ <div class="category-header" data-category="${this._escapeHtml(t.name)}">
6275
6275
  <div>
6276
- <span class="category-name">${this._escapeHtml(e.name)}</span>
6276
+ <span class="category-name">${this._escapeHtml(t.name)}</span>
6277
6277
  <span class="category-stats">${s}/${a.length} verified${r?`, ${r} failing`:""}</span>
6278
6278
  </div>
6279
6279
  <span class="category-arrow ${i?"expanded":""}">&#9654;</span>
6280
6280
  </div>
6281
6281
  ${i?`<div class="category-body">${this._renderItems(a)}</div>`:""}
6282
6282
  </div>
6283
- `}).join(""):this._renderEmpty()}_renderItems(t){return t?.length?[...t].sort((i,a)=>(qt[i.priority]??2)-(qt[a.priority]??2)).map(i=>{let a=i.status==="verified"?"status-verified":i.status==="failing"?"status-failing":"status-pending",s=["critical","major","minor"].includes(i.priority)?i.priority:"minor",r=ve[s],o=i.verification||[],n=this._getWaiverForItem(i.id),l=!!n,c=i.status==="failing"&&(s==="critical"||s==="major"),p=l?`<span class="item-waived-badge" title="${this._escapeHtml(n.reason||"No reason provided")}">WAIVED</span>`:"",u="";return c&&(l?u=`<button class="waiver-btn waiver-btn-unwaive" data-unwaive-id="${this._escapeHtml(i.id)}">Unwaive</button>`:u=`<button class="waiver-btn" data-waive-id="${this._escapeHtml(i.id)}">Waive</button>`),`
6283
+ `}).join(""):this._renderEmpty()}_renderItems(e){return e?.length?[...e].sort((i,a)=>(qe[i.priority]??2)-(qe[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=vt[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>`:"",h="";return c&&(l?h=`<button class="waiver-btn waiver-btn-unwaive" data-unwaive-id="${this._escapeHtml(i.id)}">Unwaive</button>`:h=`<button class="waiver-btn" data-waive-id="${this._escapeHtml(i.id)}">Waive</button>`),`
6284
6284
  <div class="item">
6285
6285
  <div class="item-status ${a}"></div>
6286
6286
  <div class="item-title">${this._escapeHtml(i.title||i.id||"?")}</div>
6287
6287
  <span class="item-priority" style="color:${r};border:1px solid ${r}">${s}</span>
6288
6288
  ${p}
6289
- ${u}
6289
+ ${h}
6290
6290
  <div class="verification-dots">
6291
6291
  ${o.map(b=>`<div class="v-dot ${b.passed===!0?"v-dot-pass":b.passed===!1?"v-dot-fail":"v-dot-pending"}" title="${this._escapeHtml(b.type||"")}"></div>`).join("")}
6292
6292
  </div>
@@ -6296,7 +6296,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
6296
6296
  <p><strong>No checklist data yet.</strong></p>
6297
6297
  <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>
6298
6298
  </div>
6299
- `}_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`
6299
+ `}_attachEventListeners(){let e=this.shadowRoot;e&&(e.querySelectorAll(".category-header[data-category]").forEach(t=>{t.addEventListener("click",()=>this._toggleCategory(t.dataset.category))}),e.querySelectorAll("button[data-waive-id]").forEach(t=>{t.addEventListener("click",i=>{i.stopPropagation(),this._waiveItem(t.dataset.waiveId)})}),e.querySelectorAll("button[data-unwaive-id]").forEach(t=>{t.addEventListener("click",i=>{i.stopPropagation(),this._unwaiveItem(t.dataset.unwaiveId)})}))}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}};customElements.define("loki-checklist-viewer",W);var Je={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 u{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(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_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,t]=await Promise.all([this._api.getAppRunnerStatus(),this._api.getAppRunnerLogs()]),i=JSON.stringify({status:e?.status,port:e?.port,restarts:e?.restart_count,url:e?.url}),a=JSON.stringify(t?.lines?.slice(-5)||[]),s=a!==this._lastLogsHash;if(i===this._lastDataHash&&!s)return;this._lastDataHash=i,this._lastLogsHash=a,this._status=e,this._logs=t?.lines||[],this._error=null,this.render(),this._scrollLogsToBottom()}catch(e){this._error||(this._error=`Failed to load app status: ${e.message}`,this.render())}}_scrollLogsToBottom(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector(".log-area");t&&(t.scrollTop=t.scrollHeight)}async _handleRestart(){try{await this._api.restartApp(),this._loadData()}catch(e){this._error=`Restart failed: ${e.message}`,this.render()}}async _handleStop(){try{await this._api.stopApp(),this._loadData()}catch(e){this._error=`Stop failed: ${e.message}`,this.render()}}_formatUptime(e){if(!e)return"--";let t=new Date(e),a=Math.floor((new Date-t)/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(e){if(!e)return!1;try{let t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch{return!1}}_getStyles(){return`
6300
6300
  .app-status {
6301
6301
  padding: 16px;
6302
6302
  font-family: var(--loki-font-family, system-ui, -apple-system, sans-serif);
@@ -6457,35 +6457,35 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
6457
6457
  border-radius: 4px;
6458
6458
  font-size: 12px;
6459
6459
  }
6460
- `}render(){let t=this.shadowRoot;if(!t)return;let e=this._status,i=e&&e.status&&e.status!=="not_initialized";t.innerHTML=`
6460
+ `}render(){let e=this.shadowRoot;if(!e)return;let t=this._status,i=t&&t.status&&t.status!=="not_initialized";e.innerHTML=`
6461
6461
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
6462
6462
  <div class="app-status">
6463
6463
  <div class="header">
6464
6464
  <div class="header-left">
6465
6465
  <h2 class="title">App Runner</h2>
6466
- ${this._renderStatusBadge(e)}
6466
+ ${this._renderStatusBadge(t)}
6467
6467
  </div>
6468
- ${i?this._renderActions(e):""}
6468
+ ${i?this._renderActions(t):""}
6469
6469
  </div>
6470
- ${i?this._renderStatusCard(e):""}
6470
+ ${i?this._renderStatusCard(t):""}
6471
6471
  ${i&&this._logs.length>0?this._renderLogs():""}
6472
6472
  ${i?"":this._renderEmpty()}
6473
6473
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
6474
6474
  </div>
6475
- `,this._attachEventListeners()}_renderStatusBadge(t){let e=t?.status||"not_initialized",i=Jt[e]||Jt.not_initialized;return`
6475
+ `,this._attachEventListeners()}_renderStatusBadge(e){let t=e?.status||"not_initialized",i=Je[t]||Je.not_initialized;return`
6476
6476
  <span class="status-badge" style="background: color-mix(in srgb, ${i.color} 15%, transparent); color: ${i.color}">
6477
6477
  <span class="status-dot ${i.pulse?"pulse":""}" style="background: ${i.color}"></span>
6478
6478
  ${this._escapeHtml(i.label)}
6479
6479
  </span>
6480
- `}_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`
6480
+ `}_renderStatusCard(e){let i=this._isValidUrl(e.url)?`<a href="${this._escapeHtml(e.url)}" target="_blank" rel="noopener noreferrer">${this._escapeHtml(e.url)}</a>`:this._escapeHtml(e.url||"--");return`
6481
6481
  <div class="status-card">
6482
6482
  <div class="status-row">
6483
6483
  <span class="status-label">Method</span>
6484
- <span class="status-value">${this._escapeHtml(t.method||"--")}</span>
6484
+ <span class="status-value">${this._escapeHtml(e.method||"--")}</span>
6485
6485
  </div>
6486
6486
  <div class="status-row">
6487
6487
  <span class="status-label">Port</span>
6488
- <span class="status-value">${t.port?this._escapeHtml(String(t.port)):"--"}</span>
6488
+ <span class="status-value">${e.port?this._escapeHtml(String(e.port)):"--"}</span>
6489
6489
  </div>
6490
6490
  <div class="status-row">
6491
6491
  <span class="status-label">URL</span>
@@ -6493,28 +6493,28 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
6493
6493
  </div>
6494
6494
  <div class="status-row">
6495
6495
  <span class="status-label">Restarts</span>
6496
- <span class="status-value">${t.restart_count!=null?t.restart_count:"--"}</span>
6496
+ <span class="status-value">${e.restart_count!=null?e.restart_count:"--"}</span>
6497
6497
  </div>
6498
6498
  <div class="status-row">
6499
6499
  <span class="status-label">Uptime</span>
6500
- <span class="status-value">${t.status==="running"||t.status==="stale"?this._formatUptime(t.started_at):"--"}</span>
6500
+ <span class="status-value">${e.status==="running"||e.status==="stale"?this._formatUptime(e.started_at):"--"}</span>
6501
6501
  </div>
6502
- ${t.status==="crashed"&&t.error?`
6502
+ ${e.status==="crashed"&&e.error?`
6503
6503
  <div class="status-row" style="margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--loki-border, #e4e4e7);">
6504
6504
  <span class="status-label" style="color: var(--loki-red, #dc2626)">Error</span>
6505
- <span class="status-value" style="color: var(--loki-red, #dc2626); max-width: 70%; text-align: right;">${this._escapeHtml(t.error)}</span>
6505
+ <span class="status-value" style="color: var(--loki-red, #dc2626); max-width: 70%; text-align: right;">${this._escapeHtml(e.error)}</span>
6506
6506
  </div>
6507
6507
  `:""}
6508
6508
  </div>
6509
- `}_renderLogs(){let t=this._logs.slice(-20);return`
6509
+ `}_renderLogs(){let e=this._logs.slice(-20);return`
6510
6510
  <div class="log-section">
6511
6511
  <div class="log-header">Application Logs</div>
6512
- <div class="log-area">${t.length>0?t.map(e=>this._escapeHtml(e)).join(`
6512
+ <div class="log-area">${e.length>0?e.map(t=>this._escapeHtml(t)).join(`
6513
6513
  `):'<span class="log-empty">No log output yet</span>'}</div>
6514
6514
  </div>
6515
- `}_renderActions(t){let e=t.status==="running"||t.status==="crashed"||t.status==="stopped",i=t.status==="running"||t.status==="starting";return`
6515
+ `}_renderActions(e){let t=e.status==="running"||e.status==="crashed"||e.status==="stopped",i=e.status==="running"||e.status==="starting";return`
6516
6516
  <div class="actions">
6517
- <button class="btn" data-action="restart" ${e?"":"disabled"}>Restart</button>
6517
+ <button class="btn" data-action="restart" ${t?"":"disabled"}>Restart</button>
6518
6518
  <button class="btn btn-danger" data-action="stop" ${i?"":"disabled"}>Stop</button>
6519
6519
  </div>
6520
6520
  `}_renderEmpty(){return`
@@ -6522,16 +6522,16 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
6522
6522
  <p>App runner not started</p>
6523
6523
  <p class="hint">App runner will start after the first successful build iteration.</p>
6524
6524
  </div>
6525
- `}_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`
6525
+ `}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector('[data-action="restart"]'),i=e.querySelector('[data-action="stop"]');t&&t.addEventListener("click",()=>this._handleRestart()),i&&i.addEventListener("click",()=>this._handleStop())}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}};customElements.define("loki-app-status",Q);var bt={opus:{input:5,output:25,label:"Opus 4.6",provider:"claude"},sonnet:{input:3,output:15,label:"Sonnet 4.5",provider:"claude"},haiku:{input:1,output:5,label:"Haiku 4.5",provider:"claude"},"gpt-5.3-codex":{input:1.5,output:12,label:"GPT-5.3 Codex",provider:"codex"}},X=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data={total_input_tokens:0,total_output_tokens:0,estimated_cost_usd:0,by_phase:{},by_model:{},budget_limit:null,budget_used:0,budget_remaining:null,connected:!1},this._api=null,this._pollInterval=null,this._modelPricing={...bt}}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadPricing(),this._loadCost(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadCost()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}async _loadPricing(){try{let e=await this._api.getPricing();if(e&&e.models){let t={};for(let[i,a]of Object.entries(e.models))t[i]={input:a.input,output:a.output,label:a.label||i,provider:a.provider||"unknown"};this._modelPricing=t,this._pricingSource=e.source||"api",this._pricingDate=e.updated||"",this._activeProvider=e.provider||"claude",this.render()}}catch{}}async _loadCost(){try{let e=await this._api.getCost();this._updateFromCost(e)}catch{this._data.connected=!1,this.render()}}_updateFromCost(e){e&&(this._data={...this._data,connected:!0,total_input_tokens:e.total_input_tokens||0,total_output_tokens:e.total_output_tokens||0,estimated_cost_usd:e.estimated_cost_usd||0,by_phase:e.by_phase||{},by_model:e.by_model||{},budget_limit:e.budget_limit,budget_used:e.budget_used||0,budget_remaining:e.budget_remaining},this.render())}_startPolling(){this._pollInterval=setInterval(async()=>{try{let e=await this._api.getCost();this._updateFromCost(e)}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 e=await this._api.getCost();this._updateFromCost(e)}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(e){return!e||e===0?"0":e>=1e6?(e/1e6).toFixed(2)+"M":e>=1e3?(e/1e3).toFixed(1)+"K":String(e)}_formatUSD(e){return!e||e===0?"$0.00":e<.01?"<$0.01":"$"+e.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 e=this._getBudgetPercent();return e>=90?"critical":e>=70?"warning":"ok"}_renderPhaseRows(){let e=this._data.by_phase;return!e||Object.keys(e).length===0?'<tr><td colspan="4" class="empty-cell">No phase data yet</td></tr>':Object.entries(e).map(([t,i])=>{let a=i.input_tokens||0,s=i.output_tokens||0,r=i.cost_usd||0;return`
6526
6526
  <tr>
6527
- <td class="phase-name">${this._escapeHTML(e)}</td>
6527
+ <td class="phase-name">${this._escapeHTML(t)}</td>
6528
6528
  <td class="mono-cell">${this._formatTokens(a)}</td>
6529
6529
  <td class="mono-cell">${this._formatTokens(s)}</td>
6530
6530
  <td class="mono-cell cost-cell">${this._formatUSD(r)}</td>
6531
6531
  </tr>
6532
- `}).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`
6532
+ `}).join("")}_renderModelRows(){let e=this._data.by_model;return!e||Object.keys(e).length===0?'<tr><td colspan="4" class="empty-cell">No model data yet</td></tr>':Object.entries(e).map(([t,i])=>{let a=i.input_tokens||0,s=i.output_tokens||0,r=i.cost_usd||0;return`
6533
6533
  <tr>
6534
- <td class="model-name">${this._escapeHTML(e)}</td>
6534
+ <td class="model-name">${this._escapeHTML(t)}</td>
6535
6535
  <td class="mono-cell">${this._formatTokens(a)}</td>
6536
6536
  <td class="mono-cell">${this._formatTokens(s)}</td>
6537
6537
  <td class="mono-cell cost-cell">${this._formatUSD(r)}</td>
@@ -6546,7 +6546,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
6546
6546
  </div>
6547
6547
  <div class="budget-not-set">No budget configured</div>
6548
6548
  </div>
6549
- `;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`
6549
+ `;let e=this._getBudgetPercent(),t=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`
6550
6550
  <div class="budget-section">
6551
6551
  <div class="section-header">
6552
6552
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
@@ -6555,7 +6555,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
6555
6555
  <span class="section-title">Budget</span>
6556
6556
  </div>
6557
6557
  <div class="budget-bar-container">
6558
- <div class="budget-bar ${e}" style="width: ${t.toFixed(1)}%"></div>
6558
+ <div class="budget-bar ${t}" style="width: ${e.toFixed(1)}%"></div>
6559
6559
  </div>
6560
6560
  <div class="budget-details">
6561
6561
  <span class="budget-used">${this._formatUSD(this._data.budget_used)} used</span>
@@ -6563,7 +6563,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
6563
6563
  <span class="budget-limit">of ${this._formatUSD(this._data.budget_limit)}</span>
6564
6564
  </div>
6565
6565
  </div>
6566
- `}_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=`
6566
+ `}_getRARVTier(e){if(e==null)return null;switch(e%4){case 0:return"opus";case 1:return"sonnet";case 2:return"sonnet";case 3:return"haiku";default:return"sonnet"}}_getPricingColorClass(e,t){if(t.tier==="planning")return"opus";if(t.tier==="development")return"sonnet";if(t.tier==="fast")return"haiku";if(t.iteration!=null)return this._getRARVTier(t.iteration)||"";let i=(e||"").toLowerCase();return i.includes("opus")?"opus":i.includes("sonnet")?"sonnet":i.includes("haiku")?"haiku":t.provider==="codex"||i.includes("gpt")||i.includes("codex")?"codex":""}_escapeHTML(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}render(){let e=this._data.total_input_tokens+this._data.total_output_tokens;this.shadowRoot.innerHTML=`
6567
6567
  <style>
6568
6568
  ${this.getBaseStyles()}
6569
6569
 
@@ -6837,7 +6837,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
6837
6837
  <div class="summary-grid">
6838
6838
  <div class="summary-card">
6839
6839
  <div class="card-label">Total Tokens</div>
6840
- <div class="card-value">${this._formatTokens(t)}</div>
6840
+ <div class="card-value">${this._formatTokens(e)}</div>
6841
6841
  <div class="card-sub">${this._formatTokens(this._data.total_input_tokens)} in / ${this._formatTokens(this._data.total_output_tokens)} out</div>
6842
6842
  </div>
6843
6843
 
@@ -6916,21 +6916,21 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
6916
6916
  ${this._pricingDate?`<span class="pricing-meta">Updated: ${this._escapeHTML(this._pricingDate)}</span>`:""}
6917
6917
  </div>
6918
6918
  <div class="pricing-grid">
6919
- ${Object.entries(this._modelPricing).map(([e,i])=>`
6919
+ ${Object.entries(this._modelPricing).map(([t,i])=>`
6920
6920
  <div class="pricing-item">
6921
- <div class="pricing-model ${this._getPricingColorClass(e,i)}">${i.label||e}</div>
6921
+ <div class="pricing-model ${this._getPricingColorClass(t,i)}">${i.label||t}</div>
6922
6922
  <div class="pricing-rates">In: $${Number(i.input??0).toFixed(2)} / Out: $${Number(i.output??0).toFixed(2)}</div>
6923
6923
  </div>`).join("")}
6924
6924
  </div>
6925
6925
  </div>
6926
6926
  </div>
6927
- `}};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,this._notice=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._notice=null,this.render();try{let e=await this._api._post(`/api/checkpoints/${t}/rollback`);this._rollbackTarget=null;let i=e&&e.pre_rollback_snapshot;this._notice=i?`Rolled back to ${t}. Undo this with checkpoint ${i}`:`Rolled back to ${t}.`,this.dispatchEvent(new CustomEvent("checkpoint-action",{detail:{action:"rollback",checkpointId:t,preRollbackSnapshot:i||null},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._notice=null,this.render()}_confirmRollback(t){this._rollbackTarget=t,this.render()}_cancelRollback(){this._rollbackTarget=null,this._notice=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=`
6927
+ `}};customElements.get("loki-cost-dashboard")||customElements.define("loki-cost-dashboard",X);var Z=class extends u{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,this._notice=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_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]=await Promise.allSettled([this._api._get("/api/checkpoints?limit=50")]);t.status==="fulfilled"&&(this._checkpoints=Array.isArray(t.value)?t.value:t.value?.checkpoints||[]),this._error=null}catch(t){this._error=t.message}let e=JSON.stringify({c:this._checkpoints,e:this._error});e!==this._lastDataHash&&(this._lastDataHash=e,this.render())}async _createCheckpoint(){let e=this.shadowRoot.getElementById("checkpoint-message"),t=e?e.value.trim():"";if(t){this._creating=!0,this.render();try{await this._api._post("/api/checkpoints",{message:t}),this._showCreateForm=!1,this._creating=!1,this.dispatchEvent(new CustomEvent("checkpoint-action",{detail:{action:"create",message:t},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(e){if(!this._rollingBack){this._rollingBack=!0,this._notice=null,this.render();try{let t=await this._api._post(`/api/checkpoints/${e}/rollback`);this._rollbackTarget=null;let i=t&&t.pre_rollback_snapshot;this._notice=i?`Rolled back to ${e}. Undo this with checkpoint ${i}`:`Rolled back to ${e}.`,this.dispatchEvent(new CustomEvent("checkpoint-action",{detail:{action:"rollback",checkpointId:e,preRollbackSnapshot:i||null},bubbles:!0})),this._lastDataHash=null,await this._loadData()}catch(t){this._rollbackTarget=null,this._error=`Failed to rollback: ${t.message}`}finally{this._rollingBack=!1,this.render()}}}_toggleCreateForm(){this._showCreateForm=!this._showCreateForm,this._rollbackTarget=null,this._notice=null,this.render()}_confirmRollback(e){this._rollbackTarget=e,this.render()}_cancelRollback(){this._rollbackTarget=null,this._notice=null,this.render()}_formatRelativeTime(e){if(!e)return"";try{let t=Date.now(),i=new Date(e).getTime(),a=Math.floor((t-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(e)}}render(){let e=this.shadowRoot;if(!e)return;let t=this._checkpoints.length;e.innerHTML=`
6928
6928
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
6929
6929
  <div class="checkpoint-viewer">
6930
6930
  <div class="checkpoint-header">
6931
6931
  <div class="header-left">
6932
6932
  <h2 class="title">Checkpoints</h2>
6933
- <span class="count-badge">${e}</span>
6933
+ <span class="count-badge">${t}</span>
6934
6934
  </div>
6935
6935
  <button class="btn btn-primary" id="create-btn">
6936
6936
  ${this._showCreateForm?"Cancel":"Create Checkpoint"}
@@ -6941,7 +6941,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
6941
6941
 
6942
6942
  <div class="checkpoint-list">
6943
6943
  ${this._loading?'<div class="loading-state">Loading checkpoints...</div>':""}
6944
- ${!this._loading&&e===0?'<div class="empty-state">No checkpoints yet. Create one to save the current state.</div>':""}
6944
+ ${!this._loading&&t===0?'<div class="empty-state">No checkpoints yet. Create one to save the current state.</div>':""}
6945
6945
  ${this._checkpoints.map(i=>this._renderCheckpointCard(i)).join("")}
6946
6946
  </div>
6947
6947
 
@@ -6962,34 +6962,34 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
6962
6962
  ${this._creating?"Creating...":"Save"}
6963
6963
  </button>
6964
6964
  </div>
6965
- `}_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`
6966
- <div class="checkpoint-card" data-checkpoint-id="${this._escapeHTML(t.id)}">
6965
+ `}_renderCheckpointCard(e){let t=e.git_sha?e.git_sha.substring(0,7):"",i=e.files_count||(Array.isArray(e.files)?e.files.length:0),a=this._rollbackTarget===e.id,s=e.iteration!=null?`Iter ${e.iteration}`:"",r=e.provider||"",o=e.phase||"",n=e.git_branch||"",l=[s,r,o].filter(Boolean);return`
6966
+ <div class="checkpoint-card" data-checkpoint-id="${this._escapeHTML(e.id)}">
6967
6967
  <div class="card-header">
6968
6968
  <div class="header-tags">
6969
- ${e?`<span class="checkpoint-sha mono">${this._escapeHTML(e)}</span>`:""}
6969
+ ${t?`<span class="checkpoint-sha mono">${this._escapeHTML(t)}</span>`:""}
6970
6970
  ${l.map(c=>`<span class="checkpoint-tag">${this._escapeHTML(c)}</span>`).join("")}
6971
6971
  </div>
6972
- <span class="checkpoint-time">${this._formatRelativeTime(t.created_at)}</span>
6972
+ <span class="checkpoint-time">${this._formatRelativeTime(e.created_at)}</span>
6973
6973
  </div>
6974
6974
  <div class="card-body">
6975
- <p class="checkpoint-message">${this._escapeHTML(t.message||"Checkpoint")}</p>
6975
+ <p class="checkpoint-message">${this._escapeHTML(e.message||"Checkpoint")}</p>
6976
6976
  <div class="card-meta">
6977
6977
  ${i>0?`<span class="meta-item">${i} file${i!==1?"s":""}</span>`:""}
6978
6978
  ${n?`<span class="meta-item mono">${this._escapeHTML(n)}</span>`:""}
6979
- <span class="meta-item mono">${this._escapeHTML(t.id)}</span>
6979
+ <span class="meta-item mono">${this._escapeHTML(e.id)}</span>
6980
6980
  </div>
6981
6981
  </div>
6982
6982
  <div class="card-actions">
6983
6983
  ${a?`
6984
6984
  <span class="rollback-confirm-text">Rollback to this checkpoint?</span>
6985
- <button class="btn btn-sm btn-danger" data-action="confirm-rollback" data-id="${this._escapeHTML(t.id)}">Confirm</button>
6985
+ <button class="btn btn-sm btn-danger" data-action="confirm-rollback" data-id="${this._escapeHTML(e.id)}">Confirm</button>
6986
6986
  <button class="btn btn-sm" data-action="cancel-rollback">Cancel</button>
6987
6987
  `:`
6988
- <button class="btn btn-sm" data-action="rollback" data-id="${this._escapeHTML(t.id)}">Rollback</button>
6988
+ <button class="btn btn-sm" data-action="rollback" data-id="${this._escapeHTML(e.id)}">Rollback</button>
6989
6989
  `}
6990
6990
  </div>
6991
6991
  </div>
6992
- `}_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`
6992
+ `}_escapeHTML(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("create-btn");t&&t.addEventListener("click",()=>this._toggleCreateForm());let i=e.getElementById("submit-create-btn");i&&i.addEventListener("click",()=>this._createCheckpoint());let a=e.getElementById("checkpoint-message");a&&(a.addEventListener("keydown",s=>{s.key==="Enter"&&!this._creating&&(s.preventDefault(),this._createCheckpoint())}),requestAnimationFrame(()=>a.focus())),e.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`
6993
6993
  :host {
6994
6994
  display: block;
6995
6995
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
@@ -7243,7 +7243,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
7243
7243
  color: var(--loki-green, #22c55e);
7244
7244
  font-size: 12px;
7245
7245
  }
7246
- `}};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`
7246
+ `}};customElements.get("loki-checkpoint-viewer")||customElements.define("loki-checkpoint-viewer",Z);var ee=class extends u{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(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadContext()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}async _loadContext(){try{let e=this.getAttribute("api-url")||window.location.origin,t=await fetch(e+"/api/context");t.ok&&(this._data=await t.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(e){this._activeTab=e,this.render()}_formatTokens(e){return!e||e===0?"0":e>=1e6?(e/1e6).toFixed(2)+"M":e>=1e3?(e/1e3).toFixed(1)+"K":String(e)}_formatUSD(e){return!e||e===0?"$0.00":e<.01?"<$0.01":"$"+e.toFixed(2)}_escapeHTML(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getGaugeColor(e){return e>80?"var(--loki-red)":e>=60?"var(--loki-yellow)":"var(--loki-green)"}_getGaugeColorClass(e){return e>80?"gauge-red":e>=60?"gauge-yellow":"gauge-green"}_renderGaugeTab(){let e=this._data?.current||{},t=this._data?.totals||{},i=e.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`
7247
7247
  <div class="gauge-tab">
7248
7248
  <div class="gauge-container">
7249
7249
  <svg class="gauge-svg" viewBox="0 0 180 180" aria-label="Context window usage: ${i.toFixed(1)}%">
@@ -7280,20 +7280,20 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
7280
7280
  <div class="summary-grid">
7281
7281
  <div class="summary-card">
7282
7282
  <div class="card-label">Total Tokens</div>
7283
- <div class="card-value">${this._formatTokens(t.total_tokens)}</div>
7284
- <div class="card-sub">${this._formatTokens(t.input_tokens)} in / ${this._formatTokens(t.output_tokens)} out</div>
7283
+ <div class="card-value">${this._formatTokens(e.total_tokens)}</div>
7284
+ <div class="card-sub">${this._formatTokens(e.input_tokens)} in / ${this._formatTokens(e.output_tokens)} out</div>
7285
7285
  </div>
7286
7286
  <div class="summary-card">
7287
7287
  <div class="card-label">Estimated Cost</div>
7288
- <div class="card-value accent">${this._formatUSD(t.estimated_cost_usd)}</div>
7288
+ <div class="card-value accent">${this._formatUSD(e.estimated_cost_usd)}</div>
7289
7289
  </div>
7290
7290
  <div class="summary-card">
7291
7291
  <div class="card-label">Compactions</div>
7292
- <div class="card-value">${e.compaction_count||0}</div>
7292
+ <div class="card-value">${t.compaction_count||0}</div>
7293
7293
  </div>
7294
7294
  <div class="summary-card">
7295
7295
  <div class="card-label">Iterations Tracked</div>
7296
- <div class="card-value">${e.iterations_tracked||0}</div>
7296
+ <div class="card-value">${t.iterations_tracked||0}</div>
7297
7297
  </div>
7298
7298
  </div>
7299
7299
 
@@ -7309,16 +7309,16 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
7309
7309
  <div class="cache-grid">
7310
7310
  <div class="cache-item">
7311
7311
  <span class="cache-label">Cache Read</span>
7312
- <span class="cache-value">${this._formatTokens(t.cache_read_tokens)}</span>
7312
+ <span class="cache-value">${this._formatTokens(e.cache_read_tokens)}</span>
7313
7313
  </div>
7314
7314
  <div class="cache-item">
7315
7315
  <span class="cache-label">Cache Creation</span>
7316
- <span class="cache-value">${this._formatTokens(t.cache_creation_tokens)}</span>
7316
+ <span class="cache-value">${this._formatTokens(e.cache_creation_tokens)}</span>
7317
7317
  </div>
7318
7318
  </div>
7319
7319
  </div>
7320
7320
  </div>
7321
- `}_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+=`
7321
+ `}_renderTimelineTab(){let e=this._data?.per_iteration||[],t=this._data?.compactions||[];if(e.length===0)return'<div class="empty-state">No iteration data yet</div>';let i=Math.max(...e.map(r=>(r.input_tokens||0)+(r.output_tokens||0)+(r.cache_read_tokens||0)+(r.cache_creation_tokens||0))),a=new Set(t.map(r=>r.at_iteration)),s="";for(let r of e){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+=`
7322
7322
  <div class="timeline-compaction-row">
7323
7323
  <div class="compaction-line"></div>
7324
7324
  <span class="compaction-label">Context Compacted</span>
@@ -7349,19 +7349,19 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
7349
7349
  </div>
7350
7350
  ${s}
7351
7351
  </div>
7352
- `}_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=`
7352
+ `}_renderBreakdownTab(){let e=this._data?.per_iteration||[];if(e.length===0)return'<div class="empty-state">No iteration data yet</div>';let t=Math.max(...e.map(s=>(s.input_tokens||0)+(s.output_tokens||0)+(s.cache_read_tokens||0)+(s.cache_creation_tokens||0))),i=`
7353
7353
  <div class="breakdown-legend">
7354
7354
  <div class="legend-item"><span class="legend-swatch swatch-input"></span> Input</div>
7355
7355
  <div class="legend-item"><span class="legend-swatch swatch-output"></span> Output</div>
7356
7356
  <div class="legend-item"><span class="legend-swatch swatch-cache-read"></span> Cache Read</div>
7357
7357
  <div class="legend-item"><span class="legend-swatch swatch-cache-create"></span> Cache Creation</div>
7358
7358
  </div>
7359
- `,a="";for(let s of t){let r=s.input_tokens||0,o=s.output_tokens||0,n=s.cache_read_tokens||0,l=s.cache_creation_tokens||0,c=r+o+n+l,p=e>0?r/e*100:0,u=e>0?o/e*100:0,b=e>0?n/e*100:0,m=e>0?l/e*100:0;a+=`
7359
+ `,a="";for(let s of e){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=t>0?r/t*100:0,h=t>0?o/t*100:0,b=t>0?n/t*100:0,m=t>0?l/t*100:0;a+=`
7360
7360
  <div class="breakdown-row">
7361
7361
  <div class="breakdown-iter">#${s.iteration}</div>
7362
7362
  <div class="breakdown-bar-container">
7363
7363
  <div class="breakdown-bar bar-input" style="width: ${p.toFixed(1)}%"></div>
7364
- <div class="breakdown-bar bar-output" style="width: ${u.toFixed(1)}%"></div>
7364
+ <div class="breakdown-bar bar-output" style="width: ${h.toFixed(1)}%"></div>
7365
7365
  <div class="breakdown-bar bar-cache-read" style="width: ${b.toFixed(1)}%"></div>
7366
7366
  <div class="breakdown-bar bar-cache-create" style="width: ${m.toFixed(1)}%"></div>
7367
7367
  </div>
@@ -7380,7 +7380,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
7380
7380
  ${i}
7381
7381
  ${a}
7382
7382
  </div>
7383
- `}render(){let t=this._activeTab==="gauge"?this._renderGaugeTab():this._activeTab==="timeline"?this._renderTimelineTab():this._renderBreakdownTab();this.shadowRoot.innerHTML=`
7383
+ `}render(){let e=this._activeTab==="gauge"?this._renderGaugeTab():this._activeTab==="timeline"?this._renderTimelineTab():this._renderBreakdownTab();this.shadowRoot.innerHTML=`
7384
7384
  <style>
7385
7385
  ${this.getBaseStyles()}
7386
7386
 
@@ -7764,43 +7764,43 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
7764
7764
  <button class="tab ${this._activeTab==="breakdown"?"active":""}" data-tab="breakdown">Breakdown</button>
7765
7765
  </div>
7766
7766
 
7767
- ${t}
7767
+ ${e}
7768
7768
  </div>
7769
- `,this.shadowRoot.querySelectorAll(".tab").forEach(e=>{e.addEventListener("click",()=>{this._setTab(e.dataset.tab)})})}};customElements.get("loki-context-tracker")||customElements.define("loki-context-tracker",tt);var Dt={critical:"var(--loki-red, #ef4444)",warning:"var(--loki-yellow, #eab308)",info:"var(--loki-blue, #3b82f6)",success:"var(--loki-green, #1FC5A8)"},Gt={build:{label:"Build",icon:"B"},quality:{label:"Quality",icon:"Q"},system:{label:"System",icon:"S"},security:{label:"Security",icon:"!"}},et=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._notifications=[],this._triggers=[],this._summary={},this._connected=!1,this._activeTab="feed",this._categoryFilter="all",this._panelOpen=!0,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._loadNotifications(),this._loadTriggers(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&(this._loadNotifications(),this._loadTriggers()),t==="theme"&&this._applyTheme())}async _loadNotifications(){try{let t=this.getAttribute("api-url")||window.location.origin,e=await fetch(t+"/api/notifications");if(e.ok){let i=await e.json();this._notifications=i.notifications||[],this._summary=i.summary||{},this._connected=!0}}catch{this._connected=!1}this.render()}async _loadTriggers(){try{let t=this.getAttribute("api-url")||window.location.origin,e=await fetch(t+"/api/notifications/triggers");if(e.ok){let i=await e.json();this._triggers=i.triggers||[]}}catch{}}async _acknowledgeNotification(t){let e=this.getAttribute("api-url")||window.location.origin;try{await fetch(e+"/api/notifications/"+encodeURIComponent(t)+"/acknowledge",{method:"POST"})}catch{}this._loadNotifications()}async _unacknowledgeNotification(t){let e=this.getAttribute("api-url")||window.location.origin;await fetch(e+"/api/notifications/"+encodeURIComponent(t)+"/unacknowledge",{method:"POST"}),this._loadNotifications()}async _acknowledgeAll(){let t=this.getAttribute("api-url")||window.location.origin,e=this._notifications.filter(i=>!i.acknowledged);for(let i of e)await fetch(t+"/api/notifications/"+encodeURIComponent(i.id)+"/acknowledge",{method:"POST"});this._loadNotifications()}async _toggleTrigger(t,e){let i=this.getAttribute("api-url")||window.location.origin,a=this._triggers.map(s=>s.id===t?{...s,enabled:e}:s);await fetch(i+"/api/notifications/triggers",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({triggers:a})}),this._triggers=a,this.render()}_startPolling(){this._pollInterval=setInterval(()=>{this._loadNotifications(),this._loadTriggers()},5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_formatTime(t){if(!t)return"";try{let e=new Date(t),a=new Date-e,s=Math.floor(a/1e3),r=Math.floor(s/60),o=Math.floor(r/60),n=Math.floor(o/24);return s<60?s+"s ago":r<60?r+"m ago":o<24?o+"h ago":n<7?n+"d ago":e.toLocaleDateString()}catch{return String(t)}}_getTimeGroup(t){if(!t)return"Other";try{let e=new Date(t),i=new Date,a=new Date(i.getFullYear(),i.getMonth(),i.getDate()),s=new Date(a);s.setDate(s.getDate()-1);let r=new Date(a);return r.setDate(r.getDate()-7),e>=a?"Today":e>=s?"Yesterday":e>=r?"This Week":"Earlier"}catch{return"Other"}}_escapeHTML(t){return t?String(t).replace(/&/g,"&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`
7769
+ `,this.shadowRoot.querySelectorAll(".tab").forEach(t=>{t.addEventListener("click",()=>{this._setTab(t.dataset.tab)})})}};customElements.get("loki-context-tracker")||customElements.define("loki-context-tracker",ee);var De={critical:"var(--loki-red, #ef4444)",warning:"var(--loki-yellow, #eab308)",info:"var(--loki-blue, #3b82f6)",success:"var(--loki-green, #1FC5A8)"},Ge={build:{label:"Build",icon:"B"},quality:{label:"Quality",icon:"Q"},system:{label:"System",icon:"S"},security:{label:"Security",icon:"!"}},te=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._notifications=[],this._triggers=[],this._summary={},this._connected=!1,this._activeTab="feed",this._categoryFilter="all",this._panelOpen=!0,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._loadNotifications(),this._loadTriggers(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&(this._loadNotifications(),this._loadTriggers()),e==="theme"&&this._applyTheme())}async _loadNotifications(){try{let e=this.getAttribute("api-url")||window.location.origin,t=await fetch(e+"/api/notifications");if(t.ok){let i=await t.json();this._notifications=i.notifications||[],this._summary=i.summary||{},this._connected=!0}}catch{this._connected=!1}this.render()}async _loadTriggers(){try{let e=this.getAttribute("api-url")||window.location.origin,t=await fetch(e+"/api/notifications/triggers");if(t.ok){let i=await t.json();this._triggers=i.triggers||[]}}catch{}}async _acknowledgeNotification(e){let t=this.getAttribute("api-url")||window.location.origin;try{await fetch(t+"/api/notifications/"+encodeURIComponent(e)+"/acknowledge",{method:"POST"})}catch{}this._loadNotifications()}async _unacknowledgeNotification(e){let t=this.getAttribute("api-url")||window.location.origin;await fetch(t+"/api/notifications/"+encodeURIComponent(e)+"/unacknowledge",{method:"POST"}),this._loadNotifications()}async _acknowledgeAll(){let e=this.getAttribute("api-url")||window.location.origin,t=this._notifications.filter(i=>!i.acknowledged);for(let i of t)await fetch(e+"/api/notifications/"+encodeURIComponent(i.id)+"/acknowledge",{method:"POST"});this._loadNotifications()}async _toggleTrigger(e,t){let i=this.getAttribute("api-url")||window.location.origin,a=this._triggers.map(s=>s.id===e?{...s,enabled:t}:s);await fetch(i+"/api/notifications/triggers",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({triggers:a})}),this._triggers=a,this.render()}_startPolling(){this._pollInterval=setInterval(()=>{this._loadNotifications(),this._loadTriggers()},5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_formatTime(e){if(!e)return"";try{let t=new Date(e),a=new Date-t,s=Math.floor(a/1e3),r=Math.floor(s/60),o=Math.floor(r/60),n=Math.floor(o/24);return s<60?s+"s ago":r<60?r+"m ago":o<24?o+"h ago":n<7?n+"d ago":t.toLocaleDateString()}catch{return String(e)}}_getTimeGroup(e){if(!e)return"Other";try{let t=new Date(e),i=new Date,a=new Date(i.getFullYear(),i.getMonth(),i.getDate()),s=new Date(a);s.setDate(s.getDate()-1);let r=new Date(a);return r.setDate(r.getDate()-7),t>=a?"Today":t>=s?"Yesterday":t>=r?"This Week":"Earlier"}catch{return"Other"}}_escapeHTML(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getSeverityColor(e){return De[e]||De.info}_getCategory(e){return e.category||e.type||"system"}_switchTab(e){this._activeTab=e,this.render()}_setCategoryFilter(e){this._categoryFilter=e,this.render()}_togglePanel(){this._panelOpen=!this._panelOpen,this.render()}_bindEvents(){let e=this.shadowRoot;e.querySelectorAll(".tab").forEach(a=>{a.addEventListener("click",()=>{this._switchTab(a.dataset.tab)})}),e.querySelectorAll(".cat-btn").forEach(a=>{a.addEventListener("click",()=>{this._setCategoryFilter(a.dataset.cat)})}),e.querySelectorAll(".ack-btn").forEach(a=>{a.addEventListener("click",s=>{s.stopPropagation(),this._acknowledgeNotification(a.dataset.id)})}),e.querySelectorAll(".unread-btn").forEach(a=>{a.addEventListener("click",s=>{s.stopPropagation(),this._unacknowledgeNotification(a.dataset.id)})});let t=e.querySelector(".ack-all-btn");t&&t.addEventListener("click",()=>{this._acknowledgeAll()});let i=e.querySelector(".bell-icon");i&&i.addEventListener("click",()=>{this._togglePanel()}),e.querySelectorAll(".toggle input").forEach(a=>{a.addEventListener("change",()=>{this._toggleTrigger(a.dataset.triggerId,a.checked)})}),e.querySelectorAll(".dismiss-btn").forEach(a=>{a.addEventListener("click",s=>{s.stopPropagation(),this._acknowledgeNotification(a.dataset.id)})})}_renderBellIcon(){let e=this._summary.unacknowledged||0;return`
7770
7770
  <div class="bell-container">
7771
- <button class="bell-icon" title="${t} unread notifications">
7771
+ <button class="bell-icon" title="${e} unread notifications">
7772
7772
  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
7773
7773
  <path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path>
7774
7774
  <path d="M13.73 21a2 2 0 0 1-3.46 0"></path>
7775
7775
  </svg>
7776
- ${t>0?`<span class="badge">${t>99?"99+":t}</span>`:""}
7776
+ ${e>0?`<span class="badge">${e>99?"99+":e}</span>`:""}
7777
7777
  </button>
7778
7778
  </div>
7779
- `}_renderSummaryBar(){let t=this._summary.total||0,e=this._summary.unacknowledged||0,i=this._summary.critical||0;return`
7779
+ `}_renderSummaryBar(){let e=this._summary.total||0,t=this._summary.unacknowledged||0,i=this._summary.critical||0;return`
7780
7780
  <div class="summary-row">
7781
7781
  <div class="summary-grid">
7782
7782
  <div class="summary-card">
7783
7783
  <div class="card-label">Total</div>
7784
- <div class="card-value">${t}</div>
7784
+ <div class="card-value">${e}</div>
7785
7785
  </div>
7786
7786
  <div class="summary-card">
7787
7787
  <div class="card-label">Unread</div>
7788
- <div class="card-value">${e}</div>
7788
+ <div class="card-value">${t}</div>
7789
7789
  </div>
7790
7790
  <div class="summary-card">
7791
7791
  <div class="card-label">Critical</div>
7792
- <div class="card-value" style="color: ${Dt.critical}">${i}</div>
7792
+ <div class="card-value" style="color: ${De.critical}">${i}</div>
7793
7793
  </div>
7794
7794
  </div>
7795
- ${e>0?`
7795
+ ${t>0?`
7796
7796
  <button class="ack-all-btn">Mark All as Read</button>
7797
7797
  `:""}
7798
7798
  </div>
7799
7799
  `}_renderCategoryFilter(){return`
7800
7800
  <div class="category-bar">
7801
- ${["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("")}
7801
+ ${["all","build","quality","system","security"].map(t=>{let i=this._categoryFilter===t,a=t==="all"?"All":Ge[t]?.label||t;return`<button class="cat-btn ${i?"active":""}" data-cat="${t}">${a}</button>`}).join("")}
7802
7802
  </div>
7803
- `}_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`
7803
+ `}_renderNotificationList(){let e=[...this._notifications].sort((s,r)=>new Date(r.timestamp)-new Date(s.timestamp));if(this._categoryFilter!=="all"&&(e=e.filter(s=>this._getCategory(s)===this._categoryFilter)),e.length===0)return'<div class="empty-state">No notifications</div>';let t={};for(let s of e){let r=this._getTimeGroup(s.timestamp);t[r]||(t[r]=[]),t[r].push(s)}let i=["Today","Yesterday","This Week","Earlier","Other"],a="";for(let s of i)!t[s]||t[s].length===0||(a+=`<div class="time-group-label">${s}</div>`,a+=t[s].map(r=>{let o=r.acknowledged,n=this._getSeverityColor(r.severity),l=this._getCategory(r),c=Ge[l]||{label:l,icon:"?"};return`
7804
7804
  <div class="notif-row ${o?"acknowledged":""}">
7805
7805
  <span class="severity-dot" style="background: ${n};" title="${this._escapeHTML(r.severity)}"></span>
7806
7806
  <span class="cat-icon" title="${c.label}">${c.icon}</span>
@@ -7812,15 +7812,15 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
7812
7812
  <button class="dismiss-btn" data-id="${this._escapeHTML(r.id)}" title="Dismiss">&#10005;</button>
7813
7813
  </span>
7814
7814
  </div>
7815
- `}).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`
7815
+ `}).join(""));return a}_renderTriggerList(){return this._triggers.length===0?'<div class="empty-state">No triggers configured</div>':this._triggers.map(e=>{let t=this._getSeverityColor(e.severity),i=e.threshold_pct!=null?`Threshold: ${e.threshold_pct}%`:e.pattern||"";return`
7816
7816
  <div class="trigger-row">
7817
7817
  <label class="toggle">
7818
- <input type="checkbox" data-trigger-id="${this._escapeHTML(t.id)}" ${t.enabled?"checked":""}>
7818
+ <input type="checkbox" data-trigger-id="${this._escapeHTML(e.id)}" ${e.enabled?"checked":""}>
7819
7819
  <span class="toggle-slider"></span>
7820
7820
  </label>
7821
- <span class="trigger-name">${this._escapeHTML(t.id)}</span>
7822
- <span class="trigger-badge type-badge">${this._escapeHTML(t.type||"custom")}</span>
7823
- <span class="trigger-badge severity-badge" style="background: ${e}; color: #fff;">${this._escapeHTML(t.severity||"info")}</span>
7821
+ <span class="trigger-name">${this._escapeHTML(e.id)}</span>
7822
+ <span class="trigger-badge type-badge">${this._escapeHTML(e.type||"custom")}</span>
7823
+ <span class="trigger-badge severity-badge" style="background: ${t}; color: #fff;">${this._escapeHTML(e.severity||"info")}</span>
7824
7824
  ${i?`<span class="trigger-info">${this._escapeHTML(i)}</span>`:""}
7825
7825
  </div>
7826
7826
  `}).join("")}render(){this.shadowRoot.innerHTML=`
@@ -8283,7 +8283,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
8283
8283
  `:""}
8284
8284
  `:""}
8285
8285
  </div>
8286
- `,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=`
8286
+ `,this._bindEvents()}};customElements.get("loki-notification-center")||customElements.define("loki-notification-center",te);var ie=class extends u{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(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}async _loadData(){try{this._data=await this._api._get("/api/session-diff"),this._error=null}catch(e){this._error=e.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(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_toggleDecision(e){this._expandedDecisions.has(e)?this._expandedDecisions.delete(e):this._expandedDecisions.add(e),this.render()}render(){let e=`
8287
8287
  ${this.getBaseStyles()}
8288
8288
 
8289
8289
  :host {
@@ -8481,12 +8481,12 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
8481
8481
  to { transform: rotate(360deg); }
8482
8482
  }
8483
8483
  `;if(this._loading){this.shadowRoot.innerHTML=`
8484
- <style>${t}</style>
8484
+ <style>${e}</style>
8485
8485
  <div class="diff-container">
8486
8486
  <div class="loading-state"><div class="spinner"></div> Loading session diff...</div>
8487
8487
  </div>
8488
8488
  `;return}if(this._error){this.shadowRoot.innerHTML=`
8489
- <style>${t}</style>
8489
+ <style>${e}</style>
8490
8490
  <div class="diff-container">
8491
8491
  <div class="diff-header">
8492
8492
  <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>
@@ -8494,7 +8494,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
8494
8494
  </div>
8495
8495
  <div class="empty-state">No session diff available</div>
8496
8496
  </div>
8497
- `;return}let e=this._data||{},i=this._escapeHtml(e.period||"--"),a=e.counts||{},s=e.highlights||[],r=e.decisions||[],o="";s.length>0&&(o=`
8497
+ `;return}let t=this._data||{},i=this._escapeHtml(t.period||"--"),a=t.counts||{},s=t.highlights||[],r=t.decisions||[],o="";s.length>0&&(o=`
8498
8498
  <div class="highlights-section">
8499
8499
  <div class="section-label">Highlights</div>
8500
8500
  <ul class="highlight-list">
@@ -8515,7 +8515,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
8515
8515
  `}).join("")}
8516
8516
  </div>
8517
8517
  `),this.shadowRoot.innerHTML=`
8518
- <style>${t}</style>
8518
+ <style>${e}</style>
8519
8519
  <div class="diff-container">
8520
8520
  <div class="diff-header">
8521
8521
  <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>
@@ -8545,7 +8545,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
8545
8545
  ${o}
8546
8546
  ${n}
8547
8547
  </div>
8548
- `,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=`
8548
+ `,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",ie);var ae=class extends u{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(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}async _loadData(){try{this._data=await this._api._get("/api/prompt-versions"),this._error=null}catch(e){this._error=e.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(e){this._error=e.message}this._optimizing=!1,this.render()}}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),6e4)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_formatTime(e){if(!e)return"--";try{let t=new Date(e),a=new Date-t,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(e){this._expandedChanges.has(e)?this._expandedChanges.delete(e):this._expandedChanges.add(e),this.render()}render(){let e=`
8549
8549
  ${this.getBaseStyles()}
8550
8550
 
8551
8551
  :host {
@@ -8742,12 +8742,12 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
8742
8742
  to { transform: rotate(360deg); }
8743
8743
  }
8744
8744
  `;if(this._loading){this.shadowRoot.innerHTML=`
8745
- <style>${t}</style>
8745
+ <style>${e}</style>
8746
8746
  <div class="optimizer-container">
8747
8747
  <div class="loading-state"><div class="spinner"></div> Loading prompt data...</div>
8748
8748
  </div>
8749
8749
  `;return}if(this._error&&!this._data){this.shadowRoot.innerHTML=`
8750
- <style>${t}</style>
8750
+ <style>${e}</style>
8751
8751
  <div class="optimizer-container">
8752
8752
  <div class="optimizer-header">
8753
8753
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>
@@ -8755,7 +8755,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
8755
8755
  </div>
8756
8756
  <div class="empty-state">No prompt optimization data available</div>
8757
8757
  </div>
8758
- `;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=`
8758
+ `;return}let t=this._data||{},i=t.version!=null?t.version:"--",a=this._formatTime(t.last_optimized),s=t.failures_analyzed!=null?t.failures_analyzed:"--",r=t.changes||[],o="";r.length>0&&(o=`
8759
8759
  <div class="changes-section">
8760
8760
  <div class="section-label">Changes</div>
8761
8761
  ${r.map((l,c)=>{let p=this._expandedChanges.has(c);return`
@@ -8769,7 +8769,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
8769
8769
  `}).join("")}
8770
8770
  </div>
8771
8771
  `),this.shadowRoot.innerHTML=`
8772
- <style>${t}</style>
8772
+ <style>${e}</style>
8773
8773
  <div class="optimizer-container">
8774
8774
  <div class="optimizer-header">
8775
8775
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>
@@ -8796,12 +8796,12 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
8796
8796
 
8797
8797
  ${o}
8798
8798
  </div>
8799
- `;let n=this.shadowRoot.getElementById("optimize-btn");n&&n.addEventListener("click",()=>this._triggerOptimize()),this.shadowRoot.querySelectorAll(".change-header").forEach(l=>{l.addEventListener("click",()=>{this._toggleChange(parseInt(l.dataset.index))})})}};customElements.get("loki-prompt-optimizer")||customElements.define("loki-prompt-optimizer",at);var st=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data=null,this._history=[],this._error=null,this._loading=!0,this._scanning=!1,this._rigourAvailable=!0,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _loadData(){try{let[t,e]=await Promise.allSettled([this._api._get("/api/quality-score"),this._api._get("/api/quality-score/history")]);if(t.status==="fulfilled"){let i=t.value;i&&i.error&&i.error.includes("not installed")?(this._rigourAvailable=!1,this._data=null):(this._rigourAvailable=!0,this._data=i),this._error=null}else(t.reason?.message||"").includes("404")?(this._rigourAvailable=!1,this._data=null,this._error=null):(this._error="Failed to load quality score",this._data=null);if(e.status==="fulfilled"){let i=e.value;this._history=Array.isArray(i)?i.slice(-10):(i.scores||[]).slice(-10)}}catch(t){this._error=t.message,this._data=null}this._loading=!1,this.render()}async _triggerScan(){if(!this._scanning){this._scanning=!0,this.render();try{await this._api._post("/api/quality-scan",{},{timeout:3e5}),await this._loadData()}catch(t){this._error=t.message}this._scanning=!1,this.render()}}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),6e4)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_escapeHtml(t){return t?String(t).replace(/&/g,"&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`
8799
+ `;let n=this.shadowRoot.getElementById("optimize-btn");n&&n.addEventListener("click",()=>this._triggerOptimize()),this.shadowRoot.querySelectorAll(".change-header").forEach(l=>{l.addEventListener("click",()=>{this._toggleChange(parseInt(l.dataset.index))})})}};customElements.get("loki-prompt-optimizer")||customElements.define("loki-prompt-optimizer",ae);var se=class extends u{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(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}async _loadData(){try{let[e,t]=await Promise.allSettled([this._api._get("/api/quality-score"),this._api._get("/api/quality-score/history")]);if(e.status==="fulfilled"){let i=e.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(e.reason?.message||"").includes("404")?(this._rigourAvailable=!1,this._data=null,this._error=null):(this._error="Failed to load quality score",this._data=null);if(t.status==="fulfilled"){let i=t.value;this._history=Array.isArray(i)?i.slice(-10):(i.scores||[]).slice(-10)}}catch(e){this._error=e.message,this._data=null}this._loading=!1,this.render()}async _triggerScan(){if(!this._scanning){this._scanning=!0,this.render();try{await this._api._post("/api/quality-scan",{},{timeout:3e5}),await this._loadData()}catch(e){this._error=e.message}this._scanning=!1,this.render()}}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),6e4)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getGrade(e){return e>=90?{grade:"A",color:"var(--loki-success)"}:e>=80?{grade:"B",color:"var(--loki-success)"}:e>=70?{grade:"C",color:"var(--loki-warning)"}:e>=60?{grade:"D",color:"var(--loki-warning)"}:{grade:"F",color:"var(--loki-error)"}}_renderSparkline(e){if(!e||e.length<2)return"";let t=e.map(c=>typeof c=="number"?c:c.score||0),i=Math.min(...t),s=Math.max(...t)-i||1,r=120,o=32,n=2,l=t.map((c,p)=>{let h=n+p/(t.length-1)*(r-n*2),b=n+(1-(c-i)/s)*(o-n*2);return`${h},${b}`}).join(" ");return`
8800
8800
  <svg width="${r}" height="${o}" viewBox="0 0 ${r} ${o}" class="sparkline">
8801
8801
  <polyline points="${l}" fill="none" stroke="var(--loki-accent)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
8802
8802
  <circle cx="${l.split(" ").pop().split(",")[0]}" cy="${l.split(" ").pop().split(",")[1]}" r="2.5" fill="var(--loki-accent)"/>
8803
8803
  </svg>
8804
- `}render(){let t=`
8804
+ `}render(){let e=`
8805
8805
  ${this.getBaseStyles()}
8806
8806
 
8807
8807
  :host {
@@ -9067,12 +9067,12 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
9067
9067
  to { transform: rotate(360deg); }
9068
9068
  }
9069
9069
  `;if(this._loading){this.shadowRoot.innerHTML=`
9070
- <style>${t}</style>
9070
+ <style>${e}</style>
9071
9071
  <div class="quality-container">
9072
9072
  <div class="loading-state"><div class="spinner"></div> Loading quality score...</div>
9073
9073
  </div>
9074
9074
  `;return}if(!this._rigourAvailable){this.shadowRoot.innerHTML=`
9075
- <style>${t}</style>
9075
+ <style>${e}</style>
9076
9076
  <div class="quality-container">
9077
9077
  <div class="quality-header">
9078
9078
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
@@ -9085,7 +9085,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
9085
9085
  </div>
9086
9086
  </div>
9087
9087
  `;return}if(this._error&&!this._data){this.shadowRoot.innerHTML=`
9088
- <style>${t}</style>
9088
+ <style>${e}</style>
9089
9089
  <div class="quality-container">
9090
9090
  <div class="quality-header">
9091
9091
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
@@ -9093,7 +9093,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
9093
9093
  </div>
9094
9094
  <div class="empty-state">No quality data available</div>
9095
9095
  </div>
9096
- `;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`
9096
+ `;return}let t=this._data||{},i=t.score!=null?Math.round(t.score):0,{grade:a,color:s}=this._getGrade(i),r=t.categories||{},o=t.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`
9097
9097
  <div class="category-item">
9098
9098
  <span class="category-name">${l[f]||f}</span>
9099
9099
  <div class="progress-bar">
@@ -9101,8 +9101,8 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
9101
9101
  </div>
9102
9102
  <span class="category-score">${x}</span>
9103
9103
  </div>
9104
- `}).join(""),u=[{key:"critical",cls:"finding-critical",label:"Critical"},{key:"major",cls:"finding-major",label:"Major"},{key:"minor",cls:"finding-minor",label:"Minor"},{key:"info",cls:"finding-info",label:"Info"}].filter(f=>(o[f.key]||0)>0).map(f=>`<span class="finding-badge ${f.cls}">${f.label}: ${o[f.key]}</span>`).join(""),b=this._renderSparkline(this._history);this.shadowRoot.innerHTML=`
9105
- <style>${t}</style>
9104
+ `}).join(""),h=[{key:"critical",cls:"finding-critical",label:"Critical"},{key:"major",cls:"finding-major",label:"Major"},{key:"minor",cls:"finding-minor",label:"Minor"},{key:"info",cls:"finding-info",label:"Info"}].filter(f=>(o[f.key]||0)>0).map(f=>`<span class="finding-badge ${f.cls}">${f.label}: ${o[f.key]}</span>`).join(""),b=this._renderSparkline(this._history);this.shadowRoot.innerHTML=`
9105
+ <style>${e}</style>
9106
9106
  <div class="quality-container">
9107
9107
  <div class="quality-header">
9108
9108
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
@@ -9130,55 +9130,55 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
9130
9130
  ${c}
9131
9131
  </div>
9132
9132
 
9133
- ${u?`
9133
+ ${h?`
9134
9134
  <div class="findings-section">
9135
9135
  <div class="section-label">Findings</div>
9136
- <div class="findings-row">${u}</div>
9136
+ <div class="findings-row">${h}</div>
9137
9137
  </div>
9138
9138
  `:""}
9139
9139
  </div>
9140
- `;let m=this.shadowRoot.getElementById("scan-btn");m&&m.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-score")||customElements.define("loki-quality-score",st);var Kt=["understand","guardrail","migrate","verify"],Vt={understand:"Understand",guardrail:"Guardrail",migrate:"Migrate",verify:"Verify"},fe={understand:"#5b9bd5",guardrail:"#e8b84a",migrate:"#5bb870",verify:"#5bc8c8"},rt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._migration=null,this._migrations=[],this._loading=!0,this._error=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._fetchMigrations(),this._pollInterval=setInterval(()=>this._fetchData(),15e3)}disconnectedCallback(){super.disconnectedCallback(),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._fetchMigrations()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _fetchMigrations(){try{let t=await this._api._get("/api/migration/list");this._migrations=Array.isArray(t)?t:t.migrations||[],this._error=null;let e=this._migrations.find(i=>i.status==="in_progress"||i.status==="active");e?await this._fetchStatus(e.migration_id||e.id):this._migration=null}catch(t){this._error=t.message,this._migrations=[],this._migration=null}this._loading=!1,this.render()}async _fetchStatus(t){try{this._migration=await this._api._get(`/api/migration/${encodeURIComponent(t)}/status`),this._error=null}catch(e){this._error=e.message}}async _fetchData(){let t=this._migration&&(this._migration.migration_id||this._migration.id);t?(await this._fetchStatus(t),this.render()):await this._fetchMigrations()}_escapeHtml(t){return t?String(t).replace(/&/g,"&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`
9140
+ `;let m=this.shadowRoot.getElementById("scan-btn");m&&m.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-score")||customElements.define("loki-quality-score",se);var Ke=["understand","guardrail","migrate","verify"],Ve={understand:"Understand",guardrail:"Guardrail",migrate:"Migrate",verify:"Verify"},ft={understand:"#5b9bd5",guardrail:"#e8b84a",migrate:"#5bb870",verify:"#5bc8c8"},re=class extends u{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(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._fetchMigrations()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}async _fetchMigrations(){try{let e=await this._api._get("/api/migration/list");this._migrations=Array.isArray(e)?e:e.migrations||[],this._error=null;let t=this._migrations.find(i=>i.status==="in_progress"||i.status==="active");t?await this._fetchStatus(t.migration_id||t.id):this._migration=null}catch(e){this._error=e.message,this._migrations=[],this._migration=null}this._loading=!1,this.render()}async _fetchStatus(e){try{this._migration=await this._api._get(`/api/migration/${encodeURIComponent(e)}/status`),this._error=null}catch(t){this._error=t.message}}async _fetchData(){let e=this._migration&&(this._migration.migration_id||this._migration.id);e?(await this._fetchStatus(e),this.render()):await this._fetchMigrations()}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;"):""}_getPhaseIcon(e,t,i){return(i||[]).includes(e)?"[x]":e===t?"[>]":"[ ]"}_getPhaseIndex(e){let t=Ke.indexOf(e);return t>=0?t:0}_renderPhaseBar(e,t){let i=t||[];return Ke.map(a=>{let s=i.includes(a),r=a===e,o=ft[a],n=s?"1":r?"0.7":"0.2",l=this._getPhaseIcon(a,e,t);return`
9141
9141
  <div class="phase-segment">
9142
9142
  <div class="phase-bar-fill" style="background:${o};opacity:${n};"></div>
9143
9143
  <div class="phase-label">
9144
9144
  <span class="phase-icon">${l}</span>
9145
- ${Vt[a]}
9145
+ ${Ve[a]}
9146
9146
  </div>
9147
9147
  </div>
9148
- `}).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`
9148
+ `}).join("")}_renderFeatureStats(e){if(!e)return"";let t=e.passing||0,i=e.total||0,a=i>0?Math.round(t/i*100):0,s=a>=80?"var(--loki-success)":a>=50?"var(--loki-warning)":"var(--loki-error)";return`
9149
9149
  <div class="stat-card">
9150
9150
  <div class="stat-header">Feature Tracking</div>
9151
- <div class="stat-value">${e} / ${i}</div>
9151
+ <div class="stat-value">${t} / ${i}</div>
9152
9152
  <div class="stat-pct">${a}% passing</div>
9153
9153
  <div class="progress-bar">
9154
9154
  <div class="progress-fill" style="width:${a}%;background:${s};"></div>
9155
9155
  </div>
9156
9156
  </div>
9157
- `}_renderStepProgress(t){if(!t)return"";let e=t.current||0,i=t.total||0,a=i>0?Math.round(e/i*100):0;return`
9157
+ `}_renderStepProgress(e){if(!e)return"";let t=e.current||0,i=e.total||0,a=i>0?Math.round(t/i*100):0;return`
9158
9158
  <div class="stat-card">
9159
9159
  <div class="stat-header">Step Progress</div>
9160
- <div class="stat-value">${e} / ${i}</div>
9160
+ <div class="stat-value">${t} / ${i}</div>
9161
9161
  <div class="stat-pct">${a}% complete</div>
9162
9162
  <div class="progress-bar">
9163
9163
  <div class="progress-fill" style="width:${a}%;background:var(--loki-accent);"></div>
9164
9164
  </div>
9165
9165
  </div>
9166
- `}_renderSeamSummary(t){if(!t)return"";let e=t.total||0,i=t.high||0,a=t.medium||0,s=t.low||0;return`
9166
+ `}_renderSeamSummary(e){if(!e)return"";let t=e.total||0,i=e.high||0,a=e.medium||0,s=e.low||0;return`
9167
9167
  <div class="stat-card">
9168
9168
  <div class="stat-header">Seam Summary</div>
9169
- <div class="stat-value">${e} seams</div>
9169
+ <div class="stat-value">${t} seams</div>
9170
9170
  <div class="seam-breakdown">
9171
9171
  <span class="seam-badge seam-high">High: ${i}</span>
9172
9172
  <span class="seam-badge seam-medium">Med: ${a}</span>
9173
9173
  <span class="seam-badge seam-low">Low: ${s}</span>
9174
9174
  </div>
9175
9175
  </div>
9176
- `}_renderCheckpoint(t){if(!t)return"";let e=t.timestamp?new Date(t.timestamp).toLocaleString():"--",i=this._escapeHtml(t.step_id||t.stepId||"--");return`
9176
+ `}_renderCheckpoint(e){if(!e)return"";let t=e.timestamp?new Date(e.timestamp).toLocaleString():"--",i=this._escapeHtml(e.step_id||e.stepId||"--");return`
9177
9177
  <div class="checkpoint-section">
9178
9178
  <div class="section-label">Last Checkpoint</div>
9179
9179
  <div class="checkpoint-row">
9180
9180
  <span class="checkpoint-label">Time:</span>
9181
- <span class="checkpoint-value">${this._escapeHtml(e)}</span>
9181
+ <span class="checkpoint-value">${this._escapeHtml(t)}</span>
9182
9182
  </div>
9183
9183
  <div class="checkpoint-row">
9184
9184
  <span class="checkpoint-label">Step:</span>
@@ -9190,7 +9190,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
9190
9190
  <thead>
9191
9191
  <tr><th>ID</th><th>Migration</th><th>Status</th></tr>
9192
9192
  </thead>
9193
- <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`
9193
+ <tbody>${this._migrations.map(t=>{let i=this._escapeHtml(t.migration_id||t.id||"--"),a=this._escapeHtml(t.source||"--"),s=this._escapeHtml(t.target||"--"),r=this._escapeHtml(t.status||"--"),o=t.status==="completed"?"status-done":t.status==="failed"?"status-failed":"status-pending";return`
9194
9194
  <tr>
9195
9195
  <td class="mono">${i}</td>
9196
9196
  <td>${a} -> ${s}</td>
@@ -9198,7 +9198,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
9198
9198
  </tr>
9199
9199
  `}).join("")}</tbody>
9200
9200
  </table>
9201
- `}render(){let t=`
9201
+ `}render(){let e=`
9202
9202
  ${this.getBaseStyles()}
9203
9203
 
9204
9204
  :host { display: block; }
@@ -9496,25 +9496,25 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
9496
9496
  @keyframes spin {
9497
9497
  to { transform: rotate(360deg); }
9498
9498
  }
9499
- `,e='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 3 21 3 21 8"/><line x1="4" y1="20" x2="21" y2="3"/><polyline points="21 16 21 21 16 21"/><line x1="15" y1="15" x2="21" y2="21"/><line x1="4" y1="4" x2="9" y2="9"/></svg>';if(this._loading){this.shadowRoot.innerHTML=`
9500
- <style>${t}</style>
9499
+ `,t='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 3 21 3 21 8"/><line x1="4" y1="20" x2="21" y2="3"/><polyline points="21 16 21 21 16 21"/><line x1="15" y1="15" x2="21" y2="21"/><line x1="4" y1="4" x2="9" y2="9"/></svg>';if(this._loading){this.shadowRoot.innerHTML=`
9500
+ <style>${e}</style>
9501
9501
  <div class="migration-container">
9502
9502
  <div class="loading-state"><div class="spinner"></div> Loading migrations...</div>
9503
9503
  </div>
9504
9504
  `;return}if(this._error&&!this._migration&&this._migrations.length===0){this.shadowRoot.innerHTML=`
9505
- <style>${t}</style>
9505
+ <style>${e}</style>
9506
9506
  <div class="migration-container">
9507
9507
  <div class="migration-header">
9508
- ${e}
9508
+ ${t}
9509
9509
  <span class="migration-title">Migration Dashboard</span>
9510
9510
  </div>
9511
9511
  <div class="empty-state">No migration data available</div>
9512
9512
  </div>
9513
9513
  `;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=`
9514
- <style>${t}</style>
9514
+ <style>${e}</style>
9515
9515
  <div class="migration-container">
9516
9516
  <div class="migration-header">
9517
- ${e}
9517
+ ${t}
9518
9518
  <span class="migration-title">Migration Dashboard</span>
9519
9519
  <span class="migration-id">${a}</span>
9520
9520
  </div>
@@ -9533,7 +9533,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
9533
9533
  </div>
9534
9534
  <div class="meta-item">
9535
9535
  <span class="meta-label">Phase</span>
9536
- <span>${Vt[o]||this._escapeHtml(o)}</span>
9536
+ <span>${Ve[o]||this._escapeHtml(o)}</span>
9537
9537
  </div>
9538
9538
  </div>
9539
9539
 
@@ -9551,16 +9551,16 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
9551
9551
  ${this._renderCheckpoint(i.last_checkpoint||i.checkpoint)}
9552
9552
  </div>
9553
9553
  `;return}this.shadowRoot.innerHTML=`
9554
- <style>${t}</style>
9554
+ <style>${e}</style>
9555
9555
  <div class="migration-container">
9556
9556
  <div class="migration-header">
9557
- ${e}
9557
+ ${t}
9558
9558
  <span class="migration-title">Migration Dashboard</span>
9559
9559
  </div>
9560
9560
  <div class="section-label">Migrations</div>
9561
9561
  ${this._renderMigrationList()}
9562
9562
  </div>
9563
- `}};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`
9563
+ `}};customElements.get("loki-migration-dashboard")||customElements.define("loki-migration-dashboard",re);var kt=[["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 xt(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 _t(d,e){if(e!=null){let i=xt(e);if(i)return i.provider}let t=(d||"").toLowerCase();for(let[i,a]of kt)if(t.includes(i))return a;return"unknown"}var oe=class extends u{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(e,t,i){t!==i&&e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}async _fetchActivity(){let e=this._api.baseUrl||window.location.origin,t=new AbortController,i=setTimeout(()=>t.abort(),1e4);try{let a=await fetch(`${e}/api/activity?limit=1000`,{signal:t.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 e=await Promise.allSettled([this._fetchActivity(),this._api.getToolEfficiency(50),this._api.getCost(),this._api.getContext(),this._api.getLearningTrends({timeRange:this._toolTimeRange})]);if(e[0].status==="fulfilled"&&(this._activity=e[0].value||[]),e[1].status==="fulfilled"&&(this._tools=e[1].value||[]),e[2].status==="fulfilled"&&(this._cost=e[2].value||{}),e[3].status==="fulfilled"&&(this._context=e[3].value||{}),e[4].status==="fulfilled"){let t=e[4].value||{};this._trends=Array.isArray(t)?t:t.dataPoints||[]}this._connected=e.some(t=>t.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 e={},t=Array.isArray(this._activity)?this._activity:[];for(let c of t){let p=c.timestamp||c.ts||c.created_at;if(!p)continue;let h=new Date(p);if(isNaN(h.getTime()))continue;let b=this._localDateKey(h);e[b]=(e[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=e[c]||0;p>l&&(l=p),o.push({date:c,count:p,day:n.getDay()}),n.setDate(n.getDate()+1)}return{cells:o,maxCount:l}}_getHeatmapLevel(e,t){if(e===0||t===0)return 0;let i=e/t;return i<=.25?1:i<=.5?2:i<=.75?3:4}_renderHeatmap(){let{cells:e,maxCount:t}=this._computeHeatmap(),i=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],a=["","Mon","","Wed","","Fri",""],s=[],r=-1,o=-1;for(let p=0;p<e.length;p++){e[p].day===0&&o++;let h=new Date(e[p].date).getMonth();h!==r&&(s.push({month:i[h],col:Math.max(o,1)}),r=h)}let n=s.map(p=>`<span class="heatmap-month" style="grid-column: ${p.col}">${p.month}</span>`).join(""),l=e.map(p=>`<div class="heatmap-cell level-${this._getHeatmapLevel(p.count,t)}" title="${p.date}: ${p.count} activities"></div>`).join(""),c=a.map(p=>`<span class="heatmap-day-label">${p}</span>`).join("");return`
9564
9564
  <div class="heatmap-container">
9565
9565
  <div class="heatmap-months">${n}</div>
9566
9566
  <div class="heatmap-body">
@@ -9577,7 +9577,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
9577
9577
  <span class="heatmap-legend-label">More</span>
9578
9578
  </div>
9579
9579
  </div>
9580
- `}_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`
9580
+ `}_computeToolUsage(){let e=Array.isArray(this._tools)?this._tools:[],t={};for(let i of e){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;t[a]=(t[a]||0)+s}return Object.entries(t).sort((i,a)=>a[1]-i[1]).slice(0,15)}_renderToolUsage(){let e=this._computeToolUsage(),t=e.length>0?e[0][1]:0;return e.length===0?'<div class="empty-state">No tool usage data available</div>':'<div class="tool-bars">'+e.map(([a,s])=>{let r=t>0?s/t*100:0;return`
9581
9581
  <div class="tool-row">
9582
9582
  <span class="tool-name" title="${this._esc(a)}">${this._esc(a)}</span>
9583
9583
  <div class="tool-bar-track">
@@ -9585,7 +9585,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
9585
9585
  </div>
9586
9586
  <span class="tool-count">${s}</span>
9587
9587
  </div>
9588
- `}).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`
9588
+ `}).join("")+"</div>"}_computeVelocity(){let e=this._context||{},t=e.per_iteration||e.iterations||[],i=Array.isArray(t)&&t.length>0?t.length:e.totals&&e.totals.iterations_tracked||e.total_iterations||0,a=0;if(Array.isArray(t)&&t.length>=2){let o=t.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(t)&&t.length>0){let o={};for(let l of t){let c=l.timestamp||l.started_at||l.ts;if(!c)continue;let h=new Date(c).toISOString().slice(0,13);o[h]=(o[h]||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:e,totalIterations:t,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`
9589
9589
  ${`
9590
9590
  <div class="tool-filter">
9591
9591
  <select class="tool-time-select" id="tool-time-range">
@@ -9599,20 +9599,20 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
9599
9599
  <div class="velocity-cards">
9600
9600
  <div class="velocity-card">
9601
9601
  <div class="velocity-label">Iterations / Hour</div>
9602
- <div class="velocity-value">${t.toFixed(1)}</div>
9602
+ <div class="velocity-value">${e.toFixed(1)}</div>
9603
9603
  </div>
9604
9604
  <div class="velocity-card">
9605
9605
  <div class="velocity-label">Total Iterations</div>
9606
- <div class="velocity-value">${e}</div>
9606
+ <div class="velocity-value">${t}</div>
9607
9607
  </div>
9608
9608
  </div>
9609
9609
  <div class="sparkline-container">
9610
9610
  <div class="sparkline-label">Activity Trend (hourly)</div>
9611
9611
  <div class="sparkline">${s}</div>
9612
9612
  </div>
9613
- `}_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>':`
9613
+ `}_computeProviders(){let e=this._cost.by_model||{},t={};for(let[r,o]of Object.entries(e)){let n=_t(r);t[n]||(t[n]={cost:0,tokens:0,iterations:0,models:[]});let l=o.cost_usd||0,c=(o.input_tokens||0)+(o.output_tokens||0);t[n].cost+=l,t[n].tokens+=c,t[n].models.push(r)}let a=(this._context.totals||{}).iterations_tracked||this._context.total_iterations||this._context.iteration||0,s=this._cost.estimated_cost_usd||0;for(let r of Object.values(t))if(s>0&&a>0){let o=r.cost/s;r.iterations=Math.round(o*a)}return t}_renderProviders(){let e=this._computeProviders(),t={claude:{label:"Claude",color:"var(--loki-accent)"},codex:{label:"Codex",color:"var(--loki-success)"},cline:{label:"Cline",color:"var(--loki-info)"},aider:{label:"Aider",color:"var(--loki-blue)"},unknown:{label:"Other",color:"var(--loki-text-muted)"}},i=Object.entries(e);return i.length===0?'<div class="empty-state">No provider data available. Start a session to see cross-provider comparison.</div>':`
9614
9614
  <div class="provider-grid">
9615
- ${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`
9615
+ ${i.map(([a,s])=>{let r=t[a]||t.unknown,o=s.iterations>0?(s.cost/s.iterations).toFixed(4):"--",n=s.iterations>0?Math.round(s.tokens/s.iterations).toLocaleString():"--";return`
9616
9616
  <div class="provider-card">
9617
9617
  <div class="provider-accent" style="background: ${r.color}"></div>
9618
9618
  <div class="provider-body">
@@ -9638,7 +9638,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
9638
9638
  </div>
9639
9639
  `}).join("")}
9640
9640
  </div>
9641
- `}_esc(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;"):""}_localDateKey(t){return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")}`}_handleTabClick(t){let e=t.target.closest("[data-tab]");e&&(this._activeTab=e.dataset.tab,this.render())}_handleTimeRangeChange(t){this._toolTimeRange=t.target.value,this._loadData()}render(){let t=[{id:"heatmap",label:"Activity",icon:'<svg viewBox="0 0 24 24"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg>'},{id:"tools",label:"Tools",icon:'<svg viewBox="0 0 24 24"><path d="M14.7 6.3a1 1 0 000 1.4l1.6 1.6a1 1 0 001.4 0l3.77-3.77a6 6 0 01-7.94 7.94l-6.91 6.91a2.12 2.12 0 01-3-3l6.91-6.91a6 6 0 017.94-7.94l-3.76 3.76z"/></svg>'},{id:"velocity",label:"Velocity",icon:'<svg viewBox="0 0 24 24"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>'},{id:"providers",label:"Providers",icon:'<svg viewBox="0 0 24 24"><line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/></svg>'}],e="";switch(this._activeTab){case"heatmap":e=this._renderHeatmap();break;case"tools":e=this._renderToolUsage();break;case"velocity":e=this._renderVelocity();break;case"providers":e=this._renderProviders();break}this.shadowRoot.innerHTML=`
9641
+ `}_esc(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;"):""}_localDateKey(e){return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`}_handleTabClick(e){let t=e.target.closest("[data-tab]");t&&(this._activeTab=t.dataset.tab,this.render())}_handleTimeRangeChange(e){this._toolTimeRange=e.target.value,this._loadData()}render(){let e=[{id:"heatmap",label:"Activity",icon:'<svg viewBox="0 0 24 24"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg>'},{id:"tools",label:"Tools",icon:'<svg viewBox="0 0 24 24"><path d="M14.7 6.3a1 1 0 000 1.4l1.6 1.6a1 1 0 001.4 0l3.77-3.77a6 6 0 01-7.94 7.94l-6.91 6.91a2.12 2.12 0 01-3-3l6.91-6.91a6 6 0 017.94-7.94l-3.76 3.76z"/></svg>'},{id:"velocity",label:"Velocity",icon:'<svg viewBox="0 0 24 24"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>'},{id:"providers",label:"Providers",icon:'<svg viewBox="0 0 24 24"><line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/></svg>'}],t="";switch(this._activeTab){case"heatmap":t=this._renderHeatmap();break;case"tools":t=this._renderToolUsage();break;case"velocity":t=this._renderVelocity();break;case"providers":t=this._renderProviders();break}this.shadowRoot.innerHTML=`
9642
9642
  <style>
9643
9643
  ${this.getBaseStyles()}
9644
9644
 
@@ -9997,7 +9997,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
9997
9997
  ${this._connected?"":'<div class="offline-notice">Connecting to analytics API...</div>'}
9998
9998
 
9999
9999
  <div class="tab-bar">
10000
- ${t.map(a=>`
10000
+ ${e.map(a=>`
10001
10001
  <button class="tab-btn ${this._activeTab===a.id?"active":""}" data-tab="${a.id}" aria-label="${a.label}">
10002
10002
  ${a.icon}<span>${a.label}</span>
10003
10003
  </button>
@@ -10005,10 +10005,10 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
10005
10005
  </div>
10006
10006
 
10007
10007
  <div class="tab-content">
10008
- ${e}
10008
+ ${t}
10009
10009
  </div>
10010
10010
  </div>
10011
- `,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`
10011
+ `,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",oe);var Ye={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 yt(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 wt(d){if(!d||d.length===0)return{pass:0,fail:0,pending:0,total:0};let e={pass:0,fail:0,pending:0,total:d.length};for(let t of d){let i=(t.status||"pending").toLowerCase();i==="pass"?e.pass++:i==="fail"?e.fail++:e.pending++}return e}var ne=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._gates=[],this._evidence={blocked:!1},this._pollInterval=null,this._lastDataHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_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 e=await this._api._get("/api/council/gate"),t=e?.gates||e||[],i=e?.evidence||{blocked:!1},a=JSON.stringify({gates:t,evidence:i});if(a===this._lastDataHash)return;this._lastDataHash=a,this._gates=Array.isArray(t)?t:[],this._evidence=i,this._error=null}catch(e){this._error||(this._error=`Failed to load quality gates: ${e.message}`)}finally{this._loading=!1}this.render()}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
10012
10012
  :host {
10013
10013
  display: block;
10014
10014
  }
@@ -10019,6 +10019,44 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
10019
10019
  color: var(--loki-text-primary, #201515);
10020
10020
  }
10021
10021
 
10022
+ .evidence-banner {
10023
+ border: 1px solid var(--loki-red, #ef4444);
10024
+ background: var(--loki-red-bg, rgba(239, 68, 68, 0.08));
10025
+ border-radius: 8px;
10026
+ padding: 12px 14px;
10027
+ margin-bottom: 16px;
10028
+ }
10029
+
10030
+ .evidence-title {
10031
+ font-weight: 600;
10032
+ font-size: 14px;
10033
+ color: var(--loki-red, #ef4444);
10034
+ margin-bottom: 4px;
10035
+ }
10036
+
10037
+ .evidence-reason {
10038
+ font-size: 13px;
10039
+ margin-bottom: 6px;
10040
+ }
10041
+
10042
+ .evidence-failures {
10043
+ margin: 6px 0;
10044
+ padding-left: 18px;
10045
+ font-size: 12px;
10046
+ }
10047
+
10048
+ .evidence-hint {
10049
+ font-size: 11px;
10050
+ opacity: 0.75;
10051
+ }
10052
+
10053
+ .evidence-hint code {
10054
+ font-family: var(--loki-font-mono, monospace);
10055
+ background: var(--loki-code-bg, rgba(0, 0, 0, 0.06));
10056
+ padding: 1px 4px;
10057
+ border-radius: 3px;
10058
+ }
10059
+
10022
10060
  .header {
10023
10061
  display: flex;
10024
10062
  align-items: center;
@@ -10139,16 +10177,23 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
10139
10177
  color: var(--loki-text-muted, #939084);
10140
10178
  font-size: 13px;
10141
10179
  }
10142
- `}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`
10143
- <div class="gate-card status-${n}">
10180
+ `}render(){let e=this.shadowRoot;if(!e)return;let t=this._gates,i=wt(t),a;this._loading&&t.length===0?a='<div class="loading">Loading quality gates...</div>':t.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">${t.map(l=>{let c=(l.status||"pending").toLowerCase(),p=Ye[c]||Ye.pending;return`
10181
+ <div class="gate-card status-${c}">
10144
10182
  <div class="gate-header">
10145
- <span class="gate-name">${this._escapeHtml(o.name||"Unnamed Gate")}</span>
10146
- <span class="gate-badge" style="background: ${l.bg}; color: ${l.color};">${l.label}</span>
10183
+ <span class="gate-name">${this._escapeHtml(l.name||"Unnamed Gate")}</span>
10184
+ <span class="gate-badge" style="background: ${p.bg}; color: ${p.color};">${p.label}</span>
10147
10185
  </div>
10148
- ${o.description?`<div class="gate-description">${this._escapeHtml(o.description)}</div>`:""}
10149
- <div class="gate-meta">Last checked: ${ye(o.last_checked||o.lastChecked)}</div>
10186
+ ${l.description?`<div class="gate-description">${this._escapeHtml(l.description)}</div>`:""}
10187
+ <div class="gate-meta">Last checked: ${yt(l.last_checked||l.lastChecked)}</div>
10150
10188
  </div>
10151
- `}).join("")}</div>`;let s=i.total>0?`
10189
+ `}).join("")}</div>`;let s="",r=this._evidence||{};if(r.blocked){let n={empty_diff:"No changes were shipped (empty diff vs run start).",tests_red:"Tests ran and were red.",empty_diff_and_tests_red:"No changes shipped and tests were red.",no_evidence_of_completion:"No evidence of completion."},l=r.error?this._escapeHtml(r.error):n[r.reason]||this._escapeHtml(r.reason||"Completion blocked."),c=Array.isArray(r.failures)?r.failures:[],p=c.length?`<ul class="evidence-failures">${c.map(h=>`<li>${this._escapeHtml(h)}</li>`).join("")}</ul>`:"";s=`
10190
+ <div class="evidence-banner">
10191
+ <div class="evidence-title">Verified completion blocked</div>
10192
+ <div class="evidence-reason">${l}</div>
10193
+ ${p}
10194
+ <div class="evidence-hint">The run will keep iterating until there is real evidence of completion. Set <code>LOKI_EVIDENCE_GATE=0</code> to opt out.</div>
10195
+ </div>
10196
+ `}let o=i.total>0?`
10152
10197
  <div class="summary">
10153
10198
  <span class="summary-item">
10154
10199
  <span class="summary-dot" style="background: var(--loki-green, #22c55e)"></span>
@@ -10163,17 +10208,18 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
10163
10208
  ${i.pending} Pending
10164
10209
  </span>
10165
10210
  </div>
10166
- `:"";t.innerHTML=`
10211
+ `:"";e.innerHTML=`
10167
10212
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
10168
10213
  <div class="quality-gates">
10169
10214
  <div class="header">
10170
10215
  <h2 class="title">Quality Gates</h2>
10171
- ${s}
10216
+ ${o}
10172
10217
  </div>
10218
+ ${s}
10173
10219
  ${a}
10174
10220
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
10175
10221
  </div>
10176
- `}};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`
10222
+ `}};customElements.get("loki-quality-gates")||customElements.define("loki-quality-gates",ne);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"}},ze=["reason","act","reflect","verify"];function Le(d){if(d==null||d<0)return"--";if(d<1e3)return`${d}ms`;let e=Math.floor(d/1e3);if(e<60)return`${e}s`;let t=Math.floor(e/60),i=e%60;if(t<60)return`${t}m ${i}s`;let a=Math.floor(t/60),s=t%60;return`${a}h ${s}m`}function $t(d){if(!d||d.length===0)return[];let e=d.reduce((t,i)=>t+(i.duration_ms||0),0);return e===0?d.map(t=>({phase:t.phase,pct:100/d.length,duration:0})):d.map(t=>({phase:t.phase,pct:(t.duration_ms||0)/e*100,duration:t.duration_ms||0}))}function Et(d){return d==null?"--":d>=1e6?(d/1e6).toFixed(1)+"M":d>=1e3?(d/1e3).toFixed(1)+"K":String(d)}var le=class extends u{static get observedAttributes(){return["run-id","api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._timeline=null,this._pollInterval=null,this._selectedPhase=null,this._cycleHistory=[]}get runId(){let e=this.getAttribute("run-id");return e?parseInt(e,10):null}set runId(e){e!=null?this.setAttribute("run-id",String(e)):this.removeAttribute("run-id")}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),e==="run-id"&&this._loadData(),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_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 e=this.runId;if(e==null){this._timeline=null,this.render();return}try{this._loading=!0;let t=await this._api._get(`/api/v2/runs/${e}/timeline`);this._timeline=t,this._cycleHistory=t.history||[],this._error=null}catch(t){t.message&&(t.message.includes("404")||t.message.includes("Not Found"))?(this._timeline=null,this._error=null):this._error=`Failed to load timeline: ${t.message}`}finally{this._loading=!1}this.render()}_selectPhase(e){this._selectedPhase=this._selectedPhase===e?null:e,this.render()}_bindEvents(){let e=this.shadowRoot;e.querySelectorAll(".phase-segment-interactive").forEach(t=>{t.addEventListener("click",()=>{this._selectPhase(t.dataset.phase)})}),e.querySelectorAll(".legend-item-interactive").forEach(t=>{t.addEventListener("click",()=>{this._selectPhase(t.dataset.phase)})}),e.querySelectorAll(".close-detail").forEach(t=>{t.addEventListener("click",i=>{i.stopPropagation(),this._selectedPhase=null,this.render()})})}_getStyles(){return`
10177
10223
  :host {
10178
10224
  display: block;
10179
10225
  }
@@ -10458,41 +10504,41 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
10458
10504
  color: var(--loki-text-muted, #939084);
10459
10505
  font-size: 13px;
10460
10506
  }
10461
- `}_renderPlaceholderTimeline(){let t=zt.map(i=>{let a=F[i];return`<div class="phase-segment-interactive"
10507
+ `}_renderPlaceholderTimeline(){let e=ze.map(i=>{let a=F[i];return`<div class="phase-segment-interactive"
10462
10508
  data-phase="${i}"
10463
10509
  style="width: 25%; background: ${a.color}; opacity: 0.3;"
10464
10510
  title="${a.label}: awaiting data">
10465
10511
  ${a.label}
10466
- </div>`}).join(""),e=zt.map(i=>{let a=F[i];return`<div class="legend-item-interactive" data-phase="${i}">
10512
+ </div>`}).join(""),t=ze.map(i=>{let a=F[i];return`<div class="legend-item-interactive" data-phase="${i}">
10467
10513
  <span class="legend-dot" style="background: ${a.color}; opacity: 0.4;"></span>
10468
10514
  <span class="legend-label">${a.label}</span>
10469
10515
  <span class="legend-duration">--</span>
10470
10516
  </div>`}).join("");return`
10471
10517
  <div class="empty-state" style="padding: 0; text-align: left;">
10472
- <div class="timeline-bar" style="opacity: 0.5;">${t}</div>
10473
- <div class="legend">${e}</div>
10518
+ <div class="timeline-bar" style="opacity: 0.5;">${e}</div>
10519
+ <div class="legend">${t}</div>
10474
10520
  <div style="text-align: center; margin-top: 12px; font-size: 12px; color: var(--loki-text-muted, #939084);">
10475
10521
  RARV phases will populate as the session progresses
10476
10522
  </div>
10477
10523
  </div>
10478
- `}_renderPhaseDetail(t){let e=F[t];if(!e)return"";let a=(this._timeline?.phases||[]).find(s=>s.phase===t);return`
10524
+ `}_renderPhaseDetail(e){let t=F[e];if(!t)return"";let a=(this._timeline?.phases||[]).find(s=>s.phase===e);return`
10479
10525
  <div class="phase-detail">
10480
10526
  <div class="detail-header">
10481
10527
  <div class="detail-title">
10482
- <div class="detail-title-dot" style="background: ${e.color};"></div>
10483
- ${e.label} Phase
10528
+ <div class="detail-title-dot" style="background: ${t.color};"></div>
10529
+ ${t.label} Phase
10484
10530
  </div>
10485
10531
  <button class="close-detail" title="Close">&#10005;</button>
10486
10532
  </div>
10487
- <div class="detail-description">${e.description}</div>
10533
+ <div class="detail-description">${t.description}</div>
10488
10534
  <div class="detail-metrics">
10489
10535
  <div class="detail-metric">
10490
10536
  <span class="detail-metric-label">Time Spent</span>
10491
- <span class="detail-metric-value">${Lt(a?.duration_ms)}</span>
10537
+ <span class="detail-metric-value">${Le(a?.duration_ms)}</span>
10492
10538
  </div>
10493
10539
  <div class="detail-metric">
10494
10540
  <span class="detail-metric-label">Tokens Used</span>
10495
- <span class="detail-metric-value">${Ee(a?.tokens_used)}</span>
10541
+ <span class="detail-metric-value">${Et(a?.tokens_used)}</span>
10496
10542
  </div>
10497
10543
  <div class="detail-metric">
10498
10544
  <span class="detail-metric-label">Quality</span>
@@ -10504,38 +10550,38 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
10504
10550
  </div>
10505
10551
  </div>
10506
10552
  </div>
10507
- `}_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};"
10508
- title="Cycle ${a+1}: ${n.label} - ${Lt(o?.duration_ms)}"></div>`}).join("")}</div>`).join('<div class="history-separator"></div>');return`
10553
+ `}_renderCycleHistory(){if(this._cycleHistory.length===0)return"";let t=this._cycleHistory.slice(-8).map((i,a)=>`<div class="history-cycle">${ze.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};"
10554
+ title="Cycle ${a+1}: ${n.label} - ${Le(o?.duration_ms)}"></div>`}).join("")}</div>`).join('<div class="history-separator"></div>');return`
10509
10555
  <div class="cycle-history">
10510
10556
  <div class="history-label">Past Cycles (${this._cycleHistory.length} total)</div>
10511
- <div class="history-cycles">${e}</div>
10557
+ <div class="history-cycles">${t}</div>
10512
10558
  </div>
10513
- `}_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},m=s===u.phase,f=this._selectedPhase===u.phase;return`<div class="phase-segment-interactive ${m?"current":""} ${f?"selected":""}"
10514
- data-phase="${u.phase}"
10515
- style="width: ${Math.max(u.pct,2)}%; background: ${b.color};"
10516
- title="${b.label}: ${Lt(u.duration)}">
10517
- ${u.pct>12?b.label:""}
10518
- </div>`}).join(""),l=a.map(u=>{let b=F[u.phase]||{color:"var(--loki-text-muted)",label:u.phase},m=s===u.phase;return`<div class="legend-item-interactive ${this._selectedPhase===u.phase?"selected":""}" data-phase="${u.phase}">
10559
+ `}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}render(){let e=this.shadowRoot;if(!e)return;let t=this.runId,i=this._timeline,a=i?.phases||[],s=i?.current_phase||null,r=$t(a),o;if(this._loading&&!i)o='<div class="loading">Loading timeline...</div>';else if(t==null)o=this._renderPlaceholderTimeline();else if(a.length===0)o=this._renderPlaceholderTimeline();else{let n=r.map(h=>{let b=F[h.phase]||{color:"var(--loki-text-muted)",label:h.phase},m=s===h.phase,f=this._selectedPhase===h.phase;return`<div class="phase-segment-interactive ${m?"current":""} ${f?"selected":""}"
10560
+ data-phase="${h.phase}"
10561
+ style="width: ${Math.max(h.pct,2)}%; background: ${b.color};"
10562
+ title="${b.label}: ${Le(h.duration)}">
10563
+ ${h.pct>12?b.label:""}
10564
+ </div>`}).join(""),l=a.map(h=>{let b=F[h.phase]||{color:"var(--loki-text-muted)",label:h.phase},m=s===h.phase;return`<div class="legend-item-interactive ${this._selectedPhase===h.phase?"selected":""}" data-phase="${h.phase}">
10519
10565
  <span class="legend-dot" style="background: ${b.color}"></span>
10520
10566
  <span class="legend-label">${b.label}</span>
10521
- <span class="legend-duration">${Lt(u.duration_ms)}</span>
10567
+ <span class="legend-duration">${Le(h.duration_ms)}</span>
10522
10568
  ${m?'<span class="phase-current-tag">ACTIVE</span>':""}
10523
10569
  </div>`}).join(""),c=this._selectedPhase?this._renderPhaseDetail(this._selectedPhase):"",p=this._renderCycleHistory();o=`
10524
10570
  <div class="timeline-bar">${n}</div>
10525
10571
  <div class="legend">${l}</div>
10526
10572
  ${c}
10527
10573
  ${p}
10528
- `}t.innerHTML=`
10574
+ `}e.innerHTML=`
10529
10575
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
10530
10576
  <div class="timeline-container">
10531
10577
  <div class="header">
10532
10578
  <h3 class="title">RARV Timeline</h3>
10533
- ${e!=null?`<span class="run-label">Run #${e}</span>`:""}
10579
+ ${t!=null?`<span class="run-label">Run #${t}</span>`:""}
10534
10580
  </div>
10535
10581
  ${o}
10536
10582
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
10537
10583
  </div>
10538
- `,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`
10584
+ `,this._bindEvents()}};customElements.get("loki-rarv-timeline")||customElements.define("loki-rarv-timeline",le);var We={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 Ct(d,e,t){let i=d;if(i==null&&e){let l=new Date(e).getTime();i=(t?new Date(t).getTime():Date.now())-l}if(i==null||i<0)return"--";if(i<1e3)return`${i}ms`;let a=Math.floor(i/1e3);if(a<60)return`${a}s`;let s=Math.floor(a/60),r=a%60;if(s<60)return`${s}m ${r}s`;let o=Math.floor(s/60),n=s%60;return`${o}h ${n}m`}function St(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 de=class extends u{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 e=this.getAttribute("project-id");return e?parseInt(e,10):null}set projectId(e){e!=null?this.setAttribute("project-id",String(e)):this.removeAttribute("project-id")}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),e==="project-id"&&this._loadData(),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_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 e=this.projectId,t=e!=null?`?project_id=${e}`:"",i=await this._api._get(`/api/v2/runs${t}`),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(e){this._error||(this._error=`Failed to load runs: ${e.message}`)}finally{this._loading=!1}this.render()}async _cancelRun(e){try{await this._api._post(`/api/v2/runs/${e}/cancel`),await this._loadData()}catch(t){this._error=`Cancel failed: ${t.message}`,this.render()}}async _replayRun(e){try{await this._api._post(`/api/v2/runs/${e}/replay`),await this._loadData()}catch(t){this._error=`Replay failed: ${t.message}`,this.render()}}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
10539
10585
  :host {
10540
10586
  display: block;
10541
10587
  }
@@ -10688,13 +10734,13 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
10688
10734
  color: var(--loki-text-muted, #939084);
10689
10735
  margin-bottom: 8px;
10690
10736
  }
10691
- `}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`
10737
+ `}render(){let e=this.shadowRoot;if(!e)return;let t=this._runs,i;if(this._loading&&t.length===0)i='<div class="loading">Loading runs...</div>';else if(t.length===0)i='<div class="empty-state">No runs found.</div>';else{let a=t.map(s=>{let r=(s.status||"pending").toLowerCase(),o=We[r]||We.pending,n=r==="running",l=r==="completed"||r==="failed"||r==="cancelled",c=Ct(s.duration_ms,s.started_at,s.ended_at);return`
10692
10738
  <tr>
10693
10739
  <td><span class="run-id">#${s.id}</span></td>
10694
10740
  <td>${this._escapeHtml(s.project_name||s.project||(s.project_id?`Project #${s.project_id}`:"--"))}</td>
10695
10741
  <td><span class="status-badge" style="background: ${o.bg}; color: ${o.color};">${o.label}</span></td>
10696
10742
  <td>${this._escapeHtml(s.trigger||s.trigger_type||"--")}</td>
10697
- <td>${Se(s.started_at)}</td>
10743
+ <td>${St(s.started_at)}</td>
10698
10744
  <td>${c}</td>
10699
10745
  <td>
10700
10746
  <div class="actions-cell">
@@ -10704,7 +10750,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
10704
10750
  </td>
10705
10751
  </tr>
10706
10752
  `}).join("");i=`
10707
- <div class="run-count">${e.length} runs</div>
10753
+ <div class="run-count">${t.length} runs</div>
10708
10754
  <div class="runs-table-wrapper">
10709
10755
  <table>
10710
10756
  <thead>
@@ -10721,7 +10767,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
10721
10767
  <tbody>${a}</tbody>
10722
10768
  </table>
10723
10769
  </div>
10724
- `}t.innerHTML=`
10770
+ `}e.innerHTML=`
10725
10771
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
10726
10772
  <div class="run-manager">
10727
10773
  <div class="header">
@@ -10731,7 +10777,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
10731
10777
  ${i}
10732
10778
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
10733
10779
  </div>
10734
- `,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`
10780
+ `,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("refresh-btn");t&&t.addEventListener("click",()=>this._loadData()),e.querySelectorAll('[data-action="cancel"]').forEach(i=>{i.addEventListener("click",()=>this._cancelRun(i.dataset.runId))}),e.querySelectorAll('[data-action="replay"]').forEach(i=>{i.addEventListener("click",()=>this._replayRun(i.dataset.runId))})}};customElements.get("loki-run-manager")||customElements.define("loki-run-manager",de);function At(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 Tt(d){let e=new URLSearchParams;for(let[i,a]of Object.entries(d))a!=null&&a!==""&&e.set(i,String(a));let t=e.toString();return t?`?${t}`:""}var ce=class extends u{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 e=this.getAttribute("limit");return e?parseInt(e,10):50}set limit(e){this.setAttribute("limit",String(e))}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData()}disconnectedCallback(){super.disconnectedCallback()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),e==="limit"&&this._loadData(),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}async _loadData(){try{this._loading=!0,this.render();let e={limit:this.limit,action:this._filters.action,resource:this._filters.resource,date_from:this._filters.dateFrom,date_to:this._filters.dateTo},t=Tt(e),i=await this._api._get(`/api/v2/audit${t}`);this._entries=i?.entries||i||[],this._error=null}catch(e){this._error=`Failed to load audit log: ${e.message}`}finally{this._loading=!1}this.render()}async _verifyIntegrity(){try{this._verifying=!0,this._verifyResult=null,this.render();let e=await this._api._get("/api/v2/audit/verify");this._verifyResult=e}catch(e){this._verifyResult={valid:!1,error:e.message}}finally{this._verifying=!1}this.render()}_onFilterChange(e,t){this._filters[e]=t,this._loadData()}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
10735
10781
  :host {
10736
10782
  display: block;
10737
10783
  }
@@ -10945,20 +10991,20 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
10945
10991
  color: var(--loki-text-muted, #939084);
10946
10992
  margin-bottom: 8px;
10947
10993
  }
10948
- `}_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=`
10994
+ `}_getStatusClass(e){if(!e)return"status-warning";let t=e.toLowerCase();return t==="success"||t==="ok"||t==="pass"?"status-success":t==="failure"||t==="error"||t==="fail"?"status-failure":"status-warning"}render(){let e=this.shadowRoot;if(!e)return;let t=this._entries,i="";if(this._verifyResult){let s=this._verifyResult.valid!==!1;i=`
10949
10995
  <div class="verify-result ${s?"verify-valid":"verify-invalid"}">
10950
10996
  ${s?"[VALID] Audit chain integrity verified.":`[TAMPERED] ${this._escapeHtml(this._verifyResult.error||"Integrity check failed.")}`}
10951
10997
  </div>
10952
- `}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=>`
10998
+ `}let a;if(this._loading&&t.length===0)a='<div class="loading">Loading audit log...</div>';else if(t.length===0)a='<div class="empty-state">No audit entries found matching filters.</div>';else{let s=t.map(r=>`
10953
10999
  <tr>
10954
- <td>${Ae(r.timestamp)}</td>
11000
+ <td>${At(r.timestamp)}</td>
10955
11001
  <td>${this._escapeHtml(r.action||"--")}</td>
10956
11002
  <td>${this._escapeHtml(r.resource||r.resource_type||"--")}</td>
10957
11003
  <td>${this._escapeHtml(r.user||r.actor||"--")}</td>
10958
11004
  <td><span class="status-badge ${this._getStatusClass(r.status)}">${this._escapeHtml(r.status||"unknown")}</span></td>
10959
11005
  </tr>
10960
11006
  `).join("");a=`
10961
- <div class="entry-count">${e.length} entries</div>
11007
+ <div class="entry-count">${t.length} entries</div>
10962
11008
  <div class="audit-table-wrapper">
10963
11009
  <table>
10964
11010
  <thead>
@@ -10973,7 +11019,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
10973
11019
  <tbody>${s}</tbody>
10974
11020
  </table>
10975
11021
  </div>
10976
- `}t.innerHTML=`
11022
+ `}e.innerHTML=`
10977
11023
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
10978
11024
  <div class="audit-viewer">
10979
11025
  <div class="header">
@@ -11015,7 +11061,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
11015
11061
  ${a}
11016
11062
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
11017
11063
  </div>
11018
- `,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`
11064
+ `,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("verify-btn");t&&t.addEventListener("click",()=>this._verifyIntegrity());let i=e.getElementById("refresh-btn");i&&i.addEventListener("click",()=>this._loadData());let a=e.getElementById("filter-action");a&&a.addEventListener("change",n=>this._onFilterChange("action",n.target.value));let s=e.getElementById("filter-resource");s&&s.addEventListener("change",n=>this._onFilterChange("resource",n.target.value));let r=e.getElementById("filter-date-from");r&&r.addEventListener("change",n=>this._onFilterChange("dateFrom",n.target.value));let o=e.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",ce);function Qe(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 pe=class extends u{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(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}async _loadData(){try{this._loading=!0,this.render();let e=await this._api._get("/api/v2/api-keys");this._keys=Array.isArray(e)?e:e?.keys||[],this._error=null}catch(e){this._error=`Failed to load API keys: ${e.message}`}finally{this._loading=!1}this.render()}async _createKey(){if(!this._createName.trim()){this._error="Key name is required.",this.render();return}try{let e={name:this._createName.trim(),role:this._createRole};this._createExpiration&&(e.expiration=this._createExpiration);let t=await this._api._post("/api/v2/api-keys",e);this._newToken=t?.token||t?.key||null,this._showCreateForm=!1,this._createName="",this._createRole="read",this._createExpiration="",this._error=null,await this._loadData()}catch(e){this._error=`Create failed: ${e.message}`,this.render()}}async _rotateKey(e){try{let t={grace_period_hours:parseInt(this._rotateGracePeriod,10)||24},i=await this._api._post(`/api/v2/api-keys/${e}/rotate`,t);this._newToken=i?.token||i?.key||null,this._rotateKeyId=null,this._error=null,await this._loadData()}catch(t){this._error=`Rotate failed: ${t.message}`,this.render()}}async _deleteKey(e){try{await this._api._delete(`/api/v2/api-keys/${e}`),this._confirmDeleteId=null,this._error=null,await this._loadData()}catch(t){this._error=`Delete failed: ${t.message}`,this._confirmDeleteId=null,this.render()}}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
11019
11065
  :host {
11020
11066
  display: block;
11021
11067
  }
@@ -11321,7 +11367,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
11321
11367
  color: var(--loki-text-muted, #939084);
11322
11368
  font-size: 13px;
11323
11369
  }
11324
- `}render(){let t=this.shadowRoot;if(!t)return;let e=this._keys,i="";this._newToken&&(i=`
11370
+ `}render(){let e=this.shadowRoot;if(!e)return;let t=this._keys,i="";this._newToken&&(i=`
11325
11371
  <div class="new-token-banner">
11326
11372
  <div class="new-token-label">API Key Created</div>
11327
11373
  <div class="new-token-warning">Copy this token now. It will not be shown again.</div>
@@ -11357,7 +11403,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
11357
11403
  <button class="btn" id="cancel-create">Cancel</button>
11358
11404
  </div>
11359
11405
  </div>
11360
- `);let s;this._loading&&e.length===0?s='<div class="loading">Loading API keys...</div>':e.length===0?s='<div class="empty-state">No API keys configured. Create one to get started.</div>':s=`
11406
+ `);let s;this._loading&&t.length===0?s='<div class="loading">Loading API keys...</div>':t.length===0?s='<div class="empty-state">No API keys configured. Create one to get started.</div>':s=`
11361
11407
  <div class="keys-table-wrapper">
11362
11408
  <table>
11363
11409
  <thead>
@@ -11370,7 +11416,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
11370
11416
  <th>Actions</th>
11371
11417
  </tr>
11372
11418
  </thead>
11373
- <tbody>${e.map(o=>{let n=o.id||o.key_id,l=(o.status||"active").toLowerCase(),c=l==="active"?"key-status-active":l==="expired"?"key-status-expired":"key-status-revoked",p=this._confirmDeleteId===n,u=this._rotateKeyId===n,b;return p?b=`
11419
+ <tbody>${t.map(o=>{let n=o.id||o.key_id,l=(o.status||"active").toLowerCase(),c=l==="active"?"key-status-active":l==="expired"?"key-status-expired":"key-status-revoked",p=this._confirmDeleteId===n,h=this._rotateKeyId===n,b;return p?b=`
11374
11420
  <div class="confirm-delete">
11375
11421
  <span>Delete this key?</span>
11376
11422
  <button class="btn btn-sm btn-danger" data-action="confirm-delete" data-key-id="${n}">Yes</button>
@@ -11381,7 +11427,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
11381
11427
  <button class="btn btn-sm btn-warn" data-action="rotate" data-key-id="${n}">Rotate</button>
11382
11428
  <button class="btn btn-sm btn-danger" data-action="delete" data-key-id="${n}">Delete</button>
11383
11429
  </div>
11384
- ${u?`
11430
+ ${h?`
11385
11431
  <div class="rotate-inline">
11386
11432
  <span class="rotate-label">Grace period:</span>
11387
11433
  <input type="number" class="rotate-input" id="rotate-grace-${n}" value="${this._rotateGracePeriod}" min="0">
@@ -11394,15 +11440,15 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
11394
11440
  <tr>
11395
11441
  <td><span class="key-name">${this._escapeHtml(o.name||"Unnamed")}</span></td>
11396
11442
  <td><span class="key-role">${this._escapeHtml(o.role||o.scopes||"--")}</span></td>
11397
- <td>${Qt(o.created_at||o.created)}</td>
11398
- <td>${Qt(o.last_used_at||o.last_used)}</td>
11443
+ <td>${Qe(o.created_at||o.created)}</td>
11444
+ <td>${Qe(o.last_used_at||o.last_used)}</td>
11399
11445
  <td><span class="${c}">${this._escapeHtml(l)}</span></td>
11400
11446
  <td><div class="actions-cell">${b}</div></td>
11401
11447
  </tr>
11402
11448
  `}).join("")}</tbody>
11403
11449
  </table>
11404
11450
  </div>
11405
- `,t.innerHTML=`
11451
+ `,e.innerHTML=`
11406
11452
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
11407
11453
  <div class="api-keys">
11408
11454
  <div class="header">
@@ -11414,7 +11460,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
11414
11460
  ${s}
11415
11461
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
11416
11462
  </div>
11417
- `,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`
11463
+ `,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("show-create");t&&t.addEventListener("click",()=>{this._showCreateForm=!0,this.render()});let i=e.getElementById("dismiss-token");i&&i.addEventListener("click",()=>{this._newToken=null,this.render()});let a=e.getElementById("submit-create");a&&a.addEventListener("click",()=>{let r=e.getElementById("create-name"),o=e.getElementById("create-role"),n=e.getElementById("create-expiration");this._createName=r?.value||"",this._createRole=o?.value||"read",this._createExpiration=n?.value||"",this._createKey()});let s=e.getElementById("cancel-create");s&&s.addEventListener("click",()=>{this._showCreateForm=!1,this.render()}),e.querySelectorAll('[data-action="delete"]').forEach(r=>{r.addEventListener("click",()=>{this._confirmDeleteId=r.dataset.keyId,this.render()})}),e.querySelectorAll('[data-action="confirm-delete"]').forEach(r=>{r.addEventListener("click",()=>{this._deleteKey(r.dataset.keyId)})}),e.querySelectorAll('[data-action="cancel-delete"]').forEach(r=>{r.addEventListener("click",()=>{this._confirmDeleteId=null,this.render()})}),e.querySelectorAll('[data-action="rotate"]').forEach(r=>{r.addEventListener("click",()=>{this._rotateKeyId=r.dataset.keyId,this.render()})}),e.querySelectorAll('[data-action="confirm-rotate"]').forEach(r=>{r.addEventListener("click",()=>{let o=e.getElementById(`rotate-grace-${r.dataset.keyId}`);this._rotateGracePeriod=o?.value||"24",this._rotateKey(r.dataset.keyId)})}),e.querySelectorAll('[data-action="cancel-rotate"]').forEach(r=>{r.addEventListener("click",()=>{this._rotateKeyId=null,this.render()})})}};customElements.get("loki-api-keys")||customElements.define("loki-api-keys",pe);function It(d){return d?d.slug&&d.name?`${d.name} (${d.slug})`:d.name||d.slug||"Unknown":"Unknown"}var he=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._tenants=[],this._selectedTenantId=null,this._dropdownOpen=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._outsideClickHandler=e=>{this._dropdownOpen&&!this.contains(e.target)&&(this._dropdownOpen=!1,this.render())},document.addEventListener("click",this._outsideClickHandler)}disconnectedCallback(){super.disconnectedCallback(),this._outsideClickHandler&&(document.removeEventListener("click",this._outsideClickHandler),this._outsideClickHandler=null)}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}async _loadData(){try{this._loading=!0;let e=await this._api._get("/api/v2/tenants");this._tenants=Array.isArray(e)?e:e?.tenants||[],this._error=null}catch(e){this._error=`Failed to load tenants: ${e.message}`}finally{this._loading=!1}this.render()}_toggleDropdown(){this._dropdownOpen=!this._dropdownOpen,this.render()}_selectTenant(e,t){this._selectedTenantId=e,this._dropdownOpen=!1,this.render(),this.dispatchEvent(new CustomEvent("tenant-changed",{detail:{tenantId:e,tenantName:t},bubbles:!0,composed:!0}))}_getSelectedTenant(){return this._selectedTenantId==null?null:this._tenants.find(e=>(e.id||e.slug)===this._selectedTenantId)||null}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
11418
11464
  :host {
11419
11465
  display: inline-block;
11420
11466
  position: relative;
@@ -11548,7 +11594,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
11548
11594
  color: var(--loki-text-muted, #939084);
11549
11595
  font-size: 12px;
11550
11596
  }
11551
- `}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=`
11597
+ `}render(){let e=this.shadowRoot;if(!e)return;let t=this._getSelectedTenant(),i=t?It(t):"All Tenants",a=this._dropdownOpen,s="";if(a){let r;if(this._loading)r='<div class="loading-text">Loading tenants...</div>';else if(this._error)r=`<div class="error-text">${this._escapeHtml(this._error)}</div>`;else{let o=this._selectedTenantId==null;r=`
11552
11598
  <button class="dropdown-item all-tenants ${o?"selected":""}" data-tenant-id="">
11553
11599
  <span class="tenant-name">All Tenants</span>
11554
11600
  ${o?'<span class="check-mark">*</span>':""}
@@ -11564,7 +11610,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
11564
11610
  ${c?'<span class="check-mark">*</span>':""}
11565
11611
  </button>
11566
11612
  `}).join("")}
11567
- `}s=`<div class="dropdown">${r}</div>`}t.innerHTML=`
11613
+ `}s=`<div class="dropdown">${r}</div>`}e.innerHTML=`
11568
11614
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
11569
11615
  <div class="tenant-switcher">
11570
11616
  <button class="trigger ${a?"open":""}" id="trigger-btn">
@@ -11573,7 +11619,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
11573
11619
  </button>
11574
11620
  ${s}
11575
11621
  </div>
11576
- `,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`
11622
+ `,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("trigger-btn");t&&t.addEventListener("click",i=>{i.stopPropagation(),this._toggleDropdown()}),e.querySelectorAll(".dropdown-item").forEach(i=>{i.addEventListener("click",a=>{a.stopPropagation();let s=i.dataset.tenantId||null,r=i.dataset.tenantName||null;this._selectTenant(s||null,r||"All Tenants")})})}};customElements.get("loki-tenant-switcher")||customElements.define("loki-tenant-switcher",he);var He={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"}},Lt=100,ue=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._items=[],this._filter="all",this._api=null,this._pollInterval=null,this._paused=!1,this._lastTimestamp=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),3e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let e=await this._api._get("/api/v2/activity"),t=e.events||e.activities||[];if(t.length>0){let i=t.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,Lt),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 e=Date.now();return[{id:"1",timestamp:new Date(e-2e3).toISOString(),message:"Build iteration #12 started",severity:"info",source:"runner"},{id:"2",timestamp:new Date(e-5e3).toISOString(),message:"Code review passed (3/3 reviewers)",severity:"success",source:"review"},{id:"3",timestamp:new Date(e-8e3).toISOString(),message:"Context window at 78% capacity",severity:"warning",source:"context"},{id:"4",timestamp:new Date(e-12e3).toISOString(),message:"Test suite completed: 42/42 passed",severity:"success",source:"testing"},{id:"5",timestamp:new Date(e-15e3).toISOString(),message:"RARV cycle: Verify phase complete",severity:"info",source:"rarv"}]}_formatTime(e){if(!e)return"";try{return new Date(e).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})}catch{return""}}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getFilteredItems(){return this._filter==="all"?this._items:this._items.filter(e=>e.severity===this._filter)}_setFilter(e){this._filter=e,this.render()}_bindEvents(){let e=this.shadowRoot;e.querySelectorAll(".filter-btn").forEach(i=>{i.addEventListener("click",()=>{this._setFilter(i.dataset.filter)})});let t=e.querySelector(".activity-feed");t&&(t.addEventListener("mouseenter",()=>{this._paused=!0}),t.addEventListener("mouseleave",()=>{this._paused=!1}))}_getStyles(){return`
11577
11623
  :host {
11578
11624
  display: block;
11579
11625
  }
@@ -11759,7 +11805,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
11759
11805
  ::-webkit-scrollbar-track { background: var(--loki-bg-primary, #FFFEFB); }
11760
11806
  ::-webkit-scrollbar-thumb { background: var(--loki-border, #ECEAE3); border-radius: 3px; }
11761
11807
  ::-webkit-scrollbar-thumb:hover { background: var(--loki-border-light, #C5C0B1); }
11762
- `}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`
11808
+ `}render(){let e=this.shadowRoot;if(!e)return;let t=this._getFilteredItems(),a=["all","info","success","warning","error"].map(r=>{let o=this._filter===r,n=r==="all"?"All":He[r]?.label||r;return`<button class="filter-btn ${o?"active":""}" data-filter="${r}">${n}</button>`}).join(""),s;if(t.length===0?s='<div class="empty-state">No activity to display</div>':s=t.map(r=>{let o=He[r.severity]||He.info;return`
11763
11809
  <div class="activity-item ${r.isNew?"new-item":""}">
11764
11810
  <div class="severity-band" style="background: ${o.color};"></div>
11765
11811
  <div class="item-content">
@@ -11769,7 +11815,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
11769
11815
  ${r.source?`<span class="item-source">${this._escapeHtml(r.source)}</span>`:""}
11770
11816
  </div>
11771
11817
  </div>
11772
- `}).join(""),t.innerHTML=`
11818
+ `}).join(""),e.innerHTML=`
11773
11819
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
11774
11820
  <div class="stream-container">
11775
11821
  <div class="header">
@@ -11780,7 +11826,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
11780
11826
  ${s}
11781
11827
  </div>
11782
11828
  </div>
11783
- `,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`
11829
+ `,this._bindEvents(),!this._paused){let r=e.querySelector(".activity-feed");r&&(r.scrollTop=0)}}};customElements.get("loki-activity-stream")||customElements.define("loki-activity-stream",ue);var Dt={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)"}},Xe={healthy:"var(--loki-green, #1FC5A8)",degraded:"var(--loki-yellow, #D4A03C)",down:"var(--loki-red, #C45B5B)",unknown:"var(--loki-text-muted, #939084)"},ge=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._providers=[],this._expandedProvider=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_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/providers/health");this._providers=e.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(e){return e==null?"--":e>=1e6?(e/1e6).toFixed(1)+"M":e>=1e3?(e/1e3).toFixed(1)+"K":String(e)}_formatLatency(e){return e==null?"--":e<1e3?e+"ms":(e/1e3).toFixed(1)+"s"}_formatCost(e){return e==null?"--":"$"+e.toFixed(2)}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_toggleExpand(e){this._expandedProvider=this._expandedProvider===e?null:e,this.render()}_bindEvents(){this.shadowRoot.querySelectorAll(".provider-card").forEach(t=>{t.addEventListener("click",()=>{this._toggleExpand(t.dataset.provider)})})}_getStyles(){return`
11784
11830
  :host {
11785
11831
  display: block;
11786
11832
  }
@@ -11959,7 +12005,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
11959
12005
  border: 1px solid var(--loki-border, #ECEAE3);
11960
12006
  border-radius: 5px;
11961
12007
  }
11962
- `}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`
12008
+ `}render(){let e=this.shadowRoot;if(!e)return;let t;this._providers.length===0?t='<div class="empty-state">No provider data available</div>':t=`<div class="provider-grid">${this._providers.map(i=>{let a=Dt[i.name]||{initial:(i.name??"?").charAt(0).toUpperCase(),color:"#939084",bgColor:"rgba(147, 144, 132, 0.12)"},s=Xe[i.status]||Xe.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`
11963
12009
  <div class="provider-card ${r?"expanded":""}" data-provider="${this._escapeHtml(i.name)}">
11964
12010
  <div class="card-header">
11965
12011
  <div class="provider-icon" style="background: ${a.bgColor}; color: ${a.color};">${a.initial}</div>
@@ -12002,16 +12048,16 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
12002
12048
  </div>
12003
12049
  `:""}
12004
12050
  </div>
12005
- `}).join("")}</div>`,t.innerHTML=`
12051
+ `}).join("")}</div>`,e.innerHTML=`
12006
12052
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
12007
12053
  <div class="health-container">
12008
12054
  <div class="header">
12009
12055
  <h3 class="title">Provider Health</h3>
12010
12056
  <span class="refresh-label">Auto-refresh: 10s</span>
12011
12057
  </div>
12012
- ${e}
12058
+ ${t}
12013
12059
  </div>
12014
- `,this._bindEvents()}};customElements.get("loki-provider-health")||customElements.define("loki-provider-health",gt);var Rt=[{id:"planning",label:"Planning",icon:"P"},{id:"scaffolding",label:"Scaffolding",icon:"S"},{id:"implementation",label:"Implementation",icon:"I"},{id:"testing",label:"Testing",icon:"T"},{id:"review",label:"Review",icon:"R"},{id:"deploy",label:"Deploy",icon:"D"}],Bt={waiting:{color:"var(--loki-text-muted, #939084)",bgColor:"var(--loki-bg-tertiary, #ECEAE3)",label:"Waiting"},active:{color:"var(--loki-accent, #553DE9)",bgColor:"var(--loki-accent-muted, rgba(85, 61, 233, 0.10))",label:"Active"},complete:{color:"var(--loki-green, #1FC5A8)",bgColor:"var(--loki-green-muted, rgba(31, 197, 168, 0.12))",label:"Complete"},failed:{color:"var(--loki-red, #C45B5B)",bgColor:"var(--loki-red-muted, rgba(196, 91, 91, 0.12))",label:"Failed"}},mt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._stages=[],this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let t=await this._api._get("/api/v2/pipeline/status");this._stages=t.stages||[]}catch{this._stages.length===0&&(this._stages=this._getDemoData())}this.render()}_getDemoData(){return[{id:"planning",status:"complete",errors:0,duration_ms:12500},{id:"scaffolding",status:"complete",errors:0,duration_ms:8300},{id:"implementation",status:"active",errors:0,duration_ms:45e3},{id:"testing",status:"waiting",errors:0,duration_ms:null},{id:"review",status:"waiting",errors:0,duration_ms:null},{id:"deploy",status:"waiting",errors:0,duration_ms:null}]}_getStageData(t){return this._stages.find(e=>e.id===t)||{id:t,status:"waiting",errors:0}}_formatDuration(t){if(t==null||t<0)return"";if(t<1e3)return t+"ms";let e=Math.floor(t/1e3);if(e<60)return e+"s";let i=Math.floor(e/60),a=e%60;return i+"m "+a+"s"}_getStyles(){return`
12060
+ `,this._bindEvents()}};customElements.get("loki-provider-health")||customElements.define("loki-provider-health",ge);var Re=[{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"}],Be={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"}},me=class extends u{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(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let e=await this._api._get("/api/v2/pipeline/status");this._stages=e.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(e){return this._stages.find(t=>t.id===e)||{id:e,status:"waiting",errors:0}}_formatDuration(e){if(e==null||e<0)return"";if(e<1e3)return e+"ms";let t=Math.floor(e/1e3);if(t<60)return t+"s";let i=Math.floor(t/60),a=t%60;return i+"m "+a+"s"}_getStyles(){return`
12015
12061
  :host {
12016
12062
  display: block;
12017
12063
  }
@@ -12174,7 +12220,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
12174
12220
  border-radius: 50%;
12175
12221
  flex-shrink: 0;
12176
12222
  }
12177
- `}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=`
12223
+ `}render(){let e=this.shadowRoot;if(!e)return;let t=Re.map((a,s)=>{let r=this._getStageData(a.id),o=Be[r.status]||Be.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,h=`
12178
12224
  <div class="stage-node">
12179
12225
  <div class="stage-circle ${l?"active":""}"
12180
12226
  style="background: ${o.bgColor}; color: ${o.color}; border: 2px solid ${o.color};">
@@ -12184,34 +12230,34 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
12184
12230
  ${r.duration_ms?`<span class="stage-duration">${this._formatDuration(r.duration_ms)}</span>`:""}
12185
12231
  ${r.errors>0?`<span class="stage-error-count">${r.errors} error${r.errors>1?"s":""}</span>`:""}
12186
12232
  </div>
12187
- `;if(s<Rt.length-1){let b=this._getStageData(Rt[s+1].id),m=n,f=l||n&&(b.status==="active"||b.status==="waiting");return u+`
12233
+ `;if(s<Re.length-1){let b=this._getStageData(Re[s+1].id),m=n,f=l||n&&(b.status==="active"||b.status==="waiting");return h+`
12188
12234
  <div class="connector">
12189
12235
  <div class="connector-line ${m?"completed":l?"active":"pending"}"></div>
12190
12236
  ${l?'<div class="flow-dot"></div>':""}
12191
12237
  </div>
12192
- `}return u}).join(""),i=Object.entries(Bt).map(([a,s])=>`<div class="legend-item">
12238
+ `}return h}).join(""),i=Object.entries(Be).map(([a,s])=>`<div class="legend-item">
12193
12239
  <div class="legend-dot" style="background: ${s.color};"></div>
12194
12240
  <span>${s.label}</span>
12195
- </div>`).join("");t.innerHTML=`
12241
+ </div>`).join("");e.innerHTML=`
12196
12242
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
12197
12243
  <div class="pipeline-container">
12198
12244
  <div class="header">
12199
12245
  <h3 class="title">Build Pipeline</h3>
12200
12246
  </div>
12201
12247
  <div class="pipeline-track">
12202
- ${e}
12248
+ ${t}
12203
12249
  </div>
12204
12250
  <div class="status-legend">
12205
12251
  ${i}
12206
12252
  </div>
12207
12253
  </div>
12208
- `}};customElements.get("loki-pipeline-view")||customElements.define("loki-pipeline-view",mt);var vt={episode:{color:"var(--loki-blue, #2F71E3)",shape:"circle",label:"Episode"},pattern:{color:"var(--loki-green, #1FC5A8)",shape:"square",label:"Pattern"},skill:{color:"var(--loki-purple, #553DE9)",shape:"diamond",label:"Skill"}};function ze(d,t,e){let i=t/2,a=e/2,s=Math.min(i,a)*.65,r=d.length;return d.map((o,n)=>{let l=2*Math.PI*n/r-Math.PI/2,c=o.importance||.5,p=s*(.5+c*.5);return{...o,x:i+p*Math.cos(l),y:a+p*Math.sin(l)}})}var bt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._nodes=[],this._edges=[],this._selectedNode=null,this._api=null,this._pollInterval=null,this._graphWidth=600,this._graphHeight=400}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),15e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let t=await this._api._get("/api/v2/memory/graph");this._nodes=t.nodes||[],this._edges=t.edges||[]}catch{if(this._nodes.length===0){let t=this._getDemoData();this._nodes=t.nodes,this._edges=t.edges}}this.render()}_getDemoData(){return{nodes:[{id:"ep1",type:"episode",label:"Build iteration #12",importance:.8,details:"Completed scaffolding and initial implementation"},{id:"ep2",type:"episode",label:"Code review #5",importance:.6,details:"Quality gate passed with 3/3 approval"},{id:"ep3",type:"episode",label:"Test failure #3",importance:.7,details:"Integration test timeout resolved"},{id:"pt1",type:"pattern",label:"Error recovery",importance:.9,details:"Retry with exponential backoff pattern"},{id:"pt2",type:"pattern",label:"API design",importance:.7,details:"REST endpoint naming conventions"},{id:"pt3",type:"pattern",label:"Test structure",importance:.5,details:"Arrange-Act-Assert with setup helpers"},{id:"sk1",type:"skill",label:"Playwright E2E",importance:.85,details:"Browser automation test writing"},{id:"sk2",type:"skill",label:"FastAPI routing",importance:.6,details:"Python API server development"}],edges:[{source:"ep1",target:"pt1",strength:.8},{source:"ep1",target:"sk1",strength:.6},{source:"ep2",target:"pt2",strength:.9},{source:"ep3",target:"pt1",strength:.7},{source:"ep3",target:"pt3",strength:.5},{source:"pt1",target:"sk2",strength:.4},{source:"pt2",target:"sk2",strength:.7},{source:"pt3",target:"sk1",strength:.6}]}}_escapeHtml(t){return t?String(t).replace(/&/g,"&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=vt[t.type]||vt.episode,s=10+(t.importance||.5)*16,r=this._selectedNode===t.id,o=r?"var(--loki-accent, #553DE9)":a.color,n=r?3:1.5,l=this._selectedNode&&!r?.4:1,c;switch(a.shape){case"square":c=`<rect x="${e-s/2}" y="${i-s/2}" width="${s}" height="${s}"
12209
- rx="3" fill="${a.color}" fill-opacity="0.2" stroke="${o}" stroke-width="${n}" opacity="${l}" />`;break;case"diamond":{let u=s/2;c=`<polygon points="${e},${i-u} ${e+u},${i} ${e},${i+u} ${e-u},${i}"
12210
- fill="${a.color}" fill-opacity="0.2" stroke="${o}" stroke-width="${n}" opacity="${l}" />`;break}default:c=`<circle cx="${e}" cy="${i}" r="${s/2}" fill="${a.color}" fill-opacity="0.2"
12211
- stroke="${o}" stroke-width="${n}" opacity="${l}" />`}let p=`<text x="${e}" y="${i+s/2+14}" text-anchor="middle" font-size="10"
12212
- 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;">
12254
+ `}};customElements.get("loki-pipeline-view")||customElements.define("loki-pipeline-view",me);var ve={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 zt(d,e,t){let i=e/2,a=t/2,s=Math.min(i,a)*.65,r=d.length;return d.map((o,n)=>{let l=2*Math.PI*n/r-Math.PI/2,c=o.importance||.5,p=s*(.5+c*.5);return{...o,x:i+p*Math.cos(l),y:a+p*Math.sin(l)}})}var be=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._nodes=[],this._edges=[],this._selectedNode=null,this._api=null,this._pollInterval=null,this._graphWidth=600,this._graphHeight=400}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),15e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let e=await this._api._get("/api/v2/memory/graph");this._nodes=e.nodes||[],this._edges=e.edges||[]}catch{if(this._nodes.length===0){let e=this._getDemoData();this._nodes=e.nodes,this._edges=e.edges}}this.render()}_getDemoData(){return{nodes:[{id:"ep1",type:"episode",label:"Build iteration #12",importance:.8,details:"Completed scaffolding and initial implementation"},{id:"ep2",type:"episode",label:"Code review #5",importance:.6,details:"Quality gate passed with 3/3 approval"},{id:"ep3",type:"episode",label:"Test failure #3",importance:.7,details:"Integration test timeout resolved"},{id:"pt1",type:"pattern",label:"Error recovery",importance:.9,details:"Retry with exponential backoff pattern"},{id:"pt2",type:"pattern",label:"API design",importance:.7,details:"REST endpoint naming conventions"},{id:"pt3",type:"pattern",label:"Test structure",importance:.5,details:"Arrange-Act-Assert with setup helpers"},{id:"sk1",type:"skill",label:"Playwright E2E",importance:.85,details:"Browser automation test writing"},{id:"sk2",type:"skill",label:"FastAPI routing",importance:.6,details:"Python API server development"}],edges:[{source:"ep1",target:"pt1",strength:.8},{source:"ep1",target:"sk1",strength:.6},{source:"ep2",target:"pt2",strength:.9},{source:"ep3",target:"pt1",strength:.7},{source:"ep3",target:"pt3",strength:.5},{source:"pt1",target:"sk2",strength:.4},{source:"pt2",target:"sk2",strength:.7},{source:"pt3",target:"sk1",strength:.6}]}}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_selectNode(e){this._selectedNode=this._selectedNode===e?null:e,this.render()}_bindEvents(){let e=this.shadowRoot;e.querySelectorAll(".graph-node").forEach(t=>{t.addEventListener("click",()=>{this._selectNode(t.dataset.nodeId)})}),e.querySelectorAll(".close-detail").forEach(t=>{t.addEventListener("click",()=>{this._selectedNode=null,this.render()})})}_renderNodeShape(e,t,i){let a=ve[e.type]||ve.episode,s=10+(e.importance||.5)*16,r=this._selectedNode===e.id,o=r?"var(--loki-accent, #553DE9)":a.color,n=r?3:1.5,l=this._selectedNode&&!r?.4:1,c;switch(a.shape){case"square":c=`<rect x="${t-s/2}" y="${i-s/2}" width="${s}" height="${s}"
12255
+ rx="3" fill="${a.color}" fill-opacity="0.2" stroke="${o}" stroke-width="${n}" opacity="${l}" />`;break;case"diamond":{let h=s/2;c=`<polygon points="${t},${i-h} ${t+h},${i} ${t},${i+h} ${t-h},${i}"
12256
+ fill="${a.color}" fill-opacity="0.2" stroke="${o}" stroke-width="${n}" opacity="${l}" />`;break}default:c=`<circle cx="${t}" cy="${i}" r="${s/2}" fill="${a.color}" fill-opacity="0.2"
12257
+ stroke="${o}" stroke-width="${n}" opacity="${l}" />`}let p=`<text x="${t}" y="${i+s/2+14}" text-anchor="middle" font-size="10"
12258
+ font-family="Inter, sans-serif" fill="var(--loki-text-secondary, #36342E)" opacity="${l}">${this._escapeHtml(e.label)}</text>`;return`<g class="graph-node" data-node-id="${this._escapeHtml(e.id)}" style="cursor: pointer;">
12213
12259
  ${c}${p}
12214
- </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}"
12260
+ </g>`}_renderEdge(e,t){let i=t.find(n=>n.id===e.source),a=t.find(n=>n.id===e.target);if(!i||!a)return"";let s=(e.strength||1)<.6,r=this._selectedNode?e.source===this._selectedNode||e.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}"
12215
12261
  stroke="var(--loki-border-light, #C5C0B1)" stroke-width="1.5" opacity="${r}" ${o} />`}_getStyles(){return`
12216
12262
  :host {
12217
12263
  display: block;
@@ -12358,7 +12404,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
12358
12404
  color: var(--loki-text-muted, #939084);
12359
12405
  font-size: 13px;
12360
12406
  }
12361
- `}render(){let t=this.shadowRoot;if(!t)return;if(this._nodes.length===0){t.innerHTML=`
12407
+ `}render(){let e=this.shadowRoot;if(!e)return;if(this._nodes.length===0){e.innerHTML=`
12362
12408
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
12363
12409
  <div class="graph-container">
12364
12410
  <div class="header">
@@ -12366,7 +12412,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
12366
12412
  </div>
12367
12413
  <div class="empty-state">No memory entries to visualize</div>
12368
12414
  </div>
12369
- `;return}let e=this._graphWidth,i=this._graphHeight,a=ze(this._nodes,e,i),s=this._edges.map(l=>this._renderEdge(l,a)).join(""),r=a.map(l=>this._renderNodeShape(l,l.x,l.y)).join(""),o="";if(this._selectedNode){let l=this._nodes.find(c=>c.id===this._selectedNode);if(l){let c=vt[l.type]||vt.episode;o=`
12415
+ `;return}let t=this._graphWidth,i=this._graphHeight,a=zt(this._nodes,t,i),s=this._edges.map(l=>this._renderEdge(l,a)).join(""),r=a.map(l=>this._renderNodeShape(l,l.x,l.y)).join(""),o="";if(this._selectedNode){let l=this._nodes.find(c=>c.id===this._selectedNode);if(l){let c=ve[l.type]||ve.episode;o=`
12370
12416
  <div class="detail-panel">
12371
12417
  <div class="detail-header">
12372
12418
  <span class="detail-title">${this._escapeHtml(l.label)}</span>
@@ -12375,17 +12421,17 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
12375
12421
  </div>
12376
12422
  <div class="detail-body">${this._escapeHtml(l.details||"No details available")}</div>
12377
12423
  </div>
12378
- `}}let n=Object.entries(vt).map(([,l])=>{let c;return l.shape==="circle"?c=`<div class="legend-circle" style="border-color: ${l.color};"></div>`:l.shape==="square"?c=`<div class="legend-square" style="border-color: ${l.color};"></div>`:c=`<div class="legend-diamond" style="border-color: ${l.color};"></div>`,`<div class="legend-item">
12424
+ `}}let n=Object.entries(ve).map(([,l])=>{let c;return l.shape==="circle"?c=`<div class="legend-circle" style="border-color: ${l.color};"></div>`:l.shape==="square"?c=`<div class="legend-square" style="border-color: ${l.color};"></div>`:c=`<div class="legend-diamond" style="border-color: ${l.color};"></div>`,`<div class="legend-item">
12379
12425
  <div class="legend-shape">${c}</div>
12380
12426
  <span>${l.label}</span>
12381
- </div>`}).join("");t.innerHTML=`
12427
+ </div>`}).join("");e.innerHTML=`
12382
12428
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
12383
12429
  <div class="graph-container">
12384
12430
  <div class="header">
12385
12431
  <h3 class="title">Memory Network</h3>
12386
12432
  </div>
12387
12433
  <div class="graph-wrap">
12388
- <svg class="graph-svg" viewBox="0 0 ${e} ${i}" xmlns="http://www.w3.org/2000/svg">
12434
+ <svg class="graph-svg" viewBox="0 0 ${t} ${i}" xmlns="http://www.w3.org/2000/svg">
12389
12435
  ${s}
12390
12436
  ${r}
12391
12437
  </svg>
@@ -12393,7 +12439,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
12393
12439
  </div>
12394
12440
  <div class="legend">${n}</div>
12395
12441
  </div>
12396
- `,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`
12442
+ `,this._bindEvents()}};customElements.get("loki-memory-graph")||customElements.define("loki-memory-graph",be);var Pe={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"}},fe=class extends u{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(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_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/cost/breakdown");this._phases=e.phases||[],this._budget=e.budget_usd||null,this._totalCost=e.total_usd||this._phases.reduce((t,i)=>t+(i.cost_usd||0),0)}catch{this._phases.length===0&&(this._phases=this._getDemoData(),this._budget=10,this._totalCost=this._phases.reduce((e,t)=>e+t.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(e){return e==null?"--":"$"+e.toFixed(2)}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_bindEvents(){this.shadowRoot.querySelectorAll(".waterfall-bar").forEach(t=>{t.addEventListener("mouseenter",()=>{this._hoveredPhase=t.dataset.phase,this._updateTooltip(t)}),t.addEventListener("mouseleave",()=>{this._hoveredPhase=null,this._hideTooltip()})})}_updateTooltip(e){let t=this.shadowRoot.querySelector(".tooltip");if(!t)return;let i=this._phases.find(o=>o.phase===this._hoveredPhase);if(!i)return;let a=Pe[i.phase]||{label:i.phase};t.innerHTML=`<strong>${a.label}</strong>: ${this._formatCost(i.cost_usd)}`,t.style.display="block";let s=e.getBoundingClientRect(),r=this.shadowRoot.querySelector(".chart-area").getBoundingClientRect();t.style.left=s.left-r.left+s.width/2+"px",t.style.top=s.top-r.top-30+"px"}_hideTooltip(){let e=this.shadowRoot.querySelector(".tooltip");e&&(e.style.display="none")}_getStyles(){return`
12397
12443
  :host {
12398
12444
  display: block;
12399
12445
  }
@@ -12575,7 +12621,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
12575
12621
  color: var(--loki-text-muted, #939084);
12576
12622
  font-size: 13px;
12577
12623
  }
12578
- `}render(){let t=this.shadowRoot;if(!t)return;if(this._phases.length===0){t.innerHTML=`
12624
+ `}render(){let e=this.shadowRoot;if(!e)return;if(this._phases.length===0){e.innerHTML=`
12579
12625
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
12580
12626
  <div class="waterfall-container">
12581
12627
  <div class="header">
@@ -12583,11 +12629,11 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
12583
12629
  </div>
12584
12630
  <div class="empty-state">No cost data available</div>
12585
12631
  </div>
12586
- `;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`
12632
+ `;return}let t=Math.max(...this._phases.map(l=>l.cost_usd||0),.01),i=160,a=this._budget?Math.max(t,this._budget):t,s=this._budget?this._budget/a*i:null,r=this._phases.map(l=>{let c=Pe[l.phase]||{color:"var(--loki-text-muted)",label:l.phase},p=(l.cost_usd||0)/a*i,h=this._hoveredPhase===l.phase;return`
12587
12633
  <div class="bar-group">
12588
12634
  <span class="bar-value">${this._formatCost(l.cost_usd)}</span>
12589
12635
  <div class="waterfall-bar" data-phase="${this._escapeHtml(l.phase)}"
12590
- style="height: ${Math.max(p,4)}px; background: ${c.color}; ${u?"opacity: 0.85;":""}">
12636
+ style="height: ${Math.max(p,4)}px; background: ${c.color}; ${h?"opacity: 0.85;":""}">
12591
12637
  </div>
12592
12638
  <span class="bar-label">${c.label}</span>
12593
12639
  </div>
@@ -12595,11 +12641,11 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
12595
12641
  <div class="budget-line" style="bottom: ${s+40}px;">
12596
12642
  <span class="budget-label">Budget: ${this._formatCost(this._budget)}</span>
12597
12643
  </div>
12598
- `:"",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">
12644
+ `:"",n=this._phases.map(l=>{let c=Pe[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">
12599
12645
  <div class="summary-dot" style="background: ${c.color};"></div>
12600
12646
  <span class="summary-label">${c.label}</span>
12601
12647
  <span class="summary-value">${this._formatCost(l.cost_usd)} (${p}%)</span>
12602
- </div>`}).join("");t.innerHTML=`
12648
+ </div>`}).join("");e.innerHTML=`
12603
12649
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
12604
12650
  <div class="waterfall-container">
12605
12651
  <div class="header">
@@ -12617,7 +12663,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
12617
12663
  </div>
12618
12664
  </div>
12619
12665
  </div>
12620
- `,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`
12666
+ `,this._bindEvents()}};customElements.get("loki-cost-waterfall")||customElements.define("loki-cost-waterfall",fe);var Ht={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"}},ke=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._agents=[],this._expandedAgent=null,this._api=null,this._pollInterval=null,this._previousRanks={}}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_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/agents/leaderboard")).agents||[],i={};t.forEach((a,s)=>{i[a.type||a.name]=s+1}),this._previousRanks={...this._currentRanks||{}},this._currentRanks=i,this._agents=t}catch{this._agents.length===0&&(this._agents=this._getDemoData(),this._currentRanks={},this._agents.forEach((e,t)=>{this._currentRanks[e.type]=t+1}),this._previousRanks={})}this.render()}_getDemoData(){return[{type:"code-generator",name:"Code Generator",tasks:24,quality:9.2,speed:"fast",cost_usd:2.4},{type:"test-writer",name:"Test Writer",tasks:18,quality:9,speed:"fast",cost_usd:1.2},{type:"code-reviewer",name:"Code Reviewer",tasks:15,quality:8.8,speed:"medium",cost_usd:1.8},{type:"architect",name:"Architect",tasks:8,quality:9.5,speed:"slow",cost_usd:3.1},{type:"debugger",name:"Debugger",tasks:12,quality:8.5,speed:"fast",cost_usd:.95},{type:"doc-writer",name:"Documentation",tasks:10,quality:8.3,speed:"fast",cost_usd:.6}]}_getRankChange(e){let t=this._currentRanks?.[e],i=this._previousRanks?.[e];return t==null||i==null?0:i-t}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_toggleAgent(e){this._expandedAgent=this._expandedAgent===e?null:e,this.render()}_bindEvents(){this.shadowRoot.querySelectorAll(".agent-row").forEach(t=>{t.addEventListener("click",()=>{this._toggleAgent(t.dataset.agent)})})}_getQualityColor(e){return e>=9?"var(--loki-green, #1FC5A8)":e>=8?"var(--loki-blue, #2F71E3)":e>=7?"var(--loki-yellow, #D4A03C)":"var(--loki-red, #C45B5B)"}_getSpeedLabel(e){return e==="fast"?{label:"Fast",color:"var(--loki-green, #1FC5A8)"}:e==="medium"?{label:"Medium",color:"var(--loki-yellow, #D4A03C)"}:{label:"Slow",color:"var(--loki-red, #C45B5B)"}}_getStyles(){return`
12621
12667
  :host {
12622
12668
  display: block;
12623
12669
  }
@@ -12822,7 +12868,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
12822
12868
  color: var(--loki-text-muted, #939084);
12823
12869
  font-size: 13px;
12824
12870
  }
12825
- `}render(){let t=this.shadowRoot;if(!t)return;if(this._agents.length===0){t.innerHTML=`
12871
+ `}render(){let e=this.shadowRoot;if(!e)return;if(this._agents.length===0){e.innerHTML=`
12826
12872
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
12827
12873
  <div class="leaderboard-container">
12828
12874
  <div class="header">
@@ -12830,7 +12876,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
12830
12876
  </div>
12831
12877
  <div class="empty-state">No agent performance data available</div>
12832
12878
  </div>
12833
- `;return}let e=this._agents.map((i,a)=>{let s=a+1,r=He[s],o=i.type||i.name,n=this._getRankChange(o),l=this._expandedAgent===o,c=this._getQualityColor(i.quality),p=this._getSpeedLabel(i.speed),u=(i.quality||0)/10*100,b;r?b=`<div class="rank-badge" style="background: ${r.bg}; color: ${r.border};">${s}</div>`:b=`<span class="rank-number" style="color: var(--loki-text-muted);">${s}</span>`;let 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?`
12879
+ `;return}let t=this._agents.map((i,a)=>{let s=a+1,r=Ht[s],o=i.type||i.name,n=this._getRankChange(o),l=this._expandedAgent===o,c=this._getQualityColor(i.quality),p=this._getSpeedLabel(i.speed),h=(i.quality||0)/10*100,b;r?b=`<div class="rank-badge" style="background: ${r.bg}; color: ${r.border};">${s}</div>`:b=`<span class="rank-number" style="color: var(--loki-text-muted);">${s}</span>`;let m="";n>0?m=`<span class="rank-change rank-up">+${n}</span>`:n<0&&(m=`<span class="rank-change rank-down">${n}</span>`);let f=l?`
12834
12880
  <div class="agent-detail">
12835
12881
  <div class="detail-metric">
12836
12882
  <span class="detail-label">Total Cost</span>
@@ -12857,7 +12903,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
12857
12903
  <div class="metric-cell">
12858
12904
  <div class="quality-score">
12859
12905
  <span style="color: ${c};">${(i.quality||0).toFixed(1)}</span>
12860
- <div class="quality-bar"><div class="quality-fill" style="width: ${u}%; background: ${c};"></div></div>
12906
+ <div class="quality-bar"><div class="quality-fill" style="width: ${h}%; background: ${c};"></div></div>
12861
12907
  </div>
12862
12908
  </div>
12863
12909
  <div class="metric-cell">
@@ -12865,7 +12911,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
12865
12911
  </div>
12866
12912
  </div>
12867
12913
  ${f}
12868
- `}).join("");t.innerHTML=`
12914
+ `}).join("");e.innerHTML=`
12869
12915
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
12870
12916
  <div class="leaderboard-container">
12871
12917
  <div class="header">
@@ -12880,23 +12926,23 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
12880
12926
  <span>Quality</span>
12881
12927
  <span>Speed</span>
12882
12928
  </div>
12883
- ${e}
12929
+ ${t}
12884
12930
  </div>
12885
12931
  </div>
12886
- `,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`
12932
+ `,this._bindEvents()}};customElements.get("loki-agent-leaderboard")||customElements.define("loki-agent-leaderboard",ke);var Ze=50,xe=class extends u{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(e,t,i){if(t!==i)switch(e){case"api-url":this._api&&(this._api.baseUrl=i,this._loadStatus());break;case"theme":this._applyTheme(),this.render();break}}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_stopPolling(){}async _loadStatus(){this._statusLoading=!0,this._statusError=null,this.render();try{this._status=await this._api.get("/api/managed/status")}catch(e){this._statusError=e&&e.message?e.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(e=Ze){this._eventsLoading=!0,this._eventsError=null,this.render();try{let t=await this._api.get("/api/managed/events?limit="+encodeURIComponent(e));Array.isArray(t)?(this._events=t,this._eventsCount=t.length,this._eventsSource=null):t&&typeof t=="object"?(this._events=Array.isArray(t.events)?t.events:[],this._eventsCount=typeof t.count=="number"?t.count:this._events.length,this._eventsSource=t.source||null):(this._events=[],this._eventsCount=0,this._eventsSource=null)}catch(t){this._eventsError=t&&t.message?t.message:"Failed to load managed events",this._events=[],this._eventsCount=0,this._eventsSource=null}finally{this._eventsLoading=!1,this.render()}}async _lookupMemoryVersion(){let e=(this._lookupId||"").trim();if(!e){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 t="/api/managed/memory_versions/"+encodeURIComponent(e);this._lookupResult=await this._api.get(t)}catch(t){this._lookupError=t&&t.message?t.message:"Failed to load memory versions",this._lookupResult=null}finally{this._lookupLoading=!1,this.render()}}_onLookupInput(e){this._lookupId=e&&e.target?e.target.value:""}_onLookupKeyDown(e){e&&e.key==="Enter"&&(e.preventDefault(),this._lookupMemoryVersion())}_attachEventHandlers(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector("#refresh-status-btn");t&&t.addEventListener("click",()=>this._loadStatus());let i=e.querySelector("#refresh-events-btn");i&&i.addEventListener("click",()=>this._loadEvents());let a=e.querySelector("#lookup-input");a&&(a.addEventListener("input",r=>this._onLookupInput(r)),a.addEventListener("keydown",r=>this._onLookupKeyDown(r)));let s=e.querySelector("#lookup-btn");s&&s.addEventListener("click",()=>this._lookupMemoryVersion())}_escapeHtml(e){return e==null?"":String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}_formatTimestamp(e){if(!e)return"";let t;return typeof e=="number"?t=new Date(e>1e12?e:e*1e3):t=new Date(e),Number.isNaN(t.getTime())?String(e):t.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`
12887
12933
  <div class="error-banner" role="alert">
12888
12934
  <strong>Status error:</strong>
12889
12935
  <span>${this._escapeHtml(this._statusError)}</span>
12890
12936
  </div>
12891
- `;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`
12937
+ `;if(!this._status)return'<div class="status-row muted">No managed memory status available.</div>';let e=!!this._status.enabled,t=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`
12892
12938
  <div class="status-grid">
12893
12939
  <div class="status-cell">
12894
12940
  <div class="status-label">Enabled</div>
12895
- <div class="status-value ${t?"on":"off"}">${t?"true":"false"}</div>
12941
+ <div class="status-value ${e?"on":"off"}">${e?"true":"false"}</div>
12896
12942
  </div>
12897
12943
  <div class="status-cell">
12898
12944
  <div class="status-label">Parent flag</div>
12899
- <div class="status-value">${this._escapeHtml(e===void 0?"-":e)}</div>
12945
+ <div class="status-value">${this._escapeHtml(t===void 0?"-":t)}</div>
12900
12946
  </div>
12901
12947
  <div class="status-cell">
12902
12948
  <div class="status-label">Child flags</div>
@@ -12925,17 +12971,17 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
12925
12971
  <strong>Events error:</strong>
12926
12972
  <span>${this._escapeHtml(this._eventsError)}</span>
12927
12973
  </div>
12928
- `;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`
12974
+ `;if(!this._events.length)return'<div class="events-empty muted">No managed memory events recorded yet.</div>';let e=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`
12929
12975
  <tr>
12930
12976
  <td class="mono nowrap">${this._escapeHtml(a)}</td>
12931
12977
  <td><span class="badge">${this._escapeHtml(s)}</span></td>
12932
12978
  <td class="mono">${this._escapeHtml(r)}</td>
12933
12979
  <td>${this._escapeHtml(n)}</td>
12934
12980
  </tr>
12935
- `}).join(""),e=this._eventsSource?`<span class="source-tag">source: ${this._escapeHtml(this._eventsSource)}</span>`:"";return`
12981
+ `}).join(""),t=this._eventsSource?`<span class="source-tag">source: ${this._escapeHtml(this._eventsSource)}</span>`:"";return`
12936
12982
  <div class="events-meta">
12937
12983
  <span class="muted">${this._eventsCount} event(s)</span>
12938
- ${e}
12984
+ ${t}
12939
12985
  </div>
12940
12986
  <div class="events-table-wrap">
12941
12987
  <table class="events-table">
@@ -12947,15 +12993,15 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
12947
12993
  <th>Summary</th>
12948
12994
  </tr>
12949
12995
  </thead>
12950
- <tbody>${t}</tbody>
12996
+ <tbody>${e}</tbody>
12951
12997
  </table>
12952
12998
  </div>
12953
- `}_renderLookupSection(){let t="";if(this._lookupLoading)t='<div class="lookup-result muted">Loading memory versions...</div>';else if(this._lookupError)t=`
12999
+ `}_renderLookupSection(){let e="";if(this._lookupLoading)e='<div class="lookup-result muted">Loading memory versions...</div>';else if(this._lookupError)e=`
12954
13000
  <div class="error-banner" role="alert">
12955
13001
  <strong>Lookup error:</strong>
12956
13002
  <span>${this._escapeHtml(this._lookupError)}</span>
12957
13003
  </div>
12958
- `;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`
13004
+ `;else if(this._lookupResult!==null&&this._lookupResult!==void 0){let i;try{i=JSON.stringify(this._lookupResult,null,2)}catch{i=String(this._lookupResult)}e=`<pre class="lookup-result mono">${this._escapeHtml(i)}</pre>`}return`
12959
13005
  <div class="lookup-controls">
12960
13006
  <input
12961
13007
  id="lookup-input"
@@ -12970,8 +13016,8 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
12970
13016
  Look up versions
12971
13017
  </button>
12972
13018
  </div>
12973
- ${t}
12974
- `}render(){if(!this.shadowRoot)return;let e=!!(this._status&&this._status.enabled)&&!this._statusError;this.shadowRoot.innerHTML=`
13019
+ ${e}
13020
+ `}render(){if(!this.shadowRoot)return;let t=!!(this._status&&this._status.enabled)&&!this._statusError;this.shadowRoot.innerHTML=`
12975
13021
  <style>
12976
13022
  ${this.getBaseStyles()}
12977
13023
 
@@ -13259,10 +13305,10 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
13259
13305
  ${this._renderStatusSection()}
13260
13306
  </div>
13261
13307
 
13262
- ${e?`
13308
+ ${t?`
13263
13309
  <div class="section">
13264
13310
  <div class="panel-header">
13265
- <h3 class="section-title">Recent events (limit ${Zt})</h3>
13311
+ <h3 class="section-title">Recent events (limit ${Ze})</h3>
13266
13312
  <button id="refresh-events-btn" class="btn" type="button">Refresh events</button>
13267
13313
  </div>
13268
13314
  ${this._renderEventsSection()}
@@ -13274,7 +13320,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
13274
13320
  </div>
13275
13321
  `:this._statusError?"":this._renderDisabledNotice()}
13276
13322
  </div>
13277
- `,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=`
13323
+ `,this._attachEventHandlers()}};customElements.get("loki-managed-memory-panel")||customElements.define("loki-managed-memory-panel",xe);var _e=class extends u{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(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadList()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||(typeof window<"u"?window.location.origin:"");this._api=g({baseUrl:e})}async _loadList(){this._loading=!0,this._error=null;try{let e=await this._api.get("/api/escalations");this._items=Array.isArray(e&&e.escalations)?e.escalations:[]}catch(e){this._error=e&&e.message?e.message:String(e),this._items=[]}finally{this._loading=!1,this.render()}}async _openFile(e){this._activeFile=e,this._activeBody=null,this._activeBodyError=null,this.render();try{let t=(this._api.baseUrl||"")+"/api/escalations/"+encodeURIComponent(e),i=await fetch(t,{credentials:"include"});if(!i.ok)throw new Error("HTTP "+i.status);this._activeBody=await i.text()}catch(t){this._activeBodyError=t&&t.message?t.message:String(t)}this.render()}_closeFile(){this._activeFile=null,this._activeBody=null,this._activeBodyError=null,this.render()}_formatSize(e){return typeof e!="number"?"--":e<1024?e+" B":e<1024*1024?(e/1024).toFixed(1)+" KB":(e/(1024*1024)).toFixed(1)+" MB"}_formatDate(e){if(!e)return"--";try{let t=new Date(e);return isNaN(t.getTime())?e:t.toLocaleString()}catch{return e}}_escapeHtml(e){return e==null?"":String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}render(){let e=this.shadowRoot||this;if(!e)return;let t=`
13278
13324
  <style>
13279
13325
  :host { display: block; }
13280
13326
  .esc-wrapper {
@@ -13344,7 +13390,7 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
13344
13390
  border-radius: 4px;
13345
13391
  }
13346
13392
  </style>
13347
- `,i="";this._loading&&this._items.length===0?i='<div class="esc-empty">Loading escalations...</div>':this._error?i='<div class="esc-error">Failed to load escalations: '+this._escapeHtml(this._error)+"</div>":!this._items||this._items.length===0?i='<div class="esc-empty">Escalations: no events yet. Handoff/escalation markdown documents written by the runner under .loki/escalations/ will appear here.</div>':i='<div class="esc-list">'+this._items.map(n=>{let l=this._escapeHtml(n.filename||""),c=this._escapeHtml(this._formatSize(n.size_bytes)),p=this._escapeHtml(this._formatDate(n.modified_at));return'<div class="esc-item" data-filename="'+l+'"><span class="esc-name">'+l+'</span><span class="esc-meta">'+c+" &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(m=>"<li>"+this._escapeHtml(String(m))+"</li>").join("")+"</ul>");let u="";return Array.isArray(t.issues)&&t.issues.length>0&&(u='<ul class="ct-issues">'+t.issues.map(m=>{let f=this._escapeHtml(m.severity||""),x=this._escapeHtml(m.description||"");return'<li><span class="ct-issue-sev ct-issue-sev-'+f.toLowerCase()+'">'+f+"</span> "+x+"</li>"}).join("")+"</ul>"),'<div class="'+s+'"><div class="ct-voter-header"><span class="ct-voter-name">'+r+"</span>"+o+l+"</div>"+(n?'<div class="ct-voter-reason">'+n+"</div>":"")+p+u+c+"</div>"}_transcriptCardHtml(t){let e=this._escapeHtml(String(t.iteration||"--")),i=this._escapeHtml(this._formatTimestamp(t.timestamp)),a=this._escapeHtml(this._truncate(t.task_or_prd,200)),s=this._outcomeBadgeHtml(t.outcome),r=Array.isArray(t.voters)?t.voters:[],o=r.filter(m=>!m.is_contrarian),n=r.filter(m=>m.is_contrarian),l=o.map(m=>this._voterRowHtml(m,!1)).join(""),c="";t.contrarian_triggered&&(c='<div class="ct-contrarian-section"><div class="ct-section-label">Anti-Sycophancy Check</div>'+n.map(f=>this._voterRowHtml(f,t.contrarian_flipped)).join("")+"</div>");let p=typeof t.approve_count=="number"?t.approve_count:"--",u=typeof t.reject_count=="number"?t.reject_count:"--",b=typeof t.threshold=="number"?t.threshold:"--";return'<div class="ct-card"><div class="ct-card-header"><div class="ct-card-meta"><span class="ct-iter-label">Iteration '+e+'</span><span class="ct-ts">'+i+"</span></div>"+s+"</div>"+(a?'<div class="ct-prd-preview">'+a+"</div>":"")+'<div class="ct-tally">Approve: '+p+" &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=`
13393
+ `,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>"}e.innerHTML=t+'<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>",e.querySelectorAll(".esc-item").forEach(o=>{o.addEventListener("click",()=>{let n=o.getAttribute("data-filename");n&&this._openFile(n)})});let r=e.querySelector('.esc-close-btn[data-action="close"]');r&&r.addEventListener("click",()=>this._closeFile())}};typeof customElements<"u"&&!customElements.get("loki-escalations")&&customElements.define("loki-escalations",_e);var ye=class extends u{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(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._load()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||(typeof window<"u"?window.location.origin:"");this._api=g({baseUrl:e})}async _load(){this._loading=!0,this._error=null;try{let e=await this._api.get("/api/council/transcripts?limit=10");this._transcripts=Array.isArray(e&&e.transcripts)?e.transcripts:[]}catch(e){this._error=e&&e.message?e.message:String(e),this._transcripts=[]}try{let e=await this._api.get("/api/council/transcripts?limit=20&type_prefix=claude_hook_");this._hookEvents=Array.isArray(e&&e.hook_events)?e.hook_events:[]}catch{this._hookEvents=[]}finally{this._loading=!1,this.render()}}_escapeHtml(e){return e==null?"":String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}_formatTimestamp(e){if(!e)return"--";try{let t=new Date(e);return isNaN(t.getTime())?e:t.toLocaleString()}catch{return e}}_truncate(e,t){if(!e)return"";let i=String(e);return i.length>t?i.slice(0,t)+"...":i}_verdictBadgeHtml(e){let t=String(e||"").toUpperCase();return t==="APPROVE"?'<span class="ct-badge ct-badge-approve">APPROVE</span>':t==="REJECT"?'<span class="ct-badge ct-badge-reject">REJECT</span>':t==="CANNOT_VALIDATE"?'<span class="ct-badge ct-badge-cannot">CANNOT_VALIDATE</span>':'<span class="ct-badge ct-badge-unknown">'+this._escapeHtml(t||"UNKNOWN")+"</span>"}_outcomeBadgeHtml(e){let t=String(e||"").toUpperCase();return t==="APPROVED"?'<span class="ct-badge ct-badge-approve">APPROVED</span>':t==="REJECTED"?'<span class="ct-badge ct-badge-reject">REJECTED</span>':t==="BLOCKED_BY_GATE"?'<span class="ct-badge ct-badge-blocked">BLOCKED BY GATE</span>':'<span class="ct-badge ct-badge-unknown">'+this._escapeHtml(t||"UNKNOWN")+"</span>"}_voterRowHtml(e,t){let i=e.is_contrarian===!0,a=i&&t===!0,s="ct-voter-row";i&&(s+=" ct-voter-contrarian"),a&&(s+=" ct-voter-flipped");let r=this._escapeHtml(e.name||"unknown"),o=this._verdictBadgeHtml(e.verdict),n=this._escapeHtml(this._truncate(e.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&&e.triggered&&(l=`<span class="ct-badge ct-badge-da">DEVIL'S ADVOCATE</span>`);let p="";i&&Array.isArray(e.challenges)&&e.challenges.length>0&&(p='<ul class="ct-challenges">'+e.challenges.map(m=>"<li>"+this._escapeHtml(String(m))+"</li>").join("")+"</ul>");let h="";return Array.isArray(e.issues)&&e.issues.length>0&&(h='<ul class="ct-issues">'+e.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+h+c+"</div>"}_transcriptCardHtml(e){let t=this._escapeHtml(String(e.iteration||"--")),i=this._escapeHtml(this._formatTimestamp(e.timestamp)),a=this._escapeHtml(this._truncate(e.task_or_prd,200)),s=this._outcomeBadgeHtml(e.outcome),r=Array.isArray(e.voters)?e.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="";e.contrarian_triggered&&(c='<div class="ct-contrarian-section"><div class="ct-section-label">Anti-Sycophancy Check</div>'+n.map(f=>this._voterRowHtml(f,e.contrarian_flipped)).join("")+"</div>");let p=typeof e.approve_count=="number"?e.approve_count:"--",h=typeof e.reject_count=="number"?e.reject_count:"--",b=typeof e.threshold=="number"?e.threshold:"--";return'<div class="ct-card"><div class="ct-card-header"><div class="ct-card-meta"><span class="ct-iter-label">Iteration '+t+'</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: "+h+" &middot; Threshold: "+b+'</div><div class="ct-voters">'+l+"</div>"+c+"</div>"}render(){let e=this.shadowRoot||this;if(!e)return;let t=`
13348
13394
  <style>
13349
13395
  :host { display: block; margin-top: 24px; }
13350
13396
  .ct-wrapper {
@@ -13513,24 +13559,24 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
13513
13559
  .ct-badge-da { background: #fdf3d4; color: #8a6c0e; }
13514
13560
  .ct-badge-unknown { background: var(--bg-secondary, #F8F4F0); color: var(--text-muted, #939084); }
13515
13561
  </style>
13516
- `,i="";this._loading&&this._transcripts.length===0?i='<div class="ct-empty">Loading council transcripts...</div>':this._error?i='<div class="ct-error">Failed to load transcripts: '+this._escapeHtml(this._error)+"</div>":!this._transcripts||this._transcripts.length===0?i='<div class="ct-empty">No council rounds recorded yet -- transcripts appear after the first iteration vote.</div>':i='<div class="ct-list">'+this._transcripts.map(s=>this._transcriptCardHtml(s)).join("")+"</div>",t.innerHTML=e+'<div class="ct-wrapper"><h3 class="ct-heading">Council Transcripts</h3><div class="ct-explain">Per-iteration voting records from .loki/council/transcripts/. Polls every 30 seconds.</div>'+i+this._hookEventsHtml()+"</div>"}_hookEventsHtml(){let t=Array.isArray(this._hookEvents)?this._hookEvents:[],e;return t.length===0?e='<div class="ct-empty">No live tool activity yet -- Claude hook events stream here while a run is active.</div>':e='<div class="ct-voters">'+t.slice(0,20).map(a=>{let s=this._escapeHtml(a.type||a.event||"event"),r=this._escapeHtml(this._formatTimestamp(a.timestamp||a.ts)),o=this._escapeHtml(this._truncate(a.tool||a.message||a.summary||(a.data?JSON.stringify(a.data):""),120));return'<div class="ct-voter-row"><span class="ct-iter-label">'+s+'</span> <span class="ct-ts">'+r+"</span>"+(o?'<div class="ct-prd-preview">'+o+"</div>":"")+"</div>"}).join("")+"</div>",'<h3 class="ct-heading" style="margin-top:24px;">Live Tool Activity</h3><div class="ct-explain">Claude hook events (PreToolUse / PostToolUse / Stop) streamed from .loki/events.jsonl. Lets you watch background tool calls as they run.</div>'+e}};typeof customElements<"u"&&!customElements.get("loki-council-transcripts")&&customElements.define("loki-council-transcripts",yt);var Re=[{id:"overview",label:"Overview"},{id:"architecture",label:"Architecture"},{id:"modules",label:"Key Modules"},{id:"data-flow",label:"Data Flow"},{id:"ask",label:"Ask"}],wt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._activeTab="overview",this._loading=!1,this._error=null,this._api=null,this._meta=null,this._sectionCache={},this._question="",this._answer=null,this._asking=!1,this._askError=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadMeta()}attributeChangedCallback(t,e,i){t==="api-url"&&this._api&&(this._api.baseUrl=i)}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _loadMeta(){this._loading=!0,this._error=null,this.render();try{this._meta=await this._api._get("/api/wiki")}catch(t){this._error=t&&t.message?t.message:"Failed to load wiki"}finally{this._loading=!1,this.render();let t=this._activeTab;this._meta&&this._meta.generated&&(t==="architecture"||t==="modules"||t==="data-flow")&&!this._sectionCache[t]&&this._loadSection(t).then(()=>this.render())}}async _loadSection(t){if(this._sectionCache[t])return this._sectionCache[t];try{let e=await this._api._get(`/api/wiki/${encodeURIComponent(t)}`);return this._sectionCache[t]=e,e}catch(e){return this._sectionCache[t]={error:e&&e.message||"load failed"},this._sectionCache[t]}}async _selectTab(t){this._activeTab=t,t==="architecture"||t==="modules"||t==="data-flow"?this._meta&&this._meta.generated?(this.render(),await this._loadSection(t)):this.render():this.render()}async _ask(){let t=(this._question||"").trim();if(t){this._asking=!0,this._askError=null,this._answer=null,this.render();try{this._answer=await this._api._post("/api/wiki/ask",{question:t},{timeout:2e5})}catch(e){this._askError=e&&e.message?e.message:"Ask failed"}finally{this._asking=!1,this.render()}}}_esc(t){return String(t??"").replace(/&/g,"&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">
13562
+ `,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>",e.innerHTML=t+'<div class="ct-wrapper"><h3 class="ct-heading">Council Transcripts</h3><div class="ct-explain">Per-iteration voting records from .loki/council/transcripts/. Polls every 30 seconds.</div>'+i+this._hookEventsHtml()+"</div>"}_hookEventsHtml(){let e=Array.isArray(this._hookEvents)?this._hookEvents:[],t;return e.length===0?t='<div class="ct-empty">No live tool activity yet -- Claude hook events stream here while a run is active.</div>':t='<div class="ct-voters">'+e.slice(0,20).map(a=>{let s=this._escapeHtml(a.type||a.event||"event"),r=this._escapeHtml(this._formatTimestamp(a.timestamp||a.ts)),o=this._escapeHtml(this._truncate(a.tool||a.message||a.summary||(a.data?JSON.stringify(a.data):""),120));return'<div class="ct-voter-row"><span class="ct-iter-label">'+s+'</span> <span class="ct-ts">'+r+"</span>"+(o?'<div class="ct-prd-preview">'+o+"</div>":"")+"</div>"}).join("")+"</div>",'<h3 class="ct-heading" style="margin-top:24px;">Live Tool Activity</h3><div class="ct-explain">Claude hook events (PreToolUse / PostToolUse / Stop) streamed from .loki/events.jsonl. Lets you watch background tool calls as they run.</div>'+t}};typeof customElements<"u"&&!customElements.get("loki-council-transcripts")&&customElements.define("loki-council-transcripts",ye);var Rt=[{id:"overview",label:"Overview"},{id:"architecture",label:"Architecture"},{id:"modules",label:"Key Modules"},{id:"data-flow",label:"Data Flow"},{id:"ask",label:"Ask"}],we=class extends u{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(e,t,i){e==="api-url"&&this._api&&(this._api.baseUrl=i)}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}async _loadMeta(){this._loading=!0,this._error=null,this.render();try{this._meta=await this._api._get("/api/wiki")}catch(e){this._error=e&&e.message?e.message:"Failed to load wiki"}finally{this._loading=!1,this.render();let e=this._activeTab;this._meta&&this._meta.generated&&(e==="architecture"||e==="modules"||e==="data-flow")&&!this._sectionCache[e]&&this._loadSection(e).then(()=>this.render())}}async _loadSection(e){if(this._sectionCache[e])return this._sectionCache[e];try{let t=await this._api._get(`/api/wiki/${encodeURIComponent(e)}`);return this._sectionCache[e]=t,t}catch(t){return this._sectionCache[e]={error:t&&t.message||"load failed"},this._sectionCache[e]}}async _selectTab(e){this._activeTab=e,e==="architecture"||e==="modules"||e==="data-flow"?this._meta&&this._meta.generated?(this.render(),await this._loadSection(e)):this.render():this.render()}async _ask(){let e=(this._question||"").trim();if(e){this._asking=!0,this._askError=null,this._answer=null,this.render();try{this._answer=await this._api._post("/api/wiki/ask",{question:e},{timeout:2e5})}catch(t){this._askError=t&&t.message?t.message:"Ask failed"}finally{this._asking=!1,this.render()}}}_esc(e){return String(e??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}_renderCitations(e){return!e||!e.length?"":`<div class="cites"><strong>Sources:</strong><ul>${e.map(i=>`<li><code>${this._esc(i.file)}:${this._esc(i.line)}</code></li>`).join("")}</ul></div>`}_renderOverview(){let e=this._meta;if(!e||!e.generated)return`<div class="empty">
13517
13563
  <p>No wiki has been generated for this project yet.</p>
13518
13564
  <p>Run <code>loki wiki generate</code> to build a cited codebase wiki.</p>
13519
- </div>`;let e=(t.sections||[]).map(i=>`<li>${this._esc(i.title)} <span class="dim">(${this._esc(i.citation_count)} citations)</span></li>`).join("");return`<div class="overview">
13520
- <p><strong>${this._esc(t.project||"Project")}</strong> wiki -
13521
- ${this._esc(t.file_count||0)} source files indexed.</p>
13522
- <p class="dim">Generated: ${this._esc(t.generated_at||"unknown")}</p>
13523
- <ul>${e}</ul>
13524
- </div>`}_renderSection(t){if(!this._meta||!this._meta.generated)return`<div class="empty">
13565
+ </div>`;let t=(e.sections||[]).map(i=>`<li>${this._esc(i.title)} <span class="dim">(${this._esc(i.citation_count)} citations)</span></li>`).join("");return`<div class="overview">
13566
+ <p><strong>${this._esc(e.project||"Project")}</strong> wiki -
13567
+ ${this._esc(e.file_count||0)} source files indexed.</p>
13568
+ <p class="dim">Generated: ${this._esc(e.generated_at||"unknown")}</p>
13569
+ <ul>${t}</ul>
13570
+ </div>`}_renderSection(e){if(!this._meta||!this._meta.generated)return`<div class="empty">
13525
13571
  <p>No wiki generated yet.</p>
13526
13572
  <p>Run <code>loki wiki generate</code> to build a cited codebase wiki.</p>
13527
- </div>`;let e=this._sectionCache[t];return e?e.error?`<div class="error">${this._esc(e.error)}</div>`:`<div class="section">
13528
- <h3>${this._esc(e.title)}</h3>
13529
- <pre class="body">${this._esc(e.body)}</pre>
13530
- ${this._renderCitations(e.citations)}
13531
- </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">
13573
+ </div>`;let t=this._sectionCache[e];return t?t.error?`<div class="error">${this._esc(t.error)}</div>`:`<div class="section">
13574
+ <h3>${this._esc(t.title)}</h3>
13575
+ <pre class="body">${this._esc(t.body)}</pre>
13576
+ ${this._renderCitations(t.citations)}
13577
+ </div>`:'<div class="empty">Loading...</div>'}_renderAsk(){let e="";if(this._asking)e='<div class="empty">Searching the codebase...</div>';else if(this._askError)e=`<div class="error">${this._esc(this._askError)}</div>`;else if(this._answer){let t=this._answer.note?`<p class="dim">${this._esc(this._answer.note)}</p>`:"";e=`<div class="answer">
13532
13578
  <pre class="body">${this._esc(this._answer.answer||"")}</pre>
13533
- ${e}
13579
+ ${t}
13534
13580
  ${this._renderCitations(this._answer.citations)}
13535
13581
  </div>`}return`<div class="ask">
13536
13582
  <div class="ask-row">
@@ -13539,8 +13585,8 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
13539
13585
  <button id="wiki-ask-btn">Ask</button>
13540
13586
  </div>
13541
13587
  <p class="dim">Answers are grounded in the indexed codebase and cite real file:line locations.</p>
13542
- ${t}
13543
- </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":""}"
13588
+ ${e}
13589
+ </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 e=Rt.map(a=>`<button class="tab ${a.id===this._activeTab?"active":""}"
13544
13590
  data-tab="${a.id}">${this._esc(a.label)}</button>`).join("");this.shadowRoot.innerHTML=`
13545
13591
  <style>
13546
13592
  :host { display: block; font-family: var(--loki-font, system-ui, sans-serif);
@@ -13566,9 +13612,9 @@ var LokiDashboard=(()=>{var $t=Object.defineProperty;var ae=Object.getOwnPropert
13566
13612
  background: var(--loki-accent, #2563eb); color: #fff; cursor: pointer; }
13567
13613
  h3 { margin-top: 0; }
13568
13614
  </style>
13569
- <div class="tabs">${t}</div>
13615
+ <div class="tabs">${e}</div>
13570
13616
  <div class="content">${this._renderBody()}</div>
13571
- `,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);})();
13617
+ `,this.shadowRoot.querySelectorAll(".tab").forEach(a=>{a.addEventListener("click",()=>this._selectTab(a.dataset.tab))});let t=this.shadowRoot.getElementById("wiki-q");t&&(t.addEventListener("input",a=>{this._question=a.target.value}),t.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",we);var Bt="1.4.0";function Pt(d={}){return d.theme?_.setTheme(d.theme):d.autoDetectContext!==!1?_.init():R.init(),d.apiUrl&&g({baseUrl:d.apiUrl}),{theme:_.getTheme(),context:_.detectContext()}}return dt(Mt);})();
13572
13618
 
13573
13619
 
13574
13620
  // Initialize dashboard when DOM is ready