Skip to content

Repository files navigation

RepoLens

CI License: MIT Python 3.12 Node 22

Project status

Actively developed, pre-1.0. This is a personal project built in the open, published so the work can be read and run. It is not a supported product.

Known gaps and caveats, stated up front:

  • Exercised locally against the bundled synthetic fixtures; not run against a large real-world repository at scale.
  • Findings are heuristic. Absence of a finding is not evidence of safety, and test presence is not measured coverage.
  • The model stage requires Ollama; without it that stage degrades to a warning and deterministic results still render.

Issues and pull requests are welcome. If something breaks on first run, that is useful information — please open an issue rather than assuming it works for everyone else.

Understand a repository without executing it.

RepoLens is a local-first repository analysis platform for developers joining unfamiliar projects, reviewing portfolios, learning architecture, or auditing generated code. Import a public HTTPS Git repository or upload a ZIP and receive a deterministic, evidence-backed report spanning structure, languages, dependencies, entry points, architecture, tests, documentation, maintainability, security patterns, recommendations, and interview preparation.

RepoLens is an assistive static-analysis tool. Findings can be wrong, absence of findings does not prove security or correctness, test presence is not measured coverage, and imported commands are never assumed to work.

Screenshots

All captures below are real, taken from a local run against the bundled synthetic fixture sample-python-api. No mocked interfaces.

RepoLens home screen showing the three safety guarantees and a table of recent analyses

Home. The three guarantees — static only, safe Git import, guarded ZIPs — are stated before anything is imported, not buried in documentation.

Analysis overview with source inventory, language distribution donut, and repository signals

Overview. Note the labelling discipline: repository signals are "observed presence, not executed or measured coverage," architecture is marked "Inference," and the sidebar carries a persistent "No code executed" badge.

Security review showing a redacted potential-secret finding classified as a test fixture candidate

Security review — the finding is severity LOW, MEDIUM CONFIDENCE, the value is redacted, and the evidence is tagged TEST FIXTURE CANDIDATE with a stated limitation: "Test fixtures and examples can resemble credentials; no provider received this value."

Worth noting: GitHub's own push protection flagged this repository's detector fixtures as live Slack and GitLab credentials and blocked the first push. RepoLens, pointed at comparable material, classifies it as a probable test fixture and redacts it rather than asserting a breach. That contrast is the whole design thesis — confidence labels and stated limitations beat a binary verdict.

Architecture view with a provenance legend separating directly observed, inferred, and model-assisted content

Architecture. Every claim is tiered — directly observed, inferred, or model-assisted — and LLM output is fenced inside an "UNVERIFIED MODEL-GENERATED DRAFT" block that tells you to check it against the deterministic evidence below.

Codebase study guide with architecture talking points and likely interviewer questions

Study guide. "Explain the project without inventing its history" — it generates talking points and likely questions while explicitly declining to imply authorship.

What it does

  • Safe shallow Git import through a DNS-pinning HTTPS proxy with hooks, prompts, redirects, credential helpers, LFS smudging, submodules, and non-HTTPS schemes disabled
  • Guarded ZIP extraction with traversal, absolute-path, symlink, expanded-size, count, and compression-ratio checks
  • File inventory, line counts, language distribution, classification, symbols, imports, dependencies, and likely entry points
  • Evidence-backed maintainability, documentation, testing, security-pattern, and conservative secret findings, with comment and string awareness for Python and JavaScript/TypeScript and measured per-rule precision
  • Git history signals for URL imports — churn, hotspots, knowledge concentration, and temporal coupling — with author identity hashed and never reported
  • Ingestion of committed coverage artefacts (coverage.xml, lcov.info, coverage-final.json) from the repository root or a coverage/ directory, reported as the project's own prior measurement, never as RepoLens's
  • Redacted source explorer with cited-line navigation and symbol outlines
  • Deterministic architecture components plus optional, schema-validated Ollama drafts that are explicitly marked unverified
  • Persistent queued jobs, cancellation, lifecycle events, searchable findings, Markdown/JSON export, history, rename, and cascading deletion
  • Immutable versioned migrations, service-heartbeat readiness, hash-locked Python installs, and digest-pinned production images
  • Responsive, keyboard-accessible dark/light developer interface

RepoLens never imports repository modules, installs repository packages, runs hooks, executes builds or tests, renders imported HTML, or invokes a shell with repository values.

Architecture

flowchart LR
  UI[React + TypeScript UI] --> API[FastAPI /api/v1]
  API --> Queue[(SQLite job queue)]
  Queue --> Worker[Supervising worker]
  Worker --> Child[Resource-limited child]
  Child --> Import[Bounded Git and ZIP importers]
  Child -->|internal-only network| Egress[Job-authorized pinning proxy]
  Egress --> Internet[Repository or configured model host]
  Import --> Scratch[Disposable bounded scratch space]
  Child --> Pipeline[Deterministic pipeline]
  Scratch --> Store[(Dedicated repository storage)]
  Pipeline --> Evidence[(SQLite evidence model)]
  Evidence --> Reports[Markdown and JSON reports]
  Evidence --> Redact[Secret redaction]
  Redact -. optional .-> Provider[Ollama or compatible endpoint]
Loading

The FastAPI service owns untrusted-input boundaries, analysis, persistence, provider calls, and report generation. The Vite application renders typed API data and never recreates findings. See architecture, methodology, and security model.

Screenshots

View Status What it must show
docs/images/dashboard.png TODO The analysis list with at least two completed analyses and one warning state
docs/images/finding-evidence.png TODO A single finding expanded, with its path:line locus and the cited source line
docs/images/source-viewer.png TODO The redacted source viewer with a [REDACTED] span visible
docs/images/progress.gif TODO ~15s: upload a fixture ZIP, stages advancing, report opening

Requirements

  • Python 3.12 (pinned in .python-version)
  • Node.js 22 (pinned in .nvmrc; CI uses the same version)
  • Git 2.30+
  • Docker Desktop (optional)
  • Ollama (optional; RepoLens remains useful offline)

Run make doctor to check all of the above before installing.

Quick start

cp .env.example .env
make install
make migrate

In terminal one:

make api

In terminal two:

make worker

In terminal three:

make web

Open http://localhost:5173, choose New analysis, and upload a ZIP of one of the bundled synthetic repositories. API documentation is at http://localhost:8000/docs.

Synthetic demo

The fixtures under sample_repositories/ are original and intentionally contain broad exception handling, duplication, and credential-shaped test data. They are safe demonstration inputs, not production examples.

make demo

This command invokes RepoLens's analyzer on sample-python-api; it does not execute the sample.

Ollama

Ollama is optional. Install it separately, pull the configured model, and keep it listening at http://localhost:11434. The default is qwen2.5-coder:7b. Set REPOLENS_MODEL_NAME to a model already available locally. Health reports ready only when both the endpoint and configured model are available. When unavailable or malformed, the model stage becomes a warning while deterministic results and exports remain intact.

For an OpenAI-compatible endpoint set:

REPOLENS_MODEL_PROVIDER=openai-compatible
REPOLENS_MODEL_BASE_URL=https://your-endpoint.example
REPOLENS_MODEL_NAME=your-model
REPOLENS_MODEL_API_KEY=your-key

The Settings page visibly reports when requests can leave the machine. Potential secrets are redacted before synthesis. API keys never appear in settings responses or reports. Model output is schema-validated but not treated as factual evidence; the UI marks it as an unverified draft and keeps deterministic evidence primary.

Docker

docker compose up --build

Open http://localhost:5173. The API applies frozen Alembic migrations before accepting traffic, while /api/v1/readiness remains unavailable until the worker and egress heartbeats are fresh. Compose mounts only the dedicated repolens-data volume. Every service runs non-root with a read-only root, dropped capabilities, a PID ceiling, and CPU/memory limits. The worker additionally receives a size-bounded noexec scratch tmpfs and only an internal Docker network. A separate proxy authorizes the current Git host or configured model endpoint, pins repository DNS, and is the worker's only egress route. Only a validated bounded tree is published to persistent storage. No arbitrary host source is mounted. Compose uses REPOLENS_DOCKER_MODEL_BASE_URL (default http://host.docker.internal:11434) for host Ollama and supplies the Linux host-gateway mapping; direct development continues to use REPOLENS_MODEL_BASE_URL.

Development

Task Command
Check the toolchain make doctor
Install make install (runs doctor first)
Install pre-commit hooks make hooks
Regenerate reviewed Python locks make lock
API with reload make api
Analysis worker make worker
Web UI make web
Migrate database make migrate
Import the bundled fixtures make seed
Backend + frontend tests make test
End-to-end tests make e2e
Lint (ruff check, ruff format --check, eslint) make lint
Apply formatting make format
Python type check make typecheck
CI's lint, type, test, coverage and advisory jobs, in CI's order make ci
Production web build make build
Analyze synthetic sample make demo
Require provider health make provider-health
Reset local data make clean-data (requires confirmation)

make ci runs CI's backend and frontend jobs plus the dependency-advisory steps, in CI's order. It does not run the four jobs that need Docker, a browser download or network access a local run should not assume: the gitleaks secret scan, CycloneDX SBOM generation, the Playwright end-to-end job (make e2e), and the docker job that boots Compose and curls health, readiness and the SPA. A green make ci predicts those seven steps, not the whole pipeline.

Formatting and linting are enforced by pre-commit and again in CI. Run make hooks once after installing so a commit cannot introduce an unformatted file; pre-commit run --all-files normalises an existing tree.

See development and troubleshooting.

Configuration

Variable Default Purpose
REPOLENS_DATA_DIR .repolens-data Dedicated import/report storage
REPOLENS_DATABASE_URL SQLite under data directory Metadata and evidence database
REPOLENS_MAX_REPOSITORY_BYTES 50 MiB Expanded authored-file limit
REPOLENS_MAX_FILE_COUNT 20,000 Imported entry/file limit
REPOLENS_MAX_FILE_BYTES 1 MiB Per-file analysis/display limit
REPOLENS_MAX_ARCHIVE_BYTES 25 MiB ZIP upload limit
REPOLENS_MAX_CLONE_STORAGE_BYTES 128 MiB Active clone storage ceiling
REPOLENS_CLONE_TIMEOUT_SECONDS 120 Git subprocess deadline
REPOLENS_SERVICE_HEARTBEAT_SECONDS 5 Worker/egress heartbeat interval
REPOLENS_SERVICE_STALE_SECONDS 20 Readiness heartbeat expiry
REPOLENS_REQUIRED_SERVICES empty; Compose sets worker,egress Services required by readiness
REPOLENS_JOB_WALL_TIMEOUT_SECONDS 300 Child-process wall deadline
REPOLENS_JOB_MEMORY_BYTES 1 GiB Linux child virtual-memory ceiling
REPOLENS_JOB_CPU_SECONDS 240 POSIX child CPU-time ceiling
REPOLENS_WORKER_SCRATCH_DIR unset Optional separately bounded worker filesystem; Compose uses /work
REPOLENS_EGRESS_PROXY_URL unset Optional trusted pinning proxy; Compose injects its isolated egress service
REPOLENS_ALLOWED_CORS_ORIGINS http://localhost:5173 Exact local UI origins
REPOLENS_BIND_HOST 127.0.0.1 Compose-only. Host interface the API and web ports publish on
REPOLENS_GIT_HISTORY_DEPTH 200 Commits fetched for churn/hotspot/coupling analysis; 1 disables it
REPOLENS_MAX_PATH_DEPTH 64 Maximum archive/clone path nesting
REPOLENS_MAX_PATH_LENGTH 1024 Maximum archive member name length
REPOLENS_MAX_MATCHES_PER_RULE_PER_FILE 10 Per-rule cap before a +N more rollup
REPOLENS_MAX_FINDINGS_PER_FILE 200 Per-file finding budget
REPOLENS_MAX_FINDINGS_PER_ANALYSIS 5000 Per-analysis finding budget
REPOLENS_REPORT_FINDINGS_LIMIT 200 Findings embedded in the detail response
REPOLENS_MODEL_CONTEXT_TOKENS 8192 Declared context window; sent to Ollama as num_ctx
REPOLENS_MODEL_PROVIDER ollama ollama or openai-compatible
REPOLENS_MODEL_BASE_URL http://localhost:11434 Provider endpoint
REPOLENS_DOCKER_MODEL_BASE_URL http://host.docker.internal:11434 Compose-only provider endpoint
REPOLENS_MODEL_NAME qwen2.5-coder:7b Configured model
REPOLENS_MODEL_TIMEOUT_SECONDS 30 Per-attempt provider timeout
REPOLENS_MODEL_RETRIES 1 Provider retries after the initial attempt
REPOLENS_MODEL_MAX_RESPONSE_BYTES 1 MiB Streamed provider-response ceiling

Supported languages

Safe text inventory and language detection cover Python, JavaScript, TypeScript, JSX, TSX, JSON, YAML, TOML, Markdown, reStructuredText, AsciiDoc, HTML, CSS, shell, Dockerfiles, and SQL. Only Python and JavaScript/TypeScript receive symbol/import extraction; see the exact support matrix.

Trust boundary

RepoLens v1 has no authentication. Its trust boundary is a single local machine, and the shipped docker-compose.yml enforces that: both published ports bind 127.0.0.1 by default. Setting REPOLENS_BIND_HOST=0.0.0.0 exposes an API that permits full read, rename, cancel, source read-back and delete to anyone who can reach it. Do not do that without putting authentication in front of it. See security model and SECURITY.md.

Known limitations

  • Version 1 is a local, single-user application and is not hardened for direct public-internet exposure.
  • The bundled worker processes one job at a time. Queue claims take the SQLite write lock up front (BEGIN IMMEDIATE) and are atomic, and the supervision loop survives a failed iteration, but concurrent workers are not covered by tests and SQLite remains intended for a local single-worker deployment.
  • Rule precision is measured against the committed corpus under apps/api/tests/corpus/, not against a broad real-world sample. Comment and string awareness exists for Python and the JavaScript/TypeScript family only; findings in other languages say so and carry lower confidence.
  • Coverage is never measured. A committed coverage.xml, lcov.info, or coverage-final.json is read and reported as the project's own prior measurement, which may be stale.
  • Git history signals are bounded by the fetched commit window and are unavailable for ZIP uploads. Author identity is hashed and never reported.
  • Multi-language complexity (lizard) and Python security rules (bandit) are optional and are not in the production lockfile. summary.capabilities reports which actually ran.
  • Hard aggregate scratch-space enforcement is supplied by Compose's bounded tmpfs. A local make worker run still has active clone monitoring and POSIX per-file limits, but its aggregate filesystem capacity depends on the configured REPOLENS_WORKER_SCRATCH_DIR mount.
  • Direct host development uses an in-process address-pinning proxy but does not receive Compose's network-namespace egress isolation.
  • Symbol extraction is AST-based for Python and conservative pattern-based for JavaScript/TypeScript.
  • .gitignore is not interpreted in version 1; a fixed safety-oriented ignore set is used.
  • No vulnerability database runs by default, so dependency hygiene findings are never labeled as CVEs.
  • Architecture and study-guide explanations are inferences, not original developer intent.
  • Git network imports depend on local network availability and the system Git binary.

Read responsible analysis before acting on a report.

Audits

RepoLens has been reviewed twice, adversarially, and both reports are published unedited — including the parts that are unflattering.

  • 2026-07-18 first-principles security review — a 55-row verification matrix, an honest "Conditional Pass", and an explicit list of features that were claimed but not implemented.
  • 2026-07-24 full-stack audit — backend security, analysis-engine quality, frontend and design, and testing/CI/DX, plus a phased roadmap. Findings were reproduced by executing the shipped code against crafted hostile inputs, not by reading it.

The 2026-07-24 audit is the source of the Phase 0 and Phase 1 work in the current CHANGELOG. Findings that remain open are listed there rather than quietly dropped.

Design decisions

Six decisions that shaped the architecture, each with the alternatives that were rejected and what would change our minds:

ADR Decision
0001 A separate egress-proxy process rather than in-process DNS pinning
0002 SQLite and a polling worker rather than Redis or Celery
0003 Fork/exec per job rather than a thread pool
0004 Frozen migrations that refuse to guess at an unknown schema
0005 Model output is schema-validated but explicitly not evidence
0006 .gitignore is deliberately not interpreted

Roadmap

  • Server-sent live stage events and explicit job retry controls
  • Deeper tree-sitter parsing and import graph cycles
  • User-configurable safe ignore rules
  • Optional maintained vulnerability scanner integration with explicit provenance
  • Measured rule precision fixtures and a false-positive review workflow

Contributions are welcome; see CONTRIBUTING.md. RepoLens is available under the MIT License.

About

Understand a repository without executing it — sandboxed static analysis with a DNS-pinning egress proxy, zip-bomb guards, and a measured-precision secret detector.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages