Hermes-agent

This commit is contained in:
Zakaria
2026-06-14 14:30:48 -04:00
commit dac4b88b94
5058 changed files with 1884848 additions and 0 deletions
@@ -0,0 +1,132 @@
---
title: "代码库检查 — 使用 pygount 检查代码库:代码行数、语言、占比"
sidebar_label: "代码库检查"
description: "使用 pygount 检查代码库:代码行数、语言、占比"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# 代码库检查
使用 pygount 检查代码库:代码行数、语言、占比。
## Skill 元数据
| | |
|---|---|
| 来源 | 内置(默认安装) |
| 路径 | `skills/github/codebase-inspection` |
| 版本 | `1.0.0` |
| 作者 | Hermes Agent |
| 许可证 | MIT |
| 平台 | linux, macos, windows |
| 标签 | `LOC`, `Code Analysis`, `pygount`, `Codebase`, `Metrics`, `Repository` |
| 相关 skill | [`github-repo-management`](/user-guide/skills/bundled/github/github-github-repo-management) |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
:::
# 使用 pygount 进行代码库检查
使用 `pygount` 分析仓库的代码行数、语言分布、文件数量及代码与注释的比例。
## 使用场景
- 用户请求统计 LOClines of code,代码行数)
- 用户需要仓库的语言分布情况
- 用户询问代码库的规模或组成
- 用户需要代码与注释的比例
- 一般性的"这个仓库有多大"问题
## 前置条件
```bash
pip install --break-system-packages pygount 2>/dev/null || pip install pygount
```
## 1. 基本摘要(最常用)
获取包含文件数量、代码行数和注释行数的完整语言分布:
```bash
cd /path/to/repo
pygount --format=summary \
--folders-to-skip=".git,node_modules,venv,.venv,__pycache__,.cache,dist,build,.next,.tox,.eggs,*.egg-info" \
.
```
**重要:** 始终使用 `--folders-to-skip` 排除依赖/构建目录,否则 pygount 会遍历这些目录,导致运行时间极长甚至卡死。
## 2. 常用目录排除项
根据项目类型进行调整:
```bash
# Python 项目
--folders-to-skip=".git,venv,.venv,__pycache__,.cache,dist,build,.tox,.eggs,.mypy_cache"
# JavaScript/TypeScript 项目
--folders-to-skip=".git,node_modules,dist,build,.next,.cache,.turbo,coverage"
# 通用兜底
--folders-to-skip=".git,node_modules,venv,.venv,__pycache__,.cache,dist,build,.next,.tox,vendor,third_party"
```
## 3. 按特定语言过滤
```bash
# 仅统计 Python 文件
pygount --suffix=py --format=summary .
# 仅统计 Python 和 YAML
pygount --suffix=py,yaml,yml --format=summary .
```
## 4. 逐文件详细输出
```bash
# 默认格式显示每个文件的详细信息
pygount --folders-to-skip=".git,node_modules,venv" .
# 按代码行数排序(通过管道传给 sort)
pygount --folders-to-skip=".git,node_modules,venv" . | sort -t$'\t' -k1 -nr | head -20
```
## 5. 输出格式
```bash
# 摘要表格(默认推荐)
pygount --format=summary .
# JSON 输出,适合程序化处理
pygount --format=json .
# 管道友好:语言、文件数、代码行、文档行、空行、字符串行
pygount --format=summary . 2>/dev/null
```
## 6. 结果解读
摘要表格各列说明:
- **Language** — 检测到的编程语言
- **Files** — 该语言的文件数量
- **Code** — 实际代码行数(可执行/声明性语句)
- **Comment** — 注释或文档行数
- **%** — 占总量的百分比
特殊伪语言:
- `__empty__` — 空文件
- `__binary__` — 二进制文件(图片、编译产物等)
- `__generated__` — 自动生成的文件(启发式检测)
- `__duplicate__` — 内容完全相同的文件
- `__unknown__` — 无法识别的文件类型
## 注意事项
1. **始终排除 .git、node_modules、venv** — 不使用 `--folders-to-skip` 时,pygount 会遍历所有内容,在大型依赖树上可能耗时数分钟甚至卡死。
2. **Markdown 显示 0 代码行** — pygount 将所有 Markdown 内容归类为注释而非代码,这是预期行为。
3. **JSON 文件代码行数偏低** — pygount 统计 JSON 行数时可能较为保守,如需精确统计 JSON 行数,请直接使用 `wc -l`
4. **大型 monorepo** — 对于非常大的仓库,建议使用 `--suffix` 指定目标语言,而非扫描全部内容。
@@ -0,0 +1,265 @@
---
title: "Github Auth — GitHub auth setup: HTTPS tokens, SSH keys, gh CLI login"
sidebar_label: "Github Auth"
description: "GitHub auth 设置:HTTPS 令牌、SSH 密钥、gh CLI 登录"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Github Auth
GitHub auth 设置:HTTPS 令牌、SSH 密钥、gh CLI 登录。
## Skill 元数据
| | |
|---|---|
| 来源 | 内置(默认安装) |
| 路径 | `skills/github/github-auth` |
| 版本 | `1.1.0` |
| 作者 | Hermes Agent |
| 许可证 | MIT |
| 平台 | linux, macos, windows |
| 标签 | `GitHub`, `Authentication`, `Git`, `gh-cli`, `SSH`, `Setup` |
| 相关 skill | [`github-pr-workflow`](/user-guide/skills/bundled/github/github-github-pr-workflow), [`github-code-review`](/user-guide/skills/bundled/github/github-github-code-review), [`github-issues`](/user-guide/skills/bundled/github/github-github-issues), [`github-repo-management`](/user-guide/skills/bundled/github/github-github-repo-management) |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
:::
# GitHub 认证设置
此 skill 用于配置认证,使 agent 能够操作 GitHub 仓库、PR、issue 和 CI。涵盖两条路径:
- **`git`(始终可用)** — 使用 HTTPS 个人访问令牌(personal access token)或 SSH 密钥
- **`gh` CLI(如已安装)** — 更丰富的 GitHub API 访问,认证流程更简单
## 检测流程
当用户要求你操作 GitHub 时,首先执行以下检查:
```bash
# Check what's available
git --version
gh --version 2>/dev/null || echo "gh not installed"
# Check if already authenticated
gh auth status 2>/dev/null || echo "gh not authenticated"
git config --global credential.helper 2>/dev/null || echo "no git credential helper"
```
**决策树:**
1.`gh auth status` 显示已认证 → 直接使用 `gh` 处理所有操作
2.`gh` 已安装但未认证 → 使用下方"gh auth"方法
3.`gh` 未安装 → 使用下方"仅 git"方法(无需 sudo
---
## 方法一:仅 Git 认证(无 gh,无 sudo
适用于任何已安装 `git` 的机器,无需 root 权限。
### 选项 A:HTTPS 配合个人访问令牌(推荐)
最通用的方法——适用于所有环境,无需 SSH 配置。
**第一步:创建个人访问令牌**
告知用户访问:**https://github.com/settings/tokens**
- 点击"Generate new token (classic)"
- 填写名称,如"hermes-agent"
- 选择权限范围(scope):
- `repo`(完整仓库访问——读、写、推送、PR)
- `workflow`(触发和管理 GitHub Actions
- `read:org`(如需操作组织仓库)
- 设置有效期(90 天是合理的默认值)
- 复制令牌——此后不会再次显示
**第二步:配置 git 存储令牌**
```bash
# Set up the credential helper to cache credentials
# "store" saves to ~/.git-credentials in plaintext (simple, persistent)
git config --global credential.helper store
# Now do a test operation that triggers auth — git will prompt for credentials
# Username: <their-github-username>
# Password: <paste the personal access token, NOT their GitHub password>
git ls-remote https://github.com/<their-username>/<any-repo>.git
```
首次输入凭据后,将被保存并在后续所有操作中复用。
**替代方案:cache helper(凭据在内存中过期)**
```bash
# Cache in memory for 8 hours (28800 seconds) instead of saving to disk
git config --global credential.helper 'cache --timeout=28800'
```
**替代方案:直接将令牌写入远程 URL(按仓库设置)**
```bash
# Embed token in the remote URL (avoids credential prompts entirely)
git remote set-url origin https://<username>:<token>@github.com/<owner>/<repo>.git
```
**第三步:配置 git 身份信息**
```bash
# Required for commits — set name and email
git config --global user.name "Their Name"
git config --global user.email "their-email@example.com"
```
**第四步:验证**
```bash
# Test push access (this should work without any prompts now)
git ls-remote https://github.com/<their-username>/<any-repo>.git
# Verify identity
git config --global user.name
git config --global user.email
```
### 选项 BSSH 密钥认证
适合偏好 SSH 或已有密钥的用户。
**第一步:检查现有 SSH 密钥**
```bash
ls -la ~/.ssh/id_*.pub 2>/dev/null || echo "No SSH keys found"
```
**第二步:如需则生成密钥**
```bash
# Generate an ed25519 key (modern, secure, fast)
ssh-keygen -t ed25519 -C "their-email@example.com" -f ~/.ssh/id_ed25519 -N ""
# Display the public key for them to add to GitHub
cat ~/.ssh/id_ed25519.pub
```
告知用户在以下地址添加公钥:**https://github.com/settings/keys**
- 点击"New SSH key"
- 粘贴公钥内容
- 填写标题,如"hermes-agent-&lt;machine-name>"
**第三步:测试连接**
```bash
ssh -T git@github.com
# Expected: "Hi <username>! You've successfully authenticated..."
```
**第四步:配置 git 使用 SSH 访问 GitHub**
```bash
# Rewrite HTTPS GitHub URLs to SSH automatically
git config --global url."git@github.com:".insteadOf "https://github.com/"
```
**第五步:配置 git 身份信息**
```bash
git config --global user.name "Their Name"
git config --global user.email "their-email@example.com"
```
---
## 方法二:gh CLI 认证
若已安装 `gh`,一步即可完成 API 访问和 git 凭据配置。
### 浏览器交互登录(桌面环境)
```bash
gh auth login
# Select: GitHub.com
# Select: HTTPS
# Authenticate via browser
```
### 基于令牌登录(无头环境 / SSH 服务器)
```bash
echo "<THEIR_TOKEN>" | gh auth login --with-token
# Set up git credentials through gh
gh auth setup-git
```
### 验证
```bash
gh auth status
```
---
## 不使用 gh 调用 GitHub API
`gh` 不可用时,仍可使用 `curl` 配合个人访问令牌访问完整的 GitHub API。其他 GitHub skill 的降级方案均采用此方式。
### 为 API 调用设置令牌
```bash
# Option 1: Export as env var (preferred — keeps it out of commands)
export GITHUB_TOKEN="<token>"
# Then use in curl calls:
curl -s -H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/user
```
### 从 Git 凭据中提取令牌
若已通过 `credential.helper store` 配置 git 凭据,可提取令牌:
```bash
# Read from git credential store
grep "github.com" ~/.git-credentials 2>/dev/null | head -1 | sed 's|https://[^:]*:\([^@]*\)@.*|\1|'
```
### 辅助函数:检测认证方式
在任何 GitHub 工作流开始时使用此模式:
```bash
# Try gh first, fall back to git + curl
if command -v gh &>/dev/null && gh auth status &>/dev/null; then
echo "AUTH_METHOD=gh"
elif [ -n "$GITHUB_TOKEN" ]; then
echo "AUTH_METHOD=curl"
elif [ -f ~/.hermes/.env ] && grep -q "^GITHUB_TOKEN=" ~/.hermes/.env; then
export GITHUB_TOKEN=$(grep "^GITHUB_TOKEN=" ~/.hermes/.env | head -1 | cut -d= -f2 | tr -d '\n\r')
echo "AUTH_METHOD=curl"
elif grep -q "github.com" ~/.git-credentials 2>/dev/null; then
export GITHUB_TOKEN=$(grep "github.com" ~/.git-credentials | head -1 | sed 's|https://[^:]*:\([^@]*\)@.*|\1|')
echo "AUTH_METHOD=curl"
else
echo "AUTH_METHOD=none"
echo "Need to set up authentication first"
fi
```
---
## 故障排查
| 问题 | 解决方案 |
|---------|----------|
| `git push` 要求输入密码 | GitHub 已禁用密码认证。请使用个人访问令牌作为密码,或切换至 SSH |
| `remote: Permission to X denied` | 令牌可能缺少 `repo` scope——请重新生成并选择正确的 scope |
| `fatal: Authentication failed` | 缓存的凭据可能已过期——运行 `git credential reject` 后重新认证 |
| `ssh: connect to host github.com port 22: Connection refused` | 尝试通过 HTTPS 端口使用 SSH:在 `~/.ssh/config` 中为 `Host github.com` 添加 `Port 443``Hostname ssh.github.com` |
| 凭据不持久 | 检查 `git config --global credential.helper`——必须为 `store``cache` |
| 多个 GitHub 账号 | 在 `~/.ssh/config` 中为不同主机别名配置不同 SSH 密钥,或使用按仓库设置的凭据 URL |
| `gh: command not found` 且无 sudo | 使用上方方法一(仅 git)——无需安装任何软件 |
@@ -0,0 +1,499 @@
---
title: "Github Code Review — 通过 gh 或 REST 审查 PR:差异对比、行内评论"
sidebar_label: "Github Code Review"
description: "通过 gh 或 REST 审查 PR:差异对比、行内评论"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Github Code Review
通过 gh 或 REST 审查 PR:差异对比、行内评论。
## Skill 元数据
| | |
|---|---|
| 来源 | 内置(默认安装) |
| 路径 | `skills/github/github-code-review` |
| 版本 | `1.1.0` |
| 作者 | Hermes Agent |
| 许可证 | MIT |
| 平台 | linux, macos, windows |
| 标签 | `GitHub`, `Code-Review`, `Pull-Requests`, `Git`, `Quality` |
| 相关 skill | [`github-auth`](/user-guide/skills/bundled/github/github-github-auth), [`github-pr-workflow`](/user-guide/skills/bundled/github/github-github-pr-workflow) |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
:::
# GitHub Code Review
在推送前对本地变更执行代码审查,或审查 GitHub 上的开放 PR。此 skill 大部分功能使用纯 `git` 命令——`gh`/`curl` 的区别仅在 PR 级别的交互中才有意义。
## 前置条件
- 已通过 GitHub 身份验证(参见 `github-auth` skill
- 位于 git 仓库内部
### 设置(用于 PR 交互)
```bash
if command -v gh &>/dev/null && gh auth status &>/dev/null; then
AUTH="gh"
else
AUTH="git"
if [ -z "$GITHUB_TOKEN" ]; then
if [ -f ~/.hermes/.env ] && grep -q "^GITHUB_TOKEN=" ~/.hermes/.env; then
GITHUB_TOKEN=$(grep "^GITHUB_TOKEN=" ~/.hermes/.env | head -1 | cut -d= -f2 | tr -d '\n\r')
elif grep -q "github.com" ~/.git-credentials 2>/dev/null; then
GITHUB_TOKEN=$(grep "github.com" ~/.git-credentials 2>/dev/null | head -1 | sed 's|https://[^:]*:\([^@]*\)@.*|\1|')
fi
fi
fi
REMOTE_URL=$(git remote get-url origin)
OWNER_REPO=$(echo "$REMOTE_URL" | sed -E 's|.*github\.com[:/]||; s|\.git$||')
OWNER=$(echo "$OWNER_REPO" | cut -d/ -f1)
REPO=$(echo "$OWNER_REPO" | cut -d/ -f2)
```
---
## 1. 审查本地变更(推送前)
此部分为纯 `git` 操作——适用于所有环境,无需 API。
### 获取差异
```bash
# 已暂存的变更(即将提交的内容)
git diff --staged
# 相对于 main 的所有变更(PR 将包含的内容)
git diff main...HEAD
# 仅显示文件名
git diff main...HEAD --name-only
# 统计摘要(每个文件的插入/删除行数)
git diff main...HEAD --stat
```
### 审查策略
1. **先了解全局:**
```bash
git diff main...HEAD --stat
git log main..HEAD --oneline
```
2. **逐文件审查**——使用 `read_file` 查看已变更文件的完整上下文,并通过差异了解具体改动:
```bash
git diff main...HEAD -- src/auth/login.py
```
3. **检查常见问题:**
```bash
# 遗留的调试语句、TODO、console.log 等
git diff main...HEAD | grep -n "print(\|console\.log\|TODO\|FIXME\|HACK\|XXX\|debugger"
# 意外暂存的大文件
git diff main...HEAD --stat | sort -t'|' -k2 -rn | head -10
# 密钥或凭据模式
git diff main...HEAD | grep -in "password\|secret\|api_key\|token.*=\|private_key"
# 合并冲突标记
git diff main...HEAD | grep -n "<<<<<<\|>>>>>>\|======="
```
4. **向用户呈现结构化反馈。**
### 审查输出格式
审查本地变更时,按以下结构呈现结果:
```
## Code Review Summary
### Critical
- **src/auth.py:45** — SQL injection: user input passed directly to query.
Suggestion: Use parameterized queries.
### Warnings
- **src/models/user.py:23** — Password stored in plaintext. Use bcrypt or argon2.
- **src/api/routes.py:112** — No rate limiting on login endpoint.
### Suggestions
- **src/utils/helpers.py:8** — Duplicates logic in `src/core/utils.py:34`. Consolidate.
- **tests/test_auth.py** — Missing edge case: expired token test.
### Looks Good
- Clean separation of concerns in the middleware layer
- Good test coverage for the happy path
```
---
## 2. 审查 GitHub 上的 Pull Request
### 查看 PR 详情
**使用 gh**
```bash
gh pr view 123
gh pr diff 123
gh pr diff 123 --name-only
```
**使用 git + curl**
```bash
PR_NUMBER=123
# 获取 PR 详情
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/pulls/$PR_NUMBER \
| python3 -c "
import sys, json
pr = json.load(sys.stdin)
print(f\"Title: {pr['title']}\")
print(f\"Author: {pr['user']['login']}\")
print(f\"Branch: {pr['head']['ref']} -> {pr['base']['ref']}\")
print(f\"State: {pr['state']}\")
print(f\"Body:\n{pr['body']}\")"
# 列出已变更文件
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/pulls/$PR_NUMBER/files \
| python3 -c "
import sys, json
for f in json.load(sys.stdin):
print(f\"{f['status']:10} +{f['additions']:-4} -{f['deletions']:-4} {f['filename']}\")"
```
### 在本地检出 PR 进行完整审查
此操作使用纯 `git`——无需 `gh`
```bash
# 获取 PR 分支并检出
git fetch origin pull/123/head:pr-123
git checkout pr-123
# 现在可以使用 read_file、search_files、运行测试等
# 查看与基础分支的差异
git diff main...pr-123
```
**使用 gh(快捷方式):**
```bash
gh pr checkout 123
```
### 在 PR 上留下评论
**通用 PR 评论——使用 gh**
```bash
gh pr comment 123 --body "Overall looks good, a few suggestions below."
```
**通用 PR 评论——使用 curl:**
```bash
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/issues/$PR_NUMBER/comments \
-d '{"body": "Overall looks good, a few suggestions below."}'
```
### 留下行内审查评论
**单条行内评论——使用 gh(通过 API):**
```bash
HEAD_SHA=$(gh pr view 123 --json headRefOid --jq '.headRefOid')
gh api repos/$OWNER/$REPO/pulls/123/comments \
--method POST \
-f body="This could be simplified with a list comprehension." \
-f path="src/auth/login.py" \
-f commit_id="$HEAD_SHA" \
-f line=45 \
-f side="RIGHT"
```
**单条行内评论——使用 curl**
```bash
# 获取 head commit SHA
HEAD_SHA=$(curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/pulls/$PR_NUMBER \
| python3 -c "import sys,json; print(json.load(sys.stdin)['head']['sha'])")
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/pulls/$PR_NUMBER/comments \
-d "{
\"body\": \"This could be simplified with a list comprehension.\",
\"path\": \"src/auth/login.py\",
\"commit_id\": \"$HEAD_SHA\",
\"line\": 45,
\"side\": \"RIGHT\"
}"
```
### 提交正式审查(批准 / 请求变更)
**使用 gh**
```bash
gh pr review 123 --approve --body "LGTM!"
gh pr review 123 --request-changes --body "See inline comments."
gh pr review 123 --comment --body "Some suggestions, nothing blocking."
```
**使用 curl——原子性提交包含多条评论的审查:**
```bash
HEAD_SHA=$(curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/pulls/$PR_NUMBER \
| python3 -c "import sys,json; print(json.load(sys.stdin)['head']['sha'])")
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/pulls/$PR_NUMBER/reviews \
-d "{
\"commit_id\": \"$HEAD_SHA\",
\"event\": \"COMMENT\",
\"body\": \"Code review from Hermes Agent\",
\"comments\": [
{\"path\": \"src/auth.py\", \"line\": 45, \"body\": \"Use parameterized queries to prevent SQL injection.\"},
{\"path\": \"src/models/user.py\", \"line\": 23, \"body\": \"Hash passwords with bcrypt before storing.\"},
{\"path\": \"tests/test_auth.py\", \"line\": 1, \"body\": \"Add test for expired token edge case.\"}
]
}"
```
事件值:`"APPROVE"``"REQUEST_CHANGES"``"COMMENT"`
`line` 字段指文件*新版本*中的行号。对于已删除的行,使用 `"side": "LEFT"`
---
## 3. 审查清单
执行代码审查(本地或 PR)时,系统性地检查以下内容:
### 正确性
- 代码是否实现了其声称的功能?
- 边界情况是否已处理(空输入、null、大数据、并发访问)?
- 错误路径是否优雅处理?
### 安全性
- 无硬编码的密钥、凭据或 API key
- 对用户输入进行验证
- 无 SQL 注入、XSS 或路径遍历
- 在需要的地方进行身份验证/授权检查
### 代码质量
- 命名清晰(变量、函数、类)
- 无不必要的复杂性或过早抽象
- DRY——无应提取的重复逻辑
- 函数职责单一
### 测试
- 新代码路径是否已测试?
- 正常路径和错误情况是否已覆盖?
- 测试是否可读且可维护?
### 性能
- 无 N+1 查询或不必要的循环
- 在适当位置使用缓存
- 异步代码路径中无阻塞操作
### 文档
- 公共 API 已文档化
- 非显而易见的逻辑有注释说明"为什么"
- 若行为发生变化,README 已更新
---
## 4. 推送前审查工作流
当用户要求"审查代码"或"推送前检查"时:
1. `git diff main...HEAD --stat`——了解变更范围
2. `git diff main...HEAD`——阅读完整差异
3. 对每个已变更的文件,如需更多上下文则使用 `read_file`
4. 应用上述审查清单
5. 按结构化格式呈现结果(Critical / Warnings / Suggestions / Looks Good
6. 若发现严重问题,在用户推送前主动提出修复
---
## 5. PR 审查工作流(端到端)
当用户要求"审查 PR #N"、"查看这个 PR",或提供 PR URL 时,按以下步骤执行:
### 第一步:设置环境
```bash
source "${HERMES_HOME:-$HOME/.hermes}/skills/github/github-auth/scripts/gh-env.sh"
# 或运行本 skill 顶部的内联设置代码块
```
### 第二步:收集 PR 上下文
获取 PR 元数据、描述和已变更文件列表,在深入代码之前了解变更范围。
**使用 gh**
```bash
gh pr view 123
gh pr diff 123 --name-only
gh pr checks 123
```
**使用 curl**
```bash
PR_NUMBER=123
# PR 详情(标题、作者、描述、分支)
curl -s -H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$GH_OWNER/$GH_REPO/pulls/$PR_NUMBER
# 带行数统计的已变更文件
curl -s -H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$GH_OWNER/$GH_REPO/pulls/$PR_NUMBER/files
```
### 第三步:在本地检出 PR
这样可以完整使用 `read_file``search_files`,以及运行测试的能力。
```bash
git fetch origin pull/$PR_NUMBER/head:pr-$PR_NUMBER
git checkout pr-$PR_NUMBER
```
### 第四步:阅读差异并理解变更
```bash
# 与基础分支的完整差异
git diff main...HEAD
# 对于大型 PR,逐文件查看
git diff main...HEAD --name-only
# 然后对每个文件:
git diff main...HEAD -- path/to/file.py
```
对每个已变更的文件,使用 `read_file` 查看变更周围的完整上下文——仅凭差异可能遗漏只有在周围代码中才能发现的问题。
### 第五步:在本地运行自动化检查(如适用)
```bash
# 若有测试套件,运行测试
python -m pytest 2>&1 | tail -20
# 或:npm test, cargo test, go test ./..., 等
# 若已配置,运行 linter
ruff check . 2>&1 | head -30
# 或:eslint, clippy, 等
```
### 第六步:应用审查清单(第 3 节)
逐一检查每个类别:正确性、安全性、代码质量、测试、性能、文档。
### 第七步:将审查结果发布到 GitHub
汇总结果并以正式审查形式提交,附带行内评论。
**使用 gh**
```bash
# 若无问题——批准
gh pr review $PR_NUMBER --approve --body "Reviewed by Hermes Agent. Code looks clean — good test coverage, no security concerns."
# 若发现问题——请求变更并附行内评论
gh pr review $PR_NUMBER --request-changes --body "Found a few issues — see inline comments."
```
**使用 curl——原子性提交包含多条行内评论的审查:**
```bash
HEAD_SHA=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$GH_OWNER/$GH_REPO/pulls/$PR_NUMBER \
| python3 -c "import sys,json; print(json.load(sys.stdin)['head']['sha'])")
# 构建审查 JSON——event 为 APPROVE、REQUEST_CHANGES 或 COMMENT
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$GH_OWNER/$GH_REPO/pulls/$PR_NUMBER/reviews \
-d "{
\"commit_id\": \"$HEAD_SHA\",
\"event\": \"REQUEST_CHANGES\",
\"body\": \"## Hermes Agent Review\n\nFound 2 issues, 1 suggestion. See inline comments.\",
\"comments\": [
{\"path\": \"src/auth.py\", \"line\": 45, \"body\": \"🔴 **Critical:** User input passed directly to SQL query — use parameterized queries.\"},
{\"path\": \"src/models.py\", \"line\": 23, \"body\": \"⚠️ **Warning:** Password stored without hashing.\"},
{\"path\": \"src/utils.py\", \"line\": 8, \"body\": \"💡 **Suggestion:** This duplicates logic in core/utils.py:34.\"}
]
}"
```
### 第八步:同时发布摘要评论
除行内评论外,还需留下顶层摘要,让 PR 作者一目了然地了解全貌。使用 `references/review-output-template.md` 中的审查输出格式。
**使用 gh**
```bash
gh pr comment $PR_NUMBER --body "$(cat <<'EOF'
## Code Review Summary
**Verdict: Changes Requested** (2 issues, 1 suggestion)
### 🔴 Critical
- **src/auth.py:45** — SQL injection vulnerability
### ⚠️ Warnings
- **src/models.py:23** — Plaintext password storage
### 💡 Suggestions
- **src/utils.py:8** — Duplicated logic, consider consolidating
### ✅ Looks Good
- Clean API design
- Good error handling in the middleware layer
---
*Reviewed by Hermes Agent*
EOF
)"
```
### 第九步:清理
```bash
git checkout main
git branch -D pr-$PR_NUMBER
```
### 决策:批准 vs 请求变更 vs 评论
- **批准(Approve)**——无严重或警告级别的问题,仅有次要建议或完全通过
- **请求变更(Request Changes)**——存在任何在合并前应修复的严重或警告级别问题
- **评论(Comment**——有观察和建议,但无阻塞性问题(在不确定或 PR 为草稿时使用)
@@ -0,0 +1,388 @@
---
title: "Github Issues — 通过 gh 或 REST 创建、分类、标记、分配 GitHub Issues"
sidebar_label: "Github Issues"
description: "通过 gh 或 REST 创建、分类、标记、分配 GitHub Issues"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Github Issues
通过 gh 或 REST 创建、分类、标记、分配 GitHub Issues。
## Skill 元数据
| | |
|---|---|
| 来源 | 内置(默认安装) |
| 路径 | `skills/github/github-issues` |
| 版本 | `1.1.0` |
| 作者 | Hermes Agent |
| 许可证 | MIT |
| 平台 | linux, macos, windows |
| 标签 | `GitHub`, `Issues`, `Project-Management`, `Bug-Tracking`, `Triage` |
| 相关 skills | [`github-auth`](/user-guide/skills/bundled/github/github-github-auth), [`github-pr-workflow`](/user-guide/skills/bundled/github/github-github-pr-workflow) |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 skill 激活时 agent 所看到的指令内容。
:::
# GitHub Issues 管理
创建、搜索、分类和管理 GitHub Issues。每个章节先展示 `gh` 命令,再展示 `curl` 备用方案。
## 前提条件
- 已通过 GitHub 认证(参见 `github-auth` skill
- 位于含有 GitHub 远程仓库的 git 仓库内,或显式指定仓库
### 设置
```bash
if command -v gh &>/dev/null && gh auth status &>/dev/null; then
AUTH="gh"
else
AUTH="git"
if [ -z "$GITHUB_TOKEN" ]; then
if [ -f ~/.hermes/.env ] && grep -q "^GITHUB_TOKEN=" ~/.hermes/.env; then
GITHUB_TOKEN=$(grep "^GITHUB_TOKEN=" ~/.hermes/.env | head -1 | cut -d= -f2 | tr -d '\n\r')
elif grep -q "github.com" ~/.git-credentials 2>/dev/null; then
GITHUB_TOKEN=$(grep "github.com" ~/.git-credentials 2>/dev/null | head -1 | sed 's|https://[^:]*:\([^@]*\)@.*|\1|')
fi
fi
fi
REMOTE_URL=$(git remote get-url origin)
OWNER_REPO=$(echo "$REMOTE_URL" | sed -E 's|.*github\.com[:/]||; s|\.git$||')
OWNER=$(echo "$OWNER_REPO" | cut -d/ -f1)
REPO=$(echo "$OWNER_REPO" | cut -d/ -f2)
```
---
## 1. 查看 Issues
**使用 gh**
```bash
gh issue list
gh issue list --state open --label "bug"
gh issue list --assignee @me
gh issue list --search "authentication error" --state all
gh issue view 42
```
**使用 curl**
```bash
# 列出开放的 issues
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/$OWNER/$REPO/issues?state=open&per_page=20" \
| python3 -c "
import sys, json
for i in json.load(sys.stdin):
if 'pull_request' not in i: # GitHub API returns PRs in /issues too
labels = ', '.join(l['name'] for l in i['labels'])
print(f\"#{i['number']:5} {i['state']:6} {labels:30} {i['title']}\")"
# 按标签过滤
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/$OWNER/$REPO/issues?state=open&labels=bug&per_page=20" \
| python3 -c "
import sys, json
for i in json.load(sys.stdin):
if 'pull_request' not in i:
print(f\"#{i['number']} {i['title']}\")"
# 查看特定 issue
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/issues/42 \
| python3 -c "
import sys, json
i = json.load(sys.stdin)
labels = ', '.join(l['name'] for l in i['labels'])
assignees = ', '.join(a['login'] for a in i['assignees'])
print(f\"#{i['number']}: {i['title']}\")
print(f\"State: {i['state']} Labels: {labels} Assignees: {assignees}\")
print(f\"Author: {i['user']['login']} Created: {i['created_at']}\")
print(f\"\n{i['body']}\")"
# 搜索 issues
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/search/issues?q=authentication+error+repo:$OWNER/$REPO" \
| python3 -c "
import sys, json
for i in json.load(sys.stdin)['items']:
print(f\"#{i['number']} {i['state']:6} {i['title']}\")"
```
## 2. 创建 Issues
**使用 gh**
```bash
gh issue create \
--title "Login redirect ignores ?next= parameter" \
--body "## Description
After logging in, users always land on /dashboard.
## Steps to Reproduce
1. Navigate to /settings while logged out
2. Get redirected to /login?next=/settings
3. Log in
4. Actual: redirected to /dashboard (should go to /settings)
## Expected Behavior
Respect the ?next= query parameter." \
--label "bug,backend" \
--assignee "username"
```
**使用 curl**
```bash
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/issues \
-d '{
"title": "Login redirect ignores ?next= parameter",
"body": "## Description\nAfter logging in, users always land on /dashboard.\n\n## Steps to Reproduce\n1. Navigate to /settings while logged out\n2. Get redirected to /login?next=/settings\n3. Log in\n4. Actual: redirected to /dashboard\n\n## Expected Behavior\nRespect the ?next= query parameter.",
"labels": ["bug", "backend"],
"assignees": ["username"]
}'
```
### Bug 报告模板
```
## Bug Description
<What's happening>
## Steps to Reproduce
1. <step>
2. <step>
## Expected Behavior
<What should happen>
## Actual Behavior
<What actually happens>
## Environment
- OS: <os>
- Version: <version>
```
### 功能请求模板
```
## Feature Description
<What you want>
## Motivation
<Why this would be useful>
## Proposed Solution
<How it could work>
## Alternatives Considered
<Other approaches>
```
## 3. 管理 Issues
### 添加/移除标签
**使用 gh**
```bash
gh issue edit 42 --add-label "priority:high,bug"
gh issue edit 42 --remove-label "needs-triage"
```
**使用 curl**
```bash
# 添加标签
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/issues/42/labels \
-d '{"labels": ["priority:high", "bug"]}'
# 移除标签
curl -s -X DELETE \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/issues/42/labels/needs-triage
# 列出仓库中可用的标签
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/labels \
| python3 -c "
import sys, json
for l in json.load(sys.stdin):
print(f\" {l['name']:30} {l.get('description', '')}\")"
```
### 分配
**使用 gh**
```bash
gh issue edit 42 --add-assignee username
gh issue edit 42 --add-assignee @me
```
**使用 curl**
```bash
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/issues/42/assignees \
-d '{"assignees": ["username"]}'
```
### 评论
**使用 gh**
```bash
gh issue comment 42 --body "Investigated — root cause is in auth middleware. Working on a fix."
```
**使用 curl**
```bash
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/issues/42/comments \
-d '{"body": "Investigated — root cause is in auth middleware. Working on a fix."}'
```
### 关闭与重新开启
**使用 gh**
```bash
gh issue close 42
gh issue close 42 --reason "not planned"
gh issue reopen 42
```
**使用 curl**
```bash
# 关闭
curl -s -X PATCH \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/issues/42 \
-d '{"state": "closed", "state_reason": "completed"}'
# 重新开启
curl -s -X PATCH \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/issues/42 \
-d '{"state": "open"}'
```
### 将 Issues 关联到 PR
当 PR 合并时,若 PR 正文中包含以下关键词,对应 issue 将自动关闭:
```
Closes #42
Fixes #42
Resolves #42
```
从 issue 创建分支:
**使用 gh**
```bash
gh issue develop 42 --checkout
```
**使用 git(手动等效方式):**
```bash
git checkout main && git pull origin main
git checkout -b fix/issue-42-login-redirect
```
## 4. Issue 分类工作流
当被要求对 issues 进行分类时:
1. **列出未分类的 issues**
```bash
# 使用 gh
gh issue list --label "needs-triage" --state open
# 使用 curl
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/$OWNER/$REPO/issues?labels=needs-triage&state=open" \
| python3 -c "
import sys, json
for i in json.load(sys.stdin):
if 'pull_request' not in i:
print(f\"#{i['number']} {i['title']}\")"
```
2. **阅读并分类**每个 issue(查看详情,理解 bug 或功能需求)
3. **添加标签和优先级**(参见上方"管理 Issues"章节)
4. **分配负责人**(若归属明确)
5. **如有需要,添加分类说明评论**
## 5. 批量操作
对于批量操作,可将 API 调用与 shell 脚本结合使用:
**使用 gh**
```bash
# 关闭所有带特定标签的 issues
gh issue list --label "wontfix" --json number --jq '.[].number' | \
xargs -I {} gh issue close {} --reason "not planned"
```
**使用 curl**
```bash
# 列出带某标签的 issue 编号,然后逐一关闭
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/$OWNER/$REPO/issues?labels=wontfix&state=open" \
| python3 -c "import sys,json; [print(i['number']) for i in json.load(sys.stdin)]" \
| while read num; do
curl -s -X PATCH \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/issues/$num \
-d '{"state": "closed", "state_reason": "not_planned"}'
echo "Closed #$num"
done
```
## 快速参考表
| 操作 | gh | curl 端点 |
|--------|-----|--------------|
| 列出 issues | `gh issue list` | `GET /repos/{o}/{r}/issues` |
| 查看 issue | `gh issue view N` | `GET /repos/{o}/{r}/issues/N` |
| 创建 issue | `gh issue create ...` | `POST /repos/{o}/{r}/issues` |
| 添加标签 | `gh issue edit N --add-label ...` | `POST /repos/{o}/{r}/issues/N/labels` |
| 分配 | `gh issue edit N --add-assignee ...` | `POST /repos/{o}/{r}/issues/N/assignees` |
| 评论 | `gh issue comment N --body ...` | `POST /repos/{o}/{r}/issues/N/comments` |
| 关闭 | `gh issue close N` | `PATCH /repos/{o}/{r}/issues/N` |
| 搜索 | `gh issue list --search "..."` | `GET /search/issues?q=...` |
@@ -0,0 +1,385 @@
---
title: "Github Pr Workflow — GitHub PR 生命周期:分支、提交、开启、CI、合并"
sidebar_label: "Github Pr Workflow"
description: "GitHub PR 生命周期:分支、提交、开启、CI、合并"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Github Pr Workflow
GitHub PR 生命周期:分支、提交、开启、CI、合并。
## Skill 元数据
| | |
|---|---|
| 来源 | 内置(默认安装) |
| 路径 | `skills/github/github-pr-workflow` |
| 版本 | `1.1.0` |
| 作者 | Hermes Agent |
| 许可证 | MIT |
| 平台 | linux, macos, windows |
| 标签 | `GitHub`, `Pull-Requests`, `CI/CD`, `Git`, `Automation`, `Merge` |
| 相关 skill | [`github-auth`](/user-guide/skills/bundled/github/github-github-auth), [`github-code-review`](/user-guide/skills/bundled/github/github-github-code-review) |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
:::
# GitHub Pull Request 工作流
管理 PR 生命周期的完整指南。每个章节优先展示 `gh` 方式,再给出适用于无 `gh` 环境的 `git` + `curl` 备用方案。
## 前提条件
- 已通过 GitHub 认证(参见 `github-auth` skill
- 位于含有 GitHub 远程仓库的 git 仓库中
### 快速认证检测
```bash
# Determine which method to use throughout this workflow
if command -v gh &>/dev/null && gh auth status &>/dev/null; then
AUTH="gh"
else
AUTH="git"
# Ensure we have a token for API calls
if [ -z "$GITHUB_TOKEN" ]; then
if [ -f ~/.hermes/.env ] && grep -q "^GITHUB_TOKEN=" ~/.hermes/.env; then
GITHUB_TOKEN=$(grep "^GITHUB_TOKEN=" ~/.hermes/.env | head -1 | cut -d= -f2 | tr -d '\n\r')
elif grep -q "github.com" ~/.git-credentials 2>/dev/null; then
GITHUB_TOKEN=$(grep "github.com" ~/.git-credentials 2>/dev/null | head -1 | sed 's|https://[^:]*:\([^@]*\)@.*|\1|')
fi
fi
fi
echo "Using: $AUTH"
```
### 从 Git 远程地址提取 Owner/Repo
许多 `curl` 命令需要 `owner/repo`。从 git 远程地址中提取:
```bash
# Works for both HTTPS and SSH remote URLs
REMOTE_URL=$(git remote get-url origin)
OWNER_REPO=$(echo "$REMOTE_URL" | sed -E 's|.*github\.com[:/]||; s|\.git$||')
OWNER=$(echo "$OWNER_REPO" | cut -d/ -f1)
REPO=$(echo "$OWNER_REPO" | cut -d/ -f2)
echo "Owner: $OWNER, Repo: $REPO"
```
---
## 1. 创建分支
此部分为纯 `git` 操作——两种方式完全相同:
```bash
# Make sure you're up to date
git fetch origin
git checkout main && git pull origin main
# Create and switch to a new branch
git checkout -b feat/add-user-authentication
```
分支命名规范:
- `feat/description` — 新功能
- `fix/description` — 缺陷修复
- `refactor/description` — 代码重构
- `docs/description` — 文档
- `ci/description` — CI/CD 变更
## 2. 提交变更
使用 agent 的文件工具(`write_file``patch`)进行修改,然后提交:
```bash
# Stage specific files
git add src/auth.py src/models/user.py tests/test_auth.py
# Commit with a conventional commit message
git commit -m "feat: add JWT-based user authentication
- Add login/register endpoints
- Add User model with password hashing
- Add auth middleware for protected routes
- Add unit tests for auth flow"
```
提交信息格式(Conventional Commits):
```
type(scope): short description
Longer explanation if needed. Wrap at 72 characters.
```
类型:`feat``fix``refactor``docs``test``ci``chore``perf`
## 3. 推送分支并创建 PR
### 推送分支(两种方式相同)
```bash
git push -u origin HEAD
```
### 创建 PR
**使用 gh**
```bash
gh pr create \
--title "feat: add JWT-based user authentication" \
--body "## Summary
- Adds login and register API endpoints
- JWT token generation and validation
## Test Plan
- [ ] Unit tests pass
Closes #42"
```
选项:`--draft``--reviewer user1,user2``--label "enhancement"``--base develop`
**使用 git + curl**
```bash
BRANCH=$(git branch --show-current)
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/$OWNER/$REPO/pulls \
-d "{
\"title\": \"feat: add JWT-based user authentication\",
\"body\": \"## Summary\nAdds login and register API endpoints.\n\nCloses #42\",
\"head\": \"$BRANCH\",
\"base\": \"main\"
}"
```
响应 JSON 中包含 PR 的 `number`——请保存以供后续命令使用。
若要创建草稿 PR,在 JSON body 中添加 `"draft": true`
## 4. 监控 CI 状态
### 检查 CI 状态
**使用 gh**
```bash
# One-shot check
gh pr checks
# Watch until all checks finish (polls every 10s)
gh pr checks --watch
```
**使用 git + curl**
```bash
# Get the latest commit SHA on the current branch
SHA=$(git rev-parse HEAD)
# Query the combined status
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/commits/$SHA/status \
| python3 -c "
import sys, json
data = json.load(sys.stdin)
print(f\"Overall: {data['state']}\")
for s in data.get('statuses', []):
print(f\" {s['context']}: {s['state']} - {s.get('description', '')}\")"
# Also check GitHub Actions check runs (separate endpoint)
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/commits/$SHA/check-runs \
| python3 -c "
import sys, json
data = json.load(sys.stdin)
for cr in data.get('check_runs', []):
print(f\" {cr['name']}: {cr['status']} / {cr['conclusion'] or 'pending'}\")"
```
### 轮询直至完成(git + curl
```bash
# Simple polling loop — check every 30 seconds, up to 10 minutes
SHA=$(git rev-parse HEAD)
for i in $(seq 1 20); do
STATUS=$(curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/commits/$SHA/status \
| python3 -c "import sys,json; print(json.load(sys.stdin)['state'])")
echo "Check $i: $STATUS"
if [ "$STATUS" = "success" ] || [ "$STATUS" = "failure" ] || [ "$STATUS" = "error" ]; then
break
fi
sleep 30
done
```
## 5. 自动修复 CI 失败
当 CI 失败时,进行诊断并修复。此循环适用于两种认证方式。
### 第一步:获取失败详情
**使用 gh**
```bash
# List recent workflow runs on this branch
gh run list --branch $(git branch --show-current) --limit 5
# View failed logs
gh run view <RUN_ID> --log-failed
```
**使用 git + curl**
```bash
BRANCH=$(git branch --show-current)
# List workflow runs on this branch
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/$OWNER/$REPO/actions/runs?branch=$BRANCH&per_page=5" \
| python3 -c "
import sys, json
runs = json.load(sys.stdin)['workflow_runs']
for r in runs:
print(f\"Run {r['id']}: {r['name']} - {r['conclusion'] or r['status']}\")"
# Get failed job logs (download as zip, extract, read)
RUN_ID=<run_id>
curl -s -L \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/logs \
-o /tmp/ci-logs.zip
cd /tmp && unzip -o ci-logs.zip -d ci-logs && cat ci-logs/*.txt
```
### 第二步:修复并推送
定位问题后,使用文件工具(`patch``write_file`)进行修复:
```bash
git add <fixed_files>
git commit -m "fix: resolve CI failure in <check_name>"
git push
```
### 第三步:验证
使用第 4 节中的命令重新检查 CI 状态。
### 自动修复循环模式
当被要求自动修复 CI 时,遵循以下循环:
1. 检查 CI 状态 → 识别失败项
2. 读取失败日志 → 理解错误原因
3. 使用 `read_file` + `patch`/`write_file` → 修复代码
4. `git add . && git commit -m "fix: ..." && git push`
5. 等待 CI → 重新检查状态
6. 若仍失败则重复(最多 3 次,之后询问用户)
## 6. 合并
**使用 gh**
```bash
# Squash merge + delete branch (cleanest for feature branches)
gh pr merge --squash --delete-branch
# Enable auto-merge (merges when all checks pass)
gh pr merge --auto --squash --delete-branch
```
**使用 git + curl**
```bash
PR_NUMBER=<number>
# Merge the PR via API (squash)
curl -s -X PUT \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/pulls/$PR_NUMBER/merge \
-d "{
\"merge_method\": \"squash\",
\"commit_title\": \"feat: add user authentication (#$PR_NUMBER)\"
}"
# Delete the remote branch after merge
BRANCH=$(git branch --show-current)
git push origin --delete $BRANCH
# Switch back to main locally
git checkout main && git pull origin main
git branch -d $BRANCH
```
合并方式:`"merge"`(合并提交)、`"squash"``"rebase"`
### 启用自动合并(curl
```bash
# Auto-merge requires the repo to have it enabled in settings.
# This uses the GraphQL API since REST doesn't support auto-merge.
PR_NODE_ID=$(curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/pulls/$PR_NUMBER \
| python3 -c "import sys,json; print(json.load(sys.stdin)['node_id'])")
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/graphql \
-d "{\"query\": \"mutation { enablePullRequestAutoMerge(input: {pullRequestId: \\\"$PR_NODE_ID\\\", mergeMethod: SQUASH}) { clientMutationId } }\"}"
```
## 7. 完整工作流示例
```bash
# 1. Start from clean main
git checkout main && git pull origin main
# 2. Branch
git checkout -b fix/login-redirect-bug
# 3. (Agent makes code changes with file tools)
# 4. Commit
git add src/auth/login.py tests/test_login.py
git commit -m "fix: correct redirect URL after login
Preserves the ?next= parameter instead of always redirecting to /dashboard."
# 5. Push
git push -u origin HEAD
# 6. Create PR (picks gh or curl based on what's available)
# ... (see Section 3)
# 7. Monitor CI (see Section 4)
# 8. Merge when green (see Section 6)
```
## 常用 PR 命令参考
| 操作 | gh | git + curl |
|--------|-----|-----------|
| 列出我的 PR | `gh pr list --author @me` | `curl -s -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/repos/$OWNER/$REPO/pulls?state=open"` |
| 查看 PR diff | `gh pr diff` | `git diff main...HEAD`(本地)或 `curl -H "Accept: application/vnd.github.diff" ...` |
| 添加评论 | `gh pr comment N --body "..."` | `curl -X POST .../issues/N/comments -d '{"body":"..."}'` |
| 请求审查 | `gh pr edit N --add-reviewer user` | `curl -X POST .../pulls/N/requested_reviewers -d '{"reviewers":["user"]}'` |
| 关闭 PR | `gh pr close N` | `curl -X PATCH .../pulls/N -d '{"state":"closed"}'` |
| 检出他人的 PR | `gh pr checkout N` | `git fetch origin pull/N/head:pr-N && git checkout pr-N` |
@@ -0,0 +1,534 @@
---
title: "Github 仓库管理 — 克隆/创建/fork 仓库;管理远程、发布"
sidebar_label: "Github 仓库管理"
description: "克隆/创建/fork 仓库;管理远程、发布"
---
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
# Github 仓库管理
克隆/创建/fork 仓库;管理远程、发布。
## Skill 元数据
| | |
|---|---|
| 来源 | 内置(默认安装) |
| 路径 | `skills/github/github-repo-management` |
| 版本 | `1.1.0` |
| 作者 | Hermes Agent |
| 许可证 | MIT |
| 平台 | linux, macos, windows |
| 标签 | `GitHub`, `Repositories`, `Git`, `Releases`, `Secrets`, `Configuration` |
| 相关 skill | [`github-auth`](/user-guide/skills/bundled/github/github-github-auth), [`github-pr-workflow`](/user-guide/skills/bundled/github/github-github-pr-workflow), [`github-issues`](/user-guide/skills/bundled/github/github-github-issues) |
## 参考:完整 SKILL.md
:::info
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
:::
# GitHub 仓库管理
创建、克隆、fork、配置和管理 GitHub 仓库。每个章节优先展示 `gh` 命令,然后是 `git` + `curl` 的备用方案。
## 前提条件
- 已通过 GitHub 认证(参见 `github-auth` skill
### 初始化设置
```bash
if command -v gh &>/dev/null && gh auth status &>/dev/null; then
AUTH="gh"
else
AUTH="git"
if [ -z "$GITHUB_TOKEN" ]; then
if [ -f ~/.hermes/.env ] && grep -q "^GITHUB_TOKEN=" ~/.hermes/.env; then
GITHUB_TOKEN=$(grep "^GITHUB_TOKEN=" ~/.hermes/.env | head -1 | cut -d= -f2 | tr -d '\n\r')
elif grep -q "github.com" ~/.git-credentials 2>/dev/null; then
GITHUB_TOKEN=$(grep "github.com" ~/.git-credentials 2>/dev/null | head -1 | sed 's|https://[^:]*:\([^@]*\)@.*|\1|')
fi
fi
fi
# Get your GitHub username (needed for several operations)
if [ "$AUTH" = "gh" ]; then
GH_USER=$(gh api user --jq '.login')
else
GH_USER=$(curl -s -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/user | python3 -c "import sys,json; print(json.load(sys.stdin)['login'])")
fi
```
如果已在某个仓库内:
```bash
REMOTE_URL=$(git remote get-url origin)
OWNER_REPO=$(echo "$REMOTE_URL" | sed -E 's|.*github\.com[:/]||; s|\.git$||')
OWNER=$(echo "$OWNER_REPO" | cut -d/ -f1)
REPO=$(echo "$OWNER_REPO" | cut -d/ -f2)
```
---
## 1. 克隆仓库
克隆使用纯 `git` 命令——两种方式完全一致:
```bash
# Clone via HTTPS (works with credential helper or token-embedded URL)
git clone https://github.com/owner/repo-name.git
# Clone into a specific directory
git clone https://github.com/owner/repo-name.git ./my-local-dir
# Shallow clone (faster for large repos)
git clone --depth 1 https://github.com/owner/repo-name.git
# Clone a specific branch
git clone --branch develop https://github.com/owner/repo-name.git
# Clone via SSH (if SSH is configured)
git clone git@github.com:owner/repo-name.git
```
**使用 gh(简写):**
```bash
gh repo clone owner/repo-name
gh repo clone owner/repo-name -- --depth 1
```
## 2. 创建仓库
**使用 gh**
```bash
# Create a public repo and clone it
gh repo create my-new-project --public --clone
# Private, with description and license
gh repo create my-new-project --private --description "A useful tool" --license MIT --clone
# Under an organization
gh repo create my-org/my-new-project --public --clone
# From existing local directory
cd /path/to/existing/project
gh repo create my-project --source . --public --push
```
**使用 git + curl**
```bash
# Create the remote repo via API
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/user/repos \
-d '{
"name": "my-new-project",
"description": "A useful tool",
"private": false,
"auto_init": true,
"license_template": "mit"
}'
# Clone it
git clone https://github.com/$GH_USER/my-new-project.git
cd my-new-project
# -- OR -- push an existing local directory to the new repo
cd /path/to/existing/project
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/$GH_USER/my-new-project.git
git push -u origin main
```
在组织下创建:
```bash
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/orgs/my-org/repos \
-d '{"name": "my-new-project", "private": false}'
```
### 从模板创建
**使用 gh**
```bash
gh repo create my-new-app --template owner/template-repo --public --clone
```
**使用 curl**
```bash
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/owner/template-repo/generate \
-d '{"owner": "'"$GH_USER"'", "name": "my-new-app", "private": false}'
```
## 3. Fork 仓库
**使用 gh**
```bash
gh repo fork owner/repo-name --clone
```
**使用 git + curl**
```bash
# Create the fork via API
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/owner/repo-name/forks
# Wait a moment for GitHub to create it, then clone
sleep 3
git clone https://github.com/$GH_USER/repo-name.git
cd repo-name
# Add the original repo as "upstream" remote
git remote add upstream https://github.com/owner/repo-name.git
```
### 保持 Fork 同步
```bash
# Pure git — works everywhere
git fetch upstream
git checkout main
git merge upstream/main
git push origin main
```
**使用 gh(快捷方式):**
```bash
gh repo sync $GH_USER/repo-name
```
## 4. 仓库信息
**使用 gh**
```bash
gh repo view owner/repo-name
gh repo list --limit 20
gh search repos "machine learning" --language python --sort stars
```
**使用 curl**
```bash
# View repo details
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO \
| python3 -c "
import sys, json
r = json.load(sys.stdin)
print(f\"Name: {r['full_name']}\")
print(f\"Description: {r['description']}\")
print(f\"Stars: {r['stargazers_count']} Forks: {r['forks_count']}\")
print(f\"Default branch: {r['default_branch']}\")
print(f\"Language: {r['language']}\")"
# List your repos
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/user/repos?per_page=20&sort=updated" \
| python3 -c "
import sys, json
for r in json.load(sys.stdin):
vis = 'private' if r['private'] else 'public'
print(f\" {r['full_name']:40} {vis:8} {r.get('language', ''):10} ★{r['stargazers_count']}\")"
# Search repos
curl -s \
"https://api.github.com/search/repositories?q=machine+learning+language:python&sort=stars&per_page=10" \
| python3 -c "
import sys, json
for r in json.load(sys.stdin)['items']:
print(f\" {r['full_name']:40} ★{r['stargazers_count']:6} {r['description'][:60] if r['description'] else ''}\")"
```
## 5. 仓库设置
**使用 gh**
```bash
gh repo edit --description "Updated description" --visibility public
gh repo edit --enable-wiki=false --enable-issues=true
gh repo edit --default-branch main
gh repo edit --add-topic "machine-learning,python"
gh repo edit --enable-auto-merge
```
**使用 curl**
```bash
curl -s -X PATCH \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO \
-d '{
"description": "Updated description",
"has_wiki": false,
"has_issues": true,
"allow_auto_merge": true
}'
# Update topics
curl -s -X PUT \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.mercy-preview+json" \
https://api.github.com/repos/$OWNER/$REPO/topics \
-d '{"names": ["machine-learning", "python", "automation"]}'
```
## 6. 分支保护
```bash
# View current protection
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/branches/main/protection
# Set up branch protection
curl -s -X PUT \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/branches/main/protection \
-d '{
"required_status_checks": {
"strict": true,
"contexts": ["ci/test", "ci/lint"]
},
"enforce_admins": false,
"required_pull_request_reviews": {
"required_approving_review_count": 1
},
"restrictions": null
}'
```
## 7. Secrets 管理(GitHub Actions
**使用 gh**
```bash
gh secret set API_KEY --body "your-secret-value"
gh secret set SSH_KEY < ~/.ssh/id_rsa
gh secret list
gh secret delete API_KEY
```
**使用 curl**
通过 API 设置 secret 需要使用仓库公钥加密——步骤较为繁琐:
```bash
# Get the repo's public key for encrypting secrets
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/actions/secrets/public-key
# Encrypt and set (requires Python with PyNaCl)
python3 -c "
from base64 import b64encode
from nacl import encoding, public
import json, sys
# Get the public key
key_id = '<key_id_from_above>'
public_key = '<base64_key_from_above>'
# Encrypt
sealed = public.SealedBox(
public.PublicKey(public_key.encode('utf-8'), encoding.Base64Encoder)
).encrypt('your-secret-value'.encode('utf-8'))
print(json.dumps({
'encrypted_value': b64encode(sealed).decode('utf-8'),
'key_id': key_id
}))"
# Then PUT the encrypted secret
curl -s -X PUT \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/actions/secrets/API_KEY \
-d '<output from python script above>'
# List secrets (names only, values hidden)
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/actions/secrets \
| python3 -c "
import sys, json
for s in json.load(sys.stdin)['secrets']:
print(f\" {s['name']:30} updated: {s['updated_at']}\")"
```
注意:对于 secret 管理,`gh secret set` 要简便得多。如果需要设置 secret 但 `gh` 不可用,建议仅为此操作安装它。
## 8. 发布(Releases
**使用 gh**
```bash
gh release create v1.0.0 --title "v1.0.0" --generate-notes
gh release create v2.0.0-rc1 --draft --prerelease --generate-notes
gh release create v1.0.0 ./dist/binary --title "v1.0.0" --notes "Release notes"
gh release list
gh release download v1.0.0 --dir ./downloads
```
**使用 curl**
```bash
# Create a release
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/releases \
-d '{
"tag_name": "v1.0.0",
"name": "v1.0.0",
"body": "## Changelog\n- Feature A\n- Bug fix B",
"draft": false,
"prerelease": false,
"generate_release_notes": true
}'
# List releases
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/releases \
| python3 -c "
import sys, json
for r in json.load(sys.stdin):
tag = r.get('tag_name', 'no tag')
print(f\" {tag:15} {r['name']:30} {'draft' if r['draft'] else 'published'}\")"
# Upload a release asset (binary file)
RELEASE_ID=<id_from_create_response>
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Content-Type: application/octet-stream" \
"https://uploads.github.com/repos/$OWNER/$REPO/releases/$RELEASE_ID/assets?name=binary-amd64" \
--data-binary @./dist/binary-amd64
```
## 9. GitHub Actions 工作流
**使用 gh**
```bash
gh workflow list
gh run list --limit 10
gh run view <RUN_ID>
gh run view <RUN_ID> --log-failed
gh run rerun <RUN_ID>
gh run rerun <RUN_ID> --failed
gh workflow run ci.yml --ref main
gh workflow run deploy.yml -f environment=staging
```
**使用 curl**
```bash
# List workflows
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/actions/workflows \
| python3 -c "
import sys, json
for w in json.load(sys.stdin)['workflows']:
print(f\" {w['id']:10} {w['name']:30} {w['state']}\")"
# List recent runs
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/$OWNER/$REPO/actions/runs?per_page=10" \
| python3 -c "
import sys, json
for r in json.load(sys.stdin)['workflow_runs']:
print(f\" Run {r['id']} {r['name']:30} {r['conclusion'] or r['status']}\")"
# Download failed run logs
RUN_ID=<run_id>
curl -s -L \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/logs \
-o /tmp/ci-logs.zip
cd /tmp && unzip -o ci-logs.zip -d ci-logs
# Re-run a failed workflow
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/rerun
# Re-run only failed jobs
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/rerun-failed-jobs
# Trigger a workflow manually (workflow_dispatch)
WORKFLOW_ID=<workflow_id_or_filename>
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/actions/workflows/$WORKFLOW_ID/dispatches \
-d '{"ref": "main", "inputs": {"environment": "staging"}}'
```
## 10. Gists
**使用 gh**
```bash
gh gist create script.py --public --desc "Useful script"
gh gist list
```
**使用 curl**
```bash
# Create a gist
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/gists \
-d '{
"description": "Useful script",
"public": true,
"files": {
"script.py": {"content": "print(\"hello\")"}
}
}'
# List your gists
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/gists \
| python3 -c "
import sys, json
for g in json.load(sys.stdin):
files = ', '.join(g['files'].keys())
print(f\" {g['id']} {g['description'] or '(no desc)':40} {files}\")"
```
## 快速参考表
| 操作 | gh | git + curl |
|--------|-----|-----------|
| 克隆 | `gh repo clone o/r` | `git clone https://github.com/o/r.git` |
| 创建仓库 | `gh repo create name --public` | `curl POST /user/repos` |
| Fork | `gh repo fork o/r --clone` | `curl POST /repos/o/r/forks` + `git clone` |
| 仓库信息 | `gh repo view o/r` | `curl GET /repos/o/r` |
| 编辑设置 | `gh repo edit --...` | `curl PATCH /repos/o/r` |
| 创建发布 | `gh release create v1.0` | `curl POST /repos/o/r/releases` |
| 列出工作流 | `gh workflow list` | `curl GET /repos/o/r/actions/workflows` |
| 重跑 CI | `gh run rerun ID` | `curl POST /repos/o/r/actions/runs/ID/rerun` |
| 设置 secret | `gh secret set KEY` | `curl PUT /repos/o/r/actions/secrets/KEY`(需加密) |