skills/stacked-prs/SKILL.md
--- name: stacked-prs description: Rebase a stacked feature branch after its parent PR has been squash-merged. Use when you have a branch B that was built on top of branch A, and A just landed on main (squash-merged). Runs git fetch + git rebase onto main + git push --force-with-lease, so B's diff no longer includes A's flattened commits. category: development argument-hint: [--onto <branch>] [--no-push] [--dry-run] allowed-tools: Bash(git *) --- # Stacked PRs: rebase-after-parent-merges One c
npx skillsauth add RonanCodes/ronan-skills skills/stacked-prsInstall 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.
One command for the recurring pain point of stacked PRs under a squash-merge + linear-history repo. When PR A squash-merges, the original commits get replaced by one new commit with a different SHA. Any branch B that was built on A still carries A's old commits in its history, which pollutes B's diff until B is rebased onto the new main.
This skill automates the fix.
/ro:stacked-prs # rebase current branch onto origin/main, force-push with lease
/ro:stacked-prs --onto develop # rebase onto a branch other than main
/ro:stacked-prs --no-push # rebase locally, stop before pushing
/ro:stacked-prs --dry-run # show what would happen, don't touch anything
/ro:new-tanstack-app's branch protection).git log main..B now shows "A's commits" + "B's commits", and B's GitHub PR diff is wider than it should be.git status will tell you).git pull --rebase is enough; this skill still works but is overkill.Branch protection only applies to main. Feature branches are explicitly allowed to be force-pushed: rebasing IS how you update a stacked PR under the squash model. --force-with-lease guards against the edge case where someone else pushed to your branch since you last fetched.
main / master. If it is, bail with "you're on the base branch, nothing to rebase."git status --porcelain empty). If not, bail with "commit or stash first."origin remote exists.BRANCH=$(git rev-parse --abbrev-ref HEAD)
BASE=${ONTO:-main}
[ "$BRANCH" = "$BASE" ] && { echo "on $BASE, nothing to rebase"; exit 1; }
[ -n "$(git status --porcelain)" ] && { echo "working tree dirty; commit or stash"; exit 1; }
git rev-parse --abbrev-ref "$BRANCH@{u}" >/dev/null 2>&1 || { echo "no upstream; git push -u first"; exit 1; }
git fetch origin
Show the commits that will be replayed + where the base moved to. This is the whole output in --dry-run mode.
echo "Will rebase $BRANCH onto origin/$BASE"
echo "Commits to replay (in order):"
git log --oneline "origin/$BASE..HEAD"
echo "---"
echo "New base: $(git log -1 --oneline origin/$BASE)"
If --dry-run, exit here.
git rebase "origin/$BASE"
If conflicts fire, abort cleanly and tell the user:
if [ $? -ne 0 ]; then
echo "Rebase hit conflicts. Resolve, then run: git add <files> && git rebase --continue"
echo "To abort entirely: git rebase --abort"
exit 2
fi
--no-push)git push --force-with-lease
--force-with-lease refuses the push if the remote has commits you haven't seen, catching the rare case where someone else pushed to your branch.
echo "✅ $BRANCH rebased onto origin/$BASE and pushed"
git log --oneline "origin/$BASE..HEAD"
/ro:gh-ship: opens the PR, watches checks, confirms merge. Run this once B is rebased./ro:new-tanstack-app: the scaffold that installs branch protection + squash-only merges. This skill exists because of the constraints that scaffold sets up.connections-helper/docs/adr/0002-github-branch-protection-squash-only-merges.md (the reasoning behind squash-only + the stacked-PR section).github-repo-hygiene in llm-wiki-research.testing
--- name: linear-pipeline description: The Fable orchestrator for a single dispatched Linear ticket. Holds almost no context itself; it receives `--issue <ID> --detached`, decides the stage sequence, and fans out a sub-agent per stage, passing forward only each stage's artifact (never re-derived, never inlined into its own context). Step zero, before any planning or stage routing, is a boundary triage against `canon/security-boundary.md` (#199): a match tags Ronan Connolly and stops the run, no
development
--- name: in-your-face description: Capture a chat-only answer into a durable artifact (markdown + HTML, PDF when cheap) and launch it automatically so the user cannot miss it. Use when user says "in your face", "don't let me lose this", "save that answer", "make that durable", or right after answering a substantive side question (a recipe, comparison, how-to, or generated prompt) that would otherwise die with the context. category: workflow argument-hint: [--no-open] [--vault <short>] [hint of
tools
One-shot headless OpenAI Codex CLI calls for background/admin AI tasks — summaries, classification, extraction, admin glue. The default engine for anything that runs AI constantly in the background (daemon-driven, per-event), because it bills the flat ChatGPT subscription instead of Claude usage or per-token API spend, and it keeps working while Claude is rate-limited. NEVER for coding — coding stays Claude. Use when a skill or daemon needs a cheap always-on AI call, when the user says "use codex", "ask codex", "codex as backup", or when building a background summarizer/classifier into a listener or loop. Reads auth from ~/.codex/auth.json (ChatGPT account, no API key).
research
Turn a warranty rejection, repair quote, or RMA email into a cited decision brief — legal read (NL/EU consumer law), is the part user-serviceable, live part and new-unit prices, repair-vs-DIY-vs-new economics, before-you-send-it checklist, deadlines. Use when the user pastes or screenshots a repair quote, warranty rejection, "not covered" email, onderzoekskosten fee, or asks "should I repair or replace this".