@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
@@ -1,4 +1,5 @@
1
1
  import { execFileSync } from 'node:child_process';
2
+ import crypto from 'node:crypto';
2
3
  import fs from 'node:fs';
3
4
  import path from 'node:path';
4
5
 
@@ -14,6 +15,21 @@ const expectedCloudflareBuildScript = {{expectedCloudflareBuildScriptJson}};
14
15
  const expectedCloudflareDeployScript = {{expectedCloudflareDeployScriptJson}};
15
16
  const expectedCloudflareSecurity = {{expectedCloudflareSecurityJson}};
16
17
  const publicSurfaceManagedSourceAssetPaths = {{publicSurfaceManagedSourceAssetPathsJson}};
18
+ const compactConfigPath = '.modernjs/ultramodern.json';
19
+ const retiredMetadataPaths = [
20
+ '.modernjs/ultramodern-generated-contract.json',
21
+ '.modernjs/ultramodern-package-source.json',
22
+ '.modernjs/ultramodern-workspace-template-manifest.json',
23
+ ];
24
+ const modernPackageCohort = [
25
+ '@modern-js/create',
26
+ '@modern-js/code-tools',
27
+ '@modern-js/app-tools',
28
+ '@modern-js/plugin-bff',
29
+ '@modern-js/plugin-i18n',
30
+ '@modern-js/plugin-tanstack',
31
+ '@modern-js/runtime',
32
+ ];
17
33
  const expectedModernPackageSpecifier = packageName => {
18
34
  if (packageSource.strategy === 'workspace') {
19
35
  return 'workspace:*';
@@ -70,6 +86,688 @@ const assertArray = (value, contract, fixArea) => {
70
86
  };
71
87
  const findById = (entries, id) =>
72
88
  Array.isArray(entries) ? entries.find(entry => entry?.id === id) : undefined;
89
+ const generatedContractLabel = compactConfigPath;
90
+ const toKebabCase = value =>
91
+ String(value)
92
+ .trim()
93
+ .replace(/([a-z0-9])([A-Z])/gu, '$1-$2')
94
+ .replace(/[^a-zA-Z0-9._-]+/gu, '-')
95
+ .replace(/[._]+/gu, '-')
96
+ .toLowerCase()
97
+ .replace(/-+/gu, '-')
98
+ .replace(/^-+|-+$/gu, '');
99
+ const toPascalCase = value =>
100
+ toKebabCase(value)
101
+ .split('-')
102
+ .filter(Boolean)
103
+ .map(part => part.charAt(0).toUpperCase() + part.slice(1))
104
+ .join('');
105
+ const toCamelCase = value => {
106
+ const pascal = toPascalCase(value);
107
+ return `${pascal.charAt(0).toLowerCase()}${pascal.slice(1)}`;
108
+ };
109
+ const toEnvSegment = value => toKebabCase(value).replace(/-/gu, '_').toUpperCase();
110
+ const packageNameFor = (scope, suffix) => `@${scope}/${suffix}`;
111
+ const normalizeRelativePath = value =>
112
+ String(value ?? '').replace(/\\/gu, '/').replace(/^\.\/+/u, '');
113
+ const appNamespace = app => (app.kind === 'shell' ? 'shell' : (app.domain ?? app.id));
114
+ const tailwindPrefixDigitWords = [
115
+ 'zero',
116
+ 'one',
117
+ 'two',
118
+ 'three',
119
+ 'four',
120
+ 'five',
121
+ 'six',
122
+ 'seven',
123
+ 'eight',
124
+ 'nine',
125
+ ];
126
+ const tailwindPrefixFor = app =>
127
+ app.kind === 'shell'
128
+ ? 'shell'
129
+ : String(app.domain ?? app.id)
130
+ .toLowerCase()
131
+ .replace(/[^a-z0-9]/gu, '')
132
+ .replace(/[0-9]/gu, digit => tailwindPrefixDigitWords[Number(digit)]);
133
+ const buildMarkerFor = app =>
134
+ crypto
135
+ .createHash('sha256')
136
+ .update(`${packageScope}:${app.packageSuffix}:${app.id}:0.1.0`)
137
+ .digest('hex')
138
+ .slice(0, 16);
139
+ const normalizeCompactApp = rawApp => {
140
+ const id = String(rawApp.id);
141
+ const kind = rawApp.kind === 'vertical' ? 'vertical' : 'shell';
142
+ const appPath =
143
+ typeof rawApp.path === 'string'
144
+ ? normalizeRelativePath(rawApp.path)
145
+ : kind === 'shell'
146
+ ? 'apps/shell-super-app'
147
+ : `verticals/${toKebabCase(id)}`;
148
+ const packageSuffix =
149
+ typeof rawApp.packageSuffix === 'string'
150
+ ? rawApp.packageSuffix
151
+ : appPath.split('/').at(-1) ?? id;
152
+ const domain =
153
+ typeof rawApp.domain === 'string'
154
+ ? rawApp.domain
155
+ : kind === 'vertical'
156
+ ? packageSuffix
157
+ : undefined;
158
+ const moduleFederation =
159
+ rawApp.moduleFederation && typeof rawApp.moduleFederation === 'object'
160
+ ? rawApp.moduleFederation
161
+ : {};
162
+ const effectApi =
163
+ rawApp.effectApi && typeof rawApp.effectApi === 'object'
164
+ ? {
165
+ stem:
166
+ typeof rawApp.effectApi.stem === 'string'
167
+ ? rawApp.effectApi.stem
168
+ : domain ?? id,
169
+ prefix:
170
+ typeof rawApp.effectApi.prefix === 'string'
171
+ ? rawApp.effectApi.prefix
172
+ : `/${domain ?? id}-api`,
173
+ consumedBy: Array.isArray(rawApp.effectApi.consumedBy)
174
+ ? rawApp.effectApi.consumedBy.filter(
175
+ consumer => typeof consumer === 'string',
176
+ )
177
+ : ['shell-super-app', id],
178
+ }
179
+ : undefined;
180
+
181
+ return {
182
+ id,
183
+ kind,
184
+ path: appPath,
185
+ package: typeof rawApp.package === 'string' ? rawApp.package : undefined,
186
+ packageSuffix,
187
+ domain,
188
+ port:
189
+ typeof rawApp.port === 'number'
190
+ ? rawApp.port
191
+ : kind === 'shell'
192
+ ? 3020
193
+ : 3030,
194
+ portEnv:
195
+ typeof rawApp.portEnv === 'string'
196
+ ? rawApp.portEnv
197
+ : kind === 'shell'
198
+ ? 'SHELL_SUPER_APP_PORT'
199
+ : `VERTICAL_${toEnvSegment(domain ?? id)}_PORT`,
200
+ mfName:
201
+ typeof moduleFederation.name === 'string'
202
+ ? moduleFederation.name
203
+ : kind === 'shell'
204
+ ? 'shellSuperApp'
205
+ : `vertical${toPascalCase(domain ?? id)}`,
206
+ exposes: Array.isArray(moduleFederation.exposes)
207
+ ? moduleFederation.exposes.filter(expose => typeof expose === 'string')
208
+ : [],
209
+ moduleFederationSsr: moduleFederation.ssr !== false,
210
+ verticalRefs: Array.isArray(moduleFederation.verticalRefs)
211
+ ? moduleFederation.verticalRefs.filter(ref => typeof ref === 'string')
212
+ : [],
213
+ effectApi,
214
+ };
215
+ };
216
+ const compactAppsFromConfig = config =>
217
+ Array.isArray(config.topology?.apps)
218
+ ? config.topology.apps.map(normalizeCompactApp)
219
+ : [];
220
+ const remoteDependencyAliasFor = app => toCamelCase(app.domain ?? app.id.replace(/^remote-/u, ''));
221
+ const remoteContractsFor = (app, apps) =>
222
+ (app.verticalRefs ?? [])
223
+ .map(ref => apps.find(candidate => candidate.id === ref))
224
+ .filter(Boolean)
225
+ .map(remote => ({
226
+ id: remote.id,
227
+ alias: remoteDependencyAliasFor(remote),
228
+ name: remote.mfName,
229
+ manifestEnv: `VERTICAL_${toEnvSegment(remote.domain ?? remote.id)}_MF_MANIFEST`,
230
+ manifestUrl: `http://localhost:${remote.port}/mf-manifest.json`,
231
+ }));
232
+ const createRouteOwnedEntries = app => {
233
+ const namespace = appNamespace(app);
234
+ const base = {
235
+ descriptionKey: `${namespace}.seo.description`,
236
+ mfBoundaryId: app.mfName,
237
+ namespace,
238
+ ownerAppId: app.id,
239
+ public: false,
240
+ indexable: false,
241
+ publicSurface: 'private-app-screen',
242
+ };
243
+
244
+ return [
245
+ {
246
+ ...base,
247
+ canonicalPath: '/',
248
+ id: app.kind === 'shell' ? 'shell-home' : `${app.id}-home`,
249
+ localisedPaths: {
250
+ cs: '/',
251
+ en: '/',
252
+ },
253
+ titleKey: app.kind === 'shell' ? 'shell.title' : `${namespace}.title`,
254
+ },
255
+ ];
256
+ };
257
+ const createPublicRoutes = app =>
258
+ createRouteOwnedEntries(app)
259
+ .filter(route => route.public && route.indexable)
260
+ .map(route => ({
261
+ canonicalPath: route.canonicalPath,
262
+ id: route.id,
263
+ localisedPaths: route.localisedPaths,
264
+ namespace: route.namespace,
265
+ ownerAppId: route.ownerAppId,
266
+ descriptionKey: route.descriptionKey,
267
+ titleKey: route.titleKey,
268
+ }));
269
+ const createLocalisedUrls = app =>
270
+ Object.fromEntries(
271
+ createRouteOwnedEntries(app).flatMap(route => {
272
+ if (route.canonicalPath === '/') {
273
+ return [];
274
+ }
275
+ return Array.from(
276
+ new Set([route.canonicalPath, ...Object.values(route.localisedPaths)]),
277
+ ).map(pathname => [pathname, route.localisedPaths]);
278
+ }),
279
+ );
280
+ const createPublicSurface = app => {
281
+ const publicRoutes = createPublicRoutes(app);
282
+ return {
283
+ authoring: 'colocated-route-meta',
284
+ artifactLifecycle: 'build-and-deploy-output',
285
+ generatedManifest: './src/routes/ultramodern-route-metadata',
286
+ source: 'route-owned-public-routes',
287
+ metadataExport: './src/routes/ultramodern-route-metadata',
288
+ generator: 'scripts/generate-public-surface-assets.mjs',
289
+ outputRoot: 'dist/public',
290
+ cloudflareOutputRoot: '.output/public',
291
+ privateRoutePolicy: 'omit-from-generated-public-surface',
292
+ files:
293
+ publicRoutes.length > 0
294
+ ? ['robots.txt', 'sitemap.xml', 'site.webmanifest']
295
+ : ['robots.txt'],
296
+ omittedByDefault: ['api-catalog.json', 'llms.txt', 'security.txt'],
297
+ languages: ['en', 'cs'],
298
+ contentExpansion: {
299
+ authoring: 'route-owned-esm-provider',
300
+ defaultProviderFile: 'route.sitemap.mjs',
301
+ entryExport: 'default-or-entries',
302
+ paramsSource: 'params-or-localeParams',
303
+ draftPolicy: 'omit-draft-by-default',
304
+ indexablePolicy: 'omit-indexable-false',
305
+ lifecycle: 'executed-during-public-surface-generation',
306
+ },
307
+ contentSources: [],
308
+ publicRoutes,
309
+ routeEntries: [],
310
+ concreteUrlPaths: [],
311
+ };
312
+ };
313
+ const createPublicHead = () => ({
314
+ authoring: 'colocated-route-meta',
315
+ generator: './src/routes/ultramodern-route-head',
316
+ renderer: '@modern-js/runtime/head Helmet',
317
+ ssr: true,
318
+ title: {
319
+ required: true,
320
+ source: 'route.titleKey',
321
+ },
322
+ description: {
323
+ required: true,
324
+ source: 'route.descriptionKey',
325
+ },
326
+ canonical: {
327
+ publicIndexableOnly: true,
328
+ source: 'localized canonical route URL',
329
+ },
330
+ alternates: {
331
+ hreflang: ['en', 'cs'],
332
+ xDefault: 'en',
333
+ },
334
+ openGraph: {
335
+ publicIndexableOnly: true,
336
+ required: ['og:title', 'og:description', 'og:url', 'og:type'],
337
+ },
338
+ twitter: {
339
+ publicIndexableOnly: true,
340
+ required: ['twitter:card', 'twitter:title', 'twitter:description'],
341
+ },
342
+ structuredData: {
343
+ publicIndexableOnly: true,
344
+ optional: true,
345
+ source: 'route.jsonLd',
346
+ inference: false,
347
+ helperModule: './src/routes/ultramodern-jsonld',
348
+ helperTypes: [
349
+ 'WebPage',
350
+ 'WebApplication',
351
+ 'SoftwareApplication',
352
+ 'BreadcrumbList',
353
+ 'FAQPage',
354
+ 'Organization',
355
+ ],
356
+ sanitizesHtmlOpenBracket: true,
357
+ },
358
+ privateRouteRobots: 'noindex, nofollow',
359
+ });
360
+ const createQualityGates = () => ({
361
+ publicRoutes: {
362
+ requireSitemapWhenPresent: true,
363
+ requireRobotsSitemapConsistency: true,
364
+ requireWebManifestWhenPresent: true,
365
+ },
366
+ statusCodes: {
367
+ notFoundRoute: '/__ultramodern-smoke-missing/nope',
368
+ unknownRouteStatus: 404,
369
+ },
370
+ indexing: {
371
+ previewNoindex: true,
372
+ productionPublicRoutesIndexable: true,
373
+ },
374
+ assets: {
375
+ cssPreloadRequired: true,
376
+ cssResponseRequired: true,
377
+ cacheControlRequiredForCss: true,
378
+ sourcemapsPubliclyReferenced: false,
379
+ },
380
+ budgets: {
381
+ ssrHtmlMaxBytes: 250_000,
382
+ mfManifestMaxBytes: 500_000,
383
+ localeJsonMaxBytes: 100_000,
384
+ sitemapXmlMaxBytes: 500_000,
385
+ cssAssetMaxBytes: 750_000,
386
+ },
387
+ csp: {
388
+ finalMode: 'report-only-dogfood',
389
+ decision:
390
+ 'Report-only remains the generated final mode until public smoke proof records MF SSR script/style/connect compatibility for the deployed surface.',
391
+ },
392
+ });
393
+ const createCloudflareRoutes = app => ({
394
+ ssr: '/en',
395
+ mfManifest: '/mf-manifest.json',
396
+ locale: `/locales/en/${appNamespace(app)}.json`,
397
+ ...(app.effectApi
398
+ ? {
399
+ apiReadiness: `${app.effectApi.prefix}/${app.effectApi.stem}/readiness`,
400
+ }
401
+ : {}),
402
+ });
403
+ const createCloudflareDeploy = app => ({
404
+ target: 'cloudflare',
405
+ workerName: expectedWorkerName(app.packageSuffix),
406
+ publicUrlEnv: `ULTRAMODERN_PUBLIC_URL_${toEnvSegment(app.id)}`,
407
+ compatibilityDate: '{{cloudflareCompatibilityDate}}',
408
+ compatibilityFlags: ['nodejs_compat', 'global_fetch_strictly_public'],
409
+ assetsBinding: 'ASSETS',
410
+ routes: createCloudflareRoutes(app),
411
+ security: expectedCloudflareSecurity,
412
+ qualityGates: createQualityGates(),
413
+ evidence: {
414
+ proofScript: 'scripts/proof-cloudflare-version.mjs',
415
+ reportDefault:
416
+ '.codex/reports/cloudflare-version-proof/public-url-proof.json',
417
+ },
418
+ });
419
+ const createEffectReadiness = app => ({
420
+ endpoint: `/${app.effectApi.stem}/readiness`,
421
+ marker: {
422
+ ui: 'ultramodernUiMarker',
423
+ api: 'ultramodernApiMarker',
424
+ skew: 'none',
425
+ },
426
+ checks: ['moduleFederation', 'ssr', 'translations', 'api'],
427
+ });
428
+ const createEffectRequestContext = () => ({
429
+ propagatedHeaders: [
430
+ 'accept-language',
431
+ 'authorization',
432
+ 'traceparent',
433
+ 'x-correlation-id',
434
+ 'x-tenant-id',
435
+ 'x-ultramodern-env',
436
+ 'x-vertical-version-id',
437
+ ],
438
+ source: 'shell-to-vertical-api-client',
439
+ });
440
+ const createEffectDomainOperations = app => {
441
+ const stem = app.effectApi.stem;
442
+ const group = toCamelCase(stem);
443
+ const basePath = `/${stem}`;
444
+ return {
445
+ workspaceFeed: {
446
+ client: `list${toPascalCase(stem)}`,
447
+ method: 'GET',
448
+ path: basePath,
449
+ resource: 'workspace-items',
450
+ owner: app.id,
451
+ },
452
+ workspaceDetail: {
453
+ client: `get${toPascalCase(stem)}`,
454
+ method: 'GET',
455
+ path: `${basePath}/:id`,
456
+ resource: 'workspace-item',
457
+ owner: app.id,
458
+ },
459
+ workspaceCreate: {
460
+ client: `create${toPascalCase(stem)}`,
461
+ method: 'POST',
462
+ path: basePath,
463
+ resource: group,
464
+ owner: app.id,
465
+ },
466
+ };
467
+ };
468
+ const createEffectOperationContract = app => ({
469
+ group: toCamelCase(app.effectApi.stem),
470
+ operations: {
471
+ readiness: {
472
+ method: 'GET',
473
+ path: `/${app.effectApi.stem}/readiness`,
474
+ source: 'generated-client',
475
+ },
476
+ },
477
+ });
478
+ const createAppConfigContract = app => ({
479
+ preset: 'presetUltramodern',
480
+ plugins: [
481
+ 'appTools',
482
+ 'tanstackRouterPlugin',
483
+ 'i18nPlugin',
484
+ ...(app.effectApi ? ['bffPlugin'] : []),
485
+ 'moduleFederationPlugin',
486
+ 'zephyrRspackPlugin',
487
+ ],
488
+ dev: {
489
+ assetPrefix: '/',
490
+ },
491
+ output: {
492
+ assetPrefix: {
493
+ envFallbackOrder: ['MODERN_ASSET_PREFIX', 'ULTRAMODERN_ASSET_PREFIX'],
494
+ default: app.kind === 'shell' ? '/' : 'app-public-origin',
495
+ },
496
+ disableTsChecker: false,
497
+ },
498
+ performance: {
499
+ readinessDiagnostics: {
500
+ default: 'enabled',
501
+ optOut: {
502
+ env: 'ULTRAMODERN_PERFORMANCE_READINESS_DIAGNOSTICS=false',
503
+ config: 'scripts/ultramodern-performance-readiness.config.mjs',
504
+ },
505
+ failOn: 'framework-invariant',
506
+ },
507
+ },
508
+ rspack: {
509
+ output: {
510
+ uniqueName: app.mfName,
511
+ chunkLoadingGlobal: expectedChunkLoadingGlobal(app.mfName),
512
+ },
513
+ },
514
+ source: {
515
+ siteUrl: {
516
+ envFallbackOrder: [
517
+ 'MODERN_PUBLIC_SITE_URL',
518
+ `ULTRAMODERN_PUBLIC_URL_${toEnvSegment(app.id)}`,
519
+ 'ULTRAMODERN_CLOUDFLARE_WORKERS_DEV_SUBDOMAIN',
520
+ app.portEnv,
521
+ ],
522
+ defaultLocalhostPort: app.port,
523
+ },
524
+ },
525
+ });
526
+ const cssDedupe = () => ({
527
+ strategy: 'shared-token-package-plus-css-content-hash',
528
+ sharedPackage: packageNameFor(packageScope, 'shared-design-tokens'),
529
+ sharedLayers: ['ultramodern-shared-tokens'],
530
+ runtimeLoad: 'once-per-content-hash',
531
+ duplicateBaseStylesAllowed: false,
532
+ });
533
+ const createStylingContract = app => {
534
+ const sharedTokenPackage = packageNameFor(packageScope, 'shared-design-tokens');
535
+ const ownedLayers =
536
+ app.kind === 'shell'
537
+ ? ['ultramodern-shell-base', 'ultramodern-shell-overlay']
538
+ : [`ultramodern-vertical-${app.domain ?? app.id}`];
539
+
540
+ return {
541
+ tailwind: tailwindEnabled,
542
+ federation: {
543
+ owner: {
544
+ id: app.id,
545
+ package: app.package ?? packageNameFor(packageScope, app.packageSuffix),
546
+ },
547
+ role: app.kind === 'shell' ? 'shell-base-overlay' : 'vertical-css',
548
+ rootSelector: `[data-app-id="${app.id}"]`,
549
+ classPrefix: `${tailwindPrefixFor(app)}:`,
550
+ layers: {
551
+ shared: ['ultramodern-shared-tokens'],
552
+ owned: ownedLayers,
553
+ },
554
+ entrypoints: {
555
+ layoutImport: 'src/routes/layout.tsx',
556
+ css: ['src/routes/index.css'],
557
+ ...(app.kind === 'shell'
558
+ ? {}
559
+ : { federationEntry: 'src/federation-entry.tsx' }),
560
+ },
561
+ assets: {
562
+ shared: [`${sharedTokenPackage}/tokens.css`],
563
+ owned: ['src/routes/index.css'],
564
+ },
565
+ dedupe: cssDedupe(),
566
+ ssr: {
567
+ cloudflare: true,
568
+ firstPaintRequired: true,
569
+ verticalCss:
570
+ app.kind === 'shell'
571
+ ? 'host-preloads-shell-and-shared-css'
572
+ : 'federated-manifest-owned-css',
573
+ },
574
+ },
575
+ };
576
+ };
577
+ const createAppContract = (app, apps) => ({
578
+ id: app.id,
579
+ package: app.package ?? packageNameFor(packageScope, app.packageSuffix),
580
+ path: app.path,
581
+ kind: app.kind,
582
+ config: createAppConfigContract(app),
583
+ styling: createStylingContract(app),
584
+ deploy: {
585
+ target: 'cloudflare',
586
+ cloudflare: createCloudflareDeploy(app),
587
+ worker: {
588
+ compatibilityDate: '{{cloudflareCompatibilityDate}}',
589
+ name: expectedWorkerName(app.packageSuffix),
590
+ security: expectedCloudflareSecurity,
591
+ ssr: true,
592
+ },
593
+ },
594
+ ssr: app.moduleFederationSsr
595
+ ? {
596
+ mode: 'string',
597
+ moduleFederationAppSSR: true,
598
+ }
599
+ : undefined,
600
+ i18n: {
601
+ languages: ['en', 'cs'],
602
+ namespace: appNamespace(app),
603
+ localisedUrls: createLocalisedUrls(app),
604
+ },
605
+ routes: {
606
+ source: 'route-owned',
607
+ metadataAuthoring: 'colocated-route-meta',
608
+ generatedManifest: true,
609
+ metadataExport: './src/routes/ultramodern-route-metadata',
610
+ localisedUrls: createLocalisedUrls(app),
611
+ owned: createRouteOwnedEntries(app),
612
+ publicRoutes: createPublicRoutes(app),
613
+ privateByDefault: true,
614
+ publicnessDefault: 'private-app-screen',
615
+ publicHead: createPublicHead(),
616
+ publicSurface: createPublicSurface(app),
617
+ },
618
+ moduleFederation: {
619
+ name: app.mfName,
620
+ ...(app.verticalRefs?.length
621
+ ? {
622
+ verticalRefs: app.verticalRefs,
623
+ remotes: remoteContractsFor(app, apps),
624
+ }
625
+ : {}),
626
+ exposes: app.exposes,
627
+ dts: {
628
+ compilerInstance: 'tsgo',
629
+ displayErrorInTerminal: true,
630
+ tsConfigPath: './tsconfig.mf-types.json',
631
+ },
632
+ browserSafeExposesOnly: true,
633
+ },
634
+ marker: {
635
+ appId: app.id,
636
+ packageName: app.package ?? packageNameFor(packageScope, app.packageSuffix),
637
+ version: '0.1.0',
638
+ build: buildMarkerFor(app),
639
+ deployProfile: 'cloudflare-ssr-mf-effect-v1',
640
+ uiSurface: 'ui',
641
+ ...(app.effectApi ? { apiSurface: 'api' } : {}),
642
+ },
643
+ ...(app.effectApi
644
+ ? {
645
+ api: {
646
+ runtime: 'effect',
647
+ import: '@modern-js/plugin-bff/effect-edge',
648
+ prefix: app.effectApi.prefix,
649
+ openapi: '/openapi.json',
650
+ strictEffectApproach: true,
651
+ workerEntry: 'worker/__modern_bff_effect.js',
652
+ contract: './api',
653
+ client: './api/client',
654
+ readiness: createEffectReadiness(app),
655
+ requestContext: createEffectRequestContext(),
656
+ domainOperations: createEffectDomainOperations(app),
657
+ ...createEffectOperationContract(app),
658
+ },
659
+ }
660
+ : {}),
661
+ });
662
+ const createCssFederationContract = () => ({
663
+ sharedDesignTokens: {
664
+ owner: {
665
+ id: 'shared-design-tokens',
666
+ package: packageNameFor(packageScope, 'shared-design-tokens'),
667
+ },
668
+ role: 'shared-design-tokens',
669
+ rootSelector: ':root',
670
+ classPrefix: '--um-',
671
+ layers: {
672
+ owned: ['ultramodern-shared-tokens'],
673
+ },
674
+ entrypoints: {
675
+ css: ['packages/shared-design-tokens/src/tokens.css'],
676
+ },
677
+ assets: {
678
+ exports: ['./tokens.css'],
679
+ },
680
+ dedupe: cssDedupe(),
681
+ ssr: {
682
+ firstPaintRequired: true,
683
+ },
684
+ },
685
+ });
686
+ const createPerformanceReadinessContract = () => ({
687
+ default: 'enabled',
688
+ mode: 'diagnostic',
689
+ scope: 'ultramodern-generated-and-framework-owned',
690
+ report: {
691
+ script: 'scripts/ultramodern-performance-readiness.mjs',
692
+ config: 'scripts/ultramodern-performance-readiness.config.mjs',
693
+ deterministic: true,
694
+ },
695
+ optOut: {
696
+ env: 'ULTRAMODERN_PERFORMANCE_READINESS_DIAGNOSTICS=false',
697
+ },
698
+ signals: [
699
+ 'bfcache',
700
+ 'core-web-vitals-rum',
701
+ 'duplicate-prefetch-warmup',
702
+ 'cache-policy-sanity',
703
+ 'save-data-behavior',
704
+ 'cloudflare-ssr-cache-hints',
705
+ ].map(id => ({ id })),
706
+ });
707
+ const createModernPackageAliases = packageSourceConfig => {
708
+ if (typeof packageSourceConfig?.aliasScope !== 'string') {
709
+ return undefined;
710
+ }
711
+ const scope = packageSourceConfig.aliasScope.replace(/^@/u, '');
712
+ const prefix =
713
+ typeof packageSourceConfig.aliasPackageNamePrefix === 'string'
714
+ ? packageSourceConfig.aliasPackageNamePrefix
715
+ : '';
716
+ return Object.fromEntries(
717
+ modernPackageCohort.map(packageName => [
718
+ packageName,
719
+ `@${scope}/${prefix}${packageName.split('/').at(-1)}`,
720
+ ]),
721
+ );
722
+ };
723
+ const synthesizePackageSourceFromCompact = config => {
724
+ const source = config.packageSource ?? {};
725
+ const strategy = source.strategy === 'install' ? 'install' : 'workspace';
726
+ const specifier =
727
+ strategy === 'install' && typeof source.modernPackageVersion === 'string'
728
+ ? source.modernPackageVersion
729
+ : 'workspace:*';
730
+ const aliases = createModernPackageAliases(source);
731
+ return {
732
+ schemaVersion: 1,
733
+ strategy,
734
+ modernPackages: {
735
+ packages: modernPackageCohort,
736
+ specifier,
737
+ ...(typeof source.registry === 'string'
738
+ ? { registry: source.registry }
739
+ : {}),
740
+ ...(aliases ? { aliases } : {}),
741
+ },
742
+ generatedWorkspacePackages: {
743
+ packages: [
744
+ packageNameFor(packageScope, 'shared-contracts'),
745
+ packageNameFor(packageScope, 'shared-design-tokens'),
746
+ ],
747
+ specifier: 'workspace:*',
748
+ },
749
+ };
750
+ };
751
+ const synthesizeGeneratedContractFromCompact = config => {
752
+ const apps = compactAppsFromConfig(config);
753
+ return {
754
+ schemaVersion: 1,
755
+ profile: config.profile ?? 'cloudflare-ssr-mf-effect-v1',
756
+ node: {
757
+ version: config.workspace?.node?.version ?? expectedNodeVersion,
758
+ engineRange: '>=26',
759
+ },
760
+ performanceReadiness: createPerformanceReadinessContract(),
761
+ cssFederation: createCssFederationContract(),
762
+ apps: apps.map(app => createAppContract(app, apps)),
763
+ };
764
+ };
765
+ const readPackageSourceView = config => {
766
+ return synthesizePackageSourceFromCompact(config);
767
+ };
768
+ const readGeneratedContractView = config => {
769
+ return synthesizeGeneratedContractFromCompact(config);
770
+ };
73
771
  const expectedManifestUrl = vertical =>
74
772
  `http://localhost:${vertical.port}/mf-manifest.json`;
75
773
  const expectedApiUrl = vertical =>
@@ -92,11 +790,12 @@ const expectedRemoteSubsetsForRefs = refs =>
92
790
  const requiredMicroVerticalPaths = vertical => [
93
791
  `${vertical.path}/package.json`,
94
792
  `${vertical.path}/tsconfig.json`,
793
+ `${vertical.path}/tsconfig.mf-types.json`,
95
794
  `${vertical.path}/modern.config.ts`,
96
795
  `${vertical.path}/module-federation.config.ts`,
97
- `${vertical.path}/api/effect/index.ts`,
98
- `${vertical.path}/shared/effect/api.ts`,
99
- `${vertical.path}/src/effect/${vertical.stem}-client.ts`,
796
+ `${vertical.path}/api/index.ts`,
797
+ `${vertical.path}/shared/api.ts`,
798
+ `${vertical.path}/src/api/${vertical.stem}-client.ts`,
100
799
  `${vertical.path}/src/modern-app-env.d.ts`,
101
800
  `${vertical.path}/src/modern.runtime.ts`,
102
801
  `${vertical.path}/src/federation-entry.tsx`,
@@ -172,11 +871,11 @@ const assertMicroVerticalContractGraph = ({
172
871
  assertObject(
173
872
  overlay.apis,
174
873
  'topology/local-overlays/development.json apis',
175
- 'restore generated local Effect API overlays',
874
+ 'restore generated local API overlays',
176
875
  );
177
876
  assertArray(
178
877
  generatedContract.apps,
179
- '.modernjs/ultramodern-generated-contract.json apps',
878
+ `${generatedContractLabel} apps`,
180
879
  'regenerate the generated contract from the workspace topology',
181
880
  );
182
881
 
@@ -201,26 +900,26 @@ const assertMicroVerticalContractGraph = ({
201
900
  assertSameJson(
202
901
  generatedContract.apps.map(app => app?.id),
203
902
  expectedAppIds,
204
- '.modernjs/ultramodern-generated-contract.json apps',
903
+ `${generatedContractLabel} apps`,
205
904
  'regenerate the generated contract after topology changes',
206
905
  );
207
906
 
208
907
  const shellContract = findById(generatedContract.apps, 'shell-super-app');
209
908
  assertObject(
210
909
  shellContract,
211
- '.modernjs/ultramodern-generated-contract.json apps.shell-super-app',
910
+ `${generatedContractLabel} apps.shell-super-app`,
212
911
  'regenerate the generated shell contract entry',
213
912
  );
214
913
  assertSameJson(
215
914
  shellContract.moduleFederation?.verticalRefs ?? [],
216
915
  expectedVerticalIds,
217
- '.modernjs/ultramodern-generated-contract.json shell moduleFederation.verticalRefs',
916
+ `${generatedContractLabel} shell moduleFederation.verticalRefs`,
218
917
  'regenerate the generated shell Module Federation contract',
219
918
  );
220
919
  assertSameJson(
221
920
  (shellContract.moduleFederation?.remotes ?? []).map(remoteContractSubset),
222
921
  expectedShellRemotes,
223
- '.modernjs/ultramodern-generated-contract.json shell moduleFederation.remotes',
922
+ `${generatedContractLabel} shell moduleFederation.remotes`,
224
923
  'regenerate the generated shell Module Federation contract',
225
924
  );
226
925
  assertSameJson(
@@ -229,7 +928,7 @@ const assertMicroVerticalContractGraph = ({
229
928
  mode: 'string',
230
929
  moduleFederationAppSSR: true,
231
930
  },
232
- '.modernjs/ultramodern-generated-contract.json shell SSR contract',
931
+ `${generatedContractLabel} shell SSR contract`,
233
932
  'restore generated string SSR Module Federation settings',
234
933
  );
235
934
 
@@ -265,9 +964,9 @@ const assertMicroVerticalContractGraph = ({
265
964
  remoteContractSubset,
266
965
  ),
267
966
  },
268
- effect: {
269
- prefix: topologyEntry.api?.effect?.bff?.prefix,
270
- serverEntry: topologyEntry.api?.effect?.serverEntry,
967
+ api: {
968
+ prefix: topologyEntry.api?.bff?.prefix,
969
+ serverEntry: topologyEntry.api?.serverEntry,
271
970
  },
272
971
  },
273
972
  {
@@ -281,9 +980,9 @@ const assertMicroVerticalContractGraph = ({
281
980
  verticalRefs: expectedRefs,
282
981
  remotes: expectedRemoteSubsetsForRefs(expectedRefs),
283
982
  },
284
- effect: {
983
+ api: {
285
984
  prefix: vertical.apiPrefix,
286
- serverEntry: `${vertical.path}/api/effect/index.ts`,
985
+ serverEntry: `${vertical.path}/api/index.ts`,
287
986
  },
288
987
  },
289
988
  `topology/reference-topology.json verticals.${vertical.id}`,
@@ -324,14 +1023,14 @@ const assertMicroVerticalContractGraph = ({
324
1023
  overlay.apis[vertical.id],
325
1024
  expectedApiUrl(vertical),
326
1025
  `topology/local-overlays/development.json apis.${vertical.id}`,
327
- 'restore generated local Effect API overlay',
1026
+ 'restore generated local API overlay',
328
1027
  );
329
1028
 
330
1029
  assertSameJson(
331
1030
  shellPackage.dependencies?.[vertical.packageName],
332
1031
  'workspace:*',
333
1032
  `apps/shell-super-app/package.json dependencies.${vertical.packageName}`,
334
- 'restore shell dependency for the MicroVertical Effect API consumer',
1033
+ 'restore shell dependency for the MicroVertical API consumer',
335
1034
  );
336
1035
  assertSameJson(
337
1036
  shellPackage['zephyr:dependencies']?.[vertical.zephyrAlias],
@@ -342,7 +1041,7 @@ const assertMicroVerticalContractGraph = ({
342
1041
 
343
1042
  assertObject(
344
1043
  contractEntry,
345
- `.modernjs/ultramodern-generated-contract.json apps.${vertical.id}`,
1044
+ `${generatedContractLabel} apps.${vertical.id}`,
346
1045
  'regenerate the generated MicroVertical contract entry',
347
1046
  );
348
1047
  assertSameJson(
@@ -358,10 +1057,10 @@ const assertMicroVerticalContractGraph = ({
358
1057
  remoteContractSubset,
359
1058
  ),
360
1059
  },
361
- effect: {
362
- prefix: contractEntry.effect?.prefix,
363
- contract: contractEntry.effect?.contract,
364
- client: contractEntry.effect?.client,
1060
+ api: {
1061
+ prefix: contractEntry.api?.prefix,
1062
+ contract: contractEntry.api?.contract,
1063
+ client: contractEntry.api?.client,
365
1064
  },
366
1065
  ssr: contractEntry.ssr,
367
1066
  },
@@ -375,21 +1074,141 @@ const assertMicroVerticalContractGraph = ({
375
1074
  verticalRefs: expectedRefs,
376
1075
  remotes: expectedRemoteSubsetsForRefs(expectedRefs),
377
1076
  },
378
- effect: {
1077
+ api: {
379
1078
  prefix: vertical.apiPrefix,
380
- contract: './shared/effect/api',
381
- client: './effect/client',
1079
+ contract: './api',
1080
+ client: './api/client',
382
1081
  },
383
1082
  ssr: {
384
1083
  mode: 'string',
385
1084
  moduleFederationAppSSR: true,
386
1085
  },
387
1086
  },
388
- `.modernjs/ultramodern-generated-contract.json apps.${vertical.id}`,
1087
+ `${generatedContractLabel} apps.${vertical.id}`,
389
1088
  'regenerate the generated MicroVertical contract entry',
390
1089
  );
391
1090
  }
392
1091
  };
1092
+ const toPosixPath = value => value.split(path.sep).join('/');
1093
+ const referenceFrom = (fromPath, toPath) => ({
1094
+ path: toPosixPath(path.relative(fromPath, toPath)),
1095
+ });
1096
+ const sharedPackagePaths = [
1097
+ 'packages/shared-contracts',
1098
+ 'packages/shared-design-tokens',
1099
+ ];
1100
+ const tsgoCacheKey = packagePath => packagePath.replace(/[^a-zA-Z0-9._-]+/gu, '__');
1101
+ const assertProjectReferenceEmitConfig = (tsConfig, packagePath) => {
1102
+ const compilerOptions = tsConfig.compilerOptions ?? {};
1103
+ const relativeRoot = toPosixPath(path.relative(packagePath, '.')) || '.';
1104
+ assert(compilerOptions.composite === true, `${packagePath} must stay a composite TS-Go project`);
1105
+ assert(compilerOptions.declaration === true, `${packagePath} must emit declarations for TS-Go build mode`);
1106
+ assert(compilerOptions.declarationMap === false, `${packagePath} must not emit declaration maps during checks`);
1107
+ assert(compilerOptions.emitDeclarationOnly === true, `${packagePath} must only emit declarations during checks`);
1108
+ assert(compilerOptions.noEmit === false, `${packagePath} must override root noEmit for TS-Go build mode`);
1109
+ assert(
1110
+ compilerOptions.outDir === `${relativeRoot}/node_modules/.cache/tsgo/declarations/${tsgoCacheKey(packagePath)}`,
1111
+ `${packagePath} must emit TS-Go declarations into the generated cache`,
1112
+ );
1113
+ assert(
1114
+ compilerOptions.tsBuildInfoFile === `${relativeRoot}/node_modules/.cache/tsgo/${tsgoCacheKey(packagePath)}.tsbuildinfo`,
1115
+ `${packagePath} must keep TS-Go build info in the generated cache`,
1116
+ );
1117
+ };
1118
+ const assertTsConfigReferenceGraph = () => {
1119
+ const rootTsConfig = readJson('tsconfig.json');
1120
+ const shellTsConfig = readJson('apps/shell-super-app/tsconfig.json');
1121
+ const shellMfTypesTsConfig = readJson(
1122
+ 'apps/shell-super-app/tsconfig.mf-types.json',
1123
+ );
1124
+ const expectedRootReferences = [
1125
+ ...sharedPackagePaths,
1126
+ 'apps/shell-super-app',
1127
+ ...fullStackVerticals.map(vertical => vertical.path),
1128
+ ].map(referencePath => ({ path: referencePath }));
1129
+ const expectedShellReferences = [
1130
+ ...sharedPackagePaths,
1131
+ ...fullStackVerticals.map(vertical => vertical.path),
1132
+ ].map(referencePath =>
1133
+ referenceFrom('apps/shell-super-app', referencePath),
1134
+ );
1135
+
1136
+ assertSameJson(
1137
+ rootTsConfig.files,
1138
+ [],
1139
+ 'tsconfig.json files',
1140
+ 'restore the generated root project-reference tsconfig',
1141
+ );
1142
+ assertSameJson(
1143
+ rootTsConfig.references ?? [],
1144
+ expectedRootReferences,
1145
+ 'tsconfig.json references',
1146
+ 'restore the generated root project-reference graph',
1147
+ );
1148
+ assertSameJson(
1149
+ shellTsConfig.references ?? [],
1150
+ expectedShellReferences,
1151
+ 'apps/shell-super-app/tsconfig.json references',
1152
+ 'restore the generated shell project-reference graph',
1153
+ );
1154
+ assertProjectReferenceEmitConfig(
1155
+ shellTsConfig,
1156
+ 'apps/shell-super-app',
1157
+ );
1158
+ assertSameJson(
1159
+ shellMfTypesTsConfig,
1160
+ {
1161
+ extends: './tsconfig.json',
1162
+ include: ['src/modern-app-env.d.ts'],
1163
+ },
1164
+ 'apps/shell-super-app/tsconfig.mf-types.json',
1165
+ 'restore the generated shell Module Federation DTS boundary',
1166
+ );
1167
+ for (const sharedPackagePath of sharedPackagePaths) {
1168
+ assertProjectReferenceEmitConfig(
1169
+ readJson(`${sharedPackagePath}/tsconfig.json`),
1170
+ sharedPackagePath,
1171
+ );
1172
+ }
1173
+
1174
+ for (const vertical of fullStackVerticals) {
1175
+ const verticalTsConfig = readJson(`${vertical.path}/tsconfig.json`);
1176
+ const verticalMfTypesTsConfig = readJson(
1177
+ `${vertical.path}/tsconfig.mf-types.json`,
1178
+ );
1179
+ const expectedVerticalReferences = [
1180
+ ...sharedPackagePaths,
1181
+ ...(vertical.verticalRefs ?? [])
1182
+ .map(verticalRef =>
1183
+ fullStackVerticals.find(candidate => candidate.id === verticalRef),
1184
+ )
1185
+ .filter(Boolean)
1186
+ .map(referencedVertical => referencedVertical.path),
1187
+ ].map(referencePath => referenceFrom(vertical.path, referencePath));
1188
+ assertSameJson(
1189
+ verticalTsConfig.references ?? [],
1190
+ expectedVerticalReferences,
1191
+ `${vertical.path}/tsconfig.json references`,
1192
+ 'restore the generated MicroVertical project-reference graph',
1193
+ );
1194
+ assertProjectReferenceEmitConfig(verticalTsConfig, vertical.path);
1195
+ assertSameJson(
1196
+ verticalMfTypesTsConfig,
1197
+ {
1198
+ extends: './tsconfig.json',
1199
+ include: [
1200
+ 'src/federation-entry.tsx',
1201
+ ...vertical.componentPaths.map(componentPath =>
1202
+ componentPath.replace(`${vertical.path}/`, ''),
1203
+ ),
1204
+ 'src/modern-app-env.d.ts',
1205
+ ],
1206
+ },
1207
+ `${vertical.path}/tsconfig.mf-types.json`,
1208
+ 'restore the generated MicroVertical Module Federation DTS boundary',
1209
+ );
1210
+ }
1211
+ };
393
1212
  const packageJsonFiles = startDir => {
394
1213
  const files = [];
395
1214
  const queue = [startDir];
@@ -649,17 +1468,15 @@ const requiredPaths = [
649
1468
  'oxfmt.config.ts',
650
1469
  '.github/renovate.json',
651
1470
  '.github/workflows/ultramodern-workspace-gates.yml',
652
- '.agents/skills-lock.json',
653
1471
  '.agents/agent-reference-repos.json',
654
- '.agents/rstackjs-agent-skills-LICENSE',
1472
+ '.codex/skills-lock.json',
1473
+ '.codex/rstackjs-agent-skills-LICENSE',
655
1474
  'topology/reference-topology.json',
656
1475
  'topology/ownership.json',
657
1476
  'topology/local-overlays/development.json',
658
- '.modernjs/ultramodern-workspace-template-manifest.json',
659
- '.modernjs/ultramodern-package-source.json',
660
- '.modernjs/ultramodern-generated-contract.json',
661
1477
  'scripts/assert-mf-types.mjs',
662
1478
  'scripts/bootstrap-agent-skills.mjs',
1479
+ 'scripts/check-ultramodern-api-boundaries.mjs',
663
1480
  'scripts/check-ultramodern-i18n-boundaries.mjs',
664
1481
  'scripts/generate-public-surface-assets.mjs',
665
1482
  'scripts/proof-cloudflare-version.mjs',
@@ -667,13 +1484,15 @@ const requiredPaths = [
667
1484
  'scripts/ultramodern-performance-readiness.config.mjs',
668
1485
  'scripts/ultramodern-performance-readiness.mjs',
669
1486
  'scripts/ultramodern-typecheck.mjs',
1487
+ 'scripts/validate-ultramodern-workspace.mjs',
670
1488
  'apps/shell-super-app/package.json',
671
1489
  'apps/shell-super-app/tsconfig.json',
1490
+ 'apps/shell-super-app/tsconfig.mf-types.json',
672
1491
  'apps/shell-super-app/modern.config.ts',
673
1492
  'apps/shell-super-app/module-federation.config.ts',
674
1493
  'apps/shell-super-app/src/modern-app-env.d.ts',
675
1494
  'apps/shell-super-app/src/modern.runtime.ts',
676
- 'apps/shell-super-app/src/effect/vertical-clients.ts',
1495
+ 'apps/shell-super-app/src/api/vertical-clients.ts',
677
1496
  'apps/shell-super-app/locales/en/translation.json',
678
1497
  `apps/shell-super-app/locales/en/${shellNamespace}.json`,
679
1498
  'apps/shell-super-app/locales/cs/translation.json',
@@ -708,6 +1527,8 @@ if (tailwindEnabled) {
708
1527
  );
709
1528
  }
710
1529
 
1530
+ requiredPaths.push(compactConfigPath);
1531
+
711
1532
  for (const vertical of fullStackVerticals) {
712
1533
  requiredMicroVerticalPaths(vertical).forEach(
713
1534
  assertRequiredVerticalFile(vertical),
@@ -719,9 +1540,15 @@ for (const requiredPath of requiredPaths) {
719
1540
  for (const oldRemotePath of oldRemotePaths) {
720
1541
  assertNotExists(oldRemotePath);
721
1542
  }
1543
+ for (const retiredMetadataPath of retiredMetadataPaths) {
1544
+ assertNotExists(retiredMetadataPath);
1545
+ }
722
1546
  const rootPackage = readJson('package.json');
723
- const packageSource = readJson('.modernjs/ultramodern-package-source.json');
724
- const generatedContract = readJson('.modernjs/ultramodern-generated-contract.json');
1547
+ const ultramodernConfig = readJson(compactConfigPath);
1548
+ const bridgeConfig =
1549
+ ultramodernConfig?.bridge?.enabled === true ? ultramodernConfig.bridge : undefined;
1550
+ const packageSource = readPackageSourceView(ultramodernConfig);
1551
+ const generatedContract = readGeneratedContractView(ultramodernConfig);
725
1552
  const topology = readJson('topology/reference-topology.json');
726
1553
  const ownership = readJson('topology/ownership.json');
727
1554
  const overlay = readJson('topology/local-overlays/development.json');
@@ -734,6 +1561,7 @@ assertMicroVerticalContractGraph({
734
1561
  overlay,
735
1562
  shellPackage,
736
1563
  });
1564
+ assertTsConfigReferenceGraph();
737
1565
 
738
1566
  assert(rootPackage.private === true, 'Root package must be private');
739
1567
  assert(typeof rootPackage.packageManager === 'string', 'Root must declare packageManager');
@@ -759,7 +1587,10 @@ assert(
759
1587
  );
760
1588
  assert(!workflowText.includes('FORCE_JAVASCRIPT_ACTIONS_TO_NODE24'), 'CI workflow must not carry the legacy Node 24 override');
761
1589
  assert(rootPackage.modernjs?.preset === 'presetUltramodern', 'Root must declare presetUltramodern');
762
- assert(rootPackage.modernjs?.packageSource?.config === './.modernjs/ultramodern-package-source.json', 'Root must point at package source metadata');
1590
+ assert(
1591
+ rootPackage.modernjs?.packageSource?.config === './.modernjs/ultramodern.json',
1592
+ 'Root must point at compact UltraModern config',
1593
+ );
763
1594
  assert(rootPackage.modernjs?.packageSource?.strategy === packageSource.strategy, 'Root package source strategy must match metadata');
764
1595
  assert(packageSource.strategy === 'workspace' || packageSource.strategy === 'install', 'Package source strategy must be workspace or install');
765
1596
  assert(packageSource.strategy === 'install' || packageSource.modernPackages?.specifier === 'workspace:*', 'Workspace package source must be explicitly backed by workspace:*');
@@ -807,22 +1638,61 @@ assert(
807
1638
  );
808
1639
  assert(rootPackage.scripts?.['cloudflare:build'] === expectedCloudflareBuildScript, 'Root cloudflare:build script is incorrect');
809
1640
  assert(!('ultramodern:check' in (rootPackage.scripts ?? {})), 'Root must not expose ultramodern:check');
810
- assert(rootPackage.scripts?.typecheck === 'node ./scripts/ultramodern-typecheck.mjs --build tsconfig.json', 'Root typecheck must run TS-Go build mode across project references');
1641
+ if (bridgeConfig) {
1642
+ assert(
1643
+ rootPackage.scripts?.typecheck ===
1644
+ 'pnpm -r --filter "./apps/*" --filter "./verticals/*" --filter "./packages/*" run typecheck',
1645
+ 'Bridge root typecheck must check generated package boundaries without building parent implementation sources',
1646
+ );
1647
+ assert(Array.isArray(bridgeConfig.workspacePackages), 'Bridge config must record workspace package patterns');
1648
+ for (const workspacePackage of bridgeConfig.workspacePackages) {
1649
+ assert(
1650
+ rootPackage.workspaces?.includes(workspacePackage.pattern),
1651
+ `Root workspaces must include bridge package pattern ${workspacePackage.pattern}`,
1652
+ );
1653
+ assert(
1654
+ readText('pnpm-workspace.yaml').includes(` - ${workspacePackage.pattern}`),
1655
+ `pnpm-workspace.yaml must include bridge package pattern ${workspacePackage.pattern}`,
1656
+ );
1657
+ }
1658
+ for (const gate of bridgeConfig.gates ?? []) {
1659
+ const expectedGateScript = `${gate.cwd ? `cd ${gate.cwd} && ` : ''}${gate.command}`;
1660
+ assert(
1661
+ rootPackage.scripts?.[`bridge:${gate.name}`] === expectedGateScript,
1662
+ `Bridge gate script bridge:${gate.name} is incorrect`,
1663
+ );
1664
+ }
1665
+ assert(rootPackage.scripts?.['bridge:check'], 'Bridge workspaces must expose bridge:check');
1666
+ } else {
1667
+ assert(rootPackage.scripts?.typecheck === 'node ./scripts/ultramodern-typecheck.mjs --build tsconfig.json', 'Root typecheck must run TS-Go build mode across project references');
1668
+ }
811
1669
  assert(rootPackage.scripts?.['contract:check'] === 'node ./scripts/validate-ultramodern-workspace.mjs', 'Root must expose contract:check');
1670
+ assert(rootPackage.scripts?.['api:check'] === 'node ./scripts/check-ultramodern-api-boundaries.mjs', 'Root must expose api:check');
812
1671
  assert(rootPackage.scripts?.['i18n:boundaries'] === 'node ./scripts/check-ultramodern-i18n-boundaries.mjs', 'Root must expose i18n:boundaries');
813
1672
  assert(rootPackage.scripts?.['performance:readiness'] === 'node ./scripts/ultramodern-performance-readiness.mjs', 'Root must expose default-on performance readiness diagnostics');
814
- assert(rootPackage.scripts?.check?.endsWith('&& pnpm performance:readiness'), 'Root check must run default-on performance readiness diagnostics');
1673
+ assert(
1674
+ bridgeConfig
1675
+ ? rootPackage.scripts?.check?.includes('pnpm api:check') &&
1676
+ rootPackage.scripts.check.endsWith('&& pnpm performance:readiness && pnpm bridge:check')
1677
+ : rootPackage.scripts?.check?.includes('pnpm api:check') &&
1678
+ rootPackage.scripts.check.endsWith('&& pnpm performance:readiness'),
1679
+ 'Root check must run default-on performance readiness diagnostics and bridge gates when configured',
1680
+ );
815
1681
  const performanceReadinessConfig = readText('scripts/ultramodern-performance-readiness.config.mjs');
816
- const performanceReadinessScript = readText('scripts/ultramodern-performance-readiness.mjs');
1682
+ const assertToolWrapper = (scriptPath, command) => {
1683
+ const source = readText(scriptPath);
1684
+ assert(source.includes('modern-js-create'), `${scriptPath} must delegate to modern-js-create`);
1685
+ assert(source.includes('ULTRAMODERN_CREATE_BIN'), `${scriptPath} must support local create-bin overrides for generated-workspace tests`);
1686
+ assert(source.includes("'ultramodern'") || source.includes('"ultramodern"'), `${scriptPath} must dispatch through the UltraModern tool surface`);
1687
+ assert(source.includes(command), `${scriptPath} must dispatch ${command}`);
1688
+ };
817
1689
  assert(performanceReadinessConfig.includes('UltramodernPerformanceReadinessDiagnosticsConfig'), 'Performance readiness config must carry the typed opt-out surface');
818
1690
  assert(performanceReadinessConfig.includes('enabled: true'), 'Performance readiness diagnostics must be default-on');
819
1691
  assert(performanceReadinessConfig.includes("failOn: 'framework-invariant'"), 'Performance readiness diagnostics must only fail framework invariants by default');
820
- assert(performanceReadinessScript.includes("ULTRAMODERN_PERFORMANCE_READINESS_DIAGNOSTICS"), 'Performance readiness script must support env opt-out');
821
- assert(performanceReadinessScript.includes('ultramodern-performance-readiness-diagnostics-v1'), 'Performance readiness script must emit the deterministic report profile');
1692
+ assertToolWrapper('scripts/validate-ultramodern-workspace.mjs', 'validate');
1693
+ assertToolWrapper('scripts/ultramodern-performance-readiness.mjs', 'performance-readiness');
822
1694
  const i18nBoundaryScript = readText('scripts/check-ultramodern-i18n-boundaries.mjs');
823
- const ultramodernTypecheckScript = readText('scripts/ultramodern-typecheck.mjs');
824
- assert(ultramodernTypecheckScript.includes("'--checkers'") && ultramodernTypecheckScript.includes("'--builders'"), 'Root typecheck script must drive TS-Go checker and builder parallelism');
825
- assert(ultramodernTypecheckScript.includes('effect-tsgo') && ultramodernTypecheckScript.includes('get-exe-path'), 'Root typecheck script must resolve the @effect/tsgo native-preview binary');
1695
+ assertToolWrapper('scripts/ultramodern-typecheck.mjs', 'typecheck');
826
1696
  assert(
827
1697
  i18nBoundaryScript.includes("from '@modern-js/code-tools'") &&
828
1698
  i18nBoundaryScript.includes('runWorkspaceSourceCheck'),
@@ -833,10 +1703,13 @@ assert(rootPackage.scripts?.['cloudflare:deploy'] === expectedCloudflareDeploySc
833
1703
  assert(rootPackage.scripts?.['cloudflare:proof'] === 'node ./scripts/proof-cloudflare-version.mjs --out .codex/reports/cloudflare-version-proof/public-url-proof.json', 'Root must expose cloudflare:proof');
834
1704
  assert(rootPackage.scripts?.['skills:install'] === 'node ./scripts/bootstrap-agent-skills.mjs', 'Root must expose skills:install');
835
1705
  assert(rootPackage.scripts?.['skills:check'] === 'node ./scripts/bootstrap-agent-skills.mjs --check', 'Root must expose skills:check');
836
- assert(rootPackage.scripts?.postinstall === "oxfmt . '!repos/**' && node ./scripts/bootstrap-agent-skills.mjs --postinstall", 'Root postinstall must only format and run the clone-free skills bootstrap; repository clones are explicit opt-in steps');
1706
+ assert(rootPackage.scripts?.postinstall === "oxfmt . '!repos/**' && node ./scripts/bootstrap-agent-skills.mjs --postinstall", 'Root postinstall must format, run the default-on Codex skills bootstrap, and leave reference repository installs explicit');
837
1707
  assert(rootPackage.scripts?.['agents:refs:install'] === 'node ./scripts/setup-agent-reference-repos.mjs', 'Root must expose agents:refs:install as the explicit reference repo installer');
838
1708
  const agentSkillsBootstrap = readText('scripts/bootstrap-agent-skills.mjs');
839
- assert(agentSkillsBootstrap.includes('never installs system packages'), 'Agent skills bootstrap must declare the no-system-install policy');
1709
+ assertToolWrapper('scripts/assert-mf-types.mjs', 'mf-types');
1710
+ assertToolWrapper('scripts/generate-public-surface-assets.mjs', 'public-surface');
1711
+ assertToolWrapper('scripts/proof-cloudflare-version.mjs', 'cloudflare-proof');
1712
+ assertToolWrapper('scripts/bootstrap-agent-skills.mjs', 'skills');
840
1713
  assert(!agentSkillsBootstrap.includes("run('brew'") && !agentSkillsBootstrap.includes('runShell('), 'Agent skills bootstrap must never invoke system package managers');
841
1714
  const agentReferenceRepoSetup = readText('scripts/setup-agent-reference-repos.mjs');
842
1715
  assert(agentReferenceRepoSetup.includes("['commit', '--no-verify', '-m', message]"), 'Agent reference repo installer commits must skip hooks during postinstall');
@@ -875,6 +1748,7 @@ assert(generatedContract.performanceReadiness?.optOut?.env === 'ULTRAMODERN_PERF
875
1748
  assert(JSON.stringify(generatedContract.performanceReadiness?.signals?.map(signal => signal.id)) === JSON.stringify(expectedPerformanceReadinessSignals), 'Performance readiness signal ids are incorrect');
876
1749
 
877
1750
  const shellModernConfig = readText('apps/shell-super-app/modern.config.ts');
1751
+ const shellModuleFederationConfig = readText('apps/shell-super-app/module-federation.config.ts');
878
1752
  const shellRouteHead = readText('apps/shell-super-app/src/routes/ultramodern-route-head.tsx');
879
1753
  const shellRouteMetadata = readText('apps/shell-super-app/src/routes/ultramodern-route-metadata.ts');
880
1754
  assert(shellRouteMetadata.includes('@generated by @modern-js/create'), 'Shell route metadata compatibility manifest must be marked generated');
@@ -909,8 +1783,9 @@ assert(shellModernConfig.includes('name: cloudflareWorkerName'), 'Shell modern.c
909
1783
  assert(shellModernConfig.includes('const assetPrefix ='), 'Shell modern.config.ts must derive a dedicated asset prefix');
910
1784
  assert(shellModernConfig.includes("const configuredUltramodernAssetPrefix = envValue('ULTRAMODERN_ASSET_PREFIX')"), 'Shell asset prefix must support ULTRAMODERN_ASSET_PREFIX');
911
1785
  assert(shellModernConfig.includes("const configuredModernAssetPrefix = envValue('MODERN_ASSET_PREFIX')"), 'Shell asset prefix must support MODERN_ASSET_PREFIX');
1786
+ assert(shellModernConfig.includes("const defaultAssetPrefix = '/'"), 'Shell asset prefix must default to origin-relative assets');
912
1787
  const shellAssetPrefixExpression = extractAssetPrefixExpression(shellModernConfig);
913
- assert(shellAssetPrefixExpression.includes("configuredModernAssetPrefix || configuredUltramodernAssetPrefix || '/'"), 'Shell asset prefix fallback order is incorrect');
1788
+ assert(shellAssetPrefixExpression.includes("configuredModernAssetPrefix || configuredUltramodernAssetPrefix || defaultAssetPrefix"), 'Shell asset prefix fallback order is incorrect');
914
1789
  assert(!shellAssetPrefixExpression.includes('configuredSiteUrl') && !shellAssetPrefixExpression.includes('MODERN_PUBLIC_SITE_URL'), 'Shell asset prefix must not fall back to MODERN_PUBLIC_SITE_URL');
915
1790
  assert(!shellAssetPrefixExpression.includes('configuredCloudflareUrl') && !shellAssetPrefixExpression.includes('ULTRAMODERN_PUBLIC_URL_SHELL_SUPER_APP'), 'Shell asset prefix must not fall back to the per-app public URL');
916
1791
  assert(!shellAssetPrefixExpression.includes('inferredCloudflareUrl') && !shellAssetPrefixExpression.includes('ULTRAMODERN_CLOUDFLARE_WORKERS_DEV_SUBDOMAIN'), 'Shell asset prefix must not infer workers.dev URLs');
@@ -926,6 +1801,9 @@ assert(shellContract?.config?.performance?.readinessDiagnostics?.optOut?.env ===
926
1801
  assert(JSON.stringify(shellContract?.config?.source?.siteUrl?.envFallbackOrder) === JSON.stringify(['MODERN_PUBLIC_SITE_URL', 'ULTRAMODERN_PUBLIC_URL_SHELL_SUPER_APP', 'ULTRAMODERN_CLOUDFLARE_WORKERS_DEV_SUBDOMAIN', 'SHELL_SUPER_APP_PORT']), 'Shell site URL env fallback order is incorrect');
927
1802
  assert(shellContract?.config?.rspack?.output?.uniqueName === 'shellSuperApp', 'Shell Rspack uniqueName is incorrect');
928
1803
  assert(shellContract?.config?.rspack?.output?.chunkLoadingGlobal === expectedChunkLoadingGlobal('shellSuperApp'), 'Shell Rspack chunkLoadingGlobal is incorrect');
1804
+ assert(shellContract?.moduleFederation?.dts?.compilerInstance === 'tsgo', 'Shell must keep mandatory DTS compiler');
1805
+ assert(shellContract?.moduleFederation?.dts?.tsConfigPath === './tsconfig.mf-types.json', 'Shell must keep dedicated Module Federation DTS tsconfig');
1806
+ assert(shellModuleFederationConfig.includes("tsConfigPath: './tsconfig.mf-types.json'"), 'Shell Module Federation config must use the dedicated DTS tsconfig');
929
1807
  assert(topology.shell?.cloudflare?.workerName === expectedWorkerName('shell-super-app'), 'Shell topology Cloudflare workerName is incorrect');
930
1808
  assert(shellContract?.styling?.federation?.owner?.id === 'shell-super-app', 'Shell CSS federation owner is missing');
931
1809
  assert(shellContract?.styling?.federation?.role === 'shell-base-overlay', 'Shell must own base and overlay CSS');
@@ -960,6 +1838,7 @@ assert(!('effectServices' in topology), 'Default APIs must be vertical-owned, no
960
1838
  for (const vertical of fullStackVerticals) {
961
1839
  const packageJson = readJson(`${vertical.path}/package.json`);
962
1840
  const modernConfig = readText(`${vertical.path}/modern.config.ts`);
1841
+ const moduleFederationConfig = readText(`${vertical.path}/module-federation.config.ts`);
963
1842
  const routeHead = readText(`${vertical.path}/src/routes/ultramodern-route-head.tsx`);
964
1843
  const routeMetadata = readText(`${vertical.path}/src/routes/ultramodern-route-metadata.ts`);
965
1844
  assert(routeMetadata.includes('@generated by @modern-js/create'), `${vertical.id} route metadata compatibility manifest must be marked generated`);
@@ -972,8 +1851,8 @@ for (const vertical of fullStackVerticals) {
972
1851
  assert(packageJson.dependencies?.['@modern-js/plugin-i18n'] === expectedModernPackageSpecifier('@modern-js/plugin-i18n'), `${vertical.id} plugin-i18n dependency must match package source metadata`);
973
1852
  assert(packageJson.dependencies?.['@modern-js/plugin-tanstack'] === expectedModernPackageSpecifier('@modern-js/plugin-tanstack'), `${vertical.id} plugin-tanstack dependency must match package source metadata`);
974
1853
  assert(packageJson.dependencies?.['@modern-js/runtime'] === expectedModernPackageSpecifier('@modern-js/runtime'), `${vertical.id} runtime dependency must match package source metadata`);
975
- assert(packageJson.exports?.['./effect/client'] === `./src/effect/${vertical.stem}-client.ts`, `${vertical.id} must export its Effect client`);
976
- assert(packageJson.exports?.['./shared/effect/api'] === './shared/effect/api.ts', `${vertical.id} must export its Effect API contract`);
1854
+ assert(packageJson.exports?.['./api/client'] === `./src/api/${vertical.stem}-client.ts`, `${vertical.id} must export its API client`);
1855
+ assert(packageJson.exports?.['./api'] === './shared/api.ts', `${vertical.id} must export its API contract`);
977
1856
  const expectedVerticalZephyrDependencies = Object.fromEntries(
978
1857
  fullStackVerticals
979
1858
  .filter(candidate => vertical.verticalRefs.includes(candidate.id))
@@ -1004,38 +1883,44 @@ for (const vertical of fullStackVerticals) {
1004
1883
  assert(modernConfig.includes('const assetPrefix ='), `${vertical.id} modern.config.ts must derive a dedicated asset prefix`);
1005
1884
  assert(modernConfig.includes("const configuredUltramodernAssetPrefix = envValue('ULTRAMODERN_ASSET_PREFIX')"), `${vertical.id} asset prefix must support ULTRAMODERN_ASSET_PREFIX`);
1006
1885
  assert(modernConfig.includes("const configuredModernAssetPrefix = envValue('MODERN_ASSET_PREFIX')"), `${vertical.id} asset prefix must support MODERN_ASSET_PREFIX`);
1886
+ assert(modernConfig.includes('const defaultRemoteAssetPrefix'), `${vertical.id} asset prefix must derive the remote asset origin`);
1887
+ assert(modernConfig.includes('const defaultAssetPrefix = defaultRemoteAssetPrefix'), `${vertical.id} asset prefix must default to its own remote origin`);
1007
1888
  const verticalAssetPrefixExpression = extractAssetPrefixExpression(modernConfig);
1008
- assert(verticalAssetPrefixExpression.includes("configuredModernAssetPrefix || configuredUltramodernAssetPrefix || '/'"), `${vertical.id} asset prefix fallback order is incorrect`);
1889
+ assert(verticalAssetPrefixExpression.includes("configuredModernAssetPrefix || configuredUltramodernAssetPrefix || defaultAssetPrefix"), `${vertical.id} asset prefix fallback order is incorrect`);
1009
1890
  assert(!verticalAssetPrefixExpression.includes('configuredSiteUrl') && !verticalAssetPrefixExpression.includes('MODERN_PUBLIC_SITE_URL'), `${vertical.id} asset prefix must not fall back to MODERN_PUBLIC_SITE_URL`);
1010
- assert(!verticalAssetPrefixExpression.includes('configuredCloudflareUrl') && !verticalAssetPrefixExpression.includes(`ULTRAMODERN_PUBLIC_URL_${vertical.id.replace(/-/g, '_').toUpperCase()}`), `${vertical.id} asset prefix must not fall back to the per-app public URL`);
1011
- assert(!verticalAssetPrefixExpression.includes('inferredCloudflareUrl') && !verticalAssetPrefixExpression.includes('ULTRAMODERN_CLOUDFLARE_WORKERS_DEV_SUBDOMAIN'), `${vertical.id} asset prefix must not infer workers.dev URLs`);
1891
+ assert(modernConfig.includes(`envValue('ULTRAMODERN_PUBLIC_URL_${vertical.id.replace(/-/g, '_').toUpperCase()}')`), `${vertical.id} asset prefix must read its per-app public URL`);
1892
+ assert(modernConfig.includes('inferredCloudflareUrl'), `${vertical.id} asset prefix must support workers.dev origin inference`);
1012
1893
  assert(modernConfig.includes("assetPrefix: '/'"), `${vertical.id} modern.config.ts must keep dev assets origin-relative`);
1013
1894
  assert(modernConfig.includes('assetPrefix,'), `${vertical.id} modern.config.ts must wire output.assetPrefix to the derived asset prefix`);
1014
1895
  assert(contractEntry?.config?.dev?.assetPrefix === '/', `${vertical.id} dev asset prefix must stay origin-relative`);
1015
- assert(contractEntry?.config?.output?.assetPrefix?.default === '/', `${vertical.id} asset prefix must default to origin-relative paths`);
1896
+ assert(contractEntry?.config?.output?.assetPrefix?.default === 'app-public-origin', `${vertical.id} asset prefix must default to its app public origin`);
1016
1897
  assert(JSON.stringify(contractEntry?.config?.output?.assetPrefix?.envFallbackOrder) === JSON.stringify(['MODERN_ASSET_PREFIX', 'ULTRAMODERN_ASSET_PREFIX']), `${vertical.id} asset prefix env fallback order is incorrect`);
1017
1898
  assert(contractEntry?.config?.output?.disableTsChecker === false, `${vertical.id} must keep the framework TypeScript checker enabled`);
1018
1899
  assert(contractEntry?.config?.performance?.readinessDiagnostics?.default === 'enabled', `${vertical.id} performance readiness diagnostics must be default-on`);
1019
1900
  assert(contractEntry?.config?.performance?.readinessDiagnostics?.failOn === 'framework-invariant', `${vertical.id} performance readiness diagnostics must only fail framework invariants by default`);
1020
1901
  assert(contractEntry?.config?.performance?.readinessDiagnostics?.optOut?.config === 'scripts/ultramodern-performance-readiness.config.mjs', `${vertical.id} performance readiness opt-out config is incorrect`);
1021
- assert(contractEntry?.deploy?.cloudflare?.routes?.effectReadiness === `${vertical.apiPrefix}/effect/${vertical.stem}/readiness`, `${vertical.id} Cloudflare proof readiness route is incorrect`);
1902
+ assert(contractEntry?.deploy?.cloudflare?.routes?.apiReadiness === `${vertical.apiPrefix}/${vertical.stem}/readiness`, `${vertical.id} Cloudflare proof readiness route is incorrect`);
1022
1903
  assert(contractEntry?.config?.rspack?.output?.uniqueName === vertical.mfName, `${vertical.id} Rspack uniqueName is incorrect`);
1023
1904
  assert(contractEntry?.config?.rspack?.output?.chunkLoadingGlobal === expectedChunkLoadingGlobal(vertical.mfName), `${vertical.id} Rspack chunkLoadingGlobal is incorrect`);
1024
1905
  assert(contractEntry?.moduleFederation?.name === vertical.mfName, `${vertical.id} MF name is incorrect`);
1025
1906
  assert(JSON.stringify(contractEntry?.moduleFederation?.exposes) === JSON.stringify(vertical.exposes), `${vertical.id} MF exposes are incorrect`);
1026
1907
  assert(contractEntry?.moduleFederation?.dts?.compilerInstance === 'tsgo', `${vertical.id} must keep mandatory DTS compiler`);
1908
+ assert(contractEntry?.moduleFederation?.dts?.tsConfigPath === './tsconfig.mf-types.json', `${vertical.id} must keep dedicated Module Federation DTS tsconfig`);
1909
+ assert(moduleFederationConfig.includes("tsConfigPath: './tsconfig.mf-types.json'"), `${vertical.id} Module Federation config must use the dedicated DTS tsconfig`);
1027
1910
  assert(JSON.stringify(contractEntry?.moduleFederation?.verticalRefs ?? []) === JSON.stringify(vertical.verticalRefs), `${vertical.id} MF verticalRefs are incorrect`);
1028
1911
  assert(
1029
1912
  JSON.stringify((contractEntry?.moduleFederation?.remotes ?? []).map(remote => remote.id)) ===
1030
1913
  JSON.stringify(vertical.verticalRefs),
1031
1914
  `${vertical.id} MF consumed verticals are incorrect`,
1032
1915
  );
1033
- assert(contractEntry?.effect?.prefix === vertical.apiPrefix, `${vertical.id} Effect API prefix is incorrect`);
1034
- assert(contractEntry?.effect?.group === vertical.group, `${vertical.id} Effect group is incorrect`);
1035
- assert(contractEntry?.effect?.readiness?.endpoint === `/effect/${vertical.stem}/readiness`, `${vertical.id} readiness endpoint is incorrect`);
1036
- assert(contractEntry?.effect?.operations?.readiness?.path === `/effect/${vertical.stem}/readiness`, `${vertical.id} readiness operation is missing`);
1037
- assert(contractEntry?.effect?.requestContext?.propagatedHeaders?.includes('traceparent'), `${vertical.id} trace context propagation is missing`);
1038
- assert(Object.keys(contractEntry?.effect?.domainOperations ?? {}).length >= 3, `${vertical.id} domain operations are missing`);
1916
+ assert(contractEntry?.api?.prefix === vertical.apiPrefix, `${vertical.id} API prefix is incorrect`);
1917
+ assert(contractEntry?.api?.group === vertical.group, `${vertical.id} API group is incorrect`);
1918
+ assert(contractEntry?.api?.runtime === 'effect', `${vertical.id} API runtime must be Effect`);
1919
+ assert(contractEntry?.api?.strictEffectApproach === true, `${vertical.id} strictEffectApproach must be enabled`);
1920
+ assert(contractEntry?.api?.readiness?.endpoint === `/${vertical.stem}/readiness`, `${vertical.id} readiness endpoint is incorrect`);
1921
+ assert(contractEntry?.api?.operations?.readiness?.path === `/${vertical.stem}/readiness`, `${vertical.id} readiness operation is missing`);
1922
+ assert(contractEntry?.api?.requestContext?.propagatedHeaders?.includes('traceparent'), `${vertical.id} trace context propagation is missing`);
1923
+ assert(Object.keys(contractEntry?.api?.domainOperations ?? {}).length >= 3, `${vertical.id} domain operations are missing`);
1039
1924
  assert(contractEntry?.i18n?.languages?.includes('en') && contractEntry?.i18n?.languages?.includes('cs'), `${vertical.id} must declare i18n languages`);
1040
1925
  assert(contractEntry?.i18n?.namespace === vertical.namespace, `${vertical.id} i18n namespace is incorrect`);
1041
1926
  assert(
@@ -1074,10 +1959,11 @@ for (const vertical of fullStackVerticals) {
1074
1959
  assert(topologyEntry?.moduleFederation?.name === vertical.mfName, `${vertical.id} topology MF name is incorrect`);
1075
1960
  assert(JSON.stringify(topologyEntry?.moduleFederation?.exposes) === JSON.stringify(vertical.exposes), `${vertical.id} topology exposes are incorrect`);
1076
1961
  assert(JSON.stringify(topologyEntry?.moduleFederation?.verticalRefs ?? []) === JSON.stringify(vertical.verticalRefs), `${vertical.id} topology verticalRefs are incorrect`);
1077
- assert(topologyEntry?.api?.effect?.bff?.prefix === vertical.apiPrefix, `${vertical.id} topology API prefix is incorrect`);
1078
- assert(topologyEntry?.api?.effect?.serverEntry === `${vertical.path}/api/effect/index.ts`, `${vertical.id} topology server entry is incorrect`);
1079
- assert(topologyEntry?.api?.effect?.readiness?.endpoint === `/effect/${vertical.stem}/readiness`, `${vertical.id} topology readiness endpoint is incorrect`);
1080
- assert(Object.keys(topologyEntry?.api?.effect?.domainOperations ?? {}).length >= 3, `${vertical.id} topology domain operations are missing`);
1962
+ assert(topologyEntry?.api?.bff?.prefix === vertical.apiPrefix, `${vertical.id} topology API prefix is incorrect`);
1963
+ assert(topologyEntry?.api?.bff?.strictEffectApproach === true, `${vertical.id} topology strictEffectApproach is incorrect`);
1964
+ assert(topologyEntry?.api?.serverEntry === `${vertical.path}/api/index.ts`, `${vertical.id} topology server entry is incorrect`);
1965
+ assert(topologyEntry?.api?.readiness?.endpoint === `/${vertical.stem}/readiness`, `${vertical.id} topology readiness endpoint is incorrect`);
1966
+ assert(Object.keys(topologyEntry?.api?.domainOperations ?? {}).length >= 3, `${vertical.id} topology domain operations are missing`);
1081
1967
 
1082
1968
  assert(ownership.owners?.some(owner => owner.id === vertical.id && owner.path === vertical.path), `${vertical.id} ownership entry is missing`);
1083
1969
  assert(overlay.ports?.[vertical.id], `${vertical.id} development port is missing`);