@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
@@ -9,16 +9,23 @@ function createAppModernConfig(scope, app) {
9
9
  const bffImport = appHasEffectApi(app) ? "import { bffPlugin } from '@modern-js/plugin-bff';\n" : '';
10
10
  const bffConfig = appHasEffectApi(app) ? ` bff: {
11
11
  effect: {
12
- entry: './api/effect/index',
12
+ entry: './api/index',
13
13
  openapi: {
14
14
  path: '/openapi.json',
15
15
  },
16
+ strictEffectApproach: true,
16
17
  },
17
18
  prefix: '${effectApiPrefix(app)}',
18
19
  runtimeFramework: 'effect',
19
20
  },
20
21
  ` : '';
21
22
  const bffPluginEntry = appHasEffectApi(app) ? ' bffPlugin(),\n' : '';
23
+ const defaultAssetPrefixSource = 'shell' === app.kind ? "const defaultAssetPrefix = '/';" : `const remoteAssetOrigin =
24
+ configuredCloudflareUrl ||
25
+ inferredCloudflareUrl ||
26
+ (cloudflareDeployEnabled ? '/' : \`http://localhost:\${port}\`);
27
+ const defaultRemoteAssetPrefix = \`\${remoteAssetOrigin.replace(/\\/+$/u, '')}/\`;
28
+ const defaultAssetPrefix = defaultRemoteAssetPrefix;`;
22
29
  return `// @effect-diagnostics processEnv:off
23
30
  import {
24
31
  appTools,
@@ -65,6 +72,8 @@ const configuredSiteUrl = envValue('MODERN_PUBLIC_SITE_URL');
65
72
  const configuredCloudflareUrl = envValue('${createCloudflarePublicUrlEnv(app)}');
66
73
  const configuredUltramodernAssetPrefix = envValue('ULTRAMODERN_ASSET_PREFIX');
67
74
  const configuredModernAssetPrefix = envValue('MODERN_ASSET_PREFIX');
75
+ const moduleFederationDevServerOrigin =
76
+ envValue('ULTRAMODERN_MF_DEV_ORIGIN') || 'http://localhost:${shellApp.port}';
68
77
  const cloudflareWorkersDevSubdomain = envValue(
69
78
  'ULTRAMODERN_CLOUDFLARE_WORKERS_DEV_SUBDOMAIN',
70
79
  );
@@ -79,12 +88,12 @@ const siteUrl =
79
88
  configuredCloudflareUrl ||
80
89
  inferredCloudflareUrl ||
81
90
  \`http://localhost:\${port}\`;
82
- // Asset loading is intentionally independent from the canonical site URL and
83
- // deployment public URL. Without an explicit asset prefix, assets stay
84
- // origin-relative so self-hosted apps, tunnels, and reverse proxies never leak
85
- // localhost URLs into production HTML.
91
+ ${defaultAssetPrefixSource}
92
+ // Asset loading is intentionally independent from the canonical site URL.
93
+ // Module Federation remotes must publish an absolute publicPath so browsers
94
+ // load remoteEntry.js and exposed chunks from the remote origin, not the host.
86
95
  const assetPrefix =
87
- configuredModernAssetPrefix || configuredUltramodernAssetPrefix || '/';
96
+ configuredModernAssetPrefix || configuredUltramodernAssetPrefix || defaultAssetPrefix;
88
97
 
89
98
  if (
90
99
  cloudflareDeployEnabled &&
@@ -188,6 +197,9 @@ ${bffPluginEntry} moduleFederationPlugin(),
188
197
  },
189
198
  mainEntryName: 'index',
190
199
  },
200
+ splitChunks: {
201
+ chunks: 'async',
202
+ },
191
203
  tools: {
192
204
  autoprefixer: {
193
205
  overrideBrowserslist: ['defaults'],
@@ -196,12 +208,14 @@ ${bffPluginEntry} moduleFederationPlugin(),
196
208
  chain.output
197
209
  .uniqueName('${createRspackUniqueName(app)}')
198
210
  .chunkLoadingGlobal('${createRspackChunkLoadingGlobal(app)}');
199
- chain.ignoreWarnings([
200
- {
201
- message: /the request of a dependency is an expression/u,
202
- module: /modern-js-plugin-i18n/u,
203
- },
204
- ]);
211
+ },
212
+ devServer: {
213
+ headers: {
214
+ 'Access-Control-Allow-Headers':
215
+ 'Accept, Authorization, Content-Type, X-Requested-With',
216
+ 'Access-Control-Allow-Methods': 'GET, HEAD, OPTIONS',
217
+ 'Access-Control-Allow-Origin': moduleFederationDevServerOrigin,
218
+ },
205
219
  },
206
220
  },
207
221
  },
@@ -223,11 +237,6 @@ function createSharedModuleFederationConfig() {
223
237
  singleton: true,
224
238
  treeShaking: false,
225
239
  },
226
- '@modern-js/plugin-i18n/runtime': {
227
- requiredVersion: pluginI18nVersion,
228
- singleton: true,
229
- treeShaking: false,
230
- },
231
240
  '@modern-js/plugin-tanstack/runtime': {
232
241
  requiredVersion: pluginTanstackVersion,
233
242
  singleton: true,
@@ -331,6 +340,7 @@ function createShellModuleFederationConfig(scope, remotes = []) {
331
340
  verticalRefs: remotes.map((remote)=>remote.id)
332
341
  };
333
342
  return `// @effect-diagnostics nodeBuiltinImport:off processEnv:off
343
+ // ultramodern-mf: host-only
334
344
  import { createRequire } from 'node:module';
335
345
  import { createModuleFederationConfig } from '@module-federation/modern-js-v3';
336
346
  import { dependencies } from './package.json';
@@ -343,7 +353,9 @@ const reactVersion = (require('react/package.json') as { version: string }).vers
343
353
  const reactDomVersion = (require('react-dom/package.json') as { version: string }).version;
344
354
 
345
355
  ${createModuleFederationRemoteUrlHelpers(shellHost, remotes)}
346
- export default createModuleFederationConfig({
356
+ const moduleFederationConfig: Parameters<
357
+ typeof createModuleFederationConfig
358
+ >[0] = createModuleFederationConfig({
347
359
  bridge: {
348
360
  enableBridgeRouter: false,
349
361
  },
@@ -355,12 +367,15 @@ export default createModuleFederationConfig({
355
367
  generateTypes: {
356
368
  compilerInstance: 'tsgo',
357
369
  },
370
+ tsConfigPath: './tsconfig.mf-types.json',
358
371
  },
359
372
  filename: 'remoteEntry.js',
360
373
  name: '${shellApp.mfName}',
361
374
  ${createModuleFederationRemotesConfig(scope, shellHost, remotes)}${createSharedModuleFederationConfig()},
362
375
  treeShakingSharedExcludePlugins: ['RspackModuleFederationPlugin'],
363
376
  });
377
+
378
+ export default moduleFederationConfig;
364
379
  `;
365
380
  }
366
381
  function createBuildMarker(scope, app) {
@@ -382,10 +397,18 @@ export const ultramodernUiMarker = {
382
397
 
383
398
  export const ultramodernApiMarker = {
384
399
  ...ultramodernVerticalIdentity,
385
- surface: 'effect-bff',
400
+ surface: 'api',
386
401
  } as const;
387
402
  `;
388
403
  }
404
+ function createUltramodernBuildReexportModule() {
405
+ return `export {
406
+ ultramodernApiMarker,
407
+ ultramodernUiMarker,
408
+ ultramodernVerticalIdentity,
409
+ } from '../shared/ultramodern-build';
410
+ `;
411
+ }
389
412
  function createRemoteModuleFederationConfig(scope, app, remotes = []) {
390
413
  const exposes = formatTsObjectLiteral(app.exposes ?? {});
391
414
  return `// @effect-diagnostics nodeBuiltinImport:off
@@ -401,7 +424,9 @@ const reactVersion = (require('react/package.json') as { version: string }).vers
401
424
  const reactDomVersion = (require('react-dom/package.json') as { version: string }).version;
402
425
 
403
426
  ${createModuleFederationRemoteUrlHelpers(app, remotes)}
404
- export default createModuleFederationConfig({
427
+ const moduleFederationConfig: Parameters<
428
+ typeof createModuleFederationConfig
429
+ >[0] = createModuleFederationConfig({
405
430
  bridge: {
406
431
  enableBridgeRouter: false,
407
432
  },
@@ -413,6 +438,7 @@ export default createModuleFederationConfig({
413
438
  generateTypes: {
414
439
  compilerInstance: 'tsgo',
415
440
  },
441
+ tsConfigPath: './tsconfig.mf-types.json',
416
442
  },
417
443
  exposes: ${exposes},
418
444
  filename: 'remoteEntry.js',
@@ -420,6 +446,8 @@ export default createModuleFederationConfig({
420
446
  ${createModuleFederationRemotesConfig(scope, app, remotes)}${createSharedModuleFederationConfig()},
421
447
  treeShakingSharedExcludePlugins: ['RspackModuleFederationPlugin'],
422
448
  });
449
+
450
+ export default moduleFederationConfig;
423
451
  `;
424
452
  }
425
- export { createAppModernConfig, createBuildMarker, createModuleFederationRemoteUrlHelpers, createModuleFederationRemotesConfig, createRemoteModuleFederationConfig, createSharedModuleFederationConfig, createShellModuleFederationConfig, createUltramodernBuildModule, formatTsObjectLiteral };
453
+ export { createAppModernConfig, createBuildMarker, createModuleFederationRemoteUrlHelpers, createModuleFederationRemotesConfig, createRemoteModuleFederationConfig, createSharedModuleFederationConfig, createShellModuleFederationConfig, createUltramodernBuildModule, createUltramodernBuildReexportModule, formatTsObjectLiteral };
@@ -81,7 +81,7 @@ const effectDiagnostics = [
81
81
  'unnecessaryPipe',
82
82
  'unnecessaryPipeChain'
83
83
  ];
84
- function appDependencies(scope, packageSource, app, remotes = []) {
84
+ function appDependencies(scope, packageSource, app, remotes = [], bridge) {
85
85
  const dependencies = {
86
86
  '@modern-js/plugin-tanstack': modernPackageSpecifier('@modern-js/plugin-tanstack', packageSource),
87
87
  '@modern-js/plugin-i18n': modernPackageSpecifier('@modern-js/plugin-i18n', packageSource),
@@ -96,8 +96,10 @@ function appDependencies(scope, packageSource, app, remotes = []) {
96
96
  [packageName(scope, 'shared-design-tokens')]: WORKSPACE_PACKAGE_VERSION,
97
97
  react: REACT_VERSION,
98
98
  'react-dom': REACT_DOM_VERSION,
99
- 'react-router': REACT_ROUTER_VERSION
99
+ 'react-router': REACT_ROUTER_VERSION,
100
+ 'react-router-dom': REACT_ROUTER_VERSION
100
101
  };
102
+ for (const dependency of bridge?.dependencies ?? [])dependencies[dependency] = WORKSPACE_PACKAGE_VERSION;
101
103
  if ('shell' === app.kind) {
102
104
  dependencies['@modern-js/plugin-bff'] = modernPackageSpecifier('@modern-js/plugin-bff', packageSource);
103
105
  for (const remote of verticalEffectApps(remotes))dependencies[packageName(scope, remote.packageSuffix)] = WORKSPACE_PACKAGE_VERSION;
@@ -124,12 +126,28 @@ function appDevDependencies(packageSource, enableTailwind) {
124
126
  wrangler: WRANGLER_VERSION
125
127
  };
126
128
  }
127
- function createRootPackageJson(scope, packageSource, remotes = []) {
129
+ function createRootPackageJson(scope, packageSource, remotes = [], bridge) {
128
130
  const shellFilter = `--filter ${packageName(scope, shellApp.packageSuffix)}`;
129
131
  const remoteFilters = remotes.map((remote)=>`--filter ${packageName(scope, remote.packageSuffix)}`);
130
132
  const remoteBuildPrefix = remotes.length > 0 ? 'ULTRAMODERN_ZEPHYR=false pnpm -r --filter "./verticals/*" run build && ' : '';
131
133
  const remoteCloudflareBuildPrefix = remotes.length > 0 ? 'pnpm -r --filter "./verticals/*" run cloudflare:build && ' : '';
132
134
  const remoteCloudflareDeployPrefix = remotes.length > 0 ? 'pnpm -r --filter "./verticals/*" run cloudflare:deploy && ' : '';
135
+ const generatedPackageTypecheck = 'pnpm -r --filter "./apps/*" --filter "./verticals/*" --filter "./packages/*" run typecheck';
136
+ const typecheck = bridge ? generatedPackageTypecheck : "node ./scripts/ultramodern-typecheck.mjs --build tsconfig.json";
137
+ const bridgeScripts = bridge ? {
138
+ ...Object.fromEntries(bridge.gates.map((gate)=>[
139
+ `bridge:${gate.name}`,
140
+ `${gate.cwd ? `cd ${gate.cwd} && ` : ''}${gate.command}`
141
+ ])),
142
+ 'bridge:check': bridge.gates.map((gate)=>`pnpm run bridge:${gate.name}`).join(' && ')
143
+ } : {};
144
+ const bridgeCheck = bridge ? ' && pnpm bridge:check' : '';
145
+ const workspacePackages = [
146
+ 'apps/*',
147
+ 'verticals/*',
148
+ 'packages/*',
149
+ ...bridge?.workspacePackages.map((entry)=>entry.pattern) ?? []
150
+ ];
133
151
  return {
134
152
  private: true,
135
153
  name: scope,
@@ -151,7 +169,7 @@ function createRootPackageJson(scope, packageSource, remotes = []) {
151
169
  'format:check': "oxfmt --check . '!repos/**'",
152
170
  lint: 'oxlint apps verticals packages',
153
171
  'lint:fix': 'oxlint apps verticals packages --fix',
154
- typecheck: "node ./scripts/ultramodern-typecheck.mjs --build tsconfig.json",
172
+ typecheck,
155
173
  'cloudflare:build': `${remoteCloudflareBuildPrefix}pnpm --filter "./apps/shell-super-app" run cloudflare:build && pnpm mf:types`,
156
174
  'cloudflare:deploy': `${remoteCloudflareDeployPrefix}pnpm --filter "./apps/shell-super-app" run cloudflare:deploy`,
157
175
  'cloudflare:proof': "node ./scripts/proof-cloudflare-version.mjs --out .codex/reports/cloudflare-version-proof/public-url-proof.json",
@@ -162,19 +180,17 @@ function createRootPackageJson(scope, packageSource, remotes = []) {
162
180
  'mf:types': "node ./scripts/assert-mf-types.mjs",
163
181
  'performance:readiness': "node ./scripts/ultramodern-performance-readiness.mjs",
164
182
  'contract:check': "node ./scripts/validate-ultramodern-workspace.mjs",
183
+ 'api:check': "node ./scripts/check-ultramodern-api-boundaries.mjs",
165
184
  'i18n:boundaries': "node ./scripts/check-ultramodern-i18n-boundaries.mjs",
185
+ ...bridgeScripts,
166
186
  postinstall: "oxfmt . '!repos/**' && node ./scripts/bootstrap-agent-skills.mjs --postinstall",
167
- check: 'pnpm format:check && pnpm lint && pnpm typecheck && pnpm skills:check && pnpm i18n:boundaries && pnpm contract:check && pnpm performance:readiness'
187
+ check: `pnpm format:check && pnpm lint && pnpm typecheck && pnpm skills:check && pnpm i18n:boundaries && pnpm api:check && pnpm contract:check && pnpm performance:readiness${bridgeCheck}`
168
188
  },
169
189
  engines: {
170
190
  node: '>=26',
171
191
  pnpm: '>=11'
172
192
  },
173
- workspaces: [
174
- 'apps/*',
175
- 'verticals/*',
176
- 'packages/*'
177
- ],
193
+ workspaces: workspacePackages,
178
194
  modernjs: {
179
195
  preset: 'presetUltramodern',
180
196
  workspace: 'ultramodern-superapp',
@@ -182,7 +198,7 @@ function createRootPackageJson(scope, packageSource, remotes = []) {
182
198
  ownership: './topology/ownership.json',
183
199
  packageSource: {
184
200
  strategy: packageSource.strategy,
185
- config: './.modernjs/ultramodern-package-source.json'
201
+ config: './.modernjs/ultramodern.json#packageSource'
186
202
  }
187
203
  },
188
204
  devDependencies: {
@@ -256,6 +272,10 @@ function createTsBuildInfoFile(packageDir) {
256
272
  const cacheKey = packageDir.replace(/[^a-zA-Z0-9._-]+/gu, '__');
257
273
  return `${relativeRootFor(packageDir)}/node_modules/.cache/tsgo/${cacheKey}.tsbuildinfo`;
258
274
  }
275
+ function createTsDeclarationOutDir(packageDir) {
276
+ const cacheKey = packageDir.replace(/[^a-zA-Z0-9._-]+/gu, '__');
277
+ return `${relativeRootFor(packageDir)}/node_modules/.cache/tsgo/declarations/${cacheKey}`;
278
+ }
259
279
  function createReferences(packageDir, references) {
260
280
  return [
261
281
  ...new Set(references)
@@ -269,16 +289,24 @@ function createPackageTsConfig(packageDir, options = {}) {
269
289
  } : options;
270
290
  const include = resolvedOptions.include ?? [
271
291
  'src',
292
+ 'locales/**/*.json',
272
293
  'modern.config.ts',
273
- 'module-federation.config.ts'
294
+ 'module-federation.config.ts',
295
+ 'package.json',
296
+ 'shared'
274
297
  ];
275
- if (resolvedOptions.includeApi) include.push('api', 'shared');
298
+ if (resolvedOptions.includeApi) include.push('api');
276
299
  const references = createReferences(packageDir, resolvedOptions.references ?? []);
277
300
  const tsconfig = {
278
301
  extends: `${relativeRootFor(packageDir)}/tsconfig.base.json`,
279
302
  compilerOptions: {
280
303
  composite: true,
304
+ declaration: true,
305
+ declarationMap: false,
306
+ emitDeclarationOnly: true,
281
307
  incremental: true,
308
+ noEmit: false,
309
+ outDir: createTsDeclarationOutDir(packageDir),
282
310
  tsBuildInfoFile: createTsBuildInfoFile(packageDir)
283
311
  },
284
312
  include
@@ -296,6 +324,18 @@ function createAppTsConfig(app, remotes = []) {
296
324
  references
297
325
  });
298
326
  }
327
+ function createAppMfTypesTsConfig(app) {
328
+ const exposedFiles = Object.values(app.exposes ?? {}).map((exposePath)=>exposePath.replace(/^\.\//u, ''));
329
+ return {
330
+ extends: './tsconfig.json',
331
+ include: [
332
+ ...new Set([
333
+ ...exposedFiles,
334
+ 'src/modern-app-env.d.ts'
335
+ ])
336
+ ]
337
+ };
338
+ }
299
339
  function createSharedPackageTsConfig(packageDir) {
300
340
  return createPackageTsConfig(packageDir, {
301
341
  include: [
@@ -316,7 +356,7 @@ function createRootTsConfig(apps = []) {
316
356
  ]
317
357
  };
318
358
  }
319
- function createAppPackage(scope, app, packageSource, enableTailwind, remotes = []) {
359
+ function createAppPackage(scope, app, packageSource, enableTailwind, remotes = [], bridge) {
320
360
  const publicSurfaceBuildCommand = createPublicSurfaceGenerationCommand(app, 'dist');
321
361
  const publicSurfaceCloudflareBuildCommand = createPublicSurfaceGenerationCommand(app, 'dist');
322
362
  const publicSurfaceCloudflareOutputCommand = createPublicSurfaceGenerationCommand(app, 'cloudflare');
@@ -344,19 +384,19 @@ function createAppPackage(scope, app, packageSource, enableTailwind, remotes = [
344
384
  appId: app.id,
345
385
  topology: `${relativeRootFor(app.directory)}/topology/reference-topology.json`,
346
386
  ...appHasEffectApi(app) ? {
347
- apiRuntime: 'effect-bff'
387
+ apiRuntime: 'effect'
348
388
  } : {}
349
389
  },
350
390
  'zephyr:dependencies': createZephyrDependencies(scope, app, remotes),
351
- dependencies: appDependencies(scope, packageSource, app, remotes),
391
+ dependencies: appDependencies(scope, packageSource, app, remotes, bridge),
352
392
  devDependencies: appDevDependencies(packageSource, enableTailwind)
353
393
  };
354
394
  if (appHasEffectApi(app)) Object.assign(packageExports, {
355
- './effect/client': `./src/effect/${app.effectApi.stem}-client.ts`,
356
- './shared/effect/api': './shared/effect/api.ts'
395
+ './api': './shared/api.ts',
396
+ './api/client': `./src/api/${app.effectApi.stem}-client.ts`
357
397
  });
358
398
  else if ('shell' === app.kind) Object.assign(packageExports, {
359
- './effect/clients': './src/effect/vertical-clients.ts'
399
+ './api/clients': './src/api/vertical-clients.ts'
360
400
  });
361
401
  if (Object.keys(packageExports).length > 0) packageJson.exports = packageExports;
362
402
  return packageJson;
@@ -388,4 +428,4 @@ function createSharedPackage(scope, id, description) {
388
428
  function createSharedContractsIndex() {
389
429
  return readFileTemplate('packages/shared-contracts-index.ts');
390
430
  }
391
- export { appDependencies, appDevDependencies, createAppPackage, createAppTsConfig, createEffectTsgoTypecheckCommand, createPackageTsConfig, createRootPackageJson, createRootTsConfig, createSharedContractsIndex, createSharedPackage, createSharedPackageTsConfig, createTsConfigBase, createZephyrDependencies, effectDiagnostics };
431
+ export { appDependencies, appDevDependencies, createAppMfTypesTsConfig, createAppPackage, createAppTsConfig, createEffectTsgoTypecheckCommand, createPackageTsConfig, createRootPackageJson, createRootTsConfig, createSharedContractsIndex, createSharedPackage, createSharedPackageTsConfig, createTsConfigBase, createZephyrDependencies, effectDiagnostics };
@@ -17,7 +17,7 @@ function createCloudflareProofRoute(app) {
17
17
  mfManifest: '/mf-manifest.json',
18
18
  locale: `/locales/en/${appI18nNamespace(app)}.json`,
19
19
  ...appHasEffectApi(app) ? {
20
- effectReadiness: `${effectApiPrefix(app)}/effect/${effectApiStem(app)}/readiness`
20
+ apiReadiness: `${effectApiPrefix(app)}/${effectApiStem(app)}/readiness`
21
21
  } : {}
22
22
  };
23
23
  }
@@ -108,7 +108,7 @@ const PUBLIC_WEBSITE_POLICY = {
108
108
  requireWebManifestWhenPresent: true
109
109
  },
110
110
  statusCodes: {
111
- notFoundRoute: '/__ultramodern-smoke-missing',
111
+ notFoundRoute: '/__ultramodern-smoke-missing/nope',
112
112
  unknownRouteStatus: 404
113
113
  },
114
114
  indexing: {
@@ -1,3 +1,4 @@
1
1
  import "node:module";
2
2
  export { addUltramodernVertical, planUltramodernVertical } from "./add-vertical.js";
3
+ export { normalizeUltramodernBridgeConfig } from "./bridge-config.js";
3
4
  export { generateUltramodernWorkspace } from "./write-workspace.js";
@@ -1,5 +1,6 @@
1
1
  import "node:module";
2
2
  const TANSTACK_ROUTER_VERSION = '1.170.16';
3
+ const TANSTACK_ROUTER_CORE_VERSION = '1.171.13';
3
4
  const MODULE_FEDERATION_VERSION = '2.6.0';
4
5
  const ZEPHYR_RSPACK_PLUGIN_VERSION = '1.1.1';
5
6
  const ZEPHYR_AGENT_VERSION = '1.1.1';
@@ -29,8 +30,9 @@ const RSTACK_AGENT_SKILLS_COMMIT = '61c948b42512e223bad44b83af4080eba48b2677';
29
30
  const MODULE_FEDERATION_AGENT_SKILLS_COMMIT = '07bb5b6c43ad457609e00c081b72d4c42508ec76';
30
31
  const ultramodernWorkspaceVersions = {
31
32
  tanstackRouter: TANSTACK_ROUTER_VERSION,
33
+ tanstackRouterCore: TANSTACK_ROUTER_CORE_VERSION,
32
34
  moduleFederation: MODULE_FEDERATION_VERSION,
33
35
  tailwind: TAILWIND_VERSION,
34
36
  tailwindPostcss: TAILWIND_POSTCSS_VERSION
35
37
  };
36
- export { CLOUDFLARE_COMPATIBILITY_DATE, EFFECT_TSGO_VERSION, I18NEXT_VERSION, LEFTHOOK_VERSION, MODULE_FEDERATION_AGENT_SKILLS_COMMIT, MODULE_FEDERATION_VERSION, NODE_FETCH_VERSION, NODE_VERSION, OXFMT_VERSION, OXLINT_VERSION, PNPM_VERSION, POSTCSS_VERSION, REACT_DOM_VERSION, REACT_ROUTER_VERSION, REACT_VERSION, RSTACK_AGENT_SKILLS_COMMIT, TAILWIND_POSTCSS_VERSION, TAILWIND_VERSION, TANSTACK_ROUTER_VERSION, TYPESCRIPT_NATIVE_PREVIEW_VERSION, TYPESCRIPT_STABLE_VERSION, TYPESCRIPT_VERSION, TYPES_REACT_DOM_VERSION, TYPES_REACT_VERSION, ULTRACITE_VERSION, WRANGLER_VERSION, ZEPHYR_AGENT_VERSION, ZEPHYR_RSPACK_PLUGIN_VERSION, ultramodernWorkspaceVersions };
38
+ export { CLOUDFLARE_COMPATIBILITY_DATE, EFFECT_TSGO_VERSION, I18NEXT_VERSION, LEFTHOOK_VERSION, MODULE_FEDERATION_AGENT_SKILLS_COMMIT, MODULE_FEDERATION_VERSION, NODE_FETCH_VERSION, NODE_VERSION, OXFMT_VERSION, OXLINT_VERSION, PNPM_VERSION, POSTCSS_VERSION, REACT_DOM_VERSION, REACT_ROUTER_VERSION, REACT_VERSION, RSTACK_AGENT_SKILLS_COMMIT, TAILWIND_POSTCSS_VERSION, TAILWIND_VERSION, TANSTACK_ROUTER_CORE_VERSION, TANSTACK_ROUTER_VERSION, TYPESCRIPT_NATIVE_PREVIEW_VERSION, TYPESCRIPT_STABLE_VERSION, TYPESCRIPT_VERSION, TYPES_REACT_DOM_VERSION, TYPES_REACT_VERSION, ULTRACITE_VERSION, WRANGLER_VERSION, ZEPHYR_AGENT_VERSION, ZEPHYR_RSPACK_PLUGIN_VERSION, ultramodernWorkspaceVersions };
@@ -8,10 +8,73 @@ import { createCloudflareSecurityContract } from "./policy.js";
8
8
  import { publicSurfaceManagedSourceAssetPaths } from "./public-surface.js";
9
9
  import { createLocalisedUrlsMap, createRouteMetaFilePath, createRouteOwnedI18nPaths, createRoutePageFilePath } from "./routes.js";
10
10
  import { CLOUDFLARE_COMPATIBILITY_DATE, NODE_VERSION, PNPM_VERSION } from "./versions.js";
11
- function createAssertMfTypesScript(remotes = []) {
12
- return renderFileTemplate("workspace-scripts/assert-mf-types.mjs", {
13
- defaultAppDirsJson: JSON.stringify(remotes.map((remote)=>remote.directory), null, 2)
11
+ function createToolWrapperScript(command, extraArgs = []) {
12
+ const commandJson = JSON.stringify(command);
13
+ const extraArgsJson = JSON.stringify(extraArgs);
14
+ return `#!/usr/bin/env node
15
+ import { spawnSync } from 'node:child_process';
16
+ import path from 'node:path';
17
+ import { fileURLToPath } from 'node:url';
18
+
19
+ const createBin = process.env.ULTRAMODERN_CREATE_BIN;
20
+ const forwardedArgs = process.argv.slice(2);
21
+ const workspaceRoot =
22
+ process.env.ULTRAMODERN_WORKSPACE_ROOT ??
23
+ path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
24
+ const ultramodernArgs = ['ultramodern', ${commandJson}, ...${extraArgsJson}, ...forwardedArgs];
25
+ const result = createBin
26
+ ? spawnSync(process.execPath, [createBin, ...ultramodernArgs], {
27
+ env: { ...process.env, ULTRAMODERN_WORKSPACE_ROOT: workspaceRoot },
28
+ stdio: 'inherit',
29
+ })
30
+ : spawnSync('modern-js-create', ultramodernArgs, {
31
+ env: { ...process.env, ULTRAMODERN_WORKSPACE_ROOT: workspaceRoot },
32
+ shell: process.platform === 'win32',
33
+ stdio: 'inherit',
14
34
  });
35
+
36
+ if (result.error) {
37
+ console.error(result.error.message);
38
+ process.exit(1);
39
+ }
40
+
41
+ process.exit(result.status ?? 1);
42
+ `;
43
+ }
44
+ function createSkillsToolWrapperScript() {
45
+ return `#!/usr/bin/env node
46
+ import { spawnSync } from 'node:child_process';
47
+ import path from 'node:path';
48
+ import { fileURLToPath } from 'node:url';
49
+
50
+ const createBin = process.env.ULTRAMODERN_CREATE_BIN;
51
+ const forwardedArgs = process.argv.slice(2);
52
+ const workspaceRoot =
53
+ process.env.ULTRAMODERN_WORKSPACE_ROOT ??
54
+ path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
55
+ const checkOnly = forwardedArgs.includes('--check');
56
+ const skillArgs = checkOnly
57
+ ? ['skills', 'check', ...forwardedArgs.filter(arg => arg !== '--check')]
58
+ : ['skills', 'install', ...forwardedArgs];
59
+ const ultramodernArgs = ['ultramodern', ...skillArgs];
60
+ const result = createBin
61
+ ? spawnSync(process.execPath, [createBin, ...ultramodernArgs], {
62
+ env: { ...process.env, ULTRAMODERN_WORKSPACE_ROOT: workspaceRoot },
63
+ stdio: 'inherit',
64
+ })
65
+ : spawnSync('modern-js-create', ultramodernArgs, {
66
+ env: { ...process.env, ULTRAMODERN_WORKSPACE_ROOT: workspaceRoot },
67
+ shell: process.platform === 'win32',
68
+ stdio: 'inherit',
69
+ });
70
+
71
+ if (result.error) {
72
+ console.error(result.error.message);
73
+ process.exit(1);
74
+ }
75
+
76
+ process.exit(result.status ?? 1);
77
+ `;
15
78
  }
16
79
  function createWorkspaceValidationScript(scope, enableTailwind, remotes = []) {
17
80
  const verticals = remotes.filter(appHasEffectApi).map((remote)=>({
@@ -65,33 +128,22 @@ function createWorkspaceValidationScript(scope, enableTailwind, remotes = []) {
65
128
  function createWorkspaceI18nBoundaryValidationScript() {
66
129
  return readFileTemplate("workspace-scripts/check-ultramodern-i18n-boundaries.mjs");
67
130
  }
68
- function createPublicSurfaceAssetsScript() {
69
- return readFileTemplate("workspace-scripts/generate-public-surface-assets.mjs");
70
- }
71
- function createCloudflareProofHelperScript() {
72
- return readFileTemplate("workspace-scripts/ultramodern-cloudflare-proof.mjs");
73
- }
74
- function createCloudflareVersionProofScript() {
75
- return readFileTemplate("workspace-scripts/proof-cloudflare-version.mjs");
131
+ function createWorkspaceApiBoundaryValidationScript() {
132
+ return readFileTemplate("workspace-scripts/check-ultramodern-api-boundaries.mjs");
76
133
  }
77
134
  function createPerformanceReadinessConfigScript() {
78
135
  return readFileTemplate("workspace-scripts/ultramodern-performance-readiness.config.mjs");
79
136
  }
80
- function createPerformanceReadinessScript() {
81
- return readFileTemplate("workspace-scripts/ultramodern-performance-readiness.mjs");
82
- }
83
- function createUltramodernTypecheckScript() {
84
- return readFileTemplate("workspace-scripts/ultramodern-typecheck.mjs");
85
- }
86
- function writeGeneratedWorkspaceScripts(targetDir, scope, enableTailwind, remotes = []) {
87
- writeFileReplacing(targetDir, "scripts/assert-mf-types.mjs", createAssertMfTypesScript(remotes));
88
- writeFileReplacing(targetDir, "scripts/validate-ultramodern-workspace.mjs", createWorkspaceValidationScript(scope, enableTailwind, remotes));
137
+ function writeGeneratedWorkspaceScripts(targetDir, _scope, _enableTailwind, _remotes = []) {
138
+ writeFileReplacing(targetDir, "scripts/assert-mf-types.mjs", createToolWrapperScript('mf-types'));
139
+ writeFileReplacing(targetDir, "scripts/validate-ultramodern-workspace.mjs", createToolWrapperScript('validate'));
89
140
  writeFileReplacing(targetDir, "scripts/check-ultramodern-i18n-boundaries.mjs", createWorkspaceI18nBoundaryValidationScript());
90
- writeFileReplacing(targetDir, "scripts/generate-public-surface-assets.mjs", createPublicSurfaceAssetsScript());
91
- writeFileReplacing(targetDir, "scripts/ultramodern-cloudflare-proof.mjs", createCloudflareProofHelperScript());
92
- writeFileReplacing(targetDir, "scripts/proof-cloudflare-version.mjs", createCloudflareVersionProofScript());
141
+ writeFileReplacing(targetDir, "scripts/check-ultramodern-api-boundaries.mjs", createWorkspaceApiBoundaryValidationScript());
142
+ writeFileReplacing(targetDir, "scripts/generate-public-surface-assets.mjs", createToolWrapperScript('public-surface'));
143
+ writeFileReplacing(targetDir, "scripts/proof-cloudflare-version.mjs", createToolWrapperScript('cloudflare-proof'));
93
144
  writeFileReplacing(targetDir, "scripts/ultramodern-performance-readiness.config.mjs", createPerformanceReadinessConfigScript());
94
- writeFileReplacing(targetDir, "scripts/ultramodern-performance-readiness.mjs", createPerformanceReadinessScript());
95
- writeFileReplacing(targetDir, "scripts/ultramodern-typecheck.mjs", createUltramodernTypecheckScript());
145
+ writeFileReplacing(targetDir, "scripts/ultramodern-performance-readiness.mjs", createToolWrapperScript('performance-readiness'));
146
+ writeFileReplacing(targetDir, "scripts/ultramodern-typecheck.mjs", createToolWrapperScript('typecheck'));
147
+ writeFileReplacing(targetDir, "scripts/bootstrap-agent-skills.mjs", createSkillsToolWrapperScript());
96
148
  }
97
- export { createAssertMfTypesScript, createCloudflareProofHelperScript, createCloudflareVersionProofScript, createPerformanceReadinessConfigScript, createPerformanceReadinessScript, createPublicSurfaceAssetsScript, createUltramodernTypecheckScript, createWorkspaceI18nBoundaryValidationScript, createWorkspaceValidationScript, writeGeneratedWorkspaceScripts };
149
+ export { createPerformanceReadinessConfigScript, createWorkspaceApiBoundaryValidationScript, createWorkspaceI18nBoundaryValidationScript, createWorkspaceValidationScript, writeGeneratedWorkspaceScripts };