@vibecheckai/cli 3.2.0 → 3.2.2

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 (60) hide show
  1. package/bin/runners/lib/agent-firewall/change-packet/builder.js +214 -0
  2. package/bin/runners/lib/agent-firewall/change-packet/schema.json +228 -0
  3. package/bin/runners/lib/agent-firewall/change-packet/store.js +200 -0
  4. package/bin/runners/lib/agent-firewall/claims/claim-types.js +21 -0
  5. package/bin/runners/lib/agent-firewall/claims/extractor.js +214 -0
  6. package/bin/runners/lib/agent-firewall/claims/patterns.js +24 -0
  7. package/bin/runners/lib/agent-firewall/evidence/auth-evidence.js +88 -0
  8. package/bin/runners/lib/agent-firewall/evidence/contract-evidence.js +75 -0
  9. package/bin/runners/lib/agent-firewall/evidence/env-evidence.js +118 -0
  10. package/bin/runners/lib/agent-firewall/evidence/resolver.js +102 -0
  11. package/bin/runners/lib/agent-firewall/evidence/route-evidence.js +142 -0
  12. package/bin/runners/lib/agent-firewall/evidence/side-effect-evidence.js +145 -0
  13. package/bin/runners/lib/agent-firewall/fs-hook/daemon.js +19 -0
  14. package/bin/runners/lib/agent-firewall/fs-hook/installer.js +87 -0
  15. package/bin/runners/lib/agent-firewall/fs-hook/watcher.js +184 -0
  16. package/bin/runners/lib/agent-firewall/git-hook/pre-commit.js +163 -0
  17. package/bin/runners/lib/agent-firewall/ide-extension/cursor.js +107 -0
  18. package/bin/runners/lib/agent-firewall/ide-extension/vscode.js +68 -0
  19. package/bin/runners/lib/agent-firewall/ide-extension/windsurf.js +66 -0
  20. package/bin/runners/lib/agent-firewall/interceptor/base.js +304 -0
  21. package/bin/runners/lib/agent-firewall/interceptor/cursor.js +35 -0
  22. package/bin/runners/lib/agent-firewall/interceptor/vscode.js +35 -0
  23. package/bin/runners/lib/agent-firewall/interceptor/windsurf.js +34 -0
  24. package/bin/runners/lib/agent-firewall/policy/default-policy.json +84 -0
  25. package/bin/runners/lib/agent-firewall/policy/engine.js +72 -0
  26. package/bin/runners/lib/agent-firewall/policy/loader.js +143 -0
  27. package/bin/runners/lib/agent-firewall/policy/rules/auth-drift.js +50 -0
  28. package/bin/runners/lib/agent-firewall/policy/rules/contract-drift.js +50 -0
  29. package/bin/runners/lib/agent-firewall/policy/rules/fake-success.js +61 -0
  30. package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +50 -0
  31. package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +50 -0
  32. package/bin/runners/lib/agent-firewall/policy/rules/scope.js +93 -0
  33. package/bin/runners/lib/agent-firewall/policy/rules/unsafe-side-effect.js +57 -0
  34. package/bin/runners/lib/agent-firewall/policy/schema.json +183 -0
  35. package/bin/runners/lib/agent-firewall/policy/verdict.js +54 -0
  36. package/bin/runners/lib/agent-firewall/truthpack/index.js +67 -0
  37. package/bin/runners/lib/agent-firewall/truthpack/loader.js +116 -0
  38. package/bin/runners/lib/agent-firewall/unblock/planner.js +337 -0
  39. package/bin/runners/lib/analysis-core.js +198 -180
  40. package/bin/runners/lib/analyzers.js +1119 -536
  41. package/bin/runners/lib/cli-output.js +236 -210
  42. package/bin/runners/lib/detectors-v2.js +547 -785
  43. package/bin/runners/lib/fingerprint.js +377 -0
  44. package/bin/runners/lib/route-truth.js +1167 -322
  45. package/bin/runners/lib/scan-output.js +144 -738
  46. package/bin/runners/lib/ship-output-enterprise.js +239 -0
  47. package/bin/runners/lib/terminal-ui.js +188 -770
  48. package/bin/runners/lib/truth.js +1004 -321
  49. package/bin/runners/lib/unified-output.js +162 -158
  50. package/bin/runners/runAgent.js +161 -0
  51. package/bin/runners/runFirewall.js +134 -0
  52. package/bin/runners/runFirewallHook.js +56 -0
  53. package/bin/runners/runScan.js +113 -10
  54. package/bin/runners/runShip.js +7 -8
  55. package/bin/runners/runTruth.js +89 -0
  56. package/mcp-server/agent-firewall-interceptor.js +164 -0
  57. package/mcp-server/index.js +347 -313
  58. package/mcp-server/truth-context.js +131 -90
  59. package/mcp-server/truth-firewall-tools.js +1412 -1045
  60. package/package.json +1 -1
@@ -1,15 +1,16 @@
1
1
  /**
2
- * Truth Context - MCP Tools for Evidence-Backed AI
3
- *
4
- * Core Context Engine tools that provide truth-backed context for AI agents.
5
- * All responses include citations (file/line) and confidence levels.
6
- *
7
- * This is the "Truth Firewall" made visible as "Evidence Pack" / "Truth Pack".
8
- *
2
+ * Truth Context MCP Tools for EvidenceBacked AI
3
+ *
4
+ * Core context-engine tools that surface **truth-backed** context for AI agents.
5
+ * Every response is grounded in concrete evidence with file/line citations
6
+ * and explicit confidence scores.
7
+ *
8
+ * This is the "Truth Firewall", exposed to agents as an "Evidence Pack" / "Truth Pack". [web:3]
9
+ *
9
10
  * Tools:
10
- * vibecheck.ctx - Get repo truth bundle (routes, auth, billing, env, schema)
11
- * vibecheck.verify_claim - Verify a claim has evidence
12
- * vibecheck.evidence - Get evidence for a specific file/function
11
+ * - vibecheck.ctx Build a repo-level Truth Pack (routes, auth, billing, env, schema)
12
+ * - vibecheck.verify_claim Check whether a claim is backed by real evidence
13
+ * - vibecheck.evidence – Pull code-level evidence for a specific file/function
13
14
  */
14
15
 
15
16
  import fs from "fs/promises";
@@ -23,60 +24,72 @@ import { execSync } from "child_process";
23
24
  export const TRUTH_CONTEXT_TOOLS = [
24
25
  {
25
26
  name: "vibecheck.ctx",
26
- description: `📋 Get repo Truth Pack routes, auth, billing, env vars, schema.
27
-
28
- Returns evidence-backed context with file/line citations.
29
- Use this before making any claims about the codebase.
27
+ description: `📋 Build a repo Truth Pack: routes, auth, billing, env vars, schema.
28
+
29
+ Generates an evidence-backed context bundle with file/line citations.
30
+ Use this before the agent makes any architectural or behavioral claims
31
+ about the codebase.
30
32
 
31
33
  Returns:
32
- - routes: All defined routes with handlers and middleware
33
- - auth: Auth guards, protected routes, auth flow
34
- - billing: Payment gates, subscription checks, paid features
35
- - env: Environment variables (declared vs used)
36
- - schema: Database schema, API contracts
37
- - confidence: Overall confidence score (0-1)`,
34
+ - routes: All detected routes with handlers and middleware
35
+ - auth: Auth guards, protected routes, auth flow indicators
36
+ - billing: Payment gates, subscription checks, paid feature indicators
37
+ - env: Environment variables (declared vs used, mismatches)
38
+ - schema: Database schema and TypeScript contracts
39
+ - confidence: Aggregate confidence score (01) for the extracted view`,
38
40
  inputSchema: {
39
41
  type: "object",
40
42
  properties: {
41
43
  scope: {
42
44
  type: "string",
43
45
  enum: ["all", "routes", "auth", "billing", "env", "schema"],
44
- description: "What context to extract (default: all)",
46
+ description: "Which slice of context to extract (default: all)",
45
47
  default: "all",
46
48
  },
47
49
  path: {
48
50
  type: "string",
49
- description: "Project path (default: current directory)",
51
+ description: "Project root path (default: current working directory)",
50
52
  },
51
53
  },
52
54
  },
53
55
  },
54
56
  {
55
57
  name: "vibecheck.verify_claim",
56
- description: `🔍 Verify a claim has evidence Truth Firewall check.
57
-
58
- Before claiming something exists or works, verify it.
59
- Returns evidence (file/line) or rejection with reason.
58
+ description: `🔍 Truth Firewall check – verify that a claim is backed by code.
59
+
60
+ Run this before asserting that something exists, is configured, or is enforced.
61
+ Returns concrete evidence (file/line) when the claim is supported,
62
+ or a structured rejection with an explanation when it is not.
60
63
 
61
64
  Examples:
62
- - "Route /api/users exists" Verified with handler at src/routes/users.ts:45
63
- - "Auth is required for /admin" Verified with middleware at src/middleware/auth.ts:12
64
- - "Stripe is configured" → REJECTED: No evidence of Stripe integration found`,
65
+ - "Route /api/users exists" VERIFIED with handler at src/routes/users.ts:45
66
+ - "Auth is required for /admin" VERIFIED via middleware at src/middleware/auth.ts:12
67
+ - "Stripe is configured" → REJECTED: No evidence of Stripe integration found`,
65
68
  inputSchema: {
66
69
  type: "object",
67
70
  properties: {
68
71
  claim_type: {
69
72
  type: "string",
70
- enum: ["route", "endpoint", "env_var", "middleware", "auth_guard", "billing_gate", "file", "function"],
71
- description: "Type of claim to verify",
73
+ enum: [
74
+ "route",
75
+ "endpoint",
76
+ "env_var",
77
+ "middleware",
78
+ "auth_guard",
79
+ "billing_gate",
80
+ "file",
81
+ "function",
82
+ ],
83
+ description: "Category of claim to verify",
72
84
  },
73
85
  claim: {
74
86
  type: "string",
75
- description: "The claim to verify (e.g., '/api/users', 'AUTH_SECRET', 'authMiddleware')",
87
+ description:
88
+ "The claim subject (e.g. '/api/users', 'AUTH_SECRET', 'authMiddleware')",
76
89
  },
77
90
  path: {
78
91
  type: "string",
79
- description: "Project path (default: current directory)",
92
+ description: "Project root path (default: current working directory)",
80
93
  },
81
94
  },
82
95
  required: ["claim_type", "claim"],
@@ -84,33 +97,35 @@ Examples:
84
97
  },
85
98
  {
86
99
  name: "vibecheck.evidence",
87
- description: `📎 Get evidence for a file/function citations with context.
88
-
89
- Returns the actual code with line numbers for citation.
90
- Use this when you need to reference specific code in your response.`,
100
+ description: `📎 Retrieve code evidence for a file or symbol.
101
+
102
+ Returns an annotated code snippet with line numbers for precise citation.
103
+ Use this when the agent needs to quote or reason about specific code blocks
104
+ in its response.`,
91
105
  inputSchema: {
92
106
  type: "object",
93
107
  properties: {
94
108
  file: {
95
109
  type: "string",
96
- description: "File path relative to project root",
110
+ description: "File path relative to the project root",
97
111
  },
98
112
  function_name: {
99
113
  type: "string",
100
- description: "Optional function/class name to find",
114
+ description: "Optional function/class name to locate within the file",
101
115
  },
102
116
  line: {
103
117
  type: "number",
104
- description: "Optional specific line number",
118
+ description: "Optional 1-based line number to center the snippet on",
105
119
  },
106
120
  context_lines: {
107
121
  type: "number",
108
- description: "Lines of context around target (default: 10)",
122
+ description:
123
+ "Number of lines of context before/after the target (default: 10)",
109
124
  default: 10,
110
125
  },
111
126
  path: {
112
127
  type: "string",
113
- description: "Project path (default: current directory)",
128
+ description: "Project root path (default: current working directory)",
114
129
  },
115
130
  },
116
131
  required: ["file"],
@@ -119,7 +134,7 @@ Use this when you need to reference specific code in your response.`,
119
134
  ];
120
135
 
121
136
  // ============================================================================
122
- // TOOL HANDLERS
137
+ // TOOL DISPATCH
123
138
  // ============================================================================
124
139
 
125
140
  export async function handleTruthContextTool(toolName, args) {
@@ -168,10 +183,11 @@ async function getTruthPack(projectPath, scope) {
168
183
  truthPack.sections.schema = await extractSchema(projectPath);
169
184
  }
170
185
 
171
- // Calculate overall confidence
172
186
  const sections = Object.values(truthPack.sections);
173
187
  if (sections.length > 0) {
174
- truthPack.confidence = sections.reduce((sum, s) => sum + (s.confidence || 0), 0) / sections.length;
188
+ truthPack.confidence =
189
+ sections.reduce((sum, section) => sum + (section.confidence || 0), 0) /
190
+ sections.length;
175
191
  }
176
192
 
177
193
  return truthPack;
@@ -179,7 +195,7 @@ async function getTruthPack(projectPath, scope) {
179
195
  return {
180
196
  error: error.message,
181
197
  projectPath,
182
- suggestion: "Run 'vibecheck init' to set up the project",
198
+ suggestion: "Run `vibecheck init` to set up the project",
183
199
  };
184
200
  }
185
201
  }
@@ -193,12 +209,12 @@ async function extractRoutes(projectPath) {
193
209
  ];
194
210
 
195
211
  const files = await findSourceFiles(projectPath, [".ts", ".js", ".tsx", ".jsx"]);
196
-
197
- for (const file of files.slice(0, 50)) { // Limit for performance
212
+
213
+ for (const file of files.slice(0, 50)) {
198
214
  try {
199
215
  const content = await fs.readFile(file, "utf8");
200
216
  const relPath = path.relative(projectPath, file);
201
-
217
+
202
218
  for (const pattern of routePatterns) {
203
219
  let match;
204
220
  pattern.lastIndex = 0;
@@ -223,7 +239,7 @@ async function extractRoutes(projectPath) {
223
239
 
224
240
  return {
225
241
  count: routes.length,
226
- routes: routes.slice(0, 100), // Limit output
242
+ routes: routes.slice(0, 100),
227
243
  confidence: routes.length > 0 ? 0.8 : 0.2,
228
244
  };
229
245
  }
@@ -238,12 +254,12 @@ async function extractAuth(projectPath) {
238
254
  ];
239
255
 
240
256
  const files = await findSourceFiles(projectPath, [".ts", ".js"]);
241
-
257
+
242
258
  for (const file of files.slice(0, 50)) {
243
259
  try {
244
260
  const content = await fs.readFile(file, "utf8");
245
261
  const relPath = path.relative(projectPath, file);
246
-
262
+
247
263
  for (const pattern of authPatterns) {
248
264
  let match;
249
265
  pattern.lastIndex = 0;
@@ -265,7 +281,12 @@ async function extractAuth(projectPath) {
265
281
  return {
266
282
  count: authIndicators.length,
267
283
  indicators: authIndicators.slice(0, 50),
268
- confidence: authIndicators.length > 5 ? 0.8 : authIndicators.length > 0 ? 0.5 : 0.1,
284
+ confidence:
285
+ authIndicators.length > 5
286
+ ? 0.8
287
+ : authIndicators.length > 0
288
+ ? 0.5
289
+ : 0.1,
269
290
  };
270
291
  }
271
292
 
@@ -279,12 +300,12 @@ async function extractBilling(projectPath) {
279
300
  ];
280
301
 
281
302
  const files = await findSourceFiles(projectPath, [".ts", ".js"]);
282
-
303
+
283
304
  for (const file of files.slice(0, 30)) {
284
305
  try {
285
306
  const content = await fs.readFile(file, "utf8");
286
307
  const relPath = path.relative(projectPath, file);
287
-
308
+
288
309
  for (const pattern of billingPatterns) {
289
310
  let match;
290
311
  pattern.lastIndex = 0;
@@ -306,7 +327,12 @@ async function extractBilling(projectPath) {
306
327
  return {
307
328
  count: billingIndicators.length,
308
329
  indicators: billingIndicators.slice(0, 30),
309
- confidence: billingIndicators.length > 3 ? 0.7 : billingIndicators.length > 0 ? 0.4 : 0.1,
330
+ confidence:
331
+ billingIndicators.length > 3
332
+ ? 0.7
333
+ : billingIndicators.length > 0
334
+ ? 0.4
335
+ : 0.1,
310
336
  };
311
337
  }
312
338
 
@@ -314,7 +340,6 @@ async function extractEnvVars(projectPath) {
314
340
  const declared = [];
315
341
  const used = [];
316
342
 
317
- // Check .env.example, .env.local.example, etc.
318
343
  const envFiles = [".env.example", ".env.local.example", ".env.sample"];
319
344
  for (const envFile of envFiles) {
320
345
  try {
@@ -331,11 +356,10 @@ async function extractEnvVars(projectPath) {
331
356
  }
332
357
  }
333
358
  } catch {
334
- // File doesn't exist
359
+ // File does not exist
335
360
  }
336
361
  }
337
362
 
338
- // Find process.env usage in code
339
363
  const files = await findSourceFiles(projectPath, [".ts", ".js"]);
340
364
  for (const file of files.slice(0, 30)) {
341
365
  try {
@@ -356,11 +380,10 @@ async function extractEnvVars(projectPath) {
356
380
  }
357
381
  }
358
382
 
359
- // Find mismatches
360
- const declaredNames = new Set(declared.map(d => d.name));
361
- const usedNames = new Set(used.map(u => u.name));
362
- const undeclared = [...usedNames].filter(n => !declaredNames.has(n));
363
- const unused = [...declaredNames].filter(n => !usedNames.has(n));
383
+ const declaredNames = new Set(declared.map((d) => d.name));
384
+ const usedNames = new Set(used.map((u) => u.name));
385
+ const undeclared = [...usedNames].filter((name) => !declaredNames.has(name));
386
+ const unused = [...declaredNames].filter((name) => !usedNames.has(name));
364
387
 
365
388
  return {
366
389
  declared: declared.slice(0, 50),
@@ -376,7 +399,6 @@ async function extractEnvVars(projectPath) {
376
399
  async function extractSchema(projectPath) {
377
400
  const schemas = [];
378
401
 
379
- // Check for Prisma schema
380
402
  try {
381
403
  const prismaPath = path.join(projectPath, "prisma", "schema.prisma");
382
404
  const content = await fs.readFile(prismaPath, "utf8");
@@ -389,16 +411,15 @@ async function extractSchema(projectPath) {
389
411
  });
390
412
  }
391
413
  } catch {
392
- // No Prisma
414
+ // No Prisma schema
393
415
  }
394
416
 
395
- // Check for TypeScript types/interfaces
396
417
  const files = await findSourceFiles(projectPath, [".ts", ".tsx"]);
397
418
  for (const file of files.slice(0, 20)) {
398
419
  try {
399
420
  const content = await fs.readFile(file, "utf8");
400
421
  const relPath = path.relative(projectPath, file);
401
-
422
+
402
423
  const typeMatches = content.matchAll(/(?:interface|type)\s+(\w+)/g);
403
424
  for (const match of typeMatches) {
404
425
  const line = content.substring(0, match.index).split("\n").length;
@@ -417,7 +438,8 @@ async function extractSchema(projectPath) {
417
438
  return {
418
439
  count: schemas.length,
419
440
  schemas: schemas.slice(0, 50),
420
- confidence: schemas.length > 5 ? 0.7 : schemas.length > 0 ? 0.4 : 0.2,
441
+ confidence:
442
+ schemas.length > 5 ? 0.7 : schemas.length > 0 ? 0.4 : 0.2,
421
443
  };
422
444
  }
423
445
 
@@ -436,7 +458,7 @@ async function verifyClaim(projectPath, claimType, claim) {
436
458
 
437
459
  try {
438
460
  switch (claimType) {
439
- case "file":
461
+ case "file": {
440
462
  const filePath = path.join(projectPath, claim);
441
463
  try {
442
464
  await fs.access(filePath);
@@ -453,11 +475,14 @@ async function verifyClaim(projectPath, claimType, claim) {
453
475
  result.rejection = `File does not exist: ${claim}`;
454
476
  }
455
477
  break;
478
+ }
456
479
 
457
480
  case "route":
458
- case "endpoint":
481
+ case "endpoint": {
459
482
  const routes = await extractRoutes(projectPath);
460
- const matchingRoute = routes.routes.find(r => r.path === claim || r.path.includes(claim));
483
+ const matchingRoute = routes.routes.find(
484
+ (route) => route.path === claim || route.path.includes(claim),
485
+ );
461
486
  if (matchingRoute) {
462
487
  result.verified = true;
463
488
  result.confidence = 0.9;
@@ -466,26 +491,31 @@ async function verifyClaim(projectPath, claimType, claim) {
466
491
  result.rejection = `No route matching "${claim}" found in codebase`;
467
492
  }
468
493
  break;
494
+ }
469
495
 
470
- case "env_var":
496
+ case "env_var": {
471
497
  const envData = await extractEnvVars(projectPath);
472
- const isDeclared = envData.declared.some(d => d.name === claim);
473
- const isUsed = envData.used.some(u => u.name === claim);
498
+ const isDeclared = envData.declared.some((env) => env.name === claim);
499
+ const isUsed = envData.used.some((env) => env.name === claim);
474
500
  if (isDeclared || isUsed) {
475
501
  result.verified = true;
476
502
  result.confidence = isDeclared && isUsed ? 1.0 : 0.7;
477
503
  result.evidence = {
478
504
  declared: isDeclared,
479
505
  used: isUsed,
480
- locations: [...envData.declared.filter(d => d.name === claim), ...envData.used.filter(u => u.name === claim)],
506
+ locations: [
507
+ ...envData.declared.filter((env) => env.name === claim),
508
+ ...envData.used.filter((env) => env.name === claim),
509
+ ],
481
510
  };
482
511
  } else {
483
512
  result.rejection = `Environment variable "${claim}" not found`;
484
513
  }
485
514
  break;
515
+ }
486
516
 
487
517
  default:
488
- result.rejection = `Claim type "${claimType}" verification not yet implemented`;
518
+ result.rejection = `Claim type "${claimType}" verification is not implemented yet`;
489
519
  }
490
520
  } catch (error) {
491
521
  result.rejection = `Verification error: ${error.message}`;
@@ -500,17 +530,19 @@ async function verifyClaim(projectPath, claimType, claim) {
500
530
 
501
531
  async function getEvidence(projectPath, file, options) {
502
532
  const filePath = path.join(projectPath, file);
503
-
533
+
504
534
  try {
505
535
  const content = await fs.readFile(filePath, "utf8");
506
536
  const lines = content.split("\n");
507
-
537
+
508
538
  let targetLine = options.line || 1;
509
539
  const contextLines = options.context_lines || 10;
510
-
511
- // If function_name provided, find it
540
+
512
541
  if (options.function_name) {
513
- const pattern = new RegExp(`(function|const|let|var|class)\\s+${options.function_name}`, "i");
542
+ const pattern = new RegExp(
543
+ `(function|const|let|var|class)\\s+${options.function_name}`,
544
+ "i",
545
+ );
514
546
  for (let i = 0; i < lines.length; i++) {
515
547
  if (pattern.test(lines[i])) {
516
548
  targetLine = i + 1;
@@ -518,14 +550,18 @@ async function getEvidence(projectPath, file, options) {
518
550
  }
519
551
  }
520
552
  }
521
-
553
+
522
554
  const startLine = Math.max(1, targetLine - contextLines);
523
555
  const endLine = Math.min(lines.length, targetLine + contextLines);
524
-
525
- const snippet = lines.slice(startLine - 1, endLine)
526
- .map((line, i) => `${String(startLine + i).padStart(4, " ")} | ${line}`)
556
+
557
+ const snippet = lines
558
+ .slice(startLine - 1, endLine)
559
+ .map(
560
+ (line, index) =>
561
+ `${String(startLine + index).padStart(4, " ")} | ${line}`,
562
+ )
527
563
  .join("\n");
528
-
564
+
529
565
  return {
530
566
  file,
531
567
  targetLine,
@@ -549,14 +585,19 @@ async function getEvidence(projectPath, file, options) {
549
585
 
550
586
  async function findSourceFiles(projectPath, extensions) {
551
587
  const files = [];
552
-
588
+
553
589
  async function walk(dir) {
554
590
  try {
555
591
  const entries = await fs.readdir(dir, { withFileTypes: true });
556
592
  for (const entry of entries) {
557
593
  const fullPath = path.join(dir, entry.name);
558
594
  if (entry.isDirectory()) {
559
- if (!entry.name.startsWith(".") && entry.name !== "node_modules" && entry.name !== "dist" && entry.name !== "build") {
595
+ if (
596
+ !entry.name.startsWith(".") &&
597
+ entry.name !== "node_modules" &&
598
+ entry.name !== "dist" &&
599
+ entry.name !== "build"
600
+ ) {
560
601
  await walk(fullPath);
561
602
  }
562
603
  } else if (entry.isFile()) {
@@ -570,7 +611,7 @@ async function findSourceFiles(projectPath, extensions) {
570
611
  // Skip inaccessible directories
571
612
  }
572
613
  }
573
-
614
+
574
615
  await walk(projectPath);
575
616
  return files;
576
617
  }