loki-mode 7.5.13 → 7.5.15
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.
- package/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/lib/sentrux-gate.sh +145 -0
- package/autonomy/loki +231 -0
- package/autonomy/run.sh +110 -3
- package/dashboard/__init__.py +1 -1
- package/dashboard/server.py +62 -0
- package/dashboard/static/index.html +199 -109
- package/docs/INSTALLATION.md +1 -1
- package/loki-ts/dist/loki.js +144 -142
- package/mcp/__init__.py +1 -1
- package/memory/storage.py +35 -7
- package/package.json +1 -1
|
@@ -566,6 +566,10 @@
|
|
|
566
566
|
<svg viewBox="0 0 24 24"><line x1="18" y1="20" x2="18" y2="10" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><line x1="12" y1="20" x2="12" y2="4" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><line x1="6" y1="20" x2="6" y2="14" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
|
|
567
567
|
Analytics
|
|
568
568
|
</button>
|
|
569
|
+
<button class="nav-link" data-section="escalations" id="nav-escalations">
|
|
570
|
+
<svg viewBox="0 0 24 24"><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
|
|
571
|
+
Escalations
|
|
572
|
+
</button>
|
|
569
573
|
</nav>
|
|
570
574
|
|
|
571
575
|
<div class="sidebar-footer">
|
|
@@ -701,6 +705,14 @@
|
|
|
701
705
|
</div>
|
|
702
706
|
<loki-analytics id="analytics-dashboard"></loki-analytics>
|
|
703
707
|
</div>
|
|
708
|
+
|
|
709
|
+
<!-- Escalations (handoff documents under .loki/escalations/) -->
|
|
710
|
+
<div class="section-page" id="page-escalations">
|
|
711
|
+
<div class="section-page-header">
|
|
712
|
+
<h2 class="section-page-title">Escalations</h2>
|
|
713
|
+
</div>
|
|
714
|
+
<loki-escalations id="escalations-panel"></loki-escalations>
|
|
715
|
+
</div>
|
|
704
716
|
</main>
|
|
705
717
|
</div>
|
|
706
718
|
|
|
@@ -725,6 +737,7 @@
|
|
|
725
737
|
<div class="shortcut-row"><span class="shortcut-desc">Notifications</span><span class="shortcut-keys"><kbd class="shortcut-key">0</kbd></span></div>
|
|
726
738
|
<div class="shortcut-row"><span class="shortcut-desc">Migration</span><span class="shortcut-keys"><kbd class="shortcut-key">m</kbd></span></div>
|
|
727
739
|
<div class="shortcut-row"><span class="shortcut-desc">Analytics</span><span class="shortcut-keys"><kbd class="shortcut-key">a</kbd></span></div>
|
|
740
|
+
<div class="shortcut-row"><span class="shortcut-desc">Escalations</span><span class="shortcut-keys"><kbd class="shortcut-key">e</kbd></span></div>
|
|
728
741
|
</div>
|
|
729
742
|
<div class="shortcuts-group">
|
|
730
743
|
<div class="shortcuts-group-title">Session</div>
|
|
@@ -744,7 +757,7 @@
|
|
|
744
757
|
|
|
745
758
|
<!-- Inlined JavaScript Bundle -->
|
|
746
759
|
<script>
|
|
747
|
-
var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropertyDescriptor;var ee=Object.getOwnPropertyNames;var ie=Object.prototype.hasOwnProperty;var ae=(d,t,e)=>t in d?_t(d,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):d[t]=e;var se=(d,t)=>{for(var e in t)_t(d,e,{get:t[e],enumerable:!0})},re=(d,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of ee(t))!ie.call(d,a)&&a!==e&&_t(d,a,{get:()=>t[a],enumerable:!(i=te(t,a))||i.enumerable});return d};var oe=d=>re(_t({},"__esModule",{value:!0}),d);var C=(d,t,e)=>ae(d,typeof t!="symbol"?t+"":t,e);var He={};se(He,{ANIMATION:()=>L,ARIA_PATTERNS:()=>$t,ApiEvents:()=>v,BASE_STYLES:()=>U,BREAKPOINTS:()=>yt,COMMON_STYLES:()=>Rt,KEYBOARD_SHORTCUTS:()=>wt,KeyboardHandler:()=>M,LokiActivityStream:()=>ht,LokiAgentLeaderboard:()=>kt,LokiAnalytics:()=>ot,LokiApiClient:()=>B,LokiApiKeys:()=>pt,LokiAppStatus:()=>Q,LokiAuditViewer:()=>ct,LokiChecklistViewer:()=>W,LokiCheckpointViewer:()=>Z,LokiContextTracker:()=>tt,LokiCostDashboard:()=>X,LokiCostWaterfall:()=>ft,LokiCouncilDashboard:()=>Y,LokiElement:()=>h,LokiLearningDashboard:()=>V,LokiLogStream:()=>G,LokiManagedMemoryPanel:()=>xt,LokiMemoryBrowser:()=>K,LokiMemoryGraph:()=>bt,LokiMigrationDashboard:()=>rt,LokiNotificationCenter:()=>et,LokiOverview:()=>O,LokiPipelineView:()=>vt,LokiPromptOptimizer:()=>at,LokiProviderHealth:()=>gt,LokiQualityGates:()=>nt,LokiQualityScore:()=>st,LokiRarvTimeline:()=>lt,LokiRunManager:()=>dt,LokiSessionControl:()=>J,LokiSessionDiff:()=>it,LokiState:()=>N,LokiTaskBoard:()=>q,LokiTenantSwitcher:()=>ut,LokiTheme:()=>R,RADIUS:()=>I,SPACING:()=>T,STATE_CHANGE_EVENT:()=>St,THEMES:()=>E,THEME_VARIABLES:()=>Et,TYPOGRAPHY:()=>_,UnifiedThemeManager:()=>x,VERSION:()=>De,Z_INDEX:()=>D,createApiClient:()=>Bt,createStore:()=>Ft,generateThemeCSS:()=>$,generateTokensCSS:()=>j,getApiClient:()=>g,getState:()=>P,init:()=>ze});var E={light:{"--loki-bg-primary":"#FFFEFB","--loki-bg-secondary":"#F8F4F0","--loki-bg-tertiary":"#ECEAE3","--loki-bg-card":"#ffffff","--loki-bg-hover":"#F3EFE9","--loki-bg-active":"#E6E2DA","--loki-bg-overlay":"rgba(32, 21, 21, 0.5)","--loki-accent":"#553DE9","--loki-accent-hover":"#4432c4","--loki-accent-active":"#3828a0","--loki-accent-light":"#7B6BF0","--loki-accent-muted":"rgba(85, 61, 233, 0.10)","--loki-text-primary":"#201515","--loki-text-secondary":"#36342E","--loki-text-muted":"#939084","--loki-text-disabled":"#C5C0B1","--loki-text-inverse":"#ffffff","--loki-border":"#ECEAE3","--loki-border-light":"#C5C0B1","--loki-border-focus":"#553DE9","--loki-success":"#1FC5A8","--loki-success-muted":"rgba(31, 197, 168, 0.12)","--loki-warning":"#D4A03C","--loki-warning-muted":"rgba(212, 160, 60, 0.12)","--loki-error":"#C45B5B","--loki-error-muted":"rgba(196, 91, 91, 0.12)","--loki-info":"#2F71E3","--loki-info-muted":"rgba(47, 113, 227, 0.12)","--loki-green":"#1FC5A8","--loki-green-muted":"rgba(31, 197, 168, 0.12)","--loki-yellow":"#D4A03C","--loki-yellow-muted":"rgba(212, 160, 60, 0.12)","--loki-red":"#C45B5B","--loki-red-muted":"rgba(196, 91, 91, 0.12)","--loki-blue":"#2F71E3","--loki-blue-muted":"rgba(47, 113, 227, 0.12)","--loki-purple":"#553DE9","--loki-purple-muted":"rgba(85, 61, 233, 0.10)","--loki-opus":"#d97706","--loki-sonnet":"#553DE9","--loki-haiku":"#1FC5A8","--loki-shadow-sm":"0 1px 2px rgba(32, 21, 21, 0.04)","--loki-shadow-md":"0 4px 6px rgba(32, 21, 21, 0.06)","--loki-shadow-lg":"0 10px 15px rgba(32, 21, 21, 0.08)","--loki-shadow-focus":"0 0 0 3px rgba(85, 61, 233, 0.25)"},dark:{"--loki-bg-primary":"#1A0F2E","--loki-bg-secondary":"#140B24","--loki-bg-tertiary":"#251842","--loki-bg-card":"#1F1338","--loki-bg-hover":"#2A1F4A","--loki-bg-active":"#352A55","--loki-bg-overlay":"rgba(20, 11, 36, 0.85)","--loki-accent":"#7B6BF0","--loki-accent-hover":"#9488F5","--loki-accent-active":"#6258D0","--loki-accent-light":"#9488F5","--loki-accent-muted":"rgba(123, 107, 240, 0.18)","--loki-text-primary":"#F0ECF8","--loki-text-secondary":"#C0B8D0","--loki-text-muted":"#8B7FA8","--loki-text-disabled":"#5A4E78","--loki-text-inverse":"#1A0F2E","--loki-border":"#2A1F3E","--loki-border-light":"#3D3060","--loki-border-focus":"#7B6BF0","--loki-success":"#2ED8B6","--loki-success-muted":"rgba(46, 216, 182, 0.18)","--loki-warning":"#E8B84A","--loki-warning-muted":"rgba(232, 184, 74, 0.18)","--loki-error":"#E07070","--loki-error-muted":"rgba(224, 112, 112, 0.18)","--loki-info":"#5A9CF5","--loki-info-muted":"rgba(90, 156, 245, 0.18)","--loki-green":"#2ED8B6","--loki-green-muted":"rgba(46, 216, 182, 0.18)","--loki-yellow":"#E8B84A","--loki-yellow-muted":"rgba(232, 184, 74, 0.18)","--loki-red":"#E07070","--loki-red-muted":"rgba(224, 112, 112, 0.18)","--loki-blue":"#5A9CF5","--loki-blue-muted":"rgba(90, 156, 245, 0.18)","--loki-purple":"#9488F5","--loki-purple-muted":"rgba(148, 136, 245, 0.18)","--loki-opus":"#f59e0b","--loki-sonnet":"#7B6BF0","--loki-haiku":"#2ED8B6","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.4)","--loki-shadow-md":"0 4px 12px rgba(0, 0, 0, 0.5)","--loki-shadow-lg":"0 10px 25px rgba(0, 0, 0, 0.6)","--loki-shadow-focus":"0 0 0 3px rgba(123, 107, 240, 0.30)"},"high-contrast":{"--loki-bg-primary":"#000000","--loki-bg-secondary":"#0a0a0a","--loki-bg-tertiary":"#141414","--loki-bg-card":"#0a0a0a","--loki-bg-hover":"#1a1a1a","--loki-bg-active":"#242424","--loki-bg-overlay":"rgba(0, 0, 0, 0.9)","--loki-accent":"#c084fc","--loki-accent-hover":"#d8b4fe","--loki-accent-active":"#e9d5ff","--loki-accent-light":"#d8b4fe","--loki-accent-muted":"rgba(192, 132, 252, 0.25)","--loki-text-primary":"#ffffff","--loki-text-secondary":"#e0e0e0","--loki-text-muted":"#b0b0b0","--loki-text-disabled":"#666666","--loki-text-inverse":"#000000","--loki-border":"#ffffff","--loki-border-light":"#cccccc","--loki-border-focus":"#c084fc","--loki-success":"#4ade80","--loki-success-muted":"rgba(74, 222, 128, 0.25)","--loki-warning":"#fde047","--loki-warning-muted":"rgba(253, 224, 71, 0.25)","--loki-error":"#f87171","--loki-error-muted":"rgba(248, 113, 113, 0.25)","--loki-info":"#60a5fa","--loki-info-muted":"rgba(96, 165, 250, 0.25)","--loki-green":"#4ade80","--loki-green-muted":"rgba(74, 222, 128, 0.25)","--loki-yellow":"#fde047","--loki-yellow-muted":"rgba(253, 224, 71, 0.25)","--loki-red":"#f87171","--loki-red-muted":"rgba(248, 113, 113, 0.25)","--loki-blue":"#60a5fa","--loki-blue-muted":"rgba(96, 165, 250, 0.25)","--loki-purple":"#c084fc","--loki-purple-muted":"rgba(192, 132, 252, 0.25)","--loki-opus":"#fbbf24","--loki-sonnet":"#818cf8","--loki-haiku":"#34d399","--loki-shadow-sm":"none","--loki-shadow-md":"none","--loki-shadow-lg":"none","--loki-shadow-focus":"0 0 0 3px #c084fc"},"vscode-light":{"--loki-bg-primary":"var(--vscode-editor-background, #ffffff)","--loki-bg-secondary":"var(--vscode-sideBar-background, #f3f3f3)","--loki-bg-tertiary":"var(--vscode-input-background, #ffffff)","--loki-bg-card":"var(--vscode-editor-background, #ffffff)","--loki-bg-hover":"var(--vscode-list-hoverBackground, #e8e8e8)","--loki-bg-active":"var(--vscode-list-activeSelectionBackground, #0060c0)","--loki-bg-overlay":"rgba(0, 0, 0, 0.4)","--loki-accent":"var(--vscode-focusBorder, #0066cc)","--loki-accent-hover":"var(--vscode-button-hoverBackground, #0055aa)","--loki-accent-active":"var(--vscode-button-background, #007acc)","--loki-accent-light":"var(--vscode-focusBorder, #0066cc)","--loki-accent-muted":"var(--vscode-editor-selectionBackground, rgba(0, 102, 204, 0.2))","--loki-text-primary":"var(--vscode-foreground, #333333)","--loki-text-secondary":"var(--vscode-descriptionForeground, #717171)","--loki-text-muted":"var(--vscode-disabledForeground, #a0a0a0)","--loki-text-disabled":"var(--vscode-disabledForeground, #cccccc)","--loki-text-inverse":"var(--vscode-button-foreground, #ffffff)","--loki-border":"var(--vscode-widget-border, #c8c8c8)","--loki-border-light":"var(--vscode-widget-border, #e0e0e0)","--loki-border-focus":"var(--vscode-focusBorder, #0066cc)","--loki-success":"var(--vscode-testing-iconPassed, #388a34)","--loki-success-muted":"rgba(56, 138, 52, 0.15)","--loki-warning":"var(--vscode-editorWarning-foreground, #bf8803)","--loki-warning-muted":"rgba(191, 136, 3, 0.15)","--loki-error":"var(--vscode-errorForeground, #e51400)","--loki-error-muted":"rgba(229, 20, 0, 0.15)","--loki-info":"var(--vscode-editorInfo-foreground, #1a85ff)","--loki-info-muted":"rgba(26, 133, 255, 0.15)","--loki-green":"var(--vscode-testing-iconPassed, #388a34)","--loki-green-muted":"rgba(56, 138, 52, 0.15)","--loki-yellow":"var(--vscode-editorWarning-foreground, #bf8803)","--loki-yellow-muted":"rgba(191, 136, 3, 0.15)","--loki-red":"var(--vscode-errorForeground, #e51400)","--loki-red-muted":"rgba(229, 20, 0, 0.15)","--loki-blue":"var(--vscode-editorInfo-foreground, #1a85ff)","--loki-blue-muted":"rgba(26, 133, 255, 0.15)","--loki-purple":"#9333ea","--loki-purple-muted":"rgba(147, 51, 234, 0.15)","--loki-opus":"#d97706","--loki-sonnet":"#4f46e5","--loki-haiku":"#059669","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.05)","--loki-shadow-md":"0 2px 4px rgba(0, 0, 0, 0.1)","--loki-shadow-lg":"0 4px 8px rgba(0, 0, 0, 0.15)","--loki-shadow-focus":"0 0 0 2px var(--vscode-focusBorder, #0066cc)"},"vscode-dark":{"--loki-bg-primary":"var(--vscode-editor-background, #1e1e1e)","--loki-bg-secondary":"var(--vscode-sideBar-background, #252526)","--loki-bg-tertiary":"var(--vscode-input-background, #3c3c3c)","--loki-bg-card":"var(--vscode-editor-background, #1e1e1e)","--loki-bg-hover":"var(--vscode-list-hoverBackground, #2a2d2e)","--loki-bg-active":"var(--vscode-list-activeSelectionBackground, #094771)","--loki-bg-overlay":"rgba(0, 0, 0, 0.6)","--loki-accent":"var(--vscode-focusBorder, #007fd4)","--loki-accent-hover":"var(--vscode-button-hoverBackground, #1177bb)","--loki-accent-active":"var(--vscode-button-background, #0e639c)","--loki-accent-light":"var(--vscode-focusBorder, #007fd4)","--loki-accent-muted":"var(--vscode-editor-selectionBackground, rgba(0, 127, 212, 0.25))","--loki-text-primary":"var(--vscode-foreground, #cccccc)","--loki-text-secondary":"var(--vscode-descriptionForeground, #9d9d9d)","--loki-text-muted":"var(--vscode-disabledForeground, #6b6b6b)","--loki-text-disabled":"var(--vscode-disabledForeground, #4d4d4d)","--loki-text-inverse":"var(--vscode-button-foreground, #ffffff)","--loki-border":"var(--vscode-widget-border, #454545)","--loki-border-light":"var(--vscode-widget-border, #5a5a5a)","--loki-border-focus":"var(--vscode-focusBorder, #007fd4)","--loki-success":"var(--vscode-testing-iconPassed, #89d185)","--loki-success-muted":"rgba(137, 209, 133, 0.2)","--loki-warning":"var(--vscode-editorWarning-foreground, #cca700)","--loki-warning-muted":"rgba(204, 167, 0, 0.2)","--loki-error":"var(--vscode-errorForeground, #f48771)","--loki-error-muted":"rgba(244, 135, 113, 0.2)","--loki-info":"var(--vscode-editorInfo-foreground, #75beff)","--loki-info-muted":"rgba(117, 190, 255, 0.2)","--loki-green":"var(--vscode-testing-iconPassed, #89d185)","--loki-green-muted":"rgba(137, 209, 133, 0.2)","--loki-yellow":"var(--vscode-editorWarning-foreground, #cca700)","--loki-yellow-muted":"rgba(204, 167, 0, 0.2)","--loki-red":"var(--vscode-errorForeground, #f48771)","--loki-red-muted":"rgba(244, 135, 113, 0.2)","--loki-blue":"var(--vscode-editorInfo-foreground, #75beff)","--loki-blue-muted":"rgba(117, 190, 255, 0.2)","--loki-purple":"#c084fc","--loki-purple-muted":"rgba(192, 132, 252, 0.2)","--loki-opus":"#f59e0b","--loki-sonnet":"#818cf8","--loki-haiku":"#34d399","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.3)","--loki-shadow-md":"0 2px 4px rgba(0, 0, 0, 0.4)","--loki-shadow-lg":"0 4px 8px rgba(0, 0, 0, 0.5)","--loki-shadow-focus":"0 0 0 2px var(--vscode-focusBorder, #007fd4)"}},T={xs:"4px",sm:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"32px","3xl":"48px"},I={none:"0",sm:"2px",md:"4px",lg:"5px",xl:"5px",full:"9999px"},_={fontFamily:{sans:"'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif",serif:"'DM Serif Display', Georgia, 'Times New Roman', serif",mono:"'JetBrains Mono', 'Fira Code', 'SF Mono', Menlo, monospace"},fontSize:{xs:"10px",sm:"11px",base:"12px",md:"13px",lg:"14px",xl:"16px","2xl":"18px","3xl":"24px"},fontWeight:{normal:"400",medium:"500",semibold:"600",bold:"700"},lineHeight:{tight:"1.25",normal:"1.5",relaxed:"1.75"}},L={duration:{fast:"100ms",normal:"200ms",slow:"300ms",slower:"500ms"},easing:{default:"cubic-bezier(0.4, 0, 0.2, 1)",in:"cubic-bezier(0.4, 0, 1, 1)",out:"cubic-bezier(0, 0, 0.2, 1)",bounce:"cubic-bezier(0.68, -0.55, 0.265, 1.55)"}},yt={sm:"640px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},D={base:"0",dropdown:"100",sticky:"200",modal:"300",popover:"400",tooltip:"500",toast:"600"},wt={"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"]}},$t={button:{role:"button",tabIndex:0},tablist:{role:"tablist"},tab:{role:"tab",ariaSelected:!1,tabIndex:-1},tabpanel:{role:"tabpanel",tabIndex:0},list:{role:"list"},listitem:{role:"listitem"},livePolite:{ariaLive:"polite",ariaAtomic:!0},liveAssertive:{ariaLive:"assertive",ariaAtomic:!0},dialog:{role:"dialog",ariaModal:!0},alertdialog:{role:"alertdialog",ariaModal:!0},status:{role:"status",ariaLive:"polite"},alert:{role:"alert",ariaLive:"assertive"},log:{role:"log",ariaLive:"polite",ariaRelevant:"additions"}};function $(d){let t=E[d];return t?Object.entries(t).map(([e,i])=>`${e}: ${i};`).join(`
|
|
760
|
+
var LokiDashboard=(()=>{var yt=Object.defineProperty;var ee=Object.getOwnPropertyDescriptor;var ie=Object.getOwnPropertyNames;var ae=Object.prototype.hasOwnProperty;var se=(d,t,e)=>t in d?yt(d,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):d[t]=e;var re=(d,t)=>{for(var e in t)yt(d,e,{get:t[e],enumerable:!0})},oe=(d,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of ie(t))!ae.call(d,a)&&a!==e&&yt(d,a,{get:()=>t[a],enumerable:!(i=ee(t,a))||i.enumerable});return d};var ne=d=>oe(yt({},"__esModule",{value:!0}),d);var C=(d,t,e)=>se(d,typeof t!="symbol"?t+"":t,e);var Re={};re(Re,{ANIMATION:()=>L,ARIA_PATTERNS:()=>Et,ApiEvents:()=>v,BASE_STYLES:()=>U,BREAKPOINTS:()=>wt,COMMON_STYLES:()=>Pt,KEYBOARD_SHORTCUTS:()=>$t,KeyboardHandler:()=>B,LokiActivityStream:()=>ht,LokiAgentLeaderboard:()=>kt,LokiAnalytics:()=>ot,LokiApiClient:()=>M,LokiApiKeys:()=>pt,LokiAppStatus:()=>Q,LokiAuditViewer:()=>ct,LokiChecklistViewer:()=>W,LokiCheckpointViewer:()=>Z,LokiContextTracker:()=>tt,LokiCostDashboard:()=>X,LokiCostWaterfall:()=>ft,LokiCouncilDashboard:()=>Y,LokiElement:()=>u,LokiEscalations:()=>_t,LokiLearningDashboard:()=>V,LokiLogStream:()=>G,LokiManagedMemoryPanel:()=>xt,LokiMemoryBrowser:()=>K,LokiMemoryGraph:()=>bt,LokiMigrationDashboard:()=>rt,LokiNotificationCenter:()=>et,LokiOverview:()=>O,LokiPipelineView:()=>vt,LokiPromptOptimizer:()=>at,LokiProviderHealth:()=>gt,LokiQualityGates:()=>nt,LokiQualityScore:()=>st,LokiRarvTimeline:()=>lt,LokiRunManager:()=>dt,LokiSessionControl:()=>J,LokiSessionDiff:()=>it,LokiState:()=>N,LokiTaskBoard:()=>q,LokiTenantSwitcher:()=>ut,LokiTheme:()=>R,RADIUS:()=>I,SPACING:()=>T,STATE_CHANGE_EVENT:()=>Tt,THEMES:()=>E,THEME_VARIABLES:()=>Ct,TYPOGRAPHY:()=>_,UnifiedThemeManager:()=>x,VERSION:()=>ze,Z_INDEX:()=>D,createApiClient:()=>Ft,createStore:()=>jt,generateThemeCSS:()=>$,generateTokensCSS:()=>j,getApiClient:()=>g,getState:()=>P,init:()=>He});var E={light:{"--loki-bg-primary":"#FFFEFB","--loki-bg-secondary":"#F8F4F0","--loki-bg-tertiary":"#ECEAE3","--loki-bg-card":"#ffffff","--loki-bg-hover":"#F3EFE9","--loki-bg-active":"#E6E2DA","--loki-bg-overlay":"rgba(32, 21, 21, 0.5)","--loki-accent":"#553DE9","--loki-accent-hover":"#4432c4","--loki-accent-active":"#3828a0","--loki-accent-light":"#7B6BF0","--loki-accent-muted":"rgba(85, 61, 233, 0.10)","--loki-text-primary":"#201515","--loki-text-secondary":"#36342E","--loki-text-muted":"#939084","--loki-text-disabled":"#C5C0B1","--loki-text-inverse":"#ffffff","--loki-border":"#ECEAE3","--loki-border-light":"#C5C0B1","--loki-border-focus":"#553DE9","--loki-success":"#1FC5A8","--loki-success-muted":"rgba(31, 197, 168, 0.12)","--loki-warning":"#D4A03C","--loki-warning-muted":"rgba(212, 160, 60, 0.12)","--loki-error":"#C45B5B","--loki-error-muted":"rgba(196, 91, 91, 0.12)","--loki-info":"#2F71E3","--loki-info-muted":"rgba(47, 113, 227, 0.12)","--loki-green":"#1FC5A8","--loki-green-muted":"rgba(31, 197, 168, 0.12)","--loki-yellow":"#D4A03C","--loki-yellow-muted":"rgba(212, 160, 60, 0.12)","--loki-red":"#C45B5B","--loki-red-muted":"rgba(196, 91, 91, 0.12)","--loki-blue":"#2F71E3","--loki-blue-muted":"rgba(47, 113, 227, 0.12)","--loki-purple":"#553DE9","--loki-purple-muted":"rgba(85, 61, 233, 0.10)","--loki-opus":"#d97706","--loki-sonnet":"#553DE9","--loki-haiku":"#1FC5A8","--loki-shadow-sm":"0 1px 2px rgba(32, 21, 21, 0.04)","--loki-shadow-md":"0 4px 6px rgba(32, 21, 21, 0.06)","--loki-shadow-lg":"0 10px 15px rgba(32, 21, 21, 0.08)","--loki-shadow-focus":"0 0 0 3px rgba(85, 61, 233, 0.25)"},dark:{"--loki-bg-primary":"#1A0F2E","--loki-bg-secondary":"#140B24","--loki-bg-tertiary":"#251842","--loki-bg-card":"#1F1338","--loki-bg-hover":"#2A1F4A","--loki-bg-active":"#352A55","--loki-bg-overlay":"rgba(20, 11, 36, 0.85)","--loki-accent":"#7B6BF0","--loki-accent-hover":"#9488F5","--loki-accent-active":"#6258D0","--loki-accent-light":"#9488F5","--loki-accent-muted":"rgba(123, 107, 240, 0.18)","--loki-text-primary":"#F0ECF8","--loki-text-secondary":"#C0B8D0","--loki-text-muted":"#8B7FA8","--loki-text-disabled":"#5A4E78","--loki-text-inverse":"#1A0F2E","--loki-border":"#2A1F3E","--loki-border-light":"#3D3060","--loki-border-focus":"#7B6BF0","--loki-success":"#2ED8B6","--loki-success-muted":"rgba(46, 216, 182, 0.18)","--loki-warning":"#E8B84A","--loki-warning-muted":"rgba(232, 184, 74, 0.18)","--loki-error":"#E07070","--loki-error-muted":"rgba(224, 112, 112, 0.18)","--loki-info":"#5A9CF5","--loki-info-muted":"rgba(90, 156, 245, 0.18)","--loki-green":"#2ED8B6","--loki-green-muted":"rgba(46, 216, 182, 0.18)","--loki-yellow":"#E8B84A","--loki-yellow-muted":"rgba(232, 184, 74, 0.18)","--loki-red":"#E07070","--loki-red-muted":"rgba(224, 112, 112, 0.18)","--loki-blue":"#5A9CF5","--loki-blue-muted":"rgba(90, 156, 245, 0.18)","--loki-purple":"#9488F5","--loki-purple-muted":"rgba(148, 136, 245, 0.18)","--loki-opus":"#f59e0b","--loki-sonnet":"#7B6BF0","--loki-haiku":"#2ED8B6","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.4)","--loki-shadow-md":"0 4px 12px rgba(0, 0, 0, 0.5)","--loki-shadow-lg":"0 10px 25px rgba(0, 0, 0, 0.6)","--loki-shadow-focus":"0 0 0 3px rgba(123, 107, 240, 0.30)"},"high-contrast":{"--loki-bg-primary":"#000000","--loki-bg-secondary":"#0a0a0a","--loki-bg-tertiary":"#141414","--loki-bg-card":"#0a0a0a","--loki-bg-hover":"#1a1a1a","--loki-bg-active":"#242424","--loki-bg-overlay":"rgba(0, 0, 0, 0.9)","--loki-accent":"#c084fc","--loki-accent-hover":"#d8b4fe","--loki-accent-active":"#e9d5ff","--loki-accent-light":"#d8b4fe","--loki-accent-muted":"rgba(192, 132, 252, 0.25)","--loki-text-primary":"#ffffff","--loki-text-secondary":"#e0e0e0","--loki-text-muted":"#b0b0b0","--loki-text-disabled":"#666666","--loki-text-inverse":"#000000","--loki-border":"#ffffff","--loki-border-light":"#cccccc","--loki-border-focus":"#c084fc","--loki-success":"#4ade80","--loki-success-muted":"rgba(74, 222, 128, 0.25)","--loki-warning":"#fde047","--loki-warning-muted":"rgba(253, 224, 71, 0.25)","--loki-error":"#f87171","--loki-error-muted":"rgba(248, 113, 113, 0.25)","--loki-info":"#60a5fa","--loki-info-muted":"rgba(96, 165, 250, 0.25)","--loki-green":"#4ade80","--loki-green-muted":"rgba(74, 222, 128, 0.25)","--loki-yellow":"#fde047","--loki-yellow-muted":"rgba(253, 224, 71, 0.25)","--loki-red":"#f87171","--loki-red-muted":"rgba(248, 113, 113, 0.25)","--loki-blue":"#60a5fa","--loki-blue-muted":"rgba(96, 165, 250, 0.25)","--loki-purple":"#c084fc","--loki-purple-muted":"rgba(192, 132, 252, 0.25)","--loki-opus":"#fbbf24","--loki-sonnet":"#818cf8","--loki-haiku":"#34d399","--loki-shadow-sm":"none","--loki-shadow-md":"none","--loki-shadow-lg":"none","--loki-shadow-focus":"0 0 0 3px #c084fc"},"vscode-light":{"--loki-bg-primary":"var(--vscode-editor-background, #ffffff)","--loki-bg-secondary":"var(--vscode-sideBar-background, #f3f3f3)","--loki-bg-tertiary":"var(--vscode-input-background, #ffffff)","--loki-bg-card":"var(--vscode-editor-background, #ffffff)","--loki-bg-hover":"var(--vscode-list-hoverBackground, #e8e8e8)","--loki-bg-active":"var(--vscode-list-activeSelectionBackground, #0060c0)","--loki-bg-overlay":"rgba(0, 0, 0, 0.4)","--loki-accent":"var(--vscode-focusBorder, #0066cc)","--loki-accent-hover":"var(--vscode-button-hoverBackground, #0055aa)","--loki-accent-active":"var(--vscode-button-background, #007acc)","--loki-accent-light":"var(--vscode-focusBorder, #0066cc)","--loki-accent-muted":"var(--vscode-editor-selectionBackground, rgba(0, 102, 204, 0.2))","--loki-text-primary":"var(--vscode-foreground, #333333)","--loki-text-secondary":"var(--vscode-descriptionForeground, #717171)","--loki-text-muted":"var(--vscode-disabledForeground, #a0a0a0)","--loki-text-disabled":"var(--vscode-disabledForeground, #cccccc)","--loki-text-inverse":"var(--vscode-button-foreground, #ffffff)","--loki-border":"var(--vscode-widget-border, #c8c8c8)","--loki-border-light":"var(--vscode-widget-border, #e0e0e0)","--loki-border-focus":"var(--vscode-focusBorder, #0066cc)","--loki-success":"var(--vscode-testing-iconPassed, #388a34)","--loki-success-muted":"rgba(56, 138, 52, 0.15)","--loki-warning":"var(--vscode-editorWarning-foreground, #bf8803)","--loki-warning-muted":"rgba(191, 136, 3, 0.15)","--loki-error":"var(--vscode-errorForeground, #e51400)","--loki-error-muted":"rgba(229, 20, 0, 0.15)","--loki-info":"var(--vscode-editorInfo-foreground, #1a85ff)","--loki-info-muted":"rgba(26, 133, 255, 0.15)","--loki-green":"var(--vscode-testing-iconPassed, #388a34)","--loki-green-muted":"rgba(56, 138, 52, 0.15)","--loki-yellow":"var(--vscode-editorWarning-foreground, #bf8803)","--loki-yellow-muted":"rgba(191, 136, 3, 0.15)","--loki-red":"var(--vscode-errorForeground, #e51400)","--loki-red-muted":"rgba(229, 20, 0, 0.15)","--loki-blue":"var(--vscode-editorInfo-foreground, #1a85ff)","--loki-blue-muted":"rgba(26, 133, 255, 0.15)","--loki-purple":"#9333ea","--loki-purple-muted":"rgba(147, 51, 234, 0.15)","--loki-opus":"#d97706","--loki-sonnet":"#4f46e5","--loki-haiku":"#059669","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.05)","--loki-shadow-md":"0 2px 4px rgba(0, 0, 0, 0.1)","--loki-shadow-lg":"0 4px 8px rgba(0, 0, 0, 0.15)","--loki-shadow-focus":"0 0 0 2px var(--vscode-focusBorder, #0066cc)"},"vscode-dark":{"--loki-bg-primary":"var(--vscode-editor-background, #1e1e1e)","--loki-bg-secondary":"var(--vscode-sideBar-background, #252526)","--loki-bg-tertiary":"var(--vscode-input-background, #3c3c3c)","--loki-bg-card":"var(--vscode-editor-background, #1e1e1e)","--loki-bg-hover":"var(--vscode-list-hoverBackground, #2a2d2e)","--loki-bg-active":"var(--vscode-list-activeSelectionBackground, #094771)","--loki-bg-overlay":"rgba(0, 0, 0, 0.6)","--loki-accent":"var(--vscode-focusBorder, #007fd4)","--loki-accent-hover":"var(--vscode-button-hoverBackground, #1177bb)","--loki-accent-active":"var(--vscode-button-background, #0e639c)","--loki-accent-light":"var(--vscode-focusBorder, #007fd4)","--loki-accent-muted":"var(--vscode-editor-selectionBackground, rgba(0, 127, 212, 0.25))","--loki-text-primary":"var(--vscode-foreground, #cccccc)","--loki-text-secondary":"var(--vscode-descriptionForeground, #9d9d9d)","--loki-text-muted":"var(--vscode-disabledForeground, #6b6b6b)","--loki-text-disabled":"var(--vscode-disabledForeground, #4d4d4d)","--loki-text-inverse":"var(--vscode-button-foreground, #ffffff)","--loki-border":"var(--vscode-widget-border, #454545)","--loki-border-light":"var(--vscode-widget-border, #5a5a5a)","--loki-border-focus":"var(--vscode-focusBorder, #007fd4)","--loki-success":"var(--vscode-testing-iconPassed, #89d185)","--loki-success-muted":"rgba(137, 209, 133, 0.2)","--loki-warning":"var(--vscode-editorWarning-foreground, #cca700)","--loki-warning-muted":"rgba(204, 167, 0, 0.2)","--loki-error":"var(--vscode-errorForeground, #f48771)","--loki-error-muted":"rgba(244, 135, 113, 0.2)","--loki-info":"var(--vscode-editorInfo-foreground, #75beff)","--loki-info-muted":"rgba(117, 190, 255, 0.2)","--loki-green":"var(--vscode-testing-iconPassed, #89d185)","--loki-green-muted":"rgba(137, 209, 133, 0.2)","--loki-yellow":"var(--vscode-editorWarning-foreground, #cca700)","--loki-yellow-muted":"rgba(204, 167, 0, 0.2)","--loki-red":"var(--vscode-errorForeground, #f48771)","--loki-red-muted":"rgba(244, 135, 113, 0.2)","--loki-blue":"var(--vscode-editorInfo-foreground, #75beff)","--loki-blue-muted":"rgba(117, 190, 255, 0.2)","--loki-purple":"#c084fc","--loki-purple-muted":"rgba(192, 132, 252, 0.2)","--loki-opus":"#f59e0b","--loki-sonnet":"#818cf8","--loki-haiku":"#34d399","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.3)","--loki-shadow-md":"0 2px 4px rgba(0, 0, 0, 0.4)","--loki-shadow-lg":"0 4px 8px rgba(0, 0, 0, 0.5)","--loki-shadow-focus":"0 0 0 2px var(--vscode-focusBorder, #007fd4)"}},T={xs:"4px",sm:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"32px","3xl":"48px"},I={none:"0",sm:"2px",md:"4px",lg:"5px",xl:"5px",full:"9999px"},_={fontFamily:{sans:"'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif",serif:"'DM Serif Display', Georgia, 'Times New Roman', serif",mono:"'JetBrains Mono', 'Fira Code', 'SF Mono', Menlo, monospace"},fontSize:{xs:"10px",sm:"11px",base:"12px",md:"13px",lg:"14px",xl:"16px","2xl":"18px","3xl":"24px"},fontWeight:{normal:"400",medium:"500",semibold:"600",bold:"700"},lineHeight:{tight:"1.25",normal:"1.5",relaxed:"1.75"}},L={duration:{fast:"100ms",normal:"200ms",slow:"300ms",slower:"500ms"},easing:{default:"cubic-bezier(0.4, 0, 0.2, 1)",in:"cubic-bezier(0.4, 0, 1, 1)",out:"cubic-bezier(0, 0, 0.2, 1)",bounce:"cubic-bezier(0.68, -0.55, 0.265, 1.55)"}},wt={sm:"640px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},D={base:"0",dropdown:"100",sticky:"200",modal:"300",popover:"400",tooltip:"500",toast:"600"},$t={"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"]}},Et={button:{role:"button",tabIndex:0},tablist:{role:"tablist"},tab:{role:"tab",ariaSelected:!1,tabIndex:-1},tabpanel:{role:"tabpanel",tabIndex:0},list:{role:"list"},listitem:{role:"listitem"},livePolite:{ariaLive:"polite",ariaAtomic:!0},liveAssertive:{ariaLive:"assertive",ariaAtomic:!0},dialog:{role:"dialog",ariaModal:!0},alertdialog:{role:"alertdialog",ariaModal:!0},status:{role:"status",ariaLive:"polite"},alert:{role:"alert",ariaLive:"assertive"},log:{role:"log",ariaLive:"polite",ariaRelevant:"additions"}};function $(d){let t=E[d];return t?Object.entries(t).map(([e,i])=>`${e}: ${i};`).join(`
|
|
748
761
|
`):""}function j(){return`
|
|
749
762
|
/* Spacing */
|
|
750
763
|
--loki-space-xs: ${T.xs};
|
|
@@ -1071,11 +1084,11 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
1071
1084
|
}
|
|
1072
1085
|
|
|
1073
1086
|
/* Responsive utilities */
|
|
1074
|
-
@media (max-width: ${
|
|
1087
|
+
@media (max-width: ${wt.md}) {
|
|
1075
1088
|
.hide-mobile { display: none !important; }
|
|
1076
1089
|
}
|
|
1077
1090
|
|
|
1078
|
-
@media (min-width: ${
|
|
1091
|
+
@media (min-width: ${wt.md}) {
|
|
1079
1092
|
.hide-desktop { display: none !important; }
|
|
1080
1093
|
}
|
|
1081
1094
|
`,k=class k{static detectContext(){return typeof acquireVsCodeApi<"u"||document.body.classList.contains("vscode-body")||getComputedStyle(document.documentElement).getPropertyValue("--vscode-editor-background")?"vscode":document.documentElement.dataset.lokiContext==="cli"?"cli":"browser"}static detectVSCodeTheme(){let t=document.body;if(t.classList.contains("vscode-high-contrast"))return"high-contrast";if(t.classList.contains("vscode-dark"))return"dark";if(t.classList.contains("vscode-light"))return"light";let e=getComputedStyle(document.documentElement).getPropertyValue("--vscode-editor-background");if(e){let i=e.match(/\d+/g);if(i)return(parseInt(i[0])*299+parseInt(i[1])*587+parseInt(i[2])*114)/1e3>128?"light":"dark"}return null}static getTheme(){if(k.detectContext()==="vscode"){let i=k.detectVSCodeTheme();return i==="high-contrast"?"high-contrast":i==="dark"?"vscode-dark":"vscode-light"}let e=localStorage.getItem(k.STORAGE_KEY);return e&&E[e]?e:window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}static setTheme(t){if(!E[t]){console.warn(`Unknown theme: ${t}`);return}localStorage.setItem(k.STORAGE_KEY,t),document.documentElement.setAttribute("data-loki-theme",t),window.dispatchEvent(new CustomEvent("loki-theme-change",{detail:{theme:t,context:k.detectContext()}}))}static toggle(){let t=k.getTheme(),e;return t.includes("dark")||t==="high-contrast"?e=t.startsWith("vscode")?"vscode-light":"light":e=t.startsWith("vscode")?"vscode-dark":"dark",k.setTheme(e),e}static getVariables(t=null){let e=t||k.getTheme();return E[e]||E.light}static generateCSS(t=null){let e=t||k.getTheme();return`
|
|
@@ -1084,7 +1097,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
1084
1097
|
${j()}
|
|
1085
1098
|
}
|
|
1086
1099
|
${U}
|
|
1087
|
-
`}static init(){let t=k.getTheme();document.documentElement.setAttribute("data-loki-theme",t),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",()=>{localStorage.getItem(k.STORAGE_KEY)||k.setTheme(k.getTheme())}),k.detectContext()==="vscode"&&new MutationObserver(()=>{let i=k.getTheme();document.documentElement.setAttribute("data-loki-theme",i),window.dispatchEvent(new CustomEvent("loki-theme-change",{detail:{theme:i,context:"vscode"}}))}).observe(document.body,{attributes:!0,attributeFilter:["class"]})}};C(k,"STORAGE_KEY","loki-theme"),C(k,"CONTEXT_KEY","loki-context");var x=k,
|
|
1100
|
+
`}static init(){let t=k.getTheme();document.documentElement.setAttribute("data-loki-theme",t),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",()=>{localStorage.getItem(k.STORAGE_KEY)||k.setTheme(k.getTheme())}),k.detectContext()==="vscode"&&new MutationObserver(()=>{let i=k.getTheme();document.documentElement.setAttribute("data-loki-theme",i),window.dispatchEvent(new CustomEvent("loki-theme-change",{detail:{theme:i,context:"vscode"}}))}).observe(document.body,{attributes:!0,attributeFilter:["class"]})}};C(k,"STORAGE_KEY","loki-theme"),C(k,"CONTEXT_KEY","loki-context");var x=k,B=class{constructor(){this._handlers=new Map,this._enabled=!0}register(t,e){let i=$t[t];if(!i){console.warn(`Unknown keyboard action: ${t}`);return}this._handlers.set(t,{shortcut:i,handler:e})}unregister(t){this._handlers.delete(t)}setEnabled(t){this._enabled=t}handleEvent(t){if(!this._enabled)return!1;for(let[e,{shortcut:i,handler:a}]of this._handlers)if(this._matchesShortcut(t,i))return t.preventDefault(),t.stopPropagation(),a(t),!0;return!1}_matchesShortcut(t,e){let i=t.key.toLowerCase(),a=e.modifiers||[];if(i!==e.key.toLowerCase())return!1;let s=a.includes("Ctrl")||a.includes("Meta"),r=a.includes("Shift"),o=a.includes("Alt"),n=(t.ctrlKey||t.metaKey)===s,l=t.shiftKey===r,c=t.altKey===o;return n&&l&&c}attach(t){this._boundHandler||(this._boundHandler=e=>this.handleEvent(e)),t.addEventListener("keydown",this._boundHandler)}detach(t){this._boundHandler&&t.removeEventListener("keydown",this._boundHandler)}};var Ct={light:{"--loki-bg-primary":"#FFFEFB","--loki-bg-secondary":"#F8F4F0","--loki-bg-tertiary":"#ECEAE3","--loki-bg-card":"#ffffff","--loki-bg-hover":"#F3EFE9","--loki-accent":"#553DE9","--loki-accent-light":"#7B6BF0","--loki-accent-muted":"rgba(85, 61, 233, 0.10)","--loki-text-primary":"#201515","--loki-text-secondary":"#36342E","--loki-text-muted":"#939084","--loki-border":"#ECEAE3","--loki-border-light":"#C5C0B1","--loki-green":"#1FC5A8","--loki-green-muted":"rgba(31, 197, 168, 0.12)","--loki-yellow":"#D4A03C","--loki-yellow-muted":"rgba(212, 160, 60, 0.12)","--loki-red":"#C45B5B","--loki-red-muted":"rgba(196, 91, 91, 0.12)","--loki-blue":"#2F71E3","--loki-blue-muted":"rgba(47, 113, 227, 0.12)","--loki-purple":"#553DE9","--loki-purple-muted":"rgba(85, 61, 233, 0.10)","--loki-opus":"#d97706","--loki-sonnet":"#553DE9","--loki-haiku":"#1FC5A8","--loki-transition":"0.2s cubic-bezier(0.4, 0, 0.2, 1)"},dark:{"--loki-bg-primary":"#1A0F2E","--loki-bg-secondary":"#140B24","--loki-bg-tertiary":"#251842","--loki-bg-card":"#1F1338","--loki-bg-hover":"#2A1F4A","--loki-accent":"#7B6BF0","--loki-accent-light":"#9488F5","--loki-accent-muted":"rgba(123, 107, 240, 0.18)","--loki-text-primary":"#F0ECF8","--loki-text-secondary":"#C0B8D0","--loki-text-muted":"#8B7FA8","--loki-border":"#2A1F3E","--loki-border-light":"#3D3060","--loki-green":"#2ED8B6","--loki-green-muted":"rgba(46, 216, 182, 0.18)","--loki-yellow":"#E8B84A","--loki-yellow-muted":"rgba(232, 184, 74, 0.18)","--loki-red":"#E07070","--loki-red-muted":"rgba(224, 112, 112, 0.18)","--loki-blue":"#5A9CF5","--loki-blue-muted":"rgba(90, 156, 245, 0.18)","--loki-purple":"#9488F5","--loki-purple-muted":"rgba(148, 136, 245, 0.18)","--loki-opus":"#f59e0b","--loki-sonnet":"#7B6BF0","--loki-haiku":"#2ED8B6","--loki-transition":"0.2s cubic-bezier(0.4, 0, 0.2, 1)"}},Pt=`
|
|
1088
1101
|
:host {
|
|
1089
1102
|
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
|
1090
1103
|
line-height: 1.5;
|
|
@@ -1180,8 +1193,8 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
1180
1193
|
::-webkit-scrollbar-track { background: var(--loki-bg-primary); }
|
|
1181
1194
|
::-webkit-scrollbar-thumb { background: var(--loki-border); border-radius: 3px; }
|
|
1182
1195
|
::-webkit-scrollbar-thumb:hover { background: var(--loki-border-light); }
|
|
1183
|
-
`,H=class H{static getTheme(){return x.getTheme()}static setTheme(t){x.setTheme(t)}static toggle(){return x.toggle()}static getVariables(t=null){let e=t||H.getTheme();return E[e]||
|
|
1184
|
-
`)}static applyToElement(t,e=null){let i=H.getVariables(e);for(let[a,s]of Object.entries(i))t.style.setProperty(a,s)}static init(){x.init()}static detectContext(){return x.detectContext()}static getAvailableThemes(){return Object.keys(E)}};C(H,"STORAGE_KEY","loki-theme");var R=H,
|
|
1196
|
+
`,H=class H{static getTheme(){return x.getTheme()}static setTheme(t){x.setTheme(t)}static toggle(){return x.toggle()}static getVariables(t=null){let e=t||H.getTheme();return E[e]||Ct[e]||Ct.light}static toCSSString(t=null){let e=t||H.getTheme();if(E[e])return $(e);let i=H.getVariables(e);return Object.entries(i).map(([a,s])=>`${a}: ${s};`).join(`
|
|
1197
|
+
`)}static applyToElement(t,e=null){let i=H.getVariables(e);for(let[a,s]of Object.entries(i))t.style.setProperty(a,s)}static init(){x.init()}static detectContext(){return x.detectContext()}static getAvailableThemes(){return Object.keys(E)}};C(H,"STORAGE_KEY","loki-theme");var R=H,u=class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}),this._theme=R.getTheme(),this._themeChangeHandler=this._onThemeChange.bind(this),this._keyboardHandler=new B}connectedCallback(){window.addEventListener("loki-theme-change",this._themeChangeHandler),this._applyTheme(),this._setupKeyboardHandling(),this.render()}disconnectedCallback(){window.removeEventListener("loki-theme-change",this._themeChangeHandler),this._keyboardHandler.detach(this)}_onThemeChange(t){this._theme=t.detail.theme,this._applyTheme(),this.onThemeChange&&this.onThemeChange(this._theme)}_applyTheme(){R.applyToElement(this.shadowRoot.host,this._theme),this.setAttribute("data-loki-theme",this._theme)}_setupKeyboardHandling(){this._keyboardHandler.attach(this)}registerShortcut(t,e){this._keyboardHandler.register(t,e)}getBaseStyles(){return`
|
|
1185
1198
|
/* Design tokens */
|
|
1186
1199
|
:host {
|
|
1187
1200
|
${j()}
|
|
@@ -1237,7 +1250,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
1237
1250
|
}
|
|
1238
1251
|
|
|
1239
1252
|
${U}
|
|
1240
|
-
`}getAriaPattern(t){return $t[t]||{}}applyAriaPattern(t,e){let i=this.getAriaPattern(e);for(let[a,s]of Object.entries(i))if(a==="role")t.setAttribute("role",s);else{let r=a.replace(/([A-Z])/g,"-$1").toLowerCase();t.setAttribute(r,s)}}render(){}};var z={realtime:1e3,normal:2e3,background:5e3,offline:1e4},Pt={vscode:z.normal,browser:z.realtime,cli:z.background},Mt={baseUrl:typeof window<"u"?window.location.origin:"http://localhost:57374",wsUrl:typeof window<"u"?`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/ws`:"ws://localhost:57374/ws",pollInterval:2e3,timeout:1e4,retryAttempts:3,retryDelay:1e3},v={CONNECTED:"api:connected",DISCONNECTED:"api:disconnected",ERROR:"api:error",STATUS_UPDATE:"api:status-update",TASK_CREATED:"api:task-created",TASK_UPDATED:"api:task-updated",TASK_DELETED:"api:task-deleted",PROJECT_CREATED:"api:project-created",PROJECT_UPDATED:"api:project-updated",AGENT_UPDATE:"api:agent-update",LOG_MESSAGE:"api:log-message",MEMORY_UPDATE:"api:memory-update",CHECKLIST_UPDATE:"api:checklist-update"},A=class A extends EventTarget{static getInstance(t={}){let e=t.baseUrl||Mt.baseUrl;return A._instances.has(e)||A._instances.set(e,new A(t)),A._instances.get(e)}static clearInstances(){A._instances.forEach(t=>t.disconnect()),A._instances.clear()}constructor(t={}){super(),this.config={...Mt,...t},this._ws=null,this._connected=!1,this._pollInterval=null,this._reconnectTimeout=null,this._reconnectAttempts=0,this._maxReconnectAttempts=20,this._cache=new Map,this._cacheTimeout=5e3,this._vscodeApi=null,this._context=this._detectContext(),this._currentPollInterval=Pt[this._context]||z.normal,this._visibilityChangeHandler=null,this._messageHandler=null,this._setupAdaptivePolling(),this._setupVSCodeBridge()}_detectContext(){return typeof acquireVsCodeApi<"u"?"vscode":typeof window<"u"&&window.location?"browser":"cli"}get context(){return this._context}static get POLL_INTERVALS(){return z}_setupAdaptivePolling(){typeof document>"u"||(this._visibilityChangeHandler=()=>{document.hidden?this._setPollInterval(z.background):this._setPollInterval(Pt[this._context]||z.normal)},document.addEventListener("visibilitychange",this._visibilityChangeHandler))}_setPollInterval(t){this._currentPollInterval=t,this._pollInterval&&(this.stopPolling(),this.startPolling(null,t))}setPollMode(t){let e=z[t];e&&this._setPollInterval(e)}_setupVSCodeBridge(){if(!(typeof acquireVsCodeApi>"u")){try{this._vscodeApi=acquireVsCodeApi()}catch{console.warn("VS Code API already acquired or unavailable");return}this._messageHandler=t=>{let e=t.data;if(!(!e||!e.type))switch(e.type){case"updateStatus":this._emit(v.STATUS_UPDATE,e.data);break;case"updateTasks":this._emit(v.TASK_UPDATED,e.data);break;case"taskCreated":this._emit(v.TASK_CREATED,e.data);break;case"taskDeleted":this._emit(v.TASK_DELETED,e.data);break;case"projectCreated":this._emit(v.PROJECT_CREATED,e.data);break;case"projectUpdated":this._emit(v.PROJECT_UPDATED,e.data);break;case"agentUpdate":this._emit(v.AGENT_UPDATE,e.data);break;case"logMessage":this._emit(v.LOG_MESSAGE,e.data);break;case"memoryUpdate":this._emit(v.MEMORY_UPDATE,e.data);break;case"connected":this._connected=!0,this._emit(v.CONNECTED,e.data);break;case"disconnected":this._connected=!1,this._emit(v.DISCONNECTED,e.data);break;case"error":this._emit(v.ERROR,e.data);break;case"setPollMode":this.setPollMode(e.data.mode);break;default:this._emit(`api:${e.type}`,e.data)}},window.addEventListener("message",this._messageHandler)}}get isVSCode(){return this._context==="vscode"}postToVSCode(t,e={}){this._vscodeApi&&this._vscodeApi.postMessage({type:t,data:e})}requestRefresh(){this.postToVSCode("requestRefresh")}notifyVSCode(t,e={}){this.postToVSCode("userAction",{action:t,...e})}get baseUrl(){return this.config.baseUrl}set baseUrl(t){this.config.baseUrl=t,this.config.wsUrl=t.replace(/^http/,"ws")+"/ws"}get isConnected(){return this._connected}async connect(){if(!(this._ws&&this._ws.readyState===WebSocket.OPEN))return new Promise((t,e)=>{try{this._ws=new WebSocket(this.config.wsUrl),this._ws.onopen=()=>{this._connected=!0,this._reconnectAttempts=0,this._emit(v.CONNECTED),t()},this._ws.onclose=()=>{this._connected=!1,this._emit(v.DISCONNECTED),this._scheduleReconnect()},this._ws.onerror=i=>{this._emit(v.ERROR,{error:i}),e(i)},this._ws.onmessage=i=>{try{let a=JSON.parse(i.data);this._handleMessage(a)}catch(a){console.error("Failed to parse WebSocket message:",a)}}}catch(i){e(i)}})}disconnect(){this._ws&&(this._ws.close(),this._ws=null),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._reconnectTimeout&&(clearTimeout(this._reconnectTimeout),this._reconnectTimeout=null),this._connected=!1,this._cleanupGlobalListeners()}_cleanupGlobalListeners(){this._visibilityChangeHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this._visibilityChangeHandler),this._visibilityChangeHandler=null),this._messageHandler&&typeof window<"u"&&(window.removeEventListener("message",this._messageHandler),this._messageHandler=null)}destroy(){this.disconnect()}_scheduleReconnect(){if(this._reconnectTimeout)return;if(this._reconnectAttempts>=this._maxReconnectAttempts){console.warn("WebSocket max reconnect attempts reached, giving up"),this._emit(v.ERROR,{error:"Max reconnect attempts reached"});return}let t=Math.min(this.config.retryDelay*Math.pow(2,this._reconnectAttempts),3e4);this._reconnectAttempts++,this._reconnectTimeout=setTimeout(()=>{this._reconnectTimeout=null,this.connect().catch(()=>{})},t)}_handleMessage(t){if(t.type==="ping"){this._ws&&this._ws.readyState===WebSocket.OPEN&&this._ws.send(JSON.stringify({type:"pong"}));return}let i={connected:v.CONNECTED,status_update:v.STATUS_UPDATE,task_created:v.TASK_CREATED,task_updated:v.TASK_UPDATED,task_deleted:v.TASK_DELETED,task_moved:v.TASK_UPDATED,project_created:v.PROJECT_CREATED,project_updated:v.PROJECT_UPDATED,agent_update:v.AGENT_UPDATE,log:v.LOG_MESSAGE}[t.type]||`api:${t.type}`;this._emit(i,t.data)}_emit(t,e={}){this.dispatchEvent(new CustomEvent(t,{detail:e}))}async _request(t,e={}){let i=`${this.config.baseUrl}${t}`,a=new AbortController,s=setTimeout(()=>a.abort(),this.config.timeout);try{let r=await fetch(i,{...e,signal:a.signal,credentials:"include",headers:{"Content-Type":"application/json",...e.headers}});if(clearTimeout(s),!r.ok){let o=await r.text().catch(()=>""),n=r.statusText||`HTTP ${r.status}`;if(o)try{let l=JSON.parse(o);n=l.detail||l.error||l.message||n}catch{n=o.length>200?o.slice(0,200)+"...":o}throw new Error(n)}return r.status===204?null:await r.json()}catch(r){throw clearTimeout(s),r.name==="AbortError"?new Error("Request timeout"):r}}async _get(t,e=!1){if(e&&this._cache.has(t)){let a=this._cache.get(t);if(Date.now()-a.timestamp<this._cacheTimeout)return a.data}let i=await this._request(t);return e&&this._cache.set(t,{data:i,timestamp:Date.now()}),i}async _post(t,e){return this._request(t,{method:"POST",body:JSON.stringify(e)})}async _put(t,e){return this._request(t,{method:"PUT",body:JSON.stringify(e)})}async _delete(t){return this._request(t,{method:"DELETE"})}async get(t){return this._get(t)}async getStatus(){return this._get("/api/status")}async healthCheck(){return this._get("/health")}async listProjects(t=null){let e=t?`?status=${t}`:"";return this._get(`/api/projects${e}`)}async getProject(t){return this._get(`/api/projects/${t}`)}async createProject(t){return this._post("/api/projects",t)}async updateProject(t,e){return this._put(`/api/projects/${t}`,e)}async deleteProject(t){return this._delete(`/api/projects/${t}`)}async listTasks(t={}){let e=new URLSearchParams;t.projectId&&e.append("project_id",t.projectId),t.status&&e.append("status",t.status),t.priority&&e.append("priority",t.priority);let i=e.toString()?`?${e}`:"";return this._get(`/api/tasks${i}`)}async getTask(t){return this._get(`/api/tasks/${t}`)}async createTask(t){return this._post("/api/tasks",t)}async updateTask(t,e){return this._put(`/api/tasks/${t}`,e)}async moveTask(t,e,i){return this._post(`/api/tasks/${t}/move`,{status:e,position:i})}async deleteTask(t){return this._delete(`/api/tasks/${t}`)}async getMemorySummary(){return this._get("/api/memory/summary",!0)}async getMemoryIndex(){return this._get("/api/memory/index",!0)}async getMemoryTimeline(){return this._get("/api/memory/timeline")}async listEpisodes(t={}){let e=new URLSearchParams(t).toString();return this._get(`/api/memory/episodes${e?"?"+e:""}`)}async getEpisode(t){return this._get(`/api/memory/episodes/${t}`)}async listPatterns(t={}){let e=new URLSearchParams(t).toString();return this._get(`/api/memory/patterns${e?"?"+e:""}`)}async getPattern(t){return this._get(`/api/memory/patterns/${t}`)}async listSkills(){return this._get("/api/memory/skills")}async getSkill(t){return this._get(`/api/memory/skills/${t}`)}async retrieveMemories(t,e=null,i=5){return this._post("/api/memory/retrieve",{query:t,taskType:e,topK:i})}async consolidateMemory(t=24){return this._post("/api/memory/consolidate",{sinceHours:t})}async getTokenEconomics(){return this._get("/api/memory/economics")}async searchMemory(t,e="all",i=20){let a=new URLSearchParams({q:t,collection:e,limit:String(i)});return this._get(`/api/memory/search?${a}`)}async getMemoryStats(){return this._get("/api/memory/stats",!0)}async listRegisteredProjects(t=!1){return this._get(`/api/registry/projects?include_inactive=${t}`)}async registerProject(t,e=null,i=null){return this._post("/api/registry/projects",{path:t,name:e,alias:i})}async discoverProjects(t=3){return this._get(`/api/registry/discover?max_depth=${t}`)}async syncRegistry(){return this._post("/api/registry/sync",{})}async getCrossProjectTasks(t=null){let e=t?`?project_ids=${t.join(",")}`:"";return this._get(`/api/registry/tasks${e}`)}async getLearningMetrics(t={}){let e=new URLSearchParams;t.timeRange&&e.append("timeRange",t.timeRange),t.signalType&&e.append("signalType",t.signalType),t.source&&e.append("source",t.source);let i=e.toString()?`?${e}`:"";return this._get(`/api/learning/metrics${i}`)}async getLearningTrends(t={}){let e=new URLSearchParams;t.timeRange&&e.append("timeRange",t.timeRange),t.signalType&&e.append("signalType",t.signalType),t.source&&e.append("source",t.source);let i=e.toString()?`?${e}`:"";return this._get(`/api/learning/trends${i}`)}async getLearningSignals(t={}){let e=new URLSearchParams;t.timeRange&&e.append("timeRange",t.timeRange),t.signalType&&e.append("signalType",t.signalType),t.source&&e.append("source",t.source),t.limit&&e.append("limit",String(t.limit)),t.offset&&e.append("offset",String(t.offset));let i=e.toString()?`?${e}`:"";return this._get(`/api/learning/signals${i}`)}async getLatestAggregation(){return this._get("/api/learning/aggregation")}async triggerAggregation(t={}){return this._post("/api/learning/aggregate",t)}async getAggregatedPreferences(t=20){return this._get(`/api/learning/preferences?limit=${t}`)}async getAggregatedErrors(t=20){return this._get(`/api/learning/errors?limit=${t}`)}async getAggregatedSuccessPatterns(t=20){return this._get(`/api/learning/success?limit=${t}`)}async getToolEfficiency(t=20){return this._get(`/api/learning/tools?limit=${t}`)}async getCost(){return this._get("/api/cost")}async getPricing(){return this._get("/api/pricing")}async getCouncilState(){return this._get("/api/council/state")}async getCouncilVerdicts(t=20){return this._get(`/api/council/verdicts?limit=${t}`)}async getCouncilConvergence(){return this._get("/api/council/convergence")}async getCouncilReport(){return this._get("/api/council/report")}async forceCouncilReview(){return this._post("/api/council/force-review",{})}async getContext(){return this._get("/api/context")}async getNotifications(t,e){let i=new URLSearchParams;t&&i.set("severity",t),e&&i.set("unread_only","true");let a=i.toString();return this._get("/api/notifications"+(a?"?"+a:""))}async getNotificationTriggers(){return this._get("/api/notifications/triggers")}async updateNotificationTriggers(t){return this._put("/api/notifications/triggers",{triggers:t})}async acknowledgeNotification(t){return this._post("/api/notifications/"+encodeURIComponent(t)+"/acknowledge",{})}async pauseSession(){return this._post("/api/control/pause",{})}async resumeSession(){return this._post("/api/control/resume",{})}async stopSession(){return this._post("/api/control/stop",{})}async getLogs(t=100){return this._get(`/api/logs?lines=${t}`)}async getChecklist(){return this._get("/api/checklist")}async getChecklistSummary(){return this._get("/api/checklist/summary")}async getPrdObservations(){let t=await fetch(`${this.baseUrl}/api/prd-observations`,{credentials:"include"});if(!t.ok)throw new Error(`HTTP ${t.status}`);return t.text()}async getChecklistWaivers(){return this._get("/api/checklist/waivers")}async addChecklistWaiver(t,e,i="dashboard"){return this._post("/api/checklist/waivers",{item_id:t,reason:e,waived_by:i})}async removeChecklistWaiver(t){return this._delete(`/api/checklist/waivers/${encodeURIComponent(t)}`)}async getCouncilGate(){return this._get("/api/council/gate")}async getAppRunnerStatus(){return this._get("/api/app-runner/status")}async getAppRunnerLogs(t=100){return this._get(`/api/app-runner/logs?lines=${t}`)}async restartApp(){return this._post("/api/control/app-restart",{})}async stopApp(){return this._post("/api/control/app-stop",{})}async getPlaywrightResults(){return this._get("/api/playwright/results")}async getPlaywrightScreenshot(){return this._get("/api/playwright/screenshot")}startPolling(t,e=null){if(this._pollInterval)return;this._pollCallback=t;let i=async()=>{try{let s=await this.getStatus();this._connected=!0,this._pollCallback&&this._pollCallback(s),this._emit(v.STATUS_UPDATE,s),this._vscodeApi&&this.postToVSCode("pollSuccess",{timestamp:Date.now()})}catch(s){this._connected=!1,this._emit(v.ERROR,{error:s}),this._vscodeApi&&this.postToVSCode("pollError",{error:s.message})}};i();let a=e||this._currentPollInterval||this.config.pollInterval;this._pollInterval=setInterval(i,a)}stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}};C(A,"_instances",new Map);var B=A;function Bt(d={}){return new B(d)}function g(d={}){return B.getInstance(d)}var St="loki-state-change",Ct={ui:{theme:"light",sidebarCollapsed:!1,activeSection:"kanban",terminalAutoScroll:!0},session:{connected:!1,lastSync:null,mode:"offline",phase:null,iteration:null},localTasks:[],cache:{projects:[],tasks:[],agents:[],memory:null,lastFetch:null},preferences:{pollInterval:2e3,notifications:!0,soundEnabled:!1}},S=class S extends EventTarget{static getInstance(){return S._instance||(S._instance=new S),S._instance}constructor(){super(),this._state=this._loadState(),this._subscribers=new Map,this._batchUpdates=[],this._batchTimeout=null}_loadState(){try{let t=localStorage.getItem(S.STORAGE_KEY);if(t){let e=JSON.parse(t);return this._mergeState(Ct,e)}}catch(t){console.warn("Failed to load state from localStorage:",t)}return{...Ct}}_mergeState(t,e){let i={...t};for(let a of Object.keys(e))a in t&&typeof t[a]=="object"&&!Array.isArray(t[a])?i[a]=this._mergeState(t[a],e[a]):i[a]=e[a];return i}_saveState(){try{let t={ui:this._state.ui,localTasks:this._state.localTasks,preferences:this._state.preferences};localStorage.setItem(S.STORAGE_KEY,JSON.stringify(t))}catch(t){console.warn("Failed to save state to localStorage:",t)}}get(t=null){if(!t)return{...this._state};let e=t.split("."),i=this._state;for(let a of e){if(i==null)return;i=i[a]}return i}set(t,e,i=!0){let a=t.split("."),s=a.pop(),r=this._state;for(let n of a)n in r||(r[n]={}),r=r[n];let o=r[s];r[s]=e,i&&this._saveState(),this._notifyChange(t,e,o)}update(t,e=!0){let i=[];for(let[a,s]of Object.entries(t)){let r=this.get(a);this.set(a,s,!1),i.push({path:a,value:s,oldValue:r})}e&&this._saveState();for(let a of i)this._notifyChange(a.path,a.value,a.oldValue)}_notifyChange(t,e,i){this.dispatchEvent(new CustomEvent(St,{detail:{path:t,value:e,oldValue:i}}));let a=this._subscribers.get(t)||[];for(let r of a)try{r(e,i,t)}catch(o){console.error("State subscriber error:",o)}let s=t.split(".");for(;s.length>1;){s.pop();let r=s.join("."),o=this._subscribers.get(r)||[];for(let n of o)try{n(this.get(r),null,r)}catch(l){console.error("State subscriber error:",l)}}}subscribe(t,e){return this._subscribers.has(t)||this._subscribers.set(t,[]),this._subscribers.get(t).push(e),()=>{let i=this._subscribers.get(t),a=i.indexOf(e);a>-1&&i.splice(a,1)}}reset(t=null){if(t){let e=t.split("."),i=Ct;for(let a of e)i=i?.[a];this.set(t,i)}else this._state={...Ct},this._saveState(),this.dispatchEvent(new CustomEvent(St,{detail:{path:null,value:this._state,oldValue:null}}))}addLocalTask(t){let e=this.get("localTasks")||[],i={id:`local-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,createdAt:new Date().toISOString(),status:"pending",...t};return this.set("localTasks",[...e,i]),i}updateLocalTask(t,e){let i=this.get("localTasks")||[],a=i.findIndex(r=>r.id===t);if(a===-1)return null;let s={...i[a],...e,updatedAt:new Date().toISOString()};return i[a]=s,this.set("localTasks",[...i]),s}deleteLocalTask(t){let e=this.get("localTasks")||[];this.set("localTasks",e.filter(i=>i.id!==t))}moveLocalTask(t,e,i=null){let s=(this.get("localTasks")||[]).find(r=>r.id===t);return s?this.updateLocalTask(t,{status:e,position:i??s.position}):null}updateSession(t){this.update(Object.fromEntries(Object.entries(t).map(([e,i])=>[`session.${e}`,i])),!1)}updateCache(t){this.update({"cache.projects":t.projects??this.get("cache.projects"),"cache.tasks":t.tasks??this.get("cache.tasks"),"cache.agents":t.agents??this.get("cache.agents"),"cache.memory":t.memory??this.get("cache.memory"),"cache.lastFetch":new Date().toISOString()},!1)}getMergedTasks(){let t=this.get("cache.tasks")||[],i=(this.get("localTasks")||[]).map(a=>({...a,isLocal:!0}));return[...t,...i]}getTasksByStatus(t){return this.getMergedTasks().filter(e=>e.status===t)}};C(S,"STORAGE_KEY","loki-dashboard-state"),C(S,"_instance",null);var N=S;function P(){return N.getInstance()}function Ft(d){let t=P();return{get:()=>t.get(d),set:e=>t.set(d,e),subscribe:e=>t.subscribe(d,e)}}var O=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data={status:"offline",phase:null,iteration:null,provider:null,running_agents:0,pending_tasks:null,uptime_seconds:0,complexity:null,connected:!1},this._api=null,this._pollInterval=null,this._statusUpdateHandler=null,this._connectedHandler=null,this._disconnectedHandler=null,this._checklistSummary=null,this._appRunnerStatus=null,this._playwrightResults=null,this._gateStatus=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._startPolling(),this._api.connect().catch(()=>{})}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._loadAbortController&&(this._loadAbortController.abort(),this._loadAbortController=null),this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(v.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(v.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(v.DISCONNECTED,this._disconnectedHandler))}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadStatus()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t}),this._statusUpdateHandler=e=>this._updateFromStatus(e.detail),this._connectedHandler=()=>{this._data.connected=!0,this.render()},this._disconnectedHandler=()=>{this._data.connected=!1,this._data.status="offline",this.render()},this._api.addEventListener(v.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(v.CONNECTED,this._connectedHandler),this._api.addEventListener(v.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){this._loadAbortController&&this._loadAbortController.abort(),this._loadAbortController=new AbortController;let{signal:t}=this._loadAbortController;try{let[e,i,a,s,r]=await Promise.allSettled([this._api.getStatus(),this._api.getChecklistSummary(),this._api.getAppRunnerStatus(),this._api.getPlaywrightResults(),this._api.getCouncilGate()]);if(t.aborted)return;e.status==="fulfilled"?this._updateFromStatus(e.value):(this._data.connected=!1,this._data.status="offline"),i.status==="fulfilled"&&(this._checklistSummary=i.value?.summary||null),a.status==="fulfilled"&&(this._appRunnerStatus=a.value),s.status==="fulfilled"&&(this._playwrightResults=s.value),r.status==="fulfilled"&&(this._gateStatus=r.value),this.render()}catch{if(t.aborted)return;this._data.connected=!1,this._data.status="offline",this.render()}}_updateFromStatus(t){t&&(this._data={...this._data,connected:!0,status:t.status||"offline",phase:t.phase||null,iteration:t.iteration!=null?t.iteration:null,provider:t.provider||null,running_agents:t.running_agents||0,pending_tasks:t.pending_tasks!=null?t.pending_tasks:null,uptime_seconds:t.uptime_seconds||0,complexity:t.complexity||null})}_startPolling(){this._pollInterval=setInterval(async()=>{try{await this._loadStatus()}catch{this._data.connected=!1,this._data.status="offline",this.render()}},5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_formatUptime(t){if(!t||t<0)return"--";let e=Math.floor(t/3600),i=Math.floor(t%3600/60),a=Math.floor(t%60);return e>0?`${e}h ${i}m`:i>0?`${i}m ${a}s`:`${a}s`}_getStatusDotClass(){switch(this._data.status){case"running":case"autonomous":return"active";case"paused":return"paused";case"stopped":return"stopped";case"error":return"error";default:return"offline"}}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_renderAppRunnerCard(){let t=this._appRunnerStatus;if(!t||t.status==="not_initialized")return`
|
|
1253
|
+
`}getAriaPattern(t){return Et[t]||{}}applyAriaPattern(t,e){let i=this.getAriaPattern(e);for(let[a,s]of Object.entries(i))if(a==="role")t.setAttribute("role",s);else{let r=a.replace(/([A-Z])/g,"-$1").toLowerCase();t.setAttribute(r,s)}}render(){}};var z={realtime:1e3,normal:2e3,background:5e3,offline:1e4},Bt={vscode:z.normal,browser:z.realtime,cli:z.background},Mt={baseUrl:typeof window<"u"?window.location.origin:"http://localhost:57374",wsUrl:typeof window<"u"?`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/ws`:"ws://localhost:57374/ws",pollInterval:2e3,timeout:1e4,retryAttempts:3,retryDelay:1e3},v={CONNECTED:"api:connected",DISCONNECTED:"api:disconnected",ERROR:"api:error",STATUS_UPDATE:"api:status-update",TASK_CREATED:"api:task-created",TASK_UPDATED:"api:task-updated",TASK_DELETED:"api:task-deleted",PROJECT_CREATED:"api:project-created",PROJECT_UPDATED:"api:project-updated",AGENT_UPDATE:"api:agent-update",LOG_MESSAGE:"api:log-message",MEMORY_UPDATE:"api:memory-update",CHECKLIST_UPDATE:"api:checklist-update"},A=class A extends EventTarget{static getInstance(t={}){let e=t.baseUrl||Mt.baseUrl;return A._instances.has(e)||A._instances.set(e,new A(t)),A._instances.get(e)}static clearInstances(){A._instances.forEach(t=>t.disconnect()),A._instances.clear()}constructor(t={}){super(),this.config={...Mt,...t},this._ws=null,this._connected=!1,this._pollInterval=null,this._reconnectTimeout=null,this._reconnectAttempts=0,this._maxReconnectAttempts=20,this._cache=new Map,this._cacheTimeout=5e3,this._vscodeApi=null,this._context=this._detectContext(),this._currentPollInterval=Bt[this._context]||z.normal,this._visibilityChangeHandler=null,this._messageHandler=null,this._setupAdaptivePolling(),this._setupVSCodeBridge()}_detectContext(){return typeof acquireVsCodeApi<"u"?"vscode":typeof window<"u"&&window.location?"browser":"cli"}get context(){return this._context}static get POLL_INTERVALS(){return z}_setupAdaptivePolling(){typeof document>"u"||(this._visibilityChangeHandler=()=>{document.hidden?this._setPollInterval(z.background):this._setPollInterval(Bt[this._context]||z.normal)},document.addEventListener("visibilitychange",this._visibilityChangeHandler))}_setPollInterval(t){this._currentPollInterval=t,this._pollInterval&&(this.stopPolling(),this.startPolling(null,t))}setPollMode(t){let e=z[t];e&&this._setPollInterval(e)}_setupVSCodeBridge(){if(!(typeof acquireVsCodeApi>"u")){try{this._vscodeApi=acquireVsCodeApi()}catch{console.warn("VS Code API already acquired or unavailable");return}this._messageHandler=t=>{let e=t.data;if(!(!e||!e.type))switch(e.type){case"updateStatus":this._emit(v.STATUS_UPDATE,e.data);break;case"updateTasks":this._emit(v.TASK_UPDATED,e.data);break;case"taskCreated":this._emit(v.TASK_CREATED,e.data);break;case"taskDeleted":this._emit(v.TASK_DELETED,e.data);break;case"projectCreated":this._emit(v.PROJECT_CREATED,e.data);break;case"projectUpdated":this._emit(v.PROJECT_UPDATED,e.data);break;case"agentUpdate":this._emit(v.AGENT_UPDATE,e.data);break;case"logMessage":this._emit(v.LOG_MESSAGE,e.data);break;case"memoryUpdate":this._emit(v.MEMORY_UPDATE,e.data);break;case"connected":this._connected=!0,this._emit(v.CONNECTED,e.data);break;case"disconnected":this._connected=!1,this._emit(v.DISCONNECTED,e.data);break;case"error":this._emit(v.ERROR,e.data);break;case"setPollMode":this.setPollMode(e.data.mode);break;default:this._emit(`api:${e.type}`,e.data)}},window.addEventListener("message",this._messageHandler)}}get isVSCode(){return this._context==="vscode"}postToVSCode(t,e={}){this._vscodeApi&&this._vscodeApi.postMessage({type:t,data:e})}requestRefresh(){this.postToVSCode("requestRefresh")}notifyVSCode(t,e={}){this.postToVSCode("userAction",{action:t,...e})}get baseUrl(){return this.config.baseUrl}set baseUrl(t){this.config.baseUrl=t,this.config.wsUrl=t.replace(/^http/,"ws")+"/ws"}get isConnected(){return this._connected}async connect(){if(!(this._ws&&this._ws.readyState===WebSocket.OPEN))return new Promise((t,e)=>{try{this._ws=new WebSocket(this.config.wsUrl),this._ws.onopen=()=>{this._connected=!0,this._reconnectAttempts=0,this._emit(v.CONNECTED),t()},this._ws.onclose=()=>{this._connected=!1,this._emit(v.DISCONNECTED),this._scheduleReconnect()},this._ws.onerror=i=>{this._emit(v.ERROR,{error:i}),e(i)},this._ws.onmessage=i=>{try{let a=JSON.parse(i.data);this._handleMessage(a)}catch(a){console.error("Failed to parse WebSocket message:",a)}}}catch(i){e(i)}})}disconnect(){this._ws&&(this._ws.close(),this._ws=null),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._reconnectTimeout&&(clearTimeout(this._reconnectTimeout),this._reconnectTimeout=null),this._connected=!1,this._cleanupGlobalListeners()}_cleanupGlobalListeners(){this._visibilityChangeHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this._visibilityChangeHandler),this._visibilityChangeHandler=null),this._messageHandler&&typeof window<"u"&&(window.removeEventListener("message",this._messageHandler),this._messageHandler=null)}destroy(){this.disconnect()}_scheduleReconnect(){if(this._reconnectTimeout)return;if(this._reconnectAttempts>=this._maxReconnectAttempts){console.warn("WebSocket max reconnect attempts reached, giving up"),this._emit(v.ERROR,{error:"Max reconnect attempts reached"});return}let t=Math.min(this.config.retryDelay*Math.pow(2,this._reconnectAttempts),3e4);this._reconnectAttempts++,this._reconnectTimeout=setTimeout(()=>{this._reconnectTimeout=null,this.connect().catch(()=>{})},t)}_handleMessage(t){if(t.type==="ping"){this._ws&&this._ws.readyState===WebSocket.OPEN&&this._ws.send(JSON.stringify({type:"pong"}));return}let i={connected:v.CONNECTED,status_update:v.STATUS_UPDATE,task_created:v.TASK_CREATED,task_updated:v.TASK_UPDATED,task_deleted:v.TASK_DELETED,task_moved:v.TASK_UPDATED,project_created:v.PROJECT_CREATED,project_updated:v.PROJECT_UPDATED,agent_update:v.AGENT_UPDATE,log:v.LOG_MESSAGE}[t.type]||`api:${t.type}`;this._emit(i,t.data)}_emit(t,e={}){this.dispatchEvent(new CustomEvent(t,{detail:e}))}async _request(t,e={}){let i=`${this.config.baseUrl}${t}`,a=new AbortController,s=setTimeout(()=>a.abort(),this.config.timeout);try{let r=await fetch(i,{...e,signal:a.signal,credentials:"include",headers:{"Content-Type":"application/json",...e.headers}});if(clearTimeout(s),!r.ok){let o=await r.text().catch(()=>""),n=r.statusText||`HTTP ${r.status}`;if(o)try{let l=JSON.parse(o);n=l.detail||l.error||l.message||n}catch{n=o.length>200?o.slice(0,200)+"...":o}throw new Error(n)}return r.status===204?null:await r.json()}catch(r){throw clearTimeout(s),r.name==="AbortError"?new Error("Request timeout"):r}}async _get(t,e=!1){if(e&&this._cache.has(t)){let a=this._cache.get(t);if(Date.now()-a.timestamp<this._cacheTimeout)return a.data}let i=await this._request(t);return e&&this._cache.set(t,{data:i,timestamp:Date.now()}),i}async _post(t,e){return this._request(t,{method:"POST",body:JSON.stringify(e)})}async _put(t,e){return this._request(t,{method:"PUT",body:JSON.stringify(e)})}async _delete(t){return this._request(t,{method:"DELETE"})}async get(t){return this._get(t)}async getStatus(){return this._get("/api/status")}async healthCheck(){return this._get("/health")}async listProjects(t=null){let e=t?`?status=${t}`:"";return this._get(`/api/projects${e}`)}async getProject(t){return this._get(`/api/projects/${t}`)}async createProject(t){return this._post("/api/projects",t)}async updateProject(t,e){return this._put(`/api/projects/${t}`,e)}async deleteProject(t){return this._delete(`/api/projects/${t}`)}async listTasks(t={}){let e=new URLSearchParams;t.projectId&&e.append("project_id",t.projectId),t.status&&e.append("status",t.status),t.priority&&e.append("priority",t.priority);let i=e.toString()?`?${e}`:"";return this._get(`/api/tasks${i}`)}async getTask(t){return this._get(`/api/tasks/${t}`)}async createTask(t){return this._post("/api/tasks",t)}async updateTask(t,e){return this._put(`/api/tasks/${t}`,e)}async moveTask(t,e,i){return this._post(`/api/tasks/${t}/move`,{status:e,position:i})}async deleteTask(t){return this._delete(`/api/tasks/${t}`)}async getMemorySummary(){return this._get("/api/memory/summary",!0)}async getMemoryIndex(){return this._get("/api/memory/index",!0)}async getMemoryTimeline(){return this._get("/api/memory/timeline")}async listEpisodes(t={}){let e=new URLSearchParams(t).toString();return this._get(`/api/memory/episodes${e?"?"+e:""}`)}async getEpisode(t){return this._get(`/api/memory/episodes/${t}`)}async listPatterns(t={}){let e=new URLSearchParams(t).toString();return this._get(`/api/memory/patterns${e?"?"+e:""}`)}async getPattern(t){return this._get(`/api/memory/patterns/${t}`)}async listSkills(){return this._get("/api/memory/skills")}async getSkill(t){return this._get(`/api/memory/skills/${t}`)}async retrieveMemories(t,e=null,i=5){return this._post("/api/memory/retrieve",{query:t,taskType:e,topK:i})}async consolidateMemory(t=24){return this._post("/api/memory/consolidate",{sinceHours:t})}async getTokenEconomics(){return this._get("/api/memory/economics")}async searchMemory(t,e="all",i=20){let a=new URLSearchParams({q:t,collection:e,limit:String(i)});return this._get(`/api/memory/search?${a}`)}async getMemoryStats(){return this._get("/api/memory/stats",!0)}async listRegisteredProjects(t=!1){return this._get(`/api/registry/projects?include_inactive=${t}`)}async registerProject(t,e=null,i=null){return this._post("/api/registry/projects",{path:t,name:e,alias:i})}async discoverProjects(t=3){return this._get(`/api/registry/discover?max_depth=${t}`)}async syncRegistry(){return this._post("/api/registry/sync",{})}async getCrossProjectTasks(t=null){let e=t?`?project_ids=${t.join(",")}`:"";return this._get(`/api/registry/tasks${e}`)}async getLearningMetrics(t={}){let e=new URLSearchParams;t.timeRange&&e.append("timeRange",t.timeRange),t.signalType&&e.append("signalType",t.signalType),t.source&&e.append("source",t.source);let i=e.toString()?`?${e}`:"";return this._get(`/api/learning/metrics${i}`)}async getLearningTrends(t={}){let e=new URLSearchParams;t.timeRange&&e.append("timeRange",t.timeRange),t.signalType&&e.append("signalType",t.signalType),t.source&&e.append("source",t.source);let i=e.toString()?`?${e}`:"";return this._get(`/api/learning/trends${i}`)}async getLearningSignals(t={}){let e=new URLSearchParams;t.timeRange&&e.append("timeRange",t.timeRange),t.signalType&&e.append("signalType",t.signalType),t.source&&e.append("source",t.source),t.limit&&e.append("limit",String(t.limit)),t.offset&&e.append("offset",String(t.offset));let i=e.toString()?`?${e}`:"";return this._get(`/api/learning/signals${i}`)}async getLatestAggregation(){return this._get("/api/learning/aggregation")}async triggerAggregation(t={}){return this._post("/api/learning/aggregate",t)}async getAggregatedPreferences(t=20){return this._get(`/api/learning/preferences?limit=${t}`)}async getAggregatedErrors(t=20){return this._get(`/api/learning/errors?limit=${t}`)}async getAggregatedSuccessPatterns(t=20){return this._get(`/api/learning/success?limit=${t}`)}async getToolEfficiency(t=20){return this._get(`/api/learning/tools?limit=${t}`)}async getCost(){return this._get("/api/cost")}async getPricing(){return this._get("/api/pricing")}async getCouncilState(){return this._get("/api/council/state")}async getCouncilVerdicts(t=20){return this._get(`/api/council/verdicts?limit=${t}`)}async getCouncilConvergence(){return this._get("/api/council/convergence")}async getCouncilReport(){return this._get("/api/council/report")}async forceCouncilReview(){return this._post("/api/council/force-review",{})}async getContext(){return this._get("/api/context")}async getNotifications(t,e){let i=new URLSearchParams;t&&i.set("severity",t),e&&i.set("unread_only","true");let a=i.toString();return this._get("/api/notifications"+(a?"?"+a:""))}async getNotificationTriggers(){return this._get("/api/notifications/triggers")}async updateNotificationTriggers(t){return this._put("/api/notifications/triggers",{triggers:t})}async acknowledgeNotification(t){return this._post("/api/notifications/"+encodeURIComponent(t)+"/acknowledge",{})}async pauseSession(){return this._post("/api/control/pause",{})}async resumeSession(){return this._post("/api/control/resume",{})}async stopSession(){return this._post("/api/control/stop",{})}async getLogs(t=100){return this._get(`/api/logs?lines=${t}`)}async getChecklist(){return this._get("/api/checklist")}async getChecklistSummary(){return this._get("/api/checklist/summary")}async getPrdObservations(){let t=await fetch(`${this.baseUrl}/api/prd-observations`,{credentials:"include"});if(!t.ok)throw new Error(`HTTP ${t.status}`);return t.text()}async getChecklistWaivers(){return this._get("/api/checklist/waivers")}async addChecklistWaiver(t,e,i="dashboard"){return this._post("/api/checklist/waivers",{item_id:t,reason:e,waived_by:i})}async removeChecklistWaiver(t){return this._delete(`/api/checklist/waivers/${encodeURIComponent(t)}`)}async getCouncilGate(){return this._get("/api/council/gate")}async getAppRunnerStatus(){return this._get("/api/app-runner/status")}async getAppRunnerLogs(t=100){return this._get(`/api/app-runner/logs?lines=${t}`)}async restartApp(){return this._post("/api/control/app-restart",{})}async stopApp(){return this._post("/api/control/app-stop",{})}async getPlaywrightResults(){return this._get("/api/playwright/results")}async getPlaywrightScreenshot(){return this._get("/api/playwright/screenshot")}startPolling(t,e=null){if(this._pollInterval)return;this._pollCallback=t;let i=async()=>{try{let s=await this.getStatus();this._connected=!0,this._pollCallback&&this._pollCallback(s),this._emit(v.STATUS_UPDATE,s),this._vscodeApi&&this.postToVSCode("pollSuccess",{timestamp:Date.now()})}catch(s){this._connected=!1,this._emit(v.ERROR,{error:s}),this._vscodeApi&&this.postToVSCode("pollError",{error:s.message})}};i();let a=e||this._currentPollInterval||this.config.pollInterval;this._pollInterval=setInterval(i,a)}stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}};C(A,"_instances",new Map);var M=A;function Ft(d={}){return new M(d)}function g(d={}){return M.getInstance(d)}var Tt="loki-state-change",St={ui:{theme:"light",sidebarCollapsed:!1,activeSection:"kanban",terminalAutoScroll:!0},session:{connected:!1,lastSync:null,mode:"offline",phase:null,iteration:null},localTasks:[],cache:{projects:[],tasks:[],agents:[],memory:null,lastFetch:null},preferences:{pollInterval:2e3,notifications:!0,soundEnabled:!1}},S=class S extends EventTarget{static getInstance(){return S._instance||(S._instance=new S),S._instance}constructor(){super(),this._state=this._loadState(),this._subscribers=new Map,this._batchUpdates=[],this._batchTimeout=null}_loadState(){try{let t=localStorage.getItem(S.STORAGE_KEY);if(t){let e=JSON.parse(t);return this._mergeState(St,e)}}catch(t){console.warn("Failed to load state from localStorage:",t)}return{...St}}_mergeState(t,e){let i={...t};for(let a of Object.keys(e))a in t&&typeof t[a]=="object"&&!Array.isArray(t[a])?i[a]=this._mergeState(t[a],e[a]):i[a]=e[a];return i}_saveState(){try{let t={ui:this._state.ui,localTasks:this._state.localTasks,preferences:this._state.preferences};localStorage.setItem(S.STORAGE_KEY,JSON.stringify(t))}catch(t){console.warn("Failed to save state to localStorage:",t)}}get(t=null){if(!t)return{...this._state};let e=t.split("."),i=this._state;for(let a of e){if(i==null)return;i=i[a]}return i}set(t,e,i=!0){let a=t.split("."),s=a.pop(),r=this._state;for(let n of a)n in r||(r[n]={}),r=r[n];let o=r[s];r[s]=e,i&&this._saveState(),this._notifyChange(t,e,o)}update(t,e=!0){let i=[];for(let[a,s]of Object.entries(t)){let r=this.get(a);this.set(a,s,!1),i.push({path:a,value:s,oldValue:r})}e&&this._saveState();for(let a of i)this._notifyChange(a.path,a.value,a.oldValue)}_notifyChange(t,e,i){this.dispatchEvent(new CustomEvent(Tt,{detail:{path:t,value:e,oldValue:i}}));let a=this._subscribers.get(t)||[];for(let r of a)try{r(e,i,t)}catch(o){console.error("State subscriber error:",o)}let s=t.split(".");for(;s.length>1;){s.pop();let r=s.join("."),o=this._subscribers.get(r)||[];for(let n of o)try{n(this.get(r),null,r)}catch(l){console.error("State subscriber error:",l)}}}subscribe(t,e){return this._subscribers.has(t)||this._subscribers.set(t,[]),this._subscribers.get(t).push(e),()=>{let i=this._subscribers.get(t),a=i.indexOf(e);a>-1&&i.splice(a,1)}}reset(t=null){if(t){let e=t.split("."),i=St;for(let a of e)i=i?.[a];this.set(t,i)}else this._state={...St},this._saveState(),this.dispatchEvent(new CustomEvent(Tt,{detail:{path:null,value:this._state,oldValue:null}}))}addLocalTask(t){let e=this.get("localTasks")||[],i={id:`local-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,createdAt:new Date().toISOString(),status:"pending",...t};return this.set("localTasks",[...e,i]),i}updateLocalTask(t,e){let i=this.get("localTasks")||[],a=i.findIndex(r=>r.id===t);if(a===-1)return null;let s={...i[a],...e,updatedAt:new Date().toISOString()};return i[a]=s,this.set("localTasks",[...i]),s}deleteLocalTask(t){let e=this.get("localTasks")||[];this.set("localTasks",e.filter(i=>i.id!==t))}moveLocalTask(t,e,i=null){let s=(this.get("localTasks")||[]).find(r=>r.id===t);return s?this.updateLocalTask(t,{status:e,position:i??s.position}):null}updateSession(t){this.update(Object.fromEntries(Object.entries(t).map(([e,i])=>[`session.${e}`,i])),!1)}updateCache(t){this.update({"cache.projects":t.projects??this.get("cache.projects"),"cache.tasks":t.tasks??this.get("cache.tasks"),"cache.agents":t.agents??this.get("cache.agents"),"cache.memory":t.memory??this.get("cache.memory"),"cache.lastFetch":new Date().toISOString()},!1)}getMergedTasks(){let t=this.get("cache.tasks")||[],i=(this.get("localTasks")||[]).map(a=>({...a,isLocal:!0}));return[...t,...i]}getTasksByStatus(t){return this.getMergedTasks().filter(e=>e.status===t)}};C(S,"STORAGE_KEY","loki-dashboard-state"),C(S,"_instance",null);var N=S;function P(){return N.getInstance()}function jt(d){let t=P();return{get:()=>t.get(d),set:e=>t.set(d,e),subscribe:e=>t.subscribe(d,e)}}var O=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data={status:"offline",phase:null,iteration:null,provider:null,running_agents:0,pending_tasks:null,uptime_seconds:0,complexity:null,connected:!1},this._api=null,this._pollInterval=null,this._statusUpdateHandler=null,this._connectedHandler=null,this._disconnectedHandler=null,this._checklistSummary=null,this._appRunnerStatus=null,this._playwrightResults=null,this._gateStatus=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._startPolling(),this._api.connect().catch(()=>{})}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._loadAbortController&&(this._loadAbortController.abort(),this._loadAbortController=null),this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(v.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(v.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(v.DISCONNECTED,this._disconnectedHandler))}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadStatus()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t}),this._statusUpdateHandler=e=>this._updateFromStatus(e.detail),this._connectedHandler=()=>{this._data.connected=!0,this.render()},this._disconnectedHandler=()=>{this._data.connected=!1,this._data.status="offline",this.render()},this._api.addEventListener(v.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(v.CONNECTED,this._connectedHandler),this._api.addEventListener(v.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){this._loadAbortController&&this._loadAbortController.abort(),this._loadAbortController=new AbortController;let{signal:t}=this._loadAbortController;try{let[e,i,a,s,r]=await Promise.allSettled([this._api.getStatus(),this._api.getChecklistSummary(),this._api.getAppRunnerStatus(),this._api.getPlaywrightResults(),this._api.getCouncilGate()]);if(t.aborted)return;e.status==="fulfilled"?this._updateFromStatus(e.value):(this._data.connected=!1,this._data.status="offline"),i.status==="fulfilled"&&(this._checklistSummary=i.value?.summary||null),a.status==="fulfilled"&&(this._appRunnerStatus=a.value),s.status==="fulfilled"&&(this._playwrightResults=s.value),r.status==="fulfilled"&&(this._gateStatus=r.value),this.render()}catch{if(t.aborted)return;this._data.connected=!1,this._data.status="offline",this.render()}}_updateFromStatus(t){t&&(this._data={...this._data,connected:!0,status:t.status||"offline",phase:t.phase||null,iteration:t.iteration!=null?t.iteration:null,provider:t.provider||null,running_agents:t.running_agents||0,pending_tasks:t.pending_tasks!=null?t.pending_tasks:null,uptime_seconds:t.uptime_seconds||0,complexity:t.complexity||null})}_startPolling(){this._pollInterval=setInterval(async()=>{try{await this._loadStatus()}catch{this._data.connected=!1,this._data.status="offline",this.render()}},5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_formatUptime(t){if(!t||t<0)return"--";let e=Math.floor(t/3600),i=Math.floor(t%3600/60),a=Math.floor(t%60);return e>0?`${e}h ${i}m`:i>0?`${i}m ${a}s`:`${a}s`}_getStatusDotClass(){switch(this._data.status){case"running":case"autonomous":return"active";case"paused":return"paused";case"stopped":return"stopped";case"error":return"error";default:return"offline"}}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_renderAppRunnerCard(){let t=this._appRunnerStatus;if(!t||t.status==="not_initialized")return`
|
|
1241
1254
|
<div class="overview-card">
|
|
1242
1255
|
<div class="card-label">App Runner</div>
|
|
1243
1256
|
<div class="card-value small-text">${this._data.status==="running"||this._data.status==="autonomous"?"Waiting...":"Not started"}</div>
|
|
@@ -1480,8 +1493,8 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
1480
1493
|
</div>
|
|
1481
1494
|
</div>
|
|
1482
1495
|
</div>
|
|
1483
|
-
`}};customElements.get("loki-overview")||customElements.define("loki-overview",O);var
|
|
1484
|
-
<ul class="md-list">${a.trim().split(/\n/).map(r=>r.replace(/^[-*]\s+/,"")).map(r=>`<li>${r}</li>`).join("")}</ul>`),e=e.split(/\n{2,}/).map(i=>/^<(h\d|ul|ol|pre)/.test(i.trim())?i:`<p class="md-p">${i.replace(/\n/g,"<br>")}</p>`).join(""),e}_formatTimestamp(t){if(!t)return"";try{let e=new Date(t);return isNaN(e.getTime())?this._escapeHtml(String(t)):e.toLocaleString()}catch{return this._escapeHtml(String(t))}}_phaseClass(t){let e=String(t||"").toLowerCase();return["reason","plan","planning"].includes(e)?"phase-reason":["act","execute","execution","implement"].includes(e)?"phase-act":["reflect","review"].includes(e)?"phase-reflect":["verify","test","gate"].includes(e)?"phase-verify":"phase-default"}_logLevelClass(t){let e=String(t||"info").toLowerCase();return e==="error"||e==="fatal"?"log-error":e==="warn"||e==="warning"?"log-warn":e==="debug"||e==="trace"?"log-debug":"log-info"}_renderTaskDetailModal(t){if(!t)return"";let e=(t.priority||"medium").toLowerCase(),i=e.charAt(0).toUpperCase()+e.slice(1),a=t.status||"pending",s=a.replace(/_/g," ").replace(/\b\w/g,m=>m.toUpperCase()),r=t.metadata||{},o=t.acceptance_criteria||[],n=t.context_files||[],l=t.specification||"",c=t.description||"",p=Array.isArray(t.notes)?t.notes:[],
|
|
1496
|
+
`}};customElements.get("loki-overview")||customElements.define("loki-overview",O);var le=[{id:"pending",label:"Pending",status:"pending",color:"var(--loki-text-muted)"},{id:"in_progress",label:"In Progress",status:"in_progress",color:"var(--loki-blue)"},{id:"review",label:"In Review",status:"review",color:"var(--loki-purple)"},{id:"done",label:"Completed",status:"done",color:"var(--loki-green)"}],q=class extends u{static get observedAttributes(){return["api-url","project-id","theme","readonly"]}constructor(){super(),this._tasks=[],this._loading=!0,this._error=null,this._draggedTask=null,this._selectedTask=null,this._expandedCards=new Set,this._selectedTasks=new Set,this._bulkMode=!1,this._activeFilter="all",this._api=null,this._state=P()}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadTasks()}disconnectedCallback(){super.disconnectedCallback(),this._api&&(this._api.removeEventListener(v.TASK_CREATED,this._onTaskEvent),this._api.removeEventListener(v.TASK_UPDATED,this._onTaskEvent),this._api.removeEventListener(v.TASK_DELETED,this._onTaskEvent))}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadTasks()),t==="project-id"&&this._loadTasks(),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t}),this._onTaskEvent&&(this._api.removeEventListener(v.TASK_CREATED,this._onTaskEvent),this._api.removeEventListener(v.TASK_UPDATED,this._onTaskEvent),this._api.removeEventListener(v.TASK_DELETED,this._onTaskEvent)),this._onTaskEvent=()=>this._loadTasks(),this._api.addEventListener(v.TASK_CREATED,this._onTaskEvent),this._api.addEventListener(v.TASK_UPDATED,this._onTaskEvent),this._api.addEventListener(v.TASK_DELETED,this._onTaskEvent)}async _loadTasks(){this._loading=!0,this._error=null,this.render();try{let t=this.getAttribute("project-id"),e=t?{projectId:parseInt(t)}:{};this._tasks=await this._api.listTasks(e);let i=this._state.get("localTasks")||[];i.length>0&&(this._tasks=[...this._tasks,...i.map(a=>({...a,isLocal:!0}))]),this._state.update({"cache.tasks":this._tasks},!1)}catch(t){this._error=t.message,this._tasks=(this._state.get("localTasks")||[]).map(e=>({...e,isLocal:!0}))}this._loading=!1,this.render()}_getTasksByStatus(t){return this._getFilteredTasks().filter(i=>i.status?.toLowerCase().replace(/-/g,"_")===t)}_handleDragStart(t,e){this.hasAttribute("readonly")||(this._draggedTask=e,t.target.classList.add("dragging"),t.dataTransfer.effectAllowed="move",t.dataTransfer.setData("text/plain",e.id.toString()))}_handleDragEnd(t){t.target.classList.remove("dragging"),this._draggedTask=null,this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(e=>{e.classList.remove("drag-over")})}_handleDragOver(t){t.preventDefault(),t.dataTransfer.dropEffect="move"}_handleDragEnter(t){t.preventDefault(),t.currentTarget.classList.add("drag-over")}_handleDragLeave(t){t.currentTarget.contains(t.relatedTarget)||t.currentTarget.classList.remove("drag-over")}async _handleDrop(t,e){if(t.preventDefault(),t.currentTarget.classList.remove("drag-over"),!this._draggedTask||this.hasAttribute("readonly"))return;let i=this._draggedTask.id,a=this._tasks.find(r=>r.id===i);if(!a)return;let s=a.status;if(s!==e){a.status=e,this.render();try{a.isLocal?this._state.moveLocalTask(i,e):await this._api.moveTask(i,e,0),this.dispatchEvent(new CustomEvent("task-moved",{detail:{taskId:i,oldStatus:s,newStatus:e}}))}catch(r){a.status=s,this.render(),console.error("Failed to move task:",r)}}}_toggleCardExpand(t){this._expandedCards.has(t)?this._expandedCards.delete(t):this._expandedCards.add(t),this.render()}_toggleTaskSelection(t,e){e&&e.stopPropagation(),this._selectedTasks.has(t)?this._selectedTasks.delete(t):this._selectedTasks.add(t),this.render()}_toggleBulkMode(){this._bulkMode=!this._bulkMode,this._bulkMode||this._selectedTasks.clear(),this.render()}async _bulkMove(t){let e=[...this._selectedTasks];for(let i of e){let a=this._tasks.find(s=>String(s.id)===String(i));if(a&&a.status!==t)try{a.isLocal?this._state.moveLocalTask(i,t):await this._api.moveTask(i,t,0),a.status=t}catch(s){console.error("Failed to bulk move task:",i,s)}}this._selectedTasks.clear(),this._bulkMode=!1,this.render(),this._loadTasks()}async _bulkDelete(){let t=[...this._selectedTasks];for(let e of t)try{await this._api.deleteTask(e)}catch(i){console.error("Failed to delete task:",e,i)}this._selectedTasks.clear(),this._bulkMode=!1,this._loadTasks()}_setFilter(t){this._activeFilter=t,this.render()}_getFilteredTasks(){let t=[...this._tasks],e=new Date,i=new Date(e.getFullYear(),e.getMonth(),e.getDate()),a=new Date(i.getTime()-7*24*60*60*1e3);switch(this._activeFilter){case"today":t=t.filter(s=>{let r=s.created_at?new Date(s.created_at):null;return r&&r>=i});break;case"this-week":t=t.filter(s=>{let r=s.created_at?new Date(s.created_at):null;return r&&r>=a});break;case"running":t=t.filter(s=>s.status==="in_progress");break;case"failed":t=t.filter(s=>s.status==="failed"||s.status==="error");break;default:break}return t}_openAddTaskModal(t="pending"){this.dispatchEvent(new CustomEvent("add-task",{detail:{status:t}}))}_openTaskDetail(t){this._selectedTask=t,this.render(),this.dispatchEvent(new CustomEvent("task-click",{detail:{task:t}}))}_closeTaskDetail(){this._selectedTask=null,this.render()}_renderMarkdown(t){if(!t)return"";let e=this._escapeHtml(String(t));return e=e.replace(/```([\s\S]*?)```/g,(i,a)=>`<pre class="md-code">${a.trim()}</pre>`),e=e.replace(/`([^`\n]+)`/g,'<code class="md-inline-code">$1</code>'),e=e.replace(/^###\s+(.+)$/gm,'<h4 class="md-h4">$1</h4>'),e=e.replace(/^##\s+(.+)$/gm,'<h3 class="md-h3">$1</h3>'),e=e.replace(/^#\s+(.+)$/gm,'<h2 class="md-h2">$1</h2>'),e=e.replace(/\*\*([^*\n]+)\*\*/g,"<strong>$1</strong>"),e=e.replace(/(^|[^*])\*([^*\n]+)\*/g,"$1<em>$2</em>"),e=e.replace(/(?:^|\n)((?:[-*]\s+.+(?:\n|$))+)/g,(i,a)=>`
|
|
1497
|
+
<ul class="md-list">${a.trim().split(/\n/).map(r=>r.replace(/^[-*]\s+/,"")).map(r=>`<li>${r}</li>`).join("")}</ul>`),e=e.split(/\n{2,}/).map(i=>/^<(h\d|ul|ol|pre)/.test(i.trim())?i:`<p class="md-p">${i.replace(/\n/g,"<br>")}</p>`).join(""),e}_formatTimestamp(t){if(!t)return"";try{let e=new Date(t);return isNaN(e.getTime())?this._escapeHtml(String(t)):e.toLocaleString()}catch{return this._escapeHtml(String(t))}}_phaseClass(t){let e=String(t||"").toLowerCase();return["reason","plan","planning"].includes(e)?"phase-reason":["act","execute","execution","implement"].includes(e)?"phase-act":["reflect","review"].includes(e)?"phase-reflect":["verify","test","gate"].includes(e)?"phase-verify":"phase-default"}_logLevelClass(t){let e=String(t||"info").toLowerCase();return e==="error"||e==="fatal"?"log-error":e==="warn"||e==="warning"?"log-warn":e==="debug"||e==="trace"?"log-debug":"log-info"}_renderTaskDetailModal(t){if(!t)return"";let e=(t.priority||"medium").toLowerCase(),i=e.charAt(0).toUpperCase()+e.slice(1),a=t.status||"pending",s=a.replace(/_/g," ").replace(/\b\w/g,m=>m.toUpperCase()),r=t.metadata||{},o=t.acceptance_criteria||[],n=t.context_files||[],l=t.specification||"",c=t.description||"",p=Array.isArray(t.notes)?t.notes:[],h=Array.isArray(t.logs)?t.logs:[],b=t.full_content||"";return`
|
|
1485
1498
|
<div class="modal-overlay" id="task-detail-overlay">
|
|
1486
1499
|
<div class="modal-container">
|
|
1487
1500
|
<div class="modal-header">
|
|
@@ -1549,16 +1562,16 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
1549
1562
|
</div>
|
|
1550
1563
|
`:""}
|
|
1551
1564
|
|
|
1552
|
-
${
|
|
1565
|
+
${h.length>0?`
|
|
1553
1566
|
<div class="modal-section">
|
|
1554
1567
|
<h3 class="modal-section-title">Logs</h3>
|
|
1555
1568
|
<div class="logs-scroll">
|
|
1556
1569
|
<ul class="logs-timeline" role="list">
|
|
1557
|
-
${
|
|
1570
|
+
${h.map(m=>{let f=this._formatTimestamp(m&&m.timestamp),y=m&&m.iteration!==void 0&&m.iteration!==null?`i${this._escapeHtml(String(m.iteration))}`:"",w=m&&m.phase?String(m.phase):"",Xt=this._phaseClass(w),Zt=this._logLevelClass(m&&m.level),te=m&&m.message?this._escapeHtml(String(m.message)):"";return`<li class="log-entry ${Zt}">
|
|
1558
1571
|
${f?`<span class="log-time">${f}</span>`:""}
|
|
1559
1572
|
${y?`<span class="log-iter">${y}</span>`:""}
|
|
1560
|
-
${w?`<span class="log-phase ${
|
|
1561
|
-
<span class="log-message">${
|
|
1573
|
+
${w?`<span class="log-phase ${Xt}">${this._escapeHtml(w)}</span>`:""}
|
|
1574
|
+
<span class="log-message">${te}</span>
|
|
1562
1575
|
</li>`}).join("")}
|
|
1563
1576
|
</ul>
|
|
1564
1577
|
</div>
|
|
@@ -2434,11 +2447,11 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
2434
2447
|
display: block;
|
|
2435
2448
|
}
|
|
2436
2449
|
</style>
|
|
2437
|
-
`,e=a=>{switch(a){case"pending":return'<circle cx="12" cy="12" r="10"/>';case"in_progress":return'<path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/>';case"review":return'<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/>';case"done":return'<path d="M22 11.08V12a10 10 0 11-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/>';default:return'<circle cx="12" cy="12" r="10"/>'}},i;if(this._loading)i='<div class="loading">Loading tasks...</div>';else if(this._error&&this._tasks.length===0)i=`<div class="error">Error: ${this._escapeHtml(this._error)}</div>`;else{let a=this.hasAttribute("readonly"),s=[{id:"all",label:"All"},{id:"today",label:"Today"},{id:"this-week",label:"This Week"},{id:"running",label:"Running"},{id:"failed",label:"Failed"}],r=o=>{if(!o.assigned_agent_id&&!o.agent_type)return"";let n=(o.agent_type||"").toLowerCase(),l="AG",c="default",p="idle",
|
|
2450
|
+
`,e=a=>{switch(a){case"pending":return'<circle cx="12" cy="12" r="10"/>';case"in_progress":return'<path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/>';case"review":return'<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/>';case"done":return'<path d="M22 11.08V12a10 10 0 11-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/>';default:return'<circle cx="12" cy="12" r="10"/>'}},i;if(this._loading)i='<div class="loading">Loading tasks...</div>';else if(this._error&&this._tasks.length===0)i=`<div class="error">Error: ${this._escapeHtml(this._error)}</div>`;else{let a=this.hasAttribute("readonly"),s=[{id:"all",label:"All"},{id:"today",label:"Today"},{id:"this-week",label:"This Week"},{id:"running",label:"Running"},{id:"failed",label:"Failed"}],r=o=>{if(!o.assigned_agent_id&&!o.agent_type)return"";let n=(o.agent_type||"").toLowerCase(),l="AG",c="default",p="idle",h=`Agent #${o.assigned_agent_id||"?"}`;return n.includes("architect")||n==="ar"?(l="AR",c="architect",h="Architect"):n.includes("develop")||n==="dv"?(l="DV",c="developer",h="Developer"):n.includes("test")||n==="ts"?(l="TS",c="tester",h="Tester"):(n.includes("review")||n==="rv")&&(l="RV",c="reviewer",h="Reviewer"),o.status==="in_progress"&&(p="active"),(o.status==="failed"||o.status==="error")&&(p="failed"),`
|
|
2438
2451
|
<div class="agent-avatar ${c}">
|
|
2439
2452
|
${l}
|
|
2440
2453
|
<span class="agent-status-dot ${p}"></span>
|
|
2441
|
-
<span class="agent-tooltip">${this._escapeHtml(
|
|
2454
|
+
<span class="agent-tooltip">${this._escapeHtml(h)}</span>
|
|
2442
2455
|
</div>
|
|
2443
2456
|
`};i=`
|
|
2444
2457
|
<div class="filter-bar">
|
|
@@ -2458,7 +2471,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
2458
2471
|
`:""}
|
|
2459
2472
|
|
|
2460
2473
|
<div class="kanban-board">
|
|
2461
|
-
${
|
|
2474
|
+
${le.map(o=>{let n=this._getTasksByStatus(o.status);return`
|
|
2462
2475
|
<div class="kanban-column" data-status="${o.status}">
|
|
2463
2476
|
<div class="kanban-column-header">
|
|
2464
2477
|
<span class="kanban-column-title">
|
|
@@ -2471,8 +2484,8 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
2471
2484
|
</div>
|
|
2472
2485
|
<div class="kanban-tasks" data-status="${o.status}">
|
|
2473
2486
|
${n.length===0?'<div class="empty-column">No tasks</div>':""}
|
|
2474
|
-
${n.map(l=>{let c=String(l.id||""),p=this._expandedCards.has(c),
|
|
2475
|
-
<div class="task-card ${!a&&!l.fromServer?"draggable":""} ${l.isLocal?"local":""} ${p?"expanded":""} ${
|
|
2487
|
+
${n.map(l=>{let c=String(l.id||""),p=this._expandedCards.has(c),h=this._selectedTasks.has(c);return`
|
|
2488
|
+
<div class="task-card ${!a&&!l.fromServer?"draggable":""} ${l.isLocal?"local":""} ${p?"expanded":""} ${h?"selected":""}"
|
|
2476
2489
|
data-task-id="${this._escapeHtml(c)}"
|
|
2477
2490
|
tabindex="0"
|
|
2478
2491
|
role="button"
|
|
@@ -2480,7 +2493,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
2480
2493
|
${!a&&!l.fromServer?'draggable="true"':""}>
|
|
2481
2494
|
<div class="task-card-header">
|
|
2482
2495
|
<div style="display:flex;align-items:center;gap:6px;">
|
|
2483
|
-
${this._bulkMode?`<div class="task-checkbox ${
|
|
2496
|
+
${this._bulkMode?`<div class="task-checkbox ${h?"checked":""}" data-check-id="${this._escapeHtml(c)}"></div>`:""}
|
|
2484
2497
|
<span class="task-id">${l.isLocal?"LOCAL":"#"+this._escapeHtml(c)}</span>
|
|
2485
2498
|
</div>
|
|
2486
2499
|
<div style="display:flex;align-items:center;gap:6px;">
|
|
@@ -2542,7 +2555,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
2542
2555
|
${i}
|
|
2543
2556
|
</div>
|
|
2544
2557
|
${this._selectedTask?this._renderTaskDetailModal(this._selectedTask):""}
|
|
2545
|
-
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("refresh-btn");t&&t.addEventListener("click",()=>this._loadTasks());let e=this.shadowRoot.getElementById("bulk-toggle-btn");e&&e.addEventListener("click",()=>this._toggleBulkMode()),this.shadowRoot.querySelectorAll(".filter-pill").forEach(s=>{s.addEventListener("click",()=>this._setFilter(s.dataset.filter))}),this.shadowRoot.querySelectorAll(".bulk-btn").forEach(s=>{s.addEventListener("click",()=>{let r=s.dataset.bulkAction;r==="delete"?this._bulkDelete():this._bulkMove(r)})}),this.shadowRoot.querySelectorAll(".add-task-btn").forEach(s=>{s.addEventListener("click",()=>{this._openAddTaskModal(s.dataset.status)})}),this.shadowRoot.querySelectorAll(".task-checkbox").forEach(s=>{s.addEventListener("click",r=>{r.stopPropagation(),this._toggleTaskSelection(s.dataset.checkId,r)})}),this.shadowRoot.querySelectorAll(".expand-toggle").forEach(s=>{s.addEventListener("click",r=>{r.stopPropagation(),this._toggleCardExpand(s.dataset.expandId)})}),this.shadowRoot.querySelectorAll(".task-card").forEach(s=>{let r=s.dataset.taskId,o=this._tasks.find(n=>n.id.toString()===r);o&&(s.addEventListener("click",n=>{if(this._bulkMode){this._toggleTaskSelection(r,n);return}this._openTaskDetail(o)}),s.addEventListener("keydown",n=>{n.key==="Enter"||n.key===" "?(n.preventDefault(),this._bulkMode?this._toggleTaskSelection(r,n):this._openTaskDetail(o)):(n.key==="ArrowDown"||n.key==="ArrowUp")&&(n.preventDefault(),this._navigateTaskCards(s,n.key==="ArrowDown"?"next":"prev"))}),s.classList.contains("draggable")&&(s.addEventListener("dragstart",n=>this._handleDragStart(n,o)),s.addEventListener("dragend",n=>this._handleDragEnd(n))))}),this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(s=>{s.addEventListener("dragover",r=>this._handleDragOver(r)),s.addEventListener("dragenter",r=>this._handleDragEnter(r)),s.addEventListener("dragleave",r=>this._handleDragLeave(r)),s.addEventListener("drop",r=>this._handleDrop(r,s.dataset.status))});let i=this.shadowRoot.getElementById("modal-close-btn");i&&i.addEventListener("click",()=>this._closeTaskDetail());let a=this.shadowRoot.getElementById("task-detail-overlay");a&&a.addEventListener("click",s=>{s.target===a&&this._closeTaskDetail()})}_escapeHtml(t){let e=document.createElement("div");return e.textContent=t,e.innerHTML}_navigateTaskCards(t,e){let i=Array.from(this.shadowRoot.querySelectorAll(".task-card")),a=i.indexOf(t);if(a===-1)return;let s=e==="next"?a+1:a-1;s>=0&&s<i.length&&i[s].focus()}};customElements.get("loki-task-board")||customElements.define("loki-task-board",q);var J=class extends
|
|
2558
|
+
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("refresh-btn");t&&t.addEventListener("click",()=>this._loadTasks());let e=this.shadowRoot.getElementById("bulk-toggle-btn");e&&e.addEventListener("click",()=>this._toggleBulkMode()),this.shadowRoot.querySelectorAll(".filter-pill").forEach(s=>{s.addEventListener("click",()=>this._setFilter(s.dataset.filter))}),this.shadowRoot.querySelectorAll(".bulk-btn").forEach(s=>{s.addEventListener("click",()=>{let r=s.dataset.bulkAction;r==="delete"?this._bulkDelete():this._bulkMove(r)})}),this.shadowRoot.querySelectorAll(".add-task-btn").forEach(s=>{s.addEventListener("click",()=>{this._openAddTaskModal(s.dataset.status)})}),this.shadowRoot.querySelectorAll(".task-checkbox").forEach(s=>{s.addEventListener("click",r=>{r.stopPropagation(),this._toggleTaskSelection(s.dataset.checkId,r)})}),this.shadowRoot.querySelectorAll(".expand-toggle").forEach(s=>{s.addEventListener("click",r=>{r.stopPropagation(),this._toggleCardExpand(s.dataset.expandId)})}),this.shadowRoot.querySelectorAll(".task-card").forEach(s=>{let r=s.dataset.taskId,o=this._tasks.find(n=>n.id.toString()===r);o&&(s.addEventListener("click",n=>{if(this._bulkMode){this._toggleTaskSelection(r,n);return}this._openTaskDetail(o)}),s.addEventListener("keydown",n=>{n.key==="Enter"||n.key===" "?(n.preventDefault(),this._bulkMode?this._toggleTaskSelection(r,n):this._openTaskDetail(o)):(n.key==="ArrowDown"||n.key==="ArrowUp")&&(n.preventDefault(),this._navigateTaskCards(s,n.key==="ArrowDown"?"next":"prev"))}),s.classList.contains("draggable")&&(s.addEventListener("dragstart",n=>this._handleDragStart(n,o)),s.addEventListener("dragend",n=>this._handleDragEnd(n))))}),this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(s=>{s.addEventListener("dragover",r=>this._handleDragOver(r)),s.addEventListener("dragenter",r=>this._handleDragEnter(r)),s.addEventListener("dragleave",r=>this._handleDragLeave(r)),s.addEventListener("drop",r=>this._handleDrop(r,s.dataset.status))});let i=this.shadowRoot.getElementById("modal-close-btn");i&&i.addEventListener("click",()=>this._closeTaskDetail());let a=this.shadowRoot.getElementById("task-detail-overlay");a&&a.addEventListener("click",s=>{s.target===a&&this._closeTaskDetail()})}_escapeHtml(t){let e=document.createElement("div");return e.textContent=t,e.innerHTML}_navigateTaskCards(t,e){let i=Array.from(this.shadowRoot.querySelectorAll(".task-card")),a=i.indexOf(t);if(a===-1)return;let s=e==="next"?a+1:a-1;s>=0&&s<i.length&&i[s].focus()}};customElements.get("loki-task-board")||customElements.define("loki-task-board",q);var J=class extends u{static get observedAttributes(){return["api-url","theme","compact"]}constructor(){super(),this._status={mode:"offline",phase:null,iteration:null,complexity:null,connected:!1,version:null,uptime:0,activeAgents:0,pendingTasks:0},this._api=null,this._state=P(),this._statusUpdateHandler=null,this._connectedHandler=null,this._disconnectedHandler=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(v.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(v.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(v.DISCONNECTED,this._disconnectedHandler))}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadStatus()),t==="theme"&&this._applyTheme(),t==="compact"&&this.render())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t}),this._statusUpdateHandler=e=>this._updateFromStatus(e.detail),this._connectedHandler=()=>{this._status.connected=!0,this.render()},this._disconnectedHandler=()=>{this._status.connected=!1,this._status.mode="offline",this.render()},this._api.addEventListener(v.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(v.CONNECTED,this._connectedHandler),this._api.addEventListener(v.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){try{let t=await this._api.getStatus();this._updateFromStatus(t)}catch{this._status.connected=!1,this._status.mode="offline",this.render()}}_updateFromStatus(t){t&&(this._status={...this._status,connected:!0,mode:t.status||"running",version:t.version,uptime:t.uptime_seconds||0,activeAgents:t.running_agents||0,pendingTasks:t.pending_tasks||0,phase:t.phase,iteration:t.iteration,complexity:t.complexity},this._state.updateSession({connected:!0,mode:this._status.mode,lastSync:new Date().toISOString()}),this.render())}_startPolling(){this._ownPollInterval=setInterval(async()=>{try{let t=await this._api.getStatus();this._updateFromStatus(t)}catch{this._status.connected=!1,this._status.mode="offline",this.render()}},3e3)}_stopPolling(){this._ownPollInterval&&(clearInterval(this._ownPollInterval),this._ownPollInterval=null)}_formatUptime(t){if(!t||t<0)return"--";let e=Math.floor(t/3600),i=Math.floor(t%3600/60),a=Math.floor(t%60);return e>0?`${e}h ${i}m`:i>0?`${i}m ${a}s`:`${a}s`}_escapeHtml(t){let e=document.createElement("div");return e.textContent=String(t??""),e.innerHTML}_getStatusClass(){switch(this._status.mode){case"running":case"autonomous":return"active";case"paused":return"paused";case"stopped":return"stopped";case"error":return"error";default:return"offline"}}_getStatusLabel(){switch(this._status.mode){case"running":case"autonomous":return"AUTONOMOUS";case"paused":return"PAUSED";case"stopped":return"STOPPED";case"error":return"ERROR";default:return"OFFLINE"}}_triggerStart(){this.dispatchEvent(new CustomEvent("session-start",{detail:this._status}))}async _triggerPause(){try{let t=await this._api.pauseSession();if(t&&t.error)throw new Error(t.error);this._status.mode="paused",this.render(),this.dispatchEvent(new CustomEvent("session-pause",{detail:this._status}))}catch(t){console.error("Failed to pause session:",t),this.render()}}async _triggerResume(){try{let t=await this._api.resumeSession();if(t&&t.error)throw new Error(t.error);this._status.mode="running",this.render(),this.dispatchEvent(new CustomEvent("session-resume",{detail:this._status}))}catch(t){console.error("Failed to resume session:",t),this.render()}}async _triggerStop(){try{let t=await this._api.stopSession();if(t&&t.error)throw new Error(t.error);this._status.mode="stopped",this.render(),this.dispatchEvent(new CustomEvent("session-stop",{detail:this._status}))}catch(t){console.error("Failed to stop session:",t),this.render()}}render(){let t=this.hasAttribute("compact"),e=this._getStatusClass(),i=this._getStatusLabel(),a=["running","autonomous"].includes(this._status.mode),s=this._status.mode==="paused",r=`
|
|
2546
2559
|
<style>
|
|
2547
2560
|
${this.getBaseStyles()}
|
|
2548
2561
|
|
|
@@ -2821,9 +2834,9 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
2821
2834
|
`;this.shadowRoot.innerHTML=`
|
|
2822
2835
|
${r}
|
|
2823
2836
|
${t?o:n}
|
|
2824
|
-
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("pause-btn"),e=this.shadowRoot.getElementById("resume-btn"),i=this.shadowRoot.getElementById("stop-btn"),a=this.shadowRoot.getElementById("start-btn");t&&t.addEventListener("click",()=>this._triggerPause()),e&&e.addEventListener("click",()=>this._triggerResume()),i&&i.addEventListener("click",()=>this._triggerStop()),a&&a.addEventListener("click",()=>this._triggerStart())}};customElements.get("loki-session-control")||customElements.define("loki-session-control",J);var
|
|
2837
|
+
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("pause-btn"),e=this.shadowRoot.getElementById("resume-btn"),i=this.shadowRoot.getElementById("stop-btn"),a=this.shadowRoot.getElementById("start-btn");t&&t.addEventListener("click",()=>this._triggerPause()),e&&e.addEventListener("click",()=>this._triggerResume()),i&&i.addEventListener("click",()=>this._triggerStop()),a&&a.addEventListener("click",()=>this._triggerStart())}};customElements.get("loki-session-control")||customElements.define("loki-session-control",J);var Ut={info:{color:"var(--loki-blue)",label:"INFO"},success:{color:"var(--loki-green)",label:"SUCCESS"},warning:{color:"var(--loki-yellow)",label:"WARN"},error:{color:"var(--loki-red)",label:"ERROR"},step:{color:"var(--loki-purple)",label:"STEP"},agent:{color:"var(--loki-accent)",label:"AGENT"},debug:{color:"var(--loki-text-muted)",label:"DEBUG"}},G=class extends u{static get observedAttributes(){return["api-url","max-lines","auto-scroll","theme","log-file"]}constructor(){super(),this._logs=[],this._maxLines=500,this._autoScroll=!0,this._filter="",this._levelFilter="all",this._api=null,this._pollInterval=null,this._logMessageHandler=null}connectedCallback(){super.connectedCallback(),this._maxLines=parseInt(this.getAttribute("max-lines"))||500,this._autoScroll=this.hasAttribute("auto-scroll"),this._setupApi(),this._startLogPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopLogPolling(),this._api&&this._logMessageHandler&&this._api.removeEventListener(v.LOG_MESSAGE,this._logMessageHandler)}attributeChangedCallback(t,e,i){if(e!==i)switch(t){case"api-url":this._api&&(this._api.baseUrl=i);break;case"max-lines":this._maxLines=parseInt(i)||500,this._trimLogs(),this.render();break;case"auto-scroll":this._autoScroll=this.hasAttribute("auto-scroll"),this.render();break;case"theme":this._applyTheme();break}}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t}),this._logMessageHandler=e=>this._addLog(e.detail),this._api.addEventListener(v.LOG_MESSAGE,this._logMessageHandler)}_startLogPolling(){let t=this.getAttribute("log-file");t?this._pollLogFile(t):this._pollApiLogs()}async _pollApiLogs(){let t=0,e=async()=>{try{let i=await this._api.getLogs(200);if(Array.isArray(i)&&i.length>t){let a=i.slice(t);for(let s of a)s.message&&s.message.trim()&&this._addLog({message:s.message,level:s.level||"info",timestamp:s.timestamp||new Date().toLocaleTimeString()});t=i.length}}catch{}};e(),this._apiPollInterval=setInterval(e,2e3)}async _pollLogFile(t){let e=0,i=async()=>{try{let a=await fetch(`${t}?t=${Date.now()}`,{credentials:"include"});if(!a.ok)return;let r=(await a.text()).split(`
|
|
2825
2838
|
`);if(r.length>e){let o=r.slice(e);for(let n of o)n.trim()&&this._addLog(this._parseLine(n));e=r.length}}catch{}};i(),this._pollInterval=setInterval(i,1e3)}_stopLogPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._apiPollInterval&&(clearInterval(this._apiPollInterval),this._apiPollInterval=null)}_parseLine(t){let e=t.match(/^\[([^\]]+)\]\s*\[([^\]]+)\]\s*(.+)$/);if(e)return{timestamp:e[1],level:e[2].toLowerCase(),message:e[3]};let i=t.match(/^(\d{2}:\d{2}:\d{2})\s+(\w+)\s+(.+)$/);return i?{timestamp:i[1],level:i[2].toLowerCase(),message:i[3]}:{timestamp:new Date().toLocaleTimeString(),level:"info",message:t}}_addLog(t){if(!t)return;let e={id:Date.now()+Math.random(),timestamp:t.timestamp||new Date().toLocaleTimeString(),level:(t.level||"info").toLowerCase(),message:t.message||t};this._logs.push(e),this._trimLogs(),this.dispatchEvent(new CustomEvent("log-received",{detail:e})),this._renderLogs(),this._autoScroll&&this._scrollToBottom()}_trimLogs(){this._logs.length>this._maxLines&&(this._logs=this._logs.slice(-this._maxLines))}_clearLogs(){this._logs=[],this.dispatchEvent(new CustomEvent("logs-cleared")),this._renderLogs()}_toggleAutoScroll(){this._autoScroll=!this._autoScroll,this.render(),this._autoScroll&&this._scrollToBottom()}_scrollToBottom(){requestAnimationFrame(()=>{let t=this.shadowRoot.getElementById("log-output");t&&(t.scrollTop=t.scrollHeight)})}_downloadLogs(){let t=this._logs.map(s=>`[${s.timestamp}] [${s.level.toUpperCase()}] ${s.message}`).join(`
|
|
2826
|
-
`),e=new Blob([t],{type:"text/plain"}),i=URL.createObjectURL(e),a=document.createElement("a");a.href=i,a.download=`loki-logs-${new Date().toISOString().split("T")[0]}.txt`,a.click(),URL.revokeObjectURL(i)}_setFilter(t){this._filter=t.toLowerCase(),this._renderLogs()}_setLevelFilter(t){this._levelFilter=t,this._renderLogs()}_getFilteredLogs(){return this._logs.filter(t=>!(this._levelFilter!=="all"&&t.level!==this._levelFilter||this._filter&&!t.message.toLowerCase().includes(this._filter)))}_renderLogs(){let t=this.shadowRoot.getElementById("log-output");if(!t)return;let e=this._getFilteredLogs();if(e.length===0){t.innerHTML='<div class="log-empty">No log output yet. Terminal will update when Loki Mode is running.</div>';return}t.innerHTML=e.map(i=>{let a=
|
|
2839
|
+
`),e=new Blob([t],{type:"text/plain"}),i=URL.createObjectURL(e),a=document.createElement("a");a.href=i,a.download=`loki-logs-${new Date().toISOString().split("T")[0]}.txt`,a.click(),URL.revokeObjectURL(i)}_setFilter(t){this._filter=t.toLowerCase(),this._renderLogs()}_setLevelFilter(t){this._levelFilter=t,this._renderLogs()}_getFilteredLogs(){return this._logs.filter(t=>!(this._levelFilter!=="all"&&t.level!==this._levelFilter||this._filter&&!t.message.toLowerCase().includes(this._filter)))}_renderLogs(){let t=this.shadowRoot.getElementById("log-output");if(!t)return;let e=this._getFilteredLogs();if(e.length===0){t.innerHTML='<div class="log-empty">No log output yet. Terminal will update when Loki Mode is running.</div>';return}t.innerHTML=e.map(i=>{let a=Ut[i.level]||Ut.info;return`
|
|
2827
2840
|
<div class="log-line">
|
|
2828
2841
|
<span class="timestamp">${this._escapeHtml(i.timestamp)}</span>
|
|
2829
2842
|
<span class="level" style="color: ${a.color}">[${this._escapeHtml(a.label)}]</span>
|
|
@@ -3022,7 +3035,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
3022
3035
|
${this._logs.length} lines (${this._getFilteredLogs().length} shown)
|
|
3023
3036
|
</div>
|
|
3024
3037
|
</div>
|
|
3025
|
-
`,this._attachEventListeners(),this._renderLogs()}_attachEventListeners(){let t=this.shadowRoot.getElementById("filter-input"),e=this.shadowRoot.getElementById("level-select"),i=this.shadowRoot.getElementById("auto-scroll-btn"),a=this.shadowRoot.getElementById("clear-btn"),s=this.shadowRoot.getElementById("download-btn");t&&(t.value=this._filter,t.addEventListener("input",r=>this._setFilter(r.target.value))),e&&(e.value=this._levelFilter,e.addEventListener("change",r=>this._setLevelFilter(r.target.value))),i&&i.addEventListener("click",()=>this._toggleAutoScroll()),a&&a.addEventListener("click",()=>this._clearLogs()),s&&s.addEventListener("click",()=>this._downloadLogs())}addLog(t,e="info"){this._addLog({message:t,level:e,timestamp:new Date().toLocaleTimeString()})}clear(){this._clearLogs()}};customElements.get("loki-log-stream")||customElements.define("loki-log-stream",G);var
|
|
3038
|
+
`,this._attachEventListeners(),this._renderLogs()}_attachEventListeners(){let t=this.shadowRoot.getElementById("filter-input"),e=this.shadowRoot.getElementById("level-select"),i=this.shadowRoot.getElementById("auto-scroll-btn"),a=this.shadowRoot.getElementById("clear-btn"),s=this.shadowRoot.getElementById("download-btn");t&&(t.value=this._filter,t.addEventListener("input",r=>this._setFilter(r.target.value))),e&&(e.value=this._levelFilter,e.addEventListener("change",r=>this._setLevelFilter(r.target.value))),i&&i.addEventListener("click",()=>this._toggleAutoScroll()),a&&a.addEventListener("click",()=>this._clearLogs()),s&&s.addEventListener("click",()=>this._downloadLogs())}addLog(t,e="info"){this._addLog({message:t,level:e,timestamp:new Date().toLocaleTimeString()})}clear(){this._clearLogs()}};customElements.get("loki-log-stream")||customElements.define("loki-log-stream",G);var de=[{id:"summary",label:"Summary",icon:"M4 6h16M4 12h16M4 18h16"},{id:"search",label:"Search",icon:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"},{id:"episodes",label:"Episodes",icon:"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"},{id:"patterns",label:"Patterns",icon:"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"},{id:"skills",label:"Skills",icon:"M13 10V3L4 14h7v7l9-11h-7z"}],K=class extends u{static get observedAttributes(){return["api-url","theme","tab"]}constructor(){super(),this._activeTab="summary",this._loading=!1,this._error=null,this._api=null,this._summary=null,this._stats=null,this._episodes=[],this._patterns=[],this._skills=[],this._tokenEconomics=null,this._selectedItem=null,this._lastFocusedElement=null,this._searchQuery="",this._searchCollection="all",this._searchResults=[],this._searchLoading=!1,this._searchError=null}connectedCallback(){super.connectedCallback(),this._activeTab=this.getAttribute("tab")||"summary",this._setupApi(),this._loadData()}attributeChangedCallback(t,e,i){if(e!==i)switch(t){case"api-url":this._api&&(this._api.baseUrl=i,this._loadData());break;case"theme":this._applyTheme();break;case"tab":this._setTab(i);break}}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _loadData(){this._loading=!0,this._error=null,this.render();try{let[t,e,i]=await Promise.allSettled([this._api.getMemorySummary(),this._api.getTokenEconomics(),this._api.getMemoryStats()]);this._summary=t.status==="fulfilled"?t.value:null,this._tokenEconomics=e.status==="fulfilled"?e.value:null,this._stats=i.status==="fulfilled"?i.value:null,await this._loadTabData()}catch(t){this._error=t.message||"Failed to load memory data"}this._loading=!1,this.render()}async _loadTabData(){switch(this._activeTab){case"episodes":this._episodes=await this._api.listEpisodes({limit:50}).catch(()=>[]);break;case"patterns":this._patterns=await this._api.listPatterns().catch(()=>[]);break;case"skills":this._skills=await this._api.listSkills().catch(()=>[]);break}}_setTab(t){this._activeTab!==t&&(this._activeTab=t,this._selectedItem=null,this._loadTabData().then(()=>this.render()))}async _selectEpisode(t){try{this._lastFocusedElement=this.shadowRoot.activeElement,this._selectedItem=await this._api.getEpisode(t),this.dispatchEvent(new CustomEvent("episode-select",{detail:this._selectedItem})),this.render(),this._focusDetailPanel()}catch(e){console.error("Failed to load episode:",e)}}async _selectPattern(t){try{this._lastFocusedElement=this.shadowRoot.activeElement,this._selectedItem=await this._api.getPattern(t),this.dispatchEvent(new CustomEvent("pattern-select",{detail:this._selectedItem})),this.render(),this._focusDetailPanel()}catch(e){console.error("Failed to load pattern:",e)}}async _selectSkill(t){try{this._lastFocusedElement=this.shadowRoot.activeElement,this._selectedItem=await this._api.getSkill(t),this.dispatchEvent(new CustomEvent("skill-select",{detail:this._selectedItem})),this.render(),this._focusDetailPanel()}catch(e){console.error("Failed to load skill:",e)}}_focusDetailPanel(){requestAnimationFrame(()=>{let t=this.shadowRoot.getElementById("close-detail");t&&t.focus()})}_closeDetail(){this._selectedItem=null,this.render(),this._lastFocusedElement&&requestAnimationFrame(()=>{this._lastFocusedElement.focus(),this._lastFocusedElement=null})}async _triggerConsolidation(){try{let t=await this._api.consolidateMemory(24);alert(`Consolidation complete:
|
|
3026
3039
|
- Patterns created: ${t.patternsCreated}
|
|
3027
3040
|
- Patterns merged: ${t.patternsMerged}
|
|
3028
3041
|
- Episodes processed: ${t.episodesProcessed}`),this._loadData()}catch(t){alert("Consolidation failed: "+t.message)}}async _executeSearch(){let t=this._searchQuery.trim();if(t){this._searchLoading=!0,this._searchError=null,this.render();try{let e=await this._api.searchMemory(t,this._searchCollection,20);this._searchResults=e.results||[]}catch(e){this._searchError=e.message||"Search failed",this._searchResults=[]}this._searchLoading=!1,this.render(),requestAnimationFrame(()=>{let e=this.shadowRoot.getElementById("memory-search-input");e&&e.focus()})}}_renderSearch(){let t=["all","episodes","patterns","skills"];return`
|
|
@@ -3893,7 +3906,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
3893
3906
|
<span class="browser-title">Memory System</span>
|
|
3894
3907
|
</div>
|
|
3895
3908
|
<div class="tabs" role="tablist" aria-label="Memory browser sections">
|
|
3896
|
-
${
|
|
3909
|
+
${de.map((i,a)=>`
|
|
3897
3910
|
<button class="tab ${this._activeTab===i.id?"active":""}"
|
|
3898
3911
|
data-tab="${i.id}"
|
|
3899
3912
|
role="tab"
|
|
@@ -3910,12 +3923,12 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
3910
3923
|
${e}
|
|
3911
3924
|
</div>
|
|
3912
3925
|
</div>
|
|
3913
|
-
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.querySelectorAll(".tab");t.forEach((n,l)=>{n.addEventListener("click",()=>this._setTab(n.dataset.tab)),n.addEventListener("keydown",c=>{if(c.key==="ArrowRight"||c.key==="ArrowLeft"){c.preventDefault();let p=Array.from(t),
|
|
3926
|
+
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.querySelectorAll(".tab");t.forEach((n,l)=>{n.addEventListener("click",()=>this._setTab(n.dataset.tab)),n.addEventListener("keydown",c=>{if(c.key==="ArrowRight"||c.key==="ArrowLeft"){c.preventDefault();let p=Array.from(t),h=c.key==="ArrowRight"?(l+1)%p.length:(l-1+p.length)%p.length;p[h].focus(),this._setTab(p[h].dataset.tab)}})}),this.shadowRoot.querySelectorAll(".item-card").forEach(n=>{n.addEventListener("click",()=>this._handleItemClick(n)),n.addEventListener("keydown",l=>{l.key==="Enter"||l.key===" "?(l.preventDefault(),this._handleItemClick(n)):(l.key==="ArrowDown"||l.key==="ArrowUp")&&(l.preventDefault(),this._navigateItemCards(n,l.key==="ArrowDown"?"next":"prev"))})});let e=this.shadowRoot.getElementById("close-detail");e&&e.addEventListener("click",()=>this._closeDetail());let i=this.shadowRoot.getElementById("consolidate-btn");i&&i.addEventListener("click",()=>this._triggerConsolidation());let a=this.shadowRoot.getElementById("refresh-btn");a&&a.addEventListener("click",()=>this._loadData());let s=this.shadowRoot.getElementById("memory-search-input"),r=this.shadowRoot.getElementById("search-btn"),o=this.shadowRoot.getElementById("memory-search-collection");s&&(s.addEventListener("keydown",n=>{n.key==="Enter"&&(n.preventDefault(),this._searchQuery=s.value,this._executeSearch())}),s.addEventListener("input",n=>{this._searchQuery=n.target.value})),r&&r.addEventListener("click",()=>{let n=this.shadowRoot.getElementById("memory-search-input");n&&(this._searchQuery=n.value),this._executeSearch()}),o&&o.addEventListener("change",n=>{this._searchCollection=n.target.value})}_handleItemClick(t){let e=t.dataset.id;switch(t.dataset.type){case"episode":this._selectEpisode(e);break;case"pattern":this._selectPattern(e);break;case"skill":this._selectSkill(e);break}}_navigateItemCards(t,e){let i=Array.from(this.shadowRoot.querySelectorAll(".item-card")),a=i.indexOf(t);if(a===-1)return;let s=e==="next"?a+1:a-1;s>=0&&s<i.length&&i[s].focus()}};customElements.get("loki-memory-browser")||customElements.define("loki-memory-browser",K);var ce=[{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}],pe=[{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"}],ue=[{id:"all",label:"All Sources"},{id:"cli",label:"CLI"},{id:"api",label:"API"},{id:"vscode",label:"VS Code"},{id:"mcp",label:"MCP"},{id:"dashboard",label:"Dashboard"}],V=class extends u{static get observedAttributes(){return["api-url","theme","time-range","signal-type","source"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._timeRange="7d",this._signalType="all",this._source="all",this._metrics=null,this._trends=null,this._signals=[],this._selectedMetric=null}connectedCallback(){super.connectedCallback(),this._timeRange=this.getAttribute("time-range")||"7d",this._signalType=this.getAttribute("signal-type")||"all",this._source=this.getAttribute("source")||"all",this._setupApi(),this._loadData()}attributeChangedCallback(t,e,i){if(e!==i)switch(t){case"api-url":this._api&&(this._api.baseUrl=i,this._loadData());break;case"theme":this._applyTheme();break;case"time-range":this._timeRange=i,this._loadData();break;case"signal-type":this._signalType=i,this._loadData();break;case"source":this._source=i,this._loadData();break}}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _loadData(){this._loading=!0,this._error=null,this.render();try{let t={timeRange:this._timeRange,signalType:this._signalType!=="all"?this._signalType:void 0,source:this._source!=="all"?this._source:void 0},[e,i,a]=await Promise.all([this._api.getLearningMetrics(t).catch(()=>null),this._api.getLearningTrends(t).catch(()=>null),this._api.getLearningSignals({...t,limit:50}).catch(()=>[])]);this._metrics=e,this._trends=i,this._signals=a||[]}catch(t){this._error=t.message||"Failed to load learning data"}this._loading=!1,this.render()}_setFilter(t,e){switch(t){case"timeRange":this._timeRange=e,this.setAttribute("time-range",e);break;case"signalType":this._signalType=e,this.setAttribute("signal-type",e);break;case"source":this._source=e,this.setAttribute("source",e);break}this.dispatchEvent(new CustomEvent("filter-change",{detail:{timeRange:this._timeRange,signalType:this._signalType,source:this._source}})),this._loadData()}_selectMetric(t,e){this._selectedMetric={type:t,item:e},this.dispatchEvent(new CustomEvent("metric-select",{detail:{type:t,item:e}})),this.render()}_closeDetail(){this._selectedMetric=null,this.render()}_formatNumber(t){return t>=1e6?(t/1e6).toFixed(1)+"M":t>=1e3?(t/1e3).toFixed(1)+"K":t?.toString()||"0"}_formatPercent(t){return(t*100).toFixed(1)+"%"}_formatDuration(t){return t<60?t.toFixed(0)+"s":t<3600?(t/60).toFixed(1)+"m":(t/3600).toFixed(1)+"h"}_escapeHtml(t){if(!t)return"";let e=document.createElement("div");return e.textContent=t,e.innerHTML}_renderFilters(){return`
|
|
3914
3927
|
<div class="filters">
|
|
3915
3928
|
<div class="filter-group">
|
|
3916
3929
|
<label>Time Range</label>
|
|
3917
3930
|
<select id="time-range-select" class="filter-select">
|
|
3918
|
-
${
|
|
3931
|
+
${ce.map(t=>`
|
|
3919
3932
|
<option value="${t.id}" ${this._timeRange===t.id?"selected":""}>${t.label}</option>
|
|
3920
3933
|
`).join("")}
|
|
3921
3934
|
</select>
|
|
@@ -3923,7 +3936,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
3923
3936
|
<div class="filter-group">
|
|
3924
3937
|
<label>Signal Type</label>
|
|
3925
3938
|
<select id="signal-type-select" class="filter-select">
|
|
3926
|
-
${
|
|
3939
|
+
${pe.map(t=>`
|
|
3927
3940
|
<option value="${t.id}" ${this._signalType===t.id?"selected":""}>${t.label}</option>
|
|
3928
3941
|
`).join("")}
|
|
3929
3942
|
</select>
|
|
@@ -3931,7 +3944,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
3931
3944
|
<div class="filter-group">
|
|
3932
3945
|
<label>Source</label>
|
|
3933
3946
|
<select id="source-select" class="filter-select">
|
|
3934
|
-
${
|
|
3947
|
+
${ue.map(t=>`
|
|
3935
3948
|
<option value="${t.id}" ${this._source===t.id?"selected":""}>${t.label}</option>
|
|
3936
3949
|
`).join("")}
|
|
3937
3950
|
</select>
|
|
@@ -4922,7 +4935,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
4922
4935
|
${e}
|
|
4923
4936
|
</div>
|
|
4924
4937
|
</div>
|
|
4925
|
-
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("time-range-select");t&&t.addEventListener("change",r=>this._setFilter("timeRange",r.target.value));let e=this.shadowRoot.getElementById("signal-type-select");e&&e.addEventListener("change",r=>this._setFilter("signalType",r.target.value));let i=this.shadowRoot.getElementById("source-select");i&&i.addEventListener("change",r=>this._setFilter("source",r.target.value));let a=this.shadowRoot.getElementById("refresh-btn");a&&a.addEventListener("click",()=>this._loadData());let s=this.shadowRoot.getElementById("close-detail");s&&s.addEventListener("click",()=>this._closeDetail()),this.shadowRoot.querySelectorAll(".list-item").forEach(r=>{r.addEventListener("click",()=>{let o=r.dataset.type,n=r.dataset.id,l=this._findItemData(o,n);l&&this._selectMetric(o,l)}),r.addEventListener("keydown",o=>{(o.key==="Enter"||o.key===" ")&&(o.preventDefault(),r.click())})})}_findItemData(t,e){if(!this._metrics?.aggregation)return null;switch(t){case"preference":return this._metrics.aggregation.preferences?.find(i=>i.preference_key===e);case"error_pattern":return this._metrics.aggregation.error_patterns?.find(i=>i.error_type===e);case"success_pattern":return this._metrics.aggregation.success_patterns?.find(i=>i.pattern_name===e);case"tool_efficiency":return this._metrics.aggregation.tool_efficiencies?.find(i=>i.tool_name===e);default:return null}}};customElements.get("loki-learning-dashboard")||customElements.define("loki-learning-dashboard",V);var
|
|
4938
|
+
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot.getElementById("time-range-select");t&&t.addEventListener("change",r=>this._setFilter("timeRange",r.target.value));let e=this.shadowRoot.getElementById("signal-type-select");e&&e.addEventListener("change",r=>this._setFilter("signalType",r.target.value));let i=this.shadowRoot.getElementById("source-select");i&&i.addEventListener("change",r=>this._setFilter("source",r.target.value));let a=this.shadowRoot.getElementById("refresh-btn");a&&a.addEventListener("click",()=>this._loadData());let s=this.shadowRoot.getElementById("close-detail");s&&s.addEventListener("click",()=>this._closeDetail()),this.shadowRoot.querySelectorAll(".list-item").forEach(r=>{r.addEventListener("click",()=>{let o=r.dataset.type,n=r.dataset.id,l=this._findItemData(o,n);l&&this._selectMetric(o,l)}),r.addEventListener("keydown",o=>{(o.key==="Enter"||o.key===" ")&&(o.preventDefault(),r.click())})})}_findItemData(t,e){if(!this._metrics?.aggregation)return null;switch(t){case"preference":return this._metrics.aggregation.preferences?.find(i=>i.preference_key===e);case"error_pattern":return this._metrics.aggregation.error_patterns?.find(i=>i.error_type===e);case"success_pattern":return this._metrics.aggregation.success_patterns?.find(i=>i.pattern_name===e);case"tool_efficiency":return this._metrics.aggregation.tool_efficiencies?.find(i=>i.tool_name===e);default:return null}}};customElements.get("loki-learning-dashboard")||customElements.define("loki-learning-dashboard",V);var he=[{id:"overview",label:"Overview"},{id:"decisions",label:"Decision Log"},{id:"convergence",label:"Convergence"},{id:"agents",label:"Agents"}],Y=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._activeTab="overview",this._pollInterval=null,this._councilState=null,this._verdicts=[],this._convergence=[],this._agents=[],this._selectedAgent=null,this._lastDataHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),3e3),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadData(),this._pollInterval=setInterval(()=>this._loadData(),3e3))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null),this._pendingRaf&&(cancelAnimationFrame(this._pendingRaf),this._pendingRaf=null)}async _loadData(){try{let[e,i,a,s]=await Promise.allSettled([this._api._get("/api/council/state"),this._api._get("/api/council/verdicts"),this._api._get("/api/council/convergence"),this._api._get("/api/agents")]);e.status==="fulfilled"&&(this._councilState=e.value),i.status==="fulfilled"&&(this._verdicts=i.value.verdicts||[]),a.status==="fulfilled"&&(this._convergence=a.value.dataPoints||[]),s.status==="fulfilled"&&(this._agents=Array.isArray(s.value)?s.value:[]),this._error=null}catch(e){this._error=e.message}let t=JSON.stringify({s:this._councilState,v:this._verdicts,c:this._convergence,a:this._agents,e:this._error});t!==this._lastDataHash&&(this._lastDataHash=t,this.render())}async _forceReview(){try{await this._api._post("/api/council/force-review"),this.dispatchEvent(new CustomEvent("council-action",{detail:{action:"force-review"},bubbles:!0}))}catch(t){this._error=`Failed to force review: ${t.message}`,this.render()}}async _killAgent(t){if(confirm(`Kill agent ${t}?`))try{await this._api._post(`/api/agents/${t}/kill`),this.dispatchEvent(new CustomEvent("council-action",{detail:{action:"kill-agent",agentId:t},bubbles:!0})),await this._loadData()}catch(e){this._error=`Failed to kill agent: ${e.message}`,this.render()}}async _pauseAgent(t){try{await this._api._post(`/api/agents/${t}/pause`),await this._loadData()}catch(e){this._error=`Failed to pause agent: ${e.message}`,this.render()}}async _resumeAgent(t){try{await this._api._post(`/api/agents/${t}/resume`),await this._loadData()}catch(e){this._error=`Failed to resume agent: ${e.message}`,this.render()}}_setTab(t){this._activeTab=t,this.render()}_selectAgent(t){this._selectedAgent=this._selectedAgent?.id===t.id?null:t,this.render()}render(){let t=this.shadowRoot;t&&(this._pendingRaf&&(cancelAnimationFrame(this._pendingRaf),this._pendingRaf=null),t.innerHTML=`
|
|
4926
4939
|
<style>${this.getBaseStyles()}${this._getStyles()}</style>
|
|
4927
4940
|
<div class="council-dashboard">
|
|
4928
4941
|
<div class="council-header">
|
|
@@ -4936,7 +4949,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
4936
4949
|
</div>
|
|
4937
4950
|
|
|
4938
4951
|
<div class="tabs">
|
|
4939
|
-
${
|
|
4952
|
+
${he.map(e=>`
|
|
4940
4953
|
<button
|
|
4941
4954
|
class="tab ${this._activeTab===e.id?"active":""}"
|
|
4942
4955
|
data-tab="${e.id}"
|
|
@@ -5509,7 +5522,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
5509
5522
|
color: var(--loki-error);
|
|
5510
5523
|
font-size: 12px;
|
|
5511
5524
|
}
|
|
5512
|
-
`}};customElements.get("loki-council-dashboard")||customElements.define("loki-council-dashboard",Y);var
|
|
5525
|
+
`}};customElements.get("loki-council-dashboard")||customElements.define("loki-council-dashboard",Y);var Nt={critical:0,major:1,minor:2},ge={critical:"var(--loki-status-error, #ef4444)",major:"var(--loki-status-warning, #f59e0b)",minor:"var(--loki-text-muted, #71717a)"},W=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._pollInterval=null,this._checklist=null,this._waivers=[],this._expandedCategories=new Set,this._lastDataHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),5e3),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadData(),this._pollInterval=setInterval(()=>this._loadData(),5e3))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null)}async _loadData(){try{let[t,e]=await Promise.all([this._api.getChecklist(),this._api.getChecklistWaivers().catch(()=>null)]),i=JSON.stringify(e),a=JSON.stringify(t)+i;if(a===this._lastDataHash)return;this._lastDataHash=a,this._checklist=t,this._waivers=e&&e.waivers?e.waivers.filter(s=>s.active):[],this._error=null,this.render()}catch(t){this._error=`Failed to load checklist: ${t.message}`,this.render()}}_isItemWaived(t){return this._waivers.some(e=>e.item_id===t)}_getWaiverForItem(t){return this._waivers.find(e=>e.item_id===t)||null}async _waiveItem(t){let e=window.prompt("Enter reason for waiving this item:");if(e)try{await this._api.addChecklistWaiver(t,e),this._lastDataHash=null,await this._loadData()}catch(i){this._error=`Failed to add waiver: ${i.message}`,this.render()}}async _unwaiveItem(t){try{await this._api.removeChecklistWaiver(t),this._lastDataHash=null,await this._loadData()}catch(e){this._error=`Failed to remove waiver: ${e.message}`,this.render()}}_toggleCategory(t){this._expandedCategories.has(t)?this._expandedCategories.delete(t):this._expandedCategories.add(t),this.render()}_getStyles(){return`
|
|
5513
5526
|
.checklist-viewer {
|
|
5514
5527
|
padding: 16px;
|
|
5515
5528
|
font-family: var(--loki-font-family, system-ui, -apple-system, sans-serif);
|
|
@@ -5798,13 +5811,13 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
5798
5811
|
</div>
|
|
5799
5812
|
${i?`<div class="category-body">${this._renderItems(a)}</div>`:""}
|
|
5800
5813
|
</div>
|
|
5801
|
-
`}).join(""):this._renderEmpty()}_renderItems(t){return t?.length?[...t].sort((i,a)=>(
|
|
5814
|
+
`}).join(""):this._renderEmpty()}_renderItems(t){return t?.length?[...t].sort((i,a)=>(Nt[i.priority]??2)-(Nt[a.priority]??2)).map(i=>{let a=i.status==="verified"?"status-verified":i.status==="failing"?"status-failing":"status-pending",s=["critical","major","minor"].includes(i.priority)?i.priority:"minor",r=ge[s],o=i.verification||[],n=this._getWaiverForItem(i.id),l=!!n,c=i.status==="failing"&&(s==="critical"||s==="major"),p=l?`<span class="item-waived-badge" title="${this._escapeHtml(n.reason||"No reason provided")}">WAIVED</span>`:"",h="";return c&&(l?h=`<button class="waiver-btn waiver-btn-unwaive" data-unwaive-id="${this._escapeHtml(i.id)}">Unwaive</button>`:h=`<button class="waiver-btn" data-waive-id="${this._escapeHtml(i.id)}">Waive</button>`),`
|
|
5802
5815
|
<div class="item">
|
|
5803
5816
|
<div class="item-status ${a}"></div>
|
|
5804
5817
|
<div class="item-title">${this._escapeHtml(i.title||i.id||"?")}</div>
|
|
5805
5818
|
<span class="item-priority" style="color:${r};border:1px solid ${r}">${s}</span>
|
|
5806
5819
|
${p}
|
|
5807
|
-
${
|
|
5820
|
+
${h}
|
|
5808
5821
|
<div class="verification-dots">
|
|
5809
5822
|
${o.map(b=>`<div class="v-dot ${b.passed===!0?"v-dot-pass":b.passed===!1?"v-dot-fail":"v-dot-pending"}" title="${this._escapeHtml(b.type||"")}"></div>`).join("")}
|
|
5810
5823
|
</div>
|
|
@@ -5814,7 +5827,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
5814
5827
|
<p><strong>No checklist data yet.</strong></p>
|
|
5815
5828
|
<p class="hint">The spec checklist is generated during the first iteration. Start a session with <code>loki start ./spec.md</code> (PRD files also accepted) -- groups and items will appear here as the session progresses and can be expanded for details.</p>
|
|
5816
5829
|
</div>
|
|
5817
|
-
`}_attachEventListeners(){let t=this.shadowRoot;t&&(t.querySelectorAll(".category-header[data-category]").forEach(e=>{e.addEventListener("click",()=>this._toggleCategory(e.dataset.category))}),t.querySelectorAll("button[data-waive-id]").forEach(e=>{e.addEventListener("click",i=>{i.stopPropagation(),this._waiveItem(e.dataset.waiveId)})}),t.querySelectorAll("button[data-unwaive-id]").forEach(e=>{e.addEventListener("click",i=>{i.stopPropagation(),this._unwaiveItem(e.dataset.unwaiveId)})}))}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}};customElements.define("loki-checklist-viewer",W);var
|
|
5830
|
+
`}_attachEventListeners(){let t=this.shadowRoot;t&&(t.querySelectorAll(".category-header[data-category]").forEach(e=>{e.addEventListener("click",()=>this._toggleCategory(e.dataset.category))}),t.querySelectorAll("button[data-waive-id]").forEach(e=>{e.addEventListener("click",i=>{i.stopPropagation(),this._waiveItem(e.dataset.waiveId)})}),t.querySelectorAll("button[data-unwaive-id]").forEach(e=>{e.addEventListener("click",i=>{i.stopPropagation(),this._unwaiveItem(e.dataset.unwaiveId)})}))}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}};customElements.define("loki-checklist-viewer",W);var Ot={not_initialized:{color:"var(--loki-text-muted, #71717a)",label:"Not Started",pulse:!1},starting:{color:"var(--loki-yellow, #ca8a04)",label:"Starting...",pulse:!0},running:{color:"var(--loki-green, #16a34a)",label:"Running",pulse:!0},stale:{color:"var(--loki-yellow, #ca8a04)",label:"Stale",pulse:!1},completed:{color:"var(--loki-text-muted, #a1a1aa)",label:"Completed",pulse:!1},failed:{color:"var(--loki-red, #dc2626)",label:"Failed",pulse:!1},crashed:{color:"var(--loki-red, #dc2626)",label:"Crashed",pulse:!1},stopped:{color:"var(--loki-text-muted, #a1a1aa)",label:"Stopped",pulse:!1},unknown:{color:"var(--loki-text-muted, #71717a)",label:"Unknown",pulse:!1}},Q=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._pollInterval=null,this._status=null,this._logs=[],this._lastDataHash=null,this._lastLogsHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),3e3),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadData(),this._pollInterval=setInterval(()=>this._loadData(),3e3))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null)}async _loadData(){try{let[t,e]=await Promise.all([this._api.getAppRunnerStatus(),this._api.getAppRunnerLogs()]),i=JSON.stringify({status:t?.status,port:t?.port,restarts:t?.restart_count,url:t?.url}),a=JSON.stringify(e?.lines?.slice(-5)||[]),s=a!==this._lastLogsHash;if(i===this._lastDataHash&&!s)return;this._lastDataHash=i,this._lastLogsHash=a,this._status=t,this._logs=e?.lines||[],this._error=null,this.render(),this._scrollLogsToBottom()}catch(t){this._error||(this._error=`Failed to load app status: ${t.message}`,this.render())}}_scrollLogsToBottom(){let t=this.shadowRoot;if(!t)return;let e=t.querySelector(".log-area");e&&(e.scrollTop=e.scrollHeight)}async _handleRestart(){try{await this._api.restartApp(),this._loadData()}catch(t){this._error=`Restart failed: ${t.message}`,this.render()}}async _handleStop(){try{await this._api.stopApp(),this._loadData()}catch(t){this._error=`Stop failed: ${t.message}`,this.render()}}_formatUptime(t){if(!t)return"--";let e=new Date(t),a=Math.floor((new Date-e)/1e3);if(a<60)return`${a}s`;if(a<3600)return`${Math.floor(a/60)}m ${a%60}s`;let s=Math.floor(a/3600),r=Math.floor(a%3600/60);return`${s}h ${r}m`}_isValidUrl(t){if(!t)return!1;try{let e=new URL(t);return e.protocol==="http:"||e.protocol==="https:"}catch{return!1}}_getStyles(){return`
|
|
5818
5831
|
.app-status {
|
|
5819
5832
|
padding: 16px;
|
|
5820
5833
|
font-family: var(--loki-font-family, system-ui, -apple-system, sans-serif);
|
|
@@ -5990,7 +6003,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
5990
6003
|
${i?"":this._renderEmpty()}
|
|
5991
6004
|
${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
|
|
5992
6005
|
</div>
|
|
5993
|
-
`,this._attachEventListeners()}_renderStatusBadge(t){let e=t?.status||"not_initialized",i=
|
|
6006
|
+
`,this._attachEventListeners()}_renderStatusBadge(t){let e=t?.status||"not_initialized",i=Ot[e]||Ot.not_initialized;return`
|
|
5994
6007
|
<span class="status-badge" style="background: color-mix(in srgb, ${i.color} 15%, transparent); color: ${i.color}">
|
|
5995
6008
|
<span class="status-dot ${i.pulse?"pulse":""}" style="background: ${i.color}"></span>
|
|
5996
6009
|
${this._escapeHtml(i.label)}
|
|
@@ -6040,7 +6053,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
6040
6053
|
<p>App runner not started</p>
|
|
6041
6054
|
<p class="hint">App runner will start after the first successful build iteration.</p>
|
|
6042
6055
|
</div>
|
|
6043
|
-
`}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.querySelector('[data-action="restart"]'),i=t.querySelector('[data-action="stop"]');e&&e.addEventListener("click",()=>this._handleRestart()),i&&i.addEventListener("click",()=>this._handleStop())}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}};customElements.define("loki-app-status",Q);var
|
|
6056
|
+
`}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.querySelector('[data-action="restart"]'),i=t.querySelector('[data-action="stop"]');e&&e.addEventListener("click",()=>this._handleRestart()),i&&i.addEventListener("click",()=>this._handleStop())}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}};customElements.define("loki-app-status",Q);var ve={opus:{input:5,output:25,label:"Opus 4.6",provider:"claude"},sonnet:{input:3,output:15,label:"Sonnet 4.5",provider:"claude"},haiku:{input:1,output:5,label:"Haiku 4.5",provider:"claude"},"gpt-5.3-codex":{input:1.5,output:12,label:"GPT-5.3 Codex",provider:"codex"},"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"}},X=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data={total_input_tokens:0,total_output_tokens:0,estimated_cost_usd:0,by_phase:{},by_model:{},budget_limit:null,budget_used:0,budget_remaining:null,connected:!1},this._api=null,this._pollInterval=null,this._modelPricing={...ve}}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadPricing(),this._loadCost(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadCost()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _loadPricing(){try{let t=await this._api.getPricing();if(t&&t.models){let e={};for(let[i,a]of Object.entries(t.models))e[i]={input:a.input,output:a.output,label:a.label||i,provider:a.provider||"unknown"};this._modelPricing=e,this._pricingSource=t.source||"api",this._pricingDate=t.updated||"",this._activeProvider=t.provider||"claude",this.render()}}catch{}}async _loadCost(){try{let t=await this._api.getCost();this._updateFromCost(t)}catch{this._data.connected=!1,this.render()}}_updateFromCost(t){t&&(this._data={...this._data,connected:!0,total_input_tokens:t.total_input_tokens||0,total_output_tokens:t.total_output_tokens||0,estimated_cost_usd:t.estimated_cost_usd||0,by_phase:t.by_phase||{},by_model:t.by_model||{},budget_limit:t.budget_limit,budget_used:t.budget_used||0,budget_remaining:t.budget_remaining},this.render())}_startPolling(){this._pollInterval=setInterval(async()=>{try{let t=await this._api.getCost();this._updateFromCost(t)}catch{this._data.connected=!1,this.render()}},5e3),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadCost(),this._pollInterval=setInterval(async()=>{try{let t=await this._api.getCost();this._updateFromCost(t)}catch{this._data.connected=!1,this.render()}},5e3))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null)}_formatTokens(t){return!t||t===0?"0":t>=1e6?(t/1e6).toFixed(2)+"M":t>=1e3?(t/1e3).toFixed(1)+"K":String(t)}_formatUSD(t){return!t||t===0?"$0.00":t<.01?"<$0.01":"$"+t.toFixed(2)}_getBudgetPercent(){return!this._data.budget_limit||this._data.budget_limit<=0?0:Math.min(100,this._data.budget_used/this._data.budget_limit*100)}_getBudgetStatusClass(){let t=this._getBudgetPercent();return t>=90?"critical":t>=70?"warning":"ok"}_renderPhaseRows(){let t=this._data.by_phase;return!t||Object.keys(t).length===0?'<tr><td colspan="4" class="empty-cell">No phase data yet</td></tr>':Object.entries(t).map(([e,i])=>{let a=i.input_tokens||0,s=i.output_tokens||0,r=i.cost_usd||0;return`
|
|
6044
6057
|
<tr>
|
|
6045
6058
|
<td class="phase-name">${this._escapeHTML(e)}</td>
|
|
6046
6059
|
<td class="mono-cell">${this._formatTokens(a)}</td>
|
|
@@ -6443,7 +6456,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
6443
6456
|
</div>
|
|
6444
6457
|
</div>
|
|
6445
6458
|
</div>
|
|
6446
|
-
`}};customElements.get("loki-cost-dashboard")||customElements.define("loki-cost-dashboard",X);var Z=class extends
|
|
6459
|
+
`}};customElements.get("loki-cost-dashboard")||customElements.define("loki-cost-dashboard",X);var Z=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._checkpoints=[],this._pollInterval=null,this._lastDataHash=null,this._showCreateForm=!1,this._creating=!1,this._rollingBack=!1,this._rollbackTarget=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),3e3),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadData(),this._pollInterval=setInterval(()=>this._loadData(),3e3))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null)}async _loadData(){try{let[e]=await Promise.allSettled([this._api._get("/api/checkpoints?limit=50")]);e.status==="fulfilled"&&(this._checkpoints=Array.isArray(e.value)?e.value:e.value?.checkpoints||[]),this._error=null}catch(e){this._error=e.message}let t=JSON.stringify({c:this._checkpoints,e:this._error});t!==this._lastDataHash&&(this._lastDataHash=t,this.render())}async _createCheckpoint(){let t=this.shadowRoot.getElementById("checkpoint-message"),e=t?t.value.trim():"";if(e){this._creating=!0,this.render();try{await this._api._post("/api/checkpoints",{message:e}),this._showCreateForm=!1,this._creating=!1,this.dispatchEvent(new CustomEvent("checkpoint-action",{detail:{action:"create",message:e},bubbles:!0})),this._lastDataHash=null,await this._loadData()}catch(i){this._creating=!1,this._error=`Failed to create checkpoint: ${i.message}`,this.render()}}}async _rollbackCheckpoint(t){if(!this._rollingBack){this._rollingBack=!0,this.render();try{await this._api._post(`/api/checkpoints/${t}/rollback`),this._rollbackTarget=null,this.dispatchEvent(new CustomEvent("checkpoint-action",{detail:{action:"rollback",checkpointId:t},bubbles:!0})),this._lastDataHash=null,await this._loadData()}catch(e){this._rollbackTarget=null,this._error=`Failed to rollback: ${e.message}`}finally{this._rollingBack=!1,this.render()}}}_toggleCreateForm(){this._showCreateForm=!this._showCreateForm,this._rollbackTarget=null,this.render()}_confirmRollback(t){this._rollbackTarget=t,this.render()}_cancelRollback(){this._rollbackTarget=null,this.render()}_formatRelativeTime(t){if(!t)return"";try{let e=Date.now(),i=new Date(t).getTime(),a=Math.floor((e-i)/1e3);return a<60?`${a}s ago`:a<3600?`${Math.floor(a/60)}m ago`:a<86400?`${Math.floor(a/3600)}h ago`:`${Math.floor(a/86400)}d ago`}catch{return this._escapeHTML(t)}}render(){let t=this.shadowRoot;if(!t)return;let e=this._checkpoints.length;t.innerHTML=`
|
|
6447
6460
|
<style>${this.getBaseStyles()}${this._getStyles()}</style>
|
|
6448
6461
|
<div class="checkpoint-viewer">
|
|
6449
6462
|
<div class="checkpoint-header">
|
|
@@ -6751,7 +6764,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
6751
6764
|
color: var(--loki-red);
|
|
6752
6765
|
font-size: 12px;
|
|
6753
6766
|
}
|
|
6754
|
-
`}};customElements.get("loki-checkpoint-viewer")||customElements.define("loki-checkpoint-viewer",Z);var tt=class extends
|
|
6767
|
+
`}};customElements.get("loki-checkpoint-viewer")||customElements.define("loki-checkpoint-viewer",Z);var tt=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data=null,this._connected=!1,this._activeTab="gauge",this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadContext(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadContext()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _loadContext(){try{let t=this.getAttribute("api-url")||window.location.origin,e=await fetch(t+"/api/context");e.ok&&(this._data=await e.json(),this._connected=!0)}catch{this._connected=!1}this.render()}_startPolling(){this._pollInterval=setInterval(()=>{this._loadContext()},5e3),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadContext(),this._pollInterval=setInterval(()=>this._loadContext(),5e3))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null)}_setTab(t){this._activeTab=t,this.render()}_formatTokens(t){return!t||t===0?"0":t>=1e6?(t/1e6).toFixed(2)+"M":t>=1e3?(t/1e3).toFixed(1)+"K":String(t)}_formatUSD(t){return!t||t===0?"$0.00":t<.01?"<$0.01":"$"+t.toFixed(2)}_escapeHTML(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getGaugeColor(t){return t>80?"var(--loki-red)":t>=60?"var(--loki-yellow)":"var(--loki-green)"}_getGaugeColorClass(t){return t>80?"gauge-red":t>=60?"gauge-yellow":"gauge-green"}_renderGaugeTab(){let t=this._data?.current||{},e=this._data?.totals||{},i=t.context_window_pct||0,a=this._getGaugeColor(i),s=this._getGaugeColorClass(i),r=70,o=2*Math.PI*r,n=o-i/100*o;return`
|
|
6755
6768
|
<div class="gauge-tab">
|
|
6756
6769
|
<div class="gauge-container">
|
|
6757
6770
|
<svg class="gauge-svg" viewBox="0 0 180 180" aria-label="Context window usage: ${i.toFixed(1)}%">
|
|
@@ -6864,12 +6877,12 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
6864
6877
|
<div class="legend-item"><span class="legend-swatch swatch-cache-read"></span> Cache Read</div>
|
|
6865
6878
|
<div class="legend-item"><span class="legend-swatch swatch-cache-create"></span> Cache Creation</div>
|
|
6866
6879
|
</div>
|
|
6867
|
-
`,a="";for(let s of t){let r=s.input_tokens||0,o=s.output_tokens||0,n=s.cache_read_tokens||0,l=s.cache_creation_tokens||0,c=r+o+n+l,p=e>0?r/e*100:0,
|
|
6880
|
+
`,a="";for(let s of t){let r=s.input_tokens||0,o=s.output_tokens||0,n=s.cache_read_tokens||0,l=s.cache_creation_tokens||0,c=r+o+n+l,p=e>0?r/e*100:0,h=e>0?o/e*100:0,b=e>0?n/e*100:0,m=e>0?l/e*100:0;a+=`
|
|
6868
6881
|
<div class="breakdown-row">
|
|
6869
6882
|
<div class="breakdown-iter">#${s.iteration}</div>
|
|
6870
6883
|
<div class="breakdown-bar-container">
|
|
6871
6884
|
<div class="breakdown-bar bar-input" style="width: ${p.toFixed(1)}%"></div>
|
|
6872
|
-
<div class="breakdown-bar bar-output" style="width: ${
|
|
6885
|
+
<div class="breakdown-bar bar-output" style="width: ${h.toFixed(1)}%"></div>
|
|
6873
6886
|
<div class="breakdown-bar bar-cache-read" style="width: ${b.toFixed(1)}%"></div>
|
|
6874
6887
|
<div class="breakdown-bar bar-cache-create" style="width: ${m.toFixed(1)}%"></div>
|
|
6875
6888
|
</div>
|
|
@@ -7274,7 +7287,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
7274
7287
|
|
|
7275
7288
|
${t}
|
|
7276
7289
|
</div>
|
|
7277
|
-
`,this.shadowRoot.querySelectorAll(".tab").forEach(e=>{e.addEventListener("click",()=>{this._setTab(e.dataset.tab)})})}};customElements.get("loki-context-tracker")||customElements.define("loki-context-tracker",tt);var
|
|
7290
|
+
`,this.shadowRoot.querySelectorAll(".tab").forEach(e=>{e.addEventListener("click",()=>{this._setTab(e.dataset.tab)})})}};customElements.get("loki-context-tracker")||customElements.define("loki-context-tracker",tt);var It={critical:"var(--loki-red, #ef4444)",warning:"var(--loki-yellow, #eab308)",info:"var(--loki-blue, #3b82f6)",success:"var(--loki-green, #1FC5A8)"},qt={build:{label:"Build",icon:"B"},quality:{label:"Quality",icon:"Q"},system:{label:"System",icon:"S"},security:{label:"Security",icon:"!"}},et=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._notifications=[],this._triggers=[],this._summary={},this._connected=!1,this._activeTab="feed",this._categoryFilter="all",this._panelOpen=!0,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._loadNotifications(),this._loadTriggers(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&(this._loadNotifications(),this._loadTriggers()),t==="theme"&&this._applyTheme())}async _loadNotifications(){try{let t=this.getAttribute("api-url")||window.location.origin,e=await fetch(t+"/api/notifications");if(e.ok){let i=await e.json();this._notifications=i.notifications||[],this._summary=i.summary||{},this._connected=!0}}catch{this._connected=!1}this.render()}async _loadTriggers(){try{let t=this.getAttribute("api-url")||window.location.origin,e=await fetch(t+"/api/notifications/triggers");if(e.ok){let i=await e.json();this._triggers=i.triggers||[]}}catch{}}async _acknowledgeNotification(t){let e=this.getAttribute("api-url")||window.location.origin;await fetch(e+"/api/notifications/"+encodeURIComponent(t)+"/acknowledge",{method:"POST"}),this._loadNotifications()}async _unacknowledgeNotification(t){let e=this.getAttribute("api-url")||window.location.origin;await fetch(e+"/api/notifications/"+encodeURIComponent(t)+"/unacknowledge",{method:"POST"}),this._loadNotifications()}async _acknowledgeAll(){let t=this.getAttribute("api-url")||window.location.origin,e=this._notifications.filter(i=>!i.acknowledged);for(let i of e)await fetch(t+"/api/notifications/"+encodeURIComponent(i.id)+"/acknowledge",{method:"POST"});this._loadNotifications()}async _toggleTrigger(t,e){let i=this.getAttribute("api-url")||window.location.origin,a=this._triggers.map(s=>s.id===t?{...s,enabled:e}:s);await fetch(i+"/api/notifications/triggers",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({triggers:a})}),this._triggers=a,this.render()}_startPolling(){this._pollInterval=setInterval(()=>{this._loadNotifications(),this._loadTriggers()},5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_formatTime(t){if(!t)return"";try{let e=new Date(t),a=new Date-e,s=Math.floor(a/1e3),r=Math.floor(s/60),o=Math.floor(r/60),n=Math.floor(o/24);return s<60?s+"s ago":r<60?r+"m ago":o<24?o+"h ago":n<7?n+"d ago":e.toLocaleDateString()}catch{return String(t)}}_getTimeGroup(t){if(!t)return"Other";try{let e=new Date(t),i=new Date,a=new Date(i.getFullYear(),i.getMonth(),i.getDate()),s=new Date(a);s.setDate(s.getDate()-1);let r=new Date(a);return r.setDate(r.getDate()-7),e>=a?"Today":e>=s?"Yesterday":e>=r?"This Week":"Earlier"}catch{return"Other"}}_escapeHTML(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getSeverityColor(t){return It[t]||It.info}_getCategory(t){return t.category||t.type||"system"}_switchTab(t){this._activeTab=t,this.render()}_setCategoryFilter(t){this._categoryFilter=t,this.render()}_togglePanel(){this._panelOpen=!this._panelOpen,this.render()}_bindEvents(){let t=this.shadowRoot;t.querySelectorAll(".tab").forEach(a=>{a.addEventListener("click",()=>{this._switchTab(a.dataset.tab)})}),t.querySelectorAll(".cat-btn").forEach(a=>{a.addEventListener("click",()=>{this._setCategoryFilter(a.dataset.cat)})}),t.querySelectorAll(".ack-btn").forEach(a=>{a.addEventListener("click",s=>{s.stopPropagation(),this._acknowledgeNotification(a.dataset.id)})}),t.querySelectorAll(".unread-btn").forEach(a=>{a.addEventListener("click",s=>{s.stopPropagation(),this._unacknowledgeNotification(a.dataset.id)})});let e=t.querySelector(".ack-all-btn");e&&e.addEventListener("click",()=>{this._acknowledgeAll()});let i=t.querySelector(".bell-icon");i&&i.addEventListener("click",()=>{this._togglePanel()}),t.querySelectorAll(".toggle input").forEach(a=>{a.addEventListener("change",()=>{this._toggleTrigger(a.dataset.triggerId,a.checked)})}),t.querySelectorAll(".dismiss-btn").forEach(a=>{a.addEventListener("click",s=>{s.stopPropagation(),this._acknowledgeNotification(a.dataset.id)})})}_renderBellIcon(){let t=this._summary.unacknowledged||0;return`
|
|
7278
7291
|
<div class="bell-container">
|
|
7279
7292
|
<button class="bell-icon" title="${t} unread notifications">
|
|
7280
7293
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
@@ -7297,7 +7310,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
7297
7310
|
</div>
|
|
7298
7311
|
<div class="summary-card">
|
|
7299
7312
|
<div class="card-label">Critical</div>
|
|
7300
|
-
<div class="card-value" style="color: ${
|
|
7313
|
+
<div class="card-value" style="color: ${It.critical}">${i}</div>
|
|
7301
7314
|
</div>
|
|
7302
7315
|
</div>
|
|
7303
7316
|
${e>0?`
|
|
@@ -7306,9 +7319,9 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
7306
7319
|
</div>
|
|
7307
7320
|
`}_renderCategoryFilter(){return`
|
|
7308
7321
|
<div class="category-bar">
|
|
7309
|
-
${["all","build","quality","system","security"].map(e=>{let i=this._categoryFilter===e,a=e==="all"?"All":
|
|
7322
|
+
${["all","build","quality","system","security"].map(e=>{let i=this._categoryFilter===e,a=e==="all"?"All":qt[e]?.label||e;return`<button class="cat-btn ${i?"active":""}" data-cat="${e}">${a}</button>`}).join("")}
|
|
7310
7323
|
</div>
|
|
7311
|
-
`}_renderNotificationList(){let t=[...this._notifications].sort((s,r)=>new Date(r.timestamp)-new Date(s.timestamp));if(this._categoryFilter!=="all"&&(t=t.filter(s=>this._getCategory(s)===this._categoryFilter)),t.length===0)return'<div class="empty-state">No notifications</div>';let e={};for(let s of t){let r=this._getTimeGroup(s.timestamp);e[r]||(e[r]=[]),e[r].push(s)}let i=["Today","Yesterday","This Week","Earlier","Other"],a="";for(let s of i)!e[s]||e[s].length===0||(a+=`<div class="time-group-label">${s}</div>`,a+=e[s].map(r=>{let o=r.acknowledged,n=this._getSeverityColor(r.severity),l=this._getCategory(r),c=
|
|
7324
|
+
`}_renderNotificationList(){let t=[...this._notifications].sort((s,r)=>new Date(r.timestamp)-new Date(s.timestamp));if(this._categoryFilter!=="all"&&(t=t.filter(s=>this._getCategory(s)===this._categoryFilter)),t.length===0)return'<div class="empty-state">No notifications</div>';let e={};for(let s of t){let r=this._getTimeGroup(s.timestamp);e[r]||(e[r]=[]),e[r].push(s)}let i=["Today","Yesterday","This Week","Earlier","Other"],a="";for(let s of i)!e[s]||e[s].length===0||(a+=`<div class="time-group-label">${s}</div>`,a+=e[s].map(r=>{let o=r.acknowledged,n=this._getSeverityColor(r.severity),l=this._getCategory(r),c=qt[l]||{label:l,icon:"?"};return`
|
|
7312
7325
|
<div class="notif-row ${o?"acknowledged":""}">
|
|
7313
7326
|
<span class="severity-dot" style="background: ${n};" title="${this._escapeHTML(r.severity)}"></span>
|
|
7314
7327
|
<span class="cat-icon" title="${c.label}">${c.icon}</span>
|
|
@@ -7791,7 +7804,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
7791
7804
|
`:""}
|
|
7792
7805
|
`:""}
|
|
7793
7806
|
</div>
|
|
7794
|
-
`,this._bindEvents()}};customElements.get("loki-notification-center")||customElements.define("loki-notification-center",et);var it=class extends
|
|
7807
|
+
`,this._bindEvents()}};customElements.get("loki-notification-center")||customElements.define("loki-notification-center",et);var it=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data=null,this._error=null,this._loading=!0,this._api=null,this._pollInterval=null,this._expandedDecisions=new Set}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _loadData(){try{this._data=await this._api._get("/api/session-diff"),this._error=null}catch(t){this._error=t.message,this._data=null}this._loading=!1,this.render()}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),3e4)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_toggleDecision(t){this._expandedDecisions.has(t)?this._expandedDecisions.delete(t):this._expandedDecisions.add(t),this.render()}render(){let t=`
|
|
7795
7808
|
${this.getBaseStyles()}
|
|
7796
7809
|
|
|
7797
7810
|
:host {
|
|
@@ -8053,7 +8066,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
8053
8066
|
${o}
|
|
8054
8067
|
${n}
|
|
8055
8068
|
</div>
|
|
8056
|
-
`,this.shadowRoot.querySelectorAll(".decision-header").forEach(l=>{l.addEventListener("click",()=>{this._toggleDecision(parseInt(l.dataset.index))})})}};customElements.get("loki-session-diff")||customElements.define("loki-session-diff",it);var at=class extends
|
|
8069
|
+
`,this.shadowRoot.querySelectorAll(".decision-header").forEach(l=>{l.addEventListener("click",()=>{this._toggleDecision(parseInt(l.dataset.index))})})}};customElements.get("loki-session-diff")||customElements.define("loki-session-diff",it);var at=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data=null,this._error=null,this._loading=!0,this._optimizing=!1,this._api=null,this._pollInterval=null,this._expandedChanges=new Set}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _loadData(){try{this._data=await this._api._get("/api/prompt-versions"),this._error=null}catch(t){this._error=t.message,this._data=null}this._loading=!1,this.render()}async _triggerOptimize(){if(!this._optimizing){this._optimizing=!0,this.render();try{await this._api._post("/api/prompt-optimize?dry_run=false",{}),await this._loadData()}catch(t){this._error=t.message}this._optimizing=!1,this.render()}}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),6e4)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_formatTime(t){if(!t)return"--";try{let e=new Date(t),a=new Date-e,s=Math.floor(a/6e4);if(s<1)return"Just now";if(s<60)return`${s}m ago`;let r=Math.floor(s/60);return r<24?`${r}h ago`:`${Math.floor(r/24)}d ago`}catch{return"--"}}_toggleChange(t){this._expandedChanges.has(t)?this._expandedChanges.delete(t):this._expandedChanges.add(t),this.render()}render(){let t=`
|
|
8057
8070
|
${this.getBaseStyles()}
|
|
8058
8071
|
|
|
8059
8072
|
:host {
|
|
@@ -8304,7 +8317,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
8304
8317
|
|
|
8305
8318
|
${o}
|
|
8306
8319
|
</div>
|
|
8307
|
-
`;let n=this.shadowRoot.getElementById("optimize-btn");n&&n.addEventListener("click",()=>this._triggerOptimize()),this.shadowRoot.querySelectorAll(".change-header").forEach(l=>{l.addEventListener("click",()=>{this._toggleChange(parseInt(l.dataset.index))})})}};customElements.get("loki-prompt-optimizer")||customElements.define("loki-prompt-optimizer",at);var st=class extends
|
|
8320
|
+
`;let n=this.shadowRoot.getElementById("optimize-btn");n&&n.addEventListener("click",()=>this._triggerOptimize()),this.shadowRoot.querySelectorAll(".change-header").forEach(l=>{l.addEventListener("click",()=>{this._toggleChange(parseInt(l.dataset.index))})})}};customElements.get("loki-prompt-optimizer")||customElements.define("loki-prompt-optimizer",at);var st=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data=null,this._history=[],this._error=null,this._loading=!0,this._scanning=!1,this._rigourAvailable=!0,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _loadData(){try{let[t,e]=await Promise.allSettled([this._api._get("/api/quality-score"),this._api._get("/api/quality-score/history")]);if(t.status==="fulfilled"){let i=t.value;i&&i.error&&i.error.includes("not installed")?(this._rigourAvailable=!1,this._data=null):(this._rigourAvailable=!0,this._data=i),this._error=null}else(t.reason?.message||"").includes("404")?(this._rigourAvailable=!1,this._data=null,this._error=null):(this._error="Failed to load quality score",this._data=null);if(e.status==="fulfilled"){let i=e.value;this._history=Array.isArray(i)?i.slice(-10):(i.scores||[]).slice(-10)}}catch(t){this._error=t.message,this._data=null}this._loading=!1,this.render()}async _triggerScan(){if(!this._scanning){this._scanning=!0,this.render();try{await this._api._post("/api/quality-scan",{}),await this._loadData()}catch(t){this._error=t.message}this._scanning=!1,this.render()}}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),6e4)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getGrade(t){return t>=90?{grade:"A",color:"var(--loki-success)"}:t>=80?{grade:"B",color:"var(--loki-success)"}:t>=70?{grade:"C",color:"var(--loki-warning)"}:t>=60?{grade:"D",color:"var(--loki-warning)"}:{grade:"F",color:"var(--loki-error)"}}_renderSparkline(t){if(!t||t.length<2)return"";let e=t.map(c=>typeof c=="number"?c:c.score||0),i=Math.min(...e),s=Math.max(...e)-i||1,r=120,o=32,n=2,l=e.map((c,p)=>{let h=n+p/(e.length-1)*(r-n*2),b=n+(1-(c-i)/s)*(o-n*2);return`${h},${b}`}).join(" ");return`
|
|
8308
8321
|
<svg width="${r}" height="${o}" viewBox="0 0 ${r} ${o}" class="sparkline">
|
|
8309
8322
|
<polyline points="${l}" fill="none" stroke="var(--loki-accent)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
8310
8323
|
<circle cx="${l.split(" ").pop().split(",")[0]}" cy="${l.split(" ").pop().split(",")[1]}" r="2.5" fill="var(--loki-accent)"/>
|
|
@@ -8609,7 +8622,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
8609
8622
|
</div>
|
|
8610
8623
|
<span class="category-score">${y}</span>
|
|
8611
8624
|
</div>
|
|
8612
|
-
`}).join(""),
|
|
8625
|
+
`}).join(""),h=[{key:"critical",cls:"finding-critical",label:"Critical"},{key:"major",cls:"finding-major",label:"Major"},{key:"minor",cls:"finding-minor",label:"Minor"},{key:"info",cls:"finding-info",label:"Info"}].filter(f=>(o[f.key]||0)>0).map(f=>`<span class="finding-badge ${f.cls}">${f.label}: ${o[f.key]}</span>`).join(""),b=this._renderSparkline(this._history);this.shadowRoot.innerHTML=`
|
|
8613
8626
|
<style>${t}</style>
|
|
8614
8627
|
<div class="quality-container">
|
|
8615
8628
|
<div class="quality-header">
|
|
@@ -8638,19 +8651,19 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
8638
8651
|
${c}
|
|
8639
8652
|
</div>
|
|
8640
8653
|
|
|
8641
|
-
${
|
|
8654
|
+
${h?`
|
|
8642
8655
|
<div class="findings-section">
|
|
8643
8656
|
<div class="section-label">Findings</div>
|
|
8644
|
-
<div class="findings-row">${
|
|
8657
|
+
<div class="findings-row">${h}</div>
|
|
8645
8658
|
</div>
|
|
8646
8659
|
`:""}
|
|
8647
8660
|
</div>
|
|
8648
|
-
`;let m=this.shadowRoot.getElementById("scan-btn");m&&m.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-score")||customElements.define("loki-quality-score",st);var
|
|
8661
|
+
`;let m=this.shadowRoot.getElementById("scan-btn");m&&m.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-score")||customElements.define("loki-quality-score",st);var Jt=["understand","guardrail","migrate","verify"],Gt={understand:"Understand",guardrail:"Guardrail",migrate:"Migrate",verify:"Verify"},me={understand:"#5b9bd5",guardrail:"#e8b84a",migrate:"#5bb870",verify:"#5bc8c8"},rt=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._migration=null,this._migrations=[],this._loading=!0,this._error=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._fetchMigrations(),this._pollInterval=setInterval(()=>this._fetchData(),15e3)}disconnectedCallback(){super.disconnectedCallback(),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._fetchMigrations()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _fetchMigrations(){try{let t=await this._api._get("/api/migration/list");this._migrations=Array.isArray(t)?t:t.migrations||[],this._error=null;let e=this._migrations.find(i=>i.status==="in_progress"||i.status==="active");e?await this._fetchStatus(e.migration_id||e.id):this._migration=null}catch(t){this._error=t.message,this._migrations=[],this._migration=null}this._loading=!1,this.render()}async _fetchStatus(t){try{this._migration=await this._api._get(`/api/migration/${encodeURIComponent(t)}/status`),this._error=null}catch(e){this._error=e.message}}async _fetchData(){let t=this._migration&&(this._migration.migration_id||this._migration.id);t?(await this._fetchStatus(t),this.render()):await this._fetchMigrations()}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"):""}_getPhaseIcon(t,e,i){return(i||[]).includes(t)?"[x]":t===e?"[>]":"[ ]"}_getPhaseIndex(t){let e=Jt.indexOf(t);return e>=0?e:0}_renderPhaseBar(t,e){let i=e||[];return Jt.map(a=>{let s=i.includes(a),r=a===t,o=me[a],n=s?"1":r?"0.7":"0.2",l=this._getPhaseIcon(a,t,e);return`
|
|
8649
8662
|
<div class="phase-segment">
|
|
8650
8663
|
<div class="phase-bar-fill" style="background:${o};opacity:${n};"></div>
|
|
8651
8664
|
<div class="phase-label">
|
|
8652
8665
|
<span class="phase-icon">${l}</span>
|
|
8653
|
-
${
|
|
8666
|
+
${Gt[a]}
|
|
8654
8667
|
</div>
|
|
8655
8668
|
</div>
|
|
8656
8669
|
`}).join("")}_renderFeatureStats(t){if(!t)return"";let e=t.passing||0,i=t.total||0,a=i>0?Math.round(e/i*100):0,s=a>=80?"var(--loki-success)":a>=50?"var(--loki-warning)":"var(--loki-error)";return`
|
|
@@ -9041,7 +9054,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
9041
9054
|
</div>
|
|
9042
9055
|
<div class="meta-item">
|
|
9043
9056
|
<span class="meta-label">Phase</span>
|
|
9044
|
-
<span>${
|
|
9057
|
+
<span>${Gt[o]||this._escapeHtml(o)}</span>
|
|
9045
9058
|
</div>
|
|
9046
9059
|
</div>
|
|
9047
9060
|
|
|
@@ -9068,7 +9081,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
9068
9081
|
<div class="section-label">Migrations</div>
|
|
9069
9082
|
${this._renderMigrationList()}
|
|
9070
9083
|
</div>
|
|
9071
|
-
`}};customElements.get("loki-migration-dashboard")||customElements.define("loki-migration-dashboard",rt);var
|
|
9084
|
+
`}};customElements.get("loki-migration-dashboard")||customElements.define("loki-migration-dashboard",rt);var be=[["claude-opus","claude"],["claude-sonnet","claude"],["claude-haiku","claude"],["opus","claude"],["sonnet","claude"],["haiku","claude"],["claude","claude"],["gpt-4","codex"],["gpt-5","codex"],["gpt","codex"],["codex","codex"],["o1","codex"],["o3","codex"],["gemini","gemini"]];function fe(d){if(d==null)return null;switch(d%4){case 0:return{tier:"planning",model:"opus",provider:"claude"};case 1:return{tier:"development",model:"sonnet",provider:"claude"};case 2:return{tier:"development",model:"sonnet",provider:"claude"};case 3:return{tier:"fast",model:"haiku",provider:"claude"};default:return{tier:"development",model:"sonnet",provider:"claude"}}}function ke(d,t){if(t!=null){let i=fe(t);if(i)return i.provider}let e=(d||"").toLowerCase();for(let[i,a]of be)if(e.includes(i))return a;return"unknown"}var ot=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._api=null,this._pollInterval=null,this._activeTab="heatmap",this._activity=[],this._tools=[],this._cost={},this._context={},this._trends=[],this._toolTimeRange="7d",this._connected=!1,this._loading=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _fetchActivity(){let t=this._api.baseUrl||window.location.origin,e=new AbortController,i=setTimeout(()=>e.abort(),1e4);try{let a=await fetch(`${t}/api/activity?limit=1000`,{signal:e.signal});if(clearTimeout(i),!a.ok)throw new Error(`Activity API ${a.status}`);return a.json()}catch(a){throw clearTimeout(i),a}}async _loadData(){if(!(!this.isConnected||this._loading)){this._loading=!0;try{let t=await Promise.allSettled([this._fetchActivity(),this._api.getToolEfficiency(50),this._api.getCost(),this._api.getContext(),this._api.getLearningTrends({timeRange:this._toolTimeRange})]);if(t[0].status==="fulfilled"&&(this._activity=t[0].value||[]),t[1].status==="fulfilled"&&(this._tools=t[1].value||[]),t[2].status==="fulfilled"&&(this._cost=t[2].value||{}),t[3].status==="fulfilled"&&(this._context=t[3].value||{}),t[4].status==="fulfilled"){let e=t[4].value||{};this._trends=Array.isArray(e)?e:e.dataPoints||[]}this._connected=t.some(e=>e.status==="fulfilled"),this.render()}finally{this._loading=!1}}}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),3e4),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadData(),this._pollInterval=setInterval(()=>this._loadData(),3e4))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null)}_computeHeatmap(){let t={},e=Array.isArray(this._activity)?this._activity:[];for(let c of e){let p=c.timestamp||c.ts||c.created_at;if(!p)continue;let h=new Date(p);if(isNaN(h.getTime()))continue;let b=this._localDateKey(h);t[b]=(t[b]||0)+1}let i=new Date;i.setHours(0,0,0,0);let a=i.getDay(),s=new Date(i),r=new Date(i);r.setDate(r.getDate()-(52*7+a));let o=[],n=new Date(r),l=0;for(;n<=s;){let c=this._localDateKey(n),p=t[c]||0;p>l&&(l=p),o.push({date:c,count:p,day:n.getDay()}),n.setDate(n.getDate()+1)}return{cells:o,maxCount:l}}_getHeatmapLevel(t,e){if(t===0||e===0)return 0;let i=t/e;return i<=.25?1:i<=.5?2:i<=.75?3:4}_renderHeatmap(){let{cells:t,maxCount:e}=this._computeHeatmap(),i=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],a=["","Mon","","Wed","","Fri",""],s=[],r=-1,o=-1;for(let p=0;p<t.length;p++){t[p].day===0&&o++;let h=new Date(t[p].date).getMonth();h!==r&&(s.push({month:i[h],col:Math.max(o,1)}),r=h)}let n=s.map(p=>`<span class="heatmap-month" style="grid-column: ${p.col}">${p.month}</span>`).join(""),l=t.map(p=>`<div class="heatmap-cell level-${this._getHeatmapLevel(p.count,e)}" title="${p.date}: ${p.count} activities"></div>`).join(""),c=a.map(p=>`<span class="heatmap-day-label">${p}</span>`).join("");return`
|
|
9072
9085
|
<div class="heatmap-container">
|
|
9073
9086
|
<div class="heatmap-months">${n}</div>
|
|
9074
9087
|
<div class="heatmap-body">
|
|
@@ -9093,7 +9106,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
9093
9106
|
</div>
|
|
9094
9107
|
<span class="tool-count">${s}</span>
|
|
9095
9108
|
</div>
|
|
9096
|
-
`}).join("")+"</div>"}_computeVelocity(){let t=this._context||{},e=t.per_iteration||t.iterations||[],i=Array.isArray(e)&&e.length>0?e.length:t.totals&&t.totals.iterations_tracked||t.total_iterations||0,a=0;if(Array.isArray(e)&&e.length>=2){let o=e.map(n=>new Date(n.timestamp||n.started_at||n.ts).getTime()).filter(n=>!isNaN(n)).sort((n,l)=>n-l);if(o.length>=2){let n=(o[o.length-1]-o[0])/36e5;n>0&&(a=Math.max(o.length-1,1)/n)}}let s=[],r=Array.isArray(this._trends)?this._trends:[];if(r.length>0)for(let o of r.slice(-24))s.push(o.count??o.value??0);else if(Array.isArray(e)&&e.length>0){let o={};for(let l of e){let c=l.timestamp||l.started_at||l.ts;if(!c)continue;let
|
|
9109
|
+
`}).join("")+"</div>"}_computeVelocity(){let t=this._context||{},e=t.per_iteration||t.iterations||[],i=Array.isArray(e)&&e.length>0?e.length:t.totals&&t.totals.iterations_tracked||t.total_iterations||0,a=0;if(Array.isArray(e)&&e.length>=2){let o=e.map(n=>new Date(n.timestamp||n.started_at||n.ts).getTime()).filter(n=>!isNaN(n)).sort((n,l)=>n-l);if(o.length>=2){let n=(o[o.length-1]-o[0])/36e5;n>0&&(a=Math.max(o.length-1,1)/n)}}let s=[],r=Array.isArray(this._trends)?this._trends:[];if(r.length>0)for(let o of r.slice(-24))s.push(o.count??o.value??0);else if(Array.isArray(e)&&e.length>0){let o={};for(let l of e){let c=l.timestamp||l.started_at||l.ts;if(!c)continue;let h=new Date(c).toISOString().slice(0,13);o[h]=(o[h]||0)+1}let n=Object.keys(o).sort().slice(-24);for(let l of n)s.push(o[l])}return{iterPerHour:a,totalIterations:i,hourlyBuckets:s}}_renderVelocity(){let{iterPerHour:t,totalIterations:e,hourlyBuckets:i}=this._computeVelocity(),a=Math.max(1,...i),s=i.length>0?i.map(o=>{let n=o/a*100;return`<div class="spark-bar" style="height: ${Math.max(2,n)}%" title="${o}"></div>`}).join(""):'<div class="empty-state" style="padding: 12px">No trend data</div>';return`
|
|
9097
9110
|
${`
|
|
9098
9111
|
<div class="tool-filter">
|
|
9099
9112
|
<select class="tool-time-select" id="tool-time-range">
|
|
@@ -9118,7 +9131,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
9118
9131
|
<div class="sparkline-label">Activity Trend (hourly)</div>
|
|
9119
9132
|
<div class="sparkline">${s}</div>
|
|
9120
9133
|
</div>
|
|
9121
|
-
`}_computeProviders(){let t=this._cost.by_model||{},e={};for(let[r,o]of Object.entries(t)){let n=
|
|
9134
|
+
`}_computeProviders(){let t=this._cost.by_model||{},e={};for(let[r,o]of Object.entries(t)){let n=ke(r);e[n]||(e[n]={cost:0,tokens:0,iterations:0,models:[]});let l=o.cost_usd||0,c=(o.input_tokens||0)+(o.output_tokens||0);e[n].cost+=l,e[n].tokens+=c,e[n].models.push(r)}let a=(this._context.totals||{}).iterations_tracked||this._context.total_iterations||this._context.iteration||0,s=this._cost.estimated_cost_usd||0;for(let r of Object.values(e))if(s>0&&a>0){let o=r.cost/s;r.iterations=Math.round(o*a)}return e}_renderProviders(){let t=this._computeProviders(),e={claude:{label:"Claude",color:"var(--loki-accent)"},codex:{label:"Codex",color:"var(--loki-success)"},gemini:{label:"Gemini",color:"var(--loki-info)"},unknown:{label:"Other",color:"var(--loki-text-muted)"}},i=Object.entries(t);return i.length===0?'<div class="empty-state">No provider data available. Start a session to see cross-provider comparison.</div>':`
|
|
9122
9135
|
<div class="provider-grid">
|
|
9123
9136
|
${i.map(([a,s])=>{let r=e[a]||e.unknown,o=s.iterations>0?(s.cost/s.iterations).toFixed(4):"--",n=s.iterations>0?Math.round(s.tokens/s.iterations).toLocaleString():"--";return`
|
|
9124
9137
|
<div class="provider-card">
|
|
@@ -9516,7 +9529,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
9516
9529
|
${e}
|
|
9517
9530
|
</div>
|
|
9518
9531
|
</div>
|
|
9519
|
-
`,this.shadowRoot.querySelectorAll("[data-tab]").forEach(a=>{a.addEventListener("click",s=>this._handleTabClick(s))});let i=this.shadowRoot.getElementById("tool-time-range");i&&i.addEventListener("change",a=>this._handleTimeRangeChange(a))}};customElements.get("loki-analytics")||customElements.define("loki-analytics",ot);var
|
|
9532
|
+
`,this.shadowRoot.querySelectorAll("[data-tab]").forEach(a=>{a.addEventListener("click",s=>this._handleTabClick(s))});let i=this.shadowRoot.getElementById("tool-time-range");i&&i.addEventListener("change",a=>this._handleTimeRangeChange(a))}};customElements.get("loki-analytics")||customElements.define("loki-analytics",ot);var Kt={pass:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"PASS"},fail:{color:"var(--loki-red, #ef4444)",bg:"var(--loki-red-muted, rgba(239, 68, 68, 0.15))",label:"FAIL"},pending:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"PENDING"}};function xe(d){if(!d)return"Never";try{return new Date(d).toLocaleString([],{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return"Unknown"}}function _e(d){if(!d||d.length===0)return{pass:0,fail:0,pending:0,total:0};let t={pass:0,fail:0,pending:0,total:d.length};for(let e of d){let i=(e.status||"pending").toLowerCase();i==="pass"?t.pass++:i==="fail"?t.fail++:t.pending++}return t}var nt=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._gates=[],this._pollInterval=null,this._lastDataHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),3e4),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadData(),this._pollInterval=setInterval(()=>this._loadData(),3e4))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null)}async _loadData(){try{this._loading=!0;let t=await this._api._get("/api/council/gate"),e=t?.gates||t||[],i=JSON.stringify(e);if(i===this._lastDataHash)return;this._lastDataHash=i,this._gates=Array.isArray(e)?e:[],this._error=null}catch(t){this._error||(this._error=`Failed to load quality gates: ${t.message}`)}finally{this._loading=!1}this.render()}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getStyles(){return`
|
|
9520
9533
|
:host {
|
|
9521
9534
|
display: block;
|
|
9522
9535
|
}
|
|
@@ -9647,14 +9660,14 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
9647
9660
|
color: var(--loki-text-muted, #939084);
|
|
9648
9661
|
font-size: 13px;
|
|
9649
9662
|
}
|
|
9650
|
-
`}render(){let t=this.shadowRoot;if(!t)return;let e=this._gates,i=
|
|
9663
|
+
`}render(){let t=this.shadowRoot;if(!t)return;let e=this._gates,i=_e(e),a;this._loading&&e.length===0?a='<div class="loading">Loading quality gates...</div>':e.length===0?a='<div class="empty-state"><strong>No gate results yet.</strong> Quality gates run automatically between RARV iterations during an active session. Start a session with <code>loki start ./prd.md</code> to see results here. You can also run gates manually with <code>loki review</code>.</div>':a=`<div class="gates-grid">${e.map(o=>{let n=(o.status||"pending").toLowerCase(),l=Kt[n]||Kt.pending;return`
|
|
9651
9664
|
<div class="gate-card status-${n}">
|
|
9652
9665
|
<div class="gate-header">
|
|
9653
9666
|
<span class="gate-name">${this._escapeHtml(o.name||"Unnamed Gate")}</span>
|
|
9654
9667
|
<span class="gate-badge" style="background: ${l.bg}; color: ${l.color};">${l.label}</span>
|
|
9655
9668
|
</div>
|
|
9656
9669
|
${o.description?`<div class="gate-description">${this._escapeHtml(o.description)}</div>`:""}
|
|
9657
|
-
<div class="gate-meta">Last checked: ${
|
|
9670
|
+
<div class="gate-meta">Last checked: ${xe(o.last_checked||o.lastChecked)}</div>
|
|
9658
9671
|
</div>
|
|
9659
9672
|
`}).join("")}</div>`;let s=i.total>0?`
|
|
9660
9673
|
<div class="summary">
|
|
@@ -9681,7 +9694,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
9681
9694
|
${a}
|
|
9682
9695
|
${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
|
|
9683
9696
|
</div>
|
|
9684
|
-
`}};customElements.get("loki-quality-gates")||customElements.define("loki-quality-gates",nt);var F={reason:{color:"var(--loki-blue, #3b82f6)",label:"Reason",description:"Analyzing requirements and planning approach"},act:{color:"var(--loki-green, #22c55e)",label:"Act",description:"Implementing changes and executing tasks"},reflect:{color:"var(--loki-purple, #a78bfa)",label:"Reflect",description:"Reviewing results and evaluating quality"},verify:{color:"var(--loki-yellow, #eab308)",label:"Verify",description:"Running tests and validating correctness"}},
|
|
9697
|
+
`}};customElements.get("loki-quality-gates")||customElements.define("loki-quality-gates",nt);var F={reason:{color:"var(--loki-blue, #3b82f6)",label:"Reason",description:"Analyzing requirements and planning approach"},act:{color:"var(--loki-green, #22c55e)",label:"Act",description:"Implementing changes and executing tasks"},reflect:{color:"var(--loki-purple, #a78bfa)",label:"Reflect",description:"Reviewing results and evaluating quality"},verify:{color:"var(--loki-yellow, #eab308)",label:"Verify",description:"Running tests and validating correctness"}},Lt=["reason","act","reflect","verify"];function At(d){if(d==null||d<0)return"--";if(d<1e3)return`${d}ms`;let t=Math.floor(d/1e3);if(t<60)return`${t}s`;let e=Math.floor(t/60),i=t%60;if(e<60)return`${e}m ${i}s`;let a=Math.floor(e/60),s=e%60;return`${a}h ${s}m`}function ye(d){if(!d||d.length===0)return[];let t=d.reduce((e,i)=>e+(i.duration_ms||0),0);return t===0?d.map(e=>({phase:e.phase,pct:100/d.length,duration:0})):d.map(e=>({phase:e.phase,pct:(e.duration_ms||0)/t*100,duration:e.duration_ms||0}))}function we(d){return d==null?"--":d>=1e6?(d/1e6).toFixed(1)+"M":d>=1e3?(d/1e3).toFixed(1)+"K":String(d)}var lt=class extends u{static get observedAttributes(){return["run-id","api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._timeline=null,this._pollInterval=null,this._selectedPhase=null,this._cycleHistory=[]}get runId(){let t=this.getAttribute("run-id");return t?parseInt(t,10):null}set runId(t){t!=null?this.setAttribute("run-id",String(t)):this.removeAttribute("run-id")}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="run-id"&&this._loadData(),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),5e3),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadData(),this._pollInterval=setInterval(()=>this._loadData(),5e3))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null)}async _loadData(){let t=this.runId;if(t==null){this._timeline=null,this.render();return}try{this._loading=!0;let e=await this._api._get(`/api/v2/runs/${t}/timeline`);this._timeline=e,this._cycleHistory=e.history||[],this._error=null}catch(e){e.message&&(e.message.includes("404")||e.message.includes("Not Found"))?(this._timeline=null,this._error=null):this._error=`Failed to load timeline: ${e.message}`}finally{this._loading=!1}this.render()}_selectPhase(t){this._selectedPhase=this._selectedPhase===t?null:t,this.render()}_bindEvents(){let t=this.shadowRoot;t.querySelectorAll(".phase-segment-interactive").forEach(e=>{e.addEventListener("click",()=>{this._selectPhase(e.dataset.phase)})}),t.querySelectorAll(".legend-item-interactive").forEach(e=>{e.addEventListener("click",()=>{this._selectPhase(e.dataset.phase)})}),t.querySelectorAll(".close-detail").forEach(e=>{e.addEventListener("click",i=>{i.stopPropagation(),this._selectedPhase=null,this.render()})})}_getStyles(){return`
|
|
9685
9698
|
:host {
|
|
9686
9699
|
display: block;
|
|
9687
9700
|
}
|
|
@@ -9966,12 +9979,12 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
9966
9979
|
color: var(--loki-text-muted, #939084);
|
|
9967
9980
|
font-size: 13px;
|
|
9968
9981
|
}
|
|
9969
|
-
`}_renderPlaceholderTimeline(){let t=
|
|
9982
|
+
`}_renderPlaceholderTimeline(){let t=Lt.map(i=>{let a=F[i];return`<div class="phase-segment-interactive"
|
|
9970
9983
|
data-phase="${i}"
|
|
9971
9984
|
style="width: 25%; background: ${a.color}; opacity: 0.3;"
|
|
9972
9985
|
title="${a.label}: awaiting data">
|
|
9973
9986
|
${a.label}
|
|
9974
|
-
</div>`}).join(""),e=
|
|
9987
|
+
</div>`}).join(""),e=Lt.map(i=>{let a=F[i];return`<div class="legend-item-interactive" data-phase="${i}">
|
|
9975
9988
|
<span class="legend-dot" style="background: ${a.color}; opacity: 0.4;"></span>
|
|
9976
9989
|
<span class="legend-label">${a.label}</span>
|
|
9977
9990
|
<span class="legend-duration">--</span>
|
|
@@ -9996,11 +10009,11 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
9996
10009
|
<div class="detail-metrics">
|
|
9997
10010
|
<div class="detail-metric">
|
|
9998
10011
|
<span class="detail-metric-label">Time Spent</span>
|
|
9999
|
-
<span class="detail-metric-value">${
|
|
10012
|
+
<span class="detail-metric-value">${At(a?.duration_ms)}</span>
|
|
10000
10013
|
</div>
|
|
10001
10014
|
<div class="detail-metric">
|
|
10002
10015
|
<span class="detail-metric-label">Tokens Used</span>
|
|
10003
|
-
<span class="detail-metric-value">${
|
|
10016
|
+
<span class="detail-metric-value">${we(a?.tokens_used)}</span>
|
|
10004
10017
|
</div>
|
|
10005
10018
|
<div class="detail-metric">
|
|
10006
10019
|
<span class="detail-metric-label">Quality</span>
|
|
@@ -10012,21 +10025,21 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
10012
10025
|
</div>
|
|
10013
10026
|
</div>
|
|
10014
10027
|
</div>
|
|
10015
|
-
`}_renderCycleHistory(){if(this._cycleHistory.length===0)return"";let e=this._cycleHistory.slice(-8).map((i,a)=>`<div class="history-cycle">${
|
|
10016
|
-
title="Cycle ${a+1}: ${n.label} - ${
|
|
10028
|
+
`}_renderCycleHistory(){if(this._cycleHistory.length===0)return"";let e=this._cycleHistory.slice(-8).map((i,a)=>`<div class="history-cycle">${Lt.map(r=>{let o=i.phases?.find(p=>p.phase===r),n=F[r],l=o?.status||"pending",c=l==="complete"?"0.8":l==="active"?"1":"0.3";return`<div class="history-dot" style="background: ${n.color}; opacity: ${c};"
|
|
10029
|
+
title="Cycle ${a+1}: ${n.label} - ${At(o?.duration_ms)}"></div>`}).join("")}</div>`).join('<div class="history-separator"></div>');return`
|
|
10017
10030
|
<div class="cycle-history">
|
|
10018
10031
|
<div class="history-label">Past Cycles (${this._cycleHistory.length} total)</div>
|
|
10019
10032
|
<div class="history-cycles">${e}</div>
|
|
10020
10033
|
</div>
|
|
10021
|
-
`}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}render(){let t=this.shadowRoot;if(!t)return;let e=this.runId,i=this._timeline,a=i?.phases||[],s=i?.current_phase||null,r=
|
|
10022
|
-
data-phase="${
|
|
10023
|
-
style="width: ${Math.max(
|
|
10024
|
-
title="${b.label}: ${
|
|
10025
|
-
${
|
|
10026
|
-
</div>`}).join(""),l=a.map(
|
|
10034
|
+
`}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}render(){let t=this.shadowRoot;if(!t)return;let e=this.runId,i=this._timeline,a=i?.phases||[],s=i?.current_phase||null,r=ye(a),o;if(this._loading&&!i)o='<div class="loading">Loading timeline...</div>';else if(e==null)o=this._renderPlaceholderTimeline();else if(a.length===0)o=this._renderPlaceholderTimeline();else{let n=r.map(h=>{let b=F[h.phase]||{color:"var(--loki-text-muted)",label:h.phase},m=s===h.phase,f=this._selectedPhase===h.phase;return`<div class="phase-segment-interactive ${m?"current":""} ${f?"selected":""}"
|
|
10035
|
+
data-phase="${h.phase}"
|
|
10036
|
+
style="width: ${Math.max(h.pct,2)}%; background: ${b.color};"
|
|
10037
|
+
title="${b.label}: ${At(h.duration)}">
|
|
10038
|
+
${h.pct>12?b.label:""}
|
|
10039
|
+
</div>`}).join(""),l=a.map(h=>{let b=F[h.phase]||{color:"var(--loki-text-muted)",label:h.phase},m=s===h.phase;return`<div class="legend-item-interactive ${this._selectedPhase===h.phase?"selected":""}" data-phase="${h.phase}">
|
|
10027
10040
|
<span class="legend-dot" style="background: ${b.color}"></span>
|
|
10028
10041
|
<span class="legend-label">${b.label}</span>
|
|
10029
|
-
<span class="legend-duration">${
|
|
10042
|
+
<span class="legend-duration">${At(h.duration_ms)}</span>
|
|
10030
10043
|
${m?'<span class="phase-current-tag">ACTIVE</span>':""}
|
|
10031
10044
|
</div>`}).join(""),c=this._selectedPhase?this._renderPhaseDetail(this._selectedPhase):"",p=this._renderCycleHistory();o=`
|
|
10032
10045
|
<div class="timeline-bar">${n}</div>
|
|
@@ -10043,7 +10056,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
10043
10056
|
${o}
|
|
10044
10057
|
${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
|
|
10045
10058
|
</div>
|
|
10046
|
-
`,this._bindEvents()}};customElements.get("loki-rarv-timeline")||customElements.define("loki-rarv-timeline",lt);var
|
|
10059
|
+
`,this._bindEvents()}};customElements.get("loki-rarv-timeline")||customElements.define("loki-rarv-timeline",lt);var Vt={running:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"Running"},completed:{color:"var(--loki-blue, #3b82f6)",bg:"var(--loki-blue-muted, rgba(59, 130, 246, 0.15))",label:"Completed"},failed:{color:"var(--loki-red, #ef4444)",bg:"var(--loki-red-muted, rgba(239, 68, 68, 0.15))",label:"Failed"},cancelled:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"Cancelled"},pending:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Pending"},queued:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Queued"}};function $e(d,t,e){let i=d;if(i==null&&t){let l=new Date(t).getTime();i=(e?new Date(e).getTime():Date.now())-l}if(i==null||i<0)return"--";if(i<1e3)return`${i}ms`;let a=Math.floor(i/1e3);if(a<60)return`${a}s`;let s=Math.floor(a/60),r=a%60;if(s<60)return`${s}m ${r}s`;let o=Math.floor(s/60),n=s%60;return`${o}h ${n}m`}function Ee(d){if(!d)return"--";try{return new Date(d).toLocaleString([],{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return String(d)}}var dt=class extends u{static get observedAttributes(){return["api-url","project-id","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._runs=[],this._pollInterval=null,this._lastDataHash=null}get projectId(){let t=this.getAttribute("project-id");return t?parseInt(t,10):null}set projectId(t){t!=null?this.setAttribute("project-id",String(t)):this.removeAttribute("project-id")}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="project-id"&&this._loadData(),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),5e3),this._visibilityHandler=()=>{document.hidden?this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null):this._pollInterval||(this._loadData(),this._pollInterval=setInterval(()=>this._loadData(),5e3))},document.addEventListener("visibilitychange",this._visibilityHandler)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null)}async _loadData(){try{let t=this.projectId,e=t!=null?`?project_id=${t}`:"",i=await this._api._get(`/api/v2/runs${e}`),a=i?.runs||i||[],s=JSON.stringify(a);if(s===this._lastDataHash)return;this._lastDataHash=s,this._runs=Array.isArray(a)?a:[],this._error=null}catch(t){this._error||(this._error=`Failed to load runs: ${t.message}`)}finally{this._loading=!1}this.render()}async _cancelRun(t){try{await this._api._post(`/api/v2/runs/${t}/cancel`),await this._loadData()}catch(e){this._error=`Cancel failed: ${e.message}`,this.render()}}async _replayRun(t){try{await this._api._post(`/api/v2/runs/${t}/replay`),await this._loadData()}catch(e){this._error=`Replay failed: ${e.message}`,this.render()}}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getStyles(){return`
|
|
10047
10060
|
:host {
|
|
10048
10061
|
display: block;
|
|
10049
10062
|
}
|
|
@@ -10196,13 +10209,13 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
10196
10209
|
color: var(--loki-text-muted, #939084);
|
|
10197
10210
|
margin-bottom: 8px;
|
|
10198
10211
|
}
|
|
10199
|
-
`}render(){let t=this.shadowRoot;if(!t)return;let e=this._runs,i;if(this._loading&&e.length===0)i='<div class="loading">Loading runs...</div>';else if(e.length===0)i='<div class="empty-state">No runs found.</div>';else{let a=e.map(s=>{let r=(s.status||"pending").toLowerCase(),o=
|
|
10212
|
+
`}render(){let t=this.shadowRoot;if(!t)return;let e=this._runs,i;if(this._loading&&e.length===0)i='<div class="loading">Loading runs...</div>';else if(e.length===0)i='<div class="empty-state">No runs found.</div>';else{let a=e.map(s=>{let r=(s.status||"pending").toLowerCase(),o=Vt[r]||Vt.pending,n=r==="running",l=r==="completed"||r==="failed"||r==="cancelled",c=$e(s.duration_ms,s.started_at,s.ended_at);return`
|
|
10200
10213
|
<tr>
|
|
10201
10214
|
<td><span class="run-id">#${s.id}</span></td>
|
|
10202
10215
|
<td>${this._escapeHtml(s.project_name||s.project||(s.project_id?`Project #${s.project_id}`:"--"))}</td>
|
|
10203
10216
|
<td><span class="status-badge" style="background: ${o.bg}; color: ${o.color};">${o.label}</span></td>
|
|
10204
10217
|
<td>${this._escapeHtml(s.trigger||s.trigger_type||"--")}</td>
|
|
10205
|
-
<td>${
|
|
10218
|
+
<td>${Ee(s.started_at)}</td>
|
|
10206
10219
|
<td>${c}</td>
|
|
10207
10220
|
<td>
|
|
10208
10221
|
<div class="actions-cell">
|
|
@@ -10239,7 +10252,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
10239
10252
|
${i}
|
|
10240
10253
|
${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
|
|
10241
10254
|
</div>
|
|
10242
|
-
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.getElementById("refresh-btn");e&&e.addEventListener("click",()=>this._loadData()),t.querySelectorAll('[data-action="cancel"]').forEach(i=>{i.addEventListener("click",()=>this._cancelRun(i.dataset.runId))}),t.querySelectorAll('[data-action="replay"]').forEach(i=>{i.addEventListener("click",()=>this._replayRun(i.dataset.runId))})}};customElements.get("loki-run-manager")||customElements.define("loki-run-manager",dt);function
|
|
10255
|
+
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.getElementById("refresh-btn");e&&e.addEventListener("click",()=>this._loadData()),t.querySelectorAll('[data-action="cancel"]').forEach(i=>{i.addEventListener("click",()=>this._cancelRun(i.dataset.runId))}),t.querySelectorAll('[data-action="replay"]').forEach(i=>{i.addEventListener("click",()=>this._replayRun(i.dataset.runId))})}};customElements.get("loki-run-manager")||customElements.define("loki-run-manager",dt);function Ce(d){if(!d)return"--";try{return new Date(d).toLocaleString([],{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit"})}catch{return String(d)}}function Se(d){let t=new URLSearchParams;for(let[i,a]of Object.entries(d))a!=null&&a!==""&&t.set(i,String(a));let e=t.toString();return e?`?${e}`:""}var ct=class extends u{static get observedAttributes(){return["api-url","limit","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._entries=[],this._verifyResult=null,this._verifying=!1,this._filters={action:"",resource:"",dateFrom:"",dateTo:""}}get limit(){let t=this.getAttribute("limit");return t?parseInt(t,10):50}set limit(t){this.setAttribute("limit",String(t))}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData()}disconnectedCallback(){super.disconnectedCallback()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="limit"&&this._loadData(),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _loadData(){try{this._loading=!0,this.render();let t={limit:this.limit,action:this._filters.action,resource:this._filters.resource,date_from:this._filters.dateFrom,date_to:this._filters.dateTo},e=Se(t),i=await this._api._get(`/api/v2/audit${e}`);this._entries=i?.entries||i||[],this._error=null}catch(t){this._error=`Failed to load audit log: ${t.message}`}finally{this._loading=!1}this.render()}async _verifyIntegrity(){try{this._verifying=!0,this._verifyResult=null,this.render();let t=await this._api._get("/api/v2/audit/verify");this._verifyResult=t}catch(t){this._verifyResult={valid:!1,error:t.message}}finally{this._verifying=!1}this.render()}_onFilterChange(t,e){this._filters[t]=e,this._loadData()}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getStyles(){return`
|
|
10243
10256
|
:host {
|
|
10244
10257
|
display: block;
|
|
10245
10258
|
}
|
|
@@ -10459,7 +10472,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
10459
10472
|
</div>
|
|
10460
10473
|
`}let a;if(this._loading&&e.length===0)a='<div class="loading">Loading audit log...</div>';else if(e.length===0)a='<div class="empty-state">No audit entries found matching filters.</div>';else{let s=e.map(r=>`
|
|
10461
10474
|
<tr>
|
|
10462
|
-
<td>${
|
|
10475
|
+
<td>${Ce(r.timestamp)}</td>
|
|
10463
10476
|
<td>${this._escapeHtml(r.action||"--")}</td>
|
|
10464
10477
|
<td>${this._escapeHtml(r.resource||r.resource_type||"--")}</td>
|
|
10465
10478
|
<td>${this._escapeHtml(r.user||r.actor||"--")}</td>
|
|
@@ -10523,7 +10536,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
10523
10536
|
${a}
|
|
10524
10537
|
${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
|
|
10525
10538
|
</div>
|
|
10526
|
-
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.getElementById("verify-btn");e&&e.addEventListener("click",()=>this._verifyIntegrity());let i=t.getElementById("refresh-btn");i&&i.addEventListener("click",()=>this._loadData());let a=t.getElementById("filter-action");a&&a.addEventListener("change",n=>this._onFilterChange("action",n.target.value));let s=t.getElementById("filter-resource");s&&s.addEventListener("change",n=>this._onFilterChange("resource",n.target.value));let r=t.getElementById("filter-date-from");r&&r.addEventListener("change",n=>this._onFilterChange("dateFrom",n.target.value));let o=t.getElementById("filter-date-to");o&&o.addEventListener("change",n=>this._onFilterChange("dateTo",n.target.value))}};customElements.get("loki-audit-viewer")||customElements.define("loki-audit-viewer",ct);function
|
|
10539
|
+
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.getElementById("verify-btn");e&&e.addEventListener("click",()=>this._verifyIntegrity());let i=t.getElementById("refresh-btn");i&&i.addEventListener("click",()=>this._loadData());let a=t.getElementById("filter-action");a&&a.addEventListener("change",n=>this._onFilterChange("action",n.target.value));let s=t.getElementById("filter-resource");s&&s.addEventListener("change",n=>this._onFilterChange("resource",n.target.value));let r=t.getElementById("filter-date-from");r&&r.addEventListener("change",n=>this._onFilterChange("dateFrom",n.target.value));let o=t.getElementById("filter-date-to");o&&o.addEventListener("change",n=>this._onFilterChange("dateTo",n.target.value))}};customElements.get("loki-audit-viewer")||customElements.define("loki-audit-viewer",ct);function Yt(d){if(!d)return"Never";try{return new Date(d).toLocaleString([],{month:"short",day:"numeric",year:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return String(d)}}var pt=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._keys=[],this._showCreateForm=!1,this._newToken=null,this._confirmDeleteId=null,this._rotateKeyId=null,this._rotateGracePeriod="24",this._createName="",this._createRole="read",this._createExpiration=""}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData()}disconnectedCallback(){super.disconnectedCallback()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _loadData(){try{this._loading=!0,this.render();let t=await this._api._get("/api/v2/api-keys");this._keys=Array.isArray(t)?t:t?.keys||[],this._error=null}catch(t){this._error=`Failed to load API keys: ${t.message}`}finally{this._loading=!1}this.render()}async _createKey(){if(!this._createName.trim()){this._error="Key name is required.",this.render();return}try{let t={name:this._createName.trim(),role:this._createRole};this._createExpiration&&(t.expiration=this._createExpiration);let e=await this._api._post("/api/v2/api-keys",t);this._newToken=e?.token||e?.key||null,this._showCreateForm=!1,this._createName="",this._createRole="read",this._createExpiration="",this._error=null,await this._loadData()}catch(t){this._error=`Create failed: ${t.message}`,this.render()}}async _rotateKey(t){try{let e={grace_period_hours:parseInt(this._rotateGracePeriod,10)||24},i=await this._api._post(`/api/v2/api-keys/${t}/rotate`,e);this._newToken=i?.token||i?.key||null,this._rotateKeyId=null,this._error=null,await this._loadData()}catch(e){this._error=`Rotate failed: ${e.message}`,this.render()}}async _deleteKey(t){try{await this._api._delete(`/api/v2/api-keys/${t}`),this._confirmDeleteId=null,this._error=null,await this._loadData()}catch(e){this._error=`Delete failed: ${e.message}`,this._confirmDeleteId=null,this.render()}}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getStyles(){return`
|
|
10527
10540
|
:host {
|
|
10528
10541
|
display: block;
|
|
10529
10542
|
}
|
|
@@ -10878,7 +10891,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
10878
10891
|
<th>Actions</th>
|
|
10879
10892
|
</tr>
|
|
10880
10893
|
</thead>
|
|
10881
|
-
<tbody>${e.map(o=>{let n=o.id||o.key_id,l=(o.status||"active").toLowerCase(),c=l==="active"?"key-status-active":l==="expired"?"key-status-expired":"key-status-revoked",p=this._confirmDeleteId===n,
|
|
10894
|
+
<tbody>${e.map(o=>{let n=o.id||o.key_id,l=(o.status||"active").toLowerCase(),c=l==="active"?"key-status-active":l==="expired"?"key-status-expired":"key-status-revoked",p=this._confirmDeleteId===n,h=this._rotateKeyId===n,b;return p?b=`
|
|
10882
10895
|
<div class="confirm-delete">
|
|
10883
10896
|
<span>Delete this key?</span>
|
|
10884
10897
|
<button class="btn btn-sm btn-danger" data-action="confirm-delete" data-key-id="${n}">Yes</button>
|
|
@@ -10889,7 +10902,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
10889
10902
|
<button class="btn btn-sm btn-warn" data-action="rotate" data-key-id="${n}">Rotate</button>
|
|
10890
10903
|
<button class="btn btn-sm btn-danger" data-action="delete" data-key-id="${n}">Delete</button>
|
|
10891
10904
|
</div>
|
|
10892
|
-
${
|
|
10905
|
+
${h?`
|
|
10893
10906
|
<div class="rotate-inline">
|
|
10894
10907
|
<span class="rotate-label">Grace period:</span>
|
|
10895
10908
|
<input type="number" class="rotate-input" id="rotate-grace-${n}" value="${this._rotateGracePeriod}" min="0">
|
|
@@ -10902,8 +10915,8 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
10902
10915
|
<tr>
|
|
10903
10916
|
<td><span class="key-name">${this._escapeHtml(o.name||"Unnamed")}</span></td>
|
|
10904
10917
|
<td><span class="key-role">${this._escapeHtml(o.role||o.scopes||"--")}</span></td>
|
|
10905
|
-
<td>${
|
|
10906
|
-
<td>${
|
|
10918
|
+
<td>${Yt(o.created_at||o.created)}</td>
|
|
10919
|
+
<td>${Yt(o.last_used_at||o.last_used)}</td>
|
|
10907
10920
|
<td><span class="${c}">${this._escapeHtml(l)}</span></td>
|
|
10908
10921
|
<td><div class="actions-cell">${b}</div></td>
|
|
10909
10922
|
</tr>
|
|
@@ -10922,7 +10935,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
10922
10935
|
${s}
|
|
10923
10936
|
${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
|
|
10924
10937
|
</div>
|
|
10925
|
-
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.getElementById("show-create");e&&e.addEventListener("click",()=>{this._showCreateForm=!0,this.render()});let i=t.getElementById("dismiss-token");i&&i.addEventListener("click",()=>{this._newToken=null,this.render()});let a=t.getElementById("submit-create");a&&a.addEventListener("click",()=>{let r=t.getElementById("create-name"),o=t.getElementById("create-role"),n=t.getElementById("create-expiration");this._createName=r?.value||"",this._createRole=o?.value||"read",this._createExpiration=n?.value||"",this._createKey()});let s=t.getElementById("cancel-create");s&&s.addEventListener("click",()=>{this._showCreateForm=!1,this.render()}),t.querySelectorAll('[data-action="delete"]').forEach(r=>{r.addEventListener("click",()=>{this._confirmDeleteId=r.dataset.keyId,this.render()})}),t.querySelectorAll('[data-action="confirm-delete"]').forEach(r=>{r.addEventListener("click",()=>{this._deleteKey(r.dataset.keyId)})}),t.querySelectorAll('[data-action="cancel-delete"]').forEach(r=>{r.addEventListener("click",()=>{this._confirmDeleteId=null,this.render()})}),t.querySelectorAll('[data-action="rotate"]').forEach(r=>{r.addEventListener("click",()=>{this._rotateKeyId=r.dataset.keyId,this.render()})}),t.querySelectorAll('[data-action="confirm-rotate"]').forEach(r=>{r.addEventListener("click",()=>{let o=t.getElementById(`rotate-grace-${r.dataset.keyId}`);this._rotateGracePeriod=o?.value||"24",this._rotateKey(r.dataset.keyId)})}),t.querySelectorAll('[data-action="cancel-rotate"]').forEach(r=>{r.addEventListener("click",()=>{this._rotateKeyId=null,this.render()})})}};customElements.get("loki-api-keys")||customElements.define("loki-api-keys",pt);function
|
|
10938
|
+
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.getElementById("show-create");e&&e.addEventListener("click",()=>{this._showCreateForm=!0,this.render()});let i=t.getElementById("dismiss-token");i&&i.addEventListener("click",()=>{this._newToken=null,this.render()});let a=t.getElementById("submit-create");a&&a.addEventListener("click",()=>{let r=t.getElementById("create-name"),o=t.getElementById("create-role"),n=t.getElementById("create-expiration");this._createName=r?.value||"",this._createRole=o?.value||"read",this._createExpiration=n?.value||"",this._createKey()});let s=t.getElementById("cancel-create");s&&s.addEventListener("click",()=>{this._showCreateForm=!1,this.render()}),t.querySelectorAll('[data-action="delete"]').forEach(r=>{r.addEventListener("click",()=>{this._confirmDeleteId=r.dataset.keyId,this.render()})}),t.querySelectorAll('[data-action="confirm-delete"]').forEach(r=>{r.addEventListener("click",()=>{this._deleteKey(r.dataset.keyId)})}),t.querySelectorAll('[data-action="cancel-delete"]').forEach(r=>{r.addEventListener("click",()=>{this._confirmDeleteId=null,this.render()})}),t.querySelectorAll('[data-action="rotate"]').forEach(r=>{r.addEventListener("click",()=>{this._rotateKeyId=r.dataset.keyId,this.render()})}),t.querySelectorAll('[data-action="confirm-rotate"]').forEach(r=>{r.addEventListener("click",()=>{let o=t.getElementById(`rotate-grace-${r.dataset.keyId}`);this._rotateGracePeriod=o?.value||"24",this._rotateKey(r.dataset.keyId)})}),t.querySelectorAll('[data-action="cancel-rotate"]').forEach(r=>{r.addEventListener("click",()=>{this._rotateKeyId=null,this.render()})})}};customElements.get("loki-api-keys")||customElements.define("loki-api-keys",pt);function Te(d){return d?d.slug&&d.name?`${d.name} (${d.slug})`:d.name||d.slug||"Unknown":"Unknown"}var ut=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._tenants=[],this._selectedTenantId=null,this._dropdownOpen=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._outsideClickHandler=t=>{this._dropdownOpen&&!this.contains(t.target)&&(this._dropdownOpen=!1,this.render())},document.addEventListener("click",this._outsideClickHandler)}disconnectedCallback(){super.disconnectedCallback(),this._outsideClickHandler&&(document.removeEventListener("click",this._outsideClickHandler),this._outsideClickHandler=null)}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}async _loadData(){try{this._loading=!0;let t=await this._api._get("/api/v2/tenants");this._tenants=Array.isArray(t)?t:t?.tenants||[],this._error=null}catch(t){this._error=`Failed to load tenants: ${t.message}`}finally{this._loading=!1}this.render()}_toggleDropdown(){this._dropdownOpen=!this._dropdownOpen,this.render()}_selectTenant(t,e){this._selectedTenantId=t,this._dropdownOpen=!1,this.render(),this.dispatchEvent(new CustomEvent("tenant-changed",{detail:{tenantId:t,tenantName:e},bubbles:!0,composed:!0}))}_getSelectedTenant(){return this._selectedTenantId==null?null:this._tenants.find(t=>(t.id||t.slug)===this._selectedTenantId)||null}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getStyles(){return`
|
|
10926
10939
|
:host {
|
|
10927
10940
|
display: inline-block;
|
|
10928
10941
|
position: relative;
|
|
@@ -11056,7 +11069,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
11056
11069
|
color: var(--loki-text-muted, #939084);
|
|
11057
11070
|
font-size: 12px;
|
|
11058
11071
|
}
|
|
11059
|
-
`}render(){let t=this.shadowRoot;if(!t)return;let e=this._getSelectedTenant(),i=e?
|
|
11072
|
+
`}render(){let t=this.shadowRoot;if(!t)return;let e=this._getSelectedTenant(),i=e?Te(e):"All Tenants",a=this._dropdownOpen,s="";if(a){let r;if(this._loading)r='<div class="loading-text">Loading tenants...</div>';else if(this._error)r=`<div class="error-text">${this._escapeHtml(this._error)}</div>`;else{let o=this._selectedTenantId==null;r=`
|
|
11060
11073
|
<button class="dropdown-item all-tenants ${o?"selected":""}" data-tenant-id="">
|
|
11061
11074
|
<span class="tenant-name">All Tenants</span>
|
|
11062
11075
|
${o?'<span class="check-mark">*</span>':""}
|
|
@@ -11081,7 +11094,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
11081
11094
|
</button>
|
|
11082
11095
|
${s}
|
|
11083
11096
|
</div>
|
|
11084
|
-
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.getElementById("trigger-btn");e&&e.addEventListener("click",i=>{i.stopPropagation(),this._toggleDropdown()}),t.querySelectorAll(".dropdown-item").forEach(i=>{i.addEventListener("click",a=>{a.stopPropagation();let s=i.dataset.tenantId||null,r=i.dataset.tenantName||null;this._selectTenant(s||null,r||"All Tenants")})})}};customElements.get("loki-tenant-switcher")||customElements.define("loki-tenant-switcher",ut);var
|
|
11097
|
+
`,this._attachEventListeners()}_attachEventListeners(){let t=this.shadowRoot;if(!t)return;let e=t.getElementById("trigger-btn");e&&e.addEventListener("click",i=>{i.stopPropagation(),this._toggleDropdown()}),t.querySelectorAll(".dropdown-item").forEach(i=>{i.addEventListener("click",a=>{a.stopPropagation();let s=i.dataset.tenantId||null,r=i.dataset.tenantName||null;this._selectTenant(s||null,r||"All Tenants")})})}};customElements.get("loki-tenant-switcher")||customElements.define("loki-tenant-switcher",ut);var Dt={info:{color:"var(--loki-blue, #2F71E3)",label:"INFO",icon:"i"},success:{color:"var(--loki-green, #1FC5A8)",label:"OK",icon:"+"},warning:{color:"var(--loki-yellow, #D4A03C)",label:"WARN",icon:"!"},error:{color:"var(--loki-red, #C45B5B)",label:"ERR",icon:"x"}},Ae=100,ht=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._items=[],this._filter="all",this._api=null,this._pollInterval=null,this._paused=!1,this._lastTimestamp=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),3e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let t=await this._api._get("/api/v2/activity"),e=t.events||t.activities||[];if(e.length>0){let i=e.filter(a=>!this._lastTimestamp||new Date(a.timestamp)>new Date(this._lastTimestamp)).map(a=>({id:a.id||crypto.randomUUID(),timestamp:a.timestamp||new Date().toISOString(),message:a.message||a.description||"",severity:a.severity||a.level||"info",source:a.source||a.component||"",isNew:!0}));i.length>0&&(this._items=[...i,...this._items].slice(0,Ae),this._lastTimestamp=i[0].timestamp,setTimeout(()=>{this._items.forEach(a=>a.isNew=!1)},600))}}catch{this._items.length===0&&(this._items=this._getDemoItems())}this.render()}_getDemoItems(){let t=Date.now();return[{id:"1",timestamp:new Date(t-2e3).toISOString(),message:"Build iteration #12 started",severity:"info",source:"runner"},{id:"2",timestamp:new Date(t-5e3).toISOString(),message:"Code review passed (3/3 reviewers)",severity:"success",source:"review"},{id:"3",timestamp:new Date(t-8e3).toISOString(),message:"Context window at 78% capacity",severity:"warning",source:"context"},{id:"4",timestamp:new Date(t-12e3).toISOString(),message:"Test suite completed: 42/42 passed",severity:"success",source:"testing"},{id:"5",timestamp:new Date(t-15e3).toISOString(),message:"RARV cycle: Verify phase complete",severity:"info",source:"rarv"}]}_formatTime(t){if(!t)return"";try{return new Date(t).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})}catch{return""}}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getFilteredItems(){return this._filter==="all"?this._items:this._items.filter(t=>t.severity===this._filter)}_setFilter(t){this._filter=t,this.render()}_bindEvents(){let t=this.shadowRoot;t.querySelectorAll(".filter-btn").forEach(i=>{i.addEventListener("click",()=>{this._setFilter(i.dataset.filter)})});let e=t.querySelector(".activity-feed");e&&(e.addEventListener("mouseenter",()=>{this._paused=!0}),e.addEventListener("mouseleave",()=>{this._paused=!1}))}_getStyles(){return`
|
|
11085
11098
|
:host {
|
|
11086
11099
|
display: block;
|
|
11087
11100
|
}
|
|
@@ -11267,7 +11280,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
11267
11280
|
::-webkit-scrollbar-track { background: var(--loki-bg-primary, #FFFEFB); }
|
|
11268
11281
|
::-webkit-scrollbar-thumb { background: var(--loki-border, #ECEAE3); border-radius: 3px; }
|
|
11269
11282
|
::-webkit-scrollbar-thumb:hover { background: var(--loki-border-light, #C5C0B1); }
|
|
11270
|
-
`}render(){let t=this.shadowRoot;if(!t)return;let e=this._getFilteredItems(),a=["all","info","success","warning","error"].map(r=>{let o=this._filter===r,n=r==="all"?"All":
|
|
11283
|
+
`}render(){let t=this.shadowRoot;if(!t)return;let e=this._getFilteredItems(),a=["all","info","success","warning","error"].map(r=>{let o=this._filter===r,n=r==="all"?"All":Dt[r]?.label||r;return`<button class="filter-btn ${o?"active":""}" data-filter="${r}">${n}</button>`}).join(""),s;if(e.length===0?s='<div class="empty-state">No activity to display</div>':s=e.map(r=>{let o=Dt[r.severity]||Dt.info;return`
|
|
11271
11284
|
<div class="activity-item ${r.isNew?"new-item":""}">
|
|
11272
11285
|
<div class="severity-band" style="background: ${o.color};"></div>
|
|
11273
11286
|
<div class="item-content">
|
|
@@ -11288,7 +11301,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
11288
11301
|
${s}
|
|
11289
11302
|
</div>
|
|
11290
11303
|
</div>
|
|
11291
|
-
`,this._bindEvents(),!this._paused){let r=t.querySelector(".activity-feed");r&&(r.scrollTop=0)}}};customElements.get("loki-activity-stream")||customElements.define("loki-activity-stream",ht);var
|
|
11304
|
+
`,this._bindEvents(),!this._paused){let r=t.querySelector(".activity-feed");r&&(r.scrollTop=0)}}};customElements.get("loki-activity-stream")||customElements.define("loki-activity-stream",ht);var Ie={claude:{initial:"C",color:"#553DE9",bgColor:"rgba(85, 61, 233, 0.12)"},codex:{initial:"X",color:"#1FC5A8",bgColor:"rgba(31, 197, 168, 0.12)"},gemini:{initial:"G",color:"#2F71E3",bgColor:"rgba(47, 113, 227, 0.12)"},cline:{initial:"L",color:"#D4A03C",bgColor:"rgba(212, 160, 60, 0.12)"},aider:{initial:"A",color:"#C45B5B",bgColor:"rgba(196, 91, 91, 0.12)"}},Wt={healthy:"var(--loki-green, #1FC5A8)",degraded:"var(--loki-yellow, #D4A03C)",down:"var(--loki-red, #C45B5B)",unknown:"var(--loki-text-muted, #939084)"},gt=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._providers=[],this._expandedProvider=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),1e4)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let t=await this._api._get("/api/v2/providers/health");this._providers=t.providers||[]}catch{this._providers.length===0&&(this._providers=this._getDemoData())}this.render()}_getDemoData(){return[{name:"claude",status:"healthy",latency_ms:245,tokens_used:125400,model:"claude-opus-4-7",api_version:"v1",rate_limit:{remaining:45,limit:50},cost_usd:3.42},{name:"codex",status:"degraded",latency_ms:890,tokens_used:45200,model:"gpt-5.3-codex",api_version:"v1",rate_limit:{remaining:12,limit:60},cost_usd:.87},{name:"gemini",status:"healthy",latency_ms:320,tokens_used:78600,model:"gemini-3-pro",api_version:"v1beta",rate_limit:{remaining:55,limit:60},cost_usd:1.15}]}_formatTokens(t){return t==null?"--":t>=1e6?(t/1e6).toFixed(1)+"M":t>=1e3?(t/1e3).toFixed(1)+"K":String(t)}_formatLatency(t){return t==null?"--":t<1e3?t+"ms":(t/1e3).toFixed(1)+"s"}_formatCost(t){return t==null?"--":"$"+t.toFixed(2)}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_toggleExpand(t){this._expandedProvider=this._expandedProvider===t?null:t,this.render()}_bindEvents(){this.shadowRoot.querySelectorAll(".provider-card").forEach(e=>{e.addEventListener("click",()=>{this._toggleExpand(e.dataset.provider)})})}_getStyles(){return`
|
|
11292
11305
|
:host {
|
|
11293
11306
|
display: block;
|
|
11294
11307
|
}
|
|
@@ -11467,7 +11480,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
11467
11480
|
border: 1px solid var(--loki-border, #ECEAE3);
|
|
11468
11481
|
border-radius: 5px;
|
|
11469
11482
|
}
|
|
11470
|
-
`}render(){let t=this.shadowRoot;if(!t)return;let e;this._providers.length===0?e='<div class="empty-state">No provider data available</div>':e=`<div class="provider-grid">${this._providers.map(i=>{let a=
|
|
11483
|
+
`}render(){let t=this.shadowRoot;if(!t)return;let e;this._providers.length===0?e='<div class="empty-state">No provider data available</div>':e=`<div class="provider-grid">${this._providers.map(i=>{let a=Ie[i.name]||{initial:(i.name??"?").charAt(0).toUpperCase(),color:"#939084",bgColor:"rgba(147, 144, 132, 0.12)"},s=Wt[i.status]||Wt.unknown,r=this._expandedProvider===i.name,o=i.rate_limit?i.rate_limit.remaining/i.rate_limit.limit*100:100,n=o>50?"var(--loki-green)":o>20?"var(--loki-yellow)":"var(--loki-red)";return`
|
|
11471
11484
|
<div class="provider-card ${r?"expanded":""}" data-provider="${this._escapeHtml(i.name)}">
|
|
11472
11485
|
<div class="card-header">
|
|
11473
11486
|
<div class="provider-icon" style="background: ${a.bgColor}; color: ${a.color};">${a.initial}</div>
|
|
@@ -11519,7 +11532,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
11519
11532
|
</div>
|
|
11520
11533
|
${e}
|
|
11521
11534
|
</div>
|
|
11522
|
-
`,this._bindEvents()}};customElements.get("loki-provider-health")||customElements.define("loki-provider-health",gt);var
|
|
11535
|
+
`,this._bindEvents()}};customElements.get("loki-provider-health")||customElements.define("loki-provider-health",gt);var zt=[{id:"planning",label:"Planning",icon:"P"},{id:"scaffolding",label:"Scaffolding",icon:"S"},{id:"implementation",label:"Implementation",icon:"I"},{id:"testing",label:"Testing",icon:"T"},{id:"review",label:"Review",icon:"R"},{id:"deploy",label:"Deploy",icon:"D"}],Ht={waiting:{color:"var(--loki-text-muted, #939084)",bgColor:"var(--loki-bg-tertiary, #ECEAE3)",label:"Waiting"},active:{color:"var(--loki-accent, #553DE9)",bgColor:"var(--loki-accent-muted, rgba(85, 61, 233, 0.10))",label:"Active"},complete:{color:"var(--loki-green, #1FC5A8)",bgColor:"var(--loki-green-muted, rgba(31, 197, 168, 0.12))",label:"Complete"},failed:{color:"var(--loki-red, #C45B5B)",bgColor:"var(--loki-red-muted, rgba(196, 91, 91, 0.12))",label:"Failed"}},vt=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._stages=[],this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),5e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let t=await this._api._get("/api/v2/pipeline/status");this._stages=t.stages||[]}catch{this._stages.length===0&&(this._stages=this._getDemoData())}this.render()}_getDemoData(){return[{id:"planning",status:"complete",errors:0,duration_ms:12500},{id:"scaffolding",status:"complete",errors:0,duration_ms:8300},{id:"implementation",status:"active",errors:0,duration_ms:45e3},{id:"testing",status:"waiting",errors:0,duration_ms:null},{id:"review",status:"waiting",errors:0,duration_ms:null},{id:"deploy",status:"waiting",errors:0,duration_ms:null}]}_getStageData(t){return this._stages.find(e=>e.id===t)||{id:t,status:"waiting",errors:0}}_formatDuration(t){if(t==null||t<0)return"";if(t<1e3)return t+"ms";let e=Math.floor(t/1e3);if(e<60)return e+"s";let i=Math.floor(e/60),a=e%60;return i+"m "+a+"s"}_getStyles(){return`
|
|
11523
11536
|
:host {
|
|
11524
11537
|
display: block;
|
|
11525
11538
|
}
|
|
@@ -11682,7 +11695,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
11682
11695
|
border-radius: 50%;
|
|
11683
11696
|
flex-shrink: 0;
|
|
11684
11697
|
}
|
|
11685
|
-
`}render(){let t=this.shadowRoot;if(!t)return;let e=
|
|
11698
|
+
`}render(){let t=this.shadowRoot;if(!t)return;let e=zt.map((a,s)=>{let r=this._getStageData(a.id),o=Ht[r.status]||Ht.waiting,n=r.status==="complete",l=r.status==="active",c=r.status==="failed",p=n?'<span class="stage-check">✓</span>':c?'<span class="stage-check">✗</span>':a.icon,h=`
|
|
11686
11699
|
<div class="stage-node">
|
|
11687
11700
|
<div class="stage-circle ${l?"active":""}"
|
|
11688
11701
|
style="background: ${o.bgColor}; color: ${o.color}; border: 2px solid ${o.color};">
|
|
@@ -11692,12 +11705,12 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
11692
11705
|
${r.duration_ms?`<span class="stage-duration">${this._formatDuration(r.duration_ms)}</span>`:""}
|
|
11693
11706
|
${r.errors>0?`<span class="stage-error-count">${r.errors} error${r.errors>1?"s":""}</span>`:""}
|
|
11694
11707
|
</div>
|
|
11695
|
-
`;if(s<
|
|
11708
|
+
`;if(s<zt.length-1){let b=this._getStageData(zt[s+1].id),m=n,f=l||n&&(b.status==="active"||b.status==="waiting");return h+`
|
|
11696
11709
|
<div class="connector">
|
|
11697
11710
|
<div class="connector-line ${m?"completed":l?"active":"pending"}"></div>
|
|
11698
11711
|
${l?'<div class="flow-dot"></div>':""}
|
|
11699
11712
|
</div>
|
|
11700
|
-
`}return
|
|
11713
|
+
`}return h}).join(""),i=Object.entries(Ht).map(([a,s])=>`<div class="legend-item">
|
|
11701
11714
|
<div class="legend-dot" style="background: ${s.color};"></div>
|
|
11702
11715
|
<span>${s.label}</span>
|
|
11703
11716
|
</div>`).join("");t.innerHTML=`
|
|
@@ -11713,8 +11726,8 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
11713
11726
|
${i}
|
|
11714
11727
|
</div>
|
|
11715
11728
|
</div>
|
|
11716
|
-
`}};customElements.get("loki-pipeline-view")||customElements.define("loki-pipeline-view",vt);var mt={episode:{color:"var(--loki-blue, #2F71E3)",shape:"circle",label:"Episode"},pattern:{color:"var(--loki-green, #1FC5A8)",shape:"square",label:"Pattern"},skill:{color:"var(--loki-purple, #553DE9)",shape:"diamond",label:"Skill"}};function
|
|
11717
|
-
rx="3" fill="${a.color}" fill-opacity="0.2" stroke="${o}" stroke-width="${n}" opacity="${l}" />`;break;case"diamond":{let
|
|
11729
|
+
`}};customElements.get("loki-pipeline-view")||customElements.define("loki-pipeline-view",vt);var mt={episode:{color:"var(--loki-blue, #2F71E3)",shape:"circle",label:"Episode"},pattern:{color:"var(--loki-green, #1FC5A8)",shape:"square",label:"Pattern"},skill:{color:"var(--loki-purple, #553DE9)",shape:"diamond",label:"Skill"}};function Le(d,t,e){let i=t/2,a=e/2,s=Math.min(i,a)*.65,r=d.length;return d.map((o,n)=>{let l=2*Math.PI*n/r-Math.PI/2,c=o.importance||.5,p=s*(.5+c*.5);return{...o,x:i+p*Math.cos(l),y:a+p*Math.sin(l)}})}var bt=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._nodes=[],this._edges=[],this._selectedNode=null,this._api=null,this._pollInterval=null,this._graphWidth=600,this._graphHeight=400}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),15e3)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let t=await this._api._get("/api/v2/memory/graph");this._nodes=t.nodes||[],this._edges=t.edges||[]}catch{if(this._nodes.length===0){let t=this._getDemoData();this._nodes=t.nodes,this._edges=t.edges}}this.render()}_getDemoData(){return{nodes:[{id:"ep1",type:"episode",label:"Build iteration #12",importance:.8,details:"Completed scaffolding and initial implementation"},{id:"ep2",type:"episode",label:"Code review #5",importance:.6,details:"Quality gate passed with 3/3 approval"},{id:"ep3",type:"episode",label:"Test failure #3",importance:.7,details:"Integration test timeout resolved"},{id:"pt1",type:"pattern",label:"Error recovery",importance:.9,details:"Retry with exponential backoff pattern"},{id:"pt2",type:"pattern",label:"API design",importance:.7,details:"REST endpoint naming conventions"},{id:"pt3",type:"pattern",label:"Test structure",importance:.5,details:"Arrange-Act-Assert with setup helpers"},{id:"sk1",type:"skill",label:"Playwright E2E",importance:.85,details:"Browser automation test writing"},{id:"sk2",type:"skill",label:"FastAPI routing",importance:.6,details:"Python API server development"}],edges:[{source:"ep1",target:"pt1",strength:.8},{source:"ep1",target:"sk1",strength:.6},{source:"ep2",target:"pt2",strength:.9},{source:"ep3",target:"pt1",strength:.7},{source:"ep3",target:"pt3",strength:.5},{source:"pt1",target:"sk2",strength:.4},{source:"pt2",target:"sk2",strength:.7},{source:"pt3",target:"sk1",strength:.6}]}}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_selectNode(t){this._selectedNode=this._selectedNode===t?null:t,this.render()}_bindEvents(){let t=this.shadowRoot;t.querySelectorAll(".graph-node").forEach(e=>{e.addEventListener("click",()=>{this._selectNode(e.dataset.nodeId)})}),t.querySelectorAll(".close-detail").forEach(e=>{e.addEventListener("click",()=>{this._selectedNode=null,this.render()})})}_renderNodeShape(t,e,i){let a=mt[t.type]||mt.episode,s=10+(t.importance||.5)*16,r=this._selectedNode===t.id,o=r?"var(--loki-accent, #553DE9)":a.color,n=r?3:1.5,l=this._selectedNode&&!r?.4:1,c;switch(a.shape){case"square":c=`<rect x="${e-s/2}" y="${i-s/2}" width="${s}" height="${s}"
|
|
11730
|
+
rx="3" fill="${a.color}" fill-opacity="0.2" stroke="${o}" stroke-width="${n}" opacity="${l}" />`;break;case"diamond":{let h=s/2;c=`<polygon points="${e},${i-h} ${e+h},${i} ${e},${i+h} ${e-h},${i}"
|
|
11718
11731
|
fill="${a.color}" fill-opacity="0.2" stroke="${o}" stroke-width="${n}" opacity="${l}" />`;break}default:c=`<circle cx="${e}" cy="${i}" r="${s/2}" fill="${a.color}" fill-opacity="0.2"
|
|
11719
11732
|
stroke="${o}" stroke-width="${n}" opacity="${l}" />`}let p=`<text x="${e}" y="${i+s/2+14}" text-anchor="middle" font-size="10"
|
|
11720
11733
|
font-family="Inter, sans-serif" fill="var(--loki-text-secondary, #36342E)" opacity="${l}">${this._escapeHtml(t.label)}</text>`;return`<g class="graph-node" data-node-id="${this._escapeHtml(t.id)}" style="cursor: pointer;">
|
|
@@ -11874,7 +11887,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
11874
11887
|
</div>
|
|
11875
11888
|
<div class="empty-state">No memory entries to visualize</div>
|
|
11876
11889
|
</div>
|
|
11877
|
-
`;return}let e=this._graphWidth,i=this._graphHeight,a=
|
|
11890
|
+
`;return}let e=this._graphWidth,i=this._graphHeight,a=Le(this._nodes,e,i),s=this._edges.map(l=>this._renderEdge(l,a)).join(""),r=a.map(l=>this._renderNodeShape(l,l.x,l.y)).join(""),o="";if(this._selectedNode){let l=this._nodes.find(c=>c.id===this._selectedNode);if(l){let c=mt[l.type]||mt.episode;o=`
|
|
11878
11891
|
<div class="detail-panel">
|
|
11879
11892
|
<div class="detail-header">
|
|
11880
11893
|
<span class="detail-title">${this._escapeHtml(l.label)}</span>
|
|
@@ -11901,7 +11914,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
11901
11914
|
</div>
|
|
11902
11915
|
<div class="legend">${n}</div>
|
|
11903
11916
|
</div>
|
|
11904
|
-
`,this._bindEvents()}};customElements.get("loki-memory-graph")||customElements.define("loki-memory-graph",bt);var
|
|
11917
|
+
`,this._bindEvents()}};customElements.get("loki-memory-graph")||customElements.define("loki-memory-graph",bt);var Rt={planning:{color:"var(--loki-blue, #2F71E3)",label:"Planning"},building:{color:"var(--loki-green, #1FC5A8)",label:"Building"},implementation:{color:"var(--loki-green, #1FC5A8)",label:"Building"},testing:{color:"var(--loki-purple, #553DE9)",label:"Testing"},review:{color:"var(--loki-yellow, #D4A03C)",label:"Review"},overhead:{color:"var(--loki-text-muted, #939084)",label:"Overhead"}},ft=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._phases=[],this._budget=null,this._totalCost=0,this._hoveredPhase=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),1e4)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let t=await this._api._get("/api/v2/cost/breakdown");this._phases=t.phases||[],this._budget=t.budget_usd||null,this._totalCost=t.total_usd||this._phases.reduce((e,i)=>e+(i.cost_usd||0),0)}catch{this._phases.length===0&&(this._phases=this._getDemoData(),this._budget=10,this._totalCost=this._phases.reduce((t,e)=>t+e.cost_usd,0))}this.render()}_getDemoData(){return[{phase:"planning",cost_usd:.85,tokens:12400},{phase:"building",cost_usd:3.2,tokens:68500},{phase:"testing",cost_usd:1.45,tokens:31200},{phase:"review",cost_usd:.9,tokens:18800},{phase:"overhead",cost_usd:.35,tokens:5600}]}_formatCost(t){return t==null?"--":"$"+t.toFixed(2)}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_bindEvents(){this.shadowRoot.querySelectorAll(".waterfall-bar").forEach(e=>{e.addEventListener("mouseenter",()=>{this._hoveredPhase=e.dataset.phase,this._updateTooltip(e)}),e.addEventListener("mouseleave",()=>{this._hoveredPhase=null,this._hideTooltip()})})}_updateTooltip(t){let e=this.shadowRoot.querySelector(".tooltip");if(!e)return;let i=this._phases.find(o=>o.phase===this._hoveredPhase);if(!i)return;let a=Rt[i.phase]||{label:i.phase};e.innerHTML=`<strong>${a.label}</strong>: ${this._formatCost(i.cost_usd)}`,e.style.display="block";let s=t.getBoundingClientRect(),r=this.shadowRoot.querySelector(".chart-area").getBoundingClientRect();e.style.left=s.left-r.left+s.width/2+"px",e.style.top=s.top-r.top-30+"px"}_hideTooltip(){let t=this.shadowRoot.querySelector(".tooltip");t&&(t.style.display="none")}_getStyles(){return`
|
|
11905
11918
|
:host {
|
|
11906
11919
|
display: block;
|
|
11907
11920
|
}
|
|
@@ -12091,11 +12104,11 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
12091
12104
|
</div>
|
|
12092
12105
|
<div class="empty-state">No cost data available</div>
|
|
12093
12106
|
</div>
|
|
12094
|
-
`;return}let e=Math.max(...this._phases.map(l=>l.cost_usd||0),.01),i=160,a=this._budget?Math.max(e,this._budget):e,s=this._budget?this._budget/a*i:null,r=this._phases.map(l=>{let c=
|
|
12107
|
+
`;return}let e=Math.max(...this._phases.map(l=>l.cost_usd||0),.01),i=160,a=this._budget?Math.max(e,this._budget):e,s=this._budget?this._budget/a*i:null,r=this._phases.map(l=>{let c=Rt[l.phase]||{color:"var(--loki-text-muted)",label:l.phase},p=(l.cost_usd||0)/a*i,h=this._hoveredPhase===l.phase;return`
|
|
12095
12108
|
<div class="bar-group">
|
|
12096
12109
|
<span class="bar-value">${this._formatCost(l.cost_usd)}</span>
|
|
12097
12110
|
<div class="waterfall-bar" data-phase="${this._escapeHtml(l.phase)}"
|
|
12098
|
-
style="height: ${Math.max(p,4)}px; background: ${c.color}; ${
|
|
12111
|
+
style="height: ${Math.max(p,4)}px; background: ${c.color}; ${h?"opacity: 0.85;":""}">
|
|
12099
12112
|
</div>
|
|
12100
12113
|
<span class="bar-label">${c.label}</span>
|
|
12101
12114
|
</div>
|
|
@@ -12103,7 +12116,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
12103
12116
|
<div class="budget-line" style="bottom: ${s+40}px;">
|
|
12104
12117
|
<span class="budget-label">Budget: ${this._formatCost(this._budget)}</span>
|
|
12105
12118
|
</div>
|
|
12106
|
-
`:"",n=this._phases.map(l=>{let c=
|
|
12119
|
+
`:"",n=this._phases.map(l=>{let c=Rt[l.phase]||{color:"var(--loki-text-muted)",label:l.phase},p=this._totalCost>0?(l.cost_usd/this._totalCost*100).toFixed(0):0;return`<div class="summary-item">
|
|
12107
12120
|
<div class="summary-dot" style="background: ${c.color};"></div>
|
|
12108
12121
|
<span class="summary-label">${c.label}</span>
|
|
12109
12122
|
<span class="summary-value">${this._formatCost(l.cost_usd)} (${p}%)</span>
|
|
@@ -12125,7 +12138,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
12125
12138
|
</div>
|
|
12126
12139
|
</div>
|
|
12127
12140
|
</div>
|
|
12128
|
-
`,this._bindEvents()}};customElements.get("loki-cost-waterfall")||customElements.define("loki-cost-waterfall",ft);var
|
|
12141
|
+
`,this._bindEvents()}};customElements.get("loki-cost-waterfall")||customElements.define("loki-cost-waterfall",ft);var De={1:{bg:"rgba(212, 160, 60, 0.15)",border:"#D4A03C",label:"1st"},2:{bg:"rgba(147, 144, 132, 0.15)",border:"#939084",label:"2nd"},3:{bg:"rgba(196, 130, 91, 0.15)",border:"#C4825B",label:"3rd"}},kt=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._agents=[],this._expandedAgent=null,this._api=null,this._pollInterval=null,this._previousRanks={}}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadData()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_startPolling(){this._pollInterval=setInterval(()=>this._loadData(),1e4)}_stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}async _loadData(){try{let e=(await this._api._get("/api/v2/agents/leaderboard")).agents||[],i={};e.forEach((a,s)=>{i[a.type||a.name]=s+1}),this._previousRanks={...this._currentRanks||{}},this._currentRanks=i,this._agents=e}catch{this._agents.length===0&&(this._agents=this._getDemoData(),this._currentRanks={},this._agents.forEach((t,e)=>{this._currentRanks[t.type]=e+1}),this._previousRanks={})}this.render()}_getDemoData(){return[{type:"code-generator",name:"Code Generator",tasks:24,quality:9.2,speed:"fast",cost_usd:2.4},{type:"test-writer",name:"Test Writer",tasks:18,quality:9,speed:"fast",cost_usd:1.2},{type:"code-reviewer",name:"Code Reviewer",tasks:15,quality:8.8,speed:"medium",cost_usd:1.8},{type:"architect",name:"Architect",tasks:8,quality:9.5,speed:"slow",cost_usd:3.1},{type:"debugger",name:"Debugger",tasks:12,quality:8.5,speed:"fast",cost_usd:.95},{type:"doc-writer",name:"Documentation",tasks:10,quality:8.3,speed:"fast",cost_usd:.6}]}_getRankChange(t){let e=this._currentRanks?.[t],i=this._previousRanks?.[t];return e==null||i==null?0:i-e}_escapeHtml(t){return t?String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_toggleAgent(t){this._expandedAgent=this._expandedAgent===t?null:t,this.render()}_bindEvents(){this.shadowRoot.querySelectorAll(".agent-row").forEach(e=>{e.addEventListener("click",()=>{this._toggleAgent(e.dataset.agent)})})}_getQualityColor(t){return t>=9?"var(--loki-green, #1FC5A8)":t>=8?"var(--loki-blue, #2F71E3)":t>=7?"var(--loki-yellow, #D4A03C)":"var(--loki-red, #C45B5B)"}_getSpeedLabel(t){return t==="fast"?{label:"Fast",color:"var(--loki-green, #1FC5A8)"}:t==="medium"?{label:"Medium",color:"var(--loki-yellow, #D4A03C)"}:{label:"Slow",color:"var(--loki-red, #C45B5B)"}}_getStyles(){return`
|
|
12129
12142
|
:host {
|
|
12130
12143
|
display: block;
|
|
12131
12144
|
}
|
|
@@ -12338,7 +12351,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
12338
12351
|
</div>
|
|
12339
12352
|
<div class="empty-state">No agent performance data available</div>
|
|
12340
12353
|
</div>
|
|
12341
|
-
`;return}let e=this._agents.map((i,a)=>{let s=a+1,r=
|
|
12354
|
+
`;return}let e=this._agents.map((i,a)=>{let s=a+1,r=De[s],o=i.type||i.name,n=this._getRankChange(o),l=this._expandedAgent===o,c=this._getQualityColor(i.quality),p=this._getSpeedLabel(i.speed),h=(i.quality||0)/10*100,b;r?b=`<div class="rank-badge" style="background: ${r.bg}; color: ${r.border};">${s}</div>`:b=`<span class="rank-number" style="color: var(--loki-text-muted);">${s}</span>`;let m="";n>0?m=`<span class="rank-change rank-up">+${n}</span>`:n<0&&(m=`<span class="rank-change rank-down">${n}</span>`);let f=l?`
|
|
12342
12355
|
<div class="agent-detail">
|
|
12343
12356
|
<div class="detail-metric">
|
|
12344
12357
|
<span class="detail-label">Total Cost</span>
|
|
@@ -12365,7 +12378,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
12365
12378
|
<div class="metric-cell">
|
|
12366
12379
|
<div class="quality-score">
|
|
12367
12380
|
<span style="color: ${c};">${(i.quality||0).toFixed(1)}</span>
|
|
12368
|
-
<div class="quality-bar"><div class="quality-fill" style="width: ${
|
|
12381
|
+
<div class="quality-bar"><div class="quality-fill" style="width: ${h}%; background: ${c};"></div></div>
|
|
12369
12382
|
</div>
|
|
12370
12383
|
</div>
|
|
12371
12384
|
<div class="metric-cell">
|
|
@@ -12391,7 +12404,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
12391
12404
|
${e}
|
|
12392
12405
|
</div>
|
|
12393
12406
|
</div>
|
|
12394
|
-
`,this._bindEvents()}};customElements.get("loki-agent-leaderboard")||customElements.define("loki-agent-leaderboard",kt);var
|
|
12407
|
+
`,this._bindEvents()}};customElements.get("loki-agent-leaderboard")||customElements.define("loki-agent-leaderboard",kt);var Qt=50,xt=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._api=null,this._statusLoading=!1,this._statusError=null,this._status=null,this._eventsLoading=!1,this._eventsError=null,this._events=[],this._eventsSource=null,this._eventsCount=0,this._lookupId="",this._lookupLoading=!1,this._lookupError=null,this._lookupResult=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(t,e,i){if(e!==i)switch(t){case"api-url":this._api&&(this._api.baseUrl=i,this._loadStatus());break;case"theme":this._applyTheme(),this.render();break}}_setupApi(){let t=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:t})}_stopPolling(){}async _loadStatus(){this._statusLoading=!0,this._statusError=null,this.render();try{this._status=await this._api.get("/api/managed/status")}catch(t){this._statusError=t&&t.message?t.message:"Failed to load managed status",this._status=null}finally{this._statusLoading=!1}this._status&&this._status.enabled?await this._loadEvents():this.render()}async _loadEvents(t=Qt){this._eventsLoading=!0,this._eventsError=null,this.render();try{let e=await this._api.get("/api/managed/events?limit="+encodeURIComponent(t));Array.isArray(e)?(this._events=e,this._eventsCount=e.length,this._eventsSource=null):e&&typeof e=="object"?(this._events=Array.isArray(e.events)?e.events:[],this._eventsCount=typeof e.count=="number"?e.count:this._events.length,this._eventsSource=e.source||null):(this._events=[],this._eventsCount=0,this._eventsSource=null)}catch(e){this._eventsError=e&&e.message?e.message:"Failed to load managed events",this._events=[],this._eventsCount=0,this._eventsSource=null}finally{this._eventsLoading=!1,this.render()}}async _lookupMemoryVersion(){let t=(this._lookupId||"").trim();if(!t){this._lookupError="Enter a memory ID to look up",this._lookupResult=null,this.render();return}this._lookupLoading=!0,this._lookupError=null,this._lookupResult=null,this.render();try{let e="/api/managed/memory_versions/"+encodeURIComponent(t);this._lookupResult=await this._api.get(e)}catch(e){this._lookupError=e&&e.message?e.message:"Failed to load memory versions",this._lookupResult=null}finally{this._lookupLoading=!1,this.render()}}_onLookupInput(t){this._lookupId=t&&t.target?t.target.value:""}_onLookupKeyDown(t){t&&t.key==="Enter"&&(t.preventDefault(),this._lookupMemoryVersion())}_attachEventHandlers(){let t=this.shadowRoot;if(!t)return;let e=t.querySelector("#refresh-status-btn");e&&e.addEventListener("click",()=>this._loadStatus());let i=t.querySelector("#refresh-events-btn");i&&i.addEventListener("click",()=>this._loadEvents());let a=t.querySelector("#lookup-input");a&&(a.addEventListener("input",r=>this._onLookupInput(r)),a.addEventListener("keydown",r=>this._onLookupKeyDown(r)));let s=t.querySelector("#lookup-btn");s&&s.addEventListener("click",()=>this._lookupMemoryVersion())}_escapeHtml(t){return t==null?"":String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}_formatTimestamp(t){if(!t)return"";let e;return typeof t=="number"?e=new Date(t>1e12?t:t*1e3):e=new Date(t),Number.isNaN(e.getTime())?String(t):e.toISOString().replace("T"," ").replace(/\.\d+Z$/,"Z")}_renderStatusSection(){if(this._statusLoading)return'<div class="status-row muted">Loading managed memory status...</div>';if(this._statusError)return`
|
|
12395
12408
|
<div class="error-banner" role="alert">
|
|
12396
12409
|
<strong>Status error:</strong>
|
|
12397
12410
|
<span>${this._escapeHtml(this._statusError)}</span>
|
|
@@ -12770,7 +12783,7 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
12770
12783
|
${e?`
|
|
12771
12784
|
<div class="section">
|
|
12772
12785
|
<div class="panel-header">
|
|
12773
|
-
<h3 class="section-title">Recent events (limit ${
|
|
12786
|
+
<h3 class="section-title">Recent events (limit ${Qt})</h3>
|
|
12774
12787
|
<button id="refresh-events-btn" class="btn" type="button">Refresh events</button>
|
|
12775
12788
|
</div>
|
|
12776
12789
|
${this._renderEventsSection()}
|
|
@@ -12782,7 +12795,77 @@ var LokiDashboard=(()=>{var _t=Object.defineProperty;var te=Object.getOwnPropert
|
|
|
12782
12795
|
</div>
|
|
12783
12796
|
`:this._statusError?"":this._renderDisabledNotice()}
|
|
12784
12797
|
</div>
|
|
12785
|
-
`,this._attachEventHandlers()}};customElements.get("loki-managed-memory-panel")||customElements.define("loki-managed-memory-panel",xt);var
|
|
12798
|
+
`,this._attachEventHandlers()}};customElements.get("loki-managed-memory-panel")||customElements.define("loki-managed-memory-panel",xt);var _t=class extends u{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._items=[],this._loading=!1,this._error=null,this._activeFile=null,this._activeBody=null,this._activeBodyError=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadList(),this._pollInterval=setInterval(()=>this._loadList(),1e4)}disconnectedCallback(){super.disconnectedCallback(),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}attributeChangedCallback(t,e,i){e!==i&&(t==="api-url"&&this._api&&(this._api.baseUrl=i,this._loadList()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||(typeof window<"u"?window.location.origin:"");this._api=g({baseUrl:t})}async _loadList(){this._loading=!0,this._error=null;try{let t=await this._api.get("/api/escalations");this._items=Array.isArray(t&&t.escalations)?t.escalations:[]}catch(t){this._error=t&&t.message?t.message:String(t),this._items=[]}finally{this._loading=!1,this.render()}}async _openFile(t){this._activeFile=t,this._activeBody=null,this._activeBodyError=null,this.render();try{let e=(this._api.baseUrl||"")+"/api/escalations/"+encodeURIComponent(t),i=await fetch(e,{credentials:"include"});if(!i.ok)throw new Error("HTTP "+i.status);this._activeBody=await i.text()}catch(e){this._activeBodyError=e&&e.message?e.message:String(e)}this.render()}_closeFile(){this._activeFile=null,this._activeBody=null,this._activeBodyError=null,this.render()}_formatSize(t){return typeof t!="number"?"--":t<1024?t+" B":t<1024*1024?(t/1024).toFixed(1)+" KB":(t/(1024*1024)).toFixed(1)+" MB"}_formatDate(t){if(!t)return"--";try{let e=new Date(t);return isNaN(e.getTime())?t:e.toLocaleString()}catch{return t}}_escapeHtml(t){return t==null?"":String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}render(){let t=this.shadowRoot||this;if(!t)return;let e=`
|
|
12799
|
+
<style>
|
|
12800
|
+
:host { display: block; }
|
|
12801
|
+
.esc-wrapper {
|
|
12802
|
+
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
|
12803
|
+
color: var(--text-primary, #201515);
|
|
12804
|
+
}
|
|
12805
|
+
.esc-explain {
|
|
12806
|
+
color: var(--text-muted, #939084);
|
|
12807
|
+
font-size: 0.875rem;
|
|
12808
|
+
margin-bottom: 12px;
|
|
12809
|
+
}
|
|
12810
|
+
.esc-empty {
|
|
12811
|
+
padding: 16px;
|
|
12812
|
+
background: var(--bg-card, #ffffff);
|
|
12813
|
+
border: 1px dashed var(--border, #ECEAE3);
|
|
12814
|
+
border-radius: 6px;
|
|
12815
|
+
color: var(--text-muted, #939084);
|
|
12816
|
+
font-size: 0.875rem;
|
|
12817
|
+
}
|
|
12818
|
+
.esc-list { display: flex; flex-direction: column; gap: 6px; }
|
|
12819
|
+
.esc-item {
|
|
12820
|
+
display: flex; justify-content: space-between; align-items: center;
|
|
12821
|
+
padding: 10px 12px;
|
|
12822
|
+
background: var(--bg-card, #ffffff);
|
|
12823
|
+
border: 1px solid var(--border, #ECEAE3);
|
|
12824
|
+
border-radius: 6px;
|
|
12825
|
+
cursor: pointer;
|
|
12826
|
+
}
|
|
12827
|
+
.esc-item:hover { background: var(--bg-hover, #F3EFE9); }
|
|
12828
|
+
.esc-name { font-family: 'JetBrains Mono', monospace; font-size: 0.85rem; }
|
|
12829
|
+
.esc-meta { font-size: 0.75rem; color: var(--text-muted, #939084); }
|
|
12830
|
+
.esc-error {
|
|
12831
|
+
padding: 10px 12px;
|
|
12832
|
+
background: var(--bg-card, #ffffff);
|
|
12833
|
+
border: 1px solid var(--error, #C45B5B);
|
|
12834
|
+
border-radius: 6px;
|
|
12835
|
+
color: var(--error, #C45B5B);
|
|
12836
|
+
font-size: 0.85rem;
|
|
12837
|
+
}
|
|
12838
|
+
.esc-viewer {
|
|
12839
|
+
margin-top: 16px;
|
|
12840
|
+
padding: 12px;
|
|
12841
|
+
background: var(--bg-card, #ffffff);
|
|
12842
|
+
border: 1px solid var(--border, #ECEAE3);
|
|
12843
|
+
border-radius: 6px;
|
|
12844
|
+
}
|
|
12845
|
+
.esc-viewer-header {
|
|
12846
|
+
display: flex; justify-content: space-between; align-items: center;
|
|
12847
|
+
margin-bottom: 8px;
|
|
12848
|
+
}
|
|
12849
|
+
.esc-close-btn {
|
|
12850
|
+
padding: 4px 10px; cursor: pointer;
|
|
12851
|
+
border: 1px solid var(--border, #ECEAE3);
|
|
12852
|
+
background: transparent; border-radius: 4px;
|
|
12853
|
+
color: var(--text-secondary, #36342E);
|
|
12854
|
+
font-size: 0.75rem;
|
|
12855
|
+
}
|
|
12856
|
+
.esc-body {
|
|
12857
|
+
font-family: 'JetBrains Mono', monospace;
|
|
12858
|
+
font-size: 0.78rem;
|
|
12859
|
+
white-space: pre-wrap;
|
|
12860
|
+
word-wrap: break-word;
|
|
12861
|
+
max-height: 480px;
|
|
12862
|
+
overflow: auto;
|
|
12863
|
+
background: var(--bg-secondary, #F8F4F0);
|
|
12864
|
+
padding: 10px;
|
|
12865
|
+
border-radius: 4px;
|
|
12866
|
+
}
|
|
12867
|
+
</style>
|
|
12868
|
+
`,i="";this._loading&&this._items.length===0?i='<div class="esc-empty">Loading escalations...</div>':this._error?i='<div class="esc-error">Failed to load escalations: '+this._escapeHtml(this._error)+"</div>":!this._items||this._items.length===0?i='<div class="esc-empty">Escalations: no events yet. Handoff/escalation markdown documents written by the runner under .loki/escalations/ will appear here.</div>':i='<div class="esc-list">'+this._items.map(n=>{let l=this._escapeHtml(n.filename||""),c=this._escapeHtml(this._formatSize(n.size_bytes)),p=this._escapeHtml(this._formatDate(n.modified_at));return'<div class="esc-item" data-filename="'+l+'"><span class="esc-name">'+l+'</span><span class="esc-meta">'+c+" · "+p+"</span></div>"}).join("")+"</div>";let a="";if(this._activeFile){let o=this._escapeHtml(this._activeFile),n;this._activeBodyError?n='<div class="esc-error">Failed to load: '+this._escapeHtml(this._activeBodyError)+"</div>":this._activeBody===null?n='<div class="esc-body">Loading '+o+"...</div>":n='<div class="esc-body">'+this._escapeHtml(this._activeBody)+"</div>",a='<div class="esc-viewer"><div class="esc-viewer-header"><span class="esc-name">'+o+'</span><button class="esc-close-btn" data-action="close">Close</button></div>'+n+"</div>"}t.innerHTML=e+'<div class="esc-wrapper"><div class="esc-explain">Handoff/escalation documents written under .loki/escalations/. Click an entry to view its contents.</div>'+i+a+"</div>",t.querySelectorAll(".esc-item").forEach(o=>{o.addEventListener("click",()=>{let n=o.getAttribute("data-filename");n&&this._openFile(n)})});let r=t.querySelector('.esc-close-btn[data-action="close"]');r&&r.addEventListener("click",()=>this._closeFile())}};typeof customElements<"u"&&!customElements.get("loki-escalations")&&customElements.define("loki-escalations",_t);var ze="1.4.0";function He(d={}){return d.theme?x.setTheme(d.theme):d.autoDetectContext!==!1?x.init():R.init(),d.apiUrl&&g({baseUrl:d.apiUrl}),{theme:x.getTheme(),context:x.detectContext()}}return ne(Re);})();
|
|
12786
12869
|
|
|
12787
12870
|
|
|
12788
12871
|
// Initialize dashboard when DOM is ready
|
|
@@ -12844,7 +12927,8 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
12844
12927
|
'quality-gates',
|
|
12845
12928
|
'rarv-timeline',
|
|
12846
12929
|
'migration-dashboard',
|
|
12847
|
-
'analytics-dashboard'
|
|
12930
|
+
'analytics-dashboard',
|
|
12931
|
+
'escalations-panel'
|
|
12848
12932
|
];
|
|
12849
12933
|
components.forEach(function(id) {
|
|
12850
12934
|
var el = document.getElementById(id);
|
|
@@ -12928,7 +13012,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
12928
13012
|
document.addEventListener('keydown', function(e) {
|
|
12929
13013
|
if ((e.metaKey || e.ctrlKey) && ((e.key >= '1' && e.key <= '9') || e.key === '0')) {
|
|
12930
13014
|
e.preventDefault();
|
|
12931
|
-
var sections = ['overview', 'insights', 'prd-checklist', 'app-runner', 'council', 'quality', 'cost', 'checkpoint', 'context', 'notifications', 'migration', 'analytics'];
|
|
13015
|
+
var sections = ['overview', 'insights', 'prd-checklist', 'app-runner', 'council', 'quality', 'cost', 'checkpoint', 'context', 'notifications', 'migration', 'analytics', 'escalations'];
|
|
12932
13016
|
var idx = e.key === '0' ? 9 : parseInt(e.key) - 1;
|
|
12933
13017
|
if (idx < sections.length) switchSection(sections[idx]);
|
|
12934
13018
|
}
|
|
@@ -12969,7 +13053,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
12969
13053
|
// Skip if modifier keys are held (let browser defaults work)
|
|
12970
13054
|
if (e.metaKey || e.ctrlKey || e.altKey) return;
|
|
12971
13055
|
|
|
12972
|
-
var sections = ['overview', 'insights', 'prd-checklist', 'app-runner', 'council', 'quality', 'cost', 'checkpoint', 'context', 'notifications', 'migration', 'analytics'];
|
|
13056
|
+
var sections = ['overview', 'insights', 'prd-checklist', 'app-runner', 'council', 'quality', 'cost', 'checkpoint', 'context', 'notifications', 'migration', 'analytics', 'escalations'];
|
|
12973
13057
|
|
|
12974
13058
|
switch (e.key) {
|
|
12975
13059
|
// Section navigation: 1-9, 0
|
|
@@ -12994,6 +13078,12 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
12994
13078
|
switchSection('analytics');
|
|
12995
13079
|
break;
|
|
12996
13080
|
|
|
13081
|
+
// Escalations page
|
|
13082
|
+
case 'e':
|
|
13083
|
+
e.preventDefault();
|
|
13084
|
+
switchSection('escalations');
|
|
13085
|
+
break;
|
|
13086
|
+
|
|
12997
13087
|
// Help overlay
|
|
12998
13088
|
case '?':
|
|
12999
13089
|
e.preventDefault();
|