Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Create a pull request for the current branch: creates a new branch if needed, commits staged/unstaged changes, pushes, and opens a PR using the repo's pull_request_template.md. Use when the user says "create PR", "open PR", "make a pull request", "push and PR", or similar. Requires a SmartContract-team (EXSC) Linear ticket — assigned and estimated — on every PR; resolves one from context or creates one (auto-assigned, proposed estimate) unless the user explicitly opts out. Leaves reviewer checkl
.claude/skills/lifinance-create-pr/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-06 | ✗→✓ | ▲ Improved | 479% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 297% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 263% | 0% |
| case-15 | ✗→✓ | ▲ Improved | 128% | 0% |
| case-07 | ✓→✗ | ▼ Worse | 430% | 0% |
User says any of:
/create-pr [branch-name]feat/short-description).--draft in step 11. All other steps (template, Linear ticket, tests) apply unchanged.s at the step 5 prompt) — the absence of a known ticket is never an opt-out.This skill creates PRs. For editing an existing PR's title/body, follow CLAUDE.md → "Creating and editing PRs via gh" (uses gh api -X PATCH with a JSON payload).
There is no local CodeRabbit pre-flight anymore (/pr-ready was removed — the CLI was hitting rate limits and wasting review cycles). Cloud CodeRabbit still runs in GitHub CI on every PR as the review backstop.
Run git status and git diff HEAD to understand:
gh pr view)Handle these edge cases before continuing:
main/master with local changes: require a new branch (step 3); never commit to a protected branch.<type>/<lowercase-id>-<short-slug> when a Linear ID is already known from conversation context (e.g. feat/exsc-327-add-foo). Branch-name ID prefix is the most reliable trigger for Linear's GitHub auto-link.feat/<short-slug>, fix/<short-slug>, chore/<short-slug>) when no Linear ID exists yet. Step 5 may still resolve or create one later, in which case the branch can be renamed (git branch -m) before push.main or master — create a new branch.bashgit checkout -b <branch-name>
If branch already exists locally, switch to it (git checkout <branch-name>).
git add -A blindly — check for unrelated untracked files first and skip them.git log entries (e.g. chore(skills): …).bashgit commit -m "<subject line>"
Read .github/pull_request_template.md verbatim. Fill in:
feat/exsc-327-…, see step 2), orFixes EXSC-327, Closes EXSC-327, Resolves EXSC-327, or Ref EXSC-327 (case-insensitive; use Ref for partial work that should not auto-close the ticket on merge).A bare EXSC-327 mention in the body alone does not reliably trigger the link. Prefer the branch-name route; always render the body's Linear line as a markdown link — Fixes [<ID>](<ticket URL>) (or Ref [<ID>](<ticket URL>)), using the url returned by the Linear MCP — so reviewers can click through to the ticket, and the keyword + ID still trigger the auto-link as a belt-and-braces measure. No extra Linear MCP call is needed for cross-linking once either condition is satisfied.
EXSC-123) mentioned by the user in this session.(?i)([A-Z]+-\d+) (e.g. feature/exsc-327-…), look up that ID directly via the Linear MCP list_issues tool with query: "<ID>". If found and the ID matches, use it — no further questions about which ticket to link (the validation block below still applies).feat/, fix/, chore/, replace - with space) and the commit subject. Query the Linear MCP list_issues tool with team: "SmartContract" (i.e. EXSC tickets) and the keyword string. Do not filter by assignee — tickets are often created by PMs/others.statusType: started or unstarted).ID — Title — status, and ask which to link (with a "none of these" option that falls through to route 4's required-ticket prompt — it is not an opt-out). Use AskUserQuestion if available; otherwise plain chat.Validation (applies to any ticket resolved via routes 1–3) — fetch it with the Linear MCP get_issue tool and check:
Ref <ID> line if relevant, but fall through to route 4 to create the EXSC ticket.save_issue with assignee: "me". Never reassign a ticket that already has an assignee.save_issue. Unattended runs set the proposed value directly.Report any repairs made (assignee/estimate) in the pre-flight summary (step 9).
<!-- No Linear task -->. The consent prompt must make both side-effects visible up front (ticket creation + local branch rename), so the user knows exactly what they're approving with a single keystroke. Default action is edit so the user always sees the proposed title and the proposed new branch name before anything is created or renamed: No Linear ticket found — one is required. Create in EXSC and rename branch? • Ticket: team=SmartContract, title="<derived title>" • Assignee: <current user> • Estimate: <proposed, default 1> • Branch: <current-branch> → <type>/<id-after-creation>-<slug>
e (default) — show the proposed title and estimate (and the resulting new branch name once an ID is allocated) and let the user adjust before either action runs.y — create the ticket with the proposed title as-is and rename the branch.s — explicit opt-out; proceed without a ticket and leave the branch as-is. If the change genuinely qualifies (typo / doc-only / dep-bump / single-line fix), suggest adding the trivial label so the ticket-linkage metric counts the PR as linked.y / e (after the user confirms the edited title): call the Linear MCP save_issue tool with team: "SmartContract", the (edited) title, a short body summarizing the change + a placeholder for the PR URL, assignee: "me", and the confirmed estimate (default 1 for simple tasks, scaled to the diff). Use the returned ID:Fixes [<ID>](<ticket URL>) in the PR body's Linear section (URL from the save_issue response).git branch -m <new-name> (use <type>/<lowercase-id>-<short-slug> per step 2). The user already consented to this rename via the prompt above.s (explicit user opt-out) — leave the section blank with <!-- No Linear task -->. Never fabricate a link, and do not rename the branch.<br> breaks, so hard-wrapped text displays with ragged mid-sentence line breaks.[x] I have performed a self-review of my code — tick only after you actually walk the full git diff main...HEAD and confirm: no leftover debug prints/commented-out code, no obvious bugs, no unrelated edits, no secrets/credentials, naming/style matches the surrounding code. Note any findings in the summary; if anything looks off, surface it instead of ticking.[x] This pull request is as small as possible and only tackles one problem — tick only after you inspect the file list (git diff --name-only main...HEAD). Tick if all touched files serve a single, coherent concern. Do not tick if the branch mixes unrelated changes. Ignore commit granularity: GitHub squashes commits on merge, so fix-up / iterative commits are not a reason to withhold the tick.[x] I have added tests that cover the functionality — tick only if tests were actually added in this diff.[x] For new facets: ... — tick only if a new facet was added.[x] I have updated any required documentation — tick only if docs were updated.- [ ]).Short imperative title (≤70 chars). Match existing commit style in git log.
Revert PRs: the title must start with Revert or contain [Revert]. versionControlAndAuditCheck.yml uses the title to exempt revert PRs from the audit-commit-hash check (the audited commit lives in the reverted PR's history, never in the revert PR's commit list) — a non-conforming title (e.g. fix: undo facet change) blocks the merge of a genuine revert that touches audited contracts.
Lint, format, typecheck, build, solhint, and secret scanning are already enforced by .husky/pre-commit (and .agents/hooks/post-edit-validate.sh) at every commit in step 4. Don't repeat them here.
The one gap pre-commit deliberately leaves is tests (forge build --skip test, no bun test:ts). Per .agents/rules/099-finish.md, run them now:
bun test:scoped -- <path-or-match> during iteration; full bun test (or forge test --match-path if scope is clear) before opening a PR.bun test <path> during iteration; full bun test:ts (runs every script/**/*.test.ts) before opening a PR.N/A in the summary.If anything fails, stop and surface the failure — do not push without explicit user override.
Before pushing or opening a PR, display a summary and wait for explicit approval:
About to create PR on branch `<branch-name>`:
(renamed from `<old-branch>` in step 5) ← show only if step 5 renamed it
Commits (<N>) since main (from `git log main..HEAD --oneline`):
• <sha> <subject> ← step 4
...
Files changed (<N>) (from `git diff --name-only main...HEAD`):
• <file1>
• <file2>
...
↑ If any file here looks unrelated to the task,
answer `n` below and we'll split it into a separate PR.
Self-review:
• Diff walked: <N> files, <±M> lines
• Findings: <none / list any concerns>
• Single-concern: <yes / no — and why>
Linear: <EXSC-ID> — assignee <name>, estimate <n> (repairs: <none / assigned <name> / estimate set to <n>>)
↑ or: no ticket (explicit user opt-out)
Checks run:
• Pre-commit hook ... PASS (enforced lint/typecheck/build/secrets at every commit)
• forge test ........ PASS / FAIL / N/A
• bun test:ts ....... PASS / FAIL / N/A
PR title: <title>
PR body:
─────────────────────────────────────────
<full filled-in PR body>
─────────────────────────────────────────
Proceed? (y/n)If the user says n: ask what to change (title, body, files) and loop back. Do not push. If the user says y: proceed to steps 9–10.
bashgit push -u origin <branch-name>
Write body to a temp file and create via gh:
bashgh pr create --title "<title>" --body "$(cat /tmp/pr-body.md)" --base main --head <branch-name>
Append --draft if the Draft input was requested.
Print the resulting PR URL to the user.
After the PR is created, ask:
> PR created: <url>. Want me to post it for review? (/post-pr-for-review)
/post-pr-for-review owns the channel choice — don't name a channel here.
e (default, edit title) / y (accept as-is) / s (explicit opt-out). Only on explicit opt-out, leave the section blank with <!-- No Linear task -->; unattended runs must create the ticket. Never fabricate a link.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-05 | fail→fail | 4,467 | 6,133 | +37% | 1 | 1 | 0% | 634 | 4,361 | +588% | 0 | 0 | — |
case-01 | fail→fail | 11,241 | 3,901 | -65% | 1 | 1 | 0% | 1,890 | 4,165 | +120% | 0 | 0 | — |
case-02 | fail→fail | 10,439 | 29,721 | +185% | 1 | 1 | 0% | 1,793 | 4,198 | +134% | 0 | 0 | — |
case-03 | fail→fail | 4,502 | 4,889 | +9% | 1 | 1 | 0% | 264 | 4,195 | +1489% | 0 | 0 | — |
case-04 | fail→fail | 4,007 | 6,635 | +66% | 1 | 1 | 0% | 730 | 4,385 | +501% | 0 | 0 | — |
case-06 | fail→pass | 5,849 | 2,994 | -49% | 1 | 1 | 0% | 763 | 4,415 | +479% | 0 | 0 | — |
case-07 | pass→fail | 4,718 | 4,409 | -7% | 1 | 1 | 0% | 811 | 4,296 | +430% | 0 | 0 | — |
case-08 | fail→fail | 5,008 | 5,765 | +15% | 1 | 1 | 0% | 750 | 4,255 | +467% | 0 | 0 | — |
case-09 | fail→fail | 5,968 | 32,657 | +447% | 1 | 1 | 0% | 892 | 4,137 | +364% | 0 | 0 | — |
case-10 | fail→fail | 7,957 | 3,250 | -59% | 1 | 1 | 0% | 1,286 | 4,136 | +222% | 0 | 0 | — |
case-11 | fail→pass | 7,272 | 2,963 | -59% | 1 | 1 | 0% | 1,120 | 4,442 | +297% | 0 | 0 | — |
case-12 | pass→pass | 7,348 | 3,196 | -57% | 1 | 1 | 0% | 1,198 | 4,473 | +273% | 0 | 0 | — |
case-13 | fail→pass | 7,690 | 2,724 | -65% | 1 | 1 | 0% | 1,210 | 4,394 | +263% | 0 | 0 | — |
case-14 | pass→fail | 7,492 | 3,062 | -59% | 1 | 1 | 0% | 1,033 | 4,480 | +334% | 0 | 0 | — |
case-15 | fail→pass | 13,191 | 3,082 | -77% | 1 | 1 | 0% | 1,959 | 4,466 | +128% | 0 | 0 | — |
case-16 | pass→pass | 8,276 | 2,151 | -74% | 1 | 1 | 0% | 1,182 | 4,226 | +258% | 0 | 0 | — |
case-17 | pass→fail | 8,014 | 7,595 | -5% | 1 | 1 | 0% | 1,216 | 4,317 | +255% | 0 | 0 | — |
case-18 | fail→fail | 9,162 | 2,992 | -67% | 1 | 1 | 0% | 1,501 | 4,209 | +180% | 0 | 0 | — |
case-19 | fail→fail | 7,428 | 2,613 | -65% | 1 | 1 | 0% | 1,209 | 4,167 | +245% | 0 | 0 | — |
case-20 | pass→fail | 9,123 | 5,930 | -35% | 1 | 1 | 0% | 1,450 | 4,184 | +189% | 0 | 0 | — |
case-21 | pass→pass | 12,161 | 2,180 | -82% | 1 | 1 | 0% | 1,797 | 4,254 | +137% | 0 | 0 | — |
case-22 | pass→fail | 7,992 | 2,986 | -63% | 1 | 1 | 0% | 1,248 | 4,233 | +239% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 11 counted toward the lift figure. The other 11 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of -5 percentage points is the difference between those two pass rates over the 11 comparable cases. 7 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.