Datum scans a GitHub codebase for security flaws, bugs and leftover TODO/FIXME markers and gives you a health score, a ranked list of findings with exact file and line, and suggested fixes.
- Resolve — reads the repo's full file tree from the GitHub API (default branch unless you give
/tree/<branch>). - Static scan (deterministic) — fetches every scannable file (text/code under 1 MB, no vendored or generated paths) and runs the rules in
lib/scanner/rules.ts: committed keys and private keys, hardcoded credentials,eval, SQL built from strings, shell injection, disabled TLS, raw HTML injection, weak hashes, emptycatch,@ts-ignore, and so on. TODO/FIXME/HACK/XXX comments are found by regex, so every one reported literally exists at the reported line. Nothing here is generated by a model. - AI review (optional) — the highest-risk files (those with static hits first) are sent to a Groq model to catch logic and security problems regex cannot see. The model must cite files and lines from what it was shown; anything else is discarded. If no key is set or the call fails, you still get the full static result plus a note.
- Score —
100 − weighted penaltyfor high/medium/low findings, with diminishing returns so one noisy file can't zero a repo.
Progress in the UI is real: the server streams newline-delimited JSON events (tree, progress, ai, result, error) from POST /api/scan.
If a repo has more than 1,500 scannable files, Datum stops before reading anything and shows a folder picker (with file counts; likely source folders are pre-ticked). Pick folders, hit Scan selected, and come back to scan others afterwards. Folders bigger than the limit are split into subfolders so every choice is a manageable size. Vendored dirs (node_modules, vendor, compiled, dist, ...) are never offered.
- Always: vendored, generated and build output (
node_modules,vendor,dist,build,compiled,third_party,generated, snapshots, virtualenvs, ...), binaries, lockfiles, files over 1 MB. - By default: tests, docs, examples, demos, fixtures, benchmarks (
test/,__tests__/,docs/,examples/,*.test.*, ...). Real code, but rarely where you want findings, and they flood reports with fake secrets. In large repos they still appear in the folder picker, tagged and unticked, so you can opt in.
- Every scannable file is read (highest-ranked first), within a 4-minute budget. Binaries, lockfiles, vendored/build dirs and files over 1 MB are skipped.
filesSkippedin the result shows what wasn't read. - The AI pass reviews up to 36 of the riskiest files (6 batches); the static scan covers all files.
- Public repos work without a token. Set
GITHUB_TOKENfor private repos and higher rate limits. - GitHub only. Figma links are not supported.
- Static rules are heuristics: expect some false positives (tests/docs/placeholders are filtered) and no data-flow analysis.
pnpm install
cp .env.example .env.local # add GROQ_API_KEY (and optionally GITHUB_TOKEN)
pnpm dev # http://localhost:3000Other scripts: pnpm test (scanner unit tests), pnpm typecheck, pnpm lint.
| Path | Purpose |
|---|---|
app/api/scan/route.ts |
Streaming scan endpoint |
app/api/models/route.ts |
Lists available Groq models |
lib/github.ts |
Tree/file fetching, file filtering and ranking, concurrency pool |
lib/folders.ts |
Splits big repos into pickable folders |
lib/scanner/rules.ts |
Detection rules |
lib/scanner/scan.ts |
Per-file scanner and health score |
lib/scanner/ai.ts |
AI review pass |
lib/groq.ts |
Groq client with multi-key rotation and model fallback |
components/ |
UI (hero, streaming analysis view, report export, history) |
Add an entry to SECURITY_RULES or BUG_RULES in lib/scanner/rules.ts (id, severity, regex, optional appliesTo path filter) and a case to lib/scanner/scan.test.ts.