Files
agent-skills/sn-search-code/scripts/github_search.py
Hermes Agent ccc63d1e70 first commit
2026-05-10 13:52:46 +08:00

97 lines
3.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""GitHub 搜索仓库、代码、Issue。通过 GitHub REST API。"""
from __future__ import annotations
import sys
from search_utils import build_parser, get_client, get_key, make_item, make_result, print_json
API_BASE = "https://api.github.com/search"
# 搜索类型 -> API 路径
SEARCH_TYPES = {
"repositories": "repositories",
"code": "code",
"issues": "issues",
"repo": "repositories", # 别名
"issue": "issues", # 别名
}
def search(query: str, limit: int, search_type: str = "repositories", token: str | None = None) -> list[dict]:
"""执行 GitHub 搜索。"""
endpoint = SEARCH_TYPES.get(search_type, "repositories")
url = f"{API_BASE}/{endpoint}"
headers = {"Accept": "application/vnd.github.v3+json"}
if token:
headers["Authorization"] = f"Bearer {token}"
params = {
"q": query,
"per_page": min(limit, 100),
"sort": "best match",
}
with get_client(headers=headers) as client:
resp = client.get(url, params=params)
resp.raise_for_status()
data = resp.json()
items = []
for item in data.get("items", [])[:limit]:
if endpoint == "repositories":
items.append(make_item(
title=item.get("full_name", ""),
url=item.get("html_url", ""),
snippet=item.get("description") or "",
stars=item.get("stargazers_count", 0),
language=item.get("language"),
updated_at=item.get("updated_at"),
))
elif endpoint == "code":
repo = item.get("repository", {})
items.append(make_item(
title=item.get("name", ""),
url=item.get("html_url", ""),
snippet=f"{repo.get('full_name', '')} - {item.get('path', '')}",
repo=repo.get("full_name"),
path=item.get("path"),
))
elif endpoint == "issues":
items.append(make_item(
title=item.get("title", ""),
url=item.get("html_url", ""),
snippet=_truncate(item.get("body") or "", 200),
state=item.get("state"),
comments=item.get("comments", 0),
created_at=item.get("created_at"),
))
return items
def _truncate(text: str, max_len: int) -> str:
return text[:max_len] + "..." if len(text) > max_len else text
def main():
parser = build_parser("搜索 GitHub 仓库、代码、Issue")
parser.add_argument("--type", "-t", default="repositories",
choices=list(SEARCH_TYPES.keys()),
help="搜索类型(默认 repositories")
parser.add_argument("--token", help="GitHub Token也可通过 GITHUB_TOKEN 环境变量设置)")
args = parser.parse_args()
token = get_key("GITHUB_TOKEN", args.token)
try:
items = search(args.query, args.limit, args.type, token)
print_json(make_result(True, args.query, "github", items))
except Exception as e:
print_json(make_result(False, args.query, "github", [], str(e)))
sys.exit(1)
if __name__ == "__main__":
main()