@ours.network/fleet 1.2.0-nightly.3 → 1.2.0-nightly.31

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 (458) hide show
  1. package/README.md +158 -28
  2. package/dist/account-origin.d.ts +2 -0
  3. package/dist/account-origin.js +6 -0
  4. package/dist/agent-ours/bridge.d.ts +3 -0
  5. package/dist/agent-ours/bridge.js +178 -0
  6. package/dist/agent-ours/controller.d.ts +14 -0
  7. package/dist/agent-ours/controller.js +60 -0
  8. package/dist/agent-ours/correspondence.d.ts +10 -0
  9. package/dist/agent-ours/correspondence.js +1 -0
  10. package/dist/agent-ours/file-rpc.d.ts +23 -0
  11. package/dist/agent-ours/file-rpc.js +123 -0
  12. package/dist/agent-ours/harness.d.ts +14 -0
  13. package/dist/agent-ours/harness.js +72 -0
  14. package/dist/agent-ours/mcp-endpoint.d.ts +15 -0
  15. package/dist/agent-ours/mcp-endpoint.js +111 -0
  16. package/dist/agent-ours/runtime.d.ts +59 -0
  17. package/dist/agent-ours/runtime.js +283 -0
  18. package/dist/agent-ours/service.d.ts +23 -0
  19. package/dist/agent-ours/service.js +372 -0
  20. package/dist/agent-ours/state.d.ts +45 -0
  21. package/dist/agent-ours/state.js +95 -0
  22. package/dist/agent-ours/wire.d.ts +14 -0
  23. package/dist/agent-ours/wire.js +55 -0
  24. package/dist/application/conversation-history.d.ts +25 -0
  25. package/dist/application/conversation-history.js +189 -0
  26. package/dist/application/fleet-query-service.d.ts +1 -1
  27. package/dist/application/fleet-query-service.js +2 -2
  28. package/dist/application/legacy-supervisor-identity.d.ts +7 -0
  29. package/dist/application/legacy-supervisor-identity.js +43 -0
  30. package/dist/application/model-catalog.d.ts +1 -1
  31. package/dist/application/model-catalog.js +5 -2
  32. package/dist/application/preset-provenance.d.ts +19 -0
  33. package/dist/application/preset-provenance.js +59 -0
  34. package/dist/application/room-layout-definitions.d.ts +45 -0
  35. package/dist/application/room-layout-definitions.js +130 -0
  36. package/dist/application/session-control.d.ts +18 -0
  37. package/dist/application/session-control.js +54 -3
  38. package/dist/application/supervisor-ours-tools.d.ts +159 -0
  39. package/dist/application/supervisor-ours-tools.js +113 -0
  40. package/dist/application/task-layouts.d.ts +91 -0
  41. package/dist/application/task-layouts.js +249 -0
  42. package/dist/application/task-room-service.d.ts +99 -3
  43. package/dist/application/task-room-service.js +296 -31
  44. package/dist/atomic-file.d.ts +5 -0
  45. package/dist/atomic-file.js +62 -1
  46. package/dist/briefing.js +10 -59
  47. package/dist/build-info.json +6 -4
  48. package/dist/capabilities.d.ts +3 -1
  49. package/dist/capabilities.js +4 -0
  50. package/dist/cli.js +131 -5
  51. package/dist/client-profile.d.ts +5 -16
  52. package/dist/client-profile.js +4 -112
  53. package/dist/config.d.ts +4 -0
  54. package/dist/config.js +7 -0
  55. package/dist/creation.d.ts +1 -1
  56. package/dist/creation.js +5 -16
  57. package/dist/daemon-recovery.d.ts +1 -8
  58. package/dist/daemon-recovery.js +8 -113
  59. package/dist/docs.d.ts +3 -3
  60. package/dist/docs.js +43 -23
  61. package/dist/doctor.d.ts +1 -1
  62. package/dist/doctor.js +46 -59
  63. package/dist/erased-resources.d.ts +9 -0
  64. package/dist/erased-resources.js +87 -0
  65. package/dist/fleet-command-audit.d.ts +1 -0
  66. package/dist/fleet-command-audit.js +12 -7
  67. package/dist/harness/agent-session.d.ts +2 -0
  68. package/dist/harness/claude-code-session.js +4 -2
  69. package/dist/harness/codex-app-server-proxy.d.ts +4 -1
  70. package/dist/harness/codex-app-server-proxy.js +41 -5
  71. package/dist/harness/codex-session.js +9 -2
  72. package/dist/harness/codex.d.ts +3 -2
  73. package/dist/harness/codex.js +4 -3
  74. package/dist/harness/hermes-session.js +7 -1
  75. package/dist/init-wizard.js +20 -9
  76. package/dist/isolation/policy.js +2 -0
  77. package/dist/isolation/types.d.ts +5 -0
  78. package/dist/monitor.d.ts +1 -34
  79. package/dist/monitor.js +24 -151
  80. package/dist/notifications/fleet-producer.d.ts +18 -0
  81. package/dist/notifications/fleet-producer.js +129 -0
  82. package/dist/notifications/outbox.d.ts +31 -0
  83. package/dist/notifications/outbox.js +104 -0
  84. package/dist/owner-channel/channel.d.ts +3 -0
  85. package/dist/owner-channel/channel.js +34 -6
  86. package/dist/owner-channel/commands.d.ts +4 -0
  87. package/dist/owner-channel/commands.js +8 -0
  88. package/dist/owner-channel/lifecycle-outbox.js +4 -3
  89. package/dist/owner-channel/ours-client.js +2 -17
  90. package/dist/preset-migration.js +15 -0
  91. package/dist/rooms-tasks/add-member.d.ts +48 -0
  92. package/dist/rooms-tasks/add-member.js +83 -0
  93. package/dist/rooms-tasks/archived-absence.d.ts +8 -0
  94. package/dist/rooms-tasks/archived-absence.js +48 -0
  95. package/dist/rooms-tasks/cli.js +34 -5
  96. package/dist/rooms-tasks/close.d.ts +5 -2
  97. package/dist/rooms-tasks/close.js +208 -28
  98. package/dist/rooms-tasks/config.js +3 -1
  99. package/dist/rooms-tasks/cowork-adapter.d.ts +6 -4
  100. package/dist/rooms-tasks/cowork-adapter.js +11 -117
  101. package/dist/rooms-tasks/cowork-http.d.ts +3 -0
  102. package/dist/rooms-tasks/cowork-http.js +70 -0
  103. package/dist/rooms-tasks/deletion.d.ts +1 -1
  104. package/dist/rooms-tasks/deletion.js +74 -5
  105. package/dist/rooms-tasks/erasure.d.ts +6 -0
  106. package/dist/rooms-tasks/erasure.js +169 -0
  107. package/dist/rooms-tasks/external-worker.d.ts +1 -1
  108. package/dist/rooms-tasks/external-worker.js +3 -4
  109. package/dist/rooms-tasks/layout-binding-client.d.ts +11 -0
  110. package/dist/rooms-tasks/layout-binding-client.js +56 -0
  111. package/dist/rooms-tasks/layout-binding-grants.d.ts +21 -0
  112. package/dist/rooms-tasks/layout-binding-grants.js +128 -0
  113. package/dist/rooms-tasks/layout-cli.d.ts +4 -0
  114. package/dist/rooms-tasks/layout-cli.js +107 -0
  115. package/dist/rooms-tasks/layout-config.d.ts +11 -0
  116. package/dist/rooms-tasks/layout-config.js +89 -0
  117. package/dist/rooms-tasks/layout-control.d.ts +21 -0
  118. package/dist/rooms-tasks/layout-control.js +52 -0
  119. package/dist/rooms-tasks/layout-service.d.ts +42 -0
  120. package/dist/rooms-tasks/layout-service.js +185 -0
  121. package/dist/rooms-tasks/layout.d.ts +114 -0
  122. package/dist/rooms-tasks/layout.js +250 -0
  123. package/dist/rooms-tasks/live-readiness.d.ts +18 -0
  124. package/dist/rooms-tasks/live-readiness.js +85 -0
  125. package/dist/rooms-tasks/member-startup.d.ts +1 -0
  126. package/dist/rooms-tasks/member-startup.js +2 -0
  127. package/dist/rooms-tasks/provision.d.ts +14 -0
  128. package/dist/rooms-tasks/provision.js +182 -48
  129. package/dist/rooms-tasks/room-state.d.ts +4 -2
  130. package/dist/rooms-tasks/room-state.js +53 -8
  131. package/dist/rooms-tasks/task-state.d.ts +42 -7
  132. package/dist/rooms-tasks/task-state.js +153 -23
  133. package/dist/rooms-tasks/types.d.ts +28 -0
  134. package/dist/rooms-tasks/workspace-artifacts.d.ts +6 -0
  135. package/dist/rooms-tasks/workspace-artifacts.js +93 -0
  136. package/dist/rooms-tasks/workspace.d.ts +26 -0
  137. package/dist/rooms-tasks/workspace.js +195 -0
  138. package/dist/runner.d.ts +23 -3
  139. package/dist/runner.js +581 -494
  140. package/dist/session/acp.d.ts +3 -0
  141. package/dist/session/acp.js +14 -0
  142. package/dist/session/arbiter.d.ts +3 -0
  143. package/dist/session/arbiter.js +20 -2
  144. package/dist/session/codex-app-server-transport.js +1 -1
  145. package/dist/session/codex-app-server.d.ts +3 -0
  146. package/dist/session/codex-app-server.js +25 -1
  147. package/dist/session/control.d.ts +10 -1
  148. package/dist/session/control.js +37 -2
  149. package/dist/session/conversation-normalizer.d.ts +2 -1
  150. package/dist/session/conversation-normalizer.js +1 -1
  151. package/dist/session/conversation-types.d.ts +5 -3
  152. package/dist/session/task-notice.d.ts +14 -0
  153. package/dist/session/task-notice.js +13 -0
  154. package/dist/session/types.d.ts +3 -0
  155. package/dist/socket-path.d.ts +2 -0
  156. package/dist/socket-path.js +22 -0
  157. package/dist/spawn.js +19 -16
  158. package/dist/startup-readiness.d.ts +13 -0
  159. package/dist/startup-readiness.js +38 -0
  160. package/dist/subscriptions/cli.d.ts +78 -0
  161. package/dist/subscriptions/cli.js +186 -0
  162. package/dist/subscriptions/launch.d.ts +37 -0
  163. package/dist/subscriptions/launch.js +93 -0
  164. package/dist/subscriptions/login.d.ts +75 -0
  165. package/dist/subscriptions/login.js +182 -0
  166. package/dist/subscriptions/observed.d.ts +7 -0
  167. package/dist/subscriptions/observed.js +44 -0
  168. package/dist/subscriptions/probe.d.ts +10 -0
  169. package/dist/subscriptions/probe.js +73 -0
  170. package/dist/subscriptions/service.d.ts +102 -0
  171. package/dist/subscriptions/service.js +364 -0
  172. package/dist/subscriptions/store.d.ts +71 -0
  173. package/dist/subscriptions/store.js +140 -0
  174. package/dist/supervisor/launchd.js +2 -1
  175. package/dist/supervisor/systemd.js +9 -23
  176. package/dist/temp-idle.d.ts +17 -0
  177. package/dist/temp-idle.js +42 -0
  178. package/dist/temp-lifecycle.d.ts +6 -1
  179. package/dist/temp-lifecycle.js +29 -13
  180. package/dist/temp-supervisor-recovery.d.ts +3 -0
  181. package/dist/temp-supervisor-recovery.js +46 -0
  182. package/dist/watchdog/briefing.js +3 -16
  183. package/dist/watchdog/run.js +19 -5
  184. package/dist/web/agent-attachments.d.ts +29 -0
  185. package/dist/web/agent-attachments.js +162 -0
  186. package/dist/web/auth.d.ts +28 -2
  187. package/dist/web/auth.js +81 -8
  188. package/dist/web/available-port.d.ts +2 -0
  189. package/dist/web/available-port.js +23 -0
  190. package/dist/web/control.d.ts +3 -2
  191. package/dist/web/control.js +11 -7
  192. package/dist/web/fleet-config-service.d.ts +4 -1
  193. package/dist/web/fleet-config-service.js +46 -15
  194. package/dist/web/prefix-gateway.d.ts +23 -0
  195. package/dist/web/prefix-gateway.js +156 -0
  196. package/dist/web/runtime.d.ts +4 -0
  197. package/dist/web/runtime.js +106 -20
  198. package/dist/web/server.d.ts +11 -0
  199. package/dist/web/server.js +445 -31
  200. package/dist/web/service.d.ts +11 -2
  201. package/dist/web/service.js +30 -4
  202. package/dist/web/workspace-devices.d.ts +29 -0
  203. package/dist/web/workspace-devices.js +84 -0
  204. package/dist/web/workspace-tunnel.d.ts +1 -0
  205. package/dist/web/workspace-tunnel.js +32 -0
  206. package/dist/web-app/assets/FleetApp-D58F4xje.css +1 -0
  207. package/dist/web-app/assets/FleetApp-DP5cBY0o.js +302 -0
  208. package/dist/web-app/assets/FleetApp-DP5cBY0o.js.map +1 -0
  209. package/dist/web-app/assets/abnfDiagram-VCTEODGH-BvJIz7wN.js +2 -0
  210. package/dist/web-app/assets/abnfDiagram-VCTEODGH-BvJIz7wN.js.map +1 -0
  211. package/dist/web-app/assets/arc-AT_BEfpe.js +2 -0
  212. package/dist/web-app/assets/arc-AT_BEfpe.js.map +1 -0
  213. package/dist/web-app/assets/architectureDiagram-5GKGNRK7-vSgJa9Xb.js +37 -0
  214. package/dist/web-app/assets/architectureDiagram-5GKGNRK7-vSgJa9Xb.js.map +1 -0
  215. package/dist/web-app/assets/blockDiagram-I7D4REHJ-DCFk_4Kv.js +130 -0
  216. package/dist/web-app/assets/blockDiagram-I7D4REHJ-DCFk_4Kv.js.map +1 -0
  217. package/dist/web-app/assets/browser-CMIwJ_8L.js +9 -0
  218. package/dist/web-app/assets/browser-CMIwJ_8L.js.map +1 -0
  219. package/dist/web-app/assets/c4Diagram-7LVT6UL2-8J_dVUtF.js +39 -0
  220. package/dist/web-app/assets/c4Diagram-7LVT6UL2-8J_dVUtF.js.map +1 -0
  221. package/dist/web-app/assets/channel-BHCBlfND.js +2 -0
  222. package/dist/web-app/assets/channel-BHCBlfND.js.map +1 -0
  223. package/dist/web-app/assets/chunk-2Q5K7J3B-31RX-jnL.js +2 -0
  224. package/dist/web-app/assets/chunk-2Q5K7J3B-31RX-jnL.js.map +1 -0
  225. package/dist/web-app/assets/chunk-5VM5RSS4-CFF8_ZJH.js +16 -0
  226. package/dist/web-app/assets/chunk-5VM5RSS4-CFF8_ZJH.js.map +1 -0
  227. package/dist/web-app/assets/chunk-F27PBJKO-Dx1l5wLI.js +2 -0
  228. package/dist/web-app/assets/chunk-F27PBJKO-Dx1l5wLI.js.map +1 -0
  229. package/dist/web-app/assets/chunk-IMKFNOWR-Ba2_9bl_.js +232 -0
  230. package/dist/web-app/assets/chunk-IMKFNOWR-Ba2_9bl_.js.map +1 -0
  231. package/dist/web-app/assets/chunk-JWPE2WC7-_mnRB2OH.js +2 -0
  232. package/dist/web-app/assets/chunk-JWPE2WC7-_mnRB2OH.js.map +1 -0
  233. package/dist/web-app/assets/chunk-POPQ4Y6H-B8jQTxQO.js +2 -0
  234. package/dist/web-app/assets/chunk-POPQ4Y6H-B8jQTxQO.js.map +1 -0
  235. package/dist/web-app/assets/chunk-SVP7TREG-BO_Jnb_c.js +89 -0
  236. package/dist/web-app/assets/chunk-SVP7TREG-BO_Jnb_c.js.map +1 -0
  237. package/dist/web-app/assets/chunk-TICWLB2K-ZYZ9hFu5.js +207 -0
  238. package/dist/web-app/assets/chunk-TICWLB2K-ZYZ9hFu5.js.map +1 -0
  239. package/dist/web-app/assets/chunk-XXDRQBXY-ByUAYXI3.js +2 -0
  240. package/dist/web-app/assets/chunk-XXDRQBXY-ByUAYXI3.js.map +1 -0
  241. package/dist/web-app/assets/classDiagram-ZZMXUADV-Ddx7RAuT.js +2 -0
  242. package/dist/web-app/assets/classDiagram-ZZMXUADV-Ddx7RAuT.js.map +1 -0
  243. package/dist/web-app/assets/classDiagram-v2-VYDZK3BY-Ddx7RAuT.js +2 -0
  244. package/dist/web-app/assets/classDiagram-v2-VYDZK3BY-Ddx7RAuT.js.map +1 -0
  245. package/dist/web-app/assets/cose-bilkent-JH36ORCC-BuOGJgHG.js +2 -0
  246. package/dist/web-app/assets/cose-bilkent-JH36ORCC-BuOGJgHG.js.map +1 -0
  247. package/dist/web-app/assets/cynefin-OW5HDTMX-DLksGPh8.js +179 -0
  248. package/dist/web-app/assets/cynefin-OW5HDTMX-DLksGPh8.js.map +1 -0
  249. package/dist/web-app/assets/cynefinDiagram-5FMLGOSQ-nJQb5qZR.js +63 -0
  250. package/dist/web-app/assets/cynefinDiagram-5FMLGOSQ-nJQb5qZR.js.map +1 -0
  251. package/dist/web-app/assets/cytoscape.esm-CtNdOvlO.js +332 -0
  252. package/dist/web-app/assets/cytoscape.esm-CtNdOvlO.js.map +1 -0
  253. package/dist/web-app/assets/dagre-GXQ25YYZ-CCF5O_UD.js +5 -0
  254. package/dist/web-app/assets/dagre-GXQ25YYZ-CCF5O_UD.js.map +1 -0
  255. package/dist/web-app/assets/defaultLocale-DX6XiGOO.js +2 -0
  256. package/dist/web-app/assets/defaultLocale-DX6XiGOO.js.map +1 -0
  257. package/dist/web-app/assets/diagram-S7CK7UJ4-C88au4NC.js +31 -0
  258. package/dist/web-app/assets/diagram-S7CK7UJ4-C88au4NC.js.map +1 -0
  259. package/dist/web-app/assets/diagram-UQ7AKVKN-B4QnPs7U.js +42 -0
  260. package/dist/web-app/assets/diagram-UQ7AKVKN-B4QnPs7U.js.map +1 -0
  261. package/dist/web-app/assets/diagram-VSXAHHWV-DeANdVWA.js +4 -0
  262. package/dist/web-app/assets/diagram-VSXAHHWV-DeANdVWA.js.map +1 -0
  263. package/dist/web-app/assets/diagram-VX7I27RA-YzlB_2AY.js +25 -0
  264. package/dist/web-app/assets/diagram-VX7I27RA-YzlB_2AY.js.map +1 -0
  265. package/dist/web-app/assets/diagram-Z3DM3KII-YY9NFaz_.js +25 -0
  266. package/dist/web-app/assets/diagram-Z3DM3KII-YY9NFaz_.js.map +1 -0
  267. package/dist/web-app/assets/ebnfDiagram-PWID7BFC-Cqu9kHUC.js +2 -0
  268. package/dist/web-app/assets/ebnfDiagram-PWID7BFC-Cqu9kHUC.js.map +1 -0
  269. package/dist/web-app/assets/erDiagram-RLTQ6QDP-IHi93MdG.js +100 -0
  270. package/dist/web-app/assets/erDiagram-RLTQ6QDP-IHi93MdG.js.map +1 -0
  271. package/dist/web-app/assets/flowDiagram-HODETNUW-19bm7W5P.js +169 -0
  272. package/dist/web-app/assets/flowDiagram-HODETNUW-19bm7W5P.js.map +1 -0
  273. package/dist/web-app/assets/ganttDiagram-EL5Y4UJY-BvCqvyiB.js +293 -0
  274. package/dist/web-app/assets/ganttDiagram-EL5Y4UJY-BvCqvyiB.js.map +1 -0
  275. package/dist/web-app/assets/gitGraphDiagram-WWUBYQGX-G4Ubl8Fs.js +107 -0
  276. package/dist/web-app/assets/gitGraphDiagram-WWUBYQGX-G4Ubl8Fs.js.map +1 -0
  277. package/dist/web-app/assets/index-C4BdeFB9.css +1 -0
  278. package/dist/web-app/assets/index-Dtn3ZY6J.js +430 -0
  279. package/dist/web-app/assets/index-Dtn3ZY6J.js.map +1 -0
  280. package/dist/web-app/assets/infoDiagram-27XIBGKW-B6rtfbuC.js +3 -0
  281. package/dist/web-app/assets/infoDiagram-27XIBGKW-B6rtfbuC.js.map +1 -0
  282. package/dist/web-app/assets/init-Gi6I4Gst.js +2 -0
  283. package/dist/web-app/assets/init-Gi6I4Gst.js.map +1 -0
  284. package/dist/web-app/assets/ishikawaDiagram-5VMMS53U-Lp8q1D21.js +71 -0
  285. package/dist/web-app/assets/ishikawaDiagram-5VMMS53U-Lp8q1D21.js.map +1 -0
  286. package/dist/web-app/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
  287. package/dist/web-app/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
  288. package/dist/web-app/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  289. package/dist/web-app/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  290. package/dist/web-app/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
  291. package/dist/web-app/assets/journeyDiagram-3NMN7TZE-Av03B9l3.js +140 -0
  292. package/dist/web-app/assets/journeyDiagram-3NMN7TZE-Av03B9l3.js.map +1 -0
  293. package/dist/web-app/assets/kanban-definition-UXKFOSKX-Ddd3_ejb.js +90 -0
  294. package/dist/web-app/assets/kanban-definition-UXKFOSKX-Ddd3_ejb.js.map +1 -0
  295. package/dist/web-app/assets/katex-HP8lGamR.js +258 -0
  296. package/dist/web-app/assets/katex-HP8lGamR.js.map +1 -0
  297. package/dist/web-app/assets/layout-CNjBeOlp.js +2 -0
  298. package/dist/web-app/assets/layout-CNjBeOlp.js.map +1 -0
  299. package/dist/web-app/assets/linear-DDONU9Ir.js +2 -0
  300. package/dist/web-app/assets/linear-DDONU9Ir.js.map +1 -0
  301. package/dist/web-app/assets/mermaid.core-B9X3C61k.js +313 -0
  302. package/dist/web-app/assets/mermaid.core-B9X3C61k.js.map +1 -0
  303. package/dist/web-app/assets/mindmap-definition-YA3MSWOX-I2UME2Ce.js +97 -0
  304. package/dist/web-app/assets/mindmap-definition-YA3MSWOX-I2UME2Ce.js.map +1 -0
  305. package/dist/web-app/assets/ordinal-Cboi1Yqb.js +2 -0
  306. package/dist/web-app/assets/ordinal-Cboi1Yqb.js.map +1 -0
  307. package/dist/web-app/assets/pegDiagram-XKGWAZYB-BER8lNbi.js +2 -0
  308. package/dist/web-app/assets/pegDiagram-XKGWAZYB-BER8lNbi.js.map +1 -0
  309. package/dist/web-app/assets/pieDiagram-E7YTZNPT-FVWVg8rH.js +40 -0
  310. package/dist/web-app/assets/pieDiagram-E7YTZNPT-FVWVg8rH.js.map +1 -0
  311. package/dist/web-app/assets/quadrantDiagram-AXDQQJYC-YlvT1u77.js +8 -0
  312. package/dist/web-app/assets/quadrantDiagram-AXDQQJYC-YlvT1u77.js.map +1 -0
  313. package/dist/web-app/assets/railroadDiagram-O6MQD6OU-CvxT6dMW.js +2 -0
  314. package/dist/web-app/assets/railroadDiagram-O6MQD6OU-CvxT6dMW.js.map +1 -0
  315. package/dist/web-app/assets/requirementDiagram-BXWQKSXE-Caav4EkP.js +85 -0
  316. package/dist/web-app/assets/requirementDiagram-BXWQKSXE-Caav4EkP.js.map +1 -0
  317. package/dist/web-app/assets/sankeyDiagram-P5KCCOFB-B5Uw70Gn.js +41 -0
  318. package/dist/web-app/assets/sankeyDiagram-P5KCCOFB-B5Uw70Gn.js.map +1 -0
  319. package/dist/web-app/assets/sequenceDiagram-WJ2MYXX4-D2SLKVJl.js +163 -0
  320. package/dist/web-app/assets/sequenceDiagram-WJ2MYXX4-D2SLKVJl.js.map +1 -0
  321. package/dist/web-app/assets/sizeCapture-INFHLROL-BVaBfbwa.js +2 -0
  322. package/dist/web-app/assets/sizeCapture-INFHLROL-BVaBfbwa.js.map +1 -0
  323. package/dist/web-app/assets/stateDiagram-D77RDMKH-BlV9y2tf.js +2 -0
  324. package/dist/web-app/assets/stateDiagram-D77RDMKH-BlV9y2tf.js.map +1 -0
  325. package/dist/web-app/assets/stateDiagram-v2-MP3YSRHH-BU4Tu2pp.js +2 -0
  326. package/dist/web-app/assets/stateDiagram-v2-MP3YSRHH-BU4Tu2pp.js.map +1 -0
  327. package/dist/web-app/assets/swimlanes-42K2YHIH-Pv3Wv8c7.js +2 -0
  328. package/dist/web-app/assets/swimlanes-42K2YHIH-Pv3Wv8c7.js.map +1 -0
  329. package/dist/web-app/assets/swimlanesDiagram-VR7AAH4N-BNKjOvPH.js +9 -0
  330. package/dist/web-app/assets/swimlanesDiagram-VR7AAH4N-BNKjOvPH.js.map +1 -0
  331. package/dist/web-app/assets/timeline-definition-24CTP7MA-C9TOilaR.js +121 -0
  332. package/dist/web-app/assets/timeline-definition-24CTP7MA-C9TOilaR.js.map +1 -0
  333. package/dist/web-app/assets/vennDiagram-4TSXK5OY-DeSDprN4.js +35 -0
  334. package/dist/web-app/assets/vennDiagram-4TSXK5OY-DeSDprN4.js.map +1 -0
  335. package/dist/web-app/assets/wardleyDiagram-VM6X3IG4-SulZn-nm.js +79 -0
  336. package/dist/web-app/assets/wardleyDiagram-VM6X3IG4-SulZn-nm.js.map +1 -0
  337. package/dist/web-app/assets/xychartDiagram-S5SC5T6Z-CC6MrQ0h.js +8 -0
  338. package/dist/web-app/assets/xychartDiagram-S5SC5T6Z-CC6MrQ0h.js.map +1 -0
  339. package/dist/web-app/fleet-index.html +19 -0
  340. package/dist/web-app/fleet.webmanifest +37 -0
  341. package/dist/web-app/icons/apple-touch-icon.png +0 -0
  342. package/dist/web-app/icons/favicon-16.png +0 -0
  343. package/dist/web-app/icons/favicon-32.png +0 -0
  344. package/dist/web-app/icons/icon-192-maskable.png +0 -0
  345. package/dist/web-app/icons/icon-192.png +0 -0
  346. package/dist/web-app/icons/icon-512-maskable.png +0 -0
  347. package/dist/web-app/icons/icon-512.png +0 -0
  348. package/dist/web-app/index.html +9 -7
  349. package/dist/web-app/manifest.webmanifest +10 -8
  350. package/dist/web-app/sw.js +210 -40
  351. package/dist/web-app/version.json +1 -0
  352. package/dist/web-app/workspace-install.sh +148 -0
  353. package/dist/workspace-enrollment.d.ts +28 -0
  354. package/dist/workspace-enrollment.js +129 -0
  355. package/docs/room-layouts.md +227 -0
  356. package/docs/task-workspaces.md +130 -0
  357. package/examples/room-layouts/fresh.yaml +27 -0
  358. package/examples/room-layouts/scoped.yaml +21 -0
  359. package/examples/room-layouts/shared.yaml +19 -0
  360. package/package.json +14 -17
  361. package/presets/README.md +78 -0
  362. package/presets/brain-catalog.json +8 -2
  363. package/presets/fleet/agent_templates/Engineer.yaml +5 -0
  364. package/presets/fleet/brains/claude-fable-5-1-high.yaml +5 -0
  365. package/presets/fleet/brains/claude-fable-5-1-low.yaml +5 -0
  366. package/presets/fleet/brains/claude-fable-5-1-max.yaml +5 -0
  367. package/presets/fleet/brains/claude-fable-5-1-medium.yaml +5 -0
  368. package/presets/fleet/brains/claude-fable-5-1-xhigh.yaml +5 -0
  369. package/presets/fleet/brains/claude-fable-5-high.yaml +1 -1
  370. package/presets/fleet/brains/claude-fable-5-low.yaml +1 -1
  371. package/presets/fleet/brains/claude-fable-5-max.yaml +1 -1
  372. package/presets/fleet/brains/claude-fable-5-medium.yaml +1 -1
  373. package/presets/fleet/brains/claude-fable-5-xhigh.yaml +1 -1
  374. package/presets/fleet/brains/claude-haiku-4-5-20251001-default.yaml +4 -0
  375. package/presets/fleet/brains/claude-opus-5-5-high.yaml +5 -0
  376. package/presets/fleet/brains/claude-opus-5-5-low.yaml +5 -0
  377. package/presets/fleet/brains/claude-opus-5-5-max.yaml +5 -0
  378. package/presets/fleet/brains/claude-opus-5-5-medium.yaml +5 -0
  379. package/presets/fleet/brains/claude-opus-5-5-xhigh.yaml +5 -0
  380. package/presets/fleet/brains/claude-opus-5-high.yaml +1 -1
  381. package/presets/fleet/brains/claude-opus-5-low.yaml +1 -1
  382. package/presets/fleet/brains/claude-opus-5-max.yaml +1 -1
  383. package/presets/fleet/brains/claude-opus-5-medium.yaml +1 -1
  384. package/presets/fleet/brains/claude-opus-5-xhigh.yaml +1 -1
  385. package/presets/fleet/brains/claude-sonnet-5-high.yaml +1 -1
  386. package/presets/fleet/brains/claude-sonnet-5-low.yaml +1 -1
  387. package/presets/fleet/brains/claude-sonnet-5-max.yaml +1 -1
  388. package/presets/fleet/brains/claude-sonnet-5-medium.yaml +1 -1
  389. package/presets/fleet/brains/claude-sonnet-5-xhigh.yaml +1 -1
  390. package/presets/fleet/brains/codex-gpt-5-3-codex-spark-high.yaml +1 -1
  391. package/presets/fleet/brains/codex-gpt-5-3-codex-spark-low.yaml +1 -1
  392. package/presets/fleet/brains/codex-gpt-5-3-codex-spark-medium.yaml +1 -1
  393. package/presets/fleet/brains/codex-gpt-5-3-codex-spark-xhigh.yaml +1 -1
  394. package/presets/fleet/brains/codex-gpt-5-4-high.yaml +1 -1
  395. package/presets/fleet/brains/codex-gpt-5-4-low.yaml +1 -1
  396. package/presets/fleet/brains/codex-gpt-5-4-medium.yaml +1 -1
  397. package/presets/fleet/brains/codex-gpt-5-4-mini-high.yaml +1 -1
  398. package/presets/fleet/brains/codex-gpt-5-4-mini-low.yaml +1 -1
  399. package/presets/fleet/brains/codex-gpt-5-4-mini-medium.yaml +1 -1
  400. package/presets/fleet/brains/codex-gpt-5-4-mini-xhigh.yaml +1 -1
  401. package/presets/fleet/brains/codex-gpt-5-4-xhigh.yaml +1 -1
  402. package/presets/fleet/brains/codex-gpt-5-5-high.yaml +1 -1
  403. package/presets/fleet/brains/codex-gpt-5-5-low.yaml +1 -1
  404. package/presets/fleet/brains/codex-gpt-5-5-medium.yaml +1 -1
  405. package/presets/fleet/brains/codex-gpt-5-5-xhigh.yaml +1 -1
  406. package/presets/fleet/brains/codex-gpt-5-6-luna-high.yaml +1 -1
  407. package/presets/fleet/brains/codex-gpt-5-6-luna-low.yaml +1 -1
  408. package/presets/fleet/brains/codex-gpt-5-6-luna-max.yaml +1 -1
  409. package/presets/fleet/brains/codex-gpt-5-6-luna-medium.yaml +1 -1
  410. package/presets/fleet/brains/codex-gpt-5-6-luna-xhigh.yaml +1 -1
  411. package/presets/fleet/brains/codex-gpt-5-6-sol-high.yaml +1 -1
  412. package/presets/fleet/brains/codex-gpt-5-6-sol-low.yaml +1 -1
  413. package/presets/fleet/brains/codex-gpt-5-6-sol-max.yaml +1 -1
  414. package/presets/fleet/brains/codex-gpt-5-6-sol-medium.yaml +1 -1
  415. package/presets/fleet/brains/codex-gpt-5-6-sol-ultra.yaml +1 -1
  416. package/presets/fleet/brains/codex-gpt-5-6-sol-xhigh.yaml +1 -1
  417. package/presets/fleet/brains/codex-gpt-5-6-terra-high.yaml +1 -1
  418. package/presets/fleet/brains/codex-gpt-5-6-terra-low.yaml +1 -1
  419. package/presets/fleet/brains/codex-gpt-5-6-terra-max.yaml +1 -1
  420. package/presets/fleet/brains/codex-gpt-5-6-terra-medium.yaml +1 -1
  421. package/presets/fleet/brains/codex-gpt-5-6-terra-ultra.yaml +1 -1
  422. package/presets/fleet/brains/codex-gpt-5-6-terra-xhigh.yaml +1 -1
  423. package/presets/fleet/brains/codex-gpt-6-1-sol-high.yaml +5 -0
  424. package/presets/fleet/brains/codex-gpt-6-1-sol-low.yaml +5 -0
  425. package/presets/fleet/brains/codex-gpt-6-1-sol-max.yaml +5 -0
  426. package/presets/fleet/brains/codex-gpt-6-1-sol-medium.yaml +5 -0
  427. package/presets/fleet/brains/codex-gpt-6-1-sol-ultra.yaml +5 -0
  428. package/presets/fleet/brains/codex-gpt-6-1-sol-xhigh.yaml +5 -0
  429. package/presets/fleet/brains/codex-gpt-6-astra-high.yaml +1 -1
  430. package/presets/fleet/brains/codex-gpt-6-astra-low.yaml +1 -1
  431. package/presets/fleet/brains/codex-gpt-6-astra-max.yaml +1 -1
  432. package/presets/fleet/brains/codex-gpt-6-astra-medium.yaml +1 -1
  433. package/presets/fleet/brains/codex-gpt-6-astra-ultra.yaml +1 -1
  434. package/presets/fleet/brains/codex-gpt-6-astra-xhigh.yaml +1 -1
  435. package/presets/fleet/brains/codex-gpt-6-luna-high.yaml +5 -0
  436. package/presets/fleet/brains/codex-gpt-6-luna-low.yaml +5 -0
  437. package/presets/fleet/brains/codex-gpt-6-luna-max.yaml +5 -0
  438. package/presets/fleet/brains/codex-gpt-6-luna-medium.yaml +5 -0
  439. package/presets/fleet/brains/codex-gpt-6-luna-xhigh.yaml +5 -0
  440. package/presets/fleet/brains/codex-gpt-6-sol-high.yaml +5 -0
  441. package/presets/fleet/brains/codex-gpt-6-sol-low.yaml +5 -0
  442. package/presets/fleet/brains/codex-gpt-6-sol-max.yaml +5 -0
  443. package/presets/fleet/brains/codex-gpt-6-sol-medium.yaml +5 -0
  444. package/presets/fleet/brains/codex-gpt-6-sol-ultra.yaml +5 -0
  445. package/presets/fleet/brains/codex-gpt-6-sol-xhigh.yaml +5 -0
  446. package/presets/fleet/roles/Coordinator.yaml +22 -0
  447. package/presets/fleet/roles/Engineer.yaml +40 -0
  448. package/presets/fleet/room_layouts/engineering.yaml +25 -0
  449. package/presets/fleet/room_layouts/pair.yaml +24 -0
  450. package/presets/fleet/room_layouts/single.yaml +17 -0
  451. package/presets/fleet/room_layouts/team.yaml +30 -0
  452. package/presets/fleet/room_templates/engineering.yaml +19 -0
  453. package/presets/manifest.json +2 -2
  454. package/dist/web-app/assets/index-59GF-gsZ.css +0 -1
  455. package/dist/web-app/assets/index-C0h3ALvs.js +0 -10
  456. package/dist/web-app/icons/ours-fleet-maskable.svg +0 -4
  457. package/dist/web-app/icons/ours-fleet.svg +0 -4
  458. package/dist/web-app/offline.html +0 -18
@@ -2,6 +2,8 @@ import { withFileLock } from '../atomic-file.js';
2
2
  import { type TempLifecycleDeps } from '../temp-lifecycle.js';
3
3
  import { type CoworkAdapter } from './cowork-adapter.js';
4
4
  import type { RoomMemberSeat, RoomOrchestrationRecord } from './types.js';
5
+ export declare const CLOSE_LOCK_STALE_MS: number;
6
+ export declare function roomCloseLockPath(roomId: string): string;
5
7
  export interface RoomCloseDeps {
6
8
  inspectMember?(seat: RoomMemberSeat): Promise<{
7
9
  launchId: string;
@@ -19,12 +21,13 @@ export declare function waitForLivenessAbsent(role: string, launchId: string, li
19
21
  /** Report whether any daemon identity — under any name — carries this exact CID. */
20
22
  export declare function identityCidPresent(cid: string): Promise<boolean>;
21
23
  export declare function removeExactMemberIdentity(seat: RoomMemberSeat): Promise<void>;
24
+ export declare function assertMemberIdentityAbsent(seat: RoomMemberSeat): Promise<void>;
22
25
  /** One forward-only room close saga shared by every Fleet entry point. */
23
26
  export declare function acceptManagedRoomClose(roomId: string): Promise<RoomOrchestrationRecord>;
24
27
  export declare function recordManagedRoomCloseError(roomId: string, error: string, recoveryHint: string): Promise<RoomOrchestrationRecord>;
25
28
  export declare function closeManagedRoom(input: {
26
29
  roomId: string;
27
- cowork: Pick<CoworkAdapter, 'closeRoom'>;
30
+ cowork: Pick<CoworkAdapter, 'closeRoom'> & Partial<Pick<CoworkAdapter, 'getRoom'>>;
28
31
  deps?: RoomCloseDeps;
29
32
  }): Promise<RoomOrchestrationRecord>;
30
33
  export interface ManagedRoomDeleteResult {
@@ -38,6 +41,6 @@ export declare function deleteLegacyClosedRooms(input: {
38
41
  /** Retire live resources through the existing cursor, then delete retained state. */
39
42
  export declare function deleteManagedRoom(input: {
40
43
  roomId: string;
41
- cowork: Pick<CoworkAdapter, 'closeRoom' | 'deleteRoom'>;
44
+ cowork: Pick<CoworkAdapter, 'closeRoom' | 'deleteRoom'> & Partial<Pick<CoworkAdapter, 'getRoom'>>;
42
45
  deps?: RoomCloseDeps;
43
46
  }): Promise<ManagedRoomDeleteResult>;
@@ -1,16 +1,22 @@
1
+ import { detachDeletedRoom } from './task-state.js';
2
+ import { binderKey } from '../agent-ours/state.js';
3
+ import { eraseMemberArtifacts } from './erasure.js';
4
+ import { deleteWorkspace, assertWorkspaceDeletable } from './workspace.js';
5
+ import { collectWorkspaceArchives } from './workspace-artifacts.js';
1
6
  import { existsSync, readFileSync } from 'node:fs';
2
7
  import { join } from 'node:path';
3
8
  import { randomUUID } from 'node:crypto';
4
9
  import { attachOursClient } from '@ours.network/sdk/client';
5
10
  import { withFileLock } from '../atomic-file.js';
6
11
  import { agentDir, stateRoot } from '../paths.js';
7
- import { readTempSupervisor, secureStoppedTempArchive, stopTempSupervisor, tempSupervisorLiveness, } from '../temp-lifecycle.js';
12
+ import { readClientProfile } from '../client-profile.js';
13
+ import { readTempSupervisor, secureStoppedTempArchive, stopTempSupervisor, tempSupervisorLiveness, tempArchiveForLaunch, tempArchiveForCreationAction, } from '../temp-lifecycle.js';
8
14
  import { CoworkProtocolError } from './cowork-adapter.js';
9
- import { advanceMemberRetirement, advanceRoomClose, beginRoomClose, closeRoom, deleteRoomRecord, getRoomRecord, listRoomRecords, setRoomCloseError, } from './room-state.js';
10
- const CLOSE_LOCK_STALE_MS = 5 * 60_000;
15
+ import { advanceMemberRetirement, advanceRoomClose, beginRoomClose, closeRoom, deleteRoomRecord, getRoomRecord, listRoomRecords, setRoomCloseError, recordRetirementMemberCids, } from './room-state.js';
16
+ export const CLOSE_LOCK_STALE_MS = 5 * 60_000;
11
17
  const STOP_POLLS = 50;
12
18
  const STOP_POLL_MS = 100;
13
- function roomCloseLockPath(roomId) {
19
+ export function roomCloseLockPath(roomId) {
14
20
  return join(stateRoot(), 'locks', 'room-close', encodeURIComponent(roomId));
15
21
  }
16
22
  function errorText(error) {
@@ -19,6 +25,20 @@ function errorText(error) {
19
25
  function exactMemberIdentity(seat) {
20
26
  const dir = agentDir(seat.role_name, true);
21
27
  const identityPath = join(dir, '.identity');
28
+ if (existsSync(dir) && !existsSync(identityPath) && seat.launch?.action_id && seat.launch.launch_id) {
29
+ const supervisor = readTempSupervisor(dir);
30
+ let creation;
31
+ try {
32
+ creation = JSON.parse(readFileSync(join(dir, 'creation.json'), 'utf8'));
33
+ }
34
+ catch (error) {
35
+ if (error.code !== 'ENOENT')
36
+ throw error;
37
+ }
38
+ if (supervisor?.role === seat.role_name && supervisor.launchId === seat.launch.launch_id
39
+ && creation?.role === seat.role_name && creation.creationActionId === seat.launch.action_id)
40
+ return;
41
+ }
22
42
  if (!existsSync(dir) || !existsSync(identityPath)) {
23
43
  throw new Error(`room member '${seat.role_name}' has no live Fleet temp-state identity proof; refusing retirement`);
24
44
  }
@@ -30,7 +50,8 @@ function exactMemberIdentity(seat) {
30
50
  export async function inspectMember(seat) {
31
51
  exactMemberIdentity(seat);
32
52
  const supervisor = readTempSupervisor(agentDir(seat.role_name, true));
33
- if (!supervisor || supervisor.role !== seat.role_name) {
53
+ if (!supervisor || supervisor.role !== seat.role_name
54
+ || (seat.launch?.launch_id && supervisor.launchId !== seat.launch.launch_id)) {
34
55
  throw new Error(`room member '${seat.role_name}' has no exact Fleet supervisor ownership proof`);
35
56
  }
36
57
  return { launchId: supervisor.launchId };
@@ -54,16 +75,24 @@ export async function waitForLivenessAbsent(role, launchId, lifecycleDeps = {})
54
75
  throw new Error(`temporary role '${role}' did not reach proven stopped liveness`);
55
76
  }
56
77
  async function withIdentityClient(work) {
78
+ const profile = readClientProfile(process.env);
79
+ const leaseToken = `ours-fleet-room-close-${process.pid}-${randomUUID()}`;
57
80
  const client = await attachOursClient({
58
- env: process.env,
59
- leaseToken: `ours-fleet-room-close-${process.pid}-${randomUUID()}`,
60
- clientPid: process.pid,
81
+ endpoint: profile.endpoint,
82
+ expectedInstanceId: profile.expectedInstanceId,
83
+ credentialPath: profile.credentialPath,
84
+ sessionMode: 'external', env: {}, leaseToken,
61
85
  });
62
86
  try {
63
87
  return await work(client);
64
88
  }
65
89
  finally {
66
- await client.releaseLease().catch(() => { });
90
+ try {
91
+ await client.releaseLease().catch(() => { });
92
+ }
93
+ finally {
94
+ await client.close();
95
+ }
67
96
  }
68
97
  }
69
98
  function listedIdentity(rows, name) {
@@ -78,14 +107,19 @@ export async function identityCidPresent(cid) {
78
107
  }
79
108
  export async function removeExactMemberIdentity(seat) {
80
109
  await withIdentityClient(async (client) => {
81
- const before = listedIdentity(await client.listIdentities(), seat.role_name);
82
- if (!before)
110
+ const rows = await client.listIdentities();
111
+ const before = listedIdentity(rows, seat.role_name);
112
+ if (!before) {
113
+ if (rows.some(row => row.name === seat.role_name || (seat.identity_cid && 'cid' in row
114
+ && row.cid.toLowerCase() === seat.identity_cid.toLowerCase())))
115
+ throw new Error(`room member '${seat.role_name}' identity absence is not proven`);
83
116
  return;
117
+ }
84
118
  if (!seat.identity_cid) {
85
- throw new Error(`room member '${seat.role_name}' exists without a recorded authenticated CID; refusing removal`);
119
+ throw new Error(`room member '${seat.role_name}' exists without a recorded authenticated CID; identity absence is not proven; refusing removal`);
86
120
  }
87
121
  if (before.cid?.toLowerCase() !== seat.identity_cid.toLowerCase()) {
88
- throw new Error(`room member '${seat.role_name}' identity CID mismatch: recorded ${seat.identity_cid}, found ${before.cid ?? 'none'}`);
122
+ throw new Error(`room member '${seat.role_name}' identity absence is not proven: CID mismatch: recorded ${seat.identity_cid}, found ${before.cid ?? 'none'}`);
89
123
  }
90
124
  try {
91
125
  await client.removeIdentity({ name: seat.role_name });
@@ -100,17 +134,59 @@ export async function removeExactMemberIdentity(seat) {
100
134
  if (after)
101
135
  throw error;
102
136
  }
103
- const after = listedIdentity(await client.listIdentities(), seat.role_name);
104
- if (after) {
137
+ const after = await client.listIdentities();
138
+ if (after.some(row => row.name === seat.role_name || (seat.identity_cid && 'cid' in row
139
+ && row.cid.toLowerCase() === seat.identity_cid.toLowerCase()))) {
105
140
  throw new Error(`room member '${seat.role_name}' identity still exists after remove_identity`);
106
141
  }
107
142
  });
108
143
  }
144
+ export async function assertMemberIdentityAbsent(seat) {
145
+ await withIdentityClient(async (client) => {
146
+ const rows = await client.listIdentities();
147
+ if (rows.some(row => row.name === seat.role_name ||
148
+ (seat.identity_cid && 'cid' in row && row.cid.toLowerCase() === seat.identity_cid.toLowerCase()))) {
149
+ throw new Error(`room member '${seat.role_name}' identity absence is not proven; refusing retirement`);
150
+ }
151
+ });
152
+ }
109
153
  async function retireMember(roomId, seat, deps) {
110
154
  let room = getRoomRecord(roomId);
111
155
  let current = room.member_seats.find(candidate => candidate.role_name === seat.role_name);
112
156
  let retirement = current.retirement;
157
+ if (retirement?.phase === 'identity_absent') {
158
+ if (!deps.inspectMember) {
159
+ if (existsSync(agentDir(current.role_name, true)))
160
+ throw new Error('Retired member has replacement launch live state');
161
+ await assertMemberIdentityAbsent(current);
162
+ }
163
+ return;
164
+ }
113
165
  if (!retirement) {
166
+ if (!existsSync(agentDir(current.role_name, true)) && current.launch?.launch_id && current.launch.action_id) {
167
+ const archived = tempArchiveForLaunch(current.role_name, current.launch.launch_id);
168
+ const created = tempArchiveForCreationAction(current.role_name, current.launch.action_id);
169
+ if (archived && (!created || created.path !== archived || created.launchId !== current.launch.launch_id))
170
+ throw new Error('Archived member creation ownership mismatch');
171
+ if (archived && created?.path === archived && created.launchId === current.launch.launch_id) {
172
+ if (readFileSync(join(archived, '.identity'), 'utf8').trim() !== current.role_name)
173
+ throw new Error(`room member '${current.role_name}' archive identity mismatch`);
174
+ if (await tempSupervisorLiveness(archived) !== 'stopped')
175
+ throw new Error(`room member '${current.role_name}' archived supervisor is not proven stopped`);
176
+ // A terminated launch can archive itself before room retirement begins.
177
+ // Accept its exact durable provenance only when no identity needs removal.
178
+ await (deps.removeIdentity ?? removeExactMemberIdentity)(current);
179
+ await assertMemberIdentityAbsent(current);
180
+ const latest = getRoomRecord(roomId)?.member_seats.find(seat => seat.role_name === current.role_name);
181
+ if (existsSync(agentDir(current.role_name, true))
182
+ || latest?.launch?.launch_id !== current.launch.launch_id
183
+ || latest?.launch?.action_id !== current.launch.action_id
184
+ || latest?.identity_cid !== current.identity_cid)
185
+ throw new Error(`room member '${current.role_name}' changed during archived retirement proof`);
186
+ advanceMemberRetirement(roomId, current.role_name, 'identity_absent', current.launch.launch_id, archived);
187
+ return;
188
+ }
189
+ }
114
190
  if (current.launch?.state === 'pending' && current.launch.attempt === 0) {
115
191
  if (existsSync(agentDir(current.role_name, true))) {
116
192
  throw new Error(`never-launched room member '${current.role_name}' unexpectedly has Fleet temp state`);
@@ -119,12 +195,31 @@ async function retireMember(roomId, seat, deps) {
119
195
  advanceMemberRetirement(roomId, current.role_name, 'identity_absent', 'never-launched');
120
196
  return;
121
197
  }
198
+ if (!deps.inspectMember && !existsSync(agentDir(current.role_name, true))) {
199
+ await (deps.removeIdentity ?? removeExactMemberIdentity)(current);
200
+ if (existsSync(agentDir(current.role_name, true)))
201
+ throw new Error(`room member '${current.role_name}' acquired replacement state during retirement`);
202
+ advanceMemberRetirement(roomId, current.role_name, 'identity_absent', 'absent-verified');
203
+ return;
204
+ }
122
205
  const ownership = await (deps.inspectMember ?? inspectMember)(current);
123
206
  room = advanceMemberRetirement(roomId, current.role_name, 'stop_requested', ownership.launchId);
124
207
  current = room.member_seats.find(candidate => candidate.role_name === seat.role_name);
125
208
  retirement = current.retirement;
126
209
  }
210
+ if (['stop_requested', 'liveness_absent', 'archive_secured'].includes(retirement.phase) && !deps.requestStop
211
+ && !existsSync(agentDir(current.role_name, true))) {
212
+ const archive = tempArchiveForLaunch(current.role_name, retirement.launch_id);
213
+ if (archive && await tempSupervisorLiveness(archive) !== 'stopped')
214
+ throw new Error('Archived supervisor is not proven stopped');
215
+ await (deps.removeIdentity ?? removeExactMemberIdentity)(current);
216
+ await assertMemberIdentityAbsent(current);
217
+ advanceMemberRetirement(roomId, current.role_name, 'identity_absent', retirement.launch_id, archive, !archive);
218
+ return;
219
+ }
127
220
  if (retirement.phase === 'stop_requested') {
221
+ if (!deps.inspectMember && (await inspectMember(current)).launchId !== retirement.launch_id)
222
+ throw new Error('Member launch changed before stop');
128
223
  await (deps.requestStop ?? (async (role) => { await stopTempSupervisor(role); }))(current.role_name);
129
224
  await (deps.waitForLivenessAbsent ?? waitForLivenessAbsent)(current.role_name, retirement.launch_id);
130
225
  room = advanceMemberRetirement(roomId, current.role_name, 'liveness_absent', retirement.launch_id);
@@ -154,19 +249,31 @@ export async function closeManagedRoom(input) {
154
249
  const lock = deps.lock ?? withFileLock;
155
250
  return lock(roomCloseLockPath(input.roomId), async () => {
156
251
  let room = beginRoomClose(input.roomId);
157
- if (room.state === 'closed')
252
+ if (room.state === 'closed') {
253
+ if (!deps.inspectMember)
254
+ for (const seat of room.member_seats) {
255
+ if (existsSync(agentDir(seat.role_name, true)))
256
+ throw new Error('Closed room has replacement live state');
257
+ await assertMemberIdentityAbsent(seat);
258
+ }
158
259
  return room;
260
+ }
159
261
  try {
160
262
  if (room.close?.phase === 'retire_members') {
263
+ room = await recoverMemberCids(room, input.cowork);
161
264
  for (const seat of room.member_seats) {
162
- if (seat.retirement?.phase === 'identity_absent')
163
- continue;
164
265
  await retireMember(input.roomId, seat, deps);
165
266
  }
166
267
  room = advanceRoomClose(input.roomId, 'close_cowork');
167
268
  }
168
269
  if (room.close?.phase === 'close_cowork') {
169
- await input.cowork.closeRoom(input.roomId);
270
+ try {
271
+ await input.cowork.closeRoom(input.roomId);
272
+ }
273
+ catch (error) {
274
+ if (!(error instanceof CoworkProtocolError && error.code === 'not_found'))
275
+ throw error;
276
+ }
170
277
  }
171
278
  return closeRoom(input.roomId);
172
279
  }
@@ -180,6 +287,9 @@ export async function closeManagedRoom(input) {
180
287
  export async function deleteLegacyClosedRooms(input) {
181
288
  const deleted = [];
182
289
  for (const room of listRoomRecords({ state: 'closed' })) {
290
+ // This compatibility sweep is retirement, never explicit workspace deletion.
291
+ if (room.workspace)
292
+ continue;
183
293
  try {
184
294
  await input.cowork.deleteRoom(room.room_id);
185
295
  }
@@ -196,14 +306,84 @@ export async function deleteLegacyClosedRooms(input) {
196
306
  }
197
307
  /** Retire live resources through the existing cursor, then delete retained state. */
198
308
  export async function deleteManagedRoom(input) {
199
- await closeManagedRoom(input);
200
- try {
201
- await input.cowork.deleteRoom(input.roomId);
202
- }
203
- catch (error) {
204
- setRoomCloseError(input.roomId, errorText(error), `Retry 'ours-fleet room delete ${input.roomId} ${input.roomId}'.`);
205
- throw error;
309
+ if (getRoomRecord(input.roomId))
310
+ await closeManagedRoom(input);
311
+ return withFileLock(roomCloseLockPath(input.roomId), async () => {
312
+ try {
313
+ try {
314
+ await input.cowork.deleteRoom(input.roomId);
315
+ }
316
+ catch (error) {
317
+ // An earlier explicit delete may have removed the remote room before
318
+ // local filesystem cleanup failed. Never restore it or repeat creation.
319
+ if (!(error instanceof CoworkProtocolError && error.code === 'not_found'))
320
+ throw error;
321
+ }
322
+ const retained = getRoomRecord(input.roomId);
323
+ if (retained?.workspace && !retained.task_id) {
324
+ assertWorkspaceDeletable(retained.workspace, 'room', input.roomId);
325
+ collectWorkspaceArchives(retained.workspace);
326
+ deleteWorkspace(retained.workspace, 'room', input.roomId);
327
+ }
328
+ if (retained)
329
+ await eraseMemberArtifacts('room', input.roomId, retained.member_seats, [input.roomId]);
330
+ if (retained?.task_id)
331
+ detachDeletedRoom(retained.task_id, input.roomId);
332
+ deleteRoomRecord(input.roomId);
333
+ return { room_id: input.roomId, deleted: true };
334
+ }
335
+ catch (error) {
336
+ if (getRoomRecord(input.roomId))
337
+ setRoomCloseError(input.roomId, errorText(error), `Fix the cleanup error and explicitly retry room delete ${input.roomId} ${input.roomId}.`);
338
+ throw error;
339
+ }
340
+ }, {}, CLOSE_LOCK_STALE_MS);
341
+ }
342
+ /** Recover only an authenticated seat tied to this exact room and issued invite.
343
+ * Display names and the current daemon name inventory are never binding proof.
344
+ */
345
+ async function recoverMemberCids(room, cowork) {
346
+ if (!room.member_seats.some(seat => !seat.identity_cid))
347
+ return room;
348
+ const profile = room.member_seats.some(seat => seat.launch?.action_id) ? readClientProfile(process.env) : undefined;
349
+ let remote;
350
+ if (cowork.getRoom && room.room_identity_cid) {
351
+ try {
352
+ remote = await cowork.getRoom(room.room_id);
353
+ }
354
+ catch (error) {
355
+ if (!(error instanceof CoworkProtocolError && error.code === 'not_found'))
356
+ throw error;
357
+ }
358
+ if (remote && (remote.room_id !== room.room_id || remote.identity_cid.toLowerCase() !== room.room_identity_cid.toLowerCase()))
359
+ throw new Error('Room identity mismatch during deletion recovery');
206
360
  }
207
- deleteRoomRecord(input.roomId);
208
- return { room_id: input.roomId, deleted: true };
361
+ const seats = room.member_seats.map(seat => {
362
+ let runtimeCid;
363
+ if (profile && seat.launch?.action_id) {
364
+ const dir = join(stateRoot(), 'private-ours', binderKey(profile.expectedInstanceId, seat.role_name));
365
+ try {
366
+ const state = JSON.parse(readFileSync(join(dir, 'state.json'), 'utf8'));
367
+ const instance = JSON.parse(readFileSync(join(dir, 'instance.json'), 'utf8'));
368
+ if (state.name === seat.role_name && state.daemon === profile.expectedInstanceId
369
+ && state.lifetime === 'temporary' && state.action === seat.launch.action_id
370
+ && instance.role === seat.role_name && instance.temporary === true && instance.instance === state.instance)
371
+ runtimeCid = state.cid;
372
+ }
373
+ catch (error) {
374
+ if (error.code !== 'ENOENT')
375
+ throw error;
376
+ }
377
+ }
378
+ const matches = seat.invite_id ? remote?.seats.filter(value => value.invite_id === seat.invite_id && value.role === seat.cowork_role) ?? [] : [];
379
+ if (matches.length > 1)
380
+ throw new Error('Ambiguous authenticated member identity during deletion recovery');
381
+ const candidates = [seat.identity_cid, runtimeCid, matches[0]?.identity_cid].filter((v) => !!v);
382
+ if (candidates.some(cid => !/^[a-f0-9]{64}$/i.test(cid)))
383
+ throw new Error('Invalid authenticated member CID');
384
+ if (new Set(candidates.map(cid => cid.toLowerCase())).size > 1)
385
+ throw new Error('Contradictory authenticated member CID evidence');
386
+ return candidates.length ? { ...seat, identity_cid: candidates[0] } : seat;
387
+ });
388
+ return recordRetirementMemberCids(room.room_id, seats);
209
389
  }
@@ -54,7 +54,9 @@ export function validateRoomsConfig(raw, vars, path) {
54
54
  if (!isPlainObject(raw.cowork))
55
55
  throw new RoomsTasksConfigError(path, 'rooms.cowork: must be a mapping');
56
56
  rejectUnknown(raw.cowork, RCK, path, 'rooms.cowork');
57
- cowork = { config: raw.cowork.config };
57
+ if (raw.cowork.config !== undefined)
58
+ throw new RoomsTasksConfigError(path, 'rooms.cowork.config is no longer supported; remove it and configure ~/.ours-client/profile.json for all services');
59
+ cowork = {};
58
60
  }
59
61
  if (!isPlainObject(raw.owner))
60
62
  throw new RoomsTasksConfigError(path, 'rooms.owner: required and must be a mapping');
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Typed client for the ours-cowork v1 private management-socket protocol.
2
+ * Typed client for the ours-cowork v1 gateway management protocol.
3
3
  *
4
4
  * Cowork owns room state. Fleet only invokes the versioned JSON RPC exposed
5
- * by Cowork's Unix socket and projects the response into orchestration data.
5
+ * through the shared HTTP gateway and projects the response into orchestration data.
6
6
  */
7
7
  import type { Socket } from 'node:net';
8
8
  import type { RoomHistoryEvidence } from './types.js';
@@ -58,6 +58,10 @@ export interface CoworkAdapter {
58
58
  briefing: string;
59
59
  quiet_membership?: boolean;
60
60
  anonymous?: boolean;
61
+ activation_requirements?: Array<{
62
+ role: string;
63
+ count: number;
64
+ }>;
61
65
  }): Promise<CoworkRoomCreateResult>;
62
66
  acceptInvite(roomId: string, invite: string, opts: {
63
67
  role: string;
@@ -104,6 +108,4 @@ export interface CoworkAdapterOptions {
104
108
  home?: string;
105
109
  connect?: (path: string) => Socket;
106
110
  }
107
- /** Resolve the same config/state inputs as ours-cowork and return its Unix socket. */
108
- export declare function resolveCoworkSocketPath(options?: CoworkAdapterOptions): string;
109
111
  export declare function createCoworkAdapter(options?: CoworkAdapterOptions): CoworkAdapter;
@@ -1,18 +1,14 @@
1
1
  /**
2
- * Typed client for the ours-cowork v1 private management-socket protocol.
2
+ * Typed client for the ours-cowork v1 gateway management protocol.
3
3
  *
4
4
  * Cowork owns room state. Fleet only invokes the versioned JSON RPC exposed
5
- * by Cowork's Unix socket and projects the response into orchestration data.
5
+ * through the shared HTTP gateway and projects the response into orchestration data.
6
6
  */
7
- import { existsSync, readFileSync } from 'node:fs';
8
- import { homedir } from 'node:os';
9
- import { join, resolve } from 'node:path';
10
- import { createConnection } from 'node:net';
11
- const RPC_VERSION = 1;
7
+ import { readClientProfile } from '../client-profile.js';
8
+ import { coworkHttpCall } from './cowork-http.js';
12
9
  const DEFAULT_TIMEOUT_MS = 30_000;
13
- const MAX_RESPONSE_BYTES = 4 * 1024 * 1024;
14
10
  export class CoworkUnavailableError extends Error {
15
- constructor(message = 'Cowork management socket is not reachable', options) {
11
+ constructor(message = 'Cowork gateway management is not reachable', options) {
16
12
  super(message, options);
17
13
  this.name = 'CoworkUnavailableError';
18
14
  }
@@ -169,116 +165,13 @@ function projectHistoryRecord(value) {
169
165
  }
170
166
  return undefined;
171
167
  }
172
- /** Resolve the same config/state inputs as ours-cowork and return its Unix socket. */
173
- export function resolveCoworkSocketPath(options = {}) {
174
- if (options.socketPath)
175
- return resolve(options.socketPath);
176
- const env = options.env ?? process.env;
177
- const home = options.home ?? homedir();
178
- const configuredPath = options.configPath ?? env.OURS_COWORK_CONFIG;
179
- const configPath = resolve(configuredPath ?? join(home, '.ours-cowork', 'config.json'));
180
- let stateDir = resolve(home, '.ours-cowork');
181
- if (existsSync(configPath)) {
182
- let parsed;
183
- try {
184
- parsed = JSON.parse(readFileSync(configPath, 'utf8'));
185
- }
186
- catch (error) {
187
- throw new CoworkProtocolError('config', `malformed config at ${configPath}`, 'invalid_config', { cause: error });
188
- }
189
- const config = object(parsed, 'config', 'config');
190
- if (config.version !== 1 || typeof config.stateDir !== 'string' || !config.stateDir)
191
- throw new CoworkProtocolError('config', `invalid Cowork v1 config at ${configPath}`, 'invalid_config');
192
- stateDir = resolve(config.stateDir);
193
- }
194
- else if (configuredPath !== undefined) {
195
- throw new CoworkProtocolError('config', `configured Cowork config does not exist: ${configPath}`, 'invalid_config');
196
- }
197
- if (env.OURS_COWORK_STATE_DIR)
198
- stateDir = resolve(env.OURS_COWORK_STATE_DIR);
199
- return join(stateDir, 'management.sock');
200
- }
201
- function rpcCall(socketPath, method, params, timeoutMs, connect) {
202
- const id = `${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
203
- const request = `${JSON.stringify({ version: RPC_VERSION, id, method, params })}\n`;
204
- return new Promise((resolveCall, rejectCall) => {
205
- const socket = connect(socketPath);
206
- let bytes = '';
207
- let size = 0;
208
- let settled = false;
209
- let connected = false;
210
- const finishError = (error) => {
211
- if (settled)
212
- return;
213
- settled = true;
214
- clearTimeout(timer);
215
- socket.destroy();
216
- rejectCall(error);
217
- };
218
- const timer = setTimeout(() => finishError(new CoworkUnavailableError(connected ? 'Cowork did not answer the management socket' : 'Cowork management socket is not reachable')), timeoutMs);
219
- socket.setEncoding('utf8');
220
- socket.once('connect', () => {
221
- connected = true;
222
- socket.write(request);
223
- });
224
- socket.on('data', (chunk) => {
225
- if (settled)
226
- return;
227
- const text = typeof chunk === 'string' ? chunk : chunk.toString('utf8');
228
- size += Buffer.byteLength(text);
229
- if (size > MAX_RESPONSE_BYTES) {
230
- finishError(new CoworkProtocolError(method, 'response exceeded 4 MiB'));
231
- return;
232
- }
233
- bytes += text;
234
- const newline = bytes.indexOf('\n');
235
- if (newline < 0)
236
- return;
237
- if (bytes.slice(newline + 1).trim() !== '') {
238
- finishError(new CoworkProtocolError(method, 'daemon returned more than one response'));
239
- return;
240
- }
241
- let response;
242
- try {
243
- response = object(JSON.parse(bytes.slice(0, newline)), method, 'RPC response');
244
- }
245
- catch (error) {
246
- finishError(error instanceof CoworkProtocolError
247
- ? error : new CoworkProtocolError(method, 'daemon returned malformed JSON', 'protocol_error', { cause: error }));
248
- return;
249
- }
250
- if (response.version !== RPC_VERSION || response.id !== id
251
- || (Object.hasOwn(response, 'error') === Object.hasOwn(response, 'result'))) {
252
- finishError(new CoworkProtocolError(method, 'daemon returned an invalid RPC response'));
253
- return;
254
- }
255
- settled = true;
256
- clearTimeout(timer);
257
- socket.destroy();
258
- if (Object.hasOwn(response, 'error')) {
259
- const error = object(response.error, method, 'RPC error');
260
- rejectCall(new CoworkProtocolError(method, typeof error.message === 'string' ? error.message : 'unknown RPC error', typeof error.code === 'string' ? error.code : 'rpc_error'));
261
- }
262
- else {
263
- resolveCall(response.result);
264
- }
265
- });
266
- socket.once('end', () => {
267
- if (!settled)
268
- finishError(new CoworkProtocolError(method, 'daemon closed without a complete response'));
269
- });
270
- socket.once('error', (error) => {
271
- if (!settled)
272
- finishError(new CoworkUnavailableError(error.code === 'EACCES' || error.code === 'EPERM'
273
- ? 'Cowork management socket access denied' : 'Cowork management socket is not reachable', { cause: error }));
274
- });
275
- });
276
- }
277
168
  export function createCoworkAdapter(options = {}) {
278
- const socketPath = resolveCoworkSocketPath(options);
169
+ const env = options.env ?? process.env;
170
+ if (options.socketPath !== undefined || options.configPath !== undefined)
171
+ throw new CoworkProtocolError('config', 'Local Cowork selectors are unsupported; configure the shared gateway client profile', 'invalid_config');
172
+ const profile = readClientProfile({ ...env, HOME: options.home ?? env.HOME });
279
173
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
280
- const connect = options.connect ?? ((path) => createConnection(path));
281
- const call = (method, params) => rpcCall(socketPath, method, params, timeoutMs, connect);
174
+ const call = (method, params) => coworkHttpCall(profile, method, params, timeoutMs);
282
175
  return {
283
176
  async available() {
284
177
  try {
@@ -296,6 +189,7 @@ export function createCoworkAdapter(options = {}) {
296
189
  briefing: opts.briefing,
297
190
  ...(opts.quiet_membership === undefined ? {} : { quiet_membership: opts.quiet_membership }),
298
191
  ...(opts.anonymous === undefined ? {} : { anonymous: opts.anonymous }),
192
+ ...(opts.activation_requirements === undefined ? {} : { activation_requirements: opts.activation_requirements }),
299
193
  }), 'room.create');
300
194
  if (!result.identity_cid)
301
195
  throw new CoworkProtocolError('room.create', 'created room did not establish an identity CID');
@@ -0,0 +1,3 @@
1
+ import type { ExplicitClientProfile } from '../client-profile.js';
2
+ /** Same RPC protocol as the local socket; never replay a possibly delivered mutation. */
3
+ export declare function coworkHttpCall(profile: ExplicitClientProfile, method: string, params: Record<string, unknown>, timeoutMs: number): Promise<unknown>;
@@ -0,0 +1,70 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { attachOursClient } from '@ours.network/sdk/client';
3
+ import { readPrivateFile } from '@ours.network/sdk/connector';
4
+ import { CoworkProtocolError, CoworkUnavailableError } from './cowork-adapter.js';
5
+ /** Same RPC protocol as the local socket; never replay a possibly delivered mutation. */
6
+ export async function coworkHttpCall(profile, method, params, timeoutMs) {
7
+ const id = randomUUID();
8
+ const signal = AbortSignal.timeout(timeoutMs);
9
+ const body = JSON.stringify({ version: 1, id, method, params });
10
+ if (Buffer.byteLength(body) > 1024 * 1024)
11
+ throw new CoworkProtocolError(method, 'request exceeded 1 MiB');
12
+ try {
13
+ const client = await attachOursClient({ endpoint: profile.endpoint, expectedInstanceId: profile.expectedInstanceId,
14
+ credentialPath: profile.credentialPath, sessionMode: 'external', leaseToken: `fleet-cowork-check-${id}`, env: {}, requestSignal: signal });
15
+ await client.close();
16
+ const token = readPrivateFile(profile.credentialPath, 4096).toString('utf8').trim();
17
+ const response = await fetch(profile.serverUrl + '/cowork/management/rpc', {
18
+ method: 'POST', redirect: 'error', signal,
19
+ headers: { 'content-type': 'application/json', 'x-ours-api-token': token },
20
+ body,
21
+ });
22
+ if (response.status === 401 || response.status === 403) {
23
+ await response.body?.cancel();
24
+ throw new CoworkProtocolError(method, 'server credential was rejected', 'unauthorized');
25
+ }
26
+ const reader = response.body?.getReader();
27
+ if (!reader)
28
+ throw new CoworkProtocolError(method, 'empty HTTP response');
29
+ const chunks = [];
30
+ let size = 0;
31
+ try {
32
+ for (;;) {
33
+ const { done, value } = await reader.read();
34
+ if (done)
35
+ break;
36
+ size += value.length;
37
+ if (size > 4 * 1024 * 1024)
38
+ throw new CoworkProtocolError(method, 'response exceeded 4 MiB');
39
+ chunks.push(value);
40
+ }
41
+ }
42
+ finally {
43
+ await reader.cancel();
44
+ }
45
+ let rpc;
46
+ try {
47
+ rpc = JSON.parse(Buffer.concat(chunks).toString('utf8'));
48
+ }
49
+ catch {
50
+ throw new CoworkProtocolError(method, 'server returned malformed JSON');
51
+ }
52
+ if (!rpc || Array.isArray(rpc) || rpc.version !== 1 || rpc.id !== id
53
+ || Object.hasOwn(rpc, 'result') === Object.hasOwn(rpc, 'error'))
54
+ throw new CoworkProtocolError(method, 'server returned an invalid RPC response');
55
+ if (Object.hasOwn(rpc, 'error')) {
56
+ const error = rpc.error;
57
+ if (!error || typeof error.code !== 'string' || typeof error.message !== 'string')
58
+ throw new CoworkProtocolError(method, 'server returned an invalid RPC error');
59
+ throw new CoworkProtocolError(method, error.message, error.code);
60
+ }
61
+ if (!response.ok)
62
+ throw new CoworkProtocolError(method, `management answered HTTP ${response.status}`);
63
+ return rpc.result;
64
+ }
65
+ catch (error) {
66
+ if (error instanceof CoworkProtocolError)
67
+ throw error;
68
+ throw new CoworkUnavailableError('Cowork HTTP management failed; check the selected server and credential', { cause: error });
69
+ }
70
+ }
@@ -3,7 +3,7 @@ import { type CoworkAdapter } from './cowork-adapter.js';
3
3
  import { type TaskDeletionAcceptance } from './task-state.js';
4
4
  import type { TaskDeletionActor, TaskRecord } from './types.js';
5
5
  export { DELETION_MEMBER_ABSENT_VERIFIED } from './task-state.js';
6
- type DeletionCowork = Pick<CoworkAdapter, 'closeRoom' | 'deleteRoom'>;
6
+ type DeletionCowork = Pick<CoworkAdapter, 'closeRoom' | 'deleteRoom'> & Partial<Pick<CoworkAdapter, 'getRoom'>>;
7
7
  export interface TaskDeletionSettleDeps {
8
8
  roomClose?: RoomCloseDeps;
9
9
  /** Test seam for the temp-state existence proof. */