@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
@@ -12,7 +12,18 @@ class WorkspaceTransactionConflictError extends Error {
12
12
  }
13
13
  const __transactionTestHooks = {};
14
14
  function isIgnoredRelativePath(relativePath) {
15
- return normalizePath(relativePath).split('/').some((segment)=>ignoredSnapshotDirectories.has(segment));
15
+ const segments = normalizePath(relativePath).split('/');
16
+ return segments.some((segment, index)=>{
17
+ if (1 === index && [
18
+ 'apps',
19
+ 'verticals',
20
+ 'packages'
21
+ ].includes(segments[0]) && [
22
+ 'dist',
23
+ 'coverage'
24
+ ].includes(segment)) return false;
25
+ return ignoredSnapshotDirectories.has(segment);
26
+ });
16
27
  }
17
28
  function walkWorkspaceFiles(root, onFile) {
18
29
  if (!node_fs.existsSync(root)) return;
@@ -23,26 +34,30 @@ function walkWorkspaceFiles(root, onFile) {
23
34
  const entryPath = node_path.join(currentDir, entry.name);
24
35
  const relativePath = normalizePath(node_path.relative(root, entryPath));
25
36
  if (!isIgnoredRelativePath(relativePath)) if (entry.isDirectory()) collect(entryPath);
26
- else if (entry.isFile()) onFile(relativePath, entryPath);
37
+ else if (entry.isFile() || entry.isSymbolicLink()) onFile(relativePath, entryPath);
27
38
  else throw new WorkspaceTransactionConflictError(`Staged workspace contains an unsupported link or special file: ${relativePath}`);
28
39
  }
29
40
  };
30
41
  collect(root);
31
42
  }
32
- function captureWorkspace(root) {
43
+ function captureWorkspace(root, publishedRoot = root) {
33
44
  const files = new Map();
34
45
  walkWorkspaceFiles(root, (relativePath, absolutePath)=>{
35
- const stat = node_fs.statSync(absolutePath);
46
+ const stat = node_fs.lstatSync(absolutePath);
47
+ const target = stat.isSymbolicLink() ? node_fs.readlinkSync(absolutePath) : void 0;
36
48
  files.set(relativePath, {
37
- content: node_fs.readFileSync(absolutePath),
38
- mode: 511 & stat.mode
49
+ 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),
50
+ mode: 4095 & stat.mode,
51
+ ...void 0 === target ? {} : {
52
+ symlink: true
53
+ }
39
54
  });
40
55
  });
41
56
  return files;
42
57
  }
43
58
  function sameFile(left, right) {
44
59
  if (void 0 === left || void 0 === right) return left === right;
45
- return left.mode === right.mode && left.content.equals(right.content);
60
+ return left.symlink === right.symlink && left.mode === right.mode && left.content.equals(right.content);
46
61
  }
47
62
  function buildChangePlan(before, after) {
48
63
  return [
@@ -68,7 +83,7 @@ function createTemporarySibling(root) {
68
83
  node_fs.mkdirSync(parent, {
69
84
  recursive: true
70
85
  });
71
- return node_fs.mkdtempSync(node_path.join(parent, `.${node_path.basename(absoluteRoot)}.ultramodern-stage-`));
86
+ return node_fs.realpathSync.native(node_fs.mkdtempSync(node_path.join(parent, `.${node_path.basename(absoluteRoot)}.ultramodern-stage-`)));
72
87
  }
73
88
  function removeOwnedTemporaryDirectory(temporaryRoot, identity) {
74
89
  let current;
@@ -120,6 +135,7 @@ function assertFreshTarget(targetDir, expected) {
120
135
  if ('empty' !== current.kind || current.dev !== expected.dev || current.ino !== expected.ino) throw new WorkspaceTransactionConflictError(`Workspace target changed during generation: ${targetDir}`);
121
136
  }
122
137
  function publishFileExclusive(sourcePath, targetPath) {
138
+ if (node_fs.lstatSync(sourcePath).isSymbolicLink()) return void node_fs.symlinkSync(node_fs.readlinkSync(sourcePath), targetPath);
123
139
  try {
124
140
  node_fs.linkSync(sourcePath, targetPath);
125
141
  } catch (error) {
@@ -132,15 +148,36 @@ function publishFileExclusive(sourcePath, targetPath) {
132
148
  node_fs.copyFileSync(sourcePath, targetPath, node_fs.constants.COPYFILE_EXCL);
133
149
  }
134
150
  }
151
+ function isInside(root, target) {
152
+ const relative = node_path.relative(root, target);
153
+ return '..' !== relative && !relative.startsWith(`..${node_path.sep}`) && !node_path.isAbsolute(relative);
154
+ }
135
155
  function copyWorkspaceToStage(root, stagingRoot) {
156
+ walkWorkspaceFiles(root, (relativePath, absolutePath)=>{
157
+ if (!node_fs.lstatSync(absolutePath).isSymbolicLink()) return;
158
+ let target;
159
+ try {
160
+ target = node_fs.realpathSync.native(absolutePath);
161
+ } catch (cause) {
162
+ throw new WorkspaceTransactionConflictError(`Unsupported dangling or cyclic workspace link: ${relativePath}`, {
163
+ cause
164
+ });
165
+ }
166
+ if (!isInside(root, target) || isIgnoredRelativePath(node_path.relative(root, target))) throw new WorkspaceTransactionConflictError(`Workspace transaction conflict: link escapes the staged input: ${relativePath}`);
167
+ });
136
168
  node_fs.cpSync(root, stagingRoot, {
137
169
  mode: node_fs.constants.COPYFILE_FICLONE,
138
170
  recursive: true,
139
- filter (sourcePath) {
140
- const relativePath = node_path.relative(root, sourcePath);
141
- if ('' === relativePath) return true;
142
- if (isIgnoredRelativePath(relativePath)) return false;
143
- return !node_fs.lstatSync(sourcePath).isSymbolicLink();
171
+ verbatimSymlinks: true,
172
+ filter: (sourcePath)=>!isIgnoredRelativePath(node_path.relative(root, sourcePath))
173
+ });
174
+ walkWorkspaceFiles(stagingRoot, (_relativePath, absolutePath)=>{
175
+ if (!node_fs.lstatSync(absolutePath).isSymbolicLink()) return;
176
+ const target = node_fs.readlinkSync(absolutePath);
177
+ if (node_path.isAbsolute(target)) {
178
+ const realTarget = node_fs.realpathSync.native(target);
179
+ node_fs.unlinkSync(absolutePath);
180
+ node_fs.symlinkSync(node_path.join(stagingRoot, node_path.relative(root, realTarget)), absolutePath);
144
181
  }
145
182
  });
146
183
  }
@@ -160,6 +197,7 @@ function relocateStagedWorkspaceReferences(stagingRoot, workspaceRoot) {
160
197
  const stagedPath = Buffer.from(stagingRoot);
161
198
  const publishedPath = Buffer.from(workspaceRoot);
162
199
  walkWorkspaceFiles(stagingRoot, (_relativePath, absolutePath)=>{
200
+ if (node_fs.lstatSync(absolutePath).isSymbolicLink()) return;
163
201
  const content = node_fs.readFileSync(absolutePath);
164
202
  if (!content.includes(stagedPath)) return;
165
203
  node_fs.writeFileSync(absolutePath, replaceBuffer(content, stagedPath, publishedPath));
@@ -176,10 +214,13 @@ function readFilePath(absolutePath, displayPath) {
176
214
  if ('ENOENT' === error.code) return;
177
215
  throw error;
178
216
  }
179
- if (!stat.isFile()) throw new WorkspaceTransactionConflictError(`Workspace target changed type during generation: ${displayPath}`);
217
+ if (!stat.isFile() && !stat.isSymbolicLink()) throw new WorkspaceTransactionConflictError(`Workspace target changed type during generation: ${displayPath}`);
180
218
  return {
181
- content: node_fs.readFileSync(absolutePath),
182
- mode: 511 & stat.mode
219
+ content: stat.isSymbolicLink() ? Buffer.from(node_fs.readlinkSync(absolutePath)) : node_fs.readFileSync(absolutePath),
220
+ mode: 4095 & stat.mode,
221
+ ...stat.isSymbolicLink() ? {
222
+ symlink: true
223
+ } : {}
183
224
  };
184
225
  }
185
226
  function assertPreimage(root, change) {
@@ -211,6 +252,7 @@ function temporaryFilePath(root, relativePath, role) {
211
252
  return node_path.join(node_path.dirname(targetPath), `.${node_path.basename(targetPath)}.ultramodern-${role}-${randomUUID()}.tmp`);
212
253
  }
213
254
  function writeTemporaryFile(filePath, file) {
255
+ if (file.symlink) return void node_fs.symlinkSync(file.content.toString(), filePath);
214
256
  node_fs.writeFileSync(filePath, file.content, {
215
257
  flag: 'wx',
216
258
  mode: file.mode
@@ -226,19 +268,10 @@ function removeIfPresent(filePath) {
226
268
  if ('ENOENT' !== error.code) throw error;
227
269
  }
228
270
  }
229
- function prepareChanges(root, changes, createdDirectories, preparedChanges) {
230
- for (const change of changes){
231
- ensureOwnedParentDirectories(root, change.relativePath, createdDirectories);
232
- const prepared = {
233
- ...change,
234
- published: false
235
- };
236
- preparedChanges.push(prepared);
237
- if (change.after) {
238
- prepared.publishPath = temporaryFilePath(root, change.relativePath, 'publish');
239
- writeTemporaryFile(prepared.publishPath, change.after);
240
- }
241
- if (change.before) prepared.rollbackPath = temporaryFilePath(root, change.relativePath, change.after ? 'rollback' : 'removed');
271
+ function prepareChanges(root, preparedChanges, createdDirectories) {
272
+ for (const prepared of preparedChanges){
273
+ ensureOwnedParentDirectories(root, prepared.relativePath, createdDirectories);
274
+ if (prepared.after && prepared.publishPath) writeTemporaryFile(prepared.publishPath, prepared.after);
242
275
  }
243
276
  }
244
277
  function assertPublishedState(root, change) {
@@ -394,17 +427,278 @@ function publishChange(root, change) {
394
427
  }
395
428
  change.published = true;
396
429
  }
397
- function publishChangePlan(root, stagingRoot, changes) {
430
+ const receiptSuffix = '.receipt.json';
431
+ function persistReceipt(receiptPath, receipt) {
432
+ const temporary = `${receiptPath}.next`;
433
+ const fd = node_fs.openSync(temporary, 'wx', 384);
434
+ try {
435
+ node_fs.writeFileSync(fd, JSON.stringify(receipt));
436
+ node_fs.fsyncSync(fd);
437
+ } finally{
438
+ node_fs.closeSync(fd);
439
+ }
440
+ node_fs.renameSync(temporary, receiptPath);
441
+ if ('win32' === process.platform) return;
442
+ const directory = node_fs.openSync(node_path.dirname(receiptPath), 'r');
443
+ try {
444
+ node_fs.fsyncSync(directory);
445
+ } finally{
446
+ node_fs.closeSync(directory);
447
+ }
448
+ }
449
+ function encodedReceipt(root, stagingRoot, changes, directories) {
450
+ const encode = (file)=>file ? {
451
+ ...file,
452
+ content: file.content.toString('base64')
453
+ } : void 0;
454
+ const identity = (filePath)=>{
455
+ const { dev, ino } = node_fs.lstatSync(filePath);
456
+ return {
457
+ dev,
458
+ ino
459
+ };
460
+ };
461
+ return {
462
+ schema: 'ultramodern-workspace-transaction-v1',
463
+ root,
464
+ rootIdentity: identity(root),
465
+ stagingIdentity: identity(stagingRoot),
466
+ pid: process.pid,
467
+ state: 'publishing',
468
+ ...directories ? {
469
+ purpose: 'fresh-empty',
470
+ directories
471
+ } : {},
472
+ changes: changes.map((change)=>({
473
+ ...change,
474
+ before: encode(change.before),
475
+ after: encode(change.after)
476
+ }))
477
+ };
478
+ }
479
+ function decodeReceipt(receiptPath, root) {
480
+ const stat = node_fs.lstatSync(receiptPath);
481
+ if (!stat.isFile() || stat.isSymbolicLink() || 'function' == typeof process.getuid && stat.uid !== process.getuid()) throw new WorkspaceTransactionConflictError(`Unsafe interrupted transaction receipt: ${receiptPath}`);
482
+ const receipt = JSON.parse(node_fs.readFileSync(receiptPath, 'utf8'));
483
+ const stagingRoot = receiptPath.slice(0, -receiptSuffix.length);
484
+ if ('ultramodern-workspace-transaction-v1' !== receipt.schema || receipt.root !== root || ![
485
+ 'publishing',
486
+ 'committed'
487
+ ].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}`);
488
+ const paths = new Set();
489
+ const decode = (file)=>{
490
+ if (void 0 === file) return;
491
+ 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}`);
492
+ return {
493
+ ...file,
494
+ content: Buffer.from(file.content, 'base64')
495
+ };
496
+ };
497
+ const changes = receipt.changes.map((change)=>{
498
+ const relative = change.relativePath;
499
+ 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)}`);
500
+ paths.add(relative);
501
+ for (const temporary of [
502
+ change.publishPath,
503
+ change.rollbackPath
504
+ ])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)}`);
505
+ return {
506
+ relativePath: relative,
507
+ before: decode(change.before),
508
+ after: decode(change.after),
509
+ publishPath: change.publishPath,
510
+ rollbackPath: change.rollbackPath,
511
+ published: false
512
+ };
513
+ });
514
+ if (void 0 !== receipt.purpose && 'fresh-empty' !== receipt.purpose) throw new WorkspaceTransactionConflictError(`Unknown transaction purpose: ${receiptPath}`);
515
+ if ('fresh-empty' === receipt.purpose) {
516
+ const expected = freshParentPaths(changes);
517
+ 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}`);
518
+ } else if (void 0 !== receipt.directories) throw new WorkspaceTransactionConflictError(`Unexpected transaction directories: ${receiptPath}`);
519
+ return {
520
+ receipt,
521
+ changes
522
+ };
523
+ }
524
+ function freshParentPaths(changes) {
525
+ const parents = new Set();
526
+ for (const change of changes){
527
+ const segments = change.relativePath.split('/');
528
+ for(let length = 1; length < segments.length; length++)parents.add(segments.slice(0, length).join('/'));
529
+ }
530
+ return [
531
+ ...parents
532
+ ].sort((left, right)=>left.split('/').length - right.split('/').length || left.localeCompare(right));
533
+ }
534
+ function stageFreshDirectories(stagingRoot, changes) {
535
+ return freshParentPaths(changes).map((relativePath)=>{
536
+ const temporaryPath = node_path.join(stagingRoot, `.ultramodern-directory-${randomUUID()}.tmp`);
537
+ node_fs.mkdirSync(temporaryPath, {
538
+ mode: 511 & node_fs.statSync(node_path.join(stagingRoot, relativePath)).mode
539
+ });
540
+ const { dev, ino } = node_fs.lstatSync(temporaryPath);
541
+ return {
542
+ relativePath,
543
+ temporaryPath,
544
+ dev,
545
+ ino
546
+ };
547
+ });
548
+ }
549
+ function assertFreshDirectoryAncestors(root, receipt, relativePath) {
550
+ const ancestors = relativePath.split('/').slice(0, -1);
551
+ for(let length = 0; length <= ancestors.length; length++){
552
+ const relative = ancestors.slice(0, length).join('/');
553
+ const expected = 0 === length ? receipt.rootIdentity : receipt.directories.find((directory)=>directory.relativePath === relative);
554
+ const candidate = node_path.join(root, relative);
555
+ const stat = node_fs.lstatSync(candidate);
556
+ if (!stat.isDirectory() || stat.isSymbolicLink() || !sameIdentity(stat, expected)) throw new WorkspaceTransactionConflictError(`Fresh transaction parent changed; preserved at ${candidate}`);
557
+ }
558
+ }
559
+ function publishFreshDirectory(root, receipt, directory) {
560
+ const target = node_path.join(root, directory.relativePath);
561
+ assertFreshDirectoryAncestors(root, receipt, directory.relativePath);
562
+ const staged = node_fs.lstatSync(directory.temporaryPath);
563
+ const stagingRoot = node_path.dirname(directory.temporaryPath);
564
+ 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}`);
565
+ if (node_fs.existsSync(target)) throw new WorkspaceTransactionConflictError(`Fresh transaction directory appeared: ${target}`);
566
+ node_fs.renameSync(directory.temporaryPath, target);
567
+ try {
568
+ assertFreshDirectoryAncestors(root, receipt, directory.relativePath);
569
+ const published = node_fs.lstatSync(target);
570
+ if (!published.isDirectory() || published.isSymbolicLink() || !sameIdentity(published, directory)) throw new WorkspaceTransactionConflictError(`Fresh transaction directory changed; preserved at ${target}`);
571
+ } catch (error) {
572
+ throw new WorkspaceTransactionConflictError(`Fresh directory publication could not validate ownership at ${target}; no cleanup attempted through this path`, {
573
+ cause: error
574
+ });
575
+ }
576
+ }
577
+ function validateFreshDirectories(root, receipt, changes) {
578
+ const directories = receipt.directories;
579
+ const allowed = new Set(directories.map((directory)=>node_path.join(root, directory.relativePath)));
580
+ for (const change of changes){
581
+ allowed.add(node_path.join(root, change.relativePath));
582
+ if (change.publishPath) allowed.add(change.publishPath);
583
+ }
584
+ const liveDirectories = [
585
+ root
586
+ ];
587
+ for (const directory of directories)for (const candidate of [
588
+ node_path.join(root, directory.relativePath),
589
+ directory.temporaryPath
590
+ ]){
591
+ let stat;
592
+ try {
593
+ stat = node_fs.lstatSync(candidate);
594
+ } catch (error) {
595
+ if ('ENOENT' === error.code) continue;
596
+ throw error;
597
+ }
598
+ if (!stat.isDirectory() || stat.isSymbolicLink() || !sameIdentity(stat, directory)) throw new WorkspaceTransactionConflictError(`Fresh transaction directory changed; preserved at ${candidate}`);
599
+ if (candidate !== directory.temporaryPath) liveDirectories.push(candidate);
600
+ }
601
+ if ('committed' === receipt.state) return;
602
+ 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)}`);
603
+ }
604
+ function removeFreshDirectories(root, directories) {
605
+ for (const directory of [
606
+ ...directories
607
+ ].reverse()){
608
+ const target = node_path.join(root, directory.relativePath);
609
+ let stat;
610
+ try {
611
+ stat = node_fs.lstatSync(target);
612
+ } catch (error) {
613
+ if ('ENOENT' === error.code) continue;
614
+ throw error;
615
+ }
616
+ if (!stat.isDirectory() || stat.isSymbolicLink() || !sameIdentity(stat, directory)) throw new WorkspaceTransactionConflictError(`Fresh transaction directory changed; preserved at ${target}`);
617
+ node_fs.rmdirSync(target);
618
+ }
619
+ }
620
+ function recoverFreshWorkspaceTransactions(root) {
621
+ try {
622
+ const stat = node_fs.lstatSync(root);
623
+ if (!stat.isDirectory() || stat.isSymbolicLink()) return;
624
+ } catch (error) {
625
+ if ('ENOENT' === error.code) return;
626
+ throw error;
627
+ }
628
+ recoverWorkspaceTransactions(root, 'fresh-empty');
629
+ }
630
+ function recoverWorkspaceTransactions(root, purpose = 'update') {
631
+ const workspaceRoot = node_fs.realpathSync.native(root);
632
+ const parent = node_path.dirname(workspaceRoot);
633
+ const prefix = `.${node_path.basename(workspaceRoot)}.ultramodern-stage-`;
634
+ for (const entry of node_fs.readdirSync(parent).sort()){
635
+ if (!entry.startsWith(prefix) || !entry.endsWith(receiptSuffix)) continue;
636
+ const receiptPath = node_path.join(parent, entry);
637
+ const { receipt, changes } = decodeReceipt(receiptPath, workspaceRoot);
638
+ if ((receipt.purpose ?? 'update') === purpose) {
639
+ try {
640
+ process.kill(receipt.pid, 0);
641
+ throw new WorkspaceTransactionConflictError(`Workspace publication is still owned by process ${receipt.pid}: ${receiptPath}`);
642
+ } catch (error) {
643
+ if ('ESRCH' !== error.code) throw error;
644
+ }
645
+ if ('fresh-empty' === receipt.purpose) validateFreshDirectories(workspaceRoot, receipt, changes);
646
+ for (const change of changes){
647
+ if ('fresh-empty' !== receipt.purpose) ensureOwnedParentDirectories(workspaceRoot, change.relativePath, []);
648
+ for (const [temporary, expected] of [
649
+ [
650
+ change.publishPath,
651
+ change.after
652
+ ],
653
+ [
654
+ change.rollbackPath,
655
+ change.before
656
+ ]
657
+ ])if (temporary && node_fs.existsSync(temporary) && !sameFile(readFilePath(temporary, temporary), expected)) throw new WorkspaceTransactionConflictError(`Interrupted transaction temporary changed; preserved at ${temporary}`);
658
+ if ('committed' === receipt.state) continue;
659
+ const current = readWorkspaceFile(workspaceRoot, change.relativePath);
660
+ if (!sameFile(current, change.before)) if (sameFile(current, change.after)) {
661
+ change.published = true;
662
+ if (change.before && change.rollbackPath && !node_fs.existsSync(change.rollbackPath)) writeTemporaryFile(change.rollbackPath, change.before);
663
+ } else if (void 0 === current && change.before && change.rollbackPath && node_fs.existsSync(change.rollbackPath)) {
664
+ if (!restoreQuarantinedPreimage(change, node_path.join(workspaceRoot, change.relativePath))) throw new WorkspaceTransactionConflictError(`Interrupted preimage cannot be restored: ${change.relativePath}`);
665
+ } else throw new WorkspaceTransactionConflictError(`Interrupted transaction conflicts with newer consumer bytes: ${change.relativePath}; receipt ${receiptPath}`);
666
+ }
667
+ if ('publishing' === receipt.state) rollbackPublishedChanges(workspaceRoot, changes);
668
+ cleanupPreparedChanges(changes, []);
669
+ if ('fresh-empty' === receipt.purpose && 'publishing' === receipt.state) removeFreshDirectories(workspaceRoot, receipt.directories);
670
+ removeOwnedTemporaryDirectory(receiptPath.slice(0, -receiptSuffix.length), receipt.stagingIdentity);
671
+ removeIfPresent(receiptPath);
672
+ }
673
+ }
674
+ }
675
+ function publishChangePlan(root, stagingRoot, changes, emptyTarget) {
398
676
  __transactionTestHooks.beforePublish?.({
399
677
  workspaceRoot: root,
400
678
  stagingRoot,
401
679
  changedPaths: changes.map((change)=>change.relativePath)
402
680
  });
681
+ if (emptyTarget) assertFreshTarget(root, emptyTarget);
403
682
  for (const change of changes)assertPreimage(root, change);
683
+ if (0 === changes.length) return;
404
684
  const createdDirectories = [];
405
- const preparedChanges = [];
685
+ const preparedChanges = changes.map((change)=>({
686
+ ...change,
687
+ published: false,
688
+ ...change.after ? {
689
+ publishPath: temporaryFilePath(root, change.relativePath, 'publish')
690
+ } : {},
691
+ ...change.before ? {
692
+ rollbackPath: temporaryFilePath(root, change.relativePath, 'rollback')
693
+ } : {}
694
+ }));
695
+ const receiptPath = `${stagingRoot}${receiptSuffix}`;
696
+ const directories = emptyTarget ? stageFreshDirectories(stagingRoot, changes) : void 0;
697
+ const receipt = encodedReceipt(root, stagingRoot, preparedChanges, directories);
698
+ persistReceipt(receiptPath, receipt);
406
699
  try {
407
- prepareChanges(root, changes, createdDirectories, preparedChanges);
700
+ for (const directory of directories ?? [])publishFreshDirectory(root, receipt, directory);
701
+ prepareChanges(root, preparedChanges, createdDirectories);
408
702
  for (const change of preparedChanges)assertPreimage(root, change);
409
703
  preparedChanges.forEach((change, index)=>{
410
704
  __transactionTestHooks.beforePublishPath?.({
@@ -413,36 +707,67 @@ function publishChangePlan(root, stagingRoot, changes) {
413
707
  index
414
708
  });
415
709
  publishChange(root, change);
710
+ __transactionTestHooks.afterPublishPath?.({
711
+ workspaceRoot: root,
712
+ relativePath: change.relativePath,
713
+ index
714
+ });
715
+ });
716
+ persistReceipt(receiptPath, {
717
+ ...receipt,
718
+ state: 'committed'
416
719
  });
417
720
  } catch (error) {
418
721
  try {
722
+ if (directories) validateFreshDirectories(root, receipt, preparedChanges);
419
723
  rollbackPublishedChanges(root, preparedChanges);
724
+ if (directories) {
725
+ cleanupPreparedChanges(preparedChanges, []);
726
+ removeFreshDirectories(root, directories);
727
+ }
420
728
  } catch (rollbackError) {
421
- throw new WorkspaceTransactionConflictError('Workspace transaction failed and concurrent target changes prevented a safe rollback.', {
422
- cause: rollbackError
729
+ throw new WorkspaceTransactionConflictError(`Workspace transaction failed and concurrent target changes prevented a safe rollback; recovery receipt ${receiptPath}.`, {
730
+ cause: directories ? new AggregateError([
731
+ error,
732
+ rollbackError
733
+ ], 'Fresh publication and rollback conflicts') : rollbackError
423
734
  });
424
- } finally{
425
- cleanPreparedChanges(preparedChanges, createdDirectories);
426
735
  }
736
+ cleanPreparedChanges(preparedChanges, createdDirectories);
737
+ if (!preparedChanges.some((change)=>change.preserveRollback || change.preservedPaths?.length)) removeIfPresent(receiptPath);
427
738
  throw error;
428
739
  }
429
740
  cleanPreparedChanges(preparedChanges, []);
741
+ removeIfPresent(receiptPath);
430
742
  }
431
- function runWorkspaceTransaction(root, mutate) {
743
+ function runWorkspaceTransaction(root, mutate, options = {}) {
432
744
  const workspaceRoot = node_fs.realpathSync.native(node_path.resolve(root));
433
745
  if (!node_fs.statSync(workspaceRoot).isDirectory()) throw new Error(`Workspace root is not a directory: ${root}`);
746
+ if ('preview' !== options.mode) recoverWorkspaceTransactions(workspaceRoot);
434
747
  const stagingRoot = createTemporarySibling(workspaceRoot);
435
748
  const stagingIdentity = node_fs.lstatSync(stagingRoot);
749
+ const cleanup = ()=>{
750
+ if (!node_fs.existsSync(`${stagingRoot}${receiptSuffix}`)) cleanOwnedTemporaryDirectory(stagingRoot, stagingIdentity);
751
+ };
436
752
  try {
437
753
  copyWorkspaceToStage(workspaceRoot, stagingRoot);
438
- const before = captureWorkspace(stagingRoot);
754
+ const before = captureWorkspace(stagingRoot, workspaceRoot);
755
+ const finish = (result)=>{
756
+ if (options.commitWhen && !options.commitWhen(result)) return result;
757
+ relocateStagedWorkspaceReferences(stagingRoot, root);
758
+ const changes = buildChangePlan(before, captureWorkspace(stagingRoot, workspaceRoot));
759
+ options.inspectChanges?.(changes);
760
+ if ('preview' !== options.mode) publishChangePlan(workspaceRoot, stagingRoot, changes);
761
+ return result;
762
+ };
439
763
  const result = mutate(stagingRoot);
440
- relocateStagedWorkspaceReferences(stagingRoot, root);
441
- const changes = buildChangePlan(before, captureWorkspace(stagingRoot));
442
- publishChangePlan(workspaceRoot, stagingRoot, changes);
443
- return result;
444
- } finally{
445
- cleanOwnedTemporaryDirectory(stagingRoot, stagingIdentity);
764
+ if (null !== result && ('object' == typeof result || 'function' == typeof result) && 'function' == typeof result.then) return Promise.resolve(result).then(finish).finally(cleanup);
765
+ const completed = finish(result);
766
+ cleanup();
767
+ return completed;
768
+ } catch (error) {
769
+ cleanup();
770
+ throw error;
446
771
  }
447
772
  }
448
773
  function sameIdentity(stat, identity) {
@@ -483,6 +808,7 @@ function cleanEmptyTargetRollback(rollbackPath, expected) {
483
808
  function publishFreshWorkspace(stagingRoot, workspaceRoot, target) {
484
809
  assertFreshTarget(workspaceRoot, target);
485
810
  if ('absent' === target.kind) return void node_fs.renameSync(stagingRoot, workspaceRoot);
811
+ if ('win32' === process.platform && currentDirectoryIs(workspaceRoot)) return void publishChangePlan(node_fs.realpathSync.native(workspaceRoot), stagingRoot, buildChangePlan(new Map(), captureWorkspace(stagingRoot, workspaceRoot)), target);
486
812
  const rollbackPath = node_path.join(node_path.dirname(workspaceRoot), `.${node_path.basename(workspaceRoot)}.ultramodern-empty-${randomUUID()}.tmp`);
487
813
  const restoreCwd = currentDirectoryIs(workspaceRoot);
488
814
  node_fs.renameSync(workspaceRoot, rollbackPath);
@@ -511,6 +837,7 @@ function publishFreshWorkspace(stagingRoot, workspaceRoot, target) {
511
837
  }
512
838
  function runFreshWorkspaceTransaction(targetDir, generate) {
513
839
  const workspaceRoot = node_path.resolve(targetDir);
840
+ recoverFreshWorkspaceTransactions(workspaceRoot);
514
841
  const target = inspectFreshTarget(workspaceRoot);
515
842
  const stagingRoot = createTemporarySibling(workspaceRoot);
516
843
  const stagingIdentity = node_fs.lstatSync(stagingRoot);
@@ -524,7 +851,7 @@ function runFreshWorkspaceTransaction(targetDir, generate) {
524
851
  publishFreshWorkspace(stagingRoot, workspaceRoot, target);
525
852
  return result;
526
853
  } finally{
527
- cleanOwnedTemporaryDirectory(stagingRoot, stagingIdentity);
854
+ if (!node_fs.existsSync(`${stagingRoot}${receiptSuffix}`)) cleanOwnedTemporaryDirectory(stagingRoot, stagingIdentity);
528
855
  }
529
856
  }
530
- export { WorkspaceTransactionConflictError, __transactionTestHooks, relocateStagedWorkspaceReferences, runFreshWorkspaceTransaction, runWorkspaceTransaction };
857
+ export { WorkspaceTransactionConflictError, __transactionTestHooks, recoverFreshWorkspaceTransactions, recoverWorkspaceTransactions, relocateStagedWorkspaceReferences, runFreshWorkspaceTransaction, runWorkspaceTransaction };
@@ -1,48 +1,36 @@
1
1
  import "node:module";
2
2
  import node_fs from "node:fs";
3
3
  import node_path from "node:path";
4
- import { readUltramodernConfig } from "../../ultramodern-tooling/config.js";
5
- import { ULTRAMODERN_CONFIG_PATH } from "../descriptors.js";
6
4
  import { toKebabCase } from "../naming.js";
7
5
  import { resolvePackageSource } from "../package-source.js";
8
6
  import { FIRST_VERTICAL_PORT } from "./constants.js";
9
- function existingPackageSource(workspaceRoot, modernVersion, packageSource) {
10
- if (packageSource) return resolvePackageSource({
11
- targetDir: workspaceRoot,
12
- packageName: node_path.basename(workspaceRoot),
13
- modernVersion,
14
- packageSource
15
- });
16
- const compactPath = node_path.join(workspaceRoot, ULTRAMODERN_CONFIG_PATH);
17
- if (node_fs.existsSync(compactPath)) {
18
- const compactConfig = readUltramodernConfig(workspaceRoot);
19
- if (compactConfig.packageSource) return compactConfig.packageSource;
20
- }
21
- throw new Error(`Missing UltraModern workspace file: ${compactPath}`);
22
- }
23
- function existingTailwindEnabled(workspaceRoot) {
24
- const compactPath = node_path.join(workspaceRoot, ULTRAMODERN_CONFIG_PATH);
25
- if (node_fs.existsSync(compactPath)) return readUltramodernConfig(workspaceRoot).features.tailwind;
26
- throw new Error(`Missing UltraModern workspace file: ${compactPath}`);
27
- }
28
- function existingBridgeConfig(workspaceRoot) {
29
- const compactPath = node_path.join(workspaceRoot, ULTRAMODERN_CONFIG_PATH);
30
- return node_fs.existsSync(compactPath) ? readUltramodernConfig(workspaceRoot).bridge : void 0;
7
+ function workspaceOperationSettings(options, config) {
8
+ const packageSource = options.packageSource ? resolvePackageSource({
9
+ targetDir: options.workspaceRoot,
10
+ packageName: node_path.basename(options.workspaceRoot),
11
+ modernVersion: options.modernVersion,
12
+ packageSource: options.packageSource
13
+ }) : config.packageSource;
14
+ if (!packageSource) throw new Error(`Missing UltraModern package source in workspace manifests: ${options.workspaceRoot}`);
15
+ return {
16
+ packageSource,
17
+ enableTailwind: options.enableTailwind ?? config.features.tailwind,
18
+ bridge: void 0
19
+ };
31
20
  }
32
21
  function assertValidVerticalName(name) {
33
22
  const normalized = toKebabCase(name);
34
23
  if (!normalized || normalized !== name) throw new Error(`Invalid Vertical name "${name}". Use lowercase kebab-case.`);
35
24
  return normalized;
36
25
  }
37
- function configuredDevelopmentPorts(ports, additionalShells = []) {
26
+ function configuredDevelopmentPorts(ports, _additionalShells = []) {
38
27
  return [
39
28
  ...new Set([
40
- ...Object.values(ports),
41
- ...additionalShells.map((shell)=>shell.port)
29
+ ...Object.values(ports)
42
30
  ].filter((value)=>'number' == typeof value && Number.isFinite(value)))
43
31
  ];
44
32
  }
45
- function assertGlobalPortUniqueness(ports, additionalShells = []) {
33
+ function assertGlobalPortUniqueness(ports, _additionalShells = []) {
46
34
  const owners = new Map();
47
35
  for (const [id, value] of Object.entries(ports)){
48
36
  if ('number' != typeof value || !Number.isFinite(value)) continue;
@@ -50,11 +38,6 @@ function assertGlobalPortUniqueness(ports, additionalShells = []) {
50
38
  if (previous) throw new Error(`Duplicate development port "${value}" for ${previous} and ${id}.`);
51
39
  owners.set(value, id);
52
40
  }
53
- for (const shell of additionalShells){
54
- const previous = owners.get(shell.port);
55
- if (previous) throw new Error(`Duplicate development port "${shell.port}" for ${previous} and ${shell.id}.`);
56
- owners.set(shell.port, shell.id);
57
- }
58
41
  }
59
42
  function nextAvailablePort(ports, additionalShells = [], minimumPort = FIRST_VERTICAL_PORT) {
60
43
  const used = new Set(configuredDevelopmentPorts(ports, additionalShells));
@@ -65,4 +48,4 @@ function nextAvailablePort(ports, additionalShells = [], minimumPort = FIRST_VER
65
48
  function assertCanCreate(workspaceRoot, relativePath) {
66
49
  if (node_fs.existsSync(node_path.join(workspaceRoot, relativePath))) throw new Error(`Refusing to overwrite existing path: ${relativePath}`);
67
50
  }
68
- export { assertCanCreate, assertGlobalPortUniqueness, assertValidVerticalName, configuredDevelopmentPorts, existingBridgeConfig, existingPackageSource, existingTailwindEnabled, nextAvailablePort };
51
+ export { assertCanCreate, assertGlobalPortUniqueness, assertValidVerticalName, configuredDevelopmentPorts, nextAvailablePort, workspaceOperationSettings };
@@ -4,4 +4,4 @@ export { planUltramodernVertical } from "./add-vertical/plan.js";
4
4
  export { prepareAddUltramodernVertical } from "./add-vertical/preflight.js";
5
5
  export { rewriteShellAppFiles, updateRootWorkspaceScripts } from "./add-vertical/shell-files.js";
6
6
  export { ownershipEntry, verticalTopologyEntry, verticalsFromTopology } from "./add-vertical/topology.js";
7
- export { assertCanCreate, assertValidVerticalName, existingBridgeConfig, existingPackageSource, existingTailwindEnabled, nextAvailablePort } from "./add-vertical/workspace-state.js";
7
+ export { assertCanCreate, assertValidVerticalName, nextAvailablePort } from "./add-vertical/workspace-state.js";