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).