@triedotdev/mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/QUICK_START.md +230 -0
- package/README.md +235 -0
- package/dist/chunk-3CS6Z2SL.js +927 -0
- package/dist/chunk-3CS6Z2SL.js.map +1 -0
- package/dist/chunk-6NLHFIYA.js +344 -0
- package/dist/chunk-6NLHFIYA.js.map +1 -0
- package/dist/chunk-DGUM43GV.js +11 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/chunk-E7CKHS3R.js +7615 -0
- package/dist/chunk-E7CKHS3R.js.map +1 -0
- package/dist/chunk-EYNAGEQK.js +950 -0
- package/dist/chunk-EYNAGEQK.js.map +1 -0
- package/dist/chunk-MR755QGT.js +927 -0
- package/dist/chunk-MR755QGT.js.map +1 -0
- package/dist/cli/create-agent.d.ts +1 -0
- package/dist/cli/create-agent.js +156 -0
- package/dist/cli/create-agent.js.map +1 -0
- package/dist/cli/main.d.ts +1 -0
- package/dist/cli/main.js +280 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/yolo-daemon.d.ts +1 -0
- package/dist/cli/yolo-daemon.js +326 -0
- package/dist/cli/yolo-daemon.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3882 -0
- package/dist/index.js.map +1 -0
- package/dist/vibe-code-signatures-4CBHUSI7.js +15 -0
- package/dist/vibe-code-signatures-4CBHUSI7.js.map +1 -0
- package/dist/vulnerability-signatures-J3CUQ7VR.js +17 -0
- package/dist/vulnerability-signatures-J3CUQ7VR.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +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';\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 console.error(` š§ Loaded ${VULNERABILITY_PATTERNS.length} vulnerability signatures into trie`);\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":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
buildAgentFromDocument
|
|
4
|
+
} from "../chunk-EYNAGEQK.js";
|
|
5
|
+
import "../chunk-DGUM43GV.js";
|
|
6
|
+
|
|
7
|
+
// src/cli/create-agent.ts
|
|
8
|
+
import { existsSync } from "fs";
|
|
9
|
+
import { resolve, basename, extname } from "path";
|
|
10
|
+
function parseArgs() {
|
|
11
|
+
const args = process.argv.slice(2);
|
|
12
|
+
if (args.length === 0 || args.includes("--help") || args.includes("-h")) {
|
|
13
|
+
showHelp();
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
let filePath = args[0];
|
|
17
|
+
if (!filePath) {
|
|
18
|
+
console.error("\u274C Error: Please provide a file path");
|
|
19
|
+
showHelp();
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
filePath = filePath.replace(/^['"]|['"]$/g, "").trim();
|
|
23
|
+
filePath = resolve(filePath);
|
|
24
|
+
let agentName = args[1];
|
|
25
|
+
if (!agentName || agentName.startsWith("--")) {
|
|
26
|
+
const filename = basename(filePath, extname(filePath));
|
|
27
|
+
agentName = filename.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
28
|
+
console.log(`\u{1F4DD} Auto-generated agent name: ${agentName}`);
|
|
29
|
+
}
|
|
30
|
+
const options = {
|
|
31
|
+
filePath,
|
|
32
|
+
agentName
|
|
33
|
+
};
|
|
34
|
+
for (let i = 2; i < args.length; i++) {
|
|
35
|
+
const arg = args[i];
|
|
36
|
+
const nextArg = args[i + 1];
|
|
37
|
+
switch (arg) {
|
|
38
|
+
case "--display-name":
|
|
39
|
+
case "-n":
|
|
40
|
+
if (nextArg) options.displayName = nextArg;
|
|
41
|
+
i++;
|
|
42
|
+
break;
|
|
43
|
+
case "--description":
|
|
44
|
+
case "-d":
|
|
45
|
+
if (nextArg) options.description = nextArg;
|
|
46
|
+
i++;
|
|
47
|
+
break;
|
|
48
|
+
case "--category":
|
|
49
|
+
case "-c":
|
|
50
|
+
if (nextArg) options.category = nextArg;
|
|
51
|
+
i++;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return options;
|
|
56
|
+
}
|
|
57
|
+
function showHelp() {
|
|
58
|
+
console.log(`
|
|
59
|
+
\u{1F4DA} Trie Agent Creator
|
|
60
|
+
Create custom code review agents from documents.
|
|
61
|
+
|
|
62
|
+
Usage:
|
|
63
|
+
trie-create <file-path> [agent-name] [options]
|
|
64
|
+
|
|
65
|
+
Arguments:
|
|
66
|
+
file-path Path to PDF, TXT, MD, or RTF file (drag & drop supported!)
|
|
67
|
+
agent-name Name for the agent (optional - auto-generated from filename)
|
|
68
|
+
|
|
69
|
+
Options:
|
|
70
|
+
--display-name, -n Friendly display name for the agent
|
|
71
|
+
--description, -d Description of what the agent does
|
|
72
|
+
--category, -c Category (react, security, compliance, architecture, etc.)
|
|
73
|
+
--help, -h Show this help message
|
|
74
|
+
|
|
75
|
+
Examples:
|
|
76
|
+
# Basic usage
|
|
77
|
+
trie-create ./react-book.pdf react-fundamentals
|
|
78
|
+
|
|
79
|
+
# With options
|
|
80
|
+
trie-create ./gdpr-guide.pdf gdpr-compliance --category legal
|
|
81
|
+
|
|
82
|
+
# Auto-generate name from filename
|
|
83
|
+
trie-create ./clean-code.pdf
|
|
84
|
+
|
|
85
|
+
# Drag & drop a file to terminal, then add name
|
|
86
|
+
trie-create /Users/you/Downloads/my-book.pdf my-agent
|
|
87
|
+
|
|
88
|
+
Supported File Types:
|
|
89
|
+
\u2022 PDF (.pdf) - Requires pdf-parse: npm install pdf-parse
|
|
90
|
+
\u2022 Text (.txt) - Plain text files
|
|
91
|
+
\u2022 Markdown (.md, .markdown)
|
|
92
|
+
\u2022 RTF (.rtf) - Rich Text Format
|
|
93
|
+
|
|
94
|
+
After Creation:
|
|
95
|
+
The agent is saved to .trie/agents/<name>.json and will automatically
|
|
96
|
+
activate during scans when it detects relevant code patterns.
|
|
97
|
+
`);
|
|
98
|
+
}
|
|
99
|
+
async function main() {
|
|
100
|
+
console.log("\n\u{1F52E} Trie Agent Creator\n");
|
|
101
|
+
const options = parseArgs();
|
|
102
|
+
if (!options) {
|
|
103
|
+
process.exit(0);
|
|
104
|
+
}
|
|
105
|
+
if (!existsSync(options.filePath)) {
|
|
106
|
+
console.error(`\u274C File not found: ${options.filePath}`);
|
|
107
|
+
console.error("\n\u{1F4A1} Tip: Drag & drop the file directly into the terminal!");
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
const ext = extname(options.filePath).toLowerCase();
|
|
111
|
+
const supportedTypes = [".pdf", ".txt", ".md", ".markdown", ".rtf"];
|
|
112
|
+
if (!supportedTypes.includes(ext)) {
|
|
113
|
+
console.error(`\u274C Unsupported file type: ${ext}`);
|
|
114
|
+
console.error(` Supported types: ${supportedTypes.join(", ")}`);
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
console.log(`\u{1F4C4} File: ${options.filePath}`);
|
|
118
|
+
console.log(`\u{1F3F7}\uFE0F Agent: ${options.agentName}`);
|
|
119
|
+
if (options.category) console.log(`\u{1F4C1} Category: ${options.category}`);
|
|
120
|
+
console.log("");
|
|
121
|
+
try {
|
|
122
|
+
const createOptions = {
|
|
123
|
+
filePath: options.filePath,
|
|
124
|
+
agentName: options.agentName
|
|
125
|
+
};
|
|
126
|
+
if (options.displayName) createOptions.displayName = options.displayName;
|
|
127
|
+
if (options.description) createOptions.description = options.description;
|
|
128
|
+
if (options.category) createOptions.category = options.category;
|
|
129
|
+
const result = await buildAgentFromDocument(createOptions, true);
|
|
130
|
+
if (result.success) {
|
|
131
|
+
console.log("\n" + "\u2501".repeat(50));
|
|
132
|
+
console.log("\u2705 Agent created successfully!");
|
|
133
|
+
console.log("\u2501".repeat(50));
|
|
134
|
+
console.log(`
|
|
135
|
+
\u{1F4CD} Config saved to: ${result.configPath}`);
|
|
136
|
+
console.log(`
|
|
137
|
+
\u{1F4CA} Stats:`);
|
|
138
|
+
console.log(` \u2022 Document words: ${result.stats.documentWords.toLocaleString()}`);
|
|
139
|
+
console.log(` \u2022 Concepts extracted: ${result.stats.conceptsExtracted}`);
|
|
140
|
+
console.log(` \u2022 Detection patterns: ${result.stats.patternsGenerated}`);
|
|
141
|
+
console.log(` \u2022 Compression ratio: ${result.stats.compressionRatio}:1`);
|
|
142
|
+
console.log("\n\u{1F680} The agent will now activate during code scans!");
|
|
143
|
+
console.log(" Run: trie_scan to test it\n");
|
|
144
|
+
} else {
|
|
145
|
+
console.error(`
|
|
146
|
+
\u274C Failed: ${result.error}`);
|
|
147
|
+
process.exit(1);
|
|
148
|
+
}
|
|
149
|
+
} catch (error) {
|
|
150
|
+
console.error(`
|
|
151
|
+
\u274C Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
main();
|
|
156
|
+
//# sourceMappingURL=create-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/create-agent.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Trie Agent Creator CLI\n * \n * Create custom agents from PDF, TXT, MD, or RTF documents.\n * \n * Usage:\n * trie-create <file-path> <agent-name> [options]\n * \n * Examples:\n * trie-create ./react-book.pdf react-fundamentals\n * trie-create ~/Documents/gdpr-guide.pdf gdpr-compliance --category legal\n * \n * Drag & Drop:\n * Just drag a file to terminal and add the agent name:\n * trie-create /path/to/dropped/file.pdf my-agent\n */\n\nimport { buildAgentFromDocument } from '../ingest/agent-builder.js';\nimport { existsSync } from 'fs';\nimport { resolve, basename, extname } from 'path';\n\ninterface CLIOptions {\n filePath: string;\n agentName: string;\n displayName?: string;\n description?: string;\n category?: string;\n}\n\nfunction parseArgs(): CLIOptions | null {\n const args = process.argv.slice(2);\n \n // Show help\n if (args.length === 0 || args.includes('--help') || args.includes('-h')) {\n showHelp();\n return null;\n }\n \n // First arg is file path (handles drag & drop)\n let filePath = args[0];\n if (!filePath) {\n console.error('ā Error: Please provide a file path');\n showHelp();\n return null;\n }\n \n // Clean up path (remove quotes that might be added by drag & drop)\n filePath = filePath.replace(/^['\"]|['\"]$/g, '').trim();\n filePath = resolve(filePath);\n \n // Second arg is agent name (optional - will auto-generate if not provided)\n let agentName = args[1];\n if (!agentName || agentName.startsWith('--')) {\n // Auto-generate from filename\n const filename = basename(filePath, extname(filePath));\n agentName = filename\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '');\n console.log(`š Auto-generated agent name: ${agentName}`);\n }\n \n // Parse options\n const options: CLIOptions = {\n filePath,\n agentName,\n };\n \n for (let i = 2; i < args.length; i++) {\n const arg = args[i];\n const nextArg = args[i + 1];\n \n switch (arg) {\n case '--display-name':\n case '-n':\n if (nextArg) options.displayName = nextArg;\n i++;\n break;\n case '--description':\n case '-d':\n if (nextArg) options.description = nextArg;\n i++;\n break;\n case '--category':\n case '-c':\n if (nextArg) options.category = nextArg;\n i++;\n break;\n }\n }\n \n return options;\n}\n\nfunction showHelp(): void {\n console.log(`\nš Trie Agent Creator\nCreate custom code review agents from documents.\n\nUsage:\n trie-create <file-path> [agent-name] [options]\n\nArguments:\n file-path Path to PDF, TXT, MD, or RTF file (drag & drop supported!)\n agent-name Name for the agent (optional - auto-generated from filename)\n\nOptions:\n --display-name, -n Friendly display name for the agent\n --description, -d Description of what the agent does\n --category, -c Category (react, security, compliance, architecture, etc.)\n --help, -h Show this help message\n\nExamples:\n # Basic usage\n trie-create ./react-book.pdf react-fundamentals\n\n # With options\n trie-create ./gdpr-guide.pdf gdpr-compliance --category legal\n\n # Auto-generate name from filename\n trie-create ./clean-code.pdf\n\n # Drag & drop a file to terminal, then add name\n trie-create /Users/you/Downloads/my-book.pdf my-agent\n\nSupported File Types:\n ⢠PDF (.pdf) - Requires pdf-parse: npm install pdf-parse\n ⢠Text (.txt) - Plain text files\n ⢠Markdown (.md, .markdown)\n ⢠RTF (.rtf) - Rich Text Format\n\nAfter Creation:\n The agent is saved to .trie/agents/<name>.json and will automatically\n activate during scans when it detects relevant code patterns.\n`);\n}\n\nasync function main(): Promise<void> {\n console.log('\\nš® Trie Agent Creator\\n');\n \n const options = parseArgs();\n if (!options) {\n process.exit(0);\n }\n \n // Validate file exists\n if (!existsSync(options.filePath)) {\n console.error(`ā File not found: ${options.filePath}`);\n console.error('\\nš” Tip: Drag & drop the file directly into the terminal!');\n process.exit(1);\n }\n \n // Validate file type\n const ext = extname(options.filePath).toLowerCase();\n const supportedTypes = ['.pdf', '.txt', '.md', '.markdown', '.rtf'];\n if (!supportedTypes.includes(ext)) {\n console.error(`ā Unsupported file type: ${ext}`);\n console.error(` Supported types: ${supportedTypes.join(', ')}`);\n process.exit(1);\n }\n \n console.log(`š File: ${options.filePath}`);\n console.log(`š·ļø Agent: ${options.agentName}`);\n if (options.category) console.log(`š Category: ${options.category}`);\n console.log('');\n \n try {\n const createOptions: Parameters<typeof buildAgentFromDocument>[0] = {\n filePath: options.filePath,\n agentName: options.agentName,\n };\n if (options.displayName) createOptions.displayName = options.displayName;\n if (options.description) createOptions.description = options.description;\n if (options.category) createOptions.category = options.category;\n \n const result = await buildAgentFromDocument(createOptions, true);\n \n if (result.success) {\n console.log('\\n' + 'ā'.repeat(50));\n console.log('ā
Agent created successfully!');\n console.log('ā'.repeat(50));\n console.log(`\\nš Config saved to: ${result.configPath}`);\n console.log(`\\nš Stats:`);\n console.log(` ⢠Document words: ${result.stats.documentWords.toLocaleString()}`);\n console.log(` ⢠Concepts extracted: ${result.stats.conceptsExtracted}`);\n console.log(` ⢠Detection patterns: ${result.stats.patternsGenerated}`);\n console.log(` ⢠Compression ratio: ${result.stats.compressionRatio}:1`);\n console.log('\\nš The agent will now activate during code scans!');\n console.log(' Run: trie_scan to test it\\n');\n } else {\n console.error(`\\nā Failed: ${result.error}`);\n process.exit(1);\n }\n } catch (error) {\n console.error(`\\nā Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n}\n\nmain();\n\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/cli/main.js
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
__require
|
|
4
|
+
} from "../chunk-DGUM43GV.js";
|
|
5
|
+
|
|
6
|
+
// src/cli/main.ts
|
|
7
|
+
import { resolve, join, dirname } from "path";
|
|
8
|
+
import { existsSync, readFileSync } from "fs";
|
|
9
|
+
import { fileURLToPath } from "url";
|
|
10
|
+
var __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
var __dirname = dirname(__filename);
|
|
12
|
+
var VERSION = "1.0.0";
|
|
13
|
+
function showHelp() {
|
|
14
|
+
console.log(`
|
|
15
|
+
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
16
|
+
\u2551 \u2551
|
|
17
|
+
\u2551 \u{1F53A} Trie Agent - Intelligent Code Review for AI-Generated Code \u2551
|
|
18
|
+
\u2551 \u2551
|
|
19
|
+
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
20
|
+
|
|
21
|
+
Version: ${VERSION}
|
|
22
|
+
|
|
23
|
+
USAGE:
|
|
24
|
+
trie-agent <command> [options]
|
|
25
|
+
|
|
26
|
+
COMMANDS:
|
|
27
|
+
help Show this help message
|
|
28
|
+
setup Configure API key and environment
|
|
29
|
+
scan Scan codebase once and exit
|
|
30
|
+
watch Watch for changes and scan continuously
|
|
31
|
+
yolo \u{1F525} YOLO mode: auto-fix issues as they occur
|
|
32
|
+
agents List all available agents
|
|
33
|
+
version Show version information
|
|
34
|
+
|
|
35
|
+
EXAMPLES:
|
|
36
|
+
# First time setup
|
|
37
|
+
trie-agent setup
|
|
38
|
+
|
|
39
|
+
# Scan your project once
|
|
40
|
+
trie-agent scan
|
|
41
|
+
|
|
42
|
+
# Watch mode (scan on file changes)
|
|
43
|
+
trie-agent watch
|
|
44
|
+
|
|
45
|
+
# YOLO mode (auto-fix issues)
|
|
46
|
+
trie-agent yolo
|
|
47
|
+
|
|
48
|
+
# Scan specific directory
|
|
49
|
+
trie-agent scan --dir ./src
|
|
50
|
+
|
|
51
|
+
MCP TOOLS (use via Cursor/Claude Desktop):
|
|
52
|
+
trie_scan Intelligent scan with agent selection
|
|
53
|
+
trie_fix Apply high-confidence fixes
|
|
54
|
+
trie_explain Explain code, issues, or changes
|
|
55
|
+
trie_watch Watch mode with optional YOLO
|
|
56
|
+
|
|
57
|
+
Individual Agents:
|
|
58
|
+
trie_security Security vulnerabilities
|
|
59
|
+
trie_privacy Privacy & GDPR compliance
|
|
60
|
+
trie_legal Legal compliance
|
|
61
|
+
trie_accessibility WCAG 2.1 accessibility
|
|
62
|
+
trie_architecture Code organization & SOLID
|
|
63
|
+
trie_bugs Bug finding & null safety
|
|
64
|
+
trie_ux UX testing (happy path, edge cases)
|
|
65
|
+
trie_types TypeScript type safety
|
|
66
|
+
trie_devops DevOps & deployment
|
|
67
|
+
trie_clean Clean up AI-generated code
|
|
68
|
+
|
|
69
|
+
Custom Agents:
|
|
70
|
+
trie_create_agent Create agent from PDF/TXT/MD document
|
|
71
|
+
trie_list_agents List all registered agents
|
|
72
|
+
|
|
73
|
+
NOTE: No API key required! Trie uses your AI tool's built-in Claude.
|
|
74
|
+
|
|
75
|
+
For more info: https://github.com/Trie-OS/Trie-Agent
|
|
76
|
+
`);
|
|
77
|
+
}
|
|
78
|
+
function showSetup() {
|
|
79
|
+
console.log(`
|
|
80
|
+
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
81
|
+
\u2551 \u{1F527} Trie Agent Setup \u2551
|
|
82
|
+
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
83
|
+
|
|
84
|
+
No API key required! Trie uses your AI tool's built-in Claude.
|
|
85
|
+
|
|
86
|
+
STEP 1: Configure for your AI tool
|
|
87
|
+
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
88
|
+
|
|
89
|
+
For CLAUDE CODE:
|
|
90
|
+
claude mcp add trie-agent -- node /path/to/@triedotdev/mcp/dist/index.js
|
|
91
|
+
|
|
92
|
+
Or add to ~/.claude/settings.json:
|
|
93
|
+
{
|
|
94
|
+
"mcpServers": {
|
|
95
|
+
"trie-agent": {
|
|
96
|
+
"command": "node",
|
|
97
|
+
"args": ["/path/to/@triedotdev/mcp/dist/index.js"]
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
For CURSOR (~/.cursor/mcp.json):
|
|
103
|
+
{
|
|
104
|
+
"mcpServers": {
|
|
105
|
+
"trie-agent": {
|
|
106
|
+
"command": "node",
|
|
107
|
+
"args": ["/path/to/@triedotdev/mcp/dist/index.js"]
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
STEP 2: Restart your AI tool
|
|
113
|
+
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
114
|
+
Restart Claude Code or Cursor to load the MCP configuration.
|
|
115
|
+
|
|
116
|
+
STEP 3: Start scanning!
|
|
117
|
+
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
118
|
+
Ask your AI assistant: "Scan this with Trie" or "Use trie_scan"
|
|
119
|
+
|
|
120
|
+
Need help? https://github.com/Trie-OS/Trie-Agent/issues
|
|
121
|
+
`);
|
|
122
|
+
}
|
|
123
|
+
function listAgents() {
|
|
124
|
+
console.log(`
|
|
125
|
+
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
126
|
+
\u2551 \u{1F4CB} Available Agents \u2551
|
|
127
|
+
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
128
|
+
|
|
129
|
+
BUILT-IN AGENTS:
|
|
130
|
+
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
131
|
+
security Security vulnerabilities, injection risks, auth issues
|
|
132
|
+
privacy GDPR, HIPAA, PII handling, data encryption
|
|
133
|
+
legal GDPR, CCPA, consent patterns, data retention
|
|
134
|
+
design-engineer WCAG 2.1 accessibility, UX best practices
|
|
135
|
+
software-architect Code organization, SOLID principles, scalability
|
|
136
|
+
bug-finding Null safety, edge cases, async issues
|
|
137
|
+
user-testing Simulate users: happy path, security tester, confused user
|
|
138
|
+
typecheck Type errors, missing annotations, null checks
|
|
139
|
+
devops Config issues, logging, env vars, deployment
|
|
140
|
+
trie_clean Clean up AI-generated code patterns
|
|
141
|
+
|
|
142
|
+
CUSTOM AGENTS:
|
|
143
|
+
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`);
|
|
144
|
+
const agentsDir = join(process.cwd(), ".trie", "agents");
|
|
145
|
+
if (existsSync(agentsDir)) {
|
|
146
|
+
try {
|
|
147
|
+
const { readdirSync } = __require("fs");
|
|
148
|
+
const files = readdirSync(agentsDir).filter((f) => f.endsWith(".json"));
|
|
149
|
+
if (files.length > 0) {
|
|
150
|
+
for (const file of files) {
|
|
151
|
+
const config = JSON.parse(readFileSync(join(agentsDir, file), "utf-8"));
|
|
152
|
+
console.log(` ${config.name.padEnd(18)} ${config.description || "Custom agent"}`);
|
|
153
|
+
}
|
|
154
|
+
} else {
|
|
155
|
+
console.log(` (No custom agents found)`);
|
|
156
|
+
}
|
|
157
|
+
} catch {
|
|
158
|
+
console.log(` (No custom agents found)`);
|
|
159
|
+
}
|
|
160
|
+
} else {
|
|
161
|
+
console.log(` (No custom agents found)`);
|
|
162
|
+
}
|
|
163
|
+
console.log(`
|
|
164
|
+
CREATE CUSTOM AGENTS:
|
|
165
|
+
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
166
|
+
You can create agents from PDF, TXT, or MD documents:
|
|
167
|
+
|
|
168
|
+
Via MCP: Use trie_create_agent tool
|
|
169
|
+
CLI: trie-create --file book.pdf --name my-agent
|
|
170
|
+
|
|
171
|
+
The agent will learn patterns from your document and apply them
|
|
172
|
+
to code reviews. Great for style guides, compliance docs, etc.
|
|
173
|
+
`);
|
|
174
|
+
}
|
|
175
|
+
function showVersion() {
|
|
176
|
+
console.log(`trie-agent v${VERSION}`);
|
|
177
|
+
}
|
|
178
|
+
async function runScan(args) {
|
|
179
|
+
const { spawn } = await import("child_process");
|
|
180
|
+
let daemonPath;
|
|
181
|
+
if (__filename.endsWith(".ts")) {
|
|
182
|
+
daemonPath = resolve(__dirname, "yolo-daemon.ts");
|
|
183
|
+
} else {
|
|
184
|
+
daemonPath = resolve(__dirname, "yolo-daemon.js");
|
|
185
|
+
}
|
|
186
|
+
const daemonArgs = ["--once", ...args];
|
|
187
|
+
const executor = daemonPath.endsWith(".ts") ? "npx" : "node";
|
|
188
|
+
const execArgs = daemonPath.endsWith(".ts") ? ["tsx", daemonPath, ...daemonArgs] : [daemonPath, ...daemonArgs];
|
|
189
|
+
const child = spawn(executor, execArgs, {
|
|
190
|
+
stdio: "inherit",
|
|
191
|
+
env: process.env
|
|
192
|
+
});
|
|
193
|
+
child.on("close", (code) => {
|
|
194
|
+
process.exit(code || 0);
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
async function runWatch(args) {
|
|
198
|
+
const { spawn } = await import("child_process");
|
|
199
|
+
let daemonPath;
|
|
200
|
+
if (__filename.endsWith(".ts")) {
|
|
201
|
+
daemonPath = resolve(__dirname, "yolo-daemon.ts");
|
|
202
|
+
} else {
|
|
203
|
+
daemonPath = resolve(__dirname, "yolo-daemon.js");
|
|
204
|
+
}
|
|
205
|
+
const executor = daemonPath.endsWith(".ts") ? "npx" : "node";
|
|
206
|
+
const execArgs = daemonPath.endsWith(".ts") ? ["tsx", daemonPath, ...args] : [daemonPath, ...args];
|
|
207
|
+
const child = spawn(executor, execArgs, {
|
|
208
|
+
stdio: "inherit",
|
|
209
|
+
env: process.env
|
|
210
|
+
});
|
|
211
|
+
child.on("close", (code) => {
|
|
212
|
+
process.exit(code || 0);
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
async function runYolo(args) {
|
|
216
|
+
const { spawn } = await import("child_process");
|
|
217
|
+
const daemonPath = resolve(__dirname, "yolo-daemon.js");
|
|
218
|
+
const daemonArgs = ["--yolo", ...args];
|
|
219
|
+
const child = spawn("node", [daemonPath, ...daemonArgs], {
|
|
220
|
+
stdio: "inherit",
|
|
221
|
+
env: process.env
|
|
222
|
+
});
|
|
223
|
+
child.on("close", (code) => {
|
|
224
|
+
process.exit(code || 0);
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
function main() {
|
|
228
|
+
const args = process.argv.slice(2);
|
|
229
|
+
const command = args[0]?.toLowerCase();
|
|
230
|
+
const restArgs = args.slice(1);
|
|
231
|
+
if (!command || command === "help" || command === "--help" || command === "-h") {
|
|
232
|
+
showHelp();
|
|
233
|
+
process.exit(0);
|
|
234
|
+
}
|
|
235
|
+
switch (command) {
|
|
236
|
+
case "setup":
|
|
237
|
+
case "config":
|
|
238
|
+
case "configure":
|
|
239
|
+
case "init":
|
|
240
|
+
showSetup();
|
|
241
|
+
break;
|
|
242
|
+
case "agents":
|
|
243
|
+
case "list":
|
|
244
|
+
case "list-agents":
|
|
245
|
+
listAgents();
|
|
246
|
+
break;
|
|
247
|
+
case "version":
|
|
248
|
+
case "--version":
|
|
249
|
+
case "-v":
|
|
250
|
+
showVersion();
|
|
251
|
+
break;
|
|
252
|
+
case "scan":
|
|
253
|
+
runScan(restArgs);
|
|
254
|
+
break;
|
|
255
|
+
case "watch":
|
|
256
|
+
runWatch(restArgs);
|
|
257
|
+
break;
|
|
258
|
+
case "yolo":
|
|
259
|
+
runYolo(restArgs);
|
|
260
|
+
break;
|
|
261
|
+
default:
|
|
262
|
+
if (command.startsWith("-")) {
|
|
263
|
+
const { spawn } = __require("child_process");
|
|
264
|
+
const daemonPath = resolve(__dirname, "yolo-daemon.js");
|
|
265
|
+
const child = spawn("node", [daemonPath, ...args], {
|
|
266
|
+
stdio: "inherit",
|
|
267
|
+
env: process.env
|
|
268
|
+
});
|
|
269
|
+
child.on("close", (code) => {
|
|
270
|
+
process.exit(code || 0);
|
|
271
|
+
});
|
|
272
|
+
} else {
|
|
273
|
+
console.error(`Unknown command: ${command}`);
|
|
274
|
+
console.error(`Run 'trie-agent help' for usage information.`);
|
|
275
|
+
process.exit(1);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
main();
|
|
280
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/main.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Trie Agent CLI\n * \n * Main command-line interface for Trie Agent.\n * Provides help, setup, and routes to specific tools.\n * \n * Usage:\n * trie-agent [command] [options]\n */\n\nimport { resolve, join, dirname } from 'path';\nimport { existsSync, readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\n\n// ES module __dirname equivalent\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst VERSION = '1.0.0';\n\n/**\n * Show the main help message\n */\nfunction showHelp(): void {\n console.log(`\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\nā ā\nā šŗ Trie Agent - Intelligent Code Review for AI-Generated Code ā\nā ā\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n\nVersion: ${VERSION}\n\nUSAGE:\n trie-agent <command> [options]\n\nCOMMANDS:\n help Show this help message\n setup Configure API key and environment\n scan Scan codebase once and exit\n watch Watch for changes and scan continuously\n yolo š„ YOLO mode: auto-fix issues as they occur\n agents List all available agents\n version Show version information\n\nEXAMPLES:\n # First time setup\n trie-agent setup\n\n # Scan your project once\n trie-agent scan\n\n # Watch mode (scan on file changes)\n trie-agent watch\n\n # YOLO mode (auto-fix issues)\n trie-agent yolo\n\n # Scan specific directory\n trie-agent scan --dir ./src\n\nMCP TOOLS (use via Cursor/Claude Desktop):\n trie_scan Intelligent scan with agent selection\n trie_fix Apply high-confidence fixes\n trie_explain Explain code, issues, or changes\n trie_watch Watch mode with optional YOLO\n \n Individual Agents:\n trie_security Security vulnerabilities\n trie_privacy Privacy & GDPR compliance\n trie_legal Legal compliance\n trie_accessibility WCAG 2.1 accessibility\n trie_architecture Code organization & SOLID\n trie_bugs Bug finding & null safety\n trie_ux UX testing (happy path, edge cases)\n trie_types TypeScript type safety\n trie_devops DevOps & deployment\n trie_clean Clean up AI-generated code\n\n Custom Agents:\n trie_create_agent Create agent from PDF/TXT/MD document\n trie_list_agents List all registered agents\n\nNOTE: No API key required! Trie uses your AI tool's built-in Claude.\n\nFor more info: https://github.com/Trie-OS/Trie-Agent\n`);\n}\n\n/**\n * Show setup instructions\n */\nfunction showSetup(): void {\n console.log(`\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\nā š§ Trie Agent Setup ā\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n\nNo API key required! Trie uses your AI tool's built-in Claude.\n\nSTEP 1: Configure for your AI tool\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n\nFor CLAUDE CODE:\n claude mcp add trie-agent -- node /path/to/@triedotdev/mcp/dist/index.js\n\n Or add to ~/.claude/settings.json:\n {\n \"mcpServers\": {\n \"trie-agent\": {\n \"command\": \"node\",\n \"args\": [\"/path/to/@triedotdev/mcp/dist/index.js\"]\n }\n }\n }\n\nFor CURSOR (~/.cursor/mcp.json):\n{\n \"mcpServers\": {\n \"trie-agent\": {\n \"command\": \"node\",\n \"args\": [\"/path/to/@triedotdev/mcp/dist/index.js\"]\n }\n }\n}\n\nSTEP 2: Restart your AI tool\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\nRestart Claude Code or Cursor to load the MCP configuration.\n\nSTEP 3: Start scanning!\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\nAsk your AI assistant: \"Scan this with Trie\" or \"Use trie_scan\"\n\nNeed help? https://github.com/Trie-OS/Trie-Agent/issues\n`);\n}\n\n/**\n * List available agents\n */\nfunction listAgents(): void {\n console.log(`\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\nā š Available Agents ā\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n\nBUILT-IN AGENTS:\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n security Security vulnerabilities, injection risks, auth issues\n privacy GDPR, HIPAA, PII handling, data encryption\n legal GDPR, CCPA, consent patterns, data retention\n design-engineer WCAG 2.1 accessibility, UX best practices\n software-architect Code organization, SOLID principles, scalability\n bug-finding Null safety, edge cases, async issues\n user-testing Simulate users: happy path, security tester, confused user\n typecheck Type errors, missing annotations, null checks\n devops Config issues, logging, env vars, deployment\n trie_clean Clean up AI-generated code patterns\n\nCUSTOM AGENTS:\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā`);\n\n // Check for custom agents\n const agentsDir = join(process.cwd(), '.trie', 'agents');\n if (existsSync(agentsDir)) {\n try {\n const { readdirSync } = require('fs');\n const files = readdirSync(agentsDir).filter((f: string) => f.endsWith('.json'));\n \n if (files.length > 0) {\n for (const file of files) {\n const config = JSON.parse(readFileSync(join(agentsDir, file), 'utf-8'));\n console.log(` ${config.name.padEnd(18)} ${config.description || 'Custom agent'}`);\n }\n } else {\n console.log(` (No custom agents found)`);\n }\n } catch {\n console.log(` (No custom agents found)`);\n }\n } else {\n console.log(` (No custom agents found)`);\n }\n\n console.log(`\nCREATE CUSTOM AGENTS:\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\nYou can create agents from PDF, TXT, or MD documents:\n\n Via MCP: Use trie_create_agent tool\n CLI: trie-create --file book.pdf --name my-agent\n\nThe agent will learn patterns from your document and apply them\nto code reviews. Great for style guides, compliance docs, etc.\n`);\n}\n\n/**\n * Show version\n */\nfunction showVersion(): void {\n console.log(`trie-agent v${VERSION}`);\n}\n\n/**\n * Run scan command\n */\nasync function runScan(args: string[]): Promise<void> {\n // Forward to yolo-daemon with --once flag\n const { spawn } = await import('child_process');\n \n // Determine daemon path - works for both source (tsx) and built (node) execution\n let daemonPath: string;\n if (__filename.endsWith('.ts')) {\n // Running from source with tsx\n daemonPath = resolve(__dirname, 'yolo-daemon.ts');\n } else {\n // Running from built dist\n daemonPath = resolve(__dirname, 'yolo-daemon.js');\n }\n \n const daemonArgs = ['--once', ...args];\n \n // Use tsx for .ts files, node for .js files\n const executor = daemonPath.endsWith('.ts') ? 'npx' : 'node';\n const execArgs = daemonPath.endsWith('.ts') \n ? ['tsx', daemonPath, ...daemonArgs]\n : [daemonPath, ...daemonArgs];\n \n const child = spawn(executor, execArgs, {\n stdio: 'inherit',\n env: process.env\n });\n\n child.on('close', (code) => {\n process.exit(code || 0);\n });\n}\n\n/**\n * Run watch command\n */\nasync function runWatch(args: string[]): Promise<void> {\n const { spawn } = await import('child_process');\n \n // Determine daemon path - works for both source (tsx) and built (node) execution\n let daemonPath: string;\n if (__filename.endsWith('.ts')) {\n daemonPath = resolve(__dirname, 'yolo-daemon.ts');\n } else {\n daemonPath = resolve(__dirname, 'yolo-daemon.js');\n }\n \n // Use tsx for .ts files, node for .js files\n const executor = daemonPath.endsWith('.ts') ? 'npx' : 'node';\n const execArgs = daemonPath.endsWith('.ts') \n ? ['tsx', daemonPath, ...args]\n : [daemonPath, ...args];\n \n const child = spawn(executor, execArgs, {\n stdio: 'inherit',\n env: process.env\n });\n\n child.on('close', (code) => {\n process.exit(code || 0);\n });\n}\n\n/**\n * Run YOLO mode\n */\nasync function runYolo(args: string[]): Promise<void> {\n const { spawn } = await import('child_process');\n const daemonPath = resolve(__dirname, 'yolo-daemon.js');\n \n const daemonArgs = ['--yolo', ...args];\n \n const child = spawn('node', [daemonPath, ...daemonArgs], {\n stdio: 'inherit',\n env: process.env\n });\n\n child.on('close', (code) => {\n process.exit(code || 0);\n });\n}\n\n/**\n * Main entry point\n */\nfunction main(): void {\n const args = process.argv.slice(2);\n const command = args[0]?.toLowerCase();\n const restArgs = args.slice(1);\n\n // No command or help flag\n if (!command || command === 'help' || command === '--help' || command === '-h') {\n showHelp();\n process.exit(0);\n }\n\n switch (command) {\n case 'setup':\n case 'config':\n case 'configure':\n case 'init':\n showSetup();\n break;\n\n case 'agents':\n case 'list':\n case 'list-agents':\n listAgents();\n break;\n\n case 'version':\n case '--version':\n case '-v':\n showVersion();\n break;\n\n case 'scan':\n runScan(restArgs);\n break;\n\n case 'watch':\n runWatch(restArgs);\n break;\n\n case 'yolo':\n runYolo(restArgs);\n break;\n\n default:\n // Check if it looks like a flag (pass to yolo daemon)\n if (command.startsWith('-')) {\n // Treat as yolo-daemon args\n const { spawn } = require('child_process');\n const daemonPath = resolve(__dirname, 'yolo-daemon.js');\n \n const child = spawn('node', [daemonPath, ...args], {\n stdio: 'inherit',\n env: process.env\n });\n\n child.on('close', (code: number) => {\n process.exit(code || 0);\n });\n } else {\n console.error(`Unknown command: ${command}`);\n console.error(`Run 'trie-agent help' for usage information.`);\n process.exit(1);\n }\n }\n}\n\nmain();\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|