@baochunli/flakes 0.0.4 → 0.0.6

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 (275) hide show
  1. package/dist/commands/host.d.ts.map +1 -1
  2. package/dist/commands/host.js +76 -2
  3. package/dist/commands/host.js.map +1 -1
  4. package/dist/commands/projects.d.ts +4 -0
  5. package/dist/commands/projects.d.ts.map +1 -0
  6. package/dist/commands/projects.js +133 -0
  7. package/dist/commands/projects.js.map +1 -0
  8. package/dist/commands/runs.d.ts.map +1 -1
  9. package/dist/commands/runs.js +5 -1
  10. package/dist/commands/runs.js.map +1 -1
  11. package/dist/commands/runtime.d.ts +0 -1
  12. package/dist/commands/runtime.d.ts.map +1 -1
  13. package/dist/commands/runtime.js +2 -280
  14. package/dist/commands/runtime.js.map +1 -1
  15. package/dist/commands/server.d.ts.map +1 -1
  16. package/dist/commands/server.js +0 -6
  17. package/dist/commands/server.js.map +1 -1
  18. package/dist/config-example.js +1 -1
  19. package/dist/config-example.js.map +1 -1
  20. package/dist/host-config.d.ts +1 -6
  21. package/dist/host-config.d.ts.map +1 -1
  22. package/dist/host-config.js +10 -28
  23. package/dist/host-config.js.map +1 -1
  24. package/dist/host-runner.d.ts +3 -0
  25. package/dist/host-runner.d.ts.map +1 -1
  26. package/dist/host-runner.js +18 -6
  27. package/dist/host-runner.js.map +1 -1
  28. package/dist/host-runtime.d.ts.map +1 -1
  29. package/dist/host-runtime.js +92 -2
  30. package/dist/host-runtime.js.map +1 -1
  31. package/dist/host-transport.js +2 -5
  32. package/dist/host-transport.js.map +1 -1
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +19 -28
  35. package/dist/index.js.map +1 -1
  36. package/dist/node_modules/@flakes/auth/package.json +1 -1
  37. package/dist/node_modules/@flakes/console/.output/nitro.json +1 -1
  38. package/dist/node_modules/@flakes/console/.output/public/assets/DocumentationPage-CGIcMKwf.js +1 -0
  39. package/dist/node_modules/@flakes/console/.output/public/assets/ProjectsPage-ByTl4Kyy.js +1 -0
  40. package/dist/node_modules/@flakes/console/.output/public/assets/RunPage-5MmbVpaE.js +3 -0
  41. package/dist/node_modules/@flakes/console/.output/public/assets/RunsPage-fbDKP9kM.js +1 -0
  42. package/dist/node_modules/@flakes/console/.output/public/assets/SandboxesLens-DPG87mUE.js +1 -0
  43. package/dist/node_modules/@flakes/console/.output/public/assets/SandboxesPage-DIpzR_Ef.js +1 -0
  44. package/dist/node_modules/@flakes/console/.output/public/assets/TranscriptPage-mCgSqfv0.js +1 -0
  45. package/dist/node_modules/@flakes/console/.output/public/assets/_-CM2hE2sZ.js +1 -0
  46. package/dist/node_modules/@flakes/console/.output/public/assets/_runId-3ZZOAqUK.js +2 -0
  47. package/dist/node_modules/@flakes/console/.output/public/assets/_taskId-cy4RxW8Y.js +2 -0
  48. package/dist/node_modules/@flakes/console/.output/public/assets/account-BWoGGXJw.js +1 -0
  49. package/dist/node_modules/@flakes/console/.output/public/assets/account-forms-Dq70JDyg.js +1 -0
  50. package/dist/node_modules/@flakes/console/.output/public/assets/arrow-right-QzVbRzF_.js +1 -0
  51. package/dist/node_modules/@flakes/console/.output/public/assets/auth-layout-BFusNq3W.js +1 -0
  52. package/dist/node_modules/@flakes/console/.output/public/assets/bits-CTGNpp-v.js +1 -0
  53. package/dist/node_modules/@flakes/console/.output/public/assets/card-37qs8AAd.js +1 -0
  54. package/dist/node_modules/@flakes/console/.output/public/assets/circle-alert-CM0SVfzc.js +1 -0
  55. package/dist/node_modules/@flakes/console/.output/public/assets/circle-check-CzwcEElH.js +1 -0
  56. package/dist/node_modules/@flakes/console/.output/public/assets/circle-x-C_sOQVNQ.js +1 -0
  57. package/dist/node_modules/@flakes/console/.output/public/assets/device-BajR3eSF.js +1 -0
  58. package/dist/node_modules/@flakes/console/.output/public/assets/documentation-6ao_Ux6x.js +1 -0
  59. package/dist/node_modules/@flakes/console/.output/public/assets/{external-link-BW8lpiMR.js → external-link-BWhbbPgy.js} +1 -1
  60. package/dist/node_modules/@flakes/console/.output/public/assets/{file-text-DMdy8OfN.js → file-text-DLxLJ7P1.js} +1 -1
  61. package/dist/node_modules/@flakes/console/.output/public/assets/forgot-password-DOKn8_7P.js +1 -0
  62. package/dist/node_modules/@flakes/console/.output/public/assets/inbox-BVu38EN6.js +1 -0
  63. package/dist/node_modules/@flakes/console/.output/public/assets/{lib-DtfURcG3.js → lib-COfgMmRR.js} +3 -3
  64. package/dist/node_modules/@flakes/console/.output/public/assets/link-ll3nLBSM.js +1 -0
  65. package/dist/node_modules/@flakes/console/.output/public/assets/{lock-D4OhqEPW.js → lock-Ck2SfQA2.js} +1 -1
  66. package/dist/node_modules/@flakes/console/.output/public/assets/main-DVO9gWzi.js +1215 -0
  67. package/dist/node_modules/@flakes/console/.output/public/assets/matchContext-puEkI9BI.js +1 -0
  68. package/dist/node_modules/@flakes/console/.output/public/assets/otp-verification-qolVtiom.js +20 -0
  69. package/dist/node_modules/@flakes/console/.output/public/assets/projects-n5LSsNi3.js +2 -0
  70. package/dist/node_modules/@flakes/console/.output/public/assets/react-B8IZ02wI.js +1 -0
  71. package/dist/node_modules/@flakes/console/.output/public/assets/react-dom-ki7NpxV4.js +1 -0
  72. package/dist/node_modules/@flakes/console/.output/public/assets/redirect-Cu9zBy04.js +1 -0
  73. package/dist/node_modules/@flakes/console/.output/public/assets/reset-password-D-OlZeHQ.js +1 -0
  74. package/dist/node_modules/@flakes/console/.output/public/assets/runs-BB9ogobQ.js +2 -0
  75. package/dist/node_modules/@flakes/console/.output/public/assets/sandboxes-BIimz5FI.js +2 -0
  76. package/dist/node_modules/@flakes/console/.output/public/assets/{save-1uf5fQff.js → save-Bte_1tnN.js} +1 -1
  77. package/dist/node_modules/@flakes/console/.output/public/assets/security-DdQNcp6k.js +1 -0
  78. package/dist/node_modules/@flakes/console/.output/public/assets/signin-BoZiVxyq.js +1 -0
  79. package/dist/node_modules/@flakes/console/.output/public/assets/signin-form-tTBWDjhi.js +1 -0
  80. package/dist/node_modules/@flakes/console/.output/public/assets/signup-CBSszmUC.js +1 -0
  81. package/dist/node_modules/@flakes/console/.output/public/assets/styles-B8OXOvkO.css +2 -0
  82. package/dist/node_modules/@flakes/console/.output/public/assets/table-WMIs2m3R.js +1 -0
  83. package/dist/node_modules/@flakes/console/.output/public/assets/tiny-invariant-CO5X59di.js +1 -0
  84. package/dist/node_modules/@flakes/console/.output/public/assets/user-Bt9z7sSI.js +1 -0
  85. package/dist/node_modules/@flakes/console/.output/public/assets/utils-CBxvVKOM.js +1 -0
  86. package/dist/node_modules/@flakes/console/.output/public/assets/x-Bdsfqbi3.js +1 -0
  87. package/dist/node_modules/@flakes/console/.output/server/{_-DwPiGKLE.mjs → _-BGsKgsbF.mjs} +3 -3
  88. package/dist/node_modules/@flakes/console/.output/server/{_-C-u135Pp.mjs → _-DtPMXzt0.mjs} +3 -3
  89. package/dist/node_modules/@flakes/console/.output/server/_chunks/ProjectsPage.mjs +588 -0
  90. package/dist/node_modules/@flakes/console/.output/server/_chunks/RunPage.mjs +13 -7
  91. package/dist/node_modules/@flakes/console/.output/server/_chunks/RunsPage.mjs +43 -13
  92. package/dist/node_modules/@flakes/console/.output/server/_chunks/SandboxesLens.mjs +1 -1
  93. package/dist/node_modules/@flakes/console/.output/server/_chunks/SandboxesPage.mjs +253 -18
  94. package/dist/node_modules/@flakes/console/.output/server/_chunks/TranscriptPage.mjs +2 -3
  95. package/dist/node_modules/@flakes/console/.output/server/_chunks/bits.mjs +1 -1
  96. package/dist/node_modules/@flakes/console/.output/server/_chunks/button.mjs +461 -3
  97. package/dist/node_modules/@flakes/console/.output/server/_chunks/card.mjs +1 -1
  98. package/dist/node_modules/@flakes/console/.output/server/_chunks/project-navigation.mjs +79 -0
  99. package/dist/node_modules/@flakes/console/.output/server/_chunks/router.mjs +193 -111
  100. package/dist/node_modules/@flakes/console/.output/server/_chunks/table.mjs +1 -1
  101. package/dist/node_modules/@flakes/console/.output/server/_libs/lucide-react.mjs +178 -1
  102. package/dist/node_modules/@flakes/console/.output/server/{_runId-Cag5UaYU.mjs → _runId-P1u-vfcm.mjs} +2 -2
  103. package/dist/node_modules/@flakes/console/.output/server/{_runId-CJ5_8uS8.mjs → _runId-vO4tlCOP.mjs} +3 -3
  104. package/dist/node_modules/@flakes/console/.output/server/_ssr/{App-CwFtUgAz.mjs → App-C-XaVKoO.mjs} +118 -64
  105. package/dist/node_modules/@flakes/console/.output/server/_ssr/{DocumentationPage-CtBAQbzy.mjs → DocumentationPage-BR2KosFz.mjs} +3 -3
  106. package/dist/node_modules/@flakes/console/.output/server/_ssr/ProjectsPage-BUrep1wl.mjs +590 -0
  107. package/dist/node_modules/@flakes/console/.output/server/_ssr/{RunPage-CatpnkFy.mjs → RunPage-BHs-v0LU.mjs} +14 -7
  108. package/dist/node_modules/@flakes/console/.output/server/_ssr/{RunsPage-BmLTih8Z.mjs → RunsPage-iTNYVwL0.mjs} +44 -13
  109. package/dist/node_modules/@flakes/console/.output/server/_ssr/SandboxesPage-C1Z6dVce.mjs +423 -0
  110. package/dist/node_modules/@flakes/console/.output/server/_ssr/{TranscriptPage-DaSIDCKk.mjs → TranscriptPage-BcomoTls.mjs} +3 -3
  111. package/dist/node_modules/@flakes/console/.output/server/_ssr/{account-DzluYS58.mjs → account-Cp0s_IQK.mjs} +2 -2
  112. package/dist/node_modules/@flakes/console/.output/server/_ssr/account-forms-CsothyLo.mjs +1 -1
  113. package/dist/node_modules/@flakes/console/.output/server/_ssr/device-CRZl7dGv.mjs +1 -1
  114. package/dist/node_modules/@flakes/console/.output/server/_ssr/documentation-BnxmM-Yo.mjs +210 -0
  115. package/dist/node_modules/@flakes/console/.output/server/_ssr/{documentation-PC93pMWl.mjs → documentation-Cgyr3VKK.mjs} +3 -3
  116. package/dist/node_modules/@flakes/console/.output/server/_ssr/{hooks-COIYuQzf.mjs → hooks-CsVtQ1m-.mjs} +178 -6
  117. package/dist/node_modules/@flakes/console/.output/server/_ssr/project-navigation-DI77TL9a.mjs +79 -0
  118. package/dist/node_modules/@flakes/console/.output/server/_ssr/projects-R9sxR_t4.mjs +5 -0
  119. package/dist/node_modules/@flakes/console/.output/server/_ssr/reset-password-SmmTixcr.mjs +1 -1
  120. package/dist/node_modules/@flakes/console/.output/server/_ssr/{router-elhBqT5k.mjs → router-CobdI6gO.mjs} +49 -41
  121. package/dist/node_modules/@flakes/console/.output/server/_ssr/runs-D8MHe3QU.mjs +19 -0
  122. package/dist/node_modules/@flakes/console/.output/server/_ssr/{runs-CBkO-RO8.mjs → runs-mTxbc_pm.mjs} +17 -5
  123. package/dist/node_modules/@flakes/console/.output/server/_ssr/{sandboxes-qSX_pfUJ.mjs → sandboxes-B2z_9JyU.mjs} +2 -2
  124. package/dist/node_modules/@flakes/console/.output/server/_ssr/{sandboxes-BIAgn8pu2.mjs → sandboxes-r0y6Ihg6.mjs} +3 -3
  125. package/dist/node_modules/@flakes/console/.output/server/_ssr/signin-form-CQDi-0A5.mjs +1 -1
  126. package/dist/node_modules/@flakes/console/.output/server/_ssr/ssr.mjs +2 -2
  127. package/dist/node_modules/@flakes/console/.output/server/{_tanstack-start-manifest_v-CR_hZXXv.mjs → _tanstack-start-manifest_v-DpAwCFK9.mjs} +53 -46
  128. package/dist/node_modules/@flakes/console/.output/server/{_taskId-BaezvY0w.mjs → _taskId-Cz9xwj5L.mjs} +2 -2
  129. package/dist/node_modules/@flakes/console/.output/server/{_taskId-Da7kHKj9.mjs → _taskId-wQsG2CQj.mjs} +3 -3
  130. package/dist/node_modules/@flakes/console/package.json +1 -1
  131. package/dist/node_modules/@flakes/control-plane/dist/client-access.d.ts +17 -0
  132. package/dist/node_modules/@flakes/control-plane/dist/client-access.d.ts.map +1 -1
  133. package/dist/node_modules/@flakes/control-plane/dist/client-access.js +12 -0
  134. package/dist/node_modules/@flakes/control-plane/dist/client-access.js.map +1 -1
  135. package/dist/node_modules/@flakes/control-plane/dist/host-pool-matching.d.ts +24 -1
  136. package/dist/node_modules/@flakes/control-plane/dist/host-pool-matching.d.ts.map +1 -1
  137. package/dist/node_modules/@flakes/control-plane/dist/host-pool-matching.js +87 -3
  138. package/dist/node_modules/@flakes/control-plane/dist/host-pool-matching.js.map +1 -1
  139. package/dist/node_modules/@flakes/control-plane/dist/host-stream.d.ts.map +1 -1
  140. package/dist/node_modules/@flakes/control-plane/dist/host-stream.js +150 -40
  141. package/dist/node_modules/@flakes/control-plane/dist/host-stream.js.map +1 -1
  142. package/dist/node_modules/@flakes/control-plane/dist/routes/hosts.d.ts.map +1 -1
  143. package/dist/node_modules/@flakes/control-plane/dist/routes/hosts.js +219 -0
  144. package/dist/node_modules/@flakes/control-plane/dist/routes/hosts.js.map +1 -1
  145. package/dist/node_modules/@flakes/control-plane/dist/routes/projects.d.ts +3 -0
  146. package/dist/node_modules/@flakes/control-plane/dist/routes/projects.d.ts.map +1 -0
  147. package/dist/node_modules/@flakes/control-plane/dist/routes/projects.js +226 -0
  148. package/dist/node_modules/@flakes/control-plane/dist/routes/projects.js.map +1 -0
  149. package/dist/node_modules/@flakes/control-plane/dist/routes/runs.d.ts.map +1 -1
  150. package/dist/node_modules/@flakes/control-plane/dist/routes/runs.js +93 -6
  151. package/dist/node_modules/@flakes/control-plane/dist/routes/runs.js.map +1 -1
  152. package/dist/node_modules/@flakes/control-plane/dist/routes/sandboxes.js +48 -3
  153. package/dist/node_modules/@flakes/control-plane/dist/routes/sandboxes.js.map +1 -1
  154. package/dist/node_modules/@flakes/control-plane/dist/routes/tasks.js +2 -2
  155. package/dist/node_modules/@flakes/control-plane/dist/routes/tasks.js.map +1 -1
  156. package/dist/node_modules/@flakes/control-plane/dist/scheduler.d.ts +2 -0
  157. package/dist/node_modules/@flakes/control-plane/dist/scheduler.d.ts.map +1 -1
  158. package/dist/node_modules/@flakes/control-plane/dist/scheduler.js +53 -21
  159. package/dist/node_modules/@flakes/control-plane/dist/scheduler.js.map +1 -1
  160. package/dist/node_modules/@flakes/control-plane/dist/server.d.ts.map +1 -1
  161. package/dist/node_modules/@flakes/control-plane/dist/server.js +2 -0
  162. package/dist/node_modules/@flakes/control-plane/dist/server.js.map +1 -1
  163. package/dist/node_modules/@flakes/control-plane/dist/types.d.ts +2 -0
  164. package/dist/node_modules/@flakes/control-plane/dist/types.d.ts.map +1 -1
  165. package/dist/node_modules/@flakes/control-plane/package.json +1 -1
  166. package/dist/node_modules/@flakes/core/dist/config.d.ts.map +1 -1
  167. package/dist/node_modules/@flakes/core/dist/config.js +6 -2
  168. package/dist/node_modules/@flakes/core/dist/config.js.map +1 -1
  169. package/dist/node_modules/@flakes/core/dist/ids.d.ts +4 -0
  170. package/dist/node_modules/@flakes/core/dist/ids.d.ts.map +1 -1
  171. package/dist/node_modules/@flakes/core/dist/ids.js +2 -0
  172. package/dist/node_modules/@flakes/core/dist/ids.js.map +1 -1
  173. package/dist/node_modules/@flakes/core/dist/runtime.d.ts +1 -1
  174. package/dist/node_modules/@flakes/core/dist/schemas.d.ts +11 -0
  175. package/dist/node_modules/@flakes/core/dist/schemas.d.ts.map +1 -1
  176. package/dist/node_modules/@flakes/core/dist/schemas.js +10 -0
  177. package/dist/node_modules/@flakes/core/dist/schemas.js.map +1 -1
  178. package/dist/node_modules/@flakes/core/package.json +1 -1
  179. package/dist/node_modules/@flakes/harness-agent/package.json +1 -1
  180. package/dist/node_modules/@flakes/harness-sdk/package.json +1 -1
  181. package/dist/node_modules/@flakes/pi-agent/package.json +1 -1
  182. package/dist/node_modules/@flakes/protocol/dist/index.d.ts +1 -1
  183. package/dist/node_modules/@flakes/protocol/dist/index.d.ts.map +1 -1
  184. package/dist/node_modules/@flakes/protocol/dist/index.js +1 -1
  185. package/dist/node_modules/@flakes/protocol/dist/index.js.map +1 -1
  186. package/dist/node_modules/@flakes/protocol/dist/v1.d.ts +317 -0
  187. package/dist/node_modules/@flakes/protocol/dist/v1.d.ts.map +1 -1
  188. package/dist/node_modules/@flakes/protocol/dist/v1.js +50 -1
  189. package/dist/node_modules/@flakes/protocol/dist/v1.js.map +1 -1
  190. package/dist/node_modules/@flakes/protocol/package.json +1 -1
  191. package/dist/node_modules/@flakes/sandbox-runtime/dist/transport.js +3 -6
  192. package/dist/node_modules/@flakes/sandbox-runtime/dist/transport.js.map +1 -1
  193. package/dist/node_modules/@flakes/sandbox-runtime/package.json +1 -1
  194. package/dist/node_modules/@flakes/store/dist/artifacts-events-store.d.ts.map +1 -1
  195. package/dist/node_modules/@flakes/store/dist/artifacts-events-store.js +10 -0
  196. package/dist/node_modules/@flakes/store/dist/artifacts-events-store.js.map +1 -1
  197. package/dist/node_modules/@flakes/store/dist/host-provisioning-limits.d.ts +2 -1
  198. package/dist/node_modules/@flakes/store/dist/host-provisioning-limits.d.ts.map +1 -1
  199. package/dist/node_modules/@flakes/store/dist/host-provisioning-limits.js +1 -0
  200. package/dist/node_modules/@flakes/store/dist/host-provisioning-limits.js.map +1 -1
  201. package/dist/node_modules/@flakes/store/dist/kysely-store.d.ts +2 -2
  202. package/dist/node_modules/@flakes/store/dist/kysely-store.d.ts.map +1 -1
  203. package/dist/node_modules/@flakes/store/dist/kysely-store.js +2 -2
  204. package/dist/node_modules/@flakes/store/dist/kysely-store.js.map +1 -1
  205. package/dist/node_modules/@flakes/store/dist/managed-sandbox-instances-store.d.ts +14 -2
  206. package/dist/node_modules/@flakes/store/dist/managed-sandbox-instances-store.d.ts.map +1 -1
  207. package/dist/node_modules/@flakes/store/dist/managed-sandbox-instances-store.js +567 -9
  208. package/dist/node_modules/@flakes/store/dist/managed-sandbox-instances-store.js.map +1 -1
  209. package/dist/node_modules/@flakes/store/dist/mappers.d.ts +10 -2
  210. package/dist/node_modules/@flakes/store/dist/mappers.d.ts.map +1 -1
  211. package/dist/node_modules/@flakes/store/dist/mappers.js +46 -0
  212. package/dist/node_modules/@flakes/store/dist/mappers.js.map +1 -1
  213. package/dist/node_modules/@flakes/store/dist/projects-store.d.ts +42 -0
  214. package/dist/node_modules/@flakes/store/dist/projects-store.d.ts.map +1 -0
  215. package/dist/node_modules/@flakes/store/dist/projects-store.js +376 -0
  216. package/dist/node_modules/@flakes/store/dist/projects-store.js.map +1 -0
  217. package/dist/node_modules/@flakes/store/dist/runs-store.d.ts.map +1 -1
  218. package/dist/node_modules/@flakes/store/dist/runs-store.js +7 -2
  219. package/dist/node_modules/@flakes/store/dist/runs-store.js.map +1 -1
  220. package/dist/node_modules/@flakes/store/dist/schema.js +72 -0
  221. package/dist/node_modules/@flakes/store/dist/schema.js.map +1 -1
  222. package/dist/node_modules/@flakes/store/dist/store-base.d.ts +14 -12
  223. package/dist/node_modules/@flakes/store/dist/store-base.d.ts.map +1 -1
  224. package/dist/node_modules/@flakes/store/dist/tables.d.ts +41 -1
  225. package/dist/node_modules/@flakes/store/dist/tables.d.ts.map +1 -1
  226. package/dist/node_modules/@flakes/store/dist/tasks-store.d.ts.map +1 -1
  227. package/dist/node_modules/@flakes/store/dist/tasks-store.js +9 -2
  228. package/dist/node_modules/@flakes/store/dist/tasks-store.js.map +1 -1
  229. package/dist/node_modules/@flakes/store/dist/types.d.ts +189 -2
  230. package/dist/node_modules/@flakes/store/dist/types.d.ts.map +1 -1
  231. package/dist/node_modules/@flakes/store/package.json +1 -1
  232. package/package.json +1 -1
  233. package/dist/node_modules/@flakes/console/.output/public/assets/DocumentationPage-DM-ZYPgQ.js +0 -1
  234. package/dist/node_modules/@flakes/console/.output/public/assets/RunPage-i03UqHYF.js +0 -3
  235. package/dist/node_modules/@flakes/console/.output/public/assets/RunsPage-u8qbeAoV.js +0 -1
  236. package/dist/node_modules/@flakes/console/.output/public/assets/SandboxesLens-BUQQWmH6.js +0 -1
  237. package/dist/node_modules/@flakes/console/.output/public/assets/SandboxesPage-D8D_5kXP.js +0 -1
  238. package/dist/node_modules/@flakes/console/.output/public/assets/TranscriptPage-ChoFjiPI.js +0 -1
  239. package/dist/node_modules/@flakes/console/.output/public/assets/_-C4ecJpHe.js +0 -1
  240. package/dist/node_modules/@flakes/console/.output/public/assets/_runId-BZXYFY32.js +0 -2
  241. package/dist/node_modules/@flakes/console/.output/public/assets/_taskId-C28oHEU_.js +0 -2
  242. package/dist/node_modules/@flakes/console/.output/public/assets/account-B4wDEC7t.js +0 -1
  243. package/dist/node_modules/@flakes/console/.output/public/assets/account-forms-BLo66Mqa.js +0 -1
  244. package/dist/node_modules/@flakes/console/.output/public/assets/arrow-right-BMW8fJP5.js +0 -1
  245. package/dist/node_modules/@flakes/console/.output/public/assets/auth-layout-DiUSgtaY.js +0 -1
  246. package/dist/node_modules/@flakes/console/.output/public/assets/bits-Cv0Te4iz.js +0 -1
  247. package/dist/node_modules/@flakes/console/.output/public/assets/card-DSG3_teC.js +0 -1
  248. package/dist/node_modules/@flakes/console/.output/public/assets/circle-check-B0gtb8OH.js +0 -1
  249. package/dist/node_modules/@flakes/console/.output/public/assets/device-NrLWypMd.js +0 -1
  250. package/dist/node_modules/@flakes/console/.output/public/assets/dist-BtPw3IIV.js +0 -1
  251. package/dist/node_modules/@flakes/console/.output/public/assets/documentation-NRDmcDud.js +0 -1
  252. package/dist/node_modules/@flakes/console/.output/public/assets/forgot-password--3Mujc8s.js +0 -1
  253. package/dist/node_modules/@flakes/console/.output/public/assets/link-BsixJinJ.js +0 -1
  254. package/dist/node_modules/@flakes/console/.output/public/assets/main-KBvz0mSQ.js +0 -1055
  255. package/dist/node_modules/@flakes/console/.output/public/assets/matchContext-tJ0VTv5m.js +0 -1
  256. package/dist/node_modules/@flakes/console/.output/public/assets/otp-verification-BSXwS5bo.js +0 -20
  257. package/dist/node_modules/@flakes/console/.output/public/assets/react-DtOYBmep.js +0 -1
  258. package/dist/node_modules/@flakes/console/.output/public/assets/react-dom-DrIU40PY.js +0 -1
  259. package/dist/node_modules/@flakes/console/.output/public/assets/redirect-BEm0VK76.js +0 -1
  260. package/dist/node_modules/@flakes/console/.output/public/assets/reset-password-C7SbNx2J.js +0 -1
  261. package/dist/node_modules/@flakes/console/.output/public/assets/runs-xD4ynllK.js +0 -2
  262. package/dist/node_modules/@flakes/console/.output/public/assets/sandboxes-Cfr1Y2Dn.js +0 -2
  263. package/dist/node_modules/@flakes/console/.output/public/assets/security-CCThSJae.js +0 -1
  264. package/dist/node_modules/@flakes/console/.output/public/assets/signin-CYeR3TaY.js +0 -1
  265. package/dist/node_modules/@flakes/console/.output/public/assets/signin-form-Bp22jPob.js +0 -1
  266. package/dist/node_modules/@flakes/console/.output/public/assets/signup-DHhPfohX.js +0 -1
  267. package/dist/node_modules/@flakes/console/.output/public/assets/styles-8wEqfToJ.css +0 -2
  268. package/dist/node_modules/@flakes/console/.output/public/assets/table-DptQuuuq.js +0 -1
  269. package/dist/node_modules/@flakes/console/.output/public/assets/user-DK27uFod.js +0 -1
  270. package/dist/node_modules/@flakes/console/.output/public/assets/utils-CEE0-YEp.js +0 -1
  271. package/dist/node_modules/@flakes/console/.output/public/assets/x-fKvnmCoQ.js +0 -1
  272. package/dist/node_modules/@flakes/console/.output/server/_chunks/utils.mjs +0 -285
  273. package/dist/node_modules/@flakes/console/.output/server/_ssr/SandboxesPage-Dlq0Ga24.mjs +0 -187
  274. package/dist/node_modules/@flakes/console/.output/server/_ssr/documentation-Bf0VPrnt.mjs +0 -210
  275. package/dist/node_modules/@flakes/console/.output/server/_ssr/runs-BzfGldVd.mjs +0 -12
@@ -4,7 +4,17 @@ import { HOST_PROVISIONING_QUOTAS, HostProvisioningQuotaError, jsonByteLength, }
4
4
  import { addMs, fromJson, toJson } from "./json.js";
5
5
  import { mapHost, mapHostCredential, mapHostPool, mapManagedSandboxInstance, mapProvisioningLease, mapSandboxCredential, mapSandboxIdentity, } from "./mappers.js";
6
6
  const nonTerminalManagedInstanceStatuses = ["pending_launch", "launching", "running", "draining", "stopping"];
7
- const cleanupManagedInstanceStatuses = ["stopped", "failed", "expired", "cancelled"];
7
+ const cleanupManagedInstanceStatuses = ["stopped", "failed", "expired", "cancelled", "deleting"];
8
+ const noProviderDeleteManagedInstanceStatuses = [
9
+ "stopped",
10
+ "failed",
11
+ "expired",
12
+ "cancelled",
13
+ "running",
14
+ "draining",
15
+ "stopping",
16
+ ];
17
+ const providerDeleteManagedInstanceStatuses = [...noProviderDeleteManagedInstanceStatuses, "deleting"];
8
18
  const nonTerminalProvisioningLeaseStates = [
9
19
  "pending",
10
20
  "claimed",
@@ -38,6 +48,7 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
38
48
  owner_key: input.ownerKey,
39
49
  name,
40
50
  status: input.status ?? "created",
51
+ project_workspace_root: null,
41
52
  last_seen_at: null,
42
53
  connection_id: null,
43
54
  stream_generation: 0,
@@ -261,6 +272,7 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
261
272
  "host.owner_key as auth_host_owner_key",
262
273
  "host.name as auth_host_name",
263
274
  "host.status as auth_host_status",
275
+ "host.project_workspace_root as auth_host_project_workspace_root",
264
276
  "host.last_seen_at as auth_host_last_seen_at",
265
277
  "host.connection_id as auth_host_connection_id",
266
278
  "host.stream_generation as auth_host_stream_generation",
@@ -404,6 +416,7 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
404
416
  owner_key: input.ownerKey,
405
417
  name: input.hostName,
406
418
  status: "created",
419
+ project_workspace_root: null,
407
420
  last_seen_at: null,
408
421
  connection_id: null,
409
422
  stream_generation: 0,
@@ -930,6 +943,7 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
930
943
  owner_kind: input.ownerKind,
931
944
  owner_id: input.ownerId,
932
945
  owner_key: input.ownerKey,
946
+ project_id: input.projectId ?? null,
933
947
  host_id: input.hostId,
934
948
  host_pool_id: input.hostPoolId,
935
949
  pool_id: input.hostPoolId,
@@ -1057,6 +1071,261 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
1057
1071
  clearedAssignments: cleared.cleared,
1058
1072
  };
1059
1073
  }
1074
+ /** Deletes or queues cleanup for an owner-scoped stale managed sandbox row. */
1075
+ async deleteManagedSandboxInstance(input) {
1076
+ return this.withTransaction(async (trx) => {
1077
+ const liveness = await this.lockManagedSandboxLiveness(trx, input.sandboxId);
1078
+ const instance = await trx
1079
+ .selectFrom("managed_sandbox_instances as instance")
1080
+ .innerJoin("sandbox_identities as identity", "identity.sandbox_id", "instance.sandbox_id")
1081
+ .select([
1082
+ "instance.instance_id as instance_id",
1083
+ "instance.owner_kind as owner_kind",
1084
+ "instance.owner_id as owner_id",
1085
+ "instance.owner_key as owner_key",
1086
+ "instance.project_id as project_id",
1087
+ "instance.host_id as host_id",
1088
+ "instance.host_pool_id as host_pool_id",
1089
+ "instance.sandbox_id as sandbox_id",
1090
+ "instance.status as status",
1091
+ "instance.provider_resource_id as provider_resource_id",
1092
+ "identity.sandbox_identity_id as sandbox_identity_id",
1093
+ "identity.disabled_at as identity_disabled_at",
1094
+ ])
1095
+ .where("instance.owner_key", "=", input.ownerKey)
1096
+ .where("instance.sandbox_id", "=", input.sandboxId)
1097
+ .where("identity.owner_key", "=", input.ownerKey)
1098
+ .forUpdate()
1099
+ .executeTakeFirst();
1100
+ if (!instance) {
1101
+ return { status: "not_found" };
1102
+ }
1103
+ const blockers = [];
1104
+ const providerResourceId = instance.provider_resource_id;
1105
+ const eligibleStatuses = providerResourceId === null
1106
+ ? noProviderDeleteManagedInstanceStatuses
1107
+ : providerDeleteManagedInstanceStatuses;
1108
+ if (!eligibleStatuses.includes(instance.status)) {
1109
+ blockers.push("unsafe_status");
1110
+ }
1111
+ if (liveness?.status === "active") {
1112
+ blockers.push("live_sandbox");
1113
+ }
1114
+ if (blockers.length > 0) {
1115
+ return {
1116
+ status: "blocked",
1117
+ sandboxId: input.sandboxId,
1118
+ blockers,
1119
+ };
1120
+ }
1121
+ const latestLiveness = liveness ??
1122
+ (await this.lockManagedSandboxLiveness(trx, input.sandboxId));
1123
+ if (latestLiveness?.status === "active") {
1124
+ return {
1125
+ status: "blocked",
1126
+ sandboxId: input.sandboxId,
1127
+ blockers: ["live_sandbox"],
1128
+ };
1129
+ }
1130
+ const hostPoolId = instance.host_pool_id;
1131
+ if (providerResourceId !== null) {
1132
+ if (hostPoolId === null) {
1133
+ return {
1134
+ status: "blocked",
1135
+ sandboxId: input.sandboxId,
1136
+ blockers: ["provider_cleanup_required"],
1137
+ };
1138
+ }
1139
+ if (await this.managedSandboxHasAcceptedRunningAssignments(trx, input.sandboxId)) {
1140
+ return {
1141
+ status: "blocked",
1142
+ sandboxId: input.sandboxId,
1143
+ blockers: ["accepted_running_assignments"],
1144
+ };
1145
+ }
1146
+ const clearedAssignments = await this.clearReservedSandboxAssignmentsForDelete(trx, input.sandboxId);
1147
+ const now = this.nowIso();
1148
+ const reason = redactReason(input.reason) ?? "managed sandbox deleted";
1149
+ await this.cancelSupersededProviderStopLeasesForDelete(trx, {
1150
+ ownerKey: instance.owner_key,
1151
+ hostId: instance.host_id,
1152
+ instanceId: instance.instance_id,
1153
+ }, now, reason);
1154
+ const cleanupLease = await this.queueManagedSandboxDeleteCleanup(trx, {
1155
+ instanceId: instance.instance_id,
1156
+ ownerKind: instance.owner_kind,
1157
+ ownerId: instance.owner_id,
1158
+ ownerKey: instance.owner_key,
1159
+ projectId: instance.project_id,
1160
+ hostId: instance.host_id,
1161
+ hostPoolId,
1162
+ sandboxId: instance.sandbox_id,
1163
+ providerResourceId,
1164
+ }, now);
1165
+ await trx
1166
+ .updateTable("managed_sandbox_instances")
1167
+ .set({
1168
+ status: "deleting",
1169
+ last_error: reason,
1170
+ updated_at: now,
1171
+ })
1172
+ .where("instance_id", "=", instance.instance_id)
1173
+ .where("owner_key", "=", input.ownerKey)
1174
+ .where("sandbox_id", "=", input.sandboxId)
1175
+ .where("provider_resource_id", "=", providerResourceId)
1176
+ .where("status", "in", [...providerDeleteManagedInstanceStatuses])
1177
+ .executeTakeFirst();
1178
+ await this.invalidateManagedSandboxRuntimeAuthForDelete(trx, {
1179
+ sandboxIdentityId: instance.sandbox_identity_id,
1180
+ identityDisabledAt: instance.identity_disabled_at,
1181
+ reason,
1182
+ now,
1183
+ });
1184
+ return {
1185
+ status: "cleanup_queued",
1186
+ sandboxId: input.sandboxId,
1187
+ instanceId: instance.instance_id,
1188
+ leaseId: cleanupLease.leaseId,
1189
+ providerResourceId,
1190
+ clearedAssignments,
1191
+ };
1192
+ }
1193
+ if (await this.managedSandboxHasAcceptedRunningAssignments(trx, input.sandboxId)) {
1194
+ return {
1195
+ status: "blocked",
1196
+ sandboxId: input.sandboxId,
1197
+ blockers: ["accepted_running_assignments"],
1198
+ };
1199
+ }
1200
+ const clearedAssignments = await this.clearReservedSandboxAssignmentsForDelete(trx, input.sandboxId);
1201
+ const now = this.nowIso();
1202
+ const reason = redactReason(input.reason) ?? "managed sandbox deleted";
1203
+ await this.invalidateManagedSandboxRuntimeAuthForDelete(trx, {
1204
+ sandboxIdentityId: instance.sandbox_identity_id,
1205
+ identityDisabledAt: instance.identity_disabled_at,
1206
+ reason,
1207
+ now,
1208
+ });
1209
+ await trx
1210
+ .deleteFrom("managed_sandbox_instances")
1211
+ .where("instance_id", "=", instance.instance_id)
1212
+ .where("owner_key", "=", input.ownerKey)
1213
+ .where("sandbox_id", "=", input.sandboxId)
1214
+ .executeTakeFirst();
1215
+ return {
1216
+ status: "deleted",
1217
+ sandboxId: input.sandboxId,
1218
+ instanceId: instance.instance_id,
1219
+ clearedAssignments,
1220
+ };
1221
+ });
1222
+ }
1223
+ async invalidateManagedSandboxRuntimeAuthForDelete(executor, input) {
1224
+ await executor
1225
+ .updateTable("sandbox_credentials")
1226
+ .set({
1227
+ revoked_at: input.now,
1228
+ revoked_reason: input.reason,
1229
+ updated_at: input.now,
1230
+ })
1231
+ .where("sandbox_identity_id", "=", input.sandboxIdentityId)
1232
+ .where("revoked_at", "is", null)
1233
+ .execute();
1234
+ await executor
1235
+ .updateTable("sandbox_identities")
1236
+ .set({
1237
+ status: "disabled",
1238
+ disabled_at: input.identityDisabledAt ?? input.now,
1239
+ updated_at: input.now,
1240
+ })
1241
+ .where("sandbox_identity_id", "=", input.sandboxIdentityId)
1242
+ .execute();
1243
+ }
1244
+ async queueManagedSandboxDeleteCleanup(executor, instance, now) {
1245
+ const existing = await executor
1246
+ .selectFrom("provisioning_leases")
1247
+ .selectAll()
1248
+ .where("owner_key", "=", instance.ownerKey)
1249
+ .where("host_id", "=", instance.hostId)
1250
+ .where("instance_id", "=", instance.instanceId)
1251
+ .where("action", "=", "provider_cleanup")
1252
+ .where("state", "in", [...nonTerminalProvisioningLeaseStates])
1253
+ .forUpdate()
1254
+ .executeTakeFirst();
1255
+ if (existing) {
1256
+ if (existing.state === "pending" && existing.lease_deadline_at <= now) {
1257
+ const refreshed = await executor
1258
+ .updateTable("provisioning_leases")
1259
+ .set({
1260
+ lease_deadline_at: addMs(this.clock.now(), providerCleanupLeaseTtlMs),
1261
+ last_error: null,
1262
+ updated_at: now,
1263
+ })
1264
+ .where("lease_id", "=", existing.lease_id)
1265
+ .where("owner_key", "=", instance.ownerKey)
1266
+ .where("host_id", "=", instance.hostId)
1267
+ .where("action", "=", "provider_cleanup")
1268
+ .where("state", "=", "pending")
1269
+ .returningAll()
1270
+ .executeTakeFirst();
1271
+ return mapProvisioningLease(refreshed ?? existing);
1272
+ }
1273
+ return mapProvisioningLease(existing);
1274
+ }
1275
+ await this.assertProvisioningLeaseQuota(executor, instance.ownerKey);
1276
+ const row = await executor
1277
+ .insertInto("provisioning_leases")
1278
+ .values({
1279
+ lease_id: this.idGenerator.createId("provisioning_lease"),
1280
+ owner_kind: instance.ownerKind,
1281
+ owner_id: instance.ownerId,
1282
+ owner_key: instance.ownerKey,
1283
+ project_id: instance.projectId,
1284
+ host_project_binding_id: null,
1285
+ host_id: instance.hostId,
1286
+ host_pool_id: instance.hostPoolId,
1287
+ instance_id: instance.instanceId,
1288
+ sandbox_id: instance.sandboxId,
1289
+ demand_task_id: null,
1290
+ action: "provider_cleanup",
1291
+ state: "pending",
1292
+ claim_id: null,
1293
+ attempt: 0,
1294
+ max_attempts: providerCleanupLeaseMaxAttempts,
1295
+ lease_deadline_at: addMs(this.clock.now(), providerCleanupLeaseTtlMs),
1296
+ claim_deadline_at: null,
1297
+ hello_deadline_at: null,
1298
+ accepted_at: null,
1299
+ running_at: null,
1300
+ completed_at: null,
1301
+ credential_ref: null,
1302
+ provider_resource_id: instance.providerResourceId,
1303
+ provider_result_json: null,
1304
+ last_error: null,
1305
+ release_audit_json: null,
1306
+ created_at: now,
1307
+ updated_at: now,
1308
+ })
1309
+ .returningAll()
1310
+ .executeTakeFirstOrThrow();
1311
+ return mapProvisioningLease(row);
1312
+ }
1313
+ async cancelSupersededProviderStopLeasesForDelete(executor, input, now, reason) {
1314
+ await executor
1315
+ .updateTable("provisioning_leases")
1316
+ .set({
1317
+ state: "cancelled",
1318
+ completed_at: now,
1319
+ last_error: reason,
1320
+ updated_at: now,
1321
+ })
1322
+ .where("owner_key", "=", input.ownerKey)
1323
+ .where("host_id", "=", input.hostId)
1324
+ .where("instance_id", "=", input.instanceId)
1325
+ .where("action", "=", "provider_stop")
1326
+ .where("state", "in", [...nonTerminalProvisioningLeaseStates])
1327
+ .execute();
1328
+ }
1060
1329
  /** Returns one owner/host-scoped provisioning lease. */
1061
1330
  async getProvisioningLease(input) {
1062
1331
  const row = await this.db
@@ -1111,6 +1380,25 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
1111
1380
  if (input.maxAttempts <= 0) {
1112
1381
  throw new Error("lease maxAttempts must be positive");
1113
1382
  }
1383
+ const projectId = input.projectId ?? instance.project_id;
1384
+ if (projectId !== instance.project_id) {
1385
+ throw new Error("launch lease project mismatch");
1386
+ }
1387
+ if (projectId !== null && input.hostProjectBindingId === undefined) {
1388
+ throw new Error("host project binding is required for project launch");
1389
+ }
1390
+ if (projectId === null && input.hostProjectBindingId !== undefined) {
1391
+ throw new Error("host project binding requires project launch");
1392
+ }
1393
+ if (projectId !== null && input.hostProjectBindingId !== undefined) {
1394
+ await this.requireActiveHostProjectBindingForPool(trx, {
1395
+ ownerKey: input.ownerKey,
1396
+ hostId: input.hostId,
1397
+ projectId,
1398
+ hostProjectBindingId: input.hostProjectBindingId,
1399
+ hostPoolId: input.hostPoolId,
1400
+ });
1401
+ }
1114
1402
  await this.assertProvisioningLeaseQuota(trx, input.ownerKey);
1115
1403
  const now = this.nowIso();
1116
1404
  const leaseId = input.leaseId ?? this.idGenerator.createId("provisioning_lease");
@@ -1122,6 +1410,8 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
1122
1410
  owner_kind: host.owner_kind,
1123
1411
  owner_id: host.owner_id,
1124
1412
  owner_key: host.owner_key,
1413
+ project_id: projectId,
1414
+ host_project_binding_id: input.hostProjectBindingId ?? null,
1125
1415
  host_id: input.hostId,
1126
1416
  host_pool_id: input.hostPoolId,
1127
1417
  instance_id: input.instanceId,
@@ -1229,6 +1519,8 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
1229
1519
  owner_kind: host.owner_kind,
1230
1520
  owner_id: host.owner_id,
1231
1521
  owner_key: host.owner_key,
1522
+ project_id: instance.project_id,
1523
+ host_project_binding_id: null,
1232
1524
  host_id: input.hostId,
1233
1525
  host_pool_id: instance.host_pool_id,
1234
1526
  instance_id: input.instanceId,
@@ -1335,6 +1627,8 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
1335
1627
  owner_kind: host.owner_kind,
1336
1628
  owner_id: host.owner_id,
1337
1629
  owner_key: host.owner_key,
1630
+ project_id: instance.project_id,
1631
+ host_project_binding_id: null,
1338
1632
  host_id: input.hostId,
1339
1633
  host_pool_id: instance.host_pool_id,
1340
1634
  instance_id: input.instanceId,
@@ -1462,6 +1756,43 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
1462
1756
  !hasAllCapabilities(poolCapabilities, requiredCapabilities)) {
1463
1757
  return { status: "skipped", reason: "pool_mismatch" };
1464
1758
  }
1759
+ const taskProjectId = task.project_id;
1760
+ if (taskProjectId === null) {
1761
+ return { status: "skipped", reason: "pool_mismatch" };
1762
+ }
1763
+ if (input.projectId !== undefined &&
1764
+ input.projectId !== taskProjectId) {
1765
+ return { status: "skipped", reason: "pool_mismatch" };
1766
+ }
1767
+ if (taskProjectId !== null) {
1768
+ if (input.hostProjectBindingId === undefined) {
1769
+ return { status: "skipped", reason: "pool_mismatch" };
1770
+ }
1771
+ const binding = await trx
1772
+ .selectFrom("host_project_bindings as binding")
1773
+ .innerJoin("projects as project", (join) => join
1774
+ .onRef("project.project_id", "=", "binding.project_id")
1775
+ .onRef("project.owner_key", "=", "binding.owner_key"))
1776
+ .select([
1777
+ "binding.allowed_pool_keys_json",
1778
+ "binding.availability",
1779
+ "project.status as project_status",
1780
+ ])
1781
+ .where("binding.binding_id", "=", input.hostProjectBindingId)
1782
+ .where("binding.owner_key", "=", input.ownerKey)
1783
+ .where("binding.host_id", "=", input.hostId)
1784
+ .where("binding.project_id", "=", taskProjectId)
1785
+ .forUpdate()
1786
+ .executeTakeFirst();
1787
+ const allowedPoolKeys = binding
1788
+ ? (fromJson(binding.allowed_pool_keys_json) ?? [])
1789
+ : [];
1790
+ if (binding?.project_status !== "active" ||
1791
+ binding.availability !== "available" ||
1792
+ !allowedPoolKeys.includes(pool.pool_key)) {
1793
+ return { status: "skipped", reason: "pool_mismatch" };
1794
+ }
1795
+ }
1465
1796
  const activeInstances = await trx
1466
1797
  .selectFrom("managed_sandbox_instances")
1467
1798
  .select(sql `count(*)::text`.as("count"))
@@ -1500,6 +1831,7 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
1500
1831
  owner_kind: input.ownerKind,
1501
1832
  owner_id: input.ownerId,
1502
1833
  owner_key: input.ownerKey,
1834
+ project_id: task.project_id,
1503
1835
  host_id: input.hostId,
1504
1836
  host_pool_id: input.hostPoolId,
1505
1837
  pool_id: input.hostPoolId,
@@ -1523,6 +1855,8 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
1523
1855
  owner_kind: host.owner_kind,
1524
1856
  owner_id: host.owner_id,
1525
1857
  owner_key: host.owner_key,
1858
+ project_id: task.project_id,
1859
+ host_project_binding_id: input.hostProjectBindingId ?? null,
1526
1860
  host_id: input.hostId,
1527
1861
  host_pool_id: input.hostPoolId,
1528
1862
  instance_id: instanceRow.instance_id,
@@ -1606,15 +1940,30 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
1606
1940
  "available") {
1607
1941
  return [];
1608
1942
  }
1609
- const now = this.nowIso();
1943
+ const nowDate = this.clock.now();
1944
+ const now = nowDate.toISOString();
1610
1945
  const candidates = await trx
1611
1946
  .selectFrom("provisioning_leases as lease")
1612
1947
  .innerJoin("host_pools as pool", "pool.host_pool_id", "lease.host_pool_id")
1613
1948
  .innerJoin("managed_sandbox_instances as instance", "instance.instance_id", "lease.instance_id")
1614
1949
  .innerJoin("sandbox_identities as identity", "identity.sandbox_id", "lease.sandbox_id")
1615
- .select(["lease.lease_id"])
1950
+ .innerJoin("projects as project", (join) => join
1951
+ .onRef("project.project_id", "=", "lease.project_id")
1952
+ .onRef("project.owner_key", "=", "lease.owner_key"))
1953
+ .innerJoin("host_project_bindings as binding", (join) => join
1954
+ .onRef("binding.binding_id", "=", "lease.host_project_binding_id")
1955
+ .onRef("binding.project_id", "=", "lease.project_id")
1956
+ .onRef("binding.owner_key", "=", "lease.owner_key")
1957
+ .onRef("binding.host_id", "=", "lease.host_id"))
1958
+ .select([
1959
+ "lease.lease_id",
1960
+ "binding.binding_id as host_project_binding_id",
1961
+ "project.project_key",
1962
+ ])
1616
1963
  .where("lease.owner_key", "=", input.ownerKey)
1617
1964
  .where("lease.host_id", "=", input.hostId)
1965
+ .where("lease.project_id", "is not", null)
1966
+ .whereRef("instance.project_id", "=", "lease.project_id")
1618
1967
  .where("lease.action", "=", "launch")
1619
1968
  .where("lease.state", "=", "pending")
1620
1969
  .where("lease.lease_deadline_at", ">", now)
@@ -1622,6 +1971,13 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
1622
1971
  .where("pool.owner_key", "=", input.ownerKey)
1623
1972
  .where("pool.host_id", "=", input.hostId)
1624
1973
  .where("pool.status", "=", "available")
1974
+ .where("project.status", "=", "active")
1975
+ .where("binding.availability", "=", "available")
1976
+ .where(sql `exists (
1977
+ select 1
1978
+ from jsonb_array_elements_text(binding.allowed_pool_keys_json::jsonb) as allowed(pool_key)
1979
+ where allowed.pool_key = pool.pool_key
1980
+ )`)
1625
1981
  .where("instance.owner_key", "=", input.ownerKey)
1626
1982
  .whereRef("instance.host_id", "=", "lease.host_id")
1627
1983
  .whereRef("instance.host_pool_id", "=", "lease.host_pool_id")
@@ -1652,7 +2008,12 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
1652
2008
  hostStreamFence: input.hostStreamFence,
1653
2009
  });
1654
2010
  if (result?.credential) {
1655
- claimed.push(result);
2011
+ claimed.push({
2012
+ lease: result.lease,
2013
+ credential: result.credential,
2014
+ hostProjectBindingId: candidate.host_project_binding_id,
2015
+ projectKey: candidate.project_key,
2016
+ });
1656
2017
  }
1657
2018
  }
1658
2019
  return claimed;
@@ -1680,7 +2041,8 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
1680
2041
  action: "provider_stop",
1681
2042
  limit,
1682
2043
  });
1683
- const now = this.nowIso();
2044
+ const nowDate = this.clock.now();
2045
+ const now = nowDate.toISOString();
1684
2046
  const candidates = await trx
1685
2047
  .selectFrom("provisioning_leases as lease")
1686
2048
  .innerJoin("host_pools as pool", "pool.host_pool_id", "lease.host_pool_id")
@@ -1746,17 +2108,26 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
1746
2108
  action: "provider_cleanup",
1747
2109
  limit,
1748
2110
  });
1749
- const now = this.nowIso();
2111
+ const nowDate = this.clock.now();
2112
+ const now = nowDate.toISOString();
1750
2113
  const candidates = await trx
1751
2114
  .selectFrom("provisioning_leases as lease")
1752
2115
  .innerJoin("host_pools as pool", "pool.host_pool_id", "lease.host_pool_id")
1753
2116
  .innerJoin("managed_sandbox_instances as instance", "instance.instance_id", "lease.instance_id")
1754
- .select(["lease.lease_id", "pool.provider"])
2117
+ .select([
2118
+ "lease.lease_id",
2119
+ "lease.lease_deadline_at",
2120
+ "pool.provider",
2121
+ "instance.status as instance_status",
2122
+ ])
1755
2123
  .where("lease.owner_key", "=", input.ownerKey)
1756
2124
  .where("lease.host_id", "=", input.hostId)
1757
2125
  .where("lease.action", "=", "provider_cleanup")
1758
2126
  .where("lease.state", "=", "pending")
1759
- .where("lease.lease_deadline_at", ">", now)
2127
+ .where((eb) => eb.or([
2128
+ eb("lease.lease_deadline_at", ">", now),
2129
+ eb("instance.status", "=", "deleting"),
2130
+ ]))
1760
2131
  .where("lease.provider_resource_id", "is not", null)
1761
2132
  .where("pool.owner_key", "=", input.ownerKey)
1762
2133
  .where("pool.host_id", "=", input.hostId)
@@ -1773,6 +2144,25 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
1773
2144
  .execute();
1774
2145
  const claimed = [];
1775
2146
  for (const candidate of candidates) {
2147
+ if (candidate.instance_status === "deleting" &&
2148
+ candidate.lease_deadline_at <= now) {
2149
+ const refreshed = await trx
2150
+ .updateTable("provisioning_leases")
2151
+ .set({
2152
+ lease_deadline_at: addMs(nowDate, providerCleanupLeaseTtlMs),
2153
+ last_error: null,
2154
+ updated_at: now,
2155
+ })
2156
+ .where("lease_id", "=", candidate.lease_id)
2157
+ .where("owner_key", "=", input.ownerKey)
2158
+ .where("host_id", "=", input.hostId)
2159
+ .where("action", "=", "provider_cleanup")
2160
+ .where("state", "=", "pending")
2161
+ .executeTakeFirst();
2162
+ if (refreshed.numUpdatedRows === 0n) {
2163
+ continue;
2164
+ }
2165
+ }
1776
2166
  const result = await this.claimLeaseInTransaction(trx, {
1777
2167
  ownerKey: input.ownerKey,
1778
2168
  hostId: input.hostId,
@@ -2147,6 +2537,8 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
2147
2537
  owner_kind: current.owner_kind,
2148
2538
  owner_id: current.owner_id,
2149
2539
  owner_key: current.owner_key,
2540
+ project_id: current.project_id,
2541
+ host_project_binding_id: current.host_project_binding_id,
2150
2542
  host_id: current.host_id,
2151
2543
  host_pool_id: current.host_pool_id,
2152
2544
  instance_id: current.instance_id,
@@ -2263,6 +2655,20 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
2263
2655
  if (!instanceRow) {
2264
2656
  return { status: "rejected" };
2265
2657
  }
2658
+ const deletingIdentity = input.status === "succeeded" && instanceRow.status === "deleting"
2659
+ ? await trx
2660
+ .selectFrom("sandbox_identities")
2661
+ .select(["sandbox_identity_id", "disabled_at"])
2662
+ .where("owner_key", "=", current.owner_key)
2663
+ .where("sandbox_id", "=", current.sandbox_id ?? "")
2664
+ .forUpdate()
2665
+ .executeTakeFirst()
2666
+ : undefined;
2667
+ if (input.status === "succeeded" && instanceRow.status === "deleting") {
2668
+ if (!deletingIdentity) {
2669
+ return { status: "rejected" };
2670
+ }
2671
+ }
2266
2672
  const row = await trx
2267
2673
  .updateTable("provisioning_leases")
2268
2674
  .set({
@@ -2288,6 +2694,22 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
2288
2694
  if (!row) {
2289
2695
  throw new Error("failed to record provider cleanup lease result");
2290
2696
  }
2697
+ if (deletingIdentity) {
2698
+ await this.invalidateManagedSandboxRuntimeAuthForDelete(trx, {
2699
+ sandboxIdentityId: deletingIdentity.sandbox_identity_id,
2700
+ identityDisabledAt: deletingIdentity.disabled_at,
2701
+ reason: redactReason(input.reason) ?? "managed sandbox deleted",
2702
+ now,
2703
+ });
2704
+ await trx
2705
+ .deleteFrom("managed_sandbox_instances")
2706
+ .where("instance_id", "=", current.instance_id)
2707
+ .where("owner_key", "=", current.owner_key)
2708
+ .where("host_id", "=", current.host_id)
2709
+ .where("status", "=", "deleting")
2710
+ .where("provider_resource_id", "is", null)
2711
+ .executeTakeFirst();
2712
+ }
2291
2713
  return {
2292
2714
  status: "recorded",
2293
2715
  lease: mapProvisioningLease(row),
@@ -2477,7 +2899,7 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
2477
2899
  if (current.action === "launch" && current.host_pool_id !== null) {
2478
2900
  const pool = await trx
2479
2901
  .selectFrom("host_pools")
2480
- .select(["status"])
2902
+ .select(["pool_key", "status"])
2481
2903
  .where("host_pool_id", "=", current.host_pool_id)
2482
2904
  .where("owner_key", "=", current.owner_key)
2483
2905
  .where("host_id", "=", current.host_id)
@@ -2486,6 +2908,35 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
2486
2908
  if (pool?.status !== "available") {
2487
2909
  return undefined;
2488
2910
  }
2911
+ if (current.project_id !== null) {
2912
+ if (current.host_project_binding_id === null) {
2913
+ return undefined;
2914
+ }
2915
+ const binding = await trx
2916
+ .selectFrom("host_project_bindings as binding")
2917
+ .innerJoin("projects as project", (join) => join
2918
+ .onRef("project.project_id", "=", "binding.project_id")
2919
+ .onRef("project.owner_key", "=", "binding.owner_key"))
2920
+ .select([
2921
+ "binding.allowed_pool_keys_json",
2922
+ "binding.availability",
2923
+ "project.status as project_status",
2924
+ ])
2925
+ .where("binding.binding_id", "=", current.host_project_binding_id)
2926
+ .where("binding.owner_key", "=", current.owner_key)
2927
+ .where("binding.host_id", "=", current.host_id)
2928
+ .where("binding.project_id", "=", current.project_id)
2929
+ .forUpdate()
2930
+ .executeTakeFirst();
2931
+ const allowedPoolKeys = binding
2932
+ ? (fromJson(binding.allowed_pool_keys_json) ?? [])
2933
+ : [];
2934
+ if (binding?.project_status !== "active" ||
2935
+ binding.availability !== "available" ||
2936
+ !allowedPoolKeys.includes(pool.pool_key)) {
2937
+ return undefined;
2938
+ }
2939
+ }
2489
2940
  }
2490
2941
  const nowDate = this.clock.now();
2491
2942
  const now = nowDate.toISOString();
@@ -2538,6 +2989,7 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
2538
2989
  .where("pool.status", "=", "available")
2539
2990
  .where("instance.owner_key", "=", current.owner_key)
2540
2991
  .where("instance.host_id", "=", current.host_id)
2992
+ .where(sql `instance.project_id is not distinct from lease.project_id`)
2541
2993
  .where("instance.host_pool_id", "=", current.host_pool_id)
2542
2994
  .where("instance.sandbox_id", "=", current.sandbox_id)
2543
2995
  .where("instance.launch_lease_id", "=", current.lease_id)
@@ -2709,8 +3161,84 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
2709
3161
  if (nonterminalManagedInstances.count > 0) {
2710
3162
  blockers.push("nonterminal_managed_instances");
2711
3163
  }
3164
+ const retryableDeletingProviderInstances = await executor
3165
+ .selectFrom("managed_sandbox_instances")
3166
+ .select(sql `count(*)::int`.as("count"))
3167
+ .where("owner_key", "=", ownerKey)
3168
+ .where("host_id", "=", hostId)
3169
+ .where("status", "=", "deleting")
3170
+ .where("provider_resource_id", "is not", null)
3171
+ .executeTakeFirstOrThrow();
3172
+ if (retryableDeletingProviderInstances.count > 0 &&
3173
+ !blockers.includes("nonterminal_managed_instances")) {
3174
+ blockers.push("nonterminal_managed_instances");
3175
+ }
2712
3176
  return blockers;
2713
3177
  }
3178
+ async lockManagedSandboxLiveness(executor, sandboxId) {
3179
+ return executor
3180
+ .selectFrom("sandboxes")
3181
+ .select(["sandbox_id", "status"])
3182
+ .where("sandbox_id", "=", sandboxId)
3183
+ .forUpdate()
3184
+ .executeTakeFirst();
3185
+ }
3186
+ async managedSandboxHasAcceptedRunningAssignments(executor, sandboxId) {
3187
+ const row = await executor
3188
+ .selectFrom("tasks")
3189
+ .select("task_id")
3190
+ .where("status", "=", "RUNNING")
3191
+ .where("assigned_sandbox_id", "=", sandboxId)
3192
+ .where("assignment_accepted_at", "is not", null)
3193
+ .where("current_assignment_id", "is not", null)
3194
+ .forUpdate()
3195
+ .executeTakeFirst();
3196
+ return row !== undefined;
3197
+ }
3198
+ async clearReservedSandboxAssignmentsForDelete(executor, sandboxId) {
3199
+ const tasks = await executor
3200
+ .selectFrom("tasks")
3201
+ .select(["task_id", "run_id"])
3202
+ .where("status", "=", "RUNNING")
3203
+ .where("assigned_sandbox_id", "=", sandboxId)
3204
+ .where("assignment_accepted_at", "is", null)
3205
+ .where("current_assignment_id", "is not", null)
3206
+ .forUpdate()
3207
+ .execute();
3208
+ if (tasks.length === 0) {
3209
+ return 0;
3210
+ }
3211
+ const now = this.nowIso();
3212
+ const taskIds = tasks.map((task) => task.task_id);
3213
+ const cleared = await executor
3214
+ .updateTable("tasks")
3215
+ .set({
3216
+ status: "QUEUED",
3217
+ current_attempt_number: null,
3218
+ current_assignment_id: null,
3219
+ assigned_sandbox_id: null,
3220
+ assignment_created_at: null,
3221
+ assignment_sent_at: null,
3222
+ assignment_delivery_deadline_at: null,
3223
+ assignment_accepted_at: null,
3224
+ assignment_expires_at: null,
3225
+ assignment_heartbeat_at: null,
3226
+ assignment_delivery_attempt_count: 0,
3227
+ assignment_last_delivery_error: "managed_sandbox_deleted",
3228
+ not_before_at: null,
3229
+ updated_at: now,
3230
+ queued_at: now,
3231
+ })
3232
+ .where("task_id", "in", taskIds)
3233
+ .where("status", "=", "RUNNING")
3234
+ .where("assigned_sandbox_id", "=", sandboxId)
3235
+ .where("assignment_accepted_at", "is", null)
3236
+ .executeTakeFirst();
3237
+ for (const runId of new Set(tasks.map((task) => task.run_id))) {
3238
+ await this.updateRunState(executor, runId);
3239
+ }
3240
+ return Number(cleared.numUpdatedRows);
3241
+ }
2714
3242
  async requireHostPoolOwner(executor, hostPoolId, hostId, ownerKey) {
2715
3243
  const pool = await executor
2716
3244
  .selectFrom("host_pools")
@@ -2725,6 +3253,35 @@ export class ManagedSandboxInstancesStore extends ArtifactsEventsStore {
2725
3253
  }
2726
3254
  return pool;
2727
3255
  }
3256
+ async requireActiveHostProjectBindingForPool(executor, input) {
3257
+ const binding = await executor
3258
+ .selectFrom("host_project_bindings as binding")
3259
+ .innerJoin("projects as project", (join) => join
3260
+ .onRef("project.project_id", "=", "binding.project_id")
3261
+ .onRef("project.owner_key", "=", "binding.owner_key"))
3262
+ .innerJoin("host_pools as pool", (join) => join
3263
+ .onRef("pool.owner_key", "=", "binding.owner_key")
3264
+ .onRef("pool.host_id", "=", "binding.host_id"))
3265
+ .select([
3266
+ "binding.allowed_pool_keys_json",
3267
+ "project.status as project_status",
3268
+ "pool.pool_key",
3269
+ ])
3270
+ .where("binding.binding_id", "=", input.hostProjectBindingId)
3271
+ .where("binding.owner_key", "=", input.ownerKey)
3272
+ .where("binding.host_id", "=", input.hostId)
3273
+ .where("binding.project_id", "=", input.projectId)
3274
+ .where("pool.host_pool_id", "=", input.hostPoolId)
3275
+ .executeTakeFirst();
3276
+ if (!binding) {
3277
+ throw new Error("host project binding not found");
3278
+ }
3279
+ const allowedPoolKeys = fromJson(binding.allowed_pool_keys_json) ?? [];
3280
+ if (binding.project_status !== "active" ||
3281
+ !allowedPoolKeys.includes(binding.pool_key)) {
3282
+ throw new Error("host project binding is not valid for project launch");
3283
+ }
3284
+ }
2728
3285
  async requireSandboxIdentityOwner(executor, sandboxId, ownerKey) {
2729
3286
  const sandbox = await executor
2730
3287
  .selectFrom("sandbox_identities")
@@ -3105,6 +3662,7 @@ function mapHostCredentialAuth(row) {
3105
3662
  owner_key: row.auth_host_owner_key,
3106
3663
  name: row.auth_host_name,
3107
3664
  status: row.auth_host_status,
3665
+ project_workspace_root: row.auth_host_project_workspace_root,
3108
3666
  last_seen_at: row.auth_host_last_seen_at,
3109
3667
  connection_id: row.auth_host_connection_id,
3110
3668
  stream_generation: row.auth_host_stream_generation,