Generates a full dedicated Docusaurus page for every one of the 132 skills
(73 bundled + 59 optional) under website/docs/user-guide/skills/{bundled,optional}/<category>/.
Each page carries the skill's description, metadata (version, author, license,
dependencies, platform gating, tags, related skills cross-linked to their own
pages), and the complete SKILL.md body that Hermes loads at runtime.
Previously the two catalog pages just listed skills with a one-line blurb and
no way to see what the skill actually did — users had to go read the source
repo. Now every skill has a browsable, searchable, cross-linked reference in
the docs.
- website/scripts/generate-skill-docs.py — generator that reads skills/ and
optional-skills/, writes per-skill pages, regenerates both catalog indexes,
and rewrites the Skills section of sidebars.ts. Handles MDX escaping
(outside fenced code blocks: curly braces, unsafe HTML-ish tags) and
rewrites relative references/*.md links to point at the GitHub source.
- website/docs/reference/skills-catalog.md — regenerated; each row links to
the new dedicated page.
- website/docs/reference/optional-skills-catalog.md — same.
- website/sidebars.ts — Skills section now has Bundled / Optional subtrees
with one nested category per skill folder.
- .github/workflows/{docs-site-checks,deploy-site}.yml — run the generator
before docusaurus build so CI stays in sync with the source SKILL.md files.
Build verified locally with `npx docusaurus build`. Only remaining warnings
are pre-existing broken link/anchor issues in unrelated pages.
9.9 KiB
| title | sidebar_label | description |
|---|---|---|
| Github Issues — Create, manage, triage, and close GitHub issues | Github Issues | Create, manage, triage, and close 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
Create, manage, triage, and close GitHub issues. Search existing issues, add labels, assign people, and link to PRs. Works with gh CLI or falls back to git + GitHub REST API via curl.
Skill metadata
| Source | Bundled (installed by default) |
| Path | skills/github/github-issues |
| Version | 1.1.0 |
| Author | Hermes Agent |
| License | MIT |
| Tags | GitHub, Issues, Project-Management, Bug-Tracking, Triage |
| Related skills | github-auth, github-pr-workflow |
Reference: full SKILL.md
:::info The following is the complete skill definition that Hermes loads when this skill is triggered. This is what the agent sees as instructions when the skill is active. :::
GitHub Issues Management
Create, search, triage, and manage GitHub issues. Each section shows gh first, then the curl fallback.
Prerequisites
- Authenticated with GitHub (see
github-authskill) - Inside a git repo with a GitHub remote, or specify the repo explicitly
Setup
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. Viewing Issues
With gh:
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
With curl:
# List open 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']}\")"
# Filter by label
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']}\")"
# View a specific 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']}\")"
# Search 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. Creating Issues
With gh:
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"
With curl:
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 Report Template
## 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 Request Template
## Feature Description
<What you want>
## Motivation
<Why this would be useful>
## Proposed Solution
<How it could work>
## Alternatives Considered
<Other approaches>
3. Managing Issues
Add/Remove Labels
With gh:
gh issue edit 42 --add-label "priority:high,bug"
gh issue edit 42 --remove-label "needs-triage"
With curl:
# Add labels
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/issues/42/labels \
-d '{"labels": ["priority:high", "bug"]}'
# Remove a label
curl -s -X DELETE \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/issues/42/labels/needs-triage
# List available labels in the repo
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', '')}\")"
Assignment
With gh:
gh issue edit 42 --add-assignee username
gh issue edit 42 --add-assignee @me
With curl:
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/issues/42/assignees \
-d '{"assignees": ["username"]}'
Commenting
With gh:
gh issue comment 42 --body "Investigated — root cause is in auth middleware. Working on a fix."
With curl:
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."}'
Closing and Reopening
With gh:
gh issue close 42
gh issue close 42 --reason "not planned"
gh issue reopen 42
With curl:
# Close
curl -s -X PATCH \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/issues/42 \
-d '{"state": "closed", "state_reason": "completed"}'
# Reopen
curl -s -X PATCH \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/issues/42 \
-d '{"state": "open"}'
Linking Issues to PRs
Issues are automatically closed when a PR merges with the right keywords in the body:
Closes #42
Fixes #42
Resolves #42
To create a branch from an issue:
With gh:
gh issue develop 42 --checkout
With git (manual equivalent):
git checkout main && git pull origin main
git checkout -b fix/issue-42-login-redirect
4. Issue Triage Workflow
When asked to triage issues:
- List untriaged issues:
# With gh
gh issue list --label "needs-triage" --state open
# With 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']}\")"
-
Read and categorize each issue (view details, understand the bug/feature)
-
Apply labels and priority (see Managing Issues above)
-
Assign if the owner is clear
-
Comment with triage notes if needed
5. Bulk Operations
For batch operations, combine API calls with shell scripting:
With gh:
# Close all issues with a specific label
gh issue list --label "wontfix" --json number --jq '.[].number' | \
xargs -I {} gh issue close {} --reason "not planned"
With curl:
# List issue numbers with a label, then close each
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
Quick Reference Table
| Action | gh | curl endpoint |
|---|---|---|
| List issues | gh issue list |
GET /repos/{o}/{r}/issues |
| View issue | gh issue view N |
GET /repos/{o}/{r}/issues/N |
| Create issue | gh issue create ... |
POST /repos/{o}/{r}/issues |
| Add labels | gh issue edit N --add-label ... |
POST /repos/{o}/{r}/issues/N/labels |
| Assign | gh issue edit N --add-assignee ... |
POST /repos/{o}/{r}/issues/N/assignees |
| Comment | gh issue comment N --body ... |
POST /repos/{o}/{r}/issues/N/comments |
| Close | gh issue close N |
PATCH /repos/{o}/{r}/issues/N |
| Search | gh issue list --search "..." |
GET /search/issues?q=... |