@ashlr/hub 3.11.5 → 3.13.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 (408) hide show
  1. package/CHANGELOG.md +153 -0
  2. package/README.md +29 -16
  3. package/dist/authority-surface.json +91 -45
  4. package/dist/build-identity.json +2 -2
  5. package/dist/cli/authority.d.ts +145 -33
  6. package/dist/cli/authority.js +1196 -313
  7. package/dist/cli/authority.js.map +1 -1
  8. package/dist/cli/cloud.js +12 -3
  9. package/dist/cli/cloud.js.map +1 -1
  10. package/dist/core/authority/protected-paths.js +11 -0
  11. package/dist/core/authority/protected-paths.js.map +1 -1
  12. package/dist/core/authority/resident.d.ts +101 -0
  13. package/dist/core/authority/resident.js +246 -0
  14. package/dist/core/authority/resident.js.map +1 -0
  15. package/dist/core/authority/trust-roots.js +7 -1
  16. package/dist/core/authority/trust-roots.js.map +1 -1
  17. package/dist/core/authority/types.d.ts +43 -0
  18. package/dist/core/authority/types.js +6 -0
  19. package/dist/core/authority/types.js.map +1 -1
  20. package/dist/core/cloud/budget.js +11 -1
  21. package/dist/core/cloud/budget.js.map +1 -1
  22. package/dist/core/cloud/cloud-api.d.ts +25 -2
  23. package/dist/core/cloud/cloud-api.js +139 -5
  24. package/dist/core/cloud/cloud-api.js.map +1 -1
  25. package/dist/core/cloud/pr-actions.d.ts +93 -0
  26. package/dist/core/cloud/pr-actions.js +436 -0
  27. package/dist/core/cloud/pr-actions.js.map +1 -0
  28. package/dist/core/cloud/pr-preview.d.ts +128 -0
  29. package/dist/core/cloud/pr-preview.js +228 -0
  30. package/dist/core/cloud/pr-preview.js.map +1 -0
  31. package/dist/core/cloud/store.d.ts +2 -0
  32. package/dist/core/cloud/store.js +28 -0
  33. package/dist/core/cloud/store.js.map +1 -1
  34. package/dist/core/cloud/timeline-api.d.ts +24 -0
  35. package/dist/core/cloud/timeline-api.js +46 -0
  36. package/dist/core/cloud/timeline-api.js.map +1 -0
  37. package/dist/core/cloud/timeline-types.d.ts +62 -0
  38. package/dist/core/cloud/timeline-types.js +36 -0
  39. package/dist/core/cloud/timeline-types.js.map +1 -0
  40. package/dist/core/cloud/timeline.d.ts +102 -0
  41. package/dist/core/cloud/timeline.js +919 -0
  42. package/dist/core/cloud/timeline.js.map +1 -0
  43. package/dist/core/cloud/tracker.js +67 -0
  44. package/dist/core/cloud/tracker.js.map +1 -1
  45. package/dist/core/cloud/types.d.ts +38 -0
  46. package/dist/core/cloud/types.js +1 -1
  47. package/dist/core/cloud/types.js.map +1 -1
  48. package/dist/core/daemon/service-install-authority.d.ts +10 -2
  49. package/dist/core/daemon/service-install-authority.js +14 -5
  50. package/dist/core/daemon/service-install-authority.js.map +1 -1
  51. package/dist/core/daemon/service.d.ts +15 -0
  52. package/dist/core/daemon/service.js +26 -0
  53. package/dist/core/daemon/service.js.map +1 -1
  54. package/dist/core/fleet/cloud-intake.d.ts +95 -0
  55. package/dist/core/fleet/cloud-intake.js +557 -0
  56. package/dist/core/fleet/cloud-intake.js.map +1 -0
  57. package/dist/core/fleet/dispatch-router.d.ts +13 -0
  58. package/dist/core/fleet/dispatch-router.js +32 -8
  59. package/dist/core/fleet/dispatch-router.js.map +1 -1
  60. package/dist/core/fleet/fleet-merge-state.d.ts +10 -0
  61. package/dist/core/fleet/fleet-merge-state.js.map +1 -1
  62. package/dist/core/fleet/host-merge.d.ts +5 -0
  63. package/dist/core/fleet/host-merge.js +11 -0
  64. package/dist/core/fleet/host-merge.js.map +1 -1
  65. package/dist/core/fleet/merge-gates.d.ts +8 -0
  66. package/dist/core/fleet/merge-gates.js +25 -5
  67. package/dist/core/fleet/merge-gates.js.map +1 -1
  68. package/dist/core/fleet/standing-merge-pass.js +30 -0
  69. package/dist/core/fleet/standing-merge-pass.js.map +1 -1
  70. package/dist/core/fleet/tick-hooks-live.d.ts +9 -0
  71. package/dist/core/fleet/tick-hooks-live.js +44 -5
  72. package/dist/core/fleet/tick-hooks-live.js.map +1 -1
  73. package/dist/core/fleet/verify-check-run.d.ts +90 -0
  74. package/dist/core/fleet/verify-check-run.js +274 -0
  75. package/dist/core/fleet/verify-check-run.js.map +1 -0
  76. package/dist/core/routing/budget-api.d.ts +11 -0
  77. package/dist/core/routing/budget-api.js +64 -8
  78. package/dist/core/routing/budget-api.js.map +1 -1
  79. package/dist/core/routing/budget-store.d.ts +22 -1
  80. package/dist/core/routing/budget-store.js +22 -8
  81. package/dist/core/routing/budget-store.js.map +1 -1
  82. package/dist/core/universe/builtins/preparation/manifest.json +1 -1
  83. package/dist/core/universe/builtins/preparation/preparation-bridge.mjs +8 -2
  84. package/dist/core/universe/builtins/preparation/preparation-verification-fixtures.mjs +7 -1
  85. package/dist/core/verse/account-health.js +9 -3
  86. package/dist/core/verse/account-health.js.map +1 -1
  87. package/dist/core/verse/activity-api.d.ts +5 -1
  88. package/dist/core/verse/activity-api.js +62 -14
  89. package/dist/core/verse/activity-api.js.map +1 -1
  90. package/dist/core/verse/authority-api.d.ts +9 -1
  91. package/dist/core/verse/authority-api.js +82 -2
  92. package/dist/core/verse/authority-api.js.map +1 -1
  93. package/dist/core/verse/seat-readiness.d.ts +25 -0
  94. package/dist/core/verse/seat-readiness.js +43 -6
  95. package/dist/core/verse/seat-readiness.js.map +1 -1
  96. package/dist/core/verse/verse-api.d.ts +3 -1
  97. package/dist/core/verse/verse-api.js +6 -0
  98. package/dist/core/verse/verse-api.js.map +1 -1
  99. package/dist/core/web/public/next/assets/{ActionMenu-DffwPklw.js → ActionMenu-Dwjk6rUQ.js} +2 -2
  100. package/dist/core/web/public/next/assets/{ActionMenu-DffwPklw.js.map → ActionMenu-Dwjk6rUQ.js.map} +1 -1
  101. package/dist/core/web/public/next/assets/Advanced-cVYTAsfB.js +2 -0
  102. package/dist/core/web/public/next/assets/{Advanced-CxzE6ekM.js.map → Advanced-cVYTAsfB.js.map} +1 -1
  103. package/dist/core/web/public/next/assets/App-IsaWDsdF.js +7 -0
  104. package/dist/core/web/public/next/assets/{App-DFlp-vdv.js.map → App-IsaWDsdF.js.map} +1 -1
  105. package/dist/core/web/public/next/assets/AppsSection-DDqeSrty.js +2 -0
  106. package/dist/core/web/public/next/assets/{AppsSection-Ct2O605-.js.map → AppsSection-DDqeSrty.js.map} +1 -1
  107. package/dist/core/web/public/next/assets/{AreaTrend-o-GLl2Is.js → AreaTrend-C32rUaxm.js} +2 -2
  108. package/dist/core/web/public/next/assets/{AreaTrend-o-GLl2Is.js.map → AreaTrend-C32rUaxm.js.map} +1 -1
  109. package/dist/core/web/public/next/assets/AutonomyOffState-CmSSTHVe.css +1 -0
  110. package/dist/core/web/public/next/assets/AutonomyOffState-CpFYS3tQ.js +3 -0
  111. package/dist/core/web/public/next/assets/AutonomyOffState-CpFYS3tQ.js.map +1 -0
  112. package/dist/core/web/public/next/assets/AutonomySection-Dwn8UtOy.js +2 -0
  113. package/dist/core/web/public/next/assets/{AutonomySection-BTg7yVa1.js.map → AutonomySection-Dwn8UtOy.js.map} +1 -1
  114. package/dist/core/web/public/next/assets/{BranchBar-BjPFtGsj.js → BranchBar-ISZ7xUCj.js} +2 -2
  115. package/dist/core/web/public/next/assets/{BranchBar-BjPFtGsj.js.map → BranchBar-ISZ7xUCj.js.map} +1 -1
  116. package/dist/core/web/public/next/assets/BudgetControl-BARVp-En.js +2 -0
  117. package/dist/core/web/public/next/assets/BudgetControl-BARVp-En.js.map +1 -0
  118. package/dist/core/web/public/next/assets/{Button-OjVJSrFq.js → Button-DtE0rlWD.js} +2 -2
  119. package/dist/core/web/public/next/assets/{Button-OjVJSrFq.js.map → Button-DtE0rlWD.js.map} +1 -1
  120. package/dist/core/web/public/next/assets/{CapacityStrip-Bx4c3dxD.js → CapacityStrip-DKbKA_Aa.js} +2 -2
  121. package/dist/core/web/public/next/assets/{CapacityStrip-Bx4c3dxD.js.map → CapacityStrip-DKbKA_Aa.js.map} +1 -1
  122. package/dist/core/web/public/next/assets/{ChartFrame-B_w2Siqg.js → ChartFrame-DK_BDXCt.js} +2 -2
  123. package/dist/core/web/public/next/assets/{ChartFrame-B_w2Siqg.js.map → ChartFrame-DK_BDXCt.js.map} +1 -1
  124. package/dist/core/web/public/next/assets/ChatSection-C9myY4ei.js +3 -0
  125. package/dist/core/web/public/next/assets/ChatSection-C9myY4ei.js.map +1 -0
  126. package/dist/core/web/public/next/assets/{CloudBudgetForm-5Gf4iAok.js → CloudBudgetForm-CvjK4Oh6.js} +2 -2
  127. package/dist/core/web/public/next/assets/{CloudBudgetForm-5Gf4iAok.js.map → CloudBudgetForm-CvjK4Oh6.js.map} +1 -1
  128. package/dist/core/web/public/next/assets/{CommandPalette-iTpk6I8r.js → CommandPalette-DzPsth0u.js} +2 -2
  129. package/dist/core/web/public/next/assets/{CommandPalette-iTpk6I8r.js.map → CommandPalette-DzPsth0u.js.map} +1 -1
  130. package/dist/core/web/public/next/assets/CommandSection-Brp73iox.js +3 -0
  131. package/dist/core/web/public/next/assets/CommandSection-Brp73iox.js.map +1 -0
  132. package/dist/core/web/public/next/assets/{ConfirmDialog-_S9iE-cJ.js → ConfirmDialog-CLUhzaBj.js} +2 -2
  133. package/dist/core/web/public/next/assets/{ConfirmDialog-_S9iE-cJ.js.map → ConfirmDialog-CLUhzaBj.js.map} +1 -1
  134. package/dist/core/web/public/next/assets/{DeleteChatDialog-KUYUygiA.js → DeleteChatDialog-C_eDhV8b.js} +2 -2
  135. package/dist/core/web/public/next/assets/{DeleteChatDialog-KUYUygiA.js.map → DeleteChatDialog-C_eDhV8b.js.map} +1 -1
  136. package/dist/core/web/public/next/assets/{Dialog-BuIaG6HF.js → Dialog-BRd_B9OE.js} +2 -2
  137. package/dist/core/web/public/next/assets/{Dialog-BuIaG6HF.js.map → Dialog-BRd_B9OE.js.map} +1 -1
  138. package/dist/core/web/public/next/assets/{DiffPane-De4IQt82.js → DiffPane-Cpr9soB2.js} +2 -2
  139. package/dist/core/web/public/next/assets/{DiffPane-De4IQt82.js.map → DiffPane-Cpr9soB2.js.map} +1 -1
  140. package/dist/core/web/public/next/assets/{DiffViewer-B75t6Ile.js → DiffViewer-CNwd0W3Q.js} +2 -2
  141. package/dist/core/web/public/next/assets/{DiffViewer-B75t6Ile.js.map → DiffViewer-CNwd0W3Q.js.map} +1 -1
  142. package/dist/core/web/public/next/assets/DockHost-BcEq2qaS.js +2 -0
  143. package/dist/core/web/public/next/assets/{DockHost-BPqyhtCP.js.map → DockHost-BcEq2qaS.js.map} +1 -1
  144. package/dist/core/web/public/next/assets/{EmptyState-DXkT4vhW.js → EmptyState-DsN1H6MC.js} +2 -2
  145. package/dist/core/web/public/next/assets/{EmptyState-DXkT4vhW.js.map → EmptyState-DsN1H6MC.js.map} +1 -1
  146. package/dist/core/web/public/next/assets/{Epistemic-CfqFe_aP.js → Epistemic-fycQTBRO.js} +2 -2
  147. package/dist/core/web/public/next/assets/{Epistemic-CfqFe_aP.js.map → Epistemic-fycQTBRO.js.map} +1 -1
  148. package/dist/core/web/public/next/assets/EvidenceTimeline-PBDAiSuG.css +1 -0
  149. package/dist/core/web/public/next/assets/EvidenceTimeline-sCCAdnBK.js +2 -0
  150. package/dist/core/web/public/next/assets/EvidenceTimeline-sCCAdnBK.js.map +1 -0
  151. package/dist/core/web/public/next/assets/{FleetSection-B7f-XBiX.js → FleetSection-BG8iGraG.js} +3 -3
  152. package/dist/core/web/public/next/assets/{FleetSection-B7f-XBiX.js.map → FleetSection-BG8iGraG.js.map} +1 -1
  153. package/dist/core/web/public/next/assets/{Funnel-pXYySwXQ.js → Funnel-B88_wpA4.js} +2 -2
  154. package/dist/core/web/public/next/assets/{Funnel-pXYySwXQ.js.map → Funnel-B88_wpA4.js.map} +1 -1
  155. package/dist/core/web/public/next/assets/{GearTray-gj6lT7ba.js → GearTray-CpDt0xwj.js} +2 -2
  156. package/dist/core/web/public/next/assets/{GearTray-gj6lT7ba.js.map → GearTray-CpDt0xwj.js.map} +1 -1
  157. package/dist/core/web/public/next/assets/{GrowthSection-D8e9m9Wy.js → GrowthSection-BvZezOsX.js} +2 -2
  158. package/dist/core/web/public/next/assets/{GrowthSection-D8e9m9Wy.js.map → GrowthSection-BvZezOsX.js.map} +1 -1
  159. package/dist/core/web/public/next/assets/{HandoffDialog-VfKxKhxF.js → HandoffDialog-B1G6gQyk.js} +2 -2
  160. package/dist/core/web/public/next/assets/{HandoffDialog-VfKxKhxF.js.map → HandoffDialog-B1G6gQyk.js.map} +1 -1
  161. package/dist/core/web/public/next/assets/{Input-u1YR_Ogl.js → Input-CI0yBHmn.js} +2 -2
  162. package/dist/core/web/public/next/assets/{Input-u1YR_Ogl.js.map → Input-CI0yBHmn.js.map} +1 -1
  163. package/dist/core/web/public/next/assets/{LeaderCard-BDELBrnx.js → LeaderCard-BxxiEg4e.js} +2 -2
  164. package/dist/core/web/public/next/assets/{LeaderCard-BDELBrnx.js.map → LeaderCard-BxxiEg4e.js.map} +1 -1
  165. package/dist/core/web/public/next/assets/{MatrixHeatmap-NKLF2srR.js → MatrixHeatmap-iPFEU2Tv.js} +2 -2
  166. package/dist/core/web/public/next/assets/{MatrixHeatmap-NKLF2srR.js.map → MatrixHeatmap-iPFEU2Tv.js.map} +1 -1
  167. package/dist/core/web/public/next/assets/McpSection-nuXer4K-.js +2 -0
  168. package/dist/core/web/public/next/assets/{McpSection-D1tDvlRa.js.map → McpSection-nuXer4K-.js.map} +1 -1
  169. package/dist/core/web/public/next/assets/{MessageMarkdown-DlfLEJxu.js → MessageMarkdown-BCe4TsXk.js} +3 -3
  170. package/dist/core/web/public/next/assets/{MessageMarkdown-DlfLEJxu.js.map → MessageMarkdown-BCe4TsXk.js.map} +1 -1
  171. package/dist/core/web/public/next/assets/{MessageMarkdownRenderer-BYZzI115.js → MessageMarkdownRenderer-DL3LU5kL.js} +2 -2
  172. package/dist/core/web/public/next/assets/{MessageMarkdownRenderer-BYZzI115.js.map → MessageMarkdownRenderer-DL3LU5kL.js.map} +1 -1
  173. package/dist/core/web/public/next/assets/{Meter-BSVhU43Q.js → Meter-b69LM0mU.js} +2 -2
  174. package/dist/core/web/public/next/assets/{Meter-BSVhU43Q.js.map → Meter-b69LM0mU.js.map} +1 -1
  175. package/dist/core/web/public/next/assets/{MindSection-lqV2e_Sq.js → MindSection-Dc5v5rH3.js} +2 -2
  176. package/dist/core/web/public/next/assets/{MindSection-lqV2e_Sq.js.map → MindSection-Dc5v5rH3.js.map} +1 -1
  177. package/dist/core/web/public/next/assets/{MutationTokenDialog-CLGP72g6.js → MutationTokenDialog-Bm34BNVV.js} +2 -2
  178. package/dist/core/web/public/next/assets/{MutationTokenDialog-CLGP72g6.js.map → MutationTokenDialog-Bm34BNVV.js.map} +1 -1
  179. package/dist/core/web/public/next/assets/NeedsYouDrawer-N1cWJjpz.js +3 -0
  180. package/dist/core/web/public/next/assets/NeedsYouDrawer-N1cWJjpz.js.map +1 -0
  181. package/dist/core/web/public/next/assets/NeedsYouList-CH6Mq-E_.css +1 -0
  182. package/dist/core/web/public/next/assets/NeedsYouList-D5Kk549g.js +2 -0
  183. package/dist/core/web/public/next/assets/{NeedsYouList-eBOlJr0b.js.map → NeedsYouList-D5Kk549g.js.map} +1 -1
  184. package/dist/core/web/public/next/assets/{NewChatDialog-DoYTH26M.js → NewChatDialog-BqFTWgHU.js} +2 -2
  185. package/dist/core/web/public/next/assets/{NewChatDialog-DoYTH26M.js.map → NewChatDialog-BqFTWgHU.js.map} +1 -1
  186. package/dist/core/web/public/next/assets/OnboardingFlow-DcDsguAM.js +3 -0
  187. package/dist/core/web/public/next/assets/OnboardingFlow-DcDsguAM.js.map +1 -0
  188. package/dist/core/web/public/next/assets/OnboardingGate-BZafM1Vf.js +3 -0
  189. package/dist/core/web/public/next/assets/{OnboardingGate-DrDEVBqw.js.map → OnboardingGate-BZafM1Vf.js.map} +1 -1
  190. package/dist/core/web/public/next/assets/{PreviewPane-ULN673zm.js → PreviewPane-zT3gK9TD.js} +2 -2
  191. package/dist/core/web/public/next/assets/{PreviewPane-ULN673zm.js.map → PreviewPane-zT3gK9TD.js.map} +1 -1
  192. package/dist/core/web/public/next/assets/{ProviderLogo-8WaUjTlN.js → ProviderLogo-AwHn2sKm.js} +2 -2
  193. package/dist/core/web/public/next/assets/{ProviderLogo-8WaUjTlN.js.map → ProviderLogo-AwHn2sKm.js.map} +1 -1
  194. package/dist/core/web/public/next/assets/{RailStatus-Ckw9nvYU.js → RailStatus-xHrovWvI.js} +2 -2
  195. package/dist/core/web/public/next/assets/{RailStatus-Ckw9nvYU.js.map → RailStatus-xHrovWvI.js.map} +1 -1
  196. package/dist/core/web/public/next/assets/{RefreshIndicator-DGubF4vR.js → RefreshIndicator-SEFZlMB2.js} +2 -2
  197. package/dist/core/web/public/next/assets/{RefreshIndicator-DGubF4vR.js.map → RefreshIndicator-SEFZlMB2.js.map} +1 -1
  198. package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-BahEaY4d.js → ResourcePoolConsoleApp-CAxPQ4sZ.js} +3 -3
  199. package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-BahEaY4d.js.map → ResourcePoolConsoleApp-CAxPQ4sZ.js.map} +1 -1
  200. package/dist/core/web/public/next/assets/ResourcesChrome-BnhnEdJe.js +3 -0
  201. package/dist/core/web/public/next/assets/{ResourcesChrome-C2ZrA7la.js.map → ResourcesChrome-BnhnEdJe.js.map} +1 -1
  202. package/dist/core/web/public/next/assets/{ResourcesDrawer-BC93fzwQ.js → ResourcesDrawer-BAFGodny.js} +2 -2
  203. package/dist/core/web/public/next/assets/{ResourcesDrawer-BC93fzwQ.js.map → ResourcesDrawer-BAFGodny.js.map} +1 -1
  204. package/dist/core/web/public/next/assets/{RouteErrorBoundary-BvhHNpE_.js → RouteErrorBoundary-C8WGiixc.js} +2 -2
  205. package/dist/core/web/public/next/assets/{RouteErrorBoundary-BvhHNpE_.js.map → RouteErrorBoundary-C8WGiixc.js.map} +1 -1
  206. package/dist/core/web/public/next/assets/{RunInCloudAction-Dywfnw0C.js → RunInCloudAction-1-IPLYhf.js} +2 -2
  207. package/dist/core/web/public/next/assets/{RunInCloudAction-Dywfnw0C.js.map → RunInCloudAction-1-IPLYhf.js.map} +1 -1
  208. package/dist/core/web/public/next/assets/{SeatSelector-CH7hTgwy.js → SeatSelector-DpwNiX8F.js} +2 -2
  209. package/dist/core/web/public/next/assets/{SeatSelector-CH7hTgwy.js.map → SeatSelector-DpwNiX8F.js.map} +1 -1
  210. package/dist/core/web/public/next/assets/{Segmented-Wynbg0F5.js → Segmented-Wt1ATod9.js} +2 -2
  211. package/dist/core/web/public/next/assets/{Segmented-Wynbg0F5.js.map → Segmented-Wt1ATod9.js.map} +1 -1
  212. package/dist/core/web/public/next/assets/{Select-DMyLCkId.js → Select-By-V9lMc.js} +2 -2
  213. package/dist/core/web/public/next/assets/{Select-DMyLCkId.js.map → Select-By-V9lMc.js.map} +1 -1
  214. package/dist/core/web/public/next/assets/{SessionGate-8RtQFWeZ.js → SessionGate-WROS02tK.js} +2 -2
  215. package/dist/core/web/public/next/assets/{SessionGate-8RtQFWeZ.js.map → SessionGate-WROS02tK.js.map} +1 -1
  216. package/dist/core/web/public/next/assets/{SessionInsightChip-zBJbKv2L.js → SessionInsightChip-DNUcruwp.js} +2 -2
  217. package/dist/core/web/public/next/assets/{SessionInsightChip-zBJbKv2L.js.map → SessionInsightChip-DNUcruwp.js.map} +1 -1
  218. package/dist/core/web/public/next/assets/{SessionSearch-DfJIcxxM.js → SessionSearch-UHtt7a8f.js} +2 -2
  219. package/dist/core/web/public/next/assets/{SessionSearch-DfJIcxxM.js.map → SessionSearch-UHtt7a8f.js.map} +1 -1
  220. package/dist/core/web/public/next/assets/{SettingsSection-Da9RYyH5.js → SettingsSection-Bf74l0Gj.js} +2 -2
  221. package/dist/core/web/public/next/assets/{SettingsSection-Da9RYyH5.js.map → SettingsSection-Bf74l0Gj.js.map} +1 -1
  222. package/dist/core/web/public/next/assets/SetupChecklist-BhZpFLsj.css +1 -0
  223. package/dist/core/web/public/next/assets/SetupChecklist-CzpEcfOl.js +2 -0
  224. package/dist/core/web/public/next/assets/SetupChecklist-CzpEcfOl.js.map +1 -0
  225. package/dist/core/web/public/next/assets/{Sheet-DhXyIDmq.js → Sheet-HkBOBMTT.js} +2 -2
  226. package/dist/core/web/public/next/assets/{Sheet-DhXyIDmq.js.map → Sheet-HkBOBMTT.js.map} +1 -1
  227. package/dist/core/web/public/next/assets/{ShortcutsOverlay-Bi5f-wUw.js → ShortcutsOverlay-DiigiT8H.js} +2 -2
  228. package/dist/core/web/public/next/assets/{ShortcutsOverlay-Bi5f-wUw.js.map → ShortcutsOverlay-DiigiT8H.js.map} +1 -1
  229. package/dist/core/web/public/next/assets/Sidebar-C9YtBYVZ.js +3 -0
  230. package/dist/core/web/public/next/assets/Sidebar-C9YtBYVZ.js.map +1 -0
  231. package/dist/core/web/public/next/assets/{Slider-Bd9YFWEV.js → Slider-DaEDws-b.js} +2 -2
  232. package/dist/core/web/public/next/assets/{Slider-Bd9YFWEV.js.map → Slider-DaEDws-b.js.map} +1 -1
  233. package/dist/core/web/public/next/assets/{StatTile-DScTd3c-.js → StatTile-CTX41O6y.js} +2 -2
  234. package/dist/core/web/public/next/assets/{StatTile-DScTd3c-.js.map → StatTile-CTX41O6y.js.map} +1 -1
  235. package/dist/core/web/public/next/assets/{StatusBadge-DQ1UtQAJ.js → StatusBadge-CXG3iNL4.js} +2 -2
  236. package/dist/core/web/public/next/assets/{StatusBadge-DQ1UtQAJ.js.map → StatusBadge-CXG3iNL4.js.map} +1 -1
  237. package/dist/core/web/public/next/assets/{StepBand-BB3IJxhr.js → StepBand-jJTqYIdX.js} +2 -2
  238. package/dist/core/web/public/next/assets/{StepBand-BB3IJxhr.js.map → StepBand-jJTqYIdX.js.map} +1 -1
  239. package/dist/core/web/public/next/assets/{Surface-DWMtQe3Q.js → Surface-5bNA08tK.js} +2 -2
  240. package/dist/core/web/public/next/assets/{Surface-DWMtQe3Q.js.map → Surface-5bNA08tK.js.map} +1 -1
  241. package/dist/core/web/public/next/assets/{Swimlane-DcENqtdp.js → Swimlane-LrslsGxw.js} +2 -2
  242. package/dist/core/web/public/next/assets/{Swimlane-DcENqtdp.js.map → Swimlane-LrslsGxw.js.map} +1 -1
  243. package/dist/core/web/public/next/assets/{Switch-CenChEYf.js → Switch-BmCzfFnu.js} +2 -2
  244. package/dist/core/web/public/next/assets/{Switch-CenChEYf.js.map → Switch-BmCzfFnu.js.map} +1 -1
  245. package/dist/core/web/public/next/assets/{Tag-D4k5E3u0.js → Tag-WSUIaMVy.js} +2 -2
  246. package/dist/core/web/public/next/assets/{Tag-D4k5E3u0.js.map → Tag-WSUIaMVy.js.map} +1 -1
  247. package/dist/core/web/public/next/assets/{TerminalPane-DCQTukcE.js → TerminalPane-BVFgYX6K.js} +5 -5
  248. package/dist/core/web/public/next/assets/{TerminalPane-DCQTukcE.js.map → TerminalPane-BVFgYX6K.js.map} +1 -1
  249. package/dist/core/web/public/next/assets/{UniverseConsoleApp-DsuWT0pi.js → UniverseConsoleApp-BpphLqoz.js} +2 -2
  250. package/dist/core/web/public/next/assets/{UniverseConsoleApp-DsuWT0pi.js.map → UniverseConsoleApp-BpphLqoz.js.map} +1 -1
  251. package/dist/core/web/public/next/assets/{UniverseView-DyI5ApsA.js → UniverseView-DbpbSMwO.js} +4 -4
  252. package/dist/core/web/public/next/assets/{UniverseView-DyI5ApsA.js.map → UniverseView-DbpbSMwO.js.map} +1 -1
  253. package/dist/core/web/public/next/assets/{UsageSection-Imr28nwK.js → UsageSection-CUlaKtws.js} +3 -3
  254. package/dist/core/web/public/next/assets/{UsageSection-Imr28nwK.js.map → UsageSection-CUlaKtws.js.map} +1 -1
  255. package/dist/core/web/public/next/assets/VerseConsoleApp-DXDv1aOi.js +3 -0
  256. package/dist/core/web/public/next/assets/VerseConsoleApp-DXDv1aOi.js.map +1 -0
  257. package/dist/core/web/public/next/assets/{Workspace-CpxBO98E.js → Workspace-RXy0pqp6.js} +5 -5
  258. package/dist/core/web/public/next/assets/{Workspace-CpxBO98E.js.map → Workspace-RXy0pqp6.js.map} +1 -1
  259. package/dist/core/web/public/next/assets/{actions-DE8NoWV_.js → actions-BZTidCXZ.js} +2 -2
  260. package/dist/core/web/public/next/assets/{actions-DE8NoWV_.js.map → actions-BZTidCXZ.js.map} +1 -1
  261. package/dist/core/web/public/next/assets/{apps-model-CFGCUu9p.js → apps-model-CHO133qt.js} +2 -2
  262. package/dist/core/web/public/next/assets/{apps-model-CFGCUu9p.js.map → apps-model-CHO133qt.js.map} +1 -1
  263. package/dist/core/web/public/next/assets/{authority-model-CmnfJzmM.js → authority-model-8NeAEwAF.js} +2 -2
  264. package/dist/core/web/public/next/assets/{authority-model-CmnfJzmM.js.map → authority-model-8NeAEwAF.js.map} +1 -1
  265. package/dist/core/web/public/next/assets/{budget-queries-DjrPRFwl.js → budget-queries-DFF-3ICg.js} +2 -2
  266. package/dist/core/web/public/next/assets/{budget-queries-DjrPRFwl.js.map → budget-queries-DFF-3ICg.js.map} +1 -1
  267. package/dist/core/web/public/next/assets/{capacity-strip-model-C7cdQnuK.js → capacity-strip-model-5ViUgUlP.js} +2 -2
  268. package/dist/core/web/public/next/assets/{capacity-strip-model-C7cdQnuK.js.map → capacity-strip-model-5ViUgUlP.js.map} +1 -1
  269. package/dist/core/web/public/next/assets/{charts-DUD_jprE.js → charts-CzxWrZn7.js} +2 -2
  270. package/dist/core/web/public/next/assets/{charts-DUD_jprE.js.map → charts-CzxWrZn7.js.map} +1 -1
  271. package/dist/core/web/public/next/assets/cloud-model-CfRydq8N.js +2 -0
  272. package/dist/core/web/public/next/assets/{cloud-model-DoxBMDvx.js.map → cloud-model-CfRydq8N.js.map} +1 -1
  273. package/dist/core/web/public/next/assets/{cloud-queries-CTGvO-k-.js → cloud-queries-DmptbjS8.js} +2 -2
  274. package/dist/core/web/public/next/assets/{cloud-queries-CTGvO-k-.js.map → cloud-queries-DmptbjS8.js.map} +1 -1
  275. package/dist/core/web/public/next/assets/{command-catalog-CmrHNFzh.js → command-catalog-ffCAijVY.js} +2 -2
  276. package/dist/core/web/public/next/assets/{command-catalog-CmrHNFzh.js.map → command-catalog-ffCAijVY.js.map} +1 -1
  277. package/dist/core/web/public/next/assets/{context-model-2Owp2jYF.js → context-model-Bb15chFt.js} +2 -2
  278. package/dist/core/web/public/next/assets/{context-model-2Owp2jYF.js.map → context-model-Bb15chFt.js.map} +1 -1
  279. package/dist/core/web/public/next/assets/{context-model-9xywbXxX.js → context-model-CDeyP0cA.js} +2 -2
  280. package/dist/core/web/public/next/assets/{context-model-9xywbXxX.js.map → context-model-CDeyP0cA.js.map} +1 -1
  281. package/dist/core/web/public/next/assets/{context-queries-wvcRnV-I.js → context-queries-_9bFWb9v.js} +2 -2
  282. package/dist/core/web/public/next/assets/{context-queries-wvcRnV-I.js.map → context-queries-_9bFWb9v.js.map} +1 -1
  283. package/dist/core/web/public/next/assets/{control-queries-DB6Kh7UN.js → control-queries-CXtmZZH6.js} +2 -2
  284. package/dist/core/web/public/next/assets/{control-queries-DB6Kh7UN.js.map → control-queries-CXtmZZH6.js.map} +1 -1
  285. package/dist/core/web/public/next/assets/copy-setup-BIp0iaiZ.js +2 -0
  286. package/dist/core/web/public/next/assets/copy-setup-BIp0iaiZ.js.map +1 -0
  287. package/dist/core/web/public/next/assets/{dock-icons-BBUGl4tE.js → dock-icons-Cc43W7r4.js} +2 -2
  288. package/dist/core/web/public/next/assets/{dock-icons-BBUGl4tE.js.map → dock-icons-Cc43W7r4.js.map} +1 -1
  289. package/dist/core/web/public/next/assets/{fleet-model-BRfRWkZl.js → fleet-model-DOK8ZtEt.js} +2 -2
  290. package/dist/core/web/public/next/assets/{fleet-model-BRfRWkZl.js.map → fleet-model-DOK8ZtEt.js.map} +1 -1
  291. package/dist/core/web/public/next/assets/{fleet-queries-tU6UEXN2.js → fleet-queries-BeEAqD6y.js} +2 -2
  292. package/dist/core/web/public/next/assets/{fleet-queries-tU6UEXN2.js.map → fleet-queries-BeEAqD6y.js.map} +1 -1
  293. package/dist/core/web/public/next/assets/{focus-trap-BGOceFvj.js → focus-trap-ChZ5EFfM.js} +2 -2
  294. package/dist/core/web/public/next/assets/{focus-trap-BGOceFvj.js.map → focus-trap-ChZ5EFfM.js.map} +1 -1
  295. package/dist/core/web/public/next/assets/format-BmH2yWL6.js +2 -0
  296. package/dist/core/web/public/next/assets/format-BmH2yWL6.js.map +1 -0
  297. package/dist/core/web/public/next/assets/{git-model-53iRLInY.js → git-model-BFwAVbxF.js} +2 -2
  298. package/dist/core/web/public/next/assets/{git-model-53iRLInY.js.map → git-model-BFwAVbxF.js.map} +1 -1
  299. package/dist/core/web/public/next/assets/global-y_exIyAP.js +2 -0
  300. package/dist/core/web/public/next/assets/{global-CXHHMz9o.js.map → global-y_exIyAP.js.map} +1 -1
  301. package/dist/core/web/public/next/assets/{guarded-runners-B8zFVBVZ.js → guarded-runners-Cd4POBtI.js} +2 -2
  302. package/dist/core/web/public/next/assets/{guarded-runners-B8zFVBVZ.js.map → guarded-runners-Cd4POBtI.js.map} +1 -1
  303. package/dist/core/web/public/next/assets/{icons-D4s-jlxX.js → icons-CygCEFWs.js} +2 -2
  304. package/dist/core/web/public/next/assets/{icons-D4s-jlxX.js.map → icons-CygCEFWs.js.map} +1 -1
  305. package/dist/core/web/public/next/assets/{index-BG177cPN.js → index-CyK31YRm.js} +3 -3
  306. package/dist/core/web/public/next/assets/{index-BG177cPN.js.map → index-CyK31YRm.js.map} +1 -1
  307. package/dist/core/web/public/next/assets/{live-model-CEf01wrW.js → live-model-D7hilYFk.js} +2 -2
  308. package/dist/core/web/public/next/assets/live-model-D7hilYFk.js.map +1 -0
  309. package/dist/core/web/public/next/assets/{mind.module-D_xk6HIQ.js → mind.module-B15k0Y9q.js} +2 -2
  310. package/dist/core/web/public/next/assets/{mind.module-D_xk6HIQ.js.map → mind.module-B15k0Y9q.js.map} +1 -1
  311. package/dist/core/web/public/next/assets/mutations-CWlxEMEm.js +2 -0
  312. package/dist/core/web/public/next/assets/{mutations-CbTSofVH.js.map → mutations-CWlxEMEm.js.map} +1 -1
  313. package/dist/core/web/public/next/assets/{nav-CmZcbPFJ.js → nav-mimleI0R.js} +2 -2
  314. package/dist/core/web/public/next/assets/{nav-CmZcbPFJ.js.map → nav-mimleI0R.js.map} +1 -1
  315. package/dist/core/web/public/next/assets/{overnight-queries-CR0b_j-V.js → overnight-queries-DJ4mZKSj.js} +2 -2
  316. package/dist/core/web/public/next/assets/{overnight-queries-CR0b_j-V.js.map → overnight-queries-DJ4mZKSj.js.map} +1 -1
  317. package/dist/core/web/public/next/assets/primitives-DMijqcu0.js +1 -0
  318. package/dist/core/web/public/next/assets/{queries-rvRsAGW2.js → queries-Bw1McHTj.js} +2 -2
  319. package/dist/core/web/public/next/assets/{queries-rvRsAGW2.js.map → queries-Bw1McHTj.js.map} +1 -1
  320. package/dist/core/web/public/next/assets/{reasoning-pref-DMPQkujg.js → reasoning-pref-KkhI_5-j.js} +2 -2
  321. package/dist/core/web/public/next/assets/{reasoning-pref-DMPQkujg.js.map → reasoning-pref-KkhI_5-j.js.map} +1 -1
  322. package/dist/core/web/public/next/assets/{reveal-anchor-BKk2wZZZ.js → reveal-anchor-CCCx_kfT.js} +2 -2
  323. package/dist/core/web/public/next/assets/{reveal-anchor-BKk2wZZZ.js.map → reveal-anchor-CCCx_kfT.js.map} +1 -1
  324. package/dist/core/web/public/next/assets/{seat-subscription-CLn2ReSZ.js → seat-subscription-BhUUz7VL.js} +2 -2
  325. package/dist/core/web/public/next/assets/{seat-subscription-CLn2ReSZ.js.map → seat-subscription-BhUUz7VL.js.map} +1 -1
  326. package/dist/core/web/public/next/assets/{sidebar-model-CjQLvdag.js → sidebar-model-Dcd437cf.js} +2 -2
  327. package/dist/core/web/public/next/assets/{sidebar-model-CjQLvdag.js.map → sidebar-model-Dcd437cf.js.map} +1 -1
  328. package/dist/core/web/public/next/assets/{slots-DRxNosZg.js → slots-BL_J5mmV.js} +3 -3
  329. package/dist/core/web/public/next/assets/{slots-DRxNosZg.js.map → slots-BL_J5mmV.js.map} +1 -1
  330. package/dist/core/web/public/next/assets/{surface-data-DshUC_TU.js → surface-data-C3UAQ4QX.js} +2 -2
  331. package/dist/core/web/public/next/assets/{surface-data-DshUC_TU.js.map → surface-data-C3UAQ4QX.js.map} +1 -1
  332. package/dist/core/web/public/next/assets/surface-prefetch-BXKjPsV5.js +2 -0
  333. package/dist/core/web/public/next/assets/{surface-prefetch-DO8r4ttQ.js.map → surface-prefetch-BXKjPsV5.js.map} +1 -1
  334. package/dist/core/web/public/next/assets/{tasks-model-BKPFZAmZ.js → tasks-model-CzHvclVm.js} +2 -2
  335. package/dist/core/web/public/next/assets/{tasks-model-BKPFZAmZ.js.map → tasks-model-CzHvclVm.js.map} +1 -1
  336. package/dist/core/web/public/next/assets/{terminal-icons-DoeQkP3y.js → terminal-icons-BwgQTQP0.js} +2 -2
  337. package/dist/core/web/public/next/assets/{terminal-icons-DoeQkP3y.js.map → terminal-icons-BwgQTQP0.js.map} +1 -1
  338. package/dist/core/web/public/next/assets/types-IYKrYLku.js +2 -0
  339. package/dist/core/web/public/next/assets/types-IYKrYLku.js.map +1 -0
  340. package/dist/core/web/public/next/assets/{usage-queries-MnUeYzwp.js → usage-queries-pXxvy54x.js} +2 -2
  341. package/dist/core/web/public/next/assets/{usage-queries-MnUeYzwp.js.map → usage-queries-pXxvy54x.js.map} +1 -1
  342. package/dist/core/web/public/next/assets/{use-guarded-action-P12MfNwU.js → use-guarded-action-EgVWjM5c.js} +2 -2
  343. package/dist/core/web/public/next/assets/{use-guarded-action-P12MfNwU.js.map → use-guarded-action-EgVWjM5c.js.map} +1 -1
  344. package/dist/core/web/public/next/assets/{use-ticker-DIvAZ4Ey.js → use-ticker-BoqFxRFG.js} +2 -2
  345. package/dist/core/web/public/next/assets/{use-ticker-DIvAZ4Ey.js.map → use-ticker-BoqFxRFG.js.map} +1 -1
  346. package/dist/core/web/public/next/assets/{use-token-gate-DfEja7Wr.js → use-token-gate-DSNIIpI6.js} +2 -2
  347. package/dist/core/web/public/next/assets/{use-token-gate-DfEja7Wr.js.map → use-token-gate-DSNIIpI6.js.map} +1 -1
  348. package/dist/core/web/public/next/assets/{useOnboarding-CkOHadqC.js → useOnboarding-Bk0VnkxQ.js} +2 -2
  349. package/dist/core/web/public/next/assets/{useOnboarding-CkOHadqC.js.map → useOnboarding-Bk0VnkxQ.js.map} +1 -1
  350. package/dist/core/web/public/next/assets/{useSeatsRefresh-BDlbDlIU.js → useSeatsRefresh-q7Id9RcW.js} +2 -2
  351. package/dist/core/web/public/next/assets/{useSeatsRefresh-BDlbDlIU.js.map → useSeatsRefresh-q7Id9RcW.js.map} +1 -1
  352. package/dist/core/web/public/next/assets/{useVerseTranscript-BGtA55k2.js → useVerseTranscript-CqH51rt9.js} +2 -2
  353. package/dist/core/web/public/next/assets/{useVerseTranscript-BGtA55k2.js.map → useVerseTranscript-CqH51rt9.js.map} +1 -1
  354. package/dist/core/web/public/next/assets/{verse-icons-wOet9JZy.js → verse-icons-DsG1dOQx.js} +2 -2
  355. package/dist/core/web/public/next/assets/{verse-icons-wOet9JZy.js.map → verse-icons-DsG1dOQx.js.map} +1 -1
  356. package/dist/core/web/public/next/assets/{verse-model-CSzzdyu2.js → verse-model-JTuvRBVK.js} +2 -2
  357. package/dist/core/web/public/next/assets/{verse-model-CSzzdyu2.js.map → verse-model-JTuvRBVK.js.map} +1 -1
  358. package/dist/core/web/public/next/assets/{warmup-CecO_Nk0.js → warmup-Bv1RumVq.js} +3 -3
  359. package/dist/core/web/public/next/assets/{warmup-CecO_Nk0.js.map → warmup-Bv1RumVq.js.map} +1 -1
  360. package/dist/core/web/public/next/assets/why-seat-model-Cau8qG6O.js +2 -0
  361. package/dist/core/web/public/next/assets/why-seat-model-Cau8qG6O.js.map +1 -0
  362. package/dist/core/web/public/next/assets/{workspace-model-BdIVybKr.js → workspace-model-D-SLfads.js} +2 -2
  363. package/dist/core/web/public/next/assets/{workspace-model-BdIVybKr.js.map → workspace-model-D-SLfads.js.map} +1 -1
  364. package/dist/core/web/public/next/index.html +1 -1
  365. package/dist/release-dependency-inventory.json +1 -1
  366. package/docs/AUTONOMY-GAP.md +1 -1
  367. package/package.json +1 -1
  368. package/dist/core/web/public/next/assets/Advanced-CxzE6ekM.js +0 -2
  369. package/dist/core/web/public/next/assets/App-DFlp-vdv.js +0 -7
  370. package/dist/core/web/public/next/assets/AppsSection-Ct2O605-.js +0 -2
  371. package/dist/core/web/public/next/assets/AutonomyOffState-CXhXpsim.js +0 -2
  372. package/dist/core/web/public/next/assets/AutonomyOffState-CXhXpsim.js.map +0 -1
  373. package/dist/core/web/public/next/assets/AutonomyOffState-DmbE71vI.css +0 -1
  374. package/dist/core/web/public/next/assets/AutonomySection-BTg7yVa1.js +0 -2
  375. package/dist/core/web/public/next/assets/BudgetControl-ng6swoZp.js +0 -2
  376. package/dist/core/web/public/next/assets/BudgetControl-ng6swoZp.js.map +0 -1
  377. package/dist/core/web/public/next/assets/ChatSection-Bisj9R6E.js +0 -3
  378. package/dist/core/web/public/next/assets/ChatSection-Bisj9R6E.js.map +0 -1
  379. package/dist/core/web/public/next/assets/CommandSection-D8ZihzvE.js +0 -2
  380. package/dist/core/web/public/next/assets/CommandSection-D8ZihzvE.js.map +0 -1
  381. package/dist/core/web/public/next/assets/DockHost-BPqyhtCP.js +0 -2
  382. package/dist/core/web/public/next/assets/McpSection-D1tDvlRa.js +0 -2
  383. package/dist/core/web/public/next/assets/NeedsYouDrawer-D992XTOn.js +0 -2
  384. package/dist/core/web/public/next/assets/NeedsYouDrawer-D992XTOn.js.map +0 -1
  385. package/dist/core/web/public/next/assets/NeedsYouList-CruOt4JT.css +0 -1
  386. package/dist/core/web/public/next/assets/NeedsYouList-eBOlJr0b.js +0 -2
  387. package/dist/core/web/public/next/assets/OnboardingFlow-D3yfITK1.js +0 -2
  388. package/dist/core/web/public/next/assets/OnboardingFlow-D3yfITK1.js.map +0 -1
  389. package/dist/core/web/public/next/assets/OnboardingGate-DrDEVBqw.js +0 -3
  390. package/dist/core/web/public/next/assets/ResourcesChrome-C2ZrA7la.js +0 -3
  391. package/dist/core/web/public/next/assets/Sidebar-BuO3sViG.js +0 -3
  392. package/dist/core/web/public/next/assets/Sidebar-BuO3sViG.js.map +0 -1
  393. package/dist/core/web/public/next/assets/VerseConsoleApp-DeuBEvAO.js +0 -3
  394. package/dist/core/web/public/next/assets/VerseConsoleApp-DeuBEvAO.js.map +0 -1
  395. package/dist/core/web/public/next/assets/cloud-model-DoxBMDvx.js +0 -2
  396. package/dist/core/web/public/next/assets/copy-setup-CJQhFl-4.js +0 -2
  397. package/dist/core/web/public/next/assets/copy-setup-CJQhFl-4.js.map +0 -1
  398. package/dist/core/web/public/next/assets/format-DEAaVF6X.js +0 -2
  399. package/dist/core/web/public/next/assets/format-DEAaVF6X.js.map +0 -1
  400. package/dist/core/web/public/next/assets/global-CXHHMz9o.js +0 -2
  401. package/dist/core/web/public/next/assets/live-model-CEf01wrW.js.map +0 -1
  402. package/dist/core/web/public/next/assets/mutations-CbTSofVH.js +0 -2
  403. package/dist/core/web/public/next/assets/primitives-DNI-uJBd.js +0 -1
  404. package/dist/core/web/public/next/assets/surface-prefetch-DO8r4ttQ.js +0 -2
  405. package/dist/core/web/public/next/assets/types-D5XOdyw8.js +0 -2
  406. package/dist/core/web/public/next/assets/types-D5XOdyw8.js.map +0 -1
  407. package/dist/core/web/public/next/assets/why-seat-model-D68ZA7G8.js +0 -2
  408. package/dist/core/web/public/next/assets/why-seat-model-D68ZA7G8.js.map +0 -1
@@ -1,2 +1,2 @@
1
- import{_ as e,o as t}from"./colors-BZ3a9wFf.js";import{a as n,o as r}from"./why-seat-model-D68ZA7G8.js";var i={local:`local`,"grok-cli":`grok`,"claude-cli":`claude`,codex:`codex`},a={local:`Local`,"grok-cli":`Grok`,"claude-cli":`Claude`,codex:`Codex`};function o(e){return{name:a[e.lane],slots:e.slots===0?`off`:`${e.busy}/${e.slots}`}}function s(e){let t=e.capReason?.trim();return t?n(t):null}function c(e){let t=new Map;for(let n of e){let e=s(n);if(!e)continue;let r=t.get(e)??[];r.push(n.lane),t.set(e,r)}return[...t.entries()].map(([t,n])=>({lanes:n,all:n.length===e.length&&e.length>1,reason:t}))}function l(e){return e.phase===`queued`||e.phase===`parked`?e.phase:e.phase===`reverting`?`reverting`:e.outcome??e.phase}var u={producing:`running`,verifying:`running`,judging:`running`,landing:`running`,watching:`info`,reverting:`danger`,merged:`success`,proposed:`info`,"owner-lane":`warning`,refused:`warning`,failed:`danger`,reverted:`danger`,cancelled:`neutral`,queued:`neutral`,parked:`neutral`};function d(e){return u[e]??`unknown`}function f(e){let t=Date.parse(e.startedAt??e.phaseStartedAt??``);return Number.isFinite(t)?t:null}function p(e){if(!e.endedAt)return null;let t=Date.parse(e.endedAt);return Number.isFinite(t)?t:null}function m(e){return[e.repo.includes(`/`)?e.repo.split(`/`)[1]:e.repo,e.title,e.model,e.prNumber?`PR #${e.prNumber}`:null].filter(Boolean).join(` · `)}var h=[`local`,`grok-cli`,`claude-cli`,`codex`,`none`];function g(e,t,n,r={}){let o=r.includeParked??!0,s=new Map;for(let r of e){if(!o&&r.phase===`parked`)continue;let e=f(r);if(e===null||(p(r)??n)<t||e>n)continue;let i=r.lane??`none`;s.has(i)||s.set(i,[]),s.get(i).push(r)}let c=[];for(let e of h){let t=s.get(e);if(!t?.length)continue;t.sort((e,t)=>f(e)-f(t));let r=[],o=[];for(let e of t){let t=f(e),i=p(e)??n,a=r.findIndex(e=>e<=t);a===-1?(a=r.length,r.push(i),o.push([])):r[a]=i,o[a].push(e)}let u=e===`none`?`Unassigned`:a[e];o.forEach((t,n)=>{c.push({id:`${e}:${n}`,label:o.length>1?`${u} · ${n+1}`:u,...e===`none`?{}:{engine:i[e]},items:t.map(e=>({id:e.id,start:f(e),end:p(e),status:l(e),detail:m(e)}))})})}return c}function _(e,t){let n=e.filter(e=>e.phase===`parked`||e.hold!==null),a=n.map(e=>e.hold?.nextEligibleAt?Date.parse(e.hold.nextEligibleAt):NaN).filter(Number.isFinite),o=n.map(e=>f(e)??t),s=Math.min(t-36e5,...o),c=Math.min(t+1728e5,Math.max(t+72e5,...a)),l=0;return{lanes:n.map(e=>{let n=e.hold?.nextEligibleAt?Date.parse(e.hold.nextEligibleAt):NaN;Number.isFinite(n)||l++;let a=e.repo.includes(`/`)?e.repo.split(`/`)[1]:e.repo;return{id:e.id,label:`${a}: ${e.title}`,...e.lane?{engine:i[e.lane]}:{},items:[{id:e.id,start:f(e)??t,end:Number.isFinite(n)?n:null,status:e.hold?.kind===`split`?`split`:`parked`,outline:!0,detail:`${r(e.hold?.reason??`parked`,t)}${Number.isFinite(n)?``:` · release time unknown`}`}]}}),from:s,to:c,unknownRelease:l}}var v={G0:`Authority`,G1:`Protected paths`,G1b:`Tamper`,G2:`Scope`,G3:`Verify`,G4:`Claims`,G5:`Blast radius`,G6:`Judge`,G7:`GitHub checks`};function y(e){return!e||e.stages.length===0?[]:[{id:`entered`,label:`Proposals`,value:e.stages[0].entered},...e.stages.map(e=>({id:e.gate,label:`${e.gate} ${v[e.gate]??``}`.trim(),value:e.passed}))]}function b(n,r=5){if(!n)return{categories:[],segments:[],values:[],total:0};let i=new Map;for(let e of n.stages)for(let t of e.refusals){let e=i.get(t.code);i.set(t.code,{reason:e?.reason??t.reason,count:(e?.count??0)+t.count})}let a=[...i.entries()].sort((e,t)=>t[1].count-e[1].count||e[0].localeCompare(t[0])),o=a.slice(0,r).map(([e])=>e),s=a.length>r,c=[...o.map((t,n)=>({id:t,label:i.get(t).reason,color:e(n)})),...s?[{id:`__other`,label:`Other reasons`,color:t}]:[]],l=n.stages.filter(e=>e.refusals.length>0||e.entered!==e.passed);return{categories:l.map(e=>e.gate),segments:c,values:l.map(e=>{let t=o.map(t=>e.refusals.find(e=>e.code===t)?.count??0);return s&&t.push(e.refusals.filter(e=>!o.includes(e.code)).reduce((e,t)=>e+t.count,0)),t}),total:a.reduce((e,[,t])=>e+t.count,0)}}function x(e){return e.runs.length===0&&y(e.funnel).length===0&&b(e.funnel).total===0}function S(e){if(!e)return null;let t=e.runs.filter(e=>e.seatDecision!==null);if(!t.length)return null;t.sort((e,t)=>(f(t)??0)-(f(e)??0));let n=t[0];return{decision:n.seatDecision,run:n}}export{c as a,S as c,b as d,d as f,o as i,x as l,a as n,s as o,y as r,g as s,i as t,_ as u};
2
- //# sourceMappingURL=live-model-CEf01wrW.js.map
1
+ import{_ as e,o as t}from"./colors-BZ3a9wFf.js";import{a as n,o as r}from"./why-seat-model-Cau8qG6O.js";var i={local:`local`,"grok-cli":`grok`,"claude-cli":`claude`,codex:`codex`},a={local:`Local`,"grok-cli":`Grok`,"claude-cli":`Claude`,codex:`Codex`};function o(e){return{name:a[e.lane],slots:e.slots===0?`off`:`${e.busy}/${e.slots}`}}function s(e){let t=e.capReason?.trim();return t?n(t):null}function c(e){let t=new Map;for(let n of e){let e=s(n);if(!e)continue;let r=t.get(e)??[];r.push(n.lane),t.set(e,r)}return[...t.entries()].map(([t,n])=>({lanes:n,all:n.length===e.length&&e.length>1,reason:t}))}function l(e){return e.phase===`queued`||e.phase===`parked`?e.phase:e.phase===`reverting`?`reverting`:e.outcome??e.phase}var u={producing:`running`,verifying:`running`,judging:`running`,landing:`running`,watching:`info`,reverting:`danger`,merged:`success`,proposed:`info`,"owner-lane":`warning`,refused:`warning`,failed:`danger`,reverted:`danger`,cancelled:`neutral`,queued:`neutral`,parked:`neutral`};function d(e){return u[e]??`unknown`}function f(e){let t=Date.parse(e.startedAt??e.phaseStartedAt??``);return Number.isFinite(t)?t:null}function p(e){if(!e.endedAt)return null;let t=Date.parse(e.endedAt);return Number.isFinite(t)?t:null}function m(e){return[e.repo.includes(`/`)?e.repo.split(`/`)[1]:e.repo,e.title,e.model,e.prNumber?`PR #${e.prNumber}`:null].filter(Boolean).join(` · `)}var h=[`local`,`grok-cli`,`claude-cli`,`codex`,`none`];function g(e,t,n,r={}){let o=r.includeParked??!0,s=new Map;for(let r of e){if(!o&&r.phase===`parked`)continue;let e=f(r);if(e===null||(p(r)??n)<t||e>n)continue;let i=r.lane??`none`;s.has(i)||s.set(i,[]),s.get(i).push(r)}let c=[];for(let e of h){let t=s.get(e);if(!t?.length)continue;t.sort((e,t)=>f(e)-f(t));let r=[],o=[];for(let e of t){let t=f(e),i=p(e)??n,a=r.findIndex(e=>e<=t);a===-1?(a=r.length,r.push(i),o.push([])):r[a]=i,o[a].push(e)}let u=e===`none`?`Unassigned`:a[e];o.forEach((t,n)=>{c.push({id:`${e}:${n}`,label:o.length>1?`${u} · ${n+1}`:u,...e===`none`?{}:{engine:i[e]},items:t.map(e=>({id:e.id,start:f(e),end:p(e),status:l(e),detail:m(e)}))})})}return c}function _(e,t){let n=e.filter(e=>e.phase===`parked`||e.hold!==null),a=n.map(e=>e.hold?.nextEligibleAt?Date.parse(e.hold.nextEligibleAt):NaN).filter(Number.isFinite),o=n.map(e=>f(e)??t),s=Math.min(t-36e5,...o),c=Math.min(t+1728e5,Math.max(t+72e5,...a)),l=0;return{lanes:n.map(e=>{let n=e.hold?.nextEligibleAt?Date.parse(e.hold.nextEligibleAt):NaN;Number.isFinite(n)||l++;let a=e.repo.includes(`/`)?e.repo.split(`/`)[1]:e.repo;return{id:e.id,label:`${a}: ${e.title}`,...e.lane?{engine:i[e.lane]}:{},items:[{id:e.id,start:f(e)??t,end:Number.isFinite(n)?n:null,status:e.hold?.kind===`split`?`split`:`parked`,outline:!0,detail:`${r(e.hold?.reason??`parked`,t)}${Number.isFinite(n)?``:` · release time unknown`}`}]}}),from:s,to:c,unknownRelease:l}}var v={G0:`Authority`,G1:`Protected paths`,G1b:`Tamper`,G2:`Scope`,G3:`Verify`,G4:`Claims`,G5:`Blast radius`,G6:`Judge`,G7:`GitHub checks`};function y(e){return!e||e.stages.length===0?[]:[{id:`entered`,label:`Proposals`,value:e.stages[0].entered},...e.stages.map(e=>({id:e.gate,label:`${e.gate} ${v[e.gate]??``}`.trim(),value:e.passed}))]}function b(n,r=5){if(!n)return{categories:[],segments:[],values:[],total:0};let i=new Map;for(let e of n.stages)for(let t of e.refusals){let e=i.get(t.code);i.set(t.code,{reason:e?.reason??t.reason,count:(e?.count??0)+t.count})}let a=[...i.entries()].sort((e,t)=>t[1].count-e[1].count||e[0].localeCompare(t[0])),o=a.slice(0,r).map(([e])=>e),s=a.length>r,c=[...o.map((t,n)=>({id:t,label:i.get(t).reason,color:e(n)})),...s?[{id:`__other`,label:`Other reasons`,color:t}]:[]],l=n.stages.filter(e=>e.refusals.length>0||e.entered!==e.passed);return{categories:l.map(e=>e.gate),segments:c,values:l.map(e=>{let t=o.map(t=>e.refusals.find(e=>e.code===t)?.count??0);return s&&t.push(e.refusals.filter(e=>!o.includes(e.code)).reduce((e,t)=>e+t.count,0)),t}),total:a.reduce((e,[,t])=>e+t.count,0)}}function x(e){return e.runs.length===0&&y(e.funnel).length===0&&b(e.funnel).total===0}function S(e){if(!e)return null;let t=e.runs.filter(e=>e.seatDecision!==null);if(!t.length)return null;t.sort((e,t)=>(f(t)??0)-(f(e)??0));let n=t[0];return{decision:n.seatDecision,run:n}}export{c as a,S as c,b as d,d as f,o as i,x as l,a as n,s as o,y as r,g as s,i as t,_ as u};
2
+ //# sourceMappingURL=live-model-D7hilYFk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-model-D7hilYFk.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/fleet/live-model.ts"],"sourcesContent":["/**\n * routes/verse/fleet/live-model.ts — FleetLiveSnapshotV1 → chart props\n * (unit C7; SPEC-310B §6 Fleet, SPEC-310C §5). Shared by Command's 12 h\n * swimlane and every Fleet card, so both make the same decisions:\n *\n * - rows are LANES × SLOTS: runs overlapping in one lane stack into\n * numbered slot rows (\"Grok · 2\"), so a bar never hides behind another;\n * - bar colour is STATUS (running amber, merged green, reverted red …);\n * the lane's ENGINE is the tick + monogram beside its label;\n * - queued and parked work draws as an outline (it holds a place; nothing\n * runs) — the Parked Gantt runs from \"parked since\" to `nextEligibleAt`,\n * and an unknown `nextEligibleAt` stays open-ended with \"unknown\" in words.\n *\n * Framework-free; tested directly.\n */\nimport type { FleetEngine, FleetGateFunnel, FleetLaneState, FleetLiveRun, FleetLiveSnapshotV1 } from '../../../../core/fleet/fleet-types.js';\nimport type { SeatDecision } from '../../../../core/routing/types.js';\nimport type { ChartEngine, ChartTone } from '../../../components/charts/colors.js';\nimport { CHART_NEUTRAL, seriesColor } from '../../../components/charts/colors.js';\nimport type { SwimlaneLane } from '../../../components/charts/Swimlane.js';\nimport type { FunnelStage } from '../../../components/charts/Funnel.js';\nimport type { BarStackSegment } from '../../../components/charts/BarStack.js';\nimport { laneReasonText, localTimes } from './why-seat-model.js';\n\nexport const LANE_ENGINE: Readonly<Record<FleetEngine, ChartEngine>> = {\n local: 'local',\n 'grok-cli': 'grok',\n 'claude-cli': 'claude',\n codex: 'codex',\n};\n\nexport const LANE_LABEL: Readonly<Record<FleetEngine, string>> = {\n local: 'Local',\n 'grok-cli': 'Grok',\n 'claude-cli': 'Claude',\n codex: 'Codex',\n};\n\n/** A lane chip's words: \"Local · off\", \"Grok · 1/2\". The why is a separate line (`laneNotes`). */\nexport function laneChipText(lane: FleetLaneState): { name: string; slots: string } {\n return { name: LANE_LABEL[lane.lane], slots: lane.slots === 0 ? 'off' : `${lane.busy}/${lane.slots}` };\n}\n\nexport interface LaneNote {\n /** The lanes this reason applies to, in strip order. */\n lanes: FleetEngine[];\n /** True when every lane shares it — then it is said once, without names. */\n all: boolean;\n reason: string;\n}\n\n/** A lane's cap reason as the operator reads it (`laneReasonText`); null when it has none. */\nexport function laneReason(lane: FleetLaneState): string | null {\n const reason = lane.capReason?.trim();\n return reason ? laneReasonText(reason) : null;\n}\n\n/**\n * Each distinct lane cap reason ONCE, with the lanes it covers, in the plain\n * words the server already wrote. A dark fleet gives every lane the same sentence; 3.10.0\n * repeated it inside every chip and truncated it there.\n */\nexport function laneNotes(lanes: readonly FleetLaneState[]): LaneNote[] {\n const byReason = new Map<string, FleetEngine[]>();\n for (const lane of lanes) {\n const reason = laneReason(lane);\n if (!reason) continue;\n const list = byReason.get(reason) ?? [];\n list.push(lane.lane);\n byReason.set(reason, list);\n }\n return [...byReason.entries()].map(([reason, covered]) => ({\n lanes: covered,\n all: covered.length === lanes.length && lanes.length > 1,\n reason,\n }));\n}\n\n/** The word a bar is labelled with: the outcome once it ended, else the phase. */\nexport function runStatus(run: FleetLiveRun): string {\n if (run.phase === 'queued' || run.phase === 'parked') return run.phase;\n if (run.phase === 'reverting') return 'reverting';\n return run.outcome ?? run.phase;\n}\n\nconst TONES: Readonly<Record<string, ChartTone>> = {\n producing: 'running',\n verifying: 'running',\n judging: 'running',\n landing: 'running',\n watching: 'info',\n reverting: 'danger',\n merged: 'success',\n proposed: 'info',\n 'owner-lane': 'warning',\n refused: 'warning',\n failed: 'danger',\n reverted: 'danger',\n cancelled: 'neutral',\n queued: 'neutral',\n parked: 'neutral',\n};\n\nexport function runTone(status: string): ChartTone {\n return TONES[status] ?? 'unknown';\n}\n\nfunction startOf(run: FleetLiveRun): number | null {\n const t = Date.parse(run.startedAt ?? run.phaseStartedAt ?? '');\n return Number.isFinite(t) ? t : null;\n}\n\nfunction endOf(run: FleetLiveRun): number | null {\n if (!run.endedAt) return null;\n const t = Date.parse(run.endedAt);\n return Number.isFinite(t) ? t : null;\n}\n\nfunction runDetail(run: FleetLiveRun): string {\n const where = run.repo.includes('/') ? run.repo.split('/')[1] : run.repo;\n return [where, run.title, run.model, run.prNumber ? `PR #${run.prNumber}` : null].filter(Boolean).join(' · ');\n}\n\nconst LANE_ORDER: readonly (FleetEngine | 'none')[] = ['local', 'grok-cli', 'claude-cli', 'codex', 'none'];\n\n/**\n * Runs within [from, now] packed into lane × slot rows. `parkedAsGantt`\n * leaves parked runs out (the Fleet surface draws them in their own Gantt);\n * Command keeps them in, as outlines.\n */\nexport function laneRows(runs: readonly FleetLiveRun[], from: number, now: number, opts: { includeParked?: boolean } = {}): SwimlaneLane[] {\n const includeParked = opts.includeParked ?? true;\n const byLane = new Map<FleetEngine | 'none', FleetLiveRun[]>();\n for (const run of runs) {\n if (!includeParked && run.phase === 'parked') continue;\n const s = startOf(run);\n if (s === null) continue;\n const e = endOf(run) ?? now;\n if (e < from || s > now) continue;\n const key = run.lane ?? 'none';\n if (!byLane.has(key)) byLane.set(key, []);\n byLane.get(key)!.push(run);\n }\n const lanes: SwimlaneLane[] = [];\n for (const key of LANE_ORDER) {\n const list = byLane.get(key);\n if (!list?.length) continue;\n list.sort((a, b) => startOf(a)! - startOf(b)!);\n const slotEnds: number[] = [];\n const slotItems: FleetLiveRun[][] = [];\n for (const run of list) {\n const s = startOf(run)!;\n const e = endOf(run) ?? now;\n let slot = slotEnds.findIndex((end) => end <= s);\n if (slot === -1) {\n slot = slotEnds.length;\n slotEnds.push(e);\n slotItems.push([]);\n } else {\n slotEnds[slot] = e;\n }\n slotItems[slot]!.push(run);\n }\n const name = key === 'none' ? 'Unassigned' : LANE_LABEL[key];\n slotItems.forEach((items, i) => {\n lanes.push({\n id: `${key}:${i}`,\n label: slotItems.length > 1 ? `${name} · ${i + 1}` : name,\n ...(key === 'none' ? {} : { engine: LANE_ENGINE[key] }),\n items: items.map((run) => ({\n id: run.id,\n start: startOf(run)!,\n end: endOf(run),\n status: runStatus(run),\n detail: runDetail(run),\n })),\n });\n });\n }\n return lanes;\n}\n\nexport interface GanttRow {\n lanes: SwimlaneLane[];\n from: number;\n to: number;\n /** Rows whose release time is unknown (drawn open-ended). */\n unknownRelease: number;\n}\n\n/**\n * The Parked Gantt: one row per parked item, from when it parked to when its\n * seat should free up. The window always shows \"now\" plus the furthest known\n * release (capped at 48 h — a week-long wait still reads, it just runs off\n * the right edge and the table carries the exact time).\n */\nexport function parkedGantt(runs: readonly FleetLiveRun[], now: number): GanttRow {\n const parked = runs.filter((r) => r.phase === 'parked' || r.hold !== null);\n const releases = parked.map((r) => (r.hold?.nextEligibleAt ? Date.parse(r.hold.nextEligibleAt) : NaN)).filter(Number.isFinite);\n const starts = parked.map((r) => startOf(r) ?? now);\n const from = Math.min(now - 60 * 60_000, ...starts);\n const to = Math.min(now + 48 * 3_600_000, Math.max(now + 2 * 3_600_000, ...releases));\n let unknownRelease = 0;\n const lanes: SwimlaneLane[] = parked.map((r) => {\n const release = r.hold?.nextEligibleAt ? Date.parse(r.hold.nextEligibleAt) : NaN;\n if (!Number.isFinite(release)) unknownRelease++;\n const where = r.repo.includes('/') ? r.repo.split('/')[1] : r.repo;\n return {\n id: r.id,\n label: `${where}: ${r.title}`,\n ...(r.lane ? { engine: LANE_ENGINE[r.lane] } : {}),\n items: [{\n id: r.id,\n start: startOf(r) ?? now,\n end: Number.isFinite(release) ? release : null,\n status: r.hold?.kind === 'split' ? 'split' : 'parked',\n outline: true,\n detail: `${localTimes(r.hold?.reason ?? 'parked', now)}${Number.isFinite(release) ? '' : ' · release time unknown'}`,\n }],\n };\n });\n return { lanes, from, to, unknownRelease };\n}\n\n// ---------------------------------------------------------------------------\n// Gate funnel + refusal reasons\n// ---------------------------------------------------------------------------\n\n/** Gate names in operator words (the funnel's stage labels). */\nexport const GATE_LABEL: Readonly<Record<string, string>> = {\n G0: 'Authority',\n G1: 'Protected paths',\n G1b: 'Tamper',\n G2: 'Scope',\n G3: 'Verify',\n G4: 'Claims',\n G5: 'Blast radius',\n G6: 'Judge',\n G7: 'GitHub checks',\n};\n\n/** Entered G0, then how many passed each gate — a strictly narrowing pipeline. */\nexport function funnelStages(funnel: FleetGateFunnel | null): FunnelStage[] {\n if (!funnel || funnel.stages.length === 0) return [];\n return [\n { id: 'entered', label: 'Proposals', value: funnel.stages[0]!.entered },\n ...funnel.stages.map((s) => ({ id: s.gate, label: `${s.gate} ${GATE_LABEL[s.gate] ?? ''}`.trim(), value: s.passed })),\n ];\n}\n\nexport interface RefusalStack {\n categories: string[];\n segments: BarStackSegment[];\n values: (number | null)[][];\n total: number;\n}\n\n/**\n * Refusals per gate, stacked by reason. The top five reasons (by count over\n * the window) keep FIXED identity slots — a reason's colour never changes\n * when another is filtered out — and the rest fold into a neutral \"Other\".\n */\nexport function refusalStack(funnel: FleetGateFunnel | null, topN = 5): RefusalStack {\n if (!funnel) return { categories: [], segments: [], values: [], total: 0 };\n const totals = new Map<string, { reason: string; count: number }>();\n for (const s of funnel.stages) for (const r of s.refusals) {\n const prev = totals.get(r.code);\n totals.set(r.code, { reason: prev?.reason ?? r.reason, count: (prev?.count ?? 0) + r.count });\n }\n const ranked = [...totals.entries()].sort((a, b) => b[1].count - a[1].count || a[0].localeCompare(b[0]));\n const top = ranked.slice(0, topN).map(([code]) => code);\n const hasOther = ranked.length > topN;\n const segments: BarStackSegment[] = [\n ...top.map((code, i) => ({ id: code, label: totals.get(code)!.reason, color: seriesColor(i) })),\n ...(hasOther ? [{ id: '__other', label: 'Other reasons', color: CHART_NEUTRAL }] : []),\n ];\n const stages = funnel.stages.filter((s) => s.refusals.length > 0 || s.entered !== s.passed);\n return {\n categories: stages.map((s) => s.gate),\n segments,\n values: stages.map((s) => {\n const row = top.map((code) => s.refusals.find((r) => r.code === code)?.count ?? 0);\n if (hasOther) row.push(s.refusals.filter((r) => !top.includes(r.code)).reduce((n, r) => n + r.count, 0));\n return row;\n }),\n total: ranked.reduce((n, [, v]) => n + v.count, 0),\n };\n}\n\n/**\n * No run of any kind and no proposal at the gates: every chart card on Fleet\n * (live swimlane, gate funnel, refusals, parked) would be an empty state.\n */\nexport function nothingToDraw(fleet: FleetLiveSnapshotV1): boolean {\n return fleet.runs.length === 0 && funnelStages(fleet.funnel).length === 0 && refusalStack(fleet.funnel).total === 0;\n}\n\n/** The newest seat decision behind a live dispatch (\"why this seat\"). */\nexport function latestDecision(fleet: FleetLiveSnapshotV1 | null): { decision: SeatDecision; run: FleetLiveRun } | null {\n if (!fleet) return null;\n const withDecision = fleet.runs.filter((r) => r.seatDecision !== null);\n if (!withDecision.length) return null;\n withDecision.sort((a, b) => (startOf(b) ?? 0) - (startOf(a) ?? 0));\n const run = withDecision[0]!;\n return { decision: run.seatDecision!, run };\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{v as e}from"./colors-BZ3a9wFf.js";import{t}from"./calendar-day-BxBYHfX1.js";import{a as n}from"./workspace-model-BdIVybKr.js";function r(e){let t=e.trim().replace(/\\/g,`/`).replace(/\/+$/,``);return t=t.replace(/^\/private(?=\/(?:tmp|var)(?:\/|$))/,``),t=t.replace(/^(?:\/Users\/[^/]+|\/home\/[^/]+|[A-Za-z]:\/Users\/[^/]+)(?=\/|$)/,`~`),t||`/`}var i=[/^\/tmp(?:\/|$)/,/^\/var\/tmp(?:\/|$)/,/^\/var\/folders\/[^/]+\/[^/]+\/T(?:\/|$)/,/^[A-Za-z]:\/Windows\/Temp(?:\/|$)/i,/\/AppData\/Local\/Temp(?:\/|$)/i];function a(e){let t=r(e);return i.some(e=>e.test(t))}function o(e,t){let n=new Map,i=(e,t)=>{let i=r(e),a=t.trim();i!==`/`&&i!==`~`&&a&&!n.has(i)&&n.set(i,a)};for(let t of e??[])for(let e of t.roots)i(e.path,t.name);for(let e of t??[])i(e.path,e.name);return n}function s(e,t){let n=r(e),i=t.get(n);if(i!==void 0)return i;let a=null;for(let[e,r]of t)n.startsWith(`${e}/`)&&(!a||e.length>a.root.length)&&(a={root:e,name:r});return a?.name??null}function c(e,t=new Map){return{label:s(e,t)??n(e),full:e,scratch:a(e)}}var l=e=>e.length>14?`${e.slice(0,13)}…`:e;function u(e,t){let n=new Map(e.map(e=>[e,e.split(`/`).filter(Boolean).reverse()])),r=new Map;for(let i of e){let a=n.get(i),o=null,s=null;for(let r=0;r<a.length&&s===null;r++){let c=a[r];c!==t&&c!==`~`&&(o??=c,e.every(e=>e===i||n.get(e)[r]!==c)&&(s=c))}r.set(i,s??o)}return r}function d(e,t=new Map){let n=new Map;for(let t of[...new Set(e)].sort()){let e=r(t);n.set(e,[...n.get(e)??[],t])}let i=new Map;for(let[e,r]of n){let n=c(r[0],t).label;i.set(n,[...i.get(n)??[],e])}let o=new Map,s=new Map;for(let[e,t]of i){let n=t.length>1?u(t,e):null;for(let r of t){let t=n?.get(r)??null;o.set(r,t?`${e} (${l(t)})`:e),t&&l(t)!==t&&s.set(r,`${e} (${t})`)}}let d=new Map;for(let e of o.values())d.set(e,(d.get(e)??0)+1);let f=new Set,p=new Map;for(let e of[...o.keys()].sort()){let t=o.get(e),n=d.get(t)>1?s.get(e)??t:t,r=n;for(let e=2;f.has(r);e++)r=`${n} #${e}`;f.add(r),p.set(e,r)}let m=new Map;for(let[e,t]of n)for(let n of t)m.set(n,{label:p.get(e),full:n,scratch:a(n)});return m}var f=[`loop`,`struggle`,`verification-gap`,`uncertainty`,`backtrack`,`win`],p={loop:`Loops`,struggle:`Repeated failures`,"verification-gap":`Edits without tests`,uncertainty:`Uncertainty`,backtrack:`Backtracking`,win:`Wins`},m={claude:`Claude`,codex:`Codex`,grok:`Grok`,local:`Local`},h=[`claude`,`codex`,`grok`,`local`];function g(e){return h.includes(e)?e:null}function _(e){if(!e)return[];let t=new Map;for(let n of e.insights){if(!n.repo)continue;let e=r(n.repo),i=t.get(e)??{total:0,spellings:new Map};i.total+=n.count,i.spellings.set(n.repo,(i.spellings.get(n.repo)??0)+n.count),t.set(e,i)}let n=(e,t)=>t[1]-e[1]||e[0].localeCompare(t[0]);return[...t.values()].map(e=>[[...e.spellings.entries()].sort(n)[0][0],e.total]).sort(n).map(([e])=>e)}function v(e,t){return!!e&&(e===t||r(e)===r(t))}function y(e,t){let n=f.map(e=>({id:e,label:p[e]}));if(!e)return{rows:n,columns:[],values:[]};let r=[...new Set([...Object.keys(e.totals.byEngine),...e.insights.map(e=>e.engine).filter(e=>!!e)])].sort((e,t)=>{let n=h.indexOf(e),r=h.indexOf(t);return(n===-1?99:n)-(r===-1?99:r)||e.localeCompare(t)}),i=r.map(e=>{let t=g(e);return{id:e,label:m[e]??e,...t?{engine:t}:{}}}),a=e.insights.filter(e=>t===null||v(e.repo,t));return{rows:n,columns:i,values:f.map(t=>r.map(n=>{let r=(e.totals.byEngine[n]??0)>0,i=a.filter(e=>e.kind===t&&e.engine===n).reduce((e,t)=>e+t.count,0);return r||i>0?i:null}))}}function b(e,t=3){if(!e)return[];let n={high:0,warn:1,info:2};return e.insights.filter(e=>e.kind!==`win`).sort((e,t)=>n[e.severity]-n[t.severity]||Date.parse(t.lastAt)-Date.parse(e.lastAt)).slice(0,t)}function x(n){if(!n)return[];let r=e=>n.trends.map(n=>({x:t(n.day),y:n.steps===0?null:e(n)}));return[{id:`struggles`,label:`Struggles`,color:e(`warning`),points:r(e=>e.struggles)},{id:`wins`,label:`Wins`,color:e(`success`),points:r(e=>e.wins)}]}var S=new Set([`loop`,`struggle`]);function C(e,t){return e.evidence.some(e=>e.ref.startsWith(`session:${t}#`)||e.ref.startsWith(`verse:${t}:`))}function w(e,t){return!e||!t?[]:e.insights.filter(e=>S.has(e.kind)&&C(e,t)).sort((e,t)=>Date.parse(t.lastAt)-Date.parse(e.lastAt))}var T={stack:`_stack_1bdwr_5`,muted:`_muted_1bdwr_11`,link:`_link_1bdwr_17`,veto:`_veto_1bdwr_33`,chip:`_chip_1bdwr_34`,timeline:`_timeline_1bdwr_40`,memo:`_memo_1bdwr_48`,memoDay:`_memoDay_1bdwr_62`,mark:`_mark_1bdwr_69`,memoBody:`_memoBody_1bdwr_92`,memoMove:`_memoMove_1bdwr_99`,memoWhy:`_memoWhy_1bdwr_106`,memoMeta:`_memoMeta_1bdwr_113`,standards:`_standards_1bdwr_157`,standardRule:`_standardRule_1bdwr_172`,standardMeta:`_standardMeta_1bdwr_178`,insights:`_insights_1bdwr_184`,insight:`_insight_1bdwr_184`,insightKind:`_insightKind_1bdwr_213`,insightSeverity:`_insightSeverity_1bdwr_220`,insightTitle:`_insightTitle_1bdwr_233`,insightMeta:`_insightMeta_1bdwr_240`,insightPlace:`_insightPlace_1bdwr_248`,scratchTag:`_scratchTag_1bdwr_254`,log:`_log_1bdwr_266`,facet:`_facet_1bdwr_274`,chipWrap:`_chipWrap_1bdwr_294`,chipDot:`_chipDot_1bdwr_321`,chipMore:`_chipMore_1bdwr_332`,chipPanel:`_chipPanel_1bdwr_336`,chipList:`_chipList_1bdwr_352`};export{x as a,c,_ as i,d as l,p as n,w as o,y as r,b as s,T as t,o as u};
2
- //# sourceMappingURL=mind.module-D_xk6HIQ.js.map
1
+ import{v as e}from"./colors-BZ3a9wFf.js";import{t}from"./calendar-day-BxBYHfX1.js";import{a as n}from"./workspace-model-D-SLfads.js";function r(e){let t=e.trim().replace(/\\/g,`/`).replace(/\/+$/,``);return t=t.replace(/^\/private(?=\/(?:tmp|var)(?:\/|$))/,``),t=t.replace(/^(?:\/Users\/[^/]+|\/home\/[^/]+|[A-Za-z]:\/Users\/[^/]+)(?=\/|$)/,`~`),t||`/`}var i=[/^\/tmp(?:\/|$)/,/^\/var\/tmp(?:\/|$)/,/^\/var\/folders\/[^/]+\/[^/]+\/T(?:\/|$)/,/^[A-Za-z]:\/Windows\/Temp(?:\/|$)/i,/\/AppData\/Local\/Temp(?:\/|$)/i];function a(e){let t=r(e);return i.some(e=>e.test(t))}function o(e,t){let n=new Map,i=(e,t)=>{let i=r(e),a=t.trim();i!==`/`&&i!==`~`&&a&&!n.has(i)&&n.set(i,a)};for(let t of e??[])for(let e of t.roots)i(e.path,t.name);for(let e of t??[])i(e.path,e.name);return n}function s(e,t){let n=r(e),i=t.get(n);if(i!==void 0)return i;let a=null;for(let[e,r]of t)n.startsWith(`${e}/`)&&(!a||e.length>a.root.length)&&(a={root:e,name:r});return a?.name??null}function c(e,t=new Map){return{label:s(e,t)??n(e),full:e,scratch:a(e)}}var l=e=>e.length>14?`${e.slice(0,13)}…`:e;function u(e,t){let n=new Map(e.map(e=>[e,e.split(`/`).filter(Boolean).reverse()])),r=new Map;for(let i of e){let a=n.get(i),o=null,s=null;for(let r=0;r<a.length&&s===null;r++){let c=a[r];c!==t&&c!==`~`&&(o??=c,e.every(e=>e===i||n.get(e)[r]!==c)&&(s=c))}r.set(i,s??o)}return r}function d(e,t=new Map){let n=new Map;for(let t of[...new Set(e)].sort()){let e=r(t);n.set(e,[...n.get(e)??[],t])}let i=new Map;for(let[e,r]of n){let n=c(r[0],t).label;i.set(n,[...i.get(n)??[],e])}let o=new Map,s=new Map;for(let[e,t]of i){let n=t.length>1?u(t,e):null;for(let r of t){let t=n?.get(r)??null;o.set(r,t?`${e} (${l(t)})`:e),t&&l(t)!==t&&s.set(r,`${e} (${t})`)}}let d=new Map;for(let e of o.values())d.set(e,(d.get(e)??0)+1);let f=new Set,p=new Map;for(let e of[...o.keys()].sort()){let t=o.get(e),n=d.get(t)>1?s.get(e)??t:t,r=n;for(let e=2;f.has(r);e++)r=`${n} #${e}`;f.add(r),p.set(e,r)}let m=new Map;for(let[e,t]of n)for(let n of t)m.set(n,{label:p.get(e),full:n,scratch:a(n)});return m}var f=[`loop`,`struggle`,`verification-gap`,`uncertainty`,`backtrack`,`win`],p={loop:`Loops`,struggle:`Repeated failures`,"verification-gap":`Edits without tests`,uncertainty:`Uncertainty`,backtrack:`Backtracking`,win:`Wins`},m={claude:`Claude`,codex:`Codex`,grok:`Grok`,local:`Local`},h=[`claude`,`codex`,`grok`,`local`];function g(e){return h.includes(e)?e:null}function _(e){if(!e)return[];let t=new Map;for(let n of e.insights){if(!n.repo)continue;let e=r(n.repo),i=t.get(e)??{total:0,spellings:new Map};i.total+=n.count,i.spellings.set(n.repo,(i.spellings.get(n.repo)??0)+n.count),t.set(e,i)}let n=(e,t)=>t[1]-e[1]||e[0].localeCompare(t[0]);return[...t.values()].map(e=>[[...e.spellings.entries()].sort(n)[0][0],e.total]).sort(n).map(([e])=>e)}function v(e,t){return!!e&&(e===t||r(e)===r(t))}function y(e,t){let n=f.map(e=>({id:e,label:p[e]}));if(!e)return{rows:n,columns:[],values:[]};let r=[...new Set([...Object.keys(e.totals.byEngine),...e.insights.map(e=>e.engine).filter(e=>!!e)])].sort((e,t)=>{let n=h.indexOf(e),r=h.indexOf(t);return(n===-1?99:n)-(r===-1?99:r)||e.localeCompare(t)}),i=r.map(e=>{let t=g(e);return{id:e,label:m[e]??e,...t?{engine:t}:{}}}),a=e.insights.filter(e=>t===null||v(e.repo,t));return{rows:n,columns:i,values:f.map(t=>r.map(n=>{let r=(e.totals.byEngine[n]??0)>0,i=a.filter(e=>e.kind===t&&e.engine===n).reduce((e,t)=>e+t.count,0);return r||i>0?i:null}))}}function b(e,t=3){if(!e)return[];let n={high:0,warn:1,info:2};return e.insights.filter(e=>e.kind!==`win`).sort((e,t)=>n[e.severity]-n[t.severity]||Date.parse(t.lastAt)-Date.parse(e.lastAt)).slice(0,t)}function x(n){if(!n)return[];let r=e=>n.trends.map(n=>({x:t(n.day),y:n.steps===0?null:e(n)}));return[{id:`struggles`,label:`Struggles`,color:e(`warning`),points:r(e=>e.struggles)},{id:`wins`,label:`Wins`,color:e(`success`),points:r(e=>e.wins)}]}var S=new Set([`loop`,`struggle`]);function C(e,t){return e.evidence.some(e=>e.ref.startsWith(`session:${t}#`)||e.ref.startsWith(`verse:${t}:`))}function w(e,t){return!e||!t?[]:e.insights.filter(e=>S.has(e.kind)&&C(e,t)).sort((e,t)=>Date.parse(t.lastAt)-Date.parse(e.lastAt))}var T={stack:`_stack_1bdwr_5`,muted:`_muted_1bdwr_11`,link:`_link_1bdwr_17`,veto:`_veto_1bdwr_33`,chip:`_chip_1bdwr_34`,timeline:`_timeline_1bdwr_40`,memo:`_memo_1bdwr_48`,memoDay:`_memoDay_1bdwr_62`,mark:`_mark_1bdwr_69`,memoBody:`_memoBody_1bdwr_92`,memoMove:`_memoMove_1bdwr_99`,memoWhy:`_memoWhy_1bdwr_106`,memoMeta:`_memoMeta_1bdwr_113`,standards:`_standards_1bdwr_157`,standardRule:`_standardRule_1bdwr_172`,standardMeta:`_standardMeta_1bdwr_178`,insights:`_insights_1bdwr_184`,insight:`_insight_1bdwr_184`,insightKind:`_insightKind_1bdwr_213`,insightSeverity:`_insightSeverity_1bdwr_220`,insightTitle:`_insightTitle_1bdwr_233`,insightMeta:`_insightMeta_1bdwr_240`,insightPlace:`_insightPlace_1bdwr_248`,scratchTag:`_scratchTag_1bdwr_254`,log:`_log_1bdwr_266`,facet:`_facet_1bdwr_274`,chipWrap:`_chipWrap_1bdwr_294`,chipDot:`_chipDot_1bdwr_321`,chipMore:`_chipMore_1bdwr_332`,chipPanel:`_chipPanel_1bdwr_336`,chipList:`_chipList_1bdwr_352`};export{x as a,c,_ as i,d as l,p as n,w as o,y as r,b as s,T as t,o as u};
2
+ //# sourceMappingURL=mind.module-B15k0Y9q.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mind.module-D_xk6HIQ.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/mind/project-label.ts","../../../../../../src/web-ui/routes/verse/mind/mind-model.ts","../../../../../../src/web-ui/routes/verse/mind/mind.module.css"],"sourcesContent":["/**\n * routes/verse/mind/project-label.ts — how Mind names the place a reasoning\n * insight happened.\n *\n * A7 keys insights by the workspace path the engine ran in, verbatim, so the\n * cards used to read \"/private/tmp/claude-501/-Users-…/9d28bdb1-…/scratchpad/\n * grokpad · grok · 1×\". The card now shows a human label:\n *\n * 1. the REGISTERED name — a saved project (Chat → Projects) whose root is\n * that folder or contains it, else a project Verse knows from bootstrap;\n * 2. otherwise the folder's own name (`grokpad`), the same rule a saved\n * project uses when the operator names nothing (defaultWorkspaceName).\n *\n * The full path is never dropped: it rides in the tooltip. A folder under the\n * OS temp directory (an agent's scratchpad, a test fixture) is tagged\n * `scratch` rather than hidden — the insight is real, the place is throwaway.\n * The browser cannot ask the OS for its temp dir, so the well-known locations\n * are matched instead (macOS /tmp, /private/tmp and the per-user\n * /var/folders/…/T; Linux /tmp and /var/tmp; Windows …\\AppData\\Local\\Temp).\n *\n * Two different folders that would read the same (two agents' `scratchpad`s)\n * get a short distinguisher appended, so the Repo facet never offers two\n * identical choices; two spellings of ONE folder share one label.\n *\n * Framework-free; tested directly.\n */\nimport type { VerseProject, VerseWorkspace } from '../../../data/api-types.js';\nimport { defaultWorkspaceName } from '../workspace-model.js';\n\nexport interface ProjectLabel {\n /** What the card draws: the registered name, else the folder's own name. */\n label: string;\n /** The path (or slug) exactly as recorded — the tooltip. */\n full: string;\n /** Lives under the OS temp directory: a scratch folder, not a project. */\n scratch: boolean;\n}\n\n/** Registered names keyed by `pathKey(root)`. */\nexport type ProjectNames = ReadonlyMap<string, string>;\n\n/**\n * A comparable form of a path: `/` separators, no trailing separator, the\n * macOS `/private` alias folded (`/tmp` and `/var` are symlinks into it, and\n * the same folder is recorded either way), a home directory as `~` (a project\n * saved as `~/dev/hub` still runs in `/Users/me/dev/hub`).\n */\nexport function pathKey(path: string): string {\n let p = path.trim().replace(/\\\\/g, '/').replace(/\\/+$/, '');\n p = p.replace(/^\\/private(?=\\/(?:tmp|var)(?:\\/|$))/, '');\n p = p.replace(/^(?:\\/Users\\/[^/]+|\\/home\\/[^/]+|[A-Za-z]:\\/Users\\/[^/]+)(?=\\/|$)/, '~');\n return p || '/';\n}\n\nconst SCRATCH_ROOTS: readonly RegExp[] = [\n /^\\/tmp(?:\\/|$)/, // also /private/tmp, folded by pathKey\n /^\\/var\\/tmp(?:\\/|$)/,\n /^\\/var\\/folders\\/[^/]+\\/[^/]+\\/T(?:\\/|$)/, // macOS per-user $TMPDIR\n /^[A-Za-z]:\\/Windows\\/Temp(?:\\/|$)/i,\n /\\/AppData\\/Local\\/Temp(?:\\/|$)/i,\n];\n\n/** Is this folder under the OS temp directory? */\nexport function isScratchPath(path: string): boolean {\n const key = pathKey(path);\n return SCRATCH_ROOTS.some((re) => re.test(key));\n}\n\n/**\n * Registered names by root. Saved projects win (the operator named them),\n * then Verse's known projects; every root of a multi-folder project maps to\n * that project's name.\n */\nexport function projectNames(\n workspaces: readonly { name: VerseWorkspace['name']; roots: readonly { path: string }[] }[] | null | undefined,\n projects: readonly Pick<VerseProject, 'name' | 'path'>[] | null | undefined,\n): Map<string, string> {\n const names = new Map<string, string>();\n const add = (path: string, name: string) => {\n const key = pathKey(path);\n const label = name.trim();\n if (key !== '/' && key !== '~' && label && !names.has(key)) names.set(key, label);\n };\n for (const w of workspaces ?? []) for (const r of w.roots) add(r.path, w.name);\n for (const p of projects ?? []) add(p.path, p.name);\n return names;\n}\n\n/** The registered name for `path`: its own root, else the longest registered root containing it. */\nfunction registeredName(path: string, names: ProjectNames): string | null {\n const key = pathKey(path);\n const exact = names.get(key);\n if (exact !== undefined) return exact;\n let best: { root: string; name: string } | null = null;\n for (const [root, name] of names) {\n if (key.startsWith(`${root}/`) && (!best || root.length > best.root.length)) best = { root, name };\n }\n return best?.name ?? null;\n}\n\n/** One insight's place, as the card draws it. */\nexport function projectLabel(repo: string, names: ProjectNames = new Map()): ProjectLabel {\n return { label: registeredName(repo, names) ?? defaultWorkspaceName(repo), full: repo, scratch: isScratchPath(repo) };\n}\n\nconst short = (name: string) => (name.length > 14 ? `${name.slice(0, 13)}…` : name);\n\n/**\n * What tells same-label folders apart, per folder (keyed by `pathKey`):\n * walking up from the folder itself, the NEAREST path segment that no other\n * folder in the group has at that same depth — `grokpad (9d28bdb1-4c1e…)` for\n * two agents' `…/<uuid>/scratchpad/grokpad` (their parents are both\n * `scratchpad`), `Hub (a)` for two folders under one registered project. A\n * segment that only repeats the label (or is the home `~`) says nothing and\n * is skipped. When no single segment is unique, the nearest informative one\n * is returned and `projectLabels` settles whatever still collides.\n */\nfunction distinguishers(keys: readonly string[], label: string): Map<string, string | null> {\n const parts = new Map(keys.map((k) => [k, k.split('/').filter(Boolean).reverse()]));\n const out = new Map<string, string | null>();\n for (const key of keys) {\n const mine = parts.get(key)!;\n let nearest: string | null = null;\n let unique: string | null = null;\n for (let depth = 0; depth < mine.length && unique === null; depth++) {\n const seg = mine[depth]!;\n if (seg === label || seg === '~') continue;\n nearest ??= seg;\n if (keys.every((other) => other === key || parts.get(other)![depth] !== seg)) unique = seg;\n }\n out.set(key, unique ?? nearest);\n }\n return out;\n}\n\n/**\n * Labels for every repo on a surface at once, so the cards and the Repo facet\n * agree — and two different folders NEVER read the same:\n *\n * 1. spellings of one folder (`/tmp/x` and `/private/tmp/x`: one `pathKey`)\n * share one label; each keeps its own `full` path for the tooltip;\n * 2. different folders that would read the same get their nearest\n * distinguishing ancestor appended, shortened (`distinguishers`);\n * 3. whatever still collides — two ancestors that shorten alike, a folder\n * with nothing left to tell it apart — is settled by construction: the\n * whole segment instead of the shortened one, then an ordinal (\"#2\").\n */\nexport function projectLabels(repos: readonly string[], names: ProjectNames = new Map()): Map<string, ProjectLabel> {\n // One entry per folder, in a stable order: the labels never depend on the\n // order the insights arrived in.\n const spellings = new Map<string, string[]>();\n for (const repo of [...new Set(repos)].sort()) {\n const key = pathKey(repo);\n spellings.set(key, [...(spellings.get(key) ?? []), repo]);\n }\n const byLabel = new Map<string, string[]>();\n for (const [key, list] of spellings) {\n const label = projectLabel(list[0]!, names).label;\n byLabel.set(label, [...(byLabel.get(label) ?? []), key]);\n }\n\n const wanted = new Map<string, string>();\n const whole = new Map<string, string>();\n for (const [label, keys] of byLabel) {\n const extra = keys.length > 1 ? distinguishers(keys, label) : null;\n for (const key of keys) {\n const seg = extra?.get(key) ?? null;\n wanted.set(key, seg ? `${label} (${short(seg)})` : label);\n if (seg && short(seg) !== seg) whole.set(key, `${label} (${seg})`);\n }\n }\n\n const shared = new Map<string, number>();\n for (const l of wanted.values()) shared.set(l, (shared.get(l) ?? 0) + 1);\n const taken = new Set<string>();\n const labelOf = new Map<string, string>();\n for (const key of [...wanted.keys()].sort()) {\n const first = wanted.get(key)!;\n const pick = shared.get(first)! > 1 ? (whole.get(key) ?? first) : first;\n let label = pick;\n for (let n = 2; taken.has(label); n++) label = `${pick} #${n}`;\n taken.add(label);\n labelOf.set(key, label);\n }\n\n const out = new Map<string, ProjectLabel>();\n for (const [key, list] of spellings) {\n for (const repo of list) out.set(repo, { label: labelOf.get(key)!, full: repo, scratch: isScratchPath(repo) });\n }\n return out;\n}\n","/**\n * routes/verse/mind/mind-model.ts — the reasoning digest (A7) as Mind's\n * charts and cards, plus the chat-header chip's matching rule (unit C7;\n * SPEC-310B §6 Mind, SPEC-310C §5).\n *\n * The matrix is insight KIND × ENGINE, faceted by repo. A cell is:\n * - a count of insight occurrences when that engine produced reasoning in\n * the window (0 is a real zero: it reasoned and nothing was flagged);\n * - UNKNOWN (null) when that engine recorded no reasoning at all — nothing\n * was measured, so nothing can be said (hatched, never a pale zero).\n *\n * Framework-free; tested directly.\n */\nimport type { ReasoningDigest, ReasoningInsight, ReasoningInsightKind } from '../../../../core/reasoning/types.js';\nimport type { ChartEngine } from '../../../components/charts/colors.js';\nimport type { MatrixAxisItem } from '../../../components/charts/MatrixHeatmap.js';\nimport type { AreaTrendSeries } from '../../../components/charts/AreaTrend.js';\nimport { toneColor } from '../../../components/charts/colors.js';\nimport { calendarDayStart } from '../growth/calendar-day.js';\nimport { pathKey } from './project-label.js';\n\nexport const INSIGHT_KINDS: readonly ReasoningInsightKind[] = ['loop', 'struggle', 'verification-gap', 'uncertainty', 'backtrack', 'win'];\n\nexport const KIND_LABEL: Readonly<Record<ReasoningInsightKind, string>> = {\n loop: 'Loops',\n struggle: 'Repeated failures',\n 'verification-gap': 'Edits without tests',\n uncertainty: 'Uncertainty',\n backtrack: 'Backtracking',\n win: 'Wins',\n};\n\nconst ENGINE_LABEL: Readonly<Record<string, string>> = { claude: 'Claude', codex: 'Codex', grok: 'Grok', local: 'Local' };\nconst KNOWN_ENGINES: readonly ChartEngine[] = ['claude', 'codex', 'grok', 'local'];\n\nfunction asEngine(name: string): ChartEngine | null {\n return (KNOWN_ENGINES as readonly string[]).includes(name) ? (name as ChartEngine) : null;\n}\n\n/**\n * Repos that appear in the digest's insights, most insight occurrences first\n * — ONE per folder: two spellings of the same folder (`/tmp/x` and\n * `/private/tmp/x`, which `pathKey` treats as one) are one Repo facet entry,\n * named by the spelling recorded most often.\n */\nexport function insightRepos(digest: ReasoningDigest | null): string[] {\n if (!digest) return [];\n const folders = new Map<string, { total: number; spellings: Map<string, number> }>();\n for (const i of digest.insights) {\n if (!i.repo) continue;\n const key = pathKey(i.repo);\n const f = folders.get(key) ?? { total: 0, spellings: new Map<string, number>() };\n f.total += i.count;\n f.spellings.set(i.repo, (f.spellings.get(i.repo) ?? 0) + i.count);\n folders.set(key, f);\n }\n const byCount = (a: [string, number], b: [string, number]) => b[1] - a[1] || a[0].localeCompare(b[0]);\n return [...folders.values()]\n .map((f) => [[...f.spellings.entries()].sort(byCount)[0]![0], f.total] as [string, number])\n .sort(byCount)\n .map(([r]) => r);\n}\n\n/** Does insight `repo` name the same folder as facet `facet` (any spelling)? */\nfunction sameFolder(repo: string | null | undefined, facet: string): boolean {\n return !!repo && (repo === facet || pathKey(repo) === pathKey(facet));\n}\n\nexport interface InsightMatrix {\n rows: MatrixAxisItem[];\n columns: MatrixAxisItem[];\n values: (number | null)[][];\n}\n\n/** `repo` null = every repo. */\nexport function insightMatrix(digest: ReasoningDigest | null, repo: string | null): InsightMatrix {\n const rows = INSIGHT_KINDS.map((k) => ({ id: k, label: KIND_LABEL[k] }));\n if (!digest) return { rows, columns: [], values: [] };\n // Columns: every engine that reasoned in the window, plus any engine an\n // insight names (so a count is never dropped), known engines first.\n const names = new Set<string>([...Object.keys(digest.totals.byEngine), ...digest.insights.map((i) => i.engine).filter((e): e is string => !!e)]);\n const ordered = [...names].sort((a, b) => {\n const ia = KNOWN_ENGINES.indexOf(a as ChartEngine);\n const ib = KNOWN_ENGINES.indexOf(b as ChartEngine);\n return (ia === -1 ? 99 : ia) - (ib === -1 ? 99 : ib) || a.localeCompare(b);\n });\n const columns: MatrixAxisItem[] = ordered.map((name) => {\n const engine = asEngine(name);\n return { id: name, label: ENGINE_LABEL[name] ?? name, ...(engine ? { engine } : {}) };\n });\n const insights = digest.insights.filter((i) => repo === null || sameFolder(i.repo, repo));\n const values = INSIGHT_KINDS.map((kind) =>\n ordered.map((engine) => {\n const measured = (digest.totals.byEngine[engine] ?? 0) > 0;\n const count = insights.filter((i) => i.kind === kind && i.engine === engine).reduce((n, i) => n + i.count, 0);\n return measured || count > 0 ? count : null;\n }),\n );\n return { rows, columns, values };\n}\n\n/** The three cards: most severe first, then most recent — wins are not problems. */\nexport function topInsights(digest: ReasoningDigest | null, n = 3): ReasoningInsight[] {\n if (!digest) return [];\n const rank = { high: 0, warn: 1, info: 2 } as const;\n return digest.insights\n .filter((i) => i.kind !== 'win')\n .sort((a, b) => rank[a.severity] - rank[b.severity] || Date.parse(b.lastAt) - Date.parse(a.lastAt))\n .slice(0, n);\n}\n\n/**\n * Struggles vs wins per day, for the trends card. Each day is stamped at the\n * viewer's LOCAL midnight (`calendarDayStart`), because the chart labels its\n * x values in the local zone: a UTC-midnight stamp read one day early west of\n * UTC (\"2026-09-24\" as \"Sep 23\").\n */\nexport function reasoningTrendSeries(digest: ReasoningDigest | null): AreaTrendSeries[] {\n if (!digest) return [];\n const pts = (pick: (d: ReasoningDigest['trends'][number]) => number) =>\n digest.trends.map((d) => ({ x: calendarDayStart(d.day), y: d.steps === 0 ? null : pick(d) }));\n return [\n { id: 'struggles', label: 'Struggles', color: toneColor('warning'), points: pts((d) => d.struggles) },\n { id: 'wins', label: 'Wins', color: toneColor('success'), points: pts((d) => d.wins) },\n ];\n}\n\n// ---------------------------------------------------------------------------\n// SessionInsightChip\n// ---------------------------------------------------------------------------\n\n/** The chip shows only the insight kinds that mean \"this chat is stuck\". */\nexport const CHIP_KINDS: ReadonlySet<ReasoningInsightKind> = new Set(['loop', 'struggle']);\n\n/**\n * Does `insight` cite chat `sessionId`? Verse evidence refs are\n * `session:<id>#<seq>` (tool / message events) or `verse:<id>:<turn|seq>`\n * (thinking steps) — A7's ingest-verse.ts. The id is matched exactly up to\n * its delimiter, so chat `s1` never matches `s12`.\n */\nexport function citesSession(insight: Pick<ReasoningInsight, 'evidence'>, sessionId: string): boolean {\n return insight.evidence.some((e) => e.ref.startsWith(`session:${sessionId}#`) || e.ref.startsWith(`verse:${sessionId}:`));\n}\n\nexport function sessionInsights(digest: ReasoningDigest | null, sessionId: string): ReasoningInsight[] {\n if (!digest || !sessionId) return [];\n return digest.insights\n .filter((i) => CHIP_KINDS.has(i.kind) && citesSession(i, sessionId))\n .sort((a, b) => Date.parse(b.lastAt) - Date.parse(a.lastAt));\n}\n","/*\n * routes/verse/mind/mind.module.css — Mind cards and the chat-header chip\n * (unit C7). Tokens only (style-scan-310).\n */\n.stack {\n display: flex;\n flex-direction: column;\n gap: var(--surface-gap);\n}\n\n.muted {\n margin: 0;\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n}\n\n.link {\n align-self: flex-start;\n padding: 0;\n border: 0;\n background: none;\n color: var(--text-link);\n font: inherit;\n font-size: var(--text-xs-size);\n cursor: pointer;\n}\n\n.link:hover {\n text-decoration: underline;\n}\n\n.link:focus-visible,\n.veto:focus-visible,\n.chip:focus-visible {\n outline: 2px solid var(--border-focus);\n outline-offset: 2px;\n}\n\n/* ---- memo timeline ---------------------------------------------------- */\n.timeline {\n display: flex;\n flex-direction: column;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.memo {\n display: grid;\n grid-template-columns: 88px 20px minmax(0, 1fr) auto;\n gap: var(--space-3);\n align-items: start;\n padding: var(--space-3) 0;\n border-top: 1px solid var(--border-subtle);\n}\n\n.memo:first-child {\n border-top: 0;\n padding-top: 0;\n}\n\n.memoDay {\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n line-height: var(--text-sm-line);\n font-variant-numeric: tabular-nums;\n}\n\n.mark {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: var(--radius-full);\n background: var(--status-neutral-bg);\n color: var(--status-neutral-fg);\n font-size: var(--text-xs-size);\n font-weight: var(--font-weight-semibold);\n}\n\n.mark[data-outcome='hit'] {\n background: var(--status-success-bg);\n color: var(--status-success-fg);\n}\n\n.mark[data-outcome='miss'] {\n background: var(--status-danger-bg);\n color: var(--status-danger-fg);\n}\n\n.memoBody {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.memoMove {\n color: var(--text-primary);\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n overflow-wrap: anywhere;\n}\n\n.memoWhy {\n color: var(--text-secondary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n overflow-wrap: anywhere;\n}\n\n.memoMeta {\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n}\n\n.memoMeta [data-outcome='hit'] {\n color: var(--status-success-fg);\n}\n\n.memoMeta [data-outcome='miss'] {\n color: var(--status-danger-fg);\n}\n\n.veto {\n min-height: var(--control-h-sm);\n padding: 0 var(--space-3);\n border: 1px solid var(--border-default);\n border-radius: var(--radius-sm);\n background: transparent;\n color: var(--text-primary);\n font: inherit;\n font-size: var(--text-xs-size);\n cursor: pointer;\n}\n\n.veto:hover {\n background: var(--bg-hover);\n}\n\n.veto:disabled {\n color: var(--text-disabled);\n cursor: default;\n}\n\n[data-viewport='compact'] .memo {\n grid-template-columns: 20px minmax(0, 1fr) auto;\n}\n\n[data-viewport='compact'] .memoDay {\n grid-column: 1 / -1;\n}\n\n/* ---- standards -------------------------------------------------------- */\n.standards {\n display: flex;\n flex-direction: column;\n gap: var(--space-3);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.standards li {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.standardRule {\n color: var(--text-primary);\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line-relaxed);\n}\n\n.standardMeta {\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n}\n\n/* ---- insight cards ---------------------------------------------------- */\n.insights {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: var(--surface-gap);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n[data-viewport='compact'] .insights,\n[data-viewport='medium'] .insights {\n grid-template-columns: minmax(0, 1fr);\n}\n\n.insight {\n display: flex;\n flex-direction: column;\n gap: var(--space-2);\n padding: var(--card-pad);\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-lg);\n background: var(--bg-surface);\n box-shadow: inset 0 1px 0 var(--hairline-lift, transparent);\n}\n\n.insight[data-severity='high'] {\n border-color: var(--status-danger-solid);\n}\n\n.insightKind {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-2);\n}\n\n.insightSeverity {\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n}\n\n.insightSeverity[data-severity='high'] {\n color: var(--status-danger-fg);\n}\n\n.insightSeverity[data-severity='warn'] {\n color: var(--status-warning-fg);\n}\n\n.insightTitle {\n color: var(--text-primary);\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line-relaxed);\n overflow-wrap: anywhere;\n}\n\n.insightMeta {\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n}\n\n/* The project's name reads a step stronger than the rest of the meta line;\n the full path is its tooltip. */\n.insightPlace {\n color: var(--text-secondary);\n overflow-wrap: anywhere;\n}\n\n/* A folder under the OS temp dir: tagged, quietly — never hidden. */\n.scratchTag {\n display: inline-block;\n margin-left: var(--space-1);\n padding: 0 var(--space-1);\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-sm);\n color: var(--text-tertiary);\n font-size: var(--text-2xs-size);\n line-height: var(--text-2xs-line);\n vertical-align: 1px;\n}\n\n.log {\n display: flex;\n flex-direction: column;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.facet {\n display: inline-flex;\n align-items: center;\n gap: var(--space-2);\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n}\n\n.facet select {\n min-height: var(--control-h-xs);\n padding: 0 var(--space-2);\n border: 1px solid var(--border-default);\n border-radius: var(--radius-sm);\n background: var(--bg-input);\n color: var(--text-primary);\n font: inherit;\n font-size: var(--text-xs-size);\n}\n\n/* ---- chat-header chip ------------------------------------------------- */\n.chipWrap {\n position: relative;\n display: inline-flex;\n}\n\n.chip {\n display: inline-flex;\n align-items: center;\n gap: var(--space-1);\n min-height: var(--control-h-xs);\n padding: 0 var(--space-2);\n border: 1px solid var(--border-default);\n border-radius: var(--radius-full);\n background: var(--bg-surface);\n color: var(--text-secondary);\n font: inherit;\n font-size: var(--text-xs-size);\n white-space: nowrap;\n cursor: pointer;\n}\n\n.chip:hover,\n.chip[aria-expanded='true'] {\n background: var(--bg-hover);\n color: var(--text-primary);\n}\n\n.chipDot {\n width: 6px;\n height: 6px;\n border-radius: var(--radius-full);\n background: var(--status-warning-solid);\n}\n\n.chipDot[data-severity='high'] {\n background: var(--status-danger-solid);\n}\n\n.chipMore {\n color: var(--text-tertiary);\n}\n\n.chipPanel {\n position: absolute;\n top: calc(100% + var(--space-1));\n right: 0;\n z-index: var(--z-dropdown);\n display: flex;\n flex-direction: column;\n gap: var(--space-3);\n width: min(320px, calc(100vw - var(--space-8)));\n padding: var(--space-3);\n border: 1px solid var(--border-default);\n border-radius: var(--radius-md);\n background: var(--bg-surface-raised);\n box-shadow: var(--shadow-menu);\n}\n\n.chipList {\n display: flex;\n flex-direction: column;\n gap: var(--space-2);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.chipList li {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"mind.module-B15k0Y9q.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/mind/project-label.ts","../../../../../../src/web-ui/routes/verse/mind/mind-model.ts","../../../../../../src/web-ui/routes/verse/mind/mind.module.css"],"sourcesContent":["/**\n * routes/verse/mind/project-label.ts — how Mind names the place a reasoning\n * insight happened.\n *\n * A7 keys insights by the workspace path the engine ran in, verbatim, so the\n * cards used to read \"/private/tmp/claude-501/-Users-…/9d28bdb1-…/scratchpad/\n * grokpad · grok · 1×\". The card now shows a human label:\n *\n * 1. the REGISTERED name — a saved project (Chat → Projects) whose root is\n * that folder or contains it, else a project Verse knows from bootstrap;\n * 2. otherwise the folder's own name (`grokpad`), the same rule a saved\n * project uses when the operator names nothing (defaultWorkspaceName).\n *\n * The full path is never dropped: it rides in the tooltip. A folder under the\n * OS temp directory (an agent's scratchpad, a test fixture) is tagged\n * `scratch` rather than hidden — the insight is real, the place is throwaway.\n * The browser cannot ask the OS for its temp dir, so the well-known locations\n * are matched instead (macOS /tmp, /private/tmp and the per-user\n * /var/folders/…/T; Linux /tmp and /var/tmp; Windows …\\AppData\\Local\\Temp).\n *\n * Two different folders that would read the same (two agents' `scratchpad`s)\n * get a short distinguisher appended, so the Repo facet never offers two\n * identical choices; two spellings of ONE folder share one label.\n *\n * Framework-free; tested directly.\n */\nimport type { VerseProject, VerseWorkspace } from '../../../data/api-types.js';\nimport { defaultWorkspaceName } from '../workspace-model.js';\n\nexport interface ProjectLabel {\n /** What the card draws: the registered name, else the folder's own name. */\n label: string;\n /** The path (or slug) exactly as recorded — the tooltip. */\n full: string;\n /** Lives under the OS temp directory: a scratch folder, not a project. */\n scratch: boolean;\n}\n\n/** Registered names keyed by `pathKey(root)`. */\nexport type ProjectNames = ReadonlyMap<string, string>;\n\n/**\n * A comparable form of a path: `/` separators, no trailing separator, the\n * macOS `/private` alias folded (`/tmp` and `/var` are symlinks into it, and\n * the same folder is recorded either way), a home directory as `~` (a project\n * saved as `~/dev/hub` still runs in `/Users/me/dev/hub`).\n */\nexport function pathKey(path: string): string {\n let p = path.trim().replace(/\\\\/g, '/').replace(/\\/+$/, '');\n p = p.replace(/^\\/private(?=\\/(?:tmp|var)(?:\\/|$))/, '');\n p = p.replace(/^(?:\\/Users\\/[^/]+|\\/home\\/[^/]+|[A-Za-z]:\\/Users\\/[^/]+)(?=\\/|$)/, '~');\n return p || '/';\n}\n\nconst SCRATCH_ROOTS: readonly RegExp[] = [\n /^\\/tmp(?:\\/|$)/, // also /private/tmp, folded by pathKey\n /^\\/var\\/tmp(?:\\/|$)/,\n /^\\/var\\/folders\\/[^/]+\\/[^/]+\\/T(?:\\/|$)/, // macOS per-user $TMPDIR\n /^[A-Za-z]:\\/Windows\\/Temp(?:\\/|$)/i,\n /\\/AppData\\/Local\\/Temp(?:\\/|$)/i,\n];\n\n/** Is this folder under the OS temp directory? */\nexport function isScratchPath(path: string): boolean {\n const key = pathKey(path);\n return SCRATCH_ROOTS.some((re) => re.test(key));\n}\n\n/**\n * Registered names by root. Saved projects win (the operator named them),\n * then Verse's known projects; every root of a multi-folder project maps to\n * that project's name.\n */\nexport function projectNames(\n workspaces: readonly { name: VerseWorkspace['name']; roots: readonly { path: string }[] }[] | null | undefined,\n projects: readonly Pick<VerseProject, 'name' | 'path'>[] | null | undefined,\n): Map<string, string> {\n const names = new Map<string, string>();\n const add = (path: string, name: string) => {\n const key = pathKey(path);\n const label = name.trim();\n if (key !== '/' && key !== '~' && label && !names.has(key)) names.set(key, label);\n };\n for (const w of workspaces ?? []) for (const r of w.roots) add(r.path, w.name);\n for (const p of projects ?? []) add(p.path, p.name);\n return names;\n}\n\n/** The registered name for `path`: its own root, else the longest registered root containing it. */\nfunction registeredName(path: string, names: ProjectNames): string | null {\n const key = pathKey(path);\n const exact = names.get(key);\n if (exact !== undefined) return exact;\n let best: { root: string; name: string } | null = null;\n for (const [root, name] of names) {\n if (key.startsWith(`${root}/`) && (!best || root.length > best.root.length)) best = { root, name };\n }\n return best?.name ?? null;\n}\n\n/** One insight's place, as the card draws it. */\nexport function projectLabel(repo: string, names: ProjectNames = new Map()): ProjectLabel {\n return { label: registeredName(repo, names) ?? defaultWorkspaceName(repo), full: repo, scratch: isScratchPath(repo) };\n}\n\nconst short = (name: string) => (name.length > 14 ? `${name.slice(0, 13)}…` : name);\n\n/**\n * What tells same-label folders apart, per folder (keyed by `pathKey`):\n * walking up from the folder itself, the NEAREST path segment that no other\n * folder in the group has at that same depth — `grokpad (9d28bdb1-4c1e…)` for\n * two agents' `…/<uuid>/scratchpad/grokpad` (their parents are both\n * `scratchpad`), `Hub (a)` for two folders under one registered project. A\n * segment that only repeats the label (or is the home `~`) says nothing and\n * is skipped. When no single segment is unique, the nearest informative one\n * is returned and `projectLabels` settles whatever still collides.\n */\nfunction distinguishers(keys: readonly string[], label: string): Map<string, string | null> {\n const parts = new Map(keys.map((k) => [k, k.split('/').filter(Boolean).reverse()]));\n const out = new Map<string, string | null>();\n for (const key of keys) {\n const mine = parts.get(key)!;\n let nearest: string | null = null;\n let unique: string | null = null;\n for (let depth = 0; depth < mine.length && unique === null; depth++) {\n const seg = mine[depth]!;\n if (seg === label || seg === '~') continue;\n nearest ??= seg;\n if (keys.every((other) => other === key || parts.get(other)![depth] !== seg)) unique = seg;\n }\n out.set(key, unique ?? nearest);\n }\n return out;\n}\n\n/**\n * Labels for every repo on a surface at once, so the cards and the Repo facet\n * agree — and two different folders NEVER read the same:\n *\n * 1. spellings of one folder (`/tmp/x` and `/private/tmp/x`: one `pathKey`)\n * share one label; each keeps its own `full` path for the tooltip;\n * 2. different folders that would read the same get their nearest\n * distinguishing ancestor appended, shortened (`distinguishers`);\n * 3. whatever still collides — two ancestors that shorten alike, a folder\n * with nothing left to tell it apart — is settled by construction: the\n * whole segment instead of the shortened one, then an ordinal (\"#2\").\n */\nexport function projectLabels(repos: readonly string[], names: ProjectNames = new Map()): Map<string, ProjectLabel> {\n // One entry per folder, in a stable order: the labels never depend on the\n // order the insights arrived in.\n const spellings = new Map<string, string[]>();\n for (const repo of [...new Set(repos)].sort()) {\n const key = pathKey(repo);\n spellings.set(key, [...(spellings.get(key) ?? []), repo]);\n }\n const byLabel = new Map<string, string[]>();\n for (const [key, list] of spellings) {\n const label = projectLabel(list[0]!, names).label;\n byLabel.set(label, [...(byLabel.get(label) ?? []), key]);\n }\n\n const wanted = new Map<string, string>();\n const whole = new Map<string, string>();\n for (const [label, keys] of byLabel) {\n const extra = keys.length > 1 ? distinguishers(keys, label) : null;\n for (const key of keys) {\n const seg = extra?.get(key) ?? null;\n wanted.set(key, seg ? `${label} (${short(seg)})` : label);\n if (seg && short(seg) !== seg) whole.set(key, `${label} (${seg})`);\n }\n }\n\n const shared = new Map<string, number>();\n for (const l of wanted.values()) shared.set(l, (shared.get(l) ?? 0) + 1);\n const taken = new Set<string>();\n const labelOf = new Map<string, string>();\n for (const key of [...wanted.keys()].sort()) {\n const first = wanted.get(key)!;\n const pick = shared.get(first)! > 1 ? (whole.get(key) ?? first) : first;\n let label = pick;\n for (let n = 2; taken.has(label); n++) label = `${pick} #${n}`;\n taken.add(label);\n labelOf.set(key, label);\n }\n\n const out = new Map<string, ProjectLabel>();\n for (const [key, list] of spellings) {\n for (const repo of list) out.set(repo, { label: labelOf.get(key)!, full: repo, scratch: isScratchPath(repo) });\n }\n return out;\n}\n","/**\n * routes/verse/mind/mind-model.ts — the reasoning digest (A7) as Mind's\n * charts and cards, plus the chat-header chip's matching rule (unit C7;\n * SPEC-310B §6 Mind, SPEC-310C §5).\n *\n * The matrix is insight KIND × ENGINE, faceted by repo. A cell is:\n * - a count of insight occurrences when that engine produced reasoning in\n * the window (0 is a real zero: it reasoned and nothing was flagged);\n * - UNKNOWN (null) when that engine recorded no reasoning at all — nothing\n * was measured, so nothing can be said (hatched, never a pale zero).\n *\n * Framework-free; tested directly.\n */\nimport type { ReasoningDigest, ReasoningInsight, ReasoningInsightKind } from '../../../../core/reasoning/types.js';\nimport type { ChartEngine } from '../../../components/charts/colors.js';\nimport type { MatrixAxisItem } from '../../../components/charts/MatrixHeatmap.js';\nimport type { AreaTrendSeries } from '../../../components/charts/AreaTrend.js';\nimport { toneColor } from '../../../components/charts/colors.js';\nimport { calendarDayStart } from '../growth/calendar-day.js';\nimport { pathKey } from './project-label.js';\n\nexport const INSIGHT_KINDS: readonly ReasoningInsightKind[] = ['loop', 'struggle', 'verification-gap', 'uncertainty', 'backtrack', 'win'];\n\nexport const KIND_LABEL: Readonly<Record<ReasoningInsightKind, string>> = {\n loop: 'Loops',\n struggle: 'Repeated failures',\n 'verification-gap': 'Edits without tests',\n uncertainty: 'Uncertainty',\n backtrack: 'Backtracking',\n win: 'Wins',\n};\n\nconst ENGINE_LABEL: Readonly<Record<string, string>> = { claude: 'Claude', codex: 'Codex', grok: 'Grok', local: 'Local' };\nconst KNOWN_ENGINES: readonly ChartEngine[] = ['claude', 'codex', 'grok', 'local'];\n\nfunction asEngine(name: string): ChartEngine | null {\n return (KNOWN_ENGINES as readonly string[]).includes(name) ? (name as ChartEngine) : null;\n}\n\n/**\n * Repos that appear in the digest's insights, most insight occurrences first\n * — ONE per folder: two spellings of the same folder (`/tmp/x` and\n * `/private/tmp/x`, which `pathKey` treats as one) are one Repo facet entry,\n * named by the spelling recorded most often.\n */\nexport function insightRepos(digest: ReasoningDigest | null): string[] {\n if (!digest) return [];\n const folders = new Map<string, { total: number; spellings: Map<string, number> }>();\n for (const i of digest.insights) {\n if (!i.repo) continue;\n const key = pathKey(i.repo);\n const f = folders.get(key) ?? { total: 0, spellings: new Map<string, number>() };\n f.total += i.count;\n f.spellings.set(i.repo, (f.spellings.get(i.repo) ?? 0) + i.count);\n folders.set(key, f);\n }\n const byCount = (a: [string, number], b: [string, number]) => b[1] - a[1] || a[0].localeCompare(b[0]);\n return [...folders.values()]\n .map((f) => [[...f.spellings.entries()].sort(byCount)[0]![0], f.total] as [string, number])\n .sort(byCount)\n .map(([r]) => r);\n}\n\n/** Does insight `repo` name the same folder as facet `facet` (any spelling)? */\nfunction sameFolder(repo: string | null | undefined, facet: string): boolean {\n return !!repo && (repo === facet || pathKey(repo) === pathKey(facet));\n}\n\nexport interface InsightMatrix {\n rows: MatrixAxisItem[];\n columns: MatrixAxisItem[];\n values: (number | null)[][];\n}\n\n/** `repo` null = every repo. */\nexport function insightMatrix(digest: ReasoningDigest | null, repo: string | null): InsightMatrix {\n const rows = INSIGHT_KINDS.map((k) => ({ id: k, label: KIND_LABEL[k] }));\n if (!digest) return { rows, columns: [], values: [] };\n // Columns: every engine that reasoned in the window, plus any engine an\n // insight names (so a count is never dropped), known engines first.\n const names = new Set<string>([...Object.keys(digest.totals.byEngine), ...digest.insights.map((i) => i.engine).filter((e): e is string => !!e)]);\n const ordered = [...names].sort((a, b) => {\n const ia = KNOWN_ENGINES.indexOf(a as ChartEngine);\n const ib = KNOWN_ENGINES.indexOf(b as ChartEngine);\n return (ia === -1 ? 99 : ia) - (ib === -1 ? 99 : ib) || a.localeCompare(b);\n });\n const columns: MatrixAxisItem[] = ordered.map((name) => {\n const engine = asEngine(name);\n return { id: name, label: ENGINE_LABEL[name] ?? name, ...(engine ? { engine } : {}) };\n });\n const insights = digest.insights.filter((i) => repo === null || sameFolder(i.repo, repo));\n const values = INSIGHT_KINDS.map((kind) =>\n ordered.map((engine) => {\n const measured = (digest.totals.byEngine[engine] ?? 0) > 0;\n const count = insights.filter((i) => i.kind === kind && i.engine === engine).reduce((n, i) => n + i.count, 0);\n return measured || count > 0 ? count : null;\n }),\n );\n return { rows, columns, values };\n}\n\n/** The three cards: most severe first, then most recent — wins are not problems. */\nexport function topInsights(digest: ReasoningDigest | null, n = 3): ReasoningInsight[] {\n if (!digest) return [];\n const rank = { high: 0, warn: 1, info: 2 } as const;\n return digest.insights\n .filter((i) => i.kind !== 'win')\n .sort((a, b) => rank[a.severity] - rank[b.severity] || Date.parse(b.lastAt) - Date.parse(a.lastAt))\n .slice(0, n);\n}\n\n/**\n * Struggles vs wins per day, for the trends card. Each day is stamped at the\n * viewer's LOCAL midnight (`calendarDayStart`), because the chart labels its\n * x values in the local zone: a UTC-midnight stamp read one day early west of\n * UTC (\"2026-09-24\" as \"Sep 23\").\n */\nexport function reasoningTrendSeries(digest: ReasoningDigest | null): AreaTrendSeries[] {\n if (!digest) return [];\n const pts = (pick: (d: ReasoningDigest['trends'][number]) => number) =>\n digest.trends.map((d) => ({ x: calendarDayStart(d.day), y: d.steps === 0 ? null : pick(d) }));\n return [\n { id: 'struggles', label: 'Struggles', color: toneColor('warning'), points: pts((d) => d.struggles) },\n { id: 'wins', label: 'Wins', color: toneColor('success'), points: pts((d) => d.wins) },\n ];\n}\n\n// ---------------------------------------------------------------------------\n// SessionInsightChip\n// ---------------------------------------------------------------------------\n\n/** The chip shows only the insight kinds that mean \"this chat is stuck\". */\nexport const CHIP_KINDS: ReadonlySet<ReasoningInsightKind> = new Set(['loop', 'struggle']);\n\n/**\n * Does `insight` cite chat `sessionId`? Verse evidence refs are\n * `session:<id>#<seq>` (tool / message events) or `verse:<id>:<turn|seq>`\n * (thinking steps) — A7's ingest-verse.ts. The id is matched exactly up to\n * its delimiter, so chat `s1` never matches `s12`.\n */\nexport function citesSession(insight: Pick<ReasoningInsight, 'evidence'>, sessionId: string): boolean {\n return insight.evidence.some((e) => e.ref.startsWith(`session:${sessionId}#`) || e.ref.startsWith(`verse:${sessionId}:`));\n}\n\nexport function sessionInsights(digest: ReasoningDigest | null, sessionId: string): ReasoningInsight[] {\n if (!digest || !sessionId) return [];\n return digest.insights\n .filter((i) => CHIP_KINDS.has(i.kind) && citesSession(i, sessionId))\n .sort((a, b) => Date.parse(b.lastAt) - Date.parse(a.lastAt));\n}\n","/*\n * routes/verse/mind/mind.module.css — Mind cards and the chat-header chip\n * (unit C7). Tokens only (style-scan-310).\n */\n.stack {\n display: flex;\n flex-direction: column;\n gap: var(--surface-gap);\n}\n\n.muted {\n margin: 0;\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n}\n\n.link {\n align-self: flex-start;\n padding: 0;\n border: 0;\n background: none;\n color: var(--text-link);\n font: inherit;\n font-size: var(--text-xs-size);\n cursor: pointer;\n}\n\n.link:hover {\n text-decoration: underline;\n}\n\n.link:focus-visible,\n.veto:focus-visible,\n.chip:focus-visible {\n outline: 2px solid var(--border-focus);\n outline-offset: 2px;\n}\n\n/* ---- memo timeline ---------------------------------------------------- */\n.timeline {\n display: flex;\n flex-direction: column;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.memo {\n display: grid;\n grid-template-columns: 88px 20px minmax(0, 1fr) auto;\n gap: var(--space-3);\n align-items: start;\n padding: var(--space-3) 0;\n border-top: 1px solid var(--border-subtle);\n}\n\n.memo:first-child {\n border-top: 0;\n padding-top: 0;\n}\n\n.memoDay {\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n line-height: var(--text-sm-line);\n font-variant-numeric: tabular-nums;\n}\n\n.mark {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: var(--radius-full);\n background: var(--status-neutral-bg);\n color: var(--status-neutral-fg);\n font-size: var(--text-xs-size);\n font-weight: var(--font-weight-semibold);\n}\n\n.mark[data-outcome='hit'] {\n background: var(--status-success-bg);\n color: var(--status-success-fg);\n}\n\n.mark[data-outcome='miss'] {\n background: var(--status-danger-bg);\n color: var(--status-danger-fg);\n}\n\n.memoBody {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.memoMove {\n color: var(--text-primary);\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n overflow-wrap: anywhere;\n}\n\n.memoWhy {\n color: var(--text-secondary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n overflow-wrap: anywhere;\n}\n\n.memoMeta {\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n}\n\n.memoMeta [data-outcome='hit'] {\n color: var(--status-success-fg);\n}\n\n.memoMeta [data-outcome='miss'] {\n color: var(--status-danger-fg);\n}\n\n.veto {\n min-height: var(--control-h-sm);\n padding: 0 var(--space-3);\n border: 1px solid var(--border-default);\n border-radius: var(--radius-sm);\n background: transparent;\n color: var(--text-primary);\n font: inherit;\n font-size: var(--text-xs-size);\n cursor: pointer;\n}\n\n.veto:hover {\n background: var(--bg-hover);\n}\n\n.veto:disabled {\n color: var(--text-disabled);\n cursor: default;\n}\n\n[data-viewport='compact'] .memo {\n grid-template-columns: 20px minmax(0, 1fr) auto;\n}\n\n[data-viewport='compact'] .memoDay {\n grid-column: 1 / -1;\n}\n\n/* ---- standards -------------------------------------------------------- */\n.standards {\n display: flex;\n flex-direction: column;\n gap: var(--space-3);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.standards li {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.standardRule {\n color: var(--text-primary);\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line-relaxed);\n}\n\n.standardMeta {\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n}\n\n/* ---- insight cards ---------------------------------------------------- */\n.insights {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: var(--surface-gap);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n[data-viewport='compact'] .insights,\n[data-viewport='medium'] .insights {\n grid-template-columns: minmax(0, 1fr);\n}\n\n.insight {\n display: flex;\n flex-direction: column;\n gap: var(--space-2);\n padding: var(--card-pad);\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-lg);\n background: var(--bg-surface);\n box-shadow: inset 0 1px 0 var(--hairline-lift, transparent);\n}\n\n.insight[data-severity='high'] {\n border-color: var(--status-danger-solid);\n}\n\n.insightKind {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-2);\n}\n\n.insightSeverity {\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n}\n\n.insightSeverity[data-severity='high'] {\n color: var(--status-danger-fg);\n}\n\n.insightSeverity[data-severity='warn'] {\n color: var(--status-warning-fg);\n}\n\n.insightTitle {\n color: var(--text-primary);\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line-relaxed);\n overflow-wrap: anywhere;\n}\n\n.insightMeta {\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n}\n\n/* The project's name reads a step stronger than the rest of the meta line;\n the full path is its tooltip. */\n.insightPlace {\n color: var(--text-secondary);\n overflow-wrap: anywhere;\n}\n\n/* A folder under the OS temp dir: tagged, quietly — never hidden. */\n.scratchTag {\n display: inline-block;\n margin-left: var(--space-1);\n padding: 0 var(--space-1);\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-sm);\n color: var(--text-tertiary);\n font-size: var(--text-2xs-size);\n line-height: var(--text-2xs-line);\n vertical-align: 1px;\n}\n\n.log {\n display: flex;\n flex-direction: column;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.facet {\n display: inline-flex;\n align-items: center;\n gap: var(--space-2);\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n}\n\n.facet select {\n min-height: var(--control-h-xs);\n padding: 0 var(--space-2);\n border: 1px solid var(--border-default);\n border-radius: var(--radius-sm);\n background: var(--bg-input);\n color: var(--text-primary);\n font: inherit;\n font-size: var(--text-xs-size);\n}\n\n/* ---- chat-header chip ------------------------------------------------- */\n.chipWrap {\n position: relative;\n display: inline-flex;\n}\n\n.chip {\n display: inline-flex;\n align-items: center;\n gap: var(--space-1);\n min-height: var(--control-h-xs);\n padding: 0 var(--space-2);\n border: 1px solid var(--border-default);\n border-radius: var(--radius-full);\n background: var(--bg-surface);\n color: var(--text-secondary);\n font: inherit;\n font-size: var(--text-xs-size);\n white-space: nowrap;\n cursor: pointer;\n}\n\n.chip:hover,\n.chip[aria-expanded='true'] {\n background: var(--bg-hover);\n color: var(--text-primary);\n}\n\n.chipDot {\n width: 6px;\n height: 6px;\n border-radius: var(--radius-full);\n background: var(--status-warning-solid);\n}\n\n.chipDot[data-severity='high'] {\n background: var(--status-danger-solid);\n}\n\n.chipMore {\n color: var(--text-tertiary);\n}\n\n.chipPanel {\n position: absolute;\n top: calc(100% + var(--space-1));\n right: 0;\n z-index: var(--z-dropdown);\n display: flex;\n flex-direction: column;\n gap: var(--space-3);\n width: min(320px, calc(100vw - var(--space-8)));\n padding: var(--space-3);\n border: 1px solid var(--border-default);\n border-radius: var(--radius-md);\n background: var(--bg-surface-raised);\n box-shadow: var(--shadow-menu);\n}\n\n.chipList {\n display: flex;\n flex-direction: column;\n gap: var(--space-2);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.chipList li {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{D as e,F as t,U as n,W as r,l as i}from"./global-y_exIyAP.js";var a=class extends Error{constructor(){super(`No mutation token held for this session yet.`),this.name=`MissingMutationTokenError`}};async function o(n,r){let o=e();if(!o)throw new a;let s=await i(n,r,o);return t(),s}async function s(){await o(`/api/fleet/pause`,{}),n(`dashboard-snapshot`),n(`control-snapshot`),n(`fleet`),n(`fleet-activity`)}async function c(){await o(`/api/fleet/resume`,{}),n(`dashboard-snapshot`),n(`control-snapshot`),n(`fleet`),n(`fleet-activity`)}async function l(e){await o(`/api/inbox/${encodeURIComponent(e)}/approve`,{}),n(`inbox`),n(`dashboard-snapshot`),n(`proposal-detail-${e}`),r(`inbox-list:`)}async function u(e){await o(`/api/inbox/${encodeURIComponent(e)}/reject`,{}),n(`inbox`),n(`dashboard-snapshot`),n(`proposal-detail-${e}`),r(`inbox-list:`)}export{c as i,s as n,u as r,l as t};
2
+ //# sourceMappingURL=mutations-CWlxEMEm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mutations-CbTSofVH.js","names":[],"sources":["../../../../../../src/web-ui/data/mutations.ts"],"sourcesContent":["/**\n * data/mutations.ts — every mutating call the foundation ships with, each\n * wrapped so it (a) pulls the held mutation token from auth-store instead\n * of asking every call site to thread it through, (b) touches the hold on\n * success so a burst of approvals doesn't idle-expire mid-session, and\n * (c) invalidates whatever cache keys the mutation obviously affects so\n * views update without waiting for the next SSE tick.\n *\n * Routes mirror the mutating surface documented at the top of\n * src/core/web/api.ts. Every one of these 404s (not 401/403) when the\n * server was started without --allow-dispatch — apiPost maps that code-less\n * 404 to DispatchDisabledError (a 404 carrying a `code` stays an ApiError).\n */\nimport { apiPost } from './client.js';\nimport { getMutationToken, touchMutationHold } from './auth-store.js';\nimport { invalidate, invalidatePrefix } from './cache.js';\n\nclass MissingMutationTokenError extends Error {\n constructor() {\n super('No mutation token held for this session yet.');\n this.name = 'MissingMutationTokenError';\n }\n}\n\nasync function post<T>(path: string, body: unknown): Promise<T> {\n const token = getMutationToken();\n if (!token) throw new MissingMutationTokenError();\n const result = await apiPost<T>(path, body, token);\n touchMutationHold();\n return result;\n}\n\nexport async function pauseFleet(): Promise<void> {\n await post('/api/fleet/pause', {});\n invalidate('dashboard-snapshot');\n invalidate('control-snapshot');\n invalidate('fleet');\n invalidate('fleet-activity');\n}\n\nexport async function resumeFleet(): Promise<void> {\n await post('/api/fleet/resume', {});\n invalidate('dashboard-snapshot');\n invalidate('control-snapshot');\n invalidate('fleet');\n invalidate('fleet-activity');\n}\n\nexport async function approveProposal(id: string): Promise<void> {\n await post(`/api/inbox/${encodeURIComponent(id)}/approve`, {});\n invalidate('inbox');\n invalidate('dashboard-snapshot');\n invalidate(`proposal-detail-${id}`);\n invalidatePrefix('inbox-list:');\n}\n\nexport async function rejectProposal(id: string): Promise<void> {\n await post(`/api/inbox/${encodeURIComponent(id)}/reject`, {});\n invalidate('inbox');\n invalidate('dashboard-snapshot');\n invalidate(`proposal-detail-${id}`);\n invalidatePrefix('inbox-list:');\n}\n\nexport interface OpenTargetRequest {\n path: string;\n target: 'editor' | 'finder';\n}\n\nexport async function openTarget(req: OpenTargetRequest): Promise<void> {\n await post('/api/open', req);\n}\n"],"mappings":"qEAiBA,IAAM,EAAN,cAAwC,KAAM,CAC5C,aAAc,CACZ,MAAM,8CAA8C,EACpD,KAAK,KAAO,2BACd,CACF,EAEA,eAAe,EAAQ,EAAc,EAA2B,CAC9D,IAAM,EAAQ,EAAiB,EAC/B,GAAI,CAAC,EAAO,MAAM,IAAI,EACtB,IAAM,EAAS,MAAM,EAAW,EAAM,EAAM,CAAK,EAEjD,OADA,EAAkB,EACX,CACT,CAEA,eAAsB,GAA4B,CAChD,MAAM,EAAK,mBAAoB,CAAC,CAAC,EACjC,EAAW,oBAAoB,EAC/B,EAAW,kBAAkB,EAC7B,EAAW,OAAO,EAClB,EAAW,gBAAgB,CAC7B,CAEA,eAAsB,GAA6B,CACjD,MAAM,EAAK,oBAAqB,CAAC,CAAC,EAClC,EAAW,oBAAoB,EAC/B,EAAW,kBAAkB,EAC7B,EAAW,OAAO,EAClB,EAAW,gBAAgB,CAC7B,CAEA,eAAsB,EAAgB,EAA2B,CAC/D,MAAM,EAAK,cAAc,mBAAmB,CAAE,EAAE,UAAW,CAAC,CAAC,EAC7D,EAAW,OAAO,EAClB,EAAW,oBAAoB,EAC/B,EAAW,mBAAmB,GAAI,EAClC,EAAiB,aAAa,CAChC,CAEA,eAAsB,EAAe,EAA2B,CAC9D,MAAM,EAAK,cAAc,mBAAmB,CAAE,EAAE,SAAU,CAAC,CAAC,EAC5D,EAAW,OAAO,EAClB,EAAW,oBAAoB,EAC/B,EAAW,mBAAmB,GAAI,EAClC,EAAiB,aAAa,CAChC"}
1
+ {"version":3,"file":"mutations-CWlxEMEm.js","names":[],"sources":["../../../../../../src/web-ui/data/mutations.ts"],"sourcesContent":["/**\n * data/mutations.ts — every mutating call the foundation ships with, each\n * wrapped so it (a) pulls the held mutation token from auth-store instead\n * of asking every call site to thread it through, (b) touches the hold on\n * success so a burst of approvals doesn't idle-expire mid-session, and\n * (c) invalidates whatever cache keys the mutation obviously affects so\n * views update without waiting for the next SSE tick.\n *\n * Routes mirror the mutating surface documented at the top of\n * src/core/web/api.ts. Every one of these 404s (not 401/403) when the\n * server was started without --allow-dispatch — apiPost maps that code-less\n * 404 to DispatchDisabledError (a 404 carrying a `code` stays an ApiError).\n */\nimport { apiPost } from './client.js';\nimport { getMutationToken, touchMutationHold } from './auth-store.js';\nimport { invalidate, invalidatePrefix } from './cache.js';\n\nclass MissingMutationTokenError extends Error {\n constructor() {\n super('No mutation token held for this session yet.');\n this.name = 'MissingMutationTokenError';\n }\n}\n\nasync function post<T>(path: string, body: unknown): Promise<T> {\n const token = getMutationToken();\n if (!token) throw new MissingMutationTokenError();\n const result = await apiPost<T>(path, body, token);\n touchMutationHold();\n return result;\n}\n\nexport async function pauseFleet(): Promise<void> {\n await post('/api/fleet/pause', {});\n invalidate('dashboard-snapshot');\n invalidate('control-snapshot');\n invalidate('fleet');\n invalidate('fleet-activity');\n}\n\nexport async function resumeFleet(): Promise<void> {\n await post('/api/fleet/resume', {});\n invalidate('dashboard-snapshot');\n invalidate('control-snapshot');\n invalidate('fleet');\n invalidate('fleet-activity');\n}\n\nexport async function approveProposal(id: string): Promise<void> {\n await post(`/api/inbox/${encodeURIComponent(id)}/approve`, {});\n invalidate('inbox');\n invalidate('dashboard-snapshot');\n invalidate(`proposal-detail-${id}`);\n invalidatePrefix('inbox-list:');\n}\n\nexport async function rejectProposal(id: string): Promise<void> {\n await post(`/api/inbox/${encodeURIComponent(id)}/reject`, {});\n invalidate('inbox');\n invalidate('dashboard-snapshot');\n invalidate(`proposal-detail-${id}`);\n invalidatePrefix('inbox-list:');\n}\n\nexport interface OpenTargetRequest {\n path: string;\n target: 'editor' | 'finder';\n}\n\nexport async function openTarget(req: OpenTargetRequest): Promise<void> {\n await post('/api/open', req);\n}\n"],"mappings":"qEAiBA,IAAM,EAAN,cAAwC,KAAM,CAC5C,aAAc,CACZ,MAAM,8CAA8C,EACpD,KAAK,KAAO,2BACd,CACF,EAEA,eAAe,EAAQ,EAAc,EAA2B,CAC9D,IAAM,EAAQ,EAAiB,EAC/B,GAAI,CAAC,EAAO,MAAM,IAAI,EACtB,IAAM,EAAS,MAAM,EAAW,EAAM,EAAM,CAAK,EAEjD,OADA,EAAkB,EACX,CACT,CAEA,eAAsB,GAA4B,CAChD,MAAM,EAAK,mBAAoB,CAAC,CAAC,EACjC,EAAW,oBAAoB,EAC/B,EAAW,kBAAkB,EAC7B,EAAW,OAAO,EAClB,EAAW,gBAAgB,CAC7B,CAEA,eAAsB,GAA6B,CACjD,MAAM,EAAK,oBAAqB,CAAC,CAAC,EAClC,EAAW,oBAAoB,EAC/B,EAAW,kBAAkB,EAC7B,EAAW,OAAO,EAClB,EAAW,gBAAgB,CAC7B,CAEA,eAAsB,EAAgB,EAA2B,CAC/D,MAAM,EAAK,cAAc,mBAAmB,CAAE,EAAE,UAAW,CAAC,CAAC,EAC7D,EAAW,OAAO,EAClB,EAAW,oBAAoB,EAC/B,EAAW,mBAAmB,GAAI,EAClC,EAAiB,aAAa,CAChC,CAEA,eAAsB,EAAe,EAA2B,CAC9D,MAAM,EAAK,cAAc,mBAAmB,CAAE,EAAE,SAAU,CAAC,CAAC,EAC5D,EAAW,OAAO,EAClB,EAAW,oBAAoB,EAC/B,EAAW,mBAAmB,GAAI,EAClC,EAAiB,aAAa,CAChC"}
@@ -1,2 +1,2 @@
1
- import{lt as e,rt as t,tt as n}from"./VerseConsoleApp-DeuBEvAO.js";function r(e=null){n(e?{focusId:e}:{})}function i(e){return`c7-anchor-${e.replace(/[^A-Za-z0-9_-]/g,`-`)}`}function a(e){let t=document.getElementById(i(e));t&&typeof t.scrollIntoView==`function`&&t.scrollIntoView({block:`center`,behavior:`smooth`})}function o(t,n=null){e(t),n&&requestAnimationFrame(()=>{document.getElementById(i(n))?a(n):requestAnimationFrame(()=>a(n))})}function s(e){t(e)}export{r as i,o as n,s as r,i as t};
2
- //# sourceMappingURL=nav-CmZcbPFJ.js.map
1
+ import{lt as e,rt as t,tt as n}from"./VerseConsoleApp-DXDv1aOi.js";function r(e=null){n(e?{focusId:e}:{})}function i(e){return`c7-anchor-${e.replace(/[^A-Za-z0-9_-]/g,`-`)}`}function a(e){let t=document.getElementById(i(e));t&&typeof t.scrollIntoView==`function`&&t.scrollIntoView({block:`center`,behavior:`smooth`})}function o(t,n=null){e(t),n&&requestAnimationFrame(()=>{document.getElementById(i(n))?a(n):requestAnimationFrame(()=>a(n))})}function s(e){t(e)}export{r as i,o as n,s as r,i as t};
2
+ //# sourceMappingURL=nav-mimleI0R.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"nav-CmZcbPFJ.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/command/nav.ts"],"sourcesContent":["/**\n * routes/verse/command/nav.ts — how a surface card asks the shell to go\n * somewhere (unit C7). The shell (C1) owns navigation state; these are thin\n * wrappers over its store so every card words navigation the same way:\n *\n * openNeedsYou() ⌘J's drawer, optionally focused on one item;\n * goToSection(s, a) switch surface (keep-alive: the target keeps its\n * state) and, when `anchor` names a card or row on\n * it, scroll that into view once it is on screen;\n * openChat(sessionId) the chat a Needs-you item or insight is about.\n */\nimport type { WorkbenchSectionId } from '../../../../core/verse/workbench-types.js';\nimport { openVerseNeedsYou, openVerseSession, setVerseSection } from '../verse-ui-store.js';\n\nexport function openNeedsYou(focusId: string | null = null): void {\n openVerseNeedsYou(focusId ? { focusId } : {});\n}\n\n/** DOM id for an anchor (\"repo-ashlrai/binshield\" → \"c7-anchor-repo-ashlrai-binshield\"). */\nexport function anchorId(anchor: string): string {\n return `c7-anchor-${anchor.replace(/[^A-Za-z0-9_-]/g, '-')}`;\n}\n\nexport function scrollToAnchor(anchor: string): void {\n const el = document.getElementById(anchorId(anchor));\n if (el && typeof el.scrollIntoView === 'function') el.scrollIntoView({ block: 'center', behavior: 'smooth' });\n}\n\nexport function goToSection(section: WorkbenchSectionId, anchor: string | null = null): void {\n setVerseSection(section);\n if (!anchor) return;\n // The target surface may be mounting (lazy chunk) or un-hiding (keep-alive):\n // try on the next two frames, then give up quietly — a missing anchor is\n // never an error, the operator is already on the right surface.\n requestAnimationFrame(() => {\n if (document.getElementById(anchorId(anchor))) scrollToAnchor(anchor);\n else requestAnimationFrame(() => scrollToAnchor(anchor));\n });\n}\n\nexport function openChat(sessionId: string): void {\n openVerseSession(sessionId);\n}\n"],"mappings":"mEAcA,SAAgB,EAAa,EAAyB,KAAY,CAChE,EAAkB,EAAU,CAAE,SAAQ,EAAI,CAAC,CAAC,CAC9C,CAGA,SAAgB,EAAS,EAAwB,CAC/C,MAAO,aAAa,EAAO,QAAQ,kBAAmB,GAAG,GAC3D,CAEA,SAAgB,EAAe,EAAsB,CACnD,IAAM,EAAK,SAAS,eAAe,EAAS,CAAM,CAAC,EAC/C,GAAM,OAAO,EAAG,gBAAmB,YAAY,EAAG,eAAe,CAAE,MAAO,SAAU,SAAU,QAAS,CAAC,CAC9G,CAEA,SAAgB,EAAY,EAA6B,EAAwB,KAAY,CAC3F,EAAgB,CAAO,EAClB,GAIL,0BAA4B,CACtB,SAAS,eAAe,EAAS,CAAM,CAAC,EAAG,EAAe,CAAM,EAC/D,0BAA4B,EAAe,CAAM,CAAC,CACzD,CAAC,CACH,CAEA,SAAgB,EAAS,EAAyB,CAChD,EAAiB,CAAS,CAC5B"}
1
+ {"version":3,"file":"nav-mimleI0R.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/command/nav.ts"],"sourcesContent":["/**\n * routes/verse/command/nav.ts — how a surface card asks the shell to go\n * somewhere (unit C7). The shell (C1) owns navigation state; these are thin\n * wrappers over its store so every card words navigation the same way:\n *\n * openNeedsYou() ⌘J's drawer, optionally focused on one item;\n * goToSection(s, a) switch surface (keep-alive: the target keeps its\n * state) and, when `anchor` names a card or row on\n * it, scroll that into view once it is on screen;\n * openChat(sessionId) the chat a Needs-you item or insight is about.\n */\nimport type { WorkbenchSectionId } from '../../../../core/verse/workbench-types.js';\nimport { openVerseNeedsYou, openVerseSession, setVerseSection } from '../verse-ui-store.js';\n\nexport function openNeedsYou(focusId: string | null = null): void {\n openVerseNeedsYou(focusId ? { focusId } : {});\n}\n\n/** DOM id for an anchor (\"repo-ashlrai/binshield\" → \"c7-anchor-repo-ashlrai-binshield\"). */\nexport function anchorId(anchor: string): string {\n return `c7-anchor-${anchor.replace(/[^A-Za-z0-9_-]/g, '-')}`;\n}\n\nexport function scrollToAnchor(anchor: string): void {\n const el = document.getElementById(anchorId(anchor));\n if (el && typeof el.scrollIntoView === 'function') el.scrollIntoView({ block: 'center', behavior: 'smooth' });\n}\n\nexport function goToSection(section: WorkbenchSectionId, anchor: string | null = null): void {\n setVerseSection(section);\n if (!anchor) return;\n // The target surface may be mounting (lazy chunk) or un-hiding (keep-alive):\n // try on the next two frames, then give up quietly — a missing anchor is\n // never an error, the operator is already on the right surface.\n requestAnimationFrame(() => {\n if (document.getElementById(anchorId(anchor))) scrollToAnchor(anchor);\n else requestAnimationFrame(() => scrollToAnchor(anchor));\n });\n}\n\nexport function openChat(sessionId: string): void {\n openVerseSession(sessionId);\n}\n"],"mappings":"mEAcA,SAAgB,EAAa,EAAyB,KAAY,CAChE,EAAkB,EAAU,CAAE,SAAQ,EAAI,CAAC,CAAC,CAC9C,CAGA,SAAgB,EAAS,EAAwB,CAC/C,MAAO,aAAa,EAAO,QAAQ,kBAAmB,GAAG,GAC3D,CAEA,SAAgB,EAAe,EAAsB,CACnD,IAAM,EAAK,SAAS,eAAe,EAAS,CAAM,CAAC,EAC/C,GAAM,OAAO,EAAG,gBAAmB,YAAY,EAAG,eAAe,CAAE,MAAO,SAAU,SAAU,QAAS,CAAC,CAC9G,CAEA,SAAgB,EAAY,EAA6B,EAAwB,KAAY,CAC3F,EAAgB,CAAO,EAClB,GAIL,0BAA4B,CACtB,SAAS,eAAe,EAAS,CAAM,CAAC,EAAG,EAAe,CAAM,EAC/D,0BAA4B,EAAe,CAAM,CAAC,CACzD,CAAC,CACH,CAEA,SAAgB,EAAS,EAAyB,CAChD,EAAiB,CAAS,CAC5B"}
@@ -1,2 +1,2 @@
1
- import{a as e,c as t}from"./index-BG177cPN.js";import{E as n,H as r,P as i,c as a,l as o,m as s,o as c}from"./global-CXHHMz9o.js";import{c as l}from"./format-DEAaVF6X.js";import{n as u,t as d}from"./control-queries-DB6Kh7UN.js";var f=t(e(),1);function p(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function m(e){return typeof e==`string`&&e.trim()!==``?e:null}function h(e){return typeof e==`boolean`?e:null}function g(e){return typeof e!=`number`||!Number.isFinite(e)||e<0?null:Math.floor(e)}function _(e){if(!p(e))return null;let t=m(e.kind);if(t===`until-paused`)return{kind:`until-paused`};if(t===`at-time`){let t=m(e.at);return t===null||Number.isNaN(Date.parse(t))?null:{kind:`at-time`,at:t}}if(t===`after-iterations`){let t=g(e.iterations);return t===null||t<=0?null:{kind:`after-iterations`,iterations:t}}return null}function v(e){if(!Array.isArray(e))return[];let t=[];for(let[n,r]of e.entries()){if(!p(r))continue;let e=m(r.repo);e!==null&&t.push({id:m(r.id)??`${e}:${n}`,repo:e,title:m(r.title)??`untitled change`,at:m(r.at),commit:m(r.commit)})}return t}function y(e){if(!Array.isArray(e))return[];let t=[];for(let[n,r]of e.entries()){if(!p(r))continue;let e=m(r.repo);e!==null&&t.push({id:m(r.id)??`${e}:${n}`,repo:e,title:m(r.title)??`untitled change`,at:m(r.at),reason:m(r.reason)??`no reason recorded`})}return t}function b(e){return p(e)?{tests:h(e.tests),lint:h(e.lint),typecheck:h(e.typecheck),autoMerge:h(e.autoMerge),branch:m(e.branch)}:null}function x(e){if(!p(e))return null;let t=m(e.runId);return t===null?null:{runId:t,startedAt:m(e.startedAt),stopRule:_(e.stopRule),iterationsDone:g(e.iterationsDone),repo:m(e.repo),activity:m(e.activity),merged:v(e.merged),discarded:y(e.discarded)}}function S(e){if(!p(e))return null;let t=h(e.armed);return t===null?null:{armed:t,run:x(e.run),repos:g(e.repos),...e.mirrors===void 0?{}:{mirrors:g(e.mirrors)},gate:b(e.gate)}}function C(e,t=new Date){let n=/^(\d{1,2}):(\d{2})$/.exec(e.trim());if(!n)return null;let r=Number(n[1]),i=Number(n[2]);if(!Number.isInteger(r)||!Number.isInteger(i)||r<0||r>23||i<0||i>59)return null;let a=new Date(t);return a.setHours(r,i,0,0),a.getTime()<=t.getTime()&&a.setDate(a.getDate()+1),a.toISOString()}function w(e){if(!e)return`—`;let t=Date.parse(e);return Number.isNaN(t)?`—`:new Date(t).toLocaleTimeString(void 0,{hour:`2-digit`,minute:`2-digit`})}function T(e,t=new Date){if(!e)return!1;let n=Date.parse(e);return!Number.isNaN(n)&&new Date(n).toDateString()!==t.toDateString()}function E(e,t=new Date){switch(e.kind){case`until-paused`:return`Runs until you pause it — no stop time, no iteration limit.`;case`at-time`:return`Stops at ${w(e.at)}${T(e.at,t)?` tomorrow`:``}.`;case`after-iterations`:return`Stops after ${e.iterations} ${e.iterations===1?`iteration`:`iterations`}.`}}function D(e,t,n=Date.now()){if(e===null)return{headline:`Stop rule not stated`,remaining:`—`,percent:null,reached:!1};if(e.kind===`until-paused`)return{headline:`Runs until you pause it`,remaining:`no stop time, no iteration limit`,percent:null,reached:!1};if(e.kind===`at-time`){let r=Date.parse(e.at);if(Number.isNaN(r))return{headline:`Stop time not readable`,remaining:`—`,percent:null,reached:!1};let i=`Stops at ${w(e.at)}`,a=r-n;if(a<=0)return{headline:i,remaining:`stop time reached`,percent:100,reached:!0};let o=t?.startedAt?Date.parse(t.startedAt):NaN,s=Number.isNaN(o)||r<=o?null:Math.min(100,Math.max(0,Math.round((n-o)/(r-o)*100)));return{headline:i,remaining:`${l(a)} left`,percent:s,reached:!1}}let r=t?.iterationsDone,i=`Stops after ${e.iterations} ${e.iterations===1?`iteration`:`iterations`}`;return typeof r==`number`?{headline:i,remaining:`${r} of ${e.iterations} done`,percent:Math.min(100,Math.round(r/e.iterations*100)),reached:r>=e.iterations}:{headline:i,remaining:`— of ${e.iterations} done`,percent:null,reached:!1}}function O(e,t=Date.now()){if(!e)return`—`;let n=Date.parse(e);return Number.isNaN(n)?`—`:l(Math.max(0,t-n))}function k(e){if(e===null)return[];let t=[];return e.tests===!0&&t.push(`tests`),e.lint===!0&&t.push(`lint`),e.typecheck===!0&&t.push(`typecheck`),t}function A(e){if(e===null)return[`tests`,`lint`,`typecheck`];let t=[];return e.tests===null&&t.push(`tests`),e.lint===null&&t.push(`lint`),e.typecheck===null&&t.push(`typecheck`),t}function j(e){return e.length===0?``:e.length===1?e[0]:`${e.slice(0,-1).join(`, `)} and ${e[e.length-1]}`}var M=`verse-overnight`,N=`/api/verse/overnight`;function P(e){return e instanceof c?e.status===404?`Overnight runs are not available on this server.`:`${N} answered HTTP ${e.status}.`:`${N} could not be reached.`}var F={key:M,fetch:async e=>{try{let t=S(await a(N,e));return t===null?{value:null,available:!0,reason:`Unrecognized response — update Ashlr.`}:{value:t,available:!0,reason:null}}catch(e){if(e instanceof c&&e.status===401||e instanceof DOMException&&e.name===`AbortError`)throw e;return{value:null,available:!1,reason:P(e)}}}};async function I(e,t){let r=n();if(!r)throw new u;let a=await o(e,t,r);return i(),a}function L(){r(M),r(d)}async function R(e){let t=await I(N,{action:`arm`,stopRule:e});return L(),t}async function z(){let e=await I(N,{action:`disarm`});return L(),e}var B=15e3;function V(e,t=B){let n=s(F);(0,f.useEffect)(()=>{if(!e)return;let r=null,i=()=>{r===null&&(r=setInterval(n,t))},a=()=>{r!==null&&(clearInterval(r),r=null)},o=()=>{if(document.visibilityState===`hidden`){a();return}n(),i()};return document.visibilityState!==`hidden`&&i(),document.addEventListener(`visibilitychange`,o),()=>{a(),document.removeEventListener(`visibilitychange`,o)}},[e,t,n])}export{E as a,A as c,D as d,V as i,j as l,z as n,O as o,F as r,k as s,R as t,C as u};
2
- //# sourceMappingURL=overnight-queries-CR0b_j-V.js.map
1
+ import{a as e,c as t}from"./index-CyK31YRm.js";import{D as n,F as r,U as i,c as a,h as o,l as s,o as c}from"./global-y_exIyAP.js";import{c as l}from"./format-BmH2yWL6.js";import{n as u,t as d}from"./control-queries-CXtmZZH6.js";var f=t(e(),1);function p(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function m(e){return typeof e==`string`&&e.trim()!==``?e:null}function h(e){return typeof e==`boolean`?e:null}function g(e){return typeof e!=`number`||!Number.isFinite(e)||e<0?null:Math.floor(e)}function _(e){if(!p(e))return null;let t=m(e.kind);if(t===`until-paused`)return{kind:`until-paused`};if(t===`at-time`){let t=m(e.at);return t===null||Number.isNaN(Date.parse(t))?null:{kind:`at-time`,at:t}}if(t===`after-iterations`){let t=g(e.iterations);return t===null||t<=0?null:{kind:`after-iterations`,iterations:t}}return null}function v(e){if(!Array.isArray(e))return[];let t=[];for(let[n,r]of e.entries()){if(!p(r))continue;let e=m(r.repo);e!==null&&t.push({id:m(r.id)??`${e}:${n}`,repo:e,title:m(r.title)??`untitled change`,at:m(r.at),commit:m(r.commit)})}return t}function y(e){if(!Array.isArray(e))return[];let t=[];for(let[n,r]of e.entries()){if(!p(r))continue;let e=m(r.repo);e!==null&&t.push({id:m(r.id)??`${e}:${n}`,repo:e,title:m(r.title)??`untitled change`,at:m(r.at),reason:m(r.reason)??`no reason recorded`})}return t}function b(e){return p(e)?{tests:h(e.tests),lint:h(e.lint),typecheck:h(e.typecheck),autoMerge:h(e.autoMerge),branch:m(e.branch)}:null}function x(e){if(!p(e))return null;let t=m(e.runId);return t===null?null:{runId:t,startedAt:m(e.startedAt),stopRule:_(e.stopRule),iterationsDone:g(e.iterationsDone),repo:m(e.repo),activity:m(e.activity),merged:v(e.merged),discarded:y(e.discarded)}}function S(e){if(!p(e))return null;let t=h(e.armed);return t===null?null:{armed:t,run:x(e.run),repos:g(e.repos),...e.mirrors===void 0?{}:{mirrors:g(e.mirrors)},gate:b(e.gate)}}function C(e,t=new Date){let n=/^(\d{1,2}):(\d{2})$/.exec(e.trim());if(!n)return null;let r=Number(n[1]),i=Number(n[2]);if(!Number.isInteger(r)||!Number.isInteger(i)||r<0||r>23||i<0||i>59)return null;let a=new Date(t);return a.setHours(r,i,0,0),a.getTime()<=t.getTime()&&a.setDate(a.getDate()+1),a.toISOString()}function w(e){if(!e)return`—`;let t=Date.parse(e);return Number.isNaN(t)?`—`:new Date(t).toLocaleTimeString(void 0,{hour:`2-digit`,minute:`2-digit`})}function T(e,t=new Date){if(!e)return!1;let n=Date.parse(e);return!Number.isNaN(n)&&new Date(n).toDateString()!==t.toDateString()}function E(e,t=new Date){switch(e.kind){case`until-paused`:return`Runs until you pause it — no stop time, no iteration limit.`;case`at-time`:return`Stops at ${w(e.at)}${T(e.at,t)?` tomorrow`:``}.`;case`after-iterations`:return`Stops after ${e.iterations} ${e.iterations===1?`iteration`:`iterations`}.`}}function D(e,t,n=Date.now()){if(e===null)return{headline:`Stop rule not stated`,remaining:`—`,percent:null,reached:!1};if(e.kind===`until-paused`)return{headline:`Runs until you pause it`,remaining:`no stop time, no iteration limit`,percent:null,reached:!1};if(e.kind===`at-time`){let r=Date.parse(e.at);if(Number.isNaN(r))return{headline:`Stop time not readable`,remaining:`—`,percent:null,reached:!1};let i=`Stops at ${w(e.at)}`,a=r-n;if(a<=0)return{headline:i,remaining:`stop time reached`,percent:100,reached:!0};let o=t?.startedAt?Date.parse(t.startedAt):NaN,s=Number.isNaN(o)||r<=o?null:Math.min(100,Math.max(0,Math.round((n-o)/(r-o)*100)));return{headline:i,remaining:`${l(a)} left`,percent:s,reached:!1}}let r=t?.iterationsDone,i=`Stops after ${e.iterations} ${e.iterations===1?`iteration`:`iterations`}`;return typeof r==`number`?{headline:i,remaining:`${r} of ${e.iterations} done`,percent:Math.min(100,Math.round(r/e.iterations*100)),reached:r>=e.iterations}:{headline:i,remaining:`— of ${e.iterations} done`,percent:null,reached:!1}}function O(e,t=Date.now()){if(!e)return`—`;let n=Date.parse(e);return Number.isNaN(n)?`—`:l(Math.max(0,t-n))}function k(e){if(e===null)return[];let t=[];return e.tests===!0&&t.push(`tests`),e.lint===!0&&t.push(`lint`),e.typecheck===!0&&t.push(`typecheck`),t}function A(e){if(e===null)return[`tests`,`lint`,`typecheck`];let t=[];return e.tests===null&&t.push(`tests`),e.lint===null&&t.push(`lint`),e.typecheck===null&&t.push(`typecheck`),t}function j(e){return e.length===0?``:e.length===1?e[0]:`${e.slice(0,-1).join(`, `)} and ${e[e.length-1]}`}var M=`verse-overnight`,N=`/api/verse/overnight`;function P(e){return e instanceof c?e.status===404?`Overnight runs are not available on this server.`:`${N} answered HTTP ${e.status}.`:`${N} could not be reached.`}var F={key:M,fetch:async e=>{try{let t=S(await a(N,e));return t===null?{value:null,available:!0,reason:`Unrecognized response — update Ashlr.`}:{value:t,available:!0,reason:null}}catch(e){if(e instanceof c&&e.status===401||e instanceof DOMException&&e.name===`AbortError`)throw e;return{value:null,available:!1,reason:P(e)}}}};async function I(e,t){let i=n();if(!i)throw new u;let a=await s(e,t,i);return r(),a}function L(){i(M),i(d)}async function R(e){let t=await I(N,{action:`arm`,stopRule:e});return L(),t}async function z(){let e=await I(N,{action:`disarm`});return L(),e}var B=15e3;function V(e,t=B){let n=o(F);(0,f.useEffect)(()=>{if(!e)return;let r=null,i=()=>{r===null&&(r=setInterval(n,t))},a=()=>{r!==null&&(clearInterval(r),r=null)},o=()=>{if(document.visibilityState===`hidden`){a();return}n(),i()};return document.visibilityState!==`hidden`&&i(),document.addEventListener(`visibilitychange`,o),()=>{a(),document.removeEventListener(`visibilitychange`,o)}},[e,t,n])}export{E as a,A as c,D as d,V as i,j as l,z as n,O as o,F as r,k as s,R as t,C as u};
2
+ //# sourceMappingURL=overnight-queries-DJ4mZKSj.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"overnight-queries-CR0b_j-V.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/autonomy/overnight-model.ts","../../../../../../src/web-ui/routes/verse/autonomy/overnight-queries.ts"],"sourcesContent":["/**\n * routes/verse/autonomy/overnight-model.ts — the pure half of the Overnight\n * panel: narrow the server's body, resolve the operator's stop rule, and\n * derive the one line that says how far the run is from stopping.\n *\n * Framework-free so it unit-tests without a DOM, and separate from the panel\n * because two of these functions are where the panel can most easily start\n * lying:\n *\n * - `projectOvernight` NARROWS, it does not cast. The route is being written\n * by another owner in parallel with this surface, so a field that drifts in\n * name or type has to degrade to `null` — which the panel renders as \"not\n * stated\" — rather than reach a render as `undefined` and crash, or reach\n * it as `0` and read as a fact. Same discipline as `fleet-model.ts`.\n * - `stopProgress` never invents a denominator. \"Until I pause it\" has no\n * progress, and drawing a bar for it would be a picture of a finish line\n * that does not exist.\n */\nimport { formatDuration, UNKNOWN } from './format.js';\nimport type {\n OvernightDiscard,\n OvernightGate,\n OvernightMerge,\n OvernightRun,\n OvernightStatus,\n OvernightStopRule,\n OvernightStopRuleKind,\n} from './overnight-contract.js';\n\n// ---------------------------------------------------------------------------\n// Narrowing\n// ---------------------------------------------------------------------------\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction str(value: unknown): string | null {\n return typeof value === 'string' && value.trim() !== '' ? value : null;\n}\n\nfunction bool(value: unknown): boolean | null {\n return typeof value === 'boolean' ? value : null;\n}\n\n/** A count. Negative and non-finite are not counts, so they are not observed. */\nfunction count(value: unknown): number | null {\n if (typeof value !== 'number' || !Number.isFinite(value) || value < 0) return null;\n return Math.floor(value);\n}\n\nexport function projectStopRule(raw: unknown): OvernightStopRule | null {\n if (!isRecord(raw)) return null;\n const kind = str(raw['kind']);\n if (kind === 'until-paused') return { kind: 'until-paused' };\n if (kind === 'at-time') {\n const at = str(raw['at']);\n // An unparseable instant is worse than no rule: it would render as a\n // countdown to NaN. Refuse it here so the panel can say \"not stated\".\n if (at === null || Number.isNaN(Date.parse(at))) return null;\n return { kind: 'at-time', at };\n }\n if (kind === 'after-iterations') {\n const iterations = count(raw['iterations']);\n if (iterations === null || iterations <= 0) return null;\n return { kind: 'after-iterations', iterations };\n }\n return null;\n}\n\nfunction projectMerges(raw: unknown): OvernightMerge[] {\n if (!Array.isArray(raw)) return [];\n const out: OvernightMerge[] = [];\n for (const [index, item] of raw.entries()) {\n if (!isRecord(item)) continue;\n const repo = str(item['repo']);\n if (repo === null) continue;\n out.push({\n id: str(item['id']) ?? `${repo}:${index}`,\n repo,\n title: str(item['title']) ?? 'untitled change',\n at: str(item['at']),\n commit: str(item['commit']),\n });\n }\n return out;\n}\n\nfunction projectDiscards(raw: unknown): OvernightDiscard[] {\n if (!Array.isArray(raw)) return [];\n const out: OvernightDiscard[] = [];\n for (const [index, item] of raw.entries()) {\n if (!isRecord(item)) continue;\n const repo = str(item['repo']);\n if (repo === null) continue;\n out.push({\n id: str(item['id']) ?? `${repo}:${index}`,\n repo,\n title: str(item['title']) ?? 'untitled change',\n at: str(item['at']),\n // A discard with no stated reason is the one row an operator will ask\n // about in the morning, so it says that it has none rather than being\n // rendered as a blank cell.\n reason: str(item['reason']) ?? 'no reason recorded',\n });\n }\n return out;\n}\n\nfunction projectGate(raw: unknown): OvernightGate | null {\n if (!isRecord(raw)) return null;\n return {\n tests: bool(raw['tests']),\n lint: bool(raw['lint']),\n typecheck: bool(raw['typecheck']),\n autoMerge: bool(raw['autoMerge']),\n branch: str(raw['branch']),\n };\n}\n\nfunction projectRun(raw: unknown): OvernightRun | null {\n if (!isRecord(raw)) return null;\n const runId = str(raw['runId']);\n if (runId === null) return null;\n return {\n runId,\n startedAt: str(raw['startedAt']),\n stopRule: projectStopRule(raw['stopRule']),\n iterationsDone: count(raw['iterationsDone']),\n repo: str(raw['repo']),\n activity: str(raw['activity']),\n merged: projectMerges(raw['merged']),\n discarded: projectDiscards(raw['discarded']),\n };\n}\n\n/**\n * `GET /api/verse/overnight` → a status, or null when the body is not one.\n *\n * `armed` is the single field this refuses to guess: a body that does not say\n * whether a run is armed is not a status, because \"nothing is armed\" is\n * exactly the claim a person checks before closing the laptop.\n */\nexport function projectOvernight(raw: unknown): OvernightStatus | null {\n if (!isRecord(raw)) return null;\n const armed = bool(raw['armed']);\n if (armed === null) return null;\n return {\n armed,\n run: projectRun(raw['run']),\n repos: count(raw['repos']),\n // Present-but-invalid reads as null (\"not recorded\"); absent stays absent,\n // so an older server is not shown as having lost a count it never sent.\n ...(raw['mirrors'] !== undefined ? { mirrors: count(raw['mirrors']) } : {}),\n gate: projectGate(raw['gate']),\n };\n}\n\n// ---------------------------------------------------------------------------\n// The operator's side of the stop rule\n// ---------------------------------------------------------------------------\n\n/** Smallest and largest iteration cap the form will send. */\nexport const ITERATIONS_MIN = 1;\nexport const ITERATIONS_MAX = 500;\n\n/**\n * Turn an `<input type=\"time\">` value (\"23:30\") into the next occurrence of\n * that wall-clock time, as an absolute instant.\n *\n * The whole point of arming this at 11pm is that \"07:00\" means tomorrow\n * morning. Resolving it on the client, in the operator's own zone, is what\n * makes that unambiguous by the time it reaches a server that may not share\n * the zone — and rounds to the minute, so a run armed at 06:59:58 for 07:00\n * does not stop two seconds later.\n */\nexport function resolveStopAt(value: string, now: Date = new Date()): string | null {\n const match = /^(\\d{1,2}):(\\d{2})$/.exec(value.trim());\n if (!match) return null;\n const hours = Number(match[1]);\n const minutes = Number(match[2]);\n if (!Number.isInteger(hours) || !Number.isInteger(minutes)) return null;\n if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) return null;\n const at = new Date(now);\n at.setHours(hours, minutes, 0, 0);\n if (at.getTime() <= now.getTime()) at.setDate(at.getDate() + 1);\n return at.toISOString();\n}\n\n/** \"07:00\" as the operator's locale writes it — never a raw ISO string. */\nexport function formatStopClock(iso: string | null): string {\n if (!iso) return UNKNOWN;\n const ms = Date.parse(iso);\n if (Number.isNaN(ms)) return UNKNOWN;\n return new Date(ms).toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' });\n}\n\n/** True when the resolved instant is not today — \"07:00 tomorrow\". */\nexport function isNextDay(iso: string | null, now: Date = new Date()): boolean {\n if (!iso) return false;\n const ms = Date.parse(iso);\n if (Number.isNaN(ms)) return false;\n return new Date(ms).toDateString() !== now.toDateString();\n}\n\n/**\n * The sentence the Arm button is committing to, before the click.\n *\n * It restates the rule the operator chose in the operator's own units, so the\n * button is never the only description of what is about to be authorised.\n */\nexport function describeStopRule(rule: OvernightStopRule, now: Date = new Date()): string {\n switch (rule.kind) {\n case 'until-paused':\n return 'Runs until you pause it — no stop time, no iteration limit.';\n case 'at-time':\n return `Stops at ${formatStopClock(rule.at)}${isNextDay(rule.at, now) ? ' tomorrow' : ''}.`;\n case 'after-iterations':\n return `Stops after ${rule.iterations} ${rule.iterations === 1 ? 'iteration' : 'iterations'}.`;\n }\n}\n\n/** The short label each stop rule wears in the armed summary. */\nexport function stopRuleLabel(kind: OvernightStopRuleKind): string {\n switch (kind) {\n case 'until-paused':\n return 'Until paused';\n case 'at-time':\n return 'At a set time';\n case 'after-iterations':\n return 'After N iterations';\n }\n}\n\n// ---------------------------------------------------------------------------\n// How far to the stop condition\n// ---------------------------------------------------------------------------\n\nexport interface StopProgress {\n /** The rule, restated: \"Stops at 07:00\". */\n headline: string;\n /** How much is left: \"4h 12m left\", \"12 of 20 done\". */\n remaining: string;\n /** 0-100 for a meter, or null when there is no honest denominator. */\n percent: number | null;\n /** True once the condition is met and the loop should be winding down. */\n reached: boolean;\n}\n\n/**\n * How far the run is from its stop condition.\n *\n * `percent` is null for \"until I pause it\" on purpose: an open-ended run has\n * no finish line, and a bar with no denominator is the exact kind of confident\n * graphic this cockpit is not allowed to draw.\n */\nexport function stopProgress(\n rule: OvernightStopRule | null,\n run: OvernightRun | null,\n now: number = Date.now(),\n): StopProgress {\n if (rule === null) {\n return {\n headline: 'Stop rule not stated',\n remaining: UNKNOWN,\n percent: null,\n reached: false,\n };\n }\n\n if (rule.kind === 'until-paused') {\n return {\n headline: 'Runs until you pause it',\n remaining: 'no stop time, no iteration limit',\n percent: null,\n reached: false,\n };\n }\n\n if (rule.kind === 'at-time') {\n const at = Date.parse(rule.at);\n if (Number.isNaN(at)) {\n return { headline: 'Stop time not readable', remaining: UNKNOWN, percent: null, reached: false };\n }\n const headline = `Stops at ${formatStopClock(rule.at)}`;\n const left = at - now;\n if (left <= 0) {\n return { headline, remaining: 'stop time reached', percent: 100, reached: true };\n }\n const startedAt = run?.startedAt ? Date.parse(run.startedAt) : Number.NaN;\n // Elapsed over the run's whole window — which needs a start. Without one\n // the countdown is still true, so it is shown; only the bar is withheld.\n const percent =\n Number.isNaN(startedAt) || at <= startedAt\n ? null\n : Math.min(100, Math.max(0, Math.round(((now - startedAt) / (at - startedAt)) * 100)));\n return { headline, remaining: `${formatDuration(left)} left`, percent, reached: false };\n }\n\n const done = run?.iterationsDone;\n const headline = `Stops after ${rule.iterations} ${rule.iterations === 1 ? 'iteration' : 'iterations'}`;\n if (typeof done !== 'number') {\n return {\n headline,\n remaining: `${UNKNOWN} of ${rule.iterations} done`,\n percent: null,\n reached: false,\n };\n }\n return {\n headline,\n remaining: `${done} of ${rule.iterations} done`,\n percent: Math.min(100, Math.round((done / rule.iterations) * 100)),\n reached: done >= rule.iterations,\n };\n}\n\n/** \"3h 04m\" since the run started, or UNKNOWN when it never said. */\nexport function formatRunElapsed(startedAt: string | null | undefined, now: number = Date.now()): string {\n if (!startedAt) return UNKNOWN;\n const ms = Date.parse(startedAt);\n if (Number.isNaN(ms)) return UNKNOWN;\n return formatDuration(Math.max(0, now - ms));\n}\n\n/**\n * The checks named as one phrase: \"tests, lint and typecheck\".\n *\n * Only checks the server said `true` about are named. A `null` check is not\n * named as running AND not named as skipped — `gateCaveat` below says so in\n * words instead, because a gate an operator believes is running when it is not\n * is the single most expensive misreading this panel could cause.\n */\nexport function gateChecks(gate: OvernightGate | null): string[] {\n if (gate === null) return [];\n const named: string[] = [];\n if (gate.tests === true) named.push('tests');\n if (gate.lint === true) named.push('lint');\n if (gate.typecheck === true) named.push('typecheck');\n return named;\n}\n\n/** The checks the server would not commit to, if any. */\nexport function gateUnstated(gate: OvernightGate | null): string[] {\n if (gate === null) return ['tests', 'lint', 'typecheck'];\n const unstated: string[] = [];\n if (gate.tests === null) unstated.push('tests');\n if (gate.lint === null) unstated.push('lint');\n if (gate.typecheck === null) unstated.push('typecheck');\n return unstated;\n}\n\nexport function joinPhrase(parts: readonly string[]): string {\n if (parts.length === 0) return '';\n if (parts.length === 1) return parts[0]!;\n return `${parts.slice(0, -1).join(', ')} and ${parts[parts.length - 1]!}`;\n}\n","/**\n * routes/verse/autonomy/overnight-queries.ts — the one read and the one write\n * behind the Overnight panel: `GET /api/verse/overnight` and\n * `POST /api/verse/overnight`.\n *\n * Same contract as `control-queries.ts` and `fleet-queries.ts` — the read is a\n * QueryDef consumed through `useQuery` (cache-backed, so a poll never blanks a\n * populated panel); the write pulls the held mutation token from auth-store,\n * touches the hold on success, and invalidates exactly the keys it affects.\n * There is no new data layer here on purpose.\n *\n * TWO THINGS THAT ARE DELIBERATE:\n *\n * 1. **The read does not throw on absence.** The route does not exist yet —\n * four owners are building the engine, the permit, the budgets and the\n * local-only policy in parallel. A server without it answers 404, and 404\n * means \"this panel has no source yet\", not \"Autonomy is broken\". It comes\n * back as `OptionalFleetRead` (reused rather than re-declared, because two\n * shapes for \"a read that is allowed to be absent\" would be one too many)\n * and the panel renders a designed not-available state from `reason`.\n * 401 still propagates: an expired read session is an unauthorized state\n * for the whole surface, not a missing panel.\n *\n * 2. **There is no pause route here, and there must not be one.** The halt\n * this panel offers is the DAEMON-SCOPED pause — `~/.ashlr/daemon.paused`,\n * via `runDaemonAction('pause')` in control-queries.ts. Disarming stops\n * arming the next run; pausing stops the loop that is running now, and\n * they are different questions. Neither is `stopDaemon()`, which is\n * `setKill(true)` and therefore the emergency stop wearing a quieter name\n * (see the header of DaemonControls.tsx).\n */\nimport { ApiError, apiGet, apiPost } from '../../../data/client.js';\nimport { getMutationToken, touchMutationHold } from '../../../data/auth-store.js';\nimport { invalidate } from '../../../data/cache.js';\nimport type { QueryDef } from '../../../data/queries.js';\nimport { useRefetch } from '../../../data/hooks.js';\nimport { useEffect } from 'react';\nimport { VERSE_CONTROL_KEY, VerseControlLockedError } from './control-queries.js';\nimport type { OptionalFleetRead } from './fleet-contract.js';\nimport type {\n OvernightAction,\n OvernightActionResult,\n OvernightStatus,\n OvernightStopRule,\n} from './overnight-contract.js';\nimport { projectOvernight } from './overnight-model.js';\n\nexport const VERSE_OVERNIGHT_KEY = 'verse-overnight';\nexport const OVERNIGHT_PATH = '/api/verse/overnight';\n\nfunction describeAbsence(err: unknown): string {\n if (err instanceof ApiError) {\n if (err.status === 404) {\n // A missing route — not a run that refused to start.\n return 'Overnight runs are not available on this server.';\n }\n return `${OVERNIGHT_PATH} answered HTTP ${err.status}.`;\n }\n return `${OVERNIGHT_PATH} could not be reached.`;\n}\n\n/**\n * `GET /api/verse/overnight` — is a run armed, and what has it done.\n *\n * `value` is null both when the route was absent and when it answered\n * something this client could not narrow; `available` and `reason` are what\n * tell those two apart, and the panel words them differently.\n */\nexport const overnightQuery: QueryDef<OptionalFleetRead<OvernightStatus>> = {\n key: VERSE_OVERNIGHT_KEY,\n fetch: async (signal) => {\n try {\n const raw = await apiGet<unknown>(OVERNIGHT_PATH, signal);\n const value = projectOvernight(raw);\n if (value === null) {\n return {\n value: null,\n available: true,\n // Nothing is shown rather than guessed from an unknown shape.\n reason: 'Unrecognized response — update Ashlr.',\n };\n }\n return { value, available: true, reason: null };\n } catch (err) {\n if (err instanceof ApiError && err.status === 401) throw err;\n if (err instanceof DOMException && err.name === 'AbortError') throw err;\n return { value: null, available: false, reason: describeAbsence(err) };\n }\n },\n};\n\n// ---------------------------------------------------------------------------\n// Writes\n// ---------------------------------------------------------------------------\n\nasync function post<T>(path: string, body: unknown): Promise<T> {\n const token = getMutationToken();\n if (!token) throw new VerseControlLockedError();\n const result = await apiPost<T>(path, body, token);\n touchMutationHold();\n return result;\n}\n\nfunction invalidateOvernight(): void {\n invalidate(VERSE_OVERNIGHT_KEY);\n // Arming changes what the daemon will do next, and the control snapshot is\n // what the rest of the cockpit reads that from.\n invalidate(VERSE_CONTROL_KEY);\n}\n\n/** Arm an overnight run with exactly one stop rule. */\nexport async function armOvernight(stopRule: OvernightStopRule): Promise<OvernightActionResult> {\n const body: OvernightAction = { action: 'arm', stopRule };\n const result = await post<OvernightActionResult>(OVERNIGHT_PATH, body);\n invalidateOvernight();\n return result;\n}\n\n/**\n * Disarm: no further overnight run starts.\n *\n * This is NOT the halt. It stops the arrangement, not the loop — a run already\n * in flight keeps going until it is paused. The panel says so at the click.\n */\nexport async function disarmOvernight(): Promise<OvernightActionResult> {\n const body: OvernightAction = { action: 'disarm' };\n const result = await post<OvernightActionResult>(OVERNIGHT_PATH, body);\n invalidateOvernight();\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Polling\n// ---------------------------------------------------------------------------\n\n/**\n * Slower than the fleet's 4s: an overnight run's counters move on the scale of\n * whole iterations, and the thing an operator watches second by second (the\n * elapsed clock and the countdown) is derived locally from `useNow`.\n */\nexport const OVERNIGHT_POLL_MS = 15_000;\n\n/**\n * Keep the overnight status live while a run is armed and the tab is visible.\n *\n * Only while armed: a disarmed panel has one boolean to report and polling it\n * every fifteen seconds forever would be pure waste. Hidden tabs stop the\n * timer and take one immediate reading when they come back, so a panel\n * returned to in the morning is current on the first frame.\n */\nexport function useOvernightPolling(armed: boolean, intervalMs: number = OVERNIGHT_POLL_MS): void {\n const refetch = useRefetch(overnightQuery);\n\n useEffect(() => {\n if (!armed) return;\n let timer: ReturnType<typeof setInterval> | null = null;\n\n const start = (): void => {\n if (timer !== null) return;\n timer = setInterval(refetch, intervalMs);\n };\n const stop = (): void => {\n if (timer === null) return;\n clearInterval(timer);\n timer = null;\n };\n const onVisibility = (): void => {\n if (document.visibilityState === 'hidden') {\n stop();\n return;\n }\n refetch();\n start();\n };\n\n if (document.visibilityState !== 'hidden') start();\n document.addEventListener('visibilitychange', onVisibility);\n return () => {\n stop();\n document.removeEventListener('visibilitychange', onVisibility);\n };\n }, [armed, intervalMs, refetch]);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"overnight-queries-DJ4mZKSj.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/autonomy/overnight-model.ts","../../../../../../src/web-ui/routes/verse/autonomy/overnight-queries.ts"],"sourcesContent":["/**\n * routes/verse/autonomy/overnight-model.ts — the pure half of the Overnight\n * panel: narrow the server's body, resolve the operator's stop rule, and\n * derive the one line that says how far the run is from stopping.\n *\n * Framework-free so it unit-tests without a DOM, and separate from the panel\n * because two of these functions are where the panel can most easily start\n * lying:\n *\n * - `projectOvernight` NARROWS, it does not cast. The route is being written\n * by another owner in parallel with this surface, so a field that drifts in\n * name or type has to degrade to `null` — which the panel renders as \"not\n * stated\" — rather than reach a render as `undefined` and crash, or reach\n * it as `0` and read as a fact. Same discipline as `fleet-model.ts`.\n * - `stopProgress` never invents a denominator. \"Until I pause it\" has no\n * progress, and drawing a bar for it would be a picture of a finish line\n * that does not exist.\n */\nimport { formatDuration, UNKNOWN } from './format.js';\nimport type {\n OvernightDiscard,\n OvernightGate,\n OvernightMerge,\n OvernightRun,\n OvernightStatus,\n OvernightStopRule,\n OvernightStopRuleKind,\n} from './overnight-contract.js';\n\n// ---------------------------------------------------------------------------\n// Narrowing\n// ---------------------------------------------------------------------------\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction str(value: unknown): string | null {\n return typeof value === 'string' && value.trim() !== '' ? value : null;\n}\n\nfunction bool(value: unknown): boolean | null {\n return typeof value === 'boolean' ? value : null;\n}\n\n/** A count. Negative and non-finite are not counts, so they are not observed. */\nfunction count(value: unknown): number | null {\n if (typeof value !== 'number' || !Number.isFinite(value) || value < 0) return null;\n return Math.floor(value);\n}\n\nexport function projectStopRule(raw: unknown): OvernightStopRule | null {\n if (!isRecord(raw)) return null;\n const kind = str(raw['kind']);\n if (kind === 'until-paused') return { kind: 'until-paused' };\n if (kind === 'at-time') {\n const at = str(raw['at']);\n // An unparseable instant is worse than no rule: it would render as a\n // countdown to NaN. Refuse it here so the panel can say \"not stated\".\n if (at === null || Number.isNaN(Date.parse(at))) return null;\n return { kind: 'at-time', at };\n }\n if (kind === 'after-iterations') {\n const iterations = count(raw['iterations']);\n if (iterations === null || iterations <= 0) return null;\n return { kind: 'after-iterations', iterations };\n }\n return null;\n}\n\nfunction projectMerges(raw: unknown): OvernightMerge[] {\n if (!Array.isArray(raw)) return [];\n const out: OvernightMerge[] = [];\n for (const [index, item] of raw.entries()) {\n if (!isRecord(item)) continue;\n const repo = str(item['repo']);\n if (repo === null) continue;\n out.push({\n id: str(item['id']) ?? `${repo}:${index}`,\n repo,\n title: str(item['title']) ?? 'untitled change',\n at: str(item['at']),\n commit: str(item['commit']),\n });\n }\n return out;\n}\n\nfunction projectDiscards(raw: unknown): OvernightDiscard[] {\n if (!Array.isArray(raw)) return [];\n const out: OvernightDiscard[] = [];\n for (const [index, item] of raw.entries()) {\n if (!isRecord(item)) continue;\n const repo = str(item['repo']);\n if (repo === null) continue;\n out.push({\n id: str(item['id']) ?? `${repo}:${index}`,\n repo,\n title: str(item['title']) ?? 'untitled change',\n at: str(item['at']),\n // A discard with no stated reason is the one row an operator will ask\n // about in the morning, so it says that it has none rather than being\n // rendered as a blank cell.\n reason: str(item['reason']) ?? 'no reason recorded',\n });\n }\n return out;\n}\n\nfunction projectGate(raw: unknown): OvernightGate | null {\n if (!isRecord(raw)) return null;\n return {\n tests: bool(raw['tests']),\n lint: bool(raw['lint']),\n typecheck: bool(raw['typecheck']),\n autoMerge: bool(raw['autoMerge']),\n branch: str(raw['branch']),\n };\n}\n\nfunction projectRun(raw: unknown): OvernightRun | null {\n if (!isRecord(raw)) return null;\n const runId = str(raw['runId']);\n if (runId === null) return null;\n return {\n runId,\n startedAt: str(raw['startedAt']),\n stopRule: projectStopRule(raw['stopRule']),\n iterationsDone: count(raw['iterationsDone']),\n repo: str(raw['repo']),\n activity: str(raw['activity']),\n merged: projectMerges(raw['merged']),\n discarded: projectDiscards(raw['discarded']),\n };\n}\n\n/**\n * `GET /api/verse/overnight` → a status, or null when the body is not one.\n *\n * `armed` is the single field this refuses to guess: a body that does not say\n * whether a run is armed is not a status, because \"nothing is armed\" is\n * exactly the claim a person checks before closing the laptop.\n */\nexport function projectOvernight(raw: unknown): OvernightStatus | null {\n if (!isRecord(raw)) return null;\n const armed = bool(raw['armed']);\n if (armed === null) return null;\n return {\n armed,\n run: projectRun(raw['run']),\n repos: count(raw['repos']),\n // Present-but-invalid reads as null (\"not recorded\"); absent stays absent,\n // so an older server is not shown as having lost a count it never sent.\n ...(raw['mirrors'] !== undefined ? { mirrors: count(raw['mirrors']) } : {}),\n gate: projectGate(raw['gate']),\n };\n}\n\n// ---------------------------------------------------------------------------\n// The operator's side of the stop rule\n// ---------------------------------------------------------------------------\n\n/** Smallest and largest iteration cap the form will send. */\nexport const ITERATIONS_MIN = 1;\nexport const ITERATIONS_MAX = 500;\n\n/**\n * Turn an `<input type=\"time\">` value (\"23:30\") into the next occurrence of\n * that wall-clock time, as an absolute instant.\n *\n * The whole point of arming this at 11pm is that \"07:00\" means tomorrow\n * morning. Resolving it on the client, in the operator's own zone, is what\n * makes that unambiguous by the time it reaches a server that may not share\n * the zone — and rounds to the minute, so a run armed at 06:59:58 for 07:00\n * does not stop two seconds later.\n */\nexport function resolveStopAt(value: string, now: Date = new Date()): string | null {\n const match = /^(\\d{1,2}):(\\d{2})$/.exec(value.trim());\n if (!match) return null;\n const hours = Number(match[1]);\n const minutes = Number(match[2]);\n if (!Number.isInteger(hours) || !Number.isInteger(minutes)) return null;\n if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) return null;\n const at = new Date(now);\n at.setHours(hours, minutes, 0, 0);\n if (at.getTime() <= now.getTime()) at.setDate(at.getDate() + 1);\n return at.toISOString();\n}\n\n/** \"07:00\" as the operator's locale writes it — never a raw ISO string. */\nexport function formatStopClock(iso: string | null): string {\n if (!iso) return UNKNOWN;\n const ms = Date.parse(iso);\n if (Number.isNaN(ms)) return UNKNOWN;\n return new Date(ms).toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' });\n}\n\n/** True when the resolved instant is not today — \"07:00 tomorrow\". */\nexport function isNextDay(iso: string | null, now: Date = new Date()): boolean {\n if (!iso) return false;\n const ms = Date.parse(iso);\n if (Number.isNaN(ms)) return false;\n return new Date(ms).toDateString() !== now.toDateString();\n}\n\n/**\n * The sentence the Arm button is committing to, before the click.\n *\n * It restates the rule the operator chose in the operator's own units, so the\n * button is never the only description of what is about to be authorised.\n */\nexport function describeStopRule(rule: OvernightStopRule, now: Date = new Date()): string {\n switch (rule.kind) {\n case 'until-paused':\n return 'Runs until you pause it — no stop time, no iteration limit.';\n case 'at-time':\n return `Stops at ${formatStopClock(rule.at)}${isNextDay(rule.at, now) ? ' tomorrow' : ''}.`;\n case 'after-iterations':\n return `Stops after ${rule.iterations} ${rule.iterations === 1 ? 'iteration' : 'iterations'}.`;\n }\n}\n\n/** The short label each stop rule wears in the armed summary. */\nexport function stopRuleLabel(kind: OvernightStopRuleKind): string {\n switch (kind) {\n case 'until-paused':\n return 'Until paused';\n case 'at-time':\n return 'At a set time';\n case 'after-iterations':\n return 'After N iterations';\n }\n}\n\n// ---------------------------------------------------------------------------\n// How far to the stop condition\n// ---------------------------------------------------------------------------\n\nexport interface StopProgress {\n /** The rule, restated: \"Stops at 07:00\". */\n headline: string;\n /** How much is left: \"4h 12m left\", \"12 of 20 done\". */\n remaining: string;\n /** 0-100 for a meter, or null when there is no honest denominator. */\n percent: number | null;\n /** True once the condition is met and the loop should be winding down. */\n reached: boolean;\n}\n\n/**\n * How far the run is from its stop condition.\n *\n * `percent` is null for \"until I pause it\" on purpose: an open-ended run has\n * no finish line, and a bar with no denominator is the exact kind of confident\n * graphic this cockpit is not allowed to draw.\n */\nexport function stopProgress(\n rule: OvernightStopRule | null,\n run: OvernightRun | null,\n now: number = Date.now(),\n): StopProgress {\n if (rule === null) {\n return {\n headline: 'Stop rule not stated',\n remaining: UNKNOWN,\n percent: null,\n reached: false,\n };\n }\n\n if (rule.kind === 'until-paused') {\n return {\n headline: 'Runs until you pause it',\n remaining: 'no stop time, no iteration limit',\n percent: null,\n reached: false,\n };\n }\n\n if (rule.kind === 'at-time') {\n const at = Date.parse(rule.at);\n if (Number.isNaN(at)) {\n return { headline: 'Stop time not readable', remaining: UNKNOWN, percent: null, reached: false };\n }\n const headline = `Stops at ${formatStopClock(rule.at)}`;\n const left = at - now;\n if (left <= 0) {\n return { headline, remaining: 'stop time reached', percent: 100, reached: true };\n }\n const startedAt = run?.startedAt ? Date.parse(run.startedAt) : Number.NaN;\n // Elapsed over the run's whole window — which needs a start. Without one\n // the countdown is still true, so it is shown; only the bar is withheld.\n const percent =\n Number.isNaN(startedAt) || at <= startedAt\n ? null\n : Math.min(100, Math.max(0, Math.round(((now - startedAt) / (at - startedAt)) * 100)));\n return { headline, remaining: `${formatDuration(left)} left`, percent, reached: false };\n }\n\n const done = run?.iterationsDone;\n const headline = `Stops after ${rule.iterations} ${rule.iterations === 1 ? 'iteration' : 'iterations'}`;\n if (typeof done !== 'number') {\n return {\n headline,\n remaining: `${UNKNOWN} of ${rule.iterations} done`,\n percent: null,\n reached: false,\n };\n }\n return {\n headline,\n remaining: `${done} of ${rule.iterations} done`,\n percent: Math.min(100, Math.round((done / rule.iterations) * 100)),\n reached: done >= rule.iterations,\n };\n}\n\n/** \"3h 04m\" since the run started, or UNKNOWN when it never said. */\nexport function formatRunElapsed(startedAt: string | null | undefined, now: number = Date.now()): string {\n if (!startedAt) return UNKNOWN;\n const ms = Date.parse(startedAt);\n if (Number.isNaN(ms)) return UNKNOWN;\n return formatDuration(Math.max(0, now - ms));\n}\n\n/**\n * The checks named as one phrase: \"tests, lint and typecheck\".\n *\n * Only checks the server said `true` about are named. A `null` check is not\n * named as running AND not named as skipped — `gateCaveat` below says so in\n * words instead, because a gate an operator believes is running when it is not\n * is the single most expensive misreading this panel could cause.\n */\nexport function gateChecks(gate: OvernightGate | null): string[] {\n if (gate === null) return [];\n const named: string[] = [];\n if (gate.tests === true) named.push('tests');\n if (gate.lint === true) named.push('lint');\n if (gate.typecheck === true) named.push('typecheck');\n return named;\n}\n\n/** The checks the server would not commit to, if any. */\nexport function gateUnstated(gate: OvernightGate | null): string[] {\n if (gate === null) return ['tests', 'lint', 'typecheck'];\n const unstated: string[] = [];\n if (gate.tests === null) unstated.push('tests');\n if (gate.lint === null) unstated.push('lint');\n if (gate.typecheck === null) unstated.push('typecheck');\n return unstated;\n}\n\nexport function joinPhrase(parts: readonly string[]): string {\n if (parts.length === 0) return '';\n if (parts.length === 1) return parts[0]!;\n return `${parts.slice(0, -1).join(', ')} and ${parts[parts.length - 1]!}`;\n}\n","/**\n * routes/verse/autonomy/overnight-queries.ts — the one read and the one write\n * behind the Overnight panel: `GET /api/verse/overnight` and\n * `POST /api/verse/overnight`.\n *\n * Same contract as `control-queries.ts` and `fleet-queries.ts` — the read is a\n * QueryDef consumed through `useQuery` (cache-backed, so a poll never blanks a\n * populated panel); the write pulls the held mutation token from auth-store,\n * touches the hold on success, and invalidates exactly the keys it affects.\n * There is no new data layer here on purpose.\n *\n * TWO THINGS THAT ARE DELIBERATE:\n *\n * 1. **The read does not throw on absence.** The route does not exist yet —\n * four owners are building the engine, the permit, the budgets and the\n * local-only policy in parallel. A server without it answers 404, and 404\n * means \"this panel has no source yet\", not \"Autonomy is broken\". It comes\n * back as `OptionalFleetRead` (reused rather than re-declared, because two\n * shapes for \"a read that is allowed to be absent\" would be one too many)\n * and the panel renders a designed not-available state from `reason`.\n * 401 still propagates: an expired read session is an unauthorized state\n * for the whole surface, not a missing panel.\n *\n * 2. **There is no pause route here, and there must not be one.** The halt\n * this panel offers is the DAEMON-SCOPED pause — `~/.ashlr/daemon.paused`,\n * via `runDaemonAction('pause')` in control-queries.ts. Disarming stops\n * arming the next run; pausing stops the loop that is running now, and\n * they are different questions. Neither is `stopDaemon()`, which is\n * `setKill(true)` and therefore the emergency stop wearing a quieter name\n * (see the header of DaemonControls.tsx).\n */\nimport { ApiError, apiGet, apiPost } from '../../../data/client.js';\nimport { getMutationToken, touchMutationHold } from '../../../data/auth-store.js';\nimport { invalidate } from '../../../data/cache.js';\nimport type { QueryDef } from '../../../data/queries.js';\nimport { useRefetch } from '../../../data/hooks.js';\nimport { useEffect } from 'react';\nimport { VERSE_CONTROL_KEY, VerseControlLockedError } from './control-queries.js';\nimport type { OptionalFleetRead } from './fleet-contract.js';\nimport type {\n OvernightAction,\n OvernightActionResult,\n OvernightStatus,\n OvernightStopRule,\n} from './overnight-contract.js';\nimport { projectOvernight } from './overnight-model.js';\n\nexport const VERSE_OVERNIGHT_KEY = 'verse-overnight';\nexport const OVERNIGHT_PATH = '/api/verse/overnight';\n\nfunction describeAbsence(err: unknown): string {\n if (err instanceof ApiError) {\n if (err.status === 404) {\n // A missing route — not a run that refused to start.\n return 'Overnight runs are not available on this server.';\n }\n return `${OVERNIGHT_PATH} answered HTTP ${err.status}.`;\n }\n return `${OVERNIGHT_PATH} could not be reached.`;\n}\n\n/**\n * `GET /api/verse/overnight` — is a run armed, and what has it done.\n *\n * `value` is null both when the route was absent and when it answered\n * something this client could not narrow; `available` and `reason` are what\n * tell those two apart, and the panel words them differently.\n */\nexport const overnightQuery: QueryDef<OptionalFleetRead<OvernightStatus>> = {\n key: VERSE_OVERNIGHT_KEY,\n fetch: async (signal) => {\n try {\n const raw = await apiGet<unknown>(OVERNIGHT_PATH, signal);\n const value = projectOvernight(raw);\n if (value === null) {\n return {\n value: null,\n available: true,\n // Nothing is shown rather than guessed from an unknown shape.\n reason: 'Unrecognized response — update Ashlr.',\n };\n }\n return { value, available: true, reason: null };\n } catch (err) {\n if (err instanceof ApiError && err.status === 401) throw err;\n if (err instanceof DOMException && err.name === 'AbortError') throw err;\n return { value: null, available: false, reason: describeAbsence(err) };\n }\n },\n};\n\n// ---------------------------------------------------------------------------\n// Writes\n// ---------------------------------------------------------------------------\n\nasync function post<T>(path: string, body: unknown): Promise<T> {\n const token = getMutationToken();\n if (!token) throw new VerseControlLockedError();\n const result = await apiPost<T>(path, body, token);\n touchMutationHold();\n return result;\n}\n\nfunction invalidateOvernight(): void {\n invalidate(VERSE_OVERNIGHT_KEY);\n // Arming changes what the daemon will do next, and the control snapshot is\n // what the rest of the cockpit reads that from.\n invalidate(VERSE_CONTROL_KEY);\n}\n\n/** Arm an overnight run with exactly one stop rule. */\nexport async function armOvernight(stopRule: OvernightStopRule): Promise<OvernightActionResult> {\n const body: OvernightAction = { action: 'arm', stopRule };\n const result = await post<OvernightActionResult>(OVERNIGHT_PATH, body);\n invalidateOvernight();\n return result;\n}\n\n/**\n * Disarm: no further overnight run starts.\n *\n * This is NOT the halt. It stops the arrangement, not the loop — a run already\n * in flight keeps going until it is paused. The panel says so at the click.\n */\nexport async function disarmOvernight(): Promise<OvernightActionResult> {\n const body: OvernightAction = { action: 'disarm' };\n const result = await post<OvernightActionResult>(OVERNIGHT_PATH, body);\n invalidateOvernight();\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Polling\n// ---------------------------------------------------------------------------\n\n/**\n * Slower than the fleet's 4s: an overnight run's counters move on the scale of\n * whole iterations, and the thing an operator watches second by second (the\n * elapsed clock and the countdown) is derived locally from `useNow`.\n */\nexport const OVERNIGHT_POLL_MS = 15_000;\n\n/**\n * Keep the overnight status live while a run is armed and the tab is visible.\n *\n * Only while armed: a disarmed panel has one boolean to report and polling it\n * every fifteen seconds forever would be pure waste. Hidden tabs stop the\n * timer and take one immediate reading when they come back, so a panel\n * returned to in the morning is current on the first frame.\n */\nexport function useOvernightPolling(armed: boolean, intervalMs: number = OVERNIGHT_POLL_MS): void {\n const refetch = useRefetch(overnightQuery);\n\n useEffect(() => {\n if (!armed) return;\n let timer: ReturnType<typeof setInterval> | null = null;\n\n const start = (): void => {\n if (timer !== null) return;\n timer = setInterval(refetch, intervalMs);\n };\n const stop = (): void => {\n if (timer === null) return;\n clearInterval(timer);\n timer = null;\n };\n const onVisibility = (): void => {\n if (document.visibilityState === 'hidden') {\n stop();\n return;\n }\n refetch();\n start();\n };\n\n if (document.visibilityState !== 'hidden') start();\n document.addEventListener('visibilitychange', onVisibility);\n return () => {\n stop();\n document.removeEventListener('visibilitychange', onVisibility);\n };\n }, [armed, intervalMs, refetch]);\n}\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ import"./global-y_exIyAP.js";import"./focus-trap-ChZ5EFfM.js";import"./Dialog-BRd_B9OE.js";import"./Epistemic-fycQTBRO.js";import"./StatusBadge-CXG3iNL4.js";import"./RouteErrorBoundary-C8WGiixc.js";import"./RefreshIndicator-SEFZlMB2.js";import"./VerseConsoleApp-DXDv1aOi.js";import"./Segmented-Wt1ATod9.js";import"./Tag-WSUIaMVy.js";import"./Button-DtE0rlWD.js";import"./EmptyState-DsN1H6MC.js";import"./Meter-b69LM0mU.js";import"./Slider-DaEDws-b.js";import"./Switch-BmCzfFnu.js";import"./Sheet-HkBOBMTT.js";import"./Select-By-V9lMc.js";import"./Input-CI0yBHmn.js";
@@ -1,2 +1,2 @@
1
- import{c as e}from"./global-CXHHMz9o.js";var t={key:`dashboard-snapshot`,fetch:t=>e(`/api/snapshot`,t)},n={key:`control-snapshot`,fetch:t=>e(`/api/control`,t)},r={key:`agent-os-snapshot`,fetch:t=>e(`/api/agent-os`,t)},i={key:`universe-overview`,fetch:t=>e(`/api/universe`,t)};function a(t){return{key:`universe-graph-${t}`,fetch:n=>e(`/api/universe/graph?universeId=${encodeURIComponent(t)}`,n)}}var o={key:`runs`,fetch:t=>e(`/api/runs`,t)};function s(t){return{key:`run-detail-${t}`,fetch:n=>e(`/api/run/${encodeURIComponent(t)}`,n)}}var c={key:`swarms`,fetch:t=>e(`/api/swarms`,t)};function l(t){return{key:`swarm-detail-${t}`,fetch:n=>e(`/api/swarm/${encodeURIComponent(t)}`,n)}}var u={key:`daemon`,fetch:t=>e(`/api/daemon-observation`,t)},d={key:`fleet`,fetch:t=>e(`/api/fleet`,t)},f={key:`fleet-activity`,fetch:t=>e(`/api/fleet-activity`,t)},p={key:`goals`,fetch:t=>e(`/api/goals`,t)},m={key:`vision-mission`,fetch:t=>e(`/api/vision/mission`,t)},h={key:`inbox`,fetch:t=>e(`/api/inbox`,t)};function g(t={}){let n=new URLSearchParams;t.status!==void 0&&n.set(`status`,t.status),t.since!==void 0&&n.set(`since`,t.since),t.limit!==void 0&&n.set(`limit`,String(t.limit));let r=n.toString();return{key:`inbox-list:${t.status??`pending`}:${t.since??``}:${t.limit??``}`,fetch:t=>e(`/api/inbox${r?`?${r}`:``}`,t)}}function _(t){return{key:`proposal-detail-${t}`,fetch:n=>e(`/api/inbox/${encodeURIComponent(t)}`,n)}}var v={key:`control-logs-observation`,fetch:t=>e(`/api/logs-observation?tail=200`,t)};function y(t){return{key:`pulse-${t}`,fetch:n=>e(`/api/pulse?window=${t}`,n)}}function b(e){return typeof e==`object`&&!!e&&`entry`in e&&`score`in e}function x(t){let n=t.trim();return{key:n?`genome-search-${n}`:`genome-list`,fetch:t=>e(n?`/api/genome?q=${encodeURIComponent(n)}`:`/api/genome`,t)}}function S(t){return{key:`models-${t}`,fetch:n=>e(`/api/models?window=${t}`,n)}}var C={key:`portfolio`,fetch:t=>e(`/api/portfolio`,t)};export{m as C,i as S,s as _,t as a,c as b,x as c,h as d,b as f,y as g,_ as h,u as i,p as l,C as m,v as n,f as o,S as p,n as r,d as s,r as t,g as u,o as v,a as x,l as y};
2
- //# sourceMappingURL=queries-rvRsAGW2.js.map
1
+ import{c as e}from"./global-y_exIyAP.js";var t={key:`dashboard-snapshot`,fetch:t=>e(`/api/snapshot`,t)},n={key:`control-snapshot`,fetch:t=>e(`/api/control`,t)},r={key:`agent-os-snapshot`,fetch:t=>e(`/api/agent-os`,t)},i={key:`universe-overview`,fetch:t=>e(`/api/universe`,t)};function a(t){return{key:`universe-graph-${t}`,fetch:n=>e(`/api/universe/graph?universeId=${encodeURIComponent(t)}`,n)}}var o={key:`runs`,fetch:t=>e(`/api/runs`,t)};function s(t){return{key:`run-detail-${t}`,fetch:n=>e(`/api/run/${encodeURIComponent(t)}`,n)}}var c={key:`swarms`,fetch:t=>e(`/api/swarms`,t)};function l(t){return{key:`swarm-detail-${t}`,fetch:n=>e(`/api/swarm/${encodeURIComponent(t)}`,n)}}var u={key:`daemon`,fetch:t=>e(`/api/daemon-observation`,t)},d={key:`fleet`,fetch:t=>e(`/api/fleet`,t)},f={key:`fleet-activity`,fetch:t=>e(`/api/fleet-activity`,t)},p={key:`goals`,fetch:t=>e(`/api/goals`,t)},m={key:`vision-mission`,fetch:t=>e(`/api/vision/mission`,t)},h={key:`inbox`,fetch:t=>e(`/api/inbox`,t)};function g(t={}){let n=new URLSearchParams;t.status!==void 0&&n.set(`status`,t.status),t.since!==void 0&&n.set(`since`,t.since),t.limit!==void 0&&n.set(`limit`,String(t.limit));let r=n.toString();return{key:`inbox-list:${t.status??`pending`}:${t.since??``}:${t.limit??``}`,fetch:t=>e(`/api/inbox${r?`?${r}`:``}`,t)}}function _(t){return{key:`proposal-detail-${t}`,fetch:n=>e(`/api/inbox/${encodeURIComponent(t)}`,n)}}var v={key:`control-logs-observation`,fetch:t=>e(`/api/logs-observation?tail=200`,t)};function y(t){return{key:`pulse-${t}`,fetch:n=>e(`/api/pulse?window=${t}`,n)}}function b(e){return typeof e==`object`&&!!e&&`entry`in e&&`score`in e}function x(t){let n=t.trim();return{key:n?`genome-search-${n}`:`genome-list`,fetch:t=>e(n?`/api/genome?q=${encodeURIComponent(n)}`:`/api/genome`,t)}}function S(t){return{key:`models-${t}`,fetch:n=>e(`/api/models?window=${t}`,n)}}var C={key:`portfolio`,fetch:t=>e(`/api/portfolio`,t)};export{m as C,i as S,s as _,t as a,c as b,x as c,h as d,b as f,y as g,_ as h,u as i,p as l,C as m,v as n,f as o,S as p,n as r,d as s,r as t,g as u,o as v,a as x,l as y};
2
+ //# sourceMappingURL=queries-Bw1McHTj.js.map