feat(ce-pr-description): focused skill for PR description generation#561
feat(ce-pr-description): focused skill for PR description generation#561
Conversation
…d skill
New skill owns the value-first description writing logic that was
previously inline in git-commit-push-pr. Input contract is two-shape:
pr:<number> for existing PRs (used by refresh mode), or range:<base>..<head>
for pre-PR generation (used by new PR creation and by ce-pr-stack per
layer). Output is structured {title, body}; caller decides whether to
apply via gh pr edit.
No interactive prompts, no auto-apply, no branch coupling. The skill
is a pure capability — git-commit-push-pr wraps it with confirmation
prompts and evidence-capture for single-PR interactive flows;
ce-pr-stack (via git-commit-push-pr's stack-aware routing, coming next)
will call it per layer without the interactive scaffolding.
Refactor preserves git-commit-push-pr's user-facing behavior:
- Full flow: commit + push + create PR, description generated via
ce-pr-description with range:<base>..<head> and passed to gh pr create
in a single call (no transient placeholder on GitHub)
- Refresh mode (DU-1/DU-2/DU-3): interactive scaffolding stays; DU-3
delegates description generation to ce-pr-description with pr:<number>,
then presents the compare-and-confirm as before
Naming: ce-pr-description, not git-pr-description. PR is a GitHub
artifact; the ce- prefix matches the future convention for plugin
skills. git-commit-push-pr will rename later.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 11f466825d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…gger words Addresses two issues flagged in PR #561 review. P1 — range: input no longer assumes the base ref is local. Fetches on demand before validating, matching the pre-refactor git-commit-push-pr behavior. Handles both remote-prefixed forms (origin/main) and bare branch names with a sensible remote-detection fallback. Previously a fresh clone or a deleted local branch caused an early graceful exit and skipped description generation entirely; now it fetches and proceeds. P2 — pr: input no longer uses headRefName directly in git commands. Fetches refs/pull/<number>/head (GitHub's always-available pull ref), captures FETCH_HEAD into PR_HEAD_SHA, and uses the SHA in subsequent merge-base/log/diff calls. Works for fork PRs, deleted local branches, and cases where the user runs the skill from a different branch. Documents an alternative SHA-from-gh-metadata path for non-GitHub remotes where pull/<N>/head isn't exposed. Also optimizes the frontmatter for skill triggering: - Description now leads with explicit trigger phrases ('write a PR description', 'refresh the PR description', 'regenerate the PR body', 'rewrite this PR', 'freshen the PR', etc.) so Claude reliably consults this skill for standalone description work, not only via the git-commit-push-pr and ce-pr-stack callers. - argument-hint surfaces the three input forms (pr: / range: / focus:) and notes that fork PRs and non-local base refs are handled automatically — so callers and humans know the skill is robust. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 024625a4f8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
… pr: input pr: now takes three equivalent forms: - Bare number: pr: 561 (resolves in current repo) - Full URL: pr: https://github.com/owner/repo/pull/561 - Shorthand: pr: owner/repo#561 gh pr view accepts all three natively, so the metadata fetch is unchanged. Two runtime paths split on whether the PR's base repo matches the current working directory: Case A (same repo): local-git path — fetch refs/pull/<N>/head, use PR_HEAD_SHA in merge-base/log/diff. Existing behavior. Case B (different repo): API-only path — gh pr diff gives the diff without requiring the commits to be local. Equivalent output with a caller-facing note that API fallback was used (relevant for evidence preservation logic in Step 3). Enables workflows like pasting a PR URL from a repo the user doesn't have a local clone of, or refreshing descriptions across repos from a single working directory. Description and argument-hint updated to surface URL support. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d37f492b6c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…rning, sharpen diagram vs table Three issues surfaced by content-quality evals on PR #561. JSON field correction: gh pr view --json does NOT expose baseRepository. The SKILL.md previously requested it alongside headRepository, which would have failed at runtime. Corrected to headRepository + headRepositoryOwner + isCrossRepository (the fields that actually exist). Case A vs Case B routing now uses isCrossRepository + URL parsing against origin, not the nonexistent baseRepository. FETCH_HEAD handling: the warning to capture PR_HEAD_SHA immediately now explicitly forbids parallel commands and split tool calls between fetch and rev-parse. The ephemeral nature of FETCH_HEAD is the failure mode; any intervening fetch silently corrupts the SHA. Visual communication: reshape the "when to use Mermaid vs when to use a table" guidance around the real distinction — topology vs parallel variation. Architecture changes have edges (A → B, who talks to whom, who delegates to what), which tables cannot express; diagrams are almost always right for architecture. Tables are for parallel variation of a single shape (same metric different values, same attributes different variants). Adds an in-doubt heuristic: "edges → Mermaid, rows → table." Previously the guidance allowed tables as a substitute for architecture diagrams, which caused evals to pass the visual-aid assertion with flat lists where a graph was needed. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 53dfb5e841
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…ETCH_HEAD The previous Case A path ran a multi-ref fetch and read FETCH_HEAD: git fetch --no-tags origin main refs/pull/<N>/head PR_HEAD_SHA=$(git rev-parse FETCH_HEAD) git rev-parse FETCH_HEAD returns only the first entry in .git/FETCH_HEAD, which is the base branch SHA, not the PR head. Silent failure — merge-base equals PR_HEAD_SHA, diff is empty, commit list is empty, and the skill produces a broken description with no error signal. Fix: extract the PR head SHA explicitly from gh pr view --json commits (the last entry of the commits array is the PR's current tip), then address all subsequent git commands by explicit SHA rather than via FETCH_HEAD. A single fetch populates the object store; downstream commands don't depend on ref ordering. Also documents a fallback that parses .git/FETCH_HEAD by pull-ref pattern via awk — robust to multi-ref ordering — for the rare case where a server refuses to serve non-tip SHAs directly. Caught during integration testing of git-commit-push-pr's refresh-mode delegation to ce-pr-description (PR #561). An agent following the old instructions silently produced an empty diff and had to work around by falling through to the SHA-from-commits-array path that was documented as an alternative — that path is now primary. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 30c87f87bf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Two issues surfaced by exercising the full invocation matrix. owner/repo#NN shorthand was claimed as a third input form, but gh pr view's positional argument accepts only <number>, <url>, or <branch> — NOT shorthand. Passing owner/repo#NN produces "no pull requests found for branch" errors. Corrected the input-form documentation to the two forms that actually work: bare number (current repo) and full URL (any repo). Added a note that cross-repo number references are done via gh pr view <N> -R owner/repo, which callers can use directly when needed. A full URL remains the simplest cross-repo path. headRefOid is a direct JSON field exposed by gh pr view --json. Using it is more robust than indexing into .commits[-1].oid, which depended on the commits array being non-empty and correctly ordered. The FETCH_HEAD multi-ref bug fix from the previous commit is preserved — both paths produce the same SHA — but headRefOid is now the primary recommendation. Also added baseRefOid to the documented field list. Validated end-to-end against the invocation matrix: - pr: bare number (same repo) — headRefOid path resolves correctly - pr: full URL (same repo) — URL parse + headRefOid resolves correctly - pr: full URL (different repo) — Case B API fallback kicks in - range: origin/main..HEAD — resolves directly - range: main..HEAD (not local) — fetch-on-demand works - range: HEAD~1..HEAD — commit-ish resolves without fetch - pr: nonexistent — gh surfaces GraphQL error, graceful exit - pr: merged/closed PR — state check exits gracefully - range: bogus base — rev-parse fails, graceful exit Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
argument-hint is meant to be a quick argument shape for discovery, not a full spec. The long-form explanations belong in the description (where they are) and the body. Cut from 280+ characters to just the signature. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e768a95640
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Cluster A — git-commit-push-pr orchestration gaps from Unit 5 refactor: - DU-3 and Step 6 existing-PR delegation now pass full PR URL (unambiguous repo/PR identity) to ce-pr-description instead of bare number - Existing-PR flow reordered: Step 7 asks rewrite-or-not first, Step 6 runs only on yes, so the delegation call site is actually reached - Step 6 gathers real branch diff (git diff <remote>/<base>...HEAD) before the evidence decision gate, so feature branches with pushed commits are judged on the branch diff not the working-tree diff Cluster B — ce-pr-description input-handling correctness: - range: base resolution now treats <remote>/<branch> and <bare-branch> as distinct possibilities. Tries local first, then matched-remote prefix, then bare branch across remotes. release/2026-04, feat/foo, hotfix/x now resolve correctly via origin. - EFFECTIVE_BASE tracks the actually-resolving ref separately from user-supplied <base>; used in all downstream merge-base/log/diff. Fixes range:main..HEAD in clones where local main was deleted. - pr: Case A now falls back to Case B API path if fetch fails or merge-base can't resolve — covers shallow clones, detached states, offline/auth issues without hard-failing the skill. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d9c975d5f5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Replaces the pr:/range:/focus: formal grammar with two modes and free-form input parsing: 1. Current-branch mode (default) — when no PR reference is given, describe the commits on HEAD against the repo's default base (origin/HEAD), or against an existing PR's baseRefName if a PR is already open on the branch. 2. PR mode — when the input contains any PR reference (full URL, pr:<N>, #NN, or a bare number), describe that PR using the existing Case A/B routing. Focus is now free-form steering text. The agent extracts whichever PR reference pattern is present; everything else is treated as focus. No formal focus: keyword required (though it still works). Removes the range: input surface entirely: - No more <remote>/<branch> vs bare-branch ambiguity - No more EFFECTIVE_BASE tracking - No more multi-remote resolution cascade - No more fetch-on-demand logic for arbitrary user input - All three Cluster B feedback threads were about this complexity; the problem class now doesn't exist. Current-branch mode uses a narrow, well-defined base resolution: origin/HEAD or the existing PR's base. Callers like git-commit-push-pr never hit the problematic edge cases because they operate on well-known local refs. Updates git-commit-push-pr's Step 6 and DU-3 to match the new contract: invoke ce-pr-description with no arg (current-branch mode, new PRs) or with the PR URL (existing PRs). Focus is appended as free text rather than passed as a formal focus: argument. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 103248df15
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Evidence preservation now triggers for any PR mode invocation, not only the bare-number form. After the earlier refactor, callers like git-commit-push-pr pass full PR URLs for repo-safe delegation, which made the conditional fall through to "omit entirely" and silently dropped existing ## Demo / ## Screenshots blocks during refresh. Preservation is about whether we have an existing PR body to read, not about which input shape the caller used. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Add base:<ref> override for current-branch mode so callers can forward an already-resolved base branch. Non-default base targets (develop, release/*, or any branch set as the PR's base in git-commit-push-pr's Step 6) now generate descriptions from the correct commit range. Base resolution priority in current-branch mode: 1. Caller-supplied base:<ref> 2. Existing PR's baseRefName (for branches with a PR already open) 3. origin/HEAD (repo default) Updates git-commit-push-pr Step 6 to pass base:<base-remote>/<base-branch> when invoking ce-pr-description for new PRs, so description scope matches the branch actually being opened. PR mode is unchanged — PRs define their own base via baseRefName. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f2bef3be58
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Branch diff collection now falls back to local state when the remote is unreachable. rev-parse --verify first; only fetch if the base ref isn't local. Restores the pre-refactor behavior and prevents offline, restricted-network, or expired-auth environments from hard-failing when git diff <base>...HEAD could run entirely from local refs. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
New entry for ce-pr-description in the README's Git Workflow section. Also updates the git-commit-push-pr entry to note that it delegates title/body generation to ce-pr-description. Skill count bumped from 41+ to 42+. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Two evidence-decision bullets still said "pass via focus: context" after the ce-pr-description refactor dropped the formal focus: keyword in favor of free-text steering. Matches the existing wording elsewhere in this file (DU-3 already says "steering text") and matches the ce-pr-description skill's current input contract. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Summary
Any skill that needs a value-first PR description can now delegate to
ce-pr-description. It takes a natural-language prompt, extracts a PR reference if one is present (pr:561,#561, a full URL, or a bare number), and otherwise describes the commits on the current branch. It returns a structured{title, body}for the caller to apply. No interactive prompts, no auto-apply, no opinions about which ref to fetch.git-commit-push-prnow delegates both its full-flow PR creation and its refresh-mode rewrites through this skill. Same writing voice across every caller; one place to evolve the writing principles.How callers invoke it
ce-pr-descriptionce-pr-description emphasize the benchmarksce-pr-description pr:561ce-pr-description #561 emphasize the perf storyce-pr-description https://github.com/foo/bar/pull/561ce-pr-description base:origin/developorigin/develop(non-default base override)Steering text is optional and free-form. The skill treats whatever isn't a PR reference as focus — no
focus:keyword required.Current-branch mode
Used by
git-commit-push-pr's full flow to describe a feature branch beforegh pr create. Base resolution priority:base:<ref>(for non-default targets likedeveloporrelease/*)baseRefNameif one is already open on the branchorigin/HEADfallbackgit-commit-push-prpassesbase:<base-remote>/<base-branch>when it has already resolved the target, so descriptions always reflect the correct commit range even when the PR targets a non-default base.PR mode
Uses
gh pr view --jsonto read PR metadata, then routes on whether the URL's repo matchesorigin:headRefOid, not fromFETCH_HEAD— which has a multi-ref ordering bug that silently returns the wrong SHA) and computes the merge base + diff locally.gh pr diff. Lets the skill describe PRs from repos that aren't cloned locally — paste a URL from any directory, get a description.git-commit-push-pr integration
git-commit-push-pr's user-facing behavior is unchanged. What moved:ce-pr-description. The returned{title, body}feeds a singlegh pr create --title --bodycall. No transient placeholder on GitHub.gh pr edit.Evidence blocks (
## Demo,## Screenshots) are preserved for every PR mode invocation regardless of input shape — bare number, URL, or shorthand — so refreshes don't drop existing visual evidence.Naming
ce-pr-description, notgit-pr-description. A pull request is a GitHub artifact, not a git primitive; "git" is redundant plumbing detail. Thece-prefix lands at the target for the future plugin-wide skill rename, so this one starts there directly.git-commit-push-prwill migrate later.Test plan
bun test tests/frontmatter.test.ts— passes (95 tests)bun run release:validate— clean (43 skills, +1 for ce-pr-description)git-commit-push-prrefresh mode against this PR generated an equivalent high-quality description end-to-end; caught and fixed aFETCH_HEADmulti-ref bug and three input-handling bugs (all resolved)#NN, non-existent PR, merged PR, invalidbase:all behave correctlyContext
Originally extracted as a prerequisite for stacked-PR work (see draft PRs #559 and #560, currently parked on
gh stackprivate-preview availability). The extraction and refactor are independently valuable and stand alone — this PR can merge today. Future callers (stacked-PR description generation, release-note blurbs, changelog entries) can invoke the same skill without dragging in interactive scaffolding.