@vibecheck-ai/mcp 24.6.9 → 24.6.12

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 (41) hide show
  1. package/README.md +1 -1
  2. package/dist/APITruthEngine-IZRR3NT5-LPFUOMLD.js +9 -0
  3. package/dist/CredentialsEngine-B66ANCBB-HY5ZQTSX.js +9 -0
  4. package/dist/EnvVarEngine-ZFNW2XKP-6HRTZULP.js +9 -0
  5. package/dist/ErrorHandlingEngine-FG65SFRB-4NEANCMF.js +11 -0
  6. package/dist/FrameworkPackEngine-RRBJW4MC-KH7WRXXS.js +12 -0
  7. package/dist/GhostRouteEngine-UMYBCOCL-MSZOPVZY.js +9 -0
  8. package/dist/LogicGapEngine-OK5UKZQ5-YGXZDERB.js +11 -0
  9. package/dist/PhantomDepEngine-5O7Z7MDE-4A37GGL4.js +10 -0
  10. package/dist/SecurityEngine-MVMRPKLH-BNP7IC46.js +9 -0
  11. package/dist/VersionHallucinationEngine-673DJ26J-BD4SK6JX.js +9 -0
  12. package/dist/chokidar-CI5VJY5M.js +2414 -0
  13. package/dist/chunk-43XAAYST.js +863 -0
  14. package/dist/chunk-5DADZJ3D.js +650 -0
  15. package/dist/chunk-DDTUTWRY.js +605 -0
  16. package/dist/chunk-DGNNNAVK.js +304 -0
  17. package/dist/chunk-F34MHA6A.js +772 -0
  18. package/dist/chunk-FGMVY5QW.js +42 -0
  19. package/dist/chunk-FMRX5OVJ.js +1968 -0
  20. package/dist/chunk-FRK2XZX5.js +213309 -0
  21. package/dist/chunk-J52EUKKW.js +196 -0
  22. package/dist/chunk-JZSHXEYP.js +915 -0
  23. package/dist/chunk-LQSBUKYZ.js +551 -0
  24. package/dist/chunk-MUP4JXOF.js +219 -0
  25. package/dist/chunk-NR36RTVO.js +152 -0
  26. package/dist/chunk-QGPX6H6L.js +3044 -0
  27. package/dist/chunk-QYXENOVK.js +499 -0
  28. package/dist/chunk-RR5ETBSV.js +66 -0
  29. package/dist/chunk-WUHPSW7M.js +11130 -0
  30. package/dist/chunk-YWUMPN4Z.js +53 -0
  31. package/dist/dist-HFMJ3GIR.js +1091 -0
  32. package/dist/dist-JUOVMQEA.js +9 -0
  33. package/dist/dist-NXITTS32-O3XLWR6T.js +386 -0
  34. package/dist/dist-Y2Z46SBD.js +22 -0
  35. package/dist/fingerprint-NOJ7TDB6-K6SB7LCZ.js +9 -0
  36. package/dist/index.js +5462 -4676
  37. package/dist/semantic-WW6XVII4.js +8544 -0
  38. package/dist/transformers.node-K4WKH4PR.js +45809 -0
  39. package/dist/tree-sitter-AGICL65I.js +1412 -0
  40. package/dist/tree-sitter-H5E7LKR4-MKO3NNLJ.js +9 -0
  41. package/package.json +7 -6
@@ -0,0 +1,650 @@
1
+ import { createRequire } from 'module';
2
+ import { fileURLToPath } from 'url';
3
+ import * as path from 'path';
4
+ import { dirname } from 'path';
5
+
6
+ createRequire(import.meta.url);
7
+ const __filename$1 = fileURLToPath(import.meta.url);
8
+ dirname(__filename$1);
9
+ function deterministicId(uri, line, ruleId, patternName) {
10
+ const input = `cred:${uri}::${line}::${ruleId}::${patternName}`;
11
+ let hash = 2166136261;
12
+ for (let i = 0; i < input.length; i++) {
13
+ hash ^= input.charCodeAt(i);
14
+ hash = hash * 16777619 >>> 0;
15
+ }
16
+ return `cred-${hash.toString(16).padStart(8, "0")}`;
17
+ }
18
+ function inferCredentialLang(delta) {
19
+ const lid = delta.documentLanguage.toLowerCase();
20
+ if (lid.includes("python")) return "python";
21
+ if (lid.includes("go") || lid === "gomod") return "go";
22
+ const uriPath = delta.documentUri.replace(/^file:\/\//, "");
23
+ const ext = path.extname(uriPath).toLowerCase();
24
+ if (ext === ".py" || ext === ".pyi") return "python";
25
+ if (ext === ".go") return "go";
26
+ if (ext === ".ts" || ext === ".tsx" || ext === ".js" || ext === ".jsx" || ext === ".mjs" || ext === ".cjs" || ext === ".mts" || ext === ".cts") {
27
+ return "javascript";
28
+ }
29
+ return "other";
30
+ }
31
+ function isTestFile(uri) {
32
+ const u = uri.replace(/^file:\/\//, "");
33
+ if (/(?:^|[\\/])test_[\w.-]+\.py$/i.test(u) || /(?:^|[\\/])[\w.-]+_test\.py$/i.test(u) || /(?:^|[\\/])conftest\.py$/i.test(u))
34
+ return true;
35
+ if (/[^\\/]+_test\.go$/i.test(u)) return true;
36
+ return /\.(test|spec)\.(ts|tsx|js|jsx)$/i.test(u) || /(?:^|[\\/])(?:__tests__|__mocks__|tests?|fixtures?|e2e|spec|cypress|playwright|__snapshots__|__fixtures__|stubs?|mocks?|test[-_]?data|test[-_]?helpers?|test[-_]?utils?)[\\/]/i.test(u) || /\.(?:mock|fixture|stub)\.[^\\/]*$/i.test(u);
37
+ }
38
+ function isExampleFile(uri) {
39
+ return /\.(?:example|sample|template)\b/.test(uri) || /\.env\.(?:example|sample)\b/.test(uri);
40
+ }
41
+ var FAKE_VALUE_PATTERNS = /(?:test|example|sample|dummy|fake|placeholder|xxx+|your[-_]|changeme|todo|mock|fixture|replace[-_]?me|insert[-_]?here|fill[-_]?in|update[-_]?me|secret|password|change[-_]?this|put[-_]?here|add[-_]?your|enter[-_]?your|sk[-_]test|pk[-_]test|demo|default|replace|temp|tmp|foobar|foo|bar|baz|qux|lorem|ipsum|abc|1234|0000)/i;
42
+ function hasLowEntropy(value) {
43
+ const unique = new Set(value.toLowerCase()).size;
44
+ return unique <= 4 && value.length >= 8;
45
+ }
46
+ function isFakeCredentialValue(value) {
47
+ if (value.length < 8) return true;
48
+ if (FAKE_VALUE_PATTERNS.test(value)) return true;
49
+ if (hasLowEntropy(value)) return true;
50
+ if (value.length < 16 && /^[a-z_-]+$/.test(value)) return true;
51
+ return false;
52
+ }
53
+ function isCriticalPath(uri) {
54
+ const u = uri.replace(/^file:\/\//, "");
55
+ return /[\\/]api[\\/]|[\\/]auth[\\/]|[\\/]payment|[\\/]billing|[\\/]admin|[\\/]checkout|[\\/]webhook|[\\/]security/.test(u) || /middleware\.(ts|js|go|py)$/.test(u) || /[\\/]lib[\\/]auth|[\\/]lib[\\/]db|[\\/]lib[\\/]stripe/.test(u) || /(?:^|[\\/])(?:settings|urls)\.py$/i.test(u) || /[\\/](?:internal[\\/]auth|internal[\\/]api|handlers)(?:[\\/]|$)/i.test(u);
56
+ }
57
+ function localizeCredentialSuggestion(suggestion, lang) {
58
+ if (lang === "javascript" || lang === "other") return suggestion;
59
+ if (lang === "python") {
60
+ return suggestion.replace(/\bprocess\.env\.([A-Z_][A-Z0-9_]*)\b/g, 'os.environ["$1"]').replace(/\bimport\.meta\.env\.([A-Z_][A-Z0-9_]*)\b/g, 'os.environ["$1"]');
61
+ }
62
+ if (lang === "go") {
63
+ return suggestion.replace(/\bprocess\.env\.([A-Z_][A-Z0-9_]*)\b/g, 'os.Getenv("$1")').replace(/\bimport\.meta\.env\.([A-Z_][A-Z0-9_]*)\b/g, 'os.Getenv("$1")');
64
+ }
65
+ return suggestion;
66
+ }
67
+ function escalate(severity, critical) {
68
+ if (!critical) return severity;
69
+ const up = {
70
+ low: "medium",
71
+ medium: "high",
72
+ high: "critical",
73
+ critical: "critical"
74
+ };
75
+ return up[severity] ?? severity;
76
+ }
77
+ function maskEvidence(evidence) {
78
+ return evidence.replace(/(sk_(?:live|test)_)[a-zA-Z0-9]{4,}/g, "$1****").replace(/(pk_(?:live|test)_)[a-zA-Z0-9]{4,}/g, "$1****").replace(/(AKIA)[0-9A-Z]{12,}/g, "$1****").replace(/(sk-(?:ant-)?)[a-zA-Z0-9-]{8,}/g, "$1****").replace(/(gh[po]_)[a-zA-Z0-9]{4,}/g, "$1****").replace(/(xox[bpoas]-)[0-9a-zA-Z-]{4,}/g, "$1****").replace(/(SG\.)[a-zA-Z0-9_-]{4,}/g, "$1****").replace(/(npm_)[a-zA-Z0-9]{4,}/g, "$1****").replace(/(hf_)[a-zA-Z0-9]{4,}/g, "$1****").replace(/(AIza)[0-9A-Za-z_-]{4,}/g, "$1****").replace(/(pscale_(?:tkn|pw)_)[a-zA-Z0-9_]{4,}/g, "$1****").replace(/(dapi)[a-f0-9]{4,}/g, "$1****").replace(/(key-)[a-f0-9]{4,}/g, "$1****").replace(/(phc_)[a-zA-Z0-9]{4,}/g, "$1****").replace(/(lin_api_)[a-zA-Z0-9]{4,}/g, "$1****").replace(/(re_)[a-zA-Z0-9]{4,}/g, "$1****").replace(/([MN][A-Za-z\d]{23,})\.[^'"` ]{6,}/g, "$1.****").replace(/:\/\/([^:]+):([^@]{4,})@/g, "://$1:****@").replace(/['"`]([a-zA-Z0-9+/=_-]{32,})['"`]/g, (m, val) => m.replace(val, val.slice(0, 4) + "****"));
79
+ }
80
+ var PATTERNS = [
81
+ // ── Stripe ──
82
+ {
83
+ name: "stripe-live-secret",
84
+ ruleId: "CRED001",
85
+ regex: /(?:['"`](sk_live_[a-zA-Z0-9]{20,})['"`]|(?:^|[\s=])(sk_live_[a-zA-Z0-9]{20,})(?:\s|$))/m,
86
+ severity: "critical",
87
+ message: "Stripe live secret key hardcoded",
88
+ suggestion: "Move to process.env.STRIPE_SECRET_KEY and add to .env (gitignored).",
89
+ confidence: 99,
90
+ flagInTests: true,
91
+ skipInExamples: false
92
+ },
93
+ {
94
+ name: "stripe-live-publishable",
95
+ ruleId: "CRED001",
96
+ regex: /['"`](pk_live_[a-zA-Z0-9]{20,})['"`]/,
97
+ severity: "high",
98
+ message: "Stripe live publishable key hardcoded",
99
+ suggestion: "Use process.env.NEXT_PUBLIC_STRIPE_KEY",
100
+ confidence: 95,
101
+ flagInTests: false,
102
+ skipInExamples: true
103
+ },
104
+ {
105
+ name: "stripe-test-secret",
106
+ ruleId: "CRED001",
107
+ regex: /['"`](sk_test_[a-zA-Z0-9]{20,})['"`]/,
108
+ severity: "high",
109
+ message: "Stripe test secret key hardcoded \u2014 use env var even for test keys",
110
+ suggestion: "Use process.env.STRIPE_TEST_KEY",
111
+ confidence: 90,
112
+ flagInTests: false,
113
+ skipInExamples: true
114
+ },
115
+ // ── AWS ──
116
+ {
117
+ name: "aws-access-key",
118
+ ruleId: "CRED001",
119
+ regex: /['"`](AKIA[0-9A-Z]{16})['"`]/,
120
+ severity: "critical",
121
+ message: "AWS Access Key ID hardcoded",
122
+ suggestion: "Use AWS SDK credential chain or AWS_ACCESS_KEY_ID env var.",
123
+ confidence: 99,
124
+ flagInTests: true,
125
+ skipInExamples: false
126
+ },
127
+ {
128
+ name: "aws-secret-key",
129
+ ruleId: "CRED001",
130
+ regex: /aws_secret_access_key\s*[:=]\s*['"`]([^'"`]{20,})['"`]/i,
131
+ severity: "critical",
132
+ message: "AWS Secret Access Key hardcoded",
133
+ suggestion: "Use AWS_SECRET_ACCESS_KEY environment variable.",
134
+ confidence: 98,
135
+ flagInTests: true,
136
+ skipInExamples: false
137
+ },
138
+ // ── AI providers ──
139
+ {
140
+ name: "openai-key",
141
+ ruleId: "CRED001",
142
+ regex: /['"`](sk-[a-zA-Z0-9]{32,})['"`]/,
143
+ severity: "critical",
144
+ message: "OpenAI API key hardcoded",
145
+ suggestion: "Use process.env.OPENAI_API_KEY",
146
+ confidence: 92,
147
+ flagInTests: true,
148
+ skipInExamples: false
149
+ },
150
+ {
151
+ name: "anthropic-key",
152
+ ruleId: "CRED001",
153
+ regex: /['"`](sk-ant-[a-zA-Z0-9-]{20,})['"`]/,
154
+ severity: "critical",
155
+ message: "Anthropic API key hardcoded",
156
+ suggestion: "Use process.env.ANTHROPIC_API_KEY",
157
+ confidence: 98,
158
+ flagInTests: true,
159
+ skipInExamples: false
160
+ },
161
+ // ── GitHub ──
162
+ {
163
+ name: "github-pat",
164
+ ruleId: "CRED001",
165
+ regex: /['"`](ghp_[a-zA-Z0-9]{36,})['"`]/,
166
+ severity: "critical",
167
+ message: "GitHub personal access token hardcoded",
168
+ suggestion: "Use process.env.GITHUB_TOKEN",
169
+ confidence: 99,
170
+ flagInTests: true,
171
+ skipInExamples: false
172
+ },
173
+ {
174
+ name: "github-oauth",
175
+ ruleId: "CRED001",
176
+ regex: /['"`](gho_[a-zA-Z0-9]{36,})['"`]/,
177
+ severity: "critical",
178
+ message: "GitHub OAuth token hardcoded",
179
+ suggestion: "Use process.env.GITHUB_OAUTH_TOKEN",
180
+ confidence: 99,
181
+ flagInTests: true,
182
+ skipInExamples: false
183
+ },
184
+ // ── Google ──
185
+ {
186
+ name: "google-api-key",
187
+ ruleId: "CRED001",
188
+ regex: /['"`](AIza[0-9A-Za-z_-]{35,})['"`]/,
189
+ severity: "high",
190
+ message: "Google API key hardcoded",
191
+ suggestion: "Use process.env.GOOGLE_API_KEY",
192
+ confidence: 95,
193
+ flagInTests: false,
194
+ skipInExamples: false
195
+ },
196
+ // ── Generic secrets ──
197
+ {
198
+ name: "jwt-secret",
199
+ ruleId: "CRED003",
200
+ regex: /(?:jwt[_-]?secret|JWT_SECRET)\s*[:=]\s*['"`]([^'"`]{8,})['"`]/i,
201
+ severity: "critical",
202
+ message: "JWT signing secret hardcoded \u2014 anyone with this can forge auth tokens",
203
+ suggestion: "Store in JWT_SECRET environment variable and rotate regularly.",
204
+ confidence: 90,
205
+ flagInTests: false,
206
+ skipInExamples: true
207
+ },
208
+ {
209
+ name: "generic-password",
210
+ ruleId: "CRED002",
211
+ regex: /(?:password|passwd|pwd)\s*[:=]\s*['"`]([^'"`]{4,})['"`]/i,
212
+ severity: "high",
213
+ message: "Hardcoded password detected",
214
+ suggestion: "Use an environment variable or secrets manager (Vault, AWS Secrets Manager).",
215
+ confidence: 75,
216
+ flagInTests: false,
217
+ skipInExamples: true
218
+ },
219
+ {
220
+ name: "generic-secret",
221
+ ruleId: "CRED002",
222
+ regex: /(?:secret|api[_-]?key|auth[_-]?token)\s*[:=]\s*['"`]([^'"`]{8,})['"`]/i,
223
+ severity: "high",
224
+ message: "Hardcoded secret / token detected",
225
+ suggestion: "Use an environment variable.",
226
+ confidence: 70,
227
+ flagInTests: false,
228
+ skipInExamples: true
229
+ },
230
+ {
231
+ name: "private-key-pem",
232
+ ruleId: "CRED004",
233
+ regex: /-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/,
234
+ severity: "critical",
235
+ message: "Private key embedded in source code",
236
+ suggestion: "Store key in a file and reference its path via env var.",
237
+ confidence: 99,
238
+ flagInTests: true,
239
+ skipInExamples: false
240
+ },
241
+ {
242
+ name: "connection-string",
243
+ ruleId: "CRED005",
244
+ regex: /['"`](?:mongodb(?:\+srv)?|postgres(?:ql)?|mysql|redis|amqp):\/\/[^'"`\s]{10,}['"`]/i,
245
+ severity: "critical",
246
+ message: "Database connection string with credentials in source",
247
+ suggestion: "Use DATABASE_URL environment variable.",
248
+ confidence: 92,
249
+ flagInTests: false,
250
+ skipInExamples: true
251
+ },
252
+ // ── SaaS tokens ──
253
+ {
254
+ name: "slack-token",
255
+ ruleId: "CRED001",
256
+ regex: /['"`](xox[bpoas]-[0-9a-zA-Z-]{10,})['"`]/,
257
+ severity: "critical",
258
+ message: "Slack token hardcoded",
259
+ suggestion: "Use process.env.SLACK_TOKEN",
260
+ confidence: 97,
261
+ flagInTests: true,
262
+ skipInExamples: false
263
+ },
264
+ {
265
+ name: "sendgrid-key",
266
+ ruleId: "CRED001",
267
+ regex: /['"`](SG\.[a-zA-Z0-9_-]{22,}\.[a-zA-Z0-9_-]{43,})['"`]/,
268
+ severity: "critical",
269
+ message: "SendGrid API key hardcoded",
270
+ suggestion: "Use process.env.SENDGRID_API_KEY",
271
+ confidence: 99,
272
+ flagInTests: true,
273
+ skipInExamples: false
274
+ },
275
+ {
276
+ name: "twilio-key",
277
+ ruleId: "CRED001",
278
+ regex: /['"`](SK[a-f0-9]{32})['"`]/,
279
+ severity: "high",
280
+ message: "Twilio API key hardcoded",
281
+ suggestion: "Use process.env.TWILIO_API_KEY",
282
+ confidence: 85,
283
+ flagInTests: false,
284
+ skipInExamples: true
285
+ },
286
+ {
287
+ name: "npm-token",
288
+ ruleId: "CRED001",
289
+ regex: /['"`](npm_[a-zA-Z0-9]{36,})['"`]/,
290
+ severity: "critical",
291
+ message: "npm auth token hardcoded",
292
+ suggestion: "Use .npmrc with env var interpolation: //registry.npmjs.org/:_authToken=${NPM_TOKEN}",
293
+ confidence: 98,
294
+ flagInTests: true,
295
+ skipInExamples: false
296
+ },
297
+ {
298
+ name: "huggingface-token",
299
+ ruleId: "CRED001",
300
+ regex: /['"`](hf_[a-zA-Z0-9]{30,})['"`]/,
301
+ severity: "critical",
302
+ message: "HuggingFace API token hardcoded",
303
+ suggestion: "Use process.env.HUGGINGFACE_TOKEN",
304
+ confidence: 97,
305
+ flagInTests: true,
306
+ skipInExamples: false
307
+ },
308
+ // ── Additional SaaS tokens ──
309
+ {
310
+ name: "supabase-service-key",
311
+ ruleId: "CRED001",
312
+ regex: /['"`](eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9\.[a-zA-Z0-9_-]{50,}\.[a-zA-Z0-9_-]{20,})['"`]/,
313
+ severity: "critical",
314
+ message: "Supabase service role key hardcoded \u2014 grants admin access to your database",
315
+ suggestion: "Use process.env.SUPABASE_SERVICE_ROLE_KEY. Never expose service role keys client-side.",
316
+ confidence: 88,
317
+ flagInTests: true,
318
+ skipInExamples: false
319
+ },
320
+ {
321
+ name: "clerk-secret-key",
322
+ ruleId: "CRED001",
323
+ regex: /['"`](sk_(?:live|test)_[a-zA-Z0-9]{20,})['"`]/,
324
+ severity: "critical",
325
+ message: "Clerk secret key hardcoded",
326
+ suggestion: "Use process.env.CLERK_SECRET_KEY",
327
+ confidence: 90,
328
+ flagInTests: true,
329
+ skipInExamples: false
330
+ },
331
+ {
332
+ name: "vercel-token",
333
+ ruleId: "CRED001",
334
+ regex: /['"`]([a-zA-Z0-9]{24})['"`](?=.*(?:vercel|VERCEL))/i,
335
+ severity: "high",
336
+ message: "Vercel API token hardcoded",
337
+ suggestion: "Use process.env.VERCEL_TOKEN",
338
+ confidence: 80,
339
+ flagInTests: false,
340
+ skipInExamples: true
341
+ },
342
+ {
343
+ name: "discord-bot-token",
344
+ ruleId: "CRED001",
345
+ regex: /['"`]([MN][A-Za-z\d]{23,}\.[\w-]{6}\.[\w-]{27,})['"`]/,
346
+ severity: "critical",
347
+ message: "Discord bot token hardcoded",
348
+ suggestion: "Use process.env.DISCORD_BOT_TOKEN",
349
+ confidence: 95,
350
+ flagInTests: true,
351
+ skipInExamples: false
352
+ },
353
+ {
354
+ name: "linear-api-key",
355
+ ruleId: "CRED001",
356
+ regex: /['"`](lin_api_[a-zA-Z0-9]{30,})['"`]/,
357
+ severity: "critical",
358
+ message: "Linear API key hardcoded",
359
+ suggestion: "Use process.env.LINEAR_API_KEY",
360
+ confidence: 98,
361
+ flagInTests: true,
362
+ skipInExamples: false
363
+ },
364
+ {
365
+ name: "resend-api-key",
366
+ ruleId: "CRED001",
367
+ regex: /['"`](re_[a-zA-Z0-9]{20,})['"`]/,
368
+ severity: "critical",
369
+ message: "Resend API key hardcoded",
370
+ suggestion: "Use process.env.RESEND_API_KEY",
371
+ confidence: 90,
372
+ flagInTests: true,
373
+ skipInExamples: false
374
+ },
375
+ // ── Cloud Providers ──
376
+ {
377
+ name: "gcp-service-account-key",
378
+ ruleId: "CRED001",
379
+ regex: /['"`](\{[^'"`]*"type"\s*:\s*"service_account"[^'"`]*\})['"`]/,
380
+ severity: "critical",
381
+ message: "GCP service account key JSON hardcoded \u2014 grants full cloud access",
382
+ suggestion: "Use GOOGLE_APPLICATION_CREDENTIALS env var pointing to a key file outside the repo.",
383
+ confidence: 98,
384
+ flagInTests: true,
385
+ skipInExamples: false
386
+ },
387
+ {
388
+ name: "gcp-api-key",
389
+ ruleId: "CRED001",
390
+ regex: /['"`](AIza[0-9A-Za-z_-]{35})['"`]/,
391
+ severity: "high",
392
+ message: "Google Cloud / Firebase API key hardcoded",
393
+ suggestion: "Use process.env.GOOGLE_API_KEY or restrict the key in GCP console.",
394
+ confidence: 95,
395
+ flagInTests: false,
396
+ skipInExamples: true
397
+ },
398
+ {
399
+ name: "azure-storage-key",
400
+ ruleId: "CRED001",
401
+ regex: /(?:AccountKey|azure_storage_key|AZURE_STORAGE_KEY)\s*[:=]\s*['"`]([A-Za-z0-9+/=]{44,})['"`]/i,
402
+ severity: "critical",
403
+ message: "Azure Storage account key hardcoded",
404
+ suggestion: "Use process.env.AZURE_STORAGE_KEY or Managed Identity for authentication.",
405
+ confidence: 90,
406
+ flagInTests: true,
407
+ skipInExamples: false
408
+ },
409
+ {
410
+ name: "azure-connection-string",
411
+ ruleId: "CRED005",
412
+ regex: /['"`]DefaultEndpointsProtocol=https?;AccountName=[^;]+;AccountKey=[^'"`]{20,}['"`]/,
413
+ severity: "critical",
414
+ message: "Azure connection string with credentials hardcoded",
415
+ suggestion: "Use process.env.AZURE_STORAGE_CONNECTION_STRING",
416
+ confidence: 98,
417
+ flagInTests: true,
418
+ skipInExamples: false
419
+ },
420
+ {
421
+ name: "cloudflare-api-token",
422
+ ruleId: "CRED001",
423
+ regex: /['"`]([A-Za-z0-9_-]{40})['"`](?=.*(?:cloudflare|CLOUDFLARE|CF_))/i,
424
+ severity: "critical",
425
+ message: "Cloudflare API token hardcoded",
426
+ suggestion: "Use process.env.CLOUDFLARE_API_TOKEN",
427
+ confidence: 82,
428
+ flagInTests: true,
429
+ skipInExamples: false
430
+ },
431
+ {
432
+ name: "planetscale-token",
433
+ ruleId: "CRED001",
434
+ regex: /['"`](pscale_tkn_[a-zA-Z0-9_]{20,})['"`]/,
435
+ severity: "critical",
436
+ message: "PlanetScale API token hardcoded",
437
+ suggestion: "Use process.env.PLANETSCALE_TOKEN",
438
+ confidence: 98,
439
+ flagInTests: true,
440
+ skipInExamples: false
441
+ },
442
+ {
443
+ name: "planetscale-password",
444
+ ruleId: "CRED001",
445
+ regex: /['"`](pscale_pw_[a-zA-Z0-9_]{20,})['"`]/,
446
+ severity: "critical",
447
+ message: "PlanetScale database password hardcoded",
448
+ suggestion: "Use process.env.DATABASE_PASSWORD or PlanetScale connection string from env.",
449
+ confidence: 98,
450
+ flagInTests: true,
451
+ skipInExamples: false
452
+ },
453
+ {
454
+ name: "neon-connection-string",
455
+ ruleId: "CRED005",
456
+ regex: /['"`]postgres(?:ql)?:\/\/[^'"`]*\.neon\.tech[^'"`]*['"`]/i,
457
+ severity: "critical",
458
+ message: "Neon database connection string hardcoded",
459
+ suggestion: "Use process.env.DATABASE_URL",
460
+ confidence: 95,
461
+ flagInTests: false,
462
+ skipInExamples: true
463
+ },
464
+ {
465
+ name: "turso-auth-token",
466
+ ruleId: "CRED001",
467
+ regex: /(?:TURSO_AUTH_TOKEN|authToken)\s*[:=]\s*['"`](eyJ[a-zA-Z0-9_-]{20,}\.[a-zA-Z0-9_-]{20,})['"`]/i,
468
+ severity: "critical",
469
+ message: "Turso database auth token hardcoded",
470
+ suggestion: "Use process.env.TURSO_AUTH_TOKEN",
471
+ confidence: 92,
472
+ flagInTests: true,
473
+ skipInExamples: false
474
+ },
475
+ {
476
+ name: "upstash-redis-token",
477
+ ruleId: "CRED001",
478
+ regex: /(?:UPSTASH_REDIS_REST_TOKEN|upstash.*token)\s*[:=]\s*['"`]([A-Za-z0-9]{20,})['"`]/i,
479
+ severity: "critical",
480
+ message: "Upstash Redis REST token hardcoded",
481
+ suggestion: "Use process.env.UPSTASH_REDIS_REST_TOKEN",
482
+ confidence: 88,
483
+ flagInTests: true,
484
+ skipInExamples: false
485
+ },
486
+ {
487
+ name: "databricks-token",
488
+ ruleId: "CRED001",
489
+ regex: /['"`](dapi[a-f0-9]{32})['"`]/,
490
+ severity: "critical",
491
+ message: "Databricks API token hardcoded",
492
+ suggestion: "Use process.env.DATABRICKS_TOKEN",
493
+ confidence: 96,
494
+ flagInTests: true,
495
+ skipInExamples: false
496
+ },
497
+ {
498
+ name: "telegram-bot-token",
499
+ ruleId: "CRED001",
500
+ regex: /['"`](\d{8,10}:[A-Za-z0-9_-]{35})['"`]/,
501
+ severity: "critical",
502
+ message: "Telegram bot token hardcoded",
503
+ suggestion: "Use process.env.TELEGRAM_BOT_TOKEN",
504
+ confidence: 92,
505
+ flagInTests: true,
506
+ skipInExamples: false
507
+ },
508
+ {
509
+ name: "postmark-server-token",
510
+ ruleId: "CRED001",
511
+ regex: /['"`]([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})['"`](?=.*(?:postmark|POSTMARK))/i,
512
+ severity: "critical",
513
+ message: "Postmark server token hardcoded",
514
+ suggestion: "Use process.env.POSTMARK_SERVER_TOKEN",
515
+ confidence: 85,
516
+ flagInTests: true,
517
+ skipInExamples: false
518
+ },
519
+ {
520
+ name: "mailgun-api-key",
521
+ ruleId: "CRED001",
522
+ regex: /['"`](key-[a-f0-9]{32})['"`]/,
523
+ severity: "critical",
524
+ message: "Mailgun API key hardcoded",
525
+ suggestion: "Use process.env.MAILGUN_API_KEY",
526
+ confidence: 95,
527
+ flagInTests: true,
528
+ skipInExamples: false
529
+ },
530
+ {
531
+ name: "algolia-admin-key",
532
+ ruleId: "CRED001",
533
+ regex: /['"`]([a-f0-9]{32})['"`](?=.*(?:algolia|ALGOLIA).*(?:admin|ADMIN))/i,
534
+ severity: "critical",
535
+ message: "Algolia admin API key hardcoded",
536
+ suggestion: "Use process.env.ALGOLIA_ADMIN_API_KEY. Use search-only keys client-side.",
537
+ confidence: 82,
538
+ flagInTests: true,
539
+ skipInExamples: false
540
+ },
541
+ {
542
+ name: "sentry-dsn",
543
+ ruleId: "CRED001",
544
+ regex: /['"`](https:\/\/[a-f0-9]{32}@[a-z0-9]+\.ingest\.sentry\.io\/\d+)['"`]/,
545
+ severity: "medium",
546
+ message: "Sentry DSN hardcoded \u2014 consider using env var for environment-specific DSNs",
547
+ suggestion: "Use process.env.SENTRY_DSN (or NEXT_PUBLIC_SENTRY_DSN for client-side).",
548
+ confidence: 85,
549
+ flagInTests: false,
550
+ skipInExamples: true
551
+ },
552
+ {
553
+ name: "posthog-api-key",
554
+ ruleId: "CRED001",
555
+ regex: /['"`](phc_[a-zA-Z0-9]{20,})['"`]/,
556
+ severity: "medium",
557
+ message: "PostHog API key hardcoded \u2014 use env var for environment isolation",
558
+ suggestion: "Use process.env.NEXT_PUBLIC_POSTHOG_KEY",
559
+ confidence: 90,
560
+ flagInTests: false,
561
+ skipInExamples: true
562
+ },
563
+ // ── URL-embedded credentials ──
564
+ {
565
+ name: "url-embedded-credentials",
566
+ ruleId: "CRED006",
567
+ regex: /['"`]https?:\/\/[^'"`\s]*:[^'"`\s@]*@[^'"`\s]+['"`]/,
568
+ severity: "high",
569
+ message: "URL contains embedded credentials (user:password@host)",
570
+ suggestion: "Move credentials to environment variables. Use URL without auth: https://host/path",
571
+ confidence: 85,
572
+ flagInTests: false,
573
+ skipInExamples: true
574
+ }
575
+ ];
576
+ var CredentialsEngine = class {
577
+ id = "credentials";
578
+ async scan(delta, signal) {
579
+ if (signal?.aborted) return [];
580
+ const uri = delta.documentUri;
581
+ const source = delta.fullText;
582
+ if (!source.includes("'") && !source.includes('"') && !source.includes("`") && !source.includes("-----BEGIN ") && !/(?:sk_live_|sk_test_|pk_live_|AKIA|ghp_|gho_|xox[bpoas]-|sk-ant-|npm_|hf_)/i.test(source)) return [];
583
+ const credLang = inferCredentialLang(delta);
584
+ const isTest = isTestFile(uri);
585
+ const isExample = isExampleFile(uri);
586
+ const critical = isCriticalPath(uri);
587
+ const findings = [];
588
+ const lines = delta.lines ?? source.split("\n");
589
+ for (let i = 0; i < lines.length; i++) {
590
+ if (signal?.aborted) break;
591
+ const line = lines[i];
592
+ const trimmed = line.trim();
593
+ if (trimmed.startsWith("//") || trimmed.startsWith("*") || trimmed.startsWith("#") || credLang === "python" && (trimmed.startsWith('"""') || trimmed.startsWith("'''"))) {
594
+ continue;
595
+ }
596
+ for (const pattern of PATTERNS) {
597
+ if (isTest && !pattern.flagInTests) continue;
598
+ if (isExample && pattern.skipInExamples) continue;
599
+ const match = pattern.regex.exec(line);
600
+ if (!match) continue;
601
+ if (/^\s*\w+\s*[?]?\s*:\s*(?:string|number|boolean|any|unknown|Record|Partial|Required)/.test(line)) continue;
602
+ if (/\(\s*\w+\s*:\s*(?:string|any)/.test(line)) continue;
603
+ if (pattern.ruleId !== "CRED001" && pattern.ruleId !== "CRED004") {
604
+ if (/process\.env\.|import\.meta\.env\.|config\.|getenv|dotenv/.test(line)) continue;
605
+ }
606
+ if (pattern.ruleId === "CRED002" || pattern.ruleId === "CRED003") {
607
+ const val = match[1] ?? "";
608
+ if (!val) continue;
609
+ if (isFakeCredentialValue(val)) continue;
610
+ if (/(?:type\s|interface\s|Schema|schema|zod\.|z\.|yup\.|joi\.|@param|@type|PropTypes)/.test(line)) continue;
611
+ if (/(?:expect|assert|should|toBe|toEqual|toMatch|describe|it\s*\()/.test(line)) continue;
612
+ }
613
+ if (pattern.name === "generic-password") {
614
+ const val = match[1] ?? "";
615
+ if (!val || val.length < 6) continue;
616
+ if (isFakeCredentialValue(val)) continue;
617
+ if (/password\s*:\s*(?:string|undefined|null|boolean)/.test(line)) continue;
618
+ }
619
+ if (pattern.name === "generic-secret") {
620
+ const val = match[1] ?? "";
621
+ if (!val || /^[a-z_]+$/i.test(val)) continue;
622
+ if (isFakeCredentialValue(val)) continue;
623
+ if (/\w+\(|\w+\.\w+/.test(val)) continue;
624
+ }
625
+ if (pattern.ruleId === "CRED005" || pattern.ruleId === "CRED006") {
626
+ if (/\$\{|<.*>|YOUR_|REPLACE|TODO|localhost/.test(line)) continue;
627
+ if (/example/i.test(line) && !/example\.(?:com|org|net|io)/i.test(line)) continue;
628
+ }
629
+ findings.push({
630
+ id: deterministicId(uri, i + 1, pattern.ruleId, pattern.name),
631
+ engine: "credentials",
632
+ severity: escalate(pattern.severity, critical),
633
+ category: "credentials",
634
+ file: uri,
635
+ line: i + 1,
636
+ column: match.index ?? 0,
637
+ message: pattern.message,
638
+ evidence: maskEvidence(trimmed),
639
+ suggestion: localizeCredentialSuggestion(pattern.suggestion, credLang),
640
+ confidence: pattern.confidence / 100,
641
+ autoFixable: false,
642
+ ruleId: pattern.ruleId
643
+ });
644
+ }
645
+ }
646
+ return findings;
647
+ }
648
+ };
649
+
650
+ export { CredentialsEngine };