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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>