Create GitHub issues from a PR's work, and update the PR
Takes work that's already happened on a branch (or that the user is
about to describe) and turns it into GitHub issues — one flat issue for
a single atomic change, or a parent epic plus child issues when the work
genuinely splits into distinct pieces — then rewrites the pull request's
title and description so the description carries an itemized, correctly
nested list of every issue it's tracked by.
The two halves of this (creating issues, updating the PR) are meant to
happen together: an issue list in a PR description is only useful if the
numbers in it are real and current, and issues filed for a PR are only
useful if the PR actually points back at them.
Workflow
Establish what work you're filing issues for. If a PR number is
given or obvious from context (the current branch's open PR), read it
— pull_request_read method get for its title/body/branches, and
either get_commits or a local git log/git diff against the base
branch for what actually changed. Ground every issue in real,
verifiable work: a commit, a diff, a file. If the user is describing
work that isn't reflected in commits yet, that's fine to file too, but
say so explicitly rather than presenting it as already-done. If
there's no PR yet and no clear scope, ask rather than guessing at what
to track.
Decide the shape: one issue, or a parent epic with children?
- A single, atomic, well-scoped change — one commit's worth, one
coherent piece of work — gets one issue. Don't manufacture an
epic-of-one just to have a hierarchy.
- Multiple genuinely distinct pieces of work serving one umbrella goal
(typically: several commits, each a self-contained step) get a
parent epic issue plus one child per piece, linked through
GitHub's actual parent/child issue relationship — not just shared
labels or a checklist with no real links behind it.
- A reliable way to find the right split: look at the commit history
for the branch/PR. One child issue per tightly-scoped commit (or
small cluster of commits that are really one step) tends to produce
issues that are each individually closeable and meaningful — check
this shape before inventing your own grouping from scratch.
- "Group where applicable" cuts both ways: don't force unrelated work
under one parent, and don't flatten obviously related, multi-step
work into a flat pile of ungrouped issues either.
Check issue-type support before creating anything. Call
list_issue_types for the owner/repo. If the repository defines
types (commonly something like Feature/Bug/Task), pick the closest
fit for each issue you create and pass it. If the repository has no
issue types configured, omit the type field entirely rather than
guessing at a value that doesn't exist there.
Search before creating, to avoid duplicates. Use search_issues
(or list_issues for a small repo) for anything already covering the
same work — a stale or half-finished issue from earlier is worth
linking to and updating rather than duplicating. Only skip this check
if the user has made clear these are definitely new.
Create the issues, parent first.
- Parent (if any):
issue_write method create, with a body
naming the PR it's tracked in and a short description of the
overall goal. A plain-text checklist of the sub-pieces is fine here
even before the children exist — you can go back and turn it into
real #-linked bullets once the children have numbers, but that's
a nice-to-have, not required.
- Children:
issue_write method create with parent_issue_number
set to the parent's number — this attaches the child to the parent
in the same call; no separate linking step needed. (sub_issue_write
is for re-parenting an issue that already exists — you don't need it
for issues you're creating fresh in this workflow.)
- Give each issue a real, specific body: what changed, which files or
areas, and why — pulled from the actual commit message or diff for
that piece of work, not written generically from the title alone.
- Create children in the same order the corresponding commits landed,
so the issue numbers read in a sensible sequence.
Update the PR — title and body, in one call.
Title: short. When a parent epic exists, matching its title
verbatim keeps the PR and its tracking issue recognizable as the
same piece of work at a glance — an epic title that was itself kept
short is usually reusable as-is. Otherwise, write a short, accurate
title for the single issue's scope. Aim well under 70 characters.
Body: add (or rewrite) an ## Issues section listing every
issue created, one per line, in exactly this format:
- Closes #{{issue-number}} -- {{issue-title}}
The Closes keyword is deliberate, on every line including a
parent epic's — GitHub auto-closes any issue referenced this way
when the PR merges into the repo's default branch, so the list
doubles as the mechanism that closes the issues, not just a
description of them.
Indent each level of child under its parent by two spaces — GitHub
renders two-space-indented bullets as a nested list. A flat set of
issues with no parent is just one un-indented list. Keep whatever
other sections belong in this PR's description (Summary, Key
changes, Test plan, whatever the repo's own convention is) — the
Issues section is additive. The one exception: if the existing
description is generic boilerplate that no longer reflects the PR's
actual current state (common after several rounds of commits since
it was first written), rewriting the whole body to match reality is
the right call — just say that's what you're doing rather than
silently overwriting something that looked deliberate.
Use update_pull_request with both title and body set in the
same call.
Verify — don't trust the write call's echo. After creating the
issues and updating the PR, read them back: pull_request_read
method get on the PR to confirm the title and body actually saved
as given (GitHub's write endpoints occasionally normalize or truncate
content silently), and spot-check the created issues if there's any
doubt about the parent/child structure actually taking. Only report
the work as done once you've confirmed it from a fresh read, not from
memory of what you sent.
Format reference
With a parent epic:
## Issues
- Closes #50 -- Add Stata skill (stata-recipes)
- Closes #51 -- Create the initial stata-recipes skill
- Closes #52 -- Expand stata-recipes: time-series/panel regression, unit-root tests
- Closes #53 -- Restructure stata-recipes recipes into models/ and tests/ subfolders
Flat, no parent:
## Issues
- Closes #61 -- Fix broken link in README
Two levels of nesting (a parent whose children each have their own
children) follows the same two-spaces-per-level rule:
## Issues
- Closes #70 -- Rewrite the onboarding flow
- Closes #71 -- New signup form
- Closes #72 -- Add email verification step
- Closes #73 -- New welcome email
What this doesn't do
- Doesn't invent work that wasn't done or described — every issue traces
back to a commit, a diff, or something the user explicitly asked to
track.
- Doesn't create labels, milestones, or projects — only issues (with a
type, when the repository supports one) and the PR's own title and
body.
- Doesn't merge, approve, request review, or otherwise touch the PR's
review state — title and description only.
- Doesn't assume any one environment's house rules for GitHub posts
(e.g. an attribution footer convention) apply everywhere — an issue
body or PR description is content the workflow above writes, not a
comment; follow whatever posting conventions the current
environment or repository actually specifies for those, rather than
a rule baked into this skill.
Development
See meta/MAINTAINERS.md for layout and versioning notes. Not read as
part of carrying out a live "file issues for this PR" request — don't
act on it while answering one.
1---2name: create-issues-update-pr3description: Files GitHub issue(s) for work already done (or about to be done) on a branch/PR, grouping related issues under a parent epic when there's a genuine hierarchy — using GitHub's native parent/child issue relationship, not just labels — and then updates that pull request's title (kept short) and description so the description lists every issue in the exact format '- Closes #{{issue-number}} -- {{issue-title}}', indented to match parent-child nesting. Use this whenever the user asks to file issue(s) for a PR, 'add gh issues for this', 'track this as issues', link a PR to tracking issues, or update a PR's title/description to list the issues covering its changes — including when they invoke /create-issues-update-pr directly. Also trigger when a PR description is stale or generic relative to its actual current commits and the user wants it brought up to date alongside issue creation.4license: MIT5---67# Create GitHub issues from a PR's work, and update the PR89Takes work that's already happened on a branch (or that the user is10about to describe) and turns it into GitHub issues — one flat issue for11a single atomic change, or a parent epic plus child issues when the work12genuinely splits into distinct pieces — then rewrites the pull request's13title and description so the description carries an itemized, correctly14nested list of every issue it's tracked by.1516The two halves of this (creating issues, updating the PR) are meant to17happen together: an issue list in a PR description is only useful if the18numbers in it are real and current, and issues filed for a PR are only19useful if the PR actually points back at them.2021## Workflow22231. **Establish what work you're filing issues for.** If a PR number is24 given or obvious from context (the current branch's open PR), read it25 — `pull_request_read` method `get` for its title/body/branches, and26 either `get_commits` or a local `git log`/`git diff` against the base27 branch for what actually changed. Ground every issue in real,28 verifiable work: a commit, a diff, a file. If the user is describing29 work that isn't reflected in commits yet, that's fine to file too, but30 say so explicitly rather than presenting it as already-done. If31 there's no PR yet and no clear scope, ask rather than guessing at what32 to track.33342. **Decide the shape: one issue, or a parent epic with children?**35 - A single, atomic, well-scoped change — one commit's worth, one36 coherent piece of work — gets **one issue**. Don't manufacture an37 epic-of-one just to have a hierarchy.38 - Multiple genuinely distinct pieces of work serving one umbrella goal39 (typically: several commits, each a self-contained step) get a40 **parent epic issue plus one child per piece**, linked through41 GitHub's actual parent/child issue relationship — not just shared42 labels or a checklist with no real links behind it.43 - A reliable way to find the right split: look at the commit history44 for the branch/PR. One child issue per tightly-scoped commit (or45 small cluster of commits that are really one step) tends to produce46 issues that are each individually closeable and meaningful — check47 this shape before inventing your own grouping from scratch.48 - "Group where applicable" cuts both ways: don't force unrelated work49 under one parent, and don't flatten obviously related, multi-step50 work into a flat pile of ungrouped issues either.51523. **Check issue-type support before creating anything.** Call53 `list_issue_types` for the owner/repo. If the repository defines54 types (commonly something like Feature/Bug/Task), pick the closest55 fit for each issue you create and pass it. If the repository has no56 issue types configured, omit the `type` field entirely rather than57 guessing at a value that doesn't exist there.58594. **Search before creating, to avoid duplicates.** Use `search_issues`60 (or `list_issues` for a small repo) for anything already covering the61 same work — a stale or half-finished issue from earlier is worth62 linking to and updating rather than duplicating. Only skip this check63 if the user has made clear these are definitely new.64655. **Create the issues, parent first.**66 - **Parent (if any)**: `issue_write` method `create`, with a body67 naming the PR it's tracked in and a short description of the68 overall goal. A plain-text checklist of the sub-pieces is fine here69 even before the children exist — you can go back and turn it into70 real `#`-linked bullets once the children have numbers, but that's71 a nice-to-have, not required.72 - **Children**: `issue_write` method `create` with `parent_issue_number`73 set to the parent's number — this attaches the child to the parent74 in the same call; no separate linking step needed. (`sub_issue_write`75 is for re-parenting an issue that already exists — you don't need it76 for issues you're creating fresh in this workflow.)77 - Give each issue a real, specific body: what changed, which files or78 areas, and why — pulled from the actual commit message or diff for79 that piece of work, not written generically from the title alone.80 - Create children in the same order the corresponding commits landed,81 so the issue numbers read in a sensible sequence.82836. **Update the PR — title and body, in one call.**84 - **Title**: short. When a parent epic exists, matching its title85 verbatim keeps the PR and its tracking issue recognizable as the86 same piece of work at a glance — an epic title that was itself kept87 short is usually reusable as-is. Otherwise, write a short, accurate88 title for the single issue's scope. Aim well under 70 characters.89 - **Body**: add (or rewrite) an `## Issues` section listing every90 issue created, one per line, in exactly this format:9192 ```93 - Closes #{{issue-number}} -- {{issue-title}}94 ```9596 The `Closes` keyword is deliberate, on every line including a97 parent epic's — GitHub auto-closes any issue referenced this way98 when the PR merges into the repo's default branch, so the list99 doubles as the mechanism that closes the issues, not just a100 description of them.101102 Indent each level of child under its parent by two spaces — GitHub103 renders two-space-indented bullets as a nested list. A flat set of104 issues with no parent is just one un-indented list. Keep whatever105 other sections belong in this PR's description (Summary, Key106 changes, Test plan, whatever the repo's own convention is) — the107 Issues section is additive. The one exception: if the existing108 description is generic boilerplate that no longer reflects the PR's109 actual current state (common after several rounds of commits since110 it was first written), rewriting the whole body to match reality is111 the right call — just say that's what you're doing rather than112 silently overwriting something that looked deliberate.113 - Use `update_pull_request` with both `title` and `body` set in the114 same call.1151167. **Verify — don't trust the write call's echo.** After creating the117 issues and updating the PR, read them back: `pull_request_read`118 method `get` on the PR to confirm the title and body actually saved119 as given (GitHub's write endpoints occasionally normalize or truncate120 content silently), and spot-check the created issues if there's any121 doubt about the parent/child structure actually taking. Only report122 the work as done once you've confirmed it from a fresh read, not from123 memory of what you sent.124125## Format reference126127With a parent epic:128129```130## Issues131132- Closes #50 -- Add Stata skill (stata-recipes)133 - Closes #51 -- Create the initial stata-recipes skill134 - Closes #52 -- Expand stata-recipes: time-series/panel regression, unit-root tests135 - Closes #53 -- Restructure stata-recipes recipes into models/ and tests/ subfolders136```137138Flat, no parent:139140```141## Issues142143- Closes #61 -- Fix broken link in README144```145146Two levels of nesting (a parent whose children each have their own147children) follows the same two-spaces-per-level rule:148149```150## Issues151152- Closes #70 -- Rewrite the onboarding flow153 - Closes #71 -- New signup form154 - Closes #72 -- Add email verification step155 - Closes #73 -- New welcome email156```157158## What this doesn't do159160- Doesn't invent work that wasn't done or described — every issue traces161 back to a commit, a diff, or something the user explicitly asked to162 track.163- Doesn't create labels, milestones, or projects — only issues (with a164 `type`, when the repository supports one) and the PR's own title and165 body.166- Doesn't merge, approve, request review, or otherwise touch the PR's167 review state — title and description only.168- Doesn't assume any one environment's house rules for GitHub posts169 (e.g. an attribution footer convention) apply everywhere — an issue170 body or PR description is content the workflow above writes, not a171 comment; follow whatever posting conventions the current172 environment or repository actually specifies for those, rather than173 a rule baked into this skill.174175## Development176177See `meta/MAINTAINERS.md` for layout and versioning notes. Not read as178part of carrying out a live "file issues for this PR" request — don't179act on it while answering one.