# Exploring Github

> Explore and understand GitHub repositories using the gh CLI. Use when asked to browse repos, read files, search code, analyze issues/PRs/commits/releases, or understand codebases on GitHub. Replaces MCP-based GitHub tools with zero dependencies beyond gh. Use when this capability is needed.

- Skill: `tomevault-io/exploring-github` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/exploring-github`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/exploring-github/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/exploring-github

---


# Exploring GitHub

Explore and understand GitHub repositories using the `gh` CLI — a zero-dependency alternative to MCP-based GitHub context servers like gitctx.

## Prerequisites

- `gh` CLI installed and authenticated
- Works with any MCP client: Claude Code, Amp, Pi, or any agent with shell access

If `gh` is not found or not authenticated, stop and ask the user to install/authenticate it. If a command fails for a non-blocking reason (e.g., rate limit on a non-critical call), skip it and continue.

## Context State

Maintain a mental "current repo" context. Once the user specifies a repo (e.g., `rust-lang/rust`), use `-R owner/repo` on all subsequent `gh` commands. Track:

- **Repo**: `OWNER/REPO` — always pass via `-R`
- **Branch**: default branch unless user switches — pass via `--branch` or `@ref` where applicable
- **Path prefix**: for scoped file navigation

## Tool Reference

### 1. Repository Discovery & Metadata

**Find/search repos:**
```bash
gh search repos "<query>" --sort stars --limit 10 --json fullName,description,stargazersCount,language,updatedAt
```

**View repo metadata:**
```bash
gh repo view OWNER/REPO --json name,description,defaultBranchRef,isPrivate,diskUsage,forkCount,stargazerCount,languages,homepageUrl
```

**List branches:**
```bash
gh api repos/OWNER/REPO/branches --paginate --jq '.[].name'
```

### 2. Code Navigation

**List directory contents (root or subdir):**
```bash
gh api repos/OWNER/REPO/contents/PATH --jq '.[] | "\(.type)\t\(.name)\t\(.size // "")"' -H "Accept: application/vnd.github.v3+json"
```
For a specific branch:
```bash
gh api "repos/OWNER/REPO/contents/PATH?ref=BRANCH" --jq '.[] | "\(.type)\t\(.name)\t\(.size // "")"'
```

**Read a file:**
```bash
gh api repos/OWNER/REPO/contents/PATH -H "Accept: application/vnd.github.v3.raw" 2>&1 | head -500
```
For a specific branch:
```bash
gh api "repos/OWNER/REPO/contents/PATH?ref=BRANCH" -H "Accept: application/vnd.github.v3.raw" 2>&1 | head -500
```

**Read multiple files (run in parallel):**
Read each file with the command above. Run multiple Bash calls in parallel for efficiency.

**Get full repo tree (recursive):**
```bash
gh api repos/OWNER/REPO/git/trees/BRANCH?recursive=1 --jq '.tree[] | select(.type=="blob") | .path' | head -200
```

**Search code in a repo:**
```bash
gh search code "<query>" --repo OWNER/REPO --limit 20 --json path,textMatches
```

**Search code globally:**
```bash
gh search code "<query>" --language LANG --limit 20 --json repository,path,textMatches
```

### 3. Issues

**List/search issues:**
```bash
gh issue list -R OWNER/REPO --state all --search "<query>" --limit 20 --json number,title,state,author,labels,createdAt,updatedAt
```

**Get issue details:**
```bash
gh issue view NUMBER -R OWNER/REPO --json number,title,state,body,author,labels,assignees,comments,createdAt,closedAt
```

**List issue comments:**
```bash
gh issue view NUMBER -R OWNER/REPO --json comments --jq '.comments[] | "[\(.author.login) \(.createdAt)]\n\(.body)\n---"'
```

### 4. Pull Requests

**List/search PRs:**
```bash
gh pr list -R OWNER/REPO --state all --search "<query>" --limit 20 --json number,title,state,author,labels,baseRefName,headRefName,createdAt,mergedAt
```

**Get PR details:**
```bash
gh pr view NUMBER -R OWNER/REPO --json number,title,state,body,author,labels,assignees,comments,reviews,additions,deletions,changedFiles,baseRefName,headRefName,mergedAt,mergedBy
```

**Get PR diff:**
```bash
gh pr diff NUMBER -R OWNER/REPO
```

**List PR review comments:**
```bash
gh api repos/OWNER/REPO/pulls/NUMBER/comments --jq '.[] | "[\(.user.login) \(.created_at) \(.path):\(.line // .original_line)]\n\(.body)\n---"'
```

### 5. Commits

**List commits:**
```bash
gh api repos/OWNER/REPO/commits --paginate -f sha=BRANCH -f per_page=20 --jq '.[] | "\(.sha[:8]) \(.commit.author.date) \(.commit.author.name): \(.commit.message | split("\n")[0])"'
```

With path filter:
```bash
gh api repos/OWNER/REPO/commits -f sha=BRANCH -f path=PATH -f per_page=20 --jq '.[] | "\(.sha[:8]) \(.commit.author.date) \(.commit.author.name): \(.commit.message | split("\n")[0])"'
```

With author filter:
```bash
gh api repos/OWNER/REPO/commits -f sha=BRANCH -f author=USERNAME -f per_page=20 --jq '.[] | "\(.sha[:8]) \(.commit.author.date): \(.commit.message | split("\n")[0])"'
```

**Get commit details:**
```bash
gh api repos/OWNER/REPO/commits/SHA --jq '{sha: .sha, message: .commit.message, author: .commit.author, files: [.files[] | {filename, status, additions, deletions, patch}]}'
```

**Compare commits/refs:**
```bash
gh api repos/OWNER/REPO/compare/BASE...HEAD --jq '{ahead_by, behind_by, total_commits: .total_commits, files: [.files[] | {filename, status, additions, deletions}], commits: [.commits[] | {sha: .sha[:8], message: .commit.message | split("\n")[0]}]}'
```

**Blame a file:**
```bash
gh api graphql -f query='
  query {
    repository(owner: "OWNER", name: "REPO") {
      object(expression: "BRANCH:PATH") {
        ... on Blob {
          blame {
            ranges {
              startingLine
              endingLine
              commit {
                abbreviatedOid
                message
                author { name date }
              }
            }
          }
        }
      }
    }
  }
' --jq '.data.repository.object.blame.ranges[] | "L\(.startingLine)-\(.endingLine) \(.commit.abbreviatedOid) \(.commit.author.name) (\(.commit.author.date)): \(.commit.message | split("\n")[0])"'
```

### 6. Releases

**List releases:**
```bash
gh release list -R OWNER/REPO --limit 20 --json tagName,name,publishedAt,isPrerelease,isDraft,isLatest
```

**Get release details:**
```bash
gh release view TAG -R OWNER/REPO --json tagName,name,body,publishedAt,author,assets,isPrerelease,isDraft
```

**Compare releases (commits between two tags):**
```bash
gh api repos/OWNER/REPO/compare/TAG1...TAG2 --jq '{total_commits: .total_commits, commits: [.commits[] | {sha: .sha[:8], message: .commit.message | split("\n")[0]}], files_changed: [.files[] | .filename]}'
```

### 7. Repository Insights

**Top contributors:**
```bash
gh api repos/OWNER/REPO/contributors -f per_page=20 --jq '.[] | "\(.login): \(.contributions) commits"'
```

**Repository stats (commit activity):**
```bash
gh api repos/OWNER/REPO/stats/participation --jq '"Owner commits (last 52 weeks): \(.owner | add)\nAll commits (last 52 weeks): \(.all | add)"'
```

**Language breakdown:**
```bash
gh api repos/OWNER/REPO/languages
```

**Dependency graph (if available):**
```bash
gh api repos/OWNER/REPO/dependency-graph/sbom --jq '.sbom.packages[:30][] | "\(.name) \(.versionInfo // "unknown")"'
```

## Usage Recommendation

This skill is best used via a **subagent** (e.g. Claude Code's Task tool, or any agent that supports delegated subtasks). GitHub exploration generates a lot of intermediate output — file trees, code snippets, API responses — that is useful for answering the question but clutters the main conversation. Delegating to a subagent keeps that noise isolated and returns only the synthesized answer.

## Exploration Strategy

Follow a **broad-then-narrow** approach:

1. **Orient** — start with repo metadata (`gh repo view`) and file tree to understand project shape
2. **Survey** — read key entry points: README, config files (package.json, Cargo.toml, go.mod), main entry files
3. **Target** — use code search and directory listing to locate the specific area asked about
4. **Deep-read** — read the relevant files thoroughly; do not skim or summarize code you have not actually read
5. **Cross-reference** — connect findings across concerns (trace a function from definition to usage to tests to related PRs/issues)

Run independent operations in parallel whenever possible. For example, read multiple files at once, or search code while listing a directory. When exploring unfamiliar territory, adjust your investigation based on what you discover — do not follow a rigid script.

### Codebase Understanding

1. `gh repo view` — get overview, default branch, languages
2. `gh api .../git/trees/BRANCH?recursive=1` — get file tree
3. Read key files: README, config files, entry points
4. `gh search code` — find specific patterns or implementations
5. Synthesize architecture understanding

### Issue/PR Triage

1. `gh issue list` / `gh pr list` with filters
2. `gh issue view` / `gh pr view` for details
3. `gh pr diff` for code changes
4. Cross-reference with commits and blame

### Release Analysis

1. `gh release list` — recent releases
2. `gh api .../compare/TAG1...TAG2` — diff between releases
3. Check linked issues/PRs for changelog context

## Output Guidelines

- Always use `--json` + `--jq` for structured, token-efficient output
- Pipe large outputs through `head -N` to avoid flooding context
- For file contents, limit to 500 lines unless the user requests more
- Lead with the answer — state the key finding first, then support with details
- Include evidence — reference specific files, line ranges, commit SHAs, issue/PR numbers
- Use Mermaid diagrams when explaining architecture, data flow, or component relationships
- Quantify when possible — "47 files changed across 3 packages" not "many files changed"
- When mentioning files, link to them on GitHub: `[src/auth.rs](https://github.com/OWNER/REPO/blob/BRANCH/src/auth.rs#L10-L25)`

## Error Handling

- Rate-limited? Use `gh api -H "Accept: ..." --cache 1h` for cacheable requests
- 404 errors likely mean private repo without access or wrong path — verify repo name
- Large repos: use tree + targeted reads instead of recursive listing

---
> Converted and distributed by [TomeVault](https://tomevault.io/claim/andrewbastin) — claim your Tome and manage your conversions.
<!-- tomevault:4.0:skill_md:2026-04-11 -->

