entkapp 5.4.0 → 5.6.0

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 (76) hide show
  1. package/README.md +7 -1
  2. package/bin/cli.js +117 -58
  3. package/bin/cli.mjs +175 -0
  4. package/index.cjs +18 -0
  5. package/index.mjs +51 -0
  6. package/package.json +7 -6
  7. package/src/EngineContext.js +0 -6
  8. package/src/EngineContext.mjs +428 -0
  9. package/src/Initializer.mjs +82 -0
  10. package/src/analyzers/CodeSmellAnalyzer.mjs +106 -0
  11. package/src/analyzers/OxcAnalyzer.mjs +11 -0
  12. package/src/api/HeadlessAPI.js +31 -16
  13. package/src/api/HeadlessAPI.mjs +369 -0
  14. package/src/api/PluginSDK.mjs +135 -0
  15. package/src/ast/ASTAnalyzer.js +23 -97
  16. package/src/ast/ASTAnalyzer.mjs +742 -0
  17. package/src/ast/AdvancedAnalysis.mjs +586 -0
  18. package/src/ast/BarrelParser.mjs +230 -0
  19. package/src/ast/DeadCodeDetector.js +7 -5
  20. package/src/ast/DeadCodeDetector.mjs +92 -0
  21. package/src/ast/MagicDetector.js +43 -23
  22. package/src/ast/MagicDetector.mjs +203 -0
  23. package/src/ast/OxcAnalyzer.js +27 -190
  24. package/src/ast/OxcAnalyzer.mjs +188 -0
  25. package/src/ast/SecretScanner.mjs +374 -0
  26. package/src/healing/GitSandbox.mjs +82 -0
  27. package/src/healing/SelfHealer.mjs +48 -0
  28. package/src/index.js +41 -88
  29. package/src/index.mjs +1176 -0
  30. package/src/performance/GraphCache.js +0 -27
  31. package/src/performance/GraphCache.mjs +108 -0
  32. package/src/performance/SupplyChainGuard.mjs +92 -0
  33. package/src/performance/WorkerPool.js +4 -22
  34. package/src/performance/WorkerPool.mjs +132 -0
  35. package/src/performance/WorkerTaskRunner.js +0 -26
  36. package/src/performance/WorkerTaskRunner.mjs +144 -0
  37. package/src/plugins/BasePlugin.js +27 -16
  38. package/src/plugins/BasePlugin.mjs +240 -0
  39. package/src/plugins/PluginRegistry.js +0 -44
  40. package/src/plugins/PluginRegistry.mjs +203 -0
  41. package/src/plugins/ecosystems/BackendServices.mjs +197 -0
  42. package/src/plugins/ecosystems/GenericPlugins.mjs +142 -0
  43. package/src/plugins/ecosystems/ModernFrameworks.mjs +162 -0
  44. package/src/plugins/ecosystems/MorePlugins.mjs +562 -0
  45. package/src/plugins/ecosystems/NewPlugins.mjs +526 -0
  46. package/src/plugins/ecosystems/NextJsPlugin.mjs +45 -0
  47. package/src/plugins/ecosystems/PluginLoader.mjs +193 -0
  48. package/src/plugins/ecosystems/TypeScriptPlugin.mjs +56 -0
  49. package/src/plugins/ecosystems/UltimateBundle.js +0 -259
  50. package/src/plugins/ecosystems/UltimateBundle.mjs +1182 -0
  51. package/src/refractor/ImpactAnalyzer.mjs +92 -0
  52. package/src/refractor/SourceRewriter.mjs +86 -0
  53. package/src/refractor/TransactionManager.mjs +5 -0
  54. package/src/refractor/TypeIntegrity.mjs +4 -0
  55. package/src/resolution/BuildOrchestrator.mjs +46 -0
  56. package/src/resolution/CircularDetector.mjs +91 -0
  57. package/src/resolution/ConfigGenerator.mjs +83 -0
  58. package/src/resolution/ConfigLoader.js +26 -190
  59. package/src/resolution/ConfigLoader.mjs +94 -0
  60. package/src/resolution/DepencyResolver.mjs +66 -0
  61. package/src/resolution/DependencyFixer.mjs +88 -0
  62. package/src/resolution/DependencyProfiler.mjs +286 -0
  63. package/src/resolution/EntryPointDetector.mjs +134 -0
  64. package/src/resolution/FrameworkConfigParser.mjs +119 -0
  65. package/src/resolution/GraphAnalyzer.js +1 -65
  66. package/src/resolution/GraphAnalyzer.mjs +80 -0
  67. package/src/resolution/MigrationAnalyzer.mjs +60 -0
  68. package/src/resolution/PathMapper.js +0 -81
  69. package/src/resolution/PathMapper.mjs +82 -0
  70. package/src/resolution/TSConfigLoader.js +1 -3
  71. package/src/resolution/TSConfigLoader.mjs +162 -0
  72. package/src/resolution/WorkSpaceGraph.js +89 -260
  73. package/src/resolution/WorkSpaceGraph.mjs +183 -0
  74. package/src/resolution/WorkspaceDiagnostic.mjs +139 -0
  75. package/test.js +76 -0
  76. package/wrangler.toml +6 -0
@@ -0,0 +1,193 @@
1
+ /**
2
+ * ============================================================================
3
+ * Plugin Loader for entkapp v5.0.0
4
+ * ============================================================================
5
+ * Registers all built-in plugins from all ecosystem bundles.
6
+ * v5.0.0: Added 40+ new plugins with full dependency detection support.
7
+ */
8
+ import {
9
+ TailwindPlugin, PostcssPlugin, UnoCSSPlugin, StylelintPlugin,
10
+ JestPlugin, VitestPlugin, PlaywrightPlugin, CypressPlugin, StorybookPlugin, MswPlugin,
11
+ EslintPlugin, PrettierPlugin, BiomePlugin, OxlintPlugin,
12
+ HuskyPlugin, LintStagedPlugin, CommitlintPlugin, ChangesetPlugin,
13
+ BabelPlugin, SWCPlugin,
14
+ VitePlugin, EsbuildPlugin, RollupPlugin, WebpackPlugin, ParcelPlugin,
15
+ TurboPlugin, NxPlugin,
16
+ GithubActionsPlugin, DockerPlugin, TerraformPlugin,
17
+ EditorConfigPlugin, NvmPlugin, VoltaPlugin, DotenvPlugin,
18
+ PnpmPlugin, YarnPlugin, BunPlugin,
19
+ SwiperPlugin, QuillPlugin, EnvelopPlugin,
20
+ } from './MorePlugins.mjs';
21
+
22
+ import {
23
+ ReduxPlugin, ZustandPlugin, JotaiPlugin, RecoilPlugin, MobXPlugin, PiniaPlugin, TanStackQueryPlugin,
24
+ ReactRouterPlugin, TanStackRouterPlugin, VueRouterPlugin,
25
+ AntdPlugin, MuiPlugin, ShadcnPlugin, RadixUIPlugin, ChakraUIPlugin,
26
+ FramerMotionPlugin, GSAPPlugin,
27
+ ZodPlugin, YupPlugin, ValibotPlugin,
28
+ I18nextPlugin, VueI18nPlugin,
29
+ SentryPlugin, OpenTelemetryPlugin,
30
+ ExpressPlugin, FastifyPlugin, NestJsPlugin, HonoPlugin, KoaPlugin, ElysiaPlugin,
31
+ SocketIoPlugin,
32
+ } from './NewPlugins.mjs';
33
+
34
+ import {
35
+ GraphQLPlugin, ApolloPlugin, DatabasePlugin, PrismaPlugin, DrizzlePlugin, MongoosePlugin,
36
+ SupabasePlugin, FirebasePlugin, ClerkPlugin, TRPCPlugin,
37
+ } from './BackendServices.mjs';
38
+
39
+ import {
40
+ NuxtPlugin, RemixPlugin, SvelteKitPlugin, AstroPlugin, VitepressPlugin, GatsbyPlugin, RedwoodPlugin,
41
+ } from './GenericPlugins.mjs';
42
+
43
+ import {
44
+ ReactPlugin, VuePlugin, SveltePlugin, AngularPlugin, PreactPlugin, SolidPlugin, QwikPlugin, LitPlugin,
45
+ } from './ModernFrameworks.mjs';
46
+
47
+ export function loadAdditionalPlugins(registry) {
48
+ const ctx = registry.context;
49
+
50
+ // ── Frontend Frameworks ──────────────────────────────────────────────────
51
+ registry.register(new ReactPlugin(ctx));
52
+ registry.register(new VuePlugin(ctx));
53
+ registry.register(new SveltePlugin(ctx));
54
+ registry.register(new AngularPlugin(ctx));
55
+ registry.register(new PreactPlugin(ctx));
56
+ registry.register(new SolidPlugin(ctx));
57
+ registry.register(new QwikPlugin(ctx));
58
+ registry.register(new LitPlugin(ctx));
59
+
60
+ // ── Meta-Frameworks ──────────────────────────────────────────────────────
61
+ registry.register(new NuxtPlugin(ctx));
62
+ registry.register(new RemixPlugin(ctx));
63
+ registry.register(new SvelteKitPlugin(ctx));
64
+ registry.register(new AstroPlugin(ctx));
65
+ registry.register(new VitepressPlugin(ctx));
66
+ registry.register(new GatsbyPlugin(ctx));
67
+ registry.register(new RedwoodPlugin(ctx));
68
+
69
+ // ── Backend Frameworks ───────────────────────────────────────────────────
70
+ registry.register(new ExpressPlugin(ctx));
71
+ registry.register(new FastifyPlugin(ctx));
72
+ registry.register(new NestJsPlugin(ctx));
73
+ registry.register(new HonoPlugin(ctx));
74
+ registry.register(new KoaPlugin(ctx));
75
+ registry.register(new ElysiaPlugin(ctx));
76
+
77
+ // ── Data / API ───────────────────────────────────────────────────────────
78
+ registry.register(new GraphQLPlugin(ctx));
79
+ registry.register(new ApolloPlugin(ctx));
80
+ registry.register(new TRPCPlugin(ctx));
81
+ registry.register(new DatabasePlugin(ctx));
82
+ registry.register(new PrismaPlugin(ctx));
83
+ registry.register(new DrizzlePlugin(ctx));
84
+ registry.register(new MongoosePlugin(ctx));
85
+
86
+ // ── BaaS / Auth ──────────────────────────────────────────────────────────
87
+ registry.register(new SupabasePlugin(ctx));
88
+ registry.register(new FirebasePlugin(ctx));
89
+ registry.register(new ClerkPlugin(ctx));
90
+
91
+ // ── State Management ─────────────────────────────────────────────────────
92
+ registry.register(new ReduxPlugin(ctx));
93
+ registry.register(new ZustandPlugin(ctx));
94
+ registry.register(new JotaiPlugin(ctx));
95
+ registry.register(new RecoilPlugin(ctx));
96
+ registry.register(new MobXPlugin(ctx));
97
+ registry.register(new PiniaPlugin(ctx));
98
+ registry.register(new TanStackQueryPlugin(ctx));
99
+
100
+ // ── Routing ──────────────────────────────────────────────────────────────
101
+ registry.register(new ReactRouterPlugin(ctx));
102
+ registry.register(new TanStackRouterPlugin(ctx));
103
+ registry.register(new VueRouterPlugin(ctx));
104
+
105
+ // ── UI Components ────────────────────────────────────────────────────────
106
+ registry.register(new AntdPlugin(ctx));
107
+ registry.register(new MuiPlugin(ctx));
108
+ registry.register(new ShadcnPlugin(ctx));
109
+ registry.register(new RadixUIPlugin(ctx));
110
+ registry.register(new ChakraUIPlugin(ctx));
111
+
112
+ // ── Animation ────────────────────────────────────────────────────────────
113
+ registry.register(new FramerMotionPlugin(ctx));
114
+ registry.register(new GSAPPlugin(ctx));
115
+
116
+ // ── Validation ───────────────────────────────────────────────────────────
117
+ registry.register(new ZodPlugin(ctx));
118
+ registry.register(new YupPlugin(ctx));
119
+ registry.register(new ValibotPlugin(ctx));
120
+
121
+ // ── Internationalisation ─────────────────────────────────────────────────
122
+ registry.register(new I18nextPlugin(ctx));
123
+ registry.register(new VueI18nPlugin(ctx));
124
+
125
+ // ── Monitoring ───────────────────────────────────────────────────────────
126
+ registry.register(new SentryPlugin(ctx));
127
+ registry.register(new OpenTelemetryPlugin(ctx));
128
+
129
+ // ── Real-time ────────────────────────────────────────────────────────────
130
+ registry.register(new SocketIoPlugin(ctx));
131
+
132
+ // ── CSS / Styling ────────────────────────────────────────────────────────
133
+ registry.register(new TailwindPlugin(ctx));
134
+ registry.register(new PostcssPlugin(ctx));
135
+ registry.register(new UnoCSSPlugin(ctx));
136
+ registry.register(new StylelintPlugin(ctx));
137
+
138
+ // ── Linting / Formatting ─────────────────────────────────────────────────
139
+ registry.register(new EslintPlugin(ctx));
140
+ registry.register(new PrettierPlugin(ctx));
141
+ registry.register(new BiomePlugin(ctx));
142
+ registry.register(new OxlintPlugin(ctx));
143
+
144
+ // ── Git Hooks / Commit ───────────────────────────────────────────────────
145
+ registry.register(new HuskyPlugin(ctx));
146
+ registry.register(new LintStagedPlugin(ctx));
147
+ registry.register(new CommitlintPlugin(ctx));
148
+ registry.register(new ChangesetPlugin(ctx));
149
+
150
+ // ── Transpilers ──────────────────────────────────────────────────────────
151
+ registry.register(new BabelPlugin(ctx));
152
+ registry.register(new SWCPlugin(ctx));
153
+
154
+ // ── Build Tools ──────────────────────────────────────────────────────────
155
+ registry.register(new VitePlugin(ctx));
156
+ registry.register(new EsbuildPlugin(ctx));
157
+ registry.register(new RollupPlugin(ctx));
158
+ registry.register(new WebpackPlugin(ctx));
159
+ registry.register(new ParcelPlugin(ctx));
160
+
161
+ // ── Monorepo ─────────────────────────────────────────────────────────────
162
+ registry.register(new TurboPlugin(ctx));
163
+ registry.register(new NxPlugin(ctx));
164
+
165
+ // ── Testing ──────────────────────────────────────────────────────────────
166
+ registry.register(new JestPlugin(ctx));
167
+ registry.register(new VitestPlugin(ctx));
168
+ registry.register(new PlaywrightPlugin(ctx));
169
+ registry.register(new CypressPlugin(ctx));
170
+ registry.register(new StorybookPlugin(ctx));
171
+ registry.register(new MswPlugin(ctx));
172
+
173
+ // ── CI / Infra ───────────────────────────────────────────────────────────
174
+ registry.register(new GithubActionsPlugin(ctx));
175
+ registry.register(new DockerPlugin(ctx));
176
+ registry.register(new TerraformPlugin(ctx));
177
+
178
+ // ── Dev Environment ──────────────────────────────────────────────────────
179
+ registry.register(new EditorConfigPlugin(ctx));
180
+ registry.register(new NvmPlugin(ctx));
181
+ registry.register(new VoltaPlugin(ctx));
182
+ registry.register(new DotenvPlugin(ctx));
183
+
184
+ // ── Package Managers ─────────────────────────────────────────────────────
185
+ registry.register(new PnpmPlugin(ctx));
186
+ registry.register(new YarnPlugin(ctx));
187
+ registry.register(new BunPlugin(ctx));
188
+
189
+ // ── Misc Utilities ───────────────────────────────────────────────────────
190
+ registry.register(new SwiperPlugin(ctx));
191
+ registry.register(new QuillPlugin(ctx));
192
+ registry.register(new EnvelopPlugin(ctx));
193
+ }
@@ -0,0 +1,56 @@
1
+ import path from 'path';
2
+ import fs from 'fs/promises';
3
+ import { BasePlugin } from '../BasePlugin.mjs';
4
+
5
+ /**
6
+ * TypeScript Plugin for entkapp v5.0.0.
7
+ * Handles tsconfig.json detection, TypeScript-specific entry points,
8
+ * and missing dependency detection.
9
+ */
10
+ export class TypeScriptPlugin extends BasePlugin {
11
+ get name() {
12
+ return 'typescript';
13
+ }
14
+ getConfigFiles() {
15
+ return ['tsconfig.json', 'tsconfig.base.json', 'tsconfig.eslint.json', 'tsconfig.node.json', 'tsconfig.app.json'];
16
+ }
17
+ getRequiredPackages() {
18
+ return [
19
+ { name: 'typescript', dev: true },
20
+ { name: '@types/node', dev: true, optional: true },
21
+ ];
22
+ }
23
+ getRoutePatterns() {
24
+ return [
25
+ /src\/index\.ts$/,
26
+ /src\/main\.ts$/,
27
+ /src\/lib\.ts$/,
28
+ /.*\.d\.ts$/
29
+ ];
30
+ }
31
+ getRequiredSystemContracts() {
32
+ return ['default'];
33
+ }
34
+ /**
35
+ * Custom Getter for v3.2.0: Get the compiler version from the project.
36
+ */
37
+ async getCompilerVersion() {
38
+ try {
39
+ const packageJsonPath = path.join(this.context.cwd, 'package.json');
40
+ const content = await fs.readFile(packageJsonPath, 'utf8');
41
+ const pkg = JSON.parse(content);
42
+ return pkg.devDependencies?.typescript || pkg.dependencies?.typescript || 'unknown';
43
+ } catch {
44
+ return 'not installed';
45
+ }
46
+ }
47
+ async isActive(baseDir) {
48
+ for (const file of this.getConfigFiles()) {
49
+ try {
50
+ await fs.access(path.join(baseDir, file));
51
+ return true;
52
+ } catch {}
53
+ }
54
+ return false;
55
+ }
56
+ }
@@ -8,7 +8,6 @@
8
8
  import path from 'path';
9
9
  import fs from 'fs/promises';
10
10
  import { BasePlugin } from '../BasePlugin.js';
11
- import { FrameworkConfigParser } from '../../resolution/FrameworkConfigParser.js';
12
11
 
13
12
 
14
13
  export class GraphQLPlugin extends BasePlugin {
@@ -212,27 +211,6 @@ export class NuxtPlugin extends BasePlugin {
212
211
  }
213
212
  return false;
214
213
  }
215
- detectEntryPoints(content, filePath) {
216
- if (this.getConfigFiles().some(f => filePath.endsWith(f))) {
217
- const parser = new FrameworkConfigParser(this.context);
218
- const { entries } = parser.parse(content, filePath);
219
- return Array.from(entries);
220
- }
221
- return [];
222
- }
223
- async analyze(node, filePath) {
224
- if (this.getConfigFiles().some(f => filePath.endsWith(f))) {
225
- node.isEntry = true;
226
- if (node.rawCode) {
227
- const parser = new FrameworkConfigParser(this.context);
228
- const { aliases, entries } = parser.parse(node.rawCode, filePath);
229
- if (aliases.size > 0) node.frameworkAliases = aliases;
230
- if (entries.size > 0) node.frameworkEntries = entries;
231
- if (node.rawCode.includes('modules:')) node.hasNuxtModules = true;
232
- if (node.rawCode.includes('components:')) node.hasNuxtComponentsConfig = true;
233
- }
234
- }
235
- }
236
214
  }
237
215
 
238
216
  export class RemixPlugin extends BasePlugin {
@@ -255,21 +233,6 @@ export class RemixPlugin extends BasePlugin {
255
233
  }
256
234
  return false;
257
235
  }
258
- detectEntryPoints(content, filePath) {
259
- if (filePath.endsWith('remix.config.js') || filePath.includes('vite.config.')) {
260
- const parser = new FrameworkConfigParser(this.context);
261
- const { entries } = parser.parse(content, filePath);
262
- return Array.from(entries);
263
- }
264
- return [];
265
- }
266
- async analyze(node, filePath) {
267
- if (filePath.endsWith('remix.config.js')) {
268
- node.isEntry = true;
269
- if (node.rawCode?.includes('ignoredRouteFiles:')) node.hasRemixIgnoredRoutes = true;
270
- if (node.rawCode?.includes('serverBuildPath:')) node.hasRemixServerBuildPath = true;
271
- }
272
- }
273
236
  }
274
237
 
275
238
  export class SvelteKitPlugin extends BasePlugin {
@@ -288,29 +251,6 @@ export class SvelteKitPlugin extends BasePlugin {
288
251
  async isActive(baseDir) {
289
252
  try { await fs.access(path.join(baseDir, 'svelte.config.js')); return true; } catch { return false; }
290
253
  }
291
- detectEntryPoints(content, filePath) {
292
- if (filePath.includes('svelte.config.')) {
293
- const parser = new FrameworkConfigParser(this.context);
294
- const { entries } = parser.parse(content, filePath);
295
- return Array.from(entries);
296
- }
297
- return [];
298
- }
299
- async analyze(node, filePath) {
300
- if (filePath.includes('svelte.config.')) {
301
- node.isEntry = true;
302
- if (node.rawCode) {
303
- const parser = new FrameworkConfigParser(this.context);
304
- const { aliases, entries } = parser.parse(node.rawCode, filePath);
305
- if (aliases.size > 0) {
306
- node.frameworkAliases = aliases;
307
- node.hasSvelteAliases = true;
308
- }
309
- if (entries.size > 0) node.frameworkEntries = entries;
310
- if (node.rawCode.includes('adapter:')) node.hasSvelteAdapter = true;
311
- }
312
- }
313
- }
314
254
  }
315
255
 
316
256
  export class AstroPlugin extends BasePlugin {
@@ -325,39 +265,12 @@ export class AstroPlugin extends BasePlugin {
325
265
  }
326
266
  return false;
327
267
  }
328
- detectEntryPoints(content, filePath) {
329
- if (this.getConfigFiles().some(f => filePath.endsWith(f))) {
330
- const parser = new FrameworkConfigParser(this.context);
331
- const { entries } = parser.parse(content, filePath);
332
- return Array.from(entries);
333
- }
334
- return [];
335
- }
336
- async analyze(node, filePath) {
337
- if (this.getConfigFiles().some(f => filePath.endsWith(f))) {
338
- node.isEntry = true;
339
- if (node.rawCode) {
340
- const parser = new FrameworkConfigParser(this.context);
341
- const { aliases, entries } = parser.parse(node.rawCode, filePath);
342
- if (aliases.size > 0) node.frameworkAliases = aliases;
343
- if (entries.size > 0) node.frameworkEntries = entries;
344
- if (node.rawCode.includes('integrations:')) node.hasAstroIntegrations = true;
345
- if (node.rawCode.includes('output:')) node.hasAstroOutputConfig = true;
346
- }
347
- }
348
- }
349
268
  }
350
269
 
351
270
  export class VitepressPlugin extends BasePlugin {
352
271
  get name() { return 'vitepress'; }
353
272
  getConfigFiles() { return ['package.json']; }
354
273
  getRequiredPackages() { return [{ name: 'vitepress', dev: true }]; }
355
-
356
- getRoutePatterns() {
357
- // Protection: Every file inside a .vitepress folder is treated as an entry point
358
- return [/\/\.vitepress\//];
359
- }
360
-
361
274
  async isActive(baseDir) {
362
275
  try {
363
276
  const pkgJson = JSON.parse(await fs.readFile(path.join(baseDir, 'package.json'), 'utf8'));
@@ -369,62 +282,6 @@ export class VitepressPlugin extends BasePlugin {
369
282
  return hasDep;
370
283
  } catch { return false; }
371
284
  }
372
-
373
- async runDependencyDiagnostics(baseDir) {
374
- const diagnostics = await super.runDependencyDiagnostics(baseDir);
375
-
376
- let pkg = null;
377
- try {
378
- const raw = await fs.readFile(path.join(baseDir, 'package.json'), 'utf8');
379
- pkg = JSON.parse(raw);
380
- } catch { return diagnostics; }
381
-
382
- const scripts = pkg.scripts || {};
383
- const allDeps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };
384
- const hasVitepressDep = 'vitepress' in allDeps;
385
-
386
- // Check if any script uses vitepress
387
- const hasVitepressCommand = Object.values(scripts).some(s => s.includes('vitepress'));
388
-
389
- // Logic for .vitepress folder existence
390
- let hasVitepressFolder = false;
391
- const possibleDirs = ['.vitepress', 'docs/.vitepress', 'docs/docs/.vitepress'];
392
- for (const d of possibleDirs) {
393
- try {
394
- await fs.access(path.join(baseDir, d));
395
- hasVitepressFolder = true;
396
- break;
397
- } catch {}
398
- }
399
-
400
- // Scenario 1: build cmd/dependency exists but no folder -> unused dependency
401
- if ((hasVitepressCommand || hasVitepressDep) && !hasVitepressFolder) {
402
- diagnostics.push({
403
- plugin: this.name,
404
- severity: 'warning',
405
- message: `Plugin "${this.name}": "vitepress" is defined in package.json or scripts, but no ".vitepress" folder was found. This might be an unused dependency.`
406
- });
407
- }
408
-
409
- // Scenario 2: folder exists but no dependency -> missing dependency
410
- if (hasVitepressFolder && !hasVitepressDep) {
411
- diagnostics.push({
412
- plugin: this.name,
413
- severity: 'error',
414
- message: `Plugin "${this.name}": ".vitepress" folder exists, but "vitepress" package is not installed in package.json.`
415
- });
416
- }
417
-
418
- return diagnostics;
419
- }
420
-
421
- async analyze(node, filePath) {
422
- // If it's a config file inside .vitepress, mark it
423
- if (filePath.includes('/.vitepress/config.') || filePath.includes('/.vitepress/theme/')) {
424
- node.isEntry = true;
425
- node.isVitepressInternal = true;
426
- }
427
- }
428
285
  }
429
286
 
430
287
  export class GatsbyPlugin extends BasePlugin {
@@ -464,14 +321,6 @@ export class NextJsPlugin extends BasePlugin {
464
321
  }
465
322
  return false;
466
323
  }
467
- async analyze(node, filePath) {
468
- if (this.getConfigFiles().some(f => filePath.endsWith(f))) {
469
- node.isEntry = true;
470
- if (node.rawCode?.includes('rewrites')) node.hasNextRewrites = true;
471
- if (node.rawCode?.includes('redirects')) node.hasNextRedirects = true;
472
- if (node.rawCode?.includes('images:')) node.hasNextImageConfig = true;
473
- }
474
- }
475
324
  }
476
325
 
477
326
  export class ReactPlugin extends BasePlugin {
@@ -594,42 +443,6 @@ export class VitePlugin extends BasePlugin {
594
443
  }
595
444
  return false;
596
445
  }
597
- detectEntryPoints(content, filePath) {
598
- if (filePath.includes('vite.config.')) {
599
- const parser = new FrameworkConfigParser(this.context);
600
- const { entries } = parser.parse(content, filePath);
601
- return Array.from(entries);
602
- }
603
- return [];
604
- }
605
- async analyze(node, filePath) {
606
- if (filePath.includes('vite.config.')) {
607
- // Mark config as an entry so its own dependencies are tracked
608
- node.isEntry = true;
609
-
610
- // UPGRADE: Use FrameworkConfigParser for deep structural extraction
611
- if (node.rawCode) {
612
- const parser = new FrameworkConfigParser(this.context);
613
- const { aliases, entries } = parser.parse(node.rawCode, filePath);
614
-
615
- if (aliases.size > 0) {
616
- node.frameworkAliases = aliases;
617
- node.viteAliasesDetected = true;
618
- }
619
-
620
- if (entries.size > 0) {
621
- node.frameworkEntries = entries;
622
- node.hasCustomViteInputs = true;
623
- }
624
-
625
- // Detect Plugins (Keep existing simple check)
626
- const pluginsPattern = /plugins\s*:\s*\[([\s\S]*?)\]/g;
627
- if (pluginsPattern.test(node.rawCode)) {
628
- node.hasVitePlugins = true;
629
- }
630
- }
631
- }
632
- }
633
446
  }
634
447
 
635
448
  export class EsbuildPlugin extends BasePlugin {
@@ -666,30 +479,6 @@ export class WebpackPlugin extends BasePlugin {
666
479
  }
667
480
  return false;
668
481
  }
669
- detectEntryPoints(content, filePath) {
670
- if (this.getConfigFiles().some(f => filePath.endsWith(f))) {
671
- const parser = new FrameworkConfigParser(this.context);
672
- const { entries } = parser.parse(content, filePath);
673
- return Array.from(entries);
674
- }
675
- return [];
676
- }
677
- detectEntryPoints(content, filePath) {
678
- if (this.getConfigFiles().some(f => filePath.endsWith(f))) {
679
- const parser = new FrameworkConfigParser(this.context);
680
- const { entries } = parser.parse(content, filePath);
681
- return Array.from(entries);
682
- }
683
- return [];
684
- }
685
- async analyze(node, filePath) {
686
- if (this.getConfigFiles().some(f => filePath.endsWith(f))) {
687
- node.isEntry = true;
688
- if (node.rawCode?.includes('entry:')) node.hasWebpackEntries = true;
689
- if (node.rawCode?.includes('resolve:')) node.hasWebpackResolve = true;
690
- if (node.rawCode?.includes('plugins:')) node.hasWebpackPlugins = true;
691
- }
692
- }
693
482
  }
694
483
 
695
484
  export class ParcelPlugin extends BasePlugin {
@@ -732,14 +521,6 @@ export class TailwindPlugin extends BasePlugin {
732
521
  }
733
522
  return false;
734
523
  }
735
- async analyze(node, filePath) {
736
- if (this.getConfigFiles().some(f => filePath.endsWith(f))) {
737
- node.isEntry = true;
738
- if (node.rawCode?.includes('content:')) node.hasTailwindContent = true;
739
- if (node.rawCode?.includes('theme:')) node.hasTailwindTheme = true;
740
- if (node.rawCode?.includes('plugins:')) node.hasTailwindPlugins = true;
741
- }
742
- }
743
524
  }
744
525
 
745
526
  export class PostcssPlugin extends BasePlugin {
@@ -884,13 +665,6 @@ export class JestPlugin extends BasePlugin {
884
665
  async isActive(baseDir) {
885
666
  try { await fs.access(path.join(baseDir, 'jest.config.js')); return true; } catch { return false; }
886
667
  }
887
- async analyze(node, filePath) {
888
- if (filePath.endsWith('jest.config.js')) {
889
- node.isEntry = true;
890
- if (node.rawCode?.includes('testEnvironment:')) node.hasJestTestEnv = true;
891
- if (node.rawCode?.includes('setupFiles:')) node.hasJestSetupFiles = true;
892
- }
893
- }
894
668
  }
895
669
 
896
670
  export class VitestPlugin extends BasePlugin {
@@ -903,39 +677,6 @@ export class VitestPlugin extends BasePlugin {
903
677
  }
904
678
  return false;
905
679
  }
906
- detectEntryPoints(content, filePath) {
907
- if (this.getConfigFiles().some(f => filePath.endsWith(f))) {
908
- const parser = new FrameworkConfigParser(this.context);
909
- const { entries } = parser.parse(content, filePath);
910
- return Array.from(entries);
911
- }
912
- return [];
913
- }
914
- detectEntryPoints(content, filePath) {
915
- if (this.getConfigFiles().some(f => filePath.endsWith(f))) {
916
- const parser = new FrameworkConfigParser(this.context);
917
- const { entries } = parser.parse(content, filePath);
918
- return Array.from(entries);
919
- }
920
- return [];
921
- }
922
- async analyze(node, filePath) {
923
- if (this.getConfigFiles().some(f => filePath.endsWith(f))) {
924
- node.isEntry = true;
925
- if (node.rawCode) {
926
- const parser = new FrameworkConfigParser(this.context);
927
- const { aliases, entries } = parser.parse(node.rawCode, filePath);
928
- if (aliases.size > 0) {
929
- node.frameworkAliases = aliases;
930
- node.hasWebpackAliases = true;
931
- }
932
- if (entries.size > 0) {
933
- node.frameworkEntries = entries;
934
- node.hasWebpackEntries = true;
935
- }
936
- }
937
- }
938
- }
939
680
  }
940
681
 
941
682
  export class PlaywrightPlugin extends BasePlugin {