lovstudio-gh-access
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineselovstudio:gh-access
lovstudio:gh-access
Grant, revoke, and audit collaborator access on private GitHub repos — by
username or email, with read-only as the safe default.
管理私有GitHub仓库的协作者访问权限——支持通过用户名或邮箱操作,默认采用安全的只读权限。
Prerequisites
前置条件
- CLI authenticated (
gh) with a token that has:gh auth status- scope (always)
repo - scope (if the target repo is org-owned; caller must be org owner or repo admin)
admin:org
- The target repo exists and is accessible to the caller.
- 已通过CLI完成身份验证(执行
gh查看),且令牌具备以下权限范围:gh auth status- 权限范围(必填)
repo - 权限范围(若目标仓库归组织所有;调用者必须是组织所有者或仓库管理员)
admin:org
- 目标仓库已存在且调用者可访问。
Subcommands
子命令
This skill has three modes. Pick based on the user's intent:
| User intent | Subcommand |
|---|---|
| "开权限 / share / invite / grant" | grant |
| "撤销 / remove / revoke / 踢出" | revoke |
| "谁有权限 / who has access / list" | list |
If intent is unclear, use to disambiguate.
AskUserQuestion该技能包含三种模式,根据用户意图选择:
| 用户意图 | 子命令 |
|---|---|
| "开权限 / share / invite / grant" | grant |
| "撤销 / remove / revoke / 踢出" | revoke |
| "谁有权限 / who has access / list" | list |
若意图不明确,使用询问用户以明确需求。
AskUserQuestionWorkflow
工作流程
Step 0: Collect inputs via AskUserQuestion
步骤0:通过AskUserQuestion
收集输入信息
AskUserQuestionALWAYS collect the following BEFORE touching the API:
- Target repo — (e.g.
<owner>/<repo>). If the user is inside a git repo, pre-fill fromlovstudio/private-demo.gh repo view --json nameWithOwner -q .nameWithOwner - Subcommand — grant / revoke / list.
- (grant/revoke only) Identifiers — a whitespace- or comma-separated list of GitHub usernames and/or email addresses. Mixed is fine.
- (grant only) Permission level — default (read-only). Offer:
pull- — read + issues + PRs (recommended default)
pull - — read + can label/close issues & PRs, no code write
triage - — write access (⚠ confirm explicitly)
push - /
maintain— block unless user explicitly insistsadmin
Never silently escalate. If the user just says "给他权限" without specifying
level, default to and state that clearly.
pull务必在调用API前收集以下信息:
- 目标仓库 — (例如
<owner>/<repo>)。若用户当前处于git仓库目录中,可通过lovstudio/private-demo预填充该信息。gh repo view --json nameWithOwner -q .nameWithOwner - 子命令 — grant / revoke / list。
- (仅grant/revoke模式需要)标识信息 — 由空格或逗号分隔的GitHub用户名和/或电子邮件地址列表,支持混合输入。
- (仅grant模式需要)权限级别 — 默认(只读)。可提供以下选项:
pull- — 只读 + 提交Issue和PR(推荐默认选项)
pull - — 只读 + 可标记/关闭Issue和PR,但无代码写入权限
triage - — 写入权限(⚠ 需明确确认)
push - /
maintain— 除非用户明确要求,否则禁止使用admin
切勿擅自提升权限级别。若用户仅说“给他权限”而未指定级别,默认使用权限并明确告知用户。
pullStep 1: Resolve identifiers → GitHub usernames
步骤1:解析标识信息 → GitHub用户名
For each identifier in the list, follow this resolution chain and record the
outcome per identifier (for the final summary report):
identifier → classify → resolveClassification rule: an identifier containing is treated as an email,
otherwise as a GitHub username.
@针对列表中的每个标识,按照以下解析流程处理,并记录每个标识的处理结果(用于最终汇总报告):
identifier → classify → resolve分类规则: 包含的标识视为电子邮件地址,否则视为GitHub用户名。
@Case A — looks like a username
场景A — 标识为用户名
- Verify the account exists:
bash
gh api "users/<login>" --jq '.login' 2>/dev/null - If it returns the login → resolved as , status
login.user_ok - If the call 404s → status . Do NOT fall back to email invite (we don't have an email). Report and skip.
user_not_found
- 验证账户是否存在:
bash
gh api "users/<login>" --jq '.login' 2>/dev/null - 若返回登录名 → 解析为,状态为
login。user_ok - 若调用返回404错误 → 状态为。不退回至邮件邀请(无可用邮箱),向用户报告并跳过该标识。
user_not_found
Case B — looks like an email
场景B — 标识为电子邮件地址
- Search by email:
bash
gh api "search/users?q=<email>+in:email" --jq '.total_count, .items[0].login' - If and a login is returned → resolved as
total_count >= 1, statuslogin.email_to_user - If → fall back to email invite path:
total_count == 0- For org repos: then add the pending member as an outside collaborator on the repo once they accept. Note: inviting directly-to-repo by email is not supported by the REST API for non-org personal repos — if the target is a personal repo, report
gh api -X POST "orgs/<org>/invitations" -f email=<email> -f role=direct_memberand ask the user to obtain the recipient's GitHub username.email_no_account - Status: (org) or
email_invited(personal repo).email_no_account
- For org repos:
Show the resolution table to the user before performing writes:
| Input | Type | Resolved | Status |
|---|---|---|---|
| username | | user_ok |
| | email_to_user | |
| — | email_invited (or email_no_account) | |
| username | — | user_not_found |
Ask the user to confirm before proceeding with writes. Skip
and entries by default.
user_not_foundemail_no_account- 通过邮箱搜索用户:
bash
gh api "search/users?q=<email>+in:email" --jq '.total_count, .items[0].login' - 若且返回登录名 → 解析为
total_count >= 1,状态为login。email_to_user - 若→ 退化为邮件邀请流程:
total_count == 0- 组织仓库:执行,待用户接受邀请后,将其添加为仓库的外部协作者。注意:REST API不支持直接向个人私有仓库发送邮件邀请——若目标是个人仓库,报告
gh api -X POST "orgs/<org>/invitations" -f email=<email> -f role=direct_member并请求用户获取收件人的GitHub用户名。email_no_account - 状态:(组织仓库)或
email_invited(个人仓库)。email_no_account
- 组织仓库:执行
在执行写入操作前,向用户展示解析结果表格:
| 输入内容 | 类型 | 解析结果 | 状态 |
|---|---|---|---|
| 用户名 | | user_ok |
| 邮箱 | | email_to_user |
| 邮箱 | — | email_invited(或email_no_account) |
| 用户名 | — | user_not_found |
在执行写入操作前请用户确认。默认跳过和的条目。
user_not_foundemail_no_accountStep 2: Execute
步骤2:执行操作
grant
grant(授予权限)
For each resolved username, issue a repo invitation:
bash
gh api -X PUT "repos/<owner>/<repo>/collaborators/<login>" \
-f permission=<pull|triage|push|maintain|admin>- Response = invitation sent (pending until recipient accepts).
201 - Response = already a collaborator; permission was updated.
204 - Response = user not found or already pending; inspect and report.
422
For org-repo email invites that resolved to above, no
additional call is needed — the org invitation covers repo access once the
user accepts. Tell the user to remind the recipient to check their email.
email_invited针对每个解析后的用户名,发送仓库邀请:
bash
gh api -X PUT "repos/<owner>/<repo>/collaborators/<login>" \
-f permission=<pull|triage|push|maintain|admin>- 响应= 邀请已发送(待收件人接受)。
201 - 响应= 用户已是协作者;权限已更新。
204 - 响应= 用户不存在或邀请已处于待处理状态;检查并报告。
422
对于组织仓库中解析为的邮件邀请,无需额外调用API——用户接受组织邀请后即可获得仓库访问权限。告知用户提醒收件人查看邮箱。
email_invitedrevoke
revoke(撤销权限)
bash
gh api -X DELETE "repos/<owner>/<repo>/collaborators/<login>"- Response = removed (or was never a collaborator — idempotent).
204 - For email-only identifiers with no resolved login: use
only if the user explicitly wants to remove from the whole org; otherwise skip and report.
gh api -X DELETE "orgs/<org>/memberships/<login>"
Before executing revokes, show the list of logins that will be removed and
ask for a final confirmation (revokes are visible to the recipient and can
be socially awkward to reverse).
bash
gh api -X DELETE "repos/<owner>/<repo>/collaborators/<login>"- 响应= 权限已撤销(或用户从未是协作者——操作具有幂等性)。
204 - 对于无法解析为登录名的纯邮箱标识:仅当用户明确要求从整个组织移除时,执行;否则跳过并报告。
gh api -X DELETE "orgs/<org>/memberships/<login>"
执行撤销操作前,展示将被移除的登录名列表并请求最终确认(撤销操作对收件人可见,撤销后恢复可能会造成社交尴尬)。
list
list(列出协作者)
bash
gh api "repos/<owner>/<repo>/collaborators?affiliation=all" \
--jq '.[] | {login, permissions}' \
--paginateAlso list pending invitations:
bash
gh api "repos/<owner>/<repo>/invitations" --paginate \
--jq '.[] | {invitee: .invitee.login, email, permissions, created_at}'Present as two tables: Active collaborators and Pending invitations.
bash
gh api "repos/<owner>/<repo>/collaborators?affiliation=all" \
--jq '.[] | {login, permissions}' \
--paginate同时列出待处理的邀请:
bash
gh api "repos/<owner>/<repo>/invitations" --paginate \
--jq '.[] | {invitee: .invitee.login, email, permissions, created_at}'以两个表格形式展示:当前协作者和待处理邀请。
Step 3: Report
步骤3:生成报告
Show a final summary table for grant/revoke operations:
gh-access report — <owner>/<repo>
=================================
Granted (pull): alice, bobhub
Invited via email: carol@startup.io (pending org invite)
Skipped: typo-user (user_not_found)Include the invitation URL the user can share manually if helpful:
https://github.com/<owner>/<repo>/invitations为grant/revoke操作展示最终汇总表格:
gh-access report — <owner>/<repo>
=================================
已授予权限(pull):alice, bobhub
已发送邮件邀请:carol@startup.io(待组织邀请确认)
已跳过:typo-user(用户不存在)若有帮助,可附上用户可手动分享的邀请链接:
https://github.com/<owner>/<repo>/invitationsRules
规则
- Default to (read-only) unless the user explicitly names a higher permission. State the chosen level clearly before executing.
pull - Never escalate to /
adminwithout an explicit, unambiguous request — ask a confirmingmaintaineven if the user seemed to ask.AskUserQuestion - Show the resolution table before writes. Clients mistyping a username is common; showing the resolved login prevents inviting the wrong person.
- Idempotent revokes. A on a non-collaborator is fine — don't panic.
204 - Batch-friendly. A single invocation can process a long mixed list; execute resolution in parallel where possible, but keep writes sequential so partial failures are easy to report.
- Email invites only work cleanly for org repos. For personal repos without a resolved username, stop and ask the user to obtain a GitHub username from the recipient.
- Private repos only are the typical case, but this skill works on public repos too — no need to refuse.
- 默认使用(只读)权限,除非用户明确指定更高权限。执行前需明确告知用户所选权限级别。
pull - 切勿擅自提升至/
admin权限,除非用户明确、无歧义地提出请求——即使用户看似提出了该需求,也需通过maintain确认。AskUserQuestion - 执行写入操作前展示解析结果表格。用户输入用户名时容易出错,展示解析后的登录名可避免邀请错误的用户。
- 撤销操作具有幂等性。对非协作者执行撤销操作返回是正常情况——无需惊慌。
204 - 支持批量处理。单次调用可处理长列表的混合标识;尽可能并行执行解析操作,但写入操作需按顺序执行,以便轻松报告部分失败情况。
- 邮件邀请仅适用于组织仓库。对于无法解析用户名的个人仓库,需停止操作并请求用户获取收件人的GitHub用户名。
- 典型场景为私有仓库,但该技能也适用于公开仓库——无需拒绝处理。
Common gh CLI quick reference
常用gh CLI速查
bash
undefinedbash
undefinedWho am I? What scopes do I have?
查看当前登录身份及权限范围
gh auth status
gh auth status
Is this a repo I can admin?
查看是否拥有仓库管理员权限
gh api "repos/<owner>/<repo>" --jq '.permissions'
gh api "repos/<owner>/<repo>" --jq '.permissions'
Cancel a pending invitation
取消待处理的邀请
gh api -X DELETE "repos/<owner>/<repo>/invitations/<invitation_id>"
gh api -X DELETE "repos/<owner>/<repo>/invitations/<invitation_id>"
Show org membership of a user
查看用户的组织成员身份
gh api "orgs/<org>/memberships/<login>" --jq '.role, .state'
undefinedgh api "orgs/<org>/memberships/<login>" --jq '.role, .state'
undefined