
Code Distill
- 66 installs
- 191 repo stars
- Updated July 24, 2026
- pproenca/dot-skills
code-distill is a Claude Code skill for ai & agent building.
About
code-distill is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- code-distill
- AI & Agent Building
- AI-coding skill
Code Distill by the numbers
- 66 all-time installs (skills.sh)
- +8 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #5,968 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/pproenca/dot-skills --skill code-distillAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 66 |
|---|---|
| repo stars | ★ 191 |
| Last updated | July 24, 2026 |
| Repository | pproenca/dot-skills ↗ |
How do I helps with ai & agent building tasks during AI-assisted development.?
Helps with ai & agent building tasks during AI-assisted development.
Who is it for?
Best when you're working on ai & agent building and need structured help with code distill.
Skip if: Teams with no ai & agent building needs, or anyone wanting a generic chat assistant without this specific workflow.
When should I use this skill?
When you need to helps with ai & agent building tasks during AI-assisted development., or when code-distill is a claude code skill for ai & agent building.
What you get
Structured output aligned to code-distill: code-distill, AI & Agent Building.
Files
Code-Distill — Pattern Extraction Methodology for GitHub Codebases
Methodology distillation of the generic moves an agent makes when distilling code patterns on demand from a specific GitHub codebase, given a focused query. Not a per-library skill — one skill plus a thin per-library record in the shared knowledge graph (`/knowledge/libraries/`), because 90% of the work is the same regardless of which repo.
This is the dynamic light sibling of your static code-atlas distillations: opencode-ts, openai-codex-rust-patterns, nextjs-ppr-patterns. Those skills are heavy curated outputs — they distilled patterns from a single repo ahead of time. This skill is the on-demand alternative: when no static skill exists for the library yet, point at the repo and let the methodology run.
When to Apply
Use this skill when:
- The user asks "how does
<library>implement<feature>?" and points at (or names) a real GitHub repo - The query is focused on a single subsystem (design system, composition, state, error handling, effects, build, routing) — not "what is this whole codebase?"
- No static code-atlas skill exists for the library yet (or the existing one is stale)
- An ad-hoc invocation looks like
/distill <library> <query>or "show me X in repo Y" in natural language - The library has too small a surface area, or too short a lifespan, to justify authoring a full static code-atlas distillation
This skill is NOT for:
- Libraries with a static code-atlas skill — use `opencode-ts`, `openai-codex-rust-patterns`, `nextjs-ppr-patterns`, or other shipped per-library skills first. They are faster (already curated) and incorporate failure-gap lessons this skill cannot rediscover on demand.
- Full-codebase architecture mapping — when the question is "what does this whole codebase do, by domain?", use `codebase-comprehension-algorithms`. That skill is the heavy algorithmic toolkit (Leiden, MoJoFM, SBM); this skill is focused-query extraction.
- Authoring a full static code-atlas skill — the methodology playbook for that authoring task is a separate (not-yet-built) skill, the code-source sibling of `library-reference-distillation`. When you find yourself running
code-distillagainst the same library more than ~3 times, that is the signal to graduate to a full static skill. - Documentation lookup — for "where do I find X in
<library>docs?" use `docs-search`. This skill is for source code, not docs.
How to Use
The four categories are orthogonal moves. Match the symptom to the move:
| Symptom | Reach for | First rule to read |
|---|---|---|
| About to grep blindly, query is vague | Find | `find-classify-query` |
| About to read a whole file before locating the pattern | Find (grep) | `find-grep-before-read` |
| Found a candidate file; not sure if it's idiomatic | Find (tests) | `find-tests-show-intent` |
| About to scan knowledge/libraries/ before reading the named entry | Find (bounded read) | `find-bounded-knowledge-read` |
| Found the implementation; need to map its public surface | Trace (outward) | `trace-imports-outward` |
| Have the public surface; need to see variants & evolution | Trace (inward) | `trace-usages-inward` |
| Buried in boilerplate, legacy paths, test scaffolding | Filter | `filter-load-bearing` |
| Done — about to close the session | Capture | `capture-registry-record` |
For category overviews and ordering rationale, see `references/_sections.md`.
Rule Categories
| # | Category | Prefix | Move | Rules |
|---|---|---|---|---|
| 1 | Find | find | Locate the right code given the query; bounded read of knowledge | 4 |
| 2 | Trace | trace | Follow imports and usages to map the pattern | 2 |
| 3 | Filter | filter | Cut noise to surface load-bearing pattern | 1 |
| 4 | Capture | capture | Write code topography to registry/ for reuse | 1 |
Quick Reference
1. Find
- `find-classify-query` — Classify the query (component / composition / state / effect / error / build / routing) before grepping; the classification picks the grep targets and folder hints
- `find-grep-before-read` — Grep narrowly first to pinpoint files; never start by reading whole files
- `find-tests-show-intent` — Tests,
examples/, ande2e/dirs are the authors' canonical demonstration of intent; consult them before forming a hypothesis from prose - `find-bounded-knowledge-read` — Filename is the index: read only
knowledge/libraries/<slug>.md, never scan the dir; bounds per-invocation token cost regardless of knowledge-store size
2. Trace
- `trace-imports-outward` — From the implementation file, follow imports outward to discover the pattern's public surface and dependencies
- `trace-usages-inward` — From the public surface, find call sites inside the same repo to see variants, edge cases, and how the pattern evolves
3. Filter
- `filter-load-bearing` — Cut boilerplate (re-exports, builders, helpers), legacy paths (deprecated dirs,
_old/,legacy/), and test scaffolding from the answer; only the load-bearing pattern is the answer
4. Capture
- `capture-registry-record` — At end of a successful session, write the
code:section ofknowledge/libraries/<library>.md(repo URL, branch, SHA, folder map, naming conventions, AGENTS.md flag, samples-dir location) so the next lookup skips discovery
Knowledge Store
Per-library code topography records live in the repo-root shared knowledge graph at `/knowledge/libraries/`. The same files are written by `docs-search` — each skill owns one section (code: for this skill, docs: for docs-search) and never overwrites the other. See `knowledge/README.md` for the merged schema, wiki-link conventions, and the merge discipline.
The knowledge store is intentionally empty at v0.1.0. The radical-simplification recommendation that produced this skill said: do not pre-empt; add the first entry from a real lookup. If you find yourself adding a record for a repo you have not actually queried, stop — wait for the real need.
Read discipline: when the user names a library, do exactly read knowledge/libraries/<slug>.md. Never scan knowledge/libraries/ to "see what's available" — the filename is the index, and lazy access is what keeps per-invocation token cost bounded regardless of knowledge-store size.
Related Skills
- `docs-search` — Symmetric sibling for documentation instead of source code; same shape (methodology + shared knowledge graph); writes the
docs:section of the sameknowledge/libraries/<lib>.mdfiles this skill writes thecode:section of - `library-reference-distillation` — Authoring playbook for full library-ref rule packs from upstream docs; the heavy docs-source sibling
- (Future) code-atlas-distillation — Not yet built. Authoring playbook for full static code-atlas skills like
opencode-ts. Extract when you ship your 4th or 5th static code-atlas skill and the empirical patterns are observable. - `opencode-ts`, `openai-codex-rust-patterns`, `nextjs-ppr-patterns` — Heavy curated outputs for specific libraries; use them in preference to this skill when they exist
- `codebase-comprehension-algorithms` — Heavy algorithmic toolkit (Leiden, MoJoFM, SBM) for full-codebase domain mapping; orthogonal to focused-query extraction
- `radical-simplification` — Thinking layer above this skill; this skill itself is the third instance of the "constrain → name the invariant" move applied to the recurring "N skills per X" trap
Authoring Note
These rules are load-bearing, not decorative. Each names a wrong default an agent has when reaching for unfamiliar source code: reading whole files before grepping, ignoring tests as canonical intent, conflating boilerplate with load-bearing pattern, treating each lookup as one-shot. If a rule restates something a capable model already does correctly, cut it. Coverage is proven by /dev-skill:eval on real "how does X implement Y" prompts, not by rule count. The registry grows organically as real lookups demand entries; when a library gets queried more than ~3 times, that is the signal to graduate it to a full static code-atlas skill.
Source-Code Pattern Extraction Methodology
Version 0.2.0 dot-skills May 2026
---
Abstract
Methodology distillation of the generic moves an agent makes when distilling code patterns on demand from a specific GitHub codebase, given a focused query (e.g. 'how does shadcn/ui implement the design system', 'how does opencode use effect-ts', 'how does base-ui handle composition'). 8 rules across 4 orthogonal categories — Find, Trace, Filter, Capture — each naming a wrong default an agent makes when reaching for unfamiliar code (reading whole files before grepping, ignoring tests as canonical intent, conflating boilerplate with load-bearing pattern, treating each lookup as one-shot). Per-library code topography (repo URL, default branch, last-verified SHA, folder map, naming conventions, AGENTS.md flags) lives in registry/<lib>.md as ~30-line frontmatter — the dynamic light sibling of static code-atlas distillations (opencode-ts, openai-codex-rust-patterns, nextjs-ppr-patterns). Registry is intentionally empty at v0.1.0; first entry should be grounded in a real session.
---
Table of Contents
1. Find
- 1.1 Classify the query before grepping — component, composition, state, effect, error, build, routing
- 1.2 Grep narrowly before reading whole files
- 1.3 Read only the named knowledge entry; never scan knowledge/libraries/
- 1.4 Read tests, examples/, and e2e/ dirs as the authors' canonical demonstration of intent
2. Trace
- 2.1 Follow imports outward from the implementation file to map the public surface
- 2.2 From the public surface, follow usages inward to see variants and evolution
3. Filter
- 3.1 Cut boilerplate, legacy paths, and test scaffolding to surface the load-bearing pattern
4. Capture
- 4.1 Write the code section of knowledge/libraries/<library>.md after a successful session
---
References
1. https://github.com/BurntSushi/ripgrep 2. https://diataxis.fr/
---
Source Files
This document was compiled from individual reference files. For detailed editing or extension:
| File | Description |
|---|---|
| references/_sections.md | Category definitions and ordering |
| assets/templates/_template.md | Template for creating new rules |
| SKILL.md | Quick reference entry point |
| metadata.json | Version and reference URLs |
{
"name": "code-distill",
"version": "0.2.0",
"organization": "dot-skills",
"technology": "Source-Code Pattern Extraction Methodology",
"discipline": "distillation",
"type": "code-quality",
"date": "May 2026",
"abstract": "Methodology distillation of the generic moves an agent makes when distilling code patterns on demand from a specific GitHub codebase, given a focused query (e.g. 'how does shadcn/ui implement the design system', 'how does opencode use effect-ts', 'how does base-ui handle composition'). 8 rules across 4 orthogonal categories — Find, Trace, Filter, Capture — each naming a wrong default an agent makes when reaching for unfamiliar code (reading whole files before grepping, ignoring tests as canonical intent, conflating boilerplate with load-bearing pattern, treating each lookup as one-shot). Per-library code topography (repo URL, default branch, last-verified SHA, folder map, naming conventions, AGENTS.md flags) lives in registry/<lib>.md as ~30-line frontmatter — the dynamic light sibling of static code-atlas distillations (opencode-ts, openai-codex-rust-patterns, nextjs-ppr-patterns). Registry is intentionally empty at v0.1.0; first entry should be grounded in a real session.",
"references": [
"https://github.com/BurntSushi/ripgrep",
"https://diataxis.fr/"
]
}
Sections
This file defines the four orthogonal categories of moves an agent makes when distilling a code pattern on demand from a specific GitHub codebase, given a focused query. The prefix in parentheses is the filename prefix that groups rules. Categories are ordered by the sequence they fire in a real session: find the right code → trace it outward and inward → filter noise from load-bearing → capture findings for reuse.
The four categories are orthogonal — getting one right does not help with the others. Match the symptom in front of you:
- "About to grep blindly or open whole files" →
find - "Found the implementation, need to map its public surface or variants" →
trace - "Surrounded by boilerplate / legacy / tests; pattern is buried" →
filter - "Found the answer; about to close the session" →
capture
This skill is the methodology layer for ad-hoc code-pattern extraction. Per-library code topography (where shadcn keeps its tokens, where opencode puts its Effect services, where base-ui defines its slot composition) is not rules — it is reference data living in registry/<library>.md, intentionally empty at v0.1.0 and growing only when real lookups demand new entries.
A library that gets queried more than ~3 times is graduating to a full static code-atlas distillation skill (the heavy sibling, see opencode-ts, openai-codex-rust-patterns, nextjs-ppr-patterns). When that happens, retire the registry entry — the full skill subsumes the topography.
---
1. Find (find)
Description: Locating the right code given the query. The default failure mode is grepping blindly for query keywords and opening whole files to read linearly — both burn tokens and miss the canonical demonstration of intent. Covers classifying the query into a recognizable kind (component vs composition vs state vs effect vs error vs build vs routing) which picks folder hints and grep targets, gripping narrowly before reading, and consulting tests / examples/ / e2e/ as the authors' own canonical usage.
2. Trace (trace)
Description: Mapping the pattern's surface once you have located it. The default failure mode is forming a hypothesis from a single file without checking imports (missing the public boundary) or usages (missing variants and evolution). Covers following imports outward from the implementation file to discover the public surface, and following usages inward from the public surface to see how the pattern is actually consumed in the same repo.
3. Filter (filter)
Description: Cutting noise from the answer. The default failure mode is surfacing everything that grepped — boilerplate re-exports, legacy deprecated paths, test scaffolding, helper utilities — as if all of it were the pattern. Covers identifying load-bearing code (the implementation that makes the pattern work) and rejecting noise (re-exports, builders, helpers, _old//legacy/ dirs, test scaffolding) before producing the answer.
4. Capture (capture)
Description: Recording topography findings so the next lookup is cheaper. The default failure mode is treating each session as one-shot, then re-discovering the same repo URL, branch, SHA, folder map, and naming conventions next time. Covers writing the code: section of the shared knowledge file at knowledge/libraries/<library>.md at the end of a successful session — and graduating a library to a full static code-atlas skill when it has been queried more than ~3 times. The file is shared with docs-search, which writes the docs: section — each skill owns one section and never overwrites the other.
Write the code section of knowledge/libraries/<library>.md after a successful session
By default each code-distill session is one-shot — the agent discovers the repo URL, branch, SHA, folder map, and naming conventions, then loses all of that when the session ends. The next agent re-discovers the same facts. The move is to capture topography findings to the shared knowledge graph at `knowledge/libraries/<library>.md` (code: section only) after each successful session, and to graduate libraries with ≥ 3 lookups to a full static code-atlas distillation skill. The file is shared with docs-search, which writes the docs: section — this skill owns the code: section, neither overwrites the other.
Write when you have just distilled a pattern from a repo, the answer was correct, and the discovery work (folder map, AGENTS.md/CONTRIBUTING.md presence, naming conventions) is fresh from this session. Do not write from training-data recall — entries are grounded observations from the session that just completed.
The code section of the knowledge record:
---
library: shadcn-ui # filename stem, kebab-case
last-verified-date: YYYY-MM-DD
# Shared metadata (any writer may merge into these lists)
uses: ["[[radix-ui]]", "[[cva]]", "[[tailwindcss]]"]
implements: []
notable-landmarks:
- apps/www = dogfood docs site
- packages/cli = install-by-copy CLI
# docs-search writes the docs: section; do not touch it from here
# This skill owns the code: section
code:
repo: https://github.com/shadcn-ui/ui
default-branch: main
last-verified-sha: <SHA>
agents-md: false
contributing-md: true
folder-map:
components: apps/www/registry/<style>/ui/
tokens: apps/www/registry/<style>/lib/utils.ts
examples: apps/www/registry/<style>/example/
tests: limited; demo apps act as integration tests
naming-conventions:
- PascalCase component files
- cva() for variant definitions
- cn() for className composition
package-manager: pnpm workspaces
lookup-count: 1
---The merge discipline (CRITICAL):
- If the file does not exist → create with
library:, shared metadata, andcode:only - If the file exists with no
code:section → addcode:only; do not modifydocs:or other sections - If the file exists with
code:already → update fields undercode:, incrementcode.lookup-count, refreshlast-verified-dateandcode.last-verified-sha - For shared list fields (
uses,implements,notable-landmarks): merge by union; do not replace
When to refresh:
- On every session: increment
code.lookup-count, refreshcode.last-verified-sha, refreshlast-verified-date - If the folder map changed: update it; note the change in the prose Notes section
- If the SHA is more than ~30 days behind on a fast-moving repo: re-verify before relying on the record
- If the repo was renamed/moved/archived: update or delete the file in the same session
The graduation rule. When code.lookup-count >= 3 on a single library, the library has earned a full static code-atlas distillation skill (see opencode-ts, openai-codex-rust-patterns, nextjs-ppr-patterns for the heavy form). Once shipped:
1. Delete knowledge/libraries/<library>.md (the whole file, not just the code: section — if docs-search also wants to keep its data, that's a separate decision; usually the static skill subsumes both) 2. Add the library to this skill's "When NOT to Apply" with a pointer to the new static skill 3. The library moves out of this light layer into the heavy layer
Do NOT write here:
- Specific code patterns or idioms (those go in the static code-atlas skill if/when authored)
- Opinions about the library
- A stale SHA without a verification date
- The
docs:section (that is owned by `docs-search`)
The mechanical trigger: at the end of any successful code-distill session for a library whose code: section is missing from knowledge/libraries/, write it before closing out. If the section exists but is more than ~30 days old, refresh it. Discovery was already done during the session; capturing costs seconds.
Reference: knowledge/README.md — full schema, wiki-link conventions, and merge discipline
Cut boilerplate, legacy paths, and test scaffolding to surface the load-bearing pattern
By default once the agent has gathered candidate code (via find + trace), it reports everything that the greps surfaced as if it were all part of the pattern. The result is a noisy answer full of re-exports, helper utilities, deprecated paths, and test scaffolding — which obscures the load-bearing code that actually makes the pattern work. The move is to explicitly cut noise before producing the answer, and to name the cut categories so the user can re-include anything that was wrongly filtered.
The noise categories (cut these from the answer, by default):
1. Re-exports / barrels
export { Slot } from "./slot"
export * from "./internal"
These are zero-content; they reveal the package shape but
not the pattern. Mention them in passing ("re-exported from
X") and do not show the re-export file itself.
2. Builder / helper utilities
function createSlotPropsResolver(...) { ... }
Helpers that exist because the pattern needs them but that
are not themselves the pattern. Acknowledge their existence;
do not detail them unless the user asked about a helper.
3. Legacy / deprecated paths
packages/<lib>/legacy/, _old/, deprecated/, vN-compat/
Files marked @deprecated in JSDoc
Often present in mature libraries during migration. If the
query is about CURRENT usage, cut these. If the query is
about migration or version history, surface them as legacy.
4. Test scaffolding
describe/it blocks, test fixtures, mock implementations
conftest.py, setup.ts, __mocks__/
Tests demonstrate the pattern (find-tests-show-intent) but
test scaffolding (describe shells, mock builders) is not
the pattern. Use tests for intent, then cut the wrapping.
5. Code-style boilerplate
JSDoc blocks, license headers, type-only re-imports,
`import type` lines, prettier-formatted whitespace runs
Always cut unless the user asked about types or licensing.
What COUNTS as load-bearing (keep these):
- The function/class/component that contains the pattern's
distinctive verbs (the `cloneElement` for Slot; the
`Effect.gen` for effect-ts services; the `cva()` call for
shadcn variants)
- The hooks/contexts that wire the pattern across the tree
- The TypeScript generics or constraint that encode the
pattern's contract
- Real call sites that demonstrate at least 2 distinct
variants (per trace-usages-inward)
The audit:
After drafting the answer, name each piece you included and
justify its presence with "this is load-bearing because ___."
If the justification is "it appeared in the grep results," cut
it. If the justification is "without this, the pattern doesn't
work," keep it.
Anti-pattern:
Producing a 12-file dump labeled "here is how X is implemented"
where 3 files are re-exports, 4 are tests, 2 are deprecated,
and 3 are helpers. The user wanted the pattern, not a tour of
the directory.The mechanical trigger: before producing the final answer, list each file/function you are about to include and pass it through the noise categories above. Anything in a noise category is cut unless explicitly justified. The answer becomes 3 load-bearing pieces instead of 12 mixed ones.
Reference: The library-reference-distillation skill's `source-failure-gap` rule — the same "what would I cut?" discipline applied to rule selection
Read only the named knowledge entry; never scan knowledge/libraries/
By default once the agent learns there is a knowledge graph under /knowledge/libraries/, it does ls knowledge/libraries/ to "see what's available" before reading the named entry — or reads several entries to "compare." Both burn tokens linearly in the size of the knowledge store. The move is to treat the filename as the index: when the user names library X, read exactly knowledge/libraries/<x-slug>.md and proceed. The filesystem is the hash table; lazy access is what keeps per-invocation token cost bounded regardless of how many entries accumulate over time.
The bounded-access discipline:
When the user names library X (or a repo to distill against):
1. Compute the slug (kebab-case, matching the library's own name):
"shadcn/ui" → shadcn-ui
"base-ui" → base-ui
"Effect-ts" → effect-ts
2. Try exactly: read knowledge/libraries/<slug>.md
3a. File exists with a code: section → proceed with that entry
3b. File exists with no code: section → still read it (for shared
metadata and the docs: section's hints), then do code discovery
and capture the code: section at session end
3c. File does not exist → full discovery (find-classify-query
through trace-usages-inward); capture findings at session end
Never:
- ls knowledge/libraries/ to "see what's available" before
reading the named entry
- read multiple library entries to compare unless the user's
question explicitly requires cross-library comparison
- read knowledge/README.md on every invocation (only when
WRITING a new entry)
- grep across knowledge/libraries/ for keywords (the filename
is the canonical key)
The only legitimate multi-entry access:
- Following a wiki-link: if libraries/shadcn-ui.md has
uses: [[radix-ui]] AND the query specifically asks about
what shadcn inherits from Radix, you MAY follow to
libraries/radix-ui.md
- Cross-library pattern lookup: if knowledge/patterns/ exists
(it doesn't yet) and the user asks "what else implements
composition like X?" — the pattern node lists instances,
then read only the named instances
Token-cost guardrail:
Per-invocation knowledge read cost = O(1) when disciplined.
Per-invocation knowledge read cost = O(N) when undisciplined.
With N → 100+ entries, the difference is measured in seconds
and thousands of tokens per query.The mechanical check: before any operation that touches more than ONE file under knowledge/, ask "is this strictly required for the named query?" If the answer is "I want to see what's there" or "it might be useful," the answer is no — bound the access to the named entry. If a needed entry doesn't exist, do discovery and capture; do not browse the registry first.
Reference: knowledge/README.md — Reading from knowledge section codifies the same discipline
Classify the query before grepping — component, composition, state, effect, error, build, routing
By default the agent takes the user's keywords ("design system", "composition", "effect handling") and runs grep against them directly. This produces hundreds of false positives — grep "effect" in any React repo hits every useEffect call site. The move is to classify the query into a recognizable kind first — each kind has its own grep targets, folder hints, and file-extension filters. The classification takes seconds and cuts the search space by 10× or more.
Query kind Grep targets Folder hints
─────────────────────────────────────────────────────────────────────
Component class names; export const src/components/, ui/,
"design system" <Capitalized>; cva, tv; registry/, packages/<ui>/
"tokens" tailwind.config, tokens.ts
Composition Slot, asChild, Comp =, components with both
"slot props" Children, cloneElement; <X.Root> and <X.Trigger>
"compound" forwardRef + children
State management Provider, Context, store, src/state/, store/,
"global state" create, atom, signal, contexts/, providers/
"store" subscribe, dispatch
Effects / async Effect., Layer., gen, pipe; tests using effect/test;
"effect-ts" useEffect with deps; examples/ for runtime use
"side effects" Promise.all, AbortController
Error handling throw new <Lib>Error, errors.ts, exceptions.ts,
"error model" Result, Either, Option, boundaries/
ErrorBoundary, catch +
instanceof
Build / bundling rollup, vite, esbuild, build/, scripts/, package.json
"exports" "exports" in package.json "files", "main", "module"
"tsconfig" tsconfig.json paths
Routing Route, useNavigate, href, app/, pages/, routes/,
"navigation" <Link>, redirect, middleware files
middlewareThe mechanical trigger: before any Grep or Bash grep call, state the query kind out loud (even silently). If you cannot classify it, ask the user to clarify what kind of thing they want to see — "component" and "composition" can blur together, "state" and "effect" can overlap in some libraries, and grepping under the wrong category wastes the entire session.
If the query crosses two kinds (e.g. "how does shadcn compose its components into a design system" — both component AND composition) run the classifications sequentially, not in one mixed grep.
Anti-pattern: searching for vague nouns from the user's prompt ("system", "handling", "approach") as if they were code identifiers. Those words live in prose, not source. Translate them to the closest kind, then grep for the kind's targets.
Grep narrowly before reading whole files
By default the agent opens the README or a likely-named file and reads it linearly looking for the pattern. This burns the context window — most repos have 50-line README sections, 200-line index.ts files, and 500-line implementation files that are 80% boilerplate. The move is to grep narrowly first to pinpoint the exact lines that hold the pattern, then read a small window around each hit. Open whole files only after grep has narrowed the candidate set to ≤ 3 files.
The grep-narrow sequence:
1. Form a SHARP grep target — a token that the pattern's
implementation will use but that boilerplate will not.
Good targets (specific, low-noise):
"createContext" - state pattern; appears once per store
"Slot.Root" - Radix-style composition entry
"export const cva" - class-variance-authority idiom
"Effect.gen" - effect-ts canonical usage form
Bad targets (vague, high-noise):
"state" - matches half the repo
"component" - 4-digit hit count
"design" - hits comments more than code
2. Add structural filters to the grep.
--type=ts - skip CSS, markdown, lockfiles
--glob='!**/test/**' - exclude tests during the FIND phase
(tests come back in `find-tests-show-intent`)
--glob='!**/dist/**' - skip build output
--glob='!**/node_modules/**'
3. Read ONLY the file the grep hit, and ONLY a window around the hit.
output_mode: "content" with -B 5 -A 20 (or -B 10 -A 30)
NOT: open the whole file
4. If the window is insufficient, EXPAND it (-B 30 -A 60) rather
than read the whole file. Most patterns are visible in <80 lines
of context.
5. Read the whole file ONLY after grep has narrowed to ≤ 3 files
AND the windowed reads were inconclusive.
The token-cost guardrail:
- Whole-file read: 200-1000 lines × N candidates
- Grep + windowed read: 20-80 lines × N candidates
Difference is typically 10×. Reading whole files first is the
single most expensive habit in code-pattern extraction sessions.The mechanical trigger: before any Read call on a file > 100 lines, ask "did I grep for the specific token I'm looking for first?" If no, grep first. The grep-narrow pass is a few seconds of work; the whole-file read is a few seconds of work plus 800 lines of context burn.
Read tests, examples/, and e2e/ dirs as the authors' canonical demonstration of intent
By default the agent forms a hypothesis about how a pattern works by reading the prose docs, the README, or a randomly-encountered implementation file. This misses the authors' own canonical demonstration of intent — which lives in test/, examples/, and e2e/ directories, written and maintained by the same authors as the library. These dirs are how the maintainers exhibit the API they intend you to use. Read them before forming a hypothesis, not after.
The intent-source ladder (consult in this order, for "how does X work" queries):
Tier 1 — examples/ in the main repo
github.com/<org>/<lib>/tree/main/examples/
Each example is a self-contained, runnable demonstration of one
feature. The author chose what to demo here; that choice is
a strong signal of canonical usage.
Tier 2 — e2e/ or integration test dirs
github.com/<org>/<lib>/tree/main/e2e/
Wider scope than unit tests; uses the library "as a consumer
would." Reveals how subsystems are meant to compose.
Tier 3 — Unit test files next to the implementation
foo.ts → foo.test.ts (or foo.spec.ts) in the same dir
Reveals the EDGE CASES the author cares about, error paths,
and the public contract surface they pinned with assertions.
Tier 4 — Story files (.stories.tsx) for component libraries
Each <Component>.stories.tsx lists the canonical variants &
states the author wants to demo. Strong intent signal for
component libraries (shadcn, base-ui, MUI, etc.).
Tier 5 — Demo apps in monorepo (apps/www/, docs/, playground/)
The library's own marketing/docs site is usually built USING
the library — the dogfood is the canonical recipe.
Tier 6 — README + prose docs (LAST, for context only)
Prose is how the library is MARKETED; tests/examples are how
it is USED. Prose comes after the code-canonical sources, never
before — and only to add WHY context.
Anti-pattern:
Reading the README first and forming a mental model of the
pattern. The README has marketing-flavored simplifications and
may show a deprecated idiom because it's easier to explain.
The tests and examples never lie.
When the repo has no tests / examples (small library, early stage):
Drop to: GitHub code search for `<distinctive-import>` filtered
to repos with >100 stars. Real consumer usage in the wild.The mechanical trigger: when the query is "how should I use X?" or "how does X work?" the FIRST Read should be a test file, an example file, or a story file — never a README, never an implementation file, never a guide. The test/example shows you the intended call shape; the implementation file shows you how the library does it internally (a different question).
Reference: The library-reference-distillation skill's `source-priority-ladder` rule — same observation applied to skill-authoring source selection
Follow imports outward from the implementation file to map the public surface
By default once the agent has found an implementation file, it reads only that file and reports its contents as "the pattern." This misses the public boundary — the pattern's true surface is what gets exported from the library's package entry point, not what happens to be defined in one internal file. The move is to trace imports outward until you arrive at the package's public exports, then report the surface, not the internals.
The outward-trace sequence:
1. From the implementation file `foo.ts`, read the top: what
does this file import?
import { X } from "./bar"
import { Y } from "./baz"
import type { Z } from "../types"
2. Of those imports, identify which are PUBLIC API and which are
INTERNAL utilities. Heuristics:
- Public if it's re-exported from the package root
(check `package.json` "main"/"module" → trace from there)
- Internal if it's used only inside the same dir
(Grep for the import path across the rest of the repo)
3. Follow the public ones outward. Each step:
File → grep for "export.*<symbol>" in the parent / index file
→ if exported, continue outward; if not, stop.
4. The terminal node is the package's public entry point:
index.ts at the package root, OR
a file named in package.json "exports" / "main" / "module"
5. Report THIS surface to the user — not the internals.
"The Slot pattern in <library> is exported as `Slot` and
`Slottable` from the package root. Implementation lives in
src/internal/slot.ts, but consumers only import the two
public names."
Why this matters:
- Internal implementation files often have multiple alternatives,
deprecated branches, or experimental code. The PUBLIC surface
is what the maintainers commit to. Confusing the two leads to
answers that show off non-public internals as if they were
idiomatic — they aren't; they could disappear in any patch.
- For TypeScript libraries, the public surface is also enforced
by `.d.ts` files. The compiled types are the contract.
Anti-pattern:
Showing an internal helper function (e.g. `_normalizePropsImpl`)
as if it were the canonical API just because it's where the
query-grep landed. If the symbol starts with `_` or is not
re-exported from the package root, it is internal — name it
as such or stop describing it as part of the pattern.The mechanical trigger: before reporting "the pattern is X" to the user, confirm that X (or the symbol you're describing) appears in the package's public exports. If you cannot find it via the outward trace, you are showing internals and should reframe.
Reference: The library-reference-distillation skill's `source-priority-ladder` Tier 4 (TypeScript types as ground truth) — same discipline
From the public surface, follow usages inward to see variants and evolution
By default once the agent has identified the public symbol of a pattern (e.g. Slot from base-ui), it reports the symbol's signature and stops. This misses the variants — the different shapes consumers actually use the pattern in, the edge cases, and how the pattern evolved. The move is to follow usages inward by grepping for call sites of the public symbol across the same repo and reporting the variation, not just the abstract definition.
The inward-trace sequence:
1. From the public symbol P (e.g. `Slot`, `useQueryState`,
`Effect.gen`), grep across the SAME repo for call sites:
grep -rn "<P>" --type=ts \
--glob='!**/dist/**' \
--glob='!**/node_modules/**'
2. Categorize the hits:
- Library-internal usage (the library uses its own symbol
inside other implementations) → shows the canonical
compositional pattern
- Test usage → shows edge cases and contract
- Example usage → shows the recommended consumer shape
- Demo / docs usage → shows the marketed usage shape
3. For each category, sample 2-3 call sites and note the
PARAMETER PATTERNS:
Slot variant A: <Slot>{children}</Slot> (passthrough)
Slot variant B: <Slot asChild>{children}</Slot>
(delegate)
Slot variant C: <Slot ref={ref} {...props}>{children}</Slot>
(forwarded ref)
4. Report the SHAPE of variation to the user, with at least one
concrete example per variant. Variants reveal the pattern's
real flexibility — and the gaps a static API doc doesn't show.
5. If a recent commit changed how the pattern is used (renamed
prop, added a required arg), the inward grep will surface
BOTH the old and new shapes. That's a drift signal worth
flagging — describe the current shape, but note when the
repo is mid-migration.
Why this matters:
- The abstract type signature `Slot<T>(props: SlotProps<T>): ReactNode`
is uninformative. The four real call patterns in
`apps/www/src/registry/` are what teach the pattern.
- Inward usage also reveals the COMBINATORS — patterns that show
up when the public symbol is composed with another (e.g. Slot
+ asChild + cloneElement; useQueryState + parseAsInteger +
.withDefault(0)).
Anti-pattern:
Reporting "the pattern is `Slot(props)`" with no concrete call
example. The user asked HOW it's implemented; that means showing
at least one variant from the real repo, not the type signature.The mechanical trigger: before reporting "the pattern is X" to the user, surface 2-3 concrete call sites from the same repo. If you cannot find 2 distinct variants in the inward grep, treat the pattern as narrower than you thought — or recognize you are looking at an internal helper, not a public surface, and re-run the outward trace.
Reference: The library-reference-distillation skill's `source-failure-gap` rule — also extracted by tracing rule sources to real call sites in the repo
Related skills
FAQ
What does code-distill do?
code-distill is a Claude Code skill for ai & agent building.
When should I use code-distill?
When you need to helps with ai & agent building tasks during AI-assisted development., or when code-distill is a claude code skill for ai & agent building.
What are the main capabilities?
code-distill; AI & Agent Building; AI-coding skill.