Skip to content
Development
Skill

/gh-stack

Native stacked pull requests through the github/gh-stack extension. Detects the extension, installs it only after the user approves, resolves the branch chain, and executes `gh stack link` / `gh stack push` / `gh stack submit --auto` under a per-use AskUserQuestion gate. Use

From plugin
sd0x-dev-flow
189100 skills16 agents5 hooks
Install
$ npx -y skills add sd0xdev/sd0x-dev-flow --skill gh-stack --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/gh-stack

Context preview

The summary Claude sees to decide when to auto-load this skill.

Native stacked pull requests through the github/gh-stack extension. Detects the extension, installs it only after the user approves, resolves the branch chain, and executes `gh stack link` / `gh stack push` / `gh stack submit --auto` under a per-use AskUserQuestion gate. Use

SKILL.md

gh-stack.SKILL.md
name: gh-stack
description: "Native stacked pull requests through the github/gh-stack extension. Detects the extension, installs it only after the user approves, resolves the branch chain, and executes `gh stack link` / `gh stack push` / `gh stack submit --auto` under a per-use AskUserQuestion gate. Use when: opening or refreshing a native stack of PRs, linking existing PRs into a stack on GitHub, pushing a stack's branches, or when /create-pr --stack delegates the native path here. Not for: a single PR (use /create-pr), pushing one branch (use /push-ci), merging a chain (use /epic-merge), or any history rewrite — `gh stack rebase` / `sync` / `modify` stay the user's to run. Output: stack table + per-command verdict + attribution verify."
allowed-tools: Bash(gh:*), Bash(git:*), Bash(bash:*), Bash(/bin/bash:*), Bash(mktemp:*), Bash(rm:*), Read, Write, Grep, Glob, AskUserQuestion

GH Stack — Native Stacked PRs

Wraps the `github/gh-stack` extension so a branch chain becomes a real **Stack** on GitHub — one PR per layer, chained bases, per-layer diff view, linked merges — instead of the hand-built chained-base PR set `/create-pr --stack` produces on its own.

Authorization

⚠️ This skill is one of the four workflows Anchor Register #4 enumerates (@rules/discretion.md).
⚠️ It may execute exactly three subcommands of the extension — `gh stack link`, `gh stack push`,
   `gh stack submit --auto` — and nothing else from it, `gh stack view` included: `view` syncs PR
   metadata and writes it back into `.git/gh-stack`, so it is not a read. What this skill needs to
   read, it reads without the extension (the first row of the table below).
⚠️ All three push, and they do not push the same way. Read from the extension's source at v0.1.1
   (§ Force form): `link` runs a plain `git push --atomic`; `push` and `submit --auto` run a
   per-branch, value-bearing `git push --force-with-lease=refs/heads/<b>:<sha>`. The approval
   names the form the chosen subcommand uses.
⚠️ Every `gh stack` invocation REQUIRES explicit per-use user approval via AskUserQuestion
   — no flag, no earlier approval and no delegating skill substitutes for it.
⚠️ Every other subcommand is printed for the user to run, never executed.

| Operation | Executor | Authorization | |-----------|----------|---------------| | `gh --version`, `gh auth status` (exit status only), `gh extension list`, `gh pr list --json`, `gh pr view --json`, `gh api 'repos/{owner}/{repo}/stacks?pull_request=<n>'` (GET), `git rev-parse`, `git merge-base`, and the extension's tracking file `<git-dir>/gh-stack` read with the Read tool | this skill | read-only | | `gh extension install github/gh-stack` | this skill | Phase 1 AskUserQuestion — **never** installed silently | | `gh stack link`, `gh stack push`, `gh stack submit --auto` | this skill | Phase 3 per-use AskUserQuestion naming the push form and the branches | | `gh stack view`, `gh stack rebase`, `gh stack sync`, `gh stack modify`, `gh stack merge`, `gh stack unstack`, `gh stack init`, `gh stack add`, `gh stack checkout` | **user only** — printed, never run | outside the grant | | `gh pr edit` for an attribution remediation | this skill | `/create-pr` § 7b contract (CLAUDE.md rule 3, Anchor) | | `git push` by any other route | `/push-ci` | its own workflow |

**Why that split, rather than "whatever the extension offers".** The three granted subcommands move **remote refs and PR state**; the ungranted ones rewrite **local history** (`rebase`, `sync`, `modify`), merge PRs (`merge`), or need a TUI no agent can drive (`modify`, `checkout` without an argument, and `submit` without `--auto`). `sync` is the one that reads like a convenience and is not: it fetches, cascade-rebases, force-pushes and prunes in one call, so approving "a sync" approves a history rewrite nobody has seen. It stays the user's. `view` is the one that reads like a query and is not: both its `--json` and its default form sync PR metadata from GitHub and then call `SaveNonBlocking`, which rewrites `.git/gh-stack` (`cmd/view.go`, v0.1.1). A read that persists state is a mutation of the extension's own bookkeeping, and nothing in this skill needs it — the file can be read directly, and the remote Stack has a REST endpoint of its own.

**`gh stack submit` is never run without `--auto`.** Interactively it opens a full-screen editor; an agent invoking it hangs the session holding an approved force push. Readiness is the same for **both** publishing forms — `gh stack submit --auto` and `gh stack link` alike create new PRs as **drafts** unless `--open` is passed, and `--open` is carried into the Phase 3 approval — a caller may propose it, this skill does not execute it unless that approval affirms readiness.

Push safety — the obligation this skill carries itself

Every granted subcommand pushes, two of them with force, and the `pre-push` hook is **opt-in** (@rules/git-workflow.md § Push safety). So:

| Obligation | How this skill meets it | |------------|-------------------------| | The **unshared attestation** — *is anybody else working on the branches this push rewrites* | For `gh stack push` and `gh stack submit --auto`, Phase 3 asks it **by name and before the force approval**, listing the branches, and refuses the invocation when the answer is not the attestation. An installed hook may ask again over `/dev/tty`; that is defence in depth, never a reason to skip the question, because where the hook is absent nothing else asks. `gh stack link` rewrites nothing: its push carries no force, so a branch that diverged on the remote is refused by git itself and the run stops there (§ Force form) | | `ALLOW_PUSH_PROTECTED` and `ALLOW_FORCE_UNSHARED` are developer-set only | Never set by this skill, and **cleared on every invocation it executes** — a value exported earlier in the shell answers the hook's question without anybody being asked now | | `ALLOW_FORCE_WITH_LEASE` | Set **only** on the single approved `gh stack push`

Read more
Ships withsd0x-dev-flow

Language: English | 繁體中文 | 简体中文 | 日本語 | 한국어 | Español The harness layer for Claude Code. Let the model choose the path. Keep "done" verifiable. Full control plane on Claude Code. Skills-only distribution for Codex CLI and other compatible agents.

Get the whole plugin

Other skills on sd0x-dev-flow.