@shipfox/api-runners 5.0.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (414) hide show
  1. package/.turbo/turbo-build.log +6 -6
  2. package/CHANGELOG.md +61 -0
  3. package/dist/config.d.ts +5 -1
  4. package/dist/config.d.ts.map +1 -1
  5. package/dist/config.js +53 -6
  6. package/dist/config.js.map +1 -1
  7. package/dist/core/capacity-assignments.d.ts +7 -0
  8. package/dist/core/capacity-assignments.d.ts.map +1 -0
  9. package/dist/core/capacity-assignments.js +6 -0
  10. package/dist/core/capacity-assignments.js.map +1 -0
  11. package/dist/core/demand.d.ts +6 -6
  12. package/dist/core/demand.d.ts.map +1 -1
  13. package/dist/core/demand.js +10 -10
  14. package/dist/core/demand.js.map +1 -1
  15. package/dist/core/entities/capacity-assignment.d.ts +9 -0
  16. package/dist/core/entities/capacity-assignment.d.ts.map +1 -0
  17. package/dist/core/entities/capacity-assignment.js +3 -0
  18. package/dist/core/entities/capacity-assignment.js.map +1 -0
  19. package/dist/core/entities/ephemeral-registration-token.d.ts +1 -1
  20. package/dist/core/entities/ephemeral-registration-token.d.ts.map +1 -1
  21. package/dist/core/entities/ephemeral-registration-token.js.map +1 -1
  22. package/dist/core/entities/provisioner-capability-snapshot.d.ts +13 -0
  23. package/dist/core/entities/provisioner-capability-snapshot.d.ts.map +1 -0
  24. package/dist/core/entities/provisioner-capability-snapshot.js +3 -0
  25. package/dist/core/entities/provisioner-capability-snapshot.js.map +1 -0
  26. package/dist/core/entities/provisioner-token.d.ts +10 -2
  27. package/dist/core/entities/provisioner-token.d.ts.map +1 -1
  28. package/dist/core/entities/provisioner-token.js.map +1 -1
  29. package/dist/core/entities/{provisioned-runner.d.ts → runner-instance.d.ts} +6 -6
  30. package/dist/core/entities/runner-instance.d.ts.map +1 -0
  31. package/dist/core/entities/runner-instance.js +3 -0
  32. package/dist/core/entities/runner-instance.js.map +1 -0
  33. package/dist/core/entities/runner-session.d.ts +4 -2
  34. package/dist/core/entities/runner-session.d.ts.map +1 -1
  35. package/dist/core/entities/runner-session.js.map +1 -1
  36. package/dist/core/ephemeral-registration-tokens.d.ts +5 -5
  37. package/dist/core/ephemeral-registration-tokens.d.ts.map +1 -1
  38. package/dist/core/ephemeral-registration-tokens.js +12 -12
  39. package/dist/core/ephemeral-registration-tokens.js.map +1 -1
  40. package/dist/core/errors.d.ts +16 -4
  41. package/dist/core/errors.d.ts.map +1 -1
  42. package/dist/core/errors.js +22 -4
  43. package/dist/core/errors.js.map +1 -1
  44. package/dist/core/index.d.ts +10 -4
  45. package/dist/core/index.d.ts.map +1 -1
  46. package/dist/core/index.js +6 -2
  47. package/dist/core/index.js.map +1 -1
  48. package/dist/core/job-executions.d.ts +2 -0
  49. package/dist/core/job-executions.d.ts.map +1 -1
  50. package/dist/core/job-executions.js +1 -2
  51. package/dist/core/job-executions.js.map +1 -1
  52. package/dist/core/maintenance.d.ts +1 -1
  53. package/dist/core/maintenance.d.ts.map +1 -1
  54. package/dist/core/maintenance.js +5 -5
  55. package/dist/core/maintenance.js.map +1 -1
  56. package/dist/core/provisioner-capability-snapshots.d.ts +5 -0
  57. package/dist/core/provisioner-capability-snapshots.d.ts.map +1 -0
  58. package/dist/core/provisioner-capability-snapshots.js +10 -0
  59. package/dist/core/provisioner-capability-snapshots.js.map +1 -0
  60. package/dist/core/provisioner-tokens.d.ts +10 -0
  61. package/dist/core/provisioner-tokens.d.ts.map +1 -1
  62. package/dist/core/provisioner-tokens.js +23 -1
  63. package/dist/core/provisioner-tokens.js.map +1 -1
  64. package/dist/core/rate-limit.d.ts.map +1 -1
  65. package/dist/core/rate-limit.js +2 -7
  66. package/dist/core/rate-limit.js.map +1 -1
  67. package/dist/core/runner-activation.d.ts +13 -0
  68. package/dist/core/runner-activation.d.ts.map +1 -0
  69. package/dist/core/runner-activation.js +36 -0
  70. package/dist/core/runner-activation.js.map +1 -0
  71. package/dist/core/runner-control-sessions.d.ts +46 -0
  72. package/dist/core/runner-control-sessions.d.ts.map +1 -0
  73. package/dist/core/runner-control-sessions.js +121 -0
  74. package/dist/core/runner-control-sessions.js.map +1 -0
  75. package/dist/core/runner-instances.d.ts +79 -0
  76. package/dist/core/runner-instances.d.ts.map +1 -0
  77. package/dist/core/runner-instances.js +168 -0
  78. package/dist/core/runner-instances.js.map +1 -0
  79. package/dist/core/runner-sessions.d.ts +8 -2
  80. package/dist/core/runner-sessions.d.ts.map +1 -1
  81. package/dist/core/runner-sessions.js +8 -5
  82. package/dist/core/runner-sessions.js.map +1 -1
  83. package/dist/db/capacity-assignments.d.ts +7 -0
  84. package/dist/db/capacity-assignments.d.ts.map +1 -0
  85. package/dist/db/capacity-assignments.js +72 -0
  86. package/dist/db/capacity-assignments.js.map +1 -0
  87. package/dist/db/db.d.ts +2837 -1009
  88. package/dist/db/db.d.ts.map +1 -1
  89. package/dist/db/db.js +11 -2
  90. package/dist/db/db.js.map +1 -1
  91. package/dist/db/ephemeral-registration-tokens.d.ts +2 -2
  92. package/dist/db/ephemeral-registration-tokens.d.ts.map +1 -1
  93. package/dist/db/ephemeral-registration-tokens.js +21 -21
  94. package/dist/db/ephemeral-registration-tokens.js.map +1 -1
  95. package/dist/db/index.d.ts +7 -4
  96. package/dist/db/index.d.ts.map +1 -1
  97. package/dist/db/index.js +5 -2
  98. package/dist/db/index.js.map +1 -1
  99. package/dist/db/job-executions.d.ts +6 -6
  100. package/dist/db/job-executions.d.ts.map +1 -1
  101. package/dist/db/job-executions.js +20 -19
  102. package/dist/db/job-executions.js.map +1 -1
  103. package/dist/db/provisioner-capability-snapshots.d.ts +21 -0
  104. package/dist/db/provisioner-capability-snapshots.d.ts.map +1 -0
  105. package/dist/db/provisioner-capability-snapshots.js +57 -0
  106. package/dist/db/provisioner-capability-snapshots.js.map +1 -0
  107. package/dist/db/provisioner-tokens.d.ts +7 -2
  108. package/dist/db/provisioner-tokens.d.ts.map +1 -1
  109. package/dist/db/provisioner-tokens.js +59 -10
  110. package/dist/db/provisioner-tokens.js.map +1 -1
  111. package/dist/db/reservations.d.ts +18 -0
  112. package/dist/db/reservations.d.ts.map +1 -1
  113. package/dist/db/reservations.js +88 -1
  114. package/dist/db/reservations.js.map +1 -1
  115. package/dist/db/runner-instances.d.ts +91 -0
  116. package/dist/db/runner-instances.d.ts.map +1 -0
  117. package/dist/db/runner-instances.js +511 -0
  118. package/dist/db/runner-instances.js.map +1 -0
  119. package/dist/db/runner-sessions.d.ts +5 -0
  120. package/dist/db/runner-sessions.d.ts.map +1 -1
  121. package/dist/db/runner-sessions.js +48 -2
  122. package/dist/db/runner-sessions.js.map +1 -1
  123. package/dist/db/schema/capacity-assignments.d.ts +113 -0
  124. package/dist/db/schema/capacity-assignments.d.ts.map +1 -0
  125. package/dist/db/schema/capacity-assignments.js +29 -0
  126. package/dist/db/schema/capacity-assignments.js.map +1 -0
  127. package/dist/db/schema/ephemeral-registration-tokens.d.ts +2 -2
  128. package/dist/db/schema/ephemeral-registration-tokens.js +3 -3
  129. package/dist/db/schema/ephemeral-registration-tokens.js.map +1 -1
  130. package/dist/db/schema/provisioner-capability-snapshots.d.ts +207 -0
  131. package/dist/db/schema/provisioner-capability-snapshots.d.ts.map +1 -0
  132. package/dist/db/schema/provisioner-capability-snapshots.js +38 -0
  133. package/dist/db/schema/provisioner-capability-snapshots.js.map +1 -0
  134. package/dist/db/schema/provisioner-tokens.d.ts +19 -1
  135. package/dist/db/schema/provisioner-tokens.d.ts.map +1 -1
  136. package/dist/db/schema/provisioner-tokens.js +29 -3
  137. package/dist/db/schema/provisioner-tokens.js.map +1 -1
  138. package/dist/db/schema/runner-activation-tokens.d.ts +161 -0
  139. package/dist/db/schema/runner-activation-tokens.d.ts.map +1 -0
  140. package/dist/db/schema/runner-activation-tokens.js +27 -0
  141. package/dist/db/schema/runner-activation-tokens.js.map +1 -0
  142. package/dist/db/schema/runner-control-sessions.d.ts +338 -0
  143. package/dist/db/schema/runner-control-sessions.d.ts.map +1 -0
  144. package/dist/db/schema/runner-control-sessions.js +52 -0
  145. package/dist/db/schema/runner-control-sessions.js.map +1 -0
  146. package/dist/db/schema/{provisioned-runners.d.ts → runner-instances.d.ts} +88 -34
  147. package/dist/db/schema/runner-instances.d.ts.map +1 -0
  148. package/dist/db/schema/{provisioned-runners.js → runner-instances.js} +19 -14
  149. package/dist/db/schema/runner-instances.js.map +1 -0
  150. package/dist/db/schema/runner-sessions.d.ts +39 -5
  151. package/dist/db/schema/runner-sessions.d.ts.map +1 -1
  152. package/dist/db/schema/runner-sessions.js +13 -6
  153. package/dist/db/schema/runner-sessions.js.map +1 -1
  154. package/dist/db/schema/running-job-executions.d.ts +2 -2
  155. package/dist/db/schema/running-job-executions.js +4 -4
  156. package/dist/db/schema/running-job-executions.js.map +1 -1
  157. package/dist/index.d.ts +7 -2
  158. package/dist/index.d.ts.map +1 -1
  159. package/dist/index.js +45 -38
  160. package/dist/index.js.map +1 -1
  161. package/dist/installation-provisioning.d.ts +14 -0
  162. package/dist/installation-provisioning.d.ts.map +1 -0
  163. package/dist/installation-provisioning.js +7 -0
  164. package/dist/installation-provisioning.js.map +1 -0
  165. package/dist/metrics/index.d.ts +1 -1
  166. package/dist/metrics/index.d.ts.map +1 -1
  167. package/dist/metrics/index.js +1 -1
  168. package/dist/metrics/index.js.map +1 -1
  169. package/dist/metrics/instance.d.ts +11 -7
  170. package/dist/metrics/instance.d.ts.map +1 -1
  171. package/dist/metrics/instance.js +13 -7
  172. package/dist/metrics/instance.js.map +1 -1
  173. package/dist/presentation/auth/index.d.ts +1 -0
  174. package/dist/presentation/auth/index.d.ts.map +1 -1
  175. package/dist/presentation/auth/index.js +1 -0
  176. package/dist/presentation/auth/index.js.map +1 -1
  177. package/dist/presentation/auth/provisioner-token-auth.d.ts.map +1 -1
  178. package/dist/presentation/auth/provisioner-token-auth.js +5 -1
  179. package/dist/presentation/auth/provisioner-token-auth.js.map +1 -1
  180. package/dist/presentation/auth/runner-control-session-auth.d.ts +4 -0
  181. package/dist/presentation/auth/runner-control-session-auth.d.ts.map +1 -0
  182. package/dist/presentation/auth/runner-control-session-auth.js +29 -0
  183. package/dist/presentation/auth/runner-control-session-auth.js.map +1 -0
  184. package/dist/presentation/auth/runner-registration-token-auth.d.ts +5 -1
  185. package/dist/presentation/auth/runner-registration-token-auth.d.ts.map +1 -1
  186. package/dist/presentation/auth/runner-registration-token-auth.js +21 -1
  187. package/dist/presentation/auth/runner-registration-token-auth.js.map +1 -1
  188. package/dist/presentation/dto/index.d.ts +2 -2
  189. package/dist/presentation/dto/index.d.ts.map +1 -1
  190. package/dist/presentation/dto/index.js +2 -2
  191. package/dist/presentation/dto/index.js.map +1 -1
  192. package/dist/presentation/dto/mint-registration-tokens.d.ts +5 -3
  193. package/dist/presentation/dto/mint-registration-tokens.d.ts.map +1 -1
  194. package/dist/presentation/dto/mint-registration-tokens.js +4 -4
  195. package/dist/presentation/dto/mint-registration-tokens.js.map +1 -1
  196. package/dist/presentation/dto/poll-demand.d.ts.map +1 -1
  197. package/dist/presentation/dto/poll-demand.js +7 -1
  198. package/dist/presentation/dto/poll-demand.js.map +1 -1
  199. package/dist/presentation/dto/provisioner-token.d.ts +1 -0
  200. package/dist/presentation/dto/provisioner-token.d.ts.map +1 -1
  201. package/dist/presentation/dto/provisioner-token.js +5 -1
  202. package/dist/presentation/dto/provisioner-token.js.map +1 -1
  203. package/dist/presentation/dto/{provisioned-runners.d.ts → runner-instances.d.ts} +9 -9
  204. package/dist/presentation/dto/runner-instances.d.ts.map +1 -0
  205. package/dist/presentation/dto/{provisioned-runners.js → runner-instances.js} +6 -6
  206. package/dist/presentation/dto/runner-instances.js.map +1 -0
  207. package/dist/presentation/index.d.ts +2 -2
  208. package/dist/presentation/index.d.ts.map +1 -1
  209. package/dist/presentation/index.js +2 -2
  210. package/dist/presentation/index.js.map +1 -1
  211. package/dist/presentation/inter-module.d.ts +5 -0
  212. package/dist/presentation/inter-module.d.ts.map +1 -0
  213. package/dist/presentation/inter-module.js +43 -0
  214. package/dist/presentation/inter-module.js.map +1 -0
  215. package/dist/presentation/routes/assign-capacity.d.ts +2 -0
  216. package/dist/presentation/routes/assign-capacity.d.ts.map +1 -0
  217. package/dist/presentation/routes/assign-capacity.js +44 -0
  218. package/dist/presentation/routes/assign-capacity.js.map +1 -0
  219. package/dist/presentation/routes/get-provisioner-me.d.ts.map +1 -1
  220. package/dist/presentation/routes/get-provisioner-me.js +5 -1
  221. package/dist/presentation/routes/get-provisioner-me.js.map +1 -1
  222. package/dist/presentation/routes/heartbeat.d.ts +2 -1
  223. package/dist/presentation/routes/heartbeat.d.ts.map +1 -1
  224. package/dist/presentation/routes/heartbeat.js +60 -50
  225. package/dist/presentation/routes/heartbeat.js.map +1 -1
  226. package/dist/presentation/routes/index.d.ts +3 -1
  227. package/dist/presentation/routes/index.d.ts.map +1 -1
  228. package/dist/presentation/routes/index.js +83 -50
  229. package/dist/presentation/routes/index.js.map +1 -1
  230. package/dist/presentation/routes/mint-registration-tokens.d.ts.map +1 -1
  231. package/dist/presentation/routes/mint-registration-tokens.js +5 -5
  232. package/dist/presentation/routes/mint-registration-tokens.js.map +1 -1
  233. package/dist/presentation/routes/planned-capacity.d.ts +3 -0
  234. package/dist/presentation/routes/planned-capacity.d.ts.map +1 -0
  235. package/dist/presentation/routes/planned-capacity.js +54 -0
  236. package/dist/presentation/routes/planned-capacity.js.map +1 -0
  237. package/dist/presentation/routes/poll-demand.d.ts +2 -0
  238. package/dist/presentation/routes/poll-demand.d.ts.map +1 -1
  239. package/dist/presentation/routes/poll-demand.js +86 -45
  240. package/dist/presentation/routes/poll-demand.js.map +1 -1
  241. package/dist/presentation/routes/reconcile-runner-instances.d.ts +2 -0
  242. package/dist/presentation/routes/reconcile-runner-instances.d.ts.map +1 -0
  243. package/dist/presentation/routes/reconcile-runner-instances.js +27 -0
  244. package/dist/presentation/routes/reconcile-runner-instances.js.map +1 -0
  245. package/dist/presentation/routes/register.d.ts +2 -1
  246. package/dist/presentation/routes/register.d.ts.map +1 -1
  247. package/dist/presentation/routes/register.js +55 -52
  248. package/dist/presentation/routes/register.js.map +1 -1
  249. package/dist/presentation/routes/report-runner-instances.d.ts +2 -0
  250. package/dist/presentation/routes/report-runner-instances.d.ts.map +1 -0
  251. package/dist/presentation/routes/report-runner-instances.js +37 -0
  252. package/dist/presentation/routes/report-runner-instances.js.map +1 -0
  253. package/dist/presentation/routes/request-job.d.ts +2 -1
  254. package/dist/presentation/routes/request-job.d.ts.map +1 -1
  255. package/dist/presentation/routes/request-job.js +39 -36
  256. package/dist/presentation/routes/request-job.js.map +1 -1
  257. package/dist/presentation/routes/runner-enrollment.d.ts +7 -0
  258. package/dist/presentation/routes/runner-enrollment.d.ts.map +1 -0
  259. package/dist/presentation/routes/runner-enrollment.js +185 -0
  260. package/dist/presentation/routes/runner-enrollment.js.map +1 -0
  261. package/dist/temporal/activities/index.d.ts +2 -2
  262. package/dist/temporal/activities/index.d.ts.map +1 -1
  263. package/dist/temporal/activities/index.js +2 -2
  264. package/dist/temporal/activities/index.js.map +1 -1
  265. package/dist/temporal/activities/maintenance-activities.d.ts +1 -1
  266. package/dist/temporal/activities/maintenance-activities.d.ts.map +1 -1
  267. package/dist/temporal/activities/maintenance-activities.js +3 -3
  268. package/dist/temporal/activities/maintenance-activities.js.map +1 -1
  269. package/dist/temporal/workflows/index.bundle.js +3 -3
  270. package/dist/temporal/workflows/stuck-job-detector.js +2 -2
  271. package/dist/temporal/workflows/stuck-job-detector.js.map +1 -1
  272. package/dist/tsconfig.test.tsbuildinfo +1 -1
  273. package/drizzle/0000_initial.sql +102 -24
  274. package/drizzle/meta/0000_snapshot.json +483 -63
  275. package/package.json +21 -16
  276. package/src/config.test.ts +0 -26
  277. package/src/config.ts +47 -6
  278. package/src/core/capacity-assignments.ts +10 -0
  279. package/src/core/demand.test.ts +29 -29
  280. package/src/core/demand.ts +22 -22
  281. package/src/core/entities/capacity-assignment.ts +8 -0
  282. package/src/core/entities/ephemeral-registration-token.ts +1 -1
  283. package/src/core/entities/provisioner-capability-snapshot.ts +12 -0
  284. package/src/core/entities/provisioner-token.ts +8 -2
  285. package/src/core/entities/{provisioned-runner.ts → runner-instance.ts} +5 -5
  286. package/src/core/entities/runner-session.ts +4 -2
  287. package/src/core/ephemeral-registration-tokens.test.ts +11 -11
  288. package/src/core/ephemeral-registration-tokens.ts +18 -20
  289. package/src/core/errors.ts +23 -4
  290. package/src/core/index.ts +39 -17
  291. package/src/core/job-executions.ts +3 -2
  292. package/src/core/maintenance.test.ts +13 -17
  293. package/src/core/maintenance.ts +5 -5
  294. package/src/core/provisioner-capability-snapshots.test.ts +35 -0
  295. package/src/core/provisioner-capability-snapshots.ts +12 -0
  296. package/src/core/provisioner-tokens.test.ts +20 -0
  297. package/src/core/provisioner-tokens.ts +33 -0
  298. package/src/core/rate-limit.test.ts +11 -27
  299. package/src/core/rate-limit.ts +3 -11
  300. package/src/core/runner-activation.ts +72 -0
  301. package/src/core/runner-control-sessions.ts +190 -0
  302. package/src/core/{provisioned-runners.test.ts → runner-instances.test.ts} +24 -24
  303. package/src/core/runner-instances.ts +310 -0
  304. package/src/core/runner-sessions.test.ts +112 -22
  305. package/src/core/runner-sessions.ts +25 -14
  306. package/src/db/capacity-assignments.test.ts +159 -0
  307. package/src/db/capacity-assignments.ts +116 -0
  308. package/src/db/db.ts +11 -2
  309. package/src/db/ephemeral-registration-tokens.test.ts +9 -9
  310. package/src/db/ephemeral-registration-tokens.ts +26 -26
  311. package/src/db/index.ts +31 -21
  312. package/src/db/job-executions.test.ts +13 -11
  313. package/src/db/job-executions.ts +33 -27
  314. package/src/db/provisioner-capability-snapshots.test.ts +175 -0
  315. package/src/db/provisioner-capability-snapshots.ts +130 -0
  316. package/src/db/provisioner-tokens.test.ts +139 -2
  317. package/src/db/provisioner-tokens.ts +123 -15
  318. package/src/db/reservations.test.ts +49 -0
  319. package/src/db/reservations.ts +146 -1
  320. package/src/db/{provisioned-runners.test.ts → runner-instances.test.ts} +429 -353
  321. package/src/db/runner-instances.ts +942 -0
  322. package/src/db/runner-sessions.test.ts +19 -6
  323. package/src/db/runner-sessions.ts +78 -2
  324. package/src/db/schema/capacity-assignments.ts +34 -0
  325. package/src/db/schema/ephemeral-registration-tokens.ts +4 -4
  326. package/src/db/schema/provisioner-capability-snapshots.ts +46 -0
  327. package/src/db/schema/provisioner-tokens.ts +33 -2
  328. package/src/db/schema/runner-activation-tokens.ts +22 -0
  329. package/src/db/schema/runner-control-sessions.ts +46 -0
  330. package/src/db/schema/{provisioned-runners.ts → runner-instances.ts} +26 -27
  331. package/src/db/schema/runner-sessions.ts +11 -7
  332. package/src/db/schema/running-job-executions.ts +5 -5
  333. package/src/index.test.ts +26 -0
  334. package/src/index.ts +39 -19
  335. package/src/installation-provisioning.ts +14 -0
  336. package/src/metrics/index.ts +5 -5
  337. package/src/metrics/instance.ts +25 -14
  338. package/src/presentation/auth/index.ts +4 -0
  339. package/src/presentation/auth/provisioner-token-auth.ts +8 -4
  340. package/src/presentation/auth/runner-control-session-auth.ts +31 -0
  341. package/src/presentation/auth/runner-registration-token-auth.ts +39 -3
  342. package/src/presentation/dto/index.ts +5 -5
  343. package/src/presentation/dto/mint-registration-tokens.ts +8 -15
  344. package/src/presentation/dto/poll-demand.ts +3 -1
  345. package/src/presentation/dto/provisioner-token.ts +5 -0
  346. package/src/presentation/dto/{provisioned-runners.ts → runner-instances.ts} +13 -15
  347. package/src/presentation/index.ts +2 -1
  348. package/src/presentation/inter-module.test.ts +15 -0
  349. package/src/presentation/inter-module.ts +53 -0
  350. package/src/presentation/routes/assign-capacity.ts +48 -0
  351. package/src/presentation/routes/get-provisioner-me.ts +3 -4
  352. package/src/presentation/routes/heartbeat.test.ts +4 -3
  353. package/src/presentation/routes/heartbeat.ts +67 -64
  354. package/src/presentation/routes/index.ts +93 -43
  355. package/src/presentation/routes/list-active-runners.test.ts +23 -23
  356. package/src/presentation/routes/manual-registration-tokens.test.ts +4 -3
  357. package/src/presentation/routes/mint-registration-tokens.test.ts +12 -12
  358. package/src/presentation/routes/mint-registration-tokens.ts +5 -7
  359. package/src/presentation/routes/planned-capacity.ts +49 -0
  360. package/src/presentation/routes/poll-demand-release.test.ts +4 -4
  361. package/src/presentation/routes/poll-demand.test.ts +161 -22
  362. package/src/presentation/routes/poll-demand.ts +105 -45
  363. package/src/presentation/routes/provisioner-me.test.ts +37 -3
  364. package/src/presentation/routes/{reconcile-provisioned-runners.test.ts → reconcile-runner-instances.test.ts} +66 -61
  365. package/src/presentation/routes/reconcile-runner-instances.ts +30 -0
  366. package/src/presentation/routes/register.test.ts +9 -5
  367. package/src/presentation/routes/register.ts +61 -57
  368. package/src/presentation/routes/{report-provisioned-runners.test.ts → report-runner-instances.test.ts} +28 -28
  369. package/src/presentation/routes/{report-provisioned-runners.ts → report-runner-instances.ts} +14 -14
  370. package/src/presentation/routes/request-job.test.ts +5 -3
  371. package/src/presentation/routes/request-job.ts +41 -37
  372. package/src/presentation/routes/runner-enrollment.test.ts +259 -0
  373. package/src/presentation/routes/runner-enrollment.ts +174 -0
  374. package/src/temporal/activities/index.ts +2 -2
  375. package/src/temporal/activities/maintenance-activities.test.ts +7 -7
  376. package/src/temporal/activities/maintenance-activities.ts +3 -3
  377. package/src/temporal/workflows/stuck-job-detector.test.ts +3 -3
  378. package/src/temporal/workflows/stuck-job-detector.ts +2 -2
  379. package/test/env.ts +1 -3
  380. package/test/factories/ephemeral-registration-token.ts +2 -2
  381. package/test/factories/provisioner-token.ts +3 -1
  382. package/test/factories/runner-instance.ts +57 -0
  383. package/test/factories/runner-session.ts +3 -1
  384. package/test/fixtures/auth-inter-module.ts +30 -0
  385. package/test/globalSetup.ts +5 -1
  386. package/test/index.ts +2 -1
  387. package/tsconfig.build.tsbuildinfo +1 -1
  388. package/dist/core/entities/provisioned-runner.d.ts.map +0 -1
  389. package/dist/core/entities/provisioned-runner.js +0 -3
  390. package/dist/core/entities/provisioned-runner.js.map +0 -1
  391. package/dist/core/provisioned-runners.d.ts +0 -67
  392. package/dist/core/provisioned-runners.d.ts.map +0 -1
  393. package/dist/core/provisioned-runners.js +0 -162
  394. package/dist/core/provisioned-runners.js.map +0 -1
  395. package/dist/db/provisioned-runners.d.ts +0 -79
  396. package/dist/db/provisioned-runners.d.ts.map +0 -1
  397. package/dist/db/provisioned-runners.js +0 -466
  398. package/dist/db/provisioned-runners.js.map +0 -1
  399. package/dist/db/schema/provisioned-runners.d.ts.map +0 -1
  400. package/dist/db/schema/provisioned-runners.js.map +0 -1
  401. package/dist/presentation/dto/provisioned-runners.d.ts.map +0 -1
  402. package/dist/presentation/dto/provisioned-runners.js.map +0 -1
  403. package/dist/presentation/routes/reconcile-provisioned-runners.d.ts +0 -2
  404. package/dist/presentation/routes/reconcile-provisioned-runners.d.ts.map +0 -1
  405. package/dist/presentation/routes/reconcile-provisioned-runners.js +0 -27
  406. package/dist/presentation/routes/reconcile-provisioned-runners.js.map +0 -1
  407. package/dist/presentation/routes/report-provisioned-runners.d.ts +0 -2
  408. package/dist/presentation/routes/report-provisioned-runners.d.ts.map +0 -1
  409. package/dist/presentation/routes/report-provisioned-runners.js +0 -37
  410. package/dist/presentation/routes/report-provisioned-runners.js.map +0 -1
  411. package/src/core/provisioned-runners.ts +0 -301
  412. package/src/db/provisioned-runners.ts +0 -886
  413. package/src/presentation/routes/reconcile-provisioned-runners.ts +0 -30
  414. package/test/factories/provisioned-runner.ts +0 -78
@@ -0,0 +1,159 @@
1
+ import {eq, inArray} from 'drizzle-orm';
2
+ import {assignCapacityBatch} from '#db/capacity-assignments.js';
3
+ import {db} from '#db/db.js';
4
+ import {capacityAssignments} from '#db/schema/capacity-assignments.js';
5
+ import {reservations} from '#db/schema/reservations.js';
6
+ import {providerRunners} from '#db/schema/runner-instances.js';
7
+
8
+ describe('assignCapacityBatch', () => {
9
+ let workspaceId: string;
10
+ let provisionerId: string;
11
+
12
+ beforeEach(() => {
13
+ workspaceId = crypto.randomUUID();
14
+ provisionerId = crypto.randomUUID();
15
+ });
16
+
17
+ it('assigns compatible live capacity once and returns the same assignment on retry', async () => {
18
+ const reservation = await createReservation();
19
+ const capacity = await createCapacity();
20
+
21
+ const first = await assignCapacityBatch({
22
+ provisionerId,
23
+ reservationId: reservation.id,
24
+ capacityIds: [capacity.id],
25
+ });
26
+ const retry = await assignCapacityBatch({
27
+ provisionerId,
28
+ reservationId: reservation.id,
29
+ capacityIds: [capacity.id],
30
+ });
31
+
32
+ expect(first).toHaveLength(1);
33
+ expect(retry).toEqual(first);
34
+ expect(first[0]).toMatchObject({
35
+ capacityId: capacity.id,
36
+ reservationId: reservation.id,
37
+ workspaceId,
38
+ provisionerId,
39
+ });
40
+ });
41
+
42
+ it('does not rebind capacity or a reservation under concurrent assignment requests', async () => {
43
+ const reservation = await createReservation();
44
+ const firstCapacity = await createCapacity();
45
+ const secondCapacity = await createCapacity();
46
+
47
+ const result = await Promise.allSettled([
48
+ assignCapacityBatch({
49
+ provisionerId,
50
+ reservationId: reservation.id,
51
+ capacityIds: [firstCapacity.id],
52
+ }),
53
+ assignCapacityBatch({
54
+ provisionerId,
55
+ reservationId: reservation.id,
56
+ capacityIds: [secondCapacity.id],
57
+ }),
58
+ ]);
59
+
60
+ expect(result.filter((entry) => entry.status === 'fulfilled')).toHaveLength(1);
61
+ const rows = await db()
62
+ .select()
63
+ .from(capacityAssignments)
64
+ .where(eq(capacityAssignments.reservationId, reservation.id));
65
+ expect(rows).toHaveLength(1);
66
+ });
67
+
68
+ it('consumes each slot in a multi-capacity reservation without rebinding capacity', async () => {
69
+ const reservation = await createReservation({count: 2});
70
+ const firstCapacity = await createCapacity();
71
+ const secondCapacity = await createCapacity();
72
+
73
+ const assignments = await assignCapacityBatch({
74
+ provisionerId,
75
+ reservationId: reservation.id,
76
+ capacityIds: [firstCapacity.id, secondCapacity.id],
77
+ });
78
+ const retry = await assignCapacityBatch({
79
+ provisionerId,
80
+ reservationId: reservation.id,
81
+ capacityIds: [firstCapacity.id, secondCapacity.id],
82
+ });
83
+
84
+ expect(assignments).toHaveLength(2);
85
+ expect(retry).toEqual(assignments);
86
+ });
87
+
88
+ it('rejects expired, incompatible, and foreign capacity without consuming it', async () => {
89
+ const expiredReservation = await createReservation({expiresAt: new Date(Date.now() - 1_000)});
90
+ const compatibleCapacity = await createCapacity();
91
+ const incompatibleReservation = await createReservation({requiredLabels: ['gpu']});
92
+ const foreignCapacity = await createCapacity({provisionerId: crypto.randomUUID()});
93
+
94
+ await expect(
95
+ assignCapacityBatch({
96
+ provisionerId,
97
+ reservationId: expiredReservation.id,
98
+ capacityIds: [compatibleCapacity.id],
99
+ }),
100
+ ).rejects.toMatchObject({name: 'ReservationExpiredError'});
101
+ await expect(
102
+ assignCapacityBatch({
103
+ provisionerId,
104
+ reservationId: incompatibleReservation.id,
105
+ capacityIds: [compatibleCapacity.id],
106
+ }),
107
+ ).rejects.toMatchObject({name: 'CapacityNotAssignableError'});
108
+ await expect(
109
+ assignCapacityBatch({
110
+ provisionerId,
111
+ reservationId: incompatibleReservation.id,
112
+ capacityIds: [foreignCapacity.id],
113
+ }),
114
+ ).rejects.toMatchObject({name: 'CapacityNotAssignableError'});
115
+
116
+ const rows = await db()
117
+ .select()
118
+ .from(capacityAssignments)
119
+ .where(
120
+ inArray(capacityAssignments.reservationId, [
121
+ expiredReservation.id,
122
+ incompatibleReservation.id,
123
+ ]),
124
+ );
125
+ expect(rows).toEqual([]);
126
+ });
127
+
128
+ async function createReservation(overrides: Partial<typeof reservations.$inferInsert> = {}) {
129
+ const [row] = await db()
130
+ .insert(reservations)
131
+ .values({
132
+ workspaceId,
133
+ provisionerId,
134
+ requiredLabels: ['linux'],
135
+ count: 1,
136
+ expiresAt: new Date(Date.now() + 60_000),
137
+ ...overrides,
138
+ })
139
+ .returning();
140
+ if (!row) throw new Error('Reservation insert returned no row');
141
+ return row;
142
+ }
143
+
144
+ async function createCapacity(overrides: Partial<typeof providerRunners.$inferInsert> = {}) {
145
+ const [row] = await db()
146
+ .insert(providerRunners)
147
+ .values({
148
+ provisionerId,
149
+ providerRunnerId: crypto.randomUUID(),
150
+ labels: ['linux'],
151
+ state: 'running',
152
+ reportedAt: new Date(),
153
+ ...overrides,
154
+ })
155
+ .returning();
156
+ if (!row) throw new Error('Capacity insert returned no row');
157
+ return row;
158
+ }
159
+ });
@@ -0,0 +1,116 @@
1
+ import {and, eq, inArray, sql} from 'drizzle-orm';
2
+ import type {CapacityAssignment} from '#core/entities/capacity-assignment.js';
3
+ import {
4
+ CapacityAlreadyAssignedError,
5
+ CapacityNotAssignableError,
6
+ ReservationExpiredError,
7
+ ReservationNotFoundError,
8
+ } from '#core/errors.js';
9
+ import {db} from './db.js';
10
+ import {capacityAssignments, toCapacityAssignment} from './schema/capacity-assignments.js';
11
+ import {reservations} from './schema/reservations.js';
12
+ import {providerRunners} from './schema/runner-instances.js';
13
+
14
+ export async function assignCapacityBatch(params: {
15
+ provisionerId: string;
16
+ reservationId: string;
17
+ capacityIds: string[];
18
+ }): Promise<CapacityAssignment[]> {
19
+ return await db().transaction(async (tx) => {
20
+ const lockKey = [
21
+ 'runners_capacity_assignments',
22
+ params.provisionerId,
23
+ params.reservationId,
24
+ ].join(':');
25
+ await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${lockKey}))`);
26
+ for (const capacityId of [...params.capacityIds].sort()) {
27
+ await tx.execute(
28
+ sql`select pg_advisory_xact_lock(hashtext(${['runners_capacity_assignments', capacityId].join(':')}))`,
29
+ );
30
+ }
31
+
32
+ const [reservation] = await tx
33
+ .select()
34
+ .from(reservations)
35
+ .where(
36
+ and(
37
+ eq(reservations.id, params.reservationId),
38
+ eq(reservations.provisionerId, params.provisionerId),
39
+ ),
40
+ )
41
+ .limit(1);
42
+ if (!reservation) throw new ReservationNotFoundError(params.reservationId);
43
+ if (reservation.expiresAt <= new Date())
44
+ throw new ReservationExpiredError(params.reservationId);
45
+
46
+ const existing = await tx
47
+ .select()
48
+ .from(capacityAssignments)
49
+ .where(eq(capacityAssignments.reservationId, reservation.id));
50
+ const existingByCapacityId = new Map(
51
+ existing.map((assignment) => [assignment.capacityId, assignment]),
52
+ );
53
+ const newCapacityIds = params.capacityIds.filter(
54
+ (capacityId) => !existingByCapacityId.has(capacityId),
55
+ );
56
+ if (existing.length + newCapacityIds.length > reservation.count)
57
+ throw new CapacityNotAssignableError(params.capacityIds[0] ?? '');
58
+
59
+ if (newCapacityIds.length === 0) {
60
+ return params.capacityIds.flatMap((capacityId) => {
61
+ const assignment = existingByCapacityId.get(capacityId);
62
+ return assignment ? [toCapacityAssignment(assignment)] : [];
63
+ });
64
+ }
65
+
66
+ const capacities = await tx
67
+ .select()
68
+ .from(providerRunners)
69
+ .where(
70
+ and(
71
+ eq(providerRunners.provisionerId, params.provisionerId),
72
+ inArray(providerRunners.id, newCapacityIds),
73
+ ),
74
+ );
75
+ if (capacities.length !== newCapacityIds.length)
76
+ throw new CapacityNotAssignableError(params.capacityIds[0] ?? '');
77
+ for (const capacity of capacities) {
78
+ if (capacity.state !== 'starting' && capacity.state !== 'running')
79
+ throw new CapacityNotAssignableError(capacity.id);
80
+ if (
81
+ !capacity.providerRunnerId ||
82
+ capacity.labels.length === 0 ||
83
+ !reservation.requiredLabels.every((label) => capacity.labels.includes(label))
84
+ ) {
85
+ throw new CapacityNotAssignableError(capacity.id);
86
+ }
87
+ }
88
+
89
+ const assignedCapacity = await tx
90
+ .select({capacityId: capacityAssignments.capacityId})
91
+ .from(capacityAssignments)
92
+ .where(inArray(capacityAssignments.capacityId, newCapacityIds));
93
+ if (assignedCapacity.length > 0)
94
+ throw new CapacityAlreadyAssignedError(assignedCapacity[0]?.capacityId ?? '');
95
+
96
+ const inserted = await tx
97
+ .insert(capacityAssignments)
98
+ .values(
99
+ newCapacityIds.map((capacityId) => ({
100
+ capacityId,
101
+ reservationId: reservation.id,
102
+ workspaceId: reservation.workspaceId,
103
+ provisionerId: params.provisionerId,
104
+ })),
105
+ )
106
+ .returning();
107
+ const insertedByCapacityId = new Map(
108
+ inserted.map((assignment) => [assignment.capacityId, assignment]),
109
+ );
110
+ return params.capacityIds.flatMap((capacityId) => {
111
+ const assignment =
112
+ existingByCapacityId.get(capacityId) ?? insertedByCapacityId.get(capacityId);
113
+ return assignment ? [toCapacityAssignment(assignment)] : [];
114
+ });
115
+ });
116
+ }
package/src/db/db.ts CHANGED
@@ -1,24 +1,33 @@
1
1
  import {drizzle, type NodePgDatabase} from '@shipfox/node-drizzle';
2
2
  import {pgClient} from '@shipfox/node-postgres';
3
+ import {capacityAssignments} from './schema/capacity-assignments.js';
3
4
  import {ephemeralRegistrationTokens} from './schema/ephemeral-registration-tokens.js';
4
5
  import {manualRegistrationTokens} from './schema/manual-registration-tokens.js';
5
6
  import {runnersOutbox} from './schema/outbox.js';
6
7
  import {pendingJobExecutions} from './schema/pending-job-executions.js';
7
- import {provisionedRunners} from './schema/provisioned-runners.js';
8
+ import {provisionerCapabilitySnapshots} from './schema/provisioner-capability-snapshots.js';
8
9
  import {provisionerTokens} from './schema/provisioner-tokens.js';
9
10
  import {runnersRateLimits} from './schema/rate-limits.js';
10
11
  import {reservations} from './schema/reservations.js';
12
+ import {runnerActivationTokens} from './schema/runner-activation-tokens.js';
13
+ import {runnerBootstrapTokens, runnerControlSessions} from './schema/runner-control-sessions.js';
14
+ import {providerRunners} from './schema/runner-instances.js';
11
15
  import {runnerSessions} from './schema/runner-sessions.js';
12
16
  import {runningJobExecutions} from './schema/running-job-executions.js';
13
17
 
14
18
  export const schema = {
19
+ capacityAssignments,
15
20
  ephemeralRegistrationTokens,
16
21
  pendingJobExecutions,
17
- provisionedRunners,
22
+ providerRunners,
23
+ provisionerCapabilitySnapshots,
18
24
  provisionerTokens,
19
25
  runnersRateLimits,
20
26
  reservations,
21
27
  runnerSessions,
28
+ runnerBootstrapTokens,
29
+ runnerControlSessions,
30
+ runnerActivationTokens,
22
31
  manualRegistrationTokens,
23
32
  runningJobExecutions,
24
33
  runnersOutbox,
@@ -44,7 +44,7 @@ describe('createEphemeralRegistrationTokensBatch', () => {
44
44
  });
45
45
 
46
46
  expect(result).toHaveLength(2);
47
- expect(result.map((token) => token.provisionedRunnerId).sort()).toEqual([
47
+ expect(result.map((token) => token.providerRunnerId).sort()).toEqual([
48
48
  'provisioned-runner-a',
49
49
  'provisioned-runner-b',
50
50
  ]);
@@ -53,14 +53,14 @@ describe('createEphemeralRegistrationTokensBatch', () => {
53
53
  expect(result.every((token) => token.provisionerId === provisionerId)).toBe(true);
54
54
  expect(
55
55
  await resolveEphemeralRegistrationTokenByHash(hashOpaqueToken(rawTokens[0] ?? '')),
56
- ).toEqual(expect.objectContaining({provisionedRunnerId: 'provisioned-runner-a'}));
56
+ ).toEqual(expect.objectContaining({providerRunnerId: 'provisioned-runner-a'}));
57
57
  });
58
58
 
59
59
  it('rejects the batch and inserts no rows when any provisioned runner already has an active token', async () => {
60
60
  await ephemeralRegistrationTokenFactory.create({
61
61
  workspaceId,
62
62
  provisionerId,
63
- provisionedRunnerId: 'provisioned-runner-a',
63
+ providerRunnerId: 'provisioned-runner-a',
64
64
  expiresAt: new Date(Date.now() + 60_000),
65
65
  });
66
66
  const rawToken = generateOpaqueToken('ephemeralRegistrationToken');
@@ -85,7 +85,7 @@ describe('createEphemeralRegistrationTokensBatch', () => {
85
85
  ),
86
86
  );
87
87
  expect(rows).toHaveLength(1);
88
- expect(rows[0]?.provisionedRunnerId).toBe('provisioned-runner-a');
88
+ expect(rows[0]?.providerRunnerId).toBe('provisioned-runner-a');
89
89
  });
90
90
 
91
91
  it('allows sequential batches that exactly reach the reservation count', async () => {
@@ -152,7 +152,7 @@ describe('createEphemeralRegistrationTokensBatch', () => {
152
152
  workspaceId,
153
153
  provisionerId,
154
154
  reservationId,
155
- provisionedRunnerId: 'provisioned-runner-consumed',
155
+ providerRunnerId: 'provisioned-runner-consumed',
156
156
  expiresAt: new Date(Date.now() + 60_000),
157
157
  });
158
158
  await db()
@@ -163,7 +163,7 @@ describe('createEphemeralRegistrationTokensBatch', () => {
163
163
  workspaceId,
164
164
  provisionerId,
165
165
  reservationId,
166
- provisionedRunnerId: 'provisioned-runner-expired',
166
+ providerRunnerId: 'provisioned-runner-expired',
167
167
  expiresAt: new Date(Date.now() - 60_000),
168
168
  });
169
169
 
@@ -209,9 +209,9 @@ describe('createEphemeralRegistrationTokensBatch', () => {
209
209
  return rows.length;
210
210
  }
211
211
 
212
- function row(provisionedRunnerId: string, rawToken: string) {
212
+ function row(providerRunnerId: string, rawToken: string) {
213
213
  return {
214
- provisionedRunnerId,
214
+ providerRunnerId,
215
215
  hashedToken: hashOpaqueToken(rawToken),
216
216
  prefix: extractDisplayPrefix(rawToken),
217
217
  };
@@ -303,7 +303,7 @@ describe('deleteExpiredEphemeralRegistrationTokens', () => {
303
303
  id,
304
304
  workspaceId,
305
305
  provisionerId,
306
- provisionedRunnerId: `provisioned-${id}`,
306
+ providerRunnerId: `provisioned-${id}`,
307
307
  hashedToken: crypto.randomUUID(),
308
308
  prefix: 'sfxr_test',
309
309
  expiresAt: params.expiresAt,
@@ -16,22 +16,22 @@ import {
16
16
  ephemeralRegistrationTokens,
17
17
  toEphemeralRegistrationToken,
18
18
  } from './schema/ephemeral-registration-tokens.js';
19
- import {provisionedRunners} from './schema/provisioned-runners.js';
20
19
  import {reservations} from './schema/reservations.js';
20
+ import {providerRunners} from './schema/runner-instances.js';
21
21
  import {runnerSessions, toRunnerSession} from './schema/runner-sessions.js';
22
22
 
23
23
  export interface CreateEphemeralRegistrationTokenParams {
24
24
  workspaceId: string;
25
25
  provisionerId: string;
26
26
  reservationId?: string | null | undefined;
27
- provisionedRunnerId: string;
27
+ providerRunnerId: string;
28
28
  hashedToken: string;
29
29
  prefix: string;
30
30
  expiresAt: Date;
31
31
  }
32
32
 
33
33
  export interface CreateEphemeralRegistrationTokensBatchRow {
34
- provisionedRunnerId: string;
34
+ providerRunnerId: string;
35
35
  hashedToken: string;
36
36
  prefix: string;
37
37
  }
@@ -48,13 +48,13 @@ export async function createEphemeralRegistrationToken(
48
48
  params: CreateEphemeralRegistrationTokenParams,
49
49
  ): Promise<EphemeralRegistrationToken> {
50
50
  const rows = await db().transaction(async (tx) => {
51
- const provisionedRunnerLockKey = [
51
+ const providerRunnerLockKey = [
52
52
  'runners_ephemeral_registration_tokens',
53
53
  params.workspaceId,
54
54
  params.provisionerId,
55
- params.provisionedRunnerId,
55
+ params.providerRunnerId,
56
56
  ].join(':');
57
- await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${provisionedRunnerLockKey}))`);
57
+ await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${providerRunnerLockKey}))`);
58
58
 
59
59
  const [active] = await tx
60
60
  .select({id: ephemeralRegistrationTokens.id})
@@ -63,7 +63,7 @@ export async function createEphemeralRegistrationToken(
63
63
  and(
64
64
  eq(ephemeralRegistrationTokens.workspaceId, params.workspaceId),
65
65
  eq(ephemeralRegistrationTokens.provisionerId, params.provisionerId),
66
- eq(ephemeralRegistrationTokens.provisionedRunnerId, params.provisionedRunnerId),
66
+ eq(ephemeralRegistrationTokens.providerRunnerId, params.providerRunnerId),
67
67
  isNull(ephemeralRegistrationTokens.consumedAt),
68
68
  gt(ephemeralRegistrationTokens.expiresAt, sql`now()`),
69
69
  ),
@@ -74,7 +74,7 @@ export async function createEphemeralRegistrationToken(
74
74
  throw new ActiveEphemeralRegistrationTokenExistsError(
75
75
  params.workspaceId,
76
76
  params.provisionerId,
77
- params.provisionedRunnerId,
77
+ params.providerRunnerId,
78
78
  );
79
79
  }
80
80
 
@@ -84,7 +84,7 @@ export async function createEphemeralRegistrationToken(
84
84
  workspaceId: params.workspaceId,
85
85
  provisionerId: params.provisionerId,
86
86
  reservationId: params.reservationId ?? null,
87
- provisionedRunnerId: params.provisionedRunnerId,
87
+ providerRunnerId: params.providerRunnerId,
88
88
  hashedToken: params.hashedToken,
89
89
  prefix: params.prefix,
90
90
  expiresAt: params.expiresAt,
@@ -107,16 +107,16 @@ export async function createEphemeralRegistrationTokensBatch(
107
107
  params.provisionerId,
108
108
  ].join(':');
109
109
  await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${provisionerLockKey}))`);
110
- for (const provisionedRunnerId of [
111
- ...new Set(params.rows.map((row) => row.provisionedRunnerId)),
110
+ for (const providerRunnerId of [
111
+ ...new Set(params.rows.map((row) => row.providerRunnerId)),
112
112
  ].sort()) {
113
- const provisionedRunnerLockKey = [
113
+ const providerRunnerLockKey = [
114
114
  'runners_ephemeral_registration_tokens',
115
115
  params.workspaceId,
116
116
  params.provisionerId,
117
- provisionedRunnerId,
117
+ providerRunnerId,
118
118
  ].join(':');
119
- await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${provisionedRunnerLockKey}))`);
119
+ await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${providerRunnerLockKey}))`);
120
120
  }
121
121
 
122
122
  const [reservation] = await tx
@@ -162,15 +162,15 @@ export async function createEphemeralRegistrationTokensBatch(
162
162
  );
163
163
  }
164
164
 
165
- const provisionedRunnerIds = params.rows.map((row) => row.provisionedRunnerId);
165
+ const providerRunnerIds = params.rows.map((row) => row.providerRunnerId);
166
166
  const activeRows = await tx
167
- .select({provisionedRunnerId: ephemeralRegistrationTokens.provisionedRunnerId})
167
+ .select({providerRunnerId: ephemeralRegistrationTokens.providerRunnerId})
168
168
  .from(ephemeralRegistrationTokens)
169
169
  .where(
170
170
  and(
171
171
  eq(ephemeralRegistrationTokens.workspaceId, params.workspaceId),
172
172
  eq(ephemeralRegistrationTokens.provisionerId, params.provisionerId),
173
- inArray(ephemeralRegistrationTokens.provisionedRunnerId, provisionedRunnerIds),
173
+ inArray(ephemeralRegistrationTokens.providerRunnerId, providerRunnerIds),
174
174
  isNull(ephemeralRegistrationTokens.consumedAt),
175
175
  gt(ephemeralRegistrationTokens.expiresAt, sql`now()`),
176
176
  ),
@@ -178,7 +178,7 @@ export async function createEphemeralRegistrationTokensBatch(
178
178
 
179
179
  if (activeRows.length > 0) {
180
180
  throw new ActiveEphemeralRegistrationTokensExistError(
181
- activeRows.map((row) => row.provisionedRunnerId),
181
+ activeRows.map((row) => row.providerRunnerId),
182
182
  );
183
183
  }
184
184
 
@@ -189,7 +189,7 @@ export async function createEphemeralRegistrationTokensBatch(
189
189
  workspaceId: params.workspaceId,
190
190
  provisionerId: params.provisionerId,
191
191
  reservationId: params.reservationId,
192
- provisionedRunnerId: row.provisionedRunnerId,
192
+ providerRunnerId: row.providerRunnerId,
193
193
  hashedToken: row.hashedToken,
194
194
  prefix: row.prefix,
195
195
  expiresAt: params.expiresAt,
@@ -277,7 +277,7 @@ export async function createRunnerSessionConsumingEphemeralToken(params: {
277
277
  .returning({
278
278
  id: ephemeralRegistrationTokens.id,
279
279
  provisionerId: ephemeralRegistrationTokens.provisionerId,
280
- provisionedRunnerId: ephemeralRegistrationTokens.provisionedRunnerId,
280
+ providerRunnerId: ephemeralRegistrationTokens.providerRunnerId,
281
281
  });
282
282
 
283
283
  if (!consumed[0]) {
@@ -315,7 +315,7 @@ export async function createRunnerSessionConsumingEphemeralToken(params: {
315
315
  registrationTokenId: params.ephemeralTokenId,
316
316
  registrationTokenKind: 'ephemeral',
317
317
  provisionerId: consumed[0].provisionerId,
318
- provisionedRunnerId: consumed[0].provisionedRunnerId,
318
+ providerRunnerId: consumed[0].providerRunnerId,
319
319
  labels: params.labels,
320
320
  toolCapabilities: params.toolCapabilities ?? null,
321
321
  toolCapabilitiesReportedAt: params.toolCapabilities ? sql`now()` : null,
@@ -332,14 +332,14 @@ export async function createRunnerSessionConsumingEphemeralToken(params: {
332
332
  .where(eq(ephemeralRegistrationTokens.id, params.ephemeralTokenId));
333
333
 
334
334
  await tx
335
- .update(provisionedRunners)
335
+ .update(providerRunners)
336
336
  .set({runnerSessionId: session.id, updatedAt: sql`now()`})
337
337
  .where(
338
338
  and(
339
- eq(provisionedRunners.workspaceId, params.workspaceId),
340
- eq(provisionedRunners.provisionerId, consumed[0].provisionerId),
341
- eq(provisionedRunners.provisionedRunnerId, consumed[0].provisionedRunnerId),
342
- isNull(provisionedRunners.reservationReleasedAt),
339
+ eq(providerRunners.workspaceId, params.workspaceId),
340
+ eq(providerRunners.provisionerId, consumed[0].provisionerId),
341
+ eq(providerRunners.providerRunnerId, consumed[0].providerRunnerId),
342
+ isNull(providerRunners.reservationReleasedAt),
343
343
  ),
344
344
  );
345
345
 
package/src/db/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import {dirname, resolve} from 'node:path';
2
2
  import {fileURLToPath} from 'node:url';
3
3
 
4
+ export {assignCapacityBatch} from './capacity-assignments.js';
4
5
  export {closeDb, db, schema} from './db.js';
5
6
  export type {
6
7
  CreateEphemeralRegistrationTokenParams,
@@ -15,7 +16,7 @@ export {
15
16
  export type {
16
17
  ClaimedJobExecution,
17
18
  EnqueueJobExecutionParams,
18
- ProvisionedRunnerBoundJobExecution,
19
+ RunnerInstanceBoundJobExecution,
19
20
  } from './job-executions.js';
20
21
  export {
21
22
  cancelRunnerJobs,
@@ -24,7 +25,7 @@ export {
24
25
  expireStuckJobExecutions,
25
26
  isJobLeaseActive,
26
27
  listActiveRunningJobExecutions,
27
- listRunningJobExecutionsByProvisionedRunnerTx,
28
+ listRunningJobExecutionsByRunnerInstanceTx,
28
29
  recordHeartbeat,
29
30
  releaseJobExecution,
30
31
  } from './job-executions.js';
@@ -35,26 +36,12 @@ export {
35
36
  resolveManualRegistrationTokenByHash,
36
37
  revokeManualRegistrationToken,
37
38
  } from './manual-registration-tokens.js';
38
- export type {
39
- ActiveProvisionedRunnerTemplateCount,
40
- ProvisionedRunnerReportEvent,
41
- ProvisionedRunnerTerminateIntent,
42
- ProvisionedRunnerTerminateIntentReason,
43
- ReapStaleProvisionedRunnersResult,
44
- ReconcileProvisionedRunnersDbResult,
45
- ReconcileProvisionedRunnersParams,
46
- ReportProvisionedRunnersParams,
47
- } from './provisioned-runners.js';
48
39
  export {
49
- isTerminalState,
50
- listActiveProvisionedRunnerCountsByTemplateTx,
51
- listActiveProvisionedRunners,
52
- listProvisionerTerminateIntentRowsTx,
53
- listProvisionerTerminateIntents,
54
- reapStaleProvisionedRunners,
55
- reconcileProvisionedRunners,
56
- reportProvisionedRunners,
57
- } from './provisioned-runners.js';
40
+ hasActiveWorkspaceProvisionerCapability,
41
+ listActiveWorkspaceProvisionerCapabilitySnapshots,
42
+ listStaleWorkspaceProvisionerCapabilitySnapshots,
43
+ publishWorkspaceProvisionerCapabilitySnapshot,
44
+ } from './provisioner-capability-snapshots.js';
58
45
  export type {CreateProvisionerTokenParams} from './provisioner-tokens.js';
59
46
  export {
60
47
  createProvisionerToken,
@@ -80,11 +67,34 @@ export {
80
67
  pollDemandAndReserve,
81
68
  releaseReservationUnits,
82
69
  } from './reservations.js';
70
+ export type {
71
+ ActiveRunnerInstanceTemplateCount,
72
+ ReapStaleRunnerInstancesResult,
73
+ ReconcileRunnerInstancesDbResult,
74
+ ReconcileRunnerInstancesParams,
75
+ ReportRunnerInstancesParams,
76
+ RunnerInstanceReportEvent,
77
+ RunnerInstanceTerminateIntent,
78
+ RunnerInstanceTerminateIntentReason,
79
+ } from './runner-instances.js';
80
+ export {
81
+ attachProviderRunnerId,
82
+ createPlannedProvisionedCapacity,
83
+ isTerminalState,
84
+ listActiveRunnerInstanceCountsByTemplateTx,
85
+ listActiveRunnerInstances,
86
+ listProvisionerTerminateIntentRowsTx,
87
+ listProvisionerTerminateIntents,
88
+ reapStaleRunnerInstances,
89
+ reconcileRunnerInstances,
90
+ reportRunnerInstances,
91
+ } from './runner-instances.js';
83
92
  export type {
84
93
  CreateRunnerSessionParams,
85
94
  DeleteExpiredRunnerSessionsParams,
86
95
  } from './runner-sessions.js';
87
96
  export {createRunnerSession, deleteExpiredRunnerSessions} from './runner-sessions.js';
88
97
  export {runnersOutbox} from './schema/outbox.js';
98
+ export {runnerBootstrapTokens, runnerControlSessions} from './schema/runner-control-sessions.js';
89
99
 
90
100
  export const migrationsPath = resolve(dirname(fileURLToPath(import.meta.url)), '../../drizzle');