agentleFS
oaustegardoaustegard/claude-skills/exploring-codebases/SKILL.md

exploring-codebases

Skill158 starsChanged 8 months agoMITView on GitHub

First-encounter orientation on a repository nobody here has worked in yet. Runs a fixed five-step workflow — venv setup, tarball fetch, tree-sitting structural scan, featuring synthesis, then reasoning over the two — and yields an account of what the repo contains and how it is arranged, optionally written out as _FEATURES.md. Use for "I just cloned this", "what is this repo", "what does this do", "explore this repo", "give me an orientation", "what are the main features", "review what's new in this repo", or before starting work in a codebase you have not seen. This is the divergent what's-here skill. Route elsewhere for: a named symbol, a file's structure or a line range (tree-sitting); all callers of a Python symbol (searching-codebases); teaching a human the codebase through exercises (orienting-codebases); fetching or cloning a repo without analysing it (accessing-github-repos, cloning-project).

  • Installs packages

2 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

9 rules. About 0 are common, 3 are distinctive, and 6 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 6

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    If step 2's --stats reports Symbols: 0 on a repo you know contains code, the tree-sitter core package isn't installed — come back here and …

    line 40
  2. Very specific:

    Ref selection matters: If exploring a feature branch, PR, or tag, set REF accordingly.

    line 65
  3. Distinctive:

    Read the output. It gives file counts, symbol counts, languages, and per-directory symbol density.

    line 75
  4. Distinctive:

    When you do drill, batch queries in one invocation: Every treesit call pays the full scan cost.

    line 84
  5. Very specific:

    Never pipe the full output through head: If you are about to truncate it, --orient was the correct mode and you have paid for thousands …

    line 120
  6. Very specific:

    bm25 → tree-sitting: Use bm25 to find the top-ranked files for a concept.

    line 175
  7. Distinctive:

    Only when the repo is large (>1000 files or several distinct subsystems) and this environment exposes a subagent tool (Agent/Task in Claude …

    line 187
  8. Very specific:

    Large repos (>100 files): use --skip tests,vendored,docs,...

    line 201
  9. Very specific:

    Monorepos: treat each package/service as a separate exploration.

    line 203

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Exploring Codebases

Exploratory code analysis for unfamiliar repositories. Orchestrates tree-sitting (structural) and featuring (semantic) over a local copy.

Workflow

Five numbered steps, in order. Do not skip step 0.

0. Setup (once per session)

uv venv /home/claude/.venv 2>/dev/null
uv pip install tree-sitter --python /home/claude/.venv/bin/python
export PYTHON=/home/claude/.venv/bin/python
export TREESIT=/mnt/skills/user/tree-sitting/scripts/treesit.py
export GATHER=/mnt/skills/user/featuring/scripts/gather.py

If step 2's --stats reports Symbols: 0 on a repo you know contains code, the tree-sitter core package isn't installed — come back here and install it (the engine bundles its own grammars and does NOT use tree-sitter-language-pack). Treesit exits 0 and prints no error in that case, so zero symbols is the only signal you get. There is no Errors: line: that one appears for parse failures, and an absent parser never reaches parsing. The full signal is in the tree-sitting skill's Setup section.

1. Get the repo (tarball, not per-file)

OWNER=...
REPO=...
REF=main                    # branch name, tag, or SHA. For a PR: pull/N/head
curl -sL -H "Authorization: Bearer $GH_TOKEN" \
  "https://api.github.com/repos/$OWNER/$REPO/tarball/$REF" -o /tmp/$REPO.tar.gz
mkdir -p /tmp/$REPO && tar -xzf /tmp/$REPO.tar.gz -C /tmp/$REPO --strip-components=1
ls /tmp/$REPO | head        # sanity check — did extraction land?

One HTTP call gets the whole repo. Do NOT curl README, cat files, or fetch via contents/PATH first — they're in the tarball. The Authorization header is only needed for private repos; public repos work without it.

Ref selection matters. If exploring a feature branch, PR, or tag, set REF accordingly. The default main will silently give you stale code if the question is about an unmerged branch.

2. Structural scan

$PYTHON $TREESIT /tmp/$REPO --stats

Read the output. It gives file counts, symbol counts, languages, and per-directory symbol density. This IS the orienting artifact — treat it as the product of this step, not warm-up.

Drill only if you have a specific question. For pure "what is this repo" exploration, skip drilling and go to step 3 — featuring surfaces the interesting paths for you. Drill when a user asked about a specific subsystem, or when step 3's output raises a question that needs source.

When you do drill, batch queries in one invocation. Every treesit call pays the full scan cost. Multiple queries added to the same command share that scan and each additional query adds ~0ms. If you're about to make a second treesit call on the same path, fold it into the first.

# GOOD — one scan, three answers
$PYTHON $TREESIT /tmp/$REPO --path=SUBDIR --detail=full \
  'find:*Handler*:function' 'source:main' 'refs:Config'

# BAD — three scans, three answers (3× the cost for the same information)
$PYTHON $TREESIT /tmp/$REPO --path=SUBDIR --detail=full
$PYTHON $TREESIT /tmp/$REPO 'find:*Handler*:function'
$PYTHON $TREESIT /tmp/$REPO 'refs:Config'

3. Feature synthesis

Pick the mode from your DELIVERABLE, before you run it.

Your deliverableCommandSize
Your own understanding — a review, an orientation read, answering a question--orient~115 lines
A written _FEATURES.md that must cite every symbolfull outputthousands of lines
# Default. Complexity assessment, decomposition ranking, directory tree, entry points.
$PYTHON $GATHER /tmp/$REPO --skip tests,.github,node_modules --orient

# Only when you are about to WRITE the inventory into a file:
$PYTHON $GATHER /tmp/$REPO --skip tests,.github,node_modules --source-budget 8000

Output includes a "Candidate areas for sub-files (by symbol density)" list near the top — that's your drill-target picker, ranked.

Never pipe the full output through head. If you are about to truncate it, --orient was the correct mode and you have paid for thousands of lines you will not read. One review's full gather ran to 5,697 lines and was cut at line 120; every finding in it came from treesit drilling and targeted reads instead. --orient returns the ~115 lines that get used. The full mode's symbol inventory exists to be CITED, not read.

4. Reason about the combined output

Synthesize 2+3: capabilities, feature groups, architecture, entry points, anomalies. Produce _FEATURES.md when warranted. This is the LLM step; everything before was mechanical.

When to Use This vs Other Skills

SituationUse
"I just cloned this, what is it?"exploring-codebases (this skill)
"Where is the retry logic?"searching-codebases
"Find all files matching class.*Error"searching-codebases
"Show me the symbols in auth.py"tree-sitting directly
"Which files are most about CSRF / sessions / queryset filtering?"bm25
"Rank these docs by relevance to a multi-word concept"bm25
"Document what this codebase does"featuring directly
"Teach me this codebase" (a human is learning)orienting-codebases
"Get me this repo" — fetch, no analysisaccessing-github-repos, cloning-project

Exploring is the divergent skill — you don't know what you're looking for yet. Searching is the convergent skill — you know what you want.

orienting-codebases runs the same tree-sitting + featuring pipeline and is the nearest thing in the catalogue to this skill. The split is the audience: this one builds Claude's understanding so work can proceed; that one builds the user's understanding through guided exercises and HTML artifacts. If nobody is being taught, this is the right skill.

Pairing bm25 with this workflow

Once steps 2–3 have surfaced the rough shape of the repo, bm25 is the natural complement when you want ranked content search beyond grep and beyond exact-symbol lookup. It ranks files by lexical relevance to a multi-word query, which is useful for "what's this codebase actually about when I search for X?" — particularly when you don't yet know the symbol name to feed to tree-sitting.

BM25=/mnt/skills/user/bm25/scripts/bm25.py

# Pass multiple queries — index builds once, all queries reuse it
python3 $BM25 /tmp/$REPO 'auth flow' 'session backend' 'middleware pipeline' \
  --exclude 'tests/*' --exclude '*/tests/*' --top-k 5

Two patterns that pair especially well:

  1. bm25 → tree-sitting. Use bm25 to find the top-ranked files for a concept; then tree-sitting source:Symbol:path/to/file.py to read the actual implementation.
  2. bm25 with --exclude 'tests/*'. Test directories tend to dominate keyword queries because test names redundantly mention domain terms. Excluding them up front lands you on implementation files.

bm25 is corpus-agnostic — it'll also work on project knowledge stores or uploads/ if your exploration spans docs, transcripts, or PDFs.

Delegating to subagents

Only when the repo is large (>1000 files or several distinct subsystems) and this environment exposes a subagent tool (Agent/Task in Claude Code and CCotw). Claude.ai chat and bare-skill runs have none: run steps 2-4 inline and skip this entirely. Never simulate fan-out by other means when the tool is absent.

Steps 2-3 stay inline either way. Only step 4's judgment work fans out, one agent per subsystem, and a subagent inherits nothing -- not the conversation, not this file, not the knowledge that scan artifacts are already on disk. Read references/subagent-delegation.md before writing the first agent prompt; it carries the four things every prompt must include and what happens when they are missing.

Notes

  • Large repos (>100 files): use --skip tests,vendored,docs,... in step 2 to focus the scan.
  • Monorepos: treat each package/service as a separate exploration. Generate per-subsystem _FEATURES.md files linked from a root index.
  • Drill heuristics (if step 2 drilling is warranted): directories with high symbol-to-file ratio (dense logic), entry-point names (main, cli, app, server, routes), files with many imports (integration points).

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.