@bleedingdev/modern-js-create 3.2.0-ultramodern.18 → 3.2.0-ultramodern.19
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/dist/index.js +18 -1
- package/package.json +1 -1
- package/template-workspace/.agents/agent-reference-repos.json +23 -0
- package/template-workspace/AGENTS.md +9 -0
- package/template-workspace/README.md.handlebars +5 -0
- package/template-workspace/scripts/setup-agent-reference-repos.mjs +217 -0
- package/template-workspace/scripts/validate-ultramodern-workspace.mjs.handlebars +60 -0
package/dist/index.js
CHANGED
|
@@ -556,6 +556,7 @@ const ultramodern_workspace_dirname = node_path.dirname(fileURLToPath(import.met
|
|
|
556
556
|
const workspaceTemplateDir = node_path.resolve(ultramodern_workspace_dirname, '..', 'template-workspace');
|
|
557
557
|
const TANSTACK_ROUTER_VERSION = '1.170.1';
|
|
558
558
|
const MODULE_FEDERATION_VERSION = '2.4.0';
|
|
559
|
+
const ZEPHYR_MODERNJS_PLUGIN_VERSION = '1.1.1';
|
|
559
560
|
const EFFECT_TSGO_VERSION = '0.7.3';
|
|
560
561
|
const TYPESCRIPT_NATIVE_PREVIEW_VERSION = '7.0.0-dev.20260518.1';
|
|
561
562
|
const OXLINT_VERSION = '1.65.0';
|
|
@@ -926,6 +927,7 @@ function appDependencies(scope, packageSource) {
|
|
|
926
927
|
'@module-federation/modern-js-v3': MODULE_FEDERATION_VERSION,
|
|
927
928
|
'@module-federation/runtime': MODULE_FEDERATION_VERSION,
|
|
928
929
|
'@tanstack/react-router': TANSTACK_ROUTER_VERSION,
|
|
930
|
+
'zephyr-modernjs-plugin': ZEPHYR_MODERNJS_PLUGIN_VERSION,
|
|
929
931
|
[ultramodern_workspace_packageName(scope, 'shared-contracts')]: WORKSPACE_PACKAGE_VERSION,
|
|
930
932
|
[ultramodern_workspace_packageName(scope, 'shared-design-tokens')]: WORKSPACE_PACKAGE_VERSION,
|
|
931
933
|
i18next: I18NEXT_VERSION,
|
|
@@ -967,7 +969,10 @@ function createRootPackageJson(scope, packageSource) {
|
|
|
967
969
|
typecheck: `pnpm -r --filter "@${scope}/*" typecheck`,
|
|
968
970
|
'skills:install': "node ./scripts/bootstrap-agent-skills.mjs",
|
|
969
971
|
'skills:check': "node ./scripts/bootstrap-agent-skills.mjs --check",
|
|
972
|
+
'agents:refs:install': "node ./scripts/setup-agent-reference-repos.mjs",
|
|
973
|
+
'agents:refs:check': "node ./scripts/setup-agent-reference-repos.mjs --check",
|
|
970
974
|
'ultramodern:check': "node ./scripts/validate-ultramodern-workspace.mjs",
|
|
975
|
+
postinstall: "node ./scripts/setup-agent-reference-repos.mjs",
|
|
971
976
|
check: 'pnpm format:check && pnpm lint && pnpm typecheck && pnpm i18n:check && pnpm skills:check && pnpm ultramodern:check'
|
|
972
977
|
},
|
|
973
978
|
engines: {
|
|
@@ -1136,6 +1141,7 @@ import { appTools, defineConfig, presetUltramodern } from '@modern-js/app-tools'
|
|
|
1136
1141
|
import { i18nPlugin } from '@modern-js/plugin-i18n';
|
|
1137
1142
|
import { tanstackRouterPlugin } from '@modern-js/plugin-tanstack';
|
|
1138
1143
|
import { moduleFederationPlugin } from '@module-federation/modern-js-v3';
|
|
1144
|
+
import { withZephyr } from 'zephyr-modernjs-plugin';
|
|
1139
1145
|
|
|
1140
1146
|
const appId = '${app.id}';
|
|
1141
1147
|
const port = Number(process.env['${app.portEnv}'] ?? ${app.port});
|
|
@@ -1157,11 +1163,19 @@ export default defineConfig(
|
|
|
1157
1163
|
{
|
|
1158
1164
|
output: {
|
|
1159
1165
|
disableTsChecker: true,
|
|
1166
|
+
distPath: {
|
|
1167
|
+
html: './',
|
|
1168
|
+
},
|
|
1160
1169
|
polyfill: 'off',
|
|
1161
1170
|
splitRouteChunks: false,
|
|
1162
1171
|
},
|
|
1172
|
+
html: {
|
|
1173
|
+
outputStructure: 'flat',
|
|
1174
|
+
},
|
|
1163
1175
|
plugins: [
|
|
1164
|
-
appTools(
|
|
1176
|
+
appTools({
|
|
1177
|
+
bundler: 'rspack',
|
|
1178
|
+
}),
|
|
1165
1179
|
i18nPlugin({
|
|
1166
1180
|
localeDetection: {
|
|
1167
1181
|
fallbackLanguage: 'en',
|
|
@@ -1171,6 +1185,7 @@ export default defineConfig(
|
|
|
1171
1185
|
}),
|
|
1172
1186
|
tanstackRouterPlugin(),
|
|
1173
1187
|
moduleFederationPlugin(),
|
|
1188
|
+
withZephyr(),
|
|
1174
1189
|
],
|
|
1175
1190
|
server: {
|
|
1176
1191
|
port,
|
|
@@ -1180,6 +1195,7 @@ export default defineConfig(
|
|
|
1180
1195
|
},
|
|
1181
1196
|
},
|
|
1182
1197
|
source: {
|
|
1198
|
+
mainEntryName: 'index',
|
|
1183
1199
|
globalVars: {
|
|
1184
1200
|
ULTRAMODERN_SITE_URL: siteUrl,
|
|
1185
1201
|
},
|
|
@@ -1856,6 +1872,7 @@ function createTemplateManifest(modernVersion, packageSource) {
|
|
|
1856
1872
|
allowedPaths: [
|
|
1857
1873
|
'.agents/**',
|
|
1858
1874
|
'.github/**',
|
|
1875
|
+
'.gitignore',
|
|
1859
1876
|
'.modernjs/**',
|
|
1860
1877
|
'AGENTS.md',
|
|
1861
1878
|
'README.md',
|
package/package.json
CHANGED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"defaultEnabled": true,
|
|
4
|
+
"installDir": "repos",
|
|
5
|
+
"repositories": [
|
|
6
|
+
{
|
|
7
|
+
"id": "effect",
|
|
8
|
+
"name": "Effect",
|
|
9
|
+
"url": "https://github.com/Effect-TS/effect.git",
|
|
10
|
+
"ref": "main",
|
|
11
|
+
"path": "repos/effect",
|
|
12
|
+
"readOnly": true
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"id": "ultramodern-js",
|
|
16
|
+
"name": "UltraModern.js",
|
|
17
|
+
"url": "https://github.com/BleedingDev/ultramodern.js.git",
|
|
18
|
+
"ref": "main-ultramodern",
|
|
19
|
+
"path": "repos/ultramodern.js",
|
|
20
|
+
"readOnly": true
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
@@ -38,6 +38,15 @@ pnpm skills:install
|
|
|
38
38
|
|
|
39
39
|
The installer copies only the allowlisted private skills from `.agents/skills-lock.json`: `plan-graph`, `dag`, `subagent-graph`, `helm`, and `debugger-mode`.
|
|
40
40
|
|
|
41
|
+
## Agent Reference Repositories
|
|
42
|
+
|
|
43
|
+
The workspace installs read-only source snapshots under `repos/` by default during `pnpm install`. These repositories are reference material for coding agents, not application source:
|
|
44
|
+
|
|
45
|
+
- `repos/effect` from `Effect-TS/effect`.
|
|
46
|
+
- `repos/ultramodern.js` from `BleedingDev/ultramodern.js`.
|
|
47
|
+
|
|
48
|
+
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`.
|
|
49
|
+
|
|
41
50
|
## Project Priorities
|
|
42
51
|
|
|
43
52
|
- Keep `presetUltramodern` as the single preset.
|
|
@@ -19,6 +19,11 @@ Run the scaffold validator before adding business code:
|
|
|
19
19
|
pnpm ultramodern:check
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
+
By default, `pnpm install` also prepares read-only agent reference repositories
|
|
23
|
+
under `repos/` for Effect and UltraModern.js source lookup. Disable this setup
|
|
24
|
+
with `ULTRAMODERN_SKIP_AGENT_REPOS=1 pnpm install`, or rerun it explicitly with
|
|
25
|
+
`pnpm agents:refs:install`.
|
|
26
|
+
|
|
22
27
|
The topology and ownership metadata are generated under `topology/`. The
|
|
23
28
|
workspace also ships `.github/workflows/ultramodern-workspace-gates.yml` and
|
|
24
29
|
`.github/renovate.json` with read-only workflow permissions, commit-pinned
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
|
|
5
|
+
const root = process.cwd();
|
|
6
|
+
const args = new Set(process.argv.slice(2));
|
|
7
|
+
const checkOnly = args.has('--check');
|
|
8
|
+
const configPath = path.join(root, '.agents', 'agent-reference-repos.json');
|
|
9
|
+
const manifestPath = path.join(root, '.modernjs', 'agent-reference-repos.json');
|
|
10
|
+
const tempRoot = path.join(root, '.modernjs', 'agent-reference-repos-tmp');
|
|
11
|
+
|
|
12
|
+
const truthy = value => /^(1|true|yes|on)$/i.test(String(value ?? ''));
|
|
13
|
+
const falsy = value => /^(0|false|no|off)$/i.test(String(value ?? ''));
|
|
14
|
+
|
|
15
|
+
const skipRequested =
|
|
16
|
+
truthy(process.env.ULTRAMODERN_SKIP_AGENT_REPOS) ||
|
|
17
|
+
falsy(process.env.ULTRAMODERN_AGENT_REPOS);
|
|
18
|
+
const required = truthy(process.env.ULTRAMODERN_AGENT_REPOS_REQUIRED);
|
|
19
|
+
const refresh = truthy(process.env.ULTRAMODERN_AGENT_REPOS_REFRESH);
|
|
20
|
+
|
|
21
|
+
const log = message => console.log(`[agent-reference-repos] ${message}`);
|
|
22
|
+
const warn = message => console.warn(`[agent-reference-repos] ${message}`);
|
|
23
|
+
|
|
24
|
+
function fail(message) {
|
|
25
|
+
if (required || checkOnly) {
|
|
26
|
+
throw new Error(message);
|
|
27
|
+
}
|
|
28
|
+
warn(message);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function readJson(filePath) {
|
|
32
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function run(command, commandArgs, options = {}) {
|
|
36
|
+
const result = spawnSync(command, commandArgs, {
|
|
37
|
+
cwd: options.cwd ?? root,
|
|
38
|
+
encoding: 'utf-8',
|
|
39
|
+
stdio: options.stdio ?? ['ignore', 'pipe', 'pipe'],
|
|
40
|
+
timeout: options.timeout ?? 120000,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
if (result.error) {
|
|
44
|
+
throw result.error;
|
|
45
|
+
}
|
|
46
|
+
if (result.status !== 0) {
|
|
47
|
+
const stderr = result.stderr?.trim();
|
|
48
|
+
throw new Error(
|
|
49
|
+
`${command} ${commandArgs.join(' ')} failed${
|
|
50
|
+
stderr ? `: ${stderr}` : ''
|
|
51
|
+
}`,
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
return result.stdout?.trim() ?? '';
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function assertSafeRepoPath(relativePath) {
|
|
58
|
+
if (
|
|
59
|
+
typeof relativePath !== 'string' ||
|
|
60
|
+
relativePath.length === 0 ||
|
|
61
|
+
path.isAbsolute(relativePath) ||
|
|
62
|
+
relativePath.split(/[\\/]+/).includes('..') ||
|
|
63
|
+
!relativePath.startsWith('repos/')
|
|
64
|
+
) {
|
|
65
|
+
throw new Error(`Unsafe reference repository path: ${relativePath}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function hasGit() {
|
|
70
|
+
const result = spawnSync('git', ['--version'], {
|
|
71
|
+
encoding: 'utf-8',
|
|
72
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
73
|
+
});
|
|
74
|
+
return result.status === 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function existingReference(targetPath, repo) {
|
|
78
|
+
const markerPath = path.join(targetPath, '.ultramodern-reference-repo.json');
|
|
79
|
+
if (!fs.existsSync(markerPath)) {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
const marker = readJson(markerPath);
|
|
84
|
+
if (marker.url === repo.url && marker.ref === repo.ref) {
|
|
85
|
+
return marker;
|
|
86
|
+
}
|
|
87
|
+
} catch {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function materializeRepository(repo) {
|
|
94
|
+
assertSafeRepoPath(repo.path);
|
|
95
|
+
const targetPath = path.join(root, repo.path);
|
|
96
|
+
const existing = existingReference(targetPath, repo);
|
|
97
|
+
|
|
98
|
+
if (existing && !refresh) {
|
|
99
|
+
log(`${repo.id} already present at ${repo.path} (${existing.commit})`);
|
|
100
|
+
return { ...existing, status: 'present' };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (fs.existsSync(targetPath)) {
|
|
104
|
+
if (!refresh) {
|
|
105
|
+
fail(`${repo.path} exists but is not a managed reference repo`);
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
fs.rmSync(targetPath, { recursive: true, force: true });
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (checkOnly) {
|
|
112
|
+
fail(`${repo.path} is missing`);
|
|
113
|
+
return undefined;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
fs.mkdirSync(tempRoot, { recursive: true });
|
|
117
|
+
const tempPath = fs.mkdtempSync(path.join(tempRoot, `${repo.id}-`));
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
log(`cloning ${repo.name} from ${repo.url}#${repo.ref}`);
|
|
121
|
+
run(
|
|
122
|
+
'git',
|
|
123
|
+
[
|
|
124
|
+
'clone',
|
|
125
|
+
'--depth',
|
|
126
|
+
'1',
|
|
127
|
+
'--single-branch',
|
|
128
|
+
'--branch',
|
|
129
|
+
repo.ref,
|
|
130
|
+
'--filter=blob:none',
|
|
131
|
+
repo.url,
|
|
132
|
+
tempPath,
|
|
133
|
+
],
|
|
134
|
+
{ timeout: 300000 },
|
|
135
|
+
);
|
|
136
|
+
const commit = run('git', ['-C', tempPath, 'rev-parse', 'HEAD']);
|
|
137
|
+
fs.rmSync(path.join(tempPath, '.git'), { recursive: true, force: true });
|
|
138
|
+
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
139
|
+
fs.renameSync(tempPath, targetPath);
|
|
140
|
+
|
|
141
|
+
const marker = {
|
|
142
|
+
schemaVersion: 1,
|
|
143
|
+
id: repo.id,
|
|
144
|
+
name: repo.name,
|
|
145
|
+
url: repo.url,
|
|
146
|
+
ref: repo.ref,
|
|
147
|
+
commit,
|
|
148
|
+
path: repo.path,
|
|
149
|
+
readOnly: repo.readOnly !== false,
|
|
150
|
+
installedAt: new Date().toISOString(),
|
|
151
|
+
};
|
|
152
|
+
fs.writeFileSync(
|
|
153
|
+
path.join(targetPath, '.ultramodern-reference-repo.json'),
|
|
154
|
+
`${JSON.stringify(marker, null, 2)}\n`,
|
|
155
|
+
);
|
|
156
|
+
log(`${repo.id} installed at ${repo.path} (${commit})`);
|
|
157
|
+
return { ...marker, status: 'installed' };
|
|
158
|
+
} catch (error) {
|
|
159
|
+
fs.rmSync(tempPath, { recursive: true, force: true });
|
|
160
|
+
fail(`Could not install ${repo.id}: ${error.message}`);
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function main() {
|
|
166
|
+
if (!fs.existsSync(configPath)) {
|
|
167
|
+
fail('Missing .agents/agent-reference-repos.json');
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const config = readJson(configPath);
|
|
172
|
+
const enabled = config.defaultEnabled !== false && !skipRequested;
|
|
173
|
+
|
|
174
|
+
if (!enabled) {
|
|
175
|
+
log('setup skipped; set ULTRAMODERN_SKIP_AGENT_REPOS=0 to enable it again');
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (!hasGit()) {
|
|
180
|
+
fail('git is required to install agent reference repositories');
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const installed = [];
|
|
185
|
+
for (const repo of config.repositories ?? []) {
|
|
186
|
+
const result = materializeRepository(repo);
|
|
187
|
+
if (result) {
|
|
188
|
+
installed.push(result);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (!checkOnly) {
|
|
193
|
+
fs.mkdirSync(path.dirname(manifestPath), { recursive: true });
|
|
194
|
+
fs.writeFileSync(
|
|
195
|
+
manifestPath,
|
|
196
|
+
`${JSON.stringify(
|
|
197
|
+
{
|
|
198
|
+
schemaVersion: 1,
|
|
199
|
+
generatedAt: new Date().toISOString(),
|
|
200
|
+
installDir: config.installDir ?? 'repos',
|
|
201
|
+
repositories: installed,
|
|
202
|
+
},
|
|
203
|
+
null,
|
|
204
|
+
2,
|
|
205
|
+
)}\n`,
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
try {
|
|
211
|
+
main();
|
|
212
|
+
} catch (error) {
|
|
213
|
+
console.error(`[agent-reference-repos] ${error.message}`);
|
|
214
|
+
process.exitCode = 1;
|
|
215
|
+
} finally {
|
|
216
|
+
fs.rmSync(tempRoot, { recursive: true, force: true });
|
|
217
|
+
}
|
|
@@ -36,6 +36,7 @@ const assertExists = (relativePath) => {
|
|
|
36
36
|
|
|
37
37
|
const requiredPaths = [
|
|
38
38
|
'AGENTS.md',
|
|
39
|
+
'.gitignore',
|
|
39
40
|
'package.json',
|
|
40
41
|
'pnpm-workspace.yaml',
|
|
41
42
|
'tsconfig.base.json',
|
|
@@ -44,6 +45,7 @@ const requiredPaths = [
|
|
|
44
45
|
'.github/renovate.json',
|
|
45
46
|
'.github/workflows/ultramodern-workspace-gates.yml',
|
|
46
47
|
'.agents/skills-lock.json',
|
|
48
|
+
'.agents/agent-reference-repos.json',
|
|
47
49
|
'.agents/rstackjs-agent-skills-LICENSE',
|
|
48
50
|
'.agents/skills/rsbuild-best-practices/SKILL.md',
|
|
49
51
|
'.agents/skills/rspack-best-practices/SKILL.md',
|
|
@@ -61,6 +63,7 @@ const requiredPaths = [
|
|
|
61
63
|
'.modernjs/ultramodern-workspace-template-manifest.json',
|
|
62
64
|
'.modernjs/ultramodern-package-source.json',
|
|
63
65
|
'scripts/bootstrap-agent-skills.mjs',
|
|
66
|
+
'scripts/setup-agent-reference-repos.mjs',
|
|
64
67
|
'scripts/check-i18n-strings.mjs',
|
|
65
68
|
'apps/shell-super-app/package.json',
|
|
66
69
|
'apps/shell-super-app/config/public/locales/en/translation.json',
|
|
@@ -122,6 +125,7 @@ for (const appDirectory of [
|
|
|
122
125
|
const rootPackage = readJson('package.json');
|
|
123
126
|
const packageSource = readJson('.modernjs/ultramodern-package-source.json');
|
|
124
127
|
const skillsLock = readJson('.agents/skills-lock.json');
|
|
128
|
+
const agentReferenceRepos = readJson('.agents/agent-reference-repos.json');
|
|
125
129
|
const pnpmWorkspace = readText('pnpm-workspace.yaml');
|
|
126
130
|
const workflowContent = readText('.github/workflows/ultramodern-workspace-gates.yml');
|
|
127
131
|
const renovateConfig = readJson('.github/renovate.json');
|
|
@@ -237,6 +241,9 @@ const requiredRootScripts = {
|
|
|
237
241
|
'i18n:check': 'node ./scripts/check-i18n-strings.mjs',
|
|
238
242
|
lint: 'oxlint .',
|
|
239
243
|
'lint:fix': 'oxlint . --fix',
|
|
244
|
+
'agents:refs:check': 'node ./scripts/setup-agent-reference-repos.mjs --check',
|
|
245
|
+
'agents:refs:install': 'node ./scripts/setup-agent-reference-repos.mjs',
|
|
246
|
+
postinstall: 'node ./scripts/setup-agent-reference-repos.mjs',
|
|
240
247
|
'skills:check': 'node ./scripts/bootstrap-agent-skills.mjs --check',
|
|
241
248
|
'skills:install': 'node ./scripts/bootstrap-agent-skills.mjs',
|
|
242
249
|
typecheck: `pnpm -r --filter "@${packageScope}/*" typecheck`,
|
|
@@ -274,6 +281,34 @@ assert(
|
|
|
274
281
|
skillsLock.installDir === '.agents/skills',
|
|
275
282
|
'Agent skills lock must use .agents/skills as installDir',
|
|
276
283
|
);
|
|
284
|
+
assert(
|
|
285
|
+
agentReferenceRepos.defaultEnabled === true,
|
|
286
|
+
'Agent reference repositories must be enabled by default',
|
|
287
|
+
);
|
|
288
|
+
assert(
|
|
289
|
+
agentReferenceRepos.repositories?.some(
|
|
290
|
+
(repo) =>
|
|
291
|
+
repo.id === 'effect' &&
|
|
292
|
+
repo.url === 'https://github.com/Effect-TS/effect.git' &&
|
|
293
|
+
repo.path === 'repos/effect',
|
|
294
|
+
),
|
|
295
|
+
'Agent reference repositories must include Effect',
|
|
296
|
+
);
|
|
297
|
+
assert(
|
|
298
|
+
agentReferenceRepos.repositories?.some(
|
|
299
|
+
(repo) =>
|
|
300
|
+
repo.id === 'ultramodern-js' &&
|
|
301
|
+
repo.url === 'https://github.com/BleedingDev/ultramodern.js.git' &&
|
|
302
|
+
repo.path === 'repos/ultramodern.js',
|
|
303
|
+
),
|
|
304
|
+
'Agent reference repositories must include UltraModern.js',
|
|
305
|
+
);
|
|
306
|
+
assert(
|
|
307
|
+
readText('scripts/setup-agent-reference-repos.mjs').includes(
|
|
308
|
+
'ULTRAMODERN_SKIP_AGENT_REPOS',
|
|
309
|
+
),
|
|
310
|
+
'Agent reference repository setup must expose an opt-out environment variable',
|
|
311
|
+
);
|
|
277
312
|
for (const skillName of baselineAgentSkills) {
|
|
278
313
|
assert(
|
|
279
314
|
skillsLock.baseline?.some((skill) => skill.name === skillName),
|
|
@@ -357,6 +392,10 @@ for (const packagePath of appPackagePaths) {
|
|
|
357
392
|
packageJson.dependencies?.['@module-federation/modern-js-v3'] === '2.4.0',
|
|
358
393
|
`${packagePath} must include the Module Federation plugin`,
|
|
359
394
|
);
|
|
395
|
+
assert(
|
|
396
|
+
packageJson.dependencies?.['zephyr-modernjs-plugin'] === '1.1.1',
|
|
397
|
+
`${packagePath} must include the official Zephyr Modern.js plugin`,
|
|
398
|
+
);
|
|
360
399
|
assert(
|
|
361
400
|
packageJson.modernjs?.preset === 'presetUltramodern',
|
|
362
401
|
`${packagePath} must keep presetUltramodern metadata`,
|
|
@@ -383,6 +422,27 @@ for (const configPath of [
|
|
|
383
422
|
config.includes('moduleFederationPlugin()'),
|
|
384
423
|
`${configPath} must enable Module Federation`,
|
|
385
424
|
);
|
|
425
|
+
assert(
|
|
426
|
+
config.includes("from 'zephyr-modernjs-plugin'"),
|
|
427
|
+
`${configPath} must import the official Zephyr Modern.js plugin`,
|
|
428
|
+
);
|
|
429
|
+
assert(config.includes('withZephyr()'), `${configPath} must enable Zephyr through plugins`);
|
|
430
|
+
assert(
|
|
431
|
+
config.includes("bundler: 'rspack'"),
|
|
432
|
+
`${configPath} must keep appTools on the rspack bundler for Zephyr`,
|
|
433
|
+
);
|
|
434
|
+
assert(
|
|
435
|
+
config.includes("html: './'"),
|
|
436
|
+
`${configPath} must keep Modern.js output.distPath.html compatible with Zephyr`,
|
|
437
|
+
);
|
|
438
|
+
assert(
|
|
439
|
+
config.includes("outputStructure: 'flat'"),
|
|
440
|
+
`${configPath} must keep Modern.js HTML output flat for Zephyr`,
|
|
441
|
+
);
|
|
442
|
+
assert(
|
|
443
|
+
config.includes("mainEntryName: 'index'"),
|
|
444
|
+
`${configPath} must keep Modern.js source.mainEntryName compatible with Zephyr`,
|
|
445
|
+
);
|
|
386
446
|
}
|
|
387
447
|
|
|
388
448
|
for (const routePath of [
|