PR Anywhere
Make a change to any GitHub repository and open a pull request, from any terminal.
Always works in the ghq-managed clone so behaviour is identical everywhere and never
disturbs whatever checkout you happen to be sitting in.
Steps (follow strictly)
1. Parse the arguments
The first token of
is the target repository when it looks like
(or a full GitHub URL). Everything after it is the change to make.
- No first token: ask the user which repository to change. Do not guess
from the current directory — this skill is meant to be run from anywhere, so the
current checkout says nothing about the intended target.
- Repository given but no change described: ask what to change.
2. Preflight: gh auth and ghq
If
fails, STOP and tell the user to run
, then wait.
bash
command -v ghq || mise use -g ghq@latest
If
fails to resolve, fall back to
mise use -g ubi:x-motemen/ghq
.
3. Resolve the repository's facts
Never assume the default branch is
, and never assume you can push to it.
bash
gh repo view <owner/repo> --json defaultBranchRef,viewerPermission
- — the base branch for the PR.
- — , , or means you can push a branch
directly to origin. , , or means you must fork (step 7).
If the command fails, the repo does not exist or is not visible to this account.
Report that and stop.
4. Get (clone or update) the repository
bash
ghq get -u github.com/<owner>/<repo>
repo="$(ghq list --full-path --exact github.com/<owner>/<repo>)"
cd "$repo"
5. Sync the base branch and create a working branch
Always branch off the fresh default branch — never edit it directly, never push to it.
bash
git switch <default-branch>
git pull --ff-only
git switch -c "<type>/<slug>"
- : / / / / (match the change)
- : short kebab-case summary, e.g. ,
If the branch already exists from a prior run, pick a new slug (append
, etc.).
6. Learn the repo's conventions, then apply the edit
Before editing, read whatever the repository says about itself —
,
,
,
.github/PULL_REQUEST_TEMPLATE.md
— and check
for the commit message style actually in use. Follow them
over any habit of your own.
Make the requested change with the normal edit tools. Keep it focused — one logical
change per PR.
Run whatever check the repo defines (lint, test, typecheck) if one is obvious from
its config or CI workflow. Report failures rather than working around them.
7. Push
With write access (step 3 said
/
/
):
bash
git push -u origin "<branch>"
Without write access — fork first, and push the branch to the fork:
bash
gh repo fork --remote --remote-name fork
git push -u fork "<branch>"
8. Open the PR
bash
gh pr create --base <default-branch> --title "<type>: <summary>" --body "<why>"
Add
when pushing from a fork, so the PR lands on the upstream
repository rather than the fork.
Write the body yourself — state what changed and why. Use
only when the
commit message already says everything the reviewer needs.
9. Report
Output the PR URL returned by
.
Gotchas
- Never touch the current checkout: even when invoked from inside a checkout of
the target repo, work in the ghq clone. This keeps behaviour identical on every
terminal and avoids disturbing uncommitted work.
- The default branch is not always : resolve it in step 3. Hardcoding
fails on repos and on any repo using a release branch as default.
- gh not authenticated: step 8 fails cryptically. Verify with in
step 2 first.
- is checked by exit code: only installs when
truly missing.
- : fails loudly if the local clone diverged from origin (e.g.
leftover commits on the default branch). If it fails,
git reset --hard origin/<default-branch>
after confirming there is nothing to keep.
- Branch already exists: fails. Reuse it ()
only if it is yours and clean, otherwise choose a new slug.
- A stale ghq clone of a fork: if lands on a clone whose is
your fork rather than upstream, still describes upstream while
goes to the fork. Check when the PR base looks
wrong.