Skip to content

Commit a81d5e0

Browse files
committed
chore: add repobuddy/agent-security skill
1 parent 8e53040 commit a81d5e0

2 files changed

Lines changed: 231 additions & 33 deletions

File tree

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
---
2+
name: fix-security-pr
3+
description: "Fix a PR that is failing due to security or vulnerability issues — npm/pnpm/yarn/bun audit failures, CVE alerts, Dependabot merge conflicts, Snyk failures, or GitHub security advisory blocks. Use when asked to 'fix the security PR', 'resolve the vulnerability failure', or 'unblock the Dependabot PR'."
4+
---
5+
6+
# Fix Security PR
7+
8+
Diagnose and remediate security/vulnerability failures in a pull request so CI passes.
9+
10+
## Step 1 — Identify the PR and failure
11+
12+
**Detect the PR:**
13+
- If a PR URL or number is provided, use it directly
14+
- If on a branch: `gh pr view --json number,url,headRefName,baseRefName`
15+
- If unspecified: list recent failing PRs: `gh pr list --state open --json number,title,url | grep -i -E "security|vuln|cve|dependabot|snyk|audit"`
16+
17+
**Read the failure:**
18+
19+
```bash
20+
gh run list --repo <owner>/<repo> --branch <branch> --limit 5 --json databaseId,conclusion,name
21+
gh run view <run-id> --log-failed 2>&1 | head -100
22+
```
23+
24+
Look for these patterns in the logs:
25+
26+
| Pattern | Source | Meaning |
27+
|---|---|---|
28+
| `npm audit` / `pnpm audit` / `yarn audit` exit non-zero | Audit step | Vulnerable dep in tree |
29+
| `High` / `Critical` severity advisory | Audit output | Specific CVE needs fixing |
30+
| `merge conflict` / `conflict` in PR | Git | Dependabot PR is stale; needs rebase |
31+
| `Snyk found` / `snyk test` failure | Snyk | Vulnerable dep detected by Snyk |
32+
| `GHSA-*` advisory ID | GitHub Advisory | Specific advisory blocking |
33+
34+
## Step 2 — Understand the vulnerability
35+
36+
Extract from the failure log:
37+
- **Package name** (e.g. `lodash`)
38+
- **Vulnerable version range** (e.g. `<4.17.21`)
39+
- **Safe version** (e.g. `>=4.17.21`)
40+
- **Severity** (critical / high / moderate / low)
41+
- **Advisory ID** (CVE or GHSA number)
42+
- **Whether it's a direct or transitive dependency**
43+
44+
For Dependabot PRs, also check:
45+
```bash
46+
gh pr view <number> --json body,title,commits
47+
```
48+
49+
## Step 3 — Detect package manager and repo type
50+
51+
| File | Package manager |
52+
|---|---|
53+
| `pnpm-lock.yaml` | pnpm |
54+
| `bun.lock` / `bun.lockb` | bun |
55+
| `yarn.lock` | yarn |
56+
| `package-lock.json` | npm |
57+
58+
Check for monorepo: `pnpm-workspace.yaml`, `workspaces` in root `package.json`, or `bun.workspace.ts`.
59+
60+
## Step 4 — Apply the fix
61+
62+
Choose the approach based on whether the dependency is direct or transitive:
63+
64+
### Direct dependency
65+
66+
Update the version in `package.json` to the safe version, then reinstall:
67+
68+
```bash
69+
# pnpm
70+
pnpm update <package>@<safe-version>
71+
72+
# npm
73+
npm install <package>@<safe-version>
74+
75+
# yarn
76+
yarn upgrade <package>@<safe-version>
77+
78+
# bun
79+
bun update <package>
80+
```
81+
82+
### Transitive dependency (you don't control the version directly)
83+
84+
Add an override to force the safe version across the entire tree:
85+
86+
**pnpm** (`package.json`):
87+
```json
88+
{
89+
"pnpm": {
90+
"overrides": {
91+
"<package>": ">=<safe-version>"
92+
}
93+
}
94+
}
95+
```
96+
97+
**npm** (`package.json`):
98+
```json
99+
{
100+
"overrides": {
101+
"<package>": ">=<safe-version>"
102+
}
103+
}
104+
```
105+
106+
**yarn** (`package.json`):
107+
```json
108+
{
109+
"resolutions": {
110+
"<package>": ">=<safe-version>"
111+
}
112+
}
113+
```
114+
115+
After adding the override, reinstall to regenerate the lockfile:
116+
```bash
117+
<pm> install
118+
```
119+
120+
### Dependabot PR with merge conflicts
121+
122+
The PR branch is stale. Rebase it onto the base branch:
123+
124+
```bash
125+
git fetch origin
126+
git checkout <dependabot-branch>
127+
git rebase origin/<base-branch>
128+
# resolve any conflicts
129+
git push --force-with-lease origin <dependabot-branch>
130+
```
131+
132+
If the conflict is in the lockfile, delete it and reinstall after resolving `package.json` conflicts:
133+
```bash
134+
rm <lockfile>
135+
<pm> install
136+
git add <lockfile>
137+
git rebase --continue
138+
```
139+
140+
### Monorepo: vulnerability in a workspace package
141+
142+
Check which workspace contains the vulnerable dep:
143+
```bash
144+
<pm> audit --json 2>/dev/null | jq '.vulnerabilities | to_entries[] | {pkg: .key, via: .value.via}'
145+
```
146+
147+
If the vulnerable dep is a transitive dep of a workspace, add the override to the **root** `package.json` (not the workspace's).
148+
149+
## Step 5 — Verify the fix locally
150+
151+
```bash
152+
# Confirm no remaining vulnerabilities at the severity level that was failing
153+
<pm> audit --audit-level=high # or: critical / moderate
154+
155+
# If Snyk is used
156+
npx snyk test
157+
```
158+
159+
If the audit still fails after fixing one package, check for additional advisories in the output and repeat Step 4 for each.
160+
161+
## Step 6 — Commit and push
162+
163+
```bash
164+
git add package.json <lockfile>
165+
git commit -m "fix: patch <package> vulnerability (<CVE-or-GHSA>)"
166+
git push origin <branch>
167+
```
168+
169+
For Dependabot PRs where you rebased with `--force-with-lease`, the push is already done in Step 4.
170+
171+
## Step 7 — Re-trigger CI and verify
172+
173+
```bash
174+
# Watch the new run
175+
gh run list --branch <branch> --limit 3
176+
gh run watch <new-run-id>
177+
```
178+
179+
If CI passes, the PR is unblocked. If another security failure appears, return to Step 2 for the next advisory.
180+
181+
## Edge cases
182+
183+
**Audit level mismatch:** CI may fail on `moderate` while you're checking `high`. Check the CI command's `--audit-level` flag and match it when verifying locally.
184+
185+
**No safe version exists yet:** If the advisory has no fix available, options are:
186+
1. Remove the package entirely if it's not truly needed
187+
2. Add the package to an audit ignore list (`.nsprc`, `auditignore`, or `--ignore` flag) and leave a comment explaining why — inform the user before doing this
188+
3. Wait for upstream to release a fix; inform the user
189+
190+
**Private registry:** If `npm audit` / `pnpm audit` fails to reach the registry, check for `.npmrc` or `.pnpmrc` with a private registry URL. The fix process is the same; just ensure the registry is reachable in CI.
191+
192+
**Dependabot already auto-merged:** Check if the PR is still open before starting. If it merged and CI still fails on `main`, the vulnerability is in the base branch — treat it as a direct fix to `main`, not a PR fix.

skills-lock.json

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,41 @@
11
{
2-
"version": 1,
3-
"skills": {
4-
"add-changeset": {
5-
"source": "repobuddy/agent-changesets",
6-
"sourceType": "github",
7-
"skillPath": "skills/add-changeset/SKILL.md",
8-
"computedHash": "8a5266fe92b2f9f755238564e44b5b44e1b5ce0a469d5659c1b03d49dd590dd1"
9-
},
10-
"create-skill": {
11-
"source": "repobuddy/agent-changesets",
12-
"sourceType": "github",
13-
"skillPath": ".agents/skills/create-skill/SKILL.md",
14-
"computedHash": "6f7a5b9959fb330b0fa8308dadca1df6bb654b578aedeb976fb445c62b31f5eb"
15-
},
16-
"init": {
17-
"source": "repobuddy/agent-changesets",
18-
"sourceType": "github",
19-
"skillPath": ".agents/skills/init/SKILL.md",
20-
"computedHash": "3b7fe09f0412d2607040b48d1a976fd5a3a690a6da7233b6d9c7a45ca11898ef"
21-
},
22-
"setup-changesets": {
23-
"source": "repobuddy/agent-changesets",
24-
"sourceType": "github",
25-
"skillPath": "skills/setup-changesets/SKILL.md",
26-
"computedHash": "6ee922527e013544ff5f739dea8fe6e178caa9629e123a29793776f485ff2e8e"
27-
},
28-
"validate-skill": {
29-
"source": "repobuddy/agent-changesets",
30-
"sourceType": "github",
31-
"skillPath": ".agents/skills/validate-skill/SKILL.md",
32-
"computedHash": "dac87a91e49948a897a82b4df7b5a1b5ef9f3600908282e92731d2e2151d9427"
33-
}
34-
}
2+
"version": 1,
3+
"skills": {
4+
"add-changeset": {
5+
"source": "repobuddy/agent-changesets",
6+
"sourceType": "github",
7+
"skillPath": "skills/add-changeset/SKILL.md",
8+
"computedHash": "8a5266fe92b2f9f755238564e44b5b44e1b5ce0a469d5659c1b03d49dd590dd1"
9+
},
10+
"create-skill": {
11+
"source": "repobuddy/agent-changesets",
12+
"sourceType": "github",
13+
"skillPath": ".agents/skills/create-skill/SKILL.md",
14+
"computedHash": "6f7a5b9959fb330b0fa8308dadca1df6bb654b578aedeb976fb445c62b31f5eb"
15+
},
16+
"fix-security-pr": {
17+
"source": "repobuddy/agent-security",
18+
"sourceType": "github",
19+
"skillPath": "skills/fix-security-pr/SKILL.md",
20+
"computedHash": "d78b2e51db20d5e19948faa0428ef3a1d51efed14706d4dc58cea2dfc6ef6530"
21+
},
22+
"init": {
23+
"source": "repobuddy/agent-changesets",
24+
"sourceType": "github",
25+
"skillPath": ".agents/skills/init/SKILL.md",
26+
"computedHash": "3b7fe09f0412d2607040b48d1a976fd5a3a690a6da7233b6d9c7a45ca11898ef"
27+
},
28+
"setup-changesets": {
29+
"source": "repobuddy/agent-changesets",
30+
"sourceType": "github",
31+
"skillPath": "skills/setup-changesets/SKILL.md",
32+
"computedHash": "6ee922527e013544ff5f739dea8fe6e178caa9629e123a29793776f485ff2e8e"
33+
},
34+
"validate-skill": {
35+
"source": "repobuddy/agent-changesets",
36+
"sourceType": "github",
37+
"skillPath": ".agents/skills/validate-skill/SKILL.md",
38+
"computedHash": "dac87a91e49948a897a82b4df7b5a1b5ef9f3600908282e92731d2e2151d9427"
39+
}
40+
}
3541
}

0 commit comments

Comments
 (0)