GH PR
Overview
Create or update GitHub Pull Requests with the gh CLI using a detailed body template and strict same-branch rules.
Decision rules (must follow)
- Do not create or switch branches. Always use the current branch as the PR head.
- Check local working tree state before push/PR operations.
git status --porcelain
- If output is non-empty (tracked or untracked changes), pause and ask the user what to do.
- Present 3 options: continue as-is, abort, or manual cleanup then rerun.
- Do not run
git stash, git commit, or git clean automatically unless explicitly requested.
- Check for an existing PR for the current head branch.
gh pr list --head <head> --state all --json number,state,mergedAt,updatedAt,url,title,mergeCommit
- If no PR exists → create a new PR.
- If any PR exists and is NOT merged (
mergedAt is null) → push only and finish (do not create a new PR).
- This applies to OPEN or CLOSED (unmerged) PRs.
- Only update title/body/labels if the user explicitly requests changes.
- If all PRs for the head are merged → check for post-merge commits (see below).
- If multiple PRs exist for the head → use the most recently updated PR for reporting, but the create vs push decision is based on
mergedAt.
Post-merge commit check (critical)
When all PRs for the head branch are merged, you must check whether there are new commits after the merge:
- Get the merge commit SHA of the most recent merged PR.
- Validate merge commit ancestry first:
git merge-base --is-ancestor <merge_commit> HEAD
- If the merge commit is an ancestor of
HEAD, count commits after the merge:
git rev-list --count <merge_commit>..HEAD
- If the merge commit is missing or not an ancestor of
HEAD, fallback to the branch upstream first:
git rev-list --count origin/<head>..HEAD
- If the upstream comparison fails, fallback to the base branch comparison:
git rev-list --count origin/<base>..HEAD
- Decision:
- If the selected count is greater than 0 → create a new PR
- If the selected count is 0 → report "No new changes since merge" and finish
- If both fallback comparisons fail → stop and report
MANUAL CHECK
Why this matters
- Scenario A: PR merged → user makes local changes → pushes → changes are NOT in the merged PR
- Without this check, the changes would be lost or require manual intervention
- Scenario B: PR merged → user says "create PR" without new changes → would create empty/duplicate PR
- This check prevents unnecessary PR creation
PR title rules (must follow)
- Format:
<type>(<scope>): <subject> — follow Conventional Commits.
- type: must be one of
feat / fix / docs / chore / refactor / test / ci / perf.
- scope: optional. Use a short scope that clearly identifies the affected area (for example:
gui, core, pty).
- subject: keep it within 70 characters. Use the imperative mood (for example: "add ..." / "fix ..."). Do not capitalize the first letter or end with a period.
- If the branch name has a prefix such as
feat/ or fix/, the title type must match that prefix.
PR body rules (must follow)
Section classification
| Section |
Required |
Notes |
| Summary |
YES |
1-3 bullet points. Include both the what and the why. |
| Changes |
YES |
Enumerate changes by file or module. |
| Testing |
YES |
List the commands run or the exact manual test steps. |
| Related Issues / Links |
YES |
Specify issue numbers, spec links, or "None". |
| Checklist |
YES |
Review every item and mark it checked or N/A. |
| Context |
Conditional |
Required when 3 or more files changed or the rationale is non-trivial. |
| Risk / Impact |
Conditional |
Required when the change is breaking, performance-sensitive, or needs rollback steps. |
| Screenshots |
Conditional |
Required only for UI changes. |
| Deployment |
Optional |
Include only when deployment steps exist. |
| Notes |
Optional |
Include only when reviewers need extra context. |
Validation (agent must check before creating PR)
- Do not create a PR if any required section still contains
TODO.
- If a conditional section does not apply, remove the entire section instead of leaving an empty TODO.
- Each Summary bullet must be a single sentence. Do not use vague wording such as "several changes" or "various fixes."
- Changes must be specific and include the changed file or module names.
- Testing must be reproducible. Do not use vague wording such as "tested."
- Add a reason comment to every unchecked checklist item (for example:
- [ ] Docs updated — N/A: no user-facing change).
- Related Issues must be written as
#123 or as a URL. If nothing applies, explicitly write "None".
Issue/PR Comment Formatting (must follow)
- Final comment text must not contain escaped newline literals such as
\n.
- Use real line breaks in comment bodies. Do not rely on escaped sequences for formatting.
- Before posting, verify the final body does not accidentally include escaped control sequences (
\n, \t).
- If a raw escape sequence must be shown for explanation, include it only inside a fenced code block and clarify it is intentional.
Issue Progress Comment Template (required for issue-based work)
When work is tracked in GitHub Issues, progress updates must use this template:
Progress
- ...
Done
- ...
Next
- ...
- Post updates at least when starting work, after meaningful progress, and when blocked/unblocked.
- In
Next, explicitly state blockers or the immediate next action.
Workflow (recommended)
Confirm repo + branches
- Repo root:
git rev-parse --show-toplevel
- Current branch (head):
git rev-parse --abbrev-ref HEAD
- Base branch defaults to
develop unless user specifies.
Check local working tree state (preflight)
- Run
git status --porcelain.
- If empty, continue.
- If non-empty, show detected files and ask the user to choose:
- Continue as-is
- Abort
- Manual cleanup first (
git commit / git stash / git clean) and rerun
- Proceed only when the user explicitly chooses continue.
Fetch latest remote state
git fetch origin to ensure accurate comparison
Check branch sync against base (critical)
- Run
git rev-list --left-right --count "HEAD...origin/$base".
- Parse the result as
ahead behind.
- If
behind > 0 and ahead == 0 → stop and report Branch update required before creating a PR.
- If
behind > 0 and ahead > 0 → stop and report Branch has diverged from base. Sync it before creating a PR.
- Continue only when
behind == 0.
Check existing PR for head branch
- Use decision rules above to pick action.
- Treat
mergedAt as the source of truth for "merged".
If all PRs are merged, perform post-merge commit check
- Get merge commit:
gh pr list --head <head> --state merged --json mergeCommit -q '.[0].mergeCommit.oid'
- If the merge commit is an ancestor of
HEAD, count git rev-list --count <merge_commit>..HEAD
- If the merge commit is missing or not an ancestor, count
git rev-list --count origin/<head>..HEAD first
- Only if the upstream comparison fails, count
git rev-list --count origin/<base>..HEAD
- If the selected count is 0 → finish with message "No new changes since merge"
- If the selected count is >0 → proceed to create new PR
- If neither comparison is usable → stop with
MANUAL CHECK
Ensure the head branch is pushed
- If no upstream:
git push -u origin <head>
- Otherwise:
git push
Collect PR inputs (for new PR or explicit update)
- Title, Summary, Context, Changes, Testing, Risk/Impact, Deployment, Screenshots, Related Links, Notes
- Optional: labels, reviewers, assignees, draft
Build PR body from template
- Read the template from the gwt-pr skill path (not the current project path):
PR_BODY_TEMPLATE=".claude/skills/gwt-pr/references/pr-body-template.md"
- Read
${PR_BODY_TEMPLATE} and fill all required placeholders.
- If a conditional section does not apply, remove the entire section.
- Remove any
<!-- GUIDE: ... --> comments from the final output.
- If any required section still contains TODO, do not create the PR and ask the user for the missing information.
Create or update the PR
- Create:
gh pr create -B <base> -H <head> --title "<title>" --body-file <file>
- Update (only if user asked):
gh pr edit <number> --title "<title>" --body-file <file>
Return PR URL
gh pr view <number> --json url -q .url
Post-PR CI/merge check (automatic).
- After PR creation or push, load
.claude/skills/gwt-fix-pr/SKILL.md and follow its workflow to inspect CI status, merge state, and review feedback.
- If all CI checks are still pending, poll (30s interval) until complete.
- If conflicts, review issues, or CI failures are detected, proceed with the gwt-fix-pr workflow to diagnose and fix.
Command snippets (bash)
head=$(git rev-parse --abbrev-ref HEAD)
base=develop
PR_BODY_TEMPLATE=".claude/skills/gwt-pr/references/pr-body-template.md"
if [ ! -f "$PR_BODY_TEMPLATE" ]; then
echo "PR template not found: $PR_BODY_TEMPLATE" >&2
exit 1
fi
# Preflight: local working tree state
status_lines=$(git status --porcelain)
if [ -n "$status_lines" ] && [ "${ALLOW_DIRTY_WORKTREE:-0}" != "1" ]; then
echo "Detected local uncommitted/untracked changes:" >&2
echo "$status_lines" >&2
echo "Choose one before continuing: continue as-is, abort, or manual cleanup then rerun." >&2
echo "Set ALLOW_DIRTY_WORKTREE=1 only after explicit user confirmation to continue." >&2
exit 1
fi
# Fetch latest remote state
git fetch origin
# Check branch sync against base before PR creation
divergence=$(git rev-list --left-right --count "HEAD...origin/$base" 2>/dev/null) || {
echo "Failed to compare HEAD with origin/$base" >&2
exit 1
}
ahead_count=$(echo "$divergence" | awk '{print $1}')
behind_count=$(echo "$divergence" | awk '{print $2}')
if [ "${behind_count:-0}" -gt 0 ] && [ "${ahead_count:-0}" -gt 0 ]; then
echo "Branch has diverged from base. Sync it before creating a PR." >&2
exit 1
fi
if [ "${behind_count:-0}" -gt 0 ]; then
echo "Branch update required before creating a PR." >&2
exit 1
fi
# Check existing PRs for the head branch
pr_json=$(gh pr list --head "$head" --state all --json number,state,mergedAt,mergeCommit)
pr_count=$(echo "$pr_json" | jq 'length')
unmerged_count=$(echo "$pr_json" | jq 'map(select(.mergedAt == null)) | length')
if [ "$pr_count" -eq 0 ]; then
action=create
elif [ "$unmerged_count" -gt 0 ]; then
action=push_only
else
# All PRs are merged - check for post-merge commits
merge_commit=$(echo "$pr_json" | jq -r 'sort_by(.mergedAt) | last | .mergeCommit.oid')
new_commits=""
if [ -n "$merge_commit" ] && [ "$merge_commit" != "null" ] && \
git merge-base --is-ancestor "$merge_commit" HEAD 2>/dev/null; then
new_commits=$(git rev-list --count "$merge_commit"..HEAD 2>/dev/null || echo "")
fi
if [ -n "$new_commits" ]; then
if [ "$new_commits" -gt 0 ]; then
echo "Found $new_commits commit(s) after merge - creating new PR"
action=create
else
echo "No new commits since merge - nothing to do"
action=none
fi
else
upstream_commits=$(git rev-list --count "origin/$head"..HEAD 2>/dev/null || echo "")
if [ -n "$upstream_commits" ]; then
if [ "$upstream_commits" -gt 0 ]; then
echo "Found $upstream_commits commit(s) ahead of origin/$head - creating new PR"
action=create
else
echo "No new commits ahead of origin/$head - nothing to do"
action=none
fi
else
fallback_commits=$(git rev-list --count "origin/$base"..HEAD 2>/dev/null || echo "")
if [ -n "$fallback_commits" ]; then
if [ "$fallback_commits" -gt 0 ]; then
echo "Upstream comparison unavailable; found $fallback_commits commit(s) ahead of origin/$base - creating new PR"
action=create
else
echo "Upstream comparison unavailable and no commits ahead of origin/$base - nothing to do"
action=none
fi
else
echo "Manual check required: could not determine whether new commits exist after the last merge" >&2
action=manual_check
fi
fi
fi
fi
# Execute action
case "$action" in
create)
cp "$PR_BODY_TEMPLATE" /tmp/pr-body.md
git push -u origin "$head"
gh pr create -B "$base" -H "$head" --title "..." --body-file /tmp/pr-body.md
;;
push_only)
echo "Existing unmerged PR found - pushing changes only"
git push
gh pr list --head "$head" --state open --json url -q '.[0].url'
;;
none)
echo "No action needed - no new changes since last merge"
;;
manual_check)
echo "Manual check required - post-merge commit status could not be determined" >&2
exit 1
;;
esac
References
.claude/skills/gwt-pr/references/pr-body-template.md: PR body template
1---2name: gwt-pr-33description: Create or update GitHub Pull Requests with the gh CLI, including deciding whether to create a new PR or only push based on existing PR merge status. Use when the user asks to open/create/edit a PR, generate a PR body/template, or says 'open a PR/create a PR/gh pr'. Defaults: base=develop, head=current branch (same-branch only; never create/switch branches).4---56# GH PR78## Overview910Create or update GitHub Pull Requests with the gh CLI using a detailed body template and strict same-branch rules.1112## Decision rules (must follow)13141. **Do not create or switch branches.** Always use the current branch as the PR head.152. **Check local working tree state before push/PR operations.**16 - `git status --porcelain`17 - If output is non-empty (tracked or untracked changes), pause and ask the user what to do.18 - Present 3 options: continue as-is, abort, or manual cleanup then rerun.19 - **Do not** run `git stash`, `git commit`, or `git clean` automatically unless explicitly requested.203. **Check for an existing PR for the current head branch.**21 - `gh pr list --head <head> --state all --json number,state,mergedAt,updatedAt,url,title,mergeCommit`224. **If no PR exists** → create a new PR.235. **If any PR exists and is NOT merged** (`mergedAt` is null) → push only and finish (do **not** create a new PR).24 - This applies to OPEN or CLOSED (unmerged) PRs.25 - Only update title/body/labels if the user explicitly requests changes.266. **If all PRs for the head are merged** → check for post-merge commits (see below).277. **If multiple PRs exist for the head** → use the most recently updated PR for reporting, but the create vs push decision is based on `mergedAt`.2829## Post-merge commit check (critical)3031When all PRs for the head branch are merged, you **must** check whether there are new commits after the merge:32331. **Get the merge commit SHA** of the most recent merged PR.342. **Validate merge commit ancestry first**: `git merge-base --is-ancestor <merge_commit> HEAD`353. **If the merge commit is an ancestor of `HEAD`**, count commits after the merge:36 - `git rev-list --count <merge_commit>..HEAD`374. **If the merge commit is missing or not an ancestor of `HEAD`**, fallback to the branch upstream first:38 - `git rev-list --count origin/<head>..HEAD`395. **If the upstream comparison fails**, fallback to the base branch comparison:40 - `git rev-list --count origin/<base>..HEAD`416. **Decision**:42 - If the selected count is greater than 0 → create a new PR43 - If the selected count is 0 → report "No new changes since merge" and finish44 - If both fallback comparisons fail → stop and report `MANUAL CHECK`4546### Why this matters4748- **Scenario A**: PR merged → user makes local changes → pushes → changes are NOT in the merged PR49 - Without this check, the changes would be lost or require manual intervention50- **Scenario B**: PR merged → user says "create PR" without new changes → would create empty/duplicate PR51 - This check prevents unnecessary PR creation5253## PR title rules (must follow)54551. **Format**: `<type>(<scope>): <subject>` — follow Conventional Commits.562. **type**: must be one of `feat` / `fix` / `docs` / `chore` / `refactor` / `test` / `ci` / `perf`.573. **scope**: optional. Use a short scope that clearly identifies the affected area (for example: `gui`, `core`, `pty`).584. **subject**: keep it within 70 characters. Use the imperative mood (for example: "add ..." / "fix ..."). Do not capitalize the first letter or end with a period.595. If the branch name has a prefix such as `feat/` or `fix/`, **the title type must match that prefix**.6061## PR body rules (must follow)6263### Section classification6465| Section | Required | Notes |66|---------|----------|-------|67| Summary | **YES** | 1-3 bullet points. Include both the what and the why. |68| Changes | **YES** | Enumerate changes by file or module. |69| Testing | **YES** | List the commands run or the exact manual test steps. |70| Related Issues / Links | **YES** | Specify issue numbers, spec links, or "None". |71| Checklist | **YES** | Review every item and mark it checked or N/A. |72| Context | Conditional | Required when 3 or more files changed or the rationale is non-trivial. |73| Risk / Impact | Conditional | Required when the change is breaking, performance-sensitive, or needs rollback steps. |74| Screenshots | Conditional | Required only for UI changes. |75| Deployment | Optional | Include only when deployment steps exist. |76| Notes | Optional | Include only when reviewers need extra context. |7778### Validation (agent must check before creating PR)79801. **Do not create a PR if any required section still contains `TODO`.**812. If a conditional section does not apply, remove the entire section instead of leaving an empty TODO.823. Each Summary bullet must be a **single sentence**. Do not use vague wording such as "several changes" or "various fixes."834. Changes must be specific and include the changed file or module names.845. Testing must be reproducible. Do not use vague wording such as "tested."856. Add a reason comment to every unchecked checklist item (for example: `- [ ] Docs updated — N/A: no user-facing change`).867. Related Issues must be written as `#123` or as a URL. If nothing applies, explicitly write "None".8788## Issue/PR Comment Formatting (must follow)8990- Final comment text must not contain escaped newline literals such as `\n`.91- Use real line breaks in comment bodies. Do not rely on escaped sequences for formatting.92- Before posting, verify the final body does not accidentally include escaped control sequences (`\n`, `\t`).93- If a raw escape sequence must be shown for explanation, include it only inside a fenced code block and clarify it is intentional.9495## Issue Progress Comment Template (required for issue-based work)9697When work is tracked in GitHub Issues, progress updates must use this template:9899```markdown100Progress101- ...102103Done104- ...105106Next107- ...108```109110- Post updates at least when starting work, after meaningful progress, and when blocked/unblocked.111- In `Next`, explicitly state blockers or the immediate next action.112113## Workflow (recommended)1141151. **Confirm repo + branches**116 - Repo root: `git rev-parse --show-toplevel`117 - Current branch (head): `git rev-parse --abbrev-ref HEAD`118 - Base branch defaults to `develop` unless user specifies.1191202. **Check local working tree state (preflight)**121 - Run `git status --porcelain`.122 - If empty, continue.123 - If non-empty, show detected files and ask the user to choose:124 - Continue as-is125 - Abort126 - Manual cleanup first (`git commit` / `git stash` / `git clean`) and rerun127 - Proceed only when the user explicitly chooses continue.1281293. **Fetch latest remote state**130 - `git fetch origin` to ensure accurate comparison1311324. **Check branch sync against base (critical)**133 - Run `git rev-list --left-right --count "HEAD...origin/$base"`.134 - Parse the result as `ahead behind`.135 - If `behind > 0` and `ahead == 0` → stop and report `Branch update required before creating a PR.`136 - If `behind > 0` and `ahead > 0` → stop and report `Branch has diverged from base. Sync it before creating a PR.`137 - Continue only when `behind == 0`.1381395. **Check existing PR for head branch**140 - Use decision rules above to pick action.141 - Treat `mergedAt` as the source of truth for "merged".1421436. **If all PRs are merged, perform post-merge commit check**144 - Get merge commit: `gh pr list --head <head> --state merged --json mergeCommit -q '.[0].mergeCommit.oid'`145 - If the merge commit is an ancestor of `HEAD`, count `git rev-list --count <merge_commit>..HEAD`146 - If the merge commit is missing or not an ancestor, count `git rev-list --count origin/<head>..HEAD` first147 - Only if the upstream comparison fails, count `git rev-list --count origin/<base>..HEAD`148 - If the selected count is 0 → finish with message "No new changes since merge"149 - If the selected count is >0 → proceed to create new PR150 - If neither comparison is usable → stop with `MANUAL CHECK`1511527. **Ensure the head branch is pushed**153 - If no upstream: `git push -u origin <head>`154 - Otherwise: `git push`1551568. **Collect PR inputs (for new PR or explicit update)**157 - Title, Summary, Context, Changes, Testing, Risk/Impact, Deployment, Screenshots, Related Links, Notes158 - Optional: labels, reviewers, assignees, draft1591609. **Build PR body from template**161 - Read the template from the gwt-pr skill path (not the current project path):162 - `PR_BODY_TEMPLATE=".claude/skills/gwt-pr/references/pr-body-template.md"`163 - Read `${PR_BODY_TEMPLATE}` and fill all required placeholders.164 - **If a conditional section does not apply, remove the entire section.**165 - **Remove any `<!-- GUIDE: ... -->` comments from the final output.**166 - **If any required section still contains TODO, do not create the PR and ask the user for the missing information.**16716810. **Create or update the PR**169 - Create: `gh pr create -B <base> -H <head> --title "<title>" --body-file <file>`170 - Update (only if user asked): `gh pr edit <number> --title "<title>" --body-file <file>`17117211. **Return PR URL**173 - `gh pr view <number> --json url -q .url`17417512. **Post-PR CI/merge check (automatic).**176 - After PR creation or push, load `.claude/skills/gwt-fix-pr/SKILL.md` and follow its workflow to inspect CI status, merge state, and review feedback.177 - If all CI checks are still pending, poll (30s interval) until complete.178 - If conflicts, review issues, or CI failures are detected, proceed with the gwt-fix-pr workflow to diagnose and fix.179180## Command snippets (bash)181182```bash183head=$(git rev-parse --abbrev-ref HEAD)184base=develop185PR_BODY_TEMPLATE=".claude/skills/gwt-pr/references/pr-body-template.md"186187if [ ! -f "$PR_BODY_TEMPLATE" ]; then188 echo "PR template not found: $PR_BODY_TEMPLATE" >&2189 exit 1190fi191192# Preflight: local working tree state193status_lines=$(git status --porcelain)194if [ -n "$status_lines" ] && [ "${ALLOW_DIRTY_WORKTREE:-0}" != "1" ]; then195 echo "Detected local uncommitted/untracked changes:" >&2196 echo "$status_lines" >&2197 echo "Choose one before continuing: continue as-is, abort, or manual cleanup then rerun." >&2198 echo "Set ALLOW_DIRTY_WORKTREE=1 only after explicit user confirmation to continue." >&2199 exit 1200fi201202# Fetch latest remote state203git fetch origin204205# Check branch sync against base before PR creation206divergence=$(git rev-list --left-right --count "HEAD...origin/$base" 2>/dev/null) || {207 echo "Failed to compare HEAD with origin/$base" >&2208 exit 1209}210ahead_count=$(echo "$divergence" | awk '{print $1}')211behind_count=$(echo "$divergence" | awk '{print $2}')212213if [ "${behind_count:-0}" -gt 0 ] && [ "${ahead_count:-0}" -gt 0 ]; then214 echo "Branch has diverged from base. Sync it before creating a PR." >&2215 exit 1216fi217218if [ "${behind_count:-0}" -gt 0 ]; then219 echo "Branch update required before creating a PR." >&2220 exit 1221fi222223# Check existing PRs for the head branch224pr_json=$(gh pr list --head "$head" --state all --json number,state,mergedAt,mergeCommit)225pr_count=$(echo "$pr_json" | jq 'length')226unmerged_count=$(echo "$pr_json" | jq 'map(select(.mergedAt == null)) | length')227228if [ "$pr_count" -eq 0 ]; then229 action=create230elif [ "$unmerged_count" -gt 0 ]; then231 action=push_only232else233 # All PRs are merged - check for post-merge commits234 merge_commit=$(echo "$pr_json" | jq -r 'sort_by(.mergedAt) | last | .mergeCommit.oid')235 new_commits=""236237 if [ -n "$merge_commit" ] && [ "$merge_commit" != "null" ] && \238 git merge-base --is-ancestor "$merge_commit" HEAD 2>/dev/null; then239 new_commits=$(git rev-list --count "$merge_commit"..HEAD 2>/dev/null || echo "")240 fi241242 if [ -n "$new_commits" ]; then243 if [ "$new_commits" -gt 0 ]; then244 echo "Found $new_commits commit(s) after merge - creating new PR"245 action=create246 else247 echo "No new commits since merge - nothing to do"248 action=none249 fi250 else251 upstream_commits=$(git rev-list --count "origin/$head"..HEAD 2>/dev/null || echo "")252253 if [ -n "$upstream_commits" ]; then254 if [ "$upstream_commits" -gt 0 ]; then255 echo "Found $upstream_commits commit(s) ahead of origin/$head - creating new PR"256 action=create257 else258 echo "No new commits ahead of origin/$head - nothing to do"259 action=none260 fi261 else262 fallback_commits=$(git rev-list --count "origin/$base"..HEAD 2>/dev/null || echo "")263264 if [ -n "$fallback_commits" ]; then265 if [ "$fallback_commits" -gt 0 ]; then266 echo "Upstream comparison unavailable; found $fallback_commits commit(s) ahead of origin/$base - creating new PR"267 action=create268 else269 echo "Upstream comparison unavailable and no commits ahead of origin/$base - nothing to do"270 action=none271 fi272 else273 echo "Manual check required: could not determine whether new commits exist after the last merge" >&2274 action=manual_check275 fi276 fi277 fi278fi279280# Execute action281case "$action" in282 create)283 cp "$PR_BODY_TEMPLATE" /tmp/pr-body.md284285 git push -u origin "$head"286 gh pr create -B "$base" -H "$head" --title "..." --body-file /tmp/pr-body.md287 ;;288 push_only)289 echo "Existing unmerged PR found - pushing changes only"290 git push291 gh pr list --head "$head" --state open --json url -q '.[0].url'292 ;;293 none)294 echo "No action needed - no new changes since last merge"295 ;;296 manual_check)297 echo "Manual check required - post-merge commit status could not be determined" >&2298 exit 1299 ;;300esac301```302303## References304305- `.claude/skills/gwt-pr/references/pr-body-template.md`: PR body template