@opengeni/react 3.3.2 → 3.4.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 (855) hide show
  1. package/README.md +769 -22
  2. package/dist/accounts.js +2 -0
  3. package/dist/accounts.js.map +1 -1
  4. package/dist/approvals.d.ts +2 -1
  5. package/dist/artifacts-document.js +5 -3
  6. package/dist/artifacts-presentation.js +5 -3
  7. package/dist/artifacts-spreadsheet.d.ts +1 -1
  8. package/dist/artifacts-spreadsheet.js +5 -3
  9. package/dist/artifacts.d.ts +5 -1
  10. package/dist/artifacts.js +536 -42
  11. package/dist/artifacts.js.map +1 -1
  12. package/dist/browser-viewer-ZWR6MWJ7.js +19 -0
  13. package/dist/capability-catalog-row.d.ts +20 -0
  14. package/dist/capability-logo-fallback.d.ts +3 -0
  15. package/dist/chat-interactive-block-4EUKJXUO.js +14 -0
  16. package/dist/chunk-2DDJ6YH6.js +41 -0
  17. package/dist/chunk-2DDJ6YH6.js.map +1 -0
  18. package/dist/chunk-2HVLQ26H.js +183 -0
  19. package/dist/chunk-2HVLQ26H.js.map +1 -0
  20. package/dist/{chunk-XYRDDSXF.js → chunk-2I6R3GCZ.js} +4285 -3980
  21. package/dist/chunk-2I6R3GCZ.js.map +1 -0
  22. package/dist/{chunk-JAQ5K7W6.js → chunk-2SFFYIH3.js} +1178 -166
  23. package/dist/chunk-2SFFYIH3.js.map +1 -0
  24. package/dist/chunk-3PVDYTTB.js +24 -0
  25. package/dist/chunk-3PVDYTTB.js.map +1 -0
  26. package/dist/chunk-3RJKUVCA.js +14068 -0
  27. package/dist/chunk-3RJKUVCA.js.map +1 -0
  28. package/dist/chunk-3UZCWK46.js +298 -0
  29. package/dist/chunk-3UZCWK46.js.map +1 -0
  30. package/dist/chunk-47CKUXTW.js +293 -0
  31. package/dist/chunk-47CKUXTW.js.map +1 -0
  32. package/dist/chunk-4QYP6QUI.js +109 -0
  33. package/dist/chunk-4QYP6QUI.js.map +1 -0
  34. package/dist/chunk-5EY26VZ7.js +1053 -0
  35. package/dist/chunk-5EY26VZ7.js.map +1 -0
  36. package/dist/chunk-5I4VRWBB.js +56 -0
  37. package/dist/chunk-5I4VRWBB.js.map +1 -0
  38. package/dist/chunk-5WOR7UCL.js +191 -0
  39. package/dist/chunk-5WOR7UCL.js.map +1 -0
  40. package/dist/chunk-5YJLGOM5.js +51 -0
  41. package/dist/chunk-5YJLGOM5.js.map +1 -0
  42. package/dist/chunk-6JFN3OWG.js +386 -0
  43. package/dist/chunk-6JFN3OWG.js.map +1 -0
  44. package/dist/chunk-7QJT5O4S.js +35 -0
  45. package/dist/chunk-7QJT5O4S.js.map +1 -0
  46. package/dist/chunk-A55KV72M.js +402 -0
  47. package/dist/chunk-A55KV72M.js.map +1 -0
  48. package/dist/chunk-ADWCLI4G.js +2028 -0
  49. package/dist/chunk-ADWCLI4G.js.map +1 -0
  50. package/dist/chunk-B27E3V37.js +29 -0
  51. package/dist/chunk-B27E3V37.js.map +1 -0
  52. package/dist/chunk-B7TC2A33.js +83 -0
  53. package/dist/chunk-B7TC2A33.js.map +1 -0
  54. package/dist/chunk-BLL56F7R.js +385 -0
  55. package/dist/chunk-BLL56F7R.js.map +1 -0
  56. package/dist/chunk-BOFEQC6K.js +162 -0
  57. package/dist/chunk-BOFEQC6K.js.map +1 -0
  58. package/dist/chunk-CM7LVUKC.js +35 -0
  59. package/dist/chunk-CM7LVUKC.js.map +1 -0
  60. package/dist/chunk-CORUP6JB.js +122 -0
  61. package/dist/chunk-CORUP6JB.js.map +1 -0
  62. package/dist/chunk-CSX5FFKZ.js +35 -0
  63. package/dist/chunk-CSX5FFKZ.js.map +1 -0
  64. package/dist/chunk-EGVHJKGJ.js +3125 -0
  65. package/dist/chunk-EGVHJKGJ.js.map +1 -0
  66. package/dist/{chunk-NEXLLTP4.js → chunk-G76LSA76.js} +6 -5
  67. package/dist/chunk-G76LSA76.js.map +1 -0
  68. package/dist/{chunk-PEI6RANI.js → chunk-GQMRL52F.js} +311 -75
  69. package/dist/chunk-GQMRL52F.js.map +1 -0
  70. package/dist/{chunk-ELIYWBZR.js → chunk-GUUXOISA.js} +1113 -457
  71. package/dist/chunk-GUUXOISA.js.map +1 -0
  72. package/dist/{chunk-HUIKIDM5.js → chunk-I7X2P4FU.js} +225 -116
  73. package/dist/chunk-I7X2P4FU.js.map +1 -0
  74. package/dist/chunk-IGFZFLI2.js +1390 -0
  75. package/dist/chunk-IGFZFLI2.js.map +1 -0
  76. package/dist/{chunk-4MDLEHXL.js → chunk-IMSUVYQB.js} +26 -13
  77. package/dist/chunk-IMSUVYQB.js.map +1 -0
  78. package/dist/chunk-IOYHDEP3.js +38 -0
  79. package/dist/chunk-IOYHDEP3.js.map +1 -0
  80. package/dist/chunk-IZV5FTJC.js +55 -0
  81. package/dist/chunk-IZV5FTJC.js.map +1 -0
  82. package/dist/chunk-KF33GTWN.js +343 -0
  83. package/dist/chunk-KF33GTWN.js.map +1 -0
  84. package/dist/chunk-KSGQ5ODA.js +457 -0
  85. package/dist/chunk-KSGQ5ODA.js.map +1 -0
  86. package/dist/{chunk-ZPBTI3TE.js → chunk-KZC6QRNR.js} +1513 -697
  87. package/dist/chunk-KZC6QRNR.js.map +1 -0
  88. package/dist/chunk-LJUMYUBO.js +218 -0
  89. package/dist/chunk-LJUMYUBO.js.map +1 -0
  90. package/dist/chunk-LSW2OJVV.js +380 -0
  91. package/dist/chunk-LSW2OJVV.js.map +1 -0
  92. package/dist/chunk-M357MHH3.js +2 -0
  93. package/dist/chunk-M357MHH3.js.map +1 -0
  94. package/dist/chunk-MK2TQO4Y.js +24 -0
  95. package/dist/chunk-MK2TQO4Y.js.map +1 -0
  96. package/dist/chunk-N7S72EXK.js +25 -0
  97. package/dist/chunk-N7S72EXK.js.map +1 -0
  98. package/dist/{chunk-YVCHAQZY.js → chunk-NKMYZFHA.js} +616 -621
  99. package/dist/chunk-NKMYZFHA.js.map +1 -0
  100. package/dist/chunk-NX4ADH73.js +14 -0
  101. package/dist/chunk-NX4ADH73.js.map +1 -0
  102. package/dist/chunk-O7F6UJO4.js +71 -0
  103. package/dist/chunk-O7F6UJO4.js.map +1 -0
  104. package/dist/chunk-OYQQJL3J.js +16 -0
  105. package/dist/chunk-OYQQJL3J.js.map +1 -0
  106. package/dist/{chunk-H5YGYNXS.js → chunk-P4BNUO57.js} +60 -17
  107. package/dist/chunk-P4BNUO57.js.map +1 -0
  108. package/dist/{chunk-JVYQRRC4.js → chunk-PEHTX3V7.js} +21 -1
  109. package/dist/chunk-PEHTX3V7.js.map +1 -0
  110. package/dist/chunk-PMV53IMM.js +26 -0
  111. package/dist/chunk-PMV53IMM.js.map +1 -0
  112. package/dist/{chunk-KCGXPP5V.js → chunk-PYEOPA4M.js} +13 -7
  113. package/dist/chunk-PYEOPA4M.js.map +1 -0
  114. package/dist/{chunk-KZ73RL76.js → chunk-QHUE7E4N.js} +8 -3
  115. package/dist/chunk-QHUE7E4N.js.map +1 -0
  116. package/dist/chunk-QV3DJVRZ.js +11 -0
  117. package/dist/chunk-QV3DJVRZ.js.map +1 -0
  118. package/dist/chunk-R5SBNG7S.js +810 -0
  119. package/dist/chunk-R5SBNG7S.js.map +1 -0
  120. package/dist/chunk-RI42H5IU.js +326 -0
  121. package/dist/chunk-RI42H5IU.js.map +1 -0
  122. package/dist/chunk-S2QH6EZ5.js +211 -0
  123. package/dist/chunk-S2QH6EZ5.js.map +1 -0
  124. package/dist/chunk-SHLZMAJN.js +304 -0
  125. package/dist/chunk-SHLZMAJN.js.map +1 -0
  126. package/dist/chunk-TGXK4BAZ.js +293 -0
  127. package/dist/chunk-TGXK4BAZ.js.map +1 -0
  128. package/dist/{chunk-5YK2ZDIG.js → chunk-TNEZNMSN.js} +4 -10
  129. package/dist/chunk-TNEZNMSN.js.map +1 -0
  130. package/dist/{chunk-22KP6LR5.js → chunk-TXS65BB2.js} +3 -1
  131. package/dist/{chunk-22KP6LR5.js.map → chunk-TXS65BB2.js.map} +1 -1
  132. package/dist/chunk-UNJPZGNK.js +63 -0
  133. package/dist/chunk-UNJPZGNK.js.map +1 -0
  134. package/dist/{chunk-IOLVN74D.js → chunk-V5ZUJT2T.js} +175 -42
  135. package/dist/chunk-V5ZUJT2T.js.map +1 -0
  136. package/dist/chunk-WBJY57A3.js +402 -0
  137. package/dist/chunk-WBJY57A3.js.map +1 -0
  138. package/dist/chunk-WIUKB3LD.js +1911 -0
  139. package/dist/chunk-WIUKB3LD.js.map +1 -0
  140. package/dist/{chunk-ICA6R6TW.js → chunk-WNN7NO2N.js} +1451 -355
  141. package/dist/chunk-WNN7NO2N.js.map +1 -0
  142. package/dist/{chunk-3AGBGTRT.js → chunk-X5UVUIMF.js} +1712 -1174
  143. package/dist/chunk-X5UVUIMF.js.map +1 -0
  144. package/dist/chunk-XDA5QJE7.js +402 -0
  145. package/dist/chunk-XDA5QJE7.js.map +1 -0
  146. package/dist/{chunk-VZTQ73XT.js → chunk-XEA5BCMA.js} +3 -1
  147. package/dist/{chunk-VZTQ73XT.js.map → chunk-XEA5BCMA.js.map} +1 -1
  148. package/dist/chunk-XHF7OYAN.js +1150 -0
  149. package/dist/chunk-XHF7OYAN.js.map +1 -0
  150. package/dist/chunk-YSRBFJMQ.js +43 -0
  151. package/dist/chunk-YSRBFJMQ.js.map +1 -0
  152. package/dist/chunk-ZOZAPAUO.js +174 -0
  153. package/dist/chunk-ZOZAPAUO.js.map +1 -0
  154. package/dist/chunk-ZQV5W7YC.js +809 -0
  155. package/dist/chunk-ZQV5W7YC.js.map +1 -0
  156. package/dist/chunk-ZUWF4NF7.js +13 -0
  157. package/dist/chunk-ZUWF4NF7.js.map +1 -0
  158. package/dist/client.d.ts +16 -7
  159. package/dist/clipboard.js +3 -1
  160. package/dist/commands/types.d.ts +2 -0
  161. package/dist/components/anthropic-mark.d.ts +3 -0
  162. package/dist/components/approval-surface.d.ts +19 -6
  163. package/dist/components/artifacts/artifact-chrome.d.ts +120 -0
  164. package/dist/components/artifacts/artifact-sandbox.d.ts +30 -0
  165. package/dist/components/artifacts/artifact-surface.d.ts +4 -2
  166. package/dist/components/artifacts/chat-interactive-block.d.ts +29 -0
  167. package/dist/components/artifacts/deferred-chat-media.d.ts +15 -0
  168. package/dist/components/artifacts/document-editor.d.ts +4 -2
  169. package/dist/components/artifacts/editable-artifact-ui.d.ts +2 -1
  170. package/dist/components/artifacts/editable-artifact-view.d.ts +48 -0
  171. package/dist/components/artifacts/editable-document.d.ts +1 -1
  172. package/dist/components/artifacts/editable-presentation.d.ts +2 -2
  173. package/dist/components/artifacts/editable-spreadsheet.d.ts +8 -3
  174. package/dist/components/artifacts/index.d.ts +9 -2
  175. package/dist/components/artifacts/inline-html-document.d.ts +2 -0
  176. package/dist/components/artifacts/latest-task-runner.d.ts +15 -0
  177. package/dist/components/artifacts/presentation-editor.d.ts +6 -2
  178. package/dist/components/artifacts/published-html-artifact-frame.d.ts +23 -3
  179. package/dist/components/artifacts/session-artifact-viewer.d.ts +39 -0
  180. package/dist/components/artifacts/site-view.d.ts +26 -0
  181. package/dist/components/artifacts/spreadsheet-command-queue.d.ts +20 -0
  182. package/dist/components/artifacts/spreadsheet-download.d.ts +7 -0
  183. package/dist/components/artifacts/spreadsheet-general-display.d.ts +24 -0
  184. package/dist/components/artifacts/spreadsheet-grid.d.ts +10 -3
  185. package/dist/components/artifacts/spreadsheet-resize.d.ts +50 -0
  186. package/dist/components/artifacts/spreadsheet-submissions.d.ts +9 -0
  187. package/dist/components/artifacts/visualization-assets.gen.d.ts +2 -0
  188. package/dist/components/browser-select-control.d.ts +16 -0
  189. package/dist/components/browser-viewer.d.ts +11 -2
  190. package/dist/components/chat-composer.d.ts +21 -3
  191. package/dist/components/child-session-link.d.ts +9 -0
  192. package/dist/components/claude-mark.d.ts +3 -0
  193. package/dist/components/code-editor.d.ts +1 -4
  194. package/dist/components/composer-transcription-control.d.ts +7 -0
  195. package/dist/components/composer.d.ts +34 -67
  196. package/dist/components/computer-viewer.d.ts +1 -1
  197. package/dist/components/copy-button.d.ts +3 -1
  198. package/dist/components/desktop-viewer.d.ts +1 -1
  199. package/dist/components/grok-mark.d.ts +26 -0
  200. package/dist/components/human-input-form.d.ts +28 -32
  201. package/dist/components/human-input-surface.d.ts +7 -2
  202. package/dist/components/linkified-text.d.ts +18 -0
  203. package/dist/components/machine-input-display.d.ts +22 -1
  204. package/dist/components/machines/agent-status-icon.d.ts +6 -0
  205. package/dist/components/machines/machine-detail.d.ts +7 -1
  206. package/dist/components/machines/machine-status.d.ts +48 -0
  207. package/dist/components/markdown-table-layout.d.ts +18 -0
  208. package/dist/components/markdown.d.ts +37 -4
  209. package/dist/components/message-timeline.d.ts +86 -7
  210. package/dist/components/model-mark.d.ts +29 -0
  211. package/dist/components/model-policy-picker-menu.d.ts +9 -0
  212. package/dist/components/model-policy-picker.d.ts +35 -28
  213. package/dist/components/new-conversation.d.ts +32 -0
  214. package/dist/components/open-geni-chat.d.ts +73 -0
  215. package/dist/components/open-geni-links.d.ts +68 -0
  216. package/dist/components/openrouter-mark.d.ts +6 -0
  217. package/dist/components/opper-mark.d.ts +7 -0
  218. package/dist/components/preview-loading.d.ts +2 -0
  219. package/dist/components/provider-recovery-notice.d.ts +16 -0
  220. package/dist/components/queue-item-content.d.ts +9 -0
  221. package/dist/components/rehype-secret-refs.d.ts +23 -0
  222. package/dist/components/remark-soft-line-breaks.d.ts +38 -0
  223. package/dist/components/sandbox-files.d.ts +3 -1
  224. package/dist/components/sandbox-workspace.d.ts +18 -0
  225. package/dist/components/secret-question-field.d.ts +31 -0
  226. package/dist/components/secret-ref-chip.d.ts +35 -0
  227. package/dist/components/session-capability-frame.d.ts +37 -0
  228. package/dist/components/session-chrome.d.ts +57 -8
  229. package/dist/components/session-commands-panel.d.ts +6 -0
  230. package/dist/components/session-commands.d.ts +6 -0
  231. package/dist/components/session-connection-request.d.ts +8 -0
  232. package/dist/components/session-conversation.d.ts +157 -0
  233. package/dist/components/session-list.d.ts +39 -0
  234. package/dist/components/session-mcp-capability-card.d.ts +41 -0
  235. package/dist/components/session-proxy-scope.d.ts +35 -0
  236. package/dist/components/session-status.d.ts +4 -1
  237. package/dist/components/session-usage-limit-notice.d.ts +39 -0
  238. package/dist/components/timeline-anchor.d.ts +24 -0
  239. package/dist/components/timeline-annotation-chrome.d.ts +25 -0
  240. package/dist/components/timeline-annotation-layout.d.ts +42 -0
  241. package/dist/components/timeline-annotation-markers.d.ts +8 -0
  242. package/dist/components/timeline-annotation-reveal-context.d.ts +4 -0
  243. package/dist/components/timeline-annotation-shared.d.ts +31 -0
  244. package/dist/components/timeline-annotations-dialog.d.ts +3 -2
  245. package/dist/components/timeline-annotations.d.ts +13 -3
  246. package/dist/components/timeline-reading-progress.d.ts +11 -0
  247. package/dist/components/timeline-search.d.ts +34 -0
  248. package/dist/components/timeline-settlement.d.ts +16 -0
  249. package/dist/components/tool-action-review.d.ts +47 -0
  250. package/dist/components/tool-review-history.d.ts +25 -0
  251. package/dist/components/usage-limit-notice.d.ts +49 -0
  252. package/dist/components/usage-member-list.d.ts +91 -0
  253. package/dist/components/usage-meter.d.ts +73 -0
  254. package/dist/components/use-viewer-menu-dismiss.d.ts +2 -0
  255. package/dist/components/user-message-body.d.ts +10 -1
  256. package/dist/composer-messages.d.ts +74 -0
  257. package/dist/composer-messages.js +9 -0
  258. package/dist/composer-messages.js.map +1 -0
  259. package/dist/composer-voice-events.d.ts +8 -0
  260. package/dist/composer.d.ts +5 -4
  261. package/dist/composer.js +26 -13
  262. package/dist/computer-viewer-GMLDXPON.js +20 -0
  263. package/dist/computer-viewer-GMLDXPON.js.map +1 -0
  264. package/dist/connect-account-identity.d.ts +8 -0
  265. package/dist/connect-accounts.d.ts +15 -0
  266. package/dist/connect-chooser.d.ts +18 -0
  267. package/dist/connect-panel.d.ts +18 -0
  268. package/dist/connect-setup.d.ts +18 -0
  269. package/dist/connect.d.ts +21 -0
  270. package/dist/connect.js +2149 -0
  271. package/dist/connect.js.map +1 -0
  272. package/dist/connection-catalog.d.ts +38 -0
  273. package/dist/connection-discovery.d.ts +12 -0
  274. package/dist/connection-installed.d.ts +17 -0
  275. package/dist/connection-logo.d.ts +9 -0
  276. package/dist/connection-service-logo.d.ts +8 -0
  277. package/dist/connection-service-presentation.d.ts +13 -0
  278. package/dist/connection-skeleton.d.ts +5 -0
  279. package/dist/connection-type-picker.d.ts +6 -0
  280. package/dist/conversation-timeline.d.ts +5 -0
  281. package/dist/desktop.d.ts +7 -0
  282. package/dist/desktop.js +27 -0
  283. package/dist/desktop.js.map +1 -0
  284. package/dist/device-authorization.d.ts +23 -0
  285. package/dist/diffs.d.ts +8 -0
  286. package/dist/diffs.js +15 -0
  287. package/dist/diffs.js.map +1 -0
  288. package/dist/discovery-cache.d.ts +5 -0
  289. package/dist/editor.d.ts +7 -0
  290. package/dist/editor.js +22 -0
  291. package/dist/editor.js.map +1 -0
  292. package/dist/embedded-new-voice-OCRNT6U5.js +18 -0
  293. package/dist/embedded-new-voice-OCRNT6U5.js.map +1 -0
  294. package/dist/embedded-voice-RPHPYVBT.js +18 -0
  295. package/dist/embedded-voice-RPHPYVBT.js.map +1 -0
  296. package/dist/{fleet-decision-row-GGCAT4E4.js → fleet-decision-row-SI63O5V4.js} +4 -1
  297. package/dist/fleet-decision-row-SI63O5V4.js.map +1 -0
  298. package/dist/hooks/latest-question.d.ts +25 -0
  299. package/dist/hooks/shared-machines-list.d.ts +4 -0
  300. package/dist/hooks/shared-query.d.ts +113 -0
  301. package/dist/hooks/use-attached-browsers.d.ts +1 -1
  302. package/dist/hooks/use-auth-runs.d.ts +1 -4
  303. package/dist/hooks/use-available-models.d.ts +1 -1
  304. package/dist/hooks/use-browser-frame-stream.d.ts +1 -1
  305. package/dist/hooks/use-browser-session.d.ts +12 -1
  306. package/dist/hooks/use-client-config-flags.d.ts +49 -0
  307. package/dist/hooks/use-codex-accounts.d.ts +59 -10
  308. package/dist/hooks/use-composer.d.ts +24 -2
  309. package/dist/hooks/use-computer-frame-stream.d.ts +1 -1
  310. package/dist/hooks/use-computer-input-posture.d.ts +13 -0
  311. package/dist/hooks/use-computer-session.d.ts +4 -0
  312. package/dist/hooks/use-connect.d.ts +23 -0
  313. package/dist/hooks/use-desktop-stream.d.ts +1 -1
  314. package/dist/hooks/use-file-attachments.d.ts +12 -0
  315. package/dist/hooks/use-goal.d.ts +2 -1
  316. package/dist/hooks/use-last-started-turn-policy.d.ts +5 -1
  317. package/dist/hooks/use-new-conversation.d.ts +56 -0
  318. package/dist/hooks/use-new-session-draft.d.ts +74 -0
  319. package/dist/hooks/use-realtime-voice-models.d.ts +7 -0
  320. package/dist/hooks/use-sandbox-files.d.ts +4 -1
  321. package/dist/hooks/use-session-conversation.d.ts +49 -0
  322. package/dist/hooks/use-session-events.d.ts +26 -5
  323. package/dist/hooks/use-session-mcp-approval-policy.d.ts +2 -2
  324. package/dist/hooks/use-session-model-account.d.ts +48 -0
  325. package/dist/hooks/use-supergrok-accounts.d.ts +7 -1
  326. package/dist/hooks/use-terminal-stream.d.ts +11 -5
  327. package/dist/hooks/use-usage.d.ts +40 -0
  328. package/dist/hooks/use-vaults.d.ts +53 -0
  329. package/dist/hooks/use-voice-input.d.ts +8 -1
  330. package/dist/hooks/use-workspace-edit.d.ts +4 -0
  331. package/dist/hooks/use-workspace-sessions.d.ts +24 -5
  332. package/dist/human-input-model.d.ts +122 -0
  333. package/dist/identity-link-accounts.d.ts +11 -0
  334. package/dist/identity-link-consent.d.ts +18 -0
  335. package/dist/index.d.ts +82 -20
  336. package/dist/index.js +2340 -6603
  337. package/dist/index.js.map +1 -1
  338. package/dist/interaction.d.ts +1 -1
  339. package/dist/interaction.js +14 -24
  340. package/dist/interaction.js.map +1 -1
  341. package/dist/latest-question-R77KWSUP.js +118 -0
  342. package/dist/latest-question-R77KWSUP.js.map +1 -0
  343. package/dist/lib/clipboard.d.ts +7 -0
  344. package/dist/lib/error-message.d.ts +7 -0
  345. package/dist/lib/format.d.ts +58 -4
  346. package/dist/lib/host-theme.d.ts +77 -0
  347. package/dist/lib/interaction-errors.d.ts +3 -0
  348. package/dist/lib/menu-styles.d.ts +22 -0
  349. package/dist/lib/notify-observer.d.ts +2 -0
  350. package/dist/lib/pierre-diffs-loader.d.ts +20 -0
  351. package/dist/lib/provider-recovery.d.ts +55 -0
  352. package/dist/lib/scrollbars.d.ts +11 -0
  353. package/dist/lib/terminal-input-readiness.d.ts +11 -0
  354. package/dist/lib/transient-retry.d.ts +25 -0
  355. package/dist/lib/workbench-peers.d.ts +36 -0
  356. package/dist/lib/xterm-theme.d.ts +7 -5
  357. package/dist/machines.js +9 -5
  358. package/dist/markdown-table-layout-3PV2UAAH.js +113 -0
  359. package/dist/markdown-table-layout-3PV2UAAH.js.map +1 -0
  360. package/dist/mcp-connection-status.d.ts +14 -0
  361. package/dist/model-mark-paths.d.ts +34 -0
  362. package/dist/model-mark-paths.js +16 -0
  363. package/dist/model-mark-paths.js.map +1 -0
  364. package/dist/model-picker-model.d.ts +111 -0
  365. package/dist/model-picker-model.js +25 -0
  366. package/dist/model-picker-model.js.map +1 -0
  367. package/dist/model-policy-picker-menu-7GJ5URPR.js +17 -0
  368. package/dist/model-policy-picker-menu-7GJ5URPR.js.map +1 -0
  369. package/dist/model-policy.d.ts +30 -3
  370. package/dist/model-policy.js +14 -1
  371. package/dist/native-previews.d.ts +28 -0
  372. package/dist/native-previews.js +82 -0
  373. package/dist/native-previews.js.map +1 -0
  374. package/dist/new-session-draft.d.ts +7 -0
  375. package/dist/new-session-draft.js +639 -0
  376. package/dist/new-session-draft.js.map +1 -0
  377. package/dist/notification-text.d.ts +27 -0
  378. package/dist/{noto-sans-arabic-loader-IA2T4X2A.js → noto-sans-arabic-loader-XSH2KYWJ.js} +3 -1
  379. package/dist/{noto-sans-arabic-loader-IA2T4X2A.js.map → noto-sans-arabic-loader-XSH2KYWJ.js.map} +1 -1
  380. package/dist/{noto-sans-jp-loader.generated-HFGLYBR3.js → noto-sans-jp-loader.generated-MR5L6V7K.js} +3 -1
  381. package/dist/{noto-sans-jp-loader.generated-HFGLYBR3.js.map → noto-sans-jp-loader.generated-MR5L6V7K.js.map} +1 -1
  382. package/dist/older-history.d.ts +3 -2
  383. package/dist/organization-model.d.ts +32 -0
  384. package/dist/organization-model.js +65 -0
  385. package/dist/organization-model.js.map +1 -0
  386. package/dist/{platform-activity-row-BJHUHXAT.js → platform-activity-row-5OCKOQWZ.js} +16 -78
  387. package/dist/platform-activity-row-5OCKOQWZ.js.map +1 -0
  388. package/dist/plugin-details.d.ts +14 -0
  389. package/dist/plugin-discovery.d.ts +25 -0
  390. package/dist/preview-loading-paint.d.ts +20 -0
  391. package/dist/provider.d.ts +25 -2
  392. package/dist/queue-presentation-model.d.ts +72 -0
  393. package/dist/queue-presentation-model.js +38 -0
  394. package/dist/queue-presentation-model.js.map +1 -0
  395. package/dist/{queue-surface-implementation-BSKUWHRI.js → queue-surface-implementation-GJBH7NKO.js} +65 -265
  396. package/dist/queue-surface-implementation-GJBH7NKO.js.map +1 -0
  397. package/dist/realtime/embedded-new-voice.d.ts +1 -0
  398. package/dist/realtime/embedded-voice.d.ts +1 -0
  399. package/dist/realtime/realtime-control.d.ts +4 -65
  400. package/dist/realtime/session-realtime.d.ts +78 -0
  401. package/dist/realtime.js +25 -1333
  402. package/dist/realtime.js.map +1 -1
  403. package/dist/sandbox-files-O27IPOZW.js +21 -0
  404. package/dist/sandbox-files-O27IPOZW.js.map +1 -0
  405. package/dist/sandbox-label-model.d.ts +30 -0
  406. package/dist/sandbox-label-model.js +20 -0
  407. package/dist/sandbox-label-model.js.map +1 -0
  408. package/dist/scrollbars.d.ts +1 -0
  409. package/dist/scrollbars.js +10 -0
  410. package/dist/scrollbars.js.map +1 -0
  411. package/dist/secret-reference-label.d.ts +14 -0
  412. package/dist/secrets-ui.d.ts +57 -0
  413. package/dist/session-agents-model.d.ts +10 -0
  414. package/dist/session-agents-model.js +25 -0
  415. package/dist/session-agents-model.js.map +1 -0
  416. package/dist/session-attention-model.d.ts +8 -0
  417. package/dist/session-attention-model.js +47 -0
  418. package/dist/session-attention-model.js.map +1 -0
  419. package/dist/session-auth-recommendation.d.ts +5 -0
  420. package/dist/session-capability-policy.d.ts +31 -0
  421. package/dist/session-feedback-model.d.ts +20 -0
  422. package/dist/session-feedback-model.js +56 -0
  423. package/dist/session-feedback-model.js.map +1 -0
  424. package/dist/session-list-model.d.ts +138 -0
  425. package/dist/session-list-model.js +274 -0
  426. package/dist/session-list-model.js.map +1 -0
  427. package/dist/session-realtime-7DJOIHQW.js +21 -0
  428. package/dist/session-realtime-7DJOIHQW.js.map +1 -0
  429. package/dist/session-realtime.d.ts +7 -0
  430. package/dist/session-realtime.js +19 -0
  431. package/dist/session-realtime.js.map +1 -0
  432. package/dist/session-status-model.d.ts +36 -0
  433. package/dist/session-ui.d.ts +39 -1
  434. package/dist/session-ui.js +126 -12
  435. package/dist/session-ui.js.map +1 -1
  436. package/dist/session.d.ts +8 -2
  437. package/dist/session.js +35 -20
  438. package/dist/site-snapshot.d.ts +14 -0
  439. package/dist/sites-ui.d.ts +24 -0
  440. package/dist/sites.d.ts +3 -0
  441. package/dist/sites.js +14 -0
  442. package/dist/sites.js.map +1 -0
  443. package/dist/skill-discovery.d.ts +47 -0
  444. package/dist/terminal.d.ts +8 -0
  445. package/dist/terminal.js +32 -0
  446. package/dist/terminal.js.map +1 -0
  447. package/dist/testing/session-scenarios.d.ts +10 -0
  448. package/dist/testing/session-scenarios.js +367 -0
  449. package/dist/testing/session-scenarios.js.map +1 -0
  450. package/dist/timeline/activity-rail.d.ts +11 -2
  451. package/dist/timeline/agent-identity.d.ts +30 -0
  452. package/dist/timeline/agent-row.d.ts +31 -0
  453. package/dist/timeline/allowance-exhausted-row.d.ts +24 -0
  454. package/dist/timeline/compaction-copy.d.ts +46 -0
  455. package/dist/timeline/focus-sequence.d.ts +9 -0
  456. package/dist/timeline/genie-copy.d.ts +3 -0
  457. package/dist/timeline/genie-loading.d.ts +47 -0
  458. package/dist/timeline/index.d.ts +10 -5
  459. package/dist/timeline/knowledge-receipt.d.ts +17 -0
  460. package/dist/timeline/message-sender.d.ts +19 -0
  461. package/dist/timeline/notice-presentation.d.ts +13 -0
  462. package/dist/timeline/parsers.d.ts +11 -0
  463. package/dist/timeline/patch-apply-command.d.ts +18 -0
  464. package/dist/timeline/platform-activity-presentation.d.ts +21 -0
  465. package/dist/timeline/platform-activity-row.d.ts +1 -2
  466. package/dist/timeline/presented-image.d.ts +11 -0
  467. package/dist/timeline/projection.d.ts +31 -2
  468. package/dist/timeline/provider-logo.d.ts +15 -0
  469. package/dist/timeline/question-nav-model.d.ts +23 -0
  470. package/dist/timeline/registry.d.ts +12 -1
  471. package/dist/timeline/retained-image.d.ts +18 -0
  472. package/dist/timeline/retained-loaders.d.ts +27 -0
  473. package/dist/timeline/rolling-activity.d.ts +11 -0
  474. package/dist/timeline/screenshot-lightbox.d.ts +23 -1
  475. package/dist/timeline/session-usage-limit-row.d.ts +11 -0
  476. package/dist/timeline/shared.d.ts +4 -1
  477. package/dist/timeline/startup-dispatch-details.d.ts +5 -0
  478. package/dist/timeline/startup-preference.d.ts +3 -0
  479. package/dist/timeline/startup-timings.d.ts +4 -0
  480. package/dist/timeline/tool-display-name.d.ts +5 -2
  481. package/dist/timeline/tool-presentation.d.ts +172 -0
  482. package/dist/timeline/turn-summary-model.d.ts +95 -0
  483. package/dist/timeline/turn-summary.d.ts +20 -54
  484. package/dist/timeline/types.d.ts +179 -7
  485. package/dist/timeline/work-presentation.d.ts +60 -0
  486. package/dist/timeline-annotation-markers-U3G66KUD.js +166 -0
  487. package/dist/timeline-annotation-markers-U3G66KUD.js.map +1 -0
  488. package/dist/timeline-annotation-selection-BI7QTPTZ.js +242 -0
  489. package/dist/timeline-annotation-selection-BI7QTPTZ.js.map +1 -0
  490. package/dist/timeline-annotations-dialog-FOMHSDTE.js +274 -0
  491. package/dist/timeline-annotations-dialog-FOMHSDTE.js.map +1 -0
  492. package/dist/timeline-model.d.ts +29 -0
  493. package/dist/timeline-model.js +254 -0
  494. package/dist/timeline-model.js.map +1 -0
  495. package/dist/usage/allowance-copy.d.ts +25 -0
  496. package/dist/usage/session-usage-limit.d.ts +88 -0
  497. package/dist/usage/summary.d.ts +35 -0
  498. package/dist/usage.d.ts +17 -0
  499. package/dist/usage.js +1187 -0
  500. package/dist/usage.js.map +1 -0
  501. package/dist/voice-recording-owner.d.ts +7 -0
  502. package/package.json +106 -7
  503. package/src/approvals.ts +8 -1
  504. package/src/artifacts-spreadsheet.ts +1 -0
  505. package/src/artifacts.ts +44 -0
  506. package/src/assets/README.md +8 -0
  507. package/src/assets/gmail.ico +0 -0
  508. package/src/assets/outlook.ico +0 -0
  509. package/src/capability-catalog-row.tsx +94 -0
  510. package/src/capability-logo-fallback.ts +22 -0
  511. package/src/client.ts +20 -31
  512. package/src/commands/registry.ts +18 -15
  513. package/src/commands/types.ts +2 -0
  514. package/src/components/anthropic-mark.tsx +10 -0
  515. package/src/components/approval-surface.tsx +401 -138
  516. package/src/components/artifacts/artifact-chrome.tsx +413 -0
  517. package/src/components/artifacts/artifact-sandbox.tsx +193 -0
  518. package/src/components/artifacts/artifact-surface.tsx +40 -20
  519. package/src/components/artifacts/chat-interactive-block.tsx +260 -0
  520. package/src/components/artifacts/deferred-chat-media.tsx +67 -0
  521. package/src/components/artifacts/document-editor.tsx +141 -16
  522. package/src/components/artifacts/editable-artifact-ui.tsx +4 -2
  523. package/src/components/artifacts/editable-artifact-view.tsx +197 -0
  524. package/src/components/artifacts/editable-artifact-workbench.tsx +5 -2
  525. package/src/components/artifacts/editable-document.tsx +37 -36
  526. package/src/components/artifacts/editable-presentation.tsx +36 -18
  527. package/src/components/artifacts/editable-spreadsheet.tsx +543 -103
  528. package/src/components/artifacts/index.ts +45 -0
  529. package/src/components/artifacts/inline-html-document.ts +24 -0
  530. package/src/components/artifacts/latest-task-runner.ts +49 -0
  531. package/src/components/artifacts/presentation-editor.tsx +323 -67
  532. package/src/components/artifacts/published-html-artifact-frame.tsx +122 -5
  533. package/src/components/artifacts/session-artifact-viewer.tsx +378 -0
  534. package/src/components/artifacts/site-view.tsx +121 -0
  535. package/src/components/artifacts/spreadsheet-canvas.ts +5 -10
  536. package/src/components/artifacts/spreadsheet-command-queue.ts +184 -0
  537. package/src/components/artifacts/spreadsheet-download.tsx +109 -0
  538. package/src/components/artifacts/spreadsheet-general-display.ts +43 -0
  539. package/src/components/artifacts/spreadsheet-grid.tsx +344 -144
  540. package/src/components/artifacts/spreadsheet-resize.tsx +421 -0
  541. package/src/components/artifacts/spreadsheet-submissions.tsx +46 -0
  542. package/src/components/artifacts/visualization-assets/base.css +1015 -0
  543. package/src/components/artifacts/visualization-assets/helpers.html +349 -0
  544. package/src/components/artifacts/visualization-assets.gen.ts +3 -0
  545. package/src/components/browser-select-control.tsx +312 -0
  546. package/src/components/browser-viewer.tsx +778 -318
  547. package/src/components/chat-composer.tsx +47 -5
  548. package/src/components/child-session-link.tsx +36 -0
  549. package/src/components/claude-mark.tsx +11 -0
  550. package/src/components/code-editor.tsx +13 -16
  551. package/src/components/composer-transcription-control.tsx +128 -30
  552. package/src/components/composer.tsx +404 -195
  553. package/src/components/computer-viewer.tsx +880 -253
  554. package/src/components/copy-button.tsx +13 -5
  555. package/src/components/desktop-viewer.tsx +1 -1
  556. package/src/components/enrollment-consent.tsx +1 -1
  557. package/src/components/enrollment-device-flow.tsx +1 -1
  558. package/src/components/file-browser.tsx +10 -14
  559. package/src/components/fleet-tile.tsx +5 -3
  560. package/src/components/generated-video-player.tsx +4 -2
  561. package/src/components/grok-mark.tsx +34 -0
  562. package/src/components/human-input-form.tsx +590 -283
  563. package/src/components/human-input-surface.tsx +11 -0
  564. package/src/components/interaction-intervention-banner.tsx +2 -2
  565. package/src/components/linkified-text.tsx +79 -0
  566. package/src/components/machine-card.tsx +35 -78
  567. package/src/components/machine-dock-bar.tsx +1 -1
  568. package/src/components/machine-input-display.ts +197 -3
  569. package/src/components/machines/agent-status-icon.tsx +31 -0
  570. package/src/components/machines/machine-detail.tsx +200 -31
  571. package/src/components/machines/machine-operation-policy.tsx +1 -1
  572. package/src/components/machines/machine-status.ts +241 -0
  573. package/src/components/machines-dashboard.tsx +2 -17
  574. package/src/components/markdown-table-layout.ts +143 -0
  575. package/src/components/markdown.tsx +466 -129
  576. package/src/components/message-timeline.tsx +2370 -667
  577. package/src/components/model-mark.tsx +102 -0
  578. package/src/components/model-picker.tsx +15 -4
  579. package/src/components/model-policy-picker-menu.tsx +371 -0
  580. package/src/components/model-policy-picker.tsx +252 -429
  581. package/src/components/new-conversation.tsx +221 -0
  582. package/src/components/open-geni-chat.tsx +309 -0
  583. package/src/components/open-geni-links.tsx +179 -0
  584. package/src/components/openrouter-mark.tsx +13 -0
  585. package/src/components/opper-mark.tsx +18 -0
  586. package/src/components/pierre-diff.tsx +41 -16
  587. package/src/components/pierre-file.tsx +35 -10
  588. package/src/components/preview-loading.tsx +109 -0
  589. package/src/components/provider-recovery-notice.tsx +49 -0
  590. package/src/components/queue-item-content.ts +14 -0
  591. package/src/components/queue-surface-implementation.tsx +51 -356
  592. package/src/components/queue-surface-state.tsx +3 -1
  593. package/src/components/rehype-secret-refs.ts +98 -0
  594. package/src/components/remark-soft-line-breaks.ts +166 -0
  595. package/src/components/sandbox-files.tsx +91 -15
  596. package/src/components/sandbox-terminal.tsx +84 -13
  597. package/src/components/sandbox-workspace.tsx +147 -51
  598. package/src/components/secret-question-field.tsx +324 -0
  599. package/src/components/secret-ref-chip.tsx +185 -0
  600. package/src/components/session-capability-frame.tsx +197 -0
  601. package/src/components/session-chrome.tsx +842 -251
  602. package/src/components/session-commands-panel.tsx +126 -0
  603. package/src/components/session-commands.tsx +18 -0
  604. package/src/components/session-connection-request.tsx +97 -0
  605. package/src/components/session-conversation.tsx +876 -0
  606. package/src/components/session-list.tsx +257 -0
  607. package/src/components/session-mcp-capability-card.tsx +680 -0
  608. package/src/components/session-proxy-scope.tsx +153 -0
  609. package/src/components/session-status.tsx +26 -17
  610. package/src/components/session-usage-limit-notice.tsx +174 -0
  611. package/src/components/timeline-anchor.tsx +119 -0
  612. package/src/components/timeline-annotation-chrome.tsx +196 -0
  613. package/src/components/timeline-annotation-layout.ts +268 -0
  614. package/src/components/timeline-annotation-markers.tsx +185 -0
  615. package/src/components/timeline-annotation-reveal-context.ts +9 -0
  616. package/src/components/timeline-annotation-selection.tsx +106 -54
  617. package/src/components/timeline-annotation-shared.ts +245 -0
  618. package/src/components/timeline-annotations-dialog.tsx +185 -128
  619. package/src/components/timeline-annotations.tsx +189 -45
  620. package/src/components/timeline-reading-progress.ts +80 -0
  621. package/src/components/timeline-search.tsx +168 -0
  622. package/src/components/timeline-settlement.ts +60 -0
  623. package/src/components/tool-action-review.tsx +650 -0
  624. package/src/components/tool-review-history.tsx +88 -0
  625. package/src/components/usage-limit-notice.tsx +179 -0
  626. package/src/components/usage-member-list.tsx +792 -0
  627. package/src/components/usage-meter.tsx +382 -0
  628. package/src/components/use-viewer-menu-dismiss.ts +33 -0
  629. package/src/components/user-message-body.tsx +27 -2
  630. package/src/components/workspace-dock.tsx +18 -1
  631. package/src/composer-messages.ts +150 -0
  632. package/src/composer-voice-events.ts +12 -0
  633. package/src/composer.ts +6 -1
  634. package/src/connect-account-identity.tsx +34 -0
  635. package/src/connect-accounts.tsx +233 -0
  636. package/src/connect-chooser.tsx +336 -0
  637. package/src/connect-panel.tsx +99 -0
  638. package/src/connect-setup.tsx +355 -0
  639. package/src/connect.ts +60 -0
  640. package/src/connection-assets.d.ts +4 -0
  641. package/src/connection-catalog.tsx +162 -0
  642. package/src/connection-discovery.tsx +238 -0
  643. package/src/connection-installed.tsx +51 -0
  644. package/src/connection-logo.tsx +37 -0
  645. package/src/connection-service-logo.tsx +55 -0
  646. package/src/connection-service-presentation.ts +46 -0
  647. package/src/connection-skeleton.tsx +16 -0
  648. package/src/connection-type-picker.tsx +36 -0
  649. package/src/conversation-timeline.ts +92 -0
  650. package/src/desktop.ts +24 -0
  651. package/src/device-authorization.tsx +98 -0
  652. package/src/diffs.ts +16 -0
  653. package/src/discovery-cache.ts +42 -0
  654. package/src/editor.ts +13 -0
  655. package/src/hooks/internal.ts +3 -2
  656. package/src/hooks/latest-question.ts +164 -0
  657. package/src/hooks/shared-machines-list.ts +34 -1
  658. package/src/hooks/shared-query.ts +721 -0
  659. package/src/hooks/use-attached-browsers.ts +1 -1
  660. package/src/hooks/use-auth-runs.ts +0 -27
  661. package/src/hooks/use-available-models.ts +2 -2
  662. package/src/hooks/use-browser-frame-stream.ts +19 -2
  663. package/src/hooks/use-browser-session.ts +680 -205
  664. package/src/hooks/use-browser-sessions.ts +32 -1
  665. package/src/hooks/use-client-config-flags.ts +118 -0
  666. package/src/hooks/use-codex-accounts.ts +247 -47
  667. package/src/hooks/use-composer.ts +227 -44
  668. package/src/hooks/use-computer-frame-stream.ts +25 -7
  669. package/src/hooks/use-computer-input-posture.ts +94 -0
  670. package/src/hooks/use-computer-session.ts +409 -95
  671. package/src/hooks/use-connect.ts +23 -0
  672. package/src/hooks/use-desktop-stream.ts +19 -28
  673. package/src/hooks/use-file-attachments.ts +80 -4
  674. package/src/hooks/use-goal.ts +79 -9
  675. package/src/hooks/use-last-started-turn-policy.ts +37 -11
  676. package/src/hooks/use-machines.ts +4 -0
  677. package/src/hooks/use-new-conversation.ts +374 -0
  678. package/src/hooks/use-new-session-draft.ts +813 -0
  679. package/src/hooks/use-realtime-voice-models.ts +46 -0
  680. package/src/hooks/use-sandbox-files.ts +68 -20
  681. package/src/hooks/use-session-background-commands.ts +22 -11
  682. package/src/hooks/use-session-capabilities.ts +3 -2
  683. package/src/hooks/use-session-conversation.ts +150 -0
  684. package/src/hooks/use-session-events.ts +531 -335
  685. package/src/hooks/use-session-mcp-approval-policy.ts +13 -5
  686. package/src/hooks/use-session-model-account.ts +174 -0
  687. package/src/hooks/use-session.ts +30 -2
  688. package/src/hooks/use-slash-commands.ts +6 -11
  689. package/src/hooks/use-supergrok-accounts.ts +22 -8
  690. package/src/hooks/use-terminal-stream.ts +153 -27
  691. package/src/hooks/use-transcription.ts +6 -0
  692. package/src/hooks/use-turn-queue.ts +2 -1
  693. package/src/hooks/use-usage.ts +100 -0
  694. package/src/hooks/use-vaults.ts +153 -0
  695. package/src/hooks/use-video-artifact-playback.ts +1 -1
  696. package/src/hooks/use-voice-input.ts +127 -19
  697. package/src/hooks/use-workspace-capture.ts +3 -2
  698. package/src/hooks/use-workspace-edit.ts +23 -5
  699. package/src/hooks/use-workspace-sessions.ts +74 -7
  700. package/src/human-input-model.ts +359 -0
  701. package/src/identity-link-accounts.tsx +148 -0
  702. package/src/identity-link-consent.tsx +192 -0
  703. package/src/index.ts +262 -16
  704. package/src/interaction.ts +1 -0
  705. package/src/lib/clipboard.ts +29 -0
  706. package/src/lib/error-message.ts +37 -0
  707. package/src/lib/format.ts +205 -10
  708. package/src/lib/host-theme.ts +529 -0
  709. package/src/lib/interaction-errors.ts +15 -0
  710. package/src/lib/menu-styles.ts +44 -0
  711. package/src/lib/notify-observer.ts +15 -0
  712. package/src/lib/pierre-diffs-loader.ts +53 -0
  713. package/src/lib/provider-recovery.ts +243 -0
  714. package/src/lib/scrollbars.ts +30 -0
  715. package/src/lib/terminal-input-readiness.ts +51 -0
  716. package/src/lib/transient-retry.ts +99 -0
  717. package/src/lib/workbench-peers.ts +62 -0
  718. package/src/lib/xterm-theme.ts +23 -21
  719. package/src/mcp-connection-status.ts +35 -0
  720. package/src/model-mark-paths.ts +53 -0
  721. package/src/model-picker-model.ts +330 -0
  722. package/src/model-policy.ts +299 -74
  723. package/src/native-previews.ts +100 -0
  724. package/src/new-session-draft.ts +22 -0
  725. package/src/notification-text.ts +81 -0
  726. package/src/older-history.ts +22 -4
  727. package/src/organization-model.ts +118 -0
  728. package/src/plugin-details.tsx +185 -0
  729. package/src/plugin-discovery.tsx +196 -0
  730. package/src/preview-loading-paint.ts +68 -0
  731. package/src/provider.tsx +74 -15
  732. package/src/queue-presentation-model.ts +464 -0
  733. package/src/realtime/dropdown-menu.tsx +19 -12
  734. package/src/realtime/embedded-new-voice.tsx +1 -0
  735. package/src/realtime/embedded-voice.tsx +3 -0
  736. package/src/realtime/realtime-control.tsx +138 -550
  737. package/src/realtime/session-realtime.ts +566 -0
  738. package/src/sandbox-label-model.ts +53 -0
  739. package/src/scrollbars.ts +3 -0
  740. package/src/secret-reference-label.ts +43 -0
  741. package/src/secrets-ui.tsx +59 -0
  742. package/src/session-agents-model.ts +33 -0
  743. package/src/session-attention-model.ts +62 -0
  744. package/src/session-auth-recommendation.ts +48 -0
  745. package/src/session-capability-policy.ts +196 -0
  746. package/src/session-context.ts +3 -4
  747. package/src/session-feedback-model.ts +95 -0
  748. package/src/session-list-model.ts +434 -0
  749. package/src/session-realtime.ts +18 -0
  750. package/src/session-status-model.ts +99 -0
  751. package/src/session-ui.ts +98 -1
  752. package/src/session.ts +17 -1
  753. package/src/site-snapshot.ts +74 -0
  754. package/src/sites-ui.tsx +348 -0
  755. package/src/sites.ts +3 -0
  756. package/src/skill-discovery.tsx +208 -0
  757. package/src/terminal.ts +26 -0
  758. package/src/testing/session-scenarios.ts +404 -0
  759. package/src/timeline/activity-rail.tsx +242 -101
  760. package/src/timeline/agent-identity.tsx +84 -0
  761. package/src/timeline/agent-row.tsx +231 -0
  762. package/src/timeline/allowance-exhausted-row.tsx +86 -0
  763. package/src/timeline/compaction-copy.ts +115 -0
  764. package/src/timeline/fleet-decision-projection.ts +2 -1
  765. package/src/timeline/fleet-decision-row.tsx +1 -0
  766. package/src/timeline/focus-sequence.ts +44 -0
  767. package/src/timeline/genie-copy.ts +19 -0
  768. package/src/timeline/genie-loading.tsx +143 -0
  769. package/src/timeline/index.ts +30 -2
  770. package/src/timeline/knowledge-receipt.tsx +100 -0
  771. package/src/timeline/message-sender.tsx +71 -0
  772. package/src/timeline/notice-presentation.ts +48 -0
  773. package/src/timeline/parsers.ts +42 -2
  774. package/src/timeline/patch-apply-command.tsx +135 -0
  775. package/src/timeline/platform-activity-presentation.ts +166 -0
  776. package/src/timeline/platform-activity-row.tsx +15 -90
  777. package/src/timeline/presented-image.ts +63 -0
  778. package/src/timeline/projection.ts +1742 -76
  779. package/src/timeline/provider-logo.tsx +53 -0
  780. package/src/timeline/question-nav-model.ts +28 -0
  781. package/src/timeline/registry.ts +26 -4
  782. package/src/timeline/retained-image.ts +97 -0
  783. package/src/timeline/retained-loaders.ts +91 -0
  784. package/src/timeline/rolling-activity.tsx +80 -0
  785. package/src/timeline/screenshot-lightbox.tsx +228 -5
  786. package/src/timeline/session-usage-limit-row.tsx +42 -0
  787. package/src/timeline/shared.tsx +42 -15
  788. package/src/timeline/startup-dispatch-details.tsx +36 -0
  789. package/src/timeline/startup-preference.ts +33 -0
  790. package/src/timeline/startup-timings.tsx +145 -0
  791. package/src/timeline/tool-display-name.ts +19 -7
  792. package/src/timeline/tool-presentation.ts +1316 -0
  793. package/src/timeline/tool-renderers.tsx +835 -1138
  794. package/src/timeline/turn-summary-model.ts +343 -0
  795. package/src/timeline/turn-summary.tsx +272 -365
  796. package/src/timeline/types.ts +189 -6
  797. package/src/timeline/work-presentation.ts +189 -0
  798. package/src/timeline-model.ts +143 -0
  799. package/src/usage/allowance-copy.ts +64 -0
  800. package/src/usage/session-usage-limit.ts +266 -0
  801. package/src/usage/summary.ts +93 -0
  802. package/src/usage.ts +70 -0
  803. package/src/voice-recording-owner.ts +22 -0
  804. package/styles/compiled.css +2319 -748
  805. package/styles/connect.css +290 -0
  806. package/styles/connect.d.ts +1 -0
  807. package/styles/effective-tokens.css +1 -0
  808. package/styles/index.css +309 -9
  809. package/styles/responsive.css +99 -7
  810. package/styles/session-capability.css +44 -0
  811. package/styles/tokens.css +134 -66
  812. package/dist/browser-viewer-MKKFRRRV.js +0 -14
  813. package/dist/chunk-2DZVYHVO.js +0 -470
  814. package/dist/chunk-2DZVYHVO.js.map +0 -1
  815. package/dist/chunk-3AGBGTRT.js.map +0 -1
  816. package/dist/chunk-4MDLEHXL.js.map +0 -1
  817. package/dist/chunk-5YK2ZDIG.js.map +0 -1
  818. package/dist/chunk-7EAFGICR.js +0 -302
  819. package/dist/chunk-7EAFGICR.js.map +0 -1
  820. package/dist/chunk-ELIYWBZR.js.map +0 -1
  821. package/dist/chunk-H5YGYNXS.js.map +0 -1
  822. package/dist/chunk-HUIKIDM5.js.map +0 -1
  823. package/dist/chunk-ICA6R6TW.js.map +0 -1
  824. package/dist/chunk-IOLVN74D.js.map +0 -1
  825. package/dist/chunk-JAQ5K7W6.js.map +0 -1
  826. package/dist/chunk-JVYQRRC4.js.map +0 -1
  827. package/dist/chunk-KCGXPP5V.js.map +0 -1
  828. package/dist/chunk-KZ73RL76.js.map +0 -1
  829. package/dist/chunk-NEXLLTP4.js.map +0 -1
  830. package/dist/chunk-PEI6RANI.js.map +0 -1
  831. package/dist/chunk-VTOREEXF.js +0 -142
  832. package/dist/chunk-VTOREEXF.js.map +0 -1
  833. package/dist/chunk-WSK7G5LE.js +0 -170
  834. package/dist/chunk-WSK7G5LE.js.map +0 -1
  835. package/dist/chunk-X4A66EWZ.js +0 -223
  836. package/dist/chunk-X4A66EWZ.js.map +0 -1
  837. package/dist/chunk-XYRDDSXF.js.map +0 -1
  838. package/dist/chunk-YG4QEQF5.js +0 -9557
  839. package/dist/chunk-YG4QEQF5.js.map +0 -1
  840. package/dist/chunk-YVCHAQZY.js.map +0 -1
  841. package/dist/chunk-ZPBTI3TE.js.map +0 -1
  842. package/dist/computer-viewer-FWEZISW4.js +0 -16
  843. package/dist/fleet-decision-row-GGCAT4E4.js.map +0 -1
  844. package/dist/hooks/use-environments.d.ts +0 -41
  845. package/dist/hooks/use-packs.d.ts +0 -32
  846. package/dist/platform-activity-row-BJHUHXAT.js.map +0 -1
  847. package/dist/queue-surface-implementation-BSKUWHRI.js.map +0 -1
  848. package/dist/timeline-annotation-selection-3L7LHGG2.js +0 -187
  849. package/dist/timeline-annotation-selection-3L7LHGG2.js.map +0 -1
  850. package/dist/timeline-annotations-dialog-U7EVLR75.js +0 -196
  851. package/dist/timeline-annotations-dialog-U7EVLR75.js.map +0 -1
  852. package/src/hooks/use-environments.ts +0 -182
  853. package/src/hooks/use-packs.ts +0 -157
  854. /package/dist/{browser-viewer-MKKFRRRV.js.map → browser-viewer-ZWR6MWJ7.js.map} +0 -0
  855. /package/dist/{computer-viewer-FWEZISW4.js.map → chat-interactive-block-4EUKJXUO.js.map} +0 -0
@@ -1,18 +1,21 @@
1
+ "use client";
2
+ import {
3
+ machineScopeLabel
4
+ } from "./chunk-CSX5FFKZ.js";
1
5
  import {
2
6
  useMutationRunner,
3
7
  usePageLiveActivity
4
- } from "./chunk-KZ73RL76.js";
8
+ } from "./chunk-QHUE7E4N.js";
5
9
  import {
6
- OpenGeniContext,
7
10
  useOpenGeni
8
- } from "./chunk-NEXLLTP4.js";
11
+ } from "./chunk-G76LSA76.js";
9
12
  import {
10
13
  formatBytes,
11
14
  formatRelativeTime
12
- } from "./chunk-VTOREEXF.js";
15
+ } from "./chunk-BLL56F7R.js";
13
16
  import {
14
17
  cn
15
- } from "./chunk-22KP6LR5.js";
18
+ } from "./chunk-TXS65BB2.js";
16
19
 
17
20
  // src/types/machines.ts
18
21
  function connectionStatusForState(state) {
@@ -286,12 +289,9 @@ import {
286
289
  AlertTriangleIcon,
287
290
  ArrowRightIcon,
288
291
  CpuIcon,
289
- CircleCheckIcon,
290
- DownloadIcon,
291
292
  LaptopIcon,
292
293
  MonitorIcon,
293
294
  MonitorOffIcon,
294
- LoaderCircleIcon,
295
295
  ServerIcon,
296
296
  UsersIcon
297
297
  } from "lucide-react";
@@ -430,8 +430,195 @@ function MachineHealthPill({
430
430
  ] });
431
431
  }
432
432
 
433
+ // src/components/machines/agent-status-icon.tsx
434
+ import {
435
+ CircleAlertIcon,
436
+ CircleCheckIcon,
437
+ ClockIcon,
438
+ DownloadIcon,
439
+ LoaderCircleIcon,
440
+ TriangleAlertIcon
441
+ } from "lucide-react";
442
+ import { jsx as jsx4 } from "react/jsx-runtime";
443
+ function AgentStatusIcon({ tone, className }) {
444
+ const size = cn("size-3.5 shrink-0", className);
445
+ switch (tone) {
446
+ case "ok":
447
+ return /* @__PURE__ */ jsx4(CircleCheckIcon, { className: cn(size, "text-og-status-idle"), "aria-hidden": true });
448
+ case "progress":
449
+ return /* @__PURE__ */ jsx4(LoaderCircleIcon, { className: cn(size, "animate-og-spin text-og-accent"), "aria-hidden": true });
450
+ case "waiting":
451
+ return /* @__PURE__ */ jsx4(ClockIcon, { className: cn(size, "text-og-fg-subtle"), "aria-hidden": true });
452
+ case "attention":
453
+ return /* @__PURE__ */ jsx4(TriangleAlertIcon, { className: cn(size, "text-og-status-waiting"), "aria-hidden": true });
454
+ case "failed":
455
+ return /* @__PURE__ */ jsx4(CircleAlertIcon, { className: cn(size, "text-og-status-failed"), "aria-hidden": true });
456
+ default:
457
+ return /* @__PURE__ */ jsx4(DownloadIcon, { className: cn(size, "text-og-fg-subtle"), "aria-hidden": true });
458
+ }
459
+ }
460
+
461
+ // src/components/machines/machine-status.ts
462
+ var UPDATE_CONFIRMATION_GRACE_MS = 3e4;
463
+ function isPostponedUpdate(errorCode) {
464
+ return typeof errorCode === "string" && errorCode.startsWith("update_busy");
465
+ }
466
+ var FAILURE_REASON = {
467
+ update_state_unavailable: "the agent couldn't check whether the machine was idle",
468
+ agent_offline: "the machine was offline",
469
+ update_dispatch_rejected: "the agent refused the request",
470
+ invalid_agent_response: "the agent sent an unexpected reply"
471
+ };
472
+ function failureReason(code) {
473
+ if (!code) return null;
474
+ return FAILURE_REASON[code] ?? code.replaceAll("_", " ");
475
+ }
476
+ var ACTIVE_STATUSES = /* @__PURE__ */ new Set([
477
+ "requested",
478
+ "accepted",
479
+ "waiting_for_idle",
480
+ "downloading",
481
+ "verifying",
482
+ "applying",
483
+ "restarting"
484
+ ]);
485
+ function describeAgentRuntime(runtime, now) {
486
+ const installed = runtime.installedVersion;
487
+ const title = installed ? `Agent v${installed}` : "Agent version unknown";
488
+ const blocked = runtime.updateBlockedReason?.trim() || null;
489
+ const update = runtime.update;
490
+ const target = update ? `v${update.targetVersion}` : null;
491
+ const alreadyInstalled = update !== null && (update.targetVersion === installed || runtime.versionState === "current" || runtime.versionState === "ahead");
492
+ if (update && ACTIVE_STATUSES.has(update.status) && !alreadyInstalled) {
493
+ const base = { title, tone: "progress", note: null, action: null };
494
+ switch (update.status) {
495
+ case "requested": {
496
+ const stalled = now - new Date(update.updatedAt).getTime() >= UPDATE_CONFIRMATION_GRACE_MS;
497
+ return stalled ? {
498
+ title,
499
+ status: `The agent hasn't confirmed the update to ${target}`,
500
+ tone: "attention",
501
+ note: null,
502
+ action: { kind: "resend", label: "Send again" }
503
+ } : { ...base, status: `Sending the update to ${target}\u2026` };
504
+ }
505
+ case "accepted":
506
+ return { ...base, status: `Updating to ${target}\u2026` };
507
+ case "waiting_for_idle":
508
+ return {
509
+ ...base,
510
+ tone: "waiting",
511
+ status: `Updates to ${target} when current work finishes`
512
+ };
513
+ case "downloading":
514
+ return { ...base, status: `Downloading ${target}\u2026` };
515
+ case "verifying":
516
+ return { ...base, status: `Verifying ${target}\u2026` };
517
+ case "applying":
518
+ return { ...base, status: `Installing ${target}\u2026` };
519
+ default:
520
+ return { ...base, status: "Restarting the agent\u2026" };
521
+ }
522
+ }
523
+ if (update?.status === "failed" && !alreadyInstalled) {
524
+ if (isPostponedUpdate(update.errorCode)) {
525
+ const browsersWouldClose = update.errorCode === "update_busy_browsers";
526
+ return {
527
+ title,
528
+ status: browsersWouldClose ? `Update to ${target} postponed: open browsers would close` : `Update to ${target} postponed while the machine was busy`,
529
+ tone: "waiting",
530
+ note: blocked ?? (browsersWouldClose ? "The installed agent closes its browsers when it restarts. Updating now closes them." : null),
531
+ action: blocked ? null : { kind: "update", label: "Update now" }
532
+ };
533
+ }
534
+ const reason = failureReason(update.errorCode);
535
+ const retry = update.retryable && !blocked ? { kind: "retry", label: "Try again" } : null;
536
+ if (update.rolledBack) {
537
+ return {
538
+ title,
539
+ status: `Couldn't update to ${target}, so the current version was kept`,
540
+ tone: "attention",
541
+ note: blocked ?? (reason ? `Reason: ${reason}.` : null),
542
+ action: retry
543
+ };
544
+ }
545
+ return {
546
+ title,
547
+ status: `Update to ${target} failed`,
548
+ tone: "failed",
549
+ note: blocked ?? (reason ? `Reason: ${reason}.` : null),
550
+ action: retry
551
+ };
552
+ }
553
+ const desired = runtime.desiredVersion;
554
+ switch (runtime.versionState) {
555
+ case "current":
556
+ return {
557
+ title,
558
+ status: runtime.updateChannel === "beta" ? "Up to date \xB7 beta" : "Up to date",
559
+ tone: "ok",
560
+ note: null,
561
+ action: null
562
+ };
563
+ case "ahead":
564
+ return {
565
+ title,
566
+ status: desired ? `Newer than the released v${desired}` : "Newer than the release",
567
+ tone: "muted",
568
+ note: null,
569
+ action: null
570
+ };
571
+ case "unknown":
572
+ return {
573
+ title,
574
+ status: desired ? `Latest is v${desired}` : "No release configured",
575
+ tone: "muted",
576
+ note: blocked,
577
+ action: null
578
+ };
579
+ default:
580
+ if (!desired || desired === installed) {
581
+ return { title, status: "Up to date", tone: "ok", note: null, action: null };
582
+ }
583
+ return {
584
+ title,
585
+ status: `v${desired} available`,
586
+ tone: "waiting",
587
+ note: blocked,
588
+ action: blocked ? null : { kind: "update", label: "Update" }
589
+ };
590
+ }
591
+ }
592
+ var RUNNER_CONFLICT_ACTIVE_MS = 2 * 6e4;
593
+ function runnerConflict(authority, now) {
594
+ if (authority.duplicateRunnerDeniedCount <= 0) return null;
595
+ const lastAt = authority.duplicateRunnerDeniedAt;
596
+ const last = lastAt ? new Date(lastAt).getTime() : Number.NaN;
597
+ return {
598
+ active: Number.isFinite(last) && now - last < RUNNER_CONFLICT_ACTIVE_MS,
599
+ count: authority.duplicateRunnerDeniedCount,
600
+ lastAt
601
+ };
602
+ }
603
+ function describeAgentConnection(authority) {
604
+ const label = authority.state === "active" ? "Agent connected" : authority.state === "expired" ? "Agent connection lapsed" : "Agent not connected yet";
605
+ const n = authority.supersededCount;
606
+ return {
607
+ label,
608
+ detail: n > 0 ? `Reconnected ${n} ${n === 1 ? "time" : "times"} since setup` : null
609
+ };
610
+ }
611
+ var STATUS_TONE_TEXT = {
612
+ ok: "text-og-status-idle",
613
+ progress: "text-og-accent",
614
+ waiting: "text-og-fg-muted",
615
+ attention: "text-og-status-waiting",
616
+ failed: "text-og-status-failed",
617
+ muted: "text-og-fg-subtle"
618
+ };
619
+
433
620
  // src/components/machines/metric-sparkline.tsx
434
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
621
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
435
622
  var VW = 120;
436
623
  function MetricSparkline({
437
624
  points,
@@ -444,7 +631,7 @@ function MetricSparkline({
444
631
  (p) => p.v != null && Number.isFinite(p.v)
445
632
  );
446
633
  if (valued.length < 2) {
447
- return /* @__PURE__ */ jsx4("div", { className, style: { height }, "aria-hidden": true });
634
+ return /* @__PURE__ */ jsx5("div", { className, style: { height }, "aria-hidden": true });
448
635
  }
449
636
  const vh = height;
450
637
  const top = yMax === "auto" ? Math.max(1, ...valued.map((p) => p.v)) * 1.1 : yMax;
@@ -473,12 +660,12 @@ function MetricSparkline({
473
660
  style: { height, width: "100%" },
474
661
  "aria-hidden": true,
475
662
  children: [
476
- /* @__PURE__ */ jsx4("defs", { children: /* @__PURE__ */ jsxs4("linearGradient", { id: gid, x1: "0", y1: "0", x2: "0", y2: "1", children: [
477
- /* @__PURE__ */ jsx4("stop", { offset: "0%", stopColor: color, stopOpacity: "0.22" }),
478
- /* @__PURE__ */ jsx4("stop", { offset: "100%", stopColor: color, stopOpacity: "0" })
663
+ /* @__PURE__ */ jsx5("defs", { children: /* @__PURE__ */ jsxs4("linearGradient", { id: gid, x1: "0", y1: "0", x2: "0", y2: "1", children: [
664
+ /* @__PURE__ */ jsx5("stop", { offset: "0%", stopColor: color, stopOpacity: "0.22" }),
665
+ /* @__PURE__ */ jsx5("stop", { offset: "100%", stopColor: color, stopOpacity: "0" })
479
666
  ] }) }),
480
- /* @__PURE__ */ jsx4("path", { d: `${d} L${last.x},${vh} L${xy[0].x},${vh} Z`, fill: `url(#${gid})` }),
481
- /* @__PURE__ */ jsx4(
667
+ /* @__PURE__ */ jsx5("path", { d: `${d} L${last.x},${vh} L${xy[0].x},${vh} Z`, fill: `url(#${gid})` }),
668
+ /* @__PURE__ */ jsx5(
482
669
  "path",
483
670
  {
484
671
  d,
@@ -490,19 +677,21 @@ function MetricSparkline({
490
677
  vectorEffect: "non-scaling-stroke"
491
678
  }
492
679
  ),
493
- /* @__PURE__ */ jsx4("circle", { cx: last.x, cy: last.y, r: 1.6, fill: color, vectorEffect: "non-scaling-stroke" })
680
+ /* @__PURE__ */ jsx5("circle", { cx: last.x, cy: last.y, r: 1.6, fill: color, vectorEffect: "non-scaling-stroke" })
494
681
  ]
495
682
  }
496
683
  );
497
684
  }
498
685
 
499
686
  // src/components/machine-card.tsx
500
- import { Fragment, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
687
+ import { Fragment, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
501
688
  function KindIcon({ machine }) {
502
- if (machine.isSessionGroup)
503
- return /* @__PURE__ */ jsx5(ServerIcon, { className: "size-4 text-og-fg-subtle", "aria-hidden": true });
504
- if (machine.kind === "modal") return /* @__PURE__ */ jsx5(CpuIcon, { className: "size-4 text-og-fg-subtle", "aria-hidden": true });
505
- return /* @__PURE__ */ jsx5(LaptopIcon, { className: "size-4 text-og-fg-subtle", "aria-hidden": true });
689
+ if (machine.kind === "local" || machine.kind === "selfhosted")
690
+ return /* @__PURE__ */ jsx6(LaptopIcon, { className: "size-4 text-og-fg-subtle", "aria-hidden": true });
691
+ if (machine.kind === "docker" || machine.isSessionGroup)
692
+ return /* @__PURE__ */ jsx6(ServerIcon, { className: "size-4 text-og-fg-subtle", "aria-hidden": true });
693
+ if (machine.kind === "modal") return /* @__PURE__ */ jsx6(CpuIcon, { className: "size-4 text-og-fg-subtle", "aria-hidden": true });
694
+ return /* @__PURE__ */ jsx6(ServerIcon, { className: "size-4 text-og-fg-subtle", "aria-hidden": true });
506
695
  }
507
696
  function MachineCard({
508
697
  machine,
@@ -523,33 +712,9 @@ function MachineCard({
523
712
  const cpuPts = (series ?? []).map((s) => ({ t: new Date(s.sampledAt).getTime(), v: s.cpuPct }));
524
713
  const openable = Boolean(onOpenDetail);
525
714
  const runtime = machine.runtime;
526
- const updateRunning = runtime?.versionState === "updating";
527
- const dispatchConfirmationStalled = runtime?.update?.status === "requested" && clockNow - new Date(runtime.update.updatedAt).getTime() >= 3e4;
528
- const canUpdate = Boolean(machine.enrollmentId && onUpdateAgent) && !offline && (runtime?.versionState === "outdated" || runtime?.versionState === "update_failed" || dispatchConfirmationStalled);
529
- const updateLabel = (() => {
530
- const update = runtime?.update;
531
- if (!update) return null;
532
- switch (update.status) {
533
- case "requested":
534
- return dispatchConfirmationStalled ? "Agent confirmation delayed" : "Confirming with agent";
535
- case "accepted":
536
- return "Update accepted";
537
- case "waiting_for_idle":
538
- return "Waiting for current work";
539
- case "downloading":
540
- case "verifying":
541
- case "applying":
542
- return `${update.status}\u2026`;
543
- case "restarting":
544
- return "Restarting agent";
545
- case "succeeded":
546
- return `Updated \xB7 v${update.targetVersion}`;
547
- case "failed": {
548
- const detail = update.errorCode?.replaceAll("_", " ");
549
- return update.rolledBack ? `Update rolled back safely${detail ? ` \xB7 ${detail}` : ""}` : `Update failed${detail ? ` \xB7 ${detail}` : ""}`;
550
- }
551
- }
552
- })();
715
+ const agent = runtime ? describeAgentRuntime(runtime, clockNow) : null;
716
+ const updateAction = agent?.action && machine.enrollmentId && onUpdateAgent && !offline ? agent.action : null;
717
+ const conflict = runnerConflict(machine.connectionAuthority, clockNow);
553
718
  return /* @__PURE__ */ jsxs5(
554
719
  "div",
555
720
  {
@@ -572,14 +737,14 @@ function MachineCard({
572
737
  className
573
738
  ),
574
739
  children: [
575
- machine.active ? /* @__PURE__ */ jsx5("span", { "aria-hidden": true, className: "absolute inset-y-0 left-0 w-0.5 bg-og-accent" }) : null,
740
+ machine.active ? /* @__PURE__ */ jsx6("span", { "aria-hidden": true, className: "absolute inset-y-0 left-0 w-0.5 bg-og-accent" }) : null,
576
741
  /* @__PURE__ */ jsxs5("div", { className: "flex items-start justify-between gap-3", children: [
577
742
  /* @__PURE__ */ jsxs5("div", { className: "flex min-w-0 items-start gap-2.5", children: [
578
- /* @__PURE__ */ jsx5("span", { className: "mt-0.5 shrink-0", children: /* @__PURE__ */ jsx5(KindIcon, { machine }) }),
743
+ /* @__PURE__ */ jsx6("span", { className: "mt-0.5 shrink-0", children: /* @__PURE__ */ jsx6(KindIcon, { machine }) }),
579
744
  /* @__PURE__ */ jsxs5("div", { className: "min-w-0", children: [
580
745
  /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
581
- /* @__PURE__ */ jsx5("span", { className: "truncate text-og-base font-medium text-og-fg", children: machine.name }),
582
- machine.active ? /* @__PURE__ */ jsx5(
746
+ /* @__PURE__ */ jsx6("span", { className: "truncate text-og-base font-medium text-og-fg", children: machine.name }),
747
+ machine.active ? /* @__PURE__ */ jsx6(
583
748
  "span",
584
749
  {
585
750
  "data-active-marker": true,
@@ -589,24 +754,24 @@ function MachineCard({
589
754
  ) : null
590
755
  ] }),
591
756
  /* @__PURE__ */ jsxs5("div", { className: "mt-0.5 flex flex-wrap items-center gap-x-2 gap-y-0.5 text-og-xs text-og-fg-subtle", children: [
592
- /* @__PURE__ */ jsx5("span", { "data-machine-scope": machine.scope, className: "capitalize", children: machine.scope === "user" ? "personal" : machine.scope }),
593
- /* @__PURE__ */ jsx5("span", { "aria-hidden": true, children: "\xB7" }),
594
- /* @__PURE__ */ jsx5("span", { className: "capitalize", children: machine.isSessionGroup ? "session sandbox" : machine.kind }),
595
- /* @__PURE__ */ jsx5("span", { "aria-hidden": true, children: "\xB7" }),
757
+ /* @__PURE__ */ jsx6("span", { "data-machine-scope": machine.scope, children: machineScopeLabel(machine.scope) }),
758
+ /* @__PURE__ */ jsx6("span", { "aria-hidden": true, children: "\xB7" }),
759
+ /* @__PURE__ */ jsx6("span", { className: "capitalize", children: machine.kind }),
760
+ /* @__PURE__ */ jsx6("span", { "aria-hidden": true, children: "\xB7" }),
596
761
  /* @__PURE__ */ jsxs5("span", { className: "font-og-mono", children: [
597
762
  machine.os,
598
763
  "/",
599
764
  machine.arch
600
765
  ] }),
601
- /* @__PURE__ */ jsx5("span", { "aria-hidden": true, children: "\xB7" }),
766
+ /* @__PURE__ */ jsx6("span", { "aria-hidden": true, children: "\xB7" }),
602
767
  /* @__PURE__ */ jsxs5("span", { className: "inline-flex items-center gap-1", children: [
603
- machine.hasDisplay ? /* @__PURE__ */ jsx5(MonitorIcon, { className: "size-3", "aria-hidden": true }) : /* @__PURE__ */ jsx5(MonitorOffIcon, { className: "size-3", "aria-hidden": true }),
768
+ machine.hasDisplay ? /* @__PURE__ */ jsx6(MonitorIcon, { className: "size-3", "aria-hidden": true }) : /* @__PURE__ */ jsx6(MonitorOffIcon, { className: "size-3", "aria-hidden": true }),
604
769
  machine.hasDisplay ? "display" : "headless"
605
770
  ] })
606
771
  ] })
607
772
  ] })
608
773
  ] }),
609
- /* @__PURE__ */ jsx5(
774
+ /* @__PURE__ */ jsx6(
610
775
  MachineHealthPill,
611
776
  {
612
777
  state: machine.state,
@@ -623,25 +788,31 @@ function MachineCard({
623
788
  "data-shared-disclosure": true,
624
789
  className: "flex items-center gap-1.5 rounded-og-md border border-og-accent/25 bg-og-accent-soft px-2.5 py-1.5 text-og-xs text-og-fg-muted",
625
790
  children: [
626
- /* @__PURE__ */ jsx5(UsersIcon, { className: "size-3.5 shrink-0 text-og-accent", "aria-hidden": true }),
791
+ /* @__PURE__ */ jsx6(UsersIcon, { className: "size-3.5 shrink-0 text-og-accent", "aria-hidden": true }),
627
792
  "Shared \u2014 ",
628
793
  machine.sharedSessionCount,
629
794
  " sessions are on this machine."
630
795
  ]
631
796
  }
632
797
  ) : null,
633
- machine.connectionAuthority.duplicateRunnerDeniedCount > 0 ? /* @__PURE__ */ jsxs5(
798
+ conflict?.active ? /* @__PURE__ */ jsxs5(
634
799
  "p",
635
800
  {
636
801
  "data-runner-conflict": true,
637
- className: "flex items-center gap-1.5 rounded-og-md border border-og-status-failed/30 bg-og-status-failed/5 px-2.5 py-1.5 text-og-xs text-og-status-failed",
802
+ className: "flex items-start gap-1.5 rounded-og-md border border-og-status-waiting/30 bg-og-status-waiting/5 px-2.5 py-1.5 text-og-xs text-og-fg-muted",
638
803
  children: [
639
- /* @__PURE__ */ jsx5(AlertTriangleIcon, { className: "size-3.5 shrink-0", "aria-hidden": true }),
640
- "Competing agent process blocked. Open diagnostics for details."
804
+ /* @__PURE__ */ jsx6(
805
+ AlertTriangleIcon,
806
+ {
807
+ className: "mt-px size-3.5 shrink-0 text-og-status-waiting",
808
+ "aria-hidden": true
809
+ }
810
+ ),
811
+ /* @__PURE__ */ jsx6("span", { children: "A second copy of the agent is running on this machine. It's kept out, so work isn't affected. Stop the extra copy." })
641
812
  ]
642
813
  }
643
814
  ) : null,
644
- runtime ? /* @__PURE__ */ jsxs5(
815
+ agent ? /* @__PURE__ */ jsxs5(
645
816
  "div",
646
817
  {
647
818
  "data-agent-runtime": true,
@@ -649,46 +820,51 @@ function MachineCard({
649
820
  children: [
650
821
  /* @__PURE__ */ jsxs5("div", { className: "min-w-0", children: [
651
822
  /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-1.5 text-og-fg-muted", children: [
652
- runtime.versionState === "current" ? /* @__PURE__ */ jsx5(CircleCheckIcon, { className: "size-3.5 text-og-status-idle", "aria-hidden": true }) : updateRunning ? /* @__PURE__ */ jsx5(LoaderCircleIcon, { className: "size-3.5 animate-og-spin text-og-accent", "aria-hidden": true }) : /* @__PURE__ */ jsx5(DownloadIcon, { className: "size-3.5", "aria-hidden": true }),
653
- /* @__PURE__ */ jsxs5("span", { className: "truncate", children: [
654
- "Agent",
655
- " ",
656
- runtime.installedVersion ? `v${runtime.installedVersion}` : "version unknown"
657
- ] })
823
+ /* @__PURE__ */ jsx6(AgentStatusIcon, { tone: agent.tone }),
824
+ /* @__PURE__ */ jsx6("span", { className: "truncate", children: agent.title })
658
825
  ] }),
659
- /* @__PURE__ */ jsx5("p", { className: "mt-0.5 truncate text-og-fg-subtle", children: updateLabel ?? (runtime.versionState === "current" ? `Current \xB7 ${runtime.updateChannel ?? "channel unknown"}` : runtime.desiredVersion ? `Promoted v${runtime.desiredVersion}` : "No promoted version configured") })
826
+ /* @__PURE__ */ jsx6(
827
+ "p",
828
+ {
829
+ "data-agent-status": agent.tone,
830
+ className: cn("mt-0.5", STATUS_TONE_TEXT[agent.tone]),
831
+ children: agent.status
832
+ }
833
+ ),
834
+ agent.note ? /* @__PURE__ */ jsx6("p", { className: "mt-1 text-og-fg-muted", children: agent.note }) : null
660
835
  ] }),
661
- canUpdate ? /* @__PURE__ */ jsx5(
836
+ updateAction ? /* @__PURE__ */ jsx6(
662
837
  "button",
663
838
  {
664
839
  type: "button",
665
840
  "data-update-agent": true,
841
+ "data-update-action": updateAction.kind,
666
842
  disabled: updatingAgent,
667
843
  onClick: (event) => {
668
844
  event.stopPropagation();
669
845
  onUpdateAgent?.(machine);
670
846
  },
671
847
  className: "shrink-0 rounded-og-sm border border-og-border px-2 py-1 font-medium text-og-fg-muted transition-colors hover:border-og-border-strong hover:text-og-fg disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:min-h-11",
672
- children: updatingAgent ? "Starting\u2026" : dispatchConfirmationStalled ? "Retry delivery" : runtime.versionState === "update_failed" ? "Retry" : "Update"
848
+ children: updatingAgent ? "Starting\u2026" : updateAction.label
673
849
  }
674
850
  ) : null
675
851
  ]
676
852
  }
677
853
  ) : null,
678
- /* @__PURE__ */ jsx5(MachineMetrics, { metrics: machine.metrics }),
854
+ /* @__PURE__ */ jsx6(MachineMetrics, { metrics: machine.metrics }),
679
855
  cpuPts.length > 1 ? /* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-1 rounded-og-md bg-og-surface-2/40 p-2.5", children: [
680
856
  /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between text-[10px] font-medium uppercase tracking-wide text-og-fg-subtle", children: [
681
- /* @__PURE__ */ jsx5("span", { children: "CPU \xB7 last 15m" }),
857
+ /* @__PURE__ */ jsx6("span", { children: "CPU \xB7 last 15m" }),
682
858
  openable ? /* @__PURE__ */ jsxs5("span", { className: "flex items-center gap-0.5 opacity-0 transition-opacity group-hover:opacity-100", children: [
683
859
  "Telemetry ",
684
- /* @__PURE__ */ jsx5(ArrowRightIcon, { className: "size-2.5", "aria-hidden": true })
860
+ /* @__PURE__ */ jsx6(ArrowRightIcon, { className: "size-2.5", "aria-hidden": true })
685
861
  ] }) : null
686
862
  ] }),
687
- /* @__PURE__ */ jsx5(MetricSparkline, { points: cpuPts, color: "var(--og-color-accent)", yMax: 100, height: 26 })
863
+ /* @__PURE__ */ jsx6(MetricSparkline, { points: cpuPts, color: "var(--og-color-accent)", yMax: 100, height: 26 })
688
864
  ] }) : null,
689
865
  /* @__PURE__ */ jsxs5("div", { className: "mt-1 flex items-center justify-between gap-3 text-og-xs text-og-fg-subtle", children: [
690
- /* @__PURE__ */ jsx5("span", { className: "inline-flex items-center gap-1.5", children: sampledAgo ? /* @__PURE__ */ jsxs5(Fragment, { children: [
691
- /* @__PURE__ */ jsx5(
866
+ /* @__PURE__ */ jsx6("span", { className: "inline-flex items-center gap-1.5", children: sampledAgo ? /* @__PURE__ */ jsxs5(Fragment, { children: [
867
+ /* @__PURE__ */ jsx6(
692
868
  "span",
693
869
  {
694
870
  className: cn(
@@ -703,7 +879,7 @@ function MachineCard({
703
879
  "Last seen ",
704
880
  formatRelativeTime(machine.lastSeenAt, new Date(clockNow))
705
881
  ] }) : "Never connected" }),
706
- machine.active ? /* @__PURE__ */ jsx5("span", { className: "text-og-accent", children: "Routing here" }) : attachable ? /* @__PURE__ */ jsx5(
882
+ machine.active ? /* @__PURE__ */ jsx6("span", { className: "text-og-accent", children: "Routing here" }) : attachable ? /* @__PURE__ */ jsx6(
707
883
  "button",
708
884
  {
709
885
  type: "button",
@@ -719,7 +895,7 @@ function MachineCard({
719
895
  ),
720
896
  children: attaching ? "Switching\u2026" : "Attach"
721
897
  }
722
- ) : /* @__PURE__ */ jsx5("span", { className: "text-og-fg-subtle/70", children: offline ? "Unavailable" : "\u2014" })
898
+ ) : /* @__PURE__ */ jsx6("span", { className: "text-og-fg-subtle/70", children: offline ? "Unavailable" : "\u2014" })
723
899
  ] })
724
900
  ]
725
901
  }
@@ -728,7 +904,7 @@ function MachineCard({
728
904
 
729
905
  // src/components/machines/metric-history-chart.tsx
730
906
  import { useLayoutEffect, useRef, useState } from "react";
731
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
907
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
732
908
  var PAD = { top: 10, right: 12, bottom: 18, left: 40 };
733
909
  function niceCeil(v) {
734
910
  if (v <= 0) return 1;
@@ -813,7 +989,7 @@ function MetricHistoryChart({
813
989
  style: { height: H },
814
990
  "data-metric-chart": true,
815
991
  children: [
816
- valued.length === 0 ? /* @__PURE__ */ jsx6("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsxs6("span", { className: "text-og-xs text-og-fg-subtle", children: [
992
+ valued.length === 0 ? /* @__PURE__ */ jsx7("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsxs6("span", { className: "text-og-xs text-og-fg-subtle", children: [
817
993
  "No samples ",
818
994
  rangeLabel
819
995
  ] }) }) : /* @__PURE__ */ jsxs6(
@@ -839,14 +1015,14 @@ function MetricHistoryChart({
839
1015
  setHover(best);
840
1016
  },
841
1017
  children: [
842
- /* @__PURE__ */ jsx6("defs", { children: /* @__PURE__ */ jsxs6("linearGradient", { id: gid, x1: "0", y1: "0", x2: "0", y2: "1", children: [
843
- /* @__PURE__ */ jsx6("stop", { offset: "0%", stopColor: color, stopOpacity: "0.26" }),
844
- /* @__PURE__ */ jsx6("stop", { offset: "100%", stopColor: color, stopOpacity: "0" })
1018
+ /* @__PURE__ */ jsx7("defs", { children: /* @__PURE__ */ jsxs6("linearGradient", { id: gid, x1: "0", y1: "0", x2: "0", y2: "1", children: [
1019
+ /* @__PURE__ */ jsx7("stop", { offset: "0%", stopColor: color, stopOpacity: "0.26" }),
1020
+ /* @__PURE__ */ jsx7("stop", { offset: "100%", stopColor: color, stopOpacity: "0" })
845
1021
  ] }) }),
846
1022
  yTicks.map((v, i) => {
847
1023
  const y = yOf(v);
848
1024
  return /* @__PURE__ */ jsxs6("g", { children: [
849
- /* @__PURE__ */ jsx6(
1025
+ /* @__PURE__ */ jsx7(
850
1026
  "line",
851
1027
  {
852
1028
  x1: PAD.left,
@@ -858,7 +1034,7 @@ function MetricHistoryChart({
858
1034
  strokeWidth: 1
859
1035
  }
860
1036
  ),
861
- /* @__PURE__ */ jsx6(
1037
+ /* @__PURE__ */ jsx7(
862
1038
  "text",
863
1039
  {
864
1040
  x: PAD.left - 8,
@@ -877,7 +1053,7 @@ function MetricHistoryChart({
877
1053
  if (tv == null || tv > top) return null;
878
1054
  const y = yOf(tv);
879
1055
  const stroke = k === "crit" ? "var(--og-color-status-failed)" : "var(--og-color-status-waiting)";
880
- return /* @__PURE__ */ jsx6(
1056
+ return /* @__PURE__ */ jsx7(
881
1057
  "line",
882
1058
  {
883
1059
  x1: PAD.left,
@@ -892,7 +1068,7 @@ function MetricHistoryChart({
892
1068
  k
893
1069
  );
894
1070
  }),
895
- valued.length > 1 && [tMin, tMax].map((t, i) => /* @__PURE__ */ jsx6(
1071
+ valued.length > 1 && [tMin, tMax].map((t, i) => /* @__PURE__ */ jsx7(
896
1072
  "text",
897
1073
  {
898
1074
  x: i === 0 ? PAD.left : w - PAD.right,
@@ -905,8 +1081,8 @@ function MetricHistoryChart({
905
1081
  },
906
1082
  i === 0 ? "x-start" : "x-end"
907
1083
  )),
908
- area && /* @__PURE__ */ jsx6("path", { d: area, fill: `url(#${gid})` }),
909
- /* @__PURE__ */ jsx6(
1084
+ area && /* @__PURE__ */ jsx7("path", { d: area, fill: `url(#${gid})` }),
1085
+ /* @__PURE__ */ jsx7(
910
1086
  "path",
911
1087
  {
912
1088
  d: line,
@@ -919,9 +1095,9 @@ function MetricHistoryChart({
919
1095
  className: "og-mh-draw"
920
1096
  }
921
1097
  ),
922
- sparse && pxPts.map((p) => /* @__PURE__ */ jsx6("circle", { cx: p.x, cy: p.y, r: 2.5, fill: color }, `m-${p.t}`)),
1098
+ sparse && pxPts.map((p) => /* @__PURE__ */ jsx7("circle", { cx: p.x, cy: p.y, r: 2.5, fill: color }, `m-${p.t}`)),
923
1099
  hoverPt && /* @__PURE__ */ jsxs6("g", { pointerEvents: "none", children: [
924
- /* @__PURE__ */ jsx6(
1100
+ /* @__PURE__ */ jsx7(
925
1101
  "line",
926
1102
  {
927
1103
  x1: hoverPt.x,
@@ -932,7 +1108,7 @@ function MetricHistoryChart({
932
1108
  strokeWidth: 1
933
1109
  }
934
1110
  ),
935
- /* @__PURE__ */ jsx6(
1111
+ /* @__PURE__ */ jsx7(
936
1112
  "circle",
937
1113
  {
938
1114
  cx: hoverPt.x,
@@ -956,8 +1132,8 @@ function MetricHistoryChart({
956
1132
  top: Math.max(hoverPt.y - 42, 0)
957
1133
  },
958
1134
  children: [
959
- /* @__PURE__ */ jsx6("span", { className: "font-og-mono text-og-sm font-medium tabular-nums text-og-fg", children: fmt(hoverPt.v) }),
960
- /* @__PURE__ */ jsx6("span", { className: "font-og-mono text-[10px] tabular-nums text-og-fg-subtle", children: fmtClock(hoverPt.t) })
1135
+ /* @__PURE__ */ jsx7("span", { className: "font-og-mono text-og-sm font-medium tabular-nums text-og-fg", children: fmt(hoverPt.v) }),
1136
+ /* @__PURE__ */ jsx7("span", { className: "font-og-mono text-[10px] tabular-nums text-og-fg-subtle", children: fmtClock(hoverPt.t) })
961
1137
  ]
962
1138
  }
963
1139
  )
@@ -968,13 +1144,18 @@ function MetricHistoryChart({
968
1144
 
969
1145
  // src/components/machines/machine-detail.tsx
970
1146
  import {
971
- AlertTriangleIcon as AlertTriangleIcon3,
972
1147
  ArrowLeftIcon,
1148
+ BuildingIcon,
1149
+ ChevronRightIcon,
973
1150
  CpuIcon as CpuIcon2,
974
1151
  LaptopIcon as LaptopIcon2,
1152
+ PlugIcon,
975
1153
  RadioIcon,
976
1154
  ServerIcon as ServerIcon2,
977
- Trash2Icon
1155
+ TriangleAlertIcon as TriangleAlertIcon2,
1156
+ Trash2Icon,
1157
+ UserIcon,
1158
+ UsersIcon as UsersIcon2
978
1159
  } from "lucide-react";
979
1160
 
980
1161
  // src/components/machines/series.ts
@@ -1063,7 +1244,7 @@ function pointsFor(def, samples) {
1063
1244
  // src/components/machines/machine-operation-policy.tsx
1064
1245
  import { AlertTriangleIcon as AlertTriangleIcon2, Loader2Icon } from "lucide-react";
1065
1246
  import { useEffect, useState as useState2 } from "react";
1066
- import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
1247
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1067
1248
  function fieldValue(value) {
1068
1249
  return value === null ? "" : String(value);
1069
1250
  }
@@ -1139,11 +1320,11 @@ function MachineOperationPolicyEditor({
1139
1320
  className: "rounded-og-lg border border-og-border bg-og-surface-1 p-4 shadow-og-sm",
1140
1321
  children: [
1141
1322
  /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-1", children: [
1142
- /* @__PURE__ */ jsx7("h2", { className: "text-og-sm font-semibold text-og-fg", children: "Per-command resource policy" }),
1143
- /* @__PURE__ */ jsx7("p", { className: "text-og-xs leading-relaxed text-og-fg-muted", children: "Optional limits applied separately to each newly admitted exec and Git command. Running commands keep their admitted policy. Blank means unrestricted. The runner or host may apply a stricter explicit policy; browser, computer-use, and terminal capabilities remain unchanged." })
1323
+ /* @__PURE__ */ jsx8("h2", { className: "text-og-sm font-semibold text-og-fg", children: "Per-command resource policy" }),
1324
+ /* @__PURE__ */ jsx8("p", { className: "text-og-xs leading-relaxed text-og-fg-muted", children: "Optional limits applied separately to each newly admitted exec and Git command. Running commands keep their admitted policy. Blank means unrestricted. The runner or host may apply a stricter explicit policy; browser, computer-use, and terminal capabilities remain unchanged." })
1144
1325
  ] }),
1145
1326
  configured && (unsupportedMemory || unsupportedCpu) ? /* @__PURE__ */ jsxs7("div", { className: "mt-3 flex gap-2 rounded-og-md border border-og-status-failed/40 bg-og-status-failed/5 p-3 text-og-xs text-og-status-failed", children: [
1146
- /* @__PURE__ */ jsx7(AlertTriangleIcon2, { className: "mt-0.5 size-3.5 shrink-0", "aria-hidden": true }),
1327
+ /* @__PURE__ */ jsx8(AlertTriangleIcon2, { className: "mt-0.5 size-3.5 shrink-0", "aria-hidden": true }),
1147
1328
  /* @__PURE__ */ jsxs7("span", { children: [
1148
1329
  unsupportedCpu ? "This runner cannot enforce the configured CPU limit." : "This runner cannot enforce the configured memory limit.",
1149
1330
  " ",
@@ -1153,7 +1334,7 @@ function MachineOperationPolicyEditor({
1153
1334
  /* @__PURE__ */ jsxs7("form", { className: "mt-4 grid gap-3 sm:grid-cols-2", onSubmit: submit, children: [
1154
1335
  /* @__PURE__ */ jsxs7("label", { className: "flex flex-col gap-1.5 text-og-xs text-og-fg-muted", children: [
1155
1336
  "Hard ceiling (bytes)",
1156
- /* @__PURE__ */ jsx7(
1337
+ /* @__PURE__ */ jsx8(
1157
1338
  "input",
1158
1339
  {
1159
1340
  inputMode: "numeric",
@@ -1168,7 +1349,7 @@ function MachineOperationPolicyEditor({
1168
1349
  ] }),
1169
1350
  /* @__PURE__ */ jsxs7("label", { className: "flex flex-col gap-1.5 text-og-xs text-og-fg-muted", children: [
1170
1351
  "Reclaim threshold (bytes)",
1171
- /* @__PURE__ */ jsx7(
1352
+ /* @__PURE__ */ jsx8(
1172
1353
  "input",
1173
1354
  {
1174
1355
  inputMode: "numeric",
@@ -1183,7 +1364,7 @@ function MachineOperationPolicyEditor({
1183
1364
  ] }),
1184
1365
  /* @__PURE__ */ jsxs7("label", { className: "flex flex-col gap-1.5 text-og-xs text-og-fg-muted", children: [
1185
1366
  "CPU maximum (millicores)",
1186
- /* @__PURE__ */ jsx7(
1367
+ /* @__PURE__ */ jsx8(
1187
1368
  "input",
1188
1369
  {
1189
1370
  inputMode: "numeric",
@@ -1195,10 +1376,10 @@ function MachineOperationPolicyEditor({
1195
1376
  className: "min-h-9 rounded-og-sm border border-og-border bg-og-bg px-2.5 font-og-mono text-og-sm text-og-fg outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent/50 disabled:opacity-60"
1196
1377
  }
1197
1378
  ),
1198
- /* @__PURE__ */ jsx7("span", { children: "1000 millicores = one CPU core. Blank is unlimited." })
1379
+ /* @__PURE__ */ jsx8("span", { children: "1000 millicores = one CPU core. Blank is unlimited." })
1199
1380
  ] }),
1200
1381
  /* @__PURE__ */ jsxs7("div", { className: "flex min-h-9 items-center justify-between gap-3 sm:col-span-2", children: [
1201
- /* @__PURE__ */ jsx7(
1382
+ /* @__PURE__ */ jsx8(
1202
1383
  "span",
1203
1384
  {
1204
1385
  role: validationError ? "alert" : void 0,
@@ -1211,9 +1392,9 @@ function MachineOperationPolicyEditor({
1211
1392
  {
1212
1393
  type: "submit",
1213
1394
  disabled: saving,
1214
- className: "inline-flex min-h-9 items-center gap-1.5 rounded-og-sm bg-og-accent px-3 py-1.5 text-og-xs font-medium text-og-accent-fg transition-colors hover:bg-og-accent-strong disabled:cursor-not-allowed disabled:opacity-60",
1395
+ className: "inline-flex min-h-9 items-center gap-1.5 rounded-og-sm border border-og-primary-border bg-og-primary text-og-primary-fg px-3 py-1.5 text-og-xs font-medium transition-colors hover:bg-og-primary-hover disabled:cursor-not-allowed disabled:opacity-60",
1215
1396
  children: [
1216
- saving ? /* @__PURE__ */ jsx7(Loader2Icon, { className: "size-3.5 animate-spin", "aria-hidden": true }) : null,
1397
+ saving ? /* @__PURE__ */ jsx8(Loader2Icon, { className: "size-3.5 animate-spin", "aria-hidden": true }) : null,
1217
1398
  "Save policy"
1218
1399
  ]
1219
1400
  }
@@ -1226,22 +1407,162 @@ function MachineOperationPolicyEditor({
1226
1407
  }
1227
1408
 
1228
1409
  // src/components/machines/machine-detail.tsx
1229
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
1410
+ import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1411
+ var AUDIENCE = {
1412
+ user: { label: "Only me", description: "Only its owner can run chats on it.", Icon: UserIcon },
1413
+ workspace: {
1414
+ label: "This workspace",
1415
+ description: "Everyone in this workspace can run chats on it.",
1416
+ Icon: UsersIcon2
1417
+ },
1418
+ organization: {
1419
+ label: "Whole organization",
1420
+ description: "Every workspace in the organization can use it.",
1421
+ Icon: BuildingIcon
1422
+ }
1423
+ };
1424
+ function MachineAudienceRow({
1425
+ machine,
1426
+ onChange
1427
+ }) {
1428
+ const audience = AUDIENCE[machine.scope];
1429
+ const changeable = onChange !== void 0 && machine.scope !== "organization";
1430
+ const content = /* @__PURE__ */ jsxs8(Fragment2, { children: [
1431
+ /* @__PURE__ */ jsx9(audience.Icon, { className: "size-4 shrink-0 text-og-fg-subtle", "aria-hidden": true }),
1432
+ /* @__PURE__ */ jsxs8("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5 text-left", children: [
1433
+ /* @__PURE__ */ jsx9("span", { className: "text-og-sm font-medium text-og-fg", children: "Who can use it?" }),
1434
+ /* @__PURE__ */ jsx9("span", { className: "text-og-xs text-og-fg-muted", children: audience.description })
1435
+ ] }),
1436
+ /* @__PURE__ */ jsx9("span", { className: "shrink-0 text-og-sm text-og-fg-muted", children: audience.label }),
1437
+ changeable ? /* @__PURE__ */ jsx9(ChevronRightIcon, { className: "size-4 shrink-0 text-og-fg-subtle", "aria-hidden": true }) : null
1438
+ ] });
1439
+ const frame = "flex w-full min-h-14 items-center gap-3 rounded-og-lg border border-og-border bg-og-surface-1 px-4 py-3 shadow-og-sm";
1440
+ return changeable ? /* @__PURE__ */ jsx9(
1441
+ "button",
1442
+ {
1443
+ type: "button",
1444
+ "data-machine-audience": machine.scope,
1445
+ onClick: () => onChange(machine),
1446
+ "aria-label": `Who can use ${machine.name}: ${audience.label}. Change`,
1447
+ className: cn(
1448
+ frame,
1449
+ "transition-colors hover:bg-og-surface-2 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent/50"
1450
+ ),
1451
+ children: content
1452
+ }
1453
+ ) : /* @__PURE__ */ jsx9("div", { "data-machine-audience": machine.scope, className: frame, children: content });
1454
+ }
1230
1455
  function KindIcon2({ kind, session }) {
1231
- if (session) return /* @__PURE__ */ jsx8(ServerIcon2, { className: "size-4 text-og-fg-subtle", "aria-hidden": true });
1232
- if (kind === "modal") return /* @__PURE__ */ jsx8(CpuIcon2, { className: "size-4 text-og-fg-subtle", "aria-hidden": true });
1233
- return /* @__PURE__ */ jsx8(LaptopIcon2, { className: "size-4 text-og-fg-subtle", "aria-hidden": true });
1456
+ if (kind === "local" || kind === "selfhosted")
1457
+ return /* @__PURE__ */ jsx9(LaptopIcon2, { className: "size-4 text-og-fg-subtle", "aria-hidden": true });
1458
+ if (kind === "docker" || session)
1459
+ return /* @__PURE__ */ jsx9(ServerIcon2, { className: "size-4 text-og-fg-subtle", "aria-hidden": true });
1460
+ if (kind === "modal") return /* @__PURE__ */ jsx9(CpuIcon2, { className: "size-4 text-og-fg-subtle", "aria-hidden": true });
1461
+ return /* @__PURE__ */ jsx9(ServerIcon2, { className: "size-4 text-og-fg-subtle", "aria-hidden": true });
1462
+ }
1463
+ function MachineAgentPanel({
1464
+ machine,
1465
+ now,
1466
+ onUpdateAgent,
1467
+ updatingAgent
1468
+ }) {
1469
+ const authority = machine.connectionAuthority;
1470
+ const runtime = machine.runtime;
1471
+ if (!runtime && authority.state === "not_applicable") return null;
1472
+ const agent = runtime ? describeAgentRuntime(runtime, now) : null;
1473
+ const action = agent?.action && machine.enrollmentId && onUpdateAgent && machine.state !== "offline" ? agent.action : null;
1474
+ const connection = authority.state === "not_applicable" ? null : describeAgentConnection(authority);
1475
+ const conflict = runnerConflict(authority, now);
1476
+ const conflictAgo = conflict?.lastAt ? formatRelativeTime(conflict.lastAt, new Date(now)) : null;
1477
+ return /* @__PURE__ */ jsxs8(
1478
+ "section",
1479
+ {
1480
+ "data-machine-agent": true,
1481
+ "aria-label": "Agent",
1482
+ className: "flex flex-col divide-y divide-og-border rounded-og-lg border border-og-border bg-og-surface-1 shadow-og-sm",
1483
+ children: [
1484
+ agent ? /* @__PURE__ */ jsxs8("div", { "data-agent-runtime": true, className: "flex min-h-14 items-center gap-3 px-4 py-3", children: [
1485
+ /* @__PURE__ */ jsx9(AgentStatusIcon, { tone: agent.tone, className: "size-4" }),
1486
+ /* @__PURE__ */ jsxs8("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
1487
+ /* @__PURE__ */ jsx9("span", { className: "text-og-sm font-medium text-og-fg", children: agent.title }),
1488
+ /* @__PURE__ */ jsx9(
1489
+ "span",
1490
+ {
1491
+ "data-agent-status": agent.tone,
1492
+ className: cn("text-og-xs", STATUS_TONE_TEXT[agent.tone]),
1493
+ children: agent.status
1494
+ }
1495
+ ),
1496
+ agent.note ? /* @__PURE__ */ jsx9("span", { className: "text-og-xs text-og-fg-muted", children: agent.note }) : null
1497
+ ] }),
1498
+ action ? /* @__PURE__ */ jsx9(
1499
+ "button",
1500
+ {
1501
+ type: "button",
1502
+ "data-update-agent": true,
1503
+ "data-update-action": action.kind,
1504
+ disabled: updatingAgent,
1505
+ onClick: () => onUpdateAgent?.(machine),
1506
+ className: "inline-flex min-h-9 shrink-0 items-center rounded-og-sm border border-og-border px-3 py-1 text-og-xs font-medium text-og-fg-muted transition-colors hover:border-og-border-strong hover:text-og-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent/50 disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:min-h-11",
1507
+ children: updatingAgent ? "Starting\u2026" : action.label
1508
+ }
1509
+ ) : null
1510
+ ] }) : null,
1511
+ connection ? /* @__PURE__ */ jsxs8(
1512
+ "div",
1513
+ {
1514
+ "data-connection-authority": authority.state,
1515
+ className: "flex min-h-14 items-start gap-3 px-4 py-3",
1516
+ children: [
1517
+ /* @__PURE__ */ jsx9(PlugIcon, { className: "mt-0.5 size-4 shrink-0 text-og-fg-subtle", "aria-hidden": true }),
1518
+ /* @__PURE__ */ jsxs8("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
1519
+ /* @__PURE__ */ jsx9("span", { className: "text-og-sm font-medium text-og-fg", children: connection.label }),
1520
+ connection.detail ? /* @__PURE__ */ jsx9("span", { className: "text-og-xs text-og-fg-muted", children: connection.detail }) : null,
1521
+ conflict?.active ? /* @__PURE__ */ jsxs8(
1522
+ "span",
1523
+ {
1524
+ "data-runner-conflict": "active",
1525
+ className: "mt-1 flex items-start gap-1.5 text-og-xs text-og-fg-muted",
1526
+ children: [
1527
+ /* @__PURE__ */ jsx9(
1528
+ TriangleAlertIcon2,
1529
+ {
1530
+ className: "mt-px size-3.5 shrink-0 text-og-status-waiting",
1531
+ "aria-hidden": true
1532
+ }
1533
+ ),
1534
+ "A second copy of the agent is running on this machine. It's kept out, so work isn't affected. Stop the extra copy."
1535
+ ]
1536
+ }
1537
+ ) : conflict ? /* @__PURE__ */ jsxs8("span", { "data-runner-conflict": "past", className: "text-og-xs text-og-fg-subtle", children: [
1538
+ "Kept out ",
1539
+ conflict.count,
1540
+ " extra ",
1541
+ conflict.count === 1 ? "copy" : "copies",
1542
+ " of the agent",
1543
+ conflictAgo ? `, most recently ${conflictAgo === "now" ? "just now" : `${conflictAgo} ago`}` : ""
1544
+ ] }) : null
1545
+ ] })
1546
+ ]
1547
+ }
1548
+ ) : null
1549
+ ]
1550
+ }
1551
+ );
1234
1552
  }
1235
1553
  function MachineDetail({
1236
1554
  machine,
1237
1555
  series,
1238
- window: window2,
1556
+ window,
1239
1557
  onWindowChange,
1240
1558
  loadingSeries,
1241
1559
  onBack,
1242
1560
  onRemove,
1243
1561
  onUpdateOperationPolicy,
1244
1562
  updatingOperationPolicy,
1563
+ onChangeAudience,
1564
+ onUpdateAgent,
1565
+ updatingAgent,
1245
1566
  now = Date.now(),
1246
1567
  className
1247
1568
  }) {
@@ -1249,25 +1570,23 @@ function MachineDetail({
1249
1570
  const tone = HEALTH_TOKEN[health.level];
1250
1571
  const latest = machine.metrics;
1251
1572
  const sampledAgo = latest ? formatRelativeTime(latest.sampledAt, new Date(now)) : null;
1252
- const authority = machine.connectionAuthority;
1253
- const duplicateDeniedAgo = authority.duplicateRunnerDeniedAt ? formatRelativeTime(authority.duplicateRunnerDeniedAt, new Date(now)) : null;
1254
1573
  const visible = METRICS.filter((m) => !(m.key === "gpu" && latest?.gpuUtilPct == null));
1255
1574
  const tileCols = visible.length >= 5 ? "grid-cols-2 sm:grid-cols-3 lg:grid-cols-5" : "grid-cols-2 sm:grid-cols-4";
1256
1575
  return /* @__PURE__ */ jsxs8("div", { className: cn("og-root mx-auto flex w-full max-w-5xl flex-col gap-5", className), children: [
1257
1576
  /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between gap-3", children: [
1258
1577
  /* @__PURE__ */ jsxs8("div", { className: "flex min-w-0 items-center gap-2.5", children: [
1259
- onBack && /* @__PURE__ */ jsx8(
1578
+ onBack && /* @__PURE__ */ jsx9(
1260
1579
  "button",
1261
1580
  {
1262
1581
  type: "button",
1263
1582
  onClick: onBack,
1264
1583
  className: "flex size-7 shrink-0 items-center justify-center rounded-og-sm border border-og-border bg-og-surface-1 text-og-fg-muted transition-colors hover:bg-og-surface-2 hover:text-og-fg",
1265
1584
  "aria-label": "Back to machines",
1266
- children: /* @__PURE__ */ jsx8(ArrowLeftIcon, { className: "size-3.5", "aria-hidden": true })
1585
+ children: /* @__PURE__ */ jsx9(ArrowLeftIcon, { className: "size-3.5", "aria-hidden": true })
1267
1586
  }
1268
1587
  ),
1269
- /* @__PURE__ */ jsx8(KindIcon2, { kind: machine.kind, session: machine.isSessionGroup }),
1270
- /* @__PURE__ */ jsx8("h1", { className: "truncate text-og-md font-semibold text-og-fg", children: machine.name }),
1588
+ /* @__PURE__ */ jsx9(KindIcon2, { kind: machine.kind, session: machine.isSessionGroup }),
1589
+ /* @__PURE__ */ jsx9("h1", { className: "truncate text-og-md font-semibold text-og-fg", children: machine.name }),
1271
1590
  /* @__PURE__ */ jsxs8("span", { className: "hidden shrink-0 rounded-og-sm border border-og-border bg-og-surface-1 px-1.5 py-0.5 font-og-mono text-og-xs text-og-fg-subtle sm:inline", children: [
1272
1591
  machine.os,
1273
1592
  " \xB7 ",
@@ -1284,20 +1603,20 @@ function MachineDetail({
1284
1603
  onClick: () => onRemove(machine),
1285
1604
  className: "inline-flex min-h-9 items-center gap-1.5 rounded-og-sm border border-og-status-failed/40 px-2.5 py-1 font-medium text-og-xs text-og-status-failed transition-colors hover:bg-og-status-failed/10 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-status-failed/50 pointer-coarse:min-h-11",
1286
1605
  children: [
1287
- /* @__PURE__ */ jsx8(Trash2Icon, { className: "size-3.5", "aria-hidden": true }),
1288
- /* @__PURE__ */ jsx8("span", { className: "hidden sm:inline", children: "Remove machine" })
1606
+ /* @__PURE__ */ jsx9(Trash2Icon, { className: "size-3.5", "aria-hidden": true }),
1607
+ /* @__PURE__ */ jsx9("span", { className: "hidden sm:inline", children: "Remove machine" })
1289
1608
  ]
1290
1609
  }
1291
1610
  ) : null,
1292
- /* @__PURE__ */ jsx8("div", { className: "flex items-center gap-0.5 rounded-og-md border border-og-border bg-og-surface-1 p-0.5", children: METRIC_WINDOWS.map((w) => /* @__PURE__ */ jsx8(
1611
+ /* @__PURE__ */ jsx9("div", { className: "flex items-center gap-0.5 rounded-og-md border border-og-border bg-og-surface-1 p-0.5", children: METRIC_WINDOWS.map((w) => /* @__PURE__ */ jsx9(
1293
1612
  "button",
1294
1613
  {
1295
1614
  type: "button",
1296
1615
  onClick: () => onWindowChange(w),
1297
- "data-active": w === window2,
1616
+ "data-active": w === window,
1298
1617
  className: cn(
1299
1618
  "rounded-og-sm px-2 py-1 font-og-mono text-og-xs transition-colors",
1300
- w === window2 ? "bg-og-surface-3 text-og-fg shadow-og-sm" : "text-og-fg-subtle hover:text-og-fg-muted"
1619
+ w === window ? "bg-og-surface-3 text-og-fg shadow-og-sm" : "text-og-fg-subtle hover:text-og-fg-muted"
1301
1620
  ),
1302
1621
  children: w
1303
1622
  },
@@ -1313,11 +1632,11 @@ function MachineDetail({
1313
1632
  tone.soft
1314
1633
  ),
1315
1634
  children: [
1316
- /* @__PURE__ */ jsx8("span", { "aria-hidden": true, className: cn("absolute inset-y-0 left-0 w-1", tone.dot) }),
1635
+ /* @__PURE__ */ jsx9("span", { "aria-hidden": true, className: cn("absolute inset-y-0 left-0 w-1", tone.dot) }),
1317
1636
  /* @__PURE__ */ jsxs8("div", { className: "flex flex-wrap items-center justify-between gap-3 pl-1", children: [
1318
1637
  /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-3", children: [
1319
1638
  /* @__PURE__ */ jsxs8("span", { className: "relative flex size-3", children: [
1320
- healthPulses(health.level) && /* @__PURE__ */ jsx8(
1639
+ healthPulses(health.level) && /* @__PURE__ */ jsx9(
1321
1640
  "span",
1322
1641
  {
1323
1642
  className: cn(
@@ -1326,18 +1645,18 @@ function MachineDetail({
1326
1645
  )
1327
1646
  }
1328
1647
  ),
1329
- /* @__PURE__ */ jsx8("span", { className: cn("relative inline-flex size-3 rounded-full", tone.dot) })
1648
+ /* @__PURE__ */ jsx9("span", { className: cn("relative inline-flex size-3 rounded-full", tone.dot) })
1330
1649
  ] }),
1331
1650
  /* @__PURE__ */ jsxs8("div", { className: "flex flex-col", children: [
1332
- /* @__PURE__ */ jsx8("span", { className: cn("text-og-md font-semibold", tone.text), children: health.label }),
1333
- /* @__PURE__ */ jsx8("span", { className: "text-og-sm text-og-fg-muted", children: health.reason })
1651
+ /* @__PURE__ */ jsx9("span", { className: cn("text-og-md font-semibold", tone.text), children: health.label }),
1652
+ /* @__PURE__ */ jsx9("span", { className: "text-og-sm text-og-fg-muted", children: health.reason })
1334
1653
  ] })
1335
1654
  ] }),
1336
1655
  /* @__PURE__ */ jsxs8("div", { className: "flex items-start gap-5 pr-1", children: [
1337
1656
  sampledAgo && /* @__PURE__ */ jsxs8("div", { className: "flex flex-col items-end gap-0.5", children: [
1338
- /* @__PURE__ */ jsx8("span", { className: "text-[10px] font-medium uppercase tracking-wide text-og-fg-subtle", children: "Sampled" }),
1657
+ /* @__PURE__ */ jsx9("span", { className: "text-[10px] font-medium uppercase tracking-wide text-og-fg-subtle", children: "Sampled" }),
1339
1658
  /* @__PURE__ */ jsxs8("span", { className: "flex items-center gap-1 font-og-mono text-og-sm tabular-nums text-og-fg", children: [
1340
- /* @__PURE__ */ jsx8(
1659
+ /* @__PURE__ */ jsx9(
1341
1660
  RadioIcon,
1342
1661
  {
1343
1662
  className: cn("size-3", health.stale ? "text-og-fg-subtle" : tone.text),
@@ -1348,12 +1667,12 @@ function MachineDetail({
1348
1667
  ] })
1349
1668
  ] }),
1350
1669
  machine.lastSeenAt && /* @__PURE__ */ jsxs8("div", { className: "hidden flex-col items-end gap-0.5 sm:flex", children: [
1351
- /* @__PURE__ */ jsx8("span", { className: "text-[10px] font-medium uppercase tracking-wide text-og-fg-subtle", children: "Last seen" }),
1352
- /* @__PURE__ */ jsx8("span", { className: "font-og-mono text-og-sm tabular-nums text-og-fg-muted", children: formatRelativeTime(machine.lastSeenAt, new Date(now)) })
1670
+ /* @__PURE__ */ jsx9("span", { className: "text-[10px] font-medium uppercase tracking-wide text-og-fg-subtle", children: "Last seen" }),
1671
+ /* @__PURE__ */ jsx9("span", { className: "font-og-mono text-og-sm tabular-nums text-og-fg-muted", children: formatRelativeTime(machine.lastSeenAt, new Date(now)) })
1353
1672
  ] })
1354
1673
  ] })
1355
1674
  ] }),
1356
- latest && /* @__PURE__ */ jsx8(
1675
+ latest && /* @__PURE__ */ jsx9(
1357
1676
  "div",
1358
1677
  {
1359
1678
  className: cn(
@@ -1363,42 +1682,28 @@ function MachineDetail({
1363
1682
  children: visible.map((m) => {
1364
1683
  const pts = pointsFor(m, series);
1365
1684
  return /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-1.5 bg-og-surface-1 p-3", children: [
1366
- /* @__PURE__ */ jsx8("span", { className: "text-[10px] font-medium uppercase tracking-wide text-og-fg-subtle", children: m.title }),
1367
- /* @__PURE__ */ jsx8("span", { className: "font-og-mono text-og-md font-medium tabular-nums text-og-fg", children: m.current(latest) }),
1368
- /* @__PURE__ */ jsx8(MetricSparkline, { points: pts, color: m.color, yMax: m.yMax, height: 22 }),
1369
- m.sub && /* @__PURE__ */ jsx8("span", { className: "truncate font-og-mono text-[10px] text-og-fg-subtle", children: m.sub(latest) })
1685
+ /* @__PURE__ */ jsx9("span", { className: "text-[10px] font-medium uppercase tracking-wide text-og-fg-subtle", children: m.title }),
1686
+ /* @__PURE__ */ jsx9("span", { className: "font-og-mono text-og-md font-medium tabular-nums text-og-fg", children: m.current(latest) }),
1687
+ /* @__PURE__ */ jsx9(MetricSparkline, { points: pts, color: m.color, yMax: m.yMax, height: 22 }),
1688
+ m.sub && /* @__PURE__ */ jsx9("span", { className: "truncate font-og-mono text-[10px] text-og-fg-subtle", children: m.sub(latest) })
1370
1689
  ] }, m.key);
1371
1690
  })
1372
1691
  }
1373
- ),
1374
- authority.state !== "not_applicable" ? /* @__PURE__ */ jsxs8(
1375
- "div",
1376
- {
1377
- "data-connection-authority": authority.state,
1378
- className: "flex flex-wrap items-center justify-between gap-2 rounded-og-md border border-og-border bg-og-surface-1/75 px-3 py-2 text-og-xs",
1379
- children: [
1380
- /* @__PURE__ */ jsxs8("span", { className: "text-og-fg-muted", children: [
1381
- "Runner ",
1382
- authority.state.replace("_", " "),
1383
- " \xB7 generation ",
1384
- authority.generation,
1385
- authority.supersededCount > 0 ? ` \xB7 ${authority.supersededCount} earlier ${authority.supersededCount === 1 ? "runner" : "runners"} fenced` : ""
1386
- ] }),
1387
- authority.duplicateRunnerDeniedCount > 0 ? /* @__PURE__ */ jsxs8("span", { className: "inline-flex items-center gap-1.5 text-og-status-failed", children: [
1388
- /* @__PURE__ */ jsx8(AlertTriangleIcon3, { className: "size-3.5", "aria-hidden": true }),
1389
- "Blocked ",
1390
- authority.duplicateRunnerDeniedCount,
1391
- " competing runner",
1392
- authority.duplicateRunnerDeniedCount === 1 ? "" : "s",
1393
- duplicateDeniedAgo ? ` \xB7 ${duplicateDeniedAgo === "now" ? "now" : `${duplicateDeniedAgo} ago`}` : ""
1394
- ] }) : null
1395
- ]
1396
- }
1397
- ) : null
1692
+ )
1398
1693
  ]
1399
1694
  }
1400
1695
  ),
1401
- onUpdateOperationPolicy && machine.enrollmentId && machine.operationPolicy ? /* @__PURE__ */ jsx8(
1696
+ /* @__PURE__ */ jsx9(
1697
+ MachineAgentPanel,
1698
+ {
1699
+ machine,
1700
+ now,
1701
+ onUpdateAgent,
1702
+ updatingAgent
1703
+ }
1704
+ ),
1705
+ machine.enrollmentId && !machine.isSessionGroup ? /* @__PURE__ */ jsx9(MachineAudienceRow, { machine, onChange: onChangeAudience }) : null,
1706
+ onUpdateOperationPolicy && machine.enrollmentId && machine.operationPolicy ? /* @__PURE__ */ jsx9(
1402
1707
  MachineOperationPolicyEditor,
1403
1708
  {
1404
1709
  policy: machine.operationPolicy,
@@ -1408,7 +1713,7 @@ function MachineDetail({
1408
1713
  onSave: (request) => onUpdateOperationPolicy(machine, request)
1409
1714
  }
1410
1715
  ) : null,
1411
- /* @__PURE__ */ jsx8("div", { className: "grid grid-cols-1 gap-3 lg:grid-cols-2", children: visible.map((m) => {
1716
+ /* @__PURE__ */ jsx9("div", { className: "grid grid-cols-1 gap-3 lg:grid-cols-2", children: visible.map((m) => {
1412
1717
  const pts = pointsFor(m, series);
1413
1718
  return /* @__PURE__ */ jsxs8(
1414
1719
  "div",
@@ -1416,10 +1721,10 @@ function MachineDetail({
1416
1721
  className: "flex flex-col gap-3 rounded-og-lg border border-og-border bg-og-surface-1 p-4 shadow-og-sm",
1417
1722
  children: [
1418
1723
  /* @__PURE__ */ jsxs8("div", { className: "flex items-baseline justify-between", children: [
1419
- /* @__PURE__ */ jsx8("span", { className: "text-og-sm font-medium text-og-fg", children: m.title }),
1420
- latest && /* @__PURE__ */ jsx8("span", { className: "font-og-mono text-og-sm tabular-nums text-og-fg-muted", children: m.current(latest) })
1724
+ /* @__PURE__ */ jsx9("span", { className: "text-og-sm font-medium text-og-fg", children: m.title }),
1725
+ latest && /* @__PURE__ */ jsx9("span", { className: "font-og-mono text-og-sm tabular-nums text-og-fg-muted", children: m.current(latest) })
1421
1726
  ] }),
1422
- /* @__PURE__ */ jsx8(
1727
+ /* @__PURE__ */ jsx9(
1423
1728
  MetricHistoryChart,
1424
1729
  {
1425
1730
  points: pts,
@@ -1427,7 +1732,7 @@ function MachineDetail({
1427
1732
  unit: m.unit,
1428
1733
  color: m.color,
1429
1734
  thresholds: m.thresholds,
1430
- rangeLabel: WINDOW_LABEL[window2],
1735
+ rangeLabel: WINDOW_LABEL[window],
1431
1736
  height: 128,
1432
1737
  className: cn(loadingSeries && "opacity-50 transition-opacity")
1433
1738
  }
@@ -1442,7 +1747,7 @@ function MachineDetail({
1442
1747
 
1443
1748
  // src/components/machines-dashboard.tsx
1444
1749
  import { LaptopIcon as LaptopIcon3, PlusIcon, RefreshCwIcon } from "lucide-react";
1445
- import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1750
+ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1446
1751
  function EmptyState({ onEnroll }) {
1447
1752
  return /* @__PURE__ */ jsxs9(
1448
1753
  "div",
@@ -1450,10 +1755,10 @@ function EmptyState({ onEnroll }) {
1450
1755
  "data-machines-empty": true,
1451
1756
  className: "flex flex-col items-center justify-center gap-3 rounded-og-lg border border-dashed border-og-border bg-og-surface-1 px-6 py-12 text-center",
1452
1757
  children: [
1453
- /* @__PURE__ */ jsx9("span", { className: "flex size-10 items-center justify-center rounded-full bg-og-surface-2 text-og-fg-subtle", children: /* @__PURE__ */ jsx9(LaptopIcon3, { className: "size-5", "aria-hidden": true }) }),
1758
+ /* @__PURE__ */ jsx10("span", { className: "flex size-10 items-center justify-center rounded-full bg-og-surface-2 text-og-fg-subtle", children: /* @__PURE__ */ jsx10(LaptopIcon3, { className: "size-5", "aria-hidden": true }) }),
1454
1759
  /* @__PURE__ */ jsxs9("div", { className: "space-y-1", children: [
1455
- /* @__PURE__ */ jsx9("p", { className: "text-og-base font-medium text-og-fg", children: "No machines yet" }),
1456
- /* @__PURE__ */ jsx9("p", { className: "max-w-xs text-og-sm text-og-fg-muted", children: "Connect your own computer to run the agent on it \u2014 your files, your terminal, your desktop." })
1760
+ /* @__PURE__ */ jsx10("p", { className: "text-og-base font-medium text-og-fg", children: "No machines yet" }),
1761
+ /* @__PURE__ */ jsx10("p", { className: "max-w-xs text-og-sm text-og-fg-muted", children: "Connect your own computer to run the agent on it \u2014 your files, your terminal, your desktop." })
1457
1762
  ] }),
1458
1763
  onEnroll ? /* @__PURE__ */ jsxs9(
1459
1764
  "button",
@@ -1461,9 +1766,9 @@ function EmptyState({ onEnroll }) {
1461
1766
  type: "button",
1462
1767
  "data-enroll-cta": true,
1463
1768
  onClick: onEnroll,
1464
- className: "inline-flex items-center gap-1.5 rounded-og-sm bg-og-accent px-3 py-1.5 text-og-sm font-medium text-og-accent-fg transition-colors hover:bg-og-accent-strong pointer-coarse:min-h-11",
1769
+ className: "inline-flex items-center gap-1.5 rounded-og-sm border border-og-primary-border bg-og-primary text-og-primary-fg px-3 py-1.5 text-og-sm font-medium transition-colors hover:bg-og-primary-hover pointer-coarse:min-h-11",
1465
1770
  children: [
1466
- /* @__PURE__ */ jsx9(PlusIcon, { className: "size-3.5", "aria-hidden": true }),
1771
+ /* @__PURE__ */ jsx10(PlusIcon, { className: "size-3.5", "aria-hidden": true }),
1467
1772
  "Connect a machine"
1468
1773
  ]
1469
1774
  }
@@ -1474,41 +1779,26 @@ function EmptyState({ onEnroll }) {
1474
1779
  }
1475
1780
  function Header({
1476
1781
  count,
1477
- onEnroll,
1478
- onRefresh,
1479
- loading
1782
+ onEnroll
1480
1783
  }) {
1481
1784
  return /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between gap-3", children: [
1482
1785
  /* @__PURE__ */ jsxs9("div", { className: "flex items-baseline gap-2", children: [
1483
- /* @__PURE__ */ jsx9("h2", { className: "text-og-base font-semibold text-og-fg", children: "Machines" }),
1484
- /* @__PURE__ */ jsx9("span", { className: "font-og-mono text-og-xs text-og-fg-subtle", children: count })
1786
+ /* @__PURE__ */ jsx10("h2", { className: "text-og-base font-semibold text-og-fg", children: "Machines" }),
1787
+ /* @__PURE__ */ jsx10("span", { className: "font-og-mono text-og-xs text-og-fg-subtle", children: count })
1485
1788
  ] }),
1486
- /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-1.5", children: [
1487
- onRefresh ? /* @__PURE__ */ jsx9(
1488
- "button",
1489
- {
1490
- type: "button",
1491
- "data-refresh": true,
1492
- onClick: onRefresh,
1493
- title: "Refresh",
1494
- className: "rounded-og-sm p-1.5 text-og-fg-subtle transition-colors hover:bg-og-surface-2 hover:text-og-fg",
1495
- children: /* @__PURE__ */ jsx9(RefreshCwIcon, { className: cn("size-3.5", loading && "animate-og-spin"), "aria-hidden": true })
1496
- }
1497
- ) : null,
1498
- onEnroll ? /* @__PURE__ */ jsxs9(
1499
- "button",
1500
- {
1501
- type: "button",
1502
- "data-enroll-cta": true,
1503
- onClick: onEnroll,
1504
- className: "inline-flex items-center gap-1.5 rounded-og-sm border border-og-border px-2.5 py-1 text-og-sm font-medium text-og-fg-muted transition-colors hover:border-og-border-strong hover:text-og-fg pointer-coarse:min-h-11",
1505
- children: [
1506
- /* @__PURE__ */ jsx9(PlusIcon, { className: "size-3.5", "aria-hidden": true }),
1507
- "Connect a machine"
1508
- ]
1509
- }
1510
- ) : null
1511
- ] })
1789
+ /* @__PURE__ */ jsx10("div", { className: "flex items-center gap-1.5", children: onEnroll ? /* @__PURE__ */ jsxs9(
1790
+ "button",
1791
+ {
1792
+ type: "button",
1793
+ "data-enroll-cta": true,
1794
+ onClick: onEnroll,
1795
+ className: "inline-flex items-center gap-1.5 rounded-og-sm border border-og-border px-2.5 py-1 text-og-sm font-medium text-og-fg-muted transition-colors hover:border-og-border-strong hover:text-og-fg pointer-coarse:min-h-11",
1796
+ children: [
1797
+ /* @__PURE__ */ jsx10(PlusIcon, { className: "size-3.5", "aria-hidden": true }),
1798
+ "Connect a machine"
1799
+ ]
1800
+ }
1801
+ ) : null })
1512
1802
  ] });
1513
1803
  }
1514
1804
  function MachinesDashboard({
@@ -1529,7 +1819,7 @@ function MachinesDashboard({
1529
1819
  }) {
1530
1820
  const isEmpty = !loading && !error && machines.length === 0;
1531
1821
  return /* @__PURE__ */ jsxs9("section", { "data-machines-dashboard": true, className: cn("og-root flex flex-col gap-3", className), children: [
1532
- /* @__PURE__ */ jsx9(Header, { count: machines.length, onEnroll, onRefresh, loading }),
1822
+ /* @__PURE__ */ jsx10(Header, { count: machines.length, onEnroll }),
1533
1823
  error ? /* @__PURE__ */ jsxs9(
1534
1824
  "div",
1535
1825
  {
@@ -1549,7 +1839,7 @@ function MachinesDashboard({
1549
1839
  disabled: loading,
1550
1840
  className: "inline-flex items-center gap-1.5 rounded-og-sm border border-og-status-failed/30 px-2 py-1 text-og-xs font-medium transition-colors hover:border-og-status-failed/50 disabled:cursor-not-allowed disabled:opacity-60 pointer-coarse:min-h-11",
1551
1841
  children: [
1552
- /* @__PURE__ */ jsx9(RefreshCwIcon, { className: cn("size-3.5", loading && "animate-og-spin"), "aria-hidden": true }),
1842
+ /* @__PURE__ */ jsx10(RefreshCwIcon, { className: cn("size-3.5", loading && "animate-og-spin"), "aria-hidden": true }),
1553
1843
  loading ? "Retrying\u2026" : "Retry"
1554
1844
  ]
1555
1845
  }
@@ -1557,13 +1847,13 @@ function MachinesDashboard({
1557
1847
  ]
1558
1848
  }
1559
1849
  ) : null,
1560
- loading && machines.length === 0 ? /* @__PURE__ */ jsx9("div", { "data-machines-loading": true, className: "grid gap-3 sm:grid-cols-2", children: [0, 1].map((i) => /* @__PURE__ */ jsx9(
1850
+ loading && machines.length === 0 ? /* @__PURE__ */ jsx10("div", { "data-machines-loading": true, className: "grid gap-3 sm:grid-cols-2", children: [0, 1].map((i) => /* @__PURE__ */ jsx10(
1561
1851
  "div",
1562
1852
  {
1563
1853
  className: "h-36 animate-og-pulse rounded-og-lg border border-og-border bg-og-surface-1"
1564
1854
  },
1565
1855
  i
1566
- )) }) : isEmpty ? /* @__PURE__ */ jsx9(EmptyState, { onEnroll }) : /* @__PURE__ */ jsx9("div", { className: "grid gap-3 sm:grid-cols-2 xl:grid-cols-3", "data-machines-grid": true, children: machines.map((machine) => /* @__PURE__ */ jsx9(
1856
+ )) }) : isEmpty ? /* @__PURE__ */ jsx10(EmptyState, { onEnroll }) : /* @__PURE__ */ jsx10("div", { className: "grid gap-3 sm:grid-cols-2 xl:grid-cols-3", "data-machines-grid": true, children: machines.map((machine) => /* @__PURE__ */ jsx10(
1567
1857
  MachineCard,
1568
1858
  {
1569
1859
  machine: {
@@ -1584,10 +1874,10 @@ function MachinesDashboard({
1584
1874
  }
1585
1875
 
1586
1876
  // src/components/machine-dock-bar.tsx
1587
- import { LaptopIcon as LaptopIcon4, CpuIcon as CpuIcon3, UsersIcon as UsersIcon2 } from "lucide-react";
1588
- import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1877
+ import { LaptopIcon as LaptopIcon4, CpuIcon as CpuIcon3, UsersIcon as UsersIcon3 } from "lucide-react";
1878
+ import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
1589
1879
  function MachineDockBar({ name, kind, state, className }) {
1590
- const Icon = kind === "selfhosted" ? LaptopIcon4 : CpuIcon3;
1880
+ const Icon = kind === "selfhosted" || kind === "local" ? LaptopIcon4 : CpuIcon3;
1591
1881
  const stateBadge = MACHINE_STATE_BADGE_META[state];
1592
1882
  return /* @__PURE__ */ jsxs10(
1593
1883
  "div",
@@ -1599,9 +1889,9 @@ function MachineDockBar({ name, kind, state, className }) {
1599
1889
  ),
1600
1890
  children: [
1601
1891
  /* @__PURE__ */ jsxs10("div", { className: "flex min-w-0 items-center gap-1.5", children: [
1602
- /* @__PURE__ */ jsx10(Icon, { className: "size-3.5 shrink-0 text-og-fg-subtle", "aria-hidden": true }),
1603
- /* @__PURE__ */ jsx10("span", { className: "truncate text-[11px] font-medium text-og-fg", children: name }),
1604
- stateBadge ? /* @__PURE__ */ jsx10(
1892
+ /* @__PURE__ */ jsx11(Icon, { className: "size-3.5 shrink-0 text-og-fg-subtle", "aria-hidden": true }),
1893
+ /* @__PURE__ */ jsx11("span", { className: "truncate text-[11px] font-medium text-og-fg", children: name }),
1894
+ stateBadge ? /* @__PURE__ */ jsx11(
1605
1895
  "span",
1606
1896
  {
1607
1897
  "data-state-badge": state,
@@ -1613,7 +1903,7 @@ function MachineDockBar({ name, kind, state, className }) {
1613
1903
  }
1614
1904
  ) : null
1615
1905
  ] }),
1616
- /* @__PURE__ */ jsx10(
1906
+ /* @__PURE__ */ jsx11(
1617
1907
  ConnectionStatusPill,
1618
1908
  {
1619
1909
  status: connectionStatusForState(state),
@@ -1641,7 +1931,7 @@ function SharedMachineDisclosure({
1641
1931
  className
1642
1932
  ),
1643
1933
  children: [
1644
- /* @__PURE__ */ jsx10(UsersIcon2, { className: "size-3.5 shrink-0 text-og-accent", "aria-hidden": true }),
1934
+ /* @__PURE__ */ jsx11(UsersIcon3, { className: "size-3.5 shrink-0 text-og-accent", "aria-hidden": true }),
1645
1935
  /* @__PURE__ */ jsxs10("span", { children: [
1646
1936
  "Shared \u2014 ",
1647
1937
  others === 1 ? "another session is" : `${others} other sessions are`,
@@ -1654,7 +1944,7 @@ function SharedMachineDisclosure({
1654
1944
 
1655
1945
  // src/components/enrollment-device-flow.tsx
1656
1946
  import { CopyIcon, ExternalLinkIcon, LaptopIcon as LaptopIcon5, TerminalIcon } from "lucide-react";
1657
- import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
1947
+ import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
1658
1948
  var PHASE_TO_STATE = {
1659
1949
  pending: "enrolling",
1660
1950
  authorized: "online",
@@ -1670,7 +1960,7 @@ function PhaseLabel({ phase }) {
1670
1960
  expired: "Code expired",
1671
1961
  disabled: "Enrollment disabled"
1672
1962
  };
1673
- return /* @__PURE__ */ jsx11("span", { children: text[phase] });
1963
+ return /* @__PURE__ */ jsx12("span", { children: text[phase] });
1674
1964
  }
1675
1965
  function EnrollmentDeviceFlow({
1676
1966
  userCode,
@@ -1698,26 +1988,26 @@ function EnrollmentDeviceFlow({
1698
1988
  children: [
1699
1989
  /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between gap-3", children: [
1700
1990
  /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
1701
- /* @__PURE__ */ jsx11("span", { className: "flex size-7 items-center justify-center rounded-full bg-og-surface-2 text-og-fg-muted", children: /* @__PURE__ */ jsx11(LaptopIcon5, { className: "size-4", "aria-hidden": true }) }),
1702
- /* @__PURE__ */ jsx11("h2", { className: "text-og-menu font-semibold text-og-fg", children: "Connect a machine" })
1991
+ /* @__PURE__ */ jsx12("span", { className: "flex size-7 items-center justify-center rounded-full bg-og-surface-2 text-og-fg-muted", children: /* @__PURE__ */ jsx12(LaptopIcon5, { className: "size-4", "aria-hidden": true }) }),
1992
+ /* @__PURE__ */ jsx12("h2", { className: "text-og-menu font-semibold text-og-fg", children: "Connect a machine" })
1703
1993
  ] }),
1704
- /* @__PURE__ */ jsx11(
1994
+ /* @__PURE__ */ jsx12(
1705
1995
  ConnectionStatusPill,
1706
1996
  {
1707
1997
  status: PHASE_TO_STATE[phase] === "online" ? "online" : PHASE_TO_STATE[phase] === "offline" ? "offline" : "reconnecting",
1708
- label: /* @__PURE__ */ jsx11(PhaseLabel, { phase }),
1998
+ label: /* @__PURE__ */ jsx12(PhaseLabel, { phase }),
1709
1999
  size: "sm"
1710
2000
  }
1711
2001
  )
1712
2002
  ] }),
1713
2003
  installCommand ? /* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-1.5", children: [
1714
- /* @__PURE__ */ jsx11("span", { className: "text-[11px] font-medium uppercase tracking-wide text-og-fg-subtle", children: "1 \xB7 Run on the machine" }),
2004
+ /* @__PURE__ */ jsx12("span", { className: "text-[11px] font-medium uppercase tracking-wide text-og-fg-subtle", children: "1 \xB7 Run on the machine" }),
1715
2005
  /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between gap-2 overflow-hidden rounded-og-md border border-og-border bg-og-bg px-2.5 py-1.5", children: [
1716
2006
  /* @__PURE__ */ jsxs11("code", { className: "flex min-w-0 items-center gap-2 overflow-x-auto font-og-mono text-[12px] text-og-fg", children: [
1717
- /* @__PURE__ */ jsx11(TerminalIcon, { className: "size-3.5 shrink-0 text-og-fg-subtle", "aria-hidden": true }),
2007
+ /* @__PURE__ */ jsx12(TerminalIcon, { className: "size-3.5 shrink-0 text-og-fg-subtle", "aria-hidden": true }),
1718
2008
  installCommand
1719
2009
  ] }),
1720
- /* @__PURE__ */ jsx11(
2010
+ /* @__PURE__ */ jsx12(
1721
2011
  "button",
1722
2012
  {
1723
2013
  type: "button",
@@ -1725,15 +2015,15 @@ function EnrollmentDeviceFlow({
1725
2015
  onClick: onCopyInstall,
1726
2016
  title: "Copy command",
1727
2017
  className: "shrink-0 rounded-og-sm p-1.5 text-og-fg-subtle transition-colors hover:bg-og-surface-2 hover:text-og-fg",
1728
- children: /* @__PURE__ */ jsx11(CopyIcon, { className: "size-4", "aria-hidden": true })
2018
+ children: /* @__PURE__ */ jsx12(CopyIcon, { className: "size-4", "aria-hidden": true })
1729
2019
  }
1730
2020
  )
1731
2021
  ] })
1732
2022
  ] }) : null,
1733
2023
  /* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-1.5", children: [
1734
- /* @__PURE__ */ jsx11("span", { className: "text-[11px] font-medium uppercase tracking-wide text-og-fg-subtle", children: installCommand ? "2 \xB7 Approve the machine" : "Approve the machine" }),
2024
+ /* @__PURE__ */ jsx12("span", { className: "text-[11px] font-medium uppercase tracking-wide text-og-fg-subtle", children: installCommand ? "2 \xB7 Approve the machine" : "Approve the machine" }),
1735
2025
  /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between gap-3 rounded-og-md border border-og-border bg-og-bg px-3 py-2.5", children: [
1736
- awaitingCode ? /* @__PURE__ */ jsx11("span", { "data-user-code": true, className: "font-og-mono text-[13px] text-og-fg-subtle", children: "Run the command above \u2014 your code appears here" }) : /* @__PURE__ */ jsx11(
2026
+ awaitingCode ? /* @__PURE__ */ jsx12("span", { "data-user-code": true, className: "font-og-mono text-[13px] text-og-fg-subtle", children: "Run the command above \u2014 your code appears here" }) : /* @__PURE__ */ jsx12(
1737
2027
  "span",
1738
2028
  {
1739
2029
  "data-user-code": true,
@@ -1741,7 +2031,7 @@ function EnrollmentDeviceFlow({
1741
2031
  children: userCode
1742
2032
  }
1743
2033
  ),
1744
- /* @__PURE__ */ jsx11(
2034
+ /* @__PURE__ */ jsx12(
1745
2035
  "button",
1746
2036
  {
1747
2037
  type: "button",
@@ -1750,7 +2040,7 @@ function EnrollmentDeviceFlow({
1750
2040
  disabled: awaitingCode,
1751
2041
  title: "Copy code",
1752
2042
  className: "shrink-0 rounded-og-sm p-1.5 text-og-fg-subtle transition-colors hover:bg-og-surface-2 hover:text-og-fg disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:bg-transparent disabled:hover:text-og-fg-subtle",
1753
- children: /* @__PURE__ */ jsx11(CopyIcon, { className: "size-4", "aria-hidden": true })
2043
+ children: /* @__PURE__ */ jsx12(CopyIcon, { className: "size-4", "aria-hidden": true })
1754
2044
  }
1755
2045
  )
1756
2046
  ] })
@@ -1763,26 +2053,26 @@ function EnrollmentDeviceFlow({
1763
2053
  target: "_blank",
1764
2054
  rel: "noreferrer",
1765
2055
  onClick: onOpenVerification,
1766
- className: "inline-flex items-center justify-center gap-1.5 rounded-og-sm bg-og-accent px-3 py-2 text-og-menu font-medium text-og-accent-fg transition-colors hover:bg-og-accent-strong",
2056
+ className: "inline-flex items-center justify-center gap-1.5 rounded-og-sm border border-og-primary-border bg-og-primary text-og-primary-fg px-3 py-2 text-og-menu font-medium transition-colors hover:bg-og-primary-hover",
1767
2057
  children: [
1768
2058
  "Open approval page",
1769
- /* @__PURE__ */ jsx11(ExternalLinkIcon, { className: "size-3.5", "aria-hidden": true })
2059
+ /* @__PURE__ */ jsx12(ExternalLinkIcon, { className: "size-3.5", "aria-hidden": true })
1770
2060
  ]
1771
2061
  }
1772
2062
  ),
1773
- /* @__PURE__ */ jsx11("p", { className: "text-center text-[11px] text-og-fg-subtle", children: awaitingCode ? /* @__PURE__ */ jsxs11(Fragment2, { children: [
2063
+ /* @__PURE__ */ jsx12("p", { className: "text-center text-[11px] text-og-fg-subtle", children: awaitingCode ? /* @__PURE__ */ jsxs11(Fragment3, { children: [
1774
2064
  "The one-liner prints a short code. Open",
1775
2065
  " ",
1776
- /* @__PURE__ */ jsx11("span", { className: "font-og-mono text-og-fg-muted", children: verificationUri }),
2066
+ /* @__PURE__ */ jsx12("span", { className: "font-og-mono text-og-fg-muted", children: verificationUri }),
1777
2067
  " and confirm the code shown there matches."
1778
- ] }) : /* @__PURE__ */ jsxs11(Fragment2, { children: [
2068
+ ] }) : /* @__PURE__ */ jsxs11(Fragment3, { children: [
1779
2069
  "Confirm code ",
1780
- /* @__PURE__ */ jsx11("span", { className: "font-og-mono text-og-fg-muted", children: userCode }),
2070
+ /* @__PURE__ */ jsx12("span", { className: "font-og-mono text-og-fg-muted", children: userCode }),
1781
2071
  " \u2014 the one printed by the one-liner \u2014 at",
1782
2072
  " ",
1783
- /* @__PURE__ */ jsx11("span", { className: "font-og-mono text-og-fg-muted", children: verificationUri }),
2073
+ /* @__PURE__ */ jsx12("span", { className: "font-og-mono text-og-fg-muted", children: verificationUri }),
1784
2074
  ".",
1785
- typeof expiresInSeconds === "number" ? /* @__PURE__ */ jsxs11(Fragment2, { children: [
2075
+ typeof expiresInSeconds === "number" ? /* @__PURE__ */ jsxs11(Fragment3, { children: [
1786
2076
  " Expires in ",
1787
2077
  Math.max(0, Math.round(expiresInSeconds / 60)),
1788
2078
  " min."
@@ -1796,21 +2086,21 @@ function EnrollmentDeviceFlow({
1796
2086
  // src/components/enrollment-consent.tsx
1797
2087
  import { useState as useState3 } from "react";
1798
2088
  import {
1799
- CircleAlertIcon,
2089
+ CircleAlertIcon as CircleAlertIcon2,
1800
2090
  LaptopIcon as LaptopIcon6,
1801
2091
  MonitorIcon as MonitorIcon2,
1802
2092
  ScreenShareIcon,
1803
2093
  ShieldAlertIcon,
1804
2094
  TerminalIcon as TerminalIcon2,
1805
- UsersIcon as UsersIcon3
2095
+ UsersIcon as UsersIcon4
1806
2096
  } from "lucide-react";
1807
- import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
2097
+ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
1808
2098
  function Capability({ icon, title, body }) {
1809
2099
  return /* @__PURE__ */ jsxs12("li", { className: "flex items-start gap-2.5", children: [
1810
- /* @__PURE__ */ jsx12("span", { className: "mt-0.5 shrink-0 text-og-status-failed", children: icon }),
2100
+ /* @__PURE__ */ jsx13("span", { className: "mt-0.5 shrink-0 text-og-status-failed", children: icon }),
1811
2101
  /* @__PURE__ */ jsxs12("span", { className: "min-w-0", children: [
1812
- /* @__PURE__ */ jsx12("span", { className: "block text-og-base font-medium text-og-fg", children: title }),
1813
- /* @__PURE__ */ jsx12("span", { className: "block text-og-sm text-og-fg-muted", children: body })
2102
+ /* @__PURE__ */ jsx13("span", { className: "block text-og-base font-medium text-og-fg", children: title }),
2103
+ /* @__PURE__ */ jsx13("span", { className: "block text-og-sm text-og-fg-muted", children: body })
1814
2104
  ] })
1815
2105
  ] });
1816
2106
  }
@@ -1842,7 +2132,7 @@ function EnrollmentConsent({
1842
2132
  }
1843
2133
  };
1844
2134
  if (phase === "approved") {
1845
- return /* @__PURE__ */ jsx12(
2135
+ return /* @__PURE__ */ jsx13(
1846
2136
  ConsentResult,
1847
2137
  {
1848
2138
  className,
@@ -1853,7 +2143,7 @@ function EnrollmentConsent({
1853
2143
  );
1854
2144
  }
1855
2145
  if (phase === "denied") {
1856
- return /* @__PURE__ */ jsx12(
2146
+ return /* @__PURE__ */ jsx13(
1857
2147
  ConsentResult,
1858
2148
  {
1859
2149
  className,
@@ -1864,7 +2154,7 @@ function EnrollmentConsent({
1864
2154
  );
1865
2155
  }
1866
2156
  if (phase === "error") {
1867
- return /* @__PURE__ */ jsx12(
2157
+ return /* @__PURE__ */ jsx13(
1868
2158
  ConsentResult,
1869
2159
  {
1870
2160
  className,
@@ -1884,59 +2174,59 @@ function EnrollmentConsent({
1884
2174
  ),
1885
2175
  children: [
1886
2176
  /* @__PURE__ */ jsxs12("div", { className: "flex items-start gap-3", children: [
1887
- /* @__PURE__ */ jsx12("span", { className: "flex size-9 shrink-0 items-center justify-center rounded-full bg-og-status-failed/15 text-og-status-failed", children: /* @__PURE__ */ jsx12(ShieldAlertIcon, { className: "size-5", "aria-hidden": true }) }),
2177
+ /* @__PURE__ */ jsx13("span", { className: "flex size-9 shrink-0 items-center justify-center rounded-full bg-og-status-failed/15 text-og-status-failed", children: /* @__PURE__ */ jsx13(ShieldAlertIcon, { className: "size-5", "aria-hidden": true }) }),
1888
2178
  /* @__PURE__ */ jsxs12("div", { className: "min-w-0", children: [
1889
- /* @__PURE__ */ jsx12("h1", { className: "text-og-md font-semibold text-og-fg", children: "Give the agent your whole machine?" }),
2179
+ /* @__PURE__ */ jsx13("h1", { className: "text-og-md font-semibold text-og-fg", children: "Give the agent your whole machine?" }),
1890
2180
  /* @__PURE__ */ jsxs12("p", { className: "mt-1 text-og-base text-og-fg-muted", children: [
1891
- "Approving lets the OpenGeni agent run on",
2181
+ "Approving lets the Opengeni agent run on",
1892
2182
  " ",
1893
- /* @__PURE__ */ jsx12("span", { className: "font-medium text-og-fg", children: machine.machineName }),
2183
+ /* @__PURE__ */ jsx13("span", { className: "font-medium text-og-fg", children: machine.machineName }),
1894
2184
  " with full access. This is your real computer \u2014 not a sandbox."
1895
2185
  ] })
1896
2186
  ] })
1897
2187
  ] }),
1898
2188
  /* @__PURE__ */ jsxs12("div", { className: "flex flex-wrap items-center gap-2 rounded-og-md border border-og-border bg-og-surface-2 px-3 py-2 text-og-sm", children: [
1899
- /* @__PURE__ */ jsx12(LaptopIcon6, { className: "size-4 text-og-fg-subtle", "aria-hidden": true }),
1900
- /* @__PURE__ */ jsx12("span", { className: "font-medium text-og-fg", children: machine.machineName }),
2189
+ /* @__PURE__ */ jsx13(LaptopIcon6, { className: "size-4 text-og-fg-subtle", "aria-hidden": true }),
2190
+ /* @__PURE__ */ jsx13("span", { className: "font-medium text-og-fg", children: machine.machineName }),
1901
2191
  /* @__PURE__ */ jsxs12("span", { className: "font-og-mono text-og-fg-subtle", children: [
1902
2192
  machine.os,
1903
2193
  "/",
1904
2194
  machine.arch
1905
2195
  ] }),
1906
- /* @__PURE__ */ jsx12("span", { "aria-hidden": true, className: "text-og-fg-subtle", children: "\xB7" }),
2196
+ /* @__PURE__ */ jsx13("span", { "aria-hidden": true, className: "text-og-fg-subtle", children: "\xB7" }),
1907
2197
  /* @__PURE__ */ jsxs12("span", { className: "text-og-fg-subtle", children: [
1908
2198
  "code ",
1909
- /* @__PURE__ */ jsx12("span", { className: "font-og-mono font-medium text-og-fg", children: userCode })
2199
+ /* @__PURE__ */ jsx13("span", { className: "font-og-mono font-medium text-og-fg", children: userCode })
1910
2200
  ] })
1911
2201
  ] }),
1912
2202
  /* @__PURE__ */ jsxs12("ul", { className: "flex flex-col gap-3", children: [
1913
- /* @__PURE__ */ jsx12(
2203
+ /* @__PURE__ */ jsx13(
1914
2204
  Capability,
1915
2205
  {
1916
- icon: /* @__PURE__ */ jsx12(TerminalIcon2, { className: "size-4", "aria-hidden": true }),
2206
+ icon: /* @__PURE__ */ jsx13(TerminalIcon2, { className: "size-4", "aria-hidden": true }),
1917
2207
  title: "Read, write & run anything",
1918
2208
  body: "The agent can read and modify any file, run any command, and use your git credentials \u2014 as if it were you at the keyboard."
1919
2209
  }
1920
2210
  ),
1921
- machine.canOfferDisplay ? /* @__PURE__ */ jsx12(
2211
+ machine.canOfferDisplay ? /* @__PURE__ */ jsx13(
1922
2212
  Capability,
1923
2213
  {
1924
- icon: /* @__PURE__ */ jsx12(MonitorIcon2, { className: "size-4", "aria-hidden": true }),
2214
+ icon: /* @__PURE__ */ jsx13(MonitorIcon2, { className: "size-4", "aria-hidden": true }),
1925
2215
  title: "See your screen",
1926
2216
  body: "The agent can capture this machine's display to watch what it is doing."
1927
2217
  }
1928
2218
  ) : null,
1929
- /* @__PURE__ */ jsx12(
2219
+ /* @__PURE__ */ jsx13(
1930
2220
  Capability,
1931
2221
  {
1932
- icon: /* @__PURE__ */ jsx12(UsersIcon3, { className: "size-4", "aria-hidden": true }),
2222
+ icon: /* @__PURE__ */ jsx13(UsersIcon4, { className: "size-4", "aria-hidden": true }),
1933
2223
  title: `${scopeCopy[scope].label} access while connected`,
1934
2224
  body: `${scopeCopy[scope].body} Disconnect the agent to revoke access instantly.`
1935
2225
  }
1936
2226
  )
1937
2227
  ] }),
1938
2228
  /* @__PURE__ */ jsxs12("fieldset", { className: "flex flex-col gap-2", disabled: busy, children: [
1939
- /* @__PURE__ */ jsx12("legend", { className: "mb-1 text-og-sm font-medium text-og-fg", children: "Who can use this machine?" }),
2229
+ /* @__PURE__ */ jsx13("legend", { className: "mb-1 text-og-sm font-medium text-og-fg", children: "Who can use this machine?" }),
1940
2230
  ["user", "workspace", "organization"].map((candidate) => {
1941
2231
  const disabled = candidate === "organization" && !allowOrganizationScope;
1942
2232
  return /* @__PURE__ */ jsxs12(
@@ -1949,7 +2239,7 @@ function EnrollmentConsent({
1949
2239
  disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer"
1950
2240
  ),
1951
2241
  children: [
1952
- /* @__PURE__ */ jsx12(
2242
+ /* @__PURE__ */ jsx13(
1953
2243
  "input",
1954
2244
  {
1955
2245
  type: "radio",
@@ -1966,7 +2256,7 @@ function EnrollmentConsent({
1966
2256
  scopeCopy[candidate].label,
1967
2257
  disabled ? " \xB7 organization admin required" : ""
1968
2258
  ] }),
1969
- /* @__PURE__ */ jsx12("span", { className: "block text-og-sm text-og-fg-muted", children: scopeCopy[candidate].body })
2259
+ /* @__PURE__ */ jsx13("span", { className: "block text-og-sm text-og-fg-muted", children: scopeCopy[candidate].body })
1970
2260
  ] })
1971
2261
  ]
1972
2262
  },
@@ -1980,7 +2270,7 @@ function EnrollmentConsent({
1980
2270
  "data-screen-control-toggle": true,
1981
2271
  className: "flex cursor-pointer items-start gap-3 rounded-og-md border border-og-border bg-og-bg px-3 py-2.5",
1982
2272
  children: [
1983
- /* @__PURE__ */ jsx12(
2273
+ /* @__PURE__ */ jsx13(
1984
2274
  "input",
1985
2275
  {
1986
2276
  type: "checkbox",
@@ -1992,19 +2282,19 @@ function EnrollmentConsent({
1992
2282
  ),
1993
2283
  /* @__PURE__ */ jsxs12("span", { className: "min-w-0", children: [
1994
2284
  /* @__PURE__ */ jsxs12("span", { className: "flex items-center gap-1.5 text-og-base font-medium text-og-fg", children: [
1995
- /* @__PURE__ */ jsx12(ScreenShareIcon, { className: "size-3.5 text-og-fg-muted", "aria-hidden": true }),
2285
+ /* @__PURE__ */ jsx13(ScreenShareIcon, { className: "size-3.5 text-og-fg-muted", "aria-hidden": true }),
1996
2286
  "Also let the agent control my mouse & keyboard"
1997
2287
  ] }),
1998
- /* @__PURE__ */ jsx12("span", { className: "mt-0.5 block text-og-sm text-og-fg-muted", children: "Optional. Enables computer-use \u2014 the agent can move the pointer, type, and click on this machine's desktop. Leave off to let it only watch." })
2288
+ /* @__PURE__ */ jsx13("span", { className: "mt-0.5 block text-og-sm text-og-fg-muted", children: "Optional. Enables computer-use \u2014 the agent can move the pointer, type, and click on this machine's desktop. Leave off to let it only watch." })
1999
2289
  ] })
2000
2290
  ]
2001
2291
  }
2002
2292
  ) : /* @__PURE__ */ jsxs12("p", { className: "flex items-start gap-2 rounded-og-md border border-og-border bg-og-bg px-3 py-2 text-og-sm text-og-fg-muted", children: [
2003
- /* @__PURE__ */ jsx12(CircleAlertIcon, { className: "mt-px size-3.5 shrink-0 text-og-fg-subtle", "aria-hidden": true }),
2293
+ /* @__PURE__ */ jsx13(CircleAlertIcon2, { className: "mt-px size-3.5 shrink-0 text-og-fg-subtle", "aria-hidden": true }),
2004
2294
  "This machine has no display, so screen control isn't available \u2014 files, terminal, and git only."
2005
2295
  ] }),
2006
2296
  /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2", children: [
2007
- /* @__PURE__ */ jsx12(
2297
+ /* @__PURE__ */ jsx13(
2008
2298
  "button",
2009
2299
  {
2010
2300
  type: "button",
@@ -2015,7 +2305,7 @@ function EnrollmentConsent({
2015
2305
  children: "Cancel"
2016
2306
  }
2017
2307
  ),
2018
- /* @__PURE__ */ jsx12(
2308
+ /* @__PURE__ */ jsx13(
2019
2309
  "button",
2020
2310
  {
2021
2311
  type: "button",
@@ -2049,354 +2339,39 @@ function ConsentResult({
2049
2339
  className
2050
2340
  ),
2051
2341
  children: [
2052
- /* @__PURE__ */ jsx12(
2342
+ /* @__PURE__ */ jsx13(
2053
2343
  "span",
2054
2344
  {
2055
2345
  className: cn(
2056
2346
  "flex size-10 items-center justify-center rounded-full bg-og-surface-2",
2057
2347
  iconClass
2058
2348
  ),
2059
- children: /* @__PURE__ */ jsx12(LaptopIcon6, { className: "size-5", "aria-hidden": true })
2349
+ children: /* @__PURE__ */ jsx13(LaptopIcon6, { className: "size-5", "aria-hidden": true })
2060
2350
  }
2061
2351
  ),
2062
- /* @__PURE__ */ jsx12("h1", { className: "text-og-md font-semibold text-og-fg", children: title }),
2063
- /* @__PURE__ */ jsx12("p", { className: "max-w-sm text-og-base text-og-fg-muted", children: body })
2352
+ /* @__PURE__ */ jsx13("h1", { className: "text-og-md font-semibold text-og-fg", children: title }),
2353
+ /* @__PURE__ */ jsx13("p", { className: "max-w-sm text-og-base text-og-fg-muted", children: body })
2064
2354
  ]
2065
2355
  }
2066
2356
  );
2067
2357
  }
2068
2358
 
2069
2359
  // src/hooks/use-machines.ts
2070
- import { useCallback as useCallback3, useRef as useRef3, useState as useState6 } from "react";
2071
-
2072
- // src/provider.tsx
2073
- import {
2074
- OpenGeniApiContractMismatchError,
2075
- OPENGENI_API_CONTRACT_REVISION
2076
- } from "@opengeni/sdk";
2077
- import { useCallback, useEffect as useEffect2, useMemo, useRef as useRef2, useState as useState4 } from "react";
2078
- import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
2079
- var CONTRACT_RELOAD_STORAGE_PREFIX = "opengeni.reloadForApiContract:";
2080
- function OpenGeniProvider({
2081
- client,
2082
- workspaceId,
2083
- onWorkspaceControlEvent,
2084
- onWorkspaceInteractionEvent,
2085
- children
2086
- }) {
2087
- const [workspaceControlEvent, setWorkspaceControlEvent] = useState4(
2088
- null
2089
- );
2090
- const [workspaceControlConnectionState, setWorkspaceControlConnectionState] = useState4("idle");
2091
- const [workspaceInteractionEvent, setWorkspaceInteractionEvent] = useState4(null);
2092
- const [workspaceInteractionConnectionState, setWorkspaceInteractionConnectionState] = useState4("idle");
2093
- const [contractMismatch, setContractMismatch] = useState4(
2094
- null
2095
- );
2096
- const callbackRef = useRef2(onWorkspaceControlEvent);
2097
- const interactionCallbackRef = useRef2(onWorkspaceInteractionEvent);
2098
- const reconcilersRef = useRef2(/* @__PURE__ */ new Map());
2099
- const reconcileInFlightRef = useRef2(/* @__PURE__ */ new Map());
2100
- const workspaceControlSequencesRef = useRef2(/* @__PURE__ */ new Map());
2101
- const workspaceInteractionSequencesRef = useRef2(/* @__PURE__ */ new Map());
2102
- const pageLive = usePageLiveActivity();
2103
- const supportsWorkspaceLiveStream = "streamWorkspaceLiveEvents" in client && typeof client.streamWorkspaceLiveEvents === "function";
2104
- callbackRef.current = onWorkspaceControlEvent;
2105
- interactionCallbackRef.current = onWorkspaceInteractionEvent;
2106
- const verifyApiContract = useCallback(async () => {
2107
- try {
2108
- const config = await client.getClientConfig();
2109
- if (config.apiContractRevision !== OPENGENI_API_CONTRACT_REVISION) {
2110
- throw new OpenGeniApiContractMismatchError(
2111
- OPENGENI_API_CONTRACT_REVISION,
2112
- String(config.apiContractRevision || "(missing)")
2113
- );
2114
- }
2115
- } catch (error) {
2116
- if (error instanceof OpenGeniApiContractMismatchError) {
2117
- setContractMismatch(error);
2118
- reloadForContractMismatchOnce(error);
2119
- }
2120
- throw error;
2121
- }
2122
- }, [client]);
2123
- const registerSessionReconciler = useMemo(
2124
- () => (sessionId, key, reconcile2) => {
2125
- const sessionReconcilers = reconcilersRef.current.get(sessionId) ?? /* @__PURE__ */ new Map();
2126
- sessionReconcilers.set(key, reconcile2);
2127
- reconcilersRef.current.set(sessionId, sessionReconcilers);
2128
- return () => {
2129
- const current = reconcilersRef.current.get(sessionId);
2130
- current?.delete(key);
2131
- if (current?.size === 0) reconcilersRef.current.delete(sessionId);
2132
- };
2133
- },
2134
- []
2135
- );
2136
- const reconcileSession = useMemo(
2137
- () => (sessionId) => {
2138
- const existing = reconcileInFlightRef.current.get(sessionId);
2139
- if (existing) return existing;
2140
- const promise = (async () => {
2141
- await withTimeout(verifyApiContract(), 1e4, "API contract reconciliation");
2142
- const callbacks = [...reconcilersRef.current.get(sessionId)?.values() ?? []];
2143
- await withTimeout(
2144
- Promise.all(callbacks.map((reconcile2) => reconcile2())).then(() => void 0),
2145
- 15e3,
2146
- "session reconciliation"
2147
- );
2148
- })().finally(() => {
2149
- if (reconcileInFlightRef.current.get(sessionId) === promise) {
2150
- reconcileInFlightRef.current.delete(sessionId);
2151
- }
2152
- });
2153
- reconcileInFlightRef.current.set(sessionId, promise);
2154
- return promise;
2155
- },
2156
- [verifyApiContract]
2157
- );
2158
- useEffect2(() => {
2159
- if (!supportsWorkspaceLiveStream) return;
2160
- const openLiveStream = client.streamWorkspaceLiveEvents;
2161
- setWorkspaceControlEvent(null);
2162
- setWorkspaceInteractionEvent(null);
2163
- if (!pageLive) {
2164
- setWorkspaceControlConnectionState("idle");
2165
- setWorkspaceInteractionConnectionState("idle");
2166
- return;
2167
- }
2168
- const controller = new AbortController();
2169
- const setConnectionState = (state) => {
2170
- setWorkspaceControlConnectionState(state);
2171
- setWorkspaceInteractionConnectionState(state);
2172
- };
2173
- setConnectionState("connecting");
2174
- void (async () => {
2175
- try {
2176
- await verifyApiContract();
2177
- const workspace = await client.getWorkspace(workspaceId);
2178
- const controlAfter = Math.max(
2179
- workspaceControlSequencesRef.current.get(workspaceId) ?? 0,
2180
- workspace.inferenceControl.revision
2181
- );
2182
- const interactionAfter = workspaceInteractionSequencesRef.current.get(workspaceId) ?? 0;
2183
- workspaceControlSequencesRef.current.set(workspaceId, controlAfter);
2184
- const stream = openLiveStream.call(client, workspaceId, {
2185
- controlAfter,
2186
- interactionAfter,
2187
- signal: controller.signal,
2188
- onStateChange: setConnectionState
2189
- });
2190
- for await (const event of stream) {
2191
- if (controller.signal.aborted) return;
2192
- if (event.type === "workspace.control.changed") {
2193
- workspaceControlSequencesRef.current.set(
2194
- workspaceId,
2195
- Math.max(workspaceControlSequencesRef.current.get(workspaceId) ?? 0, event.sequence)
2196
- );
2197
- setWorkspaceControlEvent(
2198
- (current) => !current || event.sequence > current.sequence ? event : current
2199
- );
2200
- callbackRef.current?.(event);
2201
- } else {
2202
- workspaceInteractionSequencesRef.current.set(
2203
- workspaceId,
2204
- Math.max(
2205
- workspaceInteractionSequencesRef.current.get(workspaceId) ?? 0,
2206
- event.sequence
2207
- )
2208
- );
2209
- setWorkspaceInteractionEvent(
2210
- (current) => !current || event.sequence > current.sequence ? event : current
2211
- );
2212
- interactionCallbackRef.current?.(event);
2213
- }
2214
- }
2215
- } catch (error) {
2216
- if (error instanceof OpenGeniApiContractMismatchError) {
2217
- setContractMismatch(error);
2218
- reloadForContractMismatchOnce(error);
2219
- }
2220
- if (!controller.signal.aborted) {
2221
- setWorkspaceControlConnectionState("error");
2222
- setWorkspaceInteractionConnectionState("error");
2223
- }
2224
- }
2225
- })();
2226
- return () => controller.abort();
2227
- }, [client, pageLive, supportsWorkspaceLiveStream, verifyApiContract, workspaceId]);
2228
- useEffect2(() => {
2229
- if (supportsWorkspaceLiveStream) return;
2230
- if (!pageLive) {
2231
- setWorkspaceControlConnectionState("idle");
2232
- return;
2233
- }
2234
- const controller = new AbortController();
2235
- setWorkspaceControlConnectionState("connecting");
2236
- void (async () => {
2237
- try {
2238
- await verifyApiContract();
2239
- const workspace = await client.getWorkspace(workspaceId);
2240
- const resumeAfter = Math.max(
2241
- workspaceControlSequencesRef.current.get(workspaceId) ?? 0,
2242
- workspace.inferenceControl.revision
2243
- );
2244
- workspaceControlSequencesRef.current.set(workspaceId, resumeAfter);
2245
- const stream = client.streamWorkspaceControlEvents(workspaceId, {
2246
- after: resumeAfter,
2247
- signal: controller.signal,
2248
- onStateChange: setWorkspaceControlConnectionState
2249
- });
2250
- for await (const event of stream) {
2251
- if (controller.signal.aborted) return;
2252
- workspaceControlSequencesRef.current.set(
2253
- workspaceId,
2254
- Math.max(workspaceControlSequencesRef.current.get(workspaceId) ?? 0, event.sequence)
2255
- );
2256
- setWorkspaceControlEvent(
2257
- (current) => !current || event.sequence > current.sequence ? event : current
2258
- );
2259
- callbackRef.current?.(event);
2260
- }
2261
- } catch (error) {
2262
- if (error instanceof OpenGeniApiContractMismatchError) {
2263
- setContractMismatch(error);
2264
- reloadForContractMismatchOnce(error);
2265
- }
2266
- if (!controller.signal.aborted) setWorkspaceControlConnectionState("error");
2267
- }
2268
- })();
2269
- return () => controller.abort();
2270
- }, [client, pageLive, supportsWorkspaceLiveStream, verifyApiContract, workspaceId]);
2271
- useEffect2(() => {
2272
- if (supportsWorkspaceLiveStream) return;
2273
- setWorkspaceInteractionEvent(null);
2274
- if (!pageLive) {
2275
- setWorkspaceInteractionConnectionState("idle");
2276
- return;
2277
- }
2278
- const controller = new AbortController();
2279
- setWorkspaceInteractionConnectionState("connecting");
2280
- void (async () => {
2281
- try {
2282
- await verifyApiContract();
2283
- const resumeAfter = workspaceInteractionSequencesRef.current.get(workspaceId) ?? 0;
2284
- const stream = client.streamWorkspaceInteractionRevisions(workspaceId, {
2285
- after: resumeAfter,
2286
- signal: controller.signal,
2287
- onStateChange: setWorkspaceInteractionConnectionState
2288
- });
2289
- for await (const event of stream) {
2290
- if (controller.signal.aborted) return;
2291
- workspaceInteractionSequencesRef.current.set(
2292
- workspaceId,
2293
- Math.max(
2294
- workspaceInteractionSequencesRef.current.get(workspaceId) ?? 0,
2295
- event.sequence
2296
- )
2297
- );
2298
- setWorkspaceInteractionEvent(
2299
- (current) => !current || event.sequence > current.sequence ? event : current
2300
- );
2301
- interactionCallbackRef.current?.(event);
2302
- }
2303
- } catch (error) {
2304
- if (error instanceof OpenGeniApiContractMismatchError) {
2305
- setContractMismatch(error);
2306
- reloadForContractMismatchOnce(error);
2307
- }
2308
- if (!controller.signal.aborted) setWorkspaceInteractionConnectionState("error");
2309
- }
2310
- })();
2311
- return () => controller.abort();
2312
- }, [client, pageLive, supportsWorkspaceLiveStream, verifyApiContract, workspaceId]);
2313
- const value = useMemo(
2314
- () => ({
2315
- client,
2316
- workspaceId,
2317
- workspaceControlEvent,
2318
- workspaceControlConnectionState,
2319
- workspaceInteractionEvent,
2320
- workspaceInteractionConnectionState,
2321
- registerSessionReconciler,
2322
- reconcileSession
2323
- }),
2324
- [
2325
- client,
2326
- workspaceId,
2327
- workspaceControlEvent,
2328
- workspaceControlConnectionState,
2329
- workspaceInteractionEvent,
2330
- workspaceInteractionConnectionState,
2331
- registerSessionReconciler,
2332
- reconcileSession
2333
- ]
2334
- );
2335
- return /* @__PURE__ */ jsxs13(OpenGeniContext.Provider, { value, children: [
2336
- children,
2337
- contractMismatch ? /* @__PURE__ */ jsx13(ApiContractMismatchScreen, { mismatch: contractMismatch }) : null
2338
- ] });
2339
- }
2340
- function withTimeout(promise, timeoutMs, label) {
2341
- let timer;
2342
- return Promise.race([
2343
- promise,
2344
- new Promise((_resolve, reject) => {
2345
- timer = setTimeout(
2346
- () => reject(new Error(`${label} timed out after ${timeoutMs}ms`)),
2347
- timeoutMs
2348
- );
2349
- })
2350
- ]).finally(() => {
2351
- if (timer !== void 0) clearTimeout(timer);
2352
- });
2353
- }
2354
- function ApiContractMismatchScreen({ mismatch }) {
2355
- return /* @__PURE__ */ jsx13(
2356
- "div",
2357
- {
2358
- className: "og-root fixed inset-0 z-[2147483647] grid place-items-center bg-og-bg/95 p-6 backdrop-blur-sm",
2359
- role: "alert",
2360
- "aria-live": "assertive",
2361
- "data-opengeni-api-contract-mismatch": true,
2362
- children: /* @__PURE__ */ jsxs13("div", { className: "w-full max-w-md rounded-xl border border-og-border bg-og-surface p-6 shadow-2xl", children: [
2363
- /* @__PURE__ */ jsx13("p", { className: "text-og-menu font-semibold text-og-fg", children: "OpenGeni updated" }),
2364
- /* @__PURE__ */ jsx13("p", { className: "mt-2 text-og-menu leading-6 text-og-muted", children: "This tab cannot safely continue with the new server version. Reload it before sending or controlling work." }),
2365
- /* @__PURE__ */ jsxs13("p", { className: "mt-3 font-mono text-og-control text-og-subtle", children: [
2366
- "Client ",
2367
- mismatch.expected,
2368
- " \xB7 API ",
2369
- mismatch.actual
2370
- ] }),
2371
- /* @__PURE__ */ jsx13(
2372
- "button",
2373
- {
2374
- type: "button",
2375
- className: "mt-5 inline-flex h-9 items-center rounded-md bg-og-fg px-3 text-og-menu font-medium text-og-bg",
2376
- onClick: () => window.location.reload(),
2377
- children: "Reload now"
2378
- }
2379
- )
2380
- ] })
2381
- }
2382
- );
2383
- }
2384
- function reloadForContractMismatchOnce(mismatch) {
2385
- if (typeof window === "undefined" || typeof sessionStorage === "undefined") return;
2386
- const key = `${CONTRACT_RELOAD_STORAGE_PREFIX}${mismatch.actual}`;
2387
- if (sessionStorage.getItem(key) === OPENGENI_API_CONTRACT_REVISION) return;
2388
- sessionStorage.setItem(key, OPENGENI_API_CONTRACT_REVISION);
2389
- window.setTimeout(() => window.location.reload(), 150);
2390
- }
2360
+ import { useCallback as useCallback2, useRef as useRef2, useState as useState5 } from "react";
2391
2361
 
2392
2362
  // src/hooks/shared-machines-list.ts
2393
- import { useCallback as useCallback2, useEffect as useEffect3, useState as useState5 } from "react";
2363
+ import { useCallback, useEffect as useEffect2, useState as useState4 } from "react";
2394
2364
  var EMPTY_MACHINES = {
2395
2365
  activeSandboxId: null,
2396
2366
  activeEpoch: 0,
2397
2367
  machines: []
2398
2368
  };
2399
2369
  var shares = /* @__PURE__ */ new Map();
2370
+ function isMachinesAccessRefusal(cause) {
2371
+ if (!cause || typeof cause !== "object" || !("status" in cause)) return false;
2372
+ const status = cause.status;
2373
+ return status === 401 || status === 403 || status === 404;
2374
+ }
2400
2375
  function emit(share) {
2401
2376
  for (const subscriber of share.subscribers) {
2402
2377
  subscriber.onChange();
@@ -2435,6 +2410,7 @@ function cancelDispose(share) {
2435
2410
  }
2436
2411
  function arm(share) {
2437
2412
  stopTimer(share);
2413
+ if (share.halted) return;
2438
2414
  const { enabled, pollIntervalMs } = effective(share);
2439
2415
  if (!enabled || pollIntervalMs === void 0) return;
2440
2416
  share.timer = setTimeout(() => {
@@ -2451,10 +2427,15 @@ async function runFresh(share) {
2451
2427
  try {
2452
2428
  const data = await load(abort.signal);
2453
2429
  if (ticket !== share.generation || abort.signal.aborted) return;
2430
+ share.halted = false;
2454
2431
  share.snapshot = { data, loading: false, error: null };
2455
2432
  emit(share);
2456
2433
  } catch (cause) {
2457
2434
  if (ticket !== share.generation || abort.signal.aborted) return;
2435
+ if (isMachinesAccessRefusal(cause)) {
2436
+ share.halted = true;
2437
+ stopTimer(share);
2438
+ }
2458
2439
  share.snapshot = {
2459
2440
  data: share.snapshot.data,
2460
2441
  loading: false,
@@ -2471,7 +2452,7 @@ function run(share, force = false) {
2471
2452
  if (share.trailing) return share.trailing;
2472
2453
  let trailing;
2473
2454
  trailing = share.inFlight.then(async () => {
2474
- if (!effective(share).enabled) return;
2455
+ if (!effective(share).enabled || share.halted) return;
2475
2456
  await run(share);
2476
2457
  }).finally(() => {
2477
2458
  if (share.trailing === trailing) share.trailing = null;
@@ -2494,12 +2475,19 @@ function reconcile(share) {
2494
2475
  share.abort = null;
2495
2476
  share.inFlight = null;
2496
2477
  stopTimer(share);
2478
+ if (share.halted) {
2479
+ share.halted = false;
2480
+ share.snapshot = { data: share.snapshot.data, loading: false, error: null };
2481
+ emit(share);
2482
+ return;
2483
+ }
2497
2484
  if (share.snapshot.loading) {
2498
2485
  share.snapshot = { ...share.snapshot, loading: false };
2499
2486
  emit(share);
2500
2487
  }
2501
2488
  return;
2502
2489
  }
2490
+ if (share.halted) return;
2503
2491
  if (share.snapshot.data !== null || share.snapshot.error) {
2504
2492
  arm(share);
2505
2493
  return;
@@ -2522,7 +2510,8 @@ function getOrCreate(shareKey) {
2522
2510
  abort: null,
2523
2511
  inFlight: null,
2524
2512
  trailing: null,
2525
- generation: 0
2513
+ generation: 0,
2514
+ halted: false
2526
2515
  };
2527
2516
  shares.set(shareKey, created);
2528
2517
  return created;
@@ -2530,15 +2519,18 @@ function getOrCreate(shareKey) {
2530
2519
  async function refreshSharedMachinesList(shareKey) {
2531
2520
  const share = shares.get(shareKey);
2532
2521
  if (!share) return;
2522
+ const wasHalted = share.halted;
2523
+ share.halted = false;
2533
2524
  await run(share, true);
2525
+ if (wasHalted) arm(share);
2534
2526
  }
2535
2527
  function useSharedMachinesList(shareKey, load, options = {}) {
2536
2528
  const enabled = options.enabled ?? true;
2537
2529
  const pageLive = usePageLiveActivity();
2538
- const [, setRevision] = useState5(0);
2530
+ const [, setRevision] = useState4(0);
2539
2531
  const live = shares.get(shareKey)?.snapshot;
2540
2532
  const view = live ?? { data: null, loading: enabled && pageLive, error: null };
2541
- useEffect3(() => {
2533
+ useEffect2(() => {
2542
2534
  const share = getOrCreate(shareKey);
2543
2535
  const subscriber = {
2544
2536
  load,
@@ -2571,7 +2563,7 @@ function useSharedMachinesList(shareKey, load, options = {}) {
2571
2563
  }, 0);
2572
2564
  };
2573
2565
  }, [shareKey, load, options.pollIntervalMs, enabled, pageLive]);
2574
- const refresh = useCallback2(() => refreshSharedMachinesList(shareKey), [shareKey]);
2566
+ const refresh = useCallback(() => refreshSharedMachinesList(shareKey), [shareKey]);
2575
2567
  return { ...view, refresh };
2576
2568
  }
2577
2569
 
@@ -2601,6 +2593,10 @@ function swapFailureMessage(result) {
2601
2593
  return "The selected machine is offline.";
2602
2594
  case "concurrent_swap":
2603
2595
  return "The session route changed concurrently. Refresh and try again.";
2596
+ case "personal_machine_permission_required":
2597
+ return "The machine's owner has not allowed this chat to use it.";
2598
+ case "personal_machine_not_permitted":
2599
+ return "Only the machine's owner can use it in this chat.";
2604
2600
  default:
2605
2601
  return "The session stayed on its current sandbox.";
2606
2602
  }
@@ -2610,9 +2606,9 @@ function useMachines(options = {}) {
2610
2606
  const machinesClient = options.machinesClient ?? client;
2611
2607
  const sessionId = options.sessionId;
2612
2608
  const identityKey = `${workspaceId}\0${sessionId ?? ""}\0${machinesClientId(machinesClient)}`;
2613
- const identityRef = useRef3(identityKey);
2609
+ const identityRef = useRef2(identityKey);
2614
2610
  identityRef.current = identityKey;
2615
- const load = useCallback3(
2611
+ const load = useCallback2(
2616
2612
  async (signal) => {
2617
2613
  return await machinesClient.listMachines(workspaceId, {
2618
2614
  ...sessionId ? { sessionId } : {},
@@ -2631,20 +2627,20 @@ function useMachines(options = {}) {
2631
2627
  enabled: options.enabled
2632
2628
  });
2633
2629
  const { run: run2, mutating, mutationError, clearMutationError } = useMutationRunner(identityKey);
2634
- const [attachState, setAttachState] = useState6(() => ({ identity: identityKey, sandboxId: null }));
2630
+ const [attachState, setAttachState] = useState5(() => ({ identity: identityKey, sandboxId: null }));
2635
2631
  const attachingSandboxId = attachState.identity === identityKey ? attachState.sandboxId : null;
2636
- const [removeState, setRemoveState] = useState6(() => ({ identity: identityKey, enrollmentId: null }));
2632
+ const [removeState, setRemoveState] = useState5(() => ({ identity: identityKey, enrollmentId: null }));
2637
2633
  const removingEnrollmentId = removeState.identity === identityKey ? removeState.enrollmentId : null;
2638
- const [updateState, setUpdateState] = useState6(() => ({ identity: identityKey, enrollmentId: null }));
2634
+ const [updateState, setUpdateState] = useState5(() => ({ identity: identityKey, enrollmentId: null }));
2639
2635
  const updatingEnrollmentId = updateState.identity === identityKey ? updateState.enrollmentId : null;
2640
- const [operationPolicyState, setOperationPolicyState] = useState6(() => ({ identity: identityKey, enrollmentId: null }));
2636
+ const [operationPolicyState, setOperationPolicyState] = useState5(() => ({ identity: identityKey, enrollmentId: null }));
2641
2637
  const updatingOperationPolicyEnrollmentId = operationPolicyState.identity === identityKey ? operationPolicyState.enrollmentId : null;
2642
2638
  const data = loadedData ?? EMPTY_MACHINES;
2643
2639
  const canAttach = sessionId !== void 0 && (typeof machinesClient.attachMachine === "function" || typeof machinesClient.swapActiveSandbox === "function");
2644
2640
  const canRemove = typeof machinesClient.removeEnrollment === "function";
2645
2641
  const canUpdateAgent = typeof machinesClient.updateMachineAgent === "function";
2646
2642
  const canUpdateOperationPolicy = typeof machinesClient.updateMachineOperationPolicy === "function";
2647
- const attach = useCallback3(
2643
+ const attach = useCallback2(
2648
2644
  async (sandboxId) => {
2649
2645
  if (sessionId === void 0) return false;
2650
2646
  const runSwap = machinesClient.attachMachine ? () => machinesClient.attachMachine(workspaceId, sessionId, sandboxId) : machinesClient.swapActiveSandbox ? () => machinesClient.swapActiveSandbox(workspaceId, sessionId, { target: sandboxId }) : null;
@@ -2666,14 +2662,14 @@ function useMachines(options = {}) {
2666
2662
  },
2667
2663
  [machinesClient, workspaceId, sessionId, identityKey, run2, refresh]
2668
2664
  );
2669
- const fetchSeries = useCallback3(
2670
- async (enrollmentId, window2 = "1h") => {
2665
+ const fetchSeries = useCallback2(
2666
+ async (enrollmentId, window = "1h") => {
2671
2667
  if (!machinesClient.machineMetricsSeries) return [];
2672
- return await machinesClient.machineMetricsSeries(workspaceId, enrollmentId, { window: window2 });
2668
+ return await machinesClient.machineMetricsSeries(workspaceId, enrollmentId, { window });
2673
2669
  },
2674
2670
  [machinesClient, workspaceId]
2675
2671
  );
2676
- const remove = useCallback3(
2672
+ const remove = useCallback2(
2677
2673
  async (enrollmentId, request = {}) => {
2678
2674
  if (!machinesClient.removeEnrollment) return null;
2679
2675
  const ownedIdentity = identityKey;
@@ -2691,7 +2687,7 @@ function useMachines(options = {}) {
2691
2687
  },
2692
2688
  [machinesClient, workspaceId, identityKey, run2, refresh]
2693
2689
  );
2694
- const updateAgent = useCallback3(
2690
+ const updateAgent = useCallback2(
2695
2691
  async (enrollmentId) => {
2696
2692
  if (!machinesClient.updateMachineAgent) return null;
2697
2693
  const ownedIdentity = identityKey;
@@ -2705,7 +2701,7 @@ function useMachines(options = {}) {
2705
2701
  },
2706
2702
  [machinesClient, workspaceId, identityKey, run2, refresh]
2707
2703
  );
2708
- const updateOperationPolicy = useCallback3(
2704
+ const updateOperationPolicy = useCallback2(
2709
2705
  async (enrollmentId, request) => {
2710
2706
  if (!machinesClient.updateMachineOperationPolicy) return null;
2711
2707
  const ownedIdentity = identityKey;
@@ -2748,7 +2744,6 @@ function useMachines(options = {}) {
2748
2744
  }
2749
2745
 
2750
2746
  export {
2751
- OpenGeniProvider,
2752
2747
  connectionStatusForState,
2753
2748
  MACHINES_DASHBOARD_POLL_MS,
2754
2749
  MACHINES_SESSION_POLL_MS,
@@ -2779,4 +2774,4 @@ export {
2779
2774
  EnrollmentDeviceFlow,
2780
2775
  EnrollmentConsent
2781
2776
  };
2782
- //# sourceMappingURL=chunk-YVCHAQZY.js.map
2777
+ //# sourceMappingURL=chunk-NKMYZFHA.js.map