@codeharbor/agent-playbook 0.1.0 → 0.1.1
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/package.json +5 -2
- package/skills/api-designer/README.md +36 -0
- package/skills/api-designer/SKILL.md +232 -0
- package/skills/api-designer/references/graphql-patterns.md +12 -0
- package/skills/api-designer/references/rest-patterns.md +17 -0
- package/skills/api-designer/scripts/generate_api.py +87 -0
- package/skills/api-designer/scripts/validate_api.py +48 -0
- package/skills/api-documenter/README.md +41 -0
- package/skills/api-documenter/SKILL.md +209 -0
- package/skills/api-documenter/references/examples/README.md +3 -0
- package/skills/api-documenter/references/examples/openapi-example.yaml +10 -0
- package/skills/api-documenter/references/openapi-template.yaml +5 -0
- package/skills/api-documenter/scripts/generate_openapi.py +84 -0
- package/skills/api-documenter/scripts/validate_openapi.py +45 -0
- package/skills/architecting-solutions/README.md +22 -0
- package/skills/architecting-solutions/SKILL.md +459 -0
- package/skills/auto-trigger/README.md +23 -0
- package/skills/auto-trigger/SKILL.md +183 -0
- package/skills/code-reviewer/README.md +59 -0
- package/skills/code-reviewer/SKILL.md +220 -0
- package/skills/code-reviewer/references/checklist.md +80 -0
- package/skills/code-reviewer/references/patterns.md +226 -0
- package/skills/code-reviewer/references/security.md +88 -0
- package/skills/code-reviewer/scripts/review_checklist.py +191 -0
- package/skills/commit-helper/README.md +58 -0
- package/skills/commit-helper/SKILL.md +159 -0
- package/skills/commit-helper/references/conventional-commits.md +68 -0
- package/skills/commit-helper/references/examples.md +125 -0
- package/skills/commit-helper/references/scopes.md +49 -0
- package/skills/commit-helper/scripts/validate_commit.py +70 -0
- package/skills/create-pr/README.md +182 -0
- package/skills/create-pr/SKILL.md +340 -0
- package/skills/debugger/README.md +53 -0
- package/skills/debugger/SKILL.md +239 -0
- package/skills/debugger/references/checklist.md +7 -0
- package/skills/debugger/references/errors.md +6 -0
- package/skills/debugger/references/patterns.md +5 -0
- package/skills/debugger/scripts/debug_report.py +77 -0
- package/skills/deployment-engineer/README.md +40 -0
- package/skills/deployment-engineer/SKILL.md +242 -0
- package/skills/deployment-engineer/references/kubernetes.md +23 -0
- package/skills/deployment-engineer/references/monitoring.md +14 -0
- package/skills/deployment-engineer/references/pipelines.md +12 -0
- package/skills/deployment-engineer/scripts/generate_deploy.py +72 -0
- package/skills/deployment-engineer/scripts/validate_deploy.py +46 -0
- package/skills/documentation-engineer/README.md +41 -0
- package/skills/documentation-engineer/SKILL.md +164 -0
- package/skills/documentation-engineer/references/api-template.md +22 -0
- package/skills/documentation-engineer/references/readme-template.md +25 -0
- package/skills/documentation-engineer/references/style-guide.md +13 -0
- package/skills/documentation-engineer/scripts/generate_docs.py +68 -0
- package/skills/documentation-engineer/scripts/validate_docs.py +46 -0
- package/skills/figma-designer/README.md +222 -0
- package/skills/figma-designer/SKILL.md +407 -0
- package/skills/figma-designer/references/example-output.md +86 -0
- package/skills/performance-engineer/README.md +42 -0
- package/skills/performance-engineer/SKILL.md +236 -0
- package/skills/performance-engineer/references/checklist.md +6 -0
- package/skills/performance-engineer/references/monitoring.md +5 -0
- package/skills/performance-engineer/references/optimization.md +7 -0
- package/skills/performance-engineer/scripts/perf_report.py +64 -0
- package/skills/performance-engineer/scripts/profile.py +63 -0
- package/skills/planning-with-files/README.md +27 -0
- package/skills/planning-with-files/SKILL.md +103 -0
- package/skills/prd-implementation-precheck/README.md +97 -0
- package/skills/prd-implementation-precheck/SKILL.md +112 -0
- package/skills/prd-planner/README.md +102 -0
- package/skills/prd-planner/SKILL.md +449 -0
- package/skills/prd-planner/references/edge-case-analysis.md +111 -0
- package/skills/qa-expert/README.md +37 -0
- package/skills/qa-expert/SKILL.md +225 -0
- package/skills/qa-expert/references/gates.md +11 -0
- package/skills/qa-expert/references/metrics.md +6 -0
- package/skills/qa-expert/references/strategy.md +11 -0
- package/skills/qa-expert/scripts/coverage_analysis.py +61 -0
- package/skills/qa-expert/scripts/generate_test_plan.py +68 -0
- package/skills/refactoring-specialist/README.md +37 -0
- package/skills/refactoring-specialist/SKILL.md +283 -0
- package/skills/refactoring-specialist/references/checklist.md +6 -0
- package/skills/refactoring-specialist/references/smells.md +6 -0
- package/skills/refactoring-specialist/references/techniques.md +6 -0
- package/skills/security-auditor/README.md +48 -0
- package/skills/security-auditor/SKILL.md +256 -0
- package/skills/security-auditor/references/checklist.md +7 -0
- package/skills/security-auditor/references/owasp.md +12 -0
- package/skills/security-auditor/references/remediation.md +7 -0
- package/skills/security-auditor/scripts/find_secrets.py +58 -0
- package/skills/security-auditor/scripts/security_audit.py +64 -0
- package/skills/self-improving-agent/README.md +136 -0
- package/skills/self-improving-agent/SKILL.md +407 -0
- package/skills/self-improving-agent/hooks/post-bash.sh +10 -0
- package/skills/self-improving-agent/hooks/pre-tool.sh +10 -0
- package/skills/self-improving-agent/hooks/session-end.sh +4 -0
- package/skills/self-improving-agent/memory/semantic-patterns.json +288 -0
- package/skills/self-improving-agent/references/appendix.md +131 -0
- package/skills/self-improving-agent/templates/correction-template.md +11 -0
- package/skills/self-improving-agent/templates/pattern-template.md +15 -0
- package/skills/self-improving-agent/templates/validation-template.md +14 -0
- package/skills/session-logger/README.md +50 -0
- package/skills/session-logger/SKILL.md +156 -0
- package/skills/skill-router/README.md +155 -0
- package/skills/skill-router/SKILL.md +215 -0
- package/skills/test-automator/README.md +41 -0
- package/skills/test-automator/SKILL.md +202 -0
- package/skills/test-automator/references/best-practices.md +6 -0
- package/skills/test-automator/references/examples/README.md +3 -0
- package/skills/test-automator/references/examples/unit-test-example.md +8 -0
- package/skills/test-automator/references/mocking.md +5 -0
- package/skills/test-automator/scripts/coverage_report.py +59 -0
- package/skills/test-automator/scripts/generate_test.py +66 -0
- package/skills/workflow-orchestrator/README.md +20 -0
- package/skills/workflow-orchestrator/SKILL.md +342 -0
- package/src/cli.js +25 -10
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# Common Patterns and Anti-Patterns
|
|
2
|
+
|
|
3
|
+
## Patterns to Encourage
|
|
4
|
+
|
|
5
|
+
### Error Handling
|
|
6
|
+
|
|
7
|
+
**Good:**
|
|
8
|
+
```typescript
|
|
9
|
+
async function getUser(id: string) {
|
|
10
|
+
const user = await db.users.findById(id);
|
|
11
|
+
if (!user) {
|
|
12
|
+
throw new NotFoundError(`User ${id} not found`);
|
|
13
|
+
}
|
|
14
|
+
return user;
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Bad:**
|
|
19
|
+
```typescript
|
|
20
|
+
async function getUser(id: string) {
|
|
21
|
+
return await db.users.findById(id); // Returns null, not handled
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Async/Await
|
|
26
|
+
|
|
27
|
+
**Good:**
|
|
28
|
+
```typescript
|
|
29
|
+
const result = await fetch(url);
|
|
30
|
+
const data = await result.json();
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Bad:**
|
|
34
|
+
```typescript
|
|
35
|
+
fetch(url).then(r => r.json()).then(data => {
|
|
36
|
+
// Nested callbacks
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Early Returns
|
|
41
|
+
|
|
42
|
+
**Good:**
|
|
43
|
+
```typescript
|
|
44
|
+
function process(user) {
|
|
45
|
+
if (!user) return null;
|
|
46
|
+
if (!user.active) return null;
|
|
47
|
+
return user.data;
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Bad:**
|
|
52
|
+
```typescript
|
|
53
|
+
function process(user) {
|
|
54
|
+
if (user) {
|
|
55
|
+
if (user.active) {
|
|
56
|
+
return user.data;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Destructuring
|
|
64
|
+
|
|
65
|
+
**Good:**
|
|
66
|
+
```typescript
|
|
67
|
+
const { name, email } = user;
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Bad:**
|
|
71
|
+
```typescript
|
|
72
|
+
const name = user.name;
|
|
73
|
+
const email = user.email;
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Anti-Patterns to Catch
|
|
77
|
+
|
|
78
|
+
### Magic Numbers
|
|
79
|
+
|
|
80
|
+
**Bad:**
|
|
81
|
+
```typescript
|
|
82
|
+
if (user.role === 5) { ... }
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Good:**
|
|
86
|
+
```typescript
|
|
87
|
+
const Role = { ADMIN: 5, USER: 1 };
|
|
88
|
+
if (user.role === Role.ADMIN) { ... }
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Neglected Promise Rejection
|
|
92
|
+
|
|
93
|
+
**Bad:**
|
|
94
|
+
```typescript
|
|
95
|
+
fetch(url).then(data => processData(data));
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Good:**
|
|
99
|
+
```typescript
|
|
100
|
+
fetch(url)
|
|
101
|
+
.then(data => processData(data))
|
|
102
|
+
.catch(error => logError(error));
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Any Type
|
|
106
|
+
|
|
107
|
+
**Bad:**
|
|
108
|
+
```typescript
|
|
109
|
+
function parse(data: any) { ... }
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Good:**
|
|
113
|
+
```typescript
|
|
114
|
+
function parse(data: unknown): Result { ... }
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Deep Nesting
|
|
118
|
+
|
|
119
|
+
**Bad:**
|
|
120
|
+
```typescript
|
|
121
|
+
if (a) {
|
|
122
|
+
if (b) {
|
|
123
|
+
if (c) {
|
|
124
|
+
doSomething();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Good:**
|
|
131
|
+
```typescript
|
|
132
|
+
if (!a) return;
|
|
133
|
+
if (!b) return;
|
|
134
|
+
if (!c) return;
|
|
135
|
+
doSomething();
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Large Functions
|
|
139
|
+
|
|
140
|
+
**Bad:** Functions > 50 lines
|
|
141
|
+
|
|
142
|
+
**Good:** Split into smaller, focused functions
|
|
143
|
+
|
|
144
|
+
### God Objects
|
|
145
|
+
|
|
146
|
+
**Bad:** Classes/methods that do everything
|
|
147
|
+
|
|
148
|
+
**Good:** Single Responsibility Principle
|
|
149
|
+
|
|
150
|
+
### Shotgun Surgery
|
|
151
|
+
|
|
152
|
+
**Bad:** Adding a feature requires changing many files
|
|
153
|
+
|
|
154
|
+
**Good:** Good separation of concerns
|
|
155
|
+
|
|
156
|
+
## React Specific
|
|
157
|
+
|
|
158
|
+
### Hooks Dependencies
|
|
159
|
+
|
|
160
|
+
**Bad:**
|
|
161
|
+
```typescript
|
|
162
|
+
useEffect(() => {
|
|
163
|
+
fetchData(userId);
|
|
164
|
+
}, []); // Missing userId dependency
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Good:**
|
|
168
|
+
```typescript
|
|
169
|
+
useEffect(() => {
|
|
170
|
+
fetchData(userId);
|
|
171
|
+
}, [userId]);
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### State Updates
|
|
175
|
+
|
|
176
|
+
**Bad:**
|
|
177
|
+
```typescript
|
|
178
|
+
setCount(count + 1);
|
|
179
|
+
setCount(count + 1);
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**Good:**
|
|
183
|
+
```typescript
|
|
184
|
+
setCount(c => c + 2);
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Key Props
|
|
188
|
+
|
|
189
|
+
**Bad:**
|
|
190
|
+
```typescript
|
|
191
|
+
items.map((item, i) => <Item key={i} />)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**Good:**
|
|
195
|
+
```typescript
|
|
196
|
+
items.map(item => <Item key={item.id} />)
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Backend Specific
|
|
200
|
+
|
|
201
|
+
### N+1 Query
|
|
202
|
+
|
|
203
|
+
**Bad:**
|
|
204
|
+
```python
|
|
205
|
+
for user in users:
|
|
206
|
+
posts = db.query("SELECT * FROM posts WHERE user_id = ?", user.id)
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**Good:**
|
|
210
|
+
```python
|
|
211
|
+
user_ids = [u.id for u in users]
|
|
212
|
+
posts = db.query("SELECT * FROM posts WHERE user_id IN ?", user_ids)
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Transaction Handling
|
|
216
|
+
|
|
217
|
+
**Bad:**
|
|
218
|
+
```python
|
|
219
|
+
db.transfer(a, b, amount) # No transaction
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
**Good:**
|
|
223
|
+
```python
|
|
224
|
+
with db.transaction():
|
|
225
|
+
db.transfer(a, b, amount)
|
|
226
|
+
```
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Security Review Guidelines
|
|
2
|
+
|
|
3
|
+
## OWASP Top 10 Coverage
|
|
4
|
+
|
|
5
|
+
### A01:2021 – Broken Access Control
|
|
6
|
+
- [ ] Users can only access their own data
|
|
7
|
+
- [ ] API endpoints have proper authentication
|
|
8
|
+
- [ ] Admin actions require admin role
|
|
9
|
+
- [ ] No IDOR (Insecure Direct Object References)
|
|
10
|
+
- [ ] Proper authorization checks on all endpoints
|
|
11
|
+
|
|
12
|
+
### A02:2021 – Cryptographic Failures
|
|
13
|
+
- [ ] Passwords are hashed (bcrypt/argon2)
|
|
14
|
+
- [ ] HTTPS is enforced
|
|
15
|
+
- [ ] Sensitive data is encrypted at rest
|
|
16
|
+
- [ ] No weak cipher suites
|
|
17
|
+
- [ ] Proper key management
|
|
18
|
+
|
|
19
|
+
### A03:2021 – Injection
|
|
20
|
+
- [ ] Parameterized queries for SQL
|
|
21
|
+
- [ ] Input validation and sanitization
|
|
22
|
+
- [ ] ORM used safely
|
|
23
|
+
- [ ] No command injection from user input
|
|
24
|
+
- [ ] No LDAP injection
|
|
25
|
+
|
|
26
|
+
### A04:2021 – Insecure Design
|
|
27
|
+
- [ ] Rate limiting on auth endpoints
|
|
28
|
+
- [ ] Proper logout functionality
|
|
29
|
+
- [ ] Session timeout is reasonable
|
|
30
|
+
- [ ] No security through obscurity
|
|
31
|
+
|
|
32
|
+
### A05:2021 – Security Misconfiguration
|
|
33
|
+
- [ ] Debug mode off in production
|
|
34
|
+
- [ ] Error messages don't leak information
|
|
35
|
+
- [ ] Default credentials changed
|
|
36
|
+
- [ ] Security headers configured
|
|
37
|
+
- [ ] CORS configured correctly
|
|
38
|
+
|
|
39
|
+
### A06:2021 – Vulnerable Components
|
|
40
|
+
- [ ] Dependencies up to date
|
|
41
|
+
- [ ] No known vulnerabilities in deps
|
|
42
|
+
- [ ] Unused dependencies removed
|
|
43
|
+
|
|
44
|
+
### A07:2021 – Auth Failures
|
|
45
|
+
- [ ] Strong password policy
|
|
46
|
+
- [ ] No brute force protection needed (rate limiting)
|
|
47
|
+
- [ ] MFA implemented for sensitive operations
|
|
48
|
+
- [ ] Session IDs are random
|
|
49
|
+
|
|
50
|
+
### A08:2021 – Software/Data Integrity
|
|
51
|
+
- [ ] Dependencies from trusted sources
|
|
52
|
+
- [ ] CI/CD has integrity checks
|
|
53
|
+
- [ ] Verify data integrity
|
|
54
|
+
|
|
55
|
+
### A09:2021 – Logging Failures
|
|
56
|
+
- [ ] Security events logged
|
|
57
|
+
- [ ] Logs don't contain sensitive data
|
|
58
|
+
- [ ] Log tampering protection
|
|
59
|
+
- [ ] Audit trail for critical operations
|
|
60
|
+
|
|
61
|
+
### A10:2021 – SSRF
|
|
62
|
+
- [ ] No arbitrary URL fetching from user input
|
|
63
|
+
- [ ] Allowlist for external calls
|
|
64
|
+
- [ ] Network segmentation
|
|
65
|
+
|
|
66
|
+
## Frontend Security
|
|
67
|
+
|
|
68
|
+
- [ ] XSS prevention
|
|
69
|
+
- [ ] CSRF tokens
|
|
70
|
+
- [ ] Content Security Policy
|
|
71
|
+
- [ ] Subresource Integrity
|
|
72
|
+
- [ ] No `dangerouslySetInnerHTML` with user content
|
|
73
|
+
|
|
74
|
+
## Backend Security
|
|
75
|
+
|
|
76
|
+
- [ ] Input validation on all endpoints
|
|
77
|
+
- [ ] Output encoding
|
|
78
|
+
- [ ] Prepared statements
|
|
79
|
+
- [ ] Principle of least privilege
|
|
80
|
+
- [ ] Secure file upload handling
|
|
81
|
+
|
|
82
|
+
## Infrastructure Security
|
|
83
|
+
|
|
84
|
+
- [ ] Secrets in environment variables
|
|
85
|
+
- [ ] No secrets in code
|
|
86
|
+
- [ ] Proper RBAC
|
|
87
|
+
- [ ] Network security rules
|
|
88
|
+
- [ ] Regular security updates
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Code Review Checklist Generator
|
|
4
|
+
Generates a structured review checklist for a given PR or diff.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import argparse
|
|
8
|
+
import subprocess
|
|
9
|
+
import sys
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_changed_files(base_branch: str = "main") -> list[str]:
|
|
14
|
+
"""Get list of changed files."""
|
|
15
|
+
try:
|
|
16
|
+
result = subprocess.run(
|
|
17
|
+
["git", "diff", f"{base_branch}...HEAD", "--name-only"],
|
|
18
|
+
capture_output=True,
|
|
19
|
+
text=True,
|
|
20
|
+
check=True
|
|
21
|
+
)
|
|
22
|
+
return [f.strip() for f in result.stdout.strip().split('\n') if f.strip()]
|
|
23
|
+
except subprocess.CalledProcessError:
|
|
24
|
+
return []
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def get_commit_messages(base_branch: str = "main") -> list[str]:
|
|
28
|
+
"""Get commit messages in the PR."""
|
|
29
|
+
try:
|
|
30
|
+
result = subprocess.run(
|
|
31
|
+
["git", "log", f"{base_branch}...HEAD", "--oneline"],
|
|
32
|
+
capture_output=True,
|
|
33
|
+
text=True,
|
|
34
|
+
check=True
|
|
35
|
+
)
|
|
36
|
+
return [line.strip() for line in result.stdout.strip().split('\n') if line.strip()]
|
|
37
|
+
except subprocess.CalledProcessError:
|
|
38
|
+
return []
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def get_diff(base_branch: str = "main") -> str:
|
|
42
|
+
"""Get the full diff."""
|
|
43
|
+
try:
|
|
44
|
+
result = subprocess.run(
|
|
45
|
+
["git", "diff", f"{base_branch}...HEAD"],
|
|
46
|
+
capture_output=True,
|
|
47
|
+
text=True,
|
|
48
|
+
check=True
|
|
49
|
+
)
|
|
50
|
+
return result.stdout
|
|
51
|
+
except subprocess.CalledProcessError:
|
|
52
|
+
return ""
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def categorize_file(filename: str) -> str:
|
|
56
|
+
"""Categorize file by extension for targeted checks."""
|
|
57
|
+
ext = Path(filename).suffix.lower()
|
|
58
|
+
if ext in {'.ts', '.tsx', '.js', '.jsx'}:
|
|
59
|
+
return 'javascript'
|
|
60
|
+
if ext in {'.py'}:
|
|
61
|
+
return 'python'
|
|
62
|
+
if ext in {'.go'}:
|
|
63
|
+
return 'go'
|
|
64
|
+
if ext in {'.rs'}:
|
|
65
|
+
return 'rust'
|
|
66
|
+
if ext in {'.java', '.kt'}:
|
|
67
|
+
return 'jvm'
|
|
68
|
+
if ext in {'.sql'}:
|
|
69
|
+
return 'sql'
|
|
70
|
+
if ext in {'.yml', '.yaml'}:
|
|
71
|
+
return 'yaml'
|
|
72
|
+
if ext in {'.md', '.rst'}:
|
|
73
|
+
return 'docs'
|
|
74
|
+
return 'general'
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def generate_review_checklist(base_branch: str = "main") -> str:
|
|
78
|
+
"""Generate a structured review checklist."""
|
|
79
|
+
files = get_changed_files(base_branch)
|
|
80
|
+
commits = get_commit_messages(base_branch)
|
|
81
|
+
diff = get_diff(base_branch)
|
|
82
|
+
|
|
83
|
+
if not files:
|
|
84
|
+
return "# No changes found\n\nNo files changed compared to " + base_branch
|
|
85
|
+
|
|
86
|
+
lines = ["# Code Review Checklist\n"]
|
|
87
|
+
|
|
88
|
+
# Overview
|
|
89
|
+
lines.append("## Overview\n")
|
|
90
|
+
lines.append(f"- **Branch**: {base_branch} → HEAD")
|
|
91
|
+
lines.append(f"- **Files changed**: {len(files)}")
|
|
92
|
+
lines.append(f"- **Commits**: {len(commits)}\n")
|
|
93
|
+
|
|
94
|
+
# Commits
|
|
95
|
+
lines.append("### Commits\n")
|
|
96
|
+
for commit in commits:
|
|
97
|
+
lines.append(f"- {commit}")
|
|
98
|
+
lines.append("")
|
|
99
|
+
|
|
100
|
+
# Files by category
|
|
101
|
+
categories = {}
|
|
102
|
+
for f in files:
|
|
103
|
+
cat = categorize_file(f)
|
|
104
|
+
categories.setdefault(cat, []).append(f)
|
|
105
|
+
|
|
106
|
+
lines.append("## Files to Review\n")
|
|
107
|
+
for cat, cat_files in categories.items():
|
|
108
|
+
lines.append(f"\n### {cat.title()}\n")
|
|
109
|
+
for f in cat_files:
|
|
110
|
+
lines.append(f"- [{f}]")
|
|
111
|
+
|
|
112
|
+
# Diff snippet (first 100 lines)
|
|
113
|
+
lines.append("\n## Diff Preview\n")
|
|
114
|
+
lines.append("```diff")
|
|
115
|
+
for line in diff.split('\n')[:100]:
|
|
116
|
+
lines.append(line)
|
|
117
|
+
if len(diff.split('\n')) > 100:
|
|
118
|
+
lines.append("\n... (diff truncated)")
|
|
119
|
+
lines.append("```\n")
|
|
120
|
+
|
|
121
|
+
# Review sections
|
|
122
|
+
lines.append("## Review Sections\n")
|
|
123
|
+
|
|
124
|
+
# Security check
|
|
125
|
+
lines.append("### 🔒 Security\n")
|
|
126
|
+
if any('secret' in f.lower() or 'config' in f.lower() or 'env' in f.lower() for f in files):
|
|
127
|
+
lines.append("- [ ] **Secrets check**: No hardcoded credentials in config/env files\n")
|
|
128
|
+
lines.append("- [ ] **Input validation**: User input is validated and sanitized\n")
|
|
129
|
+
lines.append("- [ ] **Injection**: No SQL/command injection vulnerabilities\n")
|
|
130
|
+
lines.append("- [ ] **Auth**: Proper authentication/authorization on new endpoints\n")
|
|
131
|
+
|
|
132
|
+
# Code quality
|
|
133
|
+
lines.append("\n### 📝 Code Quality\n")
|
|
134
|
+
lines.append("- [ ] **Readability**: Code is clear and understandable\n")
|
|
135
|
+
lines.append("- [ ] **Naming**: Variables/functions are well named\n")
|
|
136
|
+
lines.append("- [ ] **DRY**: No duplicate code\n")
|
|
137
|
+
lines.append("- [ ] **Comments**: Complex logic is explained\n")
|
|
138
|
+
|
|
139
|
+
# Testing
|
|
140
|
+
test_files = [f for f in files if 'test' in f.lower() or 'spec' in f.lower()]
|
|
141
|
+
if test_files:
|
|
142
|
+
lines.append(f"\n### 🧪 Testing ({len(test_files)} test files)\n")
|
|
143
|
+
else:
|
|
144
|
+
lines.append("\n### 🧪 Testing\n")
|
|
145
|
+
lines.append("- [ ] **Tests added**: New functionality has tests\n")
|
|
146
|
+
lines.append("- [ ] **Coverage**: Test coverage not decreased\n")
|
|
147
|
+
lines.append("- [ ] **Edge cases**: Edge cases are tested\n")
|
|
148
|
+
|
|
149
|
+
# Performance
|
|
150
|
+
lines.append("\n### ⚡ Performance\n")
|
|
151
|
+
lines.append("- [ ] **N+1 queries**: No database queries in loops\n")
|
|
152
|
+
lines.append("- [ ] **Caching**: Appropriate caching where needed\n")
|
|
153
|
+
lines.append("- [ ] **Efficiency**: Efficient algorithms/data structures\n")
|
|
154
|
+
|
|
155
|
+
# Documentation
|
|
156
|
+
lines.append("\n### 📚 Documentation\n")
|
|
157
|
+
lines.append("- [ ] **API docs**: Public APIs are documented\n")
|
|
158
|
+
lines.append("- [ ] **README**: README updated if needed\n")
|
|
159
|
+
lines.append("- [ ] **Comments**: Complex logic has comments\n")
|
|
160
|
+
|
|
161
|
+
# Breaking changes
|
|
162
|
+
lines.append("\n### ⚠️ Breaking Changes\n")
|
|
163
|
+
lines.append("- [ ] **Documented**: Breaking changes are documented\n")
|
|
164
|
+
lines.append("- [ ] **Migration**: Migration guide provided if needed\n")
|
|
165
|
+
|
|
166
|
+
# Approval
|
|
167
|
+
lines.append("\n## Approval\n")
|
|
168
|
+
lines.append("- [ ] **Critical issues**: None\n")
|
|
169
|
+
lines.append("- [ ] **Tests pass**: All tests pass locally\n")
|
|
170
|
+
lines.append("- [ ] **Ready to merge**: No blocking issues\n")
|
|
171
|
+
|
|
172
|
+
return '\n'.join(lines)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def main():
|
|
176
|
+
parser = argparse.ArgumentParser(description="Generate code review checklist")
|
|
177
|
+
parser.add_argument("--base", default="main", help="Base branch to compare against")
|
|
178
|
+
parser.add_argument("--output", "-o", help="Output file (default: stdout)")
|
|
179
|
+
args = parser.parse_args()
|
|
180
|
+
|
|
181
|
+
checklist = generate_review_checklist(args.base)
|
|
182
|
+
|
|
183
|
+
if args.output:
|
|
184
|
+
Path(args.output).write_text(checklist)
|
|
185
|
+
print(f"Checklist written to {args.output}")
|
|
186
|
+
else:
|
|
187
|
+
print(checklist)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
if __name__ == "__main__":
|
|
191
|
+
main()
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Commit Helper
|
|
2
|
+
|
|
3
|
+
> A Claude Code skill for writing Git commit messages following the Conventional Commits specification.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
This skill is part of the [agent-playbook](https://github.com/Charon-Fan/agent-playbook) collection.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
When working with Git, simply ask Claude to commit your changes:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
You: commit my changes
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The skill will automatically:
|
|
18
|
+
1. Review your changes with `git diff`
|
|
19
|
+
2. Generate a properly formatted commit message
|
|
20
|
+
3. Present it for your approval
|
|
21
|
+
4. Execute the commit when confirmed
|
|
22
|
+
|
|
23
|
+
## Examples
|
|
24
|
+
|
|
25
|
+
### Simple Feature
|
|
26
|
+
```
|
|
27
|
+
You: Commit the new user authentication feature
|
|
28
|
+
|
|
29
|
+
Claude generates:
|
|
30
|
+
feat(auth): add OAuth2 login support
|
|
31
|
+
|
|
32
|
+
Implement OAuth2 authentication flow for Google and GitHub.
|
|
33
|
+
Users can now link multiple social accounts to their profile.
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Bug Fix
|
|
37
|
+
```
|
|
38
|
+
You: Commit the API timeout fix
|
|
39
|
+
|
|
40
|
+
Claude generates:
|
|
41
|
+
fix(api): resolve timeout in user endpoint
|
|
42
|
+
|
|
43
|
+
Added 30-second timeout to database query to prevent slow queries
|
|
44
|
+
from causing request timeouts.
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Validation
|
|
48
|
+
|
|
49
|
+
The skill includes a validation script to check commit message format:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
python scripts/validate_commit.py "feat(api): add user endpoint"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## References
|
|
56
|
+
|
|
57
|
+
- [Conventional Commits Specification](https://www.conventionalcommits.org/)
|
|
58
|
+
- [Angular Commit Guidelines](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit)
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: commit-helper
|
|
3
|
+
description: Helps write Git commit messages following the Conventional Commits specification. Use this skill when the user asks to commit changes, write commit messages, format commits, or mentions git commits.
|
|
4
|
+
allowed-tools: Read, Write, Edit, Bash, Grep
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Commit Message Helper
|
|
8
|
+
|
|
9
|
+
A skill for creating properly formatted Git commit messages following the [Conventional Commits](https://www.conventionalcommits.org/) specification.
|
|
10
|
+
|
|
11
|
+
## When This Skill Activates
|
|
12
|
+
|
|
13
|
+
This skill activates when you:
|
|
14
|
+
- Ask to commit changes
|
|
15
|
+
- Mention commit messages
|
|
16
|
+
- Request git commit formatting
|
|
17
|
+
- Say "commit" or "git commit"
|
|
18
|
+
|
|
19
|
+
## Commit Message Format
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
<type>(<scope>): <subject>
|
|
23
|
+
|
|
24
|
+
<body>
|
|
25
|
+
|
|
26
|
+
<footer>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Types
|
|
30
|
+
|
|
31
|
+
| Type | Description |
|
|
32
|
+
|------|-------------|
|
|
33
|
+
| `feat` | A new feature |
|
|
34
|
+
| `fix` | A bug fix |
|
|
35
|
+
| `docs` | Documentation only changes |
|
|
36
|
+
| `style` | Changes that do not affect the meaning of the code (formatting, etc.) |
|
|
37
|
+
| `refactor` | A code change that neither fixes a bug nor adds a feature |
|
|
38
|
+
| `perf` | A code change that improves performance |
|
|
39
|
+
| `test` | Adding missing tests or correcting existing tests |
|
|
40
|
+
| `chore` | Changes to the build process or auxiliary tools |
|
|
41
|
+
| `ci` | Changes to CI configuration files and scripts |
|
|
42
|
+
| `build` | Changes that affect the build system or external dependencies |
|
|
43
|
+
|
|
44
|
+
## Scope
|
|
45
|
+
|
|
46
|
+
The scope should indicate the area of the codebase affected:
|
|
47
|
+
- For frontend: `components`, `hooks`, `store`, `styles`, `utils`
|
|
48
|
+
- For backend: `api`, `models`, `services`, `database`, `auth`
|
|
49
|
+
- For devops: `ci`, `deploy`, `docker`
|
|
50
|
+
- Project-specific scopes are also acceptable
|
|
51
|
+
|
|
52
|
+
## Guidelines
|
|
53
|
+
|
|
54
|
+
### Subject Line
|
|
55
|
+
- Use imperative mood ("add feature" not "added feature" or "adds feature")
|
|
56
|
+
- No period at the end
|
|
57
|
+
- Maximum 50 characters
|
|
58
|
+
- Be specific and concise
|
|
59
|
+
|
|
60
|
+
### Body
|
|
61
|
+
- Separate subject from body with a blank line
|
|
62
|
+
- Use the body to explain **what** and **why**, not **how**
|
|
63
|
+
- Wrap at 72 characters per line
|
|
64
|
+
- Mention any breaking changes
|
|
65
|
+
|
|
66
|
+
### Footer
|
|
67
|
+
- Reference issues: `Closes #123`, `Fixes #456`, `Refs #789`
|
|
68
|
+
- Multiple issues: `Closes #123, #456, #789`
|
|
69
|
+
- Breaking changes: Start with `BREAKING CHANGE:` followed by description
|
|
70
|
+
|
|
71
|
+
## Examples
|
|
72
|
+
|
|
73
|
+
### Good Examples
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
feat(auth): add OAuth2 login support
|
|
77
|
+
|
|
78
|
+
Implement OAuth2 authentication flow to allow users to log in
|
|
79
|
+
with their Google or GitHub accounts.
|
|
80
|
+
|
|
81
|
+
This change adds:
|
|
82
|
+
- New OAuth2 middleware for handling callbacks
|
|
83
|
+
- Updated login UI with social login buttons
|
|
84
|
+
- User profile synchronization
|
|
85
|
+
|
|
86
|
+
Closes #123
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
fix(api): resolve race condition in user creation
|
|
91
|
+
|
|
92
|
+
The concurrent user creation requests could result in duplicate
|
|
93
|
+
email entries. Added unique constraint and proper error handling.
|
|
94
|
+
|
|
95
|
+
Fixes #456
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
refactor(user): simplify profile update logic
|
|
100
|
+
|
|
101
|
+
Extracted common validation logic into a reusable function
|
|
102
|
+
to reduce code duplication across profile update endpoints.
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
docs: update API documentation with new endpoints
|
|
107
|
+
|
|
108
|
+
Added documentation for the v2 user management endpoints
|
|
109
|
+
including request/response examples and error codes.
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Bad Examples
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
updated stuff # Too vague, no type/scope
|
|
116
|
+
fixed bug # No context about which bug
|
|
117
|
+
feat: added feature # Redundant ("feat" means new feature)
|
|
118
|
+
Feat(User): Add Login # Incorrect capitalization
|
|
119
|
+
feat: A really really really long subject line that exceeds the recommended limit # Too long
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Breaking Changes
|
|
123
|
+
|
|
124
|
+
When introducing breaking changes, add `BREAKING CHANGE:` to the footer:
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
feat(api): migrate to REST v2
|
|
128
|
+
|
|
129
|
+
The API endpoints have been restructured for better consistency.
|
|
130
|
+
Old endpoints are deprecated and will be removed in v3.0.
|
|
131
|
+
|
|
132
|
+
BREAKING CHANGE: `/api/v1/users` is now `/api/v2/users`.
|
|
133
|
+
All consumers must update their integration by 2025-03-01.
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Workflow
|
|
137
|
+
|
|
138
|
+
When writing a commit message:
|
|
139
|
+
|
|
140
|
+
1. **Review changes** - Run `git diff` to understand what changed
|
|
141
|
+
2. **Identify type** - Determine the type of change
|
|
142
|
+
3. **Identify scope** - Determine which area is affected
|
|
143
|
+
4. **Write subject** - Create a clear, concise subject line
|
|
144
|
+
5. **Write body** - Explain what and why (if needed)
|
|
145
|
+
6. **Add footer** - Reference issues or note breaking changes
|
|
146
|
+
|
|
147
|
+
## Validation
|
|
148
|
+
|
|
149
|
+
Use the validation script to check commit message format:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
python scripts/validate_commit.py "your commit message"
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Reference Documents
|
|
156
|
+
|
|
157
|
+
- See `references/conventional-commits.md` for full specification
|
|
158
|
+
- See `references/examples.md` for more examples
|
|
159
|
+
- See `references/scopes.md` for recommended scope naming
|