loki-mode 5.42.2 → 5.46.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.
@@ -495,6 +495,14 @@
495
495
  <svg viewBox="0 0 24 24"><path d="M12 20V10"/><path d="M18 20V4"/><path d="M6 20v-4"/></svg>
496
496
  Learning
497
497
  </button>
498
+ <button class="nav-link" data-section="prd-checklist" id="nav-prd-checklist">
499
+ <svg viewBox="0 0 24 24"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 01-2 2H5a2 2 0 01-2-2V5a2 2 0 012-2h11"/></svg>
500
+ PRD Checklist
501
+ </button>
502
+ <button class="nav-link" data-section="app-runner" id="nav-app-runner">
503
+ <svg viewBox="0 0 24 24"><polygon points="5 3 19 12 5 21 5 3"/></svg>
504
+ App Runner
505
+ </button>
498
506
  <button class="nav-link" data-section="council" id="nav-council">
499
507
  <svg viewBox="0 0 24 24"><path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 00-3-3.87"/><path d="M16 3.13a4 4 0 010 7.75"/></svg>
500
508
  Council
@@ -571,6 +579,22 @@
571
579
  <loki-learning-dashboard id="learning-dashboard" time-range="7d"></loki-learning-dashboard>
572
580
  </div>
573
581
 
582
+ <!-- PRD Checklist -->
583
+ <div class="section-page" id="page-prd-checklist">
584
+ <div class="section-page-header">
585
+ <h2 class="section-page-title">PRD Checklist</h2>
586
+ </div>
587
+ <loki-checklist-viewer id="checklist-viewer"></loki-checklist-viewer>
588
+ </div>
589
+
590
+ <!-- App Runner -->
591
+ <div class="section-page" id="page-app-runner">
592
+ <div class="section-page-header">
593
+ <h2 class="section-page-title">App Runner</h2>
594
+ </div>
595
+ <loki-app-status id="app-status"></loki-app-status>
596
+ </div>
597
+
574
598
  <!-- Completion Council -->
575
599
  <div class="section-page" id="page-council">
576
600
  <div class="section-page-header">
@@ -627,11 +651,10 @@
627
651
  <div class="shortcut-row"><span class="shortcut-desc">Logs</span><span class="shortcut-keys"><kbd class="shortcut-key">3</kbd></span></div>
628
652
  <div class="shortcut-row"><span class="shortcut-desc">Memory</span><span class="shortcut-keys"><kbd class="shortcut-key">4</kbd></span></div>
629
653
  <div class="shortcut-row"><span class="shortcut-desc">Learning</span><span class="shortcut-keys"><kbd class="shortcut-key">5</kbd></span></div>
630
- <div class="shortcut-row"><span class="shortcut-desc">Council</span><span class="shortcut-keys"><kbd class="shortcut-key">6</kbd></span></div>
631
- <div class="shortcut-row"><span class="shortcut-desc">Cost</span><span class="shortcut-keys"><kbd class="shortcut-key">7</kbd></span></div>
632
- <div class="shortcut-row"><span class="shortcut-desc">Checkpoints</span><span class="shortcut-keys"><kbd class="shortcut-key">8</kbd></span></div>
633
- <div class="shortcut-row"><span class="shortcut-desc">Context</span><span class="shortcut-keys"><kbd class="shortcut-key">9</kbd></span></div>
634
- <div class="shortcut-row"><span class="shortcut-desc">Notifications</span><span class="shortcut-keys"><kbd class="shortcut-key">0</kbd></span></div>
654
+ <div class="shortcut-row"><span class="shortcut-desc">App Runner</span><span class="shortcut-keys"><kbd class="shortcut-key">7</kbd></span></div>
655
+ <div class="shortcut-row"><span class="shortcut-desc">Council</span><span class="shortcut-keys"><kbd class="shortcut-key">8</kbd></span></div>
656
+ <div class="shortcut-row"><span class="shortcut-desc">Cost</span><span class="shortcut-keys"><kbd class="shortcut-key">9</kbd></span></div>
657
+ <div class="shortcut-row"><span class="shortcut-desc">Checkpoints</span><span class="shortcut-keys"><kbd class="shortcut-key">0</kbd></span></div>
635
658
  </div>
636
659
  <div class="shortcuts-group">
637
660
  <div class="shortcuts-group-title">Session</div>
@@ -651,16 +674,16 @@
651
674
 
652
675
  <!-- Inlined JavaScript Bundle -->
653
676
  <script>
654
- var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnPropertyDescriptor;var ue=Object.getOwnPropertyNames;var ge=Object.prototype.hasOwnProperty;var he=(d,e,t)=>e in d?K(d,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):d[e]=t;var ve=(d,e)=>{for(var t in e)K(d,t,{get:e[t],enumerable:!0})},me=(d,e,t,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of ue(e))!ge.call(d,i)&&i!==t&&K(d,i,{get:()=>e[i],enumerable:!(a=pe(e,i))||a.enumerable});return d};var be=d=>me(K({},"__esModule",{value:!0}),d);var k=(d,e,t)=>he(d,typeof e!="symbol"?e+"":e,t);var Se={};ve(Se,{ANIMATION:()=>w,ARIA_PATTERNS:()=>W,ApiEvents:()=>n,BASE_STYLES:()=>M,BREAKPOINTS:()=>V,COMMON_STYLES:()=>te,KEYBOARD_SHORTCUTS:()=>Y,KeyboardHandler:()=>L,LokiApiClient:()=>I,LokiCheckpointViewer:()=>q,LokiContextTracker:()=>G,LokiCostDashboard:()=>N,LokiCouncilDashboard:()=>O,LokiElement:()=>c,LokiLearningDashboard:()=>F,LokiLogStream:()=>U,LokiMemoryBrowser:()=>j,LokiNotificationCenter:()=>J,LokiOverview:()=>z,LokiSessionControl:()=>B,LokiState:()=>R,LokiTaskBoard:()=>H,LokiTheme:()=>S,RADIUS:()=>y,SPACING:()=>x,STATE_CHANGE_EVENT:()=>Q,THEMES:()=>b,THEME_VARIABLES:()=>X,TYPOGRAPHY:()=>v,UnifiedThemeManager:()=>h,VERSION:()=>Te,Z_INDEX:()=>$,createApiClient:()=>se,createStore:()=>re,generateThemeCSS:()=>m,generateTokensCSS:()=>P,getApiClient:()=>u,getState:()=>C,init:()=>Ee});var b={light:{"--loki-bg-primary":"#fafafa","--loki-bg-secondary":"#f4f4f5","--loki-bg-tertiary":"#e4e4e7","--loki-bg-card":"#ffffff","--loki-bg-hover":"#f0f0f3","--loki-bg-active":"#e8e8ec","--loki-bg-overlay":"rgba(0, 0, 0, 0.5)","--loki-accent":"#7c3aed","--loki-accent-hover":"#6d28d9","--loki-accent-active":"#5b21b6","--loki-accent-light":"#8b5cf6","--loki-accent-muted":"rgba(124, 58, 237, 0.12)","--loki-text-primary":"#18181b","--loki-text-secondary":"#52525b","--loki-text-muted":"#a1a1aa","--loki-text-disabled":"#d4d4d8","--loki-text-inverse":"#ffffff","--loki-border":"#e4e4e7","--loki-border-light":"#d4d4d8","--loki-border-focus":"#7c3aed","--loki-success":"#16a34a","--loki-success-muted":"rgba(22, 163, 74, 0.12)","--loki-warning":"#ca8a04","--loki-warning-muted":"rgba(202, 138, 4, 0.12)","--loki-error":"#dc2626","--loki-error-muted":"rgba(220, 38, 38, 0.12)","--loki-info":"#2563eb","--loki-info-muted":"rgba(37, 99, 235, 0.12)","--loki-green":"#16a34a","--loki-green-muted":"rgba(22, 163, 74, 0.12)","--loki-yellow":"#ca8a04","--loki-yellow-muted":"rgba(202, 138, 4, 0.12)","--loki-red":"#dc2626","--loki-red-muted":"rgba(220, 38, 38, 0.12)","--loki-blue":"#2563eb","--loki-blue-muted":"rgba(37, 99, 235, 0.12)","--loki-purple":"#9333ea","--loki-purple-muted":"rgba(147, 51, 234, 0.12)","--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 4px 6px rgba(0, 0, 0, 0.07)","--loki-shadow-lg":"0 10px 15px rgba(0, 0, 0, 0.1)","--loki-shadow-focus":"0 0 0 3px rgba(124, 58, 237, 0.3)"},dark:{"--loki-bg-primary":"#09090b","--loki-bg-secondary":"#0c0c0f","--loki-bg-tertiary":"#111114","--loki-bg-card":"#18181b","--loki-bg-hover":"#1f1f23","--loki-bg-active":"#27272a","--loki-bg-overlay":"rgba(0, 0, 0, 0.8)","--loki-accent":"#8b5cf6","--loki-accent-hover":"#a78bfa","--loki-accent-active":"#7c3aed","--loki-accent-light":"#a78bfa","--loki-accent-muted":"rgba(139, 92, 246, 0.15)","--loki-text-primary":"#fafafa","--loki-text-secondary":"#a1a1aa","--loki-text-muted":"#52525b","--loki-text-disabled":"#3f3f46","--loki-text-inverse":"#09090b","--loki-border":"rgba(255, 255, 255, 0.06)","--loki-border-light":"rgba(255, 255, 255, 0.1)","--loki-border-focus":"#8b5cf6","--loki-success":"#22c55e","--loki-success-muted":"rgba(34, 197, 94, 0.15)","--loki-warning":"#eab308","--loki-warning-muted":"rgba(234, 179, 8, 0.15)","--loki-error":"#ef4444","--loki-error-muted":"rgba(239, 68, 68, 0.15)","--loki-info":"#3b82f6","--loki-info-muted":"rgba(59, 130, 246, 0.15)","--loki-green":"#22c55e","--loki-green-muted":"rgba(34, 197, 94, 0.15)","--loki-yellow":"#eab308","--loki-yellow-muted":"rgba(234, 179, 8, 0.15)","--loki-red":"#ef4444","--loki-red-muted":"rgba(239, 68, 68, 0.15)","--loki-blue":"#3b82f6","--loki-blue-muted":"rgba(59, 130, 246, 0.15)","--loki-purple":"#a78bfa","--loki-purple-muted":"rgba(167, 139, 250, 0.15)","--loki-opus":"#f59e0b","--loki-sonnet":"#818cf8","--loki-haiku":"#34d399","--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(139, 92, 246, 0.25)"},"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)"}},x={xs:"4px",sm:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"32px","3xl":"48px"},y={none:"0",sm:"4px",md:"6px",lg:"8px",xl:"10px",full:"9999px"},v={fontFamily:{sans:"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-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"}},w={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)"}},V={sm:"640px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},$={base:"0",dropdown:"100",sticky:"200",modal:"300",popover:"400",tooltip:"500",toast:"600"},Y={"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"]}},W={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 m(d){let e=b[d];return e?Object.entries(e).map(([t,a])=>`${t}: ${a};`).join(`
677
+ var LokiDashboard=(()=>{var Y=Object.defineProperty;var ht=Object.getOwnPropertyDescriptor;var vt=Object.getOwnPropertyNames;var mt=Object.prototype.hasOwnProperty;var bt=(d,t,e)=>t in d?Y(d,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):d[t]=e;var kt=(d,t)=>{for(var e in t)Y(d,e,{get:t[e],enumerable:!0})},ft=(d,t,e,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of vt(t))!mt.call(d,i)&&i!==e&&Y(d,i,{get:()=>t[i],enumerable:!(a=ht(t,i))||a.enumerable});return d};var _t=d=>ft(Y({},"__esModule",{value:!0}),d);var k=(d,t,e)=>bt(d,typeof t!="symbol"?t+"":t,e);var It={};kt(It,{ANIMATION:()=>w,ARIA_PATTERNS:()=>Z,ApiEvents:()=>n,BASE_STYLES:()=>R,BREAKPOINTS:()=>W,COMMON_STYLES:()=>it,KEYBOARD_SHORTCUTS:()=>X,KeyboardHandler:()=>L,LokiApiClient:()=>I,LokiAppStatus:()=>q,LokiChecklistViewer:()=>N,LokiCheckpointViewer:()=>J,LokiContextTracker:()=>K,LokiCostDashboard:()=>G,LokiCouncilDashboard:()=>O,LokiElement:()=>c,LokiLearningDashboard:()=>F,LokiLogStream:()=>U,LokiMemoryBrowser:()=>j,LokiNotificationCenter:()=>V,LokiOverview:()=>H,LokiSessionControl:()=>B,LokiState:()=>M,LokiTaskBoard:()=>z,LokiTheme:()=>S,RADIUS:()=>y,SPACING:()=>_,STATE_CHANGE_EVENT:()=>et,THEMES:()=>b,THEME_VARIABLES:()=>Q,TYPOGRAPHY:()=>v,UnifiedThemeManager:()=>h,VERSION:()=>At,Z_INDEX:()=>$,createApiClient:()=>ot,createStore:()=>nt,generateThemeCSS:()=>m,generateTokensCSS:()=>P,getApiClient:()=>p,getState:()=>C,init:()=>Lt});var b={light:{"--loki-bg-primary":"#fafafa","--loki-bg-secondary":"#f4f4f5","--loki-bg-tertiary":"#e4e4e7","--loki-bg-card":"#ffffff","--loki-bg-hover":"#f0f0f3","--loki-bg-active":"#e8e8ec","--loki-bg-overlay":"rgba(0, 0, 0, 0.5)","--loki-accent":"#7c3aed","--loki-accent-hover":"#6d28d9","--loki-accent-active":"#5b21b6","--loki-accent-light":"#8b5cf6","--loki-accent-muted":"rgba(124, 58, 237, 0.12)","--loki-text-primary":"#18181b","--loki-text-secondary":"#52525b","--loki-text-muted":"#a1a1aa","--loki-text-disabled":"#d4d4d8","--loki-text-inverse":"#ffffff","--loki-border":"#e4e4e7","--loki-border-light":"#d4d4d8","--loki-border-focus":"#7c3aed","--loki-success":"#16a34a","--loki-success-muted":"rgba(22, 163, 74, 0.12)","--loki-warning":"#ca8a04","--loki-warning-muted":"rgba(202, 138, 4, 0.12)","--loki-error":"#dc2626","--loki-error-muted":"rgba(220, 38, 38, 0.12)","--loki-info":"#2563eb","--loki-info-muted":"rgba(37, 99, 235, 0.12)","--loki-green":"#16a34a","--loki-green-muted":"rgba(22, 163, 74, 0.12)","--loki-yellow":"#ca8a04","--loki-yellow-muted":"rgba(202, 138, 4, 0.12)","--loki-red":"#dc2626","--loki-red-muted":"rgba(220, 38, 38, 0.12)","--loki-blue":"#2563eb","--loki-blue-muted":"rgba(37, 99, 235, 0.12)","--loki-purple":"#9333ea","--loki-purple-muted":"rgba(147, 51, 234, 0.12)","--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 4px 6px rgba(0, 0, 0, 0.07)","--loki-shadow-lg":"0 10px 15px rgba(0, 0, 0, 0.1)","--loki-shadow-focus":"0 0 0 3px rgba(124, 58, 237, 0.3)"},dark:{"--loki-bg-primary":"#09090b","--loki-bg-secondary":"#0c0c0f","--loki-bg-tertiary":"#111114","--loki-bg-card":"#18181b","--loki-bg-hover":"#1f1f23","--loki-bg-active":"#27272a","--loki-bg-overlay":"rgba(0, 0, 0, 0.8)","--loki-accent":"#8b5cf6","--loki-accent-hover":"#a78bfa","--loki-accent-active":"#7c3aed","--loki-accent-light":"#a78bfa","--loki-accent-muted":"rgba(139, 92, 246, 0.15)","--loki-text-primary":"#fafafa","--loki-text-secondary":"#a1a1aa","--loki-text-muted":"#52525b","--loki-text-disabled":"#3f3f46","--loki-text-inverse":"#09090b","--loki-border":"rgba(255, 255, 255, 0.06)","--loki-border-light":"rgba(255, 255, 255, 0.1)","--loki-border-focus":"#8b5cf6","--loki-success":"#22c55e","--loki-success-muted":"rgba(34, 197, 94, 0.15)","--loki-warning":"#eab308","--loki-warning-muted":"rgba(234, 179, 8, 0.15)","--loki-error":"#ef4444","--loki-error-muted":"rgba(239, 68, 68, 0.15)","--loki-info":"#3b82f6","--loki-info-muted":"rgba(59, 130, 246, 0.15)","--loki-green":"#22c55e","--loki-green-muted":"rgba(34, 197, 94, 0.15)","--loki-yellow":"#eab308","--loki-yellow-muted":"rgba(234, 179, 8, 0.15)","--loki-red":"#ef4444","--loki-red-muted":"rgba(239, 68, 68, 0.15)","--loki-blue":"#3b82f6","--loki-blue-muted":"rgba(59, 130, 246, 0.15)","--loki-purple":"#a78bfa","--loki-purple-muted":"rgba(167, 139, 250, 0.15)","--loki-opus":"#f59e0b","--loki-sonnet":"#818cf8","--loki-haiku":"#34d399","--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(139, 92, 246, 0.25)"},"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)"}},_={xs:"4px",sm:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"32px","3xl":"48px"},y={none:"0",sm:"4px",md:"6px",lg:"8px",xl:"10px",full:"9999px"},v={fontFamily:{sans:"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-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"}},w={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)"}},W={sm:"640px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},$={base:"0",dropdown:"100",sticky:"200",modal:"300",popover:"400",tooltip:"500",toast:"600"},X={"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"]}},Z={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 m(d){let t=b[d];return t?Object.entries(t).map(([e,a])=>`${e}: ${a};`).join(`
655
678
  `):""}function P(){return`
656
679
  /* Spacing */
657
- --loki-space-xs: ${x.xs};
658
- --loki-space-sm: ${x.sm};
659
- --loki-space-md: ${x.md};
660
- --loki-space-lg: ${x.lg};
661
- --loki-space-xl: ${x.xl};
662
- --loki-space-2xl: ${x["2xl"]};
663
- --loki-space-3xl: ${x["3xl"]};
680
+ --loki-space-xs: ${_.xs};
681
+ --loki-space-sm: ${_.sm};
682
+ --loki-space-md: ${_.md};
683
+ --loki-space-lg: ${_.lg};
684
+ --loki-space-xl: ${_.xl};
685
+ --loki-space-2xl: ${_["2xl"]};
686
+ --loki-space-3xl: ${_["3xl"]};
664
687
 
665
688
  /* Border Radius */
666
689
  --loki-radius-none: ${y.none};
@@ -701,7 +724,7 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
701
724
  --loki-glass-bg: rgba(255, 255, 255, 0.03);
702
725
  --loki-glass-border: rgba(255, 255, 255, 0.06);
703
726
  --loki-glass-blur: blur(12px);
704
- `}var M=`
727
+ `}var R=`
705
728
  /* Reset and base */
706
729
  :host {
707
730
  font-family: var(--loki-font-sans);
@@ -977,20 +1000,20 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
977
1000
  }
978
1001
 
979
1002
  /* Responsive utilities */
980
- @media (max-width: ${V.md}) {
1003
+ @media (max-width: ${W.md}) {
981
1004
  .hide-mobile { display: none !important; }
982
1005
  }
983
1006
 
984
- @media (min-width: ${V.md}) {
1007
+ @media (min-width: ${W.md}) {
985
1008
  .hide-desktop { display: none !important; }
986
1009
  }
987
- `,g=class g{static detectContext(){return typeof acquireVsCodeApi<"u"||document.body.classList.contains("vscode-body")||getComputedStyle(document.documentElement).getPropertyValue("--vscode-editor-background")?"vscode":document.documentElement.dataset.lokiContext==="cli"?"cli":"browser"}static detectVSCodeTheme(){let e=document.body;if(e.classList.contains("vscode-high-contrast"))return"high-contrast";if(e.classList.contains("vscode-dark"))return"dark";if(e.classList.contains("vscode-light"))return"light";let t=getComputedStyle(document.documentElement).getPropertyValue("--vscode-editor-background");if(t){let a=t.match(/\d+/g);if(a)return(parseInt(a[0])*299+parseInt(a[1])*587+parseInt(a[2])*114)/1e3>128?"light":"dark"}return null}static getTheme(){if(g.detectContext()==="vscode"){let a=g.detectVSCodeTheme();return a==="high-contrast"?"high-contrast":a==="dark"?"vscode-dark":"vscode-light"}let t=localStorage.getItem(g.STORAGE_KEY);return t&&b[t]?t:window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}static setTheme(e){if(!b[e]){console.warn(`Unknown theme: ${e}`);return}localStorage.setItem(g.STORAGE_KEY,e),document.documentElement.setAttribute("data-loki-theme",e),window.dispatchEvent(new CustomEvent("loki-theme-change",{detail:{theme:e,context:g.detectContext()}}))}static toggle(){let e=g.getTheme(),t;return e.includes("dark")||e==="high-contrast"?t=e.startsWith("vscode")?"vscode-light":"light":t=e.startsWith("vscode")?"vscode-dark":"dark",g.setTheme(t),t}static getVariables(e=null){let t=e||g.getTheme();return b[t]||b.light}static generateCSS(e=null){let t=e||g.getTheme();return`
1010
+ `,g=class g{static detectContext(){return typeof acquireVsCodeApi<"u"||document.body.classList.contains("vscode-body")||getComputedStyle(document.documentElement).getPropertyValue("--vscode-editor-background")?"vscode":document.documentElement.dataset.lokiContext==="cli"?"cli":"browser"}static detectVSCodeTheme(){let t=document.body;if(t.classList.contains("vscode-high-contrast"))return"high-contrast";if(t.classList.contains("vscode-dark"))return"dark";if(t.classList.contains("vscode-light"))return"light";let e=getComputedStyle(document.documentElement).getPropertyValue("--vscode-editor-background");if(e){let a=e.match(/\d+/g);if(a)return(parseInt(a[0])*299+parseInt(a[1])*587+parseInt(a[2])*114)/1e3>128?"light":"dark"}return null}static getTheme(){if(g.detectContext()==="vscode"){let a=g.detectVSCodeTheme();return a==="high-contrast"?"high-contrast":a==="dark"?"vscode-dark":"vscode-light"}let e=localStorage.getItem(g.STORAGE_KEY);return e&&b[e]?e:window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}static setTheme(t){if(!b[t]){console.warn(`Unknown theme: ${t}`);return}localStorage.setItem(g.STORAGE_KEY,t),document.documentElement.setAttribute("data-loki-theme",t),window.dispatchEvent(new CustomEvent("loki-theme-change",{detail:{theme:t,context:g.detectContext()}}))}static toggle(){let t=g.getTheme(),e;return t.includes("dark")||t==="high-contrast"?e=t.startsWith("vscode")?"vscode-light":"light":e=t.startsWith("vscode")?"vscode-dark":"dark",g.setTheme(e),e}static getVariables(t=null){let e=t||g.getTheme();return b[e]||b.light}static generateCSS(t=null){let e=t||g.getTheme();return`
988
1011
  :host {
989
- ${m(t)}
1012
+ ${m(e)}
990
1013
  ${P()}
991
1014
  }
992
- ${M}
993
- `}static init(){let e=g.getTheme();document.documentElement.setAttribute("data-loki-theme",e),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",()=>{localStorage.getItem(g.STORAGE_KEY)||g.setTheme(g.getTheme())}),g.detectContext()==="vscode"&&new MutationObserver(()=>{let a=g.getTheme();document.documentElement.setAttribute("data-loki-theme",a),window.dispatchEvent(new CustomEvent("loki-theme-change",{detail:{theme:a,context:"vscode"}}))}).observe(document.body,{attributes:!0,attributeFilter:["class"]})}};k(g,"STORAGE_KEY","loki-theme"),k(g,"CONTEXT_KEY","loki-context");var h=g,L=class{constructor(){this._handlers=new Map,this._enabled=!0}register(e,t){let a=Y[e];if(!a){console.warn(`Unknown keyboard action: ${e}`);return}this._handlers.set(e,{shortcut:a,handler:t})}unregister(e){this._handlers.delete(e)}setEnabled(e){this._enabled=e}handleEvent(e){if(!this._enabled)return!1;for(let[t,{shortcut:a,handler:i}]of this._handlers)if(this._matchesShortcut(e,a))return e.preventDefault(),e.stopPropagation(),i(e),!0;return!1}_matchesShortcut(e,t){let a=e.key.toLowerCase(),i=t.modifiers||[];if(a!==t.key.toLowerCase())return!1;let s=i.includes("Ctrl")||i.includes("Meta"),r=i.includes("Shift"),o=i.includes("Alt"),l=(e.ctrlKey||e.metaKey)===s,p=e.shiftKey===r,A=e.altKey===o;return l&&p&&A}attach(e){this._boundHandler||(this._boundHandler=t=>this.handleEvent(t)),e.addEventListener("keydown",this._boundHandler)}detach(e){this._boundHandler&&e.removeEventListener("keydown",this._boundHandler)}};var X={light:{"--loki-bg-primary":"#fafafa","--loki-bg-secondary":"#f4f4f5","--loki-bg-tertiary":"#e4e4e7","--loki-bg-card":"#ffffff","--loki-bg-hover":"#f0f0f3","--loki-accent":"#7c3aed","--loki-accent-light":"#8b5cf6","--loki-accent-muted":"rgba(124, 58, 237, 0.12)","--loki-text-primary":"#18181b","--loki-text-secondary":"#52525b","--loki-text-muted":"#a1a1aa","--loki-border":"#e4e4e7","--loki-border-light":"#d4d4d8","--loki-green":"#16a34a","--loki-green-muted":"rgba(22, 163, 74, 0.12)","--loki-yellow":"#ca8a04","--loki-yellow-muted":"rgba(202, 138, 4, 0.12)","--loki-red":"#dc2626","--loki-red-muted":"rgba(220, 38, 38, 0.12)","--loki-blue":"#2563eb","--loki-blue-muted":"rgba(37, 99, 235, 0.12)","--loki-purple":"#9333ea","--loki-purple-muted":"rgba(147, 51, 234, 0.12)","--loki-opus":"#d97706","--loki-sonnet":"#4f46e5","--loki-haiku":"#059669","--loki-transition":"0.2s cubic-bezier(0.4, 0, 0.2, 1)"},dark:{"--loki-bg-primary":"#09090b","--loki-bg-secondary":"#0c0c0f","--loki-bg-tertiary":"#111114","--loki-bg-card":"#18181b","--loki-bg-hover":"#1f1f23","--loki-accent":"#8b5cf6","--loki-accent-light":"#a78bfa","--loki-accent-muted":"rgba(139, 92, 246, 0.15)","--loki-text-primary":"#fafafa","--loki-text-secondary":"#a1a1aa","--loki-text-muted":"#52525b","--loki-border":"rgba(255, 255, 255, 0.06)","--loki-border-light":"rgba(255, 255, 255, 0.1)","--loki-green":"#22c55e","--loki-green-muted":"rgba(34, 197, 94, 0.15)","--loki-yellow":"#eab308","--loki-yellow-muted":"rgba(234, 179, 8, 0.15)","--loki-red":"#ef4444","--loki-red-muted":"rgba(239, 68, 68, 0.15)","--loki-blue":"#3b82f6","--loki-blue-muted":"rgba(59, 130, 246, 0.15)","--loki-purple":"#a78bfa","--loki-purple-muted":"rgba(167, 139, 250, 0.15)","--loki-opus":"#f59e0b","--loki-sonnet":"#818cf8","--loki-haiku":"#34d399","--loki-transition":"0.2s cubic-bezier(0.4, 0, 0.2, 1)"}},te=`
1015
+ ${R}
1016
+ `}static init(){let t=g.getTheme();document.documentElement.setAttribute("data-loki-theme",t),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",()=>{localStorage.getItem(g.STORAGE_KEY)||g.setTheme(g.getTheme())}),g.detectContext()==="vscode"&&new MutationObserver(()=>{let a=g.getTheme();document.documentElement.setAttribute("data-loki-theme",a),window.dispatchEvent(new CustomEvent("loki-theme-change",{detail:{theme:a,context:"vscode"}}))}).observe(document.body,{attributes:!0,attributeFilter:["class"]})}};k(g,"STORAGE_KEY","loki-theme"),k(g,"CONTEXT_KEY","loki-context");var h=g,L=class{constructor(){this._handlers=new Map,this._enabled=!0}register(t,e){let a=X[t];if(!a){console.warn(`Unknown keyboard action: ${t}`);return}this._handlers.set(t,{shortcut:a,handler:e})}unregister(t){this._handlers.delete(t)}setEnabled(t){this._enabled=t}handleEvent(t){if(!this._enabled)return!1;for(let[e,{shortcut:a,handler:i}]of this._handlers)if(this._matchesShortcut(t,a))return t.preventDefault(),t.stopPropagation(),i(t),!0;return!1}_matchesShortcut(t,e){let a=t.key.toLowerCase(),i=e.modifiers||[];if(a!==e.key.toLowerCase())return!1;let s=i.includes("Ctrl")||i.includes("Meta"),r=i.includes("Shift"),o=i.includes("Alt"),l=(t.ctrlKey||t.metaKey)===s,u=t.shiftKey===r,A=t.altKey===o;return l&&u&&A}attach(t){this._boundHandler||(this._boundHandler=e=>this.handleEvent(e)),t.addEventListener("keydown",this._boundHandler)}detach(t){this._boundHandler&&t.removeEventListener("keydown",this._boundHandler)}};var Q={light:{"--loki-bg-primary":"#fafafa","--loki-bg-secondary":"#f4f4f5","--loki-bg-tertiary":"#e4e4e7","--loki-bg-card":"#ffffff","--loki-bg-hover":"#f0f0f3","--loki-accent":"#7c3aed","--loki-accent-light":"#8b5cf6","--loki-accent-muted":"rgba(124, 58, 237, 0.12)","--loki-text-primary":"#18181b","--loki-text-secondary":"#52525b","--loki-text-muted":"#a1a1aa","--loki-border":"#e4e4e7","--loki-border-light":"#d4d4d8","--loki-green":"#16a34a","--loki-green-muted":"rgba(22, 163, 74, 0.12)","--loki-yellow":"#ca8a04","--loki-yellow-muted":"rgba(202, 138, 4, 0.12)","--loki-red":"#dc2626","--loki-red-muted":"rgba(220, 38, 38, 0.12)","--loki-blue":"#2563eb","--loki-blue-muted":"rgba(37, 99, 235, 0.12)","--loki-purple":"#9333ea","--loki-purple-muted":"rgba(147, 51, 234, 0.12)","--loki-opus":"#d97706","--loki-sonnet":"#4f46e5","--loki-haiku":"#059669","--loki-transition":"0.2s cubic-bezier(0.4, 0, 0.2, 1)"},dark:{"--loki-bg-primary":"#09090b","--loki-bg-secondary":"#0c0c0f","--loki-bg-tertiary":"#111114","--loki-bg-card":"#18181b","--loki-bg-hover":"#1f1f23","--loki-accent":"#8b5cf6","--loki-accent-light":"#a78bfa","--loki-accent-muted":"rgba(139, 92, 246, 0.15)","--loki-text-primary":"#fafafa","--loki-text-secondary":"#a1a1aa","--loki-text-muted":"#52525b","--loki-border":"rgba(255, 255, 255, 0.06)","--loki-border-light":"rgba(255, 255, 255, 0.1)","--loki-green":"#22c55e","--loki-green-muted":"rgba(34, 197, 94, 0.15)","--loki-yellow":"#eab308","--loki-yellow-muted":"rgba(234, 179, 8, 0.15)","--loki-red":"#ef4444","--loki-red-muted":"rgba(239, 68, 68, 0.15)","--loki-blue":"#3b82f6","--loki-blue-muted":"rgba(59, 130, 246, 0.15)","--loki-purple":"#a78bfa","--loki-purple-muted":"rgba(167, 139, 250, 0.15)","--loki-opus":"#f59e0b","--loki-sonnet":"#818cf8","--loki-haiku":"#34d399","--loki-transition":"0.2s cubic-bezier(0.4, 0, 0.2, 1)"}},it=`
994
1017
  :host {
995
1018
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
996
1019
  line-height: 1.5;
@@ -1086,8 +1109,8 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
1086
1109
  ::-webkit-scrollbar-track { background: var(--loki-bg-primary); }
1087
1110
  ::-webkit-scrollbar-thumb { background: var(--loki-border); border-radius: 3px; }
1088
1111
  ::-webkit-scrollbar-thumb:hover { background: var(--loki-border-light); }
1089
- `,E=class E{static getTheme(){return h.getTheme()}static setTheme(e){h.setTheme(e)}static toggle(){return h.toggle()}static getVariables(e=null){let t=e||E.getTheme();return b[t]||X[t]||X.light}static toCSSString(e=null){let t=e||E.getTheme();if(b[t])return m(t);let a=E.getVariables(t);return Object.entries(a).map(([i,s])=>`${i}: ${s};`).join(`
1090
- `)}static applyToElement(e,t=null){let a=E.getVariables(t);for(let[i,s]of Object.entries(a))e.style.setProperty(i,s)}static init(){h.init()}static detectContext(){return h.detectContext()}static getAvailableThemes(){return Object.keys(b)}};k(E,"STORAGE_KEY","loki-theme");var S=E,c=class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}),this._theme=S.getTheme(),this._themeChangeHandler=this._onThemeChange.bind(this),this._keyboardHandler=new L}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(){S.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`
1112
+ `,E=class E{static getTheme(){return h.getTheme()}static setTheme(t){h.setTheme(t)}static toggle(){return h.toggle()}static getVariables(t=null){let e=t||E.getTheme();return b[e]||Q[e]||Q.light}static toCSSString(t=null){let e=t||E.getTheme();if(b[e])return m(e);let a=E.getVariables(e);return Object.entries(a).map(([i,s])=>`${i}: ${s};`).join(`
1113
+ `)}static applyToElement(t,e=null){let a=E.getVariables(e);for(let[i,s]of Object.entries(a))t.style.setProperty(i,s)}static init(){h.init()}static detectContext(){return h.detectContext()}static getAvailableThemes(){return Object.keys(b)}};k(E,"STORAGE_KEY","loki-theme");var S=E,c=class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}),this._theme=S.getTheme(),this._themeChangeHandler=this._onThemeChange.bind(this),this._keyboardHandler=new L}connectedCallback(){window.addEventListener("loki-theme-change",this._themeChangeHandler),this._applyTheme(),this._setupKeyboardHandling(),this.render()}disconnectedCallback(){window.removeEventListener("loki-theme-change",this._themeChangeHandler),this._keyboardHandler.detach(this)}_onThemeChange(t){this._theme=t.detail.theme,this._applyTheme(),this.onThemeChange&&this.onThemeChange(this._theme)}_applyTheme(){S.applyToElement(this.shadowRoot.host,this._theme),this.setAttribute("data-loki-theme",this._theme)}_setupKeyboardHandling(){this._keyboardHandler.attach(this)}registerShortcut(t,e){this._keyboardHandler.register(t,e)}getBaseStyles(){return`
1091
1114
  /* Design tokens */
1092
1115
  :host {
1093
1116
  ${P()}
@@ -1142,8 +1165,50 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
1142
1165
  }
1143
1166
  }
1144
1167
 
1145
- ${M}
1146
- `}getAriaPattern(e){return W[e]||{}}applyAriaPattern(e,t){let a=this.getAriaPattern(t);for(let[i,s]of Object.entries(a))if(i==="role")e.setAttribute("role",s);else{let r=i.replace(/([A-Z])/g,"-$1").toLowerCase();e.setAttribute(r,s)}}render(){}};var T={realtime:1e3,normal:2e3,background:5e3,offline:1e4},ae={vscode:T.normal,browser:T.realtime,cli:T.background},ie={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},n={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"},_=class _ extends EventTarget{static getInstance(e={}){let t=e.baseUrl||ie.baseUrl;return _._instances.has(t)||_._instances.set(t,new _(e)),_._instances.get(t)}static clearInstances(){_._instances.forEach(e=>e.disconnect()),_._instances.clear()}constructor(e={}){super(),this.config={...ie,...e},this._ws=null,this._connected=!1,this._pollInterval=null,this._reconnectTimeout=null,this._cache=new Map,this._cacheTimeout=5e3,this._vscodeApi=null,this._context=this._detectContext(),this._currentPollInterval=ae[this._context]||T.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 T}_setupAdaptivePolling(){typeof document>"u"||(this._visibilityChangeHandler=()=>{document.hidden?this._setPollInterval(T.background):this._setPollInterval(ae[this._context]||T.normal)},document.addEventListener("visibilitychange",this._visibilityChangeHandler))}_setPollInterval(e){this._currentPollInterval=e,this._pollInterval&&(this.stopPolling(),this.startPolling(null,e))}setPollMode(e){let t=T[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(n.STATUS_UPDATE,t.data);break;case"updateTasks":this._emit(n.TASK_UPDATED,t.data);break;case"taskCreated":this._emit(n.TASK_CREATED,t.data);break;case"taskDeleted":this._emit(n.TASK_DELETED,t.data);break;case"projectCreated":this._emit(n.PROJECT_CREATED,t.data);break;case"projectUpdated":this._emit(n.PROJECT_UPDATED,t.data);break;case"agentUpdate":this._emit(n.AGENT_UPDATE,t.data);break;case"logMessage":this._emit(n.LOG_MESSAGE,t.data);break;case"memoryUpdate":this._emit(n.MEMORY_UPDATE,t.data);break;case"connected":this._connected=!0,this._emit(n.CONNECTED,t.data);break;case"disconnected":this._connected=!1,this._emit(n.DISCONNECTED,t.data);break;case"error":this._emit(n.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._emit(n.CONNECTED),e()},this._ws.onclose=()=>{this._connected=!1,this._emit(n.DISCONNECTED),this._scheduleReconnect()},this._ws.onerror=a=>{this._emit(n.ERROR,{error:a}),t(a)},this._ws.onmessage=a=>{try{let i=JSON.parse(a.data);this._handleMessage(i)}catch(i){console.error("Failed to parse WebSocket message:",i)}}}catch(a){t(a)}})}disconnect(){this._ws&&(this._ws.close(),this._ws=null),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._reconnectTimeout&&(clearTimeout(this._reconnectTimeout),this._reconnectTimeout=null),this._connected=!1,this._cleanupGlobalListeners()}_cleanupGlobalListeners(){this._visibilityChangeHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this._visibilityChangeHandler),this._visibilityChangeHandler=null),this._messageHandler&&typeof window<"u"&&(window.removeEventListener("message",this._messageHandler),this._messageHandler=null)}destroy(){this.disconnect()}_scheduleReconnect(){this._reconnectTimeout||(this._reconnectTimeout=setTimeout(()=>{this._reconnectTimeout=null,this.connect().catch(()=>{})},this.config.retryDelay))}_handleMessage(e){let a={connected:n.CONNECTED,status_update:n.STATUS_UPDATE,task_created:n.TASK_CREATED,task_updated:n.TASK_UPDATED,task_deleted:n.TASK_DELETED,task_moved:n.TASK_UPDATED,project_created:n.PROJECT_CREATED,project_updated:n.PROJECT_UPDATED,agent_update:n.AGENT_UPDATE,log:n.LOG_MESSAGE}[e.type]||`api:${e.type}`;this._emit(a,e.data)}_emit(e,t={}){this.dispatchEvent(new CustomEvent(e,{detail:t}))}async _request(e,t={}){let a=`${this.config.baseUrl}${e}`,i=new AbortController,s=setTimeout(()=>i.abort(),this.config.timeout);try{let r=await fetch(a,{...t,signal:i.signal,headers:{"Content-Type":"application/json",...t.headers}});if(clearTimeout(s),!r.ok){let o=await r.json().catch(()=>({detail:r.statusText}));throw new Error(o.detail||`HTTP ${r.status}`)}return r.status===204?null:await r.json()}catch(r){throw clearTimeout(s),r.name==="AbortError"?new Error("Request timeout"):r}}async _get(e,t=!1){if(t&&this._cache.has(e)){let i=this._cache.get(e);if(Date.now()-i.timestamp<this._cacheTimeout)return i.data}let a=await this._request(e);return t&&this._cache.set(e,{data:a,timestamp:Date.now()}),a}async _post(e,t){return this._request(e,{method:"POST",body:JSON.stringify(t)})}async _put(e,t){return this._request(e,{method:"PUT",body:JSON.stringify(t)})}async _delete(e){return this._request(e,{method:"DELETE"})}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 a=t.toString()?`?${t}`:"";return this._get(`/api/tasks${a}`)}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,a){return this._post(`/api/tasks/${e}/move`,{status:t,position:a})}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,a=5){return this._post("/api/memory/retrieve",{query:e,taskType:t,topK:a})}async consolidateMemory(e=24){return this._post("/api/memory/consolidate",{sinceHours:e})}async getTokenEconomics(){return this._get("/api/memory/economics")}async listRegisteredProjects(e=!1){return this._get(`/api/registry/projects?include_inactive=${e}`)}async registerProject(e,t=null,a=null){return this._post("/api/registry/projects",{path:e,name:t,alias:a})}async discoverProjects(e=3){return this._get(`/api/registry/discover?max_depth=${e}`)}async syncRegistry(){return this._post("/api/registry/sync",{})}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 a=t.toString()?`?${t}`:"";return this._get(`/api/learning/metrics${a}`)}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 a=t.toString()?`?${t}`:"";return this._get(`/api/learning/trends${a}`)}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 a=t.toString()?`?${t}`:"";return this._get(`/api/learning/signals${a}`)}async getLatestAggregation(){return this._get("/api/learning/aggregation")}async triggerAggregation(e={}){return this._post("/api/learning/aggregate",e)}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 getContext(){return this._get("/api/context")}async getNotifications(e,t){let a=new URLSearchParams;e&&a.set("severity",e),t&&a.set("unread_only","true");let i=a.toString();return this._get("/api/notifications"+(i?"?"+i:""))}async getNotificationTriggers(){return this._get("/api/notifications/triggers")}async updateNotificationTriggers(e){return this._put("/api/notifications/triggers",{triggers:e})}async acknowledgeNotification(e){return this._post("/api/notifications/"+encodeURIComponent(e)+"/acknowledge",{})}async pauseSession(){return this._post("/api/control/pause",{})}async resumeSession(){return this._post("/api/control/resume",{})}async stopSession(){return this._post("/api/control/stop",{})}async getLogs(e=100){return this._get(`/api/logs?lines=${e}`)}startPolling(e,t=null){if(this._pollInterval)return;this._pollCallback=e;let a=async()=>{try{let s=await this.getStatus();this._connected=!0,this._pollCallback&&this._pollCallback(s),this._emit(n.STATUS_UPDATE,s),this._vscodeApi&&this.postToVSCode("pollSuccess",{timestamp:Date.now()})}catch(s){this._connected=!1,this._emit(n.ERROR,{error:s}),this._vscodeApi&&this.postToVSCode("pollError",{error:s.message})}};a();let i=t||this._currentPollInterval||this.config.pollInterval;this._pollInterval=setInterval(a,i)}stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}};k(_,"_instances",new Map);var I=_;function se(d={}){return new I(d)}function u(d={}){return I.getInstance(d)}var Q="loki-state-change",Z={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}},f=class f extends EventTarget{static getInstance(){return f._instance||(f._instance=new f),f._instance}constructor(){super(),this._state=this._loadState(),this._subscribers=new Map,this._batchUpdates=[],this._batchTimeout=null}_loadState(){try{let e=localStorage.getItem(f.STORAGE_KEY);if(e){let t=JSON.parse(e);return this._mergeState(Z,t)}}catch(e){console.warn("Failed to load state from localStorage:",e)}return{...Z}}_mergeState(e,t){let a={...e};for(let i of Object.keys(t))i in e&&typeof e[i]=="object"&&!Array.isArray(e[i])?a[i]=this._mergeState(e[i],t[i]):a[i]=t[i];return a}_saveState(){try{let e={ui:this._state.ui,localTasks:this._state.localTasks,preferences:this._state.preferences};localStorage.setItem(f.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("."),a=this._state;for(let i of t){if(a==null)return;a=a[i]}return a}set(e,t,a=!0){let i=e.split("."),s=i.pop(),r=this._state;for(let l of i)l in r||(r[l]={}),r=r[l];let o=r[s];r[s]=t,a&&this._saveState(),this._notifyChange(e,t,o)}update(e,t=!0){let a=[];for(let[i,s]of Object.entries(e)){let r=this.get(i);this.set(i,s,!1),a.push({path:i,value:s,oldValue:r})}t&&this._saveState();for(let i of a)this._notifyChange(i.path,i.value,i.oldValue)}_notifyChange(e,t,a){this.dispatchEvent(new CustomEvent(Q,{detail:{path:e,value:t,oldValue:a}}));let i=this._subscribers.get(e)||[];for(let r of i)try{r(t,a,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 l of o)try{l(this.get(r),null,r)}catch(p){console.error("State subscriber error:",p)}}}subscribe(e,t){return this._subscribers.has(e)||this._subscribers.set(e,[]),this._subscribers.get(e).push(t),()=>{let a=this._subscribers.get(e),i=a.indexOf(t);i>-1&&a.splice(i,1)}}reset(e=null){if(e){let t=e.split("."),a=Z;for(let i of t)a=a?.[i];this.set(e,a)}else this._state={...Z},this._saveState(),this.dispatchEvent(new CustomEvent(Q,{detail:{path:null,value:this._state,oldValue:null}}))}addLocalTask(e){let t=this.get("localTasks")||[],a={id:`local-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,createdAt:new Date().toISOString(),status:"pending",...e};return this.set("localTasks",[...t,a]),a}updateLocalTask(e,t){let a=this.get("localTasks")||[],i=a.findIndex(r=>r.id===e);if(i===-1)return null;let s={...a[i],...t,updatedAt:new Date().toISOString()};return a[i]=s,this.set("localTasks",[...a]),s}deleteLocalTask(e){let t=this.get("localTasks")||[];this.set("localTasks",t.filter(a=>a.id!==e))}moveLocalTask(e,t,a=null){let s=(this.get("localTasks")||[]).find(r=>r.id===e);return s?this.updateLocalTask(e,{status:t,position:a??s.position}):null}updateSession(e){this.update(Object.fromEntries(Object.entries(e).map(([t,a])=>[`session.${t}`,a])),!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")||[],a=(this.get("localTasks")||[]).map(i=>({...i,isLocal:!0}));return[...e,...a]}getTasksByStatus(e){return this.getMergedTasks().filter(t=>t.status===e)}};k(f,"STORAGE_KEY","loki-dashboard-state"),k(f,"_instance",null);var R=f;function C(){return R.getInstance()}function re(d){let e=C();return{get:()=>e.get(d),set:t=>e.set(d,t),subscribe:t=>e.subscribe(d,t)}}var z=class extends c{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}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(n.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(n.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(n.DISCONNECTED,this._disconnectedHandler))}attributeChangedCallback(e,t,a){t!==a&&(e==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadStatus()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=u({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(n.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(n.CONNECTED,this._connectedHandler),this._api.addEventListener(n.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){try{let e=await this._api.getStatus();this._updateFromStatus(e)}catch{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},this.render())}_startPolling(){this._pollInterval=setInterval(async()=>{try{let e=await this._api.getStatus();this._updateFromStatus(e)}catch{this._data.connected=!1,this._data.status="offline",this.render()}},5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_formatUptime(e){if(!e||e<0)return"--";let t=Math.floor(e/3600),a=Math.floor(e%3600/60),i=Math.floor(e%60);return t>0?`${t}h ${a}m`:a>0?`${a}m ${i}s`:`${i}s`}_getStatusDotClass(){switch(this._data.status){case"running":case"autonomous":return"active";case"paused":return"paused";case"stopped":return"stopped";case"error":return"error";default:return"offline"}}render(){let e=this._getStatusDotClass(),t=(this._data.status||"OFFLINE").toUpperCase(),a=this._data.phase||"--",i=this._data.iteration!=null?String(this._data.iteration):"0",s=(this._data.provider||"CLAUDE").toUpperCase(),r=String(this._data.running_agents||0),o=this._data.pending_tasks!=null?`${this._data.pending_tasks} pending`:"--",l=this._formatUptime(this._data.uptime_seconds),p=(this._data.complexity||"STANDARD").toUpperCase();this.shadowRoot.innerHTML=`
1168
+ ${R}
1169
+ `}getAriaPattern(t){return Z[t]||{}}applyAriaPattern(t,e){let a=this.getAriaPattern(e);for(let[i,s]of Object.entries(a))if(i==="role")t.setAttribute("role",s);else{let r=i.replace(/([A-Z])/g,"-$1").toLowerCase();t.setAttribute(r,s)}}render(){}};var T={realtime:1e3,normal:2e3,background:5e3,offline:1e4},st={vscode:T.normal,browser:T.realtime,cli:T.background},rt={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},n={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"},x=class x extends EventTarget{static getInstance(t={}){let e=t.baseUrl||rt.baseUrl;return x._instances.has(e)||x._instances.set(e,new x(t)),x._instances.get(e)}static clearInstances(){x._instances.forEach(t=>t.disconnect()),x._instances.clear()}constructor(t={}){super(),this.config={...rt,...t},this._ws=null,this._connected=!1,this._pollInterval=null,this._reconnectTimeout=null,this._cache=new Map,this._cacheTimeout=5e3,this._vscodeApi=null,this._context=this._detectContext(),this._currentPollInterval=st[this._context]||T.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 T}_setupAdaptivePolling(){typeof document>"u"||(this._visibilityChangeHandler=()=>{document.hidden?this._setPollInterval(T.background):this._setPollInterval(st[this._context]||T.normal)},document.addEventListener("visibilitychange",this._visibilityChangeHandler))}_setPollInterval(t){this._currentPollInterval=t,this._pollInterval&&(this.stopPolling(),this.startPolling(null,t))}setPollMode(t){let e=T[t];e&&this._setPollInterval(e)}_setupVSCodeBridge(){if(!(typeof acquireVsCodeApi>"u")){try{this._vscodeApi=acquireVsCodeApi()}catch{console.warn("VS Code API already acquired or unavailable");return}this._messageHandler=t=>{let e=t.data;if(!(!e||!e.type))switch(e.type){case"updateStatus":this._emit(n.STATUS_UPDATE,e.data);break;case"updateTasks":this._emit(n.TASK_UPDATED,e.data);break;case"taskCreated":this._emit(n.TASK_CREATED,e.data);break;case"taskDeleted":this._emit(n.TASK_DELETED,e.data);break;case"projectCreated":this._emit(n.PROJECT_CREATED,e.data);break;case"projectUpdated":this._emit(n.PROJECT_UPDATED,e.data);break;case"agentUpdate":this._emit(n.AGENT_UPDATE,e.data);break;case"logMessage":this._emit(n.LOG_MESSAGE,e.data);break;case"memoryUpdate":this._emit(n.MEMORY_UPDATE,e.data);break;case"connected":this._connected=!0,this._emit(n.CONNECTED,e.data);break;case"disconnected":this._connected=!1,this._emit(n.DISCONNECTED,e.data);break;case"error":this._emit(n.ERROR,e.data);break;case"setPollMode":this.setPollMode(e.data.mode);break;default:this._emit(`api:${e.type}`,e.data)}},window.addEventListener("message",this._messageHandler)}}get isVSCode(){return this._context==="vscode"}postToVSCode(t,e={}){this._vscodeApi&&this._vscodeApi.postMessage({type:t,data:e})}requestRefresh(){this.postToVSCode("requestRefresh")}notifyVSCode(t,e={}){this.postToVSCode("userAction",{action:t,...e})}get baseUrl(){return this.config.baseUrl}set baseUrl(t){this.config.baseUrl=t,this.config.wsUrl=t.replace(/^http/,"ws")+"/ws"}get isConnected(){return this._connected}async connect(){if(!(this._ws&&this._ws.readyState===WebSocket.OPEN))return new Promise((t,e)=>{try{this._ws=new WebSocket(this.config.wsUrl),this._ws.onopen=()=>{this._connected=!0,this._emit(n.CONNECTED),t()},this._ws.onclose=()=>{this._connected=!1,this._emit(n.DISCONNECTED),this._scheduleReconnect()},this._ws.onerror=a=>{this._emit(n.ERROR,{error:a}),e(a)},this._ws.onmessage=a=>{try{let i=JSON.parse(a.data);this._handleMessage(i)}catch(i){console.error("Failed to parse WebSocket message:",i)}}}catch(a){e(a)}})}disconnect(){this._ws&&(this._ws.close(),this._ws=null),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._reconnectTimeout&&(clearTimeout(this._reconnectTimeout),this._reconnectTimeout=null),this._connected=!1,this._cleanupGlobalListeners()}_cleanupGlobalListeners(){this._visibilityChangeHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this._visibilityChangeHandler),this._visibilityChangeHandler=null),this._messageHandler&&typeof window<"u"&&(window.removeEventListener("message",this._messageHandler),this._messageHandler=null)}destroy(){this.disconnect()}_scheduleReconnect(){this._reconnectTimeout||(this._reconnectTimeout=setTimeout(()=>{this._reconnectTimeout=null,this.connect().catch(()=>{})},this.config.retryDelay))}_handleMessage(t){let a={connected:n.CONNECTED,status_update:n.STATUS_UPDATE,task_created:n.TASK_CREATED,task_updated:n.TASK_UPDATED,task_deleted:n.TASK_DELETED,task_moved:n.TASK_UPDATED,project_created:n.PROJECT_CREATED,project_updated:n.PROJECT_UPDATED,agent_update:n.AGENT_UPDATE,log:n.LOG_MESSAGE}[t.type]||`api:${t.type}`;this._emit(a,t.data)}_emit(t,e={}){this.dispatchEvent(new CustomEvent(t,{detail:e}))}async _request(t,e={}){let a=`${this.config.baseUrl}${t}`,i=new AbortController,s=setTimeout(()=>i.abort(),this.config.timeout);try{let r=await fetch(a,{...e,signal:i.signal,headers:{"Content-Type":"application/json",...e.headers}});if(clearTimeout(s),!r.ok){let o=await r.json().catch(()=>({detail:r.statusText}));throw new Error(o.detail||`HTTP ${r.status}`)}return r.status===204?null:await r.json()}catch(r){throw clearTimeout(s),r.name==="AbortError"?new Error("Request timeout"):r}}async _get(t,e=!1){if(e&&this._cache.has(t)){let i=this._cache.get(t);if(Date.now()-i.timestamp<this._cacheTimeout)return i.data}let a=await this._request(t);return e&&this._cache.set(t,{data:a,timestamp:Date.now()}),a}async _post(t,e){return this._request(t,{method:"POST",body:JSON.stringify(e)})}async _put(t,e){return this._request(t,{method:"PUT",body:JSON.stringify(e)})}async _delete(t){return this._request(t,{method:"DELETE"})}async getStatus(){return this._get("/api/status")}async healthCheck(){return this._get("/health")}async listProjects(t=null){let e=t?`?status=${t}`:"";return this._get(`/api/projects${e}`)}async getProject(t){return this._get(`/api/projects/${t}`)}async createProject(t){return this._post("/api/projects",t)}async updateProject(t,e){return this._put(`/api/projects/${t}`,e)}async deleteProject(t){return this._delete(`/api/projects/${t}`)}async listTasks(t={}){let e=new URLSearchParams;t.projectId&&e.append("project_id",t.projectId),t.status&&e.append("status",t.status),t.priority&&e.append("priority",t.priority);let a=e.toString()?`?${e}`:"";return this._get(`/api/tasks${a}`)}async getTask(t){return this._get(`/api/tasks/${t}`)}async createTask(t){return this._post("/api/tasks",t)}async updateTask(t,e){return this._put(`/api/tasks/${t}`,e)}async moveTask(t,e,a){return this._post(`/api/tasks/${t}/move`,{status:e,position:a})}async deleteTask(t){return this._delete(`/api/tasks/${t}`)}async getMemorySummary(){return this._get("/api/memory/summary",!0)}async getMemoryIndex(){return this._get("/api/memory/index",!0)}async getMemoryTimeline(){return this._get("/api/memory/timeline")}async listEpisodes(t={}){let e=new URLSearchParams(t).toString();return this._get(`/api/memory/episodes${e?"?"+e:""}`)}async getEpisode(t){return this._get(`/api/memory/episodes/${t}`)}async listPatterns(t={}){let e=new URLSearchParams(t).toString();return this._get(`/api/memory/patterns${e?"?"+e:""}`)}async getPattern(t){return this._get(`/api/memory/patterns/${t}`)}async listSkills(){return this._get("/api/memory/skills")}async getSkill(t){return this._get(`/api/memory/skills/${t}`)}async retrieveMemories(t,e=null,a=5){return this._post("/api/memory/retrieve",{query:t,taskType:e,topK:a})}async consolidateMemory(t=24){return this._post("/api/memory/consolidate",{sinceHours:t})}async getTokenEconomics(){return this._get("/api/memory/economics")}async listRegisteredProjects(t=!1){return this._get(`/api/registry/projects?include_inactive=${t}`)}async registerProject(t,e=null,a=null){return this._post("/api/registry/projects",{path:t,name:e,alias:a})}async discoverProjects(t=3){return this._get(`/api/registry/discover?max_depth=${t}`)}async syncRegistry(){return this._post("/api/registry/sync",{})}async getCrossProjectTasks(t=null){let e=t?`?project_ids=${t.join(",")}`:"";return this._get(`/api/registry/tasks${e}`)}async getLearningMetrics(t={}){let e=new URLSearchParams;t.timeRange&&e.append("timeRange",t.timeRange),t.signalType&&e.append("signalType",t.signalType),t.source&&e.append("source",t.source);let a=e.toString()?`?${e}`:"";return this._get(`/api/learning/metrics${a}`)}async getLearningTrends(t={}){let e=new URLSearchParams;t.timeRange&&e.append("timeRange",t.timeRange),t.signalType&&e.append("signalType",t.signalType),t.source&&e.append("source",t.source);let a=e.toString()?`?${e}`:"";return this._get(`/api/learning/trends${a}`)}async getLearningSignals(t={}){let e=new URLSearchParams;t.timeRange&&e.append("timeRange",t.timeRange),t.signalType&&e.append("signalType",t.signalType),t.source&&e.append("source",t.source),t.limit&&e.append("limit",String(t.limit)),t.offset&&e.append("offset",String(t.offset));let a=e.toString()?`?${e}`:"";return this._get(`/api/learning/signals${a}`)}async getLatestAggregation(){return this._get("/api/learning/aggregation")}async triggerAggregation(t={}){return this._post("/api/learning/aggregate",t)}async getAggregatedPreferences(t=20){return this._get(`/api/learning/preferences?limit=${t}`)}async getAggregatedErrors(t=20){return this._get(`/api/learning/errors?limit=${t}`)}async getAggregatedSuccessPatterns(t=20){return this._get(`/api/learning/success?limit=${t}`)}async getToolEfficiency(t=20){return this._get(`/api/learning/tools?limit=${t}`)}async getCost(){return this._get("/api/cost")}async getPricing(){return this._get("/api/pricing")}async getCouncilState(){return this._get("/api/council/state")}async getCouncilVerdicts(t=20){return this._get(`/api/council/verdicts?limit=${t}`)}async getCouncilConvergence(){return this._get("/api/council/convergence")}async getCouncilReport(){return this._get("/api/council/report")}async forceCouncilReview(){return this._post("/api/council/force-review",{})}async getContext(){return this._get("/api/context")}async getNotifications(t,e){let a=new URLSearchParams;t&&a.set("severity",t),e&&a.set("unread_only","true");let i=a.toString();return this._get("/api/notifications"+(i?"?"+i:""))}async getNotificationTriggers(){return this._get("/api/notifications/triggers")}async updateNotificationTriggers(t){return this._put("/api/notifications/triggers",{triggers:t})}async acknowledgeNotification(t){return this._post("/api/notifications/"+encodeURIComponent(t)+"/acknowledge",{})}async pauseSession(){return this._post("/api/control/pause",{})}async resumeSession(){return this._post("/api/control/resume",{})}async stopSession(){return this._post("/api/control/stop",{})}async getLogs(t=100){return this._get(`/api/logs?lines=${t}`)}async getChecklist(){return this._get("/api/checklist")}async getChecklistSummary(){return this._get("/api/checklist/summary")}async getPrdObservations(){let t=await fetch(`${this.baseUrl}/api/prd-observations`);if(!t.ok)throw new Error(`HTTP ${t.status}`);return t.text()}async getAppRunnerStatus(){return this._get("/api/app-runner/status")}async getAppRunnerLogs(t=100){return this._get(`/api/app-runner/logs?lines=${t}`)}async restartApp(){return this._post("/api/control/app-restart")}async stopApp(){return this._post("/api/control/app-stop")}async getPlaywrightResults(){return this._get("/api/playwright/results")}async getPlaywrightScreenshot(){return this._get("/api/playwright/screenshot")}startPolling(t,e=null){if(this._pollInterval)return;this._pollCallback=t;let a=async()=>{try{let s=await this.getStatus();this._connected=!0,this._pollCallback&&this._pollCallback(s),this._emit(n.STATUS_UPDATE,s),this._vscodeApi&&this.postToVSCode("pollSuccess",{timestamp:Date.now()})}catch(s){this._connected=!1,this._emit(n.ERROR,{error:s}),this._vscodeApi&&this.postToVSCode("pollError",{error:s.message})}};a();let i=e||this._currentPollInterval||this.config.pollInterval;this._pollInterval=setInterval(a,i)}stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}};k(x,"_instances",new Map);var I=x;function ot(d={}){return new I(d)}function p(d={}){return I.getInstance(d)}var et="loki-state-change",tt={ui:{theme:"light",sidebarCollapsed:!1,activeSection:"kanban",terminalAutoScroll:!0},session:{connected:!1,lastSync:null,mode:"offline",phase:null,iteration:null},localTasks:[],cache:{projects:[],tasks:[],agents:[],memory:null,lastFetch:null},preferences:{pollInterval:2e3,notifications:!0,soundEnabled:!1}},f=class f extends EventTarget{static getInstance(){return f._instance||(f._instance=new f),f._instance}constructor(){super(),this._state=this._loadState(),this._subscribers=new Map,this._batchUpdates=[],this._batchTimeout=null}_loadState(){try{let t=localStorage.getItem(f.STORAGE_KEY);if(t){let e=JSON.parse(t);return this._mergeState(tt,e)}}catch(t){console.warn("Failed to load state from localStorage:",t)}return{...tt}}_mergeState(t,e){let a={...t};for(let i of Object.keys(e))i in t&&typeof t[i]=="object"&&!Array.isArray(t[i])?a[i]=this._mergeState(t[i],e[i]):a[i]=e[i];return a}_saveState(){try{let t={ui:this._state.ui,localTasks:this._state.localTasks,preferences:this._state.preferences};localStorage.setItem(f.STORAGE_KEY,JSON.stringify(t))}catch(t){console.warn("Failed to save state to localStorage:",t)}}get(t=null){if(!t)return{...this._state};let e=t.split("."),a=this._state;for(let i of e){if(a==null)return;a=a[i]}return a}set(t,e,a=!0){let i=t.split("."),s=i.pop(),r=this._state;for(let l of i)l in r||(r[l]={}),r=r[l];let o=r[s];r[s]=e,a&&this._saveState(),this._notifyChange(t,e,o)}update(t,e=!0){let a=[];for(let[i,s]of Object.entries(t)){let r=this.get(i);this.set(i,s,!1),a.push({path:i,value:s,oldValue:r})}e&&this._saveState();for(let i of a)this._notifyChange(i.path,i.value,i.oldValue)}_notifyChange(t,e,a){this.dispatchEvent(new CustomEvent(et,{detail:{path:t,value:e,oldValue:a}}));let i=this._subscribers.get(t)||[];for(let r of i)try{r(e,a,t)}catch(o){console.error("State subscriber error:",o)}let s=t.split(".");for(;s.length>1;){s.pop();let r=s.join("."),o=this._subscribers.get(r)||[];for(let l of o)try{l(this.get(r),null,r)}catch(u){console.error("State subscriber error:",u)}}}subscribe(t,e){return this._subscribers.has(t)||this._subscribers.set(t,[]),this._subscribers.get(t).push(e),()=>{let a=this._subscribers.get(t),i=a.indexOf(e);i>-1&&a.splice(i,1)}}reset(t=null){if(t){let e=t.split("."),a=tt;for(let i of e)a=a?.[i];this.set(t,a)}else this._state={...tt},this._saveState(),this.dispatchEvent(new CustomEvent(et,{detail:{path:null,value:this._state,oldValue:null}}))}addLocalTask(t){let e=this.get("localTasks")||[],a={id:`local-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,createdAt:new Date().toISOString(),status:"pending",...t};return this.set("localTasks",[...e,a]),a}updateLocalTask(t,e){let a=this.get("localTasks")||[],i=a.findIndex(r=>r.id===t);if(i===-1)return null;let s={...a[i],...e,updatedAt:new Date().toISOString()};return a[i]=s,this.set("localTasks",[...a]),s}deleteLocalTask(t){let e=this.get("localTasks")||[];this.set("localTasks",e.filter(a=>a.id!==t))}moveLocalTask(t,e,a=null){let s=(this.get("localTasks")||[]).find(r=>r.id===t);return s?this.updateLocalTask(t,{status:e,position:a??s.position}):null}updateSession(t){this.update(Object.fromEntries(Object.entries(t).map(([e,a])=>[`session.${e}`,a])),!1)}updateCache(t){this.update({"cache.projects":t.projects??this.get("cache.projects"),"cache.tasks":t.tasks??this.get("cache.tasks"),"cache.agents":t.agents??this.get("cache.agents"),"cache.memory":t.memory??this.get("cache.memory"),"cache.lastFetch":new Date().toISOString()},!1)}getMergedTasks(){let t=this.get("cache.tasks")||[],a=(this.get("localTasks")||[]).map(i=>({...i,isLocal:!0}));return[...t,...a]}getTasksByStatus(t){return this.getMergedTasks().filter(e=>e.status===t)}};k(f,"STORAGE_KEY","loki-dashboard-state"),k(f,"_instance",null);var M=f;function C(){return M.getInstance()}function nt(d){let t=C();return{get:()=>t.get(d),set:e=>t.set(d,e),subscribe:e=>t.subscribe(d,e)}}var H=class extends c{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}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(n.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(n.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(n.DISCONNECTED,this._disconnectedHandler))}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadStatus()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=p({baseUrl:t}),this._statusUpdateHandler=e=>this._updateFromStatus(e.detail),this._connectedHandler=()=>{this._data.connected=!0,this.render()},this._disconnectedHandler=()=>{this._data.connected=!1,this._data.status="offline",this.render()},this._api.addEventListener(n.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(n.CONNECTED,this._connectedHandler),this._api.addEventListener(n.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){try{let[t,e,a,i]=await Promise.allSettled([this._api.getStatus(),this._api.getChecklistSummary(),this._api.getAppRunnerStatus(),this._api.getPlaywrightResults()]);t.status==="fulfilled"?this._updateFromStatus(t.value):(this._data.connected=!1,this._data.status="offline"),e.status==="fulfilled"&&(this._checklistSummary=e.value?.summary||null),a.status==="fulfilled"&&(this._appRunnerStatus=a.value),i.status==="fulfilled"&&(this._playwrightResults=i.value),this.render()}catch{this._data.connected=!1,this._data.status="offline",this.render()}}_updateFromStatus(t){t&&(this._data={...this._data,connected:!0,status:t.status||"offline",phase:t.phase||null,iteration:t.iteration!=null?t.iteration:null,provider:t.provider||null,running_agents:t.running_agents||0,pending_tasks:t.pending_tasks!=null?t.pending_tasks:null,uptime_seconds:t.uptime_seconds||0,complexity:t.complexity||null},this.render())}_startPolling(){this._pollInterval=setInterval(async()=>{try{let t=await this._api.getStatus();this._updateFromStatus(t)}catch{this._data.connected=!1,this._data.status="offline",this.render()}},5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_formatUptime(t){if(!t||t<0)return"--";let e=Math.floor(t/3600),a=Math.floor(t%3600/60),i=Math.floor(t%60);return e>0?`${e}h ${a}m`:a>0?`${a}m ${i}s`:`${i}s`}_getStatusDotClass(){switch(this._data.status){case"running":case"autonomous":return"active";case"paused":return"paused";case"stopped":return"stopped";case"error":return"error";default:return"offline"}}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_renderAppRunnerCard(){let t=this._appRunnerStatus;if(!t||t.status==="not_initialized")return`
1170
+ <div class="overview-card">
1171
+ <div class="card-label">App Runner</div>
1172
+ <div class="card-value small-text">--</div>
1173
+ </div>
1174
+ `;let a={running:"var(--loki-green, #22c55e)",starting:"var(--loki-yellow, #f59e0b)",crashed:"var(--loki-red, #ef4444)",stopped:"var(--loki-text-muted, #a1a1aa)"}[t.status]||"var(--loki-text-muted)",i=t.status==="running"?"active":t.status==="crashed"?"error":"offline",s=(t.status||"unknown").toUpperCase(),r=t.port?`:${t.port}`:"";return`
1175
+ <div class="overview-card">
1176
+ <div class="card-label">App Runner</div>
1177
+ <div class="card-value small-text">
1178
+ <span class="status-dot ${i}"></span>
1179
+ ${s}${r}
1180
+ </div>
1181
+ ${t.method?`<div style="font-size:10px;color:var(--loki-text-muted);margin-top:2px;">${this._escapeHtml(t.method)}</div>`:""}
1182
+ </div>
1183
+ `}_renderPlaywrightCard(){let t=this._playwrightResults;if(!t||t==="null"||!t.verified_at)return`
1184
+ <div class="overview-card">
1185
+ <div class="card-label">Verification</div>
1186
+ <div class="card-value small-text">--</div>
1187
+ </div>
1188
+ `;let e=t.passed===!0,a=e?"var(--loki-green, #22c55e)":"var(--loki-red, #ef4444)",i=e?"PASSED":"FAILED",s=e?"active":"error",r=t.checks||{},o=Object.values(r).filter(l=>!l).length;return`
1189
+ <div class="overview-card">
1190
+ <div class="card-label">Verification</div>
1191
+ <div class="card-value small-text">
1192
+ <span class="status-dot ${s}"></span>
1193
+ ${i}
1194
+ </div>
1195
+ ${!e&&o>0?`<div style="font-size:10px;color:var(--loki-red,#ef4444);margin-top:2px;">${o} check(s) failed</div>`:""}
1196
+ </div>
1197
+ `}_renderChecklistCard(){let t=this._checklistSummary;if(!t||!t.total)return`
1198
+ <div class="overview-card">
1199
+ <div class="card-label">PRD Progress</div>
1200
+ <div class="card-value small-text">--</div>
1201
+ </div>
1202
+ `;let e=Math.round(t.verified/t.total*100),a=t.failing>0?"var(--loki-yellow, #f59e0b)":"var(--loki-green, #22c55e)";return`
1203
+ <div class="overview-card">
1204
+ <div class="card-label">PRD Progress</div>
1205
+ <div class="card-value small-text">${t.verified}/${t.total} (${e}%)</div>
1206
+ <div class="mini-progress" style="margin-top:4px;height:4px;background:var(--loki-bg-secondary,#e4e4e7);border-radius:2px;overflow:hidden;">
1207
+ <div style="width:${e}%;height:100%;background:${a};transition:width 0.3s;"></div>
1208
+ </div>
1209
+ ${t.failing?`<div style="font-size:10px;color:var(--loki-red,#ef4444);margin-top:2px;">${t.failing} failing</div>`:""}
1210
+ </div>
1211
+ `}render(){let t=this._getStatusDotClass(),e=(this._data.status||"OFFLINE").toUpperCase(),a=this._data.phase||"--",i=this._data.iteration!=null?String(this._data.iteration):"0",s=(this._data.provider||"CLAUDE").toUpperCase(),r=String(this._data.running_agents||0),o=this._data.pending_tasks!=null?`${this._data.pending_tasks} pending`:"--",l=this._formatUptime(this._data.uptime_seconds),u=(this._data.complexity||"STANDARD").toUpperCase();this.shadowRoot.innerHTML=`
1147
1212
  <style>
1148
1213
  ${this.getBaseStyles()}
1149
1214
 
@@ -1269,8 +1334,8 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
1269
1334
  <div class="overview-card">
1270
1335
  <div class="card-label">Session</div>
1271
1336
  <div class="card-value">
1272
- <span class="status-dot ${e}"></span>
1273
- ${t}
1337
+ <span class="status-dot ${t}"></span>
1338
+ ${e}
1274
1339
  </div>
1275
1340
  </div>
1276
1341
 
@@ -1299,6 +1364,12 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
1299
1364
  <div class="card-value small-text">${o}</div>
1300
1365
  </div>
1301
1366
 
1367
+ ${this._renderChecklistCard()}
1368
+
1369
+ ${this._renderAppRunnerCard()}
1370
+
1371
+ ${this._renderPlaywrightCard()}
1372
+
1302
1373
  <div class="overview-card">
1303
1374
  <div class="card-label">Uptime</div>
1304
1375
  <div class="card-value small-text">${l}</div>
@@ -1306,11 +1377,11 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
1306
1377
 
1307
1378
  <div class="overview-card">
1308
1379
  <div class="card-label">Complexity</div>
1309
- <div class="card-value small-text">${p}</div>
1380
+ <div class="card-value small-text">${u}</div>
1310
1381
  </div>
1311
1382
  </div>
1312
1383
  </div>
1313
- `}};customElements.get("loki-overview")||customElements.define("loki-overview",z);var ke=[{id:"pending",label:"Pending",status:"pending",color:"var(--loki-text-muted)"},{id:"in_progress",label:"In Progress",status:"in_progress",color:"var(--loki-blue)"},{id:"review",label:"In Review",status:"review",color:"var(--loki-purple)"},{id:"done",label:"Completed",status:"done",color:"var(--loki-green)"}];var H=class extends c{static get observedAttributes(){return["api-url","project-id","theme","readonly"]}constructor(){super(),this._tasks=[],this._loading=!0,this._error=null,this._draggedTask=null,this._api=null,this._state=C()}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadTasks()}disconnectedCallback(){super.disconnectedCallback(),this._api&&(this._api.removeEventListener(n.TASK_CREATED,this._onTaskEvent),this._api.removeEventListener(n.TASK_UPDATED,this._onTaskEvent),this._api.removeEventListener(n.TASK_DELETED,this._onTaskEvent))}attributeChangedCallback(e,t,a){t!==a&&(e==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadTasks()),e==="project-id"&&this._loadTasks(),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=u({baseUrl:e}),this._onTaskEvent=()=>this._loadTasks(),this._api.addEventListener(n.TASK_CREATED,this._onTaskEvent),this._api.addEventListener(n.TASK_UPDATED,this._onTaskEvent),this._api.addEventListener(n.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 a=this._state.get("localTasks")||[];a.length>0&&(this._tasks=[...this._tasks,...a.map(i=>({...i,isLocal:!0}))]),this._state.update({"cache.tasks":this._tasks},!1)}catch(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._tasks.filter(t=>t.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 a=this._draggedTask.id,i=this._tasks.find(r=>r.id===a);if(!i)return;let s=i.status;if(s!==t){i.status=t,this.render();try{i.isLocal?this._state.moveLocalTask(a,t):await this._api.moveTask(a,t,0),this.dispatchEvent(new CustomEvent("task-moved",{detail:{taskId:a,oldStatus:s,newStatus:t}}))}catch(r){i.status=s,this.render(),console.error("Failed to move task:",r)}}}_openAddTaskModal(e="pending"){this.dispatchEvent(new CustomEvent("add-task",{detail:{status:e}}))}_openTaskDetail(e){this.dispatchEvent(new CustomEvent("task-click",{detail:{task:e}}))}render(){let e=`
1384
+ `}};customElements.get("loki-overview")||customElements.define("loki-overview",H);var xt=[{id:"pending",label:"Pending",status:"pending",color:"var(--loki-text-muted)"},{id:"in_progress",label:"In Progress",status:"in_progress",color:"var(--loki-blue)"},{id:"review",label:"In Review",status:"review",color:"var(--loki-purple)"},{id:"done",label:"Completed",status:"done",color:"var(--loki-green)"}];var z=class extends c{static get observedAttributes(){return["api-url","project-id","theme","readonly"]}constructor(){super(),this._tasks=[],this._loading=!0,this._error=null,this._draggedTask=null,this._api=null,this._state=C()}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadTasks()}disconnectedCallback(){super.disconnectedCallback(),this._api&&(this._api.removeEventListener(n.TASK_CREATED,this._onTaskEvent),this._api.removeEventListener(n.TASK_UPDATED,this._onTaskEvent),this._api.removeEventListener(n.TASK_DELETED,this._onTaskEvent))}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadTasks()),t==="project-id"&&this._loadTasks(),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=p({baseUrl:t}),this._onTaskEvent&&(this._api.removeEventListener(n.TASK_CREATED,this._onTaskEvent),this._api.removeEventListener(n.TASK_UPDATED,this._onTaskEvent),this._api.removeEventListener(n.TASK_DELETED,this._onTaskEvent)),this._onTaskEvent=()=>this._loadTasks(),this._api.addEventListener(n.TASK_CREATED,this._onTaskEvent),this._api.addEventListener(n.TASK_UPDATED,this._onTaskEvent),this._api.addEventListener(n.TASK_DELETED,this._onTaskEvent)}async _loadTasks(){this._loading=!0,this._error=null,this.render();try{let t=this.getAttribute("project-id"),e=t?{projectId:parseInt(t)}:{};this._tasks=await this._api.listTasks(e);let a=this._state.get("localTasks")||[];a.length>0&&(this._tasks=[...this._tasks,...a.map(i=>({...i,isLocal:!0}))]),this._state.update({"cache.tasks":this._tasks},!1)}catch(t){this._error=t.message,this._tasks=(this._state.get("localTasks")||[]).map(e=>({...e,isLocal:!0}))}this._loading=!1,this.render()}_getTasksByStatus(t){return this._tasks.filter(e=>e.status?.toLowerCase().replace(/-/g,"_")===t)}_handleDragStart(t,e){this.hasAttribute("readonly")||(this._draggedTask=e,t.target.classList.add("dragging"),t.dataTransfer.effectAllowed="move",t.dataTransfer.setData("text/plain",e.id.toString()))}_handleDragEnd(t){t.target.classList.remove("dragging"),this._draggedTask=null,this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(e=>{e.classList.remove("drag-over")})}_handleDragOver(t){t.preventDefault(),t.dataTransfer.dropEffect="move"}_handleDragEnter(t){t.preventDefault(),t.currentTarget.classList.add("drag-over")}_handleDragLeave(t){t.currentTarget.contains(t.relatedTarget)||t.currentTarget.classList.remove("drag-over")}async _handleDrop(t,e){if(t.preventDefault(),t.currentTarget.classList.remove("drag-over"),!this._draggedTask||this.hasAttribute("readonly"))return;let a=this._draggedTask.id,i=this._tasks.find(r=>r.id===a);if(!i)return;let s=i.status;if(s!==e){i.status=e,this.render();try{i.isLocal?this._state.moveLocalTask(a,e):await this._api.moveTask(a,e,0),this.dispatchEvent(new CustomEvent("task-moved",{detail:{taskId:a,oldStatus:s,newStatus:e}}))}catch(r){i.status=s,this.render(),console.error("Failed to move task:",r)}}}_openAddTaskModal(t="pending"){this.dispatchEvent(new CustomEvent("add-task",{detail:{status:t}}))}_openTaskDetail(t){this.dispatchEvent(new CustomEvent("task-click",{detail:{task:t}}))}render(){let t=`
1314
1385
  <style>
1315
1386
  ${this.getBaseStyles()}
1316
1387
 
@@ -1547,14 +1618,14 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
1547
1618
  fill: none;
1548
1619
  }
1549
1620
  </style>
1550
- `,t=i=>{switch(i){case"pending":return'<circle cx="12" cy="12" r="10"/>';case"in_progress":return'<path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/>';case"review":return'<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/>';case"done":return'<path d="M22 11.08V12a10 10 0 11-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/>';default:return'<circle cx="12" cy="12" r="10"/>'}},a;if(this._loading)a='<div class="loading">Loading tasks...</div>';else if(this._error&&this._tasks.length===0)a=`<div class="error">Error: ${this._error}</div>`;else{let i=this.hasAttribute("readonly");a=`
1621
+ `,e=i=>{switch(i){case"pending":return'<circle cx="12" cy="12" r="10"/>';case"in_progress":return'<path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/>';case"review":return'<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/>';case"done":return'<path d="M22 11.08V12a10 10 0 11-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/>';default:return'<circle cx="12" cy="12" r="10"/>'}},a;if(this._loading)a='<div class="loading">Loading tasks...</div>';else if(this._error&&this._tasks.length===0)a=`<div class="error">Error: ${this._error}</div>`;else{let i=this.hasAttribute("readonly");a=`
1551
1622
  <div class="kanban-board">
1552
- ${ke.map(s=>{let r=this._getTasksByStatus(s.status);return`
1623
+ ${xt.map(s=>{let r=this._getTasksByStatus(s.status);return`
1553
1624
  <div class="kanban-column" data-status="${s.status}">
1554
1625
  <div class="kanban-column-header">
1555
1626
  <span class="kanban-column-title">
1556
1627
  <svg class="column-icon" viewBox="0 0 24 24" style="color: ${s.color}">
1557
- ${t(s.status)}
1628
+ ${e(s.status)}
1558
1629
  </svg>
1559
1630
  ${s.label}
1560
1631
  </span>
@@ -1588,7 +1659,7 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
1588
1659
  `}).join("")}
1589
1660
  </div>
1590
1661
  `}this.shadowRoot.innerHTML=`
1591
- ${e}
1662
+ ${t}
1592
1663
  <div class="board-container">
1593
1664
  <div class="board-header">
1594
1665
  <h2 class="board-title">Task Queue</h2>
@@ -1605,7 +1676,7 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
1605
1676
  </div>
1606
1677
  ${a}
1607
1678
  </div>
1608
- `,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot.getElementById("refresh-btn");e&&e.addEventListener("click",()=>this._loadTasks()),this.shadowRoot.querySelectorAll(".add-task-btn").forEach(t=>{t.addEventListener("click",()=>{this._openAddTaskModal(t.dataset.status)})}),this.shadowRoot.querySelectorAll(".task-card").forEach(t=>{let a=t.dataset.taskId,i=this._tasks.find(s=>s.id.toString()===a);i&&(t.addEventListener("click",()=>this._openTaskDetail(i)),t.addEventListener("keydown",s=>{s.key==="Enter"||s.key===" "?(s.preventDefault(),this._openTaskDetail(i)):(s.key==="ArrowDown"||s.key==="ArrowUp")&&(s.preventDefault(),this._navigateTaskCards(t,s.key==="ArrowDown"?"next":"prev"))}),t.classList.contains("draggable")&&(t.addEventListener("dragstart",s=>this._handleDragStart(s,i)),t.addEventListener("dragend",s=>this._handleDragEnd(s))))}),this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(t=>{t.addEventListener("dragover",a=>this._handleDragOver(a)),t.addEventListener("dragenter",a=>this._handleDragEnter(a)),t.addEventListener("dragleave",a=>this._handleDragLeave(a)),t.addEventListener("drop",a=>this._handleDrop(a,t.dataset.status))})}_escapeHtml(e){let t=document.createElement("div");return t.textContent=e,t.innerHTML}_navigateTaskCards(e,t){let a=Array.from(this.shadowRoot.querySelectorAll(".task-card")),i=a.indexOf(e);if(i===-1)return;let s=t==="next"?i+1:i-1;s>=0&&s<a.length&&a[s].focus()}};customElements.get("loki-task-board")||customElements.define("loki-task-board",H);var B=class extends c{static get observedAttributes(){return["api-url","theme","compact"]}constructor(){super(),this._status={mode:"offline",phase:null,iteration:null,complexity:null,connected:!1,version:null,uptime:0,activeAgents:0,pendingTasks:0},this._api=null,this._state=C(),this._statusUpdateHandler=null,this._connectedHandler=null,this._disconnectedHandler=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(n.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(n.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(n.DISCONNECTED,this._disconnectedHandler))}attributeChangedCallback(e,t,a){t!==a&&(e==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadStatus()),e==="theme"&&this._applyTheme(),e==="compact"&&this.render())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=u({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(n.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(n.CONNECTED,this._connectedHandler),this._api.addEventListener(n.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){try{let e=await this._api.getStatus();this._updateFromStatus(e)}catch{this._status.connected=!1,this._status.mode="offline",this.render()}}_updateFromStatus(e){e&&(this._status={...this._status,connected:!0,mode:e.status||"running",version:e.version,uptime:e.uptime_seconds||0,activeAgents:e.running_agents||0,pendingTasks:e.pending_tasks||0,phase:e.phase,iteration:e.iteration,complexity:e.complexity},this._state.updateSession({connected:!0,mode:this._status.mode,lastSync:new Date().toISOString()}),this.render())}_startPolling(){this._ownPollInterval=setInterval(async()=>{try{let e=await this._api.getStatus();this._updateFromStatus(e)}catch{this._status.connected=!1,this._status.mode="offline",this.render()}},3e3)}_stopPolling(){this._ownPollInterval&&(clearInterval(this._ownPollInterval),this._ownPollInterval=null)}_formatUptime(e){if(!e||e<0)return"--";let t=Math.floor(e/3600),a=Math.floor(e%3600/60),i=Math.floor(e%60);return t>0?`${t}h ${a}m`:a>0?`${a}m ${i}s`:`${i}s`}_getStatusClass(){switch(this._status.mode){case"running":case"autonomous":return"active";case"paused":return"paused";case"stopped":return"stopped";case"error":return"error";default:return"offline"}}_getStatusLabel(){switch(this._status.mode){case"running":case"autonomous":return"AUTONOMOUS";case"paused":return"PAUSED";case"stopped":return"STOPPED";case"error":return"ERROR";default:return"OFFLINE"}}_triggerStart(){this.dispatchEvent(new CustomEvent("session-start",{detail:this._status}))}async _triggerPause(){try{await this._api.pauseSession(),this._status.mode="paused",this.render()}catch(e){console.error("Failed to pause session:",e)}this.dispatchEvent(new CustomEvent("session-pause",{detail:this._status}))}async _triggerResume(){try{await this._api.resumeSession(),this._status.mode="running",this.render()}catch(e){console.error("Failed to resume session:",e)}this.dispatchEvent(new CustomEvent("session-resume",{detail:this._status}))}async _triggerStop(){try{await this._api.stopSession(),this._status.mode="stopped",this.render()}catch(e){console.error("Failed to stop session:",e)}this.dispatchEvent(new CustomEvent("session-stop",{detail:this._status}))}render(){let e=this.hasAttribute("compact"),t=this._getStatusClass(),a=this._getStatusLabel(),i=["running","autonomous"].includes(this._status.mode),s=this._status.mode==="paused",r=`
1679
+ `,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("refresh-btn");t&&t.addEventListener("click",()=>this._loadTasks()),this.shadowRoot.querySelectorAll(".add-task-btn").forEach(e=>{e.addEventListener("click",()=>{this._openAddTaskModal(e.dataset.status)})}),this.shadowRoot.querySelectorAll(".task-card").forEach(e=>{let a=e.dataset.taskId,i=this._tasks.find(s=>s.id.toString()===a);i&&(e.addEventListener("click",()=>this._openTaskDetail(i)),e.addEventListener("keydown",s=>{s.key==="Enter"||s.key===" "?(s.preventDefault(),this._openTaskDetail(i)):(s.key==="ArrowDown"||s.key==="ArrowUp")&&(s.preventDefault(),this._navigateTaskCards(e,s.key==="ArrowDown"?"next":"prev"))}),e.classList.contains("draggable")&&(e.addEventListener("dragstart",s=>this._handleDragStart(s,i)),e.addEventListener("dragend",s=>this._handleDragEnd(s))))}),this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(e=>{e.addEventListener("dragover",a=>this._handleDragOver(a)),e.addEventListener("dragenter",a=>this._handleDragEnter(a)),e.addEventListener("dragleave",a=>this._handleDragLeave(a)),e.addEventListener("drop",a=>this._handleDrop(a,e.dataset.status))})}_escapeHtml(t){let e=document.createElement("div");return e.textContent=t,e.innerHTML}_navigateTaskCards(t,e){let a=Array.from(this.shadowRoot.querySelectorAll(".task-card")),i=a.indexOf(t);if(i===-1)return;let s=e==="next"?i+1:i-1;s>=0&&s<a.length&&a[s].focus()}};customElements.get("loki-task-board")||customElements.define("loki-task-board",z);var B=class extends c{static get observedAttributes(){return["api-url","theme","compact"]}constructor(){super(),this._status={mode:"offline",phase:null,iteration:null,complexity:null,connected:!1,version:null,uptime:0,activeAgents:0,pendingTasks:0},this._api=null,this._state=C(),this._statusUpdateHandler=null,this._connectedHandler=null,this._disconnectedHandler=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(n.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(n.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(n.DISCONNECTED,this._disconnectedHandler))}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadStatus()),t==="theme"&&this._applyTheme(),t==="compact"&&this.render())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=p({baseUrl:t}),this._statusUpdateHandler=e=>this._updateFromStatus(e.detail),this._connectedHandler=()=>{this._status.connected=!0,this.render()},this._disconnectedHandler=()=>{this._status.connected=!1,this._status.mode="offline",this.render()},this._api.addEventListener(n.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(n.CONNECTED,this._connectedHandler),this._api.addEventListener(n.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){try{let t=await this._api.getStatus();this._updateFromStatus(t)}catch{this._status.connected=!1,this._status.mode="offline",this.render()}}_updateFromStatus(t){t&&(this._status={...this._status,connected:!0,mode:t.status||"running",version:t.version,uptime:t.uptime_seconds||0,activeAgents:t.running_agents||0,pendingTasks:t.pending_tasks||0,phase:t.phase,iteration:t.iteration,complexity:t.complexity},this._state.updateSession({connected:!0,mode:this._status.mode,lastSync:new Date().toISOString()}),this.render())}_startPolling(){this._ownPollInterval=setInterval(async()=>{try{let t=await this._api.getStatus();this._updateFromStatus(t)}catch{this._status.connected=!1,this._status.mode="offline",this.render()}},3e3)}_stopPolling(){this._ownPollInterval&&(clearInterval(this._ownPollInterval),this._ownPollInterval=null)}_formatUptime(t){if(!t||t<0)return"--";let e=Math.floor(t/3600),a=Math.floor(t%3600/60),i=Math.floor(t%60);return e>0?`${e}h ${a}m`:a>0?`${a}m ${i}s`:`${i}s`}_getStatusClass(){switch(this._status.mode){case"running":case"autonomous":return"active";case"paused":return"paused";case"stopped":return"stopped";case"error":return"error";default:return"offline"}}_getStatusLabel(){switch(this._status.mode){case"running":case"autonomous":return"AUTONOMOUS";case"paused":return"PAUSED";case"stopped":return"STOPPED";case"error":return"ERROR";default:return"OFFLINE"}}_triggerStart(){this.dispatchEvent(new CustomEvent("session-start",{detail:this._status}))}async _triggerPause(){try{await this._api.pauseSession(),this._status.mode="paused",this.render()}catch(t){console.error("Failed to pause session:",t)}this.dispatchEvent(new CustomEvent("session-pause",{detail:this._status}))}async _triggerResume(){try{await this._api.resumeSession(),this._status.mode="running",this.render()}catch(t){console.error("Failed to resume session:",t)}this.dispatchEvent(new CustomEvent("session-resume",{detail:this._status}))}async _triggerStop(){try{await this._api.stopSession(),this._status.mode="stopped",this.render()}catch(t){console.error("Failed to stop session:",t)}this.dispatchEvent(new CustomEvent("session-stop",{detail:this._status}))}render(){let t=this.hasAttribute("compact"),e=this._getStatusClass(),a=this._getStatusLabel(),i=["running","autonomous"].includes(this._status.mode),s=this._status.mode==="paused",r=`
1609
1680
  <style>
1610
1681
  ${this.getBaseStyles()}
1611
1682
 
@@ -1792,7 +1863,7 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
1792
1863
  <div class="control-panel compact">
1793
1864
  <div class="status-row">
1794
1865
  <span class="status-value">
1795
- <span class="status-dot ${t}"></span>
1866
+ <span class="status-dot ${e}"></span>
1796
1867
  ${a}
1797
1868
  </span>
1798
1869
  </div>
@@ -1821,7 +1892,7 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
1821
1892
  <div class="status-row">
1822
1893
  <span class="status-label">Mode</span>
1823
1894
  <span class="status-value">
1824
- <span class="status-dot ${t}"></span>
1895
+ <span class="status-dot ${e}"></span>
1825
1896
  ${a}
1826
1897
  </span>
1827
1898
  </div>
@@ -1883,16 +1954,16 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
1883
1954
  </div>
1884
1955
  `;this.shadowRoot.innerHTML=`
1885
1956
  ${r}
1886
- ${e?o:l}
1887
- `,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot.getElementById("pause-btn"),t=this.shadowRoot.getElementById("resume-btn"),a=this.shadowRoot.getElementById("stop-btn"),i=this.shadowRoot.getElementById("start-btn");e&&e.addEventListener("click",()=>this._triggerPause()),t&&t.addEventListener("click",()=>this._triggerResume()),a&&a.addEventListener("click",()=>this._triggerStop()),i&&i.addEventListener("click",()=>this._triggerStart())}};customElements.get("loki-session-control")||customElements.define("loki-session-control",B);var oe={info:{color:"var(--loki-blue)",label:"INFO"},success:{color:"var(--loki-green)",label:"SUCCESS"},warning:{color:"var(--loki-yellow)",label:"WARN"},error:{color:"var(--loki-red)",label:"ERROR"},step:{color:"var(--loki-purple)",label:"STEP"},agent:{color:"var(--loki-accent)",label:"AGENT"},debug:{color:"var(--loki-text-muted)",label:"DEBUG"}},U=class extends c{static get observedAttributes(){return["api-url","max-lines","auto-scroll","theme","log-file"]}constructor(){super(),this._logs=[],this._maxLines=500,this._autoScroll=!0,this._filter="",this._levelFilter="all",this._api=null,this._pollInterval=null,this._logMessageHandler=null}connectedCallback(){super.connectedCallback(),this._maxLines=parseInt(this.getAttribute("max-lines"))||500,this._autoScroll=this.hasAttribute("auto-scroll"),this._setupApi(),this._startLogPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopLogPolling(),this._api&&this._logMessageHandler&&this._api.removeEventListener(n.LOG_MESSAGE,this._logMessageHandler)}attributeChangedCallback(e,t,a){if(t!==a)switch(e){case"api-url":this._api&&(this._api.baseUrl=a);break;case"max-lines":this._maxLines=parseInt(a)||500,this._trimLogs(),this.render();break;case"auto-scroll":this._autoScroll=this.hasAttribute("auto-scroll"),this.render();break;case"theme":this._applyTheme();break}}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=u({baseUrl:e}),this._logMessageHandler=t=>this._addLog(t.detail),this._api.addEventListener(n.LOG_MESSAGE,this._logMessageHandler)}_startLogPolling(){let e=this.getAttribute("log-file");e?this._pollLogFile(e):this._pollApiLogs()}async _pollApiLogs(){let e=0,t=async()=>{try{let a=await this._api.getLogs(200);if(Array.isArray(a)&&a.length>e){let i=a.slice(e);for(let s of i)s.message&&s.message.trim()&&this._addLog({message:s.message,level:s.level||"info",timestamp:s.timestamp||new Date().toLocaleTimeString()});e=a.length}}catch{}};t(),this._apiPollInterval=setInterval(t,2e3)}async _pollLogFile(e){let t=0,a=async()=>{try{let i=await fetch(`${e}?t=${Date.now()}`);if(!i.ok)return;let r=(await i.text()).split(`
1888
- `);if(r.length>t){let o=r.slice(t);for(let l of o)l.trim()&&this._addLog(this._parseLine(l));t=r.length}}catch{}};a(),this._pollInterval=setInterval(a,1e3)}_stopLogPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._apiPollInterval&&(clearInterval(this._apiPollInterval),this._apiPollInterval=null)}_parseLine(e){let t=e.match(/^\[([^\]]+)\]\s*\[([^\]]+)\]\s*(.+)$/);if(t)return{timestamp:t[1],level:t[2].toLowerCase(),message:t[3]};let a=e.match(/^(\d{2}:\d{2}:\d{2})\s+(\w+)\s+(.+)$/);return a?{timestamp:a[1],level:a[2].toLowerCase(),message:a[3]}:{timestamp:new Date().toLocaleTimeString(),level:"info",message: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(`
1889
- `),t=new Blob([e],{type:"text/plain"}),a=URL.createObjectURL(t),i=document.createElement("a");i.href=a,i.download=`loki-logs-${new Date().toISOString().split("T")[0]}.txt`,i.click(),URL.revokeObjectURL(a)}_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(a=>{let i=oe[a.level]||oe.info;return`
1957
+ ${t?o:l}
1958
+ `,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("pause-btn"),e=this.shadowRoot.getElementById("resume-btn"),a=this.shadowRoot.getElementById("stop-btn"),i=this.shadowRoot.getElementById("start-btn");t&&t.addEventListener("click",()=>this._triggerPause()),e&&e.addEventListener("click",()=>this._triggerResume()),a&&a.addEventListener("click",()=>this._triggerStop()),i&&i.addEventListener("click",()=>this._triggerStart())}};customElements.get("loki-session-control")||customElements.define("loki-session-control",B);var lt={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"}},U=class extends c{static get observedAttributes(){return["api-url","max-lines","auto-scroll","theme","log-file"]}constructor(){super(),this._logs=[],this._maxLines=500,this._autoScroll=!0,this._filter="",this._levelFilter="all",this._api=null,this._pollInterval=null,this._logMessageHandler=null}connectedCallback(){super.connectedCallback(),this._maxLines=parseInt(this.getAttribute("max-lines"))||500,this._autoScroll=this.hasAttribute("auto-scroll"),this._setupApi(),this._startLogPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopLogPolling(),this._api&&this._logMessageHandler&&this._api.removeEventListener(n.LOG_MESSAGE,this._logMessageHandler)}attributeChangedCallback(t,e,a){if(e!==a)switch(t){case"api-url":this._api&&(this._api.baseUrl=a);break;case"max-lines":this._maxLines=parseInt(a)||500,this._trimLogs(),this.render();break;case"auto-scroll":this._autoScroll=this.hasAttribute("auto-scroll"),this.render();break;case"theme":this._applyTheme();break}}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=p({baseUrl:t}),this._logMessageHandler=e=>this._addLog(e.detail),this._api.addEventListener(n.LOG_MESSAGE,this._logMessageHandler)}_startLogPolling(){let t=this.getAttribute("log-file");t?this._pollLogFile(t):this._pollApiLogs()}async _pollApiLogs(){let t=0,e=async()=>{try{let a=await this._api.getLogs(200);if(Array.isArray(a)&&a.length>t){let i=a.slice(t);for(let s of i)s.message&&s.message.trim()&&this._addLog({message:s.message,level:s.level||"info",timestamp:s.timestamp||new Date().toLocaleTimeString()});t=a.length}}catch{}};e(),this._apiPollInterval=setInterval(e,2e3)}async _pollLogFile(t){let e=0,a=async()=>{try{let i=await fetch(`${t}?t=${Date.now()}`);if(!i.ok)return;let r=(await i.text()).split(`
1959
+ `);if(r.length>e){let o=r.slice(e);for(let l of o)l.trim()&&this._addLog(this._parseLine(l));e=r.length}}catch{}};a(),this._pollInterval=setInterval(a,1e3)}_stopLogPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._apiPollInterval&&(clearInterval(this._apiPollInterval),this._apiPollInterval=null)}_parseLine(t){let e=t.match(/^\[([^\]]+)\]\s*\[([^\]]+)\]\s*(.+)$/);if(e)return{timestamp:e[1],level:e[2].toLowerCase(),message:e[3]};let a=t.match(/^(\d{2}:\d{2}:\d{2})\s+(\w+)\s+(.+)$/);return a?{timestamp:a[1],level:a[2].toLowerCase(),message:a[3]}:{timestamp:new Date().toLocaleTimeString(),level:"info",message:t}}_addLog(t){if(!t)return;let e={id:Date.now()+Math.random(),timestamp:t.timestamp||new Date().toLocaleTimeString(),level:(t.level||"info").toLowerCase(),message:t.message||t};this._logs.push(e),this._trimLogs(),this.dispatchEvent(new CustomEvent("log-received",{detail:e})),this._renderLogs(),this._autoScroll&&this._scrollToBottom()}_trimLogs(){this._logs.length>this._maxLines&&(this._logs=this._logs.slice(-this._maxLines))}_clearLogs(){this._logs=[],this.dispatchEvent(new CustomEvent("logs-cleared")),this._renderLogs()}_toggleAutoScroll(){this._autoScroll=!this._autoScroll,this.render(),this._autoScroll&&this._scrollToBottom()}_scrollToBottom(){requestAnimationFrame(()=>{let t=this.shadowRoot.getElementById("log-output");t&&(t.scrollTop=t.scrollHeight)})}_downloadLogs(){let t=this._logs.map(s=>`[${s.timestamp}] [${s.level.toUpperCase()}] ${s.message}`).join(`
1960
+ `),e=new Blob([t],{type:"text/plain"}),a=URL.createObjectURL(e),i=document.createElement("a");i.href=a,i.download=`loki-logs-${new Date().toISOString().split("T")[0]}.txt`,i.click(),URL.revokeObjectURL(a)}_setFilter(t){this._filter=t.toLowerCase(),this._renderLogs()}_setLevelFilter(t){this._levelFilter=t,this._renderLogs()}_getFilteredLogs(){return this._logs.filter(t=>!(this._levelFilter!=="all"&&t.level!==this._levelFilter||this._filter&&!t.message.toLowerCase().includes(this._filter)))}_renderLogs(){let t=this.shadowRoot.getElementById("log-output");if(!t)return;let e=this._getFilteredLogs();if(e.length===0){t.innerHTML='<div class="log-empty">No log output yet. Terminal will update when Loki Mode is running.</div>';return}t.innerHTML=e.map(a=>{let i=lt[a.level]||lt.info;return`
1890
1961
  <div class="log-line">
1891
1962
  <span class="timestamp">${this._escapeHtml(a.timestamp)}</span>
1892
1963
  <span class="level" style="color: ${i.color}">[${this._escapeHtml(i.label)}]</span>
1893
1964
  <span class="message">${this._escapeHtml(a.message)}</span>
1894
1965
  </div>
1895
- `}).join(""),this._autoScroll&&this._scrollToBottom()}_escapeHtml(e){let t=document.createElement("div");return t.textContent=e,t.innerHTML}render(){let e=`
1966
+ `}).join(""),this._autoScroll&&this._scrollToBottom()}_escapeHtml(t){let e=document.createElement("div");return e.textContent=t,e.innerHTML}render(){let t=`
1896
1967
  <style>
1897
1968
  ${this.getBaseStyles()}
1898
1969
 
@@ -2050,7 +2121,7 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
2050
2121
  .log-output::-webkit-scrollbar-thumb:hover { background: var(--loki-text-muted); }
2051
2122
  </style>
2052
2123
  `;this.shadowRoot.innerHTML=`
2053
- ${e}
2124
+ ${t}
2054
2125
  <div class="terminal-container">
2055
2126
  <div class="terminal-header">
2056
2127
  <div class="terminal-title">
@@ -2085,36 +2156,36 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
2085
2156
  ${this._logs.length} lines (${this._getFilteredLogs().length} shown)
2086
2157
  </div>
2087
2158
  </div>
2088
- `,this._attachEventListeners(),this._renderLogs()}_attachEventListeners(){let e=this.shadowRoot.getElementById("filter-input"),t=this.shadowRoot.getElementById("level-select"),a=this.shadowRoot.getElementById("auto-scroll-btn"),i=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))),a&&a.addEventListener("click",()=>this._toggleAutoScroll()),i&&i.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",U);var fe=[{id:"summary",label:"Summary",icon:"M4 6h16M4 12h16M4 18h16"},{id:"episodes",label:"Episodes",icon:"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"},{id:"patterns",label:"Patterns",icon:"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"},{id:"skills",label:"Skills",icon:"M13 10V3L4 14h7v7l9-11h-7z"}],j=class extends c{static get observedAttributes(){return["api-url","theme","tab"]}constructor(){super(),this._activeTab="summary",this._loading=!1,this._error=null,this._api=null,this._summary=null,this._episodes=[],this._patterns=[],this._skills=[],this._tokenEconomics=null,this._selectedItem=null,this._lastFocusedElement=null}connectedCallback(){super.connectedCallback(),this._activeTab=this.getAttribute("tab")||"summary",this._setupApi(),this._loadData()}attributeChangedCallback(e,t,a){if(t!==a)switch(e){case"api-url":this._api&&(this._api.baseUrl=a,this._loadData());break;case"theme":this._applyTheme();break;case"tab":this._setTab(a);break}}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=u({baseUrl:e})}async _loadData(){this._loading=!0,this._error=null,this.render();try{this._summary=await this._api.getMemorySummary().catch(()=>null),this._tokenEconomics=await this._api.getTokenEconomics().catch(()=>null),await this._loadTabData()}catch(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:
2089
- - Patterns created: ${e.patternsCreated}
2090
- - Patterns merged: ${e.patternsMerged}
2091
- - Episodes processed: ${e.episodesProcessed}`),this._loadData()}catch(e){alert("Consolidation failed: "+e.message)}}_renderSummary(){if(!this._summary)return'<div class="empty-state">No memory data available</div>';let{episodic:e,semantic:t,procedural:a,tokenEconomics:i}=this._summary;return`
2159
+ `,this._attachEventListeners(),this._renderLogs()}_attachEventListeners(){let t=this.shadowRoot.getElementById("filter-input"),e=this.shadowRoot.getElementById("level-select"),a=this.shadowRoot.getElementById("auto-scroll-btn"),i=this.shadowRoot.getElementById("clear-btn"),s=this.shadowRoot.getElementById("download-btn");t&&(t.value=this._filter,t.addEventListener("input",r=>this._setFilter(r.target.value))),e&&(e.value=this._levelFilter,e.addEventListener("change",r=>this._setLevelFilter(r.target.value))),a&&a.addEventListener("click",()=>this._toggleAutoScroll()),i&&i.addEventListener("click",()=>this._clearLogs()),s&&s.addEventListener("click",()=>this._downloadLogs())}addLog(t,e="info"){this._addLog({message:t,level:e,timestamp:new Date().toLocaleTimeString()})}clear(){this._clearLogs()}};customElements.get("loki-log-stream")||customElements.define("loki-log-stream",U);var yt=[{id:"summary",label:"Summary",icon:"M4 6h16M4 12h16M4 18h16"},{id:"episodes",label:"Episodes",icon:"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"},{id:"patterns",label:"Patterns",icon:"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"},{id:"skills",label:"Skills",icon:"M13 10V3L4 14h7v7l9-11h-7z"}],j=class extends c{static get observedAttributes(){return["api-url","theme","tab"]}constructor(){super(),this._activeTab="summary",this._loading=!1,this._error=null,this._api=null,this._summary=null,this._episodes=[],this._patterns=[],this._skills=[],this._tokenEconomics=null,this._selectedItem=null,this._lastFocusedElement=null}connectedCallback(){super.connectedCallback(),this._activeTab=this.getAttribute("tab")||"summary",this._setupApi(),this._loadData()}attributeChangedCallback(t,e,a){if(e!==a)switch(t){case"api-url":this._api&&(this._api.baseUrl=a,this._loadData());break;case"theme":this._applyTheme();break;case"tab":this._setTab(a);break}}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=p({baseUrl:t})}async _loadData(){this._loading=!0,this._error=null,this.render();try{this._summary=await this._api.getMemorySummary().catch(()=>null),this._tokenEconomics=await this._api.getTokenEconomics().catch(()=>null),await this._loadTabData()}catch(t){this._error=t.message||"Failed to load memory data"}this._loading=!1,this.render()}async _loadTabData(){switch(this._activeTab){case"episodes":this._episodes=await this._api.listEpisodes({limit:50}).catch(()=>[]);break;case"patterns":this._patterns=await this._api.listPatterns().catch(()=>[]);break;case"skills":this._skills=await this._api.listSkills().catch(()=>[]);break}}_setTab(t){this._activeTab!==t&&(this._activeTab=t,this._selectedItem=null,this._loadTabData().then(()=>this.render()))}async _selectEpisode(t){try{this._lastFocusedElement=this.shadowRoot.activeElement,this._selectedItem=await this._api.getEpisode(t),this.dispatchEvent(new CustomEvent("episode-select",{detail:this._selectedItem})),this.render(),this._focusDetailPanel()}catch(e){console.error("Failed to load episode:",e)}}async _selectPattern(t){try{this._lastFocusedElement=this.shadowRoot.activeElement,this._selectedItem=await this._api.getPattern(t),this.dispatchEvent(new CustomEvent("pattern-select",{detail:this._selectedItem})),this.render(),this._focusDetailPanel()}catch(e){console.error("Failed to load pattern:",e)}}async _selectSkill(t){try{this._lastFocusedElement=this.shadowRoot.activeElement,this._selectedItem=await this._api.getSkill(t),this.dispatchEvent(new CustomEvent("skill-select",{detail:this._selectedItem})),this.render(),this._focusDetailPanel()}catch(e){console.error("Failed to load skill:",e)}}_focusDetailPanel(){requestAnimationFrame(()=>{let t=this.shadowRoot.getElementById("close-detail");t&&t.focus()})}_closeDetail(){this._selectedItem=null,this.render(),this._lastFocusedElement&&requestAnimationFrame(()=>{this._lastFocusedElement.focus(),this._lastFocusedElement=null})}async _triggerConsolidation(){try{let t=await this._api.consolidateMemory(24);alert(`Consolidation complete:
2160
+ - Patterns created: ${t.patternsCreated}
2161
+ - Patterns merged: ${t.patternsMerged}
2162
+ - Episodes processed: ${t.episodesProcessed}`),this._loadData()}catch(t){alert("Consolidation failed: "+t.message)}}_renderSummary(){if(!this._summary)return'<div class="empty-state">No memory data available</div>';let{episodic:t,semantic:e,procedural:a,tokenEconomics:i}=this._summary;return`
2092
2163
  <div class="summary-grid">
2093
2164
  <div class="summary-card">
2094
2165
  <div class="summary-card-header">
2095
2166
  <span class="summary-card-title">Episodic Memory</span>
2096
- <span class="summary-card-count">${e?.count||0}</span>
2167
+ <span class="summary-card-count">${t?.count||0}</span>
2097
2168
  </div>
2098
2169
  <div class="summary-card-detail">
2099
2170
  Specific interaction traces and outcomes
2100
2171
  </div>
2101
- ${e?.latestDate?`<div class="summary-card-meta">Latest: ${new Date(e.latestDate).toLocaleDateString()}</div>`:""}
2172
+ ${t?.latestDate?`<div class="summary-card-meta">Latest: ${new Date(t.latestDate).toLocaleDateString()}</div>`:""}
2102
2173
  <div class="memory-bar">
2103
- <div class="memory-bar-fill episodic" style="width: ${Math.min((e?.count||0)/100*100,100)}%"></div>
2174
+ <div class="memory-bar-fill episodic" style="width: ${Math.min((t?.count||0)/100*100,100)}%"></div>
2104
2175
  </div>
2105
2176
  </div>
2106
2177
 
2107
2178
  <div class="summary-card">
2108
2179
  <div class="summary-card-header">
2109
2180
  <span class="summary-card-title">Semantic Memory</span>
2110
- <span class="summary-card-count">${t?.patterns||0}</span>
2181
+ <span class="summary-card-count">${e?.patterns||0}</span>
2111
2182
  </div>
2112
2183
  <div class="summary-card-detail">
2113
2184
  Generalized patterns and anti-patterns
2114
2185
  </div>
2115
- <div class="summary-card-meta">Anti-patterns: ${t?.antiPatterns||0}</div>
2186
+ <div class="summary-card-meta">Anti-patterns: ${e?.antiPatterns||0}</div>
2116
2187
  <div class="memory-bar">
2117
- <div class="memory-bar-fill semantic" style="width: ${Math.min((t?.patterns||0)/100*100,100)}%"></div>
2188
+ <div class="memory-bar-fill semantic" style="width: ${Math.min((e?.patterns||0)/100*100,100)}%"></div>
2118
2189
  </div>
2119
2190
  </div>
2120
2191
 
@@ -2173,94 +2244,94 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
2173
2244
  </div>
2174
2245
  `}_renderEpisodes(){return this._episodes.length===0?'<div class="empty-state">No episodes recorded yet</div>':`
2175
2246
  <div class="item-list" role="list" aria-label="Episodes list">
2176
- ${this._episodes.map(e=>`
2177
- <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"}">
2247
+ ${this._episodes.map(t=>`
2248
+ <div class="item-card" data-id="${t.id}" data-type="episode" tabindex="0" role="listitem" aria-label="Episode ${t.id}: ${this._escapeHtml(t.taskId||"Task")}, outcome ${t.outcome||"unknown"}">
2178
2249
  <div class="item-header">
2179
- <span class="item-id mono">${e.id}</span>
2180
- <span class="item-outcome ${e.outcome?.toLowerCase()}">${e.outcome||"unknown"}</span>
2250
+ <span class="item-id mono">${t.id}</span>
2251
+ <span class="item-outcome ${t.outcome?.toLowerCase()}">${t.outcome||"unknown"}</span>
2181
2252
  </div>
2182
- <div class="item-title">${this._escapeHtml(e.taskId||"Task")}</div>
2253
+ <div class="item-title">${this._escapeHtml(t.taskId||"Task")}</div>
2183
2254
  <div class="item-meta">
2184
- <span>${e.agent||"unknown agent"}</span>
2185
- <span>${e.phase||"unknown phase"}</span>
2186
- <span>${new Date(e.timestamp).toLocaleString()}</span>
2255
+ <span>${t.agent||"unknown agent"}</span>
2256
+ <span>${t.phase||"unknown phase"}</span>
2257
+ <span>${new Date(t.timestamp).toLocaleString()}</span>
2187
2258
  </div>
2188
2259
  </div>
2189
2260
  `).join("")}
2190
2261
  </div>
2191
2262
  `}_renderPatterns(){return this._patterns.length===0?'<div class="empty-state">No patterns discovered yet</div>':`
2192
2263
  <div class="item-list" role="list" aria-label="Patterns list">
2193
- ${this._patterns.map(e=>`
2194
- <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">
2264
+ ${this._patterns.map(t=>`
2265
+ <div class="item-card" data-id="${t.id}" data-type="pattern" tabindex="0" role="listitem" aria-label="Pattern: ${this._escapeHtml(t.pattern)}, ${(t.confidence*100).toFixed(0)} percent confidence">
2195
2266
  <div class="item-header">
2196
- <span class="item-category">${e.category||"general"}</span>
2197
- <span class="confidence-badge">${(e.confidence*100).toFixed(0)}%</span>
2267
+ <span class="item-category">${t.category||"general"}</span>
2268
+ <span class="confidence-badge">${(t.confidence*100).toFixed(0)}%</span>
2198
2269
  </div>
2199
- <div class="item-title">${this._escapeHtml(e.pattern)}</div>
2270
+ <div class="item-title">${this._escapeHtml(t.pattern)}</div>
2200
2271
  <div class="item-meta">
2201
- <span>Used ${e.usageCount||0} times</span>
2272
+ <span>Used ${t.usageCount||0} times</span>
2202
2273
  </div>
2203
2274
  </div>
2204
2275
  `).join("")}
2205
2276
  </div>
2206
2277
  `}_renderSkills(){return this._skills.length===0?'<div class="empty-state">No skills learned yet</div>':`
2207
2278
  <div class="item-list" role="list" aria-label="Skills list">
2208
- ${this._skills.map(e=>`
2209
- <div class="item-card" data-id="${e.id}" data-type="skill" tabindex="0" role="listitem" aria-label="Skill: ${this._escapeHtml(e.name)}">
2279
+ ${this._skills.map(t=>`
2280
+ <div class="item-card" data-id="${t.id}" data-type="skill" tabindex="0" role="listitem" aria-label="Skill: ${this._escapeHtml(t.name)}">
2210
2281
  <div class="item-header">
2211
- <span class="item-id mono">${e.id}</span>
2282
+ <span class="item-id mono">${t.id}</span>
2212
2283
  </div>
2213
- <div class="item-title">${this._escapeHtml(e.name)}</div>
2214
- <div class="item-description">${this._escapeHtml(e.description||"")}</div>
2284
+ <div class="item-title">${this._escapeHtml(t.name)}</div>
2285
+ <div class="item-description">${this._escapeHtml(t.description||"")}</div>
2215
2286
  </div>
2216
2287
  `).join("")}
2217
2288
  </div>
2218
- `}_renderDetail(){if(!this._selectedItem)return"";let e=this._selectedItem;return e.actionLog!==void 0?`
2289
+ `}_renderDetail(){if(!this._selectedItem)return"";let t=this._selectedItem;return t.actionLog!==void 0?`
2219
2290
  <div class="detail-panel">
2220
2291
  <div class="detail-header">
2221
- <h3>Episode: ${e.id}</h3>
2292
+ <h3>Episode: ${t.id}</h3>
2222
2293
  <button class="close-btn" id="close-detail">&times;</button>
2223
2294
  </div>
2224
2295
  <div class="detail-body">
2225
2296
  <div class="detail-row">
2226
2297
  <span class="detail-label">Task</span>
2227
- <span class="detail-value">${e.taskId||"--"}</span>
2298
+ <span class="detail-value">${t.taskId||"--"}</span>
2228
2299
  </div>
2229
2300
  <div class="detail-row">
2230
2301
  <span class="detail-label">Agent</span>
2231
- <span class="detail-value">${e.agent||"--"}</span>
2302
+ <span class="detail-value">${t.agent||"--"}</span>
2232
2303
  </div>
2233
2304
  <div class="detail-row">
2234
2305
  <span class="detail-label">Phase</span>
2235
- <span class="detail-value">${e.phase||"--"}</span>
2306
+ <span class="detail-value">${t.phase||"--"}</span>
2236
2307
  </div>
2237
2308
  <div class="detail-row">
2238
2309
  <span class="detail-label">Outcome</span>
2239
- <span class="detail-value outcome ${e.outcome?.toLowerCase()}">${e.outcome||"--"}</span>
2310
+ <span class="detail-value outcome ${t.outcome?.toLowerCase()}">${t.outcome||"--"}</span>
2240
2311
  </div>
2241
2312
  <div class="detail-row">
2242
2313
  <span class="detail-label">Duration</span>
2243
- <span class="detail-value">${e.durationSeconds||0}s</span>
2314
+ <span class="detail-value">${t.durationSeconds||0}s</span>
2244
2315
  </div>
2245
2316
  <div class="detail-row">
2246
2317
  <span class="detail-label">Tokens Used</span>
2247
- <span class="detail-value">${e.tokensUsed?.toLocaleString()||0}</span>
2318
+ <span class="detail-value">${t.tokensUsed?.toLocaleString()||0}</span>
2248
2319
  </div>
2249
- ${e.goal?`
2320
+ ${t.goal?`
2250
2321
  <div class="detail-section">
2251
2322
  <div class="detail-label">Goal</div>
2252
- <div class="detail-content">${this._escapeHtml(e.goal)}</div>
2323
+ <div class="detail-content">${this._escapeHtml(t.goal)}</div>
2253
2324
  </div>
2254
2325
  `:""}
2255
- ${e.actionLog?.length?`
2326
+ ${t.actionLog?.length?`
2256
2327
  <div class="detail-section">
2257
- <div class="detail-label">Action Log (${e.actionLog.length})</div>
2328
+ <div class="detail-label">Action Log (${t.actionLog.length})</div>
2258
2329
  <div class="action-log">
2259
- ${e.actionLog.map(t=>`
2330
+ ${t.actionLog.map(e=>`
2260
2331
  <div class="action-entry">
2261
- <span class="action-time">+${t.t}s</span>
2262
- <span class="action-type">${t.action}</span>
2263
- <span class="action-target">${this._escapeHtml(t.target)}</span>
2332
+ <span class="action-time">+${e.t}s</span>
2333
+ <span class="action-type">${e.action}</span>
2334
+ <span class="action-target">${this._escapeHtml(e.target)}</span>
2264
2335
  </div>
2265
2336
  `).join("")}
2266
2337
  </div>
@@ -2268,89 +2339,89 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
2268
2339
  `:""}
2269
2340
  </div>
2270
2341
  </div>
2271
- `:e.conditions!==void 0?`
2342
+ `:t.conditions!==void 0?`
2272
2343
  <div class="detail-panel">
2273
2344
  <div class="detail-header">
2274
- <h3>Pattern: ${e.id}</h3>
2345
+ <h3>Pattern: ${t.id}</h3>
2275
2346
  <button class="close-btn" id="close-detail">&times;</button>
2276
2347
  </div>
2277
2348
  <div class="detail-body">
2278
2349
  <div class="detail-row">
2279
2350
  <span class="detail-label">Category</span>
2280
- <span class="detail-value">${e.category||"general"}</span>
2351
+ <span class="detail-value">${t.category||"general"}</span>
2281
2352
  </div>
2282
2353
  <div class="detail-row">
2283
2354
  <span class="detail-label">Confidence</span>
2284
- <span class="detail-value">${(e.confidence*100).toFixed(0)}%</span>
2355
+ <span class="detail-value">${(t.confidence*100).toFixed(0)}%</span>
2285
2356
  </div>
2286
2357
  <div class="detail-row">
2287
2358
  <span class="detail-label">Usage Count</span>
2288
- <span class="detail-value">${e.usageCount||0}</span>
2359
+ <span class="detail-value">${t.usageCount||0}</span>
2289
2360
  </div>
2290
2361
  <div class="detail-section">
2291
2362
  <div class="detail-label">Pattern</div>
2292
- <div class="detail-content">${this._escapeHtml(e.pattern)}</div>
2363
+ <div class="detail-content">${this._escapeHtml(t.pattern)}</div>
2293
2364
  </div>
2294
- ${e.conditions?.length?`
2365
+ ${t.conditions?.length?`
2295
2366
  <div class="detail-section">
2296
2367
  <div class="detail-label">Conditions</div>
2297
2368
  <ul class="detail-list">
2298
- ${e.conditions.map(t=>`<li>${this._escapeHtml(t)}</li>`).join("")}
2369
+ ${t.conditions.map(e=>`<li>${this._escapeHtml(e)}</li>`).join("")}
2299
2370
  </ul>
2300
2371
  </div>
2301
2372
  `:""}
2302
- ${e.correctApproach?`
2373
+ ${t.correctApproach?`
2303
2374
  <div class="detail-section">
2304
2375
  <div class="detail-label">Correct Approach</div>
2305
- <div class="detail-content success">${this._escapeHtml(e.correctApproach)}</div>
2376
+ <div class="detail-content success">${this._escapeHtml(t.correctApproach)}</div>
2306
2377
  </div>
2307
2378
  `:""}
2308
- ${e.incorrectApproach?`
2379
+ ${t.incorrectApproach?`
2309
2380
  <div class="detail-section">
2310
2381
  <div class="detail-label">Incorrect Approach</div>
2311
- <div class="detail-content error">${this._escapeHtml(e.incorrectApproach)}</div>
2382
+ <div class="detail-content error">${this._escapeHtml(t.incorrectApproach)}</div>
2312
2383
  </div>
2313
2384
  `:""}
2314
2385
  </div>
2315
2386
  </div>
2316
- `:e.steps!==void 0?`
2387
+ `:t.steps!==void 0?`
2317
2388
  <div class="detail-panel">
2318
2389
  <div class="detail-header">
2319
- <h3>Skill: ${e.name}</h3>
2390
+ <h3>Skill: ${t.name}</h3>
2320
2391
  <button class="close-btn" id="close-detail">&times;</button>
2321
2392
  </div>
2322
2393
  <div class="detail-body">
2323
2394
  <div class="detail-section">
2324
2395
  <div class="detail-label">Description</div>
2325
- <div class="detail-content">${this._escapeHtml(e.description)}</div>
2396
+ <div class="detail-content">${this._escapeHtml(t.description)}</div>
2326
2397
  </div>
2327
- ${e.prerequisites?.length?`
2398
+ ${t.prerequisites?.length?`
2328
2399
  <div class="detail-section">
2329
2400
  <div class="detail-label">Prerequisites</div>
2330
2401
  <ul class="detail-list">
2331
- ${e.prerequisites.map(t=>`<li>${this._escapeHtml(t)}</li>`).join("")}
2402
+ ${t.prerequisites.map(e=>`<li>${this._escapeHtml(e)}</li>`).join("")}
2332
2403
  </ul>
2333
2404
  </div>
2334
2405
  `:""}
2335
- ${e.steps?.length?`
2406
+ ${t.steps?.length?`
2336
2407
  <div class="detail-section">
2337
2408
  <div class="detail-label">Steps</div>
2338
2409
  <ol class="detail-list numbered">
2339
- ${e.steps.map(t=>`<li>${this._escapeHtml(t)}</li>`).join("")}
2410
+ ${t.steps.map(e=>`<li>${this._escapeHtml(e)}</li>`).join("")}
2340
2411
  </ol>
2341
2412
  </div>
2342
2413
  `:""}
2343
- ${e.exitCriteria?.length?`
2414
+ ${t.exitCriteria?.length?`
2344
2415
  <div class="detail-section">
2345
2416
  <div class="detail-label">Exit Criteria</div>
2346
2417
  <ul class="detail-list">
2347
- ${e.exitCriteria.map(t=>`<li>${this._escapeHtml(t)}</li>`).join("")}
2418
+ ${t.exitCriteria.map(e=>`<li>${this._escapeHtml(e)}</li>`).join("")}
2348
2419
  </ul>
2349
2420
  </div>
2350
2421
  `:""}
2351
2422
  </div>
2352
2423
  </div>
2353
- `:""}_escapeHtml(e){if(!e)return"";let t=document.createElement("div");return t.textContent=e,t.innerHTML}render(){let e=`
2424
+ `:""}_escapeHtml(t){if(!t)return"";let e=document.createElement("div");return e.textContent=t,e.innerHTML}render(){let t=`
2354
2425
  <style>
2355
2426
  ${this.getBaseStyles()}
2356
2427
 
@@ -2751,17 +2822,17 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
2751
2822
  font-size: 12px;
2752
2823
  }
2753
2824
  </style>
2754
- `,t;if(this._loading)t='<div class="loading">Loading memory data...</div>';else if(this._error)t=`<div class="error-state">Error: ${this._error}</div>`;else{let a;switch(this._activeTab){case"summary":a=this._renderSummary();break;case"episodes":a=this._renderEpisodes();break;case"patterns":a=this._renderPatterns();break;case"skills":a=this._renderSkills();break;default:a=this._renderSummary()}t=`
2825
+ `,e;if(this._loading)e='<div class="loading">Loading memory data...</div>';else if(this._error)e=`<div class="error-state">Error: ${this._error}</div>`;else{let a;switch(this._activeTab){case"summary":a=this._renderSummary();break;case"episodes":a=this._renderEpisodes();break;case"patterns":a=this._renderPatterns();break;case"skills":a=this._renderSkills();break;default:a=this._renderSummary()}e=`
2755
2826
  <div class="content-main">${a}</div>
2756
2827
  ${this._renderDetail()}
2757
2828
  `}this.shadowRoot.innerHTML=`
2758
- ${e}
2829
+ ${t}
2759
2830
  <div class="memory-browser">
2760
2831
  <div class="browser-header">
2761
2832
  <span class="browser-title">Memory System</span>
2762
2833
  </div>
2763
2834
  <div class="tabs" role="tablist" aria-label="Memory browser sections">
2764
- ${fe.map((a,i)=>`
2835
+ ${yt.map((a,i)=>`
2765
2836
  <button class="tab ${this._activeTab===a.id?"active":""}"
2766
2837
  data-tab="${a.id}"
2767
2838
  role="tab"
@@ -2775,32 +2846,32 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
2775
2846
  `).join("")}
2776
2847
  </div>
2777
2848
  <div class="browser-content" role="tabpanel" id="tabpanel-${this._activeTab}" aria-labelledby="tab-${this._activeTab}">
2778
- ${t}
2849
+ ${e}
2779
2850
  </div>
2780
2851
  </div>
2781
- `,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot.querySelectorAll(".tab");e.forEach((s,r)=>{s.addEventListener("click",()=>this._setTab(s.dataset.tab)),s.addEventListener("keydown",o=>{if(o.key==="ArrowRight"||o.key==="ArrowLeft"){o.preventDefault();let l=Array.from(e),p=o.key==="ArrowRight"?(r+1)%l.length:(r-1+l.length)%l.length;l[p].focus(),this._setTab(l[p].dataset.tab)}})}),this.shadowRoot.querySelectorAll(".item-card").forEach(s=>{s.addEventListener("click",()=>this._handleItemClick(s)),s.addEventListener("keydown",r=>{r.key==="Enter"||r.key===" "?(r.preventDefault(),this._handleItemClick(s)):(r.key==="ArrowDown"||r.key==="ArrowUp")&&(r.preventDefault(),this._navigateItemCards(s,r.key==="ArrowDown"?"next":"prev"))})});let t=this.shadowRoot.getElementById("close-detail");t&&t.addEventListener("click",()=>this._closeDetail());let a=this.shadowRoot.getElementById("consolidate-btn");a&&a.addEventListener("click",()=>this._triggerConsolidation());let i=this.shadowRoot.getElementById("refresh-btn");i&&i.addEventListener("click",()=>this._loadData())}_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 a=Array.from(this.shadowRoot.querySelectorAll(".item-card")),i=a.indexOf(e);if(i===-1)return;let s=t==="next"?i+1:i-1;s>=0&&s<a.length&&a[s].focus()}};customElements.get("loki-memory-browser")||customElements.define("loki-memory-browser",j);var xe=[{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}],_e=[{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"}],ye=[{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"}],F=class extends c{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,a){if(t!==a)switch(e){case"api-url":this._api&&(this._api.baseUrl=a,this._loadData());break;case"theme":this._applyTheme();break;case"time-range":this._timeRange=a,this._loadData();break;case"signal-type":this._signalType=a,this._loadData();break;case"source":this._source=a,this._loadData();break}}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=u({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,a,i]=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=a,this._signals=i||[]}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`
2852
+ `,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.querySelectorAll(".tab");t.forEach((s,r)=>{s.addEventListener("click",()=>this._setTab(s.dataset.tab)),s.addEventListener("keydown",o=>{if(o.key==="ArrowRight"||o.key==="ArrowLeft"){o.preventDefault();let l=Array.from(t),u=o.key==="ArrowRight"?(r+1)%l.length:(r-1+l.length)%l.length;l[u].focus(),this._setTab(l[u].dataset.tab)}})}),this.shadowRoot.querySelectorAll(".item-card").forEach(s=>{s.addEventListener("click",()=>this._handleItemClick(s)),s.addEventListener("keydown",r=>{r.key==="Enter"||r.key===" "?(r.preventDefault(),this._handleItemClick(s)):(r.key==="ArrowDown"||r.key==="ArrowUp")&&(r.preventDefault(),this._navigateItemCards(s,r.key==="ArrowDown"?"next":"prev"))})});let e=this.shadowRoot.getElementById("close-detail");e&&e.addEventListener("click",()=>this._closeDetail());let a=this.shadowRoot.getElementById("consolidate-btn");a&&a.addEventListener("click",()=>this._triggerConsolidation());let i=this.shadowRoot.getElementById("refresh-btn");i&&i.addEventListener("click",()=>this._loadData())}_handleItemClick(t){let e=t.dataset.id;switch(t.dataset.type){case"episode":this._selectEpisode(e);break;case"pattern":this._selectPattern(e);break;case"skill":this._selectSkill(e);break}}_navigateItemCards(t,e){let a=Array.from(this.shadowRoot.querySelectorAll(".item-card")),i=a.indexOf(t);if(i===-1)return;let s=e==="next"?i+1:i-1;s>=0&&s<a.length&&a[s].focus()}};customElements.get("loki-memory-browser")||customElements.define("loki-memory-browser",j);var wt=[{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}],$t=[{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"}],Tt=[{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"}],F=class extends c{static get observedAttributes(){return["api-url","theme","time-range","signal-type","source"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._timeRange="7d",this._signalType="all",this._source="all",this._metrics=null,this._trends=null,this._signals=[],this._selectedMetric=null}connectedCallback(){super.connectedCallback(),this._timeRange=this.getAttribute("time-range")||"7d",this._signalType=this.getAttribute("signal-type")||"all",this._source=this.getAttribute("source")||"all",this._setupApi(),this._loadData()}attributeChangedCallback(t,e,a){if(e!==a)switch(t){case"api-url":this._api&&(this._api.baseUrl=a,this._loadData());break;case"theme":this._applyTheme();break;case"time-range":this._timeRange=a,this._loadData();break;case"signal-type":this._signalType=a,this._loadData();break;case"source":this._source=a,this._loadData();break}}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=p({baseUrl:t})}async _loadData(){this._loading=!0,this._error=null,this.render();try{let t={timeRange:this._timeRange,signalType:this._signalType!=="all"?this._signalType:void 0,source:this._source!=="all"?this._source:void 0},[e,a,i]=await Promise.all([this._api.getLearningMetrics(t).catch(()=>null),this._api.getLearningTrends(t).catch(()=>null),this._api.getLearningSignals({...t,limit:50}).catch(()=>[])]);this._metrics=e,this._trends=a,this._signals=i||[]}catch(t){this._error=t.message||"Failed to load learning data"}this._loading=!1,this.render()}_setFilter(t,e){switch(t){case"timeRange":this._timeRange=e,this.setAttribute("time-range",e);break;case"signalType":this._signalType=e,this.setAttribute("signal-type",e);break;case"source":this._source=e,this.setAttribute("source",e);break}this.dispatchEvent(new CustomEvent("filter-change",{detail:{timeRange:this._timeRange,signalType:this._signalType,source:this._source}})),this._loadData()}_selectMetric(t,e){this._selectedMetric={type:t,item:e},this.dispatchEvent(new CustomEvent("metric-select",{detail:{type:t,item:e}})),this.render()}_closeDetail(){this._selectedMetric=null,this.render()}_formatNumber(t){return t>=1e6?(t/1e6).toFixed(1)+"M":t>=1e3?(t/1e3).toFixed(1)+"K":t?.toString()||"0"}_formatPercent(t){return(t*100).toFixed(1)+"%"}_formatDuration(t){return t<60?t.toFixed(0)+"s":t<3600?(t/60).toFixed(1)+"m":(t/3600).toFixed(1)+"h"}_escapeHtml(t){if(!t)return"";let e=document.createElement("div");return e.textContent=t,e.innerHTML}_renderFilters(){return`
2782
2853
  <div class="filters">
2783
2854
  <div class="filter-group">
2784
2855
  <label>Time Range</label>
2785
2856
  <select id="time-range-select" class="filter-select">
2786
- ${xe.map(e=>`
2787
- <option value="${e.id}" ${this._timeRange===e.id?"selected":""}>${e.label}</option>
2857
+ ${wt.map(t=>`
2858
+ <option value="${t.id}" ${this._timeRange===t.id?"selected":""}>${t.label}</option>
2788
2859
  `).join("")}
2789
2860
  </select>
2790
2861
  </div>
2791
2862
  <div class="filter-group">
2792
2863
  <label>Signal Type</label>
2793
2864
  <select id="signal-type-select" class="filter-select">
2794
- ${_e.map(e=>`
2795
- <option value="${e.id}" ${this._signalType===e.id?"selected":""}>${e.label}</option>
2865
+ ${$t.map(t=>`
2866
+ <option value="${t.id}" ${this._signalType===t.id?"selected":""}>${t.label}</option>
2796
2867
  `).join("")}
2797
2868
  </select>
2798
2869
  </div>
2799
2870
  <div class="filter-group">
2800
2871
  <label>Source</label>
2801
2872
  <select id="source-select" class="filter-select">
2802
- ${ye.map(e=>`
2803
- <option value="${e.id}" ${this._source===e.id?"selected":""}>${e.label}</option>
2873
+ ${Tt.map(t=>`
2874
+ <option value="${t.id}" ${this._source===t.id?"selected":""}>${t.label}</option>
2804
2875
  `).join("")}
2805
2876
  </select>
2806
2877
  </div>
@@ -2812,16 +2883,16 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
2812
2883
  Refresh
2813
2884
  </button>
2814
2885
  </div>
2815
- `}_renderSummaryCards(){if(!this._metrics)return'<div class="empty-state">No metrics available</div>';let{totalSignals:e,signalsByType:t,signalsBySource:a,aggregation:i}=this._metrics;return`
2886
+ `}_renderSummaryCards(){if(!this._metrics)return'<div class="empty-state">No metrics available</div>';let{totalSignals:t,signalsByType:e,signalsBySource:a,aggregation:i}=this._metrics;return`
2816
2887
  <div class="summary-cards">
2817
2888
  <div class="summary-card">
2818
2889
  <div class="summary-card-header">
2819
2890
  <span class="summary-card-title">Total Signals</span>
2820
- <span class="summary-card-count">${this._formatNumber(e||0)}</span>
2891
+ <span class="summary-card-count">${this._formatNumber(t||0)}</span>
2821
2892
  </div>
2822
2893
  <div class="summary-card-detail">Learning signals collected</div>
2823
2894
  <div class="signal-breakdown">
2824
- ${Object.entries(t||{}).map(([s,r])=>`
2895
+ ${Object.entries(e||{}).map(([s,r])=>`
2825
2896
  <div class="breakdown-item">
2826
2897
  <span class="breakdown-label">${s.replace("_"," ")}</span>
2827
2898
  <span class="breakdown-value">${this._formatNumber(r)}</span>
@@ -2881,7 +2952,7 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
2881
2952
  </div>
2882
2953
  </div>
2883
2954
  </div>
2884
- `}_renderTrendChart(){if(!this._trends||!this._trends.dataPoints||this._trends.dataPoints.length===0)return'<div class="chart-empty">No trend data available</div>';let{dataPoints:e,maxValue:t}=this._trends,a=120,i=400,s=20,r=e.map((l,p)=>{let A=s+p/(e.length-1||1)*(i-s*2),D=a-s-l.count/(t||1)*(a-s*2);return`${A},${D}`}).join(" "),o=`${s},${a-s} ${r} ${i-s},${a-s}`;return`
2955
+ `}_renderTrendChart(){if(!this._trends||!this._trends.dataPoints||this._trends.dataPoints.length===0)return'<div class="chart-empty">No trend data available</div>';let{dataPoints:t,maxValue:e}=this._trends,a=120,i=400,s=20,r=t.map((l,u)=>{let A=s+u/(t.length-1||1)*(i-s*2),D=a-s-l.count/(e||1)*(a-s*2);return`${A},${D}`}).join(" "),o=`${s},${a-s} ${r} ${i-s},${a-s}`;return`
2885
2956
  <div class="trend-chart">
2886
2957
  <div class="chart-header">
2887
2958
  <span class="chart-title">Signal Volume Over Time</span>
@@ -2899,25 +2970,25 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
2899
2970
  <polyline points="${r}" fill="none" stroke="var(--loki-accent)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
2900
2971
 
2901
2972
  <!-- Data points -->
2902
- ${e.map((l,p)=>{let A=s+p/(e.length-1||1)*(i-s*2),D=a-s-l.count/(t||1)*(a-s*2);return`<circle cx="${A}" cy="${D}" r="3" fill="var(--loki-accent)" />`}).join("")}
2973
+ ${t.map((l,u)=>{let A=s+u/(t.length-1||1)*(i-s*2),D=a-s-l.count/(e||1)*(a-s*2);return`<circle cx="${A}" cy="${D}" r="3" fill="var(--loki-accent)" />`}).join("")}
2903
2974
  </svg>
2904
2975
  <div class="chart-labels">
2905
- ${e.length>0?`
2906
- <span class="chart-label-start">${e[0].label}</span>
2907
- <span class="chart-label-end">${e[e.length-1].label}</span>
2976
+ ${t.length>0?`
2977
+ <span class="chart-label-start">${t[0].label}</span>
2978
+ <span class="chart-label-end">${t[t.length-1].label}</span>
2908
2979
  `:""}
2909
2980
  </div>
2910
2981
  </div>
2911
- `}_renderTopLists(){if(!this._metrics?.aggregation)return"";let{preferences:e,error_patterns:t,success_patterns:a,tool_efficiencies:i}=this._metrics.aggregation;return`
2982
+ `}_renderTopLists(){if(!this._metrics?.aggregation)return"";let{preferences:t,error_patterns:e,success_patterns:a,tool_efficiencies:i}=this._metrics.aggregation;return`
2912
2983
  <div class="top-lists">
2913
2984
  <!-- User Preferences -->
2914
2985
  <div class="top-list">
2915
2986
  <div class="list-header">
2916
2987
  <span class="list-title">Top User Preferences</span>
2917
- <span class="list-count">${e?.length||0}</span>
2988
+ <span class="list-count">${t?.length||0}</span>
2918
2989
  </div>
2919
2990
  <div class="list-items" role="list">
2920
- ${(e||[]).slice(0,5).map(s=>`
2991
+ ${(t||[]).slice(0,5).map(s=>`
2921
2992
  <div class="list-item" data-type="preference" data-id="${s.preference_key}" tabindex="0" role="listitem">
2922
2993
  <div class="item-main">
2923
2994
  <span class="item-key">${this._escapeHtml(s.preference_key)}</span>
@@ -2936,10 +3007,10 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
2936
3007
  <div class="top-list">
2937
3008
  <div class="list-header">
2938
3009
  <span class="list-title">Common Error Patterns</span>
2939
- <span class="list-count">${t?.length||0}</span>
3010
+ <span class="list-count">${e?.length||0}</span>
2940
3011
  </div>
2941
3012
  <div class="list-items" role="list">
2942
- ${(t||[]).slice(0,5).map(s=>`
3013
+ ${(e||[]).slice(0,5).map(s=>`
2943
3014
  <div class="list-item error-item" data-type="error_pattern" data-id="${s.error_type}" tabindex="0" role="listitem">
2944
3015
  <div class="item-main">
2945
3016
  <span class="item-key">${this._escapeHtml(s.error_type)}</span>
@@ -3006,7 +3077,7 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
3006
3077
  <span class="signals-count">${this._signals.length}</span>
3007
3078
  </div>
3008
3079
  <div class="signals-list">
3009
- ${this._signals.slice(0,10).map(e=>{let t=e.data||{},a=e.type||"unknown",i=t.action||e.action||a,s=t.source||e.source||"-",r=t.outcome||e.outcome||"-",o=e.timestamp?new Date(e.timestamp).toLocaleTimeString():"-";return`
3080
+ ${this._signals.slice(0,10).map(t=>{let e=t.data||{},a=t.type||"unknown",i=e.action||t.action||a,s=e.source||t.source||"-",r=e.outcome||t.outcome||"-",o=t.timestamp?new Date(t.timestamp).toLocaleTimeString():"-";return`
3010
3081
  <div class="signal-item">
3011
3082
  <div class="signal-type ${a}">${a.replace("_"," ")}</div>
3012
3083
  <div class="signal-content">
@@ -3020,106 +3091,106 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
3020
3091
  </div>`}).join("")}
3021
3092
  </div>
3022
3093
  </div>
3023
- `}_renderDetailPanel(){if(!this._selectedMetric)return"";let{type:e,item:t}=this._selectedMetric,a="";switch(e){case"preference":a=`
3094
+ `}_renderDetailPanel(){if(!this._selectedMetric)return"";let{type:t,item:e}=this._selectedMetric,a="";switch(t){case"preference":a=`
3024
3095
  <div class="detail-row">
3025
3096
  <span class="detail-label">Preference Key</span>
3026
- <span class="detail-value">${this._escapeHtml(t.preference_key)}</span>
3097
+ <span class="detail-value">${this._escapeHtml(e.preference_key)}</span>
3027
3098
  </div>
3028
3099
  <div class="detail-row">
3029
3100
  <span class="detail-label">Preferred Value</span>
3030
- <span class="detail-value">${this._escapeHtml(String(t.preferred_value))}</span>
3101
+ <span class="detail-value">${this._escapeHtml(String(e.preferred_value))}</span>
3031
3102
  </div>
3032
3103
  <div class="detail-row">
3033
3104
  <span class="detail-label">Frequency</span>
3034
- <span class="detail-value">${t.frequency} occurrences</span>
3105
+ <span class="detail-value">${e.frequency} occurrences</span>
3035
3106
  </div>
3036
3107
  <div class="detail-row">
3037
3108
  <span class="detail-label">Confidence</span>
3038
- <span class="detail-value">${this._formatPercent(t.confidence)}</span>
3109
+ <span class="detail-value">${this._formatPercent(e.confidence)}</span>
3039
3110
  </div>
3040
- ${t.alternatives_rejected?.length?`
3111
+ ${e.alternatives_rejected?.length?`
3041
3112
  <div class="detail-section">
3042
3113
  <div class="detail-label">Alternatives Rejected</div>
3043
3114
  <ul class="detail-list">
3044
- ${t.alternatives_rejected.map(i=>`<li>${this._escapeHtml(i)}</li>`).join("")}
3115
+ ${e.alternatives_rejected.map(i=>`<li>${this._escapeHtml(i)}</li>`).join("")}
3045
3116
  </ul>
3046
3117
  </div>
3047
3118
  `:""}
3048
3119
  `;break;case"error_pattern":a=`
3049
3120
  <div class="detail-row">
3050
3121
  <span class="detail-label">Error Type</span>
3051
- <span class="detail-value">${this._escapeHtml(t.error_type)}</span>
3122
+ <span class="detail-value">${this._escapeHtml(e.error_type)}</span>
3052
3123
  </div>
3053
3124
  <div class="detail-row">
3054
3125
  <span class="detail-label">Resolution Rate</span>
3055
- <span class="detail-value">${this._formatPercent(t.resolution_rate)}</span>
3126
+ <span class="detail-value">${this._formatPercent(e.resolution_rate)}</span>
3056
3127
  </div>
3057
- ${t.common_messages?.length?`
3128
+ ${e.common_messages?.length?`
3058
3129
  <div class="detail-section">
3059
3130
  <div class="detail-label">Common Messages</div>
3060
3131
  <ul class="detail-list">
3061
- ${t.common_messages.map(i=>`<li>${this._escapeHtml(i)}</li>`).join("")}
3132
+ ${e.common_messages.map(i=>`<li>${this._escapeHtml(i)}</li>`).join("")}
3062
3133
  </ul>
3063
3134
  </div>
3064
3135
  `:""}
3065
- ${t.resolutions?.length?`
3136
+ ${e.resolutions?.length?`
3066
3137
  <div class="detail-section">
3067
3138
  <div class="detail-label">Known Resolutions</div>
3068
3139
  <ul class="detail-list success">
3069
- ${t.resolutions.map(i=>`<li>${this._escapeHtml(i)}</li>`).join("")}
3140
+ ${e.resolutions.map(i=>`<li>${this._escapeHtml(i)}</li>`).join("")}
3070
3141
  </ul>
3071
3142
  </div>
3072
3143
  `:""}
3073
3144
  `;break;case"success_pattern":a=`
3074
3145
  <div class="detail-row">
3075
3146
  <span class="detail-label">Pattern Name</span>
3076
- <span class="detail-value">${this._escapeHtml(t.pattern_name)}</span>
3147
+ <span class="detail-value">${this._escapeHtml(e.pattern_name)}</span>
3077
3148
  </div>
3078
3149
  <div class="detail-row">
3079
3150
  <span class="detail-label">Avg Duration</span>
3080
- <span class="detail-value">${this._formatDuration(t.avg_duration_seconds)}</span>
3151
+ <span class="detail-value">${this._formatDuration(e.avg_duration_seconds)}</span>
3081
3152
  </div>
3082
- ${t.common_actions?.length?`
3153
+ ${e.common_actions?.length?`
3083
3154
  <div class="detail-section">
3084
3155
  <div class="detail-label">Common Actions</div>
3085
3156
  <ol class="detail-list numbered">
3086
- ${t.common_actions.map(i=>`<li>${this._escapeHtml(i)}</li>`).join("")}
3157
+ ${e.common_actions.map(i=>`<li>${this._escapeHtml(i)}</li>`).join("")}
3087
3158
  </ol>
3088
3159
  </div>
3089
3160
  `:""}
3090
3161
  `;break;case"tool_efficiency":a=`
3091
3162
  <div class="detail-row">
3092
3163
  <span class="detail-label">Tool Name</span>
3093
- <span class="detail-value">${this._escapeHtml(t.tool_name)}</span>
3164
+ <span class="detail-value">${this._escapeHtml(e.tool_name)}</span>
3094
3165
  </div>
3095
3166
  <div class="detail-row">
3096
3167
  <span class="detail-label">Usage Count</span>
3097
- <span class="detail-value">${t.usage_count}</span>
3168
+ <span class="detail-value">${e.usage_count}</span>
3098
3169
  </div>
3099
3170
  <div class="detail-row">
3100
3171
  <span class="detail-label">Success Rate</span>
3101
- <span class="detail-value">${this._formatPercent(t.success_rate)}</span>
3172
+ <span class="detail-value">${this._formatPercent(e.success_rate)}</span>
3102
3173
  </div>
3103
3174
  <div class="detail-row">
3104
3175
  <span class="detail-label">Avg Execution Time</span>
3105
- <span class="detail-value">${t.avg_execution_time_ms.toFixed(0)}ms</span>
3176
+ <span class="detail-value">${e.avg_execution_time_ms.toFixed(0)}ms</span>
3106
3177
  </div>
3107
3178
  <div class="detail-row">
3108
3179
  <span class="detail-label">Total Tokens</span>
3109
- <span class="detail-value">${this._formatNumber(t.total_tokens_used)}</span>
3180
+ <span class="detail-value">${this._formatNumber(e.total_tokens_used)}</span>
3110
3181
  </div>
3111
- ${t.alternative_tools?.length?`
3182
+ ${e.alternative_tools?.length?`
3112
3183
  <div class="detail-section">
3113
3184
  <div class="detail-label">Alternative Tools</div>
3114
3185
  <div class="tag-list">
3115
- ${t.alternative_tools.map(i=>`<span class="tag">${this._escapeHtml(i)}</span>`).join("")}
3186
+ ${e.alternative_tools.map(i=>`<span class="tag">${this._escapeHtml(i)}</span>`).join("")}
3116
3187
  </div>
3117
3188
  </div>
3118
3189
  `:""}
3119
3190
  `;break}return`
3120
3191
  <div class="detail-panel">
3121
3192
  <div class="detail-header">
3122
- <h3>${e.replace("_"," ").replace(/\b\w/g,i=>i.toUpperCase())}</h3>
3193
+ <h3>${t.replace("_"," ").replace(/\b\w/g,i=>i.toUpperCase())}</h3>
3123
3194
  <button class="close-btn" id="close-detail">&times;</button>
3124
3195
  </div>
3125
3196
  <div class="detail-body">
@@ -3127,20 +3198,20 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
3127
3198
  <div class="detail-row">
3128
3199
  <span class="detail-label">Sources</span>
3129
3200
  <div class="source-tags">
3130
- ${(t.sources||[]).map(i=>`<span class="source-badge ${i}">${i}</span>`).join("")}
3201
+ ${(e.sources||[]).map(i=>`<span class="source-badge ${i}">${i}</span>`).join("")}
3131
3202
  </div>
3132
3203
  </div>
3133
3204
  <div class="detail-row">
3134
3205
  <span class="detail-label">First Seen</span>
3135
- <span class="detail-value">${t.first_seen?new Date(t.first_seen).toLocaleDateString():"--"}</span>
3206
+ <span class="detail-value">${e.first_seen?new Date(e.first_seen).toLocaleDateString():"--"}</span>
3136
3207
  </div>
3137
3208
  <div class="detail-row">
3138
3209
  <span class="detail-label">Last Seen</span>
3139
- <span class="detail-value">${t.last_seen?new Date(t.last_seen).toLocaleDateString():"--"}</span>
3210
+ <span class="detail-value">${e.last_seen?new Date(e.last_seen).toLocaleDateString():"--"}</span>
3140
3211
  </div>
3141
3212
  </div>
3142
3213
  </div>
3143
- `}render(){let e=`
3214
+ `}render(){let t=`
3144
3215
  <style>
3145
3216
  ${this.getBaseStyles()}
3146
3217
 
@@ -3764,7 +3835,7 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
3764
3835
  font-size: 12px;
3765
3836
  }
3766
3837
  </style>
3767
- `,t;this._loading?t='<div class="loading">Loading learning metrics...</div>':this._error?t=`<div class="error-state">Error: ${this._error}</div>`:t=`
3838
+ `,e;this._loading?e='<div class="loading">Loading learning metrics...</div>':this._error?e=`<div class="error-state">Error: ${this._error}</div>`:e=`
3768
3839
  <div class="content-main">
3769
3840
  ${this._renderSummaryCards()}
3770
3841
  ${this._renderTrendChart()}
@@ -3773,7 +3844,7 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
3773
3844
  </div>
3774
3845
  ${this._renderDetailPanel()}
3775
3846
  `,this.shadowRoot.innerHTML=`
3776
- ${e}
3847
+ ${t}
3777
3848
  <div class="learning-dashboard">
3778
3849
  <div class="dashboard-header">
3779
3850
  <span class="dashboard-title">
@@ -3787,10 +3858,10 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
3787
3858
  </div>
3788
3859
  ${this._renderFilters()}
3789
3860
  <div class="dashboard-content">
3790
- ${t}
3861
+ ${e}
3791
3862
  </div>
3792
3863
  </div>
3793
- `,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 a=this.shadowRoot.getElementById("source-select");a&&a.addEventListener("change",r=>this._setFilter("source",r.target.value));let i=this.shadowRoot.getElementById("refresh-btn");i&&i.addEventListener("click",()=>this._loadData());let s=this.shadowRoot.getElementById("close-detail");s&&s.addEventListener("click",()=>this._closeDetail()),this.shadowRoot.querySelectorAll(".list-item").forEach(r=>{r.addEventListener("click",()=>{let o=r.dataset.type,l=r.dataset.id,p=this._findItemData(o,l);p&&this._selectMetric(o,p)}),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(a=>a.preference_key===t);case"error_pattern":return this._metrics.aggregation.error_patterns?.find(a=>a.error_type===t);case"success_pattern":return this._metrics.aggregation.success_patterns?.find(a=>a.pattern_name===t);case"tool_efficiency":return this._metrics.aggregation.tool_efficiencies?.find(a=>a.tool_name===t);default:return null}}};customElements.get("loki-learning-dashboard")||customElements.define("loki-learning-dashboard",F);var we=[{id:"overview",label:"Overview"},{id:"decisions",label:"Decision Log"},{id:"convergence",label:"Convergence"},{id:"agents",label:"Agents"}],O=class extends c{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,a){t!==a&&(e==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=u({baseUrl:e})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),3e3),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadData(),this._pollInterval=setInterval(()=>this._loadData(),3e3))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null),this._pendingRaf&&(cancelAnimationFrame(this._pendingRaf),this._pendingRaf=null)}async _loadData(){try{let[t,a,i,s]=await Promise.allSettled([this._api._get("/api/council/state"),this._api._get("/api/council/verdicts"),this._api._get("/api/council/convergence"),this._api._get("/api/agents")]);t.status==="fulfilled"&&(this._councilState=t.value),a.status==="fulfilled"&&(this._verdicts=a.value.verdicts||[]),i.status==="fulfilled"&&(this._convergence=i.value.dataPoints||[]),s.status==="fulfilled"&&(this._agents=Array.isArray(s.value)?s.value:[]),this._error=null}catch(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=`
3864
+ `,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("time-range-select");t&&t.addEventListener("change",r=>this._setFilter("timeRange",r.target.value));let e=this.shadowRoot.getElementById("signal-type-select");e&&e.addEventListener("change",r=>this._setFilter("signalType",r.target.value));let a=this.shadowRoot.getElementById("source-select");a&&a.addEventListener("change",r=>this._setFilter("source",r.target.value));let i=this.shadowRoot.getElementById("refresh-btn");i&&i.addEventListener("click",()=>this._loadData());let s=this.shadowRoot.getElementById("close-detail");s&&s.addEventListener("click",()=>this._closeDetail()),this.shadowRoot.querySelectorAll(".list-item").forEach(r=>{r.addEventListener("click",()=>{let o=r.dataset.type,l=r.dataset.id,u=this._findItemData(o,l);u&&this._selectMetric(o,u)}),r.addEventListener("keydown",o=>{(o.key==="Enter"||o.key===" ")&&(o.preventDefault(),r.click())})})}_findItemData(t,e){if(!this._metrics?.aggregation)return null;switch(t){case"preference":return this._metrics.aggregation.preferences?.find(a=>a.preference_key===e);case"error_pattern":return this._metrics.aggregation.error_patterns?.find(a=>a.error_type===e);case"success_pattern":return this._metrics.aggregation.success_patterns?.find(a=>a.pattern_name===e);case"tool_efficiency":return this._metrics.aggregation.tool_efficiencies?.find(a=>a.tool_name===e);default:return null}}};customElements.get("loki-learning-dashboard")||customElements.define("loki-learning-dashboard",F);var Et=[{id:"overview",label:"Overview"},{id:"decisions",label:"Decision Log"},{id:"convergence",label:"Convergence"},{id:"agents",label:"Agents"}],O=class extends c{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._activeTab="overview",this._pollInterval=null,this._councilState=null,this._verdicts=[],this._convergence=[],this._agents=[],this._selectedAgent=null,this._lastDataHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=p({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),3e3),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadData(),this._pollInterval=setInterval(()=>this._loadData(),3e3))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null),this._pendingRaf&&(cancelAnimationFrame(this._pendingRaf),this._pendingRaf=null)}async _loadData(){try{let[e,a,i,s]=await Promise.allSettled([this._api._get("/api/council/state"),this._api._get("/api/council/verdicts"),this._api._get("/api/council/convergence"),this._api._get("/api/agents")]);e.status==="fulfilled"&&(this._councilState=e.value),a.status==="fulfilled"&&(this._verdicts=a.value.verdicts||[]),i.status==="fulfilled"&&(this._convergence=i.value.dataPoints||[]),s.status==="fulfilled"&&(this._agents=Array.isArray(s.value)?s.value:[]),this._error=null}catch(e){this._error=e.message}let t=JSON.stringify({s:this._councilState,v:this._verdicts,c:this._convergence,a:this._agents,e:this._error});t!==this._lastDataHash&&(this._lastDataHash=t,this.render())}async _forceReview(){try{await this._api._post("/api/council/force-review"),this.dispatchEvent(new CustomEvent("council-action",{detail:{action:"force-review"},bubbles:!0}))}catch(t){this._error=`Failed to force review: ${t.message}`,this.render()}}async _killAgent(t){if(confirm(`Kill agent ${t}?`))try{await this._api._post(`/api/agents/${t}/kill`),this.dispatchEvent(new CustomEvent("council-action",{detail:{action:"kill-agent",agentId:t},bubbles:!0})),await this._loadData()}catch(e){this._error=`Failed to kill agent: ${e.message}`,this.render()}}async _pauseAgent(t){try{await this._api._post(`/api/agents/${t}/pause`),await this._loadData()}catch(e){this._error=`Failed to pause agent: ${e.message}`,this.render()}}async _resumeAgent(t){try{await this._api._post(`/api/agents/${t}/resume`),await this._loadData()}catch(e){this._error=`Failed to resume agent: ${e.message}`,this.render()}}_setTab(t){this._activeTab=t,this.render()}_selectAgent(t){this._selectedAgent=this._selectedAgent?.id===t.id?null:t,this.render()}render(){let t=this.shadowRoot;t&&(this._pendingRaf&&(cancelAnimationFrame(this._pendingRaf),this._pendingRaf=null),t.innerHTML=`
3794
3865
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
3795
3866
  <div class="council-dashboard">
3796
3867
  <div class="council-header">
@@ -3804,11 +3875,11 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
3804
3875
  </div>
3805
3876
 
3806
3877
  <div class="tabs">
3807
- ${we.map(t=>`
3878
+ ${Et.map(e=>`
3808
3879
  <button
3809
- class="tab ${this._activeTab===t.id?"active":""}"
3810
- data-tab="${t.id}"
3811
- >${t.label}</button>
3880
+ class="tab ${this._activeTab===e.id?"active":""}"
3881
+ data-tab="${e.id}"
3882
+ >${e.label}</button>
3812
3883
  `).join("")}
3813
3884
  </div>
3814
3885
 
@@ -3818,12 +3889,12 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
3818
3889
 
3819
3890
  ${this._error?`<div class="error-banner">${this._error}</div>`:""}
3820
3891
  </div>
3821
- `,this._attachEventListeners())}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("force-review-btn");t&&t.addEventListener("click",()=>this._forceReview()),e.querySelectorAll(".tab[data-tab]").forEach(a=>{a.addEventListener("click",()=>this._setTab(a.dataset.tab))})}_renderTabContent(){switch(this._activeTab){case"overview":return this._renderOverview();case"decisions":return this._renderDecisions();case"convergence":return this._renderConvergence();case"agents":return this._renderAgents();default:return""}}_renderOverview(){let e=this._councilState||{},t=e.consecutive_no_change||0,a=e.done_signals||0,i=e.total_votes||0,s=e.approve_votes||0,r=this._verdicts.length>0?this._verdicts[this._verdicts.length-1]:null,o=this._agents.filter(l=>l.alive).length;return`
3892
+ `,this._attachEventListeners())}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.getElementById("force-review-btn");e&&e.addEventListener("click",()=>this._forceReview()),t.querySelectorAll(".tab[data-tab]").forEach(a=>{a.addEventListener("click",()=>this._setTab(a.dataset.tab))})}_renderTabContent(){switch(this._activeTab){case"overview":return this._renderOverview();case"decisions":return this._renderDecisions();case"convergence":return this._renderConvergence();case"agents":return this._renderAgents();default:return""}}_renderOverview(){let t=this._councilState||{},e=t.consecutive_no_change||0,a=t.done_signals||0,i=t.total_votes||0,s=t.approve_votes||0,r=this._verdicts.length>0?this._verdicts[this._verdicts.length-1]:null,o=this._agents.filter(l=>l.alive).length;return`
3822
3893
  <div class="overview-grid">
3823
3894
  <div class="stat-card">
3824
3895
  <div class="stat-label">Council Status</div>
3825
- <div class="stat-value ${e.enabled!==!1?"text-green":"text-muted"}">
3826
- ${e.enabled!==!1?"Monitoring":"Disabled"}
3896
+ <div class="stat-value ${t.enabled!==!1?"text-green":"text-muted"}">
3897
+ ${t.enabled!==!1?"Monitoring":"Disabled"}
3827
3898
  </div>
3828
3899
  </div>
3829
3900
  <div class="stat-card">
@@ -3833,7 +3904,7 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
3833
3904
  </div>
3834
3905
  <div class="stat-card">
3835
3906
  <div class="stat-label">Stagnation Streak</div>
3836
- <div class="stat-value ${t>=3?"text-warn":""}">${t}</div>
3907
+ <div class="stat-value ${e>=3?"text-warn":""}">${e}</div>
3837
3908
  <div class="stat-sub">consecutive no-change</div>
3838
3909
  </div>
3839
3910
  <div class="stat-card">
@@ -3863,9 +3934,9 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
3863
3934
  </div>
3864
3935
  </div>
3865
3936
  `:""}
3866
- `}_renderConvergenceBar(){let e=this._convergence.slice(-20);if(e.length===0)return'<span class="text-muted">No data</span>';let t=Math.max(...e.map(a=>a.files_changed),1);return`
3937
+ `}_renderConvergenceBar(){let t=this._convergence.slice(-20);if(t.length===0)return'<span class="text-muted">No data</span>';let e=Math.max(...t.map(a=>a.files_changed),1);return`
3867
3938
  <div class="bar-chart">
3868
- ${e.map(a=>{let i=Math.max(4,a.files_changed/t*60),s=a.no_change_streak>0;return`
3939
+ ${t.map(a=>{let i=Math.max(4,a.files_changed/e*60),s=a.no_change_streak>0;return`
3869
3940
  <div class="bar-wrapper" title="Iter ${a.iteration}: ${a.files_changed} files changed">
3870
3941
  <div class="bar ${s?"bar-stagnant":"bar-active"}" style="height: ${i}px"></div>
3871
3942
  <div class="bar-label">${a.iteration}</div>
@@ -3874,18 +3945,18 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
3874
3945
  </div>
3875
3946
  `}_renderDecisions(){return this._verdicts.length===0?`<div class="empty-state">No council decisions yet. The council convenes every ${this._councilState?.check_interval||5} iterations.</div>`:`
3876
3947
  <div class="decision-list">
3877
- ${this._verdicts.slice().reverse().map(e=>`
3878
- <div class="decision-card ${e.result==="APPROVED"?"decision-approved":"decision-rejected"}">
3948
+ ${this._verdicts.slice().reverse().map(t=>`
3949
+ <div class="decision-card ${t.result==="APPROVED"?"decision-approved":"decision-rejected"}">
3879
3950
  <div class="decision-header">
3880
- <span class="decision-result ${e.result==="APPROVED"?"text-green":"text-warn"}">
3881
- ${e.result}
3951
+ <span class="decision-result ${t.result==="APPROVED"?"text-green":"text-warn"}">
3952
+ ${t.result}
3882
3953
  </span>
3883
- <span class="decision-iter">Iteration ${e.iteration}</span>
3884
- <span class="decision-time">${this._formatTime(e.timestamp)}</span>
3954
+ <span class="decision-iter">Iteration ${t.iteration}</span>
3955
+ <span class="decision-time">${this._formatTime(t.timestamp)}</span>
3885
3956
  </div>
3886
3957
  <div class="decision-votes">
3887
- <span class="vote-approve">${e.approve} Approve</span>
3888
- <span class="vote-reject">${e.reject} Reject</span>
3958
+ <span class="vote-approve">${t.approve} Approve</span>
3959
+ <span class="vote-reject">${t.reject} Reject</span>
3889
3960
  </div>
3890
3961
  </div>
3891
3962
  `).join("")}
@@ -3911,45 +3982,45 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
3911
3982
  </tr>
3912
3983
  </thead>
3913
3984
  <tbody>
3914
- ${this._convergence.slice().reverse().map(e=>`
3915
- <tr class="${e.no_change_streak>=3?"row-warn":""}">
3916
- <td>${e.iteration}</td>
3917
- <td>${e.files_changed}</td>
3918
- <td>${e.no_change_streak}</td>
3919
- <td>${e.done_signals}</td>
3985
+ ${this._convergence.slice().reverse().map(t=>`
3986
+ <tr class="${t.no_change_streak>=3?"row-warn":""}">
3987
+ <td>${t.iteration}</td>
3988
+ <td>${t.files_changed}</td>
3989
+ <td>${t.no_change_streak}</td>
3990
+ <td>${t.done_signals}</td>
3920
3991
  </tr>
3921
3992
  `).join("")}
3922
3993
  </tbody>
3923
3994
  </table>
3924
3995
  </div>
3925
3996
  </div>
3926
- `}_renderAgents(){if(this._agents.length===0)return'<div class="empty-state">No agents registered.</div>';let e=`
3997
+ `}_renderAgents(){if(this._agents.length===0)return'<div class="empty-state">No agents registered.</div>';let t=`
3927
3998
  <div class="agents-list">
3928
- ${this._agents.map((t,a)=>`
3929
- <div class="agent-card ${this._selectedAgent?.id===t.id?"agent-selected":""}"
3999
+ ${this._agents.map((e,a)=>`
4000
+ <div class="agent-card ${this._selectedAgent?.id===e.id?"agent-selected":""}"
3930
4001
  data-agent-index="${a}">
3931
4002
  <div class="agent-header">
3932
- <span class="agent-name">${t.name||t.id||"Unknown"}</span>
3933
- <span class="agent-status ${t.alive?"status-alive":"status-dead"}">
3934
- ${t.alive?"Running":"Stopped"}
4003
+ <span class="agent-name">${e.name||e.id||"Unknown"}</span>
4004
+ <span class="agent-status ${e.alive?"status-alive":"status-dead"}">
4005
+ ${e.alive?"Running":"Stopped"}
3935
4006
  </span>
3936
4007
  </div>
3937
4008
  <div class="agent-meta">
3938
- ${t.type?`<span class="agent-type">${t.type}</span>`:""}
3939
- ${t.pid?`<span class="agent-pid">PID: ${t.pid}</span>`:""}
3940
- ${t.task?`<span class="agent-task">Task: ${t.task}</span>`:""}
4009
+ ${e.type?`<span class="agent-type">${e.type}</span>`:""}
4010
+ ${e.pid?`<span class="agent-pid">PID: ${e.pid}</span>`:""}
4011
+ ${e.task?`<span class="agent-task">Task: ${e.task}</span>`:""}
3941
4012
  </div>
3942
- ${this._selectedAgent?.id===t.id?`
4013
+ ${this._selectedAgent?.id===e.id?`
3943
4014
  <div class="agent-actions">
3944
- ${t.alive?`
3945
- <button class="btn btn-sm btn-warn" data-action="pause" data-agent-id="${t.id||t.name}">
4015
+ ${e.alive?`
4016
+ <button class="btn btn-sm btn-warn" data-action="pause" data-agent-id="${e.id||e.name}">
3946
4017
  Pause
3947
4018
  </button>
3948
- <button class="btn btn-sm btn-danger" data-action="kill" data-agent-id="${t.id||t.name}">
4019
+ <button class="btn btn-sm btn-danger" data-action="kill" data-agent-id="${e.id||e.name}">
3949
4020
  Kill
3950
4021
  </button>
3951
4022
  `:`
3952
- <button class="btn btn-sm btn-primary" data-action="resume" data-agent-id="${t.id||t.name}">
4023
+ <button class="btn btn-sm btn-primary" data-action="resume" data-agent-id="${e.id||e.name}">
3953
4024
  Resume
3954
4025
  </button>
3955
4026
  `}
@@ -3958,7 +4029,7 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
3958
4029
  </div>
3959
4030
  `).join("")}
3960
4031
  </div>
3961
- `;return this._pendingRaf=requestAnimationFrame(()=>{this._pendingRaf=null;let t=this.shadowRoot;t&&t.querySelectorAll(".agent-card[data-agent-index]").forEach(a=>{let i=parseInt(a.dataset.agentIndex,10),s=this._agents[i];s&&(a.addEventListener("click",()=>this._selectAgent(s)),a.querySelectorAll("[data-action]").forEach(r=>{r.addEventListener("click",o=>{o.stopPropagation();let l=r.dataset.action,p=r.dataset.agentId;l==="pause"?this._pauseAgent(p):l==="kill"?this._killAgent(p):l==="resume"&&this._resumeAgent(p)})}))})}),e}_formatTime(e){if(!e)return"";try{return new Date(e).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}catch{return e}}_getStyles(){return`
4032
+ `;return this._pendingRaf=requestAnimationFrame(()=>{this._pendingRaf=null;let e=this.shadowRoot;e&&e.querySelectorAll(".agent-card[data-agent-index]").forEach(a=>{let i=parseInt(a.dataset.agentIndex,10),s=this._agents[i];s&&(a.addEventListener("click",()=>this._selectAgent(s)),a.querySelectorAll("[data-action]").forEach(r=>{r.addEventListener("click",o=>{o.stopPropagation();let l=r.dataset.action,u=r.dataset.agentId;l==="pause"?this._pauseAgent(u):l==="kill"?this._killAgent(u):l==="resume"&&this._resumeAgent(u)})}))})}),t}_formatTime(t){if(!t)return"";try{return new Date(t).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}catch{return t}}_getStyles(){return`
3962
4033
  :host {
3963
4034
  display: block;
3964
4035
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
@@ -4371,16 +4442,478 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
4371
4442
  color: var(--loki-error);
4372
4443
  font-size: 12px;
4373
4444
  }
4374
- `}};customElements.get("loki-council-dashboard")||customElements.define("loki-council-dashboard",O);var $e={opus:{input:5,output:25,label:"Opus 4.6",provider:"claude"},sonnet:{input:3,output:15,label:"Sonnet 4.5",provider:"claude"},haiku:{input:1,output:5,label:"Haiku 4.5",provider:"claude"},"gpt-5.3-codex":{input:1.5,output:12,label:"GPT-5.3 Codex",provider:"codex"},"gemini-3-pro":{input:1.25,output:10,label:"Gemini 3 Pro",provider:"gemini"},"gemini-3-flash":{input:.1,output:.4,label:"Gemini 3 Flash",provider:"gemini"}},ne={...$e},N=class extends c{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}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadPricing(),this._loadCost(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,a){t!==a&&(e==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadCost()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=u({baseUrl:e})}async _loadPricing(){try{let e=await this._api.getPricing();if(e&&e.models){let t={};for(let[a,i]of Object.entries(e.models))t[a]={input:i.input,output:i.output,label:i.label||a,provider:i.provider||"unknown"};ne=t,this._pricingSource=e.source||"api",this._pricingDate=e.updated||"",this._activeProvider=e.provider||"claude",this.render()}}catch{}}async _loadCost(){try{let e=await this._api.getCost();this._updateFromCost(e)}catch{this._data.connected=!1,this.render()}}_updateFromCost(e){e&&(this._data={...this._data,connected:!0,total_input_tokens:e.total_input_tokens||0,total_output_tokens:e.total_output_tokens||0,estimated_cost_usd:e.estimated_cost_usd||0,by_phase:e.by_phase||{},by_model:e.by_model||{},budget_limit:e.budget_limit,budget_used:e.budget_used||0,budget_remaining:e.budget_remaining},this.render())}_startPolling(){this._pollInterval=setInterval(async()=>{try{let e=await this._api.getCost();this._updateFromCost(e)}catch{this._data.connected=!1,this.render()}},5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=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,a])=>{let i=a.input_tokens||0,s=a.output_tokens||0,r=a.cost_usd||0;return`
4445
+ `}};customElements.get("loki-council-dashboard")||customElements.define("loki-council-dashboard",O);var dt={critical:0,major:1,minor:2},St={critical:"var(--loki-status-error, #ef4444)",major:"var(--loki-status-warning, #f59e0b)",minor:"var(--loki-text-muted, #71717a)"},N=class extends c{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._expandedCategories=new Set,this._lastDataHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=p({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),5e3),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadData(),this._pollInterval=setInterval(()=>this._loadData(),5e3))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null)}async _loadData(){try{let t=await this._api.getChecklist(),e=JSON.stringify(t?.summary);if(e===this._lastDataHash)return;this._lastDataHash=e,this._checklist=t,this._error=null,this.render()}catch(t){this._error=`Failed to load checklist: ${t.message}`,this.render()}}_toggleCategory(t){this._expandedCategories.has(t)?this._expandedCategories.delete(t):this._expandedCategories.add(t),this.render()}_getStyles(){return`
4446
+ .checklist-viewer {
4447
+ padding: 16px;
4448
+ font-family: var(--loki-font-family, system-ui, -apple-system, sans-serif);
4449
+ color: var(--loki-text-primary, #18181b);
4450
+ }
4451
+ .checklist-header {
4452
+ display: flex;
4453
+ align-items: center;
4454
+ justify-content: space-between;
4455
+ margin-bottom: 16px;
4456
+ }
4457
+ .title {
4458
+ font-size: 18px;
4459
+ font-weight: 600;
4460
+ margin: 0;
4461
+ }
4462
+ .summary-badges {
4463
+ display: flex;
4464
+ gap: 8px;
4465
+ }
4466
+ .badge {
4467
+ display: inline-flex;
4468
+ align-items: center;
4469
+ padding: 2px 8px;
4470
+ border-radius: 9999px;
4471
+ font-size: 12px;
4472
+ font-weight: 500;
4473
+ }
4474
+ .badge-verified {
4475
+ background: color-mix(in srgb, var(--loki-status-success, #22c55e) 15%, transparent);
4476
+ color: var(--loki-status-success, #22c55e);
4477
+ }
4478
+ .badge-failing {
4479
+ background: color-mix(in srgb, var(--loki-status-error, #ef4444) 15%, transparent);
4480
+ color: var(--loki-status-error, #ef4444);
4481
+ }
4482
+ .badge-pending {
4483
+ background: color-mix(in srgb, var(--loki-text-muted, #71717a) 15%, transparent);
4484
+ color: var(--loki-text-muted, #71717a);
4485
+ }
4486
+
4487
+ /* Progress bar */
4488
+ .progress-container {
4489
+ margin-bottom: 20px;
4490
+ }
4491
+ .progress-bar {
4492
+ height: 8px;
4493
+ background: var(--loki-bg-tertiary, #e4e4e7);
4494
+ border-radius: 4px;
4495
+ overflow: hidden;
4496
+ display: flex;
4497
+ }
4498
+ .progress-verified {
4499
+ background: var(--loki-status-success, #22c55e);
4500
+ transition: width 0.3s ease;
4501
+ }
4502
+ .progress-failing {
4503
+ background: var(--loki-status-error, #ef4444);
4504
+ transition: width 0.3s ease;
4505
+ }
4506
+ .progress-label {
4507
+ display: flex;
4508
+ justify-content: space-between;
4509
+ margin-top: 4px;
4510
+ font-size: 12px;
4511
+ color: var(--loki-text-secondary, #52525b);
4512
+ }
4513
+
4514
+ /* Category accordions */
4515
+ .category {
4516
+ border: 1px solid var(--loki-border, #e4e4e7);
4517
+ border-radius: 8px;
4518
+ margin-bottom: 8px;
4519
+ overflow: hidden;
4520
+ }
4521
+ .category-header {
4522
+ display: flex;
4523
+ align-items: center;
4524
+ justify-content: space-between;
4525
+ padding: 10px 14px;
4526
+ cursor: pointer;
4527
+ background: var(--loki-bg-secondary, #f4f4f5);
4528
+ user-select: none;
4529
+ transition: background 0.15s;
4530
+ }
4531
+ .category-header:hover {
4532
+ background: var(--loki-bg-hover, #f0f0f3);
4533
+ }
4534
+ .category-name {
4535
+ font-weight: 600;
4536
+ font-size: 14px;
4537
+ }
4538
+ .category-stats {
4539
+ font-size: 12px;
4540
+ color: var(--loki-text-secondary, #52525b);
4541
+ }
4542
+ .category-arrow {
4543
+ font-size: 12px;
4544
+ transition: transform 0.2s;
4545
+ }
4546
+ .category-arrow.expanded {
4547
+ transform: rotate(90deg);
4548
+ }
4549
+ .category-body {
4550
+ padding: 0;
4551
+ }
4552
+
4553
+ /* Checklist items */
4554
+ .item {
4555
+ display: flex;
4556
+ align-items: center;
4557
+ gap: 10px;
4558
+ padding: 8px 14px;
4559
+ border-top: 1px solid var(--loki-border, #e4e4e7);
4560
+ font-size: 13px;
4561
+ }
4562
+ .item-status {
4563
+ width: 10px;
4564
+ height: 10px;
4565
+ border-radius: 50%;
4566
+ flex-shrink: 0;
4567
+ }
4568
+ .status-verified {
4569
+ background: var(--loki-status-success, #22c55e);
4570
+ }
4571
+ .status-failing {
4572
+ background: var(--loki-status-error, #ef4444);
4573
+ }
4574
+ .status-pending {
4575
+ background: var(--loki-text-muted, #a1a1aa);
4576
+ }
4577
+ .item-title {
4578
+ flex: 1;
4579
+ min-width: 0;
4580
+ }
4581
+ .item-priority {
4582
+ font-size: 10px;
4583
+ font-weight: 600;
4584
+ text-transform: uppercase;
4585
+ letter-spacing: 0.5px;
4586
+ padding: 1px 6px;
4587
+ border-radius: 4px;
4588
+ flex-shrink: 0;
4589
+ }
4590
+ .verification-dots {
4591
+ display: flex;
4592
+ gap: 3px;
4593
+ flex-shrink: 0;
4594
+ }
4595
+ .v-dot {
4596
+ width: 6px;
4597
+ height: 6px;
4598
+ border-radius: 50%;
4599
+ }
4600
+ .v-dot-pass { background: var(--loki-status-success, #22c55e); }
4601
+ .v-dot-fail { background: var(--loki-status-error, #ef4444); }
4602
+ .v-dot-pending { background: var(--loki-text-muted, #a1a1aa); }
4603
+
4604
+ /* Empty state */
4605
+ .empty-state {
4606
+ text-align: center;
4607
+ padding: 48px 24px;
4608
+ color: var(--loki-text-secondary, #52525b);
4609
+ }
4610
+ .empty-state p {
4611
+ margin: 8px 0;
4612
+ font-size: 14px;
4613
+ }
4614
+ .empty-state .hint {
4615
+ font-size: 12px;
4616
+ color: var(--loki-text-muted, #71717a);
4617
+ }
4618
+
4619
+ /* Error */
4620
+ .error-banner {
4621
+ margin-top: 12px;
4622
+ padding: 8px 12px;
4623
+ background: color-mix(in srgb, var(--loki-status-error, #ef4444) 10%, transparent);
4624
+ color: var(--loki-status-error, #ef4444);
4625
+ border-radius: 6px;
4626
+ font-size: 12px;
4627
+ }
4628
+ `}render(){let t=this.shadowRoot;if(!t)return;let e=this._checklist,a=e&&e.status!=="not_initialized"&&e.categories?.length>0;t.innerHTML=`
4629
+ <style>${this.getBaseStyles()}${this._getStyles()}</style>
4630
+ <div class="checklist-viewer">
4631
+ <div class="checklist-header">
4632
+ <h2 class="title">PRD Checklist</h2>
4633
+ ${a?this._renderBadges(e.summary):""}
4634
+ </div>
4635
+ ${a?this._renderProgress(e.summary):""}
4636
+ ${a?this._renderCategories(e.categories):this._renderEmpty()}
4637
+ ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
4638
+ </div>
4639
+ `,this._attachEventListeners()}_renderBadges(t){return t?`
4640
+ <div class="summary-badges">
4641
+ ${t.verified?`<span class="badge badge-verified">${t.verified} verified</span>`:""}
4642
+ ${t.failing?`<span class="badge badge-failing">${t.failing} failing</span>`:""}
4643
+ ${t.pending?`<span class="badge badge-pending">${t.pending} pending</span>`:""}
4644
+ </div>
4645
+ `:""}_renderProgress(t){if(!t||!t.total)return"";let e=t.verified/t.total*100,a=t.failing/t.total*100;return`
4646
+ <div class="progress-container">
4647
+ <div class="progress-bar">
4648
+ <div class="progress-verified" style="width: ${e}%"></div>
4649
+ <div class="progress-failing" style="width: ${a}%"></div>
4650
+ </div>
4651
+ <div class="progress-label">
4652
+ <span>${t.verified}/${t.total} verified</span>
4653
+ <span>${Math.round(e)}%</span>
4654
+ </div>
4655
+ </div>
4656
+ `}_renderCategories(t){return t?.length?t.map(e=>{let a=this._expandedCategories.has(e.name),i=e.items||[],s=i.filter(o=>o.status==="verified").length,r=i.filter(o=>o.status==="failing").length;return`
4657
+ <div class="category">
4658
+ <div class="category-header" data-category="${this._escapeHtml(e.name)}">
4659
+ <div>
4660
+ <span class="category-name">${this._escapeHtml(e.name)}</span>
4661
+ <span class="category-stats">${s}/${i.length} verified${r?`, ${r} failing`:""}</span>
4662
+ </div>
4663
+ <span class="category-arrow ${a?"expanded":""}">&#9654;</span>
4664
+ </div>
4665
+ ${a?`<div class="category-body">${this._renderItems(i)}</div>`:""}
4666
+ </div>
4667
+ `}).join(""):this._renderEmpty()}_renderItems(t){return t?.length?[...t].sort((a,i)=>(dt[a.priority]??2)-(dt[i.priority]??2)).map(a=>{let i=a.status==="verified"?"status-verified":a.status==="failing"?"status-failing":"status-pending",s=["critical","major","minor"].includes(a.priority)?a.priority:"minor",r=St[s],o=a.verification||[];return`
4668
+ <div class="item">
4669
+ <div class="item-status ${i}"></div>
4670
+ <div class="item-title">${this._escapeHtml(a.title||a.id||"?")}</div>
4671
+ <span class="item-priority" style="color:${r};border:1px solid ${r}">${s}</span>
4672
+ <div class="verification-dots">
4673
+ ${o.map(l=>`<div class="v-dot ${l.passed===!0?"v-dot-pass":l.passed===!1?"v-dot-fail":"v-dot-pending"}" title="${this._escapeHtml(l.type||"")}"></div>`).join("")}
4674
+ </div>
4675
+ </div>
4676
+ `}).join(""):'<div class="item" style="color:var(--loki-text-muted)">No items</div>'}_renderEmpty(){return`
4677
+ <div class="empty-state">
4678
+ <p>Checklist not initialized</p>
4679
+ <p class="hint">The PRD checklist will be created during the first iteration when a PRD is provided.</p>
4680
+ </div>
4681
+ `}_attachEventListeners(){let t=this.shadowRoot;t&&t.querySelectorAll(".category-header[data-category]").forEach(e=>{e.addEventListener("click",()=>this._toggleCategory(e.dataset.category))})}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}};customElements.define("loki-checklist-viewer",N);var ct={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},crashed:{color:"var(--loki-red, #dc2626)",label:"Crashed",pulse:!1},stopped:{color:"var(--loki-text-muted, #a1a1aa)",label:"Stopped",pulse:!1}},q=class extends c{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}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=p({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),3e3),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadData(),this._pollInterval=setInterval(()=>this._loadData(),3e3))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null)}async _loadData(){try{let[t,e]=await Promise.all([this._api.getAppRunnerStatus(),this._api.getAppRunnerLogs()]),a=JSON.stringify({status:t?.status,port:t?.port,restarts:t?.restart_count,url:t?.url}),i=(e?.lines?.length||0)!==this._logs.length;if(a===this._lastDataHash&&!i)return;this._lastDataHash=a,this._status=t,this._logs=e?.lines||[],this._error=null,this.render(),this._scrollLogsToBottom()}catch(t){this._error||(this._error=`Failed to load app status: ${t.message}`,this.render())}}_scrollLogsToBottom(){let t=this.shadowRoot;if(!t)return;let e=t.querySelector(".log-area");e&&(e.scrollTop=e.scrollHeight)}async _handleRestart(){try{await this._api.restartApp(),this._loadData()}catch(t){this._error=`Restart failed: ${t.message}`,this.render()}}async _handleStop(){try{await this._api.stopApp(),this._loadData()}catch(t){this._error=`Stop failed: ${t.message}`,this.render()}}_formatUptime(t){if(!t)return"--";let e=new Date(t),i=Math.floor((new Date-e)/1e3);if(i<60)return`${i}s`;if(i<3600)return`${Math.floor(i/60)}m ${i%60}s`;let s=Math.floor(i/3600),r=Math.floor(i%3600/60);return`${s}h ${r}m`}_isValidUrl(t){if(!t)return!1;try{let e=new URL(t);return e.protocol==="http:"||e.protocol==="https:"}catch{return!1}}_getStyles(){return`
4682
+ .app-status {
4683
+ padding: 16px;
4684
+ font-family: var(--loki-font-family, system-ui, -apple-system, sans-serif);
4685
+ color: var(--loki-text-primary, #18181b);
4686
+ }
4687
+ .header {
4688
+ display: flex;
4689
+ align-items: center;
4690
+ justify-content: space-between;
4691
+ margin-bottom: 16px;
4692
+ }
4693
+ .header-left {
4694
+ display: flex;
4695
+ align-items: center;
4696
+ gap: 10px;
4697
+ }
4698
+ .title {
4699
+ font-size: 18px;
4700
+ font-weight: 600;
4701
+ margin: 0;
4702
+ }
4703
+
4704
+ /* Status dot */
4705
+ .status-dot {
4706
+ width: 10px;
4707
+ height: 10px;
4708
+ border-radius: 50%;
4709
+ flex-shrink: 0;
4710
+ }
4711
+ .status-dot.pulse {
4712
+ animation: dot-pulse 1.5s ease-in-out infinite;
4713
+ }
4714
+ @keyframes dot-pulse {
4715
+ 0%, 100% { opacity: 1; }
4716
+ 50% { opacity: 0.4; }
4717
+ }
4718
+
4719
+ .status-badge {
4720
+ display: inline-flex;
4721
+ align-items: center;
4722
+ gap: 6px;
4723
+ padding: 2px 10px;
4724
+ border-radius: 9999px;
4725
+ font-size: 12px;
4726
+ font-weight: 500;
4727
+ }
4728
+
4729
+ /* Status card */
4730
+ .status-card {
4731
+ background: var(--loki-bg-card, #ffffff);
4732
+ border: 1px solid var(--loki-border, #e4e4e7);
4733
+ border-radius: 8px;
4734
+ padding: 14px;
4735
+ margin-bottom: 12px;
4736
+ }
4737
+ .status-row {
4738
+ display: flex;
4739
+ justify-content: space-between;
4740
+ align-items: center;
4741
+ padding: 4px 0;
4742
+ font-size: 13px;
4743
+ }
4744
+ .status-label {
4745
+ color: var(--loki-text-secondary, #52525b);
4746
+ }
4747
+ .status-value {
4748
+ font-weight: 500;
4749
+ }
4750
+ .status-value a {
4751
+ color: var(--loki-accent, #7c3aed);
4752
+ text-decoration: none;
4753
+ }
4754
+ .status-value a:hover {
4755
+ text-decoration: underline;
4756
+ }
4757
+
4758
+ /* Log viewer */
4759
+ .log-section {
4760
+ margin-bottom: 12px;
4761
+ }
4762
+ .log-header {
4763
+ font-size: 13px;
4764
+ font-weight: 600;
4765
+ margin-bottom: 6px;
4766
+ color: var(--loki-text-secondary, #52525b);
4767
+ }
4768
+ .log-area {
4769
+ background: var(--loki-bg-tertiary, #1a1a2e);
4770
+ border: 1px solid var(--loki-border, #e4e4e7);
4771
+ border-radius: 6px;
4772
+ padding: 10px;
4773
+ max-height: 300px;
4774
+ overflow-y: auto;
4775
+ font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', monospace;
4776
+ font-size: 11px;
4777
+ line-height: 1.5;
4778
+ color: var(--loki-text-muted, #a1a1aa);
4779
+ white-space: pre-wrap;
4780
+ word-break: break-all;
4781
+ }
4782
+ .log-empty {
4783
+ color: var(--loki-text-muted, #71717a);
4784
+ font-style: italic;
4785
+ }
4786
+
4787
+ /* Action buttons */
4788
+ .actions {
4789
+ display: flex;
4790
+ gap: 8px;
4791
+ }
4792
+ .btn {
4793
+ padding: 5px 14px;
4794
+ border-radius: 6px;
4795
+ font-size: 12px;
4796
+ font-weight: 500;
4797
+ cursor: pointer;
4798
+ border: 1px solid var(--loki-border, #e4e4e7);
4799
+ background: var(--loki-bg-secondary, #f4f4f5);
4800
+ color: var(--loki-text-primary, #18181b);
4801
+ transition: background 0.15s;
4802
+ }
4803
+ .btn:hover {
4804
+ background: var(--loki-bg-hover, #f0f0f3);
4805
+ }
4806
+ .btn-danger {
4807
+ border-color: var(--loki-red, #dc2626);
4808
+ color: var(--loki-red, #dc2626);
4809
+ }
4810
+ .btn-danger:hover {
4811
+ background: var(--loki-red-muted, rgba(220, 38, 38, 0.12));
4812
+ }
4813
+ .btn:disabled {
4814
+ opacity: 0.5;
4815
+ cursor: not-allowed;
4816
+ }
4817
+
4818
+ /* Empty state */
4819
+ .empty-state {
4820
+ text-align: center;
4821
+ padding: 48px 24px;
4822
+ color: var(--loki-text-secondary, #52525b);
4823
+ }
4824
+ .empty-state p {
4825
+ margin: 8px 0;
4826
+ font-size: 14px;
4827
+ }
4828
+ .empty-state .hint {
4829
+ font-size: 12px;
4830
+ color: var(--loki-text-muted, #71717a);
4831
+ }
4832
+
4833
+ /* Error */
4834
+ .error-banner {
4835
+ margin-top: 12px;
4836
+ padding: 8px 12px;
4837
+ background: color-mix(in srgb, var(--loki-status-error, #ef4444) 10%, transparent);
4838
+ color: var(--loki-status-error, #ef4444);
4839
+ border-radius: 6px;
4840
+ font-size: 12px;
4841
+ }
4842
+ `}render(){let t=this.shadowRoot;if(!t)return;let e=this._status,a=e&&e.status&&e.status!=="not_initialized";t.innerHTML=`
4843
+ <style>${this.getBaseStyles()}${this._getStyles()}</style>
4844
+ <div class="app-status">
4845
+ <div class="header">
4846
+ <div class="header-left">
4847
+ <h2 class="title">App Runner</h2>
4848
+ ${this._renderStatusBadge(e)}
4849
+ </div>
4850
+ ${a?this._renderActions(e):""}
4851
+ </div>
4852
+ ${a?this._renderStatusCard(e):""}
4853
+ ${a&&this._logs.length>0?this._renderLogs():""}
4854
+ ${a?"":this._renderEmpty()}
4855
+ ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
4856
+ </div>
4857
+ `,this._attachEventListeners()}_renderStatusBadge(t){let e=t?.status||"not_initialized",a=ct[e]||ct.not_initialized;return`
4858
+ <span class="status-badge" style="background: color-mix(in srgb, ${a.color} 15%, transparent); color: ${a.color}">
4859
+ <span class="status-dot ${a.pulse?"pulse":""}" style="background: ${a.color}"></span>
4860
+ ${this._escapeHtml(a.label)}
4861
+ </span>
4862
+ `}_renderStatusCard(t){let a=this._isValidUrl(t.url)?`<a href="${this._escapeHtml(t.url)}" target="_blank" rel="noopener noreferrer">${this._escapeHtml(t.url)}</a>`:this._escapeHtml(t.url||"--");return`
4863
+ <div class="status-card">
4864
+ <div class="status-row">
4865
+ <span class="status-label">Method</span>
4866
+ <span class="status-value">${this._escapeHtml(t.method||"--")}</span>
4867
+ </div>
4868
+ <div class="status-row">
4869
+ <span class="status-label">Port</span>
4870
+ <span class="status-value">${t.port?this._escapeHtml(String(t.port)):"--"}</span>
4871
+ </div>
4872
+ <div class="status-row">
4873
+ <span class="status-label">URL</span>
4874
+ <span class="status-value">${a}</span>
4875
+ </div>
4876
+ <div class="status-row">
4877
+ <span class="status-label">Restarts</span>
4878
+ <span class="status-value">${t.restart_count!=null?t.restart_count:"--"}</span>
4879
+ </div>
4880
+ <div class="status-row">
4881
+ <span class="status-label">Uptime</span>
4882
+ <span class="status-value">${this._formatUptime(t.started_at)}</span>
4883
+ </div>
4884
+ ${t.status==="crashed"&&t.error?`
4885
+ <div class="status-row" style="margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--loki-border, #e4e4e7);">
4886
+ <span class="status-label" style="color: var(--loki-red, #dc2626)">Error</span>
4887
+ <span class="status-value" style="color: var(--loki-red, #dc2626); max-width: 70%; text-align: right;">${this._escapeHtml(t.error)}</span>
4888
+ </div>
4889
+ `:""}
4890
+ </div>
4891
+ `}_renderLogs(){let t=this._logs.slice(-20);return`
4892
+ <div class="log-section">
4893
+ <div class="log-header">Application Logs</div>
4894
+ <div class="log-area">${t.length>0?t.map(e=>this._escapeHtml(e)).join(`
4895
+ `):'<span class="log-empty">No log output yet</span>'}</div>
4896
+ </div>
4897
+ `}_renderActions(t){let e=t.status==="running"||t.status==="crashed"||t.status==="stopped",a=t.status==="running"||t.status==="starting";return`
4898
+ <div class="actions">
4899
+ <button class="btn" data-action="restart" ${e?"":"disabled"}>Restart</button>
4900
+ <button class="btn btn-danger" data-action="stop" ${a?"":"disabled"}>Stop</button>
4901
+ </div>
4902
+ `}_renderEmpty(){return`
4903
+ <div class="empty-state">
4904
+ <p>App runner not started</p>
4905
+ <p class="hint">App runner will start after the first successful build iteration.</p>
4906
+ </div>
4907
+ `}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.querySelector('[data-action="restart"]'),a=t.querySelector('[data-action="stop"]');e&&e.addEventListener("click",()=>this._handleRestart()),a&&a.addEventListener("click",()=>this._handleStop())}_escapeHtml(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}};customElements.define("loki-app-status",q);var Ct={opus:{input:5,output:25,label:"Opus 4.6",provider:"claude"},sonnet:{input:3,output:15,label:"Sonnet 4.5",provider:"claude"},haiku:{input:1,output:5,label:"Haiku 4.5",provider:"claude"},"gpt-5.3-codex":{input:1.5,output:12,label:"GPT-5.3 Codex",provider:"codex"},"gemini-3-pro":{input:1.25,output:10,label:"Gemini 3 Pro",provider:"gemini"},"gemini-3-flash":{input:.1,output:.4,label:"Gemini 3 Flash",provider:"gemini"}},G=class extends c{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={...Ct}}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadPricing(),this._loadCost(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadCost()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=p({baseUrl:t})}async _loadPricing(){try{let t=await this._api.getPricing();if(t&&t.models){let e={};for(let[a,i]of Object.entries(t.models))e[a]={input:i.input,output:i.output,label:i.label||a,provider:i.provider||"unknown"};this._modelPricing=e,this._pricingSource=t.source||"api",this._pricingDate=t.updated||"",this._activeProvider=t.provider||"claude",this.render()}}catch{}}async _loadCost(){try{let t=await this._api.getCost();this._updateFromCost(t)}catch{this._data.connected=!1,this.render()}}_updateFromCost(t){t&&(this._data={...this._data,connected:!0,total_input_tokens:t.total_input_tokens||0,total_output_tokens:t.total_output_tokens||0,estimated_cost_usd:t.estimated_cost_usd||0,by_phase:t.by_phase||{},by_model:t.by_model||{},budget_limit:t.budget_limit,budget_used:t.budget_used||0,budget_remaining:t.budget_remaining},this.render())}_startPolling(){this._pollInterval=setInterval(async()=>{try{let t=await this._api.getCost();this._updateFromCost(t)}catch{this._data.connected=!1,this.render()}},5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_formatTokens(t){return!t||t===0?"0":t>=1e6?(t/1e6).toFixed(2)+"M":t>=1e3?(t/1e3).toFixed(1)+"K":String(t)}_formatUSD(t){return!t||t===0?"$0.00":t<.01?"<$0.01":"$"+t.toFixed(2)}_getBudgetPercent(){return!this._data.budget_limit||this._data.budget_limit<=0?0:Math.min(100,this._data.budget_used/this._data.budget_limit*100)}_getBudgetStatusClass(){let t=this._getBudgetPercent();return t>=90?"critical":t>=70?"warning":"ok"}_renderPhaseRows(){let t=this._data.by_phase;return!t||Object.keys(t).length===0?'<tr><td colspan="4" class="empty-cell">No phase data yet</td></tr>':Object.entries(t).map(([e,a])=>{let i=a.input_tokens||0,s=a.output_tokens||0,r=a.cost_usd||0;return`
4375
4908
  <tr>
4376
- <td class="phase-name">${this._escapeHTML(t)}</td>
4909
+ <td class="phase-name">${this._escapeHTML(e)}</td>
4377
4910
  <td class="mono-cell">${this._formatTokens(i)}</td>
4378
4911
  <td class="mono-cell">${this._formatTokens(s)}</td>
4379
4912
  <td class="mono-cell cost-cell">${this._formatUSD(r)}</td>
4380
4913
  </tr>
4381
- `}).join("")}_renderModelRows(){let e=this._data.by_model;return!e||Object.keys(e).length===0?'<tr><td colspan="4" class="empty-cell">No model data yet</td></tr>':Object.entries(e).map(([t,a])=>{let i=a.input_tokens||0,s=a.output_tokens||0,r=a.cost_usd||0;return`
4914
+ `}).join("")}_renderModelRows(){let t=this._data.by_model;return!t||Object.keys(t).length===0?'<tr><td colspan="4" class="empty-cell">No model data yet</td></tr>':Object.entries(t).map(([e,a])=>{let i=a.input_tokens||0,s=a.output_tokens||0,r=a.cost_usd||0;return`
4382
4915
  <tr>
4383
- <td class="model-name">${this._escapeHTML(t)}</td>
4916
+ <td class="model-name">${this._escapeHTML(e)}</td>
4384
4917
  <td class="mono-cell">${this._formatTokens(i)}</td>
4385
4918
  <td class="mono-cell">${this._formatTokens(s)}</td>
4386
4919
  <td class="mono-cell cost-cell">${this._formatUSD(r)}</td>
@@ -4395,7 +4928,7 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
4395
4928
  </div>
4396
4929
  <div class="budget-not-set">No budget configured</div>
4397
4930
  </div>
4398
- `;let e=this._getBudgetPercent(),t=this._getBudgetStatusClass(),a=this._data.budget_remaining!=null?this._formatUSD(this._data.budget_remaining):this._formatUSD(this._data.budget_limit-this._data.budget_used);return`
4931
+ `;let t=this._getBudgetPercent(),e=this._getBudgetStatusClass(),a=this._data.budget_remaining!=null?this._formatUSD(this._data.budget_remaining):this._formatUSD(this._data.budget_limit-this._data.budget_used);return`
4399
4932
  <div class="budget-section">
4400
4933
  <div class="section-header">
4401
4934
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
@@ -4404,7 +4937,7 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
4404
4937
  <span class="section-title">Budget</span>
4405
4938
  </div>
4406
4939
  <div class="budget-bar-container">
4407
- <div class="budget-bar ${t}" style="width: ${e.toFixed(1)}%"></div>
4940
+ <div class="budget-bar ${e}" style="width: ${t.toFixed(1)}%"></div>
4408
4941
  </div>
4409
4942
  <div class="budget-details">
4410
4943
  <span class="budget-used">${this._formatUSD(this._data.budget_used)} used</span>
@@ -4412,7 +4945,7 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
4412
4945
  <span class="budget-limit">of ${this._formatUSD(this._data.budget_limit)}</span>
4413
4946
  </div>
4414
4947
  </div>
4415
- `}_getPricingColorClass(e,t){return e==="opus"||e.includes("opus")?"opus":e==="sonnet"||e.includes("sonnet")?"sonnet":e==="haiku"||e.includes("haiku")?"haiku":t.provider==="codex"?"codex":t.provider==="gemini"?"gemini":""}_escapeHTML(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}render(){let e=this._data.total_input_tokens+this._data.total_output_tokens;this.shadowRoot.innerHTML=`
4948
+ `}_getPricingColorClass(t,e){return t==="opus"||t.includes("opus")?"opus":t==="sonnet"||t.includes("sonnet")?"sonnet":t==="haiku"||t.includes("haiku")?"haiku":e.provider==="codex"?"codex":e.provider==="gemini"?"gemini":""}_escapeHTML(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}render(){let t=this._data.total_input_tokens+this._data.total_output_tokens;this.shadowRoot.innerHTML=`
4416
4949
  <style>
4417
4950
  ${this.getBaseStyles()}
4418
4951
 
@@ -4687,7 +5220,7 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
4687
5220
  <div class="summary-grid">
4688
5221
  <div class="summary-card">
4689
5222
  <div class="card-label">Total Tokens</div>
4690
- <div class="card-value">${this._formatTokens(e)}</div>
5223
+ <div class="card-value">${this._formatTokens(t)}</div>
4691
5224
  <div class="card-sub">${this._formatTokens(this._data.total_input_tokens)} in / ${this._formatTokens(this._data.total_output_tokens)} out</div>
4692
5225
  </div>
4693
5226
 
@@ -4766,21 +5299,21 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
4766
5299
  ${this._pricingDate?`<span class="pricing-meta">Updated: ${this._escapeHTML(this._pricingDate)}</span>`:""}
4767
5300
  </div>
4768
5301
  <div class="pricing-grid">
4769
- ${Object.entries(ne).map(([t,a])=>`
5302
+ ${Object.entries(this._modelPricing).map(([e,a])=>`
4770
5303
  <div class="pricing-item">
4771
- <div class="pricing-model ${this._getPricingColorClass(t,a)}">${a.label||t}</div>
5304
+ <div class="pricing-model ${this._getPricingColorClass(e,a)}">${a.label||e}</div>
4772
5305
  <div class="pricing-rates">In: $${a.input.toFixed(2)} / Out: $${a.output.toFixed(2)}</div>
4773
5306
  </div>`).join("")}
4774
5307
  </div>
4775
5308
  </div>
4776
5309
  </div>
4777
- `}};customElements.get("loki-cost-dashboard")||customElements.define("loki-cost-dashboard",N);var q=class extends c{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._checkpoints=[],this._pollInterval=null,this._lastDataHash=null,this._showCreateForm=!1,this._creating=!1,this._rollingBack=!1,this._rollbackTarget=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,a){t!==a&&(e==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=u({baseUrl:e})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),3e3),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadData(),this._pollInterval=setInterval(()=>this._loadData(),3e3))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null)}async _loadData(){try{let[t]=await Promise.allSettled([this._api._get("/api/checkpoints?limit=50")]);t.status==="fulfilled"&&(this._checkpoints=Array.isArray(t.value)?t.value:t.value?.checkpoints||[]),this._error=null}catch(t){this._error=t.message}let e=JSON.stringify({c:this._checkpoints,e:this._error});e!==this._lastDataHash&&(this._lastDataHash=e,this.render())}async _createCheckpoint(){let e=this.shadowRoot.getElementById("checkpoint-message"),t=e?e.value.trim():"";if(t){this._creating=!0,this.render();try{await this._api._post("/api/checkpoints",{message:t}),this._showCreateForm=!1,this._creating=!1,this.dispatchEvent(new CustomEvent("checkpoint-action",{detail:{action:"create",message:t},bubbles:!0})),this._lastDataHash=null,await this._loadData()}catch(a){this._creating=!1,this._error=`Failed to create checkpoint: ${a.message}`,this.render()}}}async _rollbackCheckpoint(e){if(!this._rollingBack){this._rollingBack=!0,this.render();try{await this._api._post(`/api/checkpoints/${e}/rollback`),this._rollbackTarget=null,this.dispatchEvent(new CustomEvent("checkpoint-action",{detail:{action:"rollback",checkpointId:e},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.render()}_confirmRollback(e){this._rollbackTarget=e,this.render()}_cancelRollback(){this._rollbackTarget=null,this.render()}_formatRelativeTime(e){if(!e)return"";try{let t=Date.now(),a=new Date(e).getTime(),i=Math.floor((t-a)/1e3);return i<60?`${i}s ago`:i<3600?`${Math.floor(i/60)}m ago`:i<86400?`${Math.floor(i/3600)}h ago`:`${Math.floor(i/86400)}d ago`}catch{return this._escapeHTML(e)}}render(){let e=this.shadowRoot;if(!e)return;let t=this._checkpoints.length;e.innerHTML=`
5310
+ `}};customElements.get("loki-cost-dashboard")||customElements.define("loki-cost-dashboard",G);var J=class extends c{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._checkpoints=[],this._pollInterval=null,this._lastDataHash=null,this._showCreateForm=!1,this._creating=!1,this._rollingBack=!1,this._rollbackTarget=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=p({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),3e3),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadData(),this._pollInterval=setInterval(()=>this._loadData(),3e3))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null)}async _loadData(){try{let[e]=await Promise.allSettled([this._api._get("/api/checkpoints?limit=50")]);e.status==="fulfilled"&&(this._checkpoints=Array.isArray(e.value)?e.value:e.value?.checkpoints||[]),this._error=null}catch(e){this._error=e.message}let t=JSON.stringify({c:this._checkpoints,e:this._error});t!==this._lastDataHash&&(this._lastDataHash=t,this.render())}async _createCheckpoint(){let t=this.shadowRoot.getElementById("checkpoint-message"),e=t?t.value.trim():"";if(e){this._creating=!0,this.render();try{await this._api._post("/api/checkpoints",{message:e}),this._showCreateForm=!1,this._creating=!1,this.dispatchEvent(new CustomEvent("checkpoint-action",{detail:{action:"create",message:e},bubbles:!0})),this._lastDataHash=null,await this._loadData()}catch(a){this._creating=!1,this._error=`Failed to create checkpoint: ${a.message}`,this.render()}}}async _rollbackCheckpoint(t){if(!this._rollingBack){this._rollingBack=!0,this.render();try{await this._api._post(`/api/checkpoints/${t}/rollback`),this._rollbackTarget=null,this.dispatchEvent(new CustomEvent("checkpoint-action",{detail:{action:"rollback",checkpointId:t},bubbles:!0})),this._lastDataHash=null,await this._loadData()}catch(e){this._rollbackTarget=null,this._error=`Failed to rollback: ${e.message}`}finally{this._rollingBack=!1,this.render()}}}_toggleCreateForm(){this._showCreateForm=!this._showCreateForm,this._rollbackTarget=null,this.render()}_confirmRollback(t){this._rollbackTarget=t,this.render()}_cancelRollback(){this._rollbackTarget=null,this.render()}_formatRelativeTime(t){if(!t)return"";try{let e=Date.now(),a=new Date(t).getTime(),i=Math.floor((e-a)/1e3);return i<60?`${i}s ago`:i<3600?`${Math.floor(i/60)}m ago`:i<86400?`${Math.floor(i/3600)}h ago`:`${Math.floor(i/86400)}d ago`}catch{return this._escapeHTML(t)}}render(){let t=this.shadowRoot;if(!t)return;let e=this._checkpoints.length;t.innerHTML=`
4778
5311
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
4779
5312
  <div class="checkpoint-viewer">
4780
5313
  <div class="checkpoint-header">
4781
5314
  <div class="header-left">
4782
5315
  <h2 class="title">Checkpoints</h2>
4783
- <span class="count-badge">${t}</span>
5316
+ <span class="count-badge">${e}</span>
4784
5317
  </div>
4785
5318
  <button class="btn btn-primary" id="create-btn">
4786
5319
  ${this._showCreateForm?"Cancel":"Create Checkpoint"}
@@ -4791,7 +5324,7 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
4791
5324
 
4792
5325
  <div class="checkpoint-list">
4793
5326
  ${this._loading?'<div class="loading-state">Loading checkpoints...</div>':""}
4794
- ${!this._loading&&t===0?'<div class="empty-state">No checkpoints yet. Create one to save the current state.</div>':""}
5327
+ ${!this._loading&&e===0?'<div class="empty-state">No checkpoints yet. Create one to save the current state.</div>':""}
4795
5328
  ${this._checkpoints.map(a=>this._renderCheckpointCard(a)).join("")}
4796
5329
  </div>
4797
5330
 
@@ -4811,30 +5344,30 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
4811
5344
  ${this._creating?"Creating...":"Save"}
4812
5345
  </button>
4813
5346
  </div>
4814
- `}_renderCheckpointCard(e){let t=e.git_sha?e.git_sha.substring(0,7):"unknown",a=Array.isArray(e.files)?e.files.length:e.files_count||0,i=this._rollbackTarget===e.id;return`
4815
- <div class="checkpoint-card" data-checkpoint-id="${this._escapeHTML(e.id)}">
5347
+ `}_renderCheckpointCard(t){let e=t.git_sha?t.git_sha.substring(0,7):"unknown",a=Array.isArray(t.files)?t.files.length:t.files_count||0,i=this._rollbackTarget===t.id;return`
5348
+ <div class="checkpoint-card" data-checkpoint-id="${this._escapeHTML(t.id)}">
4816
5349
  <div class="card-header">
4817
- <span class="checkpoint-sha mono">${this._escapeHTML(t)}</span>
4818
- <span class="checkpoint-time">${this._formatRelativeTime(e.created_at)}</span>
5350
+ <span class="checkpoint-sha mono">${this._escapeHTML(e)}</span>
5351
+ <span class="checkpoint-time">${this._formatRelativeTime(t.created_at)}</span>
4819
5352
  </div>
4820
5353
  <div class="card-body">
4821
- <p class="checkpoint-message">${this._escapeHTML(e.message||"No message")}</p>
5354
+ <p class="checkpoint-message">${this._escapeHTML(t.message||"No message")}</p>
4822
5355
  <div class="card-meta">
4823
5356
  <span class="meta-item">${a} file${a!==1?"s":""}</span>
4824
- <span class="meta-item mono">ID: ${this._escapeHTML(e.id)}</span>
5357
+ <span class="meta-item mono">ID: ${this._escapeHTML(t.id)}</span>
4825
5358
  </div>
4826
5359
  </div>
4827
5360
  <div class="card-actions">
4828
5361
  ${i?`
4829
5362
  <span class="rollback-confirm-text">Rollback to this checkpoint?</span>
4830
- <button class="btn btn-sm btn-danger" data-action="confirm-rollback" data-id="${this._escapeHTML(e.id)}">Confirm</button>
5363
+ <button class="btn btn-sm btn-danger" data-action="confirm-rollback" data-id="${this._escapeHTML(t.id)}">Confirm</button>
4831
5364
  <button class="btn btn-sm" data-action="cancel-rollback">Cancel</button>
4832
5365
  `:`
4833
- <button class="btn btn-sm" data-action="rollback" data-id="${this._escapeHTML(e.id)}">Rollback</button>
5366
+ <button class="btn btn-sm" data-action="rollback" data-id="${this._escapeHTML(t.id)}">Rollback</button>
4834
5367
  `}
4835
5368
  </div>
4836
5369
  </div>
4837
- `}_escapeHTML(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("create-btn");t&&t.addEventListener("click",()=>this._toggleCreateForm());let a=e.getElementById("submit-create-btn");a&&a.addEventListener("click",()=>this._createCheckpoint());let i=e.getElementById("checkpoint-message");i&&(i.addEventListener("keydown",s=>{s.key==="Enter"&&!this._creating&&(s.preventDefault(),this._createCheckpoint())}),requestAnimationFrame(()=>i.focus())),e.querySelectorAll("[data-action]").forEach(s=>{s.addEventListener("click",r=>{r.stopPropagation();let o=s.dataset.action,l=s.dataset.id;o==="rollback"?this._confirmRollback(l):o==="confirm-rollback"?this._rollbackCheckpoint(l):o==="cancel-rollback"&&this._cancelRollback()})})}_getStyles(){return`
5370
+ `}_escapeHTML(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.getElementById("create-btn");e&&e.addEventListener("click",()=>this._toggleCreateForm());let a=t.getElementById("submit-create-btn");a&&a.addEventListener("click",()=>this._createCheckpoint());let i=t.getElementById("checkpoint-message");i&&(i.addEventListener("keydown",s=>{s.key==="Enter"&&!this._creating&&(s.preventDefault(),this._createCheckpoint())}),requestAnimationFrame(()=>i.focus())),t.querySelectorAll("[data-action]").forEach(s=>{s.addEventListener("click",r=>{r.stopPropagation();let o=s.dataset.action,l=s.dataset.id;o==="rollback"?this._confirmRollback(l):o==="confirm-rollback"?this._rollbackCheckpoint(l):o==="cancel-rollback"&&this._cancelRollback()})})}_getStyles(){return`
4838
5371
  :host {
4839
5372
  display: block;
4840
5373
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
@@ -5061,7 +5594,7 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
5061
5594
  color: var(--loki-red);
5062
5595
  font-size: 12px;
5063
5596
  }
5064
- `}};customElements.get("loki-checkpoint-viewer")||customElements.define("loki-checkpoint-viewer",q);var G=class extends c{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,a){t!==a&&(e==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadContext()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=u({baseUrl:e})}async _loadContext(){try{let e=this.getAttribute("api-url")||window.location.origin,t=await fetch(e+"/api/context");t.ok&&(this._data=await t.json(),this._connected=!0)}catch{this._connected=!1}this.render()}_startPolling(){this._pollInterval=setInterval(()=>{this._loadContext()},5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=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||{},a=e.context_window_pct||0,i=this._getGaugeColor(a),s=this._getGaugeColorClass(a),r=70,o=2*Math.PI*r,l=o-a/100*o;return`
5597
+ `}};customElements.get("loki-checkpoint-viewer")||customElements.define("loki-checkpoint-viewer",J);var K=class extends c{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data=null,this._connected=!1,this._activeTab="gauge",this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadContext(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,this._loadContext()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=p({baseUrl:t})}async _loadContext(){try{let t=this.getAttribute("api-url")||window.location.origin,e=await fetch(t+"/api/context");e.ok&&(this._data=await e.json(),this._connected=!0)}catch{this._connected=!1}this.render()}_startPolling(){this._pollInterval=setInterval(()=>{this._loadContext()},5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_setTab(t){this._activeTab=t,this.render()}_formatTokens(t){return!t||t===0?"0":t>=1e6?(t/1e6).toFixed(2)+"M":t>=1e3?(t/1e3).toFixed(1)+"K":String(t)}_formatUSD(t){return!t||t===0?"$0.00":t<.01?"<$0.01":"$"+t.toFixed(2)}_escapeHTML(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getGaugeColor(t){return t>80?"var(--loki-red)":t>=60?"var(--loki-yellow)":"var(--loki-green)"}_getGaugeColorClass(t){return t>80?"gauge-red":t>=60?"gauge-yellow":"gauge-green"}_renderGaugeTab(){let t=this._data?.current||{},e=this._data?.totals||{},a=t.context_window_pct||0,i=this._getGaugeColor(a),s=this._getGaugeColorClass(a),r=70,o=2*Math.PI*r,l=o-a/100*o;return`
5065
5598
  <div class="gauge-tab">
5066
5599
  <div class="gauge-container">
5067
5600
  <svg class="gauge-svg" viewBox="0 0 180 180" aria-label="Context window usage: ${a.toFixed(1)}%">
@@ -5098,20 +5631,20 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
5098
5631
  <div class="summary-grid">
5099
5632
  <div class="summary-card">
5100
5633
  <div class="card-label">Total Tokens</div>
5101
- <div class="card-value">${this._formatTokens(e.total_tokens)}</div>
5102
- <div class="card-sub">${this._formatTokens(e.input_tokens)} in / ${this._formatTokens(e.output_tokens)} out</div>
5634
+ <div class="card-value">${this._formatTokens(t.total_tokens)}</div>
5635
+ <div class="card-sub">${this._formatTokens(t.input_tokens)} in / ${this._formatTokens(t.output_tokens)} out</div>
5103
5636
  </div>
5104
5637
  <div class="summary-card">
5105
5638
  <div class="card-label">Estimated Cost</div>
5106
- <div class="card-value accent">${this._formatUSD(e.estimated_cost_usd)}</div>
5639
+ <div class="card-value accent">${this._formatUSD(t.estimated_cost_usd)}</div>
5107
5640
  </div>
5108
5641
  <div class="summary-card">
5109
5642
  <div class="card-label">Compactions</div>
5110
- <div class="card-value">${t.compaction_count||0}</div>
5643
+ <div class="card-value">${e.compaction_count||0}</div>
5111
5644
  </div>
5112
5645
  <div class="summary-card">
5113
5646
  <div class="card-label">Iterations Tracked</div>
5114
- <div class="card-value">${t.iterations_tracked||0}</div>
5647
+ <div class="card-value">${e.iterations_tracked||0}</div>
5115
5648
  </div>
5116
5649
  </div>
5117
5650
 
@@ -5127,23 +5660,23 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
5127
5660
  <div class="cache-grid">
5128
5661
  <div class="cache-item">
5129
5662
  <span class="cache-label">Cache Read</span>
5130
- <span class="cache-value">${this._formatTokens(e.cache_read_tokens)}</span>
5663
+ <span class="cache-value">${this._formatTokens(t.cache_read_tokens)}</span>
5131
5664
  </div>
5132
5665
  <div class="cache-item">
5133
5666
  <span class="cache-label">Cache Creation</span>
5134
- <span class="cache-value">${this._formatTokens(e.cache_creation_tokens)}</span>
5667
+ <span class="cache-value">${this._formatTokens(t.cache_creation_tokens)}</span>
5135
5668
  </div>
5136
5669
  </div>
5137
5670
  </div>
5138
5671
  </div>
5139
- `}_renderTimelineTab(){let e=this._data?.per_iteration||[],t=this._data?.compactions||[];if(e.length===0)return'<div class="empty-state">No iteration data yet</div>';let a=Math.max(...e.map(r=>(r.input_tokens||0)+(r.output_tokens||0)+(r.cache_read_tokens||0)+(r.cache_creation_tokens||0))),i=new Set(t.map(r=>r.at_iteration)),s="";for(let r of e){let o=(r.input_tokens||0)+(r.output_tokens||0)+(r.cache_read_tokens||0)+(r.cache_creation_tokens||0),l=a>0?o/a*100:0,p=r.compacted===!0;i.has(r.iteration)&&(s+=`
5672
+ `}_renderTimelineTab(){let t=this._data?.per_iteration||[],e=this._data?.compactions||[];if(t.length===0)return'<div class="empty-state">No iteration data yet</div>';let a=Math.max(...t.map(r=>(r.input_tokens||0)+(r.output_tokens||0)+(r.cache_read_tokens||0)+(r.cache_creation_tokens||0))),i=new Set(e.map(r=>r.at_iteration)),s="";for(let r of t){let o=(r.input_tokens||0)+(r.output_tokens||0)+(r.cache_read_tokens||0)+(r.cache_creation_tokens||0),l=a>0?o/a*100:0,u=r.compacted===!0;i.has(r.iteration)&&(s+=`
5140
5673
  <div class="timeline-compaction-row">
5141
5674
  <div class="compaction-line"></div>
5142
5675
  <span class="compaction-label">Context Compacted</span>
5143
5676
  <div class="compaction-line"></div>
5144
5677
  </div>
5145
5678
  `),s+=`
5146
- <div class="timeline-row ${p?"compacted":""}">
5679
+ <div class="timeline-row ${u?"compacted":""}">
5147
5680
  <div class="timeline-iter">#${r.iteration}</div>
5148
5681
  <div class="timeline-bar-container">
5149
5682
  <div class="timeline-bar" style="width: ${l.toFixed(1)}%"></div>
@@ -5167,21 +5700,21 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
5167
5700
  </div>
5168
5701
  ${s}
5169
5702
  </div>
5170
- `}_renderBreakdownTab(){let e=this._data?.per_iteration||[];if(e.length===0)return'<div class="empty-state">No iteration data yet</div>';let t=Math.max(...e.map(s=>(s.input_tokens||0)+(s.output_tokens||0)+(s.cache_read_tokens||0)+(s.cache_creation_tokens||0))),a=`
5703
+ `}_renderBreakdownTab(){let t=this._data?.per_iteration||[];if(t.length===0)return'<div class="empty-state">No iteration data yet</div>';let e=Math.max(...t.map(s=>(s.input_tokens||0)+(s.output_tokens||0)+(s.cache_read_tokens||0)+(s.cache_creation_tokens||0))),a=`
5171
5704
  <div class="breakdown-legend">
5172
5705
  <div class="legend-item"><span class="legend-swatch swatch-input"></span> Input</div>
5173
5706
  <div class="legend-item"><span class="legend-swatch swatch-output"></span> Output</div>
5174
5707
  <div class="legend-item"><span class="legend-swatch swatch-cache-read"></span> Cache Read</div>
5175
5708
  <div class="legend-item"><span class="legend-swatch swatch-cache-create"></span> Cache Creation</div>
5176
5709
  </div>
5177
- `,i="";for(let s of e){let r=s.input_tokens||0,o=s.output_tokens||0,l=s.cache_read_tokens||0,p=s.cache_creation_tokens||0,A=r+o+l+p,D=t>0?r/t*100:0,le=t>0?o/t*100:0,de=t>0?l/t*100:0,ce=t>0?p/t*100:0;i+=`
5710
+ `,i="";for(let s of t){let r=s.input_tokens||0,o=s.output_tokens||0,l=s.cache_read_tokens||0,u=s.cache_creation_tokens||0,A=r+o+l+u,D=e>0?r/e*100:0,pt=e>0?o/e*100:0,ut=e>0?l/e*100:0,gt=e>0?u/e*100:0;i+=`
5178
5711
  <div class="breakdown-row">
5179
5712
  <div class="breakdown-iter">#${s.iteration}</div>
5180
5713
  <div class="breakdown-bar-container">
5181
5714
  <div class="breakdown-bar bar-input" style="width: ${D.toFixed(1)}%"></div>
5182
- <div class="breakdown-bar bar-output" style="width: ${le.toFixed(1)}%"></div>
5183
- <div class="breakdown-bar bar-cache-read" style="width: ${de.toFixed(1)}%"></div>
5184
- <div class="breakdown-bar bar-cache-create" style="width: ${ce.toFixed(1)}%"></div>
5715
+ <div class="breakdown-bar bar-output" style="width: ${pt.toFixed(1)}%"></div>
5716
+ <div class="breakdown-bar bar-cache-read" style="width: ${ut.toFixed(1)}%"></div>
5717
+ <div class="breakdown-bar bar-cache-create" style="width: ${gt.toFixed(1)}%"></div>
5185
5718
  </div>
5186
5719
  <div class="breakdown-cost">${this._formatUSD(s.cost_usd)}</div>
5187
5720
  </div>
@@ -5198,7 +5731,7 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
5198
5731
  ${a}
5199
5732
  ${i}
5200
5733
  </div>
5201
- `}render(){let e=this._activeTab==="gauge"?this._renderGaugeTab():this._activeTab==="timeline"?this._renderTimelineTab():this._renderBreakdownTab();this.shadowRoot.innerHTML=`
5734
+ `}render(){let t=this._activeTab==="gauge"?this._renderGaugeTab():this._activeTab==="timeline"?this._renderTimelineTab():this._renderBreakdownTab();this.shadowRoot.innerHTML=`
5202
5735
  <style>
5203
5736
  ${this.getBaseStyles()}
5204
5737
 
@@ -5583,45 +6116,45 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
5583
6116
  <button class="tab ${this._activeTab==="breakdown"?"active":""}" data-tab="breakdown">Breakdown</button>
5584
6117
  </div>
5585
6118
 
5586
- ${e}
6119
+ ${t}
5587
6120
  </div>
5588
- `,this.shadowRoot.querySelectorAll(".tab").forEach(t=>{t.addEventListener("click",()=>{this._setTab(t.dataset.tab)})})}};customElements.get("loki-context-tracker")||customElements.define("loki-context-tracker",G);var ee={critical:"var(--loki-red, #ef4444)",warning:"var(--loki-yellow, #eab308)",info:"var(--loki-blue, #3b82f6)"},J=class extends c{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._notifications=[],this._triggers=[],this._summary={},this._connected=!1,this._activeTab="feed",this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._loadNotifications(),this._loadTriggers(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,a){t!==a&&(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 a=await t.json();this._notifications=a.notifications||[],this._summary=a.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 a=await t.json();this._triggers=a.triggers||[]}}catch{}}async _acknowledgeNotification(e){let t=this.getAttribute("api-url")||window.location.origin;await fetch(t+"/api/notifications/"+encodeURIComponent(e)+"/acknowledge",{method:"POST"}),this._loadNotifications()}async _acknowledgeAll(){let e=this.getAttribute("api-url")||window.location.origin,t=this._notifications.filter(a=>!a.acknowledged);for(let a of t)await fetch(e+"/api/notifications/"+encodeURIComponent(a.id)+"/acknowledge",{method:"POST"});this._loadNotifications()}async _toggleTrigger(e,t){let a=this.getAttribute("api-url")||window.location.origin,i=this._triggers.map(s=>s.id===e?{...s,enabled:t}:s);await fetch(a+"/api/notifications/triggers",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({triggers:i})}),this._triggers=i,this.render()}_startPolling(){this._pollInterval=setInterval(()=>{this._loadNotifications(),this._loadTriggers()},5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_formatTime(e){if(!e)return"";try{let t=new Date(e),i=new Date-t,s=Math.floor(i/1e3),r=Math.floor(s/60),o=Math.floor(r/60),l=Math.floor(o/24);return s<60?s+"s ago":r<60?r+"m ago":o<24?o+"h ago":l<7?l+"d ago":t.toLocaleDateString()}catch{return String(e)}}_escapeHTML(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getSeverityColor(e){return ee[e]||ee.info}_switchTab(e){this._activeTab=e,this.render()}_bindEvents(){let e=this.shadowRoot;e.querySelectorAll(".tab").forEach(a=>{a.addEventListener("click",()=>{this._switchTab(a.dataset.tab)})}),e.querySelectorAll(".ack-btn").forEach(a=>{a.addEventListener("click",()=>{this._acknowledgeNotification(a.dataset.id)})});let t=e.querySelector(".ack-all-btn");t&&t.addEventListener("click",()=>{this._acknowledgeAll()}),e.querySelectorAll(".toggle input").forEach(a=>{a.addEventListener("change",()=>{this._toggleTrigger(a.dataset.triggerId,a.checked)})})}_renderSummaryBar(){let e=this._summary.total||0,t=this._summary.unacknowledged||0,a=this._summary.critical||0;return`
6121
+ `,this.shadowRoot.querySelectorAll(".tab").forEach(e=>{e.addEventListener("click",()=>{this._setTab(e.dataset.tab)})})}};customElements.get("loki-context-tracker")||customElements.define("loki-context-tracker",K);var at={critical:"var(--loki-red, #ef4444)",warning:"var(--loki-yellow, #eab308)",info:"var(--loki-blue, #3b82f6)"},V=class extends c{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._notifications=[],this._triggers=[],this._summary={},this._connected=!1,this._activeTab="feed",this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._loadNotifications(),this._loadTriggers(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&(this._loadNotifications(),this._loadTriggers()),t==="theme"&&this._applyTheme())}async _loadNotifications(){try{let t=this.getAttribute("api-url")||window.location.origin,e=await fetch(t+"/api/notifications");if(e.ok){let a=await e.json();this._notifications=a.notifications||[],this._summary=a.summary||{},this._connected=!0}}catch{this._connected=!1}this.render()}async _loadTriggers(){try{let t=this.getAttribute("api-url")||window.location.origin,e=await fetch(t+"/api/notifications/triggers");if(e.ok){let a=await e.json();this._triggers=a.triggers||[]}}catch{}}async _acknowledgeNotification(t){let e=this.getAttribute("api-url")||window.location.origin;await fetch(e+"/api/notifications/"+encodeURIComponent(t)+"/acknowledge",{method:"POST"}),this._loadNotifications()}async _acknowledgeAll(){let t=this.getAttribute("api-url")||window.location.origin,e=this._notifications.filter(a=>!a.acknowledged);for(let a of e)await fetch(t+"/api/notifications/"+encodeURIComponent(a.id)+"/acknowledge",{method:"POST"});this._loadNotifications()}async _toggleTrigger(t,e){let a=this.getAttribute("api-url")||window.location.origin,i=this._triggers.map(s=>s.id===t?{...s,enabled:e}:s);await fetch(a+"/api/notifications/triggers",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({triggers:i})}),this._triggers=i,this.render()}_startPolling(){this._pollInterval=setInterval(()=>{this._loadNotifications(),this._loadTriggers()},5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_formatTime(t){if(!t)return"";try{let e=new Date(t),i=new Date-e,s=Math.floor(i/1e3),r=Math.floor(s/60),o=Math.floor(r/60),l=Math.floor(o/24);return s<60?s+"s ago":r<60?r+"m ago":o<24?o+"h ago":l<7?l+"d ago":e.toLocaleDateString()}catch{return String(t)}}_escapeHTML(t){return t?String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getSeverityColor(t){return at[t]||at.info}_switchTab(t){this._activeTab=t,this.render()}_bindEvents(){let t=this.shadowRoot;t.querySelectorAll(".tab").forEach(a=>{a.addEventListener("click",()=>{this._switchTab(a.dataset.tab)})}),t.querySelectorAll(".ack-btn").forEach(a=>{a.addEventListener("click",()=>{this._acknowledgeNotification(a.dataset.id)})});let e=t.querySelector(".ack-all-btn");e&&e.addEventListener("click",()=>{this._acknowledgeAll()}),t.querySelectorAll(".toggle input").forEach(a=>{a.addEventListener("change",()=>{this._toggleTrigger(a.dataset.triggerId,a.checked)})})}_renderSummaryBar(){let t=this._summary.total||0,e=this._summary.unacknowledged||0,a=this._summary.critical||0;return`
5589
6122
  <div class="summary-row">
5590
6123
  <div class="summary-grid">
5591
6124
  <div class="summary-card">
5592
6125
  <div class="card-label">Total</div>
5593
- <div class="card-value">${e}</div>
6126
+ <div class="card-value">${t}</div>
5594
6127
  </div>
5595
6128
  <div class="summary-card">
5596
6129
  <div class="card-label">Unread</div>
5597
- <div class="card-value">${t}</div>
6130
+ <div class="card-value">${e}</div>
5598
6131
  </div>
5599
6132
  <div class="summary-card">
5600
6133
  <div class="card-label">Critical</div>
5601
- <div class="card-value" style="color: ${ee.critical}">${a}</div>
6134
+ <div class="card-value" style="color: ${at.critical}">${a}</div>
5602
6135
  </div>
5603
6136
  </div>
5604
- ${t>0?`
6137
+ ${e>0?`
5605
6138
  <button class="ack-all-btn">Acknowledge All</button>
5606
6139
  `:""}
5607
6140
  </div>
5608
- `}_renderNotificationList(){return this._notifications.length===0?'<div class="empty-state">No notifications</div>':[...this._notifications].sort((t,a)=>new Date(a.timestamp)-new Date(t.timestamp)).map(t=>{let a=t.acknowledged,i=this._getSeverityColor(t.severity);return`
6141
+ `}_renderNotificationList(){return this._notifications.length===0?'<div class="empty-state">No notifications</div>':[...this._notifications].sort((e,a)=>new Date(a.timestamp)-new Date(e.timestamp)).map(e=>{let a=e.acknowledged,i=this._getSeverityColor(e.severity);return`
5609
6142
  <div class="notif-row ${a?"acknowledged":""}">
5610
- <span class="severity-dot" style="background: ${i};" title="${this._escapeHTML(t.severity)}"></span>
5611
- <span class="notif-time">${this._formatTime(t.timestamp)}</span>
5612
- <span class="notif-message">${this._escapeHTML(t.message)}</span>
5613
- ${t.iteration!=null?`<span class="notif-iteration">iter ${t.iteration}</span>`:""}
5614
- ${a?"":`<button class="ack-btn" data-id="${this._escapeHTML(t.id)}">Ack</button>`}
6143
+ <span class="severity-dot" style="background: ${i};" title="${this._escapeHTML(e.severity)}"></span>
6144
+ <span class="notif-time">${this._formatTime(e.timestamp)}</span>
6145
+ <span class="notif-message">${this._escapeHTML(e.message)}</span>
6146
+ ${e.iteration!=null?`<span class="notif-iteration">iter ${e.iteration}</span>`:""}
6147
+ ${a?"":`<button class="ack-btn" data-id="${this._escapeHTML(e.id)}">Ack</button>`}
5615
6148
  </div>
5616
- `}).join("")}_renderTriggerList(){return this._triggers.length===0?'<div class="empty-state">No triggers configured</div>':this._triggers.map(e=>{let t=this._getSeverityColor(e.severity),a=e.threshold_pct!=null?`Threshold: ${e.threshold_pct}%`:e.pattern||"";return`
6149
+ `}).join("")}_renderTriggerList(){return this._triggers.length===0?'<div class="empty-state">No triggers configured</div>':this._triggers.map(t=>{let e=this._getSeverityColor(t.severity),a=t.threshold_pct!=null?`Threshold: ${t.threshold_pct}%`:t.pattern||"";return`
5617
6150
  <div class="trigger-row">
5618
6151
  <label class="toggle">
5619
- <input type="checkbox" data-trigger-id="${this._escapeHTML(e.id)}" ${e.enabled?"checked":""}>
6152
+ <input type="checkbox" data-trigger-id="${this._escapeHTML(t.id)}" ${t.enabled?"checked":""}>
5620
6153
  <span class="toggle-slider"></span>
5621
6154
  </label>
5622
- <span class="trigger-name">${this._escapeHTML(e.id)}</span>
5623
- <span class="trigger-badge type-badge">${this._escapeHTML(e.type||"custom")}</span>
5624
- <span class="trigger-badge severity-badge" style="background: ${t}; color: #fff;">${this._escapeHTML(e.severity||"info")}</span>
6155
+ <span class="trigger-name">${this._escapeHTML(t.id)}</span>
6156
+ <span class="trigger-badge type-badge">${this._escapeHTML(t.type||"custom")}</span>
6157
+ <span class="trigger-badge severity-badge" style="background: ${e}; color: #fff;">${this._escapeHTML(t.severity||"info")}</span>
5625
6158
  ${a?`<span class="trigger-info">${this._escapeHTML(a)}</span>`:""}
5626
6159
  </div>
5627
6160
  `}).join("")}render(){this.shadowRoot.innerHTML=`
@@ -5961,7 +6494,7 @@ var LokiDashboard=(()=>{var K=Object.defineProperty;var pe=Object.getOwnProperty
5961
6494
  </div>
5962
6495
  `:""}
5963
6496
  </div>
5964
- `,this._bindEvents()}};customElements.get("loki-notification-center")||customElements.define("loki-notification-center",J);var Te="1.3.0";function Ee(d={}){return d.theme?h.setTheme(d.theme):d.autoDetectContext!==!1?h.init():S.init(),d.apiUrl&&u({baseUrl:d.apiUrl}),{theme:h.getTheme(),context:h.detectContext()}}return be(Se);})();
6497
+ `,this._bindEvents()}};customElements.get("loki-notification-center")||customElements.define("loki-notification-center",V);var At="1.3.0";function Lt(d={}){return d.theme?h.setTheme(d.theme):d.autoDetectContext!==!1?h.init():S.init(),d.apiUrl&&p({baseUrl:d.apiUrl}),{theme:h.getTheme(),context:h.detectContext()}}return _t(It);})();
5965
6498
 
5966
6499
 
5967
6500
  // Initialize dashboard when DOM is ready
@@ -6010,6 +6543,8 @@ document.addEventListener('DOMContentLoaded', function() {
6010
6543
  'log-stream',
6011
6544
  'memory-browser',
6012
6545
  'learning-dashboard',
6546
+ 'checklist-viewer',
6547
+ 'app-status',
6013
6548
  'council-dashboard',
6014
6549
  'cost-dashboard',
6015
6550
  'checkpoint-viewer',
@@ -6104,7 +6639,7 @@ document.addEventListener('DOMContentLoaded', function() {
6104
6639
  document.addEventListener('keydown', function(e) {
6105
6640
  if ((e.metaKey || e.ctrlKey) && ((e.key >= '1' && e.key <= '9') || e.key === '0')) {
6106
6641
  e.preventDefault();
6107
- var sections = ['overview', 'tasks', 'logs', 'memory', 'learning', 'council', 'cost', 'checkpoint', 'context', 'notifications'];
6642
+ var sections = ['overview', 'tasks', 'logs', 'memory', 'learning', 'prd-checklist', 'app-runner', 'council', 'cost', 'checkpoint', 'context', 'notifications'];
6108
6643
  var idx = e.key === '0' ? 9 : parseInt(e.key) - 1;
6109
6644
  if (idx < sections.length) switchSection(sections[idx]);
6110
6645
  }
@@ -6145,14 +6680,18 @@ document.addEventListener('DOMContentLoaded', function() {
6145
6680
  // Skip if modifier keys are held (let browser defaults work)
6146
6681
  if (e.metaKey || e.ctrlKey || e.altKey) return;
6147
6682
 
6148
- var sections = ['overview', 'tasks', 'logs', 'memory', 'learning', 'council', 'cost', 'checkpoint'];
6683
+ var sections = ['overview', 'tasks', 'logs', 'memory', 'learning', 'prd-checklist', 'app-runner', 'council', 'cost', 'checkpoint', 'context', 'notifications'];
6149
6684
 
6150
6685
  switch (e.key) {
6151
- // Section navigation: 1-8
6152
- case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8':
6686
+ // Section navigation: 1-9, 0
6687
+ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
6153
6688
  e.preventDefault();
6154
6689
  switchSection(sections[parseInt(e.key) - 1]);
6155
6690
  break;
6691
+ case '0':
6692
+ e.preventDefault();
6693
+ switchSection(sections[9]);
6694
+ break;
6156
6695
 
6157
6696
  // Help overlay
6158
6697
  case '?':