/gh
Patterns for invoking the GitHub CLI (gh) from agents. Covers structured output, pagination, repo targeting, search vs list, gh api fallback.
$ npx -y skills add cli/cli --skill gh --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/gh
Context preview
The summary Claude sees to decide when to auto-load this skill.
Patterns for invoking the GitHub CLI (gh) from agents. Covers structured output, pagination, repo targeting, search vs list, gh api fallback.
SKILL.md
gh.SKILL.mdname: gh
description: Patterns for invoking the GitHub CLI (gh) from agents. Covers structured output, pagination, repo targeting, search vs list, gh api fallback.
Reference
Interactivity policy
`gh` already does the right thing in non-TTY contexts: it skips the pager, strips ANSI color, and errors out fast with a helpful message instead of prompting (e.g. `must provide --title and --body when not running interactively`). You don't need to defensively set `GH_PAGER` or pass `--no-pager` (no such flag exists).
Parsing JSON
Human output from `gh` is column-formatted. If you want structured data:
- Add `--json field1,field2,...` for structured output.
- For `gh issue view` and `gh pr view`, use `--json ...,comments` to include comments in structured data; use `--comments` only with the human-readable view.
- Run a command with `--json` and **no field list** to print the full set of
available fields, then pick what you need.
- Use `--jq '<expr>'` for filtering without piping through a separate `jq`.
- Use `--template '<go-template>'` (alongside `--json`) when you want shaped
text output. Note that `--template`/`-T` collides with a body-template flag on a few commands (e.g. `gh pr create -T`, `gh issue create -T`); always check `--help` before assuming which one you're hitting.
Pagination and silent truncation
List commands cap results.
- `gh issue list`, `gh pr list`, `gh search ...`: pass `-L N` (`--limit N`).
The default is usually 30.
- `gh issue list` / `gh pr list` do not expose aggregate totals like
`totalCount` via `--json`. If you need a true total, use `gh api graphql` to query `totalCount`; otherwise, treat `-L` as the cap for the current call.
- For raw API calls use `gh api --paginate <path>`. Combine with
`--jq` and (optionally) `--slurp` to assemble one array.
Repo targeting
`gh` infers the repo from the cwd's git remotes.
Pass `--repo OWNER/REPO` (`-R`) to override the resolved CWD repo.
Search vs list
- `gh search issues|prs|code|repos|commits|users` uses GitHub's search
index and accepts the full search syntax (`is:open`, `author:`, `label:`, `repo:owner/name`, `in:title`, ...). Pass each qualifier as its own bare token, not as one quoted string: `gh search issues repo:cli/cli is:open author:monalisa` works, but `gh search issues "repo:cli/cli is:open"` is treated as a single keyword (parsed as `repo:"cli/cli is:open"`) and fails with `Invalid search query`. Quote only multi-word free text (`gh search issues "broken feature"`). Most qualifiers also have a dedicated flag (`--repo`, `--author`, `--label`, ...). Prefer search for anything cross-repo or filtered by author/label.
- `gh issue list --search "..."` and `gh pr list --search "..."` take the
query as one quoted string (it is a flag value) and are scoped to one repo.
- Bots author as GitHub Apps, so `--author dependabot` matches nothing. Use
`--app dependabot` (on `pr`/`issue list` and `search prs|issues`; expands to `author:app/<slug>`) or `--author "dependabot[bot]"`.
- `gh search issues` also takes `--search-type <lexical|semantic|hybrid>`
(github.com/GHEC only, issues only): use `semantic` when the user describes a problem in natural language rather than exact terms, and `hybrid` to blend keyword and semantic ranking; `lexical` (default) is exact matching.
Issue types, sub-issues, and relationships
Newer `gh issue` subcommands model issue types, sub-issue hierarchy, and blocked-by/blocking relationships.
- `gh issue create`: `--type <name>`, `--parent <number|url>` (creates the
new issue as a sub-issue), `--blocked-by <number|url,...>`, `--blocking <number|url,...>`.
- `gh issue edit` (edits one or more issues in the same repo, e.g.
`gh issue edit 23 34`): `--type <name>` / `--remove-type`, `--parent <n|url>` / `--remove-parent`, `--add-sub-issue <n,n>` / `--remove-sub-issue <n,n>`, `--add-blocked-by <n,n>` / `--remove-blocked-by <n,n>`, `--add-blocking <n,n>` / `--remove-blocking <n,n>`. Relationship and parent refs are issue numbers or URLs; a URL may point to another repo on the same host, but a different host is rejected. `--add-sub-issue` cannot be used when editing more than one issue.
- `gh issue list --type <name>` filters by issue type.
- `gh issue view` and `gh issue list` accept these as `--json` fields (prefer
them over scraping the default text output): `issueType`, `parent`, `subIssues`, `subIssuesSummary`, `blockedBy`, `blocking`. `subIssues`, `blockedBy`, and `blocking` are objects shaped `{"nodes": [...], "totalCount": N}` (not flat arrays), and `nodes` is capped (`subIssues` at 100, `blockedBy`/`blocking` at 50), so compare the node count against `totalCount` to detect truncation.
- GHES: issue types and sub-issues need 3.17+; blocked-by/blocking
relationships need 3.19+.
Attaching images and videos
`--attach <path>` is available on `gh issue create`, `gh issue edit`, `gh issue comment`, `gh pr create`, `gh pr edit`, and `gh pr comment`.
- Repeat `--attach` to upload multiple files:
`gh issue comment 12 --attach ./before.png --attach ./after.png`.
- Each command invocation accepts at most 50 `--attach` values total across
images and videos.
- Supported files are `png`, `jpg`, `jpeg`, `gif`, `webp`, `svg`, `mp4`,
`mov`, and `webm`.
- For an image, append alt text to the path after `#`. Quote the value so the
shell does not treat `#` as a comment: `gh pr create --attach './login.png#The login error state'`. Without alt text, the filename is used.
- `--attach` paths and local Markdown destinations may be absolute or relative
to the directory where `gh` runs.
- If the body references an attached path, `gh` rewrites that Markdown
reference to the uploaded URL. The reference keeps its existing alt text. Otherwise, `gh` appends the attachment to the body. For example: `gh pr edit 23 --body '' --attach ./login.png`.
- Videos cannot take a
Read more
name: gh description: Patterns for invoking the GitHub CLI (gh) from agents. Covers structured output, pagination, repo targeting, search vs list, gh api fallback.
Reference
Interactivity policy
`gh` already does the right thing in non-TTY contexts: it skips the pager, strips ANSI color, and errors out fast with a helpful message instead of prompting (e.g. `must provide --title and --body when not running interactively`). You don't need to defensively set `GH_PAGER` or pass `--no-pager` (no such flag exists).
Parsing JSON
Human output from `gh` is column-formatted. If you want structured data:
- Add `--json field1,field2,...` for structured output.
- For `gh issue view` and `gh pr view`, use `--json ...,comments` to include comments in structured data; use `--comments` only with the human-readable view.
- Run a command with `--json` and **no field list** to print the full set of
available fields, then pick what you need.
- Use `--jq '<expr>'` for filtering without piping through a separate `jq`.
- Use `--template '<go-template>'` (alongside `--json`) when you want shaped
text output. Note that `--template`/`-T` collides with a body-template flag on a few commands (e.g. `gh pr create -T`, `gh issue create -T`); always check `--help` before assuming which one you're hitting.
Pagination and silent truncation
List commands cap results.
- `gh issue list`, `gh pr list`, `gh search ...`: pass `-L N` (`--limit N`).
The default is usually 30.
- `gh issue list` / `gh pr list` do not expose aggregate totals like
`totalCount` via `--json`. If you need a true total, use `gh api graphql` to query `totalCount`; otherwise, treat `-L` as the cap for the current call.
- For raw API calls use `gh api --paginate <path>`. Combine with
`--jq` and (optionally) `--slurp` to assemble one array.
Repo targeting
`gh` infers the repo from the cwd's git remotes.
Pass `--repo OWNER/REPO` (`-R`) to override the resolved CWD repo.
Search vs list
- `gh search issues|prs|code|repos|commits|users` uses GitHub's search
index and accepts the full search syntax (`is:open`, `author:`, `label:`, `repo:owner/name`, `in:title`, ...). Pass each qualifier as its own bare token, not as one quoted string: `gh search issues repo:cli/cli is:open author:monalisa` works, but `gh search issues "repo:cli/cli is:open"` is treated as a single keyword (parsed as `repo:"cli/cli is:open"`) and fails with `Invalid search query`. Quote only multi-word free text (`gh search issues "broken feature"`). Most qualifiers also have a dedicated flag (`--repo`, `--author`, `--label`, ...). Prefer search for anything cross-repo or filtered by author/label.
- `gh issue list --search "..."` and `gh pr list --search "..."` take the
query as one quoted string (it is a flag value) and are scoped to one repo.
- Bots author as GitHub Apps, so `--author dependabot` matches nothing. Use
`--app dependabot` (on `pr`/`issue list` and `search prs|issues`; expands to `author:app/<slug>`) or `--author "dependabot[bot]"`.
- `gh search issues` also takes `--search-type <lexical|semantic|hybrid>`
(github.com/GHEC only, issues only): use `semantic` when the user describes a problem in natural language rather than exact terms, and `hybrid` to blend keyword and semantic ranking; `lexical` (default) is exact matching.
Issue types, sub-issues, and relationships
Newer `gh issue` subcommands model issue types, sub-issue hierarchy, and blocked-by/blocking relationships.
- `gh issue create`: `--type <name>`, `--parent <number|url>` (creates the
new issue as a sub-issue), `--blocked-by <number|url,...>`, `--blocking <number|url,...>`.
- `gh issue edit` (edits one or more issues in the same repo, e.g.
`gh issue edit 23 34`): `--type <name>` / `--remove-type`, `--parent <n|url>` / `--remove-parent`, `--add-sub-issue <n,n>` / `--remove-sub-issue <n,n>`, `--add-blocked-by <n,n>` / `--remove-blocked-by <n,n>`, `--add-blocking <n,n>` / `--remove-blocking <n,n>`. Relationship and parent refs are issue numbers or URLs; a URL may point to another repo on the same host, but a different host is rejected. `--add-sub-issue` cannot be used when editing more than one issue.
- `gh issue list --type <name>` filters by issue type.
- `gh issue view` and `gh issue list` accept these as `--json` fields (prefer
them over scraping the default text output): `issueType`, `parent`, `subIssues`, `subIssuesSummary`, `blockedBy`, `blocking`. `subIssues`, `blockedBy`, and `blocking` are objects shaped `{"nodes": [...], "totalCount": N}` (not flat arrays), and `nodes` is capped (`subIssues` at 100, `blockedBy`/`blocking` at 50), so compare the node count against `totalCount` to detect truncation.
- GHES: issue types and sub-issues need 3.17+; blocked-by/blocking
relationships need 3.19+.
Attaching images and videos
`--attach <path>` is available on `gh issue create`, `gh issue edit`, `gh issue comment`, `gh pr create`, `gh pr edit`, and `gh pr comment`.
- Repeat `--attach` to upload multiple files:
`gh issue comment 12 --attach ./before.png --attach ./after.png`.
- Each command invocation accepts at most 50 `--attach` values total across
images and videos.
- Supported files are `png`, `jpg`, `jpeg`, `gif`, `webp`, `svg`, `mp4`,
`mov`, and `webm`.
- For an image, append alt text to the path after `#`. Quote the value so the
shell does not treat `#` as a comment: `gh pr create --attach './login.png#The login error state'`. Without alt text, the filename is used.
- `--attach` paths and local Markdown destinations may be absolute or relative
to the directory where `gh` runs.
- If the body references an attached path, `gh` rewrites that Markdown
reference to the uploaded URL. The reference keeps its existing alt text. Otherwise, `gh` appends the attachment to the body. For example: `gh pr edit 23 --body '' --attach ./login.png`.
- Videos cannot take a
GitHub CLI, or the gh CLI, is GitHub on the command line. It brings pull requests, issues, and other GitHub concepts to the terminal next to where you are already working with git and your code.
Repo: cli/cli

