@bleedingdev/modern-js-create 3.2.0-ultramodern.1 → 3.2.0-ultramodern.11
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 +12 -0
- package/dist/index.js +330 -185
- package/package.json +5 -2
- package/template/.agents/skills-lock.json +34 -0
- package/template/AGENTS.md +20 -0
- package/template/api/effect/index.ts.handlebars +7 -45
- package/template/modern.config.ts.handlebars +20 -24
- package/template/oxfmt.config.ts +8 -0
- package/template/oxlint.config.ts +12 -0
- package/template/package.json.handlebars +41 -26
- package/template/scripts/bootstrap-agent-skills.mjs +95 -0
- package/template/scripts/validate-ultramodern.mjs.handlebars +81 -17
- package/template/shared/effect/api.ts.handlebars +1 -2
- package/template/src/modern.runtime.ts.handlebars +2 -4
- package/template/src/routes/index.css.handlebars +14 -3
- package/template/src/routes/page.tsx.handlebars +28 -11
- package/template/tsconfig.json +106 -2
- package/template-workspace/.agents/rstackjs-agent-skills-LICENSE +21 -0
- package/template-workspace/.agents/skills/rsbuild-best-practices/SKILL.md +57 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/SKILL.md +96 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/command-map.md +113 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/common-analysis-patterns.md +190 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor-common.md +88 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor-rspack.md +138 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor-webpack.md +71 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor.md +39 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/rsdoctor-data-types.md +103 -0
- package/template-workspace/.agents/skills/rslib-best-practices/SKILL.md +58 -0
- package/template-workspace/.agents/skills/rslib-modern-package/SKILL.md +173 -0
- package/template-workspace/.agents/skills/rspack-best-practices/SKILL.md +70 -0
- package/template-workspace/.agents/skills/rspack-tracing/SKILL.md +75 -0
- package/template-workspace/.agents/skills/rspack-tracing/references/bottlenecks.md +47 -0
- package/template-workspace/.agents/skills/rspack-tracing/references/tracing-guide.md +38 -0
- package/template-workspace/.agents/skills/rspack-tracing/scripts/analyze_trace.js +184 -0
- package/template-workspace/.agents/skills/rstest-best-practices/SKILL.md +133 -0
- package/template-workspace/.agents/skills-lock.json +95 -0
- package/template-workspace/AGENTS.md +45 -0
- package/template-workspace/oxfmt.config.ts +16 -0
- package/template-workspace/oxlint.config.ts +19 -0
- package/template-workspace/pnpm-workspace.yaml +12 -0
- package/template-workspace/scripts/bootstrap-agent-skills.mjs +95 -0
- package/template-workspace/scripts/validate-ultramodern-workspace.mjs.handlebars +188 -59
- package/template/biome.json +0 -41
|
@@ -4,40 +4,60 @@ import path from 'node:path';
|
|
|
4
4
|
const root = process.cwd();
|
|
5
5
|
const packageScope = '{{packageScope}}';
|
|
6
6
|
const tanstackVersion = '1.170.1';
|
|
7
|
+
const rstackAgentSkillsCommit = '61c948b42512e223bad44b83af4080eba48b2677';
|
|
7
8
|
const modernPackages = [
|
|
8
9
|
'@modern-js/app-tools',
|
|
9
10
|
'@modern-js/plugin-bff',
|
|
10
11
|
'@modern-js/plugin-tanstack',
|
|
11
12
|
'@modern-js/runtime',
|
|
12
13
|
];
|
|
14
|
+
const baselineAgentSkills = [
|
|
15
|
+
'rsbuild-best-practices',
|
|
16
|
+
'rspack-best-practices',
|
|
17
|
+
'rspack-tracing',
|
|
18
|
+
'rsdoctor-analysis',
|
|
19
|
+
'rslib-best-practices',
|
|
20
|
+
'rslib-modern-package',
|
|
21
|
+
'rstest-best-practices',
|
|
22
|
+
];
|
|
23
|
+
const privateAgentSkills = ['plan-graph', 'dag', 'subagent-graph', 'helm', 'debugger-mode'];
|
|
13
24
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
function readJson(relativePath) {
|
|
19
|
-
return JSON.parse(readText(relativePath));
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function assert(condition, message) {
|
|
25
|
+
const readText = (relativePath) => fs.readFileSync(path.join(root, relativePath), 'utf-8');
|
|
26
|
+
const readJson = (relativePath) => JSON.parse(readText(relativePath));
|
|
27
|
+
const assert = (condition, message) => {
|
|
23
28
|
if (!condition) {
|
|
24
29
|
throw new Error(message);
|
|
25
30
|
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function assertExists(relativePath) {
|
|
31
|
+
};
|
|
32
|
+
const assertExists = (relativePath) => {
|
|
29
33
|
assert(fs.existsSync(path.join(root, relativePath)), `Missing ${relativePath}`);
|
|
30
|
-
}
|
|
34
|
+
};
|
|
31
35
|
|
|
32
36
|
const requiredPaths = [
|
|
37
|
+
'AGENTS.md',
|
|
33
38
|
'package.json',
|
|
34
39
|
'pnpm-workspace.yaml',
|
|
35
40
|
'tsconfig.base.json',
|
|
41
|
+
'oxlint.config.ts',
|
|
42
|
+
'oxfmt.config.ts',
|
|
43
|
+
'.agents/skills-lock.json',
|
|
44
|
+
'.agents/rstackjs-agent-skills-LICENSE',
|
|
45
|
+
'.agents/skills/rsbuild-best-practices/SKILL.md',
|
|
46
|
+
'.agents/skills/rspack-best-practices/SKILL.md',
|
|
47
|
+
'.agents/skills/rspack-tracing/SKILL.md',
|
|
48
|
+
'.agents/skills/rspack-tracing/references/tracing-guide.md',
|
|
49
|
+
'.agents/skills/rspack-tracing/scripts/analyze_trace.js',
|
|
50
|
+
'.agents/skills/rsdoctor-analysis/SKILL.md',
|
|
51
|
+
'.agents/skills/rsdoctor-analysis/references/rsdoctor-data-types.md',
|
|
52
|
+
'.agents/skills/rslib-best-practices/SKILL.md',
|
|
53
|
+
'.agents/skills/rslib-modern-package/SKILL.md',
|
|
54
|
+
'.agents/skills/rstest-best-practices/SKILL.md',
|
|
36
55
|
'topology/reference-topology.json',
|
|
37
56
|
'topology/ownership.json',
|
|
38
57
|
'topology/local-overlays/development.json',
|
|
39
58
|
'.modernjs/ultramodern-workspace-template-manifest.json',
|
|
40
59
|
'.modernjs/ultramodern-package-source.json',
|
|
60
|
+
'scripts/bootstrap-agent-skills.mjs',
|
|
41
61
|
'apps/shell-super-app/package.json',
|
|
42
62
|
'apps/shell-super-app/modern.config.ts',
|
|
43
63
|
'apps/shell-super-app/module-federation.config.ts',
|
|
@@ -65,12 +85,11 @@ for (const requiredPath of requiredPaths) {
|
|
|
65
85
|
|
|
66
86
|
const rootPackage = readJson('package.json');
|
|
67
87
|
const packageSource = readJson('.modernjs/ultramodern-package-source.json');
|
|
88
|
+
const skillsLock = readJson('.agents/skills-lock.json');
|
|
68
89
|
const expectedModernSpecifier =
|
|
69
|
-
packageSource.strategy === 'install'
|
|
70
|
-
? packageSource.modernPackages?.specifier
|
|
71
|
-
: 'workspace:*';
|
|
90
|
+
packageSource.strategy === 'install' ? packageSource.modernPackages?.specifier : 'workspace:*';
|
|
72
91
|
|
|
73
|
-
|
|
92
|
+
const expectedModernDependency = (packageName) => {
|
|
74
93
|
if (packageSource.strategy !== 'install') {
|
|
75
94
|
return 'workspace:*';
|
|
76
95
|
}
|
|
@@ -79,13 +98,14 @@ function expectedModernDependency(packageName) {
|
|
|
79
98
|
return aliasPackageName
|
|
80
99
|
? `npm:${aliasPackageName}@${expectedModernSpecifier}`
|
|
81
100
|
: expectedModernSpecifier;
|
|
82
|
-
}
|
|
101
|
+
};
|
|
83
102
|
|
|
84
103
|
assert(rootPackage.private === true, 'Root package must be private');
|
|
85
104
|
assert(rootPackage.modernjs?.preset === 'presetUltramodern', 'Root must declare presetUltramodern');
|
|
105
|
+
assert(rootPackage.packageManager === 'pnpm@11.1.2', 'Root must pin pnpm 11.1.2');
|
|
106
|
+
assert(rootPackage.engines?.pnpm === '>=11.0.0', 'Root must require pnpm >=11');
|
|
86
107
|
assert(
|
|
87
|
-
rootPackage.modernjs?.packageSource?.config ===
|
|
88
|
-
'./.modernjs/ultramodern-package-source.json',
|
|
108
|
+
rootPackage.modernjs?.packageSource?.config === './.modernjs/ultramodern-package-source.json',
|
|
89
109
|
'Root must point to the UltraModern package source metadata',
|
|
90
110
|
);
|
|
91
111
|
assert(
|
|
@@ -101,21 +121,82 @@ assert(
|
|
|
101
121
|
'Generated shared packages must keep workspace:* links',
|
|
102
122
|
);
|
|
103
123
|
assert(
|
|
104
|
-
modernPackages.every(packageName =>
|
|
124
|
+
modernPackages.every((packageName) =>
|
|
105
125
|
packageSource.modernPackages?.packages?.includes(packageName),
|
|
106
126
|
),
|
|
107
127
|
'Package source metadata must list all Modern runtime/tooling packages',
|
|
108
128
|
);
|
|
109
129
|
assert(
|
|
110
|
-
expectedModernSpecifier &&
|
|
111
|
-
packageSource.modernPackages?.specifier === expectedModernSpecifier,
|
|
130
|
+
expectedModernSpecifier && packageSource.modernPackages?.specifier === expectedModernSpecifier,
|
|
112
131
|
'Package source metadata must provide a Modern package specifier',
|
|
113
132
|
);
|
|
133
|
+
|
|
134
|
+
const requiredRootScripts = {
|
|
135
|
+
format: 'oxfmt .',
|
|
136
|
+
'format:check': 'oxfmt --check .',
|
|
137
|
+
lint: 'oxlint .',
|
|
138
|
+
'lint:fix': 'oxlint . --fix',
|
|
139
|
+
'skills:check': 'node ./scripts/bootstrap-agent-skills.mjs --check',
|
|
140
|
+
'skills:install': 'node ./scripts/bootstrap-agent-skills.mjs',
|
|
141
|
+
typecheck: `pnpm -r --filter "@${packageScope}/*" typecheck`,
|
|
142
|
+
'ultramodern:check': 'node ./scripts/validate-ultramodern-workspace.mjs',
|
|
143
|
+
};
|
|
144
|
+
for (const [scriptName, scriptCommand] of Object.entries(requiredRootScripts)) {
|
|
145
|
+
assert(rootPackage.scripts?.[scriptName] === scriptCommand, `Root must expose ${scriptName}`);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
for (const dependency of [
|
|
149
|
+
'@effect/tsgo',
|
|
150
|
+
'@typescript/native-preview',
|
|
151
|
+
'oxfmt',
|
|
152
|
+
'oxlint',
|
|
153
|
+
'ultracite',
|
|
154
|
+
]) {
|
|
155
|
+
assert(rootPackage.devDependencies?.[dependency], `Root must depend on ${dependency}`);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const agentsInstructions = readText('AGENTS.md');
|
|
114
159
|
assert(
|
|
115
|
-
|
|
116
|
-
'
|
|
117
|
-
'Root must
|
|
160
|
+
agentsInstructions.includes('UltraModern Agent Contract') &&
|
|
161
|
+
agentsInstructions.includes('Required Skill Baseline'),
|
|
162
|
+
'Root AGENTS.md must document the UltraModern agent contract',
|
|
118
163
|
);
|
|
164
|
+
assert(
|
|
165
|
+
skillsLock.source?.repository === 'https://github.com/rstackjs/agent-skills',
|
|
166
|
+
'Agent skills lock must retain the Rstack skill source repository',
|
|
167
|
+
);
|
|
168
|
+
assert(
|
|
169
|
+
skillsLock.source?.commit === rstackAgentSkillsCommit,
|
|
170
|
+
'Agent skills lock must pin the expected Rstack skill commit',
|
|
171
|
+
);
|
|
172
|
+
assert(
|
|
173
|
+
skillsLock.installDir === '.agents/skills',
|
|
174
|
+
'Agent skills lock must use .agents/skills as installDir',
|
|
175
|
+
);
|
|
176
|
+
for (const skillName of baselineAgentSkills) {
|
|
177
|
+
assert(
|
|
178
|
+
skillsLock.baseline?.some((skill) => skill.name === skillName),
|
|
179
|
+
`Agent skills lock must include ${skillName}`,
|
|
180
|
+
);
|
|
181
|
+
assert(
|
|
182
|
+
readText(`.agents/skills/${skillName}/SKILL.md`).includes(`name: ${skillName}`),
|
|
183
|
+
`${skillName} must contain matching skill metadata`,
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const privateSource = skillsLock.sources?.find(
|
|
188
|
+
(source) => source.repository === 'https://github.com/TechsioCZ/skills',
|
|
189
|
+
);
|
|
190
|
+
assert(
|
|
191
|
+
privateSource?.install === 'clone-if-authorized',
|
|
192
|
+
'Agent skills lock must configure TechsioCZ skills as clone-if-authorized',
|
|
193
|
+
);
|
|
194
|
+
for (const skillName of privateAgentSkills) {
|
|
195
|
+
assert(
|
|
196
|
+
privateSource.baseline?.some((skill) => skill.name === skillName),
|
|
197
|
+
`Agent skills lock must allowlist private skill ${skillName}`,
|
|
198
|
+
);
|
|
199
|
+
}
|
|
119
200
|
|
|
120
201
|
const appPackagePaths = [
|
|
121
202
|
'apps/shell-super-app/package.json',
|
|
@@ -129,26 +210,30 @@ for (const packagePath of appPackagePaths) {
|
|
|
129
210
|
assert(
|
|
130
211
|
packageJson.dependencies?.['@modern-js/plugin-tanstack'] ===
|
|
131
212
|
expectedModernDependency('@modern-js/plugin-tanstack'),
|
|
132
|
-
`${packagePath} must
|
|
213
|
+
`${packagePath} must use @modern-js/plugin-tanstack through ${expectedModernDependency(
|
|
214
|
+
'@modern-js/plugin-tanstack',
|
|
215
|
+
)}`,
|
|
133
216
|
);
|
|
134
217
|
assert(
|
|
135
218
|
packageJson.dependencies?.['@modern-js/runtime'] ===
|
|
136
219
|
expectedModernDependency('@modern-js/runtime'),
|
|
137
|
-
`${packagePath} must
|
|
220
|
+
`${packagePath} must use @modern-js/runtime through ${expectedModernDependency(
|
|
221
|
+
'@modern-js/runtime',
|
|
222
|
+
)}`,
|
|
138
223
|
);
|
|
139
224
|
assert(
|
|
140
225
|
packageJson.devDependencies?.['@modern-js/app-tools'] ===
|
|
141
226
|
expectedModernDependency('@modern-js/app-tools'),
|
|
142
|
-
`${packagePath} must
|
|
227
|
+
`${packagePath} must use @modern-js/app-tools through ${expectedModernDependency(
|
|
228
|
+
'@modern-js/app-tools',
|
|
229
|
+
)}`,
|
|
143
230
|
);
|
|
144
231
|
assert(
|
|
145
|
-
packageJson.dependencies?.[`@${packageScope}/shared-contracts`] ===
|
|
146
|
-
'workspace:*',
|
|
232
|
+
packageJson.dependencies?.[`@${packageScope}/shared-contracts`] === 'workspace:*',
|
|
147
233
|
`${packagePath} must link generated shared contracts through workspace:*`,
|
|
148
234
|
);
|
|
149
235
|
assert(
|
|
150
|
-
packageJson.dependencies?.[`@${packageScope}/shared-design-tokens`] ===
|
|
151
|
-
'workspace:*',
|
|
236
|
+
packageJson.dependencies?.[`@${packageScope}/shared-design-tokens`] === 'workspace:*',
|
|
152
237
|
`${packagePath} must link generated shared design tokens through workspace:*`,
|
|
153
238
|
);
|
|
154
239
|
assert(
|
|
@@ -174,56 +259,83 @@ for (const configPath of [
|
|
|
174
259
|
const config = readText(configPath);
|
|
175
260
|
assert(config.includes('presetUltramodern('), `${configPath} must use presetUltramodern`);
|
|
176
261
|
assert(config.includes('tanstackRouterPlugin()'), `${configPath} must enable plugin-tanstack`);
|
|
177
|
-
assert(
|
|
262
|
+
assert(
|
|
263
|
+
config.includes('moduleFederationPlugin()'),
|
|
264
|
+
`${configPath} must enable Module Federation`,
|
|
265
|
+
);
|
|
178
266
|
}
|
|
179
267
|
|
|
180
268
|
const shellMf = readText('apps/shell-super-app/module-federation.config.ts');
|
|
181
269
|
assert(shellMf.includes("name: 'shellSuperApp'"), 'Shell MF config must name the shell');
|
|
182
|
-
assert(
|
|
183
|
-
|
|
184
|
-
|
|
270
|
+
assert(
|
|
271
|
+
shellMf.includes('remoteCommerce@http://localhost:3021/mf-manifest.json'),
|
|
272
|
+
'Shell must reference commerce remote',
|
|
273
|
+
);
|
|
274
|
+
assert(
|
|
275
|
+
shellMf.includes('remoteIdentity@http://localhost:3022/mf-manifest.json'),
|
|
276
|
+
'Shell must reference identity remote',
|
|
277
|
+
);
|
|
278
|
+
assert(
|
|
279
|
+
shellMf.includes('remoteDesignSystem@http://localhost:3023/mf-manifest.json'),
|
|
280
|
+
'Shell must reference design-system remote',
|
|
281
|
+
);
|
|
185
282
|
|
|
186
283
|
const commerceMf = readText('apps/remotes/remote-commerce/module-federation.config.ts');
|
|
187
284
|
assert(commerceMf.includes("name: 'remoteCommerce'"), 'Commerce remote MF name is missing');
|
|
188
|
-
assert(commerceMf.includes('
|
|
285
|
+
assert(commerceMf.includes("'./Widget'"), 'Commerce remote must expose a widget');
|
|
189
286
|
|
|
190
287
|
const designMf = readText('apps/remotes/remote-design-system/module-federation.config.ts');
|
|
191
288
|
assert(designMf.includes("name: 'remoteDesignSystem'"), 'Design-system remote MF name is missing');
|
|
192
|
-
assert(designMf.includes('
|
|
193
|
-
assert(designMf.includes('
|
|
289
|
+
assert(designMf.includes("'./Button'"), 'Design-system remote must expose Button');
|
|
290
|
+
assert(designMf.includes("'./tokens'"), 'Design-system remote must expose tokens');
|
|
194
291
|
|
|
195
292
|
const servicePackage = readJson('services/service-recommendations-effect/package.json');
|
|
196
293
|
assert(
|
|
197
294
|
servicePackage.dependencies?.['@modern-js/runtime'] ===
|
|
198
295
|
expectedModernDependency('@modern-js/runtime'),
|
|
199
|
-
`Effect service must use @modern-js/runtime through ${expectedModernDependency(
|
|
296
|
+
`Effect service must use @modern-js/runtime through ${expectedModernDependency(
|
|
297
|
+
'@modern-js/runtime',
|
|
298
|
+
)}`,
|
|
200
299
|
);
|
|
201
300
|
assert(
|
|
202
301
|
servicePackage.devDependencies?.['@modern-js/app-tools'] ===
|
|
203
302
|
expectedModernDependency('@modern-js/app-tools'),
|
|
204
|
-
`Effect service must use @modern-js/app-tools through ${expectedModernDependency(
|
|
303
|
+
`Effect service must use @modern-js/app-tools through ${expectedModernDependency(
|
|
304
|
+
'@modern-js/app-tools',
|
|
305
|
+
)}`,
|
|
205
306
|
);
|
|
206
307
|
assert(
|
|
207
308
|
servicePackage.devDependencies?.['@modern-js/plugin-bff'] ===
|
|
208
309
|
expectedModernDependency('@modern-js/plugin-bff'),
|
|
209
|
-
`Effect service must use @modern-js/plugin-bff through ${expectedModernDependency(
|
|
310
|
+
`Effect service must use @modern-js/plugin-bff through ${expectedModernDependency(
|
|
311
|
+
'@modern-js/plugin-bff',
|
|
312
|
+
)}`,
|
|
210
313
|
);
|
|
211
314
|
assert(
|
|
212
|
-
servicePackage.dependencies?.[`@${packageScope}/shared-effect-api`] ===
|
|
213
|
-
'workspace:*',
|
|
315
|
+
servicePackage.dependencies?.[`@${packageScope}/shared-effect-api`] === 'workspace:*',
|
|
214
316
|
'Effect service must link generated shared Effect API through workspace:*',
|
|
215
317
|
);
|
|
216
318
|
|
|
217
319
|
const serviceConfig = readText('services/service-recommendations-effect/modern.config.ts');
|
|
218
|
-
assert(
|
|
320
|
+
assert(
|
|
321
|
+
serviceConfig.includes("runtimeFramework: 'effect'"),
|
|
322
|
+
'Effect service must use Effect runtime',
|
|
323
|
+
);
|
|
219
324
|
assert(serviceConfig.includes('bffPlugin()'), 'Effect service must enable bffPlugin');
|
|
220
325
|
|
|
221
326
|
const serviceEntry = readText('services/service-recommendations-effect/api/effect/index.ts');
|
|
222
|
-
assert(
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
assert(
|
|
327
|
+
assert(
|
|
328
|
+
serviceEntry.includes('defineEffectBff'),
|
|
329
|
+
'Effect service must expose defineEffectBff placeholder',
|
|
330
|
+
);
|
|
331
|
+
assert(
|
|
332
|
+
serviceEntry.includes('recommendationsEffectApi'),
|
|
333
|
+
'Effect service must use shared recommendations API',
|
|
334
|
+
);
|
|
335
|
+
assert(
|
|
336
|
+
readText('services/service-recommendations-effect/shared/effect/api.ts').includes('HttpApi.make'),
|
|
337
|
+
'Effect shared API placeholder must define HttpApi',
|
|
338
|
+
);
|
|
227
339
|
|
|
228
340
|
const topology = readJson('topology/reference-topology.json');
|
|
229
341
|
assert(topology.preset === 'presetUltramodern', 'Topology must reference presetUltramodern');
|
|
@@ -232,27 +344,26 @@ assert(topology.shell?.remoteRefs?.length === 3, 'Topology shell must reference
|
|
|
232
344
|
assert(topology.remotes?.length === 3, 'Topology must contain three remotes');
|
|
233
345
|
assert(
|
|
234
346
|
topology.remotes.some(
|
|
235
|
-
remote =>
|
|
236
|
-
remote.id === 'remote-design-system' &&
|
|
237
|
-
remote.kind === 'horizontal-design-system',
|
|
347
|
+
(remote) => remote.id === 'remote-design-system' && remote.kind === 'horizontal-design-system',
|
|
238
348
|
),
|
|
239
349
|
'Topology must contain the horizontal design-system remote',
|
|
240
350
|
);
|
|
241
|
-
assert(
|
|
351
|
+
assert(
|
|
352
|
+
topology.effectServices?.[0]?.runtime === 'effect',
|
|
353
|
+
'Topology must contain an Effect service',
|
|
354
|
+
);
|
|
242
355
|
assert(topology.sharedPackages?.length === 3, 'Topology must contain shared package placeholders');
|
|
243
356
|
|
|
244
357
|
const ownership = readJson('topology/ownership.json');
|
|
245
358
|
assert(
|
|
246
359
|
ownership.owners?.some(
|
|
247
|
-
owner =>
|
|
248
|
-
owner.id === 'remote-commerce' &&
|
|
249
|
-
owner.ownership?.team === 'commerce-experience',
|
|
360
|
+
(owner) => owner.id === 'remote-commerce' && owner.ownership?.team === 'commerce-experience',
|
|
250
361
|
),
|
|
251
362
|
'Ownership metadata must retain commerce owner',
|
|
252
363
|
);
|
|
253
364
|
assert(
|
|
254
365
|
ownership.owners?.some(
|
|
255
|
-
owner =>
|
|
366
|
+
(owner) =>
|
|
256
367
|
owner.id === 'service-recommendations-effect' &&
|
|
257
368
|
owner.package === `@${packageScope}/service-recommendations-effect`,
|
|
258
369
|
),
|
|
@@ -268,6 +379,24 @@ assert(
|
|
|
268
379
|
manifest.packageSource?.strategy === packageSource.strategy,
|
|
269
380
|
'Template manifest must retain the generated package source strategy',
|
|
270
381
|
);
|
|
382
|
+
assert(
|
|
383
|
+
manifest.agentSkills?.source?.commit === rstackAgentSkillsCommit,
|
|
384
|
+
'Template manifest must retain the Rstack agent skills commit',
|
|
385
|
+
);
|
|
386
|
+
assert(
|
|
387
|
+
baselineAgentSkills.every((skillName) => manifest.agentSkills?.baseline?.includes(skillName)),
|
|
388
|
+
'Template manifest must list every baseline agent skill',
|
|
389
|
+
);
|
|
390
|
+
assert(
|
|
391
|
+
manifest.agentSkills?.privateSource?.repository === 'https://github.com/TechsioCZ/skills',
|
|
392
|
+
'Template manifest must retain the private TechsioCZ skill source',
|
|
393
|
+
);
|
|
394
|
+
assert(
|
|
395
|
+
privateAgentSkills.every((skillName) =>
|
|
396
|
+
manifest.agentSkills?.privateSource?.baseline?.includes(skillName),
|
|
397
|
+
),
|
|
398
|
+
'Template manifest must list every private agent skill allowlist entry',
|
|
399
|
+
);
|
|
271
400
|
assert(
|
|
272
401
|
manifest.validation?.expectedCommands?.includes('pnpm run ultramodern:check'),
|
|
273
402
|
'Template manifest must document the validation command',
|
package/template/biome.json
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"root": false,
|
|
3
|
-
"$schema": "https://biomejs.dev/schemas/2.4.15/schema.json",
|
|
4
|
-
"vcs": {
|
|
5
|
-
"enabled": true,
|
|
6
|
-
"defaultBranch": "main",
|
|
7
|
-
"clientKind": "git",
|
|
8
|
-
"useIgnoreFile": true
|
|
9
|
-
},
|
|
10
|
-
"formatter": {
|
|
11
|
-
"enabled": true,
|
|
12
|
-
"indentStyle": "space"
|
|
13
|
-
},
|
|
14
|
-
"javascript": {
|
|
15
|
-
"formatter": {
|
|
16
|
-
"quoteStyle": "single",
|
|
17
|
-
"arrowParentheses": "asNeeded",
|
|
18
|
-
"jsxQuoteStyle": "double",
|
|
19
|
-
"lineWidth": 80
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
"linter": {
|
|
23
|
-
"enabled": true,
|
|
24
|
-
"rules": {
|
|
25
|
-
"recommended": true,
|
|
26
|
-
"suspicious": {
|
|
27
|
-
"noDuplicateFontNames": "off"
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
"assist": { "actions": { "source": { "organizeImports": "on" } } },
|
|
32
|
-
"files": {
|
|
33
|
-
"ignoreUnknown": true,
|
|
34
|
-
"includes": [
|
|
35
|
-
"**",
|
|
36
|
-
"!**/.vscode/**/*",
|
|
37
|
-
"!**/node_modules/**/*",
|
|
38
|
-
"!**/dist/**/*"
|
|
39
|
-
]
|
|
40
|
-
}
|
|
41
|
-
}
|