mcpField
G
gh-cli

gh-cli

github.com/bobmatnyc开发78190 次安装16 周前更新
代码仓库

关于 gh-cli

面向使用 GitHub `gh` 管理问题、拉取请求和标签的 Agent 与自动化任务,提供操作前检查及常见认证故障排查,并要求只报告已验证的结果或确切错误。

主要功能

  1. 01操作前检查认证与仓库访问
  2. 02排查密钥链与配置问题
  3. 03处理账号选择和 SAML SSO
  4. 04用机器可读输出核验结果
  5. 05提供服务端自动化方案

适用场景

  1. 01创建或更新问题并避免重复
  2. 02通过 `gh` 管理拉取请求和标签
  3. 03排查沙盒 Shell 中的认证失败
  4. 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——不要这样做。

查明的根本原因(多个原因叠加)
  1. GH_CONFIG_DIR 已过期 — 子 Agent 继承了 GH_CONFIG_DIR=/Users/masa/.config/gh-duetto,但该目录不存在,因此 gh 无法找到凭据。(参见 §3。)
  2. 沙盒阻止访问钥匙串 — Bash 沙盒阻止读取 OS 钥匙串,导致出现“未登录”的错误提示。(参见 §2。)
  3. .env.local 中的 PAT 受到 SAML SSO 限制 — duettoresearch 组织启用了 SAML 验证,因此 .env.local 中的 PAT 被拒绝。(参见 §5。)
  4. 钥匙串令牌已过期 — 账户 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 限制)。

评论

支持 Markdown