(repoPath: string, options: ScanOptions)
| 85 | * @param options - Scan options from CLI |
| 86 | */ |
| 87 | export async function executeScan(repoPath: string, options: ScanOptions): Promise<void> { |
| 88 | let client: AgentClient | null = null; |
| 89 | let mcpProcess: ChildProcess | null = null; |
| 90 | let mcpBridge: SocketIoMcpBridge | null = null; |
| 91 | let sessionId: string | undefined = undefined; |
| 92 | const originalLogLevel = getLogLevel(); |
| 93 | const structuredOutputRequested = |
| 94 | options.json === true || |
| 95 | options.format === CodeScanOutputFormat.JSON || |
| 96 | options.format === CodeScanOutputFormat.SARIF; |
| 97 | const absoluteRepoPath = path.resolve(repoPath); |
| 98 | const cleanupRefs: CleanupRefs = { |
| 99 | repoPath: absoluteRepoPath, |
| 100 | socket: null, |
| 101 | mcpBridge: null, |
| 102 | mcpProcess: null, |
| 103 | spinner: null, |
| 104 | abortController: null, |
| 105 | }; |
| 106 | let outputFormat: CodeScanOutputFormat | null = null; |
| 107 | let spinner: ReturnType<typeof createSpinner> | undefined; |
| 108 | let showSpinner = false; |
| 109 | |
| 110 | const startTime = Date.now(); |
| 111 | |
| 112 | try { |
| 113 | outputFormat = resolveOutputFormat(options); |
| 114 | // Structured modes reserve stdout for the payload. src/entrypoint.ts already pre-sets |
| 115 | // LOG_LEVEL=error before the logger module is imported (so any module-init logs are |
| 116 | // already suppressed); we re-apply here for callers that bypass the CLI entrypoint |
| 117 | // (e.g., library consumers calling executeScan directly). |
| 118 | if (outputFormat !== CodeScanOutputFormat.TEXT) { |
| 119 | setLogLevel('error'); |
| 120 | } |
| 121 | |
| 122 | // Load and merge configuration |
| 123 | const baseConfig: Config = loadConfigOrDefault(options.config); |
| 124 | const config = mergeConfigWithOptions(baseConfig, options); |
| 125 | |
| 126 | // Resolve guidance (CLI options take precedence) |
| 127 | const guidance = resolveGuidance(options, config); |
| 128 | |
| 129 | // Display startup messages (skipped for non-text formats to keep stdout clean for parsing) |
| 130 | if (outputFormat === CodeScanOutputFormat.TEXT) { |
| 131 | logger.info('Beginning scan for LLM-related vulnerabilities in your code.'); |
| 132 | logger.info(` Minimum severity: ${config.minimumSeverity}`); |
| 133 | if (config.diffsOnly) { |
| 134 | logger.info(` Mode: diffs only`); |
| 135 | } else { |
| 136 | logger.info(` Mode: diffs + tracing into repo`); |
| 137 | } |
| 138 | logger.info(''); |
| 139 | } |
| 140 | |
| 141 | logger.debug(`Repository: ${absoluteRepoPath}`); |
| 142 | |
| 143 | // Register cleanup handlers for signals (SIGINT, SIGTERM, etc.) |
| 144 | registerCleanupHandlers(cleanupRefs); |
no test coverage detected
searching dependent graphs…