@triedotdev/mcp 1.0.65 → 1.0.67

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 (67) hide show
  1. package/dist/{agent-smith-ILGLKYRT.js → agent-smith-XGYNJUCJ.js} +5 -5
  2. package/dist/{agent-smith-runner-NWJGTREO.js → agent-smith-runner-QHYGVRNR.js} +65 -65
  3. package/dist/agent-smith-runner-QHYGVRNR.js.map +1 -0
  4. package/dist/{chunk-TSHZQKCM.js → chunk-2KLYR5GW.js} +4 -4
  5. package/dist/chunk-2KLYR5GW.js.map +1 -0
  6. package/dist/{chunk-JP4U3OMW.js → chunk-4H6HAVYQ.js} +3 -3
  7. package/dist/{chunk-7KHT2NKR.js → chunk-6TSYRIQS.js} +2 -2
  8. package/dist/{chunk-DQ4FYOHV.js → chunk-6XMLAP65.js} +414 -200
  9. package/dist/chunk-6XMLAP65.js.map +1 -0
  10. package/dist/{chunk-KOFQ47YW.js → chunk-CM7EHNQK.js} +6 -6
  11. package/dist/chunk-CM7EHNQK.js.map +1 -0
  12. package/dist/{chunk-PBOVCPKE.js → chunk-CMZTFDNC.js} +41 -41
  13. package/dist/chunk-CMZTFDNC.js.map +1 -0
  14. package/dist/{chunk-H5MDUTL3.js → chunk-E2ASFZMF.js} +15 -15
  15. package/dist/chunk-E2ASFZMF.js.map +1 -0
  16. package/dist/{chunk-NM35UECE.js → chunk-EWQF6INU.js} +6 -6
  17. package/dist/chunk-EWQF6INU.js.map +1 -0
  18. package/dist/{chunk-ULOW5HSH.js → chunk-FCMAQSV7.js} +3 -3
  19. package/dist/{chunk-ULOW5HSH.js.map → chunk-FCMAQSV7.js.map} +1 -1
  20. package/dist/{chunk-D3DMONAJ.js → chunk-HWJJIAR7.js} +138 -11
  21. package/dist/chunk-HWJJIAR7.js.map +1 -0
  22. package/dist/{chunk-RAZUNSBI.js → chunk-MIL54SAF.js} +2 -2
  23. package/dist/{chunk-RAZUNSBI.js.map → chunk-MIL54SAF.js.map} +1 -1
  24. package/dist/{chunk-4YSLDGBL.js → chunk-O7WFJC2P.js} +5 -5
  25. package/dist/chunk-O7WFJC2P.js.map +1 -0
  26. package/dist/{chunk-GWSNINKX.js → chunk-PH4HZEAM.js} +2 -2
  27. package/dist/{chunk-3RQPPRM3.js → chunk-PSYXALLF.js} +13 -13
  28. package/dist/chunk-PSYXALLF.js.map +1 -0
  29. package/dist/{chunk-MVUCBUBR.js → chunk-SH2JIQLB.js} +3 -3
  30. package/dist/{chunk-MVUCBUBR.js.map → chunk-SH2JIQLB.js.map} +1 -1
  31. package/dist/{chunk-AQCAMIQQ.js → chunk-Z7N7KDK3.js} +4 -4
  32. package/dist/{chunk-AQCAMIQQ.js.map → chunk-Z7N7KDK3.js.map} +1 -1
  33. package/dist/cli/create-agent.js +18 -18
  34. package/dist/cli/create-agent.js.map +1 -1
  35. package/dist/cli/main.js +31 -31
  36. package/dist/cli/main.js.map +1 -1
  37. package/dist/cli/yolo-daemon.js +17 -17
  38. package/dist/cli/yolo-daemon.js.map +1 -1
  39. package/dist/{goal-manager-KFBOAP4X.js → goal-manager-B673YUZF.js} +6 -6
  40. package/dist/guardian-agent-FYZ5F3DA.js +17 -0
  41. package/dist/index.js +77 -77
  42. package/dist/index.js.map +1 -1
  43. package/dist/{issue-store-QRDF3X55.js → issue-store-SHQZICED.js} +4 -4
  44. package/dist/{vibe-code-signatures-TGMQXYGO.js → vibe-code-signatures-X26VXSZ4.js} +3 -3
  45. package/dist/{vulnerability-signatures-GOVD4Q24.js → vulnerability-signatures-BER2HRDC.js} +3 -3
  46. package/dist/workers/agent-worker.js +8 -8
  47. package/package.json +1 -1
  48. package/dist/agent-smith-runner-NWJGTREO.js.map +0 -1
  49. package/dist/chunk-3RQPPRM3.js.map +0 -1
  50. package/dist/chunk-4YSLDGBL.js.map +0 -1
  51. package/dist/chunk-D3DMONAJ.js.map +0 -1
  52. package/dist/chunk-DQ4FYOHV.js.map +0 -1
  53. package/dist/chunk-H5MDUTL3.js.map +0 -1
  54. package/dist/chunk-KOFQ47YW.js.map +0 -1
  55. package/dist/chunk-NM35UECE.js.map +0 -1
  56. package/dist/chunk-PBOVCPKE.js.map +0 -1
  57. package/dist/chunk-TSHZQKCM.js.map +0 -1
  58. package/dist/guardian-agent-PULK546O.js +0 -17
  59. /package/dist/{agent-smith-ILGLKYRT.js.map → agent-smith-XGYNJUCJ.js.map} +0 -0
  60. /package/dist/{chunk-JP4U3OMW.js.map → chunk-4H6HAVYQ.js.map} +0 -0
  61. /package/dist/{chunk-7KHT2NKR.js.map → chunk-6TSYRIQS.js.map} +0 -0
  62. /package/dist/{chunk-GWSNINKX.js.map → chunk-PH4HZEAM.js.map} +0 -0
  63. /package/dist/{goal-manager-KFBOAP4X.js.map → goal-manager-B673YUZF.js.map} +0 -0
  64. /package/dist/{guardian-agent-PULK546O.js.map → guardian-agent-FYZ5F3DA.js.map} +0 -0
  65. /package/dist/{issue-store-QRDF3X55.js.map → issue-store-SHQZICED.js.map} +0 -0
  66. /package/dist/{vibe-code-signatures-TGMQXYGO.js.map → vibe-code-signatures-X26VXSZ4.js.map} +0 -0
  67. /package/dist/{vulnerability-signatures-GOVD4Q24.js.map → vulnerability-signatures-BER2HRDC.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/trie/vulnerability-signatures.ts"],"sourcesContent":["/**\n * Vulnerability Signature Database\n * \n * Pre-indexed security patterns using Aho-Corasick for O(n + z) scanning\n * where n = file size, z = number of matches.\n * \n * This is MUCH faster than running 100+ regex patterns on every file.\n * \n * IMPROVEMENTS (v2):\n * - Context-aware pattern matching to reduce false positives\n * - File path exclusions for test/lock files\n * - SQL injection detection only in SQL contexts\n * - Better secret detection avoiding package names/URLs\n */\n\nimport { AhoCorasick, PatternMetadata } from './trie.js';\nimport { isInteractiveMode } from '../utils/progress.js';\n\nexport interface VulnerabilityMatch {\n pattern: string;\n line: number;\n column: number;\n severity: 'critical' | 'serious' | 'moderate' | 'low';\n category: string;\n description: string;\n cwe?: string;\n fix: string;\n}\n\n/**\n * Files/patterns to ALWAYS exclude from scanning (never any false positives from these)\n */\nconst ALWAYS_EXCLUDED_FILES = [\n /vulnerability-signatures\\.[jt]s$/, // CRITICAL: Never scan ourselves!\n /vibe-code-signatures\\.[jt]s$/, // Never scan signature files\n /package-lock\\.json$/, // Lock files\n /yarn\\.lock$/,\n /pnpm-lock\\.yaml$/,\n /node_modules\\//, // Dependencies\n /\\.d\\.ts$/, // Type definitions\n /\\.min\\.[jt]s$/, // Minified files\n /dist\\//, // Build output\n /build\\//,\n];\n\n/**\n * Files to exclude from non-critical checks (test files, examples, etc.)\n */\nconst EXCLUDED_FILE_PATTERNS = [\n /\\.test\\.[jt]sx?$/, // Test files\n /\\.spec\\.[jt]sx?$/, // Spec files\n /__tests__\\//, // Test directories\n /\\/test\\//, // test/ directory\n /\\/tests\\//, // tests/ directory\n /\\.stories\\.[jt]sx?$/, // Storybook files\n /\\.config\\.[jt]s$/, // Config files\n /example/i, // Example files\n /demo/i, // Demo files\n /fixture/i, // Test fixtures\n /mock/i, // Mock files\n];\n\n/**\n * Check if a file should be completely excluded from scanning\n */\nexport function shouldAlwaysExcludeFile(filePath: string): boolean {\n return ALWAYS_EXCLUDED_FILES.some(pattern => pattern.test(filePath));\n}\n\n/**\n * Check if a file should be excluded from certain checks\n */\nexport function shouldExcludeFile(filePath: string, patternCategory: string): boolean {\n // CRITICAL: Always exclude signature files - never flag ourselves!\n if (shouldAlwaysExcludeFile(filePath)) {\n return true;\n }\n \n // For secrets in test files, we need extra context checking (done elsewhere)\n // Don't auto-exclude test files for secrets here, let isFalsePositive handle it\n if (patternCategory === 'secrets' || patternCategory === 'exposed-secrets') {\n return false;\n }\n \n // Exclude certain file types from non-critical checks\n return EXCLUDED_FILE_PATTERNS.some(pattern => pattern.test(filePath));\n}\n\n/**\n * SQL-related keywords that indicate a SQL context\n */\nconst SQL_CONTEXT_KEYWORDS = [\n 'SELECT', 'INSERT', 'UPDATE', 'DELETE', 'FROM', 'WHERE', 'JOIN',\n 'query', 'execute', 'sql', 'prisma', 'knex', 'sequelize',\n 'createQueryBuilder', 'rawQuery', '.raw('\n];\n\n/**\n * Check if a line is in a SQL context\n */\nfunction isInSQLContext(line: string, surroundingLines: string[]): boolean {\n const allContent = [line, ...surroundingLines].join(' ').toLowerCase();\n return SQL_CONTEXT_KEYWORDS.some(keyword => \n allContent.includes(keyword.toLowerCase())\n );\n}\n\n/**\n * Security vulnerability patterns organized by category\n */\nconst VULNERABILITY_PATTERNS: Array<{\n pattern: string;\n metadata: PatternMetadata;\n}> = [\n // ============================================\n // CRITICAL: Injection vulnerabilities\n // ============================================\n {\n pattern: 'eval(',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'injection',\n description: 'eval() can execute arbitrary code - potential RCE',\n cwe: 'CWE-95',\n fix: 'Use safer alternatives like JSON.parse() or a sandboxed interpreter',\n },\n },\n {\n pattern: 'new Function(',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'injection',\n description: 'new Function() can execute arbitrary code',\n cwe: 'CWE-95',\n fix: 'Avoid dynamic function creation from user input',\n },\n },\n {\n pattern: 'exec(',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'injection',\n description: 'Command execution - potential command injection',\n cwe: 'CWE-78',\n fix: 'Use parameterized commands and validate/sanitize all inputs',\n },\n },\n {\n pattern: 'execSync(',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'injection',\n description: 'Synchronous command execution - potential injection',\n cwe: 'CWE-78',\n fix: 'Use spawn with argument arrays instead of shell strings',\n },\n },\n {\n pattern: 'spawn(',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'injection',\n description: 'Process spawn - verify inputs are sanitized',\n cwe: 'CWE-78',\n fix: 'Use shell: false and pass arguments as array',\n },\n },\n {\n pattern: 'child_process',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'injection',\n description: 'Child process module - review for command injection',\n cwe: 'CWE-78',\n fix: 'Validate all inputs passed to child processes',\n },\n },\n\n // ============================================\n // CRITICAL: SQL Injection patterns\n // NOTE: ${} is NOT flagged here - we check SQL context in isFalsePositive\n // ============================================\n {\n pattern: 'SELECT * FROM',\n metadata: {\n type: 'vulnerability',\n severity: 'moderate',\n category: 'sql-injection',\n description: 'Raw SQL query detected - verify parameterization',\n cwe: 'CWE-89',\n fix: 'Use ORM or parameterized queries',\n },\n },\n {\n pattern: 'INSERT INTO',\n metadata: {\n type: 'vulnerability',\n severity: 'moderate',\n category: 'sql-injection',\n description: 'Raw SQL INSERT - verify parameterization',\n cwe: 'CWE-89',\n fix: 'Use parameterized queries',\n },\n },\n {\n pattern: 'DELETE FROM',\n metadata: {\n type: 'vulnerability',\n severity: 'moderate',\n category: 'sql-injection',\n description: 'Raw SQL DELETE - verify parameterization',\n cwe: 'CWE-89',\n fix: 'Use parameterized queries',\n },\n },\n {\n pattern: '.raw(`',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'sql-injection',\n description: 'Raw query with template literal - high injection risk',\n cwe: 'CWE-89',\n fix: 'Avoid raw queries with interpolation or use proper escaping',\n },\n },\n {\n pattern: \".raw('\",\n metadata: {\n type: 'vulnerability',\n severity: 'moderate',\n category: 'sql-injection',\n description: 'Raw query method - verify for injection risk',\n cwe: 'CWE-89',\n fix: 'Use parameterized queries instead of raw SQL',\n },\n },\n {\n pattern: '.raw(\"',\n metadata: {\n type: 'vulnerability',\n severity: 'moderate',\n category: 'sql-injection',\n description: 'Raw query method - verify for injection risk',\n cwe: 'CWE-89',\n fix: 'Use parameterized queries instead of raw SQL',\n },\n },\n {\n pattern: '`SELECT',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'sql-injection',\n description: 'SQL in template literal - check for injection',\n cwe: 'CWE-89',\n fix: 'Use parameterized queries with placeholders',\n },\n },\n {\n pattern: '`INSERT',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'sql-injection',\n description: 'SQL INSERT in template literal - check for injection',\n cwe: 'CWE-89',\n fix: 'Use parameterized queries with placeholders',\n },\n },\n {\n pattern: '`UPDATE',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'sql-injection',\n description: 'SQL UPDATE in template literal - check for injection',\n cwe: 'CWE-89',\n fix: 'Use parameterized queries with placeholders',\n },\n },\n {\n pattern: '`DELETE',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'sql-injection',\n description: 'SQL DELETE in template literal - check for injection',\n cwe: 'CWE-89',\n fix: 'Use parameterized queries with placeholders',\n },\n },\n\n // ============================================\n // CRITICAL: XSS vulnerabilities\n // ============================================\n {\n pattern: 'innerHTML',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'xss',\n description: 'innerHTML can inject malicious scripts',\n cwe: 'CWE-79',\n fix: 'Use textContent or sanitize HTML with DOMPurify',\n },\n },\n {\n pattern: 'outerHTML',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'xss',\n description: 'outerHTML can inject malicious scripts',\n cwe: 'CWE-79',\n fix: 'Avoid outerHTML with user input',\n },\n },\n {\n pattern: 'document.write',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'xss',\n description: 'document.write can inject malicious content',\n cwe: 'CWE-79',\n fix: 'Use DOM methods like createElement instead',\n },\n },\n {\n pattern: 'dangerouslySetInnerHTML',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'xss',\n description: 'React dangerouslySetInnerHTML - XSS risk',\n cwe: 'CWE-79',\n fix: 'Sanitize with DOMPurify before using',\n },\n },\n {\n pattern: 'v-html',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'xss',\n description: 'Vue v-html directive - XSS risk',\n cwe: 'CWE-79',\n fix: 'Sanitize content or use v-text',\n },\n },\n {\n pattern: '[innerHTML]',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'xss',\n description: 'Angular innerHTML binding - XSS risk',\n cwe: 'CWE-79',\n fix: 'Use Angular DomSanitizer',\n },\n },\n\n // ============================================\n // CRITICAL: Hardcoded secrets\n // More specific patterns to reduce false positives\n // ============================================\n {\n pattern: \"password = '\",\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'secrets',\n description: 'Hardcoded password in string',\n cwe: 'CWE-798',\n fix: 'Use environment variables or secret management',\n },\n },\n {\n pattern: 'password = \"',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'secrets',\n description: 'Hardcoded password in string',\n cwe: 'CWE-798',\n fix: 'Use environment variables or secret management',\n },\n },\n {\n pattern: \"password: '\",\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'secrets',\n description: 'Hardcoded password in config',\n cwe: 'CWE-798',\n fix: 'Use environment variables or secret management',\n },\n },\n {\n pattern: 'password: \"',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'secrets',\n description: 'Hardcoded password in config',\n cwe: 'CWE-798',\n fix: 'Use environment variables or secret management',\n },\n },\n {\n pattern: \"api_key = '\",\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'secrets',\n description: 'Hardcoded API key',\n cwe: 'CWE-798',\n fix: 'Use environment variables',\n },\n },\n {\n pattern: 'api_key = \"',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'secrets',\n description: 'Hardcoded API key',\n cwe: 'CWE-798',\n fix: 'Use environment variables',\n },\n },\n {\n pattern: \"apiKey: '\",\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'secrets',\n description: 'Hardcoded API key in config',\n cwe: 'CWE-798',\n fix: 'Use environment variables',\n },\n },\n {\n pattern: 'apiKey: \"',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'secrets',\n description: 'Hardcoded API key in config',\n cwe: 'CWE-798',\n fix: 'Use environment variables',\n },\n },\n {\n pattern: \"secret = '\",\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'secrets',\n description: 'Hardcoded secret',\n cwe: 'CWE-798',\n fix: 'Use environment variables or secret management',\n },\n },\n {\n pattern: 'secret = \"',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'secrets',\n description: 'Hardcoded secret',\n cwe: 'CWE-798',\n fix: 'Use environment variables or secret management',\n },\n },\n {\n pattern: 'AWS_SECRET_ACCESS_KEY=',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'secrets',\n description: 'AWS secret key assignment',\n cwe: 'CWE-798',\n fix: 'Use IAM roles or AWS Secrets Manager',\n },\n },\n {\n pattern: \"'Bearer \",\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'secrets',\n description: 'Hardcoded bearer token in string',\n cwe: 'CWE-798',\n fix: 'Use environment variables for tokens',\n },\n },\n {\n pattern: '\"Bearer ',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'secrets',\n description: 'Hardcoded bearer token in string',\n cwe: 'CWE-798',\n fix: 'Use environment variables for tokens',\n },\n },\n\n // ============================================\n // SERIOUS: Authentication issues\n // ============================================\n {\n pattern: 'password ==',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'auth',\n description: 'Plain text password comparison',\n cwe: 'CWE-256',\n fix: 'Use bcrypt.compare() or similar secure comparison',\n },\n },\n {\n pattern: 'password ===',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'auth',\n description: 'Plain text password comparison',\n cwe: 'CWE-256',\n fix: 'Use bcrypt.compare() or similar secure comparison',\n },\n },\n {\n pattern: 'MD5(',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'crypto',\n description: 'MD5 is cryptographically broken',\n cwe: 'CWE-328',\n fix: 'Use SHA-256 or bcrypt for passwords',\n },\n },\n {\n pattern: 'md5(',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'crypto',\n description: 'MD5 is cryptographically broken',\n cwe: 'CWE-328',\n fix: 'Use SHA-256 or bcrypt for passwords',\n },\n },\n {\n pattern: 'SHA1(',\n metadata: {\n type: 'vulnerability',\n severity: 'moderate',\n category: 'crypto',\n description: 'SHA1 is deprecated for security use',\n cwe: 'CWE-328',\n fix: 'Use SHA-256 or stronger',\n },\n },\n {\n pattern: 'sha1(',\n metadata: {\n type: 'vulnerability',\n severity: 'moderate',\n category: 'crypto',\n description: 'SHA1 is deprecated for security use',\n cwe: 'CWE-328',\n fix: 'Use SHA-256 or stronger',\n },\n },\n {\n pattern: 'Math.random()',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'crypto',\n description: 'Math.random() is not cryptographically secure',\n cwe: 'CWE-338',\n fix: 'Use crypto.randomBytes() or crypto.getRandomValues()',\n },\n },\n\n // ============================================\n // SERIOUS: Insecure configurations\n // ============================================\n {\n pattern: 'cors: true',\n metadata: {\n type: 'vulnerability',\n severity: 'moderate',\n category: 'config',\n description: 'CORS enabled - verify origin restrictions',\n cwe: 'CWE-942',\n fix: 'Specify allowed origins explicitly',\n },\n },\n {\n pattern: \"origin: '*'\",\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'config',\n description: 'CORS allows all origins',\n cwe: 'CWE-942',\n fix: 'Restrict to specific trusted origins',\n },\n },\n {\n pattern: 'origin: \"*\"',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'config',\n description: 'CORS allows all origins',\n cwe: 'CWE-942',\n fix: 'Restrict to specific trusted origins',\n },\n },\n {\n pattern: 'secure: false',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'config',\n description: 'Insecure cookie/connection setting',\n cwe: 'CWE-614',\n fix: 'Set secure: true in production',\n },\n },\n {\n pattern: 'httpOnly: false',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'config',\n description: 'Cookie accessible to JavaScript',\n cwe: 'CWE-1004',\n fix: 'Set httpOnly: true to prevent XSS cookie theft',\n },\n },\n {\n pattern: 'rejectUnauthorized: false',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'config',\n description: 'TLS certificate validation disabled',\n cwe: 'CWE-295',\n fix: 'Enable certificate validation in production',\n },\n },\n {\n pattern: 'NODE_TLS_REJECT_UNAUTHORIZED',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'config',\n description: 'TLS validation may be disabled',\n cwe: 'CWE-295',\n fix: 'Never disable TLS validation in production',\n },\n },\n\n // ============================================\n // MODERATE: Common bugs and issues\n // ============================================\n {\n pattern: '.forEach(async',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'async',\n description: 'async forEach does not await - unexpected behavior',\n cwe: 'CWE-703',\n fix: 'Use for...of loop or Promise.all(arr.map())',\n },\n },\n {\n pattern: 'JSON.parse(',\n metadata: {\n type: 'vulnerability',\n severity: 'moderate',\n category: 'error-handling',\n description: 'JSON.parse can throw - needs try/catch',\n cwe: 'CWE-755',\n fix: 'Wrap in try/catch block',\n },\n },\n {\n pattern: 'atob(',\n metadata: {\n type: 'vulnerability',\n severity: 'low',\n category: 'encoding',\n description: 'atob can throw on invalid input',\n cwe: 'CWE-755',\n fix: 'Wrap in try/catch and validate input',\n },\n },\n\n // ============================================\n // Privacy & Compliance patterns\n // ============================================\n {\n pattern: 'console.log(',\n metadata: {\n type: 'vulnerability',\n severity: 'low',\n category: 'logging',\n description: 'Console logging - may leak sensitive data',\n cwe: 'CWE-532',\n fix: 'Remove or replace with proper logging in production',\n },\n },\n {\n pattern: 'localStorage.setItem',\n metadata: {\n type: 'vulnerability',\n severity: 'moderate',\n category: 'storage',\n description: 'localStorage is accessible to XSS attacks',\n cwe: 'CWE-922',\n fix: 'Avoid storing sensitive data in localStorage',\n },\n },\n {\n pattern: 'sessionStorage.setItem',\n metadata: {\n type: 'vulnerability',\n severity: 'moderate',\n category: 'storage',\n description: 'sessionStorage is accessible to XSS attacks',\n cwe: 'CWE-922',\n fix: 'Avoid storing sensitive data in sessionStorage',\n },\n },\n];\n\n/**\n * Build the vulnerability signature trie\n * Called once at startup, then O(1) access\n */\nlet vulnerabilityTrie: AhoCorasick<PatternMetadata> | null = null;\n\nexport function getVulnerabilityTrie(): AhoCorasick<PatternMetadata> {\n if (!vulnerabilityTrie) {\n vulnerabilityTrie = new AhoCorasick<PatternMetadata>();\n \n for (const { pattern, metadata } of VULNERABILITY_PATTERNS) {\n vulnerabilityTrie.addPattern(pattern, metadata, metadata);\n }\n \n vulnerabilityTrie.build();\n if (!isInteractiveMode()) {\n console.error(` 🔧 Loaded ${VULNERABILITY_PATTERNS.length} vulnerability signatures into trie`);\n }\n }\n \n return vulnerabilityTrie;\n}\n\n/**\n * Scan code for vulnerabilities using the trie\n * O(n + z) where n = code length, z = number of matches\n */\nexport function scanForVulnerabilities(code: string, filePath: string): VulnerabilityMatch[] {\n // CRITICAL: Skip files that should never be scanned\n if (shouldAlwaysExcludeFile(filePath)) {\n return [];\n }\n \n const trie = getVulnerabilityTrie();\n const rawMatches = trie.search(code);\n const lines = code.split('\\n');\n \n // Deduplicate and filter false positives\n const matches: VulnerabilityMatch[] = [];\n const seen = new Set<string>();\n \n for (const match of rawMatches) {\n // Create unique key for deduplication\n const key = `${match.line}:${match.pattern}`;\n if (seen.has(key)) continue;\n seen.add(key);\n \n const meta = match.metadata!;\n \n // Check file exclusions\n if (shouldExcludeFile(filePath, meta.category || '')) continue;\n \n // Filter out false positives\n if (isFalsePositive(code, match, filePath, lines)) continue;\n \n const vulnMatch: VulnerabilityMatch = {\n pattern: match.pattern,\n line: match.line,\n column: match.column,\n severity: meta.severity as any,\n category: meta.category || 'unknown',\n description: meta.description || '',\n fix: meta.fix || '',\n };\n if (meta.cwe !== undefined) {\n vulnMatch.cwe = meta.cwe;\n }\n matches.push(vulnMatch);\n }\n \n return matches;\n}\n\n/**\n * Get surrounding lines for context analysis\n */\nfunction getSurroundingLines(lines: string[], lineNum: number, range: number = 3): string[] {\n const start = Math.max(0, lineNum - range - 1);\n const end = Math.min(lines.length, lineNum + range);\n return lines.slice(start, end);\n}\n\n/**\n * Filter out common false positives with enhanced context awareness\n */\nfunction isFalsePositive(_code: string, match: any, filePath: string, lines: string[]): boolean {\n const line = lines[match.line - 1] || '';\n const trimmedLine = line.trim();\n const pattern = match.pattern;\n const category = match.metadata?.category || '';\n \n // ============================================\n // CRITICAL: Skip signature/pattern definition files\n // ============================================\n if (filePath.includes('signature') || \n filePath.includes('patterns') ||\n filePath.includes('rules')) {\n // If the line contains 'pattern:' or 'pattern =' it's a definition, not a vulnerability\n if (/pattern\\s*[:=]/.test(line)) {\n return true;\n }\n }\n \n // Skip if line is a pattern string definition (in any file)\n // e.g., pattern: \"password = '\", or { pattern: 'secret' }\n if (/^\\s*(pattern|regex|rule|signature)\\s*[:=]/.test(trimmedLine)) {\n return true;\n }\n \n // ============================================\n // CRITICAL: Skip test files entirely for most patterns\n // ============================================\n if (isTestFile(filePath)) {\n // Test files can have intentional bad code for testing detection\n // Only flag REAL secrets (actual API keys that look real)\n if (category === 'secrets') {\n // Skip if it's clearly test/mock data\n if (/test|mock|fake|dummy|example|fixture|sample|placeholder/i.test(line)) {\n return true;\n }\n // Skip generic fake values like \"password123\", \"secret_test\", etc.\n if (/'[a-z_]*password[a-z_0-9]*'|\"[a-z_]*password[a-z_0-9]*\"|'[a-z_]*secret[a-z_0-9]*'|\"[a-z_]*secret[a-z_0-9]*\"/i.test(line)) {\n return true;\n }\n // Skip obviously fake API keys (short or with placeholder patterns)\n if (/sk-[a-z0-9]{10,20}\"|'sk-[a-z0-9]{10,20}'|api[_-]?key.*['\"][a-z0-9_-]{5,30}['\"]/i.test(line)) {\n return true;\n }\n }\n // For non-secrets, skip all test file findings\n return true;\n }\n \n // ============================================\n // SKIP: Comments and documentation\n // ============================================\n if (trimmedLine.startsWith('//') || \n trimmedLine.startsWith('*') || \n trimmedLine.startsWith('/*') ||\n trimmedLine.startsWith('#') ||\n trimmedLine.startsWith('<!--')) {\n return true;\n }\n \n // Skip JSDoc and documentation blocks\n if (/^\\s*\\*\\s/.test(line) || /@(param|returns|example|description|see|link)/i.test(line)) {\n return true;\n }\n \n // Skip description/fix/metadata strings (common in config objects)\n if (/^\\s*(description|fix|message|help|hint|reason|why)\\s*[:=]/.test(trimmedLine)) {\n return true;\n }\n \n // ============================================\n // SKIP: Type definitions and interfaces\n // ============================================\n if (/^\\s*(interface|type|export\\s+interface|export\\s+type)\\s/.test(line)) {\n return true;\n }\n \n // Skip TypeScript type annotations (e.g., password: string)\n if (/:\\s*(string|number|boolean|any|unknown|null|undefined|void)\\s*(;|,|\\)|$)/.test(line)) {\n return true;\n }\n \n // Skip interface/type property definitions\n if (/^\\s*\\w+\\s*\\??\\s*:\\s*(string|number|boolean|any)/.test(trimmedLine)) {\n return true;\n }\n \n // ============================================\n // SKIP: Environment variable reads (not hardcoded)\n // ============================================\n if (/process\\.env|import\\.meta\\.env|getenv|os\\.environ|Deno\\.env|\\.env\\.|config\\.\\w+|settings\\.\\w+/.test(line)) {\n return true;\n }\n \n // ============================================\n // SKIP: Lock files and package metadata\n // ============================================\n if (filePath.endsWith('package-lock.json') || \n filePath.endsWith('yarn.lock') ||\n filePath.endsWith('pnpm-lock.yaml') ||\n filePath.includes('node_modules/')) {\n return true;\n }\n \n // ============================================\n // SKIP: String in object definition (metadata, not code)\n // ============================================\n // Lines like: severity: 'critical', or category: 'secrets'\n if (/^\\s*(severity|category|type|level|priority|cwe|owasp)\\s*:\\s*['\"]/.test(trimmedLine)) {\n return true;\n }\n \n // ============================================\n // Category-specific false positive detection\n // ============================================\n \n // SQL Injection: Only flag in SQL contexts\n if (category === 'sql-injection') {\n const surroundingLines = getSurroundingLines(lines, match.line);\n if (!isInSQLContext(line, surroundingLines)) {\n return true;\n }\n }\n \n // Secrets: Very strict detection to avoid false positives\n if (category === 'secrets' || category === 'auth') {\n // Skip function parameters (function foo(password: string))\n if (/\\(\\s*[^)]*\\w+\\s*:\\s*(string|any)/.test(line)) {\n return true;\n }\n // Skip object destructuring ({ password })\n if (/\\{\\s*\\w*password\\w*\\s*(,|\\}|:)/.test(line) && !/'|\"|`/.test(line.split(/password/i)[1] || '')) {\n return true;\n }\n // Skip when reading from env or config\n if (/=\\s*(process\\.env|config\\.|options\\.|settings\\.|env\\.)/.test(line)) {\n return true;\n }\n // Skip variable declarations without string literals\n if (/password\\s*[=:](?!\\s*['\"`])/.test(line)) {\n return true;\n }\n // Skip if it's reading from another variable\n if (/password\\s*=\\s*\\w+(\\.|$)/.test(line) && !/'|\"|`/.test(line)) {\n return true;\n }\n // Skip error messages and logging about passwords\n if (/error|message|log|warn|info|debug|throw|new Error/i.test(line)) {\n return true;\n }\n // Skip regex patterns for password validation\n if (/regex|RegExp|\\/.*password.*\\//i.test(line)) {\n return true;\n }\n }\n \n // Logging: Skip in development/debug contexts\n if (category === 'logging') {\n // console.error is often intentional\n if (pattern === 'console.error(' || pattern === 'console.warn(') {\n return true;\n }\n // Skip if in catch block (error logging)\n if (/catch|error|err\\b/.test(line)) {\n return true;\n }\n }\n \n // Config patterns: Skip legitimate security config\n if (category === 'config') {\n // Skip when setting secure values\n if (/secure:\\s*true/.test(line) || /httpOnly:\\s*true/.test(line)) {\n return true;\n }\n // Skip environment-based config\n if (/NODE_ENV|process\\.env|production|development/.test(line)) {\n return true;\n }\n // Skip conditional configs\n if (/if\\s*\\(|ternary|\\?.*:/.test(line)) {\n return true;\n }\n }\n \n // Crypto: Skip in contexts where weak crypto is acceptable\n if (category === 'crypto') {\n // MD5/SHA1 for non-security purposes (checksums, cache keys)\n if (/checksum|hash.*file|etag|cache.*key|fingerprint|integrity|content.*hash/i.test(line)) {\n return true;\n }\n // Math.random for non-crypto purposes (UI, games, etc.)\n if (pattern === 'Math.random()') {\n // Only flag if in security context\n if (!/token|secret|password|key|auth|session|csrf|nonce/i.test(line)) {\n return true;\n }\n }\n }\n \n // Async: forEach async is sometimes intentional\n if (category === 'async') {\n // Skip if there's a comment indicating it's intentional\n if (/\\/\\/.*intentional|\\/\\/.*fire.?and.?forget|\\/\\/.*parallel/i.test(line)) {\n return true;\n }\n }\n \n // ============================================\n // SKIP: Validation/check patterns (not vulnerabilities)\n // ============================================\n // Skip password validation logic\n if (/password.*length|validate.*password|check.*password|verify.*password|is.*valid/i.test(line)) {\n return true;\n }\n \n // Skip comparison against hashed values\n if (/bcrypt|argon|scrypt|pbkdf|compare.*hash|hash.*compare|verify.*hash/i.test(line)) {\n return true;\n }\n \n // Skip schema definitions (Zod, Yup, etc.)\n if (/z\\.|yup\\.|joi\\.|schema|validation|validator/i.test(line)) {\n return true;\n }\n \n // ============================================\n // SKIP: Imports and requires\n // ============================================\n if (/^\\s*(import|require|from)\\s/.test(trimmedLine)) {\n return true;\n }\n \n // ============================================\n // SKIP: Example/Demo files\n // ============================================\n if (/example|demo|sample|tutorial|readme/i.test(filePath)) {\n return true;\n }\n \n return false;\n}\n\n/**\n * Check if file is a test file\n */\nfunction isTestFile(filePath: string): boolean {\n return /\\.(test|spec)\\.[jt]sx?$/.test(filePath) ||\n /__tests__\\//.test(filePath) ||\n /test\\//.test(filePath) ||\n /tests\\//.test(filePath) ||\n /\\.stories\\.[jt]sx?$/.test(filePath);\n}\n\n/**\n * Get vulnerability statistics\n */\nexport function getVulnerabilityStats(): { total: number; byCategory: Record<string, number>; bySeverity: Record<string, number> } {\n const byCategory: Record<string, number> = {};\n const bySeverity: Record<string, number> = {};\n \n for (const { metadata } of VULNERABILITY_PATTERNS) {\n const cat = metadata.category || 'unknown';\n const sev = metadata.severity || 'unknown';\n byCategory[cat] = (byCategory[cat] || 0) + 1;\n bySeverity[sev] = (bySeverity[sev] || 0) + 1;\n }\n \n return {\n total: VULNERABILITY_PATTERNS.length,\n byCategory,\n bySeverity,\n };\n}\n\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/trie/vulnerability-signatures.ts"],"sourcesContent":["/**\n * Vulnerability Signature Database\n * \n * Pre-indexed security patterns using Aho-Corasick for O(n + z) scanning\n * where n = file size, z = number of matches.\n * \n * This is MUCH faster than running 100+ regex patterns on every file.\n * \n * IMPROVEMENTS (v2):\n * - Context-aware pattern matching to reduce false positives\n * - File path exclusions for test/lock files\n * - SQL injection detection only in SQL contexts\n * - Better secret detection avoiding package names/URLs\n */\n\nimport { AhoCorasick, PatternMetadata } from './trie.js';\nimport { isInteractiveMode } from '../utils/progress.js';\n\nexport interface VulnerabilityMatch {\n pattern: string;\n line: number;\n column: number;\n severity: 'critical' | 'serious' | 'moderate' | 'low';\n category: string;\n description: string;\n cwe?: string;\n fix: string;\n}\n\n/**\n * Files/patterns to ALWAYS exclude from scanning (never any false positives from these)\n */\nconst ALWAYS_EXCLUDED_FILES = [\n /vulnerability-signatures\\.[jt]s$/, // CRITICAL: Never scan ourselves!\n /vibe-code-signatures\\.[jt]s$/, // Never scan signature files\n /package-lock\\.json$/, // Lock files\n /yarn\\.lock$/,\n /pnpm-lock\\.yaml$/,\n /node_modules\\//, // Dependencies\n /\\.d\\.ts$/, // Type definitions\n /\\.min\\.[jt]s$/, // Minified files\n /dist\\//, // Build output\n /build\\//,\n];\n\n/**\n * Files to exclude from non-critical checks (test files, examples, etc.)\n */\nconst EXCLUDED_FILE_PATTERNS = [\n /\\.test\\.[jt]sx?$/, // Test files\n /\\.spec\\.[jt]sx?$/, // Spec files\n /__tests__\\//, // Test directories\n /\\/test\\//, // test/ directory\n /\\/tests\\//, // tests/ directory\n /\\.stories\\.[jt]sx?$/, // Storybook files\n /\\.config\\.[jt]s$/, // Config files\n /example/i, // Example files\n /demo/i, // Demo files\n /fixture/i, // Test fixtures\n /mock/i, // Mock files\n];\n\n/**\n * Check if a file should be completely excluded from scanning\n */\nexport function shouldAlwaysExcludeFile(filePath: string): boolean {\n return ALWAYS_EXCLUDED_FILES.some(pattern => pattern.test(filePath));\n}\n\n/**\n * Check if a file should be excluded from certain checks\n */\nexport function shouldExcludeFile(filePath: string, patternCategory: string): boolean {\n // CRITICAL: Always exclude signature files - never flag ourselves!\n if (shouldAlwaysExcludeFile(filePath)) {\n return true;\n }\n \n // For secrets in test files, we need extra context checking (done elsewhere)\n // Don't auto-exclude test files for secrets here, let isFalsePositive handle it\n if (patternCategory === 'secrets' || patternCategory === 'exposed-secrets') {\n return false;\n }\n \n // Exclude certain file types from non-critical checks\n return EXCLUDED_FILE_PATTERNS.some(pattern => pattern.test(filePath));\n}\n\n/**\n * SQL-related keywords that indicate a SQL context\n */\nconst SQL_CONTEXT_KEYWORDS = [\n 'SELECT', 'INSERT', 'UPDATE', 'DELETE', 'FROM', 'WHERE', 'JOIN',\n 'query', 'execute', 'sql', 'prisma', 'knex', 'sequelize',\n 'createQueryBuilder', 'rawQuery', '.raw('\n];\n\n/**\n * Check if a line is in a SQL context\n */\nfunction isInSQLContext(line: string, surroundingLines: string[]): boolean {\n const allContent = [line, ...surroundingLines].join(' ').toLowerCase();\n return SQL_CONTEXT_KEYWORDS.some(keyword => \n allContent.includes(keyword.toLowerCase())\n );\n}\n\n/**\n * Security vulnerability patterns organized by category\n */\nconst VULNERABILITY_PATTERNS: Array<{\n pattern: string;\n metadata: PatternMetadata;\n}> = [\n // ============================================\n // CRITICAL: Injection vulnerabilities\n // ============================================\n {\n pattern: 'eval(',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'injection',\n description: 'eval() can execute arbitrary code - potential RCE',\n cwe: 'CWE-95',\n fix: 'Use safer alternatives like JSON.parse() or a sandboxed interpreter',\n },\n },\n {\n pattern: 'new Function(',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'injection',\n description: 'new Function() can execute arbitrary code',\n cwe: 'CWE-95',\n fix: 'Avoid dynamic function creation from user input',\n },\n },\n {\n pattern: 'exec(',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'injection',\n description: 'Command execution - potential command injection',\n cwe: 'CWE-78',\n fix: 'Use parameterized commands and validate/sanitize all inputs',\n },\n },\n {\n pattern: 'execSync(',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'injection',\n description: 'Synchronous command execution - potential injection',\n cwe: 'CWE-78',\n fix: 'Use spawn with argument arrays instead of shell strings',\n },\n },\n {\n pattern: 'spawn(',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'injection',\n description: 'Process spawn - verify inputs are sanitized',\n cwe: 'CWE-78',\n fix: 'Use shell: false and pass arguments as array',\n },\n },\n {\n pattern: 'child_process',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'injection',\n description: 'Child process module - review for command injection',\n cwe: 'CWE-78',\n fix: 'Validate all inputs passed to child processes',\n },\n },\n\n // ============================================\n // CRITICAL: SQL Injection patterns\n // NOTE: ${} is NOT flagged here - we check SQL context in isFalsePositive\n // ============================================\n {\n pattern: 'SELECT * FROM',\n metadata: {\n type: 'vulnerability',\n severity: 'moderate',\n category: 'sql-injection',\n description: 'Raw SQL query detected - verify parameterization',\n cwe: 'CWE-89',\n fix: 'Use ORM or parameterized queries',\n },\n },\n {\n pattern: 'INSERT INTO',\n metadata: {\n type: 'vulnerability',\n severity: 'moderate',\n category: 'sql-injection',\n description: 'Raw SQL INSERT - verify parameterization',\n cwe: 'CWE-89',\n fix: 'Use parameterized queries',\n },\n },\n {\n pattern: 'DELETE FROM',\n metadata: {\n type: 'vulnerability',\n severity: 'moderate',\n category: 'sql-injection',\n description: 'Raw SQL DELETE - verify parameterization',\n cwe: 'CWE-89',\n fix: 'Use parameterized queries',\n },\n },\n {\n pattern: '.raw(`',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'sql-injection',\n description: 'Raw query with template literal - high injection risk',\n cwe: 'CWE-89',\n fix: 'Avoid raw queries with interpolation or use proper escaping',\n },\n },\n {\n pattern: \".raw('\",\n metadata: {\n type: 'vulnerability',\n severity: 'moderate',\n category: 'sql-injection',\n description: 'Raw query method - verify for injection risk',\n cwe: 'CWE-89',\n fix: 'Use parameterized queries instead of raw SQL',\n },\n },\n {\n pattern: '.raw(\"',\n metadata: {\n type: 'vulnerability',\n severity: 'moderate',\n category: 'sql-injection',\n description: 'Raw query method - verify for injection risk',\n cwe: 'CWE-89',\n fix: 'Use parameterized queries instead of raw SQL',\n },\n },\n {\n pattern: '`SELECT',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'sql-injection',\n description: 'SQL in template literal - check for injection',\n cwe: 'CWE-89',\n fix: 'Use parameterized queries with placeholders',\n },\n },\n {\n pattern: '`INSERT',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'sql-injection',\n description: 'SQL INSERT in template literal - check for injection',\n cwe: 'CWE-89',\n fix: 'Use parameterized queries with placeholders',\n },\n },\n {\n pattern: '`UPDATE',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'sql-injection',\n description: 'SQL UPDATE in template literal - check for injection',\n cwe: 'CWE-89',\n fix: 'Use parameterized queries with placeholders',\n },\n },\n {\n pattern: '`DELETE',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'sql-injection',\n description: 'SQL DELETE in template literal - check for injection',\n cwe: 'CWE-89',\n fix: 'Use parameterized queries with placeholders',\n },\n },\n\n // ============================================\n // CRITICAL: XSS vulnerabilities\n // ============================================\n {\n pattern: 'innerHTML',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'xss',\n description: 'innerHTML can inject malicious scripts',\n cwe: 'CWE-79',\n fix: 'Use textContent or sanitize HTML with DOMPurify',\n },\n },\n {\n pattern: 'outerHTML',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'xss',\n description: 'outerHTML can inject malicious scripts',\n cwe: 'CWE-79',\n fix: 'Avoid outerHTML with user input',\n },\n },\n {\n pattern: 'document.write',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'xss',\n description: 'document.write can inject malicious content',\n cwe: 'CWE-79',\n fix: 'Use DOM methods like createElement instead',\n },\n },\n {\n pattern: 'dangerouslySetInnerHTML',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'xss',\n description: 'React dangerouslySetInnerHTML - XSS risk',\n cwe: 'CWE-79',\n fix: 'Sanitize with DOMPurify before using',\n },\n },\n {\n pattern: 'v-html',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'xss',\n description: 'Vue v-html directive - XSS risk',\n cwe: 'CWE-79',\n fix: 'Sanitize content or use v-text',\n },\n },\n {\n pattern: '[innerHTML]',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'xss',\n description: 'Angular innerHTML binding - XSS risk',\n cwe: 'CWE-79',\n fix: 'Use Angular DomSanitizer',\n },\n },\n\n // ============================================\n // CRITICAL: Hardcoded secrets\n // More specific patterns to reduce false positives\n // ============================================\n {\n pattern: \"password = '\",\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'secrets',\n description: 'Hardcoded password in string',\n cwe: 'CWE-798',\n fix: 'Use environment variables or secret management',\n },\n },\n {\n pattern: 'password = \"',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'secrets',\n description: 'Hardcoded password in string',\n cwe: 'CWE-798',\n fix: 'Use environment variables or secret management',\n },\n },\n {\n pattern: \"password: '\",\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'secrets',\n description: 'Hardcoded password in config',\n cwe: 'CWE-798',\n fix: 'Use environment variables or secret management',\n },\n },\n {\n pattern: 'password: \"',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'secrets',\n description: 'Hardcoded password in config',\n cwe: 'CWE-798',\n fix: 'Use environment variables or secret management',\n },\n },\n {\n pattern: \"api_key = '\",\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'secrets',\n description: 'Hardcoded API key',\n cwe: 'CWE-798',\n fix: 'Use environment variables',\n },\n },\n {\n pattern: 'api_key = \"',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'secrets',\n description: 'Hardcoded API key',\n cwe: 'CWE-798',\n fix: 'Use environment variables',\n },\n },\n {\n pattern: \"apiKey: '\",\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'secrets',\n description: 'Hardcoded API key in config',\n cwe: 'CWE-798',\n fix: 'Use environment variables',\n },\n },\n {\n pattern: 'apiKey: \"',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'secrets',\n description: 'Hardcoded API key in config',\n cwe: 'CWE-798',\n fix: 'Use environment variables',\n },\n },\n {\n pattern: \"secret = '\",\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'secrets',\n description: 'Hardcoded secret',\n cwe: 'CWE-798',\n fix: 'Use environment variables or secret management',\n },\n },\n {\n pattern: 'secret = \"',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'secrets',\n description: 'Hardcoded secret',\n cwe: 'CWE-798',\n fix: 'Use environment variables or secret management',\n },\n },\n {\n pattern: 'AWS_SECRET_ACCESS_KEY=',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'secrets',\n description: 'AWS secret key assignment',\n cwe: 'CWE-798',\n fix: 'Use IAM roles or AWS Secrets Manager',\n },\n },\n {\n pattern: \"'Bearer \",\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'secrets',\n description: 'Hardcoded bearer token in string',\n cwe: 'CWE-798',\n fix: 'Use environment variables for tokens',\n },\n },\n {\n pattern: '\"Bearer ',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'secrets',\n description: 'Hardcoded bearer token in string',\n cwe: 'CWE-798',\n fix: 'Use environment variables for tokens',\n },\n },\n\n // ============================================\n // SERIOUS: Authentication issues\n // ============================================\n {\n pattern: 'password ==',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'auth',\n description: 'Plain text password comparison',\n cwe: 'CWE-256',\n fix: 'Use bcrypt.compare() or similar secure comparison',\n },\n },\n {\n pattern: 'password ===',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'auth',\n description: 'Plain text password comparison',\n cwe: 'CWE-256',\n fix: 'Use bcrypt.compare() or similar secure comparison',\n },\n },\n {\n pattern: 'MD5(',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'crypto',\n description: 'MD5 is cryptographically broken',\n cwe: 'CWE-328',\n fix: 'Use SHA-256 or bcrypt for passwords',\n },\n },\n {\n pattern: 'md5(',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'crypto',\n description: 'MD5 is cryptographically broken',\n cwe: 'CWE-328',\n fix: 'Use SHA-256 or bcrypt for passwords',\n },\n },\n {\n pattern: 'SHA1(',\n metadata: {\n type: 'vulnerability',\n severity: 'moderate',\n category: 'crypto',\n description: 'SHA1 is deprecated for security use',\n cwe: 'CWE-328',\n fix: 'Use SHA-256 or stronger',\n },\n },\n {\n pattern: 'sha1(',\n metadata: {\n type: 'vulnerability',\n severity: 'moderate',\n category: 'crypto',\n description: 'SHA1 is deprecated for security use',\n cwe: 'CWE-328',\n fix: 'Use SHA-256 or stronger',\n },\n },\n {\n pattern: 'Math.random()',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'crypto',\n description: 'Math.random() is not cryptographically secure',\n cwe: 'CWE-338',\n fix: 'Use crypto.randomBytes() or crypto.getRandomValues()',\n },\n },\n\n // ============================================\n // SERIOUS: Insecure configurations\n // ============================================\n {\n pattern: 'cors: true',\n metadata: {\n type: 'vulnerability',\n severity: 'moderate',\n category: 'config',\n description: 'CORS enabled - verify origin restrictions',\n cwe: 'CWE-942',\n fix: 'Specify allowed origins explicitly',\n },\n },\n {\n pattern: \"origin: '*'\",\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'config',\n description: 'CORS allows all origins',\n cwe: 'CWE-942',\n fix: 'Restrict to specific trusted origins',\n },\n },\n {\n pattern: 'origin: \"*\"',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'config',\n description: 'CORS allows all origins',\n cwe: 'CWE-942',\n fix: 'Restrict to specific trusted origins',\n },\n },\n {\n pattern: 'secure: false',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'config',\n description: 'Insecure cookie/connection setting',\n cwe: 'CWE-614',\n fix: 'Set secure: true in production',\n },\n },\n {\n pattern: 'httpOnly: false',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'config',\n description: 'Cookie accessible to JavaScript',\n cwe: 'CWE-1004',\n fix: 'Set httpOnly: true to prevent XSS cookie theft',\n },\n },\n {\n pattern: 'rejectUnauthorized: false',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'config',\n description: 'TLS certificate validation disabled',\n cwe: 'CWE-295',\n fix: 'Enable certificate validation in production',\n },\n },\n {\n pattern: 'NODE_TLS_REJECT_UNAUTHORIZED',\n metadata: {\n type: 'vulnerability',\n severity: 'critical',\n category: 'config',\n description: 'TLS validation may be disabled',\n cwe: 'CWE-295',\n fix: 'Never disable TLS validation in production',\n },\n },\n\n // ============================================\n // MODERATE: Common bugs and issues\n // ============================================\n {\n pattern: '.forEach(async',\n metadata: {\n type: 'vulnerability',\n severity: 'serious',\n category: 'async',\n description: 'async forEach does not await - unexpected behavior',\n cwe: 'CWE-703',\n fix: 'Use for...of loop or Promise.all(arr.map())',\n },\n },\n {\n pattern: 'JSON.parse(',\n metadata: {\n type: 'vulnerability',\n severity: 'moderate',\n category: 'error-handling',\n description: 'JSON.parse can throw - needs try/catch',\n cwe: 'CWE-755',\n fix: 'Wrap in try/catch block',\n },\n },\n {\n pattern: 'atob(',\n metadata: {\n type: 'vulnerability',\n severity: 'low',\n category: 'encoding',\n description: 'atob can throw on invalid input',\n cwe: 'CWE-755',\n fix: 'Wrap in try/catch and validate input',\n },\n },\n\n // ============================================\n // Privacy & Compliance patterns\n // ============================================\n {\n pattern: 'console.log(',\n metadata: {\n type: 'vulnerability',\n severity: 'low',\n category: 'logging',\n description: 'Console logging - may leak sensitive data',\n cwe: 'CWE-532',\n fix: 'Remove or replace with proper logging in production',\n },\n },\n {\n pattern: 'localStorage.setItem',\n metadata: {\n type: 'vulnerability',\n severity: 'moderate',\n category: 'storage',\n description: 'localStorage is accessible to XSS attacks',\n cwe: 'CWE-922',\n fix: 'Avoid storing sensitive data in localStorage',\n },\n },\n {\n pattern: 'sessionStorage.setItem',\n metadata: {\n type: 'vulnerability',\n severity: 'moderate',\n category: 'storage',\n description: 'sessionStorage is accessible to XSS attacks',\n cwe: 'CWE-922',\n fix: 'Avoid storing sensitive data in sessionStorage',\n },\n },\n];\n\n/**\n * Build the vulnerability signature trie\n * Called once at startup, then O(1) access\n */\nlet vulnerabilityTrie: AhoCorasick<PatternMetadata> | null = null;\n\nexport function getVulnerabilityTrie(): AhoCorasick<PatternMetadata> {\n if (!vulnerabilityTrie) {\n vulnerabilityTrie = new AhoCorasick<PatternMetadata>();\n \n for (const { pattern, metadata } of VULNERABILITY_PATTERNS) {\n vulnerabilityTrie.addPattern(pattern, metadata, metadata);\n }\n \n vulnerabilityTrie.build();\n if (!isInteractiveMode()) {\n console.error(` Loaded ${VULNERABILITY_PATTERNS.length} vulnerability signatures into trie`);\n }\n }\n \n return vulnerabilityTrie;\n}\n\n/**\n * Scan code for vulnerabilities using the trie\n * O(n + z) where n = code length, z = number of matches\n */\nexport function scanForVulnerabilities(code: string, filePath: string): VulnerabilityMatch[] {\n // CRITICAL: Skip files that should never be scanned\n if (shouldAlwaysExcludeFile(filePath)) {\n return [];\n }\n \n const trie = getVulnerabilityTrie();\n const rawMatches = trie.search(code);\n const lines = code.split('\\n');\n \n // Deduplicate and filter false positives\n const matches: VulnerabilityMatch[] = [];\n const seen = new Set<string>();\n \n for (const match of rawMatches) {\n // Create unique key for deduplication\n const key = `${match.line}:${match.pattern}`;\n if (seen.has(key)) continue;\n seen.add(key);\n \n const meta = match.metadata!;\n \n // Check file exclusions\n if (shouldExcludeFile(filePath, meta.category || '')) continue;\n \n // Filter out false positives\n if (isFalsePositive(code, match, filePath, lines)) continue;\n \n const vulnMatch: VulnerabilityMatch = {\n pattern: match.pattern,\n line: match.line,\n column: match.column,\n severity: meta.severity as any,\n category: meta.category || 'unknown',\n description: meta.description || '',\n fix: meta.fix || '',\n };\n if (meta.cwe !== undefined) {\n vulnMatch.cwe = meta.cwe;\n }\n matches.push(vulnMatch);\n }\n \n return matches;\n}\n\n/**\n * Get surrounding lines for context analysis\n */\nfunction getSurroundingLines(lines: string[], lineNum: number, range: number = 3): string[] {\n const start = Math.max(0, lineNum - range - 1);\n const end = Math.min(lines.length, lineNum + range);\n return lines.slice(start, end);\n}\n\n/**\n * Filter out common false positives with enhanced context awareness\n */\nfunction isFalsePositive(_code: string, match: any, filePath: string, lines: string[]): boolean {\n const line = lines[match.line - 1] || '';\n const trimmedLine = line.trim();\n const pattern = match.pattern;\n const category = match.metadata?.category || '';\n \n // ============================================\n // CRITICAL: Skip signature/pattern definition files\n // ============================================\n if (filePath.includes('signature') || \n filePath.includes('patterns') ||\n filePath.includes('rules')) {\n // If the line contains 'pattern:' or 'pattern =' it's a definition, not a vulnerability\n if (/pattern\\s*[:=]/.test(line)) {\n return true;\n }\n }\n \n // Skip if line is a pattern string definition (in any file)\n // e.g., pattern: \"password = '\", or { pattern: 'secret' }\n if (/^\\s*(pattern|regex|rule|signature)\\s*[:=]/.test(trimmedLine)) {\n return true;\n }\n \n // ============================================\n // CRITICAL: Skip test files entirely for most patterns\n // ============================================\n if (isTestFile(filePath)) {\n // Test files can have intentional bad code for testing detection\n // Only flag REAL secrets (actual API keys that look real)\n if (category === 'secrets') {\n // Skip if it's clearly test/mock data\n if (/test|mock|fake|dummy|example|fixture|sample|placeholder/i.test(line)) {\n return true;\n }\n // Skip generic fake values like \"password123\", \"secret_test\", etc.\n if (/'[a-z_]*password[a-z_0-9]*'|\"[a-z_]*password[a-z_0-9]*\"|'[a-z_]*secret[a-z_0-9]*'|\"[a-z_]*secret[a-z_0-9]*\"/i.test(line)) {\n return true;\n }\n // Skip obviously fake API keys (short or with placeholder patterns)\n if (/sk-[a-z0-9]{10,20}\"|'sk-[a-z0-9]{10,20}'|api[_-]?key.*['\"][a-z0-9_-]{5,30}['\"]/i.test(line)) {\n return true;\n }\n }\n // For non-secrets, skip all test file findings\n return true;\n }\n \n // ============================================\n // SKIP: Comments and documentation\n // ============================================\n if (trimmedLine.startsWith('//') || \n trimmedLine.startsWith('*') || \n trimmedLine.startsWith('/*') ||\n trimmedLine.startsWith('#') ||\n trimmedLine.startsWith('<!--')) {\n return true;\n }\n \n // Skip JSDoc and documentation blocks\n if (/^\\s*\\*\\s/.test(line) || /@(param|returns|example|description|see|link)/i.test(line)) {\n return true;\n }\n \n // Skip description/fix/metadata strings (common in config objects)\n if (/^\\s*(description|fix|message|help|hint|reason|why)\\s*[:=]/.test(trimmedLine)) {\n return true;\n }\n \n // ============================================\n // SKIP: Type definitions and interfaces\n // ============================================\n if (/^\\s*(interface|type|export\\s+interface|export\\s+type)\\s/.test(line)) {\n return true;\n }\n \n // Skip TypeScript type annotations (e.g., password: string)\n if (/:\\s*(string|number|boolean|any|unknown|null|undefined|void)\\s*(;|,|\\)|$)/.test(line)) {\n return true;\n }\n \n // Skip interface/type property definitions\n if (/^\\s*\\w+\\s*\\??\\s*:\\s*(string|number|boolean|any)/.test(trimmedLine)) {\n return true;\n }\n \n // ============================================\n // SKIP: Environment variable reads (not hardcoded)\n // ============================================\n if (/process\\.env|import\\.meta\\.env|getenv|os\\.environ|Deno\\.env|\\.env\\.|config\\.\\w+|settings\\.\\w+/.test(line)) {\n return true;\n }\n \n // ============================================\n // SKIP: Lock files and package metadata\n // ============================================\n if (filePath.endsWith('package-lock.json') || \n filePath.endsWith('yarn.lock') ||\n filePath.endsWith('pnpm-lock.yaml') ||\n filePath.includes('node_modules/')) {\n return true;\n }\n \n // ============================================\n // SKIP: String in object definition (metadata, not code)\n // ============================================\n // Lines like: severity: 'critical', or category: 'secrets'\n if (/^\\s*(severity|category|type|level|priority|cwe|owasp)\\s*:\\s*['\"]/.test(trimmedLine)) {\n return true;\n }\n \n // ============================================\n // Category-specific false positive detection\n // ============================================\n \n // SQL Injection: Only flag in SQL contexts\n if (category === 'sql-injection') {\n const surroundingLines = getSurroundingLines(lines, match.line);\n if (!isInSQLContext(line, surroundingLines)) {\n return true;\n }\n }\n \n // Secrets: Very strict detection to avoid false positives\n if (category === 'secrets' || category === 'auth') {\n // Skip function parameters (function foo(password: string))\n if (/\\(\\s*[^)]*\\w+\\s*:\\s*(string|any)/.test(line)) {\n return true;\n }\n // Skip object destructuring ({ password })\n if (/\\{\\s*\\w*password\\w*\\s*(,|\\}|:)/.test(line) && !/'|\"|`/.test(line.split(/password/i)[1] || '')) {\n return true;\n }\n // Skip when reading from env or config\n if (/=\\s*(process\\.env|config\\.|options\\.|settings\\.|env\\.)/.test(line)) {\n return true;\n }\n // Skip variable declarations without string literals\n if (/password\\s*[=:](?!\\s*['\"`])/.test(line)) {\n return true;\n }\n // Skip if it's reading from another variable\n if (/password\\s*=\\s*\\w+(\\.|$)/.test(line) && !/'|\"|`/.test(line)) {\n return true;\n }\n // Skip error messages and logging about passwords\n if (/error|message|log|warn|info|debug|throw|new Error/i.test(line)) {\n return true;\n }\n // Skip regex patterns for password validation\n if (/regex|RegExp|\\/.*password.*\\//i.test(line)) {\n return true;\n }\n }\n \n // Logging: Skip in development/debug contexts\n if (category === 'logging') {\n // console.error is often intentional\n if (pattern === 'console.error(' || pattern === 'console.warn(') {\n return true;\n }\n // Skip if in catch block (error logging)\n if (/catch|error|err\\b/.test(line)) {\n return true;\n }\n }\n \n // Config patterns: Skip legitimate security config\n if (category === 'config') {\n // Skip when setting secure values\n if (/secure:\\s*true/.test(line) || /httpOnly:\\s*true/.test(line)) {\n return true;\n }\n // Skip environment-based config\n if (/NODE_ENV|process\\.env|production|development/.test(line)) {\n return true;\n }\n // Skip conditional configs\n if (/if\\s*\\(|ternary|\\?.*:/.test(line)) {\n return true;\n }\n }\n \n // Crypto: Skip in contexts where weak crypto is acceptable\n if (category === 'crypto') {\n // MD5/SHA1 for non-security purposes (checksums, cache keys)\n if (/checksum|hash.*file|etag|cache.*key|fingerprint|integrity|content.*hash/i.test(line)) {\n return true;\n }\n // Math.random for non-crypto purposes (UI, games, etc.)\n if (pattern === 'Math.random()') {\n // Only flag if in security context\n if (!/token|secret|password|key|auth|session|csrf|nonce/i.test(line)) {\n return true;\n }\n }\n }\n \n // Async: forEach async is sometimes intentional\n if (category === 'async') {\n // Skip if there's a comment indicating it's intentional\n if (/\\/\\/.*intentional|\\/\\/.*fire.?and.?forget|\\/\\/.*parallel/i.test(line)) {\n return true;\n }\n }\n \n // ============================================\n // SKIP: Validation/check patterns (not vulnerabilities)\n // ============================================\n // Skip password validation logic\n if (/password.*length|validate.*password|check.*password|verify.*password|is.*valid/i.test(line)) {\n return true;\n }\n \n // Skip comparison against hashed values\n if (/bcrypt|argon|scrypt|pbkdf|compare.*hash|hash.*compare|verify.*hash/i.test(line)) {\n return true;\n }\n \n // Skip schema definitions (Zod, Yup, etc.)\n if (/z\\.|yup\\.|joi\\.|schema|validation|validator/i.test(line)) {\n return true;\n }\n \n // ============================================\n // SKIP: Imports and requires\n // ============================================\n if (/^\\s*(import|require|from)\\s/.test(trimmedLine)) {\n return true;\n }\n \n // ============================================\n // SKIP: Example/Demo files\n // ============================================\n if (/example|demo|sample|tutorial|readme/i.test(filePath)) {\n return true;\n }\n \n return false;\n}\n\n/**\n * Check if file is a test file\n */\nfunction isTestFile(filePath: string): boolean {\n return /\\.(test|spec)\\.[jt]sx?$/.test(filePath) ||\n /__tests__\\//.test(filePath) ||\n /test\\//.test(filePath) ||\n /tests\\//.test(filePath) ||\n /\\.stories\\.[jt]sx?$/.test(filePath);\n}\n\n/**\n * Get vulnerability statistics\n */\nexport function getVulnerabilityStats(): { total: number; byCategory: Record<string, number>; bySeverity: Record<string, number> } {\n const byCategory: Record<string, number> = {};\n const bySeverity: Record<string, number> = {};\n \n for (const { metadata } of VULNERABILITY_PATTERNS) {\n const cat = metadata.category || 'unknown';\n const sev = metadata.severity || 'unknown';\n byCategory[cat] = (byCategory[cat] || 0) + 1;\n bySeverity[sev] = (bySeverity[sev] || 0) + 1;\n }\n \n return {\n total: VULNERABILITY_PATTERNS.length,\n byCategory,\n bySeverity,\n };\n}\n\n"],"mappings":"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","names":[]}
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  getGuardianState
3
- } from "./chunk-4YSLDGBL.js";
3
+ } from "./chunk-O7WFJC2P.js";
4
4
  import {
5
5
  BackupManager,
6
6
  atomicWriteJSON,
7
7
  getMemoryStats,
8
8
  safeParseAndValidate,
9
9
  searchIssues
10
- } from "./chunk-TSHZQKCM.js";
10
+ } from "./chunk-2KLYR5GW.js";
11
11
 
12
12
  // src/guardian/insight-store.ts
13
13
  import { mkdir, readFile } from "fs/promises";
@@ -19,7 +19,16 @@ var InsightDetailsSchema = z.object({
19
19
  issueBreakdown: z.record(z.string(), z.number()).optional(),
20
20
  examples: z.array(z.string()).optional(),
21
21
  trend: z.enum(["improving", "stable", "worsening"]).optional(),
22
- comparison: z.string().optional()
22
+ comparison: z.string().optional(),
23
+ resolvedCount: z.number().optional(),
24
+ resolvedIssues: z.array(z.object({
25
+ file: z.string(),
26
+ line: z.number().optional(),
27
+ issue: z.string(),
28
+ agent: z.string(),
29
+ resolvedAt: z.string().optional()
30
+ })).optional(),
31
+ summary: z.string().optional()
23
32
  });
24
33
  var GuardianInsightSchema = z.object({
25
34
  id: z.string(),
@@ -115,10 +124,10 @@ var InsightStore = class _InsightStore {
115
124
  this.deduplicateInsights();
116
125
  return this.data;
117
126
  }
118
- console.error(` \u26A0\uFE0F Insight store corrupted: ${result.error}`);
127
+ console.error(` Insight store corrupted: ${result.error}`);
119
128
  const backupManager = new BackupManager(storePath);
120
129
  if (await backupManager.recoverFromBackup()) {
121
- console.error(" \u2705 Recovered from backup");
130
+ console.error(" Recovered from backup");
122
131
  const recovered = await readFile(storePath, "utf-8");
123
132
  const recoveredResult = safeParseAndValidate(recovered, InsightStoreDataSchema);
124
133
  if (recoveredResult.success) {
@@ -128,10 +137,10 @@ var InsightStore = class _InsightStore {
128
137
  return this.data;
129
138
  }
130
139
  }
131
- console.error(" \u274C No valid backup found, starting fresh");
140
+ console.error(" No valid backup found, starting fresh");
132
141
  }
133
142
  } catch (error) {
134
- console.error(` \u26A0\uFE0F Could not load insight store: ${error}`);
143
+ console.error(` Could not load insight store: ${error}`);
135
144
  }
136
145
  this.data = this.createEmptyData();
137
146
  this.loaded = true;
@@ -644,7 +653,7 @@ var GoalManager = class {
644
653
  const insight = {
645
654
  id: `insight-goal-${goal.id}`,
646
655
  type: "suggestion",
647
- message: `\u{1F3AF} New goal suggested: ${goal.description}`,
656
+ message: `New goal suggested: ${goal.description}`,
648
657
  context: opportunity.reasoning,
649
658
  suggestedAction: "Review and accept/reject this goal",
650
659
  relatedIssues: [],
@@ -783,19 +792,137 @@ var GoalManager = class {
783
792
  * Create a celebration insight for goal achievement
784
793
  */
785
794
  async celebrateGoalAchievement(goal) {
795
+ const resolvedDetails = await this.getResolvedIssuesForGoal(goal);
796
+ if (goal.startValue === void 0 || goal.startValue === null) {
797
+ throw new Error(`Goal ${goal.id} missing startValue`);
798
+ }
799
+ if (goal.currentValue === void 0 || goal.currentValue === null) {
800
+ throw new Error(`Goal ${goal.id} missing currentValue`);
801
+ }
802
+ if (goal.target === void 0 || goal.target === null) {
803
+ throw new Error(`Goal ${goal.id} missing target`);
804
+ }
805
+ for (let i = 0; i < resolvedDetails.length; i++) {
806
+ const issue = resolvedDetails[i];
807
+ if (!issue) {
808
+ throw new Error(`Resolved issue at index ${i} is null/undefined`);
809
+ }
810
+ if (!issue.file) {
811
+ throw new Error(`Resolved issue at index ${i} missing file field`);
812
+ }
813
+ if (!issue.issue) {
814
+ throw new Error(`Resolved issue at index ${i} missing issue description`);
815
+ }
816
+ if (!issue.agent) {
817
+ throw new Error(`Resolved issue at index ${i} missing agent field`);
818
+ }
819
+ }
786
820
  const insight = {
787
821
  id: `insight-achieved-${goal.id}`,
788
822
  type: "celebration",
789
- message: `\u{1F389} Goal achieved: ${goal.description}!`,
823
+ message: `Goal achieved: ${goal.description}!`,
790
824
  context: `Started at ${goal.startValue}, now at ${goal.currentValue}. Target was ${goal.target}.`,
791
825
  relatedIssues: [],
792
826
  priority: 8,
793
827
  timestamp: Date.now(),
794
828
  dismissed: false,
795
- category: "progress"
829
+ category: "progress",
830
+ details: {
831
+ resolvedCount: resolvedDetails.length,
832
+ resolvedIssues: resolvedDetails.slice(0, 20).map((issue) => ({
833
+ file: issue.file,
834
+ line: issue.line,
835
+ issue: issue.issue,
836
+ agent: issue.agent,
837
+ resolvedAt: issue.resolvedAt
838
+ })),
839
+ summary: resolvedDetails.length > 0 ? `Resolved ${resolvedDetails.length} issue${resolvedDetails.length > 1 ? "s" : ""} matching this goal` : "Progress tracked via metric reduction"
840
+ }
796
841
  };
842
+ if (!insight.details) {
843
+ throw new Error("Failed to create details object for goal achievement insight");
844
+ }
845
+ if (insight.details.resolvedCount === void 0) {
846
+ throw new Error("resolvedCount is undefined in goal achievement insight");
847
+ }
848
+ if (insight.details.resolvedCount > 0 && (!insight.details.resolvedIssues || insight.details.resolvedIssues.length === 0)) {
849
+ throw new Error(`resolvedCount is ${insight.details.resolvedCount} but resolvedIssues array is empty`);
850
+ }
851
+ if (insight.details.resolvedCount !== insight.details.resolvedIssues?.length) {
852
+ throw new Error(`resolvedCount (${insight.details.resolvedCount}) doesn't match resolvedIssues length (${insight.details.resolvedIssues?.length})`);
853
+ }
797
854
  await this.insightStore.addInsight(insight);
798
855
  }
856
+ /**
857
+ * Get resolved issues that match a goal's metric pattern
858
+ */
859
+ async getResolvedIssuesForGoal(goal) {
860
+ try {
861
+ const allResolved = await searchIssues("", {
862
+ workDir: this.projectPath,
863
+ limit: 1e3,
864
+ includeResolved: true
865
+ });
866
+ const resolved = allResolved.map((r) => r.issue).filter((issue) => issue.resolved === true);
867
+ const desc = goal.description.toLowerCase();
868
+ const metric = goal.metric.toLowerCase();
869
+ let matchingResolved = resolved;
870
+ if (metric.endsWith("_issues")) {
871
+ const prefix = metric.replace("_issues", "");
872
+ if (prefix.includes("/")) {
873
+ matchingResolved = resolved.filter((i) => i.file.startsWith(prefix));
874
+ } else {
875
+ matchingResolved = resolved.filter((i) => i.agent === prefix);
876
+ }
877
+ } else if (metric === "critical_issues") {
878
+ matchingResolved = resolved.filter((i) => i.severity === "critical");
879
+ } else {
880
+ if (desc.includes("dead code") || desc.includes("unused") || desc.includes("remove unused")) {
881
+ matchingResolved = resolved.filter((i) => {
882
+ const msg = i.issue.toLowerCase();
883
+ return msg.includes("unused") || msg.includes("dead code") || msg.includes("never used") || msg.includes("unreachable") || msg.includes("no-unused") || msg.includes("defined but never");
884
+ });
885
+ } else if (desc.includes("security") || desc.includes("vulnerab") || desc.includes("fix security")) {
886
+ matchingResolved = resolved.filter(
887
+ (i) => i.agent === "security" || i.agent === "privacy" || i.severity === "critical"
888
+ );
889
+ } else if (desc.includes("type") || desc.includes("typescript") || desc.includes("any type")) {
890
+ matchingResolved = resolved.filter(
891
+ (i) => i.agent === "typecheck" || i.issue.toLowerCase().includes("type") || i.issue.toLowerCase().includes("any")
892
+ );
893
+ } else if (desc.includes("test") || desc.includes("coverage")) {
894
+ matchingResolved = resolved.filter(
895
+ (i) => i.agent === "test" || i.issue.toLowerCase().includes("test") || i.issue.toLowerCase().includes("coverage")
896
+ );
897
+ } else if (desc.includes("performance") || desc.includes("slow") || desc.includes("optimize")) {
898
+ matchingResolved = resolved.filter(
899
+ (i) => i.agent === "performance" || i.issue.toLowerCase().includes("performance") || i.issue.toLowerCase().includes("slow")
900
+ );
901
+ } else if (desc.includes("accessibility") || desc.includes("a11y") || desc.includes("accessible")) {
902
+ matchingResolved = resolved.filter(
903
+ (i) => i.agent === "accessibility" || i.issue.toLowerCase().includes("accessibility")
904
+ );
905
+ } else if (desc.includes("bug") || desc.includes("fix") || desc.includes("error")) {
906
+ matchingResolved = resolved.filter(
907
+ (i) => i.agent === "bug-finding" || i.severity === "critical" || i.severity === "serious"
908
+ );
909
+ }
910
+ }
911
+ const goalCreatedAt = new Date(goal.createdAt).getTime();
912
+ const goalAchievedAt = goal.achievedAt ? new Date(goal.achievedAt).getTime() : Date.now();
913
+ return matchingResolved.filter((issue) => {
914
+ if (!issue.resolvedAt) return false;
915
+ const resolvedAt = new Date(issue.resolvedAt).getTime();
916
+ return resolvedAt >= goalCreatedAt && resolvedAt <= goalAchievedAt;
917
+ }).sort((a, b) => {
918
+ const aTime = a.resolvedAt ? new Date(a.resolvedAt).getTime() : 0;
919
+ const bTime = b.resolvedAt ? new Date(b.resolvedAt).getTime() : 0;
920
+ return bTime - aTime;
921
+ });
922
+ } catch {
923
+ return [];
924
+ }
925
+ }
799
926
  /**
800
927
  * Accept an auto-generated goal
801
928
  */
@@ -901,4 +1028,4 @@ export {
901
1028
  getGoalManager,
902
1029
  clearGoalManagers
903
1030
  };
904
- //# sourceMappingURL=chunk-D3DMONAJ.js.map
1031
+ //# sourceMappingURL=chunk-HWJJIAR7.js.map