@bleedingdev/modern-js-ultramodern-create 3.9.0-ultramodern.2 → 3.9.0-ultramodern.21

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 (442) hide show
  1. package/README.md +43 -74
  2. package/dist/cjs/cli/package-source.cjs +2 -2
  3. package/dist/cjs/cli/project-setup.cjs +2 -22
  4. package/dist/cjs/index.cjs +9 -1
  5. package/dist/cjs/locale/en.cjs +2 -1
  6. package/dist/cjs/locale/zh.cjs +2 -1
  7. package/dist/cjs/ultramodern-package-source.cjs +13 -9
  8. package/dist/cjs/ultramodern-release-cohort.cjs +6 -21
  9. package/dist/cjs/ultramodern-tooling/commands/cloudflare-output-verify.cjs +49 -56
  10. package/dist/cjs/ultramodern-tooling/commands/context.cjs +11 -29
  11. package/dist/cjs/ultramodern-tooling/commands/routes-generate-app.cjs +67 -0
  12. package/dist/cjs/ultramodern-tooling/commands/routes-generate.cjs +24 -53
  13. package/dist/cjs/ultramodern-tooling/commands/validate.cjs +5 -11
  14. package/dist/cjs/ultramodern-tooling/commands.cjs +15 -8
  15. package/dist/cjs/ultramodern-tooling/config/index.cjs +10 -24
  16. package/dist/cjs/ultramodern-tooling/config/load.cjs +12 -10
  17. package/dist/cjs/ultramodern-tooling/config/metadata.cjs +34 -32
  18. package/dist/cjs/ultramodern-tooling/config/normalize.cjs +165 -164
  19. package/dist/cjs/ultramodern-workspace/add-shell.cjs +118 -118
  20. package/dist/cjs/ultramodern-workspace/add-vertical/execute.cjs +121 -25
  21. package/dist/cjs/ultramodern-workspace/add-vertical/plan.cjs +14 -160
  22. package/dist/cjs/ultramodern-workspace/add-vertical/preflight.cjs +16 -48
  23. package/dist/cjs/ultramodern-workspace/add-vertical/preview.cjs +78 -0
  24. package/dist/cjs/ultramodern-workspace/add-vertical/shell-files.cjs +87 -24
  25. package/dist/cjs/ultramodern-workspace/add-vertical/topology.cjs +4 -1
  26. package/dist/cjs/ultramodern-workspace/add-vertical/transaction.cjs +378 -45
  27. package/dist/cjs/ultramodern-workspace/add-vertical/workspace-state.cjs +21 -44
  28. package/dist/cjs/ultramodern-workspace/add-vertical.cjs +0 -9
  29. package/dist/cjs/ultramodern-workspace/api/client.cjs +5 -5
  30. package/dist/cjs/ultramodern-workspace/api/contracts.cjs +2 -2
  31. package/dist/cjs/ultramodern-workspace/api/rpc.cjs +20 -18
  32. package/dist/cjs/ultramodern-workspace/api/service.cjs +49 -24
  33. package/dist/cjs/ultramodern-workspace/api/shared.cjs +28 -18
  34. package/dist/cjs/ultramodern-workspace/app-files.cjs +3 -23
  35. package/dist/cjs/ultramodern-workspace/backend-federation.cjs +27 -27
  36. package/dist/cjs/ultramodern-workspace/contracts.cjs +14 -183
  37. package/dist/cjs/ultramodern-workspace/delivery-unit-schema/surfaces.cjs +85 -0
  38. package/dist/cjs/ultramodern-workspace/delivery-unit-schema/types.cjs +8 -85
  39. package/dist/cjs/ultramodern-workspace/delivery-unit-stamp.cjs +16 -4
  40. package/dist/cjs/ultramodern-workspace/delivery-unit-sync.cjs +27 -17
  41. package/dist/cjs/ultramodern-workspace/delivery-unit.cjs +16 -10
  42. package/dist/cjs/ultramodern-workspace/demo-components.cjs +66 -433
  43. package/dist/cjs/ultramodern-workspace/descriptors.cjs +0 -4
  44. package/dist/cjs/ultramodern-workspace/fs-io.cjs +37 -2
  45. package/dist/cjs/ultramodern-workspace/generation-result.cjs +4 -4
  46. package/dist/cjs/ultramodern-workspace/index.cjs +2 -5
  47. package/dist/cjs/ultramodern-workspace/mf-validation/constants.cjs +0 -6
  48. package/dist/cjs/ultramodern-workspace/mf-validation/discovery.cjs +6 -6
  49. package/dist/cjs/{ultramodern-tooling/commands/migrate-strict-effect/generated-patches.cjs → ultramodern-workspace/mf-validation/exposes.cjs} +13 -17
  50. package/dist/cjs/ultramodern-workspace/mf-validation/inspect.cjs +26 -7
  51. package/dist/cjs/ultramodern-workspace/mf-validation/object-literal.cjs +21 -122
  52. package/dist/cjs/ultramodern-workspace/mf-validation/path-utils.cjs +37 -38
  53. package/dist/cjs/ultramodern-workspace/mf-validation/syntax.cjs +93 -153
  54. package/dist/cjs/ultramodern-workspace/mf-validation.cjs +4 -0
  55. package/dist/cjs/ultramodern-workspace/module-federation/config.cjs +24 -29
  56. package/dist/cjs/ultramodern-workspace/module-federation/reexport-module.cjs +39 -58
  57. package/dist/cjs/ultramodern-workspace/module-federation/remote-refs.cjs +1 -43
  58. package/dist/cjs/ultramodern-workspace/package-json.cjs +63 -37
  59. package/dist/cjs/ultramodern-workspace/patch-inventory.cjs +104 -0
  60. package/dist/cjs/ultramodern-workspace/policy.cjs +3 -577
  61. package/dist/cjs/ultramodern-workspace/public-surface.cjs +3 -3
  62. package/dist/cjs/ultramodern-workspace/routes.cjs +2 -11
  63. package/dist/cjs/ultramodern-workspace/shared-patches.cjs +12 -2
  64. package/dist/cjs/ultramodern-workspace/shells.cjs +0 -70
  65. package/dist/cjs/ultramodern-workspace/tooling-command-catalog.cjs +27 -41
  66. package/dist/cjs/ultramodern-workspace/tsconfigs.cjs +8 -2
  67. package/dist/cjs/ultramodern-workspace/validation/architecture.cjs +397 -0
  68. package/dist/cjs/ultramodern-workspace/validation/assertions.cjs +140 -0
  69. package/dist/cjs/ultramodern-workspace/validation/types.cjs +18 -0
  70. package/dist/cjs/ultramodern-workspace/validation/workspace.cjs +344 -0
  71. package/dist/cjs/ultramodern-workspace/versions.cjs +81 -45
  72. package/dist/cjs/ultramodern-workspace/workspace-artifact-ownership.cjs +183 -0
  73. package/dist/cjs/ultramodern-workspace/workspace-script-plan.cjs +36 -25
  74. package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +11 -200
  75. package/dist/cjs/ultramodern-workspace/workspace-validation-contract.cjs +62 -373
  76. package/dist/cjs/ultramodern-workspace/write-app.cjs +19 -11
  77. package/dist/cjs/ultramodern-workspace/write-workspace.cjs +20 -50
  78. package/dist/cjs/ultramodern-workspace/zerops.cjs +2 -0
  79. package/dist/esm/cli/package-source.js +3 -3
  80. package/dist/esm/cli/project-setup.js +2 -22
  81. package/dist/esm/index.js +10 -2
  82. package/dist/esm/locale/en.js +2 -1
  83. package/dist/esm/locale/zh.js +2 -1
  84. package/dist/esm/ultramodern-package-source.js +14 -4
  85. package/dist/esm/ultramodern-release-cohort.js +5 -14
  86. package/dist/esm/ultramodern-tooling/commands/cloudflare-output-verify.js +49 -56
  87. package/dist/esm/ultramodern-tooling/commands/context.js +10 -26
  88. package/dist/esm/ultramodern-tooling/commands/routes-generate-app.js +35 -0
  89. package/dist/esm/ultramodern-tooling/commands/routes-generate.js +25 -54
  90. package/dist/esm/ultramodern-tooling/commands/validate.js +6 -12
  91. package/dist/esm/ultramodern-tooling/commands.js +15 -9
  92. package/dist/esm/ultramodern-tooling/config/index.js +0 -2
  93. package/dist/esm/ultramodern-tooling/config/load.js +9 -9
  94. package/dist/esm/ultramodern-tooling/config/metadata.js +33 -28
  95. package/dist/esm/ultramodern-tooling/config/normalize.js +159 -156
  96. package/dist/esm/ultramodern-workspace/add-shell.js +124 -123
  97. package/dist/esm/ultramodern-workspace/add-vertical/execute.js +119 -27
  98. package/dist/esm/ultramodern-workspace/add-vertical/plan.js +16 -150
  99. package/dist/esm/ultramodern-workspace/add-vertical/preflight.js +15 -47
  100. package/dist/esm/ultramodern-workspace/add-vertical/preview.js +40 -0
  101. package/dist/esm/ultramodern-workspace/add-vertical/shell-files.js +87 -25
  102. package/dist/esm/ultramodern-workspace/add-vertical/topology.js +4 -1
  103. package/dist/esm/ultramodern-workspace/add-vertical/transaction.js +373 -46
  104. package/dist/esm/ultramodern-workspace/add-vertical/workspace-state.js +17 -34
  105. package/dist/esm/ultramodern-workspace/add-vertical.js +1 -1
  106. package/dist/esm/ultramodern-workspace/api/client.js +5 -5
  107. package/dist/esm/ultramodern-workspace/api/contracts.js +2 -2
  108. package/dist/esm/ultramodern-workspace/api/rpc.js +20 -18
  109. package/dist/esm/ultramodern-workspace/api/service.js +49 -24
  110. package/dist/esm/ultramodern-workspace/api/shared.js +28 -18
  111. package/dist/esm/ultramodern-workspace/app-files.js +3 -23
  112. package/dist/esm/ultramodern-workspace/backend-federation.js +5 -5
  113. package/dist/esm/ultramodern-workspace/contracts.js +14 -180
  114. package/dist/esm/ultramodern-workspace/delivery-unit-schema/surfaces.js +41 -0
  115. package/dist/esm/ultramodern-workspace/delivery-unit-schema/types.js +1 -75
  116. package/dist/esm/ultramodern-workspace/delivery-unit-stamp.js +16 -4
  117. package/dist/esm/ultramodern-workspace/delivery-unit-sync.js +28 -18
  118. package/dist/esm/ultramodern-workspace/delivery-unit.js +12 -6
  119. package/dist/esm/ultramodern-workspace/demo-components.js +67 -428
  120. package/dist/esm/ultramodern-workspace/descriptors.js +1 -2
  121. package/dist/esm/ultramodern-workspace/fs-io.js +37 -2
  122. package/dist/esm/ultramodern-workspace/generation-result.js +3 -3
  123. package/dist/esm/ultramodern-workspace/index.js +1 -1
  124. package/dist/esm/ultramodern-workspace/mf-validation/constants.js +1 -4
  125. package/dist/esm/ultramodern-workspace/mf-validation/discovery.js +7 -7
  126. package/dist/esm/ultramodern-workspace/mf-validation/exposes.js +14 -0
  127. package/dist/esm/ultramodern-workspace/mf-validation/inspect.js +27 -8
  128. package/dist/esm/ultramodern-workspace/mf-validation/object-literal.js +22 -123
  129. package/dist/esm/ultramodern-workspace/mf-validation/path-utils.js +36 -34
  130. package/dist/esm/ultramodern-workspace/mf-validation/syntax.js +83 -143
  131. package/dist/esm/ultramodern-workspace/mf-validation.js +1 -0
  132. package/dist/esm/ultramodern-workspace/module-federation/config.js +25 -30
  133. package/dist/esm/ultramodern-workspace/module-federation/reexport-module.js +39 -58
  134. package/dist/esm/ultramodern-workspace/module-federation/remote-refs.js +1 -43
  135. package/dist/esm/ultramodern-workspace/package-json.js +58 -32
  136. package/dist/esm/ultramodern-workspace/patch-inventory.js +66 -0
  137. package/dist/esm/ultramodern-workspace/policy.js +2 -564
  138. package/dist/esm/ultramodern-workspace/public-surface.js +3 -3
  139. package/dist/esm/ultramodern-workspace/routes.js +2 -11
  140. package/dist/esm/ultramodern-workspace/shared-patches.js +2 -2
  141. package/dist/esm/ultramodern-workspace/shells.js +3 -67
  142. package/dist/esm/ultramodern-workspace/tooling-command-catalog.js +22 -37
  143. package/dist/esm/ultramodern-workspace/tsconfigs.js +9 -3
  144. package/dist/esm/ultramodern-workspace/validation/architecture.js +348 -0
  145. package/dist/esm/ultramodern-workspace/validation/assertions.js +65 -0
  146. package/dist/esm/ultramodern-workspace/validation/types.js +0 -0
  147. package/dist/esm/ultramodern-workspace/validation/workspace.js +286 -0
  148. package/dist/esm/ultramodern-workspace/versions.js +74 -29
  149. package/dist/esm/ultramodern-workspace/workspace-artifact-ownership.js +128 -0
  150. package/dist/esm/ultramodern-workspace/workspace-script-plan.js +35 -27
  151. package/dist/esm/ultramodern-workspace/workspace-scripts.js +10 -190
  152. package/dist/esm/ultramodern-workspace/workspace-validation-contract.js +65 -376
  153. package/dist/esm/ultramodern-workspace/write-app.js +18 -10
  154. package/dist/esm/ultramodern-workspace/write-workspace.js +25 -52
  155. package/dist/esm/ultramodern-workspace/zerops.js +2 -0
  156. package/dist/esm-node/cli/package-source.js +3 -3
  157. package/dist/esm-node/cli/project-setup.js +2 -22
  158. package/dist/esm-node/index.js +10 -2
  159. package/dist/esm-node/locale/en.js +2 -1
  160. package/dist/esm-node/locale/zh.js +2 -1
  161. package/dist/esm-node/ultramodern-package-source.js +14 -4
  162. package/dist/esm-node/ultramodern-release-cohort.js +5 -14
  163. package/dist/esm-node/ultramodern-tooling/commands/cloudflare-output-verify.js +49 -56
  164. package/dist/esm-node/ultramodern-tooling/commands/context.js +10 -26
  165. package/dist/esm-node/ultramodern-tooling/commands/routes-generate-app.js +36 -0
  166. package/dist/esm-node/ultramodern-tooling/commands/routes-generate.js +25 -54
  167. package/dist/esm-node/ultramodern-tooling/commands/validate.js +6 -12
  168. package/dist/esm-node/ultramodern-tooling/commands.js +15 -9
  169. package/dist/esm-node/ultramodern-tooling/config/index.js +0 -2
  170. package/dist/esm-node/ultramodern-tooling/config/load.js +9 -9
  171. package/dist/esm-node/ultramodern-tooling/config/metadata.js +33 -28
  172. package/dist/esm-node/ultramodern-tooling/config/normalize.js +159 -156
  173. package/dist/esm-node/ultramodern-workspace/add-shell.js +124 -123
  174. package/dist/esm-node/ultramodern-workspace/add-vertical/execute.js +119 -27
  175. package/dist/esm-node/ultramodern-workspace/add-vertical/plan.js +16 -150
  176. package/dist/esm-node/ultramodern-workspace/add-vertical/preflight.js +15 -47
  177. package/dist/esm-node/ultramodern-workspace/add-vertical/preview.js +41 -0
  178. package/dist/esm-node/ultramodern-workspace/add-vertical/shell-files.js +87 -25
  179. package/dist/esm-node/ultramodern-workspace/add-vertical/topology.js +4 -1
  180. package/dist/esm-node/ultramodern-workspace/add-vertical/transaction.js +373 -46
  181. package/dist/esm-node/ultramodern-workspace/add-vertical/workspace-state.js +17 -34
  182. package/dist/esm-node/ultramodern-workspace/add-vertical.js +1 -1
  183. package/dist/esm-node/ultramodern-workspace/api/client.js +5 -5
  184. package/dist/esm-node/ultramodern-workspace/api/contracts.js +2 -2
  185. package/dist/esm-node/ultramodern-workspace/api/rpc.js +20 -18
  186. package/dist/esm-node/ultramodern-workspace/api/service.js +49 -24
  187. package/dist/esm-node/ultramodern-workspace/api/shared.js +28 -18
  188. package/dist/esm-node/ultramodern-workspace/app-files.js +3 -23
  189. package/dist/esm-node/ultramodern-workspace/backend-federation.js +5 -5
  190. package/dist/esm-node/ultramodern-workspace/contracts.js +14 -180
  191. package/dist/esm-node/ultramodern-workspace/delivery-unit-schema/surfaces.js +42 -0
  192. package/dist/esm-node/ultramodern-workspace/delivery-unit-schema/types.js +1 -75
  193. package/dist/esm-node/ultramodern-workspace/delivery-unit-stamp.js +16 -4
  194. package/dist/esm-node/ultramodern-workspace/delivery-unit-sync.js +28 -18
  195. package/dist/esm-node/ultramodern-workspace/delivery-unit.js +12 -6
  196. package/dist/esm-node/ultramodern-workspace/demo-components.js +67 -428
  197. package/dist/esm-node/ultramodern-workspace/descriptors.js +1 -2
  198. package/dist/esm-node/ultramodern-workspace/fs-io.js +37 -2
  199. package/dist/esm-node/ultramodern-workspace/generation-result.js +3 -3
  200. package/dist/esm-node/ultramodern-workspace/index.js +1 -1
  201. package/dist/esm-node/ultramodern-workspace/mf-validation/constants.js +1 -4
  202. package/dist/esm-node/ultramodern-workspace/mf-validation/discovery.js +7 -7
  203. package/dist/esm-node/ultramodern-workspace/mf-validation/exposes.js +15 -0
  204. package/dist/esm-node/ultramodern-workspace/mf-validation/inspect.js +27 -8
  205. package/dist/esm-node/ultramodern-workspace/mf-validation/object-literal.js +22 -123
  206. package/dist/esm-node/ultramodern-workspace/mf-validation/path-utils.js +36 -34
  207. package/dist/esm-node/ultramodern-workspace/mf-validation/syntax.js +83 -143
  208. package/dist/esm-node/ultramodern-workspace/mf-validation.js +1 -0
  209. package/dist/esm-node/ultramodern-workspace/module-federation/config.js +25 -30
  210. package/dist/esm-node/ultramodern-workspace/module-federation/reexport-module.js +39 -58
  211. package/dist/esm-node/ultramodern-workspace/module-federation/remote-refs.js +1 -43
  212. package/dist/esm-node/ultramodern-workspace/package-json.js +58 -32
  213. package/dist/esm-node/ultramodern-workspace/patch-inventory.js +67 -0
  214. package/dist/esm-node/ultramodern-workspace/policy.js +2 -564
  215. package/dist/esm-node/ultramodern-workspace/public-surface.js +3 -3
  216. package/dist/esm-node/ultramodern-workspace/routes.js +2 -11
  217. package/dist/esm-node/ultramodern-workspace/shared-patches.js +2 -2
  218. package/dist/esm-node/ultramodern-workspace/shells.js +3 -67
  219. package/dist/esm-node/ultramodern-workspace/tooling-command-catalog.js +22 -37
  220. package/dist/esm-node/ultramodern-workspace/tsconfigs.js +9 -3
  221. package/dist/esm-node/ultramodern-workspace/validation/architecture.js +349 -0
  222. package/dist/esm-node/ultramodern-workspace/validation/assertions.js +66 -0
  223. package/dist/esm-node/ultramodern-workspace/validation/types.js +1 -0
  224. package/dist/esm-node/ultramodern-workspace/validation/workspace.js +287 -0
  225. package/dist/esm-node/ultramodern-workspace/versions.js +74 -29
  226. package/dist/esm-node/ultramodern-workspace/workspace-artifact-ownership.js +129 -0
  227. package/dist/esm-node/ultramodern-workspace/workspace-script-plan.js +35 -27
  228. package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +10 -190
  229. package/dist/esm-node/ultramodern-workspace/workspace-validation-contract.js +65 -376
  230. package/dist/esm-node/ultramodern-workspace/write-app.js +18 -10
  231. package/dist/esm-node/ultramodern-workspace/write-workspace.js +25 -52
  232. package/dist/esm-node/ultramodern-workspace/zerops.js +2 -0
  233. package/dist/types/cli/project-setup.d.ts +1 -1
  234. package/dist/types/locale/en.d.ts +1 -0
  235. package/dist/types/locale/index.d.ts +2 -0
  236. package/dist/types/locale/zh.d.ts +1 -0
  237. package/dist/types/ultramodern-package-source.d.ts +2 -4
  238. package/dist/types/ultramodern-release-cohort.d.ts +1 -3
  239. package/dist/types/ultramodern-tooling/commands/cloudflare-output-verify.d.ts +2 -2
  240. package/dist/types/ultramodern-tooling/commands/context.d.ts +4 -1
  241. package/dist/types/ultramodern-tooling/commands/routes-generate-app.d.ts +1 -0
  242. package/dist/types/ultramodern-tooling/commands/routes-generate.d.ts +1 -1
  243. package/dist/types/ultramodern-tooling/commands/validate.d.ts +1 -1
  244. package/dist/types/ultramodern-tooling/config/index.d.ts +0 -2
  245. package/dist/types/ultramodern-tooling/config/load.d.ts +10 -2
  246. package/dist/types/ultramodern-tooling/config/metadata.d.ts +2 -2
  247. package/dist/types/ultramodern-tooling/config/normalize.d.ts +19 -19
  248. package/dist/types/ultramodern-tooling/config/types.d.ts +2 -9
  249. package/dist/types/ultramodern-workspace/add-shell.d.ts +1 -1
  250. package/dist/types/ultramodern-workspace/add-vertical/execute.d.ts +1 -0
  251. package/dist/types/ultramodern-workspace/add-vertical/preflight.d.ts +4 -3
  252. package/dist/types/ultramodern-workspace/add-vertical/preview.d.ts +4 -0
  253. package/dist/types/ultramodern-workspace/add-vertical/shell-files.d.ts +7 -2
  254. package/dist/types/ultramodern-workspace/add-vertical/transaction.d.ts +32 -6
  255. package/dist/types/ultramodern-workspace/add-vertical/workspace-state.d.ts +10 -7
  256. package/dist/types/ultramodern-workspace/add-vertical.d.ts +1 -1
  257. package/dist/types/ultramodern-workspace/api/client.d.ts +3 -1
  258. package/dist/types/ultramodern-workspace/api/rpc.d.ts +1 -1
  259. package/dist/types/ultramodern-workspace/api/service.d.ts +3 -1
  260. package/dist/types/ultramodern-workspace/api/shared.d.ts +2 -0
  261. package/dist/types/ultramodern-workspace/backend-federation.d.ts +1 -1
  262. package/dist/types/ultramodern-workspace/contracts.d.ts +1 -3
  263. package/dist/types/ultramodern-workspace/delivery-unit-schema/surfaces.d.ts +17 -0
  264. package/dist/types/ultramodern-workspace/delivery-unit-schema/types.d.ts +3 -68
  265. package/dist/types/ultramodern-workspace/delivery-unit-stamp.d.ts +2 -2
  266. package/dist/types/ultramodern-workspace/delivery-unit.d.ts +3 -3
  267. package/dist/types/ultramodern-workspace/demo-components.d.ts +0 -3
  268. package/dist/types/ultramodern-workspace/descriptors.d.ts +0 -1
  269. package/dist/types/ultramodern-workspace/fs-io.d.ts +1 -1
  270. package/dist/types/ultramodern-workspace/index.d.ts +1 -1
  271. package/dist/types/ultramodern-workspace/mf-validation/constants.d.ts +0 -1
  272. package/dist/types/ultramodern-workspace/mf-validation/exposes.d.ts +11 -0
  273. package/dist/types/ultramodern-workspace/mf-validation/path-utils.d.ts +2 -3
  274. package/dist/types/ultramodern-workspace/mf-validation/syntax.d.ts +4 -3
  275. package/dist/types/ultramodern-workspace/mf-validation/types.d.ts +1 -0
  276. package/dist/types/ultramodern-workspace/mf-validation.d.ts +1 -0
  277. package/dist/types/ultramodern-workspace/module-federation/config.d.ts +1 -1
  278. package/dist/types/ultramodern-workspace/module-federation/reexport-module.d.ts +2 -2
  279. package/dist/types/ultramodern-workspace/package-json.d.ts +1 -1
  280. package/dist/types/ultramodern-workspace/patch-inventory.d.ts +10 -0
  281. package/dist/types/ultramodern-workspace/policy.d.ts +31 -209
  282. package/dist/types/ultramodern-workspace/routes.d.ts +6 -1
  283. package/dist/types/ultramodern-workspace/shells.d.ts +2 -15
  284. package/dist/types/ultramodern-workspace/tooling-command-catalog.d.ts +8 -7
  285. package/dist/types/ultramodern-workspace/types.d.ts +9 -9
  286. package/dist/types/ultramodern-workspace/validation/architecture.d.ts +2 -0
  287. package/dist/types/ultramodern-workspace/validation/assertions.d.ts +14 -0
  288. package/dist/types/ultramodern-workspace/validation/types.d.ts +9 -0
  289. package/dist/types/ultramodern-workspace/validation/workspace.d.ts +6 -0
  290. package/dist/types/ultramodern-workspace/versions.d.ts +73 -28
  291. package/dist/types/ultramodern-workspace/workspace-artifact-ownership.d.ts +18 -0
  292. package/dist/types/ultramodern-workspace/workspace-script-plan.d.ts +4 -5
  293. package/dist/types/ultramodern-workspace/workspace-scripts.d.ts +8 -13
  294. package/dist/types/ultramodern-workspace/workspace-validation-contract.d.ts +22 -188
  295. package/dist/types/ultramodern-workspace/write-workspace.d.ts +1 -3
  296. package/package.json +18 -11
  297. package/{template-workspace/.modernjs/release-cohort.json → release-cohort.json} +88 -40
  298. package/template-workspace/.codex/skills/rspack-tracing/scripts/analyze_trace.js +1 -1
  299. package/template-workspace/README.md.handlebars +20 -35
  300. package/template-workspace/oxfmt.config.ts +3 -0
  301. package/template-workspace/pnpm-workspace.yaml.handlebars +0 -24
  302. package/template-workspace/scripts/bootstrap-agent-skills.mjs +4 -4
  303. package/templates/packages/shared-contracts-index.ts +4 -332
  304. package/templates/workspace/apps/modern.config.shared-module-federation.ts.handlebars +10 -0
  305. package/templates/workspace/apps/modern.config.ts.handlebars +13 -27
  306. package/templates/workspace/apps/shared/src/routes/ultramodern-route-metadata.ts.handlebars +21 -11
  307. package/templates/workspace/apps/shell-super-app/src/routes/[lang]/page.tsx.handlebars +20 -20
  308. package/templates/workspace/apps/shell-super-app/src/routes/vertical-components.helpers.tsx.handlebars +4 -6
  309. package/templates/workspace/apps/shell-super-app/src/routes/vertical-components.imports.tsx.handlebars +2 -2
  310. package/templates/workspace/apps/shell-super-app/src/routes/vertical-components.tsx.handlebars +11 -11
  311. package/templates/workspace/apps/shell-super-app/src/routes/vertical-components.worker.helpers.tsx.handlebars +1 -1
  312. package/templates/workspace/apps/shell-super-app/src/routes/vertical-components.worker.imports.tsx.handlebars +1 -1
  313. package/templates/workspace-scripts/generate-node-backend-federation.mjs +68 -77
  314. package/templates/workspace-scripts/generate-public-surface-assets.mjs +107 -207
  315. package/templates/workspace-scripts/materialize-zerops-runtime.mjs +12 -19
  316. package/templates/workspace-scripts/proof-cloudflare-version.mjs +53 -444
  317. package/templates/workspace-scripts/proof-node-backend-federation.mjs +212 -91
  318. package/templates/workspace-scripts/{proof-workerd-ssr.mts → proof-workerd-ssr.mjs} +434 -239
  319. package/templates/workspace-scripts/ultramodern-cloudflare-proof.mjs +25 -7
  320. package/templates/workspace-scripts/ultramodern-performance-readiness.mjs +45 -147
  321. package/templates/workspace-scripts/ultramodern-typecheck.mjs +1 -1
  322. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/api-metadata.cjs +0 -212
  323. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/declaration-patches.cjs +0 -47
  324. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/dependency-usage.cjs +0 -112
  325. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-backend-federation.cjs +0 -55
  326. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-build-identity.cjs +0 -102
  327. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-modern-configs.cjs +0 -195
  328. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-oxfmt.cjs +0 -146
  329. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-oxlint.cjs +0 -110
  330. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-removal.cjs +0 -67
  331. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-typescript.cjs +0 -307
  332. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-zerops.cjs +0 -58
  333. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts.cjs +0 -71
  334. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/generated-ui-source.cjs +0 -151
  335. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/help.cjs +0 -67
  336. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/install.cjs +0 -52
  337. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/io.cjs +0 -447
  338. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.cjs +0 -323
  339. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/package-source.cjs +0 -87
  340. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/pnpm-policy.cjs +0 -612
  341. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/pnpm-yaml.cjs +0 -376
  342. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/policy-constants.cjs +0 -73
  343. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/react-router-retirement.cjs +0 -215
  344. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/toolchain-pins.cjs +0 -135
  345. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect.cjs +0 -454
  346. package/dist/cjs/ultramodern-tooling/config/constants.cjs +0 -48
  347. package/dist/cjs/ultramodern-tooling/config/synthesize.cjs +0 -157
  348. package/dist/cjs/ultramodern-workspace/delivery-unit-schema/up-projection.cjs +0 -188
  349. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/api-metadata.js +0 -154
  350. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/declaration-patches.js +0 -9
  351. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/dependency-usage.js +0 -63
  352. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-backend-federation.js +0 -7
  353. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-build-identity.js +0 -47
  354. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-modern-configs.js +0 -146
  355. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-oxfmt.js +0 -97
  356. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-oxlint.js +0 -61
  357. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-removal.js +0 -16
  358. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-typescript.js +0 -258
  359. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-zerops.js +0 -10
  360. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts.js +0 -8
  361. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-patches.js +0 -15
  362. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-ui-source.js +0 -100
  363. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/help.js +0 -29
  364. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/install.js +0 -14
  365. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/io.js +0 -385
  366. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.js +0 -276
  367. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/package-source.js +0 -49
  368. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/pnpm-policy.js +0 -559
  369. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/pnpm-yaml.js +0 -329
  370. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/policy-constants.js +0 -19
  371. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/react-router-retirement.js +0 -148
  372. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/toolchain-pins.js +0 -80
  373. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect.js +0 -405
  374. package/dist/esm/ultramodern-tooling/config/constants.js +0 -4
  375. package/dist/esm/ultramodern-tooling/config/synthesize.js +0 -108
  376. package/dist/esm/ultramodern-workspace/delivery-unit-schema/up-projection.js +0 -129
  377. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/api-metadata.js +0 -155
  378. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/declaration-patches.js +0 -10
  379. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/dependency-usage.js +0 -64
  380. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-backend-federation.js +0 -8
  381. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-build-identity.js +0 -48
  382. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-modern-configs.js +0 -147
  383. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-oxfmt.js +0 -98
  384. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-oxlint.js +0 -62
  385. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-removal.js +0 -17
  386. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-typescript.js +0 -259
  387. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-zerops.js +0 -11
  388. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts.js +0 -9
  389. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-patches.js +0 -16
  390. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-ui-source.js +0 -101
  391. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/help.js +0 -30
  392. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/install.js +0 -15
  393. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/io.js +0 -386
  394. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.js +0 -277
  395. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/package-source.js +0 -50
  396. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/pnpm-policy.js +0 -560
  397. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/pnpm-yaml.js +0 -330
  398. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/policy-constants.js +0 -20
  399. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/react-router-retirement.js +0 -149
  400. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/toolchain-pins.js +0 -81
  401. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect.js +0 -406
  402. package/dist/esm-node/ultramodern-tooling/config/constants.js +0 -5
  403. package/dist/esm-node/ultramodern-tooling/config/synthesize.js +0 -109
  404. package/dist/esm-node/ultramodern-workspace/delivery-unit-schema/up-projection.js +0 -130
  405. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/api-metadata.d.ts +0 -12
  406. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/declaration-patches.d.ts +0 -4
  407. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/dependency-usage.d.ts +0 -1
  408. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-backend-federation.d.ts +0 -3
  409. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-build-identity.d.ts +0 -5
  410. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-modern-configs.d.ts +0 -3
  411. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-oxfmt.d.ts +0 -2
  412. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-oxlint.d.ts +0 -2
  413. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-removal.d.ts +0 -4
  414. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-typescript.d.ts +0 -3
  415. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-zerops.d.ts +0 -3
  416. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts.d.ts +0 -8
  417. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/generated-patches.d.ts +0 -3
  418. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/generated-ui-source.d.ts +0 -3
  419. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/help.d.ts +0 -1
  420. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/install.d.ts +0 -2
  421. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/io.d.ts +0 -26
  422. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.d.ts +0 -25
  423. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/package-source.d.ts +0 -3
  424. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/pnpm-policy.d.ts +0 -26
  425. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/pnpm-yaml.d.ts +0 -26
  426. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/policy-constants.d.ts +0 -6
  427. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/react-router-retirement.d.ts +0 -37
  428. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/toolchain-pins.d.ts +0 -4
  429. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect.d.ts +0 -2
  430. package/dist/types/ultramodern-tooling/config/constants.d.ts +0 -3
  431. package/dist/types/ultramodern-tooling/config/synthesize.d.ts +0 -5
  432. package/dist/types/ultramodern-workspace/delivery-unit-schema/up-projection.d.ts +0 -189
  433. package/template-workspace/patches/@module-federation__bridge-react@2.9.0.patch +0 -47
  434. package/template-workspace/patches/@module-federation__dts-plugin@2.9.0.patch +0 -26
  435. package/template-workspace/patches/@module-federation__modern-js-v3@2.9.0.patch +0 -268
  436. package/template-workspace/patches/@module-federation__runtime-core@2.9.0.patch +0 -13
  437. package/template-workspace/patches/drizzle-orm-ts7-strict-declarations.patch +0 -471
  438. package/template-workspace/patches/msgpackr@2.1.0.patch +0 -30
  439. package/template-workspace/patches/zod@4.5.4.patch +0 -56
  440. package/templates/workspace-scripts/check-ultramodern-api-boundaries.mts +0 -779
  441. package/templates/workspace-scripts/check-ultramodern-i18n-boundaries.mts +0 -9
  442. package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +0 -4109
@@ -11,7 +11,18 @@ class WorkspaceTransactionConflictError extends Error {
11
11
  }
12
12
  const __transactionTestHooks = {};
13
13
  function isIgnoredRelativePath(relativePath) {
14
- return normalizePath(relativePath).split('/').some((segment)=>ignoredSnapshotDirectories.has(segment));
14
+ const segments = normalizePath(relativePath).split('/');
15
+ return segments.some((segment, index)=>{
16
+ if (1 === index && [
17
+ 'apps',
18
+ 'verticals',
19
+ 'packages'
20
+ ].includes(segments[0]) && [
21
+ 'dist',
22
+ 'coverage'
23
+ ].includes(segment)) return false;
24
+ return ignoredSnapshotDirectories.has(segment);
25
+ });
15
26
  }
16
27
  function walkWorkspaceFiles(root, onFile) {
17
28
  if (!node_fs.existsSync(root)) return;
@@ -22,26 +33,30 @@ function walkWorkspaceFiles(root, onFile) {
22
33
  const entryPath = node_path.join(currentDir, entry.name);
23
34
  const relativePath = normalizePath(node_path.relative(root, entryPath));
24
35
  if (!isIgnoredRelativePath(relativePath)) if (entry.isDirectory()) collect(entryPath);
25
- else if (entry.isFile()) onFile(relativePath, entryPath);
36
+ else if (entry.isFile() || entry.isSymbolicLink()) onFile(relativePath, entryPath);
26
37
  else throw new WorkspaceTransactionConflictError(`Staged workspace contains an unsupported link or special file: ${relativePath}`);
27
38
  }
28
39
  };
29
40
  collect(root);
30
41
  }
31
- function captureWorkspace(root) {
42
+ function captureWorkspace(root, publishedRoot = root) {
32
43
  const files = new Map();
33
44
  walkWorkspaceFiles(root, (relativePath, absolutePath)=>{
34
- const stat = node_fs.statSync(absolutePath);
45
+ const stat = node_fs.lstatSync(absolutePath);
46
+ const target = stat.isSymbolicLink() ? node_fs.readlinkSync(absolutePath) : void 0;
35
47
  files.set(relativePath, {
36
- content: node_fs.readFileSync(absolutePath),
37
- mode: 511 & stat.mode
48
+ content: void 0 === target ? node_fs.readFileSync(absolutePath) : Buffer.from(node_path.isAbsolute(target) && isInside(root, target) ? node_path.join(publishedRoot, node_path.relative(root, target)) : target),
49
+ mode: 4095 & stat.mode,
50
+ ...void 0 === target ? {} : {
51
+ symlink: true
52
+ }
38
53
  });
39
54
  });
40
55
  return files;
41
56
  }
42
57
  function sameFile(left, right) {
43
58
  if (void 0 === left || void 0 === right) return left === right;
44
- return left.mode === right.mode && left.content.equals(right.content);
59
+ return left.symlink === right.symlink && left.mode === right.mode && left.content.equals(right.content);
45
60
  }
46
61
  function buildChangePlan(before, after) {
47
62
  return [
@@ -67,7 +82,7 @@ function createTemporarySibling(root) {
67
82
  node_fs.mkdirSync(parent, {
68
83
  recursive: true
69
84
  });
70
- return node_fs.mkdtempSync(node_path.join(parent, `.${node_path.basename(absoluteRoot)}.ultramodern-stage-`));
85
+ return node_fs.realpathSync.native(node_fs.mkdtempSync(node_path.join(parent, `.${node_path.basename(absoluteRoot)}.ultramodern-stage-`)));
71
86
  }
72
87
  function removeOwnedTemporaryDirectory(temporaryRoot, identity) {
73
88
  let current;
@@ -119,6 +134,7 @@ function assertFreshTarget(targetDir, expected) {
119
134
  if ('empty' !== current.kind || current.dev !== expected.dev || current.ino !== expected.ino) throw new WorkspaceTransactionConflictError(`Workspace target changed during generation: ${targetDir}`);
120
135
  }
121
136
  function publishFileExclusive(sourcePath, targetPath) {
137
+ if (node_fs.lstatSync(sourcePath).isSymbolicLink()) return void node_fs.symlinkSync(node_fs.readlinkSync(sourcePath), targetPath);
122
138
  try {
123
139
  node_fs.linkSync(sourcePath, targetPath);
124
140
  } catch (error) {
@@ -131,15 +147,36 @@ function publishFileExclusive(sourcePath, targetPath) {
131
147
  node_fs.copyFileSync(sourcePath, targetPath, node_fs.constants.COPYFILE_EXCL);
132
148
  }
133
149
  }
150
+ function isInside(root, target) {
151
+ const relative = node_path.relative(root, target);
152
+ return '..' !== relative && !relative.startsWith(`..${node_path.sep}`) && !node_path.isAbsolute(relative);
153
+ }
134
154
  function copyWorkspaceToStage(root, stagingRoot) {
155
+ walkWorkspaceFiles(root, (relativePath, absolutePath)=>{
156
+ if (!node_fs.lstatSync(absolutePath).isSymbolicLink()) return;
157
+ let target;
158
+ try {
159
+ target = node_fs.realpathSync.native(absolutePath);
160
+ } catch (cause) {
161
+ throw new WorkspaceTransactionConflictError(`Unsupported dangling or cyclic workspace link: ${relativePath}`, {
162
+ cause
163
+ });
164
+ }
165
+ if (!isInside(root, target) || isIgnoredRelativePath(node_path.relative(root, target))) throw new WorkspaceTransactionConflictError(`Workspace transaction conflict: link escapes the staged input: ${relativePath}`);
166
+ });
135
167
  node_fs.cpSync(root, stagingRoot, {
136
168
  mode: node_fs.constants.COPYFILE_FICLONE,
137
169
  recursive: true,
138
- filter (sourcePath) {
139
- const relativePath = node_path.relative(root, sourcePath);
140
- if ('' === relativePath) return true;
141
- if (isIgnoredRelativePath(relativePath)) return false;
142
- return !node_fs.lstatSync(sourcePath).isSymbolicLink();
170
+ verbatimSymlinks: true,
171
+ filter: (sourcePath)=>!isIgnoredRelativePath(node_path.relative(root, sourcePath))
172
+ });
173
+ walkWorkspaceFiles(stagingRoot, (_relativePath, absolutePath)=>{
174
+ if (!node_fs.lstatSync(absolutePath).isSymbolicLink()) return;
175
+ const target = node_fs.readlinkSync(absolutePath);
176
+ if (node_path.isAbsolute(target)) {
177
+ const realTarget = node_fs.realpathSync.native(target);
178
+ node_fs.unlinkSync(absolutePath);
179
+ node_fs.symlinkSync(node_path.join(stagingRoot, node_path.relative(root, realTarget)), absolutePath);
143
180
  }
144
181
  });
145
182
  }
@@ -159,6 +196,7 @@ function relocateStagedWorkspaceReferences(stagingRoot, workspaceRoot) {
159
196
  const stagedPath = Buffer.from(stagingRoot);
160
197
  const publishedPath = Buffer.from(workspaceRoot);
161
198
  walkWorkspaceFiles(stagingRoot, (_relativePath, absolutePath)=>{
199
+ if (node_fs.lstatSync(absolutePath).isSymbolicLink()) return;
162
200
  const content = node_fs.readFileSync(absolutePath);
163
201
  if (!content.includes(stagedPath)) return;
164
202
  node_fs.writeFileSync(absolutePath, replaceBuffer(content, stagedPath, publishedPath));
@@ -175,10 +213,13 @@ function readFilePath(absolutePath, displayPath) {
175
213
  if ('ENOENT' === error.code) return;
176
214
  throw error;
177
215
  }
178
- if (!stat.isFile()) throw new WorkspaceTransactionConflictError(`Workspace target changed type during generation: ${displayPath}`);
216
+ if (!stat.isFile() && !stat.isSymbolicLink()) throw new WorkspaceTransactionConflictError(`Workspace target changed type during generation: ${displayPath}`);
179
217
  return {
180
- content: node_fs.readFileSync(absolutePath),
181
- mode: 511 & stat.mode
218
+ content: stat.isSymbolicLink() ? Buffer.from(node_fs.readlinkSync(absolutePath)) : node_fs.readFileSync(absolutePath),
219
+ mode: 4095 & stat.mode,
220
+ ...stat.isSymbolicLink() ? {
221
+ symlink: true
222
+ } : {}
182
223
  };
183
224
  }
184
225
  function assertPreimage(root, change) {
@@ -210,6 +251,7 @@ function temporaryFilePath(root, relativePath, role) {
210
251
  return node_path.join(node_path.dirname(targetPath), `.${node_path.basename(targetPath)}.ultramodern-${role}-${randomUUID()}.tmp`);
211
252
  }
212
253
  function writeTemporaryFile(filePath, file) {
254
+ if (file.symlink) return void node_fs.symlinkSync(file.content.toString(), filePath);
213
255
  node_fs.writeFileSync(filePath, file.content, {
214
256
  flag: 'wx',
215
257
  mode: file.mode
@@ -225,19 +267,10 @@ function removeIfPresent(filePath) {
225
267
  if ('ENOENT' !== error.code) throw error;
226
268
  }
227
269
  }
228
- function prepareChanges(root, changes, createdDirectories, preparedChanges) {
229
- for (const change of changes){
230
- ensureOwnedParentDirectories(root, change.relativePath, createdDirectories);
231
- const prepared = {
232
- ...change,
233
- published: false
234
- };
235
- preparedChanges.push(prepared);
236
- if (change.after) {
237
- prepared.publishPath = temporaryFilePath(root, change.relativePath, 'publish');
238
- writeTemporaryFile(prepared.publishPath, change.after);
239
- }
240
- if (change.before) prepared.rollbackPath = temporaryFilePath(root, change.relativePath, change.after ? 'rollback' : 'removed');
270
+ function prepareChanges(root, preparedChanges, createdDirectories) {
271
+ for (const prepared of preparedChanges){
272
+ ensureOwnedParentDirectories(root, prepared.relativePath, createdDirectories);
273
+ if (prepared.after && prepared.publishPath) writeTemporaryFile(prepared.publishPath, prepared.after);
241
274
  }
242
275
  }
243
276
  function assertPublishedState(root, change) {
@@ -393,17 +426,278 @@ function publishChange(root, change) {
393
426
  }
394
427
  change.published = true;
395
428
  }
396
- function publishChangePlan(root, stagingRoot, changes) {
429
+ const receiptSuffix = '.receipt.json';
430
+ function persistReceipt(receiptPath, receipt) {
431
+ const temporary = `${receiptPath}.next`;
432
+ const fd = node_fs.openSync(temporary, 'wx', 384);
433
+ try {
434
+ node_fs.writeFileSync(fd, JSON.stringify(receipt));
435
+ node_fs.fsyncSync(fd);
436
+ } finally{
437
+ node_fs.closeSync(fd);
438
+ }
439
+ node_fs.renameSync(temporary, receiptPath);
440
+ if ('win32' === process.platform) return;
441
+ const directory = node_fs.openSync(node_path.dirname(receiptPath), 'r');
442
+ try {
443
+ node_fs.fsyncSync(directory);
444
+ } finally{
445
+ node_fs.closeSync(directory);
446
+ }
447
+ }
448
+ function encodedReceipt(root, stagingRoot, changes, directories) {
449
+ const encode = (file)=>file ? {
450
+ ...file,
451
+ content: file.content.toString('base64')
452
+ } : void 0;
453
+ const identity = (filePath)=>{
454
+ const { dev, ino } = node_fs.lstatSync(filePath);
455
+ return {
456
+ dev,
457
+ ino
458
+ };
459
+ };
460
+ return {
461
+ schema: 'ultramodern-workspace-transaction-v1',
462
+ root,
463
+ rootIdentity: identity(root),
464
+ stagingIdentity: identity(stagingRoot),
465
+ pid: process.pid,
466
+ state: 'publishing',
467
+ ...directories ? {
468
+ purpose: 'fresh-empty',
469
+ directories
470
+ } : {},
471
+ changes: changes.map((change)=>({
472
+ ...change,
473
+ before: encode(change.before),
474
+ after: encode(change.after)
475
+ }))
476
+ };
477
+ }
478
+ function decodeReceipt(receiptPath, root) {
479
+ const stat = node_fs.lstatSync(receiptPath);
480
+ if (!stat.isFile() || stat.isSymbolicLink() || 'function' == typeof process.getuid && stat.uid !== process.getuid()) throw new WorkspaceTransactionConflictError(`Unsafe interrupted transaction receipt: ${receiptPath}`);
481
+ const receipt = JSON.parse(node_fs.readFileSync(receiptPath, 'utf8'));
482
+ const stagingRoot = receiptPath.slice(0, -receiptSuffix.length);
483
+ if ('ultramodern-workspace-transaction-v1' !== receipt.schema || receipt.root !== root || ![
484
+ 'publishing',
485
+ 'committed'
486
+ ].includes(receipt.state) || !Number.isSafeInteger(receipt.pid) || receipt.pid <= 0 || !sameIdentity(node_fs.lstatSync(root), receipt.rootIdentity) || !sameIdentity(node_fs.lstatSync(stagingRoot), receipt.stagingIdentity) || !Array.isArray(receipt.changes)) throw new WorkspaceTransactionConflictError(`Unrecognized interrupted transaction receipt: ${receiptPath}`);
487
+ const paths = new Set();
488
+ const decode = (file)=>{
489
+ if (void 0 === file) return;
490
+ if (!file || 'string' != typeof file.content || !Number.isInteger(file.mode) || file.mode < 0 || file.mode > 4095 || void 0 !== file.symlink && true !== file.symlink || Buffer.from(file.content, 'base64').toString('base64') !== file.content) throw new WorkspaceTransactionConflictError(`Malformed interrupted transaction preimage: ${receiptPath}`);
491
+ return {
492
+ ...file,
493
+ content: Buffer.from(file.content, 'base64')
494
+ };
495
+ };
496
+ const changes = receipt.changes.map((change)=>{
497
+ const relative = change.relativePath;
498
+ if ('string' != typeof relative || !relative || node_path.isAbsolute(relative) || normalizePath(node_path.normalize(relative)) !== relative || !isInside(root, node_path.resolve(root, relative)) || isIgnoredRelativePath(relative) || paths.has(relative)) throw new WorkspaceTransactionConflictError(`Unsafe interrupted transaction target: ${String(relative)}`);
499
+ paths.add(relative);
500
+ for (const temporary of [
501
+ change.publishPath,
502
+ change.rollbackPath
503
+ ])if (void 0 !== temporary && ('string' != typeof temporary || node_path.dirname(temporary) !== node_path.dirname(node_path.join(root, relative)) || !node_path.basename(temporary).startsWith(`.${node_path.basename(relative)}.ultramodern-`) || !temporary.endsWith('.tmp'))) throw new WorkspaceTransactionConflictError(`Unsafe interrupted transaction temporary: ${String(temporary)}`);
504
+ return {
505
+ relativePath: relative,
506
+ before: decode(change.before),
507
+ after: decode(change.after),
508
+ publishPath: change.publishPath,
509
+ rollbackPath: change.rollbackPath,
510
+ published: false
511
+ };
512
+ });
513
+ if (void 0 !== receipt.purpose && 'fresh-empty' !== receipt.purpose) throw new WorkspaceTransactionConflictError(`Unknown transaction purpose: ${receiptPath}`);
514
+ if ('fresh-empty' === receipt.purpose) {
515
+ const expected = freshParentPaths(changes);
516
+ if (!Array.isArray(receipt.directories) || receipt.directories.length !== expected.length || changes.some((change)=>void 0 !== change.before || void 0 === change.after) || receipt.directories.some((directory, index)=>!directory || directory.relativePath !== expected[index] || 'string' != typeof directory.temporaryPath || node_path.dirname(directory.temporaryPath) !== stagingRoot || !/^\.ultramodern-directory-[\da-f-]+\.tmp$/u.test(node_path.basename(directory.temporaryPath)) || !Number.isInteger(directory.dev) || !Number.isInteger(directory.ino)) || new Set(receipt.directories.map((directory)=>directory.temporaryPath)).size !== expected.length) throw new WorkspaceTransactionConflictError(`Unsafe fresh transaction directories: ${receiptPath}`);
517
+ } else if (void 0 !== receipt.directories) throw new WorkspaceTransactionConflictError(`Unexpected transaction directories: ${receiptPath}`);
518
+ return {
519
+ receipt,
520
+ changes
521
+ };
522
+ }
523
+ function freshParentPaths(changes) {
524
+ const parents = new Set();
525
+ for (const change of changes){
526
+ const segments = change.relativePath.split('/');
527
+ for(let length = 1; length < segments.length; length++)parents.add(segments.slice(0, length).join('/'));
528
+ }
529
+ return [
530
+ ...parents
531
+ ].sort((left, right)=>left.split('/').length - right.split('/').length || left.localeCompare(right));
532
+ }
533
+ function stageFreshDirectories(stagingRoot, changes) {
534
+ return freshParentPaths(changes).map((relativePath)=>{
535
+ const temporaryPath = node_path.join(stagingRoot, `.ultramodern-directory-${randomUUID()}.tmp`);
536
+ node_fs.mkdirSync(temporaryPath, {
537
+ mode: 511 & node_fs.statSync(node_path.join(stagingRoot, relativePath)).mode
538
+ });
539
+ const { dev, ino } = node_fs.lstatSync(temporaryPath);
540
+ return {
541
+ relativePath,
542
+ temporaryPath,
543
+ dev,
544
+ ino
545
+ };
546
+ });
547
+ }
548
+ function assertFreshDirectoryAncestors(root, receipt, relativePath) {
549
+ const ancestors = relativePath.split('/').slice(0, -1);
550
+ for(let length = 0; length <= ancestors.length; length++){
551
+ const relative = ancestors.slice(0, length).join('/');
552
+ const expected = 0 === length ? receipt.rootIdentity : receipt.directories.find((directory)=>directory.relativePath === relative);
553
+ const candidate = node_path.join(root, relative);
554
+ const stat = node_fs.lstatSync(candidate);
555
+ if (!stat.isDirectory() || stat.isSymbolicLink() || !sameIdentity(stat, expected)) throw new WorkspaceTransactionConflictError(`Fresh transaction parent changed; preserved at ${candidate}`);
556
+ }
557
+ }
558
+ function publishFreshDirectory(root, receipt, directory) {
559
+ const target = node_path.join(root, directory.relativePath);
560
+ assertFreshDirectoryAncestors(root, receipt, directory.relativePath);
561
+ const staged = node_fs.lstatSync(directory.temporaryPath);
562
+ const stagingRoot = node_path.dirname(directory.temporaryPath);
563
+ if (!staged.isDirectory() || staged.isSymbolicLink() || !sameIdentity(staged, directory) || !sameIdentity(node_fs.lstatSync(stagingRoot), receipt.stagingIdentity)) throw new WorkspaceTransactionConflictError(`Fresh transaction staged directory changed: ${directory.temporaryPath}`);
564
+ if (node_fs.existsSync(target)) throw new WorkspaceTransactionConflictError(`Fresh transaction directory appeared: ${target}`);
565
+ node_fs.renameSync(directory.temporaryPath, target);
566
+ try {
567
+ assertFreshDirectoryAncestors(root, receipt, directory.relativePath);
568
+ const published = node_fs.lstatSync(target);
569
+ if (!published.isDirectory() || published.isSymbolicLink() || !sameIdentity(published, directory)) throw new WorkspaceTransactionConflictError(`Fresh transaction directory changed; preserved at ${target}`);
570
+ } catch (error) {
571
+ throw new WorkspaceTransactionConflictError(`Fresh directory publication could not validate ownership at ${target}; no cleanup attempted through this path`, {
572
+ cause: error
573
+ });
574
+ }
575
+ }
576
+ function validateFreshDirectories(root, receipt, changes) {
577
+ const directories = receipt.directories;
578
+ const allowed = new Set(directories.map((directory)=>node_path.join(root, directory.relativePath)));
579
+ for (const change of changes){
580
+ allowed.add(node_path.join(root, change.relativePath));
581
+ if (change.publishPath) allowed.add(change.publishPath);
582
+ }
583
+ const liveDirectories = [
584
+ root
585
+ ];
586
+ for (const directory of directories)for (const candidate of [
587
+ node_path.join(root, directory.relativePath),
588
+ directory.temporaryPath
589
+ ]){
590
+ let stat;
591
+ try {
592
+ stat = node_fs.lstatSync(candidate);
593
+ } catch (error) {
594
+ if ('ENOENT' === error.code) continue;
595
+ throw error;
596
+ }
597
+ if (!stat.isDirectory() || stat.isSymbolicLink() || !sameIdentity(stat, directory)) throw new WorkspaceTransactionConflictError(`Fresh transaction directory changed; preserved at ${candidate}`);
598
+ if (candidate !== directory.temporaryPath) liveDirectories.push(candidate);
599
+ }
600
+ if ('committed' === receipt.state) return;
601
+ for (const directory of liveDirectories)for (const entry of node_fs.readdirSync(directory))if (!allowed.has(node_path.join(directory, entry))) throw new WorkspaceTransactionConflictError(`Fresh transaction conflicts with newer consumer path: ${node_path.join(directory, entry)}`);
602
+ }
603
+ function removeFreshDirectories(root, directories) {
604
+ for (const directory of [
605
+ ...directories
606
+ ].reverse()){
607
+ const target = node_path.join(root, directory.relativePath);
608
+ let stat;
609
+ try {
610
+ stat = node_fs.lstatSync(target);
611
+ } catch (error) {
612
+ if ('ENOENT' === error.code) continue;
613
+ throw error;
614
+ }
615
+ if (!stat.isDirectory() || stat.isSymbolicLink() || !sameIdentity(stat, directory)) throw new WorkspaceTransactionConflictError(`Fresh transaction directory changed; preserved at ${target}`);
616
+ node_fs.rmdirSync(target);
617
+ }
618
+ }
619
+ function recoverFreshWorkspaceTransactions(root) {
620
+ try {
621
+ const stat = node_fs.lstatSync(root);
622
+ if (!stat.isDirectory() || stat.isSymbolicLink()) return;
623
+ } catch (error) {
624
+ if ('ENOENT' === error.code) return;
625
+ throw error;
626
+ }
627
+ recoverWorkspaceTransactions(root, 'fresh-empty');
628
+ }
629
+ function recoverWorkspaceTransactions(root, purpose = 'update') {
630
+ const workspaceRoot = node_fs.realpathSync.native(root);
631
+ const parent = node_path.dirname(workspaceRoot);
632
+ const prefix = `.${node_path.basename(workspaceRoot)}.ultramodern-stage-`;
633
+ for (const entry of node_fs.readdirSync(parent).sort()){
634
+ if (!entry.startsWith(prefix) || !entry.endsWith(receiptSuffix)) continue;
635
+ const receiptPath = node_path.join(parent, entry);
636
+ const { receipt, changes } = decodeReceipt(receiptPath, workspaceRoot);
637
+ if ((receipt.purpose ?? 'update') === purpose) {
638
+ try {
639
+ process.kill(receipt.pid, 0);
640
+ throw new WorkspaceTransactionConflictError(`Workspace publication is still owned by process ${receipt.pid}: ${receiptPath}`);
641
+ } catch (error) {
642
+ if ('ESRCH' !== error.code) throw error;
643
+ }
644
+ if ('fresh-empty' === receipt.purpose) validateFreshDirectories(workspaceRoot, receipt, changes);
645
+ for (const change of changes){
646
+ if ('fresh-empty' !== receipt.purpose) ensureOwnedParentDirectories(workspaceRoot, change.relativePath, []);
647
+ for (const [temporary, expected] of [
648
+ [
649
+ change.publishPath,
650
+ change.after
651
+ ],
652
+ [
653
+ change.rollbackPath,
654
+ change.before
655
+ ]
656
+ ])if (temporary && node_fs.existsSync(temporary) && !sameFile(readFilePath(temporary, temporary), expected)) throw new WorkspaceTransactionConflictError(`Interrupted transaction temporary changed; preserved at ${temporary}`);
657
+ if ('committed' === receipt.state) continue;
658
+ const current = readWorkspaceFile(workspaceRoot, change.relativePath);
659
+ if (!sameFile(current, change.before)) if (sameFile(current, change.after)) {
660
+ change.published = true;
661
+ if (change.before && change.rollbackPath && !node_fs.existsSync(change.rollbackPath)) writeTemporaryFile(change.rollbackPath, change.before);
662
+ } else if (void 0 === current && change.before && change.rollbackPath && node_fs.existsSync(change.rollbackPath)) {
663
+ if (!restoreQuarantinedPreimage(change, node_path.join(workspaceRoot, change.relativePath))) throw new WorkspaceTransactionConflictError(`Interrupted preimage cannot be restored: ${change.relativePath}`);
664
+ } else throw new WorkspaceTransactionConflictError(`Interrupted transaction conflicts with newer consumer bytes: ${change.relativePath}; receipt ${receiptPath}`);
665
+ }
666
+ if ('publishing' === receipt.state) rollbackPublishedChanges(workspaceRoot, changes);
667
+ cleanupPreparedChanges(changes, []);
668
+ if ('fresh-empty' === receipt.purpose && 'publishing' === receipt.state) removeFreshDirectories(workspaceRoot, receipt.directories);
669
+ removeOwnedTemporaryDirectory(receiptPath.slice(0, -receiptSuffix.length), receipt.stagingIdentity);
670
+ removeIfPresent(receiptPath);
671
+ }
672
+ }
673
+ }
674
+ function publishChangePlan(root, stagingRoot, changes, emptyTarget) {
397
675
  __transactionTestHooks.beforePublish?.({
398
676
  workspaceRoot: root,
399
677
  stagingRoot,
400
678
  changedPaths: changes.map((change)=>change.relativePath)
401
679
  });
680
+ if (emptyTarget) assertFreshTarget(root, emptyTarget);
402
681
  for (const change of changes)assertPreimage(root, change);
682
+ if (0 === changes.length) return;
403
683
  const createdDirectories = [];
404
- const preparedChanges = [];
684
+ const preparedChanges = changes.map((change)=>({
685
+ ...change,
686
+ published: false,
687
+ ...change.after ? {
688
+ publishPath: temporaryFilePath(root, change.relativePath, 'publish')
689
+ } : {},
690
+ ...change.before ? {
691
+ rollbackPath: temporaryFilePath(root, change.relativePath, 'rollback')
692
+ } : {}
693
+ }));
694
+ const receiptPath = `${stagingRoot}${receiptSuffix}`;
695
+ const directories = emptyTarget ? stageFreshDirectories(stagingRoot, changes) : void 0;
696
+ const receipt = encodedReceipt(root, stagingRoot, preparedChanges, directories);
697
+ persistReceipt(receiptPath, receipt);
405
698
  try {
406
- prepareChanges(root, changes, createdDirectories, preparedChanges);
699
+ for (const directory of directories ?? [])publishFreshDirectory(root, receipt, directory);
700
+ prepareChanges(root, preparedChanges, createdDirectories);
407
701
  for (const change of preparedChanges)assertPreimage(root, change);
408
702
  preparedChanges.forEach((change, index)=>{
409
703
  __transactionTestHooks.beforePublishPath?.({
@@ -412,36 +706,67 @@ function publishChangePlan(root, stagingRoot, changes) {
412
706
  index
413
707
  });
414
708
  publishChange(root, change);
709
+ __transactionTestHooks.afterPublishPath?.({
710
+ workspaceRoot: root,
711
+ relativePath: change.relativePath,
712
+ index
713
+ });
714
+ });
715
+ persistReceipt(receiptPath, {
716
+ ...receipt,
717
+ state: 'committed'
415
718
  });
416
719
  } catch (error) {
417
720
  try {
721
+ if (directories) validateFreshDirectories(root, receipt, preparedChanges);
418
722
  rollbackPublishedChanges(root, preparedChanges);
723
+ if (directories) {
724
+ cleanupPreparedChanges(preparedChanges, []);
725
+ removeFreshDirectories(root, directories);
726
+ }
419
727
  } catch (rollbackError) {
420
- throw new WorkspaceTransactionConflictError('Workspace transaction failed and concurrent target changes prevented a safe rollback.', {
421
- cause: rollbackError
728
+ throw new WorkspaceTransactionConflictError(`Workspace transaction failed and concurrent target changes prevented a safe rollback; recovery receipt ${receiptPath}.`, {
729
+ cause: directories ? new AggregateError([
730
+ error,
731
+ rollbackError
732
+ ], 'Fresh publication and rollback conflicts') : rollbackError
422
733
  });
423
- } finally{
424
- cleanPreparedChanges(preparedChanges, createdDirectories);
425
734
  }
735
+ cleanPreparedChanges(preparedChanges, createdDirectories);
736
+ if (!preparedChanges.some((change)=>change.preserveRollback || change.preservedPaths?.length)) removeIfPresent(receiptPath);
426
737
  throw error;
427
738
  }
428
739
  cleanPreparedChanges(preparedChanges, []);
740
+ removeIfPresent(receiptPath);
429
741
  }
430
- function runWorkspaceTransaction(root, mutate) {
742
+ function runWorkspaceTransaction(root, mutate, options = {}) {
431
743
  const workspaceRoot = node_fs.realpathSync.native(node_path.resolve(root));
432
744
  if (!node_fs.statSync(workspaceRoot).isDirectory()) throw new Error(`Workspace root is not a directory: ${root}`);
745
+ if ('preview' !== options.mode) recoverWorkspaceTransactions(workspaceRoot);
433
746
  const stagingRoot = createTemporarySibling(workspaceRoot);
434
747
  const stagingIdentity = node_fs.lstatSync(stagingRoot);
748
+ const cleanup = ()=>{
749
+ if (!node_fs.existsSync(`${stagingRoot}${receiptSuffix}`)) cleanOwnedTemporaryDirectory(stagingRoot, stagingIdentity);
750
+ };
435
751
  try {
436
752
  copyWorkspaceToStage(workspaceRoot, stagingRoot);
437
- const before = captureWorkspace(stagingRoot);
753
+ const before = captureWorkspace(stagingRoot, workspaceRoot);
754
+ const finish = (result)=>{
755
+ if (options.commitWhen && !options.commitWhen(result)) return result;
756
+ relocateStagedWorkspaceReferences(stagingRoot, root);
757
+ const changes = buildChangePlan(before, captureWorkspace(stagingRoot, workspaceRoot));
758
+ options.inspectChanges?.(changes);
759
+ if ('preview' !== options.mode) publishChangePlan(workspaceRoot, stagingRoot, changes);
760
+ return result;
761
+ };
438
762
  const result = mutate(stagingRoot);
439
- relocateStagedWorkspaceReferences(stagingRoot, root);
440
- const changes = buildChangePlan(before, captureWorkspace(stagingRoot));
441
- publishChangePlan(workspaceRoot, stagingRoot, changes);
442
- return result;
443
- } finally{
444
- cleanOwnedTemporaryDirectory(stagingRoot, stagingIdentity);
763
+ if (null !== result && ('object' == typeof result || 'function' == typeof result) && 'function' == typeof result.then) return Promise.resolve(result).then(finish).finally(cleanup);
764
+ const completed = finish(result);
765
+ cleanup();
766
+ return completed;
767
+ } catch (error) {
768
+ cleanup();
769
+ throw error;
445
770
  }
446
771
  }
447
772
  function sameIdentity(stat, identity) {
@@ -482,6 +807,7 @@ function cleanEmptyTargetRollback(rollbackPath, expected) {
482
807
  function publishFreshWorkspace(stagingRoot, workspaceRoot, target) {
483
808
  assertFreshTarget(workspaceRoot, target);
484
809
  if ('absent' === target.kind) return void node_fs.renameSync(stagingRoot, workspaceRoot);
810
+ if ('win32' === process.platform && currentDirectoryIs(workspaceRoot)) return void publishChangePlan(node_fs.realpathSync.native(workspaceRoot), stagingRoot, buildChangePlan(new Map(), captureWorkspace(stagingRoot, workspaceRoot)), target);
485
811
  const rollbackPath = node_path.join(node_path.dirname(workspaceRoot), `.${node_path.basename(workspaceRoot)}.ultramodern-empty-${randomUUID()}.tmp`);
486
812
  const restoreCwd = currentDirectoryIs(workspaceRoot);
487
813
  node_fs.renameSync(workspaceRoot, rollbackPath);
@@ -510,6 +836,7 @@ function publishFreshWorkspace(stagingRoot, workspaceRoot, target) {
510
836
  }
511
837
  function runFreshWorkspaceTransaction(targetDir, generate) {
512
838
  const workspaceRoot = node_path.resolve(targetDir);
839
+ recoverFreshWorkspaceTransactions(workspaceRoot);
513
840
  const target = inspectFreshTarget(workspaceRoot);
514
841
  const stagingRoot = createTemporarySibling(workspaceRoot);
515
842
  const stagingIdentity = node_fs.lstatSync(stagingRoot);
@@ -523,7 +850,7 @@ function runFreshWorkspaceTransaction(targetDir, generate) {
523
850
  publishFreshWorkspace(stagingRoot, workspaceRoot, target);
524
851
  return result;
525
852
  } finally{
526
- cleanOwnedTemporaryDirectory(stagingRoot, stagingIdentity);
853
+ if (!node_fs.existsSync(`${stagingRoot}${receiptSuffix}`)) cleanOwnedTemporaryDirectory(stagingRoot, stagingIdentity);
527
854
  }
528
855
  }
529
- export { WorkspaceTransactionConflictError, __transactionTestHooks, relocateStagedWorkspaceReferences, runFreshWorkspaceTransaction, runWorkspaceTransaction };
856
+ export { WorkspaceTransactionConflictError, __transactionTestHooks, recoverFreshWorkspaceTransactions, recoverWorkspaceTransactions, relocateStagedWorkspaceReferences, runFreshWorkspaceTransaction, runWorkspaceTransaction };
@@ -1,47 +1,35 @@
1
1
  import node_fs from "node:fs";
2
2
  import node_path from "node:path";
3
- import { readUltramodernConfig } from "../../ultramodern-tooling/config.js";
4
- import { ULTRAMODERN_CONFIG_PATH } from "../descriptors.js";
5
3
  import { toKebabCase } from "../naming.js";
6
4
  import { resolvePackageSource } from "../package-source.js";
7
5
  import { FIRST_VERTICAL_PORT } from "./constants.js";
8
- function existingPackageSource(workspaceRoot, modernVersion, packageSource) {
9
- if (packageSource) return resolvePackageSource({
10
- targetDir: workspaceRoot,
11
- packageName: node_path.basename(workspaceRoot),
12
- modernVersion,
13
- packageSource
14
- });
15
- const compactPath = node_path.join(workspaceRoot, ULTRAMODERN_CONFIG_PATH);
16
- if (node_fs.existsSync(compactPath)) {
17
- const compactConfig = readUltramodernConfig(workspaceRoot);
18
- if (compactConfig.packageSource) return compactConfig.packageSource;
19
- }
20
- throw new Error(`Missing UltraModern workspace file: ${compactPath}`);
21
- }
22
- function existingTailwindEnabled(workspaceRoot) {
23
- const compactPath = node_path.join(workspaceRoot, ULTRAMODERN_CONFIG_PATH);
24
- if (node_fs.existsSync(compactPath)) return readUltramodernConfig(workspaceRoot).features.tailwind;
25
- throw new Error(`Missing UltraModern workspace file: ${compactPath}`);
26
- }
27
- function existingBridgeConfig(workspaceRoot) {
28
- const compactPath = node_path.join(workspaceRoot, ULTRAMODERN_CONFIG_PATH);
29
- return node_fs.existsSync(compactPath) ? readUltramodernConfig(workspaceRoot).bridge : void 0;
6
+ function workspaceOperationSettings(options, config) {
7
+ const packageSource = options.packageSource ? resolvePackageSource({
8
+ targetDir: options.workspaceRoot,
9
+ packageName: node_path.basename(options.workspaceRoot),
10
+ modernVersion: options.modernVersion,
11
+ packageSource: options.packageSource
12
+ }) : config.packageSource;
13
+ if (!packageSource) throw new Error(`Missing UltraModern package source in workspace manifests: ${options.workspaceRoot}`);
14
+ return {
15
+ packageSource,
16
+ enableTailwind: options.enableTailwind ?? config.features.tailwind,
17
+ bridge: void 0
18
+ };
30
19
  }
31
20
  function assertValidVerticalName(name) {
32
21
  const normalized = toKebabCase(name);
33
22
  if (!normalized || normalized !== name) throw new Error(`Invalid Vertical name "${name}". Use lowercase kebab-case.`);
34
23
  return normalized;
35
24
  }
36
- function configuredDevelopmentPorts(ports, additionalShells = []) {
25
+ function configuredDevelopmentPorts(ports, _additionalShells = []) {
37
26
  return [
38
27
  ...new Set([
39
- ...Object.values(ports),
40
- ...additionalShells.map((shell)=>shell.port)
28
+ ...Object.values(ports)
41
29
  ].filter((value)=>'number' == typeof value && Number.isFinite(value)))
42
30
  ];
43
31
  }
44
- function assertGlobalPortUniqueness(ports, additionalShells = []) {
32
+ function assertGlobalPortUniqueness(ports, _additionalShells = []) {
45
33
  const owners = new Map();
46
34
  for (const [id, value] of Object.entries(ports)){
47
35
  if ('number' != typeof value || !Number.isFinite(value)) continue;
@@ -49,11 +37,6 @@ function assertGlobalPortUniqueness(ports, additionalShells = []) {
49
37
  if (previous) throw new Error(`Duplicate development port "${value}" for ${previous} and ${id}.`);
50
38
  owners.set(value, id);
51
39
  }
52
- for (const shell of additionalShells){
53
- const previous = owners.get(shell.port);
54
- if (previous) throw new Error(`Duplicate development port "${shell.port}" for ${previous} and ${shell.id}.`);
55
- owners.set(shell.port, shell.id);
56
- }
57
40
  }
58
41
  function nextAvailablePort(ports, additionalShells = [], minimumPort = FIRST_VERTICAL_PORT) {
59
42
  const used = new Set(configuredDevelopmentPorts(ports, additionalShells));
@@ -64,4 +47,4 @@ function nextAvailablePort(ports, additionalShells = [], minimumPort = FIRST_VER
64
47
  function assertCanCreate(workspaceRoot, relativePath) {
65
48
  if (node_fs.existsSync(node_path.join(workspaceRoot, relativePath))) throw new Error(`Refusing to overwrite existing path: ${relativePath}`);
66
49
  }
67
- export { assertCanCreate, assertGlobalPortUniqueness, assertValidVerticalName, configuredDevelopmentPorts, existingBridgeConfig, existingPackageSource, existingTailwindEnabled, nextAvailablePort };
50
+ export { assertCanCreate, assertGlobalPortUniqueness, assertValidVerticalName, configuredDevelopmentPorts, nextAvailablePort, workspaceOperationSettings };
@@ -3,4 +3,4 @@ export { planUltramodernVertical } from "./add-vertical/plan.js";
3
3
  export { prepareAddUltramodernVertical } from "./add-vertical/preflight.js";
4
4
  export { rewriteShellAppFiles, updateRootWorkspaceScripts } from "./add-vertical/shell-files.js";
5
5
  export { ownershipEntry, verticalTopologyEntry, verticalsFromTopology } from "./add-vertical/topology.js";
6
- export { assertCanCreate, assertValidVerticalName, existingBridgeConfig, existingPackageSource, existingTailwindEnabled, nextAvailablePort } from "./add-vertical/workspace-state.js";
6
+ export { assertCanCreate, assertValidVerticalName, nextAvailablePort } from "./add-vertical/workspace-state.js";