github-workflows/skills/refresh-repo/SKILL.md
Check PR merge readiness, sync local repo, cleanup stale worktrees; optional cross-repo sweep and stale-branch prune modes
npx skillsauth add jacobpevans/claude-code-plugins refresh-repoInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Check open PR merge-readiness status, sync the local repository, and cleanup stale worktrees. Note: Does not automatically merge PRs - only reports readiness status for each PR.
State warning: Branch state, remote tracking, and PR status change between invocations. Re-run all git/gh commands from Step 1.
CRITICAL: Always check for open PRs, regardless of current branch.
# Check for PR from current branch
gh pr view --json state,number,title 2>/dev/null
# ALWAYS also check for any open PRs by the user
gh pr list --author @me --state open --json number,title,headRefName
For each open PR, DO NOT MERGE - only check and report.
Run the canonical PR-readiness gate from /gh-cli-patterns.
Replace <OWNER>, <REPO>, <PR_NUMBER> per the placeholder legend in that skill.
Merge-ready criteria — all of the following must hold:
| Field | Required | Status |
|---|---|---|
| state | OPEN | Not ready |
| mergeable | MERGEABLE | Not ready |
| mergeStateStatus | CLEAN or HAS_HOOKS | Not ready (BEHIND, BLOCKED, DIRTY, UNSTABLE, UNKNOWN, DRAFT) |
| isDraft | false | Not ready |
| reviewDecision | APPROVED or null | Not ready |
| statusCheckRollup.state | SUCCESS | Not ready |
| All reviewThreads.isResolved | true | Not ready — unresolved threads |
| reviewThreads.pageInfo.hasNextPage | false | Not ready — >100 threads, paginate |
git fetch origin --no-tags --prune --forceorigin/HEAD, falling back to main or master.<repo>/main/ (or <repo>/master/) must always
be checked out to the default branch. After a feature PR merges, that
worktree is often left on the now-[gone] feature branch. Detect and fix:
git worktree list --porcelain,
matching on the branch refs/heads/<default> entry — do not rely on
basename matching of paths, since a feature branch named
feature/<default> would also produce a path basename of <default>.git -C <path> rev-parse --abbrev-ref HEAD does not equal
<default> (this is safer than symbolic-ref --short HEAD, which errors on
detached HEAD during a rebase or commit-checkout):
git -C <path> status --porcelain is non-empty), stash them first with
git -C <path> stash push -u -m "refresh-repo: auto-stash before <default> restore"
and surface the stash reference in the summary so the user can recover.git -C <path> checkout <default>.--force, never discard uncommitted work, never reset.git -C <path> so the merge always targets the default worktree regardless
of the current shell directory:
git -C <path> merge --ff-only origin/<default>.
If the default worktree is dirty or divergent, report it and skip instead of resetting.git branch -d.
Never delete main/master/develop/current branches, worktree-checked-out branches, or branches
with open PRs.git -C <path> to operate on the default worktree directly, the current shell's
working directory and branch were never changed — each worktree owns its checkout.Do not use git fetch --tags, git fetch --prune-tags, or git pull --tags during the
normal refresh. Tags are audited separately in Step 4 so local-only non-release tags and
tag rewrites are not deleted by a broad fetch refspec.
Treat origin as authoritative for release tags only.
Use native Git commands to compare local tags to remote tags:
git for-each-ref '--format=%(refname:short)' refs/tags
git show-ref --tags
git ls-remote --tags --refs origin
For local-only tags:
v[0-9]*, delete it with
git tag -d <tag>.For tags that exist both locally and on origin but point at different objects, report the mismatch and do not force-update it automatically. Never delete or rewrite remote tags.
Only remove a worktree if it is confirmed stale.
Stale definition: No open PR, no uncommitted changes, and either:
mergedAt) whose headRefOid matches the local branch HEAD
(gh pr list --state merged --head <branch> --json number,headRefOid,mergedAt)[gone] in git branch -vv) and it has no commits
ahead of the default branch (git log origin/<default>..HEAD --oneline is empty)Branches with open PRs, local-only branches without PRs, and worktrees with uncommitted changes are NEVER stale.
For each worktree from git worktree list:
git worktree remove <path> — NEVER use --forcegit branch -d <branch>.
If this fails only because a squash-merged branch is not reachable from local default,
use git branch -D <branch> only when the merged PR headRefOid matched the local
branch HEAD before removing the worktree.Finish with git worktree prune.
Report: PRs assessed as merge-ready (if any), tags deleted or reported, branches cleaned up, worktrees removed, default-branch worktree restorations (with any stash references created), current branch, and sync status.
Optional modes that change /refresh-repo from single-repo to workspace-wide.
Both modes reuse the stale-worktree definition from Step 5 and the deletion
rules from Step 5.7 — they only add new pre-filters, never weaken existing
safety.
--sweep [<repo-glob>]Multi-repo cleanup of abandoned local branches. For every main worktree
in your workspace (caller can pass a custom glob if their layout differs),
for every local branch where git log origin/main..HEAD is non-empty:
origin/main. If every touched file is content-equivalent
to (or older than) origin/main, delete the branch and its worktree.
Already-on-main contributions do not deserve a PR.grep -r <name> . returns
zero matches for, surface for human review. Do not open a draft.Origin: the 2026-05-22 sweep opened 8 dead PRs against ansible-splunk
(6 already-on-main duplicates, 2 workaround anti-patterns). Both filters
above would have caught all 8 before any CI ran.
--prune-stale <days> (default 60)Delete local branches with no open PR and no push activity within <days>.
Expands Step 5's stale definition with a time threshold; still respects every
safety rule (never delete branches with open PRs, uncommitted changes, or
the current checkout).
Per branch: if gh pr list --head <branch> is empty AND
git log -1 --format=%cr <branch> is older than <days>, run
git worktree remove <path> (per Step 5 — never --force) then
git branch -d <branch>.
Use --prune-stale 30 for an aggressive sweep, --prune-stale 90 for
conservative.
DO NOT skip the PR check just because you're on main. The user may have multiple open PRs from different branches.
Always run gh pr list --author @me --state open to find work that needs merging.
Do not use --prune-tags as a shortcut for tag cleanup. Git treats tag pruning as an
explicit refspec prune and can delete local-only tags that are not release artifacts.
documentation
Use when editing GitHub Actions workflow files (.github/workflows/*.yml) in JacobPEvans repos. Documents when to target self-hosted RunsOn runners vs GitHub-hosted runners, the v3 label catalog used across the org, the required github.run_id segment, and the GitHub App allowlist prereq.
tools
Local rebase-merge workflow for pull requests with signed commits
tools
Canonical reference for all gh CLI command shapes used by skills in this plugin. Defines the placeholder convention, allowed --json fields, GraphQL fallback rules, -f/-F/--raw-field flag semantics, the PR-readiness gate, code-scanning alert query, review-thread fetch/count/resolve mutations, and heredoc bodies. Prevents Unknown JSON field errors and divergent query shapes.
tools
Analyze current Claude Code session token usage via Splunk. Shows per-model, per-tool, and subagent token breakdown with cache efficiency metrics.