Skip to content

πŸ”¬ Industrial-grade static analysis for all popular programming languages. Catch 1000+ bug patterns before production

License

Notifications You must be signed in to change notification settings

Dicklesworthstone/ultimate_bug_scanner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ”¬ Ultimate Bug Scanner v5.0

The AI Coding Agent's Secret Weapon: Flagging Likely Bugs for Fixing Early On

License: MIT Platform Version

# One command to catch 1000+ bug patterns (always master, cache-busted)
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_scanner/master/install.sh?$(date +%s)" \
  | bash -s --

Just want it to do everything without confirmations? Live life on the edge with easy-mode to auto-install every dependency, accept all prompts, detect local coding agents, and wire their quality guardrails with zero extra questions:

curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_scanner/master/install.sh?$(date +%s)" \
  | bash -s -- --easy-mode

Note: Windows users must run the installer one-liner from within Git Bash, or use WSL for Windows.

πŸ’₯ The Problem: AI Moves Fast, Bugs Move Faster

You're coding faster than ever with Claude Code, Codex, Cursor, and other AI coding agents. You're shipping features in minutes that used to take days. But here's the painful truth:

Even the best AI makes these mistakes:

JavaScript/TypeScript example (similar patterns exist in Python, Go, Rust, Java, C++, Ruby):

// ❌ CRITICAL BUG #1: Null pointer crash waiting to happen
const submitButton = document.getElementById('submit');
submitButton.addEventListener('click', handleSubmit);  // πŸ’₯ Crashes if element doesn't exist

// ❌ CRITICAL BUG #2: XSS vulnerability
function displayUserComment(comment) {
  document.getElementById('comments').innerHTML = comment;  // 🚨 Security hole
}

// ❌ CRITICAL BUG #3: Silent failure (missing await)
async function saveUser(data) {
  const result = validateUser(data);  // πŸ’₯ Should be 'await validateUser(data)'
  await saveToDatabase(result);  // Saves undefined!
}

// ❌ CRITICAL BUG #4: Always false comparison
if (calculatedValue === NaN) {  // πŸ’₯ This NEVER works (always false)
  console.log("Invalid calculation");
}

// ❌ CRITICAL BUG #5: parseInt footgun
const zipCode = parseInt(userInput);  // πŸ’₯ "08" becomes 0 in old browsers (octal!)

Each of these bugs could cost 3-6 hours to debug in production. Similar issues plague every language: unguarded null access, missing await, security holes from eval(), buffer overflows from strcpy(), .unwrap() panics, goroutine leaks... You've probably hit all of them.


🎯 The Solution: Your 24/7 Bug Hunting Partner

🧠 Language-Aware Meta-Runner

  • ubs auto-detects JavaScript/TypeScript, Python, C/C++, Rust, Go, Java, and Ruby in the same repo and fans out to per-language scanners.
  • Each scanner lives under modules/ubs-<lang>.sh, ships independently, and supports --format text|json|jsonl|sarif for consistent downstream tooling.
  • Modules download lazily (PATH β†’ repo modules/ β†’ cached under ${XDG_DATA_HOME:-$HOME/.local/share}/ubs/modules) and are validated before execution.
  • Results from every language merge into one text/JSON/SARIF report via jq, so CI systems and AI agents only have to parse a single artifact.

πŸ” Supply-Chain Safeguards

  • Every lazily-downloaded module ships with a pinned SHA-256 checksum baked into the meta-runner. Files fetched from GitHub are verified before they can execute, preventing tampering between releases.
  • The cache lives under ${XDG_DATA_HOME:-$HOME/.local/share}/ubs/modules by default; use --module-dir to relocate it (e.g., inside a CI workspace) while retaining the same verification guarantees.
  • Run ubs doctor at any time to audit your environment. It checks for curl/wget availability, writable cache directories, and per-language module integrity. Add --fix to redownload missing or corrupted modules proactively.
  • Scanner runs still respect --update-modules, but an invalid checksum now causes an immediate failure with remediation guidance rather than executing unverified code.

πŸŽ› Category Packs & Shareable Reports

  • --category=resource-lifecycle focuses the scanners on Python/Go/Java resource hygiene (context managers, defer symmetry, try-with-resources). UBS automatically narrows the language set to those with lifecycle packs enabled and suppresses unrelated categories.
  • --comparison=<baseline.json> diff the latest combined summary against a stored run. Deltas feed into console output, JSON, HTML, and SARIF automation metadata so CI can detect regressions.
  • --report-json=<file> writes an enriched summary (project, totals, git metadata, optional comparison block) that you can archive or share with teammates/CI.
  • --html-report=<file> emits a standalone HTML preview showing totals, trends vs. baseline, and per-language breakdownsβ€”ideal for attaching to PRs or chat updates.
  • All shareable outputs inject GitHub permalinks when UBS is run inside a git repo with a GitHub remote. Text output automatically annotates path:line references, JSON gains git.* metadata, and merged SARIF runs now include versionControlProvenance plus automationDetails keyed by the comparison id.

Resource lifecycle heuristics in each language

  • Python – Category 16 now correlates every open() call against matching with open(...) usage and explicit encoding= parameters, while Category 19 uses the new AST helper at modules/helpers/resource_lifecycle_py.py to walk every file, socket, subprocess, asyncio task, and context cancellation path. The helper resolves alias imports, context managers, and awaited tasks so the diff counts (acquire=X, release=Y, context-managed=Z) show the exact imbalance per file.
  • Go – Category 5/17 now run a Go AST walker (modules/helpers/resource_lifecycle_go.go) that detects context.With* calls missing cancel, time.NewTicker/NewTimer without Stop, os.Open/sql.Open without Close, and mutex Lock/Unlock symmetry. Findings come straight from the AST positions, so β€œticker missing Stop()” lines map to the exact file:line instead of coarse regex summaries.
  • Java – Category 5 surfaces FileInputStream, readers/writers, JDBC handles, etc. that were created outside try-with-resources, while Category 19 keeps tracking executor services and file streams that never close. The new summary text matches the manifest fixtures, so CI will fail if regression swallows these warnings.

Shareable output quickstart

# 1) Capture a baseline JSON (checked into CI artifacts or local history)
ubs --ci --only=python --category=resource-lifecycle \
    --report-json .ubs/baseline.json test-suite/python/buggy

# 2) Re-run with comparison + HTML preview for PRs or chat threads
ubs --ci --only=python --category=resource-lifecycle \
    --comparison .ubs/baseline.json \
    --report-json .ubs/latest.json \
    --html-report  .ubs/latest.html \
    test-suite/python/buggy

latest.json now contains the git metadata (repo URL, commit, blob_base) plus a comparison.delta block, and latest.html renders a lightweight dashboard summarising the deltas. SARIF uploads also pick up the comparison id so repeating runs in CI stay grouped by automation id.


πŸ’‘ Basic Usage

# Scan current directory
ubs .

# Scan specific directory
ubs /path/to/your/project

# Verbose mode (show more code examples)
ubs -v .

# Save report to file
ubs . bug-report.txt

# CI mode (exit code 1 on warnings)
ubs . --fail-on-warning

# Quiet mode (summary only)
ubs -q .

# Skip specific categories (e.g., skip TODO markers)
ubs . --skip=11,14

# Custom file extensions
ubs . --include-ext=js,ts,vue,svelte

Handy switches

# Git-aware quick scans (changed files only)
ubs --staged    # Scan files staged for commit
ubs --diff      # Scan working tree changes vs HEAD

# Strictness profiles
ubs --profile=strict   # Fail on warnings, enforce high standards
ubs --profile=loose    # Skip TODO/debug/code-quality nits when prototyping

# Machine-readable output
ubs . --format=json    # Pure JSON on stdout; logs go to stderr
ubs . --format=jsonl   # Line-delimited summary per scanner + totals
ubs . --format=jsonl --beads-jsonl out/findings.jsonl  # Save JSONL for Beads/"strung"

Keeping noise low

  • UBS auto-ignores common junk (node_modules, virtualenvs, dist/build/target/vendor, editor caches, etc.).
  • Inline suppression is available when a finding is intentional: eval("print('safe')") # ubs:ignore

πŸš€ Quick Install (30 Seconds)

Option 1: Automated Install (Recommended)

curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_scanner/master/install.sh?$(date +%s)" | bash

Option 2: Integrity-first install (signed checksums)

export UBS_MINISIGN_PUBKEY="RWQg+jMrKiloMT5L3URISMoRzCMc/pVcVRCTfuY+WIzttzIr4CUJYRUk"
curl -fsSL https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_scanner/master/scripts/verify.sh | bash

The verifier downloads SHA256SUMS + SHA256SUMS.minisig from the matching release, validates them with minisign, checks install.sh, and only then executes it. Use --insecure to bypass verification (not recommended).

Option 3: Nix

Run directly (no install):

nix run github:Dicklesworthstone/ultimate_bug_scanner

Dev shell for contributors:

nix develop

Option 4: Docker / OCI

Pull & inspect:

docker run --rm ghcr.io/dicklesworthstone/ubs-tools ubs --help

Scan host code (risk-aware: grants container access to host FS):

docker run --rm -v /:/host ghcr.io/dicklesworthstone/ubs-tools bash -c "cd /host/path && ubs ."

⚠️ Use the host-mount pattern only when you understand the write-access implications.

Deployment & Security

The installer will:

  • βœ… Install the ubs command globally
  • βœ… Optionally install ast-grep (for advanced AST analysis)
  • βœ… Optionally install ripgrep (for 10x faster scanning)
  • βœ… Optionally install jq (needed for JSON/SARIF merging across all language scanners)
  • βœ… Optionally install typos (smart spellchecker for docs and identifiers)
  • βœ… Optionally install Node.js + typescript (enables deep TypeScript type narrowing analysis)
  • βœ… Auto-run ubs doctor post-install and append a session summary to ~/.config/ubs/session.md
  • βœ… Capture readiness facts (ripgrep/jq/typos/type narrowing) and store them for ubs sessions --entries 1
  • βœ… Set up git hooks (block commits with critical bugs)
  • βœ… Set up Claude Code hooks (scan on file save)
  • βœ… Add documentation to your AGENTS.md

Need to revisit what the installer discovered later? Run ubs sessions --entries 1 to view the most recent session log (or point teammates at the same summary).

Need the β€œjust make it work” button? Run the installer with --easy-mode to auto-install every dependency, accept all prompts, detect local coding agents, and wire their quality guardrails with zero extra questions:

curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_scanner/master/install.sh?$(date +%s)" \
  | bash -s -- --easy-mode

Total time: 30 seconds to 2 minutes (depending on dependencies)

Need to keep your shell RC files untouched? Combine --no-path-modify (and optionally --skip-hooks) with the command aboveβ€”the installer will still drop ubs into your chosen --install-dir, but it will skip both PATH edits and the alias helper entirely.

Option 2: Manual Install

# Download and install the unified runner
curl -fsSL https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_scanner/master/ubs \
  -o /usr/local/bin/ubs && chmod +x /usr/local/bin/ubs

# Verify it works
ubs --help

# Optional but recommended: Install dependencies
npm install -g @ast-grep/cli     # AST-based analysis
brew install ripgrep             # 10x faster searching (or: apt/dnf/cargo install)
brew install typos-cli           # Spellchecker tuned for code (or: cargo install typos-cli)
npm install -g typescript        # Enables full tsserver-based type narrowing checks

Option 3: Use Without Installing

# Download once
curl -fsSL https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_scanner/master/ubs \
  -o ubs && chmod +x ubs

# Run it
./ubs .

Installer Safety Nets

Uninstall from any shell

Run the installer in --uninstall mode via curl if you want to remove UBS and all of its integrations:

curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_scanner/master/install.sh?$(date +%s)" | bash -s -- --uninstall --non-interactive

This command deletes the UBS binary, shell RC snippets/aliases, config under ~/.config/ubs, and the optional Claude/Git hooks that the installer set up. Because it passes --non-interactive, it auto-confirms all prompts and runs unattended.

Flag What it does Why it matters
--dry-run Prints every install action (downloads, PATH edits, hook writes, cleanup) without touching disk. Dry runs still resolve config, detect agents, and show you exactly what would change. Audit the installer, demo it to teammates, or validate CI steps without modifying a workstation.
--self-test Immediately runs test-suite/install/run_tests.sh after installation and exits non-zero if the smoke suite fails. CI/CD jobs and verified setups can prove the installer still works end-to-end before trusting a release.
--skip-type-narrowing Skip the Node.js + TypeScript readiness probe and the cross-language guard analyzers (JS/Rust/Kotlin/Swift). Useful for air-gapped hosts or environments that want to stay in heuristic-only mode.
--skip-typos Skip the Typos spellchecker installation + diagnostics. Handy when corp images already provide Typos or when you deliberately disable spellcheck automation.
--skip-doctor Skip the automatic ubs doctor run + session summary after install. Use when CI already runs doctor separately or when you're iterating locally and want a faster finish.

Warning

--self-test requires running install.sh from a working tree that contains test-suite/install/run_tests.sh (i.e., the repo root). Curl-piping the installer from GitHub can’t self-test because the harness isn’t present, so the flag will error out early instead of giving a false sense of safety.

Note

After every install the script now double-checks command -v ubs. If another copy shadows the freshly written binary, you’ll get an explicit warning with both paths so you can fix PATH order before running scans.

Tip

Type narrowing relies on Node.js plus the typescript npm package and the Python helpers that power the Rust/Kotlin/Swift checks. The installer now checks Node/TypeScript readiness, can optionally run npm install -g typescript, and surfaces the status inside install.sh --diagnose. Use --skip-type-narrowing if you’re on an air-gapped host or plan to keep the heuristic-only mode.

Tip

To avoid global npm permission issues, the installer now detects/installs bun just like other dependencies and uses bun install --global typescript by default, falling back to npm only if bun isn’t available.

The diagnostics also call out Swift guard readiness: if python3 is available we count .swift files under your repo and record whether the guard helper will actually run. That fact shows up in install.sh --diagnose output and the auto-generated session log so iOS/macOS teams can tell at a glance whether the ObjC-bridging heuristics are active.

Common combos

# Preview everything without touching dotfiles or hooks
bash install.sh --dry-run --no-path-modify --skip-hooks --non-interactive

# CI-friendly install that self-tests the smoke harness
bash install.sh --easy-mode --self-test --skip-hooks

πŸ”„ Auto-Update

The ubs meta-runner automatically checks for updates once every 24 hours. If a new version is available, it self-updates securely before running your scan.

To disable this behavior (e.g., in strict environments):

export UBS_NO_AUTO_UPDATE=1
# or
ubs --no-auto-update .

Ultimate Bug Scanner is like having a senior developer review every line of code in under 5 seconds; it's the perfect automated companion to your favorite coding agent:

$ ubs .

╔══════════════════════════════════════════════════════════════════════╗
β•‘  πŸ”¬ ULTIMATE BUG SCANNER v4.4 - Scanning your project...             β•‘
β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

Project:  /Users/you/awesome-app
Files:    247 JS/TS + 58 Python + 24 Go + 16 Java + 11 Ruby + 12 C++/Rust files
Finished: 3.2 seconds

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Summary Statistics:
  Files scanned:    247
  πŸ”₯ Critical:      0    ← Would have crashed in production!
  ⚠️  Warnings:      8    ← Should fix before shipping
  ℹ️  Info:          23   ← Code quality improvements

✨ EXCELLENT! No critical issues found ✨

⚑ Why Developers + AI Agents Will Love This Tool

πŸš€ 1. Catches What Humans & AI Miss

18 specialized detection categories covering the bugs that actually matter:

Category What It Prevents Time Saved Per Bug
Null Safety "Cannot read property of undefined" crashes 2-4 hours
Security Holes XSS, code injection, prototype pollution 8-20 hours + reputation damage
Async/Await Bugs Race conditions, unhandled rejections 4-8 hours
Memory Leaks Event listeners, timers, detached DOM 6-12 hours
Type Coercion JavaScript's === vs == madness 1-3 hours
+ 13 more categories 100+ hours/month saved

πŸ’¨ 2. Blazing Fast (Because Your Time Matters)

Small project (5K lines):     0.8 seconds  ⚑
Medium project (50K lines):   3.2 seconds  πŸš€
Large project (200K lines):  12 seconds    πŸ’¨
Huge project (1M lines):     58 seconds    πŸƒ

That's 10,000+ lines analyzed per second. Faster than you can say "but it worked on my machine."

πŸ€– 3. Built FOR AI Agents, BY Developers Who Use AI

Unlike traditional linters that fight AI-generated code, this scanner embraces it:

βœ… Designed for Claude Code, Cursor, Windsurf, Aider, Continue, Copilot
βœ… Zero configuration - works with ANY JS/TS, Python, C/C++, Rust, Go, Java, or Ruby project
βœ… Integrates with git hooks, CI/CD, file watchers
βœ… Actionable output (tells you WHAT's wrong and HOW to fix it)
βœ… Fails fast in CI (catch bugs before they merge)
βœ… React Hooks dependency analysis that spots missing deps, unstable objects, and stale closures
βœ… Lightweight taint analysis that traces req.body/window.location/localStorage β†’ innerHTML/res.send/eval/exec/db.query and flags flows without DOMPurify/escapeHtml/parameterized SQL

πŸ“Š 4. Real-World Impact

Scenario Without Scanner With Scanner
AI implements user auth β€’ 3 null pointer crashes (9h debugging)
β€’ 1 XSS vulnerability (8h + incident)
β€’ 2 race conditions (4h debugging)
Total: ~21 hours + security incident
β€’ All issues caught in 4 seconds
β€’ Fixed before commit (15 min)
Total: 15 minutes
Savings: 84x faster ⚑
Refactor payment flow β€’ Division by zero in edge case (3h)
β€’ Unhandled promise rejection (2h)
β€’ Missing error logging (1h)
Total: 6 hours debugging
β€’ Caught instantly (3 sec)
β€’ Fixed before merge (10 min)
Total: 10 minutes
Savings: 36x faster πŸš€

πŸ€– AI Agent Integration (The Real Magic)

On-Device Agent Guardrails

install.sh now inspects your workstation for the most common coding agents (the same set listed below) and, when asked, drops guardrails that remind those agents to run ubs --fail-on-warning . before claiming a task is done. In --easy-mode this happens automatically; otherwise you can approve each integration individually.

Agent / IDE What we wire up Why it helps
Claude Code Desktop (.claude/hooks/on-file-write.sh) File-save hook that shells out to ubs --ci whenever Claude saves JS/TS files. Keeps Claude from accepting β€œApply Patch” without a fresh scan.
Cursor (.cursor/rules) Shared rule block that tells Cursor plans/tasks to run ubs --fail-on-warning . and summarize outstanding issues. Cursor’s autonomous jobs inherit the same QA checklist as humans.
Codex CLI (.codex/rules) Adds the identical rule block for Anthropic’s Codex terminal workflow. Ensures Codex sessions never skip the scanner during long refactors.
Gemini Code Assist (.gemini/rules) Guidance instructing Gemini agents to run ubs before closing a ticket. Keeps Gemini’s asynchronous fixes aligned with UBS exit criteria.
Windsurf (.windsurf/rules) Guardrail text + sample command palette snippet referencing ubs. Windsurf’s multi-step plans stay grounded in the same quality gate.
Cline (.cline/rules) Markdown instructions that Cline’s VS Code extension ingests. Forces every β€œtool call” from Cline to mention scanner findings.
OpenCode MCP (.opencode/rules) Local MCP instructions so HTTP tooling always calls ubs before replying. Makes OpenCode’s multi-agent swarms share the same notion of β€œdone”.

Why This Matters for AI Workflows

When you're coding with AI, you're moving 10-100x faster than traditional development. But bugs accumulate just as quickly. Traditional tools slow you down. This scanner keeps pace:

Traditional workflow:              AI-powered workflow with scanner:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ AI writes code   β”‚              β”‚ AI writes code   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                                 β”‚
         ↓                                 ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ You review       β”‚              β”‚ Scanner runs     β”‚
β”‚ (15 min)         β”‚              β”‚ (3 seconds)      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                                 β”‚
         ↓                                 ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Tests pass?      β”‚              β”‚ Critical bugs?   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚ NO!                              β”‚ YES!
         ↓                                 ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Debug in prod    β”‚              β”‚ AI fixes them    β”‚
β”‚ (6 hours)        β”‚              β”‚ (5 minutes)      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                           ↓
                                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                  β”‚ Ship with         β”‚
                                  β”‚ confidence        β”‚
                                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Total: 6.25 hours                Total: 8 minutes

Pattern 1: Claude Code Integration (Real-Time Scanning)

Drop this into .claude/hooks/on-file-write.sh:

#!/bin/bash
# Auto-scan UBS-supported languages (JS/TS, Python, C/C++, Rust, Go, Java, Ruby) on save

if [[ "$FILE_PATH" =~ \.(js|jsx|ts|tsx|mjs|cjs|py|pyw|pyi|c|cc|cpp|cxx|h|hh|hpp|hxx|rs|go|java|rb)$ ]]; then
  echo "πŸ”¬ Quality check running..."

  if ubs "${PROJECT_DIR}" --ci 2>&1 | head -30; then
    echo "βœ… No critical issues"
  else
    echo "⚠️  Issues detected - review above"
  fi
fi

Result: Every time Claude writes code, the scanner catches bugs instantly.

Pattern 2: Git Pre-Commit Hook (Quality Gate)

The installer can set this up automatically, or add to .git/hooks/pre-commit:

#!/bin/bash
# Block commits with critical bugs

echo "πŸ”¬ Running bug scanner..."

if ! ubs . --fail-on-warning 2>&1 | tee /tmp/scan.txt | tail -30; then
  echo ""
  echo "❌ Critical issues found. Fix them or use: git commit --no-verify"
  echo ""
  echo "Top issues:"
  grep -A 3 "πŸ”₯ CRITICAL" /tmp/scan.txt | head -20
  exit 1
fi

echo "βœ… Quality check passed - committing..."

Result: Bugs cannot be committed. Period.

Pattern 3: Cursor/Windsurf/Continue Integration

Add to your .cursorrules or similar:

## Code Quality Standards

Before marking any task as complete:

1. Run the bug scanner: `ubs .`
2. Fix ALL critical issues (πŸ”₯)
3. Review warnings (⚠️) and fix if trivial
4. Only then mark task complete

If the scanner finds critical issues, your task is NOT done.

Result: AI agents have built-in quality standards.

Pattern 4: CI/CD Pipeline (GitHub Actions Example)

name: Code Quality Gate

on: [push, pull_request]

jobs:
  bug-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Install Bug Scanner
        run: |
          curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_scanner/master/install.sh?$(date +%s)" | bash -s -- --non-interactive

      - name: Scan for Bugs
        run: |
          ubs . --fail-on-warning --ci

Result: Pull requests with critical bugs cannot merge.

Pattern 5: The Fix-Verify Loop (For AI Agents)

This is the golden pattern for AI coding workflows:

#!/bin/bash
# Have your AI agent run this after implementing features

echo "πŸ”¬ Post-implementation quality check..."

# Run scanner
if ubs . --fail-on-warning > /tmp/scan-result.txt 2>&1; then
  echo "βœ… All quality checks passed!"
  echo "πŸ“ Ready to commit"
  exit 0
else
  echo "❌ Issues found:"
  echo ""

  # Show critical issues
  grep -A 5 "πŸ”₯ CRITICAL" /tmp/scan-result.txt | head -30

  echo ""
  echo "πŸ€– AI: Please fix these issues and re-run this check"
  exit 1
fi

Usage pattern:

User: "Add user registration with email validation"

AI Agent:
1. Implements the feature
2. Runs quality check (scanner finds 3 critical bugs)
3. Fixes the bugs
4. Re-runs quality check (passes)
5. Commits the code

Total time: 12 minutes (vs. 6 hours debugging in production)

Pattern 6: The "AI Agent Decision Tree"

Train your AI agent to use this decision tree:

Did I modify code in any supported language?
(JS/TS, Python, Go, Rust, Java, C++, Ruby)
         β”‚
         ↓ YES
Changed more than 50 lines?
         β”‚
         ↓ YES
    Run scanner ←──────────┐
         β”‚                 β”‚
         ↓                 β”‚
Critical issues found? ───── YES
         β”‚ NO              β”‚
         ↓                 β”‚
     Warnings?             β”‚
         β”‚                 β”‚
         ↓ YES             β”‚
  Show to user             β”‚
  Ask if should fix ────────
         β”‚ NO              β”‚
         ↓                 ↓
    Commit code      Fix issues

Important

Copy the blurb below to your project's AGENTS.md, .claude/claude_docs/, or .cursorrules file for comprehensive UBS integration guidance.

## UBS Quick Reference for AI Agents

UBS stands for "Ultimate Bug Scanner": **The AI Coding Agent's Secret Weapon: Flagging Likely Bugs for Fixing Early On**

**Install:** `curl -sSL https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_scanner/main/install.sh | bash`

**Golden Rule:** `ubs <changed-files>` before every commit. Exit 0 = safe. Exit >0 = fix & re-run.

**Commands:**
```bash
ubs file.ts file2.py                    # Specific files (< 1s) β€” USE THIS
ubs $(git diff --name-only --cached)    # Staged files β€” before commit
ubs --only=js,python src/               # Language filter (3-5x faster)
ubs --ci --fail-on-warning .            # CI mode β€” before PR
ubs --help                              # Full command reference
ubs sessions --entries 1                # Tail the latest install session log
ubs .                                   # Whole project (ignores things like .venv and node_modules automatically)
```

**Output Format:**
```
⚠️  Category (N errors)
    file.ts:42:5 – Issue description
    πŸ’‘ Suggested fix
Exit code: 1
```
Parse: `file:line:col` β†’ location | πŸ’‘ β†’ how to fix | Exit 0/1 β†’ pass/fail

**Fix Workflow:**
1. Read finding β†’ category + fix suggestion
2. Navigate `file:line:col` β†’ view context
3. Verify real issue (not false positive)
4. Fix root cause (not symptom)
5. Re-run `ubs <file>` β†’ exit 0
6. Commit

**Speed Critical:** Scope to changed files. `ubs src/file.ts` (< 1s) vs `ubs .` (30s). Never full scan for small edits.

**Bug Severity:**
- **Critical** (always fix): Null safety, XSS/injection, async/await, memory leaks
- **Important** (production): Type narrowing, division-by-zero, resource leaks
- **Contextual** (judgment): TODO/FIXME, console logs

**Anti-Patterns:**
- ❌ Ignore findings β†’ βœ… Investigate each
- ❌ Full scan per edit β†’ βœ… Scope to file
- ❌ Fix symptom (`if (x) { x.y }`) β†’ βœ… Root cause (`x?.y`)

🎬 See It In Action

Examples show JavaScript output; each language has equivalent detections (Python: None checks, Go: nil guards, Rust: Option handling, etc.)

Example 1: Catching a Null Pointer Bug

$ ubs src/

β–“β–“β–“ NULL SAFETY & DEFENSIVE PROGRAMMING
Detects: Null pointer dereferences, missing guards, unsafe property access

  πŸ”₯ CRITICAL (5 found)
    Unguarded property access after getElementById
    Consider: const el = document.getElementById('x'); if (!el) return;

      src/components/form.js:42
        const submitBtn = document.getElementById('submit-button');
        submitBtn.classList.add('active');  // ← Crashes if element missing

      src/utils/dom.js:87
        const modal = document.querySelector('.modal');
        modal.style.display = 'block';  // ← Runtime crash guaranteed

  πŸ’‘ Fix: Always check for null before accessing properties

Before: 3 production crashes this week After: 0 crashes, caught in 2 seconds

Example 2: Security Vulnerability Detection

β–“β–“β–“ SECURITY VULNERABILITIES
Detects: Code injection, XSS, prototype pollution, timing attacks

  πŸ”₯ CRITICAL (3 found)
    innerHTML without sanitization - XSS risk
    Use textContent or DOMPurify.sanitize()

      src/comments.js:156
        element.innerHTML = userComment;  // ← XSS vulnerability!

  πŸ”₯ CRITICAL (1 found)
    Hardcoded API keys detected
    Use environment variables or secret managers

      src/config.js:23
        const apiKey = "sk_live_abc123xyz";  // ← Security breach!

Before: Security incident, customer data at risk After: Vulnerability caught before git commit

Example 3: Async/Await Gotchas

β–“β–“β–“ ASYNC/AWAIT & PROMISE PITFALLS
Detects: Missing await, unhandled rejections, race conditions

  πŸ”₯ CRITICAL (8 found)
    await used in non-async function
    SyntaxError in JavaScript

      src/api/users.js:67
        function saveUser(data) {
          await database.insert(data);  // ← SyntaxError!
        }

  ⚠️  WARNING (12 found)
    Promises without .catch() or try/catch
    Unhandled rejections crash Node.js

      src/services/email.js:45
        sendEmail(user.email).then(result => ...)  // ← No error handling!

Before: Silent failures, mysterious bugs in production After: All async bugs caught and fixed before deploy


πŸ“‹ What It Detects (The Complete Arsenal)

Each language module has specialized detections. Examples below are representative (JavaScript shown; Python has eval(), Go has goroutine leaks, Rust has .unwrap() panics, C++ has buffer overflows, etc.)

πŸ”΄ Critical Issues (Production Blockers)

These WILL cause crashes, security breaches, or data corruption:

Pattern Example Why It's Dangerous
eval() usage eval(userInput) Allows arbitrary code execution - RCE vulnerability
Direct NaN comparison if (x === NaN) Always returns false - logic bug
Missing await asyncFunc() in async context Silent failures, race conditions - data corruption
Prototype pollution obj.__proto__ = {} Security vulnerability - privilege escalation
Unguarded null access el.style.color without null check Runtime crash guaranteed
parseInt without radix parseInt("08") Returns 0 in some browsers - calculation bug
Empty catch blocks catch(e) {} Swallows errors - debugging nightmare
innerHTML with user data el.innerHTML = userInput XSS vulnerability
Missing async keyword await without async function SyntaxError
Hardcoded secrets const key = "sk_live..." Security breach

🟑 Warnings (Should Fix Before Shipping)

These cause bugs, performance issues, or maintenance headaches:

Pattern Example Impact
Promises without .catch() promise.then(...) Unhandled rejections crash Node.js
Division without zero check total / count Returns Infinity or NaN
Event listeners without cleanup addEventListener in React Memory leak (app gets slower over time)
setInterval without clear setInterval(fn, 1000) Timer leak (infinite timers)
await inside loops for(...) { await api.call() } Slow (sequential, not parallel)
Array mutation during iteration arr.forEach(() => arr.push(...)) Skipped/duplicate elements
Missing switch default switch(x) { case 1: ... } Unhandled values cause silent failures
isNaN() instead of Number.isNaN() isNaN("foo") Type coercion bugs

πŸ”΅ Info (Code Quality & Best Practices)

Improvements that make code cleaner and more maintainable:

  • Optional chaining opportunities (obj?.prop?.value)
  • Nullish coalescing opportunities (value ?? default)
  • TypeScript any usage (reduces type safety)
  • console.log statements (remove before production)
  • Technical debt markers (TODO, FIXME, HACK)
  • Performance optimizations (DOM queries in loops)
  • var usage (use let/const instead)
  • Deep property access without guards
  • Large inline arrays (move to separate files)
  • Complex nested ternaries (readability)

βš™οΈ Advanced Configuration

Command-Line Options (Full Reference)

ubs [OPTIONS] [PROJECT_DIR] [OUTPUT_FILE]

Core Options:
  -v, --verbose            Show 10 code samples per finding (default: 3)
  -q, --quiet              Minimal output (summary only)
  --ci                     CI mode (stable output, no colors by default)
  --fail-on-warning        Exit with code 1 on warnings (strict mode)
  --version                Print UBS meta-runner version and exit
  --profile=MODE           strict|loose (sets defaults for strictness)
  --baseline=FILE          Compare findings against a baseline JSON (alias for --comparison)
  -h, --help               Show help and exit

Git Integration:
  --staged                 Scan only files staged for commit
  --diff, --git-diff       Scan only modified files (working tree vs HEAD)

Output Control:
  --format=FMT             Output format: text|json|jsonl|sarif (default: text)
  --beads-jsonl=FILE      Write JSONL summary alongside normal output for Beads/"strung"
  --no-color               Force disable ANSI colors
  OUTPUT_FILE              Save report to file (auto-tees to stdout)

File Selection:
  --include-ext=CSV        File extensions (default: auto-detect by language)
                           JS: js,jsx,ts,tsx,mjs,cjs | Python: py,pyi,pyx
                           Go: go | Rust: rs | Java: java | C++: cpp,cc,cxx,c,h
                           Ruby: rb,rake,ru | Custom: --include-ext=js,ts,vue
  --exclude=GLOB[,...]     Additional paths to exclude (comma-separated)
                           Example: --exclude=legacy (deps ignored by default)

Performance:
  --jobs=N                 Parallel jobs for ripgrep (default: auto-detect cores)
                           Set to 1 for deterministic output

Rule Control:
  --skip=CSV               Skip categories by number (see output for numbers)
                           Example: --skip=11,14  # Skip debug code + TODOs
  --skip-type-narrowing    Disable tsserver-based guard analysis (falls back to text heuristics)
  --rules=DIR              Additional ast-grep rules directory
                           Rules are merged with built-in rules
  --no-auto-update         Disable automatic self-update
  --suggest-ignore         Print large-directory candidates to add to .ubsignore (no changes applied)

Environment Variables:
  JOBS                     Same as --jobs=N
  NO_COLOR                 Disable colors (respects standard)
  CI                       Enable CI mode automatically

Arguments:
  PROJECT_DIR              Directory to scan (default: current directory)
  OUTPUT_FILE              Save full report to file

Exit Codes:
  0                        No critical issues (or no issues at all)
  1                        Critical issues found
  1                        Warnings found (only with --fail-on-warning)
  2                        Invalid arguments or configuration

Examples

# Basic scan
ubs .

# Verbose scan with full details
ubs -v /path/to/project

# Strict mode for CI (fail on any warning)
ubs --fail-on-warning --ci

# Save report without cluttering terminal
ubs . report.txt

# Scan Vue.js project
ubs . --include-ext=js,ts,vue

# Skip categories you don't care about
ubs . --skip=14  # Skip TODO/FIXME markers

# Maximum performance (use all cores)
ubs --jobs=0 .  # Auto-detect
ubs --jobs=16 .  # Explicit core count

# Exclude vendor code
ubs . --exclude=node_modules,vendor,dist,build

# Custom rules directory
ubs . --rules=~/.config/ubs/custom-rules

# Combine multiple options
ubs -v --fail-on-warning --exclude=legacy --include-ext=js,ts,tsx . report.txt

JSONL schema

--format=jsonl (and --beads-jsonl=FILE) emit newline-delimited objects for easy piping into tools like Beads or jq:

{"type":"scanner","project":"/path/to/project","language":"python","files":42,"critical":1,"warning":3,"info":12,"timestamp":"2025-11-22T09:04:20Z"}
{"type":"totals","project":"/path/to/project","files":99,"critical":1,"warning":3,"info":27,"timestamp":"2025-11-22T09:04:22Z"}

Custom AST-Grep Rules

You can add your own bug detection patterns:

# Create custom rules directory
mkdir -p ~/.config/ubs/rules

# Add a custom rule (YAML format)
cat > ~/.config/ubs/rules/no-console-in-prod.yml <<'EOF'
id: custom.no-console-in-prod
language: javascript
rule:
  any:
    - pattern: console.log($$$)
    - pattern: console.debug($$$)
    - pattern: console.info($$$)
severity: warning
message: "console statements should be removed before production"
note: "Use a proper logging library or remove debug statements"
EOF

# Run with custom rules
ubs . --rules=~/.config/ubs/rules

Common custom rules:

# Enforce specific naming conventions
id: custom.component-naming
language: typescript
rule:
  pattern: export function $NAME() { $$$ }
  not:
    pattern: export function $UPPER() { $$$ }
severity: info
message: "React components should start with uppercase letter"
# Catch specific anti-patterns in your codebase
id: custom.no-direct-state-mutation
language: typescript
rule:
  pattern: this.state.$FIELD = $VALUE
severity: critical
message: "Never mutate state directly - use setState()"

Excluding False Positives

If the scanner reports false positives for your specific use case:

# Skip entire categories
ubs . --skip=11,14  # Skip debug code detection and TODO markers

# Exclude specific files/directories
ubs . --exclude=legacy,third-party,generated

# For persistent config, create a wrapper script
cat > ~/bin/ubs-custom <<'EOF'
#!/bin/bash
ubs "$@" \
  --exclude=legacy,generated \
  --skip=14 \
  --rules=~/.config/ubs/rules
EOF
chmod +x ~/bin/ubs-custom

πŸŽ“ How It Works (Under the Hood)

Multi-Layer Analysis Engine

The scanner uses a sophisticated 4-layer approach:

Layer 1: PATTERN MATCHING (Fast) ──┐
β”œβ”€ Regex-based detection           β”‚
β”œβ”€ Optimized with ripgrep          β”‚
└─ Finds 70% of bugs in <1 second  β”‚
                                    β”œβ”€β”€β–Ί Combined Results
Layer 2: AST ANALYSIS (Deep) ───────
β”œβ”€ Semantic code understanding      β”‚
β”œβ”€ Powered by ast-grep             β”‚
└─ Catches complex patterns        β”‚
                                    β”‚
Layer 3: CONTEXT AWARENESS (Smart) ─
β”œβ”€ Understands surrounding code     β”‚
β”œβ”€ Reduces false positives         β”‚
└─ Knows when rules don't apply    β”‚
                                    β”‚
Layer 4: STATISTICAL (Insightful)  β”‚
β”œβ”€ Code smell detection            β”‚
β”œβ”€ Anomaly identification          β”‚
└─ Architectural suggestions       β”‚
                                    ↓
                         Final Report (3-5 sec)

Technology Stack

Component Technology Purpose Why This Choice
Core Engine Bash 4.0+ Orchestration Universal compatibility, zero dependencies
Pattern Matching Ripgrep Text search 10-100x faster than grep, parallelized
AST Parser ast-grep Semantic analysis Understands code structure, not just text
Fallback GNU grep Text search Works on any Unix-like system
Rule Engine YAML Pattern definitions Human-readable, easy to extend

Performance Optimizations

# Automatic parallelization (uses all CPU cores)
- Auto-detects: 16-core = 16 parallel jobs
- Manually set: --jobs=N

# Smart file filtering (only scans relevant files)
- JS/TS: .js, .jsx, .ts, .tsx, .mjs, .cjs (auto-skip node_modules/dist/build)
- Python: .py + pyproject/requirements (skip venv/__pycache__)
- C/C++: .c/.cc/.cpp/.cxx + headers + CMake files (skip build/out)
- Rust: .rs + Cargo manifests (skip target/.cargo)
- Go: .go + go.mod/go.sum/go.work (skip vendor/bin)
- Java: .java + pom.xml + Gradle scripts (skip target/build/out)
- Ruby: .rb + Gemfile/Gemspec/Rakefile (skip vendor/bundle,tmp)
- Custom: --include-ext=js,ts,vue

# Efficient streaming (low memory usage)
- No temp files created
- Results streamed as found
- Memory usage: <100MB for most projects

# Incremental scanning (future feature)
- Only scan changed files (git diff)
- Cache previous results
- 10x faster on large projects

πŸ† Comparison with Other Tools

Feature Ultimate Bug Scanner ESLint TypeScript SonarQube DeepCode
Setup Time 30 seconds 30 minutes 1-2 hours 2-4 hours Account required
Speed (50K lines) 3 seconds 15 seconds 8 seconds 2 minutes Cloud upload
Zero Config βœ… Yes ❌ No ❌ No ❌ No ❌ No
Works Without Types βœ… Yes βœ… Yes ❌ No βœ… Yes βœ… Yes
Null Safety βœ… Yes ⚠️ Limited βœ… Yes ⚠️ Limited ⚠️ Limited
Security Scanning βœ… Yes ⚠️ Plugin ❌ No βœ… Yes βœ… Yes
Memory Leaks βœ… Yes ❌ No ❌ No ⚠️ Limited ❌ No
Async/Await βœ… Deep ⚠️ Basic βœ… Good ⚠️ Basic ⚠️ Basic
CI/CD Ready βœ… Yes βœ… Yes βœ… Yes βœ… Yes ⚠️ Cloud
Offline βœ… Yes βœ… Yes βœ… Yes ⚠️ Limited ❌ No
AI Agent Friendly βœ… Built for it ⚠️ Config heavy ⚠️ Config heavy ❌ Complex ⚠️ Cloud
Cost Free Free Free $$$$ $$$

When to use what:

  • Ultimate Bug Scanner: Quick scans, AI workflows, no config needed
  • ESLint: Style enforcement, custom rules, team standards
  • TypeScript: Type safety (use WITH this scanner)
  • SonarQube: Enterprise compliance, detailed metrics
  • DeepCode: ML-powered analysis (if you trust cloud)

Best combo: TypeScript + ESLint + Ultimate Bug Scanner = Maximum safety


🧠 Project Justification and Rationale

Why This Exists (And Why It's Not "Just Another Linter")

You might be thinking: "We already have ESLint, Pylint, Clippy, RuboCop... why build another tool?"

Fair question. And honestly, your first reaction is probably right to be skeptical.

The Initial Skepticism is Valid (But Misses the Point)

When you first look at UBS, it's natural to think:

"This is just worse ESLint. It has fewer rules, uses regex (false positives!), and doesn't auto-fix anything. Why would I use this instead of mature, comprehensive linters?"

That's analyzing through the wrong lens.

You're comparing it to tools designed for a fundamentally different workflow (human developers writing code manually) when it's solving a fundamentally different problem (LLM agents generating code at 100x speed).

It's like comparing a smoke detector to a building inspector:

  • Building inspector (ESLint): Thorough, comprehensive, finds every issue, takes hours
  • Smoke detector (UBS): Fast, catches critical dangers, instant alert, always running

You need both. But when your house might be on fire (AI just generated 500 lines in 30 seconds), you want the smoke detector first.

The Paradigm Shift: AI-Native Development

Software development is undergoing a fundamental transformation:

2020 (Pre-LLM Era):

  • Developer writes 50-200 lines/day manually
  • Deep thought before each line
  • Single language per project (mostly)
  • Time to review: abundant
  • Quality gate: comprehensive linting + code review (hours)

2025 (LLM Era):

  • AI generates 500-5000 lines/day across projects
  • Code appears in seconds
  • Polyglot projects standard (microservices in Go, UI in TypeScript, ML in Python, workers in Rust)
  • Time to review: scarce
  • Quality gate needed: instant feedback (<5s) or the loop breaks

Traditional tools weren't designed for this. They were built when "code generation" meant 200 lines/day, not 2000.

Here's the Fundamental Difference:

1. This Tool is Built FOR AI Agents, Not Just Humans

Traditional linters were designed for human developers in single-language codebases. UBS is designed for LLM coding agents working across polyglot projects.

The paradigm shift:

Traditional Linting (Human-First) UBS Approach (LLM-First)
Goal: Comprehensive coverage + auto-fix
Speed: 15-60 seconds acceptable
Setup: 30 min config per language
Languages: One tool per language
False positives: Must be <1% (frustrates humans)
Output: Human-readable prose
Goal: Critical bug detection + fast feedback
Speed: <5 seconds required
Setup: Zero config (instant start)
Languages: One scan for all 7 languages
False positives: 10-20% OK (LLMs filter instantly)
Output: Structured file:line for LLM parsing

2. LLMs Don't Need Auto-Fixβ€”They ARE the Auto-Fix Engine

Why traditional linters have auto-fix:

// ESLint flags: "Use === instead of =="
if (value == null)  // ❌

// ESLint auto-fix (rigid, no context):
if (value === null)  // βœ… Technically correct, but...

Why UBS doesn't (and shouldn't):

// UBS flags: "Type coercion bug: == should be ==="
if (value == null)  // ❌

// Claude reads the error and understands context:
if (value !== null && value !== undefined)  // βœ… Better - handles both
// OR
if (value != null)  // βœ… Or keeps == for null/undefined (intentional)

The hard part is DETECTION, not fixing. Once flagged, LLMs can:

  • Understand semantic context
  • Consider surrounding code
  • Apply the right fix (not just the mechanical one)
  • Refactor holistically

Auto-fix would be worse because it's context-free. LLMs need to know WHAT'S wrong and WHERE, then they fix it properly.

3. The Multi-Language Zero-Config Design is the Moat

Imagine asking Claude to set up quality gates for a polyglot project:

Traditional approach (15-30 min per project):

# JavaScript/TypeScript
npm install --save-dev eslint @eslint/js @typescript-eslint/parser
# Create .eslintrc.js (200 lines of config)

# Python
pip install pylint black mypy
# Create .pylintrc, pyproject.toml sections

# Rust
# Add to Cargo.toml: [lints]
# Configure clippy rules

# Go
# Install golangci-lint, create .golangci.yml

# Java
# Setup Checkstyle + PMD + SpotBugs + config XMLs

# C++
# Setup clang-tidy, create .clang-tidy config

# Ruby
# Create .rubocop.yml with 150+ lines

# Now run 7 different commands and parse 7 different output formats...

UBS approach (30 seconds):

curl -fsSL https://raw.githubusercontent.com/.../install.sh | bash
ubs .

# Done. All 7 languages scanned, unified report.

This matters because:

  • LLMs generate code across languages in one session (Python API β†’ Go service β†’ TypeScript UI β†’ Rust worker)
  • Configuring 7 tools is error-prone for LLMs
  • Humans don't want to maintain 7 different config files
  • CI/CD pipelines want one command, one exit code

Type Narrowing Coverage Across Languages

  • TypeScript – UBS shells out to tsserver (via the bundled helper) whenever Node.js + the typescript package are available. The installer surfaces a "Type narrowing readiness" diagnostic so you immediately know if tsserver-powered guards are running.
  • Rust – A Python helper inspects if let Some/Ok guard clauses and flags subsequent .unwrap()/.expect() calls outside of exiting blocks. Fixtures and manifest cases keep this regression-tested.
  • Kotlin – The Java module scans .kt sources for if (value == null) guards that merely log and keep running before hitting value!!, catching the same pitfall on JVM teams that mix Java + Kotlin.
  • Swift – The dedicated ubs-swift module now ships the guard-let helper directly, so optional chaining/Objective‑C bridging heuristics fire even when you run ubs --only=swift locally (no piggybacking on the Java module). It catches cases where code logs and keeps going before force-unwrapping value!, protecting iOS/macOS pipelines that blend Swift + ObjC.

Resource Lifecycle AST Coverage

  • Python – modules/helpers/resource_lifecycle_py.py now reasons over the AST, tracking with/async with, alias imports, and .open()/.connect() calls so ubs-python warns only when a handle is truly leaking. Pathlib Path.open() and similar patterns are handled without brittle regexes.
  • Java – New ast-grep rules (java.resource.executor-no-shutdown, java.resource.thread-no-join, java.resource.jdbc-no-close, java.resource.resultset-no-close, java.resource.statement-no-close) ensure ExecutorServices, raw Threads, java.sql.Connections, Statement/PreparedStatement/CallableStatement, and ResultSet handles all get proper shutdown/close semantics before the regex fallback ever runs.
  • C++ / Rust / Ruby – These modules already relied on ast-grep rule packs; the β€œUniversal AST Adoption” epic is now complete with every language module (JS, Python, Go, C++, Rust, Java, Ruby, Swift, Kotlin) running semantic detectors instead of fragile grep-only heuristics.

Python – AST helper in action

import asyncio, subprocess

fh = open("/tmp/leaky.txt", "w")
proc = subprocess.Popen(["sleep", "1"])

async def leak_task():
    task = asyncio.create_task(asyncio.sleep(1))
    await asyncio.sleep(0.1)
    return task

asyncio.run(leak_task())
$ ./ubs --only=python test-suite/python/buggy/resource_lifecycle.py
  πŸ”₯ File handles opened without context manager/close [resource_lifecycle.py:4]
    File handle fh opened without context manager or close()
  ⚠ Popen handles not waited or terminated [resource_lifecycle.py:7]

The helper catches the unguarded file handle, zombie subprocess, and orphaned asyncio task because it walks the AST (tracking aliases and async contexts) instead of grepping for strings.

Go – AST helper validating cleanups

ctx, cancel := context.WithTimeout(context.Background(), time.Second)
ticker := time.NewTicker(time.Millisecond * 500)
timer := time.NewTimer(time.Second)
f, _ := os.Open("/tmp/data.txt")

_ = ctx
_ = cancel
_ = ticker
_ = timer
_ = f
$ ./ubs --only=golang test-suite/golang/buggy/resource_lifecycle.go
  πŸ”₯ context.With* without deferred cancel [resource_lifecycle.go:10]
  ⚠ time.NewTicker not stopped [resource_lifecycle.go:13]
  ⚠ time.NewTimer not stopped [resource_lifecycle.go:15]
  ⚠ os.Open/OpenFile without defer Close() [resource_lifecycle.go:17]

Because the helper hashes AST positions, the manifest can assert on deterministic substrings (context/ticker/timer/file) and we avoid flakiness from color codes or log headings.

Use --skip-type-narrowing (or UBS_SKIP_TYPE_NARROWING=1) when you want to bypass all of these guard analyzersβ€”for example on air-gapped CI environments or when validating legacy projects one language at a time.

4. Speed Enables Tight Iteration Loops

The generate β†’ scan β†’ fix cycle needs to be fast for AI workflows:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Traditional Linter (30-45 seconds)     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Claude generates code:        10s      β”‚
β”‚  Run ESLint + Pylint + ...     30s  ⏳  β”‚
β”‚  Claude reads findings:         5s      β”‚
β”‚  Claude fixes bugs:            15s      β”‚
β”‚  Re-run linters:               30s  ⏳  β”‚
β”‚  ──────────────────────────────────     β”‚
β”‚  Total iteration:              90s      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  UBS (3-5 seconds)                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Claude generates code:        10s      β”‚
β”‚  Run UBS:                       3s  ⚑  β”‚
β”‚  Claude reads findings:         2s      β”‚
β”‚  Claude fixes bugs:            10s      β”‚
β”‚  Re-run UBS:                    3s  ⚑  β”‚
β”‚  ──────────────────────────────────     β”‚
β”‚  Total iteration:              28s      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

3x faster feedback loop = 3x more iterations in the same time

When you're shipping 10+ features a day with AI assistance, this compounds.

5. Detecting LLM-Specific Bug Patterns

UBS targets the bugs AI agents actually generate, not every possible code smell.

Bugs LLMs frequently produce:

Pattern Why LLMs Generate It Traditional Linters
Missing await Forgets async keyword, syntax looks fine ❌ TypeScript only
Unguarded null access "Optimistic" coding - assumes happy path ⚠️ Requires strict config
eval() / code injection Reaches for "easy" dynamic solution βœ… Most flag this
Memory leaks (event listeners) Doesn't think about cleanup lifecycle ❌ ESLint plugin needed
innerHTML XSS Doesn't threat-model user input ⚠️ Security plugins only
Division by zero Doesn't consider edge cases ❌ Most miss this
Hardcoded secrets Uses placeholder, forgets to externalize ⚠️ Requires secrets scanner
Goroutine leaks Forgets context cancellation ❌ Go-specific tooling
.unwrap() panics Assumes success path βœ… Clippy catches
Buffer overflows Forgets bounds checking ⚠️ Sanitizers only

UBS is optimized for this specific threat model.

6. Novel Analysis: Deep Property Guard Correlation

This is genuinely not available in standard linters:

# Code LLM generates:
def get_theme(user):
    return user.profile.settings.theme  # ❌ Unguarded chain

# ESLint/Pylint: βœ… No error (syntactically correct)
# TypeScript: βœ… No error (if types claim non-null)

# UBS Deep Guard Analysis:
# 1. Scans for: user.profile.settings.theme (found at line 42)
# 2. Scans for: if user and user.profile and user.profile.settings
# 3. Correlates: NO MATCHING GUARD FOUND
# 4. Reports: ⚠️ Unguarded deep property access

This requires:

  • AST extraction of property chains across the file
  • AST extraction of conditional guards
  • Cross-reference matching with context awareness
  • Contextual suggestions

Nobody else does this by default because it's not a lint ruleβ€”it's a correlation analysis across multiple code patterns.

7. Complementary, Not Competitive

UBS is designed to work WITH existing tools, not replace them:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Your Quality Stack (Recommended)                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  TypeScript           β†’ Type safety                β”‚
β”‚  ESLint/Clippy/etc    β†’ Comprehensive linting      β”‚
β”‚  Jest/PyTest          β†’ Unit tests                 β”‚
β”‚  ✨ UBS                β†’ AI-generated bug oracle   β”‚
β”‚  GitHub Actions       β†’ CI/CD integration          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Use UBS for:

  • βœ… Fast multi-language scanning in AI workflows
  • βœ… Critical bug detection before commits
  • βœ… Git hooks that block obviously broken code
  • βœ… Claude/Cursor/AI agent quality guardrails
  • βœ… Polyglot projects where configuring 7 linters is painful

Use ESLint/Pylint/Clippy/etc for:

  • βœ… Comprehensive style enforcement
  • βœ… Framework-specific rules (React hooks, etc.)
  • βœ… Custom team conventions
  • βœ… Auto-formatting
  • βœ… Deep single-language analysis

They solve different problems. UBS is the "smoke detector" (fast, catches critical issues). Traditional linters are the "building inspector" (thorough, catches everything).

8. The Technical Moat

What makes this hard to replicate:

Multi-layer analysis:

Layer 1: Ripgrep (regex)     β†’ 70% of bugs in 0.5s
Layer 2: ast-grep (AST)      β†’ Complex semantic patterns
Layer 3: Correlation logic   β†’ Cross-pattern analysis (novel)
Layer 4: Metrics collection  β†’ Time-series quality tracking

This combination of speed + semantic understanding + correlation is unique.

Unified multi-language runner:

  • Auto-detects 7 languages in one scan
  • Parallel execution (Go + Python + Rust simultaneously)
  • Unified JSON/SARIF output for tooling
  • Module system with lazy download/caching

LLM-optimized integration points:

  • Git hooks (block bad commits)
  • Claude Code file-write hooks
  • .cursorrules / .aiconfig integration
  • Clean structured output for LLM parsing

9. 30 Rules is Better Than 600 (For This Use Case)

You might notice: ESLint has 200+ core rules, Clippy has 600+ lints, but UBS has ~30 patterns per language.

That's intentional, not a limitation.

The 80/20 rule for AI-generated bugs:

  • 80% of production-breaking bugs come from ~30 common patterns
  • 20% of edge cases require the other 570 rules

For LLM workflows, you want:

βœ… Fast scan (3s) that catches 80% of critical bugs
   ↓
   LLM fixes them immediately
   ↓
   βœ… Fast re-scan (3s) confirms fixes
   ↓
   Then run comprehensive linters (30s) for the remaining 20%

Not:

❌ Comprehensive scan (30s) that catches 100% of issues
   ↓
   LLM waits... workflow broken... context switch...
   ↓
   Slower iteration = fewer features shipped

The bugs UBS targets are:

  • Missing await (crashes)
  • Null pointer access (crashes)
  • Security holes: eval(), XSS, hardcoded secrets (breaches)
  • Memory leaks (performance degradation)
  • Race conditions (data corruption)

The bugs comprehensive linters add:

  • Inconsistent quote style (style)
  • Missing trailing commas (style)
  • Prefer const over let when not reassigned (style)
  • Function name should be camelCase (style)
  • Line too long (style)

Which matters more when AI just generated 500 lines that might have eval() and missing await everywhere?

Target the critical bugs that cost hours. Let comprehensive linters handle style in a separate pass.

10. Market Timing: This Wouldn't Have Made Sense 3 Years Ago

Why this tool exists NOW:

2021:

  • GitHub Copilot launches (single-line completions)
  • Still mostly human-written code
  • Traditional linting workflow works fine

2023:

  • ChatGPT/GPT-4 can generate full functions
  • Claude Code, Cursor emerge
  • Devs start AI-assisted workflows
  • Pain point appears: "AI is fast but buggy"

2025:

  • LLMs generate entire features in minutes
  • Multi-file refactors happen in seconds
  • Polyglot microservices are standard
  • Quality gates can't keep up with generation speed

The problem UBS solves didn't exist before LLM coding became mainstream.

This tool is perfectly timed for the AI coding explosion happening RIGHT NOW.

11. False Positive Philosophy

For human developers:

  • False positive = context switch + investigation + frustration
  • Acceptable rate: <1%

For LLM agents:

  • False positive = parse (0.1s) + analyze (0.5s) + determine safe (0.2s)
  • Acceptable rate: 10-20%

LLMs don't get frustrated. They evaluate every finding programmatically.

This means UBS can be more aggressive:

  • Flag suspicious patterns even if not 100% certain
  • Catch more bugs at the cost of some noise
  • LLMs filter false positives cognitively (for free)

Better to flag 100 issues where 20 are safe than miss 1 critical bug.


FAQ: Common Questions and Objections

Q: "Isn't this just reinventing the wheel? ESLint already exists."

A: It's not reinventing the wheelβ€”it's building a different vehicle for a different road.

ESLint is a truck (heavy, comprehensive, hauls everything). UBS is a sports car (fast, targeted, gets you there quickly).

You wouldn't use a truck for a Formula 1 race. You wouldn't use a sports car to move furniture.

Different tools, different use cases. Use UBS for rapid AI iteration, ESLint for comprehensive quality enforcement.


Q: "Why not just contribute these patterns to existing linters?"

A: Three reasons:

1. Different design philosophy

  • Existing linters: comprehensive, human-first, single-language
  • UBS: fast, LLM-first, multi-language, correlation-based

These are fundamentally incompatible goals. ESLint would never accept "10-20% false positives are fine" or "skip auto-fix entirely."

2. Multi-language meta-runner

  • The unified runner that auto-detects 7 languages is the core innovation
  • This doesn't fit into any single linter's architecture
  • Each linter project has different maintainers, philosophies, release cycles

3. Correlation analysis is novel

  • Deep property guard matching isn't a "lint rule"
  • It's cross-pattern analysis that requires a different architecture
  • Existing linters don't have this capability baked into their core

Contributing patterns misses the pointβ€”the integration IS the innovation.


Q: "What about Semgrep? Doesn't it do multi-language pattern matching?"

A: Semgrep is excellent and closer to UBS than traditional linters. Key differences:

Feature Semgrep UBS
Setup Requires config file + rule selection Zero config
Speed ~10-20s on medium projects ~3s (optimized for speed)
Target user Security teams, human developers LLM agents
Rule focus Security + custom patterns AI-generated bug patterns
Multi-language βœ… Yes βœ… Yes
Correlation analysis ❌ Pattern matching only βœ… Deep guards, metrics
LLM integration Not designed for it Purpose-built

Use Semgrep if: You need custom security rules and have time to configure them. Use UBS if: You want instant AI workflow integration with zero setup.

They're complementary. Some users run both.


Q: "Won't regex-based detection have tons of false positives?"

A: Less than you'd think, and it's acceptable for LLM consumers.

Reality check:

  • Layer 1 (ripgrep/regex): ~15-20% false positive rate on some patterns
  • Layer 2 (ast-grep/AST): ~2-5% false positive rate (semantic understanding)
  • Layer 3 (correlation): ~1-3% false positive rate (contextual analysis)

Blended approach: ~8-12% overall false positive rate.

Why this is OK:

  • LLMs don't get frustrated like humans do
  • They evaluate findings in 0.8 seconds total
  • Better to flag 100 (20 safe) than miss 1 critical bug
  • Humans reviewing AI code ALREADY have to check everything anyway

For critical patterns (eval, XSS, hardcoded secrets), we use ast-grep (high precision). For style patterns, we use regex (fast, some FP acceptable).

And we're always improving. Each release reduces FP rate through better heuristics.


Q: "Why Bash? Why not Python/Rust/Go?"

A: Controversial choice, but intentional:

Advantages of Bash:

  • βœ… Zero dependencies - runs on any Unix-like system
  • βœ… Universal availability - every dev machine has Bash 4.0+
  • βœ… Shell integration - git hooks, CI/CD, file watchers are natural
  • βœ… Module system - each language scanner is standalone
  • βœ… Rapid prototyping - adding new patterns is trivial
  • βœ… LLM-readable - AI agents can understand and modify rules

Disadvantages:

  • ❌ Not as "elegant" as Python
  • ❌ String handling can be verbose
  • ❌ No static typing

Bottom line: For a tool that orchestrates existing CLI tools (ripgrep, ast-grep, jq, typos) and needs to be universally available, Bash is pragmatic.

Future: Core modules might be rewritten in Rust for speed, but the meta-runner will stay Bash for compatibility.


Q: "Can I use this if I'm NOT using AI coding tools?"

A: Absolutely! It's optimized for AI workflows, but works great for humans too.

Scenarios where humans love it:

1. Code review speed-up

# Reviewing a PR with 800+ lines
git checkout feature-branch
ubs .
# Instantly see critical issues before deep review

2. Legacy code audits

# "What's dangerous in this 10-year-old codebase?"
ubs /path/to/legacy-app
# Finds all the eval(), XSS, memory leaks

3. Learning new languages

# "I'm new to Rust, what am I doing wrong?"
ubs . --verbose
# Shows common Rust pitfalls in your code

4. Polyglot projects

# Microservices in 5 languages
ubs .
# One scan, all languages checked

Humans appreciate:

  • Zero setup (no config files to maintain)
  • Fast feedback (3s vs 30s)
  • Multi-language support (one command)
  • Finding bugs ESLint misses (deep guards)

Q: "How is this different from security scanners like Snyk or GitHub Advanced Security?"

A: Different focus and scope:

Security scanners (Snyk, Dependabot, etc.):

  • Focus: Dependency vulnerabilities
  • Checks: npm packages, CVE databases
  • Speed: Seconds to minutes
  • Output: "Update package X to fix CVE-2024-1234"

UBS:

  • Focus: Code-level bugs in YOUR code
  • Checks: Logic errors, null safety, memory leaks, security anti-patterns
  • Speed: 3-5 seconds
  • Output: "You have unguarded null access at line 42"

They're complementary:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Complete Security Stack            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Snyk/Dependabot  β†’ Dependencies    β”‚
β”‚  ✨ UBS            β†’ Your code bugs β”‚
β”‚  SAST tools       β†’ Deep security   β”‚
β”‚  GitHub Advanced  β†’ Secrets in Git  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Security scanners won't catch: "You forgot await and your async function silently fails." UBS won't catch: "Your version of lodash has a known CVE."

Use both.


Q: "Will you support language X in the future?"

A: Probably! The module system makes it easy to add languages.

Current: JavaScript/TypeScript, Python, Go, Rust, Java, C++, Ruby (7 languages)

Roadmap considerations:

  • PHP - High demand, lots of legacy code
  • Swift - iOS development
  • Kotlin - Android development
  • Scala - JVM ecosystem
  • Elixir - Growing adoption

How we prioritize:

  1. Community demand (GitHub issues)
  2. AI coding tool usage (what LLMs generate most)
  3. Module maintainer availability

Want to contribute? Writing a new module is ~800-1200 lines of Bash. Check the existing modules as templates.


Q: "What's the catch? Why is this free?"

A: No catch. It's MIT licensed.

Philosophy:

  • Built by developers, for developers
  • AI coding is exploding, quality tools should be accessible
  • Open source enables community contributions (more patterns, better detection)

Business model: None currently. This is a community project.

Future possibilities:

  • Enterprise support contracts
  • Hosted version for teams
  • Premium modules for specific frameworks

But the core tool will always be free and open source.


The Bottom Line

This isn't trying to replace ESLint. It's solving a different problem:

"How do I give LLM coding agents the ability to self-audit across 7 languages with zero configuration overhead and sub-5-second feedback?"

No existing tool does this because:

  • Traditional linters are human-first (need auto-fix, low FP tolerance)
  • They're single-language focused (polyglot = 7 different tools)
  • They're comprehensive, not fast (30s scan time kills AI iteration loops)
  • They're not designed for LLM consumption

UBS is purpose-built for the AI coding era.

Use it WITH your existing tools. Let ESLint handle style. Let TypeScript handle types. Let UBS catch the critical bugs that AI agents generate but can't see.


πŸ§ͺ Development & Internals

Python Tooling (uv + CPython 3.13)

All helper scripts (manifest runner, fixtures, inline analyzers inside ubs) assume a single source of truth: CPython 3.13 managed by uv living inside .venv/ at the repo root.

# 1) Install uv (one-time)
curl -LsSf https://astral.sh/uv/install.sh | sh

# 2) Create the managed environment defined by pyproject.toml / uv.lock
uv sync --python 3.13

# 3) Activate it whenever you work in this repo (puts .venv/bin first on PATH)
source .venv/bin/activate

# 4) Run any Python entrypoint through the env
uv run python test-suite/run_manifest.py --case js-core-buggy
# ...or rely on 'python'/'python3' now that they point at .venv/bin/python3.13

Note

Shell scripts that invoke python3 (language modules under modules/, test-suite/run_all.sh, etc.) automatically pick up .venv/bin/python3 as long as the environment is activated or .venv/bin is on your PATH. The pinned pyproject.toml + uv.lock are the single source of truth for this toolchain.

Common uv-powered entrypoints:

  • uv run python test-suite/run_manifest.py --case js-core-buggy – run the manifest in CI or locally without manually activating the venv.
  • source .venv/bin/activate && python -m pip list – verify that every inline python3 invocation maps to CPython 3.13.
  • uv run python - <<'PY' … – mirrors how the language modules embed Python helpers, but now guaranteed to execute inside the managed interpreter.

🚫 Ignoring Paths with .ubsignore

Need repo-wide scans to ignore generated code or intentionally buggy fixtures (like this project’s test-suite/)? Drop a .ubsignore at the root.

  • Format mirrors .gitignore: one glob per line, # for comments.
  • UBS loads PROJECT/.ubsignore automatically; override with --ignore-file=/path/to/file.
  • Built-in ignores already cover node_modules, virtualenvs, dist/build/target/vendor, editor caches, and more, so you rarely need to add them yourself.
  • Use --suggest-ignore to print large top-level directories that might deserve an entry (no files are modified automatically).
  • Inline suppression works for intentional one-offs: eval("print('safe')") # ubs:ignore.
  • Every language module receives the ignore list via their --exclude flag, so skips stay consistent.
  • This repository ships with a default .ubsignore that excludes test-suite/, keeping β€œreal” source scans noise-free.

Example:

# Ignore fixtures + build output
test-suite/
dist/
coverage/

🧭 Language Coverage Comparison

UBS ships seven language-focused analyzers. Each category below is scored using the following scale:

  • 0 – Not covered
  • 1 – Simple heuristics/regex only
  • 2 – Multi-signal/static heuristics (context-aware passes)
  • 3 – Deep analysis (AST-grep rule packs, taint/dataflow engines, or toolchain integrations such as cargo clippy)
Issue Category JS / TS Python Go C / C++ Rust Java Ruby
Null / Nil Safety 2 – DOM guard & optional-chaining heuristics (cat.1) 2 – None guard + dataclass fallbacks 1 – Basic nil/pointer guards 2 – Raw pointer/nullptr/RAII checks 3 – Borrow/Option misuse via clippy + rules 2 – Optional/null equality audits 1 – Nil guard reminders
Numeric & Type Coercion 2 – NaN/loose equality/float equality (cat.2/4) 2 – Division-by-zero & float precision 1 – Limited arithmetic heuristics 2 – UB risk & narrowing warnings 2 – Float/overflow watchers (cat.4) 1 – Basic comparisons only 1 – Simple arithmetic foot-guns
Collections & Memory 2 – Array mutation/leak detectors 2 – Dict/list iteration pitfalls 1 – Slice/map heuristics 3 – malloc/free, iterator invalidation, UB (cat.1/5/7) 2 – Vec/String/iterator audits 2 – Collections & generics misuse 1 – Enumerator/default mutability hints
Async / Concurrency 3 – AST-grep + fallback for missing await, React hooks dep analyzer 2 – Async/Await pitfall scans 3 – Goroutine/channel/context/defer hygiene 2 – std::thread join + std::async wait tracking 2 – Async macros, Send/Sync checks 2 – ExecutorService shutdown, synchronized monitors 1 – Basic thread/promise hints
Error Handling & Logging 2 – Promise rejection / try–catch auditing 2 – Exception swallow/logging checks 2 – Error wrapping, panic usage 2 – Throw-in-dtor, catch-by-value 2 – Result/expect/panic usage 2 – Logging best practices, try-with-resources 1 – Rescue/raise heuristics
Security & Taint 3 – Lightweight taint engine + security heuristics (cat.7) 2 – Eval/exec/SQL string heuristics 2 – HTTP/crypto/command checks 1 – Limited dedicated security (mostly UB) 2 – Security category (cat.8) 3 – SQL concat, Runtime.exec, SSL/crypto checks 2 – Rails mass-assignment, shell/eval warnings
Resource Lifecycle & I/O 3 – AST event-listener/timer/observer tracking + heuristics 2 – Context-manager & file lifecycle hints 2 – defer/file close + HTTP resource hygiene 2 – Thread join/malloc/free & resource correlation 2 – Drop/RAII heuristics + correlation 3 – Executor/file stream cleanup detections 2 – File open/close + block usage hints
Build / Tooling Hygiene 0 – Not covered yet 2 – uv extras, packaging, notebook hygiene 2 – Go toolchain sanity (go vet, module drift) 1 – CMake/CXX standard reminders 3 – cargo fmt/clippy/test/check integrations 2 – Maven/Gradle best-effort builds 2 – Bundler/Rake/AST rule packs
Code Quality Markers 1 – TODO/HACK detectors 1 1 1 1 1 1
Domain-Specific Extras 3 – React hooks, Node I/O, taint flows 2 – Typing strictness, notebook linting 2 – Context propagation, HTTP server/client reviews 2 – Modernization, macro/STL idioms 3 – Unsafe/FFI audits, cargo inventory 3 – SQL/Executor/annotation/path handling 2 – Rails practicals, bundle hygiene

Use this matrix to decide which language module’s findings you want to prioritize or extend. For example, if you need deeper Go resource-lifecycle audits, you can extend category 5 (defer/cleanup) or contribute new AST-grep rules; for JavaScript security you can build on the taint engine already running in category 7.


πŸ“œ License

MIT License - see LICENSE file

TL;DR: Use it anywhere. Modify it. Share it. Commercial use OK. No restrictions.


πŸ™ Acknowledgments

This project wouldn't exist without:

  • ast-grep by Herrington Darkholme - Revolutionary AST tooling that makes semantic analysis accessible
  • ripgrep by Andrew Gallant - The fastest search tool ever built
  • Open Source Communities - JavaScript, Python, Rust, Go, Java, C++, and Ruby communities for documenting thousands of bug patterns and anti-patterns over decades
  • AI Coding Tools - Claude, GPT-5, Cursor, Copilot for inspiring this tool and making development faster

πŸ“ž Support

Issues & Questions


πŸ’Ž The Bottom Line

Every hour spent debugging production bugs is an hour not spent building features.

The Ultimate Bug Scanner gives you:

  • βœ… Confidence that code won't fail in production
  • βœ… Speed (catch bugs in seconds, not hours)
  • βœ… Quality gates for AI-generated code
  • βœ… Peace of mind when you deploy

One Command. Three Seconds. Zero Production Bugs.

curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_scanner/master/install.sh?$(date +%s)" | bash

Then never waste another evening debugging a null pointer exception.


Ready to stop debugging and start shipping?

Install Now View on GitHub Documentation

Star this repo if it saved you from a production bug ⭐

βœ‰οΈ Works Great with MCP Agent Mail

MCP Agent Mail is a Git-backed mailbox system that lets your coding agents coordinate work, hand off tasks, and keep durable histories of every change discussion.

  • UBS + MCP Agent Mail together: run ubs --fail-on-warning . as a standard guardrail step in your MCP Agent Mail workflows so any agent proposing code changes must attach a clean scan (or a summary of remaining issues) to their reply.
  • Ideal pattern: one agent writes or refactors code, a β€œQA agent” triggered via MCP Agent Mail runs UBS against the touched paths, then posts a concise findings report back into the same thread for humans or other agents to act on.
  • Result: your multi-agent automation keeps all the communication history in MCP Agent Mail while UBS continuously enforces fast, language-agnostic quality checks on every change.

About

πŸ”¬ Industrial-grade static analysis for all popular programming languages. Catch 1000+ bug patterns before production

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Packages