关于 cyrus-setup-github
cyrus-setup-github 是为 Cyrus 配置 GitHub CLI 和 Git 身份的技能,也可选创建 GitHub App 与 Webhook。它为 Cyrus 创建分支、提交和 PR,并可接收 PR 评论与审查中的 @提及。
主要功能
- 01检查并配置 gh 身份验证
- 02设置全局 Git 用户名和邮箱
- 03可选创建 GitHub App
- 04配置 Webhook 凭据
- 05将 App 安装到目标仓库
适用场景
- 01为 Cyrus 配置 GitHub 提交身份
- 02启用 PR 评论和审查中的 @提及响应
- 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>。如果可用:
- 创建一个使用该名称的免费 GitHub 用户账号
- 邀请该账号加入你的组织和/或仓库,作为协作者
- 将
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 实体转义(将 " 替换为 "),因为它会放在 HTML 属性中:
# Escape the manifest JSON for safe embedding in an HTML attribute
MANIFEST_HTML_ESCAPED=$(echo '<MANIFEST_JSON>' | sed 's/"/\"/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
根据可用情况选择自动化路径:
- 如果有
claude-in-chromeMCP 工具 → 使用路径 A-1 - 如果已安装
agent-browser且已连接 Chrome 调试会话 → 使用路径 A-2 - 否则 → 使用路径 B(手动)
路径 A-1(claude-in-chrome):
- 导航到
http://localhost:8976/github-app-manifest.html - 点击提交按钮,将 manifest POST 到 GitHub
- GitHub 会显示确认页面——点击创建 GitHub App
- 重定向后,从 URL 中提取
code参数
路径 A-2(agent-browser):
通过 agent-browser 执行相同流程——导航到辅助页面,点击提交,然后点击创建。
路径 B(手动):
告知用户:
- 在浏览器中打开
http://localhost:8976/github-app-manifest.html并点击按钮- 查看 GitHub 上的权限,然后点击创建 GitHub App
- 重定向后,从浏览器地址栏复制完整 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 会自动重试。