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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/README.md +35 -12
  2. package/dist/cjs/create-package-root.cjs +7 -9
  3. package/dist/cjs/index.cjs +74 -44
  4. package/dist/cjs/locale/en.cjs +6 -7
  5. package/dist/cjs/locale/zh.cjs +6 -7
  6. package/dist/cjs/ultramodern-workspace/add-vertical.cjs +337 -0
  7. package/dist/cjs/ultramodern-workspace/app-files.cjs +223 -0
  8. package/dist/cjs/ultramodern-workspace/contracts.cjs +836 -0
  9. package/dist/cjs/ultramodern-workspace/demo-components.cjs +422 -0
  10. package/dist/cjs/ultramodern-workspace/descriptors.cjs +222 -0
  11. package/dist/cjs/ultramodern-workspace/effect-api.cjs +952 -0
  12. package/dist/cjs/ultramodern-workspace/fs-io.cjs +191 -0
  13. package/dist/cjs/ultramodern-workspace/index.cjs +48 -0
  14. package/dist/cjs/ultramodern-workspace/locales.cjs +173 -0
  15. package/dist/cjs/ultramodern-workspace/module-federation.cjs +487 -0
  16. package/dist/cjs/ultramodern-workspace/naming.cjs +161 -0
  17. package/dist/cjs/ultramodern-workspace/package-json.cjs +406 -0
  18. package/dist/cjs/ultramodern-workspace/package-source.cjs +59 -0
  19. package/dist/cjs/ultramodern-workspace/policy.cjs +248 -0
  20. package/dist/cjs/ultramodern-workspace/public-surface.cjs +268 -0
  21. package/dist/cjs/ultramodern-workspace/routes.cjs +375 -0
  22. package/dist/cjs/ultramodern-workspace/types.cjs +61 -0
  23. package/dist/cjs/ultramodern-workspace/versions.cjs +153 -0
  24. package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +153 -0
  25. package/dist/cjs/ultramodern-workspace/write-workspace.cjs +175 -0
  26. package/dist/esm/create-package-root.js +7 -9
  27. package/dist/esm/index.js +72 -42
  28. package/dist/esm/locale/en.js +6 -7
  29. package/dist/esm/locale/zh.js +6 -7
  30. package/dist/esm/ultramodern-workspace/add-vertical.js +252 -0
  31. package/dist/esm/ultramodern-workspace/app-files.js +149 -0
  32. package/dist/esm/ultramodern-workspace/contracts.js +741 -0
  33. package/dist/esm/ultramodern-workspace/demo-components.js +363 -0
  34. package/dist/esm/ultramodern-workspace/descriptors.js +133 -0
  35. package/dist/esm/ultramodern-workspace/effect-api.js +854 -0
  36. package/dist/esm/ultramodern-workspace/fs-io.js +90 -0
  37. package/dist/esm/ultramodern-workspace/index.js +3 -0
  38. package/dist/esm/ultramodern-workspace/locales.js +122 -0
  39. package/dist/esm/ultramodern-workspace/module-federation.js +415 -0
  40. package/dist/esm/ultramodern-workspace/naming.js +71 -0
  41. package/dist/esm/ultramodern-workspace/package-json.js +338 -0
  42. package/dist/esm/ultramodern-workspace/package-source.js +21 -0
  43. package/dist/esm/ultramodern-workspace/policy.js +183 -0
  44. package/dist/esm/ultramodern-workspace/public-surface.js +183 -0
  45. package/dist/esm/ultramodern-workspace/routes.js +280 -0
  46. package/dist/esm/ultramodern-workspace/types.js +16 -0
  47. package/dist/esm/ultramodern-workspace/versions.js +34 -0
  48. package/dist/esm/ultramodern-workspace/workspace-scripts.js +91 -0
  49. package/dist/esm/ultramodern-workspace/write-workspace.js +121 -0
  50. package/dist/esm-node/create-package-root.js +7 -9
  51. package/dist/esm-node/index.js +72 -42
  52. package/dist/esm-node/locale/en.js +6 -7
  53. package/dist/esm-node/locale/zh.js +6 -7
  54. package/dist/esm-node/ultramodern-workspace/add-vertical.js +253 -0
  55. package/dist/esm-node/ultramodern-workspace/app-files.js +150 -0
  56. package/dist/esm-node/ultramodern-workspace/contracts.js +742 -0
  57. package/dist/esm-node/ultramodern-workspace/demo-components.js +364 -0
  58. package/dist/esm-node/ultramodern-workspace/descriptors.js +134 -0
  59. package/dist/esm-node/ultramodern-workspace/effect-api.js +855 -0
  60. package/dist/esm-node/ultramodern-workspace/fs-io.js +91 -0
  61. package/dist/esm-node/ultramodern-workspace/index.js +4 -0
  62. package/dist/esm-node/ultramodern-workspace/locales.js +123 -0
  63. package/dist/esm-node/ultramodern-workspace/module-federation.js +416 -0
  64. package/dist/esm-node/ultramodern-workspace/naming.js +72 -0
  65. package/dist/esm-node/ultramodern-workspace/package-json.js +339 -0
  66. package/dist/esm-node/ultramodern-workspace/package-source.js +22 -0
  67. package/dist/esm-node/ultramodern-workspace/policy.js +184 -0
  68. package/dist/esm-node/ultramodern-workspace/public-surface.js +184 -0
  69. package/dist/esm-node/ultramodern-workspace/routes.js +281 -0
  70. package/dist/esm-node/ultramodern-workspace/types.js +17 -0
  71. package/dist/esm-node/ultramodern-workspace/versions.js +35 -0
  72. package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +92 -0
  73. package/dist/esm-node/ultramodern-workspace/write-workspace.js +122 -0
  74. package/dist/types/locale/en.d.ts +4 -5
  75. package/dist/types/locale/index.d.ts +8 -10
  76. package/dist/types/locale/zh.d.ts +4 -5
  77. package/dist/types/ultramodern-workspace/add-vertical.d.ts +19 -0
  78. package/dist/types/ultramodern-workspace/app-files.d.ts +14 -0
  79. package/dist/types/ultramodern-workspace/contracts.d.ts +21 -0
  80. package/dist/types/ultramodern-workspace/demo-components.d.ts +9 -0
  81. package/dist/types/ultramodern-workspace/descriptors.d.ts +39 -0
  82. package/dist/types/ultramodern-workspace/effect-api.d.ts +73 -0
  83. package/dist/types/ultramodern-workspace/fs-io.d.ts +18 -0
  84. package/dist/types/ultramodern-workspace/index.d.ts +4 -0
  85. package/dist/types/ultramodern-workspace/locales.d.ts +183 -0
  86. package/dist/types/ultramodern-workspace/module-federation.d.ts +16 -0
  87. package/dist/types/ultramodern-workspace/naming.d.ts +16 -0
  88. package/dist/types/ultramodern-workspace/package-json.d.ts +12 -0
  89. package/dist/types/ultramodern-workspace/package-source.d.ts +2 -0
  90. package/dist/types/ultramodern-workspace/policy.d.ts +60 -0
  91. package/dist/types/ultramodern-workspace/public-surface.d.ts +37 -0
  92. package/dist/types/ultramodern-workspace/routes.d.ts +25 -0
  93. package/dist/types/ultramodern-workspace/types.d.ts +95 -0
  94. package/dist/types/ultramodern-workspace/versions.d.ts +38 -0
  95. package/dist/types/ultramodern-workspace/workspace-scripts.d.ts +10 -0
  96. package/dist/types/ultramodern-workspace/write-workspace.d.ts +4 -0
  97. package/package.json +4 -3
  98. package/template-workspace/.github/workflows/ultramodern-workspace-gates.yml.handlebars +1 -4
  99. package/template-workspace/.mise.toml.handlebars +1 -0
  100. package/template-workspace/{AGENTS.md → AGENTS.md.handlebars} +12 -7
  101. package/template-workspace/README.md.handlebars +40 -24
  102. package/template-workspace/{pnpm-workspace.yaml → pnpm-workspace.yaml.handlebars} +2 -2
  103. package/template-workspace/scripts/bootstrap-agent-skills.mjs +31 -51
  104. package/templates/app/shell-frame.tsx +49 -0
  105. package/templates/app/ultramodern-route-head.tsx.handlebars +142 -0
  106. package/templates/packages/shared-contracts-index.ts +466 -0
  107. package/templates/workspace-scripts/assert-mf-types.mjs.handlebars +69 -0
  108. package/templates/workspace-scripts/check-ultramodern-i18n-boundaries.mjs +9 -0
  109. package/templates/workspace-scripts/generate-public-surface-assets.mjs +529 -0
  110. package/templates/workspace-scripts/proof-cloudflare-version.mjs +125 -0
  111. package/templates/workspace-scripts/ultramodern-cloudflare-proof.mjs +851 -0
  112. package/templates/workspace-scripts/ultramodern-performance-readiness.config.mjs +7 -0
  113. package/templates/workspace-scripts/ultramodern-performance-readiness.mjs +223 -0
  114. package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +656 -0
  115. package/dist/cjs/ultramodern-workspace.cjs +0 -6797
  116. package/dist/esm/ultramodern-workspace.js +0 -6738
  117. package/dist/esm-node/ultramodern-workspace.js +0 -6739
  118. package/dist/types/ultramodern-workspace.d.ts +0 -29
@@ -0,0 +1,12 @@
1
+ import type { JsonValue, ResolvedPackageSource, WorkspaceApp } from './types';
2
+ export declare const effectTsgoTypecheckCommand = "node -e \"const fs = require('node:fs'); const { execFileSync, spawnSync } = require('node:child_process'); const bin = execFileSync('effect-tsgo', ['get-exe-path'], { encoding: 'utf8' }).trim(); if (process.platform !== 'win32') fs.chmodSync(bin, 0o755); const result = spawnSync(bin, ['--noEmit', '-p', 'tsconfig.json'], { stdio: 'inherit' }); process.exit(result.status ?? 1);\"";
3
+ export declare const effectDiagnostics: string[];
4
+ export declare function appDependencies(scope: string, packageSource: ResolvedPackageSource, app: WorkspaceApp, remotes?: WorkspaceApp[]): Record<string, string>;
5
+ export declare function appDevDependencies(packageSource: ResolvedPackageSource, enableTailwind: boolean): Record<string, string>;
6
+ export declare function createRootPackageJson(scope: string, packageSource: ResolvedPackageSource, remotes?: WorkspaceApp[]): JsonValue;
7
+ export declare function createZephyrDependencies(scope: string, app: WorkspaceApp, remotes?: WorkspaceApp[]): JsonValue;
8
+ export declare function createTsConfigBase(): JsonValue;
9
+ export declare function createPackageTsConfig(packageDir: string, includeApi?: boolean): JsonValue;
10
+ export declare function createAppPackage(scope: string, app: WorkspaceApp, packageSource: ResolvedPackageSource, enableTailwind: boolean, remotes?: WorkspaceApp[]): JsonValue;
11
+ export declare function createSharedPackage(scope: string, id: string, description: string): JsonValue;
12
+ export declare function createSharedContractsIndex(): string;
@@ -0,0 +1,2 @@
1
+ import type { ResolvedPackageSource, UltramodernWorkspaceOptions } from './types';
2
+ export declare function resolvePackageSource(options: UltramodernWorkspaceOptions): ResolvedPackageSource;
@@ -0,0 +1,60 @@
1
+ import type { JsonValue, WorkspaceApp } from './types';
2
+ export declare function createCloudflareProofRoute(app: WorkspaceApp): JsonValue;
3
+ export declare function createCloudflareSecurityContract(): JsonValue;
4
+ export declare const PUBLIC_WEBSITE_POLICY: {
5
+ qualityGates: {
6
+ publicRoutes: {
7
+ requireSitemapWhenPresent: boolean;
8
+ requireRobotsSitemapConsistency: boolean;
9
+ requireWebManifestWhenPresent: boolean;
10
+ };
11
+ statusCodes: {
12
+ notFoundRoute: string;
13
+ unknownRouteStatus: number;
14
+ };
15
+ indexing: {
16
+ previewNoindex: boolean;
17
+ productionPublicRoutesIndexable: boolean;
18
+ };
19
+ assets: {
20
+ cssPreloadRequired: boolean;
21
+ cssResponseRequired: boolean;
22
+ cacheControlRequiredForCss: boolean;
23
+ sourcemapsPubliclyReferenced: boolean;
24
+ };
25
+ budgets: {
26
+ ssrHtmlMaxBytes: number;
27
+ mfManifestMaxBytes: number;
28
+ localeJsonMaxBytes: number;
29
+ sitemapXmlMaxBytes: number;
30
+ cssAssetMaxBytes: number;
31
+ };
32
+ csp: {
33
+ finalMode: string;
34
+ decision: string;
35
+ };
36
+ };
37
+ publicHead: {
38
+ indexableRobots: string;
39
+ privateRouteRobots: string;
40
+ };
41
+ publicSurface: {
42
+ defaultProviderFile: string;
43
+ draftPolicy: string;
44
+ indexablePolicy: string;
45
+ };
46
+ };
47
+ export declare function formatTsJsonValue(value: JsonValue, indent: number): string;
48
+ export declare function formatIntegerCodeLiteral(value: number): string;
49
+ export declare function createPublicWebsiteQualityGateContract(): JsonValue;
50
+ export declare function createPublicWebsiteBudgetFallback(budgetName: keyof (typeof PUBLIC_WEBSITE_POLICY)['qualityGates']['budgets']): string;
51
+ export declare function createPublicHeadRobotsPolicy(): {
52
+ indexableRobots: string;
53
+ privateRouteRobots: string;
54
+ };
55
+ export declare function createPublicSurfaceContentExpansionPolicy(): {
56
+ defaultProviderFile: string;
57
+ draftPolicy: string;
58
+ indexablePolicy: string;
59
+ };
60
+ export declare function createCloudflareDeployContract(scope: string, app: WorkspaceApp): JsonValue;
@@ -0,0 +1,37 @@
1
+ import type { JsonValue, PublicRouteMetadata, PublicSurfaceSitemapFields, SupportedWorkspaceLanguage, WorkspaceApp } from './types';
2
+ export declare const publicSurfaceManagedSourceAssetPaths: readonly ['config/public/robots.txt', 'config/public/sitemap.xml', 'config/public/site.webmanifest'];
3
+ export declare const publicSurfaceBaseOutputFiles: readonly ['robots.txt'];
4
+ export declare const publicSurfacePublicRouteOutputFiles: readonly ['sitemap.xml', 'site.webmanifest'];
5
+ export type PublicSurfaceRouteEntry = PublicRouteMetadata & {
6
+ canonicalUrlPath: string;
7
+ localeUrlPaths: Record<SupportedWorkspaceLanguage, string>;
8
+ } & PublicSurfaceSitemapFields;
9
+ export declare function createLocalisedPublicPath(pathname: string, language: SupportedWorkspaceLanguage): string;
10
+ export declare function uniqueSorted(values: string[]): string[];
11
+ export declare function createPublicSurfaceRouteEntries(app: WorkspaceApp): PublicSurfaceRouteEntry[];
12
+ export declare function createPublicSurfaceUrlPaths(app: WorkspaceApp): string[];
13
+ export declare function createPublicSurfaceOutputFiles(app: WorkspaceApp): string[];
14
+ export type PublicSurfaceGenerationTarget = 'dist' | 'cloudflare';
15
+ export declare function createPublicSurfaceGenerationCommand(app: WorkspaceApp, target: PublicSurfaceGenerationTarget, requirePublicOrigin?: boolean): string;
16
+ /**
17
+ * Tombstone sweep: generated apps never ship hand-authored source assets under
18
+ * config/public, so reruns over an existing workspace remove any that crept
19
+ * in. The same path list feeds the generated validate script's assertions.
20
+ */
21
+ export declare function rewriteWorkspaceAssetsForApp(workspaceRoot: string, app: WorkspaceApp): void;
22
+ export declare function createPublicSurfaceContract(app: WorkspaceApp): JsonValue;
23
+ export declare function createPublicHeadContract(): JsonValue;
24
+ export type PublicWebGeneratedFile = {
25
+ path: string;
26
+ content: string;
27
+ };
28
+ export type PublicWebAppArtifacts = {
29
+ jsonLdHelperFile: PublicWebGeneratedFile;
30
+ routeMetadataFile: PublicWebGeneratedFile;
31
+ routeHeadFile: PublicWebGeneratedFile;
32
+ routeMetaFiles: PublicWebGeneratedFile[];
33
+ routeAliasFiles: PublicWebGeneratedFile[];
34
+ publicHead: JsonValue;
35
+ publicSurface: JsonValue;
36
+ };
37
+ export declare function createPublicWebAppArtifacts(app: WorkspaceApp): PublicWebAppArtifacts;
@@ -0,0 +1,25 @@
1
+ import type { JsonValue, PublicRouteMetadata, RouteOwnedI18nPath, WorkspaceApp } from './types';
2
+ export declare const privateAppRoutePublicness: {
3
+ readonly indexable: false;
4
+ readonly public: false;
5
+ readonly publicSurface: 'private-app-screen';
6
+ };
7
+ export declare function createRouteOwnedI18nPaths(app: WorkspaceApp): RouteOwnedI18nPath[];
8
+ export declare function isPublicIndexableRoute(route: RouteOwnedI18nPath): boolean;
9
+ export declare function createLocalisedUrlsMapFromRoutes(routes: RouteOwnedI18nPath[]): Record<string, JsonValue>;
10
+ export declare function createLocalisedUrlsMap(app: WorkspaceApp): Record<string, JsonValue>;
11
+ export declare function createPublicRouteMetadataFromRoutes(routes: RouteOwnedI18nPath[]): PublicRouteMetadata[];
12
+ export declare function createPublicRouteMetadata(app: WorkspaceApp): PublicRouteMetadata[];
13
+ export declare function createJsonLdHelperModule(): string;
14
+ export declare function createRouteMetadataModule(app: WorkspaceApp): string;
15
+ export declare function createRouteMetaModule(route: RouteOwnedI18nPath): string;
16
+ export declare function normalisePublicPath(pathname: string): string;
17
+ export declare function splitPublicPathSegments(pathname: string): string[];
18
+ export declare function routePathParamName(segment: string): string | undefined;
19
+ export declare function isDynamicPublicPathSegment(segment: string): boolean;
20
+ export declare function isConcretePublicPath(pathname: string): boolean;
21
+ export declare function routeSegmentToDirectory(segment: string): string;
22
+ export declare function routePathDirectorySegments(routePath: string): string[];
23
+ export declare function createRoutePageFilePath(app: WorkspaceApp, canonicalPath: string): string;
24
+ export declare function createRouteMetaFilePath(app: WorkspaceApp, canonicalPath: string): string;
25
+ export declare function createRouteAliasPage(canonicalPath: string): string;
@@ -0,0 +1,95 @@
1
+ import type { ResolvedUltramodernPackageSource, UltramodernPackageSourceStrategy } from '../ultramodern-package-source';
2
+ export type JsonValue = string | number | boolean | null | JsonValue[] | {
3
+ [key: string]: JsonValue;
4
+ };
5
+ export type JsonObject = {
6
+ [key: string]: JsonValue;
7
+ };
8
+ export type RouteJsonLd = JsonObject | JsonObject[];
9
+ export declare function sortJsonValue(value: JsonValue): JsonValue;
10
+ export type WorkspaceApp = {
11
+ id: string;
12
+ directory: string;
13
+ packageSuffix: string;
14
+ displayName: string;
15
+ kind: 'shell' | 'vertical';
16
+ domain?: string;
17
+ portEnv: string;
18
+ port: number;
19
+ mfName: string;
20
+ exposes?: Record<string, string>;
21
+ effectApi?: WorkspaceEffectApi;
22
+ verticalRefs?: string[];
23
+ ownership: Ownership;
24
+ };
25
+ export type WorkspaceEffectApi = {
26
+ stem: string;
27
+ prefix: string;
28
+ consumedBy: string[];
29
+ };
30
+ export type ResolvedPackageSource = ResolvedUltramodernPackageSource;
31
+ export type Ownership = {
32
+ team: string;
33
+ slack: string;
34
+ pagerDuty: string;
35
+ runbookRef: string;
36
+ adrRef: string;
37
+ blastRadius: {
38
+ tier: string;
39
+ references: string[];
40
+ };
41
+ };
42
+ export declare const supportedWorkspaceLanguages: readonly ['en', 'cs'];
43
+ export type SupportedWorkspaceLanguage = (typeof supportedWorkspaceLanguages)[number];
44
+ export type RoutePublicSurface = 'private-app-screen' | 'generated-public-surface' | 'explicit-public-input';
45
+ export type RouteOwnedI18nPath = {
46
+ id: string;
47
+ canonicalPath: string;
48
+ localisedPaths: Record<SupportedWorkspaceLanguage, string>;
49
+ titleKey: string;
50
+ descriptionKey: string;
51
+ ownerAppId: string;
52
+ mfBoundaryId: string;
53
+ namespace: string;
54
+ public: boolean;
55
+ indexable: boolean;
56
+ publicSurface: RoutePublicSurface;
57
+ jsonLd?: RouteJsonLd;
58
+ };
59
+ export type PublicRouteMetadata = {
60
+ canonicalPath: string;
61
+ id: string;
62
+ localisedPaths: Record<SupportedWorkspaceLanguage, string>;
63
+ namespace: string;
64
+ ownerAppId: string;
65
+ titleKey: string;
66
+ descriptionKey: string;
67
+ jsonLd?: RouteJsonLd;
68
+ };
69
+ export type PublicSitemapChangeFrequency = 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
70
+ export type PublicSurfaceSitemapFields = {
71
+ lastModified?: string;
72
+ changeFrequency?: PublicSitemapChangeFrequency;
73
+ priority?: number;
74
+ };
75
+ export type UltramodernWorkspaceOptions = {
76
+ targetDir: string;
77
+ packageName: string;
78
+ modernVersion: string;
79
+ enableTailwind?: boolean;
80
+ packageSource?: {
81
+ strategy?: UltramodernPackageSourceStrategy;
82
+ modernPackageVersion?: string;
83
+ registry?: string;
84
+ aliasScope?: string;
85
+ aliasPackageNamePrefix?: string;
86
+ };
87
+ };
88
+ export type AddUltramodernVerticalOptions = {
89
+ workspaceRoot: string;
90
+ name: string;
91
+ modernVersion: string;
92
+ enableTailwind?: boolean;
93
+ packageSource?: UltramodernWorkspaceOptions['packageSource'];
94
+ };
95
+ export declare function isRecord(value: unknown): value is Record<string, JsonValue>;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Every version pin and skill-repo commit hash baked into generated
3
+ * UltraModern workspaces lives here. Values must stay in lockstep with the
4
+ * checked-in templates under templates/ and template-workspace/.
5
+ */
6
+ export declare const TANSTACK_ROUTER_VERSION = "1.170.15";
7
+ export declare const MODULE_FEDERATION_VERSION = "2.5.1";
8
+ export declare const ZEPHYR_RSPACK_PLUGIN_VERSION = "1.1.1";
9
+ export declare const ZEPHYR_AGENT_VERSION = "1.1.1";
10
+ export declare const WRANGLER_VERSION = "4.99.0";
11
+ export declare const CLOUDFLARE_COMPATIBILITY_DATE = "2026-06-02";
12
+ export declare const TAILWIND_VERSION = "4.3.0";
13
+ export declare const TAILWIND_POSTCSS_VERSION = "4.3.0";
14
+ export declare const POSTCSS_VERSION = "8.5.15";
15
+ export declare const EFFECT_TSGO_VERSION = "0.14.3";
16
+ export declare const TYPESCRIPT_VERSION = "6.0.3";
17
+ export declare const TYPESCRIPT_NATIVE_PREVIEW_VERSION = "7.0.0-dev.20260610.1";
18
+ export declare const OXLINT_VERSION = "1.69.0";
19
+ export declare const OXFMT_VERSION = "0.54.0";
20
+ export declare const ULTRACITE_VERSION = "7.8.3";
21
+ export declare const LEFTHOOK_VERSION = "^2.1.9";
22
+ export declare const I18NEXT_VERSION = "26.3.1";
23
+ export declare const NODE_FETCH_VERSION = "^3.3.2";
24
+ export declare const REACT_VERSION = "^19.2.7";
25
+ export declare const REACT_DOM_VERSION = "^19.2.7";
26
+ export declare const REACT_ROUTER_DOM_VERSION = "7.17.0";
27
+ export declare const TYPES_REACT_VERSION = "^19.2.17";
28
+ export declare const TYPES_REACT_DOM_VERSION = "^19.2.3";
29
+ export declare const NODE_VERSION = "26.3.0";
30
+ export declare const PNPM_VERSION = "11.5.3";
31
+ export declare const RSTACK_AGENT_SKILLS_COMMIT = "61c948b42512e223bad44b83af4080eba48b2677";
32
+ export declare const MODULE_FEDERATION_AGENT_SKILLS_COMMIT = "07bb5b6c43ad457609e00c081b72d4c42508ec76";
33
+ export declare const ultramodernWorkspaceVersions: {
34
+ tanstackRouter: string;
35
+ moduleFederation: string;
36
+ tailwind: string;
37
+ tailwindPostcss: string;
38
+ };
@@ -0,0 +1,10 @@
1
+ import type { WorkspaceApp } from './types';
2
+ export declare function createAssertMfTypesScript(remotes?: WorkspaceApp[]): string;
3
+ export declare function createWorkspaceValidationScript(scope: string, enableTailwind: boolean, remotes?: WorkspaceApp[]): string;
4
+ export declare function createWorkspaceI18nBoundaryValidationScript(): string;
5
+ export declare function createPublicSurfaceAssetsScript(): string;
6
+ export declare function createCloudflareProofHelperScript(): string;
7
+ export declare function createCloudflareVersionProofScript(): string;
8
+ export declare function createPerformanceReadinessConfigScript(): string;
9
+ export declare function createPerformanceReadinessScript(): string;
10
+ export declare function writeGeneratedWorkspaceScripts(targetDir: string, scope: string, enableTailwind: boolean, remotes?: WorkspaceApp[]): void;
@@ -0,0 +1,4 @@
1
+ import type { ResolvedPackageSource, UltramodernWorkspaceOptions, WorkspaceApp } from './types';
2
+ export declare function writeApp(targetDir: string, scope: string, app: WorkspaceApp, packageSource: ResolvedPackageSource, enableTailwind: boolean, remotes?: WorkspaceApp[]): void;
3
+ export declare function writeSharedPackages(targetDir: string, scope: string): void;
4
+ export declare function generateUltramodernWorkspace(options: UltramodernWorkspaceOptions): void;
package/package.json CHANGED
@@ -21,7 +21,7 @@
21
21
  "engines": {
22
22
  "node": ">=20"
23
23
  },
24
- "version": "3.2.0-ultramodern.120",
24
+ "version": "3.2.0-ultramodern.122",
25
25
  "types": "./dist/types/index.d.ts",
26
26
  "main": "./dist/esm-node/index.js",
27
27
  "bin": {
@@ -47,11 +47,12 @@
47
47
  },
48
48
  "files": [
49
49
  "template-workspace",
50
+ "templates",
50
51
  "dist",
51
52
  "bin"
52
53
  ],
53
54
  "dependencies": {
54
- "@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.2.0-ultramodern.120"
55
+ "@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.2.0-ultramodern.122"
55
56
  },
56
57
  "devDependencies": {
57
58
  "@rslib/core": "0.22.0",
@@ -72,6 +73,6 @@
72
73
  "test": "rm -rf dist && rslib build -c rslibconfig.mts && rstest --passWithNoTests"
73
74
  },
74
75
  "ultramodern": {
75
- "frameworkVersion": "3.2.0-ultramodern.120"
76
+ "frameworkVersion": "3.2.0-ultramodern.122"
76
77
  }
77
78
  }
@@ -11,9 +11,6 @@ defaults:
11
11
  run:
12
12
  shell: bash
13
13
 
14
- env:
15
- FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
16
-
17
14
  concurrency:
18
15
  group: ultramodern-workspace-gates-${{ github.workflow }}-${{ github.ref }}
19
16
  cancel-in-progress: true
@@ -56,7 +53,7 @@ jobs:
56
53
  - name: Setup Node.js
57
54
  uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
58
55
  with:
59
- node-version: 24
56
+ node-version: "{{nodeVersion}}"
60
57
 
61
58
  - name: Setup mise
62
59
  uses: jdx/mise-action@5ac50f778e26fac95da98d50503682459e86d566 # v3.2.0
@@ -1,2 +1,3 @@
1
1
  [tools]
2
+ node = "{{nodeVersion}}"
2
3
  pnpm = "{{pnpmVersion}}"
@@ -6,6 +6,10 @@ instructions, not optional reading.
6
6
 
7
7
  ## Quality Gates
8
8
 
9
+ Generated workspaces target Node `>=26` and pnpm `{{pnpmVersion}}`. Keep
10
+ `packageManager`, `.mise.toml`, generated validation, and CI aligned to that
11
+ baseline; do not reintroduce Corepack or older pnpm aliases.
12
+
9
13
  - `pnpm lint` runs Oxlint with the Ultracite preset.
10
14
  - `pnpm format` runs oxfmt.
11
15
  - `pnpm typecheck` runs effect-tsgo as the TypeScript checker.
@@ -15,7 +19,7 @@ instructions, not optional reading.
15
19
  - `pnpm check` is a local convenience aggregate for the primitive gates.
16
20
  - Generated CI runs primitive gates as separate matrix jobs instead of calling `pnpm check`.
17
21
  - Generated Codex stop hooks and subagent-stop hooks run `pnpm format && pnpm lint:fix && pnpm check`.
18
- - `postinstall` formats the generated tree, initializes Git when needed, prepares agent skills and reference repos, then installs `lefthook`. Generated `lefthook.yml` runs separate format and lint-fix commands on pre-commit; pre-push runs read-only primitive gates in parallel.
22
+ - `postinstall` formats the generated tree and installs `lefthook`. It never clones repositories or installs system packages; agent skill repos and reference repos are explicit opt-in steps (`pnpm skills:install`, `pnpm agents:refs:install`). Generated `lefthook.yml` runs separate format and lint-fix commands on pre-commit; pre-push runs read-only primitive gates in parallel.
19
23
 
20
24
  ## Localized Routes
21
25
 
@@ -25,9 +29,10 @@ starts shell-only; `create <domain> --vertical` adds route-owned metadata,
25
29
  localized resources, and Effect BFF surfaces for that domain. Runtime i18n is
26
30
  not enabled in the starter because the current React 19 + Module Federation
27
31
  streaming SSR stack must render predictably first. Canonical and hreflang URLs
28
- use `MODERN_PUBLIC_SITE_URL` (falling back to per-app `ULTRAMODERN_PUBLIC_URL_<APP_ID>`),
29
- while asset URLs prefer the per-app `ULTRAMODERN_PUBLIC_URL_<APP_ID>`. Without
30
- any configured public URL, builds emit origin-relative asset paths so pages work
32
+ use `MODERN_PUBLIC_SITE_URL` only. JS/CSS/static assets use
33
+ `MODERN_ASSET_PREFIX`, then `ULTRAMODERN_ASSET_PREFIX`, then `/`; do not use
34
+ `MODERN_PUBLIC_SITE_URL` or stale public URL aliases as asset-prefix fallbacks.
35
+ Without an asset prefix, builds emit origin-relative asset paths so pages work
31
36
  behind tunnels and reverse proxies.
32
37
 
33
38
  ## Required Skill Baseline
@@ -43,7 +48,7 @@ Use these skills when the task touches the matching subsystem:
43
48
  - `rstest-best-practices`: Rstest configuration, test writing, mocking, snapshots, coverage, and CI test behavior.
44
49
  - `mf`: Module Federation docs, Modern.js integration, DTS/type checks, shared dependency checks, runtime errors, and observability troubleshooting.
45
50
 
46
- The public `module-federation/agent-skills` repository is installed during `pnpm install` and `pnpm skills:install`. Postinstall mode skips unavailable clone sources instead of blocking dependency installation; `pnpm skills:install` remains strict for required public skills. Use `ULTRAMODERN_SKIP_AGENT_SKILLS=1` when an install must avoid external skill repositories completely. `pnpm skills:check` fails when the required public `mf` skill is missing unless that skip flag is set.
51
+ The public `module-federation/agent-skills` repository is installed only when you explicitly run `pnpm skills:install` (or set `ULTRAMODERN_AGENT_SKILLS=1` before `pnpm install`). Postinstall never clones repositories. `pnpm skills:install` remains strict for required public skills. `pnpm skills:check` fails when a vendored skill is missing and warns when clone-installed skills such as `mf` have not been fetched yet.
47
52
 
48
53
  ## Private Skills
49
54
 
@@ -57,12 +62,12 @@ The installer copies only the pinned private skills from `.agents/skills-lock.js
57
62
 
58
63
  ## Agent Reference Repositories
59
64
 
60
- The workspace installs read-only source references under `repos/` by default during `pnpm install` using `git subtree add --squash`. These repositories are reference material for coding agents, not application source:
65
+ The workspace can install read-only source references under `repos/` with the explicit `pnpm agents:refs:install` command using `git subtree add --squash`. These repositories are reference material for coding agents, not application source:
61
66
 
62
67
  - `repos/effect` from `Effect-TS/effect`.
63
68
  - `repos/ultramodern.js` from `BleedingDev/ultramodern.js`.
64
69
 
65
- Agents may read files under `repos/` to understand upstream patterns, APIs, and project conventions. Do not edit files under `repos/`, import from them, or make production code depend on them. To skip this setup, run installs with `ULTRAMODERN_SKIP_AGENT_REPOS=1`.
70
+ Agents may read files under `repos/` to understand upstream patterns, APIs, and project conventions. Do not edit files under `repos/`, import from them, or make production code depend on them. `ULTRAMODERN_SKIP_AGENT_REPOS=1` disables the installer even when invoked explicitly.
66
71
 
67
72
  ## Project Priorities
68
73
 
@@ -7,8 +7,8 @@ UltraModern.js 3.0 SuperApp surface and starts with an explicit shell:
7
7
 
8
8
  - `apps/shell-super-app` owns shell route assembly, Module Federation host
9
9
  wiring, shared SSR/i18n runtime setup, and the boundary debugger.
10
- - `packages/shared-*` provide placeholders for cross-workspace contracts,
11
- design tokens, and Effect API sharing.
10
+ - `packages/shared-*` provide placeholders for cross-workspace contracts and
11
+ design tokens.
12
12
  - `verticals/*` is intentionally empty until a real business domain is added.
13
13
 
14
14
  Add a full-stack MicroVertical when the product needs one:
@@ -34,6 +34,13 @@ unless route metadata explicitly marks them `public && indexable`. The default
34
34
  scaffold therefore emits only a disallowing `robots.txt`; sitemap, web
35
35
  manifest, `llms.txt`, API catalog, security.txt, and JSON-LD output stay
36
36
  omitted until a safe public route or public docs/help/product surface exists.
37
+ Structured data is never inferred automatically. Add `jsonLd` explicitly in
38
+ route metadata for `public && indexable` routes and use
39
+ `src/routes/ultramodern-jsonld.ts` when the route fits the generated `WebPage`,
40
+ `WebApplication`, `SoftwareApplication`, `BreadcrumbList`, `FAQPage`, or
41
+ `Organization` helpers. Private or non-indexable routes emit no JSON-LD even
42
+ when they have localized paths, titles, descriptions, BFF APIs, or Module
43
+ Federation boundaries.
37
44
 
38
45
  Public web artifacts are build/deploy outputs generated into `dist/public` and
39
46
  `.output/public`, not hand-authored source files under `config/public`. Dynamic
@@ -53,21 +60,24 @@ pnpm check
53
60
  pnpm build
54
61
  ```
55
62
 
63
+ The generated toolchain baseline is Node `>=26` with pnpm `{{pnpmVersion}}`.
64
+ `packageManager`, `.mise.toml`, generated validation, and CI should all agree
65
+ on that baseline; do not reintroduce Corepack or older pnpm aliases.
66
+
56
67
  Generated CI does not call the local aggregate. It runs format, lint,
57
68
  typecheck, skills, i18n boundary validation, contract validation, and build as
58
69
  separate matrix jobs so failures are isolated and parallelizable.
59
70
 
60
- By default, `pnpm install` also prepares read-only agent reference repositories
61
- under `repos/` for Effect and UltraModern.js source lookup using squashed git
62
- subtrees. Disable this setup with
63
- `ULTRAMODERN_SKIP_AGENT_REPOS=1 pnpm install`, or rerun it
64
- explicitly with `pnpm agents:refs:install`.
71
+ Read-only agent reference repositories under `repos/` (Effect and
72
+ UltraModern.js source lookup using squashed git subtrees) are an explicit
73
+ opt-in step: run `pnpm agents:refs:install` when you want them. `pnpm install`
74
+ never clones repositories.
65
75
 
66
- Agent skills are prepared during `pnpm install` as a developer convenience.
67
- External skill repository failures do not block postinstall; strict installation
68
- is available with `pnpm skills:install`. Use
69
- `ULTRAMODERN_SKIP_AGENT_SKILLS=1` for a dependency install that avoids external
70
- skill repositories completely.
76
+ Vendored agent skills ship with the scaffold. Clone-installed skills (such as
77
+ the Module Federation `mf` skill) are fetched only when you explicitly run
78
+ `pnpm skills:install`, or when `ULTRAMODERN_AGENT_SKILLS=1` is set during
79
+ `pnpm install`. `pnpm skills:check` warns about missing clone-installed skills
80
+ without failing the gate.
71
81
 
72
82
  The topology and ownership metadata are generated under `topology/`. The
73
83
  workspace also ships `.github/workflows/ultramodern-workspace-gates.yml` and
@@ -85,25 +95,31 @@ packages still use `workspace:*` because they are part of this workspace.
85
95
 
86
96
  ## Public URL Environment Variables
87
97
 
88
- This workspace's apps no longer bake absolute `http://localhost:<port>` URLs
89
- into asset configuration. Two environment variables now have distinct roles in
90
- controlling where assets are served from and where SEO output links point.
98
+ This workspace's apps must not bake absolute `http://localhost:<port>` URLs
99
+ into asset configuration. Public URL and asset prefix environment variables
100
+ have distinct roles, and stale aliases should not be carried forward when
101
+ regenerating or updating the workspace.
91
102
 
92
103
  | Variable | Role | Feeds |
93
104
  | --- | --- | --- |
94
- | `ULTRAMODERN_PUBLIC_URL_<APP_ID>` | Per-app deployment and asset origin | `output.assetPrefix`, Module Federation remote URLs |
95
- | `MODERN_PUBLIC_SITE_URL` | Site-wide public origin for SEO output | Canonical, hreflang, sitemap `<loc>`, robots `Sitemap:` |
96
-
97
- Asset URLs use this precedence: `ULTRAMODERN_PUBLIC_URL_<APP_ID>`
98
- `MODERN_PUBLIC_SITE_URL` → inferred workers.dev URL → origin-relative `/`.
99
- SEO and site origin prefer: `MODERN_PUBLIC_SITE_URL` →
100
- `ULTRAMODERN_PUBLIC_URL_<APP_ID>`inferred workers.dev `http://localhost:<port>`.
105
+ | `MODERN_PUBLIC_SITE_URL` | Canonical site origin for public SEO output only | Canonical, hreflang, sitemap `<loc>`, robots `Sitemap:` |
106
+ | `MODERN_ASSET_PREFIX` | Preferred JS/CSS/static asset prefix | Modern/Rspack-emitted asset URLs |
107
+ | `ULTRAMODERN_ASSET_PREFIX` | UltraModern compatibility asset prefix | Modern/Rspack-emitted asset URLs when `MODERN_ASSET_PREFIX` is unset |
108
+ | `ULTRAMODERN_PUBLIC_URL_<APP_ID>` | Per-app deployment/proof URL | Cloudflare proof inputs and Module Federation remote URLs |
109
+
110
+ Asset URLs use this precedence: `MODERN_ASSET_PREFIX` →
111
+ `ULTRAMODERN_ASSET_PREFIX`origin-relative `/`. `MODERN_PUBLIC_SITE_URL` is
112
+ canonical/SEO-only and must not be used as an asset-prefix fallback.
113
+ SEO output uses `MODERN_PUBLIC_SITE_URL`; if it is unset, generated local and
114
+ preview outputs remain non-public until deployment proof provides explicit
115
+ public URLs.
101
116
 
102
117
  Without public URLs configured, asset paths are origin-relative (`/`), and the
103
118
  dev server uses `dev.assetPrefix: '/'` — so apps work through tunnels and
104
119
  reverse proxies (ngrok, cloudflared) without triggering Chrome's Local Network
105
- Access prompt or mixed-content errors. Shell-only workspaces can set just
106
- `MODERN_PUBLIC_SITE_URL` for SEO output.
120
+ Access prompt or mixed-content errors. Shell-only workspaces can set
121
+ `MODERN_PUBLIC_SITE_URL` for SEO output without changing where assets load
122
+ from.
107
123
 
108
124
  ## Cloudflare Proof
109
125
 
@@ -27,8 +27,8 @@ peerDependencyRules:
27
27
  typescript: '>=6.0.0'
28
28
 
29
29
  overrides:
30
- '@tanstack/react-router': 1.170.15
31
- node-fetch: '^3.3.2'
30
+ '@tanstack/react-router': {{tanstackRouterVersion}}
31
+ node-fetch: '{{nodeFetchVersion}}'
32
32
 
33
33
  allowBuilds:
34
34
  '@swc/core': true