* docs: deep audit — fix stale config keys, missing commands, and registry drift Cross-checked ~80 high-impact docs pages (getting-started, reference, top-level user-guide, user-guide/features) against the live registries: hermes_cli/commands.py COMMAND_REGISTRY (slash commands) hermes_cli/auth.py PROVIDER_REGISTRY (providers) hermes_cli/config.py DEFAULT_CONFIG (config keys) toolsets.py TOOLSETS (toolsets) tools/registry.py get_all_tool_names() (tools) python -m hermes_cli.main <subcmd> --help (CLI args) reference/ - cli-commands.md: drop duplicate hermes fallback row + duplicate section, add stepfun/lmstudio to --provider enum, expand auth/mcp/curator subcommand lists to match --help output (status/logout/spotify, login, archive/prune/ list-archived). - slash-commands.md: add missing /sessions and /reload-skills entries + correct the cross-platform Notes line. - tools-reference.md: drop bogus '68 tools' headline, drop fictional 'browser-cdp toolset' (these tools live in 'browser' and are runtime-gated), add missing 'kanban' and 'video' toolset sections, fix MCP example to use the real mcp_<server>_<tool> prefix. - toolsets-reference.md: list browser_cdp/browser_dialog inside the 'browser' row, add missing 'kanban' and 'video' toolset rows, drop the stale '38 tools' count for hermes-cli. - profile-commands.md: add missing install/update/info subcommands, document fish completion. - environment-variables.md: dedupe GMI_API_KEY/GMI_BASE_URL rows (kept the one with the correct gmi-serving.com default). - faq.md: Anthropic/Google/OpenAI examples — direct providers exist (not just via OpenRouter), refresh the OpenAI model list. getting-started/ - installation.md: PortableGit (not MinGit) is what the Windows installer fetches; document the 32-bit MinGit fallback. - installation.md / termux.md: installer prefers .[termux-all] then falls back to .[termux]. - nix-setup.md: Python 3.12 (not 3.11), Node.js 22 (not 20); fix invalid 'nix flake update --flake' invocation. - updating.md: 'hermes backup restore --state pre-update' doesn't exist — point at the snapshot/quick-snapshot flow; correct config key 'updates.pre_update_backup' (was 'update.backup'). user-guide/ - configuration.md: api_max_retries default 3 (not 2); display.runtime_footer is the real key (not display.runtime_metadata_footer); checkpoints defaults enabled=false / max_snapshots=20 (not true / 50). - configuring-models.md: 'hermes model list' / 'hermes model set ...' don't exist — hermes model is interactive only. - tui.md: busy_indicator -> tui_status_indicator with values kaomoji|emoji|unicode|ascii (not kawaii|minimal|dots|wings|none). - security.md: SSH backend keys (TERMINAL_SSH_HOST/USER/KEY) live in .env, not config.yaml. - windows-wsl-quickstart.md: there is no 'hermes api' subcommand — the OpenAI-compatible API server runs inside hermes gateway. user-guide/features/ - computer-use.md: approvals.mode (not security.approval_level); fix broken ./browser-use.md link to ./browser.md. - fallback-providers.md: top-level fallback_providers (not model.fallback_providers); the picker is subcommand-based, not modal. - api-server.md: API_SERVER_* are env vars — write to per-profile .env, not 'hermes config set' which targets YAML. - web-search.md: drop web_crawl as a registered tool (it isn't); deep-crawl modes are exposed through web_extract. - kanban.md: failure_limit default is 2, not '~5'. - plugins.md: drop hard-coded '33 providers' count. - honcho.md: fix unclosed quote in echo HONCHO_API_KEY snippet; document that 'hermes honcho' subcommand is gated on memory.provider=honcho; reconcile subcommand list with actual --help output. - memory-providers.md: legacy 'hermes honcho setup' redirect documented. Verified via 'npm run build' — site builds cleanly; broken-link count went from 149 to 146 (no regressions, fixed a few in passing). * docs: round 2 audit fixes + regenerate skill catalogs Follow-up to the previous commit on this branch: Round 2 manual fixes: - quickstart.md: KIMI_CODING_API_KEY mentioned alongside KIMI_API_KEY; voice-mode and ACP install commands rewritten — bare 'pip install ...' doesn't work for curl-installed setups (no pip on PATH, not in repo dir); replaced with 'cd ~/.hermes/hermes-agent && uv pip install -e ".[voice]"'. ACP already ships in [all] so the curl install includes it. - cli.md / configuration.md: 'auxiliary.compression.model' shown as 'google/gemini-3-flash-preview' (the doc's own claimed default); actual default is empty (= use main model). Reworded as 'leave empty (default) or pin a cheap model'. - built-in-plugins.md: added the bundled 'kanban/dashboard' plugin row that was missing from the table. Regenerated skill catalogs: - ran website/scripts/generate-skill-docs.py to refresh all 163 per-skill pages and both reference catalogs (skills-catalog.md, optional-skills-catalog.md). This adds the entries that were genuinely missing — productivity/teams-meeting-pipeline (bundled), optional/finance/* (entire category — 7 skills: 3-statement-model, comps-analysis, dcf-model, excel-author, lbo-model, merger-model, pptx-author), creative/hyperframes, creative/kanban-video-orchestrator, devops/watchers, productivity/shop-app, research/searxng-search, apple/macos-computer-use — and rewrites every other per-skill page from the current SKILL.md. Most diffs are tiny (one line of refreshed metadata). Validation: - 'npm run build' succeeded. - Broken-link count moved 146 -> 155 — the +9 are zh-Hans translation shells that lag every newly-added skill page (pre-existing pattern). No regressions on any en/ page.
389 lines
9.8 KiB
Markdown
389 lines
9.8 KiB
Markdown
---
|
|
title: "Github Issues — Create, triage, label, assign GitHub issues via gh or REST"
|
|
sidebar_label: "Github Issues"
|
|
description: "Create, triage, label, assign GitHub issues via gh or REST"
|
|
---
|
|
|
|
{/* 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, triage, label, assign GitHub issues via gh or REST.
|
|
|
|
## Skill metadata
|
|
|
|
| | |
|
|
|---|---|
|
|
| Source | Bundled (installed by default) |
|
|
| Path | `skills/github/github-issues` |
|
|
| Version | `1.1.0` |
|
|
| Author | Hermes Agent |
|
|
| License | MIT |
|
|
| Platforms | linux, macos, windows |
|
|
| Tags | `GitHub`, `Issues`, `Project-Management`, `Bug-Tracking`, `Triage` |
|
|
| Related skills | [`github-auth`](/docs/user-guide/skills/bundled/github/github-github-auth), [`github-pr-workflow`](/docs/user-guide/skills/bundled/github/github-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-auth` skill)
|
|
- Inside a git repo with a GitHub remote, or specify the repo explicitly
|
|
|
|
### Setup
|
|
|
|
```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. Viewing Issues
|
|
|
|
**With 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
|
|
```
|
|
|
|
**With curl:**
|
|
|
|
```bash
|
|
# 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:**
|
|
|
|
```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"
|
|
```
|
|
|
|
**With 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 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:**
|
|
|
|
```bash
|
|
gh issue edit 42 --add-label "priority:high,bug"
|
|
gh issue edit 42 --remove-label "needs-triage"
|
|
```
|
|
|
|
**With curl:**
|
|
|
|
```bash
|
|
# 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:**
|
|
|
|
```bash
|
|
gh issue edit 42 --add-assignee username
|
|
gh issue edit 42 --add-assignee @me
|
|
```
|
|
|
|
**With curl:**
|
|
|
|
```bash
|
|
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:**
|
|
|
|
```bash
|
|
gh issue comment 42 --body "Investigated — root cause is in auth middleware. Working on a fix."
|
|
```
|
|
|
|
**With 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."}'
|
|
```
|
|
|
|
### Closing and Reopening
|
|
|
|
**With gh:**
|
|
|
|
```bash
|
|
gh issue close 42
|
|
gh issue close 42 --reason "not planned"
|
|
gh issue reopen 42
|
|
```
|
|
|
|
**With curl:**
|
|
|
|
```bash
|
|
# 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:**
|
|
|
|
```bash
|
|
gh issue develop 42 --checkout
|
|
```
|
|
|
|
**With git (manual equivalent):**
|
|
|
|
```bash
|
|
git checkout main && git pull origin main
|
|
git checkout -b fix/issue-42-login-redirect
|
|
```
|
|
|
|
## 4. Issue Triage Workflow
|
|
|
|
When asked to triage issues:
|
|
|
|
1. **List untriaged issues:**
|
|
|
|
```bash
|
|
# 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']}\")"
|
|
```
|
|
|
|
2. **Read and categorize** each issue (view details, understand the bug/feature)
|
|
|
|
3. **Apply labels and priority** (see Managing Issues above)
|
|
|
|
4. **Assign** if the owner is clear
|
|
|
|
5. **Comment with triage notes** if needed
|
|
|
|
## 5. Bulk Operations
|
|
|
|
For batch operations, combine API calls with shell scripting:
|
|
|
|
**With gh:**
|
|
|
|
```bash
|
|
# 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:**
|
|
|
|
```bash
|
|
# 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=...` |
|