mcpField
C
cyrus-setup-github

cyrus-setup-github

github.com/cyrusagents开发8791.1k 次安装今天更新
代码仓库

关于 cyrus-setup-github

cyrus-setup-github 是为 Cyrus 配置 GitHub CLI 和 Git 身份的技能,也可选创建 GitHub App 与 Webhook。它为 Cyrus 创建分支、提交和 PR,并可接收 PR 评论与审查中的 @提及。

主要功能

  1. 01检查并配置 gh 身份验证
  2. 02设置全局 Git 用户名和邮箱
  3. 03可选创建 GitHub App
  4. 04配置 Webhook 凭据
  5. 05将 App 安装到目标仓库

适用场景

  1. 01为 Cyrus 配置 GitHub 提交身份
  2. 02启用 PR 评论和审查中的 @提及响应
  3. 03让 Cyrus 接收仓库 Webhook

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/cyrusagents/cyrus --skill cyrus-setup-github

安装后在 Claude Code 中输入/cyrus-setup-github确认已加载。

详细介绍

关键:绝不要对 ~/.cyrus/.env 或 ~/.cyrus/ 内的任何文件使用 Read、Edit 或 Write 工具。只能使用 Bash 命令(grep、printf >> 等)与环境变量文件交互——绝不能将密钥读入对话上下文。

设置 GitHub

配置 GitHub CLI 和 git,以便 Cyrus 创建分支、提交和拉取请求。还可选择创建 GitHub App,以便 Cyrus 接收并回复 PR 评论和审查中的 @提及、自动变基和合并,并根据 CI 失败自动修复(即将推出)。


A 部分:GitHub CLI + Git 配置(出站)

第 1 步:检查现有配置

检查 gh 是否已通过身份验证:

gh auth status 2>&1

如果已通过身份验证,检查 git 配置:

git config --global user.name
git config --global user.email

如果 gh 身份验证和 git 配置均已设置,请告知用户:

GitHub 已完成配置。正在跳转至 Webhook 设置。

跳转至 B 部分。

第 2 步:验证 GitHub CLI 身份

如果 gh 尚未通过身份验证:

gh auth login

这会打开交互式浏览器流程。让用户完成操作。

完成后,验证:

gh auth status
第 3 步:配置 Git 身份信息

如果尚未设置 git 用户名或邮箱,请询问用户希望使用的值:

Cyrus 提交的提交记录中应显示什么名称? (例如,你的姓名或“Cyrus Bot”)

提交记录中应显示什么邮箱? (例如,你的邮箱或 noreply 地址)

然后设置:

git config --global user.name "<name>"
git config --global user.email "<email>"
第 4 步:验证
gh auth status
git config --global user.name
git config --global user.email

B 部分:GitHub App + Webhook(入站 — 可选)

询问用户:

你希望 Cyrus 回复 PR 评论和审查中的 GitHub @提及吗?

  • 是 — 启用 @提及:创建一个 GitHub App,以便 Cyrus 通过 Webhook 接收 PR 评论和审查、在被 @提及时回复,并处理“请求更改”的审查。
  • 否 — 仅处理 PR:Cyrus 会创建分支、提交和 PR,但不会回复评论。

如果选 否 → 跳转至完成部分。

第 5 步:检查现有 Webhook 配置
grep -c '^GITHUB_WEBHOOK_SECRET=.' ~/.cyrus/.env 2>/dev/null
grep -c '^GITHUB_APP_ID=.' ~/.cyrus/.env 2>/dev/null
grep -c '^GITHUB_APP_INSTALLATION_ID=.' ~/.cyrus/.env 2>/dev/null
test -f ~/.cyrus/github-app.pem && echo "PEM exists" || echo "PEM missing"

如果四项检查都通过(1、1、1、“PEM 存在”),则跳转至完成部分——Webhook 已完成配置。

Step 6:收集输入

读取 Webhook 基础 URL:

grep '^CYRUS_BASE_URL=' ~/.cyrus/.env | cut -d= -f2-

如果未设置 CYRUS_BASE_URL,请停止并告知用户先运行端点设置步骤。

使用编排器中的 AGENT_NAME 值(在 /cyrus-setup 的 Step 0 中设置)。如果没有该值,请询问:

GitHub App 应该叫什么名字?(例如,“Cyrus”、“My Code Agent”)

重要 — GitHub @提及自动补全机制的特殊限制:GitHub 在 PR 评论中的自动补全只会建议真实的 GitHub 用户账号,不会建议 App 机器人。这意味着,除非存在名称完全相同的 GitHub 用户,否则 @your-bot 不会出现在自动补全下拉列表中。手动输入提及仍然有效,但要获得最佳体验:

选择名称之前,请检查该名称是否可用作 GitHub 用户名:https://github.com/<name>。如果可用:

  1. 创建一个使用该名称的免费 GitHub 用户账号
  2. 邀请该账号加入你的组织和/或仓库,作为协作者
  3. 将 GITHUB_BOT_USERNAME 设置为该用户名(用户在 @提及中输入的名称,而不是 <slug>[bot])

这是启用自动补全最简单的方法——这是 GitHub 一个有点荒唐的限制,但这也是已知的解决方法。

如果没有匹配的 GitHub 用户,手动输入 @提及仍然有效,但不会自动补全。此时,用户需要设置共同创作(通过 git 消息模板或添加 Co-authored-by: 的 prepare-commit-msg 钩子),才能让机器人的名称显示为仓库贡献者;这个过程比较复杂。

询问:

应在哪里创建 GitHub App?

  • 个人账号(github.com/settings/apps)
  • 组织 — 哪个组织?(github.com/organizations/<ORG>/settings/apps)

如果适用,请保存组织名称。

询问:

GitHub App 应使用什么主页 URL? 该 URL 会作为网站显示在 App 的设置页面上。它不会产生任何功能影响——GitHub 只会将其显示为链接。大多数用户会使用公司网站、GitHub 组织页面或任意占位 URL。

(例如,https://github.com/your-org、公司 URL,或直接使用 https://example.com)

Step 7:构建 Manifest JSON

构造 Manifest,并替换 AGENT_NAME、HOMEPAGE_URL 和 CYRUS_BASE_URL:

{
  "name": "<AGENT_NAME>",
  "url": "<HOMEPAGE_URL>",
  "redirect_url": "http://localhost:8976",
  "hook_attributes": {
    "url": "<CYRUS_BASE_URL>/github-webhook",
    "active": true
  },
  "public": false,
  "default_permissions": {
    "contents": "write",
    "issues": "write",
    "pull_requests": "write",
    "repository_hooks": "write"
  },
  "default_events": [
    "issue_comment",
    "pull_request_review",
    "pull_request_review_comment",
    "repository"
  ]
}

**注意:**GitHub 的 Manifest 流程要求提供 redirect_url。实际重定向时,会在此 URL 后附加 ?code= 参数——重要的是该 code,而不是目标页面。

步骤 8:通过 Manifest 创建 GitHub App

GitHub 的 manifest 流程通过向 App 创建 URL 发送包含 manifest 字段的表单来工作。用户批准后,GitHub 会重定向到一个包含 code 参数的 URL。

确定创建 URL:

  • 个人:https://github.com/settings/apps/new
  • 组织:https://github.com/organizations/<ORG>/settings/apps/new

GitHub 的 manifest 流程要求向创建 URL 发送包含 manifest 字段的表单 POST 请求——页面本身没有 manifest 输入字段。所有路径都使用相同的辅助 HTML 页面方案。

首先,创建辅助页面并通过本地 Web 服务器提供服务。这适用于本地和远程/无头环境(例如,通过 tmux/SSH 连接到服务器)。manifest JSON 必须进行 HTML 实体转义(将 " 替换为 &quot;),因为它会放在 HTML 属性中:

# Escape the manifest JSON for safe embedding in an HTML attribute
MANIFEST_HTML_ESCAPED=$(echo '<MANIFEST_JSON>' | sed 's/"/\&quot;/g')

cat > /tmp/github-app-manifest.html << HTMLEOF
<form method="post" action="<CREATION_URL>">
  <input type="hidden" name="manifest" value="$MANIFEST_HTML_ESCAPED">
  <p>Click the button to create the GitHub App:</p>
  <button type="submit" style="font-size:18px;padding:12px 24px;">Create GitHub App</button>
</form>
HTMLEOF

# Serve the page on a local port (works for headless/remote setups)
python3 -m http.server 8976 --directory /tmp &
HTTP_SERVER_PID=$!
echo "Serving at http://localhost:8976/github-app-manifest.html"

用户完成流程后,停止服务器:

kill $HTTP_SERVER_PID 2>/dev/null

根据可用情况选择自动化路径:

  1. 如果有 claude-in-chrome MCP 工具 → 使用路径 A-1
  2. 如果已安装 agent-browser 且已连接 Chrome 调试会话 → 使用路径 A-2
  3. 否则 → 使用路径 B(手动)

路径 A-1(claude-in-chrome):

  1. 导航到 http://localhost:8976/github-app-manifest.html
  2. 点击提交按钮,将 manifest POST 到 GitHub
  3. GitHub 会显示确认页面——点击创建 GitHub App
  4. 重定向后,从 URL 中提取 code 参数

路径 A-2(agent-browser):

通过 agent-browser 执行相同流程——导航到辅助页面,点击提交,然后点击创建。

路径 B(手动):

告知用户:

  1. 在浏览器中打开 http://localhost:8976/github-app-manifest.html 并点击按钮
  2. 查看 GitHub 上的权限,然后点击创建 GitHub App
  3. 重定向后,从浏览器地址栏复制完整 URL并粘贴到这里

从重定向 URL 中提取 code 参数。

步骤 9:用 Code 换取凭据

重要: /app-manifests/<CODE>/conversions 端点只能使用一次。请恰好调用一次。

# Store the full response temporarily (one-time-use endpoint — do NOT call twice)
gh api /app-manifests/<CODE>/conversions --method POST > /tmp/github-app-response.json

# Extract values (these are all secrets — handle via Bash only)
GITHUB_APP_ID=$(cat /tmp/github-app-response.json | jq -r '.id')
GITHUB_APP_SLUG=$(cat /tmp/github-app-response.json | jq -r '.slug')
GITHUB_WEBHOOK_SECRET=$(cat /tmp/github-app-response.json | jq -r '.webhook_secret')
GITHUB_APP_PEM=$(cat /tmp/github-app-response.json | jq -r '.pem')

# Clean up
rm /tmp/github-app-response.json
步骤 10:将凭据写入 Env
# Ensure directory exists (may not if running standalone outside cyrus-setup)
mkdir -p ~/.cyrus

# Webhook secret (for signature verification)
printf 'GITHUB_WEBHOOK_SECRET=%s\n' "$GITHUB_WEBHOOK_SECRET" >> ~/.cyrus/.env

# App ID (for token minting)
printf 'GITHUB_APP_ID=%s\n' "$GITHUB_APP_ID" >> ~/.cyrus/.env

# Bot username (for mention filtering — see note below about GitHub autocomplete)
printf 'GITHUB_BOT_USERNAME=%s\n' "$GITHUB_APP_SLUG" >> ~/.cyrus/.env

# Private key (multi-line — stored as a separate file)
printf '%s\n' "$GITHUB_APP_PEM" > ~/.cyrus/github-app.pem
chmod 600 ~/.cyrus/github-app.pem

# Ensure self-hosted mode is active (required for signature verification)
grep -q '^CYRUS_HOST_EXTERNAL=' ~/.cyrus/.env || printf 'CYRUS_HOST_EXTERNAL=true\n' >> ~/.cyrus/.env

验证是否已写入所有值:

grep -c '^GITHUB_WEBHOOK_SECRET=.' ~/.cyrus/.env
grep -c '^GITHUB_APP_ID=.' ~/.cyrus/.env
grep -c '^GITHUB_BOT_USERNAME=.' ~/.cyrus/.env
test -f ~/.cyrus/github-app.pem && echo "PEM exists" || echo "PEM missing"

所有检查都必须通过(返回 1、1、1、“PEM 存在”)。

步骤 11:在仓库上安装 App

必须在 Cyrus 将监控的仓库上安装 GitHub App。

前往:https://github.com/apps/<GITHUB_APP_SLUG>/installations/new

选择要安装的仓库(或“所有仓库”),然后点击安装。

也可以通过浏览器自动化完成(导航到 URL、选择仓库、点击安装)。

安装后,获取安装 ID:

# Re-read GITHUB_APP_ID from .env (shell vars don't persist between blocks)
GITHUB_APP_ID=$(grep '^GITHUB_APP_ID=' ~/.cyrus/.env | cut -d= -f2-)

# Generate a JWT to authenticate as the app
GITHUB_APP_JWT=$(node -e "
const crypto = require('crypto');
const fs = require('fs');
const key = fs.readFileSync(process.env.HOME + '/.cyrus/github-app.pem', 'utf8');
const now = Math.floor(Date.now()/1000);
const header = Buffer.from(JSON.stringify({alg:'RS256',typ:'JWT'})).toString('base64url');
const payload = Buffer.from(JSON.stringify({iat:now-60,exp:now+600,iss:'$GITHUB_APP_ID'})).toString('base64url');
const sig = crypto.createSign('RSA-SHA256').update(header+'.'+payload).sign(key,'base64url');
console.log(header+'.'+payload+'.'+sig);
")

# List installations — if multiple, show all and let user pick
INSTALLATIONS=$(curl -s -H "Authorization: Bearer $GITHUB_APP_JWT" -H "Accept: application/vnd.github+json" https://api.github.com/app/installations)
echo "$INSTALLATIONS" | jq '.[] | {id, account: .account.login}'

如果有多个安装,请询问用户要使用哪一个。然后写入安装 ID:

printf 'GITHUB_APP_INSTALLATION_ID=%s\n' "<INSTALLATION_ID>" >> ~/.cyrus/.env

验证:

grep -c '^GITHUB_APP_INSTALLATION_ID=.' ~/.cyrus/.env

必须返回 1。

完成

✓ GitHub CLI 已通过身份验证 ✓ Git 身份已配置:<name> <<email>>

如果已启用 Webhook:

✓ 已创建 GitHub App:<GITHUB_APP_SLUG> ✓ Webhook 密钥和 App 凭据已保存到 ~/.cyrus/.env ✓ 私钥已保存到 ~/.cyrus/github-app.pem ✓ App 已安装(安装 ID:<GITHUB_APP_INSTALLATION_ID>) ✓ Cyrus 将响应 PR 评论中对 @<GITHUB_BOT_USERNAME> 的提及

注意: 只有在 Cyrus 运行后,Webhook URL 才会成功响应。如果 GitHub 在设置期间显示 Webhook 投递失败,Cyrus 启动后 GitHub 会自动重试。

评论

支持 Markdown