speckit-git-pr
Open a GitHub PR for the current feature branch, auto-appending Closes #N from .specify/feature.json when source_issue is set; --draft opens it as a draft and leaves the issue open
Files1
View on GitHubSKILL.md.specify/extensions/git/.specify-dev/agent-commands/claude/speckit-git-pr/SKILL.md
GitHubCreate PR for Current Feature
Open a GitHub pull request from the current feature branch into main (or another base passed as an argument). If .specify/feature.json carries a source_issue field — written by /speckit-git-feature when it created or was bound to a GitHub issue — the PR body will include a Closes #N line so merging the PR automatically closes that issue. That is the file's only field; every other part of the feature's identity is derived from git at read time (issue #33).
Designed to be invoked as the after_implement hook (alongside the existing auto-commit hook), or directly via /speckit-git-pr.
Arguments
/speckit-git-pr [base_branch] [--draft]
base_branch— defaults tomain.--draft— draft handoff mode: open the PR as a draft and skip the/speckit-archive-featurepre-step. Use this whenever a human still has to review before the work is considered delivered — notably every/speckit-autopilot-run.
Pre-Execution (Mandatory)
Before any PR checks or gh pr create execution, run these commands in order:
/speckit-archive-feature— skipped when--draftis passed. Archiving closes the tracking issue and moves the spec out of the active tree; in draft mode the issue must stay open and the spec must stay in place until a human merges the PR (issue #28). Archive after the merge instead./speckit-git-commit— always runs, draft or not.
If a command that is supposed to run is unavailable or fails, stop and return an error. Do not continue to PR creation.
Behavior
- Run mandatory pre-execution commands:
/speckit-archive-feature(skipped in--draftmode)/speckit-git-commit
- Verify
ghis installed and the cwd is a git repo on a non-default branch. - Resolve the feature:
- The feature directory is derived from the current branch (
specs/<branch>, honouringSPECIFY_FEATURE_DIRECTORY/SPECIFY_FEATURE) → used to derive the PR title from the spec's H1 and to mention spec/plan/tasks paths in the PR body. source_issueis read from.specify/feature.json, its only field → if present and numeric, appendCloses #Nto the PR body.
- The feature directory is derived from the current branch (
- If
squash_before_pr: trueingit-config.yml, squash every commit betweenmerge-base(HEAD, <base>)andHEADinto a single commit (title from the spec H1, body listing the original commit subjects). Aborts if the working tree has uncommitted changes. - If the branch isn't yet on
origin, push it (git push -u origin <branch>). If it was already pushed and a squash happened, force-push with--force-with-lease. - If a PR already exists for the branch, print its URL and exit. In
--draftmode, if that existing PR is not a draft, also print a warning naminggh pr ready <url> --undo— the script does not mutate a PR it did not create. - Otherwise, run
gh pr create --base <base> --head <branch> --title <derived> --body <derived>, adding--draftin draft mode. The draft flag is passed togh pr createdirectly — never create a mergeable PR and convert it afterwards withgh pr ready --undo.
Execution
Run the script:
- Bash:
.specify/extensions/git/scripts/bash/create-pr.sh [base_branch] [--draft]
Default base_branch is main. Pass an alternative as the first argument if needed.
--draft may appear in either position. The script owns the draft flag on
gh pr create; skipping /speckit-archive-feature is this command's half of the
contract, since the script never invokes that command itself.
Graceful Degradation
- If
/speckit-archive-feature(non-draft mode only) or/speckit-git-commitis unavailable or fails: error and stop before PR creation. - If an unknown option or a second positional argument is passed: error with the usage line and stop.
- In
--draftmode with a pre-existing non-draft PR: warn with thegh pr ready --undohint and exit successfully; the existing PR is left untouched. - If
ghis missing: error with install hint. - If the current branch equals the base branch: refuse.
- If no
source_issueis recorded: PR is created without a closing keyword (still works, just doesn't auto-close an issue). - If a PR already exists for this branch: prints the existing URL, does not duplicate.
- If
squash_before_pr: truebut the merge-base with<base>cannot be computed, or the working tree has uncommitted changes: error and stop before pushing.