@bleedingdev/modern-js-create 3.2.0-ultramodern.120 → 3.2.0-ultramodern.121

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 (118) hide show
  1. package/README.md +35 -12
  2. package/dist/cjs/create-package-root.cjs +7 -9
  3. package/dist/cjs/index.cjs +74 -44
  4. package/dist/cjs/locale/en.cjs +6 -7
  5. package/dist/cjs/locale/zh.cjs +6 -7
  6. package/dist/cjs/ultramodern-workspace/add-vertical.cjs +337 -0
  7. package/dist/cjs/ultramodern-workspace/app-files.cjs +223 -0
  8. package/dist/cjs/ultramodern-workspace/contracts.cjs +836 -0
  9. package/dist/cjs/ultramodern-workspace/demo-components.cjs +422 -0
  10. package/dist/cjs/ultramodern-workspace/descriptors.cjs +222 -0
  11. package/dist/cjs/ultramodern-workspace/effect-api.cjs +952 -0
  12. package/dist/cjs/ultramodern-workspace/fs-io.cjs +191 -0
  13. package/dist/cjs/ultramodern-workspace/index.cjs +48 -0
  14. package/dist/cjs/ultramodern-workspace/locales.cjs +173 -0
  15. package/dist/cjs/ultramodern-workspace/module-federation.cjs +487 -0
  16. package/dist/cjs/ultramodern-workspace/naming.cjs +161 -0
  17. package/dist/cjs/ultramodern-workspace/package-json.cjs +406 -0
  18. package/dist/cjs/ultramodern-workspace/package-source.cjs +59 -0
  19. package/dist/cjs/ultramodern-workspace/policy.cjs +248 -0
  20. package/dist/cjs/ultramodern-workspace/public-surface.cjs +268 -0
  21. package/dist/cjs/ultramodern-workspace/routes.cjs +375 -0
  22. package/dist/cjs/ultramodern-workspace/types.cjs +61 -0
  23. package/dist/cjs/ultramodern-workspace/versions.cjs +153 -0
  24. package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +153 -0
  25. package/dist/cjs/ultramodern-workspace/write-workspace.cjs +175 -0
  26. package/dist/esm/create-package-root.js +7 -9
  27. package/dist/esm/index.js +72 -42
  28. package/dist/esm/locale/en.js +6 -7
  29. package/dist/esm/locale/zh.js +6 -7
  30. package/dist/esm/ultramodern-workspace/add-vertical.js +252 -0
  31. package/dist/esm/ultramodern-workspace/app-files.js +149 -0
  32. package/dist/esm/ultramodern-workspace/contracts.js +741 -0
  33. package/dist/esm/ultramodern-workspace/demo-components.js +363 -0
  34. package/dist/esm/ultramodern-workspace/descriptors.js +133 -0
  35. package/dist/esm/ultramodern-workspace/effect-api.js +854 -0
  36. package/dist/esm/ultramodern-workspace/fs-io.js +90 -0
  37. package/dist/esm/ultramodern-workspace/index.js +3 -0
  38. package/dist/esm/ultramodern-workspace/locales.js +122 -0
  39. package/dist/esm/ultramodern-workspace/module-federation.js +415 -0
  40. package/dist/esm/ultramodern-workspace/naming.js +71 -0
  41. package/dist/esm/ultramodern-workspace/package-json.js +338 -0
  42. package/dist/esm/ultramodern-workspace/package-source.js +21 -0
  43. package/dist/esm/ultramodern-workspace/policy.js +183 -0
  44. package/dist/esm/ultramodern-workspace/public-surface.js +183 -0
  45. package/dist/esm/ultramodern-workspace/routes.js +280 -0
  46. package/dist/esm/ultramodern-workspace/types.js +16 -0
  47. package/dist/esm/ultramodern-workspace/versions.js +34 -0
  48. package/dist/esm/ultramodern-workspace/workspace-scripts.js +91 -0
  49. package/dist/esm/ultramodern-workspace/write-workspace.js +121 -0
  50. package/dist/esm-node/create-package-root.js +7 -9
  51. package/dist/esm-node/index.js +72 -42
  52. package/dist/esm-node/locale/en.js +6 -7
  53. package/dist/esm-node/locale/zh.js +6 -7
  54. package/dist/esm-node/ultramodern-workspace/add-vertical.js +253 -0
  55. package/dist/esm-node/ultramodern-workspace/app-files.js +150 -0
  56. package/dist/esm-node/ultramodern-workspace/contracts.js +742 -0
  57. package/dist/esm-node/ultramodern-workspace/demo-components.js +364 -0
  58. package/dist/esm-node/ultramodern-workspace/descriptors.js +134 -0
  59. package/dist/esm-node/ultramodern-workspace/effect-api.js +855 -0
  60. package/dist/esm-node/ultramodern-workspace/fs-io.js +91 -0
  61. package/dist/esm-node/ultramodern-workspace/index.js +4 -0
  62. package/dist/esm-node/ultramodern-workspace/locales.js +123 -0
  63. package/dist/esm-node/ultramodern-workspace/module-federation.js +416 -0
  64. package/dist/esm-node/ultramodern-workspace/naming.js +72 -0
  65. package/dist/esm-node/ultramodern-workspace/package-json.js +339 -0
  66. package/dist/esm-node/ultramodern-workspace/package-source.js +22 -0
  67. package/dist/esm-node/ultramodern-workspace/policy.js +184 -0
  68. package/dist/esm-node/ultramodern-workspace/public-surface.js +184 -0
  69. package/dist/esm-node/ultramodern-workspace/routes.js +281 -0
  70. package/dist/esm-node/ultramodern-workspace/types.js +17 -0
  71. package/dist/esm-node/ultramodern-workspace/versions.js +35 -0
  72. package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +92 -0
  73. package/dist/esm-node/ultramodern-workspace/write-workspace.js +122 -0
  74. package/dist/types/locale/en.d.ts +4 -5
  75. package/dist/types/locale/index.d.ts +8 -10
  76. package/dist/types/locale/zh.d.ts +4 -5
  77. package/dist/types/ultramodern-workspace/add-vertical.d.ts +19 -0
  78. package/dist/types/ultramodern-workspace/app-files.d.ts +14 -0
  79. package/dist/types/ultramodern-workspace/contracts.d.ts +21 -0
  80. package/dist/types/ultramodern-workspace/demo-components.d.ts +9 -0
  81. package/dist/types/ultramodern-workspace/descriptors.d.ts +39 -0
  82. package/dist/types/ultramodern-workspace/effect-api.d.ts +73 -0
  83. package/dist/types/ultramodern-workspace/fs-io.d.ts +18 -0
  84. package/dist/types/ultramodern-workspace/index.d.ts +4 -0
  85. package/dist/types/ultramodern-workspace/locales.d.ts +183 -0
  86. package/dist/types/ultramodern-workspace/module-federation.d.ts +16 -0
  87. package/dist/types/ultramodern-workspace/naming.d.ts +16 -0
  88. package/dist/types/ultramodern-workspace/package-json.d.ts +12 -0
  89. package/dist/types/ultramodern-workspace/package-source.d.ts +2 -0
  90. package/dist/types/ultramodern-workspace/policy.d.ts +60 -0
  91. package/dist/types/ultramodern-workspace/public-surface.d.ts +37 -0
  92. package/dist/types/ultramodern-workspace/routes.d.ts +25 -0
  93. package/dist/types/ultramodern-workspace/types.d.ts +95 -0
  94. package/dist/types/ultramodern-workspace/versions.d.ts +38 -0
  95. package/dist/types/ultramodern-workspace/workspace-scripts.d.ts +10 -0
  96. package/dist/types/ultramodern-workspace/write-workspace.d.ts +4 -0
  97. package/package.json +4 -3
  98. package/template-workspace/.github/workflows/ultramodern-workspace-gates.yml.handlebars +1 -4
  99. package/template-workspace/.mise.toml.handlebars +1 -0
  100. package/template-workspace/{AGENTS.md → AGENTS.md.handlebars} +12 -7
  101. package/template-workspace/README.md.handlebars +40 -24
  102. package/template-workspace/{pnpm-workspace.yaml → pnpm-workspace.yaml.handlebars} +2 -2
  103. package/template-workspace/scripts/bootstrap-agent-skills.mjs +31 -51
  104. package/templates/app/shell-frame.tsx +49 -0
  105. package/templates/app/ultramodern-route-head.tsx.handlebars +142 -0
  106. package/templates/packages/shared-contracts-index.ts +466 -0
  107. package/templates/workspace-scripts/assert-mf-types.mjs.handlebars +69 -0
  108. package/templates/workspace-scripts/check-ultramodern-i18n-boundaries.mjs +9 -0
  109. package/templates/workspace-scripts/generate-public-surface-assets.mjs +529 -0
  110. package/templates/workspace-scripts/proof-cloudflare-version.mjs +125 -0
  111. package/templates/workspace-scripts/ultramodern-cloudflare-proof.mjs +851 -0
  112. package/templates/workspace-scripts/ultramodern-performance-readiness.config.mjs +7 -0
  113. package/templates/workspace-scripts/ultramodern-performance-readiness.mjs +223 -0
  114. package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +593 -0
  115. package/dist/cjs/ultramodern-workspace.cjs +0 -6797
  116. package/dist/esm/ultramodern-workspace.js +0 -6738
  117. package/dist/esm-node/ultramodern-workspace.js +0 -6739
  118. package/dist/types/ultramodern-workspace.d.ts +0 -29
package/README.md CHANGED
@@ -17,6 +17,12 @@ UltraModern SuperApp workspace.
17
17
  pnpm dlx @bleedingdev/modern-js-create my-workspace
18
18
  ```
19
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
+
20
26
  To initialize the empty directory you are already in, pass `.` explicitly:
21
27
 
22
28
  ```bash
@@ -44,6 +50,10 @@ pnpm check
44
50
  pnpm build
45
51
  ```
46
52
 
53
+ The generated toolchain baseline is Node `>=26` with pnpm `11.5.3`.
54
+ `packageManager`, `.mise.toml`, generated validation, and CI should all agree
55
+ on that baseline; do not reintroduce Corepack or older pnpm aliases.
56
+
47
57
  Generated CI does not call the local aggregate. It runs format, lint,
48
58
  typecheck, skills, i18n boundary validation, contract validation, and build as
49
59
  separate matrix jobs so failures are isolated and parallelizable. Generated
@@ -103,6 +113,13 @@ outputs generated by `scripts/generate-public-surface-assets.mjs` into
103
113
  `dist/public` and `.output/public`, not source files under `config/public`.
104
114
  Generated public files use only explicit `public && indexable` route metadata,
105
115
  so private app screens publish only a disallowing `robots.txt` by default.
116
+ JSON-LD is not inferred from route titles, descriptions, localized paths, app
117
+ names, BFF APIs, or Module Federation metadata. To publish structured data,
118
+ author `jsonLd` explicitly in route metadata for a `public && indexable` route;
119
+ generated apps provide `src/routes/ultramodern-jsonld.ts` helpers for
120
+ `WebPage`, `WebApplication`, `SoftwareApplication`, `BreadcrumbList`,
121
+ `FAQPage`, and `Organization`, while raw JSON-LD remains possible for other
122
+ schema types.
106
123
 
107
124
  Dynamic public routes can expand sitemap entries through route-owned,
108
125
  Node-safe ESM providers, normally `route.sitemap.mjs` beside the route
@@ -125,25 +142,31 @@ CSS federation is explicit:
125
142
 
126
143
  ## Public URL Environment Variables
127
144
 
128
- Generated apps no longer bake absolute `http://localhost:<port>` URLs into
129
- asset configuration. Two environment variables now have distinct roles in
130
- controlling where assets are served from and where SEO output links point.
145
+ Generated apps must not bake absolute `http://localhost:<port>` URLs into asset
146
+ configuration. Public URL and asset prefix environment variables have distinct
147
+ roles, and stale aliases should not be carried forward when regenerating or
148
+ updating workspaces.
131
149
 
132
150
  | Variable | Role | Feeds |
133
151
  | --- | --- | --- |
134
- | `ULTRAMODERN_PUBLIC_URL_<APP_ID>` | Per-app deployment and asset origin | `output.assetPrefix`, Module Federation remote URLs |
135
- | `MODERN_PUBLIC_SITE_URL` | Site-wide public origin for SEO output | Canonical, hreflang, sitemap `<loc>`, robots `Sitemap:` |
136
-
137
- Asset URLs use this precedence: `ULTRAMODERN_PUBLIC_URL_<APP_ID>`
138
- `MODERN_PUBLIC_SITE_URL` → inferred workers.dev URL → origin-relative `/`.
139
- SEO and site origin prefer: `MODERN_PUBLIC_SITE_URL` →
140
- `ULTRAMODERN_PUBLIC_URL_<APP_ID>`inferred workers.dev `http://localhost:<port>`.
152
+ | `MODERN_PUBLIC_SITE_URL` | Canonical site origin for public SEO output only | Canonical, hreflang, sitemap `<loc>`, robots `Sitemap:` |
153
+ | `MODERN_ASSET_PREFIX` | Preferred JS/CSS/static asset prefix | Modern/Rspack-emitted asset URLs |
154
+ | `ULTRAMODERN_ASSET_PREFIX` | UltraModern compatibility asset prefix | Modern/Rspack-emitted asset URLs when `MODERN_ASSET_PREFIX` is unset |
155
+ | `ULTRAMODERN_PUBLIC_URL_<APP_ID>` | Per-app deployment/proof URL | Cloudflare proof inputs and Module Federation remote URLs |
156
+
157
+ Asset URLs use this precedence: `MODERN_ASSET_PREFIX` →
158
+ `ULTRAMODERN_ASSET_PREFIX`origin-relative `/`. `MODERN_PUBLIC_SITE_URL` is
159
+ canonical/SEO-only and must not be used as an asset-prefix fallback.
160
+ SEO output uses `MODERN_PUBLIC_SITE_URL`; if it is unset, generated local and
161
+ preview outputs remain non-public until deployment proof provides explicit
162
+ public URLs.
141
163
 
142
164
  Without public URLs configured, asset paths are origin-relative (`/`), and the
143
165
  dev server uses `dev.assetPrefix: '/'` — so apps work through tunnels and
144
166
  reverse proxies (ngrok, cloudflared) without triggering Chrome's Local Network
145
- Access prompt or mixed-content errors. Shell-only workspaces can set just
146
- `MODERN_PUBLIC_SITE_URL` for SEO output.
167
+ Access prompt or mixed-content errors. Shell-only workspaces can set
168
+ `MODERN_PUBLIC_SITE_URL` for SEO output without changing where assets load
169
+ from.
147
170
 
148
171
  ## Cloudflare And Zephyr Proof
149
172
 
@@ -43,18 +43,16 @@ const external_node_fs_namespaceObject = require("node:fs");
43
43
  var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
44
44
  const external_node_path_namespaceObject = require("node:path");
45
45
  var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
46
+ const MAX_WALK_UP_LEVELS = 5;
46
47
  function resolveCreatePackageRoot(fromDir) {
47
- const candidates = [
48
- fromDir,
49
- external_node_path_default().resolve(fromDir, '..'),
50
- external_node_path_default().resolve(fromDir, '..', '..')
51
- ];
52
- const seen = new Set();
53
- for (const candidate of candidates)if (!seen.has(candidate)) {
54
- seen.add(candidate);
48
+ let candidate = fromDir;
49
+ for(let level = 0; level <= MAX_WALK_UP_LEVELS; level++){
55
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;
56
54
  }
57
- throw new Error('Unable to resolve create package root');
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}`);
58
56
  }
59
57
  exports.resolveCreatePackageRoot = __webpack_exports__.resolveCreatePackageRoot;
60
58
  for(var __rspack_i in __webpack_exports__)if (-1 === [
@@ -39,12 +39,19 @@ const external_node_url_namespaceObject = require("node:url");
39
39
  const external_create_package_root_cjs_namespaceObject = require("./create-package-root.cjs");
40
40
  const index_cjs_namespaceObject = require("./locale/index.cjs");
41
41
  const external_ultramodern_package_source_cjs_namespaceObject = require("./ultramodern-package-source.cjs");
42
- const external_ultramodern_workspace_cjs_namespaceObject = require("./ultramodern-workspace.cjs");
42
+ const external_ultramodern_workspace_index_cjs_namespaceObject = require("./ultramodern-workspace/index.cjs");
43
43
  const src_dirname = external_node_path_default().dirname((0, external_node_url_namespaceObject.fileURLToPath)(__rslib_import_meta_url__));
44
44
  const createPackageRoot = (0, external_create_package_root_cjs_namespaceObject.resolveCreatePackageRoot)(src_dirname);
45
45
  const semverPattern = /^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
46
46
  const LEGACY_MODERN_JS_FLAG = '--legacy-modern-js';
47
47
  const LEGACY_MODERN_JS_CONFIRMATION = 'USE LEGACY MODERN.JS';
48
+ const WORKSPACE_PROTOCOL_FLAG = '--workspace';
49
+ const BFF_FLAG = '--bff';
50
+ const BFF_RUNTIME_OPTION = '--bff-runtime';
51
+ const SUPPORTED_BFF_RUNTIMES = [
52
+ 'effect'
53
+ ];
54
+ const REGISTRY_LOOKUP_TIMEOUT_MS = 15000;
48
55
  function getOptionValue(args, names) {
49
56
  for (const name of names){
50
57
  const prefix = `${name}=`;
@@ -78,8 +85,10 @@ function getBleedingDevFrameworkVersion(createPackage, fallbackVersion) {
78
85
  }
79
86
  function showVersion() {
80
87
  const createPackage = readCreatePackageJson();
88
+ const name = createPackage.name || '@modern-js/create';
81
89
  const version = createPackage.version || 'unknown';
82
90
  console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.version.message, {
91
+ name,
83
92
  version
84
93
  }));
85
94
  process.exit(0);
@@ -95,20 +104,26 @@ function showHelp() {
95
104
  console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.optionHelp));
96
105
  console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.optionVersion));
97
106
  console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.optionLang));
98
- if (index_cjs_namespaceObject.localeKeys.help.optionTailwind) console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.optionTailwind));
99
- if (index_cjs_namespaceObject.localeKeys.help.optionUltramodernPackageSource) console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.optionUltramodernPackageSource));
100
- if (index_cjs_namespaceObject.localeKeys.help.optionUltramodernPackageScope) console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.optionUltramodernPackageScope));
101
- if (index_cjs_namespaceObject.localeKeys.help.optionUltramodernPackageNamePrefix) console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.optionUltramodernPackageNamePrefix));
102
- if (index_cjs_namespaceObject.localeKeys.help.optionVertical) console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.optionVertical));
103
- if (index_cjs_namespaceObject.localeKeys.help.optionLegacyModernJs) console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.optionLegacyModernJs));
107
+ console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.optionTailwind));
108
+ console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.optionBff));
109
+ console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.optionBffRuntime));
110
+ console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.optionWorkspace));
111
+ console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.optionUltramodernPackageSource));
112
+ console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.optionUltramodernPackageVersion));
113
+ console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.optionUltramodernPackageRegistry));
114
+ console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.optionUltramodernPackageScope));
115
+ console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.optionUltramodernPackageNamePrefix));
116
+ console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.optionVertical));
117
+ console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.optionLegacyModernJs));
104
118
  console.log('');
105
119
  console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.examples));
106
120
  console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.example1));
107
121
  console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.example2));
108
- if (index_cjs_namespaceObject.localeKeys.help.example4) console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.example4));
109
- if (index_cjs_namespaceObject.localeKeys.help.example5) console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.example5));
110
- if (index_cjs_namespaceObject.localeKeys.help.example6) console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.example6));
111
- if (index_cjs_namespaceObject.localeKeys.help.example12) console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.example12));
122
+ console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.example3));
123
+ console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.example4));
124
+ console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.example5));
125
+ console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.example6));
126
+ console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.example7));
112
127
  console.log('');
113
128
  console.log(index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.help.moreInfo));
114
129
  console.log('');
@@ -165,6 +180,26 @@ function delegateLegacyModernJsSetup(args) {
165
180
  });
166
181
  throw new Error('Legacy Modern.js setup requires pnpm or npx to run @modern-js/create.');
167
182
  }
183
+ function detectBffRuntime(args) {
184
+ if (args.some((arg)=>arg.startsWith(`${BFF_FLAG}=`))) {
185
+ console.error(`${BFF_FLAG} does not accept a value. Use: ${BFF_RUNTIME_OPTION} <runtime>`);
186
+ process.exit(1);
187
+ }
188
+ const runtimeRequested = args.some((arg)=>arg === BFF_RUNTIME_OPTION || arg.startsWith(`${BFF_RUNTIME_OPTION}=`));
189
+ if (!runtimeRequested) return 'effect';
190
+ const runtime = getOptionValue(args, [
191
+ BFF_RUNTIME_OPTION
192
+ ]);
193
+ if (!runtime) {
194
+ console.error(`${BFF_RUNTIME_OPTION} requires a value (supported: ${SUPPORTED_BFF_RUNTIMES.join(', ')})`);
195
+ process.exit(1);
196
+ }
197
+ if (!SUPPORTED_BFF_RUNTIMES.includes(runtime)) {
198
+ console.error(`Unsupported BFF runtime "${runtime}". UltraModern workspaces scaffold an Effect BFF for every MicroVertical (supported: ${SUPPORTED_BFF_RUNTIMES.join(', ')}).`);
199
+ process.exit(1);
200
+ }
201
+ return runtime;
202
+ }
168
203
  function detectTailwindFlag() {
169
204
  const args = process.argv.slice(2);
170
205
  return !args.includes('--no-tailwind');
@@ -216,7 +251,7 @@ function hasExplicitUltramodernPackageSource(args, value) {
216
251
  ]);
217
252
  return value ? configuredValue === value : void 0 !== configuredValue;
218
253
  }
219
- function readBleedingDevFrameworkVersionFromRegistry() {
254
+ function readBleedingDevFrameworkVersionFromRegistry(fallbackVersion) {
220
255
  const envVersion = process.env[external_ultramodern_package_source_cjs_namespaceObject.BLEEDINGDEV_FRAMEWORK_VERSION_ENV]?.trim();
221
256
  if (envVersion) {
222
257
  if (!semverPattern.test(envVersion)) {
@@ -231,16 +266,19 @@ function readBleedingDevFrameworkVersionFromRegistry() {
231
266
  `${external_ultramodern_package_source_cjs_namespaceObject.BLEEDINGDEV_CREATE_PACKAGE}@latest`,
232
267
  'ultramodern.frameworkVersion',
233
268
  '--json'
234
- ]).trim();
269
+ ], {
270
+ timeoutMs: REGISTRY_LOOKUP_TIMEOUT_MS
271
+ }).trim();
235
272
  const version = JSON.parse(rawVersion);
236
273
  if ('string' == typeof version && semverPattern.test(version)) return version;
237
274
  } catch {}
238
- console.error([
239
- `Could not resolve ${external_ultramodern_package_source_cjs_namespaceObject.BLEEDINGDEV_CREATE_PACKAGE}@latest ultramodern.frameworkVersion.`,
240
- 'Pass --workspace to use local workspace protocol dependencies,',
275
+ console.warn([
276
+ `Could not resolve ${external_ultramodern_package_source_cjs_namespaceObject.BLEEDINGDEV_CREATE_PACKAGE}@latest ultramodern.frameworkVersion from the npm registry.`,
277
+ `Falling back to the packaged framework version ${fallbackVersion}.`,
278
+ `Pass ${WORKSPACE_PROTOCOL_FLAG} to use local workspace protocol dependencies,`,
241
279
  'or pass --ultramodern-package-version with the exact BleedingDev framework cohort.'
242
280
  ].join(' '));
243
- process.exit(1);
281
+ return fallbackVersion;
244
282
  }
245
283
  function resolveInstallBackedPackageSource(args, createPackage, packageSource) {
246
284
  const explicitVersion = getOptionValue(args, [
@@ -255,7 +293,7 @@ function resolveInstallBackedPackageSource(args, createPackage, packageSource) {
255
293
  return {
256
294
  ...packageSource,
257
295
  strategy: 'install',
258
- modernPackageVersion: explicitVersion ?? (isBleedingDevCreatePackage(createPackage) ? packageSource.modernPackageVersion : readBleedingDevFrameworkVersionFromRegistry()),
296
+ modernPackageVersion: explicitVersion ?? (isBleedingDevCreatePackage(createPackage) ? packageSource.modernPackageVersion : readBleedingDevFrameworkVersionFromRegistry(packageSource.modernPackageVersion)),
259
297
  aliasScope,
260
298
  aliasPackageNamePrefix: getOptionValue(args, [
261
299
  '--ultramodern-package-name-prefix'
@@ -263,7 +301,12 @@ function resolveInstallBackedPackageSource(args, createPackage, packageSource) {
263
301
  };
264
302
  }
265
303
  function resolveWorkspacePackageSource(args, createPackage, packageSource) {
266
- if (hasExplicitUltramodernPackageSource(args, 'workspace')) return {
304
+ const workspaceProtocolRequested = args.includes(WORKSPACE_PROTOCOL_FLAG);
305
+ if (workspaceProtocolRequested && hasExplicitUltramodernPackageSource(args, 'install')) {
306
+ console.error(`${WORKSPACE_PROTOCOL_FLAG} conflicts with --ultramodern-package-source=install`);
307
+ process.exit(1);
308
+ }
309
+ if (workspaceProtocolRequested || hasExplicitUltramodernPackageSource(args, 'workspace')) return {
267
310
  ...packageSource,
268
311
  strategy: 'workspace',
269
312
  modernPackageVersion: external_ultramodern_package_source_cjs_namespaceObject.WORKSPACE_PACKAGE_VERSION
@@ -278,7 +321,8 @@ function runSetupCommand(command, args, options = {}) {
278
321
  'ignore',
279
322
  'pipe',
280
323
  'pipe'
281
- ]
324
+ ],
325
+ timeout: options.timeoutMs
282
326
  });
283
327
  }
284
328
  function commandExists(command) {
@@ -293,26 +337,9 @@ function commandExists(command) {
293
337
  return false;
294
338
  }
295
339
  }
296
- function installGitForGeneratedProject() {
340
+ function assertGitAvailableForGeneratedProject() {
297
341
  if (commandExists('git')) return;
298
- const runShell = (script)=>runSetupCommand('sh', [
299
- '-lc',
300
- script
301
- ], {
302
- stdio: 'inherit'
303
- });
304
- const sudo = 'function' == typeof process.getuid && 0 === process.getuid() ? '' : 'sudo ';
305
- if (commandExists('brew')) runSetupCommand('brew', [
306
- 'install',
307
- 'git'
308
- ], {
309
- stdio: 'inherit'
310
- });
311
- else if ('linux' === process.platform && commandExists('apt-get')) runShell(`${sudo}apt-get update && ${sudo}apt-get install -y git`);
312
- else if ('linux' === process.platform && commandExists('dnf')) runShell(`${sudo}dnf install -y git`);
313
- else if ('linux' === process.platform && commandExists('yum')) runShell(`${sudo}yum install -y git`);
314
- else if ('linux' === process.platform && commandExists('apk')) runShell('apk add --no-cache git');
315
- if (!commandExists('git')) throw new Error('Git is required for UltraModern setup. Install git and rerun create, or run pnpm skills:install after installing git.');
342
+ throw new Error('Git is required for UltraModern setup. Install git yourself (for example "brew install git" or "sudo apt-get install git") and rerun create. This tool never installs system packages on your behalf.');
316
343
  }
317
344
  function isInsideGitWorkTree(targetDir) {
318
345
  try {
@@ -327,7 +354,7 @@ function isInsideGitWorkTree(targetDir) {
327
354
  }
328
355
  }
329
356
  function initializeGeneratedGitRepository(targetDir) {
330
- installGitForGeneratedProject();
357
+ assertGitAvailableForGeneratedProject();
331
358
  if (isInsideGitWorkTree(targetDir)) return;
332
359
  try {
333
360
  runSetupCommand('git', [
@@ -369,6 +396,7 @@ async function getProjectName() {
369
396
  const optionWithValue = new Set([
370
397
  '--lang',
371
398
  '-l',
399
+ BFF_RUNTIME_OPTION,
372
400
  '--ultramodern-package-source',
373
401
  '--ultramodern-package-version',
374
402
  '--ultramodern-package-registry',
@@ -382,7 +410,8 @@ async function getProjectName() {
382
410
  '-v',
383
411
  '--tailwind',
384
412
  '--no-tailwind',
385
- '--workspace',
413
+ BFF_FLAG,
414
+ WORKSPACE_PROTOCOL_FLAG,
386
415
  '--vertical',
387
416
  LEGACY_MODERN_JS_FLAG
388
417
  ]);
@@ -394,7 +423,7 @@ async function getProjectName() {
394
423
  i += 1;
395
424
  continue;
396
425
  }
397
- if (!(arg.startsWith('--lang=') || arg.startsWith('--ultramodern-package-source=') || arg.startsWith('--ultramodern-package-version=') || arg.startsWith('--ultramodern-package-registry=') || arg.startsWith('--ultramodern-package-scope=') || arg.startsWith('--ultramodern-package-name-prefix='))) positionalArgs.push(arg);
426
+ if (!(arg.startsWith('--lang=') || arg.startsWith(`${BFF_RUNTIME_OPTION}=`) || arg.startsWith('--ultramodern-package-source=') || arg.startsWith('--ultramodern-package-version=') || arg.startsWith('--ultramodern-package-registry=') || arg.startsWith('--ultramodern-package-scope=') || arg.startsWith('--ultramodern-package-name-prefix='))) positionalArgs.push(arg);
398
427
  }
399
428
  }
400
429
  if (positionalArgs.length > 1) {
@@ -436,6 +465,7 @@ async function main() {
436
465
  delegateLegacyModernJsSetup(args);
437
466
  return;
438
467
  }
468
+ detectBffRuntime(args);
439
469
  console.log(`\n${index_cjs_namespaceObject.i18n.t(index_cjs_namespaceObject.localeKeys.message.welcome)}\n`);
440
470
  const { name: projectName, useCurrentDir } = await getProjectName();
441
471
  const targetDir = useCurrentDir ? process.cwd() : external_node_path_default().isAbsolute(projectName) ? projectName : external_node_path_default().resolve(process.cwd(), projectName);
@@ -446,7 +476,7 @@ async function main() {
446
476
  const addVertical = detectVerticalFlag();
447
477
  if (addVertical) {
448
478
  const overridePackageSource = args.some((arg)=>arg.startsWith('--ultramodern-package-')) ? detectUltramodernPackageSource(args, ultramodernPackageVersion, createPackage) : void 0;
449
- (0, external_ultramodern_workspace_cjs_namespaceObject.addUltramodernVertical)({
479
+ (0, external_ultramodern_workspace_index_cjs_namespaceObject.addUltramodernVertical)({
450
480
  workspaceRoot: process.cwd(),
451
481
  name: generatedPackageName,
452
482
  modernVersion: version,
@@ -469,7 +499,7 @@ async function main() {
469
499
  }
470
500
  }
471
501
  const packageSource = resolveWorkspacePackageSource(args, createPackage, detectUltramodernPackageSource(args, ultramodernPackageVersion, createPackage));
472
- (0, external_ultramodern_workspace_cjs_namespaceObject.generateUltramodernWorkspace)({
502
+ (0, external_ultramodern_workspace_index_cjs_namespaceObject.generateUltramodernWorkspace)({
473
503
  targetDir,
474
504
  packageName: generatedPackageName,
475
505
  modernVersion: version,
@@ -57,8 +57,12 @@ const EN_LOCALE = {
57
57
  optionVersion: ' -v, --version Display version information',
58
58
  optionLang: ' -l, --lang Set the language (en default; zh opt-in)',
59
59
  optionTailwind: ' --no-tailwind Disable default Tailwind CSS v4 workspace styling',
60
+ optionBff: ' --bff Keep the default Effect BFF scaffolding (every MicroVertical ships an Effect BFF)',
61
+ optionBffRuntime: ' --bff-runtime Select the BFF runtime for scaffolded MicroVerticals (supported: effect; default: effect)',
60
62
  optionWorkspace: ' --workspace Use workspace protocol for @modern-js dependencies (for local monorepo testing)',
61
63
  optionUltramodernPackageSource: ' --ultramodern-package-source Select UltraModern package source (workspace or install; BleedingDev defaults to install aliases)',
64
+ optionUltramodernPackageVersion: ' --ultramodern-package-version Pin the exact BleedingDev framework cohort for install package sources',
65
+ optionUltramodernPackageRegistry: ' --ultramodern-package-registry npm registry URL used for install package sources',
62
66
  optionUltramodernPackageScope: ' --ultramodern-package-scope Publish scope for npm alias installs (for example bleedingdev)',
63
67
  optionUltramodernPackageNamePrefix: ' --ultramodern-package-name-prefix Prefix for npm alias package names (default: modern-js-)',
64
68
  optionVertical: ' --vertical Mutate the current existing UltraModern workspace and wire a MicroVertical named <project-name>',
@@ -70,16 +74,11 @@ const EN_LOCALE = {
70
74
  example4: ' pnpm dlx @bleedingdev/modern-js-create --help',
71
75
  example5: ' pnpm dlx @bleedingdev/modern-js-create .',
72
76
  example6: ' pnpm dlx @bleedingdev/modern-js-create my-workspace --workspace',
73
- example7: '',
74
- example8: '',
75
- example9: '',
76
- example10: '',
77
- example11: '',
78
- example12: ' pnpm dlx @bleedingdev/modern-js-create catalog --vertical',
77
+ example7: ' pnpm dlx @bleedingdev/modern-js-create catalog --vertical',
79
78
  moreInfo: '📚 Learn more: https://modernjs.dev'
80
79
  },
81
80
  version: {
82
- message: '@bleedingdev/modern-js-create version: {version}'
81
+ message: '{name} version: {version}'
83
82
  }
84
83
  };
85
84
  __webpack_require__.d(__webpack_exports__, {}, {
@@ -57,8 +57,12 @@ const ZH_LOCALE = {
57
57
  optionVersion: ' -v, --version 显示版本信息',
58
58
  optionLang: ' -l, --lang 设置语言 (默认 en;zh 需显式选择)',
59
59
  optionTailwind: ' --no-tailwind 禁用默认 Tailwind CSS v4 工作区样式',
60
+ optionBff: ' --bff 保留默认的 Effect BFF 脚手架(每个 MicroVertical 自带 Effect BFF)',
61
+ optionBffRuntime: ' --bff-runtime 选择 MicroVertical 脚手架的 BFF 运行时(支持: effect;默认: effect)',
60
62
  optionWorkspace: ' --workspace 对 @modern-js 依赖使用 workspace 协议(用于本地 monorepo 联调)',
61
63
  optionUltramodernPackageSource: ' --ultramodern-package-source 选择 UltraModern 依赖来源(workspace 或 install;BleedingDev 默认使用 install alias)',
64
+ optionUltramodernPackageVersion: ' --ultramodern-package-version 为 install 依赖来源固定精确的 BleedingDev 框架版本',
65
+ optionUltramodernPackageRegistry: ' --ultramodern-package-registry install 依赖来源使用的 npm registry 地址',
62
66
  optionUltramodernPackageScope: ' --ultramodern-package-scope npm alias 安装使用的发布 scope(例如 bleedingdev)',
63
67
  optionUltramodernPackageNamePrefix: ' --ultramodern-package-name-prefix npm alias 包名前缀(默认:modern-js-)',
64
68
  optionVertical: ' --vertical 修改当前已有的 UltraModern 工作区,并接入名为 <项目名称> 的 MicroVertical',
@@ -70,16 +74,11 @@ const ZH_LOCALE = {
70
74
  example4: ' pnpm dlx @bleedingdev/modern-js-create --help',
71
75
  example5: ' pnpm dlx @bleedingdev/modern-js-create .',
72
76
  example6: ' pnpm dlx @bleedingdev/modern-js-create my-workspace --workspace',
73
- example7: '',
74
- example8: '',
75
- example9: '',
76
- example10: '',
77
- example11: '',
78
- example12: ' pnpm dlx @bleedingdev/modern-js-create catalog --vertical',
77
+ example7: ' pnpm dlx @bleedingdev/modern-js-create catalog --vertical',
79
78
  moreInfo: '📚 更多信息: https://modernjs.dev'
80
79
  },
81
80
  version: {
82
- message: '@bleedingdev/modern-js-create 版本: {version}'
81
+ message: '{name} 版本: {version}'
83
82
  }
84
83
  };
85
84
  __webpack_require__.d(__webpack_exports__, {}, {