@bleedingdev/modern-js-create 3.2.0-ultramodern.11 → 3.2.0-ultramodern.110

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 (95) hide show
  1. package/README.md +158 -35
  2. package/bin/run.js +0 -0
  3. package/dist/cjs/index.cjs +1040 -0
  4. package/dist/cjs/locale/en.cjs +97 -0
  5. package/dist/cjs/locale/index.cjs +50 -0
  6. package/dist/cjs/locale/zh.cjs +97 -0
  7. package/dist/cjs/ultramodern-checks/cli/i18n-check.cjs +73 -0
  8. package/dist/cjs/ultramodern-checks/cli/oxlint.cjs +174 -0
  9. package/dist/cjs/ultramodern-checks/cli/workspace-source-check.cjs +179 -0
  10. package/dist/cjs/ultramodern-checks/index.cjs +58 -0
  11. package/dist/cjs/ultramodern-checks/oxlint-plugin.cjs +354 -0
  12. package/dist/cjs/ultramodern-package-source.cjs +133 -0
  13. package/dist/cjs/ultramodern-workspace.cjs +5616 -0
  14. package/dist/esm/index.js +1002 -0
  15. package/dist/esm/locale/en.js +59 -0
  16. package/dist/esm/locale/index.js +9 -0
  17. package/dist/esm/locale/zh.js +59 -0
  18. package/dist/esm/ultramodern-checks/cli/i18n-check.js +26 -0
  19. package/dist/esm/ultramodern-checks/cli/oxlint.js +118 -0
  20. package/dist/esm/ultramodern-checks/cli/workspace-source-check.js +124 -0
  21. package/dist/esm/ultramodern-checks/index.js +3 -0
  22. package/dist/esm/ultramodern-checks/oxlint-plugin.js +316 -0
  23. package/dist/esm/ultramodern-package-source.js +61 -0
  24. package/dist/esm/ultramodern-workspace.js +5554 -0
  25. package/dist/esm-node/index.js +1003 -0
  26. package/dist/esm-node/locale/en.js +60 -0
  27. package/dist/esm-node/locale/index.js +10 -0
  28. package/dist/esm-node/locale/zh.js +60 -0
  29. package/dist/esm-node/ultramodern-checks/cli/i18n-check.js +27 -0
  30. package/dist/esm-node/ultramodern-checks/cli/oxlint.js +119 -0
  31. package/dist/esm-node/ultramodern-checks/cli/workspace-source-check.js +125 -0
  32. package/dist/esm-node/ultramodern-checks/index.js +4 -0
  33. package/dist/esm-node/ultramodern-checks/oxlint-plugin.js +317 -0
  34. package/dist/esm-node/ultramodern-package-source.js +62 -0
  35. package/dist/esm-node/ultramodern-workspace.js +5555 -0
  36. package/dist/types/locale/en.d.ts +3 -0
  37. package/dist/types/locale/index.d.ts +117 -2
  38. package/dist/types/locale/zh.d.ts +3 -0
  39. package/dist/types/ultramodern-checks/cli/i18n-check.d.ts +9 -0
  40. package/dist/types/ultramodern-checks/cli/oxlint.d.ts +22 -0
  41. package/dist/types/ultramodern-checks/cli/workspace-source-check.d.ts +8 -0
  42. package/dist/types/ultramodern-checks/index.d.ts +3 -0
  43. package/dist/types/ultramodern-checks/oxlint-plugin.d.ts +63 -0
  44. package/dist/types/ultramodern-package-source.d.ts +28 -0
  45. package/dist/types/ultramodern-workspace.d.ts +12 -2
  46. package/package.json +52 -11
  47. package/template/.codex/hooks.json +16 -0
  48. package/template/.github/renovate.json +53 -0
  49. package/template/.github/workflows/ultramodern-gates.yml.handlebars +34 -10
  50. package/template/.mise.toml.handlebars +2 -0
  51. package/template/AGENTS.md +9 -6
  52. package/template/README.md +66 -34
  53. package/template/api/effect/index.ts.handlebars +20 -9
  54. package/template/api/lambda/hello.ts.handlebars +5 -5
  55. package/template/config/favicon.svg +5 -0
  56. package/template/config/public/assets/ultramodern-logo.svg +6 -0
  57. package/template/config/public/locales/cs/translation.json +44 -0
  58. package/template/config/public/locales/en/translation.json +44 -0
  59. package/template/lefthook.yml +10 -0
  60. package/template/modern.config.ts.handlebars +35 -3
  61. package/template/oxfmt.config.ts +8 -1
  62. package/template/oxlint.config.ts +8 -1
  63. package/template/package.json.handlebars +36 -30
  64. package/template/pnpm-workspace.yaml +34 -0
  65. package/template/rstest.config.mts +5 -0
  66. package/template/scripts/bootstrap-agent-skills.mjs +148 -15
  67. package/template/scripts/check-i18n-strings.mjs +3 -0
  68. package/template/scripts/validate-ultramodern.mjs.handlebars +494 -3
  69. package/template/src/modern-app-env.d.ts +2 -0
  70. package/template/src/modern.runtime.ts.handlebars +17 -1
  71. package/template/src/routes/[lang]/page.tsx.handlebars +209 -0
  72. package/template/src/routes/index.css.handlebars +192 -55
  73. package/template/src/routes/layout.tsx.handlebars +2 -1
  74. package/template/tailwind.config.ts.handlebars +1 -1
  75. package/template/tests/tsconfig.json +7 -0
  76. package/template/tests/ultramodern.contract.test.ts.handlebars +160 -0
  77. package/template/tsconfig.json +2 -1
  78. package/template-workspace/.agents/agent-reference-repos.json +24 -0
  79. package/template-workspace/.agents/skills-lock.json +19 -0
  80. package/template-workspace/.codex/hooks.json +16 -0
  81. package/template-workspace/.github/renovate.json +29 -0
  82. package/template-workspace/.github/workflows/ultramodern-workspace-gates.yml.handlebars +54 -0
  83. package/template-workspace/.gitignore.handlebars +5 -0
  84. package/template-workspace/.mise.toml.handlebars +2 -0
  85. package/template-workspace/AGENTS.md +36 -5
  86. package/template-workspace/README.md.handlebars +70 -11
  87. package/template-workspace/lefthook.yml +10 -0
  88. package/template-workspace/oxfmt.config.ts +1 -0
  89. package/template-workspace/oxlint.config.ts +1 -0
  90. package/template-workspace/pnpm-workspace.yaml +31 -8
  91. package/template-workspace/scripts/bootstrap-agent-skills.mjs +190 -21
  92. package/template-workspace/scripts/setup-agent-reference-repos.mjs +370 -0
  93. package/dist/index.js +0 -2474
  94. package/template/src/routes/page.tsx.handlebars +0 -136
  95. 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
- declare const i18n: any;
2
- declare const localeKeys: any;
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,9 @@
1
+ type SingleAppI18nCheckOptions = {
2
+ readonly cwd?: string;
3
+ readonly targets?: readonly string[];
4
+ };
5
+ export declare const SINGLE_APP_I18N_SUCCESS = "No hardcoded user-visible JSX strings found.";
6
+ export declare const SINGLE_APP_I18N_FAILURE = "Hardcoded user-visible JSX strings found. Move copy to locale JSON files.";
7
+ export declare const runSingleAppI18nCheck: ({ cwd, targets, }?: SingleAppI18nCheckOptions) => number;
8
+ export declare const main: () => void;
9
+ export {};
@@ -0,0 +1,22 @@
1
+ type OxlintRuleConfig = string | readonly [
2
+ string,
3
+ {
4
+ readonly [key: string]: unknown;
5
+ }
6
+ ];
7
+ type OxlintRules = {
8
+ readonly [ruleName: string]: OxlintRuleConfig;
9
+ };
10
+ type OxlintRulesOptions = {
11
+ readonly cwd: string;
12
+ readonly targets: readonly string[];
13
+ readonly rules: OxlintRules;
14
+ };
15
+ type OxlintRulesResult = {
16
+ readonly exitCode: number;
17
+ readonly stdout: string;
18
+ readonly stderr: string;
19
+ };
20
+ export declare const runOxlintRules: ({ cwd, targets, rules, }: OxlintRulesOptions) => OxlintRulesResult;
21
+ export declare const printOxlintOutput: ({ stdout, stderr, }: OxlintRulesResult) => void;
22
+ export {};
@@ -0,0 +1,8 @@
1
+ type WorkspaceSourceCheckOptions = {
2
+ readonly cwd?: string;
3
+ readonly sourceRoots?: readonly string[];
4
+ };
5
+ export declare const WORKSPACE_SOURCE_SUCCESS = "UltraModern i18n and boundary guardrails validated";
6
+ export declare const runWorkspaceSourceCheck: ({ cwd, sourceRoots, }?: WorkspaceSourceCheckOptions) => number;
7
+ export declare const main: () => void;
8
+ export {};
@@ -0,0 +1,3 @@
1
+ export { runSingleAppI18nCheck } from './cli/i18n-check';
2
+ export { runWorkspaceSourceCheck } from './cli/workspace-source-check';
3
+ export { default as oxlintPlugin } from './oxlint-plugin';
@@ -0,0 +1,63 @@
1
+ type AstNode = {
2
+ readonly type?: string;
3
+ readonly parent?: AstNode;
4
+ readonly loc?: {
5
+ readonly start?: {
6
+ readonly line?: number;
7
+ };
8
+ readonly end?: {
9
+ readonly line?: number;
10
+ };
11
+ };
12
+ readonly value?: unknown;
13
+ readonly raw?: unknown;
14
+ readonly name?: unknown;
15
+ readonly openingElement?: AstNode;
16
+ readonly expression?: AstNode;
17
+ readonly expressions?: readonly AstNode[];
18
+ readonly quasis?: readonly AstNode[];
19
+ readonly test?: AstNode;
20
+ readonly consequent?: AstNode;
21
+ readonly alternate?: AstNode;
22
+ readonly arguments?: readonly AstNode[];
23
+ readonly callee?: AstNode;
24
+ readonly object?: AstNode;
25
+ readonly property?: AstNode;
26
+ readonly computed?: boolean;
27
+ };
28
+ type RuleContext = {
29
+ readonly options?: readonly unknown[];
30
+ readonly filename?: string;
31
+ getSourceCode?: () => {
32
+ readonly text?: string;
33
+ getAllComments?: () => readonly AstNode[];
34
+ getText?: (node: AstNode) => string;
35
+ };
36
+ report: (descriptor: {
37
+ readonly node: AstNode;
38
+ readonly message: string;
39
+ }) => void;
40
+ };
41
+ type Rule = {
42
+ readonly meta: {
43
+ readonly type: string;
44
+ readonly docs: {
45
+ readonly description: string;
46
+ };
47
+ readonly schema: unknown[];
48
+ };
49
+ create(context: RuleContext): Record<string, (node: AstNode) => void>;
50
+ };
51
+ declare const plugin: {
52
+ meta: {
53
+ name: string;
54
+ };
55
+ rules: {
56
+ 'no-hardcoded-jsx-text': Rule;
57
+ 'no-legacy-mf-boundary-attributes': Rule;
58
+ 'no-literal-visible-jsx-attributes': Rule;
59
+ 'no-manual-locale-copy-branching': Rule;
60
+ 'no-split-translation-keys': Rule;
61
+ };
62
+ };
63
+ export default plugin;
@@ -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/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/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 = 'workspace' | 'install';
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,50 @@
21
21
  "engines": {
22
22
  "node": ">=20"
23
23
  },
24
- "version": "3.2.0-ultramodern.11",
24
+ "version": "3.2.0-ultramodern.110",
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
+ "ultramodern-checks": [
36
+ "./dist/types/ultramodern-checks/index.d.ts"
37
+ ],
38
+ "ultramodern-checks/oxlint-plugin": [
39
+ "./dist/types/ultramodern-checks/oxlint-plugin.d.ts"
40
+ ]
41
+ }
42
+ },
30
43
  "exports": {
31
- ".": "./dist/index.js"
44
+ ".": {
45
+ "types": "./dist/types/index.d.ts",
46
+ "node": {
47
+ "import": "./dist/esm-node/index.js",
48
+ "require": "./dist/cjs/index.cjs"
49
+ },
50
+ "default": "./dist/esm-node/index.js"
51
+ },
52
+ "./ultramodern-checks": {
53
+ "types": "./dist/types/ultramodern-checks/index.d.ts",
54
+ "node": {
55
+ "import": "./dist/esm-node/ultramodern-checks/index.js",
56
+ "require": "./dist/cjs/ultramodern-checks/index.cjs"
57
+ },
58
+ "default": "./dist/esm-node/ultramodern-checks/index.js"
59
+ },
60
+ "./ultramodern-checks/oxlint-plugin": {
61
+ "types": "./dist/types/ultramodern-checks/oxlint-plugin.d.ts",
62
+ "node": {
63
+ "import": "./dist/esm-node/ultramodern-checks/oxlint-plugin.js",
64
+ "require": "./dist/cjs/ultramodern-checks/oxlint-plugin.cjs"
65
+ },
66
+ "default": "./dist/esm-node/ultramodern-checks/oxlint-plugin.js"
67
+ }
32
68
  },
33
69
  "files": [
34
70
  "template",
@@ -36,12 +72,16 @@
36
72
  "dist",
37
73
  "bin.js"
38
74
  ],
75
+ "dependencies": {
76
+ "oxlint": "1.68.0"
77
+ },
39
78
  "devDependencies": {
40
79
  "@rslib/core": "0.21.5",
41
- "@types/node": "^25.8.0",
42
- "@typescript/native-preview": "7.0.0-dev.20260516.1",
43
- "tsx": "^4.22.0",
44
- "@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.2.0-ultramodern.11"
80
+ "@types/node": "^25.9.1",
81
+ "@typescript/native-preview": "7.0.0-dev.20260606.1",
82
+ "tsx": "^4.22.3",
83
+ "@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.2.0-ultramodern.110",
84
+ "@scripts/rstest-config": "2.66.0"
45
85
  },
46
86
  "publishConfig": {
47
87
  "registry": "https://registry.npmjs.org/",
@@ -49,11 +89,12 @@
49
89
  },
50
90
  "modern:source": "./src/index.ts",
51
91
  "scripts": {
52
- "build": "rslib build && pnpm -w tsgo:dts \"$PWD\"",
53
- "dev": "rslib build -w",
54
- "start": "node ./dist/index.js"
92
+ "build": "rm -rf dist && rslib build -c rslibconfig.mts && pnpm -w tsgo:dts \"$PWD\"",
93
+ "dev": "rslib build -c rslibconfig.mts -w",
94
+ "start": "node ./dist/esm-node/index.js",
95
+ "test": "rm -rf dist && rslib build -c rslibconfig.mts && rstest --passWithNoTests"
55
96
  },
56
97
  "ultramodern": {
57
- "frameworkVersion": "3.2.0-ultramodern.11"
98
+ "frameworkVersion": "3.2.0-ultramodern.110"
58
99
  }
59
100
  }
@@ -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: Checkout
12
- uses: actions/checkout@v4
26
+ - name: Harden Runner
27
+ uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2
28
+ with:
29
+ egress-policy: audit
13
30
 
14
- - name: Setup pnpm
15
- uses: pnpm/action-setup@v4
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@v4
38
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
19
39
  with:
20
- node-version: 20
21
- cache: pnpm
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
- run: pnpm run build
52
+ env:
53
+ MODERN_PUBLIC_SITE_URL: http://localhost:8080
54
+ run: mise exec -- pnpm run build
@@ -0,0 +1,2 @@
1
+ [tools]
2
+ pnpm = "{{pnpmVersion}}"
@@ -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
- ## Private Skills
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
- Private orchestration skills are not vendored into this template. If you are authorized for `TechsioCZ/skills`, run:
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
- ```bash
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.