From ed89bc016853a9a6a77a118a7e92c06c81238b32 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Tue, 16 Jun 2026 12:49:55 +0200 Subject: [PATCH] feat: bot-gh.sh preflights per-repo collaborator access The bot must be a collaborator on EACH private repo it opens PRs in; adding it to one repo doesn't cover the rest. When it isn't, gh fails with an opaque "Could not resolve to a Repository with the name '/'" that reads like a typo, not a missing grant (hit while opening the #8 PR in a second repo). - bot-gh.sh: parse a --repo target and, if the bot can't see it, print the exact one-time grant (owner: PUT collaborators) + invite-accept (bot: PATCH repository_invitations) commands instead of letting the opaque error surface. - USAGE.md: document the per-repo "invite + accept" step in the PR-feedback loop. Co-Authored-By: Claude Fable 5 --- .claude/scripts/bot-gh.sh | 26 ++++++++++++++++++++++++++ docs/USAGE.md | 6 ++++++ 2 files changed, 32 insertions(+) diff --git a/.claude/scripts/bot-gh.sh b/.claude/scripts/bot-gh.sh index 573d5b5..200fab9 100755 --- a/.claude/scripts/bot-gh.sh +++ b/.claude/scripts/bot-gh.sh @@ -28,4 +28,30 @@ if [ -f "$root/.env" ]; then fi : "${GH_BOT_TOKEN:?GH_BOT_TOKEN not set — add it to .env (see setup notes in this script)}" +# Preflight: the bot needs collaborator access to EACH (private) repo it acts on +# (setup step 2). Without it, gh fails with an opaque +# "Could not resolve to a Repository with the name '/'" that reads like +# a typo, not a missing grant. If a --repo target is given and the bot can't see it, +# print the exact one-time grant + invite-accept commands instead. +target_repo="" +prev="" +for a in "$@"; do + if [ "$prev" = "--repo" ]; then target_repo="$a"; break; fi + case "$a" in + --repo) prev="--repo"; continue;; + --repo=*) target_repo="${a#--repo=}"; break;; + esac +done +if [ -n "$target_repo" ] && ! GH_TOKEN="$GH_BOT_TOKEN" gh repo view "$target_repo" >/dev/null 2>&1; then + bot="$(GH_TOKEN="$GH_BOT_TOKEN" gh api user --jq .login 2>/dev/null || echo '')" + cat >&2 </'` (looks like a typo, is actually a + missing grant). `bot-gh.sh` preflights this and prints the fix; the one-time setup is, as the **owner**: + `gh api -X PUT repos///collaborators/ -f permission=push`, then **accept as the bot**: + `bot-gh.sh api -X PATCH user/repository_invitations/` (private-repo invites require acceptance). 4. **Review** — the owner reviews on GitHub. To address comments, feed them back through the orchestrator (*"address the comments on PR #N"*): same implementer loop, same branch, push updates the PR in place. 5. **Merge** — owner approves, merge per `gates.json.merge`, clean the worktree (below).