@bleedingdev/modern-js-create 3.2.0-ultramodern.11 → 3.2.0-ultramodern.111
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.
- package/README.md +158 -35
- package/bin/run.js +0 -0
- package/dist/cjs/index.cjs +1042 -0
- package/dist/cjs/locale/en.cjs +97 -0
- package/dist/cjs/locale/index.cjs +50 -0
- package/dist/cjs/locale/zh.cjs +97 -0
- package/dist/cjs/ultramodern-package-source.cjs +135 -0
- package/dist/cjs/ultramodern-workspace.cjs +5623 -0
- package/dist/esm/index.js +1004 -0
- package/dist/esm/locale/en.js +59 -0
- package/dist/esm/locale/index.js +9 -0
- package/dist/esm/locale/zh.js +59 -0
- package/dist/esm/ultramodern-package-source.js +63 -0
- package/dist/esm/ultramodern-workspace.js +5561 -0
- package/dist/esm-node/index.js +1005 -0
- package/dist/esm-node/locale/en.js +60 -0
- package/dist/esm-node/locale/index.js +10 -0
- package/dist/esm-node/locale/zh.js +60 -0
- package/dist/esm-node/ultramodern-package-source.js +64 -0
- package/dist/esm-node/ultramodern-workspace.js +5562 -0
- package/dist/types/locale/en.d.ts +3 -0
- package/dist/types/locale/index.d.ts +117 -2
- package/dist/types/locale/zh.d.ts +3 -0
- package/dist/types/ultramodern-package-source.d.ts +28 -0
- package/dist/types/ultramodern-workspace.d.ts +12 -2
- package/package.json +27 -11
- package/template/.codex/hooks.json +16 -0
- package/template/.github/renovate.json +53 -0
- package/template/.github/workflows/ultramodern-gates.yml.handlebars +34 -10
- package/template/.mise.toml.handlebars +2 -0
- package/template/AGENTS.md +9 -6
- package/template/README.md +66 -34
- package/template/api/effect/index.ts.handlebars +20 -9
- package/template/api/lambda/hello.ts.handlebars +5 -5
- package/template/config/favicon.svg +5 -0
- package/template/config/public/assets/ultramodern-logo.svg +6 -0
- package/template/config/public/locales/cs/translation.json +44 -0
- package/template/config/public/locales/en/translation.json +44 -0
- package/template/lefthook.yml +10 -0
- package/template/modern.config.ts.handlebars +35 -3
- package/template/oxfmt.config.ts +8 -1
- package/template/oxlint.config.ts +8 -1
- package/template/package.json.handlebars +37 -30
- package/template/pnpm-workspace.yaml +34 -0
- package/template/rstest.config.mts +5 -0
- package/template/scripts/bootstrap-agent-skills.mjs +148 -15
- package/template/scripts/check-i18n-strings.mjs +3 -0
- package/template/scripts/validate-ultramodern.mjs.handlebars +495 -3
- package/template/src/modern-app-env.d.ts +2 -0
- package/template/src/modern.runtime.ts.handlebars +17 -1
- package/template/src/routes/[lang]/page.tsx.handlebars +209 -0
- package/template/src/routes/index.css.handlebars +192 -55
- package/template/src/routes/layout.tsx.handlebars +2 -1
- package/template/tailwind.config.ts.handlebars +1 -1
- package/template/tests/tsconfig.json +7 -0
- package/template/tests/ultramodern.contract.test.ts.handlebars +163 -0
- package/template/tsconfig.json +2 -1
- package/template-workspace/.agents/agent-reference-repos.json +24 -0
- package/template-workspace/.agents/skills-lock.json +19 -0
- package/template-workspace/.codex/hooks.json +16 -0
- package/template-workspace/.github/renovate.json +29 -0
- package/template-workspace/.github/workflows/ultramodern-workspace-gates.yml.handlebars +54 -0
- package/template-workspace/.gitignore.handlebars +5 -0
- package/template-workspace/.mise.toml.handlebars +2 -0
- package/template-workspace/AGENTS.md +36 -5
- package/template-workspace/README.md.handlebars +70 -11
- package/template-workspace/lefthook.yml +10 -0
- package/template-workspace/oxfmt.config.ts +1 -0
- package/template-workspace/oxlint.config.ts +1 -0
- package/template-workspace/pnpm-workspace.yaml +31 -8
- package/template-workspace/scripts/bootstrap-agent-skills.mjs +190 -21
- package/template-workspace/scripts/setup-agent-reference-repos.mjs +370 -0
- package/dist/index.js +0 -2474
- package/template/src/routes/page.tsx.handlebars +0 -136
- package/template-workspace/scripts/validate-ultramodern-workspace.mjs.handlebars +0 -405
|
@@ -35,6 +35,7 @@ export declare const EN_LOCALE: {
|
|
|
35
35
|
optionUltramodernPackageSource: string;
|
|
36
36
|
optionUltramodernPackageScope: string;
|
|
37
37
|
optionUltramodernPackageNamePrefix: string;
|
|
38
|
+
optionVertical: string;
|
|
38
39
|
optionSub: string;
|
|
39
40
|
examples: string;
|
|
40
41
|
example1: string;
|
|
@@ -47,6 +48,8 @@ export declare const EN_LOCALE: {
|
|
|
47
48
|
example8: string;
|
|
48
49
|
example9: string;
|
|
49
50
|
example10: string;
|
|
51
|
+
example11: string;
|
|
52
|
+
example12: string;
|
|
50
53
|
moreInfo: string;
|
|
51
54
|
};
|
|
52
55
|
version: {
|
|
@@ -1,3 +1,118 @@
|
|
|
1
|
-
|
|
2
|
-
declare const
|
|
1
|
+
import { I18n } from '@modern-js/i18n-utils';
|
|
2
|
+
declare const i18n: I18n;
|
|
3
|
+
declare const localeKeys: {
|
|
4
|
+
prompt: {
|
|
5
|
+
projectName: string;
|
|
6
|
+
};
|
|
7
|
+
error: {
|
|
8
|
+
projectNameEmpty: string;
|
|
9
|
+
directoryExists: string;
|
|
10
|
+
invalidRouter: string;
|
|
11
|
+
invalidBffRuntime: string;
|
|
12
|
+
createFailed: string;
|
|
13
|
+
};
|
|
14
|
+
message: {
|
|
15
|
+
welcome: string;
|
|
16
|
+
success: string;
|
|
17
|
+
nextSteps: string;
|
|
18
|
+
step1: string;
|
|
19
|
+
step2: string;
|
|
20
|
+
step3: string;
|
|
21
|
+
};
|
|
22
|
+
help: {
|
|
23
|
+
title: string;
|
|
24
|
+
description: string;
|
|
25
|
+
usage: string;
|
|
26
|
+
usageExample: string;
|
|
27
|
+
options: string;
|
|
28
|
+
optionHelp: string;
|
|
29
|
+
optionVersion: string;
|
|
30
|
+
optionLang: string;
|
|
31
|
+
optionRouter: string;
|
|
32
|
+
optionBff: string;
|
|
33
|
+
optionBffRuntime: string;
|
|
34
|
+
optionTailwind: string;
|
|
35
|
+
optionWorkspace: string;
|
|
36
|
+
optionUltramodernWorkspace: string;
|
|
37
|
+
optionUltramodernPackageSource: string;
|
|
38
|
+
optionUltramodernPackageScope: string;
|
|
39
|
+
optionUltramodernPackageNamePrefix: string;
|
|
40
|
+
optionVertical: string;
|
|
41
|
+
optionSub: string;
|
|
42
|
+
examples: string;
|
|
43
|
+
example1: string;
|
|
44
|
+
example2: string;
|
|
45
|
+
example3: string;
|
|
46
|
+
example4: string;
|
|
47
|
+
example5: string;
|
|
48
|
+
example6: string;
|
|
49
|
+
example7: string;
|
|
50
|
+
example8: string;
|
|
51
|
+
example9: string;
|
|
52
|
+
example10: string;
|
|
53
|
+
example11: string;
|
|
54
|
+
example12: string;
|
|
55
|
+
moreInfo: string;
|
|
56
|
+
};
|
|
57
|
+
version: {
|
|
58
|
+
message: string;
|
|
59
|
+
};
|
|
60
|
+
} | {
|
|
61
|
+
prompt: {
|
|
62
|
+
projectName: string;
|
|
63
|
+
};
|
|
64
|
+
error: {
|
|
65
|
+
projectNameEmpty: string;
|
|
66
|
+
directoryExists: string;
|
|
67
|
+
invalidRouter: string;
|
|
68
|
+
invalidBffRuntime: string;
|
|
69
|
+
createFailed: string;
|
|
70
|
+
};
|
|
71
|
+
message: {
|
|
72
|
+
welcome: string;
|
|
73
|
+
success: string;
|
|
74
|
+
nextSteps: string;
|
|
75
|
+
step1: string;
|
|
76
|
+
step2: string;
|
|
77
|
+
step3: string;
|
|
78
|
+
};
|
|
79
|
+
help: {
|
|
80
|
+
title: string;
|
|
81
|
+
description: string;
|
|
82
|
+
usage: string;
|
|
83
|
+
usageExample: string;
|
|
84
|
+
options: string;
|
|
85
|
+
optionHelp: string;
|
|
86
|
+
optionVersion: string;
|
|
87
|
+
optionLang: string;
|
|
88
|
+
optionRouter: string;
|
|
89
|
+
optionBff: string;
|
|
90
|
+
optionBffRuntime: string;
|
|
91
|
+
optionTailwind: string;
|
|
92
|
+
optionWorkspace: string;
|
|
93
|
+
optionUltramodernWorkspace: string;
|
|
94
|
+
optionUltramodernPackageSource: string;
|
|
95
|
+
optionUltramodernPackageScope: string;
|
|
96
|
+
optionUltramodernPackageNamePrefix: string;
|
|
97
|
+
optionVertical: string;
|
|
98
|
+
optionSub: string;
|
|
99
|
+
examples: string;
|
|
100
|
+
example1: string;
|
|
101
|
+
example2: string;
|
|
102
|
+
example3: string;
|
|
103
|
+
example4: string;
|
|
104
|
+
example5: string;
|
|
105
|
+
example6: string;
|
|
106
|
+
example7: string;
|
|
107
|
+
example8: string;
|
|
108
|
+
example9: string;
|
|
109
|
+
example10: string;
|
|
110
|
+
example11: string;
|
|
111
|
+
example12: string;
|
|
112
|
+
moreInfo: string;
|
|
113
|
+
};
|
|
114
|
+
version: {
|
|
115
|
+
message: string;
|
|
116
|
+
};
|
|
117
|
+
};
|
|
3
118
|
export { i18n, localeKeys };
|
|
@@ -35,6 +35,7 @@ export declare const ZH_LOCALE: {
|
|
|
35
35
|
optionUltramodernPackageSource: string;
|
|
36
36
|
optionUltramodernPackageScope: string;
|
|
37
37
|
optionUltramodernPackageNamePrefix: string;
|
|
38
|
+
optionVertical: string;
|
|
38
39
|
optionSub: string;
|
|
39
40
|
examples: string;
|
|
40
41
|
example1: string;
|
|
@@ -47,6 +48,8 @@ export declare const ZH_LOCALE: {
|
|
|
47
48
|
example8: string;
|
|
48
49
|
example9: string;
|
|
49
50
|
example10: string;
|
|
51
|
+
example11: string;
|
|
52
|
+
example12: string;
|
|
50
53
|
moreInfo: string;
|
|
51
54
|
};
|
|
52
55
|
version: {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare const WORKSPACE_PACKAGE_VERSION = "workspace:*";
|
|
2
|
+
export declare const BLEEDINGDEV_CREATE_PACKAGE = "@bleedingdev/modern-js-create";
|
|
3
|
+
export declare const BLEEDINGDEV_PACKAGE_SCOPE = "bleedingdev";
|
|
4
|
+
export declare const BLEEDINGDEV_PACKAGE_NAME_PREFIX = "modern-js-";
|
|
5
|
+
export declare const BLEEDINGDEV_FRAMEWORK_VERSION_ENV = "MODERN_CREATE_ULTRAMODERN_FRAMEWORK_VERSION";
|
|
6
|
+
export declare const ULTRAMODERN_SINGLE_APP_MODERN_PACKAGES: readonly ['@modern-js/create', '@modern-js/code-tools', '@modern-js/runtime', '@modern-js/app-tools', '@modern-js/tsconfig', '@modern-js/plugin-i18n', '@modern-js/plugin-tanstack', '@modern-js/plugin-bff', '@modern-js/adapter-rstest'];
|
|
7
|
+
export declare const ULTRAMODERN_WORKSPACE_MODERN_PACKAGES: readonly ['@modern-js/create', '@modern-js/code-tools', '@modern-js/app-tools', '@modern-js/plugin-bff', '@modern-js/plugin-i18n', '@modern-js/plugin-tanstack', '@modern-js/runtime'];
|
|
8
|
+
export type UltramodernPackageSourceStrategy = 'workspace' | 'install';
|
|
9
|
+
export type ResolvedUltramodernPackageSource = {
|
|
10
|
+
strategy: UltramodernPackageSourceStrategy;
|
|
11
|
+
modernPackageVersion: string;
|
|
12
|
+
registry?: string;
|
|
13
|
+
aliasScope?: string;
|
|
14
|
+
aliasPackageNamePrefix?: string;
|
|
15
|
+
};
|
|
16
|
+
export type UltramodernModernPackagesMetadata = {
|
|
17
|
+
packages: string[];
|
|
18
|
+
specifier: string;
|
|
19
|
+
registry?: string;
|
|
20
|
+
aliases?: Record<string, string>;
|
|
21
|
+
};
|
|
22
|
+
export declare function modernPackageVersion(packageSource: ResolvedUltramodernPackageSource): string;
|
|
23
|
+
export declare function modernAliasPackageName(packageName: string, packageSource: ResolvedUltramodernPackageSource): string;
|
|
24
|
+
export declare function modernPackageSpecifier(packageName: string, packageSource: ResolvedUltramodernPackageSource): string;
|
|
25
|
+
export declare function modernPackageAliases(packageNames: readonly string[], packageSource: ResolvedUltramodernPackageSource): Record<string, string> | undefined;
|
|
26
|
+
export declare function createModernPackagesMetadata(packageNames: readonly string[], packageSource: ResolvedUltramodernPackageSource, options?: {
|
|
27
|
+
includeAliases?: boolean;
|
|
28
|
+
}): UltramodernModernPackagesMetadata;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
type UltramodernPackageSourceStrategy
|
|
1
|
+
import { type UltramodernPackageSourceStrategy } from './ultramodern-package-source';
|
|
2
2
|
export type UltramodernWorkspaceOptions = {
|
|
3
3
|
targetDir: string;
|
|
4
4
|
packageName: string;
|
|
5
5
|
modernVersion: string;
|
|
6
|
+
enableTailwind?: boolean;
|
|
6
7
|
packageSource?: {
|
|
7
8
|
strategy?: UltramodernPackageSourceStrategy;
|
|
8
9
|
modernPackageVersion?: string;
|
|
@@ -11,10 +12,19 @@ export type UltramodernWorkspaceOptions = {
|
|
|
11
12
|
aliasPackageNamePrefix?: string;
|
|
12
13
|
};
|
|
13
14
|
};
|
|
15
|
+
export type AddUltramodernVerticalOptions = {
|
|
16
|
+
workspaceRoot: string;
|
|
17
|
+
name: string;
|
|
18
|
+
modernVersion: string;
|
|
19
|
+
enableTailwind?: boolean;
|
|
20
|
+
packageSource?: UltramodernWorkspaceOptions['packageSource'];
|
|
21
|
+
};
|
|
14
22
|
export declare const ULTRAMODERN_WORKSPACE_FLAG = "--ultramodern-workspace";
|
|
23
|
+
export declare function addUltramodernVertical(options: AddUltramodernVerticalOptions): void;
|
|
15
24
|
export declare function generateUltramodernWorkspace(options: UltramodernWorkspaceOptions): void;
|
|
16
25
|
export declare const ultramodernWorkspaceVersions: {
|
|
17
26
|
tanstackRouter: string;
|
|
18
27
|
moduleFederation: string;
|
|
28
|
+
tailwind: string;
|
|
29
|
+
tailwindPostcss: string;
|
|
19
30
|
};
|
|
20
|
-
export {};
|
package/package.json
CHANGED
|
@@ -21,14 +21,28 @@
|
|
|
21
21
|
"engines": {
|
|
22
22
|
"node": ">=20"
|
|
23
23
|
},
|
|
24
|
-
"version": "3.2.0-ultramodern.
|
|
24
|
+
"version": "3.2.0-ultramodern.111",
|
|
25
25
|
"types": "./dist/types/index.d.ts",
|
|
26
|
-
"main": "./dist/index.js",
|
|
26
|
+
"main": "./dist/esm-node/index.js",
|
|
27
27
|
"bin": {
|
|
28
28
|
"create": "bin/run.js"
|
|
29
29
|
},
|
|
30
|
+
"typesVersions": {
|
|
31
|
+
"*": {
|
|
32
|
+
".": [
|
|
33
|
+
"./dist/types/index.d.ts"
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
},
|
|
30
37
|
"exports": {
|
|
31
|
-
".":
|
|
38
|
+
".": {
|
|
39
|
+
"types": "./dist/types/index.d.ts",
|
|
40
|
+
"node": {
|
|
41
|
+
"import": "./dist/esm-node/index.js",
|
|
42
|
+
"require": "./dist/cjs/index.cjs"
|
|
43
|
+
},
|
|
44
|
+
"default": "./dist/esm-node/index.js"
|
|
45
|
+
}
|
|
32
46
|
},
|
|
33
47
|
"files": [
|
|
34
48
|
"template",
|
|
@@ -38,10 +52,11 @@
|
|
|
38
52
|
],
|
|
39
53
|
"devDependencies": {
|
|
40
54
|
"@rslib/core": "0.21.5",
|
|
41
|
-
"@types/node": "^25.
|
|
42
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
43
|
-
"tsx": "^4.22.
|
|
44
|
-
"@
|
|
55
|
+
"@types/node": "^25.9.1",
|
|
56
|
+
"@typescript/native-preview": "7.0.0-dev.20260606.1",
|
|
57
|
+
"tsx": "^4.22.3",
|
|
58
|
+
"@scripts/rstest-config": "2.66.0",
|
|
59
|
+
"@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.2.0-ultramodern.111"
|
|
45
60
|
},
|
|
46
61
|
"publishConfig": {
|
|
47
62
|
"registry": "https://registry.npmjs.org/",
|
|
@@ -49,11 +64,12 @@
|
|
|
49
64
|
},
|
|
50
65
|
"modern:source": "./src/index.ts",
|
|
51
66
|
"scripts": {
|
|
52
|
-
"build": "rslib build && pnpm -w tsgo:dts \"$PWD\"",
|
|
53
|
-
"dev": "rslib build -w",
|
|
54
|
-
"start": "node ./dist/index.js"
|
|
67
|
+
"build": "rm -rf dist && rslib build -c rslibconfig.mts && pnpm -w tsgo:dts \"$PWD\"",
|
|
68
|
+
"dev": "rslib build -c rslibconfig.mts -w",
|
|
69
|
+
"start": "node ./dist/esm-node/index.js",
|
|
70
|
+
"test": "rm -rf dist && rslib build -c rslibconfig.mts && rstest --passWithNoTests"
|
|
55
71
|
},
|
|
56
72
|
"ultramodern": {
|
|
57
|
-
"frameworkVersion": "3.2.0-ultramodern.
|
|
73
|
+
"frameworkVersion": "3.2.0-ultramodern.111"
|
|
58
74
|
}
|
|
59
75
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Stop": [
|
|
3
|
+
{
|
|
4
|
+
"command": "pnpm format && pnpm lint:fix && pnpm ultramodern:check",
|
|
5
|
+
"timeout": 600000,
|
|
6
|
+
"statusMessage": "Running UltraModern quality gates"
|
|
7
|
+
}
|
|
8
|
+
],
|
|
9
|
+
"SubagentStop": [
|
|
10
|
+
{
|
|
11
|
+
"command": "pnpm format && pnpm lint:fix && pnpm ultramodern:check",
|
|
12
|
+
"timeout": 600000,
|
|
13
|
+
"statusMessage": "Running UltraModern quality gates"
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
|
3
|
+
"extends": [
|
|
4
|
+
"config:recommended",
|
|
5
|
+
"helpers:pinGitHubActionDigests"
|
|
6
|
+
],
|
|
7
|
+
"dependencyDashboard": true,
|
|
8
|
+
"minimumReleaseAge": "1 day",
|
|
9
|
+
"prConcurrentLimit": 5,
|
|
10
|
+
"prHourlyLimit": 2,
|
|
11
|
+
"rangeStrategy": "bump",
|
|
12
|
+
"schedule": [
|
|
13
|
+
"before 5am on monday"
|
|
14
|
+
],
|
|
15
|
+
"timezone": "Etc/UTC",
|
|
16
|
+
"packageRules": [
|
|
17
|
+
{
|
|
18
|
+
"matchManagers": [
|
|
19
|
+
"github-actions"
|
|
20
|
+
],
|
|
21
|
+
"groupName": "github-actions",
|
|
22
|
+
"labels": [
|
|
23
|
+
"dependencies",
|
|
24
|
+
"github-actions",
|
|
25
|
+
"security"
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"matchManagers": [
|
|
30
|
+
"npm"
|
|
31
|
+
],
|
|
32
|
+
"matchUpdateTypes": [
|
|
33
|
+
"patch",
|
|
34
|
+
"minor"
|
|
35
|
+
],
|
|
36
|
+
"groupName": "npm minor and patch updates",
|
|
37
|
+
"labels": [
|
|
38
|
+
"dependencies",
|
|
39
|
+
"npm"
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"matchUpdateTypes": [
|
|
44
|
+
"major"
|
|
45
|
+
],
|
|
46
|
+
"dependencyDashboardApproval": true,
|
|
47
|
+
"labels": [
|
|
48
|
+
"dependencies",
|
|
49
|
+
"major"
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
@@ -4,27 +4,51 @@ on:
|
|
|
4
4
|
push:
|
|
5
5
|
pull_request:
|
|
6
6
|
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
|
|
10
|
+
defaults:
|
|
11
|
+
run:
|
|
12
|
+
shell: bash
|
|
13
|
+
|
|
14
|
+
env:
|
|
15
|
+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
16
|
+
|
|
17
|
+
concurrency:
|
|
18
|
+
group: ultramodern-gates-${{ github.workflow }}-${{ github.ref }}
|
|
19
|
+
cancel-in-progress: true
|
|
20
|
+
|
|
7
21
|
jobs:
|
|
8
22
|
ultramodern-gates:
|
|
9
23
|
runs-on: ubuntu-latest
|
|
24
|
+
timeout-minutes: 20
|
|
10
25
|
steps:
|
|
11
|
-
- name:
|
|
12
|
-
uses:
|
|
26
|
+
- name: Harden Runner
|
|
27
|
+
uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2
|
|
28
|
+
with:
|
|
29
|
+
egress-policy: audit
|
|
13
30
|
|
|
14
|
-
- name:
|
|
15
|
-
uses:
|
|
31
|
+
- name: Checkout
|
|
32
|
+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
33
|
+
with:
|
|
34
|
+
fetch-depth: 1
|
|
35
|
+
persist-credentials: false
|
|
16
36
|
|
|
17
37
|
- name: Setup Node.js
|
|
18
|
-
uses: actions/setup-node@
|
|
38
|
+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
19
39
|
with:
|
|
20
|
-
node-version:
|
|
21
|
-
|
|
40
|
+
node-version: 24
|
|
41
|
+
|
|
42
|
+
- name: Setup mise
|
|
43
|
+
uses: jdx/mise-action@5ac50f778e26fac95da98d50503682459e86d566 # v3.2.0
|
|
22
44
|
|
|
23
45
|
- name: Install Dependencies
|
|
24
|
-
run: pnpm install
|
|
46
|
+
run: mise exec -- pnpm install --frozen-lockfile
|
|
25
47
|
|
|
26
48
|
- name: Validate Ultramodern Contract
|
|
27
|
-
run: pnpm run ultramodern:check
|
|
49
|
+
run: mise exec -- pnpm run ultramodern:check
|
|
28
50
|
|
|
29
51
|
- name: Build
|
|
30
|
-
|
|
52
|
+
env:
|
|
53
|
+
MODERN_PUBLIC_SITE_URL: http://localhost:8080
|
|
54
|
+
run: mise exec -- pnpm run build
|
package/template/AGENTS.md
CHANGED
|
@@ -7,14 +7,17 @@ This project is generated for Codex-first UltraModern.js work.
|
|
|
7
7
|
- `pnpm lint` runs Oxlint with the Ultracite preset.
|
|
8
8
|
- `pnpm format` runs oxfmt.
|
|
9
9
|
- `pnpm typecheck` runs effect-tsgo as the TypeScript checker.
|
|
10
|
+
- `pnpm i18n:check` rejects hardcoded user-visible JSX text.
|
|
10
11
|
- `pnpm ultramodern:check` verifies the generated contract.
|
|
12
|
+
- Generated Codex stop hooks and subagent-stop hooks run `pnpm format && pnpm lint:fix && pnpm ultramodern:check`.
|
|
13
|
+
- `postinstall` formats the generated tree, installs private orchestration skills when available, initializes a Git repository when needed, and installs `lefthook`. Generated `lefthook.yml` runs `pnpm format && pnpm lint:fix && pnpm ultramodern:check` on pre-commit; pre-push runs `pnpm ultramodern:check`.
|
|
11
14
|
|
|
12
|
-
##
|
|
15
|
+
## Internationalization
|
|
16
|
+
|
|
17
|
+
Runtime i18n is enabled by default. Agents must put user-visible UI copy in `config/public/locales/<lang>/translation.json` and render it through `react-i18next` or `@modern-js/plugin-i18n/runtime`. Do not add hardcoded JSX text, `aria-label`, `title`, `alt`, or `placeholder` strings unless the value is a non-translatable technical token.
|
|
13
18
|
|
|
14
|
-
|
|
19
|
+
Routes are locale-prefixed by default through `localePathRedirect: true`. Keep localized pages under `src/routes/[lang]`, use links for language switching, and preserve canonical plus `hreflang` metadata. Production builds fail unless `MODERN_PUBLIC_SITE_URL` is set, so deployed canonical URLs always use the production origin.
|
|
15
20
|
|
|
16
|
-
|
|
17
|
-
pnpm skills:install
|
|
18
|
-
```
|
|
21
|
+
## Private Skills
|
|
19
22
|
|
|
20
|
-
The installer clones that private repository and copies only the allowlisted skills from `.agents/skills-lock.json
|
|
23
|
+
Private orchestration skills are installed automatically during `pnpm install` when the current developer is authorized for `TechsioCZ/skills`. The installer clones that private repository and copies only the allowlisted skills from `.agents/skills-lock.json`; unauthorized developers get a warning and can continue with the public contract.
|
package/template/README.md
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
# UltraModern.js 3.0 Starter
|
|
2
2
|
|
|
3
|
+
This generated app is a simple UltraModern.js starting point. It gives one app
|
|
4
|
+
with localized routes, production URL metadata, optional BFF support, Rstest,
|
|
5
|
+
Oxlint, oxfmt, and a local contract check. You can build a useful product here
|
|
6
|
+
without deleting fake product areas, shell packages, or deployment topology.
|
|
7
|
+
|
|
3
8
|
## Setup
|
|
4
9
|
|
|
5
10
|
Install the dependencies:
|
|
6
11
|
|
|
7
12
|
```bash
|
|
13
|
+
mise install
|
|
8
14
|
pnpm install
|
|
9
15
|
```
|
|
10
16
|
|
|
@@ -19,61 +25,87 @@ pnpm dev
|
|
|
19
25
|
Build the app for production:
|
|
20
26
|
|
|
21
27
|
```bash
|
|
22
|
-
pnpm build
|
|
28
|
+
MODERN_PUBLIC_SITE_URL=https://example.com pnpm build
|
|
23
29
|
```
|
|
24
30
|
|
|
25
|
-
|
|
31
|
+
Preview the production build locally:
|
|
26
32
|
|
|
27
33
|
```bash
|
|
28
|
-
pnpm
|
|
34
|
+
pnpm serve
|
|
29
35
|
```
|
|
30
36
|
|
|
31
|
-
|
|
37
|
+
Run the local gates before treating the scaffold as ready:
|
|
32
38
|
|
|
33
39
|
```bash
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
MODERN_BASELINE_ENABLE_TELEMETRY_EXPORTERS=false
|
|
40
|
+
pnpm run ultramodern:check
|
|
41
|
+
MODERN_PUBLIC_SITE_URL=https://example.com pnpm run build
|
|
37
42
|
```
|
|
38
43
|
|
|
39
|
-
|
|
40
|
-
That workflow runs `pnpm run ultramodern:check` and `pnpm run build` on every
|
|
41
|
-
push and pull request so the `presetUltramodern(...)` contract stays explicit.
|
|
44
|
+
## What You Get
|
|
42
45
|
|
|
43
|
-
|
|
46
|
+
The default app is intentionally monolith-friendly:
|
|
44
47
|
|
|
45
|
-
|
|
46
|
-
|
|
48
|
+
| Area | Starting Point |
|
|
49
|
+
| --- | --- |
|
|
50
|
+
| App routes | Locale-prefixed pages under `src/routes/[lang]` |
|
|
51
|
+
| Copy | English and Czech resources in `config/public/locales` |
|
|
52
|
+
| Web defaults | Local favicon/logo assets, localized metadata, semantic starter markup |
|
|
53
|
+
| Styling | App-local CSS, with Tailwind files only when selected |
|
|
54
|
+
| Server logic | Optional BFF entrypoints under `api/` |
|
|
55
|
+
| Tests | Rstest smoke coverage in `tests/` |
|
|
56
|
+
| Agent workflow | Generated `AGENTS.md`, hooks, and local quality gates |
|
|
47
57
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
npx @modern-js/create services/catalog-api --bff-runtime effect --workspace --sub
|
|
53
|
-
```
|
|
58
|
+
Keep feature code in the app while one team owns the workflow, release train,
|
|
59
|
+
and operational behavior. Add ordinary workspace packages for shared tokens,
|
|
60
|
+
small UI primitives, generated clients, or domain-neutral utilities when that
|
|
61
|
+
keeps the app easier to understand.
|
|
54
62
|
|
|
55
|
-
|
|
56
|
-
`docs/super-app-rfc-adr/WORKSPACE-0001-micro-vertical-workspace-scaffolding.md`.
|
|
57
|
-
Shell packages own route assembly and topology selection, remote packages own
|
|
58
|
-
route subtrees and degraded UI, service packages own Effect or explicit Hono
|
|
59
|
-
contracts, and shared packages are limited to tokens, primitives, generated
|
|
60
|
-
clients, or domain-neutral utilities.
|
|
63
|
+
## Customize The App
|
|
61
64
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
Start with the generated page and replace the placeholder cards with your first
|
|
66
|
+
real routes, actions, and API calls. Put user-visible text in
|
|
67
|
+
`config/public/locales/<lang>/translation.json`, then render it through
|
|
68
|
+
`react-i18next` or `@modern-js/plugin-i18n/runtime`.
|
|
66
69
|
|
|
67
|
-
The
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
The starter keeps favicon and logo assets local in `config/favicon.svg` and
|
|
71
|
+
`config/public/assets/ultramodern-logo.svg`. Replace those files when your app
|
|
72
|
+
has product branding. The localized page title and description live in the same
|
|
73
|
+
translation resources as the visible UI copy.
|
|
70
74
|
|
|
71
|
-
|
|
75
|
+
Tune the preset in `modern.config.ts`. Production builds require
|
|
76
|
+
`MODERN_PUBLIC_SITE_URL` so canonical and `hreflang` URLs use your deployed
|
|
77
|
+
origin. The local fallback is `http://localhost:8080`.
|
|
78
|
+
|
|
79
|
+
The generated preset defaults are opt-out. Disable specific contracts via env
|
|
80
|
+
vars when your app needs a softer lane:
|
|
72
81
|
|
|
73
82
|
```bash
|
|
74
|
-
|
|
83
|
+
MODERN_BASELINE_ENABLE_MF_SSR=false
|
|
84
|
+
MODERN_BASELINE_ENABLE_BFF_REQUEST_ID=false
|
|
85
|
+
MODERN_BASELINE_ENABLE_TELEMETRY_EXPORTERS=false
|
|
75
86
|
```
|
|
76
87
|
|
|
88
|
+
## Grow When Needed
|
|
89
|
+
|
|
90
|
+
Stay in the single app until a boundary has a real owner and operational reason
|
|
91
|
+
to split. A separate package is usually enough when you only need reusable code.
|
|
92
|
+
Consider a larger workspace boundary later when a feature needs independent
|
|
93
|
+
ownership, rollout, rollback, incident routing, or deployment evidence.
|
|
94
|
+
|
|
95
|
+
The public opinionated entrypoint is `presetUltramodern(...)`. It keeps Effect,
|
|
96
|
+
TanStack, SSR, BFF, i18n, and quality gates available without requiring a
|
|
97
|
+
distributed app layout on day one.
|
|
98
|
+
|
|
99
|
+
## Generated Automation
|
|
100
|
+
|
|
101
|
+
The generated starter includes `.github/workflows/ultramodern-gates.yml` and
|
|
102
|
+
`.github/renovate.json` for full app projects. The workflow runs
|
|
103
|
+
`pnpm run ultramodern:check` and `pnpm run build` on every push and pull request
|
|
104
|
+
with read-only permissions, commit-pinned actions, frozen installs, and
|
|
105
|
+
StepSecurity audit-mode runner hardening. Renovate is configured for dependency
|
|
106
|
+
dashboard review, one-day release age, grouped updates, action digest pinning,
|
|
107
|
+
and manual approval for major upgrades.
|
|
108
|
+
|
|
77
109
|
For more information, see the
|
|
78
110
|
[UltraModern.js guide](https://bleedingdev.github.io/ultramodern.js/guides/get-started/ultramodern.html)
|
|
79
111
|
and the [UltraModern.js documentation](https://bleedingdev.github.io/ultramodern.js/).
|
|
@@ -4,18 +4,29 @@
|
|
|
4
4
|
Layer,
|
|
5
5
|
defineEffectBff,
|
|
6
6
|
} from '@modern-js/plugin-bff/effect-server';
|
|
7
|
-
import {
|
|
7
|
+
import type { HttpApi, HttpApiGroup } from '@modern-js/plugin-bff/effect-server';
|
|
8
|
+
import { bffEffectApi } from '../../shared/effect/api.ts';
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
type ApiGroups<TApi> = TApi extends HttpApi.HttpApi<string, infer TGroups> ? TGroups : never;
|
|
11
|
+
type GreetingsHandlers = HttpApiBuilder.Handlers.FromGroup<
|
|
12
|
+
HttpApiGroup.WithName<ApiGroups<typeof bffEffectApi>, 'greetings'>
|
|
13
|
+
>;
|
|
14
|
+
|
|
15
|
+
const greetingsLayer = HttpApiBuilder.group(
|
|
16
|
+
bffEffectApi,
|
|
17
|
+
'greetings',
|
|
18
|
+
(handlers: GreetingsHandlers) =>
|
|
19
|
+
handlers.handle('hello', () =>
|
|
20
|
+
Effect.succeed({
|
|
21
|
+
message: 'Hello from Effect HttpApi',
|
|
22
|
+
runtime: 'effect' as const,
|
|
23
|
+
}),
|
|
24
|
+
),
|
|
16
25
|
);
|
|
17
26
|
|
|
18
|
-
const layer = HttpApiBuilder.layer(bffEffectApi).pipe(
|
|
27
|
+
const layer = HttpApiBuilder.layer(bffEffectApi).pipe(
|
|
28
|
+
Layer.provide(greetingsLayer),
|
|
29
|
+
);
|
|
19
30
|
|
|
20
31
|
export default defineEffectBff({
|
|
21
32
|
api: bffEffectApi,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
{{#if useHonoBff}}
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
{{#if useHonoBff}}const hello = () => ({
|
|
2
|
+
message: 'Hello from UltraModern.js BFF ({{bffRuntime}})',
|
|
3
|
+
});
|
|
4
|
+
|
|
5
|
+
export default hello;
|
|
6
6
|
{{/if}}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="UltraModern.js">
|
|
2
|
+
<rect width="64" height="64" rx="12" fill="#111827"/>
|
|
3
|
+
<path fill="#35d399" d="M14 17h9v21c0 5 3 8 9 8s9-3 9-8V17h9v22c0 11-8 18-18 18s-18-7-18-18V17Z"/>
|
|
4
|
+
<path fill="#ffffff" d="M28 17h8v25h-8z"/>
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 160 160" role="img" aria-label="UltraModern.js logo">
|
|
2
|
+
<rect width="160" height="160" rx="28" fill="#111827"/>
|
|
3
|
+
<path fill="#35d399" d="M42 36h22v56c0 22 14 34 36 34s36-12 36-34V36h22v57c0 35-24 57-58 57S42 128 42 93V36Z"/>
|
|
4
|
+
<path fill="#ffffff" d="M76 36h20v74H76z"/>
|
|
5
|
+
<path fill="#8be8ff" d="M112 36h18v74h-18z"/>
|
|
6
|
+
</svg>
|