Skip to content

About

🩺 Paste a GitHub repo URL β†’ explainable health scores, secret & CVE detection (OSV.dev), architecture graph & a prioritized prescription. Next.js + zero-dependency analysis engine.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

🩺 RepoDoctor

Your repository, diagnosed.

Paste a public GitHub repository β†’ get explainable health scores, secret & CVE detection, an architecture graph with cycle detection, and a prioritized prescription.

Next.js TypeScript Engine deps License: MIT Tests

Features Β· How scoring works Β· Quick start Β· API Β· Roadmap

Deploy to Render

RepoDoctor landing page


✨ What it does

RepoDoctor is a full-stack static-analysis tool β€” not another GitHub dashboard. It clones a repository, runs a dependency-free analysis engine over every source file, and produces a medical report for your codebase: vitals, diagnosis, and prescription.

πŸ” Explainable scores Every score ships with the exact penalties behind it. Click 43% and see why β€” no black box, no vibes.
πŸ” Real security signals 12 secret patterns with entropy + placeholder filtering, committed credential files (.env, .pem, .tfstate…), and 9 dangerous code patterns (eval, shell=True, verify=False, TLS bypass…).
πŸ“¦ Dependency CVEs Parses 8 lockfile formats and queries OSV.dev against your exact locked versions β€” the same CVE database powering GitHub's own advisory data.
🧭 Architecture graph JS/TS + Python import graph, aggregated by module, with Tarjan SCC cycle detection, fan-in hotspots and external-dependency mapping β€” rendered by a hand-rolled force layout, zero graph libraries.
πŸ₯Š Head-to-Head Put two repositories in the ring: mirrored category bars, a winner per vital, unique-findings diff, and a shareable duel card. Rematches are instant thanks to result caching.
🩹 Prescription Every finding maps to an action with impact Γ— effort ranking β€” the plan works with zero configuration; an optional LLM layer turns it into a written narrative.
🏷️ Shareable output shields-style SVG badge, full duel card as SVG, one-click PDF export via a print stylesheet, JSON export of the raw report.

🩺 The report

RepoDoctor report

Five vitals, each fully explainable:

Vital What it actually measures
Code Quality Cyclomatic complexity per function (branch-point approximation), deep nesting, god files, cross-file duplication, comment density
Security Committed secrets (entropy-scored), credential files, dangerous patterns, and dependency vulnerabilities from OSV.dev
Testing Test-to-code ratio curve, whether CI actually runs tests, coverage tooling, e2e presence
Documentation README depth + required sections, LICENSE, docstring/JSDoc coverage from the AST, comment density
Maintainability Linter/formatter hygiene, TODO debt per kLOC, bus factor, dependency weight, oversized directories

Explainable vitals

Every category can be expanded to the exact list of penalties that moved it β€” including a critical-findings cap and a test-ratio curve, so the number is honest about what it knows and what it sampled (171/217 files Β· partial).

πŸ₯Š Head-to-Head

Put two repos in the ring β€” express vs fastify, flask vs starlette, or any pairing:

Head-to-Head duel

Each duel generates a shareable SVG card for your README:

[![RepoDoctor Head-to-Head](https://your-host/api/card?a=<idA>&b=<idB>)](https://your-host/compare?a=<idA>&b=<idB>)

🧠 How scoring works (transparent by design)

  1. Every finding carries a severity-based penalty: critical 30 Β· major 10 Β· minor 4 Β· info 1.
  2. category score = 100 βˆ’ Ξ£ penalties, with two honesty mechanisms:
    • any critical finding caps the category at 55 (35 for two or more);
    • Testing is scored on a test-to-code ratio curve (target β‰₯ 60%) with CI penalties on top.
  3. overall = weighted mean β€” quality 25% Β· security 25% Β· testing 20% Β· documentation 15% Β· maintainability 15% β€” mapped to grades A+ β†’ F.
  4. Confidence is reported: files sampled, languages covered, and a partial flag when caps kicked in.

πŸ—οΈ Architecture

flowchart LR
    A["POST /api/analyze"] --> B["Job queue\nconcurrency 2 Β· idempotency\ncache by repo"]
    B --> C[Worker]
    C --> D["GitHub API\nmetadata Β· contributors Β· bus factor"]
    C --> E["codeload tarball\ncap 150 MB"]
    E --> F["File walker\n.gitignore-aware\ncap 4 000 files"]
    F --> G["Analysis engine\nzero dependencies"]
    G --> G1["Quality\ncomplexity Β· duplication"]
    G --> G2["Security\nsecrets Β· patterns"]
    G --> G3["Dependencies\nOSV.dev batch"]
    G --> G4["Docs Β· Testing Β· Maintainability"]
    G --> G5["Graph\nimports Β· SCC cycles"]
    G1 & G2 & G3 & G4 & G5 --> H["Scoring\npenalty model"]
    H --> I[("data/ results")]
    I --> J["SSE progress"]
    I --> K["Report UI\nVitals Β· Findings Β· Graph Β· Prescription"]
Loading

The heart of the project is lib/analyzer/ β€” a zero-dependency TypeScript engine: a comment/string-stripping state machine (template literals, triple-quoted strings, regex-literal disambiguation) feeds heuristic parsers (brace matching for JS/TS, indentation scopes for Python) that approximate cyclomatic complexity, detect clones with a sliding 7-line window, and resolve imports into a module graph that Tarjan's algorithm sweeps for cycles.

Limits & safety β€” archive ≀ 150 MB, ≀ 4 000 files, ≀ 400 KB/file, ≀ 60 MB of text; timeouts on every stage; results cached per repo for 24 h; only derived metrics are stored, never source code.

πŸš€ Quick start

git clone https://github.com/<you>/repodoctor
cd repodoctor
npm install
npm run dev          # β†’ http://localhost:3000

Optional environment (.env.local):

Variable Effect
GITHUB_TOKEN Raises the GitHub API limit from 60 to 5 000 req/hour
OPENAI_API_KEY Β· ANTHROPIC_API_KEY Β· GEMINI_API_KEY Enables the AI-written prescription (optional β€” everything works without it)

☁️ Deploy

RepoDoctor needs a long-running Node server (in-process job queue + SSE + disk cache), so serverless platforms (Vercel/Netlify functions, GitHub Pages) won't run it as-is.

The repo ships a Render Blueprint β€” one click:

Deploy to Render

Notes on the free plan:

  • The service sleeps after ~15 min idle; the first visit wakes it (~50 s).
  • data/ is ephemeral β€” the 24 h analysis cache resets on every deploy/restart.
  • Add a GITHUB_TOKEN environment variable in the Render dashboard (no scopes needed for public repos) if analyses start failing with GitHub rate-limit errors.

πŸ–₯️ Usage

# Web
npm run dev                       # paste a URL, or open /compare for a duel

# CLI
npm run analyze -- https://github.com/owner/repo [--token=ghp_xxx]

# Offline selftest (21 seeded issues in a deliberately unhealthy fixture repo)
npm run selftest

Badge in your README:

[![RepoDoctor](https://your-host/api/badge/<analysis-id>)](https://your-host/analysis/<analysis-id>)

πŸ”Œ API

Route Description
POST /api/analyze {url} Enqueue an analysis β†’ 202 {job}
GET /api/analyze/:id Job status (+ full result when done)
GET /api/analyze/:id/events SSE progress stream
POST /api/analyze/:id/prescribe LLM prescription (graceful fallback without a key)
POST /api/compare {a, b} Enqueue both sides of a duel
GET /api/analyses Recent diagnoses
GET /api/badge/:id SVG badge (accepts result id or job id)
GET /api/card?a=<id>&b=<id> Head-to-Head duel card as SVG

πŸ“‚ Project structure

repodoctor/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ api/                    # analyze Β· events (SSE) Β· compare Β· badge Β· card Β· prescribe
β”‚   β”œβ”€β”€ analysis/[id]/          # live progress + full report
β”‚   β”œβ”€β”€ compare/                # head-to-head duels
β”‚   β”œβ”€β”€ components/             # report views, graph, duel client, progress
β”‚   └── page.tsx                # landing
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ analyzer/               # ⭐ the engine β€” zero dependencies
β”‚   β”‚   β”œβ”€β”€ text.ts             #   comment/string-stripping state machine
β”‚   β”‚   β”œβ”€β”€ quality.ts          #   complexity, nesting, duplication
β”‚   β”‚   β”œβ”€β”€ security.ts         #   secrets, credential files, dangerous patterns
β”‚   β”‚   β”œβ”€β”€ deps.ts             #   8 lockfile parsers β†’ OSV.dev querybatch
β”‚   β”‚   β”œβ”€β”€ docs.ts             #   README, license, docstrings
β”‚   β”‚   β”œβ”€β”€ testing.ts          #   ratio, CI, coverage, e2e
β”‚   β”‚   β”œβ”€β”€ maintainability.ts  #   hygiene, TODO debt, bus factor
β”‚   β”‚   β”œβ”€β”€ graph.ts            #   import graph, module aggregation, Tarjan SCC
β”‚   β”‚   β”œβ”€β”€ score.ts            #   penalty model + prescription builder
β”‚   β”‚   └── index.ts            #   pipeline orchestration
β”‚   β”œβ”€β”€ github.ts               # API + tarball downloader with caps
β”‚   β”œβ”€β”€ queue.ts                # in-process job manager (BullMQ-ready)
β”‚   β”œβ”€β”€ store.ts                # JSON persistence (Postgres-ready)
β”‚   └── types.ts                # shared contracts
β”œβ”€β”€ fixtures/sample-repo/       # deliberately unhealthy repo for the selftest
β”œβ”€β”€ scripts/                    # analyze-cli.ts Β· selftest.ts
└── docs/screenshots/

πŸ§ͺ Tests

The engine is covered by an offline selftest that runs against fixtures/sample-repo β€” a fixture with 21 seeded issues (committed AWS example key, eval(), shell=True, a duplicated module, a missing lockfile…) and asserts each one is caught:

npm run selftest
# βœ… All checks passed β€” the fixture scores 49/100 (F), exactly as it should

πŸ›£οΈ Roadmap

  • Watch mode β€” GitHub webhook re-analysis + score history (needs auth + Postgres)
  • Go / Java / Rust support via tree-sitter grammars
  • Redis/BullMQ queue driver for horizontal scaling
  • og-image generation for social sharing
  • Multi-repo portfolio view ("diagnose all my repos")

🀝 Contributing

Issues and PRs are welcome. The engine is deliberately dependency-free β€” new analyzers should follow the Finding contract in lib/types.ts and register penalties in lib/analyzer/score.ts.

πŸ“„ License

MIT Β© 2026 Hajar Benhadj


Built with Next.js 15, TypeScript and an unreasonable amount of regular expressions.

About

🩺 Paste a GitHub repo URL β†’ explainable health scores, secret & CVE detection (OSV.dev), architecture graph & a prioritized prescription. Next.js + zero-dependency analysis engine.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages