@ashlr/hub 3.12.0 → 3.14.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 (719) hide show
  1. package/CHANGELOG.md +157 -0
  2. package/README.md +29 -16
  3. package/dist/authority-surface.json +274 -148
  4. package/dist/build-identity.json +2 -2
  5. package/dist/cli/authority.d.ts +145 -33
  6. package/dist/cli/authority.js +1292 -315
  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/cli/comms.d.ts +33 -19
  11. package/dist/cli/comms.js +128 -151
  12. package/dist/cli/comms.js.map +1 -1
  13. package/dist/cli/completions.js +1 -1
  14. package/dist/cli/completions.js.map +1 -1
  15. package/dist/cli/daemon.js +29 -0
  16. package/dist/cli/daemon.js.map +1 -1
  17. package/dist/cli/director.d.ts +8 -12
  18. package/dist/cli/director.js +17 -52
  19. package/dist/cli/director.js.map +1 -1
  20. package/dist/cli/fleet.js +4 -1
  21. package/dist/cli/fleet.js.map +1 -1
  22. package/dist/cli/help.js +1 -0
  23. package/dist/cli/help.js.map +1 -1
  24. package/dist/cli/leader.d.ts +27 -3
  25. package/dist/cli/leader.js +253 -4
  26. package/dist/cli/leader.js.map +1 -1
  27. package/dist/core/authority/protected-paths.js +11 -0
  28. package/dist/core/authority/protected-paths.js.map +1 -1
  29. package/dist/core/authority/resident.d.ts +101 -0
  30. package/dist/core/authority/resident.js +246 -0
  31. package/dist/core/authority/resident.js.map +1 -0
  32. package/dist/core/authority/server-enforcement.d.ts +110 -0
  33. package/dist/core/authority/server-enforcement.js +260 -0
  34. package/dist/core/authority/server-enforcement.js.map +1 -0
  35. package/dist/core/authority/standing-grant.d.ts +24 -4
  36. package/dist/core/authority/standing-grant.js +19 -3
  37. package/dist/core/authority/standing-grant.js.map +1 -1
  38. package/dist/core/authority/types.d.ts +43 -0
  39. package/dist/core/authority/types.js +6 -0
  40. package/dist/core/authority/types.js.map +1 -1
  41. package/dist/core/cloud/budget.js +11 -1
  42. package/dist/core/cloud/budget.js.map +1 -1
  43. package/dist/core/cloud/cloud-api.d.ts +25 -2
  44. package/dist/core/cloud/cloud-api.js +139 -5
  45. package/dist/core/cloud/cloud-api.js.map +1 -1
  46. package/dist/core/cloud/pr-actions.d.ts +93 -0
  47. package/dist/core/cloud/pr-actions.js +436 -0
  48. package/dist/core/cloud/pr-actions.js.map +1 -0
  49. package/dist/core/cloud/pr-preview.d.ts +128 -0
  50. package/dist/core/cloud/pr-preview.js +228 -0
  51. package/dist/core/cloud/pr-preview.js.map +1 -0
  52. package/dist/core/cloud/store.d.ts +2 -0
  53. package/dist/core/cloud/store.js +28 -0
  54. package/dist/core/cloud/store.js.map +1 -1
  55. package/dist/core/cloud/timeline-api.d.ts +24 -0
  56. package/dist/core/cloud/timeline-api.js +46 -0
  57. package/dist/core/cloud/timeline-api.js.map +1 -0
  58. package/dist/core/cloud/timeline-types.d.ts +62 -0
  59. package/dist/core/cloud/timeline-types.js +36 -0
  60. package/dist/core/cloud/timeline-types.js.map +1 -0
  61. package/dist/core/cloud/timeline.d.ts +102 -0
  62. package/dist/core/cloud/timeline.js +925 -0
  63. package/dist/core/cloud/timeline.js.map +1 -0
  64. package/dist/core/cloud/tracker.js +67 -0
  65. package/dist/core/cloud/tracker.js.map +1 -1
  66. package/dist/core/cloud/types.d.ts +38 -0
  67. package/dist/core/cloud/types.js +1 -1
  68. package/dist/core/cloud/types.js.map +1 -1
  69. package/dist/core/comms/change-digest.d.ts +130 -0
  70. package/dist/core/comms/change-digest.js +451 -0
  71. package/dist/core/comms/change-digest.js.map +1 -0
  72. package/dist/core/comms/director-prompt.d.ts +4 -5
  73. package/dist/core/comms/director-prompt.js +4 -71
  74. package/dist/core/comms/director-prompt.js.map +1 -1
  75. package/dist/core/comms/director.d.ts +24 -61
  76. package/dist/core/comms/director.js +29 -382
  77. package/dist/core/comms/director.js.map +1 -1
  78. package/dist/core/comms/dispatch.d.ts +37 -12
  79. package/dist/core/comms/dispatch.js +244 -177
  80. package/dist/core/comms/dispatch.js.map +1 -1
  81. package/dist/core/comms/elon-dialogue.d.ts +23 -15
  82. package/dist/core/comms/elon-dialogue.js +36 -307
  83. package/dist/core/comms/elon-dialogue.js.map +1 -1
  84. package/dist/core/comms/fleet-pulse.js +4 -7
  85. package/dist/core/comms/fleet-pulse.js.map +1 -1
  86. package/dist/core/comms/handlers.d.ts +10 -6
  87. package/dist/core/comms/handlers.js +14 -48
  88. package/dist/core/comms/handlers.js.map +1 -1
  89. package/dist/core/comms/migrations.d.ts +47 -0
  90. package/dist/core/comms/migrations.js +125 -0
  91. package/dist/core/comms/migrations.js.map +1 -0
  92. package/dist/core/comms/requests.d.ts +32 -5
  93. package/dist/core/comms/requests.js +101 -5
  94. package/dist/core/comms/requests.js.map +1 -1
  95. package/dist/core/comms/telegram-channel.d.ts +104 -0
  96. package/dist/core/comms/telegram-channel.js +622 -0
  97. package/dist/core/comms/telegram-channel.js.map +1 -0
  98. package/dist/core/comms/telegram-thread-map.d.ts +56 -0
  99. package/dist/core/comms/telegram-thread-map.js +144 -0
  100. package/dist/core/comms/telegram-thread-map.js.map +1 -0
  101. package/dist/core/daemon/capacity-publisher.d.ts +8 -1
  102. package/dist/core/daemon/capacity-publisher.js +40 -2
  103. package/dist/core/daemon/capacity-publisher.js.map +1 -1
  104. package/dist/core/daemon/loop.js +18 -4
  105. package/dist/core/daemon/loop.js.map +1 -1
  106. package/dist/core/daemon/service-install-authority.d.ts +10 -2
  107. package/dist/core/daemon/service-install-authority.js +14 -5
  108. package/dist/core/daemon/service-install-authority.js.map +1 -1
  109. package/dist/core/daemon/service.d.ts +15 -0
  110. package/dist/core/daemon/service.js +26 -0
  111. package/dist/core/daemon/service.js.map +1 -1
  112. package/dist/core/daemon/tick-deadline.d.ts +44 -0
  113. package/dist/core/daemon/tick-deadline.js +83 -0
  114. package/dist/core/daemon/tick-deadline.js.map +1 -0
  115. package/dist/core/daemon/tick-hooks.d.ts +7 -0
  116. package/dist/core/daemon/tick-hooks.js.map +1 -1
  117. package/dist/core/daemon/tick-progress.d.ts +39 -0
  118. package/dist/core/daemon/tick-progress.js +194 -0
  119. package/dist/core/daemon/tick-progress.js.map +1 -0
  120. package/dist/core/dashboard.js +3 -1
  121. package/dist/core/dashboard.js.map +1 -1
  122. package/dist/core/fleet/cloud-intake.d.ts +95 -0
  123. package/dist/core/fleet/cloud-intake.js +557 -0
  124. package/dist/core/fleet/cloud-intake.js.map +1 -0
  125. package/dist/core/fleet/dispatch-router.d.ts +13 -0
  126. package/dist/core/fleet/dispatch-router.js +32 -8
  127. package/dist/core/fleet/dispatch-router.js.map +1 -1
  128. package/dist/core/fleet/fleet-merge-state.d.ts +16 -0
  129. package/dist/core/fleet/fleet-merge-state.js.map +1 -1
  130. package/dist/core/fleet/host-merge.d.ts +14 -0
  131. package/dist/core/fleet/host-merge.js +24 -2
  132. package/dist/core/fleet/host-merge.js.map +1 -1
  133. package/dist/core/fleet/merge-gates.d.ts +21 -0
  134. package/dist/core/fleet/merge-gates.js +39 -5
  135. package/dist/core/fleet/merge-gates.js.map +1 -1
  136. package/dist/core/fleet/mirrors.d.ts +162 -6
  137. package/dist/core/fleet/mirrors.js +1051 -49
  138. package/dist/core/fleet/mirrors.js.map +1 -1
  139. package/dist/core/fleet/standing-merge-pass.d.ts +8 -0
  140. package/dist/core/fleet/standing-merge-pass.js +102 -1
  141. package/dist/core/fleet/standing-merge-pass.js.map +1 -1
  142. package/dist/core/fleet/status.d.ts +17 -0
  143. package/dist/core/fleet/status.js +22 -0
  144. package/dist/core/fleet/status.js.map +1 -1
  145. package/dist/core/fleet/tick-hooks-live.d.ts +10 -1
  146. package/dist/core/fleet/tick-hooks-live.js +57 -8
  147. package/dist/core/fleet/tick-hooks-live.js.map +1 -1
  148. package/dist/core/fleet/verify-check-run.d.ts +90 -0
  149. package/dist/core/fleet/verify-check-run.js +274 -0
  150. package/dist/core/fleet/verify-check-run.js.map +1 -0
  151. package/dist/core/git.d.ts +17 -0
  152. package/dist/core/git.js +124 -25
  153. package/dist/core/git.js.map +1 -1
  154. package/dist/core/goals/open-goals.d.ts +47 -0
  155. package/dist/core/goals/open-goals.js +33 -0
  156. package/dist/core/goals/open-goals.js.map +1 -0
  157. package/dist/core/inbox/merge.d.ts +5 -0
  158. package/dist/core/inbox/merge.js +58 -2
  159. package/dist/core/inbox/merge.js.map +1 -1
  160. package/dist/core/integrations/locus.d.ts +28 -0
  161. package/dist/core/integrations/locus.js +155 -30
  162. package/dist/core/integrations/locus.js.map +1 -1
  163. package/dist/core/integrations/telegram-format.d.ts +40 -0
  164. package/dist/core/integrations/telegram-format.js +123 -0
  165. package/dist/core/integrations/telegram-format.js.map +1 -0
  166. package/dist/core/integrations/telegram.d.ts +60 -4
  167. package/dist/core/integrations/telegram.js +161 -28
  168. package/dist/core/integrations/telegram.js.map +1 -1
  169. package/dist/core/mcp-registry.d.ts +12 -0
  170. package/dist/core/mcp-registry.js +70 -0
  171. package/dist/core/mcp-registry.js.map +1 -1
  172. package/dist/core/observability/rollup.d.ts +12 -10
  173. package/dist/core/observability/rollup.js +44 -17
  174. package/dist/core/observability/rollup.js.map +1 -1
  175. package/dist/core/resources/connection-monitor.d.ts +9 -0
  176. package/dist/core/resources/connection-monitor.js +19 -9
  177. package/dist/core/resources/connection-monitor.js.map +1 -1
  178. package/dist/core/resources/quota-refresh-lease.d.ts +17 -0
  179. package/dist/core/resources/quota-refresh-lease.js +34 -1
  180. package/dist/core/resources/quota-refresh-lease.js.map +1 -1
  181. package/dist/core/routing/budget-api.d.ts +18 -1
  182. package/dist/core/routing/budget-api.js +120 -10
  183. package/dist/core/routing/budget-api.js.map +1 -1
  184. package/dist/core/routing/budget-store.d.ts +22 -1
  185. package/dist/core/routing/budget-store.js +22 -8
  186. package/dist/core/routing/budget-store.js.map +1 -1
  187. package/dist/core/routing/readiness-types.d.ts +82 -0
  188. package/dist/core/routing/readiness-types.js +23 -0
  189. package/dist/core/routing/readiness-types.js.map +1 -0
  190. package/dist/core/routing/readiness.d.ts +103 -0
  191. package/dist/core/routing/readiness.js +480 -0
  192. package/dist/core/routing/readiness.js.map +1 -0
  193. package/dist/core/sandbox/confine.js +22 -1
  194. package/dist/core/sandbox/confine.js.map +1 -1
  195. package/dist/core/sandbox/policy.d.ts +23 -0
  196. package/dist/core/sandbox/policy.js +100 -0
  197. package/dist/core/sandbox/policy.js.map +1 -1
  198. package/dist/core/types.d.ts +13 -0
  199. package/dist/core/types.js.map +1 -1
  200. package/dist/core/universe/builtins/preparation/manifest.json +1 -1
  201. package/dist/core/universe/builtins/preparation/preparation-bridge.mjs +1204 -939
  202. package/dist/core/universe/builtins/preparation/preparation-verification-fixtures.mjs +1319 -1054
  203. package/dist/core/usage/frontier-usage.d.ts +20 -2
  204. package/dist/core/usage/frontier-usage.js +75 -17
  205. package/dist/core/usage/frontier-usage.js.map +1 -1
  206. package/dist/core/verse/account-health.js +9 -3
  207. package/dist/core/verse/account-health.js.map +1 -1
  208. package/dist/core/verse/accounts.d.ts +45 -0
  209. package/dist/core/verse/accounts.js +246 -17
  210. package/dist/core/verse/accounts.js.map +1 -1
  211. package/dist/core/verse/activity-api.d.ts +5 -1
  212. package/dist/core/verse/activity-api.js +62 -14
  213. package/dist/core/verse/activity-api.js.map +1 -1
  214. package/dist/core/verse/apps-api.js +23 -11
  215. package/dist/core/verse/apps-api.js.map +1 -1
  216. package/dist/core/verse/apps.d.ts +11 -9
  217. package/dist/core/verse/apps.js +2 -2
  218. package/dist/core/verse/apps.js.map +1 -1
  219. package/dist/core/verse/authority-api.d.ts +17 -3
  220. package/dist/core/verse/authority-api.js +122 -7
  221. package/dist/core/verse/authority-api.js.map +1 -1
  222. package/dist/core/verse/autonomy-ladder.d.ts +172 -0
  223. package/dist/core/verse/autonomy-ladder.js +251 -0
  224. package/dist/core/verse/autonomy-ladder.js.map +1 -0
  225. package/dist/core/verse/context-fit.js +7 -5
  226. package/dist/core/verse/context-fit.js.map +1 -1
  227. package/dist/core/verse/control-api.d.ts +23 -1
  228. package/dist/core/verse/control-api.js +117 -10
  229. package/dist/core/verse/control-api.js.map +1 -1
  230. package/dist/core/verse/fleet-live-api.js +13 -5
  231. package/dist/core/verse/fleet-live-api.js.map +1 -1
  232. package/dist/core/verse/folder-io.d.ts +50 -0
  233. package/dist/core/verse/folder-io.js +142 -0
  234. package/dist/core/verse/folder-io.js.map +1 -0
  235. package/dist/core/verse/git-api.js +5 -4
  236. package/dist/core/verse/git-api.js.map +1 -1
  237. package/dist/core/verse/git-ops.d.ts +10 -1
  238. package/dist/core/verse/git-ops.js +18 -2
  239. package/dist/core/verse/git-ops.js.map +1 -1
  240. package/dist/core/verse/github-api.d.ts +1 -1
  241. package/dist/core/verse/github-api.js +5 -4
  242. package/dist/core/verse/github-api.js.map +1 -1
  243. package/dist/core/verse/github-repo.js +118 -14
  244. package/dist/core/verse/github-repo.js.map +1 -1
  245. package/dist/core/verse/leader-api.d.ts +5 -4
  246. package/dist/core/verse/leader-api.js +237 -10
  247. package/dist/core/verse/leader-api.js.map +1 -1
  248. package/dist/core/verse/local-models.d.ts +10 -0
  249. package/dist/core/verse/local-models.js +10 -1
  250. package/dist/core/verse/local-models.js.map +1 -1
  251. package/dist/core/verse/login-path.d.ts +73 -0
  252. package/dist/core/verse/login-path.js +123 -14
  253. package/dist/core/verse/login-path.js.map +1 -1
  254. package/dist/core/verse/mcp-control-api.js +4 -4
  255. package/dist/core/verse/mcp-control-api.js.map +1 -1
  256. package/dist/core/verse/mcp-scope.d.ts +22 -0
  257. package/dist/core/verse/mcp-scope.js +41 -1
  258. package/dist/core/verse/mcp-scope.js.map +1 -1
  259. package/dist/core/verse/mcp-seat-view.d.ts +10 -0
  260. package/dist/core/verse/mcp-seat-view.js +30 -4
  261. package/dist/core/verse/mcp-seat-view.js.map +1 -1
  262. package/dist/core/verse/overnight-api.js +20 -2
  263. package/dist/core/verse/overnight-api.js.map +1 -1
  264. package/dist/core/verse/path-guard.d.ts +24 -0
  265. package/dist/core/verse/path-guard.js +91 -22
  266. package/dist/core/verse/path-guard.js.map +1 -1
  267. package/dist/core/verse/preview-api.js +22 -0
  268. package/dist/core/verse/preview-api.js.map +1 -1
  269. package/dist/core/verse/projects.d.ts +21 -0
  270. package/dist/core/verse/projects.js +82 -0
  271. package/dist/core/verse/projects.js.map +1 -1
  272. package/dist/core/verse/seat-readiness.d.ts +25 -0
  273. package/dist/core/verse/seat-readiness.js +43 -6
  274. package/dist/core/verse/seat-readiness.js.map +1 -1
  275. package/dist/core/verse/session-controls-api.js +5 -3
  276. package/dist/core/verse/session-controls-api.js.map +1 -1
  277. package/dist/core/verse/session-handoff.d.ts +26 -0
  278. package/dist/core/verse/session-handoff.js +90 -12
  279. package/dist/core/verse/session-handoff.js.map +1 -1
  280. package/dist/core/verse/terminal-api.js +7 -4
  281. package/dist/core/verse/terminal-api.js.map +1 -1
  282. package/dist/core/verse/terminal.js +9 -5
  283. package/dist/core/verse/terminal.js.map +1 -1
  284. package/dist/core/verse/verse-api.d.ts +3 -1
  285. package/dist/core/verse/verse-api.js +87 -27
  286. package/dist/core/verse/verse-api.js.map +1 -1
  287. package/dist/core/verse/workspaces.d.ts +51 -0
  288. package/dist/core/verse/workspaces.js +177 -47
  289. package/dist/core/verse/workspaces.js.map +1 -1
  290. package/dist/core/vision/leader-apply.d.ts +40 -0
  291. package/dist/core/vision/leader-apply.js +101 -30
  292. package/dist/core/vision/leader-apply.js.map +1 -1
  293. package/dist/core/vision/leader-cadence.d.ts +114 -0
  294. package/dist/core/vision/leader-cadence.js +127 -0
  295. package/dist/core/vision/leader-cadence.js.map +1 -0
  296. package/dist/core/vision/leader-goal-evidence.d.ts +25 -0
  297. package/dist/core/vision/leader-goal-evidence.js +36 -0
  298. package/dist/core/vision/leader-goal-evidence.js.map +1 -0
  299. package/dist/core/vision/leader-health.d.ts +53 -0
  300. package/dist/core/vision/leader-health.js +92 -0
  301. package/dist/core/vision/leader-health.js.map +1 -0
  302. package/dist/core/vision/leader-operator.d.ts +176 -0
  303. package/dist/core/vision/leader-operator.js +355 -0
  304. package/dist/core/vision/leader-operator.js.map +1 -0
  305. package/dist/core/vision/leader-run-chain.d.ts +41 -0
  306. package/dist/core/vision/leader-run-chain.js +54 -0
  307. package/dist/core/vision/leader-run-chain.js.map +1 -0
  308. package/dist/core/vision/leader-seat-plan.d.ts +68 -0
  309. package/dist/core/vision/leader-seat-plan.js +93 -0
  310. package/dist/core/vision/leader-seat-plan.js.map +1 -0
  311. package/dist/core/vision/leader-seat.d.ts +71 -5
  312. package/dist/core/vision/leader-seat.js +235 -33
  313. package/dist/core/vision/leader-seat.js.map +1 -1
  314. package/dist/core/vision/leader-thread-types.d.ts +104 -0
  315. package/dist/core/vision/leader-thread-types.js +9 -0
  316. package/dist/core/vision/leader-thread-types.js.map +1 -0
  317. package/dist/core/vision/leader-thread.d.ts +138 -0
  318. package/dist/core/vision/leader-thread.js +926 -0
  319. package/dist/core/vision/leader-thread.js.map +1 -0
  320. package/dist/core/vision/leader-types.d.ts +75 -1
  321. package/dist/core/vision/leader.d.ts +88 -18
  322. package/dist/core/vision/leader.js +269 -69
  323. package/dist/core/vision/leader.js.map +1 -1
  324. package/dist/core/web/public/next/assets/{ActionMenu-B4-39f2S.js → ActionMenu-CIiX2X8w.js} +2 -2
  325. package/dist/core/web/public/next/assets/{ActionMenu-B4-39f2S.js.map → ActionMenu-CIiX2X8w.js.map} +1 -1
  326. package/dist/core/web/public/next/assets/Advanced-DHsysoIL.js +2 -0
  327. package/dist/core/web/public/next/assets/{Advanced-B-LqYXvd.js.map → Advanced-DHsysoIL.js.map} +1 -1
  328. package/dist/core/web/public/next/assets/App-CMeAocmW.js +7 -0
  329. package/dist/core/web/public/next/assets/{App-E2zCDRxm.js.map → App-CMeAocmW.js.map} +1 -1
  330. package/dist/core/web/public/next/assets/AppsSection-DISYnMnc.js +2 -0
  331. package/dist/core/web/public/next/assets/{AppsSection-8wXPPhZb.js.map → AppsSection-DISYnMnc.js.map} +1 -1
  332. package/dist/core/web/public/next/assets/AreaTrend-DK2Y2TbZ.js +2 -0
  333. package/dist/core/web/public/next/assets/AreaTrend-DK2Y2TbZ.js.map +1 -0
  334. package/dist/core/web/public/next/assets/AutonomyOffState-CEPSZToP.js +3 -0
  335. package/dist/core/web/public/next/assets/AutonomyOffState-CEPSZToP.js.map +1 -0
  336. package/dist/core/web/public/next/assets/AutonomyOffState-CmSSTHVe.css +1 -0
  337. package/dist/core/web/public/next/assets/AutonomySection-DWc3ciAD.js +2 -0
  338. package/dist/core/web/public/next/assets/{AutonomySection-B46igJKR.js.map → AutonomySection-DWc3ciAD.js.map} +1 -1
  339. package/dist/core/web/public/next/assets/AutonomyStatus-CYaHjJ9U.js +2 -0
  340. package/dist/core/web/public/next/assets/AutonomyStatus-CYaHjJ9U.js.map +1 -0
  341. package/dist/core/web/public/next/assets/{BranchBar-BRkrEQGs.js → BranchBar-BxhdiIpx.js} +2 -2
  342. package/dist/core/web/public/next/assets/{BranchBar-BRkrEQGs.js.map → BranchBar-BxhdiIpx.js.map} +1 -1
  343. package/dist/core/web/public/next/assets/BudgetControl-C-0KhjRS.js +2 -0
  344. package/dist/core/web/public/next/assets/BudgetControl-C-0KhjRS.js.map +1 -0
  345. package/dist/core/web/public/next/assets/{Button-BhO-WKPp.js → Button-D90dzI_o.js} +2 -2
  346. package/dist/core/web/public/next/assets/{Button-BhO-WKPp.js.map → Button-D90dzI_o.js.map} +1 -1
  347. package/dist/core/web/public/next/assets/{CapacityStrip-CkFz5vq2.js → CapacityStrip-qKDBC65C.js} +2 -2
  348. package/dist/core/web/public/next/assets/{CapacityStrip-CkFz5vq2.js.map → CapacityStrip-qKDBC65C.js.map} +1 -1
  349. package/dist/core/web/public/next/assets/ChartFrame-DY-GVUb3.js +2 -0
  350. package/dist/core/web/public/next/assets/ChartFrame-DY-GVUb3.js.map +1 -0
  351. package/dist/core/web/public/next/assets/ChartFrame-DyjmyV8N.css +1 -0
  352. package/dist/core/web/public/next/assets/ChatSection-DlT4QU6a.js +3 -0
  353. package/dist/core/web/public/next/assets/ChatSection-DlT4QU6a.js.map +1 -0
  354. package/dist/core/web/public/next/assets/{CloudBudgetForm-Bd91iStN.js → CloudBudgetForm-BrNun_Yu.js} +2 -2
  355. package/dist/core/web/public/next/assets/{CloudBudgetForm-Bd91iStN.js.map → CloudBudgetForm-BrNun_Yu.js.map} +1 -1
  356. package/dist/core/web/public/next/assets/CommandPalette-C5lDDKN0.js +2 -0
  357. package/dist/core/web/public/next/assets/CommandPalette-C5lDDKN0.js.map +1 -0
  358. package/dist/core/web/public/next/assets/CommandSection-B0xuU-yZ.css +1 -0
  359. package/dist/core/web/public/next/assets/CommandSection-DXFvPgKp.js +3 -0
  360. package/dist/core/web/public/next/assets/CommandSection-DXFvPgKp.js.map +1 -0
  361. package/dist/core/web/public/next/assets/{ConfirmDialog-Bv4hdK2T.js → ConfirmDialog-BR4nZQ2D.js} +2 -2
  362. package/dist/core/web/public/next/assets/{ConfirmDialog-Bv4hdK2T.js.map → ConfirmDialog-BR4nZQ2D.js.map} +1 -1
  363. package/dist/core/web/public/next/assets/{DeleteChatDialog-CH1Ix8Eh.js → DeleteChatDialog-BCfP12GH.js} +2 -2
  364. package/dist/core/web/public/next/assets/{DeleteChatDialog-CH1Ix8Eh.js.map → DeleteChatDialog-BCfP12GH.js.map} +1 -1
  365. package/dist/core/web/public/next/assets/{Dialog-BSsIFNqD.js → Dialog-D3msQlCj.js} +2 -2
  366. package/dist/core/web/public/next/assets/{Dialog-BSsIFNqD.js.map → Dialog-D3msQlCj.js.map} +1 -1
  367. package/dist/core/web/public/next/assets/{DiffPane-BpNuJmth.js → DiffPane-Ix6hvXlY.js} +2 -2
  368. package/dist/core/web/public/next/assets/{DiffPane-BpNuJmth.js.map → DiffPane-Ix6hvXlY.js.map} +1 -1
  369. package/dist/core/web/public/next/assets/{DiffViewer-CJarUvs0.js → DiffViewer-C4WKsCIe.js} +2 -2
  370. package/dist/core/web/public/next/assets/{DiffViewer-CJarUvs0.js.map → DiffViewer-C4WKsCIe.js.map} +1 -1
  371. package/dist/core/web/public/next/assets/DockHost-aWP7liri.js +2 -0
  372. package/dist/core/web/public/next/assets/{DockHost-DW9q0NdR.js.map → DockHost-aWP7liri.js.map} +1 -1
  373. package/dist/core/web/public/next/assets/{EmptyState-DPrd2aak.js → EmptyState-D2IRy3Cg.js} +2 -2
  374. package/dist/core/web/public/next/assets/{EmptyState-DPrd2aak.js.map → EmptyState-D2IRy3Cg.js.map} +1 -1
  375. package/dist/core/web/public/next/assets/{Epistemic-D7MxSmED.js → Epistemic-DMr18muX.js} +2 -2
  376. package/dist/core/web/public/next/assets/{Epistemic-D7MxSmED.js.map → Epistemic-DMr18muX.js.map} +1 -1
  377. package/dist/core/web/public/next/assets/EvidenceTimeline-DXmmz6Fi.js +2 -0
  378. package/dist/core/web/public/next/assets/EvidenceTimeline-DXmmz6Fi.js.map +1 -0
  379. package/dist/core/web/public/next/assets/EvidenceTimeline-PBDAiSuG.css +1 -0
  380. package/dist/core/web/public/next/assets/FleetSection-BfplcwFU.js +3 -0
  381. package/dist/core/web/public/next/assets/FleetSection-BfplcwFU.js.map +1 -0
  382. package/dist/core/web/public/next/assets/Funnel-Dh2yVHws.js +2 -0
  383. package/dist/core/web/public/next/assets/Funnel-Dh2yVHws.js.map +1 -0
  384. package/dist/core/web/public/next/assets/{GearTray-CIPtzeIx.js → GearTray-Dt-ee32-.js} +2 -2
  385. package/dist/core/web/public/next/assets/{GearTray-CIPtzeIx.js.map → GearTray-Dt-ee32-.js.map} +1 -1
  386. package/dist/core/web/public/next/assets/GrowthSection-P9EUfGeA.js +2 -0
  387. package/dist/core/web/public/next/assets/{GrowthSection-iiQg6wvK.js.map → GrowthSection-P9EUfGeA.js.map} +1 -1
  388. package/dist/core/web/public/next/assets/{HandoffDialog-DrQ6ofuy.js → HandoffDialog-CLJQLe7M.js} +2 -2
  389. package/dist/core/web/public/next/assets/{HandoffDialog-DrQ6ofuy.js.map → HandoffDialog-CLJQLe7M.js.map} +1 -1
  390. package/dist/core/web/public/next/assets/{Input-C0MQxEM6.js → Input-D_KRJA9V.js} +2 -2
  391. package/dist/core/web/public/next/assets/{Input-C0MQxEM6.js.map → Input-D_KRJA9V.js.map} +1 -1
  392. package/dist/core/web/public/next/assets/LeaderCard-D-7DlJuR.js +2 -0
  393. package/dist/core/web/public/next/assets/LeaderCard-D-7DlJuR.js.map +1 -0
  394. package/dist/core/web/public/next/assets/LeaderCard-DNsbLwY3.css +1 -0
  395. package/dist/core/web/public/next/assets/LeaderConversation-DGZjWI-E.js +2 -0
  396. package/dist/core/web/public/next/assets/LeaderConversation-DGZjWI-E.js.map +1 -0
  397. package/dist/core/web/public/next/assets/LeaderConversation-DPHUTq6W.css +1 -0
  398. package/dist/core/web/public/next/assets/MatrixHeatmap-C7BCG2d7.js +2 -0
  399. package/dist/core/web/public/next/assets/MatrixHeatmap-C7BCG2d7.js.map +1 -0
  400. package/dist/core/web/public/next/assets/McpSection-DGbRcyv8.js +2 -0
  401. package/dist/core/web/public/next/assets/{McpSection-BRuCcTjT.js.map → McpSection-DGbRcyv8.js.map} +1 -1
  402. package/dist/core/web/public/next/assets/{MessageMarkdown-bRvD5nSc.js → MessageMarkdown-DFvk06qG.js} +3 -3
  403. package/dist/core/web/public/next/assets/{MessageMarkdown-bRvD5nSc.js.map → MessageMarkdown-DFvk06qG.js.map} +1 -1
  404. package/dist/core/web/public/next/assets/{MessageMarkdownRenderer-FjjkPKA2.js → MessageMarkdownRenderer-BAv4oEUf.js} +2 -2
  405. package/dist/core/web/public/next/assets/{MessageMarkdownRenderer-FjjkPKA2.js.map → MessageMarkdownRenderer-BAv4oEUf.js.map} +1 -1
  406. package/dist/core/web/public/next/assets/{Meter-CFNLpwA-.js → Meter-CMj-VafN.js} +2 -2
  407. package/dist/core/web/public/next/assets/{Meter-CFNLpwA-.js.map → Meter-CMj-VafN.js.map} +1 -1
  408. package/dist/core/web/public/next/assets/MindSection-C6kLPIjt.js +3 -0
  409. package/dist/core/web/public/next/assets/MindSection-C6kLPIjt.js.map +1 -0
  410. package/dist/core/web/public/next/assets/{MutationTokenDialog-T7gv3a9r.js → MutationTokenDialog-DbnO8aYi.js} +2 -2
  411. package/dist/core/web/public/next/assets/{MutationTokenDialog-T7gv3a9r.js.map → MutationTokenDialog-DbnO8aYi.js.map} +1 -1
  412. package/dist/core/web/public/next/assets/NeedsYouDrawer-crsiX-Nc.js +3 -0
  413. package/dist/core/web/public/next/assets/NeedsYouDrawer-crsiX-Nc.js.map +1 -0
  414. package/dist/core/web/public/next/assets/NeedsYouList-CCsijdWt.js +2 -0
  415. package/dist/core/web/public/next/assets/{NeedsYouList-BgH8ezqf.js.map → NeedsYouList-CCsijdWt.js.map} +1 -1
  416. package/dist/core/web/public/next/assets/NeedsYouList-CH6Mq-E_.css +1 -0
  417. package/dist/core/web/public/next/assets/NewChatDialog-BlCHtOIr.js +3 -0
  418. package/dist/core/web/public/next/assets/{NewChatDialog-Db5Xjrk8.js.map → NewChatDialog-BlCHtOIr.js.map} +1 -1
  419. package/dist/core/web/public/next/assets/OnboardingFlow-Cy9BA9eR.js +3 -0
  420. package/dist/core/web/public/next/assets/OnboardingFlow-Cy9BA9eR.js.map +1 -0
  421. package/dist/core/web/public/next/assets/OnboardingGate-BXpNFoLt.js +3 -0
  422. package/dist/core/web/public/next/assets/{OnboardingGate-C4VXn7BJ.js.map → OnboardingGate-BXpNFoLt.js.map} +1 -1
  423. package/dist/core/web/public/next/assets/PreviewPane-COid5A0f.js +2 -0
  424. package/dist/core/web/public/next/assets/{PreviewPane-BPBbcROb.js.map → PreviewPane-COid5A0f.js.map} +1 -1
  425. package/dist/core/web/public/next/assets/{ProviderLogo-CT2cSfkg.js → ProviderLogo-Cq-CYIwT.js} +2 -2
  426. package/dist/core/web/public/next/assets/{ProviderLogo-CT2cSfkg.js.map → ProviderLogo-Cq-CYIwT.js.map} +1 -1
  427. package/dist/core/web/public/next/assets/{RailStatus-Vgl0GYtd.js → RailStatus-Co5UB6We.js} +2 -2
  428. package/dist/core/web/public/next/assets/{RailStatus-Vgl0GYtd.js.map → RailStatus-Co5UB6We.js.map} +1 -1
  429. package/dist/core/web/public/next/assets/{RefreshIndicator-CSyqpY_q.js → RefreshIndicator-DO9ibnSq.js} +2 -2
  430. package/dist/core/web/public/next/assets/{RefreshIndicator-CSyqpY_q.js.map → RefreshIndicator-DO9ibnSq.js.map} +1 -1
  431. package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-Dr2WRgkq.js +7 -0
  432. package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-BX2nkdmZ.js.map → ResourcePoolConsoleApp-Dr2WRgkq.js.map} +1 -1
  433. package/dist/core/web/public/next/assets/ResourcesChrome-CwMnbqI1.js +3 -0
  434. package/dist/core/web/public/next/assets/ResourcesChrome-CwMnbqI1.js.map +1 -0
  435. package/dist/core/web/public/next/assets/ResourcesDrawer-B_Xp_JNc.js +2 -0
  436. package/dist/core/web/public/next/assets/ResourcesDrawer-B_Xp_JNc.js.map +1 -0
  437. package/dist/core/web/public/next/assets/ResourcesDrawer-DrGoO8KG.css +1 -0
  438. package/dist/core/web/public/next/assets/{RouteErrorBoundary-BaC7YVzR.js → RouteErrorBoundary-SkNhhUbt.js} +2 -2
  439. package/dist/core/web/public/next/assets/{RouteErrorBoundary-BaC7YVzR.js.map → RouteErrorBoundary-SkNhhUbt.js.map} +1 -1
  440. package/dist/core/web/public/next/assets/{RunInCloudAction-D5PDHJPE.js → RunInCloudAction-BXPlZwJQ.js} +2 -2
  441. package/dist/core/web/public/next/assets/{RunInCloudAction-D5PDHJPE.js.map → RunInCloudAction-BXPlZwJQ.js.map} +1 -1
  442. package/dist/core/web/public/next/assets/{SeatSelector-Cg75LInq.js → SeatSelector-J5R3zDkB.js} +3 -3
  443. package/dist/core/web/public/next/assets/{SeatSelector-Cg75LInq.js.map → SeatSelector-J5R3zDkB.js.map} +1 -1
  444. package/dist/core/web/public/next/assets/{Segmented-CametjLt.js → Segmented-CGh_-tBb.js} +2 -2
  445. package/dist/core/web/public/next/assets/{Segmented-CametjLt.js.map → Segmented-CGh_-tBb.js.map} +1 -1
  446. package/dist/core/web/public/next/assets/{Select-De52fghU.js → Select-CWnmUzs3.js} +2 -2
  447. package/dist/core/web/public/next/assets/{Select-De52fghU.js.map → Select-CWnmUzs3.js.map} +1 -1
  448. package/dist/core/web/public/next/assets/{SessionGate-CzlcNq3O.js → SessionGate-sp4KsnUo.js} +2 -2
  449. package/dist/core/web/public/next/assets/{SessionGate-CzlcNq3O.js.map → SessionGate-sp4KsnUo.js.map} +1 -1
  450. package/dist/core/web/public/next/assets/{SessionInsightChip-Bk_Owa7u.js → SessionInsightChip-DLFAzdbi.js} +2 -2
  451. package/dist/core/web/public/next/assets/{SessionInsightChip-Bk_Owa7u.js.map → SessionInsightChip-DLFAzdbi.js.map} +1 -1
  452. package/dist/core/web/public/next/assets/{SessionSearch-C6C8DHN8.js → SessionSearch-DbFjwR1h.js} +2 -2
  453. package/dist/core/web/public/next/assets/{SessionSearch-C6C8DHN8.js.map → SessionSearch-DbFjwR1h.js.map} +1 -1
  454. package/dist/core/web/public/next/assets/{SettingsSection-mI9wQYZg.js → SettingsSection-Ch23msJ5.js} +2 -2
  455. package/dist/core/web/public/next/assets/SettingsSection-Ch23msJ5.js.map +1 -0
  456. package/dist/core/web/public/next/assets/SetupChecklist-Bd76MBAR.js +2 -0
  457. package/dist/core/web/public/next/assets/SetupChecklist-Bd76MBAR.js.map +1 -0
  458. package/dist/core/web/public/next/assets/SetupChecklist-BhZpFLsj.css +1 -0
  459. package/dist/core/web/public/next/assets/ShadowDecisions-C5RAY91f.js +3 -0
  460. package/dist/core/web/public/next/assets/ShadowDecisions-C5RAY91f.js.map +1 -0
  461. package/dist/core/web/public/next/assets/{Sheet-CJhK9Dqv.js → Sheet-BZ2AG4Eo.js} +2 -2
  462. package/dist/core/web/public/next/assets/{Sheet-CJhK9Dqv.js.map → Sheet-BZ2AG4Eo.js.map} +1 -1
  463. package/dist/core/web/public/next/assets/{ShortcutsOverlay-DDW-i9Fc.js → ShortcutsOverlay-C8n8y3zf.js} +2 -2
  464. package/dist/core/web/public/next/assets/{ShortcutsOverlay-DDW-i9Fc.js.map → ShortcutsOverlay-C8n8y3zf.js.map} +1 -1
  465. package/dist/core/web/public/next/assets/Sidebar-DN--cPYN.js +3 -0
  466. package/dist/core/web/public/next/assets/Sidebar-DN--cPYN.js.map +1 -0
  467. package/dist/core/web/public/next/assets/{Slider-Bwd9HfXl.js → Slider-KVoJLDD6.js} +2 -2
  468. package/dist/core/web/public/next/assets/{Slider-Bwd9HfXl.js.map → Slider-KVoJLDD6.js.map} +1 -1
  469. package/dist/core/web/public/next/assets/StatTile-C4KgjltA.js +2 -0
  470. package/dist/core/web/public/next/assets/StatTile-C4KgjltA.js.map +1 -0
  471. package/dist/core/web/public/next/assets/StatTile-CNCqDoPO.css +1 -0
  472. package/dist/core/web/public/next/assets/{StatusBadge-DHKRtttH.js → StatusBadge-CXsYqmdU.js} +2 -2
  473. package/dist/core/web/public/next/assets/{StatusBadge-DHKRtttH.js.map → StatusBadge-CXsYqmdU.js.map} +1 -1
  474. package/dist/core/web/public/next/assets/StepBand-BMtVOFpK.js +2 -0
  475. package/dist/core/web/public/next/assets/StepBand-BMtVOFpK.js.map +1 -0
  476. package/dist/core/web/public/next/assets/{Surface-D--LXgQm.js → Surface-BfDmQcKe.js} +2 -2
  477. package/dist/core/web/public/next/assets/{Surface-D--LXgQm.js.map → Surface-BfDmQcKe.js.map} +1 -1
  478. package/dist/core/web/public/next/assets/Swimlane-B9Exxekk.js +2 -0
  479. package/dist/core/web/public/next/assets/Swimlane-B9Exxekk.js.map +1 -0
  480. package/dist/core/web/public/next/assets/Swimlane-Bf4Rjoy9.css +1 -0
  481. package/dist/core/web/public/next/assets/{Switch-PMixU6b0.js → Switch-9NtO_6Lj.js} +2 -2
  482. package/dist/core/web/public/next/assets/{Switch-PMixU6b0.js.map → Switch-9NtO_6Lj.js.map} +1 -1
  483. package/dist/core/web/public/next/assets/{Tag-fordBsrJ.js → Tag-DscCRFcN.js} +2 -2
  484. package/dist/core/web/public/next/assets/{Tag-fordBsrJ.js.map → Tag-DscCRFcN.js.map} +1 -1
  485. package/dist/core/web/public/next/assets/{TerminalPane-BSnGdUuF.js → TerminalPane-B668-DJW.js} +5 -5
  486. package/dist/core/web/public/next/assets/{TerminalPane-BSnGdUuF.js.map → TerminalPane-B668-DJW.js.map} +1 -1
  487. package/dist/core/web/public/next/assets/UniverseConsoleApp-BUV_brY7.js +2 -0
  488. package/dist/core/web/public/next/assets/{UniverseConsoleApp-DtXFhAhw.js.map → UniverseConsoleApp-BUV_brY7.js.map} +1 -1
  489. package/dist/core/web/public/next/assets/{UniverseView-sWm3pnTW.js → UniverseView-DG70zH0W.js} +4 -4
  490. package/dist/core/web/public/next/assets/{UniverseView-sWm3pnTW.js.map → UniverseView-DG70zH0W.js.map} +1 -1
  491. package/dist/core/web/public/next/assets/UsageSection-DY7uOTm1.js +3 -0
  492. package/dist/core/web/public/next/assets/UsageSection-DY7uOTm1.js.map +1 -0
  493. package/dist/core/web/public/next/assets/VerseConsoleApp-CWU6R3By.js +3 -0
  494. package/dist/core/web/public/next/assets/VerseConsoleApp-CWU6R3By.js.map +1 -0
  495. package/dist/core/web/public/next/assets/Workspace-D1nP9BhD.js +10 -0
  496. package/dist/core/web/public/next/assets/{Workspace-BQSZFSeO.js.map → Workspace-D1nP9BhD.js.map} +1 -1
  497. package/dist/core/web/public/next/assets/actions-CY-PjpGc.js +2 -0
  498. package/dist/core/web/public/next/assets/{actions-Ci6I4C0l.js.map → actions-CY-PjpGc.js.map} +1 -1
  499. package/dist/core/web/public/next/assets/actions-DkWhhWIg.css +1 -0
  500. package/dist/core/web/public/next/assets/{apps-model-DlwnfqwJ.js → apps-model-Du02KhAf.js} +2 -2
  501. package/dist/core/web/public/next/assets/{apps-model-DlwnfqwJ.js.map → apps-model-Du02KhAf.js.map} +1 -1
  502. package/dist/core/web/public/next/assets/{authority-model-BFuPezSo.js → authority-model-79SeuKlJ.js} +2 -2
  503. package/dist/core/web/public/next/assets/{authority-model-BFuPezSo.js.map → authority-model-79SeuKlJ.js.map} +1 -1
  504. package/dist/core/web/public/next/assets/autonomy-ladder-BGWmZzP7.css +1 -0
  505. package/dist/core/web/public/next/assets/autonomy-ladder.module-ArDv4bkr.js +2 -0
  506. package/dist/core/web/public/next/assets/autonomy-ladder.module-ArDv4bkr.js.map +1 -0
  507. package/dist/core/web/public/next/assets/budget-queries-D8QV5XtH.js +2 -0
  508. package/dist/core/web/public/next/assets/{budget-queries-DsAjH8ac.js.map → budget-queries-D8QV5XtH.js.map} +1 -1
  509. package/dist/core/web/public/next/assets/{capacity-strip-model-Dn1cNOhz.js → capacity-strip-model-BwZ1ZbkU.js} +2 -2
  510. package/dist/core/web/public/next/assets/{capacity-strip-model-Dn1cNOhz.js.map → capacity-strip-model-BwZ1ZbkU.js.map} +1 -1
  511. package/dist/core/web/public/next/assets/charts-BZ50mZD_.js +2 -0
  512. package/dist/core/web/public/next/assets/charts-BZ50mZD_.js.map +1 -0
  513. package/dist/core/web/public/next/assets/charts-ClCB18la.css +1 -0
  514. package/dist/core/web/public/next/assets/cloud-model-BDivRMqv.js +2 -0
  515. package/dist/core/web/public/next/assets/{cloud-model-CX407gPY.js.map → cloud-model-BDivRMqv.js.map} +1 -1
  516. package/dist/core/web/public/next/assets/{cloud-queries-QAhpExlz.js → cloud-queries-BPQQ5_pJ.js} +2 -2
  517. package/dist/core/web/public/next/assets/{cloud-queries-QAhpExlz.js.map → cloud-queries-BPQQ5_pJ.js.map} +1 -1
  518. package/dist/core/web/public/next/assets/{colors-BZ3a9wFf.js → colors-DvK0wMHH.js} +2 -2
  519. package/dist/core/web/public/next/assets/{colors-BZ3a9wFf.js.map → colors-DvK0wMHH.js.map} +1 -1
  520. package/dist/core/web/public/next/assets/{command-catalog-CF0cQQac.js → command-catalog-BIntSa9l.js} +2 -2
  521. package/dist/core/web/public/next/assets/command-catalog-BIntSa9l.js.map +1 -0
  522. package/dist/core/web/public/next/assets/{context-model-Co4wh3SM.js → context-model-Br8t9jgG.js} +2 -2
  523. package/dist/core/web/public/next/assets/{context-model-Co4wh3SM.js.map → context-model-Br8t9jgG.js.map} +1 -1
  524. package/dist/core/web/public/next/assets/{context-model-DV1zCfAm.js → context-model-CokrgEUq.js} +3 -3
  525. package/dist/core/web/public/next/assets/{context-model-DV1zCfAm.js.map → context-model-CokrgEUq.js.map} +1 -1
  526. package/dist/core/web/public/next/assets/context-queries-eL3caKVG.js +2 -0
  527. package/dist/core/web/public/next/assets/{context-queries-CktFQqSS.js.map → context-queries-eL3caKVG.js.map} +1 -1
  528. package/dist/core/web/public/next/assets/{control-queries-DAvlh_YM.js → control-queries-B9K-wmcB.js} +2 -2
  529. package/dist/core/web/public/next/assets/{control-queries-DAvlh_YM.js.map → control-queries-B9K-wmcB.js.map} +1 -1
  530. package/dist/core/web/public/next/assets/copy-setup-XMgCC5f8.js +2 -0
  531. package/dist/core/web/public/next/assets/copy-setup-XMgCC5f8.js.map +1 -0
  532. package/dist/core/web/public/next/assets/{dock-icons-BFuBbqJl.js → dock-icons-BJ6ZqB2t.js} +2 -2
  533. package/dist/core/web/public/next/assets/{dock-icons-BFuBbqJl.js.map → dock-icons-BJ6ZqB2t.js.map} +1 -1
  534. package/dist/core/web/public/next/assets/{fleet-model-Dfd5JyLR.js → fleet-model-BvDR3gjp.js} +2 -2
  535. package/dist/core/web/public/next/assets/{fleet-model-Dfd5JyLR.js.map → fleet-model-BvDR3gjp.js.map} +1 -1
  536. package/dist/core/web/public/next/assets/{fleet-queries-RtMTd5rR.js → fleet-queries-W2UFVMZJ.js} +2 -2
  537. package/dist/core/web/public/next/assets/{fleet-queries-RtMTd5rR.js.map → fleet-queries-W2UFVMZJ.js.map} +1 -1
  538. package/dist/core/web/public/next/assets/{focus-trap-BdrbWfC4.js → focus-trap-CtI1SlMX.js} +2 -2
  539. package/dist/core/web/public/next/assets/{focus-trap-BdrbWfC4.js.map → focus-trap-CtI1SlMX.js.map} +1 -1
  540. package/dist/core/web/public/next/assets/format-CH4g_sl1.js +2 -0
  541. package/dist/core/web/public/next/assets/format-CH4g_sl1.js.map +1 -0
  542. package/dist/core/web/public/next/assets/{format-DKrNjdwD.js → format-D7nBg2bn.js} +2 -2
  543. package/dist/core/web/public/next/assets/{format-DKrNjdwD.js.map → format-D7nBg2bn.js.map} +1 -1
  544. package/dist/core/web/public/next/assets/{git-model-_BnI_Ogh.js → git-model-Dnkd1TnK.js} +2 -2
  545. package/dist/core/web/public/next/assets/{git-model-_BnI_Ogh.js.map → git-model-Dnkd1TnK.js.map} +1 -1
  546. package/dist/core/web/public/next/assets/global-CMNW_dqn.js +2 -0
  547. package/dist/core/web/public/next/assets/{global-CNNGMril.js.map → global-CMNW_dqn.js.map} +1 -1
  548. package/dist/core/web/public/next/assets/guarded-runners-YeAc9wLQ.js +2 -0
  549. package/dist/core/web/public/next/assets/{guarded-runners-DPh2d32e.js.map → guarded-runners-YeAc9wLQ.js.map} +1 -1
  550. package/dist/core/web/public/next/assets/{icons-0haWy6nh.js → icons-D1sYbCTQ.js} +2 -2
  551. package/dist/core/web/public/next/assets/{icons-0haWy6nh.js.map → icons-D1sYbCTQ.js.map} +1 -1
  552. package/dist/core/web/public/next/assets/{index-QesfXBsb.js → index-DZ-UQ7v8.js} +3 -3
  553. package/dist/core/web/public/next/assets/{index-QesfXBsb.js.map → index-DZ-UQ7v8.js.map} +1 -1
  554. package/dist/core/web/public/next/assets/leader-focus-BjeJv7CW.js +2 -0
  555. package/dist/core/web/public/next/assets/leader-focus-BjeJv7CW.js.map +1 -0
  556. package/dist/core/web/public/next/assets/leader-thread-types-CDb-VPPO.js +2 -0
  557. package/dist/core/web/public/next/assets/leader-thread-types-CDb-VPPO.js.map +1 -0
  558. package/dist/core/web/public/next/assets/{live-model-De-q0ZFK.js → live-model-D_32RAOR.js} +2 -2
  559. package/dist/core/web/public/next/assets/live-model-D_32RAOR.js.map +1 -0
  560. package/dist/core/web/public/next/assets/{mind.module-BrK2nFOL.js → mind.module-7hA92hRg.js} +2 -2
  561. package/dist/core/web/public/next/assets/{mind.module-BrK2nFOL.js.map → mind.module-7hA92hRg.js.map} +1 -1
  562. package/dist/core/web/public/next/assets/mutations-DQPbFdRJ.js +2 -0
  563. package/dist/core/web/public/next/assets/{mutations-DTCtKCn_.js.map → mutations-DQPbFdRJ.js.map} +1 -1
  564. package/dist/core/web/public/next/assets/{nav-KmGX0CVz.js → nav-0dOYe2rJ.js} +2 -2
  565. package/dist/core/web/public/next/assets/{nav-KmGX0CVz.js.map → nav-0dOYe2rJ.js.map} +1 -1
  566. package/dist/core/web/public/next/assets/{overnight-queries-mlO0xzsr.js → overnight-queries-C4wOnFtE.js} +2 -2
  567. package/dist/core/web/public/next/assets/{overnight-queries-mlO0xzsr.js.map → overnight-queries-C4wOnFtE.js.map} +1 -1
  568. package/dist/core/web/public/next/assets/primitives-2A5Eq8FQ.js +1 -0
  569. package/dist/core/web/public/next/assets/{queries-CyBE8nsW.js → queries-BTXWdZzU.js} +2 -2
  570. package/dist/core/web/public/next/assets/{queries-CyBE8nsW.js.map → queries-BTXWdZzU.js.map} +1 -1
  571. package/dist/core/web/public/next/assets/{reasoning-pref-CaoA4_Vl.js → reasoning-pref-Ca6lN6x_.js} +2 -2
  572. package/dist/core/web/public/next/assets/{reasoning-pref-CaoA4_Vl.js.map → reasoning-pref-Ca6lN6x_.js.map} +1 -1
  573. package/dist/core/web/public/next/assets/{reveal-anchor-BP1VqnPU.js → reveal-anchor-DfNLgK_I.js} +2 -2
  574. package/dist/core/web/public/next/assets/{reveal-anchor-BP1VqnPU.js.map → reveal-anchor-DfNLgK_I.js.map} +1 -1
  575. package/dist/core/web/public/next/assets/seat-subscription-C5uPHBsN.js +2 -0
  576. package/dist/core/web/public/next/assets/{seat-subscription-C5Tvr0WQ.js.map → seat-subscription-C5uPHBsN.js.map} +1 -1
  577. package/dist/core/web/public/next/assets/{sidebar-model-B5Qk95k_.js → sidebar-model-CLCdqwkR.js} +2 -2
  578. package/dist/core/web/public/next/assets/{sidebar-model-B5Qk95k_.js.map → sidebar-model-CLCdqwkR.js.map} +1 -1
  579. package/dist/core/web/public/next/assets/{slots-DHKQDoE6.js → slots-C-qBeu-8.js} +3 -3
  580. package/dist/core/web/public/next/assets/{slots-DHKQDoE6.js.map → slots-C-qBeu-8.js.map} +1 -1
  581. package/dist/core/web/public/next/assets/{surface-data-CchClvHo.js → surface-data-Dj71tdD-.js} +2 -2
  582. package/dist/core/web/public/next/assets/{surface-data-CchClvHo.js.map → surface-data-Dj71tdD-.js.map} +1 -1
  583. package/dist/core/web/public/next/assets/surface-prefetch-B0WdJOJG.js +2 -0
  584. package/dist/core/web/public/next/assets/surface-prefetch-B0WdJOJG.js.map +1 -0
  585. package/dist/core/web/public/next/assets/{tasks-model-D6WFVULI.js → tasks-model-O8yR5YXp.js} +2 -2
  586. package/dist/core/web/public/next/assets/{tasks-model-D6WFVULI.js.map → tasks-model-O8yR5YXp.js.map} +1 -1
  587. package/dist/core/web/public/next/assets/{terminal-icons-BvCvuXk2.js → terminal-icons-CoRZq9iO.js} +2 -2
  588. package/dist/core/web/public/next/assets/{terminal-icons-BvCvuXk2.js.map → terminal-icons-CoRZq9iO.js.map} +1 -1
  589. package/dist/core/web/public/next/assets/thread-data-DQB_g66d.js +2 -0
  590. package/dist/core/web/public/next/assets/thread-data-DQB_g66d.js.map +1 -0
  591. package/dist/core/web/public/next/assets/types-IYKrYLku.js +2 -0
  592. package/dist/core/web/public/next/assets/types-IYKrYLku.js.map +1 -0
  593. package/dist/core/web/public/next/assets/{usage-queries-D1SU1t7r.js → usage-queries-AdjEyEtn.js} +2 -2
  594. package/dist/core/web/public/next/assets/{usage-queries-D1SU1t7r.js.map → usage-queries-AdjEyEtn.js.map} +1 -1
  595. package/dist/core/web/public/next/assets/{use-guarded-action-BZmBv7CJ.js → use-guarded-action-CuuMHeDX.js} +2 -2
  596. package/dist/core/web/public/next/assets/{use-guarded-action-BZmBv7CJ.js.map → use-guarded-action-CuuMHeDX.js.map} +1 -1
  597. package/dist/core/web/public/next/assets/{use-ticker-CkJ4-0wU.js → use-ticker-BBcp02SZ.js} +2 -2
  598. package/dist/core/web/public/next/assets/{use-ticker-CkJ4-0wU.js.map → use-ticker-BBcp02SZ.js.map} +1 -1
  599. package/dist/core/web/public/next/assets/{use-token-gate-CYcfk_GS.js → use-token-gate-CbXVYQYI.js} +2 -2
  600. package/dist/core/web/public/next/assets/{use-token-gate-CYcfk_GS.js.map → use-token-gate-CbXVYQYI.js.map} +1 -1
  601. package/dist/core/web/public/next/assets/{useOnboarding-CujRS6PK.js → useOnboarding-C_Fpe_sH.js} +2 -2
  602. package/dist/core/web/public/next/assets/{useOnboarding-CujRS6PK.js.map → useOnboarding-C_Fpe_sH.js.map} +1 -1
  603. package/dist/core/web/public/next/assets/{useSeatsRefresh-BEaQdkZs.js → useSeatsRefresh-Co1CnxLc.js} +2 -2
  604. package/dist/core/web/public/next/assets/{useSeatsRefresh-BEaQdkZs.js.map → useSeatsRefresh-Co1CnxLc.js.map} +1 -1
  605. package/dist/core/web/public/next/assets/{useVerseTranscript-BQ0J6Xhx.js → useVerseTranscript-DgbigUlV.js} +2 -2
  606. package/dist/core/web/public/next/assets/{useVerseTranscript-BQ0J6Xhx.js.map → useVerseTranscript-DgbigUlV.js.map} +1 -1
  607. package/dist/core/web/public/next/assets/{verse-icons-DndgEgKS.js → verse-icons-S56hIiXS.js} +2 -2
  608. package/dist/core/web/public/next/assets/{verse-icons-DndgEgKS.js.map → verse-icons-S56hIiXS.js.map} +1 -1
  609. package/dist/core/web/public/next/assets/verse-model-DAVevkNe.js +2 -0
  610. package/dist/core/web/public/next/assets/{verse-model-MMySehjj.js.map → verse-model-DAVevkNe.js.map} +1 -1
  611. package/dist/core/web/public/next/assets/{warmup-CNEH_-be.js → warmup-B_RAtNZ_.js} +3 -3
  612. package/dist/core/web/public/next/assets/{warmup-CNEH_-be.js.map → warmup-B_RAtNZ_.js.map} +1 -1
  613. package/dist/core/web/public/next/assets/why-seat-model-M_r0wX3b.js +2 -0
  614. package/dist/core/web/public/next/assets/why-seat-model-M_r0wX3b.js.map +1 -0
  615. package/dist/core/web/public/next/assets/{workspace-model-Dukb2wwv.js → workspace-model-dji5-Al3.js} +2 -2
  616. package/dist/core/web/public/next/assets/{workspace-model-Dukb2wwv.js.map → workspace-model-dji5-Al3.js.map} +1 -1
  617. package/dist/core/web/public/next/index.html +1 -1
  618. package/dist/core/web/read-projection-worker.js +2 -1
  619. package/dist/core/web/read-projection-worker.js.map +1 -1
  620. package/dist/core/web/read-projections.d.ts +3 -0
  621. package/dist/core/web/read-projections.js +2 -2
  622. package/dist/core/web/read-projections.js.map +1 -1
  623. package/dist/core/web/visibility.js +3 -4
  624. package/dist/core/web/visibility.js.map +1 -1
  625. package/dist/release-dependency-inventory.json +1 -1
  626. package/docs/AUTONOMY-GAP.md +1 -1
  627. package/package.json +3 -2
  628. package/dist/core/web/public/next/assets/Advanced-B-LqYXvd.js +0 -2
  629. package/dist/core/web/public/next/assets/App-E2zCDRxm.js +0 -7
  630. package/dist/core/web/public/next/assets/AppsSection-8wXPPhZb.js +0 -2
  631. package/dist/core/web/public/next/assets/AreaTrend-BFimExYn.js +0 -2
  632. package/dist/core/web/public/next/assets/AreaTrend-BFimExYn.js.map +0 -1
  633. package/dist/core/web/public/next/assets/AutonomyOffState-B5eEkmiz.js +0 -2
  634. package/dist/core/web/public/next/assets/AutonomyOffState-B5eEkmiz.js.map +0 -1
  635. package/dist/core/web/public/next/assets/AutonomyOffState-DmbE71vI.css +0 -1
  636. package/dist/core/web/public/next/assets/AutonomySection-B46igJKR.js +0 -2
  637. package/dist/core/web/public/next/assets/BudgetControl-T_RjPrw9.js +0 -2
  638. package/dist/core/web/public/next/assets/BudgetControl-T_RjPrw9.js.map +0 -1
  639. package/dist/core/web/public/next/assets/ChartFrame-BVuBe6RP.css +0 -1
  640. package/dist/core/web/public/next/assets/ChartFrame-SygZ7B3x.js +0 -2
  641. package/dist/core/web/public/next/assets/ChartFrame-SygZ7B3x.js.map +0 -1
  642. package/dist/core/web/public/next/assets/ChatSection-D6WybBpB.js +0 -3
  643. package/dist/core/web/public/next/assets/ChatSection-D6WybBpB.js.map +0 -1
  644. package/dist/core/web/public/next/assets/CommandPalette-B6SgDJH-.js +0 -2
  645. package/dist/core/web/public/next/assets/CommandPalette-B6SgDJH-.js.map +0 -1
  646. package/dist/core/web/public/next/assets/CommandSection-CvAVd1w4.css +0 -1
  647. package/dist/core/web/public/next/assets/CommandSection-DgMGoepd.js +0 -2
  648. package/dist/core/web/public/next/assets/CommandSection-DgMGoepd.js.map +0 -1
  649. package/dist/core/web/public/next/assets/DockHost-DW9q0NdR.js +0 -2
  650. package/dist/core/web/public/next/assets/FleetSection-BdZN6rGS.js +0 -3
  651. package/dist/core/web/public/next/assets/FleetSection-BdZN6rGS.js.map +0 -1
  652. package/dist/core/web/public/next/assets/Funnel-BeNQZWv2.js +0 -2
  653. package/dist/core/web/public/next/assets/Funnel-BeNQZWv2.js.map +0 -1
  654. package/dist/core/web/public/next/assets/GrowthSection-iiQg6wvK.js +0 -2
  655. package/dist/core/web/public/next/assets/LeaderCard-BRr3_yE-.js +0 -2
  656. package/dist/core/web/public/next/assets/LeaderCard-BRr3_yE-.js.map +0 -1
  657. package/dist/core/web/public/next/assets/MatrixHeatmap-DZvZeWXL.js +0 -2
  658. package/dist/core/web/public/next/assets/MatrixHeatmap-DZvZeWXL.js.map +0 -1
  659. package/dist/core/web/public/next/assets/McpSection-BRuCcTjT.js +0 -2
  660. package/dist/core/web/public/next/assets/MindSection-BTIiQS8P.js +0 -2
  661. package/dist/core/web/public/next/assets/MindSection-BTIiQS8P.js.map +0 -1
  662. package/dist/core/web/public/next/assets/NeedsYouDrawer-lYN4G_aM.js +0 -2
  663. package/dist/core/web/public/next/assets/NeedsYouDrawer-lYN4G_aM.js.map +0 -1
  664. package/dist/core/web/public/next/assets/NeedsYouList-BgH8ezqf.js +0 -2
  665. package/dist/core/web/public/next/assets/NeedsYouList-CruOt4JT.css +0 -1
  666. package/dist/core/web/public/next/assets/NewChatDialog-Db5Xjrk8.js +0 -3
  667. package/dist/core/web/public/next/assets/OnboardingFlow-LoY-zuSe.js +0 -2
  668. package/dist/core/web/public/next/assets/OnboardingFlow-LoY-zuSe.js.map +0 -1
  669. package/dist/core/web/public/next/assets/OnboardingGate-C4VXn7BJ.js +0 -3
  670. package/dist/core/web/public/next/assets/PreviewPane-BPBbcROb.js +0 -2
  671. package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-BX2nkdmZ.js +0 -7
  672. package/dist/core/web/public/next/assets/ResourcesChrome-B2U2lO1H.js +0 -3
  673. package/dist/core/web/public/next/assets/ResourcesChrome-B2U2lO1H.js.map +0 -1
  674. package/dist/core/web/public/next/assets/ResourcesDrawer-BCFJ2Uq8.css +0 -1
  675. package/dist/core/web/public/next/assets/ResourcesDrawer-DlUKOjl9.js +0 -2
  676. package/dist/core/web/public/next/assets/ResourcesDrawer-DlUKOjl9.js.map +0 -1
  677. package/dist/core/web/public/next/assets/SettingsSection-mI9wQYZg.js.map +0 -1
  678. package/dist/core/web/public/next/assets/Sidebar-DT7ykaqS.js +0 -3
  679. package/dist/core/web/public/next/assets/Sidebar-DT7ykaqS.js.map +0 -1
  680. package/dist/core/web/public/next/assets/StatTile-BuLMsJMx.css +0 -1
  681. package/dist/core/web/public/next/assets/StatTile-DPZ5yyaU.js +0 -2
  682. package/dist/core/web/public/next/assets/StatTile-DPZ5yyaU.js.map +0 -1
  683. package/dist/core/web/public/next/assets/StepBand-DQykLkk_.js +0 -2
  684. package/dist/core/web/public/next/assets/StepBand-DQykLkk_.js.map +0 -1
  685. package/dist/core/web/public/next/assets/Swimlane-BzH6OCee.js +0 -2
  686. package/dist/core/web/public/next/assets/Swimlane-BzH6OCee.js.map +0 -1
  687. package/dist/core/web/public/next/assets/Swimlane-o6_Zsrnr.css +0 -1
  688. package/dist/core/web/public/next/assets/UniverseConsoleApp-DtXFhAhw.js +0 -2
  689. package/dist/core/web/public/next/assets/UsageSection-CiD1DbuF.js +0 -3
  690. package/dist/core/web/public/next/assets/UsageSection-CiD1DbuF.js.map +0 -1
  691. package/dist/core/web/public/next/assets/VerseConsoleApp-BCY5uSok.js +0 -3
  692. package/dist/core/web/public/next/assets/VerseConsoleApp-BCY5uSok.js.map +0 -1
  693. package/dist/core/web/public/next/assets/Workspace-BQSZFSeO.js +0 -10
  694. package/dist/core/web/public/next/assets/actions-BmIf9avl.css +0 -1
  695. package/dist/core/web/public/next/assets/actions-Ci6I4C0l.js +0 -2
  696. package/dist/core/web/public/next/assets/budget-queries-DsAjH8ac.js +0 -2
  697. package/dist/core/web/public/next/assets/charts-C_xJbJiw.js +0 -2
  698. package/dist/core/web/public/next/assets/charts-C_xJbJiw.js.map +0 -1
  699. package/dist/core/web/public/next/assets/charts-DhKTrQLw.css +0 -1
  700. package/dist/core/web/public/next/assets/cloud-model-CX407gPY.js +0 -2
  701. package/dist/core/web/public/next/assets/command-catalog-CF0cQQac.js.map +0 -1
  702. package/dist/core/web/public/next/assets/context-queries-CktFQqSS.js +0 -2
  703. package/dist/core/web/public/next/assets/copy-setup-CqRSfELB.js +0 -2
  704. package/dist/core/web/public/next/assets/copy-setup-CqRSfELB.js.map +0 -1
  705. package/dist/core/web/public/next/assets/format-Dk4Fmxax.js +0 -2
  706. package/dist/core/web/public/next/assets/format-Dk4Fmxax.js.map +0 -1
  707. package/dist/core/web/public/next/assets/global-CNNGMril.js +0 -2
  708. package/dist/core/web/public/next/assets/guarded-runners-DPh2d32e.js +0 -2
  709. package/dist/core/web/public/next/assets/live-model-De-q0ZFK.js.map +0 -1
  710. package/dist/core/web/public/next/assets/mutations-DTCtKCn_.js +0 -2
  711. package/dist/core/web/public/next/assets/primitives-D0Fb3TtS.js +0 -1
  712. package/dist/core/web/public/next/assets/seat-subscription-C5Tvr0WQ.js +0 -2
  713. package/dist/core/web/public/next/assets/surface-prefetch-BWr0LBQn.js +0 -2
  714. package/dist/core/web/public/next/assets/surface-prefetch-BWr0LBQn.js.map +0 -1
  715. package/dist/core/web/public/next/assets/types-D5XOdyw8.js +0 -2
  716. package/dist/core/web/public/next/assets/types-D5XOdyw8.js.map +0 -1
  717. package/dist/core/web/public/next/assets/verse-model-MMySehjj.js +0 -2
  718. package/dist/core/web/public/next/assets/why-seat-model-jlDTwYSc.js +0 -2
  719. package/dist/core/web/public/next/assets/why-seat-model-jlDTwYSc.js.map +0 -1
@@ -0,0 +1,2 @@
1
+ import{a as e,c as t,n}from"./index-DZ-UQ7v8.js";import{t as r}from"./Dialog-D3msQlCj.js";import{t as i}from"./MutationTokenDialog-DbnO8aYi.js";import{t as a}from"./Button-D90dzI_o.js";import{n as o}from"./use-guarded-action-CuuMHeDX.js";var s=t(e(),1),c={lead:`_lead_1clua_8`,bar:`_bar_1clua_14`,barSpacer:`_barSpacer_1clua_22`,barSecondary:`_barSecondary_1clua_26`,switchWrap:`_switchWrap_1clua_32`,barLabel:`_barLabel_1clua_38`,pillLabel:`_pillLabel_1clua_39`,switchOption:`_switchOption_1clua_48`,touchMark:`_touchMark_1clua_54`,pill:`_pill_1clua_39`,chip:`_chip_1clua_59`,linkButton:`_linkButton_1clua_88`,moreLink:`_moreLink_1clua_89`,dot:`_dot_1clua_103`,verdict:`_verdict_1clua_126`,verdictPart:`_verdictPart_1clua_135`,verdictSep:`_verdictSep_1clua_149`,since:`_since_1clua_153`,sinceLead:`_sinceLead_1clua_162`,sinceChip:`_sinceChip_1clua_166`,actionNote:`_actionNote_1clua_192`,actionError:`_actionError_1clua_193`,kbd:`_kbd_1clua_247`,muted:`_muted_1clua_256`,mono:`_mono_1clua_263`,num:`_num_1clua_268`,confirmBody:`_confirmBody_1clua_273`,confirmActions:`_confirmActions_1clua_279`,needsList:`_needsList_1clua_287`,needsRow:`_needsRow_1clua_295`,sevDot:`_sevDot_1clua_309`,needsText:`_needsText_1clua_323`,needsKind:`_needsKind_1clua_331`,needsTitle:`_needsTitle_1clua_343`,needsDetail:`_needsDetail_1clua_355`,needsMeta:`_needsMeta_1clua_363`,needsRepo:`_needsRepo_1clua_372`,needsActions:`_needsActions_1clua_376`,allClear:`_allClear_1clua_384`,allClearTitle:`_allClearTitle_1clua_391`,allClearBody:`_allClearBody_1clua_399`,memo:`_memo_1clua_405`,memoRow:`_memoRow_1clua_412`,memoText:`_memoText_1clua_423`,delta:`_delta_1clua_429`,dryRun:`_dryRun_1clua_442`,actionList:`_actionList_1clua_454`,actionRow:`_actionRow_1clua_463`,actionSummary:`_actionSummary_1clua_472`,classBadge:`_classBadge_1clua_477`,actionText:`_actionText_1clua_500`,actionWhy:`_actionWhy_1clua_513`,actionState:`_actionState_1clua_520`,statusWord:`_statusWord_1clua_526`,vetoChip:`_vetoChip_1clua_541`,ring:`_ring_1clua_545`,ringTrack:`_ringTrack_1clua_555`,ringFill:`_ringFill_1clua_561`,ringText:`_ringText_1clua_568`,kpis:`_kpis_1clua_573`,burnGrid:`_burnGrid_1clua_602`,burnStrip:`_burnStrip_1clua_610`,burnItem:`_burnItem_1clua_621`,freeSeat:`_freeSeat_1clua_629`,freeHead:`_freeHead_1clua_639`,freeTitle:`_freeTitle_1clua_645`,freeValue:`_freeValue_1clua_652`,freeBody:`_freeBody_1clua_659`,scope:`_scope_1clua_666`,scopeBlock:`_scopeBlock_1clua_672`,scopeLead:`_scopeLead_1clua_678`,scopeMeta:`_scopeMeta_1clua_685`,scopeTable:`_scopeTable_1clua_692`,scopeList:`_scopeList_1clua_712`,ladder:`_ladder_1clua_720`,ladderId:`_ladderId_1clua_739`,sheetFooter:`_sheetFooter_1clua_744`,sheetFootnote:`_sheetFootnote_1clua_750`,sheetButtons:`_sheetButtons_1clua_757`,autonomyPlaceholder:`_autonomyPlaceholder_1clua_771`},l=n();function u({spec:e,onConfirm:t,onCancel:n}){let i=(0,s.useId)(),o=(0,s.useRef)(null),u=(0,s.useRef)(null);return(0,l.jsxs)(r,{open:e!==null,onClose:n,titleId:i,title:e?.title??``,initialFocusRef:e?.destructive?o:u,children:[(0,l.jsx)(`div`,{className:c.confirmBody,children:e?.body}),(0,l.jsxs)(`div`,{className:c.confirmActions,children:[(0,l.jsx)(a,{ref:o,variant:`ghost`,onClick:n,children:`Cancel`}),(0,l.jsx)(a,{ref:u,variant:e?.destructive?`danger`:`primary`,onClick:t,children:e?.confirmLabel??`Confirm`})]})]})}function d(){let e=o(),[t,n]=(0,s.useState)(null),{request:r}=e,a=(0,s.useCallback)((e,t,i={})=>{let a=()=>r(e,t,i.onDone);i.confirm?n({spec:i.confirm,run:a}):a()},[r]),c=(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(u,{spec:t?.spec??null,onCancel:()=>n(null),onConfirm:()=>{let e=t;n(null),e?.run()}}),(0,l.jsx)(i,{open:e.tokenOpen,onClose:e.closeToken,reason:e.tokenReason,tokenHelp:`the mutation token ashlr verse printed`})]});return{act:a,busy:e.busy,error:e.error,clearError:e.clearError,readOnly:e.readOnly,dialogs:c}}function f({actions:e}){return e.readOnly?(0,l.jsx)(`p`,{className:c.actionNote,role:`status`,children:`Read-only session: this server was started without dispatch, so switching, stopping and vetoing are unavailable. Everything shown is live.`}):e.error?(0,l.jsxs)(`p`,{className:c.actionError,role:`alert`,children:[e.error,(0,l.jsx)(`button`,{type:`button`,className:c.linkButton,onClick:e.clearError,children:`Dismiss`})]}):null}export{d as n,c as r,f as t};
2
+ //# sourceMappingURL=actions-CY-PjpGc.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"actions-Ci6I4C0l.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/command/command.module.css","../../../../../../src/web-ui/routes/verse/command/actions.tsx"],"sourcesContent":["/*\n * routes/verse/command/command.module.css — Command's cards and top bar\n * (unit C7). Tokens only: style-scan-310 bans raw hex colours and px font\n * sizes in this folder, and every colour here follows the theme.\n */\n\n/* ---- lead: top bar, verdict, since ------------------------------------ */\n.lead {\n display: flex;\n flex-direction: column;\n gap: var(--space-3);\n}\n\n.bar {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: var(--space-2) var(--space-3);\n min-height: var(--control-h);\n}\n\n.barSpacer {\n flex: 1;\n}\n\n.barSecondary {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-2);\n}\n\n.switchWrap {\n display: inline-flex;\n align-items: center;\n gap: var(--space-2);\n}\n\n.barLabel,\n.pillLabel {\n font-family: var(--font-display);\n font-size: var(--text-2xs-size);\n line-height: var(--text-2xs-line);\n letter-spacing: var(--tracking-label);\n text-transform: uppercase;\n color: var(--text-tertiary);\n}\n\n.switchOption {\n display: inline-flex;\n align-items: center;\n gap: var(--space-1);\n}\n\n.touchMark {\n color: var(--text-tertiary);\n}\n\n.pill,\n.chip {\n display: inline-flex;\n align-items: center;\n gap: var(--space-2);\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-full);\n background: var(--bg-surface);\n color: var(--text-primary);\n font-family: var(--font-ui);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n white-space: nowrap;\n}\n\nbutton.pill,\nbutton.chip {\n cursor: pointer;\n transition: background-color var(--duration-fast) var(--ease-standard);\n}\n\nbutton.pill:hover,\nbutton.chip:hover {\n background: var(--bg-hover);\n}\n\n.pill:focus-visible,\n.chip:focus-visible,\n.linkButton:focus-visible,\n.moreLink:focus-visible {\n outline: 2px solid var(--border-focus);\n outline-offset: 2px;\n}\n\n.chip[data-tone='warning'] {\n border-color: var(--status-warning-solid);\n}\n\n.chip[data-tone='danger'] {\n border-color: var(--status-danger-solid);\n color: var(--status-danger-fg);\n}\n\n.dot {\n width: 8px;\n height: 8px;\n border-radius: var(--radius-full);\n flex: none;\n background: var(--status-neutral-solid);\n}\n\n.dot[data-tone='success'] {\n background: var(--status-success-solid);\n}\n.dot[data-tone='warning'] {\n background: var(--status-warning-solid);\n}\n.dot[data-tone='danger'] {\n background: var(--status-danger-solid);\n}\n.dot[data-tone='unknown'] {\n background: var(--chart-unknown-hatch);\n border: 1px solid var(--status-unknown-solid);\n}\n\n/* Verdict: 17/24, weight 500 (SPEC-310C §6). */\n.verdict {\n margin: 0;\n font-size: var(--text-lg-size);\n line-height: var(--text-lg-line);\n font-weight: var(--font-weight-medium);\n color: var(--text-primary);\n font-variant-numeric: tabular-nums;\n}\n\n.verdictPart[data-tone='danger'] {\n color: var(--status-danger-fg);\n}\n.verdictPart[data-tone='warning'] {\n color: var(--status-warning-fg);\n}\n.verdictPart[data-tone='success'] {\n color: var(--status-success-fg);\n}\n.verdictPart[data-tone='unknown'] {\n color: var(--status-unknown-fg);\n font-style: italic;\n}\n\n.verdictSep {\n color: var(--text-tertiary);\n}\n\n.since {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-2);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n}\n\n.sinceLead {\n color: var(--text-tertiary);\n}\n\n.sinceChip {\n display: inline-flex;\n align-items: center;\n padding: 1px var(--space-2);\n border-radius: var(--radius-full);\n background: var(--status-neutral-bg);\n color: var(--status-neutral-fg);\n font-variant-numeric: tabular-nums;\n}\n.sinceChip[data-tone='success'] {\n background: var(--status-success-bg);\n color: var(--status-success-fg);\n}\n.sinceChip[data-tone='danger'] {\n background: var(--status-danger-bg);\n color: var(--status-danger-fg);\n}\n.sinceChip[data-tone='warning'] {\n background: var(--status-warning-bg);\n color: var(--status-warning-fg);\n}\n.sinceChip[data-tone='info'] {\n background: var(--status-info-bg);\n color: var(--status-info-fg);\n}\n\n.actionNote,\n.actionError {\n margin: 0;\n padding: var(--space-2) var(--space-3);\n border-radius: var(--radius-md);\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n}\n\n.actionNote {\n background: var(--bg-hover);\n color: var(--text-secondary);\n}\n\n.actionError {\n display: flex;\n align-items: baseline;\n gap: var(--space-3);\n background: var(--status-danger-bg);\n color: var(--status-danger-fg);\n}\n\n/* ---- shared small controls ------------------------------------------- */\n.linkButton,\n.moreLink {\n display: inline-flex;\n align-items: center;\n gap: var(--space-1);\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 line-height: var(--text-xs-line);\n text-decoration: none;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.linkButton:hover,\n.moreLink:hover {\n text-decoration: underline;\n}\n\n.moreLink {\n align-self: flex-start;\n}\n\n.moreLink:disabled {\n color: var(--text-disabled);\n cursor: default;\n text-decoration: none;\n}\n\n.kbd {\n padding: 0 var(--space-1);\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-xs);\n color: var(--text-tertiary);\n font-family: var(--font-mono);\n font-size: var(--text-2xs-size);\n}\n\n.muted {\n margin: 0;\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n}\n\n.mono {\n font-family: var(--font-mono);\n font-size: var(--text-xs-size);\n}\n\n.num {\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n\n.confirmBody {\n color: var(--text-secondary);\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line-relaxed);\n}\n\n.confirmActions {\n display: flex;\n justify-content: flex-end;\n gap: var(--space-2);\n margin-top: var(--space-5);\n}\n\n/* ---- Needs you ------------------------------------------------------- */\n.needsList {\n display: flex;\n flex-direction: column;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.needsRow {\n display: grid;\n grid-template-columns: auto minmax(0, 1fr) auto;\n align-items: start;\n gap: var(--space-2) var(--space-3);\n padding: var(--space-2) 0;\n border-top: 1px solid var(--border-subtle);\n}\n\n.needsRow:first-child {\n border-top: 0;\n padding-top: 0;\n}\n\n.sevDot {\n width: 8px;\n height: 8px;\n margin-top: 6px;\n border-radius: var(--radius-full);\n background: var(--status-info-solid);\n}\n.sevDot[data-severity='warn'] {\n background: var(--status-warning-solid);\n}\n.sevDot[data-severity='high'] {\n background: var(--status-danger-solid);\n}\n\n.needsText {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n/* \"Patch · Claude run\" — the proposal kind and engine the wire title led with. */\n.needsKind {\n font-family: var(--font-display);\n font-size: var(--text-2xs-size);\n line-height: var(--text-2xs-line);\n letter-spacing: var(--tracking-label);\n text-transform: uppercase;\n color: var(--text-secondary);\n}\n\n/* Two lines at most, wrapped at word boundaries. The text already ends on a\n whole word (needs-you-model readableItemTitle); the full server title rides\n in `title`. */\n.needsTitle {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 2;\n line-clamp: 2;\n overflow: hidden;\n color: var(--text-primary);\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n overflow-wrap: break-word;\n}\n\n.needsDetail {\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/* \"binshield · #81 · 38 days ago\". */\n.needsMeta {\n display: flex;\n flex-wrap: wrap;\n gap: 0 var(--space-1);\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n}\n\n.needsRepo {\n font-weight: var(--font-weight-medium);\n}\n\n.needsActions {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-end;\n align-items: center;\n gap: var(--space-2);\n}\n\n.allClear {\n display: flex;\n flex-direction: column;\n gap: var(--space-1);\n padding: var(--space-4) 0;\n}\n\n.allClearTitle {\n font-family: var(--font-display);\n font-size: var(--text-md-size);\n line-height: var(--text-md-line);\n font-weight: var(--font-weight-semibold);\n color: var(--text-primary);\n}\n\n.allClearBody {\n color: var(--text-secondary);\n font-size: var(--text-sm-size);\n}\n\n/* ---- Leader ---------------------------------------------------------- */\n.memo {\n display: flex;\n flex-direction: column;\n gap: var(--space-2);\n margin: 0;\n}\n\n.memoRow {\n display: grid;\n grid-template-columns: 96px minmax(0, 1fr);\n gap: var(--space-3);\n align-items: baseline;\n}\n\n.memoRow dd {\n margin: 0;\n}\n\n.memoText {\n color: var(--text-primary);\n font-size: var(--text-base-size);\n line-height: var(--text-base-line);\n}\n\n.delta {\n display: inline-block;\n margin-left: var(--space-2);\n padding: 0 var(--space-2);\n border-radius: var(--radius-full);\n background: var(--status-info-bg);\n color: var(--status-info-fg);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n.dryRun {\n font-family: var(--font-display); /* micro-labels follow the Display-font setting */\n padding: 0 var(--space-2);\n border: 1px dashed var(--border-strong);\n border-radius: var(--radius-full);\n color: var(--text-secondary);\n font-size: var(--text-2xs-size);\n line-height: var(--text-xs-line);\n text-transform: uppercase;\n letter-spacing: var(--tracking-label);\n}\n\n.actionList {\n display: flex;\n flex-direction: column;\n margin: 0;\n padding: 0;\n list-style: none;\n border-top: 1px solid var(--border-subtle);\n}\n\n.actionRow {\n display: grid;\n grid-template-columns: auto minmax(0, 1fr) auto;\n gap: var(--space-3);\n align-items: center;\n padding: var(--space-2) 0;\n border-bottom: 1px solid var(--border-subtle);\n}\n\n.actionRow[data-status='vetoed'] .actionSummary {\n text-decoration: line-through;\n color: var(--text-tertiary);\n}\n\n.classBadge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border: 1px solid var(--border-default);\n border-radius: var(--radius-sm);\n color: var(--text-secondary);\n font-family: var(--font-display);\n font-size: var(--text-2xs-size);\n font-weight: var(--font-weight-semibold);\n}\n\n.classBadge[data-class='B'] {\n border-color: var(--status-warning-solid);\n color: var(--status-warning-fg);\n}\n\n.classBadge[data-class='C'] {\n border-style: dashed;\n}\n\n.actionText {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.actionSummary {\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.actionWhy {\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n overflow-wrap: anywhere;\n}\n\n.actionState {\n display: inline-flex;\n align-items: center;\n gap: var(--space-2);\n}\n\n.statusWord {\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n white-space: nowrap;\n}\n\n.statusWord[data-status='escalated'] {\n color: var(--status-warning-fg);\n}\n\n.statusWord[data-status='failed'],\n.statusWord[data-status='refused'] {\n color: var(--status-danger-fg);\n}\n\n.vetoChip {\n border: 1px solid var(--border-default);\n}\n\n.ring {\n display: inline-flex;\n align-items: center;\n gap: var(--space-1);\n color: var(--status-warning-fg);\n font-size: var(--text-xs-size);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n.ringTrack {\n fill: none;\n stroke: var(--border-subtle);\n stroke-width: 2.5;\n}\n\n.ringFill {\n fill: none;\n stroke: var(--status-warning-solid);\n stroke-width: 2.5;\n stroke-linecap: round;\n}\n\n.ringText {\n min-width: 4ch;\n}\n\n/* ---- KPIs and burn-downs --------------------------------------------- */\n.kpis {\n display: grid;\n grid-template-columns: repeat(5, minmax(0, 1fr));\n gap: var(--surface-gap);\n /* One height for every tile in a row, whatever its caption wraps to (audit 15). */\n align-items: stretch;\n}\n\n/* Medium: five tiles as 3 + 2 on a 6-column track — the last two share the\n second row instead of leaving a blank third column (audit 15). */\n[data-viewport='medium'] .kpis {\n grid-template-columns: repeat(6, minmax(0, 1fr));\n}\n\n[data-viewport='medium'] .kpis > * {\n grid-column: span 2;\n}\n\n[data-viewport='medium'] .kpis > :nth-child(3n + 1):nth-last-child(2),\n[data-viewport='medium'] .kpis > :nth-child(3n + 2):nth-last-child(1) {\n grid-column: span 3;\n}\n\n[data-viewport='compact'] .kpis {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n}\n\n/* The burn-downs live on Usage (SeatBurnPanel), which has no Surface\n viewport attribute: the columns follow the panel's own width instead. */\n.burnGrid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr));\n gap: var(--surface-gap);\n align-items: start;\n}\n\n/* 375: one card at a time, snapping — the next card peeks in at the edge. */\n.burnStrip {\n display: grid;\n grid-auto-flow: column;\n grid-auto-columns: 86%;\n gap: var(--space-3);\n overflow-x: auto;\n overscroll-behavior-x: contain;\n scroll-snap-type: x mandatory;\n padding-bottom: var(--space-1);\n}\n\n.burnStrip > .burnItem {\n scroll-snap-align: start;\n}\n\n.burnItem {\n min-width: 0;\n}\n\n.freeSeat {\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}\n\n.freeHead {\n display: inline-flex;\n align-items: center;\n gap: var(--space-2);\n}\n\n.freeTitle {\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n font-weight: var(--font-weight-semibold);\n color: var(--text-primary);\n}\n\n.freeValue {\n font-size: var(--text-2xl-size);\n line-height: var(--text-2xl-line);\n font-weight: var(--font-weight-semibold);\n color: var(--text-secondary);\n}\n\n.freeBody {\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n}\n\n/* ---- Touch ID sheet -------------------------------------------------- */\n.scope {\n display: flex;\n flex-direction: column;\n gap: var(--space-5);\n}\n\n.scopeBlock {\n display: flex;\n flex-direction: column;\n gap: var(--space-2);\n}\n\n.scopeLead {\n margin: 0;\n color: var(--text-primary);\n font-size: var(--text-base-size);\n line-height: var(--text-base-line);\n}\n\n.scopeMeta {\n margin: 0;\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n}\n\n.scopeTable {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--text-xs-size);\n}\n\n.scopeTable th {\n padding: var(--space-1) var(--space-2) var(--space-1) 0;\n border-bottom: 1px solid var(--border-subtle);\n color: var(--text-tertiary);\n font-weight: var(--font-weight-medium);\n text-align: left;\n}\n\n.scopeTable td {\n padding: var(--space-1) var(--space-2) var(--space-1) 0;\n border-bottom: 1px solid var(--border-subtle);\n color: var(--text-primary);\n}\n\n.scopeList {\n margin: 0;\n padding-left: var(--space-4);\n color: var(--text-secondary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n}\n\n.ladder {\n display: flex;\n flex-direction: column;\n gap: var(--space-2);\n margin: 0;\n padding: 0;\n list-style: none;\n counter-reset: rung;\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n color: var(--text-secondary);\n}\n\n.ladder li {\n display: grid;\n grid-template-columns: 56px minmax(0, 1fr);\n gap: var(--space-2);\n}\n\n.ladderId {\n font-family: var(--font-mono);\n color: var(--text-primary);\n}\n\n.sheetFooter {\n display: flex;\n flex-direction: column;\n gap: var(--space-3);\n}\n\n.sheetFootnote {\n margin: 0;\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n}\n\n.sheetButtons {\n display: flex;\n justify-content: flex-end;\n gap: var(--space-2);\n}\n\n@media (prefers-reduced-motion: reduce) {\n button.pill,\n button.chip {\n transition: none;\n }\n}\n","/**\n * routes/verse/command/actions.tsx — how every write on the four surfaces\n * reaches the server (unit C7).\n *\n * Order is fixed and the same for a click, a key and the palette\n * (SPEC-310C §1 \"Guarded actions ask for confirmation, then the mutation\n * token\"):\n *\n * 1. a confirmation dialog, when the action asks for one (Stop, Veto,\n * Resume, every Needs-you approve / reject / veto);\n * 2. the mutation token, when none is held (useGuardedAction);\n * 3. the request, one at a time, with the server's own refusal sentence\n * shown on failure and read-only sessions explained, never errored.\n *\n * LOWERING needs no confirmation (SPEC-310B I1: \"lowering authority is\n * instant\") — callers simply omit `confirm` for the switch-down path.\n */\nimport { useCallback, useId, useRef, useState, type ReactNode } from 'react';\nimport { MutationTokenDialog } from '../../../components/auth/MutationTokenDialog.js';\nimport { Dialog } from '../../../components/primitives/Dialog.js';\nimport { Button } from '../../../components/primitives/Button.js';\nimport { useGuardedAction } from '../autonomy/use-guarded-action.js';\nimport styles from './command.module.css';\n\nexport interface ConfirmSpec {\n title: string;\n body: ReactNode;\n confirmLabel: string;\n destructive?: boolean;\n}\n\nexport function ConfirmDialog({ spec, onConfirm, onCancel }: { spec: ConfirmSpec | null; onConfirm: () => void; onCancel: () => void }) {\n const titleId = useId();\n const cancelRef = useRef<HTMLButtonElement>(null);\n const confirmRef = useRef<HTMLButtonElement>(null);\n return (\n <Dialog\n open={spec !== null}\n onClose={onCancel}\n titleId={titleId}\n title={spec?.title ?? ''}\n // A destructive confirm starts on Cancel, so a stray Enter never stops the fleet.\n initialFocusRef={spec?.destructive ? cancelRef : confirmRef}\n >\n <div className={styles.confirmBody}>{spec?.body}</div>\n <div className={styles.confirmActions}>\n <Button ref={cancelRef} variant=\"ghost\" onClick={onCancel}>\n Cancel\n </Button>\n <Button ref={confirmRef} variant={spec?.destructive ? 'danger' : 'primary'} onClick={onConfirm}>\n {spec?.confirmLabel ?? 'Confirm'}\n </Button>\n </div>\n </Dialog>\n );\n}\n\nexport interface SurfaceActions {\n /** Confirm (when asked), then token (when needed), then run `fn`. */\n act: <T>(fn: () => Promise<T>, reason: string, options?: { confirm?: ConfirmSpec; onDone?: (result: T) => void }) => void;\n busy: boolean;\n error: string | null;\n clearError: () => void;\n readOnly: boolean;\n /** Render once per surface. */\n dialogs: ReactNode;\n}\n\nexport function useSurfaceActions(): SurfaceActions {\n const guard = useGuardedAction();\n const [pending, setPending] = useState<{ spec: ConfirmSpec; run: () => void } | null>(null);\n const { request } = guard;\n\n const act = useCallback(\n <T,>(fn: () => Promise<T>, reason: string, options: { confirm?: ConfirmSpec; onDone?: (result: T) => void } = {}) => {\n const run = () => request(fn, reason, options.onDone);\n if (options.confirm) setPending({ spec: options.confirm, run });\n else run();\n },\n [request],\n );\n\n const dialogs = (\n <>\n <ConfirmDialog\n spec={pending?.spec ?? null}\n onCancel={() => setPending(null)}\n onConfirm={() => {\n const next = pending;\n setPending(null);\n next?.run();\n }}\n />\n <MutationTokenDialog open={guard.tokenOpen} onClose={guard.closeToken} reason={guard.tokenReason} tokenHelp=\"the mutation token ashlr verse printed\" />\n </>\n );\n\n return { act, busy: guard.busy, error: guard.error, clearError: guard.clearError, readOnly: guard.readOnly, dialogs };\n}\n\n/** The error / read-only line a surface shows under its top bar. */\nexport function ActionStatus({ actions }: { actions: Pick<SurfaceActions, 'error' | 'clearError' | 'readOnly'> }) {\n if (actions.readOnly) {\n return (\n <p className={styles.actionNote} role=\"status\">\n Read-only session: this server was started without dispatch, so switching, stopping and vetoing are unavailable. Everything shown is live.\n </p>\n );\n }\n if (!actions.error) return null;\n return (\n <p className={styles.actionError} role=\"alert\">\n {actions.error}\n <button type=\"button\" className={styles.linkButton} onClick={actions.clearError}>\n Dismiss\n </button>\n </p>\n );\n}\n"],"mappings":"0sFC+BA,SAAgB,EAAc,CAAE,OAAM,YAAW,YAAuF,CACtI,IAAM,GAAA,EAAU,EAAA,MAAA,CAAM,EAChB,GAAA,EAAY,EAAA,OAAA,CAA0B,IAAI,EAC1C,GAAA,EAAa,EAAA,OAAA,CAA0B,IAAI,EACjD,OACE,EAAA,EAAA,KAAA,CAAC,EAAD,CACE,KAAM,IAAS,KACf,QAAS,EACA,UACT,MAAO,GAAM,OAAS,GAEtB,gBAAiB,GAAM,YAAc,EAAY,EANnD,SAAA,EAQE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAO,YAAc,SAAA,GAAM,IAAU,CAAA,GACrD,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,EAAO,eAAvB,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,EAAD,CAAQ,IAAK,EAAW,QAAQ,QAAQ,QAAS,EAAU,SAAA,QAEnD,CAAA,GACR,EAAA,EAAA,IAAA,CAAC,EAAD,CAAQ,IAAK,EAAY,QAAS,GAAM,YAAc,SAAW,UAAW,QAAS,EAClF,SAAA,GAAM,cAAgB,SACjB,CAAA,CACL,CACC,CAAA,CAAA,GAEZ,CAaA,SAAgB,GAAoC,CAClD,IAAM,EAAQ,EAAiB,EACzB,CAAC,EAAS,IAAA,EAAc,EAAA,SAAA,CAAwD,IAAI,EACpF,CAAE,WAAY,EAEd,GAAA,EAAM,EAAA,YAAA,EACL,EAAsB,EAAgB,EAAmE,CAAC,IAAM,CACnH,IAAM,MAAY,EAAQ,EAAI,EAAQ,EAAQ,MAAM,EAChD,EAAQ,QAAS,EAAW,CAAE,KAAM,EAAQ,QAAS,KAAI,CAAC,EACzD,EAAI,CACX,EACA,CAAC,CAAO,CACV,EAEM,GACJ,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,KAAM,GAAS,MAAQ,KACvB,aAAgB,EAAW,IAAI,EAC/B,cAAiB,CACf,IAAM,EAAO,EACb,EAAW,IAAI,EACf,GAAM,IAAI,CACZ,CACD,CAAA,GACD,EAAA,EAAA,IAAA,CAAC,EAAD,CAAqB,KAAM,EAAM,UAAW,QAAS,EAAM,WAAY,OAAQ,EAAM,YAAa,UAAU,wCAA0C,CAAA,CACtJ,CAAA,CAAA,EAGJ,MAAO,CAAE,MAAK,KAAM,EAAM,KAAM,MAAO,EAAM,MAAO,WAAY,EAAM,WAAY,SAAU,EAAM,SAAU,SAAQ,CACtH,CAGA,SAAgB,EAAa,CAAE,WAAmF,CAShH,OARI,EAAQ,UAER,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAW,EAAO,WAAY,KAAK,SAAS,SAAA,4IAE5C,CAAA,EAGF,EAAQ,OAEX,EAAA,EAAA,KAAA,CAAC,IAAD,CAAG,UAAW,EAAO,YAAa,KAAK,QAAvC,SAAA,CACG,EAAQ,OACT,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,KAAK,SAAS,UAAW,EAAO,WAAY,QAAS,EAAQ,WAAY,SAAA,SAEzE,CAAA,CACP,IAPsB,IAS7B"}
1
+ {"version":3,"file":"actions-CY-PjpGc.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/command/command.module.css","../../../../../../src/web-ui/routes/verse/command/actions.tsx"],"sourcesContent":["/*\n * routes/verse/command/command.module.css — Command's cards and top bar\n * (unit C7). Tokens only: style-scan-310 bans raw hex colours and px font\n * sizes in this folder, and every colour here follows the theme.\n */\n\n/* ---- lead: top bar, verdict, since ------------------------------------ */\n.lead {\n display: flex;\n flex-direction: column;\n gap: var(--space-3);\n}\n\n.bar {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: var(--space-2) var(--space-3);\n min-height: var(--control-h);\n}\n\n.barSpacer {\n flex: 1;\n}\n\n.barSecondary {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-2);\n}\n\n.switchWrap {\n display: inline-flex;\n align-items: center;\n gap: var(--space-2);\n}\n\n.barLabel,\n.pillLabel {\n font-family: var(--font-display);\n font-size: var(--text-2xs-size);\n line-height: var(--text-2xs-line);\n letter-spacing: var(--tracking-label);\n text-transform: uppercase;\n color: var(--text-tertiary);\n}\n\n.switchOption {\n display: inline-flex;\n align-items: center;\n gap: var(--space-1);\n}\n\n.touchMark {\n color: var(--text-tertiary);\n}\n\n.pill,\n.chip {\n display: inline-flex;\n align-items: center;\n gap: var(--space-2);\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-full);\n background: var(--bg-surface);\n color: var(--text-primary);\n font-family: var(--font-ui);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n white-space: nowrap;\n}\n\nbutton.pill,\nbutton.chip {\n cursor: pointer;\n transition: background-color var(--duration-fast) var(--ease-standard);\n}\n\nbutton.pill:hover,\nbutton.chip:hover {\n background: var(--bg-hover);\n}\n\n.pill:focus-visible,\n.chip:focus-visible,\n.linkButton:focus-visible,\n.moreLink:focus-visible {\n outline: 2px solid var(--border-focus);\n outline-offset: 2px;\n}\n\n.chip[data-tone='warning'] {\n border-color: var(--status-warning-solid);\n}\n\n.chip[data-tone='danger'] {\n border-color: var(--status-danger-solid);\n color: var(--status-danger-fg);\n}\n\n.dot {\n width: 8px;\n height: 8px;\n border-radius: var(--radius-full);\n flex: none;\n background: var(--status-neutral-solid);\n}\n\n.dot[data-tone='success'] {\n background: var(--status-success-solid);\n}\n.dot[data-tone='warning'] {\n background: var(--status-warning-solid);\n}\n.dot[data-tone='danger'] {\n background: var(--status-danger-solid);\n}\n.dot[data-tone='unknown'] {\n background: var(--chart-unknown-hatch);\n border: 1px solid var(--status-unknown-solid);\n}\n\n/* Verdict: 17/24, weight 500 (SPEC-310C §6). */\n.verdict {\n margin: 0;\n font-size: var(--text-lg-size);\n line-height: var(--text-lg-line);\n font-weight: var(--font-weight-medium);\n color: var(--text-primary);\n font-variant-numeric: tabular-nums;\n}\n\n.verdictPart[data-tone='danger'] {\n color: var(--status-danger-fg);\n}\n.verdictPart[data-tone='warning'] {\n color: var(--status-warning-fg);\n}\n.verdictPart[data-tone='success'] {\n color: var(--status-success-fg);\n}\n.verdictPart[data-tone='unknown'] {\n color: var(--status-unknown-fg);\n font-style: italic;\n}\n\n.verdictSep {\n color: var(--text-tertiary);\n}\n\n.since {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-2);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n}\n\n.sinceLead {\n color: var(--text-tertiary);\n}\n\n.sinceChip {\n display: inline-flex;\n align-items: center;\n padding: 1px var(--space-2);\n border-radius: var(--radius-full);\n background: var(--status-neutral-bg);\n color: var(--status-neutral-fg);\n font-variant-numeric: tabular-nums;\n}\n.sinceChip[data-tone='success'] {\n background: var(--status-success-bg);\n color: var(--status-success-fg);\n}\n.sinceChip[data-tone='danger'] {\n background: var(--status-danger-bg);\n color: var(--status-danger-fg);\n}\n.sinceChip[data-tone='warning'] {\n background: var(--status-warning-bg);\n color: var(--status-warning-fg);\n}\n.sinceChip[data-tone='info'] {\n background: var(--status-info-bg);\n color: var(--status-info-fg);\n}\n\n.actionNote,\n.actionError {\n margin: 0;\n padding: var(--space-2) var(--space-3);\n border-radius: var(--radius-md);\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n}\n\n.actionNote {\n background: var(--bg-hover);\n color: var(--text-secondary);\n}\n\n.actionError {\n display: flex;\n align-items: baseline;\n gap: var(--space-3);\n background: var(--status-danger-bg);\n color: var(--status-danger-fg);\n}\n\n/* ---- shared small controls ------------------------------------------- */\n.linkButton,\n.moreLink {\n display: inline-flex;\n align-items: center;\n gap: var(--space-1);\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 line-height: var(--text-xs-line);\n text-decoration: none;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.linkButton:hover,\n.moreLink:hover {\n text-decoration: underline;\n}\n\n.moreLink {\n align-self: flex-start;\n}\n\n.moreLink:disabled {\n color: var(--text-disabled);\n cursor: default;\n text-decoration: none;\n}\n\n.kbd {\n padding: 0 var(--space-1);\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-xs);\n color: var(--text-tertiary);\n font-family: var(--font-mono);\n font-size: var(--text-2xs-size);\n}\n\n.muted {\n margin: 0;\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n}\n\n.mono {\n font-family: var(--font-mono);\n font-size: var(--text-xs-size);\n}\n\n.num {\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n\n.confirmBody {\n color: var(--text-secondary);\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line-relaxed);\n}\n\n.confirmActions {\n display: flex;\n justify-content: flex-end;\n gap: var(--space-2);\n margin-top: var(--space-5);\n}\n\n/* ---- Needs you ------------------------------------------------------- */\n.needsList {\n display: flex;\n flex-direction: column;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.needsRow {\n display: grid;\n grid-template-columns: auto minmax(0, 1fr) auto;\n align-items: start;\n gap: var(--space-2) var(--space-3);\n padding: var(--space-2) 0;\n border-top: 1px solid var(--border-subtle);\n}\n\n.needsRow:first-child {\n border-top: 0;\n padding-top: 0;\n}\n\n.sevDot {\n width: 8px;\n height: 8px;\n margin-top: 6px;\n border-radius: var(--radius-full);\n background: var(--status-info-solid);\n}\n.sevDot[data-severity='warn'] {\n background: var(--status-warning-solid);\n}\n.sevDot[data-severity='high'] {\n background: var(--status-danger-solid);\n}\n\n.needsText {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n/* \"Patch · Claude run\" — the proposal kind and engine the wire title led with. */\n.needsKind {\n font-family: var(--font-display);\n font-size: var(--text-2xs-size);\n line-height: var(--text-2xs-line);\n letter-spacing: var(--tracking-label);\n text-transform: uppercase;\n color: var(--text-secondary);\n}\n\n/* Two lines at most, wrapped at word boundaries. The text already ends on a\n whole word (needs-you-model readableItemTitle); the full server title rides\n in `title`. */\n.needsTitle {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 2;\n line-clamp: 2;\n overflow: hidden;\n color: var(--text-primary);\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n overflow-wrap: break-word;\n}\n\n.needsDetail {\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/* \"binshield · #81 · 38 days ago\". */\n.needsMeta {\n display: flex;\n flex-wrap: wrap;\n gap: 0 var(--space-1);\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n}\n\n.needsRepo {\n font-weight: var(--font-weight-medium);\n}\n\n.needsActions {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-end;\n align-items: center;\n gap: var(--space-2);\n}\n\n.allClear {\n display: flex;\n flex-direction: column;\n gap: var(--space-1);\n padding: var(--space-4) 0;\n}\n\n.allClearTitle {\n font-family: var(--font-display);\n font-size: var(--text-md-size);\n line-height: var(--text-md-line);\n font-weight: var(--font-weight-semibold);\n color: var(--text-primary);\n}\n\n.allClearBody {\n color: var(--text-secondary);\n font-size: var(--text-sm-size);\n}\n\n/* ---- Leader ---------------------------------------------------------- */\n.memo {\n display: flex;\n flex-direction: column;\n gap: var(--space-2);\n margin: 0;\n}\n\n.memoRow {\n display: grid;\n grid-template-columns: 96px minmax(0, 1fr);\n gap: var(--space-3);\n align-items: baseline;\n}\n\n.memoRow dd {\n margin: 0;\n}\n\n.memoText {\n color: var(--text-primary);\n font-size: var(--text-base-size);\n line-height: var(--text-base-line);\n}\n\n.delta {\n display: inline-block;\n margin-left: var(--space-2);\n padding: 0 var(--space-2);\n border-radius: var(--radius-full);\n background: var(--status-info-bg);\n color: var(--status-info-fg);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n.dryRun {\n font-family: var(--font-display); /* micro-labels follow the Display-font setting */\n padding: 0 var(--space-2);\n border: 1px dashed var(--border-strong);\n border-radius: var(--radius-full);\n color: var(--text-secondary);\n font-size: var(--text-2xs-size);\n line-height: var(--text-xs-line);\n text-transform: uppercase;\n letter-spacing: var(--tracking-label);\n}\n\n.actionList {\n display: flex;\n flex-direction: column;\n margin: 0;\n padding: 0;\n list-style: none;\n border-top: 1px solid var(--border-subtle);\n}\n\n.actionRow {\n display: grid;\n grid-template-columns: auto minmax(0, 1fr) auto;\n gap: var(--space-3);\n align-items: center;\n padding: var(--space-2) 0;\n border-bottom: 1px solid var(--border-subtle);\n}\n\n.actionRow[data-status='vetoed'] .actionSummary {\n text-decoration: line-through;\n color: var(--text-tertiary);\n}\n\n.classBadge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border: 1px solid var(--border-default);\n border-radius: var(--radius-sm);\n color: var(--text-secondary);\n font-family: var(--font-display);\n font-size: var(--text-2xs-size);\n font-weight: var(--font-weight-semibold);\n}\n\n.classBadge[data-class='B'] {\n border-color: var(--status-warning-solid);\n color: var(--status-warning-fg);\n}\n\n.classBadge[data-class='C'] {\n border-style: dashed;\n}\n\n.actionText {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.actionSummary {\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.actionWhy {\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n overflow-wrap: anywhere;\n}\n\n.actionState {\n display: inline-flex;\n align-items: center;\n gap: var(--space-2);\n}\n\n.statusWord {\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n white-space: nowrap;\n}\n\n.statusWord[data-status='escalated'] {\n color: var(--status-warning-fg);\n}\n\n.statusWord[data-status='failed'],\n.statusWord[data-status='refused'] {\n color: var(--status-danger-fg);\n}\n\n.vetoChip {\n border: 1px solid var(--border-default);\n}\n\n.ring {\n display: inline-flex;\n align-items: center;\n gap: var(--space-1);\n color: var(--status-warning-fg);\n font-size: var(--text-xs-size);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n.ringTrack {\n fill: none;\n stroke: var(--border-subtle);\n stroke-width: 2.5;\n}\n\n.ringFill {\n fill: none;\n stroke: var(--status-warning-solid);\n stroke-width: 2.5;\n stroke-linecap: round;\n}\n\n.ringText {\n min-width: 4ch;\n}\n\n/* ---- KPIs and burn-downs --------------------------------------------- */\n.kpis {\n display: grid;\n grid-template-columns: repeat(5, minmax(0, 1fr));\n gap: var(--surface-gap);\n /* One height for every tile in a row, whatever its caption wraps to (audit 15). */\n align-items: stretch;\n}\n\n/* Medium: five tiles as 3 + 2 on a 6-column track — the last two share the\n second row instead of leaving a blank third column (audit 15). */\n[data-viewport='medium'] .kpis {\n grid-template-columns: repeat(6, minmax(0, 1fr));\n}\n\n[data-viewport='medium'] .kpis > * {\n grid-column: span 2;\n}\n\n[data-viewport='medium'] .kpis > :nth-child(3n + 1):nth-last-child(2),\n[data-viewport='medium'] .kpis > :nth-child(3n + 2):nth-last-child(1) {\n grid-column: span 3;\n}\n\n[data-viewport='compact'] .kpis {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n}\n\n/* The burn-downs live on Usage (SeatBurnPanel), which has no Surface\n viewport attribute: the columns follow the panel's own width instead. */\n.burnGrid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr));\n gap: var(--surface-gap);\n align-items: start;\n}\n\n/* 375: one card at a time, snapping — the next card peeks in at the edge. */\n.burnStrip {\n display: grid;\n grid-auto-flow: column;\n grid-auto-columns: 86%;\n gap: var(--space-3);\n overflow-x: auto;\n overscroll-behavior-x: contain;\n scroll-snap-type: x mandatory;\n padding-bottom: var(--space-1);\n}\n\n.burnStrip > .burnItem {\n scroll-snap-align: start;\n}\n\n.burnItem {\n min-width: 0;\n}\n\n.freeSeat {\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}\n\n.freeHead {\n display: inline-flex;\n align-items: center;\n gap: var(--space-2);\n}\n\n.freeTitle {\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n font-weight: var(--font-weight-semibold);\n color: var(--text-primary);\n}\n\n.freeValue {\n font-size: var(--text-2xl-size);\n line-height: var(--text-2xl-line);\n font-weight: var(--font-weight-semibold);\n color: var(--text-secondary);\n}\n\n.freeBody {\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n}\n\n/* ---- Touch ID sheet -------------------------------------------------- */\n.scope {\n display: flex;\n flex-direction: column;\n gap: var(--space-5);\n}\n\n.scopeBlock {\n display: flex;\n flex-direction: column;\n gap: var(--space-2);\n}\n\n.scopeLead {\n margin: 0;\n color: var(--text-primary);\n font-size: var(--text-base-size);\n line-height: var(--text-base-line);\n}\n\n.scopeMeta {\n margin: 0;\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n}\n\n.scopeTable {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--text-xs-size);\n}\n\n.scopeTable th {\n padding: var(--space-1) var(--space-2) var(--space-1) 0;\n border-bottom: 1px solid var(--border-subtle);\n color: var(--text-tertiary);\n font-weight: var(--font-weight-medium);\n text-align: left;\n}\n\n.scopeTable td {\n padding: var(--space-1) var(--space-2) var(--space-1) 0;\n border-bottom: 1px solid var(--border-subtle);\n color: var(--text-primary);\n}\n\n.scopeList {\n margin: 0;\n padding-left: var(--space-4);\n color: var(--text-secondary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n}\n\n.ladder {\n display: flex;\n flex-direction: column;\n gap: var(--space-2);\n margin: 0;\n padding: 0;\n list-style: none;\n counter-reset: rung;\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n color: var(--text-secondary);\n}\n\n.ladder li {\n display: grid;\n grid-template-columns: 56px minmax(0, 1fr);\n gap: var(--space-2);\n}\n\n.ladderId {\n font-family: var(--font-mono);\n color: var(--text-primary);\n}\n\n.sheetFooter {\n display: flex;\n flex-direction: column;\n gap: var(--space-3);\n}\n\n.sheetFootnote {\n margin: 0;\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n}\n\n.sheetButtons {\n display: flex;\n justify-content: flex-end;\n gap: var(--space-2);\n}\n\n@media (prefers-reduced-motion: reduce) {\n button.pill,\n button.chip {\n transition: none;\n }\n}\n\n/* Held while the AutonomyStatus chunk loads (3.14), so the verdict does not jump. */\n.autonomyPlaceholder {\n min-height: 132px;\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-lg);\n background: var(--bg-surface);\n}\n","/**\n * routes/verse/command/actions.tsx — how every write on the four surfaces\n * reaches the server (unit C7).\n *\n * Order is fixed and the same for a click, a key and the palette\n * (SPEC-310C §1 \"Guarded actions ask for confirmation, then the mutation\n * token\"):\n *\n * 1. a confirmation dialog, when the action asks for one (Stop, Veto,\n * Resume, every Needs-you approve / reject / veto);\n * 2. the mutation token, when none is held (useGuardedAction);\n * 3. the request, one at a time, with the server's own refusal sentence\n * shown on failure and read-only sessions explained, never errored.\n *\n * LOWERING needs no confirmation (SPEC-310B I1: \"lowering authority is\n * instant\") — callers simply omit `confirm` for the switch-down path.\n */\nimport { useCallback, useId, useRef, useState, type ReactNode } from 'react';\nimport { MutationTokenDialog } from '../../../components/auth/MutationTokenDialog.js';\nimport { Dialog } from '../../../components/primitives/Dialog.js';\nimport { Button } from '../../../components/primitives/Button.js';\nimport { useGuardedAction } from '../autonomy/use-guarded-action.js';\nimport styles from './command.module.css';\n\nexport interface ConfirmSpec {\n title: string;\n body: ReactNode;\n confirmLabel: string;\n destructive?: boolean;\n}\n\nexport function ConfirmDialog({ spec, onConfirm, onCancel }: { spec: ConfirmSpec | null; onConfirm: () => void; onCancel: () => void }) {\n const titleId = useId();\n const cancelRef = useRef<HTMLButtonElement>(null);\n const confirmRef = useRef<HTMLButtonElement>(null);\n return (\n <Dialog\n open={spec !== null}\n onClose={onCancel}\n titleId={titleId}\n title={spec?.title ?? ''}\n // A destructive confirm starts on Cancel, so a stray Enter never stops the fleet.\n initialFocusRef={spec?.destructive ? cancelRef : confirmRef}\n >\n <div className={styles.confirmBody}>{spec?.body}</div>\n <div className={styles.confirmActions}>\n <Button ref={cancelRef} variant=\"ghost\" onClick={onCancel}>\n Cancel\n </Button>\n <Button ref={confirmRef} variant={spec?.destructive ? 'danger' : 'primary'} onClick={onConfirm}>\n {spec?.confirmLabel ?? 'Confirm'}\n </Button>\n </div>\n </Dialog>\n );\n}\n\nexport interface SurfaceActions {\n /** Confirm (when asked), then token (when needed), then run `fn`. */\n act: <T>(fn: () => Promise<T>, reason: string, options?: { confirm?: ConfirmSpec; onDone?: (result: T) => void }) => void;\n busy: boolean;\n error: string | null;\n clearError: () => void;\n readOnly: boolean;\n /** Render once per surface. */\n dialogs: ReactNode;\n}\n\nexport function useSurfaceActions(): SurfaceActions {\n const guard = useGuardedAction();\n const [pending, setPending] = useState<{ spec: ConfirmSpec; run: () => void } | null>(null);\n const { request } = guard;\n\n const act = useCallback(\n <T,>(fn: () => Promise<T>, reason: string, options: { confirm?: ConfirmSpec; onDone?: (result: T) => void } = {}) => {\n const run = () => request(fn, reason, options.onDone);\n if (options.confirm) setPending({ spec: options.confirm, run });\n else run();\n },\n [request],\n );\n\n const dialogs = (\n <>\n <ConfirmDialog\n spec={pending?.spec ?? null}\n onCancel={() => setPending(null)}\n onConfirm={() => {\n const next = pending;\n setPending(null);\n next?.run();\n }}\n />\n <MutationTokenDialog open={guard.tokenOpen} onClose={guard.closeToken} reason={guard.tokenReason} tokenHelp=\"the mutation token ashlr verse printed\" />\n </>\n );\n\n return { act, busy: guard.busy, error: guard.error, clearError: guard.clearError, readOnly: guard.readOnly, dialogs };\n}\n\n/** The error / read-only line a surface shows under its top bar. */\nexport function ActionStatus({ actions }: { actions: Pick<SurfaceActions, 'error' | 'clearError' | 'readOnly'> }) {\n if (actions.readOnly) {\n return (\n <p className={styles.actionNote} role=\"status\">\n Read-only session: this server was started without dispatch, so switching, stopping and vetoing are unavailable. Everything shown is live.\n </p>\n );\n }\n if (!actions.error) return null;\n return (\n <p className={styles.actionError} role=\"alert\">\n {actions.error}\n <button type=\"button\" className={styles.linkButton} onClick={actions.clearError}>\n Dismiss\n </button>\n </p>\n );\n}\n"],"mappings":"+vFC+BA,SAAgB,EAAc,CAAE,OAAM,YAAW,YAAuF,CACtI,IAAM,GAAA,EAAU,EAAA,MAAA,CAAM,EAChB,GAAA,EAAY,EAAA,OAAA,CAA0B,IAAI,EAC1C,GAAA,EAAa,EAAA,OAAA,CAA0B,IAAI,EACjD,OACE,EAAA,EAAA,KAAA,CAAC,EAAD,CACE,KAAM,IAAS,KACf,QAAS,EACA,UACT,MAAO,GAAM,OAAS,GAEtB,gBAAiB,GAAM,YAAc,EAAY,EANnD,SAAA,EAQE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAO,YAAc,SAAA,GAAM,IAAU,CAAA,GACrD,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,EAAO,eAAvB,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,EAAD,CAAQ,IAAK,EAAW,QAAQ,QAAQ,QAAS,EAAU,SAAA,QAEnD,CAAA,GACR,EAAA,EAAA,IAAA,CAAC,EAAD,CAAQ,IAAK,EAAY,QAAS,GAAM,YAAc,SAAW,UAAW,QAAS,EAClF,SAAA,GAAM,cAAgB,SACjB,CAAA,CACL,CACC,CAAA,CAAA,GAEZ,CAaA,SAAgB,GAAoC,CAClD,IAAM,EAAQ,EAAiB,EACzB,CAAC,EAAS,IAAA,EAAc,EAAA,SAAA,CAAwD,IAAI,EACpF,CAAE,WAAY,EAEd,GAAA,EAAM,EAAA,YAAA,EACL,EAAsB,EAAgB,EAAmE,CAAC,IAAM,CACnH,IAAM,MAAY,EAAQ,EAAI,EAAQ,EAAQ,MAAM,EAChD,EAAQ,QAAS,EAAW,CAAE,KAAM,EAAQ,QAAS,KAAI,CAAC,EACzD,EAAI,CACX,EACA,CAAC,CAAO,CACV,EAEM,GACJ,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,KAAM,GAAS,MAAQ,KACvB,aAAgB,EAAW,IAAI,EAC/B,cAAiB,CACf,IAAM,EAAO,EACb,EAAW,IAAI,EACf,GAAM,IAAI,CACZ,CACD,CAAA,GACD,EAAA,EAAA,IAAA,CAAC,EAAD,CAAqB,KAAM,EAAM,UAAW,QAAS,EAAM,WAAY,OAAQ,EAAM,YAAa,UAAU,wCAA0C,CAAA,CACtJ,CAAA,CAAA,EAGJ,MAAO,CAAE,MAAK,KAAM,EAAM,KAAM,MAAO,EAAM,MAAO,WAAY,EAAM,WAAY,SAAU,EAAM,SAAU,SAAQ,CACtH,CAGA,SAAgB,EAAa,CAAE,WAAmF,CAShH,OARI,EAAQ,UAER,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAW,EAAO,WAAY,KAAK,SAAS,SAAA,4IAE5C,CAAA,EAGF,EAAQ,OAEX,EAAA,EAAA,KAAA,CAAC,IAAD,CAAG,UAAW,EAAO,YAAa,KAAK,QAAvC,SAAA,CACG,EAAQ,OACT,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,KAAK,SAAS,UAAW,EAAO,WAAY,QAAS,EAAQ,WAAY,SAAA,SAEzE,CAAA,CACP,IAPsB,IAS7B"}
@@ -0,0 +1 @@
1
+ ._lead_1clua_8{gap:var(--space-3);flex-direction:column;display:flex}._bar_1clua_14{align-items:center;gap:var(--space-2) var(--space-3);min-height:var(--control-h);flex-wrap:wrap;display:flex}._barSpacer_1clua_22{flex:1}._barSecondary_1clua_26{gap:var(--space-2);flex-wrap:wrap;display:flex}._switchWrap_1clua_32{align-items:center;gap:var(--space-2);display:inline-flex}._barLabel_1clua_38,._pillLabel_1clua_39{font-family:var(--font-display);font-size:var(--text-2xs-size);line-height:var(--text-2xs-line);letter-spacing:var(--tracking-label);text-transform:uppercase;color:var(--text-tertiary)}._switchOption_1clua_48{align-items:center;gap:var(--space-1);display:inline-flex}._touchMark_1clua_54{color:var(--text-tertiary)}._pill_1clua_39,._chip_1clua_59{align-items:center;gap:var(--space-2);min-height:var(--control-h-sm);padding:0 var(--space-3);border:1px solid var(--border-default);border-radius:var(--radius-full);background:var(--bg-surface);color:var(--text-primary);font-family:var(--font-ui);font-size:var(--text-xs-size);line-height:var(--text-xs-line);white-space:nowrap;display:inline-flex}button._pill_1clua_39,button._chip_1clua_59{cursor:pointer;transition:background-color var(--duration-fast) var(--ease-standard)}button._pill_1clua_39:hover,button._chip_1clua_59:hover{background:var(--bg-hover)}._pill_1clua_39:focus-visible,._chip_1clua_59:focus-visible,._linkButton_1clua_88:focus-visible,._moreLink_1clua_89:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px}._chip_1clua_59[data-tone=warning]{border-color:var(--status-warning-solid)}._chip_1clua_59[data-tone=danger]{border-color:var(--status-danger-solid);color:var(--status-danger-fg)}._dot_1clua_103{border-radius:var(--radius-full);background:var(--status-neutral-solid);flex:none;width:8px;height:8px}._dot_1clua_103[data-tone=success]{background:var(--status-success-solid)}._dot_1clua_103[data-tone=warning]{background:var(--status-warning-solid)}._dot_1clua_103[data-tone=danger]{background:var(--status-danger-solid)}._dot_1clua_103[data-tone=unknown]{background:var(--chart-unknown-hatch);border:1px solid var(--status-unknown-solid)}._verdict_1clua_126{font-size:var(--text-lg-size);line-height:var(--text-lg-line);font-weight:var(--font-weight-medium);color:var(--text-primary);font-variant-numeric:tabular-nums;margin:0}._verdictPart_1clua_135[data-tone=danger]{color:var(--status-danger-fg)}._verdictPart_1clua_135[data-tone=warning]{color:var(--status-warning-fg)}._verdictPart_1clua_135[data-tone=success]{color:var(--status-success-fg)}._verdictPart_1clua_135[data-tone=unknown]{color:var(--status-unknown-fg);font-style:italic}._verdictSep_1clua_149{color:var(--text-tertiary)}._since_1clua_153{align-items:center;gap:var(--space-2);font-size:var(--text-xs-size);line-height:var(--text-xs-line);flex-wrap:wrap;display:flex}._sinceLead_1clua_162{color:var(--text-tertiary)}._sinceChip_1clua_166{padding:1px var(--space-2);border-radius:var(--radius-full);background:var(--status-neutral-bg);color:var(--status-neutral-fg);font-variant-numeric:tabular-nums;align-items:center;display:inline-flex}._sinceChip_1clua_166[data-tone=success]{background:var(--status-success-bg);color:var(--status-success-fg)}._sinceChip_1clua_166[data-tone=danger]{background:var(--status-danger-bg);color:var(--status-danger-fg)}._sinceChip_1clua_166[data-tone=warning]{background:var(--status-warning-bg);color:var(--status-warning-fg)}._sinceChip_1clua_166[data-tone=info]{background:var(--status-info-bg);color:var(--status-info-fg)}._actionNote_1clua_192,._actionError_1clua_193{padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);font-size:var(--text-sm-size);line-height:var(--text-sm-line);margin:0}._actionNote_1clua_192{background:var(--bg-hover);color:var(--text-secondary)}._actionError_1clua_193{align-items:baseline;gap:var(--space-3);background:var(--status-danger-bg);color:var(--status-danger-fg);display:flex}._linkButton_1clua_88,._moreLink_1clua_89{align-items:center;gap:var(--space-1);color:var(--text-link);font:inherit;font-size:var(--text-xs-size);line-height:var(--text-xs-line);cursor:pointer;white-space:nowrap;background:0 0;border:0;padding:0;text-decoration:none;display:inline-flex}._linkButton_1clua_88:hover,._moreLink_1clua_89:hover{text-decoration:underline}._moreLink_1clua_89{align-self:flex-start}._moreLink_1clua_89:disabled{color:var(--text-disabled);cursor:default;text-decoration:none}._kbd_1clua_247{padding:0 var(--space-1);border:1px solid var(--border-subtle);border-radius:var(--radius-xs);color:var(--text-tertiary);font-family:var(--font-mono);font-size:var(--text-2xs-size)}._muted_1clua_256{color:var(--text-tertiary);font-size:var(--text-xs-size);line-height:var(--text-xs-line);margin:0}._mono_1clua_263{font-family:var(--font-mono);font-size:var(--text-xs-size)}._num_1clua_268{text-align:right;font-variant-numeric:tabular-nums}._confirmBody_1clua_273{color:var(--text-secondary);font-size:var(--text-sm-size);line-height:var(--text-sm-line-relaxed)}._confirmActions_1clua_279{justify-content:flex-end;gap:var(--space-2);margin-top:var(--space-5);display:flex}._needsList_1clua_287{flex-direction:column;margin:0;padding:0;list-style:none;display:flex}._needsRow_1clua_295{align-items:start;gap:var(--space-2) var(--space-3);padding:var(--space-2) 0;border-top:1px solid var(--border-subtle);grid-template-columns:auto minmax(0,1fr) auto;display:grid}._needsRow_1clua_295:first-child{border-top:0;padding-top:0}._sevDot_1clua_309{border-radius:var(--radius-full);background:var(--status-info-solid);width:8px;height:8px;margin-top:6px}._sevDot_1clua_309[data-severity=warn]{background:var(--status-warning-solid)}._sevDot_1clua_309[data-severity=high]{background:var(--status-danger-solid)}._needsText_1clua_323{flex-direction:column;gap:2px;min-width:0;display:flex}._needsKind_1clua_331{font-family:var(--font-display);font-size:var(--text-2xs-size);line-height:var(--text-2xs-line);letter-spacing:var(--tracking-label);text-transform:uppercase;color:var(--text-secondary)}._needsTitle_1clua_343{-webkit-line-clamp:2;line-clamp:2;color:var(--text-primary);font-size:var(--text-sm-size);line-height:var(--text-sm-line);overflow-wrap:break-word;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}._needsDetail_1clua_355{color:var(--text-secondary);font-size:var(--text-xs-size);line-height:var(--text-xs-line);overflow-wrap:anywhere}._needsMeta_1clua_363{gap:0 var(--space-1);color:var(--text-tertiary);font-size:var(--text-xs-size);line-height:var(--text-xs-line);flex-wrap:wrap;display:flex}._needsRepo_1clua_372{font-weight:var(--font-weight-medium)}._needsActions_1clua_376{justify-content:flex-end;align-items:center;gap:var(--space-2);flex-wrap:wrap;display:flex}._allClear_1clua_384{gap:var(--space-1);padding:var(--space-4) 0;flex-direction:column;display:flex}._allClearTitle_1clua_391{font-family:var(--font-display);font-size:var(--text-md-size);line-height:var(--text-md-line);font-weight:var(--font-weight-semibold);color:var(--text-primary)}._allClearBody_1clua_399{color:var(--text-secondary);font-size:var(--text-sm-size)}._memo_1clua_405{gap:var(--space-2);flex-direction:column;margin:0;display:flex}._memoRow_1clua_412{gap:var(--space-3);grid-template-columns:96px minmax(0,1fr);align-items:baseline;display:grid}._memoRow_1clua_412 dd{margin:0}._memoText_1clua_423{color:var(--text-primary);font-size:var(--text-base-size);line-height:var(--text-base-line)}._delta_1clua_429{margin-left:var(--space-2);padding:0 var(--space-2);border-radius:var(--radius-full);background:var(--status-info-bg);color:var(--status-info-fg);font-size:var(--text-xs-size);line-height:var(--text-xs-line-relaxed);font-variant-numeric:tabular-nums;white-space:nowrap;display:inline-block}._dryRun_1clua_442{font-family:var(--font-display);padding:0 var(--space-2);border:1px dashed var(--border-strong);border-radius:var(--radius-full);color:var(--text-secondary);font-size:var(--text-2xs-size);line-height:var(--text-xs-line);text-transform:uppercase;letter-spacing:var(--tracking-label)}._actionList_1clua_454{border-top:1px solid var(--border-subtle);flex-direction:column;margin:0;padding:0;list-style:none;display:flex}._actionRow_1clua_463{gap:var(--space-3);padding:var(--space-2) 0;border-bottom:1px solid var(--border-subtle);grid-template-columns:auto minmax(0,1fr) auto;align-items:center;display:grid}._actionRow_1clua_463[data-status=vetoed] ._actionSummary_1clua_472{color:var(--text-tertiary);text-decoration:line-through}._classBadge_1clua_477{border:1px solid var(--border-default);border-radius:var(--radius-sm);width:20px;height:20px;color:var(--text-secondary);font-family:var(--font-display);font-size:var(--text-2xs-size);font-weight:var(--font-weight-semibold);justify-content:center;align-items:center;display:inline-flex}._classBadge_1clua_477[data-class=B]{border-color:var(--status-warning-solid);color:var(--status-warning-fg)}._classBadge_1clua_477[data-class=C]{border-style:dashed}._actionText_1clua_500{flex-direction:column;min-width:0;display:flex}._actionSummary_1clua_472{color:var(--text-primary);font-size:var(--text-sm-size);line-height:var(--text-sm-line);overflow-wrap:anywhere}._actionWhy_1clua_513{color:var(--text-tertiary);font-size:var(--text-xs-size);line-height:var(--text-xs-line);overflow-wrap:anywhere}._actionState_1clua_520{align-items:center;gap:var(--space-2);display:inline-flex}._statusWord_1clua_526{color:var(--text-tertiary);font-size:var(--text-xs-size);white-space:nowrap}._statusWord_1clua_526[data-status=escalated]{color:var(--status-warning-fg)}._statusWord_1clua_526[data-status=failed],._statusWord_1clua_526[data-status=refused]{color:var(--status-danger-fg)}._vetoChip_1clua_541{border:1px solid var(--border-default)}._ring_1clua_545{align-items:center;gap:var(--space-1);color:var(--status-warning-fg);font-size:var(--text-xs-size);font-variant-numeric:tabular-nums;white-space:nowrap;display:inline-flex}._ringTrack_1clua_555{fill:none;stroke:var(--border-subtle);stroke-width:2.5px}._ringFill_1clua_561{fill:none;stroke:var(--status-warning-solid);stroke-width:2.5px;stroke-linecap:round}._ringText_1clua_568{min-width:4ch}._kpis_1clua_573{gap:var(--surface-gap);grid-template-columns:repeat(5,minmax(0,1fr));align-items:stretch;display:grid}[data-viewport=medium] ._kpis_1clua_573{grid-template-columns:repeat(6,minmax(0,1fr))}[data-viewport=medium] ._kpis_1clua_573>*{grid-column:span 2}[data-viewport=medium] ._kpis_1clua_573>:nth-child(3n+1):nth-last-child(2),[data-viewport=medium] ._kpis_1clua_573>:nth-child(3n+2):last-child{grid-column:span 3}[data-viewport=compact] ._kpis_1clua_573{grid-template-columns:repeat(2,minmax(0,1fr))}._burnGrid_1clua_602{gap:var(--surface-gap);grid-template-columns:repeat(auto-fill,minmax(min(100%,320px),1fr));align-items:start;display:grid}._burnStrip_1clua_610{gap:var(--space-3);overscroll-behavior-x:contain;scroll-snap-type:x mandatory;padding-bottom:var(--space-1);grid-auto-columns:86%;grid-auto-flow:column;display:grid;overflow-x:auto}._burnStrip_1clua_610>._burnItem_1clua_621{scroll-snap-align:start}._burnItem_1clua_621{min-width:0}._freeSeat_1clua_629{gap:var(--space-2);padding:var(--card-pad);border:1px solid var(--border-subtle);border-radius:var(--radius-lg);background:var(--bg-surface);flex-direction:column;display:flex}._freeHead_1clua_639{align-items:center;gap:var(--space-2);display:inline-flex}._freeTitle_1clua_645{font-size:var(--text-sm-size);line-height:var(--text-sm-line);font-weight:var(--font-weight-semibold);color:var(--text-primary)}._freeValue_1clua_652{font-size:var(--text-2xl-size);line-height:var(--text-2xl-line);font-weight:var(--font-weight-semibold);color:var(--text-secondary)}._freeBody_1clua_659{color:var(--text-tertiary);font-size:var(--text-xs-size);line-height:var(--text-xs-line-relaxed)}._scope_1clua_666{gap:var(--space-5);flex-direction:column;display:flex}._scopeBlock_1clua_672{gap:var(--space-2);flex-direction:column;display:flex}._scopeLead_1clua_678{color:var(--text-primary);font-size:var(--text-base-size);line-height:var(--text-base-line);margin:0}._scopeMeta_1clua_685{color:var(--text-tertiary);font-size:var(--text-xs-size);line-height:var(--text-xs-line-relaxed);margin:0}._scopeTable_1clua_692{border-collapse:collapse;width:100%;font-size:var(--text-xs-size)}._scopeTable_1clua_692 th{padding:var(--space-1) var(--space-2) var(--space-1) 0;border-bottom:1px solid var(--border-subtle);color:var(--text-tertiary);font-weight:var(--font-weight-medium);text-align:left}._scopeTable_1clua_692 td{padding:var(--space-1) var(--space-2) var(--space-1) 0;border-bottom:1px solid var(--border-subtle);color:var(--text-primary)}._scopeList_1clua_712{padding-left:var(--space-4);color:var(--text-secondary);font-size:var(--text-xs-size);line-height:var(--text-xs-line-relaxed);margin:0}._ladder_1clua_720{gap:var(--space-2);counter-reset:rung;font-size:var(--text-xs-size);line-height:var(--text-xs-line-relaxed);color:var(--text-secondary);flex-direction:column;margin:0;padding:0;list-style:none;display:flex}._ladder_1clua_720 li{gap:var(--space-2);grid-template-columns:56px minmax(0,1fr);display:grid}._ladderId_1clua_739{font-family:var(--font-mono);color:var(--text-primary)}._sheetFooter_1clua_744{gap:var(--space-3);flex-direction:column;display:flex}._sheetFootnote_1clua_750{color:var(--text-tertiary);font-size:var(--text-xs-size);line-height:var(--text-xs-line-relaxed);margin:0}._sheetButtons_1clua_757{justify-content:flex-end;gap:var(--space-2);display:flex}@media (prefers-reduced-motion:reduce){button._pill_1clua_39,button._chip_1clua_59{transition:none}}._autonomyPlaceholder_1clua_771{border:1px solid var(--border-subtle);border-radius:var(--radius-lg);background:var(--bg-surface);min-height:132px}
@@ -1,2 +1,2 @@
1
- import{Ht as e}from"./VerseConsoleApp-BCY5uSok.js";var t={name:`name`,command:`command`,args:`args`,env:`env`,sourceRef:`sourceRef`},n={seatId:`seatId`,label:`label`,engine:`engine`,accountId:`accountId`,servers:`servers`,reason:`reason`,configFile:`configFile`,configFormat:`configFormat`,notes:`notes`},r={servers:`servers`,configured:`configured`,note:`note`},i={sampledAt:`sampledAt`,seats:`seats`,machine:`machine`,scope:`scope`,notes:`notes`},a={accountId:`accountId`,label:`label`,provider:`provider`,authentication:`authentication`,state:`state`,planType:`planType`,reason:`reason`,version:`version`,pinnedVersion:`pinnedVersion`,versionState:`versionState`,usageBlockedByPin:`usageBlockedByPin`,notes:`notes`},o={sampledAt:`sampledAt`,accounts:`accounts`,driftDetected:`driftDetected`,notes:`notes`},s={available:`available`,pinned:`pinned`,aliasRef:`aliasRef`,tenantRef:`tenantRef`,principalRef:`principalRef`,reason:`reason`};function c(e){return typeof e==`object`&&e&&!Array.isArray(e)?e:null}function l(e){return typeof e==`string`?e:null}function u(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`):[]}function d(e){return e===!0}function f(e){let n=c(e);if(n===null)return null;let r=l(n[t.name]),i=l(n[t.command]);if(r===null||i===null)return null;let a=null,o=c(n[t.env]);if(o!==null){let e=Object.keys(o);if(e.length>0){a={};for(let t of e)a[t]=`<set>`}}return{name:r,command:i,args:u(n[t.args]),env:a,sourceRef:l(n[t.sourceRef])??`(unknown source)`}}function p(e){let t=c(e);if(t===null)return null;let r=l(t[n.seatId]);if(r===null)return null;let i=Array.isArray(t[n.servers])?t[n.servers].map(f).filter(e=>e!==null):[];return{seatId:r,label:l(t[n.label])??r,engine:l(t[n.engine])??`unknown`,accountId:l(t[n.accountId])??r,servers:i,reason:l(t[n.reason])??`unknown`,configFile:l(t[n.configFile]),configFormat:l(t[n.configFormat]),notes:u(t[n.notes])}}function m(e){let t=c(e);return t===null?null:{available:d(t[s.available]),pinned:d(t[s.pinned]),aliasRef:l(t[s.aliasRef]),tenantRef:l(t[s.tenantRef]),principalRef:l(t[s.principalRef]),reason:l(t[s.reason])??`unknown`}}function h(e){let t=c(e);if(t===null||!Array.isArray(t[i.seats]))return null;let n=c(t[i.machine]),a=n!==null&&Array.isArray(n[r.servers])?n[r.servers].map(f).filter(e=>e!==null):[];return{sampledAt:l(t[i.sampledAt]),seats:t[i.seats].map(p).filter(e=>e!==null),machine:{servers:a,configured:n===null?a.length>0:d(n[r.configured]),note:(n===null?null:l(n[r.note]))??``},scope:m(t[i.scope]),notes:u(t[i.notes])}}function g(e){let t=c(e);if(t===null)return null;let n=l(t[a.accountId]);return n===null?null:{accountId:n,label:l(t[a.label])??n,provider:l(t[a.provider])??`unknown`,authentication:l(t[a.authentication])??`unknown`,state:l(t[a.state])??`unknown`,planType:l(t[a.planType]),reason:l(t[a.reason])??`unknown`,version:l(t[a.version]),pinnedVersion:l(t[a.pinnedVersion]),versionState:l(t[a.versionState])??`unverified`,usageBlockedByPin:d(t[a.usageBlockedByPin]),notes:u(t[a.notes])}}function _(e){let t=c(e);if(t===null||!Array.isArray(t[o.accounts]))return null;let n=t[o.accounts].map(g).filter(e=>e!==null);return{sampledAt:l(t[o.sampledAt]),accounts:n,driftDetected:d(t[o.driftDetected])||n.some(e=>e.versionState===`drift`),notes:u(t[o.notes])}}var v={"mcp-seat-isolated-by-adapter":`Verse launches every turn on this seat with an empty MCP configuration, so it loads no MCP servers at all — whatever is configured elsewhere on this machine.`,"mcp-account-config-absent":`This account has no MCP configuration file of its own, so it starts with none.`,"mcp-account-config-not-json":`This account keeps its MCP servers in a TOML config that the provider CLI reads directly. Hub does not parse or rewrite it, so it cannot list what is in there.`,"mcp-account-config-read":`Read from this account's own private configuration.`,"mcp-account-config-unreadable":`This account's configuration could not be read.`,"mcp-account-profile-unresolved":`This account's private profile could not be located, so Hub cannot say what it would load.`},y={"mcp-scope-locus-unavailable":`Locus is not reachable on this machine, so writes are not attributable to a tenant.`,"mcp-scope-unpinned":`Locus is running but nothing is pinned, so there is no tenant to scope a write to.`,"mcp-scope-seal-unverified":`Locus reports a pin whose seal did not verify. Fix the pin before writing anything.`,"mcp-scope-expired":`The Locus pin has expired.`,"mcp-scope-pinned":`Writes are attributed to the pinned Locus tenant shown here.`};function b(e,t,n){return e[t]??n}var x={ok:`success`,warn:`warning`,error:`danger`,off:`off`,unknown:`neutral`};function S(e){return x[e]}var C=[`claude`,`codex`,`grok`,`local`];function w(e){return C.includes(e)?e:null}function T(e){let t=e.replace(/\/+$/,``),n=t.lastIndexOf(`/`);return n===-1?t:t.slice(n+1)||t}function E(e){if(!e)return[];let t=[],n=new Set,r=(e,r)=>{typeof e!=`string`||e.length===0||n.has(e)||(n.add(e),t.push({path:e,name:r??T(e)}))},i=[...e.sessions].sort((e,t)=>Date.parse(t.updatedAt)-Date.parse(e.updatedAt));for(let e of i)r(e.projectPath);for(let t of e.projects)r(t.path,t.name);return t}function D(e){let t=[];for(let n of e){if(n.engine!==`local`)continue;let e=n.models[0]?.id??(n.id.startsWith(`local:`)?n.id.slice(6):null);e&&!t.includes(e)&&t.push(e)}return t}function O(e,t){return t.via===`ollama`?e.ollamaLaunch?t.model?[...e.ollamaLaunch,`--model`,t.model]:[...e.ollamaLaunch]:null:e.actions.find(e=>e.kind===`launch`)?.command??null}var k=new Set([`spent`,`not-checked`,`unavailable`]);function A(e,t){if(e.kind===`local`)return[];let n=[],r=e.connection,i=e.signedOut||r!==null&&(r.connection===`signed-out`||r.connection===`expiring`||r.fixKind===`reauth`);i&&n.push({kind:`reconnect`,label:`Reconnect`,command:null,primary:!0});let a=!i&&t!=null&&k.has(t.kind);return a&&n.push({kind:`check-again`,label:`Check again`,command:null,primary:!0}),r!==null&&r.fixKind!==`reauth`&&r.fixKind!==`none`&&r.fixCommand!==null&&n.push({kind:`fix`,label:`Fix`,command:r.fixCommand,primary:!i&&!a}),n.push({kind:`edit-budget`,label:`Edit budget`,command:null,primary:!1}),n}function j(t){return t.seats.map(t=>{let n=w(t.engine),r=t.reason===`mcp-seat-isolated-by-adapter`,i=t.servers.length;return{seatId:t.seatId,label:t.label,engine:n,monogram:n?e[n]:t.label.slice(0,1).toUpperCase(),servers:t.servers,loads:i>0?`loads ${i} server${i===1?``:`s`}`:r?`loads none — isolated by Verse`:`loads none`,isolated:r,sentence:b(v,t.reason,`Hub cannot say what this seat would load.`),reason:t.reason,notes:t.notes}})}function M(e){let t=[{id:`hub`,label:`Hub gateway registry`,disabledReason:null}];for(let n of e?.seats??[]){if(n.seatId===`local`)continue;let e=n.configFormat===`toml`||n.reason===`mcp-account-config-not-json`;t.push({id:`account:${n.accountId}`,label:`${n.label} (${n.engine})`,disabledReason:e?`Keeps its MCP servers in TOML, which Hub does not rewrite.`:null})}return t}function N(e){let t=[],n=``,r=null,i=!1;for(let a of e){if(r){a===r?r=null:n+=a;continue}if(a===`"`||a===`'`){r=a,i=!0;continue}if(/\s/.test(a)){(i||n.length>0)&&t.push(n),n=``,i=!1;continue}n+=a}return(i||n.length>0)&&t.push(n),t}function P(e){let t={};for(let n of e.split(/\r?\n/)){let e=n.trim();if(e.length===0||e.startsWith(`#`))continue;let r=e.indexOf(`=`),i=r===-1?``:e.slice(0,r).trim();if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(i))return{ok:!1,error:`“${e.slice(0,40)}” is not KEY=value.`};t[i]=e.slice(r+1)}return{ok:!0,env:t}}export{D as a,P as c,f as d,_ as f,E as i,N as l,b as m,S as n,j as o,h as p,O as r,M as s,A as t,y as u};
2
- //# sourceMappingURL=apps-model-DlwnfqwJ.js.map
1
+ import{Ht as e}from"./VerseConsoleApp-CWU6R3By.js";var t={name:`name`,command:`command`,args:`args`,env:`env`,sourceRef:`sourceRef`},n={seatId:`seatId`,label:`label`,engine:`engine`,accountId:`accountId`,servers:`servers`,reason:`reason`,configFile:`configFile`,configFormat:`configFormat`,notes:`notes`},r={servers:`servers`,configured:`configured`,note:`note`},i={sampledAt:`sampledAt`,seats:`seats`,machine:`machine`,scope:`scope`,notes:`notes`},a={accountId:`accountId`,label:`label`,provider:`provider`,authentication:`authentication`,state:`state`,planType:`planType`,reason:`reason`,version:`version`,pinnedVersion:`pinnedVersion`,versionState:`versionState`,usageBlockedByPin:`usageBlockedByPin`,notes:`notes`},o={sampledAt:`sampledAt`,accounts:`accounts`,driftDetected:`driftDetected`,notes:`notes`},s={available:`available`,pinned:`pinned`,aliasRef:`aliasRef`,tenantRef:`tenantRef`,principalRef:`principalRef`,reason:`reason`};function c(e){return typeof e==`object`&&e&&!Array.isArray(e)?e:null}function l(e){return typeof e==`string`?e:null}function u(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`):[]}function d(e){return e===!0}function f(e){let n=c(e);if(n===null)return null;let r=l(n[t.name]),i=l(n[t.command]);if(r===null||i===null)return null;let a=null,o=c(n[t.env]);if(o!==null){let e=Object.keys(o);if(e.length>0){a={};for(let t of e)a[t]=`<set>`}}return{name:r,command:i,args:u(n[t.args]),env:a,sourceRef:l(n[t.sourceRef])??`(unknown source)`}}function p(e){let t=c(e);if(t===null)return null;let r=l(t[n.seatId]);if(r===null)return null;let i=Array.isArray(t[n.servers])?t[n.servers].map(f).filter(e=>e!==null):[];return{seatId:r,label:l(t[n.label])??r,engine:l(t[n.engine])??`unknown`,accountId:l(t[n.accountId])??r,servers:i,reason:l(t[n.reason])??`unknown`,configFile:l(t[n.configFile]),configFormat:l(t[n.configFormat]),notes:u(t[n.notes])}}function m(e){let t=c(e);return t===null?null:{available:d(t[s.available]),pinned:d(t[s.pinned]),aliasRef:l(t[s.aliasRef]),tenantRef:l(t[s.tenantRef]),principalRef:l(t[s.principalRef]),reason:l(t[s.reason])??`unknown`}}function h(e){let t=c(e);if(t===null||!Array.isArray(t[i.seats]))return null;let n=c(t[i.machine]),a=n!==null&&Array.isArray(n[r.servers])?n[r.servers].map(f).filter(e=>e!==null):[];return{sampledAt:l(t[i.sampledAt]),seats:t[i.seats].map(p).filter(e=>e!==null),machine:{servers:a,configured:n===null?a.length>0:d(n[r.configured]),note:(n===null?null:l(n[r.note]))??``},scope:m(t[i.scope]),notes:u(t[i.notes])}}function g(e){let t=c(e);if(t===null)return null;let n=l(t[a.accountId]);return n===null?null:{accountId:n,label:l(t[a.label])??n,provider:l(t[a.provider])??`unknown`,authentication:l(t[a.authentication])??`unknown`,state:l(t[a.state])??`unknown`,planType:l(t[a.planType]),reason:l(t[a.reason])??`unknown`,version:l(t[a.version]),pinnedVersion:l(t[a.pinnedVersion]),versionState:l(t[a.versionState])??`unverified`,usageBlockedByPin:d(t[a.usageBlockedByPin]),notes:u(t[a.notes])}}function _(e){let t=c(e);if(t===null||!Array.isArray(t[o.accounts]))return null;let n=t[o.accounts].map(g).filter(e=>e!==null);return{sampledAt:l(t[o.sampledAt]),accounts:n,driftDetected:d(t[o.driftDetected])||n.some(e=>e.versionState===`drift`),notes:u(t[o.notes])}}var v={"mcp-seat-isolated-by-adapter":`Verse launches every turn on this seat with an empty MCP configuration, so it loads no MCP servers at all — whatever is configured elsewhere on this machine.`,"mcp-account-config-absent":`This account has no MCP configuration file of its own, so it starts with none.`,"mcp-account-config-not-json":`This account keeps its MCP servers in a TOML config that the provider CLI reads directly. Hub does not parse or rewrite it, so it cannot list what is in there.`,"mcp-account-config-read":`Read from this account's own private configuration.`,"mcp-account-config-unreadable":`This account's configuration could not be read.`,"mcp-account-profile-unresolved":`This account's private profile could not be located, so Hub cannot say what it would load.`},y={"mcp-scope-locus-unavailable":`Locus is not reachable on this machine, so writes are not attributable to a tenant.`,"mcp-scope-unpinned":`Locus is running but nothing is pinned, so there is no tenant to scope a write to.`,"mcp-scope-seal-unverified":`Locus reports a pin whose seal did not verify. Fix the pin before writing anything.`,"mcp-scope-expired":`The Locus pin has expired.`,"mcp-scope-pinned":`Writes are attributed to the pinned Locus tenant shown here.`};function b(e,t,n){return e[t]??n}var x={ok:`success`,warn:`warning`,error:`danger`,off:`off`,unknown:`neutral`};function S(e){return x[e]}var C=[`claude`,`codex`,`grok`,`local`];function w(e){return C.includes(e)?e:null}function T(e){let t=e.replace(/\/+$/,``),n=t.lastIndexOf(`/`);return n===-1?t:t.slice(n+1)||t}function E(e){if(!e)return[];let t=[],n=new Set,r=(e,r)=>{typeof e!=`string`||e.length===0||n.has(e)||(n.add(e),t.push({path:e,name:r??T(e)}))},i=[...e.sessions].sort((e,t)=>Date.parse(t.updatedAt)-Date.parse(e.updatedAt));for(let e of i)r(e.projectPath);for(let t of e.projects)r(t.path,t.name);return t}function D(e){let t=[];for(let n of e){if(n.engine!==`local`)continue;let e=n.models[0]?.id??(n.id.startsWith(`local:`)?n.id.slice(6):null);e&&!t.includes(e)&&t.push(e)}return t}function O(e,t){return t.via===`ollama`?e.ollamaLaunch?t.model?[...e.ollamaLaunch,`--model`,t.model]:[...e.ollamaLaunch]:null:e.actions.find(e=>e.kind===`launch`)?.command??null}var k=new Set([`spent`,`not-checked`,`unavailable`]);function A(e,t){if(e.kind===`local`)return[];let n=[],r=e.connection,i=e.signedOut||r!==null&&(r.connection===`signed-out`||r.connection===`expiring`||r.fixKind===`reauth`);i&&n.push({kind:`reconnect`,label:`Reconnect`,command:null,primary:!0});let a=!i&&t!=null&&k.has(t.kind);return a&&n.push({kind:`check-again`,label:`Check again`,command:null,primary:!0}),r!==null&&r.fixKind!==`reauth`&&r.fixKind!==`none`&&r.fixCommand!==null&&n.push({kind:`fix`,label:`Fix`,command:r.fixCommand,primary:!i&&!a}),n.push({kind:`edit-budget`,label:`Edit budget`,command:null,primary:!1}),n}function j(t){return t.seats.map(t=>{let n=w(t.engine),r=t.reason===`mcp-seat-isolated-by-adapter`,i=t.servers.length;return{seatId:t.seatId,label:t.label,engine:n,monogram:n?e[n]:t.label.slice(0,1).toUpperCase(),servers:t.servers,loads:i>0?`loads ${i} server${i===1?``:`s`}`:r?`loads none — isolated by Verse`:`loads none`,isolated:r,sentence:b(v,t.reason,`Hub cannot say what this seat would load.`),reason:t.reason,notes:t.notes}})}function M(e){let t=[{id:`hub`,label:`Hub gateway registry`,disabledReason:null}];for(let n of e?.seats??[]){if(n.seatId===`local`)continue;let e=n.configFormat===`toml`||n.reason===`mcp-account-config-not-json`;t.push({id:`account:${n.accountId}`,label:`${n.label} (${n.engine})`,disabledReason:e?`Keeps its MCP servers in TOML, which Hub does not rewrite.`:null})}return t}function N(e){let t=[],n=``,r=null,i=!1;for(let a of e){if(r){a===r?r=null:n+=a;continue}if(a===`"`||a===`'`){r=a,i=!0;continue}if(/\s/.test(a)){(i||n.length>0)&&t.push(n),n=``,i=!1;continue}n+=a}return(i||n.length>0)&&t.push(n),t}function P(e){let t={};for(let n of e.split(/\r?\n/)){let e=n.trim();if(e.length===0||e.startsWith(`#`))continue;let r=e.indexOf(`=`),i=r===-1?``:e.slice(0,r).trim();if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(i))return{ok:!1,error:`“${e.slice(0,40)}” is not KEY=value.`};t[i]=e.slice(r+1)}return{ok:!0,env:t}}export{D as a,P as c,f as d,_ as f,E as i,N as l,b as m,S as n,j as o,h as p,O as r,M as s,A as t,y as u};
2
+ //# sourceMappingURL=apps-model-Du02KhAf.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"apps-model-DlwnfqwJ.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/mcp/mcp-contract.ts","../../../../../../src/web-ui/routes/verse/apps/apps-model.ts"],"sourcesContent":["/**\n * routes/verse/mcp/mcp-contract.ts — the wire seam for MCP management.\n *\n * Same posture as routes/verse/usage/usage-contract.ts, for the same two\n * reasons:\n *\n * 1. EVERY import from src/core here MUST be type-only. `core/verse/\n * mcp-seat-view.ts` pulls `node:fs` and `node:os`; a VALUE import of even\n * one constant drags that graph into the browser bundle and `vite build`\n * fails. Type-only imports are erased, so the seam guards below cost\n * nothing at runtime.\n * 2. Nothing is CAST. Every read goes through a structural narrower, so a\n * field rename in src/core degrades this panel to an honest \"unknown\"\n * instead of throwing at render time — and the `WIRE_*_KEYS` blocks make\n * that rename fail `npm run typecheck:web` here, at the seam, first.\n *\n * SECURITY: the server already redacts every env value to '<set>' via\n * `redactEnv` and publishes config files as home-relative refs. This module\n * is the client-side backstop on top of that: {@link narrowServer} FORCES\n * every env value to '<set>' whatever arrived, so a server that ever\n * regressed could not print a secret through this panel.\n *\n * Pure: no React, no I/O.\n */\nimport type {\n VerseMcpMachineRegistry,\n VerseMcpSeatView,\n VerseMcpServerView,\n VerseMcpSnapshot,\n} from '../../../../core/verse/mcp-seat-view.js';\nimport type { VerseMcpScope } from '../../../../core/verse/mcp-scope.js';\nimport type {\n VerseAccountCliHealth,\n VerseCliHealthSnapshot,\n} from '../../../../core/verse/mcp-cli-health.js';\n\n// ---------------------------------------------------------------------------\n// Seam contract — compile-time only, zero runtime cost.\n// ---------------------------------------------------------------------------\n\nconst WIRE_SERVER_KEYS = {\n name: 'name',\n command: 'command',\n args: 'args',\n env: 'env',\n sourceRef: 'sourceRef',\n} as const satisfies Record<string, keyof VerseMcpServerView>;\n\nconst WIRE_SEAT_KEYS = {\n seatId: 'seatId',\n label: 'label',\n engine: 'engine',\n accountId: 'accountId',\n servers: 'servers',\n reason: 'reason',\n configFile: 'configFile',\n configFormat: 'configFormat',\n notes: 'notes',\n} as const satisfies Record<string, keyof VerseMcpSeatView>;\n\nconst WIRE_MACHINE_KEYS = {\n servers: 'servers',\n configured: 'configured',\n note: 'note',\n} as const satisfies Record<string, keyof VerseMcpMachineRegistry>;\n\nconst WIRE_SNAPSHOT_KEYS = {\n sampledAt: 'sampledAt',\n seats: 'seats',\n machine: 'machine',\n scope: 'scope',\n notes: 'notes',\n} as const satisfies Record<string, keyof VerseMcpSnapshot>;\n\nconst WIRE_HEALTH_KEYS = {\n accountId: 'accountId',\n label: 'label',\n provider: 'provider',\n authentication: 'authentication',\n state: 'state',\n planType: 'planType',\n reason: 'reason',\n version: 'version',\n pinnedVersion: 'pinnedVersion',\n versionState: 'versionState',\n usageBlockedByPin: 'usageBlockedByPin',\n notes: 'notes',\n} as const satisfies Record<string, keyof VerseAccountCliHealth>;\n\nconst WIRE_HEALTH_SNAPSHOT_KEYS = {\n sampledAt: 'sampledAt',\n accounts: 'accounts',\n driftDetected: 'driftDetected',\n notes: 'notes',\n} as const satisfies Record<string, keyof VerseCliHealthSnapshot>;\n\nconst WIRE_SCOPE_KEYS = {\n available: 'available',\n pinned: 'pinned',\n aliasRef: 'aliasRef',\n tenantRef: 'tenantRef',\n principalRef: 'principalRef',\n reason: 'reason',\n} as const satisfies Record<string, keyof VerseMcpScope>;\n\n// ---------------------------------------------------------------------------\n// Display shapes\n// ---------------------------------------------------------------------------\n\nexport interface McpServer {\n name: string;\n command: string;\n args: string[];\n /** Keys only. Every value is '<set>' — forced here, not merely trusted. */\n env: Record<string, string> | null;\n sourceRef: string;\n}\n\nexport interface McpSeat {\n seatId: string;\n label: string;\n engine: string;\n accountId: string;\n servers: McpServer[];\n reason: string;\n configFile: string | null;\n configFormat: string | null;\n notes: string[];\n}\n\nexport interface McpScope {\n available: boolean;\n pinned: boolean;\n aliasRef: string | null;\n tenantRef: string | null;\n principalRef: string | null;\n reason: string;\n}\n\nexport interface McpSnapshot {\n sampledAt: string | null;\n seats: McpSeat[];\n machine: { servers: McpServer[]; configured: boolean; note: string };\n scope: McpScope | null;\n notes: string[];\n}\n\nexport interface CliHealthRow {\n accountId: string;\n label: string;\n provider: string;\n authentication: string;\n state: string;\n planType: string | null;\n reason: string;\n version: string | null;\n pinnedVersion: string | null;\n versionState: string;\n usageBlockedByPin: boolean;\n notes: string[];\n}\n\nexport interface CliHealthSnapshot {\n sampledAt: string | null;\n accounts: CliHealthRow[];\n driftDetected: boolean;\n notes: string[];\n}\n\n// ---------------------------------------------------------------------------\n// Narrowers\n// ---------------------------------------------------------------------------\n\nfunction record(value: unknown): Record<string, unknown> | null {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction text(value: unknown): string | null {\n return typeof value === 'string' ? value : null;\n}\n\nfunction strings(value: unknown): string[] {\n return Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string') : [];\n}\n\nfunction flag(value: unknown): boolean {\n return value === true;\n}\n\n/**\n * Narrow one server, forcing every env value to '<set>'.\n *\n * The redaction is re-applied rather than trusted. The server already did it;\n * doing it again here means no future server bug can turn this panel into a\n * secret printer, and it costs one map over at most a handful of keys.\n */\nexport function narrowServer(raw: unknown): McpServer | null {\n const row = record(raw);\n if (row === null) return null;\n const name = text(row[WIRE_SERVER_KEYS.name]);\n const command = text(row[WIRE_SERVER_KEYS.command]);\n if (name === null || command === null) return null;\n\n let env: Record<string, string> | null = null;\n const rawEnv = record(row[WIRE_SERVER_KEYS.env]);\n if (rawEnv !== null) {\n const keys = Object.keys(rawEnv);\n if (keys.length > 0) {\n env = {};\n for (const key of keys) env[key] = '<set>';\n }\n }\n\n return {\n name,\n command,\n args: strings(row[WIRE_SERVER_KEYS.args]),\n env,\n sourceRef: text(row[WIRE_SERVER_KEYS.sourceRef]) ?? '(unknown source)',\n };\n}\n\nfunction narrowSeat(raw: unknown): McpSeat | null {\n const row = record(raw);\n if (row === null) return null;\n const seatId = text(row[WIRE_SEAT_KEYS.seatId]);\n if (seatId === null) return null;\n const servers = Array.isArray(row[WIRE_SEAT_KEYS.servers])\n ? (row[WIRE_SEAT_KEYS.servers] as unknown[]).map(narrowServer).filter((s): s is McpServer => s !== null)\n : [];\n return {\n seatId,\n label: text(row[WIRE_SEAT_KEYS.label]) ?? seatId,\n engine: text(row[WIRE_SEAT_KEYS.engine]) ?? 'unknown',\n accountId: text(row[WIRE_SEAT_KEYS.accountId]) ?? seatId,\n servers,\n reason: text(row[WIRE_SEAT_KEYS.reason]) ?? 'unknown',\n configFile: text(row[WIRE_SEAT_KEYS.configFile]),\n configFormat: text(row[WIRE_SEAT_KEYS.configFormat]),\n notes: strings(row[WIRE_SEAT_KEYS.notes]),\n };\n}\n\nfunction narrowScope(raw: unknown): McpScope | null {\n const row = record(raw);\n if (row === null) return null;\n return {\n available: flag(row[WIRE_SCOPE_KEYS.available]),\n pinned: flag(row[WIRE_SCOPE_KEYS.pinned]),\n aliasRef: text(row[WIRE_SCOPE_KEYS.aliasRef]),\n tenantRef: text(row[WIRE_SCOPE_KEYS.tenantRef]),\n principalRef: text(row[WIRE_SCOPE_KEYS.principalRef]),\n reason: text(row[WIRE_SCOPE_KEYS.reason]) ?? 'unknown',\n };\n}\n\n/** Narrow GET /api/verse/mcp. Null when the body is not this shape at all. */\nexport function projectMcpSnapshot(raw: unknown): McpSnapshot | null {\n const row = record(raw);\n if (row === null) return null;\n if (!Array.isArray(row[WIRE_SNAPSHOT_KEYS.seats])) return null;\n\n const machine = record(row[WIRE_SNAPSHOT_KEYS.machine]);\n const machineServers = machine !== null && Array.isArray(machine[WIRE_MACHINE_KEYS.servers])\n ? (machine[WIRE_MACHINE_KEYS.servers] as unknown[]).map(narrowServer).filter((s): s is McpServer => s !== null)\n : [];\n\n return {\n sampledAt: text(row[WIRE_SNAPSHOT_KEYS.sampledAt]),\n seats: (row[WIRE_SNAPSHOT_KEYS.seats] as unknown[])\n .map(narrowSeat)\n .filter((s): s is McpSeat => s !== null),\n machine: {\n servers: machineServers,\n configured: machine !== null ? flag(machine[WIRE_MACHINE_KEYS.configured]) : machineServers.length > 0,\n note: (machine !== null ? text(machine[WIRE_MACHINE_KEYS.note]) : null) ?? '',\n },\n scope: narrowScope(row[WIRE_SNAPSHOT_KEYS.scope]),\n notes: strings(row[WIRE_SNAPSHOT_KEYS.notes]),\n };\n}\n\nfunction narrowHealthRow(raw: unknown): CliHealthRow | null {\n const row = record(raw);\n if (row === null) return null;\n const accountId = text(row[WIRE_HEALTH_KEYS.accountId]);\n if (accountId === null) return null;\n return {\n accountId,\n label: text(row[WIRE_HEALTH_KEYS.label]) ?? accountId,\n provider: text(row[WIRE_HEALTH_KEYS.provider]) ?? 'unknown',\n authentication: text(row[WIRE_HEALTH_KEYS.authentication]) ?? 'unknown',\n state: text(row[WIRE_HEALTH_KEYS.state]) ?? 'unknown',\n planType: text(row[WIRE_HEALTH_KEYS.planType]),\n reason: text(row[WIRE_HEALTH_KEYS.reason]) ?? 'unknown',\n // A missing version stays NULL. It is never coerced to a string, because\n // \"no reading\" and \"some version\" are different facts.\n version: text(row[WIRE_HEALTH_KEYS.version]),\n pinnedVersion: text(row[WIRE_HEALTH_KEYS.pinnedVersion]),\n versionState: text(row[WIRE_HEALTH_KEYS.versionState]) ?? 'unverified',\n usageBlockedByPin: flag(row[WIRE_HEALTH_KEYS.usageBlockedByPin]),\n notes: strings(row[WIRE_HEALTH_KEYS.notes]),\n };\n}\n\n/** Narrow GET /api/verse/mcp/cli-health. */\nexport function projectCliHealth(raw: unknown): CliHealthSnapshot | null {\n const row = record(raw);\n if (row === null) return null;\n if (!Array.isArray(row[WIRE_HEALTH_SNAPSHOT_KEYS.accounts])) return null;\n const accounts = (row[WIRE_HEALTH_SNAPSHOT_KEYS.accounts] as unknown[])\n .map(narrowHealthRow)\n .filter((a): a is CliHealthRow => a !== null);\n return {\n sampledAt: text(row[WIRE_HEALTH_SNAPSHOT_KEYS.sampledAt]),\n accounts,\n // Derived locally as well as read, so a server that forgot the flag still\n // renders the banner rather than silently hiding a drift.\n driftDetected:\n flag(row[WIRE_HEALTH_SNAPSHOT_KEYS.driftDetected]) ||\n accounts.some((account) => account.versionState === 'drift'),\n notes: strings(row[WIRE_HEALTH_SNAPSHOT_KEYS.notes]),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Copy for the machine-readable reasons this surface renders\n// ---------------------------------------------------------------------------\n\n/**\n * Plain language for each seat reason. The CODE is still shown next to the\n * sentence — it is the thing to search for — but it is never the sentence.\n * Same split `usage/accounts-model.ts` uses for probe reasons.\n */\nexport const SEAT_REASON_COPY: Record<string, string> = {\n 'mcp-seat-isolated-by-adapter':\n 'Verse launches every turn on this seat with an empty MCP configuration, so it loads no MCP '\n + 'servers at all — whatever is configured elsewhere on this machine.',\n 'mcp-account-config-absent':\n 'This account has no MCP configuration file of its own, so it starts with none.',\n 'mcp-account-config-not-json':\n 'This account keeps its MCP servers in a TOML config that the provider CLI reads directly. '\n + 'Hub does not parse or rewrite it, so it cannot list what is in there.',\n 'mcp-account-config-read':\n 'Read from this account\\'s own private configuration.',\n 'mcp-account-config-unreadable':\n 'This account\\'s configuration could not be read.',\n 'mcp-account-profile-unresolved':\n 'This account\\'s private profile could not be located, so Hub cannot say what it would load.',\n};\n\nexport const SCOPE_REASON_COPY: Record<string, string> = {\n 'mcp-scope-locus-unavailable':\n 'Locus is not reachable on this machine, so writes are not attributable to a tenant.',\n 'mcp-scope-unpinned':\n 'Locus is running but nothing is pinned, so there is no tenant to scope a write to.',\n 'mcp-scope-seal-unverified':\n 'Locus reports a pin whose seal did not verify. Fix the pin before writing anything.',\n 'mcp-scope-expired': 'The Locus pin has expired.',\n 'mcp-scope-pinned': 'Writes are attributed to the pinned Locus tenant shown here.',\n};\n\n/** Prose for a code, or the caller's own sentence. NEVER the raw code alone. */\nexport function reasonSentence(\n copy: Record<string, string>,\n reason: string,\n fallback: string,\n): string {\n return copy[reason] ?? fallback;\n}\n","/**\n * routes/verse/apps/apps-model.ts — pure view-model for Apps & Accounts.\n *\n * The page has five groups (SPEC-310C §4), from three kinds of source:\n * ACCOUNTS the shared capacity rows (usage/capacity-strip-model.ts)\n * plus the actions each seat needs (Reconnect / Check again / Fix / Edit budget);\n * DESKTOP, TERMINAL AGENTS, LOCAL MODELS GET /api/verse/apps, as served;\n * MCP SERVERS GET /api/verse/mcp (what each seat would ACTUALLY load).\n * Everything that decides a word, a tone or whether a control is enabled\n * lives here, so it is unit-tested without a DOM.\n *\n * Pure: no React, no I/O.\n */\nimport type { VerseAppHealthState, VerseAppRow } from '../../../../core/verse/workbench-types.js';\nimport { ENGINE_MONOGRAM } from '../../../../core/verse/workbench-types.js';\nimport type { VerseBootstrap, VerseEngine, VerseSeat } from '../../../data/api-types.js';\nimport type { HealthTone } from '../health/health-model.js';\nimport type { McpSeat, McpServer, McpSnapshot } from '../mcp/mcp-contract.js';\nimport { reasonSentence, SEAT_REASON_COPY } from '../mcp/mcp-contract.js';\nimport type { AccountStatus, CapacityRow } from '../usage/capacity-strip-model.js';\n\n/** SPEC-310C §4 order. */\nexport const APPS_GROUP_ORDER = ['accounts', 'desktop', 'terminal-agents', 'local-models', 'mcp-servers'] as const;\nexport type AppsGroupId = (typeof APPS_GROUP_ORDER)[number];\n\nexport const APPS_GROUP_TITLE: Readonly<Record<AppsGroupId, string>> = {\n accounts: 'Accounts',\n desktop: 'Desktop',\n 'terminal-agents': 'Terminal agents',\n 'local-models': 'Local models',\n 'mcp-servers': 'MCP servers',\n};\n\nconst HEALTH_TONE: Readonly<Record<VerseAppHealthState, HealthTone | 'off'>> = {\n ok: 'success',\n warn: 'warning',\n error: 'danger',\n off: 'off',\n unknown: 'neutral',\n};\n\n/** A row's dot tone. `off` is its own quiet state (not installed, switched off) — never a fault. */\nexport function appHealthTone(state: VerseAppHealthState): HealthTone | 'off' {\n return HEALTH_TONE[state];\n}\n\nconst VERSE_ENGINES: readonly VerseEngine[] = ['claude', 'codex', 'grok', 'local'];\n\nexport function asEngine(value: string): VerseEngine | null {\n return (VERSE_ENGINES as readonly string[]).includes(value) ? (value as VerseEngine) : null;\n}\n\n// ---------------------------------------------------------------------------\n// Launch targets\n// ---------------------------------------------------------------------------\n\nexport interface LaunchProject {\n path: string;\n name: string;\n}\n\nfunction baseName(path: string): string {\n const trimmed = path.replace(/\\/+$/, '');\n const i = trimmed.lastIndexOf('/');\n return i === -1 ? trimmed : trimmed.slice(i + 1) || trimmed;\n}\n\n/**\n * Where a Launch may start, most relevant first: the folders of the most\n * recently used chats (the \"current project\"), then every discovered project.\n * The server re-checks each against the same two sources, so this list is a\n * convenience, never the gate.\n */\nexport function launchProjects(bootstrap: Pick<VerseBootstrap, 'sessions' | 'projects'> | undefined): LaunchProject[] {\n if (!bootstrap) return [];\n const out: LaunchProject[] = [];\n const seen = new Set<string>();\n const add = (path: string, name?: string) => {\n if (typeof path !== 'string' || path.length === 0 || seen.has(path)) return;\n seen.add(path);\n out.push({ path, name: name ?? baseName(path) });\n };\n const recent = [...bootstrap.sessions].sort((a, b) => Date.parse(b.updatedAt) - Date.parse(a.updatedAt));\n for (const s of recent) add(s.projectPath);\n for (const p of bootstrap.projects) add(p.path, p.name);\n return out;\n}\n\n/** Ollama tags the local seats run — the model choices for `ollama launch <id> --model`. */\nexport function localModelTags(seats: readonly VerseSeat[]): string[] {\n const out: string[] = [];\n for (const seat of seats) {\n if (seat.engine !== 'local') continue;\n const tag = seat.models[0]?.id ?? (seat.id.startsWith('local:') ? seat.id.slice('local:'.length) : null);\n if (tag && !out.includes(tag)) out.push(tag);\n }\n return out;\n}\n\nexport type LaunchVia = 'native' | 'ollama';\n\nexport interface LaunchChoice {\n via: LaunchVia;\n model: string | null;\n}\n\n/** The argv a launch choice runs, as the operator would type it. */\nexport function launchCommand(row: VerseAppRow, choice: LaunchChoice): string[] | null {\n if (choice.via === 'ollama') {\n if (!row.ollamaLaunch) return null;\n return choice.model ? [...row.ollamaLaunch, '--model', choice.model] : [...row.ollamaLaunch];\n }\n return row.actions.find((a) => a.kind === 'launch')?.command ?? null;\n}\n\n// ---------------------------------------------------------------------------\n// Accounts\n// ---------------------------------------------------------------------------\n\nexport type AccountActionKind = 'reconnect' | 'check-again' | 'fix' | 'edit-budget';\n\nexport interface AccountAction {\n kind: AccountActionKind;\n label: string;\n /** Fix only: the command the dialog shows. */\n command: string[] | null;\n /** Primary = the one thing this seat needs now. */\n primary: boolean;\n}\n\n/** Statuses a fresh health sweep can change on its own: offer \"Check again\" for them. */\nconst RECHECKABLE: ReadonlySet<AccountStatus['kind']> = new Set(['spent', 'not-checked', 'unavailable']);\n\n/**\n * What a seat row offers, the one it needs most first:\n * Reconnect signed out or sign-in expiring (the provider's own login, in Terminal);\n * Check again spent, not checked, or unavailable — a zero-cost health sweep\n * is what moves those (pass the row's SETTLED status, so the\n * button stays put while its own check runs);\n * Fix A2 has a command for what is wrong (a re-pin);\n * Edit budget every paid seat.\n * Local rows need none of these.\n */\nexport function accountActions(row: CapacityRow, status?: AccountStatus | null): AccountAction[] {\n if (row.kind === 'local') return [];\n const out: AccountAction[] = [];\n const c = row.connection;\n const needsLogin = row.signedOut\n || (c !== null && (c.connection === 'signed-out' || c.connection === 'expiring' || c.fixKind === 'reauth'));\n if (needsLogin) out.push({ kind: 'reconnect', label: 'Reconnect', command: null, primary: true });\n const recheck = !needsLogin && status != null && RECHECKABLE.has(status.kind);\n if (recheck) out.push({ kind: 'check-again', label: 'Check again', command: null, primary: true });\n if (c !== null && c.fixKind !== 'reauth' && c.fixKind !== 'none' && c.fixCommand !== null) {\n out.push({ kind: 'fix', label: 'Fix', command: c.fixCommand, primary: !needsLogin && !recheck });\n }\n out.push({ kind: 'edit-budget', label: 'Edit budget', command: null, primary: false });\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// MCP\n// ---------------------------------------------------------------------------\n\nexport interface McpSeatRow {\n seatId: string;\n label: string;\n engine: VerseEngine | null;\n monogram: string;\n servers: McpServer[];\n /** \"loads 2 servers\", \"loads none — isolated by Verse\". */\n loads: string;\n isolated: boolean;\n /** Plain language for the seat's reason; the code rides beside it. */\n sentence: string;\n reason: string;\n notes: string[];\n}\n\nexport function mcpSeatRows(snapshot: McpSnapshot): McpSeatRow[] {\n return snapshot.seats.map((seat: McpSeat) => {\n const engine = asEngine(seat.engine);\n const isolated = seat.reason === 'mcp-seat-isolated-by-adapter';\n const n = seat.servers.length;\n return {\n seatId: seat.seatId,\n label: seat.label,\n engine,\n monogram: engine ? ENGINE_MONOGRAM[engine] : seat.label.slice(0, 1).toUpperCase(),\n servers: seat.servers,\n loads: n > 0 ? `loads ${n} server${n === 1 ? '' : 's'}` : isolated ? 'loads none — isolated by Verse' : 'loads none',\n isolated,\n sentence: reasonSentence(SEAT_REASON_COPY, seat.reason, 'Hub cannot say what this seat would load.'),\n reason: seat.reason,\n notes: seat.notes,\n };\n });\n}\n\n/** Where an Add can write: the hub registry, and each account whose config is JSON. */\nexport interface McpTargetOption {\n id: string;\n label: string;\n /** Why this target cannot take a write, or null. */\n disabledReason: string | null;\n}\n\nexport function mcpTargets(snapshot: McpSnapshot | null): McpTargetOption[] {\n const out: McpTargetOption[] = [{ id: 'hub', label: 'Hub gateway registry', disabledReason: null }];\n for (const seat of snapshot?.seats ?? []) {\n if (seat.seatId === 'local') continue;\n // An isolated (Claude) account CAN be written — Claude Code in a terminal\n // reads it — and the form says a Verse chat on it still loads nothing.\n const toml = seat.configFormat === 'toml' || seat.reason === 'mcp-account-config-not-json';\n out.push({\n id: `account:${seat.accountId}`,\n label: `${seat.label} (${seat.engine})`,\n disabledReason: toml ? 'Keeps its MCP servers in TOML, which Hub does not rewrite.' : null,\n });\n }\n return out;\n}\n\n/** Split `a \"b c\" d` into argv the way a shell would, for the Add form's arguments field. */\nexport function splitArgs(text: string): string[] {\n const out: string[] = [];\n let current = '';\n let quote: '\"' | \"'\" | null = null;\n let has = false;\n for (const ch of text) {\n if (quote) {\n if (ch === quote) quote = null;\n else current += ch;\n continue;\n }\n if (ch === '\"' || ch === \"'\") {\n quote = ch;\n has = true;\n continue;\n }\n if (/\\s/.test(ch)) {\n if (has || current.length > 0) out.push(current);\n current = '';\n has = false;\n continue;\n }\n current += ch;\n }\n if (has || current.length > 0) out.push(current);\n return out;\n}\n\n/** `KEY=value` lines → an env object; the first bad line is reported, never guessed. */\nexport function parseEnvLines(text: string): { ok: true; env: Record<string, string> } | { ok: false; error: string } {\n const env: Record<string, string> = {};\n for (const raw of text.split(/\\r?\\n/)) {\n const line = raw.trim();\n if (line.length === 0 || line.startsWith('#')) continue;\n const eq = line.indexOf('=');\n const key = eq === -1 ? '' : line.slice(0, eq).trim();\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) return { ok: false, error: `“${line.slice(0, 40)}” is not KEY=value.` };\n env[key] = line.slice(eq + 1);\n }\n return { ok: true, env };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"apps-model-Du02KhAf.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/mcp/mcp-contract.ts","../../../../../../src/web-ui/routes/verse/apps/apps-model.ts"],"sourcesContent":["/**\n * routes/verse/mcp/mcp-contract.ts — the wire seam for MCP management.\n *\n * Same posture as routes/verse/usage/usage-contract.ts, for the same two\n * reasons:\n *\n * 1. EVERY import from src/core here MUST be type-only. `core/verse/\n * mcp-seat-view.ts` pulls `node:fs` and `node:os`; a VALUE import of even\n * one constant drags that graph into the browser bundle and `vite build`\n * fails. Type-only imports are erased, so the seam guards below cost\n * nothing at runtime.\n * 2. Nothing is CAST. Every read goes through a structural narrower, so a\n * field rename in src/core degrades this panel to an honest \"unknown\"\n * instead of throwing at render time — and the `WIRE_*_KEYS` blocks make\n * that rename fail `npm run typecheck:web` here, at the seam, first.\n *\n * SECURITY: the server already redacts every env value to '<set>' via\n * `redactEnv` and publishes config files as home-relative refs. This module\n * is the client-side backstop on top of that: {@link narrowServer} FORCES\n * every env value to '<set>' whatever arrived, so a server that ever\n * regressed could not print a secret through this panel.\n *\n * Pure: no React, no I/O.\n */\nimport type {\n VerseMcpMachineRegistry,\n VerseMcpSeatView,\n VerseMcpServerView,\n VerseMcpSnapshot,\n} from '../../../../core/verse/mcp-seat-view.js';\nimport type { VerseMcpScope } from '../../../../core/verse/mcp-scope.js';\nimport type {\n VerseAccountCliHealth,\n VerseCliHealthSnapshot,\n} from '../../../../core/verse/mcp-cli-health.js';\n\n// ---------------------------------------------------------------------------\n// Seam contract — compile-time only, zero runtime cost.\n// ---------------------------------------------------------------------------\n\nconst WIRE_SERVER_KEYS = {\n name: 'name',\n command: 'command',\n args: 'args',\n env: 'env',\n sourceRef: 'sourceRef',\n} as const satisfies Record<string, keyof VerseMcpServerView>;\n\nconst WIRE_SEAT_KEYS = {\n seatId: 'seatId',\n label: 'label',\n engine: 'engine',\n accountId: 'accountId',\n servers: 'servers',\n reason: 'reason',\n configFile: 'configFile',\n configFormat: 'configFormat',\n notes: 'notes',\n} as const satisfies Record<string, keyof VerseMcpSeatView>;\n\nconst WIRE_MACHINE_KEYS = {\n servers: 'servers',\n configured: 'configured',\n note: 'note',\n} as const satisfies Record<string, keyof VerseMcpMachineRegistry>;\n\nconst WIRE_SNAPSHOT_KEYS = {\n sampledAt: 'sampledAt',\n seats: 'seats',\n machine: 'machine',\n scope: 'scope',\n notes: 'notes',\n} as const satisfies Record<string, keyof VerseMcpSnapshot>;\n\nconst WIRE_HEALTH_KEYS = {\n accountId: 'accountId',\n label: 'label',\n provider: 'provider',\n authentication: 'authentication',\n state: 'state',\n planType: 'planType',\n reason: 'reason',\n version: 'version',\n pinnedVersion: 'pinnedVersion',\n versionState: 'versionState',\n usageBlockedByPin: 'usageBlockedByPin',\n notes: 'notes',\n} as const satisfies Record<string, keyof VerseAccountCliHealth>;\n\nconst WIRE_HEALTH_SNAPSHOT_KEYS = {\n sampledAt: 'sampledAt',\n accounts: 'accounts',\n driftDetected: 'driftDetected',\n notes: 'notes',\n} as const satisfies Record<string, keyof VerseCliHealthSnapshot>;\n\nconst WIRE_SCOPE_KEYS = {\n available: 'available',\n pinned: 'pinned',\n aliasRef: 'aliasRef',\n tenantRef: 'tenantRef',\n principalRef: 'principalRef',\n reason: 'reason',\n} as const satisfies Record<string, keyof VerseMcpScope>;\n\n// ---------------------------------------------------------------------------\n// Display shapes\n// ---------------------------------------------------------------------------\n\nexport interface McpServer {\n name: string;\n command: string;\n args: string[];\n /** Keys only. Every value is '<set>' — forced here, not merely trusted. */\n env: Record<string, string> | null;\n sourceRef: string;\n}\n\nexport interface McpSeat {\n seatId: string;\n label: string;\n engine: string;\n accountId: string;\n servers: McpServer[];\n reason: string;\n configFile: string | null;\n configFormat: string | null;\n notes: string[];\n}\n\nexport interface McpScope {\n available: boolean;\n pinned: boolean;\n aliasRef: string | null;\n tenantRef: string | null;\n principalRef: string | null;\n reason: string;\n}\n\nexport interface McpSnapshot {\n sampledAt: string | null;\n seats: McpSeat[];\n machine: { servers: McpServer[]; configured: boolean; note: string };\n scope: McpScope | null;\n notes: string[];\n}\n\nexport interface CliHealthRow {\n accountId: string;\n label: string;\n provider: string;\n authentication: string;\n state: string;\n planType: string | null;\n reason: string;\n version: string | null;\n pinnedVersion: string | null;\n versionState: string;\n usageBlockedByPin: boolean;\n notes: string[];\n}\n\nexport interface CliHealthSnapshot {\n sampledAt: string | null;\n accounts: CliHealthRow[];\n driftDetected: boolean;\n notes: string[];\n}\n\n// ---------------------------------------------------------------------------\n// Narrowers\n// ---------------------------------------------------------------------------\n\nfunction record(value: unknown): Record<string, unknown> | null {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction text(value: unknown): string | null {\n return typeof value === 'string' ? value : null;\n}\n\nfunction strings(value: unknown): string[] {\n return Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string') : [];\n}\n\nfunction flag(value: unknown): boolean {\n return value === true;\n}\n\n/**\n * Narrow one server, forcing every env value to '<set>'.\n *\n * The redaction is re-applied rather than trusted. The server already did it;\n * doing it again here means no future server bug can turn this panel into a\n * secret printer, and it costs one map over at most a handful of keys.\n */\nexport function narrowServer(raw: unknown): McpServer | null {\n const row = record(raw);\n if (row === null) return null;\n const name = text(row[WIRE_SERVER_KEYS.name]);\n const command = text(row[WIRE_SERVER_KEYS.command]);\n if (name === null || command === null) return null;\n\n let env: Record<string, string> | null = null;\n const rawEnv = record(row[WIRE_SERVER_KEYS.env]);\n if (rawEnv !== null) {\n const keys = Object.keys(rawEnv);\n if (keys.length > 0) {\n env = {};\n for (const key of keys) env[key] = '<set>';\n }\n }\n\n return {\n name,\n command,\n args: strings(row[WIRE_SERVER_KEYS.args]),\n env,\n sourceRef: text(row[WIRE_SERVER_KEYS.sourceRef]) ?? '(unknown source)',\n };\n}\n\nfunction narrowSeat(raw: unknown): McpSeat | null {\n const row = record(raw);\n if (row === null) return null;\n const seatId = text(row[WIRE_SEAT_KEYS.seatId]);\n if (seatId === null) return null;\n const servers = Array.isArray(row[WIRE_SEAT_KEYS.servers])\n ? (row[WIRE_SEAT_KEYS.servers] as unknown[]).map(narrowServer).filter((s): s is McpServer => s !== null)\n : [];\n return {\n seatId,\n label: text(row[WIRE_SEAT_KEYS.label]) ?? seatId,\n engine: text(row[WIRE_SEAT_KEYS.engine]) ?? 'unknown',\n accountId: text(row[WIRE_SEAT_KEYS.accountId]) ?? seatId,\n servers,\n reason: text(row[WIRE_SEAT_KEYS.reason]) ?? 'unknown',\n configFile: text(row[WIRE_SEAT_KEYS.configFile]),\n configFormat: text(row[WIRE_SEAT_KEYS.configFormat]),\n notes: strings(row[WIRE_SEAT_KEYS.notes]),\n };\n}\n\nfunction narrowScope(raw: unknown): McpScope | null {\n const row = record(raw);\n if (row === null) return null;\n return {\n available: flag(row[WIRE_SCOPE_KEYS.available]),\n pinned: flag(row[WIRE_SCOPE_KEYS.pinned]),\n aliasRef: text(row[WIRE_SCOPE_KEYS.aliasRef]),\n tenantRef: text(row[WIRE_SCOPE_KEYS.tenantRef]),\n principalRef: text(row[WIRE_SCOPE_KEYS.principalRef]),\n reason: text(row[WIRE_SCOPE_KEYS.reason]) ?? 'unknown',\n };\n}\n\n/** Narrow GET /api/verse/mcp. Null when the body is not this shape at all. */\nexport function projectMcpSnapshot(raw: unknown): McpSnapshot | null {\n const row = record(raw);\n if (row === null) return null;\n if (!Array.isArray(row[WIRE_SNAPSHOT_KEYS.seats])) return null;\n\n const machine = record(row[WIRE_SNAPSHOT_KEYS.machine]);\n const machineServers = machine !== null && Array.isArray(machine[WIRE_MACHINE_KEYS.servers])\n ? (machine[WIRE_MACHINE_KEYS.servers] as unknown[]).map(narrowServer).filter((s): s is McpServer => s !== null)\n : [];\n\n return {\n sampledAt: text(row[WIRE_SNAPSHOT_KEYS.sampledAt]),\n seats: (row[WIRE_SNAPSHOT_KEYS.seats] as unknown[])\n .map(narrowSeat)\n .filter((s): s is McpSeat => s !== null),\n machine: {\n servers: machineServers,\n configured: machine !== null ? flag(machine[WIRE_MACHINE_KEYS.configured]) : machineServers.length > 0,\n note: (machine !== null ? text(machine[WIRE_MACHINE_KEYS.note]) : null) ?? '',\n },\n scope: narrowScope(row[WIRE_SNAPSHOT_KEYS.scope]),\n notes: strings(row[WIRE_SNAPSHOT_KEYS.notes]),\n };\n}\n\nfunction narrowHealthRow(raw: unknown): CliHealthRow | null {\n const row = record(raw);\n if (row === null) return null;\n const accountId = text(row[WIRE_HEALTH_KEYS.accountId]);\n if (accountId === null) return null;\n return {\n accountId,\n label: text(row[WIRE_HEALTH_KEYS.label]) ?? accountId,\n provider: text(row[WIRE_HEALTH_KEYS.provider]) ?? 'unknown',\n authentication: text(row[WIRE_HEALTH_KEYS.authentication]) ?? 'unknown',\n state: text(row[WIRE_HEALTH_KEYS.state]) ?? 'unknown',\n planType: text(row[WIRE_HEALTH_KEYS.planType]),\n reason: text(row[WIRE_HEALTH_KEYS.reason]) ?? 'unknown',\n // A missing version stays NULL. It is never coerced to a string, because\n // \"no reading\" and \"some version\" are different facts.\n version: text(row[WIRE_HEALTH_KEYS.version]),\n pinnedVersion: text(row[WIRE_HEALTH_KEYS.pinnedVersion]),\n versionState: text(row[WIRE_HEALTH_KEYS.versionState]) ?? 'unverified',\n usageBlockedByPin: flag(row[WIRE_HEALTH_KEYS.usageBlockedByPin]),\n notes: strings(row[WIRE_HEALTH_KEYS.notes]),\n };\n}\n\n/** Narrow GET /api/verse/mcp/cli-health. */\nexport function projectCliHealth(raw: unknown): CliHealthSnapshot | null {\n const row = record(raw);\n if (row === null) return null;\n if (!Array.isArray(row[WIRE_HEALTH_SNAPSHOT_KEYS.accounts])) return null;\n const accounts = (row[WIRE_HEALTH_SNAPSHOT_KEYS.accounts] as unknown[])\n .map(narrowHealthRow)\n .filter((a): a is CliHealthRow => a !== null);\n return {\n sampledAt: text(row[WIRE_HEALTH_SNAPSHOT_KEYS.sampledAt]),\n accounts,\n // Derived locally as well as read, so a server that forgot the flag still\n // renders the banner rather than silently hiding a drift.\n driftDetected:\n flag(row[WIRE_HEALTH_SNAPSHOT_KEYS.driftDetected]) ||\n accounts.some((account) => account.versionState === 'drift'),\n notes: strings(row[WIRE_HEALTH_SNAPSHOT_KEYS.notes]),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Copy for the machine-readable reasons this surface renders\n// ---------------------------------------------------------------------------\n\n/**\n * Plain language for each seat reason. The CODE is still shown next to the\n * sentence — it is the thing to search for — but it is never the sentence.\n * Same split `usage/accounts-model.ts` uses for probe reasons.\n */\nexport const SEAT_REASON_COPY: Record<string, string> = {\n 'mcp-seat-isolated-by-adapter':\n 'Verse launches every turn on this seat with an empty MCP configuration, so it loads no MCP '\n + 'servers at all — whatever is configured elsewhere on this machine.',\n 'mcp-account-config-absent':\n 'This account has no MCP configuration file of its own, so it starts with none.',\n 'mcp-account-config-not-json':\n 'This account keeps its MCP servers in a TOML config that the provider CLI reads directly. '\n + 'Hub does not parse or rewrite it, so it cannot list what is in there.',\n 'mcp-account-config-read':\n 'Read from this account\\'s own private configuration.',\n 'mcp-account-config-unreadable':\n 'This account\\'s configuration could not be read.',\n 'mcp-account-profile-unresolved':\n 'This account\\'s private profile could not be located, so Hub cannot say what it would load.',\n};\n\nexport const SCOPE_REASON_COPY: Record<string, string> = {\n 'mcp-scope-locus-unavailable':\n 'Locus is not reachable on this machine, so writes are not attributable to a tenant.',\n 'mcp-scope-unpinned':\n 'Locus is running but nothing is pinned, so there is no tenant to scope a write to.',\n 'mcp-scope-seal-unverified':\n 'Locus reports a pin whose seal did not verify. Fix the pin before writing anything.',\n 'mcp-scope-expired': 'The Locus pin has expired.',\n 'mcp-scope-pinned': 'Writes are attributed to the pinned Locus tenant shown here.',\n};\n\n/** Prose for a code, or the caller's own sentence. NEVER the raw code alone. */\nexport function reasonSentence(\n copy: Record<string, string>,\n reason: string,\n fallback: string,\n): string {\n return copy[reason] ?? fallback;\n}\n","/**\n * routes/verse/apps/apps-model.ts — pure view-model for Apps & Accounts.\n *\n * The page has five groups (SPEC-310C §4), from three kinds of source:\n * ACCOUNTS the shared capacity rows (usage/capacity-strip-model.ts)\n * plus the actions each seat needs (Reconnect / Check again / Fix / Edit budget);\n * DESKTOP, TERMINAL AGENTS, LOCAL MODELS GET /api/verse/apps, as served;\n * MCP SERVERS GET /api/verse/mcp (what each seat would ACTUALLY load).\n * Everything that decides a word, a tone or whether a control is enabled\n * lives here, so it is unit-tested without a DOM.\n *\n * Pure: no React, no I/O.\n */\nimport type { VerseAppHealthState, VerseAppRow } from '../../../../core/verse/workbench-types.js';\nimport { ENGINE_MONOGRAM } from '../../../../core/verse/workbench-types.js';\nimport type { VerseBootstrap, VerseEngine, VerseSeat } from '../../../data/api-types.js';\nimport type { HealthTone } from '../health/health-model.js';\nimport type { McpSeat, McpServer, McpSnapshot } from '../mcp/mcp-contract.js';\nimport { reasonSentence, SEAT_REASON_COPY } from '../mcp/mcp-contract.js';\nimport type { AccountStatus, CapacityRow } from '../usage/capacity-strip-model.js';\n\n/** SPEC-310C §4 order. */\nexport const APPS_GROUP_ORDER = ['accounts', 'desktop', 'terminal-agents', 'local-models', 'mcp-servers'] as const;\nexport type AppsGroupId = (typeof APPS_GROUP_ORDER)[number];\n\nexport const APPS_GROUP_TITLE: Readonly<Record<AppsGroupId, string>> = {\n accounts: 'Accounts',\n desktop: 'Desktop',\n 'terminal-agents': 'Terminal agents',\n 'local-models': 'Local models',\n 'mcp-servers': 'MCP servers',\n};\n\nconst HEALTH_TONE: Readonly<Record<VerseAppHealthState, HealthTone | 'off'>> = {\n ok: 'success',\n warn: 'warning',\n error: 'danger',\n off: 'off',\n unknown: 'neutral',\n};\n\n/** A row's dot tone. `off` is its own quiet state (not installed, switched off) — never a fault. */\nexport function appHealthTone(state: VerseAppHealthState): HealthTone | 'off' {\n return HEALTH_TONE[state];\n}\n\nconst VERSE_ENGINES: readonly VerseEngine[] = ['claude', 'codex', 'grok', 'local'];\n\nexport function asEngine(value: string): VerseEngine | null {\n return (VERSE_ENGINES as readonly string[]).includes(value) ? (value as VerseEngine) : null;\n}\n\n// ---------------------------------------------------------------------------\n// Launch targets\n// ---------------------------------------------------------------------------\n\nexport interface LaunchProject {\n path: string;\n name: string;\n}\n\nfunction baseName(path: string): string {\n const trimmed = path.replace(/\\/+$/, '');\n const i = trimmed.lastIndexOf('/');\n return i === -1 ? trimmed : trimmed.slice(i + 1) || trimmed;\n}\n\n/**\n * Where a Launch may start, most relevant first: the folders of the most\n * recently used chats (the \"current project\"), then every discovered project.\n * The server re-checks each against the same two sources, so this list is a\n * convenience, never the gate.\n */\nexport function launchProjects(bootstrap: Pick<VerseBootstrap, 'sessions' | 'projects'> | undefined): LaunchProject[] {\n if (!bootstrap) return [];\n const out: LaunchProject[] = [];\n const seen = new Set<string>();\n const add = (path: string, name?: string) => {\n if (typeof path !== 'string' || path.length === 0 || seen.has(path)) return;\n seen.add(path);\n out.push({ path, name: name ?? baseName(path) });\n };\n const recent = [...bootstrap.sessions].sort((a, b) => Date.parse(b.updatedAt) - Date.parse(a.updatedAt));\n for (const s of recent) add(s.projectPath);\n for (const p of bootstrap.projects) add(p.path, p.name);\n return out;\n}\n\n/** Ollama tags the local seats run — the model choices for `ollama launch <id> --model`. */\nexport function localModelTags(seats: readonly VerseSeat[]): string[] {\n const out: string[] = [];\n for (const seat of seats) {\n if (seat.engine !== 'local') continue;\n const tag = seat.models[0]?.id ?? (seat.id.startsWith('local:') ? seat.id.slice('local:'.length) : null);\n if (tag && !out.includes(tag)) out.push(tag);\n }\n return out;\n}\n\nexport type LaunchVia = 'native' | 'ollama';\n\nexport interface LaunchChoice {\n via: LaunchVia;\n model: string | null;\n}\n\n/** The argv a launch choice runs, as the operator would type it. */\nexport function launchCommand(row: VerseAppRow, choice: LaunchChoice): string[] | null {\n if (choice.via === 'ollama') {\n if (!row.ollamaLaunch) return null;\n return choice.model ? [...row.ollamaLaunch, '--model', choice.model] : [...row.ollamaLaunch];\n }\n return row.actions.find((a) => a.kind === 'launch')?.command ?? null;\n}\n\n// ---------------------------------------------------------------------------\n// Accounts\n// ---------------------------------------------------------------------------\n\nexport type AccountActionKind = 'reconnect' | 'check-again' | 'fix' | 'edit-budget';\n\nexport interface AccountAction {\n kind: AccountActionKind;\n label: string;\n /** Fix only: the command the dialog shows. */\n command: string[] | null;\n /** Primary = the one thing this seat needs now. */\n primary: boolean;\n}\n\n/** Statuses a fresh health sweep can change on its own: offer \"Check again\" for them. */\nconst RECHECKABLE: ReadonlySet<AccountStatus['kind']> = new Set(['spent', 'not-checked', 'unavailable']);\n\n/**\n * What a seat row offers, the one it needs most first:\n * Reconnect signed out or sign-in expiring (the provider's own login, in Terminal);\n * Check again spent, not checked, or unavailable — a zero-cost health sweep\n * is what moves those (pass the row's SETTLED status, so the\n * button stays put while its own check runs);\n * Fix A2 has a command for what is wrong (a re-pin);\n * Edit budget every paid seat.\n * Local rows need none of these.\n */\nexport function accountActions(row: CapacityRow, status?: AccountStatus | null): AccountAction[] {\n if (row.kind === 'local') return [];\n const out: AccountAction[] = [];\n const c = row.connection;\n const needsLogin = row.signedOut\n || (c !== null && (c.connection === 'signed-out' || c.connection === 'expiring' || c.fixKind === 'reauth'));\n if (needsLogin) out.push({ kind: 'reconnect', label: 'Reconnect', command: null, primary: true });\n const recheck = !needsLogin && status != null && RECHECKABLE.has(status.kind);\n if (recheck) out.push({ kind: 'check-again', label: 'Check again', command: null, primary: true });\n if (c !== null && c.fixKind !== 'reauth' && c.fixKind !== 'none' && c.fixCommand !== null) {\n out.push({ kind: 'fix', label: 'Fix', command: c.fixCommand, primary: !needsLogin && !recheck });\n }\n out.push({ kind: 'edit-budget', label: 'Edit budget', command: null, primary: false });\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// MCP\n// ---------------------------------------------------------------------------\n\nexport interface McpSeatRow {\n seatId: string;\n label: string;\n engine: VerseEngine | null;\n monogram: string;\n servers: McpServer[];\n /** \"loads 2 servers\", \"loads none — isolated by Verse\". */\n loads: string;\n isolated: boolean;\n /** Plain language for the seat's reason; the code rides beside it. */\n sentence: string;\n reason: string;\n notes: string[];\n}\n\nexport function mcpSeatRows(snapshot: McpSnapshot): McpSeatRow[] {\n return snapshot.seats.map((seat: McpSeat) => {\n const engine = asEngine(seat.engine);\n const isolated = seat.reason === 'mcp-seat-isolated-by-adapter';\n const n = seat.servers.length;\n return {\n seatId: seat.seatId,\n label: seat.label,\n engine,\n monogram: engine ? ENGINE_MONOGRAM[engine] : seat.label.slice(0, 1).toUpperCase(),\n servers: seat.servers,\n loads: n > 0 ? `loads ${n} server${n === 1 ? '' : 's'}` : isolated ? 'loads none — isolated by Verse' : 'loads none',\n isolated,\n sentence: reasonSentence(SEAT_REASON_COPY, seat.reason, 'Hub cannot say what this seat would load.'),\n reason: seat.reason,\n notes: seat.notes,\n };\n });\n}\n\n/** Where an Add can write: the hub registry, and each account whose config is JSON. */\nexport interface McpTargetOption {\n id: string;\n label: string;\n /** Why this target cannot take a write, or null. */\n disabledReason: string | null;\n}\n\nexport function mcpTargets(snapshot: McpSnapshot | null): McpTargetOption[] {\n const out: McpTargetOption[] = [{ id: 'hub', label: 'Hub gateway registry', disabledReason: null }];\n for (const seat of snapshot?.seats ?? []) {\n if (seat.seatId === 'local') continue;\n // An isolated (Claude) account CAN be written — Claude Code in a terminal\n // reads it — and the form says a Verse chat on it still loads nothing.\n const toml = seat.configFormat === 'toml' || seat.reason === 'mcp-account-config-not-json';\n out.push({\n id: `account:${seat.accountId}`,\n label: `${seat.label} (${seat.engine})`,\n disabledReason: toml ? 'Keeps its MCP servers in TOML, which Hub does not rewrite.' : null,\n });\n }\n return out;\n}\n\n/** Split `a \"b c\" d` into argv the way a shell would, for the Add form's arguments field. */\nexport function splitArgs(text: string): string[] {\n const out: string[] = [];\n let current = '';\n let quote: '\"' | \"'\" | null = null;\n let has = false;\n for (const ch of text) {\n if (quote) {\n if (ch === quote) quote = null;\n else current += ch;\n continue;\n }\n if (ch === '\"' || ch === \"'\") {\n quote = ch;\n has = true;\n continue;\n }\n if (/\\s/.test(ch)) {\n if (has || current.length > 0) out.push(current);\n current = '';\n has = false;\n continue;\n }\n current += ch;\n }\n if (has || current.length > 0) out.push(current);\n return out;\n}\n\n/** `KEY=value` lines → an env object; the first bad line is reported, never guessed. */\nexport function parseEnvLines(text: string): { ok: true; env: Record<string, string> } | { ok: false; error: string } {\n const env: Record<string, string> = {};\n for (const raw of text.split(/\\r?\\n/)) {\n const line = raw.trim();\n if (line.length === 0 || line.startsWith('#')) continue;\n const eq = line.indexOf('=');\n const key = eq === -1 ? '' : line.slice(0, eq).trim();\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) return { ok: false, error: `“${line.slice(0, 40)}” is not KEY=value.` };\n env[key] = line.slice(eq + 1);\n }\n return { ok: true, env };\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{a as e}from"./AutonomyOffState-B5eEkmiz.js";var t={off:0,propose:1,autonomous:2},n={off:`Off`,propose:`Propose`,autonomous:`Autonomous`},r={off:`Off`,propose:`Propose`,autonomous:`Auto`},i=[`off`,`propose`,`autonomous`];function a(e,n){let r=t[e.switch],i=t[n];return i===r?`same`:i<r?`lower`:i<=t[e.maxSwitchWithoutGrant]?`raise`:`raise-needs-grant`}function o(e){return i.map(i=>{let a=t[i]>Math.max(t[e.switch],t[e.maxSwitchWithoutGrant]);return{value:i,label:n[i],short:r[i],needsGrant:a,ariaLabel:a?`${n[i]} (needs a new grant — Touch ID)`:n[i]}})}var s=864e5,c=36e5;function l(e){if(!Number.isFinite(e)||e<=0)return`0m`;if(e>=3*s)return`${Math.floor(e/s)}d`;if(e>=s){let t=Math.floor(e/s),n=Math.floor((e-t*s)/c);return n?`${t}d ${n}h`:`${t}d`}return e>=c?`${Math.floor(e/c)}h`:`${Math.max(1,Math.floor(e/6e4))}m`}var u={none:`No grant`,active:`Active`,paused:`Paused, re-approve`,expired:`Expired, renew`,revoked:`Revoked, new grant`,invalid:`Grant invalid`};function d(e,t){if(!e)return{label:`Grant unknown`,tone:`unknown`,detail:`The authority service did not answer, so the grant state is unknown.`,action:null};let n=e.grant;switch(n.state){case`active`:{let e=n.expiresAt?Date.parse(n.expiresAt):NaN;if(!Number.isFinite(e))return{label:`Active`,tone:`success`,detail:`A grant is active; its expiry could not be read.`,action:null};let r=e-t,i=r<s?`danger`:r<3*s?`warning`:`success`;return{label:l(r),tone:i,detail:`Grant active until ${new Date(e).toLocaleString(`en-US`,{month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`})}${r<3*s?` — renew soon`:``}.`,action:r<3*s?`grant`:null}}case`paused`:return{label:u.paused,tone:`warning`,detail:n.reason??`The grant is paused until you re-approve it.`,action:`re-approve`};case`expired`:return{label:u.expired,tone:`danger`,detail:n.reason??`The grant expired; autonomy is dark until a new one is signed.`,action:`grant`};case`revoked`:return{label:u.revoked,tone:`danger`,detail:n.reason??`The grant was revoked; a new one needs Touch ID.`,action:`grant`};case`invalid`:return{label:u.invalid,tone:`danger`,detail:n.reason??`The installed grant failed verification.`,action:`grant`};default:return{label:u.none,tone:`neutral`,detail:`No standing grant is installed; autonomy can only propose.`,action:`grant`}}}function f(e){return e?e.kill?{key:`mode`,text:`Stopped`,tone:`danger`}:e.grant.state===`paused`?{key:`mode`,text:`Paused, re-approve`,tone:`warning`}:{key:`mode`,text:n[e.effectiveSwitch],tone:e.effectiveSwitch===`autonomous`?`success`:`neutral`}:{key:`mode`,text:`Autonomy unknown`,tone:`unknown`}}function p(t){let n=[f(t.authority)],r=t.building!==null||t.mergedToday!==null||t.revertsToday!==null;return t.darkSince&&!(t.building&&t.building>0)?n.push({key:`dark`,text:`fleet dark since ${e(t.darkSince)}`,tone:`neutral`}):r?(t.building!==null&&n.push({key:`building`,text:`${t.building} building`}),t.mergedToday!==null&&n.push({key:`merged`,text:`${t.mergedToday} merged today`}),t.revertsToday!==null&&n.push({key:`reverts`,text:`${t.revertsToday} revert${t.revertsToday===1?``:`s`}`,tone:t.revertsToday>0?`warning`:void 0})):n.push({key:`fleet`,text:`fleet status unknown`,tone:`unknown`}),t.reserve&&t.authority?.effectiveSwitch!==`off`&&n.push({key:`reserve`,text:`${t.reserve.label} ${Math.round(t.reserve.percent)}% reserved for you`}),n}function m(e,t){let n=e.kind;return n===`new`?`grant`:n===`reapprove`?`re-approve`:t}function h(e){if(typeof e!=`object`||!e)return null;let t=e.result?.stop;if(typeof t!=`object`||!t)return null;let n=t,r=typeof n.liveExecutionLeases==`number`&&Number.isFinite(n.liveExecutionLeases)?Math.max(0,Math.round(n.liveExecutionLeases)):null,i=[];n.quiesced===!0||r===0?i.push(`Stopped. No agent is still running.`):r===null?i.push(`Stopped. Agents started before Stop may still be finishing; no new work starts.`):i.push(`Stopped. ${r} agent${r===1?``:`s`} started before Stop ${r===1?`is`:`are`} still finishing; no new work starts.`),typeof n.mergesRevoked==`number`&&n.mergesRevoked>0&&i.push(`${n.mergesRevoked} armed merge${n.mergesRevoked===1?` was`:`s were`} revoked.`);let a=Array.isArray(n.mergeRevokeFailures)?n.mergeRevokeFailures.length:0;return a>0&&i.push(`${a} armed merge${a===1?``:`s`} could not be revoked; Stop still blocks ${a===1?`it`:`them`}.`),i.join(` `)}export{d as a,o as c,a as i,p as l,t as n,f as o,m as r,h as s,n as t};
2
- //# sourceMappingURL=authority-model-BFuPezSo.js.map
1
+ import{a as e}from"./AutonomyOffState-CEPSZToP.js";var t={off:0,propose:1,autonomous:2},n={off:`Off`,propose:`Propose`,autonomous:`Autonomous`},r={off:`Off`,propose:`Propose`,autonomous:`Auto`},i=[`off`,`propose`,`autonomous`];function a(e,n){let r=t[e.switch],i=t[n];return i===r?`same`:i<r?`lower`:i<=t[e.maxSwitchWithoutGrant]?`raise`:`raise-needs-grant`}function o(e){return i.map(i=>{let a=t[i]>Math.max(t[e.switch],t[e.maxSwitchWithoutGrant]);return{value:i,label:n[i],short:r[i],needsGrant:a,ariaLabel:a?`${n[i]} (needs a new grant — Touch ID)`:n[i]}})}var s=864e5,c=36e5;function l(e){if(!Number.isFinite(e)||e<=0)return`0m`;if(e>=3*s)return`${Math.floor(e/s)}d`;if(e>=s){let t=Math.floor(e/s),n=Math.floor((e-t*s)/c);return n?`${t}d ${n}h`:`${t}d`}return e>=c?`${Math.floor(e/c)}h`:`${Math.max(1,Math.floor(e/6e4))}m`}var u={none:`No grant`,active:`Active`,paused:`Paused, re-approve`,expired:`Expired, renew`,revoked:`Revoked, new grant`,invalid:`Grant invalid`};function d(e,t){if(!e)return{label:`Grant unknown`,tone:`unknown`,detail:`The authority service did not answer, so the grant state is unknown.`,action:null};let n=e.grant;switch(n.state){case`active`:{let e=n.expiresAt?Date.parse(n.expiresAt):NaN;if(!Number.isFinite(e))return{label:`Active`,tone:`success`,detail:`A grant is active; its expiry could not be read.`,action:null};let r=e-t,i=r<s?`danger`:r<3*s?`warning`:`success`;return{label:l(r),tone:i,detail:`Grant active until ${new Date(e).toLocaleString(`en-US`,{month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`})}${r<3*s?` — renew soon`:``}.`,action:r<3*s?`grant`:null}}case`paused`:return{label:u.paused,tone:`warning`,detail:n.reason??`The grant is paused until you re-approve it.`,action:`re-approve`};case`expired`:return{label:u.expired,tone:`danger`,detail:n.reason??`The grant expired; autonomy is dark until a new one is signed.`,action:`grant`};case`revoked`:return{label:u.revoked,tone:`danger`,detail:n.reason??`The grant was revoked; a new one needs Touch ID.`,action:`grant`};case`invalid`:return{label:u.invalid,tone:`danger`,detail:n.reason??`The installed grant failed verification.`,action:`grant`};default:return{label:u.none,tone:`neutral`,detail:`No standing grant is installed; autonomy can only propose.`,action:`grant`}}}function f(e){return e?e.kill?{key:`mode`,text:`Stopped`,tone:`danger`}:e.grant.state===`paused`?{key:`mode`,text:`Paused, re-approve`,tone:`warning`}:{key:`mode`,text:n[e.effectiveSwitch],tone:e.effectiveSwitch===`autonomous`?`success`:`neutral`}:{key:`mode`,text:`Autonomy unknown`,tone:`unknown`}}function p(t){let n=[f(t.authority)],r=t.building!==null||t.mergedToday!==null||t.revertsToday!==null;return t.darkSince&&!(t.building&&t.building>0)?n.push({key:`dark`,text:`fleet dark since ${e(t.darkSince)}`,tone:`neutral`}):r?(t.building!==null&&n.push({key:`building`,text:`${t.building} building`}),t.mergedToday!==null&&n.push({key:`merged`,text:`${t.mergedToday} merged today`}),t.revertsToday!==null&&n.push({key:`reverts`,text:`${t.revertsToday} revert${t.revertsToday===1?``:`s`}`,tone:t.revertsToday>0?`warning`:void 0})):n.push({key:`fleet`,text:`fleet status unknown`,tone:`unknown`}),t.reserve&&t.authority?.effectiveSwitch!==`off`&&n.push({key:`reserve`,text:`${t.reserve.label} ${Math.round(t.reserve.percent)}% reserved for you`}),n}function m(e,t){let n=e.kind;return n===`new`?`grant`:n===`reapprove`?`re-approve`:t}function h(e){if(typeof e!=`object`||!e)return null;let t=e.result?.stop;if(typeof t!=`object`||!t)return null;let n=t,r=typeof n.liveExecutionLeases==`number`&&Number.isFinite(n.liveExecutionLeases)?Math.max(0,Math.round(n.liveExecutionLeases)):null,i=[];n.quiesced===!0||r===0?i.push(`Stopped. No agent is still running.`):r===null?i.push(`Stopped. Agents started before Stop may still be finishing; no new work starts.`):i.push(`Stopped. ${r} agent${r===1?``:`s`} started before Stop ${r===1?`is`:`are`} still finishing; no new work starts.`),typeof n.mergesRevoked==`number`&&n.mergesRevoked>0&&i.push(`${n.mergesRevoked} armed merge${n.mergesRevoked===1?` was`:`s were`} revoked.`);let a=Array.isArray(n.mergeRevokeFailures)?n.mergeRevokeFailures.length:0;return a>0&&i.push(`${a} armed merge${a===1?``:`s`} could not be revoked; Stop still blocks ${a===1?`it`:`them`}.`),i.join(` `)}export{d as a,o as c,a as i,p as l,t as n,f as o,m as r,h as s,n as t};
2
+ //# sourceMappingURL=authority-model-79SeuKlJ.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"authority-model-BFuPezSo.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/command/authority-model.ts"],"sourcesContent":["/**\n * routes/verse/command/authority-model.ts — the pure decisions behind the\n * Command top bar (unit C7; SPEC-310B §0 I1 + §6, SPEC-310C §5).\n *\n * I1 is the whole design: ONLY a grant signed under Touch ID raises\n * authority; LOWERING is instant and needs no auth. So every click on the\n * switch is classified before anything is sent:\n *\n * lower → POST at once (Off is always one click away);\n * raise → POST at once, but only up to `maxSwitchWithoutGrant`\n * — the installed grant already allows it;\n * raise-needs-grant→ nothing is sent; the Touch ID sheet opens with the\n * draft grant's full scope and expiry. The server is\n * still the authority (409 `grant-required` on a stale\n * page) — this only keeps the page from asking for\n * something it knows will be refused.\n *\n * Framework-free; tested directly.\n */\nimport type { AuthorityGrantDraft, AuthorityStatusV1, AutonomySwitch, GrantState } from '../../../../core/authority/types.js';\nimport { darkSinceLabel } from '../fleet/dark-since.js';\n\nexport const SWITCH_RANK: Readonly<Record<AutonomySwitch, number>> = { off: 0, propose: 1, autonomous: 2 };\n\nexport const SWITCH_LABEL: Readonly<Record<AutonomySwitch, string>> = {\n off: 'Off',\n propose: 'Propose',\n autonomous: 'Autonomous',\n};\n\n/** Short labels for the 375 px bar (same order, same meaning). */\nexport const SWITCH_SHORT: Readonly<Record<AutonomySwitch, string>> = {\n off: 'Off',\n propose: 'Propose',\n autonomous: 'Auto',\n};\n\nexport const SWITCH_ORDER: readonly AutonomySwitch[] = ['off', 'propose', 'autonomous'];\n\nexport type SwitchChange = 'same' | 'lower' | 'raise' | 'raise-needs-grant';\n\n/** What a click on `to` means, given the status the page last read. */\nexport function classifySwitch(status: Pick<AuthorityStatusV1, 'switch' | 'maxSwitchWithoutGrant'>, to: AutonomySwitch): SwitchChange {\n const from = SWITCH_RANK[status.switch];\n const target = SWITCH_RANK[to];\n if (target === from) return 'same';\n if (target < from) return 'lower';\n return target <= SWITCH_RANK[status.maxSwitchWithoutGrant] ? 'raise' : 'raise-needs-grant';\n}\n\nexport interface SwitchOption {\n value: AutonomySwitch;\n label: string;\n short: string;\n /** Selecting it opens the Touch ID sheet instead of switching. */\n needsGrant: boolean;\n /** Spoken name, carrying the grant requirement in words. */\n ariaLabel: string;\n}\n\nexport function switchOptions(status: Pick<AuthorityStatusV1, 'switch' | 'maxSwitchWithoutGrant'>): SwitchOption[] {\n return SWITCH_ORDER.map((value) => {\n const needsGrant = SWITCH_RANK[value] > Math.max(SWITCH_RANK[status.switch], SWITCH_RANK[status.maxSwitchWithoutGrant]);\n return {\n value,\n label: SWITCH_LABEL[value],\n short: SWITCH_SHORT[value],\n needsGrant,\n ariaLabel: needsGrant ? `${SWITCH_LABEL[value]} (needs a new grant — Touch ID)` : SWITCH_LABEL[value],\n };\n });\n}\n\n// ---------------------------------------------------------------------------\n// Grant chip\n// ---------------------------------------------------------------------------\n\nexport type ChipTone = 'neutral' | 'success' | 'warning' | 'danger' | 'unknown';\n\nexport interface GrantChip {\n label: string;\n tone: ChipTone;\n /** Longer sentence for the tooltip / accessible description. */\n detail: string;\n /** Clicking the chip opens the Touch ID sheet for this action; null = informational. */\n action: 'grant' | 're-approve' | null;\n}\n\nconst DAY = 86_400_000;\nconst HOUR = 3_600_000;\n\n/** \"23d\", \"2d 4h\", \"5h\", \"40m\" — time left, coarse on purpose (it is a chip). */\nexport function timeLeft(ms: number): string {\n if (!Number.isFinite(ms) || ms <= 0) return '0m';\n if (ms >= 3 * DAY) return `${Math.floor(ms / DAY)}d`;\n if (ms >= DAY) {\n const d = Math.floor(ms / DAY);\n const h = Math.floor((ms - d * DAY) / HOUR);\n return h ? `${d}d ${h}h` : `${d}d`;\n }\n if (ms >= HOUR) return `${Math.floor(ms / HOUR)}h`;\n return `${Math.max(1, Math.floor(ms / 60_000))}m`;\n}\n\nconst STATE_WORDS: Record<GrantState, string> = {\n none: 'No grant',\n active: 'Active',\n paused: 'Paused, re-approve',\n expired: 'Expired, renew',\n revoked: 'Revoked, new grant',\n invalid: 'Grant invalid',\n};\n\nexport function grantChip(status: AuthorityStatusV1 | null, now: number): GrantChip {\n if (!status) return { label: 'Grant unknown', tone: 'unknown', detail: 'The authority service did not answer, so the grant state is unknown.', action: null };\n const g = status.grant;\n switch (g.state) {\n case 'active': {\n const expires = g.expiresAt ? Date.parse(g.expiresAt) : NaN;\n if (!Number.isFinite(expires)) return { label: 'Active', tone: 'success', detail: 'A grant is active; its expiry could not be read.', action: null };\n const left = expires - now;\n const tone: ChipTone = left < DAY ? 'danger' : left < 3 * DAY ? 'warning' : 'success';\n return {\n label: timeLeft(left),\n tone,\n detail: `Grant active until ${new Date(expires).toLocaleString('en-US', { month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' })}${left < 3 * DAY ? ' — renew soon' : ''}.`,\n action: left < 3 * DAY ? 'grant' : null,\n };\n }\n case 'paused':\n return { label: STATE_WORDS.paused, tone: 'warning', detail: g.reason ?? 'The grant is paused until you re-approve it.', action: 're-approve' };\n case 'expired':\n return { label: STATE_WORDS.expired, tone: 'danger', detail: g.reason ?? 'The grant expired; autonomy is dark until a new one is signed.', action: 'grant' };\n case 'revoked':\n return { label: STATE_WORDS.revoked, tone: 'danger', detail: g.reason ?? 'The grant was revoked; a new one needs Touch ID.', action: 'grant' };\n case 'invalid':\n return { label: STATE_WORDS.invalid, tone: 'danger', detail: g.reason ?? 'The installed grant failed verification.', action: 'grant' };\n case 'none':\n default:\n return { label: STATE_WORDS.none, tone: 'neutral', detail: 'No standing grant is installed; autonomy can only propose.', action: 'grant' };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Verdict line\n// ---------------------------------------------------------------------------\n\nexport interface VerdictInputs {\n authority: AuthorityStatusV1 | null;\n /** FleetLiveSummary fields, null = unknown. */\n building: number | null;\n mergedToday: number | null;\n revertsToday: number | null;\n /** \"Claude\" and the percent reserved for Mason on that seat; null = unknown / no such seat. */\n reserve: { label: string; percent: number } | null;\n /**\n * THE dark-since instant — `fleetDarkSince(live)` (fleet/dark-since.ts),\n * null unless the fleet is dark. Never fleet history's \"quiet since\": an\n * idle fleet that has not produced lately is not dark.\n */\n darkSince: string | null;\n}\n\nexport interface VerdictPart {\n key: string;\n text: string;\n tone?: ChipTone;\n}\n\n/** The mode word first: what autonomy is doing right now, in one word. */\nexport function modeWord(authority: AuthorityStatusV1 | null): VerdictPart {\n if (!authority) return { key: 'mode', text: 'Autonomy unknown', tone: 'unknown' };\n if (authority.kill) return { key: 'mode', text: 'Stopped', tone: 'danger' };\n if (authority.grant.state === 'paused') return { key: 'mode', text: 'Paused, re-approve', tone: 'warning' };\n return { key: 'mode', text: SWITCH_LABEL[authority.effectiveSwitch], tone: authority.effectiveSwitch === 'autonomous' ? 'success' : 'neutral' };\n}\n\n/**\n * \"Autonomous · 5 building · 7 merged today · 0 reverts · Claude 46%\n * reserved for you\". A number that is unknown is LEFT OUT rather than shown\n * as 0 (the line would otherwise claim \"0 reverts\" it never counted); when\n * the whole fleet read is missing the line says so instead.\n */\nexport function verdictParts(v: VerdictInputs): VerdictPart[] {\n const parts: VerdictPart[] = [modeWord(v.authority)];\n const anyFleet = v.building !== null || v.mergedToday !== null || v.revertsToday !== null;\n if (v.darkSince && !(v.building && v.building > 0)) {\n // The same local-day label the Fleet surface's dark charts use.\n parts.push({ key: 'dark', text: `fleet dark since ${darkSinceLabel(v.darkSince)}`, tone: 'neutral' });\n } else if (!anyFleet) {\n parts.push({ key: 'fleet', text: 'fleet status unknown', tone: 'unknown' });\n } else {\n if (v.building !== null) parts.push({ key: 'building', text: `${v.building} building` });\n if (v.mergedToday !== null) parts.push({ key: 'merged', text: `${v.mergedToday} merged today` });\n if (v.revertsToday !== null) parts.push({ key: 'reverts', text: `${v.revertsToday} revert${v.revertsToday === 1 ? '' : 's'}`, tone: v.revertsToday > 0 ? 'warning' : undefined });\n }\n // The reserve is what autonomy leaves you; with autonomy off it reserves nothing.\n if (v.reserve && v.authority?.effectiveSwitch !== 'off') parts.push({ key: 'reserve', text: `${v.reserve.label} ${Math.round(v.reserve.percent)}% reserved for you` });\n return parts;\n}\n\n/**\n * Which POST signs a draft: the DRAFT's own `kind` decides (B-U1: GET\n * /api/verse/authority/draft answers with `kind`, and POST refuses a digest\n * whose kind does not match the action). The clicked intent is only the\n * fallback for a server that sends no kind — a grant that is no longer\n * continuable is drafted as a NEW one, and signing it must say so.\n */\nexport function actionForDraft(draft: AuthorityGrantDraft, fallback: 'grant' | 're-approve'): 'grant' | 're-approve' {\n const kind = (draft as AuthorityGrantDraft & { kind?: unknown }).kind;\n if (kind === 'new') return 'grant';\n if (kind === 'reapprove') return 're-approve';\n return fallback;\n}\n\n/**\n * What Stop actually did, in one sentence (B-U6 → C: the Stop UI shows the\n * drain result). The POST answers with the status plus `result.stop`\n * (authority/clamp.ts StopResult). Stop from Verse never waits, so agents\n * admitted before it may still be finishing; that is said with the count,\n * never as \"stopped\" alone. Unknown leases are counted as live upstream\n * (fail closed). Null when the response carries no stop result.\n */\nexport function stopOutcomeSentence(response: unknown): string | null {\n if (response === null || typeof response !== 'object') return null;\n const stop = (response as { result?: { stop?: unknown } }).result?.stop;\n if (stop === null || typeof stop !== 'object') return null;\n const r = stop as { quiesced?: unknown; liveExecutionLeases?: unknown; mergesRevoked?: unknown; mergeRevokeFailures?: unknown };\n const live = typeof r.liveExecutionLeases === 'number' && Number.isFinite(r.liveExecutionLeases) ? Math.max(0, Math.round(r.liveExecutionLeases)) : null;\n const parts: string[] = [];\n if (r.quiesced === true || live === 0) parts.push('Stopped. No agent is still running.');\n else if (live !== null) parts.push(`Stopped. ${live} agent${live === 1 ? '' : 's'} started before Stop ${live === 1 ? 'is' : 'are'} still finishing; no new work starts.`);\n else parts.push('Stopped. Agents started before Stop may still be finishing; no new work starts.');\n if (typeof r.mergesRevoked === 'number' && r.mergesRevoked > 0) {\n parts.push(`${r.mergesRevoked} armed merge${r.mergesRevoked === 1 ? ' was' : 's were'} revoked.`);\n }\n const failed = Array.isArray(r.mergeRevokeFailures) ? r.mergeRevokeFailures.length : 0;\n if (failed > 0) parts.push(`${failed} armed merge${failed === 1 ? '' : 's'} could not be revoked; Stop still blocks ${failed === 1 ? 'it' : 'them'}.`);\n return parts.join(' ');\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"authority-model-79SeuKlJ.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/command/authority-model.ts"],"sourcesContent":["/**\n * routes/verse/command/authority-model.ts — the pure decisions behind the\n * Command top bar (unit C7; SPEC-310B §0 I1 + §6, SPEC-310C §5).\n *\n * I1 is the whole design: ONLY a grant signed under Touch ID raises\n * authority; LOWERING is instant and needs no auth. So every click on the\n * switch is classified before anything is sent:\n *\n * lower → POST at once (Off is always one click away);\n * raise → POST at once, but only up to `maxSwitchWithoutGrant`\n * — the installed grant already allows it;\n * raise-needs-grant→ nothing is sent; the Touch ID sheet opens with the\n * draft grant's full scope and expiry. The server is\n * still the authority (409 `grant-required` on a stale\n * page) — this only keeps the page from asking for\n * something it knows will be refused.\n *\n * Framework-free; tested directly.\n */\nimport type { AuthorityGrantDraft, AuthorityStatusV1, AutonomySwitch, GrantState } from '../../../../core/authority/types.js';\nimport { darkSinceLabel } from '../fleet/dark-since.js';\n\nexport const SWITCH_RANK: Readonly<Record<AutonomySwitch, number>> = { off: 0, propose: 1, autonomous: 2 };\n\nexport const SWITCH_LABEL: Readonly<Record<AutonomySwitch, string>> = {\n off: 'Off',\n propose: 'Propose',\n autonomous: 'Autonomous',\n};\n\n/** Short labels for the 375 px bar (same order, same meaning). */\nexport const SWITCH_SHORT: Readonly<Record<AutonomySwitch, string>> = {\n off: 'Off',\n propose: 'Propose',\n autonomous: 'Auto',\n};\n\nexport const SWITCH_ORDER: readonly AutonomySwitch[] = ['off', 'propose', 'autonomous'];\n\nexport type SwitchChange = 'same' | 'lower' | 'raise' | 'raise-needs-grant';\n\n/** What a click on `to` means, given the status the page last read. */\nexport function classifySwitch(status: Pick<AuthorityStatusV1, 'switch' | 'maxSwitchWithoutGrant'>, to: AutonomySwitch): SwitchChange {\n const from = SWITCH_RANK[status.switch];\n const target = SWITCH_RANK[to];\n if (target === from) return 'same';\n if (target < from) return 'lower';\n return target <= SWITCH_RANK[status.maxSwitchWithoutGrant] ? 'raise' : 'raise-needs-grant';\n}\n\nexport interface SwitchOption {\n value: AutonomySwitch;\n label: string;\n short: string;\n /** Selecting it opens the Touch ID sheet instead of switching. */\n needsGrant: boolean;\n /** Spoken name, carrying the grant requirement in words. */\n ariaLabel: string;\n}\n\nexport function switchOptions(status: Pick<AuthorityStatusV1, 'switch' | 'maxSwitchWithoutGrant'>): SwitchOption[] {\n return SWITCH_ORDER.map((value) => {\n const needsGrant = SWITCH_RANK[value] > Math.max(SWITCH_RANK[status.switch], SWITCH_RANK[status.maxSwitchWithoutGrant]);\n return {\n value,\n label: SWITCH_LABEL[value],\n short: SWITCH_SHORT[value],\n needsGrant,\n ariaLabel: needsGrant ? `${SWITCH_LABEL[value]} (needs a new grant — Touch ID)` : SWITCH_LABEL[value],\n };\n });\n}\n\n// ---------------------------------------------------------------------------\n// Grant chip\n// ---------------------------------------------------------------------------\n\nexport type ChipTone = 'neutral' | 'success' | 'warning' | 'danger' | 'unknown';\n\nexport interface GrantChip {\n label: string;\n tone: ChipTone;\n /** Longer sentence for the tooltip / accessible description. */\n detail: string;\n /** Clicking the chip opens the Touch ID sheet for this action; null = informational. */\n action: 'grant' | 're-approve' | null;\n}\n\nconst DAY = 86_400_000;\nconst HOUR = 3_600_000;\n\n/** \"23d\", \"2d 4h\", \"5h\", \"40m\" — time left, coarse on purpose (it is a chip). */\nexport function timeLeft(ms: number): string {\n if (!Number.isFinite(ms) || ms <= 0) return '0m';\n if (ms >= 3 * DAY) return `${Math.floor(ms / DAY)}d`;\n if (ms >= DAY) {\n const d = Math.floor(ms / DAY);\n const h = Math.floor((ms - d * DAY) / HOUR);\n return h ? `${d}d ${h}h` : `${d}d`;\n }\n if (ms >= HOUR) return `${Math.floor(ms / HOUR)}h`;\n return `${Math.max(1, Math.floor(ms / 60_000))}m`;\n}\n\nconst STATE_WORDS: Record<GrantState, string> = {\n none: 'No grant',\n active: 'Active',\n paused: 'Paused, re-approve',\n expired: 'Expired, renew',\n revoked: 'Revoked, new grant',\n invalid: 'Grant invalid',\n};\n\nexport function grantChip(status: AuthorityStatusV1 | null, now: number): GrantChip {\n if (!status) return { label: 'Grant unknown', tone: 'unknown', detail: 'The authority service did not answer, so the grant state is unknown.', action: null };\n const g = status.grant;\n switch (g.state) {\n case 'active': {\n const expires = g.expiresAt ? Date.parse(g.expiresAt) : NaN;\n if (!Number.isFinite(expires)) return { label: 'Active', tone: 'success', detail: 'A grant is active; its expiry could not be read.', action: null };\n const left = expires - now;\n const tone: ChipTone = left < DAY ? 'danger' : left < 3 * DAY ? 'warning' : 'success';\n return {\n label: timeLeft(left),\n tone,\n detail: `Grant active until ${new Date(expires).toLocaleString('en-US', { month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' })}${left < 3 * DAY ? ' — renew soon' : ''}.`,\n action: left < 3 * DAY ? 'grant' : null,\n };\n }\n case 'paused':\n return { label: STATE_WORDS.paused, tone: 'warning', detail: g.reason ?? 'The grant is paused until you re-approve it.', action: 're-approve' };\n case 'expired':\n return { label: STATE_WORDS.expired, tone: 'danger', detail: g.reason ?? 'The grant expired; autonomy is dark until a new one is signed.', action: 'grant' };\n case 'revoked':\n return { label: STATE_WORDS.revoked, tone: 'danger', detail: g.reason ?? 'The grant was revoked; a new one needs Touch ID.', action: 'grant' };\n case 'invalid':\n return { label: STATE_WORDS.invalid, tone: 'danger', detail: g.reason ?? 'The installed grant failed verification.', action: 'grant' };\n case 'none':\n default:\n return { label: STATE_WORDS.none, tone: 'neutral', detail: 'No standing grant is installed; autonomy can only propose.', action: 'grant' };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Verdict line\n// ---------------------------------------------------------------------------\n\nexport interface VerdictInputs {\n authority: AuthorityStatusV1 | null;\n /** FleetLiveSummary fields, null = unknown. */\n building: number | null;\n mergedToday: number | null;\n revertsToday: number | null;\n /** \"Claude\" and the percent reserved for Mason on that seat; null = unknown / no such seat. */\n reserve: { label: string; percent: number } | null;\n /**\n * THE dark-since instant — `fleetDarkSince(live)` (fleet/dark-since.ts),\n * null unless the fleet is dark. Never fleet history's \"quiet since\": an\n * idle fleet that has not produced lately is not dark.\n */\n darkSince: string | null;\n}\n\nexport interface VerdictPart {\n key: string;\n text: string;\n tone?: ChipTone;\n}\n\n/** The mode word first: what autonomy is doing right now, in one word. */\nexport function modeWord(authority: AuthorityStatusV1 | null): VerdictPart {\n if (!authority) return { key: 'mode', text: 'Autonomy unknown', tone: 'unknown' };\n if (authority.kill) return { key: 'mode', text: 'Stopped', tone: 'danger' };\n if (authority.grant.state === 'paused') return { key: 'mode', text: 'Paused, re-approve', tone: 'warning' };\n return { key: 'mode', text: SWITCH_LABEL[authority.effectiveSwitch], tone: authority.effectiveSwitch === 'autonomous' ? 'success' : 'neutral' };\n}\n\n/**\n * \"Autonomous · 5 building · 7 merged today · 0 reverts · Claude 46%\n * reserved for you\". A number that is unknown is LEFT OUT rather than shown\n * as 0 (the line would otherwise claim \"0 reverts\" it never counted); when\n * the whole fleet read is missing the line says so instead.\n */\nexport function verdictParts(v: VerdictInputs): VerdictPart[] {\n const parts: VerdictPart[] = [modeWord(v.authority)];\n const anyFleet = v.building !== null || v.mergedToday !== null || v.revertsToday !== null;\n if (v.darkSince && !(v.building && v.building > 0)) {\n // The same local-day label the Fleet surface's dark charts use.\n parts.push({ key: 'dark', text: `fleet dark since ${darkSinceLabel(v.darkSince)}`, tone: 'neutral' });\n } else if (!anyFleet) {\n parts.push({ key: 'fleet', text: 'fleet status unknown', tone: 'unknown' });\n } else {\n if (v.building !== null) parts.push({ key: 'building', text: `${v.building} building` });\n if (v.mergedToday !== null) parts.push({ key: 'merged', text: `${v.mergedToday} merged today` });\n if (v.revertsToday !== null) parts.push({ key: 'reverts', text: `${v.revertsToday} revert${v.revertsToday === 1 ? '' : 's'}`, tone: v.revertsToday > 0 ? 'warning' : undefined });\n }\n // The reserve is what autonomy leaves you; with autonomy off it reserves nothing.\n if (v.reserve && v.authority?.effectiveSwitch !== 'off') parts.push({ key: 'reserve', text: `${v.reserve.label} ${Math.round(v.reserve.percent)}% reserved for you` });\n return parts;\n}\n\n/**\n * Which POST signs a draft: the DRAFT's own `kind` decides (B-U1: GET\n * /api/verse/authority/draft answers with `kind`, and POST refuses a digest\n * whose kind does not match the action). The clicked intent is only the\n * fallback for a server that sends no kind — a grant that is no longer\n * continuable is drafted as a NEW one, and signing it must say so.\n */\nexport function actionForDraft(draft: AuthorityGrantDraft, fallback: 'grant' | 're-approve'): 'grant' | 're-approve' {\n const kind = (draft as AuthorityGrantDraft & { kind?: unknown }).kind;\n if (kind === 'new') return 'grant';\n if (kind === 'reapprove') return 're-approve';\n return fallback;\n}\n\n/**\n * What Stop actually did, in one sentence (B-U6 → C: the Stop UI shows the\n * drain result). The POST answers with the status plus `result.stop`\n * (authority/clamp.ts StopResult). Stop from Verse never waits, so agents\n * admitted before it may still be finishing; that is said with the count,\n * never as \"stopped\" alone. Unknown leases are counted as live upstream\n * (fail closed). Null when the response carries no stop result.\n */\nexport function stopOutcomeSentence(response: unknown): string | null {\n if (response === null || typeof response !== 'object') return null;\n const stop = (response as { result?: { stop?: unknown } }).result?.stop;\n if (stop === null || typeof stop !== 'object') return null;\n const r = stop as { quiesced?: unknown; liveExecutionLeases?: unknown; mergesRevoked?: unknown; mergeRevokeFailures?: unknown };\n const live = typeof r.liveExecutionLeases === 'number' && Number.isFinite(r.liveExecutionLeases) ? Math.max(0, Math.round(r.liveExecutionLeases)) : null;\n const parts: string[] = [];\n if (r.quiesced === true || live === 0) parts.push('Stopped. No agent is still running.');\n else if (live !== null) parts.push(`Stopped. ${live} agent${live === 1 ? '' : 's'} started before Stop ${live === 1 ? 'is' : 'are'} still finishing; no new work starts.`);\n else parts.push('Stopped. Agents started before Stop may still be finishing; no new work starts.');\n if (typeof r.mergesRevoked === 'number' && r.mergesRevoked > 0) {\n parts.push(`${r.mergesRevoked} armed merge${r.mergesRevoked === 1 ? ' was' : 's were'} revoked.`);\n }\n const failed = Array.isArray(r.mergeRevokeFailures) ? r.mergeRevokeFailures.length : 0;\n if (failed > 0) parts.push(`${failed} armed merge${failed === 1 ? '' : 's'} could not be revoked; Stop still blocks ${failed === 1 ? 'it' : 'them'}.`);\n return parts.join(' ');\n}\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ ._panel_nse32_8{gap:var(--space-3);padding:var(--space-3) var(--card-pad);border:1px solid var(--border-subtle);border-radius:var(--radius-lg);background:var(--bg-surface);flex-direction:column;min-width:0;display:flex}._head_nse32_19{align-items:center;gap:var(--space-2) var(--space-3);flex-wrap:wrap;min-width:0;display:flex}._micro_nse32_27{font-family:var(--font-display);font-size:var(--text-2xs-size);line-height:var(--text-2xs-line);letter-spacing:var(--tracking-label);text-transform:uppercase;color:var(--text-tertiary);flex:none}._stage_nse32_37{font-size:var(--text-sm-size);line-height:var(--text-sm-line);font-weight:var(--font-weight-semibold);color:var(--text-primary);font-variant-numeric:tabular-nums}._position_nse32_45{font-weight:var(--font-weight-regular);color:var(--text-secondary)}._switchState_nse32_50{align-items:center;gap:var(--space-2);min-width:0;font-size:var(--text-xs-size);line-height:var(--text-xs-line);color:var(--text-secondary);display:inline-flex}._held_nse32_60{color:var(--text-tertiary);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}._spacer_nse32_67{flex:1}._grant_nse32_71{align-items:center;gap:var(--space-2);font-size:var(--text-xs-size);line-height:var(--text-xs-line);color:var(--text-secondary);font-variant-numeric:tabular-nums;display:inline-flex}._grant_nse32_71[data-tone=warning]{color:var(--status-warning-fg)}._grant_nse32_71[data-tone=danger]{color:var(--status-danger-fg)}._ladder_nse32_90{gap:var(--space-1);grid-auto-columns:minmax(0,1fr);grid-auto-flow:column;margin:0;padding:0;list-style:none;display:grid}._rungItem_nse32_100{min-width:0;display:flex}._rung_nse32_100{width:100%;min-height:var(--control-h-sm);padding:0 var(--space-1);border:1px solid var(--border-subtle);border-radius:var(--radius-sm);background:var(--bg-surface);color:var(--text-tertiary);font-size:var(--text-xs-size);line-height:var(--text-xs-line);font-variant-numeric:tabular-nums;white-space:nowrap;text-overflow:ellipsis;cursor:default;justify-content:center;align-items:center;display:flex;overflow:hidden}._rung_nse32_100[data-state=done]{background:var(--bg-hover);color:var(--text-secondary)}._rung_nse32_100[data-state=current]{border-color:var(--accent-500);background:var(--bg-selected);color:var(--text-primary);font-weight:var(--font-weight-semibold)}._rung_nse32_100[data-state=next]{border-style:dashed;border-color:var(--border-default);color:var(--text-secondary)}._rung_nse32_100:focus-visible,._linkButton_nse32_144:focus-visible,._decisionLink_nse32_145:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px}._rungTip_nse32_150{flex-direction:column;gap:2px;max-width:320px;display:flex}._progress_nse32_157{align-items:flex-end;gap:var(--space-2) var(--space-5);flex-wrap:wrap;display:flex}._meter_nse32_164{flex:0 200px;min-width:140px}._next_nse32_169{font-size:var(--text-xs-size);line-height:var(--text-xs-line);color:var(--text-secondary);flex:240px;margin:0}._unmet_nse32_177{color:var(--text-tertiary)}._last_nse32_181{align-items:baseline;gap:var(--space-3);padding-top:var(--space-2);border-top:1px solid var(--border-subtle);font-size:var(--text-xs-size);line-height:var(--text-xs-line);color:var(--text-primary);min-width:0;margin:0;display:flex}._lastText_nse32_194{flex:1;min-width:0}._last_nse32_181[data-tone=danger] ._lastText_nse32_194{color:var(--status-danger-fg)}._when_nse32_203{color:var(--text-tertiary);white-space:nowrap}._linkButton_nse32_144,._decisionLink_nse32_145{color:var(--text-link);font:inherit;font-size:var(--text-xs-size);cursor:pointer;white-space:nowrap;background:0 0;border:0;flex:none;padding:0;text-decoration:none}._linkButton_nse32_144:hover,._decisionLink_nse32_145:hover{text-decoration:underline}._stackGap_nse32_229{gap:var(--space-3);flex-direction:column;min-width:0;display:flex}._regressions_nse32_236{gap:var(--space-2);flex-direction:column;margin:0;padding:0;list-style:none;display:flex}._regression_nse32_236{align-items:baseline;gap:var(--space-1) var(--space-3);padding:var(--space-2) var(--space-3);border:1px solid var(--status-danger-solid);border-radius:var(--radius-md);background:var(--status-danger-bg);color:var(--status-danger-fg);font-size:var(--text-sm-size);line-height:var(--text-sm-line);flex-wrap:wrap;display:flex}._regressionTitle_nse32_259{font-weight:var(--font-weight-semibold)}._decisions_nse32_263{flex-direction:column;margin:0;padding:0;list-style:none;display:flex}._decision_nse32_145{gap:var(--space-1) var(--space-3);padding:var(--space-3) 0;border-top:1px solid var(--border-subtle);grid-template-columns:minmax(0,1fr) auto;min-width:0;display:grid}._decision_nse32_145:first-child{border-top:0;padding-top:0}._decisionHead_nse32_285{align-items:baseline;gap:var(--space-1) var(--space-2);min-width:0;font-size:var(--text-sm-size);line-height:var(--text-sm-line);flex-wrap:wrap;display:flex}._repo_nse32_295{font-weight:var(--font-weight-semibold);color:var(--text-primary)}._meta_nse32_300{color:var(--text-tertiary);font-size:var(--text-xs-size);line-height:var(--text-xs-line);font-variant-numeric:tabular-nums}._mono_nse32_307{font-family:var(--font-mono)}._outcome_nse32_311{padding:0 var(--space-2);border-radius:var(--radius-full);background:var(--status-neutral-bg);color:var(--status-neutral-fg);font-size:var(--text-xs-size);line-height:var(--text-xs-line);white-space:nowrap;align-items:center;display:inline-flex}._outcome_nse32_311[data-tone=success],._gate_nse32_324[data-tone=success]{background:var(--status-success-bg);color:var(--status-success-fg)}._outcome_nse32_311[data-tone=danger],._gate_nse32_324[data-tone=danger]{background:var(--status-danger-bg);color:var(--status-danger-fg)}._outcome_nse32_311[data-tone=warning],._gate_nse32_324[data-tone=warning]{background:var(--status-warning-bg);color:var(--status-warning-fg)}._why_nse32_341{color:var(--text-secondary);font-size:var(--text-xs-size);line-height:var(--text-xs-line);grid-column:1/-1;margin:0}._gates_nse32_349{gap:var(--space-1);flex-wrap:wrap;grid-column:1/-1;margin:0;padding:0;list-style:none;display:flex}._gate_nse32_324{min-width:2.5em;padding:0 var(--space-1);border-radius:var(--radius-sm);background:var(--status-neutral-bg);color:var(--status-neutral-fg);font-family:var(--font-mono);font-size:var(--text-2xs-size);line-height:var(--text-2xs-line);justify-content:center;align-items:center;display:inline-flex}._gate_nse32_324[data-tone=absent]{border:1px dashed var(--border-subtle);color:var(--text-tertiary);background:0 0}._links_nse32_379{align-items:baseline;gap:var(--space-3);display:inline-flex}._muted_nse32_385{color:var(--text-tertiary);font-size:var(--text-xs-size);line-height:var(--text-xs-line);margin:0}@media (max-width:600px){._ladder_nse32_90{grid-template-columns:repeat(4,minmax(0,1fr));grid-auto-flow:row}._last_nse32_181{flex-wrap:wrap}}
@@ -0,0 +1,2 @@
1
+ import{c as e}from"./surface-data-Dj71tdD-.js";var t=6e4,n=60*t,r=24*n,i=7*r;function a(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}var o=e=>Array.isArray(e)&&e.every(e=>typeof e==`string`);function s(e){return a(e)&&typeof e.id==`string`&&typeof e.index==`number`&&o(e.merging)&&o(e.proposing)&&a(e.criteria)&&(e.counts===`merges`||e.counts===`would-merge digests`)}function c(e){let t=e?e.ladder:null;return!a(t)||t.v!==1||!Array.isArray(t.stages)||!t.stages.every(s)?null:t}function l(e){return a(e)&&typeof e.proposalId==`string`&&typeof e.repo==`string`&&typeof e.outcome==`string`&&Array.isArray(e.gates)&&typeof e.why==`string`&&typeof e.at==`string`}function u(e){return!a(e)||e.v!==1||!Array.isArray(e.decisions)||!Array.isArray(e.moves)?null:{...e,decisions:e.decisions.filter(l),moves:e.moves.filter(e=>a(e)&&typeof e.toStageId==`string`&&typeof e.at==`string`)}}function d(e){return/^[a-z]/.test(e)?e[0].toUpperCase()+e.slice(1):e}function f(e){let t=e.indexOf(`/`);return t>=0?e.slice(t+1):e}function p(e){return e.map(f).join(`, `)}function m(e,i){let a=Date.parse(e);if(!Number.isFinite(a))return`at an unknown time`;let o=Math.max(0,i-a);return o<t?`just now`:o<n?`${Math.floor(o/t)} m ago`:o<r?`${Math.floor(o/n)} h ago`:`${Math.floor(o/r)} d ago`}function h(e){return Number.isInteger(e)?String(e):e.toFixed(1)}function g(e,t){let n=e.index<t?`done`:e.index===t?`current`:e.index===t+1?`next`:`later`,r=e.merging.length>0?`Merging: ${p(e.merging)}`:`Nothing merges — propose only`,i=e.proposing.length>0?`Proposing: ${p(e.proposing)}`:null,a=`${e.maxRisk} risk · ≤ ${e.maxFiles} files / ${e.maxLines} lines${e.maxMergesPerRepoPerDay>0?` · ≤ ${e.maxMergesPerRepoPerDay} merges/repo/day`:``}`,o=e.criteria,s=[`${o.minMerges} ${o.minMerges===1?e.counts.replace(/s$/,``):e.counts}`,`${o.minHours} h`];o.minPostMergeGreenPct>0&&s.push(`≥ ${o.minPostMergeGreenPct}% green`);let c=`Leaves after ${s.join(`, `)}`,l=d(e.id),u=n===`current`?` (current)`:n===`done`?` (passed)`:``;return{id:e.id,label:l,index:e.index,state:n,merging:e.merging,proposing:e.proposing,mergeLine:r,proposeLine:i,capLine:a,exitLine:c,aria:[`Stage ${e.index+1}, ${l}${u}`,r,i,a,c].filter(Boolean).join(`. `)+`.`}}var _=/^\d+ of \d+ (merges|would-merge digests)$|^\d+ h of \d+ h$/;function v(e){if(!e||e.grant.state!==`active`)return null;let t=c(e),n=e.rollout;if(!t||!n||t.stages.length===0)return null;let r=t.stages[n.stageIndex];if(!r||r.id!==n.stageId)return null;let i=n.criteria,a=[{key:`evidence`,label:r.counts===`merges`?`Merges`:`Would-merge digests`,value:n.merges,max:i.minMerges,text:`${n.merges} / ${i.minMerges}`,met:n.merges>=i.minMerges},{key:`hours`,label:`Hours in stage`,value:Math.min(n.hoursInStage,i.minHours),max:i.minHours,text:`${h(Math.floor(n.hoursInStage*10)/10)} h / ${i.minHours} h`,met:n.hoursInStage>=i.minHours}],o=t.stages[n.stageIndex+1]??null,s=o?o.merging.filter(e=>!r.merging.includes(e)):[],l=o?s.length>0?`${d(o.id)} lets ${p(s)} merge`:`${d(o.id)}: ${o.maxRisk} risk, ≤ ${o.maxFiles} files / ${o.maxLines} lines`:null;return{stageId:n.stageId,stageName:d(n.stageId),position:`${n.stageIndex+1} of ${n.stageCount}`,rungs:t.stages.map(e=>g(e,n.stageIndex)),bars:a,nextStageName:n.nextStageId?d(n.nextStageId):null,met:n.met,otherUnmet:n.unmet.filter(e=>!_.test(e)),nextLine:l}}function y(e,a){if(!e||e.grant.state!==`active`||!e.grant.expiresAt)return null;let o=Date.parse(e.grant.expiresAt);if(!Number.isFinite(o))return null;let s=o-a,c=Math.floor(s/r),l=Math.floor((s-c*r)/n);return{text:s<=0?`expired`:s>=3*r?`${c} d left`:s>=r?`${c} d ${l} h left`:s>=n?`${Math.floor(s/n)} h left`:`${Math.max(1,Math.floor(s/t))} m left`,tone:s<r?`danger`:s<6048e5?`warning`:`success`,warn:s<i,until:new Date(o).toLocaleString(`en-US`,{month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`})}}function b(e){if(e.move===`regressed`){let t=e.breach?`: ${e.breach.replace(/[.]$/,``)}`:``;return{text:`Dropped back to ${d(e.toStageId)}${e.fromStageId?` from ${d(e.fromStageId)}`:``}${t}.`,tone:`danger`,at:e.at}}return{text:`Advanced to ${d(e.toStageId)}${e.fromStageId?` from ${d(e.fromStageId)}`:``}.`,tone:`success`,at:e.at}}var x={"would-merge":`Would merge`,merged:`Merged`,refused:`Refused`,"owner-lane":`Owner lane`,waiting:`Waiting`,"in-progress":`In the gates`},S={"would-merge":`success`,merged:`success`,refused:`danger`,"owner-lane":`warning`,waiting:`neutral`,"in-progress":`neutral`};function C(e){let t=e.prNumber===null?f(e.repo):`${f(e.repo)} #${e.prNumber}`,n=S[e.outcome];switch(e.outcome){case`would-merge`:return{text:`Would merge ${t} — every gate passed.`,tone:n,at:e.at};case`merged`:return{text:`Merged ${t}.`,tone:n,at:e.at};default:return{text:`${t}: ${e.why}`,tone:n,at:e.at}}}function w(e,t){let n=[];e?.lastMove&&n.push(b(e.lastMove)),t?.moves[0]&&n.push(b(t.moves[0])),t?.decisions[0]&&n.push(C(t.decisions[0]));let r=n.filter(e=>e.at!==null&&Number.isFinite(Date.parse(e.at)));return r.sort((e,t)=>Date.parse(t.at)-Date.parse(e.at)),r[0]?r[0]:t?{text:`Nothing has reached the merge gates yet under this grant.`,tone:`neutral`,at:null}:t===null?{text:`The latest decision could not be read.`,tone:`unknown`,at:null}:{text:`Reading the latest decision…`,tone:`unknown`,at:null}}function T(e,t=3){return(e?.moves??[]).filter(e=>e.move===`regressed`).slice(0,t)}function E(e){if(e.files===null&&e.linesAdded===null)return null;let t=[];return(e.linesAdded!==null||e.linesDeleted!==null)&&t.push(`+${e.linesAdded??0} −${e.linesDeleted??0}`),e.files!==null&&t.push(`${e.files} file${e.files===1?``:`s`}`),e.risk&&t.push(`${e.risk} risk`),t.join(` · `)}function D(e){return e.prNumber===null||!/^[A-Za-z0-9-]+\/[A-Za-z0-9._-]+$/.test(e.repo)?null:`https://github.com/${e.repo}/pull/${e.prNumber}`}function O(e,t){let n=(t??[]).find(t=>t.intake?.proposalId===e.proposalId&&t.repo.toLowerCase()===e.repo.toLowerCase());return n?{id:n.id,title:n.title}:null}function k(e){return e===`pass`?`success`:e===`refuse`?`danger`:e===`owner-lane`?`warning`:`neutral`}var A=`/api/verse/authority/ledger?view=decisions&limit=40`,j=`verse-authority-decisions`,M=3e4,N=e(j,A,`Shadow decisions`,u),P={panel:`_panel_nse32_8`,head:`_head_nse32_19`,micro:`_micro_nse32_27`,stage:`_stage_nse32_37`,position:`_position_nse32_45`,switchState:`_switchState_nse32_50`,held:`_held_nse32_60`,spacer:`_spacer_nse32_67`,grant:`_grant_nse32_71`,ladder:`_ladder_nse32_90`,rungItem:`_rungItem_nse32_100`,rung:`_rung_nse32_100`,linkButton:`_linkButton_nse32_144`,decisionLink:`_decisionLink_nse32_145`,rungTip:`_rungTip_nse32_150`,progress:`_progress_nse32_157`,meter:`_meter_nse32_164`,next:`_next_nse32_169`,unmet:`_unmet_nse32_177`,last:`_last_nse32_181`,lastText:`_lastText_nse32_194`,when:`_when_nse32_203`,stackGap:`_stackGap_nse32_229`,regressions:`_regressions_nse32_236`,regression:`_regression_nse32_236`,regressionTitle:`_regressionTitle_nse32_259`,decisions:`_decisions_nse32_263`,decision:`_decision_nse32_145`,decisionHead:`_decisionHead_nse32_285`,repo:`_repo_nse32_295`,meta:`_meta_nse32_300`,mono:`_mono_nse32_307`,outcome:`_outcome_nse32_311`,gate:`_gate_nse32_324`,why:`_why_nse32_341`,gates:`_gates_nse32_349`,links:`_links_nse32_379`,muted:`_muted_nse32_385`};export{d as _,x as a,k as c,w as d,c as f,E as g,f as h,S as i,y as l,T as m,M as n,m as o,D as p,N as r,O as s,P as t,v as u};
2
+ //# sourceMappingURL=autonomy-ladder.module-ArDv4bkr.js.map