everything-dev 1.53.1 → 2.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (713) hide show
  1. package/README.md +2 -11
  2. package/dist/_virtual/_rolldown/runtime.cjs +17 -2
  3. package/dist/_virtual/_rolldown/runtime.mjs +36 -0
  4. package/dist/api/auth-middleware.cjs +161 -0
  5. package/dist/api/auth-middleware.cjs.map +1 -0
  6. package/dist/api/auth-middleware.d.cts +69 -0
  7. package/dist/api/auth-middleware.d.mts +69 -0
  8. package/dist/api/auth-middleware.mjs +160 -0
  9. package/dist/api/auth-middleware.mjs.map +1 -0
  10. package/dist/api-contract.cjs +250 -62
  11. package/dist/api-contract.cjs.map +1 -1
  12. package/dist/api-contract.mjs +246 -65
  13. package/dist/api-contract.mjs.map +1 -1
  14. package/dist/app.cjs +99 -26
  15. package/dist/app.cjs.map +1 -1
  16. package/dist/app.d.cts +3 -0
  17. package/dist/app.d.mts +3 -0
  18. package/dist/app.mjs +100 -27
  19. package/dist/app.mjs.map +1 -1
  20. package/dist/auth-login.cjs +163 -0
  21. package/dist/auth-login.cjs.map +1 -0
  22. package/dist/auth-login.mjs +162 -0
  23. package/dist/auth-login.mjs.map +1 -0
  24. package/dist/auth-session.cjs +64 -0
  25. package/dist/auth-session.cjs.map +1 -0
  26. package/dist/auth-session.mjs +58 -0
  27. package/dist/auth-session.mjs.map +1 -0
  28. package/dist/auth-types-gen.cjs +0 -1
  29. package/dist/auth-types-gen.cjs.map +1 -1
  30. package/dist/build.cjs +37 -173
  31. package/dist/build.cjs.map +1 -1
  32. package/dist/build.mjs +37 -171
  33. package/dist/build.mjs.map +1 -1
  34. package/dist/bundle-cache.cjs +74 -0
  35. package/dist/bundle-cache.cjs.map +1 -0
  36. package/dist/bundle-cache.d.cts +27 -0
  37. package/dist/bundle-cache.d.mts +27 -0
  38. package/dist/bundle-cache.mjs +68 -0
  39. package/dist/bundle-cache.mjs.map +1 -0
  40. package/dist/bundle-fs-resolve.cjs +209 -0
  41. package/dist/bundle-fs-resolve.cjs.map +1 -0
  42. package/dist/bundle-fs-resolve.d.cts +76 -0
  43. package/dist/bundle-fs-resolve.d.mts +76 -0
  44. package/dist/bundle-fs-resolve.mjs +202 -0
  45. package/dist/bundle-fs-resolve.mjs.map +1 -0
  46. package/dist/cdn-deploy.cjs +126 -0
  47. package/dist/cdn-deploy.cjs.map +1 -0
  48. package/dist/cdn-deploy.mjs +124 -0
  49. package/dist/cdn-deploy.mjs.map +1 -0
  50. package/dist/cli/db-doctor.cjs +19 -19
  51. package/dist/cli/db-doctor.cjs.map +1 -1
  52. package/dist/cli/db-doctor.mjs +18 -18
  53. package/dist/cli/db-doctor.mjs.map +1 -1
  54. package/dist/cli/db-repair.cjs +9 -32
  55. package/dist/cli/db-repair.cjs.map +1 -1
  56. package/dist/cli/db-repair.mjs +9 -32
  57. package/dist/cli/db-repair.mjs.map +1 -1
  58. package/dist/cli/framework-version.cjs +7 -3
  59. package/dist/cli/framework-version.cjs.map +1 -1
  60. package/dist/cli/framework-version.mjs +7 -3
  61. package/dist/cli/framework-version.mjs.map +1 -1
  62. package/dist/cli/infra.cjs +159 -251
  63. package/dist/cli/infra.cjs.map +1 -1
  64. package/dist/cli/infra.mjs +154 -242
  65. package/dist/cli/infra.mjs.map +1 -1
  66. package/dist/cli/init.cjs +624 -196
  67. package/dist/cli/init.cjs.map +1 -1
  68. package/dist/cli/init.d.cts +61 -8
  69. package/dist/cli/init.d.mts +61 -8
  70. package/dist/cli/init.mjs +613 -194
  71. package/dist/cli/init.mjs.map +1 -1
  72. package/dist/cli/parse.cjs +8 -7
  73. package/dist/cli/parse.cjs.map +1 -1
  74. package/dist/cli/parse.mjs +9 -7
  75. package/dist/cli/parse.mjs.map +1 -1
  76. package/dist/cli/prompts.cjs +14 -1
  77. package/dist/cli/prompts.cjs.map +1 -1
  78. package/dist/cli/prompts.mjs +14 -1
  79. package/dist/cli/prompts.mjs.map +1 -1
  80. package/dist/cli/prune.cjs +220 -0
  81. package/dist/cli/prune.cjs.map +1 -0
  82. package/dist/cli/prune.mjs +220 -0
  83. package/dist/cli/prune.mjs.map +1 -0
  84. package/dist/cli/snapshot.cjs +2 -1
  85. package/dist/cli/snapshot.cjs.map +1 -1
  86. package/dist/cli/snapshot.mjs +2 -1
  87. package/dist/cli/snapshot.mjs.map +1 -1
  88. package/dist/cli/status.cjs +5 -4
  89. package/dist/cli/status.cjs.map +1 -1
  90. package/dist/cli/status.mjs +6 -5
  91. package/dist/cli/status.mjs.map +1 -1
  92. package/dist/cli/sync.cjs +156 -58
  93. package/dist/cli/sync.cjs.map +1 -1
  94. package/dist/cli/sync.mjs +158 -63
  95. package/dist/cli/sync.mjs.map +1 -1
  96. package/dist/cli/timing.cjs +0 -1
  97. package/dist/cli/timing.cjs.map +1 -1
  98. package/dist/cli/upgrade.cjs +95 -69
  99. package/dist/cli/upgrade.cjs.map +1 -1
  100. package/dist/cli/upgrade.mjs +97 -72
  101. package/dist/cli/upgrade.mjs.map +1 -1
  102. package/dist/cli/utils/helpers.cjs.map +1 -1
  103. package/dist/cli.cjs +320 -72
  104. package/dist/cli.cjs.map +1 -1
  105. package/dist/cli.mjs +316 -68
  106. package/dist/cli.mjs.map +1 -1
  107. package/dist/code-artifacts.cjs +76 -8
  108. package/dist/code-artifacts.cjs.map +1 -1
  109. package/dist/code-artifacts.mjs +76 -10
  110. package/dist/code-artifacts.mjs.map +1 -1
  111. package/dist/commands/build.cjs +65 -0
  112. package/dist/commands/build.cjs.map +1 -0
  113. package/dist/commands/build.mjs +65 -0
  114. package/dist/commands/build.mjs.map +1 -0
  115. package/dist/commands/config.cjs +77 -0
  116. package/dist/commands/config.cjs.map +1 -0
  117. package/dist/commands/config.d.cts +8 -0
  118. package/dist/commands/config.d.mts +8 -0
  119. package/dist/commands/config.mjs +74 -0
  120. package/dist/commands/config.mjs.map +1 -0
  121. package/dist/commands/db.cjs +107 -0
  122. package/dist/commands/db.cjs.map +1 -0
  123. package/dist/commands/db.mjs +107 -0
  124. package/dist/commands/db.mjs.map +1 -0
  125. package/dist/commands/deploy.cjs +336 -0
  126. package/dist/commands/deploy.cjs.map +1 -0
  127. package/dist/commands/deploy.mjs +334 -0
  128. package/dist/commands/deploy.mjs.map +1 -0
  129. package/dist/commands/dev.cjs +75 -0
  130. package/dist/commands/dev.cjs.map +1 -0
  131. package/dist/commands/dev.mjs +73 -0
  132. package/dist/commands/dev.mjs.map +1 -0
  133. package/dist/commands/init.cjs +234 -0
  134. package/dist/commands/init.cjs.map +1 -0
  135. package/dist/commands/init.mjs +231 -0
  136. package/dist/commands/init.mjs.map +1 -0
  137. package/dist/commands/keys.cjs +255 -0
  138. package/dist/commands/keys.cjs.map +1 -0
  139. package/dist/commands/keys.mjs +253 -0
  140. package/dist/commands/keys.mjs.map +1 -0
  141. package/dist/commands/ops.cjs +199 -0
  142. package/dist/commands/ops.cjs.map +1 -0
  143. package/dist/commands/ops.mjs +197 -0
  144. package/dist/commands/ops.mjs.map +1 -0
  145. package/dist/commands/plugins.cjs +211 -0
  146. package/dist/commands/plugins.cjs.map +1 -0
  147. package/dist/commands/plugins.mjs +211 -0
  148. package/dist/commands/plugins.mjs.map +1 -0
  149. package/dist/commands/shared.cjs +8 -0
  150. package/dist/commands/shared.cjs.map +1 -0
  151. package/dist/commands/shared.d.cts +6 -0
  152. package/dist/commands/shared.d.mts +6 -0
  153. package/dist/commands/shared.mjs +8 -0
  154. package/dist/commands/shared.mjs.map +1 -0
  155. package/dist/commands/upgrade.cjs +325 -0
  156. package/dist/commands/upgrade.cjs.map +1 -0
  157. package/dist/commands/upgrade.mjs +323 -0
  158. package/dist/commands/upgrade.mjs.map +1 -0
  159. package/dist/components/dev-render.cjs +340 -0
  160. package/dist/components/dev-render.cjs.map +1 -0
  161. package/dist/components/dev-render.mjs +332 -0
  162. package/dist/components/dev-render.mjs.map +1 -0
  163. package/dist/config.cjs +460 -221
  164. package/dist/config.cjs.map +1 -1
  165. package/dist/config.d.cts +491 -48
  166. package/dist/config.d.mts +491 -48
  167. package/dist/config.mjs +439 -212
  168. package/dist/config.mjs.map +1 -1
  169. package/dist/contract.cjs +327 -50
  170. package/dist/contract.cjs.map +1 -1
  171. package/dist/contract.d.cts +1951 -1062
  172. package/dist/contract.d.mts +1951 -1062
  173. package/dist/contract.meta.cjs +107 -12
  174. package/dist/contract.meta.cjs.map +1 -1
  175. package/dist/contract.meta.d.cts +166 -8
  176. package/dist/contract.meta.d.mts +166 -8
  177. package/dist/contract.meta.mjs +107 -11
  178. package/dist/contract.meta.mjs.map +1 -1
  179. package/dist/contract.mjs +580 -327
  180. package/dist/contract.mjs.map +1 -1
  181. package/dist/dag.cjs +5 -3
  182. package/dist/dag.cjs.map +1 -1
  183. package/dist/dag.mjs +6 -3
  184. package/dist/dag.mjs.map +1 -1
  185. package/dist/db/binding.cjs +80 -0
  186. package/dist/db/binding.cjs.map +1 -0
  187. package/dist/db/binding.d.cts +39 -0
  188. package/dist/db/binding.d.mts +39 -0
  189. package/dist/db/binding.mjs +78 -0
  190. package/dist/db/binding.mjs.map +1 -0
  191. package/dist/db/bindings.cjs +78 -0
  192. package/dist/db/bindings.cjs.map +1 -0
  193. package/dist/db/bindings.d.cts +34 -0
  194. package/dist/db/bindings.d.mts +34 -0
  195. package/dist/db/bindings.mjs +76 -0
  196. package/dist/db/bindings.mjs.map +1 -0
  197. package/dist/db/core.cjs +204 -0
  198. package/dist/db/core.cjs.map +1 -0
  199. package/dist/db/core.d.cts +69 -0
  200. package/dist/db/core.d.mts +69 -0
  201. package/dist/db/core.mjs +192 -0
  202. package/dist/db/core.mjs.map +1 -0
  203. package/dist/db/driver.cjs +167 -0
  204. package/dist/db/driver.cjs.map +1 -0
  205. package/dist/db/driver.d.cts +50 -0
  206. package/dist/db/driver.d.mts +50 -0
  207. package/dist/db/driver.mjs +165 -0
  208. package/dist/db/driver.mjs.map +1 -0
  209. package/dist/db/drizzle-kit.cjs +177 -0
  210. package/dist/db/drizzle-kit.cjs.map +1 -0
  211. package/dist/db/drizzle-kit.d.cts +25 -0
  212. package/dist/db/drizzle-kit.d.mts +25 -0
  213. package/dist/db/drizzle-kit.mjs +175 -0
  214. package/dist/db/drizzle-kit.mjs.map +1 -0
  215. package/dist/db/errors.cjs +27 -0
  216. package/dist/db/errors.cjs.map +1 -0
  217. package/dist/db/errors.d.cts +16 -0
  218. package/dist/db/errors.d.mts +16 -0
  219. package/dist/db/errors.mjs +26 -0
  220. package/dist/db/errors.mjs.map +1 -0
  221. package/dist/db/identity.cjs +55 -0
  222. package/dist/db/identity.cjs.map +1 -0
  223. package/dist/db/identity.d.cts +40 -0
  224. package/dist/db/identity.d.mts +40 -0
  225. package/dist/db/identity.mjs +53 -0
  226. package/dist/db/identity.mjs.map +1 -0
  227. package/dist/db/index.cjs +43 -0
  228. package/dist/db/index.d.cts +9 -0
  229. package/dist/db/index.d.mts +9 -0
  230. package/dist/db/index.mjs +10 -0
  231. package/dist/db/run-migrations.cjs +343 -0
  232. package/dist/db/run-migrations.cjs.map +1 -0
  233. package/dist/db/run-migrations.d.cts +87 -0
  234. package/dist/db/run-migrations.d.mts +87 -0
  235. package/dist/db/run-migrations.mjs +341 -0
  236. package/dist/db/run-migrations.mjs.map +1 -0
  237. package/dist/delegate-signer.cjs +85 -0
  238. package/dist/delegate-signer.cjs.map +1 -0
  239. package/dist/delegate-signer.mjs +84 -0
  240. package/dist/delegate-signer.mjs.map +1 -0
  241. package/dist/deploy-diff.cjs +119 -0
  242. package/dist/deploy-diff.cjs.map +1 -0
  243. package/dist/deploy-diff.mjs +109 -0
  244. package/dist/deploy-diff.mjs.map +1 -0
  245. package/dist/descriptor/constructors.cjs +49 -0
  246. package/dist/descriptor/constructors.cjs.map +1 -0
  247. package/dist/descriptor/constructors.d.cts +27 -0
  248. package/dist/descriptor/constructors.d.mts +27 -0
  249. package/dist/descriptor/constructors.mjs +45 -0
  250. package/dist/descriptor/constructors.mjs.map +1 -0
  251. package/dist/descriptor/index.cjs +24 -0
  252. package/dist/descriptor/index.d.cts +5 -0
  253. package/dist/descriptor/index.d.mts +5 -0
  254. package/dist/descriptor/index.mjs +6 -0
  255. package/dist/descriptor/resolve.cjs +258 -0
  256. package/dist/descriptor/resolve.cjs.map +1 -0
  257. package/dist/descriptor/resolve.d.cts +50 -0
  258. package/dist/descriptor/resolve.d.mts +50 -0
  259. package/dist/descriptor/resolve.mjs +252 -0
  260. package/dist/descriptor/resolve.mjs.map +1 -0
  261. package/dist/descriptor/schema.cjs +109 -0
  262. package/dist/descriptor/schema.cjs.map +1 -0
  263. package/dist/descriptor/schema.d.cts +217 -0
  264. package/dist/descriptor/schema.d.mts +217 -0
  265. package/dist/descriptor/schema.mjs +102 -0
  266. package/dist/descriptor/schema.mjs.map +1 -0
  267. package/dist/descriptor/serialize.cjs +45 -0
  268. package/dist/descriptor/serialize.cjs.map +1 -0
  269. package/dist/descriptor/serialize.d.cts +7 -0
  270. package/dist/descriptor/serialize.d.mts +7 -0
  271. package/dist/descriptor/serialize.mjs +45 -0
  272. package/dist/descriptor/serialize.mjs.map +1 -0
  273. package/dist/dev-log-pipeline.cjs +273 -0
  274. package/dist/dev-log-pipeline.cjs.map +1 -0
  275. package/dist/dev-log-pipeline.mjs +267 -0
  276. package/dist/dev-log-pipeline.mjs.map +1 -0
  277. package/dist/dev-logs.cjs +39 -8
  278. package/dist/dev-logs.cjs.map +1 -1
  279. package/dist/dev-logs.mjs +37 -9
  280. package/dist/dev-logs.mjs.map +1 -1
  281. package/dist/dev-program.cjs +405 -0
  282. package/dist/dev-program.cjs.map +1 -0
  283. package/dist/dev-program.d.cts +10 -0
  284. package/dist/dev-program.d.mts +10 -0
  285. package/dist/dev-program.mjs +395 -0
  286. package/dist/dev-program.mjs.map +1 -0
  287. package/dist/dev-session-data.d.cts +27 -0
  288. package/dist/dev-session-data.d.mts +27 -0
  289. package/dist/dev-session.cjs +178 -105
  290. package/dist/dev-session.cjs.map +1 -1
  291. package/dist/dev-session.mjs +180 -105
  292. package/dist/dev-session.mjs.map +1 -1
  293. package/dist/env/process-env.cjs +16 -0
  294. package/dist/env/process-env.cjs.map +1 -0
  295. package/dist/env/process-env.mjs +13 -0
  296. package/dist/env/process-env.mjs.map +1 -0
  297. package/dist/env/project-env.cjs +144 -0
  298. package/dist/env/project-env.cjs.map +1 -0
  299. package/dist/env/project-env.d.cts +1 -0
  300. package/dist/env/project-env.d.mts +1 -0
  301. package/dist/env/project-env.mjs +132 -0
  302. package/dist/env/project-env.mjs.map +1 -0
  303. package/dist/fastkv.cjs +59 -12
  304. package/dist/fastkv.cjs.map +1 -1
  305. package/dist/fastkv.d.cts +42 -6
  306. package/dist/fastkv.d.mts +42 -6
  307. package/dist/fastkv.mjs +58 -13
  308. package/dist/fastkv.mjs.map +1 -1
  309. package/dist/fingerprint.cjs +57 -0
  310. package/dist/fingerprint.cjs.map +1 -0
  311. package/dist/fingerprint.d.cts +14 -0
  312. package/dist/fingerprint.d.mts +14 -0
  313. package/dist/fingerprint.mjs +55 -0
  314. package/dist/fingerprint.mjs.map +1 -0
  315. package/dist/http-client.cjs +17 -17
  316. package/dist/http-client.cjs.map +1 -1
  317. package/dist/http-client.mjs +17 -17
  318. package/dist/http-client.mjs.map +1 -1
  319. package/dist/image-deploy.cjs +186 -0
  320. package/dist/image-deploy.cjs.map +1 -0
  321. package/dist/image-deploy.mjs +182 -0
  322. package/dist/image-deploy.mjs.map +1 -0
  323. package/dist/index.cjs +66 -18
  324. package/dist/index.d.cts +8 -7
  325. package/dist/index.d.mts +8 -7
  326. package/dist/index.mjs +6 -5
  327. package/dist/infra/docker.cjs +77 -0
  328. package/dist/infra/docker.cjs.map +1 -0
  329. package/dist/infra/docker.d.cts +10 -0
  330. package/dist/infra/docker.d.mts +10 -0
  331. package/dist/infra/docker.mjs +69 -0
  332. package/dist/infra/docker.mjs.map +1 -0
  333. package/dist/infra/materializer.cjs +74 -0
  334. package/dist/infra/materializer.cjs.map +1 -0
  335. package/dist/infra/materializer.mjs +70 -0
  336. package/dist/infra/materializer.mjs.map +1 -0
  337. package/dist/infra/planner.cjs +135 -103
  338. package/dist/infra/planner.cjs.map +1 -1
  339. package/dist/infra/planner.mjs +137 -104
  340. package/dist/infra/planner.mjs.map +1 -1
  341. package/dist/infra/port-ownership.cjs +57 -0
  342. package/dist/infra/port-ownership.cjs.map +1 -0
  343. package/dist/infra/port-ownership.mjs +57 -0
  344. package/dist/infra/port-ownership.mjs.map +1 -0
  345. package/dist/infra/preflight.cjs +45 -33
  346. package/dist/infra/preflight.cjs.map +1 -1
  347. package/dist/infra/preflight.d.cts +1 -0
  348. package/dist/infra/preflight.d.mts +1 -0
  349. package/dist/infra/preflight.mjs +46 -34
  350. package/dist/infra/preflight.mjs.map +1 -1
  351. package/dist/infra/types.cjs.map +1 -1
  352. package/dist/infra/types.d.cts +2 -0
  353. package/dist/infra/types.d.mts +2 -0
  354. package/dist/infra/types.mjs.map +1 -1
  355. package/dist/integrity.cjs +50 -61
  356. package/dist/integrity.cjs.map +1 -1
  357. package/dist/integrity.d.cts +16 -10
  358. package/dist/integrity.d.mts +16 -10
  359. package/dist/integrity.mjs +50 -59
  360. package/dist/integrity.mjs.map +1 -1
  361. package/dist/internal/manifest-normalizer.cjs +8 -2
  362. package/dist/internal/manifest-normalizer.cjs.map +1 -1
  363. package/dist/internal/manifest-normalizer.mjs +9 -3
  364. package/dist/internal/manifest-normalizer.mjs.map +1 -1
  365. package/dist/merge.cjs +19 -1
  366. package/dist/merge.cjs.map +1 -1
  367. package/dist/merge.d.cts +1 -1
  368. package/dist/merge.d.mts +1 -1
  369. package/dist/merge.mjs +19 -2
  370. package/dist/merge.mjs.map +1 -1
  371. package/dist/mf.cjs +190 -3
  372. package/dist/mf.cjs.map +1 -1
  373. package/dist/mf.d.cts +24 -2
  374. package/dist/mf.d.mts +24 -2
  375. package/dist/mf.mjs +189 -4
  376. package/dist/mf.mjs.map +1 -1
  377. package/dist/near-cli.cjs +59 -91
  378. package/dist/near-cli.cjs.map +1 -1
  379. package/dist/near-cli.mjs +58 -90
  380. package/dist/near-cli.mjs.map +1 -1
  381. package/dist/near-signer.cjs +73 -0
  382. package/dist/near-signer.cjs.map +1 -0
  383. package/dist/near-signer.mjs +70 -0
  384. package/dist/near-signer.mjs.map +1 -0
  385. package/dist/network.cjs +0 -1
  386. package/dist/network.cjs.map +1 -1
  387. package/dist/orchestrator.cjs +256 -87
  388. package/dist/orchestrator.cjs.map +1 -1
  389. package/dist/orchestrator.mjs +248 -87
  390. package/dist/orchestrator.mjs.map +1 -1
  391. package/dist/platform-deploy.cjs +81 -0
  392. package/dist/platform-deploy.cjs.map +1 -0
  393. package/dist/platform-deploy.mjs +80 -0
  394. package/dist/platform-deploy.mjs.map +1 -0
  395. package/dist/plugin.cjs +54 -1389
  396. package/dist/plugin.cjs.map +1 -1
  397. package/dist/plugin.d.cts +6 -896
  398. package/dist/plugin.d.mts +6 -896
  399. package/dist/plugin.mjs +53 -1387
  400. package/dist/plugin.mjs.map +1 -1
  401. package/dist/process-kill.cjs +44 -0
  402. package/dist/process-kill.cjs.map +1 -0
  403. package/dist/process-kill.mjs +43 -0
  404. package/dist/process-kill.mjs.map +1 -0
  405. package/dist/process-registry.cjs +64 -9
  406. package/dist/process-registry.cjs.map +1 -1
  407. package/dist/process-registry.mjs +61 -10
  408. package/dist/process-registry.mjs.map +1 -1
  409. package/dist/progress.cjs +45 -0
  410. package/dist/progress.cjs.map +1 -0
  411. package/dist/progress.d.cts +13 -0
  412. package/dist/progress.d.mts +13 -0
  413. package/dist/progress.mjs +42 -0
  414. package/dist/progress.mjs.map +1 -0
  415. package/dist/publish.cjs +513 -79
  416. package/dist/publish.cjs.map +1 -1
  417. package/dist/publish.mjs +515 -82
  418. package/dist/publish.mjs.map +1 -1
  419. package/dist/registry-use.cjs +41 -0
  420. package/dist/registry-use.cjs.map +1 -0
  421. package/dist/registry-use.mjs +40 -0
  422. package/dist/registry-use.mjs.map +1 -0
  423. package/dist/resolution/session.cjs +335 -0
  424. package/dist/resolution/session.cjs.map +1 -0
  425. package/dist/resolution/session.d.cts +105 -0
  426. package/dist/resolution/session.d.mts +105 -0
  427. package/dist/resolution/session.mjs +331 -0
  428. package/dist/resolution/session.mjs.map +1 -0
  429. package/dist/rollback.cjs +131 -0
  430. package/dist/rollback.cjs.map +1 -0
  431. package/dist/rollback.mjs +128 -0
  432. package/dist/rollback.mjs.map +1 -0
  433. package/dist/sdk.cjs +7 -7
  434. package/dist/sdk.d.cts +3 -3
  435. package/dist/sdk.d.mts +3 -3
  436. package/dist/sdk.mjs +2 -2
  437. package/dist/service-descriptor.cjs +67 -34
  438. package/dist/service-descriptor.cjs.map +1 -1
  439. package/dist/service-descriptor.d.cts +4 -1
  440. package/dist/service-descriptor.d.mts +3 -0
  441. package/dist/service-descriptor.mjs +63 -35
  442. package/dist/service-descriptor.mjs.map +1 -1
  443. package/dist/shared-deps.cjs +17 -16
  444. package/dist/shared-deps.cjs.map +1 -1
  445. package/dist/shared-deps.mjs +17 -16
  446. package/dist/shared-deps.mjs.map +1 -1
  447. package/dist/start-config-source.cjs +24 -0
  448. package/dist/start-config-source.cjs.map +1 -0
  449. package/dist/start-config-source.d.cts +29 -0
  450. package/dist/start-config-source.d.mts +29 -0
  451. package/dist/start-config-source.mjs +22 -0
  452. package/dist/start-config-source.mjs.map +1 -0
  453. package/dist/storage-upload.cjs +145 -0
  454. package/dist/storage-upload.cjs.map +1 -0
  455. package/dist/storage-upload.mjs +143 -0
  456. package/dist/storage-upload.mjs.map +1 -0
  457. package/dist/types.cjs +126 -20
  458. package/dist/types.cjs.map +1 -1
  459. package/dist/types.d.cts +867 -585
  460. package/dist/types.d.mts +867 -585
  461. package/dist/types.mjs +307 -208
  462. package/dist/types.mjs.map +1 -1
  463. package/dist/ui/api.cjs +105 -0
  464. package/dist/ui/api.cjs.map +1 -0
  465. package/dist/ui/api.d.cts +31 -0
  466. package/dist/ui/api.d.mts +31 -0
  467. package/dist/ui/api.mjs +99 -0
  468. package/dist/ui/api.mjs.map +1 -0
  469. package/dist/ui/auth-guards.cjs +50 -0
  470. package/dist/ui/auth-guards.cjs.map +1 -0
  471. package/dist/ui/auth-guards.d.cts +39 -0
  472. package/dist/ui/auth-guards.d.mts +39 -0
  473. package/dist/ui/auth-guards.mjs +48 -0
  474. package/dist/ui/auth-guards.mjs.map +1 -0
  475. package/dist/ui/auth.cjs +197 -0
  476. package/dist/ui/auth.cjs.map +1 -0
  477. package/dist/ui/auth.d.cts +56 -0
  478. package/dist/ui/auth.d.mts +56 -0
  479. package/dist/ui/auth.mjs +179 -0
  480. package/dist/ui/auth.mjs.map +1 -0
  481. package/dist/ui/entry.cjs +16 -0
  482. package/dist/ui/entry.cjs.map +1 -0
  483. package/dist/ui/entry.d.cts +12 -0
  484. package/dist/ui/entry.d.mts +12 -0
  485. package/dist/ui/entry.mjs +15 -0
  486. package/dist/ui/entry.mjs.map +1 -0
  487. package/dist/ui/head.cjs +14 -7
  488. package/dist/ui/head.cjs.map +1 -1
  489. package/dist/ui/head.mjs +15 -7
  490. package/dist/ui/head.mjs.map +1 -1
  491. package/dist/ui/hydrate.cjs +265 -0
  492. package/dist/ui/hydrate.cjs.map +1 -0
  493. package/dist/ui/hydrate.d.cts +48 -0
  494. package/dist/ui/hydrate.d.mts +48 -0
  495. package/dist/ui/hydrate.mjs +263 -0
  496. package/dist/ui/hydrate.mjs.map +1 -0
  497. package/dist/ui/i18n.cjs +153 -0
  498. package/dist/ui/i18n.cjs.map +1 -0
  499. package/dist/ui/i18n.d.cts +29 -0
  500. package/dist/ui/i18n.d.mts +29 -0
  501. package/dist/ui/i18n.mjs +140 -0
  502. package/dist/ui/i18n.mjs.map +1 -0
  503. package/dist/ui/index.cjs +19 -1
  504. package/dist/ui/index.d.cts +6 -3
  505. package/dist/ui/index.d.mts +6 -3
  506. package/dist/ui/index.mjs +5 -2
  507. package/dist/ui/locale.cjs +53 -0
  508. package/dist/ui/locale.cjs.map +1 -0
  509. package/dist/ui/locale.d.cts +18 -0
  510. package/dist/ui/locale.d.mts +18 -0
  511. package/dist/ui/locale.mjs +49 -0
  512. package/dist/ui/locale.mjs.map +1 -0
  513. package/dist/ui/manifest/index.cjs +25 -0
  514. package/dist/ui/manifest/index.cjs.map +1 -0
  515. package/dist/ui/manifest/index.d.cts +9 -0
  516. package/dist/ui/manifest/index.d.mts +9 -0
  517. package/dist/ui/manifest/index.mjs +13 -0
  518. package/dist/ui/manifest/index.mjs.map +1 -0
  519. package/dist/ui/manifest-generator.cjs +8 -0
  520. package/dist/ui/manifest-generator.d.cts +1 -0
  521. package/dist/ui/manifest-generator.d.mts +1 -0
  522. package/dist/ui/manifest-generator.mjs +3 -0
  523. package/dist/ui/message-catalogs.cjs +8 -0
  524. package/dist/ui/message-catalogs.cjs.map +1 -0
  525. package/dist/ui/message-catalogs.d.cts +5 -0
  526. package/dist/ui/message-catalogs.d.mts +5 -0
  527. package/dist/ui/message-catalogs.mjs +8 -0
  528. package/dist/ui/message-catalogs.mjs.map +1 -0
  529. package/dist/ui/metadata.cjs +0 -1
  530. package/dist/ui/metadata.cjs.map +1 -1
  531. package/dist/ui/metadata.d.cts +1 -1
  532. package/dist/ui/metadata.d.mts +1 -1
  533. package/dist/ui/plugin-path.cjs +37 -0
  534. package/dist/ui/plugin-path.cjs.map +1 -0
  535. package/dist/ui/plugin-path.d.cts +25 -0
  536. package/dist/ui/plugin-path.d.mts +25 -0
  537. package/dist/ui/plugin-path.mjs +35 -0
  538. package/dist/ui/plugin-path.mjs.map +1 -0
  539. package/dist/ui/router-client.cjs +61 -0
  540. package/dist/ui/router-client.cjs.map +1 -0
  541. package/dist/ui/router-client.d.cts +20 -0
  542. package/dist/ui/router-client.d.mts +20 -0
  543. package/dist/ui/router-client.mjs +60 -0
  544. package/dist/ui/router-client.mjs.map +1 -0
  545. package/dist/ui/router-defaults.cjs +48 -0
  546. package/dist/ui/router-defaults.cjs.map +1 -0
  547. package/dist/ui/router-defaults.d.cts +8 -0
  548. package/dist/ui/router-defaults.d.mts +8 -0
  549. package/dist/ui/router-defaults.mjs +45 -0
  550. package/dist/ui/router-defaults.mjs.map +1 -0
  551. package/dist/ui/router-error.cjs +70 -0
  552. package/dist/ui/router-error.cjs.map +1 -0
  553. package/dist/ui/router-error.d.cts +19 -0
  554. package/dist/ui/router-error.d.mts +19 -0
  555. package/dist/ui/router-error.mjs +69 -0
  556. package/dist/ui/router-error.mjs.map +1 -0
  557. package/dist/ui/router-server.cjs +153 -0
  558. package/dist/ui/router-server.cjs.map +1 -0
  559. package/dist/ui/router-server.d.cts +38 -0
  560. package/dist/ui/router-server.d.mts +38 -0
  561. package/dist/ui/router-server.mjs +152 -0
  562. package/dist/ui/router-server.mjs.map +1 -0
  563. package/dist/ui/router.cjs +4 -16
  564. package/dist/ui/router.cjs.map +1 -1
  565. package/dist/ui/router.mjs +4 -15
  566. package/dist/ui/router.mjs.map +1 -1
  567. package/dist/ui/runtime.cjs +5 -1
  568. package/dist/ui/runtime.cjs.map +1 -1
  569. package/dist/ui/runtime.d.cts +2 -1
  570. package/dist/ui/runtime.d.mts +2 -1
  571. package/dist/ui/runtime.mjs +5 -1
  572. package/dist/ui/runtime.mjs.map +1 -1
  573. package/dist/ui/slot.cjs +34 -0
  574. package/dist/ui/slot.cjs.map +1 -0
  575. package/dist/ui/slot.d.cts +43 -0
  576. package/dist/ui/slot.d.mts +43 -0
  577. package/dist/ui/slot.mjs +34 -0
  578. package/dist/ui/slot.mjs.map +1 -0
  579. package/dist/ui/tenant.cjs +300 -0
  580. package/dist/ui/tenant.cjs.map +1 -0
  581. package/dist/ui/tenant.d.cts +122 -0
  582. package/dist/ui/tenant.d.mts +122 -0
  583. package/dist/ui/tenant.mjs +279 -0
  584. package/dist/ui/tenant.mjs.map +1 -0
  585. package/dist/ui/types.d.cts +32 -2
  586. package/dist/ui/types.d.mts +32 -2
  587. package/dist/ui/version-check.cjs +47 -0
  588. package/dist/ui/version-check.cjs.map +1 -0
  589. package/dist/ui/version-check.d.cts +23 -0
  590. package/dist/ui/version-check.d.mts +23 -0
  591. package/dist/ui/version-check.mjs +46 -0
  592. package/dist/ui/version-check.mjs.map +1 -0
  593. package/dist/utils/banner.cjs +2 -2
  594. package/dist/utils/banner.cjs.map +1 -1
  595. package/dist/utils/banner.mjs +2 -2
  596. package/dist/utils/banner.mjs.map +1 -1
  597. package/dist/utils/linkify.cjs +1 -1
  598. package/dist/utils/linkify.cjs.map +1 -1
  599. package/dist/utils/linkify.mjs +1 -0
  600. package/dist/utils/linkify.mjs.map +1 -1
  601. package/dist/utils/run.cjs +6 -6
  602. package/dist/utils/run.cjs.map +1 -1
  603. package/dist/utils/run.mjs +6 -6
  604. package/dist/utils/run.mjs.map +1 -1
  605. package/dist/utils/save-config.cjs +12 -0
  606. package/dist/utils/save-config.cjs.map +1 -1
  607. package/dist/utils/save-config.mjs +12 -0
  608. package/dist/utils/save-config.mjs.map +1 -1
  609. package/dist/utils/snapshot-hash.cjs +10 -0
  610. package/dist/utils/snapshot-hash.cjs.map +1 -0
  611. package/dist/utils/snapshot-hash.mjs +10 -0
  612. package/dist/utils/snapshot-hash.mjs.map +1 -0
  613. package/dist/utils/string.cjs +0 -1
  614. package/dist/utils/string.cjs.map +1 -1
  615. package/dist/utils/theme.cjs +30 -12
  616. package/dist/utils/theme.cjs.map +1 -1
  617. package/dist/utils/theme.mjs +30 -11
  618. package/dist/utils/theme.mjs.map +1 -1
  619. package/dist/version-manifest-deploy.cjs +50 -0
  620. package/dist/version-manifest-deploy.cjs.map +1 -0
  621. package/dist/version-manifest-deploy.mjs +49 -0
  622. package/dist/version-manifest-deploy.mjs.map +1 -0
  623. package/dist/version-manifest-resolve.cjs +42 -0
  624. package/dist/version-manifest-resolve.cjs.map +1 -0
  625. package/dist/version-manifest-resolve.d.cts +38 -0
  626. package/dist/version-manifest-resolve.d.mts +38 -0
  627. package/dist/version-manifest-resolve.mjs +40 -0
  628. package/dist/version-manifest-resolve.mjs.map +1 -0
  629. package/dist/version-status.cjs +18 -0
  630. package/dist/version-status.cjs.map +1 -0
  631. package/dist/version-status.d.cts +22 -0
  632. package/dist/version-status.d.mts +22 -0
  633. package/dist/version-status.mjs +17 -0
  634. package/dist/version-status.mjs.map +1 -0
  635. package/dist/workspace-catalog.cjs +53 -0
  636. package/dist/workspace-catalog.cjs.map +1 -0
  637. package/dist/workspace-catalog.mjs +51 -0
  638. package/dist/workspace-catalog.mjs.map +1 -0
  639. package/dist/workspace.cjs +237 -0
  640. package/dist/workspace.cjs.map +1 -0
  641. package/dist/workspace.mjs +233 -0
  642. package/dist/workspace.mjs.map +1 -0
  643. package/package.json +179 -27
  644. package/skills/add-a-route/SKILL.md +132 -0
  645. package/skills/api-and-auth/SKILL.md +87 -21
  646. package/skills/api-and-auth/references/middleware.md +1 -1
  647. package/skills/cli-reference/SKILL.md +48 -21
  648. package/skills/code-style/SKILL.md +8 -0
  649. package/skills/dev-workflow/SKILL.md +50 -26
  650. package/skills/extends-config/SKILL.md +31 -19
  651. package/skills/init-upgrade/SKILL.md +29 -16
  652. package/skills/plugin-development/SKILL.md +46 -112
  653. package/skills/plugin-development/references/database.md +82 -0
  654. package/skills/plugin-development/references/request-context.md +67 -0
  655. package/skills/publish-sync/SKILL.md +99 -22
  656. package/skills/registry/SKILL.md +82 -0
  657. package/skills/super-app/SKILL.md +25 -15
  658. package/skills/talk-to-the-app/SKILL.md +138 -0
  659. package/skills/ui-integration/SKILL.md +93 -11
  660. package/dist/cli/db-studio.cjs +0 -131
  661. package/dist/cli/db-studio.cjs.map +0 -1
  662. package/dist/cli/db-studio.mjs +0 -127
  663. package/dist/cli/db-studio.mjs.map +0 -1
  664. package/dist/cli/init.d.cts.map +0 -1
  665. package/dist/cli/init.d.mts.map +0 -1
  666. package/dist/components/dev-view.cjs +0 -309
  667. package/dist/components/dev-view.cjs.map +0 -1
  668. package/dist/components/dev-view.mjs +0 -309
  669. package/dist/components/dev-view.mjs.map +0 -1
  670. package/dist/components/streaming-view.cjs +0 -134
  671. package/dist/components/streaming-view.cjs.map +0 -1
  672. package/dist/components/streaming-view.mjs +0 -132
  673. package/dist/components/streaming-view.mjs.map +0 -1
  674. package/dist/config.d.cts.map +0 -1
  675. package/dist/config.d.mts.map +0 -1
  676. package/dist/contract.d.cts.map +0 -1
  677. package/dist/contract.d.mts.map +0 -1
  678. package/dist/contract.meta.d.cts.map +0 -1
  679. package/dist/contract.meta.d.mts.map +0 -1
  680. package/dist/dag.d.cts.map +0 -1
  681. package/dist/dag.d.mts.map +0 -1
  682. package/dist/db.cjs +0 -81
  683. package/dist/db.cjs.map +0 -1
  684. package/dist/db.d.cts +0 -30
  685. package/dist/db.d.cts.map +0 -1
  686. package/dist/db.d.mts +0 -30
  687. package/dist/db.d.mts.map +0 -1
  688. package/dist/db.mjs +0 -75
  689. package/dist/db.mjs.map +0 -1
  690. package/dist/fastkv.d.cts.map +0 -1
  691. package/dist/fastkv.d.mts.map +0 -1
  692. package/dist/integrity.d.cts.map +0 -1
  693. package/dist/integrity.d.mts.map +0 -1
  694. package/dist/merge.d.cts.map +0 -1
  695. package/dist/merge.d.mts.map +0 -1
  696. package/dist/mf.d.cts.map +0 -1
  697. package/dist/mf.d.mts.map +0 -1
  698. package/dist/plugin.d.cts.map +0 -1
  699. package/dist/plugin.d.mts.map +0 -1
  700. package/dist/service-descriptor.d.cts.map +0 -1
  701. package/dist/service-descriptor.d.mts.map +0 -1
  702. package/dist/types.d.cts.map +0 -1
  703. package/dist/types.d.mts.map +0 -1
  704. package/dist/ui/head.d.cts.map +0 -1
  705. package/dist/ui/head.d.mts.map +0 -1
  706. package/dist/ui/metadata.d.cts.map +0 -1
  707. package/dist/ui/metadata.d.mts.map +0 -1
  708. package/dist/ui/router.d.cts.map +0 -1
  709. package/dist/ui/router.d.mts.map +0 -1
  710. package/dist/ui/runtime.d.cts.map +0 -1
  711. package/dist/ui/runtime.d.mts.map +0 -1
  712. package/dist/ui/types.d.cts.map +0 -1
  713. package/dist/ui/types.d.mts.map +0 -1
@@ -1,17 +1,15 @@
1
+ import { buildDescription, isAuthMirrorPluginEntry } from "../service-descriptor.mjs";
1
2
  import { PortAllocator } from "../app.mjs";
2
- import { buildDatabaseConfigs, buildOriginMap, buildRedisConfigs, getSecretGroups, loadPortState, savePortState } from "../cli/infra.mjs";
3
- import { buildDescription } from "../service-descriptor.mjs";
3
+ import { buildConventionalDatabases, buildConventionalRedis, getSecretGroups, loadPortState, savePortState } from "../cli/infra.mjs";
4
4
  import { InfraError } from "./types.mjs";
5
+ import { shouldPersistPortState } from "./materializer.mjs";
6
+ import { ownerOfPort } from "./port-ownership.mjs";
5
7
  import { resolve } from "node:path";
8
+ import { Clock, Effect } from "effect";
6
9
  import { createHash } from "node:crypto";
7
- import { Effect } from "effect";
8
10
 
9
11
  //#region src/infra/planner.ts
10
12
  const DEFAULT_HOST_PORT = 3e3;
11
- const DEFAULT_API_PORT = 3001;
12
- const DEFAULT_AUTH_PORT = 3002;
13
- const DEFAULT_UI_PORT = 3003;
14
- const DEFAULT_PLUGIN_PORT_START = 3010;
15
13
  const POSTGRES_USER = "everythingdev";
16
14
  const POSTGRES_PASSWORD = "everythingdev";
17
15
  function workspaceKey(configDir) {
@@ -23,68 +21,98 @@ function normalizeCliPorts(input) {
23
21
  api: input.apiPort,
24
22
  auth: input.authPort,
25
23
  ui: input.uiPort,
26
- uiSsr: void 0,
27
24
  pluginsStart: input.pluginPortStart,
28
25
  plugins: input.plugins
29
26
  };
30
27
  }
31
- function allocateServices(cliPorts, plugins, configDir) {
28
+ const PLUGIN_START_OFFSET = 10;
29
+ const BLOCK_STEP = 100;
30
+ function allocateServices(cliPorts, plugins, configDir, auth, sources) {
32
31
  return Effect.gen(function* () {
33
32
  const wKey = workspaceKey(configDir);
34
33
  const persisted = loadPortState(configDir).devPorts;
35
34
  const allocator = yield* PortAllocator;
36
- const hostPort = yield* allocator.pickAvailable(cliPorts.host ?? persisted?.host ?? DEFAULT_HOST_PORT);
37
- const apiPort = yield* allocator.pickAvailable(cliPorts.api ?? persisted?.api ?? DEFAULT_API_PORT);
38
- const authPort = yield* allocator.pickAvailable(cliPorts.auth ?? persisted?.auth ?? DEFAULT_AUTH_PORT);
39
- const uiPort = yield* allocator.pickAvailable(cliPorts.ui ?? persisted?.ui ?? DEFAULT_UI_PORT);
40
- const uiSsrPort = yield* allocator.pickAvailable(cliPorts.uiSsr ?? uiPort + 1);
41
- const pluginApiPorts = {};
42
- const pluginUiPorts = {};
35
+ const base = cliPorts.host ?? persisted?.host ?? DEFAULT_HOST_PORT;
36
+ const pluginStartPreferred = cliPorts.pluginsStart ?? persisted?.pluginPortStart ?? base + PLUGIN_START_OFFSET;
37
+ const pluginStartPinned = cliPorts.pluginsStart !== void 0 || persisted?.pluginPortStart !== void 0;
38
+ const entries = [];
39
+ const addEntry = (key, flag, persistedValue, derived) => {
40
+ if (flag !== void 0) entries.push({
41
+ key,
42
+ preferred: flag,
43
+ pinned: true
44
+ });
45
+ else if (persistedValue !== void 0) entries.push({
46
+ key,
47
+ preferred: persistedValue,
48
+ pinned: true
49
+ });
50
+ else entries.push({
51
+ key,
52
+ preferred: derived,
53
+ pinned: false
54
+ });
55
+ };
56
+ addEntry("host", cliPorts.host, void 0, base);
57
+ if (sources?.api !== "remote") addEntry("api", cliPorts.api, persisted?.api, base + 1);
58
+ if (sources?.auth !== "remote") addEntry("auth", cliPorts.auth, persisted?.auth, base + 2);
59
+ if (sources?.ui !== "remote") addEntry("ui", cliPorts.ui, persisted?.ui, base + 3);
43
60
  const pluginKeys = Object.keys(plugins).sort();
44
- const pluginStart = cliPorts.pluginsStart ?? persisted?.pluginPortStart ?? DEFAULT_PLUGIN_PORT_START;
45
- let nextPluginPort = pluginStart;
61
+ const isAuthMirrorFor = (pluginId, pluginCfg) => pluginCfg !== void 0 && isAuthMirrorPluginEntry(auth, pluginId, pluginCfg);
62
+ let pluginSlot = 0;
46
63
  for (const pluginId of pluginKeys) {
47
64
  const pluginCfg = plugins[pluginId];
48
- const preferred = cliPorts.plugins?.[pluginId]?.api ?? nextPluginPort;
49
- const pluginPort = yield* allocator.pickAvailable(preferred);
50
- pluginApiPorts[pluginId] = pluginPort;
51
- nextPluginPort = pluginPort + 1;
65
+ const pluginIsLocal = pluginCfg?.source === "local";
66
+ const slotBase = pluginStartPinned ? pluginStartPreferred : base + PLUGIN_START_OFFSET;
67
+ if (!isAuthMirrorFor(pluginId, pluginCfg) && pluginIsLocal) {
68
+ addEntry(`plugin:${pluginId}`, cliPorts.plugins?.[pluginId]?.api, void 0, slotBase + pluginSlot);
69
+ pluginSlot += 1;
70
+ }
52
71
  if (pluginCfg?.source === "local" && pluginCfg?.localPath && pluginCfg?.ui?.source === "local") {
53
- const uiPreferred = cliPorts.plugins?.[pluginId]?.ui ?? nextPluginPort;
54
- const pluginUiPort = yield* allocator.pickAvailable(uiPreferred);
55
- pluginUiPorts[pluginId] = pluginUiPort;
56
- nextPluginPort = pluginUiPort + 1;
72
+ addEntry(`plugin-ui:${pluginId}`, cliPorts.plugins?.[pluginId]?.ui, void 0, slotBase + pluginSlot);
73
+ pluginSlot += 1;
57
74
  }
58
75
  }
76
+ const allocation = yield* allocator.acquireBlock({
77
+ base,
78
+ step: BLOCK_STEP,
79
+ entries
80
+ });
81
+ if (allocation.base !== base) {
82
+ yield* Effect.logError(`[Dev] Preferred port block starting at ${base} is occupied — using ${allocation.base} (this run only; restarts will retry ${base})`);
83
+ for (const conflict of allocation.conflicts.slice(0, 6)) if (conflict.claimed) yield* Effect.logError(`[Dev] port ${conflict.port} (${conflict.key}) — live bos session (registry claim)`);
84
+ else {
85
+ const owner = yield* ownerOfPort(conflict.port);
86
+ yield* Effect.logError(`[Dev] port ${conflict.port} (${conflict.key}) — ${owner ? `pid ${owner.pid} (${owner.command})` : "foreign holder (lsof unavailable)"}`);
87
+ }
88
+ }
89
+ const pluginApiPorts = {};
90
+ const pluginUiPorts = {};
91
+ for (const pluginId of pluginKeys) {
92
+ const api = allocation.ports[`plugin:${pluginId}`];
93
+ if (api !== void 0) pluginApiPorts[pluginId] = api;
94
+ const ui = allocation.ports[`plugin-ui:${pluginId}`];
95
+ if (ui !== void 0) pluginUiPorts[pluginId] = ui;
96
+ }
59
97
  const resolved = {
60
- host: hostPort,
61
- api: apiPort,
62
- auth: authPort,
63
- ui: uiPort,
64
- uiSsr: uiSsrPort,
65
- plugins: Object.fromEntries(Object.entries(pluginApiPorts).map(([k, v]) => [k, {
66
- api: v,
98
+ host: allocation.ports.host,
99
+ api: allocation.ports.api,
100
+ auth: allocation.ports.auth,
101
+ ui: allocation.ports.ui,
102
+ plugins: Object.fromEntries(pluginKeys.map((k) => [k, {
103
+ api: pluginApiPorts[k],
67
104
  ui: pluginUiPorts[k]
68
- }])),
69
- postgres: {},
70
- redis: {}
105
+ }]))
71
106
  };
72
107
  const devPortsState = {
73
- host: hostPort,
74
- api: apiPort,
75
- auth: authPort,
76
- ui: uiPort,
77
- pluginPortStart: pluginStart
78
- };
79
- const claimPorts = {
80
- host: hostPort,
81
- api: apiPort,
82
- auth: authPort,
83
- ui: uiPort,
84
- uiSsr: uiSsrPort
108
+ host: cliPorts.host,
109
+ api: cliPorts.api,
110
+ auth: cliPorts.auth,
111
+ ui: cliPorts.ui,
112
+ pluginPortStart: cliPorts.pluginsStart
85
113
  };
86
- for (const [id, port] of Object.entries(pluginApiPorts)) claimPorts[`plugin:${id}`] = port;
87
- for (const [id, port] of Object.entries(pluginUiPorts)) claimPorts[`plugin-ui:${id}`] = port;
114
+ const claimPorts = {};
115
+ for (const [key, port] of Object.entries(allocation.ports)) claimPorts[key] = port;
88
116
  return {
89
117
  ports: resolved,
90
118
  claims: [{
@@ -92,7 +120,7 @@ function allocateServices(cliPorts, plugins, configDir) {
92
120
  pid: process.pid,
93
121
  configDir,
94
122
  ports: claimPorts,
95
- startedAt: Date.now()
123
+ startedAt: yield* Clock.currentTimeMillis
96
124
  }],
97
125
  devPortsState
98
126
  };
@@ -102,46 +130,40 @@ function allocateServices(cliPorts, plugins, configDir) {
102
130
  cause: portErr
103
131
  })));
104
132
  }
105
- function allocateDatabases(runtimeConfig, configDir) {
133
+ function allocateDatabases(runtimeConfig) {
106
134
  return Effect.gen(function* () {
107
- const persisted = loadPortState(configDir);
108
135
  const allSecrets = getSecretGroups(runtimeConfig).flatMap((group) => group.secrets);
109
- const originMap = buildOriginMap(configDir, runtimeConfig);
110
136
  const allocator = yield* PortAllocator;
111
- const infraDatabases = yield* Effect.sync(() => buildDatabaseConfigs(allSecrets, originMap, { ...persisted.postgresPorts }));
112
- const infraRedis = yield* Effect.sync(() => buildRedisConfigs(allSecrets, originMap, { ...persisted.redisPorts }));
113
- const postgres = {};
137
+ const conventionalDatabases = buildConventionalDatabases(allSecrets);
138
+ const conventionalRedis = buildConventionalRedis(allSecrets);
114
139
  const dbs = [];
115
- for (const db of infraDatabases) {
116
- const port = yield* allocator.pickAvailable(db.port);
117
- postgres[db.slug] = port;
140
+ const allocatedByDesired = /* @__PURE__ */ new Map();
141
+ for (const db of conventionalDatabases) {
142
+ let port;
143
+ if (allocatedByDesired.has(db.port)) port = allocatedByDesired.get(db.port);
144
+ else {
145
+ port = yield* allocator.pickAvailable(db.port);
146
+ allocatedByDesired.set(db.port, port);
147
+ }
118
148
  dbs.push({
119
149
  secret: db.secret,
120
150
  slug: db.slug,
121
151
  port,
122
152
  dbName: db.databaseName,
123
- containerName: db.containerName,
124
- volumeName: db.volumeName,
125
- url: `postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${port}/${db.slug}_db`
153
+ url: `postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${port}/${db.databaseName}`
126
154
  });
127
155
  }
128
- const redis = {};
129
156
  const redisPlans = [];
130
- for (const r of infraRedis) {
157
+ for (const r of conventionalRedis) {
131
158
  const port = yield* allocator.pickAvailable(r.port);
132
- redis[r.slug] = port;
133
159
  redisPlans.push({
134
160
  secret: r.secret,
135
161
  slug: r.slug,
136
162
  port,
137
- containerName: r.containerName,
138
- volumeName: r.volumeName,
139
163
  url: `redis://localhost:${port}`
140
164
  });
141
165
  }
142
166
  return {
143
- postgres,
144
- redis,
145
167
  dbs,
146
168
  redisPlans
147
169
  };
@@ -192,25 +214,19 @@ function buildServiceDescriptors(runtimeConfig, resolvedPorts) {
192
214
  port: isLocal ? resolvedPorts.ui : void 0,
193
215
  localPath: isLocal ? runtimeConfig.ui.localPath : void 0
194
216
  });
195
- if (isLocal && resolvedPorts.uiSsr) descriptors.push({
196
- key: "ui-ssr",
197
- source: "local",
198
- url: `http://localhost:${resolvedPorts.uiSsr}`,
199
- port: resolvedPorts.uiSsr,
200
- localPath: runtimeConfig.ui.localPath
201
- });
202
217
  }
203
218
  if (runtimeConfig.plugins) for (const [pluginId, pluginCfg] of Object.entries(runtimeConfig.plugins)) {
204
219
  const pluginIsLocal = pluginCfg.source === "local";
205
220
  const p = resolvedPorts.plugins[pluginId];
206
- if (pluginIsLocal && p?.api) descriptors.push({
221
+ const isAuthMirror = isAuthMirrorPluginEntry(runtimeConfig.auth, pluginId, pluginCfg);
222
+ if (pluginIsLocal && p?.api && !isAuthMirror) descriptors.push({
207
223
  key: `plugin:${pluginId}`,
208
224
  source: "local",
209
225
  url: `http://localhost:${p.api}`,
210
226
  port: p.api,
211
227
  localPath: pluginCfg.localPath
212
228
  });
213
- if (!pluginIsLocal && pluginCfg.url) descriptors.push({
229
+ if (!pluginIsLocal && pluginCfg.url && !isAuthMirror) descriptors.push({
214
230
  key: `plugin:${pluginId}`,
215
231
  source: "remote",
216
232
  url: pluginCfg.url,
@@ -243,15 +259,12 @@ function buildLaunchSpec(runtimeConfig, resolvedPorts) {
243
259
  runtimeConfig
244
260
  };
245
261
  }
246
- function buildComposeModel(dbs, redisPlans) {
247
- return {
248
- databases: dbs,
249
- redis: redisPlans
250
- };
251
- }
252
262
  function buildEnvGenerated(resolvedPorts, dbs, redisPlans) {
253
263
  const env = {};
254
- if (resolvedPorts.host) env.CORS_ORIGIN = `http://localhost:${resolvedPorts.host}`;
264
+ if (resolvedPorts.host) {
265
+ env.CORS_ORIGIN = `http://localhost:${resolvedPorts.host}`;
266
+ env.BASE_URL = `http://localhost:${resolvedPorts.host}`;
267
+ }
255
268
  for (const db of dbs) env[db.secret] = db.url;
256
269
  for (const r of redisPlans) env[r.secret] = r.url;
257
270
  return env;
@@ -260,18 +273,23 @@ function planInfra(input) {
260
273
  return Effect.gen(function* () {
261
274
  const cliPorts = normalizeCliPorts(input.cli);
262
275
  const wKey = workspaceKey(input.configDir);
263
- const { ports: svcPorts, claims, devPortsState } = yield* allocateServices(cliPorts, input.bosConfig.plugins ?? {}, input.configDir);
264
- const { dbs, redisPlans, postgres: pgPorts, redis: rdPorts } = yield* allocateDatabases(input.bosConfig, input.configDir);
265
- const resolvedPorts = {
266
- ...svcPorts,
267
- postgres: pgPorts,
268
- redis: rdPorts
269
- };
270
- if (process.env.BOS_NO_PERSIST_PORTS !== "1") savePortState(input.configDir, {
271
- postgresPorts: pgPorts,
272
- redisPorts: rdPorts,
273
- devPorts: devPortsState
276
+ const { ports: svcPorts, claims, devPortsState } = yield* allocateServices(cliPorts, input.bosConfig.plugins ?? {}, input.configDir, input.bosConfig.auth, {
277
+ host: input.bosConfig.host?.source,
278
+ api: input.bosConfig.api?.source,
279
+ auth: input.bosConfig.auth?.source,
280
+ ui: input.bosConfig.ui?.source
274
281
  });
282
+ const { dbs, redisPlans } = yield* allocateDatabases(input.bosConfig);
283
+ const resolvedPorts = { ...svcPorts };
284
+ const previousDevPorts = loadPortState(input.configDir).devPorts ?? {};
285
+ const devPorts = {
286
+ host: devPortsState.host ?? previousDevPorts.host,
287
+ api: devPortsState.api ?? previousDevPorts.api,
288
+ auth: devPortsState.auth ?? previousDevPorts.auth,
289
+ ui: devPortsState.ui ?? previousDevPorts.ui,
290
+ pluginPortStart: devPortsState.pluginPortStart ?? previousDevPorts.pluginPortStart
291
+ };
292
+ if (shouldPersistPortState()) savePortState(input.configDir, { devPorts });
275
293
  const hostIsLocal = input.bosConfig.host?.source === "local";
276
294
  const apiIsLocal = input.bosConfig.api?.source === "local";
277
295
  const uiIsLocal = input.bosConfig.ui?.source === "local";
@@ -292,7 +310,8 @@ function planInfra(input) {
292
310
  ui: uiIsLocal && resolvedPorts.ui ? {
293
311
  ...input.bosConfig.ui,
294
312
  port: resolvedPorts.ui,
295
- url: `http://localhost:${resolvedPorts.ui}`
313
+ url: `http://localhost:${resolvedPorts.ui}`,
314
+ ssrUrl: void 0
296
315
  } : input.bosConfig.ui,
297
316
  auth: authIsLocal && resolvedPorts.auth && input.bosConfig.auth ? {
298
317
  ...input.bosConfig.auth,
@@ -300,21 +319,36 @@ function planInfra(input) {
300
319
  url: `http://localhost:${resolvedPorts.auth}`
301
320
  } : input.bosConfig.auth,
302
321
  plugins: input.bosConfig.plugins ? Object.fromEntries(Object.entries(input.bosConfig.plugins).map(([id, p]) => {
322
+ const isAuthMirror = isAuthMirrorPluginEntry(input.bosConfig.auth, id, p);
303
323
  const pluginPort = resolvedPorts.plugins[id];
324
+ const patchedUi = (() => {
325
+ if (p.ui?.source !== "local" || !p.ui?.localPath || !pluginPort?.ui) return p.ui;
326
+ return {
327
+ ...p.ui,
328
+ port: pluginPort.ui,
329
+ url: `http://localhost:${pluginPort.ui}`,
330
+ ssrUrl: void 0
331
+ };
332
+ })();
333
+ if (isAuthMirror) return [id, {
334
+ ...p,
335
+ ui: patchedUi
336
+ }];
304
337
  if (p.source === "local" && pluginPort?.api) return [id, {
305
338
  ...p,
306
339
  port: pluginPort.api,
307
- url: `http://localhost:${pluginPort.api}`
340
+ url: `http://localhost:${pluginPort.api}`,
341
+ ui: patchedUi
308
342
  }];
309
343
  return [id, p];
310
344
  })) : void 0
311
345
  };
312
- const serviceDescriptors = buildServiceDescriptors(input.bosConfig, resolvedPorts);
346
+ const serviceDescriptors = buildServiceDescriptors(assignedRuntimeConfig, resolvedPorts);
313
347
  const launch = buildLaunchSpec(input.bosConfig, resolvedPorts);
314
- const composeModel = buildComposeModel(dbs, redisPlans);
315
348
  const envGenerated = buildEnvGenerated(resolvedPorts, dbs, redisPlans);
316
349
  const packages = serviceDescriptors.map((d) => d.key);
317
- const description = buildDescription(new Map(serviceDescriptors.map((d) => [d.key, d])));
350
+ const descriptionMap = new Map(serviceDescriptors.map((d) => [d.key, d]));
351
+ const description = buildDescription(descriptionMap);
318
352
  const orchestrator = {
319
353
  packages,
320
354
  env: {},
@@ -331,7 +365,6 @@ function planInfra(input) {
331
365
  description,
332
366
  serviceDescriptors: new Map(serviceDescriptors.map((d) => [d.key, d])),
333
367
  envGenerated,
334
- composeModel,
335
368
  claims,
336
369
  orchestrator
337
370
  };
@@ -339,5 +372,5 @@ function planInfra(input) {
339
372
  }
340
373
 
341
374
  //#endregion
342
- export { buildComposeModel, buildEnvGenerated, buildLaunchSpec, buildServiceDescriptors, planInfra, workspaceKey };
375
+ export { buildEnvGenerated, buildLaunchSpec, buildServiceDescriptors, planInfra, workspaceKey };
343
376
  //# sourceMappingURL=planner.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"planner.mjs","names":[],"sources":["../../src/infra/planner.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { resolve } from \"node:path\";\nimport { Effect } from \"effect\";\nimport { PortAllocator } from \"../app\";\nimport {\n buildDatabaseConfigs,\n buildOriginMap,\n buildRedisConfigs,\n type DatabaseSecretConfig,\n getSecretGroups,\n loadPortState,\n type RedisSecretConfig,\n savePortState,\n} from \"../cli/infra\";\nimport { buildDescription } from \"../service-descriptor\";\nimport type { RuntimeConfig } from \"../types\";\nimport type {\n ClaimRecord,\n CliPorts,\n ComposeModelPlan,\n DatabasePlan,\n InfraInput,\n InfraPlan,\n RedisPlan,\n ResolvedPorts,\n RuntimeLaunchSpec,\n ServiceDescriptorPlan,\n} from \"./types\";\nimport { InfraError } from \"./types\";\n\nconst DEFAULT_HOST_PORT = 3000;\nconst DEFAULT_API_PORT = 3001;\nconst DEFAULT_AUTH_PORT = 3002;\nconst DEFAULT_UI_PORT = 3003;\nconst DEFAULT_PLUGIN_PORT_START = 3010;\nconst POSTGRES_USER = \"everythingdev\";\nconst POSTGRES_PASSWORD = \"everythingdev\";\n\nexport function workspaceKey(configDir: string): string {\n const hash = createHash(\"sha256\").update(resolve(configDir)).digest(\"hex\");\n return hash.slice(0, 12);\n}\n\nfunction normalizeCliPorts(input: InfraInput[\"cli\"]): CliPorts {\n return {\n host: input.port,\n api: input.apiPort,\n auth: input.authPort,\n ui: input.uiPort,\n uiSsr: undefined,\n pluginsStart: input.pluginPortStart,\n plugins: input.plugins,\n };\n}\n\ninterface AllocateServicesResult {\n ports: ResolvedPorts;\n claims: ClaimRecord[];\n devPortsState: { host: number; api: number; auth: number; ui: number; pluginPortStart: number };\n}\n\nfunction allocateServices(\n cliPorts: CliPorts,\n plugins: Record<\n string,\n { source: string; localPath?: string; ui?: { source: string; localPath?: string } }\n >,\n configDir: string,\n): Effect.Effect<AllocateServicesResult, InfraError, PortAllocator> {\n return Effect.gen(function* () {\n const wKey = workspaceKey(configDir);\n const persisted = loadPortState(configDir).devPorts;\n const allocator = yield* PortAllocator;\n\n const hostPort = yield* allocator.pickAvailable(\n cliPorts.host ?? persisted?.host ?? DEFAULT_HOST_PORT,\n );\n\n const apiPort = yield* allocator.pickAvailable(\n cliPorts.api ?? persisted?.api ?? DEFAULT_API_PORT,\n );\n\n const authPort = yield* allocator.pickAvailable(\n cliPorts.auth ?? persisted?.auth ?? DEFAULT_AUTH_PORT,\n );\n\n const uiPort = yield* allocator.pickAvailable(cliPorts.ui ?? persisted?.ui ?? DEFAULT_UI_PORT);\n\n const uiSsrPort = yield* allocator.pickAvailable(cliPorts.uiSsr ?? uiPort + 1);\n\n const pluginApiPorts: Record<string, number> = {};\n const pluginUiPorts: Record<string, number> = {};\n\n const pluginKeys = Object.keys(plugins).sort();\n const pluginStart =\n cliPorts.pluginsStart ?? persisted?.pluginPortStart ?? DEFAULT_PLUGIN_PORT_START;\n let nextPluginPort = pluginStart;\n for (const pluginId of pluginKeys) {\n const pluginCfg = plugins[pluginId];\n const preferred = cliPorts.plugins?.[pluginId]?.api ?? nextPluginPort;\n const pluginPort = yield* allocator.pickAvailable(preferred);\n pluginApiPorts[pluginId] = pluginPort;\n nextPluginPort = pluginPort + 1;\n\n if (\n pluginCfg?.source === \"local\" &&\n pluginCfg?.localPath &&\n pluginCfg?.ui?.source === \"local\"\n ) {\n const uiPreferred = cliPorts.plugins?.[pluginId]?.ui ?? nextPluginPort;\n const pluginUiPort = yield* allocator.pickAvailable(uiPreferred);\n pluginUiPorts[pluginId] = pluginUiPort;\n nextPluginPort = pluginUiPort + 1;\n }\n }\n\n const resolved: ResolvedPorts = {\n host: hostPort,\n api: apiPort,\n auth: authPort,\n ui: uiPort,\n uiSsr: uiSsrPort,\n plugins: Object.fromEntries(\n Object.entries(pluginApiPorts).map(([k, v]) => [k, { api: v, ui: pluginUiPorts[k] }]),\n ),\n postgres: {},\n redis: {},\n };\n\n const devPortsState = {\n host: hostPort,\n api: apiPort,\n auth: authPort,\n ui: uiPort,\n pluginPortStart: pluginStart,\n };\n\n const claimPorts: Record<string, number> = {\n host: hostPort,\n api: apiPort,\n auth: authPort,\n ui: uiPort,\n uiSsr: uiSsrPort,\n };\n for (const [id, port] of Object.entries(pluginApiPorts)) {\n claimPorts[`plugin:${id}`] = port;\n }\n for (const [id, port] of Object.entries(pluginUiPorts)) {\n claimPorts[`plugin-ui:${id}`] = port;\n }\n\n const claim: ClaimRecord = {\n resourceKey: `workspace:${wKey}`,\n pid: process.pid,\n configDir,\n ports: claimPorts,\n startedAt: Date.now(),\n };\n\n return { ports: resolved, claims: [claim], devPortsState };\n }).pipe(\n Effect.mapError(\n (portErr) =>\n new InfraError({\n phase: \"allocate-services\",\n message: `Port allocation failed: ${String(portErr)}`,\n cause: portErr,\n }),\n ),\n );\n}\n\nfunction allocateDatabases(\n runtimeConfig: RuntimeConfig,\n configDir: string,\n): Effect.Effect<\n {\n postgres: Record<string, number>;\n redis: Record<string, number>;\n dbs: DatabasePlan[];\n redisPlans: RedisPlan[];\n },\n InfraError,\n PortAllocator\n> {\n return Effect.gen(function* () {\n const persisted = loadPortState(configDir);\n const groups = getSecretGroups(runtimeConfig);\n const allSecrets = groups.flatMap((group) => group.secrets);\n const originMap = buildOriginMap(configDir, runtimeConfig);\n const allocator = yield* PortAllocator;\n\n const infraDatabases: DatabaseSecretConfig[] = yield* Effect.sync(() =>\n buildDatabaseConfigs(allSecrets, originMap, { ...persisted.postgresPorts }),\n );\n const infraRedis: RedisSecretConfig[] = yield* Effect.sync(() =>\n buildRedisConfigs(allSecrets, originMap, { ...persisted.redisPorts }),\n );\n\n const postgres: Record<string, number> = {};\n const dbs: DatabasePlan[] = [];\n for (const db of infraDatabases) {\n const port = yield* allocator.pickAvailable(db.port);\n postgres[db.slug] = port;\n dbs.push({\n secret: db.secret,\n slug: db.slug,\n port,\n dbName: db.databaseName,\n containerName: db.containerName,\n volumeName: db.volumeName,\n url: `postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${port}/${db.slug}_db`,\n });\n }\n\n const redis: Record<string, number> = {};\n const redisPlans: RedisPlan[] = [];\n for (const r of infraRedis) {\n const port = yield* allocator.pickAvailable(r.port);\n redis[r.slug] = port;\n redisPlans.push({\n secret: r.secret,\n slug: r.slug,\n port,\n containerName: r.containerName,\n volumeName: r.volumeName,\n url: `redis://localhost:${port}`,\n });\n }\n\n return { postgres, redis, dbs, redisPlans };\n }).pipe(\n Effect.mapError(\n (portErr) =>\n new InfraError({\n phase: \"allocate-databases\",\n message: `Database port allocation failed: ${String(portErr)}`,\n cause: portErr,\n }),\n ),\n );\n}\n\nexport function buildServiceDescriptors(\n runtimeConfig: RuntimeConfig,\n resolvedPorts: ResolvedPorts,\n): ServiceDescriptorPlan[] {\n const descriptors: ServiceDescriptorPlan[] = [];\n\n if (runtimeConfig.host) {\n const isLocal = runtimeConfig.host.source === \"local\";\n descriptors.push({\n key: \"host\",\n source: runtimeConfig.host.source,\n url: isLocal ? `http://localhost:${resolvedPorts.host}` : runtimeConfig.host.url,\n port: isLocal ? resolvedPorts.host : undefined,\n localPath: isLocal ? runtimeConfig.host.localPath : undefined,\n });\n }\n\n if (runtimeConfig.api) {\n const isLocal = runtimeConfig.api.source === \"local\";\n descriptors.push({\n key: \"api\",\n source: runtimeConfig.api.source,\n url: isLocal ? `http://localhost:${resolvedPorts.api}` : runtimeConfig.api.url,\n port: isLocal ? resolvedPorts.api : undefined,\n localPath: isLocal ? runtimeConfig.api.localPath : undefined,\n });\n }\n\n if (runtimeConfig.auth) {\n const isLocal = runtimeConfig.auth.source === \"local\";\n descriptors.push({\n key: \"auth\",\n source: runtimeConfig.auth.source,\n url: isLocal ? `http://localhost:${resolvedPorts.auth}` : runtimeConfig.auth.url,\n port: isLocal ? resolvedPorts.auth : undefined,\n localPath: isLocal ? runtimeConfig.auth.localPath : undefined,\n });\n }\n\n if (runtimeConfig.ui) {\n const isLocal = runtimeConfig.ui.source === \"local\";\n descriptors.push({\n key: \"ui\",\n source: runtimeConfig.ui.source,\n url: isLocal ? `http://localhost:${resolvedPorts.ui}` : runtimeConfig.ui.url,\n port: isLocal ? resolvedPorts.ui : undefined,\n localPath: isLocal ? runtimeConfig.ui.localPath : undefined,\n });\n if (isLocal && resolvedPorts.uiSsr) {\n descriptors.push({\n key: \"ui-ssr\",\n source: \"local\",\n url: `http://localhost:${resolvedPorts.uiSsr}`,\n port: resolvedPorts.uiSsr,\n localPath: runtimeConfig.ui.localPath,\n });\n }\n }\n\n if (runtimeConfig.plugins) {\n for (const [pluginId, pluginCfg] of Object.entries(runtimeConfig.plugins)) {\n const pluginIsLocal = pluginCfg.source === \"local\";\n const p = resolvedPorts.plugins[pluginId];\n if (pluginIsLocal && p?.api) {\n descriptors.push({\n key: `plugin:${pluginId}`,\n source: \"local\",\n url: `http://localhost:${p.api}`,\n port: p.api,\n localPath: pluginCfg.localPath,\n });\n }\n if (!pluginIsLocal && pluginCfg.url) {\n descriptors.push({\n key: `plugin:${pluginId}`,\n source: \"remote\",\n url: pluginCfg.url,\n port: undefined,\n localPath: undefined,\n });\n }\n if (pluginIsLocal && p?.ui && pluginCfg.ui?.source === \"local\") {\n descriptors.push({\n key: `plugin-ui:${pluginId}`,\n source: \"local\",\n url: `http://localhost:${p.ui}`,\n port: p.ui,\n localPath: pluginCfg.ui?.localPath,\n });\n }\n }\n }\n\n return descriptors;\n}\n\nexport function buildLaunchSpec(\n runtimeConfig: RuntimeConfig,\n resolvedPorts: ResolvedPorts,\n): RuntimeLaunchSpec {\n const hostPort =\n runtimeConfig.host?.source === \"local\" ? resolvedPorts.host : runtimeConfig.host?.port;\n const corsOrigin = hostPort ? `http://localhost:${hostPort}` : `http://localhost:3000`;\n\n return {\n port: resolvedPorts.host,\n hostUrl: runtimeConfig.host?.url,\n corsOrigin,\n env: {\n ...(resolvedPorts.host ? { PORT: String(resolvedPorts.host) } : {}),\n ...(resolvedPorts.api ? { API_PORT: String(resolvedPorts.api) } : {}),\n ...(resolvedPorts.ui ? { UI_PORT: String(resolvedPorts.ui) } : {}),\n ...(resolvedPorts.auth ? { AUTH_PORT: String(resolvedPorts.auth) } : {}),\n },\n runtimeConfig,\n };\n}\n\nexport function buildComposeModel(dbs: DatabasePlan[], redisPlans: RedisPlan[]): ComposeModelPlan {\n return { databases: dbs, redis: redisPlans };\n}\n\nexport function buildEnvGenerated(\n resolvedPorts: ResolvedPorts,\n dbs: DatabasePlan[],\n redisPlans: RedisPlan[],\n): Record<string, string> {\n const env: Record<string, string> = {};\n\n if (resolvedPorts.host) {\n env.CORS_ORIGIN = `http://localhost:${resolvedPorts.host}`;\n }\n\n for (const db of dbs) {\n env[db.secret] = db.url;\n }\n for (const r of redisPlans) {\n env[r.secret] = r.url;\n }\n\n return env;\n}\n\nexport function planInfra(input: InfraInput): Effect.Effect<InfraPlan, InfraError, PortAllocator> {\n return Effect.gen(function* () {\n const cliPorts = normalizeCliPorts(input.cli);\n const wKey = workspaceKey(input.configDir);\n\n const plugins = (input.bosConfig.plugins ?? {}) as Record<\n string,\n { source: string; localPath?: string; ui?: { source: string; localPath?: string } }\n >;\n\n const {\n ports: svcPorts,\n claims,\n devPortsState,\n } = yield* allocateServices(cliPorts, plugins, input.configDir);\n\n const {\n dbs,\n redisPlans,\n postgres: pgPorts,\n redis: rdPorts,\n } = yield* allocateDatabases(input.bosConfig, input.configDir);\n\n const resolvedPorts: ResolvedPorts = {\n ...svcPorts,\n postgres: pgPorts,\n redis: rdPorts,\n };\n\n // Write merged state once after all allocations succeed\n // Skip persistence for regression tests / ephemeral runs\n if (process.env.BOS_NO_PERSIST_PORTS !== \"1\") {\n savePortState(input.configDir, {\n postgresPorts: pgPorts,\n redisPorts: rdPorts,\n devPorts: devPortsState,\n });\n }\n\n const hostIsLocal = input.bosConfig.host?.source === \"local\";\n const apiIsLocal = input.bosConfig.api?.source === \"local\";\n const uiIsLocal = input.bosConfig.ui?.source === \"local\";\n const authIsLocal = input.bosConfig.auth?.source === \"local\";\n const assignedRuntimeConfig: RuntimeConfig = {\n ...input.bosConfig,\n host: resolvedPorts.host\n ? {\n ...input.bosConfig.host,\n port: resolvedPorts.host,\n url: `http://localhost:${resolvedPorts.host}`,\n remoteUrl: !hostIsLocal\n ? (input.bosConfig.host.remoteUrl ?? input.bosConfig.host.url)\n : undefined,\n }\n : input.bosConfig.host,\n api:\n apiIsLocal && resolvedPorts.api\n ? {\n ...input.bosConfig.api,\n port: resolvedPorts.api,\n url: `http://localhost:${resolvedPorts.api}`,\n }\n : input.bosConfig.api,\n ui:\n uiIsLocal && resolvedPorts.ui\n ? {\n ...input.bosConfig.ui,\n port: resolvedPorts.ui,\n url: `http://localhost:${resolvedPorts.ui}`,\n }\n : input.bosConfig.ui,\n auth:\n authIsLocal && resolvedPorts.auth && input.bosConfig.auth\n ? {\n ...input.bosConfig.auth,\n port: resolvedPorts.auth,\n url: `http://localhost:${resolvedPorts.auth}`,\n }\n : input.bosConfig.auth,\n plugins: input.bosConfig.plugins\n ? Object.fromEntries(\n Object.entries(input.bosConfig.plugins).map(([id, p]) => {\n const pluginPort = resolvedPorts.plugins[id];\n if (p.source === \"local\" && pluginPort?.api) {\n return [\n id,\n { ...p, port: pluginPort.api, url: `http://localhost:${pluginPort.api}` },\n ];\n }\n return [id, p];\n }),\n )\n : undefined,\n };\n\n const serviceDescriptors = buildServiceDescriptors(input.bosConfig, resolvedPorts);\n\n const launch = buildLaunchSpec(input.bosConfig, resolvedPorts);\n const composeModel = buildComposeModel(dbs, redisPlans);\n const envGenerated = buildEnvGenerated(resolvedPorts, dbs, redisPlans);\n\n const packages = serviceDescriptors.map((d) => d.key);\n const descriptionMap = new Map(serviceDescriptors.map((d) => [d.key, d]));\n const description = buildDescription(descriptionMap);\n\n const orchestrator = {\n packages,\n env: {},\n description,\n port: resolvedPorts.host,\n interactive: input.cli.interactive,\n };\n\n return {\n workspaceKey: wKey,\n cliPorts,\n resolvedPorts,\n runtimeConfig: assignedRuntimeConfig,\n launch,\n description,\n serviceDescriptors: new Map(serviceDescriptors.map((d) => [d.key, d])),\n envGenerated,\n composeModel,\n claims,\n orchestrator,\n };\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"planner.mjs","names":[],"sources":["../../src/infra/planner.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { resolve } from \"node:path\";\nimport { Clock, Effect } from \"effect\";\nimport { PortAllocator, type PortBlockEntry } from \"../app\";\nimport {\n buildConventionalDatabases,\n buildConventionalRedis,\n getSecretGroups,\n loadPortState,\n savePortState,\n} from \"../cli/infra\";\nimport {\n type AuthSlotShape,\n buildDescription,\n isAuthMirrorPluginEntry,\n} from \"../service-descriptor\";\nimport type { RuntimeConfig } from \"../types\";\nimport { shouldPersistPortState } from \"./materializer\";\nimport { ownerOfPort } from \"./port-ownership\";\nimport type {\n ClaimRecord,\n CliPorts,\n DatabasePlan,\n InfraInput,\n InfraPlan,\n RedisPlan,\n ResolvedPorts,\n RuntimeLaunchSpec,\n ServiceDescriptorPlan,\n} from \"./types\";\nimport { InfraError } from \"./types\";\n\nconst DEFAULT_HOST_PORT = 3000;\n\nconst POSTGRES_USER = \"everythingdev\";\nconst POSTGRES_PASSWORD = \"everythingdev\";\n\nexport function workspaceKey(configDir: string): string {\n const hash = createHash(\"sha256\").update(resolve(configDir)).digest(\"hex\");\n return hash.slice(0, 12);\n}\n\nfunction normalizeCliPorts(input: InfraInput[\"cli\"]): CliPorts {\n return {\n host: input.port,\n api: input.apiPort,\n auth: input.authPort,\n ui: input.uiPort,\n pluginsStart: input.pluginPortStart,\n plugins: input.plugins,\n };\n}\n\ninterface AllocateServicesResult {\n ports: ResolvedPorts;\n claims: ClaimRecord[];\n devPortsState: {\n host?: number;\n api?: number;\n auth?: number;\n ui?: number;\n pluginPortStart?: number;\n };\n}\n\nexport interface ServiceSources {\n host?: \"local\" | \"remote\";\n api?: \"local\" | \"remote\";\n auth?: \"local\" | \"remote\";\n ui?: \"local\" | \"remote\";\n}\n\nconst PLUGIN_START_OFFSET = 10;\nconst BLOCK_STEP = 100;\n\nfunction allocateServices(\n cliPorts: CliPorts,\n plugins: Record<\n string,\n { source: string; localPath?: string; ui?: { source: string; localPath?: string } }\n >,\n configDir: string,\n auth?: AuthSlotShape,\n sources?: ServiceSources,\n): Effect.Effect<AllocateServicesResult, InfraError, PortAllocator> {\n return Effect.gen(function* () {\n const wKey = workspaceKey(configDir);\n const persisted = loadPortState(configDir).devPorts;\n const allocator = yield* PortAllocator;\n\n const base = cliPorts.host ?? persisted?.host ?? DEFAULT_HOST_PORT;\n const pluginStartPreferred =\n cliPorts.pluginsStart ?? persisted?.pluginPortStart ?? base + PLUGIN_START_OFFSET;\n const pluginStartPinned =\n cliPorts.pluginsStart !== undefined || persisted?.pluginPortStart !== undefined;\n\n const entries: PortBlockEntry[] = [];\n const addEntry = (\n key: string,\n flag: number | undefined,\n persistedValue: number | undefined,\n derived: number,\n ) => {\n if (flag !== undefined) {\n entries.push({ key, preferred: flag, pinned: true });\n } else if (persistedValue !== undefined) {\n entries.push({ key, preferred: persistedValue, pinned: true });\n } else {\n entries.push({ key, preferred: derived, pinned: false });\n }\n };\n\n // Remote-source services spawn nothing locally (ADR 0009 start stack:\n // remotes load over MF from their published origins) — no port is\n // allocated for them. The host is the exception: even when loaded as a\n // remote module, runServer binds its own port.\n addEntry(\"host\", cliPorts.host, undefined, base);\n if (sources?.api !== \"remote\") {\n addEntry(\"api\", cliPorts.api, persisted?.api, base + 1);\n }\n if (sources?.auth !== \"remote\") {\n addEntry(\"auth\", cliPorts.auth, persisted?.auth, base + 2);\n }\n if (sources?.ui !== \"remote\") {\n addEntry(\"ui\", cliPorts.ui, persisted?.ui, base + 3);\n }\n\n const pluginKeys = Object.keys(plugins).sort();\n const isAuthMirrorFor = (\n pluginId: string,\n pluginCfg: { source: string; localPath?: string } | undefined,\n ) => pluginCfg !== undefined && isAuthMirrorPluginEntry(auth, pluginId, pluginCfg);\n\n let pluginSlot = 0;\n for (const pluginId of pluginKeys) {\n const pluginCfg = plugins[pluginId];\n const pluginIsLocal = pluginCfg?.source === \"local\";\n const slotBase = pluginStartPinned ? pluginStartPreferred : base + PLUGIN_START_OFFSET;\n // The auth mirror's backend is owned by the `auth` app slot — no api\n // port. Its ui surface is still real: without a port the runtime config\n // advertises an empty ui.url and the browser can never load the remote\n // (the /login page never renders).\n if (!isAuthMirrorFor(pluginId, pluginCfg) && pluginIsLocal) {\n addEntry(\n `plugin:${pluginId}`,\n cliPorts.plugins?.[pluginId]?.api,\n undefined,\n slotBase + pluginSlot,\n );\n pluginSlot += 1;\n }\n if (\n pluginCfg?.source === \"local\" &&\n pluginCfg?.localPath &&\n pluginCfg?.ui?.source === \"local\"\n ) {\n addEntry(\n `plugin-ui:${pluginId}`,\n cliPorts.plugins?.[pluginId]?.ui,\n undefined,\n slotBase + pluginSlot,\n );\n pluginSlot += 1;\n }\n }\n\n const allocation = yield* allocator.acquireBlock({ base, step: BLOCK_STEP, entries });\n\n if (allocation.base !== base) {\n yield* Effect.logError(\n `[Dev] Preferred port block starting at ${base} is occupied — using ${allocation.base} (this run only; restarts will retry ${base})`,\n );\n for (const conflict of allocation.conflicts.slice(0, 6)) {\n if (conflict.claimed) {\n yield* Effect.logError(\n `[Dev] port ${conflict.port} (${conflict.key}) — live bos session (registry claim)`,\n );\n } else {\n const owner = yield* ownerOfPort(conflict.port);\n yield* Effect.logError(\n `[Dev] port ${conflict.port} (${conflict.key}) — ${\n owner ? `pid ${owner.pid} (${owner.command})` : \"foreign holder (lsof unavailable)\"\n }`,\n );\n }\n }\n }\n\n const pluginApiPorts: Record<string, number> = {};\n const pluginUiPorts: Record<string, number> = {};\n for (const pluginId of pluginKeys) {\n const api = allocation.ports[`plugin:${pluginId}`];\n if (api !== undefined) pluginApiPorts[pluginId] = api;\n const ui = allocation.ports[`plugin-ui:${pluginId}`];\n if (ui !== undefined) pluginUiPorts[pluginId] = ui;\n }\n\n const resolved: ResolvedPorts = {\n host: allocation.ports.host,\n api: allocation.ports.api,\n auth: allocation.ports.auth,\n ui: allocation.ports.ui,\n plugins: Object.fromEntries(\n pluginKeys.map((k) => [k, { api: pluginApiPorts[k], ui: pluginUiPorts[k] }]),\n ),\n };\n\n const devPortsState = {\n host: cliPorts.host,\n api: cliPorts.api,\n auth: cliPorts.auth,\n ui: cliPorts.ui,\n pluginPortStart: cliPorts.pluginsStart,\n };\n\n const claimPorts: Record<string, number> = {};\n for (const [key, port] of Object.entries(allocation.ports)) {\n claimPorts[key] = port;\n }\n\n const claim: ClaimRecord = {\n resourceKey: `workspace:${wKey}`,\n pid: process.pid,\n configDir,\n ports: claimPorts,\n startedAt: yield* Clock.currentTimeMillis,\n };\n\n return { ports: resolved, claims: [claim], devPortsState };\n }).pipe(\n Effect.mapError(\n (portErr) =>\n new InfraError({\n phase: \"allocate-services\",\n message: `Port allocation failed: ${String(portErr)}`,\n cause: portErr,\n }),\n ),\n );\n}\n\nfunction allocateDatabases(runtimeConfig: RuntimeConfig): Effect.Effect<\n {\n dbs: DatabasePlan[];\n redisPlans: RedisPlan[];\n },\n InfraError,\n PortAllocator\n> {\n return Effect.gen(function* () {\n const groups = getSecretGroups(runtimeConfig);\n const allSecrets = groups.flatMap((group) => group.secrets);\n const allocator = yield* PortAllocator;\n\n const conventionalDatabases = buildConventionalDatabases(allSecrets);\n const conventionalRedis = buildConventionalRedis(allSecrets);\n\n const dbs: DatabasePlan[] = [];\n const allocatedByDesired = new Map<number, number>();\n for (const db of conventionalDatabases) {\n let port: number;\n if (allocatedByDesired.has(db.port)) {\n port = allocatedByDesired.get(db.port)!;\n } else {\n port = yield* allocator.pickAvailable(db.port);\n allocatedByDesired.set(db.port, port);\n }\n dbs.push({\n secret: db.secret,\n slug: db.slug,\n port,\n dbName: db.databaseName,\n url: `postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${port}/${db.databaseName}`,\n });\n }\n\n const redisPlans: RedisPlan[] = [];\n for (const r of conventionalRedis) {\n const port = yield* allocator.pickAvailable(r.port);\n redisPlans.push({\n secret: r.secret,\n slug: r.slug,\n port,\n url: `redis://localhost:${port}`,\n });\n }\n\n return { dbs, redisPlans };\n }).pipe(\n Effect.mapError(\n (portErr) =>\n new InfraError({\n phase: \"allocate-databases\",\n message: `Database port allocation failed: ${String(portErr)}`,\n cause: portErr,\n }),\n ),\n );\n}\n\nexport function buildServiceDescriptors(\n runtimeConfig: RuntimeConfig,\n resolvedPorts: ResolvedPorts,\n): ServiceDescriptorPlan[] {\n const descriptors: ServiceDescriptorPlan[] = [];\n\n if (runtimeConfig.host) {\n const isLocal = runtimeConfig.host.source === \"local\";\n descriptors.push({\n key: \"host\",\n source: runtimeConfig.host.source,\n url: isLocal ? `http://localhost:${resolvedPorts.host}` : runtimeConfig.host.url,\n port: isLocal ? resolvedPorts.host : undefined,\n localPath: isLocal ? runtimeConfig.host.localPath : undefined,\n });\n }\n\n if (runtimeConfig.api) {\n const isLocal = runtimeConfig.api.source === \"local\";\n descriptors.push({\n key: \"api\",\n source: runtimeConfig.api.source,\n url: isLocal ? `http://localhost:${resolvedPorts.api}` : runtimeConfig.api.url,\n port: isLocal ? resolvedPorts.api : undefined,\n localPath: isLocal ? runtimeConfig.api.localPath : undefined,\n });\n }\n\n if (runtimeConfig.auth) {\n const isLocal = runtimeConfig.auth.source === \"local\";\n descriptors.push({\n key: \"auth\",\n source: runtimeConfig.auth.source,\n url: isLocal ? `http://localhost:${resolvedPorts.auth}` : runtimeConfig.auth.url,\n port: isLocal ? resolvedPorts.auth : undefined,\n localPath: isLocal ? runtimeConfig.auth.localPath : undefined,\n });\n }\n\n if (runtimeConfig.ui) {\n const isLocal = runtimeConfig.ui.source === \"local\";\n descriptors.push({\n key: \"ui\",\n source: runtimeConfig.ui.source,\n url: isLocal ? `http://localhost:${resolvedPorts.ui}` : runtimeConfig.ui.url,\n port: isLocal ? resolvedPorts.ui : undefined,\n localPath: isLocal ? runtimeConfig.ui.localPath : undefined,\n });\n }\n\n if (runtimeConfig.plugins) {\n for (const [pluginId, pluginCfg] of Object.entries(runtimeConfig.plugins)) {\n const pluginIsLocal = pluginCfg.source === \"local\";\n const p = resolvedPorts.plugins[pluginId];\n const isAuthMirror = isAuthMirrorPluginEntry(runtimeConfig.auth, pluginId, pluginCfg);\n if (pluginIsLocal && p?.api && !isAuthMirror) {\n descriptors.push({\n key: `plugin:${pluginId}`,\n source: \"local\",\n url: `http://localhost:${p.api}`,\n port: p.api,\n localPath: pluginCfg.localPath,\n });\n }\n if (!pluginIsLocal && pluginCfg.url && !isAuthMirror) {\n descriptors.push({\n key: `plugin:${pluginId}`,\n source: \"remote\",\n url: pluginCfg.url,\n port: undefined,\n localPath: undefined,\n });\n }\n if (pluginIsLocal && p?.ui && pluginCfg.ui?.source === \"local\") {\n descriptors.push({\n key: `plugin-ui:${pluginId}`,\n source: \"local\",\n url: `http://localhost:${p.ui}`,\n port: p.ui,\n localPath: pluginCfg.ui?.localPath,\n });\n }\n }\n }\n\n return descriptors;\n}\n\nexport function buildLaunchSpec(\n runtimeConfig: RuntimeConfig,\n resolvedPorts: ResolvedPorts,\n): RuntimeLaunchSpec {\n const hostPort =\n runtimeConfig.host?.source === \"local\" ? resolvedPorts.host : runtimeConfig.host?.port;\n const corsOrigin = hostPort ? `http://localhost:${hostPort}` : `http://localhost:3000`;\n\n return {\n port: resolvedPorts.host,\n hostUrl: runtimeConfig.host?.url,\n corsOrigin,\n env: {\n ...(resolvedPorts.host ? { PORT: String(resolvedPorts.host) } : {}),\n ...(resolvedPorts.api ? { API_PORT: String(resolvedPorts.api) } : {}),\n ...(resolvedPorts.ui ? { UI_PORT: String(resolvedPorts.ui) } : {}),\n ...(resolvedPorts.auth ? { AUTH_PORT: String(resolvedPorts.auth) } : {}),\n },\n runtimeConfig,\n };\n}\n\nexport function buildEnvGenerated(\n resolvedPorts: ResolvedPorts,\n dbs: DatabasePlan[],\n redisPlans: RedisPlan[],\n): Record<string, string> {\n const env: Record<string, string> = {};\n\n if (resolvedPorts.host) {\n env.CORS_ORIGIN = `http://localhost:${resolvedPorts.host}`;\n // The host origin for plugins that derive absolute URLs from it (e.g. the\n // auth plugin's Better Auth baseURL — email links, passkey RP id).\n env.BASE_URL = `http://localhost:${resolvedPorts.host}`;\n }\n\n for (const db of dbs) {\n env[db.secret] = db.url;\n }\n for (const r of redisPlans) {\n env[r.secret] = r.url;\n }\n\n return env;\n}\n\nexport function planInfra(input: InfraInput): Effect.Effect<InfraPlan, InfraError, PortAllocator> {\n return Effect.gen(function* () {\n const cliPorts = normalizeCliPorts(input.cli);\n const wKey = workspaceKey(input.configDir);\n\n const plugins = (input.bosConfig.plugins ?? {}) as Record<\n string,\n { source: string; localPath?: string; ui?: { source: string; localPath?: string } }\n >;\n\n const {\n ports: svcPorts,\n claims,\n devPortsState,\n } = yield* allocateServices(cliPorts, plugins, input.configDir, input.bosConfig.auth, {\n host: input.bosConfig.host?.source,\n api: input.bosConfig.api?.source,\n auth: input.bosConfig.auth?.source,\n ui: input.bosConfig.ui?.source,\n });\n\n const { dbs, redisPlans } = yield* allocateDatabases(input.bosConfig);\n\n const resolvedPorts: ResolvedPorts = { ...svcPorts };\n\n // Write merged state once after all allocations succeed\n // Skip persistence for regression tests / ephemeral runs\n // devPorts pins are explicit choices only (ADR 0012 §4): this run's flags,\n // falling back to previously-persisted explicit choices — never drift.\n const previousDevPorts = loadPortState(input.configDir).devPorts ?? {};\n const devPorts = {\n host: devPortsState.host ?? previousDevPorts.host,\n api: devPortsState.api ?? previousDevPorts.api,\n auth: devPortsState.auth ?? previousDevPorts.auth,\n ui: devPortsState.ui ?? previousDevPorts.ui,\n pluginPortStart: devPortsState.pluginPortStart ?? previousDevPorts.pluginPortStart,\n };\n if (shouldPersistPortState()) {\n savePortState(input.configDir, { devPorts });\n }\n\n const hostIsLocal = input.bosConfig.host?.source === \"local\";\n const apiIsLocal = input.bosConfig.api?.source === \"local\";\n const uiIsLocal = input.bosConfig.ui?.source === \"local\";\n const authIsLocal = input.bosConfig.auth?.source === \"local\";\n const assignedRuntimeConfig: RuntimeConfig = {\n ...input.bosConfig,\n host: resolvedPorts.host\n ? {\n ...input.bosConfig.host,\n port: resolvedPorts.host,\n url: `http://localhost:${resolvedPorts.host}`,\n remoteUrl: !hostIsLocal\n ? (input.bosConfig.host.remoteUrl ?? input.bosConfig.host.url)\n : undefined,\n }\n : input.bosConfig.host,\n api:\n apiIsLocal && resolvedPorts.api\n ? {\n ...input.bosConfig.api,\n port: resolvedPorts.api,\n url: `http://localhost:${resolvedPorts.api}`,\n }\n : input.bosConfig.api,\n ui:\n uiIsLocal && resolvedPorts.ui\n ? {\n ...input.bosConfig.ui,\n port: resolvedPorts.ui,\n url: `http://localhost:${resolvedPorts.ui}`,\n ssrUrl: undefined,\n }\n : input.bosConfig.ui,\n auth:\n authIsLocal && resolvedPorts.auth && input.bosConfig.auth\n ? {\n ...input.bosConfig.auth,\n port: resolvedPorts.auth,\n url: `http://localhost:${resolvedPorts.auth}`,\n }\n : input.bosConfig.auth,\n plugins: input.bosConfig.plugins\n ? Object.fromEntries(\n Object.entries(input.bosConfig.plugins).map(([id, p]) => {\n const isAuthMirror = isAuthMirrorPluginEntry(input.bosConfig.auth, id, p);\n const pluginPort = resolvedPorts.plugins[id];\n const patchedUi = (() => {\n if (p.ui?.source !== \"local\" || !p.ui?.localPath || !pluginPort?.ui) return p.ui;\n return {\n ...p.ui,\n port: pluginPort.ui,\n url: `http://localhost:${pluginPort.ui}`,\n ssrUrl: undefined,\n };\n })();\n if (isAuthMirror) {\n return [id, { ...p, ui: patchedUi }];\n }\n if (p.source === \"local\" && pluginPort?.api) {\n return [\n id,\n {\n ...p,\n port: pluginPort.api,\n url: `http://localhost:${pluginPort.api}`,\n ui: patchedUi,\n },\n ];\n }\n return [id, p];\n }),\n )\n : undefined,\n };\n\n const serviceDescriptors = buildServiceDescriptors(assignedRuntimeConfig, resolvedPorts);\n\n const launch = buildLaunchSpec(input.bosConfig, resolvedPorts);\n const envGenerated = buildEnvGenerated(resolvedPorts, dbs, redisPlans);\n\n const packages = serviceDescriptors.map((d) => d.key);\n const descriptionMap = new Map(serviceDescriptors.map((d) => [d.key, d]));\n const description = buildDescription(descriptionMap);\n\n const orchestrator = {\n packages,\n env: {},\n description,\n port: resolvedPorts.host,\n interactive: input.cli.interactive,\n };\n\n return {\n workspaceKey: wKey,\n cliPorts,\n resolvedPorts,\n runtimeConfig: assignedRuntimeConfig,\n launch,\n description,\n serviceDescriptors: new Map(serviceDescriptors.map((d) => [d.key, d])),\n envGenerated,\n claims,\n orchestrator,\n };\n });\n}\n"],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ let effect = require("effect");
2
+ let node_child_process = require("node:child_process");
3
+
4
+ //#region src/infra/port-ownership.ts
5
+ let lsofCached = null;
6
+ const execFileText = (path, args) => new Promise((resolve, reject) => {
7
+ (0, node_child_process.execFile)(path, args, { timeout: 5e3 }, (error, stdout) => {
8
+ if (error && !stdout) reject(error);
9
+ else resolve(stdout);
10
+ });
11
+ });
12
+ const isValidPort = (port) => Number.isInteger(port) && port > 0 && port <= 65535;
13
+ const ownerOfPort = (port, options) => effect.Effect.callback((resume) => {
14
+ (async () => {
15
+ if (!isValidPort(port)) {
16
+ resume(effect.Effect.succeed(null));
17
+ return;
18
+ }
19
+ const lsof = options?.lsofPath ?? "lsof";
20
+ try {
21
+ const stdout = await execFileText(lsof, [
22
+ "-ti",
23
+ `:${port}`,
24
+ "-sTCP:LISTEN"
25
+ ]);
26
+ const pid = Number.parseInt(stdout.trim().split("\n")[0] ?? "", 10);
27
+ if (!Number.isInteger(pid) || pid <= 0) {
28
+ resume(effect.Effect.succeed(null));
29
+ return;
30
+ }
31
+ try {
32
+ const psOut = await execFileText(options?.psPath ?? "ps", [
33
+ "-o",
34
+ "command=",
35
+ "-p",
36
+ String(pid)
37
+ ]);
38
+ resume(effect.Effect.succeed({
39
+ pid,
40
+ command: psOut.trim() || "unknown"
41
+ }));
42
+ } catch {
43
+ resume(effect.Effect.succeed({
44
+ pid,
45
+ command: "unknown"
46
+ }));
47
+ }
48
+ } catch (error) {
49
+ if (error.code === "ENOENT") lsofCached = false;
50
+ resume(effect.Effect.succeed(null));
51
+ }
52
+ })();
53
+ });
54
+
55
+ //#endregion
56
+ exports.ownerOfPort = ownerOfPort;
57
+ //# sourceMappingURL=port-ownership.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"port-ownership.cjs","names":["Effect"],"sources":["../../src/infra/port-ownership.ts"],"sourcesContent":["import { execFile } from \"node:child_process\";\nimport { Effect } from \"effect\";\n\nexport interface PortOwner {\n pid: number;\n command: string;\n}\n\nexport interface PortOwnershipOptions {\n lsofPath?: string;\n psPath?: string;\n}\n\nlet lsofCached: boolean | null = null;\n\nconst execFileText = (path: string, args: string[]): Promise<string> =>\n new Promise((resolve, reject) => {\n execFile(path, args, { timeout: 5000 }, (error, stdout) => {\n if (error && !stdout) reject(error);\n else resolve(stdout);\n });\n });\n\nconst isValidPort = (port: number): boolean => Number.isInteger(port) && port > 0 && port <= 65535;\n\n// ownerOfPort identifies the process listening on a port via lsof + ps.\n// Returns null when the port is free or when lsof is unavailable (degraded:\n// callers report \"unknown owner\" rather than failing).\nexport const ownerOfPort = (\n port: number,\n options?: PortOwnershipOptions,\n): Effect.Effect<PortOwner | null> =>\n Effect.callback((resume) => {\n void (async () => {\n if (!isValidPort(port)) {\n resume(Effect.succeed(null));\n return;\n }\n const lsof = options?.lsofPath ?? \"lsof\";\n try {\n const stdout = await execFileText(lsof, [\"-ti\", `:${port}`, \"-sTCP:LISTEN\"]);\n const pid = Number.parseInt(stdout.trim().split(\"\\n\")[0] ?? \"\", 10);\n if (!Number.isInteger(pid) || pid <= 0) {\n resume(Effect.succeed(null));\n return;\n }\n try {\n const psOut = await execFileText(options?.psPath ?? \"ps\", [\n \"-o\",\n \"command=\",\n \"-p\",\n String(pid),\n ]);\n resume(Effect.succeed({ pid, command: psOut.trim() || \"unknown\" }));\n } catch {\n resume(Effect.succeed({ pid, command: \"unknown\" }));\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") lsofCached = false;\n resume(Effect.succeed(null));\n }\n })();\n });\n\n// isLsofAvailable probes (once per process) whether the lsof binary exists —\n// ownership reporting degrades gracefully when it does not.\nexport const isLsofAvailable = (options?: PortOwnershipOptions): Effect.Effect<boolean> =>\n Effect.callback((resume) => {\n if (lsofCached !== null) {\n resume(Effect.succeed(lsofCached));\n return;\n }\n void (async () => {\n try {\n await execFileText(options?.lsofPath ?? \"lsof\", [\"-v\"]);\n lsofCached = true;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") lsofCached = false;\n else lsofCached = true;\n }\n resume(Effect.succeed(lsofCached));\n })();\n });\n\nexport const resetLsofCacheForTests = (): void => {\n lsofCached = null;\n};\n"],"mappings":";;;;AAaA,IAAI,aAA6B;AAEjC,MAAM,gBAAgB,MAAc,SAClC,IAAI,SAAS,SAAS,WAAW;CAC/B,iCAAS,MAAM,MAAM,EAAE,SAAS,IAAK,IAAI,OAAO,WAAW;EACzD,IAAI,SAAS,CAAC,QAAQ,OAAO,KAAK;OAC7B,QAAQ,MAAM;CACrB,CAAC;AACH,CAAC;AAEH,MAAM,eAAe,SAA0B,OAAO,UAAU,IAAI,KAAK,OAAO,KAAK,QAAQ;AAK7F,MAAa,eACX,MACA,YAEAA,cAAO,UAAU,WAAW;CAC1B,CAAM,YAAY;EAChB,IAAI,CAAC,YAAY,IAAI,GAAG;GACtB,OAAOA,cAAO,QAAQ,IAAI,CAAC;GAC3B;EACF;EACA,MAAM,OAAO,SAAS,YAAY;EAClC,IAAI;GACF,MAAM,SAAS,MAAM,aAAa,MAAM;IAAC;IAAO,IAAI;IAAQ;GAAc,CAAC;GAC3E,MAAM,MAAM,OAAO,SAAS,OAAO,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE;GAClE,IAAI,CAAC,OAAO,UAAU,GAAG,KAAK,OAAO,GAAG;IACtC,OAAOA,cAAO,QAAQ,IAAI,CAAC;IAC3B;GACF;GACA,IAAI;IACF,MAAM,QAAQ,MAAM,aAAa,SAAS,UAAU,MAAM;KACxD;KACA;KACA;KACA,OAAO,GAAG;IACZ,CAAC;IACD,OAAOA,cAAO,QAAQ;KAAE;KAAK,SAAS,MAAM,KAAK,KAAK;IAAU,CAAC,CAAC;GACpE,QAAQ;IACN,OAAOA,cAAO,QAAQ;KAAE;KAAK,SAAS;IAAU,CAAC,CAAC;GACpD;EACF,SAAS,OAAO;GACd,IAAK,MAAgC,SAAS,UAAU,aAAa;GACrE,OAAOA,cAAO,QAAQ,IAAI,CAAC;EAC7B;CACF,EAAC,CAAE;AACL,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { Effect } from "effect";
2
+ import { execFile } from "node:child_process";
3
+
4
+ //#region src/infra/port-ownership.ts
5
+ let lsofCached = null;
6
+ const execFileText = (path, args) => new Promise((resolve, reject) => {
7
+ execFile(path, args, { timeout: 5e3 }, (error, stdout) => {
8
+ if (error && !stdout) reject(error);
9
+ else resolve(stdout);
10
+ });
11
+ });
12
+ const isValidPort = (port) => Number.isInteger(port) && port > 0 && port <= 65535;
13
+ const ownerOfPort = (port, options) => Effect.callback((resume) => {
14
+ (async () => {
15
+ if (!isValidPort(port)) {
16
+ resume(Effect.succeed(null));
17
+ return;
18
+ }
19
+ const lsof = options?.lsofPath ?? "lsof";
20
+ try {
21
+ const stdout = await execFileText(lsof, [
22
+ "-ti",
23
+ `:${port}`,
24
+ "-sTCP:LISTEN"
25
+ ]);
26
+ const pid = Number.parseInt(stdout.trim().split("\n")[0] ?? "", 10);
27
+ if (!Number.isInteger(pid) || pid <= 0) {
28
+ resume(Effect.succeed(null));
29
+ return;
30
+ }
31
+ try {
32
+ const psOut = await execFileText(options?.psPath ?? "ps", [
33
+ "-o",
34
+ "command=",
35
+ "-p",
36
+ String(pid)
37
+ ]);
38
+ resume(Effect.succeed({
39
+ pid,
40
+ command: psOut.trim() || "unknown"
41
+ }));
42
+ } catch {
43
+ resume(Effect.succeed({
44
+ pid,
45
+ command: "unknown"
46
+ }));
47
+ }
48
+ } catch (error) {
49
+ if (error.code === "ENOENT") lsofCached = false;
50
+ resume(Effect.succeed(null));
51
+ }
52
+ })();
53
+ });
54
+
55
+ //#endregion
56
+ export { ownerOfPort };
57
+ //# sourceMappingURL=port-ownership.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"port-ownership.mjs","names":[],"sources":["../../src/infra/port-ownership.ts"],"sourcesContent":["import { execFile } from \"node:child_process\";\nimport { Effect } from \"effect\";\n\nexport interface PortOwner {\n pid: number;\n command: string;\n}\n\nexport interface PortOwnershipOptions {\n lsofPath?: string;\n psPath?: string;\n}\n\nlet lsofCached: boolean | null = null;\n\nconst execFileText = (path: string, args: string[]): Promise<string> =>\n new Promise((resolve, reject) => {\n execFile(path, args, { timeout: 5000 }, (error, stdout) => {\n if (error && !stdout) reject(error);\n else resolve(stdout);\n });\n });\n\nconst isValidPort = (port: number): boolean => Number.isInteger(port) && port > 0 && port <= 65535;\n\n// ownerOfPort identifies the process listening on a port via lsof + ps.\n// Returns null when the port is free or when lsof is unavailable (degraded:\n// callers report \"unknown owner\" rather than failing).\nexport const ownerOfPort = (\n port: number,\n options?: PortOwnershipOptions,\n): Effect.Effect<PortOwner | null> =>\n Effect.callback((resume) => {\n void (async () => {\n if (!isValidPort(port)) {\n resume(Effect.succeed(null));\n return;\n }\n const lsof = options?.lsofPath ?? \"lsof\";\n try {\n const stdout = await execFileText(lsof, [\"-ti\", `:${port}`, \"-sTCP:LISTEN\"]);\n const pid = Number.parseInt(stdout.trim().split(\"\\n\")[0] ?? \"\", 10);\n if (!Number.isInteger(pid) || pid <= 0) {\n resume(Effect.succeed(null));\n return;\n }\n try {\n const psOut = await execFileText(options?.psPath ?? \"ps\", [\n \"-o\",\n \"command=\",\n \"-p\",\n String(pid),\n ]);\n resume(Effect.succeed({ pid, command: psOut.trim() || \"unknown\" }));\n } catch {\n resume(Effect.succeed({ pid, command: \"unknown\" }));\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") lsofCached = false;\n resume(Effect.succeed(null));\n }\n })();\n });\n\n// isLsofAvailable probes (once per process) whether the lsof binary exists —\n// ownership reporting degrades gracefully when it does not.\nexport const isLsofAvailable = (options?: PortOwnershipOptions): Effect.Effect<boolean> =>\n Effect.callback((resume) => {\n if (lsofCached !== null) {\n resume(Effect.succeed(lsofCached));\n return;\n }\n void (async () => {\n try {\n await execFileText(options?.lsofPath ?? \"lsof\", [\"-v\"]);\n lsofCached = true;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") lsofCached = false;\n else lsofCached = true;\n }\n resume(Effect.succeed(lsofCached));\n })();\n });\n\nexport const resetLsofCacheForTests = (): void => {\n lsofCached = null;\n};\n"],"mappings":";;;;AAaA,IAAI,aAA6B;AAEjC,MAAM,gBAAgB,MAAc,SAClC,IAAI,SAAS,SAAS,WAAW;CAC/B,SAAS,MAAM,MAAM,EAAE,SAAS,IAAK,IAAI,OAAO,WAAW;EACzD,IAAI,SAAS,CAAC,QAAQ,OAAO,KAAK;OAC7B,QAAQ,MAAM;CACrB,CAAC;AACH,CAAC;AAEH,MAAM,eAAe,SAA0B,OAAO,UAAU,IAAI,KAAK,OAAO,KAAK,QAAQ;AAK7F,MAAa,eACX,MACA,YAEA,OAAO,UAAU,WAAW;CAC1B,CAAM,YAAY;EAChB,IAAI,CAAC,YAAY,IAAI,GAAG;GACtB,OAAO,OAAO,QAAQ,IAAI,CAAC;GAC3B;EACF;EACA,MAAM,OAAO,SAAS,YAAY;EAClC,IAAI;GACF,MAAM,SAAS,MAAM,aAAa,MAAM;IAAC;IAAO,IAAI;IAAQ;GAAc,CAAC;GAC3E,MAAM,MAAM,OAAO,SAAS,OAAO,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE;GAClE,IAAI,CAAC,OAAO,UAAU,GAAG,KAAK,OAAO,GAAG;IACtC,OAAO,OAAO,QAAQ,IAAI,CAAC;IAC3B;GACF;GACA,IAAI;IACF,MAAM,QAAQ,MAAM,aAAa,SAAS,UAAU,MAAM;KACxD;KACA;KACA;KACA,OAAO,GAAG;IACZ,CAAC;IACD,OAAO,OAAO,QAAQ;KAAE;KAAK,SAAS,MAAM,KAAK,KAAK;IAAU,CAAC,CAAC;GACpE,QAAQ;IACN,OAAO,OAAO,QAAQ;KAAE;KAAK,SAAS;IAAU,CAAC,CAAC;GACpD;EACF,SAAS,OAAO;GACd,IAAK,MAAgC,SAAS,UAAU,aAAa;GACrE,OAAO,OAAO,QAAQ,IAAI,CAAC;EAC7B;CACF,EAAC,CAAE;AACL,CAAC"}