loki-mode 7.94.0 → 7.96.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1661,7 +1661,7 @@
1661
1661
 
1662
1662
  <!-- Inlined JavaScript Bundle -->
1663
1663
  <script>
1664
- var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropertyDescriptor;var yt=Object.getOwnPropertyNames;var wt=Object.prototype.hasOwnProperty;var $t=(d,e,t)=>e in d?He(d,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):d[e]=t;var Et=(d,e)=>{for(var t in e)He(d,t,{get:e[t],enumerable:!0})},Ct=(d,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of yt(e))!wt.call(d,a)&&a!==t&&He(d,a,{get:()=>e[a],enumerable:!(i=_t(e,a))||i.enumerable});return d};var St=d=>Ct(He({},"__esModule",{value:!0}),d);var S=(d,e,t)=>$t(d,typeof e!="symbol"?e+"":e,t);var ri={};Et(ri,{ANIMATION:()=>B,ARIA_PATTERNS:()=>Ie,ApiEvents:()=>f,BASE_STYLES:()=>V,BREAKPOINTS:()=>Be,COMMON_STYLES:()=>Ze,KEYBOARD_SHORTCUTS:()=>Pe,KeyboardHandler:()=>O,LokiActivityStream:()=>ye,LokiAgentLeaderboard:()=>Ae,LokiAnalytics:()=>ge,LokiApiClient:()=>N,LokiApiKeys:()=>xe,LokiAppPreview:()=>re,LokiAppStatus:()=>se,LokiAuditViewer:()=>ke,LokiChecklistViewer:()=>ae,LokiCheckpointViewer:()=>ne,LokiContextTracker:()=>le,LokiCostDashboard:()=>oe,LokiCostWaterfall:()=>Se,LokiCouncilDashboard:()=>ie,LokiCouncilTranscripts:()=>ze,LokiElement:()=>m,LokiEscalations:()=>Le,LokiFleet:()=>be,LokiLearningDashboard:()=>te,LokiLogStream:()=>Z,LokiManagedMemoryPanel:()=>Te,LokiMascotPresence:()=>Re,LokiMemoryBrowser:()=>ee,LokiMemoryGraph:()=>Ce,LokiMigrationDashboard:()=>ue,LokiNotificationCenter:()=>de,LokiOverview:()=>W,LokiPipelineView:()=>$e,LokiPromptOptimizer:()=>pe,LokiProviderHealth:()=>we,LokiQualityGates:()=>me,LokiQualityScore:()=>he,LokiRarvTimeline:()=>ve,LokiRunManager:()=>fe,LokiSessionControl:()=>X,LokiSessionDiff:()=>ce,LokiSpecPanel:()=>Me,LokiState:()=>Y,LokiTaskBoard:()=>Q,LokiTenantSwitcher:()=>_e,LokiTheme:()=>j,LokiWikiBrowser:()=>De,MARKDOWN_STYLES:()=>L,RADIUS:()=>H,SPACING:()=>z,STATE_CHANGE_EVENT:()=>Ue,THEMES:()=>A,THEME_VARIABLES:()=>Fe,TYPOGRAPHY:()=>$,UnifiedThemeManager:()=>w,VERSION:()=>ai,Z_INDEX:()=>P,createApiClient:()=>it,createStore:()=>at,escapeHtml:()=>Oe,generateThemeCSS:()=>E,generateTokensCSS:()=>K,getApiClient:()=>v,getState:()=>U,init:()=>si,renderMarkdown:()=>C});var A={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)"}},z={xs:"4px",sm:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"32px","3xl":"48px"},H={none:"0",sm:"2px",md:"4px",lg:"5px",xl:"5px",full:"9999px"},$={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"}},B={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)"}},Be={sm:"640px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},P={base:"0",dropdown:"100",sticky:"200",modal:"300",popover:"400",tooltip:"500",toast:"600"},Pe={"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"]}},Ie={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 E(d){let e=A[d];return e?Object.entries(e).map(([t,i])=>`${t}: ${i};`).join(`
1664
+ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropertyDescriptor;var yt=Object.getOwnPropertyNames;var wt=Object.prototype.hasOwnProperty;var $t=(d,e,t)=>e in d?Re(d,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):d[e]=t;var Et=(d,e)=>{for(var t in e)Re(d,t,{get:e[t],enumerable:!0})},Ct=(d,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of yt(e))!wt.call(d,a)&&a!==t&&Re(d,a,{get:()=>e[a],enumerable:!(i=_t(e,a))||i.enumerable});return d};var St=d=>Ct(Re({},"__esModule",{value:!0}),d);var S=(d,e,t)=>$t(d,typeof e!="symbol"?e+"":e,t);var ri={};Et(ri,{ANIMATION:()=>B,ARIA_PATTERNS:()=>Ie,ApiEvents:()=>f,BASE_STYLES:()=>V,BREAKPOINTS:()=>Be,COMMON_STYLES:()=>Ze,KEYBOARD_SHORTCUTS:()=>Pe,KeyboardHandler:()=>O,LokiActivityStream:()=>ye,LokiAgentLeaderboard:()=>Ae,LokiAnalytics:()=>ge,LokiApiClient:()=>N,LokiApiKeys:()=>xe,LokiAppPreview:()=>re,LokiAppStatus:()=>se,LokiAuditViewer:()=>ke,LokiChecklistViewer:()=>ae,LokiCheckpointViewer:()=>ne,LokiContextTracker:()=>le,LokiCostDashboard:()=>oe,LokiCostWaterfall:()=>Se,LokiCouncilDashboard:()=>ie,LokiCouncilTranscripts:()=>ze,LokiElement:()=>v,LokiEscalations:()=>Le,LokiFleet:()=>be,LokiLearningDashboard:()=>te,LokiLogStream:()=>Z,LokiManagedMemoryPanel:()=>Te,LokiMascotPresence:()=>Me,LokiMemoryBrowser:()=>ee,LokiMemoryGraph:()=>Ce,LokiMigrationDashboard:()=>ue,LokiNotificationCenter:()=>de,LokiOverview:()=>W,LokiPipelineView:()=>$e,LokiPromptOptimizer:()=>pe,LokiProviderHealth:()=>we,LokiQualityGates:()=>me,LokiQualityScore:()=>he,LokiRarvTimeline:()=>ve,LokiRunManager:()=>fe,LokiSessionControl:()=>X,LokiSessionDiff:()=>ce,LokiSpecPanel:()=>He,LokiState:()=>Y,LokiTaskBoard:()=>Q,LokiTenantSwitcher:()=>_e,LokiTheme:()=>j,LokiWikiBrowser:()=>De,MARKDOWN_STYLES:()=>L,RADIUS:()=>R,SPACING:()=>z,STATE_CHANGE_EVENT:()=>Ue,THEMES:()=>A,THEME_VARIABLES:()=>Fe,TYPOGRAPHY:()=>$,UnifiedThemeManager:()=>w,VERSION:()=>ai,Z_INDEX:()=>P,createApiClient:()=>it,createStore:()=>at,escapeHtml:()=>Oe,generateThemeCSS:()=>E,generateTokensCSS:()=>K,getApiClient:()=>h,getState:()=>U,init:()=>si,renderMarkdown:()=>C});var A={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)"}},z={xs:"4px",sm:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"32px","3xl":"48px"},R={none:"0",sm:"2px",md:"4px",lg:"5px",xl:"5px",full:"9999px"},$={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"}},B={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)"}},Be={sm:"640px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},P={base:"0",dropdown:"100",sticky:"200",modal:"300",popover:"400",tooltip:"500",toast:"600"},Pe={"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"]}},Ie={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 E(d){let e=A[d];return e?Object.entries(e).map(([t,i])=>`${t}: ${i};`).join(`
1665
1665
  `):""}function K(){return`
1666
1666
  /* Spacing */
1667
1667
  --loki-space-xs: ${z.xs};
@@ -1673,12 +1673,12 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
1673
1673
  --loki-space-3xl: ${z["3xl"]};
1674
1674
 
1675
1675
  /* Border Radius */
1676
- --loki-radius-none: ${H.none};
1677
- --loki-radius-sm: ${H.sm};
1678
- --loki-radius-md: ${H.md};
1679
- --loki-radius-lg: ${H.lg};
1680
- --loki-radius-xl: ${H.xl};
1681
- --loki-radius-full: ${H.full};
1676
+ --loki-radius-none: ${R.none};
1677
+ --loki-radius-sm: ${R.sm};
1678
+ --loki-radius-md: ${R.md};
1679
+ --loki-radius-lg: ${R.lg};
1680
+ --loki-radius-xl: ${R.xl};
1681
+ --loki-radius-full: ${R.full};
1682
1682
 
1683
1683
  /* Typography */
1684
1684
  --loki-font-sans: ${$.fontFamily.sans};
@@ -2098,7 +2098,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
2098
2098
  ::-webkit-scrollbar-thumb { background: var(--loki-border); border-radius: 3px; }
2099
2099
  ::-webkit-scrollbar-thumb:hover { background: var(--loki-border-light); }
2100
2100
  `,F=class F{static getTheme(){return w.getTheme()}static setTheme(e){w.setTheme(e)}static toggle(){return w.toggle()}static getVariables(e=null){let t=e||F.getTheme();return A[t]||Fe[t]||Fe.light}static toCSSString(e=null){let t=e||F.getTheme();if(A[t])return E(t);let i=F.getVariables(t);return Object.entries(i).map(([a,s])=>`${a}: ${s};`).join(`
2101
- `)}static applyToElement(e,t=null){let i=F.getVariables(t);for(let[a,s]of Object.entries(i))e.style.setProperty(a,s)}static init(){w.init()}static detectContext(){return w.detectContext()}static getAvailableThemes(){return Object.keys(A)}};S(F,"STORAGE_KEY","loki-theme");var j=F,m=class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}),this._theme=j.getTheme(),this._themeChangeHandler=this._onThemeChange.bind(this),this._keyboardHandler=new O}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(){j.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`
2101
+ `)}static applyToElement(e,t=null){let i=F.getVariables(t);for(let[a,s]of Object.entries(i))e.style.setProperty(a,s)}static init(){w.init()}static detectContext(){return w.detectContext()}static getAvailableThemes(){return Object.keys(A)}};S(F,"STORAGE_KEY","loki-theme");var j=F,v=class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}),this._theme=j.getTheme(),this._themeChangeHandler=this._onThemeChange.bind(this),this._keyboardHandler=new O}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(){j.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`
2102
2102
  /* Design tokens */
2103
2103
  :host {
2104
2104
  ${K()}
@@ -2156,9 +2156,9 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
2156
2156
  }
2157
2157
 
2158
2158
  ${V}
2159
- `}getAriaPattern(e){return Ie[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 I={realtime:1e3,normal:2e3,background:5e3,offline:1e4},et={vscode:I.normal,browser:I.realtime,cli:I.background},tt={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},f={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"},D=class D extends EventTarget{static getInstance(e={}){let t=e.baseUrl||tt.baseUrl;return D._instances.has(t)||D._instances.set(t,new D(e)),D._instances.get(t)}static clearInstances(){D._instances.forEach(e=>e.disconnect()),D._instances.clear()}constructor(e={}){super(),this.config={...tt,...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=et[this._context]||I.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 I}_setupAdaptivePolling(){typeof document>"u"||(this._visibilityChangeHandler=()=>{document.hidden?this._setPollInterval(I.background):this._setPollInterval(et[this._context]||I.normal)},document.addEventListener("visibilitychange",this._visibilityChangeHandler))}_setPollInterval(e){this._currentPollInterval=e,this._pollInterval&&(this.stopPolling(),this.startPolling(null,e))}setPollMode(e){let t=I[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(f.STATUS_UPDATE,t.data);break;case"updateTasks":this._emit(f.TASK_UPDATED,t.data);break;case"taskCreated":this._emit(f.TASK_CREATED,t.data);break;case"taskDeleted":this._emit(f.TASK_DELETED,t.data);break;case"projectCreated":this._emit(f.PROJECT_CREATED,t.data);break;case"projectUpdated":this._emit(f.PROJECT_UPDATED,t.data);break;case"agentUpdate":this._emit(f.AGENT_UPDATE,t.data);break;case"logMessage":this._emit(f.LOG_MESSAGE,t.data);break;case"memoryUpdate":this._emit(f.MEMORY_UPDATE,t.data);break;case"connected":this._connected=!0,this._emit(f.CONNECTED,t.data);break;case"disconnected":this._connected=!1,this._emit(f.DISCONNECTED,t.data);break;case"error":this._emit(f.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(f.CONNECTED),e()},this._ws.onclose=()=>{this._connected=!1,this._emit(f.DISCONNECTED),this._scheduleReconnect()},this._ws.onerror=i=>{this._emit(f.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(f.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:f.CONNECTED,status_update:f.STATUS_UPDATE,task_created:f.TASK_CREATED,task_updated:f.TASK_UPDATED,task_deleted:f.TASK_DELETED,task_moved:f.TASK_UPDATED,project_created:f.PROJECT_CREATED,project_updated:f.PROJECT_UPDATED,agent_update:f.AGENT_UPDATE,log:f.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 startSession(e,t={}){let i={provider:t.provider||"claude",parallel:!!t.parallel};return t.prdPath?i.prd_path=t.prdPath:i.prd_text=e||"",this._post("/api/control/start",i)}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 getSessionModel(){return this._get("/api/session/model")}async setSessionModel(e){return this._post("/api/session/model",{model:e||null})}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 getAppRunnerErrors(e=50){return this._get(`/api/app-runner/errors?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(f.STATUS_UPDATE,s),this._vscodeApi&&this.postToVSCode("pollSuccess",{timestamp:Date.now()})}catch(s){this._connected=!1,this._emit(f.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)}};S(D,"_instances",new Map);var N=D;function it(d={}){return new N(d)}function v(d={}){return N.getInstance(d)}var Ue="loki-state-change",je={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}},T=class T extends EventTarget{static getInstance(){return T._instance||(T._instance=new T),T._instance}constructor(){super(),this._state=this._loadState(),this._subscribers=new Map,this._batchUpdates=[],this._batchTimeout=null}_loadState(){try{let e=localStorage.getItem(T.STORAGE_KEY);if(e){let t=JSON.parse(e);return this._mergeState(je,t)}}catch(e){console.warn("Failed to load state from localStorage:",e)}return{...je}}_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(T.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(Ue,{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=je;for(let a of t)i=i?.[a];this.set(e,i)}else this._state={...je},this._saveState(),this.dispatchEvent(new CustomEvent(Ue,{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)}};S(T,"STORAGE_KEY","loki-dashboard-state"),S(T,"_instance",null);var Y=T;function U(){return Y.getInstance()}function at(d){let e=U();return{get:()=>e.get(d),set:t=>e.set(d,t),subscribe:t=>e.subscribe(d,t)}}function Oe(d){return String(d??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function C(d){if(d==null||d==="")return"";let e=String(d).replace(/\r\n/g,`
2160
- `),t=[];e=e.replace(/```[^\n]*\n([\s\S]*?)```/g,(h,g)=>{let u=t.length;return t.push(`<pre class="md-code"><code>${Oe(g.replace(/\n$/,""))}</code></pre>`),`\0CODEBLOCK${u}\0`});let i=Oe(e);i=i.replace(/`([^`\n]+)`/g,(h,g)=>`<code class="md-inline-code">${g}</code>`),i=i.replace(/\[([^\]\n]+)\]\(([^)\s]+)\)/g,(h,g,u)=>/^(https?:|mailto:|\/|#|\.)/.test(u)?`<a class="md-link" href="${u}" target="_blank" rel="noopener noreferrer">${g}</a>`:h);let a=i.split(`
2161
- `),s=[],r=[],o=[],n=()=>{r.length&&(s.push(`<p class="md-p">${r.join("<br>")}</p>`),r=[])},l=h=>{for(;o.length&&o[o.length-1].indent>=h;)s.push(`</${o.pop().tag}>`)},c=()=>{for(;o.length;)s.push(`</${o.pop().tag}>`)};for(let h of a){let g=h,u=g.trim(),x=u.match(/^CODEBLOCK(\d+)$/);if(x){n(),c(),s.push(t[Number(x[1])]);continue}if(u===""){n(),c();continue}let k=u.match(/^(#{1,6})\s+(.+)$/);if(k){n(),c();let R=Math.min(k[1].length+1,6);s.push(`<h${R} class="md-h${R}">${k[2]}</h${R}>`);continue}if(/^(-{3,}|\*{3,}|_{3,})$/.test(u)){n(),c(),s.push('<hr class="md-hr">');continue}let _=u.match(/^&gt;\s?(.*)$/);if(_){n(),c(),s.push(`<blockquote class="md-quote">${_[1]}</blockquote>`);continue}let M=g.match(/^(\s*)/)[1].replace(/\t/g," ").length,J=u.match(/^([-*+])\s+(.+)$/),G=u.match(/^(\d+)[.)]\s+(.+)$/);if(J||G){n();let R=G?"ol":"ul",xt=J?J[2]:G[2];!o.length||M>o[o.length-1].indent?(s.push(`<${R} class="md-list">`),o.push({tag:R,indent:M})):(l(M+1),o.length||(s.push(`<${R} class="md-list">`),o.push({tag:R,indent:M}))),s.push(`<li>${xt}</li>`);continue}c(),r.push(g.trim())}n(),c();let p=s.join(`
2159
+ `}getAriaPattern(e){return Ie[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 I={realtime:1e3,normal:2e3,background:5e3,offline:1e4},et={vscode:I.normal,browser:I.realtime,cli:I.background},tt={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},f={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"},D=class D extends EventTarget{static getInstance(e={}){let t=e.baseUrl||tt.baseUrl;return D._instances.has(t)||D._instances.set(t,new D(e)),D._instances.get(t)}static clearInstances(){D._instances.forEach(e=>e.disconnect()),D._instances.clear()}constructor(e={}){super(),this.config={...tt,...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=et[this._context]||I.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 I}_setupAdaptivePolling(){typeof document>"u"||(this._visibilityChangeHandler=()=>{document.hidden?this._setPollInterval(I.background):this._setPollInterval(et[this._context]||I.normal)},document.addEventListener("visibilitychange",this._visibilityChangeHandler))}_setPollInterval(e){this._currentPollInterval=e,this._pollInterval&&(this.stopPolling(),this.startPolling(null,e))}setPollMode(e){let t=I[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(f.STATUS_UPDATE,t.data);break;case"updateTasks":this._emit(f.TASK_UPDATED,t.data);break;case"taskCreated":this._emit(f.TASK_CREATED,t.data);break;case"taskDeleted":this._emit(f.TASK_DELETED,t.data);break;case"projectCreated":this._emit(f.PROJECT_CREATED,t.data);break;case"projectUpdated":this._emit(f.PROJECT_UPDATED,t.data);break;case"agentUpdate":this._emit(f.AGENT_UPDATE,t.data);break;case"logMessage":this._emit(f.LOG_MESSAGE,t.data);break;case"memoryUpdate":this._emit(f.MEMORY_UPDATE,t.data);break;case"connected":this._connected=!0,this._emit(f.CONNECTED,t.data);break;case"disconnected":this._connected=!1,this._emit(f.DISCONNECTED,t.data);break;case"error":this._emit(f.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(f.CONNECTED),e()},this._ws.onclose=()=>{this._connected=!1,this._emit(f.DISCONNECTED),this._scheduleReconnect()},this._ws.onerror=i=>{this._emit(f.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(f.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:f.CONNECTED,status_update:f.STATUS_UPDATE,task_created:f.TASK_CREATED,task_updated:f.TASK_UPDATED,task_deleted:f.TASK_DELETED,task_moved:f.TASK_UPDATED,project_created:f.PROJECT_CREATED,project_updated:f.PROJECT_UPDATED,agent_update:f.AGENT_UPDATE,log:f.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 startSession(e,t={}){let i={provider:t.provider||"claude",parallel:!!t.parallel};return t.prdPath?i.prd_path=t.prdPath:i.prd_text=e||"",this._post("/api/control/start",i)}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 getSessionModel(){return this._get("/api/session/model")}async setSessionModel(e){return this._post("/api/session/model",{model:e||null})}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 getAppRunnerErrors(e=50){return this._get(`/api/app-runner/errors?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(f.STATUS_UPDATE,s),this._vscodeApi&&this.postToVSCode("pollSuccess",{timestamp:Date.now()})}catch(s){this._connected=!1,this._emit(f.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)}};S(D,"_instances",new Map);var N=D;function it(d={}){return new N(d)}function h(d={}){return N.getInstance(d)}var Ue="loki-state-change",je={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}},T=class T extends EventTarget{static getInstance(){return T._instance||(T._instance=new T),T._instance}constructor(){super(),this._state=this._loadState(),this._subscribers=new Map,this._batchUpdates=[],this._batchTimeout=null}_loadState(){try{let e=localStorage.getItem(T.STORAGE_KEY);if(e){let t=JSON.parse(e);return this._mergeState(je,t)}}catch(e){console.warn("Failed to load state from localStorage:",e)}return{...je}}_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(T.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(Ue,{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=je;for(let a of t)i=i?.[a];this.set(e,i)}else this._state={...je},this._saveState(),this.dispatchEvent(new CustomEvent(Ue,{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)}};S(T,"STORAGE_KEY","loki-dashboard-state"),S(T,"_instance",null);var Y=T;function U(){return Y.getInstance()}function at(d){let e=U();return{get:()=>e.get(d),set:t=>e.set(d,t),subscribe:t=>e.subscribe(d,t)}}function Oe(d){return String(d??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function C(d){if(d==null||d==="")return"";let e=String(d).replace(/\r\n/g,`
2160
+ `),t=[];e=e.replace(/```[^\n]*\n([\s\S]*?)```/g,(u,m)=>{let g=t.length;return t.push(`<pre class="md-code"><code>${Oe(m.replace(/\n$/,""))}</code></pre>`),`\0CODEBLOCK${g}\0`});let i=Oe(e);i=i.replace(/`([^`\n]+)`/g,(u,m)=>`<code class="md-inline-code">${m}</code>`),i=i.replace(/\[([^\]\n]+)\]\(([^)\s]+)\)/g,(u,m,g)=>/^(https?:|mailto:|\/|#|\.)/.test(g)?`<a class="md-link" href="${g}" target="_blank" rel="noopener noreferrer">${m}</a>`:u);let a=i.split(`
2161
+ `),s=[],r=[],o=[],n=()=>{r.length&&(s.push(`<p class="md-p">${r.join("<br>")}</p>`),r=[])},l=u=>{for(;o.length&&o[o.length-1].indent>=u;)s.push(`</${o.pop().tag}>`)},c=()=>{for(;o.length;)s.push(`</${o.pop().tag}>`)};for(let u of a){let m=u,g=m.trim(),x=g.match(/^CODEBLOCK(\d+)$/);if(x){n(),c(),s.push(t[Number(x[1])]);continue}if(g===""){n(),c();continue}let k=g.match(/^(#{1,6})\s+(.+)$/);if(k){n(),c();let M=Math.min(k[1].length+1,6);s.push(`<h${M} class="md-h${M}">${k[2]}</h${M}>`);continue}if(/^(-{3,}|\*{3,}|_{3,})$/.test(g)){n(),c(),s.push('<hr class="md-hr">');continue}let _=g.match(/^&gt;\s?(.*)$/);if(_){n(),c(),s.push(`<blockquote class="md-quote">${_[1]}</blockquote>`);continue}let H=m.match(/^(\s*)/)[1].replace(/\t/g," ").length,J=g.match(/^([-*+])\s+(.+)$/),G=g.match(/^(\d+)[.)]\s+(.+)$/);if(J||G){n();let M=G?"ol":"ul",xt=J?J[2]:G[2];!o.length||H>o[o.length-1].indent?(s.push(`<${M} class="md-list">`),o.push({tag:M,indent:H})):(l(H+1),o.length||(s.push(`<${M} class="md-list">`),o.push({tag:M,indent:H}))),s.push(`<li>${xt}</li>`);continue}c(),r.push(m.trim())}n(),c();let p=s.join(`
2162
2162
  `);return p=p.replace(/\*\*([^*\n]+)\*\*/g,"<strong>$1</strong>"),p=p.replace(/__([^_\n]+)__/g,"<strong>$1</strong>"),p=p.replace(/(^|[^*])\*([^*\n]+)\*/g,"$1<em>$2</em>"),p}var L=`
2163
2163
  .md-body { line-height: 1.6; color: var(--loki-text, #2b2a28); font-size: 14px; word-wrap: break-word; }
2164
2164
  .md-body .md-h2 { font-size: 18px; font-weight: 650; margin: 18px 0 8px; }
@@ -2175,7 +2175,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
2175
2175
  .md-body .md-link:hover { text-decoration: underline; }
2176
2176
  .md-body .md-hr { border: 0; border-top: 1px solid var(--loki-border, #e5e1d8); margin: 16px 0; }
2177
2177
  .md-body strong { font-weight: 650; }
2178
- `;function st(d){return!d||typeof d!="string"?null:d.startsWith("page-")?d.slice(5):d}function Ne(){if(typeof document>"u")return null;let d=document.querySelector(".section-page.active");if(d&&d.id)return st(d.id);try{if(typeof localStorage<"u"){let e=localStorage.getItem("loki-active-section");if(e)return e}}catch{}return null}var Ge=class{constructor(){this._regs=new Map,this._seq=0,this._activeSection=Ne(),this._hidden=typeof document<"u"?!!document.hidden:!1,this._listenersInstalled=!1,this._sectionChangeHandler=null,this._visibilityHandler=null,this._mutationObserver=null}get _hasDom(){return typeof document<"u"}_ensureListeners(){if(!(this._listenersInstalled||!this._hasDom)){this._sectionChangeHandler=e=>{let t=e&&e.detail&&e.detail.section?e.detail.section:Ne();this._setActiveSection(t)},document.addEventListener("loki:section-change",this._sectionChangeHandler),this._visibilityHandler=()=>{let e=!!document.hidden;e!==this._hidden&&(this._hidden=e,e||(this._activeSection=Ne()),this._reevaluateAll())},document.addEventListener("visibilitychange",this._visibilityHandler);try{let e=document.getElementById("main-content")||document.body;e&&typeof MutationObserver<"u"&&(this._mutationObserver=new MutationObserver(()=>{let t=Ne();t&&t!==this._activeSection&&this._setActiveSection(t)}),this._mutationObserver.observe(e,{subtree:!0,attributes:!0,attributeFilter:["class"]}))}catch{}this._listenersInstalled=!0}}_setActiveSection(e){e!==this._activeSection&&(this._activeSection=e,this._reevaluateAll())}_resolveSection(e){if(Object.prototype.hasOwnProperty.call(e,"sectionId"))return e.sectionId===null?void 0:e.sectionId;if(e.element&&typeof e.element.closest=="function"){let t=e.element.closest(".section-page"),i=st(t&&t.id);return i===null?void 0:i}}_isAllowed(e){if(!this._hasDom)return!0;if(this._hidden)return!1;let t=this._resolveSection(e);return t===void 0?!0:t===this._activeSection}_reevaluateAll(){for(let e of this._regs.values()){let t=this._isAllowed(e);t&&!e._wasAllowed?(e._wasAllowed=!0,this._safeRun(e)):e._wasAllowed=t}}_safeRun(e){try{let t=e.loadFn();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}register(e={}){let{loadFn:t,intervalMs:i}=e;if(typeof t!="function")throw new Error("registerPoll: loadFn must be a function");if(typeof i!="number"||!(i>0))throw new Error("registerPoll: intervalMs must be a positive number");this._ensureListeners();let a=e.id||`poll-${++this._seq}`;this._regs.has(a)&&this._stopReg(this._regs.get(a));let s={id:a,loadFn:t,intervalMs:i,element:e.element||null,_timer:null,_wasAllowed:!1};return Object.prototype.hasOwnProperty.call(e,"sectionId")&&(s.sectionId=e.sectionId),s._wasAllowed=this._isAllowed(s),s._timer=setInterval(()=>{this._isAllowed(s)?(s._wasAllowed=!0,this._safeRun(s)):s._wasAllowed=!1},i),this._regs.set(a,s),e.immediate!==!1&&s._wasAllowed&&this._safeRun(s),{id:a,stop:()=>this.unregister(a),isActive:()=>this._isAllowed(s)}}_stopReg(e){e&&e._timer&&(clearInterval(e._timer),e._timer=null)}unregister(e){let t=this._regs.get(e);return t?(this._stopReg(t),this._regs.delete(e),!0):!1}get activeSection(){return this._activeSection}get size(){return this._regs.size}destroy(){for(let e of this._regs.values())this._stopReg(e);this._regs.clear(),this._hasDom&&(this._sectionChangeHandler&&(document.removeEventListener("loki:section-change",this._sectionChangeHandler),this._sectionChangeHandler=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null),this._mutationObserver&&(this._mutationObserver.disconnect(),this._mutationObserver=null)),this._listenersInstalled=!1}},Je=null;function At(){return Je||(Je=new Ge),Je}function b(d){return At().register(d)}var W=class extends m{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(f.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(f.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(f.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=v({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(f.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(f.CONNECTED,this._connectedHandler),this._api.addEventListener(f.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._poll=b({loadFn:async()=>{try{await this._loadStatus()}catch{this._data.connected=!1,this._data.status="offline",this.render()}},intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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`
2178
+ `;function st(d){return!d||typeof d!="string"?null:d.startsWith("page-")?d.slice(5):d}function Ne(){if(typeof document>"u")return null;let d=document.querySelector(".section-page.active");if(d&&d.id)return st(d.id);try{if(typeof localStorage<"u"){let e=localStorage.getItem("loki-active-section");if(e)return e}}catch{}return null}var Ge=class{constructor(){this._regs=new Map,this._seq=0,this._activeSection=Ne(),this._hidden=typeof document<"u"?!!document.hidden:!1,this._listenersInstalled=!1,this._sectionChangeHandler=null,this._visibilityHandler=null,this._mutationObserver=null}get _hasDom(){return typeof document<"u"}_ensureListeners(){if(!(this._listenersInstalled||!this._hasDom)){this._sectionChangeHandler=e=>{let t=e&&e.detail&&e.detail.section?e.detail.section:Ne();this._setActiveSection(t)},document.addEventListener("loki:section-change",this._sectionChangeHandler),this._visibilityHandler=()=>{let e=!!document.hidden;e!==this._hidden&&(this._hidden=e,e||(this._activeSection=Ne()),this._reevaluateAll())},document.addEventListener("visibilitychange",this._visibilityHandler);try{let e=document.getElementById("main-content")||document.body;e&&typeof MutationObserver<"u"&&(this._mutationObserver=new MutationObserver(()=>{let t=Ne();t&&t!==this._activeSection&&this._setActiveSection(t)}),this._mutationObserver.observe(e,{subtree:!0,attributes:!0,attributeFilter:["class"]}))}catch{}this._listenersInstalled=!0}}_setActiveSection(e){e!==this._activeSection&&(this._activeSection=e,this._reevaluateAll())}_resolveSection(e){if(Object.prototype.hasOwnProperty.call(e,"sectionId"))return e.sectionId===null?void 0:e.sectionId;if(e.element&&typeof e.element.closest=="function"){let t=e.element.closest(".section-page"),i=st(t&&t.id);return i===null?void 0:i}}_isAllowed(e){if(!this._hasDom)return!0;if(this._hidden)return!1;let t=this._resolveSection(e);return t===void 0?!0:t===this._activeSection}_reevaluateAll(){for(let e of this._regs.values()){let t=this._isAllowed(e);t&&!e._wasAllowed?(e._wasAllowed=!0,this._safeRun(e)):e._wasAllowed=t}}_safeRun(e){try{let t=e.loadFn();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}register(e={}){let{loadFn:t,intervalMs:i}=e;if(typeof t!="function")throw new Error("registerPoll: loadFn must be a function");if(typeof i!="number"||!(i>0))throw new Error("registerPoll: intervalMs must be a positive number");this._ensureListeners();let a=e.id||`poll-${++this._seq}`;this._regs.has(a)&&this._stopReg(this._regs.get(a));let s={id:a,loadFn:t,intervalMs:i,element:e.element||null,_timer:null,_wasAllowed:!1};return Object.prototype.hasOwnProperty.call(e,"sectionId")&&(s.sectionId=e.sectionId),s._wasAllowed=this._isAllowed(s),s._timer=setInterval(()=>{this._isAllowed(s)?(s._wasAllowed=!0,this._safeRun(s)):s._wasAllowed=!1},i),this._regs.set(a,s),e.immediate!==!1&&s._wasAllowed&&this._safeRun(s),{id:a,stop:()=>this.unregister(a),isActive:()=>this._isAllowed(s)}}_stopReg(e){e&&e._timer&&(clearInterval(e._timer),e._timer=null)}unregister(e){let t=this._regs.get(e);return t?(this._stopReg(t),this._regs.delete(e),!0):!1}get activeSection(){return this._activeSection}get size(){return this._regs.size}destroy(){for(let e of this._regs.values())this._stopReg(e);this._regs.clear(),this._hasDom&&(this._sectionChangeHandler&&(document.removeEventListener("loki:section-change",this._sectionChangeHandler),this._sectionChangeHandler=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null),this._mutationObserver&&(this._mutationObserver.disconnect(),this._mutationObserver=null)),this._listenersInstalled=!1}},Je=null;function At(){return Je||(Je=new Ge),Je}function b(d){return At().register(d)}var W=class extends v{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._teardownApiListeners()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._teardownApiListeners(),this._setupApi(),this._api.connect().catch(()=>{}),this._loadStatus()),e==="theme"&&this._applyTheme())}_teardownApiListeners(){this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(f.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(f.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(f.DISCONNECTED,this._disconnectedHandler))}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({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(f.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(f.CONNECTED,this._connectedHandler),this._api.addEventListener(f.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._poll=b({loadFn:async()=>{try{await this._loadStatus()}catch{this._data.connected=!1,this._data.status="offline",this.render()}},intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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`
2179
2179
  <div class="overview-card">
2180
2180
  <div class="card-label">App Status</div>
2181
2181
  <div class="card-value small-text">${this._data.status==="running"||this._data.status==="autonomous"?"Starting...":"Not started"}</div>
@@ -2430,7 +2430,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
2430
2430
  </div>
2431
2431
  </div>
2432
2432
  </div>
2433
- `}};customElements.get("loki-overview")||customElements.define("loki-overview",W);var Tt=[{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 d extends m{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._searchQuery="",this._visibleCounts={},this._api=null,this._state=U()}static get PAGE_SIZE(){return 10}_getVisibleCount(e){let t=this._visibleCounts[e];return typeof t=="number"&&t>0?t:d.PAGE_SIZE}_showMore(e){this._visibleCounts[e]=this._getVisibleCount(e)+d.PAGE_SIZE,this.render()}_columnIcon(e){switch(e){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"/>'}}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadTasks()}disconnectedCallback(){super.disconnectedCallback(),this._api&&(this._api.removeEventListener(f.TASK_CREATED,this._onTaskEvent),this._api.removeEventListener(f.TASK_UPDATED,this._onTaskEvent),this._api.removeEventListener(f.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=v({baseUrl:e}),this._onTaskEvent&&(this._api.removeEventListener(f.TASK_CREATED,this._onTaskEvent),this._api.removeEventListener(f.TASK_UPDATED,this._onTaskEvent),this._api.removeEventListener(f.TASK_DELETED,this._onTaskEvent)),this._onTaskEvent=()=>this._loadTasks(),this._api.addEventListener(f.TASK_CREATED,this._onTaskEvent),this._api.addEventListener(f.TASK_UPDATED,this._onTaskEvent),this._api.addEventListener(f.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._visibleCounts={},this.render()}_setSearch(e){this._searchQuery=e||"",this._visibleCounts={},this._renderTaskRegion();let t=this.shadowRoot.getElementById("task-search");if(t){t.focus();let i=t.value.length;try{t.setSelectionRange(i,i)}catch{}}}_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(r=>{let o=r.created_at?new Date(r.created_at):null;return o&&o>=i});break;case"this-week":e=e.filter(r=>{let o=r.created_at?new Date(r.created_at):null;return o&&o>=a});break;case"running":e=e.filter(r=>r.status==="in_progress");break;case"failed":e=e.filter(r=>r.status==="failed"||r.status==="error");break;default:break}let s=this._searchQuery.trim().toLowerCase();return s&&(e=e.filter(r=>[r.id,r.title,r.description,r.type].map(n=>String(n??"").toLowerCase()).join(" ").includes(s))),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){return C(e)}_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,u=>u.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:[],g=e.full_content||"";return`
2433
+ `}};customElements.get("loki-overview")||customElements.define("loki-overview",W);var Tt=[{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 d extends v{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._searchQuery="",this._visibleCounts={},this._api=null,this._state=U()}static get PAGE_SIZE(){return 10}_getVisibleCount(e){let t=this._visibleCounts[e];return typeof t=="number"&&t>0?t:d.PAGE_SIZE}_showMore(e){this._visibleCounts[e]=this._getVisibleCount(e)+d.PAGE_SIZE,this.render()}_columnIcon(e){switch(e){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"/>'}}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadTasks()}disconnectedCallback(){super.disconnectedCallback(),this._teardownApiListeners()}_teardownApiListeners(){this._api&&this._onTaskEvent&&(this._api.removeEventListener(f.TASK_CREATED,this._onTaskEvent),this._api.removeEventListener(f.TASK_UPDATED,this._onTaskEvent),this._api.removeEventListener(f.TASK_DELETED,this._onTaskEvent))}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._teardownApiListeners(),this._setupApi(),this._loadTasks()),e==="project-id"&&this._loadTasks(),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e}),this._onTaskEvent=()=>this._loadTasks(),this._api.addEventListener(f.TASK_CREATED,this._onTaskEvent),this._api.addEventListener(f.TASK_UPDATED,this._onTaskEvent),this._api.addEventListener(f.TASK_DELETED,this._onTaskEvent)}async _loadTasks(){let e=this._api;this._loading=!0,this._error=null,this.render();try{let t=this.getAttribute("project-id"),i=t?{projectId:parseInt(t)}:{},a=await e.listTasks(i);if(e!==this._api)return;this._tasks=a;let s=this._state.get("localTasks")||[];s.length>0&&(this._tasks=[...this._tasks,...s.map(r=>({...r,isLocal:!0}))]),this._state.update({"cache.tasks":this._tasks},!1)}catch(t){if(e!==this._api)return;this._error=t.message,this._tasks=(this._state.get("localTasks")||[]).map(i=>({...i,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._visibleCounts={},this.render()}_setSearch(e){this._searchQuery=e||"",this._visibleCounts={},this._renderTaskRegion();let t=this.shadowRoot.getElementById("task-search");if(t){t.focus();let i=t.value.length;try{t.setSelectionRange(i,i)}catch{}}}_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(r=>{let o=r.created_at?new Date(r.created_at):null;return o&&o>=i});break;case"this-week":e=e.filter(r=>{let o=r.created_at?new Date(r.created_at):null;return o&&o>=a});break;case"running":e=e.filter(r=>r.status==="in_progress");break;case"failed":e=e.filter(r=>r.status==="failed"||r.status==="error");break;default:break}let s=this._searchQuery.trim().toLowerCase();return s&&(e=e.filter(r=>[r.id,r.title,r.description,r.type].map(n=>String(n??"").toLowerCase()).join(" ").includes(s))),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){return C(e)}_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,g=>g.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:[],u=Array.isArray(e.logs)?e.logs:[],m=e.full_content||"";return`
2434
2434
  <div class="modal-overlay" id="task-detail-overlay">
2435
2435
  <div class="modal-container">
2436
2436
  <div class="modal-header">
@@ -2447,9 +2447,9 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
2447
2447
  <div class="modal-section">
2448
2448
  <h3 class="modal-section-title">Metadata</h3>
2449
2449
  <div class="meta-grid">
2450
- ${Object.entries(r).map(([u,x])=>`
2450
+ ${Object.entries(r).map(([g,x])=>`
2451
2451
  <div class="meta-cell">
2452
- <span class="meta-label">${this._escapeHtml(u.replace(/_/g," "))}</span>
2452
+ <span class="meta-label">${this._escapeHtml(g.replace(/_/g," "))}</span>
2453
2453
  <span class="meta-value">${this._escapeHtml(String(x))}</span>
2454
2454
  </div>
2455
2455
  `).join("")}
@@ -2475,7 +2475,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
2475
2475
  <div class="modal-section">
2476
2476
  <h3 class="modal-section-title">Acceptance Criteria</h3>
2477
2477
  <ul class="criteria-checklist" role="list">
2478
- ${o.map(u=>{let x=u&&typeof u=="object",k=x?u.text||u.title||"":u,_=x?!!u.done:!1;return`<li class="criteria-item">
2478
+ ${o.map(g=>{let x=g&&typeof g=="object",k=x?g.text||g.title||"":g,_=x?!!g.done:!1;return`<li class="criteria-item">
2479
2479
  <span class="criteria-checkbox ${_?"checked":""}" aria-hidden="true">${_?"&#10003;":""}</span>
2480
2480
  <span class="criteria-text ${_?"done":""}">${this._escapeHtml(String(k))}</span>
2481
2481
  </li>`}).join("")}
@@ -2487,7 +2487,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
2487
2487
  <div class="modal-section">
2488
2488
  <h3 class="modal-section-title">Notes</h3>
2489
2489
  <ul class="notes-timeline" role="list">
2490
- ${p.map(u=>{let x=this._formatTimestamp(u&&u.timestamp),k=u&&u.author?this._escapeHtml(String(u.author)):"unknown",_=u&&u.body?this._escapeHtml(String(u.body)):"";return`<li class="note-entry">
2490
+ ${p.map(g=>{let x=this._formatTimestamp(g&&g.timestamp),k=g&&g.author?this._escapeHtml(String(g.author)):"unknown",_=g&&g.body?this._escapeHtml(String(g.body)):"";return`<li class="note-entry">
2491
2491
  <div class="note-meta">
2492
2492
  <span class="note-author">${k}</span>
2493
2493
  ${x?`<span class="note-time">${x}</span>`:""}
@@ -2498,15 +2498,15 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
2498
2498
  </div>
2499
2499
  `:""}
2500
2500
 
2501
- ${h.length>0?`
2501
+ ${u.length>0?`
2502
2502
  <div class="modal-section">
2503
2503
  <h3 class="modal-section-title">Logs</h3>
2504
2504
  <div class="logs-scroll">
2505
2505
  <ul class="logs-timeline" role="list">
2506
- ${h.map(u=>{let x=this._formatTimestamp(u&&u.timestamp),k=u&&u.iteration!==void 0&&u.iteration!==null?`i${this._escapeHtml(String(u.iteration))}`:"",_=u&&u.phase?String(u.phase):"",M=this._phaseClass(_),J=this._logLevelClass(u&&u.level),G=u&&u.message?this._escapeHtml(String(u.message)):"";return`<li class="log-entry ${J}">
2506
+ ${u.map(g=>{let x=this._formatTimestamp(g&&g.timestamp),k=g&&g.iteration!==void 0&&g.iteration!==null?`i${this._escapeHtml(String(g.iteration))}`:"",_=g&&g.phase?String(g.phase):"",H=this._phaseClass(_),J=this._logLevelClass(g&&g.level),G=g&&g.message?this._escapeHtml(String(g.message)):"";return`<li class="log-entry ${J}">
2507
2507
  ${x?`<span class="log-time">${x}</span>`:""}
2508
2508
  ${k?`<span class="log-iter">${k}</span>`:""}
2509
- ${_?`<span class="log-phase ${M}">${this._escapeHtml(_)}</span>`:""}
2509
+ ${_?`<span class="log-phase ${H}">${this._escapeHtml(_)}</span>`:""}
2510
2510
  <span class="log-message">${G}</span>
2511
2511
  </li>`}).join("")}
2512
2512
  </ul>
@@ -2518,15 +2518,15 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
2518
2518
  <div class="modal-section">
2519
2519
  <h3 class="modal-section-title">Context Files</h3>
2520
2520
  <ul class="context-files-list">
2521
- ${n.map(u=>`<li class="mono">${this._escapeHtml(u)}</li>`).join("")}
2521
+ ${n.map(g=>`<li class="mono">${this._escapeHtml(g)}</li>`).join("")}
2522
2522
  </ul>
2523
2523
  </div>
2524
2524
  `:""}
2525
2525
 
2526
- ${g&&!l?`
2526
+ ${m&&!l?`
2527
2527
  <div class="modal-section">
2528
2528
  <h3 class="modal-section-title">Full Content</h3>
2529
- <pre class="modal-pre">${this._escapeHtml(g)}</pre>
2529
+ <pre class="modal-pre">${this._escapeHtml(m)}</pre>
2530
2530
  </div>
2531
2531
  `:""}
2532
2532
 
@@ -3565,8 +3565,8 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
3565
3565
  </div>
3566
3566
  <div class="kanban-tasks" data-status="${a.status}">
3567
3567
  ${s.length===0?'<div class="empty-column">No tasks</div>':""}
3568
- ${o.map(l=>{let c=String(l.id||""),p=this._expandedCards.has(c),h=this._selectedTasks.has(c);return`
3569
- <div class="task-card ${!e&&!l.fromServer?"draggable":""} ${l.isLocal?"local":""} ${p?"expanded":""} ${h?"selected":""}"
3568
+ ${o.map(l=>{let c=String(l.id||""),p=this._expandedCards.has(c),u=this._selectedTasks.has(c);return`
3569
+ <div class="task-card ${!e&&!l.fromServer?"draggable":""} ${l.isLocal?"local":""} ${p?"expanded":""} ${u?"selected":""}"
3570
3570
  data-task-id="${this._escapeHtml(c)}"
3571
3571
  tabindex="0"
3572
3572
  role="button"
@@ -3574,7 +3574,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
3574
3574
  ${!e&&!l.fromServer?'draggable="true"':""}>
3575
3575
  <div class="task-card-header">
3576
3576
  <div style="display:flex;align-items:center;gap:6px;">
3577
- ${this._bulkMode?`<div class="task-checkbox ${h?"checked":""}" data-check-id="${this._escapeHtml(c)}"></div>`:""}
3577
+ ${this._bulkMode?`<div class="task-checkbox ${u?"checked":""}" data-check-id="${this._escapeHtml(c)}"></div>`:""}
3578
3578
  <span class="task-id">${l.isLocal?"LOCAL":"#"+this._escapeHtml(c)}</span>
3579
3579
  </div>
3580
3580
  <div style="display:flex;align-items:center;gap:6px;">
@@ -3616,7 +3616,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
3616
3616
  </div>
3617
3617
  `}).join("")}
3618
3618
  </div>
3619
- `}}_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(r=>{r.addEventListener("click",()=>this._setFilter(r.dataset.filter))});let i=this.shadowRoot.getElementById("task-search");i&&i.addEventListener("input",r=>this._setSearch(r.target.value)),this.shadowRoot.querySelectorAll(".show-more-btn").forEach(r=>{r.addEventListener("click",()=>this._showMore(r.dataset.showMore))}),this.shadowRoot.querySelectorAll(".bulk-btn").forEach(r=>{r.addEventListener("click",()=>{let o=r.dataset.bulkAction;o==="delete"?this._bulkDelete():this._bulkMove(o)})}),this.shadowRoot.querySelectorAll(".add-task-btn").forEach(r=>{r.addEventListener("click",()=>{this._openAddTaskModal(r.dataset.status)})}),this.shadowRoot.querySelectorAll(".task-checkbox").forEach(r=>{r.addEventListener("click",o=>{o.stopPropagation(),this._toggleTaskSelection(r.dataset.checkId,o)})}),this.shadowRoot.querySelectorAll(".expand-toggle").forEach(r=>{r.addEventListener("click",o=>{o.stopPropagation(),this._toggleCardExpand(r.dataset.expandId)})}),this.shadowRoot.querySelectorAll(".task-card").forEach(r=>{let o=r.dataset.taskId,n=this._tasks.find(l=>l.id.toString()===o);n&&(r.addEventListener("click",l=>{if(this._bulkMode){this._toggleTaskSelection(o,l);return}this._openTaskDetail(n)}),r.addEventListener("keydown",l=>{l.key==="Enter"||l.key===" "?(l.preventDefault(),this._bulkMode?this._toggleTaskSelection(o,l):this._openTaskDetail(n)):(l.key==="ArrowDown"||l.key==="ArrowUp")&&(l.preventDefault(),this._navigateTaskCards(r,l.key==="ArrowDown"?"next":"prev"))}),r.classList.contains("draggable")&&(r.addEventListener("dragstart",l=>this._handleDragStart(l,n)),r.addEventListener("dragend",l=>this._handleDragEnd(l))))}),this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(r=>{r.addEventListener("dragover",o=>this._handleDragOver(o)),r.addEventListener("dragenter",o=>this._handleDragEnter(o)),r.addEventListener("dragleave",o=>this._handleDragLeave(o)),r.addEventListener("drop",o=>this._handleDrop(o,r.dataset.status))});let a=this.shadowRoot.getElementById("modal-close-btn");a&&a.addEventListener("click",()=>this._closeTaskDetail());let s=this.shadowRoot.getElementById("task-detail-overlay");s&&s.addEventListener("click",r=>{r.target===s&&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 X=class extends m{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._model={override:null,default:"sonnet",effective:"sonnet",notice:""},this._modelBusy=!1,this._startBusy=!1,this._startNotice="",this._specText="",this._api=null,this._state=U(),this._statusUpdateHandler=null,this._connectedHandler=null,this._disconnectedHandler=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._loadModel(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(f.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(f.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(f.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=v({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(f.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(f.CONNECTED,this._connectedHandler),this._api.addEventListener(f.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._poll=b({loadFn:()=>this._loadStatus(),intervalMs:3e3,sectionId:null,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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"}}async _triggerStart(){if(this._startBusy)return;let e=(this._specText||"").trim();if(!e){this._startNotice="Enter a spec or one-line brief to start a build.",this.render();return}if(!this._api||typeof this._api.startSession!="function"){this._startNotice="Start is not available on this server.",this.render();return}this._startBusy=!0,this._startNotice="Starting build...",this.render();try{let t=await this._api.startSession(e,{provider:this._status.provider||"claude"});if(t&&t.error)throw new Error(t.error);this._startBusy=!1,this._startNotice="",this._specText="",this._status.mode="running",this._status.connected=!0,this.render(),this._loadStatus(),this.dispatchEvent(new CustomEvent("session-start",{detail:{...this._status,pid:t&&t.pid,spec:t&&t.spec}}))}catch(t){console.error("Failed to start build:",t),this._startBusy=!1,this._startNotice=t&&t.message?`Could not start: ${t.message}`:"Could not start the build. Try again.",this.render()}}_onSpecInput(e){this._specText=e}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()}}async _loadModel(){if(!(!this._api||typeof this._api.getSessionModel!="function"))try{let e=await this._api.getSessionModel();e&&!e.error&&(this._model={...this._model,override:e.override??null,default:e.default||"sonnet",effective:e.effective||e.default||"sonnet"},this.render())}catch{}}async _onModelChange(e){if(this._modelBusy)return;this._modelBusy=!0;let t=e===""?null:e;try{let i=await this._api.setSessionModel(t);if(i&&i.error)throw new Error(i.error);this._model.override=t,this._model.notice=t?`Switching to ${t}. Applies from the next iteration, for the current run only.`:"Override cleared. Reverts to the tier mapping from the next iteration.",this._modelBusy=!1,await this._loadModel()}catch(i){console.error("Failed to set session model:",i),this._model.notice="Could not change the model. Try again.",this._modelBusy=!1,this.render()}}_renderModelControl(){let e=this._model.override||"",i=[{value:"",label:`Default (tier: ${this._escapeHtml(this._model.default)})`},{value:"haiku",label:"Haiku (fastest, cheapest)"},{value:"sonnet",label:"Sonnet (balanced)"},{value:"opus",label:"Opus (top coding)"},{value:"fable",label:"Fable 5 (2x Opus cost: $10/$50 per MTok)"}].map(s=>{let r=s.value===e?" selected":"";return`<option value="${this._escapeHtml(s.value)}"${r}>${this._escapeHtml(s.label)}</option>`}).join(""),a=this._model.effective==="fable";return`
3619
+ `}}_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(r=>{r.addEventListener("click",()=>this._setFilter(r.dataset.filter))});let i=this.shadowRoot.getElementById("task-search");i&&i.addEventListener("input",r=>this._setSearch(r.target.value)),this.shadowRoot.querySelectorAll(".show-more-btn").forEach(r=>{r.addEventListener("click",()=>this._showMore(r.dataset.showMore))}),this.shadowRoot.querySelectorAll(".bulk-btn").forEach(r=>{r.addEventListener("click",()=>{let o=r.dataset.bulkAction;o==="delete"?this._bulkDelete():this._bulkMove(o)})}),this.shadowRoot.querySelectorAll(".add-task-btn").forEach(r=>{r.addEventListener("click",()=>{this._openAddTaskModal(r.dataset.status)})}),this.shadowRoot.querySelectorAll(".task-checkbox").forEach(r=>{r.addEventListener("click",o=>{o.stopPropagation(),this._toggleTaskSelection(r.dataset.checkId,o)})}),this.shadowRoot.querySelectorAll(".expand-toggle").forEach(r=>{r.addEventListener("click",o=>{o.stopPropagation(),this._toggleCardExpand(r.dataset.expandId)})}),this.shadowRoot.querySelectorAll(".task-card").forEach(r=>{let o=r.dataset.taskId,n=this._tasks.find(l=>l.id.toString()===o);n&&(r.addEventListener("click",l=>{if(this._bulkMode){this._toggleTaskSelection(o,l);return}this._openTaskDetail(n)}),r.addEventListener("keydown",l=>{l.key==="Enter"||l.key===" "?(l.preventDefault(),this._bulkMode?this._toggleTaskSelection(o,l):this._openTaskDetail(n)):(l.key==="ArrowDown"||l.key==="ArrowUp")&&(l.preventDefault(),this._navigateTaskCards(r,l.key==="ArrowDown"?"next":"prev"))}),r.classList.contains("draggable")&&(r.addEventListener("dragstart",l=>this._handleDragStart(l,n)),r.addEventListener("dragend",l=>this._handleDragEnd(l))))}),this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(r=>{r.addEventListener("dragover",o=>this._handleDragOver(o)),r.addEventListener("dragenter",o=>this._handleDragEnter(o)),r.addEventListener("dragleave",o=>this._handleDragLeave(o)),r.addEventListener("drop",o=>this._handleDrop(o,r.dataset.status))});let a=this.shadowRoot.getElementById("modal-close-btn");a&&a.addEventListener("click",()=>this._closeTaskDetail());let s=this.shadowRoot.getElementById("task-detail-overlay");s&&s.addEventListener("click",r=>{r.target===s&&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 X=class extends v{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._model={override:null,default:"sonnet",effective:"sonnet",notice:""},this._modelBusy=!1,this._startBusy=!1,this._startNotice="",this._specText="",this._api=null,this._state=U(),this._statusUpdateHandler=null,this._connectedHandler=null,this._disconnectedHandler=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._loadModel(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._teardownApiListeners()}_teardownApiListeners(){this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(f.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(f.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(f.DISCONNECTED,this._disconnectedHandler))}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._teardownApiListeners(),this._setupApi(),this._loadStatus(),this._loadModel()),e==="theme"&&this._applyTheme(),e==="compact"&&this.render())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({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(f.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(f.CONNECTED,this._connectedHandler),this._api.addEventListener(f.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){let e=this._api;try{let t=await e.getStatus();if(e!==this._api)return;this._updateFromStatus(t)}catch{if(e!==this._api)return;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._poll=b({loadFn:()=>this._loadStatus(),intervalMs:3e3,sectionId:null,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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"}}async _triggerStart(){if(this._startBusy)return;let e=(this._specText||"").trim();if(!e){this._startNotice="Enter a spec or one-line brief to start a build.",this.render();return}if(!this._api||typeof this._api.startSession!="function"){this._startNotice="Start is not available on this server.",this.render();return}this._startBusy=!0,this._startNotice="Starting build...",this.render();try{let t=await this._api.startSession(e,{provider:this._status.provider||"claude"});if(t&&t.error)throw new Error(t.error);this._startBusy=!1,this._startNotice="",this._specText="",this._status.mode="running",this._status.connected=!0,this.render(),this._loadStatus(),this.dispatchEvent(new CustomEvent("session-start",{detail:{...this._status,pid:t&&t.pid,spec:t&&t.spec}}))}catch(t){console.error("Failed to start build:",t),this._startBusy=!1,this._startNotice=t&&t.message?`Could not start: ${t.message}`:"Could not start the build. Try again.",this.render()}}_onSpecInput(e){this._specText=e}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()}}async _loadModel(){if(!this._api||typeof this._api.getSessionModel!="function")return;let e=this._api;try{let t=await e.getSessionModel();if(e!==this._api)return;t&&!t.error&&(this._model={...this._model,override:t.override??null,default:t.default||"sonnet",effective:t.effective||t.default||"sonnet"},this.render())}catch{}}async _onModelChange(e){if(this._modelBusy)return;this._modelBusy=!0;let t=e===""?null:e;try{let i=await this._api.setSessionModel(t);if(i&&i.error)throw new Error(i.error);this._model.override=t,this._model.notice=t?`Switching to ${t}. Applies from the next iteration, for the current run only.`:"Override cleared. Reverts to the tier mapping from the next iteration.",this._modelBusy=!1,await this._loadModel()}catch(i){console.error("Failed to set session model:",i),this._model.notice="Could not change the model. Try again.",this._modelBusy=!1,this.render()}}_renderModelControl(){let e=this._model.override||"",i=[{value:"",label:`Default (tier: ${this._escapeHtml(this._model.default)})`},{value:"haiku",label:"Haiku (fastest, cheapest)"},{value:"sonnet",label:"Sonnet (balanced)"},{value:"opus",label:"Opus (top coding)"},{value:"fable",label:"Fable 5 (2x Opus cost: $10/$50 per MTok)"}].map(s=>{let r=s.value===e?" selected":"";return`<option value="${this._escapeHtml(s.value)}"${r}>${this._escapeHtml(s.label)}</option>`}).join(""),a=this._model.effective==="fable";return`
3620
3620
  <div class="model-control">
3621
3621
  <div class="model-row">
3622
3622
  <label for="model-select">Model</label>
@@ -4019,10 +4019,10 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
4019
4019
  </div>
4020
4020
  </div>
4021
4021
  </div>
4022
- `,c=this.shadowRoot.activeElement,p=c&&c.id==="spec-input",h=p?c.selectionStart:null,g=p?c.selectionEnd:null;if(this.shadowRoot.innerHTML=`
4022
+ `,c=this.shadowRoot.activeElement,p=c&&c.id==="spec-input",u=p?c.selectionStart:null,m=p?c.selectionEnd:null;if(this.shadowRoot.innerHTML=`
4023
4023
  ${o}
4024
4024
  ${e?n:l}
4025
- `,this._attachEventListeners(),p){let u=this.shadowRoot.getElementById("spec-input");if(u&&!u.disabled){u.focus();try{u.setSelectionRange(h,g)}catch{}}}}_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());let s=this.shadowRoot.getElementById("model-select");if(s){let o=()=>{this._modelInteracting=!1,this._renderPending&&(this._renderPending=!1,this.render())};s.addEventListener("mousedown",()=>{this._modelInteracting=!0}),s.addEventListener("focus",()=>{this._modelInteracting=!0}),s.addEventListener("blur",o),s.addEventListener("change",n=>{this._modelInteracting=!1,this._renderPending=!1,this._onModelChange(n.target.value)})}let r=this.shadowRoot.getElementById("spec-input");r&&r.addEventListener("input",o=>this._onSpecInput(o.target.value))}};customElements.get("loki-session-control")||customElements.define("loki-session-control",X);var rt={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"}},Z=class extends m{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,this._apiLastCount=0,this._apiLastSig=null,this._fileLastSize=0,this._fileLastSig=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(f.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=v({baseUrl:e}),this._logMessageHandler=t=>this._addLog(t.detail),this._api.addEventListener(f.LOG_MESSAGE,this._logMessageHandler)}_startLogPolling(){let e=this.getAttribute("log-file");e?this._pollLogFile(e):this._pollApiLogs()}async _pollApiLogs(){await this._apiLogPollTick(),this._poll=b({loadFn:()=>this._apiLogPollTick(),intervalMs:5e3,element:this,immediate:!1})}async _apiLogPollTick(){try{let e=await this._api.getLogs(200);if(!Array.isArray(e))return;let t=e.length?`${e.length}:${e[e.length-1]?.timestamp||""}:${e[e.length-1]?.message||""}`:"0";if(t===this._apiLastSig)return;if(this._apiLastSig=t,e.length>this._apiLastCount){let i=e.slice(this._apiLastCount);for(let a of i)a.message&&a.message.trim()&&this._addLog({message:a.message,level:a.level||"info",timestamp:a.timestamp||new Date().toLocaleTimeString()})}else e.length<this._apiLastCount&&(this._apiLastCount=0);this._apiLastCount=e.length}catch{}}async _pollLogFile(e){await this._fileLogPollTick(e),this._poll=b({loadFn:()=>this._fileLogPollTick(e),intervalMs:1e3,element:this,immediate:!1})}async _fileLogPollTick(e){try{let t=await fetch(`${e}?t=${Date.now()}`,{credentials:"include"});if(!t.ok)return;let i=await t.text(),a=`${i.length}`;if(a===this._fileLastSig)return;this._fileLastSig=a;let s=i.split(`
4025
+ `,this._attachEventListeners(),p){let g=this.shadowRoot.getElementById("spec-input");if(g&&!g.disabled){g.focus();try{g.setSelectionRange(u,m)}catch{}}}}_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());let s=this.shadowRoot.getElementById("model-select");if(s){let o=()=>{this._modelInteracting=!1,this._renderPending&&(this._renderPending=!1,this.render())};s.addEventListener("mousedown",()=>{this._modelInteracting=!0}),s.addEventListener("focus",()=>{this._modelInteracting=!0}),s.addEventListener("blur",o),s.addEventListener("change",n=>{this._modelInteracting=!1,this._renderPending=!1,this._onModelChange(n.target.value)})}let r=this.shadowRoot.getElementById("spec-input");r&&r.addEventListener("input",o=>this._onSpecInput(o.target.value))}};customElements.get("loki-session-control")||customElements.define("loki-session-control",X);var rt={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"}},Z=class extends v{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,this._apiLastCount=0,this._apiLastSig=null,this._fileLastSize=0,this._fileLastSig=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._teardownApiListeners()}_teardownApiListeners(){this._api&&this._logMessageHandler&&this._api.removeEventListener(f.LOG_MESSAGE,this._logMessageHandler)}attributeChangedCallback(e,t,i){if(t!==i)switch(e){case"api-url":this._api&&(this._teardownApiListeners(),this._logs=[],this._apiLastCount=0,this._apiLastSig=null,this._setupApi(),this.render());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=h({baseUrl:e}),this._logMessageHandler=t=>this._addLog(t.detail),this._api.addEventListener(f.LOG_MESSAGE,this._logMessageHandler)}_startLogPolling(){let e=this.getAttribute("log-file");e?this._pollLogFile(e):this._pollApiLogs()}async _pollApiLogs(){await this._apiLogPollTick(),this._poll=b({loadFn:()=>this._apiLogPollTick(),intervalMs:5e3,element:this,immediate:!1})}async _apiLogPollTick(){try{let e=await this._api.getLogs(200);if(!Array.isArray(e))return;let t=e.length?`${e.length}:${e[e.length-1]?.timestamp||""}:${e[e.length-1]?.message||""}`:"0";if(t===this._apiLastSig)return;if(this._apiLastSig=t,e.length>this._apiLastCount){let i=e.slice(this._apiLastCount);for(let a of i)a.message&&a.message.trim()&&this._addLog({message:a.message,level:a.level||"info",timestamp:a.timestamp||new Date().toLocaleTimeString()})}else e.length<this._apiLastCount&&(this._apiLastCount=0);this._apiLastCount=e.length}catch{}}async _pollLogFile(e){await this._fileLogPollTick(e),this._poll=b({loadFn:()=>this._fileLogPollTick(e),intervalMs:1e3,element:this,immediate:!1})}async _fileLogPollTick(e){try{let t=await fetch(`${e}?t=${Date.now()}`,{credentials:"include"});if(!t.ok)return;let i=await t.text(),a=`${i.length}`;if(a===this._fileLastSig)return;this._fileLastSig=a;let s=i.split(`
4026
4026
  `);if(s.length>this._fileLastSize){let r=s.slice(this._fileLastSize);for(let o of r)o.trim()&&this._addLog(this._parseLine(o))}else s.length<this._fileLastSize&&(this._fileLastSize=0);this._fileLastSize=s.length}catch{}}_stopLogPolling(){this._poll&&(this._poll.stop(),this._poll=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(`
4027
4027
  `),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=rt[i.level]||rt.info;return`
4028
4028
  <div class="log-line">
@@ -4223,10 +4223,10 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
4223
4223
  ${this._logs.length} lines (${this._getFilteredLogs().length} shown)
4224
4224
  </div>
4225
4225
  </div>
4226
- `,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",Z);var Lt=[{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"}],ee=class extends m{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=v({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:
4226
+ `,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",Z);var Lt=[{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"}],ee=class extends v{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=h({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=h({baseUrl:e})}async _loadData(){let e=this._api;this._loading=!0,this._error=null,this.render();try{let[t,i,a]=await Promise.allSettled([e.getMemorySummary(),e.getTokenEconomics(),e.getMemoryStats()]);if(e!==this._api||(this._summary=t.status==="fulfilled"?t.value:null,this._tokenEconomics=i.status==="fulfilled"?i.value:null,this._stats=a.status==="fulfilled"?a.value:null,await this._loadTabData(),e!==this._api))return}catch(t){if(e!==this._api)return;this._error=t.message||"Failed to load memory data"}this._loading=!1,this.render()}async _loadTabData(){let e=this._api;switch(this._activeTab){case"episodes":{let t=await e.listEpisodes({limit:50}).catch(()=>[]);if(e!==this._api)return;this._episodes=t;break}case"patterns":{let t=await e.listPatterns().catch(()=>[]);if(e!==this._api)return;this._patterns=t;break}case"skills":{let t=await e.listSkills().catch(()=>[]);if(e!==this._api)return;this._skills=t;break}}}_setTab(e){this._activeTab!==e&&(this._activeTab=e,this._selectedItem=null,this._loadTabData().then(()=>this.render()))}async _selectEpisode(e){let t=this._api;try{this._lastFocusedElement=this.shadowRoot.activeElement;let i=await t.getEpisode(e);if(t!==this._api)return;this._selectedItem=i,this.dispatchEvent(new CustomEvent("episode-select",{detail:this._selectedItem})),this.render(),this._focusDetailPanel()}catch(i){console.error("Failed to load episode:",i)}}async _selectPattern(e){let t=this._api;try{this._lastFocusedElement=this.shadowRoot.activeElement;let i=await t.getPattern(e);if(t!==this._api)return;this._selectedItem=i,this.dispatchEvent(new CustomEvent("pattern-select",{detail:this._selectedItem})),this.render(),this._focusDetailPanel()}catch(i){console.error("Failed to load pattern:",i)}}async _selectSkill(e){let t=this._api;try{this._lastFocusedElement=this.shadowRoot.activeElement;let i=await t.getSkill(e);if(t!==this._api)return;this._selectedItem=i,this.dispatchEvent(new CustomEvent("skill-select",{detail:this._selectedItem})),this.render(),this._focusDetailPanel()}catch(i){console.error("Failed to load skill:",i)}}_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:
4227
4227
  - Patterns created: ${e.patternsCreated}
4228
4228
  - Patterns merged: ${e.patternsMerged}
4229
- - 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`
4229
+ - Episodes processed: ${e.episodesProcessed}`),this._loadData()}catch(e){alert("Consolidation failed: "+e.message)}}async _executeSearch(){let e=this._searchQuery.trim();if(!e)return;let t=this._api;this._searchLoading=!0,this._searchError=null,this.render();try{let i=await t.searchMemory(e,this._searchCollection,20);if(t!==this._api)return;this._searchResults=i.results||[]}catch(i){if(t!==this._api)return;this._searchError=i.message||"Search failed",this._searchResults=[]}this._searchLoading=!1,this.render(),requestAnimationFrame(()=>{let i=this.shadowRoot.getElementById("memory-search-input");i&&i.focus()})}_renderSearch(){let e=["all","episodes","patterns","skills"];return`
4230
4230
  <div class="search-panel">
4231
4231
  <div class="search-bar">
4232
4232
  <input type="text" id="memory-search-input" class="search-input"
@@ -4399,15 +4399,15 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
4399
4399
  `}_renderEpisodes(){return this._episodes.length===0?'<div class="empty-state">No episodes recorded yet</div>':`
4400
4400
  <div class="item-list" role="list" aria-label="Episodes list">
4401
4401
  ${this._episodes.map(e=>`
4402
- <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"}">
4402
+ <div class="item-card" data-id="${this._escapeHtml(e.id)}" data-type="episode" tabindex="0" role="listitem" aria-label="Episode ${this._escapeHtml(e.id)}: ${this._escapeHtml(e.taskId||"Task")}, outcome ${this._escapeHtml(e.outcome||"unknown")}">
4403
4403
  <div class="item-header">
4404
- <span class="item-id mono">${e.id}</span>
4405
- <span class="item-outcome ${e.outcome?.toLowerCase()}">${e.outcome||"unknown"}</span>
4404
+ <span class="item-id mono">${this._escapeHtml(e.id)}</span>
4405
+ <span class="item-outcome ${this._escapeHtml(e.outcome?.toLowerCase())}">${this._escapeHtml(e.outcome||"unknown")}</span>
4406
4406
  </div>
4407
4407
  <div class="item-title">${this._escapeHtml(e.taskId||"Task")}</div>
4408
4408
  <div class="item-meta">
4409
- <span>${e.agent||"unknown agent"}</span>
4410
- <span>${e.phase||"unknown phase"}</span>
4409
+ <span>${this._escapeHtml(e.agent||"unknown agent")}</span>
4410
+ <span>${this._escapeHtml(e.phase||"unknown phase")}</span>
4411
4411
  <span>${new Date(e.timestamp).toLocaleString()}</span>
4412
4412
  </div>
4413
4413
  </div>
@@ -4416,9 +4416,9 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
4416
4416
  `}_renderPatterns(){return this._patterns.length===0?'<div class="empty-state">No patterns discovered yet</div>':`
4417
4417
  <div class="item-list" role="list" aria-label="Patterns list">
4418
4418
  ${this._patterns.map(e=>`
4419
- <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">
4419
+ <div class="item-card" data-id="${this._escapeHtml(e.id)}" data-type="pattern" tabindex="0" role="listitem" aria-label="Pattern: ${this._escapeHtml(e.pattern)}, ${(e.confidence*100).toFixed(0)} percent confidence">
4420
4420
  <div class="item-header">
4421
- <span class="item-category">${e.category||"general"}</span>
4421
+ <span class="item-category">${this._escapeHtml(e.category||"general")}</span>
4422
4422
  <span class="confidence-badge">${(e.confidence*100).toFixed(0)}%</span>
4423
4423
  </div>
4424
4424
  <div class="item-title">${this._escapeHtml(e.pattern)}</div>
@@ -4431,9 +4431,9 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
4431
4431
  `}_renderSkills(){return this._skills.length===0?'<div class="empty-state">No skills learned yet</div>':`
4432
4432
  <div class="item-list" role="list" aria-label="Skills list">
4433
4433
  ${this._skills.map(e=>`
4434
- <div class="item-card" data-id="${e.id}" data-type="skill" tabindex="0" role="listitem" aria-label="Skill: ${this._escapeHtml(e.name)}">
4434
+ <div class="item-card" data-id="${this._escapeHtml(e.id)}" data-type="skill" tabindex="0" role="listitem" aria-label="Skill: ${this._escapeHtml(e.name)}">
4435
4435
  <div class="item-header">
4436
- <span class="item-id mono">${e.id}</span>
4436
+ <span class="item-id mono">${this._escapeHtml(e.id)}</span>
4437
4437
  </div>
4438
4438
  <div class="item-title">${this._escapeHtml(e.name)}</div>
4439
4439
  <div class="item-description">${this._escapeHtml(e.description||"")}</div>
@@ -4443,25 +4443,25 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
4443
4443
  `}_renderDetail(){if(!this._selectedItem)return"";let e=this._selectedItem;return e.actionLog!==void 0?`
4444
4444
  <div class="detail-panel">
4445
4445
  <div class="detail-header">
4446
- <h3>Episode: ${e.id}</h3>
4446
+ <h3>Episode: ${this._escapeHtml(e.id)}</h3>
4447
4447
  <button class="close-btn" id="close-detail">&times;</button>
4448
4448
  </div>
4449
4449
  <div class="detail-body">
4450
4450
  <div class="detail-row">
4451
4451
  <span class="detail-label">Task</span>
4452
- <span class="detail-value">${e.taskId||"--"}</span>
4452
+ <span class="detail-value">${this._escapeHtml(e.taskId||"--")}</span>
4453
4453
  </div>
4454
4454
  <div class="detail-row">
4455
4455
  <span class="detail-label">Agent</span>
4456
- <span class="detail-value">${e.agent||"--"}</span>
4456
+ <span class="detail-value">${this._escapeHtml(e.agent||"--")}</span>
4457
4457
  </div>
4458
4458
  <div class="detail-row">
4459
4459
  <span class="detail-label">Phase</span>
4460
- <span class="detail-value">${e.phase||"--"}</span>
4460
+ <span class="detail-value">${this._escapeHtml(e.phase||"--")}</span>
4461
4461
  </div>
4462
4462
  <div class="detail-row">
4463
4463
  <span class="detail-label">Outcome</span>
4464
- <span class="detail-value outcome ${e.outcome?.toLowerCase()}">${e.outcome||"--"}</span>
4464
+ <span class="detail-value outcome ${this._escapeHtml(e.outcome?.toLowerCase())}">${this._escapeHtml(e.outcome||"--")}</span>
4465
4465
  </div>
4466
4466
  <div class="detail-row">
4467
4467
  <span class="detail-label">Duration</span>
@@ -4483,8 +4483,8 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
4483
4483
  <div class="action-log">
4484
4484
  ${e.actionLog.map(t=>`
4485
4485
  <div class="action-entry">
4486
- <span class="action-time">+${t.t}s</span>
4487
- <span class="action-type">${t.action}</span>
4486
+ <span class="action-time">+${this._escapeHtml(t.t)}s</span>
4487
+ <span class="action-type">${this._escapeHtml(t.action)}</span>
4488
4488
  <span class="action-target">${this._escapeHtml(t.target)}</span>
4489
4489
  </div>
4490
4490
  `).join("")}
@@ -4496,13 +4496,13 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
4496
4496
  `:e.conditions!==void 0?`
4497
4497
  <div class="detail-panel">
4498
4498
  <div class="detail-header">
4499
- <h3>Pattern: ${e.id}</h3>
4499
+ <h3>Pattern: ${this._escapeHtml(e.id)}</h3>
4500
4500
  <button class="close-btn" id="close-detail">&times;</button>
4501
4501
  </div>
4502
4502
  <div class="detail-body">
4503
4503
  <div class="detail-row">
4504
4504
  <span class="detail-label">Category</span>
4505
- <span class="detail-value">${e.category||"general"}</span>
4505
+ <span class="detail-value">${this._escapeHtml(e.category||"general")}</span>
4506
4506
  </div>
4507
4507
  <div class="detail-row">
4508
4508
  <span class="detail-label">Confidence</span>
@@ -4575,7 +4575,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
4575
4575
  `:""}
4576
4576
  </div>
4577
4577
  </div>
4578
- `:""}_escapeHtml(e){if(!e)return"";let t=document.createElement("div");return t.textContent=e,t.innerHTML}render(){let e=`
4578
+ `:""}_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=`
4579
4579
  <style>
4580
4580
  ${this.getBaseStyles()}
4581
4581
 
@@ -5111,7 +5111,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
5111
5111
  ${t}
5112
5112
  </div>
5113
5113
  </div>
5114
- `,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",ee);var zt=[{id:"1h",label:"1 Hour",hours:1},{id:"24h",label:"24 Hours",hours:24},{id:"7d",label:"7 Days",hours:168},{id:"30d",label:"30 Days",hours:720}],Dt=[{id:"all",label:"All Signals"},{id:"user_preference",label:"User Preferences"},{id:"error_pattern",label:"Error Patterns"},{id:"success_pattern",label:"Success Patterns"},{id:"tool_efficiency",label:"Tool Efficiency"},{id:"context_relevance",label:"Context Relevance"}],Mt=[{id:"all",label:"All Sources"},{id:"cli",label:"CLI"},{id:"api",label:"API"},{id:"vscode",label:"VS Code"},{id:"mcp",label:"MCP"},{id:"dashboard",label:"Dashboard"}],te=class extends m{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=v({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`
5114
+ `,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),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 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",ee);var zt=[{id:"1h",label:"1 Hour",hours:1},{id:"24h",label:"24 Hours",hours:24},{id:"7d",label:"7 Days",hours:168},{id:"30d",label:"30 Days",hours:720}],Dt=[{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"}],Ht=[{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"}],te=class extends v{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=h({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=h({baseUrl:e})}async _loadData(){this._loading=!0,this._error=null,this.render();let e=this._api;try{let t={timeRange:this._timeRange,signalType:this._signalType!=="all"?this._signalType:void 0,source:this._source!=="all"?this._source:void 0},[i,a,s]=await Promise.all([e.getLearningMetrics(t).catch(()=>null),e.getLearningTrends(t).catch(()=>null),e.getLearningSignals({...t,limit:50}).catch(()=>[])]);if(e!==this._api)return;this._metrics=i,this._trends=a,this._signals=s||[]}catch(t){if(e!==this._api)return;this._error=t.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){return e==null?"":String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}_renderFilters(){return`
5115
5115
  <div class="filters">
5116
5116
  <div class="filter-group">
5117
5117
  <label>Time Range</label>
@@ -5132,7 +5132,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
5132
5132
  <div class="filter-group">
5133
5133
  <label>Source</label>
5134
5134
  <select id="source-select" class="filter-select">
5135
- ${Mt.map(e=>`
5135
+ ${Ht.map(e=>`
5136
5136
  <option value="${e.id}" ${this._source===e.id?"selected":""}>${e.label}</option>
5137
5137
  `).join("")}
5138
5138
  </select>
@@ -5156,7 +5156,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
5156
5156
  <div class="signal-breakdown">
5157
5157
  ${Object.entries(t||{}).map(([s,r])=>`
5158
5158
  <div class="breakdown-item">
5159
- <span class="breakdown-label">${s.replace("_"," ")}</span>
5159
+ <span class="breakdown-label">${this._escapeHtml(s.replace("_"," "))}</span>
5160
5160
  <span class="breakdown-value">${this._formatNumber(r)}</span>
5161
5161
  </div>
5162
5162
  `).join("")}
@@ -5172,7 +5172,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
5172
5172
  <div class="signal-breakdown">
5173
5173
  ${Object.entries(i||{}).map(([s,r])=>`
5174
5174
  <div class="breakdown-item">
5175
- <span class="breakdown-label source-badge ${s}">${s}</span>
5175
+ <span class="breakdown-label source-badge ${this._escapeHtml(s)}">${this._escapeHtml(s)}</span>
5176
5176
  <span class="breakdown-value">${this._formatNumber(r)}</span>
5177
5177
  </div>
5178
5178
  `).join("")}
@@ -5218,7 +5218,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
5218
5218
  <div class="trend-chart">
5219
5219
  <div class="chart-header">
5220
5220
  <span class="chart-title">Signal Volume Over Time</span>
5221
- <span class="chart-subtitle">${this._trends.period}</span>
5221
+ <span class="chart-subtitle">${this._escapeHtml(this._trends.period)}</span>
5222
5222
  </div>
5223
5223
  <svg class="chart-svg" viewBox="0 0 ${a} ${i}">
5224
5224
  <!-- Grid lines -->
@@ -5236,8 +5236,8 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
5236
5236
  </svg>
5237
5237
  <div class="chart-labels">
5238
5238
  ${e.length>0?`
5239
- <span class="chart-label-start">${e[0].label}</span>
5240
- <span class="chart-label-end">${e[e.length-1].label}</span>
5239
+ <span class="chart-label-start">${this._escapeHtml(e[0].label)}</span>
5240
+ <span class="chart-label-end">${this._escapeHtml(e[e.length-1].label)}</span>
5241
5241
  `:""}
5242
5242
  </div>
5243
5243
  </div>
@@ -5251,7 +5251,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
5251
5251
  </div>
5252
5252
  <div class="list-items" role="list">
5253
5253
  ${(e||[]).slice(0,5).map(s=>`
5254
- <div class="list-item" data-type="preference" data-id="${s.preference_key}" tabindex="0" role="listitem">
5254
+ <div class="list-item" data-type="preference" data-id="${this._escapeHtml(s.preference_key)}" tabindex="0" role="listitem">
5255
5255
  <div class="item-main">
5256
5256
  <span class="item-key">${this._escapeHtml(s.preference_key)}</span>
5257
5257
  <span class="item-value">${this._escapeHtml(String(s.preferred_value))}</span>
@@ -5273,7 +5273,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
5273
5273
  </div>
5274
5274
  <div class="list-items" role="list">
5275
5275
  ${(t||[]).slice(0,5).map(s=>`
5276
- <div class="list-item error-item" data-type="error_pattern" data-id="${s.error_type}" tabindex="0" role="listitem">
5276
+ <div class="list-item error-item" data-type="error_pattern" data-id="${this._escapeHtml(s.error_type)}" tabindex="0" role="listitem">
5277
5277
  <div class="item-main">
5278
5278
  <span class="item-key">${this._escapeHtml(s.error_type)}</span>
5279
5279
  <span class="resolution-rate ${s.resolution_rate>.5?"good":"poor"}">${this._formatPercent(s.resolution_rate)} resolved</span>
@@ -5295,7 +5295,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
5295
5295
  </div>
5296
5296
  <div class="list-items" role="list">
5297
5297
  ${(i||[]).slice(0,5).map(s=>`
5298
- <div class="list-item success-item" data-type="success_pattern" data-id="${s.pattern_name}" tabindex="0" role="listitem">
5298
+ <div class="list-item success-item" data-type="success_pattern" data-id="${this._escapeHtml(s.pattern_name)}" tabindex="0" role="listitem">
5299
5299
  <div class="item-main">
5300
5300
  <span class="item-key">${this._escapeHtml(s.pattern_name)}</span>
5301
5301
  <span class="item-duration">${this._formatDuration(s.avg_duration_seconds)}</span>
@@ -5317,7 +5317,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
5317
5317
  </div>
5318
5318
  <div class="list-items" role="list">
5319
5319
  ${(a||[]).slice(0,5).map((s,r)=>`
5320
- <div class="list-item tool-item" data-type="tool_efficiency" data-id="${s.tool_name}" tabindex="0" role="listitem">
5320
+ <div class="list-item tool-item" data-type="tool_efficiency" data-id="${this._escapeHtml(s.tool_name)}" tabindex="0" role="listitem">
5321
5321
  <div class="item-rank">#${r+1}</div>
5322
5322
  <div class="item-main">
5323
5323
  <span class="item-key">${this._escapeHtml(s.tool_name)}</span>
@@ -5341,13 +5341,13 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
5341
5341
  <div class="signals-list">
5342
5342
  ${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`
5343
5343
  <div class="signal-item">
5344
- <div class="signal-type ${i}">${i.replace("_"," ")}</div>
5344
+ <div class="signal-type ${this._escapeHtml(i)}">${this._escapeHtml(i.replace("_"," "))}</div>
5345
5345
  <div class="signal-content">
5346
5346
  <span class="signal-action">${this._escapeHtml(a)}</span>
5347
- <span class="signal-source">${s}</span>
5347
+ <span class="signal-source">${this._escapeHtml(s)}</span>
5348
5348
  </div>
5349
5349
  <div class="signal-meta">
5350
- <span class="signal-outcome ${r}">${r}</span>
5350
+ <span class="signal-outcome ${this._escapeHtml(r)}">${this._escapeHtml(r)}</span>
5351
5351
  <span class="signal-time">${o}</span>
5352
5352
  </div>
5353
5353
  </div>`}).join("")}
@@ -5452,7 +5452,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
5452
5452
  `;break}return`
5453
5453
  <div class="detail-panel">
5454
5454
  <div class="detail-header">
5455
- <h3>${e.replace("_"," ").replace(/\b\w/g,a=>a.toUpperCase())}</h3>
5455
+ <h3>${this._escapeHtml(e.replace("_"," ").replace(/\b\w/g,a=>a.toUpperCase()))}</h3>
5456
5456
  <button class="close-btn" id="close-detail">&times;</button>
5457
5457
  </div>
5458
5458
  <div class="detail-body">
@@ -5460,7 +5460,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
5460
5460
  <div class="detail-row">
5461
5461
  <span class="detail-label">Sources</span>
5462
5462
  <div class="source-tags">
5463
- ${(t.sources||[]).map(a=>`<span class="source-badge ${a}">${a}</span>`).join("")}
5463
+ ${(t.sources||[]).map(a=>`<span class="source-badge ${this._escapeHtml(a)}">${this._escapeHtml(a)}</span>`).join("")}
5464
5464
  </div>
5465
5465
  </div>
5466
5466
  <div class="detail-row">
@@ -6097,7 +6097,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
6097
6097
  font-size: 12px;
6098
6098
  }
6099
6099
  </style>
6100
- `,t;this._loading?t='<div class="loading">Loading learning metrics...</div>':this._error?t=`<div class="error-state">Error: ${this._error}</div>`:t=`
6100
+ `,t;this._loading?t='<div class="loading">Loading learning metrics...</div>':this._error?t=`<div class="error-state">Error: ${this._escapeHtml(this._error)}</div>`:t=`
6101
6101
  <div class="content-main">
6102
6102
  ${this._renderSummaryCards()}
6103
6103
  ${this._renderTrendChart()}
@@ -6123,7 +6123,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
6123
6123
  ${t}
6124
6124
  </div>
6125
6125
  </div>
6126
- `,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",te);var Rt=[{id:"overview",label:"Overview"},{id:"decisions",label:"Decision Log"},{id:"convergence",label:"Convergence"},{id:"agents",label:"Agents"}],ie=class extends m{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=v({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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=`
6126
+ `,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",te);var Mt=[{id:"overview",label:"Overview"},{id:"decisions",label:"Decision Log"},{id:"convergence",label:"Convergence"},{id:"agents",label:"Agents"}],ie=class extends v{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=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null),this._pendingRaf&&(cancelAnimationFrame(this._pendingRaf),this._pendingRaf=null)}async _loadData(){let e=this._api;try{let[i,a,s,r]=await Promise.allSettled([e._get("/api/council/state"),e._get("/api/council/verdicts"),e._get("/api/council/convergence"),e._get("/api/agents")]);if(e!==this._api)return;i.status==="fulfilled"&&(this._councilState=i.value),a.status==="fulfilled"&&(this._verdicts=a.value.verdicts||[]),s.status==="fulfilled"&&(this._convergence=s.value.dataPoints||[]),r.status==="fulfilled"&&(this._agents=Array.isArray(r.value)?r.value:[]),this._error=null}catch(i){if(e!==this._api)return;this._error=i.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(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=`
6127
6127
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
6128
6128
  <div class="council-dashboard">
6129
6129
  <div class="council-header">
@@ -6137,7 +6137,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
6137
6137
  </div>
6138
6138
 
6139
6139
  <div class="tabs">
6140
- ${Rt.map(t=>`
6140
+ ${Mt.map(t=>`
6141
6141
  <button
6142
6142
  class="tab ${this._activeTab===t.id?"active":""}"
6143
6143
  data-tab="${t.id}"
@@ -6710,7 +6710,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
6710
6710
  color: var(--loki-error);
6711
6711
  font-size: 12px;
6712
6712
  }
6713
- `}};customElements.get("loki-council-dashboard")||customElements.define("loki-council-dashboard",ie);var ot={critical:0,major:1,minor:2},Ht={critical:"var(--loki-status-error, #ef4444)",major:"var(--loki-status-warning, #f59e0b)",minor:"var(--loki-text-muted, #71717a)"},ae=class extends m{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=v({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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`
6713
+ `}};customElements.get("loki-council-dashboard")||customElements.define("loki-council-dashboard",ie);var ot={critical:0,major:1,minor:2},Rt={critical:"var(--loki-status-error, #ef4444)",major:"var(--loki-status-warning, #f59e0b)",minor:"var(--loki-text-muted, #71717a)"},ae=class extends v{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=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let[t,i]=await Promise.all([e.getChecklist(),e.getChecklistWaivers().catch(()=>null)]);if(e!==this._api)return;let a=JSON.stringify(i),s=JSON.stringify(t)+a;if(s===this._lastDataHash)return;this._lastDataHash=s,this._checklist=t,this._waivers=i&&i.waivers?i.waivers.filter(r=>r.active):[],this._error=null,this.render()}catch(t){if(e!==this._api)return;this._error=`Failed to load checklist: ${t.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)return;let i=this._api;try{if(await i.addChecklistWaiver(e,t),i!==this._api)return;this._lastDataHash=null,await this._loadData()}catch(a){if(i!==this._api)return;this._error=`Failed to add waiver: ${a.message}`,this.render()}}async _unwaiveItem(e){let t=this._api;try{if(await t.removeChecklistWaiver(e),t!==this._api)return;this._lastDataHash=null,await this._loadData()}catch(i){if(t!==this._api)return;this._error=`Failed to remove waiver: ${i.message}`,this.render()}}_toggleCategory(e){this._expandedCategories.has(e)?this._expandedCategories.delete(e):this._expandedCategories.add(e),this.render()}_getStyles(){return`
6714
6714
  .checklist-viewer {
6715
6715
  padding: 16px;
6716
6716
  font-family: var(--loki-font-family, system-ui, -apple-system, sans-serif);
@@ -6999,15 +6999,15 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
6999
6999
  </div>
7000
7000
  ${i?`<div class="category-body">${this._renderItems(a)}</div>`:""}
7001
7001
  </div>
7002
- `}).join(""):this._renderEmpty()}_renderItems(e){return e?.length?[...e].sort((i,a)=>(ot[i.priority]??2)-(ot[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=Ht[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>`),`
7002
+ `}).join(""):this._renderEmpty()}_renderItems(e){return e?.length?[...e].sort((i,a)=>(ot[i.priority]??2)-(ot[a.priority]??2)).map(i=>{let a=i.status==="verified"?"status-verified":i.status==="failing"?"status-failing":"status-pending",s=["critical","major","minor"].includes(i.priority)?i.priority:"minor",r=Rt[s],o=i.verification||[],n=this._getWaiverForItem(i.id),l=!!n,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>`),`
7003
7003
  <div class="item">
7004
7004
  <div class="item-status ${a}"></div>
7005
7005
  <div class="item-title">${this._escapeHtml(i.title||i.id||"?")}</div>
7006
7006
  <span class="item-priority" style="color:${r};border:1px solid ${r}">${s}</span>
7007
7007
  ${p}
7008
- ${h}
7008
+ ${u}
7009
7009
  <div class="verification-dots">
7010
- ${o.map(g=>`<div class="v-dot ${g.passed===!0?"v-dot-pass":g.passed===!1?"v-dot-fail":"v-dot-pending"}" title="${this._escapeHtml(g.type||"")}"></div>`).join("")}
7010
+ ${o.map(m=>`<div class="v-dot ${m.passed===!0?"v-dot-pass":m.passed===!1?"v-dot-fail":"v-dot-pending"}" title="${this._escapeHtml(m.type||"")}"></div>`).join("")}
7011
7011
  </div>
7012
7012
  </div>
7013
7013
  `}).join(""):'<div class="item" style="color:var(--loki-text-muted)">No items</div>'}_renderEmpty(){return`
@@ -7015,7 +7015,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
7015
7015
  <p><strong>No checklist data yet.</strong></p>
7016
7016
  <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>
7017
7017
  </div>
7018
- `}_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",ae);var nt={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}},se=class extends m{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=v({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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,services:Array.isArray(e?.services)?e.services.map(r=>`${r?.url||""}|${r?.name||""}`).join(","):null}),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}}_extraServices(e){if(!e||!Array.isArray(e.services))return[];let t=e.url||"",i=[],a=new Set;for(let s of e.services){if(!s||typeof s.url!="string"||!s.url||s.url===t||a.has(s.url))continue;a.add(s.url);let r=typeof s.name=="string"?s.name.trim():"",o=typeof s.role=="string"?s.role.trim():"",n=s.port!=null?String(s.port):"",l=r||o||(n?`Port ${n}`:"Service");i.push({url:s.url,label:l,urlValid:this._isValidUrl(s.url)})}return i}_getStyles(){return`
7018
+ `}_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",ae);var nt={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}},se=class extends v{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=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let[t,i]=await Promise.all([e.getAppRunnerStatus(),e.getAppRunnerLogs()]);if(e!==this._api)return;let a=JSON.stringify({status:t?.status,port:t?.port,restarts:t?.restart_count,url:t?.url,services:Array.isArray(t?.services)?t.services.map(o=>`${o?.url||""}|${o?.name||""}`).join(","):null}),s=JSON.stringify(i?.lines?.slice(-5)||[]),r=s!==this._lastLogsHash;if(a===this._lastDataHash&&!r)return;this._lastDataHash=a,this._lastLogsHash=s,this._status=t,this._logs=i?.lines||[],this._error=null,this.render(),this._scrollLogsToBottom()}catch(t){if(e!==this._api)return;this._error||(this._error=`Failed to load app status: ${t.message}`,this.render())}}_scrollLogsToBottom(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector(".log-area");t&&(t.scrollTop=t.scrollHeight)}async _handleRestart(){let e=this._api;try{if(await e.restartApp(),e!==this._api)return;this._loadData()}catch(t){if(e!==this._api)return;this._error=`Restart failed: ${t.message}`,this.render()}}async _handleStop(){let e=this._api;try{if(await e.stopApp(),e!==this._api)return;this._loadData()}catch(t){if(e!==this._api)return;this._error=`Stop failed: ${t.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}}_extraServices(e){if(!e||!Array.isArray(e.services))return[];let t=e.url||"",i=[],a=new Set;for(let s of e.services){if(!s||typeof s.url!="string"||!s.url||s.url===t||a.has(s.url))continue;a.add(s.url);let r=typeof s.name=="string"?s.name.trim():"",o=typeof s.role=="string"?s.role.trim():"",n=s.port!=null?String(s.port):"",l=r||o||(n?`Port ${n}`:"Service");i.push({url:s.url,label:l,urlValid:this._isValidUrl(s.url)})}return i}_getStyles(){return`
7019
7019
  .app-status {
7020
7020
  padding: 16px;
7021
7021
  font-family: var(--loki-font-family, system-ui, -apple-system, sans-serif);
@@ -7247,7 +7247,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
7247
7247
  <p>App not running yet</p>
7248
7248
  <p class="hint">Your app will start automatically after the first successful build step.</p>
7249
7249
  </div>
7250
- `}_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",se);var lt={not_initialized:{color:"var(--loki-text-muted, #71717a)",label:"No app yet",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:"Could not start",pulse:!1},crashed:{color:"var(--loki-red, #dc2626)",label:"Crashed",pulse:!1},stopped:{color:"var(--loki-text-muted, #a1a1aa)",label:"Stopped",pulse:!1},error:{color:"var(--loki-text-muted, #71717a)",label:"Status unavailable",pulse:!1},unknown:{color:"var(--loki-text-muted, #71717a)",label:"Unknown",pulse:!1}},re=class extends m{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._api=null,this._pollInterval=null,this._status=null,this._errors=null,this._error=null,this._lastDataHash=null,this._detailsOpen=!1,this._iframeFailed=!1,this._iframeLoadTimer=null,this._IFRAME_LOAD_TIMEOUT_MS=6e3,this._activeServiceKey=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this.render(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._clearIframeLoadTimer()}_clearIframeLoadTimer(){this._iframeLoadTimer&&(clearTimeout(this._iframeLoadTimer),this._iframeLoadTimer=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=v({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){try{let e=await this._api.getAppRunnerStatus(),t=e?.status||"not_initialized",i=null;if(t==="crashed"||t==="failed")try{i=await this._api.getAppRunnerErrors(50)}catch{i=null}let a=JSON.stringify({status:t,port:e?.port,url:e?.url,crash:e?.crash_count,errLen:i?.lines?.length||0,extMgd:e?.externally_managed===!0,source:e?.source||null,healthOk:e?.last_health?.ok===!0?"ok":e?.last_health?.ok===!1?"down":"unknown",services:Array.isArray(e?.services)?e.services.map(r=>`${r?.url||""}|${r?.role||""}|${r?.name||""}`).join(","):null}),s=this._error!==null;if(a===this._lastDataHash&&!s)return;this._iframeFailed=!1,this._lastDataHash=a,this._status=e,this._errors=i,this._error=null,this.render()}catch(e){this._error||(this._error=`Could not read app status: ${e.message}`,this.render())}}_isValidUrl(e){if(!e)return!1;try{let t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch{return!1}}_getServices(){let e=this._status;if(!e)return[];let t=Array.isArray(e.services)&&e.services.length>0?e.services:[{url:e.url,role:"",name:e.primary_service||"",port:e.port}],i=new Set,a=[];for(let s of t){if(!s||!this._isValidUrl(s.url))continue;let r=typeof s.name=="string"?s.name.trim():"",o=s.port!=null?String(s.port):"",n=this._inferServiceRole(s.role,r),l=s.url||r||o;if(i.has(l))continue;i.add(l);let c=r;c||(c=n==="api"?"API":n==="ui"?"UI":""),c||(c=o?`Port ${o}`:"Service"),a.push({key:l,url:s.url,role:n,name:r,port:o,label:c})}return a}_inferServiceRole(e,t){let i=typeof e=="string"?e.trim().toLowerCase():"";if(i==="ui"||i==="web"||i==="frontend")return"ui";if(i==="api"||i==="backend"||i==="server")return"api";let a=(t||"").toLowerCase();return/\b(api|backend|server|graphql|grpc)\b/.test(a)||a.includes("api")?"api":""}_activeService(e){if(!e||e.length===0)return null;if(this._activeServiceKey){let t=e.find(i=>i.key===this._activeServiceKey);if(t)return t}return e[0]}_handleSelectService(e){this._activeServiceKey!==e&&(this._activeServiceKey=e,this._iframeFailed=!1,this.render())}async _handleRestart(){try{await this._api.restartApp(),this._loadData()}catch(e){this._error=`Restart failed: ${e.message}`,this.render()}}_currentTargetUrl(){let e=this._activeService(this._getServices());if(e&&this._isValidUrl(e.url))return e.url;let t=this._status;return t&&this._isValidUrl(t.url)?t.url:""}_handleRefresh(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector("iframe.preview-frame"),i=this._currentTargetUrl();if(t&&i){this._iframeFailed=!1,this._clearIframeLoadTimer();let a=(i.includes("?")?"&":"?")+"_t="+Date.now();t.src=i+a,this._armIframeLoadDetection()}}_handleRetryFrame(){this._iframeFailed=!1,this._lastDataHash=null,this.render(),this._loadData()}_handleOpenExternal(){let e=this._currentTargetUrl();e&&window.open(e,"_blank","noopener")}_toggleDetails(){this._detailsOpen=!this._detailsOpen,this.render()}_getStyles(){return`
7250
+ `}_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",se);var lt={not_initialized:{color:"var(--loki-text-muted, #71717a)",label:"No app yet",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:"Could not start",pulse:!1},crashed:{color:"var(--loki-red, #dc2626)",label:"Crashed",pulse:!1},stopped:{color:"var(--loki-text-muted, #a1a1aa)",label:"Stopped",pulse:!1},error:{color:"var(--loki-text-muted, #71717a)",label:"Status unavailable",pulse:!1},unknown:{color:"var(--loki-text-muted, #71717a)",label:"Unknown",pulse:!1}},re=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._api=null,this._pollInterval=null,this._status=null,this._errors=null,this._error=null,this._lastDataHash=null,this._detailsOpen=!1,this._iframeFailed=!1,this._iframeLoadTimer=null,this._IFRAME_LOAD_TIMEOUT_MS=6e3,this._activeServiceKey=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this.render(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._clearIframeLoadTimer()}_clearIframeLoadTimer(){this._iframeLoadTimer&&(clearTimeout(this._iframeLoadTimer),this._iframeLoadTimer=null)}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e.getAppRunnerStatus();if(e!==this._api)return;let i=t?.status||"not_initialized",a=null;if(i==="crashed"||i==="failed")try{a=await e.getAppRunnerErrors(50)}catch{a=null}if(e!==this._api)return;let s=JSON.stringify({status:i,port:t?.port,url:t?.url,crash:t?.crash_count,errLen:a?.lines?.length||0,extMgd:t?.externally_managed===!0,source:t?.source||null,healthOk:t?.last_health?.ok===!0?"ok":t?.last_health?.ok===!1?"down":"unknown",services:Array.isArray(t?.services)?t.services.map(o=>`${o?.url||""}|${o?.role||""}|${o?.name||""}`).join(","):null}),r=this._error!==null;if(s===this._lastDataHash&&!r)return;this._iframeFailed=!1,this._lastDataHash=s,this._status=t,this._errors=a,this._error=null,this.render()}catch(t){if(e!==this._api)return;this._error||(this._error=`Could not read app status: ${t.message}`,this.render())}}_isValidUrl(e){if(!e)return!1;try{let t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch{return!1}}_getServices(){let e=this._status;if(!e)return[];let t=Array.isArray(e.services)&&e.services.length>0?e.services:[{url:e.url,role:"",name:e.primary_service||"",port:e.port}],i=new Set,a=[];for(let s of t){if(!s||!this._isValidUrl(s.url))continue;let r=typeof s.name=="string"?s.name.trim():"",o=s.port!=null?String(s.port):"",n=this._inferServiceRole(s.role,r),l=s.url||r||o;if(i.has(l))continue;i.add(l);let c=r;c||(c=n==="api"?"API":n==="ui"?"UI":""),c||(c=o?`Port ${o}`:"Service"),a.push({key:l,url:s.url,role:n,name:r,port:o,label:c})}return a}_inferServiceRole(e,t){let i=typeof e=="string"?e.trim().toLowerCase():"";if(i==="ui"||i==="web"||i==="frontend")return"ui";if(i==="api"||i==="backend"||i==="server")return"api";let a=(t||"").toLowerCase();return/\b(api|backend|server|graphql|grpc)\b/.test(a)||a.includes("api")?"api":""}_activeService(e){if(!e||e.length===0)return null;if(this._activeServiceKey){let t=e.find(i=>i.key===this._activeServiceKey);if(t)return t}return e[0]}_handleSelectService(e){this._activeServiceKey!==e&&(this._activeServiceKey=e,this._iframeFailed=!1,this.render())}async _handleRestart(){let e=this._api;try{if(await e.restartApp(),e!==this._api)return;this._loadData()}catch(t){if(e!==this._api)return;this._error=`Restart failed: ${t.message}`,this.render()}}_currentTargetUrl(){let e=this._activeService(this._getServices());if(e&&this._isValidUrl(e.url))return e.url;let t=this._status;return t&&this._isValidUrl(t.url)?t.url:""}_handleRefresh(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector("iframe.preview-frame"),i=this._currentTargetUrl();if(t&&i){this._iframeFailed=!1,this._clearIframeLoadTimer();let a=(i.includes("?")?"&":"?")+"_t="+Date.now();t.src=i+a,this._armIframeLoadDetection()}}_handleRetryFrame(){this._iframeFailed=!1,this._lastDataHash=null,this.render(),this._loadData()}_handleOpenExternal(){let e=this._currentTargetUrl();e&&window.open(e,"_blank","noopener")}_toggleDetails(){this._detailsOpen=!this._detailsOpen,this.render()}_getStyles(){return`
7251
7251
  .preview { padding: 16px; font-family: var(--loki-font-family, system-ui, -apple-system, sans-serif); color: var(--loki-text-primary, #201515); display: flex; flex-direction: column; width: 100%; box-sizing: border-box; }
7252
7252
  .header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; gap: 12px; flex-wrap: wrap; }
7253
7253
  .header-left { display: flex; align-items: center; gap: 10px; }
@@ -7297,15 +7297,15 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
7297
7297
  .details-toggle:hover { text-decoration: underline; }
7298
7298
  .details-body { margin-top: 8px; background: var(--loki-bg-code, #1e1e1e); color: #d4d4d4; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; padding: 10px; border-radius: 6px; max-height: 200px; overflow: auto; white-space: pre-wrap; }
7299
7299
  .error-banner { margin-top: 12px; padding: 10px 12px; border-radius: 6px; background: color-mix(in srgb, var(--loki-red, #dc2626) 10%, transparent); color: var(--loki-red, #dc2626); font-size: 13px; }
7300
- `}_effectiveView(e,t){let i=this._status,a=i?.last_health,s=a&&typeof a.ok=="boolean"?a.ok:null;if(e==="running"&&t&&(i?.externally_managed===!0||i?.source==="discovered"))return{view:"running",healthOk:s};if(e==="running"&&t){if(s===!1)return{view:"starting",healthOk:s};if(s===!0)return{view:"running",healthOk:s};let r=i?.started_at?Date.parse(i.started_at):NaN;return{view:Number.isFinite(r)&&Date.now()-r<15e3?"running":"starting",healthOk:s}}return{view:e,healthOk:s}}render(){let e=this.shadowRoot;if(!e)return;this._clearIframeLoadTimer();let t=this._status,i=t?.status||"not_initialized",a=this._getServices(),s=this._activeService(a),r=a.length>1,o=s?.url||t?.url,n=this._isValidUrl(o),{view:l,healthOk:c}=this._effectiveView(i,n),p=t?.externally_managed===!0||t?.source==="discovered",h=lt[l]||lt.not_initialized,g=i==="running"&&c===!1?"Starting / not responding yet":h.label;e.innerHTML=`
7300
+ `}_effectiveView(e,t){let i=this._status,a=i?.last_health,s=a&&typeof a.ok=="boolean"?a.ok:null;if(e==="running"&&t&&(i?.externally_managed===!0||i?.source==="discovered"))return{view:"running",healthOk:s};if(e==="running"&&t){if(s===!1)return{view:"starting",healthOk:s};if(s===!0)return{view:"running",healthOk:s};let r=i?.started_at?Date.parse(i.started_at):NaN;return{view:Number.isFinite(r)&&Date.now()-r<15e3?"running":"starting",healthOk:s}}return{view:e,healthOk:s}}render(){let e=this.shadowRoot;if(!e)return;this._clearIframeLoadTimer();let t=this._status,i=t?.status||"not_initialized",a=this._getServices(),s=this._activeService(a),r=a.length>1,o=s?.url||t?.url,n=this._isValidUrl(o),{view:l,healthOk:c}=this._effectiveView(i,n),p=t?.externally_managed===!0||t?.source==="discovered",u=lt[l]||lt.not_initialized,m=i==="running"&&c===!1?"Starting / not responding yet":u.label;e.innerHTML=`
7301
7301
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
7302
7302
  <div class="preview">
7303
7303
  <div class="header">
7304
7304
  <div class="header-left">
7305
7305
  <h2 class="title">Live App</h2>
7306
- <span class="status-badge" style="background: color-mix(in srgb, ${h.color} 15%, transparent); color: ${h.color}">
7307
- <span class="status-dot ${h.pulse?"pulse":""}" style="background: ${h.color}"></span>
7308
- ${this._escapeHtml(g)}
7306
+ <span class="status-badge" style="background: color-mix(in srgb, ${u.color} 15%, transparent); color: ${u.color}">
7307
+ <span class="status-dot ${u.pulse?"pulse":""}" style="background: ${u.color}"></span>
7308
+ ${this._escapeHtml(m)}
7309
7309
  </span>
7310
7310
  </div>
7311
7311
  ${this._renderToolbar(l,n,p)}
@@ -7418,7 +7418,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
7418
7418
  </button>
7419
7419
  ${this._detailsOpen?`<div class="details-body">${s}</div>`:""}
7420
7420
  </div>
7421
- `}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=(i,a)=>{let s=e.querySelector(i);s&&s.addEventListener("click",a)};e.querySelectorAll('[data-action="restart"]').forEach(i=>i.addEventListener("click",()=>this._handleRestart())),e.querySelectorAll('[data-action="open-external"]').forEach(i=>i.addEventListener("click",()=>this._handleOpenExternal())),e.querySelectorAll('[data-action="retry-frame"]').forEach(i=>i.addEventListener("click",()=>this._handleRetryFrame())),t('[data-action="refresh"]',()=>this._handleRefresh()),t('[data-action="toggle-details"]',()=>this._toggleDetails()),e.querySelectorAll('[data-action="select-service"]').forEach(i=>i.addEventListener("click",()=>this._handleSelectService(i.getAttribute("data-service-key"))))}_escapeHtml(e){return e==null?"":String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}};customElements.define("loki-app-preview",re);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"}},oe=class extends m{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=v({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._poll=b({loadFn:()=>this._loadCost(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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`
7421
+ `}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=(i,a)=>{let s=e.querySelector(i);s&&s.addEventListener("click",a)};e.querySelectorAll('[data-action="restart"]').forEach(i=>i.addEventListener("click",()=>this._handleRestart())),e.querySelectorAll('[data-action="open-external"]').forEach(i=>i.addEventListener("click",()=>this._handleOpenExternal())),e.querySelectorAll('[data-action="retry-frame"]').forEach(i=>i.addEventListener("click",()=>this._handleRetryFrame())),t('[data-action="refresh"]',()=>this._handleRefresh()),t('[data-action="toggle-details"]',()=>this._toggleDetails()),e.querySelectorAll('[data-action="select-service"]').forEach(i=>i.addEventListener("click",()=>this._handleSelectService(i.getAttribute("data-service-key"))))}_escapeHtml(e){return e==null?"":String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}};customElements.define("loki-app-preview",re);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"}},oe=class extends v{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=h({baseUrl:i}),this._loadCost()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadPricing(){let e=this._api;try{let t=await e.getPricing();if(e!==this._api)return;if(t&&t.models){let i={};for(let[a,s]of Object.entries(t.models))i[a]={input:s.input,output:s.output,label:s.label||a,provider:s.provider||"unknown"};this._modelPricing=i,this._pricingSource=t.source||"api",this._pricingDate=t.updated||"",this._activeProvider=t.provider||"claude",this.render()}}catch{}}async _loadCost(){let e=this._api;try{let t=await e.getCost();if(e!==this._api)return;this._updateFromCost(t)}catch{if(e!==this._api)return;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._poll=b({loadFn:()=>this._loadCost(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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`
7422
7422
  <tr>
7423
7423
  <td class="phase-name">${this._escapeHTML(t)}</td>
7424
7424
  <td class="mono-cell">${this._formatTokens(a)}</td>
@@ -7814,13 +7814,13 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
7814
7814
  <div class="pricing-grid">
7815
7815
  ${Object.entries(this._modelPricing).map(([t,i])=>`
7816
7816
  <div class="pricing-item">
7817
- <div class="pricing-model ${this._getPricingColorClass(t,i)}">${i.label||t}</div>
7817
+ <div class="pricing-model ${this._getPricingColorClass(t,i)}">${this._escapeHTML(i.label||t)}</div>
7818
7818
  <div class="pricing-rates">In: $${Number(i.input??0).toFixed(2)} / Out: $${Number(i.output??0).toFixed(2)}</div>
7819
7819
  </div>`).join("")}
7820
7820
  </div>
7821
7821
  </div>
7822
7822
  </div>
7823
- `}};customElements.get("loki-cost-dashboard")||customElements.define("loki-cost-dashboard",oe);var ne=class extends m{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=v({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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=`
7823
+ `}};customElements.get("loki-cost-dashboard")||customElements.define("loki-cost-dashboard",oe);var ne=class extends v{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=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let[i]=await Promise.allSettled([e._get("/api/checkpoints?limit=50")]);if(e!==this._api)return;i.status==="fulfilled"&&(this._checkpoints=Array.isArray(i.value)?i.value:i.value?.checkpoints||[]),this._error=null}catch(i){if(e!==this._api)return;this._error=i.message}let t=JSON.stringify({c:this._checkpoints,e:this._error});t!==this._lastDataHash&&(this._lastDataHash=t,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=`
7824
7824
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
7825
7825
  <div class="checkpoint-viewer">
7826
7826
  <div class="checkpoint-header">
@@ -8139,7 +8139,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
8139
8139
  color: var(--loki-green, #22c55e);
8140
8140
  font-size: 12px;
8141
8141
  }
8142
- `}};customElements.get("loki-checkpoint-viewer")||customElements.define("loki-checkpoint-viewer",ne);var le=class extends m{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=v({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._poll=b({loadFn:()=>this._loadContext(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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`
8142
+ `}};customElements.get("loki-checkpoint-viewer")||customElements.define("loki-checkpoint-viewer",ne);var le=class extends v{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=h({baseUrl:i}),this._loadContext()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadContext(){let e=this._api;try{let t=this.getAttribute("api-url")||window.location.origin,i=await fetch(t+"/api/context");if(i.ok){let a=await i.json();if(e!==this._api)return;this._data=a,this._connected=!0}}catch{if(e!==this._api)return;this._connected=!1}this.render()}_startPolling(){this._poll=b({loadFn:()=>this._loadContext(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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`
8143
8143
  <div class="gauge-tab">
8144
8144
  <div class="gauge-container">
8145
8145
  <svg class="gauge-svg" viewBox="0 0 180 180" aria-label="Context window usage: ${i.toFixed(1)}%">
@@ -8252,14 +8252,14 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
8252
8252
  <div class="legend-item"><span class="legend-swatch swatch-cache-read"></span> Cache Read</div>
8253
8253
  <div class="legend-item"><span class="legend-swatch swatch-cache-create"></span> Cache Creation</div>
8254
8254
  </div>
8255
- `,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,g=t>0?n/t*100:0,u=t>0?l/t*100:0;a+=`
8255
+ `,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,u=t>0?o/t*100:0,m=t>0?n/t*100:0,g=t>0?l/t*100:0;a+=`
8256
8256
  <div class="breakdown-row">
8257
8257
  <div class="breakdown-iter">#${s.iteration}</div>
8258
8258
  <div class="breakdown-bar-container">
8259
8259
  <div class="breakdown-bar bar-input" style="width: ${p.toFixed(1)}%"></div>
8260
- <div class="breakdown-bar bar-output" style="width: ${h.toFixed(1)}%"></div>
8261
- <div class="breakdown-bar bar-cache-read" style="width: ${g.toFixed(1)}%"></div>
8262
- <div class="breakdown-bar bar-cache-create" style="width: ${u.toFixed(1)}%"></div>
8260
+ <div class="breakdown-bar bar-output" style="width: ${u.toFixed(1)}%"></div>
8261
+ <div class="breakdown-bar bar-cache-read" style="width: ${m.toFixed(1)}%"></div>
8262
+ <div class="breakdown-bar bar-cache-create" style="width: ${g.toFixed(1)}%"></div>
8263
8263
  </div>
8264
8264
  <div class="breakdown-cost">${this._formatUSD(s.cost_usd)}</div>
8265
8265
  </div>
@@ -8662,7 +8662,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
8662
8662
 
8663
8663
  ${e}
8664
8664
  </div>
8665
- `,this.shadowRoot.querySelectorAll(".tab").forEach(t=>{t.addEventListener("click",()=>{this._setTab(t.dataset.tab)})})}};customElements.get("loki-context-tracker")||customElements.define("loki-context-tracker",le);var Ke={critical:"var(--loki-red, #ef4444)",warning:"var(--loki-yellow, #eab308)",info:"var(--loki-blue, #3b82f6)",success:"var(--loki-green, #1FC5A8)"},dt={build:{label:"Build",icon:"B"},quality:{label:"Quality",icon:"Q"},system:{label:"System",icon:"S"},security:{label:"Security",icon:"!"}},de=class extends m{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._poll=b({loadFn:()=>{this._loadNotifications(),this._loadTriggers()},intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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 Ke[e]||Ke.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`
8665
+ `,this.shadowRoot.querySelectorAll(".tab").forEach(t=>{t.addEventListener("click",()=>{this._setTab(t.dataset.tab)})})}};customElements.get("loki-context-tracker")||customElements.define("loki-context-tracker",le);var Ke={critical:"var(--loki-red, #ef4444)",warning:"var(--loki-yellow, #eab308)",info:"var(--loki-blue, #3b82f6)",success:"var(--loki-green, #1FC5A8)"},dt={build:{label:"Build",icon:"B"},quality:{label:"Quality",icon:"Q"},system:{label:"System",icon:"S"},security:{label:"Security",icon:"!"}},de=class extends v{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._poll=b({loadFn:()=>{this._loadNotifications(),this._loadTriggers()},intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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 Ke[e]||Ke.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`
8666
8666
  <div class="bell-container">
8667
8667
  <button class="bell-icon" title="${e} unread notifications">
8668
8668
  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
@@ -8699,7 +8699,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
8699
8699
  `}_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=dt[l]||{label:l,icon:"?"};return`
8700
8700
  <div class="notif-row ${o?"acknowledged":""}">
8701
8701
  <span class="severity-dot" style="background: ${n};" title="${this._escapeHTML(r.severity)}"></span>
8702
- <span class="cat-icon" title="${c.label}">${c.icon}</span>
8702
+ <span class="cat-icon" title="${this._escapeHTML(c.label)}">${c.icon}</span>
8703
8703
  <span class="notif-time">${this._formatTime(r.timestamp)}</span>
8704
8704
  <span class="notif-message">${this._escapeHTML(r.message)}</span>
8705
8705
  ${r.iteration!=null?`<span class="notif-iteration">iter ${r.iteration}</span>`:""}
@@ -9179,7 +9179,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
9179
9179
  `:""}
9180
9180
  `:""}
9181
9181
  </div>
9182
- `,this._bindEvents()}};customElements.get("loki-notification-center")||customElements.define("loki-notification-center",de);var ce=class extends m{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=v({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._poll=b({loadFn:()=>this._loadData(),intervalMs:3e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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=`
9182
+ `,this._bindEvents()}};customElements.get("loki-notification-center")||customElements.define("loki-notification-center",de);var ce=class extends v{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=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){let e=this._api;try{let t=await e._get("/api/session-diff");if(e!==this._api)return;this._data=t,this._error=null}catch(t){if(e!==this._api)return;this._error=t.message,this._data=null}this._loading=!1,this.render()}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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=`
9183
9183
  ${this.getBaseStyles()}
9184
9184
 
9185
9185
  :host {
@@ -9400,13 +9400,13 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
9400
9400
  `);let l="";o.length>0&&(l=`
9401
9401
  <div class="decisions-section">
9402
9402
  <div class="section-label">Decisions</div>
9403
- ${o.map((c,p)=>{let h=this._expandedDecisions.has(p);return`
9403
+ ${o.map((c,p)=>{let u=this._expandedDecisions.has(p);return`
9404
9404
  <div class="decision-item">
9405
9405
  <button class="decision-header" data-index="${p}">
9406
- <span class="decision-arrow ${h?"expanded":""}">&#9654;</span>
9406
+ <span class="decision-arrow ${u?"expanded":""}">&#9654;</span>
9407
9407
  ${this._escapeHtml(c.title||c.decision||"Decision")}
9408
9408
  </button>
9409
- ${h?`<div class="decision-reasoning">${this._escapeHtml(c.reasoning||c.rationale||"No reasoning provided")}</div>`:""}
9409
+ ${u?`<div class="decision-reasoning">${this._escapeHtml(c.reasoning||c.rationale||"No reasoning provided")}</div>`:""}
9410
9410
  </div>
9411
9411
  `}).join("")}
9412
9412
  </div>
@@ -9445,7 +9445,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
9445
9445
  ${n}
9446
9446
  ${l}
9447
9447
  </div>
9448
- `,this.shadowRoot.querySelectorAll(".decision-header").forEach(c=>{c.addEventListener("click",()=>{this._toggleDecision(parseInt(c.dataset.index))})})}};customElements.get("loki-session-diff")||customElements.define("loki-session-diff",ce);var pe=class extends m{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=v({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._poll=b({loadFn:()=>this._loadData(),intervalMs:6e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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=`
9448
+ `,this.shadowRoot.querySelectorAll(".decision-header").forEach(c=>{c.addEventListener("click",()=>{this._toggleDecision(parseInt(c.dataset.index))})})}};customElements.get("loki-session-diff")||customElements.define("loki-session-diff",ce);var pe=class extends v{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=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){let e=this._api;try{let t=await e._get("/api/prompt-versions");if(e!==this._api)return;this._data=t,this._error=null}catch(t){if(e!==this._api)return;this._error=t.message,this._data=null}this._loading=!1,this.render()}async _triggerOptimize(){if(this._optimizing)return;let e=this._api;this._optimizing=!0,this.render();try{if(await e._post("/api/prompt-optimize?dry_run=false",{}),e!==this._api)return;await this._loadData()}catch(t){if(e!==this._api)return;this._error=t.message}this._optimizing=!1,this.render()}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:6e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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=`
9449
9449
  ${this.getBaseStyles()}
9450
9450
 
9451
9451
  :host {
@@ -9696,7 +9696,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
9696
9696
 
9697
9697
  ${o}
9698
9698
  </div>
9699
- `;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",pe);var he=class extends m{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=v({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):i&&i.available===!1?(this._rigourAvailable=!1,this._data=null):i&&i.score==null?(this._rigourAvailable=!0,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._poll=b({loadFn:()=>this._loadData(),intervalMs:6e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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),g=n+(1-(c-i)/s)*(o-n*2);return`${h},${g}`}).join(" ");return`
9699
+ `;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",pe);var he=class extends v{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=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){let e=this._api;try{let[t,i]=await Promise.allSettled([e._get("/api/quality-score"),e._get("/api/quality-score/history")]);if(e!==this._api)return;if(t.status==="fulfilled"){let a=t.value;a&&a.error&&a.error.includes("not installed")?(this._rigourAvailable=!1,this._data=null):a&&a.available===!1?(this._rigourAvailable=!1,this._data=null):a&&a.score==null?(this._rigourAvailable=!0,this._data=null):(this._rigourAvailable=!0,this._data=a),this._error=null}else(t.reason?.message||"").includes("404")?(this._rigourAvailable=!1,this._data=null,this._error=null):(this._error="Failed to load quality score",this._data=null);if(i.status==="fulfilled"){let a=i.value;this._history=Array.isArray(a)?a.slice(-10):(a.scores||[]).slice(-10)}}catch(t){if(e!==this._api)return;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(e){this._error=e.message}this._scanning=!1,this.render()}}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:6e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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 u=n+p/(t.length-1)*(r-n*2),m=n+(1-(c-i)/s)*(o-n*2);return`${u},${m}`}).join(" ");return`
9700
9700
  <svg width="${r}" height="${o}" viewBox="0 0 ${r} ${o}" class="sparkline">
9701
9701
  <polyline points="${l}" fill="none" stroke="var(--loki-accent)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
9702
9702
  <circle cx="${l.split(" ").pop().split(",")[0]}" cy="${l.split(" ").pop().split(",")[1]}" r="2.5" fill="var(--loki-accent)"/>
@@ -10086,15 +10086,15 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
10086
10086
  </button>
10087
10087
  </div>
10088
10088
  </div>
10089
- `;let k=this.shadowRoot.getElementById("scan-btn");k&&k.addEventListener("click",()=>this._triggerScan());return}let i=this._data||{},a=i.score!=null?Math.round(i.score):0,{grade:s,color:r}=this._getGrade(a),o=i.categories||{},n=i.findings||{},l=["security","code_quality","compliance","best_practices"],c={security:"Security",code_quality:"Code Quality",compliance:"Compliance",best_practices:"Best Practices"},p=l.map(k=>{let _=o[k]!=null?Math.round(o[k]):0,M=_>=80?"var(--loki-success)":_>=60?"var(--loki-warning)":"var(--loki-error)";return`
10089
+ `;let k=this.shadowRoot.getElementById("scan-btn");k&&k.addEventListener("click",()=>this._triggerScan());return}let i=this._data||{},a=i.score!=null?Math.round(i.score):0,{grade:s,color:r}=this._getGrade(a),o=i.categories||{},n=i.findings||{},l=["security","code_quality","compliance","best_practices"],c={security:"Security",code_quality:"Code Quality",compliance:"Compliance",best_practices:"Best Practices"},p=l.map(k=>{let _=o[k]!=null?Math.round(o[k]):0,H=_>=80?"var(--loki-success)":_>=60?"var(--loki-warning)":"var(--loki-error)";return`
10090
10090
  <div class="category-item">
10091
10091
  <span class="category-name">${c[k]||k}</span>
10092
10092
  <div class="progress-bar">
10093
- <div class="progress-fill" style="width:${_}%;background:${M};"></div>
10093
+ <div class="progress-fill" style="width:${_}%;background:${H};"></div>
10094
10094
  </div>
10095
10095
  <span class="category-score">${_}</span>
10096
10096
  </div>
10097
- `}).join(""),g=[{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(k=>(n[k.key]||0)>0).map(k=>`<span class="finding-badge ${k.cls}">${k.label}: ${n[k.key]}</span>`).join(""),u=this._renderSparkline(this._history);this.shadowRoot.innerHTML=`
10097
+ `}).join(""),m=[{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(k=>(n[k.key]||0)>0).map(k=>`<span class="finding-badge ${k.cls}">${k.label}: ${n[k.key]}</span>`).join(""),g=this._renderSparkline(this._history);this.shadowRoot.innerHTML=`
10098
10098
  <style>${e}</style>
10099
10099
  <div class="quality-container">
10100
10100
  <div class="quality-header">
@@ -10110,10 +10110,10 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
10110
10110
  <div class="score-number">${a}</div>
10111
10111
  <span class="grade-badge" style="background:${r};color:#fff;">${s}</span>
10112
10112
  </div>
10113
- ${u?`
10113
+ ${g?`
10114
10114
  <div class="sparkline-container">
10115
10115
  <span class="sparkline-label">Trend (last ${this._history.length})</span>
10116
- ${u}
10116
+ ${g}
10117
10117
  </div>
10118
10118
  `:""}
10119
10119
  </div>
@@ -10123,14 +10123,14 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
10123
10123
  ${p}
10124
10124
  </div>
10125
10125
 
10126
- ${g?`
10126
+ ${m?`
10127
10127
  <div class="findings-section">
10128
10128
  <div class="section-label">Findings</div>
10129
- <div class="findings-row">${g}</div>
10129
+ <div class="findings-row">${m}</div>
10130
10130
  </div>
10131
10131
  `:""}
10132
10132
  </div>
10133
- `;let x=this.shadowRoot.getElementById("scan-btn");x&&x.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-score")||customElements.define("loki-quality-score",he);var ct=["understand","guardrail","migrate","verify"],pt={understand:"Understand",guardrail:"Guardrail",migrate:"Migrate",verify:"Verify"},Pt={understand:"#5b9bd5",guardrail:"#e8b84a",migrate:"#5bb870",verify:"#5bc8c8"},ue=class extends m{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._poll=b({loadFn:()=>this._fetchData(),intervalMs:15e3,element:this,immediate:!1})}disconnectedCallback(){super.disconnectedCallback(),this._poll&&(this._poll.stop(),this._poll=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=v({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=ct.indexOf(e);return t>=0?t:0}_renderPhaseBar(e,t){let i=t||[];return ct.map(a=>{let s=i.includes(a),r=a===e,o=Pt[a],n=s?"1":r?"0.7":"0.2",l=this._getPhaseIcon(a,e,t);return`
10133
+ `;let x=this.shadowRoot.getElementById("scan-btn");x&&x.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-score")||customElements.define("loki-quality-score",he);var ct=["understand","guardrail","migrate","verify"],pt={understand:"Understand",guardrail:"Guardrail",migrate:"Migrate",verify:"Verify"},Pt={understand:"#5b9bd5",guardrail:"#e8b84a",migrate:"#5bb870",verify:"#5bc8c8"},ue=class extends v{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._poll=b({loadFn:()=>this._fetchData(),intervalMs:15e3,element:this,immediate:!1})}disconnectedCallback(){super.disconnectedCallback(),this._poll&&(this._poll.stop(),this._poll=null)}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._fetchMigrations()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _fetchMigrations(){let e=this._api;try{let t=await e._get("/api/migration/list");if(e!==this._api)return;this._migrations=Array.isArray(t)?t:t.migrations||[],this._error=null;let i=this._migrations.find(a=>a.status==="in_progress"||a.status==="active");if(i){if(await this._fetchStatus(i.migration_id||i.id),e!==this._api)return}else this._migration=null}catch(t){if(e!==this._api)return;this._error=t.message,this._migrations=[],this._migration=null}this._loading=!1,this.render()}async _fetchStatus(e){let t=this._api;try{let i=await t._get(`/api/migration/${encodeURIComponent(e)}/status`);if(t!==this._api)return;this._migration=i,this._error=null}catch(i){if(t!==this._api)return;this._error=i.message}}async _fetchData(){let e=this._api,t=this._migration&&(this._migration.migration_id||this._migration.id);if(t){if(await this._fetchStatus(t),e!==this._api)return;this.render()}else 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=ct.indexOf(e);return t>=0?t:0}_renderPhaseBar(e,t){let i=t||[];return ct.map(a=>{let s=i.includes(a),r=a===e,o=Pt[a],n=s?"1":r?"0.7":"0.2",l=this._getPhaseIcon(a,e,t);return`
10134
10134
  <div class="phase-segment">
10135
10135
  <div class="phase-bar-fill" style="background:${o};opacity:${n};"></div>
10136
10136
  <div class="phase-label">
@@ -10553,7 +10553,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
10553
10553
  <div class="section-label">Migrations</div>
10554
10554
  ${this._renderMigrationList()}
10555
10555
  </div>
10556
- `}};customElements.get("loki-migration-dashboard")||customElements.define("loki-migration-dashboard",ue);var It=[["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 Ft(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 jt(d,e){if(e!=null){let i=Ft(e);if(i)return i.provider}let t=(d||"").toLowerCase();for(let[i,a]of It)if(t.includes(i))return a;return"unknown"}var ge=class extends m{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,this._loadedOnce=!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=v({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._loadedOnce=!0,this.render()}finally{this._loading=!1}}}_hasAnyData(){let e=Array.isArray(this._activity)?this._activity.length:0,t=Array.isArray(this._tools)?this._tools.length:0,i=this._cost&&this._cost.by_model?Object.keys(this._cost.by_model).length:0,a=this._context||{},r=(a.totals||{}).iterations_tracked||a.total_iterations||a.iteration||0;return e>0||t>0||i>0||r>0}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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 g=this._localDateKey(h);e[g]=(e[g]||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`
10556
+ `}};customElements.get("loki-migration-dashboard")||customElements.define("loki-migration-dashboard",ue);var It=[["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 Ft(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 jt(d,e){if(e!=null){let i=Ft(e);if(i)return i.provider}let t=(d||"").toLowerCase();for(let[i,a]of It)if(t.includes(i))return a;return"unknown"}var ge=class extends v{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,this._loadedOnce=!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=h({baseUrl:i}),this._loadData())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _fetchActivity(e=this._api){let t=e.baseUrl||window.location.origin,i=new AbortController,a=setTimeout(()=>i.abort(),1e4);try{let s=await fetch(`${t}/api/activity?limit=1000`,{signal:i.signal});if(clearTimeout(a),!s.ok)throw new Error(`Activity API ${s.status}`);return s.json()}catch(s){throw clearTimeout(a),s}}async _loadData(){if(!this.isConnected||this._loading)return;let e=this._api;this._loading=!0;try{let t=await Promise.allSettled([this._fetchActivity(e),e.getToolEfficiency(50),e.getCost(),e.getContext(),e.getLearningTrends({timeRange:this._toolTimeRange})]);if(e!==this._api)return;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 i=t[4].value||{};this._trends=Array.isArray(i)?i:i.dataPoints||[]}this._connected=t.some(i=>i.status==="fulfilled"),this._loadedOnce=!0,this.render()}finally{this._loading=!1}}_hasAnyData(){let e=Array.isArray(this._activity)?this._activity.length:0,t=Array.isArray(this._tools)?this._tools.length:0,i=this._cost&&this._cost.by_model?Object.keys(this._cost.by_model).length:0,a=this._context||{},r=(a.totals||{}).iterations_tracked||a.total_iterations||a.iteration||0;return e>0||t>0||i>0||r>0}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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 u=new Date(p);if(isNaN(u.getTime()))continue;let m=this._localDateKey(u);e[m]=(e[m]||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 u=new Date(e[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=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`
10557
10557
  <div class="heatmap-container">
10558
10558
  <div class="heatmap-months">${n}</div>
10559
10559
  <div class="heatmap-body">
@@ -10578,7 +10578,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
10578
10578
  </div>
10579
10579
  <span class="tool-count">${s}</span>
10580
10580
  </div>
10581
- `}).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`
10581
+ `}).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 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: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`
10582
10582
  ${`
10583
10583
  <div class="tool-filter">
10584
10584
  <select class="tool-time-select" id="tool-time-range">
@@ -11106,7 +11106,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
11106
11106
  </div>
11107
11107
  `}
11108
11108
  </div>
11109
- `,this.shadowRoot.querySelectorAll("[data-tab]").forEach(l=>{l.addEventListener("click",c=>this._handleTabClick(c))});let r=this.shadowRoot.getElementById("tool-time-range");r&&r.addEventListener("change",l=>this._handleTimeRangeChange(l));let o=this.shadowRoot.getElementById("analytics-retry-btn");o&&o.addEventListener("click",()=>this._loadData());let n=this.shadowRoot.getElementById("analytics-overview-btn");n&&n.addEventListener("click",()=>this._navigateToOverview())}_navigateToOverview(){this.dispatchEvent(new CustomEvent("loki-navigate",{detail:{view:"overview"},bubbles:!0,composed:!0}))}};customElements.get("loki-analytics")||customElements.define("loki-analytics",ge);var ht={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 Ut(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 Ot(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 me=class extends m{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,this._scanning=!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()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=v({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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()}async _triggerScan(){if(!this._scanning){this._scanning=!0,this.render();try{await this._api._post("/api/quality-scan",{},{timeout:3e5}),this._lastDataHash=null,await this._loadData()}catch(e){this._error=`Quality scan failed: ${e.message}`}finally{this._scanning=!1,this.render()}}}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
11109
+ `,this.shadowRoot.querySelectorAll("[data-tab]").forEach(l=>{l.addEventListener("click",c=>this._handleTabClick(c))});let r=this.shadowRoot.getElementById("tool-time-range");r&&r.addEventListener("change",l=>this._handleTimeRangeChange(l));let o=this.shadowRoot.getElementById("analytics-retry-btn");o&&o.addEventListener("click",()=>this._loadData());let n=this.shadowRoot.getElementById("analytics-overview-btn");n&&n.addEventListener("click",()=>this._navigateToOverview())}_navigateToOverview(){this.dispatchEvent(new CustomEvent("loki-navigate",{detail:{view:"overview"},bubbles:!0,composed:!0}))}};customElements.get("loki-analytics")||customElements.define("loki-analytics",ge);var ht={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 Ut(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 Ot(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 me=class extends v{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,this._scanning=!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=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{this._loading=!0;let t=await e._get("/api/council/gate");if(e!==this._api)return;let i=t?.gates||t||[],a=t?.evidence||{blocked:!1},s=JSON.stringify({gates:i,evidence:a});if(s===this._lastDataHash)return;this._lastDataHash=s,this._gates=Array.isArray(i)?i:[],this._evidence=a,this._error=null}catch(t){if(e!==this._api)return;this._error||(this._error=`Failed to load quality gates: ${t.message}`)}finally{this._loading=!1}this.render()}async _triggerScan(){if(this._scanning)return;let e=this._api;this._scanning=!0,this.render();try{if(await e._post("/api/quality-scan",{},{timeout:3e5}),e!==this._api)return;this._lastDataHash=null,await this._loadData()}catch(t){if(e!==this._api)return;this._error=`Quality scan failed: ${t.message}`}finally{this._scanning=!1,this.render()}}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
11110
11110
  :host {
11111
11111
  display: block;
11112
11112
  }
@@ -11374,20 +11374,20 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
11374
11374
  <button class="es-cta" id="gates-scan-btn" ${this._scanning?"disabled":""}>
11375
11375
  ${this._scanning?'<span class="es-spinner"></span> Scanning...':"Run quality scan"}
11376
11376
  </button>
11377
- </div>`:s=`<div class="gates-grid">${t.map(p=>{let h=(p.status||"pending").toLowerCase(),g=ht[h]||ht.pending;return`
11378
- <div class="gate-card status-${h}">
11377
+ </div>`:s=`<div class="gates-grid">${t.map(p=>{let u=(p.status||"pending").toLowerCase(),m=ht[u]||ht.pending;return`
11378
+ <div class="gate-card status-${u}">
11379
11379
  <div class="gate-header">
11380
11380
  <span class="gate-name">${this._escapeHtml(p.name||"Unnamed Gate")}</span>
11381
- <span class="gate-badge" style="background: ${g.bg}; color: ${g.color};">${g.label}</span>
11381
+ <span class="gate-badge" style="background: ${m.bg}; color: ${m.color};">${m.label}</span>
11382
11382
  </div>
11383
11383
  ${p.description?`<div class="gate-description">${this._escapeHtml(p.description)}</div>`:""}
11384
11384
  <div class="gate-meta">Last checked: ${Ut(p.last_checked||p.lastChecked)}</div>
11385
11385
  </div>
11386
- `}).join("")}</div>`;let r="",o=this._evidence||{};if(o.blocked){let c={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."},p=o.error?this._escapeHtml(o.error):c[o.reason]||this._escapeHtml(o.reason||"Completion blocked."),h=Array.isArray(o.failures)?o.failures:[],g=h.length?`<ul class="evidence-failures">${h.map(u=>`<li>${this._escapeHtml(u)}</li>`).join("")}</ul>`:"";r=`
11386
+ `}).join("")}</div>`;let r="",o=this._evidence||{};if(o.blocked){let c={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."},p=o.error?this._escapeHtml(o.error):c[o.reason]||this._escapeHtml(o.reason||"Completion blocked."),u=Array.isArray(o.failures)?o.failures:[],m=u.length?`<ul class="evidence-failures">${u.map(g=>`<li>${this._escapeHtml(g)}</li>`).join("")}</ul>`:"";r=`
11387
11387
  <div class="evidence-banner">
11388
11388
  <div class="evidence-title">Verified completion blocked</div>
11389
11389
  <div class="evidence-reason">${p}</div>
11390
- ${g}
11390
+ ${m}
11391
11391
  <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>
11392
11392
  </div>
11393
11393
  `}let n=i.total>0?`
@@ -11416,7 +11416,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
11416
11416
  ${s}
11417
11417
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
11418
11418
  </div>
11419
- `;let l=e.getElementById("gates-scan-btn");l&&l.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-gates")||customElements.define("loki-quality-gates",me);var q={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"}},Ve=["reason","act","reflect","verify"];function qe(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 Nt(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 qt(d){return d==null?"--":d>=1e6?(d/1e6).toFixed(1)+"M":d>=1e3?(d/1e3).toFixed(1)+"K":String(d)}var ve=class extends m{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=v({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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`
11419
+ `;let l=e.getElementById("gates-scan-btn");l&&l.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-gates")||customElements.define("loki-quality-gates",me);var q={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"}},Ve=["reason","act","reflect","verify"];function qe(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 Nt(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 qt(d){return d==null?"--":d>=1e6?(d/1e6).toFixed(1)+"M":d>=1e3?(d/1e3).toFixed(1)+"K":String(d)}var ve=class extends v{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=h({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=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this.runId;if(e==null){this._timeline=null,this.render();return}let t=this._api;try{this._loading=!0;let i=await t._get(`/api/v2/runs/${e}/timeline`);if(t!==this._api)return;this._timeline=i,this._cycleHistory=i.history||[],this._error=null}catch(i){if(t!==this._api)return;i.message&&(i.message.includes("404")||i.message.includes("Not Found"))?(this._timeline=null,this._error=null):this._error=`Failed to load timeline: ${i.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`
11420
11420
  :host {
11421
11421
  display: block;
11422
11422
  }
@@ -11753,16 +11753,16 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
11753
11753
  <div class="history-label">Past Cycles (${this._cycleHistory.length} total)</div>
11754
11754
  <div class="history-cycles">${t}</div>
11755
11755
  </div>
11756
- `}_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=Nt(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 g=q[h.phase]||{color:"var(--loki-text-muted)",label:h.phase},u=s===h.phase,x=this._selectedPhase===h.phase;return`<div class="phase-segment-interactive ${u?"current":""} ${x?"selected":""}"
11757
- data-phase="${h.phase}"
11758
- style="width: ${Math.max(h.pct,2)}%; background: ${g.color};"
11759
- title="${g.label}: ${qe(h.duration)}">
11760
- ${h.pct>12?g.label:""}
11761
- </div>`}).join(""),l=a.map(h=>{let g=q[h.phase]||{color:"var(--loki-text-muted)",label:h.phase},u=s===h.phase;return`<div class="legend-item-interactive ${this._selectedPhase===h.phase?"selected":""}" data-phase="${h.phase}">
11762
- <span class="legend-dot" style="background: ${g.color}"></span>
11763
- <span class="legend-label">${g.label}</span>
11764
- <span class="legend-duration">${qe(h.duration_ms)}</span>
11765
- ${u?'<span class="phase-current-tag">ACTIVE</span>':""}
11756
+ `}_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=Nt(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(u=>{let m=q[u.phase]||{color:"var(--loki-text-muted)",label:u.phase},g=s===u.phase,x=this._selectedPhase===u.phase;return`<div class="phase-segment-interactive ${g?"current":""} ${x?"selected":""}"
11757
+ data-phase="${u.phase}"
11758
+ style="width: ${Math.max(u.pct,2)}%; background: ${m.color};"
11759
+ title="${m.label}: ${qe(u.duration)}">
11760
+ ${u.pct>12?m.label:""}
11761
+ </div>`}).join(""),l=a.map(u=>{let m=q[u.phase]||{color:"var(--loki-text-muted)",label:u.phase},g=s===u.phase;return`<div class="legend-item-interactive ${this._selectedPhase===u.phase?"selected":""}" data-phase="${u.phase}">
11762
+ <span class="legend-dot" style="background: ${m.color}"></span>
11763
+ <span class="legend-label">${m.label}</span>
11764
+ <span class="legend-duration">${qe(u.duration_ms)}</span>
11765
+ ${g?'<span class="phase-current-tag">ACTIVE</span>':""}
11766
11766
  </div>`}).join(""),c=this._selectedPhase?this._renderPhaseDetail(this._selectedPhase):"",p=this._renderCycleHistory();o=`
11767
11767
  <div class="timeline-bar">${n}</div>
11768
11768
  <div class="legend">${l}</div>
@@ -11778,7 +11778,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
11778
11778
  ${o}
11779
11779
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
11780
11780
  </div>
11781
- `,this._bindEvents()}};customElements.get("loki-rarv-timeline")||customElements.define("loki-rarv-timeline",ve);var ut={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 Jt(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 Gt(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 fe=class extends m{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=v({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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`
11781
+ `,this._bindEvents()}};customElements.get("loki-rarv-timeline")||customElements.define("loki-rarv-timeline",ve);var ut={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 Jt(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 Gt(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 fe=class extends v{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=h({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=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=this.projectId,i=t!=null?`?project_id=${t}`:"",a=await e._get(`/api/v2/runs${i}`);if(e!==this._api)return;let s=a?.runs||a||[],r=JSON.stringify(s);if(r===this._lastDataHash)return;this._lastDataHash=r,this._runs=Array.isArray(s)?s:[],this._error=null}catch(t){if(e!==this._api)return;this._error||(this._error=`Failed to load runs: ${t.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`
11782
11782
  :host {
11783
11783
  display: block;
11784
11784
  }
@@ -11974,7 +11974,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
11974
11974
  ${i}
11975
11975
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
11976
11976
  </div>
11977
- `,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",fe);var gt={running:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"Running"},stopped:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"Stopped"},active:{color:"var(--loki-blue, #3b82f6)",bg:"var(--loki-blue-muted, rgba(59, 130, 246, 0.15))",label:"Idle"},missing:{color:"var(--loki-red, #ef4444)",bg:"var(--loki-red-muted, rgba(239, 68, 68, 0.15))",label:"Missing"},unknown:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Unknown"}};function Kt(d){if(d==null||d<0)return"--";if(d<60)return`${d}s`;let e=Math.floor(d/60),t=d%60;if(e<60)return`${e}m ${t}s`;let i=Math.floor(e/60),a=e%60;return`${i}h ${a}m`}function mt(d){return d==null||isNaN(d)?"$0.00":`$${Number(d).toFixed(2)}`}var be=class extends m{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!0,this._error=null,this._api=null,this._runs=[],this._summary=null,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=v({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){try{let[e,t]=await Promise.all([this._api._get("/api/fleet/runs"),this._api._get("/api/fleet/summary")]),i=Array.isArray(e)?e:e?.runs||[],a=JSON.stringify({runs:i,summaryResp:t});if(a===this._lastDataHash)return;this._lastDataHash=a,this._runs=Array.isArray(i)?i:[],this._summary=t||null,this._error=null}catch(e){this._error||(this._error=`Failed to load fleet: ${e.message}`)}finally{this._loading=!1}this.render()}async _cancelRun(e){if(e&&!(typeof confirm=="function"&&!confirm(`Cancel build "${e}"? This stops the running build.`)))try{await this._api._post(`/api/fleet/runs/${encodeURIComponent(e)}/cancel`),this._lastDataHash=null,await this._loadData()}catch(t){this._error=`Cancel 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`
11977
+ `,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",fe);var gt={running:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"Running"},stopped:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"Stopped"},active:{color:"var(--loki-blue, #3b82f6)",bg:"var(--loki-blue-muted, rgba(59, 130, 246, 0.15))",label:"Idle"},missing:{color:"var(--loki-red, #ef4444)",bg:"var(--loki-red-muted, rgba(239, 68, 68, 0.15))",label:"Missing"},unknown:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Unknown"}};function Kt(d){if(d==null||d<0)return"--";if(d<60)return`${d}s`;let e=Math.floor(d/60),t=d%60;if(e<60)return`${e}m ${t}s`;let i=Math.floor(e/60),a=e%60;return`${i}h ${a}m`}function mt(d){return d==null||isNaN(d)?"$0.00":`$${Number(d).toFixed(2)}`}var be=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!0,this._error=null,this._api=null,this._runs=[],this._summary=null,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=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let[t,i]=await Promise.all([e._get("/api/fleet/runs"),e._get("/api/fleet/summary")]);if(e!==this._api)return;let a=Array.isArray(t)?t:t?.runs||[],s=JSON.stringify({runs:a,summaryResp:i});if(s===this._lastDataHash)return;this._lastDataHash=s,this._runs=Array.isArray(a)?a:[],this._summary=i||null,this._error=null}catch(t){if(e!==this._api)return;this._error||(this._error=`Failed to load fleet: ${t.message}`)}finally{this._loading=!1}this.render()}async _cancelRun(e){if(e&&!(typeof confirm=="function"&&!confirm(`Cancel build "${e}"? This stops the running build.`)))try{await this._api._post(`/api/fleet/runs/${encodeURIComponent(e)}/cancel`),this._lastDataHash=null,await this._loadData()}catch(t){this._error=`Cancel 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`
11978
11978
  :host { display: block; }
11979
11979
 
11980
11980
  .fleet {
@@ -12194,7 +12194,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
12194
12194
  ${i}
12195
12195
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
12196
12196
  </div>
12197
- `,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("refresh-btn");t&&t.addEventListener("click",()=>{this._lastDataHash=null,this._loadData()}),e.querySelectorAll('[data-action="cancel"]').forEach(i=>{i.addEventListener("click",()=>this._cancelRun(i.dataset.id))})}};customElements.get("loki-fleet")||customElements.define("loki-fleet",be);function Vt(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 Yt(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 ke=class extends m{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=v({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=Yt(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`
12197
+ `,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("refresh-btn");t&&t.addEventListener("click",()=>{this._lastDataHash=null,this._loadData()}),e.querySelectorAll('[data-action="cancel"]').forEach(i=>{i.addEventListener("click",()=>this._cancelRun(i.dataset.id))})}};customElements.get("loki-fleet")||customElements.define("loki-fleet",be);function Vt(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 Yt(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 ke=class extends v{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=h({baseUrl:i}),this._loadData()),e==="limit"&&this._loadData(),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){let e=this._api;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},i=Yt(t),a=await e._get(`/api/v2/audit${i}`);if(e!==this._api)return;this._entries=a?.entries||a||[],this._error=null}catch(t){if(e!==this._api)return;this._error=`Failed to load audit log: ${t.message}`}finally{this._loading=!1}this.render()}async _verifyIntegrity(){let e=this._api;try{this._verifying=!0,this._verifyResult=null,this.render();let t=await e._get("/api/v2/audit/verify");if(e!==this._api)return;this._verifyResult=t}catch(t){if(e!==this._api)return;this._verifyResult={valid:!1,error:t.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`
12198
12198
  :host {
12199
12199
  display: block;
12200
12200
  }
@@ -12478,7 +12478,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
12478
12478
  ${a}
12479
12479
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
12480
12480
  </div>
12481
- `,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",ke);function vt(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 xe=class extends m{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=v({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`
12481
+ `,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",ke);function vt(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 xe=class extends v{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=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){let e=this._api;try{this._loading=!0,this.render();let t=await e._get("/api/v2/api-keys");if(e!==this._api)return;this._keys=Array.isArray(t)?t:t?.keys||[],this._error=null}catch(t){if(e!==this._api)return;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 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`
12482
12482
  :host {
12483
12483
  display: block;
12484
12484
  }
@@ -12833,18 +12833,18 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
12833
12833
  <th>Actions</th>
12834
12834
  </tr>
12835
12835
  </thead>
12836
- <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,g;return p?g=`
12836
+ <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,u=this._rotateKeyId===n,m;return p?m=`
12837
12837
  <div class="confirm-delete">
12838
12838
  <span>Delete this key?</span>
12839
12839
  <button class="btn btn-sm btn-danger" data-action="confirm-delete" data-key-id="${n}">Yes</button>
12840
12840
  <button class="btn btn-sm" data-action="cancel-delete">No</button>
12841
12841
  </div>
12842
- `:g=`
12842
+ `:m=`
12843
12843
  <div class="action-row">
12844
12844
  <button class="btn btn-sm btn-warn" data-action="rotate" data-key-id="${n}">Rotate</button>
12845
12845
  <button class="btn btn-sm btn-danger" data-action="delete" data-key-id="${n}">Delete</button>
12846
12846
  </div>
12847
- ${h?`
12847
+ ${u?`
12848
12848
  <div class="rotate-inline">
12849
12849
  <span class="rotate-label">Grace period:</span>
12850
12850
  <input type="number" class="rotate-input" id="rotate-grace-${n}" value="${this._rotateGracePeriod}" min="0">
@@ -12860,7 +12860,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
12860
12860
  <td>${vt(o.created_at||o.created)}</td>
12861
12861
  <td>${vt(o.last_used_at||o.last_used)}</td>
12862
12862
  <td><span class="${c}">${this._escapeHtml(l)}</span></td>
12863
- <td><div class="actions-cell">${g}</div></td>
12863
+ <td><div class="actions-cell">${m}</div></td>
12864
12864
  </tr>
12865
12865
  `}).join("")}</tbody>
12866
12866
  </table>
@@ -12877,7 +12877,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
12877
12877
  ${s}
12878
12878
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
12879
12879
  </div>
12880
- `,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",xe);function Wt(d){return d?d.slug&&d.name?`${d.name} (${d.slug})`:d.name||d.slug||"Unknown":"Unknown"}var _e=class extends m{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=v({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`
12880
+ `,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",xe);function Wt(d){return d?d.slug&&d.name?`${d.name} (${d.slug})`:d.name||d.slug||"Unknown":"Unknown"}var _e=class extends v{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=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){let e=this._api;try{this._loading=!0;let t=await e._get("/api/v2/tenants");if(e!==this._api)return;this._tenants=Array.isArray(t)?t:t?.tenants||[],this._error=null}catch(t){if(e!==this._api)return;this._error=`Failed to load tenants: ${t.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`
12881
12881
  :host {
12882
12882
  display: inline-block;
12883
12883
  position: relative;
@@ -13036,7 +13036,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
13036
13036
  </button>
13037
13037
  ${s}
13038
13038
  </div>
13039
- `,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",_e);var Ye={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"}},Qt=100,ye=class extends m{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=v({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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,Qt),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:"Verify step complete: changes checked",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`
13039
+ `,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",_e);var Ye={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"}},Qt=100,ye=class extends v{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=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/v2/activity");if(e!==this._api)return;let i=t.events||t.activities||[];if(i.length>0){let a=i.filter(s=>!this._lastTimestamp||new Date(s.timestamp)>new Date(this._lastTimestamp)).map(s=>({id:s.id||crypto.randomUUID(),timestamp:s.timestamp||new Date().toISOString(),message:s.message||s.description||"",severity:s.severity||s.level||"info",source:s.source||s.component||"",isNew:!0}));a.length>0&&(this._items=[...a,...this._items].slice(0,Qt),this._lastTimestamp=a[0].timestamp,setTimeout(()=>{this._items.forEach(s=>s.isNew=!1)},600))}}catch{if(e!==this._api)return;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:"Verify step complete: changes checked",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`
13040
13040
  :host {
13041
13041
  display: block;
13042
13042
  }
@@ -13243,7 +13243,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
13243
13243
  ${s}
13244
13244
  </div>
13245
13245
  </div>
13246
- `,this._bindEvents(),!this._paused){let r=e.querySelector(".activity-feed");r&&(r.scrollTop=0)}}};customElements.get("loki-activity-stream")||customElements.define("loki-activity-stream",ye);var Xt={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)"}},ft={healthy:"var(--loki-green, #1FC5A8)",degraded:"var(--loki-yellow, #D4A03C)",down:"var(--loki-red, #C45B5B)",unknown:"var(--loki-text-muted, #939084)"},we=class extends m{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=v({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:1e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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`
13246
+ `,this._bindEvents(),!this._paused){let r=e.querySelector(".activity-feed");r&&(r.scrollTop=0)}}};customElements.get("loki-activity-stream")||customElements.define("loki-activity-stream",ye);var Xt={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)"}},ft={healthy:"var(--loki-green, #1FC5A8)",degraded:"var(--loki-yellow, #D4A03C)",down:"var(--loki-red, #C45B5B)",unknown:"var(--loki-text-muted, #939084)"},we=class extends v{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=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:1e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/v2/providers/health");if(e!==this._api)return;this._providers=t.providers||[]}catch{if(e!==this._api)return;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`
13247
13247
  :host {
13248
13248
  display: block;
13249
13249
  }
@@ -13474,7 +13474,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
13474
13474
  </div>
13475
13475
  ${t}
13476
13476
  </div>
13477
- `,this._bindEvents()}};customElements.get("loki-provider-health")||customElements.define("loki-provider-health",we);var We=[{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"}],Qe={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"}},$e=class extends m{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=v({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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`
13477
+ `,this._bindEvents()}};customElements.get("loki-provider-health")||customElements.define("loki-provider-health",we);var We=[{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"}],Qe={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"}},$e=class extends v{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=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/v2/pipeline/status");if(e!==this._api)return;this._stages=t.stages||[]}catch{if(e!==this._api)return;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`
13478
13478
  :host {
13479
13479
  display: block;
13480
13480
  }
@@ -13637,7 +13637,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
13637
13637
  border-radius: 50%;
13638
13638
  flex-shrink: 0;
13639
13639
  }
13640
- `}render(){let e=this.shadowRoot;if(!e)return;let t=We.map((a,s)=>{let r=this._getStageData(a.id),o=Qe[r.status]||Qe.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=`
13640
+ `}render(){let e=this.shadowRoot;if(!e)return;let t=We.map((a,s)=>{let r=this._getStageData(a.id),o=Qe[r.status]||Qe.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=`
13641
13641
  <div class="stage-node">
13642
13642
  <div class="stage-circle ${l?"active":""}"
13643
13643
  style="background: ${o.bgColor}; color: ${o.color}; border: 2px solid ${o.color};">
@@ -13647,12 +13647,12 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
13647
13647
  ${r.duration_ms?`<span class="stage-duration">${this._formatDuration(r.duration_ms)}</span>`:""}
13648
13648
  ${r.errors>0?`<span class="stage-error-count">${r.errors} error${r.errors>1?"s":""}</span>`:""}
13649
13649
  </div>
13650
- `;if(s<We.length-1){let g=this._getStageData(We[s+1].id),u=n,x=l||n&&(g.status==="active"||g.status==="waiting");return h+`
13650
+ `;if(s<We.length-1){let m=this._getStageData(We[s+1].id),g=n,x=l||n&&(m.status==="active"||m.status==="waiting");return u+`
13651
13651
  <div class="connector">
13652
- <div class="connector-line ${u?"completed":l?"active":"pending"}"></div>
13652
+ <div class="connector-line ${g?"completed":l?"active":"pending"}"></div>
13653
13653
  ${l?'<div class="flow-dot"></div>':""}
13654
13654
  </div>
13655
- `}return h}).join(""),i=Object.entries(Qe).map(([a,s])=>`<div class="legend-item">
13655
+ `}return u}).join(""),i=Object.entries(Qe).map(([a,s])=>`<div class="legend-item">
13656
13656
  <div class="legend-dot" style="background: ${s.color};"></div>
13657
13657
  <span>${s.label}</span>
13658
13658
  </div>`).join("");e.innerHTML=`
@@ -13668,8 +13668,8 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
13668
13668
  ${i}
13669
13669
  </div>
13670
13670
  </div>
13671
- `}};customElements.get("loki-pipeline-view")||customElements.define("loki-pipeline-view",$e);var Ee={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 Ce=class extends m{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=v({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:15e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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=Ee[e.type]||Ee.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}"
13672
- 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}"
13671
+ `}};customElements.get("loki-pipeline-view")||customElements.define("loki-pipeline-view",$e);var Ee={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 Ce=class extends v{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=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:15e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/v2/memory/graph");if(e!==this._api)return;this._nodes=t.nodes||[],this._edges=t.edges||[]}catch{if(e!==this._api)return;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(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=Ee[e.type]||Ee.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}"
13672
+ 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="${t},${i-u} ${t+u},${i} ${t},${i+u} ${t-u},${i}"
13673
13673
  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"
13674
13674
  stroke="${o}" stroke-width="${n}" opacity="${l}" />`}let p=`<text x="${t}" y="${i+s/2+14}" text-anchor="middle" font-size="10"
13675
13675
  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;">
@@ -13856,7 +13856,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
13856
13856
  </div>
13857
13857
  <div class="legend">${n}</div>
13858
13858
  </div>
13859
- `,this._bindEvents()}};customElements.get("loki-memory-graph")||customElements.define("loki-memory-graph",Ce);var Xe={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"}},Se=class extends m{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=v({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:1e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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=Xe[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`
13859
+ `,this._bindEvents()}};customElements.get("loki-memory-graph")||customElements.define("loki-memory-graph",Ce);var Xe={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"}},Se=class extends v{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=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:1e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/v2/cost/breakdown");if(e!==this._api)return;this._phases=t.phases||[],this._budget=t.budget_usd||null,this._totalCost=t.total_usd||this._phases.reduce((i,a)=>i+(a.cost_usd||0),0)}catch{if(e!==this._api)return;this._phases.length===0&&(this._phases=this._getDemoData(),this._budget=10,this._totalCost=this._phases.reduce((t,i)=>t+i.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=Xe[i.phase]||{label:i.phase};t.innerHTML=`<strong>${this._escapeHtml(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`
13860
13860
  :host {
13861
13861
  display: block;
13862
13862
  }
@@ -14046,13 +14046,13 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
14046
14046
  </div>
14047
14047
  <div class="empty-state">Cost details will appear once a build starts running.</div>
14048
14048
  </div>
14049
- `;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=Xe[l.phase]||{color:"var(--loki-text-muted)",label:l.phase},p=(l.cost_usd||0)/a*i,h=this._hoveredPhase===l.phase;return`
14049
+ `;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=Xe[l.phase]||{color:"var(--loki-text-muted)",label:l.phase},p=(l.cost_usd||0)/a*i,u=this._hoveredPhase===l.phase;return`
14050
14050
  <div class="bar-group">
14051
14051
  <span class="bar-value">${this._formatCost(l.cost_usd)}</span>
14052
14052
  <div class="waterfall-bar" data-phase="${this._escapeHtml(l.phase)}"
14053
- style="height: ${Math.max(p,4)}px; background: ${c.color}; ${h?"opacity: 0.85;":""}">
14053
+ style="height: ${Math.max(p,4)}px; background: ${c.color}; ${u?"opacity: 0.85;":""}">
14054
14054
  </div>
14055
- <span class="bar-label">${c.label}</span>
14055
+ <span class="bar-label">${this._escapeHtml(c.label)}</span>
14056
14056
  </div>
14057
14057
  `}).join(""),o=s!=null?`
14058
14058
  <div class="budget-line" style="bottom: ${s+40}px;">
@@ -14060,7 +14060,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
14060
14060
  </div>
14061
14061
  `:"",n=this._phases.map(l=>{let c=Xe[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">
14062
14062
  <div class="summary-dot" style="background: ${c.color};"></div>
14063
- <span class="summary-label">${c.label}</span>
14063
+ <span class="summary-label">${this._escapeHtml(c.label)}</span>
14064
14064
  <span class="summary-value">${this._formatCost(l.cost_usd)} (${p}%)</span>
14065
14065
  </div>`}).join("");e.innerHTML=`
14066
14066
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
@@ -14080,7 +14080,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
14080
14080
  </div>
14081
14081
  </div>
14082
14082
  </div>
14083
- `,this._bindEvents()}};customElements.get("loki-cost-waterfall")||customElements.define("loki-cost-waterfall",Se);var ei={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"}},Ae=class extends m{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=v({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:1e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=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`
14083
+ `,this._bindEvents()}};customElements.get("loki-cost-waterfall")||customElements.define("loki-cost-waterfall",Se);var ei={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"}},Ae=class extends v{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=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:1e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/v2/agents/leaderboard");if(e!==this._api)return;let i=t.agents||[],a={};i.forEach((s,r)=>{a[s.type||s.name]=r+1}),this._previousRanks={...this._currentRanks||{}},this._currentRanks=a,this._agents=i}catch{if(e!==this._api)return;this._agents.length===0&&(this._agents=this._getDemoData(),this._currentRanks={},this._agents.forEach((t,i)=>{this._currentRanks[t.type]=i+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`
14084
14084
  :host {
14085
14085
  display: block;
14086
14086
  }
@@ -14293,7 +14293,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
14293
14293
  </div>
14294
14294
  <div class="empty-state">No agent performance data available</div>
14295
14295
  </div>
14296
- `;return}let t=this._agents.map((i,a)=>{let s=a+1,r=ei[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,g;r?g=`<div class="rank-badge" style="background: ${r.bg}; color: ${r.border};">${s}</div>`:g=`<span class="rank-number" style="color: var(--loki-text-muted);">${s}</span>`;let u="";n>0?u=`<span class="rank-change rank-up">+${n}</span>`:n<0&&(u=`<span class="rank-change rank-down">${n}</span>`);let x=l?`
14296
+ `;return}let t=this._agents.map((i,a)=>{let s=a+1,r=ei[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,m;r?m=`<div class="rank-badge" style="background: ${r.bg}; color: ${r.border};">${s}</div>`:m=`<span class="rank-number" style="color: var(--loki-text-muted);">${s}</span>`;let g="";n>0?g=`<span class="rank-change rank-up">+${n}</span>`:n<0&&(g=`<span class="rank-change rank-down">${n}</span>`);let x=l?`
14297
14297
  <div class="agent-detail">
14298
14298
  <div class="detail-metric">
14299
14299
  <span class="detail-label">Total Cost</span>
@@ -14311,7 +14311,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
14311
14311
  `:"";return`
14312
14312
  <div class="agent-row ${s<=3?"top-3":""}" data-agent="${this._escapeHtml(o)}"
14313
14313
  style="${r?"border-left-color: "+r.border+";":""}">
14314
- <div class="rank-cell">${g}${u}</div>
14314
+ <div class="rank-cell">${m}${g}</div>
14315
14315
  <div class="agent-name-cell">
14316
14316
  <span class="agent-name">${this._escapeHtml(i.name||i.type)}</span>
14317
14317
  <span class="agent-type">${this._escapeHtml(i.type||"")}</span>
@@ -14320,7 +14320,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
14320
14320
  <div class="metric-cell">
14321
14321
  <div class="quality-score">
14322
14322
  <span style="color: ${c};">${(i.quality||0).toFixed(1)}</span>
14323
- <div class="quality-bar"><div class="quality-fill" style="width: ${h}%; background: ${c};"></div></div>
14323
+ <div class="quality-bar"><div class="quality-fill" style="width: ${u}%; background: ${c};"></div></div>
14324
14324
  </div>
14325
14325
  </div>
14326
14326
  <div class="metric-cell">
@@ -14346,7 +14346,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
14346
14346
  ${t}
14347
14347
  </div>
14348
14348
  </div>
14349
- `,this._bindEvents()}};customElements.get("loki-agent-leaderboard")||customElements.define("loki-agent-leaderboard",Ae);var bt=50,Te=class extends m{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=v({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=bt){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`
14349
+ `,this._bindEvents()}};customElements.get("loki-agent-leaderboard")||customElements.define("loki-agent-leaderboard",Ae);var bt=50,Te=class extends v{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=h({baseUrl:i}),this._loadStatus());break;case"theme":this._applyTheme(),this.render();break}}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_stopPolling(){}async _loadStatus(){let e=this._api;this._statusLoading=!0,this._statusError=null,this.render();try{let t=await e.get("/api/managed/status");if(e!==this._api)return;this._status=t}catch(t){if(e!==this._api)return;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(e=bt){let t=this._api;this._eventsLoading=!0,this._eventsError=null,this.render();try{let i=await t.get("/api/managed/events?limit="+encodeURIComponent(e));if(t!==this._api)return;Array.isArray(i)?(this._events=i,this._eventsCount=i.length,this._eventsSource=null):i&&typeof i=="object"?(this._events=Array.isArray(i.events)?i.events:[],this._eventsCount=typeof i.count=="number"?i.count:this._events.length,this._eventsSource=i.source||null):(this._events=[],this._eventsCount=0,this._eventsSource=null)}catch(i){if(t!==this._api)return;this._eventsError=i&&i.message?i.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}let t=this._api;this._lookupLoading=!0,this._lookupError=null,this._lookupResult=null,this.render();try{let i="/api/managed/memory_versions/"+encodeURIComponent(e),a=await t.get(i);if(t!==this._api)return;this._lookupResult=a}catch(i){if(t!==this._api)return;this._lookupError=i&&i.message?i.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`
14350
14350
  <div class="error-banner" role="alert">
14351
14351
  <strong>Status error:</strong>
14352
14352
  <span>${this._escapeHtml(this._statusError)}</span>
@@ -14737,7 +14737,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
14737
14737
  </div>
14738
14738
  `:this._statusError?"":this._renderDisabledNotice()}
14739
14739
  </div>
14740
- `,this._attachEventHandlers()}};customElements.get("loki-managed-memory-panel")||customElements.define("loki-managed-memory-panel",Te);var Le=class extends m{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._ensureMarkdownStyles(),this._setupApi(),this._loadList(),this._poll=b({loadFn:()=>this._loadList(),intervalMs:1e4,element:this,immediate:!1})}disconnectedCallback(){super.disconnectedCallback(),this._poll&&(this._poll.stop(),this._poll=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=v({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}}_ensureMarkdownStyles(){if(typeof document>"u"||!document.head||document.getElementById("loki-markdown-styles"))return;let e=document.createElement("style");e.id="loki-markdown-styles",e.textContent=L,document.head.appendChild(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=`
14740
+ `,this._attachEventHandlers()}};customElements.get("loki-managed-memory-panel")||customElements.define("loki-managed-memory-panel",Te);var Le=class extends v{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._ensureMarkdownStyles(),this._setupApi(),this._loadList(),this._poll=b({loadFn:()=>this._loadList(),intervalMs:1e4,element:this,immediate:!1})}disconnectedCallback(){super.disconnectedCallback(),this._poll&&(this._poll.stop(),this._poll=null)}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadList()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||(typeof window<"u"?window.location.origin:"");this._api=h({baseUrl:e})}async _loadList(){let e=this._api;this._loading=!0,this._error=null;try{let t=await e.get("/api/escalations");if(e!==this._api)return;this._items=Array.isArray(t&&t.escalations)?t.escalations:[]}catch(t){if(e!==this._api)return;this._error=t&&t.message?t.message:String(t),this._items=[]}finally{this._loading=!1,this.render()}}async _openFile(e){let t=this._api;this._activeFile=e,this._activeBody=null,this._activeBodyError=null,this.render();try{let i=(t.baseUrl||"")+"/api/escalations/"+encodeURIComponent(e),a=await fetch(i,{credentials:"include"});if(!a.ok)throw new Error("HTTP "+a.status);let s=await a.text();if(t!==this._api)return;this._activeBody=s}catch(i){if(t!==this._api)return;this._activeBodyError=i&&i.message?i.message:String(i)}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}}_ensureMarkdownStyles(){if(typeof document>"u"||!document.head||document.getElementById("loki-markdown-styles"))return;let e=document.createElement("style");e.id="loki-markdown-styles",e.textContent=L,document.head.appendChild(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=`
14741
14741
  <style>
14742
14742
  :host { display: block; }
14743
14743
  .esc-wrapper {
@@ -14813,7 +14813,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
14813
14813
  white-space: pre-wrap;
14814
14814
  }
14815
14815
  </style>
14816
- `,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">No handoff notes yet. If a build needs your attention, its notes 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 md-body">'+C(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",Le);var ze=class extends m{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._poll=b({loadFn:()=>this._load(),intervalMs:3e4,element:this,immediate:!1})}disconnectedCallback(){super.disconnectedCallback(),this._poll&&(this._poll.stop(),this._poll=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=v({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(u=>"<li>"+this._escapeHtml(String(u))+"</li>").join("")+"</ul>");let h="";return Array.isArray(e.issues)&&e.issues.length>0&&(h='<ul class="ct-issues">'+e.issues.map(u=>{let x=this._escapeHtml(u.severity||""),k=this._escapeHtml(u.description||"");return'<li><span class="ct-issue-sev ct-issue-sev-'+x.toLowerCase()+'">'+x+"</span> "+k+"</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(u=>!u.is_contrarian),n=r.filter(u=>u.is_contrarian),l=o.map(u=>this._voterRowHtml(u,!1)).join(""),c="";e.contrarian_triggered&&(c='<div class="ct-contrarian-section"><div class="ct-section-label">Anti-Sycophancy Check</div>'+n.map(x=>this._voterRowHtml(x,e.contrarian_flipped)).join("")+"</div>");let p=typeof e.approve_count=="number"?e.approve_count:"--",h=typeof e.reject_count=="number"?e.reject_count:"--",g=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: "+g+'</div><div class="ct-voters">'+l+"</div>"+c+"</div>"}render(){let e=this.shadowRoot||this;if(!e)return;let t=`
14816
+ `,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">No handoff notes yet. If a build needs your attention, its notes 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 md-body">'+C(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",Le);var ze=class extends v{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._poll=b({loadFn:()=>this._load(),intervalMs:3e4,element:this,immediate:!1})}disconnectedCallback(){super.disconnectedCallback(),this._poll&&(this._poll.stop(),this._poll=null)}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._load()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||(typeof window<"u"?window.location.origin:"");this._api=h({baseUrl:e})}async _load(){this._loading=!0,this._error=null;let e=this._api;try{let t=await e.get("/api/council/transcripts?limit=10");if(e!==this._api)return;this._transcripts=Array.isArray(t&&t.transcripts)?t.transcripts:[]}catch(t){if(e!==this._api)return;this._error=t&&t.message?t.message:String(t),this._transcripts=[]}try{let t=await e.get("/api/council/transcripts?limit=20&type_prefix=claude_hook_");if(e!==this._api)return;this._hookEvents=Array.isArray(t&&t.hook_events)?t.hook_events:[]}catch{if(e!==this._api)return;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(g=>"<li>"+this._escapeHtml(String(g))+"</li>").join("")+"</ul>");let u="";return Array.isArray(e.issues)&&e.issues.length>0&&(u='<ul class="ct-issues">'+e.issues.map(g=>{let x=this._escapeHtml(g.severity||""),k=this._escapeHtml(g.description||"");return'<li><span class="ct-issue-sev ct-issue-sev-'+x.toLowerCase()+'">'+x+"</span> "+k+"</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(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(g=>!g.is_contrarian),n=r.filter(g=>g.is_contrarian),l=o.map(g=>this._voterRowHtml(g,!1)).join(""),c="";e.contrarian_triggered&&(c='<div class="ct-contrarian-section"><div class="ct-section-label">Anti-Sycophancy Check</div>'+n.map(x=>this._voterRowHtml(x,e.contrarian_flipped)).join("")+"</div>");let p=typeof e.approve_count=="number"?e.approve_count:"--",u=typeof e.reject_count=="number"?e.reject_count:"--",m=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: "+u+" &middot; Threshold: "+m+'</div><div class="ct-voters">'+l+"</div>"+c+"</div>"}render(){let e=this.shadowRoot||this;if(!e)return;let t=`
14817
14817
  <style>
14818
14818
  :host { display: block; margin-top: 24px; }
14819
14819
  .ct-wrapper {
@@ -14982,7 +14982,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
14982
14982
  .ct-badge-da { background: #fdf3d4; color: #8a6c0e; }
14983
14983
  .ct-badge-unknown { background: var(--bg-secondary, #F8F4F0); color: var(--text-muted, #939084); }
14984
14984
  </style>
14985
- `,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 review rounds recorded yet. Transcripts appear after the first completion 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",ze);var ti=[{id:"overview",label:"Overview"},{id:"architecture",label:"Architecture"},{id:"modules",label:"Key Modules"},{id:"data-flow",label:"Data Flow"},{id:"ask",label:"Ask"}],De=class extends m{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._metaPromise=null,this._sectionCache={},this._sectionState={},this._question="",this._answer=null,this._asking=!1,this._askError=null,this._mermaid=null,this._mermaidPromise=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadMeta()}disconnectedCallback(){super.disconnectedCallback&&super.disconnectedCallback(),this._disconnected=!0}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=v({baseUrl:e})}_loadMeta(){return this._loading=!0,this._error=null,this.render(),this._metaPromise=(async()=>{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()}})(),this._metaPromise}async _loadSection(e){if(this._sectionCache[e])return this._sectionState[e]=this._sectionCache[e].error?"error":"loaded",this._sectionCache[e];this._sectionState[e]="loading";try{let t=await this._api._get(`/api/wiki/${encodeURIComponent(e)}`);return this._sectionCache[e]=t,this._sectionState[e]=t&&t.error?"error":"loaded",t}catch(t){let i={error:t&&t.message||"load failed"};return this._sectionCache[e]=i,this._sectionState[e]="error",i}}async _selectTab(e){if(this._activeTab=e,e!=="architecture"&&e!=="modules"&&e!=="data-flow"){this.render();return}if(this._sectionCache[e]){this.render();return}if(this._sectionState[e]="loading",this.render(),this._metaPromise)try{await this._metaPromise}catch{}if(!(this._disconnected||this._activeTab!==e)){if(!this._meta||!this._meta.generated){delete this._sectionState[e],this.render();return}await this._loadSection(e),!(this._disconnected||this._activeTab!==e)&&this.render()}}_ensureMermaid(){return this._mermaid?Promise.resolve(this._mermaid):this._mermaidPromise?this._mermaidPromise:(this._mermaidPromise=(async()=>{try{if(typeof window<"u"&&window.mermaid)return this._mermaid=window.mermaid,this._mermaid;if(typeof window>"u"||typeof document>"u")return null;let t=`${this._api&&this._api.baseUrl||window.location.origin}/assets/mermaid.min.js`;return await new Promise((i,a)=>{let s=document.querySelector("script[data-loki-mermaid]");if(s){s.addEventListener("load",i,{once:!0}),s.addEventListener("error",a,{once:!0}),window.mermaid&&i();return}let r=document.createElement("script");r.src=t,r.async=!0,r.setAttribute("data-loki-mermaid","1"),r.addEventListener("load",i,{once:!0}),r.addEventListener("error",()=>a(new Error("mermaid load failed")),{once:!0}),document.head.appendChild(r)}),this._mermaid=typeof window<"u"&&window.mermaid||null,this._mermaid}catch{return null}})(),this._mermaidPromise)}async _maybeRenderDiagram(e){let t=this._sectionCache[e],i=this._diagramSource(t);if(!i)return;let a;try{a=await this._ensureMermaid()}catch{a=null}if(!(!a||this._disconnected||this._activeTab!==e))try{a.initialize({startOnLoad:!1,securityLevel:"strict",theme:this._mermaidTheme(),flowchart:{htmlLabels:!1,useMaxWidth:!0},deterministicIds:!0}),typeof a.parse=="function"&&await a.parse(i);let s=`wiki-mmd-${e}-${Date.now()}`,r=await a.render(s,i),o=r&&(r.svg||r);if(typeof o!="string"||o.indexOf("<svg")===-1||this._disconnected||this._activeTab!==e||!this.shadowRoot)return;let n=this.shadowRoot.getElementById("wiki-diagram");n&&(n.innerHTML=o)}catch{}}_mermaidTheme(){return(this.getAttribute("theme")||typeof document<"u"&&document.documentElement.getAttribute("data-loki-theme")||"").toLowerCase().includes("dark")?"dark":"neutral"}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>`}_renderNotGenerated(){return`<div class="es">
14985
+ `,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 review rounds recorded yet. Transcripts appear after the first completion 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",ze);var ti=[{id:"overview",label:"Overview"},{id:"architecture",label:"Architecture"},{id:"modules",label:"Key Modules"},{id:"data-flow",label:"Data Flow"},{id:"ask",label:"Ask"}],De=class extends v{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._metaPromise=null,this._sectionCache={},this._sectionState={},this._question="",this._answer=null,this._asking=!1,this._askError=null,this._mermaid=null,this._mermaidPromise=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadMeta()}disconnectedCallback(){super.disconnectedCallback&&super.disconnectedCallback(),this._disconnected=!0}attributeChangedCallback(e,t,i){e==="api-url"&&this._api&&(this._api=h({baseUrl:i}))}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_loadMeta(){this._loading=!0,this._error=null,this.render();let e=this._api;return this._metaPromise=(async()=>{try{let t=await e._get("/api/wiki");if(e!==this._api)return;this._meta=t}catch(t){if(e!==this._api)return;this._error=t&&t.message?t.message:"Failed to load wiki"}finally{this._loading=!1,this.render()}})(),this._metaPromise}async _loadSection(e){if(this._sectionCache[e])return this._sectionState[e]=this._sectionCache[e].error?"error":"loaded",this._sectionCache[e];this._sectionState[e]="loading";let t=this._api;try{let i=await t._get(`/api/wiki/${encodeURIComponent(e)}`);return t!==this._api?this._sectionCache[e]||{error:"stale"}:(this._sectionCache[e]=i,this._sectionState[e]=i&&i.error?"error":"loaded",i)}catch(i){if(t!==this._api)return this._sectionCache[e]||{error:"stale"};let a={error:i&&i.message||"load failed"};return this._sectionCache[e]=a,this._sectionState[e]="error",a}}async _selectTab(e){if(this._activeTab=e,e!=="architecture"&&e!=="modules"&&e!=="data-flow"){this.render();return}if(this._sectionCache[e]){this.render();return}if(this._sectionState[e]="loading",this.render(),this._metaPromise)try{await this._metaPromise}catch{}if(!(this._disconnected||this._activeTab!==e)){if(!this._meta||!this._meta.generated){delete this._sectionState[e],this.render();return}await this._loadSection(e),!(this._disconnected||this._activeTab!==e)&&this.render()}}_ensureMermaid(){return this._mermaid?Promise.resolve(this._mermaid):this._mermaidPromise?this._mermaidPromise:(this._mermaidPromise=(async()=>{try{if(typeof window<"u"&&window.mermaid)return this._mermaid=window.mermaid,this._mermaid;if(typeof window>"u"||typeof document>"u")return null;let t=`${this._api&&this._api.baseUrl||window.location.origin}/assets/mermaid.min.js`;return await new Promise((i,a)=>{let s=document.querySelector("script[data-loki-mermaid]");if(s){s.addEventListener("load",i,{once:!0}),s.addEventListener("error",a,{once:!0}),window.mermaid&&i();return}let r=document.createElement("script");r.src=t,r.async=!0,r.setAttribute("data-loki-mermaid","1"),r.addEventListener("load",i,{once:!0}),r.addEventListener("error",()=>a(new Error("mermaid load failed")),{once:!0}),document.head.appendChild(r)}),this._mermaid=typeof window<"u"&&window.mermaid||null,this._mermaid}catch{return null}})(),this._mermaidPromise)}async _maybeRenderDiagram(e){let t=this._sectionCache[e],i=this._diagramSource(t);if(!i)return;let a;try{a=await this._ensureMermaid()}catch{a=null}if(!(!a||this._disconnected||this._activeTab!==e))try{a.initialize({startOnLoad:!1,securityLevel:"strict",theme:this._mermaidTheme(),flowchart:{htmlLabels:!1,useMaxWidth:!0},deterministicIds:!0}),typeof a.parse=="function"&&await a.parse(i);let s=`wiki-mmd-${e}-${Date.now()}`,r=await a.render(s,i),o=r&&(r.svg||r);if(typeof o!="string"||o.indexOf("<svg")===-1||this._disconnected||this._activeTab!==e||!this.shadowRoot)return;let n=this.shadowRoot.getElementById("wiki-diagram");n&&(n.innerHTML=o)}catch{}}_mermaidTheme(){return(this.getAttribute("theme")||typeof document<"u"&&document.documentElement.getAttribute("data-loki-theme")||"").toLowerCase().includes("dark")?"dark":"neutral"}async _ask(){let e=(this._question||"").trim();if(!e)return;this._asking=!0,this._askError=null,this._answer=null,this.render();let t=this._api;try{let i=await t._post("/api/wiki/ask",{question:e},{timeout:2e5});if(t!==this._api)return;this._answer=i}catch(i){if(t!==this._api)return;this._askError=i&&i.message?i.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>`}_renderNotGenerated(){return`<div class="es">
14986
14986
  <div class="es-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg></div>
14987
14987
  <div class="es-title">No wiki generated yet</div>
14988
14988
  <div class="es-desc">Generate a cited codebase wiki to browse architecture, modules, and data flow. Every section links to real file:line locations.</div>
@@ -15139,7 +15139,7 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
15139
15139
  </style>
15140
15140
  <div class="tabs">${e}</div>
15141
15141
  <div class="content">${this._renderBody()}</div>
15142
- `,this.shadowRoot.querySelectorAll(".tab").forEach(o=>{o.addEventListener("click",()=>this._selectTab(o.dataset.tab))});let t=this.shadowRoot.getElementById("wiki-q");t&&(t.addEventListener("input",o=>{this._question=o.target.value}),t.addEventListener("keydown",o=>{o.key==="Enter"&&this._ask()}));let i=this.shadowRoot.getElementById("wiki-ask-btn");i&&i.addEventListener("click",()=>this._ask());let a=this.shadowRoot.getElementById("wiki-gen-copy");a&&a.addEventListener("click",()=>this._copyGenerateCmd(a));let s=this.shadowRoot.getElementById("wiki-retry-btn");s&&s.addEventListener("click",()=>{this._sectionCache={},this._sectionState={},this._loadMeta()});let r=this._activeTab;(r==="architecture"||r==="data-flow")&&this._sectionCache[r]&&!this._sectionCache[r].error&&this.shadowRoot.getElementById("wiki-diagram")&&this._maybeRenderDiagram(r)}_copyGenerateCmd(e){let t="loki wiki generate",i=()=>{let a=e.innerHTML;e.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>',setTimeout(()=>{e.innerHTML=a},1500)};navigator.clipboard&&navigator.clipboard.writeText&&navigator.clipboard.writeText(t).then(i).catch(()=>{})}};customElements.get("loki-wiki-browser")||customElements.define("loki-wiki-browser",De);var kt={prd:"PRD file",spec:"Generated spec",issue:"GitHub issue",brief:"One-line brief","codebase-analysis":"Codebase analysis",none:"No spec yet",unknown:"Unknown spec"},Me=class extends m{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._api=null,this._spec=null,this._history=null,this._loading=!1,this._error=null,this._historyError=null,this._historyOpen=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._load()}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=v({baseUrl:e})}async _load(){this._loading=!0,this._error=null,this.render();try{this._spec=await this._api._get("/api/spec")}catch(e){this._error=e&&e.message?e.message:"Failed to load spec"}finally{this._loading=!1,this.render()}try{let e=await this._api._get("/api/spec/history");this._history=e&&Array.isArray(e.history)?e.history:[]}catch(e){this._historyError=e&&e.message?e.message:"Failed to load history",this._history=[]}this.render()}_esc(e){return String(e??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}_when(e){if(!e)return"unknown time";let t=new Date(e);if(isNaN(t.getTime()))return this._esc(e);try{return t.toLocaleString()}catch{return this._esc(e)}}_typeLabel(e){return kt[e]||kt.unknown}_typeBadge(e){return`<span class="badge badge-${this._esc(e)}">${this._esc(this._typeLabel(e))}</span>`}_renderActive(){if(this._loading)return'<div class="es-loading"><span class="es-spinner"></span> Loading active spec...</div>';if(this._error)return this._renderError(this._error);let e=this._spec;if(!e||!e.type||e.type==="none")return this._renderEmpty();let t=this._typeBadge(e.type),i="",a="";if(e.type==="prd"||e.type==="spec"){e.path&&(i=`<code class="src">${this._esc(e.path)}</code>`);let s=e.content||"";s.trim()?a=`<div class="body md-body">${C(s)}</div>`+(e.truncated?'<p class="dim">Preview truncated -- see the full file on disk.</p>':""):a='<p class="dim">No content available.</p>'}else if(e.type==="issue"){i=e.ref?`<code class="src">${this._esc(e.ref)}</code>`:"";let r=e.title?`<p class="issue-title">${this._esc(e.title)}</p>`:"",o=(e.body||"").trim()?`<div class="body md-body">${C(e.body)}</div>`+(e.truncated?'<p class="dim">Preview truncated.</p>':""):"";a=`${r}${o}`}else if(e.type==="brief"){let s=(e.text||"").trim();a=s?`<pre class="body brief">${this._esc(s)}</pre>`+(e.truncated?'<p class="dim">Preview truncated.</p>':""):'<p class="dim">No brief recorded.</p>'}else e.type==="codebase-analysis"?a='<p class="dim">No explicit spec. Loki is building from an analysis of the existing codebase.</p>':a='<p class="dim">The spec source could not be resolved.</p>';return`<div class="active">
15142
+ `,this.shadowRoot.querySelectorAll(".tab").forEach(o=>{o.addEventListener("click",()=>this._selectTab(o.dataset.tab))});let t=this.shadowRoot.getElementById("wiki-q");t&&(t.addEventListener("input",o=>{this._question=o.target.value}),t.addEventListener("keydown",o=>{o.key==="Enter"&&this._ask()}));let i=this.shadowRoot.getElementById("wiki-ask-btn");i&&i.addEventListener("click",()=>this._ask());let a=this.shadowRoot.getElementById("wiki-gen-copy");a&&a.addEventListener("click",()=>this._copyGenerateCmd(a));let s=this.shadowRoot.getElementById("wiki-retry-btn");s&&s.addEventListener("click",()=>{this._sectionCache={},this._sectionState={},this._loadMeta()});let r=this._activeTab;(r==="architecture"||r==="data-flow")&&this._sectionCache[r]&&!this._sectionCache[r].error&&this.shadowRoot.getElementById("wiki-diagram")&&this._maybeRenderDiagram(r)}_copyGenerateCmd(e){let t="loki wiki generate",i=()=>{let a=e.innerHTML;e.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>',setTimeout(()=>{e.innerHTML=a},1500)};navigator.clipboard&&navigator.clipboard.writeText&&navigator.clipboard.writeText(t).then(i).catch(()=>{})}};customElements.get("loki-wiki-browser")||customElements.define("loki-wiki-browser",De);var kt={prd:"PRD file",spec:"Generated spec",issue:"GitHub issue",brief:"One-line brief","codebase-analysis":"Codebase analysis",none:"No spec yet",unknown:"Unknown spec"},He=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._api=null,this._spec=null,this._history=null,this._loading=!1,this._error=null,this._historyError=null,this._historyOpen=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._load()}attributeChangedCallback(e,t,i){e==="api-url"&&this._api&&(this._api=h({baseUrl:i}))}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _load(){let e=this._api;this._loading=!0,this._error=null,this.render();try{let t=await e._get("/api/spec");if(e!==this._api)return;this._spec=t}catch(t){if(e!==this._api)return;this._error=t&&t.message?t.message:"Failed to load spec"}finally{e===this._api&&(this._loading=!1,this.render())}try{let t=await e._get("/api/spec/history");if(e!==this._api)return;this._history=t&&Array.isArray(t.history)?t.history:[]}catch(t){if(e!==this._api)return;this._historyError=t&&t.message?t.message:"Failed to load history",this._history=[]}this.render()}_esc(e){return String(e??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}_when(e){if(!e)return"unknown time";let t=new Date(e);if(isNaN(t.getTime()))return this._esc(e);try{return t.toLocaleString()}catch{return this._esc(e)}}_typeLabel(e){return kt[e]||kt.unknown}_typeBadge(e){return`<span class="badge badge-${this._esc(e)}">${this._esc(this._typeLabel(e))}</span>`}_renderActive(){if(this._loading)return'<div class="es-loading"><span class="es-spinner"></span> Loading active spec...</div>';if(this._error)return this._renderError(this._error);let e=this._spec;if(!e||!e.type||e.type==="none")return this._renderEmpty();let t=this._typeBadge(e.type),i="",a="";if(e.type==="prd"||e.type==="spec"){e.path&&(i=`<code class="src">${this._esc(e.path)}</code>`);let s=e.content||"";s.trim()?a=`<div class="body md-body">${C(s)}</div>`+(e.truncated?'<p class="dim">Preview truncated -- see the full file on disk.</p>':""):a='<p class="dim">No content available.</p>'}else if(e.type==="issue"){i=e.ref?`<code class="src">${this._esc(e.ref)}</code>`:"";let r=e.title?`<p class="issue-title">${this._esc(e.title)}</p>`:"",o=(e.body||"").trim()?`<div class="body md-body">${C(e.body)}</div>`+(e.truncated?'<p class="dim">Preview truncated.</p>':""):"";a=`${r}${o}`}else if(e.type==="brief"){let s=(e.text||"").trim();a=s?`<pre class="body brief">${this._esc(s)}</pre>`+(e.truncated?'<p class="dim">Preview truncated.</p>':""):'<p class="dim">No brief recorded.</p>'}else e.type==="codebase-analysis"?a='<p class="dim">No explicit spec. Loki is building from an analysis of the existing codebase.</p>':a='<p class="dim">The spec source could not be resolved.</p>';return`<div class="active">
15143
15143
  <div class="active-head">
15144
15144
  <span class="active-label">Building from</span>
15145
15145
  ${t}
@@ -15241,13 +15241,13 @@ var LokiDashboard=(()=>{var He=Object.defineProperty;var _t=Object.getOwnPropert
15241
15241
  </style>
15242
15242
  <div class="active-wrap">${this._renderActive()}</div>
15243
15243
  ${this._error||this._spec&&this._spec.type==="none"?"":this._renderHistory()}
15244
- `;let e=this.shadowRoot.getElementById("spec-retry-btn");e&&e.addEventListener("click",()=>this._load());let t=this.shadowRoot.getElementById("hist-toggle");t&&t.addEventListener("click",()=>{this._historyOpen=!this._historyOpen,this.render()})}};customElements.get("loki-spec-panel")||customElements.define("loki-spec-panel",Me);(function(){"use strict";if(typeof window>"u"||typeof customElements>"u")return;var d={open:'<circle cx="178" cy="214" r="7" class="fillInk"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="180.5" cy="211.5" r="2" class="fillHi"/><circle cx="246.5" cy="211.5" r="2" class="fillHi"/>',happy:'<path class="ink" d="M171 216c4-6 10-6 14 0"/><path class="ink" d="M237 216c4-6 10-6 14 0"/>',lookUp:'<circle cx="178" cy="214" r="7" class="fillInk"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="180" cy="210" r="2.4" class="fillHi"/><circle cx="246" cy="210" r="2.4" class="fillHi"/>',wide:'<circle cx="178" cy="213" r="8.5" class="fillInk"/><circle cx="244" cy="213" r="8.5" class="fillInk"/><circle cx="181" cy="210" r="2.6" class="fillHi"/><circle cx="247" cy="210" r="2.6" class="fillHi"/>',focused:'<path class="inkBold" d="M170 214h16"/><path class="inkBold" d="M236 214h16"/>',closed:'<path class="ink" d="M170 214c4 5 10 5 14 0"/><path class="ink" d="M236 214c4 5 10 5 14 0"/>',worried:'<circle cx="178" cy="216" r="6" class="fillInk"/><circle cx="244" cy="216" r="6" class="fillInk"/><circle cx="180" cy="213.5" r="1.8" class="fillHi"/><circle cx="246" cy="213.5" r="1.8" class="fillHi"/>',wink:'<path class="ink" d="M171 214c4-5 10-5 14 0"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="246.5" cy="211.5" r="2" class="fillHi"/>'},e={none:"",raised:'<path class="inkThin" d="M168 198c5-3 12-3 17 0"/><path class="inkThin" d="M237 198c5-3 12-3 17 0"/>',furrow:'<path class="inkThin" d="M168 199l16 3"/><path class="inkThin" d="M254 199l-16 3"/>',worried:'<path class="inkThin" d="M168 201l16-4"/><path class="inkThin" d="M254 201l-16-4"/>'},t={smile:'<path class="ink" d="M192 244c12 12 26 12 38 0"/>',openSmile:'<path class="fillInk" d="M194 243c8 16 26 16 34 0c-10 6-24 6-34 0z"/>',flat:'<path class="ink" d="M198 248h26"/>',o:'<ellipse cx="211" cy="248" rx="6" ry="7" class="ink"/>',frown:'<path class="ink" d="M192 250c12-12 26-12 38 0"/>',soft:'<path class="ink" d="M196 246c9 7 19 7 28 0"/>',proud:'<path class="ink" d="M194 245c10 9 24 9 32 -2"/>'},i={none:"",wave:'<g class="prop-wave"><path class="ink" d="M318 250c14-2 26 6 28 20"/><circle cx="348" cy="276" r="9" class="fillPaper ink"/></g>',zzz:'<g class="ink prop-zzz"><text x="300" y="150" class="zzz z1">z</text><text x="322" y="128" class="zzz z2">z</text><text x="344" y="110" class="zzz z3">z</text></g>',thoughtDots:'<g class="prop-think"><circle cx="300" cy="170" r="4" class="fillInk d1"/><circle cx="316" cy="150" r="5.5" class="fillInk d2"/><circle cx="336" cy="126" r="7" class="fillInk d3"/></g>',magnifier:'<g class="prop-magnifier"><circle cx="332" cy="250" r="18" class="fillGlass ink"/><path class="inkBold" d="M345 263l16 16"/><path class="inkThin" d="M325 244a10 10 0 0 1 8 4"/></g>',check:'<g class="prop-check"><circle cx="332" cy="246" r="17" class="fillSeal"/><path class="checkMark" d="M324 246l6 6 11 -13"/></g>',confetti:'<g class="prop-confetti"><rect x="110" y="120" width="7" height="7" class="fillInk c1" transform="rotate(20 113 123)"/><rect x="300" y="110" width="7" height="7" class="fillGlow c2" transform="rotate(-15 303 113)"/><rect x="140" y="96" width="6" height="6" class="fillSeal c3"/><circle cx="330" cy="150" r="4" class="fillInk c4"/><circle cx="96" cy="170" r="4" class="fillGlow c5"/><rect x="270" y="140" width="6" height="6" class="fillInk c6" transform="rotate(40 273 143)"/><path class="inkViolet c7" d="M210 92l0 12M204 98l12 0"/></g>',parcel:'<g class="prop-parcel"><rect x="316" y="244" width="40" height="34" rx="3" class="fillPaper ink"/><path class="ink" d="M316 256h40"/><path class="inkViolet" d="M336 244v34"/></g>',spinner:'<g class="prop-spinner"><path class="inkBold spin" d="M332 230a20 20 0 1 1 -14 6"/></g>'},a={idle:{eyes:"open",mouth:"smile",motion:"breathe",label:"Loki, resting",blink:!0},happy:{eyes:"happy",mouth:"smile",motion:"bob",label:"Loki, happy"},thinking:{eyes:"lookUp",brow:"raised",mouth:"flat",prop:"thoughtDots",motion:"wiggle",label:"Loki, thinking"},building:{eyes:"focused",brow:"furrow",mouth:"flat",motion:"work",label:"Loki, building"},reviewing:{eyes:"focused",brow:"furrow",mouth:"soft",prop:"magnifier",motion:"inspect",label:"Loki, reviewing the work"},verifying:{eyes:"open",mouth:"soft",prop:"check",motion:"bob",label:"Loki, verifying",blink:!0},celebrating:{eyes:"wide",mouth:"openSmile",prop:"confetti",motion:"bounce",label:"Loki, celebrating a verified result"},proud:{eyes:"happy",mouth:"proud",prop:"check",motion:"bob",label:"Loki, proud"},waving:{eyes:"wink",mouth:"smile",prop:"wave",motion:"wave",label:"Loki, waving hello"},sleeping:{eyes:"closed",mouth:"soft",prop:"zzz",motion:"sleep",label:"Loki, sleeping"},concerned:{eyes:"worried",brow:"worried",mouth:"frown",motion:"shake",label:"Loki, something went wrong"},shipping:{eyes:"happy",mouth:"smile",prop:"parcel",motion:"launch",label:"Loki, shipping"},loading:{eyes:"open",mouth:"flat",prop:"spinner",motion:"breathe",label:"Loki, loading",blink:!0},curious:{eyes:"lookUp",brow:"raised",mouth:"o",prop:"thoughtDots",motion:"tilt",label:"Loki, curious"},blinking:{eyes:"open",mouth:"smile",motion:"breathe",label:"Loki",blink:!0},walking:{eyes:"open",mouth:"soft",motion:"walk",label:"Loki, walking",blink:!0},running:{eyes:"focused",mouth:"soft",motion:"run",label:"Loki, running"}},s="idle";function r(){return'<g class="legs"><path class="ink leg legL" d="M168 318v18"/><path class="ink foot footL" d="M158 336h20"/><path class="ink leg legR" d="M252 318v18"/><path class="ink foot footR" d="M242 336h20"/></g>'}function o(h,g,u){return g&&Object.prototype.hasOwnProperty.call(h,g)?h[g]:u||""}function n(h){var g=h.blink?" blink":"";return'<svg class="figure" viewBox="0 0 420 380" aria-hidden="true" focusable="false"><ellipse cx="210" cy="338" rx="120" ry="16" class="fillInkWash"/><g class="creature">'+r()+'<path class="fillPaper ink" d="M120 132c0-22 16-36 40-37 38-2 82-2 120 0 24 1 40 15 40 38v118c0 24-16 39-41 40-40 2-78 2-118 0-25-1-41-16-41-40z"/><path class="inkThin" d="M124 168c54-4 118-4 172 0"/><circle cx="146" cy="150" r="4.5" class="inkViolet"/><circle cx="164" cy="150" r="4.5" class="inkThinDot"/><circle cx="182" cy="150" r="4.5" class="inkThinDot"/><circle cx="170" cy="232" r="9" class="fillGlow"/><circle cx="252" cy="232" r="9" class="fillGlow"/>'+o(e,h.brow,"")+'<g class="eyes'+g+'">'+o(d,h.eyes,d.open)+"</g>"+o(t,h.mouth,t.smile)+'<path class="inkViolet" d="M150 280h120"/><path class="inkThin" d="M150 296h84"/>'+o(i,h.prop,"")+"</g></svg>"}var l=[":host{display:inline-block;line-height:0;","--lm-ink:var(--color-ink,#553de9);","--lm-ink-wash:var(--color-ink-wash,rgba(85,61,233,0.08));","--lm-text:var(--color-text,#201515);","--lm-paper:var(--color-paper-card,#fffdf8);","--lm-glow:var(--color-glow,#e8a33d);","--lm-glow-wash:var(--color-glow-wash,rgba(232,163,61,0.14));","--lm-seal:var(--color-seal,#1f8a52);","}",".figure{display:block;width:100%;height:auto;overflow:visible}",".ink{fill:none;stroke:var(--lm-text);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}",".inkBold{fill:none;stroke:var(--lm-text);stroke-width:3.4;stroke-linecap:round;stroke-linejoin:round}",".inkThin{fill:none;stroke:var(--lm-text);stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}",".inkThinDot{fill:none;stroke:var(--lm-text);stroke-width:1.6}",".inkViolet{fill:none;stroke:var(--lm-ink);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}",".fillPaper{fill:var(--lm-paper)}",".fillInk{fill:var(--lm-ink)}",".fillInkWash{fill:var(--lm-ink-wash)}",".fillGlow{fill:var(--lm-glow)}",".fillSeal{fill:var(--lm-seal)}",".fillGlass{fill:rgba(85,61,233,0.06)}",".fillHi{fill:var(--lm-paper)}",".prop-wave .fillPaper{fill:var(--lm-paper)}",".checkMark{fill:none;stroke:#fff;stroke-width:3.2;stroke-linecap:round;stroke-linejoin:round}",".zzz{font:600 26px var(--font-sans,system-ui,sans-serif);fill:var(--lm-ink)}",".m-breathe .creature{transform-box:fill-box;transform-origin:center;animation:lm-breathe 4.5s ease-in-out infinite}","@keyframes lm-breathe{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-2px) scale(1.012)}}",".m-bob .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-bob 2.2s ease-in-out infinite}","@keyframes lm-bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-7px)}}",".m-bounce .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-bounce 0.9s cubic-bezier(.3,.7,.4,1) infinite}","@keyframes lm-bounce{0%,100%{transform:translateY(0) scaleY(1)}30%{transform:translateY(-22px) scaleY(1.05)}55%{transform:translateY(0) scaleY(.94)}70%{transform:translateY(-6px)}}",".m-wiggle .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-wiggle 3s ease-in-out infinite}","@keyframes lm-wiggle{0%,100%{transform:rotate(-1.5deg)}50%{transform:rotate(1.5deg)}}",".m-tilt .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-tilt 3.4s ease-in-out infinite}","@keyframes lm-tilt{0%,100%{transform:rotate(-4deg)}50%{transform:rotate(4deg)}}",".m-work .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-work 0.7s ease-in-out infinite}","@keyframes lm-work{0%,100%{transform:translateX(0) rotate(0)}25%{transform:translateX(-1.5px) rotate(-1deg)}75%{transform:translateX(1.5px) rotate(1deg)}}",".m-inspect .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-inspect 3.2s ease-in-out infinite}","@keyframes lm-inspect{0%,100%{transform:translate(0,0)}50%{transform:translate(6px,-2px)}}",".m-inspect .prop-magnifier{transform-box:fill-box;transform-origin:332px 250px;animation:lm-inspect-mag 3.2s ease-in-out infinite}","@keyframes lm-inspect-mag{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(4px,4px) scale(1.08)}}",".m-shake .creature{transform-box:fill-box;transform-origin:center;animation:lm-shake 0.5s ease-in-out infinite}","@keyframes lm-shake{0%,100%{transform:translateX(0)}25%{transform:translateX(-4px)}75%{transform:translateX(4px)}}",".m-launch .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-launch 1.6s ease-in-out infinite}","@keyframes lm-launch{0%{transform:translateY(0)}40%{transform:translateY(-3px)}70%{transform:translateY(-14px) rotate(-2deg)}100%{transform:translateY(0)}}",".m-wave .creature{transform-box:fill-box;transform-origin:center;animation:lm-breathe 4.5s ease-in-out infinite}",".m-sleep .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-sleep 5.5s ease-in-out infinite}","@keyframes lm-sleep{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-1px) scale(1.02)}}",".prop-wave{transform-box:fill-box;transform-origin:50% 100%;animation:lm-sway 1.1s ease-in-out infinite}","@keyframes lm-sway{0%,100%{transform:rotate(-8deg)}50%{transform:rotate(14deg)}}",".prop-think .d1{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite}",".prop-think .d2{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite .3s}",".prop-think .d3{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite .6s}","@keyframes lm-rise{0%{opacity:.2;transform:translateY(4px) scale(.7)}50%{opacity:1;transform:translateY(0) scale(1)}100%{opacity:.2;transform:translateY(-4px) scale(.7)}}",".zzz{opacity:0;transform-box:fill-box;transform-origin:center}",".prop-zzz .z1{animation:lm-zfloat 3s ease-in-out infinite}",".prop-zzz .z2{animation:lm-zfloat 3s ease-in-out infinite 1s}",".prop-zzz .z3{animation:lm-zfloat 3s ease-in-out infinite 2s}","@keyframes lm-zfloat{0%{opacity:0;transform:translateY(6px) scale(.7)}40%{opacity:1}100%{opacity:0;transform:translateY(-16px) scale(1.1)}}",".spin{transform-box:fill-box;transform-origin:332px 250px;animation:lm-spin 1s linear infinite}","@keyframes lm-spin{to{transform:rotate(360deg)}}",".prop-confetti>*{transform-box:fill-box;transform-origin:center;animation:lm-confetti 1.4s ease-in infinite}",".prop-confetti .c2{animation-delay:.15s}.prop-confetti .c3{animation-delay:.3s}",".prop-confetti .c4{animation-delay:.45s}.prop-confetti .c5{animation-delay:.2s}",".prop-confetti .c6{animation-delay:.5s}.prop-confetti .c7{animation-delay:.1s}","@keyframes lm-confetti{0%{opacity:0;transform:translateY(0) rotate(0)}20%{opacity:1}100%{opacity:0;transform:translateY(34px) rotate(180deg)}}",".prop-check{transform-box:fill-box;transform-origin:332px 246px;animation:lm-pop 2.4s ease-in-out infinite}","@keyframes lm-pop{0%,70%,100%{transform:scale(1)}80%{transform:scale(1.18)}}",".m-launch .prop-parcel{transform-box:fill-box;transform-origin:center;animation:lm-bob 1.6s ease-in-out infinite}",".m-walk .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-walkbody 0.8s ease-in-out infinite}","@keyframes lm-walkbody{0%,100%{transform:translateY(0) rotate(-1deg)}50%{transform:translateY(-4px) rotate(1deg)}}",".m-walk .legL{transform-box:fill-box;transform-origin:168px 318px;animation:lm-legswing 0.8s ease-in-out infinite}",".m-walk .footL{transform-box:fill-box;transform-origin:168px 336px;animation:lm-legswing 0.8s ease-in-out infinite}",".m-walk .legR{transform-box:fill-box;transform-origin:252px 318px;animation:lm-legswing 0.8s ease-in-out infinite .4s}",".m-walk .footR{transform-box:fill-box;transform-origin:252px 336px;animation:lm-legswing 0.8s ease-in-out infinite .4s}","@keyframes lm-legswing{0%,100%{transform:rotate(-16deg)}50%{transform:rotate(16deg)}}",".m-run .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-runbody 0.42s ease-in-out infinite}","@keyframes lm-runbody{0%,100%{transform:translateY(0) rotate(-4deg)}50%{transform:translateY(-7px) rotate(2deg)}}",".m-run .legL{transform-box:fill-box;transform-origin:168px 318px;animation:lm-runleg 0.42s ease-in-out infinite}",".m-run .footL{transform-box:fill-box;transform-origin:168px 336px;animation:lm-runleg 0.42s ease-in-out infinite}",".m-run .legR{transform-box:fill-box;transform-origin:252px 318px;animation:lm-runleg 0.42s ease-in-out infinite .21s}",".m-run .footR{transform-box:fill-box;transform-origin:252px 336px;animation:lm-runleg 0.42s ease-in-out infinite .21s}","@keyframes lm-runleg{0%,100%{transform:rotate(-30deg)}50%{transform:rotate(30deg)}}",".eyes.blink{transform-box:fill-box;transform-origin:center;animation:lm-blink 6s steps(1,end) infinite}","@keyframes lm-blink{0%,92%,100%{transform:scaleY(1)}95%{transform:scaleY(.1)}}","@media (prefers-reduced-motion: reduce){",".figure *{animation:none !important}",".eyes.blink{transform:scaleY(1) !important}",".zzz{opacity:1}",".prop-confetti>*{opacity:1}",".prop-think .d1,.prop-think .d2,.prop-think .d3{opacity:1}","}"].join("");function c(h){var g=parseFloat(h);return!isFinite(g)||g<=0?132:g<16?16:g>1024?1024:g}var p=function(){function h(){return class extends HTMLElement{static get observedAttributes(){return["emotion","size","motion"]}constructor(){super(),this.attachShadow({mode:"open"}),this._styleEl=document.createElement("style"),this._styleEl.textContent=l,this._wrap=document.createElement("div"),this._wrap.className="lm-root",this.shadowRoot.appendChild(this._styleEl),this.shadowRoot.appendChild(this._wrap)}connectedCallback(){this._render()}attributeChangedCallback(){this.shadowRoot&&this._render()}_render(){var u=(this.getAttribute("emotion")||s).toLowerCase(),x=a[u]||a[s],k=(this.getAttribute("motion")||x.motion||"breathe").toLowerCase(),_=c(this.getAttribute("size")||"132");this.style.width=_+"px",this.setAttribute("role","img"),this.setAttribute("aria-label",x.label||"Loki"),this._wrap.className="lm-root m-"+k,this._wrap.innerHTML=n(x)}}}return customElements.get("loki-mascot")||customElements.define("loki-mascot",h()),customElements.get("loki-mascot")}();try{p.emotions=Object.keys(a),p.getEmotion=function(h){var g=(h||s).toLowerCase(),u=a[g]||a[s];return Object.assign({name:g},u)},p.renderStandaloneSVG=function(h){var g=p.getEmotion(h),u=g.motion||"breathe",x=l.replace(":host{","svg.loki-figure{"),k=n(g).replace('<svg class="figure"','<svg xmlns="http://www.w3.org/2000/svg" class="figure loki-figure m-'+u+'" role="img" aria-label="'+(g.label||"Loki")+'"').replace('aria-hidden="true" focusable="false"','focusable="false"');return k.replace("</svg>","<style>"+x+"</style></svg>")}}catch{}})();function ii(d){switch((d||"").toLowerCase()){case"running":case"autonomous":return"building";case"paused":return"sleeping";default:return"idle"}}var Re=class extends HTMLElement{static get observedAttributes(){return["api-url","size"]}constructor(){super(),this.attachShadow({mode:"open"}),this._status="idle",this._api=null,this._statusHandler=null,this._discHandler=null,this._poll=null}connectedCallback(){this._setupApi(),this._loadStatus(),this._startPolling(),this.render()}disconnectedCallback(){this._poll&&(this._poll.stop(),this._poll=null),this._api&&(this._statusHandler&&this._api.removeEventListener(f.STATUS_UPDATE,this._statusHandler),this._discHandler&&this._api.removeEventListener(f.DISCONNECTED,this._discHandler))}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadStatus()),e==="size"&&this.render())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=v({baseUrl:e}),this._statusHandler=t=>this._updateFromStatus(t.detail),this._discHandler=()=>{this._status="offline",this.render()},this._api.addEventListener(f.STATUS_UPDATE,this._statusHandler),this._api.addEventListener(f.DISCONNECTED,this._discHandler)}_startPolling(){this._poll=b({loadFn:()=>this._loadStatus(),intervalMs:1e4,sectionId:null,immediate:!1})}async _loadStatus(){try{let e=await this._api.getStatus();this._updateFromStatus(e)}catch{this._status="offline",this.render()}}_updateFromStatus(e){if(!e)return;let t=e.status||"idle";t!==this._status&&(this._status=t,this.render())}render(){if(!this.shadowRoot)return;let e=this.getAttribute("size")||"34",t=ii(this._status);this.shadowRoot.innerHTML=`
15244
+ `;let e=this.shadowRoot.getElementById("spec-retry-btn");e&&e.addEventListener("click",()=>this._load());let t=this.shadowRoot.getElementById("hist-toggle");t&&t.addEventListener("click",()=>{this._historyOpen=!this._historyOpen,this.render()})}};customElements.get("loki-spec-panel")||customElements.define("loki-spec-panel",He);(function(){"use strict";if(typeof window>"u"||typeof customElements>"u")return;var d={open:'<circle cx="178" cy="214" r="7" class="fillInk"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="180.5" cy="211.5" r="2" class="fillHi"/><circle cx="246.5" cy="211.5" r="2" class="fillHi"/>',happy:'<path class="ink" d="M171 216c4-6 10-6 14 0"/><path class="ink" d="M237 216c4-6 10-6 14 0"/>',lookUp:'<circle cx="178" cy="214" r="7" class="fillInk"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="180" cy="210" r="2.4" class="fillHi"/><circle cx="246" cy="210" r="2.4" class="fillHi"/>',wide:'<circle cx="178" cy="213" r="8.5" class="fillInk"/><circle cx="244" cy="213" r="8.5" class="fillInk"/><circle cx="181" cy="210" r="2.6" class="fillHi"/><circle cx="247" cy="210" r="2.6" class="fillHi"/>',focused:'<path class="inkBold" d="M170 214h16"/><path class="inkBold" d="M236 214h16"/>',closed:'<path class="ink" d="M170 214c4 5 10 5 14 0"/><path class="ink" d="M236 214c4 5 10 5 14 0"/>',worried:'<circle cx="178" cy="216" r="6" class="fillInk"/><circle cx="244" cy="216" r="6" class="fillInk"/><circle cx="180" cy="213.5" r="1.8" class="fillHi"/><circle cx="246" cy="213.5" r="1.8" class="fillHi"/>',wink:'<path class="ink" d="M171 214c4-5 10-5 14 0"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="246.5" cy="211.5" r="2" class="fillHi"/>'},e={none:"",raised:'<path class="inkThin" d="M168 198c5-3 12-3 17 0"/><path class="inkThin" d="M237 198c5-3 12-3 17 0"/>',furrow:'<path class="inkThin" d="M168 199l16 3"/><path class="inkThin" d="M254 199l-16 3"/>',worried:'<path class="inkThin" d="M168 201l16-4"/><path class="inkThin" d="M254 201l-16-4"/>'},t={smile:'<path class="ink" d="M192 244c12 12 26 12 38 0"/>',openSmile:'<path class="fillInk" d="M194 243c8 16 26 16 34 0c-10 6-24 6-34 0z"/>',flat:'<path class="ink" d="M198 248h26"/>',o:'<ellipse cx="211" cy="248" rx="6" ry="7" class="ink"/>',frown:'<path class="ink" d="M192 250c12-12 26-12 38 0"/>',soft:'<path class="ink" d="M196 246c9 7 19 7 28 0"/>',proud:'<path class="ink" d="M194 245c10 9 24 9 32 -2"/>'},i={none:"",wave:'<g class="prop-wave"><path class="ink" d="M318 250c14-2 26 6 28 20"/><circle cx="348" cy="276" r="9" class="fillPaper ink"/></g>',zzz:'<g class="ink prop-zzz"><text x="300" y="150" class="zzz z1">z</text><text x="322" y="128" class="zzz z2">z</text><text x="344" y="110" class="zzz z3">z</text></g>',thoughtDots:'<g class="prop-think"><circle cx="300" cy="170" r="4" class="fillInk d1"/><circle cx="316" cy="150" r="5.5" class="fillInk d2"/><circle cx="336" cy="126" r="7" class="fillInk d3"/></g>',magnifier:'<g class="prop-magnifier"><circle cx="332" cy="250" r="18" class="fillGlass ink"/><path class="inkBold" d="M345 263l16 16"/><path class="inkThin" d="M325 244a10 10 0 0 1 8 4"/></g>',check:'<g class="prop-check"><circle cx="332" cy="246" r="17" class="fillSeal"/><path class="checkMark" d="M324 246l6 6 11 -13"/></g>',confetti:'<g class="prop-confetti"><rect x="110" y="120" width="7" height="7" class="fillInk c1" transform="rotate(20 113 123)"/><rect x="300" y="110" width="7" height="7" class="fillGlow c2" transform="rotate(-15 303 113)"/><rect x="140" y="96" width="6" height="6" class="fillSeal c3"/><circle cx="330" cy="150" r="4" class="fillInk c4"/><circle cx="96" cy="170" r="4" class="fillGlow c5"/><rect x="270" y="140" width="6" height="6" class="fillInk c6" transform="rotate(40 273 143)"/><path class="inkViolet c7" d="M210 92l0 12M204 98l12 0"/></g>',parcel:'<g class="prop-parcel"><rect x="316" y="244" width="40" height="34" rx="3" class="fillPaper ink"/><path class="ink" d="M316 256h40"/><path class="inkViolet" d="M336 244v34"/></g>',spinner:'<g class="prop-spinner"><path class="inkBold spin" d="M332 230a20 20 0 1 1 -14 6"/></g>'},a={idle:{eyes:"open",mouth:"smile",motion:"breathe",label:"Loki, resting",blink:!0},happy:{eyes:"happy",mouth:"smile",motion:"bob",label:"Loki, happy"},thinking:{eyes:"lookUp",brow:"raised",mouth:"flat",prop:"thoughtDots",motion:"wiggle",label:"Loki, thinking"},building:{eyes:"focused",brow:"furrow",mouth:"flat",motion:"work",label:"Loki, building"},reviewing:{eyes:"focused",brow:"furrow",mouth:"soft",prop:"magnifier",motion:"inspect",label:"Loki, reviewing the work"},verifying:{eyes:"open",mouth:"soft",prop:"check",motion:"bob",label:"Loki, verifying",blink:!0},celebrating:{eyes:"wide",mouth:"openSmile",prop:"confetti",motion:"bounce",label:"Loki, celebrating a verified result"},proud:{eyes:"happy",mouth:"proud",prop:"check",motion:"bob",label:"Loki, proud"},waving:{eyes:"wink",mouth:"smile",prop:"wave",motion:"wave",label:"Loki, waving hello"},sleeping:{eyes:"closed",mouth:"soft",prop:"zzz",motion:"sleep",label:"Loki, sleeping"},concerned:{eyes:"worried",brow:"worried",mouth:"frown",motion:"shake",label:"Loki, something went wrong"},shipping:{eyes:"happy",mouth:"smile",prop:"parcel",motion:"launch",label:"Loki, shipping"},loading:{eyes:"open",mouth:"flat",prop:"spinner",motion:"breathe",label:"Loki, loading",blink:!0},curious:{eyes:"lookUp",brow:"raised",mouth:"o",prop:"thoughtDots",motion:"tilt",label:"Loki, curious"},blinking:{eyes:"open",mouth:"smile",motion:"breathe",label:"Loki",blink:!0},walking:{eyes:"open",mouth:"soft",motion:"walk",label:"Loki, walking",blink:!0},running:{eyes:"focused",mouth:"soft",motion:"run",label:"Loki, running"}},s="idle";function r(){return'<g class="legs"><path class="ink leg legL" d="M168 318v18"/><path class="ink foot footL" d="M158 336h20"/><path class="ink leg legR" d="M252 318v18"/><path class="ink foot footR" d="M242 336h20"/></g>'}function o(u,m,g){return m&&Object.prototype.hasOwnProperty.call(u,m)?u[m]:g||""}function n(u){var m=u.blink?" blink":"";return'<svg class="figure" viewBox="0 0 420 380" aria-hidden="true" focusable="false"><ellipse cx="210" cy="338" rx="120" ry="16" class="fillInkWash"/><g class="creature">'+r()+'<path class="fillPaper ink" d="M120 132c0-22 16-36 40-37 38-2 82-2 120 0 24 1 40 15 40 38v118c0 24-16 39-41 40-40 2-78 2-118 0-25-1-41-16-41-40z"/><path class="inkThin" d="M124 168c54-4 118-4 172 0"/><circle cx="146" cy="150" r="4.5" class="inkViolet"/><circle cx="164" cy="150" r="4.5" class="inkThinDot"/><circle cx="182" cy="150" r="4.5" class="inkThinDot"/><circle cx="170" cy="232" r="9" class="fillGlow"/><circle cx="252" cy="232" r="9" class="fillGlow"/>'+o(e,u.brow,"")+'<g class="eyes'+m+'">'+o(d,u.eyes,d.open)+"</g>"+o(t,u.mouth,t.smile)+'<path class="inkViolet" d="M150 280h120"/><path class="inkThin" d="M150 296h84"/>'+o(i,u.prop,"")+"</g></svg>"}var l=[":host{display:inline-block;line-height:0;","--lm-ink:var(--color-ink,#553de9);","--lm-ink-wash:var(--color-ink-wash,rgba(85,61,233,0.08));","--lm-text:var(--color-text,#201515);","--lm-paper:var(--color-paper-card,#fffdf8);","--lm-glow:var(--color-glow,#e8a33d);","--lm-glow-wash:var(--color-glow-wash,rgba(232,163,61,0.14));","--lm-seal:var(--color-seal,#1f8a52);","}",".figure{display:block;width:100%;height:auto;overflow:visible}",".ink{fill:none;stroke:var(--lm-text);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}",".inkBold{fill:none;stroke:var(--lm-text);stroke-width:3.4;stroke-linecap:round;stroke-linejoin:round}",".inkThin{fill:none;stroke:var(--lm-text);stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}",".inkThinDot{fill:none;stroke:var(--lm-text);stroke-width:1.6}",".inkViolet{fill:none;stroke:var(--lm-ink);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}",".fillPaper{fill:var(--lm-paper)}",".fillInk{fill:var(--lm-ink)}",".fillInkWash{fill:var(--lm-ink-wash)}",".fillGlow{fill:var(--lm-glow)}",".fillSeal{fill:var(--lm-seal)}",".fillGlass{fill:rgba(85,61,233,0.06)}",".fillHi{fill:var(--lm-paper)}",".prop-wave .fillPaper{fill:var(--lm-paper)}",".checkMark{fill:none;stroke:#fff;stroke-width:3.2;stroke-linecap:round;stroke-linejoin:round}",".zzz{font:600 26px var(--font-sans,system-ui,sans-serif);fill:var(--lm-ink)}",".m-breathe .creature{transform-box:fill-box;transform-origin:center;animation:lm-breathe 4.5s ease-in-out infinite}","@keyframes lm-breathe{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-2px) scale(1.012)}}",".m-bob .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-bob 2.2s ease-in-out infinite}","@keyframes lm-bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-7px)}}",".m-bounce .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-bounce 0.9s cubic-bezier(.3,.7,.4,1) infinite}","@keyframes lm-bounce{0%,100%{transform:translateY(0) scaleY(1)}30%{transform:translateY(-22px) scaleY(1.05)}55%{transform:translateY(0) scaleY(.94)}70%{transform:translateY(-6px)}}",".m-wiggle .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-wiggle 3s ease-in-out infinite}","@keyframes lm-wiggle{0%,100%{transform:rotate(-1.5deg)}50%{transform:rotate(1.5deg)}}",".m-tilt .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-tilt 3.4s ease-in-out infinite}","@keyframes lm-tilt{0%,100%{transform:rotate(-4deg)}50%{transform:rotate(4deg)}}",".m-work .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-work 0.7s ease-in-out infinite}","@keyframes lm-work{0%,100%{transform:translateX(0) rotate(0)}25%{transform:translateX(-1.5px) rotate(-1deg)}75%{transform:translateX(1.5px) rotate(1deg)}}",".m-inspect .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-inspect 3.2s ease-in-out infinite}","@keyframes lm-inspect{0%,100%{transform:translate(0,0)}50%{transform:translate(6px,-2px)}}",".m-inspect .prop-magnifier{transform-box:fill-box;transform-origin:332px 250px;animation:lm-inspect-mag 3.2s ease-in-out infinite}","@keyframes lm-inspect-mag{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(4px,4px) scale(1.08)}}",".m-shake .creature{transform-box:fill-box;transform-origin:center;animation:lm-shake 0.5s ease-in-out infinite}","@keyframes lm-shake{0%,100%{transform:translateX(0)}25%{transform:translateX(-4px)}75%{transform:translateX(4px)}}",".m-launch .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-launch 1.6s ease-in-out infinite}","@keyframes lm-launch{0%{transform:translateY(0)}40%{transform:translateY(-3px)}70%{transform:translateY(-14px) rotate(-2deg)}100%{transform:translateY(0)}}",".m-wave .creature{transform-box:fill-box;transform-origin:center;animation:lm-breathe 4.5s ease-in-out infinite}",".m-sleep .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-sleep 5.5s ease-in-out infinite}","@keyframes lm-sleep{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-1px) scale(1.02)}}",".prop-wave{transform-box:fill-box;transform-origin:50% 100%;animation:lm-sway 1.1s ease-in-out infinite}","@keyframes lm-sway{0%,100%{transform:rotate(-8deg)}50%{transform:rotate(14deg)}}",".prop-think .d1{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite}",".prop-think .d2{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite .3s}",".prop-think .d3{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite .6s}","@keyframes lm-rise{0%{opacity:.2;transform:translateY(4px) scale(.7)}50%{opacity:1;transform:translateY(0) scale(1)}100%{opacity:.2;transform:translateY(-4px) scale(.7)}}",".zzz{opacity:0;transform-box:fill-box;transform-origin:center}",".prop-zzz .z1{animation:lm-zfloat 3s ease-in-out infinite}",".prop-zzz .z2{animation:lm-zfloat 3s ease-in-out infinite 1s}",".prop-zzz .z3{animation:lm-zfloat 3s ease-in-out infinite 2s}","@keyframes lm-zfloat{0%{opacity:0;transform:translateY(6px) scale(.7)}40%{opacity:1}100%{opacity:0;transform:translateY(-16px) scale(1.1)}}",".spin{transform-box:fill-box;transform-origin:332px 250px;animation:lm-spin 1s linear infinite}","@keyframes lm-spin{to{transform:rotate(360deg)}}",".prop-confetti>*{transform-box:fill-box;transform-origin:center;animation:lm-confetti 1.4s ease-in infinite}",".prop-confetti .c2{animation-delay:.15s}.prop-confetti .c3{animation-delay:.3s}",".prop-confetti .c4{animation-delay:.45s}.prop-confetti .c5{animation-delay:.2s}",".prop-confetti .c6{animation-delay:.5s}.prop-confetti .c7{animation-delay:.1s}","@keyframes lm-confetti{0%{opacity:0;transform:translateY(0) rotate(0)}20%{opacity:1}100%{opacity:0;transform:translateY(34px) rotate(180deg)}}",".prop-check{transform-box:fill-box;transform-origin:332px 246px;animation:lm-pop 2.4s ease-in-out infinite}","@keyframes lm-pop{0%,70%,100%{transform:scale(1)}80%{transform:scale(1.18)}}",".m-launch .prop-parcel{transform-box:fill-box;transform-origin:center;animation:lm-bob 1.6s ease-in-out infinite}",".m-walk .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-walkbody 0.8s ease-in-out infinite}","@keyframes lm-walkbody{0%,100%{transform:translateY(0) rotate(-1deg)}50%{transform:translateY(-4px) rotate(1deg)}}",".m-walk .legL{transform-box:fill-box;transform-origin:168px 318px;animation:lm-legswing 0.8s ease-in-out infinite}",".m-walk .footL{transform-box:fill-box;transform-origin:168px 336px;animation:lm-legswing 0.8s ease-in-out infinite}",".m-walk .legR{transform-box:fill-box;transform-origin:252px 318px;animation:lm-legswing 0.8s ease-in-out infinite .4s}",".m-walk .footR{transform-box:fill-box;transform-origin:252px 336px;animation:lm-legswing 0.8s ease-in-out infinite .4s}","@keyframes lm-legswing{0%,100%{transform:rotate(-16deg)}50%{transform:rotate(16deg)}}",".m-run .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-runbody 0.42s ease-in-out infinite}","@keyframes lm-runbody{0%,100%{transform:translateY(0) rotate(-4deg)}50%{transform:translateY(-7px) rotate(2deg)}}",".m-run .legL{transform-box:fill-box;transform-origin:168px 318px;animation:lm-runleg 0.42s ease-in-out infinite}",".m-run .footL{transform-box:fill-box;transform-origin:168px 336px;animation:lm-runleg 0.42s ease-in-out infinite}",".m-run .legR{transform-box:fill-box;transform-origin:252px 318px;animation:lm-runleg 0.42s ease-in-out infinite .21s}",".m-run .footR{transform-box:fill-box;transform-origin:252px 336px;animation:lm-runleg 0.42s ease-in-out infinite .21s}","@keyframes lm-runleg{0%,100%{transform:rotate(-30deg)}50%{transform:rotate(30deg)}}",".eyes.blink{transform-box:fill-box;transform-origin:center;animation:lm-blink 6s steps(1,end) infinite}","@keyframes lm-blink{0%,92%,100%{transform:scaleY(1)}95%{transform:scaleY(.1)}}","@media (prefers-reduced-motion: reduce){",".figure *{animation:none !important}",".eyes.blink{transform:scaleY(1) !important}",".zzz{opacity:1}",".prop-confetti>*{opacity:1}",".prop-think .d1,.prop-think .d2,.prop-think .d3{opacity:1}","}"].join("");function c(u){var m=parseFloat(u);return!isFinite(m)||m<=0?132:m<16?16:m>1024?1024:m}var p=function(){function u(){return class extends HTMLElement{static get observedAttributes(){return["emotion","size","motion"]}constructor(){super(),this.attachShadow({mode:"open"}),this._styleEl=document.createElement("style"),this._styleEl.textContent=l,this._wrap=document.createElement("div"),this._wrap.className="lm-root",this.shadowRoot.appendChild(this._styleEl),this.shadowRoot.appendChild(this._wrap)}connectedCallback(){this._render()}attributeChangedCallback(){this.shadowRoot&&this._render()}_render(){var g=(this.getAttribute("emotion")||s).toLowerCase(),x=a[g]||a[s],k=(this.getAttribute("motion")||x.motion||"breathe").toLowerCase(),_=c(this.getAttribute("size")||"132");this.style.width=_+"px",this.setAttribute("role","img"),this.setAttribute("aria-label",x.label||"Loki"),this._wrap.className="lm-root m-"+k,this._wrap.innerHTML=n(x)}}}return customElements.get("loki-mascot")||customElements.define("loki-mascot",u()),customElements.get("loki-mascot")}();try{p.emotions=Object.keys(a),p.getEmotion=function(u){var m=(u||s).toLowerCase(),g=a[m]||a[s];return Object.assign({name:m},g)},p.renderStandaloneSVG=function(u){var m=p.getEmotion(u),g=m.motion||"breathe",x=l.replace(":host{","svg.loki-figure{"),k=n(m).replace('<svg class="figure"','<svg xmlns="http://www.w3.org/2000/svg" class="figure loki-figure m-'+g+'" role="img" aria-label="'+(m.label||"Loki")+'"').replace('aria-hidden="true" focusable="false"','focusable="false"');return k.replace("</svg>","<style>"+x+"</style></svg>")}}catch{}})();function ii(d){switch((d||"").toLowerCase()){case"running":case"autonomous":return"building";case"paused":return"sleeping";default:return"idle"}}var Me=class extends HTMLElement{static get observedAttributes(){return["api-url","size"]}constructor(){super(),this.attachShadow({mode:"open"}),this._status="idle",this._api=null,this._statusHandler=null,this._discHandler=null,this._poll=null}connectedCallback(){this._setupApi(),this._loadStatus(),this._startPolling(),this.render()}disconnectedCallback(){this._poll&&(this._poll.stop(),this._poll=null),this._teardownApiListeners()}_teardownApiListeners(){this._api&&(this._statusHandler&&this._api.removeEventListener(f.STATUS_UPDATE,this._statusHandler),this._discHandler&&this._api.removeEventListener(f.DISCONNECTED,this._discHandler))}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._teardownApiListeners(),this._setupApi(),this._loadStatus()),e==="size"&&this.render())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e}),this._statusHandler=t=>this._updateFromStatus(t.detail),this._discHandler=()=>{this._status="offline",this.render()},this._api.addEventListener(f.STATUS_UPDATE,this._statusHandler),this._api.addEventListener(f.DISCONNECTED,this._discHandler)}_startPolling(){this._poll=b({loadFn:()=>this._loadStatus(),intervalMs:1e4,sectionId:null,immediate:!1})}async _loadStatus(){let e=this._api;try{let t=await e.getStatus();if(e!==this._api)return;this._updateFromStatus(t)}catch{if(e!==this._api)return;this._status="offline",this.render()}}_updateFromStatus(e){if(!e)return;let t=e.status||"idle";t!==this._status&&(this._status=t,this.render())}render(){if(!this.shadowRoot)return;let e=this.getAttribute("size")||"34",t=ii(this._status);this.shadowRoot.innerHTML=`
15245
15245
  <style>
15246
15246
  :host { display: inline-flex; align-items: center; line-height: 0; }
15247
15247
  loki-mascot { display: inline-block; }
15248
15248
  </style>
15249
15249
  <loki-mascot emotion="${t}" size="${e}"></loki-mascot>
15250
- `}};customElements.get("loki-mascot-presence")||customElements.define("loki-mascot-presence",Re);var ai="1.4.0";function si(d={}){return d.theme?w.setTheme(d.theme):d.autoDetectContext!==!1?w.init():j.init(),d.apiUrl&&v({baseUrl:d.apiUrl}),{theme:w.getTheme(),context:w.detectContext()}}return St(ri);})();
15250
+ `}};customElements.get("loki-mascot-presence")||customElements.define("loki-mascot-presence",Me);var ai="1.4.0";function si(d={}){return d.theme?w.setTheme(d.theme):d.autoDetectContext!==!1?w.init():j.init(),d.apiUrl&&h({baseUrl:d.apiUrl}),{theme:w.getTheme(),context:w.detectContext()}}return St(ri);})();
15251
15251
 
15252
15252
 
15253
15253
  // Initialize dashboard when DOM is ready
@@ -15415,6 +15415,12 @@ document.addEventListener('DOMContentLoaded', function() {
15415
15415
  var detectedUrl = window.location.origin;
15416
15416
  apiUrlInput.value = detectedUrl;
15417
15417
 
15418
+ // Broadcasting api-url via setAttribute is the correct, race-free path: each
15419
+ // component's attributeChangedCallback('api-url') now ADOPTS a fresh per-URL
15420
+ // API client (this._api = getApiClient({ baseUrl })) and reloads, instead of
15421
+ // mutating baseUrl on the cached singleton. Detach/reset of any prior-project
15422
+ // listeners + in-flight responses is handled inside the components, so a plain
15423
+ // setAttribute here cannot leak one project's data into another.
15418
15424
  function updateComponentsApiUrl(apiUrl) {
15419
15425
  var components = [
15420
15426
  'overview',