Study sources
Ground your work in real upstream source rather than recalled API shapes. When a
task turns on how a library, framework, or SDK actually behaves — its exact function
signatures, its edge cases, an error string, a private helper, a version-specific change —
read the source. This skill maps where each ecosystem already keeps readable source on
disk, and how to fetch it into .scratch/ when it isn't local yet.
Two habits make this reliable:
- Read what's installed before you clone. Most ecosystems cache decompressed source
locally —
node_modules/, ~/.m2, the Gradle/Cargo/NuGet/Go caches, the Android SDK's
sources/. Reading the version the project actually resolved is faster and more
correct than cloning main, which may be ahead of the pinned release.
- Everything fetched lands in
.scratch/. This directory is gitignored (repo-wide),
so cloned repos and unpacked archives never pollute the working tree, git status, or
the project's history. Keep one sub-folder per source, e.g.
.scratch/sources/<ecosystem>/<name>@<version>/.
Guardrails
- Read-only. This skill fetches source to study. Do not build, install, run, or
execute anything you pull in — you are reading code, not adopting a dependency.
.scratch/ only. Never clone or unpack into the project tree. If .scratch/ is not
already ignored, add it to .gitignore before fetching (do not fetch into a tracked
path). Confirm with git check-ignore .scratch when unsure.
- Prefer the resolved version. Match what the project's lockfile / build resolved, not
the latest tag, unless the user explicitly wants upstream
HEAD.
- Shallow and narrow. Clone with
--depth 1 and, for large monorepos, a sparse or
blobless checkout (see references/git-sources.md). You want
the code to read, not the full history.
- Network is a fallback. Reach the network only when the source isn't already on disk.
In sandboxed/offline runs, exhaust local caches first and tell the user if a fetch needs
network access.
The universal workflow
- Name the target. Which package/repo, and — critically — which version? Read the
project's lockfile or manifest to resolve it (
package-lock.json/pnpm-lock.yaml,
requirements.txt/poetry.lock, pom.xml/*.gradle, go.mod, Cargo.lock,
*.csproj, Gemfile.lock, composer.lock, pubspec.lock, Package.resolved).
- Check the local cache first. Use the map below to look where that ecosystem already
stores decompressed source. If it's there, read it in place — no fetch.
- Fetch into
.scratch/ if missing. Use the ecosystem's own "download source" path
(source JARs, pip download, go mod download, cargo vendor, npm pack, etc.), or
clone the Git repo at the matching tag. Land it under .scratch/sources/….
- Read narrowly. Grep for the symbol, type, or string you need. Note the
file:line and the exact version you read, so any claim you make is traceable.
Ecosystem cache map — look here before fetching
| Ecosystem |
Already-decompressed source on disk |
Reference |
| Any Git host (GitHub/GitLab/Bitbucket/…) |
— (clone into .scratch/) |
git-sources.md |
| JavaScript / TypeScript |
node_modules/<pkg>/; pnpm store ~/.local/share/pnpm/store / node_modules/.pnpm/; Yarn Berry .yarn/cache (zipped) |
javascript.md |
| Python |
active venv …/site-packages/<pkg>/; system site-packages; pip download --no-binary for sdist |
python.md |
| Java / Kotlin / JVM |
Maven ~/.m2/repository/… (-sources.jar); Gradle ~/.gradle/caches/modules-2/… |
jvm.md |
| Android |
SDK $ANDROID_HOME/sources/android-<api>/; AARs in Gradle cache; AndroidX / AOSP via cs.android.com |
android.md |
| Go |
module cache $GOPATH/pkg/mod/<module>@<version>/ (read-only) |
go.md |
| Rust |
registry ~/.cargo/registry/src/<index>/<crate>-<version>/ |
rust.md |
| .NET / C# |
NuGet ~/.nuget/packages/<pkg>/<version>/ (lib DLLs; source via SourceLink/decompile) |
dotnet.md |
| Ruby / PHP / Swift / Dart |
RubyGems $GEM_HOME/gems/; Composer vendor/; SwiftPM .build/checkouts/; Dart pub cache ~/.pub-cache/hosted/… |
ruby-php-swift-dart.md |
| C / C++ / system |
system headers /usr/include; vcpkg/conan caches; else clone upstream |
native-c-cpp.md |
If $ARGUMENTS opens with a Git URL, treat it as a clone request →
git-sources.md. If it names a package@version or an
ecosystem keyword, route to that ecosystem's reference. Otherwise infer the ecosystem from
the project's manifests and the map above.
When NOT to use this
- The answer is already in the project's own tree — read that first.
- The library's public docs fully cover the question and version drift isn't a risk (still
prefer source for exact signatures and edge cases).
- You'd be fetching just to run or build it — that's a dependency-adoption task, not a
study task; this skill only reads.
1---2name: study-sources3description: Fetch and read real upstream source code — from Git hosts (GitHub/GitLab/Bitbucket) and from installed dependencies (node_modules, ~/.m2, Gradle/Android SDK sources, Go/Rust/.NET/Ruby/PHP/Swift/Dart caches) — into a gitignored .scratch/ so you build knowledge from actual code instead of guessing at APIs. Use when a task depends on how a library, framework, package, or SDK actually behaves, when reading a dependency's implementation or types would remove guesswork, when reproducing an upstream bug, or when the user asks to pull down / study / vendor a repo or package source. Reads are read-only and never enter the repo's own git history.4---56# Study sources78Ground your work in **real upstream source** rather than recalled API shapes. When a9task turns on how a library, framework, or SDK actually behaves — its exact function10signatures, its edge cases, an error string, a private helper, a version-specific change —11read the source. This skill maps **where each ecosystem already keeps readable source on12disk**, and **how to fetch it into `.scratch/` when it isn't local yet**.1314Two habits make this reliable:15161. **Read what's installed before you clone.** Most ecosystems cache decompressed source17 locally — `node_modules/`, `~/.m2`, the Gradle/Cargo/NuGet/Go caches, the Android SDK's18 `sources/`. Reading the version the project actually resolved is faster and *more19 correct* than cloning `main`, which may be ahead of the pinned release.202. **Everything fetched lands in `.scratch/`.** This directory is gitignored (repo-wide),21 so cloned repos and unpacked archives never pollute the working tree, `git status`, or22 the project's history. Keep one sub-folder per source, e.g.23 `.scratch/sources/<ecosystem>/<name>@<version>/`.2425## Guardrails2627- **Read-only.** This skill fetches source to *study*. Do not build, install, run, or28 execute anything you pull in — you are reading code, not adopting a dependency.29- **`.scratch/` only.** Never clone or unpack into the project tree. If `.scratch/` is not30 already ignored, add it to `.gitignore` before fetching (do not fetch into a tracked31 path). Confirm with `git check-ignore .scratch` when unsure.32- **Prefer the resolved version.** Match what the project's lockfile / build resolved, not33 the latest tag, unless the user explicitly wants upstream `HEAD`.34- **Shallow and narrow.** Clone with `--depth 1` and, for large monorepos, a sparse or35 blobless checkout (see [references/git-sources.md](references/git-sources.md)). You want36 the code to read, not the full history.37- **Network is a fallback.** Reach the network only when the source isn't already on disk.38 In sandboxed/offline runs, exhaust local caches first and tell the user if a fetch needs39 network access.4041## The universal workflow42431. **Name the target.** Which package/repo, and — critically — *which version*? Read the44 project's lockfile or manifest to resolve it (`package-lock.json`/`pnpm-lock.yaml`,45 `requirements.txt`/`poetry.lock`, `pom.xml`/`*.gradle`, `go.mod`, `Cargo.lock`,46 `*.csproj`, `Gemfile.lock`, `composer.lock`, `pubspec.lock`, `Package.resolved`).472. **Check the local cache first.** Use the map below to look where that ecosystem already48 stores decompressed source. If it's there, read it in place — no fetch.493. **Fetch into `.scratch/` if missing.** Use the ecosystem's own "download source" path50 (source JARs, `pip download`, `go mod download`, `cargo vendor`, `npm pack`, etc.), or51 clone the Git repo at the matching tag. Land it under `.scratch/sources/…`.524. **Read narrowly.** Grep for the symbol, type, or string you need. Note the53 `file:line` and the exact version you read, so any claim you make is traceable.5455## Ecosystem cache map — look here before fetching5657| Ecosystem | Already-decompressed source on disk | Reference |58|---|---|---|59| **Any Git host** (GitHub/GitLab/Bitbucket/…) | — (clone into `.scratch/`) | [git-sources.md](references/git-sources.md) |60| **JavaScript / TypeScript** | `node_modules/<pkg>/`; pnpm store `~/.local/share/pnpm/store` / `node_modules/.pnpm/`; Yarn Berry `.yarn/cache` (zipped) | [javascript.md](references/javascript.md) |61| **Python** | active venv `…/site-packages/<pkg>/`; system `site-packages`; `pip download --no-binary` for sdist | [python.md](references/python.md) |62| **Java / Kotlin / JVM** | Maven `~/.m2/repository/…` (`-sources.jar`); Gradle `~/.gradle/caches/modules-2/…` | [jvm.md](references/jvm.md) |63| **Android** | SDK `$ANDROID_HOME/sources/android-<api>/`; AARs in Gradle cache; AndroidX / AOSP via `cs.android.com` | [android.md](references/android.md) |64| **Go** | module cache `$GOPATH/pkg/mod/<module>@<version>/` (read-only) | [go.md](references/go.md) |65| **Rust** | registry `~/.cargo/registry/src/<index>/<crate>-<version>/` | [rust.md](references/rust.md) |66| **.NET / C#** | NuGet `~/.nuget/packages/<pkg>/<version>/` (lib DLLs; source via SourceLink/decompile) | [dotnet.md](references/dotnet.md) |67| **Ruby / PHP / Swift / Dart** | RubyGems `$GEM_HOME/gems/`; Composer `vendor/`; SwiftPM `.build/checkouts/`; Dart pub cache `~/.pub-cache/hosted/…` | [ruby-php-swift-dart.md](references/ruby-php-swift-dart.md) |68| **C / C++ / system** | system headers `/usr/include`; vcpkg/conan caches; else clone upstream | [native-c-cpp.md](references/native-c-cpp.md) |6970If `$ARGUMENTS` opens with a Git URL, treat it as a clone request →71[git-sources.md](references/git-sources.md). If it names a `package@version` or an72ecosystem keyword, route to that ecosystem's reference. Otherwise infer the ecosystem from73the project's manifests and the map above.7475## When NOT to use this7677- The answer is already in the project's own tree — read that first.78- The library's public docs fully cover the question and version drift isn't a risk (still79 prefer source for exact signatures and edge cases).80- You'd be fetching just to run or build it — that's a dependency-adoption task, not a81 study task; this skill only reads.