From d4b84976302df5adcfd94e1a901f00add60d5048 Mon Sep 17 00:00:00 2001 From: Juan Denis Date: Sun, 25 Oct 2026 23:18:24 -0400 Subject: [PATCH] Keep the PR title out of the create-pr body file Agents opened PRs with --body-file on a file that began with the title heading, so every PR description repeated its title. The title now goes to its own .title.txt and the body file starts at the summary. --- .claude/skills/create-pr/SKILL.md | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/.claude/skills/create-pr/SKILL.md b/.claude/skills/create-pr/SKILL.md index 7840454d..99051c68 100644 --- a/.claude/skills/create-pr/SKILL.md +++ b/.claude/skills/create-pr/SKILL.md @@ -28,15 +28,20 @@ If the full diff is too large, diff individual areas (backend routes, frontend, ### 2. Write the PR file -Write the file to `.pr/YYYY-MM-DD.md` (using today's date). Create the `.pr/` directory if it doesn't exist. If a file for today's date already exists, append a counter: `YYYY-MM-DD-2.md`, `YYYY-MM-DD-3.md`, etc. +Write **two** files under `.pr/` (create the directory if it doesn't exist), sharing one base name from today's date: + +- `.pr/YYYY-MM-DD.title.txt` — the PR title, one line, nothing else. +- `.pr/YYYY-MM-DD.md` — the PR **body only**. It starts directly with the summary paragraph. + +If files for today's date already exist, append a counter to the base name: `YYYY-MM-DD-2`, `YYYY-MM-DD-3`, etc. + +**The body file must never contain the title.** No `# ` heading, no `Title:` line, no frontmatter, no "PR description:" preamble. GitHub already renders the title above the body, so anything title-like in the body file shows up twice — whoever opens the PR (you, another agent, or the user copy-pasting) pastes the body file verbatim and should not have to edit it. The structure depends on whether the PR introduces user-facing features or is purely internal (refactors, bug fixes, infra). #### When the PR has user-facing features: ~~~markdown -# <Title> - <4-6 sentence summary> ### Highlights @@ -58,8 +63,6 @@ The structure depends on whether the PR introduces user-facing features or is pu #### When the PR is purely internal (no user-facing features): ~~~markdown -# <Title> - <4-6 sentence summary> <details> @@ -82,7 +85,7 @@ Omit the Highlights section entirely for internal-only PRs — don't force it. - Bad: `feat(dns): add cloudflare provisioning` · `fix: subprocess injection` · `chore(deps): bump` - Capitalize the first word like a sentence; imperative or plain-descriptive are both fine; no trailing period. Keep it under ~70 chars. - Leading with the subsystem and a colon in plain words is fine when it aids scanning: `Backend: …`, `Extensions: …`. -- The `# <Title>` line at the top of the generated file **is** the PR title — when the PR is eventually opened, that same string is the `gh pr create --title` value. Don't write a second, different headline. +- The title lives **only** in the `.title.txt` file — that string is the `gh pr create --title` value. Don't repeat it, or a variant of it, as a headline in the body file. - **Where the release weight actually lives (so you can safely keep it out of the title):** `version-bump.yml` reads the *commit message* pushed to `dev` (`github.event.head_commit.message`), **not this title.** A `feat:`/`feature:`/`minor:` prefix or a `[minor]` tag in the commit → minor bump; `BREAKING:`/`major:` or `[major]` → major; anything else → patch. Put any bump intent in your **commits**; leave the PR title human. #### Summary @@ -123,6 +126,16 @@ Omit the Highlights section entirely for internal-only PRs — don't force it. - **No emoji.** - **No "Generated by" footer.** -### 3. Stop after writing the file +### 3. Stop after writing the files -This skill's job ends when the `.pr/` file is written. **Do not** run `gh pr create`, `git push`, or any other remote-affecting command to actually open the PR — that's a separate, explicit step the user requests on its own. Print the path of the file you wrote and a one-line note that it's ready to review/copy. +This skill's job ends when the `.pr/` files are written. **Do not** run `gh pr create`, `git push`, or any other remote-affecting command to actually open the PR — that's a separate, explicit step the user requests on its own. Print the title, the paths of both files, and a one-line note that they're ready to review/copy. + +### 4. Opening the PR (only when the user explicitly asks) + +Pass the two files separately — never derive the body from a file that has a heading in it: + +```bash +gh pr create --base main --head dev --title "$(cat .pr/YYYY-MM-DD.title.txt)" --body-file .pr/YYYY-MM-DD.md +``` + +Before running it, check the first line of the body file: if it is a `#` heading or repeats the title, delete that line first. After creating, run `gh pr view --json title,body -q .body | head -3` and confirm the body does not start with the title.