loki-mode 9.71.0 → 9.73.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/completion-council.sh +20 -3
- package/autonomy/run.sh +5 -2
- package/dashboard/__init__.py +1 -1
- package/dashboard/server.py +4 -0
- package/dashboard/static/cost.html +6 -1
- package/dashboard/static/index.html +113 -101
- package/dashboard/static/proofs.html +6 -1
- package/docs/INSTALLATION.md +1 -1
- package/docs/v10/ARCHITECT-CUTS.md +245 -0
- package/docs/v10/BOARD.md +45 -25
- package/docs/v10/TODO.md +3 -1
- package/loki-ts/dist/loki.js +2 -2
- package/mcp/__init__.py +1 -1
- package/package.json +1 -1
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/web-app/dist/assets/{AdminPage-5-i7dYRv.js → AdminPage-B11jqriL.js} +1 -1
- package/web-app/dist/assets/{Avatar-DOgXkiA5.js → Avatar-vmIEiL2U.js} +1 -1
- package/web-app/dist/assets/{Badge-BBCAEx-v.js → Badge-DxtrDGcl.js} +1 -1
- package/web-app/dist/assets/{Button-mrjJiIzX.js → Button-BiPlRkkg.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-DO1BqQtR.js → CockpitPage-DXKAc0jc.js} +1 -1
- package/web-app/dist/assets/{ComparePage-CttX-p4A.js → ComparePage-B4ddvt9J.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-DrXZPl7W.js → ErrorBoundary-BIJy59N_.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-DsHfSljL.js → EvidenceReceiptPanel-C4-Phh1f.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-DXDCz06W.js → GitHubIssuesPanel-CVIG0uwi.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-3qECbDiA.js → GitHubPRsPanel-B_VHTB-t.js} +1 -1
- package/web-app/dist/assets/{HomePage-vb55Jnnw.js → HomePage-cxONjTSm.js} +2 -2
- package/web-app/dist/assets/{LoginPage-C1wouCAg.js → LoginPage-D49p6aVy.js} +1 -1
- package/web-app/dist/assets/{MagicPage-Ccf2TzsX.js → MagicPage-C5GUEIuM.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-DxpjKBlD.js → MetricsPage-I-OXi9kG.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-BjesliCI.js → NotFoundPage-Do19cbOP.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-OLJv91Fm.js → ProjectPage-TRyzTIFH.js} +69 -69
- package/web-app/dist/assets/ProjectsPage-BLSDhtVb.js +6 -0
- package/web-app/dist/assets/{SettingsPage-B92ofTn5.js → SettingsPage-BvixtAw7.js} +1 -1
- package/web-app/dist/assets/ShowcasePage-By96BMJz.js +1 -0
- package/web-app/dist/assets/{SystemSettingsPage-DQ7y1jJw.js → SystemSettingsPage-AvVujpIo.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-DvI2Ysar.js → TeamsPage-BiT3N4px.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-qkFTI361.js → TemplatesPage-Y_m-dzfd.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-Bbi5Qsu1.js → TerminalOutput-oPTCcEGy.js} +1 -1
- package/web-app/dist/assets/{activity-B6_UNFP3.js → activity-DCa9Pi7k.js} +1 -1
- package/web-app/dist/assets/{bell-D9bRY83l.js → bell-Br7Xsjam.js} +1 -1
- package/web-app/dist/assets/{bot-B9XE8rVE.js → bot-BsQKlSP5.js} +1 -1
- package/web-app/dist/assets/{check-CIlNFVu7.js → check-Cb49hCzQ.js} +1 -1
- package/web-app/dist/assets/{chevron-left-sqTwkCti.js → chevron-left-Cs63FOmY.js} +1 -1
- package/web-app/dist/assets/{circle-alert-ClR-8eiz.js → circle-alert-C8A636Wl.js} +1 -1
- package/web-app/dist/assets/{clock-DhrLudbQ.js → clock-DhlnHjQI.js} +1 -1
- package/web-app/dist/assets/{cloud-CbY5ijES.js → cloud-uOYQxGRY.js} +1 -1
- package/web-app/dist/assets/{code-xml-DGN0zQOT.js → code-xml-9O9XlVo9.js} +1 -1
- package/web-app/dist/assets/{database-CFkV71Ae.js → database-D9Oek2JS.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-t0__nc7_.js → dollar-sign-CHetUBPR.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-V4yaRoxs.js → file-code-corner-oTJV_ce4.js} +1 -1
- package/web-app/dist/assets/{file-plus-BTdcA9zR.js → file-plus-vuloOqQB.js} +1 -1
- package/web-app/dist/assets/{globe-DJ8UlFt2.js → globe-DMVdf8bk.js} +1 -1
- package/web-app/dist/assets/{hammer-DSpaXtqP.js → hammer-15WRQJ1o.js} +1 -1
- package/web-app/dist/assets/index-Cx7e1d6w.css +1 -0
- package/web-app/dist/assets/{index-aYgURGFC.js → index-SRKz3Imw.js} +2 -2
- package/web-app/dist/assets/{layers-cbPS7UG9.js → layers-C-QQQP9K.js} +1 -1
- package/web-app/dist/assets/{loader-circle-CciQSsBx.js → loader-circle-DqoJevCK.js} +1 -1
- package/web-app/dist/assets/{lock-JtWoEayV.js → lock-B68yfqau.js} +1 -1
- package/web-app/dist/assets/{package-Dcv0g9iv.js → package-DAxTtm-S.js} +1 -1
- package/web-app/dist/assets/{plus-R_7Xr4PC.js → plus-BSbdI5QI.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-6MdZdvHz.js → refresh-cw-DlvFuI3J.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-Dcteu0jr.js → rotate-ccw-BF03pKE0.js} +1 -1
- package/web-app/dist/assets/{scroll-text-Xcw2I15b.js → scroll-text-QFZ1JdTD.js} +1 -1
- package/web-app/dist/assets/{server-BhMeLqV8.js → server-tyIvmSke.js} +1 -1
- package/web-app/dist/assets/{shield-alert-Y7birYk_.js → shield-alert-DHeqbtBK.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-B9I1RzAj.js → thumbs-up-CRag1Tn5.js} +1 -1
- package/web-app/dist/assets/{trash-2-FrJ_zeQ_.js → trash-2-B0n4x-Ds.js} +1 -1
- package/web-app/dist/assets/{trending-down-DA-YY1yX.js → trending-down-DC4Aqzso.js} +1 -1
- package/web-app/dist/assets/{trending-up-CC7ghXOa.js → trending-up-DFG157ke.js} +1 -1
- package/web-app/dist/assets/{upload-Btyqt4Cn.js → upload-BdWQ4cWx.js} +1 -1
- package/web-app/dist/assets/{usePolling-CTqGbMeS.js → usePolling-DMgD-dJ5.js} +1 -1
- package/web-app/dist/assets/{user-AWsEaMJm.js → user-DXaZeAe4.js} +1 -1
- package/web-app/dist/index.html +2 -2
- package/web-app/dist/assets/ProjectsPage-Bd0VWUNT.js +0 -6
- package/web-app/dist/assets/ShowcasePage-Ben4Ud4y.js +0 -1
- package/web-app/dist/assets/index-BfQ0f3-S.css +0 -1
|
@@ -1701,7 +1701,7 @@
|
|
|
1701
1701
|
the only place that fact surfaced was a bill. Shown ALWAYS, not
|
|
1702
1702
|
just when a cap exists, because "no cap" is the state a user most
|
|
1703
1703
|
needs to know about. -->
|
|
1704
|
-
<div id="budget-banner" style="display:none;margin-bottom:12px;padding:10px 12px;
|
|
1704
|
+
<div id="cost-budget-banner" style="display:none;margin-bottom:12px;padding:10px 12px;
|
|
1705
1705
|
border:1px solid var(--loki-border);border-radius:6px;font-size:12px;"></div>
|
|
1706
1706
|
<loki-cost-dashboard id="cost-dashboard"></loki-cost-dashboard>
|
|
1707
1707
|
</div>
|
|
@@ -1857,7 +1857,7 @@
|
|
|
1857
1857
|
|
|
1858
1858
|
<!-- Inlined JavaScript Bundle -->
|
|
1859
1859
|
<script>
|
|
1860
|
-
var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropertyDescriptor;var xt=Object.getOwnPropertyNames;var _t=Object.prototype.hasOwnProperty;var yt=(d,e,t)=>e in d?Le(d,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):d[e]=t;var wt=(d,e)=>{for(var t in e)Le(d,t,{get:e[t],enumerable:!0})},$t=(d,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of xt(e))!_t.call(d,a)&&a!==t&&Le(d,a,{get:()=>e[a],enumerable:!(i=kt(e,a))||i.enumerable});return d};var Et=d=>$t(Le({},"__esModule",{value:!0}),d);var S=(d,e,t)=>yt(d,typeof e!="symbol"?e+"":e,t);var ri={};wt(ri,{ANIMATION:()=>I,ARIA_PATTERNS:()=>Me,ApiEvents:()=>f,BASE_STYLES:()=>Y,BREAKPOINTS:()=>ze,COMMON_STYLES:()=>Qe,KEYBOARD_SHORTCUTS:()=>He,KeyboardHandler:()=>O,LokiAnalytics:()=>me,LokiApiClient:()=>q,LokiApiKeys:()=>_e,LokiAppPreview:()=>oe,LokiAppStatus:()=>re,LokiAuditViewer:()=>xe,LokiChecklistViewer:()=>se,LokiCheckpointViewer:()=>le,LokiContextTracker:()=>de,LokiCostDashboard:()=>ne,LokiCostWaterfall:()=>we,LokiCouncilDashboard:()=>ae,LokiCouncilTranscripts:()=>Ce,LokiElement:()=>v,LokiEscalations:()=>Ee,LokiFleet:()=>ke,LokiLearningDashboard:()=>ie,LokiLogStream:()=>ee,LokiManagedMemoryPanel:()=>$e,LokiMascotPresence:()=>Ae,LokiMemoryBrowser:()=>te,LokiMigrationDashboard:()=>ge,LokiNotificationCenter:()=>ce,LokiOverview:()=>Q,LokiPromptOptimizer:()=>ue,LokiQualityGates:()=>ve,LokiQualityScore:()=>he,LokiRarvTimeline:()=>fe,LokiRunManager:()=>be,LokiSessionControl:()=>Z,LokiSessionDiff:()=>pe,LokiSpecPanel:()=>Te,LokiState:()=>W,LokiTaskBoard:()=>X,LokiTenantSwitcher:()=>ye,LokiTheme:()=>U,LokiWikiBrowser:()=>Se,MARKDOWN_STYLES:()=>z,RADIUS:()=>P,SPACING:()=>H,STATE_CHANGE_EVENT:()=>Ie,THEMES:()=>T,THEME_VARIABLES:()=>Re,TYPOGRAPHY:()=>$,UnifiedThemeManager:()=>w,VERSION:()=>ai,Z_INDEX:()=>B,createApiClient:()=>et,createStore:()=>tt,escapeHtml:()=>Be,generateThemeCSS:()=>E,generateTokensCSS:()=>K,getApiClient:()=>g,getState:()=>N,init:()=>si,renderMarkdown:()=>C});var T={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":"#553de9","--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":"#553de9","--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":"#553de9","--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":"#553de9","--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)"}},H={xs:"4px",sm:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"32px","3xl":"48px"},P={none:"0",sm:"2px",md:"4px",lg:"5px",xl:"5px",full:"9999px"},$={fontFamily:{sans:"'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif",serif:"'Fraunces', 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"}},I={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)"}},ze={sm:"640px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},B={base:"0",dropdown:"100",sticky:"200",modal:"300",popover:"400",tooltip:"500",toast:"600"},He={"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"]}},Me={button:{role:"button",tabIndex:0},tablist:{role:"tablist"},tab:{role:"tab",ariaSelected:!1,tabIndex:-1},tabpanel:{role:"tabpanel",tabIndex:0},list:{role:"list"},listitem:{role:"listitem"},livePolite:{ariaLive:"polite",ariaAtomic:!0},liveAssertive:{ariaLive:"assertive",ariaAtomic:!0},dialog:{role:"dialog",ariaModal:!0},alertdialog:{role:"alertdialog",ariaModal:!0},status:{role:"status",ariaLive:"polite"},alert:{role:"alert",ariaLive:"assertive"},log:{role:"log",ariaLive:"polite",ariaRelevant:"additions"}};function E(d){let e=T[d];return e?Object.entries(e).map(([t,i])=>`${t}: ${i};`).join(`
|
|
1860
|
+
var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropertyDescriptor;var xt=Object.getOwnPropertyNames;var _t=Object.prototype.hasOwnProperty;var yt=(d,e,t)=>e in d?Le(d,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):d[e]=t;var wt=(d,e)=>{for(var t in e)Le(d,t,{get:e[t],enumerable:!0})},$t=(d,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of xt(e))!_t.call(d,a)&&a!==t&&Le(d,a,{get:()=>e[a],enumerable:!(i=kt(e,a))||i.enumerable});return d};var Et=d=>$t(Le({},"__esModule",{value:!0}),d);var S=(d,e,t)=>yt(d,typeof e!="symbol"?e+"":e,t);var oi={};wt(oi,{ANIMATION:()=>I,ARIA_PATTERNS:()=>Me,ApiEvents:()=>f,BASE_STYLES:()=>Y,BREAKPOINTS:()=>ze,COMMON_STYLES:()=>Qe,KEYBOARD_SHORTCUTS:()=>He,KeyboardHandler:()=>O,LokiAnalytics:()=>me,LokiApiClient:()=>q,LokiApiKeys:()=>_e,LokiAppPreview:()=>oe,LokiAppStatus:()=>re,LokiAuditViewer:()=>xe,LokiChecklistViewer:()=>se,LokiCheckpointViewer:()=>le,LokiContextTracker:()=>de,LokiCostDashboard:()=>ne,LokiCostWaterfall:()=>we,LokiCouncilDashboard:()=>ae,LokiCouncilTranscripts:()=>Ce,LokiElement:()=>v,LokiEscalations:()=>Ee,LokiFleet:()=>ke,LokiLearningDashboard:()=>ie,LokiLogStream:()=>ee,LokiManagedMemoryPanel:()=>$e,LokiMascotPresence:()=>Te,LokiMemoryBrowser:()=>te,LokiMigrationDashboard:()=>ge,LokiNotificationCenter:()=>ce,LokiOverview:()=>Q,LokiPromptOptimizer:()=>ue,LokiQualityGates:()=>ve,LokiQualityScore:()=>he,LokiRarvTimeline:()=>fe,LokiRunManager:()=>be,LokiSessionControl:()=>Z,LokiSessionDiff:()=>pe,LokiSpecPanel:()=>Ae,LokiState:()=>W,LokiTaskBoard:()=>X,LokiTenantSwitcher:()=>ye,LokiTheme:()=>U,LokiWikiBrowser:()=>Se,MARKDOWN_STYLES:()=>z,RADIUS:()=>P,SPACING:()=>H,STATE_CHANGE_EVENT:()=>Ie,THEMES:()=>A,THEME_VARIABLES:()=>Re,TYPOGRAPHY:()=>$,UnifiedThemeManager:()=>w,VERSION:()=>si,Z_INDEX:()=>B,createApiClient:()=>et,createStore:()=>tt,escapeHtml:()=>Be,generateThemeCSS:()=>E,generateTokensCSS:()=>K,getApiClient:()=>g,getState:()=>N,init:()=>ri,renderMarkdown:()=>C});var A={light:{"--loki-bg-primary":"#FFFEFB","--loki-bg-secondary":"#F8F4F0","--loki-bg-tertiary":"#ECEAE3","--loki-bg-card":"#ffffff","--loki-bg-hover":"#F3EFE9","--loki-bg-active":"#E6E2DA","--loki-bg-overlay":"rgba(32, 21, 21, 0.5)","--loki-accent":"#553DE9","--loki-accent-hover":"#4432c4","--loki-accent-active":"#3828a0","--loki-accent-light":"#553de9","--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":"#553de9","--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":"#553de9","--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":"#553de9","--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)"}},H={xs:"4px",sm:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"32px","3xl":"48px"},P={none:"0",sm:"2px",md:"4px",lg:"5px",xl:"5px",full:"9999px"},$={fontFamily:{sans:"'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif",serif:"'Fraunces', 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"}},I={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)"}},ze={sm:"640px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},B={base:"0",dropdown:"100",sticky:"200",modal:"300",popover:"400",tooltip:"500",toast:"600"},He={"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"]}},Me={button:{role:"button",tabIndex:0},tablist:{role:"tablist"},tab:{role:"tab",ariaSelected:!1,tabIndex:-1},tabpanel:{role:"tabpanel",tabIndex:0},list:{role:"list"},listitem:{role:"listitem"},livePolite:{ariaLive:"polite",ariaAtomic:!0},liveAssertive:{ariaLive:"assertive",ariaAtomic:!0},dialog:{role:"dialog",ariaModal:!0},alertdialog:{role:"alertdialog",ariaModal:!0},status:{role:"status",ariaLive:"polite"},alert:{role:"alert",ariaLive:"assertive"},log:{role:"log",ariaLive:"polite",ariaRelevant:"additions"}};function E(d){let e=A[d];return e?Object.entries(e).map(([t,i])=>`${t}: ${i};`).join(`
|
|
1861
1861
|
`):""}function K(){return`
|
|
1862
1862
|
/* Spacing */
|
|
1863
1863
|
--loki-space-xs: ${H.xs};
|
|
@@ -2191,13 +2191,13 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
2191
2191
|
@media (min-width: ${ze.md}) {
|
|
2192
2192
|
.hide-desktop { display: none !important; }
|
|
2193
2193
|
}
|
|
2194
|
-
`,y=class y{static detectContext(){return typeof acquireVsCodeApi<"u"||document.body.classList.contains("vscode-body")||getComputedStyle(document.documentElement).getPropertyValue("--vscode-editor-background")?"vscode":document.documentElement.dataset.lokiContext==="cli"?"cli":"browser"}static detectVSCodeTheme(){let e=document.body;if(e.classList.contains("vscode-high-contrast"))return"high-contrast";if(e.classList.contains("vscode-dark"))return"dark";if(e.classList.contains("vscode-light"))return"light";let t=getComputedStyle(document.documentElement).getPropertyValue("--vscode-editor-background");if(t){let i=t.match(/\d+/g);if(i)return(parseInt(i[0])*299+parseInt(i[1])*587+parseInt(i[2])*114)/1e3>128?"light":"dark"}return null}static getTheme(){if(y.detectContext()==="vscode"){let t=y.detectVSCodeTheme();return t==="high-contrast"?"high-contrast":t==="dark"?"vscode-dark":"vscode-light"}return"light"}static setTheme(e){if(!
|
|
2194
|
+
`,y=class y{static detectContext(){return typeof acquireVsCodeApi<"u"||document.body.classList.contains("vscode-body")||getComputedStyle(document.documentElement).getPropertyValue("--vscode-editor-background")?"vscode":document.documentElement.dataset.lokiContext==="cli"?"cli":"browser"}static detectVSCodeTheme(){let e=document.body;if(e.classList.contains("vscode-high-contrast"))return"high-contrast";if(e.classList.contains("vscode-dark"))return"dark";if(e.classList.contains("vscode-light"))return"light";let t=getComputedStyle(document.documentElement).getPropertyValue("--vscode-editor-background");if(t){let i=t.match(/\d+/g);if(i)return(parseInt(i[0])*299+parseInt(i[1])*587+parseInt(i[2])*114)/1e3>128?"light":"dark"}return null}static getTheme(){if(y.detectContext()==="vscode"){let t=y.detectVSCodeTheme();return t==="high-contrast"?"high-contrast":t==="dark"?"vscode-dark":"vscode-light"}return"light"}static setTheme(e){if(!A[e]){console.warn(`Unknown theme: ${e}`);return}localStorage.setItem(y.STORAGE_KEY,e),document.documentElement.setAttribute("data-loki-theme",e),window.dispatchEvent(new CustomEvent("loki-theme-change",{detail:{theme:e,context:y.detectContext()}}))}static toggle(){let e=y.getTheme();return e.startsWith("vscode")?e:(y.setTheme("light"),"light")}static getVariables(e=null){let t=e||y.getTheme();return A[t]||A.light}static generateCSS(e=null){let t=e||y.getTheme();return`
|
|
2195
2195
|
:host {
|
|
2196
2196
|
${E(t)}
|
|
2197
2197
|
${K()}
|
|
2198
2198
|
}
|
|
2199
2199
|
${Y}
|
|
2200
|
-
`}static init(){let e=y.getTheme();document.documentElement.setAttribute("data-loki-theme",e),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",()=>{localStorage.getItem(y.STORAGE_KEY)||y.setTheme(y.getTheme())}),y.detectContext()==="vscode"&&new MutationObserver(()=>{let i=y.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"]})}};S(y,"STORAGE_KEY","loki-theme"),S(y,"CONTEXT_KEY","loki-context");var w=y,O=class{constructor(){this._handlers=new Map,this._enabled=!0}register(e,t){let i=He[e];if(!i){console.warn(`Unknown keyboard action: ${e}`);return}this._handlers.set(e,{shortcut:i,handler:t})}unregister(e){this._handlers.delete(e)}setEnabled(e){this._enabled=e}handleEvent(e){if(!this._enabled)return!1;for(let[t,{shortcut:i,handler:a}]of this._handlers)if(this._matchesShortcut(e,i))return e.preventDefault(),e.stopPropagation(),a(e),!0;return!1}_matchesShortcut(e,t){let i=e.key.toLowerCase(),a=t.modifiers||[];if(i!==t.key.toLowerCase())return!1;let s=a.includes("Ctrl")||a.includes("Meta"),r=a.includes("Shift"),o=a.includes("Alt"),n=(e.ctrlKey||e.metaKey)===s,l=e.shiftKey===r,c=e.altKey===o;return n&&l&&c}attach(e){this._boundHandler||(this._boundHandler=t=>this.handleEvent(t)),e.addEventListener("keydown",this._boundHandler)}detach(e){this._boundHandler&&e.removeEventListener("keydown",this._boundHandler)}},We="unknown";function Ue(d,e=t=>String(t)){if(d==null)return We;let t=typeof d=="number"?d:Number(d);return Number.isNaN(t)?We:e(t)}function
|
|
2200
|
+
`}static init(){let e=y.getTheme();document.documentElement.setAttribute("data-loki-theme",e),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",()=>{localStorage.getItem(y.STORAGE_KEY)||y.setTheme(y.getTheme())}),y.detectContext()==="vscode"&&new MutationObserver(()=>{let i=y.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"]})}};S(y,"STORAGE_KEY","loki-theme"),S(y,"CONTEXT_KEY","loki-context");var w=y,O=class{constructor(){this._handlers=new Map,this._enabled=!0}register(e,t){let i=He[e];if(!i){console.warn(`Unknown keyboard action: ${e}`);return}this._handlers.set(e,{shortcut:i,handler:t})}unregister(e){this._handlers.delete(e)}setEnabled(e){this._enabled=e}handleEvent(e){if(!this._enabled)return!1;for(let[t,{shortcut:i,handler:a}]of this._handlers)if(this._matchesShortcut(e,i))return e.preventDefault(),e.stopPropagation(),a(e),!0;return!1}_matchesShortcut(e,t){let i=e.key.toLowerCase(),a=t.modifiers||[];if(i!==t.key.toLowerCase())return!1;let s=a.includes("Ctrl")||a.includes("Meta"),r=a.includes("Shift"),o=a.includes("Alt"),n=(e.ctrlKey||e.metaKey)===s,l=e.shiftKey===r,c=e.altKey===o;return n&&l&&c}attach(e){this._boundHandler||(this._boundHandler=t=>this.handleEvent(t)),e.addEventListener("keydown",this._boundHandler)}detach(e){this._boundHandler&&e.removeEventListener("keydown",this._boundHandler)}},We="unknown";function Ue(d,e=t=>String(t)){if(d==null)return We;let t=typeof d=="number"?d:Number(d);return Number.isNaN(t)?We:e(t)}function T(d){return Ue(d,e=>e!==0&&Math.abs(e)<.01?e<0?">-$0.01":"<$0.01":(e<0?"-$":"$")+Math.abs(e).toFixed(2))}function De(d){return Ue(d,e=>{let t=Math.abs(e);return t>=1e6?(e/1e6).toFixed(2)+"M":t>=1e3?(e/1e3).toFixed(1)+"K":String(e)})}function Ne(d){return Ue(d,e=>Math.abs(e)<1e3?Math.round(e)+"ms":Math.abs(e)<6e4?(e/1e3).toFixed(1)+"s":Math.floor(e/6e4)+"m "+Math.round(e%6e4/1e3)+"s")}var Re={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":"#553de9","--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":"#553de9","--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":"#553de9","--loki-haiku":"#2ED8B6","--loki-transition":"0.2s cubic-bezier(0.4, 0, 0.2, 1)"}},Qe=`
|
|
2201
2201
|
:host {
|
|
2202
2202
|
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
|
2203
2203
|
line-height: 1.5;
|
|
@@ -2293,8 +2293,8 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
2293
2293
|
::-webkit-scrollbar-track { background: var(--loki-bg-primary); }
|
|
2294
2294
|
::-webkit-scrollbar-thumb { background: var(--loki-border); border-radius: 3px; }
|
|
2295
2295
|
::-webkit-scrollbar-thumb:hover { background: var(--loki-border-light); }
|
|
2296
|
-
`,
|
|
2297
|
-
`)}static applyToElement(e,t=null){let i=
|
|
2296
|
+
`,j=class j{static getTheme(){return w.getTheme()}static setTheme(e){w.setTheme(e)}static toggle(){return w.toggle()}static getVariables(e=null){let t=e||j.getTheme();return A[t]||Re[t]||Re.light}static toCSSString(e=null){let t=e||j.getTheme();if(A[t])return E(t);let i=j.getVariables(t);return Object.entries(i).map(([a,s])=>`${a}: ${s};`).join(`
|
|
2297
|
+
`)}static applyToElement(e,t=null){let i=j.getVariables(t);for(let[a,s]of Object.entries(i))e.style.setProperty(a,s)}static init(){w.init()}static detectContext(){return w.detectContext()}static getAvailableThemes(){return Object.keys(A)}};S(j,"STORAGE_KEY","loki-theme");var U=j,v=class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}),this._theme=U.getTheme(),this._themeChangeHandler=this._onThemeChange.bind(this),this._keyboardHandler=new O}connectedCallback(){window.addEventListener("loki-theme-change",this._themeChangeHandler),this._applyTheme(),this._setupKeyboardHandling(),this.render()}disconnectedCallback(){window.removeEventListener("loki-theme-change",this._themeChangeHandler),this._keyboardHandler.detach(this)}_onThemeChange(e){this._theme=e.detail.theme,this._applyTheme(),this.onThemeChange&&this.onThemeChange(this._theme)}_applyTheme(){U.applyToElement(this.shadowRoot.host,this._theme),this.setAttribute("data-loki-theme",this._theme)}_setupKeyboardHandling(){this._keyboardHandler.attach(this)}registerShortcut(e,t){this._keyboardHandler.register(e,t)}getBaseStyles(){return`
|
|
2298
2298
|
/* Design tokens */
|
|
2299
2299
|
:host {
|
|
2300
2300
|
${K()}
|
|
@@ -2352,7 +2352,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
2352
2352
|
}
|
|
2353
2353
|
|
|
2354
2354
|
${Y}
|
|
2355
|
-
`}getAriaPattern(e){return Me[e]||{}}applyAriaPattern(e,t){let i=this.getAriaPattern(t);for(let[a,s]of Object.entries(i))if(a==="role")e.setAttribute("role",s);else{let r=a.replace(/([A-Z])/g,"-$1").toLowerCase();e.setAttribute(r,s)}}render(){}};var j={realtime:1e3,normal:2e3,background:5e3,offline:1e4},Xe={vscode:j.normal,browser:j.realtime,cli:j.background},Ze={baseUrl:typeof window<"u"?window.location.origin:"http://localhost:57374",wsUrl:typeof window<"u"?`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/ws`:"ws://localhost:57374/ws",pollInterval:2e3,timeout:1e4,retryAttempts:3,retryDelay:1e3},f={CONNECTED:"api:connected",DISCONNECTED:"api:disconnected",ERROR:"api:error",STATUS_UPDATE:"api:status-update",TASK_CREATED:"api:task-created",TASK_UPDATED:"api:task-updated",TASK_DELETED:"api:task-deleted",PROJECT_CREATED:"api:project-created",PROJECT_UPDATED:"api:project-updated",AGENT_UPDATE:"api:agent-update",LOG_MESSAGE:"api:log-message",MEMORY_UPDATE:"api:memory-update",CHECKLIST_UPDATE:"api:checklist-update"},M=class M extends EventTarget{static getInstance(e={}){let t=e.baseUrl||Ze.baseUrl;return M._instances.has(t)||M._instances.set(t,new M(e)),M._instances.get(t)}static clearInstances(){M._instances.forEach(e=>e.disconnect()),M._instances.clear()}constructor(e={}){super(),this.config={...Ze,...e},this._ws=null,this._connected=!1,this._intentionalClose=!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=Xe[this._context]||j.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 j}_setupAdaptivePolling(){typeof document>"u"||(this._visibilityChangeHandler=()=>{document.hidden?this._setPollInterval(j.background):this._setPollInterval(Xe[this._context]||j.normal)},document.addEventListener("visibilitychange",this._visibilityChangeHandler))}_setPollInterval(e){this._currentPollInterval=e,this._pollInterval&&(this.stopPolling(),this.startPolling(null,e))}setPollMode(e){let t=j[e];t&&this._setPollInterval(t)}_setupVSCodeBridge(){if(!(typeof acquireVsCodeApi>"u")){try{this._vscodeApi=acquireVsCodeApi()}catch{console.warn("VS Code API already acquired or unavailable");return}this._messageHandler=e=>{let t=e.data;if(!(!t||!t.type))switch(t.type){case"updateStatus":this._emit(f.STATUS_UPDATE,t.data);break;case"updateTasks":this._emit(f.TASK_UPDATED,t.data);break;case"taskCreated":this._emit(f.TASK_CREATED,t.data);break;case"taskDeleted":this._emit(f.TASK_DELETED,t.data);break;case"projectCreated":this._emit(f.PROJECT_CREATED,t.data);break;case"projectUpdated":this._emit(f.PROJECT_UPDATED,t.data);break;case"agentUpdate":this._emit(f.AGENT_UPDATE,t.data);break;case"logMessage":this._emit(f.LOG_MESSAGE,t.data);break;case"memoryUpdate":this._emit(f.MEMORY_UPDATE,t.data);break;case"connected":this._connected=!0,this._emit(f.CONNECTED,t.data);break;case"disconnected":this._connected=!1,this._emit(f.DISCONNECTED,t.data);break;case"error":this._emit(f.ERROR,t.data);break;case"setPollMode":this.setPollMode(t.data.mode);break;default:this._emit(`api:${t.type}`,t.data)}},window.addEventListener("message",this._messageHandler)}}get isVSCode(){return this._context==="vscode"}postToVSCode(e,t={}){this._vscodeApi&&this._vscodeApi.postMessage({type:e,data:t})}requestRefresh(){this.postToVSCode("requestRefresh")}notifyVSCode(e,t={}){this.postToVSCode("userAction",{action:e,...t})}get baseUrl(){return this.config.baseUrl}set baseUrl(e){this.config.baseUrl=e,this.config.wsUrl=e.replace(/^http/,"ws")+"/ws"}get isConnected(){return this._connected}async connect(){if(this._intentionalClose=!1,!(this._ws&&this._ws.readyState===WebSocket.OPEN))return new Promise((e,t)=>{try{this._ws=new WebSocket(this.config.wsUrl),this._ws.onopen=()=>{this._connected=!0,this._reconnectAttempts=0,this._emit(f.CONNECTED),e()},this._ws.onclose=()=>{this._connected=!1,this._emit(f.DISCONNECTED),this._intentionalClose||this._scheduleReconnect()},this._ws.onerror=i=>{this._emit(f.ERROR,{error:i}),t(i)},this._ws.onmessage=i=>{try{let a=JSON.parse(i.data);this._handleMessage(a)}catch(a){console.error("Failed to parse WebSocket message:",a)}}}catch(i){t(i)}})}disconnect(){this._intentionalClose=!0,this._ws&&(this._ws.close(),this._ws=null),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._reconnectTimeout&&(clearTimeout(this._reconnectTimeout),this._reconnectTimeout=null),this._connected=!1,this._cleanupGlobalListeners()}_cleanupGlobalListeners(){this._visibilityChangeHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this._visibilityChangeHandler),this._visibilityChangeHandler=null),this._messageHandler&&typeof window<"u"&&(window.removeEventListener("message",this._messageHandler),this._messageHandler=null)}destroy(){this.disconnect()}_scheduleReconnect(){if(this._reconnectTimeout)return;if(this._reconnectAttempts>=this._maxReconnectAttempts){console.warn("WebSocket max reconnect attempts reached, giving up"),this._emit(f.ERROR,{error:"Max reconnect attempts reached"});return}let e=Math.min(this.config.retryDelay*Math.pow(2,this._reconnectAttempts),3e4);this._reconnectAttempts++,this._reconnectTimeout=setTimeout(()=>{this._reconnectTimeout=null,this.connect().catch(()=>{})},e)}_handleMessage(e){if(e.type==="ping"){this._ws&&this._ws.readyState===WebSocket.OPEN&&this._ws.send(JSON.stringify({type:"pong"}));return}let i={connected:f.CONNECTED,status_update:f.STATUS_UPDATE,task_created:f.TASK_CREATED,task_updated:f.TASK_UPDATED,task_deleted:f.TASK_DELETED,task_moved:f.TASK_UPDATED,project_created:f.PROJECT_CREATED,project_updated:f.PROJECT_UPDATED,agent_update:f.AGENT_UPDATE,log:f.LOG_MESSAGE}[e.type]||`api:${e.type}`;this._emit(i,e.data)}_emit(e,t={}){this.dispatchEvent(new CustomEvent(e,{detail:t}))}async _request(e,t={}){let i=`${this.config.baseUrl}${e}`,a=new AbortController,s=t&&typeof t.timeout=="number"?t.timeout:this.config.timeout,r=setTimeout(()=>a.abort(),s);try{let o=await fetch(i,{...t,signal:a.signal,credentials:"include",headers:{"Content-Type":"application/json",...t.headers}});if(clearTimeout(r),!o.ok){let n=await o.text().catch(()=>""),l=o.statusText||`HTTP ${o.status}`;if(n)try{let c=JSON.parse(n);l=c.detail||c.error||c.message||l}catch{l=n.length>200?n.slice(0,200)+"...":n}throw new Error(l)}return o.status===204?null:await o.json()}catch(o){throw clearTimeout(r),o.name==="AbortError"?new Error("Request timeout"):o}}async _get(e,t=!1){if(t&&this._cache.has(e)){let a=this._cache.get(e);if(Date.now()-a.timestamp<this._cacheTimeout)return a.data}let i=await this._request(e);return t&&this._cache.set(e,{data:i,timestamp:Date.now()}),i}async _post(e,t,i={}){return this._request(e,{method:"POST",body:JSON.stringify(t),...i})}async _put(e,t){return this._request(e,{method:"PUT",body:JSON.stringify(t)})}async _delete(e){return this._request(e,{method:"DELETE"})}async get(e){return this._get(e)}async getStatus(){return this._get("/api/status")}async healthCheck(){return this._get("/health")}async listProjects(e=null){let t=e?`?status=${e}`:"";return this._get(`/api/projects${t}`)}async getProject(e){return this._get(`/api/projects/${e}`)}async createProject(e){return this._post("/api/projects",e)}async updateProject(e,t){return this._put(`/api/projects/${e}`,t)}async deleteProject(e){return this._delete(`/api/projects/${e}`)}async listTasks(e={}){let t=new URLSearchParams;e.projectId&&t.append("project_id",e.projectId),e.status&&t.append("status",e.status),e.priority&&t.append("priority",e.priority);let i=t.toString()?`?${t}`:"";return this._get(`/api/tasks${i}`)}async getTask(e){return this._get(`/api/tasks/${e}`)}async createTask(e){return this._post("/api/tasks",e)}async updateTask(e,t){return this._put(`/api/tasks/${e}`,t)}async moveTask(e,t,i){return this._post(`/api/tasks/${e}/move`,{status:t,position:i})}async deleteTask(e){return this._delete(`/api/tasks/${e}`)}async getMemorySummary(){return this._get("/api/memory/summary",!0)}async getMemoryIndex(){return this._get("/api/memory/index",!0)}async getMemoryTimeline(){return this._get("/api/memory/timeline")}async listEpisodes(e={}){let t=new URLSearchParams(e).toString();return this._get(`/api/memory/episodes${t?"?"+t:""}`)}async getEpisode(e){return this._get(`/api/memory/episodes/${e}`)}async listPatterns(e={}){let t=new URLSearchParams(e).toString();return this._get(`/api/memory/patterns${t?"?"+t:""}`)}async getPattern(e){return this._get(`/api/memory/patterns/${e}`)}async listSkills(){return this._get("/api/memory/skills")}async getSkill(e){return this._get(`/api/memory/skills/${e}`)}async retrieveMemories(e,t=null,i=5){return this._post("/api/memory/retrieve",{query:e,taskType:t,topK:i},{timeout:3e4})}async consolidateMemory(e=24){return this._post("/api/memory/consolidate",{sinceHours:e},{timeout:12e4})}async getTokenEconomics(){return this._get("/api/memory/economics")}async searchMemory(e,t="all",i=20){let a=new URLSearchParams({q:e,collection:t,limit:String(i)});return this._get(`/api/memory/search?${a}`)}async getMemoryStats(){return this._get("/api/memory/stats",!0)}async listRegisteredProjects(e=!1){return this._get(`/api/registry/projects?include_inactive=${e}`)}async registerProject(e,t=null,i=null){return this._post("/api/registry/projects",{path:e,name:t,alias:i})}async discoverProjects(e=3){return this._get(`/api/registry/discover?max_depth=${e}`)}async syncRegistry(){return this._post("/api/registry/sync",{},{timeout:45e3})}async getCrossProjectTasks(e=null){let t=e?`?project_ids=${e.join(",")}`:"";return this._get(`/api/registry/tasks${t}`)}async getLearningMetrics(e={}){let t=new URLSearchParams;e.timeRange&&t.append("timeRange",e.timeRange),e.signalType&&t.append("signalType",e.signalType),e.source&&t.append("source",e.source);let i=t.toString()?`?${t}`:"";return this._get(`/api/learning/metrics${i}`)}async getLearningTrends(e={}){let t=new URLSearchParams;e.timeRange&&t.append("timeRange",e.timeRange),e.signalType&&t.append("signalType",e.signalType),e.source&&t.append("source",e.source);let i=t.toString()?`?${t}`:"";return this._get(`/api/learning/trends${i}`)}async getLearningSignals(e={}){let t=new URLSearchParams;e.timeRange&&t.append("timeRange",e.timeRange),e.signalType&&t.append("signalType",e.signalType),e.source&&t.append("source",e.source),e.limit&&t.append("limit",String(e.limit)),e.offset&&t.append("offset",String(e.offset));let i=t.toString()?`?${t}`:"";return this._get(`/api/learning/signals${i}`)}async getLatestAggregation(){return this._get("/api/learning/aggregation")}async triggerAggregation(e={}){return this._post("/api/learning/aggregate",e,{timeout:6e4})}async getAggregatedPreferences(e=20){return this._get(`/api/learning/preferences?limit=${e}`)}async getAggregatedErrors(e=20){return this._get(`/api/learning/errors?limit=${e}`)}async getAggregatedSuccessPatterns(e=20){return this._get(`/api/learning/success?limit=${e}`)}async getToolEfficiency(e=20){return this._get(`/api/learning/tools?limit=${e}`)}async getCost(){return this._get("/api/cost")}async getPricing(){return this._get("/api/pricing")}async getCouncilState(){return this._get("/api/council/state")}async getCouncilVerdicts(e=20){return this._get(`/api/council/verdicts?limit=${e}`)}async getCouncilConvergence(){return this._get("/api/council/convergence")}async getCouncilReport(){return this._get("/api/council/report")}async forceCouncilReview(){return this._post("/api/council/force-review",{})}async getContext(){return this._get("/api/context")}async getNotifications(e,t){let i=new URLSearchParams;e&&i.set("severity",e),t&&i.set("unread_only","true");let a=i.toString();return this._get("/api/notifications"+(a?"?"+a:""))}async getNotificationTriggers(){return this._get("/api/notifications/triggers")}async updateNotificationTriggers(e){return this._put("/api/notifications/triggers",{triggers:e})}async acknowledgeNotification(e){return this._post("/api/notifications/"+encodeURIComponent(e)+"/acknowledge",{})}async startSession(e,t={}){let i={provider:t.provider||"claude",parallel:!!t.parallel};return t.prdPath?i.prd_path=t.prdPath:i.prd_text=e||"",t.model&&(i.model=t.model),t.advisorModel&&(i.advisor_model=t.advisorModel),this._post("/api/control/start",i)}async pauseSession(){return this._post("/api/control/pause",{})}async resumeSession(){return this._post("/api/control/resume",{})}async stopSession(){return this._post("/api/control/stop",{})}async getSessionModel(){return this._get("/api/session/model")}async setSessionModel(e){return this._post("/api/session/model",{model:e||null})}async getLogs(e=100){return this._get(`/api/logs?lines=${e}`)}async getChecklist(){return this._get("/api/checklist")}async getChecklistSummary(){return this._get("/api/checklist/summary")}async getPrdObservations(){let e=await fetch(`${this.baseUrl}/api/prd-observations`,{credentials:"include"});if(!e.ok)throw new Error(`HTTP ${e.status}`);return e.text()}async getChecklistWaivers(){return this._get("/api/checklist/waivers")}async addChecklistWaiver(e,t,i="dashboard"){return this._post("/api/checklist/waivers",{item_id:e,reason:t,waived_by:i})}async removeChecklistWaiver(e){return this._delete(`/api/checklist/waivers/${encodeURIComponent(e)}`)}async getCouncilGate(){return this._get("/api/council/gate")}async getAppRunnerStatus(){return this._get("/api/app-runner/status")}async getAppRunnerLogs(e=100){return this._get(`/api/app-runner/logs?lines=${e}`)}async getAppRunnerErrors(e=50){return this._get(`/api/app-runner/errors?lines=${e}`)}async restartApp(){return this._post("/api/control/app-restart",{})}async stopApp(){return this._post("/api/control/app-stop",{})}async getPlaywrightResults(){return this._get("/api/playwright/results")}async getPlaywrightScreenshot(){return this._get("/api/playwright/screenshot")}startPolling(e,t=null){if(this._pollInterval)return;this._pollCallback=e;let i=async()=>{try{let s=await this.getStatus();this._connected=!0,this._pollCallback&&this._pollCallback(s),this._emit(f.STATUS_UPDATE,s),this._vscodeApi&&this.postToVSCode("pollSuccess",{timestamp:Date.now()})}catch(s){this._connected=!1,this._emit(f.ERROR,{error:s}),this._vscodeApi&&this.postToVSCode("pollError",{error:s.message})}};i();let a=t||this._currentPollInterval||this.config.pollInterval;this._pollInterval=setInterval(i,a)}stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}};S(M,"_instances",new Map);var q=M;function et(d={}){return new q(d)}function g(d={}){return q.getInstance(d)}var Ie="loki-state-change",Pe={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}},L=class L extends EventTarget{static getInstance(){return L._instance||(L._instance=new L),L._instance}constructor(){super(),this._state=this._loadState(),this._subscribers=new Map,this._batchUpdates=[],this._batchTimeout=null}_loadState(){try{let e=localStorage.getItem(L.STORAGE_KEY);if(e){let t=JSON.parse(e);return this._mergeState(Pe,t)}}catch(e){console.warn("Failed to load state from localStorage:",e)}return{...Pe}}_mergeState(e,t){let i={...e};for(let a of Object.keys(t))a in e&&typeof e[a]=="object"&&!Array.isArray(e[a])?i[a]=this._mergeState(e[a],t[a]):i[a]=t[a];return i}_saveState(){try{let e={ui:this._state.ui,localTasks:this._state.localTasks,preferences:this._state.preferences};localStorage.setItem(L.STORAGE_KEY,JSON.stringify(e))}catch(e){console.warn("Failed to save state to localStorage:",e)}}get(e=null){if(!e)return{...this._state};let t=e.split("."),i=this._state;for(let a of t){if(i==null)return;i=i[a]}return i}set(e,t,i=!0){let a=e.split("."),s=a.pop(),r=this._state;for(let n of a)n in r||(r[n]={}),r=r[n];let o=r[s];r[s]=t,i&&this._saveState(),this._notifyChange(e,t,o)}update(e,t=!0){let i=[];for(let[a,s]of Object.entries(e)){let r=this.get(a);this.set(a,s,!1),i.push({path:a,value:s,oldValue:r})}t&&this._saveState();for(let a of i)this._notifyChange(a.path,a.value,a.oldValue)}_notifyChange(e,t,i){this.dispatchEvent(new CustomEvent(Ie,{detail:{path:e,value:t,oldValue:i}}));let a=this._subscribers.get(e)||[];for(let r of a)try{r(t,i,e)}catch(o){console.error("State subscriber error:",o)}let s=e.split(".");for(;s.length>1;){s.pop();let r=s.join("."),o=this._subscribers.get(r)||[];for(let n of o)try{n(this.get(r),null,r)}catch(l){console.error("State subscriber error:",l)}}}subscribe(e,t){return this._subscribers.has(e)||this._subscribers.set(e,[]),this._subscribers.get(e).push(t),()=>{let i=this._subscribers.get(e),a=i.indexOf(t);a>-1&&i.splice(a,1)}}reset(e=null){if(e){let t=e.split("."),i=Pe;for(let a of t)i=i?.[a];this.set(e,i)}else this._state={...Pe},this._saveState(),this.dispatchEvent(new CustomEvent(Ie,{detail:{path:null,value:this._state,oldValue:null}}))}addLocalTask(e){let t=this.get("localTasks")||[],i={id:`local-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,createdAt:new Date().toISOString(),status:"pending",...e};return this.set("localTasks",[...t,i]),i}updateLocalTask(e,t){let i=this.get("localTasks")||[],a=i.findIndex(r=>r.id===e);if(a===-1)return null;let s={...i[a],...t,updatedAt:new Date().toISOString()};return i[a]=s,this.set("localTasks",[...i]),s}deleteLocalTask(e){let t=this.get("localTasks")||[];this.set("localTasks",t.filter(i=>i.id!==e))}moveLocalTask(e,t,i=null){let s=(this.get("localTasks")||[]).find(r=>r.id===e);return s?this.updateLocalTask(e,{status:t,position:i??s.position}):null}updateSession(e){this.update(Object.fromEntries(Object.entries(e).map(([t,i])=>[`session.${t}`,i])),!1)}updateCache(e){this.update({"cache.projects":e.projects??this.get("cache.projects"),"cache.tasks":e.tasks??this.get("cache.tasks"),"cache.agents":e.agents??this.get("cache.agents"),"cache.memory":e.memory??this.get("cache.memory"),"cache.lastFetch":new Date().toISOString()},!1)}getMergedTasks(){let e=this.get("cache.tasks")||[],i=(this.get("localTasks")||[]).map(a=>({...a,isLocal:!0}));return[...e,...i]}getTasksByStatus(e){return this.getMergedTasks().filter(t=>t.status===e)}};S(L,"STORAGE_KEY","loki-dashboard-state"),S(L,"_instance",null);var W=L;function N(){return W.getInstance()}function tt(d){let e=N();return{get:()=>e.get(d),set:t=>e.set(d,t),subscribe:t=>e.subscribe(d,t)}}function Be(d){return String(d??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function C(d){if(d==null||d==="")return"";let e=String(d).replace(/\r\n/g,`
|
|
2355
|
+
`}getAriaPattern(e){return Me[e]||{}}applyAriaPattern(e,t){let i=this.getAriaPattern(t);for(let[a,s]of Object.entries(i))if(a==="role")e.setAttribute("role",s);else{let r=a.replace(/([A-Z])/g,"-$1").toLowerCase();e.setAttribute(r,s)}}render(){}};var F={realtime:1e3,normal:2e3,background:5e3,offline:1e4},Xe={vscode:F.normal,browser:F.realtime,cli:F.background},Ze={baseUrl:typeof window<"u"?window.location.origin:"http://localhost:57374",wsUrl:typeof window<"u"?`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/ws`:"ws://localhost:57374/ws",pollInterval:2e3,timeout:1e4,retryAttempts:3,retryDelay:1e3},f={CONNECTED:"api:connected",DISCONNECTED:"api:disconnected",ERROR:"api:error",STATUS_UPDATE:"api:status-update",TASK_CREATED:"api:task-created",TASK_UPDATED:"api:task-updated",TASK_DELETED:"api:task-deleted",PROJECT_CREATED:"api:project-created",PROJECT_UPDATED:"api:project-updated",AGENT_UPDATE:"api:agent-update",LOG_MESSAGE:"api:log-message",MEMORY_UPDATE:"api:memory-update",CHECKLIST_UPDATE:"api:checklist-update"},M=class M extends EventTarget{static getInstance(e={}){let t=e.baseUrl||Ze.baseUrl;return M._instances.has(t)||M._instances.set(t,new M(e)),M._instances.get(t)}static clearInstances(){M._instances.forEach(e=>e.disconnect()),M._instances.clear()}constructor(e={}){super(),this.config={...Ze,...e},this._ws=null,this._connected=!1,this._intentionalClose=!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=Xe[this._context]||F.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 F}_setupAdaptivePolling(){typeof document>"u"||(this._visibilityChangeHandler=()=>{document.hidden?this._setPollInterval(F.background):this._setPollInterval(Xe[this._context]||F.normal)},document.addEventListener("visibilitychange",this._visibilityChangeHandler))}_setPollInterval(e){this._currentPollInterval=e,this._pollInterval&&(this.stopPolling(),this.startPolling(null,e))}setPollMode(e){let t=F[e];t&&this._setPollInterval(t)}_setupVSCodeBridge(){if(!(typeof acquireVsCodeApi>"u")){try{this._vscodeApi=acquireVsCodeApi()}catch{console.warn("VS Code API already acquired or unavailable");return}this._messageHandler=e=>{let t=e.data;if(!(!t||!t.type))switch(t.type){case"updateStatus":this._emit(f.STATUS_UPDATE,t.data);break;case"updateTasks":this._emit(f.TASK_UPDATED,t.data);break;case"taskCreated":this._emit(f.TASK_CREATED,t.data);break;case"taskDeleted":this._emit(f.TASK_DELETED,t.data);break;case"projectCreated":this._emit(f.PROJECT_CREATED,t.data);break;case"projectUpdated":this._emit(f.PROJECT_UPDATED,t.data);break;case"agentUpdate":this._emit(f.AGENT_UPDATE,t.data);break;case"logMessage":this._emit(f.LOG_MESSAGE,t.data);break;case"memoryUpdate":this._emit(f.MEMORY_UPDATE,t.data);break;case"connected":this._connected=!0,this._emit(f.CONNECTED,t.data);break;case"disconnected":this._connected=!1,this._emit(f.DISCONNECTED,t.data);break;case"error":this._emit(f.ERROR,t.data);break;case"setPollMode":this.setPollMode(t.data.mode);break;default:this._emit(`api:${t.type}`,t.data)}},window.addEventListener("message",this._messageHandler)}}get isVSCode(){return this._context==="vscode"}postToVSCode(e,t={}){this._vscodeApi&&this._vscodeApi.postMessage({type:e,data:t})}requestRefresh(){this.postToVSCode("requestRefresh")}notifyVSCode(e,t={}){this.postToVSCode("userAction",{action:e,...t})}get baseUrl(){return this.config.baseUrl}set baseUrl(e){this.config.baseUrl=e,this.config.wsUrl=e.replace(/^http/,"ws")+"/ws"}get isConnected(){return this._connected}async connect(){if(this._intentionalClose=!1,!(this._ws&&this._ws.readyState===WebSocket.OPEN))return new Promise((e,t)=>{try{this._ws=new WebSocket(this.config.wsUrl),this._ws.onopen=()=>{this._connected=!0,this._reconnectAttempts=0,this._emit(f.CONNECTED),e()},this._ws.onclose=()=>{this._connected=!1,this._emit(f.DISCONNECTED),this._intentionalClose||this._scheduleReconnect()},this._ws.onerror=i=>{this._emit(f.ERROR,{error:i}),t(i)},this._ws.onmessage=i=>{try{let a=JSON.parse(i.data);this._handleMessage(a)}catch(a){console.error("Failed to parse WebSocket message:",a)}}}catch(i){t(i)}})}disconnect(){this._intentionalClose=!0,this._ws&&(this._ws.close(),this._ws=null),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null),this._reconnectTimeout&&(clearTimeout(this._reconnectTimeout),this._reconnectTimeout=null),this._connected=!1,this._cleanupGlobalListeners()}_cleanupGlobalListeners(){this._visibilityChangeHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this._visibilityChangeHandler),this._visibilityChangeHandler=null),this._messageHandler&&typeof window<"u"&&(window.removeEventListener("message",this._messageHandler),this._messageHandler=null)}destroy(){this.disconnect()}_scheduleReconnect(){if(this._reconnectTimeout)return;if(this._reconnectAttempts>=this._maxReconnectAttempts){console.warn("WebSocket max reconnect attempts reached, giving up"),this._emit(f.ERROR,{error:"Max reconnect attempts reached"});return}let e=Math.min(this.config.retryDelay*Math.pow(2,this._reconnectAttempts),3e4);this._reconnectAttempts++,this._reconnectTimeout=setTimeout(()=>{this._reconnectTimeout=null,this.connect().catch(()=>{})},e)}_handleMessage(e){if(e.type==="ping"){this._ws&&this._ws.readyState===WebSocket.OPEN&&this._ws.send(JSON.stringify({type:"pong"}));return}let i={connected:f.CONNECTED,status_update:f.STATUS_UPDATE,task_created:f.TASK_CREATED,task_updated:f.TASK_UPDATED,task_deleted:f.TASK_DELETED,task_moved:f.TASK_UPDATED,project_created:f.PROJECT_CREATED,project_updated:f.PROJECT_UPDATED,agent_update:f.AGENT_UPDATE,log:f.LOG_MESSAGE}[e.type]||`api:${e.type}`;this._emit(i,e.data)}_emit(e,t={}){this.dispatchEvent(new CustomEvent(e,{detail:t}))}async _request(e,t={}){let i=`${this.config.baseUrl}${e}`,a=new AbortController,s=t&&typeof t.timeout=="number"?t.timeout:this.config.timeout,r=setTimeout(()=>a.abort(),s);try{let o=await fetch(i,{...t,signal:a.signal,credentials:"include",headers:{"Content-Type":"application/json",...t.headers}});if(clearTimeout(r),!o.ok){let n=await o.text().catch(()=>""),l=o.statusText||`HTTP ${o.status}`;if(n)try{let c=JSON.parse(n);l=c.detail||c.error||c.message||l}catch{l=n.length>200?n.slice(0,200)+"...":n}throw new Error(l)}return o.status===204?null:await o.json()}catch(o){throw clearTimeout(r),o.name==="AbortError"?new Error("Request timeout"):o}}async _get(e,t=!1){if(t&&this._cache.has(e)){let a=this._cache.get(e);if(Date.now()-a.timestamp<this._cacheTimeout)return a.data}let i=await this._request(e);return t&&this._cache.set(e,{data:i,timestamp:Date.now()}),i}async _post(e,t,i={}){return this._request(e,{method:"POST",body:JSON.stringify(t),...i})}async _put(e,t){return this._request(e,{method:"PUT",body:JSON.stringify(t)})}async _delete(e){return this._request(e,{method:"DELETE"})}async get(e){return this._get(e)}async getStatus(){return this._get("/api/status")}async healthCheck(){return this._get("/health")}async listProjects(e=null){let t=e?`?status=${e}`:"";return this._get(`/api/projects${t}`)}async getProject(e){return this._get(`/api/projects/${e}`)}async createProject(e){return this._post("/api/projects",e)}async updateProject(e,t){return this._put(`/api/projects/${e}`,t)}async deleteProject(e){return this._delete(`/api/projects/${e}`)}async listTasks(e={}){let t=new URLSearchParams;e.projectId&&t.append("project_id",e.projectId),e.status&&t.append("status",e.status),e.priority&&t.append("priority",e.priority);let i=t.toString()?`?${t}`:"";return this._get(`/api/tasks${i}`)}async getTask(e){return this._get(`/api/tasks/${e}`)}async createTask(e){return this._post("/api/tasks",e)}async updateTask(e,t){return this._put(`/api/tasks/${e}`,t)}async moveTask(e,t,i){return this._post(`/api/tasks/${e}/move`,{status:t,position:i})}async deleteTask(e){return this._delete(`/api/tasks/${e}`)}async getMemorySummary(){return this._get("/api/memory/summary",!0)}async getMemoryIndex(){return this._get("/api/memory/index",!0)}async getMemoryTimeline(){return this._get("/api/memory/timeline")}async listEpisodes(e={}){let t=new URLSearchParams(e).toString();return this._get(`/api/memory/episodes${t?"?"+t:""}`)}async getEpisode(e){return this._get(`/api/memory/episodes/${e}`)}async listPatterns(e={}){let t=new URLSearchParams(e).toString();return this._get(`/api/memory/patterns${t?"?"+t:""}`)}async getPattern(e){return this._get(`/api/memory/patterns/${e}`)}async listSkills(){return this._get("/api/memory/skills")}async getSkill(e){return this._get(`/api/memory/skills/${e}`)}async retrieveMemories(e,t=null,i=5){return this._post("/api/memory/retrieve",{query:e,taskType:t,topK:i},{timeout:3e4})}async consolidateMemory(e=24){return this._post("/api/memory/consolidate",{sinceHours:e},{timeout:12e4})}async getTokenEconomics(){return this._get("/api/memory/economics")}async searchMemory(e,t="all",i=20){let a=new URLSearchParams({q:e,collection:t,limit:String(i)});return this._get(`/api/memory/search?${a}`)}async getMemoryStats(){return this._get("/api/memory/stats",!0)}async listRegisteredProjects(e=!1){return this._get(`/api/registry/projects?include_inactive=${e}`)}async registerProject(e,t=null,i=null){return this._post("/api/registry/projects",{path:e,name:t,alias:i})}async discoverProjects(e=3){return this._get(`/api/registry/discover?max_depth=${e}`)}async syncRegistry(){return this._post("/api/registry/sync",{},{timeout:45e3})}async getCrossProjectTasks(e=null){let t=e?`?project_ids=${e.join(",")}`:"";return this._get(`/api/registry/tasks${t}`)}async getLearningMetrics(e={}){let t=new URLSearchParams;e.timeRange&&t.append("timeRange",e.timeRange),e.signalType&&t.append("signalType",e.signalType),e.source&&t.append("source",e.source);let i=t.toString()?`?${t}`:"";return this._get(`/api/learning/metrics${i}`)}async getLearningTrends(e={}){let t=new URLSearchParams;e.timeRange&&t.append("timeRange",e.timeRange),e.signalType&&t.append("signalType",e.signalType),e.source&&t.append("source",e.source);let i=t.toString()?`?${t}`:"";return this._get(`/api/learning/trends${i}`)}async getLearningSignals(e={}){let t=new URLSearchParams;e.timeRange&&t.append("timeRange",e.timeRange),e.signalType&&t.append("signalType",e.signalType),e.source&&t.append("source",e.source),e.limit&&t.append("limit",String(e.limit)),e.offset&&t.append("offset",String(e.offset));let i=t.toString()?`?${t}`:"";return this._get(`/api/learning/signals${i}`)}async getLatestAggregation(){return this._get("/api/learning/aggregation")}async triggerAggregation(e={}){return this._post("/api/learning/aggregate",e,{timeout:6e4})}async getAggregatedPreferences(e=20){return this._get(`/api/learning/preferences?limit=${e}`)}async getAggregatedErrors(e=20){return this._get(`/api/learning/errors?limit=${e}`)}async getAggregatedSuccessPatterns(e=20){return this._get(`/api/learning/success?limit=${e}`)}async getToolEfficiency(e=20){return this._get(`/api/learning/tools?limit=${e}`)}async getCost(){return this._get("/api/cost")}async getPricing(){return this._get("/api/pricing")}async getCouncilState(){return this._get("/api/council/state")}async getCouncilVerdicts(e=20){return this._get(`/api/council/verdicts?limit=${e}`)}async getCouncilConvergence(){return this._get("/api/council/convergence")}async getCouncilReport(){return this._get("/api/council/report")}async forceCouncilReview(){return this._post("/api/council/force-review",{})}async getContext(){return this._get("/api/context")}async getNotifications(e,t){let i=new URLSearchParams;e&&i.set("severity",e),t&&i.set("unread_only","true");let a=i.toString();return this._get("/api/notifications"+(a?"?"+a:""))}async getNotificationTriggers(){return this._get("/api/notifications/triggers")}async updateNotificationTriggers(e){return this._put("/api/notifications/triggers",{triggers:e})}async acknowledgeNotification(e){return this._post("/api/notifications/"+encodeURIComponent(e)+"/acknowledge",{})}async startSession(e,t={}){let i={provider:t.provider||"claude",parallel:!!t.parallel};return t.prdPath?i.prd_path=t.prdPath:i.prd_text=e||"",t.model&&(i.model=t.model),t.advisorModel&&(i.advisor_model=t.advisorModel),this._post("/api/control/start",i)}async pauseSession(){return this._post("/api/control/pause",{})}async resumeSession(){return this._post("/api/control/resume",{})}async stopSession(){return this._post("/api/control/stop",{})}async getSessionModel(){return this._get("/api/session/model")}async setSessionModel(e){return this._post("/api/session/model",{model:e||null})}async getLogs(e=100){return this._get(`/api/logs?lines=${e}`)}async getChecklist(){return this._get("/api/checklist")}async getChecklistSummary(){return this._get("/api/checklist/summary")}async getPrdObservations(){let e=await fetch(`${this.baseUrl}/api/prd-observations`,{credentials:"include"});if(!e.ok)throw new Error(`HTTP ${e.status}`);return e.text()}async getChecklistWaivers(){return this._get("/api/checklist/waivers")}async addChecklistWaiver(e,t,i="dashboard"){return this._post("/api/checklist/waivers",{item_id:e,reason:t,waived_by:i})}async removeChecklistWaiver(e){return this._delete(`/api/checklist/waivers/${encodeURIComponent(e)}`)}async getCouncilGate(){return this._get("/api/council/gate")}async getAppRunnerStatus(){return this._get("/api/app-runner/status")}async getAppRunnerLogs(e=100){return this._get(`/api/app-runner/logs?lines=${e}`)}async getAppRunnerErrors(e=50){return this._get(`/api/app-runner/errors?lines=${e}`)}async restartApp(){return this._post("/api/control/app-restart",{})}async stopApp(){return this._post("/api/control/app-stop",{})}async getPlaywrightResults(){return this._get("/api/playwright/results")}async getPlaywrightScreenshot(){return this._get("/api/playwright/screenshot")}startPolling(e,t=null){if(this._pollInterval)return;this._pollCallback=e;let i=async()=>{try{let s=await this.getStatus();this._connected=!0,this._pollCallback&&this._pollCallback(s),this._emit(f.STATUS_UPDATE,s),this._vscodeApi&&this.postToVSCode("pollSuccess",{timestamp:Date.now()})}catch(s){this._connected=!1,this._emit(f.ERROR,{error:s}),this._vscodeApi&&this.postToVSCode("pollError",{error:s.message})}};i();let a=t||this._currentPollInterval||this.config.pollInterval;this._pollInterval=setInterval(i,a)}stopPolling(){this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}};S(M,"_instances",new Map);var q=M;function et(d={}){return new q(d)}function g(d={}){return q.getInstance(d)}var Ie="loki-state-change",Pe={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}},L=class L extends EventTarget{static getInstance(){return L._instance||(L._instance=new L),L._instance}constructor(){super(),this._state=this._loadState(),this._subscribers=new Map,this._batchUpdates=[],this._batchTimeout=null}_loadState(){try{let e=localStorage.getItem(L.STORAGE_KEY);if(e){let t=JSON.parse(e);return this._mergeState(Pe,t)}}catch(e){console.warn("Failed to load state from localStorage:",e)}return{...Pe}}_mergeState(e,t){let i={...e};for(let a of Object.keys(t))a in e&&typeof e[a]=="object"&&!Array.isArray(e[a])?i[a]=this._mergeState(e[a],t[a]):i[a]=t[a];return i}_saveState(){try{let e={ui:this._state.ui,localTasks:this._state.localTasks,preferences:this._state.preferences};localStorage.setItem(L.STORAGE_KEY,JSON.stringify(e))}catch(e){console.warn("Failed to save state to localStorage:",e)}}get(e=null){if(!e)return{...this._state};let t=e.split("."),i=this._state;for(let a of t){if(i==null)return;i=i[a]}return i}set(e,t,i=!0){let a=e.split("."),s=a.pop(),r=this._state;for(let n of a)n in r||(r[n]={}),r=r[n];let o=r[s];r[s]=t,i&&this._saveState(),this._notifyChange(e,t,o)}update(e,t=!0){let i=[];for(let[a,s]of Object.entries(e)){let r=this.get(a);this.set(a,s,!1),i.push({path:a,value:s,oldValue:r})}t&&this._saveState();for(let a of i)this._notifyChange(a.path,a.value,a.oldValue)}_notifyChange(e,t,i){this.dispatchEvent(new CustomEvent(Ie,{detail:{path:e,value:t,oldValue:i}}));let a=this._subscribers.get(e)||[];for(let r of a)try{r(t,i,e)}catch(o){console.error("State subscriber error:",o)}let s=e.split(".");for(;s.length>1;){s.pop();let r=s.join("."),o=this._subscribers.get(r)||[];for(let n of o)try{n(this.get(r),null,r)}catch(l){console.error("State subscriber error:",l)}}}subscribe(e,t){return this._subscribers.has(e)||this._subscribers.set(e,[]),this._subscribers.get(e).push(t),()=>{let i=this._subscribers.get(e),a=i.indexOf(t);a>-1&&i.splice(a,1)}}reset(e=null){if(e){let t=e.split("."),i=Pe;for(let a of t)i=i?.[a];this.set(e,i)}else this._state={...Pe},this._saveState(),this.dispatchEvent(new CustomEvent(Ie,{detail:{path:null,value:this._state,oldValue:null}}))}addLocalTask(e){let t=this.get("localTasks")||[],i={id:`local-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,createdAt:new Date().toISOString(),status:"pending",...e};return this.set("localTasks",[...t,i]),i}updateLocalTask(e,t){let i=this.get("localTasks")||[],a=i.findIndex(r=>r.id===e);if(a===-1)return null;let s={...i[a],...t,updatedAt:new Date().toISOString()};return i[a]=s,this.set("localTasks",[...i]),s}deleteLocalTask(e){let t=this.get("localTasks")||[];this.set("localTasks",t.filter(i=>i.id!==e))}moveLocalTask(e,t,i=null){let s=(this.get("localTasks")||[]).find(r=>r.id===e);return s?this.updateLocalTask(e,{status:t,position:i??s.position}):null}updateSession(e){this.update(Object.fromEntries(Object.entries(e).map(([t,i])=>[`session.${t}`,i])),!1)}updateCache(e){this.update({"cache.projects":e.projects??this.get("cache.projects"),"cache.tasks":e.tasks??this.get("cache.tasks"),"cache.agents":e.agents??this.get("cache.agents"),"cache.memory":e.memory??this.get("cache.memory"),"cache.lastFetch":new Date().toISOString()},!1)}getMergedTasks(){let e=this.get("cache.tasks")||[],i=(this.get("localTasks")||[]).map(a=>({...a,isLocal:!0}));return[...e,...i]}getTasksByStatus(e){return this.getMergedTasks().filter(t=>t.status===e)}};S(L,"STORAGE_KEY","loki-dashboard-state"),S(L,"_instance",null);var W=L;function N(){return W.getInstance()}function tt(d){let e=N();return{get:()=>e.get(d),set:t=>e.set(d,t),subscribe:t=>e.subscribe(d,t)}}function Be(d){return String(d??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function C(d){if(d==null||d==="")return"";let e=String(d).replace(/\r\n/g,`
|
|
2356
2356
|
`),t=[];e=e.replace(/```[^\n]*\n([\s\S]*?)```/g,(u,m)=>{let h=t.length;return t.push(`<pre class="md-code"><code>${Be(m.replace(/\n$/,""))}</code></pre>`),`\0CODEBLOCK${h}\0`});let i=Be(e);i=i.replace(/`([^`\n]+)`/g,(u,m)=>`<code class="md-inline-code">${m}</code>`),i=i.replace(/\[([^\]\n]+)\]\(([^)\s]+)\)/g,(u,m,h)=>/^(https?:|mailto:|\/|#|\.)/.test(h)?`<a class="md-link" href="${h}" target="_blank" rel="noopener noreferrer">${m}</a>`:u);let a=i.split(`
|
|
2357
2357
|
`),s=[],r=[],o=[],n=()=>{r.length&&(s.push(`<p class="md-p">${r.join("<br>")}</p>`),r=[])},l=u=>{for(;o.length&&o[o.length-1].indent>=u;)s.push(`</${o.pop().tag}>`)},c=()=>{for(;o.length;)s.push(`</${o.pop().tag}>`)};for(let u of a){let m=u,h=m.trim(),k=h.match(/^CODEBLOCK(\d+)$/);if(k){n(),c(),s.push(t[Number(k[1])]);continue}if(h===""){n(),c();continue}let x=h.match(/^(#{1,6})\s+(.+)$/);if(x){n(),c();let R=Math.min(x[1].length+1,6);s.push(`<h${R} class="md-h${R}">${x[2]}</h${R}>`);continue}if(/^(-{3,}|\*{3,}|_{3,})$/.test(h)){n(),c(),s.push('<hr class="md-hr">');continue}let _=h.match(/^>\s?(.*)$/);if(_){n(),c(),s.push(`<blockquote class="md-quote">${_[1]}</blockquote>`);continue}let D=m.match(/^(\s*)/)[1].replace(/\t/g," ").length,J=h.match(/^([-*+])\s+(.+)$/),V=h.match(/^(\d+)[.)]\s+(.+)$/);if(J||V){n();let R=V?"ol":"ul",bt=J?J[2]:V[2];!o.length||D>o[o.length-1].indent?(s.push(`<${R} class="md-list">`),o.push({tag:R,indent:D})):(l(D+1),o.length||(s.push(`<${R} class="md-list">`),o.push({tag:R,indent:D}))),s.push(`<li>${bt}</li>`);continue}c(),r.push(m.trim())}n(),c();let p=s.join(`
|
|
2358
2358
|
`);return p=p.replace(/\*\*([^*\n]+)\*\*/g,"<strong>$1</strong>"),p=p.replace(/__([^_\n]+)__/g,"<strong>$1</strong>"),p=p.replace(/(^|[^*])\*([^*\n]+)\*/g,"$1<em>$2</em>"),p}var z=`
|
|
@@ -2371,7 +2371,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
2371
2371
|
.md-body .md-link:hover { text-decoration: underline; }
|
|
2372
2372
|
.md-body .md-hr { border: 0; border-top: 1px solid var(--loki-border, #e5e1d8); margin: 16px 0; }
|
|
2373
2373
|
.md-body strong { font-weight: 650; }
|
|
2374
|
-
`;function it(d){return!d||typeof d!="string"?null:d.startsWith("page-")?d.slice(5):d}function
|
|
2374
|
+
`;function it(d){return!d||typeof d!="string"?null:d.startsWith("page-")?d.slice(5):d}function Fe(){if(typeof document>"u")return null;let d=document.querySelector(".section-page.active");if(d&&d.id)return it(d.id);try{if(typeof localStorage<"u"){let e=localStorage.getItem("loki-active-section");if(e)return e}}catch{}return null}var qe=class{constructor(){this._regs=new Map,this._seq=0,this._activeSection=Fe(),this._hidden=typeof document<"u"?!!document.hidden:!1,this._listenersInstalled=!1,this._sectionChangeHandler=null,this._visibilityHandler=null,this._mutationObserver=null}get _hasDom(){return typeof document<"u"}_ensureListeners(){if(!(this._listenersInstalled||!this._hasDom)){this._sectionChangeHandler=e=>{let t=e&&e.detail&&e.detail.section?e.detail.section:Fe();this._setActiveSection(t)},document.addEventListener("loki:section-change",this._sectionChangeHandler),this._visibilityHandler=()=>{let e=!!document.hidden;e!==this._hidden&&(this._hidden=e,e||(this._activeSection=Fe()),this._reevaluateAll())},document.addEventListener("visibilitychange",this._visibilityHandler);try{let e=document.getElementById("main-content")||document.body;e&&typeof MutationObserver<"u"&&(this._mutationObserver=new MutationObserver(()=>{let t=Fe();t&&t!==this._activeSection&&this._setActiveSection(t)}),this._mutationObserver.observe(e,{subtree:!0,attributes:!0,attributeFilter:["class"]}))}catch{}this._listenersInstalled=!0}}_setActiveSection(e){e!==this._activeSection&&(this._activeSection=e,this._reevaluateAll())}_resolveSection(e){if(Object.prototype.hasOwnProperty.call(e,"sectionId"))return e.sectionId===null?void 0:e.sectionId;if(e.element&&typeof e.element.closest=="function"){let t=e.element.closest(".section-page"),i=it(t&&t.id);return i===null?void 0:i}}_isAllowed(e){if(!this._hasDom)return!0;if(this._hidden)return!1;let t=this._resolveSection(e);return t===void 0?!0:t===this._activeSection}_reevaluateAll(){for(let e of this._regs.values()){let t=this._isAllowed(e);t&&!e._wasAllowed?(e._wasAllowed=!0,this._safeRun(e)):e._wasAllowed=t}}_safeRun(e){try{let t=e.loadFn();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}register(e={}){let{loadFn:t,intervalMs:i}=e;if(typeof t!="function")throw new Error("registerPoll: loadFn must be a function");if(typeof i!="number"||!(i>0))throw new Error("registerPoll: intervalMs must be a positive number");this._ensureListeners();let a=e.id||`poll-${++this._seq}`;this._regs.has(a)&&this._stopReg(this._regs.get(a));let s={id:a,loadFn:t,intervalMs:i,element:e.element||null,_timer:null,_wasAllowed:!1};return Object.prototype.hasOwnProperty.call(e,"sectionId")&&(s.sectionId=e.sectionId),s._wasAllowed=this._isAllowed(s),s._timer=setInterval(()=>{this._isAllowed(s)?(s._wasAllowed=!0,this._safeRun(s)):s._wasAllowed=!1},i),this._regs.set(a,s),e.immediate!==!1&&s._wasAllowed&&this._safeRun(s),{id:a,stop:()=>this.unregister(a),isActive:()=>this._isAllowed(s)}}_stopReg(e){e&&e._timer&&(clearInterval(e._timer),e._timer=null)}unregister(e){let t=this._regs.get(e);return t?(this._stopReg(t),this._regs.delete(e),!0):!1}get activeSection(){return this._activeSection}get size(){return this._regs.size}destroy(){for(let e of this._regs.values())this._stopReg(e);this._regs.clear(),this._hasDom&&(this._sectionChangeHandler&&(document.removeEventListener("loki:section-change",this._sectionChangeHandler),this._sectionChangeHandler=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null),this._mutationObserver&&(this._mutationObserver.disconnect(),this._mutationObserver=null)),this._listenersInstalled=!1}},Oe=null;function Ct(){return Oe||(Oe=new qe),Oe}function b(d){return Ct().register(d)}var Q=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data={status:"offline",phase:null,iteration:null,provider:null,running_agents:null,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,this._journeyProof=null,this._journeyState="empty"}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._startPolling(),this._api.connect().catch(()=>{})}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._loadAbortController&&(this._loadAbortController.abort(),this._loadAbortController=null),this._teardownApiListeners()}attributeChangedCallback(e,t,i){if(t!==i){if(e==="api-url"&&this._api){let a=this._api;this._teardownApiListeners(),this._setupApi(),a&&a!==this._api&&a.disconnect(),this._api.connect().catch(()=>{}),this._loadStatus()}e==="theme"&&this._applyTheme()}}_teardownApiListeners(){this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(f.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(f.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(f.DISCONNECTED,this._disconnectedHandler))}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e}),this._statusUpdateHandler=t=>this._updateFromStatus(t.detail),this._connectedHandler=()=>{this._data.connected=!0,this.render()},this._disconnectedHandler=()=>{this._data.connected=!1,this._data.status="offline",this.render()},this._api.addEventListener(f.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(f.CONNECTED,this._connectedHandler),this._api.addEventListener(f.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){this._loadAbortController&&this._loadAbortController.abort(),this._loadAbortController=new AbortController;let{signal:e}=this._loadAbortController;try{let[t,i,a,s,r,o]=await Promise.allSettled([this._api.getStatus(),this._api.getChecklistSummary(),this._api.getAppRunnerStatus(),this._api.getPlaywrightResults(),this._api.getCouncilGate(),this._api._get("/api/proofs")]);if(e.aborted)return;if(t.status==="fulfilled"?this._updateFromStatus(t.value):(this._data.connected=!1,this._data.status="offline"),i.status==="fulfilled"&&(this._checklistSummary=i.value?.summary||null),a.status==="fulfilled"&&(this._appRunnerStatus=a.value),s.status==="fulfilled"&&(this._playwrightResults=s.value),r.status==="fulfilled"&&(this._gateStatus=r.value),o.status==="fulfilled"){let n=Array.isArray(o.value?.proofs)?o.value.proofs:[];if(n.length===0)this._journeyProof=null,this._journeyState="empty";else{let l=n[0]?.run_id;if(typeof l=="string"&&l)try{let c=await this._api._get(`/api/proofs/${encodeURIComponent(l)}`);if(e.aborted)return;this._journeyProof=c,this._journeyState="ready"}catch{this._journeyProof=null,this._journeyState="unavailable"}else this._journeyProof=null,this._journeyState="unavailable"}}else this._journeyProof=null,this._journeyState="unavailable";this.render()}catch{if(e.aborted)return;this._data.connected=!1,this._data.status="offline",this.render()}}_updateFromStatus(e){e&&(this._data={...this._data,connected:!0,status:e.status||"offline",phase:e.phase||null,iteration:e.iteration!=null?e.iteration:null,provider:e.provider||null,running_agents:e.running_agents??null,pending_tasks:e.pending_tasks!=null?e.pending_tasks:null,uptime_seconds:e.uptime_seconds||0,complexity:e.complexity||null})}_startPolling(){this._poll=b({loadFn:async()=>{try{await this._loadStatus()}catch{this._data.connected=!1,this._data.status="offline",this.render()}},intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_formatUptime(e){if(!e||e<0)return"--";let t=Math.floor(e/3600),i=Math.floor(e%3600/60),a=Math.floor(e%60);return t>0?`${t}h ${i}m`:i>0?`${i}m ${a}s`:`${a}s`}_getStatusDotClass(){switch(this._data.status){case"running":case"autonomous":return"active";case"paused":return"paused";case"stopped":return"stopped";case"error":return"error";default:return"offline"}}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_renderAppRunnerCard(){let e=this._appRunnerStatus;if(!e||e.status==="not_initialized")return`
|
|
2375
2375
|
<div class="overview-card">
|
|
2376
2376
|
<div class="card-label">App Status</div>
|
|
2377
2377
|
<div class="card-value small-text">${this._data.status==="running"||this._data.status==="autonomous"?"Starting...":"Not started"}</div>
|
|
@@ -2858,6 +2858,15 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
2858
2858
|
color: var(--loki-red);
|
|
2859
2859
|
}
|
|
2860
2860
|
|
|
2861
|
+
.load-error-banner {
|
|
2862
|
+
margin-bottom: 12px;
|
|
2863
|
+
padding: 8px 12px;
|
|
2864
|
+
border: 1px solid var(--loki-red);
|
|
2865
|
+
border-radius: 6px;
|
|
2866
|
+
color: var(--loki-red);
|
|
2867
|
+
font-size: 13px;
|
|
2868
|
+
}
|
|
2869
|
+
|
|
2861
2870
|
.kanban-board {
|
|
2862
2871
|
display: grid;
|
|
2863
2872
|
grid-template-columns: repeat(4, 1fr);
|
|
@@ -3786,17 +3795,18 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
3786
3795
|
<div class="board-region">${t}</div>
|
|
3787
3796
|
</div>
|
|
3788
3797
|
${this._selectedTask?this._renderTaskDetailModal(this._selectedTask):""}
|
|
3789
|
-
`,this._attachEventListeners()}_renderTaskRegion(){let e=this.shadowRoot.querySelector(".board-region");if(!e){this.render();return}e.innerHTML=this._buildContent(),this._attachEventListeners()}_buildContent(){if(this._loading)return'<div class="loading">Loading tasks...</div>';if(this._error&&this._tasks.length===0)return`<div class="error">Error: ${this._escapeHtml(this._error)}</div>`;{let e=this.hasAttribute("readonly"),t=[{id:"all",label:"All"},{id:"today",label:"Today"},{id:"this-week",label:"This Week"},{id:"running",label:"Running"},{id:"failed",label:"Failed"}],i=
|
|
3790
|
-
<div class="agent-avatar ${
|
|
3791
|
-
${
|
|
3792
|
-
<span class="agent-status-dot ${
|
|
3793
|
-
<span class="agent-tooltip">${this._escapeHtml(
|
|
3798
|
+
`,this._attachEventListeners()}_renderTaskRegion(){let e=this.shadowRoot.querySelector(".board-region");if(!e){this.render();return}e.innerHTML=this._buildContent(),this._attachEventListeners()}_buildContent(){if(this._loading)return'<div class="loading">Loading tasks...</div>';if(this._error&&this._tasks.length===0)return`<div class="error">Error: ${this._escapeHtml(this._error)}</div>`;{let e=this.hasAttribute("readonly"),t=[{id:"all",label:"All"},{id:"today",label:"Today"},{id:"this-week",label:"This Week"},{id:"running",label:"Running"},{id:"failed",label:"Failed"}],i=s=>{if(!s.assigned_agent_id&&!s.agent_type)return"";let r=(s.agent_type||"").toLowerCase(),o="AG",n="default",l="idle",c=`Agent #${s.assigned_agent_id||"?"}`;return r.includes("architect")||r==="ar"?(o="AR",n="architect",c="Architect"):r.includes("develop")||r==="dv"?(o="DV",n="developer",c="Developer"):r.includes("test")||r==="ts"?(o="TS",n="tester",c="Tester"):(r.includes("review")||r==="rv")&&(o="RV",n="reviewer",c="Reviewer"),s.status==="in_progress"&&(l="active"),(s.status==="failed"||s.status==="error")&&(l="failed"),`
|
|
3799
|
+
<div class="agent-avatar ${n}">
|
|
3800
|
+
${o}
|
|
3801
|
+
<span class="agent-status-dot ${l}"></span>
|
|
3802
|
+
<span class="agent-tooltip">${this._escapeHtml(c)}</span>
|
|
3794
3803
|
</div>
|
|
3795
3804
|
`};return`
|
|
3805
|
+
${this._error?`<div class="load-error-banner" role="alert">Server tasks could not be loaded; showing local tasks only (${this._escapeHtml(this._error)})</div>`:""}
|
|
3796
3806
|
<div class="filter-bar">
|
|
3797
3807
|
<span class="filter-label">Filter:</span>
|
|
3798
|
-
${t.map(
|
|
3799
|
-
<button class="filter-pill ${this._activeFilter===
|
|
3808
|
+
${t.map(s=>`
|
|
3809
|
+
<button class="filter-pill ${this._activeFilter===s.id?"active":""}" data-filter="${s.id}">${s.label}</button>
|
|
3800
3810
|
`).join("")}
|
|
3801
3811
|
<div class="search-wrap">
|
|
3802
3812
|
<svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
|
@@ -3818,66 +3828,66 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
3818
3828
|
`:""}
|
|
3819
3829
|
|
|
3820
3830
|
<div class="kanban-board">
|
|
3821
|
-
${St.map(
|
|
3822
|
-
<div class="kanban-column" data-status="${
|
|
3831
|
+
${St.map(s=>{let r=this._getTasksByStatus(s.status),o=this._getVisibleCount(s.status),n=r.slice(0,o),l=r.length-n.length;return`
|
|
3832
|
+
<div class="kanban-column" data-status="${s.status}">
|
|
3823
3833
|
<div class="kanban-column-header">
|
|
3824
3834
|
<span class="kanban-column-title">
|
|
3825
|
-
<svg class="column-icon" viewBox="0 0 24 24" style="color: ${
|
|
3826
|
-
${this._columnIcon(
|
|
3835
|
+
<svg class="column-icon" viewBox="0 0 24 24" style="color: ${s.color}">
|
|
3836
|
+
${this._columnIcon(s.status)}
|
|
3827
3837
|
</svg>
|
|
3828
|
-
${
|
|
3838
|
+
${s.label}
|
|
3829
3839
|
</span>
|
|
3830
|
-
<span class="kanban-column-count">${
|
|
3840
|
+
<span class="kanban-column-count">${r.length}</span>
|
|
3831
3841
|
</div>
|
|
3832
|
-
<div class="kanban-tasks" data-status="${
|
|
3833
|
-
${
|
|
3834
|
-
${
|
|
3835
|
-
<div class="task-card ${!e&&!
|
|
3836
|
-
data-task-id="${this._escapeHtml(
|
|
3842
|
+
<div class="kanban-tasks" data-status="${s.status}">
|
|
3843
|
+
${r.length===0?'<div class="empty-column">No tasks</div>':""}
|
|
3844
|
+
${n.map(c=>{let p=String(c.id||""),u=this._expandedCards.has(p),m=this._selectedTasks.has(p);return`
|
|
3845
|
+
<div class="task-card ${!e&&!c.fromServer?"draggable":""} ${c.isLocal?"local":""} ${u?"expanded":""} ${m?"selected":""}"
|
|
3846
|
+
data-task-id="${this._escapeHtml(p)}"
|
|
3837
3847
|
tabindex="0"
|
|
3838
3848
|
role="button"
|
|
3839
|
-
aria-label="Task: ${this._escapeHtml(
|
|
3840
|
-
${!e&&!
|
|
3849
|
+
aria-label="Task: ${this._escapeHtml(c.title||"Untitled")}, ${this._escapeHtml(String(c.priority||"medium"))} priority"
|
|
3850
|
+
${!e&&!c.fromServer?'draggable="true"':""}>
|
|
3841
3851
|
<div class="task-card-header">
|
|
3842
3852
|
<div style="display:flex;align-items:center;gap:6px;">
|
|
3843
|
-
${this._bulkMode?`<div class="task-checkbox ${
|
|
3844
|
-
<span class="task-id">${
|
|
3853
|
+
${this._bulkMode?`<div class="task-checkbox ${m?"checked":""}" data-check-id="${this._escapeHtml(p)}"></div>`:""}
|
|
3854
|
+
<span class="task-id">${c.isLocal?"LOCAL":"#"+this._escapeHtml(p)}</span>
|
|
3845
3855
|
</div>
|
|
3846
3856
|
<div style="display:flex;align-items:center;gap:6px;">
|
|
3847
|
-
${i(
|
|
3848
|
-
<span class="task-priority ${this._escapeHtml(String(
|
|
3857
|
+
${i(c)}
|
|
3858
|
+
<span class="task-priority ${this._escapeHtml(String(c.priority||"medium").toLowerCase())}">${this._escapeHtml(String(c.priority||"medium"))}</span>
|
|
3849
3859
|
</div>
|
|
3850
3860
|
</div>
|
|
3851
|
-
<div class="task-title">${this._escapeHtml(
|
|
3852
|
-
${!
|
|
3861
|
+
<div class="task-title">${this._escapeHtml(c.title||"Untitled")}</div>
|
|
3862
|
+
${!u&&c.description?`<div class="task-desc">${this._escapeHtml(String(c.description??"").substring(0,80))}${String(c.description??"").length>80?"...":""}</div>`:""}
|
|
3853
3863
|
<div class="task-meta">
|
|
3854
|
-
<span class="task-type">${this._escapeHtml(String(
|
|
3855
|
-
<span class="expand-toggle" data-expand-id="${this._escapeHtml(
|
|
3856
|
-
${
|
|
3864
|
+
<span class="task-type">${this._escapeHtml(String(c.type||"task"))}</span>
|
|
3865
|
+
<span class="expand-toggle" data-expand-id="${this._escapeHtml(p)}">
|
|
3866
|
+
${u?'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="18 15 12 9 6 15"/></svg> Less':'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 12 15 18 9"/></svg> More'}
|
|
3857
3867
|
</span>
|
|
3858
3868
|
</div>
|
|
3859
|
-
${
|
|
3869
|
+
${u?`
|
|
3860
3870
|
<div class="card-expanded-content">
|
|
3861
|
-
${
|
|
3871
|
+
${c.description?`<div class="card-expanded-desc">${this._escapeHtml(c.description)}</div>`:""}
|
|
3862
3872
|
<dl class="card-expanded-meta">
|
|
3863
|
-
${
|
|
3864
|
-
${
|
|
3865
|
-
${
|
|
3866
|
-
${
|
|
3873
|
+
${c.assigned_agent_id?`<dt>Agent</dt><dd>#${this._escapeHtml(String(c.assigned_agent_id))}</dd>`:""}
|
|
3874
|
+
${c.created_at?`<dt>Created</dt><dd>${this._escapeHtml(new Date(c.created_at).toLocaleString())}</dd>`:""}
|
|
3875
|
+
${c.updated_at?`<dt>Updated</dt><dd>${this._escapeHtml(new Date(c.updated_at).toLocaleString())}</dd>`:""}
|
|
3876
|
+
${c.acceptance_criteria?.length?`<dt>Criteria</dt><dd>${c.acceptance_criteria.length} items</dd>`:""}
|
|
3867
3877
|
</dl>
|
|
3868
3878
|
</div>
|
|
3869
3879
|
`:""}
|
|
3870
3880
|
</div>
|
|
3871
3881
|
`}).join("")}
|
|
3872
3882
|
</div>
|
|
3873
|
-
${
|
|
3874
|
-
<button class="show-more-btn" data-show-more="${
|
|
3875
|
-
aria-label="Show ${Math.min(
|
|
3876
|
-
Show ${Math.min(
|
|
3883
|
+
${l>0?`
|
|
3884
|
+
<button class="show-more-btn" data-show-more="${s.status}"
|
|
3885
|
+
aria-label="Show ${Math.min(l,d.PAGE_SIZE)} more in ${s.label}">
|
|
3886
|
+
Show ${Math.min(l,d.PAGE_SIZE)} more (${l} hidden)
|
|
3877
3887
|
</button>
|
|
3878
3888
|
`:""}
|
|
3879
|
-
${!e&&
|
|
3880
|
-
<button class="add-task-btn" data-status="${
|
|
3889
|
+
${!e&&s.status==="pending"?`
|
|
3890
|
+
<button class="add-task-btn" data-status="${s.status}" aria-label="Add new task to ${s.label}">+ Add Task</button>
|
|
3881
3891
|
`:""}
|
|
3882
3892
|
</div>
|
|
3883
3893
|
`}).join("")}
|
|
@@ -4333,9 +4343,9 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
4333
4343
|
`,c=this.shadowRoot.activeElement,p=c&&c.id==="spec-input",u=p?c.selectionStart:null,m=p?c.selectionEnd:null;if(this.shadowRoot.innerHTML=`
|
|
4334
4344
|
${o}
|
|
4335
4345
|
${e?n:l}
|
|
4336
|
-
`,this._attachEventListeners(),p){let h=this.shadowRoot.getElementById("spec-input");if(h&&!h.disabled){h.focus();try{h.setSelectionRange(u,m)}catch{}}}}_attachEventListeners(){let e=this.shadowRoot.getElementById("pause-btn"),t=this.shadowRoot.getElementById("resume-btn"),i=this.shadowRoot.getElementById("stop-btn"),a=this.shadowRoot.getElementById("start-btn");e&&e.addEventListener("click",()=>this._triggerPause()),t&&t.addEventListener("click",()=>this._triggerResume()),i&&i.addEventListener("click",()=>this._triggerStop()),a&&a.addEventListener("click",()=>this._triggerStart());let s=this.shadowRoot.getElementById("model-select");if(s){let l=()=>{this._modelInteracting=!1,this._renderPending&&(this._renderPending=!1,this.render())};s.addEventListener("mousedown",()=>{this._modelInteracting=!0}),s.addEventListener("focus",()=>{this._modelInteracting=!0}),s.addEventListener("blur",l),s.addEventListener("change",c=>{this._modelInteracting=!1,this._renderPending=!1,this._onModelChange(c.target.value)})}let r=this.shadowRoot.getElementById("spec-input");r&&r.addEventListener("input",l=>this._onSpecInput(l.target.value));let o=this.shadowRoot.getElementById("start-model-select");o&&(o.addEventListener("mousedown",()=>{this._modelInteracting=!0}),o.addEventListener("focus",()=>{this._modelInteracting=!0}),o.addEventListener("blur",()=>{this._modelInteracting=!1,this._renderPending&&(this._renderPending=!1,this.render())}),o.addEventListener("change",l=>{this._modelInteracting=!1,this._renderPending=!1,this._startModel=l.target.value}));let n=this.shadowRoot.getElementById("advisor-select");n&&(n.addEventListener("mousedown",()=>{this._modelInteracting=!0}),n.addEventListener("focus",()=>{this._modelInteracting=!0}),n.addEventListener("blur",()=>{this._modelInteracting=!1,this._renderPending&&(this._renderPending=!1,this.render())}),n.addEventListener("change",l=>{this._modelInteracting=!1,this._renderPending=!1,this._advisorModel=l.target.value}))}};customElements.get("loki-session-control")||customElements.define("loki-session-control",Z);var at={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"}},ee=class extends v{static get observedAttributes(){return["api-url","max-lines","auto-scroll","theme","log-file"]}constructor(){super(),this._logs=[],this._maxLines=500,this._autoScroll=!0,this._filter="",this._levelFilter="all",this._api=null,this._pollInterval=null,this._logMessageHandler=null,this._apiLastCount=0,this._apiLastSig=null,this._fileLastSize=0,this._fileLastSig=null}connectedCallback(){super.connectedCallback(),this._maxLines=parseInt(this.getAttribute("max-lines"))||500,this._autoScroll=this.hasAttribute("auto-scroll"),this._setupApi(),this._startLogPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopLogPolling(),this._teardownApiListeners()}_teardownApiListeners(){this._api&&this._logMessageHandler&&this._api.removeEventListener(f.LOG_MESSAGE,this._logMessageHandler)}attributeChangedCallback(e,t,i){if(t!==i)switch(e){case"api-url":this._api&&(this._teardownApiListeners(),this._logs=[],this._apiLastCount=0,this._apiLastSig=null,this._setupApi(),this.render());break;case"max-lines":this._maxLines=parseInt(i)||500,this._trimLogs(),this.render();break;case"auto-scroll":this._autoScroll=this.hasAttribute("auto-scroll"),this.render();break;case"theme":this._applyTheme();break}}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e}),this._logMessageHandler=t=>this._addLog(t.detail),this._api.addEventListener(f.LOG_MESSAGE,this._logMessageHandler)}_startLogPolling(){let e=this.getAttribute("log-file");e?this._pollLogFile(e):this._pollApiLogs()}async _pollApiLogs(){await this._apiLogPollTick(),this._poll=b({loadFn:()=>this._apiLogPollTick(),intervalMs:5e3,element:this,immediate:!1})}async _apiLogPollTick(){try{let e=await this._api.getLogs(200);if(
|
|
4346
|
+
`,this._attachEventListeners(),p){let h=this.shadowRoot.getElementById("spec-input");if(h&&!h.disabled){h.focus();try{h.setSelectionRange(u,m)}catch{}}}}_attachEventListeners(){let e=this.shadowRoot.getElementById("pause-btn"),t=this.shadowRoot.getElementById("resume-btn"),i=this.shadowRoot.getElementById("stop-btn"),a=this.shadowRoot.getElementById("start-btn");e&&e.addEventListener("click",()=>this._triggerPause()),t&&t.addEventListener("click",()=>this._triggerResume()),i&&i.addEventListener("click",()=>this._triggerStop()),a&&a.addEventListener("click",()=>this._triggerStart());let s=this.shadowRoot.getElementById("model-select");if(s){let l=()=>{this._modelInteracting=!1,this._renderPending&&(this._renderPending=!1,this.render())};s.addEventListener("mousedown",()=>{this._modelInteracting=!0}),s.addEventListener("focus",()=>{this._modelInteracting=!0}),s.addEventListener("blur",l),s.addEventListener("change",c=>{this._modelInteracting=!1,this._renderPending=!1,this._onModelChange(c.target.value)})}let r=this.shadowRoot.getElementById("spec-input");r&&r.addEventListener("input",l=>this._onSpecInput(l.target.value));let o=this.shadowRoot.getElementById("start-model-select");o&&(o.addEventListener("mousedown",()=>{this._modelInteracting=!0}),o.addEventListener("focus",()=>{this._modelInteracting=!0}),o.addEventListener("blur",()=>{this._modelInteracting=!1,this._renderPending&&(this._renderPending=!1,this.render())}),o.addEventListener("change",l=>{this._modelInteracting=!1,this._renderPending=!1,this._startModel=l.target.value}));let n=this.shadowRoot.getElementById("advisor-select");n&&(n.addEventListener("mousedown",()=>{this._modelInteracting=!0}),n.addEventListener("focus",()=>{this._modelInteracting=!0}),n.addEventListener("blur",()=>{this._modelInteracting=!1,this._renderPending&&(this._renderPending=!1,this.render())}),n.addEventListener("change",l=>{this._modelInteracting=!1,this._renderPending=!1,this._advisorModel=l.target.value}))}};customElements.get("loki-session-control")||customElements.define("loki-session-control",Z);var At=2,at={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"}},ee=class extends v{static get observedAttributes(){return["api-url","max-lines","auto-scroll","theme","log-file"]}constructor(){super(),this._logs=[],this._maxLines=500,this._autoScroll=!0,this._filter="",this._levelFilter="all",this._api=null,this._pollInterval=null,this._logMessageHandler=null,this._apiLastCount=0,this._apiLastSig=null,this._fileLastSize=0,this._fileLastSig=null,this._apiFailures=0}connectedCallback(){super.connectedCallback(),this._maxLines=parseInt(this.getAttribute("max-lines"))||500,this._autoScroll=this.hasAttribute("auto-scroll"),this._setupApi(),this._startLogPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopLogPolling(),this._teardownApiListeners()}_teardownApiListeners(){this._api&&this._logMessageHandler&&this._api.removeEventListener(f.LOG_MESSAGE,this._logMessageHandler)}attributeChangedCallback(e,t,i){if(t!==i)switch(e){case"api-url":this._api&&(this._teardownApiListeners(),this._logs=[],this._apiLastCount=0,this._apiLastSig=null,this._setupApi(),this.render());break;case"max-lines":this._maxLines=parseInt(i)||500,this._trimLogs(),this.render();break;case"auto-scroll":this._autoScroll=this.hasAttribute("auto-scroll"),this.render();break;case"theme":this._applyTheme();break}}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e}),this._logMessageHandler=t=>this._addLog(t.detail),this._api.addEventListener(f.LOG_MESSAGE,this._logMessageHandler)}_startLogPolling(){let e=this.getAttribute("log-file");e?this._pollLogFile(e):this._pollApiLogs()}async _pollApiLogs(){await this._apiLogPollTick(),this._poll=b({loadFn:()=>this._apiLogPollTick(),intervalMs:5e3,element:this,immediate:!1})}async _apiLogPollTick(){try{let e=await this._api.getLogs(200);if(this._apiFailures&&(this._apiFailures=0,this._renderLogs()),!Array.isArray(e))return;let t=e.length?`${e.length}:${e[e.length-1]?.timestamp||""}:${e[e.length-1]?.message||""}`:"0";if(t===this._apiLastSig)return;if(this._apiLastSig=t,e.length>this._apiLastCount){let i=e.slice(this._apiLastCount);for(let a of i)a.message&&a.message.trim()&&this._addLog({message:a.message,level:a.level||"info",timestamp:a.timestamp||new Date().toLocaleTimeString()})}else e.length<this._apiLastCount&&(this._apiLastCount=0);this._apiLastCount=e.length}catch{this._apiFailures+=1,this._renderLogs()}}async _pollLogFile(e){await this._fileLogPollTick(e),this._poll=b({loadFn:()=>this._fileLogPollTick(e),intervalMs:1e3,element:this,immediate:!1})}async _fileLogPollTick(e){try{let t=await fetch(`${e}?t=${Date.now()}`,{credentials:"include"});if(!t.ok)return;let i=await t.text(),a=`${i.length}`;if(a===this._fileLastSig)return;this._fileLastSig=a;let s=i.split(`
|
|
4337
4347
|
`);if(s.length>this._fileLastSize){let r=s.slice(this._fileLastSize);for(let o of r)o.trim()&&this._addLog(this._parseLine(o))}else s.length<this._fileLastSize&&(this._fileLastSize=0);this._fileLastSize=s.length}catch{}}_stopLogPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_parseLine(e){let t=e.match(/^\[([^\]]+)\]\s*\[([^\]]+)\]\s*(.+)$/);if(t)return{timestamp:t[1],level:t[2].toLowerCase(),message:t[3]};let i=e.match(/^(\d{2}:\d{2}:\d{2})\s+(\w+)\s+(.+)$/);return i?{timestamp:i[1],level:i[2].toLowerCase(),message:i[3]}:{timestamp:new Date().toLocaleTimeString(),level:"info",message:e}}_addLog(e){if(!e)return;let t={id:Date.now()+Math.random(),timestamp:e.timestamp||new Date().toLocaleTimeString(),level:(e.level||"info").toLowerCase(),message:e.message||e};this._logs.push(t),this._trimLogs(),this.dispatchEvent(new CustomEvent("log-received",{detail:t})),this._renderLogs(),this._autoScroll&&this._scrollToBottom()}_trimLogs(){this._logs.length>this._maxLines&&(this._logs=this._logs.slice(-this._maxLines))}_clearLogs(){this._logs=[],this.dispatchEvent(new CustomEvent("logs-cleared")),this._renderLogs()}_toggleAutoScroll(){this._autoScroll=!this._autoScroll,this.render(),this._autoScroll&&this._scrollToBottom()}_scrollToBottom(){requestAnimationFrame(()=>{let e=this.shadowRoot.getElementById("log-output");e&&(e.scrollTop=e.scrollHeight)})}_downloadLogs(){let e=this._logs.map(s=>`[${s.timestamp}] [${s.level.toUpperCase()}] ${s.message}`).join(`
|
|
4338
|
-
`),t=new Blob([e],{type:"text/plain"}),i=URL.createObjectURL(t),a=document.createElement("a");a.href=i,a.download=`loki-logs-${new Date().toISOString().split("T")[0]}.txt`,a.click(),URL.revokeObjectURL(i)}_setFilter(e){this._filter=e.toLowerCase(),this._renderLogs()}_setLevelFilter(e){this._levelFilter=e,this._renderLogs()}_getFilteredLogs(){return this._logs.filter(e=>!(this._levelFilter!=="all"&&e.level!==this._levelFilter||this._filter&&!e.message.toLowerCase().includes(this._filter)))}_renderLogs(){let e=this.shadowRoot.getElementById("log-output");if(!e)return;let t=this._getFilteredLogs();if(t.length===0){e.innerHTML='<div class="log-empty">No log output yet. Terminal will update when Loki Mode is running.</div>';return}e.innerHTML=t.map(i=>{let a=at[i.level]||at.info;return`
|
|
4348
|
+
`),t=new Blob([e],{type:"text/plain"}),i=URL.createObjectURL(t),a=document.createElement("a");a.href=i,a.download=`loki-logs-${new Date().toISOString().split("T")[0]}.txt`,a.click(),URL.revokeObjectURL(i)}_setFilter(e){this._filter=e.toLowerCase(),this._renderLogs()}_setLevelFilter(e){this._levelFilter=e,this._renderLogs()}_getFilteredLogs(){return this._logs.filter(e=>!(this._levelFilter!=="all"&&e.level!==this._levelFilter||this._filter&&!e.message.toLowerCase().includes(this._filter)))}_renderLogs(){let e=this.shadowRoot.getElementById("log-output");if(!e)return;let t=this._getFilteredLogs();if(t.length===0){e.innerHTML=this._apiFailures>=At?'<div class="log-empty" role="status">Log source unreachable, retrying</div>':'<div class="log-empty">No log output yet. Terminal will update when Loki Mode is running.</div>';return}e.innerHTML=t.map(i=>{let a=at[i.level]||at.info;return`
|
|
4339
4349
|
<div class="log-line">
|
|
4340
4350
|
<span class="timestamp">${this._escapeHtml(i.timestamp)}</span>
|
|
4341
4351
|
<span class="level" style="color: ${a.color}">[${this._escapeHtml(a.label)}]</span>
|
|
@@ -5396,12 +5406,12 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
5396
5406
|
${t}
|
|
5397
5407
|
</div>
|
|
5398
5408
|
</div>
|
|
5399
|
-
`,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot.querySelectorAll(".tab");e.forEach((n,l)=>{n.addEventListener("click",()=>this._setTab(n.dataset.tab)),n.addEventListener("keydown",c=>{if(c.key==="ArrowRight"||c.key==="ArrowLeft"){c.preventDefault();let p=Array.from(e),u=c.key==="ArrowRight"?(l+1)%p.length:(l-1+p.length)%p.length;p[u].focus(),this._setTab(p[u].dataset.tab)}})}),this.shadowRoot.querySelectorAll(".item-card").forEach(n=>{n.addEventListener("click",()=>this._handleItemClick(n)),n.addEventListener("keydown",l=>{l.key==="Enter"||l.key===" "?(l.preventDefault(),this._handleItemClick(n)):(l.key==="ArrowDown"||l.key==="ArrowUp")&&(l.preventDefault(),this._navigateItemCards(n,l.key==="ArrowDown"?"next":"prev"))})});let t=this.shadowRoot.getElementById("close-detail");t&&t.addEventListener("click",()=>this._closeDetail());let i=this.shadowRoot.getElementById("consolidate-btn");i&&i.addEventListener("click",()=>this._triggerConsolidation());let a=this.shadowRoot.getElementById("refresh-btn");a&&a.addEventListener("click",()=>this._loadData());let s=this.shadowRoot.getElementById("memory-search-input"),r=this.shadowRoot.getElementById("search-btn"),o=this.shadowRoot.getElementById("memory-search-collection");s&&(s.addEventListener("keydown",n=>{n.key==="Enter"&&(n.preventDefault(),this._searchQuery=s.value,this._executeSearch())}),s.addEventListener("input",n=>{this._searchQuery=n.target.value})),r&&r.addEventListener("click",()=>{let n=this.shadowRoot.getElementById("memory-search-input");n&&(this._searchQuery=n.value),this._executeSearch()}),o&&o.addEventListener("change",n=>{this._searchCollection=n.target.value})}_handleItemClick(e){let t=e.dataset.id;switch(e.dataset.type){case"episode":this._selectEpisode(t);break;case"pattern":this._selectPattern(t);break;case"skill":this._selectSkill(t);break}}_navigateItemCards(e,t){let i=Array.from(this.shadowRoot.querySelectorAll(".item-card")),a=i.indexOf(e);if(a===-1)return;let s=t==="next"?a+1:a-1;s>=0&&s<i.length&&i[s].focus()}};customElements.get("loki-memory-browser")||customElements.define("loki-memory-browser",te);var
|
|
5409
|
+
`,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot.querySelectorAll(".tab");e.forEach((n,l)=>{n.addEventListener("click",()=>this._setTab(n.dataset.tab)),n.addEventListener("keydown",c=>{if(c.key==="ArrowRight"||c.key==="ArrowLeft"){c.preventDefault();let p=Array.from(e),u=c.key==="ArrowRight"?(l+1)%p.length:(l-1+p.length)%p.length;p[u].focus(),this._setTab(p[u].dataset.tab)}})}),this.shadowRoot.querySelectorAll(".item-card").forEach(n=>{n.addEventListener("click",()=>this._handleItemClick(n)),n.addEventListener("keydown",l=>{l.key==="Enter"||l.key===" "?(l.preventDefault(),this._handleItemClick(n)):(l.key==="ArrowDown"||l.key==="ArrowUp")&&(l.preventDefault(),this._navigateItemCards(n,l.key==="ArrowDown"?"next":"prev"))})});let t=this.shadowRoot.getElementById("close-detail");t&&t.addEventListener("click",()=>this._closeDetail());let i=this.shadowRoot.getElementById("consolidate-btn");i&&i.addEventListener("click",()=>this._triggerConsolidation());let a=this.shadowRoot.getElementById("refresh-btn");a&&a.addEventListener("click",()=>this._loadData());let s=this.shadowRoot.getElementById("memory-search-input"),r=this.shadowRoot.getElementById("search-btn"),o=this.shadowRoot.getElementById("memory-search-collection");s&&(s.addEventListener("keydown",n=>{n.key==="Enter"&&(n.preventDefault(),this._searchQuery=s.value,this._executeSearch())}),s.addEventListener("input",n=>{this._searchQuery=n.target.value})),r&&r.addEventListener("click",()=>{let n=this.shadowRoot.getElementById("memory-search-input");n&&(this._searchQuery=n.value),this._executeSearch()}),o&&o.addEventListener("change",n=>{this._searchCollection=n.target.value})}_handleItemClick(e){let t=e.dataset.id;switch(e.dataset.type){case"episode":this._selectEpisode(t);break;case"pattern":this._selectPattern(t);break;case"skill":this._selectSkill(t);break}}_navigateItemCards(e,t){let i=Array.from(this.shadowRoot.querySelectorAll(".item-card")),a=i.indexOf(e);if(a===-1)return;let s=t==="next"?a+1:a-1;s>=0&&s<i.length&&i[s].focus()}};customElements.get("loki-memory-browser")||customElements.define("loki-memory-browser",te);var Lt=[{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}],zt=[{id:"all",label:"All Signals"},{id:"user_preference",label:"User Preferences"},{id:"error_pattern",label:"Error Patterns"},{id:"success_pattern",label:"Success Patterns"},{id:"tool_efficiency",label:"Tool Efficiency"},{id:"context_relevance",label:"Context Relevance"}],Ht=[{id:"all",label:"All Sources"},{id:"cli",label:"CLI"},{id:"api",label:"API"},{id:"vscode",label:"VS Code"},{id:"mcp",label:"MCP"},{id:"dashboard",label:"Dashboard"}],ie=class extends v{static get observedAttributes(){return["api-url","theme","time-range","signal-type","source"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._timeRange="7d",this._signalType="all",this._source="all",this._metrics=null,this._trends=null,this._signals=[],this._selectedMetric=null}connectedCallback(){super.connectedCallback(),this._timeRange=this.getAttribute("time-range")||"7d",this._signalType=this.getAttribute("signal-type")||"all",this._source=this.getAttribute("source")||"all",this._setupApi(),this._loadData()}attributeChangedCallback(e,t,i){if(t!==i)switch(e){case"api-url":this._api&&(this._api=g({baseUrl:i}),this._loadData());break;case"theme":this._applyTheme();break;case"time-range":this._timeRange=i,this._loadData();break;case"signal-type":this._signalType=i,this._loadData();break;case"source":this._source=i,this._loadData();break}}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}async _loadData(){this._loading=!0,this._error=null,this.render();let e=this._api;try{let t={timeRange:this._timeRange,signalType:this._signalType!=="all"?this._signalType:void 0,source:this._source!=="all"?this._source:void 0},[i,a,s]=await Promise.all([e.getLearningMetrics(t).catch(()=>null),e.getLearningTrends(t).catch(()=>null),e.getLearningSignals({...t,limit:50}).catch(()=>null)]);if(e!==this._api)return;this._metrics=i,this._trends=a,this._signals=s}catch(t){if(e!==this._api)return;this._error=t.message||"Failed to load learning data"}this._loading=!1,this.render()}_setFilter(e,t){switch(e){case"timeRange":this._timeRange=t,this.setAttribute("time-range",t);break;case"signalType":this._signalType=t,this.setAttribute("signal-type",t);break;case"source":this._source=t,this.setAttribute("source",t);break}this.dispatchEvent(new CustomEvent("filter-change",{detail:{timeRange:this._timeRange,signalType:this._signalType,source:this._source}})),this._loadData()}_selectMetric(e,t){this._selectedMetric={type:e,item:t},this.dispatchEvent(new CustomEvent("metric-select",{detail:{type:e,item:t}})),this.render()}_closeDetail(){this._selectedMetric=null,this.render()}_num(e){let t=e==null?NaN:Number(e);return Number.isFinite(t)?t:null}_formatNumber(e){let t=this._num(e);return t==null?"--":t>=1e6?(t/1e6).toFixed(1)+"M":t>=1e3?(t/1e3).toFixed(1)+"K":String(t)}_formatPercent(e){let t=this._num(e);return t==null?"--":(t*100).toFixed(1)+"%"}_formatDuration(e){let t=this._num(e);return t==null?"--":t<60?t.toFixed(0)+"s":t<3600?(t/60).toFixed(1)+"m":(t/3600).toFixed(1)+"h"}_escapeHtml(e){return e==null?"":String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}_renderFilters(){return`
|
|
5400
5410
|
<div class="filters">
|
|
5401
5411
|
<div class="filter-group">
|
|
5402
5412
|
<label>Time Range</label>
|
|
5403
5413
|
<select id="time-range-select" class="filter-select">
|
|
5404
|
-
${
|
|
5414
|
+
${Lt.map(e=>`
|
|
5405
5415
|
<option value="${e.id}" ${this._timeRange===e.id?"selected":""}>${e.label}</option>
|
|
5406
5416
|
`).join("")}
|
|
5407
5417
|
</select>
|
|
@@ -5409,7 +5419,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
5409
5419
|
<div class="filter-group">
|
|
5410
5420
|
<label>Signal Type</label>
|
|
5411
5421
|
<select id="signal-type-select" class="filter-select">
|
|
5412
|
-
${
|
|
5422
|
+
${zt.map(e=>`
|
|
5413
5423
|
<option value="${e.id}" ${this._signalType===e.id?"selected":""}>${e.label}</option>
|
|
5414
5424
|
`).join("")}
|
|
5415
5425
|
</select>
|
|
@@ -5417,7 +5427,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
5417
5427
|
<div class="filter-group">
|
|
5418
5428
|
<label>Source</label>
|
|
5419
5429
|
<select id="source-select" class="filter-select">
|
|
5420
|
-
${
|
|
5430
|
+
${Ht.map(e=>`
|
|
5421
5431
|
<option value="${e.id}" ${this._source===e.id?"selected":""}>${e.label}</option>
|
|
5422
5432
|
`).join("")}
|
|
5423
5433
|
</select>
|
|
@@ -6408,7 +6418,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
6408
6418
|
${t}
|
|
6409
6419
|
</div>
|
|
6410
6420
|
</div>
|
|
6411
|
-
`,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot.getElementById("time-range-select");e&&e.addEventListener("change",r=>this._setFilter("timeRange",r.target.value));let t=this.shadowRoot.getElementById("signal-type-select");t&&t.addEventListener("change",r=>this._setFilter("signalType",r.target.value));let i=this.shadowRoot.getElementById("source-select");i&&i.addEventListener("change",r=>this._setFilter("source",r.target.value));let a=this.shadowRoot.getElementById("refresh-btn");a&&a.addEventListener("click",()=>this._loadData());let s=this.shadowRoot.getElementById("close-detail");s&&s.addEventListener("click",()=>this._closeDetail()),this.shadowRoot.querySelectorAll(".list-item").forEach(r=>{r.addEventListener("click",()=>{let o=r.dataset.type,n=r.dataset.id,l=this._findItemData(o,n);l&&this._selectMetric(o,l)}),r.addEventListener("keydown",o=>{(o.key==="Enter"||o.key===" ")&&(o.preventDefault(),r.click())})})}_findItemData(e,t){if(!this._metrics?.aggregation)return null;switch(e){case"preference":return this._metrics.aggregation.preferences?.find(i=>i.preference_key===t);case"error_pattern":return this._metrics.aggregation.error_patterns?.find(i=>i.error_type===t);case"success_pattern":return this._metrics.aggregation.success_patterns?.find(i=>i.pattern_name===t);case"tool_efficiency":return this._metrics.aggregation.tool_efficiencies?.find(i=>i.tool_name===t);default:return null}}};customElements.get("loki-learning-dashboard")||customElements.define("loki-learning-dashboard",ie);var
|
|
6421
|
+
`,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot.getElementById("time-range-select");e&&e.addEventListener("change",r=>this._setFilter("timeRange",r.target.value));let t=this.shadowRoot.getElementById("signal-type-select");t&&t.addEventListener("change",r=>this._setFilter("signalType",r.target.value));let i=this.shadowRoot.getElementById("source-select");i&&i.addEventListener("change",r=>this._setFilter("source",r.target.value));let a=this.shadowRoot.getElementById("refresh-btn");a&&a.addEventListener("click",()=>this._loadData());let s=this.shadowRoot.getElementById("close-detail");s&&s.addEventListener("click",()=>this._closeDetail()),this.shadowRoot.querySelectorAll(".list-item").forEach(r=>{r.addEventListener("click",()=>{let o=r.dataset.type,n=r.dataset.id,l=this._findItemData(o,n);l&&this._selectMetric(o,l)}),r.addEventListener("keydown",o=>{(o.key==="Enter"||o.key===" ")&&(o.preventDefault(),r.click())})})}_findItemData(e,t){if(!this._metrics?.aggregation)return null;switch(e){case"preference":return this._metrics.aggregation.preferences?.find(i=>i.preference_key===t);case"error_pattern":return this._metrics.aggregation.error_patterns?.find(i=>i.error_type===t);case"success_pattern":return this._metrics.aggregation.success_patterns?.find(i=>i.pattern_name===t);case"tool_efficiency":return this._metrics.aggregation.tool_efficiencies?.find(i=>i.tool_name===t);default:return null}}};customElements.get("loki-learning-dashboard")||customElements.define("loki-learning-dashboard",ie);var Mt=[{id:"overview",label:"Overview"},{id:"decisions",label:"Decision Log"},{id:"convergence",label:"Convergence"},{id:"agents",label:"Agents"}],ae=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._activeTab="overview",this._pollInterval=null,this._councilState=null,this._verdicts=null,this._convergence=[],this._agents=null,this._selectedAgent=null,this._lastDataHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=g({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null),this._pendingRaf&&(cancelAnimationFrame(this._pendingRaf),this._pendingRaf=null)}async _loadData(){let e=this._api;try{let[i,a,s,r]=await Promise.allSettled([e._get("/api/council/state"),e._get("/api/council/verdicts"),e._get("/api/council/convergence"),e._get("/api/agents")]);if(e!==this._api)return;this._councilState=i.status==="fulfilled"?i.value:null,this._verdicts=a.status==="fulfilled"?a.value?.verdicts||[]:null,s.status==="fulfilled"&&(this._convergence=s.value.dataPoints||[]),this._agents=r.status==="fulfilled"&&Array.isArray(r.value)?r.value:null,this._error=null}catch(i){if(e!==this._api)return;this._error=i.message}let t=JSON.stringify({s:this._councilState,v:this._verdicts,c:this._convergence,a:this._agents,e:this._error});t!==this._lastDataHash&&(this._lastDataHash=t,this.render())}async _forceReview(){try{await this._api._post("/api/council/force-review"),this.dispatchEvent(new CustomEvent("council-action",{detail:{action:"force-review"},bubbles:!0}))}catch(e){this._error=`Failed to force review: ${e.message}`,this.render()}}async _killAgent(e){if(confirm(`Kill agent ${e}?`))try{await this._api._post(`/api/agents/${e}/kill`),this.dispatchEvent(new CustomEvent("council-action",{detail:{action:"kill-agent",agentId:e},bubbles:!0})),await this._loadData()}catch(t){this._error=`Failed to kill agent: ${t.message}`,this.render()}}async _pauseAgent(e){try{await this._api._post(`/api/agents/${e}/pause`),await this._loadData()}catch(t){this._error=`Failed to pause agent: ${t.message}`,this.render()}}async _resumeAgent(e){try{await this._api._post(`/api/agents/${e}/resume`),await this._loadData()}catch(t){this._error=`Failed to resume agent: ${t.message}`,this.render()}}_setTab(e){this._activeTab=e,this.render()}_selectAgent(e){this._selectedAgent=this._selectedAgent?.id===e.id?null:e,this.render()}render(){let e=this.shadowRoot;e&&(this._pendingRaf&&(cancelAnimationFrame(this._pendingRaf),this._pendingRaf=null),e.innerHTML=`
|
|
6412
6422
|
<style>${this.getBaseStyles()}${this._getStyles()}</style>
|
|
6413
6423
|
<div class="council-dashboard">
|
|
6414
6424
|
<div class="council-header">
|
|
@@ -6422,7 +6432,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
6422
6432
|
</div>
|
|
6423
6433
|
|
|
6424
6434
|
<div class="tabs">
|
|
6425
|
-
${
|
|
6435
|
+
${Mt.map(t=>`
|
|
6426
6436
|
<button
|
|
6427
6437
|
class="tab ${this._activeTab===t.id?"active":""}"
|
|
6428
6438
|
data-tab="${t.id}"
|
|
@@ -6995,7 +7005,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
6995
7005
|
color: var(--loki-error);
|
|
6996
7006
|
font-size: 12px;
|
|
6997
7007
|
}
|
|
6998
|
-
`}};customElements.get("loki-council-dashboard")||customElements.define("loki-council-dashboard",ae);var st={critical:0,major:1,minor:2},
|
|
7008
|
+
`}};customElements.get("loki-council-dashboard")||customElements.define("loki-council-dashboard",ae);var st={critical:0,major:1,minor:2},Dt={critical:"var(--loki-status-error, #ef4444)",major:"var(--loki-status-warning, #f59e0b)",minor:"var(--loki-text-muted, #71717a)"},se=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._pollInterval=null,this._checklist=null,this._waivers=null,this._expandedCategories=new Set,this._lastDataHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=g({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let[t,i]=await Promise.all([e.getChecklist(),e.getChecklistWaivers().catch(()=>null)]);if(e!==this._api)return;let a=JSON.stringify(i),s=JSON.stringify(t)+a;if(s===this._lastDataHash)return;this._lastDataHash=s,this._checklist=t,this._waivers=i&&!i.error&&Array.isArray(i.waivers)?i.waivers.filter(r=>r.active):null,this._error=null,this.render()}catch(t){if(e!==this._api)return;this._error=`Failed to load checklist: ${t.message}`,this.render()}}_isItemWaived(e){return(this._waivers||[]).some(t=>t.item_id===e)}_getWaiverForItem(e){return(this._waivers||[]).find(t=>t.item_id===e)||null}async _waiveItem(e){let t=window.prompt("Enter reason for waiving this item:");if(!t)return;let i=this._api;try{if(await i.addChecklistWaiver(e,t),i!==this._api)return;this._lastDataHash=null,await this._loadData()}catch(a){if(i!==this._api)return;this._error=`Failed to add waiver: ${a.message}`,this.render()}}async _unwaiveItem(e){let t=this._api;try{if(await t.removeChecklistWaiver(e),t!==this._api)return;this._lastDataHash=null,await this._loadData()}catch(i){if(t!==this._api)return;this._error=`Failed to remove waiver: ${i.message}`,this.render()}}_toggleCategory(e){this._expandedCategories.has(e)?this._expandedCategories.delete(e):this._expandedCategories.add(e),this.render()}_getStyles(){return`
|
|
6999
7009
|
.checklist-viewer {
|
|
7000
7010
|
padding: 16px;
|
|
7001
7011
|
font-family: var(--loki-font-family, system-ui, -apple-system, sans-serif);
|
|
@@ -7284,7 +7294,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
7284
7294
|
</div>
|
|
7285
7295
|
${i?`<div class="category-body">${this._renderItems(a)}</div>`:""}
|
|
7286
7296
|
</div>
|
|
7287
|
-
`}).join(""):this._renderEmpty()}_renderItems(e){return e?.length?[...e].sort((i,a)=>(st[i.priority]??2)-(st[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=
|
|
7297
|
+
`}).join(""):this._renderEmpty()}_renderItems(e){return e?.length?[...e].sort((i,a)=>(st[i.priority]??2)-(st[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=Dt[s],o=i.verification||[],n=this._getWaiverForItem(i.id),l=!!n,c=i.status==="failing"&&(s==="critical"||s==="major"),p=l?`<span class="item-waived-badge" title="${this._escapeHtml(n.reason||"No reason provided")}">WAIVED</span>`:"",u="";return c&&(l?u=`<button class="waiver-btn waiver-btn-unwaive" data-unwaive-id="${this._escapeHtml(i.id)}">Unwaive</button>`:u=`<button class="waiver-btn" data-waive-id="${this._escapeHtml(i.id)}">Waive</button>`),`
|
|
7288
7298
|
<div class="item">
|
|
7289
7299
|
<div class="item-status ${a}"></div>
|
|
7290
7300
|
<div class="item-title">${this._escapeHtml(i.title||i.id||"?")}</div>
|
|
@@ -7712,7 +7722,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
7712
7722
|
</button>
|
|
7713
7723
|
${this._detailsOpen?`<div class="details-body">${s}</div>`:""}
|
|
7714
7724
|
</div>
|
|
7715
|
-
`}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=(i,a)=>{let s=e.querySelector(i);s&&s.addEventListener("click",a)};e.querySelectorAll('[data-action="restart"]').forEach(i=>i.addEventListener("click",()=>this._handleRestart())),e.querySelectorAll('[data-action="open-external"]').forEach(i=>i.addEventListener("click",()=>this._handleOpenExternal())),e.querySelectorAll('[data-action="retry-frame"]').forEach(i=>i.addEventListener("click",()=>this._handleRetryFrame())),t('[data-action="refresh"]',()=>this._handleRefresh()),t('[data-action="toggle-details"]',()=>this._toggleDetails()),e.querySelectorAll('[data-action="select-service"]').forEach(i=>i.addEventListener("click",()=>this._handleSelectService(i.getAttribute("data-service-key"))))}_escapeHtml(e){return e==null?"":String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}};customElements.define("loki-app-preview",oe);var
|
|
7725
|
+
`}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=(i,a)=>{let s=e.querySelector(i);s&&s.addEventListener("click",a)};e.querySelectorAll('[data-action="restart"]').forEach(i=>i.addEventListener("click",()=>this._handleRestart())),e.querySelectorAll('[data-action="open-external"]').forEach(i=>i.addEventListener("click",()=>this._handleOpenExternal())),e.querySelectorAll('[data-action="retry-frame"]').forEach(i=>i.addEventListener("click",()=>this._handleRetryFrame())),t('[data-action="refresh"]',()=>this._handleRefresh()),t('[data-action="toggle-details"]',()=>this._toggleDetails()),e.querySelectorAll('[data-action="select-service"]').forEach(i=>i.addEventListener("click",()=>this._handleSelectService(i.getAttribute("data-service-key"))))}_escapeHtml(e){return e==null?"":String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}};customElements.define("loki-app-preview",oe);var Rt={opus:{input:5,output:25,label:"Opus 4.6",provider:"claude"},sonnet:{input:3,output:15,label:"Sonnet 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"}},ne=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data={total_input_tokens:null,total_output_tokens:null,estimated_cost_usd:null,by_phase:{},by_model:{},budget_limit:null,budget_used:null,budget_remaining:null,connected:!1},this._api=null,this._pollInterval=null,this._modelPricing={...Rt}}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadPricing(),this._loadCost(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=g({baseUrl:i}),this._loadCost()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}async _loadPricing(){let e=this._api;try{let t=await e.getPricing();if(e!==this._api)return;if(t&&t.models){let i={};for(let[a,s]of Object.entries(t.models))i[a]={input:s.input,output:s.output,label:s.label||a,provider:s.provider||"unknown",note:s.note||""};this._modelPricing=i,this._pricingSource=t.source||"api",this._pricingDate=t.updated||"",this._activeProvider=t.provider||"claude",this.render()}}catch{}}async _loadCost(){let e=this._api;try{let t=await e.getCost();if(e!==this._api)return;this._updateFromCost(t)}catch{if(e!==this._api)return;this._data.connected=!1,this.render()}}_updateFromCost(e){e&&(this._data={...this._data,connected:!0,total_input_tokens:e.total_input_tokens??null,total_output_tokens:e.total_output_tokens??null,estimated_cost_usd:e.estimated_cost_usd??null,by_phase:e.by_phase||{},by_model:e.by_model||{},budget_limit:e.budget_limit,budget_used:e.budget_used??null,budget_remaining:e.budget_remaining},this.render())}_startPolling(){this._poll=b({loadFn:()=>this._loadCost(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_formatTokens(e){return De(e)}_formatUSD(e){return T(e)}_getBudgetPercent(){return!this._data.budget_limit||this._data.budget_limit<=0?0:Math.min(100,(this._data.budget_used??0)/this._data.budget_limit*100)}_getBudgetStatusClass(){let e=this._getBudgetPercent();return e>=90?"critical":e>=70?"warning":"ok"}_renderPhaseRows(){let e=this._data.by_phase;return!e||Object.keys(e).length===0?'<tr><td colspan="4" class="empty-cell">No phase data yet</td></tr>':Object.entries(e).map(([t,i])=>{let a=i.input_tokens??null,s=i.output_tokens??null,r=i.cost_usd??null;return`
|
|
7716
7726
|
<tr>
|
|
7717
7727
|
<td class="phase-name">${this._escapeHTML(t)}</td>
|
|
7718
7728
|
<td class="mono-cell">${this._formatTokens(a)}</td>
|
|
@@ -8116,13 +8126,13 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
8116
8126
|
${Object.entries(this._modelPricing).map(([a,s])=>`
|
|
8117
8127
|
<div class="pricing-item">
|
|
8118
8128
|
<div class="pricing-model ${this._getPricingColorClass(a,s)}">${this._escapeHTML(s.label||a)}</div>
|
|
8119
|
-
<div class="pricing-rates">In: ${
|
|
8129
|
+
<div class="pricing-rates">In: ${T(s.input)} / Out: ${T(s.output)}</div>
|
|
8120
8130
|
${s.note?`<div class="pricing-note">${this._escapeHTML(s.note)}</div>`:""}
|
|
8121
8131
|
</div>`).join("")}
|
|
8122
8132
|
</div>
|
|
8123
8133
|
</div>
|
|
8124
8134
|
</div>
|
|
8125
|
-
`}};customElements.get("loki-cost-dashboard")||customElements.define("loki-cost-dashboard",ne);var le=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._checkpoints=[],this._pollInterval=null,this._lastDataHash=null,this._showCreateForm=!1,this._creating=!1,this._rollingBack=!1,this._rollbackTarget=null,this._notice=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=g({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let[i]=await Promise.allSettled([e._get("/api/checkpoints?limit=50")]);if(e!==this._api)return;i.status==="
|
|
8135
|
+
`}};customElements.get("loki-cost-dashboard")||customElements.define("loki-cost-dashboard",ne);var le=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._checkpoints=[],this._pollInterval=null,this._lastDataHash=null,this._showCreateForm=!1,this._creating=!1,this._rollingBack=!1,this._rollbackTarget=null,this._notice=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=g({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let[i]=await Promise.allSettled([e._get("/api/checkpoints?limit=50")]);if(e!==this._api)return;if(i.status==="rejected"){let a=i.reason;this._error=`Could not load checkpoints: ${a?.message||a}`}else this._checkpoints=Array.isArray(i.value)?i.value:i.value?.checkpoints||[],this._error=null}catch(i){if(e!==this._api)return;this._error=i.message}let t=JSON.stringify({c:this._checkpoints,e:this._error});t!==this._lastDataHash&&(this._lastDataHash=t,this.render())}async _createCheckpoint(){let e=this.shadowRoot.getElementById("checkpoint-message"),t=e?e.value.trim():"";if(t){this._creating=!0,this.render();try{await this._api._post("/api/checkpoints",{message:t}),this._showCreateForm=!1,this._creating=!1,this.dispatchEvent(new CustomEvent("checkpoint-action",{detail:{action:"create",message:t},bubbles:!0})),this._lastDataHash=null,await this._loadData()}catch(i){this._creating=!1,this._error=`Failed to create checkpoint: ${i.message}`,this.render()}}}async _rollbackCheckpoint(e){if(!this._rollingBack){this._rollingBack=!0,this._notice=null,this.render();try{let t=await this._api._post(`/api/checkpoints/${e}/rollback`);this._rollbackTarget=null;let i=t&&t.pre_rollback_snapshot;this._notice=i?`Rolled back to ${e}. Undo this with checkpoint ${i}`:`Rolled back to ${e}.`,this.dispatchEvent(new CustomEvent("checkpoint-action",{detail:{action:"rollback",checkpointId:e,preRollbackSnapshot:i||null},bubbles:!0})),this._lastDataHash=null,await this._loadData()}catch(t){this._rollbackTarget=null,this._error=`Failed to rollback: ${t.message}`}finally{this._rollingBack=!1,this.render()}}}_toggleCreateForm(){this._showCreateForm=!this._showCreateForm,this._rollbackTarget=null,this._notice=null,this.render()}_confirmRollback(e){this._rollbackTarget=e,this.render()}_cancelRollback(){this._rollbackTarget=null,this._notice=null,this.render()}_formatRelativeTime(e){if(!e)return"";try{let t=Date.now(),i=new Date(e).getTime(),a=Math.floor((t-i)/1e3);return a<60?`${a}s ago`:a<3600?`${Math.floor(a/60)}m ago`:a<86400?`${Math.floor(a/3600)}h ago`:`${Math.floor(a/86400)}d ago`}catch{return this._escapeHTML(e)}}render(){let e=this.shadowRoot;if(!e)return;let t=this._checkpoints.length;e.innerHTML=`
|
|
8126
8136
|
<style>${this.getBaseStyles()}${this._getStyles()}</style>
|
|
8127
8137
|
<div class="checkpoint-viewer">
|
|
8128
8138
|
<div class="checkpoint-header">
|
|
@@ -8139,7 +8149,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
8139
8149
|
|
|
8140
8150
|
<div class="checkpoint-list">
|
|
8141
8151
|
${this._loading?'<div class="loading-state">Loading checkpoints...</div>':""}
|
|
8142
|
-
${!this._loading&&t===0?'<div class="empty-state">No checkpoints yet. Create one to save the current state.</div>':""}
|
|
8152
|
+
${!this._loading&&!this._error&&t===0?'<div class="empty-state">No checkpoints yet. Create one to save the current state.</div>':""}
|
|
8143
8153
|
${this._checkpoints.map(i=>this._renderCheckpointCard(i)).join("")}
|
|
8144
8154
|
</div>
|
|
8145
8155
|
|
|
@@ -10432,7 +10442,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
10432
10442
|
</div>
|
|
10433
10443
|
`:""}
|
|
10434
10444
|
</div>
|
|
10435
|
-
`;let k=this.shadowRoot.getElementById("scan-btn");k&&k.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-score")||customElements.define("loki-quality-score",he);var nt=["understand","guardrail","migrate","verify"],lt={understand:"Understand",guardrail:"Guardrail",migrate:"Migrate",verify:"Verify"},
|
|
10445
|
+
`;let k=this.shadowRoot.getElementById("scan-btn");k&&k.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-score")||customElements.define("loki-quality-score",he);var nt=["understand","guardrail","migrate","verify"],lt={understand:"Understand",guardrail:"Guardrail",migrate:"Migrate",verify:"Verify"},Pt={understand:"#5b9bd5",guardrail:"#e8b84a",migrate:"#5bb870",verify:"#5bc8c8"},ge=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._migration=null,this._migrations=[],this._loading=!0,this._error=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._fetchMigrations(),this._poll=b({loadFn:()=>this._fetchData(),intervalMs:15e3,element:this,immediate:!1})}disconnectedCallback(){super.disconnectedCallback(),this._poll&&(this._poll.stop(),this._poll=null)}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=g({baseUrl:i}),this._fetchMigrations()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}async _fetchMigrations(){let e=this._api;try{let t=await e._get("/api/migration/list");if(e!==this._api)return;this._migrations=Array.isArray(t)?t:t.migrations||[],this._error=null;let i=this._migrations.find(a=>a.status==="in_progress"||a.status==="active");if(i){if(await this._fetchStatus(i.migration_id||i.id),e!==this._api)return}else this._migration=null}catch(t){if(e!==this._api)return;this._error=t.message,this._migrations=[],this._migration=null}this._loading=!1,this.render()}async _fetchStatus(e){let t=this._api;try{let i=await t._get(`/api/migration/${encodeURIComponent(e)}/status`);if(t!==this._api)return;this._migration=i,this._error=null}catch(i){if(t!==this._api)return;this._error=i.message}}async _fetchData(){let e=this._api,t=this._migration&&(this._migration.migration_id||this._migration.id);if(t){if(await this._fetchStatus(t),e!==this._api)return;this.render()}else await this._fetchMigrations()}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"):""}_getPhaseIcon(e,t,i){return(i||[]).includes(e)?"[x]":e===t?"[>]":"[ ]"}_getPhaseIndex(e){let t=nt.indexOf(e);return t>=0?t:0}_renderPhaseBar(e,t){let i=t||[];return nt.map(a=>{let s=i.includes(a),r=a===e,o=Pt[a],n=s?"1":r?"0.7":"0.2",l=this._getPhaseIcon(a,e,t);return`
|
|
10436
10446
|
<div class="phase-segment">
|
|
10437
10447
|
<div class="phase-bar-fill" style="background:${o};opacity:${n};"></div>
|
|
10438
10448
|
<div class="phase-label">
|
|
@@ -10865,7 +10875,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
10865
10875
|
<div class="section-label">Migrations</div>
|
|
10866
10876
|
${this._renderMigrationList()}
|
|
10867
10877
|
</div>
|
|
10868
|
-
`}};customElements.get("loki-migration-dashboard")||customElements.define("loki-migration-dashboard",ge);var
|
|
10878
|
+
`}};customElements.get("loki-migration-dashboard")||customElements.define("loki-migration-dashboard",ge);var It=[["claude-opus","claude"],["claude-sonnet","claude"],["claude-haiku","claude"],["opus","claude"],["sonnet","claude"],["haiku","claude"],["claude","claude"],["gpt-4","codex"],["gpt-5","codex"],["gpt","codex"],["codex","codex"],["o1","codex"],["o3","codex"],["cline","cline"],["aider","aider"]];function Bt(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 Ft(d,e){if(e!=null){let i=Bt(e);if(i)return i.provider}let t=(d||"").toLowerCase();for(let[i,a]of It)if(t.includes(i))return a;return"unknown"}var me=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._api=null,this._pollInterval=null,this._activeTab="heatmap",this._activity=[],this._tools=[],this._cost={},this._context={},this._trends=[],this._toolTimeRange="7d",this._connected=!1,this._loading=!1,this._loadedOnce=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&e==="api-url"&&this._api&&(this._api=g({baseUrl:i}),this._loadData())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}async _fetchActivity(e=this._api){let t=e.baseUrl||window.location.origin,i=new AbortController,a=setTimeout(()=>i.abort(),1e4);try{let s=await fetch(`${t}/api/activity?limit=1000`,{signal:i.signal});if(clearTimeout(a),!s.ok)throw new Error(`Activity API ${s.status}`);return s.json()}catch(s){throw clearTimeout(a),s}}async _loadData(){if(!this.isConnected||this._loading)return;let e=this._api;this._loading=!0;try{let t=await Promise.allSettled([this._fetchActivity(e),e.getToolEfficiency(50),e.getCost(),e.getContext(),e.getLearningTrends({timeRange:this._toolTimeRange})]);if(e!==this._api)return;if(t[0].status==="fulfilled"&&(this._activity=t[0].value||[]),t[1].status==="fulfilled"&&(this._tools=t[1].value||[]),t[2].status==="fulfilled"&&(this._cost=t[2].value||{}),t[3].status==="fulfilled"&&(this._context=t[3].value||{}),t[4].status==="fulfilled"){let i=t[4].value||{};this._trends=Array.isArray(i)?i:i.dataPoints||[]}this._connected=t.some(i=>i.status==="fulfilled"),this._loadedOnce=!0,this.render()}finally{this._loading=!1}}_hasAnyData(){let e=Array.isArray(this._activity)?this._activity.length:0,t=Array.isArray(this._tools)?this._tools.length:0,i=this._cost&&this._cost.by_model?Object.keys(this._cost.by_model).length:0,a=this._context||{},r=(a.totals||{}).iterations_tracked||a.total_iterations||a.iteration||0;return e>0||t>0||i>0||r>0}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_computeHeatmap(){let e={},t=Array.isArray(this._activity)?this._activity:[],i=null;for(let u of t){let m=u.timestamp||u.ts||u.created_at;if(!m)continue;let h=new Date(m);if(isNaN(h.getTime()))continue;(i===null||h<i)&&(i=h);let k=this._localDateKey(h);e[k]=(e[k]||0)+1}let a=new Date;a.setHours(0,0,0,0);let s=a.getDay(),r=new Date(a),o=new Date(a);o.setDate(o.getDate()-(52*7+s));let n=null;i!==null&&(n=new Date(i),n.setHours(0,0,0,0));let l=[],c=new Date(o),p=0;for(;c<=r;){let u=this._localDateKey(c),m=n===null||c<n,h=m?0:e[u]||0;h>p&&(p=h),l.push({date:u,count:h,day:c.getDay(),noData:m}),c.setDate(c.getDate()+1)}return{cells:l,maxCount:p}}_getHeatmapLevel(e,t){if(e===0||t===0)return 0;let i=e/t;return i<=.25?1:i<=.5?2:i<=.75?3:4}_renderHeatmap(){let{cells:e,maxCount:t}=this._computeHeatmap(),i=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],a=["","Mon","","Wed","","Fri",""],s=[],r=-1,o=-1;for(let p=0;p<e.length;p++){e[p].day===0&&o++;let u=new Date(e[p].date).getMonth();u!==r&&(s.push({month:i[u],col:Math.max(o,1)}),r=u)}let n=s.map(p=>`<span class="heatmap-month" style="grid-column: ${p.col}">${p.month}</span>`).join(""),l=e.map(p=>p.noData?`<div class="heatmap-cell level-no-data" title="${p.date}: no data"></div>`:`<div class="heatmap-cell level-${this._getHeatmapLevel(p.count,t)}" title="${p.date}: ${p.count} activities"></div>`).join(""),c=a.map(p=>`<span class="heatmap-day-label">${p}</span>`).join("");return`
|
|
10869
10879
|
<div class="heatmap-container">
|
|
10870
10880
|
<div class="heatmap-months">${n}</div>
|
|
10871
10881
|
<div class="heatmap-body">
|
|
@@ -10915,7 +10925,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
10915
10925
|
<div class="sparkline-label">Activity Trend (hourly)</div>
|
|
10916
10926
|
<div class="sparkline">${s}</div>
|
|
10917
10927
|
</div>
|
|
10918
|
-
`}_computeProviders(){let e=this._cost.by_model||{},t={};for(let[r,o]of Object.entries(e)){let n=
|
|
10928
|
+
`}_computeProviders(){let e=this._cost.by_model||{},t={};for(let[r,o]of Object.entries(e)){let n=Ft(r);t[n]||(t[n]={cost:null,tokens:null,iterations:0,models:[],unmeasured:0});let l=t[n];o.cost_usd==null?l.unmeasured+=1:l.cost=l.cost==null?Number(o.cost_usd):l.cost+Number(o.cost_usd),(o.input_tokens!=null||o.output_tokens!=null)&&(l.tokens=(l.tokens??0)+Number(o.input_tokens??0)+Number(o.output_tokens??0)),l.models.push(r)}let a=(this._context.totals||{}).iterations_tracked||this._context.total_iterations||this._context.iteration||0,s=this._cost.estimated_cost_usd??null;for(let r of Object.values(t))if(r.cost!=null&&s>0&&a>0){let o=r.cost/s;r.iterations=Math.round(o*a)}return t}_renderProviders(){let e=this._computeProviders(),t={claude:{label:"Claude",color:"var(--loki-accent)"},codex:{label:"Codex",color:"var(--loki-success)"},cline:{label:"Cline",color:"var(--loki-info)"},aider:{label:"Aider",color:"var(--loki-blue)"},unknown:{label:"Other",color:"var(--loki-text-muted)"}},i=Object.entries(e);return i.length===0?'<div class="empty-state">No provider activity yet. Start a build to compare providers side by side.</div>':`
|
|
10919
10929
|
<div class="provider-grid">
|
|
10920
10930
|
${i.map(([a,s])=>{let r=t[a]||t.unknown,o=s.iterations>0&&s.cost!=null?(s.cost/s.iterations).toFixed(4):"--",n=s.iterations>0&&s.tokens!=null?Math.round(s.tokens/s.iterations).toLocaleString():"--",l=s.cost!=null&&s.unmeasured>0?" (partial)":"";return`
|
|
10921
10931
|
<div class="provider-card">
|
|
@@ -10924,7 +10934,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
10924
10934
|
<div class="provider-name">${r.label}</div>
|
|
10925
10935
|
<div class="provider-stat">
|
|
10926
10936
|
<span class="provider-stat-label">Total Cost</span>
|
|
10927
|
-
<span class="provider-stat-value">${
|
|
10937
|
+
<span class="provider-stat-value">${T(s.cost)}${l}</span>
|
|
10928
10938
|
</div>
|
|
10929
10939
|
<div class="provider-stat">
|
|
10930
10940
|
<span class="provider-stat-label">Cost / Iteration (est.)</span>
|
|
@@ -11419,7 +11429,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
11419
11429
|
</div>
|
|
11420
11430
|
`}
|
|
11421
11431
|
</div>
|
|
11422
|
-
`,this.shadowRoot.querySelectorAll("[data-tab]").forEach(l=>{l.addEventListener("click",c=>this._handleTabClick(c))});let r=this.shadowRoot.getElementById("tool-time-range");r&&r.addEventListener("change",l=>this._handleTimeRangeChange(l));let o=this.shadowRoot.getElementById("analytics-retry-btn");o&&o.addEventListener("click",()=>this._loadData());let n=this.shadowRoot.getElementById("analytics-overview-btn");n&&n.addEventListener("click",()=>this._navigateToOverview())}_navigateToOverview(){this.dispatchEvent(new CustomEvent("loki-navigate",{detail:{view:"overview"},bubbles:!0,composed:!0}))}};customElements.get("loki-analytics")||customElements.define("loki-analytics",me);var jt={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"}},
|
|
11432
|
+
`,this.shadowRoot.querySelectorAll("[data-tab]").forEach(l=>{l.addEventListener("click",c=>this._handleTabClick(c))});let r=this.shadowRoot.getElementById("tool-time-range");r&&r.addEventListener("change",l=>this._handleTimeRangeChange(l));let o=this.shadowRoot.getElementById("analytics-retry-btn");o&&o.addEventListener("click",()=>this._loadData());let n=this.shadowRoot.getElementById("analytics-overview-btn");n&&n.addEventListener("click",()=>this._navigateToOverview())}_navigateToOverview(){this.dispatchEvent(new CustomEvent("loki-navigate",{detail:{view:"overview"},bubbles:!0,composed:!0}))}};customElements.get("loki-analytics")||customElements.define("loki-analytics",me);var jt={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"}},Ut={color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)"};function Nt(d){if(!d)return"Not recorded";try{return new Date(d).toLocaleString([],{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return"Unknown"}}function Ot(d){if(!d||d.length===0)return{pass:0,fail:0,pending:0,notEvaluated:0,total:0};let e={pass:0,fail:0,pending:0,notEvaluated:0,total:d.length};for(let t of d){let i=(t.status||"").toLowerCase();i==="pass"?e.pass++:i==="fail"?e.fail++:i==="pending"?e.pending++:e.notEvaluated++}return e}var ve=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!0,this._error=null,this._api=null,this._gates=[],this._evidence={blocked:!1},this._policy=null,this._pollInterval=null,this._lastDataHash=null,this._scanning=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=g({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_policyLine(e){if(!Array.isArray(this._policy)||!e)return"";let i={"Static Analysis":"static_analysis","Test Suite":"test_coverage","Blind Code Review":"code_review","Anti-Sycophancy":"anti_sycophancy","Mock Integrity":"mock_integrity","Test Mutation":"mutation_integrity","Documentation Coverage":"doc_coverage","Magic Modules Debate":"magic_debate"}[e];if(!i)return"";let a=this._policy.find(l=>l&&l.gate===i);if(!a||!a.mode)return"";let s=a.mode==="blocking",r=a.audit_hits===null||a.audit_hits===void 0?"not measured":`${a.audit_hits} hit${a.audit_hits===1?"":"s"}`,o=s?"BLOCKS":"advisory",n=!s&&a.promote_with?` -- promote with ${this._escapeHtml(a.promote_with)}`:"";return`<div class="gate-meta gate-policy">${o} · ${r}${n}</div>`}async _loadData(){let e=this._api;try{this._loading=!0;let t=await e._get("/api/council/gate");if(e!==this._api)return;let i=t?.gates||t||[],a=t?.evidence||{blocked:!1},s=null;try{let o=await e._get("/api/gate-policy");if(e!==this._api)return;s=Array.isArray(o?.gates)?o.gates:null}catch{s=null}let r=JSON.stringify({gates:i,evidence:a,policy:s});if(r===this._lastDataHash)return;this._lastDataHash=r,this._gates=Array.isArray(i)?i:[],this._evidence=a,this._policy=s,this._error=null}catch(t){if(e!==this._api)return;this._error||(this._error=`Failed to load quality gates: ${t.message}`)}finally{this._loading=!1}this.render()}async _triggerScan(){if(this._scanning)return;let e=this._api;this._scanning=!0,this.render();try{if(await e._post("/api/quality-scan",{},{timeout:3e5}),e!==this._api)return;this._lastDataHash=null,await this._loadData()}catch(t){if(e!==this._api)return;this._error=`Quality scan failed: ${t.message}`}finally{this._scanning=!1,this.render()}}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getStyles(){return`
|
|
11423
11433
|
:host {
|
|
11424
11434
|
display: block;
|
|
11425
11435
|
}
|
|
@@ -11679,7 +11689,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
11679
11689
|
color: var(--loki-text-muted, #939084);
|
|
11680
11690
|
font-size: 13px;
|
|
11681
11691
|
}
|
|
11682
|
-
`}render(){let e=this.shadowRoot;if(!e)return;let t=this._gates,i=
|
|
11692
|
+
`}render(){let e=this.shadowRoot;if(!e)return;let t=this._gates,i=Ot(t),a='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg>',s;this._loading&&t.length===0?s='<div class="loading">Loading quality gates...</div>':t.length===0&&this._error?s=`
|
|
11683
11693
|
<div class="es">
|
|
11684
11694
|
<div class="es-icon">${a}</div>
|
|
11685
11695
|
<div class="es-title">Could not read gate results</div>
|
|
@@ -11691,14 +11701,14 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
11691
11701
|
<button class="es-cta" id="gates-scan-btn" ${this._scanning?"disabled":""}>
|
|
11692
11702
|
${this._scanning?'<span class="es-spinner"></span> Scanning...':"Run quality scan"}
|
|
11693
11703
|
</button>
|
|
11694
|
-
</div>`:s=`<div class="gates-grid">${t.map(p=>{let u=(p.status||"").toLowerCase(),m=jt[u]||{...
|
|
11704
|
+
</div>`:s=`<div class="gates-grid">${t.map(p=>{let u=(p.status||"").toLowerCase(),m=jt[u]||{...Ut,label:u?u.toUpperCase():"NOT EVALUATED"};return`
|
|
11695
11705
|
<div class="gate-card status-${this._escapeHtml(u||"none")}">
|
|
11696
11706
|
<div class="gate-header">
|
|
11697
11707
|
<span class="gate-name">${this._escapeHtml(p.name||"Unnamed Gate")}</span>
|
|
11698
11708
|
<span class="gate-badge" style="background: ${m.bg}; color: ${m.color};">${this._escapeHtml(m.label)}</span>
|
|
11699
11709
|
</div>
|
|
11700
11710
|
${p.description?`<div class="gate-description">${this._escapeHtml(p.description)}</div>`:""}
|
|
11701
|
-
<div class="gate-meta">Last checked: ${
|
|
11711
|
+
<div class="gate-meta">Last checked: ${Nt(p.last_checked||p.lastChecked)}</div>
|
|
11702
11712
|
${this._policyLine(p.name)}
|
|
11703
11713
|
</div>
|
|
11704
11714
|
`}).join("")}</div>`;let r="",o=this._evidence||{};if(o.blocked){let c={empty_diff:"No changes were shipped (empty diff vs run start).",tests_red:"Tests ran and were red.",empty_diff_and_tests_red:"No changes shipped and tests were red.",no_evidence_of_completion:"No evidence of completion."},p=o.error?this._escapeHtml(o.error):c[o.reason]||this._escapeHtml(o.reason||"Completion blocked."),u=Array.isArray(o.failures)?o.failures:[],m=u.length?`<ul class="evidence-failures">${u.map(h=>`<li>${this._escapeHtml(h)}</li>`).join("")}</ul>`:"";r=`
|
|
@@ -11735,7 +11745,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
11735
11745
|
${s}
|
|
11736
11746
|
${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
|
|
11737
11747
|
</div>
|
|
11738
|
-
`;let l=e.getElementById("gates-scan-btn");l&&l.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-gates")||customElements.define("loki-quality-gates",ve);var G={reason:{color:"var(--loki-blue, #3b82f6)",label:"Reason",description:"Analyzing requirements and planning approach"},act:{color:"var(--loki-green, #22c55e)",label:"Act",description:"Implementing changes and executing tasks"},reflect:{color:"var(--loki-purple, #a78bfa)",label:"Reflect",description:"Reviewing results and evaluating quality"},verify:{color:"var(--loki-yellow, #eab308)",label:"Verify",description:"Running tests and validating correctness"}},Ve=["reason","act","reflect","verify"];function
|
|
11748
|
+
`;let l=e.getElementById("gates-scan-btn");l&&l.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-gates")||customElements.define("loki-quality-gates",ve);var G={reason:{color:"var(--loki-blue, #3b82f6)",label:"Reason",description:"Analyzing requirements and planning approach"},act:{color:"var(--loki-green, #22c55e)",label:"Act",description:"Implementing changes and executing tasks"},reflect:{color:"var(--loki-purple, #a78bfa)",label:"Reflect",description:"Reviewing results and evaluating quality"},verify:{color:"var(--loki-yellow, #eab308)",label:"Verify",description:"Running tests and validating correctness"}},Ve=["reason","act","reflect","verify"];function je(d){if(d==null||d<0)return"--";if(d<1e3)return`${d}ms`;let e=Math.floor(d/1e3);if(e<60)return`${e}s`;let t=Math.floor(e/60),i=e%60;if(t<60)return`${t}m ${i}s`;let a=Math.floor(t/60),s=t%60;return`${a}h ${s}m`}function qt(d){if(!d||d.length===0)return[];let e=d.reduce((t,i)=>t+(i.duration_ms||0),0);return e===0?d.map(t=>({phase:t.phase,pct:100/d.length,duration:0})):d.map(t=>({phase:t.phase,pct:(t.duration_ms||0)/e*100,duration:t.duration_ms||0}))}function Gt(d){return d==null?"--":d>=1e6?(d/1e6).toFixed(1)+"M":d>=1e3?(d/1e3).toFixed(1)+"K":String(d)}var fe=class extends v{static get observedAttributes(){return["run-id","api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._timeline=null,this._pollInterval=null,this._selectedPhase=null,this._cycleHistory=[]}get runId(){let e=this.getAttribute("run-id");return e?parseInt(e,10):null}set runId(e){e!=null?this.setAttribute("run-id",String(e)):this.removeAttribute("run-id")}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=g({baseUrl:i}),this._loadData()),e==="run-id"&&this._loadData(),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this.runId;if(e==null){this._timeline=null,this.render();return}let t=this._api;try{this._loading=!0;let i=await t._get(`/api/v2/runs/${e}/timeline`);if(t!==this._api)return;this._timeline=i,this._cycleHistory=i.history||[],this._error=null}catch(i){if(t!==this._api)return;i.message&&(i.message.includes("404")||i.message.includes("Not Found"))?(this._timeline=null,this._error=null):this._error=`Failed to load timeline: ${i.message}`}finally{this._loading=!1}this.render()}_selectPhase(e){this._selectedPhase=this._selectedPhase===e?null:e,this.render()}_bindEvents(){let e=this.shadowRoot;e.querySelectorAll(".phase-segment-interactive").forEach(t=>{t.addEventListener("click",()=>{this._selectPhase(t.dataset.phase)})}),e.querySelectorAll(".legend-item-interactive").forEach(t=>{t.addEventListener("click",()=>{this._selectPhase(t.dataset.phase)})}),e.querySelectorAll(".close-detail").forEach(t=>{t.addEventListener("click",i=>{i.stopPropagation(),this._selectedPhase=null,this.render()})})}_getStyles(){return`
|
|
11739
11749
|
:host {
|
|
11740
11750
|
display: block;
|
|
11741
11751
|
}
|
|
@@ -12050,11 +12060,11 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
12050
12060
|
<div class="detail-metrics">
|
|
12051
12061
|
<div class="detail-metric">
|
|
12052
12062
|
<span class="detail-metric-label">Time Spent</span>
|
|
12053
|
-
<span class="detail-metric-value">${
|
|
12063
|
+
<span class="detail-metric-value">${je(a?.duration_ms)}</span>
|
|
12054
12064
|
</div>
|
|
12055
12065
|
<div class="detail-metric">
|
|
12056
12066
|
<span class="detail-metric-label">Tokens Used</span>
|
|
12057
|
-
<span class="detail-metric-value">${
|
|
12067
|
+
<span class="detail-metric-value">${Gt(a?.tokens_used)}</span>
|
|
12058
12068
|
</div>
|
|
12059
12069
|
<div class="detail-metric">
|
|
12060
12070
|
<span class="detail-metric-label">Quality</span>
|
|
@@ -12067,20 +12077,20 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
12067
12077
|
</div>
|
|
12068
12078
|
</div>
|
|
12069
12079
|
`}_renderCycleHistory(){if(this._cycleHistory.length===0)return"";let t=this._cycleHistory.slice(-8).map((i,a)=>`<div class="history-cycle">${Ve.map(r=>{let o=i.phases?.find(p=>p.phase===r),n=G[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};"
|
|
12070
|
-
title="Cycle ${a+1}: ${n.label} - ${
|
|
12080
|
+
title="Cycle ${a+1}: ${n.label} - ${je(o?.duration_ms)}"></div>`}).join("")}</div>`).join('<div class="history-separator"></div>');return`
|
|
12071
12081
|
<div class="cycle-history">
|
|
12072
12082
|
<div class="history-label">Past Cycles (${this._cycleHistory.length} total)</div>
|
|
12073
12083
|
<div class="history-cycles">${t}</div>
|
|
12074
12084
|
</div>
|
|
12075
|
-
`}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}render(){let e=this.shadowRoot;if(!e)return;let t=this.runId,i=this._timeline,a=i?.phases||[],s=i?.current_phase||null,r=
|
|
12085
|
+
`}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}render(){let e=this.shadowRoot;if(!e)return;let t=this.runId,i=this._timeline,a=i?.phases||[],s=i?.current_phase||null,r=qt(a),o;if(this._loading&&!i)o='<div class="loading">Loading timeline...</div>';else if(t==null)o=this._renderPlaceholderTimeline();else if(a.length===0)o=this._renderPlaceholderTimeline();else{let n=r.map(u=>{let m=G[u.phase]||{color:"var(--loki-text-muted)",label:u.phase},h=s===u.phase,k=this._selectedPhase===u.phase;return`<div class="phase-segment-interactive ${h?"current":""} ${k?"selected":""}"
|
|
12076
12086
|
data-phase="${u.phase}"
|
|
12077
12087
|
style="width: ${Math.max(u.pct,2)}%; background: ${m.color};"
|
|
12078
|
-
title="${m.label}: ${
|
|
12088
|
+
title="${m.label}: ${je(u.duration)}">
|
|
12079
12089
|
${u.pct>12?m.label:""}
|
|
12080
12090
|
</div>`}).join(""),l=a.map(u=>{let m=G[u.phase]||{color:"var(--loki-text-muted)",label:u.phase},h=s===u.phase;return`<div class="legend-item-interactive ${this._selectedPhase===u.phase?"selected":""}" data-phase="${u.phase}">
|
|
12081
12091
|
<span class="legend-dot" style="background: ${m.color}"></span>
|
|
12082
12092
|
<span class="legend-label">${m.label}</span>
|
|
12083
|
-
<span class="legend-duration">${
|
|
12093
|
+
<span class="legend-duration">${je(u.duration_ms)}</span>
|
|
12084
12094
|
${h?'<span class="phase-current-tag">ACTIVE</span>':""}
|
|
12085
12095
|
</div>`}).join(""),c=this._selectedPhase?this._renderPhaseDetail(this._selectedPhase):"",p=this._renderCycleHistory();o=`
|
|
12086
12096
|
<div class="timeline-bar">${n}</div>
|
|
@@ -12097,7 +12107,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
12097
12107
|
${o}
|
|
12098
12108
|
${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
|
|
12099
12109
|
</div>
|
|
12100
|
-
`,this._bindEvents()}};customElements.get("loki-rarv-timeline")||customElements.define("loki-rarv-timeline",fe);function dt(d){if(!d||typeof d!="object")return null;let e=d.freshness_s;return typeof e!="number"||!Number.isFinite(e)||e<0?null:e}function ct(d){if(!Array.isArray(d))return null;let e=null;for(let t of d){let i=dt(t);i!==null&&(e===null||i<e)&&(e=i)}return e}function pt(d={}){let{payload:e=null,receivedAtMs:t=null,nowMs:i=Date.now(),staleAfterS:a=120}=d,s=dt(e),r=null,o="none";return s!==null?(r=s,o="server"):typeof t=="number"&&Number.isFinite(t)&&(r=Math.max(0,Math.floor((i-t)/1e3)),o="client"),{known:r!==null,ageS:r,source:o,isStale:r===null?null:r>=a,staleAfterS:a}}function
|
|
12110
|
+
`,this._bindEvents()}};customElements.get("loki-rarv-timeline")||customElements.define("loki-rarv-timeline",fe);function dt(d){if(!d||typeof d!="object")return null;let e=d.freshness_s;return typeof e!="number"||!Number.isFinite(e)||e<0?null:e}function ct(d){if(!Array.isArray(d))return null;let e=null;for(let t of d){let i=dt(t);i!==null&&(e===null||i<e)&&(e=i)}return e}function pt(d={}){let{payload:e=null,receivedAtMs:t=null,nowMs:i=Date.now(),staleAfterS:a=120}=d,s=dt(e),r=null,o="none";return s!==null?(r=s,o="server"):typeof t=="number"&&Number.isFinite(t)&&(r=Math.max(0,Math.floor((i-t)/1e3)),o="client"),{known:r!==null,ageS:r,source:o,isStale:r===null?null:r>=a,staleAfterS:a}}function Jt(d){if(!d||!d.known||typeof d.ageS!="number")return"unknown";let e=d.ageS;return e<60?`${e}s ago`:e<3600?`${Math.floor(e/60)}m ago`:e<86400?`${Math.floor(e/3600)}h ago`:`${Math.floor(e/86400)}d ago`}function Ke(d){if(!d||!d.known)return"Data age unknown";let e=d.source==="client"?" (receive time)":"",t=d.isStale?" - STALE":"";return`Updated ${Jt(d)}${e}${t}`}var ut={running:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"Running"},completed:{color:"var(--loki-blue, #3b82f6)",bg:"var(--loki-blue-muted, rgba(59, 130, 246, 0.15))",label:"Completed"},failed:{color:"var(--loki-red, #ef4444)",bg:"var(--loki-red-muted, rgba(239, 68, 68, 0.15))",label:"Failed"},cancelled:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"Cancelled"},pending:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Pending"},queued:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Queued"},building:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"Building"},bootstrap:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"Bootstrap"},complete:{color:"var(--loki-blue, #3b82f6)",bg:"var(--loki-blue-muted, rgba(59, 130, 246, 0.15))",label:"Completed"},stopped:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"Stopped"},paused:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"Paused"},unknown:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Unknown"}},Vt=new Set(["running","in_progress","active","building","bootstrap"]);function Kt(d,e,t,i=!1){let a=d;if(a==null&&e&&(t||i)){let c=new Date(e).getTime();a=(t?new Date(t).getTime():Date.now())-c}if(a==null||a<0)return"--";if(a<1e3)return`${a}ms`;let s=Math.floor(a/1e3);if(s<60)return`${s}s`;let r=Math.floor(s/60),o=s%60;if(r<60)return`${r}m ${o}s`;let n=Math.floor(r/60),l=r%60;return`${n}h ${l}m`}function Yt(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 be=class extends v{static get observedAttributes(){return["api-url","project-id","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._runs=[],this._pollInterval=null,this._lastDataHash=null,this._emptyReason=null,this._source=null,this._freshPayload=null,this._changedAtMs=null}_freshness(){let e=t=>{if(!t)return!1;if(t.current===!0)return!0;let i=String(t.status||"").toLowerCase();return i==="running"||i==="in_progress"||i==="active"};return pt({payload:this._freshPayload,receivedAtMs:this._changedAtMs,staleAfterS:this._runs.some(e)?void 0:1/0})}_renderFreshness(){let e=this.shadowRoot&&this.shadowRoot.getElementById("freshness");if(!e)return;let t=this._freshness();e.className=`freshness ${t.known?t.isStale?"is-stale":"":"is-unknown"}`,e.dataset.source=t.source,e.dataset.stale=t.isStale===null?"unknown":String(t.isStale),e.textContent=Ke(t)}get projectId(){let e=this.getAttribute("project-id");return e?parseInt(e,10):null}set projectId(e){e!=null?this.setAttribute("project-id",String(e)):this.removeAttribute("project-id")}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=g({baseUrl:i}),this._loadData()),e==="project-id"&&this._loadData(),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=this.projectId,i=t!=null?`?project_id=${t}`:"",a=await e._get(`/api/v2/runs${i}`);if(e!==this._api)return;let s=a?.runs||a||[],r=Array.isArray(s)?s:[];this._freshPayload=a&&typeof a=="object"&&!Array.isArray(a)&&"freshness_s"in a?a:{freshness_s:ct(r)};let o=JSON.stringify(s),n=o!==this._lastDataHash||!!this._error;n&&(this._lastDataHash=o,this._runs=r,this._changedAtMs=Date.now()),this._emptyReason=a&&!Array.isArray(a)&&a.reason||null,this._source=a&&!Array.isArray(a)&&a.source||null,this._error=null,this._loading=!1,n?this.render():this._renderFreshness();return}catch(t){if(e!==this._api)return;this._error||(this._error=`Failed to load runs: ${t.message}`)}finally{this._loading=!1}this.render()}async _cancelRun(e){try{await this._api._post(`/api/v2/runs/${e}/cancel`),await this._loadData()}catch(t){this._error=`Cancel failed: ${t.message}`,this.render()}}async _replayRun(e){try{await this._api._post(`/api/v2/runs/${e}/replay`),await this._loadData()}catch(t){this._error=`Replay failed: ${t.message}`,this.render()}}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getStyles(){return`
|
|
12101
12111
|
:host {
|
|
12102
12112
|
display: block;
|
|
12103
12113
|
}
|
|
@@ -12271,13 +12281,13 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
12271
12281
|
align-items: center;
|
|
12272
12282
|
gap: 10px;
|
|
12273
12283
|
}
|
|
12274
|
-
`}render(){let e=this.shadowRoot;if(!e)return;let t=this._runs,i;if(this._loading&&t.length===0)i='<div class="loading">Loading runs...</div>';else if(this._error&&t.length===0)i=`<div class="empty-state error-state" role="status" aria-live="polite">Could not load runs.<div class="error-state-detail">${this._escapeHtml(this._error)}</div></div>`;else if(t.length===0){let r=this._emptyReason?`<div class="empty-reason">${this._escapeHtml(this._emptyReason)}</div>`:'<div class="empty-reason">The server did not state a reason.</div>',o=this._source?`<div class="empty-source">Read from: ${this._escapeHtml(Array.isArray(this._source)?this._source.join(", "):this._source)}</div>`:"";i=`<div class="empty-state" role="status" aria-live="polite">No runs found.${r}${o}</div>`}else{let r=t.map(o=>{let n=(o.status||"unknown").toLowerCase(),l=ut[n]||{...ut.unknown,label:o.status},c=n==="running",p=n==="completed"||n==="failed"||n==="cancelled",u=
|
|
12284
|
+
`}render(){let e=this.shadowRoot;if(!e)return;let t=this._runs,i;if(this._loading&&t.length===0)i='<div class="loading">Loading runs...</div>';else if(this._error&&t.length===0)i=`<div class="empty-state error-state" role="status" aria-live="polite">Could not load runs.<div class="error-state-detail">${this._escapeHtml(this._error)}</div></div>`;else if(t.length===0){let r=this._emptyReason?`<div class="empty-reason">${this._escapeHtml(this._emptyReason)}</div>`:'<div class="empty-reason">The server did not state a reason.</div>',o=this._source?`<div class="empty-source">Read from: ${this._escapeHtml(Array.isArray(this._source)?this._source.join(", "):this._source)}</div>`:"";i=`<div class="empty-state" role="status" aria-live="polite">No runs found.${r}${o}</div>`}else{let r=t.map(o=>{let n=(o.status||"unknown").toLowerCase(),l=ut[n]||{...ut.unknown,label:o.status},c=n==="running",p=n==="completed"||n==="failed"||n==="cancelled",u=Kt(o.duration_ms,o.started_at,o.ended_at,Vt.has(n));return`
|
|
12275
12285
|
<tr>
|
|
12276
12286
|
<td><span class="run-id">#${o.id}</span></td>
|
|
12277
12287
|
<td>${this._escapeHtml(o.project_name||o.project||(o.project_id?`Project #${o.project_id}`:"--"))}</td>
|
|
12278
12288
|
<td><span class="status-badge" style="background: ${l.bg}; color: ${l.color};">${this._escapeHtml(l.label)}</span></td>
|
|
12279
12289
|
<td>${this._escapeHtml(o.trigger||o.trigger_type||"--")}</td>
|
|
12280
|
-
<td>${
|
|
12290
|
+
<td>${Yt(o.started_at)}</td>
|
|
12281
12291
|
<td>${u}</td>
|
|
12282
12292
|
<td>
|
|
12283
12293
|
<div class="actions-cell">
|
|
@@ -12317,7 +12327,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
12317
12327
|
${i}
|
|
12318
12328
|
${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
|
|
12319
12329
|
</div>
|
|
12320
|
-
`,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("refresh-btn");t&&t.addEventListener("click",()=>this._loadData()),e.querySelectorAll('[data-action="cancel"]').forEach(i=>{i.addEventListener("click",()=>this._cancelRun(i.dataset.runId))}),e.querySelectorAll('[data-action="replay"]').forEach(i=>{i.addEventListener("click",()=>this._replayRun(i.dataset.runId))})}};customElements.get("loki-run-manager")||customElements.define("loki-run-manager",be);var ht={running:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"Running"},stopped:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"Stopped"},active:{color:"var(--loki-blue, #3b82f6)",bg:"var(--loki-blue-muted, rgba(59, 130, 246, 0.15))",label:"Idle"},missing:{color:"var(--loki-red, #ef4444)",bg:"var(--loki-red-muted, rgba(239, 68, 68, 0.15))",label:"Missing"},unknown:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Unknown"}};function
|
|
12330
|
+
`,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("refresh-btn");t&&t.addEventListener("click",()=>this._loadData()),e.querySelectorAll('[data-action="cancel"]').forEach(i=>{i.addEventListener("click",()=>this._cancelRun(i.dataset.runId))}),e.querySelectorAll('[data-action="replay"]').forEach(i=>{i.addEventListener("click",()=>this._replayRun(i.dataset.runId))})}};customElements.get("loki-run-manager")||customElements.define("loki-run-manager",be);var ht={running:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"Running"},stopped:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"Stopped"},active:{color:"var(--loki-blue, #3b82f6)",bg:"var(--loki-blue-muted, rgba(59, 130, 246, 0.15))",label:"Idle"},missing:{color:"var(--loki-red, #ef4444)",bg:"var(--loki-red-muted, rgba(239, 68, 68, 0.15))",label:"Missing"},unknown:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Unknown"}};function Wt(d){if(d==null||d<0)return"--";if(d<60)return`${d}s`;let e=Math.floor(d/60),t=d%60;if(e<60)return`${e}m ${t}s`;let i=Math.floor(e/60),a=e%60;return`${i}h ${a}m`}function gt(d){return T(d)}var ke=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!0,this._error=null,this._api=null,this._runs=[],this._summary=null,this._pollInterval=null,this._lastDataHash=null,this._emptyReason=null,this._source=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=g({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let[t,i]=await Promise.all([e._get("/api/fleet/runs"),e._get("/api/fleet/summary")]);if(e!==this._api)return;let a=Array.isArray(t)?t:t?.runs||[],s=JSON.stringify({runs:a,summaryResp:i});if(s===this._lastDataHash&&!this._error)return;this._lastDataHash=s,this._runs=Array.isArray(a)?a:[],this._summary=i||null,this._emptyReason=t&&!Array.isArray(t)&&t.reason||null,this._source=t&&!Array.isArray(t)&&t.source||null,this._error=null}catch(t){if(e!==this._api)return;this._emptyReason=null,this._source=null,this._error||(this._error=`Failed to load fleet: ${t.message}`)}finally{this._loading=!1}this.render()}async _cancelRun(e){if(e&&!(typeof confirm=="function"&&!confirm(`Cancel build "${e}"? This stops the running build.`)))try{await this._api._post(`/api/fleet/runs/${encodeURIComponent(e)}/cancel`),this._lastDataHash=null,await this._loadData()}catch(t){this._error=`Cancel failed: ${t.message}`,this.render()}}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getStyles(){return`
|
|
12321
12331
|
:host { display: block; }
|
|
12322
12332
|
|
|
12323
12333
|
.fleet {
|
|
@@ -12532,7 +12542,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
12532
12542
|
<div class="error-state-detail">${this._escapeHtml(this._error)}</div>
|
|
12533
12543
|
<div class="error-state-hint">This is a read failure, not an empty fleet. Builds may be running.</div>
|
|
12534
12544
|
</div>
|
|
12535
|
-
`;else if(t.length===0){let a=this._emptyReason?`<div class="empty-reason">${this._escapeHtml(this._emptyReason)}</div>`:'<div class="empty-reason">The server did not state a reason, so an unreadable registry is indistinguishable from an idle one here.</div>',s=this._source?`<div class="empty-source">Source: ${this._escapeHtml(Array.isArray(this._source)?this._source.join(", "):String(this._source))}</div>`:"";i=`<div class="empty-state">No registered builds. Run <code>loki start</code> in a project to populate the fleet.${a}${s}</div>`}else{let a=t.map(s=>{let r=(s.status||"unknown").toLowerCase(),o=ht[r]||ht.unknown,n=s.running===!0,l=
|
|
12545
|
+
`;else if(t.length===0){let a=this._emptyReason?`<div class="empty-reason">${this._escapeHtml(this._emptyReason)}</div>`:'<div class="empty-reason">The server did not state a reason, so an unreadable registry is indistinguishable from an idle one here.</div>',s=this._source?`<div class="empty-source">Source: ${this._escapeHtml(Array.isArray(this._source)?this._source.join(", "):String(this._source))}</div>`:"";i=`<div class="empty-state">No registered builds. Run <code>loki start</code> in a project to populate the fleet.${a}${s}</div>`}else{let a=t.map(s=>{let r=(s.status||"unknown").toLowerCase(),o=ht[r]||ht.unknown,n=s.running===!0,l=Wt(s.duration_seconds),c=s.iteration!=null?this._escapeHtml(String(s.iteration)):"--",p=s.phase?this._escapeHtml(s.phase):"--";return`
|
|
12536
12546
|
<tr>
|
|
12537
12547
|
<td>
|
|
12538
12548
|
<div class="project-name">${this._escapeHtml(s.name||"project")}</div>
|
|
@@ -12581,7 +12591,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
12581
12591
|
${i}
|
|
12582
12592
|
${this._error&&t.length>0?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
|
|
12583
12593
|
</div>
|
|
12584
|
-
`,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("refresh-btn");t&&t.addEventListener("click",()=>{this._lastDataHash=null,this._loadData()}),e.querySelectorAll('[data-action="cancel"]').forEach(i=>{i.addEventListener("click",()=>this._cancelRun(i.dataset.id))})}};customElements.get("loki-fleet")||customElements.define("loki-fleet",ke);function
|
|
12594
|
+
`,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("refresh-btn");t&&t.addEventListener("click",()=>{this._lastDataHash=null,this._loadData()}),e.querySelectorAll('[data-action="cancel"]').forEach(i=>{i.addEventListener("click",()=>this._cancelRun(i.dataset.id))})}};customElements.get("loki-fleet")||customElements.define("loki-fleet",ke);function Qt(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 Xt(d){let e=new URLSearchParams;for(let[i,a]of Object.entries(d))a!=null&&a!==""&&e.set(i,String(a));let t=e.toString();return t?`?${t}`:""}function Zt(d){if(!d||d.requestError)return{kind:"unchecked",text:`[NOT VERIFIED] Could not check the audit chain: ${d&&d.requestError||"no response"}`};let e=typeof d.files_checked=="number"?d.files_checked:null;if(d.valid===!1)return{kind:"invalid",text:`[TAMPERED] Audit chain broken${d.first_tampered_file?` at ${String(d.first_tampered_file).split("/").pop()}${d.first_tampered_line?` line ${d.first_tampered_line}`:""}`:""}.`};if(d.valid===!0&&e!==null&&e>0){let t=typeof d.entries_checked=="number"?`, ${d.entries_checked} entries`:"";return{kind:"valid",text:`[VALID] Audit chain integrity verified (${e} file${e===1?"":"s"}${t}).`}}return d.valid===!0&&e===0?{kind:"unchecked",text:"[NOT VERIFIED] Nothing was checked: no audit log file carries integrity hashes yet."}:{kind:"unchecked",text:"[NOT VERIFIED] The server returned no verdict."}}var xe=class extends v{static get observedAttributes(){return["api-url","limit","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._entries=[],this._emptyReason=null,this._verifyResult=null,this._verifying=!1,this._filters={action:"",resource:"",dateFrom:"",dateTo:""}}get limit(){let e=this.getAttribute("limit");return e?parseInt(e,10):50}set limit(e){this.setAttribute("limit",String(e))}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData()}disconnectedCallback(){super.disconnectedCallback()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=g({baseUrl:i}),this._loadData()),e==="limit"&&this._loadData(),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}async _loadData(){let e=this._api;try{this._loading=!0,this.render();let t={limit:this.limit,action:this._filters.action,resource:this._filters.resource,date_from:this._filters.dateFrom,date_to:this._filters.dateTo},i=Xt(t),a=await e._get(`/api/v2/audit${i}`);if(e!==this._api)return;this._entries=a?.entries||a||[],this._emptyReason=a&&!Array.isArray(a)&&a.reason||null,this._error=null}catch(t){if(e!==this._api)return;this._emptyReason=null,this._error=`Failed to load audit log: ${t.message}`}finally{this._loading=!1}this.render()}async _verifyIntegrity(){let e=this._api;try{this._verifying=!0,this._verifyResult=null,this.render();let t=await e._get("/api/v2/audit/verify");if(e!==this._api)return;this._verifyResult=t}catch(t){if(e!==this._api)return;this._verifyResult={requestError:t.message}}finally{this._verifying=!1}this.render()}_onFilterChange(e,t){this._filters[e]=t,this._loadData()}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getStyles(){return`
|
|
12585
12595
|
:host {
|
|
12586
12596
|
display: block;
|
|
12587
12597
|
}
|
|
@@ -12838,7 +12848,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
12838
12848
|
color: var(--loki-text-muted, #939084);
|
|
12839
12849
|
margin-bottom: 8px;
|
|
12840
12850
|
}
|
|
12841
|
-
`}_getStatusClass(e){if(!e)return"status-warning";let t=e.toLowerCase();return t==="success"||t==="ok"||t==="pass"?"status-success":t==="failure"||t==="error"||t==="fail"?"status-failure":"status-warning"}render(){let e=this.shadowRoot;if(!e)return;let t=this._entries,i="";if(this._verifyResult){let s=
|
|
12851
|
+
`}_getStatusClass(e){if(!e)return"status-warning";let t=e.toLowerCase();return t==="success"||t==="ok"||t==="pass"?"status-success":t==="failure"||t==="error"||t==="fail"?"status-failure":"status-warning"}render(){let e=this.shadowRoot;if(!e)return;let t=this._entries,i="";if(this._verifyResult){let s=Zt(this._verifyResult);i=`
|
|
12842
12852
|
<div class="verify-result verify-${s.kind}">
|
|
12843
12853
|
${this._escapeHtml(s.text)}
|
|
12844
12854
|
</div>
|
|
@@ -12850,7 +12860,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
12850
12860
|
</div>
|
|
12851
12861
|
`;else if(t.length===0)a=`<div class="empty-state">No audit entries found matching filters.${this._emptyReason?`<div class="empty-reason">${this._escapeHtml(this._emptyReason)}</div>`:'<div class="empty-reason">The server did not state a reason.</div>'}</div>`;else{let s=t.map(r=>`
|
|
12852
12862
|
<tr>
|
|
12853
|
-
<td>${
|
|
12863
|
+
<td>${Qt(r.timestamp)}</td>
|
|
12854
12864
|
<td>${this._escapeHtml(r.action||"--")}</td>
|
|
12855
12865
|
<td>${this._escapeHtml(r.resource||r.resource_type||"--")}</td>
|
|
12856
12866
|
<td>${this._escapeHtml(r.user||r.actor||"--")}</td>
|
|
@@ -12914,7 +12924,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
12914
12924
|
${a}
|
|
12915
12925
|
${this._error&&t.length>0?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
|
|
12916
12926
|
</div>
|
|
12917
|
-
`,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("verify-btn");t&&t.addEventListener("click",()=>this._verifyIntegrity());let i=e.getElementById("refresh-btn");i&&i.addEventListener("click",()=>this._loadData());let a=e.getElementById("filter-action");a&&a.addEventListener("change",n=>this._onFilterChange("action",n.target.value));let s=e.getElementById("filter-resource");s&&s.addEventListener("change",n=>this._onFilterChange("resource",n.target.value));let r=e.getElementById("filter-date-from");r&&r.addEventListener("change",n=>this._onFilterChange("dateFrom",n.target.value));let o=e.getElementById("filter-date-to");o&&o.addEventListener("change",n=>this._onFilterChange("dateTo",n.target.value))}};customElements.get("loki-audit-viewer")||customElements.define("loki-audit-viewer",xe);function mt(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)}}function
|
|
12927
|
+
`,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("verify-btn");t&&t.addEventListener("click",()=>this._verifyIntegrity());let i=e.getElementById("refresh-btn");i&&i.addEventListener("click",()=>this._loadData());let a=e.getElementById("filter-action");a&&a.addEventListener("change",n=>this._onFilterChange("action",n.target.value));let s=e.getElementById("filter-resource");s&&s.addEventListener("change",n=>this._onFilterChange("resource",n.target.value));let r=e.getElementById("filter-date-from");r&&r.addEventListener("change",n=>this._onFilterChange("dateFrom",n.target.value));let o=e.getElementById("filter-date-to");o&&o.addEventListener("change",n=>this._onFilterChange("dateTo",n.target.value))}};customElements.get("loki-audit-viewer")||customElements.define("loki-audit-viewer",xe);function mt(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)}}function ei(d){return d.status?String(d.status).toLowerCase():d.revoked?"revoked":d.expires_at&&Date.parse(d.expires_at)<=Date.now()?"expired":d.rotation_expires_at?"rotating":d.revoked===!1?"active":"unknown"}var _e=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._keys=[],this._showCreateForm=!1,this._newToken=null,this._confirmDeleteId=null,this._rotateKeyId=null,this._rotateGracePeriod="24",this._createName="",this._createRole="read",this._createExpiration=""}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData()}disconnectedCallback(){super.disconnectedCallback()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=g({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}async _loadData(){let e=this._api;try{this._loading=!0,this.render();let t=await e._get("/api/v2/api-keys");if(e!==this._api)return;this._keys=Array.isArray(t)?t:t?.keys||[],this._error=null}catch(t){if(e!==this._api)return;this._error=`Failed to load API keys: ${t.message}`}finally{this._loading=!1}this.render()}async _createKey(){if(!this._createName.trim()){this._error="Key name is required.",this.render();return}try{let e={name:this._createName.trim(),role:this._createRole};this._createExpiration&&(e.expiration=this._createExpiration);let t=await this._api._post("/api/v2/api-keys",e);this._newToken=t?.token||t?.key||null,this._showCreateForm=!1,this._createName="",this._createRole="read",this._createExpiration="",this._error=null,await this._loadData()}catch(e){this._error=`Create failed: ${e.message}`,this.render()}}async _rotateKey(e){try{let t={grace_period_hours:parseInt(this._rotateGracePeriod,10)||24},i=await this._api._post(`/api/v2/api-keys/${e}/rotate`,t);this._newToken=i?.token||i?.key||null,this._rotateKeyId=null,this._error=null,await this._loadData()}catch(t){this._error=`Rotate failed: ${t.message}`,this.render()}}async _deleteKey(e){try{await this._api._delete(`/api/v2/api-keys/${e}`),this._confirmDeleteId=null,this._error=null,await this._loadData()}catch(t){this._error=`Delete failed: ${t.message}`,this._confirmDeleteId=null,this.render()}}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getStyles(){return`
|
|
12918
12928
|
:host {
|
|
12919
12929
|
display: block;
|
|
12920
12930
|
}
|
|
@@ -13256,7 +13266,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
13256
13266
|
<button class="btn" id="cancel-create">Cancel</button>
|
|
13257
13267
|
</div>
|
|
13258
13268
|
</div>
|
|
13259
|
-
`);let s;this._loading&&t.length===0?s='<div class="loading">Loading API keys...</div>':t.length===0?s='<div class="empty-state">No API keys configured. Create one to get started.</div>':s=`
|
|
13269
|
+
`);let s;this._loading&&t.length===0?s='<div class="loading">Loading API keys...</div>':t.length===0&&(this._error||"").startsWith("Failed to load API keys")?s="":t.length===0?s='<div class="empty-state">No API keys configured. Create one to get started.</div>':s=`
|
|
13260
13270
|
<div class="keys-table-wrapper">
|
|
13261
13271
|
<table>
|
|
13262
13272
|
<thead>
|
|
@@ -13269,7 +13279,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
13269
13279
|
<th>Actions</th>
|
|
13270
13280
|
</tr>
|
|
13271
13281
|
</thead>
|
|
13272
|
-
<tbody>${t.map(o=>{let n=o.id||o.key_id,l=
|
|
13282
|
+
<tbody>${t.map(o=>{let n=o.id||o.key_id,l=ei(o),c=l==="active"?"key-status-active":l==="expired"?"key-status-expired":"key-status-revoked",p=this._confirmDeleteId===n,u=this._rotateKeyId===n,m;return p?m=`
|
|
13273
13283
|
<div class="confirm-delete">
|
|
13274
13284
|
<span>Delete this key?</span>
|
|
13275
13285
|
<button class="btn btn-sm btn-danger" data-action="confirm-delete" data-key-id="${n}">Yes</button>
|
|
@@ -13313,7 +13323,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
13313
13323
|
${s}
|
|
13314
13324
|
${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
|
|
13315
13325
|
</div>
|
|
13316
|
-
`,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("show-create");t&&t.addEventListener("click",()=>{this._showCreateForm=!0,this.render()});let i=e.getElementById("dismiss-token");i&&i.addEventListener("click",()=>{this._newToken=null,this.render()});let a=e.getElementById("submit-create");a&&a.addEventListener("click",()=>{let r=e.getElementById("create-name"),o=e.getElementById("create-role"),n=e.getElementById("create-expiration");this._createName=r?.value||"",this._createRole=o?.value||"read",this._createExpiration=n?.value||"",this._createKey()});let s=e.getElementById("cancel-create");s&&s.addEventListener("click",()=>{this._showCreateForm=!1,this.render()}),e.querySelectorAll('[data-action="delete"]').forEach(r=>{r.addEventListener("click",()=>{this._confirmDeleteId=r.dataset.keyId,this.render()})}),e.querySelectorAll('[data-action="confirm-delete"]').forEach(r=>{r.addEventListener("click",()=>{this._deleteKey(r.dataset.keyId)})}),e.querySelectorAll('[data-action="cancel-delete"]').forEach(r=>{r.addEventListener("click",()=>{this._confirmDeleteId=null,this.render()})}),e.querySelectorAll('[data-action="rotate"]').forEach(r=>{r.addEventListener("click",()=>{this._rotateKeyId=r.dataset.keyId,this.render()})}),e.querySelectorAll('[data-action="confirm-rotate"]').forEach(r=>{r.addEventListener("click",()=>{let o=e.getElementById(`rotate-grace-${r.dataset.keyId}`);this._rotateGracePeriod=o?.value||"24",this._rotateKey(r.dataset.keyId)})}),e.querySelectorAll('[data-action="cancel-rotate"]').forEach(r=>{r.addEventListener("click",()=>{this._rotateKeyId=null,this.render()})})}};customElements.get("loki-api-keys")||customElements.define("loki-api-keys",_e);function
|
|
13326
|
+
`,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("show-create");t&&t.addEventListener("click",()=>{this._showCreateForm=!0,this.render()});let i=e.getElementById("dismiss-token");i&&i.addEventListener("click",()=>{this._newToken=null,this.render()});let a=e.getElementById("submit-create");a&&a.addEventListener("click",()=>{let r=e.getElementById("create-name"),o=e.getElementById("create-role"),n=e.getElementById("create-expiration");this._createName=r?.value||"",this._createRole=o?.value||"read",this._createExpiration=n?.value||"",this._createKey()});let s=e.getElementById("cancel-create");s&&s.addEventListener("click",()=>{this._showCreateForm=!1,this.render()}),e.querySelectorAll('[data-action="delete"]').forEach(r=>{r.addEventListener("click",()=>{this._confirmDeleteId=r.dataset.keyId,this.render()})}),e.querySelectorAll('[data-action="confirm-delete"]').forEach(r=>{r.addEventListener("click",()=>{this._deleteKey(r.dataset.keyId)})}),e.querySelectorAll('[data-action="cancel-delete"]').forEach(r=>{r.addEventListener("click",()=>{this._confirmDeleteId=null,this.render()})}),e.querySelectorAll('[data-action="rotate"]').forEach(r=>{r.addEventListener("click",()=>{this._rotateKeyId=r.dataset.keyId,this.render()})}),e.querySelectorAll('[data-action="confirm-rotate"]').forEach(r=>{r.addEventListener("click",()=>{let o=e.getElementById(`rotate-grace-${r.dataset.keyId}`);this._rotateGracePeriod=o?.value||"24",this._rotateKey(r.dataset.keyId)})}),e.querySelectorAll('[data-action="cancel-rotate"]').forEach(r=>{r.addEventListener("click",()=>{this._rotateKeyId=null,this.render()})})}};customElements.get("loki-api-keys")||customElements.define("loki-api-keys",_e);function ti(d){return d?d.slug&&d.name?`${d.name} (${d.slug})`:d.name||d.slug||"Unknown":"Unknown"}var ye=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._tenants=[],this._selectedTenantId=null,this._dropdownOpen=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._outsideClickHandler=e=>{this._dropdownOpen&&!this.contains(e.target)&&(this._dropdownOpen=!1,this.render())},document.addEventListener("click",this._outsideClickHandler)}disconnectedCallback(){super.disconnectedCallback(),this._outsideClickHandler&&(document.removeEventListener("click",this._outsideClickHandler),this._outsideClickHandler=null)}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=g({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}async _loadData(){let e=this._api;try{this._loading=!0;let t=await e._get("/api/v2/tenants");if(e!==this._api)return;this._tenants=Array.isArray(t)?t:t?.tenants||[],this._error=null}catch(t){if(e!==this._api)return;this._error=`Failed to load tenants: ${t.message}`}finally{this._loading=!1}this.render()}_toggleDropdown(){this._dropdownOpen=!this._dropdownOpen,this.render()}_selectTenant(e,t){this._selectedTenantId=e,this._dropdownOpen=!1,this.render(),this.dispatchEvent(new CustomEvent("tenant-changed",{detail:{tenantId:e,tenantName:t},bubbles:!0,composed:!0}))}_getSelectedTenant(){return this._selectedTenantId==null?null:this._tenants.find(e=>(e.id||e.slug)===this._selectedTenantId)||null}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_getStyles(){return`
|
|
13317
13327
|
:host {
|
|
13318
13328
|
display: inline-block;
|
|
13319
13329
|
position: relative;
|
|
@@ -13447,7 +13457,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
13447
13457
|
color: var(--loki-text-muted, #939084);
|
|
13448
13458
|
font-size: 12px;
|
|
13449
13459
|
}
|
|
13450
|
-
`}render(){let e=this.shadowRoot;if(!e)return;let t=this._getSelectedTenant(),i=t?
|
|
13460
|
+
`}render(){let e=this.shadowRoot;if(!e)return;let t=this._getSelectedTenant(),i=t?ti(t):"All Tenants",a=this._dropdownOpen,s="";if(a){let r;if(this._loading)r='<div class="loading-text">Loading tenants...</div>';else if(this._error)r=`<div class="error-text">${this._escapeHtml(this._error)}</div>`;else{let o=this._selectedTenantId==null;r=`
|
|
13451
13461
|
<button class="dropdown-item all-tenants ${o?"selected":""}" data-tenant-id="">
|
|
13452
13462
|
<span class="tenant-name">All Tenants</span>
|
|
13453
13463
|
${o?'<span class="check-mark">*</span>':""}
|
|
@@ -13472,7 +13482,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
13472
13482
|
</button>
|
|
13473
13483
|
${s}
|
|
13474
13484
|
</div>
|
|
13475
|
-
`,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("trigger-btn");t&&t.addEventListener("click",i=>{i.stopPropagation(),this._toggleDropdown()}),e.querySelectorAll(".dropdown-item").forEach(i=>{i.addEventListener("click",a=>{a.stopPropagation();let s=i.dataset.tenantId||null,r=i.dataset.tenantName||null;this._selectTenant(s||null,r||"All Tenants")})})}};customElements.get("loki-tenant-switcher")||customElements.define("loki-tenant-switcher",ye);var Ye={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"}},we=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._phases=[],this._budget=null,this._totalCost=null,this._hoveredPhase=null,this._loadFailed=!1,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=g({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:1e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/cost");if(e!==this._api)return;let i={phases:Object.entries(t.by_phase||{}).map(([a,s])=>({phase:a,cost_usd:s.cost_usd??null})),budget_usd:t.budget_limit,total_usd:t.estimated_cost_usd};if(this._phases=i.phases||[],this._budget=i.budget_usd||null,i.total_usd!=null)this._totalCost=i.total_usd;else{let a=this._phases.filter(s=>s.cost_usd!=null);this._totalCost=a.length?a.reduce((s,r)=>s+r.cost_usd,0):null}this._loadFailed=!1}catch{if(e!==this._api)return;this._loadFailed=!0}this.render()}_formatCost(e){return
|
|
13485
|
+
`,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("trigger-btn");t&&t.addEventListener("click",i=>{i.stopPropagation(),this._toggleDropdown()}),e.querySelectorAll(".dropdown-item").forEach(i=>{i.addEventListener("click",a=>{a.stopPropagation();let s=i.dataset.tenantId||null,r=i.dataset.tenantName||null;this._selectTenant(s||null,r||"All Tenants")})})}};customElements.get("loki-tenant-switcher")||customElements.define("loki-tenant-switcher",ye);var Ye={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"}},we=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._phases=[],this._budget=null,this._totalCost=null,this._hoveredPhase=null,this._loadFailed=!1,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=g({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:1e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/cost");if(e!==this._api)return;let i={phases:Object.entries(t.by_phase||{}).map(([a,s])=>({phase:a,cost_usd:s.cost_usd??null})),budget_usd:t.budget_limit,total_usd:t.estimated_cost_usd};if(this._phases=i.phases||[],this._budget=i.budget_usd||null,i.total_usd!=null)this._totalCost=i.total_usd;else{let a=this._phases.filter(s=>s.cost_usd!=null);this._totalCost=a.length?a.reduce((s,r)=>s+r.cost_usd,0):null}this._loadFailed=!1}catch{if(e!==this._api)return;this._loadFailed=!0}this.render()}_formatCost(e){return T(e)}_escapeHtml(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""):""}_bindEvents(){this.shadowRoot.querySelectorAll(".waterfall-bar").forEach(t=>{t.addEventListener("mouseenter",()=>{this._hoveredPhase=t.dataset.phase,this._updateTooltip(t)}),t.addEventListener("mouseleave",()=>{this._hoveredPhase=null,this._hideTooltip()})})}_updateTooltip(e){let t=this.shadowRoot.querySelector(".tooltip");if(!t)return;let i=this._phases.find(o=>o.phase===this._hoveredPhase);if(!i)return;let a=Ye[i.phase]||{label:i.phase};t.innerHTML=`<strong>${this._escapeHtml(a.label)}</strong>: ${this._formatCost(i.cost_usd)}`,t.style.display="block";let s=e.getBoundingClientRect(),r=this.shadowRoot.querySelector(".chart-area").getBoundingClientRect();t.style.left=s.left-r.left+s.width/2+"px",t.style.top=s.top-r.top-30+"px"}_hideTooltip(){let e=this.shadowRoot.querySelector(".tooltip");e&&(e.style.display="none")}_getStyles(){return`
|
|
13476
13486
|
:host {
|
|
13477
13487
|
display: block;
|
|
13478
13488
|
}
|
|
@@ -14163,7 +14173,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
14163
14173
|
white-space: pre-wrap;
|
|
14164
14174
|
}
|
|
14165
14175
|
</style>
|
|
14166
|
-
`,i="";this._loading&&this._items.length===0?i='<div class="esc-empty">Loading escalations...</div>':this._error?i='<div class="esc-error">Failed to load escalations: '+this._escapeHtml(this._error)+"</div>":!this._items||this._items.length===0?i='<div class="esc-empty">No handoff notes yet. If a build needs your attention, its notes will appear here.</div>':i='<div class="esc-list">'+this._items.map(n=>{let l=this._escapeHtml(n.filename||""),c=this._escapeHtml(this._formatSize(n.size_bytes)),p=this._escapeHtml(this._formatDate(n.modified_at));return'<div class="esc-item" data-filename="'+l+'"><span class="esc-name">'+l+'</span><span class="esc-meta">'+c+" · "+p+"</span></div>"}).join("")+"</div>";let a="";if(this._activeFile){let o=this._escapeHtml(this._activeFile),n;this._activeBodyError?n='<div class="esc-error">Failed to load: '+this._escapeHtml(this._activeBodyError)+"</div>":this._activeBody===null?n='<div class="esc-body">Loading '+o+"...</div>":n='<div class="esc-body md-body">'+C(this._activeBody)+"</div>",a='<div class="esc-viewer"><div class="esc-viewer-header"><span class="esc-name">'+o+'</span><button class="esc-close-btn" data-action="close">Close</button></div>'+n+"</div>"}e.innerHTML=t+'<div class="esc-wrapper"><div class="esc-explain">Handoff/escalation documents written under .loki/escalations/. Click an entry to view its contents.</div>'+i+a+"</div>",e.querySelectorAll(".esc-item").forEach(o=>{o.addEventListener("click",()=>{let n=o.getAttribute("data-filename");n&&this._openFile(n)})});let r=e.querySelector('.esc-close-btn[data-action="close"]');r&&r.addEventListener("click",()=>this._closeFile())}};typeof customElements<"u"&&!customElements.get("loki-escalations")&&customElements.define("loki-escalations",Ee);var Ce=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._transcripts=[],this._hookEvents=[],this._loading=!1,this._error=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._load(),this._poll=b({loadFn:()=>this._load(),intervalMs:3e4,element:this,immediate:!1})}disconnectedCallback(){super.disconnectedCallback(),this._poll&&(this._poll.stop(),this._poll=null)}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=g({baseUrl:i}),this._load()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||(typeof window<"u"?window.location.origin:"");this._api=g({baseUrl:e})}async _load(){this._loading=!0,this._error=null;let e=this._api;try{let t=await e.get("/api/council/transcripts?limit=10");if(e!==this._api)return;this._transcripts=Array.isArray(t&&t.transcripts)?t.transcripts:[]}catch(t){if(e!==this._api)return;this._error=t&&t.message?t.message:String(t),this._transcripts=[]}try{let t=await e.get("/api/council/transcripts?limit=20&type_prefix=claude_hook_");if(e!==this._api)return;this._hookEvents=Array.isArray(t&&t.hook_events)?t.hook_events:[]}catch{if(e!==this._api)return;this._hookEvents=[]}finally{this._loading=!1,this.render()}}_escapeHtml(e){return e==null?"":String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}_formatTimestamp(e){if(!e)return"--";try{let t=new Date(e);return isNaN(t.getTime())?e:t.toLocaleString()}catch{return e}}_truncate(e,t){if(!e)return"";let i=String(e);return i.length>t?i.slice(0,t)+"...":i}_verdictBadgeHtml(e){let t=String(e||"").toUpperCase();return t==="APPROVE"?'<span class="ct-badge ct-badge-approve">APPROVE</span>':t==="REJECT"?'<span class="ct-badge ct-badge-reject">REJECT</span>':t==="CANNOT_VALIDATE"?'<span class="ct-badge ct-badge-cannot">CANNOT_VALIDATE</span>':'<span class="ct-badge ct-badge-unknown">'+this._escapeHtml(t||"UNKNOWN")+"</span>"}_outcomeBadgeHtml(e){let t=String(e||"").toUpperCase();return t==="APPROVED"?'<span class="ct-badge ct-badge-approve">APPROVED</span>':t==="REJECTED"?'<span class="ct-badge ct-badge-reject">REJECTED</span>':t==="BLOCKED_BY_GATE"?'<span class="ct-badge ct-badge-blocked">BLOCKED BY GATE</span>':'<span class="ct-badge ct-badge-unknown">'+this._escapeHtml(t||"UNKNOWN")+"</span>"}_voterRowHtml(e,t){let i=e.is_contrarian===!0,a=i&&t===!0,s="ct-voter-row";i&&(s+=" ct-voter-contrarian"),a&&(s+=" ct-voter-flipped");let r=this._escapeHtml(e.name||"unknown"),o=this._verdictBadgeHtml(e.verdict),n=this._escapeHtml(this._truncate(e.reasoning,300)),l="",c="";a?(l='<span class="ct-badge ct-badge-override">OVERRIDE</span>',c=`<div class="ct-flip-caption">Devil's Advocate flipped this outcome</div>`):i&&e.triggered&&(l=`<span class="ct-badge ct-badge-da">DEVIL'S ADVOCATE</span>`);let p="";i&&Array.isArray(e.challenges)&&e.challenges.length>0&&(p='<ul class="ct-challenges">'+e.challenges.map(h=>"<li>"+this._escapeHtml(String(h))+"</li>").join("")+"</ul>");let u="";return Array.isArray(e.issues)&&e.issues.length>0&&(u='<ul class="ct-issues">'+e.issues.map(h=>{let k=this._escapeHtml(h.severity||""),x=this._escapeHtml(h.description||"");return'<li><span class="ct-issue-sev ct-issue-sev-'+k.toLowerCase()+'">'+k+"</span> "+x+"</li>"}).join("")+"</ul>"),'<div class="'+s+'"><div class="ct-voter-header"><span class="ct-voter-name">'+r+"</span>"+o+l+"</div>"+(n?'<div class="ct-voter-reason">'+n+"</div>":"")+p+u+c+"</div>"}_transcriptCardHtml(e){let t=this._escapeHtml(String(e.iteration||"--")),i=this._escapeHtml(this._formatTimestamp(e.timestamp)),a=this._escapeHtml(this._truncate(e.task_or_prd,200)),s=this._outcomeBadgeHtml(e.outcome),r=Array.isArray(e.voters)?e.voters:[],o=r.filter(h=>!h.is_contrarian),n=r.filter(h=>h.is_contrarian),l=o.map(h=>this._voterRowHtml(h,!1)).join(""),c="";e.contrarian_triggered&&(c='<div class="ct-contrarian-section"><div class="ct-section-label">Anti-Sycophancy Check</div>'+n.map(k=>this._voterRowHtml(k,e.contrarian_flipped)).join("")+"</div>");let p=typeof e.approve_count=="number"?e.approve_count:"--",u=typeof e.reject_count=="number"?e.reject_count:"--",m=typeof e.threshold=="number"?e.threshold:"--";return'<div class="ct-card"><div class="ct-card-header"><div class="ct-card-meta"><span class="ct-iter-label">Iteration '+t+'</span><span class="ct-ts">'+i+"</span></div>"+s+"</div>"+(a?'<div class="ct-prd-preview">'+a+"</div>":"")+'<div class="ct-tally">Approve: '+p+" · Reject: "+u+" · Threshold: "+m+'</div><div class="ct-voters">'+l+"</div>"+c+"</div>"}render(){let e=this.shadowRoot||this;if(!e)return;let t=`
|
|
14176
|
+
`,i="";this._loading&&this._items.length===0?i='<div class="esc-empty">Loading escalations...</div>':this._error?i='<div class="esc-error">Failed to load escalations: '+this._escapeHtml(this._error)+"</div>":!this._items||this._items.length===0?i='<div class="esc-empty">No handoff notes yet. If a build needs your attention, its notes will appear here.</div>':i='<div class="esc-list">'+this._items.map(n=>{let l=this._escapeHtml(n.filename||""),c=this._escapeHtml(this._formatSize(n.size_bytes)),p=this._escapeHtml(this._formatDate(n.modified_at));return'<div class="esc-item" data-filename="'+l+'"><span class="esc-name">'+l+'</span><span class="esc-meta">'+c+" · "+p+"</span></div>"}).join("")+"</div>";let a="";if(this._activeFile){let o=this._escapeHtml(this._activeFile),n;this._activeBodyError?n='<div class="esc-error">Failed to load: '+this._escapeHtml(this._activeBodyError)+"</div>":this._activeBody===null?n='<div class="esc-body">Loading '+o+"...</div>":n='<div class="esc-body md-body">'+C(this._activeBody)+"</div>",a='<div class="esc-viewer"><div class="esc-viewer-header"><span class="esc-name">'+o+'</span><button class="esc-close-btn" data-action="close">Close</button></div>'+n+"</div>"}e.innerHTML=t+'<div class="esc-wrapper"><div class="esc-explain">Handoff/escalation documents written under .loki/escalations/. Click an entry to view its contents.</div>'+i+a+"</div>",e.querySelectorAll(".esc-item").forEach(o=>{o.addEventListener("click",()=>{let n=o.getAttribute("data-filename");n&&this._openFile(n)})});let r=e.querySelector('.esc-close-btn[data-action="close"]');r&&r.addEventListener("click",()=>this._closeFile())}};typeof customElements<"u"&&!customElements.get("loki-escalations")&&customElements.define("loki-escalations",Ee);var Ce=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._transcripts=[],this._hookEvents=[],this._hookError=null,this._loading=!1,this._error=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._load(),this._poll=b({loadFn:()=>this._load(),intervalMs:3e4,element:this,immediate:!1})}disconnectedCallback(){super.disconnectedCallback(),this._poll&&(this._poll.stop(),this._poll=null)}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=g({baseUrl:i}),this._load()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||(typeof window<"u"?window.location.origin:"");this._api=g({baseUrl:e})}async _load(){this._loading=!0,this._error=null;let e=this._api;try{let t=await e.get("/api/council/transcripts?limit=10");if(e!==this._api)return;this._transcripts=Array.isArray(t&&t.transcripts)?t.transcripts:[]}catch(t){if(e!==this._api)return;this._error=t&&t.message?t.message:String(t),this._transcripts=[]}try{let t=await e.get("/api/council/transcripts?limit=20&type_prefix=claude_hook_");if(e!==this._api)return;this._hookEvents=Array.isArray(t&&t.hook_events)?t.hook_events:[],this._hookError=null}catch(t){if(e!==this._api)return;this._hookEvents=[],this._hookError=t&&t.message?t.message:String(t)}finally{this._loading=!1,this.render()}}_escapeHtml(e){return e==null?"":String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}_formatTimestamp(e){if(!e)return"--";try{let t=new Date(e);return isNaN(t.getTime())?e:t.toLocaleString()}catch{return e}}_truncate(e,t){if(!e)return"";let i=String(e);return i.length>t?i.slice(0,t)+"...":i}_verdictBadgeHtml(e){let t=String(e||"").toUpperCase();return t==="APPROVE"?'<span class="ct-badge ct-badge-approve">APPROVE</span>':t==="REJECT"?'<span class="ct-badge ct-badge-reject">REJECT</span>':t==="CANNOT_VALIDATE"?'<span class="ct-badge ct-badge-cannot">CANNOT_VALIDATE</span>':'<span class="ct-badge ct-badge-unknown">'+this._escapeHtml(t||"UNKNOWN")+"</span>"}_outcomeBadgeHtml(e){let t=String(e||"").toUpperCase();return t==="APPROVED"?'<span class="ct-badge ct-badge-approve">APPROVED</span>':t==="REJECTED"?'<span class="ct-badge ct-badge-reject">REJECTED</span>':t==="BLOCKED_BY_GATE"?'<span class="ct-badge ct-badge-blocked">BLOCKED BY GATE</span>':'<span class="ct-badge ct-badge-unknown">'+this._escapeHtml(t||"UNKNOWN")+"</span>"}_voterRowHtml(e,t){let i=e.is_contrarian===!0,a=i&&t===!0,s="ct-voter-row";i&&(s+=" ct-voter-contrarian"),a&&(s+=" ct-voter-flipped");let r=this._escapeHtml(e.name||"unknown"),o=this._verdictBadgeHtml(e.verdict),n=this._escapeHtml(this._truncate(e.reasoning,300)),l="",c="";a?(l='<span class="ct-badge ct-badge-override">OVERRIDE</span>',c=`<div class="ct-flip-caption">Devil's Advocate flipped this outcome</div>`):i&&e.triggered&&(l=`<span class="ct-badge ct-badge-da">DEVIL'S ADVOCATE</span>`);let p="";i&&Array.isArray(e.challenges)&&e.challenges.length>0&&(p='<ul class="ct-challenges">'+e.challenges.map(h=>"<li>"+this._escapeHtml(String(h))+"</li>").join("")+"</ul>");let u="";return Array.isArray(e.issues)&&e.issues.length>0&&(u='<ul class="ct-issues">'+e.issues.map(h=>{let k=this._escapeHtml(h.severity||""),x=this._escapeHtml(h.description||"");return'<li><span class="ct-issue-sev ct-issue-sev-'+k.toLowerCase()+'">'+k+"</span> "+x+"</li>"}).join("")+"</ul>"),'<div class="'+s+'"><div class="ct-voter-header"><span class="ct-voter-name">'+r+"</span>"+o+l+"</div>"+(n?'<div class="ct-voter-reason">'+n+"</div>":"")+p+u+c+"</div>"}_transcriptCardHtml(e){let t=this._escapeHtml(String(e.iteration||"--")),i=this._escapeHtml(this._formatTimestamp(e.timestamp)),a=this._escapeHtml(this._truncate(e.task_or_prd,200)),s=this._outcomeBadgeHtml(e.outcome),r=Array.isArray(e.voters)?e.voters:[],o=r.filter(h=>!h.is_contrarian),n=r.filter(h=>h.is_contrarian),l=o.map(h=>this._voterRowHtml(h,!1)).join(""),c="";e.contrarian_triggered&&(c='<div class="ct-contrarian-section"><div class="ct-section-label">Anti-Sycophancy Check</div>'+n.map(k=>this._voterRowHtml(k,e.contrarian_flipped)).join("")+"</div>");let p=typeof e.approve_count=="number"?e.approve_count:"--",u=typeof e.reject_count=="number"?e.reject_count:"--",m=typeof e.threshold=="number"?e.threshold:"--";return'<div class="ct-card"><div class="ct-card-header"><div class="ct-card-meta"><span class="ct-iter-label">Iteration '+t+'</span><span class="ct-ts">'+i+"</span></div>"+s+"</div>"+(a?'<div class="ct-prd-preview">'+a+"</div>":"")+'<div class="ct-tally">Approve: '+p+" · Reject: "+u+" · Threshold: "+m+'</div><div class="ct-voters">'+l+"</div>"+c+"</div>"}render(){let e=this.shadowRoot||this;if(!e)return;let t=`
|
|
14167
14177
|
<style>
|
|
14168
14178
|
:host { display: block; margin-top: 24px; }
|
|
14169
14179
|
.ct-wrapper {
|
|
@@ -14332,7 +14342,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
14332
14342
|
.ct-badge-da { background: #fdf3d4; color: #8a6c0e; }
|
|
14333
14343
|
.ct-badge-unknown { background: var(--bg-secondary, #F8F4F0); color: var(--text-muted, #939084); }
|
|
14334
14344
|
</style>
|
|
14335
|
-
`,i="";this._loading&&this._transcripts.length===0?i='<div class="ct-empty">Loading council transcripts...</div>':this._error?i='<div class="ct-error">Failed to load transcripts: '+this._escapeHtml(this._error)+"</div>":!this._transcripts||this._transcripts.length===0?i='<div class="ct-empty">No review rounds recorded yet. Transcripts appear after the first completion vote.</div>':i='<div class="ct-list">'+this._transcripts.map(s=>this._transcriptCardHtml(s)).join("")+"</div>",e.innerHTML=t+'<div class="ct-wrapper"><h3 class="ct-heading">Council Transcripts</h3><div class="ct-explain">Per-iteration voting records from .loki/council/transcripts/. Polls every 30 seconds.</div>'+i+this._hookEventsHtml()+"</div>"}_hookEventsHtml(){let e=Array.isArray(this._hookEvents)?this._hookEvents:[],t;return e.length===0?t='<div class="ct-empty">No live tool activity yet -- Claude hook events stream here while a run is active.</div>':t='<div class="ct-voters">'+e.slice(0,20).map(a=>{let s=this._escapeHtml(a.type||a.event||"event"),r=this._escapeHtml(this._formatTimestamp(a.timestamp||a.ts)),o=this._escapeHtml(this._truncate(a.tool||a.message||a.summary||(a.data?JSON.stringify(a.data):""),120));return'<div class="ct-voter-row"><span class="ct-iter-label">'+s+'</span> <span class="ct-ts">'+r+"</span>"+(o?'<div class="ct-prd-preview">'+o+"</div>":"")+"</div>"}).join("")+"</div>",'<h3 class="ct-heading" style="margin-top:24px;">Live Tool Activity</h3><div class="ct-explain">Claude hook events (PreToolUse / PostToolUse / Stop) streamed from .loki/events.jsonl. Lets you watch background tool calls as they run.</div>'+t}};typeof customElements<"u"&&!customElements.get("loki-council-transcripts")&&customElements.define("loki-council-transcripts",Ce);var
|
|
14345
|
+
`,i="";this._loading&&this._transcripts.length===0?i='<div class="ct-empty">Loading council transcripts...</div>':this._error?i='<div class="ct-error">Failed to load transcripts: '+this._escapeHtml(this._error)+"</div>":!this._transcripts||this._transcripts.length===0?i='<div class="ct-empty">No review rounds recorded yet. Transcripts appear after the first completion vote.</div>':i='<div class="ct-list">'+this._transcripts.map(s=>this._transcriptCardHtml(s)).join("")+"</div>",e.innerHTML=t+'<div class="ct-wrapper"><h3 class="ct-heading">Council Transcripts</h3><div class="ct-explain">Per-iteration voting records from .loki/council/transcripts/. Polls every 30 seconds.</div>'+i+this._hookEventsHtml()+"</div>"}_hookEventsHtml(){let e=Array.isArray(this._hookEvents)?this._hookEvents:[],t;return this._hookError?t='<div class="ct-error">Could not load hook events: '+this._escapeHtml(this._hookError)+"</div>":e.length===0?t='<div class="ct-empty">No live tool activity yet -- Claude hook events stream here while a run is active.</div>':t='<div class="ct-voters">'+e.slice(0,20).map(a=>{let s=this._escapeHtml(a.type||a.event||"event"),r=this._escapeHtml(this._formatTimestamp(a.timestamp||a.ts)),o=this._escapeHtml(this._truncate(a.tool||a.message||a.summary||(a.data?JSON.stringify(a.data):""),120));return'<div class="ct-voter-row"><span class="ct-iter-label">'+s+'</span> <span class="ct-ts">'+r+"</span>"+(o?'<div class="ct-prd-preview">'+o+"</div>":"")+"</div>"}).join("")+"</div>",'<h3 class="ct-heading" style="margin-top:24px;">Live Tool Activity</h3><div class="ct-explain">Claude hook events (PreToolUse / PostToolUse / Stop) streamed from .loki/events.jsonl. Lets you watch background tool calls as they run.</div>'+t}};typeof customElements<"u"&&!customElements.get("loki-council-transcripts")&&customElements.define("loki-council-transcripts",Ce);var ii=[{id:"overview",label:"Overview"},{id:"architecture",label:"Architecture"},{id:"modules",label:"Key Modules"},{id:"data-flow",label:"Data Flow"},{id:"ask",label:"Ask"}],Se=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._activeTab="overview",this._loading=!1,this._error=null,this._api=null,this._meta=null,this._metaPromise=null,this._sectionCache={},this._sectionState={},this._question="",this._answer=null,this._asking=!1,this._askError=null,this._mermaid=null,this._mermaidPromise=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadMeta()}disconnectedCallback(){super.disconnectedCallback&&super.disconnectedCallback(),this._disconnected=!0}attributeChangedCallback(e,t,i){e==="api-url"&&this._api&&(this._api=g({baseUrl:i}))}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}_loadMeta(){this._loading=!0,this._error=null,this.render();let e=this._api;return this._metaPromise=(async()=>{try{let t=await e._get("/api/wiki");if(e!==this._api)return;this._meta=t}catch(t){if(e!==this._api)return;this._error=t&&t.message?t.message:"Failed to load wiki"}finally{this._loading=!1,this.render()}})(),this._metaPromise}async _loadSection(e){if(this._sectionCache[e])return this._sectionState[e]=this._sectionCache[e].error?"error":"loaded",this._sectionCache[e];this._sectionState[e]="loading";let t=this._api;try{let i=await t._get(`/api/wiki/${encodeURIComponent(e)}`);return t!==this._api?this._sectionCache[e]||{error:"stale"}:(this._sectionCache[e]=i,this._sectionState[e]=i&&i.error?"error":"loaded",i)}catch(i){if(t!==this._api)return this._sectionCache[e]||{error:"stale"};let a={error:i&&i.message||"load failed"};return this._sectionCache[e]=a,this._sectionState[e]="error",a}}async _selectTab(e){if(this._activeTab=e,e!=="architecture"&&e!=="modules"&&e!=="data-flow"){this.render();return}if(this._sectionCache[e]){this.render();return}if(this._sectionState[e]="loading",this.render(),this._metaPromise)try{await this._metaPromise}catch{}if(!(this._disconnected||this._activeTab!==e)){if(!this._meta||!this._meta.generated){delete this._sectionState[e],this.render();return}await this._loadSection(e),!(this._disconnected||this._activeTab!==e)&&this.render()}}_ensureMermaid(){return this._mermaid?Promise.resolve(this._mermaid):this._mermaidPromise?this._mermaidPromise:(this._mermaidPromise=(async()=>{try{if(typeof window<"u"&&window.mermaid)return this._mermaid=window.mermaid,this._mermaid;if(typeof window>"u"||typeof document>"u")return null;let t=`${this._api&&this._api.baseUrl||window.location.origin}/assets/mermaid.min.js`;return await new Promise((i,a)=>{let s=document.querySelector("script[data-loki-mermaid]");if(s){s.addEventListener("load",i,{once:!0}),s.addEventListener("error",a,{once:!0}),window.mermaid&&i();return}let r=document.createElement("script");r.src=t,r.async=!0,r.setAttribute("data-loki-mermaid","1"),r.addEventListener("load",i,{once:!0}),r.addEventListener("error",()=>a(new Error("mermaid load failed")),{once:!0}),document.head.appendChild(r)}),this._mermaid=typeof window<"u"&&window.mermaid||null,this._mermaid}catch{return null}})(),this._mermaidPromise)}async _maybeRenderDiagram(e){let t=this._sectionCache[e],i=this._diagramSource(t);if(!i)return;let a;try{a=await this._ensureMermaid()}catch{a=null}if(!(!a||this._disconnected||this._activeTab!==e))try{a.initialize({startOnLoad:!1,securityLevel:"strict",theme:this._mermaidTheme(),flowchart:{htmlLabels:!1,useMaxWidth:!0},deterministicIds:!0}),typeof a.parse=="function"&&await a.parse(i);let s=`wiki-mmd-${e}-${Date.now()}`,r=await a.render(s,i),o=r&&(r.svg||r);if(typeof o!="string"||o.indexOf("<svg")===-1||this._disconnected||this._activeTab!==e||!this.shadowRoot)return;let n=this.shadowRoot.getElementById("wiki-diagram");n&&(n.innerHTML=o)}catch{}}_mermaidTheme(){return(this.getAttribute("theme")||typeof document<"u"&&document.documentElement.getAttribute("data-loki-theme")||"").toLowerCase().includes("dark")?"dark":"neutral"}async _ask(){let e=(this._question||"").trim();if(!e)return;this._asking=!0,this._askError=null,this._answer=null,this.render();let t=this._api;try{let i=await t._post("/api/wiki/ask",{question:e},{timeout:2e5});if(t!==this._api)return;this._answer=i}catch(i){if(t!==this._api)return;this._askError=i&&i.message?i.message:"Ask failed"}finally{this._asking=!1,this.render()}}_esc(e){return String(e??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}_renderCitations(e){return!e||!e.length?"":`<div class="cites"><strong>Sources:</strong><ul>${e.map(i=>`<li><code>${this._esc(i.file)}:${this._esc(i.line)}</code></li>`).join("")}</ul></div>`}_renderNotGenerated(){return`<div class="es">
|
|
14336
14346
|
<div class="es-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg></div>
|
|
14337
14347
|
<div class="es-title">No wiki generated yet</div>
|
|
14338
14348
|
<div class="es-desc">Generate a cited codebase wiki to browse architecture, modules, and data flow. Every section links to real file:line locations.</div>
|
|
@@ -14371,7 +14381,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
14371
14381
|
<div class="es-title">Couldn't load wiki</div>
|
|
14372
14382
|
<div class="es-desc">${this._esc(e)}</div>
|
|
14373
14383
|
<button class="es-cta" id="wiki-retry-btn">Retry</button>
|
|
14374
|
-
</div>`}_renderBody(){if(this._loading)return'<div class="es-loading"><span class="es-spinner"></span> Loading wiki...</div>';if(this._error)return this._renderError(this._error);switch(this._activeTab){case"overview":return this._renderOverview();case"architecture":return this._renderSection("architecture");case"modules":return this._renderSection("modules");case"data-flow":return this._renderSection("data-flow");case"ask":return this._renderAsk();default:return this._renderOverview()}}render(){if(!this.shadowRoot)return;let e=
|
|
14384
|
+
</div>`}_renderBody(){if(this._loading)return'<div class="es-loading"><span class="es-spinner"></span> Loading wiki...</div>';if(this._error)return this._renderError(this._error);switch(this._activeTab){case"overview":return this._renderOverview();case"architecture":return this._renderSection("architecture");case"modules":return this._renderSection("modules");case"data-flow":return this._renderSection("data-flow");case"ask":return this._renderAsk();default:return this._renderOverview()}}render(){if(!this.shadowRoot)return;let e=ii.map(o=>`<button class="tab ${o.id===this._activeTab?"active":""}"
|
|
14375
14385
|
data-tab="${o.id}">${this._esc(o.label)}</button>`).join("");this.shadowRoot.innerHTML=`
|
|
14376
14386
|
<style>
|
|
14377
14387
|
${this.getBaseStyles()}
|
|
@@ -14489,7 +14499,7 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
14489
14499
|
</style>
|
|
14490
14500
|
<div class="tabs">${e}</div>
|
|
14491
14501
|
<div class="content">${this._renderBody()}</div>
|
|
14492
|
-
`,this.shadowRoot.querySelectorAll(".tab").forEach(o=>{o.addEventListener("click",()=>this._selectTab(o.dataset.tab))});let t=this.shadowRoot.getElementById("wiki-q");t&&(t.addEventListener("input",o=>{this._question=o.target.value}),t.addEventListener("keydown",o=>{o.key==="Enter"&&this._ask()}));let i=this.shadowRoot.getElementById("wiki-ask-btn");i&&i.addEventListener("click",()=>this._ask());let a=this.shadowRoot.getElementById("wiki-gen-copy");a&&a.addEventListener("click",()=>this._copyGenerateCmd(a));let s=this.shadowRoot.getElementById("wiki-retry-btn");s&&s.addEventListener("click",()=>{this._sectionCache={},this._sectionState={},this._loadMeta()});let r=this._activeTab;(r==="architecture"||r==="data-flow")&&this._sectionCache[r]&&!this._sectionCache[r].error&&this.shadowRoot.getElementById("wiki-diagram")&&this._maybeRenderDiagram(r)}_copyGenerateCmd(e){let t="loki wiki generate",i=()=>{let a=e.innerHTML;e.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>',setTimeout(()=>{e.innerHTML=a},1500)};navigator.clipboard&&navigator.clipboard.writeText&&navigator.clipboard.writeText(t).then(i).catch(()=>{})}};customElements.get("loki-wiki-browser")||customElements.define("loki-wiki-browser",Se);var ft={prd:"PRD file",spec:"Generated spec",issue:"GitHub issue",brief:"One-line brief","codebase-analysis":"Codebase analysis",none:"No spec yet",unknown:"Unknown spec"},
|
|
14502
|
+
`,this.shadowRoot.querySelectorAll(".tab").forEach(o=>{o.addEventListener("click",()=>this._selectTab(o.dataset.tab))});let t=this.shadowRoot.getElementById("wiki-q");t&&(t.addEventListener("input",o=>{this._question=o.target.value}),t.addEventListener("keydown",o=>{o.key==="Enter"&&this._ask()}));let i=this.shadowRoot.getElementById("wiki-ask-btn");i&&i.addEventListener("click",()=>this._ask());let a=this.shadowRoot.getElementById("wiki-gen-copy");a&&a.addEventListener("click",()=>this._copyGenerateCmd(a));let s=this.shadowRoot.getElementById("wiki-retry-btn");s&&s.addEventListener("click",()=>{this._sectionCache={},this._sectionState={},this._loadMeta()});let r=this._activeTab;(r==="architecture"||r==="data-flow")&&this._sectionCache[r]&&!this._sectionCache[r].error&&this.shadowRoot.getElementById("wiki-diagram")&&this._maybeRenderDiagram(r)}_copyGenerateCmd(e){let t="loki wiki generate",i=()=>{let a=e.innerHTML;e.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>',setTimeout(()=>{e.innerHTML=a},1500)};navigator.clipboard&&navigator.clipboard.writeText&&navigator.clipboard.writeText(t).then(i).catch(()=>{})}};customElements.get("loki-wiki-browser")||customElements.define("loki-wiki-browser",Se);var ft={prd:"PRD file",spec:"Generated spec",issue:"GitHub issue",brief:"One-line brief","codebase-analysis":"Codebase analysis",none:"No spec yet",unknown:"Unknown spec"},Ae=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._api=null,this._spec=null,this._history=null,this._loading=!1,this._error=null,this._historyError=null,this._historyOpen=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._load()}attributeChangedCallback(e,t,i){e==="api-url"&&this._api&&(this._api=g({baseUrl:i}))}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e})}async _load(){let e=this._api;this._loading=!0,this._error=null,this.render();try{let t=await e._get("/api/spec");if(e!==this._api)return;this._spec=t}catch(t){if(e!==this._api)return;this._error=t&&t.message?t.message:"Failed to load spec"}finally{e===this._api&&(this._loading=!1,this.render())}try{let t=await e._get("/api/spec/history");if(e!==this._api)return;this._history=t&&Array.isArray(t.history)?t.history:[]}catch(t){if(e!==this._api)return;this._historyError=t&&t.message?t.message:"Failed to load history",this._history=[]}this.render()}_esc(e){return String(e??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}_when(e){if(!e)return"unknown time";let t=new Date(e);if(isNaN(t.getTime()))return this._esc(e);try{return t.toLocaleString()}catch{return this._esc(e)}}_typeLabel(e){return ft[e]||ft.unknown}_typeBadge(e){return`<span class="badge badge-${this._esc(e)}">${this._esc(this._typeLabel(e))}</span>`}_renderActive(){if(this._loading)return'<div class="es-loading"><span class="es-spinner"></span> Loading active spec...</div>';if(this._error)return this._renderError(this._error);let e=this._spec;if(!e||!e.type||e.type==="none")return this._renderEmpty();let t=this._typeBadge(e.type),i="",a="";if(e.type==="prd"||e.type==="spec"){e.path&&(i=`<code class="src">${this._esc(e.path)}</code>`);let s=e.content||"";s.trim()?a=`<div class="body md-body">${C(s)}</div>`+(e.truncated?'<p class="dim">Preview truncated -- see the full file on disk.</p>':""):a='<p class="dim">No content available.</p>'}else if(e.type==="issue"){i=e.ref?`<code class="src">${this._esc(e.ref)}</code>`:"";let r=e.title?`<p class="issue-title">${this._esc(e.title)}</p>`:"",o=(e.body||"").trim()?`<div class="body md-body">${C(e.body)}</div>`+(e.truncated?'<p class="dim">Preview truncated.</p>':""):"";a=`${r}${o}`}else if(e.type==="brief"){let s=(e.text||"").trim();a=s?`<pre class="body brief">${this._esc(s)}</pre>`+(e.truncated?'<p class="dim">Preview truncated.</p>':""):'<p class="dim">No brief recorded.</p>'}else e.type==="codebase-analysis"?a='<p class="dim">No explicit spec. Loki is building from an analysis of the existing codebase.</p>':a='<p class="dim">The spec source could not be resolved.</p>';return`<div class="active">
|
|
14493
14503
|
<div class="active-head">
|
|
14494
14504
|
<span class="active-label">Building from</span>
|
|
14495
14505
|
${t}
|
|
@@ -14591,13 +14601,13 @@ var LokiDashboard=(()=>{var Le=Object.defineProperty;var kt=Object.getOwnPropert
|
|
|
14591
14601
|
</style>
|
|
14592
14602
|
<div class="active-wrap">${this._renderActive()}</div>
|
|
14593
14603
|
${this._error||this._spec&&this._spec.type==="none"?"":this._renderHistory()}
|
|
14594
|
-
`;let e=this.shadowRoot.getElementById("spec-retry-btn");e&&e.addEventListener("click",()=>this._load());let t=this.shadowRoot.getElementById("hist-toggle");t&&t.addEventListener("click",()=>{this._historyOpen=!this._historyOpen,this.render()})}};customElements.get("loki-spec-panel")||customElements.define("loki-spec-panel",Te);(function(){"use strict";if(typeof window>"u"||typeof customElements>"u")return;var d={open:'<circle cx="178" cy="214" r="7" class="fillInk"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="180.5" cy="211.5" r="2" class="fillHi"/><circle cx="246.5" cy="211.5" r="2" class="fillHi"/>',happy:'<path class="ink" d="M171 216c4-6 10-6 14 0"/><path class="ink" d="M237 216c4-6 10-6 14 0"/>',lookUp:'<circle cx="178" cy="214" r="7" class="fillInk"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="180" cy="210" r="2.4" class="fillHi"/><circle cx="246" cy="210" r="2.4" class="fillHi"/>',wide:'<circle cx="178" cy="213" r="8.5" class="fillInk"/><circle cx="244" cy="213" r="8.5" class="fillInk"/><circle cx="181" cy="210" r="2.6" class="fillHi"/><circle cx="247" cy="210" r="2.6" class="fillHi"/>',focused:'<path class="inkBold" d="M170 214h16"/><path class="inkBold" d="M236 214h16"/>',closed:'<path class="ink" d="M170 214c4 5 10 5 14 0"/><path class="ink" d="M236 214c4 5 10 5 14 0"/>',worried:'<circle cx="178" cy="216" r="6" class="fillInk"/><circle cx="244" cy="216" r="6" class="fillInk"/><circle cx="180" cy="213.5" r="1.8" class="fillHi"/><circle cx="246" cy="213.5" r="1.8" class="fillHi"/>',wink:'<path class="ink" d="M171 214c4-5 10-5 14 0"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="246.5" cy="211.5" r="2" class="fillHi"/>'},e={none:"",raised:'<path class="inkThin" d="M168 198c5-3 12-3 17 0"/><path class="inkThin" d="M237 198c5-3 12-3 17 0"/>',furrow:'<path class="inkThin" d="M168 199l16 3"/><path class="inkThin" d="M254 199l-16 3"/>',worried:'<path class="inkThin" d="M168 201l16-4"/><path class="inkThin" d="M254 201l-16-4"/>'},t={smile:'<path class="ink" d="M192 244c12 12 26 12 38 0"/>',openSmile:'<path class="fillInk" d="M194 243c8 16 26 16 34 0c-10 6-24 6-34 0z"/>',flat:'<path class="ink" d="M198 248h26"/>',o:'<ellipse cx="211" cy="248" rx="6" ry="7" class="ink"/>',frown:'<path class="ink" d="M192 250c12-12 26-12 38 0"/>',soft:'<path class="ink" d="M196 246c9 7 19 7 28 0"/>',proud:'<path class="ink" d="M194 245c10 9 24 9 32 -2"/>'},i={none:"",wave:'<g class="prop-wave"><path class="ink" d="M318 250c14-2 26 6 28 20"/><circle cx="348" cy="276" r="9" class="fillPaper ink"/></g>',zzz:'<g class="ink prop-zzz"><text x="300" y="150" class="zzz z1">z</text><text x="322" y="128" class="zzz z2">z</text><text x="344" y="110" class="zzz z3">z</text></g>',thoughtDots:'<g class="prop-think"><circle cx="300" cy="170" r="4" class="fillInk d1"/><circle cx="316" cy="150" r="5.5" class="fillInk d2"/><circle cx="336" cy="126" r="7" class="fillInk d3"/></g>',magnifier:'<g class="prop-magnifier"><circle cx="332" cy="250" r="18" class="fillGlass ink"/><path class="inkBold" d="M345 263l16 16"/><path class="inkThin" d="M325 244a10 10 0 0 1 8 4"/></g>',check:'<g class="prop-check"><circle cx="332" cy="246" r="17" class="fillSeal"/><path class="checkMark" d="M324 246l6 6 11 -13"/></g>',confetti:'<g class="prop-confetti"><rect x="110" y="120" width="7" height="7" class="fillInk c1" transform="rotate(20 113 123)"/><rect x="300" y="110" width="7" height="7" class="fillGlow c2" transform="rotate(-15 303 113)"/><rect x="140" y="96" width="6" height="6" class="fillSeal c3"/><circle cx="330" cy="150" r="4" class="fillInk c4"/><circle cx="96" cy="170" r="4" class="fillGlow c5"/><rect x="270" y="140" width="6" height="6" class="fillInk c6" transform="rotate(40 273 143)"/><path class="inkViolet c7" d="M210 92l0 12M204 98l12 0"/></g>',parcel:'<g class="prop-parcel"><rect x="316" y="244" width="40" height="34" rx="3" class="fillPaper ink"/><path class="ink" d="M316 256h40"/><path class="inkViolet" d="M336 244v34"/></g>',spinner:'<g class="prop-spinner"><path class="inkBold spin" d="M332 230a20 20 0 1 1 -14 6"/></g>'},a={idle:{eyes:"open",mouth:"smile",motion:"breathe",label:"Loki, resting",blink:!0},happy:{eyes:"happy",mouth:"smile",motion:"bob",label:"Loki, happy"},thinking:{eyes:"lookUp",brow:"raised",mouth:"flat",prop:"thoughtDots",motion:"wiggle",label:"Loki, thinking"},building:{eyes:"focused",brow:"furrow",mouth:"flat",motion:"work",label:"Loki, building"},reviewing:{eyes:"focused",brow:"furrow",mouth:"soft",prop:"magnifier",motion:"inspect",label:"Loki, reviewing the work"},verifying:{eyes:"open",mouth:"soft",prop:"check",motion:"bob",label:"Loki, verifying",blink:!0},celebrating:{eyes:"wide",mouth:"openSmile",prop:"confetti",motion:"bounce",label:"Loki, celebrating a verified result"},proud:{eyes:"happy",mouth:"proud",prop:"check",motion:"bob",label:"Loki, proud"},waving:{eyes:"wink",mouth:"smile",prop:"wave",motion:"wave",label:"Loki, waving hello"},sleeping:{eyes:"closed",mouth:"soft",prop:"zzz",motion:"sleep",label:"Loki, sleeping"},concerned:{eyes:"worried",brow:"worried",mouth:"frown",motion:"shake",label:"Loki, something went wrong"},shipping:{eyes:"happy",mouth:"smile",prop:"parcel",motion:"launch",label:"Loki, shipping"},loading:{eyes:"open",mouth:"flat",prop:"spinner",motion:"breathe",label:"Loki, loading",blink:!0},curious:{eyes:"lookUp",brow:"raised",mouth:"o",prop:"thoughtDots",motion:"tilt",label:"Loki, curious"},blinking:{eyes:"open",mouth:"smile",motion:"breathe",label:"Loki",blink:!0},walking:{eyes:"open",mouth:"soft",motion:"walk",label:"Loki, walking",blink:!0},running:{eyes:"focused",mouth:"soft",motion:"run",label:"Loki, running"}},s="idle";function r(){return'<g class="legs"><path class="ink leg legL" d="M168 318v18"/><path class="ink foot footL" d="M158 336h20"/><path class="ink leg legR" d="M252 318v18"/><path class="ink foot footR" d="M242 336h20"/></g>'}function o(u,m,h){return m&&Object.prototype.hasOwnProperty.call(u,m)?u[m]:h||""}function n(u){var m=u.blink?" blink":"";return'<svg class="figure" viewBox="0 0 420 380" aria-hidden="true" focusable="false"><ellipse cx="210" cy="338" rx="120" ry="16" class="fillInkWash"/><g class="creature">'+r()+'<path class="fillPaper ink" d="M120 132c0-22 16-36 40-37 38-2 82-2 120 0 24 1 40 15 40 38v118c0 24-16 39-41 40-40 2-78 2-118 0-25-1-41-16-41-40z"/><path class="inkThin" d="M124 168c54-4 118-4 172 0"/><circle cx="146" cy="150" r="4.5" class="inkViolet"/><circle cx="164" cy="150" r="4.5" class="inkThinDot"/><circle cx="182" cy="150" r="4.5" class="inkThinDot"/><circle cx="170" cy="232" r="9" class="fillGlow"/><circle cx="252" cy="232" r="9" class="fillGlow"/>'+o(e,u.brow,"")+'<g class="eyes'+m+'">'+o(d,u.eyes,d.open)+"</g>"+o(t,u.mouth,t.smile)+'<path class="inkViolet" d="M150 280h120"/><path class="inkThin" d="M150 296h84"/>'+o(i,u.prop,"")+"</g></svg>"}var l=[":host{display:inline-block;line-height:0;","--lm-ink:var(--color-ink,#553de9);","--lm-ink-wash:var(--color-ink-wash,rgba(85,61,233,0.08));","--lm-text:var(--color-text,#201515);","--lm-paper:var(--color-paper-card,#fffdf8);","--lm-glow:var(--color-glow,#e8a33d);","--lm-glow-wash:var(--color-glow-wash,rgba(232,163,61,0.14));","--lm-seal:var(--color-seal,#1f8a52);","}",".figure{display:block;width:100%;height:auto;overflow:visible}",".ink{fill:none;stroke:var(--lm-text);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}",".inkBold{fill:none;stroke:var(--lm-text);stroke-width:3.4;stroke-linecap:round;stroke-linejoin:round}",".inkThin{fill:none;stroke:var(--lm-text);stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}",".inkThinDot{fill:none;stroke:var(--lm-text);stroke-width:1.6}",".inkViolet{fill:none;stroke:var(--lm-ink);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}",".fillPaper{fill:var(--lm-paper)}",".fillInk{fill:var(--lm-ink)}",".fillInkWash{fill:var(--lm-ink-wash)}",".fillGlow{fill:var(--lm-glow)}",".fillSeal{fill:var(--lm-seal)}",".fillGlass{fill:rgba(85,61,233,0.06)}",".fillHi{fill:var(--lm-paper)}",".prop-wave .fillPaper{fill:var(--lm-paper)}",".checkMark{fill:none;stroke:#fff;stroke-width:3.2;stroke-linecap:round;stroke-linejoin:round}",".zzz{font:600 26px var(--font-sans,system-ui,sans-serif);fill:var(--lm-ink)}",".m-breathe .creature{transform-box:fill-box;transform-origin:center;animation:lm-breathe 4.5s ease-in-out infinite}","@keyframes lm-breathe{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-2px) scale(1.012)}}",".m-bob .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-bob 2.2s ease-in-out infinite}","@keyframes lm-bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-7px)}}",".m-bounce .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-bounce 0.9s cubic-bezier(.3,.7,.4,1) infinite}","@keyframes lm-bounce{0%,100%{transform:translateY(0) scaleY(1)}30%{transform:translateY(-22px) scaleY(1.05)}55%{transform:translateY(0) scaleY(.94)}70%{transform:translateY(-6px)}}",".m-wiggle .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-wiggle 3s ease-in-out infinite}","@keyframes lm-wiggle{0%,100%{transform:rotate(-1.5deg)}50%{transform:rotate(1.5deg)}}",".m-tilt .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-tilt 3.4s ease-in-out infinite}","@keyframes lm-tilt{0%,100%{transform:rotate(-4deg)}50%{transform:rotate(4deg)}}",".m-work .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-work 0.7s ease-in-out infinite}","@keyframes lm-work{0%,100%{transform:translateX(0) rotate(0)}25%{transform:translateX(-1.5px) rotate(-1deg)}75%{transform:translateX(1.5px) rotate(1deg)}}",".m-inspect .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-inspect 3.2s ease-in-out infinite}","@keyframes lm-inspect{0%,100%{transform:translate(0,0)}50%{transform:translate(6px,-2px)}}",".m-inspect .prop-magnifier{transform-box:fill-box;transform-origin:332px 250px;animation:lm-inspect-mag 3.2s ease-in-out infinite}","@keyframes lm-inspect-mag{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(4px,4px) scale(1.08)}}",".m-shake .creature{transform-box:fill-box;transform-origin:center;animation:lm-shake 0.5s ease-in-out infinite}","@keyframes lm-shake{0%,100%{transform:translateX(0)}25%{transform:translateX(-4px)}75%{transform:translateX(4px)}}",".m-launch .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-launch 1.6s ease-in-out infinite}","@keyframes lm-launch{0%{transform:translateY(0)}40%{transform:translateY(-3px)}70%{transform:translateY(-14px) rotate(-2deg)}100%{transform:translateY(0)}}",".m-wave .creature{transform-box:fill-box;transform-origin:center;animation:lm-breathe 4.5s ease-in-out infinite}",".m-sleep .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-sleep 5.5s ease-in-out infinite}","@keyframes lm-sleep{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-1px) scale(1.02)}}",".prop-wave{transform-box:fill-box;transform-origin:50% 100%;animation:lm-sway 1.1s ease-in-out infinite}","@keyframes lm-sway{0%,100%{transform:rotate(-8deg)}50%{transform:rotate(14deg)}}",".prop-think .d1{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite}",".prop-think .d2{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite .3s}",".prop-think .d3{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite .6s}","@keyframes lm-rise{0%{opacity:.2;transform:translateY(4px) scale(.7)}50%{opacity:1;transform:translateY(0) scale(1)}100%{opacity:.2;transform:translateY(-4px) scale(.7)}}",".zzz{opacity:0;transform-box:fill-box;transform-origin:center}",".prop-zzz .z1{animation:lm-zfloat 3s ease-in-out infinite}",".prop-zzz .z2{animation:lm-zfloat 3s ease-in-out infinite 1s}",".prop-zzz .z3{animation:lm-zfloat 3s ease-in-out infinite 2s}","@keyframes lm-zfloat{0%{opacity:0;transform:translateY(6px) scale(.7)}40%{opacity:1}100%{opacity:0;transform:translateY(-16px) scale(1.1)}}",".spin{transform-box:fill-box;transform-origin:332px 250px;animation:lm-spin 1s linear infinite}","@keyframes lm-spin{to{transform:rotate(360deg)}}",".prop-confetti>*{transform-box:fill-box;transform-origin:center;animation:lm-confetti 1.4s ease-in infinite}",".prop-confetti .c2{animation-delay:.15s}.prop-confetti .c3{animation-delay:.3s}",".prop-confetti .c4{animation-delay:.45s}.prop-confetti .c5{animation-delay:.2s}",".prop-confetti .c6{animation-delay:.5s}.prop-confetti .c7{animation-delay:.1s}","@keyframes lm-confetti{0%{opacity:0;transform:translateY(0) rotate(0)}20%{opacity:1}100%{opacity:0;transform:translateY(34px) rotate(180deg)}}",".prop-check{transform-box:fill-box;transform-origin:332px 246px;animation:lm-pop 2.4s ease-in-out infinite}","@keyframes lm-pop{0%,70%,100%{transform:scale(1)}80%{transform:scale(1.18)}}",".m-launch .prop-parcel{transform-box:fill-box;transform-origin:center;animation:lm-bob 1.6s ease-in-out infinite}",".m-walk .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-walkbody 0.8s ease-in-out infinite}","@keyframes lm-walkbody{0%,100%{transform:translateY(0) rotate(-1deg)}50%{transform:translateY(-4px) rotate(1deg)}}",".m-walk .legL{transform-box:fill-box;transform-origin:168px 318px;animation:lm-legswing 0.8s ease-in-out infinite}",".m-walk .footL{transform-box:fill-box;transform-origin:168px 336px;animation:lm-legswing 0.8s ease-in-out infinite}",".m-walk .legR{transform-box:fill-box;transform-origin:252px 318px;animation:lm-legswing 0.8s ease-in-out infinite .4s}",".m-walk .footR{transform-box:fill-box;transform-origin:252px 336px;animation:lm-legswing 0.8s ease-in-out infinite .4s}","@keyframes lm-legswing{0%,100%{transform:rotate(-16deg)}50%{transform:rotate(16deg)}}",".m-run .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-runbody 0.42s ease-in-out infinite}","@keyframes lm-runbody{0%,100%{transform:translateY(0) rotate(-4deg)}50%{transform:translateY(-7px) rotate(2deg)}}",".m-run .legL{transform-box:fill-box;transform-origin:168px 318px;animation:lm-runleg 0.42s ease-in-out infinite}",".m-run .footL{transform-box:fill-box;transform-origin:168px 336px;animation:lm-runleg 0.42s ease-in-out infinite}",".m-run .legR{transform-box:fill-box;transform-origin:252px 318px;animation:lm-runleg 0.42s ease-in-out infinite .21s}",".m-run .footR{transform-box:fill-box;transform-origin:252px 336px;animation:lm-runleg 0.42s ease-in-out infinite .21s}","@keyframes lm-runleg{0%,100%{transform:rotate(-30deg)}50%{transform:rotate(30deg)}}",".eyes.blink{transform-box:fill-box;transform-origin:center;animation:lm-blink 6s steps(1,end) infinite}","@keyframes lm-blink{0%,92%,100%{transform:scaleY(1)}95%{transform:scaleY(.1)}}","@media (prefers-reduced-motion: reduce){",".figure *{animation:none !important}",".eyes.blink{transform:scaleY(1) !important}",".zzz{opacity:1}",".prop-confetti>*{opacity:1}",".prop-think .d1,.prop-think .d2,.prop-think .d3{opacity:1}","}"].join("");function c(u){var m=parseFloat(u);return!isFinite(m)||m<=0?132:m<16?16:m>1024?1024:m}var p=function(){function u(){return class extends HTMLElement{static get observedAttributes(){return["emotion","size","motion"]}constructor(){super(),this.attachShadow({mode:"open"}),this._styleEl=document.createElement("style"),this._styleEl.textContent=l,this._wrap=document.createElement("div"),this._wrap.className="lm-root",this.shadowRoot.appendChild(this._styleEl),this.shadowRoot.appendChild(this._wrap)}connectedCallback(){this._render()}attributeChangedCallback(){this.shadowRoot&&this._render()}_render(){var h=(this.getAttribute("emotion")||s).toLowerCase(),k=a[h]||a[s],x=(this.getAttribute("motion")||k.motion||"breathe").toLowerCase(),_=c(this.getAttribute("size")||"132");this.style.width=_+"px",this.setAttribute("role","img"),this.setAttribute("aria-label",k.label||"Loki"),this._wrap.className="lm-root m-"+x,this._wrap.innerHTML=n(k)}}}return customElements.get("loki-mascot")||customElements.define("loki-mascot",u()),customElements.get("loki-mascot")}();try{p.emotions=Object.keys(a),p.getEmotion=function(u){var m=(u||s).toLowerCase(),h=a[m]||a[s];return Object.assign({name:m},h)},p.renderStandaloneSVG=function(u){var m=p.getEmotion(u),h=m.motion||"breathe",k=l.replace(":host{","svg.loki-figure{"),x=n(m).replace('<svg class="figure"','<svg xmlns="http://www.w3.org/2000/svg" class="figure loki-figure m-'+h+'" role="img" aria-label="'+(m.label||"Loki")+'"').replace('aria-hidden="true" focusable="false"','focusable="false"');return x.replace("</svg>","<style>"+k+"</style></svg>")}}catch{}})();function ii(d){switch((d||"").toLowerCase()){case"running":case"autonomous":return"building";case"paused":return"sleeping";default:return"idle"}}var Ae=class extends HTMLElement{static get observedAttributes(){return["api-url","size"]}constructor(){super(),this.attachShadow({mode:"open"}),this._status="idle",this._api=null,this._statusHandler=null,this._discHandler=null,this._poll=null}connectedCallback(){this._setupApi(),this._loadStatus(),this._startPolling(),this.render()}disconnectedCallback(){this._poll&&(this._poll.stop(),this._poll=null),this._teardownApiListeners()}_teardownApiListeners(){this._api&&(this._statusHandler&&this._api.removeEventListener(f.STATUS_UPDATE,this._statusHandler),this._discHandler&&this._api.removeEventListener(f.DISCONNECTED,this._discHandler))}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._teardownApiListeners(),this._setupApi(),this._loadStatus()),e==="size"&&this.render())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e}),this._statusHandler=t=>this._updateFromStatus(t.detail),this._discHandler=()=>{this._status="offline",this.render()},this._api.addEventListener(f.STATUS_UPDATE,this._statusHandler),this._api.addEventListener(f.DISCONNECTED,this._discHandler)}_startPolling(){this._poll=b({loadFn:()=>this._loadStatus(),intervalMs:1e4,sectionId:null,immediate:!1})}async _loadStatus(){let e=this._api;try{let t=await e.getStatus();if(e!==this._api)return;this._updateFromStatus(t)}catch{if(e!==this._api)return;this._status="offline",this.render()}}_updateFromStatus(e){if(!e)return;let t=e.status||"idle";t!==this._status&&(this._status=t,this.render())}render(){if(!this.shadowRoot)return;let e=this.getAttribute("size")||"34",t=ii(this._status);this.shadowRoot.innerHTML=`
|
|
14604
|
+
`;let e=this.shadowRoot.getElementById("spec-retry-btn");e&&e.addEventListener("click",()=>this._load());let t=this.shadowRoot.getElementById("hist-toggle");t&&t.addEventListener("click",()=>{this._historyOpen=!this._historyOpen,this.render()})}};customElements.get("loki-spec-panel")||customElements.define("loki-spec-panel",Ae);(function(){"use strict";if(typeof window>"u"||typeof customElements>"u")return;var d={open:'<circle cx="178" cy="214" r="7" class="fillInk"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="180.5" cy="211.5" r="2" class="fillHi"/><circle cx="246.5" cy="211.5" r="2" class="fillHi"/>',happy:'<path class="ink" d="M171 216c4-6 10-6 14 0"/><path class="ink" d="M237 216c4-6 10-6 14 0"/>',lookUp:'<circle cx="178" cy="214" r="7" class="fillInk"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="180" cy="210" r="2.4" class="fillHi"/><circle cx="246" cy="210" r="2.4" class="fillHi"/>',wide:'<circle cx="178" cy="213" r="8.5" class="fillInk"/><circle cx="244" cy="213" r="8.5" class="fillInk"/><circle cx="181" cy="210" r="2.6" class="fillHi"/><circle cx="247" cy="210" r="2.6" class="fillHi"/>',focused:'<path class="inkBold" d="M170 214h16"/><path class="inkBold" d="M236 214h16"/>',closed:'<path class="ink" d="M170 214c4 5 10 5 14 0"/><path class="ink" d="M236 214c4 5 10 5 14 0"/>',worried:'<circle cx="178" cy="216" r="6" class="fillInk"/><circle cx="244" cy="216" r="6" class="fillInk"/><circle cx="180" cy="213.5" r="1.8" class="fillHi"/><circle cx="246" cy="213.5" r="1.8" class="fillHi"/>',wink:'<path class="ink" d="M171 214c4-5 10-5 14 0"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="246.5" cy="211.5" r="2" class="fillHi"/>'},e={none:"",raised:'<path class="inkThin" d="M168 198c5-3 12-3 17 0"/><path class="inkThin" d="M237 198c5-3 12-3 17 0"/>',furrow:'<path class="inkThin" d="M168 199l16 3"/><path class="inkThin" d="M254 199l-16 3"/>',worried:'<path class="inkThin" d="M168 201l16-4"/><path class="inkThin" d="M254 201l-16-4"/>'},t={smile:'<path class="ink" d="M192 244c12 12 26 12 38 0"/>',openSmile:'<path class="fillInk" d="M194 243c8 16 26 16 34 0c-10 6-24 6-34 0z"/>',flat:'<path class="ink" d="M198 248h26"/>',o:'<ellipse cx="211" cy="248" rx="6" ry="7" class="ink"/>',frown:'<path class="ink" d="M192 250c12-12 26-12 38 0"/>',soft:'<path class="ink" d="M196 246c9 7 19 7 28 0"/>',proud:'<path class="ink" d="M194 245c10 9 24 9 32 -2"/>'},i={none:"",wave:'<g class="prop-wave"><path class="ink" d="M318 250c14-2 26 6 28 20"/><circle cx="348" cy="276" r="9" class="fillPaper ink"/></g>',zzz:'<g class="ink prop-zzz"><text x="300" y="150" class="zzz z1">z</text><text x="322" y="128" class="zzz z2">z</text><text x="344" y="110" class="zzz z3">z</text></g>',thoughtDots:'<g class="prop-think"><circle cx="300" cy="170" r="4" class="fillInk d1"/><circle cx="316" cy="150" r="5.5" class="fillInk d2"/><circle cx="336" cy="126" r="7" class="fillInk d3"/></g>',magnifier:'<g class="prop-magnifier"><circle cx="332" cy="250" r="18" class="fillGlass ink"/><path class="inkBold" d="M345 263l16 16"/><path class="inkThin" d="M325 244a10 10 0 0 1 8 4"/></g>',check:'<g class="prop-check"><circle cx="332" cy="246" r="17" class="fillSeal"/><path class="checkMark" d="M324 246l6 6 11 -13"/></g>',confetti:'<g class="prop-confetti"><rect x="110" y="120" width="7" height="7" class="fillInk c1" transform="rotate(20 113 123)"/><rect x="300" y="110" width="7" height="7" class="fillGlow c2" transform="rotate(-15 303 113)"/><rect x="140" y="96" width="6" height="6" class="fillSeal c3"/><circle cx="330" cy="150" r="4" class="fillInk c4"/><circle cx="96" cy="170" r="4" class="fillGlow c5"/><rect x="270" y="140" width="6" height="6" class="fillInk c6" transform="rotate(40 273 143)"/><path class="inkViolet c7" d="M210 92l0 12M204 98l12 0"/></g>',parcel:'<g class="prop-parcel"><rect x="316" y="244" width="40" height="34" rx="3" class="fillPaper ink"/><path class="ink" d="M316 256h40"/><path class="inkViolet" d="M336 244v34"/></g>',spinner:'<g class="prop-spinner"><path class="inkBold spin" d="M332 230a20 20 0 1 1 -14 6"/></g>'},a={idle:{eyes:"open",mouth:"smile",motion:"breathe",label:"Loki, resting",blink:!0},happy:{eyes:"happy",mouth:"smile",motion:"bob",label:"Loki, happy"},thinking:{eyes:"lookUp",brow:"raised",mouth:"flat",prop:"thoughtDots",motion:"wiggle",label:"Loki, thinking"},building:{eyes:"focused",brow:"furrow",mouth:"flat",motion:"work",label:"Loki, building"},reviewing:{eyes:"focused",brow:"furrow",mouth:"soft",prop:"magnifier",motion:"inspect",label:"Loki, reviewing the work"},verifying:{eyes:"open",mouth:"soft",prop:"check",motion:"bob",label:"Loki, verifying",blink:!0},celebrating:{eyes:"wide",mouth:"openSmile",prop:"confetti",motion:"bounce",label:"Loki, celebrating a verified result"},proud:{eyes:"happy",mouth:"proud",prop:"check",motion:"bob",label:"Loki, proud"},waving:{eyes:"wink",mouth:"smile",prop:"wave",motion:"wave",label:"Loki, waving hello"},sleeping:{eyes:"closed",mouth:"soft",prop:"zzz",motion:"sleep",label:"Loki, sleeping"},concerned:{eyes:"worried",brow:"worried",mouth:"frown",motion:"shake",label:"Loki, something went wrong"},shipping:{eyes:"happy",mouth:"smile",prop:"parcel",motion:"launch",label:"Loki, shipping"},loading:{eyes:"open",mouth:"flat",prop:"spinner",motion:"breathe",label:"Loki, loading",blink:!0},curious:{eyes:"lookUp",brow:"raised",mouth:"o",prop:"thoughtDots",motion:"tilt",label:"Loki, curious"},blinking:{eyes:"open",mouth:"smile",motion:"breathe",label:"Loki",blink:!0},walking:{eyes:"open",mouth:"soft",motion:"walk",label:"Loki, walking",blink:!0},running:{eyes:"focused",mouth:"soft",motion:"run",label:"Loki, running"}},s="idle";function r(){return'<g class="legs"><path class="ink leg legL" d="M168 318v18"/><path class="ink foot footL" d="M158 336h20"/><path class="ink leg legR" d="M252 318v18"/><path class="ink foot footR" d="M242 336h20"/></g>'}function o(u,m,h){return m&&Object.prototype.hasOwnProperty.call(u,m)?u[m]:h||""}function n(u){var m=u.blink?" blink":"";return'<svg class="figure" viewBox="0 0 420 380" aria-hidden="true" focusable="false"><ellipse cx="210" cy="338" rx="120" ry="16" class="fillInkWash"/><g class="creature">'+r()+'<path class="fillPaper ink" d="M120 132c0-22 16-36 40-37 38-2 82-2 120 0 24 1 40 15 40 38v118c0 24-16 39-41 40-40 2-78 2-118 0-25-1-41-16-41-40z"/><path class="inkThin" d="M124 168c54-4 118-4 172 0"/><circle cx="146" cy="150" r="4.5" class="inkViolet"/><circle cx="164" cy="150" r="4.5" class="inkThinDot"/><circle cx="182" cy="150" r="4.5" class="inkThinDot"/><circle cx="170" cy="232" r="9" class="fillGlow"/><circle cx="252" cy="232" r="9" class="fillGlow"/>'+o(e,u.brow,"")+'<g class="eyes'+m+'">'+o(d,u.eyes,d.open)+"</g>"+o(t,u.mouth,t.smile)+'<path class="inkViolet" d="M150 280h120"/><path class="inkThin" d="M150 296h84"/>'+o(i,u.prop,"")+"</g></svg>"}var l=[":host{display:inline-block;line-height:0;","--lm-ink:var(--color-ink,#553de9);","--lm-ink-wash:var(--color-ink-wash,rgba(85,61,233,0.08));","--lm-text:var(--color-text,#201515);","--lm-paper:var(--color-paper-card,#fffdf8);","--lm-glow:var(--color-glow,#e8a33d);","--lm-glow-wash:var(--color-glow-wash,rgba(232,163,61,0.14));","--lm-seal:var(--color-seal,#1f8a52);","}",".figure{display:block;width:100%;height:auto;overflow:visible}",".ink{fill:none;stroke:var(--lm-text);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}",".inkBold{fill:none;stroke:var(--lm-text);stroke-width:3.4;stroke-linecap:round;stroke-linejoin:round}",".inkThin{fill:none;stroke:var(--lm-text);stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}",".inkThinDot{fill:none;stroke:var(--lm-text);stroke-width:1.6}",".inkViolet{fill:none;stroke:var(--lm-ink);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}",".fillPaper{fill:var(--lm-paper)}",".fillInk{fill:var(--lm-ink)}",".fillInkWash{fill:var(--lm-ink-wash)}",".fillGlow{fill:var(--lm-glow)}",".fillSeal{fill:var(--lm-seal)}",".fillGlass{fill:rgba(85,61,233,0.06)}",".fillHi{fill:var(--lm-paper)}",".prop-wave .fillPaper{fill:var(--lm-paper)}",".checkMark{fill:none;stroke:#fff;stroke-width:3.2;stroke-linecap:round;stroke-linejoin:round}",".zzz{font:600 26px var(--font-sans,system-ui,sans-serif);fill:var(--lm-ink)}",".m-breathe .creature{transform-box:fill-box;transform-origin:center;animation:lm-breathe 4.5s ease-in-out infinite}","@keyframes lm-breathe{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-2px) scale(1.012)}}",".m-bob .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-bob 2.2s ease-in-out infinite}","@keyframes lm-bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-7px)}}",".m-bounce .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-bounce 0.9s cubic-bezier(.3,.7,.4,1) infinite}","@keyframes lm-bounce{0%,100%{transform:translateY(0) scaleY(1)}30%{transform:translateY(-22px) scaleY(1.05)}55%{transform:translateY(0) scaleY(.94)}70%{transform:translateY(-6px)}}",".m-wiggle .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-wiggle 3s ease-in-out infinite}","@keyframes lm-wiggle{0%,100%{transform:rotate(-1.5deg)}50%{transform:rotate(1.5deg)}}",".m-tilt .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-tilt 3.4s ease-in-out infinite}","@keyframes lm-tilt{0%,100%{transform:rotate(-4deg)}50%{transform:rotate(4deg)}}",".m-work .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-work 0.7s ease-in-out infinite}","@keyframes lm-work{0%,100%{transform:translateX(0) rotate(0)}25%{transform:translateX(-1.5px) rotate(-1deg)}75%{transform:translateX(1.5px) rotate(1deg)}}",".m-inspect .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-inspect 3.2s ease-in-out infinite}","@keyframes lm-inspect{0%,100%{transform:translate(0,0)}50%{transform:translate(6px,-2px)}}",".m-inspect .prop-magnifier{transform-box:fill-box;transform-origin:332px 250px;animation:lm-inspect-mag 3.2s ease-in-out infinite}","@keyframes lm-inspect-mag{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(4px,4px) scale(1.08)}}",".m-shake .creature{transform-box:fill-box;transform-origin:center;animation:lm-shake 0.5s ease-in-out infinite}","@keyframes lm-shake{0%,100%{transform:translateX(0)}25%{transform:translateX(-4px)}75%{transform:translateX(4px)}}",".m-launch .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-launch 1.6s ease-in-out infinite}","@keyframes lm-launch{0%{transform:translateY(0)}40%{transform:translateY(-3px)}70%{transform:translateY(-14px) rotate(-2deg)}100%{transform:translateY(0)}}",".m-wave .creature{transform-box:fill-box;transform-origin:center;animation:lm-breathe 4.5s ease-in-out infinite}",".m-sleep .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-sleep 5.5s ease-in-out infinite}","@keyframes lm-sleep{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-1px) scale(1.02)}}",".prop-wave{transform-box:fill-box;transform-origin:50% 100%;animation:lm-sway 1.1s ease-in-out infinite}","@keyframes lm-sway{0%,100%{transform:rotate(-8deg)}50%{transform:rotate(14deg)}}",".prop-think .d1{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite}",".prop-think .d2{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite .3s}",".prop-think .d3{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite .6s}","@keyframes lm-rise{0%{opacity:.2;transform:translateY(4px) scale(.7)}50%{opacity:1;transform:translateY(0) scale(1)}100%{opacity:.2;transform:translateY(-4px) scale(.7)}}",".zzz{opacity:0;transform-box:fill-box;transform-origin:center}",".prop-zzz .z1{animation:lm-zfloat 3s ease-in-out infinite}",".prop-zzz .z2{animation:lm-zfloat 3s ease-in-out infinite 1s}",".prop-zzz .z3{animation:lm-zfloat 3s ease-in-out infinite 2s}","@keyframes lm-zfloat{0%{opacity:0;transform:translateY(6px) scale(.7)}40%{opacity:1}100%{opacity:0;transform:translateY(-16px) scale(1.1)}}",".spin{transform-box:fill-box;transform-origin:332px 250px;animation:lm-spin 1s linear infinite}","@keyframes lm-spin{to{transform:rotate(360deg)}}",".prop-confetti>*{transform-box:fill-box;transform-origin:center;animation:lm-confetti 1.4s ease-in infinite}",".prop-confetti .c2{animation-delay:.15s}.prop-confetti .c3{animation-delay:.3s}",".prop-confetti .c4{animation-delay:.45s}.prop-confetti .c5{animation-delay:.2s}",".prop-confetti .c6{animation-delay:.5s}.prop-confetti .c7{animation-delay:.1s}","@keyframes lm-confetti{0%{opacity:0;transform:translateY(0) rotate(0)}20%{opacity:1}100%{opacity:0;transform:translateY(34px) rotate(180deg)}}",".prop-check{transform-box:fill-box;transform-origin:332px 246px;animation:lm-pop 2.4s ease-in-out infinite}","@keyframes lm-pop{0%,70%,100%{transform:scale(1)}80%{transform:scale(1.18)}}",".m-launch .prop-parcel{transform-box:fill-box;transform-origin:center;animation:lm-bob 1.6s ease-in-out infinite}",".m-walk .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-walkbody 0.8s ease-in-out infinite}","@keyframes lm-walkbody{0%,100%{transform:translateY(0) rotate(-1deg)}50%{transform:translateY(-4px) rotate(1deg)}}",".m-walk .legL{transform-box:fill-box;transform-origin:168px 318px;animation:lm-legswing 0.8s ease-in-out infinite}",".m-walk .footL{transform-box:fill-box;transform-origin:168px 336px;animation:lm-legswing 0.8s ease-in-out infinite}",".m-walk .legR{transform-box:fill-box;transform-origin:252px 318px;animation:lm-legswing 0.8s ease-in-out infinite .4s}",".m-walk .footR{transform-box:fill-box;transform-origin:252px 336px;animation:lm-legswing 0.8s ease-in-out infinite .4s}","@keyframes lm-legswing{0%,100%{transform:rotate(-16deg)}50%{transform:rotate(16deg)}}",".m-run .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-runbody 0.42s ease-in-out infinite}","@keyframes lm-runbody{0%,100%{transform:translateY(0) rotate(-4deg)}50%{transform:translateY(-7px) rotate(2deg)}}",".m-run .legL{transform-box:fill-box;transform-origin:168px 318px;animation:lm-runleg 0.42s ease-in-out infinite}",".m-run .footL{transform-box:fill-box;transform-origin:168px 336px;animation:lm-runleg 0.42s ease-in-out infinite}",".m-run .legR{transform-box:fill-box;transform-origin:252px 318px;animation:lm-runleg 0.42s ease-in-out infinite .21s}",".m-run .footR{transform-box:fill-box;transform-origin:252px 336px;animation:lm-runleg 0.42s ease-in-out infinite .21s}","@keyframes lm-runleg{0%,100%{transform:rotate(-30deg)}50%{transform:rotate(30deg)}}",".eyes.blink{transform-box:fill-box;transform-origin:center;animation:lm-blink 6s steps(1,end) infinite}","@keyframes lm-blink{0%,92%,100%{transform:scaleY(1)}95%{transform:scaleY(.1)}}","@media (prefers-reduced-motion: reduce){",".figure *{animation:none !important}",".eyes.blink{transform:scaleY(1) !important}",".zzz{opacity:1}",".prop-confetti>*{opacity:1}",".prop-think .d1,.prop-think .d2,.prop-think .d3{opacity:1}","}"].join("");function c(u){var m=parseFloat(u);return!isFinite(m)||m<=0?132:m<16?16:m>1024?1024:m}var p=function(){function u(){return class extends HTMLElement{static get observedAttributes(){return["emotion","size","motion"]}constructor(){super(),this.attachShadow({mode:"open"}),this._styleEl=document.createElement("style"),this._styleEl.textContent=l,this._wrap=document.createElement("div"),this._wrap.className="lm-root",this.shadowRoot.appendChild(this._styleEl),this.shadowRoot.appendChild(this._wrap)}connectedCallback(){this._render()}attributeChangedCallback(){this.shadowRoot&&this._render()}_render(){var h=(this.getAttribute("emotion")||s).toLowerCase(),k=a[h]||a[s],x=(this.getAttribute("motion")||k.motion||"breathe").toLowerCase(),_=c(this.getAttribute("size")||"132");this.style.width=_+"px",this.setAttribute("role","img"),this.setAttribute("aria-label",k.label||"Loki"),this._wrap.className="lm-root m-"+x,this._wrap.innerHTML=n(k)}}}return customElements.get("loki-mascot")||customElements.define("loki-mascot",u()),customElements.get("loki-mascot")}();try{p.emotions=Object.keys(a),p.getEmotion=function(u){var m=(u||s).toLowerCase(),h=a[m]||a[s];return Object.assign({name:m},h)},p.renderStandaloneSVG=function(u){var m=p.getEmotion(u),h=m.motion||"breathe",k=l.replace(":host{","svg.loki-figure{"),x=n(m).replace('<svg class="figure"','<svg xmlns="http://www.w3.org/2000/svg" class="figure loki-figure m-'+h+'" role="img" aria-label="'+(m.label||"Loki")+'"').replace('aria-hidden="true" focusable="false"','focusable="false"');return x.replace("</svg>","<style>"+k+"</style></svg>")}}catch{}})();function ai(d){switch((d||"").toLowerCase()){case"running":case"autonomous":return"building";case"paused":return"sleeping";default:return"idle"}}var Te=class extends HTMLElement{static get observedAttributes(){return["api-url","size"]}constructor(){super(),this.attachShadow({mode:"open"}),this._status="idle",this._api=null,this._statusHandler=null,this._discHandler=null,this._poll=null}connectedCallback(){this._setupApi(),this._loadStatus(),this._startPolling(),this.render()}disconnectedCallback(){this._poll&&(this._poll.stop(),this._poll=null),this._teardownApiListeners()}_teardownApiListeners(){this._api&&(this._statusHandler&&this._api.removeEventListener(f.STATUS_UPDATE,this._statusHandler),this._discHandler&&this._api.removeEventListener(f.DISCONNECTED,this._discHandler))}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._teardownApiListeners(),this._setupApi(),this._loadStatus()),e==="size"&&this.render())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=g({baseUrl:e}),this._statusHandler=t=>this._updateFromStatus(t.detail),this._discHandler=()=>{this._status="offline",this.render()},this._api.addEventListener(f.STATUS_UPDATE,this._statusHandler),this._api.addEventListener(f.DISCONNECTED,this._discHandler)}_startPolling(){this._poll=b({loadFn:()=>this._loadStatus(),intervalMs:1e4,sectionId:null,immediate:!1})}async _loadStatus(){let e=this._api;try{let t=await e.getStatus();if(e!==this._api)return;this._updateFromStatus(t)}catch{if(e!==this._api)return;this._status="offline",this.render()}}_updateFromStatus(e){if(!e)return;let t=e.status||"idle";t!==this._status&&(this._status=t,this.render())}render(){if(!this.shadowRoot)return;let e=this.getAttribute("size")||"34",t=ai(this._status);this.shadowRoot.innerHTML=`
|
|
14595
14605
|
<style>
|
|
14596
14606
|
:host { display: inline-flex; align-items: center; line-height: 0; }
|
|
14597
14607
|
loki-mascot { display: inline-block; }
|
|
14598
14608
|
</style>
|
|
14599
14609
|
<loki-mascot emotion="${t}" size="${e}"></loki-mascot>
|
|
14600
|
-
`}};customElements.get("loki-mascot-presence")||customElements.define("loki-mascot-presence",
|
|
14610
|
+
`}};customElements.get("loki-mascot-presence")||customElements.define("loki-mascot-presence",Te);var si="1.4.0";function ri(d={}){return d.theme?w.setTheme(d.theme):d.autoDetectContext!==!1?w.init():U.init(),d.apiUrl&&g({baseUrl:d.apiUrl}),{theme:w.getTheme(),context:w.detectContext()}}return Et(oi);})();
|
|
14601
14611
|
|
|
14602
14612
|
|
|
14603
14613
|
// Initialize dashboard when DOM is ready
|
|
@@ -15059,7 +15069,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
15059
15069
|
// that sets one. Never invents a number: an unknown current cost reads
|
|
15060
15070
|
// "not measured", not $0.00.
|
|
15061
15071
|
window.loadBudget = function () {
|
|
15062
|
-
var el = document.getElementById('budget-banner');
|
|
15072
|
+
var el = document.getElementById('cost-budget-banner');
|
|
15063
15073
|
if (!el) return;
|
|
15064
15074
|
fetch('/api/budget', { headers: { 'Accept': 'application/json' } })
|
|
15065
15075
|
.then(function (r) { return r.ok ? r.json() : null; })
|
|
@@ -15110,7 +15120,8 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
15110
15120
|
if (!d) return;
|
|
15111
15121
|
var rows = Array.isArray(d) ? d : (d.learnings || []);
|
|
15112
15122
|
if (!rows.length) return; // nothing learned yet: say nothing
|
|
15113
|
-
|
|
15123
|
+
// /api/learnings already returns newest first; do not re-reverse.
|
|
15124
|
+
rows = rows.slice(0, 8);
|
|
15114
15125
|
// Every field is untrusted text (written by the run) going into
|
|
15115
15126
|
// innerHTML, so each one is escaped.
|
|
15116
15127
|
var esc = function (v) { var e = document.createElement('div'); e.textContent = String(v); return e.innerHTML; };
|
|
@@ -15155,7 +15166,8 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
15155
15166
|
if (!d) return; // endpoint absent: leave hidden
|
|
15156
15167
|
var rows = Array.isArray(d) ? d : (d.proofs || d.receipts || []);
|
|
15157
15168
|
if (!rows.length) return; // no receipts yet: say nothing
|
|
15158
|
-
|
|
15169
|
+
// /api/proofs already returns newest first; do not re-reverse.
|
|
15170
|
+
rows = rows.slice(0, 10);
|
|
15159
15171
|
// Every field is untrusted text (written by the run) going into
|
|
15160
15172
|
// innerHTML, so each one is escaped.
|
|
15161
15173
|
var esc = function (v) { var e = document.createElement('div'); e.textContent = String(v); return e.innerHTML; };
|