sequant 1.11.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +86 -2
- package/dist/src/lib/ac-linter.d.ts +116 -0
- package/dist/src/lib/ac-linter.js +304 -0
- package/dist/src/lib/plugin-version-sync.d.ts +26 -0
- package/dist/src/lib/plugin-version-sync.js +91 -0
- package/dist/src/lib/project-name.d.ts +40 -0
- package/dist/src/lib/project-name.js +191 -0
- package/dist/src/lib/semgrep.d.ts +136 -0
- package/dist/src/lib/semgrep.js +406 -0
- package/dist/src/lib/stacks.d.ts +14 -0
- package/dist/src/lib/stacks.js +159 -0
- package/dist/src/lib/templates.js +9 -3
- package/package.json +1 -1
- package/templates/hooks/pre-tool.sh +6 -0
- package/templates/memory/constitution.md +1 -5
- package/templates/skills/_shared/references/prompt-templates.md +350 -0
- package/templates/skills/_shared/references/subagent-types.md +131 -0
- package/templates/skills/exec/SKILL.md +82 -0
- package/templates/skills/fullsolve/SKILL.md +19 -2
- package/templates/skills/loop/SKILL.md +3 -1
- package/templates/skills/qa/SKILL.md +79 -9
- package/templates/skills/qa/references/quality-gates.md +85 -1
- package/templates/skills/qa/references/semgrep-rules.md +207 -0
- package/templates/skills/qa/scripts/quality-checks.sh +54 -0
- package/templates/skills/spec/SKILL.md +215 -4
|
@@ -16,6 +16,9 @@ allowed-tools:
|
|
|
16
16
|
- Bash(gh pr view:*)
|
|
17
17
|
- Bash(gh pr diff:*)
|
|
18
18
|
- Bash(gh pr comment:*)
|
|
19
|
+
- Bash(semgrep:*)
|
|
20
|
+
- Bash(npx semgrep:*)
|
|
21
|
+
- Bash(npx tsx scripts/semgrep-scan.ts:*)
|
|
19
22
|
- Task
|
|
20
23
|
- AgentOutputTool
|
|
21
24
|
---
|
|
@@ -120,11 +123,11 @@ If no feature worktree exists (work was done directly on main):
|
|
|
120
123
|
|
|
121
124
|
**Spawn ALL THREE agents in a SINGLE message:**
|
|
122
125
|
|
|
123
|
-
1. `Task(subagent_type="
|
|
126
|
+
1. `Task(subagent_type="general-purpose", model="haiku", prompt="Run type safety and deleted tests checks on the current branch vs main. Report: type issues count, deleted tests, verdict.")`
|
|
124
127
|
|
|
125
|
-
2. `Task(subagent_type="
|
|
128
|
+
2. `Task(subagent_type="general-purpose", model="haiku", prompt="Run scope and size checks on the current branch vs main. Report: files count, diff size, size assessment.")`
|
|
126
129
|
|
|
127
|
-
3. `Task(subagent_type="
|
|
130
|
+
3. `Task(subagent_type="general-purpose", model="haiku", prompt="Run security scan on changed files in current branch vs main. Report: critical/warning/info counts, verdict.")`
|
|
128
131
|
|
|
129
132
|
**Add RLS check if admin files modified:**
|
|
130
133
|
```bash
|
|
@@ -133,10 +136,52 @@ admin_modified=$(git diff main...HEAD --name-only | grep -E "^app/admin/" | head
|
|
|
133
136
|
|
|
134
137
|
See [quality-gates.md](references/quality-gates.md) for detailed verdict synthesis.
|
|
135
138
|
|
|
136
|
-
###
|
|
139
|
+
### MCP Tools (Optional - Graceful Degradation)
|
|
137
140
|
|
|
138
|
-
|
|
139
|
-
|
|
141
|
+
MCP tools enhance `/qa` but are **not required**. The skill works fully without them.
|
|
142
|
+
|
|
143
|
+
#### MCP Availability Check
|
|
144
|
+
|
|
145
|
+
Before using MCP tools, verify they are available. If unavailable, use the fallback strategies.
|
|
146
|
+
|
|
147
|
+
| MCP Tool | Purpose | Fallback When Unavailable |
|
|
148
|
+
|----------|---------|---------------------------|
|
|
149
|
+
| Sequential Thinking | Complex multi-step analysis | Use explicit step-by-step reasoning in response |
|
|
150
|
+
| Context7 | Library documentation lookup | Use WebSearch or codebase pattern search |
|
|
151
|
+
|
|
152
|
+
#### Sequential Thinking Fallback
|
|
153
|
+
|
|
154
|
+
**When to use Sequential Thinking:**
|
|
155
|
+
- Complex architectural trade-offs during code review
|
|
156
|
+
- Multi-dimensional quality assessment
|
|
157
|
+
- Analyzing interconnected issues across files
|
|
158
|
+
|
|
159
|
+
**If unavailable:**
|
|
160
|
+
1. Structure your analysis with explicit numbered steps
|
|
161
|
+
2. Document each concern systematically before synthesizing verdict
|
|
162
|
+
3. Use a pros/cons format for trade-off decisions
|
|
163
|
+
|
|
164
|
+
```markdown
|
|
165
|
+
## Analysis Steps (Manual Sequential Thinking)
|
|
166
|
+
|
|
167
|
+
**Step 1:** [Analyze first dimension - correctness]
|
|
168
|
+
**Step 2:** [Analyze second dimension - maintainability]
|
|
169
|
+
**Step 3:** [Analyze third dimension - performance]
|
|
170
|
+
**Step 4:** [Synthesize findings into verdict]
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
#### Context7 Fallback
|
|
174
|
+
|
|
175
|
+
**When to use Context7:**
|
|
176
|
+
- Verifying implementation matches library best practices
|
|
177
|
+
- Checking if API usage follows recommended patterns
|
|
178
|
+
- Understanding framework-specific conventions in reviewed code
|
|
179
|
+
|
|
180
|
+
**If unavailable:**
|
|
181
|
+
1. Search codebase with Grep for existing usage patterns
|
|
182
|
+
2. Use WebSearch for official library documentation
|
|
183
|
+
3. Check similar implementations in the codebase as reference
|
|
184
|
+
4. Review library's README or documentation in node_modules
|
|
140
185
|
|
|
141
186
|
### 1. Context and AC Alignment
|
|
142
187
|
|
|
@@ -180,9 +225,32 @@ See [testing-requirements.md](references/testing-requirements.md) for edge case
|
|
|
180
225
|
|
|
181
226
|
Provide an overall verdict:
|
|
182
227
|
|
|
183
|
-
- `READY_FOR_MERGE` —
|
|
184
|
-
- `AC_MET_BUT_NOT_A_PLUS` —
|
|
185
|
-
- `
|
|
228
|
+
- `READY_FOR_MERGE` — ALL ACs are `MET` and code quality is high ("A+")
|
|
229
|
+
- `AC_MET_BUT_NOT_A_PLUS` — ALL ACs are `MET`, but meaningful improvements recommended
|
|
230
|
+
- `NEEDS_VERIFICATION` — ALL ACs are `MET` or `PENDING`, at least one requires external verification
|
|
231
|
+
- `AC_NOT_MET` — One or more ACs are `NOT_MET` or `PARTIALLY_MET`
|
|
232
|
+
|
|
233
|
+
**Verdict Determination Algorithm (REQUIRED):**
|
|
234
|
+
|
|
235
|
+
```text
|
|
236
|
+
1. Count AC statuses:
|
|
237
|
+
- met_count = ACs with status MET
|
|
238
|
+
- partial_count = ACs with status PARTIALLY_MET
|
|
239
|
+
- pending_count = ACs with status PENDING
|
|
240
|
+
- not_met_count = ACs with status NOT_MET
|
|
241
|
+
|
|
242
|
+
2. Determine verdict (in order):
|
|
243
|
+
- IF not_met_count > 0 OR partial_count > 0:
|
|
244
|
+
→ AC_NOT_MET (block merge)
|
|
245
|
+
- ELSE IF pending_count > 0:
|
|
246
|
+
→ NEEDS_VERIFICATION (wait for verification)
|
|
247
|
+
- ELSE IF improvement_suggestions.length > 0:
|
|
248
|
+
→ AC_MET_BUT_NOT_A_PLUS (can merge with notes)
|
|
249
|
+
- ELSE:
|
|
250
|
+
→ READY_FOR_MERGE (A+ implementation)
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
**CRITICAL:** `PARTIALLY_MET` is NOT sufficient for merge. It MUST be treated as `NOT_MET` for verdict purposes.
|
|
186
254
|
|
|
187
255
|
See [quality-gates.md](references/quality-gates.md) for detailed verdict criteria.
|
|
188
256
|
|
|
@@ -221,9 +289,11 @@ Produce a Markdown snippet for the PR/issue:
|
|
|
221
289
|
### 7. Update GitHub Issue
|
|
222
290
|
|
|
223
291
|
Post the draft comment to GitHub and update labels:
|
|
292
|
+
|
|
224
293
|
- `AC_NOT_MET`: add `needs-work` label
|
|
225
294
|
- `READY_FOR_MERGE`: add `ready-for-review` label
|
|
226
295
|
- `AC_MET_BUT_NOT_A_PLUS`: add `needs-improvement` label
|
|
296
|
+
- `NEEDS_VERIFICATION`: add `needs-verification` label
|
|
227
297
|
|
|
228
298
|
### 8. Documentation Reminder
|
|
229
299
|
|
|
@@ -9,14 +9,56 @@ Combine agent outputs into a unified quality assessment:
|
|
|
9
9
|
| Type Safety Checker | Type issues count, verdict | High - blocking if issues > 3 |
|
|
10
10
|
| Scope/Size Checker | Files changed, LOC, assessment | Medium - warning if very large |
|
|
11
11
|
| Security Scanner | Critical/warning/info counts | High - blocking if criticals > 0 |
|
|
12
|
+
| Semgrep Static Analysis | Critical/warning findings | High - blocking if criticals > 0 |
|
|
12
13
|
| RLS Checker (conditional) | Violations found | High - blocking if violations |
|
|
13
14
|
|
|
14
15
|
**Synthesis Rules:**
|
|
15
16
|
- **Any FAIL verdict** → Flag as blocker in manual review
|
|
16
|
-
- **Security criticals** → Block merge, require fix before proceeding
|
|
17
|
+
- **Security criticals (including Semgrep)** → Block merge, require fix before proceeding
|
|
17
18
|
- **All PASS** → Proceed with confidence to manual review
|
|
18
19
|
- **WARN verdicts** → Note in review, verify manually
|
|
19
20
|
|
|
21
|
+
## Semgrep Integration
|
|
22
|
+
|
|
23
|
+
Semgrep provides static analysis for security vulnerabilities and anti-patterns.
|
|
24
|
+
|
|
25
|
+
### Verdict Mapping
|
|
26
|
+
|
|
27
|
+
| Semgrep Result | QA Verdict Impact |
|
|
28
|
+
|----------------|-------------------|
|
|
29
|
+
| Critical findings > 0 | **BLOCKING** - `AC_NOT_MET` |
|
|
30
|
+
| Warning findings only | Non-blocking - note in review |
|
|
31
|
+
| No findings | Pass - no impact |
|
|
32
|
+
| Semgrep not installed | Skipped - graceful degradation |
|
|
33
|
+
| Semgrep error | Non-blocking - log error |
|
|
34
|
+
|
|
35
|
+
### Output Format
|
|
36
|
+
|
|
37
|
+
```markdown
|
|
38
|
+
## Static Analysis (Semgrep)
|
|
39
|
+
|
|
40
|
+
✅ No critical findings
|
|
41
|
+
⚠️ 2 warnings:
|
|
42
|
+
- src/api/users.ts:47 - Potential SQL injection (user input in query)
|
|
43
|
+
- src/utils/exec.ts:12 - Command injection risk (unsanitized shell arg)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Stack-Aware Rulesets
|
|
47
|
+
|
|
48
|
+
Semgrep uses stack-specific rulesets for targeted analysis:
|
|
49
|
+
|
|
50
|
+
| Stack | Rulesets |
|
|
51
|
+
|-------|----------|
|
|
52
|
+
| Next.js | p/typescript, p/javascript, p/react, p/security-audit, p/secrets |
|
|
53
|
+
| Python | p/python, p/django, p/flask, p/security-audit, p/secrets |
|
|
54
|
+
| Go | p/golang, p/security-audit, p/secrets |
|
|
55
|
+
| Rust | p/rust, p/security-audit, p/secrets |
|
|
56
|
+
| Generic | p/security-audit, p/secrets |
|
|
57
|
+
|
|
58
|
+
### Custom Rules
|
|
59
|
+
|
|
60
|
+
Projects can add custom rules in `.sequant/semgrep-rules.yaml`. These are loaded alongside stack rules automatically.
|
|
61
|
+
|
|
20
62
|
## Verdict Criteria
|
|
21
63
|
|
|
22
64
|
### `READY_FOR_MERGE`
|
|
@@ -43,6 +85,17 @@ AC met, but one or more issues:
|
|
|
43
85
|
|
|
44
86
|
**Action:** List specific improvements, but don't block merge if working
|
|
45
87
|
|
|
88
|
+
### `NEEDS_VERIFICATION`
|
|
89
|
+
|
|
90
|
+
All AC items are `MET`, but one or more items have `PENDING` status requiring external verification:
|
|
91
|
+
|
|
92
|
+
- ⏳ CI/CD verification pending
|
|
93
|
+
- ⏳ Manual testing not yet performed
|
|
94
|
+
- ⏳ External dependency verification needed
|
|
95
|
+
- ⏳ Production environment validation required
|
|
96
|
+
|
|
97
|
+
**Action:** Complete pending verification, then re-run `/qa`
|
|
98
|
+
|
|
46
99
|
### `AC_NOT_MET`
|
|
47
100
|
|
|
48
101
|
Any of:
|
|
@@ -55,6 +108,37 @@ Any of:
|
|
|
55
108
|
|
|
56
109
|
**Action:** Block merge, list required fixes
|
|
57
110
|
|
|
111
|
+
## Verdict Determination Algorithm
|
|
112
|
+
|
|
113
|
+
**CRITICAL:** Follow this algorithm exactly when determining the verdict. Do NOT give `READY_FOR_MERGE` unless ALL conditions are met.
|
|
114
|
+
|
|
115
|
+
```text
|
|
116
|
+
1. Count AC statuses:
|
|
117
|
+
- met_count = ACs with status MET
|
|
118
|
+
- partial_count = ACs with status PARTIALLY_MET
|
|
119
|
+
- pending_count = ACs with status PENDING
|
|
120
|
+
- not_met_count = ACs with status NOT_MET
|
|
121
|
+
|
|
122
|
+
2. Determine verdict (in order):
|
|
123
|
+
- IF not_met_count > 0 OR partial_count > 0:
|
|
124
|
+
→ AC_NOT_MET (block merge)
|
|
125
|
+
- ELSE IF pending_count > 0:
|
|
126
|
+
→ NEEDS_VERIFICATION (wait for verification)
|
|
127
|
+
- ELSE IF improvement_suggestions.length > 0:
|
|
128
|
+
→ AC_MET_BUT_NOT_A_PLUS (can merge with notes)
|
|
129
|
+
- ELSE:
|
|
130
|
+
→ READY_FOR_MERGE (A+ implementation)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
| Verdict | When to Use |
|
|
134
|
+
|--------------------------|----------------------------------------------------------|
|
|
135
|
+
| `READY_FOR_MERGE` | ALL ACs are `MET`, no improvements needed |
|
|
136
|
+
| `AC_MET_BUT_NOT_A_PLUS` | ALL ACs are `MET`, but minor improvements suggested |
|
|
137
|
+
| `NEEDS_VERIFICATION` | ALL ACs are `MET` or `PENDING`, at least one is `PENDING`|
|
|
138
|
+
| `AC_NOT_MET` | ANY AC is `NOT_MET` or `PARTIALLY_MET` |
|
|
139
|
+
|
|
140
|
+
**Important:** `PARTIALLY_MET` is NOT sufficient for merge. It must be treated as `NOT_MET` for verdict purposes.
|
|
141
|
+
|
|
58
142
|
## Code Review Decision Framework
|
|
59
143
|
|
|
60
144
|
### 1. Purpose Test
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# Semgrep Integration Guide
|
|
2
|
+
|
|
3
|
+
This guide explains how to configure and use Semgrep static analysis in the `/qa` workflow.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Semgrep is a fast, open-source static analysis tool that finds bugs and enforces code standards. The `/qa` skill integrates Semgrep to automatically scan code changes for security vulnerabilities and anti-patterns.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
Semgrep is **optional**. If not installed, the `/qa` skill will gracefully skip Semgrep analysis.
|
|
12
|
+
|
|
13
|
+
### Install Semgrep
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Using pip (recommended)
|
|
17
|
+
pip install semgrep
|
|
18
|
+
|
|
19
|
+
# Using Homebrew (macOS)
|
|
20
|
+
brew install semgrep
|
|
21
|
+
|
|
22
|
+
# Using npm (via npx - no install required)
|
|
23
|
+
npx semgrep --version
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Verify Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
semgrep --version
|
|
30
|
+
# Or
|
|
31
|
+
npx semgrep --version
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## How It Works
|
|
35
|
+
|
|
36
|
+
1. During `/qa`, the quality checks script detects if Semgrep is installed
|
|
37
|
+
2. If installed, it runs Semgrep with stack-appropriate rulesets
|
|
38
|
+
3. Findings are categorized by severity (critical, warning, info)
|
|
39
|
+
4. Critical findings block the merge verdict (`AC_NOT_MET`)
|
|
40
|
+
5. Warnings are noted but don't block merges
|
|
41
|
+
|
|
42
|
+
## Default Rulesets
|
|
43
|
+
|
|
44
|
+
Semgrep uses stack-specific rulesets for targeted analysis:
|
|
45
|
+
|
|
46
|
+
| Stack | Rulesets Applied |
|
|
47
|
+
|-------|------------------|
|
|
48
|
+
| **Next.js** | p/typescript, p/javascript, p/react, p/security-audit, p/secrets |
|
|
49
|
+
| **Astro** | p/typescript, p/javascript, p/security-audit, p/secrets |
|
|
50
|
+
| **SvelteKit** | p/typescript, p/javascript, p/security-audit, p/secrets |
|
|
51
|
+
| **Remix** | p/typescript, p/javascript, p/react, p/security-audit, p/secrets |
|
|
52
|
+
| **Nuxt** | p/typescript, p/javascript, p/security-audit, p/secrets |
|
|
53
|
+
| **Python** | p/python, p/django, p/flask, p/security-audit, p/secrets |
|
|
54
|
+
| **Go** | p/golang, p/security-audit, p/secrets |
|
|
55
|
+
| **Rust** | p/rust, p/security-audit, p/secrets |
|
|
56
|
+
| **Generic** | p/security-audit, p/secrets |
|
|
57
|
+
|
|
58
|
+
## Custom Rules
|
|
59
|
+
|
|
60
|
+
You can add project-specific rules by creating `.sequant/semgrep-rules.yaml` in your project root.
|
|
61
|
+
|
|
62
|
+
### Getting Started
|
|
63
|
+
|
|
64
|
+
Copy the example template to your project:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Copy the example template
|
|
68
|
+
cp docs/examples/semgrep-rules.example.yaml .sequant/semgrep-rules.yaml
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Custom Rules File Location
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
your-project/
|
|
75
|
+
├── .sequant/
|
|
76
|
+
│ └── semgrep-rules.yaml # Your custom rules
|
|
77
|
+
├── src/
|
|
78
|
+
└── package.json
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Example Custom Rules
|
|
82
|
+
|
|
83
|
+
```yaml
|
|
84
|
+
rules:
|
|
85
|
+
# Prevent console.log in production code
|
|
86
|
+
- id: no-console-log
|
|
87
|
+
pattern: console.log(...)
|
|
88
|
+
message: "Remove console.log before merging"
|
|
89
|
+
severity: WARNING
|
|
90
|
+
languages: [typescript, javascript]
|
|
91
|
+
paths:
|
|
92
|
+
exclude:
|
|
93
|
+
- "**/*.test.*"
|
|
94
|
+
- "**/__tests__/**"
|
|
95
|
+
|
|
96
|
+
# Require explicit return types on exported functions
|
|
97
|
+
- id: explicit-return-type
|
|
98
|
+
pattern: |
|
|
99
|
+
export function $FUNC(...): $RET { ... }
|
|
100
|
+
pattern-not: |
|
|
101
|
+
export function $FUNC(...): void { ... }
|
|
102
|
+
message: "Exported functions should have explicit return types"
|
|
103
|
+
severity: INFO
|
|
104
|
+
languages: [typescript]
|
|
105
|
+
|
|
106
|
+
# Detect potential SQL injection
|
|
107
|
+
- id: sql-injection-risk
|
|
108
|
+
patterns:
|
|
109
|
+
- pattern: $DB.query($SQL + ...)
|
|
110
|
+
- pattern: $DB.query(`...${...}...`)
|
|
111
|
+
message: "Potential SQL injection - use parameterized queries"
|
|
112
|
+
severity: ERROR
|
|
113
|
+
languages: [typescript, javascript]
|
|
114
|
+
|
|
115
|
+
# Prevent hardcoded API keys
|
|
116
|
+
- id: no-hardcoded-api-key
|
|
117
|
+
pattern-regex: "(api[_-]?key|apikey|secret[_-]?key)\\s*[:=]\\s*['\"][^'\"]{8,}['\"]"
|
|
118
|
+
message: "Don't hardcode API keys - use environment variables"
|
|
119
|
+
severity: ERROR
|
|
120
|
+
languages: [typescript, javascript, python]
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Rule Severity Levels
|
|
124
|
+
|
|
125
|
+
| Severity | Verdict Impact | Description |
|
|
126
|
+
|----------|----------------|-------------|
|
|
127
|
+
| `ERROR` | **Blocking** | Critical issues that must be fixed |
|
|
128
|
+
| `WARNING` | Non-blocking | Issues that should be reviewed |
|
|
129
|
+
| `INFO` | Non-blocking | Style suggestions |
|
|
130
|
+
|
|
131
|
+
## Running Semgrep Manually
|
|
132
|
+
|
|
133
|
+
You can run Semgrep manually using the provided script:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
# Scan entire project with auto-detected stack
|
|
137
|
+
npx tsx scripts/semgrep-scan.ts
|
|
138
|
+
|
|
139
|
+
# Scan only changed files (faster, recommended)
|
|
140
|
+
npx tsx scripts/semgrep-scan.ts --changed-only
|
|
141
|
+
|
|
142
|
+
# Scan specific directories
|
|
143
|
+
npx tsx scripts/semgrep-scan.ts src/api/ src/lib/
|
|
144
|
+
|
|
145
|
+
# Override detected stack
|
|
146
|
+
npx tsx scripts/semgrep-scan.ts --stack python
|
|
147
|
+
|
|
148
|
+
# Get JSON output
|
|
149
|
+
npx tsx scripts/semgrep-scan.ts --json > semgrep-results.json
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Interpreting Results
|
|
153
|
+
|
|
154
|
+
### Clean Output
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
## Static Analysis (Semgrep)
|
|
158
|
+
|
|
159
|
+
✅ No security issues found
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Issues Found
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
## Static Analysis (Semgrep)
|
|
166
|
+
|
|
167
|
+
❌ 1 critical finding(s)
|
|
168
|
+
⚠️ 2 warning(s)
|
|
169
|
+
|
|
170
|
+
### ❌ Critical Issues
|
|
171
|
+
|
|
172
|
+
- `src/api/users.ts:47` - Potential SQL injection (user input in query) (security.sql-injection)
|
|
173
|
+
|
|
174
|
+
### ⚠️ Warnings
|
|
175
|
+
|
|
176
|
+
- `src/utils/exec.ts:12` - Command injection risk (unsanitized shell arg) (security.command-injection)
|
|
177
|
+
- `src/lib/logger.ts:8` - Remove console.log before merging (custom.no-console-log)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Troubleshooting
|
|
181
|
+
|
|
182
|
+
### Semgrep Not Running
|
|
183
|
+
|
|
184
|
+
1. Check if Semgrep is installed: `semgrep --version`
|
|
185
|
+
2. If not installed, install it or use `npx semgrep`
|
|
186
|
+
3. Check for error messages in the quality checks output
|
|
187
|
+
|
|
188
|
+
### False Positives
|
|
189
|
+
|
|
190
|
+
If a rule produces false positives:
|
|
191
|
+
|
|
192
|
+
1. Add a `# nosemgrep: rule-id` comment to ignore specific lines
|
|
193
|
+
2. Create custom rules that exclude specific patterns
|
|
194
|
+
3. Use path exclusions in your custom rules
|
|
195
|
+
|
|
196
|
+
### Performance
|
|
197
|
+
|
|
198
|
+
- Semgrep only scans changed files by default (via `--changed-only`)
|
|
199
|
+
- Large codebases may take longer on first scan
|
|
200
|
+
- Results are not cached between runs
|
|
201
|
+
|
|
202
|
+
## Resources
|
|
203
|
+
|
|
204
|
+
- [Semgrep Documentation](https://semgrep.dev/docs/)
|
|
205
|
+
- [Semgrep Rule Registry](https://semgrep.dev/r)
|
|
206
|
+
- [Writing Custom Rules](https://semgrep.dev/docs/writing-rules/overview/)
|
|
207
|
+
- [Rule Syntax Reference](https://semgrep.dev/docs/writing-rules/rule-syntax/)
|
|
@@ -92,5 +92,59 @@ else
|
|
|
92
92
|
echo " npx not available, skipping security scan"
|
|
93
93
|
fi
|
|
94
94
|
|
|
95
|
+
# 9. Semgrep static analysis (optional - graceful skip if not installed)
|
|
96
|
+
echo ""
|
|
97
|
+
echo "🔍 Running Semgrep static analysis..."
|
|
98
|
+
|
|
99
|
+
# Check if Semgrep is available
|
|
100
|
+
semgrep_available=false
|
|
101
|
+
if command -v semgrep &> /dev/null; then
|
|
102
|
+
semgrep_available=true
|
|
103
|
+
semgrep_cmd="semgrep"
|
|
104
|
+
elif command -v npx &> /dev/null && npx semgrep --version &> /dev/null 2>&1; then
|
|
105
|
+
semgrep_available=true
|
|
106
|
+
semgrep_cmd="npx semgrep"
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
if [[ "$semgrep_available" == "true" ]]; then
|
|
110
|
+
# Get changed files for targeted scan
|
|
111
|
+
changed_files=$(git diff main...HEAD --name-only | grep -E '\.(ts|tsx|js|jsx|py|go|rs)$' || true)
|
|
112
|
+
|
|
113
|
+
if [[ -n "$changed_files" ]]; then
|
|
114
|
+
# Run Semgrep with security rules on changed files
|
|
115
|
+
echo " Scanning $(echo "$changed_files" | wc -l | xargs) changed file(s)..."
|
|
116
|
+
|
|
117
|
+
# Run with basic security rules, JSON output for reliable parsing
|
|
118
|
+
# Use --quiet to suppress progress
|
|
119
|
+
semgrep_output=$($semgrep_cmd --config p/security-audit --config p/secrets \
|
|
120
|
+
--quiet --no-git-ignore --json \
|
|
121
|
+
$changed_files 2>&1) || semgrep_exit=$?
|
|
122
|
+
|
|
123
|
+
if [[ -z "$semgrep_output" ]] || ! echo "$semgrep_output" | grep -q '"results"'; then
|
|
124
|
+
echo " ✅ Semgrep: No security issues found"
|
|
125
|
+
else
|
|
126
|
+
# Count findings by severity from JSON output
|
|
127
|
+
# Semgrep JSON uses "severity":"ERROR" (uppercase) for critical, "WARNING" for warnings
|
|
128
|
+
critical_count=$(echo "$semgrep_output" | grep -o '"severity":"ERROR"' | wc -l | xargs)
|
|
129
|
+
warning_count=$(echo "$semgrep_output" | grep -o '"severity":"WARNING"' | wc -l | xargs)
|
|
130
|
+
|
|
131
|
+
if [[ "$critical_count" -gt 0 ]]; then
|
|
132
|
+
echo " ❌ Semgrep: $critical_count critical finding(s) - REVIEW REQUIRED"
|
|
133
|
+
fi
|
|
134
|
+
if [[ "$warning_count" -gt 0 ]]; then
|
|
135
|
+
echo " ⚠️ Semgrep: $warning_count warning(s)"
|
|
136
|
+
fi
|
|
137
|
+
if [[ "$critical_count" -eq 0 && "$warning_count" -eq 0 ]]; then
|
|
138
|
+
echo " ✅ Semgrep: No security issues found"
|
|
139
|
+
fi
|
|
140
|
+
fi
|
|
141
|
+
else
|
|
142
|
+
echo " No source files changed, skipping Semgrep scan"
|
|
143
|
+
fi
|
|
144
|
+
else
|
|
145
|
+
echo " ⚠️ Semgrep not installed (optional)"
|
|
146
|
+
echo " Install with: pip install semgrep"
|
|
147
|
+
fi
|
|
148
|
+
|
|
95
149
|
echo ""
|
|
96
150
|
echo "✅ Quality checks complete"
|