pr-craft
pr-craft
Drive a clean PR end to end: branch, stage only the relevant files, conventional-commit, push, open the PR with a structured body. Default to one focused PR; for a large change that splits into ordered dependent layers, open a stack instead (see Stacked PRs).
Flow
-
Inspect.
git status+git diff(andgit diff --staged). Identify which changed files belong to this task. Pre-existing modified/untracked files unrelated to the work (lockfiles, config, scratch dirs) are NOT yours — leave them. -
Size the change. Measure what the PR will actually ask someone to read, before committing, so a split is still cheap:
BASE=$(git symbolic-ref --short refs/remotes/origin/HEAD 2>/dev/null | sed 's|origin/||') git diff --numstat "${BASE}...HEAD" -- . \ ':(exclude)*.lock' ':(exclude)*lock.json' ':(exclude)*.lockb' \ ':(exclude)dist/**' ':(exclude)build/**' ':(exclude)vendor/**' \ ':(exclude)**/*.min.*' ':(exclude)**/*.snap' ':(exclude)**/*.generated.*' \ | awk '{a+=$1; d+=$2; f++} END{printf "%d files, +%d -%d (%d lines)\n", f, a, d, a+d}'Work not committed yet? Same pipe over
git diff --numstat HEAD, but first mark this task's new files withgit add -N <file> …(intent-to-add, named individually like step 4, never-A).git diffdoes not see untracked files, so without it a feature made of brand-new files measures as zero lines and sails past the gate. The exclusions are deliberate: a regenerated lockfile or adist/rebuild is not review surface, and counting it splits PRs that never needed splitting.