| name | llmdoc |
| description | Use when the user runs /llmdoc, asks to annotate or index the codebase for LLM context, or wants a summary dump of source files. Handles annotate and dump subcommands. |
llmdoc
Overview
Scan source files, generate concise per-file summaries using Claude's own intelligence, and store them in .llmdoc/index.json. Incremental — only new or changed files (detected via SHA-256 hash) are re-summarised. No API key required.
Commands
/llmdoc annotate [path] — walk the codebase (or a subdirectory), hash files, summarise changed ones, update the index
/llmdoc dump [path] — export summaries to a named dump file for pasting into an LLM context window
If no subcommand is given, default to annotate.
annotate Workflow
1. Load existing index
Read .llmdoc/index.json if it exists. If not, start with an empty object {}.
Index format:
{
"apps/backend/src/routes/webhooks.ts": {
"hash": "a3f2...",
"summary": "Handles incoming Worldpay webhooks...",
"generated": "2026-04-04T10:00:00Z"
}
}
2. Discover files
Use Glob to find files matching these patterns (relative to repo root), skipping ignored paths:
Include extensions: .ts, .tsx, .js, .mjs, .prisma, .php, .sql, .sh
Exclude paths (skip any file whose path contains):
node_modules/
.next/
dist/
build/
.git/
generated/
*.d.ts files
*.min.js files
migrations/ (SQL migration files are auto-generated, not worth summarising)
public/
.llmdoc/
3. Hash each file
For each discovered file, run:
shasum -a 256 <filepath> | awk '{print $1}'
Compare the hash against the stored hash in the index.
- Hash matches → skip (print
unchanged <path>)
- Hash differs or not in index → needs summarising (print
updating <path> or creating <path>)
4. Summarise changed files
For each file that needs summarising:
- Read the file
- Write a summary of 2–4 sentences covering:
- What this file does and its role in the system
- Key exports, functions, or types it provides
- Any important dependencies or side effects worth noting
- Store in the index with the new hash and current timestamp
Summary style: precise and functional. Name the actual exports/behaviours. Avoid vague language like "handles various tasks" or "provides utility functions". A future Claude reading this should immediately know whether to open this file.
Example of a good summary:
Defines the StoreConfig type and per-brand configuration objects for all storefronts (FABDEFENSE, HOLOSUN, SS, etc.). Exports BRAND_CONFIGS, getBrandConfig (lookup by siteSlug), and shared email recipient arrays. This is the single source of truth for brand IDs, email config, delivery rules, and Plausible domains.
Example of a bad summary:
This file contains configuration for the stores. It exports some config objects and helper functions.
5. Write updated index
Write the full updated index back to .llmdoc/index.json.
6. Report
Print a summary:
created apps/holosun/src/config/store.ts
updated packages/store-kit/src/orders/index.ts
unchanged packages/core/src/logger/index.ts
...
Summary: X created, Y updated, Z unchanged
dump Workflow
1. Determine the output filename
Derive the dump filename from the path argument:
/llmdoc dump packages/store-kit → .llmdoc/store-kit-dump.md
/llmdoc dump apps/backend → .llmdoc/backend-dump.md
/llmdoc dump (no path, whole repo) → .llmdoc/dump.md
Use the last path segment (e.g. store-kit from packages/store-kit), lowercased, with hyphens.
2. Read the index
Read .llmdoc/index.json. If empty or missing, run annotate first.
Filter entries to only those whose path starts with the given path argument (if provided).
3. Generate the dump
Write .llmdoc/<name>-dump.md (or .llmdoc/dump.md for whole-repo) with this structure:
# Codebase Summary
Generated: <timestamp>
## Directory Overview
<brief listing of top-level dirs and their purpose>
## File Summaries
### apps/backend/
**src/routes/webhooks.ts** — Handles incoming Worldpay webhooks...
**src/db/connection.ts** — ...
### packages/store-kit/
...
Group files by their immediate parent directory. Sort directories alphabetically. Within each directory, sort files alphabetically.
4. Update the dump index
After writing the dump file, read .llmdoc/dumps.md (create if missing) and upsert a row for this dump:
# Dump Index
| File | Scope | Files | Generated |
|------|-------|-------|-----------|
| [store-kit-dump.md](store-kit-dump.md) | packages/store-kit | 37 | 2026-04-04 |
| [backend-dump.md](backend-dump.md) | apps/backend | 24 | 2026-04-04 |
| [dump.md](dump.md) | (whole repo) | 180 | 2026-04-03 |
- If a row for this dump file already exists, replace it (update file count and date).
- Sort rows alphabetically by filename.
dumps.md is committed to the repo (not gitignored) so the team can see what dumps exist.
5. Confirm
Tell the user the dump filename and how many files are included.
Practical Notes
- Process files in batches if there are many — don't try to read 200 files in one pass. Work through them systematically, updating the index as you go, so progress is saved even if interrupted.
.llmdoc/index.json and .llmdoc/dumps.md should be committed to the repo so the team shares them.
- Dump files (
*-dump.md) are gitignored — regenerate on demand with /llmdoc dump <path>.
- If the user specifies a subdirectory (e.g.
/llmdoc annotate packages/store-kit), scope the Glob to that path only.