GitHub Queries
bash.agents/skills/github/scripts/github.sh [-C <path>] <command> [options]
Commands
| Command | Purpose |
|---|---|
pr-data <N> [--actionable] | Get PR with threads, comments, files. --actionable: unresolved non-outdated only. |
pr-view [N] [--json FIELDS] | View PR details (wraps gh pr view with bounded auth/no-PR errors) |
pr-threads <N> [--unresolved|--resolved] [--format=safe|raw] | Complete paginated thread list/count, outdated included. Both filters apply in both formats. See PR blocked with no visible conversations. |
pr-list-ready [--all] [--format=safe|table] | List PRs ready for merge |
pr-list-failing [--all] [--format=safe|table] | List PRs with CI failures |
pr-create [--title T] [--body B | --body-file PATH] [--draft] [--dry-run] [--force] | Create PR as bot. Safety checks: not main, has commits, pushed; --force skips them. |
pr-edit-body <N> --body-file PATH | Update an existing PR body through the sanitized router. |
pr-merge <N> [--check|--force|--admin|--auto] | Merge PR. --check reports readiness as JSON on stdout plus a one-word verdict and head-run: <ids> (the run scope of the CI classification) on stderr; --auto queues a currently-blocked PR. Three exit codes, the review-thread gate, and --force/--admin. See PR Merge Outcomes. |
ci-classify-refusal <N> | Name the cause of a pr-merge refusal on one cause: line (fetch_error, merge_conflict, changes_requested, threads, ci_failed, ci_pending, computing, merged, closed, none; an issue prefix outside that vocabulary becomes the cause word itself, and none means the checks pass now); ci_failed adds fail: lines run-correlated to the authoritative run and superseded: lines naming runs whose checks were not counted. --help |
pr-cross-check [N...] [--quick|--verify] | Cross-PR analysis. --verify: full build+test (auto-detects build system). |
pr-issue <N> [--format=safe|text] | Extract issue ID from PR branch (configurable via GH_ISSUE_PATTERN) |
label-add <PR-or-issue> <label> [--issue] [--required|--optional] | Add a label after checking the live inventory. Mode semantics and exit codes: label-add --help. |
label-remove <PR-or-issue> <label> [--issue] | Remove a label through the sanitized router. |
await-mergeable <N> [--interval S] [--max-iter N] [--quiet] | Block until GitHub resolves a PR's merge state. Polls state + mergeStateStatus. Exit 0 + JSON on resolve, 124 on timeout. |
ci-logs <N> [--lines N] [--format=safe|text] | Get CI failure logs for PR |
bot-token [--format=safe|text] | Check if bot token is configured, naming the selected variable as source |
dismiss-review <PR> [--bot|--user NAME] [--message M] | Dismiss blocking review |
resolve-thread <PRRT_...> | Mark thread(s) resolved. Works on threads the UI cannot render. See PR blocked with no visible conversations. |
unresolve-thread <PRRT_...> | Reopen thread(s) |
post-reply <PRRT_...|numeric-id> [body | --body-file PATH] [--pr N] | Reply to review comment. --pr N is REQUIRED for numeric comment IDs; thread PRRT_... IDs need no PR number. |
post-comment <PR> [body | --body-file PATH] | Post PR-level comment. |
find-comment <PR> --pattern <regex> | Find comment by pattern/author |
edit-comment <id> [body | --body-file PATH] | Edit existing comment. |
sticky-comment <PR> [--verdict|--analysis|--body] | Get bot sticky comment. --verdict: quick pass/fail. --analysis: deep recommendation. |
CI waiting belongs to .agents/skills/orch/scripts/ci-wait; await-mergeable waits for merge-state resolution.
Contracts: label-add --help, git-https-auth --help, git-diff-summary --help.
PR Merge Outcomes
Full contract: pr-merge --help. Exit 75 is volatile: the caller arms one exact head and waits on that head with the orch skill's queue-wait, whose --help § Verdicts maps each verdict to a route; an unrecognized verdict is never re-armed. With the review-gate skill installed, its watcher output contract is pr-watch.sh --help. If can_merge is false with no issues, read state. The thread gate is Policy, not mechanism. --force and the explicit-user-only --admin are its overrides.
PR blocked with no visible conversations
Under required_conversation_resolution, an outdated thread can block a merge while the UI shows none; resolve-thread reaches it by id.
bashgithub.sh pr-threads 42 # complete list, outdated included github.sh resolve-thread PRRT_kwDO... # resolve by thread id
pr-threads follows every page and fails rather than returning a partial list, so a thread id absent from its output is genuinely absent. Repeat resolve-thread per blocking id until the merge clears.
Waiting for merge state
Never gate termination on gh pr view --json mergeable. That field stays UNKNOWN permanently after a merge. Use await-mergeable (resolution rules and exit codes: await-mergeable --help). To watch MANY PRs, do not hand-roll a poll loop keyed on state transitions. Use the review-gate skill's reducer when installed (.agents/skills/review-gate/scripts/pr-watch.sh).
Output Formats
Formats and flag rules: github.sh --help.
Configuration
Keep secrets in .env.local; commit non-secret defaults to kendex.settings.toml under [env]. Other contracts: github.sh --help.
Troubleshooting
VAR_SIGN: use a multi-line GraphQL query with -F variables.
Stale-token HTTP 401: clear both environment tokens:
bashenv -u GH_TOKEN -u GITHUB_TOKEN gh pr list
github.sh falls back when keyring auth succeeds.
Dependencies
ghCLI (authenticated)jqopCLI (optional, 1Password token references)

