Skip to content

AI-powered bug hunter that piggybacks on existing LLM subscriptions (Claude Code, Cursor, Aider)

License

Notifications You must be signed in to change notification settings

shakecodeslikecray/whiterose

Repository files navigation

whiterose

npm version npm downloads GitHub stars License: PolyForm Noncommercial

"I've been staring at your code for a long time."

AI-powered bug hunter that uses your existing LLM subscription. No API keys needed. No extra costs.

β–ˆβ–ˆβ•—    β–ˆβ–ˆβ•—β–ˆβ–ˆβ•—  β–ˆβ–ˆβ•—β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
β–ˆβ–ˆβ•‘    β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•”β•β•β•β•β•
β–ˆβ–ˆβ•‘ β–ˆβ•— β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•”β•β•β•  β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘β•šβ•β•β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•
β•šβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
 β•šβ•β•β•β•šβ•β•β• β•šβ•β•  β•šβ•β•β•šβ•β•   β•šβ•β•   β•šβ•β•β•β•β•β•β•β•šβ•β•  β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β•

Table of Contents


Why whiterose?

You're already paying for Claude Code Max, Cursor, Codex, or similar AI coding tools. Why pay again for bug detection APIs?

whiterose piggybacks on your existing subscription to find bugs in your code. Zero additional cost.

Feature whiterose Traditional SAST
Cost $0 (uses existing subscription) $100-500/mo
Setup npm install -g Complex integrations
False positives Low (LLM understands context) High (pattern matching)
Fix generation Yes (agentic) No
Provider lock-in None (works with any LLM CLI) Vendor-specific

Installation

npm install -g @shakecodeslikecray/whiterose

Prerequisites

You need at least one LLM CLI tool installed:

Provider Installation Status
Claude Code npm install -g @anthropic-ai/claude-code βœ… Ready
Codex npm install -g @openai/codex βœ… Ready
Gemini npm install -g @google/gemini-cli βœ… Ready
Aider pip install aider-chat βœ… Ready
OpenCode curl -fsSL https://opencode.ai/install | bash βœ… Ready

Quick Start

# Interactive menu (recommended)
whiterose

# Or use commands directly:
whiterose init              # Initialize (explores codebase, generates understanding)
whiterose scan              # Scan for bugs (19-pass pipeline)
whiterose scan --quick      # Quick scan (single pass, for pre-commit)
whiterose fix               # Fix bugs interactively

Example output:

β”Œ  whiterose - thorough scan
β”‚
β—‡  Found 64 files to scan
β—‡  Static analysis: 37 signals found

════ CORE SCANNER (PIPELINE MODE) ════
  Provider: claude-code
  Passes: 19 (9 unit β†’ 5 integration β†’ 5 E2E)
  Findings flow: Unit β†’ Integration β†’ E2E

════ PHASE 1: UNIT ANALYSIS ════
  Looking for: injection, null refs, auth bypass, etc.
  [Batch 1/2] injection, auth-bypass, null-safety, type-safety, resource-leaks
    βœ“ injection: 2 bugs
    βœ“ auth-bypass: 0 bugs
    βœ“ null-safety: 1 bugs
    ...

════ PHASE 2: INTEGRATION ANALYSIS ════
  Building on 5 unit findings
  Looking for: auth flows, data flows, trust boundaries
    βœ“ auth-flow-trace: 1 bugs
    ...

════ PHASE 3: E2E ANALYSIS ════
  Building on 5 unit + 2 integration findings
  Looking for: attack chains, privilege escalation
    βœ“ attack-chain-analysis: 1 bugs
    ...

════ SCAN COMPLETE ════
  Duration: 4m 32s
  Unit: 5 β†’ Integration: 2 β†’ E2E: 1
  Final bugs: 7

Commands

whiterose init

First-time setup. Explores your codebase and generates understanding.

whiterose init

Creates .whiterose/ directory with:

  • config.yml - Configuration
  • intent.md - Behavioral contracts (editable)
  • cache/understanding.json - AI-generated codebase understanding

whiterose scan

Find bugs using the 19-pass pipeline.

whiterose scan                    # Incremental scan (changed files only)
whiterose scan --full             # Full scan (all files)
whiterose scan --quick            # Quick scan (single pass, fast)
whiterose scan --provider codex   # Use specific provider
whiterose scan --json             # JSON output
whiterose scan --ci               # CI mode (exit 1 if bugs found)
whiterose scan src/api/           # Scan specific path

whiterose fix

Interactive TUI for reviewing and fixing bugs.

whiterose fix                     # Interactive dashboard
whiterose fix WR-001              # Fix specific bug by ID
whiterose fix --dry-run           # Preview without applying
whiterose fix --provider claude-code  # Use specific provider

# External bug sources:
whiterose fix --sarif ./semgrep.sarif      # Import from SARIF
whiterose fix --github https://github.com/owner/repo/issues/123
whiterose fix --describe                    # Manually describe a bug

Agentic Fix: whiterose uses an agentic approach - the LLM reads the code, explores context, and applies fixes directly. It can also detect false positives during fix and notify you.

whiterose refresh

Rebuild codebase understanding from scratch.

whiterose status

Show current status (provider, cache, last scan).


Architecture

This section explains how whiterose works internally. Critical reading for contributors.

Three-Layer Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    LAYER 0: UNDERSTANDING                           β”‚
β”‚                         (whiterose init)                            β”‚
β”‚                                                                     β”‚
β”‚  Input:                           Output:                           β”‚
β”‚  - README.md, package.json        - .whiterose/intent.md            β”‚
β”‚  - CONTRIBUTING.md                - .whiterose/cache/understanding  β”‚
β”‚  - Existing documentation         - Project type, framework, etc.   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                  β”‚
                                  β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    LAYER 1: BUG FINDING                             β”‚
β”‚                        (whiterose scan)                             β”‚
β”‚                                                                     β”‚
β”‚  1. Load understanding from Layer 0                                 β”‚
β”‚  2. Run static analysis (tsc, eslint)                               β”‚
β”‚  3. Run 19-pass LLM pipeline (Unit β†’ Integration β†’ E2E)             β”‚
β”‚  4. Deduplicate and merge findings                                  β”‚
β”‚  5. Output reports (SARIF, Markdown, JSON)                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                  β”‚
                                  β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    LAYER 2: BUG FIXING                              β”‚
β”‚                         (whiterose fix)                             β”‚
β”‚                                                                     β”‚
β”‚  1. Load bugs from scan results (or external sources)               β”‚
β”‚  2. Interactive TUI for review                                      β”‚
β”‚  3. Agentic fix (LLM explores and fixes)                            β”‚
β”‚  4. False positive detection during fix                             β”‚
β”‚  5. Commit changes                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

19-Pass Pipeline

whiterose runs 19 specialized passes organized into 3 phases, with findings flowing through:

Static Analysis (tsc/eslint)
           β”‚
           β–Ό
     staticResults ─────────────────────────────────────┐
           β”‚                                            β”‚
           β–Ό                                            β”‚
════ PHASE 1: UNIT ANALYSIS (9 passes) ════            β”‚
β”‚                                                      β”‚
β”‚  Each pass focuses on ONE bug category:              β”‚
β”‚  1. injection      - SQL, XSS, command injection     β”‚
β”‚  2. auth-bypass    - Missing/broken auth checks      β”‚
β”‚  3. null-safety    - Null/undefined dereference      β”‚
β”‚  4. type-safety    - Type coercion bugs              β”‚
β”‚  5. resource-leaks - Unclosed handles, listeners     β”‚
β”‚  6. async-issues   - Missing await, race conditions  β”‚
β”‚  7. data-validation - Input validation gaps          β”‚
β”‚  8. secrets-exposure - Hardcoded secrets, leaks      β”‚
β”‚  9. logic-errors   - Off-by-one, wrong operators     β”‚
β”‚                                                      β”‚
β”‚  Runs in batches of 5 (parallel within batch)        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           β–Ό
      unitFindings ─────────────────────────────┐
           β”‚                                    β”‚
           β–Ό                                    β–Ό
════ PHASE 2: INTEGRATION ANALYSIS (5 passes) ════
β”‚  Input: staticResults + unitFindings         β”‚
β”‚                                              β”‚
β”‚  Prompt includes previous findings:          β”‚
β”‚  "## PREVIOUS FINDINGS TO BUILD ON           β”‚
β”‚   - [high] SQL injection at api.ts:42        β”‚
β”‚   - [medium] Missing auth at routes.ts:15"   β”‚
β”‚                                              β”‚
β”‚  Passes:                                     β”‚
β”‚  1. auth-flow-trace      - Auth across files β”‚
β”‚  2. data-flow-trace      - Data propagation  β”‚
β”‚  3. validation-boundary  - Trust boundaries  β”‚
β”‚  4. error-propagation    - Error handling    β”‚
β”‚  5. trust-boundary-trace - Security bounds   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           β–Ό
   integrationFindings ─────────────────┐
           β”‚                            β”‚
           β–Ό                            β–Ό
════ PHASE 3: E2E ANALYSIS (5 passes) ════
β”‚  Input: staticResults + unitFindings β”‚
β”‚         + integrationFindings        β”‚
β”‚                                      β”‚
β”‚  Builds attack chains from ALL       β”‚
β”‚  previous findings.                  β”‚
β”‚                                      β”‚
β”‚  Passes:                             β”‚
β”‚  1. attack-chain-analysis            β”‚
β”‚  2. privilege-escalation-trace       β”‚
β”‚  3. session-lifecycle-trace          β”‚
β”‚  4. user-journey-simulation          β”‚
β”‚  5. api-contract-verification        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           β–Ό
════ POST-PROCESSING ════
β”‚  1. Combine all findings             β”‚
β”‚  2. Deduplicate (file:line:category) β”‚
β”‚  3. Merge similar (within 5 lines)   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           β–Ό
      Final Bugs

LSP-Compliant Provider Abstraction

whiterose follows the Liskov Substitution Principle - all providers are interchangeable and get the same 19-pass scanning.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      CoreScanner                                 β”‚
β”‚  src/core/scanner.ts                                            β”‚
β”‚  ─────────────────────────────────────────────────────────────  β”‚
β”‚  β€’ 19-pass pipeline logic                                       β”‚
β”‚  β€’ Batching (5 parallel, 2s delay)                              β”‚
β”‚  β€’ Phase dependencies (Unit β†’ Integration β†’ E2E)                β”‚
β”‚  β€’ Deduplication & merging                                      β”‚
β”‚  β€’ Progress callbacks                                           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚
                              β”‚ executor.runPrompt(prompt)
                              β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚               PromptExecutor (interface)                         β”‚
β”‚  src/core/scanner.ts                                            β”‚
β”‚  ─────────────────────────────────────────────────────────────  β”‚
β”‚  interface PromptExecutor {                                     β”‚
β”‚    name: string;                                                β”‚
β”‚    isAvailable(): Promise<boolean>;                             β”‚
β”‚    runPrompt(prompt: string, options: PromptOptions):           β”‚
β”‚      Promise<PromptResult>;                                     β”‚
β”‚  }                                                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚              β”‚              β”‚              β”‚              β”‚
         β–Ό              β–Ό              β–Ό              β–Ό              β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ claude   β”‚  β”‚  codex   β”‚  β”‚  gemini  β”‚  β”‚  aider   β”‚  β”‚ opencode β”‚
   β”‚  -code   β”‚  β”‚          β”‚  β”‚          β”‚  β”‚          β”‚  β”‚          β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
   executors/    executors/    executors/    executors/    executors/

Adding a new provider is trivial - just implement the PromptExecutor interface (~30 lines).

Static Analysis Integration

Static analysis runs first, deterministically, before any LLM passes:

// In scan.ts
staticResults = await runStaticAnalysis(cwd, filesToScan, config);

// Passed to CoreScanner
const bugs = await scanner.scan({
  files: filesToScan,
  understanding,
  staticResults,  // ← Every pass sees this
});

Each LLM pass receives static analysis signals in its prompt:

## STATIC ANALYSIS SIGNALS (from tsc/eslint)
- typescript: src/api.ts:42 - TS2532: Object is possibly 'undefined'
- eslint: src/db.ts:15 - @typescript-eslint/no-explicit-any

NOTE: Static tools already verified control flow. Don't report issues they would catch.

This reduces false positives - the LLM knows what tsc/eslint already flagged.


Configuration

.whiterose/config.yml:

version: "1"
provider: claude-code  # or codex, gemini, aider

include:
  - "**/*.ts"
  - "**/*.tsx"
  - "**/*.js"
  - "**/*.jsx"

exclude:
  - node_modules
  - dist
  - "**/*.test.*"
  - "**/*.spec.*"

priorities:
  src/api/checkout.ts: critical
  src/auth/: high

categories:
  - injection
  - auth-bypass
  - null-reference
  - logic-error
  - async-issue
  - resource-leak
  - data-validation
  - secrets-exposure

minConfidence: low  # low, medium, high

staticAnalysis:
  typescript: true
  eslint: true

output:
  sarif: true
  markdown: true
  sarifPath: .whiterose/reports
  markdownPath: BUGS.md

Bug Categories

whiterose looks for bugs in these categories:

Category Description Example
injection SQL, XSS, command injection db.query("SELECT * FROM users WHERE id=" + userId)
auth-bypass Missing/broken authentication Route handler without auth middleware
null-reference Null/undefined dereference user.profile.name when profile might be null
logic-error Off-by-one, wrong operators i <= arr.length instead of i < arr.length
async-issue Missing await, race conditions const data = fetchData(); use(data);
resource-leak Unclosed handles, listeners db.connect() without db.close()
data-validation Input validation gaps Missing sanitization on user input
secrets-exposure Hardcoded secrets const API_KEY = "sk-..."
type-coercion Loose equality bugs if (value == null) when 0 is valid
boundary-error Edge case handling Empty array, zero values
concurrency Thread safety issues Shared state without locks
intent-violation Violates documented behavior Code contradicts README/docs

Output Formats

SARIF

Standard format for static analysis tools. Works with:

  • VS Code (SARIF Viewer extension)
  • GitHub Code Scanning
  • Azure DevOps

Markdown

Two formats:

  • bugs.md - Technical (for developers)
  • bugs-human.md - Tester-friendly (for QA)

JSON

Full bug data with code paths, evidence, and confidence scores.


Contributing

Project Structure

whiterose/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ cli/
β”‚   β”‚   β”œβ”€β”€ index.ts              # CLI entry point
β”‚   β”‚   └── commands/
β”‚   β”‚       β”œβ”€β”€ init.ts           # whiterose init
β”‚   β”‚       β”œβ”€β”€ scan.ts           # whiterose scan
β”‚   β”‚       └── fix.ts            # whiterose fix
β”‚   β”‚
β”‚   β”œβ”€β”€ core/
β”‚   β”‚   β”œβ”€β”€ scanner.ts            # CoreScanner + PromptExecutor interface
β”‚   β”‚   β”œβ”€β”€ multipass-scanner.ts  # Pass configurations (SCAN_PASSES)
β”‚   β”‚   β”œβ”€β”€ flow-analyzer.ts      # Flow pass configurations (FLOW_PASSES)
β”‚   β”‚   β”œβ”€β”€ fixer.ts              # Agentic fix logic
β”‚   β”‚   β”œβ”€β”€ config.ts             # Config loading
β”‚   β”‚   └── utils.ts              # Utilities
β”‚   β”‚
β”‚   β”œβ”€β”€ providers/
β”‚   β”‚   β”œβ”€β”€ executors/            # LSP-compliant provider implementations
β”‚   β”‚   β”‚   β”œβ”€β”€ index.ts          # getExecutor(), getAvailableExecutors()
β”‚   β”‚   β”‚   β”œβ”€β”€ claude-code.ts    # ClaudeCodeExecutor
β”‚   β”‚   β”‚   β”œβ”€β”€ codex.ts          # CodexExecutor
β”‚   β”‚   β”‚   β”œβ”€β”€ gemini.ts         # GeminiExecutor
β”‚   β”‚   β”‚   β”œβ”€β”€ aider.ts          # AiderExecutor
β”‚   β”‚   β”‚   └── opencode.ts       # OpenCodeExecutor
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ prompts/
β”‚   β”‚   β”‚   β”œβ”€β”€ multipass-prompts.ts    # Unit pass prompts
β”‚   β”‚   β”‚   β”œβ”€β”€ flow-analysis-prompts.ts # Integration/E2E prompts
β”‚   β”‚   β”‚   └── adversarial.ts          # Validation prompts
β”‚   β”‚   β”‚
β”‚   β”‚   └── detect.ts             # Provider detection
β”‚   β”‚
β”‚   β”œβ”€β”€ analysis/
β”‚   β”‚   └── static.ts             # tsc/eslint integration
β”‚   β”‚
β”‚   β”œβ”€β”€ tui/
β”‚   β”‚   β”œβ”€β”€ App.tsx               # Main TUI app
β”‚   β”‚   └── screens/              # TUI screens
β”‚   β”‚
β”‚   β”œβ”€β”€ output/
β”‚   β”‚   β”œβ”€β”€ sarif.ts              # SARIF output
β”‚   β”‚   β”œβ”€β”€ markdown.ts           # Technical markdown
β”‚   β”‚   └── human-readable.ts     # Tester-friendly markdown
β”‚   β”‚
β”‚   └── types.ts                  # TypeScript types (Zod schemas)
β”‚
β”œβ”€β”€ tsup.config.ts                # Build config
└── package.json

Key Files for Contributors

File Purpose
src/core/scanner.ts Start here. CoreScanner orchestrates everything.
src/core/multipass-scanner.ts Pass configurations for unit analysis
src/core/flow-analyzer.ts Pass configurations for integration/E2E
src/providers/executors/*.ts Provider implementations (simple!)
src/providers/prompts/*.ts Prompt templates

Adding a New Provider

  1. Create src/providers/executors/your-provider.ts:
import { PromptExecutor, PromptOptions, PromptResult } from '../../core/scanner.js';

export class YourProviderExecutor implements PromptExecutor {
  name = 'your-provider';

  async isAvailable(): Promise<boolean> {
    // Check if CLI tool is installed
  }

  async runPrompt(prompt: string, options: PromptOptions): Promise<PromptResult> {
    // Run: your-cli -p "prompt"
    // Return: { output: stdout, error: stderr }
  }
}
  1. Register in src/providers/executors/index.ts
  2. Add to ProviderType in src/types.ts
  3. Add detection in src/providers/detect.ts

Adding a New Pass

  1. Add pass config to SCAN_PASSES in src/core/multipass-scanner.ts (for unit passes) or FLOW_PASSES in src/core/flow-analyzer.ts (for integration/E2E)

  2. Add to pipeline in src/providers/prompts/flow-analysis-prompts.ts:

export function getFullAnalysisPipeline() {
  return [
    { phase: 'Unit Analysis', passes: [..., 'your-new-pass'] },
    // ...
  ];
}

Building

npm run build    # Build
npm run dev      # Watch mode
npm test         # Run tests

Philosophy

  • SRP: whiterose finds bugs. It doesn't write tests, lint code, or format files.
  • Leverage, Don't Reinvent: Uses existing AI agents (Claude Code, Codex) rather than building a custom agent loop.
  • LSP-Compliant: All providers are interchangeable. Scanning logic lives in ONE place.
  • Transparency: Shows exactly what's happening in real-time.
  • Grounded: Every bug must have evidence and a code path trace.
  • Zero Cost: Uses your existing LLM subscription.

Show Your Support

If you're using whiterose, we'd love to know!

Add whiterose topic


License

PolyForm Noncommercial 1.0.0

This software is free for non-commercial use. See LICENSE for details.


Credits

Named after the Mr. Robot character who sees everything and orchestrates from the shadows.


Copyright (c) 2024-2025 shakecodeslikecray (https://github.com/shakecodeslikecray)

About

AI-powered bug hunter that piggybacks on existing LLM subscriptions (Claude Code, Cursor, Aider)

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

No packages published