@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.
Files changed (43) hide show
  1. package/README.md +12 -0
  2. package/dist/index.js +330 -185
  3. package/package.json +5 -2
  4. package/template/.agents/skills-lock.json +34 -0
  5. package/template/AGENTS.md +20 -0
  6. package/template/api/effect/index.ts.handlebars +7 -45
  7. package/template/modern.config.ts.handlebars +20 -24
  8. package/template/oxfmt.config.ts +8 -0
  9. package/template/oxlint.config.ts +12 -0
  10. package/template/package.json.handlebars +41 -26
  11. package/template/scripts/bootstrap-agent-skills.mjs +95 -0
  12. package/template/scripts/validate-ultramodern.mjs.handlebars +81 -17
  13. package/template/shared/effect/api.ts.handlebars +1 -2
  14. package/template/src/modern.runtime.ts.handlebars +2 -4
  15. package/template/src/routes/index.css.handlebars +14 -3
  16. package/template/src/routes/page.tsx.handlebars +28 -11
  17. package/template/tsconfig.json +106 -2
  18. package/template-workspace/.agents/rstackjs-agent-skills-LICENSE +21 -0
  19. package/template-workspace/.agents/skills/rsbuild-best-practices/SKILL.md +57 -0
  20. package/template-workspace/.agents/skills/rsdoctor-analysis/SKILL.md +96 -0
  21. package/template-workspace/.agents/skills/rsdoctor-analysis/references/command-map.md +113 -0
  22. package/template-workspace/.agents/skills/rsdoctor-analysis/references/common-analysis-patterns.md +190 -0
  23. package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor-common.md +88 -0
  24. package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor-rspack.md +138 -0
  25. package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor-webpack.md +71 -0
  26. package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor.md +39 -0
  27. package/template-workspace/.agents/skills/rsdoctor-analysis/references/rsdoctor-data-types.md +103 -0
  28. package/template-workspace/.agents/skills/rslib-best-practices/SKILL.md +58 -0
  29. package/template-workspace/.agents/skills/rslib-modern-package/SKILL.md +173 -0
  30. package/template-workspace/.agents/skills/rspack-best-practices/SKILL.md +70 -0
  31. package/template-workspace/.agents/skills/rspack-tracing/SKILL.md +75 -0
  32. package/template-workspace/.agents/skills/rspack-tracing/references/bottlenecks.md +47 -0
  33. package/template-workspace/.agents/skills/rspack-tracing/references/tracing-guide.md +38 -0
  34. package/template-workspace/.agents/skills/rspack-tracing/scripts/analyze_trace.js +184 -0
  35. package/template-workspace/.agents/skills/rstest-best-practices/SKILL.md +133 -0
  36. package/template-workspace/.agents/skills-lock.json +95 -0
  37. package/template-workspace/AGENTS.md +45 -0
  38. package/template-workspace/oxfmt.config.ts +16 -0
  39. package/template-workspace/oxlint.config.ts +19 -0
  40. package/template-workspace/pnpm-workspace.yaml +12 -0
  41. package/template-workspace/scripts/bootstrap-agent-skills.mjs +95 -0
  42. package/template-workspace/scripts/validate-ultramodern-workspace.mjs.handlebars +188 -59
  43. 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
- function readText(relativePath) {
15
- return fs.readFileSync(path.join(root, relativePath), 'utf-8');
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
- function expectedModernDependency(packageName) {
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
- rootPackage.scripts?.['ultramodern:check'] ===
116
- 'node ./scripts/validate-ultramodern-workspace.mjs',
117
- 'Root must expose the ultramodern:check script',
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 depend on @modern-js/plugin-tanstack through ${expectedModernDependency('@modern-js/plugin-tanstack')}`,
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 depend on @modern-js/runtime through ${expectedModernDependency('@modern-js/runtime')}`,
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 depend on @modern-js/app-tools through ${expectedModernDependency('@modern-js/app-tools')}`,
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(config.includes('moduleFederationPlugin()'), `${configPath} must enable Module Federation`);
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(shellMf.includes('remoteCommerce@http://localhost:3021/mf-manifest.json'), 'Shell must reference commerce remote');
183
- assert(shellMf.includes('remoteIdentity@http://localhost:3022/mf-manifest.json'), 'Shell must reference identity remote');
184
- assert(shellMf.includes('remoteDesignSystem@http://localhost:3023/mf-manifest.json'), 'Shell must reference design-system remote');
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('"./Widget"'), 'Commerce remote must expose a widget');
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('"./Button"'), 'Design-system remote must expose Button');
193
- assert(designMf.includes('"./tokens"'), 'Design-system remote must expose tokens');
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('@modern-js/runtime')}`,
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('@modern-js/app-tools')}`,
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('@modern-js/plugin-bff')}`,
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(serviceConfig.includes("runtimeFramework: 'effect'"), 'Effect service must use Effect runtime');
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(serviceEntry.includes('defineEffectBff'), 'Effect service must expose defineEffectBff placeholder');
223
- assert(serviceEntry.includes('recommendationsEffectApi'), 'Effect service must use shared recommendations API');
224
-
225
- const serviceApi = readText('services/service-recommendations-effect/shared/effect/api.ts');
226
- assert(serviceApi.includes('HttpApi.make'), 'Effect shared API placeholder must define HttpApi');
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(topology.effectServices?.[0]?.runtime === 'effect', 'Topology must contain an Effect service');
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',
@@ -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
- }