dryrun-pr-review
Use when the user asks to create a pull request or merge request, submit changes for review, push for review, or open a pull request.
What this skill does
# DryRunSecurity PR Review Workflow Full PR lifecycle: detect platform, branch, commit, open a PR, poll for DryRunSecurity comments, present findings to the user. ## Platform Detection & Repo Info Run this and read the output to determine platform and repo coordinates: ```bash git remote get-url origin ``` From the URL: - Contains `github.com` → GitHub; use `gh` CLI. Extract `OWNER` and `REPO` from the URL path. - Otherwise → GitLab; use `glab` CLI. Extract the project path and URL-encode it (replace `/` with `%2F`) for API calls. All subsequent steps reference `PLATFORM`, `OWNER`, `REPO` (GitHub) or `PROJECT` (GitLab), and `PR_NUMBER`. ## Workflow ### 1. Branch If on `main`/`master`, create a new branch following this repo's naming conventions. Otherwise use the existing feature branch. ### 2. Stage & Commit ```bash git status git add <files> # selective — never commit secrets or generated files git commit -m "<message following this repo's commit style> Co-Authored-By: DryRun Security <[email protected]>" ``` ### 3. Push & Open PR ```bash git push -u origin <branch-name> ``` Check whether a pull request already exists for this branch before creating one: ```bash # GitHub — reuse existing PR if present EXISTING=$(gh pr view --json number --jq '.number' 2>/dev/null) if [ -n "$EXISTING" ]; then echo "Using existing PR #$EXISTING" PR_NUMBER=$EXISTING else gh pr create --title "<title>" --body "<body>" # capture PR_NUMBER from the URL in the output (last path segment) fi # GitLab — reuse existing MR if present BRANCH=$(git rev-parse --abbrev-ref HEAD) EXISTING=$(glab mr list --source-branch "$BRANCH" 2>/dev/null | awk 'NR==2{print $1}' | tr -d '!') if [ -n "$EXISTING" ]; then echo "Using existing PR !$EXISTING" PR_NUMBER=$EXISTING else glab mr create --title "<title>" --description "<body>" # capture PR_NUMBER from the output fi ``` Store the result as `PR_NUMBER`. ### 4. Poll for DryRunSecurity Review Comments Poll for up to **10 minutes** (every 30 seconds). Use timestamp-based polling — not count-based. Comments can be edited/replaced. Exit as soon as DRS activity is detected — a DryRunSecurity comment means the review is complete. ```bash START_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") START_EPOCH=$(date +%s) TIMEOUT=600 POLL_INTERVAL=30 while true; do ELAPSED=$(( $(date +%s) - START_EPOCH )) if [ $ELAPSED -ge $TIMEOUT ]; then echo "Timed out after ${ELAPSED}s with no DryRunSecurity activity." break fi if [ "$PLATFORM" = "github" ]; then DRS_NEW=$(gh api repos/${OWNER}/${REPO}/issues/${PR_NUMBER}/comments \ --jq "[.[] | select((.user.login == \"dryrunsecurity\" or .user.login == \"dryrunsecurity[bot]\") and .created_at > \"${START_TIME}\")] | length") DRS_REVIEWS=$(gh api repos/${OWNER}/${REPO}/pulls/${PR_NUMBER}/reviews \ --jq "[.[] | select((.user.login | test(\"dryrunsecurity\"; \"i\")) and .submitted_at > \"${START_TIME}\")] | length") TOTAL=$(( DRS_NEW + DRS_REVIEWS )) echo "Waiting for DryRunSecurity review... (${ELAPSED}s elapsed)" [ "$TOTAL" -gt 0 ] && echo "DryRunSecurity review received: ${DRS_NEW} comment(s), ${DRS_REVIEWS} review(s)." && break else DRS_NEW=$(glab api projects/${PROJECT}/merge_requests/${PR_NUMBER}/notes \ | jq "[.[] | select(.author.username == \"dryrunsecurity\" and .created_at > \"${START_TIME}\")] | length") echo "Waiting for DryRunSecurity review... (${ELAPSED}s elapsed)" [ "$DRS_NEW" -gt 0 ] && echo "DryRunSecurity review received: ${DRS_NEW} note(s)." && break fi sleep $POLL_INTERVAL done ``` If the loop timed out with no DRS activity, inform the user: the DryRunSecurity review period is complete. ### 5. Present DryRunSecurity Comments to User Fetch all DryRunSecurity comments and **present them to the user** — do not fix automatically. ```bash # GitHub gh api repos/${OWNER}/${REPO}/issues/${PR_NUMBER}/comments \ --jq '.[] | select(.user.login == "dryrunsecurity" or .user.login == "dryrunsecurity[bot]") | {id: .id, body: .body}' gh api repos/${OWNER}/${REPO}/pulls/${PR_NUMBER}/reviews \ --jq '.[] | select(.user.login | test("dryrunsecurity"; "i")) | {id: .id, body: .body, state: .state}' # GitLab glab api projects/${PROJECT}/merge_requests/${PR_NUMBER}/notes \ | jq '.[] | select(.author.username == "dryrunsecurity") | {id: .id, body: .body}' ``` For each comment, present: - File:line (if applicable) - Summary of the security finding - Your suggested fix or reason it's a false positive Then **ask the user** which comments to address and how. ### 6. Act on User Decisions For comments the user wants fixed: ```bash # Make code changes, then: git add <files> git commit -m "<message following this repo's commit style — addressing DryRunSecurity finding> Co-Authored-By: Claude <[email protected]>" ``` For comments the user wants to decline, post a new comment on the PR thread explaining why: ```bash # GitHub — DryRunSecurity posts on the PR thread (not inline), so reply via issue comments gh api repos/${OWNER}/${REPO}/issues/${PR_NUMBER}/comments \ -f body="Not addressing DryRunSecurity finding: <explanation>" # GitLab glab api projects/${PROJECT}/merge_requests/${PR_NUMBER}/notes \ --method POST -f body="Not addressing DryRunSecurity finding: <explanation>" ``` ### 7. Push & Re-poll ```bash git push ``` Return to Step 4 using the current time as the new `START_TIME`. Continue until polling times out with no new comments. ## Important Notes - Never force push unless explicitly requested - Always read files before suggesting changes - Use `gh` for GitHub repos, `glab` for GitLab repos — detect via `git remote get-url origin` - Timestamp-based polling only — never count-based - **Minimize Bash invocations** — consolidate related commands into single scripts (e.g., combine `git add` + `git commit` + `git push` into one call). Each separate Bash call is a potential permission prompt for the user. - The polling loop in Step 4 must remain a single Bash invocation — do not break it into multiple calls
Related in Code Review
gstack
IncludedFast headless browser for QA testing and site dogfooding. Navigate pages, interact with elements, verify state, diff before/after, take annotated screenshots, test responsive layouts, forms, uploads, dialogs, and capture bug evidence. Use when asked to open or test a site, verify a deployment, dogfood a user flow, or file a bug with screenshots. (gstack)
startup-due-diligence
IncludedLegal due diligence review for seed-stage and Series A startups (US, Delaware C-Corp focus). Supports both investor and founder perspectives. Capabilities include: (1) Interactive document review and issue spotting; (2) Document request list generation; (3) Cap table and SAFE/convertible note analysis; (4) Red flag identification with severity ratings; (5) Diligence report generation. TRIGGERS: due diligence, DD, startup investment, cap table review, Series A, seed round, investor diligence, legal review startup, SAFE analysis, convertible note, 409A, founder vesting.
interview-master
IncludedThis skill should be used when the user asks to "generate interview questions", "prepare for interview", "optimize resume", "conduct mock interview", "analyze git commits for resume", "generate resume from code", "review my resume", or mentions interview preparation, career assistance, or extracting project experience from git history. Provides comprehensive interview and career development guidance for both job seekers and interviewers.
fix-issue
IncludedFixes GitHub issues using parallel analysis agents for root cause investigation, code exploration, and regression detection. Reads issue context from gh CLI, searches codebase and memory for related patterns, generates a fix with tests, and links the resolution back to the issue via PR. Includes prevention analysis to avoid recurrence. Use when debugging errors, resolving regressions, fixing bugs, or triaging issues.
sf-apex
IncludedGenerates and reviews Salesforce Apex code with 150-point scoring. TRIGGER when: user writes, reviews, or fixes Apex classes, triggers, test classes, batch/queueable/schedulable jobs, or touches .cls/.trigger files. DO NOT TRIGGER when: LWC JavaScript (use sf-lwc), Flow XML (use sf-flow), SOQL-only queries (use sf-soql), or non-Salesforce code.
swift-development
IncludedComprehensive Swift development for building, testing, and deploying iOS/macOS applications. Use when Claude needs to: (1) Build Swift packages or Xcode projects from command line, (2) Run tests with XCTest or Swift Testing framework, (3) Manage iOS simulators with simctl, (4) Handle code signing, provisioning profiles, and app distribution, (5) Format or lint Swift code with SwiftFormat/SwiftLint, (6) Work with Swift Package Manager (SPM), (7) Implement Swift 6 concurrency patterns (async/await, actors, Sendable), (8) Create SwiftUI views with MVVM architecture, (9) Set up Core Data or SwiftData persistence, or any other Swift/iOS/macOS development tasks.