@bleedingdev/modern-js-create 3.2.0-ultramodern.98 → 3.4.0-ultramodern.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/README.md +281 -106
  2. package/bin/run.js +1 -0
  3. package/dist/cjs/create-package-root.cjs +63 -0
  4. package/dist/cjs/index.cjs +658 -0
  5. package/dist/cjs/locale/en.cjs +101 -0
  6. package/dist/cjs/locale/index.cjs +50 -0
  7. package/dist/cjs/locale/zh.cjs +101 -0
  8. package/dist/cjs/ultramodern-package-source.cjs +135 -0
  9. package/dist/cjs/ultramodern-workspace/add-vertical.cjs +603 -0
  10. package/dist/cjs/ultramodern-workspace/app-files.cjs +223 -0
  11. package/dist/cjs/ultramodern-workspace/codesmith.cjs +134 -0
  12. package/dist/cjs/ultramodern-workspace/contracts.cjs +837 -0
  13. package/dist/cjs/ultramodern-workspace/demo-components.cjs +422 -0
  14. package/dist/cjs/ultramodern-workspace/descriptors.cjs +222 -0
  15. package/dist/cjs/ultramodern-workspace/effect-api.cjs +952 -0
  16. package/dist/cjs/ultramodern-workspace/fs-io.cjs +191 -0
  17. package/dist/cjs/ultramodern-workspace/generation-result.cjs +158 -0
  18. package/dist/cjs/ultramodern-workspace/index.cjs +51 -0
  19. package/dist/cjs/ultramodern-workspace/locales.cjs +173 -0
  20. package/dist/cjs/ultramodern-workspace/module-federation.cjs +487 -0
  21. package/dist/cjs/ultramodern-workspace/naming.cjs +161 -0
  22. package/dist/cjs/ultramodern-workspace/overlays.cjs +120 -0
  23. package/dist/cjs/ultramodern-workspace/package-json.cjs +406 -0
  24. package/dist/cjs/ultramodern-workspace/package-source.cjs +59 -0
  25. package/dist/cjs/ultramodern-workspace/policy.cjs +248 -0
  26. package/dist/cjs/ultramodern-workspace/public-api.cjs +47 -0
  27. package/dist/cjs/ultramodern-workspace/public-surface.cjs +268 -0
  28. package/dist/cjs/ultramodern-workspace/routes.cjs +375 -0
  29. package/dist/cjs/ultramodern-workspace/types.cjs +61 -0
  30. package/dist/cjs/ultramodern-workspace/versions.cjs +161 -0
  31. package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +154 -0
  32. package/dist/cjs/ultramodern-workspace/write-workspace.cjs +197 -0
  33. package/dist/esm/create-package-root.js +14 -0
  34. package/dist/esm/index.js +621 -0
  35. package/dist/esm/locale/en.js +63 -0
  36. package/dist/esm/locale/index.js +9 -0
  37. package/dist/esm/locale/zh.js +63 -0
  38. package/dist/esm/ultramodern-package-source.js +63 -0
  39. package/dist/esm/ultramodern-workspace/add-vertical.js +511 -0
  40. package/dist/esm/ultramodern-workspace/app-files.js +149 -0
  41. package/dist/esm/ultramodern-workspace/codesmith.js +86 -0
  42. package/dist/esm/ultramodern-workspace/contracts.js +742 -0
  43. package/dist/esm/ultramodern-workspace/demo-components.js +363 -0
  44. package/dist/esm/ultramodern-workspace/descriptors.js +133 -0
  45. package/dist/esm/ultramodern-workspace/effect-api.js +854 -0
  46. package/dist/esm/ultramodern-workspace/fs-io.js +90 -0
  47. package/dist/esm/ultramodern-workspace/generation-result.js +102 -0
  48. package/dist/esm/ultramodern-workspace/index.js +3 -0
  49. package/dist/esm/ultramodern-workspace/locales.js +122 -0
  50. package/dist/esm/ultramodern-workspace/module-federation.js +415 -0
  51. package/dist/esm/ultramodern-workspace/naming.js +71 -0
  52. package/dist/esm/ultramodern-workspace/overlays.js +79 -0
  53. package/dist/esm/ultramodern-workspace/package-json.js +338 -0
  54. package/dist/esm/ultramodern-workspace/package-source.js +21 -0
  55. package/dist/esm/ultramodern-workspace/policy.js +183 -0
  56. package/dist/esm/ultramodern-workspace/public-api.js +2 -0
  57. package/dist/esm/ultramodern-workspace/public-surface.js +183 -0
  58. package/dist/esm/ultramodern-workspace/routes.js +280 -0
  59. package/dist/esm/ultramodern-workspace/types.js +16 -0
  60. package/dist/esm/ultramodern-workspace/versions.js +36 -0
  61. package/dist/esm/ultramodern-workspace/workspace-scripts.js +92 -0
  62. package/dist/esm/ultramodern-workspace/write-workspace.js +143 -0
  63. package/dist/esm-node/create-package-root.js +15 -0
  64. package/dist/esm-node/index.js +622 -0
  65. package/dist/esm-node/locale/en.js +64 -0
  66. package/dist/esm-node/locale/index.js +10 -0
  67. package/dist/esm-node/locale/zh.js +64 -0
  68. package/dist/esm-node/ultramodern-package-source.js +64 -0
  69. package/dist/esm-node/ultramodern-workspace/add-vertical.js +512 -0
  70. package/dist/esm-node/ultramodern-workspace/app-files.js +150 -0
  71. package/dist/esm-node/ultramodern-workspace/codesmith.js +87 -0
  72. package/dist/esm-node/ultramodern-workspace/contracts.js +743 -0
  73. package/dist/esm-node/ultramodern-workspace/demo-components.js +364 -0
  74. package/dist/esm-node/ultramodern-workspace/descriptors.js +134 -0
  75. package/dist/esm-node/ultramodern-workspace/effect-api.js +855 -0
  76. package/dist/esm-node/ultramodern-workspace/fs-io.js +91 -0
  77. package/dist/esm-node/ultramodern-workspace/generation-result.js +103 -0
  78. package/dist/esm-node/ultramodern-workspace/index.js +4 -0
  79. package/dist/esm-node/ultramodern-workspace/locales.js +123 -0
  80. package/dist/esm-node/ultramodern-workspace/module-federation.js +416 -0
  81. package/dist/esm-node/ultramodern-workspace/naming.js +72 -0
  82. package/dist/esm-node/ultramodern-workspace/overlays.js +80 -0
  83. package/dist/esm-node/ultramodern-workspace/package-json.js +339 -0
  84. package/dist/esm-node/ultramodern-workspace/package-source.js +22 -0
  85. package/dist/esm-node/ultramodern-workspace/policy.js +184 -0
  86. package/dist/esm-node/ultramodern-workspace/public-api.js +3 -0
  87. package/dist/esm-node/ultramodern-workspace/public-surface.js +184 -0
  88. package/dist/esm-node/ultramodern-workspace/routes.js +281 -0
  89. package/dist/esm-node/ultramodern-workspace/types.js +17 -0
  90. package/dist/esm-node/ultramodern-workspace/versions.js +37 -0
  91. package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +93 -0
  92. package/dist/esm-node/ultramodern-workspace/write-workspace.js +144 -0
  93. package/dist/types/create-package-root.d.ts +1 -0
  94. package/dist/types/locale/en.d.ts +12 -8
  95. package/dist/types/locale/index.d.ts +125 -2
  96. package/dist/types/locale/zh.d.ts +12 -8
  97. package/dist/types/ultramodern-package-source.d.ts +28 -0
  98. package/dist/types/ultramodern-workspace/add-vertical.d.ts +36 -0
  99. package/dist/types/ultramodern-workspace/app-files.d.ts +14 -0
  100. package/dist/types/ultramodern-workspace/codesmith.d.ts +53 -0
  101. package/dist/types/ultramodern-workspace/contracts.d.ts +21 -0
  102. package/dist/types/ultramodern-workspace/demo-components.d.ts +9 -0
  103. package/dist/types/ultramodern-workspace/descriptors.d.ts +39 -0
  104. package/dist/types/ultramodern-workspace/effect-api.d.ts +73 -0
  105. package/dist/types/ultramodern-workspace/fs-io.d.ts +18 -0
  106. package/dist/types/ultramodern-workspace/generation-result.d.ts +14 -0
  107. package/dist/types/ultramodern-workspace/index.d.ts +4 -0
  108. package/dist/types/ultramodern-workspace/locales.d.ts +183 -0
  109. package/dist/types/ultramodern-workspace/module-federation.d.ts +16 -0
  110. package/dist/types/ultramodern-workspace/naming.d.ts +16 -0
  111. package/dist/types/ultramodern-workspace/overlays.d.ts +6 -0
  112. package/dist/types/ultramodern-workspace/package-json.d.ts +12 -0
  113. package/dist/types/ultramodern-workspace/package-source.d.ts +2 -0
  114. package/dist/types/ultramodern-workspace/policy.d.ts +60 -0
  115. package/dist/types/ultramodern-workspace/public-api.d.ts +3 -0
  116. package/dist/types/ultramodern-workspace/public-surface.d.ts +37 -0
  117. package/dist/types/ultramodern-workspace/routes.d.ts +25 -0
  118. package/dist/types/ultramodern-workspace/types.d.ts +197 -0
  119. package/dist/types/ultramodern-workspace/versions.d.ts +40 -0
  120. package/dist/types/ultramodern-workspace/workspace-scripts.d.ts +10 -0
  121. package/dist/types/ultramodern-workspace/write-workspace.d.ts +4 -0
  122. package/package.json +58 -15
  123. package/template-workspace/.agents/agent-reference-repos.json +24 -0
  124. package/template-workspace/.agents/rstackjs-agent-skills-LICENSE +21 -0
  125. package/template-workspace/.agents/skills/rsbuild-best-practices/SKILL.md +57 -0
  126. package/template-workspace/.agents/skills/rsdoctor-analysis/SKILL.md +96 -0
  127. package/template-workspace/.agents/skills/rsdoctor-analysis/references/command-map.md +113 -0
  128. package/template-workspace/.agents/skills/rsdoctor-analysis/references/common-analysis-patterns.md +190 -0
  129. package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor-common.md +88 -0
  130. package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor-rspack.md +138 -0
  131. package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor-webpack.md +71 -0
  132. package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor.md +39 -0
  133. package/template-workspace/.agents/skills/rsdoctor-analysis/references/rsdoctor-data-types.md +103 -0
  134. package/template-workspace/.agents/skills/rslib-best-practices/SKILL.md +58 -0
  135. package/template-workspace/.agents/skills/rslib-modern-package/SKILL.md +173 -0
  136. package/template-workspace/.agents/skills/rspack-best-practices/SKILL.md +70 -0
  137. package/template-workspace/.agents/skills/rspack-tracing/SKILL.md +75 -0
  138. package/template-workspace/.agents/skills/rspack-tracing/references/bottlenecks.md +47 -0
  139. package/template-workspace/.agents/skills/rspack-tracing/references/tracing-guide.md +38 -0
  140. package/template-workspace/.agents/skills/rspack-tracing/scripts/analyze_trace.js +184 -0
  141. package/template-workspace/.agents/skills/rstest-best-practices/SKILL.md +133 -0
  142. package/template-workspace/.agents/skills-lock.json +114 -0
  143. package/template-workspace/.codex/hooks.json +16 -0
  144. package/template-workspace/.github/renovate.json +29 -0
  145. package/template-workspace/.github/workflows/ultramodern-workspace-gates.yml.handlebars +67 -0
  146. package/template-workspace/.gitignore.handlebars +5 -0
  147. package/template-workspace/.mise.toml.handlebars +3 -0
  148. package/template-workspace/{AGENTS.md → AGENTS.md.handlebars} +20 -9
  149. package/template-workspace/README.md.handlebars +85 -14
  150. package/template-workspace/lefthook.yml +18 -4
  151. package/template-workspace/pnpm-workspace.yaml.handlebars +45 -0
  152. package/template-workspace/scripts/bootstrap-agent-skills.mjs +69 -75
  153. package/template-workspace/scripts/setup-agent-reference-repos.mjs +8 -6
  154. package/templates/app/shell-frame.tsx +49 -0
  155. package/templates/app/ultramodern-route-head.tsx.handlebars +142 -0
  156. package/templates/packages/shared-contracts-index.ts +466 -0
  157. package/templates/workspace-scripts/assert-mf-types.mjs.handlebars +69 -0
  158. package/templates/workspace-scripts/check-ultramodern-i18n-boundaries.mjs +9 -0
  159. package/templates/workspace-scripts/generate-public-surface-assets.mjs +529 -0
  160. package/templates/workspace-scripts/proof-cloudflare-version.mjs +125 -0
  161. package/templates/workspace-scripts/ultramodern-cloudflare-proof.mjs +851 -0
  162. package/templates/workspace-scripts/ultramodern-performance-readiness.config.mjs +7 -0
  163. package/templates/workspace-scripts/ultramodern-performance-readiness.mjs +223 -0
  164. package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +986 -0
  165. package/dist/index.js +0 -6625
  166. package/dist/types/ultramodern-workspace.d.ts +0 -31
  167. package/template/AGENTS.md +0 -23
  168. package/template/README.md +0 -105
  169. package/template/api/effect/index.ts.handlebars +0 -34
  170. package/template/api/lambda/hello.ts.handlebars +0 -6
  171. package/template/config/public/locales/cs/translation.json +0 -39
  172. package/template/config/public/locales/en/translation.json +0 -39
  173. package/template/lefthook.yml +0 -10
  174. package/template/modern.config.ts.handlebars +0 -71
  175. package/template/oxfmt.config.ts +0 -15
  176. package/template/oxlint.config.ts +0 -19
  177. package/template/package.json.handlebars +0 -66
  178. package/template/pnpm-workspace.yaml +0 -29
  179. package/template/postcss.config.mjs.handlebars +0 -6
  180. package/template/rstest.config.mts +0 -5
  181. package/template/scripts/bootstrap-agent-skills.mjs +0 -228
  182. package/template/scripts/check-i18n-strings.mjs +0 -94
  183. package/template/scripts/validate-ultramodern.mjs.handlebars +0 -538
  184. package/template/shared/effect/api.ts.handlebars +0 -17
  185. package/template/src/modern-app-env.d.ts +0 -3
  186. package/template/src/modern.runtime.ts.handlebars +0 -23
  187. package/template/src/routes/[lang]/page.tsx.handlebars +0 -211
  188. package/template/src/routes/index.css.handlebars +0 -129
  189. package/template/src/routes/layout.tsx.handlebars +0 -10
  190. package/template/tailwind.config.ts.handlebars +0 -10
  191. package/template/tests/tsconfig.json +0 -7
  192. package/template/tests/ultramodern.contract.test.ts.handlebars +0 -78
  193. package/template/tsconfig.json +0 -120
  194. package/template-workspace/pnpm-workspace.yaml +0 -35
package/README.md CHANGED
@@ -8,102 +8,263 @@
8
8
  A Progressive React Framework for modern web development.
9
9
  </p>
10
10
 
11
- ## Getting Started
11
+ ## UltraModern.js Create
12
12
 
13
- Please follow [Quick Start](https://modernjs.dev/en/guides/get-started/quick-start) to get started with Modern.js.
14
-
15
- For UltraModern.js, use the BleedingDev create package. It defaults to a
16
- production-ready single app with `presetUltramodern(...)`, TanStack Router,
17
- Tailwind CSS v4, i18n, Effect BFF, generated quality gates, and published
18
- BleedingDev package aliases:
13
+ The BleedingDev create package has one supported generated product: an
14
+ UltraModern SuperApp workspace.
19
15
 
20
16
  ```bash
21
- pnpm dlx @bleedingdev/modern-js-create my-app
17
+ pnpm dlx @bleedingdev/modern-js-create my-workspace
22
18
  ```
23
19
 
20
+ The supported pnpm command contract is the scoped package specifier above:
21
+ `pnpm dlx @bleedingdev/modern-js-create <target>`. Do not shorten it to
22
+ `pnpm dlx modern-js-create`; there is no unscoped `modern-js-create` npm
23
+ package. Release proof runs this scoped form from a temporary pnpm store/cache
24
+ so it cannot pass because of a local link cache.
25
+
24
26
  To initialize the empty directory you are already in, pass `.` explicitly:
25
27
 
26
28
  ```bash
27
29
  pnpm dlx @bleedingdev/modern-js-create .
28
30
  ```
29
31
 
30
- The default is the full UltraModern single-app setup. Create a SuperApp
31
- workspace explicitly when you need independently owned verticals:
32
-
33
- ```bash
34
- pnpm dlx @bleedingdev/modern-js-create my-super-app --ultramodern-workspace
35
- ```
36
-
37
32
  The workspace starts shell-only so the first commit has no fake business
38
33
  domains to delete. It generates:
39
34
 
40
35
  - `apps/shell-super-app` as the Module Federation host and topology owner.
41
- - `verticals/*` empty until you add a real domain with `--vertical`.
42
- - `packages/shared-*` placeholders for shared contracts, tokens, and API
43
- support.
44
- - `.modernjs/ultramodern-generated-contract.json` with MF, Effect, i18n,
45
- federated CSS, Cloudflare, and Zephyr dependency metadata.
36
+ - `verticals/*` empty until a real domain is added with `--vertical`.
37
+ - `packages/shared-*` placeholders for shared contracts, tokens, and Effect
38
+ API support.
39
+ - `.modernjs/ultramodern-generated-contract.json` with Module Federation,
40
+ Effect, i18n, federated CSS, Cloudflare, route publicness, generated
41
+ public-surface, and Zephyr dependency metadata.
46
42
 
47
43
  Validate the generated workspace before making application changes:
48
44
 
49
45
  ```bash
50
- cd my-super-app
46
+ cd my-workspace
51
47
  mise install
52
48
  pnpm install
53
49
  pnpm check
54
50
  pnpm build
55
51
  ```
56
52
 
57
- ### Router Template
53
+ The generated toolchain baseline is Node `>=26` with pnpm `11+`.
54
+ `packageManager`, `.mise.toml`, generated validation, and CI should all agree
55
+ on that baseline; do not reintroduce Corepack or older pnpm aliases.
56
+
57
+ ## TS-Go Compatibility Boundary
58
58
 
59
- TanStack Router is generated by default. Choose React Router only as an explicit
60
- compatibility lane:
59
+ The supported generator runtime surfaces are:
60
+
61
+ - `@modern-js/create/ultramodern-workspace`
62
+ - `@modern-js/create/ultramodern-workspace/codesmith`
63
+ - The `@bleedingdev/modern-js-create` CLI that delegates to those APIs.
64
+
65
+ These surfaces are plain Node generator code. They must not import
66
+ `typescript`, `@typescript/native-preview`, or TypeScript compiler internals at
67
+ runtime. The package build is the local validation command for this boundary:
61
68
 
62
69
  ```bash
63
- pnpm dlx @bleedingdev/modern-js-create my-app --router react-router
70
+ pnpm --filter @modern-js/create build
64
71
  ```
65
72
 
66
- ### Tailwind Template
73
+ That command runs the Rslib runtime build and then emits declarations through
74
+ the repo `tsgo:dts` flow. Run `pnpm --filter @modern-js/create test` when
75
+ changing generator behavior; it includes a boundary test that scans generator
76
+ sources, templates, and generated workspace output for compiler API imports.
77
+
78
+ Generated app packages install the TypeScript 7 RC package line and use
79
+ `@effect/tsgo` plus `@typescript/native-preview` as tooling for
80
+ `pnpm typecheck`, but generated app/package source must not depend on compiler
81
+ API internals. Existing compiler API tests in this package use the stable
82
+ TypeScript 6 package. If a future AST utility is needed, keep it behind a
83
+ dedicated compatibility module and test it against stable `typescript`, not
84
+ native-preview internals.
67
85
 
68
- Tailwind CSS v4 setup is generated by default. Disable it explicitly when you
69
- need a plain CSS starter:
86
+ Generated CI does not call the local aggregate. It runs format, lint,
87
+ typecheck, skills, i18n boundary validation, contract validation, and build as
88
+ separate matrix jobs so failures are isolated and parallelizable. Generated
89
+ lefthook config runs separate format and lint-fix commands on pre-commit, then
90
+ runs the read-only primitive gates in parallel on pre-push.
91
+
92
+ For local monorepo dependency testing, add `--workspace`:
70
93
 
71
94
  ```bash
72
- pnpm dlx @bleedingdev/modern-js-create my-app --no-tailwind
95
+ pnpm dlx @bleedingdev/modern-js-create my-workspace --workspace
96
+ ```
97
+
98
+ For package-source validation outside the monorepo, pass explicit
99
+ `--ultramodern-package-*` options.
100
+
101
+ ## Automation And Public API
102
+
103
+ The supported runtime import is the public generator subpath. It exposes only
104
+ generator operations and stable result types; CLI argument parsing, prompts,
105
+ registry lookup, and process-exit flows stay private.
106
+
107
+ ```ts
108
+ import {
109
+ addUltramodernVertical,
110
+ generateUltramodernWorkspace,
111
+ planUltramodernVertical,
112
+ } from '@modern-js/create/ultramodern-workspace';
113
+
114
+ const workspace = generateUltramodernWorkspace({
115
+ targetDir: '/tmp/my-workspace',
116
+ packageName: 'my-workspace',
117
+ modernVersion: '3.4.0',
118
+ packageSource: {
119
+ strategy: 'install',
120
+ modernPackageVersion: '3.4.0',
121
+ },
122
+ });
123
+
124
+ const plan = planUltramodernVertical({
125
+ workspaceRoot: workspace.workspaceRoot,
126
+ name: 'new-vertical',
127
+ modernVersion: '3.4.0',
128
+ });
129
+
130
+ const vertical = addUltramodernVertical({
131
+ workspaceRoot: workspace.workspaceRoot,
132
+ name: 'new-vertical',
133
+ modernVersion: '3.4.0',
134
+ });
73
135
  ```
74
136
 
75
- TanStack Router and Tailwind CSS work together without extra flags:
137
+ Workspace generation returns `operation`, `workspaceRoot`, `packageScope`,
138
+ `packageSource`, `createdApps`, `createdPaths`, `rewrittenPaths`,
139
+ `assignedPorts`, `moduleFederationNames`, `effectApiPrefixes`,
140
+ `generatedContractPath`, and `warnings`. MicroVertical addition returns the
141
+ same shape for the new vertical and all rewritten integration surfaces.
142
+
143
+ Dry-run is available for MicroVertical addition only. The CLI prints the plan as
144
+ JSON and writes no files:
76
145
 
77
146
  ```bash
78
- pnpm dlx @bleedingdev/modern-js-create my-app
147
+ pnpm dlx @bleedingdev/modern-js-create new-vertical --vertical --dry-run
148
+ pnpm dlx @bleedingdev/modern-js-create --vertical=new-vertical --dry-run
149
+ pnpm dlx @bleedingdev/modern-js-create --vertical-name new-vertical --dry-run
79
150
  ```
80
151
 
81
- ### BFF Runtime Template
152
+ The dry-run object adds `dryRun: true`, `selectedPort`,
153
+ `moduleFederationRemote`, `effectApiPrefix`, `jsonMutations`,
154
+ `shellDependencyChanges`, and `generatedContractChanges`. It still validates
155
+ the workspace before returning a plan.
156
+
157
+ Validation runs before the first filesystem write. Failures name the owning
158
+ contract so automation can stop safely:
159
+
160
+ | Failure area | Typical cause | Fix |
161
+ | --- | --- | --- |
162
+ | Fresh input | Invalid or missing vertical name | Use `<name> --vertical`, `--vertical=<name>`, or `--vertical-name <name>` |
163
+ | Existing topology | Duplicate app ID, package suffix, path, Module Federation name, port, API prefix, or manifest key | Choose a new vertical name or repair the existing topology/local overlay first |
164
+ | Workspace files | Missing or non-object topology, ownership, package-source, local overlay, or generated contract JSON | Restore the generated contract file from source control or rerun from a valid workspace |
165
+ | Tailwind prefix | Existing app already owns the generated CSS prefix | Rename the vertical before generation |
166
+ | Output path | A generated path already exists | Treat it as an existing vertical and do not overwrite it |
167
+
168
+ Package source is explicit and recorded in `.modernjs/ultramodern-package-source.json`.
169
+
170
+ | Strategy | Use when | CLI |
171
+ | --- | --- | --- |
172
+ | `install` | Published BleedingDev package cohort or release proof | Default for the BleedingDev create package; optional `--ultramodern-package-version`, `--ultramodern-package-registry`, `--ultramodern-package-scope`, and `--ultramodern-package-name-prefix` |
173
+ | `workspace` | Local monorepo testing against unreleased packages | `--workspace` or `--ultramodern-package-source=workspace` |
174
+
175
+ ## Migrating Older Workspaces
82
176
 
83
- UltraModern app scaffolds include Effect HttpApi BFF by default:
177
+ Older generated repos should move by adopting one published BleedingDev cohort
178
+ at a time. Start with a dry-run vertical addition so validation reports
179
+ topology, ownership, package-source, overlay, Tailwind prefix, Module Federation,
180
+ and generated-contract conflicts before files are written:
84
181
 
85
182
  ```bash
86
- pnpm dlx @bleedingdev/modern-js-create my-app
183
+ pnpm dlx @bleedingdev/modern-js-create@latest catalog --vertical --dry-run
184
+ pnpm dlx @bleedingdev/modern-js-create@latest catalog --vertical
185
+ mise install
186
+ mise exec -- pnpm install
187
+ mise exec -- pnpm check
188
+ mise exec -- pnpm build
87
189
  ```
88
190
 
89
- To scaffold Hono runtime explicitly:
191
+ Use `--ultramodern-package-source=install` for published cohort proof and pin a
192
+ specific release with `--ultramodern-package-version` when CI must prove an
193
+ exact framework version. Keep `--workspace` only for local monorepo testing
194
+ against unpublished packages. After install, run the generated
195
+ `scripts/validate-ultramodern-workspace.mjs` contract check and fix ownership
196
+ conflicts in the owning JSON/config files instead of editing generated package
197
+ metadata by hand.
90
198
 
91
- ```bash
92
- pnpm dlx @bleedingdev/modern-js-create my-app --bff-runtime hono
199
+ ## CodeSmith Adapter And Overlays
200
+
201
+ The CodeSmith adapter is exported from:
202
+
203
+ ```ts
204
+ import ultramodernCodeSmith from '@modern-js/create/ultramodern-workspace/codesmith';
93
205
  ```
94
206
 
95
- Generated starters expose `presetUltramodern(...)` as the public opinionated
96
- config wrapper when you want the full Ultramodern setup surface in
97
- `modern.config.ts`.
207
+ Non-interactive usage passes config directly:
208
+
209
+ ```ts
210
+ await ultramodernCodeSmith({
211
+ config: {
212
+ mode: 'workspace',
213
+ name: 'my-workspace',
214
+ targetDir: '/tmp/my-workspace',
215
+ modernVersion: '3.4.0',
216
+ packageSourceStrategy: 'install',
217
+ modernPackageVersion: '3.4.0',
218
+ },
219
+ });
220
+
221
+ await ultramodernCodeSmith({
222
+ config: {
223
+ mode: 'vertical',
224
+ name: 'new-vertical',
225
+ workspaceRoot: '/tmp/my-workspace',
226
+ dryRun: true,
227
+ logResult: true,
228
+ },
229
+ });
230
+ ```
231
+
232
+ The adapter prompts only when a required name is missing and a CodeSmith prompt
233
+ function is available. It returns the same public generation result or dry-run
234
+ plan as the direct API.
98
235
 
99
- TanStack Router, default Tailwind, and Effect BFF are included without extra
100
- flags. For local monorepo dependency testing, add `--workspace`:
236
+ Overlays are explicit CodeSmith generators that run after base workspace or
237
+ MicroVertical generation:
101
238
 
102
239
  ```bash
103
- pnpm dlx @bleedingdev/modern-js-create my-app --workspace
240
+ pnpm dlx @bleedingdev/modern-js-create new-vertical --vertical \
241
+ --codesmith-overlay ./generators/vertical-overlay
242
+ ```
243
+
244
+ ```ts
245
+ addUltramodernVertical({
246
+ workspaceRoot: '/tmp/my-workspace',
247
+ name: 'new-vertical',
248
+ modernVersion: '3.4.0',
249
+ overlays: [
250
+ {
251
+ generator: './generators/vertical-overlay',
252
+ config: { owner: 'workspace' },
253
+ },
254
+ ],
255
+ });
104
256
  ```
105
257
 
106
- ### Vertical Workspace Recipes
258
+ Overlay config receives `workspaceRoot`, `packageScope`, `operation`,
259
+ `generatedApp`, `generatedApps`, `assignedPort`, `assignedPorts`,
260
+ `moduleFederationName`, `moduleFederationNames`, `effectApiPrefix`,
261
+ `effectApiPrefixes`, `packageSource`, and `generationResult`. Overlays extend
262
+ the generated output after base generation; they do not replace, inherit, or
263
+ shadow the base templates. Overlay failures stop the command with an
264
+ `UltraModern CodeSmith overlay failed` error and do not report base generation
265
+ as fully successful.
266
+
267
+ ## Vertical Workspace Recipes
107
268
 
108
269
  Use the workspace add flow from the UltraModern workspace root. It derives the
109
270
  package path, package name, port, Module Federation name, topology entry, local
@@ -112,6 +273,8 @@ requested vertical name.
112
273
 
113
274
  ```bash
114
275
  pnpm dlx @bleedingdev/modern-js-create catalog --vertical
276
+ pnpm dlx @bleedingdev/modern-js-create --vertical=catalog
277
+ pnpm dlx @bleedingdev/modern-js-create --vertical-name catalog
115
278
  ```
116
279
 
117
280
  Use this decision table before adding a vertical:
@@ -124,33 +287,44 @@ Use this decision table before adding a vertical:
124
287
  | Design tokens, primitives, generated clients, or domain-neutral utilities | Yes | Use an ordinary workspace package, not a vertical |
125
288
  | Feature composites or workflow state shared across verticals | No | Revisit ownership; do not hide it in shared code |
126
289
 
127
- The lower-level `--router react-router`, `--workspace`, and `--sub` flags remain
128
- available for compatibility and local package scaffolding, but UltraModern
129
- vertical additions should use `--vertical` so paths, topology, Effect BFF
130
- contracts, and local overlays stay consistent.
131
-
132
- See
133
- `docs/super-app-rfc-adr/WORKSPACE-0001-micro-vertical-workspace-scaffolding.md`
134
- for the canonical workspace topology and local orchestration model.
135
-
136
- The published `@bleedingdev/modern-js-create` package is the preferred
137
- UltraModern.js entrypoint. The lower-level `--ultramodern-*` flags remain
138
- available for release engineering and local package-source testing, but users
139
- should not need them for normal app creation.
140
-
141
- ### SuperApp Architecture Contracts
290
+ ## SuperApp Architecture Contracts
142
291
 
143
292
  The generated shell owns route assembly and policy. Each vertical added with
144
- `--vertical` owns its route subtree, MF exposes, Effect BFF contract, generated
145
- client, `localisedUrls`, locale JSON, CSS layer, and Cloudflare Worker output.
146
- The shell consumes vertical UI through MF manifests and vertical APIs through
147
- generated Effect clients exported by the vertical packages.
148
-
149
- Route localization is route-owned. Each app writes
150
- `src/routes/ultramodern-route-metadata` and passes
151
- `ultramodernLocalisedUrls` into `@modern-js/plugin-i18n`. Locale JSON is served
152
- from `/locales/{{lng}}/{{ns}}.json`; Czech and English routes are generated from
153
- the route owner, not from shell rewrites.
293
+ `--vertical` owns its route subtree, Module Federation exposes, Effect BFF
294
+ contract, generated client, `localisedUrls`, locale JSON, CSS layer, and
295
+ Cloudflare Worker output. The shell consumes vertical UI through Module
296
+ Federation manifests and vertical APIs through generated Effect clients
297
+ exported by the vertical packages.
298
+
299
+ Route metadata is route-owned and colocated in
300
+ `src/routes/**/route.meta.ts`. The scaffold regenerates
301
+ `src/routes/ultramodern-route-metadata.ts` as a compatibility manifest for
302
+ Modern.js config, i18n, public head, and public surface contracts; authors
303
+ should not hand-maintain it. Locale JSON is served from
304
+ `/locales/{{lng}}/{{ns}}.json`; Czech and English routes are generated from the
305
+ route owner, not from shell rewrites.
306
+
307
+ Routes default to `privateByDefault: true` and
308
+ `publicnessDefault: private-app-screen`. Public web artifacts are build/deploy
309
+ outputs generated by `scripts/generate-public-surface-assets.mjs` into
310
+ `dist/public` and `.output/public`, not source files under `config/public`.
311
+ Generated public files use only explicit `public && indexable` route metadata,
312
+ so private app screens publish only a disallowing `robots.txt` by default.
313
+ JSON-LD is not inferred from route titles, descriptions, localized paths, app
314
+ names, BFF APIs, or Module Federation metadata. To publish structured data,
315
+ author `jsonLd` explicitly in route metadata for a `public && indexable` route;
316
+ generated apps provide `src/routes/ultramodern-jsonld.ts` helpers for
317
+ `WebPage`, `WebApplication`, `SoftwareApplication`, `BreadcrumbList`,
318
+ `FAQPage`, and `Organization`, while raw JSON-LD remains possible for other
319
+ schema types.
320
+
321
+ Dynamic public routes can expand sitemap entries through route-owned,
322
+ Node-safe ESM providers, normally `route.sitemap.mjs` beside the route
323
+ metadata. The public-surface generator discovers those providers for dynamic
324
+ public routes and still honors explicit `routes.publicSurface.contentSources`
325
+ entries in the generated compatibility manifest. Providers may export
326
+ `entries`, `entries()`, or a default entries/loader returning sitemap entries;
327
+ draft entries and `indexable: false` entries are omitted.
154
328
 
155
329
  CSS federation is explicit:
156
330
 
@@ -162,15 +336,36 @@ CSS federation is explicit:
162
336
  - Tailwind CSS v4 is configured per app through `@tailwindcss/postcss`.
163
337
  - Duplicate base styles are forbidden; SSR first paint depends on shared token
164
338
  CSS plus Modern/Rspack-emitted app CSS.
165
- - Apps should not inject remote `async-index.css` paths, hardcode remote
166
- stylesheet links, or disable filename hashing to make CSS URLs predictable.
167
- UltraModern SSR resolves federated CSS from build output and MF manifests so
168
- generated shells and demos can keep normal hashed assets.
169
339
 
170
- Version switching evidence must keep UI, Effect API, CSS, i18n JSON, and MF
171
- manifest markers in lockstep for the same vertical version.
340
+ ## Public URL Environment Variables
172
341
 
173
- ### Cloudflare And Zephyr Proof
342
+ Generated apps must not bake absolute `http://localhost:<port>` URLs into asset
343
+ configuration. Public URL and asset prefix environment variables have distinct
344
+ roles, and stale aliases should not be carried forward when regenerating or
345
+ updating workspaces.
346
+
347
+ | Variable | Role | Feeds |
348
+ | --- | --- | --- |
349
+ | `MODERN_PUBLIC_SITE_URL` | Canonical site origin for public SEO output only | Canonical, hreflang, sitemap `<loc>`, robots `Sitemap:` |
350
+ | `MODERN_ASSET_PREFIX` | Preferred JS/CSS/static asset prefix | Modern/Rspack-emitted asset URLs |
351
+ | `ULTRAMODERN_ASSET_PREFIX` | UltraModern compatibility asset prefix | Modern/Rspack-emitted asset URLs when `MODERN_ASSET_PREFIX` is unset |
352
+ | `ULTRAMODERN_PUBLIC_URL_<APP_ID>` | Per-app deployment/proof URL | Cloudflare proof inputs and Module Federation remote URLs |
353
+
354
+ Asset URLs use this precedence: `MODERN_ASSET_PREFIX` →
355
+ `ULTRAMODERN_ASSET_PREFIX` → origin-relative `/`. `MODERN_PUBLIC_SITE_URL` is
356
+ canonical/SEO-only and must not be used as an asset-prefix fallback.
357
+ SEO output uses `MODERN_PUBLIC_SITE_URL`; if it is unset, generated local and
358
+ preview outputs remain non-public until deployment proof provides explicit
359
+ public URLs.
360
+
361
+ Without public URLs configured, asset paths are origin-relative (`/`), and the
362
+ dev server uses `dev.assetPrefix: '/'` — so apps work through tunnels and
363
+ reverse proxies (ngrok, cloudflared) without triggering Chrome's Local Network
364
+ Access prompt or mixed-content errors. Shell-only workspaces can set
365
+ `MODERN_PUBLIC_SITE_URL` for SEO output without changing where assets load
366
+ from.
367
+
368
+ ## Cloudflare And Zephyr Proof
174
369
 
175
370
  Each generated workspace app has:
176
371
 
@@ -181,9 +376,12 @@ Each generated workspace app has:
181
376
  - `zephyr-rspack-plugin` wired through the generated Modern.js Rspack bridge.
182
377
 
183
378
  Deploy first, then pass each deployed app's generated public URL env key into
184
- the proof step. Shell-only workspaces only need the shell URL; added verticals
185
- use the same `ULTRAMODERN_PUBLIC_URL_<APP_ID>` pattern with hyphens converted
186
- to underscores and uppercased:
379
+ the proof step. The proof script reads the generated contract and checks the
380
+ Cloudflare Worker surface, including public-route sitemap/robots consistency,
381
+ preview noindex behavior, unknown-route status, asset headers, byte budgets,
382
+ and public sourcemap exposure. Shell-only workspaces only need the shell URL;
383
+ added verticals use the same `ULTRAMODERN_PUBLIC_URL_<APP_ID>` pattern with
384
+ hyphens converted to underscores and uppercased:
187
385
 
188
386
  ```bash
189
387
  pnpm cloudflare:deploy
@@ -192,50 +390,27 @@ ULTRAMODERN_PUBLIC_URL_TRANSPORTATION=https://transportation.example.workers.dev
192
390
  pnpm cloudflare:proof -- --require-public-urls
193
391
  ```
194
392
 
195
- Without public URLs and credentials, use local `pnpm check` and `pnpm build`
393
+ Without public URLs and credentials, use local primitive gates and `pnpm build`
196
394
  evidence only; do not claim live Cloudflare or Zephyr selection has been
197
395
  proven.
198
396
 
199
- ### Troubleshooting
397
+ ## Troubleshooting
200
398
 
201
399
  | Symptom | Current check | Owner |
202
400
  | --- | --- | --- |
203
401
  | Package cohort mismatch | Regenerate with one package source strategy, run `mise install`, then rerun `pnpm install` from the activated shell. | Generated workspace package source metadata |
204
402
  | Install failure | Check the active Node/pnpm from `mise install`; rerun `pnpm install` after the shell sees the pinned versions. | Toolchain setup |
205
- | Build failure | Run `pnpm check` before `pnpm build`; fix reported format, lint, type, skill, i18n, or generated-contract failures first. | Owning package or generated contract |
403
+ | Build failure | Run the matching primitive gate (`pnpm lint`, `pnpm typecheck`, `pnpm i18n:boundaries`, `pnpm contract:check`) before `pnpm build`; fix the owning failure first. | Owning package or generated contract |
206
404
  | Missing public URL | Set the env key from `.modernjs/ultramodern-generated-contract.json`, for example `ULTRAMODERN_PUBLIC_URL_SHELL_SUPER_APP`. | Deployment operator |
207
405
  | Cloudflare credentials | Confirm Wrangler credentials before `pnpm cloudflare:deploy`; local checks do not prove live Worker access. | Deployment operator |
208
406
  | Asset or CSS 404 | Rebuild with `pnpm build` or `pnpm cloudflare:deploy` and inspect emitted Modern/Rspack asset paths instead of hardcoding CSS URLs. | Framework/runtime asset pipeline |
209
407
  | Federation manifest failure | Run the shell and vertical build scripts, then check each deployed `/mf-manifest.json` URL used by the shell. | Module Federation owner |
210
408
 
211
- ### Local Monorepo Testing
212
-
213
- When testing unreleased Modern.js packages from a local monorepo checkout, use
214
- workspace protocol dependencies:
215
-
216
- ```bash
217
- pnpm dlx @bleedingdev/modern-js-create my-app --workspace
218
- ```
219
-
220
- For package-source validation of the full SuperApp workspace, generate with the
221
- workspace package source, then run the generated contract gate:
222
-
223
- ```bash
224
- pnpm dlx @bleedingdev/modern-js-create my-super-app --ultramodern-workspace --ultramodern-package-source workspace
225
- cd my-super-app
226
- pnpm install
227
- pnpm check
228
- ```
229
-
230
- ## Documentation
409
+ ## Modern.js Documentation
231
410
 
232
411
  - [English Documentation](https://modernjs.dev/en/)
233
412
  - [中文文档](https://modernjs.dev)
234
413
 
235
- ## Contributing
236
-
237
- Please read the [Contributing Guide](https://github.com/web-infra-dev/modern.js/blob/main/CONTRIBUTING.md).
238
-
239
414
  ## License
240
415
 
241
416
  Modern.js is [MIT licensed](https://github.com/web-infra-dev/modern.js/blob/main/LICENSE).
package/bin/run.js CHANGED
@@ -69,5 +69,6 @@ if (env === 'development') {
69
69
  } else {
70
70
  import(pathToFileURL(entry).href).catch(e => {
71
71
  console.error(e);
72
+ process.exit(1);
72
73
  });
73
74
  }
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.n = (module)=>{
5
+ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
6
+ __webpack_require__.d(getter, {
7
+ a: getter
8
+ });
9
+ return getter;
10
+ };
11
+ })();
12
+ (()=>{
13
+ __webpack_require__.d = (exports1, getters, values)=>{
14
+ var define = (defs, kind)=>{
15
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
16
+ enumerable: true,
17
+ [kind]: defs[key]
18
+ });
19
+ };
20
+ define(getters, "get");
21
+ define(values, "value");
22
+ };
23
+ })();
24
+ (()=>{
25
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
26
+ })();
27
+ (()=>{
28
+ __webpack_require__.r = (exports1)=>{
29
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
30
+ value: 'Module'
31
+ });
32
+ Object.defineProperty(exports1, '__esModule', {
33
+ value: true
34
+ });
35
+ };
36
+ })();
37
+ var __webpack_exports__ = {};
38
+ __webpack_require__.r(__webpack_exports__);
39
+ __webpack_require__.d(__webpack_exports__, {
40
+ resolveCreatePackageRoot: ()=>resolveCreatePackageRoot
41
+ });
42
+ const external_node_fs_namespaceObject = require("node:fs");
43
+ var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
44
+ const external_node_path_namespaceObject = require("node:path");
45
+ var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
46
+ const MAX_WALK_UP_LEVELS = 5;
47
+ function resolveCreatePackageRoot(fromDir) {
48
+ let candidate = fromDir;
49
+ for(let level = 0; level <= MAX_WALK_UP_LEVELS; level++){
50
+ if (external_node_fs_default().existsSync(external_node_path_default().join(candidate, 'package.json')) && external_node_fs_default().existsSync(external_node_path_default().join(candidate, 'template-workspace'))) return candidate;
51
+ const parent = external_node_path_default().dirname(candidate);
52
+ if (parent === candidate) break;
53
+ candidate = parent;
54
+ }
55
+ throw new Error(`Unable to resolve the @modern-js/create package root (a directory containing both package.json and template-workspace/) within ${MAX_WALK_UP_LEVELS} levels above ${fromDir}`);
56
+ }
57
+ exports.resolveCreatePackageRoot = __webpack_exports__.resolveCreatePackageRoot;
58
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
59
+ "resolveCreatePackageRoot"
60
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
61
+ Object.defineProperty(exports, '__esModule', {
62
+ value: true
63
+ });