@vibesdotdev/infra-deploy 0.0.1 → 1.0.0-rc.4

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 (662) hide show
  1. package/LICENSE +18 -0
  2. package/README.md +79 -118
  3. package/dist/cli/alerts/infra-alerts-create.cli-command.descriptor.d.ts +48 -35
  4. package/dist/cli/alerts/infra-alerts-create.cli-command.descriptor.d.ts.map +1 -1
  5. package/dist/cli/alerts/infra-alerts-create.cli-command.descriptor.js +1 -1
  6. package/dist/cli/alerts/infra-alerts-create.cli-command.descriptor.js.map +1 -1
  7. package/dist/cli/alerts/infra-alerts-create.cli-command.impl.d.ts +2 -1
  8. package/dist/cli/alerts/infra-alerts-create.cli-command.impl.d.ts.map +1 -1
  9. package/dist/cli/alerts/infra-alerts-create.cli-command.impl.js +31 -21
  10. package/dist/cli/alerts/infra-alerts-create.cli-command.impl.js.map +1 -1
  11. package/dist/cli/alerts/infra-alerts-delete.cli-command.descriptor.d.ts +26 -27
  12. package/dist/cli/alerts/infra-alerts-delete.cli-command.descriptor.d.ts.map +1 -1
  13. package/dist/cli/alerts/infra-alerts-delete.cli-command.descriptor.js +1 -1
  14. package/dist/cli/alerts/infra-alerts-delete.cli-command.descriptor.js.map +1 -1
  15. package/dist/cli/alerts/infra-alerts-delete.cli-command.impl.d.ts +2 -1
  16. package/dist/cli/alerts/infra-alerts-delete.cli-command.impl.d.ts.map +1 -1
  17. package/dist/cli/alerts/infra-alerts-delete.cli-command.impl.js +11 -11
  18. package/dist/cli/alerts/infra-alerts-delete.cli-command.impl.js.map +1 -1
  19. package/dist/cli/alerts/infra-alerts-list.cli-command.descriptor.d.ts +19 -17
  20. package/dist/cli/alerts/infra-alerts-list.cli-command.descriptor.d.ts.map +1 -1
  21. package/dist/cli/alerts/infra-alerts-list.cli-command.descriptor.js +1 -1
  22. package/dist/cli/alerts/infra-alerts-list.cli-command.descriptor.js.map +1 -1
  23. package/dist/cli/alerts/infra-alerts-list.cli-command.impl.d.ts +2 -1
  24. package/dist/cli/alerts/infra-alerts-list.cli-command.impl.d.ts.map +1 -1
  25. package/dist/cli/alerts/infra-alerts-list.cli-command.impl.js +15 -14
  26. package/dist/cli/alerts/infra-alerts-list.cli-command.impl.js.map +1 -1
  27. package/dist/cli/alerts/infra-alerts.cli-group.descriptor.d.ts +8 -8
  28. package/dist/cli/alerts/infra-alerts.cli-group.descriptor.js +1 -1
  29. package/dist/cli/alerts/infra-alerts.cli-group.descriptor.js.map +1 -1
  30. package/dist/cli/audit/infra-audit.cli-command.descriptor.d.ts +24 -17
  31. package/dist/cli/audit/infra-audit.cli-command.descriptor.d.ts.map +1 -1
  32. package/dist/cli/audit/infra-audit.cli-command.descriptor.js +8 -3
  33. package/dist/cli/audit/infra-audit.cli-command.descriptor.js.map +1 -1
  34. package/dist/cli/audit/infra-audit.cli-command.impl.d.ts +164 -1
  35. package/dist/cli/audit/infra-audit.cli-command.impl.d.ts.map +1 -1
  36. package/dist/cli/audit/infra-audit.cli-command.impl.js +557 -76
  37. package/dist/cli/audit/infra-audit.cli-command.impl.js.map +1 -1
  38. package/dist/cli/db/infra-db.cli-command.descriptor.d.ts +49 -0
  39. package/dist/cli/db/infra-db.cli-command.descriptor.d.ts.map +1 -0
  40. package/dist/cli/db/infra-db.cli-command.descriptor.js +60 -0
  41. package/dist/cli/db/infra-db.cli-command.descriptor.js.map +1 -0
  42. package/dist/cli/db/infra-db.cli-command.impl.d.ts +30 -0
  43. package/dist/cli/db/infra-db.cli-command.impl.d.ts.map +1 -0
  44. package/dist/cli/db/infra-db.cli-command.impl.js +167 -0
  45. package/dist/cli/db/infra-db.cli-command.impl.js.map +1 -0
  46. package/dist/cli/dns/infra-dns-activate.cli-command.impl.d.ts +6 -0
  47. package/dist/cli/dns/infra-dns-activate.cli-command.impl.d.ts.map +1 -0
  48. package/dist/cli/dns/infra-dns-activate.cli-command.impl.js +53 -0
  49. package/dist/cli/dns/infra-dns-activate.cli-command.impl.js.map +1 -0
  50. package/dist/cli/dns/infra-dns-delete.cli-command.descriptor.d.ts +41 -0
  51. package/dist/cli/dns/infra-dns-delete.cli-command.descriptor.d.ts.map +1 -0
  52. package/dist/cli/dns/infra-dns-delete.cli-command.descriptor.js +50 -0
  53. package/dist/cli/dns/infra-dns-delete.cli-command.descriptor.js.map +1 -0
  54. package/dist/cli/dns/infra-dns-delete.cli-command.impl.d.ts +12 -0
  55. package/dist/cli/dns/infra-dns-delete.cli-command.impl.d.ts.map +1 -0
  56. package/dist/cli/dns/infra-dns-delete.cli-command.impl.js +70 -0
  57. package/dist/cli/dns/infra-dns-delete.cli-command.impl.js.map +1 -0
  58. package/dist/cli/dns/infra-dns-list.cli-command.descriptor.d.ts +32 -0
  59. package/dist/cli/dns/infra-dns-list.cli-command.descriptor.d.ts.map +1 -0
  60. package/dist/cli/dns/infra-dns-list.cli-command.descriptor.js +39 -0
  61. package/dist/cli/dns/infra-dns-list.cli-command.descriptor.js.map +1 -0
  62. package/dist/cli/dns/infra-dns-list.cli-command.impl.d.ts +17 -0
  63. package/dist/cli/dns/infra-dns-list.cli-command.impl.d.ts.map +1 -0
  64. package/dist/cli/dns/infra-dns-list.cli-command.impl.js +66 -0
  65. package/dist/cli/dns/infra-dns-list.cli-command.impl.js.map +1 -0
  66. package/dist/cli/dns/infra-dns-set.cli-command.descriptor.d.ts +58 -0
  67. package/dist/cli/dns/infra-dns-set.cli-command.descriptor.d.ts.map +1 -0
  68. package/dist/cli/dns/infra-dns-set.cli-command.descriptor.js +72 -0
  69. package/dist/cli/dns/infra-dns-set.cli-command.descriptor.js.map +1 -0
  70. package/dist/cli/dns/infra-dns-set.cli-command.impl.d.ts +14 -0
  71. package/dist/cli/dns/infra-dns-set.cli-command.impl.d.ts.map +1 -0
  72. package/dist/cli/dns/infra-dns-set.cli-command.impl.js +110 -0
  73. package/dist/cli/dns/infra-dns-set.cli-command.impl.js.map +1 -0
  74. package/dist/cli/dns/infra-dns.cli-group.descriptor.d.ts +41 -0
  75. package/dist/cli/dns/infra-dns.cli-group.descriptor.d.ts.map +1 -0
  76. package/dist/cli/dns/infra-dns.cli-group.descriptor.js +47 -0
  77. package/dist/cli/dns/infra-dns.cli-group.descriptor.js.map +1 -0
  78. package/dist/cli/dns/resolve-dns-provider.d.ts +24 -0
  79. package/dist/cli/dns/resolve-dns-provider.d.ts.map +1 -0
  80. package/dist/cli/dns/resolve-dns-provider.js +62 -0
  81. package/dist/cli/dns/resolve-dns-provider.js.map +1 -0
  82. package/dist/cli/edge-tls/infra-edge-tls-delete.cli-command.descriptor.d.ts +37 -0
  83. package/dist/cli/edge-tls/infra-edge-tls-delete.cli-command.descriptor.d.ts.map +1 -0
  84. package/dist/cli/edge-tls/infra-edge-tls-delete.cli-command.descriptor.js +45 -0
  85. package/dist/cli/edge-tls/infra-edge-tls-delete.cli-command.descriptor.js.map +1 -0
  86. package/dist/cli/edge-tls/infra-edge-tls-delete.cli-command.impl.d.ts +15 -0
  87. package/dist/cli/edge-tls/infra-edge-tls-delete.cli-command.impl.d.ts.map +1 -0
  88. package/dist/cli/edge-tls/infra-edge-tls-delete.cli-command.impl.js +78 -0
  89. package/dist/cli/edge-tls/infra-edge-tls-delete.cli-command.impl.js.map +1 -0
  90. package/dist/cli/edge-tls/infra-edge-tls-list.cli-command.descriptor.d.ts +29 -0
  91. package/dist/cli/edge-tls/infra-edge-tls-list.cli-command.descriptor.d.ts.map +1 -0
  92. package/dist/cli/edge-tls/infra-edge-tls-list.cli-command.descriptor.js +35 -0
  93. package/dist/cli/edge-tls/infra-edge-tls-list.cli-command.descriptor.js.map +1 -0
  94. package/dist/cli/edge-tls/infra-edge-tls-list.cli-command.impl.d.ts +19 -0
  95. package/dist/cli/edge-tls/infra-edge-tls-list.cli-command.impl.d.ts.map +1 -0
  96. package/dist/cli/edge-tls/infra-edge-tls-list.cli-command.impl.js +73 -0
  97. package/dist/cli/edge-tls/infra-edge-tls-list.cli-command.impl.js.map +1 -0
  98. package/dist/cli/edge-tls/infra-edge-tls-set-zone-default.cli-command.descriptor.d.ts +41 -0
  99. package/dist/cli/edge-tls/infra-edge-tls-set-zone-default.cli-command.descriptor.d.ts.map +1 -0
  100. package/dist/cli/edge-tls/infra-edge-tls-set-zone-default.cli-command.descriptor.js +50 -0
  101. package/dist/cli/edge-tls/infra-edge-tls-set-zone-default.cli-command.descriptor.js.map +1 -0
  102. package/dist/cli/edge-tls/infra-edge-tls-set-zone-default.cli-command.impl.d.ts +16 -0
  103. package/dist/cli/edge-tls/infra-edge-tls-set-zone-default.cli-command.impl.d.ts.map +1 -0
  104. package/dist/cli/edge-tls/infra-edge-tls-set-zone-default.cli-command.impl.js +81 -0
  105. package/dist/cli/edge-tls/infra-edge-tls-set-zone-default.cli-command.impl.js.map +1 -0
  106. package/dist/cli/edge-tls/infra-edge-tls-set.cli-command.descriptor.d.ts +40 -0
  107. package/dist/cli/edge-tls/infra-edge-tls-set.cli-command.descriptor.d.ts.map +1 -0
  108. package/dist/cli/edge-tls/infra-edge-tls-set.cli-command.descriptor.js +49 -0
  109. package/dist/cli/edge-tls/infra-edge-tls-set.cli-command.descriptor.js.map +1 -0
  110. package/dist/cli/edge-tls/infra-edge-tls-set.cli-command.impl.d.ts +14 -0
  111. package/dist/cli/edge-tls/infra-edge-tls-set.cli-command.impl.d.ts.map +1 -0
  112. package/dist/cli/edge-tls/infra-edge-tls-set.cli-command.impl.js +78 -0
  113. package/dist/cli/edge-tls/infra-edge-tls-set.cli-command.impl.js.map +1 -0
  114. package/dist/cli/edge-tls/infra-edge-tls.cli-group.descriptor.d.ts +12 -0
  115. package/dist/cli/edge-tls/infra-edge-tls.cli-group.descriptor.d.ts.map +1 -0
  116. package/dist/cli/edge-tls/infra-edge-tls.cli-group.descriptor.js +12 -0
  117. package/dist/cli/edge-tls/infra-edge-tls.cli-group.descriptor.js.map +1 -0
  118. package/dist/cli/edge-tls/resolve-edge-tls-provider.d.ts +25 -0
  119. package/dist/cli/edge-tls/resolve-edge-tls-provider.d.ts.map +1 -0
  120. package/dist/cli/edge-tls/resolve-edge-tls-provider.js +74 -0
  121. package/dist/cli/edge-tls/resolve-edge-tls-provider.js.map +1 -0
  122. package/dist/cli/infra-deploy.cli-group.descriptor.d.ts +8 -8
  123. package/dist/cli/infra-deploy.cli-group.descriptor.js +1 -1
  124. package/dist/cli/infra-deploy.cli-group.descriptor.js.map +1 -1
  125. package/dist/cli/infra.cli-group.descriptor.d.ts +7 -7
  126. package/dist/cli/infra.cli-group.descriptor.js +1 -1
  127. package/dist/cli/infra.cli-group.descriptor.js.map +1 -1
  128. package/dist/cli/inventory/infra-inventory.cli-command.descriptor.d.ts +26 -0
  129. package/dist/cli/inventory/infra-inventory.cli-command.descriptor.d.ts.map +1 -0
  130. package/dist/cli/inventory/infra-inventory.cli-command.descriptor.js +18 -0
  131. package/dist/cli/inventory/infra-inventory.cli-command.descriptor.js.map +1 -0
  132. package/dist/cli/inventory/infra-inventory.cli-command.impl.d.ts +18 -0
  133. package/dist/cli/inventory/infra-inventory.cli-command.impl.d.ts.map +1 -0
  134. package/dist/cli/inventory/infra-inventory.cli-command.impl.js +204 -0
  135. package/dist/cli/inventory/infra-inventory.cli-command.impl.js.map +1 -0
  136. package/dist/cli/list/infra-deploy.list.cli-command.descriptor.d.ts +40 -30
  137. package/dist/cli/list/infra-deploy.list.cli-command.descriptor.d.ts.map +1 -1
  138. package/dist/cli/list/infra-deploy.list.cli-command.descriptor.js +7 -3
  139. package/dist/cli/list/infra-deploy.list.cli-command.descriptor.js.map +1 -1
  140. package/dist/cli/list/infra-deploy.list.cli-command.impl.d.ts +35 -1
  141. package/dist/cli/list/infra-deploy.list.cli-command.impl.d.ts.map +1 -1
  142. package/dist/cli/list/infra-deploy.list.cli-command.impl.js +202 -20
  143. package/dist/cli/list/infra-deploy.list.cli-command.impl.js.map +1 -1
  144. package/dist/cli/logs/infra-logs.cli-command.descriptor.d.ts +113 -35
  145. package/dist/cli/logs/infra-logs.cli-command.descriptor.d.ts.map +1 -1
  146. package/dist/cli/logs/infra-logs.cli-command.descriptor.js +87 -3
  147. package/dist/cli/logs/infra-logs.cli-command.descriptor.js.map +1 -1
  148. package/dist/cli/logs/infra-logs.cli-command.impl.d.ts +61 -1
  149. package/dist/cli/logs/infra-logs.cli-command.impl.d.ts.map +1 -1
  150. package/dist/cli/logs/infra-logs.cli-command.impl.js +1161 -108
  151. package/dist/cli/logs/infra-logs.cli-command.impl.js.map +1 -1
  152. package/dist/cli/logs/stream-worker-tail.d.ts +7 -2
  153. package/dist/cli/logs/stream-worker-tail.d.ts.map +1 -1
  154. package/dist/cli/logs/stream-worker-tail.js +280 -113
  155. package/dist/cli/logs/stream-worker-tail.js.map +1 -1
  156. package/dist/cli/migrate/infra-deploy.migrate.cli-command.descriptor.d.ts +62 -0
  157. package/dist/cli/migrate/infra-deploy.migrate.cli-command.descriptor.d.ts.map +1 -0
  158. package/dist/cli/migrate/infra-deploy.migrate.cli-command.descriptor.js +79 -0
  159. package/dist/cli/migrate/infra-deploy.migrate.cli-command.descriptor.js.map +1 -0
  160. package/dist/cli/migrate/infra-deploy.migrate.cli-command.impl.d.ts +8 -0
  161. package/dist/cli/migrate/infra-deploy.migrate.cli-command.impl.d.ts.map +1 -0
  162. package/dist/cli/migrate/infra-deploy.migrate.cli-command.impl.js +105 -0
  163. package/dist/cli/migrate/infra-deploy.migrate.cli-command.impl.js.map +1 -0
  164. package/dist/cli/npm/infra-npm-mirror.cli-command.descriptor.d.ts +34 -0
  165. package/dist/cli/npm/infra-npm-mirror.cli-command.descriptor.d.ts.map +1 -0
  166. package/dist/cli/npm/infra-npm-mirror.cli-command.descriptor.js +42 -0
  167. package/dist/cli/npm/infra-npm-mirror.cli-command.descriptor.js.map +1 -0
  168. package/dist/cli/npm/infra-npm-mirror.cli-command.impl.d.ts +13 -0
  169. package/dist/cli/npm/infra-npm-mirror.cli-command.impl.d.ts.map +1 -0
  170. package/dist/cli/npm/infra-npm-mirror.cli-command.impl.js +82 -0
  171. package/dist/cli/npm/infra-npm-mirror.cli-command.impl.js.map +1 -0
  172. package/dist/cli/npm/infra-npm-publish.cli-command.descriptor.d.ts +80 -23
  173. package/dist/cli/npm/infra-npm-publish.cli-command.descriptor.d.ts.map +1 -1
  174. package/dist/cli/npm/infra-npm-publish.cli-command.descriptor.js +48 -16
  175. package/dist/cli/npm/infra-npm-publish.cli-command.descriptor.js.map +1 -1
  176. package/dist/cli/npm/infra-npm-publish.cli-command.impl.d.ts +47 -1
  177. package/dist/cli/npm/infra-npm-publish.cli-command.impl.d.ts.map +1 -1
  178. package/dist/cli/npm/infra-npm-publish.cli-command.impl.js +532 -351
  179. package/dist/cli/npm/infra-npm-publish.cli-command.impl.js.map +1 -1
  180. package/dist/cli/npm/infra-npm-reconcile-latest.cli-command.descriptor.d.ts +28 -0
  181. package/dist/cli/npm/infra-npm-reconcile-latest.cli-command.descriptor.d.ts.map +1 -0
  182. package/dist/cli/npm/infra-npm-reconcile-latest.cli-command.descriptor.js +34 -0
  183. package/dist/cli/npm/infra-npm-reconcile-latest.cli-command.descriptor.js.map +1 -0
  184. package/dist/cli/npm/infra-npm-reconcile-latest.cli-command.impl.d.ts +12 -0
  185. package/dist/cli/npm/infra-npm-reconcile-latest.cli-command.impl.d.ts.map +1 -0
  186. package/dist/cli/npm/infra-npm-reconcile-latest.cli-command.impl.js +134 -0
  187. package/dist/cli/npm/infra-npm-reconcile-latest.cli-command.impl.js.map +1 -0
  188. package/dist/cli/npm/infra-npm.cli-group.descriptor.d.ts +8 -8
  189. package/dist/cli/npm/infra-npm.cli-group.descriptor.js +1 -1
  190. package/dist/cli/npm/infra-npm.cli-group.descriptor.js.map +1 -1
  191. package/dist/cli/npm/mirror-registry-artifacts.d.ts +64 -0
  192. package/dist/cli/npm/mirror-registry-artifacts.d.ts.map +1 -0
  193. package/dist/cli/npm/mirror-registry-artifacts.js +114 -0
  194. package/dist/cli/npm/mirror-registry-artifacts.js.map +1 -0
  195. package/dist/cli/npm/publish/command-options.d.ts +24 -0
  196. package/dist/cli/npm/publish/command-options.d.ts.map +1 -0
  197. package/dist/cli/npm/publish/command-options.js +85 -0
  198. package/dist/cli/npm/publish/command-options.js.map +1 -0
  199. package/dist/cli/npm/publish/concurrency.d.ts +19 -0
  200. package/dist/cli/npm/publish/concurrency.d.ts.map +1 -0
  201. package/dist/cli/npm/publish/concurrency.js +60 -0
  202. package/dist/cli/npm/publish/concurrency.js.map +1 -0
  203. package/dist/cli/npm/publish/consumer-smoke.d.ts +83 -0
  204. package/dist/cli/npm/publish/consumer-smoke.d.ts.map +1 -0
  205. package/dist/cli/npm/publish/consumer-smoke.js +371 -0
  206. package/dist/cli/npm/publish/consumer-smoke.js.map +1 -0
  207. package/dist/cli/npm/publish/consumer-surfaces.d.ts +81 -0
  208. package/dist/cli/npm/publish/consumer-surfaces.d.ts.map +1 -0
  209. package/dist/cli/npm/publish/consumer-surfaces.js +199 -0
  210. package/dist/cli/npm/publish/consumer-surfaces.js.map +1 -0
  211. package/dist/cli/npm/publish/external-requirements.d.ts +171 -0
  212. package/dist/cli/npm/publish/external-requirements.d.ts.map +1 -0
  213. package/dist/cli/npm/publish/external-requirements.js +365 -0
  214. package/dist/cli/npm/publish/external-requirements.js.map +1 -0
  215. package/dist/cli/npm/publish/forge-source-identity.d.ts +64 -0
  216. package/dist/cli/npm/publish/forge-source-identity.d.ts.map +1 -0
  217. package/dist/cli/npm/publish/forge-source-identity.js +201 -0
  218. package/dist/cli/npm/publish/forge-source-identity.js.map +1 -0
  219. package/dist/cli/npm/publish/fs-paths.d.ts +25 -0
  220. package/dist/cli/npm/publish/fs-paths.d.ts.map +1 -0
  221. package/dist/cli/npm/publish/fs-paths.js +87 -0
  222. package/dist/cli/npm/publish/fs-paths.js.map +1 -0
  223. package/dist/cli/npm/publish/lease-preflight-answer.d.ts +17 -0
  224. package/dist/cli/npm/publish/lease-preflight-answer.d.ts.map +1 -0
  225. package/dist/cli/npm/publish/lease-preflight-answer.js +35 -0
  226. package/dist/cli/npm/publish/lease-preflight-answer.js.map +1 -0
  227. package/dist/cli/npm/publish/lease-preflight.d.ts +92 -0
  228. package/dist/cli/npm/publish/lease-preflight.d.ts.map +1 -0
  229. package/dist/cli/npm/publish/lease-preflight.js +205 -0
  230. package/dist/cli/npm/publish/lease-preflight.js.map +1 -0
  231. package/dist/cli/npm/publish/managed-lease.d.ts +110 -0
  232. package/dist/cli/npm/publish/managed-lease.d.ts.map +1 -0
  233. package/dist/cli/npm/publish/managed-lease.js +191 -0
  234. package/dist/cli/npm/publish/managed-lease.js.map +1 -0
  235. package/dist/cli/npm/publish/npm-exec.d.ts +148 -0
  236. package/dist/cli/npm/publish/npm-exec.d.ts.map +1 -0
  237. package/dist/cli/npm/publish/npm-exec.js +311 -0
  238. package/dist/cli/npm/publish/npm-exec.js.map +1 -0
  239. package/dist/cli/npm/publish/package-artifact.d.ts +107 -0
  240. package/dist/cli/npm/publish/package-artifact.d.ts.map +1 -0
  241. package/dist/cli/npm/publish/package-artifact.js +418 -0
  242. package/dist/cli/npm/publish/package-artifact.js.map +1 -0
  243. package/dist/cli/npm/publish/platform-registry.d.ts +76 -0
  244. package/dist/cli/npm/publish/platform-registry.d.ts.map +1 -0
  245. package/dist/cli/npm/publish/platform-registry.js +324 -0
  246. package/dist/cli/npm/publish/platform-registry.js.map +1 -0
  247. package/dist/cli/npm/publish/proof-external-closure.d.ts +139 -0
  248. package/dist/cli/npm/publish/proof-external-closure.d.ts.map +1 -0
  249. package/dist/cli/npm/publish/proof-external-closure.js +339 -0
  250. package/dist/cli/npm/publish/proof-external-closure.js.map +1 -0
  251. package/dist/cli/npm/publish/proof-installed-graph.d.ts +26 -0
  252. package/dist/cli/npm/publish/proof-installed-graph.d.ts.map +1 -0
  253. package/dist/cli/npm/publish/proof-installed-graph.js +229 -0
  254. package/dist/cli/npm/publish/proof-installed-graph.js.map +1 -0
  255. package/dist/cli/npm/publish/proof-registry.d.ts +74 -0
  256. package/dist/cli/npm/publish/proof-registry.d.ts.map +1 -0
  257. package/dist/cli/npm/publish/proof-registry.js +335 -0
  258. package/dist/cli/npm/publish/proof-registry.js.map +1 -0
  259. package/dist/cli/npm/publish/proof-source-credentials.d.ts +42 -0
  260. package/dist/cli/npm/publish/proof-source-credentials.d.ts.map +1 -0
  261. package/dist/cli/npm/publish/proof-source-credentials.js +129 -0
  262. package/dist/cli/npm/publish/proof-source-credentials.js.map +1 -0
  263. package/dist/cli/npm/publish/publish-package.d.ts +66 -0
  264. package/dist/cli/npm/publish/publish-package.d.ts.map +1 -0
  265. package/dist/cli/npm/publish/publish-package.js +544 -0
  266. package/dist/cli/npm/publish/publish-package.js.map +1 -0
  267. package/dist/cli/npm/publish/publisher-manifest.d.ts +173 -0
  268. package/dist/cli/npm/publish/publisher-manifest.d.ts.map +1 -0
  269. package/dist/cli/npm/publish/publisher-manifest.js +79 -0
  270. package/dist/cli/npm/publish/publisher-manifest.js.map +1 -0
  271. package/dist/cli/npm/publish/rc-major-exception.d.ts +20 -0
  272. package/dist/cli/npm/publish/rc-major-exception.d.ts.map +1 -0
  273. package/dist/cli/npm/publish/rc-major-exception.js +46 -0
  274. package/dist/cli/npm/publish/rc-major-exception.js.map +1 -0
  275. package/dist/cli/npm/publish/registry-availability.d.ts +150 -0
  276. package/dist/cli/npm/publish/registry-availability.d.ts.map +1 -0
  277. package/dist/cli/npm/publish/registry-availability.js +570 -0
  278. package/dist/cli/npm/publish/registry-availability.js.map +1 -0
  279. package/dist/cli/npm/publish/registry-credentials.d.ts +108 -0
  280. package/dist/cli/npm/publish/registry-credentials.d.ts.map +1 -0
  281. package/dist/cli/npm/publish/registry-credentials.js +290 -0
  282. package/dist/cli/npm/publish/registry-credentials.js.map +1 -0
  283. package/dist/cli/npm/publish/registry-reads.d.ts +42 -0
  284. package/dist/cli/npm/publish/registry-reads.d.ts.map +1 -0
  285. package/dist/cli/npm/publish/registry-reads.js +164 -0
  286. package/dist/cli/npm/publish/registry-reads.js.map +1 -0
  287. package/dist/cli/npm/publish/release-build.d.ts +46 -0
  288. package/dist/cli/npm/publish/release-build.d.ts.map +1 -0
  289. package/dist/cli/npm/publish/release-build.js +140 -0
  290. package/dist/cli/npm/publish/release-build.js.map +1 -0
  291. package/dist/cli/npm/publish/release-consumer-proof.d.ts +70 -0
  292. package/dist/cli/npm/publish/release-consumer-proof.d.ts.map +1 -0
  293. package/dist/cli/npm/publish/release-consumer-proof.js +397 -0
  294. package/dist/cli/npm/publish/release-consumer-proof.js.map +1 -0
  295. package/dist/cli/npm/publish/release-executor.d.ts +46 -0
  296. package/dist/cli/npm/publish/release-executor.d.ts.map +1 -0
  297. package/dist/cli/npm/publish/release-executor.js +181 -0
  298. package/dist/cli/npm/publish/release-executor.js.map +1 -0
  299. package/dist/cli/npm/publish/release-grants.client.impl.d.ts +10 -0
  300. package/dist/cli/npm/publish/release-grants.client.impl.d.ts.map +1 -0
  301. package/dist/cli/npm/publish/release-grants.client.impl.js +63 -0
  302. package/dist/cli/npm/publish/release-grants.client.impl.js.map +1 -0
  303. package/dist/cli/npm/publish/release-jobs.client.d.ts +39 -0
  304. package/dist/cli/npm/publish/release-jobs.client.d.ts.map +1 -0
  305. package/dist/cli/npm/publish/release-jobs.client.js +124 -0
  306. package/dist/cli/npm/publish/release-jobs.client.js.map +1 -0
  307. package/dist/cli/npm/publish/release-jobs.consumer.plugin.d.ts +20 -0
  308. package/dist/cli/npm/publish/release-jobs.consumer.plugin.d.ts.map +1 -0
  309. package/dist/cli/npm/publish/release-jobs.consumer.plugin.js +82 -0
  310. package/dist/cli/npm/publish/release-jobs.consumer.plugin.js.map +1 -0
  311. package/dist/cli/npm/publish/release-jobs.impl.d.ts +15 -0
  312. package/dist/cli/npm/publish/release-jobs.impl.d.ts.map +1 -0
  313. package/dist/cli/npm/publish/release-jobs.impl.js +42 -0
  314. package/dist/cli/npm/publish/release-jobs.impl.js.map +1 -0
  315. package/dist/cli/npm/publish/release-lock.d.ts +143 -0
  316. package/dist/cli/npm/publish/release-lock.d.ts.map +1 -0
  317. package/dist/cli/npm/publish/release-lock.js +371 -0
  318. package/dist/cli/npm/publish/release-lock.js.map +1 -0
  319. package/dist/cli/npm/publish/release-phases.d.ts +93 -0
  320. package/dist/cli/npm/publish/release-phases.d.ts.map +1 -0
  321. package/dist/cli/npm/publish/release-phases.js +175 -0
  322. package/dist/cli/npm/publish/release-phases.js.map +1 -0
  323. package/dist/cli/npm/publish/release-plan.d.ts +65 -0
  324. package/dist/cli/npm/publish/release-plan.d.ts.map +1 -0
  325. package/dist/cli/npm/publish/release-plan.js +178 -0
  326. package/dist/cli/npm/publish/release-plan.js.map +1 -0
  327. package/dist/cli/npm/publish/release-preflight.job.impl.d.ts +16 -0
  328. package/dist/cli/npm/publish/release-preflight.job.impl.d.ts.map +1 -0
  329. package/dist/cli/npm/publish/release-preflight.job.impl.js +71 -0
  330. package/dist/cli/npm/publish/release-preflight.job.impl.js.map +1 -0
  331. package/dist/cli/npm/publish/release-publish.job.impl.d.ts +18 -0
  332. package/dist/cli/npm/publish/release-publish.job.impl.d.ts.map +1 -0
  333. package/dist/cli/npm/publish/release-publish.job.impl.js +295 -0
  334. package/dist/cli/npm/publish/release-publish.job.impl.js.map +1 -0
  335. package/dist/cli/npm/publish/release-workspace.d.ts +95 -0
  336. package/dist/cli/npm/publish/release-workspace.d.ts.map +1 -0
  337. package/dist/cli/npm/publish/release-workspace.js +243 -0
  338. package/dist/cli/npm/publish/release-workspace.js.map +1 -0
  339. package/dist/cli/npm/publish/sensitive-temp.d.ts +90 -0
  340. package/dist/cli/npm/publish/sensitive-temp.d.ts.map +1 -0
  341. package/dist/cli/npm/publish/sensitive-temp.js +351 -0
  342. package/dist/cli/npm/publish/sensitive-temp.js.map +1 -0
  343. package/dist/cli/npm/publish/source-snapshot.d.ts +91 -0
  344. package/dist/cli/npm/publish/source-snapshot.d.ts.map +1 -0
  345. package/dist/cli/npm/publish/source-snapshot.js +245 -0
  346. package/dist/cli/npm/publish/source-snapshot.js.map +1 -0
  347. package/dist/cli/npm/publish/types.d.ts +69 -0
  348. package/dist/cli/npm/publish/types.d.ts.map +1 -0
  349. package/dist/cli/npm/publish/types.js +2 -0
  350. package/dist/cli/npm/publish/types.js.map +1 -0
  351. package/dist/cli/npm/publish/workspace-discovery.d.ts +48 -0
  352. package/dist/cli/npm/publish/workspace-discovery.d.ts.map +1 -0
  353. package/dist/cli/npm/publish/workspace-discovery.js +313 -0
  354. package/dist/cli/npm/publish/workspace-discovery.js.map +1 -0
  355. package/dist/cli/npm/put-attested-packument.d.ts +96 -0
  356. package/dist/cli/npm/put-attested-packument.d.ts.map +1 -0
  357. package/dist/cli/npm/put-attested-packument.js +240 -0
  358. package/dist/cli/npm/put-attested-packument.js.map +1 -0
  359. package/dist/cli/npm/reconcile-latest.d.ts +55 -0
  360. package/dist/cli/npm/reconcile-latest.d.ts.map +1 -0
  361. package/dist/cli/npm/reconcile-latest.js +59 -0
  362. package/dist/cli/npm/reconcile-latest.js.map +1 -0
  363. package/dist/cli/observability/blind-spots.d.ts +10 -0
  364. package/dist/cli/observability/blind-spots.d.ts.map +1 -0
  365. package/dist/cli/observability/blind-spots.js +19 -0
  366. package/dist/cli/observability/blind-spots.js.map +1 -0
  367. package/dist/cli/observability/infra-observability-exports-list.cli-command.impl.d.ts +6 -0
  368. package/dist/cli/observability/infra-observability-exports-list.cli-command.impl.d.ts.map +1 -0
  369. package/dist/cli/observability/infra-observability-exports-list.cli-command.impl.js +75 -0
  370. package/dist/cli/observability/infra-observability-exports-list.cli-command.impl.js.map +1 -0
  371. package/dist/cli/observability/infra-observability-set.cli-command.descriptor.d.ts +42 -21
  372. package/dist/cli/observability/infra-observability-set.cli-command.descriptor.d.ts.map +1 -1
  373. package/dist/cli/observability/infra-observability-set.cli-command.descriptor.js +3 -3
  374. package/dist/cli/observability/infra-observability-set.cli-command.descriptor.js.map +1 -1
  375. package/dist/cli/observability/infra-observability-set.cli-command.impl.d.ts +3 -2
  376. package/dist/cli/observability/infra-observability-set.cli-command.impl.d.ts.map +1 -1
  377. package/dist/cli/observability/infra-observability-set.cli-command.impl.js +14 -14
  378. package/dist/cli/observability/infra-observability-set.cli-command.impl.js.map +1 -1
  379. package/dist/cli/observability/infra-observability-status.cli-command.descriptor.d.ts +25 -17
  380. package/dist/cli/observability/infra-observability-status.cli-command.descriptor.d.ts.map +1 -1
  381. package/dist/cli/observability/infra-observability-status.cli-command.descriptor.js +1 -1
  382. package/dist/cli/observability/infra-observability-status.cli-command.descriptor.js.map +1 -1
  383. package/dist/cli/observability/infra-observability-status.cli-command.impl.d.ts +2 -1
  384. package/dist/cli/observability/infra-observability-status.cli-command.impl.d.ts.map +1 -1
  385. package/dist/cli/observability/infra-observability-status.cli-command.impl.js +30 -23
  386. package/dist/cli/observability/infra-observability-status.cli-command.impl.js.map +1 -1
  387. package/dist/cli/observability/infra-observability.cli-group.descriptor.d.ts +8 -8
  388. package/dist/cli/observability/infra-observability.cli-group.descriptor.js +1 -1
  389. package/dist/cli/observability/infra-observability.cli-group.descriptor.js.map +1 -1
  390. package/dist/cli/plugin.d.ts +3 -0
  391. package/dist/cli/plugin.d.ts.map +1 -0
  392. package/dist/cli/plugin.js +45 -0
  393. package/dist/cli/plugin.js.map +1 -0
  394. package/dist/cli/readiness/infra-deploy.readiness.cli-command.descriptor.d.ts +38 -0
  395. package/dist/cli/readiness/infra-deploy.readiness.cli-command.descriptor.d.ts.map +1 -0
  396. package/dist/cli/readiness/infra-deploy.readiness.cli-command.descriptor.js +43 -0
  397. package/dist/cli/readiness/infra-deploy.readiness.cli-command.descriptor.js.map +1 -0
  398. package/dist/cli/readiness/infra-deploy.readiness.cli-command.impl.d.ts +117 -0
  399. package/dist/cli/readiness/infra-deploy.readiness.cli-command.impl.d.ts.map +1 -0
  400. package/dist/cli/readiness/infra-deploy.readiness.cli-command.impl.js +678 -0
  401. package/dist/cli/readiness/infra-deploy.readiness.cli-command.impl.js.map +1 -0
  402. package/dist/cli/regenerate/infra-deploy.regenerate.cli-command.descriptor.d.ts +37 -23
  403. package/dist/cli/regenerate/infra-deploy.regenerate.cli-command.descriptor.d.ts.map +1 -1
  404. package/dist/cli/regenerate/infra-deploy.regenerate.cli-command.descriptor.js +7 -1
  405. package/dist/cli/regenerate/infra-deploy.regenerate.cli-command.descriptor.js.map +1 -1
  406. package/dist/cli/regenerate/infra-deploy.regenerate.cli-command.impl.d.ts +2 -1
  407. package/dist/cli/regenerate/infra-deploy.regenerate.cli-command.impl.d.ts.map +1 -1
  408. package/dist/cli/regenerate/infra-deploy.regenerate.cli-command.impl.js +100 -25
  409. package/dist/cli/regenerate/infra-deploy.regenerate.cli-command.impl.js.map +1 -1
  410. package/dist/cli/release/cli/latest-manifest.d.ts +148 -0
  411. package/dist/cli/release/cli/latest-manifest.d.ts.map +1 -0
  412. package/dist/cli/release/cli/latest-manifest.js +152 -0
  413. package/dist/cli/release/cli/latest-manifest.js.map +1 -0
  414. package/dist/cli/rollback/infra-deploy.rollback.cli-command.descriptor.d.ts +41 -0
  415. package/dist/cli/rollback/infra-deploy.rollback.cli-command.descriptor.d.ts.map +1 -0
  416. package/dist/cli/rollback/infra-deploy.rollback.cli-command.descriptor.js +49 -0
  417. package/dist/cli/rollback/infra-deploy.rollback.cli-command.descriptor.js.map +1 -0
  418. package/dist/cli/rollback/infra-deploy.rollback.cli-command.impl.d.ts +16 -0
  419. package/dist/cli/rollback/infra-deploy.rollback.cli-command.impl.d.ts.map +1 -0
  420. package/dist/cli/rollback/infra-deploy.rollback.cli-command.impl.js +52 -0
  421. package/dist/cli/rollback/infra-deploy.rollback.cli-command.impl.js.map +1 -0
  422. package/dist/cli/rum/infra-rum-status.cli-command.descriptor.d.ts +19 -17
  423. package/dist/cli/rum/infra-rum-status.cli-command.descriptor.d.ts.map +1 -1
  424. package/dist/cli/rum/infra-rum-status.cli-command.descriptor.js +1 -1
  425. package/dist/cli/rum/infra-rum-status.cli-command.descriptor.js.map +1 -1
  426. package/dist/cli/rum/infra-rum-status.cli-command.impl.d.ts +2 -1
  427. package/dist/cli/rum/infra-rum-status.cli-command.impl.d.ts.map +1 -1
  428. package/dist/cli/rum/infra-rum-status.cli-command.impl.js +21 -15
  429. package/dist/cli/rum/infra-rum-status.cli-command.impl.js.map +1 -1
  430. package/dist/cli/rum/infra-rum.cli-group.descriptor.d.ts +8 -8
  431. package/dist/cli/rum/infra-rum.cli-group.descriptor.js +1 -1
  432. package/dist/cli/rum/infra-rum.cli-group.descriptor.js.map +1 -1
  433. package/dist/cli/run/deploy-smoke.d.ts +57 -0
  434. package/dist/cli/run/deploy-smoke.d.ts.map +1 -0
  435. package/dist/cli/run/deploy-smoke.js +251 -0
  436. package/dist/cli/run/deploy-smoke.js.map +1 -0
  437. package/dist/cli/run/deployment-marker.d.ts +74 -0
  438. package/dist/cli/run/deployment-marker.d.ts.map +1 -0
  439. package/dist/cli/run/deployment-marker.js +237 -0
  440. package/dist/cli/run/deployment-marker.js.map +1 -0
  441. package/dist/cli/run/deployment-provider.d.ts +56 -0
  442. package/dist/cli/run/deployment-provider.d.ts.map +1 -0
  443. package/dist/cli/run/deployment-provider.js +295 -0
  444. package/dist/cli/run/deployment-provider.js.map +1 -0
  445. package/dist/cli/run/deployment-run-ledger.d.ts +72 -0
  446. package/dist/cli/run/deployment-run-ledger.d.ts.map +1 -0
  447. package/dist/cli/run/deployment-run-ledger.js +164 -0
  448. package/dist/cli/run/deployment-run-ledger.js.map +1 -0
  449. package/dist/cli/run/git-source-identity.d.ts +21 -0
  450. package/dist/cli/run/git-source-identity.d.ts.map +1 -0
  451. package/dist/cli/run/git-source-identity.js +73 -0
  452. package/dist/cli/run/git-source-identity.js.map +1 -0
  453. package/dist/cli/run/immutable-deployment-release.program.d.ts +403 -0
  454. package/dist/cli/run/immutable-deployment-release.program.d.ts.map +1 -0
  455. package/dist/cli/run/immutable-deployment-release.program.js +589 -0
  456. package/dist/cli/run/immutable-deployment-release.program.js.map +1 -0
  457. package/dist/cli/run/immutable-deployment-workspace.d.ts +39 -0
  458. package/dist/cli/run/immutable-deployment-workspace.d.ts.map +1 -0
  459. package/dist/cli/run/immutable-deployment-workspace.js +525 -0
  460. package/dist/cli/run/immutable-deployment-workspace.js.map +1 -0
  461. package/dist/cli/run/infra-deploy.run.cli-command.descriptor.d.ts +80 -23
  462. package/dist/cli/run/infra-deploy.run.cli-command.descriptor.d.ts.map +1 -1
  463. package/dist/cli/run/infra-deploy.run.cli-command.descriptor.js +50 -8
  464. package/dist/cli/run/infra-deploy.run.cli-command.descriptor.js.map +1 -1
  465. package/dist/cli/run/infra-deploy.run.cli-command.impl.d.ts +46 -1
  466. package/dist/cli/run/infra-deploy.run.cli-command.impl.d.ts.map +1 -1
  467. package/dist/cli/run/infra-deploy.run.cli-command.impl.js +464 -226
  468. package/dist/cli/run/infra-deploy.run.cli-command.impl.js.map +1 -1
  469. package/dist/cli/shared/build-workspace-artifacts.d.ts +147 -0
  470. package/dist/cli/shared/build-workspace-artifacts.d.ts.map +1 -0
  471. package/dist/cli/shared/build-workspace-artifacts.js +2013 -0
  472. package/dist/cli/shared/build-workspace-artifacts.js.map +1 -0
  473. package/dist/cli/shared/credential-source.d.ts +3 -0
  474. package/dist/cli/shared/credential-source.d.ts.map +1 -0
  475. package/dist/cli/shared/credential-source.js +19 -0
  476. package/dist/cli/shared/credential-source.js.map +1 -0
  477. package/dist/cli/shared/discover-deployments.d.ts +46 -5
  478. package/dist/cli/shared/discover-deployments.d.ts.map +1 -1
  479. package/dist/cli/shared/discover-deployments.js +167 -41
  480. package/dist/cli/shared/discover-deployments.js.map +1 -1
  481. package/dist/cli/shared/infer-apex-zone.d.ts +18 -0
  482. package/dist/cli/shared/infer-apex-zone.d.ts.map +1 -0
  483. package/dist/cli/shared/infer-apex-zone.js +75 -0
  484. package/dist/cli/shared/infer-apex-zone.js.map +1 -0
  485. package/dist/cli/shared/option-strings.d.ts +2 -0
  486. package/dist/cli/shared/option-strings.d.ts.map +1 -0
  487. package/dist/cli/shared/option-strings.js +13 -0
  488. package/dist/cli/shared/option-strings.js.map +1 -0
  489. package/dist/cli/shared/repository-collection.d.ts +42 -0
  490. package/dist/cli/shared/repository-collection.d.ts.map +1 -0
  491. package/dist/cli/shared/repository-collection.js +111 -0
  492. package/dist/cli/shared/repository-collection.js.map +1 -0
  493. package/dist/cli/shared/runtime-execution.d.ts +78 -0
  494. package/dist/cli/shared/runtime-execution.d.ts.map +1 -0
  495. package/dist/cli/shared/runtime-execution.js +182 -0
  496. package/dist/cli/shared/runtime-execution.js.map +1 -0
  497. package/dist/cli/shared/workspace-artifact-lock.d.ts +17 -0
  498. package/dist/cli/shared/workspace-artifact-lock.d.ts.map +1 -0
  499. package/dist/cli/shared/workspace-artifact-lock.js +37 -0
  500. package/dist/cli/shared/workspace-artifact-lock.js.map +1 -0
  501. package/dist/cli/workers/doks-worker-runtime.d.ts +238 -0
  502. package/dist/cli/workers/doks-worker-runtime.d.ts.map +1 -0
  503. package/dist/cli/workers/doks-worker-runtime.js +410 -0
  504. package/dist/cli/workers/doks-worker-runtime.js.map +1 -0
  505. package/dist/cli/workers/infra-workers-apply.cli-command.descriptor.d.ts +28 -0
  506. package/dist/cli/workers/infra-workers-apply.cli-command.descriptor.d.ts.map +1 -0
  507. package/dist/cli/workers/infra-workers-apply.cli-command.descriptor.js +28 -0
  508. package/dist/cli/workers/infra-workers-apply.cli-command.descriptor.js.map +1 -0
  509. package/dist/cli/workers/infra-workers-apply.cli-command.impl.d.ts +6 -0
  510. package/dist/cli/workers/infra-workers-apply.cli-command.impl.d.ts.map +1 -0
  511. package/dist/cli/workers/infra-workers-apply.cli-command.impl.js +75 -0
  512. package/dist/cli/workers/infra-workers-apply.cli-command.impl.js.map +1 -0
  513. package/dist/cli/workers/infra-workers-build.cli-command.descriptor.d.ts +31 -0
  514. package/dist/cli/workers/infra-workers-build.cli-command.descriptor.d.ts.map +1 -0
  515. package/dist/cli/workers/infra-workers-build.cli-command.descriptor.js +32 -0
  516. package/dist/cli/workers/infra-workers-build.cli-command.descriptor.js.map +1 -0
  517. package/dist/cli/workers/infra-workers-build.cli-command.impl.d.ts +6 -0
  518. package/dist/cli/workers/infra-workers-build.cli-command.impl.d.ts.map +1 -0
  519. package/dist/cli/workers/infra-workers-build.cli-command.impl.js +67 -0
  520. package/dist/cli/workers/infra-workers-build.cli-command.impl.js.map +1 -0
  521. package/dist/cli/workers/infra-workers-logs.cli-command.descriptor.d.ts +48 -0
  522. package/dist/cli/workers/infra-workers-logs.cli-command.descriptor.d.ts.map +1 -0
  523. package/dist/cli/workers/infra-workers-logs.cli-command.descriptor.js +60 -0
  524. package/dist/cli/workers/infra-workers-logs.cli-command.descriptor.js.map +1 -0
  525. package/dist/cli/workers/infra-workers-logs.cli-command.impl.d.ts +6 -0
  526. package/dist/cli/workers/infra-workers-logs.cli-command.impl.d.ts.map +1 -0
  527. package/dist/cli/workers/infra-workers-logs.cli-command.impl.js +74 -0
  528. package/dist/cli/workers/infra-workers-logs.cli-command.impl.js.map +1 -0
  529. package/dist/cli/workers/infra-workers.cli-group.descriptor.d.ts +12 -0
  530. package/dist/cli/workers/infra-workers.cli-group.descriptor.d.ts.map +1 -0
  531. package/dist/cli/workers/infra-workers.cli-group.descriptor.js +12 -0
  532. package/dist/cli/workers/infra-workers.cli-group.descriptor.js.map +1 -0
  533. package/dist/config-loader.d.ts +60 -13
  534. package/dist/config-loader.d.ts.map +1 -1
  535. package/dist/config-loader.js +371 -104
  536. package/dist/config-loader.js.map +1 -1
  537. package/dist/declared-provider.d.ts +27 -0
  538. package/dist/declared-provider.d.ts.map +1 -0
  539. package/dist/declared-provider.js +46 -0
  540. package/dist/declared-provider.js.map +1 -0
  541. package/dist/deployment-collisions.d.ts +55 -0
  542. package/dist/deployment-collisions.d.ts.map +1 -0
  543. package/dist/deployment-collisions.js +70 -0
  544. package/dist/deployment-collisions.js.map +1 -0
  545. package/dist/deployment-environment.d.ts +57 -0
  546. package/dist/deployment-environment.d.ts.map +1 -0
  547. package/dist/deployment-environment.js +198 -0
  548. package/dist/deployment-environment.js.map +1 -0
  549. package/dist/deployment-settings.d.ts +27 -0
  550. package/dist/deployment-settings.d.ts.map +1 -0
  551. package/dist/deployment-settings.js +52 -0
  552. package/dist/deployment-settings.js.map +1 -0
  553. package/dist/deployment.config.descriptor.d.ts +59 -0
  554. package/dist/deployment.config.descriptor.d.ts.map +1 -0
  555. package/dist/deployment.config.descriptor.js +54 -0
  556. package/dist/deployment.config.descriptor.js.map +1 -0
  557. package/dist/descriptors/observability/infra-observability-exports-list.cli-command.descriptor.d.ts +29 -0
  558. package/dist/descriptors/observability/infra-observability-exports-list.cli-command.descriptor.d.ts.map +1 -0
  559. package/dist/descriptors/observability/infra-observability-exports-list.cli-command.descriptor.js +35 -0
  560. package/dist/descriptors/observability/infra-observability-exports-list.cli-command.descriptor.js.map +1 -0
  561. package/dist/descriptors/observability/infra-observability-exports.cli-group.descriptor.d.ts +12 -0
  562. package/dist/descriptors/observability/infra-observability-exports.cli-group.descriptor.d.ts.map +1 -0
  563. package/dist/descriptors/observability/infra-observability-exports.cli-group.descriptor.js +12 -0
  564. package/dist/descriptors/observability/infra-observability-exports.cli-group.descriptor.js.map +1 -0
  565. package/dist/index.d.ts +11 -3
  566. package/dist/index.d.ts.map +1 -1
  567. package/dist/index.js +11 -3
  568. package/dist/index.js.map +1 -1
  569. package/dist/infra-deploy.plugin.d.ts +2 -2
  570. package/dist/infra-deploy.plugin.d.ts.map +1 -1
  571. package/dist/infra-deploy.plugin.js +63 -20
  572. package/dist/infra-deploy.plugin.js.map +1 -1
  573. package/dist/logger.d.ts +10 -0
  574. package/dist/logger.d.ts.map +1 -0
  575. package/dist/logger.js +11 -0
  576. package/dist/logger.js.map +1 -0
  577. package/dist/migrations/migrate-workspace.d.ts +21 -0
  578. package/dist/migrations/migrate-workspace.d.ts.map +1 -0
  579. package/dist/migrations/migrate-workspace.js +83 -0
  580. package/dist/migrations/migrate-workspace.js.map +1 -0
  581. package/dist/migrations/run-migrate.d.ts +15 -0
  582. package/dist/migrations/run-migrate.d.ts.map +1 -0
  583. package/dist/migrations/run-migrate.js +314 -0
  584. package/dist/migrations/run-migrate.js.map +1 -0
  585. package/dist/regenerate.d.ts +52 -30
  586. package/dist/regenerate.d.ts.map +1 -1
  587. package/dist/regenerate.js +176 -148
  588. package/dist/regenerate.js.map +1 -1
  589. package/dist/runtime-execution.d.ts +5 -0
  590. package/dist/runtime-execution.d.ts.map +1 -0
  591. package/dist/runtime-execution.js +12 -0
  592. package/dist/runtime-execution.js.map +1 -0
  593. package/dist/schemas/migrate.d.ts +110 -0
  594. package/dist/schemas/migrate.d.ts.map +1 -0
  595. package/dist/schemas/migrate.js +55 -0
  596. package/dist/schemas/migrate.js.map +1 -0
  597. package/dist/schemas/proof-registry.d.ts +25 -0
  598. package/dist/schemas/proof-registry.d.ts.map +1 -0
  599. package/dist/schemas/proof-registry.js +24 -0
  600. package/dist/schemas/proof-registry.js.map +1 -0
  601. package/dist/schemas/release-grants.d.ts +7 -0
  602. package/dist/schemas/release-grants.d.ts.map +1 -0
  603. package/dist/schemas/release-grants.js +6 -0
  604. package/dist/schemas/release-grants.js.map +1 -0
  605. package/dist/schemas/release-jobs.d.ts +444 -0
  606. package/dist/schemas/release-jobs.d.ts.map +1 -0
  607. package/dist/schemas/release-jobs.js +204 -0
  608. package/dist/schemas/release-jobs.js.map +1 -0
  609. package/dist/schemas/service-release.d.ts +15 -0
  610. package/dist/schemas/service-release.d.ts.map +1 -0
  611. package/dist/schemas/service-release.js +13 -0
  612. package/dist/schemas/service-release.js.map +1 -0
  613. package/dist/schemas/worker-logs.d.ts +42 -0
  614. package/dist/schemas/worker-logs.d.ts.map +1 -0
  615. package/dist/schemas/worker-logs.js +29 -0
  616. package/dist/schemas/worker-logs.js.map +1 -0
  617. package/dist/storage/deployment-runs.schema.d.ts +199 -0
  618. package/dist/storage/deployment-runs.schema.d.ts.map +1 -0
  619. package/dist/storage/deployment-runs.schema.js +61 -0
  620. package/dist/storage/deployment-runs.schema.js.map +1 -0
  621. package/dist/storage/deployment-runs.storage.descriptor.d.ts +4 -0
  622. package/dist/storage/deployment-runs.storage.descriptor.d.ts.map +1 -0
  623. package/dist/storage/deployment-runs.storage.descriptor.js +36 -0
  624. package/dist/storage/deployment-runs.storage.descriptor.js.map +1 -0
  625. package/package.json +110 -42
  626. package/SPEC.md +0 -181
  627. package/src/cli/alerts/infra-alerts-create.cli-command.descriptor.ts +0 -61
  628. package/src/cli/alerts/infra-alerts-create.cli-command.impl.ts +0 -131
  629. package/src/cli/alerts/infra-alerts-delete.cli-command.descriptor.ts +0 -36
  630. package/src/cli/alerts/infra-alerts-delete.cli-command.impl.ts +0 -75
  631. package/src/cli/alerts/infra-alerts-list.cli-command.descriptor.ts +0 -27
  632. package/src/cli/alerts/infra-alerts-list.cli-command.impl.ts +0 -88
  633. package/src/cli/alerts/infra-alerts.cli-group.descriptor.ts +0 -12
  634. package/src/cli/audit/infra-audit.cli-command.descriptor.ts +0 -28
  635. package/src/cli/audit/infra-audit.cli-command.impl.ts +0 -293
  636. package/src/cli/infra-deploy.cli-group.descriptor.ts +0 -12
  637. package/src/cli/infra.cli-group.descriptor.ts +0 -11
  638. package/src/cli/list/infra-deploy.list.cli-command.descriptor.ts +0 -29
  639. package/src/cli/list/infra-deploy.list.cli-command.impl.ts +0 -125
  640. package/src/cli/logs/infra-logs.cli-command.descriptor.ts +0 -65
  641. package/src/cli/logs/infra-logs.cli-command.impl.ts +0 -354
  642. package/src/cli/logs/stream-worker-tail.ts +0 -202
  643. package/src/cli/npm/infra-npm-publish.cli-command.descriptor.ts +0 -75
  644. package/src/cli/npm/infra-npm-publish.cli-command.impl.ts +0 -474
  645. package/src/cli/npm/infra-npm.cli-group.descriptor.ts +0 -12
  646. package/src/cli/observability/infra-observability-set.cli-command.descriptor.ts +0 -57
  647. package/src/cli/observability/infra-observability-set.cli-command.impl.ts +0 -173
  648. package/src/cli/observability/infra-observability-status.cli-command.descriptor.ts +0 -35
  649. package/src/cli/observability/infra-observability-status.cli-command.impl.ts +0 -124
  650. package/src/cli/observability/infra-observability.cli-group.descriptor.ts +0 -12
  651. package/src/cli/regenerate/infra-deploy.regenerate.cli-command.descriptor.ts +0 -36
  652. package/src/cli/regenerate/infra-deploy.regenerate.cli-command.impl.ts +0 -103
  653. package/src/cli/rum/infra-rum-status.cli-command.descriptor.ts +0 -27
  654. package/src/cli/rum/infra-rum-status.cli-command.impl.ts +0 -112
  655. package/src/cli/rum/infra-rum.cli-group.descriptor.ts +0 -12
  656. package/src/cli/run/infra-deploy.run.cli-command.descriptor.ts +0 -49
  657. package/src/cli/run/infra-deploy.run.cli-command.impl.ts +0 -330
  658. package/src/cli/shared/discover-deployments.ts +0 -127
  659. package/src/config-loader.ts +0 -179
  660. package/src/index.ts +0 -11
  661. package/src/infra-deploy.plugin.ts +0 -83
  662. package/src/regenerate.ts +0 -230
@@ -0,0 +1,2013 @@
1
+ import { satisfies, validRange } from 'semver';
2
+ import * as z from 'zod/v4';
3
+ import { CapabilityError, settle } from '@vibesdotdev/kernel';
4
+ import { JsonValueSchema } from '@vibesdotdev/kernel/schemas/json';
5
+ import { planDag } from '@vibesdotdev/shared/schemas';
6
+ import { resolveHash } from '@vibesdotdev/crypto';
7
+ import { DeploymentBuildEvidenceSchema } from '@vibesdotdev/infra-core/kinds';
8
+ import { realpathChecked, resolveFileSystemAdapter } from '@vibesdotdev/filesystem';
9
+ import { getRuntimePath } from '@vibesdotdev/paths';
10
+ import { declaredPackageDirectories } from "../npm/publish/workspace-discovery.js";
11
+ import { parsePublisherManifest } from "../npm/publish/publisher-manifest.js";
12
+ import { infraDeployLogger } from "../../logger.js";
13
+ import { withWorkspaceArtifactLock } from "./workspace-artifact-lock.js";
14
+ import { runRuntimeCommand, registryTokenEnv } from "./runtime-execution.js";
15
+ function failureMessage(failure) {
16
+ return failure instanceof Error ? failure.message : failure.description;
17
+ }
18
+ /** The separator `paths.join` actually used, so containment checks follow the host. */
19
+ function pathSeparator(paths) {
20
+ const joined = paths.join('a', 'b');
21
+ const separator = joined.slice(1, joined.length - 1);
22
+ if (separator.length !== 1) {
23
+ throw new CapabilityError('The path host did not join two segments with one separator.', 'UNAVAILABLE', { reason: 'path-separator-unavailable' });
24
+ }
25
+ return separator;
26
+ }
27
+ async function resolveArtifactHost(runtime) {
28
+ const [files, paths, hash] = await Promise.all([
29
+ resolveFileSystemAdapter(runtime, { binding: false }),
30
+ getRuntimePath(runtime),
31
+ resolveHash(runtime)
32
+ ]);
33
+ return {
34
+ runtime,
35
+ files,
36
+ paths,
37
+ sep: pathSeparator(paths),
38
+ sha256: () => hash.createSha256()
39
+ };
40
+ }
41
+ async function readText(files, path) {
42
+ const contents = await files.readFile(path, 'utf8');
43
+ return contents instanceof Uint8Array ? new TextDecoder().decode(contents) : contents;
44
+ }
45
+ async function readBytes(files, path) {
46
+ const contents = await files.readFile(path);
47
+ return contents instanceof Uint8Array ? contents : new TextEncoder().encode(contents);
48
+ }
49
+ /** Follows one symlink, matching host `stat`. A link is not a directory entry. */
50
+ async function followedStat(host, path) {
51
+ const listed = await host.files.stat(path);
52
+ if (listed.kind !== 'symlink')
53
+ return listed;
54
+ return host.files.stat(await realpathChecked(host.files, path));
55
+ }
56
+ async function removeIfPresent(files, path) {
57
+ const removed = await settle(async () => {
58
+ await files.remove(path);
59
+ });
60
+ if (removed.ok || isMissingPathError(removed.cause))
61
+ return;
62
+ throw removed.cause;
63
+ }
64
+ /**
65
+ * The build-artifact directory a package's manifest declares via
66
+ * `"vibes": { "artifactsDir": "…" }`, or `dist` when it declares nothing.
67
+ * Every package that does not opt in keeps the original `dist`-only
68
+ * behaviour untouched.
69
+ */
70
+ function resolveArtifactsDir(pkg) {
71
+ return pkg.packageJson.vibes?.artifactsDir ?? 'dist';
72
+ }
73
+ /** Source admission and emitted bytes are separate receipts. A source hash never certifies output. */
74
+ export const WorkspaceBuildArtifactReceiptSchema = DeploymentBuildEvidenceSchema.shape.artifact.unwrap().extend({
75
+ files: z.array(z.object({ path: z.string(), digest: z.string().regex(/^[a-f0-9]{64}$/) }))
76
+ });
77
+ /** Installed locks are build inputs while a provider prepares its final artifacts. Missing locks participate too. */
78
+ export async function workspaceBuildLockDigest(input) {
79
+ const host = await resolveArtifactHost(input.runtime);
80
+ const root = await realpathChecked(host.files, input.workspaceRoot);
81
+ const locks = [];
82
+ for (const lock of [...new Set(input.lockFiles)].sort()) {
83
+ const path = host.paths.resolve(root, lock);
84
+ if (!isPathWithin(host, root, path))
85
+ throw new CapabilityError('An installed lock escapes its owned workspace.', 'INVALID_INPUT', { reason: 'workspace-artifact-outside' });
86
+ const stated = await settle(() => host.files.stat(path));
87
+ if (!stated.ok) {
88
+ if (!isMissingPathError(stated.cause))
89
+ throw stated.cause;
90
+ locks.push({ path: lock, digest: null });
91
+ continue;
92
+ }
93
+ if (stated.value.kind !== 'file' || !isPathWithin(host, root, await realpathChecked(host.files, path))) {
94
+ throw new CapabilityError('An installed lock is not an owned regular file.', 'INVALID_INPUT', { reason: 'workspace-artifact-invalid' });
95
+ }
96
+ locks.push({ path: lock, digest: host.sha256().update(await readBytes(host.files, path)).digestHex() });
97
+ }
98
+ return host.sha256().update(JSON.stringify(locks)).digestHex();
99
+ }
100
+ /** Hash the actual run-owned outputs and installed locks, including additions and same-size edits. */
101
+ export async function sealWorkspaceBuildArtifacts(input) {
102
+ const host = await resolveArtifactHost(input.runtime);
103
+ const root = await realpathChecked(host.files, input.workspaceRoot);
104
+ const files = new Map();
105
+ const visit = async (path) => {
106
+ if (!isPathWithin(host, root, path)) {
107
+ throw new CapabilityError('A build artifact escapes its owned workspace.', 'INVALID_INPUT', { reason: 'workspace-artifact-outside' });
108
+ }
109
+ const stated = await settle(() => host.files.stat(path));
110
+ if (!stated.ok) {
111
+ if (isMissingPathError(stated.cause))
112
+ throw new CapabilityError('A build artifact disappeared before consumption.', 'CONFLICT', { reason: 'workspace-artifact-missing', cause: stated.cause });
113
+ throw stated.cause;
114
+ }
115
+ const entry = stated.value;
116
+ if (entry.kind === 'symlink') {
117
+ throw new CapabilityError('Build artifact receipts require owned regular files.', 'INVALID_INPUT', { reason: 'workspace-artifact-symlink' });
118
+ }
119
+ if (!isPathWithin(host, root, await realpathChecked(host.files, path))) {
120
+ throw new CapabilityError('A build artifact resolves outside its owned workspace.', 'INVALID_INPUT', { reason: 'workspace-artifact-outside' });
121
+ }
122
+ if (entry.kind === 'directory') {
123
+ for (const child of await host.files.list(path))
124
+ await visit(host.paths.join(path, child.name));
125
+ return;
126
+ }
127
+ if (entry.kind !== 'file') {
128
+ throw new CapabilityError('Build output is not a regular file.', 'INVALID_INPUT', { reason: 'workspace-artifact-invalid' });
129
+ }
130
+ files.set(toPosixPath(host, host.paths.relative(root, path)), host.sha256().update(await readBytes(host.files, path)).digestHex());
131
+ };
132
+ for (const directory of input.directories)
133
+ await visit(host.paths.resolve(root, directory));
134
+ if (files.size === 0) {
135
+ throw new CapabilityError('The build emitted no certifiable artifact bytes.', 'CONFLICT', { reason: 'workspace-artifact-empty' });
136
+ }
137
+ for (const lock of input.lockFiles) {
138
+ const path = host.paths.resolve(root, lock);
139
+ if (await host.files.exists(path))
140
+ await visit(path);
141
+ }
142
+ const recorded = [...files].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([path, digest]) => ({ path, digest }));
143
+ const references = [...new Set(input.references ?? [])].sort();
144
+ const artifactDigest = host.sha256().update(JSON.stringify(references.length ? { files: recorded, references } : recorded)).digestHex();
145
+ return WorkspaceBuildArtifactReceiptSchema.parse({ compositionDigest: input.compositionDigest, sourceCommit: input.sourceCommit, artifactDigest, files: recorded, references });
146
+ }
147
+ /** Re-read the bytes at the provider boundary; no mtime, size, or source-stamp shortcut. */
148
+ export async function assertWorkspaceBuildArtifactReceipt(input, receipt) {
149
+ const admitted = WorkspaceBuildArtifactReceiptSchema.parse(receipt);
150
+ if (admitted.compositionDigest !== input.compositionDigest || admitted.sourceCommit !== input.sourceCommit) {
151
+ throw new CapabilityError('Build output belongs to another source or composition.', 'CONFLICT', { reason: 'workspace-artifact-identity-mismatch' });
152
+ }
153
+ const current = await sealWorkspaceBuildArtifacts(input);
154
+ if (current.artifactDigest !== admitted.artifactDigest || JSON.stringify(current.references) !== JSON.stringify([...new Set(admitted.references ?? [])].sort())) {
155
+ throw new CapabilityError('Build output changed before provider consumption.', 'CONFLICT', { reason: 'workspace-artifact-digest-mismatch' });
156
+ }
157
+ }
158
+ const CSS_IMPORT_RE = /@import\s+['"](@vibesdotdev\/[a-zA-Z0-9_./-]+)['"]/g;
159
+ const SOURCE_EXTENSIONS = new Set([
160
+ '.css',
161
+ '.cjs',
162
+ '.js',
163
+ '.json',
164
+ '.mjs',
165
+ '.svelte',
166
+ '.ts',
167
+ '.tsx'
168
+ ]);
169
+ const SKIP_DIRS = new Set([
170
+ '.git',
171
+ '.svelte-kit',
172
+ '.turbo',
173
+ '__stubs__',
174
+ '__tests__',
175
+ 'coverage',
176
+ 'dist',
177
+ 'node_modules',
178
+ 'test-results'
179
+ ]);
180
+ const WORKSPACE_DIAGNOSTIC_MAX_LINES = 40;
181
+ const WORKSPACE_DIAGNOSTIC_MAX_CHARS = 4000;
182
+ const WORKSPACE_DIAGNOSTIC_MAX_LINE_CHARS = 1000;
183
+ /** The ESC byte of an ANSI color sequence, built from its code point so the
184
+ * pattern carries no literal control byte (the sequence itself is the target). */
185
+ const ANSI_ESCAPE_START = String.fromCodePoint(27);
186
+ const ANSI_ESCAPE_RE = new RegExp(`${ANSI_ESCAPE_START}\\[[0-9;]*m`, "g");
187
+ const BEARER_RE = /\bBearer\s+[^\s,;]+/gi;
188
+ const SENSITIVE_ASSIGNMENT_RE = /\b([A-Z0-9_]*(?:TOKEN|SECRET|PASSWORD|CREDENTIAL|API_?KEY|PRIVATE_?KEY)[A-Z0-9_]*)\b\s*[:=]\s*["']?[^"',\s]+["']?/gi;
189
+ const SENSITIVE_QUERY_RE = /([?&](?:token|secret|password|api[_-]?key)=)[^&\s]+/gi;
190
+ const URL_PASSWORD_RE = /(https?:\/\/[^:\s/@]+:)[^@\s/]+@/gi;
191
+ /** True for the C0 control characters the sanitizer strips (tab, newline and
192
+ * carriage return are preserved as compiler output formatting). */
193
+ function isStrippedControlChar(code) {
194
+ return (code <= 31 && code !== 9 && code !== 10 && code !== 13) || code === 127;
195
+ }
196
+ export function sanitizeWorkspaceBuildDiagnostic(value) {
197
+ const stripped = Array.from(value)
198
+ .filter((ch) => !isStrippedControlChar(ch.codePointAt(0) ?? 0))
199
+ .join('');
200
+ return stripped
201
+ .replace(ANSI_ESCAPE_RE, '')
202
+ .replace(BEARER_RE, 'Bearer [redacted]')
203
+ .replace(SENSITIVE_ASSIGNMENT_RE, '$1=[redacted]')
204
+ .replace(SENSITIVE_QUERY_RE, '$1[redacted]')
205
+ .replace(URL_PASSWORD_RE, '$1[redacted]@');
206
+ }
207
+ function createWorkspaceDiagnosticTail() {
208
+ const entries = [];
209
+ let omitted = 0;
210
+ const renderedLength = () => entries.reduce((total, entry) => total + entry.line.length + entry.stream.length + 5, 0);
211
+ return {
212
+ push(stream, line) {
213
+ const sanitized = sanitizeWorkspaceBuildDiagnostic(line);
214
+ const bounded = sanitized.length <= WORKSPACE_DIAGNOSTIC_MAX_LINE_CHARS
215
+ ? sanitized
216
+ : `${sanitized.slice(0, WORKSPACE_DIAGNOSTIC_MAX_LINE_CHARS)}… [line truncated]`;
217
+ entries.push({ stream, line: bounded });
218
+ while (entries.length > WORKSPACE_DIAGNOSTIC_MAX_LINES ||
219
+ renderedLength() > WORKSPACE_DIAGNOSTIC_MAX_CHARS) {
220
+ entries.shift();
221
+ omitted += 1;
222
+ }
223
+ return bounded;
224
+ },
225
+ render() {
226
+ if (entries.length === 0)
227
+ return '[no compiler output captured]';
228
+ const prefix = omitted > 0 ? `[${omitted} earlier diagnostic line(s) truncated]\n` : '';
229
+ return `${prefix}${entries.map((entry) => `[${entry.stream}] ${entry.line}`).join('\n')}`;
230
+ }
231
+ };
232
+ }
233
+ /**
234
+ * App hosts ("app") and other never-published roots ("never-publish") are not
235
+ * package tiers, whatever their `private` flag says. Publish discovery skips
236
+ * them the same way; parsing them as publisher manifests refuses every deploy
237
+ * in a workspace that contains one (for example vessel-desktop, `private: false`).
238
+ */
239
+ const PrivateAppMemberSchema = z
240
+ .object({ vibes: z.object({ visibility: z.enum(['app', 'never-publish']) }).loose() })
241
+ .loose();
242
+ async function readJson(host, path) {
243
+ const read = await settle(async () => JSON.parse(await readText(host.files, path)));
244
+ if (!read.ok) {
245
+ // A missing manifest is a declared-absent input; any other read failure is real.
246
+ if (isMissingPathError(read.cause))
247
+ return undefined;
248
+ throw read.cause;
249
+ }
250
+ if (PrivateAppMemberSchema.safeParse(read.value).success)
251
+ return undefined;
252
+ return parsePublisherManifest(read.value);
253
+ }
254
+ /**
255
+ * What the deployed app's own manifest is read for: the workspace packages it
256
+ * declares. An app is never a publish manifest (`vibes.visibility: "app"`).
257
+ */
258
+ const AppDependencyManifestSchema = z.looseObject({
259
+ dependencies: z.record(z.string(), z.string()).optional(),
260
+ peerDependencies: z.record(z.string(), z.string()).optional(),
261
+ peerDependenciesMeta: z
262
+ .record(z.string(), z.object({ optional: z.boolean().optional() }).catchall(JsonValueSchema))
263
+ .optional()
264
+ });
265
+ async function readAppManifest(host, path) {
266
+ const read = await settle(async () => AppDependencyManifestSchema.parse(JSON.parse(await readText(host.files, path))));
267
+ if (read.ok)
268
+ return read.value;
269
+ // A missing manifest is a declared-absent input; any other read failure is real.
270
+ if (isMissingPathError(read.cause))
271
+ return undefined;
272
+ throw read.cause;
273
+ }
274
+ /** The errno facts a raw host absence carries. */
275
+ const ErrnoCodeSchema = z.object({ code: z.string().optional() }).loose();
276
+ function isMissingPathError(error) {
277
+ if (error instanceof CapabilityError && error.code === 'NOT_FOUND')
278
+ return true;
279
+ const facts = ErrnoCodeSchema.safeParse(error);
280
+ return facts.success && (facts.data.code === 'ENOENT' || facts.data.code === 'ENOTDIR');
281
+ }
282
+ /**
283
+ * A deploy root's declared `workspaces` is a string array or `{ packages: string[] }`.
284
+ * The kernel's listing reads any other shape as "no members" (kernel
285
+ * bootstrap/discovery.ts WorkspacesManifestSchema), so the deploy refuses it here
286
+ * rather than planning an empty closure.
287
+ */
288
+ const DeployRootWorkspacesSchema = z.looseObject({
289
+ workspaces: z.union([z.array(z.string()), z.looseObject({ packages: z.array(z.string()) })]).optional()
290
+ });
291
+ async function discoverWorkspacePackages(host, workspaceRoot) {
292
+ const packages = new Map();
293
+ const canonicalRoot = await realpathChecked(host.files, workspaceRoot);
294
+ const directories = new Set();
295
+ const rootManifest = await settle(async () => DeployRootWorkspacesSchema.parse(JSON.parse(await readText(host.files, host.paths.join(workspaceRoot, 'package.json')))));
296
+ if (!rootManifest.ok) {
297
+ throw new Error('Workspace root package.json must declare a string workspaces array');
298
+ }
299
+ // The kernel owns the workspace dialect (braces, `!` exclusions, `vibes.packageRoots`)
300
+ // and lists only declared members that exist, so a deploy from a partial checkout
301
+ // never fails on a declared path it does not hold.
302
+ for (const directory of await declaredPackageDirectories(host.runtime, workspaceRoot, undefined)) {
303
+ const canonicalDirectory = await realpathChecked(host.files, directory);
304
+ if (canonicalDirectory !== canonicalRoot &&
305
+ !canonicalDirectory.startsWith(`${canonicalRoot}${host.sep}`)) {
306
+ throw new Error(`Workspace package escapes the workspace root: ${directory}`);
307
+ }
308
+ // Overlapping declarations identify one member, not two.
309
+ if (directories.has(canonicalDirectory))
310
+ continue;
311
+ // A directory that matches a workspace glob but holds no manifest is not a
312
+ // workspace member — the package manager resolves membership the same way, so
313
+ // treating it as fatal makes the deploy disagree with the install that produced
314
+ // node_modules. It also makes the outcome depend on untracked local state: a
315
+ // folded package leaves `dist/` and `node_modules/` behind at its old path, and
316
+ // that residue alone would fail every deploy from an otherwise clean checkout.
317
+ // A manifest that exists but does not parse is still fatal below.
318
+ const manifestPath = host.paths.join(canonicalDirectory, 'package.json');
319
+ if (!(await host.files.exists(manifestPath))) {
320
+ continue;
321
+ }
322
+ directories.add(canonicalDirectory);
323
+ const rawManifestOutcome = await settle(async () => JSON.parse(await readText(host.files, manifestPath)));
324
+ if (!rawManifestOutcome.ok) {
325
+ throw new Error(`Invalid workspace package manifest at ${host.paths.relative(workspaceRoot, canonicalDirectory)}: ${failureMessage(rawManifestOutcome.cause)}`);
326
+ }
327
+ if (PrivateAppMemberSchema.safeParse(rawManifestOutcome.value).success) {
328
+ continue;
329
+ }
330
+ const manifestOutcome = await settle(async () => parsePublisherManifest(rawManifestOutcome.value));
331
+ if (!manifestOutcome.ok) {
332
+ throw new Error(`Invalid workspace package manifest at ${host.paths.relative(workspaceRoot, canonicalDirectory)}: ${failureMessage(manifestOutcome.cause)}`);
333
+ }
334
+ const packageJson = manifestOutcome.value;
335
+ if (!packageJson.name) {
336
+ throw new Error(`Workspace package manifest has no name: ${host.paths.relative(workspaceRoot, canonicalDirectory)}`);
337
+ }
338
+ if (packages.has(packageJson.name)) {
339
+ throw new Error(`Duplicate workspace package name: ${packageJson.name}`);
340
+ }
341
+ packages.set(packageJson.name, {
342
+ name: packageJson.name,
343
+ dir: canonicalDirectory,
344
+ packageJson
345
+ });
346
+ }
347
+ return packages;
348
+ }
349
+ async function resolveWorkspacePackages(host, workspaceRoot, packageScope) {
350
+ if (!packageScope)
351
+ return discoverWorkspacePackages(host, workspaceRoot);
352
+ const canonicalRoot = await realpathChecked(host.files, workspaceRoot);
353
+ const directories = new Set();
354
+ const scoped = new Map();
355
+ for (const [name, pkg] of packageScope) {
356
+ if (name !== pkg.name || (pkg.packageJson.name && pkg.packageJson.name !== name)) {
357
+ throw new Error(`Workspace package scope identity mismatch for ${name}`);
358
+ }
359
+ const canonicalDirectory = await realpathChecked(host.files, pkg.dir);
360
+ if (canonicalDirectory !== canonicalRoot &&
361
+ !canonicalDirectory.startsWith(`${canonicalRoot}${host.sep}`)) {
362
+ throw new Error(`Workspace package scope escapes the workspace root: ${pkg.dir}`);
363
+ }
364
+ if (directories.has(canonicalDirectory)) {
365
+ throw new Error(`Workspace package scope repeats directory ${canonicalDirectory}`);
366
+ }
367
+ directories.add(canonicalDirectory);
368
+ scoped.set(name, { ...pkg, dir: canonicalDirectory });
369
+ }
370
+ return scoped;
371
+ }
372
+ function hasBuildArtifacts(pkg) {
373
+ if (!pkg.packageJson.scripts?.build)
374
+ return false;
375
+ if (pkg.packageJson.vibes?.artifactsDir !== undefined)
376
+ return true;
377
+ return JSON.stringify({
378
+ main: pkg.packageJson.main,
379
+ types: pkg.packageJson.types,
380
+ svelte: pkg.packageJson.svelte,
381
+ exports: pkg.packageJson.exports
382
+ }).includes(resolveArtifactsDir(pkg));
383
+ }
384
+ /**
385
+ * `build` is a consumer-facing convenience script, not a contract that it
386
+ * builds ONLY the publishable artifact. `kit` (and other Svelte packages that
387
+ * ship both a library and a local preview/demo app) declare `build: "bun run
388
+ * package && bun run build:app"` — `build:app` is a full Vite/SvelteKit
389
+ * compile of the preview app, something no consumer resolving `kit`'s dist,
390
+ * and no publish of `kit` to the registry, ever needs. The `package` script
391
+ * (the `svelte-package`/`prepack` convention: producing exactly the files
392
+ * `main`/`exports`/`files` ship) is what a dependency-artifact build wants
393
+ * whenever a package declares one; `build` stays the fallback for every
394
+ * package that has not split the two.
395
+ */
396
+ function resolveBuildScriptName(pkg) {
397
+ return pkg.packageJson.scripts?.package ? 'package' : 'build';
398
+ }
399
+ /** Written into the artifacts directory only after a build exits 0. */
400
+ export const BUILD_STAMP_FILENAME = '.build-ok.json';
401
+ const TYPESCRIPT_BUILD_INFO_FILENAME = 'tsconfig.tsbuildinfo';
402
+ /** Toolchain packages whose declared versions the stamp records. */
403
+ const STAMPED_TOOL_PACKAGES = ['typescript', 'svelte', '@sveltejs/package', 'vite', 'esbuild', 'tsup'];
404
+ function toPosixPath(host, path) {
405
+ return host.sep === '/' ? path : path.split(host.sep).join('/');
406
+ }
407
+ /** Tool configuration a package's build reads from its root, beside its tsconfig files. */
408
+ const BUILD_CONFIG_FILE = /^(?:svelte|vite|tsup|esbuild|rollup|vitest)\.config\.[cm]?[jt]s$/;
409
+ const TSCONFIG_FILE = /^tsconfig(?:\.[^/]*)?\.json$/;
410
+ /** A path-looking word in a build script (`scripts/build.ts`, `./tsconfig.svelte.json`, `src/x/y.css`). */
411
+ const SCRIPT_FILE_TOKEN = /^(?:\.{1,2}\/)?[\w@][\w@.\-/]*\.(?:[cm]?[jt]sx?|json|css|scss|svg|md)$/;
412
+ /** Removes `//` and block comments from tsconfig-style JSON without touching string contents. */
413
+ function stripJsonComments(text) {
414
+ let out = '';
415
+ for (let index = 0; index < text.length; index += 1) {
416
+ const char = text[index];
417
+ if (char === '"') {
418
+ let end = index + 1;
419
+ while (end < text.length && text[end] !== '"')
420
+ end += text[end] === '\\' ? 2 : 1;
421
+ out += text.slice(index, end + 1);
422
+ index = end;
423
+ }
424
+ else if (char === '/' && text[index + 1] === '/') {
425
+ while (index < text.length && text[index] !== '\n')
426
+ index += 1;
427
+ out += '\n';
428
+ }
429
+ else if (char === '/' && text[index + 1] === '*') {
430
+ const end = text.indexOf('*/', index + 2);
431
+ index = end === -1 ? text.length : end + 1;
432
+ }
433
+ else {
434
+ out += char;
435
+ }
436
+ }
437
+ return out.replace(/,(\s*[}\]])/g, '$1');
438
+ }
439
+ /**
440
+ * Every file a tsconfig makes `tsc` read beyond the package's `src/`: the
441
+ * authored config, its relative `extends` chain, and the literal directories or
442
+ * files its `include`/`files` name. Generated build directories remain excluded:
443
+ * SvelteKit sync rewrites their metadata during the very build being stamped.
444
+ * A config that cannot be parsed contributes
445
+ * only itself: its bytes are still hashed, so any edit still invalidates.
446
+ */
447
+ async function collectTsconfigInputs(host, packageRoot, artifactsDir, configPath, inputs) {
448
+ const configTop = host.paths.relative(packageRoot, configPath).split(host.sep)[0];
449
+ if (configTop === artifactsDir || SKIP_DIRS.has(configTop))
450
+ return;
451
+ if (inputs.has(configPath) || !(await host.files.exists(configPath)))
452
+ return;
453
+ inputs.add(configPath);
454
+ const TsconfigFieldsSchema = z.object({
455
+ extends: z.union([z.string(), z.array(z.string())]).optional(),
456
+ include: z.array(z.string()).optional(),
457
+ files: z.array(z.string()).optional()
458
+ }).loose();
459
+ const parsed = await settle(async () => TsconfigFieldsSchema.parse(JSON.parse(stripJsonComments(await readText(host.files, configPath)))));
460
+ if (!parsed.ok) {
461
+ infraDeployLogger(host.runtime).warn(`tsconfig ${configPath} is not parseable JSON; only its own bytes are hashed`, {
462
+ error: failureMessage(parsed.cause)
463
+ });
464
+ return;
465
+ }
466
+ const config = parsed.value;
467
+ const parents = config.extends ? [config.extends].flat() : [];
468
+ for (const parent of parents) {
469
+ if (!parent.startsWith('.'))
470
+ continue;
471
+ const resolved = host.paths.join(host.paths.dirname(configPath), parent);
472
+ await collectTsconfigInputs(host, packageRoot, artifactsDir, resolved.endsWith('.json') ? resolved : `${resolved}.json`, inputs);
473
+ }
474
+ const named = [...(config.include ?? []), ...(config.files ?? [])];
475
+ for (const entry of named) {
476
+ const literal = [];
477
+ for (const segment of entry.split('/')) {
478
+ if (/[*?{[]/.test(segment))
479
+ break;
480
+ literal.push(segment);
481
+ }
482
+ const base = host.paths.join(host.paths.dirname(configPath), ...literal);
483
+ if (base === packageRoot || !isPathWithin(host, packageRoot, base))
484
+ continue;
485
+ const top = host.paths.relative(packageRoot, base).split(host.sep)[0];
486
+ if (top === artifactsDir || SKIP_DIRS.has(top))
487
+ continue;
488
+ if (!(await host.files.exists(base)))
489
+ continue;
490
+ if ((await followedStat(host, base)).kind === 'directory') {
491
+ for (const path of await filesInDirectory(host, base, isBuildInput))
492
+ inputs.add(path);
493
+ }
494
+ else {
495
+ inputs.add(base);
496
+ }
497
+ }
498
+ }
499
+ /**
500
+ * Files the package's own build reads: its manifest,
501
+ * every `tsconfig*.json` (and their `extends`/`include` targets), tool config
502
+ * files (`vite.config.*`, `svelte.config.*`, ...), `scripts/`, every file the
503
+ * selected build script names, and every non-test, non-hidden file under
504
+ * `src/`. Workspace dependencies are folded in by {@link effectiveSourceHash}.
505
+ */
506
+ async function packageBuildInputs(host, pkg) {
507
+ const packageRoot = pkg.dir;
508
+ const artifactsDir = resolveArtifactsDir(pkg);
509
+ const inputs = new Set(await filesInDirectory(host, host.paths.join(packageRoot, 'src'), isBuildInput));
510
+ for (const path of await filesInDirectory(host, host.paths.join(packageRoot, 'scripts'), isBuildInput))
511
+ inputs.add(path);
512
+ for (const entry of await host.files.list(packageRoot)) {
513
+ if (entry.kind !== 'file')
514
+ continue;
515
+ if (entry.name === 'package.json' || BUILD_CONFIG_FILE.test(entry.name)) {
516
+ inputs.add(host.paths.join(packageRoot, entry.name));
517
+ }
518
+ if (TSCONFIG_FILE.test(entry.name)) {
519
+ await collectTsconfigInputs(host, packageRoot, artifactsDir, host.paths.join(packageRoot, entry.name), inputs);
520
+ }
521
+ }
522
+ const buildScript = pkg.packageJson.scripts?.[resolveBuildScriptName(pkg)] ?? '';
523
+ for (const token of buildScript.split(/[\s"'`=;&|()]+/)) {
524
+ if (!SCRIPT_FILE_TOKEN.test(token))
525
+ continue;
526
+ const path = host.paths.join(packageRoot, token);
527
+ const top = host.paths.relative(packageRoot, path).split(host.sep)[0];
528
+ if (top === artifactsDir || top === 'node_modules' || !isPathWithin(host, packageRoot, path))
529
+ continue;
530
+ if ((await host.files.exists(path)) && (await followedStat(host, path)).kind === 'file')
531
+ inputs.add(path);
532
+ if (TSCONFIG_FILE.test(token.split('/').pop() ?? '')) {
533
+ await collectTsconfigInputs(host, packageRoot, artifactsDir, path, inputs);
534
+ }
535
+ }
536
+ return inputs;
537
+ }
538
+ async function computePackageSourceHash(host, packageRoot) {
539
+ const hash = host.sha256();
540
+ const pkg = await readPackageManifest(host, packageRoot);
541
+ const entries = [...await packageBuildInputs(host, pkg)]
542
+ .map((path) => ({ path: toPosixPath(host, host.paths.relative(packageRoot, path)), absolute: path }))
543
+ .sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));
544
+ for (const entry of entries) {
545
+ const fileHash = host.sha256().update(await readBytes(host.files, entry.absolute)).digestHex();
546
+ hash.update(`${entry.path}\0${fileHash}\n`);
547
+ }
548
+ return hash.digestHex();
549
+ }
550
+ /** One memo for the build inputs and hashes read in a plan or independent postflight. */
551
+ const effectiveHashMemos = new WeakMap();
552
+ function dependencyHashMemo(ownHashes) {
553
+ let memo = effectiveHashMemos.get(ownHashes);
554
+ if (!memo) {
555
+ memo = { effective: new Map(), edges: new Map() };
556
+ effectiveHashMemos.set(ownHashes, memo);
557
+ }
558
+ return memo;
559
+ }
560
+ function buildDependencyNames(host, pkg, packages, memo) {
561
+ let pending = memo.edges.get(pkg.name);
562
+ if (!pending) {
563
+ pending = workspaceDependencyEdges(host, pkg, packages)
564
+ .then(({ inputs }) => inputs.filter((name) => packages.has(name)));
565
+ memo.edges.set(pkg.name, pending);
566
+ }
567
+ return pending;
568
+ }
569
+ /**
570
+ * A package's own source hash folded with its workspace dependencies'
571
+ * effective hashes, computed once per package in linear time.
572
+ *
573
+ * Packages that import each other (a tolerated mutual-import cycle) form a
574
+ * strongly connected component; every member's hash covers the whole
575
+ * component and everything it depends on, so the result does not depend on
576
+ * which package the walk started from. A package outside any cycle hashes
577
+ * exactly as it always has: its own hash, then `\0name\0effective` for each
578
+ * declared dependency in order.
579
+ */
580
+ async function effectiveSourceHash(host, pkg, packages, ownHashes) {
581
+ const scope = dependencyHashMemo(ownHashes);
582
+ const memo = scope.effective;
583
+ const known = memo.get(pkg.name);
584
+ if (known !== undefined)
585
+ return known;
586
+ // Hash the planner's build inputs. Imported optional peers participate in
587
+ // freshness without becoming required members of the build closure.
588
+ const graph = new Map();
589
+ const pending = [pkg.name];
590
+ const queued = new Set(pending);
591
+ for (let cursor = 0; cursor < pending.length; cursor += 1) {
592
+ const name = pending[cursor];
593
+ if (memo.has(name))
594
+ continue;
595
+ const dependencies = await buildDependencyNames(host, packages.get(name), packages, scope);
596
+ graph.set(name, dependencies);
597
+ for (const dependency of dependencies) {
598
+ if (memo.has(dependency) || queued.has(dependency))
599
+ continue;
600
+ queued.add(dependency);
601
+ pending.push(dependency);
602
+ }
603
+ }
604
+ // Another concurrent writer may have completed this component during I/O.
605
+ const completed = memo.get(pkg.name);
606
+ if (completed !== undefined)
607
+ return completed;
608
+ const edges = (name) => graph.get(name) ?? [];
609
+ // Tarjan's SCC over the packages reachable from `pkg` that are not yet
610
+ // memoized; components come out dependencies-first.
611
+ const index = new Map();
612
+ const low = new Map();
613
+ const onStack = new Set();
614
+ const stack = [];
615
+ const components = [];
616
+ let counter = 0;
617
+ const connect = (name) => {
618
+ index.set(name, counter);
619
+ low.set(name, counter);
620
+ counter += 1;
621
+ stack.push(name);
622
+ onStack.add(name);
623
+ for (const dep of edges(name)) {
624
+ if (memo.has(dep))
625
+ continue;
626
+ if (!index.has(dep)) {
627
+ connect(dep);
628
+ low.set(name, Math.min(low.get(name), low.get(dep)));
629
+ }
630
+ else if (onStack.has(dep)) {
631
+ low.set(name, Math.min(low.get(name), index.get(dep)));
632
+ }
633
+ }
634
+ if (low.get(name) === index.get(name)) {
635
+ const component = [];
636
+ let member;
637
+ do {
638
+ member = stack.pop();
639
+ onStack.delete(member);
640
+ component.push(member);
641
+ } while (member !== name);
642
+ components.push(component);
643
+ }
644
+ };
645
+ connect(pkg.name);
646
+ const ownOf = async (name) => {
647
+ let own = ownHashes.get(name);
648
+ if (own === undefined) {
649
+ own = await computePackageSourceHash(host, packages.get(name).dir);
650
+ ownHashes.set(name, own);
651
+ }
652
+ return own;
653
+ };
654
+ for (const component of components) {
655
+ const members = new Set(component);
656
+ const selfLoop = component.length === 1 && edges(component[0]).includes(component[0]);
657
+ if (component.length === 1 && !selfLoop) {
658
+ const name = component[0];
659
+ const hash = host.sha256().update(await ownOf(name));
660
+ for (const dep of edges(name))
661
+ hash.update(`\0${dep}\0${memo.get(dep)}`);
662
+ memo.set(name, hash.digestHex());
663
+ continue;
664
+ }
665
+ // One hash for the whole component: every member's own hash and every
666
+ // dependency the component reaches outside itself, in a fixed order.
667
+ const componentHash = host.sha256().update('scc');
668
+ for (const name of [...component].sort())
669
+ componentHash.update(`\0${name}\0${await ownOf(name)}`);
670
+ const external = new Set();
671
+ for (const name of component)
672
+ for (const dep of edges(name))
673
+ if (!members.has(dep))
674
+ external.add(dep);
675
+ for (const dep of [...external].sort())
676
+ componentHash.update(`\0dep\0${dep}\0${memo.get(dep)}`);
677
+ const shared = componentHash.digestHex();
678
+ // Publish the whole component without yielding: concurrent walks must
679
+ // never observe only part of a cycle as memoized.
680
+ for (const name of component) {
681
+ memo.set(name, host.sha256().update(ownHashes.get(name)).update(`\0scc\0${shared}`).digestHex());
682
+ }
683
+ }
684
+ return memo.get(pkg.name);
685
+ }
686
+ /** What a stamp records about a package's workspace dependencies: name -> effective source hash. */
687
+ const RecordedDependencyHashesSchema = z.record(z.string(), z.string());
688
+ async function workspaceDependencyHashes(host, pkg, packages, ownHashes) {
689
+ const recorded = {};
690
+ if (!packages)
691
+ return recorded;
692
+ for (const name of await buildDependencyNames(host, pkg, packages, dependencyHashMemo(ownHashes))) {
693
+ const dependency = packages.get(name);
694
+ if (!dependency)
695
+ continue;
696
+ recorded[name] = await effectiveSourceHash(host, dependency, packages, ownHashes);
697
+ }
698
+ return recorded;
699
+ }
700
+ /** Every file the build emitted under the artifacts directory (the stamp itself excluded). */
701
+ async function listEmittedFiles(host, artifactsDirectory) {
702
+ const files = [];
703
+ const visit = async (directory) => {
704
+ for (const entry of await host.files.list(directory)) {
705
+ const entryPath = host.paths.join(directory, entry.name);
706
+ if (entry.kind === 'directory') {
707
+ await visit(entryPath);
708
+ continue;
709
+ }
710
+ const relativePath = toPosixPath(host, host.paths.relative(artifactsDirectory, entryPath));
711
+ if (relativePath === BUILD_STAMP_FILENAME)
712
+ continue;
713
+ const stats = await followedStat(host, entryPath);
714
+ if (stats.kind === 'file')
715
+ files.push({ path: relativePath, size: stats.size });
716
+ }
717
+ };
718
+ if (await host.files.exists(artifactsDirectory))
719
+ await visit(artifactsDirectory);
720
+ return files.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));
721
+ }
722
+ /** Declared versions of the toolchain packages a stamp records. */
723
+ const StampedToolVersionsSchema = z.record(z.string(), z.string());
724
+ function declaredToolVersions(packageJson) {
725
+ const versions = {};
726
+ for (const name of STAMPED_TOOL_PACKAGES) {
727
+ const declared = packageJson.devDependencies?.[name] ??
728
+ packageJson.dependencies?.[name] ??
729
+ packageJson.peerDependencies?.[name];
730
+ if (declared)
731
+ versions[name] = declared;
732
+ }
733
+ return versions;
734
+ }
735
+ async function readPackageManifest(host, packageDir) {
736
+ const packageJson = await readJson(host, host.paths.join(packageDir, 'package.json'));
737
+ if (!packageJson)
738
+ throw new Error(`Package has no manifest: ${packageDir}`);
739
+ return { name: packageJson.name ?? packageDir, dir: packageDir, packageJson };
740
+ }
741
+ /** Removes the build-success stamp, so an interrupted or failed build can never look fresh. */
742
+ async function removeBuildStamp(host, pkg) {
743
+ await removeIfPresent(host.files, host.paths.join(pkg.dir, resolveArtifactsDir(pkg), BUILD_STAMP_FILENAME));
744
+ }
745
+ /**
746
+ * Records a successful build: the source content hash it was built from and the
747
+ * exact files it emitted. Callers write it only after the build exited 0.
748
+ */
749
+ export async function writeBuildOkStamp(packageDir,
750
+ /** The runtime whose logger reports a build input the hash could only read as bytes. */
751
+ runtime, packages, dependencySourceHashes = new Map()) {
752
+ const host = await resolveArtifactHost(runtime);
753
+ const pkg = await readPackageManifest(host, packageDir);
754
+ const artifactsDirectory = host.paths.join(pkg.dir, resolveArtifactsDir(pkg));
755
+ const stamp = {
756
+ sourceHash: await computePackageSourceHash(host, pkg.dir),
757
+ dependencies: await workspaceDependencyHashes(host, pkg, packages, dependencySourceHashes),
758
+ toolVersions: declaredToolVersions(pkg.packageJson),
759
+ files: await listEmittedFiles(host, artifactsDirectory)
760
+ };
761
+ // A build that exited 0 but emitted nothing (an honest outcome the freshness
762
+ // check reports as "no artifacts") still earns its stamp: recording it must
763
+ // not crash on the absent directory and mask the build's real result.
764
+ await host.files.mkdir(artifactsDirectory, { recursive: true });
765
+ await host.files.writeFile(host.paths.join(artifactsDirectory, BUILD_STAMP_FILENAME), `${JSON.stringify(stamp, null, '\t')}\n`);
766
+ return stamp;
767
+ }
768
+ /** The admitted shape of a build stamp, parsed once at the boundary. */
769
+ const BuildStampSchema = z.object({
770
+ sourceHash: z.string(),
771
+ dependencies: z.record(z.string(), z.string()),
772
+ toolVersions: z.record(z.string(), z.string()),
773
+ files: z.array(z.object({ path: z.string(), size: z.number() }).loose())
774
+ }).loose();
775
+ function parseBuildStamp(text) {
776
+ const parsed = BuildStampSchema.safeParse(JSON.parse(text));
777
+ if (parsed.success) {
778
+ // The schema admits extra keys from older and newer writers; the stamp
779
+ // is the four typed fields, constructed explicitly instead of cast.
780
+ const { sourceHash, dependencies, toolVersions, files } = parsed.data;
781
+ return {
782
+ sourceHash,
783
+ dependencies,
784
+ toolVersions,
785
+ files: files.map((file) => ({ path: file.path, size: file.size }))
786
+ };
787
+ }
788
+ // An unparseable or malformed stamp is an invalid stamp: the caller reports
789
+ // it as not fresh.
790
+ return undefined;
791
+ }
792
+ /**
793
+ * The single freshness decision every caller shares: `assertDeployWorkspacePreflight`
794
+ * uses it to refuse a deploy over stale inputs, and the build orchestration
795
+ * below uses the same predicate to skip a closure member that never went
796
+ * stale. Fresh means a build-success stamp exists, its source hash equals the
797
+ * hash of the package's current build inputs, and every file it lists still
798
+ * exists at the recorded size. There is no timestamp heuristic: a package with
799
+ * no stamp (never built, failed build, interrupted build) is not fresh.
800
+ */
801
+ async function checkWorkspacePackageFreshness(host, pkg, packages, ownHashes = new Map()) {
802
+ const resolvedPackageRoot = await realpathChecked(host.files, pkg.dir);
803
+ const artifactsDir = resolveArtifactsDir(pkg);
804
+ const artifactsDirectory = host.paths.join(resolvedPackageRoot, artifactsDir);
805
+ const result = (reason, artifactsMissing = false) => ({
806
+ fresh: reason === undefined,
807
+ artifactsDir,
808
+ resolvedPackageRoot,
809
+ reason,
810
+ artifactsMissing
811
+ });
812
+ const artifactNames = (await host.files.exists(artifactsDirectory))
813
+ ? (await host.files.list(artifactsDirectory)).map((entry) => entry.name)
814
+ : [];
815
+ if (artifactNames.every((name) => name === BUILD_STAMP_FILENAME)) {
816
+ return result(`${artifactsDir} has no artifacts`, true);
817
+ }
818
+ const stampPath = host.paths.join(artifactsDirectory, BUILD_STAMP_FILENAME);
819
+ if (!(await host.files.exists(stampPath))) {
820
+ return result(`${artifactsDir}/${BUILD_STAMP_FILENAME} is missing, so no successful build is recorded`);
821
+ }
822
+ const stamp = parseBuildStamp(await readText(host.files, stampPath));
823
+ if (!stamp)
824
+ return result(`${artifactsDir}/${BUILD_STAMP_FILENAME} is not a valid build stamp`);
825
+ if (stamp.files.length === 0)
826
+ return result(`${artifactsDir}/${BUILD_STAMP_FILENAME} lists no emitted files`);
827
+ if (stamp.sourceHash !== (await computePackageSourceHash(host, resolvedPackageRoot))) {
828
+ return result(`package sources changed since the last successful build`);
829
+ }
830
+ const currentDependencies = await workspaceDependencyHashes(host, pkg, packages, ownHashes);
831
+ const dependencyNames = new Set([...Object.keys(stamp.dependencies), ...Object.keys(currentDependencies)]);
832
+ for (const name of [...dependencyNames].sort()) {
833
+ if (stamp.dependencies[name] !== currentDependencies[name]) {
834
+ return result(`workspace dependency ${name} changed since the last successful build`);
835
+ }
836
+ }
837
+ for (const file of stamp.files) {
838
+ const path = host.paths.join(artifactsDirectory, file.path);
839
+ if (!isPathWithin(host, artifactsDirectory, path)) {
840
+ return result(`${artifactsDir}/${BUILD_STAMP_FILENAME} lists a path outside ${artifactsDir}: ${file.path}`);
841
+ }
842
+ const stats = await settle(() => followedStat(host, path));
843
+ if (!stats.ok) {
844
+ // An emitted file that vanished is not fresh; any other stat failure is real.
845
+ if (isMissingPathError(stats.cause))
846
+ return result(`emitted file is missing: ${artifactsDir}/${file.path}`);
847
+ throw stats.cause;
848
+ }
849
+ if (stats.value.kind !== 'file')
850
+ return result(`emitted file is not a regular file: ${artifactsDir}/${file.path}`);
851
+ const size = stats.value.size;
852
+ if (size !== file.size) {
853
+ return result(`emitted file changed size (${file.size} -> ${size}): ${artifactsDir}/${file.path}`);
854
+ }
855
+ }
856
+ const buildInfoReason = await typeScriptBuildInfoRefusal(host, host.paths.join(artifactsDirectory, TYPESCRIPT_BUILD_INFO_FILENAME));
857
+ if (buildInfoReason)
858
+ return result(buildInfoReason);
859
+ return result(undefined);
860
+ }
861
+ /**
862
+ * A stamped build whose incremental state still records pending emit or
863
+ * diagnostics is not a clean build, whatever the stamp says.
864
+ */
865
+ async function typeScriptBuildInfoRefusal(host, tsBuildInfoPath) {
866
+ if (!(await host.files.exists(tsBuildInfoPath)))
867
+ return undefined;
868
+ const TsBuildInfoSchema = z.object({
869
+ errors: z.boolean().optional(),
870
+ affectedFilesPendingEmit: z.array(z.unknown()).optional(),
871
+ semanticDiagnosticsPerFile: z.array(z.unknown()).optional()
872
+ }).loose();
873
+ const buildInfo = TsBuildInfoSchema.safeParse(JSON.parse(await readText(host.files, tsBuildInfoPath)));
874
+ if (!buildInfo.success) {
875
+ // An unreadable incremental state cannot vouch for the build.
876
+ return `${TYPESCRIPT_BUILD_INFO_FILENAME} is not valid JSON`;
877
+ }
878
+ if (buildInfo.data.errors === true)
879
+ return `${TYPESCRIPT_BUILD_INFO_FILENAME} records compile errors`;
880
+ if (Array.isArray(buildInfo.data.affectedFilesPendingEmit) && buildInfo.data.affectedFilesPendingEmit.length > 0) {
881
+ return `${TYPESCRIPT_BUILD_INFO_FILENAME} records files pending emit`;
882
+ }
883
+ // tsc lists a bare file id for a clean file and `[id, diagnostics]` for one with errors.
884
+ if (Array.isArray(buildInfo.data.semanticDiagnosticsPerFile) &&
885
+ buildInfo.data.semanticDiagnosticsPerFile.some((entry) => Array.isArray(entry))) {
886
+ return `${TYPESCRIPT_BUILD_INFO_FILENAME} records semantic diagnostics`;
887
+ }
888
+ return undefined;
889
+ }
890
+ async function buildPackage(host, workspaceRoot, pkg, execution, packages, dependencySourceHashes, onLine) {
891
+ const scriptName = resolveBuildScriptName(pkg);
892
+ onLine?.('stdout', `[workspace-artifacts] building ${pkg.name}`);
893
+ const diagnostics = createWorkspaceDiagnosticTail();
894
+ // A prior stamp must never outlive the start of a rebuild: only a build that
895
+ // exits 0 writes one, so an interrupted build reads as not fresh.
896
+ await removeBuildStamp(host, pkg);
897
+ let result;
898
+ try {
899
+ result = await runRuntimeCommand({
900
+ runtime: host.runtime,
901
+ execution,
902
+ command: 'bun',
903
+ killTree: true,
904
+ args: ['run', '--cwd', pkg.dir, scriptName],
905
+ cwd: workspaceRoot,
906
+ env: await registryTokenEnv(host.runtime),
907
+ onLine: (stream, line) => {
908
+ const sanitized = diagnostics.push(stream, line);
909
+ onLine?.(stream, sanitized);
910
+ }
911
+ });
912
+ }
913
+ catch (error) {
914
+ await invalidateFailedBuild(host, pkg);
915
+ throw error;
916
+ }
917
+ if (result.code !== 0) {
918
+ await invalidateFailedBuild(host, pkg);
919
+ throw new Error(`Workspace artifact build failed for ${pkg.name} (exit=${result.code ?? 'unknown'})\n` +
920
+ `Compiler diagnostics (redacted tail):\n${diagnostics.render()}`);
921
+ }
922
+ await writeBuildOkStamp(pkg.dir, host.runtime, packages, dependencySourceHashes);
923
+ }
924
+ /** A failed build leaves neither its stamp nor its incremental state, so the next run rebuilds from scratch. */
925
+ async function invalidateFailedBuild(host, pkg) {
926
+ const artifactsDirectory = host.paths.join(pkg.dir, resolveArtifactsDir(pkg));
927
+ await removeIfPresent(host.files, host.paths.join(artifactsDirectory, BUILD_STAMP_FILENAME));
928
+ await removeIfPresent(host.files, host.paths.join(artifactsDirectory, TYPESCRIPT_BUILD_INFO_FILENAME));
929
+ }
930
+ /**
931
+ * Builds `plan` with up to `concurrency` packages compiling at once.
932
+ * Independent branches of the dependency graph (declared or source-discovered
933
+ * edges, the same edge set the planner used) run concurrently; a mutual-import
934
+ * cycle — the class `orderCycleMembersByWorkspaceDependencies` already
935
+ * resolves into one contiguous, order-sensitive run — still builds its
936
+ * members serially, in the plan's existing order, so a tolerated cycle's
937
+ * behaviour is unchanged. `run` decides per package whether to actually spawn
938
+ * a build (it applies the freshness skip); this function only owns the safe
939
+ * scheduling.
940
+ */
941
+ async function runWorkspaceBuildPlan(host, plan, packages, concurrency, run) {
942
+ if (plan.length === 0)
943
+ return;
944
+ const dependencyCache = new Map();
945
+ for (const pkg of plan) {
946
+ dependencyCache.set(pkg.name, await workspaceDependencyEdges(host, pkg, packages));
947
+ }
948
+ const dependenciesOf = (pkg) => {
949
+ const deps = dependencyCache.get(pkg.name);
950
+ if (!deps) {
951
+ throw new Error(`Workspace dependency edges were not loaded for ${pkg.name}`);
952
+ }
953
+ return deps;
954
+ };
955
+ const components = groupWorkspaceBuildPlanIntoComponents(plan, dependenciesOf);
956
+ const remaining = components.map((component) => new Set(component.dependsOn));
957
+ const waiters = components.map(() => []);
958
+ remaining.forEach((deps, index) => {
959
+ for (const dep of deps)
960
+ waiters[dep].push(index);
961
+ });
962
+ await new Promise((resolveAll, rejectAll) => {
963
+ let settled = false;
964
+ let active = 0;
965
+ let completed = 0;
966
+ const queue = components.map((_, index) => index).filter((index) => remaining[index].size === 0);
967
+ let cursor = 0;
968
+ const fail = (failure) => {
969
+ if (settled)
970
+ return;
971
+ settled = true;
972
+ // The caught failure travels whole into the combined rejection.
973
+ rejectAll(failure);
974
+ };
975
+ // One component's build: outcome-based, so a failure travels whole into the
976
+ // combined rejection and completion always advances the scheduler.
977
+ const runComponent = async (index) => {
978
+ const outcome = await settle(async () => {
979
+ for (const pkg of components[index].members)
980
+ await run(pkg);
981
+ });
982
+ if (!outcome.ok)
983
+ fail(outcome.cause);
984
+ active -= 1;
985
+ completed += 1;
986
+ for (const waiter of waiters[index]) {
987
+ remaining[waiter].delete(index);
988
+ if (remaining[waiter].size === 0)
989
+ queue.push(waiter);
990
+ }
991
+ if (completed === components.length) {
992
+ if (!settled) {
993
+ settled = true;
994
+ resolveAll();
995
+ }
996
+ return;
997
+ }
998
+ pump();
999
+ };
1000
+ const pump = () => {
1001
+ if (settled)
1002
+ return;
1003
+ while (active < concurrency && cursor < queue.length) {
1004
+ const index = queue[cursor];
1005
+ cursor += 1;
1006
+ active += 1;
1007
+ void runComponent(index);
1008
+ }
1009
+ };
1010
+ pump();
1011
+ });
1012
+ }
1013
+ /**
1014
+ * Groups `plan` into its dependency components on the SAME `.all` edge set
1015
+ * the planner used: a lone acyclic package is its own single-member
1016
+ * component, and a mutual-import cycle collapses into one multi-member
1017
+ * component (mirroring `findStronglyConnectedComponents`'s use inside
1018
+ * `orderCycleMembersByWorkspaceDependencies`). Two components with no path
1019
+ * between them can build at the same time.
1020
+ */
1021
+ function groupWorkspaceBuildPlanIntoComponents(plan, dependenciesOf) {
1022
+ const planNames = new Set(plan.map((pkg) => pkg.name));
1023
+ const allEdges = new Map();
1024
+ for (const pkg of plan) {
1025
+ allEdges.set(pkg.name, dependenciesOf(pkg).all.filter((name) => planNames.has(name)));
1026
+ }
1027
+ const componentByName = findStronglyConnectedComponents(plan.map((pkg) => pkg.name), allEdges);
1028
+ const componentOrder = [];
1029
+ const seen = new Set();
1030
+ const membersByComponent = new Map();
1031
+ for (const pkg of plan) {
1032
+ const component = componentByName.get(pkg.name);
1033
+ if (component === undefined)
1034
+ continue;
1035
+ if (!seen.has(component)) {
1036
+ seen.add(component);
1037
+ componentOrder.push(component);
1038
+ }
1039
+ const members = membersByComponent.get(component) ?? [];
1040
+ members.push(pkg);
1041
+ membersByComponent.set(component, members);
1042
+ }
1043
+ const dependsOnByComponent = new Map();
1044
+ for (const component of componentOrder)
1045
+ dependsOnByComponent.set(component, new Set());
1046
+ for (const [name, deps] of allEdges) {
1047
+ const component = componentByName.get(name);
1048
+ if (component === undefined)
1049
+ continue;
1050
+ for (const dep of deps) {
1051
+ const depComponent = componentByName.get(dep);
1052
+ if (depComponent === undefined || depComponent === component)
1053
+ continue;
1054
+ dependsOnByComponent.get(component)?.add(depComponent);
1055
+ }
1056
+ }
1057
+ return componentOrder.map((component) => ({
1058
+ members: membersByComponent.get(component) ?? [],
1059
+ dependsOn: dependsOnByComponent.get(component) ?? new Set()
1060
+ }));
1061
+ }
1062
+ /** Independent workspace package builds run this many at a time (see `runWorkspaceBuildPlan`). */
1063
+ const DEFAULT_WORKSPACE_BUILD_CONCURRENCY = 4;
1064
+ async function buildWorkspacePlanWithFreshnessSkip(host, workspaceRoot, plan, packages, execution, onLine) {
1065
+ // Source hashes do not change while a plan builds (builds emit only into artifact directories).
1066
+ const ownHashes = new Map();
1067
+ await runWorkspaceBuildPlan(host, plan, packages, DEFAULT_WORKSPACE_BUILD_CONCURRENCY, async (pkg) => {
1068
+ const freshness = await checkWorkspacePackageFreshness(host, pkg, packages, ownHashes);
1069
+ if (freshness.fresh) {
1070
+ onLine?.('stdout', `[workspace-artifacts] skip ${pkg.name}: ${freshness.artifactsDir} is already fresh`);
1071
+ return;
1072
+ }
1073
+ await buildPackage(host, workspaceRoot, pkg, execution, packages, ownHashes, onLine);
1074
+ });
1075
+ }
1076
+ async function discoverSvelteKitApps(host, workspaceRoot) {
1077
+ const appsRoot = host.paths.join(workspaceRoot, 'apps');
1078
+ if (!(await host.files.exists(appsRoot)))
1079
+ return [];
1080
+ const apps = [];
1081
+ for (const entry of await host.files.list(appsRoot)) {
1082
+ if (entry.kind !== 'directory')
1083
+ continue;
1084
+ const dir = host.paths.join(appsRoot, entry.name);
1085
+ const hasJs = await host.files.exists(host.paths.join(dir, 'svelte.config.js'));
1086
+ const hasTs = await host.files.exists(host.paths.join(dir, 'svelte.config.ts'));
1087
+ if (!hasJs && !hasTs)
1088
+ continue;
1089
+ apps.push({ name: `apps/${entry.name}`, dir });
1090
+ }
1091
+ return apps.sort((a, b) => a.name.localeCompare(b.name));
1092
+ }
1093
+ async function needsSvelteKitSync(host, app) {
1094
+ return !(await host.files.exists(host.paths.join(app.dir, '.svelte-kit', 'tsconfig.json')));
1095
+ }
1096
+ async function syncSvelteKitApp(host, workspaceRoot, app, execution, onLine) {
1097
+ onLine?.('stdout', `[svelte-kit-sync] syncing ${app.name}`);
1098
+ const result = await runRuntimeCommand({
1099
+ runtime: host.runtime,
1100
+ execution,
1101
+ command: 'bun',
1102
+ args: ['--bun', 'svelte-kit', 'sync'],
1103
+ cwd: app.dir,
1104
+ env: await registryTokenEnv(host.runtime),
1105
+ onLine
1106
+ });
1107
+ if (result.code !== 0) {
1108
+ throw new Error(`SvelteKit metadata sync failed for ${app.name} (exit=${result.code ?? 'unknown'})`);
1109
+ }
1110
+ const syncedConfig = host.paths.join(app.dir, '.svelte-kit', 'tsconfig.json');
1111
+ if (!(await host.files.exists(syncedConfig))) {
1112
+ throw new Error(`SvelteKit metadata sync did not produce ${host.paths.relative(workspaceRoot, syncedConfig)}`);
1113
+ }
1114
+ }
1115
+ async function syncMissingSvelteKitMetadataForWorkspace(host, workspaceRoot, appDir, execution, onLine) {
1116
+ const apps = await discoverSvelteKitApps(host, workspaceRoot);
1117
+ const targetFirst = apps.sort((a, b) => {
1118
+ if (a.dir === appDir)
1119
+ return -1;
1120
+ if (b.dir === appDir)
1121
+ return 1;
1122
+ return a.name.localeCompare(b.name);
1123
+ });
1124
+ const missing = [];
1125
+ for (const app of targetFirst) {
1126
+ if (await needsSvelteKitSync(host, app))
1127
+ missing.push(app);
1128
+ }
1129
+ if (missing.length === 0)
1130
+ return;
1131
+ onLine?.('stdout', `[svelte-kit-sync] preparing generated metadata for ${missing.length} SvelteKit app(s)`);
1132
+ for (const app of missing) {
1133
+ await syncSvelteKitApp(host, workspaceRoot, app, execution, onLine);
1134
+ }
1135
+ onLine?.('stdout', `[svelte-kit-sync] metadata ready for ${missing.length} SvelteKit app(s)`);
1136
+ }
1137
+ /**
1138
+ * Workspace dependency edges for a package: the union of declared
1139
+ * `dependencies` + `peerDependencies` (the *-svelte packages declare their
1140
+ * core package as a peer dependency, so `dependencies` alone misses e.g.
1141
+ * account-svelte -> @vibesdotdev/account) and the package's own source
1142
+ * imports (catches undeclared imports such as chat-svelte importing
1143
+ * `@vibesdotdev/chat/client`).
1144
+ */
1145
+ function selectorResolvesWorkspacePackage(pkg, selector) {
1146
+ if (selector.startsWith('workspace:'))
1147
+ return true;
1148
+ if (!pkg.packageJson.version)
1149
+ return true;
1150
+ return Boolean(validRange(selector) && satisfies(pkg.packageJson.version, selector));
1151
+ }
1152
+ /** Build scripts/configuration may use development dependencies; public entry points may not. */
1153
+ function isBuildOnlyImportSource(host, pkg, path) {
1154
+ const relative = toPosixPath(host, host.paths.relative(pkg.dir, path));
1155
+ const buildOnly = relative.startsWith('scripts/') || BUILD_CONFIG_FILE.test(relative);
1156
+ if (!buildOnly)
1157
+ return false;
1158
+ const entryPoints = [pkg.packageJson.main, pkg.packageJson.types, pkg.packageJson.svelte, pkg.packageJson.bin, pkg.packageJson.exports];
1159
+ const namesPath = (value) => {
1160
+ const targetPath = z.string().safeParse(value);
1161
+ if (targetPath.success) {
1162
+ const target = targetPath.data.replace(/^\.\//, '');
1163
+ const pattern = target.split('*').map((part) => part.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('.*');
1164
+ return new RegExp('^' + pattern + '$').test(relative);
1165
+ }
1166
+ const alternatives = z.array(JsonValueSchema).safeParse(value);
1167
+ if (alternatives.success)
1168
+ return alternatives.data.some(namesPath);
1169
+ const conditions = z.record(z.string(), JsonValueSchema).safeParse(value);
1170
+ return conditions.success && Object.values(conditions.data).some(namesPath);
1171
+ };
1172
+ return !entryPoints.some(namesPath);
1173
+ }
1174
+ async function workspaceDependencyEdges(host, pkg, workspacePackages) {
1175
+ const workspacePackageNames = new Set(workspacePackages.keys());
1176
+ const declared = new Set();
1177
+ const declaredExternal = new Set();
1178
+ const optionalPeers = new Set();
1179
+ for (const [name, selector] of Object.entries(pkg.packageJson.dependencies ?? {})) {
1180
+ const target = workspacePackages.get(name);
1181
+ if (target && selectorResolvesWorkspacePackage(target, selector ?? ''))
1182
+ declared.add(name);
1183
+ else if (target)
1184
+ declaredExternal.add(name);
1185
+ else if (selector?.startsWith('workspace:')) {
1186
+ throw new Error(`Workspace artifact build plan cannot resolve ${name}, required by ${pkg.name}, to a workspace package manifest`);
1187
+ }
1188
+ }
1189
+ // Optional peers (peerDependenciesMeta[name].optional) are not build
1190
+ // prerequisites — they may be absent at runtime by contract, and treating
1191
+ // them as edges pulls whole optional families into every consumer's plan
1192
+ // and can invert cycle ordering (ai <-> ai-provider-*). Statically-imported
1193
+ // peers are still covered by the source scan below.
1194
+ for (const [name, selector] of Object.entries(pkg.packageJson.peerDependencies ?? {})) {
1195
+ const target = workspacePackages.get(name);
1196
+ // An optional peer is never part of this package's required closure,
1197
+ // whether or not its selector resolves the workspace version: a source
1198
+ // import of it orders the build only when something else already
1199
+ // requires it, and never drags it (or its own cycle) into the plan.
1200
+ if (pkg.packageJson.peerDependenciesMeta?.[name]?.optional === true) {
1201
+ if (target) {
1202
+ declaredExternal.add(name);
1203
+ if (selectorResolvesWorkspacePackage(target, selector ?? ''))
1204
+ optionalPeers.add(name);
1205
+ }
1206
+ continue;
1207
+ }
1208
+ if (target && selectorResolvesWorkspacePackage(target, selector ?? ''))
1209
+ declared.add(name);
1210
+ else if (target)
1211
+ declaredExternal.add(name);
1212
+ else if (selector?.startsWith('workspace:')) {
1213
+ throw new Error(`Workspace artifact build plan cannot resolve ${name}, required by ${pkg.name}, to a workspace package manifest`);
1214
+ }
1215
+ }
1216
+ const discovered = new Set();
1217
+ const optionalInputs = new Set();
1218
+ for (const path of await packageBuildInputs(host, pkg)) {
1219
+ const dynamicDiscovered = new Set();
1220
+ await collectImportsFromPath(host, path, discovered, workspacePackageNames, dynamicDiscovered);
1221
+ for (const name of dynamicDiscovered) {
1222
+ if (name === pkg.name)
1223
+ continue;
1224
+ const optionalPeer = pkg.packageJson.peerDependencies?.[name] !== undefined &&
1225
+ pkg.packageJson.peerDependenciesMeta?.[name]?.optional === true;
1226
+ if (optionalPeer) {
1227
+ if (optionalPeers.has(name))
1228
+ optionalInputs.add(name);
1229
+ continue;
1230
+ }
1231
+ if (declaredExternal.has(name))
1232
+ continue;
1233
+ const developmentSelector = isBuildOnlyImportSource(host, pkg, path)
1234
+ ? pkg.packageJson.devDependencies?.[name]
1235
+ : undefined;
1236
+ const requiredDeclaration = pkg.packageJson.dependencies?.[name] !== undefined ||
1237
+ (pkg.packageJson.peerDependencies?.[name] !== undefined && !optionalPeer) ||
1238
+ developmentSelector !== undefined;
1239
+ if (!requiredDeclaration) {
1240
+ throw new Error(`Workspace artifact build plan found undeclared dynamic import ${name}, required by ${pkg.name}; declare it as a dependency, required peer, or optional peer (build-only imports may use a development dependency)`);
1241
+ }
1242
+ const target = workspacePackages.get(name);
1243
+ if (developmentSelector !== undefined && target && !selectorResolvesWorkspacePackage(target, developmentSelector)) {
1244
+ continue;
1245
+ }
1246
+ discovered.add(name);
1247
+ }
1248
+ }
1249
+ for (const name of optionalPeers) {
1250
+ if (discovered.has(name))
1251
+ optionalInputs.add(name);
1252
+ }
1253
+ for (const name of declaredExternal) {
1254
+ if (!declared.has(name))
1255
+ discovered.delete(name);
1256
+ }
1257
+ declared.delete(pkg.name);
1258
+ discovered.delete(pkg.name);
1259
+ const all = new Set([...declared, ...discovered]);
1260
+ return {
1261
+ declared: [...declared].sort(),
1262
+ discovered: [...discovered].sort(),
1263
+ all: [...all].sort(),
1264
+ inputs: [...new Set([...all, ...optionalInputs])].sort()
1265
+ };
1266
+ }
1267
+ function shouldScanFile(path) {
1268
+ const filename = path.split('/').pop() ?? '';
1269
+ if (filename.includes('.test.') || filename.includes('.spec.') || filename.endsWith('.d.ts')) {
1270
+ return false;
1271
+ }
1272
+ const dot = filename.lastIndexOf('.');
1273
+ return dot >= 0 && SOURCE_EXTENSIONS.has(filename.slice(dot));
1274
+ }
1275
+ async function collectImportsFromPath(host, path, out, workspacePackageNames, dynamicOut) {
1276
+ if (!(await host.files.exists(path)))
1277
+ return;
1278
+ const stats = await followedStat(host, path);
1279
+ if (stats.kind === 'directory') {
1280
+ for (const entry of await host.files.list(path)) {
1281
+ if (entry.kind === 'directory' && SKIP_DIRS.has(entry.name))
1282
+ continue;
1283
+ await collectImportsFromPath(host, host.paths.join(path, entry.name), out, workspacePackageNames, dynamicOut);
1284
+ }
1285
+ return;
1286
+ }
1287
+ if (stats.kind !== 'file' || !shouldScanFile(path))
1288
+ return;
1289
+ const read = await settle(async () => readText(host.files, path));
1290
+ if (!read.ok) {
1291
+ // The file vanished between the directory walk and the read: nothing to scan.
1292
+ if (isMissingPathError(read.cause))
1293
+ return;
1294
+ throw read.cause;
1295
+ }
1296
+ const text = read.value;
1297
+ const filename = path.split('/').pop() ?? '';
1298
+ const dot = filename.lastIndexOf('.');
1299
+ const extension = dot >= 0 ? filename.slice(dot) : '';
1300
+ if (extension === '.css') {
1301
+ collectCssImports(text, out, workspacePackageNames);
1302
+ return;
1303
+ }
1304
+ if (extension === '.svelte') {
1305
+ for (const script of extractSvelteBlocks(text, 'script')) {
1306
+ collectEcmaScriptImports(script, out, workspacePackageNames, dynamicOut);
1307
+ }
1308
+ for (const style of extractSvelteBlocks(text, 'style')) {
1309
+ collectCssImports(style, out, workspacePackageNames);
1310
+ }
1311
+ return;
1312
+ }
1313
+ collectEcmaScriptImports(text, out, workspacePackageNames, dynamicOut);
1314
+ if (extension === '.js' || extension === '.mjs' || extension === '.cjs') {
1315
+ collectCssImports(text, out, workspacePackageNames);
1316
+ }
1317
+ }
1318
+ function collectCssImports(text, out, workspacePackageNames) {
1319
+ for (const match of text.matchAll(CSS_IMPORT_RE)) {
1320
+ if (match[1])
1321
+ addPackageFromSpecifier(out, match[1], workspacePackageNames);
1322
+ }
1323
+ }
1324
+ function extractSvelteBlocks(text, tag) {
1325
+ const blocks = [];
1326
+ const pattern = new RegExp(`<${tag}\\b[^>]*>([\\s\\S]*?)<\\/${tag}>`, 'gi');
1327
+ for (const match of text.matchAll(pattern)) {
1328
+ blocks.push(match[1] ?? '');
1329
+ }
1330
+ return blocks;
1331
+ }
1332
+ function collectEcmaScriptImports(text, out, workspacePackageNames, dynamicOut) {
1333
+ let index = 0;
1334
+ while (index < text.length) {
1335
+ const skipped = skipWhitespaceAndComments(text, index);
1336
+ index = skipped.index;
1337
+ if (skipped.stoppedInString) {
1338
+ index = skipStringLike(text, index);
1339
+ continue;
1340
+ }
1341
+ if (matchesKeyword(text, index, 'import')) {
1342
+ index = collectImportStatement(text, index + 'import'.length, out, workspacePackageNames, dynamicOut);
1343
+ continue;
1344
+ }
1345
+ if (matchesKeyword(text, index, 'export')) {
1346
+ index = collectExportStatement(text, index + 'export'.length, out, workspacePackageNames);
1347
+ continue;
1348
+ }
1349
+ index += 1;
1350
+ }
1351
+ }
1352
+ function collectImportStatement(text, index, out, workspacePackageNames, dynamicOut) {
1353
+ let cursor = skipWhitespaceAndComments(text, index).index;
1354
+ if (text[cursor] === '(') {
1355
+ cursor = skipWhitespaceAndComments(text, cursor + 1).index;
1356
+ const literal = readStringLiteral(text, cursor);
1357
+ if (literal) {
1358
+ addPackageFromSpecifier(dynamicOut ?? out, literal.value, workspacePackageNames);
1359
+ }
1360
+ return literal?.end ?? cursor + 1;
1361
+ }
1362
+ if (text[cursor] === '.')
1363
+ return cursor + 1;
1364
+ const sideEffectImport = readStringLiteral(text, cursor);
1365
+ if (sideEffectImport) {
1366
+ addPackageFromSpecifier(out, sideEffectImport.value, workspacePackageNames);
1367
+ return sideEffectImport.end;
1368
+ }
1369
+ return collectFromClause(text, cursor, out, workspacePackageNames);
1370
+ }
1371
+ function collectExportStatement(text, index, out, workspacePackageNames) {
1372
+ const cursor = skipWhitespaceAndComments(text, index).index;
1373
+ if (text[cursor] === '*' ||
1374
+ text[cursor] === '{' ||
1375
+ matchesKeyword(text, cursor, 'type')) {
1376
+ return collectFromClause(text, cursor, out, workspacePackageNames);
1377
+ }
1378
+ // `export function`, `export const`, and `export default` may contain a
1379
+ // dynamic import in their initializer/body. Keep scanning their contents
1380
+ // instead of consuming the whole declaration while looking for a `from`.
1381
+ return cursor;
1382
+ }
1383
+ function collectFromClause(text, index, out, workspacePackageNames) {
1384
+ let cursor = index;
1385
+ while (cursor < text.length) {
1386
+ const skipped = skipWhitespaceAndComments(text, cursor);
1387
+ cursor = skipped.index;
1388
+ if (skipped.stoppedInString) {
1389
+ cursor = skipStringLike(text, cursor);
1390
+ continue;
1391
+ }
1392
+ if (text[cursor] === ';')
1393
+ return cursor + 1;
1394
+ if (matchesKeyword(text, cursor, 'from')) {
1395
+ cursor = skipWhitespaceAndComments(text, cursor + 'from'.length).index;
1396
+ const literal = readStringLiteral(text, cursor);
1397
+ if (literal) {
1398
+ addPackageFromSpecifier(out, literal.value, workspacePackageNames);
1399
+ return literal.end;
1400
+ }
1401
+ return cursor;
1402
+ }
1403
+ cursor += 1;
1404
+ }
1405
+ return cursor;
1406
+ }
1407
+ function addPackageFromSpecifier(out, specifier, workspacePackageNames) {
1408
+ if (workspacePackageNames) {
1409
+ const exactWorkspacePackage = [...workspacePackageNames]
1410
+ .filter((name) => specifier === name || specifier.startsWith(`${name}/`))
1411
+ .sort((a, b) => b.length - a.length || a.localeCompare(b))[0];
1412
+ if (exactWorkspacePackage) {
1413
+ out.add(exactWorkspacePackage);
1414
+ }
1415
+ return;
1416
+ }
1417
+ const match = specifier.match(/^(@vibesdotdev\/[a-zA-Z0-9-]+)(?:\/.*)?$/);
1418
+ if (match?.[1])
1419
+ out.add(match[1]);
1420
+ }
1421
+ function matchesKeyword(text, index, keyword) {
1422
+ if (!text.startsWith(keyword, index))
1423
+ return false;
1424
+ const before = index > 0 ? text[index - 1] : '';
1425
+ const after = text[index + keyword.length] ?? '';
1426
+ return !isIdentifierChar(before) && !isIdentifierChar(after);
1427
+ }
1428
+ function isIdentifierChar(char) {
1429
+ return /[A-Za-z0-9_$]/.test(char);
1430
+ }
1431
+ function skipWhitespaceAndComments(text, index) {
1432
+ let cursor = index;
1433
+ while (cursor < text.length) {
1434
+ const char = text[cursor];
1435
+ const next = text[cursor + 1];
1436
+ if (/\s/.test(char)) {
1437
+ cursor += 1;
1438
+ continue;
1439
+ }
1440
+ if (char === '/' && next === '/') {
1441
+ const lineEnd = text.indexOf('\n', cursor + 2);
1442
+ cursor = lineEnd >= 0 ? lineEnd + 1 : text.length;
1443
+ continue;
1444
+ }
1445
+ if (char === '/' && next === '*') {
1446
+ const commentEnd = text.indexOf('*/', cursor + 2);
1447
+ cursor = commentEnd >= 0 ? commentEnd + 2 : text.length;
1448
+ continue;
1449
+ }
1450
+ return { index: cursor, stoppedInString: char === '"' || char === "'" || char === '`' };
1451
+ }
1452
+ return { index: cursor, stoppedInString: false };
1453
+ }
1454
+ function skipStringLike(text, index) {
1455
+ const quote = text[index];
1456
+ let cursor = index + 1;
1457
+ while (cursor < text.length) {
1458
+ const char = text[cursor];
1459
+ if (char === '\\') {
1460
+ cursor += 2;
1461
+ continue;
1462
+ }
1463
+ if (char === quote)
1464
+ return cursor + 1;
1465
+ cursor += 1;
1466
+ }
1467
+ return cursor;
1468
+ }
1469
+ function readStringLiteral(text, index) {
1470
+ const quote = text[index];
1471
+ if (quote !== '"' && quote !== "'")
1472
+ return null;
1473
+ let cursor = index + 1;
1474
+ let value = '';
1475
+ while (cursor < text.length) {
1476
+ const char = text[cursor];
1477
+ if (char === '\\') {
1478
+ value += text[cursor + 1] ?? '';
1479
+ cursor += 2;
1480
+ continue;
1481
+ }
1482
+ if (char === quote)
1483
+ return { value, end: cursor + 1 };
1484
+ value += char;
1485
+ cursor += 1;
1486
+ }
1487
+ return null;
1488
+ }
1489
+ function appScanPaths(host, appDir) {
1490
+ return [
1491
+ host.paths.join(appDir, 'src'),
1492
+ host.paths.join(appDir, 'vibes.config.js'),
1493
+ host.paths.join(appDir, 'vibes.config.ts'),
1494
+ host.paths.join(appDir, 'deployment.config.js'),
1495
+ host.paths.join(appDir, 'deployment.config.ts'),
1496
+ host.paths.join(appDir, 'svelte.config.js'),
1497
+ host.paths.join(appDir, 'svelte.config.ts'),
1498
+ host.paths.join(appDir, 'vite.config.js'),
1499
+ host.paths.join(appDir, 'vite.config.ts')
1500
+ ];
1501
+ }
1502
+ function cachedEdges(cache) {
1503
+ return (pkg) => {
1504
+ const deps = cache.get(pkg.name);
1505
+ if (!deps) {
1506
+ throw new Error(`Workspace dependency edges were not loaded for ${pkg.name}`);
1507
+ }
1508
+ return deps;
1509
+ };
1510
+ }
1511
+ async function edgesOf(host, pkg, packages, cache) {
1512
+ const cached = cache.get(pkg.name);
1513
+ if (cached)
1514
+ return cached;
1515
+ const deps = await workspaceDependencyEdges(host, pkg, packages);
1516
+ cache.set(pkg.name, deps);
1517
+ return deps;
1518
+ }
1519
+ /**
1520
+ * Computes the complete, dependency-ordered list of workspace packages whose
1521
+ * dist artifacts must exist before the app can build. Pure planning step —
1522
+ * does not run any builds.
1523
+ *
1524
+ * Edges are the union of declared workspace deps (dependencies +
1525
+ * peerDependencies) and source-scanned imports, so transitive deps reachable
1526
+ * only through peerDependencies or undeclared imports are included. Cycles in
1527
+ * that union (e.g. runtime <-> runtime-client via source imports) are
1528
+ * tolerated: a back-edge to a package already on the visit stack is skipped,
1529
+ * which still yields a valid topological order for the acyclic remainder.
1530
+ */
1531
+ export async function planWorkspaceArtifactBuilds(options) {
1532
+ const host = await resolveArtifactHost(options.runtime);
1533
+ return (await planWorkspacePackageClosure(host, options)).filter(hasBuildArtifacts);
1534
+ }
1535
+ /** Closure from explicit package seeds (publish preflight) — same transitive walk as the app path. */
1536
+ export async function planWorkspacePackageClosureFromSeeds(runtime, workspaceRoot, seedNames, packageScope) {
1537
+ const host = await resolveArtifactHost(runtime);
1538
+ const packages = await resolveWorkspacePackages(host, workspaceRoot, packageScope);
1539
+ const dependencyCache = new Map();
1540
+ const planned = new Set();
1541
+ const visiting = new Set();
1542
+ const order = [];
1543
+ const visit = async (pkg) => {
1544
+ if (planned.has(pkg.name) || visiting.has(pkg.name))
1545
+ return;
1546
+ visiting.add(pkg.name);
1547
+ for (const depName of (await edgesOf(host, pkg, packages, dependencyCache)).all) {
1548
+ const dep = packages.get(depName);
1549
+ if (!dep) {
1550
+ throw new Error(`Workspace package closure cannot resolve ${depName}, required by ${pkg.name}, to a workspace package manifest`);
1551
+ }
1552
+ await visit(dep);
1553
+ }
1554
+ visiting.delete(pkg.name);
1555
+ planned.add(pkg.name);
1556
+ order.push(pkg);
1557
+ };
1558
+ for (const name of [...seedNames].sort()) {
1559
+ const pkg = packages.get(name);
1560
+ if (!pkg) {
1561
+ throw new Error(`Workspace package closure seed ${name} is not a workspace package`);
1562
+ }
1563
+ await visit(pkg);
1564
+ }
1565
+ return orderCycleMembersByWorkspaceDependencies(order, cachedEdges(dependencyCache));
1566
+ }
1567
+ async function workspaceAppDependencyNames(host, workspaceRoot, appDir, packages) {
1568
+ const workspacePackageNames = new Set(packages.keys());
1569
+ const appImports = new Set();
1570
+ for (const path of appScanPaths(host, appDir)) {
1571
+ await collectImportsFromPath(host, path, appImports, workspacePackageNames);
1572
+ }
1573
+ const appPackageJson = await readAppManifest(host, host.paths.join(appDir, 'package.json'));
1574
+ const localDeclared = new Set();
1575
+ const declaredExternal = new Set();
1576
+ for (const [name, selector] of Object.entries(appPackageJson?.dependencies ?? {})) {
1577
+ const target = packages.get(name);
1578
+ if (target && selectorResolvesWorkspacePackage(target, selector ?? '')) {
1579
+ appImports.add(name);
1580
+ localDeclared.add(name);
1581
+ }
1582
+ else if (target)
1583
+ declaredExternal.add(name);
1584
+ else if (selector?.startsWith('workspace:')) {
1585
+ throw new Error(`Workspace artifact build plan cannot resolve ${name}, required by ${host.paths.relative(workspaceRoot, appDir)}, to a workspace package manifest`);
1586
+ }
1587
+ }
1588
+ for (const [name, selector] of Object.entries(appPackageJson?.peerDependencies ?? {})) {
1589
+ const target = packages.get(name);
1590
+ if (appPackageJson?.peerDependenciesMeta?.[name]?.optional === true) {
1591
+ if (target && !selectorResolvesWorkspacePackage(target, selector ?? '')) {
1592
+ declaredExternal.add(name);
1593
+ }
1594
+ continue;
1595
+ }
1596
+ if (target && selectorResolvesWorkspacePackage(target, selector ?? '')) {
1597
+ appImports.add(name);
1598
+ localDeclared.add(name);
1599
+ }
1600
+ else if (target)
1601
+ declaredExternal.add(name);
1602
+ else if (selector?.startsWith('workspace:')) {
1603
+ throw new Error(`Workspace artifact build plan cannot resolve ${name}, required by ${host.paths.relative(workspaceRoot, appDir)}, to a workspace package manifest`);
1604
+ }
1605
+ }
1606
+ for (const name of declaredExternal) {
1607
+ if (!localDeclared.has(name))
1608
+ appImports.delete(name);
1609
+ }
1610
+ return [...appImports].sort();
1611
+ }
1612
+ async function planWorkspacePackageClosure(host, { workspaceRoot, appDir }) {
1613
+ const packages = await discoverWorkspacePackages(host, workspaceRoot);
1614
+ const appImports = await workspaceAppDependencyNames(host, workspaceRoot, appDir, packages);
1615
+ const dependencyCache = new Map();
1616
+ const planned = new Set();
1617
+ const visiting = new Set();
1618
+ const order = [];
1619
+ const visit = async (pkg) => {
1620
+ // A package already on the visit stack is a dependency cycle; skip the
1621
+ // back-edge instead of failing — every member still gets built once.
1622
+ if (planned.has(pkg.name) || visiting.has(pkg.name))
1623
+ return;
1624
+ visiting.add(pkg.name);
1625
+ for (const depName of (await edgesOf(host, pkg, packages, dependencyCache)).all) {
1626
+ const dep = packages.get(depName);
1627
+ if (!dep) {
1628
+ throw new Error(`Workspace artifact build plan cannot resolve ${depName}, required by ${pkg.name}, to a workspace package manifest`);
1629
+ }
1630
+ await visit(dep);
1631
+ }
1632
+ visiting.delete(pkg.name);
1633
+ planned.add(pkg.name);
1634
+ order.push(pkg);
1635
+ };
1636
+ for (const name of appImports) {
1637
+ const pkg = packages.get(name);
1638
+ if (!pkg)
1639
+ continue;
1640
+ await visit(pkg);
1641
+ }
1642
+ return orderCycleMembersByWorkspaceDependencies(order, cachedEdges(dependencyCache));
1643
+ }
1644
+ /**
1645
+ * Refuses a deploy before its ledger, regeneration, build, or provider phases
1646
+ * when the dependency closure could resolve outside the requested worktree or
1647
+ * consume stale Node-condition artifacts. This deliberately has no skip-build
1648
+ * branch: skipping a rebuild must not permit unverified deploy inputs.
1649
+ */
1650
+ export async function assertDeployWorkspacePreflight({ workspaceRoot, runtime, appDir, packageNames, packageScope, artifactPolicy = 'strict' }) {
1651
+ const host = await resolveArtifactHost(runtime);
1652
+ const resolvedWorkspaceRoot = await realpathChecked(host.files, workspaceRoot);
1653
+ const nodeModules = host.paths.join(resolvedWorkspaceRoot, 'node_modules');
1654
+ if (!(await host.files.exists(nodeModules))) {
1655
+ throw deployPreflightFailure(`the deploy worktree has no node_modules at ${nodeModules}. Run \`bun install\` in ${resolvedWorkspaceRoot}.`);
1656
+ }
1657
+ const resolvedNodeModules = await realpathChecked(host.files, nodeModules);
1658
+ if (!isPathWithin(host, resolvedWorkspaceRoot, resolvedNodeModules)) {
1659
+ throw deployPreflightFailure(`node_modules resolves outside the deploy worktree (${resolvedNodeModules}). Run \`bun install\` in ${resolvedWorkspaceRoot}; do not reuse another worktree's dependencies.`);
1660
+ }
1661
+ const warnings = [];
1662
+ if ((appDir === undefined) === (packageNames === undefined)) {
1663
+ throw deployPreflightFailure('workspace preflight needs exactly one of appDir or packageNames as its closure seed');
1664
+ }
1665
+ const workspacePackages = appDir !== undefined
1666
+ ? await discoverWorkspacePackages(host, resolvedWorkspaceRoot)
1667
+ : await resolveWorkspacePackages(host, resolvedWorkspaceRoot, packageScope);
1668
+ let packageClosure;
1669
+ if (appDir !== undefined) {
1670
+ const resolvedAppDir = await realpathChecked(host.files, appDir);
1671
+ if (!isPathWithin(host, resolvedWorkspaceRoot, resolvedAppDir)) {
1672
+ throw deployPreflightFailure(`app resolves outside the deploy worktree (${resolvedAppDir}). Run \`bun install\` in ${resolvedWorkspaceRoot}.`);
1673
+ }
1674
+ packageClosure = await planWorkspacePackageClosure(host, {
1675
+ workspaceRoot: resolvedWorkspaceRoot,
1676
+ appDir: resolvedAppDir
1677
+ });
1678
+ for (const dependencyName of await workspaceAppDependencyNames(host, resolvedWorkspaceRoot, resolvedAppDir, workspacePackages)) {
1679
+ await assertInstalledWorkspacePackageResolution(host, {
1680
+ consumerDir: resolvedAppDir,
1681
+ consumerLabel: host.paths.relative(resolvedWorkspaceRoot, resolvedAppDir),
1682
+ dependencyName,
1683
+ workspaceRoot: resolvedWorkspaceRoot
1684
+ });
1685
+ }
1686
+ }
1687
+ else if (packageNames !== undefined) {
1688
+ packageClosure = selectWorkspacePackagesByName(workspacePackages, packageNames);
1689
+ }
1690
+ else {
1691
+ throw deployPreflightFailure('workspace preflight needs exactly one of appDir or packageNames as its closure seed');
1692
+ }
1693
+ for (const pkg of packageClosure) {
1694
+ const resolvedPackageRoot = await realpathChecked(host.files, pkg.dir);
1695
+ if (!isPathWithin(host, resolvedWorkspaceRoot, resolvedPackageRoot)) {
1696
+ throw deployPreflightFailure(`${pkg.name} resolves outside the deploy worktree (${resolvedPackageRoot}). Run \`bun install\` in ${resolvedWorkspaceRoot}.`);
1697
+ }
1698
+ for (const dependencyName of (await workspaceDependencyEdges(host, pkg, workspacePackages)).all) {
1699
+ await assertInstalledWorkspacePackageResolution(host, {
1700
+ consumerDir: resolvedPackageRoot,
1701
+ consumerLabel: pkg.name,
1702
+ dependencyName,
1703
+ workspaceRoot: resolvedWorkspaceRoot
1704
+ });
1705
+ }
1706
+ }
1707
+ if (artifactPolicy === 'planned-build') {
1708
+ return { warnings };
1709
+ }
1710
+ const ownHashes = new Map();
1711
+ for (const pkg of packageClosure.filter(hasBuildArtifacts)) {
1712
+ // Single source of truth: the same predicate that decides whether the
1713
+ // build orchestration below may skip this package's build (see
1714
+ // `checkWorkspacePackageFreshness`) decides whether this postflight
1715
+ // assertion accepts it as a valid deploy input.
1716
+ const freshness = await checkWorkspacePackageFreshness(host, pkg, workspacePackages, ownHashes);
1717
+ if (freshness.fresh)
1718
+ continue;
1719
+ if (freshness.artifactsMissing) {
1720
+ throw deployPreflightFailure(`${pkg.name} has no ${freshness.artifactsDir} artifacts. ${staleArtifactRemedy(freshness.artifactsDir)}`);
1721
+ }
1722
+ throw deployPreflightFailure(`${pkg.name} ${freshness.artifactsDir} is stale for this deploy: ${freshness.reason}. ${staleArtifactRemedy(freshness.artifactsDir)}`);
1723
+ }
1724
+ return { warnings };
1725
+ }
1726
+ function selectWorkspacePackagesByName(packages, packageNames) {
1727
+ const selected = [];
1728
+ const seen = new Set();
1729
+ for (const name of packageNames) {
1730
+ if (seen.has(name)) {
1731
+ throw new Error(`Workspace preflight package closure repeats ${name}`);
1732
+ }
1733
+ seen.add(name);
1734
+ const pkg = packages.get(name);
1735
+ if (!pkg) {
1736
+ throw new Error(`Workspace preflight package ${name} is not a workspace package`);
1737
+ }
1738
+ selected.push(pkg);
1739
+ }
1740
+ return selected;
1741
+ }
1742
+ /**
1743
+ * Orders one caller-owned package set by the dependencies its production
1744
+ * source actually imports. This does not expand the set: Registry owns the
1745
+ * release closure, while this planner owns the artifact order inside it.
1746
+ * A selected package importing an omitted workspace package is a broken sealed
1747
+ * closure and fails before any build starts.
1748
+ */
1749
+ export async function planWorkspacePackageBuildOrder(runtime, workspaceRoot, packageNames, packageScope) {
1750
+ const host = await resolveArtifactHost(runtime);
1751
+ const packages = await resolveWorkspacePackages(host, workspaceRoot, packageScope);
1752
+ const selected = selectWorkspacePackagesByName(packages, packageNames);
1753
+ const selectedNames = new Set(selected.map((pkg) => pkg.name));
1754
+ const dependencyCache = new Map();
1755
+ for (const pkg of selected) {
1756
+ const dependencies = await edgesOf(host, pkg, packages, dependencyCache);
1757
+ for (const dependency of dependencies.all) {
1758
+ if (!selectedNames.has(dependency)) {
1759
+ throw new Error(`Workspace artifact package closure omits ${dependency}, imported by ${pkg.name}`);
1760
+ }
1761
+ }
1762
+ }
1763
+ return orderCycleMembersByWorkspaceDependencies(selected, cachedEdges(dependencyCache)).map((pkg) => pkg.name);
1764
+ }
1765
+ /**
1766
+ * Only the workspace-artifacts builder writes the build stamp, so the remedy
1767
+ * names a run that goes through it; a package's own `build` script never does.
1768
+ */
1769
+ function staleArtifactRemedy(artifactsDir) {
1770
+ return `Rerun without \`--skip-build\` so the workspace-artifacts build rebuilds it and records ${artifactsDir}/${BUILD_STAMP_FILENAME}; a package's own \`bun run build\` does not write that stamp.`;
1771
+ }
1772
+ function deployPreflightFailure(message) {
1773
+ return new Error(`[workspace-preflight] Refusing deploy: ${message}`);
1774
+ }
1775
+ function isPathWithin(host, root, target) {
1776
+ const pathFromRoot = host.paths.relative(root, target);
1777
+ return (pathFromRoot === '' ||
1778
+ (pathFromRoot !== '..' &&
1779
+ !pathFromRoot.startsWith(`..${host.sep}`) &&
1780
+ !host.paths.isAbsolute(pathFromRoot)));
1781
+ }
1782
+ async function resolveInstalledWorkspacePackage(host, consumerDir, workspaceRoot, packageName) {
1783
+ let current = await realpathChecked(host.files, consumerDir);
1784
+ while (isPathWithin(host, workspaceRoot, current)) {
1785
+ const candidate = host.paths.join(current, 'node_modules', ...packageName.split('/'));
1786
+ if (await host.files.exists(candidate))
1787
+ return candidate;
1788
+ if (current === workspaceRoot)
1789
+ break;
1790
+ current = host.paths.dirname(current);
1791
+ }
1792
+ return undefined;
1793
+ }
1794
+ async function assertInstalledWorkspacePackageResolution(host, options) {
1795
+ const installedPackage = await resolveInstalledWorkspacePackage(host, options.consumerDir, options.workspaceRoot, options.dependencyName);
1796
+ if (!installedPackage) {
1797
+ throw deployPreflightFailure(`cannot resolve ${options.dependencyName}, required by ${options.consumerLabel}, from this worktree's node_modules. Run \`bun install\` in ${options.workspaceRoot}.`);
1798
+ }
1799
+ const resolvedInstalledPackage = await realpathChecked(host.files, installedPackage);
1800
+ if (!isPathWithin(host, options.workspaceRoot, resolvedInstalledPackage)) {
1801
+ throw deployPreflightFailure(`${options.dependencyName}, required by ${options.consumerLabel}, resolves outside the deploy worktree (${resolvedInstalledPackage}). Run \`bun install\` in ${options.workspaceRoot}; do not reuse another worktree's dependencies.`);
1802
+ }
1803
+ }
1804
+ /**
1805
+ * A file under `src/` the build reads. Hidden files are generated sentinels
1806
+ * (`@vibesdotdev/editor`'s nvim install writes `.vibes-install.json` through a
1807
+ * symlink into `editor/src/`), and tests, including whole `__tests__`
1808
+ * directories, are excluded from the tsconfig, so none of them is a build input.
1809
+ */
1810
+ function isBuildInput(path) {
1811
+ const filename = path.split('/').pop() ?? '';
1812
+ if (filename.startsWith('.'))
1813
+ return false;
1814
+ if (filename.includes('.test.') || filename.includes('.spec.'))
1815
+ return false;
1816
+ return !path.includes('/__tests__/');
1817
+ }
1818
+ async function filesInDirectory(host, directory, include = () => true) {
1819
+ if (!(await host.files.exists(directory)))
1820
+ return [];
1821
+ const files = [];
1822
+ const visit = async (path) => {
1823
+ for (const entry of await host.files.list(path)) {
1824
+ const entryPath = host.paths.join(path, entry.name);
1825
+ if (entry.kind === 'directory') {
1826
+ if (!SKIP_DIRS.has(entry.name))
1827
+ await visit(entryPath);
1828
+ continue;
1829
+ }
1830
+ if (entry.kind === 'file' && include(entryPath))
1831
+ files.push(entryPath);
1832
+ }
1833
+ };
1834
+ await visit(directory);
1835
+ return files;
1836
+ }
1837
+ function orderCycleMembersByWorkspaceDependencies(order, dependenciesOf) {
1838
+ const allEdges = new Map();
1839
+ const packageByName = new Map(order.map((pkg) => [pkg.name, pkg]));
1840
+ const orderIndex = new Map(order.map((pkg, index) => [pkg.name, index]));
1841
+ const reachable = new Set(packageByName.keys());
1842
+ for (const pkg of order) {
1843
+ allEdges.set(pkg.name, dependenciesOf(pkg).all.filter((name) => reachable.has(name)));
1844
+ }
1845
+ const componentByName = findStronglyConnectedComponents([...reachable], allEdges);
1846
+ const components = new Map();
1847
+ for (const pkg of order) {
1848
+ const component = componentByName.get(pkg.name);
1849
+ if (component === undefined)
1850
+ continue;
1851
+ const members = components.get(component) ?? [];
1852
+ members.push(pkg);
1853
+ components.set(component, members);
1854
+ }
1855
+ const output = [];
1856
+ for (const component of sortComponentsByDependencies(components, componentByName, allEdges, orderIndex)) {
1857
+ const members = components.get(component) ?? [];
1858
+ if (members.length === 0)
1859
+ continue;
1860
+ if (members.length === 1) {
1861
+ output.push(members[0]);
1862
+ continue;
1863
+ }
1864
+ output.push(...sortComponentByDeclaredWorkspaceDependencies(members, dependenciesOf, orderIndex));
1865
+ }
1866
+ return output;
1867
+ }
1868
+ function sortComponentsByDependencies(components, componentByName, allEdges, orderIndex) {
1869
+ const componentDeps = new Map();
1870
+ for (const component of components.keys())
1871
+ componentDeps.set(component, new Set());
1872
+ for (const [name, deps] of allEdges) {
1873
+ const component = componentByName.get(name);
1874
+ if (component === undefined)
1875
+ continue;
1876
+ const depsForComponent = componentDeps.get(component);
1877
+ if (!depsForComponent)
1878
+ continue;
1879
+ for (const dep of deps) {
1880
+ const depComponent = componentByName.get(dep);
1881
+ if (depComponent === undefined || depComponent === component)
1882
+ continue;
1883
+ depsForComponent.add(depComponent);
1884
+ }
1885
+ }
1886
+ const stableComponents = [...components.keys()].sort((a, b) => {
1887
+ const aIndex = Math.min(...(components.get(a) ?? []).map((pkg) => orderIndex.get(pkg.name) ?? Number.MAX_SAFE_INTEGER));
1888
+ const bIndex = Math.min(...(components.get(b) ?? []).map((pkg) => orderIndex.get(pkg.name) ?? Number.MAX_SAFE_INTEGER));
1889
+ return aIndex - bIndex;
1890
+ });
1891
+ const visiting = new Set();
1892
+ const emitted = new Set();
1893
+ const output = [];
1894
+ const visit = (component) => {
1895
+ if (emitted.has(component))
1896
+ return;
1897
+ if (visiting.has(component))
1898
+ return;
1899
+ visiting.add(component);
1900
+ const deps = [...(componentDeps.get(component) ?? [])].sort((a, b) => stableComponents.indexOf(a) - stableComponents.indexOf(b));
1901
+ for (const dep of deps)
1902
+ visit(dep);
1903
+ visiting.delete(component);
1904
+ emitted.add(component);
1905
+ output.push(component);
1906
+ };
1907
+ for (const component of stableComponents)
1908
+ visit(component);
1909
+ return output;
1910
+ }
1911
+ function findStronglyConnectedComponents(names, edges) {
1912
+ // The shared traversal primitive (`planDag`): the partition into strongly
1913
+ // connected components, dependencies first. Callers pass names that are
1914
+ // unique and edges that name only known packages (both filter first).
1915
+ const componentByName = new Map();
1916
+ planDag({ nodes: names.map((name) => ({ id: name, dependsOn: edges.get(name) ?? [] })) }).cohorts.forEach((cohort, component) => {
1917
+ for (const name of cohort)
1918
+ componentByName.set(name, component);
1919
+ });
1920
+ return componentByName;
1921
+ }
1922
+ /**
1923
+ * An SCC exists only because source discovery added a back-edge. Declared
1924
+ * dependency edges are the build contract and must still remain strict inside
1925
+ * that SCC: a package's TypeScript build resolves its declared workspace deps
1926
+ * through their dist exports. Ordering the SCC by the combined edge set lets a
1927
+ * discovered back-edge arbitrarily move a declared prerequisite after its
1928
+ * consumer (for example runtime after runtime-environment-cef).
1929
+ */
1930
+ function sortComponentByDeclaredWorkspaceDependencies(members, dependenciesOf, orderIndex) {
1931
+ const memberNames = new Set(members.map((pkg) => pkg.name));
1932
+ const memberByName = new Map(members.map((pkg) => [pkg.name, pkg]));
1933
+ const sortedMembers = [...members].sort((a, b) => (orderIndex.get(a.name) ?? 0) - (orderIndex.get(b.name) ?? 0));
1934
+ const orderBy = (input, selectDependencies) => {
1935
+ const emitted = new Set();
1936
+ const visiting = new Set();
1937
+ const output = [];
1938
+ const visit = (pkg) => {
1939
+ if (emitted.has(pkg.name))
1940
+ return;
1941
+ if (visiting.has(pkg.name))
1942
+ return;
1943
+ visiting.add(pkg.name);
1944
+ for (const depName of selectDependencies(dependenciesOf(pkg))) {
1945
+ if (!memberNames.has(depName))
1946
+ continue;
1947
+ const dep = memberByName.get(depName);
1948
+ if (dep)
1949
+ visit(dep);
1950
+ }
1951
+ visiting.delete(pkg.name);
1952
+ emitted.add(pkg.name);
1953
+ output.push(pkg);
1954
+ };
1955
+ for (const pkg of input)
1956
+ visit(pkg);
1957
+ return output;
1958
+ };
1959
+ // Keep as much source-discovered ordering as the SCC permits, then enforce
1960
+ // the non-negotiable manifest contract over that deterministic preference.
1961
+ const preferred = orderBy(sortedMembers, (edges) => edges.all);
1962
+ const output = orderBy(preferred, (edges) => edges.declared);
1963
+ const outputIndex = new Map(output.map((pkg, index) => [pkg.name, index]));
1964
+ for (const pkg of output) {
1965
+ for (const dependency of dependenciesOf(pkg).declared) {
1966
+ if (!memberNames.has(dependency))
1967
+ continue;
1968
+ if ((outputIndex.get(dependency) ?? -1) >= (outputIndex.get(pkg.name) ?? -1)) {
1969
+ throw new Error(`Workspace artifact build plan contains a declared dependency cycle: ${pkg.name} requires ${dependency}`);
1970
+ }
1971
+ }
1972
+ }
1973
+ return output;
1974
+ }
1975
+ export async function buildWorkspaceArtifactsForApp({ workspaceRoot, appDir, execution, runtime, onLine, dryRun = false, artifactLock }) {
1976
+ if (dryRun) {
1977
+ const plan = await planWorkspaceArtifactBuilds({ workspaceRoot, appDir, runtime });
1978
+ onLine?.('stdout', `[workspace-artifacts] dry-run: planned ${plan.length} package artifact build(s); no builds executed`);
1979
+ return;
1980
+ }
1981
+ return withWorkspaceArtifactLock({ runtime, workspaceRoot, onLine, artifactLock }, async () => {
1982
+ const host = await resolveArtifactHost(runtime);
1983
+ const plan = await planWorkspaceArtifactBuilds({ workspaceRoot, appDir, runtime });
1984
+ const appLabel = host.paths.relative(workspaceRoot, appDir);
1985
+ await syncMissingSvelteKitMetadataForWorkspace(host, workspaceRoot, appDir, execution, onLine);
1986
+ const packages = await discoverWorkspacePackages(host, workspaceRoot);
1987
+ await buildWorkspacePlanWithFreshnessSkip(host, workspaceRoot, plan, packages, execution, onLine);
1988
+ if (plan.length > 0) {
1989
+ onLine?.('stdout', `[workspace-artifacts] built ${plan.length} package artifact(s) for ${appLabel}`);
1990
+ }
1991
+ });
1992
+ }
1993
+ /**
1994
+ * Builds exactly the package set supplied by its owner, dependency-ordering it
1995
+ * from the selected packages' production source imports. Registry release
1996
+ * planning still owns membership; this step neither expands nor guesses it.
1997
+ */
1998
+ export async function buildWorkspaceArtifactsForPackages({ workspaceRoot, packageNames, packageScope, execution, runtime, onLine, artifactLock }) {
1999
+ return withWorkspaceArtifactLock({ runtime, workspaceRoot, onLine, artifactLock }, async () => {
2000
+ const host = await resolveArtifactHost(runtime);
2001
+ const packages = await resolveWorkspacePackages(host, workspaceRoot, packageScope);
2002
+ const packageByName = new Map(selectWorkspacePackagesByName(packages, packageNames).map((pkg) => [pkg.name, pkg]));
2003
+ const plan = (await planWorkspacePackageBuildOrder(runtime, workspaceRoot, packageNames, packageScope))
2004
+ .map((name) => packageByName.get(name))
2005
+ .filter(hasBuildArtifacts);
2006
+ if (plan.length === 0)
2007
+ return;
2008
+ onLine?.('stdout', `[workspace-artifacts] building ${plan.length} package(s) in dependency order`);
2009
+ await buildWorkspacePlanWithFreshnessSkip(host, workspaceRoot, plan, packages, execution, onLine);
2010
+ onLine?.('stdout', `[workspace-artifacts] built ${plan.length} release package artifact(s)`);
2011
+ });
2012
+ }
2013
+ //# sourceMappingURL=build-workspace-artifacts.js.map