@baochunli/flakes 0.0.3 → 0.0.5

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 (295) hide show
  1. package/dist/commands/auth.d.ts.map +1 -1
  2. package/dist/commands/auth.js +133 -13
  3. package/dist/commands/auth.js.map +1 -1
  4. package/dist/commands/host.d.ts.map +1 -1
  5. package/dist/commands/host.js +77 -2
  6. package/dist/commands/host.js.map +1 -1
  7. package/dist/commands/projects.d.ts +4 -0
  8. package/dist/commands/projects.d.ts.map +1 -0
  9. package/dist/commands/projects.js +133 -0
  10. package/dist/commands/projects.js.map +1 -0
  11. package/dist/commands/runs.d.ts.map +1 -1
  12. package/dist/commands/runs.js +5 -1
  13. package/dist/commands/runs.js.map +1 -1
  14. package/dist/commands/runtime.d.ts +0 -1
  15. package/dist/commands/runtime.d.ts.map +1 -1
  16. package/dist/commands/runtime.js +2 -280
  17. package/dist/commands/runtime.js.map +1 -1
  18. package/dist/commands/server.d.ts.map +1 -1
  19. package/dist/commands/server.js +0 -6
  20. package/dist/commands/server.js.map +1 -1
  21. package/dist/commands/tasks.js +3 -0
  22. package/dist/commands/tasks.js.map +1 -1
  23. package/dist/config-example.js +1 -1
  24. package/dist/config-example.js.map +1 -1
  25. package/dist/host-config.d.ts +1 -6
  26. package/dist/host-config.d.ts.map +1 -1
  27. package/dist/host-config.js +10 -28
  28. package/dist/host-config.js.map +1 -1
  29. package/dist/host-runner.d.ts +3 -0
  30. package/dist/host-runner.d.ts.map +1 -1
  31. package/dist/host-runner.js +18 -6
  32. package/dist/host-runner.js.map +1 -1
  33. package/dist/host-runtime.d.ts.map +1 -1
  34. package/dist/host-runtime.js +92 -2
  35. package/dist/host-runtime.js.map +1 -1
  36. package/dist/host-transport.js +2 -5
  37. package/dist/host-transport.js.map +1 -1
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +46 -42
  40. package/dist/index.js.map +1 -1
  41. package/dist/node_modules/@flakes/auth/dist/better-auth-shape.d.ts +10 -0
  42. package/dist/node_modules/@flakes/auth/dist/better-auth-shape.d.ts.map +1 -0
  43. package/dist/node_modules/@flakes/auth/dist/better-auth-shape.js +16 -0
  44. package/dist/node_modules/@flakes/auth/dist/better-auth-shape.js.map +1 -0
  45. package/dist/node_modules/@flakes/auth/package.json +1 -1
  46. package/dist/node_modules/@flakes/console/.output/nitro.json +1 -1
  47. package/dist/node_modules/@flakes/console/.output/public/assets/DocumentationPage-CNPk8RVl.js +1 -0
  48. package/dist/node_modules/@flakes/console/.output/public/assets/ProjectsPage-CKPR1nnu.js +1 -0
  49. package/dist/node_modules/@flakes/console/.output/public/assets/RunPage-BdugbnA3.js +3 -0
  50. package/dist/node_modules/@flakes/console/.output/public/assets/RunsPage-CJbycrqM.js +1 -0
  51. package/dist/node_modules/@flakes/console/.output/public/assets/SandboxesLens-BoLM52PY.js +1 -0
  52. package/dist/node_modules/@flakes/console/.output/public/assets/SandboxesPage-6KHjMeaR.js +1 -0
  53. package/dist/node_modules/@flakes/console/.output/public/assets/TranscriptPage-CHSq0_qN.js +1 -0
  54. package/dist/node_modules/@flakes/console/.output/public/assets/_-CD1Voz9h.js +1 -0
  55. package/dist/node_modules/@flakes/console/.output/public/assets/_runId-_0VPmGYe.js +2 -0
  56. package/dist/node_modules/@flakes/console/.output/public/assets/_taskId-CPAKAp4X.js +2 -0
  57. package/dist/node_modules/@flakes/console/.output/public/assets/account-BoRurhrq.js +1 -0
  58. package/dist/node_modules/@flakes/console/.output/public/assets/account-forms-D4eVqOhW.js +1 -0
  59. package/dist/node_modules/@flakes/console/.output/public/assets/arrow-right-QzVbRzF_.js +1 -0
  60. package/dist/node_modules/@flakes/console/.output/public/assets/auth-layout-DBnq_eif.js +1 -0
  61. package/dist/node_modules/@flakes/console/.output/public/assets/bits-BOMPEHvv.js +1 -0
  62. package/dist/node_modules/@flakes/console/.output/public/assets/card-37qs8AAd.js +1 -0
  63. package/dist/node_modules/@flakes/console/.output/public/assets/circle-alert-CM0SVfzc.js +1 -0
  64. package/dist/node_modules/@flakes/console/.output/public/assets/circle-check-CzwcEElH.js +1 -0
  65. package/dist/node_modules/@flakes/console/.output/public/assets/circle-x-C_sOQVNQ.js +1 -0
  66. package/dist/node_modules/@flakes/console/.output/public/assets/device-FqII-S41.js +1 -0
  67. package/dist/node_modules/@flakes/console/.output/public/assets/dist-BEfdrJTS.js +1 -0
  68. package/dist/node_modules/@flakes/console/.output/public/assets/documentation-2C3ncAuV.js +1 -0
  69. package/dist/node_modules/@flakes/console/.output/public/assets/{external-link-BW8lpiMR.js → external-link-BWhbbPgy.js} +1 -1
  70. package/dist/node_modules/@flakes/console/.output/public/assets/{file-text-DMdy8OfN.js → file-text-DLxLJ7P1.js} +1 -1
  71. package/dist/node_modules/@flakes/console/.output/public/assets/forgot-password-BSQ4TWpA.js +1 -0
  72. package/dist/node_modules/@flakes/console/.output/public/assets/inbox-BVu38EN6.js +1 -0
  73. package/dist/node_modules/@flakes/console/.output/public/assets/{lib-DtfURcG3.js → lib-COfgMmRR.js} +3 -3
  74. package/dist/node_modules/@flakes/console/.output/public/assets/link-ll3nLBSM.js +1 -0
  75. package/dist/node_modules/@flakes/console/.output/public/assets/{lock-D4OhqEPW.js → lock-Ck2SfQA2.js} +1 -1
  76. package/dist/node_modules/@flakes/console/.output/public/assets/main-LpSDdT-S.js +1215 -0
  77. package/dist/node_modules/@flakes/console/.output/public/assets/matchContext-puEkI9BI.js +1 -0
  78. package/dist/node_modules/@flakes/console/.output/public/assets/otp-verification-CussJQT1.js +20 -0
  79. package/dist/node_modules/@flakes/console/.output/public/assets/projects-CLgKBrCe.js +2 -0
  80. package/dist/node_modules/@flakes/console/.output/public/assets/react-B8IZ02wI.js +1 -0
  81. package/dist/node_modules/@flakes/console/.output/public/assets/react-dom-ki7NpxV4.js +1 -0
  82. package/dist/node_modules/@flakes/console/.output/public/assets/redirect-Cu9zBy04.js +1 -0
  83. package/dist/node_modules/@flakes/console/.output/public/assets/reset-password-DwWhVkEh.js +1 -0
  84. package/dist/node_modules/@flakes/console/.output/public/assets/runs-CFYk2iRh.js +2 -0
  85. package/dist/node_modules/@flakes/console/.output/public/assets/sandboxes-mGsOcVFL.js +2 -0
  86. package/dist/node_modules/@flakes/console/.output/public/assets/{save-1uf5fQff.js → save-Bte_1tnN.js} +1 -1
  87. package/dist/node_modules/@flakes/console/.output/public/assets/security-MjM55vIw.js +1 -0
  88. package/dist/node_modules/@flakes/console/.output/public/assets/signin-KbA1cD6o.js +1 -0
  89. package/dist/node_modules/@flakes/console/.output/public/assets/signin-form-CBF-d8iK.js +1 -0
  90. package/dist/node_modules/@flakes/console/.output/public/assets/signup-CbHsThKr.js +1 -0
  91. package/dist/node_modules/@flakes/console/.output/public/assets/styles-DtA2wbW8.css +2 -0
  92. package/dist/node_modules/@flakes/console/.output/public/assets/table-WMIs2m3R.js +1 -0
  93. package/dist/node_modules/@flakes/console/.output/public/assets/tiny-invariant-CO5X59di.js +1 -0
  94. package/dist/node_modules/@flakes/console/.output/public/assets/user-Bt9z7sSI.js +1 -0
  95. package/dist/node_modules/@flakes/console/.output/public/assets/utils-CBxvVKOM.js +1 -0
  96. package/dist/node_modules/@flakes/console/.output/public/assets/x-Bdsfqbi3.js +1 -0
  97. package/dist/node_modules/@flakes/console/.output/server/{_-CjpSIsvB.mjs → _-BULJ6utw.mjs} +3 -3
  98. package/dist/node_modules/@flakes/console/.output/server/{_-8ZDVkA1O.mjs → _-_ST9QYWn.mjs} +3 -3
  99. package/dist/node_modules/@flakes/console/.output/server/_chunks/ProjectsPage.mjs +589 -0
  100. package/dist/node_modules/@flakes/console/.output/server/_chunks/RunPage.mjs +13 -6
  101. package/dist/node_modules/@flakes/console/.output/server/_chunks/RunsPage.mjs +43 -12
  102. package/dist/node_modules/@flakes/console/.output/server/_chunks/SandboxesPage.mjs +2 -2
  103. package/dist/node_modules/@flakes/console/.output/server/_chunks/TranscriptPage.mjs +2 -2
  104. package/dist/node_modules/@flakes/console/.output/server/_chunks/project-navigation.mjs +79 -0
  105. package/dist/node_modules/@flakes/console/.output/server/_chunks/router.mjs +195 -112
  106. package/dist/node_modules/@flakes/console/.output/server/_chunks/utils.mjs +111 -3
  107. package/dist/node_modules/@flakes/console/.output/server/_libs/lucide-react.mjs +178 -1
  108. package/dist/node_modules/@flakes/console/.output/server/{_runId-CJ5_8uS8.mjs → _runId-CmYWNL8A.mjs} +3 -3
  109. package/dist/node_modules/@flakes/console/.output/server/{_runId-Cag5UaYU.mjs → _runId-WZmbo654.mjs} +2 -2
  110. package/dist/node_modules/@flakes/console/.output/server/_ssr/{App-CwFtUgAz.mjs → App-CUx8Ftit.mjs} +118 -64
  111. package/dist/node_modules/@flakes/console/.output/server/_ssr/{DocumentationPage-D85Budiq.mjs → DocumentationPage-0I9oWWJT.mjs} +5 -5
  112. package/dist/node_modules/@flakes/console/.output/server/_ssr/ProjectsPage-CGj9V2Of.mjs +590 -0
  113. package/dist/node_modules/@flakes/console/.output/server/_ssr/{RunPage-CatpnkFy.mjs → RunPage-B2vhVaj6.mjs} +14 -7
  114. package/dist/node_modules/@flakes/console/.output/server/_ssr/{RunsPage-BmLTih8Z.mjs → RunsPage-BifKogQE.mjs} +44 -13
  115. package/dist/node_modules/@flakes/console/.output/server/_ssr/{SandboxesPage-Dlq0Ga24.mjs → SandboxesPage-DGji_OdB.mjs} +3 -3
  116. package/dist/node_modules/@flakes/console/.output/server/_ssr/{TranscriptPage-DaSIDCKk.mjs → TranscriptPage-deSxVZaQ.mjs} +3 -3
  117. package/dist/node_modules/@flakes/console/.output/server/_ssr/{account-DzluYS58.mjs → account-D5y9vkAc.mjs} +2 -2
  118. package/dist/node_modules/@flakes/console/.output/server/_ssr/account-forms-CsothyLo.mjs +1 -1
  119. package/dist/node_modules/@flakes/console/.output/server/_ssr/device-CRZl7dGv.mjs +1 -1
  120. package/dist/node_modules/@flakes/console/.output/server/_ssr/{documentation-4BCES--X.mjs → documentation-C69e9_eF.mjs} +3 -3
  121. package/dist/node_modules/@flakes/console/.output/server/_ssr/documentation-C91gfyy0.mjs +210 -0
  122. package/dist/node_modules/@flakes/console/.output/server/_ssr/{hooks-COIYuQzf.mjs → hooks-DrgN35zn.mjs} +110 -4
  123. package/dist/node_modules/@flakes/console/.output/server/_ssr/project-navigation-DI77TL9a.mjs +79 -0
  124. package/dist/node_modules/@flakes/console/.output/server/_ssr/projects-lJ2tIIPj.mjs +5 -0
  125. package/dist/node_modules/@flakes/console/.output/server/_ssr/reset-password-SmmTixcr.mjs +1 -1
  126. package/dist/node_modules/@flakes/console/.output/server/_ssr/{router-B3vKkNtv.mjs → router-DHxFQ03L.mjs} +49 -41
  127. package/dist/node_modules/@flakes/console/.output/server/_ssr/{runs-CBkO-RO8.mjs → runs-BWxEGKO_.mjs} +17 -5
  128. package/dist/node_modules/@flakes/console/.output/server/_ssr/runs-dnPfp9dt.mjs +19 -0
  129. package/dist/node_modules/@flakes/console/.output/server/_ssr/{sandboxes-BIAgn8pu2.mjs → sandboxes-hxFINxDS.mjs} +3 -3
  130. package/dist/node_modules/@flakes/console/.output/server/_ssr/{sandboxes-qSX_pfUJ.mjs → sandboxes-v28LJQM3.mjs} +2 -2
  131. package/dist/node_modules/@flakes/console/.output/server/_ssr/signin-form-CQDi-0A5.mjs +1 -1
  132. package/dist/node_modules/@flakes/console/.output/server/_ssr/ssr.mjs +2 -2
  133. package/dist/node_modules/@flakes/console/.output/server/{_tanstack-start-manifest_v-llXRWxjT.mjs → _tanstack-start-manifest_v-DfwuEzTr.mjs} +54 -46
  134. package/dist/node_modules/@flakes/console/.output/server/{_taskId-BaezvY0w.mjs → _taskId-CBo95z-s.mjs} +2 -2
  135. package/dist/node_modules/@flakes/console/.output/server/{_taskId-Da7kHKj9.mjs → _taskId-Sil3-PKh.mjs} +3 -3
  136. package/dist/node_modules/@flakes/console/package.json +1 -1
  137. package/dist/node_modules/@flakes/control-plane/dist/client-access.d.ts +17 -0
  138. package/dist/node_modules/@flakes/control-plane/dist/client-access.d.ts.map +1 -1
  139. package/dist/node_modules/@flakes/control-plane/dist/client-access.js +12 -0
  140. package/dist/node_modules/@flakes/control-plane/dist/client-access.js.map +1 -1
  141. package/dist/node_modules/@flakes/control-plane/dist/host-credentials.d.ts +1 -1
  142. package/dist/node_modules/@flakes/control-plane/dist/host-credentials.d.ts.map +1 -1
  143. package/dist/node_modules/@flakes/control-plane/dist/host-pool-matching.d.ts +24 -1
  144. package/dist/node_modules/@flakes/control-plane/dist/host-pool-matching.d.ts.map +1 -1
  145. package/dist/node_modules/@flakes/control-plane/dist/host-pool-matching.js +87 -3
  146. package/dist/node_modules/@flakes/control-plane/dist/host-pool-matching.js.map +1 -1
  147. package/dist/node_modules/@flakes/control-plane/dist/host-stream.d.ts.map +1 -1
  148. package/dist/node_modules/@flakes/control-plane/dist/host-stream.js +150 -40
  149. package/dist/node_modules/@flakes/control-plane/dist/host-stream.js.map +1 -1
  150. package/dist/node_modules/@flakes/control-plane/dist/managed-sandbox-provisioner.d.ts +71 -0
  151. package/dist/node_modules/@flakes/control-plane/dist/managed-sandbox-provisioner.d.ts.map +1 -0
  152. package/dist/node_modules/@flakes/control-plane/dist/managed-sandbox-provisioner.js +243 -0
  153. package/dist/node_modules/@flakes/control-plane/dist/managed-sandbox-provisioner.js.map +1 -0
  154. package/dist/node_modules/@flakes/control-plane/dist/routes/hosts.d.ts.map +1 -1
  155. package/dist/node_modules/@flakes/control-plane/dist/routes/hosts.js +219 -0
  156. package/dist/node_modules/@flakes/control-plane/dist/routes/hosts.js.map +1 -1
  157. package/dist/node_modules/@flakes/control-plane/dist/routes/projects.d.ts +3 -0
  158. package/dist/node_modules/@flakes/control-plane/dist/routes/projects.d.ts.map +1 -0
  159. package/dist/node_modules/@flakes/control-plane/dist/routes/projects.js +226 -0
  160. package/dist/node_modules/@flakes/control-plane/dist/routes/projects.js.map +1 -0
  161. package/dist/node_modules/@flakes/control-plane/dist/routes/runs.d.ts.map +1 -1
  162. package/dist/node_modules/@flakes/control-plane/dist/routes/runs.js +93 -6
  163. package/dist/node_modules/@flakes/control-plane/dist/routes/runs.js.map +1 -1
  164. package/dist/node_modules/@flakes/control-plane/dist/routes/sandboxes-admin.d.ts +3 -0
  165. package/dist/node_modules/@flakes/control-plane/dist/routes/sandboxes-admin.d.ts.map +1 -0
  166. package/dist/node_modules/@flakes/control-plane/dist/routes/sandboxes-admin.js +153 -0
  167. package/dist/node_modules/@flakes/control-plane/dist/routes/sandboxes-admin.js.map +1 -0
  168. package/dist/node_modules/@flakes/control-plane/dist/routes/tasks.js +2 -2
  169. package/dist/node_modules/@flakes/control-plane/dist/routes/tasks.js.map +1 -1
  170. package/dist/node_modules/@flakes/control-plane/dist/sandbox-drain.d.ts +19 -0
  171. package/dist/node_modules/@flakes/control-plane/dist/sandbox-drain.d.ts.map +1 -0
  172. package/dist/node_modules/@flakes/control-plane/dist/sandbox-drain.js +46 -0
  173. package/dist/node_modules/@flakes/control-plane/dist/sandbox-drain.js.map +1 -0
  174. package/dist/node_modules/@flakes/control-plane/dist/scheduler.d.ts +2 -0
  175. package/dist/node_modules/@flakes/control-plane/dist/scheduler.d.ts.map +1 -1
  176. package/dist/node_modules/@flakes/control-plane/dist/scheduler.js +53 -21
  177. package/dist/node_modules/@flakes/control-plane/dist/scheduler.js.map +1 -1
  178. package/dist/node_modules/@flakes/control-plane/dist/server.d.ts.map +1 -1
  179. package/dist/node_modules/@flakes/control-plane/dist/server.js +2 -0
  180. package/dist/node_modules/@flakes/control-plane/dist/server.js.map +1 -1
  181. package/dist/node_modules/@flakes/control-plane/dist/types.d.ts +2 -0
  182. package/dist/node_modules/@flakes/control-plane/dist/types.d.ts.map +1 -1
  183. package/dist/node_modules/@flakes/control-plane/package.json +1 -1
  184. package/dist/node_modules/@flakes/core/dist/config.d.ts.map +1 -1
  185. package/dist/node_modules/@flakes/core/dist/config.js +6 -2
  186. package/dist/node_modules/@flakes/core/dist/config.js.map +1 -1
  187. package/dist/node_modules/@flakes/core/dist/ids.d.ts +4 -0
  188. package/dist/node_modules/@flakes/core/dist/ids.d.ts.map +1 -1
  189. package/dist/node_modules/@flakes/core/dist/ids.js +2 -0
  190. package/dist/node_modules/@flakes/core/dist/ids.js.map +1 -1
  191. package/dist/node_modules/@flakes/core/dist/runtime.d.ts +1 -1
  192. package/dist/node_modules/@flakes/core/dist/schemas.d.ts +11 -0
  193. package/dist/node_modules/@flakes/core/dist/schemas.d.ts.map +1 -1
  194. package/dist/node_modules/@flakes/core/dist/schemas.js +10 -0
  195. package/dist/node_modules/@flakes/core/dist/schemas.js.map +1 -1
  196. package/dist/node_modules/@flakes/core/package.json +1 -1
  197. package/dist/node_modules/@flakes/harness-agent/package.json +1 -1
  198. package/dist/node_modules/@flakes/harness-sdk/package.json +1 -1
  199. package/dist/node_modules/@flakes/pi-agent/package.json +1 -1
  200. package/dist/node_modules/@flakes/protocol/dist/index.d.ts +1 -1
  201. package/dist/node_modules/@flakes/protocol/dist/index.d.ts.map +1 -1
  202. package/dist/node_modules/@flakes/protocol/dist/index.js +1 -1
  203. package/dist/node_modules/@flakes/protocol/dist/index.js.map +1 -1
  204. package/dist/node_modules/@flakes/protocol/dist/v1.d.ts +317 -0
  205. package/dist/node_modules/@flakes/protocol/dist/v1.d.ts.map +1 -1
  206. package/dist/node_modules/@flakes/protocol/dist/v1.js +50 -1
  207. package/dist/node_modules/@flakes/protocol/dist/v1.js.map +1 -1
  208. package/dist/node_modules/@flakes/protocol/package.json +1 -1
  209. package/dist/node_modules/@flakes/sandbox-runtime/dist/transport.js +3 -6
  210. package/dist/node_modules/@flakes/sandbox-runtime/dist/transport.js.map +1 -1
  211. package/dist/node_modules/@flakes/sandbox-runtime/package.json +1 -1
  212. package/dist/node_modules/@flakes/store/dist/artifacts-events-store.d.ts.map +1 -1
  213. package/dist/node_modules/@flakes/store/dist/artifacts-events-store.js +10 -0
  214. package/dist/node_modules/@flakes/store/dist/artifacts-events-store.js.map +1 -1
  215. package/dist/node_modules/@flakes/store/dist/host-provisioning-limits.d.ts +2 -1
  216. package/dist/node_modules/@flakes/store/dist/host-provisioning-limits.d.ts.map +1 -1
  217. package/dist/node_modules/@flakes/store/dist/host-provisioning-limits.js +1 -0
  218. package/dist/node_modules/@flakes/store/dist/host-provisioning-limits.js.map +1 -1
  219. package/dist/node_modules/@flakes/store/dist/kysely-store.d.ts +2 -2
  220. package/dist/node_modules/@flakes/store/dist/kysely-store.d.ts.map +1 -1
  221. package/dist/node_modules/@flakes/store/dist/kysely-store.js +2 -2
  222. package/dist/node_modules/@flakes/store/dist/kysely-store.js.map +1 -1
  223. package/dist/node_modules/@flakes/store/dist/managed-sandbox-instances-store.d.ts +6 -2
  224. package/dist/node_modules/@flakes/store/dist/managed-sandbox-instances-store.d.ts.map +1 -1
  225. package/dist/node_modules/@flakes/store/dist/managed-sandbox-instances-store.js +160 -3
  226. package/dist/node_modules/@flakes/store/dist/managed-sandbox-instances-store.js.map +1 -1
  227. package/dist/node_modules/@flakes/store/dist/mappers.d.ts +10 -2
  228. package/dist/node_modules/@flakes/store/dist/mappers.d.ts.map +1 -1
  229. package/dist/node_modules/@flakes/store/dist/mappers.js +45 -0
  230. package/dist/node_modules/@flakes/store/dist/mappers.js.map +1 -1
  231. package/dist/node_modules/@flakes/store/dist/projects-store.d.ts +42 -0
  232. package/dist/node_modules/@flakes/store/dist/projects-store.d.ts.map +1 -0
  233. package/dist/node_modules/@flakes/store/dist/projects-store.js +376 -0
  234. package/dist/node_modules/@flakes/store/dist/projects-store.js.map +1 -0
  235. package/dist/node_modules/@flakes/store/dist/runs-store.d.ts.map +1 -1
  236. package/dist/node_modules/@flakes/store/dist/runs-store.js +7 -2
  237. package/dist/node_modules/@flakes/store/dist/runs-store.js.map +1 -1
  238. package/dist/node_modules/@flakes/store/dist/schema.js +72 -0
  239. package/dist/node_modules/@flakes/store/dist/schema.js.map +1 -1
  240. package/dist/node_modules/@flakes/store/dist/sqlite.d.ts +4 -0
  241. package/dist/node_modules/@flakes/store/dist/sqlite.d.ts.map +1 -0
  242. package/dist/node_modules/@flakes/store/dist/sqlite.js +34 -0
  243. package/dist/node_modules/@flakes/store/dist/sqlite.js.map +1 -0
  244. package/dist/node_modules/@flakes/store/dist/store-base.d.ts +14 -12
  245. package/dist/node_modules/@flakes/store/dist/store-base.d.ts.map +1 -1
  246. package/dist/node_modules/@flakes/store/dist/tables.d.ts +41 -1
  247. package/dist/node_modules/@flakes/store/dist/tables.d.ts.map +1 -1
  248. package/dist/node_modules/@flakes/store/dist/tasks-store.d.ts.map +1 -1
  249. package/dist/node_modules/@flakes/store/dist/tasks-store.js +9 -2
  250. package/dist/node_modules/@flakes/store/dist/tasks-store.js.map +1 -1
  251. package/dist/node_modules/@flakes/store/dist/types.d.ts +159 -1
  252. package/dist/node_modules/@flakes/store/dist/types.d.ts.map +1 -1
  253. package/dist/node_modules/@flakes/store/package.json +1 -1
  254. package/package.json +1 -1
  255. package/dist/node_modules/@flakes/console/.output/public/assets/DocumentationPage-DrqDulyL.js +0 -1
  256. package/dist/node_modules/@flakes/console/.output/public/assets/RunPage-BC3sGoPN.js +0 -3
  257. package/dist/node_modules/@flakes/console/.output/public/assets/RunsPage-LkYGVvbL.js +0 -1
  258. package/dist/node_modules/@flakes/console/.output/public/assets/SandboxesLens-BUQQWmH6.js +0 -1
  259. package/dist/node_modules/@flakes/console/.output/public/assets/SandboxesPage-CwWMogj6.js +0 -1
  260. package/dist/node_modules/@flakes/console/.output/public/assets/TranscriptPage-CTMgJgHp.js +0 -1
  261. package/dist/node_modules/@flakes/console/.output/public/assets/_-DRcA_CG9.js +0 -1
  262. package/dist/node_modules/@flakes/console/.output/public/assets/_runId-CO1ozt9P.js +0 -2
  263. package/dist/node_modules/@flakes/console/.output/public/assets/_taskId-CcIypX6M.js +0 -2
  264. package/dist/node_modules/@flakes/console/.output/public/assets/account-DKgjbb-C.js +0 -1
  265. package/dist/node_modules/@flakes/console/.output/public/assets/account-forms-DrHA3zEd.js +0 -1
  266. package/dist/node_modules/@flakes/console/.output/public/assets/arrow-right-BMW8fJP5.js +0 -1
  267. package/dist/node_modules/@flakes/console/.output/public/assets/auth-layout-INHonQMf.js +0 -1
  268. package/dist/node_modules/@flakes/console/.output/public/assets/bits-Cv0Te4iz.js +0 -1
  269. package/dist/node_modules/@flakes/console/.output/public/assets/card-DSG3_teC.js +0 -1
  270. package/dist/node_modules/@flakes/console/.output/public/assets/circle-check-B0gtb8OH.js +0 -1
  271. package/dist/node_modules/@flakes/console/.output/public/assets/device-DOGZUNMB.js +0 -1
  272. package/dist/node_modules/@flakes/console/.output/public/assets/dist-BtPw3IIV.js +0 -1
  273. package/dist/node_modules/@flakes/console/.output/public/assets/documentation-Dr9Bdqxh.js +0 -1
  274. package/dist/node_modules/@flakes/console/.output/public/assets/forgot-password-C7qvwcpm.js +0 -1
  275. package/dist/node_modules/@flakes/console/.output/public/assets/link-BsixJinJ.js +0 -1
  276. package/dist/node_modules/@flakes/console/.output/public/assets/main-RzjfJZwD.js +0 -1121
  277. package/dist/node_modules/@flakes/console/.output/public/assets/matchContext-tJ0VTv5m.js +0 -1
  278. package/dist/node_modules/@flakes/console/.output/public/assets/otp-verification-Cqa6lopR.js +0 -20
  279. package/dist/node_modules/@flakes/console/.output/public/assets/react-DtOYBmep.js +0 -1
  280. package/dist/node_modules/@flakes/console/.output/public/assets/react-dom-DrIU40PY.js +0 -1
  281. package/dist/node_modules/@flakes/console/.output/public/assets/redirect-BEm0VK76.js +0 -1
  282. package/dist/node_modules/@flakes/console/.output/public/assets/reset-password-tImCgEn0.js +0 -1
  283. package/dist/node_modules/@flakes/console/.output/public/assets/runs-Cuk0VOVi.js +0 -2
  284. package/dist/node_modules/@flakes/console/.output/public/assets/sandboxes-BBIIbVN8.js +0 -2
  285. package/dist/node_modules/@flakes/console/.output/public/assets/security-D3N68cBT.js +0 -1
  286. package/dist/node_modules/@flakes/console/.output/public/assets/signin-DylILjyG.js +0 -1
  287. package/dist/node_modules/@flakes/console/.output/public/assets/signin-form-DWaa_uwj.js +0 -1
  288. package/dist/node_modules/@flakes/console/.output/public/assets/signup-KmFQL_1g.js +0 -1
  289. package/dist/node_modules/@flakes/console/.output/public/assets/styles-8wEqfToJ.css +0 -2
  290. package/dist/node_modules/@flakes/console/.output/public/assets/table-DptQuuuq.js +0 -1
  291. package/dist/node_modules/@flakes/console/.output/public/assets/user-DK27uFod.js +0 -1
  292. package/dist/node_modules/@flakes/console/.output/public/assets/utils-CEE0-YEp.js +0 -1
  293. package/dist/node_modules/@flakes/console/.output/public/assets/x-fKvnmCoQ.js +0 -1
  294. package/dist/node_modules/@flakes/console/.output/server/_ssr/documentation-Do_Mr_e4.mjs +0 -210
  295. package/dist/node_modules/@flakes/console/.output/server/_ssr/runs-BzfGldVd.mjs +0 -12
@@ -0,0 +1,71 @@
1
+ import { type FliesSandboxConfig, type ManagedSandboxPoolConfig } from "@flies/core";
2
+ import type { DurableStore, StoreManagedSandboxInstance, StoreTask } from "@flies/store";
3
+ import type { SandboxStreamRegistry } from "./sandbox-stream-registry.js";
4
+ /** Input handed to a provider-specific managed sandbox starter. */
5
+ export interface StartManagedSandboxInput {
6
+ pool: ManagedSandboxPoolConfig;
7
+ instance: StoreManagedSandboxInstance;
8
+ sandboxConfig: FliesSandboxConfig;
9
+ }
10
+ /** Provider result after launching a managed sandbox daemon environment. */
11
+ export type StartManagedSandboxResult = {
12
+ status: "started";
13
+ providerResourceId?: string | undefined;
14
+ } | {
15
+ status: "ambiguous";
16
+ providerResourceId?: string | undefined;
17
+ lastError?: string | undefined;
18
+ };
19
+ /** Narrow provider boundary owned by control-plane provisioning. */
20
+ export interface ManagedSandboxStarter {
21
+ start(input: StartManagedSandboxInput): Promise<StartManagedSandboxResult>;
22
+ }
23
+ export interface ManagedSandboxProvisionerOptions {
24
+ store: DurableStore;
25
+ /** Live stream boundary used to distinguish truly schedulable live slots from durable rows. */
26
+ registry?: SandboxStreamRegistry | undefined;
27
+ pools: readonly ManagedSandboxPoolConfig[];
28
+ starter: ManagedSandboxStarter;
29
+ cleaner?: ManagedSandboxCleaner | undefined;
30
+ pollIntervalMs: number;
31
+ queuedTaskLimit?: number | undefined;
32
+ /**
33
+ * Registers a per-instance sandbox-pinned credential so the minted token is
34
+ * accepted by sandbox-pinned routes (e.g. pi-session). Without it the instance
35
+ * would have no pinned sandbox credential and those routes reject with 403.
36
+ */
37
+ registerSandboxCredential?: ((credential: {
38
+ sandboxId: string;
39
+ token: string;
40
+ }) => void) | undefined;
41
+ }
42
+ /** Input handed to a provider-specific managed sandbox cleanup action. */
43
+ export interface StopManagedSandboxInput {
44
+ instance: StoreManagedSandboxInstance;
45
+ providerResourceId: string;
46
+ }
47
+ /** Narrow provider boundary used for managed sandbox cleanup. */
48
+ export interface ManagedSandboxCleaner {
49
+ stop(input: StopManagedSandboxInput): Promise<void>;
50
+ }
51
+ export interface StopManagedSandboxInstancesInput {
52
+ store: DurableStore;
53
+ cleaner: ManagedSandboxCleaner;
54
+ }
55
+ /** Periodically starts managed sandbox instances to satisfy queued compatible demand. */
56
+ export declare class ManagedSandboxProvisioner {
57
+ #private;
58
+ constructor(options: ManagedSandboxProvisionerOptions);
59
+ /** Runs one provisioning pass. At most one instance is started per pool. */
60
+ tick(): Promise<void>;
61
+ /** Starts background provisioning; repeated calls are no-ops. */
62
+ start(): void;
63
+ /** Stops background provisioning if active. */
64
+ stop(): void;
65
+ }
66
+ /** Best-effort stop for every nonterminal managed instance. */
67
+ export declare function stopManagedSandboxInstances(input: StopManagedSandboxInstancesInput): Promise<void>;
68
+ export declare function createManagedSandboxConfig(pool: ManagedSandboxPoolConfig, sandboxId: string, token: string): FliesSandboxConfig;
69
+ /** MVP pre-launch match: only target adapter and required capabilities. */
70
+ export declare function isPreLaunchCompatible(task: StoreTask, pool: ManagedSandboxPoolConfig): boolean;
71
+ //# sourceMappingURL=managed-sandbox-provisioner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"managed-sandbox-provisioner.d.ts","sourceRoot":"","sources":["../src/managed-sandbox-provisioner.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,wBAAwB,EAC9B,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACV,YAAY,EAEZ,2BAA2B,EAC3B,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAG1E,mEAAmE;AACnE,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,wBAAwB,CAAC;IAC/B,QAAQ,EAAE,2BAA2B,CAAC;IACtC,aAAa,EAAE,kBAAkB,CAAC;CACnC;AAED,4EAA4E;AAC5E,MAAM,MAAM,yBAAyB,GACjC;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC,GACD;IACE,MAAM,EAAE,WAAW,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,CAAC;AAEN,oEAAoE;AACpE,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;CAC5E;AAED,MAAM,WAAW,gCAAgC;IAC/C,KAAK,EAAE,YAAY,CAAC;IACpB,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IAC7C,KAAK,EAAE,SAAS,wBAAwB,EAAE,CAAC;IAC3C,OAAO,EAAE,qBAAqB,CAAC;IAC/B,OAAO,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IAC5C,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC;;;;OAIG;IACH,yBAAyB,CAAC,EACtB,CAAC,CAAC,UAAU,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC,GAC5D,SAAS,CAAC;CACf;AAED,0EAA0E;AAC1E,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,2BAA2B,CAAC;IACtC,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,iEAAiE;AACjE,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,gCAAgC;IAC/C,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,qBAAqB,CAAC;CAChC;AAoBD,yFAAyF;AACzF,qBAAa,yBAAyB;;gBAcxB,OAAO,EAAE,gCAAgC;IAWrD,4EAA4E;IAC5E,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAWrB,iEAAiE;IACjE,KAAK;IAUL,+CAA+C;IAC/C,IAAI;CA0KL;AAED,+DAA+D;AAC/D,wBAAsB,2BAA2B,CAC/C,KAAK,EAAE,gCAAgC,GACtC,OAAO,CAAC,IAAI,CAAC,CAcf;AAoBD,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,wBAAwB,EAC9B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,kBAAkB,CAMpB;AASD,2EAA2E;AAC3E,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,wBAAwB,WAW/B"}
@@ -0,0 +1,243 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { createManagedSandboxConfig as createCoreManagedSandboxConfig, } from "@flies/core";
3
+ import { toError } from "./utils.js";
4
+ const defaultQueuedTaskLimit = 100;
5
+ const capacityStatuses = [
6
+ "starting",
7
+ "live",
8
+ "draining",
9
+ ];
10
+ /** Periodically starts managed sandbox instances to satisfy queued compatible demand. */
11
+ export class ManagedSandboxProvisioner {
12
+ #timer;
13
+ #tickInFlight;
14
+ #store;
15
+ #registry;
16
+ #pools;
17
+ #starter;
18
+ #cleaner;
19
+ #pollIntervalMs;
20
+ #queuedTaskLimit;
21
+ #registerSandboxCredential;
22
+ constructor(options) {
23
+ this.#store = options.store;
24
+ this.#registry = options.registry;
25
+ this.#pools = options.pools;
26
+ this.#starter = options.starter;
27
+ this.#cleaner = options.cleaner;
28
+ this.#pollIntervalMs = options.pollIntervalMs;
29
+ this.#queuedTaskLimit = options.queuedTaskLimit ?? defaultQueuedTaskLimit;
30
+ this.#registerSandboxCredential = options.registerSandboxCredential;
31
+ }
32
+ /** Runs one provisioning pass. At most one instance is started per pool. */
33
+ tick() {
34
+ if (this.#tickInFlight) {
35
+ return this.#tickInFlight;
36
+ }
37
+ this.#tickInFlight = this.#runTick().finally(() => {
38
+ this.#tickInFlight = undefined;
39
+ });
40
+ return this.#tickInFlight;
41
+ }
42
+ /** Starts background provisioning; repeated calls are no-ops. */
43
+ start() {
44
+ if (this.#timer) {
45
+ return;
46
+ }
47
+ this.#timer = globalThis.setInterval(() => {
48
+ void this.tick().catch(() => undefined);
49
+ }, this.#pollIntervalMs);
50
+ }
51
+ /** Stops background provisioning if active. */
52
+ stop() {
53
+ if (!this.#timer) {
54
+ return;
55
+ }
56
+ globalThis.clearInterval(this.#timer);
57
+ this.#timer = undefined;
58
+ }
59
+ async #runTick() {
60
+ const tasks = await this.#store.listQueuedTasks({
61
+ limit: this.#queuedTaskLimit,
62
+ });
63
+ for (const pool of this.#pools) {
64
+ const compatibleQueuedDemand = countCompatibleQueuedDemand(tasks, pool);
65
+ const capacity = await this.#poolCapacity(pool);
66
+ if (compatibleQueuedDemand === 0) {
67
+ continue;
68
+ }
69
+ if (compatibleQueuedDemand <=
70
+ capacity.liveAvailableSlots + capacity.startingSlots) {
71
+ continue;
72
+ }
73
+ if (capacity.activeInstances >= pool.maxInstances) {
74
+ continue;
75
+ }
76
+ await this.#startInstance(pool);
77
+ }
78
+ }
79
+ async #poolCapacity(pool) {
80
+ const instances = await this.#store.listManagedSandboxInstances({
81
+ poolId: pool.poolId,
82
+ statuses: capacityStatuses,
83
+ });
84
+ let liveAvailableSlots = 0;
85
+ let startingSlots = 0;
86
+ let activeInstances = 0;
87
+ for (const instance of instances) {
88
+ if (instance.status === "starting") {
89
+ activeInstances += 1;
90
+ startingSlots += pool.maxConcurrency;
91
+ continue;
92
+ }
93
+ if (instance.status === "draining") {
94
+ activeInstances += 1;
95
+ continue;
96
+ }
97
+ const liveCapacity = await this.#liveCapacity(instance);
98
+ if (liveCapacity.activeInstance) {
99
+ activeInstances += 1;
100
+ }
101
+ liveAvailableSlots += liveCapacity.availableSlots;
102
+ }
103
+ return {
104
+ liveAvailableSlots,
105
+ startingSlots,
106
+ activeInstances,
107
+ };
108
+ }
109
+ async #liveCapacity(instance) {
110
+ const sandbox = await this.#store.getSandbox(instance.sandboxId);
111
+ if (!sandbox || sandbox.status === "offline") {
112
+ await this.#store.markManagedSandboxInstanceFailed({
113
+ instanceId: instance.instanceId,
114
+ lastError: sandbox
115
+ ? "managed sandbox live instance is offline"
116
+ : "managed sandbox live instance has no sandbox record",
117
+ });
118
+ return { activeInstance: false, availableSlots: 0 };
119
+ }
120
+ if (sandbox.status !== "active" ||
121
+ sandbox.descriptor?.draining === true ||
122
+ (this.#registry && !this.#registry.latest(instance.sandboxId))) {
123
+ return { activeInstance: true, availableSlots: 0 };
124
+ }
125
+ const load = await this.#store.getSandboxLoad(instance.sandboxId);
126
+ return { activeInstance: true, availableSlots: load.availableCapacity };
127
+ }
128
+ async #startInstance(pool) {
129
+ // Mint a credential pinned to this instance's sandboxId so sandbox-pinned
130
+ // routes accept the daemon's token.
131
+ const sandboxToken = randomBytes(32).toString("hex");
132
+ const instance = await this.#store.createManagedSandboxInstance({
133
+ poolId: pool.poolId,
134
+ sandboxToken,
135
+ });
136
+ this.#registerSandboxCredential?.({
137
+ sandboxId: instance.sandboxId,
138
+ token: sandboxToken,
139
+ });
140
+ const sandboxConfig = createManagedSandboxConfig(pool, instance.sandboxId, sandboxToken);
141
+ try {
142
+ const result = await this.#starter.start({
143
+ pool,
144
+ instance,
145
+ sandboxConfig,
146
+ });
147
+ if (result.providerResourceId) {
148
+ await this.#store.setManagedSandboxProviderResource({
149
+ instanceId: instance.instanceId,
150
+ providerResourceId: result.providerResourceId,
151
+ });
152
+ }
153
+ if (result.status === "ambiguous") {
154
+ const lastError = result.lastError ??
155
+ "managed sandbox starter returned ambiguous result";
156
+ if (result.providerResourceId && this.#cleaner) {
157
+ try {
158
+ await this.#cleaner.stop({
159
+ instance: {
160
+ ...instance,
161
+ providerResourceId: result.providerResourceId,
162
+ },
163
+ providerResourceId: result.providerResourceId,
164
+ });
165
+ await this.#store.markManagedSandboxInstanceStopped({
166
+ instanceId: instance.instanceId,
167
+ lastError,
168
+ });
169
+ return;
170
+ }
171
+ catch (error) {
172
+ await this.#store.markManagedSandboxInstanceFailed({
173
+ instanceId: instance.instanceId,
174
+ lastError: `${lastError}; cleanup failed: ${toError(error).message}`,
175
+ });
176
+ return;
177
+ }
178
+ }
179
+ await this.#store.markManagedSandboxInstanceFailed({
180
+ instanceId: instance.instanceId,
181
+ lastError,
182
+ });
183
+ return;
184
+ }
185
+ }
186
+ catch (error) {
187
+ const lastError = toError(error).message;
188
+ await this.#store.markManagedSandboxInstanceFailed({
189
+ instanceId: instance.instanceId,
190
+ lastError,
191
+ });
192
+ }
193
+ }
194
+ }
195
+ /** Best-effort stop for every nonterminal managed instance. */
196
+ export async function stopManagedSandboxInstances(input) {
197
+ const instances = await input.store.listManagedSandboxInstances({
198
+ statuses: capacityStatuses,
199
+ });
200
+ for (const instance of instances) {
201
+ try {
202
+ await stopManagedSandboxInstance({ ...input, instance });
203
+ }
204
+ catch (error) {
205
+ await input.store.markManagedSandboxInstanceFailed({
206
+ instanceId: instance.instanceId,
207
+ lastError: `managed sandbox cleanup failed: ${toError(error).message}`,
208
+ });
209
+ }
210
+ }
211
+ }
212
+ async function stopManagedSandboxInstance(input) {
213
+ if (!input.instance.providerResourceId) {
214
+ return;
215
+ }
216
+ await input.cleaner.stop({
217
+ instance: input.instance,
218
+ providerResourceId: input.instance.providerResourceId,
219
+ });
220
+ await input.store.markManagedSandboxInstanceStopped({
221
+ instanceId: input.instance.instanceId,
222
+ });
223
+ }
224
+ export function createManagedSandboxConfig(pool, sandboxId, token) {
225
+ return createCoreManagedSandboxConfig({
226
+ pool,
227
+ sandboxId,
228
+ token,
229
+ });
230
+ }
231
+ function countCompatibleQueuedDemand(tasks, pool) {
232
+ return tasks.filter((task) => isPreLaunchCompatible(task, pool)).length;
233
+ }
234
+ /** MVP pre-launch match: only target adapter and required capabilities. */
235
+ export function isPreLaunchCompatible(task, pool) {
236
+ const targetAdapter = task.target?.adapter;
237
+ if (targetAdapter && targetAdapter !== pool.adapter) {
238
+ return false;
239
+ }
240
+ const poolCapabilities = new Set([pool.adapter]);
241
+ return task.requiredCapabilities.every((capability) => poolCapabilities.has(capability));
242
+ }
243
+ //# sourceMappingURL=managed-sandbox-provisioner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"managed-sandbox-provisioner.js","sourceRoot":"","sources":["../src/managed-sandbox-provisioner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EACL,0BAA0B,IAAI,8BAA8B,GAG7D,MAAM,aAAa,CAAC;AAQrB,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAwErC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AACnC,MAAM,gBAAgB,GAAmC;IACvD,UAAU;IACV,MAAM;IACN,UAAU;CACX,CAAC;AAEF,yFAAyF;AACzF,MAAM,OAAO,yBAAyB;IACpC,MAAM,CAAwD;IAC9D,aAAa,CAA4B;IAChC,MAAM,CAAe;IACrB,SAAS,CAAoC;IAC7C,MAAM,CAAsC;IAC5C,QAAQ,CAAwB;IAChC,QAAQ,CAAoC;IAC5C,eAAe,CAAS;IACxB,gBAAgB,CAAS;IACzB,0BAA0B,CAErB;IAEd,YAAY,OAAyC;QACnD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAC5B,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC;QAClC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAC5B,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;QAChC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;QAChC,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;QAC9C,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,eAAe,IAAI,sBAAsB,CAAC;QAC1E,IAAI,CAAC,0BAA0B,GAAG,OAAO,CAAC,yBAAyB,CAAC;IACtE,CAAC;IAED,4EAA4E;IAC5E,IAAI;QACF,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC,aAAa,CAAC;QAC5B,CAAC;QAED,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;YAChD,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;QACjC,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED,iEAAiE;IACjE,KAAK;QACH,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,GAAG,EAAE;YACxC,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC1C,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;IAC3B,CAAC;IAED,+CAA+C;IAC/C,IAAI;QACF,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QAED,UAAU,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;YAC9C,KAAK,EAAE,IAAI,CAAC,gBAAgB;SAC7B,CAAC,CAAC;QAEH,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC/B,MAAM,sBAAsB,GAAG,2BAA2B,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACxE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAEhD,IAAI,sBAAsB,KAAK,CAAC,EAAE,CAAC;gBACjC,SAAS;YACX,CAAC;YAED,IACE,sBAAsB;gBACtB,QAAQ,CAAC,kBAAkB,GAAG,QAAQ,CAAC,aAAa,EACpD,CAAC;gBACD,SAAS;YACX,CAAC;YAED,IAAI,QAAQ,CAAC,eAAe,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClD,SAAS;YACX,CAAC;YAED,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,aAAa,CACjB,IAA8B;QAE9B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,2BAA2B,CAAC;YAC9D,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,QAAQ,EAAE,gBAAgB;SAC3B,CAAC,CAAC;QACH,IAAI,kBAAkB,GAAG,CAAC,CAAC;QAC3B,IAAI,aAAa,GAAG,CAAC,CAAC;QACtB,IAAI,eAAe,GAAG,CAAC,CAAC;QAExB,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,IAAI,QAAQ,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;gBACnC,eAAe,IAAI,CAAC,CAAC;gBACrB,aAAa,IAAI,IAAI,CAAC,cAAc,CAAC;gBACrC,SAAS;YACX,CAAC;YAED,IAAI,QAAQ,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;gBACnC,eAAe,IAAI,CAAC,CAAC;gBACrB,SAAS;YACX,CAAC;YAED,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YACxD,IAAI,YAAY,CAAC,cAAc,EAAE,CAAC;gBAChC,eAAe,IAAI,CAAC,CAAC;YACvB,CAAC;YACD,kBAAkB,IAAI,YAAY,CAAC,cAAc,CAAC;QACpD,CAAC;QAED,OAAO;YACL,kBAAkB;YAClB,aAAa;YACb,eAAe;SAChB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,aAAa,CACjB,QAAqC;QAErC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QACjE,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC7C,MAAM,IAAI,CAAC,MAAM,CAAC,gCAAgC,CAAC;gBACjD,UAAU,EAAE,QAAQ,CAAC,UAAU;gBAC/B,SAAS,EAAE,OAAO;oBAChB,CAAC,CAAC,0CAA0C;oBAC5C,CAAC,CAAC,qDAAqD;aAC1D,CAAC,CAAC;YACH,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;QACtD,CAAC;QAED,IACE,OAAO,CAAC,MAAM,KAAK,QAAQ;YAC3B,OAAO,CAAC,UAAU,EAAE,QAAQ,KAAK,IAAI;YACrC,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,EAC9D,CAAC;YACD,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;QACrD,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QAClE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC1E,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,IAA8B;QACjD,0EAA0E;QAC1E,oCAAoC;QACpC,MAAM,YAAY,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,4BAA4B,CAAC;YAC9D,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,YAAY;SACb,CAAC,CAAC;QACH,IAAI,CAAC,0BAA0B,EAAE,CAAC;YAChC,SAAS,EAAE,QAAQ,CAAC,SAAS;YAC7B,KAAK,EAAE,YAAY;SACpB,CAAC,CAAC;QACH,MAAM,aAAa,GAAG,0BAA0B,CAC9C,IAAI,EACJ,QAAQ,CAAC,SAAS,EAClB,YAAY,CACb,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;gBACvC,IAAI;gBACJ,QAAQ;gBACR,aAAa;aACd,CAAC,CAAC;YACH,IAAI,MAAM,CAAC,kBAAkB,EAAE,CAAC;gBAC9B,MAAM,IAAI,CAAC,MAAM,CAAC,iCAAiC,CAAC;oBAClD,UAAU,EAAE,QAAQ,CAAC,UAAU;oBAC/B,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;iBAC9C,CAAC,CAAC;YACL,CAAC;YACD,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBAClC,MAAM,SAAS,GACb,MAAM,CAAC,SAAS;oBAChB,mDAAmD,CAAC;gBACtD,IAAI,MAAM,CAAC,kBAAkB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAC/C,IAAI,CAAC;wBACH,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;4BACvB,QAAQ,EAAE;gCACR,GAAG,QAAQ;gCACX,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;6BAC9C;4BACD,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;yBAC9C,CAAC,CAAC;wBACH,MAAM,IAAI,CAAC,MAAM,CAAC,iCAAiC,CAAC;4BAClD,UAAU,EAAE,QAAQ,CAAC,UAAU;4BAC/B,SAAS;yBACV,CAAC,CAAC;wBACH,OAAO;oBACT,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,MAAM,IAAI,CAAC,MAAM,CAAC,gCAAgC,CAAC;4BACjD,UAAU,EAAE,QAAQ,CAAC,UAAU;4BAC/B,SAAS,EAAE,GAAG,SAAS,qBAAqB,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE;yBACrE,CAAC,CAAC;wBACH,OAAO;oBACT,CAAC;gBACH,CAAC;gBACD,MAAM,IAAI,CAAC,MAAM,CAAC,gCAAgC,CAAC;oBACjD,UAAU,EAAE,QAAQ,CAAC,UAAU;oBAC/B,SAAS;iBACV,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC;YACzC,MAAM,IAAI,CAAC,MAAM,CAAC,gCAAgC,CAAC;gBACjD,UAAU,EAAE,QAAQ,CAAC,UAAU;gBAC/B,SAAS;aACV,CAAC,CAAC;QACL,CAAC;IACH,CAAC;CACF;AAED,+DAA+D;AAC/D,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,KAAuC;IAEvC,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,2BAA2B,CAAC;QAC9D,QAAQ,EAAE,gBAAgB;KAC3B,CAAC,CAAC;IACH,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,0BAA0B,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC3D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,KAAK,CAAC,KAAK,CAAC,gCAAgC,CAAC;gBACjD,UAAU,EAAE,QAAQ,CAAC,UAAU;gBAC/B,SAAS,EAAE,mCAAmC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE;aACvE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;AACH,CAAC;AAED,KAAK,UAAU,0BAA0B,CAAC,KAIzC;IACC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC;QACvC,OAAO;IACT,CAAC;IAED,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QACvB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,kBAAkB,EAAE,KAAK,CAAC,QAAQ,CAAC,kBAAkB;KACtD,CAAC,CAAC;IACH,MAAM,KAAK,CAAC,KAAK,CAAC,iCAAiC,CAAC;QAClD,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,UAAU;KACtC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,IAA8B,EAC9B,SAAiB,EACjB,KAAa;IAEb,OAAO,8BAA8B,CAAC;QACpC,IAAI;QACJ,SAAS;QACT,KAAK;KACN,CAAC,CAAC;AACL,CAAC;AAED,SAAS,2BAA2B,CAClC,KAA2B,EAC3B,IAA8B;IAE9B,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;AAC1E,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,qBAAqB,CACnC,IAAe,EACf,IAA8B;IAE9B,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC;IAC3C,IAAI,aAAa,IAAI,aAAa,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;QACpD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACzD,OAAO,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE,EAAE,CACpD,gBAAgB,CAAC,GAAG,CAAC,UAAU,CAAC,CACjC,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"hosts.d.ts","sourceRoot":"","sources":["../../src/routes/hosts.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAE7D,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,wBAAwB,QAKnE"}
1
+ {"version":3,"file":"hosts.d.ts","sourceRoot":"","sources":["../../src/routes/hosts.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAE7D,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,wBAAwB,QAMnE"}
@@ -1,3 +1,4 @@
1
+ import { ProjectKeySchema } from "@flakes/core";
1
2
  import { HOST_PROVISIONING_QUOTAS, HostProvisioningQuotaError, } from "@flakes/store";
2
3
  import { mustUserAuth } from "../auth.js";
3
4
  import { handleHostStream } from "../host-stream.js";
@@ -7,6 +8,7 @@ export function registerHostRoutes(context) {
7
8
  registerHostStreamRoutes(context);
8
9
  registerHostCrudRoutes(context);
9
10
  registerHostPoolRoutes(context);
11
+ registerHostProjectRoutes(context);
10
12
  registerHostCredentialRoutes(context);
11
13
  }
12
14
  function registerHostStreamRoutes(context) {
@@ -171,6 +173,112 @@ function registerHostPoolRoutes(context) {
171
173
  return pool ? reply.send(hostPoolDto(pool)) : notFound(reply);
172
174
  });
173
175
  }
176
+ function registerHostProjectRoutes(context) {
177
+ const { app, options, requireScope } = context;
178
+ app.put("/v1/hosts/:hostId/project-workspace-root", { preValidation: requireScope("client") }, async (request, reply) => {
179
+ const auth = mustUserAuth(request);
180
+ const body = requestBody(request, reply);
181
+ if (!body) {
182
+ return;
183
+ }
184
+ const projectWorkspaceRoot = absoluteHostPath(body.path, "path", reply);
185
+ if (!projectWorkspaceRoot) {
186
+ return;
187
+ }
188
+ const host = await options.store.setHostProjectWorkspaceRoot({
189
+ ownerKey: auth.ownerKey,
190
+ hostId: request.params.hostId,
191
+ projectWorkspaceRoot,
192
+ });
193
+ return host
194
+ ? reply.send(hostProjectWorkspaceRootDto(host))
195
+ : notFound(reply);
196
+ });
197
+ app.put("/v1/hosts/:hostId/project-bindings/:projectKey", { preValidation: requireScope("client") }, async (request, reply) => {
198
+ const auth = mustUserAuth(request);
199
+ const projectKey = routeProjectKey(request.params.projectKey, reply);
200
+ if (!projectKey) {
201
+ return;
202
+ }
203
+ const body = requestBody(request, reply);
204
+ if (!body) {
205
+ return;
206
+ }
207
+ const poolKeys = poolKeysField(body.poolKeys, "poolKeys", reply);
208
+ if (!poolKeys) {
209
+ return;
210
+ }
211
+ const host = await options.store.getHost({
212
+ ownerKey: auth.ownerKey,
213
+ hostId: request.params.hostId,
214
+ });
215
+ if (!host) {
216
+ return notFound(reply);
217
+ }
218
+ if (!host.projectWorkspaceRoot) {
219
+ return hostProjectWorkspaceRootRequired(reply);
220
+ }
221
+ const projectWorkspaceRoot = host.projectWorkspaceRoot;
222
+ const project = await options.store.getProject({
223
+ ownerKey: auth.ownerKey,
224
+ projectKey,
225
+ });
226
+ if (!project) {
227
+ return projectNotFound(reply);
228
+ }
229
+ if (project.status !== "active") {
230
+ return reply.code(409).send({
231
+ error: "project_archived",
232
+ message: "project is archived",
233
+ projectKey,
234
+ });
235
+ }
236
+ const existingPools = await options.store.listHostPools({
237
+ ownerKey: auth.ownerKey,
238
+ hostId: request.params.hostId,
239
+ });
240
+ const existingPoolKeys = new Set(existingPools.map((pool) => pool.poolKey));
241
+ const unknownPoolKeys = poolKeys.filter((poolKey) => !existingPoolKeys.has(poolKey));
242
+ if (unknownPoolKeys.length > 0) {
243
+ return reply.code(400).send({
244
+ error: "unknown_host_pool_keys",
245
+ message: "one or more pool keys are not configured for this host",
246
+ poolKeys: unknownPoolKeys,
247
+ });
248
+ }
249
+ const binding = await handleHostQuotaError(reply, () => options.store.upsertHostProjectBinding({
250
+ ownerKey: auth.ownerKey,
251
+ hostId: request.params.hostId,
252
+ projectKey,
253
+ allowedPoolKeys: poolKeys,
254
+ }));
255
+ if (!binding) {
256
+ return;
257
+ }
258
+ return reply.send(hostProjectBindingDto(binding, projectWorkspaceRoot));
259
+ });
260
+ app.get("/v1/hosts/:hostId/project-bindings", { preValidation: requireScope("client") }, async (request, reply) => {
261
+ const auth = mustUserAuth(request);
262
+ const host = await options.store.getHost({
263
+ ownerKey: auth.ownerKey,
264
+ hostId: request.params.hostId,
265
+ });
266
+ if (!host) {
267
+ return notFound(reply);
268
+ }
269
+ if (!host.projectWorkspaceRoot) {
270
+ return hostProjectWorkspaceRootRequired(reply);
271
+ }
272
+ const projectWorkspaceRoot = host.projectWorkspaceRoot;
273
+ const bindings = await options.store.listHostProjectBindings({
274
+ ownerKey: auth.ownerKey,
275
+ hostId: request.params.hostId,
276
+ });
277
+ return reply.send({
278
+ bindings: bindings.map((binding) => hostProjectBindingDto(binding, projectWorkspaceRoot)),
279
+ });
280
+ });
281
+ }
174
282
  function registerHostCredentialRoutes(context) {
175
283
  const { app, options, requireScope } = context;
176
284
  app.post("/v1/hosts/setup", { preValidation: requireScope("client") }, async (request, reply) => {
@@ -376,6 +484,85 @@ function requiredBodyString(value, field, reply) {
376
484
  }
377
485
  return value;
378
486
  }
487
+ function absoluteHostPath(value, field, reply) {
488
+ if (typeof value !== "string") {
489
+ reply.code(400).send({
490
+ error: "invalid_request",
491
+ message: `${field} must be an absolute path`,
492
+ field,
493
+ });
494
+ return undefined;
495
+ }
496
+ const trimmed = value.trim();
497
+ if (!isAbsoluteHostPath(trimmed)) {
498
+ reply.code(400).send({
499
+ error: "invalid_request",
500
+ message: `${field} must be an absolute path`,
501
+ field,
502
+ });
503
+ return undefined;
504
+ }
505
+ return trimmed;
506
+ }
507
+ function isAbsoluteHostPath(value) {
508
+ return (value.startsWith("/") ||
509
+ /^[A-Za-z]:[\\/]/.test(value) ||
510
+ value.startsWith("\\\\"));
511
+ }
512
+ function routeProjectKey(value, reply) {
513
+ const parsed = ProjectKeySchema.safeParse(value);
514
+ if (!parsed.success) {
515
+ reply.code(400).send({
516
+ error: "invalid_request",
517
+ message: "projectKey is invalid",
518
+ field: "projectKey",
519
+ });
520
+ return undefined;
521
+ }
522
+ return parsed.data;
523
+ }
524
+ function poolKeysField(value, field, reply) {
525
+ if (!Array.isArray(value)) {
526
+ reply.code(400).send({
527
+ error: "invalid_request",
528
+ message: `${field} must be a non-empty array of strings`,
529
+ field,
530
+ });
531
+ return undefined;
532
+ }
533
+ const parsed = value.map((item) => poolKeyString(item));
534
+ if (parsed.length === 0 || !parsed.every(isString)) {
535
+ reply.code(400).send({
536
+ error: "invalid_request",
537
+ message: `${field} must be a non-empty array of strings`,
538
+ field,
539
+ });
540
+ return undefined;
541
+ }
542
+ return [...new Set(parsed)];
543
+ }
544
+ function poolKeyString(value) {
545
+ if (typeof value !== "string") {
546
+ return undefined;
547
+ }
548
+ const trimmed = value.trim();
549
+ return trimmed.length > 0 ? trimmed : undefined;
550
+ }
551
+ function isString(value) {
552
+ return value !== undefined;
553
+ }
554
+ function projectNotFound(reply) {
555
+ return reply.code(404).send({
556
+ error: "project_not_found",
557
+ message: "project not found",
558
+ });
559
+ }
560
+ function hostProjectWorkspaceRootRequired(reply) {
561
+ return reply.code(409).send({
562
+ error: "host_project_workspace_root_required",
563
+ message: "host project workspace root is not configured",
564
+ });
565
+ }
379
566
  const invalidMetadata = Symbol("invalidMetadata");
380
567
  const allowedHostUpdateFields = new Set(["name", "metadata"]);
381
568
  const forbiddenHostUserMetadataKeys = new Set([
@@ -497,6 +684,7 @@ function hostDto(host) {
497
684
  hostId: host.hostId,
498
685
  name: host.name,
499
686
  status: host.status,
687
+ projectWorkspaceRoot: host.projectWorkspaceRoot,
500
688
  lastSeenAt: host.lastSeenAt,
501
689
  platform: host.platform,
502
690
  arch: host.arch,
@@ -506,6 +694,37 @@ function hostDto(host) {
506
694
  updatedAt: host.updatedAt,
507
695
  };
508
696
  }
697
+ function hostProjectWorkspaceRootDto(host) {
698
+ return {
699
+ hostId: host.hostId,
700
+ projectWorkspaceRoot: host.projectWorkspaceRoot,
701
+ updatedAt: host.updatedAt,
702
+ };
703
+ }
704
+ function hostProjectBindingDto(binding, projectWorkspaceRoot) {
705
+ return {
706
+ hostProjectBindingId: binding.bindingId,
707
+ hostId: binding.hostId,
708
+ projectId: binding.projectId,
709
+ projectKey: binding.projectKey,
710
+ workspacePath: hostProjectWorkspacePath(projectWorkspaceRoot, binding.projectKey),
711
+ poolKeys: binding.allowedPoolKeys,
712
+ availability: binding.availability,
713
+ lastValidatedAt: binding.lastValidatedAt,
714
+ validationReason: binding.unavailableReason,
715
+ createdAt: binding.createdAt,
716
+ updatedAt: binding.updatedAt,
717
+ };
718
+ }
719
+ function hostProjectWorkspacePath(projectWorkspaceRoot, projectKey) {
720
+ const separator = projectWorkspaceRoot.includes("\\") && !projectWorkspaceRoot.includes("/")
721
+ ? "\\"
722
+ : "/";
723
+ return projectWorkspaceRoot.endsWith("/") ||
724
+ projectWorkspaceRoot.endsWith("\\")
725
+ ? `${projectWorkspaceRoot}${projectKey}`
726
+ : `${projectWorkspaceRoot}${separator}${projectKey}`;
727
+ }
509
728
  function hostPoolDto(pool) {
510
729
  return {
511
730
  hostPoolId: pool.hostPoolId,