omgkit 2.1.1 → 2.2.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/package.json +1 -1
- package/plugin/skills/SKILL_STANDARDS.md +743 -0
- package/plugin/skills/databases/mongodb/SKILL.md +797 -28
- package/plugin/skills/databases/prisma/SKILL.md +776 -30
- package/plugin/skills/databases/redis/SKILL.md +885 -25
- package/plugin/skills/devops/aws/SKILL.md +686 -28
- package/plugin/skills/devops/github-actions/SKILL.md +684 -29
- package/plugin/skills/devops/kubernetes/SKILL.md +621 -24
- package/plugin/skills/frameworks/django/SKILL.md +920 -20
- package/plugin/skills/frameworks/express/SKILL.md +1361 -35
- package/plugin/skills/frameworks/fastapi/SKILL.md +1260 -33
- package/plugin/skills/frameworks/laravel/SKILL.md +1244 -31
- package/plugin/skills/frameworks/nestjs/SKILL.md +1005 -26
- package/plugin/skills/frameworks/rails/SKILL.md +594 -28
- package/plugin/skills/frameworks/spring/SKILL.md +528 -35
- package/plugin/skills/frameworks/vue/SKILL.md +1296 -27
- package/plugin/skills/frontend/accessibility/SKILL.md +1108 -34
- package/plugin/skills/frontend/frontend-design/SKILL.md +1304 -26
- package/plugin/skills/frontend/responsive/SKILL.md +847 -21
- package/plugin/skills/frontend/shadcn-ui/SKILL.md +976 -38
- package/plugin/skills/frontend/tailwindcss/SKILL.md +831 -35
- package/plugin/skills/frontend/threejs/SKILL.md +1298 -29
- package/plugin/skills/languages/javascript/SKILL.md +935 -31
- package/plugin/skills/methodology/brainstorming/SKILL.md +597 -23
- package/plugin/skills/methodology/defense-in-depth/SKILL.md +832 -34
- package/plugin/skills/methodology/dispatching-parallel-agents/SKILL.md +665 -31
- package/plugin/skills/methodology/executing-plans/SKILL.md +556 -24
- package/plugin/skills/methodology/finishing-development-branch/SKILL.md +595 -25
- package/plugin/skills/methodology/problem-solving/SKILL.md +429 -61
- package/plugin/skills/methodology/receiving-code-review/SKILL.md +536 -24
- package/plugin/skills/methodology/requesting-code-review/SKILL.md +632 -21
- package/plugin/skills/methodology/root-cause-tracing/SKILL.md +641 -30
- package/plugin/skills/methodology/sequential-thinking/SKILL.md +262 -3
- package/plugin/skills/methodology/systematic-debugging/SKILL.md +571 -32
- package/plugin/skills/methodology/test-driven-development/SKILL.md +779 -24
- package/plugin/skills/methodology/testing-anti-patterns/SKILL.md +691 -29
- package/plugin/skills/methodology/token-optimization/SKILL.md +598 -29
- package/plugin/skills/methodology/verification-before-completion/SKILL.md +543 -22
- package/plugin/skills/methodology/writing-plans/SKILL.md +590 -18
- package/plugin/skills/omega/omega-architecture/SKILL.md +838 -39
- package/plugin/skills/omega/omega-coding/SKILL.md +636 -39
- package/plugin/skills/omega/omega-sprint/SKILL.md +855 -48
- package/plugin/skills/omega/omega-testing/SKILL.md +940 -41
- package/plugin/skills/omega/omega-thinking/SKILL.md +703 -50
- package/plugin/skills/security/better-auth/SKILL.md +1065 -28
- package/plugin/skills/security/oauth/SKILL.md +968 -31
- package/plugin/skills/security/owasp/SKILL.md +894 -33
- package/plugin/skills/testing/playwright/SKILL.md +764 -38
- package/plugin/skills/testing/pytest/SKILL.md +873 -36
- package/plugin/skills/testing/vitest/SKILL.md +980 -35
|
@@ -1,41 +1,553 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: receiving-code-review
|
|
3
|
-
description:
|
|
3
|
+
description: Handle code review feedback professionally and productively to improve code quality
|
|
4
|
+
category: methodology
|
|
5
|
+
triggers:
|
|
6
|
+
- receiving review
|
|
7
|
+
- code review feedback
|
|
8
|
+
- review comments
|
|
9
|
+
- addressing feedback
|
|
10
|
+
- PR feedback
|
|
11
|
+
- review response
|
|
12
|
+
- handling criticism
|
|
4
13
|
---
|
|
5
14
|
|
|
6
|
-
# Receiving Code Review
|
|
15
|
+
# Receiving Code Review
|
|
7
16
|
|
|
8
|
-
|
|
9
|
-
- Feedback is about code, not you
|
|
10
|
-
- Reviewers want to help
|
|
11
|
-
- Every comment is an opportunity
|
|
17
|
+
Handle **code review feedback** professionally and productively to improve code quality and grow as a developer. This skill provides frameworks for processing feedback, responding appropriately, and learning from reviews.
|
|
12
18
|
|
|
13
|
-
##
|
|
19
|
+
## Purpose
|
|
14
20
|
|
|
15
|
-
|
|
21
|
+
Turn code reviews into growth opportunities:
|
|
22
|
+
|
|
23
|
+
- Process feedback objectively without defensiveness
|
|
24
|
+
- Distinguish between required changes and suggestions
|
|
25
|
+
- Respond to comments professionally and clearly
|
|
26
|
+
- Learn patterns and improve from feedback
|
|
27
|
+
- Maintain productive reviewer relationships
|
|
28
|
+
- Track and address all feedback systematically
|
|
29
|
+
- Extract maximum learning value from reviews
|
|
30
|
+
|
|
31
|
+
## Features
|
|
32
|
+
|
|
33
|
+
### 1. The Feedback Processing Framework
|
|
34
|
+
|
|
35
|
+
```markdown
|
|
36
|
+
## Receiving Code Review Mindset
|
|
37
|
+
|
|
38
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
39
|
+
│ CODE REVIEW FEEDBACK MODEL │
|
|
40
|
+
├─────────────────────────────────────────────────────────────────────────┤
|
|
41
|
+
│ │
|
|
42
|
+
│ REMEMBER: Feedback is about the CODE, not about YOU │
|
|
43
|
+
│ │
|
|
44
|
+
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
|
45
|
+
│ │ FEEDBACK RECEIVED │ │
|
|
46
|
+
│ └──────────────────────────┬──────────────────────────────────────┘ │
|
|
47
|
+
│ │ │
|
|
48
|
+
│ ▼ │
|
|
49
|
+
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
|
50
|
+
│ │ 1. PAUSE - Don't React Immediately │ │
|
|
51
|
+
│ │ Read carefully, understand fully │ │
|
|
52
|
+
│ └──────────────────────────┬──────────────────────────────────────┘ │
|
|
53
|
+
│ │ │
|
|
54
|
+
│ ▼ │
|
|
55
|
+
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
|
56
|
+
│ │ 2. CATEGORIZE - What type of feedback? │ │
|
|
57
|
+
│ │ Required │ Suggested │ Question │ FYI │ │
|
|
58
|
+
│ └──────────────────────────┬──────────────────────────────────────┘ │
|
|
59
|
+
│ │ │
|
|
60
|
+
│ ▼ │
|
|
61
|
+
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
|
62
|
+
│ │ 3. RESPOND - Acknowledge and address │ │
|
|
63
|
+
│ │ Agree │ Discuss │ Clarify │ │
|
|
64
|
+
│ └──────────────────────────┬──────────────────────────────────────┘ │
|
|
65
|
+
│ │ │
|
|
66
|
+
│ ▼ │
|
|
67
|
+
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
|
68
|
+
│ │ 4. LEARN - Extract patterns and lessons │ │
|
|
69
|
+
│ │ Document │ Practice │ Share │ │
|
|
70
|
+
│ └─────────────────────────────────────────────────────────────────┘ │
|
|
71
|
+
│ │
|
|
72
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 2. Feedback Categorization
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
/**
|
|
79
|
+
* Categorize review comments to prioritize response
|
|
80
|
+
*/
|
|
81
|
+
|
|
82
|
+
type FeedbackCategory =
|
|
83
|
+
| 'blocking' // Must fix before merge
|
|
84
|
+
| 'suggestion' // Recommended improvement
|
|
85
|
+
| 'question' // Needs clarification
|
|
86
|
+
| 'nitpick' // Minor style issue
|
|
87
|
+
| 'praise' // Positive feedback
|
|
88
|
+
| 'fyi'; // Informational
|
|
89
|
+
|
|
90
|
+
interface ReviewComment {
|
|
91
|
+
id: string;
|
|
92
|
+
author: string;
|
|
93
|
+
content: string;
|
|
94
|
+
file?: string;
|
|
95
|
+
line?: number;
|
|
96
|
+
category: FeedbackCategory;
|
|
97
|
+
status: 'pending' | 'addressed' | 'wontfix' | 'discussing';
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function categorizeComment(comment: string, context: ReviewContext): FeedbackCategory {
|
|
101
|
+
// Blocking indicators
|
|
102
|
+
const blockingPatterns = [
|
|
103
|
+
/must|required|needs to|has to|should not/i,
|
|
104
|
+
/security|vulnerability|bug|broken/i,
|
|
105
|
+
/please fix|critical|blocking/i
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
// Question indicators
|
|
109
|
+
const questionPatterns = [
|
|
110
|
+
/\?$/,
|
|
111
|
+
/^(why|what|how|could you|can you|would you)/i,
|
|
112
|
+
/wondering|curious|not sure/i
|
|
113
|
+
];
|
|
114
|
+
|
|
115
|
+
// Suggestion indicators
|
|
116
|
+
const suggestionPatterns = [
|
|
117
|
+
/consider|might want|could|maybe|alternatively/i,
|
|
118
|
+
/^(nit|minor|optional|suggestion)/i
|
|
119
|
+
];
|
|
120
|
+
|
|
121
|
+
// Praise indicators
|
|
122
|
+
const praisePatterns = [
|
|
123
|
+
/nice|great|good|love|excellent|clever|clean/i,
|
|
124
|
+
/👍|🎉|✨|💯/
|
|
125
|
+
];
|
|
126
|
+
|
|
127
|
+
if (blockingPatterns.some(p => p.test(comment))) return 'blocking';
|
|
128
|
+
if (questionPatterns.some(p => p.test(comment))) return 'question';
|
|
129
|
+
if (praisePatterns.some(p => p.test(comment))) return 'praise';
|
|
130
|
+
if (suggestionPatterns.some(p => p.test(comment))) return 'suggestion';
|
|
131
|
+
|
|
132
|
+
return 'suggestion'; // Default to suggestion
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Priority order for addressing comments
|
|
136
|
+
const addressingPriority = [
|
|
137
|
+
'blocking', // Fix these first
|
|
138
|
+
'question', // Answer to unblock discussion
|
|
139
|
+
'suggestion', // Consider and respond
|
|
140
|
+
'nitpick', // Fix if easy, discuss if not
|
|
141
|
+
'praise', // Thank the reviewer
|
|
142
|
+
'fyi' // Acknowledge
|
|
143
|
+
];
|
|
16
144
|
```
|
|
17
|
-
|
|
145
|
+
|
|
146
|
+
### 3. Response Templates
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
/**
|
|
150
|
+
* Professional response templates for different feedback types
|
|
151
|
+
*/
|
|
152
|
+
|
|
153
|
+
const responseTemplates = {
|
|
154
|
+
// Agreement - Simple and direct
|
|
155
|
+
agree: {
|
|
156
|
+
simple: "Good catch! Fixed in {commit}.",
|
|
157
|
+
withContext: "Agreed - I missed this case. Fixed in {commit}.",
|
|
158
|
+
withThanks: "Thanks for catching this! Fixed in {commit}."
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
// Disagreement - Respectful with reasoning
|
|
162
|
+
disagree: {
|
|
163
|
+
withAlternative: `
|
|
164
|
+
I considered this approach, but chose the current implementation because:
|
|
165
|
+
- {reason1}
|
|
166
|
+
- {reason2}
|
|
167
|
+
|
|
168
|
+
What do you think about keeping it as-is given these trade-offs?`,
|
|
169
|
+
|
|
170
|
+
withData: `
|
|
171
|
+
I ran some benchmarks on both approaches:
|
|
172
|
+
- Current: {metric1}
|
|
173
|
+
- Suggested: {metric2}
|
|
174
|
+
|
|
175
|
+
The current approach seems better for our use case. Thoughts?`,
|
|
176
|
+
|
|
177
|
+
partial: `
|
|
178
|
+
Good point about {aspect}. I've addressed that part.
|
|
179
|
+
|
|
180
|
+
For {other_aspect}, I'd prefer to keep the current approach because {reason}.
|
|
181
|
+
Let me know if you feel strongly about changing it.`
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
// Clarification - Ask specific questions
|
|
185
|
+
clarify: {
|
|
186
|
+
needsMore: "Could you elaborate on {specific_point}? I want to make sure I understand the concern.",
|
|
187
|
+
example: "Do you have an example of the pattern you'd prefer? That would help me understand.",
|
|
188
|
+
context: "I may be missing some context - could you explain why {approach} is preferred here?"
|
|
189
|
+
},
|
|
190
|
+
|
|
191
|
+
// Questions - Answer directly
|
|
192
|
+
answer: {
|
|
193
|
+
withReason: "Great question! I chose this because {reason}.",
|
|
194
|
+
withTradeoff: "Good catch - there's a trade-off here. {explanation}. I went with this approach because {reasoning}.",
|
|
195
|
+
withDoc: "This is documented in {location}. The reason is {explanation}."
|
|
196
|
+
},
|
|
197
|
+
|
|
198
|
+
// Deferral - Valid reasons to defer
|
|
199
|
+
defer: {
|
|
200
|
+
scopeCreep: "That's a good idea! It's outside the scope of this PR - I'll create a follow-up issue: {issue_link}",
|
|
201
|
+
needsDiscussion: "This deserves a broader discussion. Let's sync about it in {meeting/channel}.",
|
|
202
|
+
complexChange: "Agreed this should change, but it's a larger refactor. Created {issue_link} to track."
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
// Example responses
|
|
207
|
+
const exampleResponses = {
|
|
208
|
+
// Reviewer: "This could be simplified using Array.map instead of the for loop"
|
|
209
|
+
agreeAndFix: "Good call! Refactored to use map - much cleaner. Fixed in abc123.",
|
|
210
|
+
|
|
211
|
+
// Reviewer: "Why not use a switch statement here?"
|
|
212
|
+
disagreeWithReason: `
|
|
213
|
+
I considered a switch, but the if-else works better here because:
|
|
214
|
+
- The conditions aren't simple value comparisons
|
|
215
|
+
- We need to check ranges (age > 18)
|
|
216
|
+
- The logic may expand to more complex conditions
|
|
217
|
+
|
|
218
|
+
Happy to discuss if you see issues with this approach.`,
|
|
219
|
+
|
|
220
|
+
// Reviewer: "Consider adding error handling"
|
|
221
|
+
partialAgree: `
|
|
222
|
+
Good point! Added try/catch for the network calls.
|
|
223
|
+
|
|
224
|
+
For the local operations, I've kept them without explicit try/catch since errors there indicate bugs we'd want to surface immediately. Let me know if you'd prefer explicit handling there too.`
|
|
225
|
+
};
|
|
18
226
|
```
|
|
19
227
|
|
|
20
|
-
###
|
|
228
|
+
### 4. Addressing Comments Systematically
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
/**
|
|
232
|
+
* Process all comments systematically
|
|
233
|
+
*/
|
|
234
|
+
|
|
235
|
+
interface ReviewSession {
|
|
236
|
+
prId: string;
|
|
237
|
+
comments: ReviewComment[];
|
|
238
|
+
status: 'in_progress' | 'complete' | 'blocked';
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
class ReviewResponseManager {
|
|
242
|
+
private session: ReviewSession;
|
|
243
|
+
|
|
244
|
+
async processAllComments(): Promise<void> {
|
|
245
|
+
// 1. Read all comments first (don't start responding immediately)
|
|
246
|
+
const allComments = await this.fetchAllComments();
|
|
247
|
+
|
|
248
|
+
// 2. Categorize and sort by priority
|
|
249
|
+
const categorized = allComments
|
|
250
|
+
.map(c => ({ ...c, category: categorizeComment(c.content) }))
|
|
251
|
+
.sort((a, b) =>
|
|
252
|
+
addressingPriority.indexOf(a.category) -
|
|
253
|
+
addressingPriority.indexOf(b.category)
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
// 3. Group related comments
|
|
257
|
+
const grouped = this.groupRelatedComments(categorized);
|
|
258
|
+
|
|
259
|
+
// 4. Address each group
|
|
260
|
+
for (const group of grouped) {
|
|
261
|
+
await this.addressCommentGroup(group);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// 5. Post summary update
|
|
265
|
+
await this.postSummaryUpdate();
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
private async addressCommentGroup(comments: ReviewComment[]): Promise<void> {
|
|
269
|
+
// Address the primary comment
|
|
270
|
+
const primary = comments[0];
|
|
271
|
+
|
|
272
|
+
switch (primary.category) {
|
|
273
|
+
case 'blocking':
|
|
274
|
+
await this.fixAndRespond(primary);
|
|
275
|
+
break;
|
|
276
|
+
case 'question':
|
|
277
|
+
await this.answerQuestion(primary);
|
|
278
|
+
break;
|
|
279
|
+
case 'suggestion':
|
|
280
|
+
await this.considerSuggestion(primary);
|
|
281
|
+
break;
|
|
282
|
+
case 'nitpick':
|
|
283
|
+
await this.handleNitpick(primary);
|
|
284
|
+
break;
|
|
285
|
+
case 'praise':
|
|
286
|
+
await this.acknowledgepraise(primary);
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Mark as addressed
|
|
291
|
+
primary.status = 'addressed';
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
private async postSummaryUpdate(): Promise<void> {
|
|
295
|
+
const addressed = this.session.comments.filter(c => c.status === 'addressed');
|
|
296
|
+
const pending = this.session.comments.filter(c => c.status === 'pending');
|
|
297
|
+
const wontfix = this.session.comments.filter(c => c.status === 'wontfix');
|
|
298
|
+
|
|
299
|
+
await this.postComment(`
|
|
300
|
+
## Review Response Summary
|
|
301
|
+
|
|
302
|
+
✅ Addressed: ${addressed.length} comments
|
|
303
|
+
⏳ Pending discussion: ${pending.length} comments
|
|
304
|
+
🔜 Deferred: ${wontfix.length} comments (see follow-up issues)
|
|
305
|
+
|
|
306
|
+
Ready for another look when you have time!
|
|
307
|
+
`);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
21
310
|
```
|
|
22
|
-
|
|
23
|
-
|
|
311
|
+
|
|
312
|
+
### 5. Learning from Reviews
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
/**
|
|
316
|
+
* Extract learning value from reviews
|
|
317
|
+
*/
|
|
318
|
+
|
|
319
|
+
interface ReviewLesson {
|
|
320
|
+
category: string;
|
|
321
|
+
pattern: string;
|
|
322
|
+
example: string;
|
|
323
|
+
prevention: string;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
class ReviewLearningSystem {
|
|
327
|
+
private lessons: ReviewLesson[] = [];
|
|
328
|
+
|
|
329
|
+
extractLessons(review: ReviewSession): ReviewLesson[] {
|
|
330
|
+
const lessons: ReviewLesson[] = [];
|
|
331
|
+
|
|
332
|
+
for (const comment of review.comments) {
|
|
333
|
+
if (comment.category === 'blocking' || comment.category === 'suggestion') {
|
|
334
|
+
const lesson = this.analyzeForLesson(comment);
|
|
335
|
+
if (lesson) {
|
|
336
|
+
lessons.push(lesson);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return lessons;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
private analyzeForLesson(comment: ReviewComment): ReviewLesson | null {
|
|
345
|
+
// Common lesson patterns
|
|
346
|
+
const patterns = {
|
|
347
|
+
security: {
|
|
348
|
+
triggers: ['injection', 'xss', 'auth', 'security', 'sanitize'],
|
|
349
|
+
category: 'Security',
|
|
350
|
+
prevention: 'Use parameterized queries, validate input, encode output'
|
|
351
|
+
},
|
|
352
|
+
performance: {
|
|
353
|
+
triggers: ['n+1', 'loop', 'inefficient', 'slow', 'memory'],
|
|
354
|
+
category: 'Performance',
|
|
355
|
+
prevention: 'Profile before optimizing, batch operations, use appropriate data structures'
|
|
356
|
+
},
|
|
357
|
+
errorHandling: {
|
|
358
|
+
triggers: ['error', 'exception', 'try', 'catch', 'handle'],
|
|
359
|
+
category: 'Error Handling',
|
|
360
|
+
prevention: 'Always handle errors, use typed errors, log appropriately'
|
|
361
|
+
},
|
|
362
|
+
testing: {
|
|
363
|
+
triggers: ['test', 'coverage', 'edge case', 'mock'],
|
|
364
|
+
category: 'Testing',
|
|
365
|
+
prevention: 'Test edge cases, use meaningful assertions, avoid flaky tests'
|
|
366
|
+
},
|
|
367
|
+
naming: {
|
|
368
|
+
triggers: ['name', 'unclear', 'confusing', 'rename'],
|
|
369
|
+
category: 'Naming',
|
|
370
|
+
prevention: 'Use descriptive names, follow conventions, be consistent'
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
for (const [key, pattern] of Object.entries(patterns)) {
|
|
375
|
+
if (pattern.triggers.some(t =>
|
|
376
|
+
comment.content.toLowerCase().includes(t)
|
|
377
|
+
)) {
|
|
378
|
+
return {
|
|
379
|
+
category: pattern.category,
|
|
380
|
+
pattern: comment.content,
|
|
381
|
+
example: comment.file ? `${comment.file}:${comment.line}` : 'N/A',
|
|
382
|
+
prevention: pattern.prevention
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
return null;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// Track recurring feedback
|
|
391
|
+
trackPatterns(): RecurringPattern[] {
|
|
392
|
+
const patternCounts = new Map<string, number>();
|
|
393
|
+
|
|
394
|
+
for (const lesson of this.lessons) {
|
|
395
|
+
const key = lesson.category;
|
|
396
|
+
patternCounts.set(key, (patternCounts.get(key) || 0) + 1);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
return Array.from(patternCounts.entries())
|
|
400
|
+
.filter(([_, count]) => count >= 2)
|
|
401
|
+
.map(([category, count]) => ({
|
|
402
|
+
category,
|
|
403
|
+
count,
|
|
404
|
+
suggestion: `Focus on improving ${category.toLowerCase()} skills`
|
|
405
|
+
}));
|
|
406
|
+
}
|
|
407
|
+
}
|
|
24
408
|
```
|
|
25
409
|
|
|
26
|
-
###
|
|
410
|
+
### 6. Common Anti-Patterns to Avoid
|
|
411
|
+
|
|
412
|
+
```markdown
|
|
413
|
+
## Review Response Anti-Patterns
|
|
414
|
+
|
|
415
|
+
### ❌ DON'T: Defensive Responses
|
|
416
|
+
|
|
417
|
+
Bad:
|
|
418
|
+
> "Well, it works fine on my machine and I've tested it extensively."
|
|
419
|
+
|
|
420
|
+
Good:
|
|
421
|
+
> "I see the issue now - I was testing in a different environment. Fixed in abc123."
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
### ❌ DON'T: Ignoring Comments
|
|
425
|
+
|
|
426
|
+
Bad:
|
|
427
|
+
> *No response, just mark as resolved*
|
|
428
|
+
|
|
429
|
+
Good:
|
|
430
|
+
> "Addressed this by extracting the logic into a helper function. The tests now cover the edge case too."
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
### ❌ DON'T: Dismissive Responses
|
|
434
|
+
|
|
435
|
+
Bad:
|
|
436
|
+
> "That's just a style preference, not important."
|
|
437
|
+
|
|
438
|
+
Good:
|
|
439
|
+
> "I see the benefit for consistency. Changed to match the team style."
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
### ❌ DON'T: Over-Explaining
|
|
443
|
+
|
|
444
|
+
Bad:
|
|
445
|
+
> *Three paragraphs explaining why you chose a variable name*
|
|
446
|
+
|
|
447
|
+
Good:
|
|
448
|
+
> "Renamed to userAccountStatus - clearer. Good catch."
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
### ❌ DON'T: Passive-Aggressive
|
|
452
|
+
|
|
453
|
+
Bad:
|
|
454
|
+
> "I guess we can do it your way if you insist..."
|
|
455
|
+
|
|
456
|
+
Good:
|
|
457
|
+
> "That approach does handle the edge case better. Updated."
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
### ✅ DO: Be Grateful
|
|
461
|
+
|
|
462
|
+
Good:
|
|
463
|
+
> "Thanks for the thorough review! I learned a new pattern from your suggestion about X."
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
### ✅ DO: Take Ownership
|
|
467
|
+
|
|
468
|
+
Good:
|
|
469
|
+
> "You're right, I should have caught this. Added a test to prevent regression."
|
|
27
470
|
```
|
|
28
|
-
|
|
29
|
-
|
|
471
|
+
|
|
472
|
+
## Use Cases
|
|
473
|
+
|
|
474
|
+
### Handling a Tough Review
|
|
475
|
+
|
|
476
|
+
```typescript
|
|
477
|
+
// Scenario: PR receives 20+ comments, some critical
|
|
478
|
+
|
|
479
|
+
async function handleToughReview(prId: string): Promise<void> {
|
|
480
|
+
const manager = new ReviewResponseManager(prId);
|
|
481
|
+
|
|
482
|
+
// Step 1: Don't panic, read everything first
|
|
483
|
+
const allComments = await manager.fetchAllComments();
|
|
484
|
+
console.log(`Received ${allComments.length} comments`);
|
|
485
|
+
|
|
486
|
+
// Step 2: Categorize to understand scope
|
|
487
|
+
const breakdown = categorizeAll(allComments);
|
|
488
|
+
console.log(`
|
|
489
|
+
Blocking: ${breakdown.blocking}
|
|
490
|
+
Questions: ${breakdown.questions}
|
|
491
|
+
Suggestions: ${breakdown.suggestions}
|
|
492
|
+
Nitpicks: ${breakdown.nitpicks}
|
|
493
|
+
`);
|
|
494
|
+
|
|
495
|
+
// Step 3: Address blocking issues first
|
|
496
|
+
for (const blocking of breakdown.blocking) {
|
|
497
|
+
await fixBlockingIssue(blocking);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// Step 4: Answer questions to unblock discussion
|
|
501
|
+
for (const question of breakdown.questions) {
|
|
502
|
+
await answerQuestion(question);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// Step 5: Address suggestions thoughtfully
|
|
506
|
+
for (const suggestion of breakdown.suggestions) {
|
|
507
|
+
if (suggestion.isValid) {
|
|
508
|
+
await implementSuggestion(suggestion);
|
|
509
|
+
} else {
|
|
510
|
+
await explainAlternative(suggestion);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// Step 6: Quick fixes for nitpicks
|
|
515
|
+
for (const nitpick of breakdown.nitpicks) {
|
|
516
|
+
await quickFix(nitpick);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// Step 7: Post summary and re-request review
|
|
520
|
+
await postSummary();
|
|
521
|
+
await requestReReview();
|
|
522
|
+
}
|
|
30
523
|
```
|
|
31
524
|
|
|
32
|
-
##
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
525
|
+
## Best Practices
|
|
526
|
+
|
|
527
|
+
### Do's
|
|
528
|
+
|
|
529
|
+
- **Read all comments before responding** - understand the full picture
|
|
530
|
+
- **Categorize by priority** - blocking issues first
|
|
531
|
+
- **Respond to every comment** - even if just acknowledging
|
|
532
|
+
- **Be specific in responses** - reference commit hashes
|
|
533
|
+
- **Thank reviewers** for their time and insights
|
|
534
|
+
- **Learn from feedback** - track patterns
|
|
535
|
+
- **Follow up promptly** - don't let PRs stale
|
|
536
|
+
- **Ask for clarification** when needed
|
|
537
|
+
|
|
538
|
+
### Don'ts
|
|
539
|
+
|
|
540
|
+
- Don't take feedback personally
|
|
541
|
+
- Don't respond defensively or emotionally
|
|
542
|
+
- Don't ignore comments without explanation
|
|
543
|
+
- Don't mark as resolved without addressing
|
|
544
|
+
- Don't argue about preferences endlessly
|
|
545
|
+
- Don't dismiss nitpicks dismissively
|
|
546
|
+
- Don't forget to re-request review
|
|
547
|
+
- Don't delay addressing feedback
|
|
548
|
+
|
|
549
|
+
## References
|
|
37
550
|
|
|
38
|
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
- Changing without acknowledgment
|
|
551
|
+
- [The Art of Receiving Code Reviews](https://mtlynch.io/code-review-love/)
|
|
552
|
+
- [How to Make Good Code Reviews Better](https://stackoverflow.blog/2019/09/30/how-to-make-good-code-reviews-better/)
|
|
553
|
+
- [Google Code Review Guidelines](https://google.github.io/eng-practices/review/)
|