loki-mode 9.8.0 → 9.12.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.
Files changed (79) hide show
  1. package/README.md +19 -14
  2. package/SKILL.md +3 -2
  3. package/VERSION +1 -1
  4. package/autonomy/loki +122 -1
  5. package/autonomy/run.sh +49 -2
  6. package/dashboard/__init__.py +1 -1
  7. package/dashboard/api_evidence.py +411 -0
  8. package/dashboard/api_operator.py +283 -0
  9. package/dashboard/api_phases.py +262 -0
  10. package/dashboard/api_releases.py +242 -0
  11. package/dashboard/api_runs.py +477 -0
  12. package/dashboard/api_tests.py +444 -0
  13. package/dashboard/api_v2.py +47 -1
  14. package/dashboard/server.py +54 -0
  15. package/dashboard/static/index.html +246 -135
  16. package/docs/ARCHITECTURE-OVERVIEW.md +5 -3
  17. package/docs/CAPABILITY-BACKLOG.md +53 -0
  18. package/docs/COMPARISON.md +2 -2
  19. package/docs/COMPETITIVE-ANALYSIS.md +1 -1
  20. package/docs/COMPETITIVE-SCORECARD.md +422 -0
  21. package/docs/DASHBOARD-9.12-EVIDENCE.md +97 -0
  22. package/docs/DASHBOARD-ARCHITECTURE.md +423 -0
  23. package/docs/DEMOS.md +21 -23
  24. package/docs/HANDOFF-2026-08-03.md +439 -0
  25. package/docs/INSTALLATION.md +17 -10
  26. package/docs/OUTCOME-FRONTIER.md +536 -0
  27. package/docs/PROMPT-ABLATION-RESULT.md +97 -0
  28. package/docs/TOOLS.md +800 -0
  29. package/docs/alternative-installations.md +2 -3
  30. package/docs/audit-logging.md +44 -35
  31. package/docs/authentication.md +13 -2
  32. package/docs/authorization.md +87 -81
  33. package/docs/git-workflow.md +6 -3
  34. package/docs/metrics.md +15 -16
  35. package/docs/network-security.md +16 -13
  36. package/docs/openclaw-integration.md +36 -556
  37. package/docs/show-hn-post.md +2 -2
  38. package/docs/siem-integration.md +39 -36
  39. package/loki-ts/dist/loki.js +18 -18
  40. package/mcp/__init__.py +1 -1
  41. package/package.json +2 -2
  42. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  43. package/references/confidence-routing.md +18 -1
  44. package/references/invariant-checks.md +13 -8
  45. package/references/magic-rarv-integration.md +0 -1
  46. package/references/multi-provider.md +27 -5
  47. package/skills/healing.md +4 -2
  48. package/tools/audit-docs.py +488 -0
  49. package/tools/baseline-pin.py +19 -1
  50. package/tools/calibration-audit.py +523 -0
  51. package/tools/ci-gate.py +19 -1
  52. package/tools/cost-forecast.py +344 -0
  53. package/tools/cost-guard.py +19 -1
  54. package/tools/cost-history.py +19 -1
  55. package/tools/cost-per-outcome.py +394 -0
  56. package/tools/estimate-run.py +19 -1
  57. package/tools/evidence-freshness.py +307 -0
  58. package/tools/gate-init.py +19 -1
  59. package/tools/gate-report.py +19 -1
  60. package/tools/gate-simulate.py +570 -0
  61. package/tools/gate-trend.py +354 -0
  62. package/tools/model-advisor.py +52 -1
  63. package/tools/policy-load.py +19 -1
  64. package/tools/prompt-cost.py +363 -0
  65. package/tools/prompt-diff.py +448 -0
  66. package/tools/prompt-lint.py +448 -0
  67. package/tools/receipt-bundle.py +72 -2
  68. package/tools/receipt-diff.py +19 -1
  69. package/tools/receipt-find.py +19 -1
  70. package/tools/receipt-stats.py +380 -0
  71. package/tools/receipt-timeline.py +478 -0
  72. package/tools/receipt-verify-batch.py +291 -0
  73. package/tools/run-replay.py +19 -1
  74. package/tools/signing-status.py +19 -1
  75. package/tools/token-guard.py +19 -1
  76. package/tools/token-tax.py +375 -0
  77. package/tools/tool-index.py +19 -1
  78. package/tools/verification-tax.py +277 -0
  79. package/tools/verify-chain.py +361 -0
@@ -1819,8 +1819,8 @@
1819
1819
 
1820
1820
  <!-- Inlined JavaScript Bundle -->
1821
1821
  <script>
1822
- var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropertyDescriptor;var yt=Object.getOwnPropertyNames;var wt=Object.prototype.hasOwnProperty;var $t=(d,e,t)=>e in d?Re(d,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):d[e]=t;var Et=(d,e)=>{for(var t in e)Re(d,t,{get:e[t],enumerable:!0})},Ct=(d,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of yt(e))!wt.call(d,a)&&a!==t&&Re(d,a,{get:()=>e[a],enumerable:!(i=_t(e,a))||i.enumerable});return d};var St=d=>Ct(Re({},"__esModule",{value:!0}),d);var S=(d,e,t)=>$t(d,typeof e!="symbol"?e+"":e,t);var ri={};Et(ri,{ANIMATION:()=>P,ARIA_PATTERNS:()=>Ie,ApiEvents:()=>f,BASE_STYLES:()=>V,BREAKPOINTS:()=>Pe,COMMON_STYLES:()=>Ze,KEYBOARD_SHORTCUTS:()=>Be,KeyboardHandler:()=>O,LokiActivityStream:()=>ye,LokiAgentLeaderboard:()=>Ae,LokiAnalytics:()=>ge,LokiApiClient:()=>N,LokiApiKeys:()=>xe,LokiAppPreview:()=>re,LokiAppStatus:()=>se,LokiAuditViewer:()=>ke,LokiChecklistViewer:()=>ae,LokiCheckpointViewer:()=>ne,LokiContextTracker:()=>le,LokiCostDashboard:()=>oe,LokiCostWaterfall:()=>Se,LokiCouncilDashboard:()=>ie,LokiCouncilTranscripts:()=>ze,LokiElement:()=>v,LokiEscalations:()=>Le,LokiFleet:()=>be,LokiLearningDashboard:()=>te,LokiLogStream:()=>Z,LokiManagedMemoryPanel:()=>Te,LokiMascotPresence:()=>Me,LokiMemoryBrowser:()=>ee,LokiMemoryGraph:()=>Ce,LokiMigrationDashboard:()=>ue,LokiNotificationCenter:()=>de,LokiOverview:()=>W,LokiPipelineView:()=>$e,LokiPromptOptimizer:()=>pe,LokiProviderHealth:()=>we,LokiQualityGates:()=>me,LokiQualityScore:()=>he,LokiRarvTimeline:()=>ve,LokiRunManager:()=>fe,LokiSessionControl:()=>X,LokiSessionDiff:()=>ce,LokiSpecPanel:()=>He,LokiState:()=>Y,LokiTaskBoard:()=>Q,LokiTenantSwitcher:()=>_e,LokiTheme:()=>j,LokiWikiBrowser:()=>De,MARKDOWN_STYLES:()=>L,RADIUS:()=>R,SPACING:()=>z,STATE_CHANGE_EVENT:()=>Ue,THEMES:()=>A,THEME_VARIABLES:()=>Fe,TYPOGRAPHY:()=>$,UnifiedThemeManager:()=>w,VERSION:()=>ai,Z_INDEX:()=>B,createApiClient:()=>it,createStore:()=>at,escapeHtml:()=>Oe,generateThemeCSS:()=>E,generateTokensCSS:()=>K,getApiClient:()=>h,getState:()=>U,init:()=>si,renderMarkdown:()=>C});var A={light:{"--loki-bg-primary":"#FFFEFB","--loki-bg-secondary":"#F8F4F0","--loki-bg-tertiary":"#ECEAE3","--loki-bg-card":"#ffffff","--loki-bg-hover":"#F3EFE9","--loki-bg-active":"#E6E2DA","--loki-bg-overlay":"rgba(32, 21, 21, 0.5)","--loki-accent":"#553DE9","--loki-accent-hover":"#4432c4","--loki-accent-active":"#3828a0","--loki-accent-light":"#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)"}},z={xs:"4px",sm:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"32px","3xl":"48px"},R={none:"0",sm:"2px",md:"4px",lg:"5px",xl:"5px",full:"9999px"},$={fontFamily:{sans:"'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif",serif:"'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"}},P={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)"}},Pe={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"},Be={"navigation.nextItem":{key:"ArrowDown",modifiers:[]},"navigation.prevItem":{key:"ArrowUp",modifiers:[]},"navigation.nextSection":{key:"Tab",modifiers:[]},"navigation.prevSection":{key:"Tab",modifiers:["Shift"]},"navigation.confirm":{key:"Enter",modifiers:[]},"navigation.cancel":{key:"Escape",modifiers:[]},"action.refresh":{key:"r",modifiers:["Meta"]},"action.search":{key:"k",modifiers:["Meta"]},"action.save":{key:"s",modifiers:["Meta"]},"action.close":{key:"w",modifiers:["Meta"]},"theme.toggle":{key:"d",modifiers:["Meta","Shift"]},"task.create":{key:"n",modifiers:["Meta"]},"task.complete":{key:"Enter",modifiers:["Meta"]},"view.toggleLogs":{key:"l",modifiers:["Meta","Shift"]},"view.toggleMemory":{key:"m",modifiers:["Meta","Shift"]}},Ie={button:{role:"button",tabIndex:0},tablist:{role:"tablist"},tab:{role:"tab",ariaSelected:!1,tabIndex:-1},tabpanel:{role:"tabpanel",tabIndex:0},list:{role:"list"},listitem:{role:"listitem"},livePolite:{ariaLive:"polite",ariaAtomic:!0},liveAssertive:{ariaLive:"assertive",ariaAtomic:!0},dialog:{role:"dialog",ariaModal:!0},alertdialog:{role:"alertdialog",ariaModal:!0},status:{role:"status",ariaLive:"polite"},alert:{role:"alert",ariaLive:"assertive"},log:{role:"log",ariaLive:"polite",ariaRelevant:"additions"}};function E(d){let e=A[d];return e?Object.entries(e).map(([t,i])=>`${t}: ${i};`).join(`
1823
- `):""}function K(){return`
1822
+ var LokiDashboard=(()=>{var Be=Object.defineProperty;var zt=Object.getOwnPropertyDescriptor;var Dt=Object.getOwnPropertyNames;var Ht=Object.prototype.hasOwnProperty;var Mt=(d,e,t)=>e in d?Be(d,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):d[e]=t;var Rt=(d,e)=>{for(var t in e)Be(d,t,{get:e[t],enumerable:!0})},Pt=(d,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of Dt(e))!Ht.call(d,a)&&a!==t&&Be(d,a,{get:()=>e[a],enumerable:!(i=zt(e,a))||i.enumerable});return d};var Bt=d=>Pt(Be({},"__esModule",{value:!0}),d);var S=(d,e,t)=>Mt(d,typeof e!="symbol"?e+"":e,t);var vi={};Rt(vi,{ANIMATION:()=>P,ARIA_PATTERNS:()=>Ue,ApiEvents:()=>f,BASE_STYLES:()=>W,BREAKPOINTS:()=>Ie,COMMON_STYLES:()=>ot,KEYBOARD_SHORTCUTS:()=>je,KeyboardHandler:()=>O,LokiActivityStream:()=>$e,LokiAgentLeaderboard:()=>Le,LokiAnalytics:()=>ve,LokiApiClient:()=>J,LokiApiKeys:()=>ye,LokiAppPreview:()=>ne,LokiAppStatus:()=>oe,LokiAuditViewer:()=>_e,LokiChecklistViewer:()=>re,LokiCheckpointViewer:()=>de,LokiContextTracker:()=>ce,LokiCostDashboard:()=>le,LokiCostWaterfall:()=>Te,LokiCouncilDashboard:()=>se,LokiCouncilTranscripts:()=>He,LokiElement:()=>v,LokiEscalations:()=>De,LokiFleet:()=>xe,LokiLearningDashboard:()=>ae,LokiLogStream:()=>te,LokiManagedMemoryPanel:()=>ze,LokiMascotPresence:()=>Pe,LokiMemoryBrowser:()=>ie,LokiMemoryGraph:()=>Ae,LokiMigrationDashboard:()=>me,LokiNotificationCenter:()=>pe,LokiOverview:()=>X,LokiPipelineView:()=>Ce,LokiPromptOptimizer:()=>ue,LokiProviderHealth:()=>Ee,LokiQualityGates:()=>fe,LokiQualityScore:()=>ge,LokiRarvTimeline:()=>be,LokiRunManager:()=>ke,LokiSessionControl:()=>ee,LokiSessionDiff:()=>he,LokiSpecPanel:()=>Re,LokiState:()=>Q,LokiTaskBoard:()=>Z,LokiTenantSwitcher:()=>we,LokiTheme:()=>U,LokiWikiBrowser:()=>Me,MARKDOWN_STYLES:()=>L,RADIUS:()=>R,SPACING:()=>z,STATE_CHANGE_EVENT:()=>Je,THEMES:()=>A,THEME_VARIABLES:()=>Oe,TYPOGRAPHY:()=>$,UnifiedThemeManager:()=>w,VERSION:()=>gi,Z_INDEX:()=>B,createApiClient:()=>dt,createStore:()=>ct,escapeHtml:()=>Ge,generateThemeCSS:()=>E,generateTokensCSS:()=>Y,getApiClient:()=>h,getState:()=>N,init:()=>mi,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)"}},z={xs:"4px",sm:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"32px","3xl":"48px"},R={none:"0",sm:"2px",md:"4px",lg:"5px",xl:"5px",full:"9999px"},$={fontFamily:{sans:"'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif",serif:"'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"}},P={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)"}},Ie={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"},je={"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"]}},Ue={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(`
1823
+ `):""}function Y(){return`
1824
1824
  /* Spacing */
1825
1825
  --loki-space-xs: ${z.xs};
1826
1826
  --loki-space-sm: ${z.sm};
@@ -1870,7 +1870,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
1870
1870
  --loki-glass-bg: rgba(255, 255, 255, 0.03);
1871
1871
  --loki-glass-border: rgba(255, 255, 255, 0.06);
1872
1872
  --loki-glass-blur: blur(12px);
1873
- `}var V=`
1873
+ `}var W=`
1874
1874
  /* Reset and base */
1875
1875
  :host {
1876
1876
  font-family: var(--loki-font-sans);
@@ -2146,20 +2146,20 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
2146
2146
  }
2147
2147
 
2148
2148
  /* Responsive utilities */
2149
- @media (max-width: ${Pe.md}) {
2149
+ @media (max-width: ${Ie.md}) {
2150
2150
  .hide-mobile { display: none !important; }
2151
2151
  }
2152
2152
 
2153
- @media (min-width: ${Pe.md}) {
2153
+ @media (min-width: ${Ie.md}) {
2154
2154
  .hide-desktop { display: none !important; }
2155
2155
  }
2156
2156
  `,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`
2157
2157
  :host {
2158
2158
  ${E(t)}
2159
- ${K()}
2159
+ ${Y()}
2160
2160
  }
2161
- ${V}
2162
- `}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=Be[e];if(!i){console.warn(`Unknown keyboard action: ${e}`);return}this._handlers.set(e,{shortcut:i,handler:t})}unregister(e){this._handlers.delete(e)}setEnabled(e){this._enabled=e}handleEvent(e){if(!this._enabled)return!1;for(let[t,{shortcut:i,handler:a}]of this._handlers)if(this._matchesShortcut(e,i))return e.preventDefault(),e.stopPropagation(),a(e),!0;return!1}_matchesShortcut(e,t){let i=e.key.toLowerCase(),a=t.modifiers||[];if(i!==t.key.toLowerCase())return!1;let s=a.includes("Ctrl")||a.includes("Meta"),r=a.includes("Shift"),o=a.includes("Alt"),n=(e.ctrlKey||e.metaKey)===s,l=e.shiftKey===r,c=e.altKey===o;return n&&l&&c}attach(e){this._boundHandler||(this._boundHandler=t=>this.handleEvent(t)),e.addEventListener("keydown",this._boundHandler)}detach(e){this._boundHandler&&e.removeEventListener("keydown",this._boundHandler)}};var Fe={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)"}},Ze=`
2161
+ ${W}
2162
+ `}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=je[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)}},Fe="unknown";function q(d,e=t=>String(t)){if(d==null)return Fe;let t=typeof d=="number"?d:Number(d);return Number.isNaN(t)?Fe:e(t)}function I(d){return q(d,e=>e!==0&&Math.abs(e)<.01?e<0?">-$0.01":"<$0.01":(e<0?"-$":"$")+Math.abs(e).toFixed(2))}function Ne(d){return q(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 st(d){return q(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")}function rt(d,e=1){return q(d,t=>t.toFixed(e)+"%")}var Oe={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)"}},ot=`
2163
2163
  :host {
2164
2164
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
2165
2165
  line-height: 1.5;
@@ -2255,11 +2255,11 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
2255
2255
  ::-webkit-scrollbar-track { background: var(--loki-bg-primary); }
2256
2256
  ::-webkit-scrollbar-thumb { background: var(--loki-border); border-radius: 3px; }
2257
2257
  ::-webkit-scrollbar-thumb:hover { background: var(--loki-border-light); }
2258
- `,F=class F{static getTheme(){return w.getTheme()}static setTheme(e){w.setTheme(e)}static toggle(){return w.toggle()}static getVariables(e=null){let t=e||F.getTheme();return A[t]||Fe[t]||Fe.light}static toCSSString(e=null){let t=e||F.getTheme();if(A[t])return E(t);let i=F.getVariables(t);return Object.entries(i).map(([a,s])=>`${a}: ${s};`).join(`
2259
- `)}static applyToElement(e,t=null){let i=F.getVariables(t);for(let[a,s]of Object.entries(i))e.style.setProperty(a,s)}static init(){w.init()}static detectContext(){return w.detectContext()}static getAvailableThemes(){return Object.keys(A)}};S(F,"STORAGE_KEY","loki-theme");var j=F,v=class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}),this._theme=j.getTheme(),this._themeChangeHandler=this._onThemeChange.bind(this),this._keyboardHandler=new O}connectedCallback(){window.addEventListener("loki-theme-change",this._themeChangeHandler),this._applyTheme(),this._setupKeyboardHandling(),this.render()}disconnectedCallback(){window.removeEventListener("loki-theme-change",this._themeChangeHandler),this._keyboardHandler.detach(this)}_onThemeChange(e){this._theme=e.detail.theme,this._applyTheme(),this.onThemeChange&&this.onThemeChange(this._theme)}_applyTheme(){j.applyToElement(this.shadowRoot.host,this._theme),this.setAttribute("data-loki-theme",this._theme)}_setupKeyboardHandling(){this._keyboardHandler.attach(this)}registerShortcut(e,t){this._keyboardHandler.register(e,t)}getBaseStyles(){return`
2258
+ `,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]||Oe[t]||Oe.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(`
2259
+ `)}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`
2260
2260
  /* Design tokens */
2261
2261
  :host {
2262
- ${K()}
2262
+ ${Y()}
2263
2263
  }
2264
2264
 
2265
2265
  /* Light theme (default) */
@@ -2313,10 +2313,10 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
2313
2313
  }
2314
2314
  }
2315
2315
 
2316
- ${V}
2317
- `}getAriaPattern(e){return Ie[e]||{}}applyAriaPattern(e,t){let i=this.getAriaPattern(t);for(let[a,s]of Object.entries(i))if(a==="role")e.setAttribute("role",s);else{let r=a.replace(/([A-Z])/g,"-$1").toLowerCase();e.setAttribute(r,s)}}render(){}};var I={realtime:1e3,normal:2e3,background:5e3,offline:1e4},et={vscode:I.normal,browser:I.realtime,cli:I.background},tt={baseUrl:typeof window<"u"?window.location.origin:"http://localhost:57374",wsUrl:typeof window<"u"?`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/ws`:"ws://localhost:57374/ws",pollInterval:2e3,timeout:1e4,retryAttempts:3,retryDelay:1e3},f={CONNECTED:"api:connected",DISCONNECTED:"api:disconnected",ERROR:"api:error",STATUS_UPDATE:"api:status-update",TASK_CREATED:"api:task-created",TASK_UPDATED:"api:task-updated",TASK_DELETED:"api:task-deleted",PROJECT_CREATED:"api:project-created",PROJECT_UPDATED:"api:project-updated",AGENT_UPDATE:"api:agent-update",LOG_MESSAGE:"api:log-message",MEMORY_UPDATE:"api:memory-update",CHECKLIST_UPDATE:"api:checklist-update"},D=class D extends EventTarget{static getInstance(e={}){let t=e.baseUrl||tt.baseUrl;return D._instances.has(t)||D._instances.set(t,new D(e)),D._instances.get(t)}static clearInstances(){D._instances.forEach(e=>e.disconnect()),D._instances.clear()}constructor(e={}){super(),this.config={...tt,...e},this._ws=null,this._connected=!1,this._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=et[this._context]||I.normal,this._visibilityChangeHandler=null,this._messageHandler=null,this._setupAdaptivePolling(),this._setupVSCodeBridge()}_detectContext(){return typeof acquireVsCodeApi<"u"?"vscode":typeof window<"u"&&window.location?"browser":"cli"}get context(){return this._context}static get POLL_INTERVALS(){return I}_setupAdaptivePolling(){typeof document>"u"||(this._visibilityChangeHandler=()=>{document.hidden?this._setPollInterval(I.background):this._setPollInterval(et[this._context]||I.normal)},document.addEventListener("visibilitychange",this._visibilityChangeHandler))}_setPollInterval(e){this._currentPollInterval=e,this._pollInterval&&(this.stopPolling(),this.startPolling(null,e))}setPollMode(e){let t=I[e];t&&this._setPollInterval(t)}_setupVSCodeBridge(){if(!(typeof acquireVsCodeApi>"u")){try{this._vscodeApi=acquireVsCodeApi()}catch{console.warn("VS Code API already acquired or unavailable");return}this._messageHandler=e=>{let t=e.data;if(!(!t||!t.type))switch(t.type){case"updateStatus":this._emit(f.STATUS_UPDATE,t.data);break;case"updateTasks":this._emit(f.TASK_UPDATED,t.data);break;case"taskCreated":this._emit(f.TASK_CREATED,t.data);break;case"taskDeleted":this._emit(f.TASK_DELETED,t.data);break;case"projectCreated":this._emit(f.PROJECT_CREATED,t.data);break;case"projectUpdated":this._emit(f.PROJECT_UPDATED,t.data);break;case"agentUpdate":this._emit(f.AGENT_UPDATE,t.data);break;case"logMessage":this._emit(f.LOG_MESSAGE,t.data);break;case"memoryUpdate":this._emit(f.MEMORY_UPDATE,t.data);break;case"connected":this._connected=!0,this._emit(f.CONNECTED,t.data);break;case"disconnected":this._connected=!1,this._emit(f.DISCONNECTED,t.data);break;case"error":this._emit(f.ERROR,t.data);break;case"setPollMode":this.setPollMode(t.data.mode);break;default:this._emit(`api:${t.type}`,t.data)}},window.addEventListener("message",this._messageHandler)}}get isVSCode(){return this._context==="vscode"}postToVSCode(e,t={}){this._vscodeApi&&this._vscodeApi.postMessage({type:e,data:t})}requestRefresh(){this.postToVSCode("requestRefresh")}notifyVSCode(e,t={}){this.postToVSCode("userAction",{action:e,...t})}get baseUrl(){return this.config.baseUrl}set baseUrl(e){this.config.baseUrl=e,this.config.wsUrl=e.replace(/^http/,"ws")+"/ws"}get isConnected(){return this._connected}async connect(){if(this._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(D,"_instances",new Map);var N=D;function it(d={}){return new N(d)}function h(d={}){return N.getInstance(d)}var Ue="loki-state-change",je={ui:{theme:"light",sidebarCollapsed:!1,activeSection:"kanban",terminalAutoScroll:!0},session:{connected:!1,lastSync:null,mode:"offline",phase:null,iteration:null},localTasks:[],cache:{projects:[],tasks:[],agents:[],memory:null,lastFetch:null},preferences:{pollInterval:2e3,notifications:!0,soundEnabled:!1}},T=class T extends EventTarget{static getInstance(){return T._instance||(T._instance=new T),T._instance}constructor(){super(),this._state=this._loadState(),this._subscribers=new Map,this._batchUpdates=[],this._batchTimeout=null}_loadState(){try{let e=localStorage.getItem(T.STORAGE_KEY);if(e){let t=JSON.parse(e);return this._mergeState(je,t)}}catch(e){console.warn("Failed to load state from localStorage:",e)}return{...je}}_mergeState(e,t){let i={...e};for(let a of Object.keys(t))a in e&&typeof e[a]=="object"&&!Array.isArray(e[a])?i[a]=this._mergeState(e[a],t[a]):i[a]=t[a];return i}_saveState(){try{let e={ui:this._state.ui,localTasks:this._state.localTasks,preferences:this._state.preferences};localStorage.setItem(T.STORAGE_KEY,JSON.stringify(e))}catch(e){console.warn("Failed to save state to localStorage:",e)}}get(e=null){if(!e)return{...this._state};let t=e.split("."),i=this._state;for(let a of t){if(i==null)return;i=i[a]}return i}set(e,t,i=!0){let a=e.split("."),s=a.pop(),r=this._state;for(let n of a)n in r||(r[n]={}),r=r[n];let o=r[s];r[s]=t,i&&this._saveState(),this._notifyChange(e,t,o)}update(e,t=!0){let i=[];for(let[a,s]of Object.entries(e)){let r=this.get(a);this.set(a,s,!1),i.push({path:a,value:s,oldValue:r})}t&&this._saveState();for(let a of i)this._notifyChange(a.path,a.value,a.oldValue)}_notifyChange(e,t,i){this.dispatchEvent(new CustomEvent(Ue,{detail:{path:e,value:t,oldValue:i}}));let a=this._subscribers.get(e)||[];for(let r of a)try{r(t,i,e)}catch(o){console.error("State subscriber error:",o)}let s=e.split(".");for(;s.length>1;){s.pop();let r=s.join("."),o=this._subscribers.get(r)||[];for(let n of o)try{n(this.get(r),null,r)}catch(l){console.error("State subscriber error:",l)}}}subscribe(e,t){return this._subscribers.has(e)||this._subscribers.set(e,[]),this._subscribers.get(e).push(t),()=>{let i=this._subscribers.get(e),a=i.indexOf(t);a>-1&&i.splice(a,1)}}reset(e=null){if(e){let t=e.split("."),i=je;for(let a of t)i=i?.[a];this.set(e,i)}else this._state={...je},this._saveState(),this.dispatchEvent(new CustomEvent(Ue,{detail:{path:null,value:this._state,oldValue:null}}))}addLocalTask(e){let t=this.get("localTasks")||[],i={id:`local-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,createdAt:new Date().toISOString(),status:"pending",...e};return this.set("localTasks",[...t,i]),i}updateLocalTask(e,t){let i=this.get("localTasks")||[],a=i.findIndex(r=>r.id===e);if(a===-1)return null;let s={...i[a],...t,updatedAt:new Date().toISOString()};return i[a]=s,this.set("localTasks",[...i]),s}deleteLocalTask(e){let t=this.get("localTasks")||[];this.set("localTasks",t.filter(i=>i.id!==e))}moveLocalTask(e,t,i=null){let s=(this.get("localTasks")||[]).find(r=>r.id===e);return s?this.updateLocalTask(e,{status:t,position:i??s.position}):null}updateSession(e){this.update(Object.fromEntries(Object.entries(e).map(([t,i])=>[`session.${t}`,i])),!1)}updateCache(e){this.update({"cache.projects":e.projects??this.get("cache.projects"),"cache.tasks":e.tasks??this.get("cache.tasks"),"cache.agents":e.agents??this.get("cache.agents"),"cache.memory":e.memory??this.get("cache.memory"),"cache.lastFetch":new Date().toISOString()},!1)}getMergedTasks(){let e=this.get("cache.tasks")||[],i=(this.get("localTasks")||[]).map(a=>({...a,isLocal:!0}));return[...e,...i]}getTasksByStatus(e){return this.getMergedTasks().filter(t=>t.status===e)}};S(T,"STORAGE_KEY","loki-dashboard-state"),S(T,"_instance",null);var Y=T;function U(){return Y.getInstance()}function at(d){let e=U();return{get:()=>e.get(d),set:t=>e.set(d,t),subscribe:t=>e.subscribe(d,t)}}function Oe(d){return String(d??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function C(d){if(d==null||d==="")return"";let e=String(d).replace(/\r\n/g,`
2318
- `),t=[];e=e.replace(/```[^\n]*\n([\s\S]*?)```/g,(u,m)=>{let g=t.length;return t.push(`<pre class="md-code"><code>${Oe(m.replace(/\n$/,""))}</code></pre>`),`\0CODEBLOCK${g}\0`});let i=Oe(e);i=i.replace(/`([^`\n]+)`/g,(u,m)=>`<code class="md-inline-code">${m}</code>`),i=i.replace(/\[([^\]\n]+)\]\(([^)\s]+)\)/g,(u,m,g)=>/^(https?:|mailto:|\/|#|\.)/.test(g)?`<a class="md-link" href="${g}" target="_blank" rel="noopener noreferrer">${m}</a>`:u);let a=i.split(`
2319
- `),s=[],r=[],o=[],n=()=>{r.length&&(s.push(`<p class="md-p">${r.join("<br>")}</p>`),r=[])},l=u=>{for(;o.length&&o[o.length-1].indent>=u;)s.push(`</${o.pop().tag}>`)},c=()=>{for(;o.length;)s.push(`</${o.pop().tag}>`)};for(let u of a){let m=u,g=m.trim(),x=g.match(/^CODEBLOCK(\d+)$/);if(x){n(),c(),s.push(t[Number(x[1])]);continue}if(g===""){n(),c();continue}let k=g.match(/^(#{1,6})\s+(.+)$/);if(k){n(),c();let M=Math.min(k[1].length+1,6);s.push(`<h${M} class="md-h${M}">${k[2]}</h${M}>`);continue}if(/^(-{3,}|\*{3,}|_{3,})$/.test(g)){n(),c(),s.push('<hr class="md-hr">');continue}let _=g.match(/^&gt;\s?(.*)$/);if(_){n(),c(),s.push(`<blockquote class="md-quote">${_[1]}</blockquote>`);continue}let H=m.match(/^(\s*)/)[1].replace(/\t/g," ").length,J=g.match(/^([-*+])\s+(.+)$/),G=g.match(/^(\d+)[.)]\s+(.+)$/);if(J||G){n();let M=G?"ol":"ul",xt=J?J[2]:G[2];!o.length||H>o[o.length-1].indent?(s.push(`<${M} class="md-list">`),o.push({tag:M,indent:H})):(l(H+1),o.length||(s.push(`<${M} class="md-list">`),o.push({tag:M,indent:H}))),s.push(`<li>${xt}</li>`);continue}c(),r.push(m.trim())}n(),c();let p=s.join(`
2316
+ ${W}
2317
+ `}getAriaPattern(e){return Ue[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},nt={vscode:F.normal,browser:F.realtime,cli:F.background},lt={baseUrl:typeof window<"u"?window.location.origin:"http://localhost:57374",wsUrl:typeof window<"u"?`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/ws`:"ws://localhost:57374/ws",pollInterval:2e3,timeout:1e4,retryAttempts:3,retryDelay:1e3},f={CONNECTED:"api:connected",DISCONNECTED:"api:disconnected",ERROR:"api:error",STATUS_UPDATE:"api:status-update",TASK_CREATED:"api:task-created",TASK_UPDATED:"api:task-updated",TASK_DELETED:"api:task-deleted",PROJECT_CREATED:"api:project-created",PROJECT_UPDATED:"api:project-updated",AGENT_UPDATE:"api:agent-update",LOG_MESSAGE:"api:log-message",MEMORY_UPDATE:"api:memory-update",CHECKLIST_UPDATE:"api:checklist-update"},D=class D extends EventTarget{static getInstance(e={}){let t=e.baseUrl||lt.baseUrl;return D._instances.has(t)||D._instances.set(t,new D(e)),D._instances.get(t)}static clearInstances(){D._instances.forEach(e=>e.disconnect()),D._instances.clear()}constructor(e={}){super(),this.config={...lt,...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=nt[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(nt[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(D,"_instances",new Map);var J=D;function dt(d={}){return new J(d)}function h(d={}){return J.getInstance(d)}var Je="loki-state-change",qe={ui:{theme:"light",sidebarCollapsed:!1,activeSection:"kanban",terminalAutoScroll:!0},session:{connected:!1,lastSync:null,mode:"offline",phase:null,iteration:null},localTasks:[],cache:{projects:[],tasks:[],agents:[],memory:null,lastFetch:null},preferences:{pollInterval:2e3,notifications:!0,soundEnabled:!1}},T=class T extends EventTarget{static getInstance(){return T._instance||(T._instance=new T),T._instance}constructor(){super(),this._state=this._loadState(),this._subscribers=new Map,this._batchUpdates=[],this._batchTimeout=null}_loadState(){try{let e=localStorage.getItem(T.STORAGE_KEY);if(e){let t=JSON.parse(e);return this._mergeState(qe,t)}}catch(e){console.warn("Failed to load state from localStorage:",e)}return{...qe}}_mergeState(e,t){let i={...e};for(let a of Object.keys(t))a in e&&typeof e[a]=="object"&&!Array.isArray(e[a])?i[a]=this._mergeState(e[a],t[a]):i[a]=t[a];return i}_saveState(){try{let e={ui:this._state.ui,localTasks:this._state.localTasks,preferences:this._state.preferences};localStorage.setItem(T.STORAGE_KEY,JSON.stringify(e))}catch(e){console.warn("Failed to save state to localStorage:",e)}}get(e=null){if(!e)return{...this._state};let t=e.split("."),i=this._state;for(let a of t){if(i==null)return;i=i[a]}return i}set(e,t,i=!0){let a=e.split("."),s=a.pop(),r=this._state;for(let n of a)n in r||(r[n]={}),r=r[n];let o=r[s];r[s]=t,i&&this._saveState(),this._notifyChange(e,t,o)}update(e,t=!0){let i=[];for(let[a,s]of Object.entries(e)){let r=this.get(a);this.set(a,s,!1),i.push({path:a,value:s,oldValue:r})}t&&this._saveState();for(let a of i)this._notifyChange(a.path,a.value,a.oldValue)}_notifyChange(e,t,i){this.dispatchEvent(new CustomEvent(Je,{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=qe;for(let a of t)i=i?.[a];this.set(e,i)}else this._state={...qe},this._saveState(),this.dispatchEvent(new CustomEvent(Je,{detail:{path:null,value:this._state,oldValue:null}}))}addLocalTask(e){let t=this.get("localTasks")||[],i={id:`local-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,createdAt:new Date().toISOString(),status:"pending",...e};return this.set("localTasks",[...t,i]),i}updateLocalTask(e,t){let i=this.get("localTasks")||[],a=i.findIndex(r=>r.id===e);if(a===-1)return null;let s={...i[a],...t,updatedAt:new Date().toISOString()};return i[a]=s,this.set("localTasks",[...i]),s}deleteLocalTask(e){let t=this.get("localTasks")||[];this.set("localTasks",t.filter(i=>i.id!==e))}moveLocalTask(e,t,i=null){let s=(this.get("localTasks")||[]).find(r=>r.id===e);return s?this.updateLocalTask(e,{status:t,position:i??s.position}):null}updateSession(e){this.update(Object.fromEntries(Object.entries(e).map(([t,i])=>[`session.${t}`,i])),!1)}updateCache(e){this.update({"cache.projects":e.projects??this.get("cache.projects"),"cache.tasks":e.tasks??this.get("cache.tasks"),"cache.agents":e.agents??this.get("cache.agents"),"cache.memory":e.memory??this.get("cache.memory"),"cache.lastFetch":new Date().toISOString()},!1)}getMergedTasks(){let e=this.get("cache.tasks")||[],i=(this.get("localTasks")||[]).map(a=>({...a,isLocal:!0}));return[...e,...i]}getTasksByStatus(e){return this.getMergedTasks().filter(t=>t.status===e)}};S(T,"STORAGE_KEY","loki-dashboard-state"),S(T,"_instance",null);var Q=T;function N(){return Q.getInstance()}function ct(d){let e=N();return{get:()=>e.get(d),set:t=>e.set(d,t),subscribe:t=>e.subscribe(d,t)}}function Ge(d){return String(d??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function C(d){if(d==null||d==="")return"";let e=String(d).replace(/\r\n/g,`
2318
+ `),t=[];e=e.replace(/```[^\n]*\n([\s\S]*?)```/g,(u,m)=>{let g=t.length;return t.push(`<pre class="md-code"><code>${Ge(m.replace(/\n$/,""))}</code></pre>`),`\0CODEBLOCK${g}\0`});let i=Ge(e);i=i.replace(/`([^`\n]+)`/g,(u,m)=>`<code class="md-inline-code">${m}</code>`),i=i.replace(/\[([^\]\n]+)\]\(([^)\s]+)\)/g,(u,m,g)=>/^(https?:|mailto:|\/|#|\.)/.test(g)?`<a class="md-link" href="${g}" target="_blank" rel="noopener noreferrer">${m}</a>`:u);let a=i.split(`
2319
+ `),s=[],r=[],o=[],n=()=>{r.length&&(s.push(`<p class="md-p">${r.join("<br>")}</p>`),r=[])},l=u=>{for(;o.length&&o[o.length-1].indent>=u;)s.push(`</${o.pop().tag}>`)},c=()=>{for(;o.length;)s.push(`</${o.pop().tag}>`)};for(let u of a){let m=u,g=m.trim(),x=g.match(/^CODEBLOCK(\d+)$/);if(x){n(),c(),s.push(t[Number(x[1])]);continue}if(g===""){n(),c();continue}let k=g.match(/^(#{1,6})\s+(.+)$/);if(k){n(),c();let M=Math.min(k[1].length+1,6);s.push(`<h${M} class="md-h${M}">${k[2]}</h${M}>`);continue}if(/^(-{3,}|\*{3,}|_{3,})$/.test(g)){n(),c(),s.push('<hr class="md-hr">');continue}let _=g.match(/^&gt;\s?(.*)$/);if(_){n(),c(),s.push(`<blockquote class="md-quote">${_[1]}</blockquote>`);continue}let H=m.match(/^(\s*)/)[1].replace(/\t/g," ").length,K=g.match(/^([-*+])\s+(.+)$/),V=g.match(/^(\d+)[.)]\s+(.+)$/);if(K||V){n();let M=V?"ol":"ul",Lt=K?K[2]:V[2];!o.length||H>o[o.length-1].indent?(s.push(`<${M} class="md-list">`),o.push({tag:M,indent:H})):(l(H+1),o.length||(s.push(`<${M} class="md-list">`),o.push({tag:M,indent:H}))),s.push(`<li>${Lt}</li>`);continue}c(),r.push(m.trim())}n(),c();let p=s.join(`
2320
2320
  `);return p=p.replace(/\*\*([^*\n]+)\*\*/g,"<strong>$1</strong>"),p=p.replace(/__([^_\n]+)__/g,"<strong>$1</strong>"),p=p.replace(/(^|[^*])\*([^*\n]+)\*/g,"$1<em>$2</em>"),p}var L=`
2321
2321
  .md-body { line-height: 1.6; color: var(--loki-text, #2b2a28); font-size: 14px; word-wrap: break-word; }
2322
2322
  .md-body .md-h2 { font-size: 18px; font-weight: 650; margin: 18px 0 8px; }
@@ -2333,7 +2333,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
2333
2333
  .md-body .md-link:hover { text-decoration: underline; }
2334
2334
  .md-body .md-hr { border: 0; border-top: 1px solid var(--loki-border, #e5e1d8); margin: 16px 0; }
2335
2335
  .md-body strong { font-weight: 650; }
2336
- `;function st(d){return!d||typeof d!="string"?null:d.startsWith("page-")?d.slice(5):d}function Ne(){if(typeof document>"u")return null;let d=document.querySelector(".section-page.active");if(d&&d.id)return st(d.id);try{if(typeof localStorage<"u"){let e=localStorage.getItem("loki-active-section");if(e)return e}}catch{}return null}var Ge=class{constructor(){this._regs=new Map,this._seq=0,this._activeSection=Ne(),this._hidden=typeof document<"u"?!!document.hidden:!1,this._listenersInstalled=!1,this._sectionChangeHandler=null,this._visibilityHandler=null,this._mutationObserver=null}get _hasDom(){return typeof document<"u"}_ensureListeners(){if(!(this._listenersInstalled||!this._hasDom)){this._sectionChangeHandler=e=>{let t=e&&e.detail&&e.detail.section?e.detail.section:Ne();this._setActiveSection(t)},document.addEventListener("loki:section-change",this._sectionChangeHandler),this._visibilityHandler=()=>{let e=!!document.hidden;e!==this._hidden&&(this._hidden=e,e||(this._activeSection=Ne()),this._reevaluateAll())},document.addEventListener("visibilitychange",this._visibilityHandler);try{let e=document.getElementById("main-content")||document.body;e&&typeof MutationObserver<"u"&&(this._mutationObserver=new MutationObserver(()=>{let t=Ne();t&&t!==this._activeSection&&this._setActiveSection(t)}),this._mutationObserver.observe(e,{subtree:!0,attributes:!0,attributeFilter:["class"]}))}catch{}this._listenersInstalled=!0}}_setActiveSection(e){e!==this._activeSection&&(this._activeSection=e,this._reevaluateAll())}_resolveSection(e){if(Object.prototype.hasOwnProperty.call(e,"sectionId"))return e.sectionId===null?void 0:e.sectionId;if(e.element&&typeof e.element.closest=="function"){let t=e.element.closest(".section-page"),i=st(t&&t.id);return i===null?void 0:i}}_isAllowed(e){if(!this._hasDom)return!0;if(this._hidden)return!1;let t=this._resolveSection(e);return t===void 0?!0:t===this._activeSection}_reevaluateAll(){for(let e of this._regs.values()){let t=this._isAllowed(e);t&&!e._wasAllowed?(e._wasAllowed=!0,this._safeRun(e)):e._wasAllowed=t}}_safeRun(e){try{let t=e.loadFn();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}register(e={}){let{loadFn:t,intervalMs:i}=e;if(typeof t!="function")throw new Error("registerPoll: loadFn must be a function");if(typeof i!="number"||!(i>0))throw new Error("registerPoll: intervalMs must be a positive number");this._ensureListeners();let a=e.id||`poll-${++this._seq}`;this._regs.has(a)&&this._stopReg(this._regs.get(a));let s={id:a,loadFn:t,intervalMs:i,element:e.element||null,_timer:null,_wasAllowed:!1};return Object.prototype.hasOwnProperty.call(e,"sectionId")&&(s.sectionId=e.sectionId),s._wasAllowed=this._isAllowed(s),s._timer=setInterval(()=>{this._isAllowed(s)?(s._wasAllowed=!0,this._safeRun(s)):s._wasAllowed=!1},i),this._regs.set(a,s),e.immediate!==!1&&s._wasAllowed&&this._safeRun(s),{id:a,stop:()=>this.unregister(a),isActive:()=>this._isAllowed(s)}}_stopReg(e){e&&e._timer&&(clearInterval(e._timer),e._timer=null)}unregister(e){let t=this._regs.get(e);return t?(this._stopReg(t),this._regs.delete(e),!0):!1}get activeSection(){return this._activeSection}get size(){return this._regs.size}destroy(){for(let e of this._regs.values())this._stopReg(e);this._regs.clear(),this._hasDom&&(this._sectionChangeHandler&&(document.removeEventListener("loki:section-change",this._sectionChangeHandler),this._sectionChangeHandler=null),this._visibilityHandler&&(document.removeEventListener("visibilitychange",this._visibilityHandler),this._visibilityHandler=null),this._mutationObserver&&(this._mutationObserver.disconnect(),this._mutationObserver=null)),this._listenersInstalled=!1}},Je=null;function At(){return Je||(Je=new Ge),Je}function b(d){return At().register(d)}var W=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data={status:"offline",phase:null,iteration:null,provider:null,running_agents:0,pending_tasks:null,uptime_seconds:0,complexity:null,connected:!1},this._api=null,this._pollInterval=null,this._statusUpdateHandler=null,this._connectedHandler=null,this._disconnectedHandler=null,this._checklistSummary=null,this._appRunnerStatus=null,this._playwrightResults=null,this._gateStatus=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._startPolling(),this._api.connect().catch(()=>{})}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._loadAbortController&&(this._loadAbortController.abort(),this._loadAbortController=null),this._teardownApiListeners()}attributeChangedCallback(e,t,i){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=h({baseUrl:e}),this._statusUpdateHandler=t=>this._updateFromStatus(t.detail),this._connectedHandler=()=>{this._data.connected=!0,this.render()},this._disconnectedHandler=()=>{this._data.connected=!1,this._data.status="offline",this.render()},this._api.addEventListener(f.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(f.CONNECTED,this._connectedHandler),this._api.addEventListener(f.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){this._loadAbortController&&this._loadAbortController.abort(),this._loadAbortController=new AbortController;let{signal:e}=this._loadAbortController;try{let[t,i,a,s,r]=await Promise.allSettled([this._api.getStatus(),this._api.getChecklistSummary(),this._api.getAppRunnerStatus(),this._api.getPlaywrightResults(),this._api.getCouncilGate()]);if(e.aborted)return;t.status==="fulfilled"?this._updateFromStatus(t.value):(this._data.connected=!1,this._data.status="offline"),i.status==="fulfilled"&&(this._checklistSummary=i.value?.summary||null),a.status==="fulfilled"&&(this._appRunnerStatus=a.value),s.status==="fulfilled"&&(this._playwrightResults=s.value),r.status==="fulfilled"&&(this._gateStatus=r.value),this.render()}catch{if(e.aborted)return;this._data.connected=!1,this._data.status="offline",this.render()}}_updateFromStatus(e){e&&(this._data={...this._data,connected:!0,status:e.status||"offline",phase:e.phase||null,iteration:e.iteration!=null?e.iteration:null,provider:e.provider||null,running_agents:e.running_agents||0,pending_tasks:e.pending_tasks!=null?e.pending_tasks:null,uptime_seconds:e.uptime_seconds||0,complexity:e.complexity||null})}_startPolling(){this._poll=b({loadFn:async()=>{try{await this._loadStatus()}catch{this._data.connected=!1,this._data.status="offline",this.render()}},intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_formatUptime(e){if(!e||e<0)return"--";let t=Math.floor(e/3600),i=Math.floor(e%3600/60),a=Math.floor(e%60);return t>0?`${t}h ${i}m`:i>0?`${i}m ${a}s`:`${a}s`}_getStatusDotClass(){switch(this._data.status){case"running":case"autonomous":return"active";case"paused":return"paused";case"stopped":return"stopped";case"error":return"error";default:return"offline"}}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_renderAppRunnerCard(){let e=this._appRunnerStatus;if(!e||e.status==="not_initialized")return`
2336
+ `;function pt(d){return!d||typeof d!="string"?null:d.startsWith("page-")?d.slice(5):d}function Ke(){if(typeof document>"u")return null;let d=document.querySelector(".section-page.active");if(d&&d.id)return pt(d.id);try{if(typeof localStorage<"u"){let e=localStorage.getItem("loki-active-section");if(e)return e}}catch{}return null}var We=class{constructor(){this._regs=new Map,this._seq=0,this._activeSection=Ke(),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:Ke();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=Ke()),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=Ke();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=pt(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}},Ye=null;function It(){return Ye||(Ye=new We),Ye}function b(d){return It().register(d)}var X=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data={status:"offline",phase:null,iteration:null,provider:null,running_agents:0,pending_tasks:null,uptime_seconds:0,complexity:null,connected:!1},this._api=null,this._pollInterval=null,this._statusUpdateHandler=null,this._connectedHandler=null,this._disconnectedHandler=null,this._checklistSummary=null,this._appRunnerStatus=null,this._playwrightResults=null,this._gateStatus=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._startPolling(),this._api.connect().catch(()=>{})}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._loadAbortController&&(this._loadAbortController.abort(),this._loadAbortController=null),this._teardownApiListeners()}attributeChangedCallback(e,t,i){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=h({baseUrl:e}),this._statusUpdateHandler=t=>this._updateFromStatus(t.detail),this._connectedHandler=()=>{this._data.connected=!0,this.render()},this._disconnectedHandler=()=>{this._data.connected=!1,this._data.status="offline",this.render()},this._api.addEventListener(f.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(f.CONNECTED,this._connectedHandler),this._api.addEventListener(f.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){this._loadAbortController&&this._loadAbortController.abort(),this._loadAbortController=new AbortController;let{signal:e}=this._loadAbortController;try{let[t,i,a,s,r]=await Promise.allSettled([this._api.getStatus(),this._api.getChecklistSummary(),this._api.getAppRunnerStatus(),this._api.getPlaywrightResults(),this._api.getCouncilGate()]);if(e.aborted)return;t.status==="fulfilled"?this._updateFromStatus(t.value):(this._data.connected=!1,this._data.status="offline"),i.status==="fulfilled"&&(this._checklistSummary=i.value?.summary||null),a.status==="fulfilled"&&(this._appRunnerStatus=a.value),s.status==="fulfilled"&&(this._playwrightResults=s.value),r.status==="fulfilled"&&(this._gateStatus=r.value),this.render()}catch{if(e.aborted)return;this._data.connected=!1,this._data.status="offline",this.render()}}_updateFromStatus(e){e&&(this._data={...this._data,connected:!0,status:e.status||"offline",phase:e.phase||null,iteration:e.iteration!=null?e.iteration:null,provider:e.provider||null,running_agents:e.running_agents||0,pending_tasks:e.pending_tasks!=null?e.pending_tasks:null,uptime_seconds:e.uptime_seconds||0,complexity:e.complexity||null})}_startPolling(){this._poll=b({loadFn:async()=>{try{await this._loadStatus()}catch{this._data.connected=!1,this._data.status="offline",this.render()}},intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_formatUptime(e){if(!e||e<0)return"--";let t=Math.floor(e/3600),i=Math.floor(e%3600/60),a=Math.floor(e%60);return t>0?`${t}h ${i}m`:i>0?`${i}m ${a}s`:`${a}s`}_getStatusDotClass(){switch(this._data.status){case"running":case"autonomous":return"active";case"paused":return"paused";case"stopped":return"stopped";case"error":return"error";default:return"offline"}}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_renderAppRunnerCard(){let e=this._appRunnerStatus;if(!e||e.status==="not_initialized")return`
2337
2337
  <div class="overview-card">
2338
2338
  <div class="card-label">App Status</div>
2339
2339
  <div class="card-value small-text">${this._data.status==="running"||this._data.status==="autonomous"?"Starting...":"Not started"}</div>
@@ -2588,7 +2588,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
2588
2588
  </div>
2589
2589
  </div>
2590
2590
  </div>
2591
- `}};customElements.get("loki-overview")||customElements.define("loki-overview",W);var Tt=[{id:"pending",label:"Pending",status:"pending",color:"var(--loki-text-muted)"},{id:"in_progress",label:"In Progress",status:"in_progress",color:"var(--loki-blue)"},{id:"review",label:"In Review",status:"review",color:"var(--loki-purple)"},{id:"done",label:"Completed",status:"done",color:"var(--loki-green)"}],Q=class d extends v{static get observedAttributes(){return["api-url","project-id","theme","readonly"]}constructor(){super(),this._tasks=[],this._loading=!0,this._error=null,this._draggedTask=null,this._selectedTask=null,this._expandedCards=new Set,this._selectedTasks=new Set,this._bulkMode=!1,this._activeFilter="all",this._searchQuery="",this._visibleCounts={},this._api=null,this._state=U()}static get PAGE_SIZE(){return 10}_getVisibleCount(e){let t=this._visibleCounts[e];return typeof t=="number"&&t>0?t:d.PAGE_SIZE}_showMore(e){this._visibleCounts[e]=this._getVisibleCount(e)+d.PAGE_SIZE,this.render()}_columnIcon(e){switch(e){case"pending":return'<circle cx="12" cy="12" r="10"/>';case"in_progress":return'<path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/>';case"review":return'<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/>';case"done":return'<path d="M22 11.08V12a10 10 0 11-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/>';default:return'<circle cx="12" cy="12" r="10"/>'}}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadTasks()}disconnectedCallback(){super.disconnectedCallback(),this._teardownApiListeners()}_teardownApiListeners(){this._api&&this._onTaskEvent&&(this._api.removeEventListener(f.TASK_CREATED,this._onTaskEvent),this._api.removeEventListener(f.TASK_UPDATED,this._onTaskEvent),this._api.removeEventListener(f.TASK_DELETED,this._onTaskEvent))}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._teardownApiListeners(),this._setupApi(),this._loadTasks()),e==="project-id"&&this._loadTasks(),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e}),this._onTaskEvent=()=>this._loadTasks(),this._api.addEventListener(f.TASK_CREATED,this._onTaskEvent),this._api.addEventListener(f.TASK_UPDATED,this._onTaskEvent),this._api.addEventListener(f.TASK_DELETED,this._onTaskEvent)}async _loadTasks(){let e=this._api;this._loading=!0,this._error=null,this.render();try{let t=this.getAttribute("project-id"),i=t?{projectId:parseInt(t)}:{},a=await e.listTasks(i);if(e!==this._api)return;this._tasks=a;let s=this._state.get("localTasks")||[];s.length>0&&(this._tasks=[...this._tasks,...s.map(r=>({...r,isLocal:!0}))]),this._state.update({"cache.tasks":this._tasks},!1)}catch(t){if(e!==this._api)return;this._error=t.message,this._tasks=(this._state.get("localTasks")||[]).map(i=>({...i,isLocal:!0}))}this._loading=!1,this.render()}_getTasksByStatus(e){return this._getFilteredTasks().filter(i=>i.status?.toLowerCase().replace(/-/g,"_")===e)}_handleDragStart(e,t){this.hasAttribute("readonly")||(this._draggedTask=t,e.target.classList.add("dragging"),e.dataTransfer.effectAllowed="move",e.dataTransfer.setData("text/plain",t.id.toString()))}_handleDragEnd(e){e.target.classList.remove("dragging"),this._draggedTask=null,this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(t=>{t.classList.remove("drag-over")})}_handleDragOver(e){e.preventDefault(),e.dataTransfer.dropEffect="move"}_handleDragEnter(e){e.preventDefault(),e.currentTarget.classList.add("drag-over")}_handleDragLeave(e){e.currentTarget.contains(e.relatedTarget)||e.currentTarget.classList.remove("drag-over")}async _handleDrop(e,t){if(e.preventDefault(),e.currentTarget.classList.remove("drag-over"),!this._draggedTask||this.hasAttribute("readonly"))return;let i=this._draggedTask.id,a=this._tasks.find(r=>r.id===i);if(!a)return;let s=a.status;if(s!==t){a.status=t,this.render();try{a.isLocal?this._state.moveLocalTask(i,t):await this._api.moveTask(i,t,0),this.dispatchEvent(new CustomEvent("task-moved",{detail:{taskId:i,oldStatus:s,newStatus:t}}))}catch(r){a.status=s,this.render(),console.error("Failed to move task:",r)}}}_toggleCardExpand(e){this._expandedCards.has(e)?this._expandedCards.delete(e):this._expandedCards.add(e),this.render()}_toggleTaskSelection(e,t){t&&t.stopPropagation(),this._selectedTasks.has(e)?this._selectedTasks.delete(e):this._selectedTasks.add(e),this.render()}_toggleBulkMode(){this._bulkMode=!this._bulkMode,this._bulkMode||this._selectedTasks.clear(),this.render()}async _bulkMove(e){let t=[...this._selectedTasks];for(let i of t){let a=this._tasks.find(s=>String(s.id)===String(i));if(a&&a.status!==e)try{a.isLocal?this._state.moveLocalTask(i,e):await this._api.moveTask(i,e,0),a.status=e}catch(s){console.error("Failed to bulk move task:",i,s)}}this._selectedTasks.clear(),this._bulkMode=!1,this.render(),this._loadTasks()}async _bulkDelete(){let e=[...this._selectedTasks];for(let t of e)try{await this._api.deleteTask(t)}catch(i){console.error("Failed to delete task:",t,i)}this._selectedTasks.clear(),this._bulkMode=!1,this._loadTasks()}_setFilter(e){this._activeFilter=e,this._visibleCounts={},this.render()}_setSearch(e){this._searchQuery=e||"",this._visibleCounts={},this._renderTaskRegion();let t=this.shadowRoot.getElementById("task-search");if(t){t.focus();let i=t.value.length;try{t.setSelectionRange(i,i)}catch{}}}_getFilteredTasks(){let e=[...this._tasks],t=new Date,i=new Date(t.getFullYear(),t.getMonth(),t.getDate()),a=new Date(i.getTime()-7*24*60*60*1e3);switch(this._activeFilter){case"today":e=e.filter(r=>{let o=r.created_at?new Date(r.created_at):null;return o&&o>=i});break;case"this-week":e=e.filter(r=>{let o=r.created_at?new Date(r.created_at):null;return o&&o>=a});break;case"running":e=e.filter(r=>r.status==="in_progress");break;case"failed":e=e.filter(r=>r.status==="failed"||r.status==="error");break;default:break}let s=this._searchQuery.trim().toLowerCase();return s&&(e=e.filter(r=>[r.id,r.title,r.description,r.type].map(n=>String(n??"").toLowerCase()).join(" ").includes(s))),e}_openAddTaskModal(e="pending"){this.dispatchEvent(new CustomEvent("add-task",{detail:{status:e}}))}_openTaskDetail(e){this._selectedTask=e,this.render(),this.dispatchEvent(new CustomEvent("task-click",{detail:{task:e}}))}_closeTaskDetail(){this._selectedTask=null,this.render()}_renderMarkdown(e){return C(e)}_formatTimestamp(e){if(!e)return"";try{let t=new Date(e);return isNaN(t.getTime())?this._escapeHtml(String(e)):t.toLocaleString()}catch{return this._escapeHtml(String(e))}}_phaseClass(e){let t=String(e||"").toLowerCase();return["reason","plan","planning"].includes(t)?"phase-reason":["act","execute","execution","implement"].includes(t)?"phase-act":["reflect","review"].includes(t)?"phase-reflect":["verify","test","gate"].includes(t)?"phase-verify":"phase-default"}_logLevelClass(e){let t=String(e||"info").toLowerCase();return t==="error"||t==="fatal"?"log-error":t==="warn"||t==="warning"?"log-warn":t==="debug"||t==="trace"?"log-debug":"log-info"}_renderTaskDetailModal(e){if(!e)return"";let t=(e.priority||"medium").toLowerCase(),i=t.charAt(0).toUpperCase()+t.slice(1),a=e.status||"pending",s=a.replace(/_/g," ").replace(/\b\w/g,g=>g.toUpperCase()),r=e.metadata||{},o=Array.isArray(e.acceptance_criteria)?e.acceptance_criteria:[],n=Array.isArray(e.context_files)?e.context_files:[],l=e.specification||"",c=e.description||"",p=Array.isArray(e.notes)?e.notes:[],u=Array.isArray(e.logs)?e.logs:[],m=e.full_content||"";return`
2591
+ `}};customElements.get("loki-overview")||customElements.define("loki-overview",X);var Ft=[{id:"pending",label:"Pending",status:"pending",color:"var(--loki-text-muted)"},{id:"in_progress",label:"In Progress",status:"in_progress",color:"var(--loki-blue)"},{id:"review",label:"In Review",status:"review",color:"var(--loki-purple)"},{id:"done",label:"Completed",status:"done",color:"var(--loki-green)"}],Z=class d extends v{static get observedAttributes(){return["api-url","project-id","theme","readonly"]}constructor(){super(),this._tasks=[],this._loading=!0,this._error=null,this._draggedTask=null,this._selectedTask=null,this._expandedCards=new Set,this._selectedTasks=new Set,this._bulkMode=!1,this._activeFilter="all",this._searchQuery="",this._visibleCounts={},this._api=null,this._state=N()}static get PAGE_SIZE(){return 10}_getVisibleCount(e){let t=this._visibleCounts[e];return typeof t=="number"&&t>0?t:d.PAGE_SIZE}_showMore(e){this._visibleCounts[e]=this._getVisibleCount(e)+d.PAGE_SIZE,this.render()}_columnIcon(e){switch(e){case"pending":return'<circle cx="12" cy="12" r="10"/>';case"in_progress":return'<path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/>';case"review":return'<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/>';case"done":return'<path d="M22 11.08V12a10 10 0 11-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/>';default:return'<circle cx="12" cy="12" r="10"/>'}}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadTasks()}disconnectedCallback(){super.disconnectedCallback(),this._teardownApiListeners()}_teardownApiListeners(){this._api&&this._onTaskEvent&&(this._api.removeEventListener(f.TASK_CREATED,this._onTaskEvent),this._api.removeEventListener(f.TASK_UPDATED,this._onTaskEvent),this._api.removeEventListener(f.TASK_DELETED,this._onTaskEvent))}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._teardownApiListeners(),this._setupApi(),this._loadTasks()),e==="project-id"&&this._loadTasks(),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e}),this._onTaskEvent=()=>this._loadTasks(),this._api.addEventListener(f.TASK_CREATED,this._onTaskEvent),this._api.addEventListener(f.TASK_UPDATED,this._onTaskEvent),this._api.addEventListener(f.TASK_DELETED,this._onTaskEvent)}async _loadTasks(){let e=this._api;this._loading=!0,this._error=null,this.render();try{let t=this.getAttribute("project-id"),i=t?{projectId:parseInt(t)}:{},a=await e.listTasks(i);if(e!==this._api)return;this._tasks=a;let s=this._state.get("localTasks")||[];s.length>0&&(this._tasks=[...this._tasks,...s.map(r=>({...r,isLocal:!0}))]),this._state.update({"cache.tasks":this._tasks},!1)}catch(t){if(e!==this._api)return;this._error=t.message,this._tasks=(this._state.get("localTasks")||[]).map(i=>({...i,isLocal:!0}))}this._loading=!1,this.render()}_getTasksByStatus(e){return this._getFilteredTasks().filter(i=>i.status?.toLowerCase().replace(/-/g,"_")===e)}_handleDragStart(e,t){this.hasAttribute("readonly")||(this._draggedTask=t,e.target.classList.add("dragging"),e.dataTransfer.effectAllowed="move",e.dataTransfer.setData("text/plain",t.id.toString()))}_handleDragEnd(e){e.target.classList.remove("dragging"),this._draggedTask=null,this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(t=>{t.classList.remove("drag-over")})}_handleDragOver(e){e.preventDefault(),e.dataTransfer.dropEffect="move"}_handleDragEnter(e){e.preventDefault(),e.currentTarget.classList.add("drag-over")}_handleDragLeave(e){e.currentTarget.contains(e.relatedTarget)||e.currentTarget.classList.remove("drag-over")}async _handleDrop(e,t){if(e.preventDefault(),e.currentTarget.classList.remove("drag-over"),!this._draggedTask||this.hasAttribute("readonly"))return;let i=this._draggedTask.id,a=this._tasks.find(r=>r.id===i);if(!a)return;let s=a.status;if(s!==t){a.status=t,this.render();try{a.isLocal?this._state.moveLocalTask(i,t):await this._api.moveTask(i,t,0),this.dispatchEvent(new CustomEvent("task-moved",{detail:{taskId:i,oldStatus:s,newStatus:t}}))}catch(r){a.status=s,this.render(),console.error("Failed to move task:",r)}}}_toggleCardExpand(e){this._expandedCards.has(e)?this._expandedCards.delete(e):this._expandedCards.add(e),this.render()}_toggleTaskSelection(e,t){t&&t.stopPropagation(),this._selectedTasks.has(e)?this._selectedTasks.delete(e):this._selectedTasks.add(e),this.render()}_toggleBulkMode(){this._bulkMode=!this._bulkMode,this._bulkMode||this._selectedTasks.clear(),this.render()}async _bulkMove(e){let t=[...this._selectedTasks];for(let i of t){let a=this._tasks.find(s=>String(s.id)===String(i));if(a&&a.status!==e)try{a.isLocal?this._state.moveLocalTask(i,e):await this._api.moveTask(i,e,0),a.status=e}catch(s){console.error("Failed to bulk move task:",i,s)}}this._selectedTasks.clear(),this._bulkMode=!1,this.render(),this._loadTasks()}async _bulkDelete(){let e=[...this._selectedTasks];for(let t of e)try{await this._api.deleteTask(t)}catch(i){console.error("Failed to delete task:",t,i)}this._selectedTasks.clear(),this._bulkMode=!1,this._loadTasks()}_setFilter(e){this._activeFilter=e,this._visibleCounts={},this.render()}_setSearch(e){this._searchQuery=e||"",this._visibleCounts={},this._renderTaskRegion();let t=this.shadowRoot.getElementById("task-search");if(t){t.focus();let i=t.value.length;try{t.setSelectionRange(i,i)}catch{}}}_getFilteredTasks(){let e=[...this._tasks],t=new Date,i=new Date(t.getFullYear(),t.getMonth(),t.getDate()),a=new Date(i.getTime()-7*24*60*60*1e3);switch(this._activeFilter){case"today":e=e.filter(r=>{let o=r.created_at?new Date(r.created_at):null;return o&&o>=i});break;case"this-week":e=e.filter(r=>{let o=r.created_at?new Date(r.created_at):null;return o&&o>=a});break;case"running":e=e.filter(r=>r.status==="in_progress");break;case"failed":e=e.filter(r=>r.status==="failed"||r.status==="error");break;default:break}let s=this._searchQuery.trim().toLowerCase();return s&&(e=e.filter(r=>[r.id,r.title,r.description,r.type].map(n=>String(n??"").toLowerCase()).join(" ").includes(s))),e}_openAddTaskModal(e="pending"){this.dispatchEvent(new CustomEvent("add-task",{detail:{status:e}}))}_openTaskDetail(e){this._selectedTask=e,this.render(),this.dispatchEvent(new CustomEvent("task-click",{detail:{task:e}}))}_closeTaskDetail(){this._selectedTask=null,this.render()}_renderMarkdown(e){return C(e)}_formatTimestamp(e){if(!e)return"";try{let t=new Date(e);return isNaN(t.getTime())?this._escapeHtml(String(e)):t.toLocaleString()}catch{return this._escapeHtml(String(e))}}_phaseClass(e){let t=String(e||"").toLowerCase();return["reason","plan","planning"].includes(t)?"phase-reason":["act","execute","execution","implement"].includes(t)?"phase-act":["reflect","review"].includes(t)?"phase-reflect":["verify","test","gate"].includes(t)?"phase-verify":"phase-default"}_logLevelClass(e){let t=String(e||"info").toLowerCase();return t==="error"||t==="fatal"?"log-error":t==="warn"||t==="warning"?"log-warn":t==="debug"||t==="trace"?"log-debug":"log-info"}_renderTaskDetailModal(e){if(!e)return"";let t=(e.priority||"medium").toLowerCase(),i=t.charAt(0).toUpperCase()+t.slice(1),a=e.status||"pending",s=a.replace(/_/g," ").replace(/\b\w/g,g=>g.toUpperCase()),r=e.metadata||{},o=Array.isArray(e.acceptance_criteria)?e.acceptance_criteria:[],n=Array.isArray(e.context_files)?e.context_files:[],l=e.specification||"",c=e.description||"",p=Array.isArray(e.notes)?e.notes:[],u=Array.isArray(e.logs)?e.logs:[],m=e.full_content||"";return`
2592
2592
  <div class="modal-overlay" id="task-detail-overlay">
2593
2593
  <div class="modal-container">
2594
2594
  <div class="modal-header">
@@ -2661,11 +2661,11 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
2661
2661
  <h3 class="modal-section-title">Logs</h3>
2662
2662
  <div class="logs-scroll">
2663
2663
  <ul class="logs-timeline" role="list">
2664
- ${u.map(g=>{let x=this._formatTimestamp(g&&g.timestamp),k=g&&g.iteration!==void 0&&g.iteration!==null?`i${this._escapeHtml(String(g.iteration))}`:"",_=g&&g.phase?String(g.phase):"",H=this._phaseClass(_),J=this._logLevelClass(g&&g.level),G=g&&g.message?this._escapeHtml(String(g.message)):"";return`<li class="log-entry ${J}">
2664
+ ${u.map(g=>{let x=this._formatTimestamp(g&&g.timestamp),k=g&&g.iteration!==void 0&&g.iteration!==null?`i${this._escapeHtml(String(g.iteration))}`:"",_=g&&g.phase?String(g.phase):"",H=this._phaseClass(_),K=this._logLevelClass(g&&g.level),V=g&&g.message?this._escapeHtml(String(g.message)):"";return`<li class="log-entry ${K}">
2665
2665
  ${x?`<span class="log-time">${x}</span>`:""}
2666
2666
  ${k?`<span class="log-iter">${k}</span>`:""}
2667
2667
  ${_?`<span class="log-phase ${H}">${this._escapeHtml(_)}</span>`:""}
2668
- <span class="log-message">${G}</span>
2668
+ <span class="log-message">${V}</span>
2669
2669
  </li>`}).join("")}
2670
2670
  </ul>
2671
2671
  </div>
@@ -3710,7 +3710,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
3710
3710
  `:""}
3711
3711
 
3712
3712
  <div class="kanban-board">
3713
- ${Tt.map(a=>{let s=this._getTasksByStatus(a.status),r=this._getVisibleCount(a.status),o=s.slice(0,r),n=s.length-o.length;return`
3713
+ ${Ft.map(a=>{let s=this._getTasksByStatus(a.status),r=this._getVisibleCount(a.status),o=s.slice(0,r),n=s.length-o.length;return`
3714
3714
  <div class="kanban-column" data-status="${a.status}">
3715
3715
  <div class="kanban-column-header">
3716
3716
  <span class="kanban-column-title">
@@ -3774,7 +3774,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
3774
3774
  </div>
3775
3775
  `}).join("")}
3776
3776
  </div>
3777
- `}}_attachEventListeners(){let e=this.shadowRoot.getElementById("refresh-btn");e&&e.addEventListener("click",()=>this._loadTasks());let t=this.shadowRoot.getElementById("bulk-toggle-btn");t&&t.addEventListener("click",()=>this._toggleBulkMode()),this.shadowRoot.querySelectorAll(".filter-pill").forEach(r=>{r.addEventListener("click",()=>this._setFilter(r.dataset.filter))});let i=this.shadowRoot.getElementById("task-search");i&&i.addEventListener("input",r=>this._setSearch(r.target.value)),this.shadowRoot.querySelectorAll(".show-more-btn").forEach(r=>{r.addEventListener("click",()=>this._showMore(r.dataset.showMore))}),this.shadowRoot.querySelectorAll(".bulk-btn").forEach(r=>{r.addEventListener("click",()=>{let o=r.dataset.bulkAction;o==="delete"?this._bulkDelete():this._bulkMove(o)})}),this.shadowRoot.querySelectorAll(".add-task-btn").forEach(r=>{r.addEventListener("click",()=>{this._openAddTaskModal(r.dataset.status)})}),this.shadowRoot.querySelectorAll(".task-checkbox").forEach(r=>{r.addEventListener("click",o=>{o.stopPropagation(),this._toggleTaskSelection(r.dataset.checkId,o)})}),this.shadowRoot.querySelectorAll(".expand-toggle").forEach(r=>{r.addEventListener("click",o=>{o.stopPropagation(),this._toggleCardExpand(r.dataset.expandId)})}),this.shadowRoot.querySelectorAll(".task-card").forEach(r=>{let o=r.dataset.taskId,n=this._tasks.find(l=>l.id.toString()===o);n&&(r.addEventListener("click",l=>{if(this._bulkMode){this._toggleTaskSelection(o,l);return}this._openTaskDetail(n)}),r.addEventListener("keydown",l=>{l.key==="Enter"||l.key===" "?(l.preventDefault(),this._bulkMode?this._toggleTaskSelection(o,l):this._openTaskDetail(n)):(l.key==="ArrowDown"||l.key==="ArrowUp")&&(l.preventDefault(),this._navigateTaskCards(r,l.key==="ArrowDown"?"next":"prev"))}),r.classList.contains("draggable")&&(r.addEventListener("dragstart",l=>this._handleDragStart(l,n)),r.addEventListener("dragend",l=>this._handleDragEnd(l))))}),this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(r=>{r.addEventListener("dragover",o=>this._handleDragOver(o)),r.addEventListener("dragenter",o=>this._handleDragEnter(o)),r.addEventListener("dragleave",o=>this._handleDragLeave(o)),r.addEventListener("drop",o=>this._handleDrop(o,r.dataset.status))});let a=this.shadowRoot.getElementById("modal-close-btn");a&&a.addEventListener("click",()=>this._closeTaskDetail());let s=this.shadowRoot.getElementById("task-detail-overlay");s&&s.addEventListener("click",r=>{r.target===s&&this._closeTaskDetail()})}_escapeHtml(e){let t=document.createElement("div");return t.textContent=e,t.innerHTML}_navigateTaskCards(e,t){let i=Array.from(this.shadowRoot.querySelectorAll(".task-card")),a=i.indexOf(e);if(a===-1)return;let s=t==="next"?a+1:a-1;s>=0&&s<i.length&&i[s].focus()}};customElements.get("loki-task-board")||customElements.define("loki-task-board",Q);var X=class d extends v{static get observedAttributes(){return["api-url","theme","compact"]}constructor(){super(),this._status={mode:"offline",phase:null,iteration:null,complexity:null,connected:!1,version:null,uptime:0,activeAgents:0,pendingTasks:0},this._model={override:null,default:"sonnet",effective:"sonnet",notice:"",provider:"claude",switchable:!0,offers:[]},this._modelBusy=!1,this._startBusy=!1,this._startNotice="",this._specText="",this._startModel="",this._advisorModel="",this._api=null,this._state=U(),this._statusUpdateHandler=null,this._connectedHandler=null,this._disconnectedHandler=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._loadModel(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._teardownApiListeners()}_teardownApiListeners(){this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(f.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(f.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(f.DISCONNECTED,this._disconnectedHandler))}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._teardownApiListeners(),this._setupApi(),this._loadStatus(),this._loadModel()),e==="theme"&&this._applyTheme(),e==="compact"&&this.render())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e}),this._statusUpdateHandler=t=>this._updateFromStatus(t.detail),this._connectedHandler=()=>{this._status.connected=!0,this.render()},this._disconnectedHandler=()=>{this._status.connected=!1,this._status.mode="offline",this.render()},this._api.addEventListener(f.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(f.CONNECTED,this._connectedHandler),this._api.addEventListener(f.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){let e=this._api;try{let t=await e.getStatus();if(e!==this._api)return;this._updateFromStatus(t)}catch{if(e!==this._api)return;this._status.connected=!1,this._status.mode="offline",this.render()}}_updateFromStatus(e){e&&(this._status={...this._status,connected:!0,mode:e.status||"running",version:e.version,uptime:e.uptime_seconds||0,activeAgents:e.running_agents||0,pendingTasks:e.pending_tasks||0,phase:e.phase,iteration:e.iteration,complexity:e.complexity},this._state.updateSession({connected:!0,mode:this._status.mode,lastSync:new Date().toISOString()}),this.render())}_startPolling(){this._poll=b({loadFn:()=>this._loadStatus(),intervalMs:3e3,sectionId:null,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_formatUptime(e){if(!e||e<0)return"--";let t=Math.floor(e/3600),i=Math.floor(e%3600/60),a=Math.floor(e%60);return t>0?`${t}h ${i}m`:i>0?`${i}m ${a}s`:`${a}s`}_escapeHtml(e){let t=document.createElement("div");return t.textContent=String(e??""),t.innerHTML}_getStatusClass(){switch(this._status.mode){case"running":case"autonomous":return"active";case"paused":return"paused";case"stopped":return"stopped";case"error":return"error";default:return"offline"}}_getStatusLabel(){switch(this._status.mode){case"running":case"autonomous":return"AUTONOMOUS";case"paused":return"PAUSED";case"stopped":return"STOPPED";case"error":return"ERROR";default:return"OFFLINE"}}async _triggerStart(){if(this._startBusy)return;let e=(this._specText||"").trim();if(!e){this._startNotice="Enter a spec or one-line brief to start a build.",this.render();return}if(!this._api||typeof this._api.startSession!="function"){this._startNotice="Start is not available on this server.",this.render();return}this._startBusy=!0,this._startNotice="Starting build...",this.render();try{let t=await this._api.startSession(e,{provider:this._status.provider||"claude",model:this._startModel||"",advisorModel:this._advisorModel||""});if(t&&t.error)throw new Error(t.error);this._startBusy=!1,this._startNotice="",this._specText="",this._status.mode="running",this._status.connected=!0,this.render(),this._loadStatus(),this.dispatchEvent(new CustomEvent("session-start",{detail:{...this._status,pid:t&&t.pid,spec:t&&t.spec}}))}catch(t){console.error("Failed to start build:",t),this._startBusy=!1,this._startNotice=t&&t.message?`Could not start: ${t.message}`:"Could not start the build. Try again.",this.render()}}_onSpecInput(e){this._specText=e}async _triggerPause(){try{let e=await this._api.pauseSession();if(e&&e.error)throw new Error(e.error);this._status.mode="paused",this.render(),this.dispatchEvent(new CustomEvent("session-pause",{detail:this._status}))}catch(e){console.error("Failed to pause session:",e),this.render()}}async _triggerResume(){try{let e=await this._api.resumeSession();if(e&&e.error)throw new Error(e.error);this._status.mode="running",this.render(),this.dispatchEvent(new CustomEvent("session-resume",{detail:this._status}))}catch(e){console.error("Failed to resume session:",e),this.render()}}async _triggerStop(){try{let e=await this._api.stopSession();if(e&&e.error)throw new Error(e.error);this._status.mode="stopped",this.render(),this.dispatchEvent(new CustomEvent("session-stop",{detail:this._status}))}catch(e){console.error("Failed to stop session:",e),this.render()}}async _loadModel(){if(!this._api||typeof this._api.getSessionModel!="function")return;let e=this._api;try{let t=await e.getSessionModel();if(e!==this._api)return;t&&!t.error&&(this._model={...this._model,override:t.override??null,default:t.default||"sonnet",effective:t.effective||t.default||"sonnet",provider:t.provider||"claude",switchable:t.switchable!==!1,offers:Array.isArray(t.offers)?t.offers:[]},this.render())}catch{}}async _onModelChange(e){if(this._modelBusy)return;this._modelBusy=!0;let t=e===""?null:e;try{let i=await this._api.setSessionModel(t);if(i&&i.error)throw new Error(i.error);this._model.override=t,this._model.notice=t?`Switching to ${t}. Applies from the next iteration, for the current run only.`:"Override cleared. Reverts to the tier mapping from the next iteration.",this._modelBusy=!1,await this._loadModel()}catch(i){console.error("Failed to set session model:",i),this._model.notice="Could not change the model. Try again.",this._modelBusy=!1,this.render()}}static get MODEL_HINTS(){return{haiku:"fastest, cheapest",sonnet:"balanced",opus:"top coding",fable:"2x Opus cost: $10/$50 per MTok"}}_renderModelControl(){let e=this._model.override||"",t=this._model.offers,i=d.MODEL_HINTS,s=[{value:"",label:`Default (${this._model.default})`},...t.map(l=>{let c=i[l.value],p=c?`${l.value} (${c})`:l.value;return{value:l.value,label:l.model?`${p} -> ${l.model}`:p}})].map(l=>{let c=l.value===e?" selected":"";return`<option value="${this._escapeHtml(l.value)}"${c}>${this._escapeHtml(l.label)}</option>`}).join(""),r=this._model.effective==="fable",o=this._model.switchable===!1;return`
3777
+ `}}_attachEventListeners(){let e=this.shadowRoot.getElementById("refresh-btn");e&&e.addEventListener("click",()=>this._loadTasks());let t=this.shadowRoot.getElementById("bulk-toggle-btn");t&&t.addEventListener("click",()=>this._toggleBulkMode()),this.shadowRoot.querySelectorAll(".filter-pill").forEach(r=>{r.addEventListener("click",()=>this._setFilter(r.dataset.filter))});let i=this.shadowRoot.getElementById("task-search");i&&i.addEventListener("input",r=>this._setSearch(r.target.value)),this.shadowRoot.querySelectorAll(".show-more-btn").forEach(r=>{r.addEventListener("click",()=>this._showMore(r.dataset.showMore))}),this.shadowRoot.querySelectorAll(".bulk-btn").forEach(r=>{r.addEventListener("click",()=>{let o=r.dataset.bulkAction;o==="delete"?this._bulkDelete():this._bulkMove(o)})}),this.shadowRoot.querySelectorAll(".add-task-btn").forEach(r=>{r.addEventListener("click",()=>{this._openAddTaskModal(r.dataset.status)})}),this.shadowRoot.querySelectorAll(".task-checkbox").forEach(r=>{r.addEventListener("click",o=>{o.stopPropagation(),this._toggleTaskSelection(r.dataset.checkId,o)})}),this.shadowRoot.querySelectorAll(".expand-toggle").forEach(r=>{r.addEventListener("click",o=>{o.stopPropagation(),this._toggleCardExpand(r.dataset.expandId)})}),this.shadowRoot.querySelectorAll(".task-card").forEach(r=>{let o=r.dataset.taskId,n=this._tasks.find(l=>l.id.toString()===o);n&&(r.addEventListener("click",l=>{if(this._bulkMode){this._toggleTaskSelection(o,l);return}this._openTaskDetail(n)}),r.addEventListener("keydown",l=>{l.key==="Enter"||l.key===" "?(l.preventDefault(),this._bulkMode?this._toggleTaskSelection(o,l):this._openTaskDetail(n)):(l.key==="ArrowDown"||l.key==="ArrowUp")&&(l.preventDefault(),this._navigateTaskCards(r,l.key==="ArrowDown"?"next":"prev"))}),r.classList.contains("draggable")&&(r.addEventListener("dragstart",l=>this._handleDragStart(l,n)),r.addEventListener("dragend",l=>this._handleDragEnd(l))))}),this.shadowRoot.querySelectorAll(".kanban-tasks").forEach(r=>{r.addEventListener("dragover",o=>this._handleDragOver(o)),r.addEventListener("dragenter",o=>this._handleDragEnter(o)),r.addEventListener("dragleave",o=>this._handleDragLeave(o)),r.addEventListener("drop",o=>this._handleDrop(o,r.dataset.status))});let a=this.shadowRoot.getElementById("modal-close-btn");a&&a.addEventListener("click",()=>this._closeTaskDetail());let s=this.shadowRoot.getElementById("task-detail-overlay");s&&s.addEventListener("click",r=>{r.target===s&&this._closeTaskDetail()})}_escapeHtml(e){let t=document.createElement("div");return t.textContent=e,t.innerHTML}_navigateTaskCards(e,t){let i=Array.from(this.shadowRoot.querySelectorAll(".task-card")),a=i.indexOf(e);if(a===-1)return;let s=t==="next"?a+1:a-1;s>=0&&s<i.length&&i[s].focus()}};customElements.get("loki-task-board")||customElements.define("loki-task-board",Z);var ee=class d extends v{static get observedAttributes(){return["api-url","theme","compact"]}constructor(){super(),this._status={mode:"offline",phase:null,iteration:null,complexity:null,connected:!1,version:null,uptime:0,activeAgents:0,pendingTasks:0},this._model={override:null,default:"sonnet",effective:"sonnet",notice:"",provider:"claude",switchable:!0,offers:[]},this._modelBusy=!1,this._startBusy=!1,this._startNotice="",this._specText="",this._startModel="",this._advisorModel="",this._api=null,this._state=N(),this._statusUpdateHandler=null,this._connectedHandler=null,this._disconnectedHandler=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus(),this._loadModel(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._teardownApiListeners()}_teardownApiListeners(){this._api&&(this._statusUpdateHandler&&this._api.removeEventListener(f.STATUS_UPDATE,this._statusUpdateHandler),this._connectedHandler&&this._api.removeEventListener(f.CONNECTED,this._connectedHandler),this._disconnectedHandler&&this._api.removeEventListener(f.DISCONNECTED,this._disconnectedHandler))}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._teardownApiListeners(),this._setupApi(),this._loadStatus(),this._loadModel()),e==="theme"&&this._applyTheme(),e==="compact"&&this.render())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e}),this._statusUpdateHandler=t=>this._updateFromStatus(t.detail),this._connectedHandler=()=>{this._status.connected=!0,this.render()},this._disconnectedHandler=()=>{this._status.connected=!1,this._status.mode="offline",this.render()},this._api.addEventListener(f.STATUS_UPDATE,this._statusUpdateHandler),this._api.addEventListener(f.CONNECTED,this._connectedHandler),this._api.addEventListener(f.DISCONNECTED,this._disconnectedHandler)}async _loadStatus(){let e=this._api;try{let t=await e.getStatus();if(e!==this._api)return;this._updateFromStatus(t)}catch{if(e!==this._api)return;this._status.connected=!1,this._status.mode="offline",this.render()}}_updateFromStatus(e){e&&(this._status={...this._status,connected:!0,mode:e.status||"running",version:e.version,uptime:e.uptime_seconds||0,activeAgents:e.running_agents||0,pendingTasks:e.pending_tasks||0,phase:e.phase,iteration:e.iteration,complexity:e.complexity},this._state.updateSession({connected:!0,mode:this._status.mode,lastSync:new Date().toISOString()}),this.render())}_startPolling(){this._poll=b({loadFn:()=>this._loadStatus(),intervalMs:3e3,sectionId:null,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_formatUptime(e){if(!e||e<0)return"--";let t=Math.floor(e/3600),i=Math.floor(e%3600/60),a=Math.floor(e%60);return t>0?`${t}h ${i}m`:i>0?`${i}m ${a}s`:`${a}s`}_escapeHtml(e){let t=document.createElement("div");return t.textContent=String(e??""),t.innerHTML}_getStatusClass(){switch(this._status.mode){case"running":case"autonomous":return"active";case"paused":return"paused";case"stopped":return"stopped";case"error":return"error";default:return"offline"}}_getStatusLabel(){switch(this._status.mode){case"running":case"autonomous":return"AUTONOMOUS";case"paused":return"PAUSED";case"stopped":return"STOPPED";case"error":return"ERROR";default:return"OFFLINE"}}async _triggerStart(){if(this._startBusy)return;let e=(this._specText||"").trim();if(!e){this._startNotice="Enter a spec or one-line brief to start a build.",this.render();return}if(!this._api||typeof this._api.startSession!="function"){this._startNotice="Start is not available on this server.",this.render();return}this._startBusy=!0,this._startNotice="Starting build...",this.render();try{let t=await this._api.startSession(e,{provider:this._status.provider||"claude",model:this._startModel||"",advisorModel:this._advisorModel||""});if(t&&t.error)throw new Error(t.error);this._startBusy=!1,this._startNotice="",this._specText="",this._status.mode="running",this._status.connected=!0,this.render(),this._loadStatus(),this.dispatchEvent(new CustomEvent("session-start",{detail:{...this._status,pid:t&&t.pid,spec:t&&t.spec}}))}catch(t){console.error("Failed to start build:",t),this._startBusy=!1,this._startNotice=t&&t.message?`Could not start: ${t.message}`:"Could not start the build. Try again.",this.render()}}_onSpecInput(e){this._specText=e}async _triggerPause(){try{let e=await this._api.pauseSession();if(e&&e.error)throw new Error(e.error);this._status.mode="paused",this.render(),this.dispatchEvent(new CustomEvent("session-pause",{detail:this._status}))}catch(e){console.error("Failed to pause session:",e),this.render()}}async _triggerResume(){try{let e=await this._api.resumeSession();if(e&&e.error)throw new Error(e.error);this._status.mode="running",this.render(),this.dispatchEvent(new CustomEvent("session-resume",{detail:this._status}))}catch(e){console.error("Failed to resume session:",e),this.render()}}async _triggerStop(){try{let e=await this._api.stopSession();if(e&&e.error)throw new Error(e.error);this._status.mode="stopped",this.render(),this.dispatchEvent(new CustomEvent("session-stop",{detail:this._status}))}catch(e){console.error("Failed to stop session:",e),this.render()}}async _loadModel(){if(!this._api||typeof this._api.getSessionModel!="function")return;let e=this._api;try{let t=await e.getSessionModel();if(e!==this._api)return;t&&!t.error&&(this._model={...this._model,override:t.override??null,default:t.default||"sonnet",effective:t.effective||t.default||"sonnet",provider:t.provider||"claude",switchable:t.switchable!==!1,offers:Array.isArray(t.offers)?t.offers:[]},this.render())}catch{}}async _onModelChange(e){if(this._modelBusy)return;this._modelBusy=!0;let t=e===""?null:e;try{let i=await this._api.setSessionModel(t);if(i&&i.error)throw new Error(i.error);this._model.override=t,this._model.notice=t?`Switching to ${t}. Applies from the next iteration, for the current run only.`:"Override cleared. Reverts to the tier mapping from the next iteration.",this._modelBusy=!1,await this._loadModel()}catch(i){console.error("Failed to set session model:",i),this._model.notice="Could not change the model. Try again.",this._modelBusy=!1,this.render()}}static get MODEL_HINTS(){return{haiku:"fastest, cheapest",sonnet:"balanced",opus:"top coding",fable:"2x Opus cost: $10/$50 per MTok"}}_renderModelControl(){let e=this._model.override||"",t=this._model.offers,i=d.MODEL_HINTS,s=[{value:"",label:`Default (${this._model.default})`},...t.map(l=>{let c=i[l.value],p=c?`${l.value} (${c})`:l.value;return{value:l.value,label:l.model?`${p} -> ${l.model}`:p}})].map(l=>{let c=l.value===e?" selected":"";return`<option value="${this._escapeHtml(l.value)}"${c}>${this._escapeHtml(l.label)}</option>`}).join(""),r=this._model.effective==="fable",o=this._model.switchable===!1;return`
3778
3778
  <div class="model-control">
3779
3779
  <div class="model-row">
3780
3780
  <label for="model-select">Model</label>
@@ -4225,9 +4225,9 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
4225
4225
  `,c=this.shadowRoot.activeElement,p=c&&c.id==="spec-input",u=p?c.selectionStart:null,m=p?c.selectionEnd:null;if(this.shadowRoot.innerHTML=`
4226
4226
  ${o}
4227
4227
  ${e?n:l}
4228
- `,this._attachEventListeners(),p){let g=this.shadowRoot.getElementById("spec-input");if(g&&!g.disabled){g.focus();try{g.setSelectionRange(u,m)}catch{}}}}_attachEventListeners(){let e=this.shadowRoot.getElementById("pause-btn"),t=this.shadowRoot.getElementById("resume-btn"),i=this.shadowRoot.getElementById("stop-btn"),a=this.shadowRoot.getElementById("start-btn");e&&e.addEventListener("click",()=>this._triggerPause()),t&&t.addEventListener("click",()=>this._triggerResume()),i&&i.addEventListener("click",()=>this._triggerStop()),a&&a.addEventListener("click",()=>this._triggerStart());let s=this.shadowRoot.getElementById("model-select");if(s){let 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",X);var rt={info:{color:"var(--loki-blue)",label:"INFO"},success:{color:"var(--loki-green)",label:"SUCCESS"},warning:{color:"var(--loki-yellow)",label:"WARN"},error:{color:"var(--loki-red)",label:"ERROR"},step:{color:"var(--loki-purple)",label:"STEP"},agent:{color:"var(--loki-accent)",label:"AGENT"},debug:{color:"var(--loki-text-muted)",label:"DEBUG"}},Z=class extends v{static get observedAttributes(){return["api-url","max-lines","auto-scroll","theme","log-file"]}constructor(){super(),this._logs=[],this._maxLines=500,this._autoScroll=!0,this._filter="",this._levelFilter="all",this._api=null,this._pollInterval=null,this._logMessageHandler=null,this._apiLastCount=0,this._apiLastSig=null,this._fileLastSize=0,this._fileLastSig=null}connectedCallback(){super.connectedCallback(),this._maxLines=parseInt(this.getAttribute("max-lines"))||500,this._autoScroll=this.hasAttribute("auto-scroll"),this._setupApi(),this._startLogPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopLogPolling(),this._teardownApiListeners()}_teardownApiListeners(){this._api&&this._logMessageHandler&&this._api.removeEventListener(f.LOG_MESSAGE,this._logMessageHandler)}attributeChangedCallback(e,t,i){if(t!==i)switch(e){case"api-url":this._api&&(this._teardownApiListeners(),this._logs=[],this._apiLastCount=0,this._apiLastSig=null,this._setupApi(),this.render());break;case"max-lines":this._maxLines=parseInt(i)||500,this._trimLogs(),this.render();break;case"auto-scroll":this._autoScroll=this.hasAttribute("auto-scroll"),this.render();break;case"theme":this._applyTheme();break}}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e}),this._logMessageHandler=t=>this._addLog(t.detail),this._api.addEventListener(f.LOG_MESSAGE,this._logMessageHandler)}_startLogPolling(){let e=this.getAttribute("log-file");e?this._pollLogFile(e):this._pollApiLogs()}async _pollApiLogs(){await this._apiLogPollTick(),this._poll=b({loadFn:()=>this._apiLogPollTick(),intervalMs:5e3,element:this,immediate:!1})}async _apiLogPollTick(){try{let e=await this._api.getLogs(200);if(!Array.isArray(e))return;let t=e.length?`${e.length}:${e[e.length-1]?.timestamp||""}:${e[e.length-1]?.message||""}`:"0";if(t===this._apiLastSig)return;if(this._apiLastSig=t,e.length>this._apiLastCount){let i=e.slice(this._apiLastCount);for(let a of i)a.message&&a.message.trim()&&this._addLog({message:a.message,level:a.level||"info",timestamp:a.timestamp||new Date().toLocaleTimeString()})}else e.length<this._apiLastCount&&(this._apiLastCount=0);this._apiLastCount=e.length}catch{}}async _pollLogFile(e){await this._fileLogPollTick(e),this._poll=b({loadFn:()=>this._fileLogPollTick(e),intervalMs:1e3,element:this,immediate:!1})}async _fileLogPollTick(e){try{let t=await fetch(`${e}?t=${Date.now()}`,{credentials:"include"});if(!t.ok)return;let i=await t.text(),a=`${i.length}`;if(a===this._fileLastSig)return;this._fileLastSig=a;let s=i.split(`
4228
+ `,this._attachEventListeners(),p){let g=this.shadowRoot.getElementById("spec-input");if(g&&!g.disabled){g.focus();try{g.setSelectionRange(u,m)}catch{}}}}_attachEventListeners(){let e=this.shadowRoot.getElementById("pause-btn"),t=this.shadowRoot.getElementById("resume-btn"),i=this.shadowRoot.getElementById("stop-btn"),a=this.shadowRoot.getElementById("start-btn");e&&e.addEventListener("click",()=>this._triggerPause()),t&&t.addEventListener("click",()=>this._triggerResume()),i&&i.addEventListener("click",()=>this._triggerStop()),a&&a.addEventListener("click",()=>this._triggerStart());let s=this.shadowRoot.getElementById("model-select");if(s){let 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",ee);var ht={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"}},te=class extends v{static get observedAttributes(){return["api-url","max-lines","auto-scroll","theme","log-file"]}constructor(){super(),this._logs=[],this._maxLines=500,this._autoScroll=!0,this._filter="",this._levelFilter="all",this._api=null,this._pollInterval=null,this._logMessageHandler=null,this._apiLastCount=0,this._apiLastSig=null,this._fileLastSize=0,this._fileLastSig=null}connectedCallback(){super.connectedCallback(),this._maxLines=parseInt(this.getAttribute("max-lines"))||500,this._autoScroll=this.hasAttribute("auto-scroll"),this._setupApi(),this._startLogPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopLogPolling(),this._teardownApiListeners()}_teardownApiListeners(){this._api&&this._logMessageHandler&&this._api.removeEventListener(f.LOG_MESSAGE,this._logMessageHandler)}attributeChangedCallback(e,t,i){if(t!==i)switch(e){case"api-url":this._api&&(this._teardownApiListeners(),this._logs=[],this._apiLastCount=0,this._apiLastSig=null,this._setupApi(),this.render());break;case"max-lines":this._maxLines=parseInt(i)||500,this._trimLogs(),this.render();break;case"auto-scroll":this._autoScroll=this.hasAttribute("auto-scroll"),this.render();break;case"theme":this._applyTheme();break}}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e}),this._logMessageHandler=t=>this._addLog(t.detail),this._api.addEventListener(f.LOG_MESSAGE,this._logMessageHandler)}_startLogPolling(){let e=this.getAttribute("log-file");e?this._pollLogFile(e):this._pollApiLogs()}async _pollApiLogs(){await this._apiLogPollTick(),this._poll=b({loadFn:()=>this._apiLogPollTick(),intervalMs:5e3,element:this,immediate:!1})}async _apiLogPollTick(){try{let e=await this._api.getLogs(200);if(!Array.isArray(e))return;let t=e.length?`${e.length}:${e[e.length-1]?.timestamp||""}:${e[e.length-1]?.message||""}`:"0";if(t===this._apiLastSig)return;if(this._apiLastSig=t,e.length>this._apiLastCount){let i=e.slice(this._apiLastCount);for(let a of i)a.message&&a.message.trim()&&this._addLog({message:a.message,level:a.level||"info",timestamp:a.timestamp||new Date().toLocaleTimeString()})}else e.length<this._apiLastCount&&(this._apiLastCount=0);this._apiLastCount=e.length}catch{}}async _pollLogFile(e){await this._fileLogPollTick(e),this._poll=b({loadFn:()=>this._fileLogPollTick(e),intervalMs:1e3,element:this,immediate:!1})}async _fileLogPollTick(e){try{let t=await fetch(`${e}?t=${Date.now()}`,{credentials:"include"});if(!t.ok)return;let i=await t.text(),a=`${i.length}`;if(a===this._fileLastSig)return;this._fileLastSig=a;let s=i.split(`
4229
4229
  `);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(`
4230
- `),t=new Blob([e],{type:"text/plain"}),i=URL.createObjectURL(t),a=document.createElement("a");a.href=i,a.download=`loki-logs-${new Date().toISOString().split("T")[0]}.txt`,a.click(),URL.revokeObjectURL(i)}_setFilter(e){this._filter=e.toLowerCase(),this._renderLogs()}_setLevelFilter(e){this._levelFilter=e,this._renderLogs()}_getFilteredLogs(){return this._logs.filter(e=>!(this._levelFilter!=="all"&&e.level!==this._levelFilter||this._filter&&!e.message.toLowerCase().includes(this._filter)))}_renderLogs(){let e=this.shadowRoot.getElementById("log-output");if(!e)return;let t=this._getFilteredLogs();if(t.length===0){e.innerHTML='<div class="log-empty">No log output yet. Terminal will update when Loki Mode is running.</div>';return}e.innerHTML=t.map(i=>{let a=rt[i.level]||rt.info;return`
4230
+ `),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=ht[i.level]||ht.info;return`
4231
4231
  <div class="log-line">
4232
4232
  <span class="timestamp">${this._escapeHtml(i.timestamp)}</span>
4233
4233
  <span class="level" style="color: ${a.color}">[${this._escapeHtml(a.label)}]</span>
@@ -4426,7 +4426,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
4426
4426
  ${this._logs.length} lines (${this._getFilteredLogs().length} shown)
4427
4427
  </div>
4428
4428
  </div>
4429
- `,this._attachEventListeners(),this._renderLogs()}_attachEventListeners(){let e=this.shadowRoot.getElementById("filter-input"),t=this.shadowRoot.getElementById("level-select"),i=this.shadowRoot.getElementById("auto-scroll-btn"),a=this.shadowRoot.getElementById("clear-btn"),s=this.shadowRoot.getElementById("download-btn");e&&(e.value=this._filter,e.addEventListener("input",r=>this._setFilter(r.target.value))),t&&(t.value=this._levelFilter,t.addEventListener("change",r=>this._setLevelFilter(r.target.value))),i&&i.addEventListener("click",()=>this._toggleAutoScroll()),a&&a.addEventListener("click",()=>this._clearLogs()),s&&s.addEventListener("click",()=>this._downloadLogs())}addLog(e,t="info"){this._addLog({message:e,level:t,timestamp:new Date().toLocaleTimeString()})}clear(){this._clearLogs()}};customElements.get("loki-log-stream")||customElements.define("loki-log-stream",Z);var Lt=[{id:"summary",label:"Summary",icon:"M4 6h16M4 12h16M4 18h16"},{id:"search",label:"Search",icon:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"},{id:"episodes",label:"Episodes",icon:"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"},{id:"patterns",label:"Patterns",icon:"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"},{id:"skills",label:"Skills",icon:"M13 10V3L4 14h7v7l9-11h-7z"}],ee=class extends v{static get observedAttributes(){return["api-url","theme","tab"]}constructor(){super(),this._activeTab="summary",this._loading=!1,this._error=null,this._api=null,this._summary=null,this._stats=null,this._episodes=[],this._patterns=[],this._skills=[],this._tokenEconomics=null,this._selectedItem=null,this._lastFocusedElement=null,this._searchQuery="",this._searchCollection="all",this._searchResults=[],this._searchLoading=!1,this._searchError=null}connectedCallback(){super.connectedCallback(),this._activeTab=this.getAttribute("tab")||"summary",this._setupApi(),this._loadData()}attributeChangedCallback(e,t,i){if(t!==i)switch(e){case"api-url":this._api&&(this._api=h({baseUrl:i}),this._loadData());break;case"theme":this._applyTheme();break;case"tab":this._setTab(i);break}}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){let e=this._api;this._loading=!0,this._error=null,this.render();try{let[t,i,a]=await Promise.allSettled([e.getMemorySummary(),e.getTokenEconomics(),e.getMemoryStats()]);if(e!==this._api||(this._summary=t.status==="fulfilled"?t.value:null,this._tokenEconomics=i.status==="fulfilled"?i.value:null,this._stats=a.status==="fulfilled"?a.value:null,await this._loadTabData(),e!==this._api))return}catch(t){if(e!==this._api)return;this._error=t.message||"Failed to load memory data"}this._loading=!1,this.render()}async _loadTabData(){let e=this._api;switch(this._activeTab){case"episodes":{let t=await e.listEpisodes({limit:50}).catch(()=>[]);if(e!==this._api)return;this._episodes=t;break}case"patterns":{let t=await e.listPatterns().catch(()=>[]);if(e!==this._api)return;this._patterns=t;break}case"skills":{let t=await e.listSkills().catch(()=>[]);if(e!==this._api)return;this._skills=t;break}}}_setTab(e){this._activeTab!==e&&(this._activeTab=e,this._selectedItem=null,this._loadTabData().then(()=>this.render()))}async _selectEpisode(e){let t=this._api;try{this._lastFocusedElement=this.shadowRoot.activeElement;let i=await t.getEpisode(e);if(t!==this._api)return;this._selectedItem=i,this.dispatchEvent(new CustomEvent("episode-select",{detail:this._selectedItem})),this.render(),this._focusDetailPanel()}catch(i){console.error("Failed to load episode:",i)}}async _selectPattern(e){let t=this._api;try{this._lastFocusedElement=this.shadowRoot.activeElement;let i=await t.getPattern(e);if(t!==this._api)return;this._selectedItem=i,this.dispatchEvent(new CustomEvent("pattern-select",{detail:this._selectedItem})),this.render(),this._focusDetailPanel()}catch(i){console.error("Failed to load pattern:",i)}}async _selectSkill(e){let t=this._api;try{this._lastFocusedElement=this.shadowRoot.activeElement;let i=await t.getSkill(e);if(t!==this._api)return;this._selectedItem=i,this.dispatchEvent(new CustomEvent("skill-select",{detail:this._selectedItem})),this.render(),this._focusDetailPanel()}catch(i){console.error("Failed to load skill:",i)}}_focusDetailPanel(){requestAnimationFrame(()=>{let e=this.shadowRoot.getElementById("close-detail");e&&e.focus()})}_closeDetail(){this._selectedItem=null,this.render(),this._lastFocusedElement&&requestAnimationFrame(()=>{this._lastFocusedElement.focus(),this._lastFocusedElement=null})}async _triggerConsolidation(){try{let e=await this._api.consolidateMemory(24);alert(`Consolidation complete:
4429
+ `,this._attachEventListeners(),this._renderLogs()}_attachEventListeners(){let e=this.shadowRoot.getElementById("filter-input"),t=this.shadowRoot.getElementById("level-select"),i=this.shadowRoot.getElementById("auto-scroll-btn"),a=this.shadowRoot.getElementById("clear-btn"),s=this.shadowRoot.getElementById("download-btn");e&&(e.value=this._filter,e.addEventListener("input",r=>this._setFilter(r.target.value))),t&&(t.value=this._levelFilter,t.addEventListener("change",r=>this._setLevelFilter(r.target.value))),i&&i.addEventListener("click",()=>this._toggleAutoScroll()),a&&a.addEventListener("click",()=>this._clearLogs()),s&&s.addEventListener("click",()=>this._downloadLogs())}addLog(e,t="info"){this._addLog({message:e,level:t,timestamp:new Date().toLocaleTimeString()})}clear(){this._clearLogs()}};customElements.get("loki-log-stream")||customElements.define("loki-log-stream",te);var jt=[{id:"summary",label:"Summary",icon:"M4 6h16M4 12h16M4 18h16"},{id:"search",label:"Search",icon:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"},{id:"episodes",label:"Episodes",icon:"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"},{id:"patterns",label:"Patterns",icon:"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"},{id:"skills",label:"Skills",icon:"M13 10V3L4 14h7v7l9-11h-7z"}],ie=class extends v{static get observedAttributes(){return["api-url","theme","tab"]}constructor(){super(),this._activeTab="summary",this._loading=!1,this._error=null,this._api=null,this._summary=null,this._stats=null,this._episodes=[],this._patterns=[],this._skills=[],this._tokenEconomics=null,this._selectedItem=null,this._lastFocusedElement=null,this._searchQuery="",this._searchCollection="all",this._searchResults=[],this._searchLoading=!1,this._searchError=null}connectedCallback(){super.connectedCallback(),this._activeTab=this.getAttribute("tab")||"summary",this._setupApi(),this._loadData()}attributeChangedCallback(e,t,i){if(t!==i)switch(e){case"api-url":this._api&&(this._api=h({baseUrl:i}),this._loadData());break;case"theme":this._applyTheme();break;case"tab":this._setTab(i);break}}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){let e=this._api;this._loading=!0,this._error=null,this.render();try{let[t,i,a]=await Promise.allSettled([e.getMemorySummary(),e.getTokenEconomics(),e.getMemoryStats()]);if(e!==this._api||(this._summary=t.status==="fulfilled"?t.value:null,this._tokenEconomics=i.status==="fulfilled"?i.value:null,this._stats=a.status==="fulfilled"?a.value:null,await this._loadTabData(),e!==this._api))return}catch(t){if(e!==this._api)return;this._error=t.message||"Failed to load memory data"}this._loading=!1,this.render()}async _loadTabData(){let e=this._api;switch(this._activeTab){case"episodes":{let t=await e.listEpisodes({limit:50}).catch(()=>[]);if(e!==this._api)return;this._episodes=t;break}case"patterns":{let t=await e.listPatterns().catch(()=>[]);if(e!==this._api)return;this._patterns=t;break}case"skills":{let t=await e.listSkills().catch(()=>[]);if(e!==this._api)return;this._skills=t;break}}}_setTab(e){this._activeTab!==e&&(this._activeTab=e,this._selectedItem=null,this._loadTabData().then(()=>this.render()))}async _selectEpisode(e){let t=this._api;try{this._lastFocusedElement=this.shadowRoot.activeElement;let i=await t.getEpisode(e);if(t!==this._api)return;this._selectedItem=i,this.dispatchEvent(new CustomEvent("episode-select",{detail:this._selectedItem})),this.render(),this._focusDetailPanel()}catch(i){console.error("Failed to load episode:",i)}}async _selectPattern(e){let t=this._api;try{this._lastFocusedElement=this.shadowRoot.activeElement;let i=await t.getPattern(e);if(t!==this._api)return;this._selectedItem=i,this.dispatchEvent(new CustomEvent("pattern-select",{detail:this._selectedItem})),this.render(),this._focusDetailPanel()}catch(i){console.error("Failed to load pattern:",i)}}async _selectSkill(e){let t=this._api;try{this._lastFocusedElement=this.shadowRoot.activeElement;let i=await t.getSkill(e);if(t!==this._api)return;this._selectedItem=i,this.dispatchEvent(new CustomEvent("skill-select",{detail:this._selectedItem})),this.render(),this._focusDetailPanel()}catch(i){console.error("Failed to load skill:",i)}}_focusDetailPanel(){requestAnimationFrame(()=>{let e=this.shadowRoot.getElementById("close-detail");e&&e.focus()})}_closeDetail(){this._selectedItem=null,this.render(),this._lastFocusedElement&&requestAnimationFrame(()=>{this._lastFocusedElement.focus(),this._lastFocusedElement=null})}async _triggerConsolidation(){try{let e=await this._api.consolidateMemory(24);alert(`Consolidation complete:
4430
4430
  - Patterns created: ${e.patternsCreated}
4431
4431
  - Patterns merged: ${e.patternsMerged}
4432
4432
  - Episodes processed: ${e.episodesProcessed}`),this._loadData()}catch(e){alert("Consolidation failed: "+e.message)}}async _executeSearch(){let e=this._searchQuery.trim();if(!e)return;let t=this._api;this._searchLoading=!0,this._searchError=null,this.render();try{let i=await t.searchMemory(e,this._searchCollection,20);if(t!==this._api)return;this._searchResults=i.results||[]}catch(i){if(t!==this._api)return;this._searchError=i.message||"Search failed",this._searchResults=[]}this._searchLoading=!1,this.render(),requestAnimationFrame(()=>{let i=this.shadowRoot.getElementById("memory-search-input");i&&i.focus()})}_renderSearch(){let e=["all","episodes","patterns","skills"];return`
@@ -5297,7 +5297,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
5297
5297
  <span class="browser-title">Memory System</span>
5298
5298
  </div>
5299
5299
  <div class="tabs" role="tablist" aria-label="Memory browser sections">
5300
- ${Lt.map((i,a)=>`
5300
+ ${jt.map((i,a)=>`
5301
5301
  <button class="tab ${this._activeTab===i.id?"active":""}"
5302
5302
  data-tab="${i.id}"
5303
5303
  role="tab"
@@ -5314,12 +5314,12 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
5314
5314
  ${t}
5315
5315
  </div>
5316
5316
  </div>
5317
- `,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot.querySelectorAll(".tab");e.forEach((n,l)=>{n.addEventListener("click",()=>this._setTab(n.dataset.tab)),n.addEventListener("keydown",c=>{if(c.key==="ArrowRight"||c.key==="ArrowLeft"){c.preventDefault();let p=Array.from(e),u=c.key==="ArrowRight"?(l+1)%p.length:(l-1+p.length)%p.length;p[u].focus(),this._setTab(p[u].dataset.tab)}})}),this.shadowRoot.querySelectorAll(".item-card").forEach(n=>{n.addEventListener("click",()=>this._handleItemClick(n)),n.addEventListener("keydown",l=>{l.key==="Enter"||l.key===" "?(l.preventDefault(),this._handleItemClick(n)):(l.key==="ArrowDown"||l.key==="ArrowUp")&&(l.preventDefault(),this._navigateItemCards(n,l.key==="ArrowDown"?"next":"prev"))})});let t=this.shadowRoot.getElementById("close-detail");t&&t.addEventListener("click",()=>this._closeDetail());let i=this.shadowRoot.getElementById("consolidate-btn");i&&i.addEventListener("click",()=>this._triggerConsolidation());let a=this.shadowRoot.getElementById("refresh-btn");a&&a.addEventListener("click",()=>this._loadData());let s=this.shadowRoot.getElementById("memory-search-input"),r=this.shadowRoot.getElementById("search-btn"),o=this.shadowRoot.getElementById("memory-search-collection");s&&(s.addEventListener("keydown",n=>{n.key==="Enter"&&(n.preventDefault(),this._searchQuery=s.value,this._executeSearch())}),s.addEventListener("input",n=>{this._searchQuery=n.target.value})),r&&r.addEventListener("click",()=>{let n=this.shadowRoot.getElementById("memory-search-input");n&&(this._searchQuery=n.value),this._executeSearch()}),o&&o.addEventListener("change",n=>{this._searchCollection=n.target.value})}_handleItemClick(e){let t=e.dataset.id;switch(e.dataset.type){case"episode":this._selectEpisode(t);break;case"pattern":this._selectPattern(t);break;case"skill":this._selectSkill(t);break}}_navigateItemCards(e,t){let i=Array.from(this.shadowRoot.querySelectorAll(".item-card")),a=i.indexOf(e);if(a===-1)return;let s=t==="next"?a+1:a-1;s>=0&&s<i.length&&i[s].focus()}};customElements.get("loki-memory-browser")||customElements.define("loki-memory-browser",ee);var zt=[{id:"1h",label:"1 Hour",hours:1},{id:"24h",label:"24 Hours",hours:24},{id:"7d",label:"7 Days",hours:168},{id:"30d",label:"30 Days",hours:720}],Dt=[{id:"all",label:"All Signals"},{id:"user_preference",label:"User Preferences"},{id:"error_pattern",label:"Error Patterns"},{id:"success_pattern",label:"Success Patterns"},{id:"tool_efficiency",label:"Tool Efficiency"},{id:"context_relevance",label:"Context Relevance"}],Ht=[{id:"all",label:"All Sources"},{id:"cli",label:"CLI"},{id:"api",label:"API"},{id:"vscode",label:"VS Code"},{id:"mcp",label:"MCP"},{id:"dashboard",label:"Dashboard"}],te=class extends v{static get observedAttributes(){return["api-url","theme","time-range","signal-type","source"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._timeRange="7d",this._signalType="all",this._source="all",this._metrics=null,this._trends=null,this._signals=[],this._selectedMetric=null}connectedCallback(){super.connectedCallback(),this._timeRange=this.getAttribute("time-range")||"7d",this._signalType=this.getAttribute("signal-type")||"all",this._source=this.getAttribute("source")||"all",this._setupApi(),this._loadData()}attributeChangedCallback(e,t,i){if(t!==i)switch(e){case"api-url":this._api&&(this._api=h({baseUrl:i}),this._loadData());break;case"theme":this._applyTheme();break;case"time-range":this._timeRange=i,this._loadData();break;case"signal-type":this._signalType=i,this._loadData();break;case"source":this._source=i,this._loadData();break}}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){this._loading=!0,this._error=null,this.render();let e=this._api;try{let t={timeRange:this._timeRange,signalType:this._signalType!=="all"?this._signalType:void 0,source:this._source!=="all"?this._source:void 0},[i,a,s]=await Promise.all([e.getLearningMetrics(t).catch(()=>null),e.getLearningTrends(t).catch(()=>null),e.getLearningSignals({...t,limit:50}).catch(()=>[])]);if(e!==this._api)return;this._metrics=i,this._trends=a,this._signals=s||[]}catch(t){if(e!==this._api)return;this._error=t.message||"Failed to load learning data"}this._loading=!1,this.render()}_setFilter(e,t){switch(e){case"timeRange":this._timeRange=t,this.setAttribute("time-range",t);break;case"signalType":this._signalType=t,this.setAttribute("signal-type",t);break;case"source":this._source=t,this.setAttribute("source",t);break}this.dispatchEvent(new CustomEvent("filter-change",{detail:{timeRange:this._timeRange,signalType:this._signalType,source:this._source}})),this._loadData()}_selectMetric(e,t){this._selectedMetric={type:e,item:t},this.dispatchEvent(new CustomEvent("metric-select",{detail:{type:e,item:t}})),this.render()}_closeDetail(){this._selectedMetric=null,this.render()}_formatNumber(e){return e>=1e6?(e/1e6).toFixed(1)+"M":e>=1e3?(e/1e3).toFixed(1)+"K":e?.toString()||"0"}_formatPercent(e){return(e*100).toFixed(1)+"%"}_formatDuration(e){return e<60?e.toFixed(0)+"s":e<3600?(e/60).toFixed(1)+"m":(e/3600).toFixed(1)+"h"}_escapeHtml(e){return e==null?"":String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}_renderFilters(){return`
5317
+ `,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",ie);var Ut=[{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}],Nt=[{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"}],Ot=[{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"}],ae=class extends v{static get observedAttributes(){return["api-url","theme","time-range","signal-type","source"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._timeRange="7d",this._signalType="all",this._source="all",this._metrics=null,this._trends=null,this._signals=[],this._selectedMetric=null}connectedCallback(){super.connectedCallback(),this._timeRange=this.getAttribute("time-range")||"7d",this._signalType=this.getAttribute("signal-type")||"all",this._source=this.getAttribute("source")||"all",this._setupApi(),this._loadData()}attributeChangedCallback(e,t,i){if(t!==i)switch(e){case"api-url":this._api&&(this._api=h({baseUrl:i}),this._loadData());break;case"theme":this._applyTheme();break;case"time-range":this._timeRange=i,this._loadData();break;case"signal-type":this._signalType=i,this._loadData();break;case"source":this._source=i,this._loadData();break}}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){this._loading=!0,this._error=null,this.render();let e=this._api;try{let t={timeRange:this._timeRange,signalType:this._signalType!=="all"?this._signalType:void 0,source:this._source!=="all"?this._source:void 0},[i,a,s]=await Promise.all([e.getLearningMetrics(t).catch(()=>null),e.getLearningTrends(t).catch(()=>null),e.getLearningSignals({...t,limit:50}).catch(()=>[])]);if(e!==this._api)return;this._metrics=i,this._trends=a,this._signals=s||[]}catch(t){if(e!==this._api)return;this._error=t.message||"Failed to load learning data"}this._loading=!1,this.render()}_setFilter(e,t){switch(e){case"timeRange":this._timeRange=t,this.setAttribute("time-range",t);break;case"signalType":this._signalType=t,this.setAttribute("signal-type",t);break;case"source":this._source=t,this.setAttribute("source",t);break}this.dispatchEvent(new CustomEvent("filter-change",{detail:{timeRange:this._timeRange,signalType:this._signalType,source:this._source}})),this._loadData()}_selectMetric(e,t){this._selectedMetric={type:e,item:t},this.dispatchEvent(new CustomEvent("metric-select",{detail:{type:e,item:t}})),this.render()}_closeDetail(){this._selectedMetric=null,this.render()}_formatNumber(e){return e>=1e6?(e/1e6).toFixed(1)+"M":e>=1e3?(e/1e3).toFixed(1)+"K":e?.toString()||"0"}_formatPercent(e){return(e*100).toFixed(1)+"%"}_formatDuration(e){return e<60?e.toFixed(0)+"s":e<3600?(e/60).toFixed(1)+"m":(e/3600).toFixed(1)+"h"}_escapeHtml(e){return e==null?"":String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}_renderFilters(){return`
5318
5318
  <div class="filters">
5319
5319
  <div class="filter-group">
5320
5320
  <label>Time Range</label>
5321
5321
  <select id="time-range-select" class="filter-select">
5322
- ${zt.map(e=>`
5322
+ ${Ut.map(e=>`
5323
5323
  <option value="${e.id}" ${this._timeRange===e.id?"selected":""}>${e.label}</option>
5324
5324
  `).join("")}
5325
5325
  </select>
@@ -5327,7 +5327,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
5327
5327
  <div class="filter-group">
5328
5328
  <label>Signal Type</label>
5329
5329
  <select id="signal-type-select" class="filter-select">
5330
- ${Dt.map(e=>`
5330
+ ${Nt.map(e=>`
5331
5331
  <option value="${e.id}" ${this._signalType===e.id?"selected":""}>${e.label}</option>
5332
5332
  `).join("")}
5333
5333
  </select>
@@ -5335,7 +5335,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
5335
5335
  <div class="filter-group">
5336
5336
  <label>Source</label>
5337
5337
  <select id="source-select" class="filter-select">
5338
- ${Ht.map(e=>`
5338
+ ${Ot.map(e=>`
5339
5339
  <option value="${e.id}" ${this._source===e.id?"selected":""}>${e.label}</option>
5340
5340
  `).join("")}
5341
5341
  </select>
@@ -6326,7 +6326,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
6326
6326
  ${t}
6327
6327
  </div>
6328
6328
  </div>
6329
- `,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot.getElementById("time-range-select");e&&e.addEventListener("change",r=>this._setFilter("timeRange",r.target.value));let t=this.shadowRoot.getElementById("signal-type-select");t&&t.addEventListener("change",r=>this._setFilter("signalType",r.target.value));let i=this.shadowRoot.getElementById("source-select");i&&i.addEventListener("change",r=>this._setFilter("source",r.target.value));let a=this.shadowRoot.getElementById("refresh-btn");a&&a.addEventListener("click",()=>this._loadData());let s=this.shadowRoot.getElementById("close-detail");s&&s.addEventListener("click",()=>this._closeDetail()),this.shadowRoot.querySelectorAll(".list-item").forEach(r=>{r.addEventListener("click",()=>{let o=r.dataset.type,n=r.dataset.id,l=this._findItemData(o,n);l&&this._selectMetric(o,l)}),r.addEventListener("keydown",o=>{(o.key==="Enter"||o.key===" ")&&(o.preventDefault(),r.click())})})}_findItemData(e,t){if(!this._metrics?.aggregation)return null;switch(e){case"preference":return this._metrics.aggregation.preferences?.find(i=>i.preference_key===t);case"error_pattern":return this._metrics.aggregation.error_patterns?.find(i=>i.error_type===t);case"success_pattern":return this._metrics.aggregation.success_patterns?.find(i=>i.pattern_name===t);case"tool_efficiency":return this._metrics.aggregation.tool_efficiencies?.find(i=>i.tool_name===t);default:return null}}};customElements.get("loki-learning-dashboard")||customElements.define("loki-learning-dashboard",te);var Mt=[{id:"overview",label:"Overview"},{id:"decisions",label:"Decision Log"},{id:"convergence",label:"Convergence"},{id:"agents",label:"Agents"}],ie=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._activeTab="overview",this._pollInterval=null,this._councilState=null,this._verdicts=[],this._convergence=[],this._agents=[],this._selectedAgent=null,this._lastDataHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null),this._pendingRaf&&(cancelAnimationFrame(this._pendingRaf),this._pendingRaf=null)}async _loadData(){let e=this._api;try{let[i,a,s,r]=await Promise.allSettled([e._get("/api/council/state"),e._get("/api/council/verdicts"),e._get("/api/council/convergence"),e._get("/api/agents")]);if(e!==this._api)return;i.status==="fulfilled"&&(this._councilState=i.value),a.status==="fulfilled"&&(this._verdicts=a.value.verdicts||[]),s.status==="fulfilled"&&(this._convergence=s.value.dataPoints||[]),r.status==="fulfilled"&&(this._agents=Array.isArray(r.value)?r.value:[]),this._error=null}catch(i){if(e!==this._api)return;this._error=i.message}let t=JSON.stringify({s:this._councilState,v:this._verdicts,c:this._convergence,a:this._agents,e:this._error});t!==this._lastDataHash&&(this._lastDataHash=t,this.render())}async _forceReview(){try{await this._api._post("/api/council/force-review"),this.dispatchEvent(new CustomEvent("council-action",{detail:{action:"force-review"},bubbles:!0}))}catch(e){this._error=`Failed to force review: ${e.message}`,this.render()}}async _killAgent(e){if(confirm(`Kill agent ${e}?`))try{await this._api._post(`/api/agents/${e}/kill`),this.dispatchEvent(new CustomEvent("council-action",{detail:{action:"kill-agent",agentId:e},bubbles:!0})),await this._loadData()}catch(t){this._error=`Failed to kill agent: ${t.message}`,this.render()}}async _pauseAgent(e){try{await this._api._post(`/api/agents/${e}/pause`),await this._loadData()}catch(t){this._error=`Failed to pause agent: ${t.message}`,this.render()}}async _resumeAgent(e){try{await this._api._post(`/api/agents/${e}/resume`),await this._loadData()}catch(t){this._error=`Failed to resume agent: ${t.message}`,this.render()}}_setTab(e){this._activeTab=e,this.render()}_selectAgent(e){this._selectedAgent=this._selectedAgent?.id===e.id?null:e,this.render()}render(){let e=this.shadowRoot;e&&(this._pendingRaf&&(cancelAnimationFrame(this._pendingRaf),this._pendingRaf=null),e.innerHTML=`
6329
+ `,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",ae);var qt=[{id:"overview",label:"Overview"},{id:"decisions",label:"Decision Log"},{id:"convergence",label:"Convergence"},{id:"agents",label:"Agents"}],se=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._activeTab="overview",this._pollInterval=null,this._councilState=null,this._verdicts=[],this._convergence=[],this._agents=[],this._selectedAgent=null,this._lastDataHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null),this._pendingRaf&&(cancelAnimationFrame(this._pendingRaf),this._pendingRaf=null)}async _loadData(){let e=this._api;try{let[i,a,s,r]=await Promise.allSettled([e._get("/api/council/state"),e._get("/api/council/verdicts"),e._get("/api/council/convergence"),e._get("/api/agents")]);if(e!==this._api)return;i.status==="fulfilled"&&(this._councilState=i.value),a.status==="fulfilled"&&(this._verdicts=a.value.verdicts||[]),s.status==="fulfilled"&&(this._convergence=s.value.dataPoints||[]),r.status==="fulfilled"&&(this._agents=Array.isArray(r.value)?r.value:[]),this._error=null}catch(i){if(e!==this._api)return;this._error=i.message}let t=JSON.stringify({s:this._councilState,v:this._verdicts,c:this._convergence,a:this._agents,e:this._error});t!==this._lastDataHash&&(this._lastDataHash=t,this.render())}async _forceReview(){try{await this._api._post("/api/council/force-review"),this.dispatchEvent(new CustomEvent("council-action",{detail:{action:"force-review"},bubbles:!0}))}catch(e){this._error=`Failed to force review: ${e.message}`,this.render()}}async _killAgent(e){if(confirm(`Kill agent ${e}?`))try{await this._api._post(`/api/agents/${e}/kill`),this.dispatchEvent(new CustomEvent("council-action",{detail:{action:"kill-agent",agentId:e},bubbles:!0})),await this._loadData()}catch(t){this._error=`Failed to kill agent: ${t.message}`,this.render()}}async _pauseAgent(e){try{await this._api._post(`/api/agents/${e}/pause`),await this._loadData()}catch(t){this._error=`Failed to pause agent: ${t.message}`,this.render()}}async _resumeAgent(e){try{await this._api._post(`/api/agents/${e}/resume`),await this._loadData()}catch(t){this._error=`Failed to resume agent: ${t.message}`,this.render()}}_setTab(e){this._activeTab=e,this.render()}_selectAgent(e){this._selectedAgent=this._selectedAgent?.id===e.id?null:e,this.render()}render(){let e=this.shadowRoot;e&&(this._pendingRaf&&(cancelAnimationFrame(this._pendingRaf),this._pendingRaf=null),e.innerHTML=`
6330
6330
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
6331
6331
  <div class="council-dashboard">
6332
6332
  <div class="council-header">
@@ -6340,7 +6340,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
6340
6340
  </div>
6341
6341
 
6342
6342
  <div class="tabs">
6343
- ${Mt.map(t=>`
6343
+ ${qt.map(t=>`
6344
6344
  <button
6345
6345
  class="tab ${this._activeTab===t.id?"active":""}"
6346
6346
  data-tab="${t.id}"
@@ -6913,7 +6913,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
6913
6913
  color: var(--loki-error);
6914
6914
  font-size: 12px;
6915
6915
  }
6916
- `}};customElements.get("loki-council-dashboard")||customElements.define("loki-council-dashboard",ie);var ot={critical:0,major:1,minor:2},Rt={critical:"var(--loki-status-error, #ef4444)",major:"var(--loki-status-warning, #f59e0b)",minor:"var(--loki-text-muted, #71717a)"},ae=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._pollInterval=null,this._checklist=null,this._waivers=[],this._expandedCategories=new Set,this._lastDataHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let[t,i]=await Promise.all([e.getChecklist(),e.getChecklistWaivers().catch(()=>null)]);if(e!==this._api)return;let a=JSON.stringify(i),s=JSON.stringify(t)+a;if(s===this._lastDataHash)return;this._lastDataHash=s,this._checklist=t,this._waivers=i&&i.waivers?i.waivers.filter(r=>r.active):[],this._error=null,this.render()}catch(t){if(e!==this._api)return;this._error=`Failed to load checklist: ${t.message}`,this.render()}}_isItemWaived(e){return this._waivers.some(t=>t.item_id===e)}_getWaiverForItem(e){return this._waivers.find(t=>t.item_id===e)||null}async _waiveItem(e){let t=window.prompt("Enter reason for waiving this item:");if(!t)return;let i=this._api;try{if(await i.addChecklistWaiver(e,t),i!==this._api)return;this._lastDataHash=null,await this._loadData()}catch(a){if(i!==this._api)return;this._error=`Failed to add waiver: ${a.message}`,this.render()}}async _unwaiveItem(e){let t=this._api;try{if(await t.removeChecklistWaiver(e),t!==this._api)return;this._lastDataHash=null,await this._loadData()}catch(i){if(t!==this._api)return;this._error=`Failed to remove waiver: ${i.message}`,this.render()}}_toggleCategory(e){this._expandedCategories.has(e)?this._expandedCategories.delete(e):this._expandedCategories.add(e),this.render()}_getStyles(){return`
6916
+ `}};customElements.get("loki-council-dashboard")||customElements.define("loki-council-dashboard",se);var ut={critical:0,major:1,minor:2},Jt={critical:"var(--loki-status-error, #ef4444)",major:"var(--loki-status-warning, #f59e0b)",minor:"var(--loki-text-muted, #71717a)"},re=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._pollInterval=null,this._checklist=null,this._waivers=[],this._expandedCategories=new Set,this._lastDataHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let[t,i]=await Promise.all([e.getChecklist(),e.getChecklistWaivers().catch(()=>null)]);if(e!==this._api)return;let a=JSON.stringify(i),s=JSON.stringify(t)+a;if(s===this._lastDataHash)return;this._lastDataHash=s,this._checklist=t,this._waivers=i&&i.waivers?i.waivers.filter(r=>r.active):[],this._error=null,this.render()}catch(t){if(e!==this._api)return;this._error=`Failed to load checklist: ${t.message}`,this.render()}}_isItemWaived(e){return this._waivers.some(t=>t.item_id===e)}_getWaiverForItem(e){return this._waivers.find(t=>t.item_id===e)||null}async _waiveItem(e){let t=window.prompt("Enter reason for waiving this item:");if(!t)return;let i=this._api;try{if(await i.addChecklistWaiver(e,t),i!==this._api)return;this._lastDataHash=null,await this._loadData()}catch(a){if(i!==this._api)return;this._error=`Failed to add waiver: ${a.message}`,this.render()}}async _unwaiveItem(e){let t=this._api;try{if(await t.removeChecklistWaiver(e),t!==this._api)return;this._lastDataHash=null,await this._loadData()}catch(i){if(t!==this._api)return;this._error=`Failed to remove waiver: ${i.message}`,this.render()}}_toggleCategory(e){this._expandedCategories.has(e)?this._expandedCategories.delete(e):this._expandedCategories.add(e),this.render()}_getStyles(){return`
6917
6917
  .checklist-viewer {
6918
6918
  padding: 16px;
6919
6919
  font-family: var(--loki-font-family, system-ui, -apple-system, sans-serif);
@@ -7202,7 +7202,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
7202
7202
  </div>
7203
7203
  ${i?`<div class="category-body">${this._renderItems(a)}</div>`:""}
7204
7204
  </div>
7205
- `}).join(""):this._renderEmpty()}_renderItems(e){return e?.length?[...e].sort((i,a)=>(ot[i.priority]??2)-(ot[a.priority]??2)).map(i=>{let a=i.status==="verified"?"status-verified":i.status==="failing"?"status-failing":"status-pending",s=["critical","major","minor"].includes(i.priority)?i.priority:"minor",r=Rt[s],o=i.verification||[],n=this._getWaiverForItem(i.id),l=!!n,c=i.status==="failing"&&(s==="critical"||s==="major"),p=l?`<span class="item-waived-badge" title="${this._escapeHtml(n.reason||"No reason provided")}">WAIVED</span>`:"",u="";return c&&(l?u=`<button class="waiver-btn waiver-btn-unwaive" data-unwaive-id="${this._escapeHtml(i.id)}">Unwaive</button>`:u=`<button class="waiver-btn" data-waive-id="${this._escapeHtml(i.id)}">Waive</button>`),`
7205
+ `}).join(""):this._renderEmpty()}_renderItems(e){return e?.length?[...e].sort((i,a)=>(ut[i.priority]??2)-(ut[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=Jt[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>`),`
7206
7206
  <div class="item">
7207
7207
  <div class="item-status ${a}"></div>
7208
7208
  <div class="item-title">${this._escapeHtml(i.title||i.id||"?")}</div>
@@ -7218,7 +7218,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
7218
7218
  <p><strong>No checklist data yet.</strong></p>
7219
7219
  <p class="hint">The spec checklist is generated during the first iteration. Start a session with <code>loki start ./spec.md</code> (PRD files also accepted) -- groups and items will appear here as the session progresses and can be expanded for details.</p>
7220
7220
  </div>
7221
- `}_attachEventListeners(){let e=this.shadowRoot;e&&(e.querySelectorAll(".category-header[data-category]").forEach(t=>{t.addEventListener("click",()=>this._toggleCategory(t.dataset.category))}),e.querySelectorAll("button[data-waive-id]").forEach(t=>{t.addEventListener("click",i=>{i.stopPropagation(),this._waiveItem(t.dataset.waiveId)})}),e.querySelectorAll("button[data-unwaive-id]").forEach(t=>{t.addEventListener("click",i=>{i.stopPropagation(),this._unwaiveItem(t.dataset.unwaiveId)})}))}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}};customElements.define("loki-checklist-viewer",ae);var nt={not_initialized:{color:"var(--loki-text-muted, #71717a)",label:"Not Started",pulse:!1},starting:{color:"var(--loki-yellow, #ca8a04)",label:"Starting...",pulse:!0},running:{color:"var(--loki-green, #16a34a)",label:"Running",pulse:!0},stale:{color:"var(--loki-yellow, #ca8a04)",label:"Stale",pulse:!1},completed:{color:"var(--loki-text-muted, #a1a1aa)",label:"Completed",pulse:!1},failed:{color:"var(--loki-red, #dc2626)",label:"Failed",pulse:!1},crashed:{color:"var(--loki-red, #dc2626)",label:"Crashed",pulse:!1},stopped:{color:"var(--loki-text-muted, #a1a1aa)",label:"Stopped",pulse:!1},unknown:{color:"var(--loki-text-muted, #71717a)",label:"Unknown",pulse:!1}},se=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._pollInterval=null,this._status=null,this._logs=[],this._lastDataHash=null,this._lastLogsHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let[t,i]=await Promise.all([e.getAppRunnerStatus(),e.getAppRunnerLogs()]);if(e!==this._api)return;let a=JSON.stringify({status:t?.status,port:t?.port,restarts:t?.restart_count,url:t?.url,services:Array.isArray(t?.services)?t.services.map(o=>`${o?.url||""}|${o?.name||""}`).join(","):null}),s=JSON.stringify(i?.lines?.slice(-5)||[]),r=s!==this._lastLogsHash;if(a===this._lastDataHash&&!r)return;this._lastDataHash=a,this._lastLogsHash=s,this._status=t,this._logs=i?.lines||[],this._error=null,this.render(),this._scrollLogsToBottom()}catch(t){if(e!==this._api)return;this._error||(this._error=`Failed to load app status: ${t.message}`,this.render())}}_scrollLogsToBottom(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector(".log-area");t&&(t.scrollTop=t.scrollHeight)}async _handleRestart(){let e=this._api;try{if(await e.restartApp(),e!==this._api)return;this._loadData()}catch(t){if(e!==this._api)return;this._error=`Restart failed: ${t.message}`,this.render()}}async _handleStop(){let e=this._api;try{if(await e.stopApp(),e!==this._api)return;this._loadData()}catch(t){if(e!==this._api)return;this._error=`Stop failed: ${t.message}`,this.render()}}_formatUptime(e){if(!e)return"--";let t=new Date(e),a=Math.floor((new Date-t)/1e3);if(a<60)return`${a}s`;if(a<3600)return`${Math.floor(a/60)}m ${a%60}s`;let s=Math.floor(a/3600),r=Math.floor(a%3600/60);return`${s}h ${r}m`}_isValidUrl(e){if(!e)return!1;try{let t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch{return!1}}_extraServices(e){if(!e||!Array.isArray(e.services))return[];let t=e.url||"",i=[],a=new Set;for(let s of e.services){if(!s||typeof s.url!="string"||!s.url||s.url===t||a.has(s.url))continue;a.add(s.url);let r=typeof s.name=="string"?s.name.trim():"",o=typeof s.role=="string"?s.role.trim():"",n=s.port!=null?String(s.port):"",l=r||o||(n?`Port ${n}`:"Service");i.push({url:s.url,label:l,urlValid:this._isValidUrl(s.url)})}return i}_getStyles(){return`
7221
+ `}_attachEventListeners(){let e=this.shadowRoot;e&&(e.querySelectorAll(".category-header[data-category]").forEach(t=>{t.addEventListener("click",()=>this._toggleCategory(t.dataset.category))}),e.querySelectorAll("button[data-waive-id]").forEach(t=>{t.addEventListener("click",i=>{i.stopPropagation(),this._waiveItem(t.dataset.waiveId)})}),e.querySelectorAll("button[data-unwaive-id]").forEach(t=>{t.addEventListener("click",i=>{i.stopPropagation(),this._unwaiveItem(t.dataset.unwaiveId)})}))}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}};customElements.define("loki-checklist-viewer",re);var gt={not_initialized:{color:"var(--loki-text-muted, #71717a)",label:"Not Started",pulse:!1},starting:{color:"var(--loki-yellow, #ca8a04)",label:"Starting...",pulse:!0},running:{color:"var(--loki-green, #16a34a)",label:"Running",pulse:!0},stale:{color:"var(--loki-yellow, #ca8a04)",label:"Stale",pulse:!1},completed:{color:"var(--loki-text-muted, #a1a1aa)",label:"Completed",pulse:!1},failed:{color:"var(--loki-red, #dc2626)",label:"Failed",pulse:!1},crashed:{color:"var(--loki-red, #dc2626)",label:"Crashed",pulse:!1},stopped:{color:"var(--loki-text-muted, #a1a1aa)",label:"Stopped",pulse:!1},unknown:{color:"var(--loki-text-muted, #71717a)",label:"Unknown",pulse:!1}},oe=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._pollInterval=null,this._status=null,this._logs=[],this._lastDataHash=null,this._lastLogsHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let[t,i]=await Promise.all([e.getAppRunnerStatus(),e.getAppRunnerLogs()]);if(e!==this._api)return;let a=JSON.stringify({status:t?.status,port:t?.port,restarts:t?.restart_count,url:t?.url,services:Array.isArray(t?.services)?t.services.map(o=>`${o?.url||""}|${o?.name||""}`).join(","):null}),s=JSON.stringify(i?.lines?.slice(-5)||[]),r=s!==this._lastLogsHash;if(a===this._lastDataHash&&!r)return;this._lastDataHash=a,this._lastLogsHash=s,this._status=t,this._logs=i?.lines||[],this._error=null,this.render(),this._scrollLogsToBottom()}catch(t){if(e!==this._api)return;this._error||(this._error=`Failed to load app status: ${t.message}`,this.render())}}_scrollLogsToBottom(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector(".log-area");t&&(t.scrollTop=t.scrollHeight)}async _handleRestart(){let e=this._api;try{if(await e.restartApp(),e!==this._api)return;this._loadData()}catch(t){if(e!==this._api)return;this._error=`Restart failed: ${t.message}`,this.render()}}async _handleStop(){let e=this._api;try{if(await e.stopApp(),e!==this._api)return;this._loadData()}catch(t){if(e!==this._api)return;this._error=`Stop failed: ${t.message}`,this.render()}}_formatUptime(e){if(!e)return"--";let t=new Date(e),a=Math.floor((new Date-t)/1e3);if(a<60)return`${a}s`;if(a<3600)return`${Math.floor(a/60)}m ${a%60}s`;let s=Math.floor(a/3600),r=Math.floor(a%3600/60);return`${s}h ${r}m`}_isValidUrl(e){if(!e)return!1;try{let t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch{return!1}}_extraServices(e){if(!e||!Array.isArray(e.services))return[];let t=e.url||"",i=[],a=new Set;for(let s of e.services){if(!s||typeof s.url!="string"||!s.url||s.url===t||a.has(s.url))continue;a.add(s.url);let r=typeof s.name=="string"?s.name.trim():"",o=typeof s.role=="string"?s.role.trim():"",n=s.port!=null?String(s.port):"",l=r||o||(n?`Port ${n}`:"Service");i.push({url:s.url,label:l,urlValid:this._isValidUrl(s.url)})}return i}_getStyles(){return`
7222
7222
  .app-status {
7223
7223
  padding: 16px;
7224
7224
  font-family: var(--loki-font-family, system-ui, -apple-system, sans-serif);
@@ -7394,7 +7394,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
7394
7394
  ${i?"":this._renderEmpty()}
7395
7395
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
7396
7396
  </div>
7397
- `,this._attachEventListeners()}_renderStatusBadge(e){let t=e?.status||"not_initialized",i=nt[t]||nt.not_initialized;return`
7397
+ `,this._attachEventListeners()}_renderStatusBadge(e){let t=e?.status||"not_initialized",i=gt[t]||gt.not_initialized;return`
7398
7398
  <span class="status-badge" style="background: color-mix(in srgb, ${i.color} 15%, transparent); color: ${i.color}">
7399
7399
  <span class="status-dot ${i.pulse?"pulse":""}" style="background: ${i.color}"></span>
7400
7400
  ${this._escapeHtml(i.label)}
@@ -7450,7 +7450,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
7450
7450
  <p>App not running yet</p>
7451
7451
  <p class="hint">Your app will start automatically after the first successful build step.</p>
7452
7452
  </div>
7453
- `}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector('[data-action="restart"]'),i=e.querySelector('[data-action="stop"]');t&&t.addEventListener("click",()=>this._handleRestart()),i&&i.addEventListener("click",()=>this._handleStop())}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}};customElements.define("loki-app-status",se);var lt={not_initialized:{color:"var(--loki-text-muted, #71717a)",label:"No app yet",pulse:!1},starting:{color:"var(--loki-yellow, #ca8a04)",label:"Starting",pulse:!0},running:{color:"var(--loki-green, #16a34a)",label:"Running",pulse:!0},stale:{color:"var(--loki-yellow, #ca8a04)",label:"Stale",pulse:!1},completed:{color:"var(--loki-text-muted, #a1a1aa)",label:"Completed",pulse:!1},failed:{color:"var(--loki-red, #dc2626)",label:"Could not start",pulse:!1},crashed:{color:"var(--loki-red, #dc2626)",label:"Crashed",pulse:!1},stopped:{color:"var(--loki-text-muted, #a1a1aa)",label:"Stopped",pulse:!1},error:{color:"var(--loki-text-muted, #71717a)",label:"Status unavailable",pulse:!1},unknown:{color:"var(--loki-text-muted, #71717a)",label:"Unknown",pulse:!1}},re=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._api=null,this._pollInterval=null,this._status=null,this._errors=null,this._error=null,this._lastDataHash=null,this._detailsOpen=!1,this._iframeFailed=!1,this._iframeLoadTimer=null,this._IFRAME_LOAD_TIMEOUT_MS=6e3,this._activeServiceKey=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this.render(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._clearIframeLoadTimer()}_clearIframeLoadTimer(){this._iframeLoadTimer&&(clearTimeout(this._iframeLoadTimer),this._iframeLoadTimer=null)}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e.getAppRunnerStatus();if(e!==this._api)return;let i=t?.status||"not_initialized",a=null;if(i==="crashed"||i==="failed")try{a=await e.getAppRunnerErrors(50)}catch{a=null}if(e!==this._api)return;let s=JSON.stringify({status:i,port:t?.port,url:t?.url,crash:t?.crash_count,errLen:a?.lines?.length||0,extMgd:t?.externally_managed===!0,source:t?.source||null,healthOk:t?.last_health?.ok===!0?"ok":t?.last_health?.ok===!1?"down":"unknown",services:Array.isArray(t?.services)?t.services.map(o=>`${o?.url||""}|${o?.role||""}|${o?.name||""}`).join(","):null}),r=this._error!==null;if(s===this._lastDataHash&&!r)return;this._iframeFailed=!1,this._lastDataHash=s,this._status=t,this._errors=a,this._error=null,this.render()}catch(t){if(e!==this._api)return;this._error||(this._error=`Could not read app status: ${t.message}`,this.render())}}_isValidUrl(e){if(!e)return!1;try{let t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch{return!1}}_getServices(){let e=this._status;if(!e)return[];let t=Array.isArray(e.services)&&e.services.length>0?e.services:[{url:e.url,role:"",name:e.primary_service||"",port:e.port}],i=new Set,a=[];for(let s of t){if(!s||!this._isValidUrl(s.url))continue;let r=typeof s.name=="string"?s.name.trim():"",o=s.port!=null?String(s.port):"",n=this._inferServiceRole(s.role,r),l=s.url||r||o;if(i.has(l))continue;i.add(l);let c=r;c||(c=n==="api"?"API":n==="ui"?"UI":""),c||(c=o?`Port ${o}`:"Service"),a.push({key:l,url:s.url,role:n,name:r,port:o,label:c})}return a}_inferServiceRole(e,t){let i=typeof e=="string"?e.trim().toLowerCase():"";if(i==="ui"||i==="web"||i==="frontend")return"ui";if(i==="api"||i==="backend"||i==="server")return"api";let a=(t||"").toLowerCase();return/\b(api|backend|server|graphql|grpc)\b/.test(a)||a.includes("api")?"api":""}_activeService(e){if(!e||e.length===0)return null;if(this._activeServiceKey){let t=e.find(i=>i.key===this._activeServiceKey);if(t)return t}return e[0]}_handleSelectService(e){this._activeServiceKey!==e&&(this._activeServiceKey=e,this._iframeFailed=!1,this.render())}async _handleRestart(){let e=this._api;try{if(await e.restartApp(),e!==this._api)return;this._loadData()}catch(t){if(e!==this._api)return;this._error=`Restart failed: ${t.message}`,this.render()}}_currentTargetUrl(){let e=this._activeService(this._getServices());if(e&&this._isValidUrl(e.url))return e.url;let t=this._status;return t&&this._isValidUrl(t.url)?t.url:""}_handleRefresh(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector("iframe.preview-frame"),i=this._currentTargetUrl();if(t&&i){this._iframeFailed=!1,this._clearIframeLoadTimer();let a=(i.includes("?")?"&":"?")+"_t="+Date.now();t.src=i+a,this._armIframeLoadDetection()}}_handleRetryFrame(){this._iframeFailed=!1,this._lastDataHash=null,this.render(),this._loadData()}_handleOpenExternal(){let e=this._currentTargetUrl();e&&window.open(e,"_blank","noopener")}_toggleDetails(){this._detailsOpen=!this._detailsOpen,this.render()}_getStyles(){return`
7453
+ `}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector('[data-action="restart"]'),i=e.querySelector('[data-action="stop"]');t&&t.addEventListener("click",()=>this._handleRestart()),i&&i.addEventListener("click",()=>this._handleStop())}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}};customElements.define("loki-app-status",oe);var mt={not_initialized:{color:"var(--loki-text-muted, #71717a)",label:"No app yet",pulse:!1},starting:{color:"var(--loki-yellow, #ca8a04)",label:"Starting",pulse:!0},running:{color:"var(--loki-green, #16a34a)",label:"Running",pulse:!0},stale:{color:"var(--loki-yellow, #ca8a04)",label:"Stale",pulse:!1},completed:{color:"var(--loki-text-muted, #a1a1aa)",label:"Completed",pulse:!1},failed:{color:"var(--loki-red, #dc2626)",label:"Could not start",pulse:!1},crashed:{color:"var(--loki-red, #dc2626)",label:"Crashed",pulse:!1},stopped:{color:"var(--loki-text-muted, #a1a1aa)",label:"Stopped",pulse:!1},error:{color:"var(--loki-text-muted, #71717a)",label:"Status unavailable",pulse:!1},unknown:{color:"var(--loki-text-muted, #71717a)",label:"Unknown",pulse:!1}},ne=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._api=null,this._pollInterval=null,this._status=null,this._errors=null,this._error=null,this._lastDataHash=null,this._detailsOpen=!1,this._iframeFailed=!1,this._iframeLoadTimer=null,this._IFRAME_LOAD_TIMEOUT_MS=6e3,this._activeServiceKey=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this.render(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling(),this._clearIframeLoadTimer()}_clearIframeLoadTimer(){this._iframeLoadTimer&&(clearTimeout(this._iframeLoadTimer),this._iframeLoadTimer=null)}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e.getAppRunnerStatus();if(e!==this._api)return;let i=t?.status||"not_initialized",a=null;if(i==="crashed"||i==="failed")try{a=await e.getAppRunnerErrors(50)}catch{a=null}if(e!==this._api)return;let s=JSON.stringify({status:i,port:t?.port,url:t?.url,crash:t?.crash_count,errLen:a?.lines?.length||0,extMgd:t?.externally_managed===!0,source:t?.source||null,healthOk:t?.last_health?.ok===!0?"ok":t?.last_health?.ok===!1?"down":"unknown",services:Array.isArray(t?.services)?t.services.map(o=>`${o?.url||""}|${o?.role||""}|${o?.name||""}`).join(","):null}),r=this._error!==null;if(s===this._lastDataHash&&!r)return;this._iframeFailed=!1,this._lastDataHash=s,this._status=t,this._errors=a,this._error=null,this.render()}catch(t){if(e!==this._api)return;this._error||(this._error=`Could not read app status: ${t.message}`,this.render())}}_isValidUrl(e){if(!e)return!1;try{let t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch{return!1}}_getServices(){let e=this._status;if(!e)return[];let t=Array.isArray(e.services)&&e.services.length>0?e.services:[{url:e.url,role:"",name:e.primary_service||"",port:e.port}],i=new Set,a=[];for(let s of t){if(!s||!this._isValidUrl(s.url))continue;let r=typeof s.name=="string"?s.name.trim():"",o=s.port!=null?String(s.port):"",n=this._inferServiceRole(s.role,r),l=s.url||r||o;if(i.has(l))continue;i.add(l);let c=r;c||(c=n==="api"?"API":n==="ui"?"UI":""),c||(c=o?`Port ${o}`:"Service"),a.push({key:l,url:s.url,role:n,name:r,port:o,label:c})}return a}_inferServiceRole(e,t){let i=typeof e=="string"?e.trim().toLowerCase():"";if(i==="ui"||i==="web"||i==="frontend")return"ui";if(i==="api"||i==="backend"||i==="server")return"api";let a=(t||"").toLowerCase();return/\b(api|backend|server|graphql|grpc)\b/.test(a)||a.includes("api")?"api":""}_activeService(e){if(!e||e.length===0)return null;if(this._activeServiceKey){let t=e.find(i=>i.key===this._activeServiceKey);if(t)return t}return e[0]}_handleSelectService(e){this._activeServiceKey!==e&&(this._activeServiceKey=e,this._iframeFailed=!1,this.render())}async _handleRestart(){let e=this._api;try{if(await e.restartApp(),e!==this._api)return;this._loadData()}catch(t){if(e!==this._api)return;this._error=`Restart failed: ${t.message}`,this.render()}}_currentTargetUrl(){let e=this._activeService(this._getServices());if(e&&this._isValidUrl(e.url))return e.url;let t=this._status;return t&&this._isValidUrl(t.url)?t.url:""}_handleRefresh(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector("iframe.preview-frame"),i=this._currentTargetUrl();if(t&&i){this._iframeFailed=!1,this._clearIframeLoadTimer();let a=(i.includes("?")?"&":"?")+"_t="+Date.now();t.src=i+a,this._armIframeLoadDetection()}}_handleRetryFrame(){this._iframeFailed=!1,this._lastDataHash=null,this.render(),this._loadData()}_handleOpenExternal(){let e=this._currentTargetUrl();e&&window.open(e,"_blank","noopener")}_toggleDetails(){this._detailsOpen=!this._detailsOpen,this.render()}_getStyles(){return`
7454
7454
  .preview { padding: 16px; font-family: var(--loki-font-family, system-ui, -apple-system, sans-serif); color: var(--loki-text-primary, #201515); display: flex; flex-direction: column; width: 100%; box-sizing: border-box; }
7455
7455
  .header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; gap: 12px; flex-wrap: wrap; }
7456
7456
  .header-left { display: flex; align-items: center; gap: 10px; }
@@ -7500,7 +7500,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
7500
7500
  .details-toggle:hover { text-decoration: underline; }
7501
7501
  .details-body { margin-top: 8px; background: var(--loki-bg-code, #1e1e1e); color: #d4d4d4; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; padding: 10px; border-radius: 6px; max-height: 200px; overflow: auto; white-space: pre-wrap; }
7502
7502
  .error-banner { margin-top: 12px; padding: 10px 12px; border-radius: 6px; background: color-mix(in srgb, var(--loki-red, #dc2626) 10%, transparent); color: var(--loki-red, #dc2626); font-size: 13px; }
7503
- `}_effectiveView(e,t){let i=this._status,a=i?.last_health,s=a&&typeof a.ok=="boolean"?a.ok:null;if(e==="running"&&t&&(i?.externally_managed===!0||i?.source==="discovered"))return{view:"running",healthOk:s};if(e==="running"&&t){if(s===!1)return{view:"starting",healthOk:s};if(s===!0)return{view:"running",healthOk:s};let r=i?.started_at?Date.parse(i.started_at):NaN;return{view:Number.isFinite(r)&&Date.now()-r<15e3?"running":"starting",healthOk:s}}return{view:e,healthOk:s}}render(){let e=this.shadowRoot;if(!e)return;this._clearIframeLoadTimer();let t=this._status,i=t?.status||"not_initialized",a=this._getServices(),s=this._activeService(a),r=a.length>1,o=s?.url||t?.url,n=this._isValidUrl(o),{view:l,healthOk:c}=this._effectiveView(i,n),p=t?.externally_managed===!0||t?.source==="discovered",u=lt[l]||lt.not_initialized,m=i==="running"&&c===!1?"Starting / not responding yet":u.label;e.innerHTML=`
7503
+ `}_effectiveView(e,t){let i=this._status,a=i?.last_health,s=a&&typeof a.ok=="boolean"?a.ok:null;if(e==="running"&&t&&(i?.externally_managed===!0||i?.source==="discovered"))return{view:"running",healthOk:s};if(e==="running"&&t){if(s===!1)return{view:"starting",healthOk:s};if(s===!0)return{view:"running",healthOk:s};let r=i?.started_at?Date.parse(i.started_at):NaN;return{view:Number.isFinite(r)&&Date.now()-r<15e3?"running":"starting",healthOk:s}}return{view:e,healthOk:s}}render(){let e=this.shadowRoot;if(!e)return;this._clearIframeLoadTimer();let t=this._status,i=t?.status||"not_initialized",a=this._getServices(),s=this._activeService(a),r=a.length>1,o=s?.url||t?.url,n=this._isValidUrl(o),{view:l,healthOk:c}=this._effectiveView(i,n),p=t?.externally_managed===!0||t?.source==="discovered",u=mt[l]||mt.not_initialized,m=i==="running"&&c===!1?"Starting / not responding yet":u.label;e.innerHTML=`
7504
7504
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
7505
7505
  <div class="preview">
7506
7506
  <div class="header">
@@ -7621,14 +7621,14 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
7621
7621
  </button>
7622
7622
  ${this._detailsOpen?`<div class="details-body">${s}</div>`:""}
7623
7623
  </div>
7624
- `}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=(i,a)=>{let s=e.querySelector(i);s&&s.addEventListener("click",a)};e.querySelectorAll('[data-action="restart"]').forEach(i=>i.addEventListener("click",()=>this._handleRestart())),e.querySelectorAll('[data-action="open-external"]').forEach(i=>i.addEventListener("click",()=>this._handleOpenExternal())),e.querySelectorAll('[data-action="retry-frame"]').forEach(i=>i.addEventListener("click",()=>this._handleRetryFrame())),t('[data-action="refresh"]',()=>this._handleRefresh()),t('[data-action="toggle-details"]',()=>this._toggleDetails()),e.querySelectorAll('[data-action="select-service"]').forEach(i=>i.addEventListener("click",()=>this._handleSelectService(i.getAttribute("data-service-key"))))}_escapeHtml(e){return e==null?"":String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}};customElements.define("loki-app-preview",re);var Pt={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"}},oe=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data={total_input_tokens:0,total_output_tokens:0,estimated_cost_usd:0,by_phase:{},by_model:{},budget_limit:null,budget_used:0,budget_remaining:null,connected:!1},this._api=null,this._pollInterval=null,this._modelPricing={...Pt}}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadPricing(),this._loadCost(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadCost()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadPricing(){let e=this._api;try{let t=await e.getPricing();if(e!==this._api)return;if(t&&t.models){let i={};for(let[a,s]of Object.entries(t.models))i[a]={input:s.input,output:s.output,label:s.label||a,provider:s.provider||"unknown",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||0,total_output_tokens:e.total_output_tokens||0,estimated_cost_usd:e.estimated_cost_usd||0,by_phase:e.by_phase||{},by_model:e.by_model||{},budget_limit:e.budget_limit,budget_used:e.budget_used||0,budget_remaining:e.budget_remaining},this.render())}_startPolling(){this._poll=b({loadFn:()=>this._loadCost(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_formatTokens(e){return!e||e===0?"0":e>=1e6?(e/1e6).toFixed(2)+"M":e>=1e3?(e/1e3).toFixed(1)+"K":String(e)}_formatUSD(e){return!e||e===0?"$0.00":e<.01?"<$0.01":"$"+e.toFixed(2)}_getBudgetPercent(){return!this._data.budget_limit||this._data.budget_limit<=0?0:Math.min(100,this._data.budget_used/this._data.budget_limit*100)}_getBudgetStatusClass(){let e=this._getBudgetPercent();return e>=90?"critical":e>=70?"warning":"ok"}_renderPhaseRows(){let e=this._data.by_phase;return!e||Object.keys(e).length===0?'<tr><td colspan="4" class="empty-cell">No phase data yet</td></tr>':Object.entries(e).map(([t,i])=>{let a=i.input_tokens||0,s=i.output_tokens||0,r=i.cost_usd||0;return`
7624
+ `}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=(i,a)=>{let s=e.querySelector(i);s&&s.addEventListener("click",a)};e.querySelectorAll('[data-action="restart"]').forEach(i=>i.addEventListener("click",()=>this._handleRestart())),e.querySelectorAll('[data-action="open-external"]').forEach(i=>i.addEventListener("click",()=>this._handleOpenExternal())),e.querySelectorAll('[data-action="retry-frame"]').forEach(i=>i.addEventListener("click",()=>this._handleRetryFrame())),t('[data-action="refresh"]',()=>this._handleRefresh()),t('[data-action="toggle-details"]',()=>this._toggleDetails()),e.querySelectorAll('[data-action="select-service"]').forEach(i=>i.addEventListener("click",()=>this._handleSelectService(i.getAttribute("data-service-key"))))}_escapeHtml(e){return e==null?"":String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}};customElements.define("loki-app-preview",ne);var Gt={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"}},le=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={...Gt}}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadPricing(),this._loadCost(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadCost()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadPricing(){let e=this._api;try{let t=await e.getPricing();if(e!==this._api)return;if(t&&t.models){let i={};for(let[a,s]of Object.entries(t.models))i[a]={input:s.input,output:s.output,label:s.label||a,provider:s.provider||"unknown",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 Ne(e)}_formatUSD(e){return I(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`
7625
7625
  <tr>
7626
7626
  <td class="phase-name">${this._escapeHTML(t)}</td>
7627
7627
  <td class="mono-cell">${this._formatTokens(a)}</td>
7628
7628
  <td class="mono-cell">${this._formatTokens(s)}</td>
7629
7629
  <td class="mono-cell cost-cell">${this._formatUSD(r)}</td>
7630
7630
  </tr>
7631
- `}).join("")}_renderModelRows(){let e=this._data.by_model;return!e||Object.keys(e).length===0?'<tr><td colspan="4" class="empty-cell">No model data yet</td></tr>':Object.entries(e).map(([t,i])=>{let a=i.input_tokens||0,s=i.output_tokens||0,r=i.cost_usd||0;return`
7631
+ `}).join("")}_renderModelRows(){let e=this._data.by_model;return!e||Object.keys(e).length===0?'<tr><td colspan="4" class="empty-cell">No model data yet</td></tr>':Object.entries(e).map(([t,i])=>{let a=i.input_tokens??null,s=i.output_tokens??null,r=i.cost_usd??null;return`
7632
7632
  <tr>
7633
7633
  <td class="model-name">${this._escapeHTML(t)}</td>
7634
7634
  <td class="mono-cell">${this._formatTokens(a)}</td>
@@ -7645,7 +7645,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
7645
7645
  </div>
7646
7646
  <div class="budget-not-set">No budget configured</div>
7647
7647
  </div>
7648
- `;let e=this._getBudgetPercent(),t=this._getBudgetStatusClass(),i=this._data.budget_remaining!=null?this._formatUSD(this._data.budget_remaining):this._formatUSD(this._data.budget_limit-this._data.budget_used);return`
7648
+ `;let e=this._getBudgetPercent(),t=this._getBudgetStatusClass(),i=this._data.budget_limit!=null&&this._data.budget_used!=null,a=this._data.budget_remaining!=null?this._formatUSD(this._data.budget_remaining):this._formatUSD(i?this._data.budget_limit-this._data.budget_used:null);return`
7649
7649
  <div class="budget-section">
7650
7650
  <div class="section-header">
7651
7651
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
@@ -7658,11 +7658,11 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
7658
7658
  </div>
7659
7659
  <div class="budget-details">
7660
7660
  <span class="budget-used">${this._formatUSD(this._data.budget_used)} used</span>
7661
- <span class="budget-remaining">${i} remaining</span>
7661
+ <span class="budget-remaining">${a} remaining</span>
7662
7662
  <span class="budget-limit">of ${this._formatUSD(this._data.budget_limit)}</span>
7663
7663
  </div>
7664
7664
  </div>
7665
- `}_getRARVTier(e){if(e==null)return null;switch(e%4){case 0:return"opus";case 1:return"sonnet";case 2:return"sonnet";case 3:return"haiku";default:return"sonnet"}}_getPricingColorClass(e,t){if(t.tier==="planning")return"opus";if(t.tier==="development")return"sonnet";if(t.tier==="fast")return"haiku";if(t.iteration!=null)return this._getRARVTier(t.iteration)||"";let i=(e||"").toLowerCase();return i.includes("opus")?"opus":i.includes("sonnet")?"sonnet":i.includes("haiku")?"haiku":t.provider==="codex"||i.includes("gpt")||i.includes("codex")?"codex":""}_escapeHTML(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}render(){let e=this._data.total_input_tokens+this._data.total_output_tokens;this.shadowRoot.innerHTML=`
7665
+ `}_getRARVTier(e){if(e==null)return null;switch(e%4){case 0:return"opus";case 1:return"sonnet";case 2:return"sonnet";case 3:return"haiku";default:return"sonnet"}}_getPricingColorClass(e,t){if(t.tier==="planning")return"opus";if(t.tier==="development")return"sonnet";if(t.tier==="fast")return"haiku";if(t.iteration!=null)return this._getRARVTier(t.iteration)||"";let i=(e||"").toLowerCase();return i.includes("opus")?"opus":i.includes("sonnet")?"sonnet":i.includes("haiku")?"haiku":t.provider==="codex"||i.includes("gpt")||i.includes("codex")?"codex":""}_escapeHTML(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}render(){let e=this._data.total_input_tokens,t=this._data.total_output_tokens,i=e==null&&t==null?null:(e??0)+(t??0);this.shadowRoot.innerHTML=`
7666
7666
  <style>
7667
7667
  ${this.getBaseStyles()}
7668
7668
 
@@ -7943,7 +7943,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
7943
7943
  <div class="summary-grid">
7944
7944
  <div class="summary-card">
7945
7945
  <div class="card-label">Total Tokens</div>
7946
- <div class="card-value">${this._formatTokens(e)}</div>
7946
+ <div class="card-value">${this._formatTokens(i)}</div>
7947
7947
  <div class="card-sub">${this._formatTokens(this._data.total_input_tokens)} in / ${this._formatTokens(this._data.total_output_tokens)} out</div>
7948
7948
  </div>
7949
7949
 
@@ -8022,16 +8022,16 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
8022
8022
  ${this._pricingDate?`<span class="pricing-meta">Updated: ${this._escapeHTML(this._pricingDate)}</span>`:""}
8023
8023
  </div>
8024
8024
  <div class="pricing-grid">
8025
- ${Object.entries(this._modelPricing).map(([t,i])=>`
8025
+ ${Object.entries(this._modelPricing).map(([a,s])=>`
8026
8026
  <div class="pricing-item">
8027
- <div class="pricing-model ${this._getPricingColorClass(t,i)}">${this._escapeHTML(i.label||t)}</div>
8028
- <div class="pricing-rates">In: $${Number(i.input??0).toFixed(2)} / Out: $${Number(i.output??0).toFixed(2)}</div>
8029
- ${i.note?`<div class="pricing-note">${this._escapeHTML(i.note)}</div>`:""}
8027
+ <div class="pricing-model ${this._getPricingColorClass(a,s)}">${this._escapeHTML(s.label||a)}</div>
8028
+ <div class="pricing-rates">In: $${Number(s.input??0).toFixed(2)} / Out: $${Number(s.output??0).toFixed(2)}</div>
8029
+ ${s.note?`<div class="pricing-note">${this._escapeHTML(s.note)}</div>`:""}
8030
8030
  </div>`).join("")}
8031
8031
  </div>
8032
8032
  </div>
8033
8033
  </div>
8034
- `}};customElements.get("loki-cost-dashboard")||customElements.define("loki-cost-dashboard",oe);var ne=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._checkpoints=[],this._pollInterval=null,this._lastDataHash=null,this._showCreateForm=!1,this._creating=!1,this._rollingBack=!1,this._rollbackTarget=null,this._notice=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let[i]=await Promise.allSettled([e._get("/api/checkpoints?limit=50")]);if(e!==this._api)return;i.status==="fulfilled"&&(this._checkpoints=Array.isArray(i.value)?i.value:i.value?.checkpoints||[]),this._error=null}catch(i){if(e!==this._api)return;this._error=i.message}let t=JSON.stringify({c:this._checkpoints,e:this._error});t!==this._lastDataHash&&(this._lastDataHash=t,this.render())}async _createCheckpoint(){let e=this.shadowRoot.getElementById("checkpoint-message"),t=e?e.value.trim():"";if(t){this._creating=!0,this.render();try{await this._api._post("/api/checkpoints",{message:t}),this._showCreateForm=!1,this._creating=!1,this.dispatchEvent(new CustomEvent("checkpoint-action",{detail:{action:"create",message:t},bubbles:!0})),this._lastDataHash=null,await this._loadData()}catch(i){this._creating=!1,this._error=`Failed to create checkpoint: ${i.message}`,this.render()}}}async _rollbackCheckpoint(e){if(!this._rollingBack){this._rollingBack=!0,this._notice=null,this.render();try{let t=await this._api._post(`/api/checkpoints/${e}/rollback`);this._rollbackTarget=null;let i=t&&t.pre_rollback_snapshot;this._notice=i?`Rolled back to ${e}. Undo this with checkpoint ${i}`:`Rolled back to ${e}.`,this.dispatchEvent(new CustomEvent("checkpoint-action",{detail:{action:"rollback",checkpointId:e,preRollbackSnapshot:i||null},bubbles:!0})),this._lastDataHash=null,await this._loadData()}catch(t){this._rollbackTarget=null,this._error=`Failed to rollback: ${t.message}`}finally{this._rollingBack=!1,this.render()}}}_toggleCreateForm(){this._showCreateForm=!this._showCreateForm,this._rollbackTarget=null,this._notice=null,this.render()}_confirmRollback(e){this._rollbackTarget=e,this.render()}_cancelRollback(){this._rollbackTarget=null,this._notice=null,this.render()}_formatRelativeTime(e){if(!e)return"";try{let t=Date.now(),i=new Date(e).getTime(),a=Math.floor((t-i)/1e3);return a<60?`${a}s ago`:a<3600?`${Math.floor(a/60)}m ago`:a<86400?`${Math.floor(a/3600)}h ago`:`${Math.floor(a/86400)}d ago`}catch{return this._escapeHTML(e)}}render(){let e=this.shadowRoot;if(!e)return;let t=this._checkpoints.length;e.innerHTML=`
8034
+ `}};customElements.get("loki-cost-dashboard")||customElements.define("loki-cost-dashboard",le);var de=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._checkpoints=[],this._pollInterval=null,this._lastDataHash=null,this._showCreateForm=!1,this._creating=!1,this._rollingBack=!1,this._rollbackTarget=null,this._notice=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let[i]=await Promise.allSettled([e._get("/api/checkpoints?limit=50")]);if(e!==this._api)return;i.status==="fulfilled"&&(this._checkpoints=Array.isArray(i.value)?i.value:i.value?.checkpoints||[]),this._error=null}catch(i){if(e!==this._api)return;this._error=i.message}let t=JSON.stringify({c:this._checkpoints,e:this._error});t!==this._lastDataHash&&(this._lastDataHash=t,this.render())}async _createCheckpoint(){let e=this.shadowRoot.getElementById("checkpoint-message"),t=e?e.value.trim():"";if(t){this._creating=!0,this.render();try{await this._api._post("/api/checkpoints",{message:t}),this._showCreateForm=!1,this._creating=!1,this.dispatchEvent(new CustomEvent("checkpoint-action",{detail:{action:"create",message:t},bubbles:!0})),this._lastDataHash=null,await this._loadData()}catch(i){this._creating=!1,this._error=`Failed to create checkpoint: ${i.message}`,this.render()}}}async _rollbackCheckpoint(e){if(!this._rollingBack){this._rollingBack=!0,this._notice=null,this.render();try{let t=await this._api._post(`/api/checkpoints/${e}/rollback`);this._rollbackTarget=null;let i=t&&t.pre_rollback_snapshot;this._notice=i?`Rolled back to ${e}. Undo this with checkpoint ${i}`:`Rolled back to ${e}.`,this.dispatchEvent(new CustomEvent("checkpoint-action",{detail:{action:"rollback",checkpointId:e,preRollbackSnapshot:i||null},bubbles:!0})),this._lastDataHash=null,await this._loadData()}catch(t){this._rollbackTarget=null,this._error=`Failed to rollback: ${t.message}`}finally{this._rollingBack=!1,this.render()}}}_toggleCreateForm(){this._showCreateForm=!this._showCreateForm,this._rollbackTarget=null,this._notice=null,this.render()}_confirmRollback(e){this._rollbackTarget=e,this.render()}_cancelRollback(){this._rollbackTarget=null,this._notice=null,this.render()}_formatRelativeTime(e){if(!e)return"";try{let t=Date.now(),i=new Date(e).getTime(),a=Math.floor((t-i)/1e3);return a<60?`${a}s ago`:a<3600?`${Math.floor(a/60)}m ago`:a<86400?`${Math.floor(a/3600)}h ago`:`${Math.floor(a/86400)}d ago`}catch{return this._escapeHTML(e)}}render(){let e=this.shadowRoot;if(!e)return;let t=this._checkpoints.length;e.innerHTML=`
8035
8035
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
8036
8036
  <div class="checkpoint-viewer">
8037
8037
  <div class="checkpoint-header">
@@ -8350,7 +8350,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
8350
8350
  color: var(--loki-green, #22c55e);
8351
8351
  font-size: 12px;
8352
8352
  }
8353
- `}};customElements.get("loki-checkpoint-viewer")||customElements.define("loki-checkpoint-viewer",ne);var le=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data=null,this._connected=!1,this._activeTab="gauge",this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadContext(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadContext()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadContext(){let e=this._api;try{let t=this.getAttribute("api-url")||window.location.origin,i=await fetch(t+"/api/context");if(i.ok){let a=await i.json();if(e!==this._api)return;this._data=a,this._connected=!0}}catch{if(e!==this._api)return;this._connected=!1}this.render()}_startPolling(){this._poll=b({loadFn:()=>this._loadContext(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_setTab(e){this._activeTab=e,this.render()}_formatTokens(e){return!e||e===0?"0":e>=1e6?(e/1e6).toFixed(2)+"M":e>=1e3?(e/1e3).toFixed(1)+"K":String(e)}_formatUSD(e){return!e||e===0?"$0.00":e<.01?"<$0.01":"$"+e.toFixed(2)}_escapeHTML(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getGaugeColor(e){return e>80?"var(--loki-red)":e>=60?"var(--loki-yellow)":"var(--loki-green)"}_getGaugeColorClass(e){return e>80?"gauge-red":e>=60?"gauge-yellow":"gauge-green"}_renderGaugeTab(){let e=this._data?.current||{},t=this._data?.totals||{},i=e.context_window_pct||0,a=this._getGaugeColor(i),s=this._getGaugeColorClass(i),r=70,o=2*Math.PI*r,n=o-i/100*o;return`
8353
+ `}};customElements.get("loki-checkpoint-viewer")||customElements.define("loki-checkpoint-viewer",de);var ce=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data=null,this._connected=!1,this._activeTab="gauge",this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadContext(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadContext()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadContext(){let e=this._api;try{let t=this.getAttribute("api-url")||window.location.origin,i=await fetch(t+"/api/context");if(i.ok){let a=await i.json();if(e!==this._api)return;this._data=a,this._connected=!0}}catch{if(e!==this._api)return;this._connected=!1}this.render()}_startPolling(){this._poll=b({loadFn:()=>this._loadContext(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_setTab(e){this._activeTab=e,this.render()}_formatTokens(e){return e==null||Number.isNaN(e)?"unknown":e>=1e6?(e/1e6).toFixed(2)+"M":e>=1e3?(e/1e3).toFixed(1)+"K":String(e)}_formatUSD(e){return e==null||Number.isNaN(e)?"unknown":e===0?"$0.00":e<.01?"<$0.01":"$"+e.toFixed(2)}_sumTokens(e){let t=[e.input_tokens,e.output_tokens,e.cache_read_tokens,e.cache_creation_tokens];return t.every(i=>i==null)?null:t.reduce((i,a)=>i+(a??0),0)}_escapeHTML(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getGaugeColor(e){return e>80?"var(--loki-red)":e>=60?"var(--loki-yellow)":"var(--loki-green)"}_getGaugeColorClass(e){return e>80?"gauge-red":e>=60?"gauge-yellow":"gauge-green"}_renderGaugeTab(){let e=this._data?.current||{},t=this._data?.totals||{},i=e.context_window_pct||0,a=this._getGaugeColor(i),s=this._getGaugeColorClass(i),r=70,o=2*Math.PI*r,n=o-i/100*o;return`
8354
8354
  <div class="gauge-tab">
8355
8355
  <div class="gauge-container">
8356
8356
  <svg class="gauge-svg" viewBox="0 0 180 180" aria-label="Context window usage: ${i.toFixed(1)}%">
@@ -8425,7 +8425,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
8425
8425
  </div>
8426
8426
  </div>
8427
8427
  </div>
8428
- `}_renderTimelineTab(){let e=this._data?.per_iteration||[],t=this._data?.compactions||[];if(e.length===0)return'<div class="empty-state">No iteration data yet</div>';let i=Math.max(...e.map(r=>(r.input_tokens||0)+(r.output_tokens||0)+(r.cache_read_tokens||0)+(r.cache_creation_tokens||0))),a=new Set(t.map(r=>r.at_iteration)),s="";for(let r of e){let o=(r.input_tokens||0)+(r.output_tokens||0)+(r.cache_read_tokens||0)+(r.cache_creation_tokens||0),n=i>0?o/i*100:0,l=r.compacted===!0;a.has(r.iteration)&&(s+=`
8428
+ `}_renderTimelineTab(){let e=this._data?.per_iteration||[],t=this._data?.compactions||[];if(e.length===0)return'<div class="empty-state">No iteration data yet</div>';let i=Math.max(...e.map(r=>this._sumTokens(r)||0)),a=new Set(t.map(r=>r.at_iteration)),s="";for(let r of e){let o=this._sumTokens(r),n=i>0?o/i*100:0,l=r.compacted===!0;a.has(r.iteration)&&(s+=`
8429
8429
  <div class="timeline-compaction-row">
8430
8430
  <div class="compaction-line"></div>
8431
8431
  <span class="compaction-label">Context Compacted</span>
@@ -8456,7 +8456,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
8456
8456
  </div>
8457
8457
  ${s}
8458
8458
  </div>
8459
- `}_renderBreakdownTab(){let e=this._data?.per_iteration||[];if(e.length===0)return'<div class="empty-state">No iteration data yet</div>';let t=Math.max(...e.map(s=>(s.input_tokens||0)+(s.output_tokens||0)+(s.cache_read_tokens||0)+(s.cache_creation_tokens||0))),i=`
8459
+ `}_renderBreakdownTab(){let e=this._data?.per_iteration||[];if(e.length===0)return'<div class="empty-state">No iteration data yet</div>';let t=Math.max(...e.map(s=>this._sumTokens(s)||0)),i=`
8460
8460
  <div class="breakdown-legend">
8461
8461
  <div class="legend-item"><span class="legend-swatch swatch-input"></span> Input</div>
8462
8462
  <div class="legend-item"><span class="legend-swatch swatch-output"></span> Output</div>
@@ -8873,7 +8873,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
8873
8873
 
8874
8874
  ${e}
8875
8875
  </div>
8876
- `,this.shadowRoot.querySelectorAll(".tab").forEach(t=>{t.addEventListener("click",()=>{this._setTab(t.dataset.tab)})})}};customElements.get("loki-context-tracker")||customElements.define("loki-context-tracker",le);var Ke={critical:"var(--loki-red, #ef4444)",warning:"var(--loki-yellow, #eab308)",info:"var(--loki-blue, #3b82f6)",success:"var(--loki-green, #1FC5A8)"},dt={build:{label:"Build",icon:"B"},quality:{label:"Quality",icon:"Q"},system:{label:"System",icon:"S"},security:{label:"Security",icon:"!"}},de=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._notifications=[],this._triggers=[],this._summary={},this._connected=!1,this._activeTab="feed",this._categoryFilter="all",this._panelOpen=!0,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._loadNotifications(),this._loadTriggers(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&(this._loadNotifications(),this._loadTriggers()),e==="theme"&&this._applyTheme())}async _loadNotifications(){try{let e=this.getAttribute("api-url")||window.location.origin,t=await fetch(e+"/api/notifications");if(t.ok){let i=await t.json();this._notifications=i.notifications||[],this._summary=i.summary||{},this._connected=!0}}catch{this._connected=!1}this.render()}async _loadTriggers(){try{let e=this.getAttribute("api-url")||window.location.origin,t=await fetch(e+"/api/notifications/triggers");if(t.ok){let i=await t.json();this._triggers=i.triggers||[]}}catch{}}async _acknowledgeNotification(e){let t=this.getAttribute("api-url")||window.location.origin;try{await fetch(t+"/api/notifications/"+encodeURIComponent(e)+"/acknowledge",{method:"POST"})}catch{}this._loadNotifications()}async _unacknowledgeNotification(e){let t=this.getAttribute("api-url")||window.location.origin;await fetch(t+"/api/notifications/"+encodeURIComponent(e)+"/unacknowledge",{method:"POST"}),this._loadNotifications()}async _acknowledgeAll(){let e=this.getAttribute("api-url")||window.location.origin,t=this._notifications.filter(i=>!i.acknowledged);for(let i of t)await fetch(e+"/api/notifications/"+encodeURIComponent(i.id)+"/acknowledge",{method:"POST"});this._loadNotifications()}async _toggleTrigger(e,t){let i=this.getAttribute("api-url")||window.location.origin,a=this._triggers.map(s=>s.id===e?{...s,enabled:t}:s);await fetch(i+"/api/notifications/triggers",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({triggers:a})}),this._triggers=a,this.render()}_startPolling(){this._poll=b({loadFn:()=>{this._loadNotifications(),this._loadTriggers()},intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_formatTime(e){if(!e)return"";try{let t=new Date(e),a=new Date-t,s=Math.floor(a/1e3),r=Math.floor(s/60),o=Math.floor(r/60),n=Math.floor(o/24);return s<60?s+"s ago":r<60?r+"m ago":o<24?o+"h ago":n<7?n+"d ago":t.toLocaleDateString()}catch{return String(e)}}_getTimeGroup(e){if(!e)return"Other";try{let t=new Date(e),i=new Date,a=new Date(i.getFullYear(),i.getMonth(),i.getDate()),s=new Date(a);s.setDate(s.getDate()-1);let r=new Date(a);return r.setDate(r.getDate()-7),t>=a?"Today":t>=s?"Yesterday":t>=r?"This Week":"Earlier"}catch{return"Other"}}_escapeHTML(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getSeverityColor(e){return Ke[e]||Ke.info}_getCategory(e){return e.category||e.type||"system"}_switchTab(e){this._activeTab=e,this.render()}_setCategoryFilter(e){this._categoryFilter=e,this.render()}_togglePanel(){this._panelOpen=!this._panelOpen,this.render()}_bindEvents(){let e=this.shadowRoot;e.querySelectorAll(".tab").forEach(a=>{a.addEventListener("click",()=>{this._switchTab(a.dataset.tab)})}),e.querySelectorAll(".cat-btn").forEach(a=>{a.addEventListener("click",()=>{this._setCategoryFilter(a.dataset.cat)})}),e.querySelectorAll(".ack-btn").forEach(a=>{a.addEventListener("click",s=>{s.stopPropagation(),this._acknowledgeNotification(a.dataset.id)})}),e.querySelectorAll(".unread-btn").forEach(a=>{a.addEventListener("click",s=>{s.stopPropagation(),this._unacknowledgeNotification(a.dataset.id)})});let t=e.querySelector(".ack-all-btn");t&&t.addEventListener("click",()=>{this._acknowledgeAll()});let i=e.querySelector(".bell-icon");i&&i.addEventListener("click",()=>{this._togglePanel()}),e.querySelectorAll(".toggle input").forEach(a=>{a.addEventListener("change",()=>{this._toggleTrigger(a.dataset.triggerId,a.checked)})}),e.querySelectorAll(".dismiss-btn").forEach(a=>{a.addEventListener("click",s=>{s.stopPropagation(),this._acknowledgeNotification(a.dataset.id)})})}_renderBellIcon(){let e=this._summary.unacknowledged||0;return`
8876
+ `,this.shadowRoot.querySelectorAll(".tab").forEach(t=>{t.addEventListener("click",()=>{this._setTab(t.dataset.tab)})})}};customElements.get("loki-context-tracker")||customElements.define("loki-context-tracker",ce);var Qe={critical:"var(--loki-red, #ef4444)",warning:"var(--loki-yellow, #eab308)",info:"var(--loki-blue, #3b82f6)",success:"var(--loki-green, #1FC5A8)"},vt={build:{label:"Build",icon:"B"},quality:{label:"Quality",icon:"Q"},system:{label:"System",icon:"S"},security:{label:"Security",icon:"!"}},pe=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._notifications=[],this._triggers=[],this._summary={},this._connected=!1,this._activeTab="feed",this._categoryFilter="all",this._panelOpen=!0,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._loadNotifications(),this._loadTriggers(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&(this._loadNotifications(),this._loadTriggers()),e==="theme"&&this._applyTheme())}async _loadNotifications(){try{let e=this.getAttribute("api-url")||window.location.origin,t=await fetch(e+"/api/notifications");if(t.ok){let i=await t.json();this._notifications=i.notifications||[],this._summary=i.summary||{},this._connected=!0}}catch{this._connected=!1}this.render()}async _loadTriggers(){try{let e=this.getAttribute("api-url")||window.location.origin,t=await fetch(e+"/api/notifications/triggers");if(t.ok){let i=await t.json();this._triggers=i.triggers||[]}}catch{}}async _acknowledgeNotification(e){let t=this.getAttribute("api-url")||window.location.origin;try{await fetch(t+"/api/notifications/"+encodeURIComponent(e)+"/acknowledge",{method:"POST"})}catch{}this._loadNotifications()}async _unacknowledgeNotification(e){let t=this.getAttribute("api-url")||window.location.origin;await fetch(t+"/api/notifications/"+encodeURIComponent(e)+"/unacknowledge",{method:"POST"}),this._loadNotifications()}async _acknowledgeAll(){let e=this.getAttribute("api-url")||window.location.origin,t=this._notifications.filter(i=>!i.acknowledged);for(let i of t)await fetch(e+"/api/notifications/"+encodeURIComponent(i.id)+"/acknowledge",{method:"POST"});this._loadNotifications()}async _toggleTrigger(e,t){let i=this.getAttribute("api-url")||window.location.origin,a=this._triggers.map(s=>s.id===e?{...s,enabled:t}:s);await fetch(i+"/api/notifications/triggers",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({triggers:a})}),this._triggers=a,this.render()}_startPolling(){this._poll=b({loadFn:()=>{this._loadNotifications(),this._loadTriggers()},intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_formatTime(e){if(!e)return"";try{let t=new Date(e),a=new Date-t,s=Math.floor(a/1e3),r=Math.floor(s/60),o=Math.floor(r/60),n=Math.floor(o/24);return s<60?s+"s ago":r<60?r+"m ago":o<24?o+"h ago":n<7?n+"d ago":t.toLocaleDateString()}catch{return String(e)}}_getTimeGroup(e){if(!e)return"Other";try{let t=new Date(e),i=new Date,a=new Date(i.getFullYear(),i.getMonth(),i.getDate()),s=new Date(a);s.setDate(s.getDate()-1);let r=new Date(a);return r.setDate(r.getDate()-7),t>=a?"Today":t>=s?"Yesterday":t>=r?"This Week":"Earlier"}catch{return"Other"}}_escapeHTML(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getSeverityColor(e){return Qe[e]||Qe.info}_getCategory(e){return e.category||e.type||"system"}_switchTab(e){this._activeTab=e,this.render()}_setCategoryFilter(e){this._categoryFilter=e,this.render()}_togglePanel(){this._panelOpen=!this._panelOpen,this.render()}_bindEvents(){let e=this.shadowRoot;e.querySelectorAll(".tab").forEach(a=>{a.addEventListener("click",()=>{this._switchTab(a.dataset.tab)})}),e.querySelectorAll(".cat-btn").forEach(a=>{a.addEventListener("click",()=>{this._setCategoryFilter(a.dataset.cat)})}),e.querySelectorAll(".ack-btn").forEach(a=>{a.addEventListener("click",s=>{s.stopPropagation(),this._acknowledgeNotification(a.dataset.id)})}),e.querySelectorAll(".unread-btn").forEach(a=>{a.addEventListener("click",s=>{s.stopPropagation(),this._unacknowledgeNotification(a.dataset.id)})});let t=e.querySelector(".ack-all-btn");t&&t.addEventListener("click",()=>{this._acknowledgeAll()});let i=e.querySelector(".bell-icon");i&&i.addEventListener("click",()=>{this._togglePanel()}),e.querySelectorAll(".toggle input").forEach(a=>{a.addEventListener("change",()=>{this._toggleTrigger(a.dataset.triggerId,a.checked)})}),e.querySelectorAll(".dismiss-btn").forEach(a=>{a.addEventListener("click",s=>{s.stopPropagation(),this._acknowledgeNotification(a.dataset.id)})})}_renderBellIcon(){let e=this._summary.unacknowledged||0;return`
8877
8877
  <div class="bell-container">
8878
8878
  <button class="bell-icon" title="${e} unread notifications">
8879
8879
  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
@@ -8896,7 +8896,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
8896
8896
  </div>
8897
8897
  <div class="summary-card">
8898
8898
  <div class="card-label">Critical</div>
8899
- <div class="card-value" style="color: ${Ke.critical}">${i}</div>
8899
+ <div class="card-value" style="color: ${Qe.critical}">${i}</div>
8900
8900
  </div>
8901
8901
  </div>
8902
8902
  ${t>0?`
@@ -8905,9 +8905,9 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
8905
8905
  </div>
8906
8906
  `}_renderCategoryFilter(){return`
8907
8907
  <div class="category-bar">
8908
- ${["all","build","quality","system","security"].map(t=>{let i=this._categoryFilter===t,a=t==="all"?"All":dt[t]?.label||t;return`<button class="cat-btn ${i?"active":""}" data-cat="${t}">${a}</button>`}).join("")}
8908
+ ${["all","build","quality","system","security"].map(t=>{let i=this._categoryFilter===t,a=t==="all"?"All":vt[t]?.label||t;return`<button class="cat-btn ${i?"active":""}" data-cat="${t}">${a}</button>`}).join("")}
8909
8909
  </div>
8910
- `}_renderNotificationList(){let e=[...this._notifications].sort((s,r)=>new Date(r.timestamp)-new Date(s.timestamp));if(this._categoryFilter!=="all"&&(e=e.filter(s=>this._getCategory(s)===this._categoryFilter)),e.length===0)return'<div class="empty-state">No notifications</div>';let t={};for(let s of e){let r=this._getTimeGroup(s.timestamp);t[r]||(t[r]=[]),t[r].push(s)}let i=["Today","Yesterday","This Week","Earlier","Other"],a="";for(let s of i)!t[s]||t[s].length===0||(a+=`<div class="time-group-label">${s}</div>`,a+=t[s].map(r=>{let o=r.acknowledged,n=this._getSeverityColor(r.severity),l=this._getCategory(r),c=dt[l]||{label:l,icon:"?"};return`
8910
+ `}_renderNotificationList(){let e=[...this._notifications].sort((s,r)=>new Date(r.timestamp)-new Date(s.timestamp));if(this._categoryFilter!=="all"&&(e=e.filter(s=>this._getCategory(s)===this._categoryFilter)),e.length===0)return'<div class="empty-state">No notifications</div>';let t={};for(let s of e){let r=this._getTimeGroup(s.timestamp);t[r]||(t[r]=[]),t[r].push(s)}let i=["Today","Yesterday","This Week","Earlier","Other"],a="";for(let s of i)!t[s]||t[s].length===0||(a+=`<div class="time-group-label">${s}</div>`,a+=t[s].map(r=>{let o=r.acknowledged,n=this._getSeverityColor(r.severity),l=this._getCategory(r),c=vt[l]||{label:l,icon:"?"};return`
8911
8911
  <div class="notif-row ${o?"acknowledged":""}">
8912
8912
  <span class="severity-dot" style="background: ${n};" title="${this._escapeHTML(r.severity)}"></span>
8913
8913
  <span class="cat-icon" title="${this._escapeHTML(c.label)}">${c.icon}</span>
@@ -9390,7 +9390,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
9390
9390
  `:""}
9391
9391
  `:""}
9392
9392
  </div>
9393
- `,this._bindEvents()}};customElements.get("loki-notification-center")||customElements.define("loki-notification-center",de);var ce=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data=null,this._error=null,this._loading=!0,this._api=null,this._pollInterval=null,this._expandedDecisions=new Set}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){let e=this._api;try{let t=await e._get("/api/session-diff");if(e!==this._api)return;this._data=t,this._error=null}catch(t){if(e!==this._api)return;this._error=t.message,this._data=null}this._loading=!1,this.render()}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_toggleDecision(e){this._expandedDecisions.has(e)?this._expandedDecisions.delete(e):this._expandedDecisions.add(e),this.render()}render(){let e=`
9393
+ `,this._bindEvents()}};customElements.get("loki-notification-center")||customElements.define("loki-notification-center",pe);var he=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data=null,this._error=null,this._loading=!0,this._api=null,this._pollInterval=null,this._expandedDecisions=new Set}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){let e=this._api;try{let t=await e._get("/api/session-diff");if(e!==this._api)return;this._data=t,this._error=null}catch(t){if(e!==this._api)return;this._error=t.message,this._data=null}this._loading=!1,this.render()}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_toggleDecision(e){this._expandedDecisions.has(e)?this._expandedDecisions.delete(e):this._expandedDecisions.add(e),this.render()}render(){let e=`
9394
9394
  ${this.getBaseStyles()}
9395
9395
 
9396
9396
  :host {
@@ -9656,7 +9656,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
9656
9656
  ${n}
9657
9657
  ${l}
9658
9658
  </div>
9659
- `,this.shadowRoot.querySelectorAll(".decision-header").forEach(c=>{c.addEventListener("click",()=>{this._toggleDecision(parseInt(c.dataset.index))})})}};customElements.get("loki-session-diff")||customElements.define("loki-session-diff",ce);var pe=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data=null,this._error=null,this._loading=!0,this._optimizing=!1,this._api=null,this._pollInterval=null,this._expandedChanges=new Set}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){let e=this._api;try{let t=await e._get("/api/prompt-versions");if(e!==this._api)return;this._data=t,this._error=null}catch(t){if(e!==this._api)return;this._error=t.message,this._data=null}this._loading=!1,this.render()}async _triggerOptimize(){if(this._optimizing)return;let e=this._api;this._optimizing=!0,this.render();try{if(await e._post("/api/prompt-optimize?dry_run=false",{}),e!==this._api)return;await this._loadData()}catch(t){if(e!==this._api)return;this._error=t.message}this._optimizing=!1,this.render()}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:6e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_formatTime(e){if(!e)return"--";try{let t=new Date(e),a=new Date-t,s=Math.floor(a/6e4);if(s<1)return"Just now";if(s<60)return`${s}m ago`;let r=Math.floor(s/60);return r<24?`${r}h ago`:`${Math.floor(r/24)}d ago`}catch{return"--"}}_toggleChange(e){this._expandedChanges.has(e)?this._expandedChanges.delete(e):this._expandedChanges.add(e),this.render()}render(){let e=`
9659
+ `,this.shadowRoot.querySelectorAll(".decision-header").forEach(c=>{c.addEventListener("click",()=>{this._toggleDecision(parseInt(c.dataset.index))})})}};customElements.get("loki-session-diff")||customElements.define("loki-session-diff",he);var ue=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data=null,this._error=null,this._loading=!0,this._optimizing=!1,this._api=null,this._pollInterval=null,this._expandedChanges=new Set}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){let e=this._api;try{let t=await e._get("/api/prompt-versions");if(e!==this._api)return;this._data=t,this._error=null}catch(t){if(e!==this._api)return;this._error=t.message,this._data=null}this._loading=!1,this.render()}async _triggerOptimize(){if(this._optimizing)return;let e=this._api;this._optimizing=!0,this.render();try{if(await e._post("/api/prompt-optimize?dry_run=false",{}),e!==this._api)return;await this._loadData()}catch(t){if(e!==this._api)return;this._error=t.message}this._optimizing=!1,this.render()}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:6e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_formatTime(e){if(!e)return"--";try{let t=new Date(e),a=new Date-t,s=Math.floor(a/6e4);if(s<1)return"Just now";if(s<60)return`${s}m ago`;let r=Math.floor(s/60);return r<24?`${r}h ago`:`${Math.floor(r/24)}d ago`}catch{return"--"}}_toggleChange(e){this._expandedChanges.has(e)?this._expandedChanges.delete(e):this._expandedChanges.add(e),this.render()}render(){let e=`
9660
9660
  ${this.getBaseStyles()}
9661
9661
 
9662
9662
  :host {
@@ -9907,7 +9907,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
9907
9907
 
9908
9908
  ${o}
9909
9909
  </div>
9910
- `;let n=this.shadowRoot.getElementById("optimize-btn");n&&n.addEventListener("click",()=>this._triggerOptimize()),this.shadowRoot.querySelectorAll(".change-header").forEach(l=>{l.addEventListener("click",()=>{this._toggleChange(parseInt(l.dataset.index))})})}};customElements.get("loki-prompt-optimizer")||customElements.define("loki-prompt-optimizer",pe);var he=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data=null,this._history=[],this._error=null,this._loading=!0,this._scanning=!1,this._rigourAvailable=!0,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){let e=this._api;try{let[t,i]=await Promise.allSettled([e._get("/api/quality-score"),e._get("/api/quality-score/history")]);if(e!==this._api)return;if(t.status==="fulfilled"){let a=t.value;a&&a.error&&a.error.includes("not installed")?(this._rigourAvailable=!1,this._data=null):a&&a.available===!1?(this._rigourAvailable=!1,this._data=null):a&&a.score==null?(this._rigourAvailable=!0,this._data=null):(this._rigourAvailable=!0,this._data=a),this._error=null}else(t.reason?.message||"").includes("404")?(this._rigourAvailable=!1,this._data=null,this._error=null):(this._error="Failed to load quality score",this._data=null);if(i.status==="fulfilled"){let a=i.value;this._history=Array.isArray(a)?a.slice(-10):(a.scores||[]).slice(-10)}}catch(t){if(e!==this._api)return;this._error=t.message,this._data=null}this._loading=!1,this.render()}async _triggerScan(){if(!this._scanning){this._scanning=!0,this.render();try{await this._api._post("/api/quality-scan",{},{timeout:3e5}),await this._loadData()}catch(e){this._error=e.message}this._scanning=!1,this.render()}}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:6e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getGrade(e){return e>=90?{grade:"A",color:"var(--loki-success)"}:e>=80?{grade:"B",color:"var(--loki-success)"}:e>=70?{grade:"C",color:"var(--loki-warning)"}:e>=60?{grade:"D",color:"var(--loki-warning)"}:{grade:"F",color:"var(--loki-error)"}}_renderSparkline(e){if(!e||e.length<2)return"";let t=e.map(c=>typeof c=="number"?c:c.score||0),i=Math.min(...t),s=Math.max(...t)-i||1,r=120,o=32,n=2,l=t.map((c,p)=>{let u=n+p/(t.length-1)*(r-n*2),m=n+(1-(c-i)/s)*(o-n*2);return`${u},${m}`}).join(" ");return`
9910
+ `;let n=this.shadowRoot.getElementById("optimize-btn");n&&n.addEventListener("click",()=>this._triggerOptimize()),this.shadowRoot.querySelectorAll(".change-header").forEach(l=>{l.addEventListener("click",()=>{this._toggleChange(parseInt(l.dataset.index))})})}};customElements.get("loki-prompt-optimizer")||customElements.define("loki-prompt-optimizer",ue);var ge=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._data=null,this._history=[],this._error=null,this._loading=!0,this._scanning=!1,this._rigourAvailable=!0,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){let e=this._api;try{let[t,i]=await Promise.allSettled([e._get("/api/quality-score"),e._get("/api/quality-score/history")]);if(e!==this._api)return;if(t.status==="fulfilled"){let a=t.value;a&&a.error&&a.error.includes("not installed")?(this._rigourAvailable=!1,this._data=null):a&&a.available===!1?(this._rigourAvailable=!1,this._data=null):a&&a.score==null?(this._rigourAvailable=!0,this._data=null):(this._rigourAvailable=!0,this._data=a),this._error=null}else(t.reason?.message||"").includes("404")?(this._rigourAvailable=!1,this._data=null,this._error=null):(this._error="Failed to load quality score",this._data=null);if(i.status==="fulfilled"){let a=i.value;this._history=Array.isArray(a)?a.slice(-10):(a.scores||[]).slice(-10)}}catch(t){if(e!==this._api)return;this._error=t.message,this._data=null}this._loading=!1,this.render()}async _triggerScan(){if(!this._scanning){this._scanning=!0,this.render();try{await this._api._post("/api/quality-scan",{},{timeout:3e5}),await this._loadData()}catch(e){this._error=e.message}this._scanning=!1,this.render()}}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:6e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getGrade(e){return e>=90?{grade:"A",color:"var(--loki-success)"}:e>=80?{grade:"B",color:"var(--loki-success)"}:e>=70?{grade:"C",color:"var(--loki-warning)"}:e>=60?{grade:"D",color:"var(--loki-warning)"}:{grade:"F",color:"var(--loki-error)"}}_renderSparkline(e){if(!e||e.length<2)return"";let t=e.map(c=>typeof c=="number"?c:c.score||0),i=Math.min(...t),s=Math.max(...t)-i||1,r=120,o=32,n=2,l=t.map((c,p)=>{let u=n+p/(t.length-1)*(r-n*2),m=n+(1-(c-i)/s)*(o-n*2);return`${u},${m}`}).join(" ");return`
9911
9911
  <svg width="${r}" height="${o}" viewBox="0 0 ${r} ${o}" class="sparkline">
9912
9912
  <polyline points="${l}" fill="none" stroke="var(--loki-accent)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
9913
9913
  <circle cx="${l.split(" ").pop().split(",")[0]}" cy="${l.split(" ").pop().split(",")[1]}" r="2.5" fill="var(--loki-accent)"/>
@@ -10341,12 +10341,12 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
10341
10341
  </div>
10342
10342
  `:""}
10343
10343
  </div>
10344
- `;let x=this.shadowRoot.getElementById("scan-btn");x&&x.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-score")||customElements.define("loki-quality-score",he);var ct=["understand","guardrail","migrate","verify"],pt={understand:"Understand",guardrail:"Guardrail",migrate:"Migrate",verify:"Verify"},Bt={understand:"#5b9bd5",guardrail:"#e8b84a",migrate:"#5bb870",verify:"#5bc8c8"},ue=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._migration=null,this._migrations=[],this._loading=!0,this._error=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._fetchMigrations(),this._poll=b({loadFn:()=>this._fetchData(),intervalMs:15e3,element:this,immediate:!1})}disconnectedCallback(){super.disconnectedCallback(),this._poll&&(this._poll.stop(),this._poll=null)}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._fetchMigrations()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _fetchMigrations(){let e=this._api;try{let t=await e._get("/api/migration/list");if(e!==this._api)return;this._migrations=Array.isArray(t)?t:t.migrations||[],this._error=null;let i=this._migrations.find(a=>a.status==="in_progress"||a.status==="active");if(i){if(await this._fetchStatus(i.migration_id||i.id),e!==this._api)return}else this._migration=null}catch(t){if(e!==this._api)return;this._error=t.message,this._migrations=[],this._migration=null}this._loading=!1,this.render()}async _fetchStatus(e){let t=this._api;try{let i=await t._get(`/api/migration/${encodeURIComponent(e)}/status`);if(t!==this._api)return;this._migration=i,this._error=null}catch(i){if(t!==this._api)return;this._error=i.message}}async _fetchData(){let e=this._api,t=this._migration&&(this._migration.migration_id||this._migration.id);if(t){if(await this._fetchStatus(t),e!==this._api)return;this.render()}else await this._fetchMigrations()}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;"):""}_getPhaseIcon(e,t,i){return(i||[]).includes(e)?"[x]":e===t?"[>]":"[ ]"}_getPhaseIndex(e){let t=ct.indexOf(e);return t>=0?t:0}_renderPhaseBar(e,t){let i=t||[];return ct.map(a=>{let s=i.includes(a),r=a===e,o=Bt[a],n=s?"1":r?"0.7":"0.2",l=this._getPhaseIcon(a,e,t);return`
10344
+ `;let x=this.shadowRoot.getElementById("scan-btn");x&&x.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-score")||customElements.define("loki-quality-score",ge);var ft=["understand","guardrail","migrate","verify"],bt={understand:"Understand",guardrail:"Guardrail",migrate:"Migrate",verify:"Verify"},Kt={understand:"#5b9bd5",guardrail:"#e8b84a",migrate:"#5bb870",verify:"#5bc8c8"},me=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._migration=null,this._migrations=[],this._loading=!0,this._error=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._fetchMigrations(),this._poll=b({loadFn:()=>this._fetchData(),intervalMs:15e3,element:this,immediate:!1})}disconnectedCallback(){super.disconnectedCallback(),this._poll&&(this._poll.stop(),this._poll=null)}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._fetchMigrations()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _fetchMigrations(){let e=this._api;try{let t=await e._get("/api/migration/list");if(e!==this._api)return;this._migrations=Array.isArray(t)?t:t.migrations||[],this._error=null;let i=this._migrations.find(a=>a.status==="in_progress"||a.status==="active");if(i){if(await this._fetchStatus(i.migration_id||i.id),e!==this._api)return}else this._migration=null}catch(t){if(e!==this._api)return;this._error=t.message,this._migrations=[],this._migration=null}this._loading=!1,this.render()}async _fetchStatus(e){let t=this._api;try{let i=await t._get(`/api/migration/${encodeURIComponent(e)}/status`);if(t!==this._api)return;this._migration=i,this._error=null}catch(i){if(t!==this._api)return;this._error=i.message}}async _fetchData(){let e=this._api,t=this._migration&&(this._migration.migration_id||this._migration.id);if(t){if(await this._fetchStatus(t),e!==this._api)return;this.render()}else await this._fetchMigrations()}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;"):""}_getPhaseIcon(e,t,i){return(i||[]).includes(e)?"[x]":e===t?"[>]":"[ ]"}_getPhaseIndex(e){let t=ft.indexOf(e);return t>=0?t:0}_renderPhaseBar(e,t){let i=t||[];return ft.map(a=>{let s=i.includes(a),r=a===e,o=Kt[a],n=s?"1":r?"0.7":"0.2",l=this._getPhaseIcon(a,e,t);return`
10345
10345
  <div class="phase-segment">
10346
10346
  <div class="phase-bar-fill" style="background:${o};opacity:${n};"></div>
10347
10347
  <div class="phase-label">
10348
10348
  <span class="phase-icon">${l}</span>
10349
- ${pt[a]}
10349
+ ${bt[a]}
10350
10350
  </div>
10351
10351
  </div>
10352
10352
  `}).join("")}_renderFeatureStats(e){if(!e)return"";let t=e.passing||0,i=e.total||0,a=i>0?Math.round(t/i*100):0,s=a>=80?"var(--loki-success)":a>=50?"var(--loki-warning)":"var(--loki-error)";return`
@@ -10737,7 +10737,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
10737
10737
  </div>
10738
10738
  <div class="meta-item">
10739
10739
  <span class="meta-label">Phase</span>
10740
- <span>${pt[o]||this._escapeHtml(o)}</span>
10740
+ <span>${bt[o]||this._escapeHtml(o)}</span>
10741
10741
  </div>
10742
10742
  </div>
10743
10743
 
@@ -10764,7 +10764,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
10764
10764
  <div class="section-label">Migrations</div>
10765
10765
  ${this._renderMigrationList()}
10766
10766
  </div>
10767
- `}};customElements.get("loki-migration-dashboard")||customElements.define("loki-migration-dashboard",ue);var It=[["claude-opus","claude"],["claude-sonnet","claude"],["claude-haiku","claude"],["opus","claude"],["sonnet","claude"],["haiku","claude"],["claude","claude"],["gpt-4","codex"],["gpt-5","codex"],["gpt","codex"],["codex","codex"],["o1","codex"],["o3","codex"],["cline","cline"],["aider","aider"]];function Ft(d){if(d==null)return null;switch(d%4){case 0:return{tier:"planning",model:"opus",provider:"claude"};case 1:return{tier:"development",model:"sonnet",provider:"claude"};case 2:return{tier:"development",model:"sonnet",provider:"claude"};case 3:return{tier:"fast",model:"haiku",provider:"claude"};default:return{tier:"development",model:"sonnet",provider:"claude"}}}function jt(d,e){if(e!=null){let i=Ft(e);if(i)return i.provider}let t=(d||"").toLowerCase();for(let[i,a]of It)if(t.includes(i))return a;return"unknown"}var ge=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._api=null,this._pollInterval=null,this._activeTab="heatmap",this._activity=[],this._tools=[],this._cost={},this._context={},this._trends=[],this._toolTimeRange="7d",this._connected=!1,this._loading=!1,this._loadedOnce=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _fetchActivity(e=this._api){let t=e.baseUrl||window.location.origin,i=new AbortController,a=setTimeout(()=>i.abort(),1e4);try{let s=await fetch(`${t}/api/activity?limit=1000`,{signal:i.signal});if(clearTimeout(a),!s.ok)throw new Error(`Activity API ${s.status}`);return s.json()}catch(s){throw clearTimeout(a),s}}async _loadData(){if(!this.isConnected||this._loading)return;let e=this._api;this._loading=!0;try{let t=await Promise.allSettled([this._fetchActivity(e),e.getToolEfficiency(50),e.getCost(),e.getContext(),e.getLearningTrends({timeRange:this._toolTimeRange})]);if(e!==this._api)return;if(t[0].status==="fulfilled"&&(this._activity=t[0].value||[]),t[1].status==="fulfilled"&&(this._tools=t[1].value||[]),t[2].status==="fulfilled"&&(this._cost=t[2].value||{}),t[3].status==="fulfilled"&&(this._context=t[3].value||{}),t[4].status==="fulfilled"){let i=t[4].value||{};this._trends=Array.isArray(i)?i:i.dataPoints||[]}this._connected=t.some(i=>i.status==="fulfilled"),this._loadedOnce=!0,this.render()}finally{this._loading=!1}}_hasAnyData(){let e=Array.isArray(this._activity)?this._activity.length:0,t=Array.isArray(this._tools)?this._tools.length:0,i=this._cost&&this._cost.by_model?Object.keys(this._cost.by_model).length:0,a=this._context||{},r=(a.totals||{}).iterations_tracked||a.total_iterations||a.iteration||0;return e>0||t>0||i>0||r>0}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_computeHeatmap(){let e={},t=Array.isArray(this._activity)?this._activity:[];for(let c of t){let p=c.timestamp||c.ts||c.created_at;if(!p)continue;let u=new Date(p);if(isNaN(u.getTime()))continue;let m=this._localDateKey(u);e[m]=(e[m]||0)+1}let i=new Date;i.setHours(0,0,0,0);let a=i.getDay(),s=new Date(i),r=new Date(i);r.setDate(r.getDate()-(52*7+a));let o=[],n=new Date(r),l=0;for(;n<=s;){let c=this._localDateKey(n),p=e[c]||0;p>l&&(l=p),o.push({date:c,count:p,day:n.getDay()}),n.setDate(n.getDate()+1)}return{cells:o,maxCount:l}}_getHeatmapLevel(e,t){if(e===0||t===0)return 0;let i=e/t;return i<=.25?1:i<=.5?2:i<=.75?3:4}_renderHeatmap(){let{cells:e,maxCount:t}=this._computeHeatmap(),i=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],a=["","Mon","","Wed","","Fri",""],s=[],r=-1,o=-1;for(let p=0;p<e.length;p++){e[p].day===0&&o++;let u=new Date(e[p].date).getMonth();u!==r&&(s.push({month:i[u],col:Math.max(o,1)}),r=u)}let n=s.map(p=>`<span class="heatmap-month" style="grid-column: ${p.col}">${p.month}</span>`).join(""),l=e.map(p=>`<div class="heatmap-cell level-${this._getHeatmapLevel(p.count,t)}" title="${p.date}: ${p.count} activities"></div>`).join(""),c=a.map(p=>`<span class="heatmap-day-label">${p}</span>`).join("");return`
10767
+ `}};customElements.get("loki-migration-dashboard")||customElements.define("loki-migration-dashboard",me);var Vt=[["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 Yt(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 Wt(d,e){if(e!=null){let i=Yt(e);if(i)return i.provider}let t=(d||"").toLowerCase();for(let[i,a]of Vt)if(t.includes(i))return a;return"unknown"}var ve=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._api=null,this._pollInterval=null,this._activeTab="heatmap",this._activity=[],this._tools=[],this._cost={},this._context={},this._trends=[],this._toolTimeRange="7d",this._connected=!1,this._loading=!1,this._loadedOnce=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _fetchActivity(e=this._api){let t=e.baseUrl||window.location.origin,i=new AbortController,a=setTimeout(()=>i.abort(),1e4);try{let s=await fetch(`${t}/api/activity?limit=1000`,{signal:i.signal});if(clearTimeout(a),!s.ok)throw new Error(`Activity API ${s.status}`);return s.json()}catch(s){throw clearTimeout(a),s}}async _loadData(){if(!this.isConnected||this._loading)return;let e=this._api;this._loading=!0;try{let t=await Promise.allSettled([this._fetchActivity(e),e.getToolEfficiency(50),e.getCost(),e.getContext(),e.getLearningTrends({timeRange:this._toolTimeRange})]);if(e!==this._api)return;if(t[0].status==="fulfilled"&&(this._activity=t[0].value||[]),t[1].status==="fulfilled"&&(this._tools=t[1].value||[]),t[2].status==="fulfilled"&&(this._cost=t[2].value||{}),t[3].status==="fulfilled"&&(this._context=t[3].value||{}),t[4].status==="fulfilled"){let i=t[4].value||{};this._trends=Array.isArray(i)?i:i.dataPoints||[]}this._connected=t.some(i=>i.status==="fulfilled"),this._loadedOnce=!0,this.render()}finally{this._loading=!1}}_hasAnyData(){let e=Array.isArray(this._activity)?this._activity.length:0,t=Array.isArray(this._tools)?this._tools.length:0,i=this._cost&&this._cost.by_model?Object.keys(this._cost.by_model).length:0,a=this._context||{},r=(a.totals||{}).iterations_tracked||a.total_iterations||a.iteration||0;return e>0||t>0||i>0||r>0}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}_computeHeatmap(){let e={},t=Array.isArray(this._activity)?this._activity:[];for(let c of t){let p=c.timestamp||c.ts||c.created_at;if(!p)continue;let u=new Date(p);if(isNaN(u.getTime()))continue;let m=this._localDateKey(u);e[m]=(e[m]||0)+1}let i=new Date;i.setHours(0,0,0,0);let a=i.getDay(),s=new Date(i),r=new Date(i);r.setDate(r.getDate()-(52*7+a));let o=[],n=new Date(r),l=0;for(;n<=s;){let c=this._localDateKey(n),p=e[c]||0;p>l&&(l=p),o.push({date:c,count:p,day:n.getDay()}),n.setDate(n.getDate()+1)}return{cells:o,maxCount:l}}_getHeatmapLevel(e,t){if(e===0||t===0)return 0;let i=e/t;return i<=.25?1:i<=.5?2:i<=.75?3:4}_renderHeatmap(){let{cells:e,maxCount:t}=this._computeHeatmap(),i=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],a=["","Mon","","Wed","","Fri",""],s=[],r=-1,o=-1;for(let p=0;p<e.length;p++){e[p].day===0&&o++;let u=new Date(e[p].date).getMonth();u!==r&&(s.push({month:i[u],col:Math.max(o,1)}),r=u)}let n=s.map(p=>`<span class="heatmap-month" style="grid-column: ${p.col}">${p.month}</span>`).join(""),l=e.map(p=>`<div class="heatmap-cell level-${this._getHeatmapLevel(p.count,t)}" title="${p.date}: ${p.count} activities"></div>`).join(""),c=a.map(p=>`<span class="heatmap-day-label">${p}</span>`).join("");return`
10768
10768
  <div class="heatmap-container">
10769
10769
  <div class="heatmap-months">${n}</div>
10770
10770
  <div class="heatmap-body">
@@ -10814,7 +10814,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
10814
10814
  <div class="sparkline-label">Activity Trend (hourly)</div>
10815
10815
  <div class="sparkline">${s}</div>
10816
10816
  </div>
10817
- `}_computeProviders(){let e=this._cost.by_model||{},t={};for(let[r,o]of Object.entries(e)){let n=jt(r);t[n]||(t[n]={cost:0,tokens:0,iterations:0,models:[]});let l=o.cost_usd||0,c=(o.input_tokens||0)+(o.output_tokens||0);t[n].cost+=l,t[n].tokens+=c,t[n].models.push(r)}let a=(this._context.totals||{}).iterations_tracked||this._context.total_iterations||this._context.iteration||0,s=this._cost.estimated_cost_usd||0;for(let r of Object.values(t))if(s>0&&a>0){let o=r.cost/s;r.iterations=Math.round(o*a)}return t}_renderProviders(){let e=this._computeProviders(),t={claude:{label:"Claude",color:"var(--loki-accent)"},codex:{label:"Codex",color:"var(--loki-success)"},cline:{label:"Cline",color:"var(--loki-info)"},aider:{label:"Aider",color:"var(--loki-blue)"},unknown:{label:"Other",color:"var(--loki-text-muted)"}},i=Object.entries(e);return i.length===0?'<div class="empty-state">No provider activity yet. Start a build to compare providers side by side.</div>':`
10817
+ `}_computeProviders(){let e=this._cost.by_model||{},t={};for(let[r,o]of Object.entries(e)){let n=Wt(r);t[n]||(t[n]={cost:0,tokens:0,iterations:0,models:[]});let l=o.cost_usd||0,c=(o.input_tokens||0)+(o.output_tokens||0);t[n].cost+=l,t[n].tokens+=c,t[n].models.push(r)}let a=(this._context.totals||{}).iterations_tracked||this._context.total_iterations||this._context.iteration||0,s=this._cost.estimated_cost_usd||0;for(let r of Object.values(t))if(s>0&&a>0){let o=r.cost/s;r.iterations=Math.round(o*a)}return t}_renderProviders(){let e=this._computeProviders(),t={claude:{label:"Claude",color:"var(--loki-accent)"},codex:{label:"Codex",color:"var(--loki-success)"},cline:{label:"Cline",color:"var(--loki-info)"},aider:{label:"Aider",color:"var(--loki-blue)"},unknown:{label:"Other",color:"var(--loki-text-muted)"}},i=Object.entries(e);return i.length===0?'<div class="empty-state">No provider activity yet. Start a build to compare providers side by side.</div>':`
10818
10818
  <div class="provider-grid">
10819
10819
  ${i.map(([a,s])=>{let r=t[a]||t.unknown,o=s.iterations>0?(s.cost/s.iterations).toFixed(4):"--",n=s.iterations>0?Math.round(s.tokens/s.iterations).toLocaleString():"--";return`
10820
10820
  <div class="provider-card">
@@ -11317,7 +11317,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
11317
11317
  </div>
11318
11318
  `}
11319
11319
  </div>
11320
- `,this.shadowRoot.querySelectorAll("[data-tab]").forEach(l=>{l.addEventListener("click",c=>this._handleTabClick(c))});let r=this.shadowRoot.getElementById("tool-time-range");r&&r.addEventListener("change",l=>this._handleTimeRangeChange(l));let o=this.shadowRoot.getElementById("analytics-retry-btn");o&&o.addEventListener("click",()=>this._loadData());let n=this.shadowRoot.getElementById("analytics-overview-btn");n&&n.addEventListener("click",()=>this._navigateToOverview())}_navigateToOverview(){this.dispatchEvent(new CustomEvent("loki-navigate",{detail:{view:"overview"},bubbles:!0,composed:!0}))}};customElements.get("loki-analytics")||customElements.define("loki-analytics",ge);var ht={pass:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"PASS"},fail:{color:"var(--loki-red, #ef4444)",bg:"var(--loki-red-muted, rgba(239, 68, 68, 0.15))",label:"FAIL"},pending:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"PENDING"}};function Ut(d){if(!d)return"Never";try{return new Date(d).toLocaleString([],{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return"Unknown"}}function Ot(d){if(!d||d.length===0)return{pass:0,fail:0,pending:0,total:0};let e={pass:0,fail:0,pending:0,total:d.length};for(let t of d){let i=(t.status||"pending").toLowerCase();i==="pass"?e.pass++:i==="fail"?e.fail++:e.pending++}return e}var me=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._gates=[],this._evidence={blocked:!1},this._pollInterval=null,this._lastDataHash=null,this._scanning=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{this._loading=!0;let t=await e._get("/api/council/gate");if(e!==this._api)return;let i=t?.gates||t||[],a=t?.evidence||{blocked:!1},s=JSON.stringify({gates:i,evidence:a});if(s===this._lastDataHash)return;this._lastDataHash=s,this._gates=Array.isArray(i)?i:[],this._evidence=a,this._error=null}catch(t){if(e!==this._api)return;this._error||(this._error=`Failed to load quality gates: ${t.message}`)}finally{this._loading=!1}this.render()}async _triggerScan(){if(this._scanning)return;let e=this._api;this._scanning=!0,this.render();try{if(await e._post("/api/quality-scan",{},{timeout:3e5}),e!==this._api)return;this._lastDataHash=null,await this._loadData()}catch(t){if(e!==this._api)return;this._error=`Quality scan failed: ${t.message}`}finally{this._scanning=!1,this.render()}}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
11320
+ `,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",ve);var kt={pass:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"PASS"},fail:{color:"var(--loki-red, #ef4444)",bg:"var(--loki-red-muted, rgba(239, 68, 68, 0.15))",label:"FAIL"},pending:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"PENDING"}};function Qt(d){if(!d)return"Never";try{return new Date(d).toLocaleString([],{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return"Unknown"}}function Xt(d){if(!d||d.length===0)return{pass:0,fail:0,pending:0,total:0};let e={pass:0,fail:0,pending:0,total:d.length};for(let t of d){let i=(t.status||"pending").toLowerCase();i==="pass"?e.pass++:i==="fail"?e.fail++:e.pending++}return e}var fe=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._gates=[],this._evidence={blocked:!1},this._pollInterval=null,this._lastDataHash=null,this._scanning=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{this._loading=!0;let t=await e._get("/api/council/gate");if(e!==this._api)return;let i=t?.gates||t||[],a=t?.evidence||{blocked:!1},s=JSON.stringify({gates:i,evidence:a});if(s===this._lastDataHash)return;this._lastDataHash=s,this._gates=Array.isArray(i)?i:[],this._evidence=a,this._error=null}catch(t){if(e!==this._api)return;this._error||(this._error=`Failed to load quality gates: ${t.message}`)}finally{this._loading=!1}this.render()}async _triggerScan(){if(this._scanning)return;let e=this._api;this._scanning=!0,this.render();try{if(await e._post("/api/quality-scan",{},{timeout:3e5}),e!==this._api)return;this._lastDataHash=null,await this._loadData()}catch(t){if(e!==this._api)return;this._error=`Quality scan failed: ${t.message}`}finally{this._scanning=!1,this.render()}}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
11321
11321
  :host {
11322
11322
  display: block;
11323
11323
  }
@@ -11577,7 +11577,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
11577
11577
  color: var(--loki-text-muted, #939084);
11578
11578
  font-size: 13px;
11579
11579
  }
11580
- `}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?s=`
11580
+ `}render(){let e=this.shadowRoot;if(!e)return;let t=this._gates,i=Xt(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?s=`
11581
11581
  <div class="es">
11582
11582
  <div class="es-icon">${a}</div>
11583
11583
  <div class="es-title">No gate results yet</div>
@@ -11585,14 +11585,14 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
11585
11585
  <button class="es-cta" id="gates-scan-btn" ${this._scanning?"disabled":""}>
11586
11586
  ${this._scanning?'<span class="es-spinner"></span> Scanning...':"Run quality scan"}
11587
11587
  </button>
11588
- </div>`:s=`<div class="gates-grid">${t.map(p=>{let u=(p.status||"pending").toLowerCase(),m=ht[u]||ht.pending;return`
11588
+ </div>`:s=`<div class="gates-grid">${t.map(p=>{let u=(p.status||"pending").toLowerCase(),m=kt[u]||kt.pending;return`
11589
11589
  <div class="gate-card status-${u}">
11590
11590
  <div class="gate-header">
11591
11591
  <span class="gate-name">${this._escapeHtml(p.name||"Unnamed Gate")}</span>
11592
11592
  <span class="gate-badge" style="background: ${m.bg}; color: ${m.color};">${m.label}</span>
11593
11593
  </div>
11594
11594
  ${p.description?`<div class="gate-description">${this._escapeHtml(p.description)}</div>`:""}
11595
- <div class="gate-meta">Last checked: ${Ut(p.last_checked||p.lastChecked)}</div>
11595
+ <div class="gate-meta">Last checked: ${Qt(p.last_checked||p.lastChecked)}</div>
11596
11596
  </div>
11597
11597
  `}).join("")}</div>`;let r="",o=this._evidence||{};if(o.blocked){let c={empty_diff:"No changes were shipped (empty diff vs run start).",tests_red:"Tests ran and were red.",empty_diff_and_tests_red:"No changes shipped and tests were red.",no_evidence_of_completion:"No evidence of completion."},p=o.error?this._escapeHtml(o.error):c[o.reason]||this._escapeHtml(o.reason||"Completion blocked."),u=Array.isArray(o.failures)?o.failures:[],m=u.length?`<ul class="evidence-failures">${u.map(g=>`<li>${this._escapeHtml(g)}</li>`).join("")}</ul>`:"";r=`
11598
11598
  <div class="evidence-banner">
@@ -11627,7 +11627,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
11627
11627
  ${s}
11628
11628
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
11629
11629
  </div>
11630
- `;let l=e.getElementById("gates-scan-btn");l&&l.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-gates")||customElements.define("loki-quality-gates",me);var q={reason:{color:"var(--loki-blue, #3b82f6)",label:"Reason",description:"Analyzing requirements and planning approach"},act:{color:"var(--loki-green, #22c55e)",label:"Act",description:"Implementing changes and executing tasks"},reflect:{color:"var(--loki-purple, #a78bfa)",label:"Reflect",description:"Reviewing results and evaluating quality"},verify:{color:"var(--loki-yellow, #eab308)",label:"Verify",description:"Running tests and validating correctness"}},Ve=["reason","act","reflect","verify"];function qe(d){if(d==null||d<0)return"--";if(d<1e3)return`${d}ms`;let e=Math.floor(d/1e3);if(e<60)return`${e}s`;let t=Math.floor(e/60),i=e%60;if(t<60)return`${t}m ${i}s`;let a=Math.floor(t/60),s=t%60;return`${a}h ${s}m`}function Nt(d){if(!d||d.length===0)return[];let e=d.reduce((t,i)=>t+(i.duration_ms||0),0);return e===0?d.map(t=>({phase:t.phase,pct:100/d.length,duration:0})):d.map(t=>({phase:t.phase,pct:(t.duration_ms||0)/e*100,duration:t.duration_ms||0}))}function qt(d){return d==null?"--":d>=1e6?(d/1e6).toFixed(1)+"M":d>=1e3?(d/1e3).toFixed(1)+"K":String(d)}var ve=class extends v{static get observedAttributes(){return["run-id","api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._timeline=null,this._pollInterval=null,this._selectedPhase=null,this._cycleHistory=[]}get runId(){let e=this.getAttribute("run-id");return e?parseInt(e,10):null}set runId(e){e!=null?this.setAttribute("run-id",String(e)):this.removeAttribute("run-id")}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="run-id"&&this._loadData(),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this.runId;if(e==null){this._timeline=null,this.render();return}let t=this._api;try{this._loading=!0;let i=await t._get(`/api/v2/runs/${e}/timeline`);if(t!==this._api)return;this._timeline=i,this._cycleHistory=i.history||[],this._error=null}catch(i){if(t!==this._api)return;i.message&&(i.message.includes("404")||i.message.includes("Not Found"))?(this._timeline=null,this._error=null):this._error=`Failed to load timeline: ${i.message}`}finally{this._loading=!1}this.render()}_selectPhase(e){this._selectedPhase=this._selectedPhase===e?null:e,this.render()}_bindEvents(){let e=this.shadowRoot;e.querySelectorAll(".phase-segment-interactive").forEach(t=>{t.addEventListener("click",()=>{this._selectPhase(t.dataset.phase)})}),e.querySelectorAll(".legend-item-interactive").forEach(t=>{t.addEventListener("click",()=>{this._selectPhase(t.dataset.phase)})}),e.querySelectorAll(".close-detail").forEach(t=>{t.addEventListener("click",i=>{i.stopPropagation(),this._selectedPhase=null,this.render()})})}_getStyles(){return`
11630
+ `;let l=e.getElementById("gates-scan-btn");l&&l.addEventListener("click",()=>this._triggerScan())}};customElements.get("loki-quality-gates")||customElements.define("loki-quality-gates",fe);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"}},Xe=["reason","act","reflect","verify"];function Ve(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 Zt(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 ei(d){return d==null?"--":d>=1e6?(d/1e6).toFixed(1)+"M":d>=1e3?(d/1e3).toFixed(1)+"K":String(d)}var be=class extends v{static get observedAttributes(){return["run-id","api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._timeline=null,this._pollInterval=null,this._selectedPhase=null,this._cycleHistory=[]}get runId(){let e=this.getAttribute("run-id");return e?parseInt(e,10):null}set runId(e){e!=null?this.setAttribute("run-id",String(e)):this.removeAttribute("run-id")}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="run-id"&&this._loadData(),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this.runId;if(e==null){this._timeline=null,this.render();return}let t=this._api;try{this._loading=!0;let i=await t._get(`/api/v2/runs/${e}/timeline`);if(t!==this._api)return;this._timeline=i,this._cycleHistory=i.history||[],this._error=null}catch(i){if(t!==this._api)return;i.message&&(i.message.includes("404")||i.message.includes("Not Found"))?(this._timeline=null,this._error=null):this._error=`Failed to load timeline: ${i.message}`}finally{this._loading=!1}this.render()}_selectPhase(e){this._selectedPhase=this._selectedPhase===e?null:e,this.render()}_bindEvents(){let e=this.shadowRoot;e.querySelectorAll(".phase-segment-interactive").forEach(t=>{t.addEventListener("click",()=>{this._selectPhase(t.dataset.phase)})}),e.querySelectorAll(".legend-item-interactive").forEach(t=>{t.addEventListener("click",()=>{this._selectPhase(t.dataset.phase)})}),e.querySelectorAll(".close-detail").forEach(t=>{t.addEventListener("click",i=>{i.stopPropagation(),this._selectedPhase=null,this.render()})})}_getStyles(){return`
11631
11631
  :host {
11632
11632
  display: block;
11633
11633
  }
@@ -11912,12 +11912,12 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
11912
11912
  color: var(--loki-text-muted, #939084);
11913
11913
  font-size: 13px;
11914
11914
  }
11915
- `}_renderPlaceholderTimeline(){let e=Ve.map(i=>{let a=q[i];return`<div class="phase-segment-interactive"
11915
+ `}_renderPlaceholderTimeline(){let e=Xe.map(i=>{let a=G[i];return`<div class="phase-segment-interactive"
11916
11916
  data-phase="${i}"
11917
11917
  style="width: 25%; background: ${a.color}; opacity: 0.3;"
11918
11918
  title="${a.label}: awaiting data">
11919
11919
  ${a.label}
11920
- </div>`}).join(""),t=Ve.map(i=>{let a=q[i];return`<div class="legend-item-interactive" data-phase="${i}">
11920
+ </div>`}).join(""),t=Xe.map(i=>{let a=G[i];return`<div class="legend-item-interactive" data-phase="${i}">
11921
11921
  <span class="legend-dot" style="background: ${a.color}; opacity: 0.4;"></span>
11922
11922
  <span class="legend-label">${a.label}</span>
11923
11923
  <span class="legend-duration">--</span>
@@ -11929,7 +11929,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
11929
11929
  Each step fills in as your build progresses
11930
11930
  </div>
11931
11931
  </div>
11932
- `}_renderPhaseDetail(e){let t=q[e];if(!t)return"";let a=(this._timeline?.phases||[]).find(s=>s.phase===e);return`
11932
+ `}_renderPhaseDetail(e){let t=G[e];if(!t)return"";let a=(this._timeline?.phases||[]).find(s=>s.phase===e);return`
11933
11933
  <div class="phase-detail">
11934
11934
  <div class="detail-header">
11935
11935
  <div class="detail-title">
@@ -11942,11 +11942,11 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
11942
11942
  <div class="detail-metrics">
11943
11943
  <div class="detail-metric">
11944
11944
  <span class="detail-metric-label">Time Spent</span>
11945
- <span class="detail-metric-value">${qe(a?.duration_ms)}</span>
11945
+ <span class="detail-metric-value">${Ve(a?.duration_ms)}</span>
11946
11946
  </div>
11947
11947
  <div class="detail-metric">
11948
11948
  <span class="detail-metric-label">Tokens Used</span>
11949
- <span class="detail-metric-value">${qt(a?.tokens_used)}</span>
11949
+ <span class="detail-metric-value">${ei(a?.tokens_used)}</span>
11950
11950
  </div>
11951
11951
  <div class="detail-metric">
11952
11952
  <span class="detail-metric-label">Quality</span>
@@ -11958,21 +11958,21 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
11958
11958
  </div>
11959
11959
  </div>
11960
11960
  </div>
11961
- `}_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=q[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};"
11962
- title="Cycle ${a+1}: ${n.label} - ${qe(o?.duration_ms)}"></div>`}).join("")}</div>`).join('<div class="history-separator"></div>');return`
11961
+ `}_renderCycleHistory(){if(this._cycleHistory.length===0)return"";let t=this._cycleHistory.slice(-8).map((i,a)=>`<div class="history-cycle">${Xe.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};"
11962
+ title="Cycle ${a+1}: ${n.label} - ${Ve(o?.duration_ms)}"></div>`}).join("")}</div>`).join('<div class="history-separator"></div>');return`
11963
11963
  <div class="cycle-history">
11964
11964
  <div class="history-label">Past Cycles (${this._cycleHistory.length} total)</div>
11965
11965
  <div class="history-cycles">${t}</div>
11966
11966
  </div>
11967
- `}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}render(){let e=this.shadowRoot;if(!e)return;let t=this.runId,i=this._timeline,a=i?.phases||[],s=i?.current_phase||null,r=Nt(a),o;if(this._loading&&!i)o='<div class="loading">Loading timeline...</div>';else if(t==null)o=this._renderPlaceholderTimeline();else if(a.length===0)o=this._renderPlaceholderTimeline();else{let n=r.map(u=>{let m=q[u.phase]||{color:"var(--loki-text-muted)",label:u.phase},g=s===u.phase,x=this._selectedPhase===u.phase;return`<div class="phase-segment-interactive ${g?"current":""} ${x?"selected":""}"
11967
+ `}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}render(){let e=this.shadowRoot;if(!e)return;let t=this.runId,i=this._timeline,a=i?.phases||[],s=i?.current_phase||null,r=Zt(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},g=s===u.phase,x=this._selectedPhase===u.phase;return`<div class="phase-segment-interactive ${g?"current":""} ${x?"selected":""}"
11968
11968
  data-phase="${u.phase}"
11969
11969
  style="width: ${Math.max(u.pct,2)}%; background: ${m.color};"
11970
- title="${m.label}: ${qe(u.duration)}">
11970
+ title="${m.label}: ${Ve(u.duration)}">
11971
11971
  ${u.pct>12?m.label:""}
11972
- </div>`}).join(""),l=a.map(u=>{let m=q[u.phase]||{color:"var(--loki-text-muted)",label:u.phase},g=s===u.phase;return`<div class="legend-item-interactive ${this._selectedPhase===u.phase?"selected":""}" data-phase="${u.phase}">
11972
+ </div>`}).join(""),l=a.map(u=>{let m=G[u.phase]||{color:"var(--loki-text-muted)",label:u.phase},g=s===u.phase;return`<div class="legend-item-interactive ${this._selectedPhase===u.phase?"selected":""}" data-phase="${u.phase}">
11973
11973
  <span class="legend-dot" style="background: ${m.color}"></span>
11974
11974
  <span class="legend-label">${m.label}</span>
11975
- <span class="legend-duration">${qe(u.duration_ms)}</span>
11975
+ <span class="legend-duration">${Ve(u.duration_ms)}</span>
11976
11976
  ${g?'<span class="phase-current-tag">ACTIVE</span>':""}
11977
11977
  </div>`}).join(""),c=this._selectedPhase?this._renderPhaseDetail(this._selectedPhase):"",p=this._renderCycleHistory();o=`
11978
11978
  <div class="timeline-bar">${n}</div>
@@ -11989,7 +11989,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
11989
11989
  ${o}
11990
11990
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
11991
11991
  </div>
11992
- `,this._bindEvents()}};customElements.get("loki-rarv-timeline")||customElements.define("loki-rarv-timeline",ve);var ut={running:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"Running"},completed:{color:"var(--loki-blue, #3b82f6)",bg:"var(--loki-blue-muted, rgba(59, 130, 246, 0.15))",label:"Completed"},failed:{color:"var(--loki-red, #ef4444)",bg:"var(--loki-red-muted, rgba(239, 68, 68, 0.15))",label:"Failed"},cancelled:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"Cancelled"},pending:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Pending"},queued:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Queued"}};function Jt(d,e,t){let i=d;if(i==null&&e){let l=new Date(e).getTime();i=(t?new Date(t).getTime():Date.now())-l}if(i==null||i<0)return"--";if(i<1e3)return`${i}ms`;let a=Math.floor(i/1e3);if(a<60)return`${a}s`;let s=Math.floor(a/60),r=a%60;if(s<60)return`${s}m ${r}s`;let o=Math.floor(s/60),n=s%60;return`${o}h ${n}m`}function Gt(d){if(!d)return"--";try{return new Date(d).toLocaleString([],{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return String(d)}}var fe=class extends v{static get observedAttributes(){return["api-url","project-id","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._runs=[],this._pollInterval=null,this._lastDataHash=null}get projectId(){let e=this.getAttribute("project-id");return e?parseInt(e,10):null}set projectId(e){e!=null?this.setAttribute("project-id",String(e)):this.removeAttribute("project-id")}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="project-id"&&this._loadData(),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=this.projectId,i=t!=null?`?project_id=${t}`:"",a=await e._get(`/api/v2/runs${i}`);if(e!==this._api)return;let s=a?.runs||a||[],r=JSON.stringify(s);if(r===this._lastDataHash)return;this._lastDataHash=r,this._runs=Array.isArray(s)?s:[],this._error=null}catch(t){if(e!==this._api)return;this._error||(this._error=`Failed to load runs: ${t.message}`)}finally{this._loading=!1}this.render()}async _cancelRun(e){try{await this._api._post(`/api/v2/runs/${e}/cancel`),await this._loadData()}catch(t){this._error=`Cancel failed: ${t.message}`,this.render()}}async _replayRun(e){try{await this._api._post(`/api/v2/runs/${e}/replay`),await this._loadData()}catch(t){this._error=`Replay failed: ${t.message}`,this.render()}}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
11992
+ `,this._bindEvents()}};customElements.get("loki-rarv-timeline")||customElements.define("loki-rarv-timeline",be);function xt(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 _t(d){if(!Array.isArray(d))return null;let e=null;for(let t of d){let i=xt(t);i!==null&&(e===null||i<e)&&(e=i)}return e}function yt(d={}){let{payload:e=null,receivedAtMs:t=null,nowMs:i=Date.now(),staleAfterS:a=120}=d,s=xt(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 ti(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 Ze(d){if(!d||!d.known)return"Data age unknown";let e=d.source==="client"?" (receive time)":"",t=d.isStale?" - STALE":"";return`Updated ${ti(d)}${e}${t}`}var wt={running:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"Running"},completed:{color:"var(--loki-blue, #3b82f6)",bg:"var(--loki-blue-muted, rgba(59, 130, 246, 0.15))",label:"Completed"},failed:{color:"var(--loki-red, #ef4444)",bg:"var(--loki-red-muted, rgba(239, 68, 68, 0.15))",label:"Failed"},cancelled:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"Cancelled"},pending:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Pending"},queued:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Queued"}};function ii(d,e,t){let i=d;if(i==null&&e){let l=new Date(e).getTime();i=(t?new Date(t).getTime():Date.now())-l}if(i==null||i<0)return"--";if(i<1e3)return`${i}ms`;let a=Math.floor(i/1e3);if(a<60)return`${a}s`;let s=Math.floor(a/60),r=a%60;if(s<60)return`${s}m ${r}s`;let o=Math.floor(s/60),n=s%60;return`${o}h ${n}m`}function ai(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 ke=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 yt({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=Ze(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=h({baseUrl:i}),this._loadData()),e==="project-id"&&this._loadData(),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=this.projectId,i=t!=null?`?project_id=${t}`:"",a=await e._get(`/api/v2/runs${i}`);if(e!==this._api)return;let s=a?.runs||a||[],r=Array.isArray(s)?s:[];this._freshPayload=a&&typeof a=="object"&&!Array.isArray(a)&&"freshness_s"in a?a:{freshness_s:_t(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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
11993
11993
  :host {
11994
11994
  display: block;
11995
11995
  }
@@ -12142,18 +12142,39 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
12142
12142
  color: var(--loki-text-muted, #939084);
12143
12143
  margin-bottom: 8px;
12144
12144
  }
12145
- `}render(){let e=this.shadowRoot;if(!e)return;let t=this._runs,i;if(this._loading&&t.length===0)i='<div class="loading">Loading runs...</div>';else if(t.length===0)i='<div class="empty-state">No runs found.</div>';else{let a=t.map(s=>{let r=(s.status||"pending").toLowerCase(),o=ut[r]||ut.pending,n=r==="running",l=r==="completed"||r==="failed"||r==="cancelled",c=Jt(s.duration_ms,s.started_at,s.ended_at);return`
12145
+
12146
+ .freshness {
12147
+ font-size: 11px;
12148
+ color: var(--loki-text-muted, #939084);
12149
+ white-space: nowrap;
12150
+ }
12151
+
12152
+ .freshness.is-stale {
12153
+ color: var(--loki-yellow, #D4A03C);
12154
+ font-weight: 600;
12155
+ }
12156
+
12157
+ .freshness.is-unknown {
12158
+ font-style: italic;
12159
+ }
12160
+
12161
+ .header-right {
12162
+ display: flex;
12163
+ align-items: center;
12164
+ gap: 10px;
12165
+ }
12166
+ `}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||"pending").toLowerCase(),l=wt[n]||wt.pending,c=n==="running",p=n==="completed"||n==="failed"||n==="cancelled",u=ii(o.duration_ms,o.started_at,o.ended_at);return`
12146
12167
  <tr>
12147
- <td><span class="run-id">#${s.id}</span></td>
12148
- <td>${this._escapeHtml(s.project_name||s.project||(s.project_id?`Project #${s.project_id}`:"--"))}</td>
12149
- <td><span class="status-badge" style="background: ${o.bg}; color: ${o.color};">${o.label}</span></td>
12150
- <td>${this._escapeHtml(s.trigger||s.trigger_type||"--")}</td>
12151
- <td>${Gt(s.started_at)}</td>
12152
- <td>${c}</td>
12168
+ <td><span class="run-id">#${o.id}</span></td>
12169
+ <td>${this._escapeHtml(o.project_name||o.project||(o.project_id?`Project #${o.project_id}`:"--"))}</td>
12170
+ <td><span class="status-badge" style="background: ${l.bg}; color: ${l.color};">${l.label}</span></td>
12171
+ <td>${this._escapeHtml(o.trigger||o.trigger_type||"--")}</td>
12172
+ <td>${ai(o.started_at)}</td>
12173
+ <td>${u}</td>
12153
12174
  <td>
12154
12175
  <div class="actions-cell">
12155
- ${n?`<button class="btn btn-cancel" data-action="cancel" data-run-id="${s.id}">Cancel</button>`:""}
12156
- ${l?`<button class="btn btn-replay" data-action="replay" data-run-id="${s.id}">Replay</button>`:""}
12176
+ ${c?`<button class="btn btn-cancel" data-action="cancel" data-run-id="${o.id}">Cancel</button>`:""}
12177
+ ${p?`<button class="btn btn-replay" data-action="replay" data-run-id="${o.id}">Replay</button>`:""}
12157
12178
  </div>
12158
12179
  </td>
12159
12180
  </tr>
@@ -12172,20 +12193,23 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
12172
12193
  <th>Actions</th>
12173
12194
  </tr>
12174
12195
  </thead>
12175
- <tbody>${a}</tbody>
12196
+ <tbody>${r}</tbody>
12176
12197
  </table>
12177
12198
  </div>
12178
- `}e.innerHTML=`
12199
+ `}let a=this._freshness(),s=a.known?a.isStale?"is-stale":"":"is-unknown";e.innerHTML=`
12179
12200
  <style>${this.getBaseStyles()}${this._getStyles()}</style>
12180
12201
  <div class="run-manager">
12181
12202
  <div class="header">
12182
12203
  <h2 class="title">Run Manager</h2>
12183
- <button class="btn btn-refresh" id="refresh-btn">Refresh</button>
12204
+ <div class="header-right">
12205
+ <span class="freshness ${s}" id="freshness" data-source="${a.source}" data-stale="${a.isStale===null?"unknown":String(a.isStale)}">${this._escapeHtml(Ze(a))}</span>
12206
+ <button class="btn btn-refresh" id="refresh-btn">Refresh</button>
12207
+ </div>
12184
12208
  </div>
12185
12209
  ${i}
12186
12210
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
12187
12211
  </div>
12188
- `,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("refresh-btn");t&&t.addEventListener("click",()=>this._loadData()),e.querySelectorAll('[data-action="cancel"]').forEach(i=>{i.addEventListener("click",()=>this._cancelRun(i.dataset.runId))}),e.querySelectorAll('[data-action="replay"]').forEach(i=>{i.addEventListener("click",()=>this._replayRun(i.dataset.runId))})}};customElements.get("loki-run-manager")||customElements.define("loki-run-manager",fe);var gt={running:{color:"var(--loki-green, #22c55e)",bg:"var(--loki-green-muted, rgba(34, 197, 94, 0.15))",label:"Running"},stopped:{color:"var(--loki-yellow, #eab308)",bg:"var(--loki-yellow-muted, rgba(234, 179, 8, 0.15))",label:"Stopped"},active:{color:"var(--loki-blue, #3b82f6)",bg:"var(--loki-blue-muted, rgba(59, 130, 246, 0.15))",label:"Idle"},missing:{color:"var(--loki-red, #ef4444)",bg:"var(--loki-red-muted, rgba(239, 68, 68, 0.15))",label:"Missing"},unknown:{color:"var(--loki-text-muted, #939084)",bg:"var(--loki-bg-tertiary, #ECEAE3)",label:"Unknown"}};function Kt(d){if(d==null||d<0)return"--";if(d<60)return`${d}s`;let e=Math.floor(d/60),t=d%60;if(e<60)return`${e}m ${t}s`;let i=Math.floor(e/60),a=e%60;return`${i}h ${a}m`}function mt(d){return d==null||isNaN(d)?"$0.00":`$${Number(d).toFixed(2)}`}var be=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!0,this._error=null,this._api=null,this._runs=[],this._summary=null,this._pollInterval=null,this._lastDataHash=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let[t,i]=await Promise.all([e._get("/api/fleet/runs"),e._get("/api/fleet/summary")]);if(e!==this._api)return;let a=Array.isArray(t)?t:t?.runs||[],s=JSON.stringify({runs:a,summaryResp:i});if(s===this._lastDataHash)return;this._lastDataHash=s,this._runs=Array.isArray(a)?a:[],this._summary=i||null,this._error=null}catch(t){if(e!==this._api)return;this._error||(this._error=`Failed to load fleet: ${t.message}`)}finally{this._loading=!1}this.render()}async _cancelRun(e){if(e&&!(typeof confirm=="function"&&!confirm(`Cancel build "${e}"? This stops the running build.`)))try{await this._api._post(`/api/fleet/runs/${encodeURIComponent(e)}/cancel`),this._lastDataHash=null,await this._loadData()}catch(t){this._error=`Cancel failed: ${t.message}`,this.render()}}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
12212
+ `,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",ke);var $t={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 si(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 Et(d){return d==null||isNaN(d)?"$0.00":`$${Number(d).toFixed(2)}`}var xe=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=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let[t,i]=await Promise.all([e._get("/api/fleet/runs"),e._get("/api/fleet/summary")]);if(e!==this._api)return;let a=Array.isArray(t)?t:t?.runs||[],s=JSON.stringify({runs:a,summaryResp:i});if(s===this._lastDataHash&&!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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
12189
12213
  :host { display: block; }
12190
12214
 
12191
12215
  .fleet {
@@ -12322,6 +12346,44 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
12322
12346
  font-size: 13px;
12323
12347
  }
12324
12348
 
12349
+ .empty-reason,
12350
+ .empty-source {
12351
+ margin-top: 6px;
12352
+ font-size: 12px;
12353
+ color: var(--loki-text-muted, #939084);
12354
+ }
12355
+
12356
+ /* Deliberately NOT muted grey like .empty-state: a read failure is a
12357
+ different fact from an empty fleet and must be distinguishable at a
12358
+ glance, not only by reading the words. */
12359
+ .error-state {
12360
+ text-align: center;
12361
+ padding: 32px 24px;
12362
+ border: 1px solid var(--loki-red, #ef4444);
12363
+ border-radius: 4px;
12364
+ background: var(--loki-red-muted, rgba(239, 68, 68, 0.15));
12365
+ }
12366
+
12367
+ .error-state-title {
12368
+ font-size: 14px;
12369
+ font-weight: 600;
12370
+ color: var(--loki-red, #ef4444);
12371
+ }
12372
+
12373
+ .error-state-detail {
12374
+ margin-top: 6px;
12375
+ font-size: 12px;
12376
+ color: var(--loki-text-secondary, #36342E);
12377
+ font-family: var(--loki-font-mono, monospace);
12378
+ word-break: break-word;
12379
+ }
12380
+
12381
+ .error-state-hint {
12382
+ margin-top: 8px;
12383
+ font-size: 12px;
12384
+ color: var(--loki-text-muted, #939084);
12385
+ }
12386
+
12325
12387
  .error-banner {
12326
12388
  margin-top: 12px;
12327
12389
  padding: 8px 12px;
@@ -12353,10 +12415,16 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
12353
12415
  </div>
12354
12416
  <div class="summary-card">
12355
12417
  <div class="summary-label">Total Cost</div>
12356
- <div class="summary-value">${mt(e.total_cost_usd)}</div>
12418
+ <div class="summary-value">${Et(e.total_cost_usd)}</div>
12357
12419
  </div>
12358
12420
  </div>
12359
- `:""}render(){let e=this.shadowRoot;if(!e)return;let t=this._runs,i;if(this._loading&&t.length===0)i='<div class="loading">Loading fleet...</div>';else if(t.length===0)i='<div class="empty-state">No registered builds. Run <code>loki start</code> in a project to populate the fleet.</div>';else{let a=t.map(s=>{let r=(s.status||"unknown").toLowerCase(),o=gt[r]||gt.unknown,n=s.running===!0,l=Kt(s.duration_seconds),c=s.iteration!=null?s.iteration:0,p=s.phase?this._escapeHtml(s.phase):"--";return`
12421
+ `:""}render(){let e=this.shadowRoot;if(!e)return;let t=this._runs,i;if(this._loading&&t.length===0)i='<div class="loading">Loading fleet...</div>';else if(this._error&&t.length===0)i=`
12422
+ <div class="error-state" role="status">
12423
+ <div class="error-state-title">Could not load the fleet</div>
12424
+ <div class="error-state-detail">${this._escapeHtml(this._error)}</div>
12425
+ <div class="error-state-hint">This is a read failure, not an empty fleet. Builds may be running.</div>
12426
+ </div>
12427
+ `;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=$t[r]||$t.unknown,n=s.running===!0,l=si(s.duration_seconds),c=s.iteration!=null?s.iteration:0,p=s.phase?this._escapeHtml(s.phase):"--";return`
12360
12428
  <tr>
12361
12429
  <td>
12362
12430
  <div class="project-name">${this._escapeHtml(s.name||"project")}</div>
@@ -12365,7 +12433,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
12365
12433
  <td><span class="status-badge" style="background: ${o.bg}; color: ${o.color};">${o.label}</span></td>
12366
12434
  <td>${p}</td>
12367
12435
  <td>${c}</td>
12368
- <td class="cost-cell">${mt(s.cost_usd)}</td>
12436
+ <td class="cost-cell">${Et(s.cost_usd)}</td>
12369
12437
  <td>${l}</td>
12370
12438
  <td>
12371
12439
  ${n?`<button class="btn btn-cancel" data-action="cancel" data-id="${this._escapeHtml(s.id||s.path||"")}">Cancel</button>`:""}
@@ -12403,9 +12471,9 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
12403
12471
  Job-watcher is future work.
12404
12472
  </div>
12405
12473
  ${i}
12406
- ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
12474
+ ${this._error&&t.length>0?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
12407
12475
  </div>
12408
- `,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("refresh-btn");t&&t.addEventListener("click",()=>{this._lastDataHash=null,this._loadData()}),e.querySelectorAll('[data-action="cancel"]').forEach(i=>{i.addEventListener("click",()=>this._cancelRun(i.dataset.id))})}};customElements.get("loki-fleet")||customElements.define("loki-fleet",be);function Vt(d){if(!d)return"--";try{return new Date(d).toLocaleString([],{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit"})}catch{return String(d)}}function Yt(d){let e=new URLSearchParams;for(let[i,a]of Object.entries(d))a!=null&&a!==""&&e.set(i,String(a));let t=e.toString();return t?`?${t}`:""}var ke=class extends v{static get observedAttributes(){return["api-url","limit","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._entries=[],this._verifyResult=null,this._verifying=!1,this._filters={action:"",resource:"",dateFrom:"",dateTo:""}}get limit(){let e=this.getAttribute("limit");return e?parseInt(e,10):50}set limit(e){this.setAttribute("limit",String(e))}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData()}disconnectedCallback(){super.disconnectedCallback()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="limit"&&this._loadData(),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){let e=this._api;try{this._loading=!0,this.render();let t={limit:this.limit,action:this._filters.action,resource:this._filters.resource,date_from:this._filters.dateFrom,date_to:this._filters.dateTo},i=Yt(t),a=await e._get(`/api/v2/audit${i}`);if(e!==this._api)return;this._entries=a?.entries||a||[],this._error=null}catch(t){if(e!==this._api)return;this._error=`Failed to load audit log: ${t.message}`}finally{this._loading=!1}this.render()}async _verifyIntegrity(){let e=this._api;try{this._verifying=!0,this._verifyResult=null,this.render();let t=await e._get("/api/v2/audit/verify");if(e!==this._api)return;this._verifyResult=t}catch(t){if(e!==this._api)return;this._verifyResult={valid:!1,error:t.message}}finally{this._verifying=!1}this.render()}_onFilterChange(e,t){this._filters[e]=t,this._loadData()}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
12476
+ `,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",xe);function ri(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 oi(d){let e=new URLSearchParams;for(let[i,a]of Object.entries(d))a!=null&&a!==""&&e.set(i,String(a));let t=e.toString();return t?`?${t}`:""}var _e=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=h({baseUrl:i}),this._loadData()),e==="limit"&&this._loadData(),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){let e=this._api;try{this._loading=!0,this.render();let t={limit:this.limit,action:this._filters.action,resource:this._filters.resource,date_from:this._filters.dateFrom,date_to:this._filters.dateTo},i=oi(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={valid:!1,error:t.message}}finally{this._verifying=!1}this.render()}_onFilterChange(e,t){this._filters[e]=t,this._loadData()}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
12409
12477
  :host {
12410
12478
  display: block;
12411
12479
  }
@@ -12598,6 +12666,43 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
12598
12666
  font-size: 13px;
12599
12667
  }
12600
12668
 
12669
+ .empty-reason {
12670
+ margin-top: 6px;
12671
+ font-size: 12px;
12672
+ color: var(--loki-text-muted, #939084);
12673
+ }
12674
+
12675
+ /* Deliberately NOT muted grey like .empty-state: an unread audit log is
12676
+ a different fact from an empty one and must be distinguishable at a
12677
+ glance, not only by reading the words. */
12678
+ .error-state {
12679
+ text-align: center;
12680
+ padding: 32px 24px;
12681
+ border: 1px solid var(--loki-red, #ef4444);
12682
+ border-radius: 4px;
12683
+ background: var(--loki-red-muted, rgba(239, 68, 68, 0.15));
12684
+ }
12685
+
12686
+ .error-state-title {
12687
+ font-size: 14px;
12688
+ font-weight: 600;
12689
+ color: var(--loki-red, #ef4444);
12690
+ }
12691
+
12692
+ .error-state-detail {
12693
+ margin-top: 6px;
12694
+ font-size: 12px;
12695
+ color: var(--loki-text-secondary, #36342E);
12696
+ font-family: var(--loki-font-mono, monospace);
12697
+ word-break: break-word;
12698
+ }
12699
+
12700
+ .error-state-hint {
12701
+ margin-top: 8px;
12702
+ font-size: 12px;
12703
+ color: var(--loki-text-muted, #939084);
12704
+ }
12705
+
12601
12706
  .error-banner {
12602
12707
  margin-top: 12px;
12603
12708
  padding: 8px 12px;
@@ -12623,9 +12728,15 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
12623
12728
  <div class="verify-result ${s?"verify-valid":"verify-invalid"}">
12624
12729
  ${s?"[VALID] Audit chain integrity verified.":`[TAMPERED] ${this._escapeHtml(this._verifyResult.error||"Integrity check failed.")}`}
12625
12730
  </div>
12626
- `}let a;if(this._loading&&t.length===0)a='<div class="loading">Loading audit log...</div>';else if(t.length===0)a='<div class="empty-state">No audit entries found matching filters.</div>';else{let s=t.map(r=>`
12731
+ `}let a;if(this._loading&&t.length===0)a='<div class="loading">Loading audit log...</div>';else if(this._error&&t.length===0)a=`
12732
+ <div class="error-state" role="status">
12733
+ <div class="error-state-title">Could not load the audit log</div>
12734
+ <div class="error-state-detail">${this._escapeHtml(this._error)}</div>
12735
+ <div class="error-state-hint">This is a read failure, not an empty log. Do not treat this as evidence that no audited actions occurred.</div>
12736
+ </div>
12737
+ `;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=>`
12627
12738
  <tr>
12628
- <td>${Vt(r.timestamp)}</td>
12739
+ <td>${ri(r.timestamp)}</td>
12629
12740
  <td>${this._escapeHtml(r.action||"--")}</td>
12630
12741
  <td>${this._escapeHtml(r.resource||r.resource_type||"--")}</td>
12631
12742
  <td>${this._escapeHtml(r.user||r.actor||"--")}</td>
@@ -12687,9 +12798,9 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
12687
12798
 
12688
12799
  ${i}
12689
12800
  ${a}
12690
- ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
12801
+ ${this._error&&t.length>0?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
12691
12802
  </div>
12692
- `,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("verify-btn");t&&t.addEventListener("click",()=>this._verifyIntegrity());let i=e.getElementById("refresh-btn");i&&i.addEventListener("click",()=>this._loadData());let a=e.getElementById("filter-action");a&&a.addEventListener("change",n=>this._onFilterChange("action",n.target.value));let s=e.getElementById("filter-resource");s&&s.addEventListener("change",n=>this._onFilterChange("resource",n.target.value));let r=e.getElementById("filter-date-from");r&&r.addEventListener("change",n=>this._onFilterChange("dateFrom",n.target.value));let o=e.getElementById("filter-date-to");o&&o.addEventListener("change",n=>this._onFilterChange("dateTo",n.target.value))}};customElements.get("loki-audit-viewer")||customElements.define("loki-audit-viewer",ke);function vt(d){if(!d)return"Never";try{return new Date(d).toLocaleString([],{month:"short",day:"numeric",year:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return String(d)}}var xe=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._keys=[],this._showCreateForm=!1,this._newToken=null,this._confirmDeleteId=null,this._rotateKeyId=null,this._rotateGracePeriod="24",this._createName="",this._createRole="read",this._createExpiration=""}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData()}disconnectedCallback(){super.disconnectedCallback()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){let e=this._api;try{this._loading=!0,this.render();let t=await e._get("/api/v2/api-keys");if(e!==this._api)return;this._keys=Array.isArray(t)?t:t?.keys||[],this._error=null}catch(t){if(e!==this._api)return;this._error=`Failed to load API keys: ${t.message}`}finally{this._loading=!1}this.render()}async _createKey(){if(!this._createName.trim()){this._error="Key name is required.",this.render();return}try{let e={name:this._createName.trim(),role:this._createRole};this._createExpiration&&(e.expiration=this._createExpiration);let t=await this._api._post("/api/v2/api-keys",e);this._newToken=t?.token||t?.key||null,this._showCreateForm=!1,this._createName="",this._createRole="read",this._createExpiration="",this._error=null,await this._loadData()}catch(e){this._error=`Create failed: ${e.message}`,this.render()}}async _rotateKey(e){try{let t={grace_period_hours:parseInt(this._rotateGracePeriod,10)||24},i=await this._api._post(`/api/v2/api-keys/${e}/rotate`,t);this._newToken=i?.token||i?.key||null,this._rotateKeyId=null,this._error=null,await this._loadData()}catch(t){this._error=`Rotate failed: ${t.message}`,this.render()}}async _deleteKey(e){try{await this._api._delete(`/api/v2/api-keys/${e}`),this._confirmDeleteId=null,this._error=null,await this._loadData()}catch(t){this._error=`Delete failed: ${t.message}`,this._confirmDeleteId=null,this.render()}}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
12803
+ `,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",_e);function Ct(d){if(!d)return"Never";try{return new Date(d).toLocaleString([],{month:"short",day:"numeric",year:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return String(d)}}var ye=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._keys=[],this._showCreateForm=!1,this._newToken=null,this._confirmDeleteId=null,this._rotateKeyId=null,this._rotateGracePeriod="24",this._createName="",this._createRole="read",this._createExpiration=""}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData()}disconnectedCallback(){super.disconnectedCallback()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){let e=this._api;try{this._loading=!0,this.render();let t=await e._get("/api/v2/api-keys");if(e!==this._api)return;this._keys=Array.isArray(t)?t:t?.keys||[],this._error=null}catch(t){if(e!==this._api)return;this._error=`Failed to load API keys: ${t.message}`}finally{this._loading=!1}this.render()}async _createKey(){if(!this._createName.trim()){this._error="Key name is required.",this.render();return}try{let e={name:this._createName.trim(),role:this._createRole};this._createExpiration&&(e.expiration=this._createExpiration);let t=await this._api._post("/api/v2/api-keys",e);this._newToken=t?.token||t?.key||null,this._showCreateForm=!1,this._createName="",this._createRole="read",this._createExpiration="",this._error=null,await this._loadData()}catch(e){this._error=`Create failed: ${e.message}`,this.render()}}async _rotateKey(e){try{let t={grace_period_hours:parseInt(this._rotateGracePeriod,10)||24},i=await this._api._post(`/api/v2/api-keys/${e}/rotate`,t);this._newToken=i?.token||i?.key||null,this._rotateKeyId=null,this._error=null,await this._loadData()}catch(t){this._error=`Rotate failed: ${t.message}`,this.render()}}async _deleteKey(e){try{await this._api._delete(`/api/v2/api-keys/${e}`),this._confirmDeleteId=null,this._error=null,await this._loadData()}catch(t){this._error=`Delete failed: ${t.message}`,this._confirmDeleteId=null,this.render()}}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
12693
12804
  :host {
12694
12805
  display: block;
12695
12806
  }
@@ -13068,8 +13179,8 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
13068
13179
  <tr>
13069
13180
  <td><span class="key-name">${this._escapeHtml(o.name||"Unnamed")}</span></td>
13070
13181
  <td><span class="key-role">${this._escapeHtml(o.role||o.scopes||"--")}</span></td>
13071
- <td>${vt(o.created_at||o.created)}</td>
13072
- <td>${vt(o.last_used_at||o.last_used)}</td>
13182
+ <td>${Ct(o.created_at||o.created)}</td>
13183
+ <td>${Ct(o.last_used_at||o.last_used)}</td>
13073
13184
  <td><span class="${c}">${this._escapeHtml(l)}</span></td>
13074
13185
  <td><div class="actions-cell">${m}</div></td>
13075
13186
  </tr>
@@ -13088,7 +13199,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
13088
13199
  ${s}
13089
13200
  ${this._error?`<div class="error-banner">${this._escapeHtml(this._error)}</div>`:""}
13090
13201
  </div>
13091
- `,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("show-create");t&&t.addEventListener("click",()=>{this._showCreateForm=!0,this.render()});let i=e.getElementById("dismiss-token");i&&i.addEventListener("click",()=>{this._newToken=null,this.render()});let a=e.getElementById("submit-create");a&&a.addEventListener("click",()=>{let r=e.getElementById("create-name"),o=e.getElementById("create-role"),n=e.getElementById("create-expiration");this._createName=r?.value||"",this._createRole=o?.value||"read",this._createExpiration=n?.value||"",this._createKey()});let s=e.getElementById("cancel-create");s&&s.addEventListener("click",()=>{this._showCreateForm=!1,this.render()}),e.querySelectorAll('[data-action="delete"]').forEach(r=>{r.addEventListener("click",()=>{this._confirmDeleteId=r.dataset.keyId,this.render()})}),e.querySelectorAll('[data-action="confirm-delete"]').forEach(r=>{r.addEventListener("click",()=>{this._deleteKey(r.dataset.keyId)})}),e.querySelectorAll('[data-action="cancel-delete"]').forEach(r=>{r.addEventListener("click",()=>{this._confirmDeleteId=null,this.render()})}),e.querySelectorAll('[data-action="rotate"]').forEach(r=>{r.addEventListener("click",()=>{this._rotateKeyId=r.dataset.keyId,this.render()})}),e.querySelectorAll('[data-action="confirm-rotate"]').forEach(r=>{r.addEventListener("click",()=>{let o=e.getElementById(`rotate-grace-${r.dataset.keyId}`);this._rotateGracePeriod=o?.value||"24",this._rotateKey(r.dataset.keyId)})}),e.querySelectorAll('[data-action="cancel-rotate"]').forEach(r=>{r.addEventListener("click",()=>{this._rotateKeyId=null,this.render()})})}};customElements.get("loki-api-keys")||customElements.define("loki-api-keys",xe);function Wt(d){return d?d.slug&&d.name?`${d.name} (${d.slug})`:d.name||d.slug||"Unknown":"Unknown"}var _e=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._tenants=[],this._selectedTenantId=null,this._dropdownOpen=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._outsideClickHandler=e=>{this._dropdownOpen&&!this.contains(e.target)&&(this._dropdownOpen=!1,this.render())},document.addEventListener("click",this._outsideClickHandler)}disconnectedCallback(){super.disconnectedCallback(),this._outsideClickHandler&&(document.removeEventListener("click",this._outsideClickHandler),this._outsideClickHandler=null)}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){let e=this._api;try{this._loading=!0;let t=await e._get("/api/v2/tenants");if(e!==this._api)return;this._tenants=Array.isArray(t)?t:t?.tenants||[],this._error=null}catch(t){if(e!==this._api)return;this._error=`Failed to load tenants: ${t.message}`}finally{this._loading=!1}this.render()}_toggleDropdown(){this._dropdownOpen=!this._dropdownOpen,this.render()}_selectTenant(e,t){this._selectedTenantId=e,this._dropdownOpen=!1,this.render(),this.dispatchEvent(new CustomEvent("tenant-changed",{detail:{tenantId:e,tenantName:t},bubbles:!0,composed:!0}))}_getSelectedTenant(){return this._selectedTenantId==null?null:this._tenants.find(e=>(e.id||e.slug)===this._selectedTenantId)||null}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
13202
+ `,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",ye);function ni(d){return d?d.slug&&d.name?`${d.name} (${d.slug})`:d.name||d.slug||"Unknown":"Unknown"}var we=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._loading=!1,this._error=null,this._api=null,this._tenants=[],this._selectedTenantId=null,this._dropdownOpen=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._outsideClickHandler=e=>{this._dropdownOpen&&!this.contains(e.target)&&(this._dropdownOpen=!1,this.render())},document.addEventListener("click",this._outsideClickHandler)}disconnectedCallback(){super.disconnectedCallback(),this._outsideClickHandler&&(document.removeEventListener("click",this._outsideClickHandler),this._outsideClickHandler=null)}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _loadData(){let e=this._api;try{this._loading=!0;let t=await e._get("/api/v2/tenants");if(e!==this._api)return;this._tenants=Array.isArray(t)?t:t?.tenants||[],this._error=null}catch(t){if(e!==this._api)return;this._error=`Failed to load tenants: ${t.message}`}finally{this._loading=!1}this.render()}_toggleDropdown(){this._dropdownOpen=!this._dropdownOpen,this.render()}_selectTenant(e,t){this._selectedTenantId=e,this._dropdownOpen=!1,this.render(),this.dispatchEvent(new CustomEvent("tenant-changed",{detail:{tenantId:e,tenantName:t},bubbles:!0,composed:!0}))}_getSelectedTenant(){return this._selectedTenantId==null?null:this._tenants.find(e=>(e.id||e.slug)===this._selectedTenantId)||null}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getStyles(){return`
13092
13203
  :host {
13093
13204
  display: inline-block;
13094
13205
  position: relative;
@@ -13222,7 +13333,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
13222
13333
  color: var(--loki-text-muted, #939084);
13223
13334
  font-size: 12px;
13224
13335
  }
13225
- `}render(){let e=this.shadowRoot;if(!e)return;let t=this._getSelectedTenant(),i=t?Wt(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=`
13336
+ `}render(){let e=this.shadowRoot;if(!e)return;let t=this._getSelectedTenant(),i=t?ni(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=`
13226
13337
  <button class="dropdown-item all-tenants ${o?"selected":""}" data-tenant-id="">
13227
13338
  <span class="tenant-name">All Tenants</span>
13228
13339
  ${o?'<span class="check-mark">*</span>':""}
@@ -13247,7 +13358,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
13247
13358
  </button>
13248
13359
  ${s}
13249
13360
  </div>
13250
- `,this._attachEventListeners()}_attachEventListeners(){let e=this.shadowRoot;if(!e)return;let t=e.getElementById("trigger-btn");t&&t.addEventListener("click",i=>{i.stopPropagation(),this._toggleDropdown()}),e.querySelectorAll(".dropdown-item").forEach(i=>{i.addEventListener("click",a=>{a.stopPropagation();let s=i.dataset.tenantId||null,r=i.dataset.tenantName||null;this._selectTenant(s||null,r||"All Tenants")})})}};customElements.get("loki-tenant-switcher")||customElements.define("loki-tenant-switcher",_e);var Ye={info:{color:"var(--loki-blue, #2F71E3)",label:"INFO",icon:"i"},success:{color:"var(--loki-green, #1FC5A8)",label:"OK",icon:"+"},warning:{color:"var(--loki-yellow, #D4A03C)",label:"WARN",icon:"!"},error:{color:"var(--loki-red, #C45B5B)",label:"ERR",icon:"x"}},Qt=100,ye=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._items=[],this._filter="all",this._api=null,this._pollInterval=null,this._paused=!1,this._lastTimestamp=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/v2/activity");if(e!==this._api)return;let i=t.events||t.activities||[];if(i.length>0){let a=i.filter(s=>!this._lastTimestamp||new Date(s.timestamp)>new Date(this._lastTimestamp)).map(s=>({id:s.id||crypto.randomUUID(),timestamp:s.timestamp||new Date().toISOString(),message:s.message||s.description||"",severity:s.severity||s.level||"info",source:s.source||s.component||"",isNew:!0}));a.length>0&&(this._items=[...a,...this._items].slice(0,Qt),this._lastTimestamp=a[0].timestamp,setTimeout(()=>{this._items.forEach(s=>s.isNew=!1)},600))}}catch{if(e!==this._api)return;this._items.length===0&&(this._items=this._getDemoItems())}this.render()}_getDemoItems(){let e=Date.now();return[{id:"1",timestamp:new Date(e-2e3).toISOString(),message:"Build iteration #12 started",severity:"info",source:"runner"},{id:"2",timestamp:new Date(e-5e3).toISOString(),message:"Code review passed (3/3 reviewers)",severity:"success",source:"review"},{id:"3",timestamp:new Date(e-8e3).toISOString(),message:"Context window at 78% capacity",severity:"warning",source:"context"},{id:"4",timestamp:new Date(e-12e3).toISOString(),message:"Test suite completed: 42/42 passed",severity:"success",source:"testing"},{id:"5",timestamp:new Date(e-15e3).toISOString(),message:"Verify step complete: changes checked",severity:"info",source:"rarv"}]}_formatTime(e){if(!e)return"";try{return new Date(e).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})}catch{return""}}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getFilteredItems(){return this._filter==="all"?this._items:this._items.filter(e=>e.severity===this._filter)}_setFilter(e){this._filter=e,this.render()}_bindEvents(){let e=this.shadowRoot;e.querySelectorAll(".filter-btn").forEach(i=>{i.addEventListener("click",()=>{this._setFilter(i.dataset.filter)})});let t=e.querySelector(".activity-feed");t&&(t.addEventListener("mouseenter",()=>{this._paused=!0}),t.addEventListener("mouseleave",()=>{this._paused=!1}))}_getStyles(){return`
13361
+ `,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",we);var et={info:{color:"var(--loki-blue, #2F71E3)",label:"INFO",icon:"i"},success:{color:"var(--loki-green, #1FC5A8)",label:"OK",icon:"+"},warning:{color:"var(--loki-yellow, #D4A03C)",label:"WARN",icon:"!"},error:{color:"var(--loki-red, #C45B5B)",label:"ERR",icon:"x"}},li=100,$e=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._items=[],this._filter="all",this._api=null,this._pollInterval=null,this._paused=!1,this._lastTimestamp=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:3e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/v2/activity");if(e!==this._api)return;let i=t.events||t.activities||[];if(i.length>0){let a=i.filter(s=>!this._lastTimestamp||new Date(s.timestamp)>new Date(this._lastTimestamp)).map(s=>({id:s.id||crypto.randomUUID(),timestamp:s.timestamp||new Date().toISOString(),message:s.message||s.description||"",severity:s.severity||s.level||"info",source:s.source||s.component||"",isNew:!0}));a.length>0&&(this._items=[...a,...this._items].slice(0,li),this._lastTimestamp=a[0].timestamp,setTimeout(()=>{this._items.forEach(s=>s.isNew=!1)},600))}}catch{if(e!==this._api)return;this._items.length===0&&(this._items=this._getDemoItems())}this.render()}_getDemoItems(){let e=Date.now();return[{id:"1",timestamp:new Date(e-2e3).toISOString(),message:"Build iteration #12 started",severity:"info",source:"runner"},{id:"2",timestamp:new Date(e-5e3).toISOString(),message:"Code review passed (3/3 reviewers)",severity:"success",source:"review"},{id:"3",timestamp:new Date(e-8e3).toISOString(),message:"Context window at 78% capacity",severity:"warning",source:"context"},{id:"4",timestamp:new Date(e-12e3).toISOString(),message:"Test suite completed: 42/42 passed",severity:"success",source:"testing"},{id:"5",timestamp:new Date(e-15e3).toISOString(),message:"Verify step complete: changes checked",severity:"info",source:"rarv"}]}_formatTime(e){if(!e)return"";try{return new Date(e).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})}catch{return""}}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_getFilteredItems(){return this._filter==="all"?this._items:this._items.filter(e=>e.severity===this._filter)}_setFilter(e){this._filter=e,this.render()}_bindEvents(){let e=this.shadowRoot;e.querySelectorAll(".filter-btn").forEach(i=>{i.addEventListener("click",()=>{this._setFilter(i.dataset.filter)})});let t=e.querySelector(".activity-feed");t&&(t.addEventListener("mouseenter",()=>{this._paused=!0}),t.addEventListener("mouseleave",()=>{this._paused=!1}))}_getStyles(){return`
13251
13362
  :host {
13252
13363
  display: block;
13253
13364
  }
@@ -13433,7 +13544,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
13433
13544
  ::-webkit-scrollbar-track { background: var(--loki-bg-primary, #FFFEFB); }
13434
13545
  ::-webkit-scrollbar-thumb { background: var(--loki-border, #ECEAE3); border-radius: 3px; }
13435
13546
  ::-webkit-scrollbar-thumb:hover { background: var(--loki-border-light, #C5C0B1); }
13436
- `}render(){let e=this.shadowRoot;if(!e)return;let t=this._getFilteredItems(),a=["all","info","success","warning","error"].map(r=>{let o=this._filter===r,n=r==="all"?"All":Ye[r]?.label||r;return`<button class="filter-btn ${o?"active":""}" data-filter="${r}">${n}</button>`}).join(""),s;if(t.length===0?s='<div class="empty-state">No activity yet. Updates will stream here as your build runs.</div>':s=t.map(r=>{let o=Ye[r.severity]||Ye.info;return`
13547
+ `}render(){let e=this.shadowRoot;if(!e)return;let t=this._getFilteredItems(),a=["all","info","success","warning","error"].map(r=>{let o=this._filter===r,n=r==="all"?"All":et[r]?.label||r;return`<button class="filter-btn ${o?"active":""}" data-filter="${r}">${n}</button>`}).join(""),s;if(t.length===0?s='<div class="empty-state">No activity yet. Updates will stream here as your build runs.</div>':s=t.map(r=>{let o=et[r.severity]||et.info;return`
13437
13548
  <div class="activity-item ${r.isNew?"new-item":""}">
13438
13549
  <div class="severity-band" style="background: ${o.color};"></div>
13439
13550
  <div class="item-content">
@@ -13454,7 +13565,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
13454
13565
  ${s}
13455
13566
  </div>
13456
13567
  </div>
13457
- `,this._bindEvents(),!this._paused){let r=e.querySelector(".activity-feed");r&&(r.scrollTop=0)}}};customElements.get("loki-activity-stream")||customElements.define("loki-activity-stream",ye);var Xt={claude:{initial:"C",color:"#553DE9",bgColor:"rgba(85, 61, 233, 0.12)"},codex:{initial:"X",color:"#1FC5A8",bgColor:"rgba(31, 197, 168, 0.12)"},cline:{initial:"L",color:"#D4A03C",bgColor:"rgba(212, 160, 60, 0.12)"},aider:{initial:"A",color:"#C45B5B",bgColor:"rgba(196, 91, 91, 0.12)"}},ft={healthy:"var(--loki-green, #1FC5A8)",degraded:"var(--loki-yellow, #D4A03C)",down:"var(--loki-red, #C45B5B)",unknown:"var(--loki-text-muted, #939084)"},we=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._providers=[],this._expandedProvider=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:1e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/v2/providers/health");if(e!==this._api)return;this._providers=t.providers||[]}catch{if(e!==this._api)return;this._providers.length===0&&(this._providers=this._getDemoData())}this.render()}_getDemoData(){return[{name:"claude",status:"healthy",latency_ms:245,tokens_used:125400,model:"claude-opus-4-7",api_version:"v1",rate_limit:{remaining:45,limit:50},cost_usd:3.42},{name:"codex",status:"degraded",latency_ms:890,tokens_used:45200,model:"gpt-5.3-codex",api_version:"v1",rate_limit:{remaining:12,limit:60},cost_usd:.87},{name:"cline",status:"healthy",latency_ms:320,tokens_used:78600,model:"cline-default",api_version:"v1",rate_limit:{remaining:55,limit:60},cost_usd:1.15}]}_formatTokens(e){return e==null?"--":e>=1e6?(e/1e6).toFixed(1)+"M":e>=1e3?(e/1e3).toFixed(1)+"K":String(e)}_formatLatency(e){return e==null?"--":e<1e3?e+"ms":(e/1e3).toFixed(1)+"s"}_formatCost(e){return e==null?"--":"$"+e.toFixed(2)}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_toggleExpand(e){this._expandedProvider=this._expandedProvider===e?null:e,this.render()}_bindEvents(){this.shadowRoot.querySelectorAll(".provider-card").forEach(t=>{t.addEventListener("click",()=>{this._toggleExpand(t.dataset.provider)})})}_getStyles(){return`
13568
+ `,this._bindEvents(),!this._paused){let r=e.querySelector(".activity-feed");r&&(r.scrollTop=0)}}};customElements.get("loki-activity-stream")||customElements.define("loki-activity-stream",$e);var di={claude:{initial:"C",color:"#553DE9",bgColor:"rgba(85, 61, 233, 0.12)"},codex:{initial:"X",color:"#1FC5A8",bgColor:"rgba(31, 197, 168, 0.12)"},cline:{initial:"L",color:"#D4A03C",bgColor:"rgba(212, 160, 60, 0.12)"},aider:{initial:"A",color:"#C45B5B",bgColor:"rgba(196, 91, 91, 0.12)"}},St={healthy:"var(--loki-green, #1FC5A8)",degraded:"var(--loki-yellow, #D4A03C)",down:"var(--loki-red, #C45B5B)",unknown:"var(--loki-text-muted, #939084)"},Ee=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._providers=[],this._expandedProvider=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:1e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/v2/providers/health");if(e!==this._api)return;this._providers=t.providers||[]}catch{if(e!==this._api)return;this._providers.length===0&&(this._providers=this._getDemoData())}this.render()}_getDemoData(){return[{name:"claude",status:"healthy",latency_ms:245,tokens_used:125400,model:"claude-opus-4-7",api_version:"v1",rate_limit:{remaining:45,limit:50},cost_usd:3.42},{name:"codex",status:"degraded",latency_ms:890,tokens_used:45200,model:"gpt-5.3-codex",api_version:"v1",rate_limit:{remaining:12,limit:60},cost_usd:.87},{name:"cline",status:"healthy",latency_ms:320,tokens_used:78600,model:"cline-default",api_version:"v1",rate_limit:{remaining:55,limit:60},cost_usd:1.15}]}_formatTokens(e){return Ne(e)}_formatLatency(e){return st(e)}_formatCost(e){return I(e)}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_toggleExpand(e){this._expandedProvider=this._expandedProvider===e?null:e,this.render()}_bindEvents(){this.shadowRoot.querySelectorAll(".provider-card").forEach(t=>{t.addEventListener("click",()=>{this._toggleExpand(t.dataset.provider)})})}_getStyles(){return`
13458
13569
  :host {
13459
13570
  display: block;
13460
13571
  }
@@ -13633,7 +13744,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
13633
13744
  border: 1px solid var(--loki-border, #ECEAE3);
13634
13745
  border-radius: 5px;
13635
13746
  }
13636
- `}render(){let e=this.shadowRoot;if(!e)return;let t;this._providers.length===0?t='<div class="empty-state">Provider status will appear once a build starts.</div>':t=`<div class="provider-grid">${this._providers.map(i=>{let a=Xt[i.name]||{initial:(i.name??"?").charAt(0).toUpperCase(),color:"#939084",bgColor:"rgba(147, 144, 132, 0.12)"},s=ft[i.status]||ft.unknown,r=this._expandedProvider===i.name,o=i.rate_limit?i.rate_limit.remaining/i.rate_limit.limit*100:100,n=o>50?"var(--loki-green)":o>20?"var(--loki-yellow)":"var(--loki-red)";return`
13747
+ `}render(){let e=this.shadowRoot;if(!e)return;let t;this._providers.length===0?t='<div class="empty-state">Provider status will appear once a build starts.</div>':t=`<div class="provider-grid">${this._providers.map(i=>{let a=di[i.name]||{initial:(i.name??"?").charAt(0).toUpperCase(),color:"#939084",bgColor:"rgba(147, 144, 132, 0.12)"},s=St[i.status]||St.unknown,r=this._expandedProvider===i.name,o=i.rate_limit?i.rate_limit.remaining/i.rate_limit.limit*100:100,n=o>50?"var(--loki-green)":o>20?"var(--loki-yellow)":"var(--loki-red)";return`
13637
13748
  <div class="provider-card ${r?"expanded":""}" data-provider="${this._escapeHtml(i.name)}">
13638
13749
  <div class="card-header">
13639
13750
  <div class="provider-icon" style="background: ${a.bgColor}; color: ${a.color};">${a.initial}</div>
@@ -13685,7 +13796,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
13685
13796
  </div>
13686
13797
  ${t}
13687
13798
  </div>
13688
- `,this._bindEvents()}};customElements.get("loki-provider-health")||customElements.define("loki-provider-health",we);var We=[{id:"planning",label:"Planning",icon:"P"},{id:"scaffolding",label:"Scaffolding",icon:"S"},{id:"implementation",label:"Implementation",icon:"I"},{id:"testing",label:"Testing",icon:"T"},{id:"review",label:"Review",icon:"R"},{id:"deploy",label:"Deploy",icon:"D"}],Qe={waiting:{color:"var(--loki-text-muted, #939084)",bgColor:"var(--loki-bg-tertiary, #ECEAE3)",label:"Waiting"},active:{color:"var(--loki-accent, #553DE9)",bgColor:"var(--loki-accent-muted, rgba(85, 61, 233, 0.10))",label:"Active"},complete:{color:"var(--loki-green, #1FC5A8)",bgColor:"var(--loki-green-muted, rgba(31, 197, 168, 0.12))",label:"Complete"},failed:{color:"var(--loki-red, #C45B5B)",bgColor:"var(--loki-red-muted, rgba(196, 91, 91, 0.12))",label:"Failed"}},$e=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._stages=[],this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/v2/pipeline/status");if(e!==this._api)return;this._stages=t.stages||[]}catch{if(e!==this._api)return;this._stages.length===0&&(this._stages=this._getDemoData())}this.render()}_getDemoData(){return[{id:"planning",status:"complete",errors:0,duration_ms:12500},{id:"scaffolding",status:"complete",errors:0,duration_ms:8300},{id:"implementation",status:"active",errors:0,duration_ms:45e3},{id:"testing",status:"waiting",errors:0,duration_ms:null},{id:"review",status:"waiting",errors:0,duration_ms:null},{id:"deploy",status:"waiting",errors:0,duration_ms:null}]}_getStageData(e){return this._stages.find(t=>t.id===e)||{id:e,status:"waiting",errors:0}}_formatDuration(e){if(e==null||e<0)return"";if(e<1e3)return e+"ms";let t=Math.floor(e/1e3);if(t<60)return t+"s";let i=Math.floor(t/60),a=t%60;return i+"m "+a+"s"}_getStyles(){return`
13799
+ `,this._bindEvents()}};customElements.get("loki-provider-health")||customElements.define("loki-provider-health",Ee);var tt=[{id:"planning",label:"Planning",icon:"P"},{id:"scaffolding",label:"Scaffolding",icon:"S"},{id:"implementation",label:"Implementation",icon:"I"},{id:"testing",label:"Testing",icon:"T"},{id:"review",label:"Review",icon:"R"},{id:"deploy",label:"Deploy",icon:"D"}],it={waiting:{color:"var(--loki-text-muted, #939084)",bgColor:"var(--loki-bg-tertiary, #ECEAE3)",label:"Waiting"},active:{color:"var(--loki-accent, #553DE9)",bgColor:"var(--loki-accent-muted, rgba(85, 61, 233, 0.10))",label:"Active"},complete:{color:"var(--loki-green, #1FC5A8)",bgColor:"var(--loki-green-muted, rgba(31, 197, 168, 0.12))",label:"Complete"},failed:{color:"var(--loki-red, #C45B5B)",bgColor:"var(--loki-red-muted, rgba(196, 91, 91, 0.12))",label:"Failed"}},Ce=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._stages=[],this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:5e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/v2/pipeline/status");if(e!==this._api)return;this._stages=t.stages||[]}catch{if(e!==this._api)return;this._stages.length===0&&(this._stages=this._getDemoData())}this.render()}_getDemoData(){return[{id:"planning",status:"complete",errors:0,duration_ms:12500},{id:"scaffolding",status:"complete",errors:0,duration_ms:8300},{id:"implementation",status:"active",errors:0,duration_ms:45e3},{id:"testing",status:"waiting",errors:0,duration_ms:null},{id:"review",status:"waiting",errors:0,duration_ms:null},{id:"deploy",status:"waiting",errors:0,duration_ms:null}]}_getStageData(e){return this._stages.find(t=>t.id===e)||{id:e,status:"waiting",errors:0}}_formatDuration(e){if(e==null||e<0)return"";if(e<1e3)return e+"ms";let t=Math.floor(e/1e3);if(t<60)return t+"s";let i=Math.floor(t/60),a=t%60;return i+"m "+a+"s"}_getStyles(){return`
13689
13800
  :host {
13690
13801
  display: block;
13691
13802
  }
@@ -13848,7 +13959,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
13848
13959
  border-radius: 50%;
13849
13960
  flex-shrink: 0;
13850
13961
  }
13851
- `}render(){let e=this.shadowRoot;if(!e)return;let t=We.map((a,s)=>{let r=this._getStageData(a.id),o=Qe[r.status]||Qe.waiting,n=r.status==="complete",l=r.status==="active",c=r.status==="failed",p=n?'<span class="stage-check">&#10003;</span>':c?'<span class="stage-check">&#10007;</span>':a.icon,u=`
13962
+ `}render(){let e=this.shadowRoot;if(!e)return;let t=tt.map((a,s)=>{let r=this._getStageData(a.id),o=it[r.status]||it.waiting,n=r.status==="complete",l=r.status==="active",c=r.status==="failed",p=n?'<span class="stage-check">&#10003;</span>':c?'<span class="stage-check">&#10007;</span>':a.icon,u=`
13852
13963
  <div class="stage-node">
13853
13964
  <div class="stage-circle ${l?"active":""}"
13854
13965
  style="background: ${o.bgColor}; color: ${o.color}; border: 2px solid ${o.color};">
@@ -13858,12 +13969,12 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
13858
13969
  ${r.duration_ms?`<span class="stage-duration">${this._formatDuration(r.duration_ms)}</span>`:""}
13859
13970
  ${r.errors>0?`<span class="stage-error-count">${r.errors} error${r.errors>1?"s":""}</span>`:""}
13860
13971
  </div>
13861
- `;if(s<We.length-1){let m=this._getStageData(We[s+1].id),g=n,x=l||n&&(m.status==="active"||m.status==="waiting");return u+`
13972
+ `;if(s<tt.length-1){let m=this._getStageData(tt[s+1].id),g=n,x=l||n&&(m.status==="active"||m.status==="waiting");return u+`
13862
13973
  <div class="connector">
13863
13974
  <div class="connector-line ${g?"completed":l?"active":"pending"}"></div>
13864
13975
  ${l?'<div class="flow-dot"></div>':""}
13865
13976
  </div>
13866
- `}return u}).join(""),i=Object.entries(Qe).map(([a,s])=>`<div class="legend-item">
13977
+ `}return u}).join(""),i=Object.entries(it).map(([a,s])=>`<div class="legend-item">
13867
13978
  <div class="legend-dot" style="background: ${s.color};"></div>
13868
13979
  <span>${s.label}</span>
13869
13980
  </div>`).join("");e.innerHTML=`
@@ -13879,7 +13990,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
13879
13990
  ${i}
13880
13991
  </div>
13881
13992
  </div>
13882
- `}};customElements.get("loki-pipeline-view")||customElements.define("loki-pipeline-view",$e);var Ee={episode:{color:"var(--loki-blue, #2F71E3)",shape:"circle",label:"Episode"},pattern:{color:"var(--loki-green, #1FC5A8)",shape:"square",label:"Pattern"},skill:{color:"var(--loki-purple, #553DE9)",shape:"diamond",label:"Skill"}};function Zt(d,e,t){let i=e/2,a=t/2,s=Math.min(i,a)*.65,r=d.length;return d.map((o,n)=>{let l=2*Math.PI*n/r-Math.PI/2,c=o.importance||.5,p=s*(.5+c*.5);return{...o,x:i+p*Math.cos(l),y:a+p*Math.sin(l)}})}var Ce=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._nodes=[],this._edges=[],this._selectedNode=null,this._api=null,this._pollInterval=null,this._graphWidth=600,this._graphHeight=400}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:15e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/v2/memory/graph");if(e!==this._api)return;this._nodes=t.nodes||[],this._edges=t.edges||[]}catch{if(e!==this._api)return;if(this._nodes.length===0){let t=this._getDemoData();this._nodes=t.nodes,this._edges=t.edges}}this.render()}_getDemoData(){return{nodes:[{id:"ep1",type:"episode",label:"Build iteration #12",importance:.8,details:"Completed scaffolding and initial implementation"},{id:"ep2",type:"episode",label:"Code review #5",importance:.6,details:"Quality gate passed with 3/3 approval"},{id:"ep3",type:"episode",label:"Test failure #3",importance:.7,details:"Integration test timeout resolved"},{id:"pt1",type:"pattern",label:"Error recovery",importance:.9,details:"Retry with exponential backoff pattern"},{id:"pt2",type:"pattern",label:"API design",importance:.7,details:"REST endpoint naming conventions"},{id:"pt3",type:"pattern",label:"Test structure",importance:.5,details:"Arrange-Act-Assert with setup helpers"},{id:"sk1",type:"skill",label:"Playwright E2E",importance:.85,details:"Browser automation test writing"},{id:"sk2",type:"skill",label:"FastAPI routing",importance:.6,details:"Python API server development"}],edges:[{source:"ep1",target:"pt1",strength:.8},{source:"ep1",target:"sk1",strength:.6},{source:"ep2",target:"pt2",strength:.9},{source:"ep3",target:"pt1",strength:.7},{source:"ep3",target:"pt3",strength:.5},{source:"pt1",target:"sk2",strength:.4},{source:"pt2",target:"sk2",strength:.7},{source:"pt3",target:"sk1",strength:.6}]}}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_selectNode(e){this._selectedNode=this._selectedNode===e?null:e,this.render()}_bindEvents(){let e=this.shadowRoot;e.querySelectorAll(".graph-node").forEach(t=>{t.addEventListener("click",()=>{this._selectNode(t.dataset.nodeId)})}),e.querySelectorAll(".close-detail").forEach(t=>{t.addEventListener("click",()=>{this._selectedNode=null,this.render()})})}_renderNodeShape(e,t,i){let a=Ee[e.type]||Ee.episode,s=10+(e.importance||.5)*16,r=this._selectedNode===e.id,o=r?"var(--loki-accent, #553DE9)":a.color,n=r?3:1.5,l=this._selectedNode&&!r?.4:1,c;switch(a.shape){case"square":c=`<rect x="${t-s/2}" y="${i-s/2}" width="${s}" height="${s}"
13993
+ `}};customElements.get("loki-pipeline-view")||customElements.define("loki-pipeline-view",Ce);var Se={episode:{color:"var(--loki-blue, #2F71E3)",shape:"circle",label:"Episode"},pattern:{color:"var(--loki-green, #1FC5A8)",shape:"square",label:"Pattern"},skill:{color:"var(--loki-purple, #553DE9)",shape:"diamond",label:"Skill"}};function ci(d,e,t){let i=e/2,a=t/2,s=Math.min(i,a)*.65,r=d.length;return d.map((o,n)=>{let l=2*Math.PI*n/r-Math.PI/2,c=o.importance||.5,p=s*(.5+c*.5);return{...o,x:i+p*Math.cos(l),y:a+p*Math.sin(l)}})}var Ae=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._nodes=[],this._edges=[],this._selectedNode=null,this._api=null,this._pollInterval=null,this._graphWidth=600,this._graphHeight=400}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:15e3,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/v2/memory/graph");if(e!==this._api)return;this._nodes=t.nodes||[],this._edges=t.edges||[]}catch{if(e!==this._api)return;if(this._nodes.length===0){let t=this._getDemoData();this._nodes=t.nodes,this._edges=t.edges}}this.render()}_getDemoData(){return{nodes:[{id:"ep1",type:"episode",label:"Build iteration #12",importance:.8,details:"Completed scaffolding and initial implementation"},{id:"ep2",type:"episode",label:"Code review #5",importance:.6,details:"Quality gate passed with 3/3 approval"},{id:"ep3",type:"episode",label:"Test failure #3",importance:.7,details:"Integration test timeout resolved"},{id:"pt1",type:"pattern",label:"Error recovery",importance:.9,details:"Retry with exponential backoff pattern"},{id:"pt2",type:"pattern",label:"API design",importance:.7,details:"REST endpoint naming conventions"},{id:"pt3",type:"pattern",label:"Test structure",importance:.5,details:"Arrange-Act-Assert with setup helpers"},{id:"sk1",type:"skill",label:"Playwright E2E",importance:.85,details:"Browser automation test writing"},{id:"sk2",type:"skill",label:"FastAPI routing",importance:.6,details:"Python API server development"}],edges:[{source:"ep1",target:"pt1",strength:.8},{source:"ep1",target:"sk1",strength:.6},{source:"ep2",target:"pt2",strength:.9},{source:"ep3",target:"pt1",strength:.7},{source:"ep3",target:"pt3",strength:.5},{source:"pt1",target:"sk2",strength:.4},{source:"pt2",target:"sk2",strength:.7},{source:"pt3",target:"sk1",strength:.6}]}}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_selectNode(e){this._selectedNode=this._selectedNode===e?null:e,this.render()}_bindEvents(){let e=this.shadowRoot;e.querySelectorAll(".graph-node").forEach(t=>{t.addEventListener("click",()=>{this._selectNode(t.dataset.nodeId)})}),e.querySelectorAll(".close-detail").forEach(t=>{t.addEventListener("click",()=>{this._selectedNode=null,this.render()})})}_renderNodeShape(e,t,i){let a=Se[e.type]||Se.episode,s=10+(e.importance||.5)*16,r=this._selectedNode===e.id,o=r?"var(--loki-accent, #553DE9)":a.color,n=r?3:1.5,l=this._selectedNode&&!r?.4:1,c;switch(a.shape){case"square":c=`<rect x="${t-s/2}" y="${i-s/2}" width="${s}" height="${s}"
13883
13994
  rx="3" fill="${a.color}" fill-opacity="0.2" stroke="${o}" stroke-width="${n}" opacity="${l}" />`;break;case"diamond":{let u=s/2;c=`<polygon points="${t},${i-u} ${t+u},${i} ${t},${i+u} ${t-u},${i}"
13884
13995
  fill="${a.color}" fill-opacity="0.2" stroke="${o}" stroke-width="${n}" opacity="${l}" />`;break}default:c=`<circle cx="${t}" cy="${i}" r="${s/2}" fill="${a.color}" fill-opacity="0.2"
13885
13996
  stroke="${o}" stroke-width="${n}" opacity="${l}" />`}let p=`<text x="${t}" y="${i+s/2+14}" text-anchor="middle" font-size="10"
@@ -14040,7 +14151,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
14040
14151
  </div>
14041
14152
  <div class="empty-state">No memory entries to visualize</div>
14042
14153
  </div>
14043
- `;return}let t=this._graphWidth,i=this._graphHeight,a=Zt(this._nodes,t,i),s=this._edges.map(l=>this._renderEdge(l,a)).join(""),r=a.map(l=>this._renderNodeShape(l,l.x,l.y)).join(""),o="";if(this._selectedNode){let l=this._nodes.find(c=>c.id===this._selectedNode);if(l){let c=Ee[l.type]||Ee.episode;o=`
14154
+ `;return}let t=this._graphWidth,i=this._graphHeight,a=ci(this._nodes,t,i),s=this._edges.map(l=>this._renderEdge(l,a)).join(""),r=a.map(l=>this._renderNodeShape(l,l.x,l.y)).join(""),o="";if(this._selectedNode){let l=this._nodes.find(c=>c.id===this._selectedNode);if(l){let c=Se[l.type]||Se.episode;o=`
14044
14155
  <div class="detail-panel">
14045
14156
  <div class="detail-header">
14046
14157
  <span class="detail-title">${this._escapeHtml(l.label)}</span>
@@ -14049,7 +14160,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
14049
14160
  </div>
14050
14161
  <div class="detail-body">${this._escapeHtml(l.details||"No details available")}</div>
14051
14162
  </div>
14052
- `}}let n=Object.entries(Ee).map(([,l])=>{let c;return l.shape==="circle"?c=`<div class="legend-circle" style="border-color: ${l.color};"></div>`:l.shape==="square"?c=`<div class="legend-square" style="border-color: ${l.color};"></div>`:c=`<div class="legend-diamond" style="border-color: ${l.color};"></div>`,`<div class="legend-item">
14163
+ `}}let n=Object.entries(Se).map(([,l])=>{let c;return l.shape==="circle"?c=`<div class="legend-circle" style="border-color: ${l.color};"></div>`:l.shape==="square"?c=`<div class="legend-square" style="border-color: ${l.color};"></div>`:c=`<div class="legend-diamond" style="border-color: ${l.color};"></div>`,`<div class="legend-item">
14053
14164
  <div class="legend-shape">${c}</div>
14054
14165
  <span>${l.label}</span>
14055
14166
  </div>`}).join("");e.innerHTML=`
@@ -14067,7 +14178,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
14067
14178
  </div>
14068
14179
  <div class="legend">${n}</div>
14069
14180
  </div>
14070
- `,this._bindEvents()}};customElements.get("loki-memory-graph")||customElements.define("loki-memory-graph",Ce);var Xe={planning:{color:"var(--loki-blue, #2F71E3)",label:"Planning"},building:{color:"var(--loki-green, #1FC5A8)",label:"Building"},implementation:{color:"var(--loki-green, #1FC5A8)",label:"Building"},testing:{color:"var(--loki-purple, #553DE9)",label:"Testing"},review:{color:"var(--loki-yellow, #D4A03C)",label:"Review"},overhead:{color:"var(--loki-text-muted, #939084)",label:"Overhead"}},Se=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._phases=[],this._budget=null,this._totalCost=0,this._hoveredPhase=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:1e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/v2/cost/breakdown");if(e!==this._api)return;this._phases=t.phases||[],this._budget=t.budget_usd||null,this._totalCost=t.total_usd||this._phases.reduce((i,a)=>i+(a.cost_usd||0),0)}catch{if(e!==this._api)return;this._phases.length===0&&(this._phases=this._getDemoData(),this._budget=10,this._totalCost=this._phases.reduce((t,i)=>t+i.cost_usd,0))}this.render()}_getDemoData(){return[{phase:"planning",cost_usd:.85,tokens:12400},{phase:"building",cost_usd:3.2,tokens:68500},{phase:"testing",cost_usd:1.45,tokens:31200},{phase:"review",cost_usd:.9,tokens:18800},{phase:"overhead",cost_usd:.35,tokens:5600}]}_formatCost(e){return e==null?"--":"$"+e.toFixed(2)}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_bindEvents(){this.shadowRoot.querySelectorAll(".waterfall-bar").forEach(t=>{t.addEventListener("mouseenter",()=>{this._hoveredPhase=t.dataset.phase,this._updateTooltip(t)}),t.addEventListener("mouseleave",()=>{this._hoveredPhase=null,this._hideTooltip()})})}_updateTooltip(e){let t=this.shadowRoot.querySelector(".tooltip");if(!t)return;let i=this._phases.find(o=>o.phase===this._hoveredPhase);if(!i)return;let a=Xe[i.phase]||{label:i.phase};t.innerHTML=`<strong>${this._escapeHtml(a.label)}</strong>: ${this._formatCost(i.cost_usd)}`,t.style.display="block";let s=e.getBoundingClientRect(),r=this.shadowRoot.querySelector(".chart-area").getBoundingClientRect();t.style.left=s.left-r.left+s.width/2+"px",t.style.top=s.top-r.top-30+"px"}_hideTooltip(){let e=this.shadowRoot.querySelector(".tooltip");e&&(e.style.display="none")}_getStyles(){return`
14181
+ `,this._bindEvents()}};customElements.get("loki-memory-graph")||customElements.define("loki-memory-graph",Ae);var at={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"}},Te=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._phases=[],this._budget=null,this._totalCost=null,this._hoveredPhase=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:1e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/v2/cost/breakdown");if(e!==this._api)return;if(this._phases=t.phases||[],this._budget=t.budget_usd||null,t.total_usd!=null)this._totalCost=t.total_usd;else{let i=this._phases.filter(a=>a.cost_usd!=null);this._totalCost=i.length?i.reduce((a,s)=>a+s.cost_usd,0):null}}catch{if(e!==this._api)return;this._phases.length===0&&(this._phases=this._getDemoData(),this._budget=10,this._totalCost=this._phases.reduce((t,i)=>t+i.cost_usd,0))}this.render()}_getDemoData(){return[{phase:"planning",cost_usd:.85,tokens:12400},{phase:"building",cost_usd:3.2,tokens:68500},{phase:"testing",cost_usd:1.45,tokens:31200},{phase:"review",cost_usd:.9,tokens:18800},{phase:"overhead",cost_usd:.35,tokens:5600}]}_formatCost(e){return I(e)}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_bindEvents(){this.shadowRoot.querySelectorAll(".waterfall-bar").forEach(t=>{t.addEventListener("mouseenter",()=>{this._hoveredPhase=t.dataset.phase,this._updateTooltip(t)}),t.addEventListener("mouseleave",()=>{this._hoveredPhase=null,this._hideTooltip()})})}_updateTooltip(e){let t=this.shadowRoot.querySelector(".tooltip");if(!t)return;let i=this._phases.find(o=>o.phase===this._hoveredPhase);if(!i)return;let a=at[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`
14071
14182
  :host {
14072
14183
  display: block;
14073
14184
  }
@@ -14257,7 +14368,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
14257
14368
  </div>
14258
14369
  <div class="empty-state">Cost details will appear once a build starts running.</div>
14259
14370
  </div>
14260
- `;return}let t=Math.max(...this._phases.map(l=>l.cost_usd||0),.01),i=160,a=this._budget?Math.max(t,this._budget):t,s=this._budget?this._budget/a*i:null,r=this._phases.map(l=>{let c=Xe[l.phase]||{color:"var(--loki-text-muted)",label:l.phase},p=(l.cost_usd||0)/a*i,u=this._hoveredPhase===l.phase;return`
14371
+ `;return}let t=Math.max(...this._phases.map(l=>l.cost_usd||0),.01),i=160,a=this._budget?Math.max(t,this._budget):t,s=this._budget?this._budget/a*i:null,r=this._phases.map(l=>{let c=at[l.phase]||{color:"var(--loki-text-muted)",label:l.phase},p=(l.cost_usd||0)/a*i,u=this._hoveredPhase===l.phase;return`
14261
14372
  <div class="bar-group">
14262
14373
  <span class="bar-value">${this._formatCost(l.cost_usd)}</span>
14263
14374
  <div class="waterfall-bar" data-phase="${this._escapeHtml(l.phase)}"
@@ -14269,7 +14380,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
14269
14380
  <div class="budget-line" style="bottom: ${s+40}px;">
14270
14381
  <span class="budget-label">Budget: ${this._formatCost(this._budget)}</span>
14271
14382
  </div>
14272
- `:"",n=this._phases.map(l=>{let c=Xe[l.phase]||{color:"var(--loki-text-muted)",label:l.phase},p=this._totalCost>0?(l.cost_usd/this._totalCost*100).toFixed(0):0;return`<div class="summary-item">
14383
+ `:"",n=this._phases.map(l=>{let c=at[l.phase]||{color:"var(--loki-text-muted)",label:l.phase},p=this._totalCost>0?(l.cost_usd/this._totalCost*100).toFixed(0):0;return`<div class="summary-item">
14273
14384
  <div class="summary-dot" style="background: ${c.color};"></div>
14274
14385
  <span class="summary-label">${this._escapeHtml(c.label)}</span>
14275
14386
  <span class="summary-value">${this._formatCost(l.cost_usd)} (${p}%)</span>
@@ -14291,7 +14402,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
14291
14402
  </div>
14292
14403
  </div>
14293
14404
  </div>
14294
- `,this._bindEvents()}};customElements.get("loki-cost-waterfall")||customElements.define("loki-cost-waterfall",Se);var ei={1:{bg:"rgba(212, 160, 60, 0.15)",border:"#D4A03C",label:"1st"},2:{bg:"rgba(147, 144, 132, 0.15)",border:"#939084",label:"2nd"},3:{bg:"rgba(196, 130, 91, 0.15)",border:"#C4825B",label:"3rd"}},Ae=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._agents=[],this._expandedAgent=null,this._api=null,this._pollInterval=null,this._previousRanks={}}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:1e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/v2/agents/leaderboard");if(e!==this._api)return;let i=t.agents||[],a={};i.forEach((s,r)=>{a[s.type||s.name]=r+1}),this._previousRanks={...this._currentRanks||{}},this._currentRanks=a,this._agents=i}catch{if(e!==this._api)return;this._agents.length===0&&(this._agents=this._getDemoData(),this._currentRanks={},this._agents.forEach((t,i)=>{this._currentRanks[t.type]=i+1}),this._previousRanks={})}this.render()}_getDemoData(){return[{type:"code-generator",name:"Code Generator",tasks:24,quality:9.2,speed:"fast",cost_usd:2.4},{type:"test-writer",name:"Test Writer",tasks:18,quality:9,speed:"fast",cost_usd:1.2},{type:"code-reviewer",name:"Code Reviewer",tasks:15,quality:8.8,speed:"medium",cost_usd:1.8},{type:"architect",name:"Architect",tasks:8,quality:9.5,speed:"slow",cost_usd:3.1},{type:"debugger",name:"Debugger",tasks:12,quality:8.5,speed:"fast",cost_usd:.95},{type:"doc-writer",name:"Documentation",tasks:10,quality:8.3,speed:"fast",cost_usd:.6}]}_getRankChange(e){let t=this._currentRanks?.[e],i=this._previousRanks?.[e];return t==null||i==null?0:i-t}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_toggleAgent(e){this._expandedAgent=this._expandedAgent===e?null:e,this.render()}_bindEvents(){this.shadowRoot.querySelectorAll(".agent-row").forEach(t=>{t.addEventListener("click",()=>{this._toggleAgent(t.dataset.agent)})})}_getQualityColor(e){return e>=9?"var(--loki-green, #1FC5A8)":e>=8?"var(--loki-blue, #2F71E3)":e>=7?"var(--loki-yellow, #D4A03C)":"var(--loki-red, #C45B5B)"}_getSpeedLabel(e){return e==="fast"?{label:"Fast",color:"var(--loki-green, #1FC5A8)"}:e==="medium"?{label:"Medium",color:"var(--loki-yellow, #D4A03C)"}:{label:"Slow",color:"var(--loki-red, #C45B5B)"}}_getStyles(){return`
14405
+ `,this._bindEvents()}};customElements.get("loki-cost-waterfall")||customElements.define("loki-cost-waterfall",Te);var pi={1:{bg:"rgba(212, 160, 60, 0.15)",border:"#D4A03C",label:"1st"},2:{bg:"rgba(147, 144, 132, 0.15)",border:"#939084",label:"2nd"},3:{bg:"rgba(196, 130, 91, 0.15)",border:"#C4825B",label:"3rd"}},Le=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._agents=[],this._expandedAgent=null,this._api=null,this._pollInterval=null,this._previousRanks={}}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadData(),this._startPolling()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadData()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_startPolling(){this._poll=b({loadFn:()=>this._loadData(),intervalMs:1e4,element:this,immediate:!1})}_stopPolling(){this._poll&&(this._poll.stop(),this._poll=null)}async _loadData(){let e=this._api;try{let t=await e._get("/api/v2/agents/leaderboard");if(e!==this._api)return;let i=t.agents||[],a={};i.forEach((s,r)=>{a[s.type||s.name]=r+1}),this._previousRanks={...this._currentRanks||{}},this._currentRanks=a,this._agents=i}catch{if(e!==this._api)return;this._agents.length===0&&(this._agents=this._getDemoData(),this._currentRanks={},this._agents.forEach((t,i)=>{this._currentRanks[t.type]=i+1}),this._previousRanks={})}this.render()}_getDemoData(){return[{type:"code-generator",name:"Code Generator",tasks:24,quality:9.2,speed:"fast",cost_usd:2.4},{type:"test-writer",name:"Test Writer",tasks:18,quality:9,speed:"fast",cost_usd:1.2},{type:"code-reviewer",name:"Code Reviewer",tasks:15,quality:8.8,speed:"medium",cost_usd:1.8},{type:"architect",name:"Architect",tasks:8,quality:9.5,speed:"slow",cost_usd:3.1},{type:"debugger",name:"Debugger",tasks:12,quality:8.5,speed:"fast",cost_usd:.95},{type:"doc-writer",name:"Documentation",tasks:10,quality:8.3,speed:"fast",cost_usd:.6}]}_getRankChange(e){let t=this._currentRanks?.[e],i=this._previousRanks?.[e];return t==null||i==null?0:i-t}_escapeHtml(e){return e?String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}_toggleAgent(e){this._expandedAgent=this._expandedAgent===e?null:e,this.render()}_bindEvents(){this.shadowRoot.querySelectorAll(".agent-row").forEach(t=>{t.addEventListener("click",()=>{this._toggleAgent(t.dataset.agent)})})}_getQualityColor(e){return e>=9?"var(--loki-green, #1FC5A8)":e>=8?"var(--loki-blue, #2F71E3)":e>=7?"var(--loki-yellow, #D4A03C)":"var(--loki-red, #C45B5B)"}_getSpeedLabel(e){return e==="fast"?{label:"Fast",color:"var(--loki-green, #1FC5A8)"}:e==="medium"?{label:"Medium",color:"var(--loki-yellow, #D4A03C)"}:{label:"Slow",color:"var(--loki-red, #C45B5B)"}}_getStyles(){return`
14295
14406
  :host {
14296
14407
  display: block;
14297
14408
  }
@@ -14504,19 +14615,19 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
14504
14615
  </div>
14505
14616
  <div class="empty-state">No agent performance data available</div>
14506
14617
  </div>
14507
- `;return}let t=this._agents.map((i,a)=>{let s=a+1,r=ei[s],o=i.type||i.name,n=this._getRankChange(o),l=this._expandedAgent===o,c=this._getQualityColor(i.quality),p=this._getSpeedLabel(i.speed),u=(i.quality||0)/10*100,m;r?m=`<div class="rank-badge" style="background: ${r.bg}; color: ${r.border};">${s}</div>`:m=`<span class="rank-number" style="color: var(--loki-text-muted);">${s}</span>`;let g="";n>0?g=`<span class="rank-change rank-up">+${n}</span>`:n<0&&(g=`<span class="rank-change rank-down">${n}</span>`);let x=l?`
14618
+ `;return}let t=this._agents.map((i,a)=>{let s=a+1,r=pi[s],o=i.type||i.name,n=this._getRankChange(o),l=this._expandedAgent===o,c=this._getQualityColor(i.quality),p=this._getSpeedLabel(i.speed),u=(i.quality??0)/10*100,m;r?m=`<div class="rank-badge" style="background: ${r.bg}; color: ${r.border};">${s}</div>`:m=`<span class="rank-number" style="color: var(--loki-text-muted);">${s}</span>`;let g="";n>0?g=`<span class="rank-change rank-up">+${n}</span>`:n<0&&(g=`<span class="rank-change rank-down">${n}</span>`);let x=l?`
14508
14619
  <div class="agent-detail">
14509
14620
  <div class="detail-metric">
14510
14621
  <span class="detail-label">Total Cost</span>
14511
- <span class="detail-value">$${(i.cost_usd||0).toFixed(2)}</span>
14622
+ <span class="detail-value">${I(i.cost_usd)}</span>
14512
14623
  </div>
14513
14624
  <div class="detail-metric">
14514
14625
  <span class="detail-label">Avg Time/Task</span>
14515
- <span class="detail-value">${i.avg_time||"--"}</span>
14626
+ <span class="detail-value">${i.avg_time||Fe}</span>
14516
14627
  </div>
14517
14628
  <div class="detail-metric">
14518
14629
  <span class="detail-label">Success Rate</span>
14519
- <span class="detail-value">${i.success_rate!=null?i.success_rate+"%":"--"}</span>
14630
+ <span class="detail-value">${rt(i.success_rate)}</span>
14520
14631
  </div>
14521
14632
  </div>
14522
14633
  `:"";return`
@@ -14530,7 +14641,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
14530
14641
  <div class="metric-cell">${i.tasks||0}</div>
14531
14642
  <div class="metric-cell">
14532
14643
  <div class="quality-score">
14533
- <span style="color: ${c};">${(i.quality||0).toFixed(1)}</span>
14644
+ <span style="color: ${c};">${q(i.quality,k=>k.toFixed(1))}</span>
14534
14645
  <div class="quality-bar"><div class="quality-fill" style="width: ${u}%; background: ${c};"></div></div>
14535
14646
  </div>
14536
14647
  </div>
@@ -14557,7 +14668,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
14557
14668
  ${t}
14558
14669
  </div>
14559
14670
  </div>
14560
- `,this._bindEvents()}};customElements.get("loki-agent-leaderboard")||customElements.define("loki-agent-leaderboard",Ae);var bt=50,Te=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._api=null,this._statusLoading=!1,this._statusError=null,this._status=null,this._eventsLoading=!1,this._eventsError=null,this._events=[],this._eventsSource=null,this._eventsCount=0,this._lookupId="",this._lookupLoading=!1,this._lookupError=null,this._lookupResult=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){if(t!==i)switch(e){case"api-url":this._api&&(this._api=h({baseUrl:i}),this._loadStatus());break;case"theme":this._applyTheme(),this.render();break}}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_stopPolling(){}async _loadStatus(){let e=this._api;this._statusLoading=!0,this._statusError=null,this.render();try{let t=await e.get("/api/managed/status");if(e!==this._api)return;this._status=t}catch(t){if(e!==this._api)return;this._statusError=t&&t.message?t.message:"Failed to load managed status",this._status=null}finally{this._statusLoading=!1}this._status&&this._status.enabled?await this._loadEvents():this.render()}async _loadEvents(e=bt){let t=this._api;this._eventsLoading=!0,this._eventsError=null,this.render();try{let i=await t.get("/api/managed/events?limit="+encodeURIComponent(e));if(t!==this._api)return;Array.isArray(i)?(this._events=i,this._eventsCount=i.length,this._eventsSource=null):i&&typeof i=="object"?(this._events=Array.isArray(i.events)?i.events:[],this._eventsCount=typeof i.count=="number"?i.count:this._events.length,this._eventsSource=i.source||null):(this._events=[],this._eventsCount=0,this._eventsSource=null)}catch(i){if(t!==this._api)return;this._eventsError=i&&i.message?i.message:"Failed to load managed events",this._events=[],this._eventsCount=0,this._eventsSource=null}finally{this._eventsLoading=!1,this.render()}}async _lookupMemoryVersion(){let e=(this._lookupId||"").trim();if(!e){this._lookupError="Enter a memory ID to look up",this._lookupResult=null,this.render();return}let t=this._api;this._lookupLoading=!0,this._lookupError=null,this._lookupResult=null,this.render();try{let i="/api/managed/memory_versions/"+encodeURIComponent(e),a=await t.get(i);if(t!==this._api)return;this._lookupResult=a}catch(i){if(t!==this._api)return;this._lookupError=i&&i.message?i.message:"Failed to load memory versions",this._lookupResult=null}finally{this._lookupLoading=!1,this.render()}}_onLookupInput(e){this._lookupId=e&&e.target?e.target.value:""}_onLookupKeyDown(e){e&&e.key==="Enter"&&(e.preventDefault(),this._lookupMemoryVersion())}_attachEventHandlers(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector("#refresh-status-btn");t&&t.addEventListener("click",()=>this._loadStatus());let i=e.querySelector("#refresh-events-btn");i&&i.addEventListener("click",()=>this._loadEvents());let a=e.querySelector("#lookup-input");a&&(a.addEventListener("input",r=>this._onLookupInput(r)),a.addEventListener("keydown",r=>this._onLookupKeyDown(r)));let s=e.querySelector("#lookup-btn");s&&s.addEventListener("click",()=>this._lookupMemoryVersion())}_escapeHtml(e){return e==null?"":String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}_formatTimestamp(e){if(!e)return"";let t;return typeof e=="number"?t=new Date(e>1e12?e:e*1e3):t=new Date(e),Number.isNaN(t.getTime())?String(e):t.toISOString().replace("T"," ").replace(/\.\d+Z$/,"Z")}_renderStatusSection(){if(this._statusLoading)return'<div class="status-row muted">Loading managed memory status...</div>';if(this._statusError)return`
14671
+ `,this._bindEvents()}};customElements.get("loki-agent-leaderboard")||customElements.define("loki-agent-leaderboard",Le);var At=50,ze=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._api=null,this._statusLoading=!1,this._statusError=null,this._status=null,this._eventsLoading=!1,this._eventsError=null,this._events=[],this._eventsSource=null,this._eventsCount=0,this._lookupId="",this._lookupLoading=!1,this._lookupError=null,this._lookupResult=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadStatus()}disconnectedCallback(){super.disconnectedCallback(),this._stopPolling()}attributeChangedCallback(e,t,i){if(t!==i)switch(e){case"api-url":this._api&&(this._api=h({baseUrl:i}),this._loadStatus());break;case"theme":this._applyTheme(),this.render();break}}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_stopPolling(){}async _loadStatus(){let e=this._api;this._statusLoading=!0,this._statusError=null,this.render();try{let t=await e.get("/api/managed/status");if(e!==this._api)return;this._status=t}catch(t){if(e!==this._api)return;this._statusError=t&&t.message?t.message:"Failed to load managed status",this._status=null}finally{this._statusLoading=!1}this._status&&this._status.enabled?await this._loadEvents():this.render()}async _loadEvents(e=At){let t=this._api;this._eventsLoading=!0,this._eventsError=null,this.render();try{let i=await t.get("/api/managed/events?limit="+encodeURIComponent(e));if(t!==this._api)return;Array.isArray(i)?(this._events=i,this._eventsCount=i.length,this._eventsSource=null):i&&typeof i=="object"?(this._events=Array.isArray(i.events)?i.events:[],this._eventsCount=typeof i.count=="number"?i.count:this._events.length,this._eventsSource=i.source||null):(this._events=[],this._eventsCount=0,this._eventsSource=null)}catch(i){if(t!==this._api)return;this._eventsError=i&&i.message?i.message:"Failed to load managed events",this._events=[],this._eventsCount=0,this._eventsSource=null}finally{this._eventsLoading=!1,this.render()}}async _lookupMemoryVersion(){let e=(this._lookupId||"").trim();if(!e){this._lookupError="Enter a memory ID to look up",this._lookupResult=null,this.render();return}let t=this._api;this._lookupLoading=!0,this._lookupError=null,this._lookupResult=null,this.render();try{let i="/api/managed/memory_versions/"+encodeURIComponent(e),a=await t.get(i);if(t!==this._api)return;this._lookupResult=a}catch(i){if(t!==this._api)return;this._lookupError=i&&i.message?i.message:"Failed to load memory versions",this._lookupResult=null}finally{this._lookupLoading=!1,this.render()}}_onLookupInput(e){this._lookupId=e&&e.target?e.target.value:""}_onLookupKeyDown(e){e&&e.key==="Enter"&&(e.preventDefault(),this._lookupMemoryVersion())}_attachEventHandlers(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector("#refresh-status-btn");t&&t.addEventListener("click",()=>this._loadStatus());let i=e.querySelector("#refresh-events-btn");i&&i.addEventListener("click",()=>this._loadEvents());let a=e.querySelector("#lookup-input");a&&(a.addEventListener("input",r=>this._onLookupInput(r)),a.addEventListener("keydown",r=>this._onLookupKeyDown(r)));let s=e.querySelector("#lookup-btn");s&&s.addEventListener("click",()=>this._lookupMemoryVersion())}_escapeHtml(e){return e==null?"":String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}_formatTimestamp(e){if(!e)return"";let t;return typeof e=="number"?t=new Date(e>1e12?e:e*1e3):t=new Date(e),Number.isNaN(t.getTime())?String(e):t.toISOString().replace("T"," ").replace(/\.\d+Z$/,"Z")}_renderStatusSection(){if(this._statusLoading)return'<div class="status-row muted">Loading managed memory status...</div>';if(this._statusError)return`
14561
14672
  <div class="error-banner" role="alert">
14562
14673
  <strong>Status error:</strong>
14563
14674
  <span>${this._escapeHtml(this._statusError)}</span>
@@ -14936,7 +15047,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
14936
15047
  ${t?`
14937
15048
  <div class="section">
14938
15049
  <div class="panel-header">
14939
- <h3 class="section-title">Recent events (limit ${bt})</h3>
15050
+ <h3 class="section-title">Recent events (limit ${At})</h3>
14940
15051
  <button id="refresh-events-btn" class="btn" type="button">Refresh events</button>
14941
15052
  </div>
14942
15053
  ${this._renderEventsSection()}
@@ -14948,7 +15059,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
14948
15059
  </div>
14949
15060
  `:this._statusError?"":this._renderDisabledNotice()}
14950
15061
  </div>
14951
- `,this._attachEventHandlers()}};customElements.get("loki-managed-memory-panel")||customElements.define("loki-managed-memory-panel",Te);var Le=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._items=[],this._loading=!1,this._error=null,this._activeFile=null,this._activeBody=null,this._activeBodyError=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._ensureMarkdownStyles(),this._setupApi(),this._loadList(),this._poll=b({loadFn:()=>this._loadList(),intervalMs:1e4,element:this,immediate:!1})}disconnectedCallback(){super.disconnectedCallback(),this._poll&&(this._poll.stop(),this._poll=null)}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadList()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||(typeof window<"u"?window.location.origin:"");this._api=h({baseUrl:e})}async _loadList(){let e=this._api;this._loading=!0,this._error=null;try{let t=await e.get("/api/escalations");if(e!==this._api)return;this._items=Array.isArray(t&&t.escalations)?t.escalations:[]}catch(t){if(e!==this._api)return;this._error=t&&t.message?t.message:String(t),this._items=[]}finally{this._loading=!1,this.render()}}async _openFile(e){let t=this._api;this._activeFile=e,this._activeBody=null,this._activeBodyError=null,this.render();try{let i=(t.baseUrl||"")+"/api/escalations/"+encodeURIComponent(e),a=await fetch(i,{credentials:"include"});if(!a.ok)throw new Error("HTTP "+a.status);let s=await a.text();if(t!==this._api)return;this._activeBody=s}catch(i){if(t!==this._api)return;this._activeBodyError=i&&i.message?i.message:String(i)}this.render()}_closeFile(){this._activeFile=null,this._activeBody=null,this._activeBodyError=null,this.render()}_formatSize(e){return typeof e!="number"?"--":e<1024?e+" B":e<1024*1024?(e/1024).toFixed(1)+" KB":(e/(1024*1024)).toFixed(1)+" MB"}_formatDate(e){if(!e)return"--";try{let t=new Date(e);return isNaN(t.getTime())?e:t.toLocaleString()}catch{return e}}_ensureMarkdownStyles(){if(typeof document>"u"||!document.head||document.getElementById("loki-markdown-styles"))return;let e=document.createElement("style");e.id="loki-markdown-styles",e.textContent=L,document.head.appendChild(e)}_escapeHtml(e){return e==null?"":String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}render(){let e=this.shadowRoot||this;if(!e)return;let t=`
15062
+ `,this._attachEventHandlers()}};customElements.get("loki-managed-memory-panel")||customElements.define("loki-managed-memory-panel",ze);var De=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._items=[],this._loading=!1,this._error=null,this._activeFile=null,this._activeBody=null,this._activeBodyError=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._ensureMarkdownStyles(),this._setupApi(),this._loadList(),this._poll=b({loadFn:()=>this._loadList(),intervalMs:1e4,element:this,immediate:!1})}disconnectedCallback(){super.disconnectedCallback(),this._poll&&(this._poll.stop(),this._poll=null)}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._loadList()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||(typeof window<"u"?window.location.origin:"");this._api=h({baseUrl:e})}async _loadList(){let e=this._api;this._loading=!0,this._error=null;try{let t=await e.get("/api/escalations");if(e!==this._api)return;this._items=Array.isArray(t&&t.escalations)?t.escalations:[]}catch(t){if(e!==this._api)return;this._error=t&&t.message?t.message:String(t),this._items=[]}finally{this._loading=!1,this.render()}}async _openFile(e){let t=this._api;this._activeFile=e,this._activeBody=null,this._activeBodyError=null,this.render();try{let i=(t.baseUrl||"")+"/api/escalations/"+encodeURIComponent(e),a=await fetch(i,{credentials:"include"});if(!a.ok)throw new Error("HTTP "+a.status);let s=await a.text();if(t!==this._api)return;this._activeBody=s}catch(i){if(t!==this._api)return;this._activeBodyError=i&&i.message?i.message:String(i)}this.render()}_closeFile(){this._activeFile=null,this._activeBody=null,this._activeBodyError=null,this.render()}_formatSize(e){return typeof e!="number"?"--":e<1024?e+" B":e<1024*1024?(e/1024).toFixed(1)+" KB":(e/(1024*1024)).toFixed(1)+" MB"}_formatDate(e){if(!e)return"--";try{let t=new Date(e);return isNaN(t.getTime())?e:t.toLocaleString()}catch{return e}}_ensureMarkdownStyles(){if(typeof document>"u"||!document.head||document.getElementById("loki-markdown-styles"))return;let e=document.createElement("style");e.id="loki-markdown-styles",e.textContent=L,document.head.appendChild(e)}_escapeHtml(e){return e==null?"":String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}render(){let e=this.shadowRoot||this;if(!e)return;let t=`
14952
15063
  <style>
14953
15064
  :host { display: block; }
14954
15065
  .esc-wrapper {
@@ -15024,7 +15135,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
15024
15135
  white-space: pre-wrap;
15025
15136
  }
15026
15137
  </style>
15027
- `,i="";this._loading&&this._items.length===0?i='<div class="esc-empty">Loading escalations...</div>':this._error?i='<div class="esc-error">Failed to load escalations: '+this._escapeHtml(this._error)+"</div>":!this._items||this._items.length===0?i='<div class="esc-empty">No handoff notes yet. If a build needs your attention, its notes will appear here.</div>':i='<div class="esc-list">'+this._items.map(n=>{let l=this._escapeHtml(n.filename||""),c=this._escapeHtml(this._formatSize(n.size_bytes)),p=this._escapeHtml(this._formatDate(n.modified_at));return'<div class="esc-item" data-filename="'+l+'"><span class="esc-name">'+l+'</span><span class="esc-meta">'+c+" &middot; "+p+"</span></div>"}).join("")+"</div>";let a="";if(this._activeFile){let o=this._escapeHtml(this._activeFile),n;this._activeBodyError?n='<div class="esc-error">Failed to load: '+this._escapeHtml(this._activeBodyError)+"</div>":this._activeBody===null?n='<div class="esc-body">Loading '+o+"...</div>":n='<div class="esc-body md-body">'+C(this._activeBody)+"</div>",a='<div class="esc-viewer"><div class="esc-viewer-header"><span class="esc-name">'+o+'</span><button class="esc-close-btn" data-action="close">Close</button></div>'+n+"</div>"}e.innerHTML=t+'<div class="esc-wrapper"><div class="esc-explain">Handoff/escalation documents written under .loki/escalations/. Click an entry to view its contents.</div>'+i+a+"</div>",e.querySelectorAll(".esc-item").forEach(o=>{o.addEventListener("click",()=>{let n=o.getAttribute("data-filename");n&&this._openFile(n)})});let r=e.querySelector('.esc-close-btn[data-action="close"]');r&&r.addEventListener("click",()=>this._closeFile())}};typeof customElements<"u"&&!customElements.get("loki-escalations")&&customElements.define("loki-escalations",Le);var ze=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._transcripts=[],this._hookEvents=[],this._loading=!1,this._error=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._load(),this._poll=b({loadFn:()=>this._load(),intervalMs:3e4,element:this,immediate:!1})}disconnectedCallback(){super.disconnectedCallback(),this._poll&&(this._poll.stop(),this._poll=null)}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._load()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||(typeof window<"u"?window.location.origin:"");this._api=h({baseUrl:e})}async _load(){this._loading=!0,this._error=null;let e=this._api;try{let t=await e.get("/api/council/transcripts?limit=10");if(e!==this._api)return;this._transcripts=Array.isArray(t&&t.transcripts)?t.transcripts:[]}catch(t){if(e!==this._api)return;this._error=t&&t.message?t.message:String(t),this._transcripts=[]}try{let t=await e.get("/api/council/transcripts?limit=20&type_prefix=claude_hook_");if(e!==this._api)return;this._hookEvents=Array.isArray(t&&t.hook_events)?t.hook_events:[]}catch{if(e!==this._api)return;this._hookEvents=[]}finally{this._loading=!1,this.render()}}_escapeHtml(e){return e==null?"":String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}_formatTimestamp(e){if(!e)return"--";try{let t=new Date(e);return isNaN(t.getTime())?e:t.toLocaleString()}catch{return e}}_truncate(e,t){if(!e)return"";let i=String(e);return i.length>t?i.slice(0,t)+"...":i}_verdictBadgeHtml(e){let t=String(e||"").toUpperCase();return t==="APPROVE"?'<span class="ct-badge ct-badge-approve">APPROVE</span>':t==="REJECT"?'<span class="ct-badge ct-badge-reject">REJECT</span>':t==="CANNOT_VALIDATE"?'<span class="ct-badge ct-badge-cannot">CANNOT_VALIDATE</span>':'<span class="ct-badge ct-badge-unknown">'+this._escapeHtml(t||"UNKNOWN")+"</span>"}_outcomeBadgeHtml(e){let t=String(e||"").toUpperCase();return t==="APPROVED"?'<span class="ct-badge ct-badge-approve">APPROVED</span>':t==="REJECTED"?'<span class="ct-badge ct-badge-reject">REJECTED</span>':t==="BLOCKED_BY_GATE"?'<span class="ct-badge ct-badge-blocked">BLOCKED BY GATE</span>':'<span class="ct-badge ct-badge-unknown">'+this._escapeHtml(t||"UNKNOWN")+"</span>"}_voterRowHtml(e,t){let i=e.is_contrarian===!0,a=i&&t===!0,s="ct-voter-row";i&&(s+=" ct-voter-contrarian"),a&&(s+=" ct-voter-flipped");let r=this._escapeHtml(e.name||"unknown"),o=this._verdictBadgeHtml(e.verdict),n=this._escapeHtml(this._truncate(e.reasoning,300)),l="",c="";a?(l='<span class="ct-badge ct-badge-override">OVERRIDE</span>',c=`<div class="ct-flip-caption">Devil's Advocate flipped this outcome</div>`):i&&e.triggered&&(l=`<span class="ct-badge ct-badge-da">DEVIL'S ADVOCATE</span>`);let p="";i&&Array.isArray(e.challenges)&&e.challenges.length>0&&(p='<ul class="ct-challenges">'+e.challenges.map(g=>"<li>"+this._escapeHtml(String(g))+"</li>").join("")+"</ul>");let u="";return Array.isArray(e.issues)&&e.issues.length>0&&(u='<ul class="ct-issues">'+e.issues.map(g=>{let x=this._escapeHtml(g.severity||""),k=this._escapeHtml(g.description||"");return'<li><span class="ct-issue-sev ct-issue-sev-'+x.toLowerCase()+'">'+x+"</span> "+k+"</li>"}).join("")+"</ul>"),'<div class="'+s+'"><div class="ct-voter-header"><span class="ct-voter-name">'+r+"</span>"+o+l+"</div>"+(n?'<div class="ct-voter-reason">'+n+"</div>":"")+p+u+c+"</div>"}_transcriptCardHtml(e){let t=this._escapeHtml(String(e.iteration||"--")),i=this._escapeHtml(this._formatTimestamp(e.timestamp)),a=this._escapeHtml(this._truncate(e.task_or_prd,200)),s=this._outcomeBadgeHtml(e.outcome),r=Array.isArray(e.voters)?e.voters:[],o=r.filter(g=>!g.is_contrarian),n=r.filter(g=>g.is_contrarian),l=o.map(g=>this._voterRowHtml(g,!1)).join(""),c="";e.contrarian_triggered&&(c='<div class="ct-contrarian-section"><div class="ct-section-label">Anti-Sycophancy Check</div>'+n.map(x=>this._voterRowHtml(x,e.contrarian_flipped)).join("")+"</div>");let p=typeof e.approve_count=="number"?e.approve_count:"--",u=typeof e.reject_count=="number"?e.reject_count:"--",m=typeof e.threshold=="number"?e.threshold:"--";return'<div class="ct-card"><div class="ct-card-header"><div class="ct-card-meta"><span class="ct-iter-label">Iteration '+t+'</span><span class="ct-ts">'+i+"</span></div>"+s+"</div>"+(a?'<div class="ct-prd-preview">'+a+"</div>":"")+'<div class="ct-tally">Approve: '+p+" &middot; Reject: "+u+" &middot; Threshold: "+m+'</div><div class="ct-voters">'+l+"</div>"+c+"</div>"}render(){let e=this.shadowRoot||this;if(!e)return;let t=`
15138
+ `,i="";this._loading&&this._items.length===0?i='<div class="esc-empty">Loading escalations...</div>':this._error?i='<div class="esc-error">Failed to load escalations: '+this._escapeHtml(this._error)+"</div>":!this._items||this._items.length===0?i='<div class="esc-empty">No handoff notes yet. If a build needs your attention, its notes will appear here.</div>':i='<div class="esc-list">'+this._items.map(n=>{let l=this._escapeHtml(n.filename||""),c=this._escapeHtml(this._formatSize(n.size_bytes)),p=this._escapeHtml(this._formatDate(n.modified_at));return'<div class="esc-item" data-filename="'+l+'"><span class="esc-name">'+l+'</span><span class="esc-meta">'+c+" &middot; "+p+"</span></div>"}).join("")+"</div>";let a="";if(this._activeFile){let o=this._escapeHtml(this._activeFile),n;this._activeBodyError?n='<div class="esc-error">Failed to load: '+this._escapeHtml(this._activeBodyError)+"</div>":this._activeBody===null?n='<div class="esc-body">Loading '+o+"...</div>":n='<div class="esc-body md-body">'+C(this._activeBody)+"</div>",a='<div class="esc-viewer"><div class="esc-viewer-header"><span class="esc-name">'+o+'</span><button class="esc-close-btn" data-action="close">Close</button></div>'+n+"</div>"}e.innerHTML=t+'<div class="esc-wrapper"><div class="esc-explain">Handoff/escalation documents written under .loki/escalations/. Click an entry to view its contents.</div>'+i+a+"</div>",e.querySelectorAll(".esc-item").forEach(o=>{o.addEventListener("click",()=>{let n=o.getAttribute("data-filename");n&&this._openFile(n)})});let r=e.querySelector('.esc-close-btn[data-action="close"]');r&&r.addEventListener("click",()=>this._closeFile())}};typeof customElements<"u"&&!customElements.get("loki-escalations")&&customElements.define("loki-escalations",De);var He=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._transcripts=[],this._hookEvents=[],this._loading=!1,this._error=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._load(),this._poll=b({loadFn:()=>this._load(),intervalMs:3e4,element:this,immediate:!1})}disconnectedCallback(){super.disconnectedCallback(),this._poll&&(this._poll.stop(),this._poll=null)}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._api=h({baseUrl:i}),this._load()),e==="theme"&&this._applyTheme())}_setupApi(){let e=this.getAttribute("api-url")||(typeof window<"u"?window.location.origin:"");this._api=h({baseUrl:e})}async _load(){this._loading=!0,this._error=null;let e=this._api;try{let t=await e.get("/api/council/transcripts?limit=10");if(e!==this._api)return;this._transcripts=Array.isArray(t&&t.transcripts)?t.transcripts:[]}catch(t){if(e!==this._api)return;this._error=t&&t.message?t.message:String(t),this._transcripts=[]}try{let t=await e.get("/api/council/transcripts?limit=20&type_prefix=claude_hook_");if(e!==this._api)return;this._hookEvents=Array.isArray(t&&t.hook_events)?t.hook_events:[]}catch{if(e!==this._api)return;this._hookEvents=[]}finally{this._loading=!1,this.render()}}_escapeHtml(e){return e==null?"":String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}_formatTimestamp(e){if(!e)return"--";try{let t=new Date(e);return isNaN(t.getTime())?e:t.toLocaleString()}catch{return e}}_truncate(e,t){if(!e)return"";let i=String(e);return i.length>t?i.slice(0,t)+"...":i}_verdictBadgeHtml(e){let t=String(e||"").toUpperCase();return t==="APPROVE"?'<span class="ct-badge ct-badge-approve">APPROVE</span>':t==="REJECT"?'<span class="ct-badge ct-badge-reject">REJECT</span>':t==="CANNOT_VALIDATE"?'<span class="ct-badge ct-badge-cannot">CANNOT_VALIDATE</span>':'<span class="ct-badge ct-badge-unknown">'+this._escapeHtml(t||"UNKNOWN")+"</span>"}_outcomeBadgeHtml(e){let t=String(e||"").toUpperCase();return t==="APPROVED"?'<span class="ct-badge ct-badge-approve">APPROVED</span>':t==="REJECTED"?'<span class="ct-badge ct-badge-reject">REJECTED</span>':t==="BLOCKED_BY_GATE"?'<span class="ct-badge ct-badge-blocked">BLOCKED BY GATE</span>':'<span class="ct-badge ct-badge-unknown">'+this._escapeHtml(t||"UNKNOWN")+"</span>"}_voterRowHtml(e,t){let i=e.is_contrarian===!0,a=i&&t===!0,s="ct-voter-row";i&&(s+=" ct-voter-contrarian"),a&&(s+=" ct-voter-flipped");let r=this._escapeHtml(e.name||"unknown"),o=this._verdictBadgeHtml(e.verdict),n=this._escapeHtml(this._truncate(e.reasoning,300)),l="",c="";a?(l='<span class="ct-badge ct-badge-override">OVERRIDE</span>',c=`<div class="ct-flip-caption">Devil's Advocate flipped this outcome</div>`):i&&e.triggered&&(l=`<span class="ct-badge ct-badge-da">DEVIL'S ADVOCATE</span>`);let p="";i&&Array.isArray(e.challenges)&&e.challenges.length>0&&(p='<ul class="ct-challenges">'+e.challenges.map(g=>"<li>"+this._escapeHtml(String(g))+"</li>").join("")+"</ul>");let u="";return Array.isArray(e.issues)&&e.issues.length>0&&(u='<ul class="ct-issues">'+e.issues.map(g=>{let x=this._escapeHtml(g.severity||""),k=this._escapeHtml(g.description||"");return'<li><span class="ct-issue-sev ct-issue-sev-'+x.toLowerCase()+'">'+x+"</span> "+k+"</li>"}).join("")+"</ul>"),'<div class="'+s+'"><div class="ct-voter-header"><span class="ct-voter-name">'+r+"</span>"+o+l+"</div>"+(n?'<div class="ct-voter-reason">'+n+"</div>":"")+p+u+c+"</div>"}_transcriptCardHtml(e){let t=this._escapeHtml(String(e.iteration||"--")),i=this._escapeHtml(this._formatTimestamp(e.timestamp)),a=this._escapeHtml(this._truncate(e.task_or_prd,200)),s=this._outcomeBadgeHtml(e.outcome),r=Array.isArray(e.voters)?e.voters:[],o=r.filter(g=>!g.is_contrarian),n=r.filter(g=>g.is_contrarian),l=o.map(g=>this._voterRowHtml(g,!1)).join(""),c="";e.contrarian_triggered&&(c='<div class="ct-contrarian-section"><div class="ct-section-label">Anti-Sycophancy Check</div>'+n.map(x=>this._voterRowHtml(x,e.contrarian_flipped)).join("")+"</div>");let p=typeof e.approve_count=="number"?e.approve_count:"--",u=typeof e.reject_count=="number"?e.reject_count:"--",m=typeof e.threshold=="number"?e.threshold:"--";return'<div class="ct-card"><div class="ct-card-header"><div class="ct-card-meta"><span class="ct-iter-label">Iteration '+t+'</span><span class="ct-ts">'+i+"</span></div>"+s+"</div>"+(a?'<div class="ct-prd-preview">'+a+"</div>":"")+'<div class="ct-tally">Approve: '+p+" &middot; Reject: "+u+" &middot; Threshold: "+m+'</div><div class="ct-voters">'+l+"</div>"+c+"</div>"}render(){let e=this.shadowRoot||this;if(!e)return;let t=`
15028
15139
  <style>
15029
15140
  :host { display: block; margin-top: 24px; }
15030
15141
  .ct-wrapper {
@@ -15193,7 +15304,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
15193
15304
  .ct-badge-da { background: #fdf3d4; color: #8a6c0e; }
15194
15305
  .ct-badge-unknown { background: var(--bg-secondary, #F8F4F0); color: var(--text-muted, #939084); }
15195
15306
  </style>
15196
- `,i="";this._loading&&this._transcripts.length===0?i='<div class="ct-empty">Loading council transcripts...</div>':this._error?i='<div class="ct-error">Failed to load transcripts: '+this._escapeHtml(this._error)+"</div>":!this._transcripts||this._transcripts.length===0?i='<div class="ct-empty">No review rounds recorded yet. Transcripts appear after the first completion vote.</div>':i='<div class="ct-list">'+this._transcripts.map(s=>this._transcriptCardHtml(s)).join("")+"</div>",e.innerHTML=t+'<div class="ct-wrapper"><h3 class="ct-heading">Council Transcripts</h3><div class="ct-explain">Per-iteration voting records from .loki/council/transcripts/. Polls every 30 seconds.</div>'+i+this._hookEventsHtml()+"</div>"}_hookEventsHtml(){let e=Array.isArray(this._hookEvents)?this._hookEvents:[],t;return e.length===0?t='<div class="ct-empty">No live tool activity yet -- Claude hook events stream here while a run is active.</div>':t='<div class="ct-voters">'+e.slice(0,20).map(a=>{let s=this._escapeHtml(a.type||a.event||"event"),r=this._escapeHtml(this._formatTimestamp(a.timestamp||a.ts)),o=this._escapeHtml(this._truncate(a.tool||a.message||a.summary||(a.data?JSON.stringify(a.data):""),120));return'<div class="ct-voter-row"><span class="ct-iter-label">'+s+'</span> <span class="ct-ts">'+r+"</span>"+(o?'<div class="ct-prd-preview">'+o+"</div>":"")+"</div>"}).join("")+"</div>",'<h3 class="ct-heading" style="margin-top:24px;">Live Tool Activity</h3><div class="ct-explain">Claude hook events (PreToolUse / PostToolUse / Stop) streamed from .loki/events.jsonl. Lets you watch background tool calls as they run.</div>'+t}};typeof customElements<"u"&&!customElements.get("loki-council-transcripts")&&customElements.define("loki-council-transcripts",ze);var ti=[{id:"overview",label:"Overview"},{id:"architecture",label:"Architecture"},{id:"modules",label:"Key Modules"},{id:"data-flow",label:"Data Flow"},{id:"ask",label:"Ask"}],De=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._activeTab="overview",this._loading=!1,this._error=null,this._api=null,this._meta=null,this._metaPromise=null,this._sectionCache={},this._sectionState={},this._question="",this._answer=null,this._asking=!1,this._askError=null,this._mermaid=null,this._mermaidPromise=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadMeta()}disconnectedCallback(){super.disconnectedCallback&&super.disconnectedCallback(),this._disconnected=!0}attributeChangedCallback(e,t,i){e==="api-url"&&this._api&&(this._api=h({baseUrl:i}))}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_loadMeta(){this._loading=!0,this._error=null,this.render();let e=this._api;return this._metaPromise=(async()=>{try{let t=await e._get("/api/wiki");if(e!==this._api)return;this._meta=t}catch(t){if(e!==this._api)return;this._error=t&&t.message?t.message:"Failed to load wiki"}finally{this._loading=!1,this.render()}})(),this._metaPromise}async _loadSection(e){if(this._sectionCache[e])return this._sectionState[e]=this._sectionCache[e].error?"error":"loaded",this._sectionCache[e];this._sectionState[e]="loading";let t=this._api;try{let i=await t._get(`/api/wiki/${encodeURIComponent(e)}`);return t!==this._api?this._sectionCache[e]||{error:"stale"}:(this._sectionCache[e]=i,this._sectionState[e]=i&&i.error?"error":"loaded",i)}catch(i){if(t!==this._api)return this._sectionCache[e]||{error:"stale"};let a={error:i&&i.message||"load failed"};return this._sectionCache[e]=a,this._sectionState[e]="error",a}}async _selectTab(e){if(this._activeTab=e,e!=="architecture"&&e!=="modules"&&e!=="data-flow"){this.render();return}if(this._sectionCache[e]){this.render();return}if(this._sectionState[e]="loading",this.render(),this._metaPromise)try{await this._metaPromise}catch{}if(!(this._disconnected||this._activeTab!==e)){if(!this._meta||!this._meta.generated){delete this._sectionState[e],this.render();return}await this._loadSection(e),!(this._disconnected||this._activeTab!==e)&&this.render()}}_ensureMermaid(){return this._mermaid?Promise.resolve(this._mermaid):this._mermaidPromise?this._mermaidPromise:(this._mermaidPromise=(async()=>{try{if(typeof window<"u"&&window.mermaid)return this._mermaid=window.mermaid,this._mermaid;if(typeof window>"u"||typeof document>"u")return null;let t=`${this._api&&this._api.baseUrl||window.location.origin}/assets/mermaid.min.js`;return await new Promise((i,a)=>{let s=document.querySelector("script[data-loki-mermaid]");if(s){s.addEventListener("load",i,{once:!0}),s.addEventListener("error",a,{once:!0}),window.mermaid&&i();return}let r=document.createElement("script");r.src=t,r.async=!0,r.setAttribute("data-loki-mermaid","1"),r.addEventListener("load",i,{once:!0}),r.addEventListener("error",()=>a(new Error("mermaid load failed")),{once:!0}),document.head.appendChild(r)}),this._mermaid=typeof window<"u"&&window.mermaid||null,this._mermaid}catch{return null}})(),this._mermaidPromise)}async _maybeRenderDiagram(e){let t=this._sectionCache[e],i=this._diagramSource(t);if(!i)return;let a;try{a=await this._ensureMermaid()}catch{a=null}if(!(!a||this._disconnected||this._activeTab!==e))try{a.initialize({startOnLoad:!1,securityLevel:"strict",theme:this._mermaidTheme(),flowchart:{htmlLabels:!1,useMaxWidth:!0},deterministicIds:!0}),typeof a.parse=="function"&&await a.parse(i);let s=`wiki-mmd-${e}-${Date.now()}`,r=await a.render(s,i),o=r&&(r.svg||r);if(typeof o!="string"||o.indexOf("<svg")===-1||this._disconnected||this._activeTab!==e||!this.shadowRoot)return;let n=this.shadowRoot.getElementById("wiki-diagram");n&&(n.innerHTML=o)}catch{}}_mermaidTheme(){return(this.getAttribute("theme")||typeof document<"u"&&document.documentElement.getAttribute("data-loki-theme")||"").toLowerCase().includes("dark")?"dark":"neutral"}async _ask(){let e=(this._question||"").trim();if(!e)return;this._asking=!0,this._askError=null,this._answer=null,this.render();let t=this._api;try{let i=await t._post("/api/wiki/ask",{question:e},{timeout:2e5});if(t!==this._api)return;this._answer=i}catch(i){if(t!==this._api)return;this._askError=i&&i.message?i.message:"Ask failed"}finally{this._asking=!1,this.render()}}_esc(e){return String(e??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}_renderCitations(e){return!e||!e.length?"":`<div class="cites"><strong>Sources:</strong><ul>${e.map(i=>`<li><code>${this._esc(i.file)}:${this._esc(i.line)}</code></li>`).join("")}</ul></div>`}_renderNotGenerated(){return`<div class="es">
15307
+ `,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",He);var hi=[{id:"overview",label:"Overview"},{id:"architecture",label:"Architecture"},{id:"modules",label:"Key Modules"},{id:"data-flow",label:"Data Flow"},{id:"ask",label:"Ask"}],Me=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._activeTab="overview",this._loading=!1,this._error=null,this._api=null,this._meta=null,this._metaPromise=null,this._sectionCache={},this._sectionState={},this._question="",this._answer=null,this._asking=!1,this._askError=null,this._mermaid=null,this._mermaidPromise=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._loadMeta()}disconnectedCallback(){super.disconnectedCallback&&super.disconnectedCallback(),this._disconnected=!0}attributeChangedCallback(e,t,i){e==="api-url"&&this._api&&(this._api=h({baseUrl:i}))}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}_loadMeta(){this._loading=!0,this._error=null,this.render();let e=this._api;return this._metaPromise=(async()=>{try{let t=await e._get("/api/wiki");if(e!==this._api)return;this._meta=t}catch(t){if(e!==this._api)return;this._error=t&&t.message?t.message:"Failed to load wiki"}finally{this._loading=!1,this.render()}})(),this._metaPromise}async _loadSection(e){if(this._sectionCache[e])return this._sectionState[e]=this._sectionCache[e].error?"error":"loaded",this._sectionCache[e];this._sectionState[e]="loading";let t=this._api;try{let i=await t._get(`/api/wiki/${encodeURIComponent(e)}`);return t!==this._api?this._sectionCache[e]||{error:"stale"}:(this._sectionCache[e]=i,this._sectionState[e]=i&&i.error?"error":"loaded",i)}catch(i){if(t!==this._api)return this._sectionCache[e]||{error:"stale"};let a={error:i&&i.message||"load failed"};return this._sectionCache[e]=a,this._sectionState[e]="error",a}}async _selectTab(e){if(this._activeTab=e,e!=="architecture"&&e!=="modules"&&e!=="data-flow"){this.render();return}if(this._sectionCache[e]){this.render();return}if(this._sectionState[e]="loading",this.render(),this._metaPromise)try{await this._metaPromise}catch{}if(!(this._disconnected||this._activeTab!==e)){if(!this._meta||!this._meta.generated){delete this._sectionState[e],this.render();return}await this._loadSection(e),!(this._disconnected||this._activeTab!==e)&&this.render()}}_ensureMermaid(){return this._mermaid?Promise.resolve(this._mermaid):this._mermaidPromise?this._mermaidPromise:(this._mermaidPromise=(async()=>{try{if(typeof window<"u"&&window.mermaid)return this._mermaid=window.mermaid,this._mermaid;if(typeof window>"u"||typeof document>"u")return null;let t=`${this._api&&this._api.baseUrl||window.location.origin}/assets/mermaid.min.js`;return await new Promise((i,a)=>{let s=document.querySelector("script[data-loki-mermaid]");if(s){s.addEventListener("load",i,{once:!0}),s.addEventListener("error",a,{once:!0}),window.mermaid&&i();return}let r=document.createElement("script");r.src=t,r.async=!0,r.setAttribute("data-loki-mermaid","1"),r.addEventListener("load",i,{once:!0}),r.addEventListener("error",()=>a(new Error("mermaid load failed")),{once:!0}),document.head.appendChild(r)}),this._mermaid=typeof window<"u"&&window.mermaid||null,this._mermaid}catch{return null}})(),this._mermaidPromise)}async _maybeRenderDiagram(e){let t=this._sectionCache[e],i=this._diagramSource(t);if(!i)return;let a;try{a=await this._ensureMermaid()}catch{a=null}if(!(!a||this._disconnected||this._activeTab!==e))try{a.initialize({startOnLoad:!1,securityLevel:"strict",theme:this._mermaidTheme(),flowchart:{htmlLabels:!1,useMaxWidth:!0},deterministicIds:!0}),typeof a.parse=="function"&&await a.parse(i);let s=`wiki-mmd-${e}-${Date.now()}`,r=await a.render(s,i),o=r&&(r.svg||r);if(typeof o!="string"||o.indexOf("<svg")===-1||this._disconnected||this._activeTab!==e||!this.shadowRoot)return;let n=this.shadowRoot.getElementById("wiki-diagram");n&&(n.innerHTML=o)}catch{}}_mermaidTheme(){return(this.getAttribute("theme")||typeof document<"u"&&document.documentElement.getAttribute("data-loki-theme")||"").toLowerCase().includes("dark")?"dark":"neutral"}async _ask(){let e=(this._question||"").trim();if(!e)return;this._asking=!0,this._askError=null,this._answer=null,this.render();let t=this._api;try{let i=await t._post("/api/wiki/ask",{question:e},{timeout:2e5});if(t!==this._api)return;this._answer=i}catch(i){if(t!==this._api)return;this._askError=i&&i.message?i.message:"Ask failed"}finally{this._asking=!1,this.render()}}_esc(e){return String(e??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}_renderCitations(e){return!e||!e.length?"":`<div class="cites"><strong>Sources:</strong><ul>${e.map(i=>`<li><code>${this._esc(i.file)}:${this._esc(i.line)}</code></li>`).join("")}</ul></div>`}_renderNotGenerated(){return`<div class="es">
15197
15308
  <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>
15198
15309
  <div class="es-title">No wiki generated yet</div>
15199
15310
  <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>
@@ -15232,7 +15343,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
15232
15343
  <div class="es-title">Couldn't load wiki</div>
15233
15344
  <div class="es-desc">${this._esc(e)}</div>
15234
15345
  <button class="es-cta" id="wiki-retry-btn">Retry</button>
15235
- </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=ti.map(o=>`<button class="tab ${o.id===this._activeTab?"active":""}"
15346
+ </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=hi.map(o=>`<button class="tab ${o.id===this._activeTab?"active":""}"
15236
15347
  data-tab="${o.id}">${this._esc(o.label)}</button>`).join("");this.shadowRoot.innerHTML=`
15237
15348
  <style>
15238
15349
  ${this.getBaseStyles()}
@@ -15350,7 +15461,7 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
15350
15461
  </style>
15351
15462
  <div class="tabs">${e}</div>
15352
15463
  <div class="content">${this._renderBody()}</div>
15353
- `,this.shadowRoot.querySelectorAll(".tab").forEach(o=>{o.addEventListener("click",()=>this._selectTab(o.dataset.tab))});let t=this.shadowRoot.getElementById("wiki-q");t&&(t.addEventListener("input",o=>{this._question=o.target.value}),t.addEventListener("keydown",o=>{o.key==="Enter"&&this._ask()}));let i=this.shadowRoot.getElementById("wiki-ask-btn");i&&i.addEventListener("click",()=>this._ask());let a=this.shadowRoot.getElementById("wiki-gen-copy");a&&a.addEventListener("click",()=>this._copyGenerateCmd(a));let s=this.shadowRoot.getElementById("wiki-retry-btn");s&&s.addEventListener("click",()=>{this._sectionCache={},this._sectionState={},this._loadMeta()});let r=this._activeTab;(r==="architecture"||r==="data-flow")&&this._sectionCache[r]&&!this._sectionCache[r].error&&this.shadowRoot.getElementById("wiki-diagram")&&this._maybeRenderDiagram(r)}_copyGenerateCmd(e){let t="loki wiki generate",i=()=>{let a=e.innerHTML;e.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>',setTimeout(()=>{e.innerHTML=a},1500)};navigator.clipboard&&navigator.clipboard.writeText&&navigator.clipboard.writeText(t).then(i).catch(()=>{})}};customElements.get("loki-wiki-browser")||customElements.define("loki-wiki-browser",De);var kt={prd:"PRD file",spec:"Generated spec",issue:"GitHub issue",brief:"One-line brief","codebase-analysis":"Codebase analysis",none:"No spec yet",unknown:"Unknown spec"},He=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._api=null,this._spec=null,this._history=null,this._loading=!1,this._error=null,this._historyError=null,this._historyOpen=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._load()}attributeChangedCallback(e,t,i){e==="api-url"&&this._api&&(this._api=h({baseUrl:i}))}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _load(){let e=this._api;this._loading=!0,this._error=null,this.render();try{let t=await e._get("/api/spec");if(e!==this._api)return;this._spec=t}catch(t){if(e!==this._api)return;this._error=t&&t.message?t.message:"Failed to load spec"}finally{e===this._api&&(this._loading=!1,this.render())}try{let t=await e._get("/api/spec/history");if(e!==this._api)return;this._history=t&&Array.isArray(t.history)?t.history:[]}catch(t){if(e!==this._api)return;this._historyError=t&&t.message?t.message:"Failed to load history",this._history=[]}this.render()}_esc(e){return String(e??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}_when(e){if(!e)return"unknown time";let t=new Date(e);if(isNaN(t.getTime()))return this._esc(e);try{return t.toLocaleString()}catch{return this._esc(e)}}_typeLabel(e){return kt[e]||kt.unknown}_typeBadge(e){return`<span class="badge badge-${this._esc(e)}">${this._esc(this._typeLabel(e))}</span>`}_renderActive(){if(this._loading)return'<div class="es-loading"><span class="es-spinner"></span> Loading active spec...</div>';if(this._error)return this._renderError(this._error);let e=this._spec;if(!e||!e.type||e.type==="none")return this._renderEmpty();let t=this._typeBadge(e.type),i="",a="";if(e.type==="prd"||e.type==="spec"){e.path&&(i=`<code class="src">${this._esc(e.path)}</code>`);let s=e.content||"";s.trim()?a=`<div class="body md-body">${C(s)}</div>`+(e.truncated?'<p class="dim">Preview truncated -- see the full file on disk.</p>':""):a='<p class="dim">No content available.</p>'}else if(e.type==="issue"){i=e.ref?`<code class="src">${this._esc(e.ref)}</code>`:"";let r=e.title?`<p class="issue-title">${this._esc(e.title)}</p>`:"",o=(e.body||"").trim()?`<div class="body md-body">${C(e.body)}</div>`+(e.truncated?'<p class="dim">Preview truncated.</p>':""):"";a=`${r}${o}`}else if(e.type==="brief"){let s=(e.text||"").trim();a=s?`<pre class="body brief">${this._esc(s)}</pre>`+(e.truncated?'<p class="dim">Preview truncated.</p>':""):'<p class="dim">No brief recorded.</p>'}else e.type==="codebase-analysis"?a='<p class="dim">No explicit spec. Loki is building from an analysis of the existing codebase.</p>':a='<p class="dim">The spec source could not be resolved.</p>';return`<div class="active">
15464
+ `,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",Me);var Tt={prd:"PRD file",spec:"Generated spec",issue:"GitHub issue",brief:"One-line brief","codebase-analysis":"Codebase analysis",none:"No spec yet",unknown:"Unknown spec"},Re=class extends v{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._api=null,this._spec=null,this._history=null,this._loading=!1,this._error=null,this._historyError=null,this._historyOpen=!1}connectedCallback(){super.connectedCallback(),this._setupApi(),this._load()}attributeChangedCallback(e,t,i){e==="api-url"&&this._api&&(this._api=h({baseUrl:i}))}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e})}async _load(){let e=this._api;this._loading=!0,this._error=null,this.render();try{let t=await e._get("/api/spec");if(e!==this._api)return;this._spec=t}catch(t){if(e!==this._api)return;this._error=t&&t.message?t.message:"Failed to load spec"}finally{e===this._api&&(this._loading=!1,this.render())}try{let t=await e._get("/api/spec/history");if(e!==this._api)return;this._history=t&&Array.isArray(t.history)?t.history:[]}catch(t){if(e!==this._api)return;this._historyError=t&&t.message?t.message:"Failed to load history",this._history=[]}this.render()}_esc(e){return String(e??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}_when(e){if(!e)return"unknown time";let t=new Date(e);if(isNaN(t.getTime()))return this._esc(e);try{return t.toLocaleString()}catch{return this._esc(e)}}_typeLabel(e){return Tt[e]||Tt.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">
15354
15465
  <div class="active-head">
15355
15466
  <span class="active-label">Building from</span>
15356
15467
  ${t}
@@ -15452,13 +15563,13 @@ var LokiDashboard=(()=>{var Re=Object.defineProperty;var _t=Object.getOwnPropert
15452
15563
  </style>
15453
15564
  <div class="active-wrap">${this._renderActive()}</div>
15454
15565
  ${this._error||this._spec&&this._spec.type==="none"?"":this._renderHistory()}
15455
- `;let e=this.shadowRoot.getElementById("spec-retry-btn");e&&e.addEventListener("click",()=>this._load());let t=this.shadowRoot.getElementById("hist-toggle");t&&t.addEventListener("click",()=>{this._historyOpen=!this._historyOpen,this.render()})}};customElements.get("loki-spec-panel")||customElements.define("loki-spec-panel",He);(function(){"use strict";if(typeof window>"u"||typeof customElements>"u")return;var d={open:'<circle cx="178" cy="214" r="7" class="fillInk"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="180.5" cy="211.5" r="2" class="fillHi"/><circle cx="246.5" cy="211.5" r="2" class="fillHi"/>',happy:'<path class="ink" d="M171 216c4-6 10-6 14 0"/><path class="ink" d="M237 216c4-6 10-6 14 0"/>',lookUp:'<circle cx="178" cy="214" r="7" class="fillInk"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="180" cy="210" r="2.4" class="fillHi"/><circle cx="246" cy="210" r="2.4" class="fillHi"/>',wide:'<circle cx="178" cy="213" r="8.5" class="fillInk"/><circle cx="244" cy="213" r="8.5" class="fillInk"/><circle cx="181" cy="210" r="2.6" class="fillHi"/><circle cx="247" cy="210" r="2.6" class="fillHi"/>',focused:'<path class="inkBold" d="M170 214h16"/><path class="inkBold" d="M236 214h16"/>',closed:'<path class="ink" d="M170 214c4 5 10 5 14 0"/><path class="ink" d="M236 214c4 5 10 5 14 0"/>',worried:'<circle cx="178" cy="216" r="6" class="fillInk"/><circle cx="244" cy="216" r="6" class="fillInk"/><circle cx="180" cy="213.5" r="1.8" class="fillHi"/><circle cx="246" cy="213.5" r="1.8" class="fillHi"/>',wink:'<path class="ink" d="M171 214c4-5 10-5 14 0"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="246.5" cy="211.5" r="2" class="fillHi"/>'},e={none:"",raised:'<path class="inkThin" d="M168 198c5-3 12-3 17 0"/><path class="inkThin" d="M237 198c5-3 12-3 17 0"/>',furrow:'<path class="inkThin" d="M168 199l16 3"/><path class="inkThin" d="M254 199l-16 3"/>',worried:'<path class="inkThin" d="M168 201l16-4"/><path class="inkThin" d="M254 201l-16-4"/>'},t={smile:'<path class="ink" d="M192 244c12 12 26 12 38 0"/>',openSmile:'<path class="fillInk" d="M194 243c8 16 26 16 34 0c-10 6-24 6-34 0z"/>',flat:'<path class="ink" d="M198 248h26"/>',o:'<ellipse cx="211" cy="248" rx="6" ry="7" class="ink"/>',frown:'<path class="ink" d="M192 250c12-12 26-12 38 0"/>',soft:'<path class="ink" d="M196 246c9 7 19 7 28 0"/>',proud:'<path class="ink" d="M194 245c10 9 24 9 32 -2"/>'},i={none:"",wave:'<g class="prop-wave"><path class="ink" d="M318 250c14-2 26 6 28 20"/><circle cx="348" cy="276" r="9" class="fillPaper ink"/></g>',zzz:'<g class="ink prop-zzz"><text x="300" y="150" class="zzz z1">z</text><text x="322" y="128" class="zzz z2">z</text><text x="344" y="110" class="zzz z3">z</text></g>',thoughtDots:'<g class="prop-think"><circle cx="300" cy="170" r="4" class="fillInk d1"/><circle cx="316" cy="150" r="5.5" class="fillInk d2"/><circle cx="336" cy="126" r="7" class="fillInk d3"/></g>',magnifier:'<g class="prop-magnifier"><circle cx="332" cy="250" r="18" class="fillGlass ink"/><path class="inkBold" d="M345 263l16 16"/><path class="inkThin" d="M325 244a10 10 0 0 1 8 4"/></g>',check:'<g class="prop-check"><circle cx="332" cy="246" r="17" class="fillSeal"/><path class="checkMark" d="M324 246l6 6 11 -13"/></g>',confetti:'<g class="prop-confetti"><rect x="110" y="120" width="7" height="7" class="fillInk c1" transform="rotate(20 113 123)"/><rect x="300" y="110" width="7" height="7" class="fillGlow c2" transform="rotate(-15 303 113)"/><rect x="140" y="96" width="6" height="6" class="fillSeal c3"/><circle cx="330" cy="150" r="4" class="fillInk c4"/><circle cx="96" cy="170" r="4" class="fillGlow c5"/><rect x="270" y="140" width="6" height="6" class="fillInk c6" transform="rotate(40 273 143)"/><path class="inkViolet c7" d="M210 92l0 12M204 98l12 0"/></g>',parcel:'<g class="prop-parcel"><rect x="316" y="244" width="40" height="34" rx="3" class="fillPaper ink"/><path class="ink" d="M316 256h40"/><path class="inkViolet" d="M336 244v34"/></g>',spinner:'<g class="prop-spinner"><path class="inkBold spin" d="M332 230a20 20 0 1 1 -14 6"/></g>'},a={idle:{eyes:"open",mouth:"smile",motion:"breathe",label:"Loki, resting",blink:!0},happy:{eyes:"happy",mouth:"smile",motion:"bob",label:"Loki, happy"},thinking:{eyes:"lookUp",brow:"raised",mouth:"flat",prop:"thoughtDots",motion:"wiggle",label:"Loki, thinking"},building:{eyes:"focused",brow:"furrow",mouth:"flat",motion:"work",label:"Loki, building"},reviewing:{eyes:"focused",brow:"furrow",mouth:"soft",prop:"magnifier",motion:"inspect",label:"Loki, reviewing the work"},verifying:{eyes:"open",mouth:"soft",prop:"check",motion:"bob",label:"Loki, verifying",blink:!0},celebrating:{eyes:"wide",mouth:"openSmile",prop:"confetti",motion:"bounce",label:"Loki, celebrating a verified result"},proud:{eyes:"happy",mouth:"proud",prop:"check",motion:"bob",label:"Loki, proud"},waving:{eyes:"wink",mouth:"smile",prop:"wave",motion:"wave",label:"Loki, waving hello"},sleeping:{eyes:"closed",mouth:"soft",prop:"zzz",motion:"sleep",label:"Loki, sleeping"},concerned:{eyes:"worried",brow:"worried",mouth:"frown",motion:"shake",label:"Loki, something went wrong"},shipping:{eyes:"happy",mouth:"smile",prop:"parcel",motion:"launch",label:"Loki, shipping"},loading:{eyes:"open",mouth:"flat",prop:"spinner",motion:"breathe",label:"Loki, loading",blink:!0},curious:{eyes:"lookUp",brow:"raised",mouth:"o",prop:"thoughtDots",motion:"tilt",label:"Loki, curious"},blinking:{eyes:"open",mouth:"smile",motion:"breathe",label:"Loki",blink:!0},walking:{eyes:"open",mouth:"soft",motion:"walk",label:"Loki, walking",blink:!0},running:{eyes:"focused",mouth:"soft",motion:"run",label:"Loki, running"}},s="idle";function r(){return'<g class="legs"><path class="ink leg legL" d="M168 318v18"/><path class="ink foot footL" d="M158 336h20"/><path class="ink leg legR" d="M252 318v18"/><path class="ink foot footR" d="M242 336h20"/></g>'}function o(u,m,g){return m&&Object.prototype.hasOwnProperty.call(u,m)?u[m]:g||""}function n(u){var m=u.blink?" blink":"";return'<svg class="figure" viewBox="0 0 420 380" aria-hidden="true" focusable="false"><ellipse cx="210" cy="338" rx="120" ry="16" class="fillInkWash"/><g class="creature">'+r()+'<path class="fillPaper ink" d="M120 132c0-22 16-36 40-37 38-2 82-2 120 0 24 1 40 15 40 38v118c0 24-16 39-41 40-40 2-78 2-118 0-25-1-41-16-41-40z"/><path class="inkThin" d="M124 168c54-4 118-4 172 0"/><circle cx="146" cy="150" r="4.5" class="inkViolet"/><circle cx="164" cy="150" r="4.5" class="inkThinDot"/><circle cx="182" cy="150" r="4.5" class="inkThinDot"/><circle cx="170" cy="232" r="9" class="fillGlow"/><circle cx="252" cy="232" r="9" class="fillGlow"/>'+o(e,u.brow,"")+'<g class="eyes'+m+'">'+o(d,u.eyes,d.open)+"</g>"+o(t,u.mouth,t.smile)+'<path class="inkViolet" d="M150 280h120"/><path class="inkThin" d="M150 296h84"/>'+o(i,u.prop,"")+"</g></svg>"}var l=[":host{display:inline-block;line-height:0;","--lm-ink:var(--color-ink,#553de9);","--lm-ink-wash:var(--color-ink-wash,rgba(85,61,233,0.08));","--lm-text:var(--color-text,#201515);","--lm-paper:var(--color-paper-card,#fffdf8);","--lm-glow:var(--color-glow,#e8a33d);","--lm-glow-wash:var(--color-glow-wash,rgba(232,163,61,0.14));","--lm-seal:var(--color-seal,#1f8a52);","}",".figure{display:block;width:100%;height:auto;overflow:visible}",".ink{fill:none;stroke:var(--lm-text);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}",".inkBold{fill:none;stroke:var(--lm-text);stroke-width:3.4;stroke-linecap:round;stroke-linejoin:round}",".inkThin{fill:none;stroke:var(--lm-text);stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}",".inkThinDot{fill:none;stroke:var(--lm-text);stroke-width:1.6}",".inkViolet{fill:none;stroke:var(--lm-ink);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}",".fillPaper{fill:var(--lm-paper)}",".fillInk{fill:var(--lm-ink)}",".fillInkWash{fill:var(--lm-ink-wash)}",".fillGlow{fill:var(--lm-glow)}",".fillSeal{fill:var(--lm-seal)}",".fillGlass{fill:rgba(85,61,233,0.06)}",".fillHi{fill:var(--lm-paper)}",".prop-wave .fillPaper{fill:var(--lm-paper)}",".checkMark{fill:none;stroke:#fff;stroke-width:3.2;stroke-linecap:round;stroke-linejoin:round}",".zzz{font:600 26px var(--font-sans,system-ui,sans-serif);fill:var(--lm-ink)}",".m-breathe .creature{transform-box:fill-box;transform-origin:center;animation:lm-breathe 4.5s ease-in-out infinite}","@keyframes lm-breathe{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-2px) scale(1.012)}}",".m-bob .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-bob 2.2s ease-in-out infinite}","@keyframes lm-bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-7px)}}",".m-bounce .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-bounce 0.9s cubic-bezier(.3,.7,.4,1) infinite}","@keyframes lm-bounce{0%,100%{transform:translateY(0) scaleY(1)}30%{transform:translateY(-22px) scaleY(1.05)}55%{transform:translateY(0) scaleY(.94)}70%{transform:translateY(-6px)}}",".m-wiggle .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-wiggle 3s ease-in-out infinite}","@keyframes lm-wiggle{0%,100%{transform:rotate(-1.5deg)}50%{transform:rotate(1.5deg)}}",".m-tilt .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-tilt 3.4s ease-in-out infinite}","@keyframes lm-tilt{0%,100%{transform:rotate(-4deg)}50%{transform:rotate(4deg)}}",".m-work .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-work 0.7s ease-in-out infinite}","@keyframes lm-work{0%,100%{transform:translateX(0) rotate(0)}25%{transform:translateX(-1.5px) rotate(-1deg)}75%{transform:translateX(1.5px) rotate(1deg)}}",".m-inspect .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-inspect 3.2s ease-in-out infinite}","@keyframes lm-inspect{0%,100%{transform:translate(0,0)}50%{transform:translate(6px,-2px)}}",".m-inspect .prop-magnifier{transform-box:fill-box;transform-origin:332px 250px;animation:lm-inspect-mag 3.2s ease-in-out infinite}","@keyframes lm-inspect-mag{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(4px,4px) scale(1.08)}}",".m-shake .creature{transform-box:fill-box;transform-origin:center;animation:lm-shake 0.5s ease-in-out infinite}","@keyframes lm-shake{0%,100%{transform:translateX(0)}25%{transform:translateX(-4px)}75%{transform:translateX(4px)}}",".m-launch .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-launch 1.6s ease-in-out infinite}","@keyframes lm-launch{0%{transform:translateY(0)}40%{transform:translateY(-3px)}70%{transform:translateY(-14px) rotate(-2deg)}100%{transform:translateY(0)}}",".m-wave .creature{transform-box:fill-box;transform-origin:center;animation:lm-breathe 4.5s ease-in-out infinite}",".m-sleep .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-sleep 5.5s ease-in-out infinite}","@keyframes lm-sleep{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-1px) scale(1.02)}}",".prop-wave{transform-box:fill-box;transform-origin:50% 100%;animation:lm-sway 1.1s ease-in-out infinite}","@keyframes lm-sway{0%,100%{transform:rotate(-8deg)}50%{transform:rotate(14deg)}}",".prop-think .d1{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite}",".prop-think .d2{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite .3s}",".prop-think .d3{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite .6s}","@keyframes lm-rise{0%{opacity:.2;transform:translateY(4px) scale(.7)}50%{opacity:1;transform:translateY(0) scale(1)}100%{opacity:.2;transform:translateY(-4px) scale(.7)}}",".zzz{opacity:0;transform-box:fill-box;transform-origin:center}",".prop-zzz .z1{animation:lm-zfloat 3s ease-in-out infinite}",".prop-zzz .z2{animation:lm-zfloat 3s ease-in-out infinite 1s}",".prop-zzz .z3{animation:lm-zfloat 3s ease-in-out infinite 2s}","@keyframes lm-zfloat{0%{opacity:0;transform:translateY(6px) scale(.7)}40%{opacity:1}100%{opacity:0;transform:translateY(-16px) scale(1.1)}}",".spin{transform-box:fill-box;transform-origin:332px 250px;animation:lm-spin 1s linear infinite}","@keyframes lm-spin{to{transform:rotate(360deg)}}",".prop-confetti>*{transform-box:fill-box;transform-origin:center;animation:lm-confetti 1.4s ease-in infinite}",".prop-confetti .c2{animation-delay:.15s}.prop-confetti .c3{animation-delay:.3s}",".prop-confetti .c4{animation-delay:.45s}.prop-confetti .c5{animation-delay:.2s}",".prop-confetti .c6{animation-delay:.5s}.prop-confetti .c7{animation-delay:.1s}","@keyframes lm-confetti{0%{opacity:0;transform:translateY(0) rotate(0)}20%{opacity:1}100%{opacity:0;transform:translateY(34px) rotate(180deg)}}",".prop-check{transform-box:fill-box;transform-origin:332px 246px;animation:lm-pop 2.4s ease-in-out infinite}","@keyframes lm-pop{0%,70%,100%{transform:scale(1)}80%{transform:scale(1.18)}}",".m-launch .prop-parcel{transform-box:fill-box;transform-origin:center;animation:lm-bob 1.6s ease-in-out infinite}",".m-walk .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-walkbody 0.8s ease-in-out infinite}","@keyframes lm-walkbody{0%,100%{transform:translateY(0) rotate(-1deg)}50%{transform:translateY(-4px) rotate(1deg)}}",".m-walk .legL{transform-box:fill-box;transform-origin:168px 318px;animation:lm-legswing 0.8s ease-in-out infinite}",".m-walk .footL{transform-box:fill-box;transform-origin:168px 336px;animation:lm-legswing 0.8s ease-in-out infinite}",".m-walk .legR{transform-box:fill-box;transform-origin:252px 318px;animation:lm-legswing 0.8s ease-in-out infinite .4s}",".m-walk .footR{transform-box:fill-box;transform-origin:252px 336px;animation:lm-legswing 0.8s ease-in-out infinite .4s}","@keyframes lm-legswing{0%,100%{transform:rotate(-16deg)}50%{transform:rotate(16deg)}}",".m-run .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-runbody 0.42s ease-in-out infinite}","@keyframes lm-runbody{0%,100%{transform:translateY(0) rotate(-4deg)}50%{transform:translateY(-7px) rotate(2deg)}}",".m-run .legL{transform-box:fill-box;transform-origin:168px 318px;animation:lm-runleg 0.42s ease-in-out infinite}",".m-run .footL{transform-box:fill-box;transform-origin:168px 336px;animation:lm-runleg 0.42s ease-in-out infinite}",".m-run .legR{transform-box:fill-box;transform-origin:252px 318px;animation:lm-runleg 0.42s ease-in-out infinite .21s}",".m-run .footR{transform-box:fill-box;transform-origin:252px 336px;animation:lm-runleg 0.42s ease-in-out infinite .21s}","@keyframes lm-runleg{0%,100%{transform:rotate(-30deg)}50%{transform:rotate(30deg)}}",".eyes.blink{transform-box:fill-box;transform-origin:center;animation:lm-blink 6s steps(1,end) infinite}","@keyframes lm-blink{0%,92%,100%{transform:scaleY(1)}95%{transform:scaleY(.1)}}","@media (prefers-reduced-motion: reduce){",".figure *{animation:none !important}",".eyes.blink{transform:scaleY(1) !important}",".zzz{opacity:1}",".prop-confetti>*{opacity:1}",".prop-think .d1,.prop-think .d2,.prop-think .d3{opacity:1}","}"].join("");function c(u){var m=parseFloat(u);return!isFinite(m)||m<=0?132:m<16?16:m>1024?1024:m}var p=function(){function u(){return class extends HTMLElement{static get observedAttributes(){return["emotion","size","motion"]}constructor(){super(),this.attachShadow({mode:"open"}),this._styleEl=document.createElement("style"),this._styleEl.textContent=l,this._wrap=document.createElement("div"),this._wrap.className="lm-root",this.shadowRoot.appendChild(this._styleEl),this.shadowRoot.appendChild(this._wrap)}connectedCallback(){this._render()}attributeChangedCallback(){this.shadowRoot&&this._render()}_render(){var g=(this.getAttribute("emotion")||s).toLowerCase(),x=a[g]||a[s],k=(this.getAttribute("motion")||x.motion||"breathe").toLowerCase(),_=c(this.getAttribute("size")||"132");this.style.width=_+"px",this.setAttribute("role","img"),this.setAttribute("aria-label",x.label||"Loki"),this._wrap.className="lm-root m-"+k,this._wrap.innerHTML=n(x)}}}return customElements.get("loki-mascot")||customElements.define("loki-mascot",u()),customElements.get("loki-mascot")}();try{p.emotions=Object.keys(a),p.getEmotion=function(u){var m=(u||s).toLowerCase(),g=a[m]||a[s];return Object.assign({name:m},g)},p.renderStandaloneSVG=function(u){var m=p.getEmotion(u),g=m.motion||"breathe",x=l.replace(":host{","svg.loki-figure{"),k=n(m).replace('<svg class="figure"','<svg xmlns="http://www.w3.org/2000/svg" class="figure loki-figure m-'+g+'" role="img" aria-label="'+(m.label||"Loki")+'"').replace('aria-hidden="true" focusable="false"','focusable="false"');return k.replace("</svg>","<style>"+x+"</style></svg>")}}catch{}})();function ii(d){switch((d||"").toLowerCase()){case"running":case"autonomous":return"building";case"paused":return"sleeping";default:return"idle"}}var Me=class extends HTMLElement{static get observedAttributes(){return["api-url","size"]}constructor(){super(),this.attachShadow({mode:"open"}),this._status="idle",this._api=null,this._statusHandler=null,this._discHandler=null,this._poll=null}connectedCallback(){this._setupApi(),this._loadStatus(),this._startPolling(),this.render()}disconnectedCallback(){this._poll&&(this._poll.stop(),this._poll=null),this._teardownApiListeners()}_teardownApiListeners(){this._api&&(this._statusHandler&&this._api.removeEventListener(f.STATUS_UPDATE,this._statusHandler),this._discHandler&&this._api.removeEventListener(f.DISCONNECTED,this._discHandler))}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._teardownApiListeners(),this._setupApi(),this._loadStatus()),e==="size"&&this.render())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e}),this._statusHandler=t=>this._updateFromStatus(t.detail),this._discHandler=()=>{this._status="offline",this.render()},this._api.addEventListener(f.STATUS_UPDATE,this._statusHandler),this._api.addEventListener(f.DISCONNECTED,this._discHandler)}_startPolling(){this._poll=b({loadFn:()=>this._loadStatus(),intervalMs:1e4,sectionId:null,immediate:!1})}async _loadStatus(){let e=this._api;try{let t=await e.getStatus();if(e!==this._api)return;this._updateFromStatus(t)}catch{if(e!==this._api)return;this._status="offline",this.render()}}_updateFromStatus(e){if(!e)return;let t=e.status||"idle";t!==this._status&&(this._status=t,this.render())}render(){if(!this.shadowRoot)return;let e=this.getAttribute("size")||"34",t=ii(this._status);this.shadowRoot.innerHTML=`
15566
+ `;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",Re);(function(){"use strict";if(typeof window>"u"||typeof customElements>"u")return;var d={open:'<circle cx="178" cy="214" r="7" class="fillInk"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="180.5" cy="211.5" r="2" class="fillHi"/><circle cx="246.5" cy="211.5" r="2" class="fillHi"/>',happy:'<path class="ink" d="M171 216c4-6 10-6 14 0"/><path class="ink" d="M237 216c4-6 10-6 14 0"/>',lookUp:'<circle cx="178" cy="214" r="7" class="fillInk"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="180" cy="210" r="2.4" class="fillHi"/><circle cx="246" cy="210" r="2.4" class="fillHi"/>',wide:'<circle cx="178" cy="213" r="8.5" class="fillInk"/><circle cx="244" cy="213" r="8.5" class="fillInk"/><circle cx="181" cy="210" r="2.6" class="fillHi"/><circle cx="247" cy="210" r="2.6" class="fillHi"/>',focused:'<path class="inkBold" d="M170 214h16"/><path class="inkBold" d="M236 214h16"/>',closed:'<path class="ink" d="M170 214c4 5 10 5 14 0"/><path class="ink" d="M236 214c4 5 10 5 14 0"/>',worried:'<circle cx="178" cy="216" r="6" class="fillInk"/><circle cx="244" cy="216" r="6" class="fillInk"/><circle cx="180" cy="213.5" r="1.8" class="fillHi"/><circle cx="246" cy="213.5" r="1.8" class="fillHi"/>',wink:'<path class="ink" d="M171 214c4-5 10-5 14 0"/><circle cx="244" cy="214" r="7" class="fillInk"/><circle cx="246.5" cy="211.5" r="2" class="fillHi"/>'},e={none:"",raised:'<path class="inkThin" d="M168 198c5-3 12-3 17 0"/><path class="inkThin" d="M237 198c5-3 12-3 17 0"/>',furrow:'<path class="inkThin" d="M168 199l16 3"/><path class="inkThin" d="M254 199l-16 3"/>',worried:'<path class="inkThin" d="M168 201l16-4"/><path class="inkThin" d="M254 201l-16-4"/>'},t={smile:'<path class="ink" d="M192 244c12 12 26 12 38 0"/>',openSmile:'<path class="fillInk" d="M194 243c8 16 26 16 34 0c-10 6-24 6-34 0z"/>',flat:'<path class="ink" d="M198 248h26"/>',o:'<ellipse cx="211" cy="248" rx="6" ry="7" class="ink"/>',frown:'<path class="ink" d="M192 250c12-12 26-12 38 0"/>',soft:'<path class="ink" d="M196 246c9 7 19 7 28 0"/>',proud:'<path class="ink" d="M194 245c10 9 24 9 32 -2"/>'},i={none:"",wave:'<g class="prop-wave"><path class="ink" d="M318 250c14-2 26 6 28 20"/><circle cx="348" cy="276" r="9" class="fillPaper ink"/></g>',zzz:'<g class="ink prop-zzz"><text x="300" y="150" class="zzz z1">z</text><text x="322" y="128" class="zzz z2">z</text><text x="344" y="110" class="zzz z3">z</text></g>',thoughtDots:'<g class="prop-think"><circle cx="300" cy="170" r="4" class="fillInk d1"/><circle cx="316" cy="150" r="5.5" class="fillInk d2"/><circle cx="336" cy="126" r="7" class="fillInk d3"/></g>',magnifier:'<g class="prop-magnifier"><circle cx="332" cy="250" r="18" class="fillGlass ink"/><path class="inkBold" d="M345 263l16 16"/><path class="inkThin" d="M325 244a10 10 0 0 1 8 4"/></g>',check:'<g class="prop-check"><circle cx="332" cy="246" r="17" class="fillSeal"/><path class="checkMark" d="M324 246l6 6 11 -13"/></g>',confetti:'<g class="prop-confetti"><rect x="110" y="120" width="7" height="7" class="fillInk c1" transform="rotate(20 113 123)"/><rect x="300" y="110" width="7" height="7" class="fillGlow c2" transform="rotate(-15 303 113)"/><rect x="140" y="96" width="6" height="6" class="fillSeal c3"/><circle cx="330" cy="150" r="4" class="fillInk c4"/><circle cx="96" cy="170" r="4" class="fillGlow c5"/><rect x="270" y="140" width="6" height="6" class="fillInk c6" transform="rotate(40 273 143)"/><path class="inkViolet c7" d="M210 92l0 12M204 98l12 0"/></g>',parcel:'<g class="prop-parcel"><rect x="316" y="244" width="40" height="34" rx="3" class="fillPaper ink"/><path class="ink" d="M316 256h40"/><path class="inkViolet" d="M336 244v34"/></g>',spinner:'<g class="prop-spinner"><path class="inkBold spin" d="M332 230a20 20 0 1 1 -14 6"/></g>'},a={idle:{eyes:"open",mouth:"smile",motion:"breathe",label:"Loki, resting",blink:!0},happy:{eyes:"happy",mouth:"smile",motion:"bob",label:"Loki, happy"},thinking:{eyes:"lookUp",brow:"raised",mouth:"flat",prop:"thoughtDots",motion:"wiggle",label:"Loki, thinking"},building:{eyes:"focused",brow:"furrow",mouth:"flat",motion:"work",label:"Loki, building"},reviewing:{eyes:"focused",brow:"furrow",mouth:"soft",prop:"magnifier",motion:"inspect",label:"Loki, reviewing the work"},verifying:{eyes:"open",mouth:"soft",prop:"check",motion:"bob",label:"Loki, verifying",blink:!0},celebrating:{eyes:"wide",mouth:"openSmile",prop:"confetti",motion:"bounce",label:"Loki, celebrating a verified result"},proud:{eyes:"happy",mouth:"proud",prop:"check",motion:"bob",label:"Loki, proud"},waving:{eyes:"wink",mouth:"smile",prop:"wave",motion:"wave",label:"Loki, waving hello"},sleeping:{eyes:"closed",mouth:"soft",prop:"zzz",motion:"sleep",label:"Loki, sleeping"},concerned:{eyes:"worried",brow:"worried",mouth:"frown",motion:"shake",label:"Loki, something went wrong"},shipping:{eyes:"happy",mouth:"smile",prop:"parcel",motion:"launch",label:"Loki, shipping"},loading:{eyes:"open",mouth:"flat",prop:"spinner",motion:"breathe",label:"Loki, loading",blink:!0},curious:{eyes:"lookUp",brow:"raised",mouth:"o",prop:"thoughtDots",motion:"tilt",label:"Loki, curious"},blinking:{eyes:"open",mouth:"smile",motion:"breathe",label:"Loki",blink:!0},walking:{eyes:"open",mouth:"soft",motion:"walk",label:"Loki, walking",blink:!0},running:{eyes:"focused",mouth:"soft",motion:"run",label:"Loki, running"}},s="idle";function r(){return'<g class="legs"><path class="ink leg legL" d="M168 318v18"/><path class="ink foot footL" d="M158 336h20"/><path class="ink leg legR" d="M252 318v18"/><path class="ink foot footR" d="M242 336h20"/></g>'}function o(u,m,g){return m&&Object.prototype.hasOwnProperty.call(u,m)?u[m]:g||""}function n(u){var m=u.blink?" blink":"";return'<svg class="figure" viewBox="0 0 420 380" aria-hidden="true" focusable="false"><ellipse cx="210" cy="338" rx="120" ry="16" class="fillInkWash"/><g class="creature">'+r()+'<path class="fillPaper ink" d="M120 132c0-22 16-36 40-37 38-2 82-2 120 0 24 1 40 15 40 38v118c0 24-16 39-41 40-40 2-78 2-118 0-25-1-41-16-41-40z"/><path class="inkThin" d="M124 168c54-4 118-4 172 0"/><circle cx="146" cy="150" r="4.5" class="inkViolet"/><circle cx="164" cy="150" r="4.5" class="inkThinDot"/><circle cx="182" cy="150" r="4.5" class="inkThinDot"/><circle cx="170" cy="232" r="9" class="fillGlow"/><circle cx="252" cy="232" r="9" class="fillGlow"/>'+o(e,u.brow,"")+'<g class="eyes'+m+'">'+o(d,u.eyes,d.open)+"</g>"+o(t,u.mouth,t.smile)+'<path class="inkViolet" d="M150 280h120"/><path class="inkThin" d="M150 296h84"/>'+o(i,u.prop,"")+"</g></svg>"}var l=[":host{display:inline-block;line-height:0;","--lm-ink:var(--color-ink,#553de9);","--lm-ink-wash:var(--color-ink-wash,rgba(85,61,233,0.08));","--lm-text:var(--color-text,#201515);","--lm-paper:var(--color-paper-card,#fffdf8);","--lm-glow:var(--color-glow,#e8a33d);","--lm-glow-wash:var(--color-glow-wash,rgba(232,163,61,0.14));","--lm-seal:var(--color-seal,#1f8a52);","}",".figure{display:block;width:100%;height:auto;overflow:visible}",".ink{fill:none;stroke:var(--lm-text);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}",".inkBold{fill:none;stroke:var(--lm-text);stroke-width:3.4;stroke-linecap:round;stroke-linejoin:round}",".inkThin{fill:none;stroke:var(--lm-text);stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}",".inkThinDot{fill:none;stroke:var(--lm-text);stroke-width:1.6}",".inkViolet{fill:none;stroke:var(--lm-ink);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}",".fillPaper{fill:var(--lm-paper)}",".fillInk{fill:var(--lm-ink)}",".fillInkWash{fill:var(--lm-ink-wash)}",".fillGlow{fill:var(--lm-glow)}",".fillSeal{fill:var(--lm-seal)}",".fillGlass{fill:rgba(85,61,233,0.06)}",".fillHi{fill:var(--lm-paper)}",".prop-wave .fillPaper{fill:var(--lm-paper)}",".checkMark{fill:none;stroke:#fff;stroke-width:3.2;stroke-linecap:round;stroke-linejoin:round}",".zzz{font:600 26px var(--font-sans,system-ui,sans-serif);fill:var(--lm-ink)}",".m-breathe .creature{transform-box:fill-box;transform-origin:center;animation:lm-breathe 4.5s ease-in-out infinite}","@keyframes lm-breathe{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-2px) scale(1.012)}}",".m-bob .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-bob 2.2s ease-in-out infinite}","@keyframes lm-bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-7px)}}",".m-bounce .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-bounce 0.9s cubic-bezier(.3,.7,.4,1) infinite}","@keyframes lm-bounce{0%,100%{transform:translateY(0) scaleY(1)}30%{transform:translateY(-22px) scaleY(1.05)}55%{transform:translateY(0) scaleY(.94)}70%{transform:translateY(-6px)}}",".m-wiggle .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-wiggle 3s ease-in-out infinite}","@keyframes lm-wiggle{0%,100%{transform:rotate(-1.5deg)}50%{transform:rotate(1.5deg)}}",".m-tilt .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-tilt 3.4s ease-in-out infinite}","@keyframes lm-tilt{0%,100%{transform:rotate(-4deg)}50%{transform:rotate(4deg)}}",".m-work .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-work 0.7s ease-in-out infinite}","@keyframes lm-work{0%,100%{transform:translateX(0) rotate(0)}25%{transform:translateX(-1.5px) rotate(-1deg)}75%{transform:translateX(1.5px) rotate(1deg)}}",".m-inspect .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-inspect 3.2s ease-in-out infinite}","@keyframes lm-inspect{0%,100%{transform:translate(0,0)}50%{transform:translate(6px,-2px)}}",".m-inspect .prop-magnifier{transform-box:fill-box;transform-origin:332px 250px;animation:lm-inspect-mag 3.2s ease-in-out infinite}","@keyframes lm-inspect-mag{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(4px,4px) scale(1.08)}}",".m-shake .creature{transform-box:fill-box;transform-origin:center;animation:lm-shake 0.5s ease-in-out infinite}","@keyframes lm-shake{0%,100%{transform:translateX(0)}25%{transform:translateX(-4px)}75%{transform:translateX(4px)}}",".m-launch .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-launch 1.6s ease-in-out infinite}","@keyframes lm-launch{0%{transform:translateY(0)}40%{transform:translateY(-3px)}70%{transform:translateY(-14px) rotate(-2deg)}100%{transform:translateY(0)}}",".m-wave .creature{transform-box:fill-box;transform-origin:center;animation:lm-breathe 4.5s ease-in-out infinite}",".m-sleep .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-sleep 5.5s ease-in-out infinite}","@keyframes lm-sleep{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-1px) scale(1.02)}}",".prop-wave{transform-box:fill-box;transform-origin:50% 100%;animation:lm-sway 1.1s ease-in-out infinite}","@keyframes lm-sway{0%,100%{transform:rotate(-8deg)}50%{transform:rotate(14deg)}}",".prop-think .d1{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite}",".prop-think .d2{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite .3s}",".prop-think .d3{transform-box:fill-box;transform-origin:center;animation:lm-rise 2.4s ease-in-out infinite .6s}","@keyframes lm-rise{0%{opacity:.2;transform:translateY(4px) scale(.7)}50%{opacity:1;transform:translateY(0) scale(1)}100%{opacity:.2;transform:translateY(-4px) scale(.7)}}",".zzz{opacity:0;transform-box:fill-box;transform-origin:center}",".prop-zzz .z1{animation:lm-zfloat 3s ease-in-out infinite}",".prop-zzz .z2{animation:lm-zfloat 3s ease-in-out infinite 1s}",".prop-zzz .z3{animation:lm-zfloat 3s ease-in-out infinite 2s}","@keyframes lm-zfloat{0%{opacity:0;transform:translateY(6px) scale(.7)}40%{opacity:1}100%{opacity:0;transform:translateY(-16px) scale(1.1)}}",".spin{transform-box:fill-box;transform-origin:332px 250px;animation:lm-spin 1s linear infinite}","@keyframes lm-spin{to{transform:rotate(360deg)}}",".prop-confetti>*{transform-box:fill-box;transform-origin:center;animation:lm-confetti 1.4s ease-in infinite}",".prop-confetti .c2{animation-delay:.15s}.prop-confetti .c3{animation-delay:.3s}",".prop-confetti .c4{animation-delay:.45s}.prop-confetti .c5{animation-delay:.2s}",".prop-confetti .c6{animation-delay:.5s}.prop-confetti .c7{animation-delay:.1s}","@keyframes lm-confetti{0%{opacity:0;transform:translateY(0) rotate(0)}20%{opacity:1}100%{opacity:0;transform:translateY(34px) rotate(180deg)}}",".prop-check{transform-box:fill-box;transform-origin:332px 246px;animation:lm-pop 2.4s ease-in-out infinite}","@keyframes lm-pop{0%,70%,100%{transform:scale(1)}80%{transform:scale(1.18)}}",".m-launch .prop-parcel{transform-box:fill-box;transform-origin:center;animation:lm-bob 1.6s ease-in-out infinite}",".m-walk .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-walkbody 0.8s ease-in-out infinite}","@keyframes lm-walkbody{0%,100%{transform:translateY(0) rotate(-1deg)}50%{transform:translateY(-4px) rotate(1deg)}}",".m-walk .legL{transform-box:fill-box;transform-origin:168px 318px;animation:lm-legswing 0.8s ease-in-out infinite}",".m-walk .footL{transform-box:fill-box;transform-origin:168px 336px;animation:lm-legswing 0.8s ease-in-out infinite}",".m-walk .legR{transform-box:fill-box;transform-origin:252px 318px;animation:lm-legswing 0.8s ease-in-out infinite .4s}",".m-walk .footR{transform-box:fill-box;transform-origin:252px 336px;animation:lm-legswing 0.8s ease-in-out infinite .4s}","@keyframes lm-legswing{0%,100%{transform:rotate(-16deg)}50%{transform:rotate(16deg)}}",".m-run .creature{transform-box:fill-box;transform-origin:center bottom;animation:lm-runbody 0.42s ease-in-out infinite}","@keyframes lm-runbody{0%,100%{transform:translateY(0) rotate(-4deg)}50%{transform:translateY(-7px) rotate(2deg)}}",".m-run .legL{transform-box:fill-box;transform-origin:168px 318px;animation:lm-runleg 0.42s ease-in-out infinite}",".m-run .footL{transform-box:fill-box;transform-origin:168px 336px;animation:lm-runleg 0.42s ease-in-out infinite}",".m-run .legR{transform-box:fill-box;transform-origin:252px 318px;animation:lm-runleg 0.42s ease-in-out infinite .21s}",".m-run .footR{transform-box:fill-box;transform-origin:252px 336px;animation:lm-runleg 0.42s ease-in-out infinite .21s}","@keyframes lm-runleg{0%,100%{transform:rotate(-30deg)}50%{transform:rotate(30deg)}}",".eyes.blink{transform-box:fill-box;transform-origin:center;animation:lm-blink 6s steps(1,end) infinite}","@keyframes lm-blink{0%,92%,100%{transform:scaleY(1)}95%{transform:scaleY(.1)}}","@media (prefers-reduced-motion: reduce){",".figure *{animation:none !important}",".eyes.blink{transform:scaleY(1) !important}",".zzz{opacity:1}",".prop-confetti>*{opacity:1}",".prop-think .d1,.prop-think .d2,.prop-think .d3{opacity:1}","}"].join("");function c(u){var m=parseFloat(u);return!isFinite(m)||m<=0?132:m<16?16:m>1024?1024:m}var p=function(){function u(){return class extends HTMLElement{static get observedAttributes(){return["emotion","size","motion"]}constructor(){super(),this.attachShadow({mode:"open"}),this._styleEl=document.createElement("style"),this._styleEl.textContent=l,this._wrap=document.createElement("div"),this._wrap.className="lm-root",this.shadowRoot.appendChild(this._styleEl),this.shadowRoot.appendChild(this._wrap)}connectedCallback(){this._render()}attributeChangedCallback(){this.shadowRoot&&this._render()}_render(){var g=(this.getAttribute("emotion")||s).toLowerCase(),x=a[g]||a[s],k=(this.getAttribute("motion")||x.motion||"breathe").toLowerCase(),_=c(this.getAttribute("size")||"132");this.style.width=_+"px",this.setAttribute("role","img"),this.setAttribute("aria-label",x.label||"Loki"),this._wrap.className="lm-root m-"+k,this._wrap.innerHTML=n(x)}}}return customElements.get("loki-mascot")||customElements.define("loki-mascot",u()),customElements.get("loki-mascot")}();try{p.emotions=Object.keys(a),p.getEmotion=function(u){var m=(u||s).toLowerCase(),g=a[m]||a[s];return Object.assign({name:m},g)},p.renderStandaloneSVG=function(u){var m=p.getEmotion(u),g=m.motion||"breathe",x=l.replace(":host{","svg.loki-figure{"),k=n(m).replace('<svg class="figure"','<svg xmlns="http://www.w3.org/2000/svg" class="figure loki-figure m-'+g+'" role="img" aria-label="'+(m.label||"Loki")+'"').replace('aria-hidden="true" focusable="false"','focusable="false"');return k.replace("</svg>","<style>"+x+"</style></svg>")}}catch{}})();function ui(d){switch((d||"").toLowerCase()){case"running":case"autonomous":return"building";case"paused":return"sleeping";default:return"idle"}}var Pe=class extends HTMLElement{static get observedAttributes(){return["api-url","size"]}constructor(){super(),this.attachShadow({mode:"open"}),this._status="idle",this._api=null,this._statusHandler=null,this._discHandler=null,this._poll=null}connectedCallback(){this._setupApi(),this._loadStatus(),this._startPolling(),this.render()}disconnectedCallback(){this._poll&&(this._poll.stop(),this._poll=null),this._teardownApiListeners()}_teardownApiListeners(){this._api&&(this._statusHandler&&this._api.removeEventListener(f.STATUS_UPDATE,this._statusHandler),this._discHandler&&this._api.removeEventListener(f.DISCONNECTED,this._discHandler))}attributeChangedCallback(e,t,i){t!==i&&(e==="api-url"&&this._api&&(this._teardownApiListeners(),this._setupApi(),this._loadStatus()),e==="size"&&this.render())}_setupApi(){let e=this.getAttribute("api-url")||window.location.origin;this._api=h({baseUrl:e}),this._statusHandler=t=>this._updateFromStatus(t.detail),this._discHandler=()=>{this._status="offline",this.render()},this._api.addEventListener(f.STATUS_UPDATE,this._statusHandler),this._api.addEventListener(f.DISCONNECTED,this._discHandler)}_startPolling(){this._poll=b({loadFn:()=>this._loadStatus(),intervalMs:1e4,sectionId:null,immediate:!1})}async _loadStatus(){let e=this._api;try{let t=await e.getStatus();if(e!==this._api)return;this._updateFromStatus(t)}catch{if(e!==this._api)return;this._status="offline",this.render()}}_updateFromStatus(e){if(!e)return;let t=e.status||"idle";t!==this._status&&(this._status=t,this.render())}render(){if(!this.shadowRoot)return;let e=this.getAttribute("size")||"34",t=ui(this._status);this.shadowRoot.innerHTML=`
15456
15567
  <style>
15457
15568
  :host { display: inline-flex; align-items: center; line-height: 0; }
15458
15569
  loki-mascot { display: inline-block; }
15459
15570
  </style>
15460
15571
  <loki-mascot emotion="${t}" size="${e}"></loki-mascot>
15461
- `}};customElements.get("loki-mascot-presence")||customElements.define("loki-mascot-presence",Me);var ai="1.4.0";function si(d={}){return d.theme?w.setTheme(d.theme):d.autoDetectContext!==!1?w.init():j.init(),d.apiUrl&&h({baseUrl:d.apiUrl}),{theme:w.getTheme(),context:w.detectContext()}}return St(ri);})();
15572
+ `}};customElements.get("loki-mascot-presence")||customElements.define("loki-mascot-presence",Pe);var gi="1.4.0";function mi(d={}){return d.theme?w.setTheme(d.theme):d.autoDetectContext!==!1?w.init():U.init(),d.apiUrl&&h({baseUrl:d.apiUrl}),{theme:w.getTheme(),context:w.detectContext()}}return Bt(vi);})();
15462
15573
 
15463
15574
 
15464
15575
  // Initialize dashboard when DOM is ready