Deterministic, no-AI repository analysis — upload a repo zip or paste a public GitHub URL and get an evidence-backed Candidate Brief for an interview walkthrough, bug investigation, planned change, or pull-request discussion.
RepoAtlas reads repository files as text only (never executes them). Primary output is a Candidate Brief (reading path, talking points, first PR ideas, resume bullets, walkthrough script, evidence index). Supporting tabs: Folder Map, Architecture Map, Start Here, Danger Zones, Run and Contribute, and Export (PDF/PNG always; Markdown when report storage is available).
Language depth is uneven by design of the current packs: TypeScript/JavaScript uses the TypeScript Compiler API (AST-backed imports and evidence). Python and Java use structured heuristics (mostly regex/text). Rankings are repository-relative structural signals, not calibrated defect or risk probabilities — see docs/adr/003-scoring-semantics.md and eval/README.md.
Two input modes:
- Upload ZIP — local snapshots; up to 100 MB compressed locally, 4 MB on Vercel. Prefer GitHub URL for larger public repos when deployed.
- Public GitHub URL —
https://github.com/owner/repowith optional branch/tag; archive streamed up to 100 MB compressed.
When storage is available, the server saves the report and returns a report ID. When storage is unavailable or save fails, the completed report is returned inline so the UI can still render and export PDF/PNG. Markdown downloads and saved report URLs require persistence.
- Features
- How It Works
- Architecture
- Tech Stack
- Requirements
- Quick Start
- Screenshots
- Example Candidate Brief
- Usage
- API Reference
- Configuration
- Project Structure
- Development
- Testing
- Fixtures and evaluation
- Limits and Behavior
- Security Notes
- Documentation Map
- Libraries and Licenses
- License
- Dual input: ZIP upload, public GitHub URL, or bundled sample brief
- Deterministic Start Here / Danger Zones from measurable repo signals (no LLM)
- Language packs: TS/JS (AST), Python and Java (heuristic) — see depth note above
- Interactive ELK architecture graph with pan/zoom
- Exports: client PDF/PNG; server Markdown for saved reports
- Best-effort persistence (
reports/or Vercel Blob via OIDC /BLOB_READ_WRITE_TOKEN) - Private sharing: 7-day saved-report tokens at
/share/:token, or encrypted portable fragment at/share/portable#…
See docs/roadmap.md and CHANGELOG.md.
- User chooses Upload ZIP or Public GitHub URL.
POST /api/analyzereceives multipart zip, JSON{ githubUrl, ref? }, or{ sample: true }.- Ingest extracts the upload or downloads the public archive (GitHub refs resolve to an immutable commit SHA first).
- Indexing builds folder tree, file metadata, docs/CI signals, and run commands.
- Language packs compute imports, entrypoints, complexity, and proximity. TS/JS builds a parser-backed
semantic_graph; see docs/semantic-graph.md. - Scoring produces
start_hereanddanger_zones(optional churn when commit history is available for the same ingested tip). - Interview builder assembles the Candidate Brief from signals and evidence refs.
- Report is validated; the server attempts to save it when storage is configured.
- Saved results return
{ reportId, persisted: true }; unsaved results return{ reportId, report, persisted: false }for inline UI.
- Flow: ZIP or GitHub URL → ingest → analyzer → best-effort storage → saved fetch or inline UI
- Analyzer:
worker_threadsisolation by default (in-process under Vitest /ANALYZE_INLINE=1), with fallback if the worker cannot start - Storage: filesystem
reports/or Vercel Blob; same-SHA GitHub analysis cache underreports/analysis-cache/(or Blob) - Temp workspace: OS temp directory per run
- API:
POST /api/analyze, report/share/export routes,GET|POST /api/cron/cleanup - Pages:
/,/interview-preparation,/privacy,/terms,/contact,/share/:token, legacy/report/:id
Next.js 16, React 19, TypeScript 5, Tailwind CSS, elkjs, react-zoom-pan-pinch, html2canvas, jspdf, Vitest, Playwright, ESLint.
- Node.js 20+ (
package.jsonengines) - npm 9+
- Local filesystem and temp directory access
npm install
npm run devOpen http://localhost:3000, upload a zip or paste a public GitHub URL, and click Analyze Repository.
npm run capture:portfolioBundled sample: docs/examples/repoatlas-candidate-brief.md. Homepage Try sample Candidate Brief analyzes fixtures/repo-ts without uploading.
- Upload ZIP or GitHub URL (
https://github.com/owner/repo, optional branch/tag) - Tabs: Candidate Brief (default), Overview, Folder Map, Architecture Map, Start Here, Danger Zones, Run and Contribute, Export
- PDF/PNG for saved and inline reports; Markdown only when the report was saved
curl -X POST http://localhost:3000/api/analyze \
-F "file=@/path/to/repo.zip"
curl -X POST http://localhost:3000/api/analyze \
-H "Content-Type: application/json" \
-d '{"githubUrl":"https://github.com/owner/repo"}'Caller-controlled zipRef paths are rejected (400 INVALID_INPUT).
curl http://localhost:3000/api/reports/<report-id>
curl -OJ http://localhost:3000/api/reports/<report-id>/export/md| Route file | Methods | Public endpoint |
|---|---|---|
src/app/api/analyze/route.ts |
POST |
/api/analyze |
src/app/api/reports/[id]/route.ts |
GET |
/api/reports/:id |
src/app/api/reports/[id]/share/route.ts |
POST |
/api/reports/:id/share |
src/app/api/share/[token]/route.ts |
GET |
/api/share/:token |
src/app/api/reports/[id]/export/md/route.ts |
GET |
/api/reports/:id/export/md |
src/app/api/cron/cleanup/route.ts |
GET, POST |
/api/cron/cleanup |
- Multipart zip in
fileorzip, or JSON{ githubUrl, ref? } zipRefrejected with400 INVALID_INPUT
Saved success: { "reportId": "uuid", "persisted": true }
Inline success: { "reportId": "uuid", "persisted": false, "report": { ... } }
Common errors: INVALID_INPUT, ZIP_NOT_FOUND, REPO_TOO_LARGE, TIMEOUT, ANALYSIS_FAILED.
Statuses: 200, 400, 413, 500, 504.
Report GET/share/export use Cache-Control: no-store. Security headers (including production CSP) come from next.config.js / securityHeaders.js.
200 report JSON; 400 invalid id; 404 missing.
Returns { token, sharePath, expiresAt } (7-day token).
Returns { report, share } for valid tokens. Inline reports use /share/portable#… in the browser instead (no server fetch of report bytes).
Downloadable Markdown for saved reports only.
No public delete endpoint. Retention is the server-side TTL sweep via cron cleanup.
GET /api/cron/cleanup— scheduled TTL sweep (daily at 03:00 UTC on Vercel)POST /api/cron/cleanup— manual/operator TTL sweep- Both methods require
Authorization: Bearer <CRON_SECRET>in production and fail closed when the secret is missing
See .env.example and SECURITY.md. Highlights:
- Vercel: private Blob store (OIDC) for saved reports; without Blob, analysis still completes inline
- Local:
REPORTS_DIRdefaults to<project-root>/reports - Retention:
REPORT_TTL_DAYS,REPORT_MAX_COUNT; cron auth viaCRON_SECRET - Rate limiting:
ANALYZE_RATE_LIMIT_PER_MIN,MAX_CONCURRENT_ANALYSES; optional Upstash REST credentials enable a shared cross-instance request limit
RepoAtlas analyzes only public GitHub repositories and never attaches a server-owned GitHub token to user-supplied requests.
src/app/api/ # analyze, reports, share, cron
src/analyzer/ # pipeline, packs, scoring, interview, eval harness
src/components/ # report UI
src/lib/ # ingest, storage, export, validation
fixtures/ # regression repositories
eval/gold/ # human-labeled analyzer expectations
reports/ # runtime filesystem storage (gitignored)
npm run dev
npm run build
npm run start
npm run lint
npm run typecheck
npm run test
npm run test:coverage
npm run test:e2e- Unit/integration: Vitest (
npm run test, coverage vianpm run test:coverage) - E2E: Playwright (
npm run test:e2e). If a dev server already owns port 3000, usePLAYWRIGHT_PORT=3100 npm run test:e2eso Playwright starts its own server (seeAGENTS.md) - Analyzer accuracy floors:
npm test -- src/analyzer/eval/eval.test.ts - Portfolio capture (separate from default e2e):
npm run capture:portfolio
Stale .playwright-reports/ can contaminate share/report tests — delete it (and test-results/) if e2e fails unexpectedly.
Regression fixtures live under fixtures/ (repo-ts, repo-python, repo-java, repo-java-maven, repo-fastapi, repo-node-api, repo-monorepo, and smaller edge cases).
Human-labeled gold expectations and metrics live under eval/. Expanding that gold set is the preferred path to improving analyzer trust — ahead of new UI surface area.
Centralized in src/lib/ingestLimits.ts (docs/adr/002-zip-limits.md):
| Limit | Local dev | Vercel deploy |
|---|---|---|
| ZIP upload (compressed) | 100 MB | 4 MB (use GitHub URL for larger public repos) |
| GitHub archive download | 100 MB | 100 MB |
| Uncompressed extract total | 50 MB | 50 MB |
| Analysis timeout | 120 s | 120 s |
| Indexed files | 10,000 | 10,000 |
| Folder map depth | 10 | 10 |
When a deep language pass cannot run, warnings are added to the report.
See SECURITY.md. Summary:
- Static analysis only — never executes target code
- Capability-link report access; no public
DELETE - No caller-controlled filesystem paths (
zipRefrejected) - Public GitHub only; hardened ZIP extraction (magic bytes, traversal/collision rejection, size/entry caps)
Cache-Control: no-storeon report/share/export
No AI. Deterministic heuristics and extracted signals only; Candidate Brief claims should trace to evidence refs.
What we will not claim. No vulnerabilities, production readiness, business purpose, or code correctness. Danger Zones are structural signals (size, coupling, complexity, test proximity, optional churn) — not bug counts or calibrated absolute risk.
RepoAtlas also does not reliably infer dynamic runtime behavior or support private repository access.
| Document | Canonical responsibility |
|---|---|
| README.md | Product overview, supported capabilities, quick start, user-facing limits, architecture summary, and developer entry points |
| CHANGELOG.md | Shipped release history and customer-visible changes |
| docs/roadmap.md | Active future work, priorities, non-goals, and work-selection guidance |
| docs/spec.md | Current product, API, schema, analyzer, storage, and behavioral contract |
| docs/adr/ | Durable architecture and security decisions with rationale |
| SECURITY.md | Vulnerability reporting, dependency-audit policy, and security guarantees |
| AGENTS.md and docs/guardrails.md | Contributor workflow, verification caveats, and non-negotiable implementation rules |
| docs/semantic-graph.md | TypeScript/JavaScript semantic graph guarantees and limitations |
| docs/examples/repoatlas-candidate-brief.md | Generated bundled sample export; not a manually maintained product contract |
Direct runtime dependencies: next, react, react-dom, elkjs, react-zoom-pan-pinch, html2canvas, jspdf, adm-zip, @vercel/blob. Dev tooling: TypeScript, Vitest, Playwright, ESLint, Tailwind/PostCSS, and marked for Markdown export safety tests. See package.json for versions and each package’s license.
MIT — see LICENSE.


