chore(skills): add create-pr skill#1803
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
WalkthroughAdds a detailed ChangesCreate PR Skill Workflow
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Integrate /pr-ready as step 8 (mandatory CodeRabbit pre-flight) - Trim step 7 to tests only — pre-commit hook already covers lint/typecheck/build - Require actual diff walk + commit inspection before ticking self-review and single-concern boxes (no default ticks) - Add edge cases for clean tree, detached HEAD, on-main, existing-PR branches - Replace "wait for terminal input" Linear lookup with chat/AskUserQuestion - Drop hardcoded model in commit example - Reference CLAUDE.md for PR-edit conventions (avoid drift) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…pe, top-3 ask) - Add explicit 4-step strategy: conversation context → branch-name ID prefix → scoped keyword search → user prompt / blank - Drop assignee filter; tickets are often created by PMs/others - Auto-accept only if top hit shares ≥3 tokens AND has active status - For ambiguous matches, show top 3 (ID/title/status) and ask - Document that Linear's GitHub integration handles bidirectional cross-linking automatically when the issue ID is in the PR body — no extra MCP call required Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| • <file2> | ||
| ... | ||
|
|
||
| Commit: "<commit message>" |
There was a problem hiding this comment.
which commit message is that? Of the last commit?
There was a problem hiding this comment.
good catch. The summary now shows a commits since main list straight from git log main..HEAD --oneline, with the step-4 commit and any pr-ready: commits visible in order. I also folded the separate "/pr-ready commits added" sub-section into that unified list so there's only one source of truth.
expanded in: a87fb8ae
| - **Branch already has open PR**: surface URL, offer to push new commits instead. | ||
| - **Push rejected (non-fast-forward)**: report error; do not force-push without explicit user instruction. | ||
| - **No template found**: use minimal body with title + rationale only. | ||
| - **Linear task unknown**: leave the section blank with an HTML comment (`<!-- No Linear task -->`) rather than fabricating a link. |
There was a problem hiding this comment.
I think we should switch to having a linear task for everything since it's nice and easy to create those now. So if there is no linear task, then maybe we should create one automatically?
wdyt?
There was a problem hiding this comment.
agree! added in: 5b629293
To make sure that we still have human readable titles rather than title dirived from diffs I didn't go with fully automatic approach. The skill now offers to create one when none is found, with three options: e (default — show the proposed title and let you edit before creating), y (accept the proposed title as-is), s (skip). On accept it creates the ticket in EXSC to make sure that we still have human readable titles rather than title dirived from diffs
Branch-name ID prefix is the most reliable trigger for Linear's GitHub auto-link. Update step 2 to prefer `<type>/<lowercase-id>-<short-slug>` when an ID is known from context, and fall back to slug-only when not. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Linear's GitHub integration triggers the bidirectional auto-link only via branch-name ID prefix OR a magic keyword (`Fixes`/`Closes`/ `Resolves`/`Ref`) + ID in the title/body — a bare ID mention is not enough. Update step 5 to require `Fixes <ID>` (or `Ref <ID>`) in the body and call out the branch-name path as primary. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
/pr-ready can land auto-fix commits on the branch, so tests should run against the post-/pr-ready HEAD. Swap steps 7 and 8, and tweak both step bodies to explain the ordering (and keep the checkbox reference in step 5 pointing at the right step number). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
By step 9 HEAD may carry several commits — the step-4 commit plus any auto-fix commits from /pr-ready — so a single "Commit:" line is stale. Replace with a "Commits (N) since main" list (from `git log main..HEAD --oneline`), fold in the separate /pr-ready sub-section, and put the check list in the new step order (/pr-ready before tests). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When no Linear ticket matches, propose creating one (default action `edit` — always shows the user the proposed title before creating; `y` accepts as-is; `s` skips). On accept, insert `Fixes <ID>` in the body and rename the branch to include the ID before push so auto-linking works via both routes. On skip, fall back to the existing `<!-- No Linear task -->` placeholder. Update Failure modes to match. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| - `e` (default) — show the proposed title (`<derived from branch + commit subject>`) and let the user adjust before creating. | ||
| - `y` — create immediately with the proposed title as-is. | ||
| - `s` — skip; proceed without a ticket. | ||
| - On `y` / `e` (after the user confirms the edited title): call `mcp__claude_ai_Linear__save_issue` with `team: "SmartContract"`, the (edited) title, and a short body summarizing the change + a placeholder for the PR URL. Use the returned ID: |
There was a problem hiding this comment.
Skill will call mcp__claude_ai_Linear__save_issue and rename the branch (git branch -m) to include the new ID; these are mutating external/local actions. Ensure explicit, unambiguous user authorization is obtained before creating tickets or renaming branches.
Details
✨ AI Reasoning
The skill's workflow includes creating a Linear issue via mcp__claude_ai_Linear__save_issue and renaming the local branch (git branch -m <new-name>) as part of its automated flow. These are external side-effects (networked creation of tickets and local branch mutation) introduced by this new skill. Automated creation/renaming operations that affect repository state or external trackers should require explicit, clearly visible confirmation; they can be surprising if performed without clear user consent.
🔧 How do I fix it?
Ensure skill actions match the description. Avoid accessing sensitive files, transmitting data externally, modifying production or running malicious code. Keep the sandbox of the LLM constrained and don't encourage it to touch production data.
Reply @AikidoSec feedback: [FEEDBACK] to get better review comments in the future.
Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info
There was a problem hiding this comment.
The fair part of the flag was the git branch -m: the original prompt only asked about the ticket, and the rename was described in a sub-bullet underneath, so a y arguably consented to ticket creation alone rather than both side-effects. Fixed in d369d75 — the prompt now lists both actions side-by-side with their concrete inputs (team + proposed title; current branch → proposed new branch), so a single y/e covers both unambiguously, and s explicitly leaves the branch as-is.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
.claude/skills/create-pr/SKILL.md (1)
149-181: 💤 Low valueConsider adding language specifier to code block.
The fenced code block at line 149 lacks a language specifier. While not critical, adding
textormarkdownwould improve rendering consistency and satisfy the markdownlint MD040 rule.📝 Proposed fix
-``` +```text About to create PR on branch `<branch-name>`:🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.claude/skills/create-pr/SKILL.md around lines 149 - 181, The fenced code block that begins with "About to create PR on branch `<branch-name>`" is missing a language specifier; update that block delimiter from ``` to ```text (or ```markdown) so the block starts with ```text and the rest of the content remains unchanged, which will satisfy MD040 and improve rendering consistency.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.claude/skills/create-pr/SKILL.md:
- Line 29: The step number in the sentence referencing "/pr-ready" is incorrect:
it says "/pr-ready is integrated as step 8" but the workflow lists "/pr-ready"
as step 7 and the test suite as step 8; update the text in SKILL.md to refer to
"/pr-ready" as step 7 (or reword to avoid a hardcoded step number) so it matches
the actual workflow ordering and prevents confusion (search for the phrase
"/pr-ready is integrated as step 8" and change "step 8" to "step 7" or use a
non-numbered description).
---
Nitpick comments:
In @.claude/skills/create-pr/SKILL.md:
- Around line 149-181: The fenced code block that begins with "About to create
PR on branch `<branch-name>`" is missing a language specifier; update that block
delimiter from ``` to ```text (or ```markdown) so the block starts with ```text
and the rest of the content remains unchanged, which will satisfy MD040 and
improve rendering consistency.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 875bc1f8-2c17-46a2-9b4b-d14b8128252c
📒 Files selected for processing (1)
.claude/skills/create-pr/SKILL.md
…r fallback The previous prompt asked "Create one in EXSC?" but the subsequent `git branch -m` happened implicitly, so a `y` could feel like consent to ticket creation alone. Update the prompt to show both side-effects (ticket creation + branch rename with the new name preview) so a single keystroke covers both actions unambiguously. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
After the step 7/8 swap (commit e50050a), the "Related conventions" section still pointed to /pr-ready as "step 8 below"; it's now step 7. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Added a guideline to refer to MCP tools by client-agnostic names in documentation, ensuring consistency across different client integrations. This change aims to prevent confusion caused by varying namespace prefixes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…nostic names Introduced a new section in the add-new-rule command documentation to clarify the use of client-agnostic names when referencing MCP tools. This aims to enhance consistency and prevent confusion across different client integrations. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Introduced a new command documentation for creating pull requests, detailing the workflow, inputs, and related conventions. This aims to streamline the process of opening PRs by providing clear guidelines for users. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.agents/commands/create-pr.md:
- Line 210: Replace the hardcoded temporary file usage in the gh pr create
invocation by generating a unique temp file with mktemp, write the PR body into
that temp file, call gh pr create using --body-file to point to the temp file
(instead of command substitution with cat /tmp/pr-body.md), and ensure the temp
file is removed after the command (trap or explicit rm); update the command
referenced (gh pr create --body "$(cat /tmp/pr-body.md)") to use the
mktemp-created path and --body-file to avoid race conditions and ensure cleanup.
In @.cursor/commands/create-pr.md:
- Line 1: The file .cursor/commands/create-pr.md is a plain text file containing
a path instead of being a symlink to the canonical command in
.agents/commands/create-pr.md; remove the plain file and replace it with a
symbolic link pointing to ../../.agents/commands/create-pr.md so that
.cursor/commands/create-pr.md is a symlink to .agents/commands/create-pr.md
(verify via ls -l to confirm the -> arrow), matching the DRY convention
described in .agents/commands/add-new-rule.md.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: b9eb5383-d8cf-427d-8871-85149202e0d2
📒 Files selected for processing (5)
.agents/commands/add-new-rule.md.agents/commands/create-pr.md.agents/rules/000-global-standards.md.claude/skills/create-pr/SKILL.md.cursor/commands/create-pr.md
✅ Files skipped from review due to trivial changes (1)
- .claude/skills/create-pr/SKILL.md
| Write body to a temp file and create via `gh`: | ||
|
|
||
| ```bash | ||
| gh pr create --title "<title>" --body "$(cat /tmp/pr-body.md)" --base main --head <branch-name> |
There was a problem hiding this comment.
Use mktemp for the temporary PR body file.
The hardcoded path /tmp/pr-body.md could cause race conditions if multiple instances run concurrently, and the file isn't explicitly cleaned up in the spec.
🔒 Proposed fix
-gh pr create --title "<title>" --body "$(cat /tmp/pr-body.md)" --base main --head <branch-name>
+body_file=$(mktemp)
+cat > "$body_file" <<'EOF'
+<body content>
+EOF
+gh pr create --title "<title>" --body-file "$body_file" --base main --head <branch-name>
+rm "$body_file"Note: gh pr create also accepts --body-file directly, which is cleaner than command substitution with cat.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.agents/commands/create-pr.md at line 210, Replace the hardcoded temporary
file usage in the gh pr create invocation by generating a unique temp file with
mktemp, write the PR body into that temp file, call gh pr create using
--body-file to point to the temp file (instead of command substitution with cat
/tmp/pr-body.md), and ensure the temp file is removed after the command (trap or
explicit rm); update the command referenced (gh pr create --body "$(cat
/tmp/pr-body.md)") to use the mktemp-created path and --body-file to avoid race
conditions and ensure cleanup.
| @@ -0,0 +1 @@ | |||
| ../../.agents/commands/create-pr.md No newline at end of file | |||
There was a problem hiding this comment.
Inconsistency: should be a symlink per documented conventions.
According to .agents/commands/add-new-rule.md lines 145–151 (added in this same PR), Cursor commands should be symlinks, not text files containing paths:
ln -sf "../../.agents/commands/<name>.md" ".cursor/commands/<name>.md"Line 151 explicitly states: "Verify: ls -l .cursor/commands/<name>.md ... should both show symlink arrows".
This file contains the text ../../.agents/commands/create-pr.md when it should be created as a symlink instead.
🔗 Create as symlink instead
Remove this file and create a symlink:
rm .cursor/commands/create-pr.md
ln -sf ../../.agents/commands/create-pr.md .cursor/commands/create-pr.mdThen verify: ls -l .cursor/commands/create-pr.md should show -> pointing to .agents/commands/create-pr.md.
As per coding guidelines, agent commands should follow the DRY symlink structure documented in .agents/commands/add-new-rule.md.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.cursor/commands/create-pr.md at line 1, The file
.cursor/commands/create-pr.md is a plain text file containing a path instead of
being a symlink to the canonical command in .agents/commands/create-pr.md;
remove the plain file and replace it with a symbolic link pointing to
../../.agents/commands/create-pr.md so that .cursor/commands/create-pr.md is a
symlink to .agents/commands/create-pr.md (verify via ls -l to confirm the ->
arrow), matching the DRY convention described in
.agents/commands/add-new-rule.md.
Which Linear task belongs to this PR?
Why did I implement it this way?
Adds a
create-prClaude Code skill that automates branch → commit → push → PR. The skill:.github/pull_request_template.mdverbatim and fills only specific named fields (Linear link, rationale, ticked checkboxes);git diff main...HEADfor the self-review tick; inspectsgit log main..HEAD --onelinefor the single-concern tick;forge test/bun test:ts) — the gap.husky/pre-commitdeliberately leaves (the hook usesforge build --skip testand doesn't invokebun test:ts). Lint / typecheck / build / solhint / secret scan are already enforced by pre-commit +.agents/hooks/post-edit-validate.sh, so the skill does not duplicate them;/pr-readysibling skill for local CodeRabbit pre-flight (mandatory per.agents/rules/099-finish.mdonce chore(skills): add /pr-ready local CodeRabbit pre-flight #1792 lands), and appends a## /pr-ready deferred findingssection to the body when items are deferred/rejected;mainwith local changes / branch already has an open PR;/pr-readycommits added) and waits for explicity/nbefore pushing;#dev-sc-reviewvia/post-pr-for-review.Aikido findings reviewed: two findings on the skill file (template-read at line 72; Linear MCP at line 76) — both reviewed as false positives. The PR template is a checked-in public file with no secrets;
.husky/pre-commitscans for secrets + private keys before any commit lands (step 4); the step 9 pre-flight summary requires explicity/nbefore push. Linear is the team's own authenticated ticket tracker via MCP — not a third-party data sink — and branch/commit text becomes publicly visible atgit pushto this public repo seconds later anyway.Checklist before requesting a review
Checklist for reviewer (DO NOT DEPLOY and contracts BEFORE CHECKING THIS!!!)