| name | credfeto-pr-sync |
| description | Keep pull request titles, bodies, and labels in sync with their linked issues, and manage PR lifecycle including bot-created PR ownership and draft state. Use on every agent run that interacts with a PR, when creating or updating a PR, when checking for existing PRs before starting work, when replying to PR comments, when checking CI status on a PR, or when blocking a PR pending human input. |
Pull Request Sync and Lifecycle
Title, Body, and Label Sync (MANDATORY — every PR interaction)
On every agent run, for every PR being interacted with:
-
Ensure the title accurately reflects all changes in the PR — update it if the scope has changed.
-
Ensure the body summarises all changes and includes Closes #<n> for each linked issue, if any.
-
Sync labels from all linked closing issues to the PR:
gh pr view <pr> --repo <owner/repo> --json closingIssuesReferences \
--jq '.closingIssuesReferences[].number' \
| while IFS= read -r n; do
gh issue view "$n" --repo <owner/repo> --json labels --jq '.labels[].name' \
|| echo "Warning: could not fetch labels for issue $n" >&2
done \
| sort -u \
| grep -vE '^(Blocked|On-Hold)$' \
| while IFS= read -r label; do
gh pr edit <pr> --repo <owner/repo> --add-label "$label" \
|| echo "Warning: could not add label '$label' to PR" >&2
done
The Blocked and On-Hold labels are explicitly excluded — workflow-control labels must never be synced from an issue to its PR.
-
Never remove any label from a PR or issue — GitHub workflows add labels automatically and they must not be removed.
Label Management (MANDATORY)
- Always use
--add-label when adding labels — never --label, which replaces all existing labels and destroys automatically-applied classification labels.
- Never remove labels from issues or PRs.
Comment Replies (MANDATORY)
Reply to every PR comment that prompted an action. Check both comment surfaces before concluding there is nothing to reply to: top-level PR comments and review summaries (gh pr view <n> --repo <owner/repo> --json comments,reviews) and inline/diff-level review comments (gh api repos/<owner>/<repo>/pulls/<n>/comments) — a review can carry an empty top-level body with the actual feedback only in an inline comment.
- Code change made: reply with
Fixed in <commit-sha> — <one sentence describing what changed and why>.
- Question answered inline (no code change): reply with the full answer.
- No reply means no acknowledgement — always close the loop.
CI Checks (MANDATORY)
When working on a PR, check CI state once: gh pr checks <number> --repo <owner/repo>. Then act immediately — do not loop, sleep, or use --watch:
- All required checks passed → proceed with the next step.
- Any check pending or in_progress → stop silently — do not post a status comment. CI checks are bound by GitHub's own timeouts and will eventually pass, fail, or time out without intervention.
- Any check failed → investigate, fix, push, post a status comment, and stop. Do not wait for the new run to complete.
- CI consistently failing and cannot be fixed → mark the PR blocked:
gh pr edit <number> --repo <owner/repo> --add-label "Blocked".
Blocked Label (MANDATORY)
When asking a question in a PR comment and waiting for an answer before continuing:
- Add the
Blocked label to the PR immediately after posting the question: gh pr edit <number> --repo <owner/repo> --add-label "Blocked".
- Do not continue working on the PR until the label is removed.
- Use only the
Blocked label for this purpose — never a substitute such as do not merge or needs review.
- Live-chat approval is not sufficient on its own: if a human answers or approves in a live chat session rather than posting a GitHub comment directly, post the comment yourself — quoting the live instruction — before resuming work and before asking for
Blocked to be removed.
PR Lifecycle
- Only one active branch or open PR per repository at a time; do not create another until the current one is merged and closed.
- Before blocking new work because of an existing PR: always verify its current state with
gh pr view <number> --repo <owner/repo> --json state,mergedAt — never rely on conversation memory.
- When adding work to an open PR (review comments, missing coverage, CI fixes), convert to draft first:
gh pr ready <number> --undo. Keep it in draft until testing and review are both satisfied — only convert it back when ready for submission.
- Assign yourself to PRs when creating or updating:
gh pr edit <number> --add-assignee @me.
Bot-Created PRs (MANDATORY — treat as your own)
GitHub is configured to automatically create PRs from pushed branches. These PRs appear authored by app/github-actions but the commits are authored by you.
Before starting any work in a repository:
- Run
gh pr list --state open --repo <owner/repo> --json number,title,author,headRefName,url — no --author @me filter.
- For any PR authored by
app/github-actions, check the commit authors: gh pr view <n> --repo <owner/repo> --json commits --jq '.commits[].authors[].login'.
- If all commits are from your account, take ownership: update the PR title and body to match the proper format (summary,
Closes #<n>, test plan), add yourself as assignee, and treat it as your active PR for that repo.
- If commits are from multiple authors (e.g. you plus a human or Copilot), do not take over — leave the PR as-is.
- Do not create a new branch or PR for the same issue — that would be duplicate work.
Checking for existing work before branching (MANDATORY):
- Check branch names in all open PRs, not just PR authors. If any open PR's
headRefName contains the issue number, that is your work from a prior session — resume it instead of creating a new branch.
When you find a duplicate pair (a bot-created PR and one you authored yourself, for the same issue or branch):
- Keep whichever has the more complete body and later review activity.
- Close the other with a comment explaining which PR supersedes it.
GitHub CLI Comment Bodies (MANDATORY)
When posting comment or PR bodies via the GitHub CLI, always pass multi-line text using a HEREDOC so that real newline characters are embedded. Never use escaped \n sequences — GitHub renders them as literal characters:
gh pr comment <number> --repo <owner/repo> --body "$(cat <<'COMMENT'
First paragraph.
Second paragraph.
COMMENT
)"
GitHub CLI Proxy Behaviour
When GH_HOST is set to a value other than github.com, gh routes through a proxy:
-
gh pr create: always pass both --repo <owner>/<repo> and --head <owner>:<branch>. Without --repo, gh performs a client-side check that a git remote URL's hostname matches GH_HOST — since remotes use github.com but GH_HOST is the proxy host, no remote matches and gh refuses before any API request reaches the proxy. Without --head, gh may try to detect the branch from git remotes, leading to a blank head ref at the proxy's GraphQL layer.
gh pr create \
--repo <owner>/<repo> \
--head <owner>:<branch-name> \
--base main \
--draft \
--title "..." \
--body "..."
-
If a gh command fails, raise an issue on credfeto/github-api-proxy with the exact subcommand and flags, the API method (if visible), and the full error message.
-
Commit and push operations are always rejected by the proxy — use the git CLI directly for all commit and push operations.