GitHub CLI (gh)

Full GitHub workflow from the terminal — repos, PRs, issues, releases, and raw API access with jq-pipeable JSON.

Your Repository Landscape

All your repos — ranked by size
gh repo list --limit 50 --json name,diskUsage | jq -r '.[] | "\(.diskUsage)\t\(.name)"' | sort -rn
Repos ranked by last activity
gh repo list --limit 30 --json name,pushedAt | jq -r '.[] | "\(.pushedAt[:10])\t\(.name)"' | sort -r
Repos by language
gh repo list --limit 50 --json name,primaryLanguage | jq -r '.[] | "\(.primaryLanguage.name // "none")\t\(.name)"' | sort
Count repos per language
gh repo list --limit 100 --json primaryLanguage | jq -r '.[].primaryLanguage.name // "none"' | sort | uniq -c | sort -rn
Find repos you haven’t touched in 30+ days
gh repo list --limit 100 --json name,pushedAt | jq -r '.[] | select(.pushedAt < "2026-03-08") | "\(.pushedAt[:10])\t\(.name)"' | sort

Commit History — What Did I Actually Build?

Recent commits across a repo
gh api repos/EvanusModestus/domus-api/commits --jq '.[].commit.message' | head -20
Commits with dates and authors
gh api repos/EvanusModestus/domus-api/commits | jq -r '.[] | "\(.commit.author.date[:10])\t\(.commit.message | split("\n")[0])"' | head -15
Commit count per repo (how active is each project?)
for repo in domus-api domus-captures association-engine dots-quantum; do
    count=$(gh api "repos/EvanusModestus/$repo/commits?per_page=1" -i 2>/dev/null | grep -i 'link:' | grep -oP 'page=\K[0-9]+(?=>; rel="last")' || echo "?")
    printf "%-30s %s commits\n" "$repo" "$count"
done
What changed this week in a repo?
gh api "repos/EvanusModestus/domus-captures/commits?since=2026-04-01" | jq -r '.[] | "\(.commit.author.date[:10]) \(.commit.message | split("\n")[0])"'

File Contents — Read Code Without Cloning

Read a file from any repo (no clone needed)
gh api repos/EvanusModestus/domus-api/contents/src/domus_api/main.py | jq -r '.content' | base64 -d | head -30
List files in a directory
gh api repos/EvanusModestus/domus-api/contents/src/domus_api/routes | jq -r '.[].name'
Get file size and type
gh api repos/EvanusModestus/domus-api/contents/src/domus_api | jq -r '.[] | "\(.size)\t\(.type)\t\(.name)"' | sort -rn
Read a specific file from a branch
gh api "repos/EvanusModestus/domus-api/contents/pyproject.toml?ref=main" | jq -r '.content' | base64 -d

Learning From Other Projects

Search GitHub for code patterns — learn how others implement things
gh search code "AssociationGraph" --language python --json repository,path | jq -r '.[] | "\(.repository.nameWithOwner)\t\(.path)"'
Search repos by topic
gh search repos "knowledge graph" --language python --json fullName,description,stargazersCount | jq -r '.[] | "\(.stargazersCount)\t\(.fullName)\t\(.description[:60])"' | sort -rn | head -10
Search for specific file patterns in repos
gh search code "from fastapi import" --language python --json repository,path | jq -r '.[] | .repository.nameWithOwner' | sort -u | head -10
Find popular Python CLI tools (study their structure)
gh search repos "typer cli" --language python --sort stars --json fullName,stargazersCount,description | jq -r '.[] | "\(.stargazersCount)\t\(.fullName)\t\(.description[:50])"' | head -10
Read someone else’s pyproject.toml (learn packaging patterns)
gh api repos/tiangolo/fastapi/contents/pyproject.toml | jq -r '.content' | base64 -d | head -40

Issues & PRs — Project Intelligence

Your open issues across all repos
gh search issues --author @me --state open --json repository,title,createdAt | jq -r '.[] | "\(.createdAt[:10])\t\(.repository.nameWithOwner)\t\(.title)"' | sort -r
PRs you’ve created
gh search prs --author @me --json repository,title,state | jq -r '.[] | "\(.state)\t\(.repository.nameWithOwner)\t\(.title)"'
Create an issue from the terminal
gh issue create --repo EvanusModestus/domus-api --title "Phase 3: Ollama RAG integration" --body "See roadmap partial for architecture design"
Create an issue with labels
gh issue create --repo EvanusModestus/association-engine --title "Add path traversal (BFS)" --label "enhancement" --body "assoc path CISSP consulting should find multi-hop connections"

Releases & Tags — Version Management

Create a release with auto-generated notes
gh release create v0.1.0 --repo EvanusModestus/association-engine --generate-notes --title "Association Engine v0.1.0"
List releases
gh release list --repo EvanusModestus/domus-api
Download a release asset
gh release download v1.0.0 --repo owner/repo --pattern "*.tar.gz"

Gists — Quick Knowledge Snippets

Create a gist from a file
gh gist create validate.sh --desc "domus-api endpoint validation script"
Create a gist from stdin
curl -s localhost:8080/associations/python | jq | gh gist create --desc "Python associations graph" --filename python-associations.json
List your gists
gh gist list
Read a gist
gh gist view <gist-id>

Cross-Repo Knowledge Queries

Which repos have a CLAUDE.md? (who uses Claude Code?)
for repo in $(gh repo list --limit 50 --json name -q '.[].name'); do
    exists=$(gh api "repos/EvanusModestus/$repo/contents/.claude/CLAUDE.md" 2>/dev/null | jq -r '.name // empty')
    [[ -n "$exists" ]] && echo "  ✅ $repo"
done
Which repos have tests?
for repo in $(gh repo list --limit 30 --json name -q '.[].name'); do
    has_tests=$(gh api "repos/EvanusModestus/$repo/contents/tests" 2>/dev/null | jq 'length' 2>/dev/null)
    [[ "$has_tests" -gt 0 ]] 2>/dev/null && echo "  ✅ $repo ($has_tests test files)"
done
Which repos have pyproject.toml? (Python projects)
for repo in $(gh repo list --limit 50 --json name -q '.[].name'); do
    exists=$(gh api "repos/EvanusModestus/$repo/contents/pyproject.toml" 2>/dev/null | jq -r '.name // empty')
    [[ -n "$exists" ]] && echo "  $repo"
done
Compare two repos' directory structures
diff <(gh api repos/EvanusModestus/domus-api/contents/src/domus_api | jq -r '.[].name' | sort) \
     <(gh api repos/EvanusModestus/association-engine/contents/src/association_engine | jq -r '.[].name' | sort)

GitHub Actions — CI/CD Intelligence

List workflow runs
gh run list --repo EvanusModestus/domus-captures --limit 5
View a specific run
gh run view <run-id>
Watch a run in real-time
gh run watch <run-id>

Notifications & Activity

Your notifications
gh api notifications | jq -r '.[] | "\(.updated_at[:10])\t\(.subject.type)\t\(.subject.title)"' | head -10
Mark all notifications as read
gh api -X PUT notifications

The Power Pattern: gh + jq + awk

Generate a markdown report of all your repos
{
    echo "# GitHub Repository Report — $(date +%Y-%m-%d)"
    echo ""
    echo "## Repos by Size"
    gh repo list --limit 50 --json name,diskUsage | jq -r '.[] | "- \(.name): \(.diskUsage) KB"' | head -10
    echo ""
    echo "## Repos by Activity"
    gh repo list --limit 20 --json name,pushedAt | jq -r '.[] | "- \(.name): last push \(.pushedAt[:10])"'
    echo ""
    echo "## Language Distribution"
    gh repo list --limit 100 --json primaryLanguage | jq -r '.[].primaryLanguage.name // "none"' | sort | uniq -c | sort -rn | awk '{printf "- %s: %d repos\n", $2, $1}'
}
Export all repos as YAML (for association engine seed data)
echo "associations:"
gh repo list --limit 50 --json name,primaryLanguage | jq -r '.[] | "  - source: \(.name)\n    relation: uses\n    target: \(.primaryLanguage.name // "unknown")"'

See Also

  • GitHub Releases — asset discovery, download, and verification

  • Remotes — SSH vs HTTPS, multi-remote setups