关于 gh-cli
面向使用 GitHub `gh` 管理问题、拉取请求和标签的 Agent 与自动化任务,提供操作前检查及常见认证故障排查,并要求只报告已验证的结果或确切错误。
主要功能
- 01操作前检查认证与仓库访问
- 02排查密钥链与配置问题
- 03处理账号选择和 SAML SSO
- 04用机器可读输出核验结果
- 05提供服务端自动化方案
适用场景
- 01创建或更新问题并避免重复
- 02通过 `gh` 管理拉取请求和标签
- 03排查沙盒 Shell 中的认证失败
- 04在 CI 或批量任务中运行 GitHub 操作
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ bobmatnyc/ claude-mpm-skills --skill gh-cli安装后在 Claude Code 中输入/gh-cli确认已加载。
附带文件metadata.json
详细介绍
GitHub gh CLI
使用 GitHub gh CLI 执行 issue、PR 和标签操作的可靠模式——专为自动化和子 Agent 环境打造;在这些环境中,静默的身份验证失败很常见,而捏造结果则是最糟糕的情况。
适用场景:任何时候通过 gh 创建、列出、查看、编辑或关闭 GitHub issue、PR 或标签,尤其是在沙盒 shell 或委派的子 Agent 中。
首要规则:绝不捏造
如果无法验证操作是否成功,请报告失败并提供确切错误。绝不要编造 issue 编号、URL 或“创建成功”之类的消息。明确、准确地报告失败,永远胜过假装成功——下游 Agent 和人类会根据报告采取行动。
1. 预检验证(在执行任何操作之前运行)
务必先确认身份验证和仓库访问权限。这些检查成本低、只读,能在更改任何内容之前发现绝大多数问题。
# 1. Confirm you are authenticated and see which account/scopes are active
gh auth status
# 2. Confirm you can actually reach the target repo (proves token + SSO + network)
gh repo view <org>/<repo> --json name,url
- 如果
gh auth status报告 “not logged into any GitHub hosts” 或出现任何错误,立即停止。不要运行创建、编辑或关闭操作。根据下文各节进行诊断,然后逐字报告确切错误。 - 如果
gh repo view失败(404、SAML、Bad credentials),立即停止。令牌可能有效,但没有访问此组织或仓库的权限。请报告确切错误。 - 只有在两条命令都成功后,才能继续执行会更改内容的操作。
在子 Agent 中:将预检失败视为必须停止的情况。身份验证失败时却返回“我创建了 issue #42”,正是此技能旨在防止的失败模式。
2. 注意事项:沙盒 / OS 密钥链访问
gh 的 OAuth(密钥环)令牌存储在 OS 密钥链中(macOS Keychain、Linux Secret Service)。沙盒 shell 无法读取密钥链,因此 gh 会回退到“未找到凭据”,并报告 “not logged into any GitHub hosts”——即使有效凭据确实存在。
症状:gh auth status 显示未登录,但在普通终端中运行相同命令却成功。
解决方法:禁用沙盒运行 gh,以便其访问密钥链。
- 在 Claude Code 中,对运行
gh的 Bash 工具调用设置dangerouslyDisableSandbox: true。 - 禁用沙盒后重新运行预检(
gh auth status),确认成功后再继续。
3. 注意事项:过时的 GH_CONFIG_DIR
如果设置了环境变量 GH_CONFIG_DIR,gh 会从该目录读取配置(包括凭据所在的 hosts.yml);否则会从 ~/.config/gh 读取。过时或错误的 GH_CONFIG_DIR 指向不存在的目录,会导致 gh 报告“未登录”,即使有效的密钥环凭据存在于其他位置。
诊断:
echo "$GH_CONFIG_DIR" # Is it set? To what?
ls "$GH_CONFIG_DIR" # Does the directory exist? Has hosts.yml?
查找实际存有凭据的配置目录:
find ~ -maxdepth 5 -name hosts.yml -path '*gh*'
解决方法——将 GH_CONFIG_DIR 指向实际配置目录,或取消设置以回退到默认目录:
# Option A: point at the working config explicitly
GH_CONFIG_DIR=/path/to/real/gh-config gh auth status
# Option B: unset to use ~/.config/gh
unset GH_CONFIG_DIR && gh auth status
4. 多个账户
gh auth status 可能会列出多个账户,其中一个标记为活动账户。gh 会使用活动账户。如果该账户无权访问目标组织或仓库,请切换账户:
gh auth status # see all accounts; note which is "Active account: true"
gh auth switch -u <username> # make the correct account active
gh repo view <org>/<repo> --json name,url # re-verify after switching
5. 注意事项:组织的 SAML SSO 会拒绝 PAT
从 .env 文件中读取的个人访问令牌经常会被强制执行 SAML SSO 的组织拒绝:
HTTP 403: Resource protected by organization SAML enforcement.
You must grant your Personal Access token access to this organization.
原因:即使 PAT 有效,也必须通过浏览器授权,针对特定组织完成 SSO 授权。在无头环境中从 .env 注入的令牌通常从未完成过该授权。
首选解决方法:使用已获组织 SSO 授权的密钥环 OAuth 令牌(gh auth login)——OAuth 登录会交互式提示进行 SSO 授权。如需授权现有 PAT,请在 GitHub 设置中完成组织的 SSO 浏览器授权(Developer settings → PATs → Configure SSO)。
经验法则:对于强制执行 SSO 的组织,优先使用密钥环 OAuth,而不是 .env 中的 PAT。
6. CI / 批量操作的服务端回退方案
如果本地身份验证不可用、不可靠,或者需要执行可靠的批量操作,请在持有 GitHub App 安装令牌的服务端运行 gh。App 安装令牌不受 SSO 限制,且权限范围限定为该安装,因此是最可靠的自动化途径。
一种常见模式是通过 AWS SSM 将命令分派到服务端:
aws ssm send-command \
--instance-ids <instance-id> --region <region> \
--document-name "AWS-RunShellScript" \
--parameters '{"commands":["gh issue create --repo <org>/<repo> --title \"...\" --body \"...\""]}'
如果无法确保本地身份验证由钥匙串提供,请将此方案视为自动化 / CI 的可靠途径。
7. 常用命令速查
使用 --json <fields> --jq <filter> 获取可供机器解析的输出,并通过它确认结果,而不是只相信退出码。
Issues
# Create — capture the returned URL; do not invent it
gh issue create --repo <org>/<repo> --title "Title" --body "Body" --label bug
# List (parseable)
gh issue list --repo <org>/<repo> --state open --json number,title,url --jq '.[]'
# View a specific issue
gh issue view <number> --repo <org>/<repo> --json number,title,state,url
# Close
gh issue close <number> --repo <org>/<repo> --comment "Resolved"
# Edit (also the basis of upsert-by-title — see below)
gh issue edit <number> --repo <org>/<repo> --add-label triaged --body "Updated body"
按标题更新或创建模式(幂等地创建 issue)
为避免重复创建 issue,请在创建前检查是否存在标题相同且仍处于打开状态的 issue:
existing=$(gh issue list --repo <org>/<repo> --state open \
--search "in:title \"My exact title\"" \
--json number,title --jq '.[] | select(.title=="My exact title") | .number' | head -n1)
if [ -n "$existing" ]; then
gh issue edit "$existing" --repo <org>/<repo> --body "Refreshed body"
else
gh issue create --repo <org>/<repo> --title "My exact title" --body "..."
fi
Pull requests
gh pr view <number> --repo <org>/<repo> --json number,title,state,url,mergeable
gh pr list --repo <org>/<repo> --state open --json number,title,headRefName --jq '.[]'
Labels
gh label create "code-intelligence" --repo <org>/<repo> --color BFD4F2 --description "..."
gh label list --repo <org>/<repo> --json name,color --jq '.[].name'
故障排查 / 环境特定说明
本节记录了上述故障模式的一个具体案例,并给出完整示例:当工单处理子 Agent 无法在 duettoresearch/code-intelligence 中创建 issue 时,我们对问题进行了诊断。通用说明适用于实际操作;本案例则展示了这些问题在实践中如何交织出现。
症状
工单处理子 Agent 报告 “not logged into any GitHub hosts” 和 “Bad credentials”,无法在 duettoresearch/code-intelligence 中创建 issue。有些运行可能会因此打算报告一个捏造的 issue URL——不要这样做。
查明的根本原因(多个原因叠加)
GH_CONFIG_DIR已过期 — 子 Agent 继承了GH_CONFIG_DIR=/Users/masa/.config/gh-duetto,但该目录不存在,因此gh无法找到凭据。(参见 §3。)- 沙盒阻止访问钥匙串 — Bash 沙盒阻止读取 OS 钥匙串,导致出现“未登录”的错误提示。(参见 §2。)
.env.local中的 PAT 受到 SAML SSO 限制 —duettoresearch组织启用了 SAML 验证,因此.env.local中的 PAT 被拒绝。(参见 §5。)- 钥匙串令牌已过期 — 账户
bobmatnyc留下的钥匙串令牌返回 HTTP 401 Bad credentials。(参见 §4 — 当前活动账户错误。)
已验证可用的配置
GH_CONFIG_DIR=/Users/masa/.config/gh-personal # real config dir with valid hosts.yml
sandbox: disabled # so gh can read the keychain
active account: bob-duetto # scopes: gist, read:org, repo, workflow
result: gh repo view duettoresearch/code-intelligence → succeeds
标准修复流程
# Run gh with the real config dir AND the sandbox disabled
# (in Claude Code: dangerouslyDisableSandbox: true on the Bash call)
GH_CONFIG_DIR=/Users/masa/.config/gh-personal gh auth status
# If the wrong account is active, switch first:
GH_CONFIG_DIR=/Users/masa/.config/gh-personal gh auth switch -u bob-duetto
# Then re-verify before any mutation:
GH_CONFIG_DIR=/Users/masa/.config/gh-personal gh repo view duettoresearch/code-intelligence --json name,url
只有在预检成功后,子 Agent 才应运行 gh issue create 等命令,并且必须报告实际返回的 URL,绝不能捏造 URL。
反模式
❌ 不要:未经验证就报告成功
gh issue create ... # exit code ignored
# "Created issue #42!" ← fabricated; the command may have failed silently
✅ 应当:捕获并确认结果
url=$(gh issue create --repo <org>/<repo> --title "T" --body "B")
echo "Created: $url" # report the actual returned URL, or the actual error
❌ 不要:认为“未登录”就意味着没有凭据
这通常意味着沙盒 / 钥匙串问题,或 GH_CONFIG_DIR 已过期——请先诊断(§2、§3)。
❌ 不要:在启用 SSO 验证的组织中依赖 .env 中的 PAT
优先使用钥匙串 OAuth 或服务端 App 安装令牌(§5、§6)。
总结
- 先进行预检:执行任何操作前,先运行
gh auth status和gh repo view。 - 绝不捏造:失败时报告确切错误;成功时报告实际 URL。
- 了解四种故障模式:沙盒 / 钥匙串、
GH_CONFIG_DIR已过期、多个账户、SAML SSO 拒绝 PAT。 - 自动化途径:CI / 批量操作使用服务端 GitHub App 安装令牌(不受 SSO 限制)。