pkg-scaffold 3.3.4 → 3.3.5

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/src/index.js CHANGED
@@ -2,10 +2,10 @@ import { DeadCodeDetector } from "./ast/DeadCodeDetector.js";
2
2
  import { OxcAnalyzer } from "./ast/OxcAnalyzer.js";
3
3
  /**
4
4
  * ============================================================================
5
- * šŸ“¦ pkg-scaffold v3.3.2: Unified Architectural Refactoring Orchestrator
5
+ * šŸ“¦ pkg-scaffold v3.4.0: Unified Architectural Refactoring Orchestrator
6
6
  * ============================================================================
7
7
  * Main execution bridge managing multi-pass compilation cycles, semantic cross-linking,
8
- * supply-chain validation audits, and automated git self-healing rollbacks.
8
+ * supply-chain validation audits, and automated structural healing rollbacks.
9
9
  */
10
10
 
11
11
  import fs from 'fs/promises';
@@ -31,7 +31,6 @@ import { SelfHealer } from './healing/SelfHealer.js';
31
31
  import { IncrementalCacheManager } from './performance/GraphCache.js';
32
32
  import { WorkerPool } from './performance/WorkerPool.js';
33
33
  import { SupplyChainGuard } from './performance/SupplyChainGuard.js';
34
- import { SecretDetector } from './performance/SecretDetector.js';
35
34
 
36
35
  /**
37
36
  * Primary Refactoring Engine Core Coordination Controller
@@ -61,7 +60,6 @@ export class RefactoringEngine {
61
60
 
62
61
  // Stage 5: Bind security audit utilities and performance cache rings
63
62
  this.supplyChainGuard = new SupplyChainGuard(this.context);
64
- this.secretDetector = new SecretDetector(this.context);
65
63
  this.cacheManager = new IncrementalCacheManager(this.context);
66
64
  this.workerPool = new WorkerPool(this.context);
67
65
  this.gitSandbox = new GitSandbox(this.context);
@@ -87,9 +85,12 @@ export class RefactoringEngine {
87
85
  await this.context.initialize();
88
86
  await this.pathMapper.loadMappings(this.context.tsconfigFilename);
89
87
 
88
+ // Always attempt workspace mesh initialization – it will auto-detect workspace
89
+ // configuration and flip `context.isWorkspaceEnabled` when found.
90
+ console.log(ansis.dim('🌐 Probing for monorepo workspace configuration...'));
91
+ await this.workspaceGraph.initializeWorkspaceMesh();
90
92
  if (this.context.isWorkspaceEnabled) {
91
- console.log(ansis.dim('🌐 Mapping local monorepo workspaces and package mesh layers...'));
92
- await this.workspaceGraph.initializeWorkspaceMesh();
93
+ console.log(ansis.dim('🌐 Monorepo workspace detected – mapping package mesh layers...'));
93
94
  }
94
95
 
95
96
  // Load asset fingerprints from disk cache to maximize cold-start performance
@@ -113,8 +114,6 @@ export class RefactoringEngine {
113
114
  }
114
115
  }
115
116
 
116
-
117
-
118
117
  // Pass 3: Process source file tokens using high-performance concurrent workers
119
118
  let parallelParseCompleted = false;
120
119
  if (sourceCodeFilesList.length > 10) {
@@ -145,6 +144,39 @@ export class RefactoringEngine {
145
144
  node.externalPackageUsage.forEach(pkg => this.context.usedExternalPackages.add(pkg));
146
145
  }
147
146
 
147
+ // Fix: Automatically mark active ecosystem packages as used.
148
+ // Maps internal plugin names to their canonical npm package names.
149
+ const pluginToPackageMap = {
150
+ 'typescript': 'typescript',
151
+ 'vitest': 'vitest',
152
+ 'eslint': 'eslint',
153
+ 'prettier': 'prettier',
154
+ 'tailwindcss': 'tailwindcss',
155
+ 'postcss': 'postcss',
156
+ 'jest': 'jest',
157
+ 'playwright': '@playwright/test',
158
+ 'cypress': 'cypress',
159
+ 'storybook': 'storybook',
160
+ 'nextjs': 'next',
161
+ 'nuxt': 'nuxt',
162
+ 'remix': '@remix-run/dev',
163
+ 'sveltekit': '@sveltejs/kit',
164
+ 'astro': 'astro'
165
+ };
166
+
167
+ activeFrameworkEcosystems.forEach(ecosystem => {
168
+ if (ecosystem !== 'universal-tooling-vectors') {
169
+ const pkgName = pluginToPackageMap[ecosystem] || ecosystem;
170
+ this.context.usedExternalPackages.add(pkgName);
171
+ }
172
+ });
173
+
174
+ // Ensure all workspace package names are pre-marked as used so they are
175
+ // never reported as unused dependencies in the manifest audit.
176
+ if (this.context.isWorkspaceEnabled) {
177
+ this.workspaceGraph.markWorkspacePackagesAsUsed();
178
+ }
179
+
148
180
  // Pass 4: Evaluate graph edges and link connections across the codebase mesh
149
181
  console.log(ansis.dim('šŸ”— Linking graph edges and checking structural usage paths...'));
150
182
  await this.linkDependencyGraph();
@@ -157,44 +189,37 @@ export class RefactoringEngine {
157
189
  this.circularDetector.formatCycles().forEach(c => console.log(ansis.dim(` • ${c}`)));
158
190
  }
159
191
 
160
- // NEW: Secret Detection
161
- console.log(ansis.dim('šŸ” Scanning for hardcoded secrets...'));
162
- const detectedSecrets = await this.secretDetector.scanCodebaseForSecrets(this.context);
163
- const secretStats = this.secretDetector.getSecretStats();
164
-
165
192
  // Pass 5: Compile metrics summary and print diagnostics report
166
- const analysisSummary = this.context.generateSummaryReport();
167
- analysisSummary.detectedSecrets = detectedSecrets;
168
- analysisSummary.secretStats = secretStats;
193
+ const analysisSummary = await this.context.generateSummaryReport();
169
194
  this.displayConsoleDiagnostics(analysisSummary);
170
195
 
171
- // Pass 6: Run self-healing automated transformations if --fix is set
172
- if (this.context.allowAutoFix) {
173
- const structuralModificationsStaged =
174
- analysisSummary.structuralIssuesDetected.deadFiles.length > 0 ||
175
- analysisSummary.structuralIssuesDetected.deadExports.length > 0 ||
176
- analysisSummary.structuralIssuesDetected.unusedDependencies.length > 0;
177
-
178
- if (structuralModificationsStaged) {
179
- console.log(ansis.bold.yellow('\nšŸ“‹ Proposed Optimization Plan:'));
180
- console.log(ansis.dim('------------------------------------------------------------'));
181
-
182
- if (analysisSummary.structuralIssuesDetected.deadFiles.length > 0) {
183
- console.log(ansis.bold(` šŸ—‘ļø Delete ${analysisSummary.structuralIssuesDetected.deadFiles.length} orphaned files:`));
184
- analysisSummary.structuralIssuesDetected.deadFiles.forEach(f => console.log(ansis.dim(` • ${f}`)));
185
- }
186
-
187
- if (analysisSummary.structuralIssuesDetected.deadExports.length > 0) {
188
- console.log(ansis.bold(` āœ‚ļø Prune ${analysisSummary.structuralIssuesDetected.deadExports.length} unused named exports:`));
189
- analysisSummary.structuralIssuesDetected.deadExports.forEach(e => console.log(ansis.dim(` • ${e.symbol} in ${e.file}:${e.line}`)));
190
- }
196
+ // Pass 6: Display Optimization Plan and Run Automated Structural Healing
197
+ const structuralModificationsStaged =
198
+ analysisSummary.structuralIssuesDetected.deadFiles.length > 0 ||
199
+ analysisSummary.structuralIssuesDetected.deadExports.length > 0 ||
200
+ analysisSummary.structuralIssuesDetected.unusedDependencies.length > 0;
201
+
202
+ if (structuralModificationsStaged) {
203
+ console.log(ansis.bold.yellow('\nšŸ“‹ Proposed Optimization Plan:'));
204
+ console.log(ansis.dim('------------------------------------------------------------'));
205
+
206
+ if (analysisSummary.structuralIssuesDetected.deadFiles.length > 0) {
207
+ console.log(ansis.bold(` šŸ—‘ļø Delete ${analysisSummary.structuralIssuesDetected.deadFiles.length} orphaned files:`));
208
+ analysisSummary.structuralIssuesDetected.deadFiles.forEach(f => console.log(ansis.dim(` • ${f}`)));
209
+ }
210
+
211
+ if (analysisSummary.structuralIssuesDetected.deadExports.length > 0) {
212
+ console.log(ansis.bold(` āœ‚ļø Prune ${analysisSummary.structuralIssuesDetected.deadExports.length} unused named exports:`));
213
+ analysisSummary.structuralIssuesDetected.deadExports.forEach(e => console.log(ansis.dim(` • ${e.symbol} in ${e.file}:${e.line}`)));
214
+ }
191
215
 
192
- if (analysisSummary.structuralIssuesDetected.unusedDependencies.length > 0) {
193
- console.log(ansis.bold(` šŸ“¦ Remove ${analysisSummary.structuralIssuesDetected.unusedDependencies.length} unused dependencies:`));
194
- analysisSummary.structuralIssuesDetected.unusedDependencies.forEach(d => console.log(ansis.dim(` • ${d.package} (${d.type} in ${d.manifest})`)));
195
- }
196
- console.log(ansis.dim('------------------------------------------------------------'));
216
+ if (analysisSummary.structuralIssuesDetected.unusedDependencies.length > 0) {
217
+ console.log(ansis.bold(` šŸ“¦ Remove ${analysisSummary.structuralIssuesDetected.unusedDependencies.length} unused dependencies:`));
218
+ analysisSummary.structuralIssuesDetected.unusedDependencies.forEach(d => console.log(ansis.dim(` • ${d.package} (${d.type} in ${d.manifest})`)));
219
+ }
220
+ console.log(ansis.dim('------------------------------------------------------------'));
197
221
 
222
+ if (this.context.allowAutoFix) {
198
223
  let proceed = this.context.skipConfirm;
199
224
  if (!proceed) {
200
225
  const answer = await rl.question(ansis.bold.cyan('\nā“ Apply these structural modifications? (y/N): '));
@@ -202,6 +227,7 @@ export class RefactoringEngine {
202
227
  }
203
228
 
204
229
  if (proceed) {
230
+ // Execute healing lifecycle (git-state-capture -> apply -> verify -> commit/rollback)
205
231
  await this.selfHealer.runSelfHealingLifecycle(async () => {
206
232
  for (const relPath of analysisSummary.structuralIssuesDetected.deadFiles) {
207
233
  const absPath = path.resolve(this.context.cwd, relPath);
@@ -261,21 +287,41 @@ export class RefactoringEngine {
261
287
 
262
288
  async linkDependencyGraph() {
263
289
  for (const [filePath, node] of this.context.graph.entries()) {
290
+ // Pass A: Link all explicit imports (static + dynamic + re-export sources)
264
291
  for (const specifier of node.explicitImports) {
265
292
  const resolvedPath = this.resolver.resolveModulePath(filePath, specifier);
266
293
  if (resolvedPath && this.context.graph.has(resolvedPath)) {
267
294
  this.context.graph.get(resolvedPath).incomingEdges.add(filePath);
268
295
  node.outgoingEdges.add(resolvedPath);
296
+
297
+ // Fix: Ensure all internal exports from a re-exported source are marked as used
298
+ // so the source file itself is never considered orphaned.
299
+ const targetNode = this.context.graph.get(resolvedPath);
300
+ const isReExport = Array.from(node.internalExports.values()).some(exp => exp.source === specifier);
301
+ if (isReExport) {
302
+ targetNode.isLibraryEntry = true; // Protect re-exported internal files
303
+ }
269
304
  }
270
305
  }
271
306
 
307
+ // Pass B: Link named-symbol imports through barrel/re-export chains
272
308
  for (const specToken of node.importedSymbols) {
273
309
  const delimiterIndex = specToken.indexOf(':');
274
310
  if (delimiterIndex === -1) continue;
275
311
  const specifier = specToken.slice(0, delimiterIndex);
276
312
  const symbol = specToken.slice(delimiterIndex + 1);
277
313
  const resolvedPath = this.resolver.resolveModulePath(filePath, specifier);
278
- if (resolvedPath && symbol !== '*') {
314
+
315
+ if (!resolvedPath) continue;
316
+
317
+ if (symbol === '*') {
318
+ // Wildcard import / re-export-all: add a direct edge to the resolved file.
319
+ if (this.context.graph.has(resolvedPath)) {
320
+ this.context.graph.get(resolvedPath).incomingEdges.add(filePath);
321
+ node.outgoingEdges.add(resolvedPath);
322
+ }
323
+ } else {
324
+ // Named import: trace through barrel files to the actual declaration origin.
279
325
  const traceResolution = await this.barrelParser.determineSymbolDeclarationOrigin(resolvedPath, symbol, this.context.graph);
280
326
  if (traceResolution && this.context.graph.has(traceResolution.originFile)) {
281
327
  this.context.graph.get(traceResolution.originFile).incomingEdges.add(filePath);
@@ -292,7 +338,6 @@ export class RefactoringEngine {
292
338
  const data = JSON.parse(text);
293
339
  const prodDeps = Object.keys(data.dependencies || {});
294
340
  const devDeps = Object.keys(data.devDependencies || {});
295
- const totalDependencies = [...prodDeps, ...devDeps];
296
341
 
297
342
  this.context.manifestDependencies.set(packageJsonPath, {
298
343
  dependencies: prodDeps,
@@ -300,66 +345,30 @@ export class RefactoringEngine {
300
345
  peerDependencies: Object.keys(data.peerDependencies || {}),
301
346
  optionalDependencies: Object.keys(data.optionalDependencies || {})
302
347
  });
303
-
304
- const supplyChainThreats = this.supplyChainGuard.detectTyposquattingAnomalies(totalDependencies);
305
- for (const anomaly of supplyChainThreats) {
306
- console.warn(ansis.bold.red(`🚨 Supply Chain Alert: Malicious package masking candidate discovered [${anomaly.maliciousCandidate}]. Mimics trusted library [${anomaly.targetMimicked}].`));
307
- }
308
- await this.supplyChainGuard.verifyIntegrityLockfileHashes(packageJsonPath);
309
- } catch {}
348
+ } catch (e) {}
310
349
  }
311
350
 
312
351
  displayConsoleDiagnostics(summary) {
313
- console.log(ansis.bold.cyan('\nšŸ“Š Operational Diagnostics Summary:'));
314
- console.log(ansis.dim('------------------------------------------------------------'));
315
- console.log(`ā±ļø Duration : ${summary.executionDuration}`);
316
- console.log(`šŸ“ Files Processed : ${summary.totalFilesProcessed}`);
317
- console.log(`🧠 Cache Hit Ratio : ${summary.graphCacheOptimization.ratio}`);
352
+ console.log(ansis.bold.cyan('\nšŸ“Š Codebase Optimization Summary Report'));
318
353
  console.log(ansis.dim('------------------------------------------------------------'));
319
-
320
- if (summary.structuralIssuesDetected.deadFiles.length > 0) {
321
- console.log(ansis.bold.red(`\nšŸ’€ Dead Files Detected (${summary.structuralIssuesDetected.deadFiles.length}):`));
322
- summary.structuralIssuesDetected.deadFiles.forEach(f => console.log(ansis.dim(` • ${f}`)));
323
- }
324
-
325
- if (summary.structuralIssuesDetected.deadExports.length > 0) {
326
- console.log(ansis.bold.red(`\nāœ‚ļø Dead Exports Detected (${summary.structuralIssuesDetected.deadExports.length}):`));
327
- summary.structuralIssuesDetected.deadExports.forEach(e => console.log(ansis.dim(` • ${e.symbol} in ${e.file}:${e.line}`)));
328
- }
329
-
330
- if (summary.structuralIssuesDetected.unusedDependencies.length > 0) {
331
- console.log(ansis.bold.red(`\nšŸ“¦ Unused Dependencies (${summary.structuralIssuesDetected.unusedDependencies.length}):`));
332
- summary.structuralIssuesDetected.unusedDependencies.forEach(d => console.log(ansis.dim(` • ${d.package} (${d.type} in ${d.manifest})`)));
333
- }
334
-
335
- if (summary.structuralIssuesDetected.securityThreats.length > 0) {
336
- console.log(ansis.bold.red(`
337
- šŸ›”ļø Security Threats (${summary.structuralIssuesDetected.securityThreats.length}):`));
338
- summary.structuralIssuesDetected.securityThreats.forEach(t => console.log(ansis.dim(` • ${t.identifier} in ${t.file}:${t.line} (Risk: ${t.riskCode})`)));
339
- }
340
-
341
- // Display detected secrets
342
- if (summary.detectedSecrets && summary.detectedSecrets.length > 0) {
343
- const criticalSecrets = summary.detectedSecrets.filter(s => s.severity === 'CRITICAL');
344
- const highSecrets = summary.detectedSecrets.filter(s => s.severity === 'HIGH');
345
-
346
- console.log(ansis.bold.red(`
347
- šŸ” Hardcoded Secrets Detected (${summary.detectedSecrets.length}):`));
348
-
349
- if (criticalSecrets.length > 0) {
350
- console.log(ansis.bold.red(` CRITICAL (${criticalSecrets.length}):`));
351
- criticalSecrets.forEach(s => {
352
- const relPath = s.file.split(/[\\/]/).slice(-2).join('/');
353
- console.log(ansis.dim(` • ${s.type} in ${relPath}:${s.line} [${s.variable}]`));
354
- });
354
+ console.log(`ā±ļø Analysis Duration: ${summary.executionDuration}`);
355
+ console.log(`šŸ“‚ Total Files Scanned: ${summary.totalFilesProcessed}`);
356
+ console.log(`šŸ’¾ Cache Optimization: ${summary.graphCacheOptimization.ratio} hits`);
357
+
358
+ console.log(ansis.bold('\nšŸ” Structural Integrity:'));
359
+ if (summary.structuralIssuesDetected.deadFiles.length === 0 &&
360
+ summary.structuralIssuesDetected.deadExports.length === 0 &&
361
+ summary.structuralIssuesDetected.unusedDependencies.length === 0) {
362
+ console.log(ansis.green(' āœ… No major structural debt detected.'));
363
+ } else {
364
+ if (summary.structuralIssuesDetected.deadFiles.length > 0) {
365
+ console.log(ansis.red(` āŒ Found ${summary.structuralIssuesDetected.deadFiles.length} orphaned/dead files.`));
355
366
  }
356
-
357
- if (highSecrets.length > 0) {
358
- console.log(ansis.bold.yellow(` HIGH (${highSecrets.length}):`));
359
- highSecrets.forEach(s => {
360
- const relPath = s.file.split(/[\\/]/).slice(-2).join('/');
361
- console.log(ansis.dim(` • ${s.type} in ${relPath}:${s.line} [${s.variable}]`));
362
- });
367
+ if (summary.structuralIssuesDetected.deadExports.length > 0) {
368
+ console.log(ansis.yellow(` āš ļø Found ${summary.structuralIssuesDetected.deadExports.length} unused named exports.`));
369
+ }
370
+ if (summary.structuralIssuesDetected.unusedDependencies.length > 0) {
371
+ console.log(ansis.yellow(` šŸ“¦ Found ${summary.structuralIssuesDetected.unusedDependencies.length} unused dependencies.`));
363
372
  }
364
373
  }
365
374
 
@@ -376,5 +385,13 @@ export class RefactoringEngine {
376
385
  if (cachedRecord.symbolSourceLocations) {
377
386
  Object.entries(cachedRecord.symbolSourceLocations).forEach(([k, v]) => node.symbolSourceLocations.set(k, v));
378
387
  }
388
+ // Restore fields that were previously missing from cache hydration
389
+ if (cachedRecord.externalPackageUsage) cachedRecord.externalPackageUsage.forEach(p => node.externalPackageUsage.add(p));
390
+ if (cachedRecord.rawStringReferences) cachedRecord.rawStringReferences.forEach(r => node.rawStringReferences.add(r));
391
+ if (cachedRecord.instantiatedIdentifiers) cachedRecord.instantiatedIdentifiers.forEach(id => node.instantiatedIdentifiers.add(id));
392
+ if (cachedRecord.propertyAccessChains) cachedRecord.propertyAccessChains.forEach(c => node.propertyAccessChains.add(c));
393
+ if (cachedRecord.localSuppressedRules) cachedRecord.localSuppressedRules.forEach(r => node.localSuppressedRules.add(r));
394
+ if (cachedRecord.calculatedDynamicImports) node.calculatedDynamicImports = cachedRecord.calculatedDynamicImports;
395
+ if (cachedRecord.isLibraryEntry !== undefined) node.isLibraryEntry = cachedRecord.isLibraryEntry;
379
396
  }
380
397
  }
@@ -31,18 +31,26 @@ async function processThreadChunks() {
31
31
  securityThreats: [],
32
32
  localSuppressedRules: new Set(),
33
33
  externalPackageUsage: new Set(),
34
- symbolSourceLocations: new Map()
34
+ symbolSourceLocations: new Map(),
35
+ calculatedDynamicImports: [],
36
+ jsxComponents: new Set(),
37
+ jsxProps: new Set(),
38
+ decorators: new Set()
35
39
  };
36
40
 
41
+ // Use the public getScriptKind() method added to ASTAnalyzer
42
+ const scriptKind = standaloneAnalyzer.getScriptKind(file);
43
+
37
44
  const sourceFile = ts.createSourceFile(
38
45
  file,
39
46
  text,
40
47
  ts.ScriptTarget.Latest,
41
48
  true,
42
- standaloneAnalyzer.getScriptKind(file)
49
+ scriptKind
43
50
  );
44
51
 
45
52
  standaloneAnalyzer.extractTopLevelJSDocSuppreessions(sourceFile, mockNode);
53
+ // Use the walkNode() alias that maps to walkAST() with the correct argument order
46
54
  standaloneAnalyzer.walkNode(sourceFile, sourceFile, mockNode);
47
55
 
48
56
  partialGraphPayloadResults.push({
@@ -57,10 +65,14 @@ async function processThreadChunks() {
57
65
  securityThreats: mockNode.securityThreats,
58
66
  localSuppressedRules: Array.from(mockNode.localSuppressedRules),
59
67
  externalPackageUsage: Array.from(mockNode.externalPackageUsage),
60
- symbolSourceLocations: Object.fromEntries(mockNode.symbolSourceLocations)
68
+ symbolSourceLocations: Object.fromEntries(mockNode.symbolSourceLocations),
69
+ calculatedDynamicImports: mockNode.calculatedDynamicImports
61
70
  });
62
- } catch {
63
- // Ignore unparseable or locked syntax nodes in thread loops
71
+ } catch (err) {
72
+ // Log parse errors in verbose mode so they are not silently swallowed
73
+ if (contextOptions.verbose) {
74
+ console.warn(`[Worker] Failed to parse ${file}: ${err.message}`);
75
+ }
64
76
  }
65
77
  }
66
78
 
@@ -54,6 +54,15 @@ export class PluginRegistry {
54
54
  // Backend Services (New in v4.0)
55
55
  const { GraphQLPlugin, DatabasePlugin } = await import('./ecosystems/BackendServices.js');
56
56
 
57
+ // Extended tooling plugins (New in v4.1)
58
+ const {
59
+ TailwindPlugin, PostcssPlugin, JestPlugin, VitestPlugin,
60
+ PlaywrightPlugin, CypressPlugin, StorybookPlugin,
61
+ EslintPlugin, PrettierPlugin, HuskyPlugin, LintStagedPlugin,
62
+ CommitlintPlugin, BabelPlugin, RollupPlugin, WebpackPlugin,
63
+ GithubActionsPlugin
64
+ } = await import('./ecosystems/MorePlugins.js');
65
+
57
66
  const builtins = [
58
67
  new NextJsPlugin(this.context),
59
68
  new NuxtPlugin(this.context),
@@ -66,7 +75,24 @@ export class PluginRegistry {
66
75
  new SveltePlugin(this.context),
67
76
  new AngularPlugin(this.context),
68
77
  new GraphQLPlugin(this.context),
69
- new DatabasePlugin(this.context)
78
+ new DatabasePlugin(this.context),
79
+ // Extended tooling plugins
80
+ new TailwindPlugin(this.context),
81
+ new PostcssPlugin(this.context),
82
+ new JestPlugin(this.context),
83
+ new VitestPlugin(this.context),
84
+ new PlaywrightPlugin(this.context),
85
+ new CypressPlugin(this.context),
86
+ new StorybookPlugin(this.context),
87
+ new EslintPlugin(this.context),
88
+ new PrettierPlugin(this.context),
89
+ new HuskyPlugin(this.context),
90
+ new LintStagedPlugin(this.context),
91
+ new CommitlintPlugin(this.context),
92
+ new BabelPlugin(this.context),
93
+ new RollupPlugin(this.context),
94
+ new WebpackPlugin(this.context),
95
+ new GithubActionsPlugin(this.context)
70
96
  ];
71
97
 
72
98
  builtins.forEach(p => {