@bleedingdev/modern-js-create 3.4.0-ultramodern.2 → 3.4.0-ultramodern.20

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 (128) hide show
  1. package/README.md +13 -11
  2. package/dist/cjs/index.cjs +37 -4
  3. package/dist/cjs/locale/en.cjs +12 -2
  4. package/dist/cjs/locale/zh.cjs +12 -2
  5. package/dist/cjs/ultramodern-tooling/commands.cjs +185 -0
  6. package/dist/cjs/ultramodern-tooling/config.cjs +172 -0
  7. package/dist/cjs/ultramodern-workspace/add-vertical.cjs +79 -61
  8. package/dist/cjs/ultramodern-workspace/bridge-config.cjs +327 -0
  9. package/dist/cjs/ultramodern-workspace/codesmith.cjs +1 -0
  10. package/dist/cjs/ultramodern-workspace/contracts.cjs +121 -648
  11. package/dist/cjs/ultramodern-workspace/demo-components.cjs +26 -33
  12. package/dist/cjs/ultramodern-workspace/descriptors.cjs +4 -4
  13. package/dist/cjs/ultramodern-workspace/effect-api.cjs +230 -100
  14. package/dist/cjs/ultramodern-workspace/fs-io.cjs +117 -0
  15. package/dist/cjs/ultramodern-workspace/generation-result.cjs +1 -1
  16. package/dist/cjs/ultramodern-workspace/index.cjs +4 -0
  17. package/dist/cjs/ultramodern-workspace/mf-validation.cjs +571 -0
  18. package/dist/cjs/ultramodern-workspace/module-federation.cjs +51 -20
  19. package/dist/cjs/ultramodern-workspace/package-json.cjs +62 -19
  20. package/dist/cjs/ultramodern-workspace/policy.cjs +2 -2
  21. package/dist/cjs/ultramodern-workspace/public-api.cjs +4 -0
  22. package/dist/cjs/ultramodern-workspace/versions.cjs +5 -0
  23. package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +80 -43
  24. package/dist/cjs/ultramodern-workspace/write-workspace.cjs +63 -20
  25. package/dist/esm/index.js +37 -4
  26. package/dist/esm/locale/en.js +12 -2
  27. package/dist/esm/locale/zh.js +12 -2
  28. package/dist/esm/ultramodern-tooling/commands.js +132 -0
  29. package/dist/esm/ultramodern-tooling/config.js +120 -0
  30. package/dist/esm/ultramodern-workspace/add-vertical.js +81 -66
  31. package/dist/esm/ultramodern-workspace/bridge-config.js +270 -0
  32. package/dist/esm/ultramodern-workspace/codesmith.js +1 -0
  33. package/dist/esm/ultramodern-workspace/contracts.js +124 -603
  34. package/dist/esm/ultramodern-workspace/demo-components.js +26 -33
  35. package/dist/esm/ultramodern-workspace/descriptors.js +2 -2
  36. package/dist/esm/ultramodern-workspace/effect-api.js +230 -100
  37. package/dist/esm/ultramodern-workspace/fs-io.js +116 -2
  38. package/dist/esm/ultramodern-workspace/generation-result.js +2 -2
  39. package/dist/esm/ultramodern-workspace/index.js +1 -0
  40. package/dist/esm/ultramodern-workspace/mf-validation.js +516 -0
  41. package/dist/esm/ultramodern-workspace/module-federation.js +49 -21
  42. package/dist/esm/ultramodern-workspace/package-json.js +60 -20
  43. package/dist/esm/ultramodern-workspace/policy.js +2 -2
  44. package/dist/esm/ultramodern-workspace/public-api.js +1 -0
  45. package/dist/esm/ultramodern-workspace/versions.js +3 -1
  46. package/dist/esm/ultramodern-workspace/workspace-scripts.js +78 -26
  47. package/dist/esm/ultramodern-workspace/write-workspace.js +67 -27
  48. package/dist/esm-node/index.js +37 -4
  49. package/dist/esm-node/locale/en.js +12 -2
  50. package/dist/esm-node/locale/zh.js +12 -2
  51. package/dist/esm-node/ultramodern-tooling/commands.js +133 -0
  52. package/dist/esm-node/ultramodern-tooling/config.js +121 -0
  53. package/dist/esm-node/ultramodern-workspace/add-vertical.js +81 -66
  54. package/dist/esm-node/ultramodern-workspace/bridge-config.js +271 -0
  55. package/dist/esm-node/ultramodern-workspace/codesmith.js +1 -0
  56. package/dist/esm-node/ultramodern-workspace/contracts.js +124 -603
  57. package/dist/esm-node/ultramodern-workspace/demo-components.js +26 -33
  58. package/dist/esm-node/ultramodern-workspace/descriptors.js +2 -2
  59. package/dist/esm-node/ultramodern-workspace/effect-api.js +230 -100
  60. package/dist/esm-node/ultramodern-workspace/fs-io.js +116 -2
  61. package/dist/esm-node/ultramodern-workspace/generation-result.js +2 -2
  62. package/dist/esm-node/ultramodern-workspace/index.js +1 -0
  63. package/dist/esm-node/ultramodern-workspace/mf-validation.js +517 -0
  64. package/dist/esm-node/ultramodern-workspace/module-federation.js +49 -21
  65. package/dist/esm-node/ultramodern-workspace/package-json.js +60 -20
  66. package/dist/esm-node/ultramodern-workspace/policy.js +2 -2
  67. package/dist/esm-node/ultramodern-workspace/public-api.js +1 -0
  68. package/dist/esm-node/ultramodern-workspace/versions.js +3 -1
  69. package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +78 -26
  70. package/dist/esm-node/ultramodern-workspace/write-workspace.js +67 -27
  71. package/dist/types/locale/en.d.ts +10 -0
  72. package/dist/types/locale/index.d.ts +20 -0
  73. package/dist/types/locale/zh.d.ts +10 -0
  74. package/dist/types/ultramodern-tooling/commands.d.ts +1 -0
  75. package/dist/types/ultramodern-tooling/config.d.ts +43 -0
  76. package/dist/types/ultramodern-workspace/add-vertical.d.ts +5 -2
  77. package/dist/types/ultramodern-workspace/bridge-config.d.ts +64 -0
  78. package/dist/types/ultramodern-workspace/codesmith.d.ts +1 -0
  79. package/dist/types/ultramodern-workspace/contracts.d.ts +2 -17
  80. package/dist/types/ultramodern-workspace/descriptors.d.ts +1 -1
  81. package/dist/types/ultramodern-workspace/fs-io.d.ts +1 -0
  82. package/dist/types/ultramodern-workspace/index.d.ts +2 -0
  83. package/dist/types/ultramodern-workspace/mf-validation.d.ts +27 -0
  84. package/dist/types/ultramodern-workspace/module-federation.d.ts +1 -0
  85. package/dist/types/ultramodern-workspace/package-json.d.ts +5 -3
  86. package/dist/types/ultramodern-workspace/public-api.d.ts +2 -0
  87. package/dist/types/ultramodern-workspace/types.d.ts +2 -0
  88. package/dist/types/ultramodern-workspace/versions.d.ts +2 -0
  89. package/dist/types/ultramodern-workspace/workspace-scripts.d.ts +2 -7
  90. package/dist/types/ultramodern-workspace/write-workspace.d.ts +4 -2
  91. package/package.json +5 -3
  92. package/template-workspace/{.agents → .codex}/skills-lock.json +12 -12
  93. package/template-workspace/.gitignore.handlebars +3 -0
  94. package/template-workspace/AGENTS.md.handlebars +11 -5
  95. package/template-workspace/README.md.handlebars +15 -12
  96. package/template-workspace/oxfmt.config.ts +1 -0
  97. package/template-workspace/oxlint.config.ts +1 -0
  98. package/template-workspace/patches/@tanstack__router-core@1.171.13.patch +51 -0
  99. package/template-workspace/pnpm-workspace.yaml.handlebars +12 -0
  100. package/template-workspace/scripts/bootstrap-agent-skills.mjs +96 -69
  101. package/templates/app/shell-frame.tsx +1 -2
  102. package/templates/app/ultramodern-route-head.tsx.handlebars +5 -6
  103. package/templates/workspace-scripts/assert-mf-types.mjs.handlebars +59 -7
  104. package/templates/workspace-scripts/check-ultramodern-api-boundaries.mjs +339 -0
  105. package/templates/workspace-scripts/generate-public-surface-assets.mjs +245 -8
  106. package/templates/workspace-scripts/proof-cloudflare-version.mjs +276 -8
  107. package/templates/workspace-scripts/ultramodern-cloudflare-proof.mjs +35 -10
  108. package/templates/workspace-scripts/ultramodern-performance-readiness.mjs +164 -1
  109. package/templates/workspace-scripts/ultramodern-typecheck.mjs +4 -2
  110. package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +949 -63
  111. /package/template-workspace/{.agents → .codex}/rstackjs-agent-skills-LICENSE +0 -0
  112. /package/template-workspace/{.agents → .codex}/skills/rsbuild-best-practices/SKILL.md +0 -0
  113. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/SKILL.md +0 -0
  114. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/command-map.md +0 -0
  115. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/common-analysis-patterns.md +0 -0
  116. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/install-rsdoctor-common.md +0 -0
  117. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/install-rsdoctor-rspack.md +0 -0
  118. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/install-rsdoctor-webpack.md +0 -0
  119. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/install-rsdoctor.md +0 -0
  120. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/rsdoctor-data-types.md +0 -0
  121. /package/template-workspace/{.agents → .codex}/skills/rslib-best-practices/SKILL.md +0 -0
  122. /package/template-workspace/{.agents → .codex}/skills/rslib-modern-package/SKILL.md +0 -0
  123. /package/template-workspace/{.agents → .codex}/skills/rspack-best-practices/SKILL.md +0 -0
  124. /package/template-workspace/{.agents → .codex}/skills/rspack-tracing/SKILL.md +0 -0
  125. /package/template-workspace/{.agents → .codex}/skills/rspack-tracing/references/bottlenecks.md +0 -0
  126. /package/template-workspace/{.agents → .codex}/skills/rspack-tracing/references/tracing-guide.md +0 -0
  127. /package/template-workspace/{.agents → .codex}/skills/rspack-tracing/scripts/analyze_trace.js +0 -0
  128. /package/template-workspace/{.agents → .codex}/skills/rstest-best-practices/SKILL.md +0 -0
@@ -37,6 +37,7 @@ var __webpack_require__ = {};
37
37
  var __webpack_exports__ = {};
38
38
  __webpack_require__.r(__webpack_exports__);
39
39
  __webpack_require__.d(__webpack_exports__, {
40
+ createCompactUltramodernConfig: ()=>createCompactUltramodernConfig,
40
41
  generateUltramodernWorkspace: ()=>generateUltramodernWorkspace,
41
42
  writeApp: ()=>writeApp,
42
43
  writeSharedPackages: ()=>writeSharedPackages
@@ -44,6 +45,7 @@ __webpack_require__.d(__webpack_exports__, {
44
45
  const external_node_fs_namespaceObject = require("node:fs");
45
46
  var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
46
47
  const external_app_files_cjs_namespaceObject = require("./app-files.cjs");
48
+ const external_bridge_config_cjs_namespaceObject = require("./bridge-config.cjs");
47
49
  const external_contracts_cjs_namespaceObject = require("./contracts.cjs");
48
50
  const external_demo_components_cjs_namespaceObject = require("./demo-components.cjs");
49
51
  const external_descriptors_cjs_namespaceObject = require("./descriptors.cjs");
@@ -59,16 +61,18 @@ const external_package_source_cjs_namespaceObject = require("./package-source.cj
59
61
  const external_public_surface_cjs_namespaceObject = require("./public-surface.cjs");
60
62
  const external_versions_cjs_namespaceObject = require("./versions.cjs");
61
63
  const external_workspace_scripts_cjs_namespaceObject = require("./workspace-scripts.cjs");
62
- function writeApp(targetDir, scope, app, packageSource, enableTailwind, remotes = []) {
64
+ function writeApp(targetDir, scope, app, packageSource, enableTailwind, remotes = [], bridge) {
63
65
  const resolvedApp = 'shell' === app.kind ? (0, external_descriptors_cjs_namespaceObject.createShellHost)(remotes) : app;
64
66
  const publicWeb = (0, external_public_surface_cjs_namespaceObject.createPublicWebAppArtifacts)(resolvedApp);
65
67
  const writeAppFile = (relativePath, content)=>{
66
68
  (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/${relativePath}`, content);
67
69
  };
68
- (0, external_fs_io_cjs_namespaceObject.writeJson)(targetDir, `${resolvedApp.directory}/package.json`, (0, external_package_json_cjs_namespaceObject.createAppPackage)(scope, resolvedApp, packageSource, enableTailwind, remotes));
70
+ (0, external_fs_io_cjs_namespaceObject.writeJson)(targetDir, `${resolvedApp.directory}/package.json`, (0, external_package_json_cjs_namespaceObject.createAppPackage)(scope, resolvedApp, packageSource, enableTailwind, remotes, bridge));
69
71
  (0, external_fs_io_cjs_namespaceObject.writeJson)(targetDir, `${resolvedApp.directory}/tsconfig.json`, (0, external_package_json_cjs_namespaceObject.createAppTsConfig)(resolvedApp, remotes));
72
+ (0, external_fs_io_cjs_namespaceObject.writeJson)(targetDir, `${resolvedApp.directory}/tsconfig.mf-types.json`, (0, external_package_json_cjs_namespaceObject.createAppMfTypesTsConfig)(resolvedApp));
70
73
  (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/src/modern-app-env.d.ts`, (0, external_app_files_cjs_namespaceObject.createAppEnvDts)(resolvedApp, remotes));
71
- (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/src/ultramodern-build.ts`, (0, external_module_federation_cjs_namespaceObject.createUltramodernBuildModule)(scope, resolvedApp));
74
+ (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/src/ultramodern-build.ts`, (0, external_module_federation_cjs_namespaceObject.createUltramodernBuildReexportModule)());
75
+ (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/shared/ultramodern-build.ts`, (0, external_module_federation_cjs_namespaceObject.createUltramodernBuildModule)(scope, resolvedApp));
72
76
  (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, publicWeb.jsonLdHelperFile.path, publicWeb.jsonLdHelperFile.content);
73
77
  (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, publicWeb.routeMetadataFile.path, publicWeb.routeMetadataFile.content);
74
78
  (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, publicWeb.routeHeadFile.path, publicWeb.routeHeadFile.content);
@@ -91,12 +95,12 @@ function writeApp(targetDir, scope, app, packageSource, enableTailwind, remotes
91
95
  if ('shell' === resolvedApp.kind) {
92
96
  writeAppFile('src/routes/vertical-components.tsx', (0, external_demo_components_cjs_namespaceObject.createShellRemoteComponents)(scope, remotes));
93
97
  writeAppFile('src/routes/shell-frame.tsx', (0, external_app_files_cjs_namespaceObject.createShellFrameComponent)());
94
- (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/src/effect/vertical-clients.ts`, (0, external_effect_api_cjs_namespaceObject.createShellEffectClient)(scope, remotes));
98
+ (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/src/api/vertical-clients.ts`, (0, external_effect_api_cjs_namespaceObject.createShellEffectClient)(scope, remotes));
95
99
  }
96
100
  if ((0, external_descriptors_cjs_namespaceObject.appHasEffectApi)(resolvedApp)) {
97
- (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/shared/effect/api.ts`, (0, external_effect_api_cjs_namespaceObject.createEffectSharedApi)(resolvedApp));
98
- (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/api/effect/index.ts`, (0, external_effect_api_cjs_namespaceObject.createEffectServiceEntry)(resolvedApp, '../../shared/effect/api.ts'));
99
- (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/src/effect/${resolvedApp.effectApi.stem}-client.ts`, (0, external_effect_api_cjs_namespaceObject.createEffectClient)(resolvedApp, '../../shared/effect/api'));
101
+ (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/shared/api.ts`, (0, external_effect_api_cjs_namespaceObject.createEffectSharedApi)(resolvedApp));
102
+ (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/api/index.ts`, (0, external_effect_api_cjs_namespaceObject.createEffectServiceEntry)(resolvedApp, '../shared/api.ts'));
103
+ (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/src/api/${resolvedApp.effectApi.stem}-client.ts`, (0, external_effect_api_cjs_namespaceObject.createEffectClient)(resolvedApp, '../../shared/api'));
100
104
  }
101
105
  if ('vertical' === resolvedApp.kind) {
102
106
  writeAppFile('src/federation-entry.tsx', (0, external_demo_components_cjs_namespaceObject.createRemoteEntry)(resolvedApp));
@@ -122,10 +126,36 @@ function writeSharedPackages(targetDir, scope) {
122
126
  `);
123
127
  (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, 'packages/shared-design-tokens/src/tokens.css', (0, external_app_files_cjs_namespaceObject.createSharedDesignTokensCss)());
124
128
  }
129
+ function createCompactRootPackageJson(scope, packageSource, remotes, bridge) {
130
+ const rootPackage = (0, external_package_json_cjs_namespaceObject.createRootPackageJson)(scope, packageSource, remotes, bridge);
131
+ if (rootPackage.modernjs?.packageSource && 'object' == typeof rootPackage.modernjs.packageSource) rootPackage.modernjs.packageSource.config = `./${external_descriptors_cjs_namespaceObject.ULTRAMODERN_CONFIG_PATH}`;
132
+ return rootPackage;
133
+ }
134
+ function createCompactUltramodernConfig(scope, modernVersion, packageSource, apps = [
135
+ (0, external_descriptors_cjs_namespaceObject.createShellHost)()
136
+ ], enableTailwind = true, bridge) {
137
+ const config = (0, external_contracts_cjs_namespaceObject.createUltramodernConfig)(scope, modernVersion, packageSource, apps, enableTailwind, bridge);
138
+ if (config.packageSource && 'object' == typeof config.packageSource && !Array.isArray(config.packageSource)) delete config.packageSource.metadata;
139
+ return config;
140
+ }
141
+ function writePnpmWorkspacePackages(targetDir, bridge) {
142
+ if (!bridge) return;
143
+ const pnpmWorkspacePath = `${targetDir}/pnpm-workspace.yaml`;
144
+ const pnpmWorkspace = external_node_fs_default().readFileSync(pnpmWorkspacePath, 'utf-8');
145
+ const packages = [
146
+ 'apps/*',
147
+ 'verticals/*',
148
+ 'packages/*',
149
+ ...bridge.workspacePackages.map((entry)=>entry.pattern)
150
+ ];
151
+ const renderedPackages = packages.map((pattern)=>` - ${pattern}`).join('\n');
152
+ (0, external_fs_io_cjs_namespaceObject.writeFileReplacing)(targetDir, 'pnpm-workspace.yaml', pnpmWorkspace.replace(/^packages:\n(?: {2}- .+\n)+/u, `packages:\n${renderedPackages}\n`));
153
+ }
125
154
  function generateUltramodernWorkspace(options) {
126
155
  const beforeFiles = (0, external_generation_result_cjs_namespaceObject.createFileSnapshot)(options.targetDir);
127
156
  const scope = (0, external_naming_cjs_namespaceObject.toPackageScope)(options.packageName);
128
157
  const packageSource = (0, external_package_source_cjs_namespaceObject.resolvePackageSource)(options);
158
+ const bridge = (0, external_bridge_config_cjs_namespaceObject.normalizeUltramodernBridgeConfig)(options.bridge);
129
159
  const enableTailwind = false !== options.enableTailwind;
130
160
  const initialVerticals = [];
131
161
  const createdApps = [
@@ -145,45 +175,58 @@ function generateUltramodernWorkspace(options) {
145
175
  nodeVersion: external_versions_cjs_namespaceObject.NODE_VERSION,
146
176
  pnpmVersion: external_versions_cjs_namespaceObject.PNPM_VERSION,
147
177
  nodeFetchVersion: external_versions_cjs_namespaceObject.NODE_FETCH_VERSION,
178
+ tanstackRouterCoreVersion: external_versions_cjs_namespaceObject.TANSTACK_ROUTER_CORE_VERSION,
148
179
  tanstackRouterVersion: external_versions_cjs_namespaceObject.TANSTACK_ROUTER_VERSION,
149
180
  typescriptVersion: external_versions_cjs_namespaceObject.TYPESCRIPT_VERSION,
150
181
  tailwindEnabled: String(enableTailwind)
151
182
  });
152
- (0, external_fs_io_cjs_namespaceObject.writeJson)(options.targetDir, 'package.json', (0, external_package_json_cjs_namespaceObject.createRootPackageJson)(scope, packageSource, initialVerticals));
183
+ writePnpmWorkspacePackages(options.targetDir, bridge);
184
+ (0, external_fs_io_cjs_namespaceObject.writeJson)(options.targetDir, 'package.json', createCompactRootPackageJson(scope, packageSource, initialVerticals, bridge));
153
185
  (0, external_fs_io_cjs_namespaceObject.writeJson)(options.targetDir, 'tsconfig.base.json', (0, external_package_json_cjs_namespaceObject.createTsConfigBase)());
154
186
  (0, external_fs_io_cjs_namespaceObject.writeJson)(options.targetDir, 'tsconfig.json', (0, external_package_json_cjs_namespaceObject.createRootTsConfig)(createdApps));
155
187
  (0, external_fs_io_cjs_namespaceObject.writeJson)(options.targetDir, 'topology/reference-topology.json', (0, external_contracts_cjs_namespaceObject.createTopology)(scope, initialVerticals));
156
188
  (0, external_fs_io_cjs_namespaceObject.writeJson)(options.targetDir, 'topology/ownership.json', (0, external_contracts_cjs_namespaceObject.createOwnership)(scope, initialVerticals));
157
189
  (0, external_fs_io_cjs_namespaceObject.writeJson)(options.targetDir, 'topology/local-overlays/development.json', (0, external_contracts_cjs_namespaceObject.createDevelopmentOverlay)(initialVerticals));
158
- (0, external_fs_io_cjs_namespaceObject.writeJson)(options.targetDir, '.modernjs/ultramodern-workspace-template-manifest.json', (0, external_contracts_cjs_namespaceObject.createTemplateManifest)(options.modernVersion, packageSource));
159
- (0, external_fs_io_cjs_namespaceObject.writeJson)(options.targetDir, '.modernjs/ultramodern-package-source.json', (0, external_contracts_cjs_namespaceObject.createPackageSourceMetadata)(scope, packageSource));
160
- (0, external_fs_io_cjs_namespaceObject.writeJson)(options.targetDir, external_descriptors_cjs_namespaceObject.GENERATED_CONTRACT_PATH, (0, external_contracts_cjs_namespaceObject.createGeneratedContract)(scope, createdApps, enableTailwind));
161
- writeApp(options.targetDir, scope, external_descriptors_cjs_namespaceObject.shellApp, packageSource, enableTailwind, initialVerticals);
162
- for (const remote of initialVerticals)writeApp(options.targetDir, scope, remote, packageSource, enableTailwind, initialVerticals);
190
+ (0, external_fs_io_cjs_namespaceObject.writeJson)(options.targetDir, external_descriptors_cjs_namespaceObject.ULTRAMODERN_CONFIG_PATH, createCompactUltramodernConfig(scope, options.modernVersion, packageSource, createdApps, enableTailwind, bridge));
191
+ writeApp(options.targetDir, scope, external_descriptors_cjs_namespaceObject.shellApp, packageSource, enableTailwind, initialVerticals, bridge);
192
+ for (const remote of initialVerticals)writeApp(options.targetDir, scope, remote, packageSource, enableTailwind, initialVerticals, bridge);
163
193
  writeSharedPackages(options.targetDir, scope);
164
194
  (0, external_workspace_scripts_cjs_namespaceObject.writeGeneratedWorkspaceScripts)(options.targetDir, scope, enableTailwind, initialVerticals);
165
- const afterFiles = (0, external_generation_result_cjs_namespaceObject.createFileSnapshot)(options.targetDir);
166
- const { createdPaths, rewrittenPaths } = (0, external_generation_result_cjs_namespaceObject.diffFileSnapshots)(beforeFiles, afterFiles);
167
- const result = (0, external_generation_result_cjs_namespaceObject.createGenerationResult)({
195
+ const preliminaryAfterFiles = (0, external_generation_result_cjs_namespaceObject.createFileSnapshot)(options.targetDir);
196
+ const preliminaryDiff = (0, external_generation_result_cjs_namespaceObject.diffFileSnapshots)(beforeFiles, preliminaryAfterFiles);
197
+ const preliminaryResult = (0, external_generation_result_cjs_namespaceObject.createGenerationResult)({
168
198
  operation: 'workspace',
169
199
  workspaceRoot: options.targetDir,
170
200
  packageScope: scope,
171
201
  packageSource,
172
202
  createdApps,
173
- createdPaths,
174
- rewrittenPaths
203
+ createdPaths: preliminaryDiff.createdPaths,
204
+ rewrittenPaths: preliminaryDiff.rewrittenPaths
175
205
  });
176
206
  (0, external_overlays_cjs_namespaceObject.runCodeSmithOverlays)({
177
207
  workspaceRoot: options.targetDir,
178
208
  overlays: options.overlays,
179
- result
209
+ result: preliminaryResult
210
+ });
211
+ (0, external_fs_io_cjs_namespaceObject.formatGeneratedWorkspaceFiles)(options.targetDir);
212
+ const afterFiles = (0, external_generation_result_cjs_namespaceObject.createFileSnapshot)(options.targetDir);
213
+ const { createdPaths, rewrittenPaths } = (0, external_generation_result_cjs_namespaceObject.diffFileSnapshots)(beforeFiles, afterFiles);
214
+ return (0, external_generation_result_cjs_namespaceObject.createGenerationResult)({
215
+ operation: 'workspace',
216
+ workspaceRoot: options.targetDir,
217
+ packageScope: scope,
218
+ packageSource,
219
+ createdApps,
220
+ createdPaths,
221
+ rewrittenPaths
180
222
  });
181
- return result;
182
223
  }
224
+ exports.createCompactUltramodernConfig = __webpack_exports__.createCompactUltramodernConfig;
183
225
  exports.generateUltramodernWorkspace = __webpack_exports__.generateUltramodernWorkspace;
184
226
  exports.writeApp = __webpack_exports__.writeApp;
185
227
  exports.writeSharedPackages = __webpack_exports__.writeSharedPackages;
186
228
  for(var __rspack_i in __webpack_exports__)if (-1 === [
229
+ "createCompactUltramodernConfig",
187
230
  "generateUltramodernWorkspace",
188
231
  "writeApp",
189
232
  "writeSharedPackages"
package/dist/esm/index.js CHANGED
@@ -6,7 +6,9 @@ import { fileURLToPath } from "node:url";
6
6
  import { resolveCreatePackageRoot } from "./create-package-root.js";
7
7
  import { i18n, localeKeys } from "./locale/index.js";
8
8
  import { BLEEDINGDEV_CREATE_PACKAGE, BLEEDINGDEV_FRAMEWORK_VERSION_ENV, BLEEDINGDEV_PACKAGE_NAME_PREFIX, BLEEDINGDEV_PACKAGE_SCOPE, WORKSPACE_PACKAGE_VERSION } from "./ultramodern-package-source.js";
9
+ import { runUltramodernToolingCli } from "./ultramodern-tooling/commands.js";
9
10
  import { addUltramodernVertical, generateUltramodernWorkspace, planUltramodernVertical } from "./ultramodern-workspace/index.js";
11
+ import { hasUltramodernBridgeCliOptions, parseUltramodernBridgeCliOptions, ultramodernBridgeCliBooleanFlags, ultramodernBridgeCliValueFlags } from "./ultramodern-workspace/bridge-config.js";
10
12
  const src_dirname = node_path.dirname(fileURLToPath(import.meta.url));
11
13
  const createPackageRoot = resolveCreatePackageRoot(src_dirname);
12
14
  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.-]+)?$/;
@@ -84,6 +86,16 @@ function showHelp() {
84
86
  console.log(i18n.t(localeKeys.help.optionUltramodernPackageRegistry));
85
87
  console.log(i18n.t(localeKeys.help.optionUltramodernPackageScope));
86
88
  console.log(i18n.t(localeKeys.help.optionUltramodernPackageNamePrefix));
89
+ console.log(i18n.t(localeKeys.help.optionBridge));
90
+ console.log(i18n.t(localeKeys.help.optionBridgeParentRoot));
91
+ console.log(i18n.t(localeKeys.help.optionBridgeWorkspacePackage));
92
+ console.log(i18n.t(localeKeys.help.optionBridgeWorkspacePackageName));
93
+ console.log(i18n.t(localeKeys.help.optionBridgeTestAlias));
94
+ console.log(i18n.t(localeKeys.help.optionBridgeDependency));
95
+ console.log(i18n.t(localeKeys.help.optionBridgeLockfilePolicy));
96
+ console.log(i18n.t(localeKeys.help.optionBridgeGate));
97
+ console.log(i18n.t(localeKeys.help.optionBridgeGateCwd));
98
+ console.log(i18n.t(localeKeys.help.optionBridgeReactSingleton));
87
99
  console.log(i18n.t(localeKeys.help.optionVertical));
88
100
  console.log(i18n.t(localeKeys.help.optionVerticalName));
89
101
  console.log(i18n.t(localeKeys.help.optionDryRun));
@@ -172,7 +184,7 @@ function detectBffRuntime(args) {
172
184
  process.exit(1);
173
185
  }
174
186
  if (!SUPPORTED_BFF_RUNTIMES.includes(runtime)) {
175
- console.error(`Unsupported BFF runtime "${runtime}". UltraModern workspaces scaffold an Effect BFF for every MicroVertical (supported: ${SUPPORTED_BFF_RUNTIMES.join(', ')}).`);
187
+ console.error(`Unsupported BFF runtime "${runtime}". UltraModern workspaces scaffold a strict Effect API runtime for every MicroVertical (supported: ${SUPPORTED_BFF_RUNTIMES.join(', ')}).`);
176
188
  process.exit(1);
177
189
  }
178
190
  return runtime;
@@ -197,7 +209,8 @@ function collectPositionalArgs(args) {
197
209
  '--ultramodern-package-scope',
198
210
  '--ultramodern-package-name-prefix',
199
211
  VERTICAL_NAME_FLAG,
200
- CODESMITH_OVERLAY_FLAG
212
+ CODESMITH_OVERLAY_FLAG,
213
+ ...ultramodernBridgeCliValueFlags
201
214
  ]);
202
215
  const optionWithoutValue = new Set([
203
216
  '--help',
@@ -210,7 +223,8 @@ function collectPositionalArgs(args) {
210
223
  WORKSPACE_PROTOCOL_FLAG,
211
224
  DRY_RUN_FLAG,
212
225
  VERTICAL_FLAG,
213
- LEGACY_MODERN_JS_FLAG
226
+ LEGACY_MODERN_JS_FLAG,
227
+ ...ultramodernBridgeCliBooleanFlags
214
228
  ]);
215
229
  const positionalArgs = [];
216
230
  for(let i = 0; i < args.length; i++){
@@ -220,7 +234,7 @@ function collectPositionalArgs(args) {
220
234
  i += 1;
221
235
  continue;
222
236
  }
223
- 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=') || arg.startsWith(`${VERTICAL_FLAG}=`) || arg.startsWith(`${VERTICAL_NAME_FLAG}=`) || arg.startsWith(`${CODESMITH_OVERLAY_FLAG}=`))) positionalArgs.push(arg);
237
+ 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=') || arg.startsWith(`${VERTICAL_FLAG}=`) || arg.startsWith(`${VERTICAL_NAME_FLAG}=`) || arg.startsWith(`${CODESMITH_OVERLAY_FLAG}=`) || ultramodernBridgeCliBooleanFlags.some((flag)=>arg.startsWith(`${flag}=`)) || ultramodernBridgeCliValueFlags.some((flag)=>arg.startsWith(`${flag}=`)))) positionalArgs.push(arg);
224
238
  }
225
239
  }
226
240
  return positionalArgs;
@@ -336,6 +350,14 @@ function detectCodeSmithOverlays(args) {
336
350
  }
337
351
  return overlays.length > 0 ? overlays : void 0;
338
352
  }
353
+ function readBridgeCliOptions(args) {
354
+ try {
355
+ return parseUltramodernBridgeCliOptions(args);
356
+ } catch (error) {
357
+ console.error(error instanceof Error ? error.message : String(error));
358
+ process.exit(1);
359
+ }
360
+ }
339
361
  function detectUltramodernPackageSource(args, defaultPackageVersion, createPackage) {
340
362
  const bleedingDevDefaults = isBleedingDevCreatePackage(createPackage);
341
363
  const strategy = getOptionValue(args, [
@@ -545,6 +567,10 @@ async function getProjectName() {
545
567
  }
546
568
  async function main() {
547
569
  const args = process.argv.slice(2);
570
+ if ('ultramodern' === args[0]) {
571
+ process.exitCode = await runUltramodernToolingCli(args.slice(1));
572
+ return;
573
+ }
548
574
  if (args.includes('--help') || args.includes('-h')) return void showHelp();
549
575
  if (args.includes('--version') || args.includes('-v')) return void showVersion();
550
576
  if (detectLegacyModernJsFlag(args)) {
@@ -556,10 +582,16 @@ async function main() {
556
582
  const dryRun = detectDryRunFlag(args);
557
583
  const verticalInput = resolveVerticalCliInput(args);
558
584
  const overlays = detectCodeSmithOverlays(args);
585
+ const bridgeRequested = hasUltramodernBridgeCliOptions(args);
559
586
  if (dryRun && !verticalInput.addVertical) {
560
587
  console.error(`${DRY_RUN_FLAG} is currently supported only with ${VERTICAL_FLAG}`);
561
588
  process.exit(1);
562
589
  }
590
+ if (verticalInput.addVertical && bridgeRequested) {
591
+ console.error('Bridge options are supported only when creating a new UltraModern workspace.');
592
+ process.exit(1);
593
+ }
594
+ const bridge = readBridgeCliOptions(args);
563
595
  if (!dryRun) console.log(`\n${i18n.t(localeKeys.message.welcome)}\n`);
564
596
  const createPackage = readCreatePackageJson();
565
597
  const version = createPackage.version || 'latest';
@@ -600,6 +632,7 @@ async function main() {
600
632
  packageName: generatedPackageName,
601
633
  modernVersion: version,
602
634
  enableTailwind: detectTailwindFlag(),
635
+ bridge,
603
636
  overlays,
604
637
  packageSource
605
638
  });
@@ -18,7 +18,7 @@ const EN_LOCALE = {
18
18
  step1: 'cd {projectName}',
19
19
  step2: 'pnpm install',
20
20
  step3: 'pnpm dev',
21
- legacyModernJsWarning: "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\nBRUTAL WARNING: YOU ARE OPTING OUT OF ULTRAMODERN.JS DEFAULTS.\nThe unattended default is the best UltraModern.js configuration:\na structured SuperApp workspace, presetUltramodern, TanStack Router,\nEffect BFF, Tailwind CSS v4, and the BleedingDev package cohort.\nThe original Modern.js setup is a dangerous opt-in path.\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
21
+ legacyModernJsWarning: "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\nBRUTAL WARNING: YOU ARE OPTING OUT OF ULTRAMODERN.JS DEFAULTS.\nThe unattended default is the best UltraModern.js configuration:\na structured SuperApp workspace, presetUltramodern, TanStack Router,\na strict Effect API runtime, Tailwind CSS v4, and the BleedingDev package cohort.\nThe original Modern.js setup is a dangerous opt-in path.\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
22
22
  },
23
23
  help: {
24
24
  title: '🚀 UltraModern.js Project Creator',
@@ -30,7 +30,7 @@ const EN_LOCALE = {
30
30
  optionVersion: ' -v, --version Display version information',
31
31
  optionLang: ' -l, --lang Set the language (en default; zh opt-in)',
32
32
  optionTailwind: ' --no-tailwind Disable default Tailwind CSS v4 workspace styling',
33
- optionBff: ' --bff Keep the default Effect BFF scaffolding (every MicroVertical ships an Effect BFF)',
33
+ optionBff: ' --bff Keep the default strict Effect API runtime (every MicroVertical ships one)',
34
34
  optionBffRuntime: ' --bff-runtime Select the BFF runtime for scaffolded MicroVerticals (supported: effect; default: effect)',
35
35
  optionWorkspace: ' --workspace Use workspace protocol for @modern-js dependencies (for local monorepo testing)',
36
36
  optionUltramodernPackageSource: ' --ultramodern-package-source Select UltraModern package source (workspace or install; BleedingDev defaults to install aliases)',
@@ -38,6 +38,16 @@ const EN_LOCALE = {
38
38
  optionUltramodernPackageRegistry: ' --ultramodern-package-registry npm registry URL used for install package sources',
39
39
  optionUltramodernPackageScope: ' --ultramodern-package-scope Publish scope for npm alias installs (for example bleedingdev)',
40
40
  optionUltramodernPackageNamePrefix: ' --ultramodern-package-name-prefix Prefix for npm alias package names (default: modern-js-)',
41
+ optionBridge: ' --bridge Enable explicit nested parent-monorepo bridge mode for new workspaces',
42
+ optionBridgeParentRoot: ' --bridge-parent-root <path> Parent monorepo root for bridge mode',
43
+ optionBridgeWorkspacePackage: ' --bridge-workspace-package <glob> Parent workspace package glob consumed by generated apps',
44
+ optionBridgeWorkspacePackageName: ' --bridge-workspace-package-name <glob=package[,package]> Package names covered by a bridge workspace glob',
45
+ optionBridgeTestAlias: ' --bridge-test-alias <glob:alias=target> Test/source alias for a bridge workspace package glob',
46
+ optionBridgeDependency: ' --bridge-dependency <package[,package]> Explicit parent package dependency consumed by generated apps',
47
+ optionBridgeLockfilePolicy: ' --bridge-lockfile-policy <nested|parent> Bridge lockfile ownership policy (default: nested)',
48
+ optionBridgeGate: ' --bridge-gate <name=command> Delegated parent workspace gate command for bridge packages',
49
+ optionBridgeGateCwd: ' --bridge-gate-cwd <name=cwd> Working directory for a named bridge gate',
50
+ optionBridgeReactSingleton: ' --bridge-react-singleton <package[,package]> React singleton package expectation (default: react,react-dom)',
41
51
  optionVertical: ' --vertical[=<name>] Mutate the current existing UltraModern workspace and wire a MicroVertical',
42
52
  optionVerticalName: ' --vertical-name <name> Explicit MicroVertical name for automation-friendly workspace mutation',
43
53
  optionDryRun: ' --dry-run Preview a MicroVertical mutation plan without writing files (supported with --vertical)',
@@ -18,7 +18,7 @@ const ZH_LOCALE = {
18
18
  step1: 'cd {projectName}',
19
19
  step2: 'pnpm install',
20
20
  step3: 'pnpm dev',
21
- legacyModernJsWarning: "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n严重警告:你正在退出 ULTRAMODERN.JS 默认配置。\n免交互默认值是最佳 UltraModern.js 配置:\n结构化 SuperApp 工作区、presetUltramodern、TanStack Router、\nEffect BFF、Tailwind CSS v4,以及 BleedingDev 包版本队列。\n原始 Modern.js 初始化是危险的显式选择路径。\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
21
+ legacyModernJsWarning: "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n严重警告:你正在退出 ULTRAMODERN.JS 默认配置。\n免交互默认值是最佳 UltraModern.js 配置:\n结构化 SuperApp 工作区、presetUltramodern、TanStack Router、\n严格 Effect API 运行时、Tailwind CSS v4,以及 BleedingDev 包版本队列。\n原始 Modern.js 初始化是危险的显式选择路径。\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
22
22
  },
23
23
  help: {
24
24
  title: '🚀 UltraModern.js 项目创建工具',
@@ -30,7 +30,7 @@ const ZH_LOCALE = {
30
30
  optionVersion: ' -v, --version 显示版本信息',
31
31
  optionLang: ' -l, --lang 设置语言 (默认 en;zh 需显式选择)',
32
32
  optionTailwind: ' --no-tailwind 禁用默认 Tailwind CSS v4 工作区样式',
33
- optionBff: ' --bff 保留默认的 Effect BFF 脚手架(每个 MicroVertical 自带 Effect BFF)',
33
+ optionBff: ' --bff 保留默认的严格 Effect API 运行时(每个 MicroVertical 自带一个)',
34
34
  optionBffRuntime: ' --bff-runtime 选择 MicroVertical 脚手架的 BFF 运行时(支持: effect;默认: effect)',
35
35
  optionWorkspace: ' --workspace 对 @modern-js 依赖使用 workspace 协议(用于本地 monorepo 联调)',
36
36
  optionUltramodernPackageSource: ' --ultramodern-package-source 选择 UltraModern 依赖来源(workspace 或 install;BleedingDev 默认使用 install alias)',
@@ -38,6 +38,16 @@ const ZH_LOCALE = {
38
38
  optionUltramodernPackageRegistry: ' --ultramodern-package-registry install 依赖来源使用的 npm registry 地址',
39
39
  optionUltramodernPackageScope: ' --ultramodern-package-scope npm alias 安装使用的发布 scope(例如 bleedingdev)',
40
40
  optionUltramodernPackageNamePrefix: ' --ultramodern-package-name-prefix npm alias 包名前缀(默认:modern-js-)',
41
+ optionBridge: ' --bridge 为新工作区启用显式的嵌套父 monorepo 桥接模式',
42
+ optionBridgeParentRoot: ' --bridge-parent-root <路径> 桥接模式使用的父 monorepo 根目录',
43
+ optionBridgeWorkspacePackage: ' --bridge-workspace-package <glob> 生成应用消费的父工作区包 glob',
44
+ optionBridgeWorkspacePackageName: ' --bridge-workspace-package-name <glob=包名[,包名]> 桥接工作区 glob 覆盖的包名',
45
+ optionBridgeTestAlias: ' --bridge-test-alias <glob:别名=目标> 桥接工作区包 glob 的测试/源码 alias',
46
+ optionBridgeDependency: ' --bridge-dependency <包名[,包名]> 生成应用显式消费的父包依赖',
47
+ optionBridgeLockfilePolicy: ' --bridge-lockfile-policy <nested|parent> 桥接 lockfile 归属策略(默认:nested)',
48
+ optionBridgeGate: ' --bridge-gate <名称=命令> 桥接包委托给父工作区执行的 gate 命令',
49
+ optionBridgeGateCwd: ' --bridge-gate-cwd <名称=目录> 指定桥接 gate 的工作目录',
50
+ optionBridgeReactSingleton: ' --bridge-react-singleton <包名[,包名]> React 单例包预期(默认:react,react-dom)',
41
51
  optionVertical: ' --vertical[=<名称>] 修改当前已有的 UltraModern 工作区,并接入 MicroVertical',
42
52
  optionVerticalName: ' --vertical-name <名称> 为自动化工作流显式指定 MicroVertical 名称',
43
53
  optionDryRun: ' --dry-run 预览 MicroVertical 修改计划但不写入文件(与 --vertical 一起使用)',
@@ -0,0 +1,132 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import node_fs from "node:fs";
3
+ import node_os from "node:os";
4
+ import node_path from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ import { resolveCreatePackageRoot } from "../create-package-root.js";
7
+ import { validateModuleFederationTypes } from "../ultramodern-workspace/mf-validation.js";
8
+ import { createWorkspaceValidationScript } from "../ultramodern-workspace/workspace-scripts.js";
9
+ import { readUltramodernConfig, workspaceAppsFromToolingConfig } from "./config.js";
10
+ const commands_dirname = node_path.dirname(fileURLToPath(import.meta.url));
11
+ const createPackageRoot = resolveCreatePackageRoot(commands_dirname);
12
+ function printHelp() {
13
+ process.stdout.write(`Usage:
14
+ modern-js-create ultramodern <command> [args]
15
+
16
+ Commands:
17
+ validate
18
+ typecheck
19
+ mf-types
20
+ public-surface
21
+ cloudflare-proof
22
+ performance-readiness
23
+ skills install
24
+ skills check
25
+ `);
26
+ }
27
+ function spawnNodeScript(relativeScriptPath, args, context, options = {}) {
28
+ const scriptPath = node_path.join(createPackageRoot, relativeScriptPath);
29
+ const result = spawnSync(process.execPath, [
30
+ scriptPath,
31
+ ...args
32
+ ], {
33
+ cwd: options.cwd ?? context.workspaceRoot,
34
+ env: {
35
+ ...process.env,
36
+ ULTRAMODERN_WORKSPACE_ROOT: context.workspaceRoot
37
+ },
38
+ stdio: 'inherit'
39
+ });
40
+ if (result.error) throw result.error;
41
+ return result.status ?? 1;
42
+ }
43
+ function runRenderedModule(source, context) {
44
+ const tempDir = node_fs.mkdtempSync(node_path.join(node_os.tmpdir(), 'ultramodern-tool-'));
45
+ const tempFile = node_path.join(tempDir, 'command.mjs');
46
+ try {
47
+ node_fs.writeFileSync(tempFile, source, 'utf-8');
48
+ const result = spawnSync(process.execPath, [
49
+ tempFile
50
+ ], {
51
+ cwd: context.workspaceRoot,
52
+ stdio: 'inherit'
53
+ });
54
+ if (result.error) throw result.error;
55
+ return result.status ?? 1;
56
+ } finally{
57
+ node_fs.rmSync(tempDir, {
58
+ force: true,
59
+ recursive: true
60
+ });
61
+ }
62
+ }
63
+ function runValidate(context) {
64
+ const config = readUltramodernConfig(context.workspaceRoot);
65
+ const apps = workspaceAppsFromToolingConfig(config);
66
+ const remotes = apps.filter((app)=>'shell' !== app.kind);
67
+ const source = createWorkspaceValidationScript(config.workspace.packageScope, config.features.tailwind, remotes);
68
+ return runRenderedModule(source, context);
69
+ }
70
+ function runMfTypes(args, context) {
71
+ if (args.includes('--help') || args.includes('-h')) {
72
+ process.stdout.write(`Usage:
73
+ modern-js-create ultramodern mf-types [app-dir...]
74
+
75
+ Checks real Module Federation config files and DTS archives for exposed apps.
76
+ `);
77
+ return 0;
78
+ }
79
+ validateModuleFederationTypes({
80
+ workspaceRoot: context.workspaceRoot,
81
+ appDirs: args.length > 0 ? args : void 0
82
+ });
83
+ return 0;
84
+ }
85
+ function runSkills(args, context) {
86
+ const [subcommand, ...rest] = args;
87
+ if ('install' === subcommand) return spawnNodeScript("template-workspace/scripts/bootstrap-agent-skills.mjs", rest, context);
88
+ if ('check' === subcommand) return spawnNodeScript("template-workspace/scripts/bootstrap-agent-skills.mjs", [
89
+ '--check',
90
+ ...rest
91
+ ], context);
92
+ throw new Error('Usage: modern-js-create ultramodern skills <install|check>');
93
+ }
94
+ async function runUltramodernToolingCli(args, workspaceRoot = process.env.ULTRAMODERN_WORKSPACE_ROOT ?? process.cwd()) {
95
+ try {
96
+ const [command, ...rest] = args;
97
+ const context = {
98
+ workspaceRoot: node_path.resolve(workspaceRoot),
99
+ invocationCwd: process.cwd()
100
+ };
101
+ switch(command){
102
+ case void 0:
103
+ case '--help':
104
+ case '-h':
105
+ printHelp();
106
+ return 0;
107
+ case 'validate':
108
+ return runValidate(context);
109
+ case 'typecheck':
110
+ return spawnNodeScript("templates/workspace-scripts/ultramodern-typecheck.mjs", rest, context, {
111
+ cwd: context.invocationCwd
112
+ });
113
+ case 'mf-types':
114
+ return runMfTypes(rest, context);
115
+ case 'public-surface':
116
+ return spawnNodeScript("templates/workspace-scripts/generate-public-surface-assets.mjs", rest, context);
117
+ case 'cloudflare-proof':
118
+ return spawnNodeScript("templates/workspace-scripts/proof-cloudflare-version.mjs", rest, context);
119
+ case 'performance-readiness':
120
+ return spawnNodeScript("templates/workspace-scripts/ultramodern-performance-readiness.mjs", rest, context);
121
+ case 'skills':
122
+ return runSkills(rest, context);
123
+ default:
124
+ throw new Error(`Unknown UltraModern command: ${command}`);
125
+ }
126
+ } catch (error) {
127
+ const message = error instanceof Error ? error.message : String(error);
128
+ process.stderr.write(`[ultramodern] ${message}\n`);
129
+ return 1;
130
+ }
131
+ }
132
+ export { runUltramodernToolingCli };
@@ -0,0 +1,120 @@
1
+ import node_fs from "node:fs";
2
+ import node_path from "node:path";
3
+ import { normalizeUltramodernBridgeConfig } from "../ultramodern-workspace/bridge-config.js";
4
+ import { ULTRAMODERN_CONFIG_PATH, createNeutralOwnership, shellApp } from "../ultramodern-workspace/descriptors.js";
5
+ import { toKebabCase } from "../ultramodern-workspace/naming.js";
6
+ function readJsonObject(filePath) {
7
+ const value = JSON.parse(node_fs.readFileSync(filePath, 'utf-8'));
8
+ if (null === value || 'object' != typeof value || Array.isArray(value)) throw new Error(`UltraModern config must contain a JSON object: ${filePath}`);
9
+ return value;
10
+ }
11
+ function readOptionalJsonObject(filePath) {
12
+ return node_fs.existsSync(filePath) ? readJsonObject(filePath) : {};
13
+ }
14
+ function packageScopeFromRoot(workspaceRoot1) {
15
+ const rootPackage = readOptionalJsonObject(node_path.join(workspaceRoot1, 'package.json'));
16
+ return 'string' == typeof rootPackage.name && rootPackage.name.length > 0 ? rootPackage.name : node_path.basename(workspaceRoot1);
17
+ }
18
+ function normalizeCompactConfig(sourcePath, config) {
19
+ const packageSource = config.packageSource && 'object' == typeof config.packageSource ? {
20
+ strategy: 'install' === config.packageSource.strategy ? 'install' : 'workspace',
21
+ modernPackageVersion: 'string' == typeof config.packageSource.modernPackageVersion ? config.packageSource.modernPackageVersion : 'workspace:*',
22
+ registry: 'string' == typeof config.packageSource.registry ? config.packageSource.registry : void 0,
23
+ aliasScope: 'string' == typeof config.packageSource.aliasScope ? config.packageSource.aliasScope : void 0,
24
+ aliasPackageNamePrefix: 'string' == typeof config.packageSource.aliasPackageNamePrefix ? config.packageSource.aliasPackageNamePrefix : void 0
25
+ } : void 0;
26
+ return {
27
+ schemaVersion: 'number' == typeof config.schemaVersion ? config.schemaVersion : 1,
28
+ profile: 'string' == typeof config.profile ? config.profile : void 0,
29
+ source: 'compact',
30
+ sourcePath,
31
+ workspace: {
32
+ packageScope: 'string' == typeof config.workspace?.packageScope ? config.workspace.packageScope : packageScopeFromRoot(workspaceRoot)
33
+ },
34
+ packageSource,
35
+ features: {
36
+ tailwind: config.features?.tailwind !== false
37
+ },
38
+ bridge: normalizeUltramodernBridgeConfig(config.bridge),
39
+ topology: {
40
+ apps: Array.isArray(config.topology?.apps) ? config.topology.apps.map((app)=>({
41
+ id: String(app.id),
42
+ kind: 'vertical' === app.kind ? 'vertical' : 'shell',
43
+ path: 'string' == typeof app.path ? app.path : '.',
44
+ package: 'string' == typeof app.package ? app.package : void 0,
45
+ packageSuffix: 'string' == typeof app.packageSuffix ? app.packageSuffix : void 0,
46
+ displayName: 'string' == typeof app.displayName ? app.displayName : void 0,
47
+ domain: 'string' == typeof app.domain ? app.domain : void 0,
48
+ port: 'number' == typeof app.port ? app.port : void 0,
49
+ portEnv: 'string' == typeof app.portEnv ? app.portEnv : void 0,
50
+ moduleFederation: app.moduleFederation && 'object' == typeof app.moduleFederation ? {
51
+ role: 'remote' === app.moduleFederation.role ? 'remote' : 'host',
52
+ name: 'string' == typeof app.moduleFederation.name ? app.moduleFederation.name : void 0,
53
+ exposes: Array.isArray(app.moduleFederation.exposes) ? app.moduleFederation.exposes.filter((expose)=>'string' == typeof expose) : void 0,
54
+ exposePaths: null === app.moduleFederation.exposePaths || 'object' != typeof app.moduleFederation.exposePaths || Array.isArray(app.moduleFederation.exposePaths) ? void 0 : Object.fromEntries(Object.entries(app.moduleFederation.exposePaths).filter((entry)=>'string' == typeof entry[0] && 'string' == typeof entry[1])),
55
+ verticalRefs: Array.isArray(app.moduleFederation.verticalRefs) ? app.moduleFederation.verticalRefs.filter((ref)=>'string' == typeof ref) : void 0,
56
+ hostOnly: true === app.moduleFederation.hostOnly,
57
+ noExposes: true === app.moduleFederation.noExposes
58
+ } : void 0,
59
+ effectApi: app.effectApi && 'object' == typeof app.effectApi ? {
60
+ stem: 'string' == typeof app.effectApi.stem ? app.effectApi.stem : String(app.id),
61
+ prefix: 'string' == typeof app.effectApi.prefix ? app.effectApi.prefix : `/${String(app.id)}-api`,
62
+ consumedBy: Array.isArray(app.effectApi.consumedBy) ? app.effectApi.consumedBy.filter((consumer)=>'string' == typeof consumer) : [
63
+ shellApp.id,
64
+ String(app.id)
65
+ ]
66
+ } : void 0
67
+ })) : []
68
+ }
69
+ };
70
+ }
71
+ function readUltramodernConfig(workspaceRoot1 = process.cwd()) {
72
+ const compactPath = node_path.join(workspaceRoot1, ULTRAMODERN_CONFIG_PATH);
73
+ if (node_fs.existsSync(compactPath)) return normalizeCompactConfig(compactPath, readJsonObject(compactPath));
74
+ throw new Error(`Missing UltraModern config. Expected ${ULTRAMODERN_CONFIG_PATH}.`);
75
+ }
76
+ function workspaceAppsFromToolingConfig(config) {
77
+ return config.topology.apps.map((app)=>{
78
+ if ('shell' === app.kind) return {
79
+ ...shellApp,
80
+ directory: app.path,
81
+ packageSuffix: app.packageSuffix ?? shellApp.packageSuffix,
82
+ displayName: app.displayName ?? shellApp.displayName,
83
+ port: app.port ?? shellApp.port,
84
+ portEnv: app.portEnv ?? shellApp.portEnv,
85
+ mfName: app.moduleFederation?.name ?? shellApp.mfName,
86
+ verticalRefs: app.moduleFederation?.verticalRefs ?? []
87
+ };
88
+ const domain = app.domain ?? app.id;
89
+ const packageSuffix = app.packageSuffix ?? domain;
90
+ const exposePaths = app.moduleFederation?.exposePaths ?? {};
91
+ const exposes = Object.fromEntries((app.moduleFederation?.exposes ?? []).map((expose)=>{
92
+ const configuredPath = exposePaths[expose];
93
+ const inferredPath = './Route' === expose ? './src/federation-entry.tsx' : './Widget' === expose ? `./src/components/${domain}-widget.tsx` : `./src/components/${toKebabCase(expose.replace(/^\.\//u, ''))}.tsx`;
94
+ return [
95
+ expose,
96
+ configuredPath ?? inferredPath
97
+ ];
98
+ }));
99
+ return {
100
+ id: app.id,
101
+ directory: app.path,
102
+ packageSuffix,
103
+ displayName: app.displayName ?? `${domain} Vertical`,
104
+ kind: 'vertical',
105
+ domain,
106
+ portEnv: app.portEnv ?? `VERTICAL_${domain.replace(/[^a-zA-Z0-9]+/g, '_').toUpperCase()}_PORT`,
107
+ port: app.port ?? 0,
108
+ mfName: app.moduleFederation?.name ?? app.id,
109
+ exposes,
110
+ ...app.moduleFederation?.verticalRefs ? {
111
+ verticalRefs: app.moduleFederation.verticalRefs
112
+ } : {},
113
+ ...app.effectApi ? {
114
+ effectApi: app.effectApi
115
+ } : {},
116
+ ownership: createNeutralOwnership(app.id)
117
+ };
118
+ });
119
+ }
120
+ export { readUltramodernConfig, workspaceAppsFromToolingConfig };