SuperAPI AI 工具集

gh-fine-grained-pat

部署与运维

查看项目

更新于 10-16 05:37

技能介绍

用途

GitHub 没有提供创建细粒度个人访问令牌(fine-grained PAT)的 API(社区议题 #148626),网页界面是唯一途径。本技能通过 Chrome DevTools Protocol 驱动该界面,从声明式 JSON 规格创建令牌,使令牌创建过程可重复、可审查、抗脆弱,而不是手工点击的一次性操作。

该技能被描述为“自进化技能”:GitHub 的设置界面会漂移,如果选择器未命中、模态框/选择器/权限流程发生变化,或某个权限的详情页名词有误,应立即修复 scripts/、CLAUDE.md(选择器映射 + 名词映射)或规格,不要推迟。仅在出现真实、可复现的故障时更新。

主要能力

  • 从规格创建限定范围的令牌(发布机器人、CI 报告器、只读审计器、账户范围),用于存储到 SCS 保险库。
  • 从已检入的规格重新创建或轮换令牌。
  • 列出、验证(回读设置)或撤销细粒度令牌。
  • 提供多个动词:create、rotate、list、inspect <name>、delete <name>、quit(按特定 PID 终止调试 Chrome)。rotate 是就地滚动令牌的安全方式——一步撤销旧值并存储新值。

使用方式

前置条件

  • node(不是 bun——Bun 的 connectOverCDP 会超时)和 playwright-core(已在仓库根 package.json 中固定版本)。
  • 标准 macOS 路径下的 Google Chrome。
  • 一次性 GitHub 登录(持久化在配置文件中)。

一次性登录(之后完全自动化)

持久化 Chrome 配置文件保存 GitHub 会话 cookie,因此只需登录一次,之后每次运行都会复用:

cd plugins/gh-tools/skills/gh-fine-grained-pat
node scripts/pat.mjs login      # opens Chrome; sign in (incl. 2FA); it auto-detects success
node scripts/pat.mjs doctor     # runtime + chrome + profile + auth health

配置文件位于 ~/.local/share/gh-pat-automation/profile(可用 GH_PAT_PROFILE_DIR 覆盖)。应将其视为敏感数据——它可以冒充你的 GitHub 会话。它位于仓库之外,永远不会被提交。

从规格创建令牌

# write the value to a 0600 file (default) — the value is NEVER printed to the terminal
node scripts/pat.mjs create specs/release-bot.json --out /tmp/.tok

# …or pipe it straight into the SCS vault (value passed in-process, never to chat)
node scripts/pat.mjs create specs/release-bot.json --vault cc-skills:gh.token

# rotate: revoke the same-named token, create a replacement, store it (sink required)
node scripts/pat.mjs rotate specs/release-bot.json --vault cc-skills:gh.token

规格格式

规格是经 schema/token-spec.schema.json(机器可读的 SSoT)验证的 JSON。最小形态:

{
  "name": "release-bot",
  "expiration": "none", // 7|30|60|90 | "YYYY-MM-DD" | "none"
  "repositoryAccess": { "mode": "selected", "repos": ["owner/repo"] },
  "permissions": { "repository": { "Contents": "write", "Issues": "write" } },
}

read → "Read-only",write → "Read and write"。权限键是确切的 UI 标签(Contents、Pull requests、Commit statuses、Gists 等)。不要列出 Metadata——它是自动必需的只读权限。

随附模板(specs/)

  • release-bot.json:semantic-release:Contents/Issues/PRs 读写,单个仓库,无过期。
  • read-only-auditor.json:Contents 只读,单个仓库。
  • ci-status-reporter.json:Commit statuses 读写 + Actions 读取。
  • account-scoped.json:仅账户权限(Gists),无仓库写入。
  • kitchen-sink.json:超集:多个仓库、无过期、许多仓库权限 + 账户权限(覆盖每个 UI 分支)。

更多示例形态(全仓库管理员、组织拥有、密钥管理)位于 specs/examples/——不会被 campaign 自动运行。依赖其中之一前请先查看该文件夹的 README。

安全不变量

  • 令牌值永远不会打印到 stdout/聊天——仅通过 --out <0600 file> 或 --vault <scope>:<dot.path>。
  • 拆除时按特定 PID 终止 Chrome(对 CDP 端口执行 lsof),绝不使用 pkill -f(进程风暴策略)。
  • 会话 cookie 配置文件是敏感的,位于仓库之外。

验证(经验性 campaign)

node test/campaign.mjs          # create→verify→delete every spec + a forced-failure case, in one session

该测试框架将测试令牌命名为 zz-pat-selftest-*,自动删除它们,断言没有泄漏,并确认真实令牌(cc-skills-release)未被触碰。重新运行无需登录(证明会话复用)。

自主网页认证(可选,多账户)

GitHub 的 sudo 模式(“Confirm access”)通常需要人工手势。引擎可以使用自托管凭据自主清除它——参见 ADR。每个账户一次性:

node scripts/pat.mjs register --account <login>   # capture a passkey (virtual authenticator) + password/TOTP → gated vault
node scripts/pat.mjs patch-password --account <login>  # fix a missed password dialog (passkey kept; idempotent) [--force] [--totp]
node scripts/pat.mjs agent start                  # memory-only session agent: one Touch-ID unlock lasts the session
GH_PAT_AUTONOMOUS=1 node scripts/pat.mjs create specs/release-bot.json --account <login> --vault cc-skills:gh.token

账户解析顺序:--account → 仓库的 origin 主机别名 → 规格所有者 → 已登录配置文件。凭据是 Touch-ID 门控的“皇冠明珠”,存储为单个 blob(github-web-<login>):进入操作时轻触一次,之后整个会话无需再操作(agent 仅在内存中缓存它)。无头/cron 被有意不支持(门控层级需要那一次实时轻触)。主路径 = 虚拟认证器 passkey;回退 = 密码 + oathtool TOTP。

适用场景

  • 为发布机器人、CI 报告器、只读审计器或账户范围用途创建限定范围的令牌,并存储到 SCS 保险库。
  • 从已检入的规格重新创建或轮换令牌。
  • 列出、验证或撤销细粒度令牌。
  • 需要可重复、可审查的令牌创建流程,而非手工点击。

限制

  • 依赖 GitHub 网页界面,因为 GitHub 没有创建细粒度 PAT 的 API。
  • 需要 node(不是 bun)和 playwright-core,以及标准 macOS 路径下的 Google Chrome。
  • 需要一次性 GitHub 登录;会话 cookie 配置文件敏感,位于仓库之外。
  • 无头/cron 被有意不支持(自主认证的门控层级需要一次实时轻触)。
  • GitHub 界面漂移可能导致选择器未命中,需要修复 scripts/、CLAUDE.md 或规格。

故障排除

GitHub 会重命名 CSS 类,但保留名称/角色/标签——引擎优先使用 role/name/label,并带有 DOM 文本回退,失败时截图到 /tmp/gh-pat-debug。当 UI 漂移时,实时选择器映射和八个来之不易的陷阱记录在 CLAUDE.md 中,便于快速修复。

执行后反思

运行此技能后,在关闭任务前反思:

  • 什么坏了?——选择器未命中、模态框/选择器/标签页流程变化,或 sudo 模式停滞:修复 scripts/form.mjs(或 browser.mjs)并更新 CLAUDE.md 中的选择器映射。
  • 新权限?——确认其详情页名词(创建一个令牌,读取设置页),并将其添加到 test/campaign.mjs(NOUN)+ CLAUDE.md 名词表。
  • 新令牌形态?——添加一个 specs/(或 specs/examples/)模板,以便下次复用。
  • 记录它。——在 CLAUDE.md 的“Recent changes”部分追加一行带日期的记录。不要推迟——下一次调用会继承你留下的一切。