repo-digest
Summarises any repository into a one-page markdown digest.
| Size | Folder | Inside |
|---|---|---|
| 14.5 kB | scripts/ | 1 script |
| 3.6 kB | skills/ | 1 skill |
| 6.3 kB | (root) | 2 docs · 1 config file |
| Size | Path |
|---|---|
| 30 B | .gitignore |
| 1.1 kB | LICENSE |
| 4.7 kB | README.md |
| 511 B | package.json |
| 14.5 kB | scripts/digest.mjs |
| 3.6 kB | skills/repo-digest.md |
Already bought this?
View your purchasesREADME
repo-digest
A one-page markdown summary of a repository: size, shape, languages, dependencies, history, and what is missing.
For the thirty seconds before you open an unfamiliar codebase, and for giving an agent enough context to start without reading every file.
Read-only. No dependencies. Node 18 or newer.
Usage
node scripts/digest.mjs # this repo, to stdout
node scripts/digest.mjs ../other-repo # somewhere else
node scripts/digest.mjs . --out DIGEST.md
node scripts/digest.mjs . --json # the same facts, machine-readable
What it produces
# my-service
**412** tracked files · **38,204** lines · **1.9 MB** · mostly **TypeScript**.
**History.** 1,284 commits by 9 authors on `main`, 2023-04-02 → 2026-08-14. 31 tags,
latest `v4.2.0`.
## Languages
| Language | Files | Lines | Share |
|---|---:|---:|---:|
| TypeScript | 231 | 24,918 | 65.2% |
| Markdown | 44 | 6,110 | 16.0% |
| CSS | 18 | 3,401 | 8.9% |
## Layout
- `src/` — 231 files
- `tests/` — 88 files
- `docs/` — 41 files
- `package.json`
## Dependencies
**npm** (`package.json`) — 14 runtime, 22 dev.
`fastify`, `pino`, `zod`, `postgres`, …
## Signals
Present: **Readme**, **Licence**, **Tests**, **CI**, **Lockfile**.
Absent: Contributing guide, Changelog, Dockerfile, Types.
What it counts
| Section | Source |
|---|---|
| Files | git ls-files in a checkout, so .gitignore is honoured and node_modules is never walked. A plain directory walk otherwise, skipping the usual build and vendor directories. |
| Languages | Extension, plus the handful of files named rather than suffixed (Dockerfile, Makefile, Gemfile). Lines are counted, not estimated — but only for text files under 2 MB, so a checked-in bundle cannot dominate the table. |
| Primary language | The most lines among things that are actually code. Markdown, JSON, YAML and TOML are counted but never named the primary language. |
| Layout | Top-level entries with a file count under each, biggest first. |
| Dependencies | The manifest, not the lockfile: package.json, pyproject.toml or requirements.txt, go.mod, Cargo.toml, Gemfile. Declared intent, not the resolved tree. |
| Signals | Presence of a readme, a licence, a contributing guide, a changelog, tests, CI, a Dockerfile, type declarations, a lockfile — and, deliberately, the list of which of those are absent. |
| History | git rev-list, git shortlog, git tag: commit count, author count, first and last commit dates, tag count and the latest tag. Omitted for a non-git directory. |
Design decisions, and why
No score. There is no health grade, no percentile, no letter. Every field is a count of something you could verify by hand. A number that has been through a weighting function looks like a fact and is not one; deciding what "412 files" means about a repo is a human judgement, and the digest declines to make it for you.
Absences are reported. "No tests, no CI, no licence" is the most useful sentence the tool can produce, and it only exists if you print what is missing rather than only what is there.
Lines are counted, not sampled. Reading every text file under 2 MB costs milliseconds on any repo a person would open, and an estimate would be wrong in exactly the cases that matter.
Untracked files are invisible. In a git checkout, if it is not tracked, it is not in the digest. That is what makes two runs on two clones comparable.
Using it as a skill
skills/repo-digest.md turns the output into a procedure: read the sections in a specific order, then open the four files the numbers point at — the README, the entry point, the largest file in the primary language, and one test. It also carries the rules for writing an onboarding brief from the digest: quote the numbers rather than characterising them, list absences as facts rather than criticism, and say what you did not check.
Drop it into wherever your agent reads skills from.
Limitations
- Language detection is by extension. A
.hfile is called C whether or not it is C++, and a.mis called Objective-C whether or not it is MATLAB. - The dependency parsers are deliberately shallow: enough to list names, not enough to resolve a version range.
pyproject.tomlreads only PEP 621[project] dependencies, so a Poetry-only project shows zero. - Binary files count towards bytes and files, never lines.
- Submodules and sparse checkouts appear in
git ls-filesbut not on disk; those entries are skipped rather than crashing the run. - Monorepos are summarised as one repo. Point it at a workspace directory for a per-package view.
Licence
MIT. See LICENSE.
Security scan report
Scanned by X402 Git, OSV (opens in a new tab) and Socket (opens in a new tab) — passed on all three. Findings from X402 Git and Socket are listed below.
- secrets
- none found
- X402 Git
- size limits
- within caps
- X402 Git
- known malware
- no dependency manifests to check
- OSV
- known vulnerabilities
- no dependency manifests to check
- OSV
- dependency behaviour
- nothing on a direct dependency · 1 in transitive packages
- Socket
- instruction smuggling
- none found
- X402 Git
- what it can do
- listed below
- X402 Git
What this can do
- Tools
- none
- Runs
- scripts/digest.mjs
- Talks to
- nothing
- Reads
- JSON
- At install
- nothing runs
Findings (3)
- LOWscripts/digest.mjs — Reads the environment variable JSON
- LOWSocket SBOM Resolver — Socket SBOM Resolver (transitive) — no lockfile, so installs are not reproducible
- LOWscripts/digest.mjs — Ships the script scripts/digest.mjs
Releases 2
- v1.0.12026-08-30
Re-cut with lines-of-code and README assets
- v1.0.02026-08-30
fix: pluralise the commit count in the history line
A repo with a single commit read "1 commits".