@polderlabs/bizar 10.0.7 → 10.2.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 (236) hide show
  1. package/README.md +0 -2
  2. package/bizar-dash/dist/assets/{ActivityFeed-Da-JCrE6.js → ActivityFeed-JjmOY2AQ.js} +1 -1
  3. package/bizar-dash/dist/assets/{ActivityFeed-Da-JCrE6.js.map → ActivityFeed-JjmOY2AQ.js.map} +1 -1
  4. package/bizar-dash/dist/assets/{ActivityView-nIRsSETb.js → ActivityView-BIIMvGWo.js} +1 -1
  5. package/bizar-dash/dist/assets/{ActivityView-nIRsSETb.js.map → ActivityView-BIIMvGWo.js.map} +1 -1
  6. package/bizar-dash/dist/assets/{AdminView-DP1NMxmG.js → AdminView-DRidJtkq.js} +1 -1
  7. package/bizar-dash/dist/assets/{AdminView-DP1NMxmG.js.map → AdminView-DRidJtkq.js.map} +1 -1
  8. package/bizar-dash/dist/assets/{AgentActivity-lSPkOr-O.js → AgentActivity-79l4SBMC.js} +1 -1
  9. package/bizar-dash/dist/assets/{AgentActivity-lSPkOr-O.js.map → AgentActivity-79l4SBMC.js.map} +1 -1
  10. package/bizar-dash/dist/assets/{AgentsView-BIWGkz7w.js → AgentsView-0vT4uPSc.js} +1 -1
  11. package/bizar-dash/dist/assets/{AgentsView-BIWGkz7w.js.map → AgentsView-0vT4uPSc.js.map} +1 -1
  12. package/bizar-dash/dist/assets/{Alert-DN0UysMg.js → Alert-CG5q_s75.js} +1 -1
  13. package/bizar-dash/dist/assets/{Alert-DN0UysMg.js.map → Alert-CG5q_s75.js.map} +1 -1
  14. package/bizar-dash/dist/assets/ArtifactsView-DM8ZmpR9.js +21 -0
  15. package/bizar-dash/dist/assets/ArtifactsView-DM8ZmpR9.js.map +1 -0
  16. package/bizar-dash/dist/assets/{AuthView-DW5cs7ma.js → AuthView-BveN94MC.js} +1 -1
  17. package/bizar-dash/dist/assets/{AuthView-DW5cs7ma.js.map → AuthView-BveN94MC.js.map} +1 -1
  18. package/bizar-dash/dist/assets/{Avatar-DZPv9pvd.js → Avatar-ulUPIYTd.js} +1 -1
  19. package/bizar-dash/dist/assets/{Avatar-DZPv9pvd.js.map → Avatar-ulUPIYTd.js.map} +1 -1
  20. package/bizar-dash/dist/assets/{BackgroundJobsView-D8O-EyMD.js → BackgroundJobsView-BWErhqFo.js} +1 -1
  21. package/bizar-dash/dist/assets/{BackgroundJobsView-D8O-EyMD.js.map → BackgroundJobsView-BWErhqFo.js.map} +1 -1
  22. package/bizar-dash/dist/assets/{BackupView-uwXkhxOV.js → BackupView-CnBjzG9N.js} +1 -1
  23. package/bizar-dash/dist/assets/{BackupView-uwXkhxOV.js.map → BackupView-CnBjzG9N.js.map} +1 -1
  24. package/bizar-dash/dist/assets/{Card-Tyboihu7.js → Card-B0imhxMk.js} +1 -1
  25. package/bizar-dash/dist/assets/{Card-Tyboihu7.js.map → Card-B0imhxMk.js.map} +1 -1
  26. package/bizar-dash/dist/assets/{ChatView-DRBHzgay.js → ChatView-D6zGytzx.js} +1 -1
  27. package/bizar-dash/dist/assets/{ChatView-DRBHzgay.js.map → ChatView-D6zGytzx.js.map} +1 -1
  28. package/bizar-dash/dist/assets/{Chip-BrXIlR9w.js → Chip-wwZSGwLE.js} +1 -1
  29. package/bizar-dash/dist/assets/{Chip-BrXIlR9w.js.map → Chip-wwZSGwLE.js.map} +1 -1
  30. package/bizar-dash/dist/assets/{ClaudeSessionsView-Ck62jaOr.js → ClaudeSessionsView-DK1sOLhi.js} +1 -1
  31. package/bizar-dash/dist/assets/{ClaudeSessionsView-Ck62jaOr.js.map → ClaudeSessionsView-DK1sOLhi.js.map} +1 -1
  32. package/bizar-dash/dist/assets/{ClipboardView-DfND6xL6.js → ClipboardView-CZ2lYPr0.js} +1 -1
  33. package/bizar-dash/dist/assets/{ClipboardView-DfND6xL6.js.map → ClipboardView-CZ2lYPr0.js.map} +1 -1
  34. package/bizar-dash/dist/assets/{ConfigView-DjJmSrOJ.js → ConfigView-D-zT9eNA.js} +1 -1
  35. package/bizar-dash/dist/assets/{ConfigView-DjJmSrOJ.js.map → ConfigView-D-zT9eNA.js.map} +1 -1
  36. package/bizar-dash/dist/assets/{DiagnosticsView-CKgItf0J.js → DiagnosticsView-BocV68Lb.js} +1 -1
  37. package/bizar-dash/dist/assets/{DiagnosticsView-CKgItf0J.js.map → DiagnosticsView-BocV68Lb.js.map} +1 -1
  38. package/bizar-dash/dist/assets/{DialogsView-DHYF8dE1.js → DialogsView-BVjPI5x7.js} +1 -1
  39. package/bizar-dash/dist/assets/{DialogsView-DHYF8dE1.js.map → DialogsView-BVjPI5x7.js.map} +1 -1
  40. package/bizar-dash/dist/assets/{DoctorView-DDLHrSKk.js → DoctorView-84gJcZwM.js} +1 -1
  41. package/bizar-dash/dist/assets/{DoctorView-DDLHrSKk.js.map → DoctorView-84gJcZwM.js.map} +1 -1
  42. package/bizar-dash/dist/assets/{EmptyState-DZ2ouKwd.js → EmptyState-BjgVOrcO.js} +1 -1
  43. package/bizar-dash/dist/assets/{EmptyState-DZ2ouKwd.js.map → EmptyState-BjgVOrcO.js.map} +1 -1
  44. package/bizar-dash/dist/assets/{EnvVarsView-D1cx83mB.js → EnvVarsView-BJ2TEzF7.js} +1 -1
  45. package/bizar-dash/dist/assets/{EnvVarsView-D1cx83mB.js.map → EnvVarsView-BJ2TEzF7.js.map} +1 -1
  46. package/bizar-dash/dist/assets/{ErrorState-DwwJ2-Jq.js → ErrorState-BE3WBFqF.js} +1 -1
  47. package/bizar-dash/dist/assets/{ErrorState-DwwJ2-Jq.js.map → ErrorState-BE3WBFqF.js.map} +1 -1
  48. package/bizar-dash/dist/assets/{EvalView-C9aYixXW.js → EvalView-BJJ2P-kK.js} +1 -1
  49. package/bizar-dash/dist/assets/{EvalView-C9aYixXW.js.map → EvalView-BJJ2P-kK.js.map} +1 -1
  50. package/bizar-dash/dist/assets/{GoalsView-DZa_mGmh.js → GoalsView-pwROHApi.js} +1 -1
  51. package/bizar-dash/dist/assets/{GoalsView-DZa_mGmh.js.map → GoalsView-pwROHApi.js.map} +1 -1
  52. package/bizar-dash/dist/assets/{Grid-CiRyhAgR.js → Grid-qcvbhx6e.js} +1 -1
  53. package/bizar-dash/dist/assets/{Grid-CiRyhAgR.js.map → Grid-qcvbhx6e.js.map} +1 -1
  54. package/bizar-dash/dist/assets/{HeadroomView-CNc-TI7u.js → HeadroomView-D1UiTYbt.js} +1 -1
  55. package/bizar-dash/dist/assets/{HeadroomView-CNc-TI7u.js.map → HeadroomView-D1UiTYbt.js.map} +1 -1
  56. package/bizar-dash/dist/assets/{HistoryView-Dv7aPxJE.js → HistoryView-C7SSOLJA.js} +1 -1
  57. package/bizar-dash/dist/assets/{HistoryView-Dv7aPxJE.js.map → HistoryView-C7SSOLJA.js.map} +1 -1
  58. package/bizar-dash/dist/assets/{Input-BbFUDQnS.js → Input-Bgzxf_Hu.js} +1 -1
  59. package/bizar-dash/dist/assets/{Input-BbFUDQnS.js.map → Input-Bgzxf_Hu.js.map} +1 -1
  60. package/bizar-dash/dist/assets/{LibrariesView-DBQ83TNa.js → LibrariesView-CbFFksox.js} +1 -1
  61. package/bizar-dash/dist/assets/{LibrariesView-DBQ83TNa.js.map → LibrariesView-CbFFksox.js.map} +1 -1
  62. package/bizar-dash/dist/assets/{LightRAGView-JYpE5u9p.js → LightRAGView-BqDrJbRq.js} +1 -1
  63. package/bizar-dash/dist/assets/{LightRAGView-JYpE5u9p.js.map → LightRAGView-BqDrJbRq.js.map} +1 -1
  64. package/bizar-dash/dist/assets/{ListHeader-BGjm11Z0.js → ListHeader-TjPJrUfY.js} +1 -1
  65. package/bizar-dash/dist/assets/{ListHeader-BGjm11Z0.js.map → ListHeader-TjPJrUfY.js.map} +1 -1
  66. package/bizar-dash/dist/assets/{MemoryView-CnOP2MvM.js → MemoryView-BlTeHLhX.js} +1 -1
  67. package/bizar-dash/dist/assets/{MemoryView-CnOP2MvM.js.map → MemoryView-BlTeHLhX.js.map} +1 -1
  68. package/bizar-dash/dist/assets/{MiscView-BBcpUbZZ.js → MiscView-B8QY82Pm.js} +1 -1
  69. package/bizar-dash/dist/assets/{MiscView-BBcpUbZZ.js.map → MiscView-B8QY82Pm.js.map} +1 -1
  70. package/bizar-dash/dist/assets/{ModsView-CU4cAmIz.js → ModsView-CvW1OWts.js} +1 -1
  71. package/bizar-dash/dist/assets/{ModsView-CU4cAmIz.js.map → ModsView-CvW1OWts.js.map} +1 -1
  72. package/bizar-dash/dist/assets/{NotificationsView-BYffvthq.js → NotificationsView-CsBt5U7x.js} +1 -1
  73. package/bizar-dash/dist/assets/{NotificationsView-BYffvthq.js.map → NotificationsView-CsBt5U7x.js.map} +1 -1
  74. package/bizar-dash/dist/assets/{ObsidianView-D3bI0row.js → ObsidianView-BCTejEj2.js} +1 -1
  75. package/bizar-dash/dist/assets/{ObsidianView-D3bI0row.js.map → ObsidianView-BCTejEj2.js.map} +1 -1
  76. package/bizar-dash/dist/assets/{OverviewView-0tq8f-Y0.js → OverviewView-BsuPxwnB.js} +1 -1
  77. package/bizar-dash/dist/assets/{OverviewView-0tq8f-Y0.js.map → OverviewView-BsuPxwnB.js.map} +1 -1
  78. package/bizar-dash/dist/assets/{ProgressBar-B-h60LKA.js → ProgressBar-DlZTETEn.js} +1 -1
  79. package/bizar-dash/dist/assets/{ProgressBar-B-h60LKA.js.map → ProgressBar-DlZTETEn.js.map} +1 -1
  80. package/bizar-dash/dist/assets/{ProjectsView-DhX5lzHS.js → ProjectsView-Soxtmpet.js} +1 -1
  81. package/bizar-dash/dist/assets/{ProjectsView-DhX5lzHS.js.map → ProjectsView-Soxtmpet.js.map} +1 -1
  82. package/bizar-dash/dist/assets/{ProvidersView-CJMX7jm9.js → ProvidersView-DaCEV9pM.js} +1 -1
  83. package/bizar-dash/dist/assets/{ProvidersView-CJMX7jm9.js.map → ProvidersView-DaCEV9pM.js.map} +1 -1
  84. package/bizar-dash/dist/assets/{SchedulesView-CcwDQ9Nm.js → SchedulesView-DY2ByBj_.js} +1 -1
  85. package/bizar-dash/dist/assets/{SchedulesView-CcwDQ9Nm.js.map → SchedulesView-DY2ByBj_.js.map} +1 -1
  86. package/bizar-dash/dist/assets/{Select-Cw7Qtz2M.js → Select-Dbd88_n8.js} +1 -1
  87. package/bizar-dash/dist/assets/{Select-Cw7Qtz2M.js.map → Select-Dbd88_n8.js.map} +1 -1
  88. package/bizar-dash/dist/assets/{SettingsRow-DgsgbPSI.js → SettingsRow-CLMNd434.js} +1 -1
  89. package/bizar-dash/dist/assets/{SettingsRow-DgsgbPSI.js.map → SettingsRow-CLMNd434.js.map} +1 -1
  90. package/bizar-dash/dist/assets/{SettingsView-DTAFdKyK.js → SettingsView-b24oFq9x.js} +1 -1
  91. package/bizar-dash/dist/assets/{SettingsView-DTAFdKyK.js.map → SettingsView-b24oFq9x.js.map} +1 -1
  92. package/bizar-dash/dist/assets/{Sheet-DH-WNJ3Y.js → Sheet-DnDid58j.js} +1 -1
  93. package/bizar-dash/dist/assets/{Sheet-DH-WNJ3Y.js.map → Sheet-DnDid58j.js.map} +1 -1
  94. package/bizar-dash/dist/assets/{Slider-DXbJuQ7y.js → Slider-BJCvKI1I.js} +1 -1
  95. package/bizar-dash/dist/assets/{Slider-DXbJuQ7y.js.map → Slider-BJCvKI1I.js.map} +1 -1
  96. package/bizar-dash/dist/assets/{Sparkline-CYtAn82j.js → Sparkline-ktqQLdyb.js} +1 -1
  97. package/bizar-dash/dist/assets/{Sparkline-CYtAn82j.js.map → Sparkline-ktqQLdyb.js.map} +1 -1
  98. package/bizar-dash/dist/assets/{Switch-BItGrPqr.js → Switch-CwXfsDii.js} +1 -1
  99. package/bizar-dash/dist/assets/{Switch-BItGrPqr.js.map → Switch-CwXfsDii.js.map} +1 -1
  100. package/bizar-dash/dist/assets/{TasksView-i5tm6CkX.js → TasksView-BHmpzFCf.js} +1 -1
  101. package/bizar-dash/dist/assets/{TasksView-i5tm6CkX.js.map → TasksView-BHmpzFCf.js.map} +1 -1
  102. package/bizar-dash/dist/assets/{Textarea-qYDf3yds.js → Textarea-BzIAwSlp.js} +1 -1
  103. package/bizar-dash/dist/assets/{Textarea-qYDf3yds.js.map → Textarea-BzIAwSlp.js.map} +1 -1
  104. package/bizar-dash/dist/assets/{UpdateView-Xln-ej26.js → UpdateView-CSmX9NN0.js} +1 -1
  105. package/bizar-dash/dist/assets/{UpdateView-Xln-ej26.js.map → UpdateView-CSmX9NN0.js.map} +1 -1
  106. package/bizar-dash/dist/assets/{UsageView-BGuZSUZ6.js → UsageView-COyr_Gfi.js} +1 -1
  107. package/bizar-dash/dist/assets/{UsageView-BGuZSUZ6.js.map → UsageView-COyr_Gfi.js.map} +1 -1
  108. package/bizar-dash/dist/assets/{ViewHeader-BqIPVKuG.js → ViewHeader-BzYZ3m-e.js} +1 -1
  109. package/bizar-dash/dist/assets/{ViewHeader-BqIPVKuG.js.map → ViewHeader-BzYZ3m-e.js.map} +1 -1
  110. package/bizar-dash/dist/assets/{VoiceView-CWUOCQs_.js → VoiceView-D33_xG5t.js} +1 -1
  111. package/bizar-dash/dist/assets/{VoiceView-CWUOCQs_.js.map → VoiceView-D33_xG5t.js.map} +1 -1
  112. package/bizar-dash/dist/assets/{brain-fsBSDl2g.js → brain-CM-Vls8r.js} +1 -1
  113. package/bizar-dash/dist/assets/{brain-fsBSDl2g.js.map → brain-CM-Vls8r.js.map} +1 -1
  114. package/bizar-dash/dist/assets/{calendar-DsHTZoCU.js → calendar-C0lgZk69.js} +1 -1
  115. package/bizar-dash/dist/assets/{calendar-DsHTZoCU.js.map → calendar-C0lgZk69.js.map} +1 -1
  116. package/bizar-dash/dist/assets/{circle-CqSxqqeJ.js → circle-Bx_hQEBC.js} +1 -1
  117. package/bizar-dash/dist/assets/{circle-CqSxqqeJ.js.map → circle-Bx_hQEBC.js.map} +1 -1
  118. package/bizar-dash/dist/assets/{circle-alert-BsLl001l.js → circle-alert-DHvsqpw5.js} +1 -1
  119. package/bizar-dash/dist/assets/{circle-alert-BsLl001l.js.map → circle-alert-DHvsqpw5.js.map} +1 -1
  120. package/bizar-dash/dist/assets/{circle-check-rVKMQmZp.js → circle-check-Bx8wmXR9.js} +1 -1
  121. package/bizar-dash/dist/assets/{circle-check-rVKMQmZp.js.map → circle-check-Bx8wmXR9.js.map} +1 -1
  122. package/bizar-dash/dist/assets/{clock-OuficfgH.js → clock-CejGoecX.js} +1 -1
  123. package/bizar-dash/dist/assets/{clock-OuficfgH.js.map → clock-CejGoecX.js.map} +1 -1
  124. package/bizar-dash/dist/assets/{download-BdHlstUY.js → download-4cEUWue1.js} +1 -1
  125. package/bizar-dash/dist/assets/{download-BdHlstUY.js.map → download-4cEUWue1.js.map} +1 -1
  126. package/bizar-dash/dist/assets/{external-link-DA3_VGm-.js → external-link-0NqUhI4i.js} +1 -1
  127. package/bizar-dash/dist/assets/{external-link-DA3_VGm-.js.map → external-link-0NqUhI4i.js.map} +1 -1
  128. package/bizar-dash/dist/assets/{file-text-B-g8H227.js → file-text-yEMkrSoZ.js} +1 -1
  129. package/bizar-dash/dist/assets/{file-text-B-g8H227.js.map → file-text-yEMkrSoZ.js.map} +1 -1
  130. package/bizar-dash/dist/assets/{filter-D9B8s5CG.js → filter-BXt60zAS.js} +1 -1
  131. package/bizar-dash/dist/assets/{filter-D9B8s5CG.js.map → filter-BXt60zAS.js.map} +1 -1
  132. package/bizar-dash/dist/assets/{git-pull-request-ByH0YuVz.js → git-pull-request-BjG5lNtR.js} +1 -1
  133. package/bizar-dash/dist/assets/{git-pull-request-ByH0YuVz.js.map → git-pull-request-BjG5lNtR.js.map} +1 -1
  134. package/bizar-dash/dist/assets/{main-CdOm1Pj9.js → main-CokHAXWM.js} +2 -2
  135. package/bizar-dash/dist/assets/{main-CdOm1Pj9.js.map → main-CokHAXWM.js.map} +1 -1
  136. package/bizar-dash/dist/assets/{pause-C9hgd8wX.js → pause-CAmulU0F.js} +1 -1
  137. package/bizar-dash/dist/assets/{pause-C9hgd8wX.js.map → pause-CAmulU0F.js.map} +1 -1
  138. package/bizar-dash/dist/assets/{pencil-BanqaMw7.js → pencil-eq5IqBmU.js} +1 -1
  139. package/bizar-dash/dist/assets/{pencil-BanqaMw7.js.map → pencil-eq5IqBmU.js.map} +1 -1
  140. package/bizar-dash/dist/assets/{play-CawUZ02_.js → play-BoLrrcBA.js} +1 -1
  141. package/bizar-dash/dist/assets/{play-CawUZ02_.js.map → play-BoLrrcBA.js.map} +1 -1
  142. package/bizar-dash/dist/assets/{plug-Cmv0-T_e.js → plug-DBrVM9lK.js} +1 -1
  143. package/bizar-dash/dist/assets/{plug-Cmv0-T_e.js.map → plug-DBrVM9lK.js.map} +1 -1
  144. package/bizar-dash/dist/assets/{plus-M6LYiKX8.js → plus-DENm0hqV.js} +1 -1
  145. package/bizar-dash/dist/assets/{plus-M6LYiKX8.js.map → plus-DENm0hqV.js.map} +1 -1
  146. package/bizar-dash/dist/assets/{power-DP5x_SRF.js → power-DLjXF7zE.js} +1 -1
  147. package/bizar-dash/dist/assets/{power-DP5x_SRF.js.map → power-DLjXF7zE.js.map} +1 -1
  148. package/bizar-dash/dist/assets/{power-off-NOJRLAIs.js → power-off-D47cOnG_.js} +1 -1
  149. package/bizar-dash/dist/assets/{power-off-NOJRLAIs.js.map → power-off-D47cOnG_.js.map} +1 -1
  150. package/bizar-dash/dist/assets/{refresh-ccw-CHMprsm5.js → refresh-ccw-DNrXX9gB.js} +1 -1
  151. package/bizar-dash/dist/assets/{refresh-ccw-CHMprsm5.js.map → refresh-ccw-DNrXX9gB.js.map} +1 -1
  152. package/bizar-dash/dist/assets/{refresh-cw-1RBqDKgJ.js → refresh-cw-CoAHDpeS.js} +1 -1
  153. package/bizar-dash/dist/assets/{refresh-cw-1RBqDKgJ.js.map → refresh-cw-CoAHDpeS.js.map} +1 -1
  154. package/bizar-dash/dist/assets/{rotate-ccw-DJRekBbi.js → rotate-ccw-ObX5awaG.js} +1 -1
  155. package/bizar-dash/dist/assets/{rotate-ccw-DJRekBbi.js.map → rotate-ccw-ObX5awaG.js.map} +1 -1
  156. package/bizar-dash/dist/assets/{rotate-cw-DHooc0Tx.js → rotate-cw-xpPJw9LP.js} +1 -1
  157. package/bizar-dash/dist/assets/{rotate-cw-DHooc0Tx.js.map → rotate-cw-xpPJw9LP.js.map} +1 -1
  158. package/bizar-dash/dist/assets/{save-DQKCKyZK.js → save-D1iKiJJl.js} +1 -1
  159. package/bizar-dash/dist/assets/{save-DQKCKyZK.js.map → save-D1iKiJJl.js.map} +1 -1
  160. package/bizar-dash/dist/assets/{send-xgy3RAi7.js → send-BRcAhZUm.js} +1 -1
  161. package/bizar-dash/dist/assets/{send-xgy3RAi7.js.map → send-BRcAhZUm.js.map} +1 -1
  162. package/bizar-dash/dist/assets/{shield-alert-CWV2F5ab.js → shield-alert-C6vEcK-g.js} +1 -1
  163. package/bizar-dash/dist/assets/{shield-alert-CWV2F5ab.js.map → shield-alert-C6vEcK-g.js.map} +1 -1
  164. package/bizar-dash/dist/assets/{trash-2-CL4khSRv.js → trash-2-DZDjEnNh.js} +1 -1
  165. package/bizar-dash/dist/assets/{trash-2-CL4khSRv.js.map → trash-2-DZDjEnNh.js.map} +1 -1
  166. package/bizar-dash/dist/assets/{trending-up-CSJJhWTS.js → trending-up-DMj-AJVf.js} +1 -1
  167. package/bizar-dash/dist/assets/{trending-up-CSJJhWTS.js.map → trending-up-DMj-AJVf.js.map} +1 -1
  168. package/bizar-dash/dist/assets/{triangle-alert-BPLb7uLt.js → triangle-alert-_2xe_tl4.js} +1 -1
  169. package/bizar-dash/dist/assets/{triangle-alert-BPLb7uLt.js.map → triangle-alert-_2xe_tl4.js.map} +1 -1
  170. package/bizar-dash/dist/assets/{upload-Cww6MvFq.js → upload-DdDljAeV.js} +1 -1
  171. package/bizar-dash/dist/assets/{upload-Cww6MvFq.js.map → upload-DdDljAeV.js.map} +1 -1
  172. package/bizar-dash/dist/assets/{zap-DmhVUzRA.js → zap-mHsgh0FP.js} +1 -1
  173. package/bizar-dash/dist/assets/{zap-DmhVUzRA.js.map → zap-mHsgh0FP.js.map} +1 -1
  174. package/bizar-dash/dist/index.html +1 -1
  175. package/bizar-dash/src/server/api.mjs +13 -6
  176. package/bizar-dash/src/server/artifacts-store.mjs +120 -14
  177. package/bizar-dash/src/server/claude-artifacts.mjs +281 -0
  178. package/bizar-dash/src/server/diagnostics-store.mjs +5 -35
  179. package/bizar-dash/src/server/mod-security.mjs +1 -2
  180. package/bizar-dash/src/server/providers-store.mjs +1 -1
  181. package/bizar-dash/src/server/routes/_shared.mjs +0 -17
  182. package/bizar-dash/src/server/routes/artifacts.mjs +42 -6
  183. package/bizar-dash/src/server/routes/audit.mjs +78 -0
  184. package/bizar-dash/src/server/routes/decisions.mjs +78 -0
  185. package/bizar-dash/src/server/routes/model-router.mjs +158 -0
  186. package/bizar-dash/src/server/routes/model-router.test.mjs +104 -0
  187. package/bizar-dash/src/server/routes/sessions.mjs +80 -0
  188. package/bizar-dash/src/server/server.mjs +1 -27
  189. package/bizar-dash/src/server/sprint.test.mjs +163 -0
  190. package/bizar-dash/src/web/v8/views/Artifacts/ArtifactsView.tsx +232 -21
  191. package/bizar-dash/src/web/v8/views/Artifacts/ClaudeArtifactView.tsx +179 -0
  192. package/bizar-dash/tests/cli-bugfixes.test.mjs +1 -1
  193. package/bizar-dash/tests/cli-error-visibility.test.mjs +1 -1
  194. package/bizar-dash/tests/cli-refactor.test.mjs +0 -1
  195. package/bizar-dash/tests/diagnostics-store.test.mjs +0 -1
  196. package/cli/bin.mjs +1 -15
  197. package/cli/cli-commands-validation.test.mjs +1 -1
  198. package/cli/commands/lightrag.mjs +1 -1
  199. package/cli/commands/util.mjs +1 -1
  200. package/cli/copy.mjs +1 -47
  201. package/cli/doctor.mjs +3 -3
  202. package/cli/install.mjs +3 -37
  203. package/cli/service-controller.mjs +0 -192
  204. package/cli/service-env.mjs +2 -9
  205. package/cli/utils.mjs +0 -7
  206. package/package.json +1 -1
  207. package/packages/sdk/dist/agent/cron.d.ts +44 -0
  208. package/packages/sdk/dist/agent/cron.js +79 -0
  209. package/packages/sdk/dist/agent/heartbeat.d.ts +43 -0
  210. package/packages/sdk/dist/agent/heartbeat.js +116 -0
  211. package/packages/sdk/dist/index.d.ts +3 -0
  212. package/packages/sdk/dist/index.js +5 -0
  213. package/packages/sdk/dist/learning/decisions.d.ts +46 -0
  214. package/packages/sdk/dist/learning/decisions.js +132 -0
  215. package/packages/sdk/dist/learning/index.d.ts +8 -0
  216. package/packages/sdk/dist/learning/index.js +8 -0
  217. package/packages/sdk/dist/learning/instincts.d.ts +38 -0
  218. package/packages/sdk/dist/learning/instincts.js +139 -0
  219. package/packages/sdk/dist/mcp/server.js +119 -1
  220. package/packages/sdk/dist/router/agent-model-registry.d.ts +89 -0
  221. package/packages/sdk/dist/router/agent-model-registry.js +144 -0
  222. package/packages/sdk/dist/router/index.d.ts +1 -0
  223. package/packages/sdk/dist/router/index.js +1 -0
  224. package/packages/sdk/package.json +3 -2
  225. package/scripts/audit.mjs +388 -0
  226. package/scripts/audit.test.mjs +149 -0
  227. package/scripts/check-deps.mjs +0 -24
  228. package/scripts/eval-gate.mjs +134 -0
  229. package/scripts/eval-gate.test.mjs +138 -0
  230. package/scripts/feature-state-machine.mjs +178 -0
  231. package/scripts/feature-state-machine.test.mjs +135 -0
  232. package/scripts/spec-dedup.test.mjs +124 -0
  233. package/scripts/sprint.mjs +213 -0
  234. package/scripts/worktree-setup.sh +79 -0
  235. package/bizar-dash/dist/assets/ArtifactsView-CDIhPBAx.js +0 -6
  236. package/bizar-dash/dist/assets/ArtifactsView-CDIhPBAx.js.map +0 -1
@@ -51,18 +51,54 @@ export function createArtifactsRouter({ state, broadcast, projectRoot }) {
51
51
  res.json(artifact);
52
52
  }));
53
53
 
54
- // v3.21.0 — Compile the artifact's MDX into a JSON-serializable
55
- // glyph structure for the new Glyphs renderer. Returns frontmatter
56
- // + a flat list of typed blocks, ready for the client-side block
57
- // component map to render.
54
+ // v3.21.0 — Compile the artifact for the renderer. Dispatches by kind:
55
+ // mdx → JSON glyph blocks (legacy v3-v9 renderer)
56
+ // claude-html → iframe-ready HTML envelope
57
+ // claude-svg → iframe-ready HTML envelope (SVG body)
58
+ // claude-react → iframe-ready HTML envelope (Babel-standalone JSX)
59
+ // The Claude-* envelope is ready to drop into an iframe `srcdoc`; the
60
+ // client previewer component (`<ClaudeArtifactView>`) picks the
61
+ // correct renderer based on `kind` and `html`.
58
62
  router.get('/artifacts/:slug/render', wrap(async (req, res) => {
59
63
  const artifact = artifactsStore.get(req.params.slug, projectRoot);
60
64
  if (!artifact) {
61
65
  res.status(404).json({ error: 'not_found' });
62
66
  return;
63
67
  }
64
- const compiled = await compileGlyphMdx(artifact.planMdx || '');
65
- res.json({ slug: req.params.slug, ...compiled });
68
+ const kind = artifact.kind || 'mdx';
69
+ if (kind === 'mdx') {
70
+ const compiled = await compileGlyphMdx(artifact.planMdx || '');
71
+ res.json({ slug: req.params.slug, kind, ...compiled });
72
+ return;
73
+ }
74
+ const compiled = artifactsStore.compile(req.params.slug, projectRoot);
75
+ if (!compiled) {
76
+ res.status(404).json({ error: 'not_found' });
77
+ return;
78
+ }
79
+ res.json({
80
+ slug: req.params.slug,
81
+ kind: compiled.kind,
82
+ html: compiled.html,
83
+ warnings: compiled.warnings || [],
84
+ safeMode: !!compiled.safeMode,
85
+ compiledAt: compiled.compiledAt,
86
+ });
87
+ }));
88
+
89
+ // v10.1.0 — Full-screen viewer. Returns the compiled HTML envelope
90
+ // with `Content-Type: text/html` so a `<a target="_blank">` opens
91
+ // the artifact on its own page (no dashboard chrome). The iframe
92
+ // `sandbox` rules from the envelope apply — the page is just the
93
+ // envelope served as `text/html`.
94
+ router.get('/artifacts/:slug/view', wrap(async (req, res) => {
95
+ const compiled = artifactsStore.compile(req.params.slug, projectRoot);
96
+ if (!compiled) {
97
+ res.status(404).type('html').send('<h1>Not found</h1>');
98
+ return;
99
+ }
100
+ res.set('Content-Security-Policy', "default-src 'self'; script-src 'unsafe-inline' 'unsafe-eval' https://unpkg.com https://cdn.jsdelivr.net https://cdnjs.cloudflare.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src https://fonts.gstatic.com; img-src * data:;");
101
+ res.type('html').send(compiled.html);
66
102
  }));
67
103
 
68
104
  // v3.1.0 — Full artifact CRUD + canvas editing.
@@ -0,0 +1,78 @@
1
+ /**
2
+ * src/server/routes/audit.mjs
3
+ *
4
+ * GET /api/audit — returns latest harness audit score + diff vs prior.
5
+ *
6
+ * Reads .harness/audit/latest.json (written by `node scripts/audit.mjs --write`).
7
+ * Returns the full audit result plus a `diff` object showing which categories
8
+ * changed score vs the prior run (if any).
9
+ */
10
+ import { existsSync, readFileSync } from 'node:fs';
11
+ import { join } from 'node:path';
12
+ import { wrap } from './_shared.mjs';
13
+
14
+ /**
15
+ * @param {object} deps
16
+ * @param {string} deps.projectRoot
17
+ * @returns {import('express').Router}
18
+ */
19
+ export function createAuditRouter({ projectRoot }) {
20
+ const router = require('express').Router();
21
+ const LATEST = join(projectRoot, '.harness', 'audit', 'latest.json');
22
+
23
+ router.get('/audit', wrap(async (_req, res) => {
24
+ if (!existsSync(LATEST)) {
25
+ res.status(404).json({
26
+ error: 'not_ready',
27
+ message: 'No audit run yet. Run `node scripts/audit.mjs --write` first.',
28
+ });
29
+ return;
30
+ }
31
+
32
+ let latest;
33
+ try {
34
+ latest = JSON.parse(readFileSync(LATEST, 'utf8'));
35
+ } catch (err) {
36
+ res.status(500).json({ error: 'parse_error', message: err.message });
37
+ return;
38
+ }
39
+
40
+ // Compute diff vs the run before last (if we have history)
41
+ /** @type {Record<string, {current: number, prior: number, delta: number} | null>} */
42
+ const diff = {};
43
+ const priorPath = join(projectRoot, '.harness', 'audit', 'previous.json');
44
+
45
+ if (existsSync(priorPath)) {
46
+ try {
47
+ const prior = JSON.parse(readFileSync(priorPath, 'utf8'));
48
+ const priorScores = prior.scores ?? {};
49
+ for (const [key, weight] of Object.entries(latest.weights ?? {})) {
50
+ const current = latest.scores?.[key] ?? 0;
51
+ const priorScore = priorScores[key] ?? 0;
52
+ if (current !== priorScore) {
53
+ diff[key] = { current, prior: priorScore, delta: current - priorScore };
54
+ }
55
+ }
56
+ // Also diff total
57
+ const currentTotal = latest.total ?? 0;
58
+ const priorTotal = prior.total ?? 0;
59
+ if (currentTotal !== priorTotal) {
60
+ diff._total = { current: currentTotal, prior: priorTotal, delta: currentTotal - priorTotal };
61
+ }
62
+ } catch {
63
+ // prior file unreadable — no diff
64
+ }
65
+ }
66
+
67
+ res.json({
68
+ latest,
69
+ diff,
70
+ _links: {
71
+ run: 'node scripts/audit.mjs --write',
72
+ latestPath: LATEST,
73
+ },
74
+ });
75
+ }));
76
+
77
+ return router;
78
+ }
@@ -0,0 +1,78 @@
1
+ /**
2
+ * src/server/routes/decisions.mjs
3
+ *
4
+ * v10.1.1 — Pillar D: Decisions log API.
5
+ *
6
+ * GET /api/decisions
7
+ * Returns list of decisions + tamper-evidence status.
8
+ *
9
+ * Storage: <projectRoot>/.bizar/learning/decisions.jsonl
10
+ * Falls back to BIZAR_HOME if projectRoot is not set.
11
+ */
12
+
13
+ 'use strict';
14
+
15
+ import { Router } from 'express';
16
+ import { existsSync, readFileSync } from 'node:fs';
17
+ import { join } from 'node:path';
18
+ import { homedir } from 'node:os';
19
+ import { wrap } from './_shared.mjs';
20
+
21
+ /** Default root: projectRoot > cwd > $HOME */
22
+ function resolveRoot(projectRoot) {
23
+ if (projectRoot && projectRoot !== '.') return projectRoot;
24
+ try { return process.cwd(); } catch { return homedir(); }
25
+ }
26
+
27
+ /**
28
+ * @param {object} deps
29
+ * @param {string} [deps.projectRoot]
30
+ * @returns {import('express').Router}
31
+ */
32
+ export function createDecisionsRouter({ projectRoot } = {}) {
33
+ const router = Router();
34
+ const root = projectRoot ?? resolveRoot(projectRoot);
35
+
36
+ // Lazy-import SDK to avoid hard coupling at boot time.
37
+ async function getDecisionsMod() {
38
+ // Try the published SDK first, then fall back to monorepo dist.
39
+ try {
40
+ return await import('@polderlabs/bizar-sdk/learning');
41
+ } catch {
42
+ return await import('../../../packages/sdk/dist/learning/index.js');
43
+ }
44
+ }
45
+
46
+ // GET /decisions — list + tamper status
47
+ router.get('/decisions', wrap(async (_req, res) => {
48
+ let mod;
49
+ try {
50
+ mod = await getDecisionsMod();
51
+ } catch (err) {
52
+ res.status(503).json({ error: 'unavailable', message: 'SDK not loaded', detail: err?.message });
53
+ return;
54
+ }
55
+
56
+ const decisions = mod.listDecisions ? mod.listDecisions({ project: root }) : [];
57
+ const verified = mod.verifyChain ? mod.verifyChain({ project: root }) : { ok: true };
58
+
59
+ // Apply datamark to all string fields to sanitise surrogates.
60
+ const sanitised = decisions.map((entry) => {
61
+ const out = {};
62
+ for (const [k, v] of Object.entries(entry)) {
63
+ out[k] = mod.datamark ? mod.datamark(v) : v;
64
+ }
65
+ return out;
66
+ });
67
+
68
+ res.json({
69
+ decisions: sanitised,
70
+ tamperEvidence: {
71
+ status: verified.ok ? 'intact' : 'broken',
72
+ at: verified.at ?? null,
73
+ },
74
+ });
75
+ }));
76
+
77
+ return router;
78
+ }
@@ -0,0 +1,158 @@
1
+ /**
2
+ * src/server/routes/model-router.mjs
3
+ *
4
+ * Surfaces the local model-router configuration and live model list.
5
+ *
6
+ * GET /api/model-router — full policy + agent→model map
7
+ * GET /api/model-router/models — live model list from the local router
8
+ * GET /api/model-router/agents — agent→model map only
9
+ * GET /api/model-router/resolve/:agent — concrete model + endpoint for an agent
10
+ *
11
+ * The local router URL defaults to ANTHROPIC_BASE_URL or
12
+ * BIZAR_MODEL_ROUTER_URL or `http://localhost:20128/v1`.
13
+ */
14
+ import { Router } from 'express';
15
+ import { readFile } from 'node:fs/promises';
16
+ import { resolve, dirname } from 'node:path';
17
+ import { fileURLToPath } from 'node:url';
18
+ import { wrap } from './_shared.mjs';
19
+
20
+ const __dirname = dirname(fileURLToPath(import.meta.url));
21
+ // .claude/model-router.json — repo root.
22
+ // From src/server/routes/ up to repo root is 3 levels (routes -> server -> src -> repo).
23
+ const ROUTER_POLICY_PATH = resolve(__dirname, '../../../../.claude/model-router.json');
24
+
25
+ const DEFAULT_ENDPOINT = 'http://localhost:20128/v1';
26
+
27
+ function resolveEndpoint(state) {
28
+ const fromEnv =
29
+ process.env.BIZAR_MODEL_ROUTER_URL ||
30
+ process.env.ANTHROPIC_BASE_URL ||
31
+ state?.config?.modelRouterUrl;
32
+ return (fromEnv || DEFAULT_ENDPOINT).replace(/\/+$/, '');
33
+ }
34
+
35
+ async function loadPolicy() {
36
+ try {
37
+ const raw = await readFile(ROUTER_POLICY_PATH, 'utf8');
38
+ return JSON.parse(raw);
39
+ } catch {
40
+ return {
41
+ version: '0.0.0',
42
+ endpoint: DEFAULT_ENDPOINT,
43
+ tiers: {},
44
+ agents: {},
45
+ policies: {},
46
+ };
47
+ }
48
+ }
49
+
50
+ async function fetchLiveModels(endpoint) {
51
+ try {
52
+ const res = await fetch(`${endpoint}/models`, {
53
+ signal: AbortSignal.timeout(2000),
54
+ });
55
+ if (!res.ok) return { reachable: false, error: `HTTP ${res.status}` };
56
+ const body = await res.json();
57
+ return {
58
+ reachable: true,
59
+ endpoint,
60
+ models: Array.isArray(body?.data) ? body.data : [],
61
+ };
62
+ } catch (err) {
63
+ return {
64
+ reachable: false,
65
+ endpoint,
66
+ error: err instanceof Error ? err.message : String(err),
67
+ };
68
+ }
69
+ }
70
+
71
+ /**
72
+ * v10.1.0 — Resolve the concrete model + endpoint for a named agent
73
+ * directly from the on-disk policy. No SDK import needed (keeps the
74
+ * dashboard route surface lightweight). Used by the front-end's
75
+ * "agent fleet" view, which renders one card per agent with its
76
+ * modelId + endpoint badge.
77
+ */
78
+ function resolveAgentFromPolicy(policy, agent, endpoint) {
79
+ const agents = policy?.agents || {};
80
+ const entry = agents[agent];
81
+ if (entry && typeof entry.model === 'string') {
82
+ return {
83
+ agent,
84
+ modelId: entry.model,
85
+ tier: typeof entry.tier === 'string' ? entry.tier : 'default',
86
+ endpoint,
87
+ rationale: typeof entry.rationale === 'string' ? entry.rationale : '',
88
+ };
89
+ }
90
+ // Fallback: first known entry by name, otherwise the default tier.
91
+ const fallback = Object.values(agents).find((e) => e && typeof e.model === 'string');
92
+ if (fallback) {
93
+ return {
94
+ agent,
95
+ modelId: fallback.model,
96
+ tier: typeof fallback.tier === 'string' ? fallback.tier : 'default',
97
+ endpoint,
98
+ rationale: 'fallback (agent not in policy)',
99
+ };
100
+ }
101
+ return {
102
+ agent,
103
+ modelId: 'bizar/MiniMax-M3',
104
+ tier: 'default',
105
+ endpoint,
106
+ rationale: 'fallback (no policy)',
107
+ };
108
+ }
109
+
110
+ /**
111
+ * @param {object} deps
112
+ * @param {object} deps.state
113
+ * @returns {import('express').Router}
114
+ */
115
+ export function createModelRouterRouter({ state }) {
116
+ const router = Router();
117
+
118
+ router.get('/model-router', wrap(async (_req, res) => {
119
+ const policy = await loadPolicy();
120
+ const endpoint = resolveEndpoint(state);
121
+ const live = await fetchLiveModels(endpoint);
122
+ res.json({
123
+ endpoint,
124
+ policy,
125
+ live,
126
+ agents: policy.agents || {},
127
+ tiers: policy.tiers || {},
128
+ });
129
+ }));
130
+
131
+ router.get('/model-router/models', wrap(async (_req, res) => {
132
+ const endpoint = resolveEndpoint(state);
133
+ const live = await fetchLiveModels(endpoint);
134
+ res.json(live);
135
+ }));
136
+
137
+ router.get('/model-router/agents', wrap(async (_req, res) => {
138
+ const policy = await loadPolicy();
139
+ res.json({ agents: policy.agents || {}, tiers: policy.tiers || {} });
140
+ }));
141
+
142
+ // v10.1.0 — Resolve one agent to its concrete model + endpoint.
143
+ // The front-end's ModelRouter page calls this so it doesn't need to
144
+ // duplicate the registry logic client-side.
145
+ router.get('/model-router/resolve/:agent', wrap(async (req, res) => {
146
+ const agent = String(req.params.agent || '').trim();
147
+ if (!/^[a-z][a-z0-9_-]{0,63}$/i.test(agent)) {
148
+ res.status(400).json({ error: 'bad_slug', message: 'agent must match /^[a-z][a-z0-9_-]{0,63}$/' });
149
+ return;
150
+ }
151
+ const policy = await loadPolicy();
152
+ const endpoint = resolveEndpoint(state);
153
+ const resolved = resolveAgentFromPolicy(policy, agent, endpoint);
154
+ res.json(resolved);
155
+ }));
156
+
157
+ return router;
158
+ }
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Smoke test for /api/model-router. Verifies:
3
+ * - the route resolves and returns the agent→model map
4
+ * - live model probe gracefully degrades when the endpoint is unreachable
5
+ * - the policy file is read from `.claude/model-router.json`
6
+ *
7
+ * Run with: bun test src/server/routes/model-router.test.mjs
8
+ * or: node --test src/server/routes/model-router.test.mjs
9
+ */
10
+ import { test } from 'node:test';
11
+ import assert from 'node:assert/strict';
12
+ import express from 'express';
13
+ import { createModelRouterRouter } from './model-router.mjs';
14
+
15
+ function buildApp() {
16
+ const app = express();
17
+ // Mount under /api to match the dashboard's mount prefix.
18
+ app.use('/api', createModelRouterRouter({ state: {} }));
19
+ return app;
20
+ }
21
+
22
+ async function getJson(app, path) {
23
+ const server = app.listen(0);
24
+ try {
25
+ const port = server.address().port;
26
+ const res = await fetch(`http://127.0.0.1:${port}${path}`);
27
+ return { status: res.status, body: await res.json() };
28
+ } finally {
29
+ await new Promise((r) => server.close(r));
30
+ }
31
+ }
32
+
33
+ test('GET /api/model-router returns agent→model map from .claude/model-router.json', async () => {
34
+ const app = buildApp();
35
+ const { status, body } = await getJson(app, '/api/model-router');
36
+ assert.equal(status, 200);
37
+ assert.ok(typeof body.endpoint === 'string' && body.endpoint.length > 0, 'endpoint present');
38
+ assert.ok(body.policy, 'policy present');
39
+ assert.ok(body.agents, 'agents map present');
40
+ // Forseti / Baldr / Vidarr must be GPT (premium tier per the routing rules).
41
+ assert.match(body.agents.forseti.model, /gpt-5\.6-sol/, 'forseti uses premium GPT');
42
+ assert.match(body.agents.baldr.model, /gpt-5\.6-sol/, 'baldr uses premium GPT');
43
+ assert.match(body.agents.vidarr.model, /gpt-5\.6-sol/, 'vidarr uses premium GPT');
44
+ // Tyr + Odin use the high-tier terra model.
45
+ assert.match(body.agents.tyr.model, /gpt-5\.6-terra/, 'tyr uses high-tier GPT');
46
+ assert.match(body.agents.odin.model, /gpt-5\.6-terra/, 'odin uses high-tier GPT');
47
+ // Everyday default agents use MiniMax-M3.
48
+ assert.equal(body.agents.frigg.model, 'bizar/MiniMax-M3', 'frigg uses default');
49
+ assert.equal(body.agents.hermod.model, 'bizar/MiniMax-M3', 'hermod uses default');
50
+ // Vor uses the budget tier.
51
+ assert.match(body.agents.vor.model, /mimo|deepseek/, 'vor uses budget tier');
52
+ });
53
+
54
+ test('GET /api/model-router/agents returns just the agents+tiers map', async () => {
55
+ const app = buildApp();
56
+ const { status, body } = await getJson(app, '/api/model-router/agents');
57
+ assert.equal(status, 200);
58
+ assert.ok(body.agents.thor, 'thor present');
59
+ assert.ok(body.tiers.default, 'default tier present');
60
+ });
61
+
62
+ test('GET /api/model-router/models probe handles unreachable endpoint gracefully', async () => {
63
+ // Override env to a guaranteed-unreachable port.
64
+ const prev = process.env.BIZAR_MODEL_ROUTER_URL;
65
+ process.env.BIZAR_MODEL_ROUTER_URL = 'http://127.0.0.1:1';
66
+ try {
67
+ const app = buildApp();
68
+ const { status, body } = await getJson(app, '/api/model-router/models');
69
+ assert.equal(status, 200);
70
+ assert.equal(body.reachable, false);
71
+ assert.ok(typeof body.error === 'string', 'error string present');
72
+ } finally {
73
+ if (prev === undefined) delete process.env.BIZAR_MODEL_ROUTER_URL;
74
+ else process.env.BIZAR_MODEL_ROUTER_URL = prev;
75
+ }
76
+ });
77
+
78
+ test('GET /api/model-router/resolve/:agent returns the concrete model + endpoint', async () => {
79
+ const app = buildApp();
80
+ const { status, body } = await getJson(app, '/api/model-router/resolve/tyr');
81
+ assert.equal(status, 200);
82
+ assert.equal(body.agent, 'tyr');
83
+ assert.match(body.modelId, /gpt-5\.6-terra/, 'tyr uses high-tier terra');
84
+ assert.match(body.endpoint, /^http/, 'endpoint is a URL');
85
+ assert.equal(typeof body.tier, 'string');
86
+ });
87
+
88
+ test('GET /api/model-router/resolve/:agent falls back for unknown agents', async () => {
89
+ const app = buildApp();
90
+ const { status, body } = await getJson(app, '/api/model-router/resolve/nonexistent-agent-xyz');
91
+ assert.equal(status, 200);
92
+ assert.equal(body.agent, 'nonexistent-agent-xyz');
93
+ assert.match(body.modelId, /[a-z0-9/_.-]+/, 'returns a model id');
94
+ assert.match(body.endpoint, /^http/, 'endpoint is a URL');
95
+ });
96
+
97
+ test('GET /api/model-router/resolve/:agent rejects bad slugs', async () => {
98
+ const app = buildApp();
99
+ // Express decodes percent-encoded path segments before the handler runs.
100
+ // Use a slug that's syntactically illegal per the route's regex.
101
+ const { status, body } = await getJson(app, '/api/model-router/resolve/has spaces');
102
+ assert.equal(status, 400);
103
+ assert.equal(body.error, 'bad_slug');
104
+ });
@@ -0,0 +1,80 @@
1
+ /**
2
+ * src/server/routes/sessions.mjs
3
+ *
4
+ * Pillar A — Session heartbeat list + stop.
5
+ *
6
+ * GET /api/sessions — list live sessions from .harness/traces/heartbeat.jsonl
7
+ * POST /api/sessions/:id/stop — mark a session as done
8
+ */
9
+
10
+ import { Router } from "express";
11
+ import { existsSync, readFileSync, appendFileSync, mkdirSync } from "node:fs";
12
+ import { join } from "node:path";
13
+ import { wrap } from "./_shared.mjs";
14
+
15
+ const HEARTBEAT_FILE = ".harness/traces/heartbeat.jsonl";
16
+
17
+ function resolveHeartbeatPath(repoRoot) {
18
+ return join(repoRoot ?? process.cwd(), HEARTBEAT_FILE);
19
+ }
20
+
21
+ /**
22
+ * @param {string} repoRoot
23
+ * @returns {Array<{session_id: string, started_at: string, last_heartbeat_at: string, status: string}>}
24
+ */
25
+ function readSessions(repoRoot) {
26
+ const fp = resolveHeartbeatPath(repoRoot);
27
+ if (!existsSync(fp)) return [];
28
+ try {
29
+ const raw = readFileSync(fp, "utf-8");
30
+ const lines = raw.split("\n").filter(Boolean);
31
+ // Deduplicate by session_id, keeping the last record per session
32
+ const map = new Map();
33
+ for (const line of lines) {
34
+ try {
35
+ const rec = JSON.parse(line);
36
+ if (rec?.session_id) map.set(rec.session_id, rec);
37
+ } catch {
38
+ // skip malformed lines
39
+ }
40
+ }
41
+ return Array.from(map.values());
42
+ } catch {
43
+ return [];
44
+ }
45
+ }
46
+
47
+ export function createSessionsRouter({ projectRoot = process.cwd() } = {}) {
48
+ const router = Router();
49
+
50
+ // GET /api/sessions
51
+ router.get("/sessions", wrap(async (_req, res) => {
52
+ const sessions = readSessions(projectRoot);
53
+ res.json({ sessions });
54
+ }));
55
+
56
+ // POST /api/sessions/:id/stop
57
+ router.post("/sessions/:id/stop", wrap(async (req, res) => {
58
+ const id = String(req.params?.id ?? "").trim();
59
+ if (!id) {
60
+ res.status(400).json({ error: "bad_request", message: "session id is required" });
61
+ return;
62
+ }
63
+ const fp = resolveHeartbeatPath(projectRoot);
64
+ // Ensure parent dir exists
65
+ const dir = join(fp, "..");
66
+ if (!existsSync(dir)) {
67
+ mkdirSync(dir, { recursive: true });
68
+ }
69
+ const record = {
70
+ session_id: id,
71
+ started_at: new Date().toISOString(),
72
+ last_heartbeat_at: new Date().toISOString(),
73
+ status: "done",
74
+ };
75
+ appendFileSync(fp, JSON.stringify(record) + "\n", "utf-8");
76
+ res.json({ session_id: id, status: "done" });
77
+ }));
78
+
79
+ return router;
80
+ }
@@ -436,32 +436,6 @@ export async function createServer({
436
436
  broadcast: localBroadcast,
437
437
  });
438
438
 
439
- // v5.0.0 — Headroom startup hook. Runs after api.mjs is loaded so the
440
- // headroom routes are registered. Errors are caught and logged — startup
441
- // must not fail if Headroom has issues.
442
- //
443
- // v10-S9 — opt-out via BIZAR_HEADROOM_AUTOSTART=0. The hook runs
444
- // `npm install` + a child process spawn which can take 2-5s on cold
445
- // boot. Real users hit this on every dashboard launch; tests hit it
446
- // too. Setting the env var skips the install + child-process spawn
447
- // entirely. Default behaviour is unchanged (settings.json
448
- // `headroom.enabled` still controls).
449
- if (/^(0|false|no|off)$/i.test((process.env.BIZAR_HEADROOM_AUTOSTART || '').trim())) {
450
- console.log('[bizar-dash] headroom startup skipped (BIZAR_HEADROOM_AUTOSTART=0)');
451
- } else {
452
- const { headroomStartupHook } = await import('./headroom.mjs');
453
- try {
454
- const settings = readSettings();
455
- if (settings?.data?.headroom) {
456
- headroomStartupHook(settings.data.headroom).catch((err) => {
457
- console.warn('[bizar-dash] headroomStartupHook error:', err?.message || err);
458
- });
459
- }
460
- } catch (err) {
461
- console.warn('[bizar-dash] headroom startup hook skipped:', err?.message || err);
462
- }
463
- }
464
-
465
439
  // v5.5.2 — Auto-migrate legacy git.repoPath from the old vault location
466
440
  // to the new default. Runs before the lightrag hook so git-dependent
467
441
  // checks are already correct.
@@ -479,7 +453,7 @@ export async function createServer({
479
453
  console.warn('[bizar-dash] git.repoPath migration check failed:', err?.message || err);
480
454
  }
481
455
 
482
- // v5.x — LightRAG startup hook (issue #6). Mirrors the headroom hook:
456
+ // v5.x — LightRAG startup hook (issue #6).
483
457
  // reads config from .bizar/memory.json + env vars, then calls
484
458
  // lightragStartupHook() which respects `lightrag.enabled` and the
485
459
  // BIZAR_LIGHTRAG_AUTOSTART env override. All errors are caught — the