Add github-explore: GitHub search/discovery/audit skill via gh CLI - #8
Conversation
Agent-plugin contribution for the community registry: plugins/Fectivnfy112357/github-explore/
dd8d0f7 to
2f916be
Compare
hetaoBackend
left a comment
There was a problem hiding this comment.
暂不符合收录门禁,主要是 credential 与远端写操作边界:
- Skill 把“直接 gh 管理操作”列为能力,references 又给出 gh auth token、gh auth status --show-token、secret set/delete、repo/issue/PR/workflow 等写命令。前两者会把凭据打印进 Agent transcript;后者可能改变远端状态,但当前 Skill 没有 preview、目标确认和执行前 consent 规则。
- 请删除所有展示 token 的命令;认证诊断只允许不回显 token 的 gh auth status。对 create/update/delete/dispatch 等写操作必须明确目标、影响、最小数据和执行前确认;默认 discovery 脚本应保持只读。
- README/PR 目前只披露 api.github.com 搜索和“no credentials stored”,没有披露 Skill 还覆盖 credential/secret/repository 管理。请把能力、权限范围、远端副作用和数据流写全。
- 10 个脚本只有 py_compile 与个人日常使用声明,没有可复现回归测试。请至少覆盖参数到 gh argv 的安全构造、分页/限流失败、输出 schema 和错误时不泄露 stderr 中的敏感信息。
validator 通过只代表包形状合规,不能覆盖这些安全行为。
…ndary 针对 #8 审阅的 4 条 credential / 写操作门禁要求做修复 + 补全测试。 ## 1. 删除 token 暴露面 - 删除 references/commands-auth-config.md 中 `gh auth token`、 `gh auth status --show-token`、`gh auth login --with-token` 等回显示例 - ensure_auth 仅调用 `gh auth status` - 新增 _lib.redact_secrets() 并接入 warn/die/gh_json 错误路径 ## 2. 写操作 consent + 默认只读 - 新增 references/SECURITY-NOTES.md 统一定义 4 条纪律 (目标 / 影响 / 最小数据 / 确认) - commands-cicd / commands-misc / commands-repo-issue-pr 各 引用该文件,去掉逐字复制 - commands-auth-config 保持独立(认证类警告不混入写操作) - SKILL.md "安全边界" 小节明确 discovery 脚本只读 - 9 个 entry-point 脚本不构造任何 create/update/delete/merge/dispatch ## 3. README/PR 完整披露 - README.md 新增 "Capabilities & permissions" 与 "Data and network" 小节 - plugin.json description 同步更新 - 脚本计数统一为 9(与 scripts/ 目录实际 entry-point 一致) ## 4. 可复现回归测试 - scripts/tests/test_argv_safety.py: argv 列表 + shell=False - scripts/tests/test_rate_limit_pagination.py: 403/429 重试 + 分页 - scripts/tests/test_output_schema.py: find_repos/explore/repo_summary 字段契约 - scripts/tests/test_secret_redaction.py: 5 种凭据形态 + warn/die 路径 - scripts/run_tests.py: unittest discover 入口 - test/github-explore.test.mjs: node --test bridge 测试结果: 19/19 OK;node --test pass;validator OK
|
@hetaoBackend 谢谢这次的反馈,4 条都很到位 — credential 暴露面和写操作边界确实是我之前没充分考虑的部分。在 commit 1. token 暴露面: 2. 写操作 consent + 默认只读:4 条纪律(目标 / 影响 / 最小数据 / 确认)抽到新文件 3. 披露:README 新增 "Capabilities & permissions" + "Data and network" 两节;plugin.json description 同步;脚本计数统一为 9(与 4. 测试:4 套 stdlib 测试结果: 顺手把 |
hetaoBackend
left a comment
There was a problem hiding this comment.
@Fectivnfy112357 这个 PR 是当前最接近收录的一批,最新 main 合成检查 27/27 通过;还需修复两个写操作安全边界:
SECURITY-NOTES.md的确认规则排除了commands-auth-config.md,但其中包含 login/logout、切换账号、扩大 scopes、credential helper 和配置写入;commands-search-format.md也包含创建 issue 的 POST。请把所有commands-*.md中的写操作统一纳入“目标、影响、最小数据、用户显式确认”门禁。- 文档声称 raw
gh写命令的 stderr 会经过_lib.redact_secrets(),实际 Agent 直接执行这些命令,并不经过 Python wrapper。请删除该保证,或让写命令真正通过安全 wrapper。
另外请补充 GH_HOST/GitHub Enterprise 会改变网络目的地的披露,并触发 CI/CodeQL。修复后可优先复审。
…H_HOST disclosure, auth-config/api-mutation consent gates - SECURITY-NOTES: consent gate now covers ALL commands-*.md including auth-config (login/logout/switch/setup-git/refresh --scopes/config set) and search-format (gh api POST/PUT/DELETE/PATCH + graphql mutation) - Remove false claim that raw gh write stderr passes redact_secrets(); add scripts/redact_stderr.py as opt-in pipe (gh <cmd> 2>&1 | python ...) - Disclose GH_HOST / GitHub Enterprise network-destination behavior: GH_TOKEN/GITHUB_TOKEN scoped to github.com/*.ghe.com/github.localhost, GHES on-prem requires GH_ENTERPRISE_TOKEN; --hostname is not a global flag (~11 subcommands only); pure git ops ignore GH_HOST - Bump plugin version 2.0.0 -> 2.1.0; sync EN/zh READMEs
|
收到,两处写操作安全边界已修复,GH_HOST 披露也补上了:
最新提交 8cb32f2,CI 与 CodeQL 均已通过。麻烦再复审,谢谢。 |
There was a problem hiding this comment.
已复核当前 head 8cb32f2。此前的写入确认范围、鉴权配置修改和 stderr 披露问题均已修复;候选分支本地完整检查 13/13 通过,当前 CI 与 CodeQL 全绿。批准合入。
What it solves
Finding the right repositories on GitHub is noisy: broad searches drown in
high-star general-purpose repos, awesome-list directories mix with real
projects, and search quotas are easy to blow. github-explore packages a
proven discovery workflow — dual-scope semantic search, topic mining,
multi-axis field mapping with signal flags (canonical / awesome / list),
trending, similar projects, code/issue search and org audits — backed by 9
zero-config, stdlib-only Python scripts — so an agent can answer
"what exists and what matters" in one skill.
What it covers
Read-only discovery (9 entry-point scripts, default)
All scripts only call
gh search/gh repo view/gh apiagainstapi.github.com; they never create, update, or delete anything.
find_reposdiscoverexploretrending--topic,--language,--min-stars)repo_summaryfind_similar--no-language)code_search--repo,--org,--owner,--extension,--filename)search_issues--state,--type,--label,--author,--assignee)org_landscapeOutput is layered: stdout ~3KB markdown summary + full report written to
%TEMP%/gh-explore-{topic}-{ts}.md;--format jsonfor pipelines.Opt-in management (references only, not in scripts)
For things the discovery scripts can't do (create repo, open PR, label,
workflow dispatch, etc.), the skill ships reference docs under
skills/github-explore/references/commands-*.mdso an agent can run rawghcommands safely. The references are organized by domain:commands-auth-config.md— auth, config, env varscommands-repo-issue-pr.md— repo, issue, PR lifecyclecommands-cicd.md— workflow, cache, secret, variable, releasecommands-misc.md— org, label, SSH/GPG, gist, codespace, alias, extensioncommands-search-format.md—gh search, JSON/jq/template output,gh apiSECURITY-NOTES.md— the 4-point consent rule (target / impact /minimal data / confirmation) for any write command
Try it
Install from
/plugins→ Local, then ask:Expected result: a ranked, deduplicated list of repositories with
relevance scores, filtered of forks/archived/awesome-list noise, plus a
layered markdown summary (or
--format jsonfor pipelines).Other examples:
Dependencies and platforms
gh auth login)api.github.com;GH_HOSTredirects it (e.g. GitHub Enterprise Server, see "Network and data")Security model
update / delete / merge / dispatch. They only read.
commands-*.md. This includes repo/issue/PR/workflow writes,commands-auth-config.mdauth/config writes (gh auth login/logout/ switch/setup-git/refresh --scopes,gh config set), andcommands-search-format.mdAPI mutations (gh api --method POST|PUT|DELETE|PATCH, GraphQLmutation). Before any such commandruns, the agent must state the target (incl. host), the impact (incl.
credential/config effects and downstream triggers), the minimal data
being changed, and obtain explicit user confirmation. The full rule
lives in
references/SECURITY-NOTES.md.gh auth statusonly —never
gh auth token,--show-token, or--with-token.mask credential-shaped stderr via
_lib.redact_secrets(). Rawghcommands the agent runs directly via the shell are not auto-
redacted;
scripts/redact_stderr.pyprovides an opt-in pipe(
gh <cmd> 2>&1 | python scripts/redact_stderr.py). Best-effort only.existing gh CLI token; the plugin requests no scopes and stores nothing.
your GitHub host via the user's own gh CLI.
Network and data
(REST, search, and GraphQL;
gitremotes only forclone/fork). Quota limits apply (search ~30/min, core ~5000/hr) and
the scripts stay within them (
--max-workers 2default, retry on403/429).
GH_HOST/ GitHub Enterprise changes the network destination.Default is
github.com.GH_HOST=github.acme.com(GHES on-prem) orGH_HOST=acme.ghe.com(GHEC tenancy) reroutes allghAPI trafficthere (pure git ops still follow
git remote).--hostnameis nota global flag — it exists only on ~11 subcommands; the universal
switch is
GH_HOST=... gh <cmd>. Credentials are per-host(
hosts.yml/ keyring keyed by host): a PAT for one host does notauthenticate to another. Env-var tokens follow a strict scope:
GH_TOKEN/GITHUB_TOKENare read only forgithub.com+*.ghe.comgithub.localhost; GHES on-prem requiresGH_ENTERPRISE_TOKEN/GITHUB_ENTERPRISE_TOKEN. The skill does notvalidate
GH_HOST— the user is responsible for confirming the targetbefore any write command runs.
plugin requests none and stores none.
explicitly drives; discovery scripts cause no remote changes.
Test evidence
node scripts/validate.mjs→OK plugin Fectivnfy112357/github-explorepython scripts/run_tests.py→ 26 tests, all passingrun_ghuses argv list withshell=None; specialcharacters pass through as a single argv element
max_attempts,non-rate-limit errors return immediately,
org_landscapepaginatespublic_repos=250into 100/100/50 in orderfind_repos(plural camelCase top-level),repo_summary(singular fields underrepokey),explore(reposnested under
axes[i].repos[j]),--schemaflag behaviourBearer,
key=…,GH_TOKEN=…) redacted on everywarn/die/gh_jsonerror path; ordinary text passes through intactnode --test test/github-explore.test.mjs→ 1/1 pass (bridge to thePython suite, no network, no gh binary required)