claude-dev-env 1.0.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/LICENSE +21 -0
- package/README.md +219 -0
- package/agents/agent-writer.md +157 -0
- package/agents/clasp-deployment-orchestrator.md +609 -0
- package/agents/clean-coder.md +295 -0
- package/agents/code-quality-agent.md +40 -0
- package/agents/code-standards-agent.md +93 -0
- package/agents/config-centralizer.md +686 -0
- package/agents/config-extraction-agent.md +225 -0
- package/agents/doc-orchestrator.md +47 -0
- package/agents/docs-agent.md +112 -0
- package/agents/docx-agent.md +211 -0
- package/agents/git-commit-crafter.md +100 -0
- package/agents/magic-value-eliminator-agent.md +72 -0
- package/agents/mandatory-agent-workflow-agent.md +88 -0
- package/agents/parallel-workflow-coordinator.md +779 -0
- package/agents/pdf-agent.md +302 -0
- package/agents/plan-executor.md +226 -0
- package/agents/pr-description-writer.md +87 -0
- package/agents/project-context-loader.md +238 -0
- package/agents/project-docs-analyzer.md +54 -0
- package/agents/project-structure-organizer-agent.md +72 -0
- package/agents/readability-review-agent.md +76 -0
- package/agents/refactoring-specialist.md +69 -0
- package/agents/right-sized-engineer.md +129 -0
- package/agents/session-continuity-manager.md +53 -0
- package/agents/skill-to-agent-converter.md +371 -0
- package/agents/skill-writer-agent.md +470 -0
- package/agents/stub-detector-agent.md +140 -0
- package/agents/tdd-test-writer.md +62 -0
- package/agents/test-data-builder.md +68 -0
- package/agents/tooling-builder.md +78 -0
- package/agents/user-docs-writer.md +67 -0
- package/agents/validation-expert.md +71 -0
- package/agents/workflow-visual-documenter.md +82 -0
- package/agents/xlsx-agent.md +169 -0
- package/bin/install.mjs +256 -0
- package/commands/commit.md +28 -0
- package/commands/docupdate.md +322 -0
- package/commands/implement.md +102 -0
- package/commands/initialize.md +91 -0
- package/commands/plan.md +63 -0
- package/commands/pr-comments.md +47 -0
- package/commands/readability-review.md +20 -0
- package/commands/review-plan.md +7 -0
- package/commands/right-size.md +15 -0
- package/commands/stubcheck.md +89 -0
- package/commands/sum.md +30 -0
- package/docs/CODE_RULES.md +186 -0
- package/docs/DJANGO_PATTERNS.md +80 -0
- package/docs/REACT_PATTERNS.md +185 -0
- package/docs/TEST_QUALITY.md +104 -0
- package/hooks/advisory/migration-safety-advisor.py +49 -0
- package/hooks/advisory/refactor-guard.py +205 -0
- package/hooks/blocking/block-main-commit.py +168 -0
- package/hooks/blocking/code-rules-enforcer.py +549 -0
- package/hooks/blocking/destructive-command-blocker.py +107 -0
- package/hooks/blocking/docker-settings-guard.py +44 -0
- package/hooks/blocking/hedging-language-blocker.py +130 -0
- package/hooks/blocking/parallel-task-blocker.py +69 -0
- package/hooks/blocking/pr-description-enforcer.py +87 -0
- package/hooks/blocking/pyautogui-scroll-blocker.py +74 -0
- package/hooks/blocking/sensitive-file-protector.py +70 -0
- package/hooks/blocking/tdd-enforcer.py +62 -0
- package/hooks/blocking/test-preflight-check.py +343 -0
- package/hooks/blocking/write-existing-file-blocker.py +63 -0
- package/hooks/git-hooks/post-commit.py +103 -0
- package/hooks/github-action/test_workflow.py +33 -0
- package/hooks/hooks.json +246 -0
- package/hooks/lifecycle/config-change-guard.py +84 -0
- package/hooks/lifecycle/session-end-cleanup.py +59 -0
- package/hooks/notification/attention-needed-notify.py +63 -0
- package/hooks/notification/claude-notification-handler.py +59 -0
- package/hooks/notification/notification_utils.py +206 -0
- package/hooks/rewrite-plugin-paths.py +116 -0
- package/hooks/session/bulk-edit-reminder.py +30 -0
- package/hooks/session/code-rules-reminder.py +97 -0
- package/hooks/session/compact-context-reinject.py +39 -0
- package/hooks/session/hook-structure-context.py +140 -0
- package/hooks/session/plugin-data-dir-cleanup.py +39 -0
- package/hooks/validation/code-style-validator.py +145 -0
- package/hooks/validation/e2e-test-validator.py +142 -0
- package/hooks/validation/hook-format-validator.py +66 -0
- package/hooks/validation/mypy_validator.py +180 -0
- package/hooks/validators/README.md +125 -0
- package/hooks/validators/VALIDATION_REPORT.md +287 -0
- package/hooks/validators/__init__.py +19 -0
- package/hooks/validators/abbreviation_checks.py +82 -0
- package/hooks/validators/code_quality_checks.py +133 -0
- package/hooks/validators/comment_checks.py +188 -0
- package/hooks/validators/file_structure_checks.py +182 -0
- package/hooks/validators/git_checks.py +107 -0
- package/hooks/validators/health_check.py +214 -0
- package/hooks/validators/magic_value_checks.py +81 -0
- package/hooks/validators/mypy_integration.py +52 -0
- package/hooks/validators/output_formatter.py +266 -0
- package/hooks/validators/pr_reference_checks.py +72 -0
- package/hooks/validators/python_antipattern_checks.py +110 -0
- package/hooks/validators/python_style_checks.py +364 -0
- package/hooks/validators/react_checks.py +90 -0
- package/hooks/validators/ruff_integration.py +80 -0
- package/hooks/validators/run_all_validators.py +772 -0
- package/hooks/validators/security_checks.py +135 -0
- package/hooks/validators/test_abbreviation_checks.py +76 -0
- package/hooks/validators/test_bad.tsx +7 -0
- package/hooks/validators/test_code_quality_checks.py +129 -0
- package/hooks/validators/test_file_structure_checks.py +307 -0
- package/hooks/validators/test_files/01_basic_component.tsx +10 -0
- package/hooks/validators/test_files/02_component_without_react.tsx +10 -0
- package/hooks/validators/test_files/03_pure_component.tsx +10 -0
- package/hooks/validators/test_files/04_pure_component_import.tsx +10 -0
- package/hooks/validators/test_files/05_typescript_generics.tsx +14 -0
- package/hooks/validators/test_files/06_typescript_two_generics.tsx +18 -0
- package/hooks/validators/test_files/07_multiline_declaration.tsx +11 -0
- package/hooks/validators/test_files/08_error_boundary_valid.tsx +14 -0
- package/hooks/validators/test_files/09_error_boundary_with_other_class.tsx +20 -0
- package/hooks/validators/test_files/10_inheritance_chain.tsx +16 -0
- package/hooks/validators/test_files/11_ts_file.ts +10 -0
- package/hooks/validators/test_files/12_non_react_class.tsx +14 -0
- package/hooks/validators/test_files/13_functional_component.tsx +8 -0
- package/hooks/validators/test_files/14_indented_class.tsx +13 -0
- package/hooks/validators/test_files/15_getDerivedStateFromError.tsx +14 -0
- package/hooks/validators/test_files/16_mixed_components.tsx +20 -0
- package/hooks/validators/test_files/EXECUTIVE_SUMMARY.md +175 -0
- package/hooks/validators/test_files/TEST_RESULTS_TABLE.txt +60 -0
- package/hooks/validators/test_files/VALIDATION_REPORT.md +201 -0
- package/hooks/validators/test_files/async_views.py +23 -0
- package/hooks/validators/test_files/async_with_imports.py +14 -0
- package/hooks/validators/test_files/bad_inline_imports.py +37 -0
- package/hooks/validators/test_files/management/commands/cmd_01_no_debug_check.py +10 -0
- package/hooks/validators/test_files/management/commands/cmd_02_proper_debug_check.py +14 -0
- package/hooks/validators/test_files/management/commands/cmd_03_debug_check_with_return.py +14 -0
- package/hooks/validators/test_files/management/commands/cmd_04_imported_DEBUG.py +14 -0
- package/hooks/validators/test_files/management/commands/cmd_05_debug_check_in_helper.py +16 -0
- package/hooks/validators/test_files/management/commands/cmd_06_debug_check_late.py +22 -0
- package/hooks/validators/test_files/management/commands/cmd_07_positive_debug_check.py +15 -0
- package/hooks/validators/test_files/management/commands/cmd_08_debug_with_and.py +14 -0
- package/hooks/validators/test_files/not_management_command.py +10 -0
- package/hooks/validators/test_files/skip_decorators/test_01_simple_skip.py +8 -0
- package/hooks/validators/test_files/skip_decorators/test_02_pytest_skipif.py +8 -0
- package/hooks/validators/test_files/skip_decorators/test_03_unittest_skipIf.py +8 -0
- package/hooks/validators/test_files/skip_decorators/test_04_skip_with_parens.py +8 -0
- package/hooks/validators/test_files/skip_decorators/test_05_xfail.py +7 -0
- package/hooks/validators/test_files/skip_decorators/test_06_custom_skip.py +11 -0
- package/hooks/validators/test_files/skip_decorators/test_07_capital_Skip.py +8 -0
- package/hooks/validators/test_files/skip_decorators/test_08_skipUnless.py +7 -0
- package/hooks/validators/test_files/skip_decorators/test_09_pytest_mark_skip_simple.py +7 -0
- package/hooks/validators/test_files/test_async_functions.py +45 -0
- package/hooks/validators/test_files/test_purecomponent/PureComponentExample.tsx +7 -0
- package/hooks/validators/test_files/test_purecomponent/ReactPureComponentExample.tsx +7 -0
- package/hooks/validators/test_git_checks.py +295 -0
- package/hooks/validators/test_good.tsx +5 -0
- package/hooks/validators/test_health_check.py +57 -0
- package/hooks/validators/test_magic_value_checks.py +63 -0
- package/hooks/validators/test_mypy_integration.py +27 -0
- package/hooks/validators/test_output_formatter.py +150 -0
- package/hooks/validators/test_pr_reference_checks.py +41 -0
- package/hooks/validators/test_python_antipattern_checks.py +113 -0
- package/hooks/validators/test_python_style_checks.py +439 -0
- package/hooks/validators/test_react_checks.py +213 -0
- package/hooks/validators/test_results.txt +25 -0
- package/hooks/validators/test_ruff_integration.py +27 -0
- package/hooks/validators/test_run_all_validators.py +228 -0
- package/hooks/validators/test_run_all_validators_integration.py +48 -0
- package/hooks/validators/test_safety_checks.py +243 -0
- package/hooks/validators/test_security_checks.py +105 -0
- package/hooks/validators/test_test_safety_checks.py +321 -0
- package/hooks/validators/test_todo_checks.py +39 -0
- package/hooks/validators/test_type_safety_checks.py +85 -0
- package/hooks/validators/test_useless_test_checks.py +55 -0
- package/hooks/validators/test_validator_base.py +26 -0
- package/hooks/validators/test_verify_paths.py +34 -0
- package/hooks/validators/todo_checks.py +59 -0
- package/hooks/validators/type_safety_checks.py +101 -0
- package/hooks/validators/useless_test_checks.py +92 -0
- package/hooks/validators/validator_base.py +19 -0
- package/hooks/validators/verify_paths.py +57 -0
- package/hooks/workflow/auto-formatter.py +114 -0
- package/hooks/workflow/investigation-tracker-reset.py +46 -0
- package/package.json +30 -0
- package/rules/agent-spawn-protocol.md +47 -0
- package/rules/cleanup-temp-files.md +27 -0
- package/rules/code-reviews.md +11 -0
- package/rules/code-standards.md +43 -0
- package/rules/conservative-action.md +20 -0
- package/rules/context7.md +12 -0
- package/rules/explore-thoroughly.md +27 -0
- package/rules/git-workflow.md +42 -0
- package/rules/parallel-tools.md +23 -0
- package/rules/research-mode.md +23 -0
- package/rules/right-sized-engineering.md +28 -0
- package/rules/tdd.md +7 -0
- package/rules/testing.md +12 -0
- package/skills/agent-prompt/SKILL.md +102 -0
- package/skills/anthropic-plan/SKILL.md +107 -0
- package/skills/everything-search/SKILL.md +144 -0
- package/skills/ingest/SKILL.md +40 -0
- package/skills/npm-creator/SKILL.md +183 -0
- package/skills/pr-review-responder/EXAMPLES.md +590 -0
- package/skills/pr-review-responder/PRINCIPLES.md +539 -0
- package/skills/pr-review-responder/README.md +209 -0
- package/skills/pr-review-responder/SKILL.md +202 -0
- package/skills/pr-review-responder/TESTING.md +407 -0
- package/skills/pr-review-responder/scripts/respond_to_reviews.py +376 -0
- package/skills/pr-review-responder/update_skill.py +297 -0
- package/skills/prompt-generator/REFERENCE.md +150 -0
- package/skills/prompt-generator/SKILL.md +154 -0
- package/skills/readability-review/SKILL.md +127 -0
- package/skills/recall/SKILL.md +27 -0
- package/skills/remember/SKILL.md +63 -0
- package/skills/rule-audit/SKILL.md +307 -0
- package/skills/rule-creator/SKILL.md +150 -0
- package/skills/skill-writer/REFERENCE.md +246 -0
- package/skills/skill-writer/SKILL.md +270 -0
- package/skills/tdd-team/SKILL.md +128 -0
|
@@ -0,0 +1,590 @@
|
|
|
1
|
+
# PR Review Responder Examples
|
|
2
|
+
|
|
3
|
+
Real-world examples of responding to PR review comments.
|
|
4
|
+
|
|
5
|
+
## Example 1: Over-Engineering Feedback
|
|
6
|
+
|
|
7
|
+
**Scenario**: Reviewer catches unnecessary wrapper class
|
|
8
|
+
|
|
9
|
+
**PR Context**:
|
|
10
|
+
- PR #12: "Add file upload to admin interface"
|
|
11
|
+
- Reviewer: Reviewer
|
|
12
|
+
- Comment on `src/storage.py:45`
|
|
13
|
+
|
|
14
|
+
**Review comment**:
|
|
15
|
+
```
|
|
16
|
+
Why create a wrapper class here? The Path().read_bytes() approach
|
|
17
|
+
is more straightforward and avoids unnecessary abstraction.
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**Your changes** (commit addressing feedback):
|
|
21
|
+
```python
|
|
22
|
+
# Before (over-engineered)
|
|
23
|
+
class FileReader:
|
|
24
|
+
def __init__(self, path):
|
|
25
|
+
self.path = path
|
|
26
|
+
|
|
27
|
+
def read(self):
|
|
28
|
+
return Path(self.path).read_bytes()
|
|
29
|
+
|
|
30
|
+
file_data = FileReader(file_path).read()
|
|
31
|
+
|
|
32
|
+
# After (simplified)
|
|
33
|
+
file_data = Path(file_path).read_bytes()
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Skill execution**:
|
|
37
|
+
```
|
|
38
|
+
$ "Respond to PR review comments"
|
|
39
|
+
|
|
40
|
+
Found 1 review comment addressed:
|
|
41
|
+
|
|
42
|
+
1. @reviewer on src/storage.py:45
|
|
43
|
+
Comment: "Why create a wrapper class here? The Path().read_bytes()..."
|
|
44
|
+
Response: ✅ **Fixed**: Removed FileReader wrapper, using Path().read_bytes() directly
|
|
45
|
+
|
|
46
|
+
Post this response to the PR? (y/n) y
|
|
47
|
+
|
|
48
|
+
Posted 1 response to PR #12
|
|
49
|
+
View PR: https://github.com/yourorg/project/pull/43
|
|
50
|
+
|
|
51
|
+
Ready to push!
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Posted response on GitHub**:
|
|
55
|
+
```
|
|
56
|
+
✅ **Fixed**: Removed FileReader wrapper, using Path().read_bytes() directly
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Example 2: Multiple Comments Across Files
|
|
62
|
+
|
|
63
|
+
**Scenario**: Refactoring PR with feedback on several files
|
|
64
|
+
|
|
65
|
+
**PR Context**:
|
|
66
|
+
- PR #67: "Refactor timing system"
|
|
67
|
+
- Reviewer: Reviewer
|
|
68
|
+
- 4 inline comments across 3 files
|
|
69
|
+
|
|
70
|
+
**Review comments**:
|
|
71
|
+
|
|
72
|
+
1. **src/views.py:23**:
|
|
73
|
+
```
|
|
74
|
+
This animation logic is duplicated in the schedule view.
|
|
75
|
+
Should extract to shared utility.
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
2. **src/views.py:89**:
|
|
79
|
+
```
|
|
80
|
+
Same timing calculation here. DRY principle.
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
3. **templates/base.html:45**:
|
|
84
|
+
```
|
|
85
|
+
Why pass CSS timing values through Python context?
|
|
86
|
+
Put them directly in CSS.
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
4. **src/utils.py:12**:
|
|
90
|
+
```
|
|
91
|
+
Good extraction! But needs type hints on parameters.
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Your changes** (commit addressing all feedback):
|
|
95
|
+
```python
|
|
96
|
+
# src/utils/view_helpers.py (NEW FILE)
|
|
97
|
+
from typing import Dict
|
|
98
|
+
|
|
99
|
+
def calculate_timing(duration: int, delay: int) -> Dict[str, str]:
|
|
100
|
+
"""Calculate CSS animation timing values."""
|
|
101
|
+
return {
|
|
102
|
+
'duration': f'{duration}ms',
|
|
103
|
+
'delay': f'{delay}ms'
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
# src/views.py (MODIFIED - removed duplication)
|
|
107
|
+
from utils.view_helpers import calculate_timing
|
|
108
|
+
|
|
109
|
+
# templates/base.html (MODIFIED - CSS values direct)
|
|
110
|
+
<style>
|
|
111
|
+
.fade-in { animation-duration: 300ms; }
|
|
112
|
+
</style>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Skill execution**:
|
|
116
|
+
```
|
|
117
|
+
$ "Respond to PR review comments before I push"
|
|
118
|
+
|
|
119
|
+
Found 4 review comments addressed:
|
|
120
|
+
|
|
121
|
+
1. @reviewer on src/views.py:23
|
|
122
|
+
Comment: "This animation logic is duplicated..."
|
|
123
|
+
Response: ✅ **Fixed**: Extracted to utils/view_helpers.py
|
|
124
|
+
|
|
125
|
+
2. @reviewer on src/views.py:89
|
|
126
|
+
Comment: "Same timing calculation here. DRY principle."
|
|
127
|
+
Response: ✅ **Fixed**: Now using shared calculate_timing()
|
|
128
|
+
|
|
129
|
+
3. @reviewer on templates/base.html:45
|
|
130
|
+
Comment: "Why pass CSS timing values through Python context?"
|
|
131
|
+
Response: ✅ **Fixed**: Moved animation values directly to CSS
|
|
132
|
+
|
|
133
|
+
4. @reviewer on src/utils.py:12
|
|
134
|
+
Comment: "Good extraction! But needs type hints..."
|
|
135
|
+
Response: ✅ **Fixed**: Added type hints (int, Dict[str, str])
|
|
136
|
+
|
|
137
|
+
Post these 4 responses to the PR? (y/n) y
|
|
138
|
+
|
|
139
|
+
Posted 4 responses to PR #67
|
|
140
|
+
View PR: https://github.com/yourorg/project/pull/67
|
|
141
|
+
|
|
142
|
+
Ready to push!
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Example 3: Partial Addressing (Some Comments Not Fixed)
|
|
148
|
+
|
|
149
|
+
**Scenario**: Some feedback addressed, some deferred
|
|
150
|
+
|
|
151
|
+
**PR Context**:
|
|
152
|
+
- PR #89: "Add user profile customization"
|
|
153
|
+
- Reviewer: Reviewer
|
|
154
|
+
- 3 comments, only 2 addressed in this commit
|
|
155
|
+
|
|
156
|
+
**Review comments**:
|
|
157
|
+
|
|
158
|
+
1. **src/models.py:34**:
|
|
159
|
+
```
|
|
160
|
+
user_name conflicts with User.username. Rename to display_name.
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
2. **src/views.py:56**:
|
|
164
|
+
```
|
|
165
|
+
This profile logic should be in a service layer, not the view.
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
3. **src/forms.py:23**:
|
|
169
|
+
```
|
|
170
|
+
Missing validation on age field (must be positive).
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Your changes** (commit addressing 2 of 3):
|
|
174
|
+
```python
|
|
175
|
+
# Fixed: Renamed field
|
|
176
|
+
class UserProfile(models.Model):
|
|
177
|
+
display_name = models.CharField(max_length=100) # was user_name
|
|
178
|
+
|
|
179
|
+
# Fixed: Added validation
|
|
180
|
+
class ProfileForm(forms.ModelForm):
|
|
181
|
+
def clean_age(self):
|
|
182
|
+
age = self.cleaned_data['age']
|
|
183
|
+
if age <= 0:
|
|
184
|
+
raise ValidationError("Age must be positive")
|
|
185
|
+
return age
|
|
186
|
+
|
|
187
|
+
# NOT FIXED: Service layer refactor (deferred to separate PR)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**Skill execution**:
|
|
191
|
+
```
|
|
192
|
+
$ "Respond to PR review comments"
|
|
193
|
+
|
|
194
|
+
Found 3 review comments, 2 addressed in this commit:
|
|
195
|
+
|
|
196
|
+
1. @reviewer on src/models.py:34
|
|
197
|
+
Comment: "user_name conflicts with User.username..."
|
|
198
|
+
Response: ✅ **Fixed**: Renamed to display_name to avoid conflict
|
|
199
|
+
|
|
200
|
+
2. @reviewer on src/forms.py:23
|
|
201
|
+
Comment: "Missing validation on age field..."
|
|
202
|
+
Response: ✅ **Fixed**: Added positive integer validation in clean_age()
|
|
203
|
+
|
|
204
|
+
Not addressed (no changes to these files):
|
|
205
|
+
3. @reviewer on src/views.py:56
|
|
206
|
+
Comment: "This profile logic should be in a service layer..."
|
|
207
|
+
[File not modified in this commit]
|
|
208
|
+
|
|
209
|
+
Post 2 responses to addressed comments? (y/n) y
|
|
210
|
+
What about the view.py comment? Add a response? (y/n) y
|
|
211
|
+
|
|
212
|
+
Custom response for src/views.py:56:
|
|
213
|
+
> 📝 **Noted**: Will refactor to service layer in separate PR to keep changes focused
|
|
214
|
+
|
|
215
|
+
Posted 3 responses to PR #89
|
|
216
|
+
Ready to push!
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Example 4: No Matching Changes (Warning)
|
|
222
|
+
|
|
223
|
+
**Scenario**: Committed changes don't address any review comments
|
|
224
|
+
|
|
225
|
+
**PR Context**:
|
|
226
|
+
- PR #52: "Add notification system"
|
|
227
|
+
- Reviewer: Reviewer
|
|
228
|
+
- Comment on `src/notifications.py:23`
|
|
229
|
+
|
|
230
|
+
**Review comment**:
|
|
231
|
+
```
|
|
232
|
+
The email sending logic should use async/await for better performance.
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
**Your changes** (commit on different topic):
|
|
236
|
+
```python
|
|
237
|
+
# Modified src/templates/notifications.html
|
|
238
|
+
# (Not related to the async/await comment)
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**Skill execution**:
|
|
242
|
+
```
|
|
243
|
+
$ "Respond to PR review comments"
|
|
244
|
+
|
|
245
|
+
Checking PR #52 for review comments...
|
|
246
|
+
|
|
247
|
+
Found 1 review comment on src/notifications.py:23
|
|
248
|
+
But your commit doesn't modify that file.
|
|
249
|
+
|
|
250
|
+
Review comment:
|
|
251
|
+
@reviewer: "The email sending logic should use async/await..."
|
|
252
|
+
|
|
253
|
+
Your changes:
|
|
254
|
+
- templates/notifications.html
|
|
255
|
+
|
|
256
|
+
No matching changes to respond to. Did you mean to address this comment?
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Example 5: Already Responded Comments (Filtered Out)
|
|
262
|
+
|
|
263
|
+
**Scenario**: Some comments already have responses
|
|
264
|
+
|
|
265
|
+
**PR Context**:
|
|
266
|
+
- PR #78: "Refactor authentication flow"
|
|
267
|
+
- Multiple commits addressing different comments
|
|
268
|
+
|
|
269
|
+
**Review comments**:
|
|
270
|
+
|
|
271
|
+
1. **src/auth.py:12** (ALREADY REPLIED):
|
|
272
|
+
```
|
|
273
|
+
Reviewer: "Use Django's built-in password validation"
|
|
274
|
+
You (yesterday): "✅ Fixed: Using validate_password()"
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
2. **src/views.py:45** (NOT REPLIED):
|
|
278
|
+
```
|
|
279
|
+
Reviewer: "Session timeout should be configurable"
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
**Your changes** (new commit):
|
|
283
|
+
```python
|
|
284
|
+
# src/settings.py (NEW)
|
|
285
|
+
SESSION_TIMEOUT = int(os.getenv('SESSION_TIMEOUT', '3600'))
|
|
286
|
+
|
|
287
|
+
# src/views.py (MODIFIED)
|
|
288
|
+
request.session.set_expiry(settings.SESSION_TIMEOUT)
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
**Skill execution**:
|
|
292
|
+
```
|
|
293
|
+
$ "Respond to PR review comments"
|
|
294
|
+
|
|
295
|
+
Checking PR #78 for review comments...
|
|
296
|
+
|
|
297
|
+
Found 2 review comments total:
|
|
298
|
+
- 1 already has replies (skipping)
|
|
299
|
+
- 1 needs response
|
|
300
|
+
|
|
301
|
+
Comments to respond to:
|
|
302
|
+
|
|
303
|
+
1. @reviewer on src/views.py:45
|
|
304
|
+
Comment: "Session timeout should be configurable"
|
|
305
|
+
Response: ✅ **Fixed**: Added SESSION_TIMEOUT env variable in settings
|
|
306
|
+
|
|
307
|
+
Post this response? (y/n) y
|
|
308
|
+
|
|
309
|
+
Posted 1 response to PR #78
|
|
310
|
+
(Skipped 1 already-replied comment)
|
|
311
|
+
|
|
312
|
+
Ready to push!
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## Example 6: General PR Comments (Not Inline)
|
|
318
|
+
|
|
319
|
+
**Scenario**: PR-level comments, not tied to specific code lines
|
|
320
|
+
|
|
321
|
+
**PR Context**:
|
|
322
|
+
- PR #91: "Add caching layer"
|
|
323
|
+
- General comment (not inline code review)
|
|
324
|
+
|
|
325
|
+
**Review comment** (general PR comment):
|
|
326
|
+
```
|
|
327
|
+
Reviewer: "Looks good overall! Can you add tests for the cache invalidation logic?"
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
**Your changes**:
|
|
331
|
+
```python
|
|
332
|
+
# tests/test_cache.py (NEW)
|
|
333
|
+
def test_cache_invalidation():
|
|
334
|
+
# Test implementation
|
|
335
|
+
pass
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
**Skill execution**:
|
|
339
|
+
```
|
|
340
|
+
$ "Respond to PR review comments"
|
|
341
|
+
|
|
342
|
+
Checking PR #91 for review comments...
|
|
343
|
+
|
|
344
|
+
Found 1 general PR comment (not inline):
|
|
345
|
+
@reviewer: "Looks good overall! Can you add tests..."
|
|
346
|
+
|
|
347
|
+
This is a general comment, not tied to specific code lines.
|
|
348
|
+
Cannot auto-respond to general comments.
|
|
349
|
+
|
|
350
|
+
Suggestion: Reply manually on GitHub or use gh CLI:
|
|
351
|
+
gh pr comment 91 -b "✅ **Added**: Cache invalidation tests in tests/test_cache.py"
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
## Example 7: Using Custom Responses
|
|
357
|
+
|
|
358
|
+
**Scenario**: Skill drafts response, but you want to customize
|
|
359
|
+
|
|
360
|
+
**PR Context**:
|
|
361
|
+
- PR #103: "Optimize database queries"
|
|
362
|
+
- Comment about N+1 query
|
|
363
|
+
|
|
364
|
+
**Review comment**:
|
|
365
|
+
```
|
|
366
|
+
This causes N+1 queries. Use select_related() or prefetch_related().
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
**Your changes**:
|
|
370
|
+
```python
|
|
371
|
+
# Before
|
|
372
|
+
users = User.objects.all()
|
|
373
|
+
for user in users:
|
|
374
|
+
print(user.profile.name) # N+1 query
|
|
375
|
+
|
|
376
|
+
# After
|
|
377
|
+
users = User.objects.select_related('profile').all()
|
|
378
|
+
for user in users:
|
|
379
|
+
print(user.profile.name) # Single query
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
**Skill execution**:
|
|
383
|
+
```
|
|
384
|
+
$ "Respond to PR review comments"
|
|
385
|
+
|
|
386
|
+
Found 1 review comment addressed:
|
|
387
|
+
|
|
388
|
+
1. @reviewer on src/queries.py:23
|
|
389
|
+
Comment: "This causes N+1 queries..."
|
|
390
|
+
Response: ✅ **Fixed**: Added select_related('profile')
|
|
391
|
+
|
|
392
|
+
Post this response? (y/n/edit) edit
|
|
393
|
+
|
|
394
|
+
Edit response:
|
|
395
|
+
> ✅ **Fixed**: Added select_related('profile') to eliminate N+1 query. Reduced from 100 queries to 1.
|
|
396
|
+
|
|
397
|
+
Post edited response? (y/n) y
|
|
398
|
+
|
|
399
|
+
Posted 1 response to PR #103
|
|
400
|
+
Ready to push!
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## Example 8: Multiple Commits, One Response Session
|
|
406
|
+
|
|
407
|
+
**Scenario**: Addressed different comments in multiple commits
|
|
408
|
+
|
|
409
|
+
**PR Context**:
|
|
410
|
+
- PR #115: "Refactor data models"
|
|
411
|
+
- Made 3 commits addressing different feedback
|
|
412
|
+
|
|
413
|
+
**Your commits**:
|
|
414
|
+
```
|
|
415
|
+
commit abc123: fix: rename conflicting field names
|
|
416
|
+
commit def456: refactor: extract validation to forms
|
|
417
|
+
commit ghi789: docs: add docstrings to model methods
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
**Skill execution** (run ONCE after all commits):
|
|
421
|
+
```
|
|
422
|
+
$ "Respond to all PR review comments for my recent commits"
|
|
423
|
+
|
|
424
|
+
Analyzing commits abc123..ghi789
|
|
425
|
+
|
|
426
|
+
Found 3 review comments addressed across 3 commits:
|
|
427
|
+
|
|
428
|
+
1. @reviewer on src/models.py:34 (fixed in abc123)
|
|
429
|
+
Comment: "user_name conflicts with User.username"
|
|
430
|
+
Response: ✅ **Fixed**: Renamed to display_name
|
|
431
|
+
|
|
432
|
+
2. @reviewer on src/views.py:45 (fixed in def456)
|
|
433
|
+
Comment: "Validation should be in forms, not views"
|
|
434
|
+
Response: ✅ **Fixed**: Moved validation to ProfileForm.clean()
|
|
435
|
+
|
|
436
|
+
3. @reviewer on src/models.py:12 (fixed in ghi789)
|
|
437
|
+
Comment: "Missing docstring on calculate_score method"
|
|
438
|
+
Response: ✅ **Fixed**: Added docstring explaining score calculation logic
|
|
439
|
+
|
|
440
|
+
Post all 3 responses? (y/n) y
|
|
441
|
+
|
|
442
|
+
Posted 3 responses to PR #115
|
|
443
|
+
Ready to push!
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
## Integration Patterns
|
|
449
|
+
|
|
450
|
+
### Pattern 1: Pre-Push Workflow
|
|
451
|
+
|
|
452
|
+
```bash
|
|
453
|
+
# Your workflow
|
|
454
|
+
git add .
|
|
455
|
+
git commit -m "fix: address PR feedback"
|
|
456
|
+
|
|
457
|
+
# Before pushing, respond to reviews
|
|
458
|
+
"Respond to PR review comments"
|
|
459
|
+
|
|
460
|
+
# Then push
|
|
461
|
+
git push
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
### Pattern 2: Slash Command
|
|
465
|
+
|
|
466
|
+
```bash
|
|
467
|
+
# Add to .claude/settings.json
|
|
468
|
+
{
|
|
469
|
+
"commands": {
|
|
470
|
+
"/respond": "Use pr-review-responder skill"
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
# Usage
|
|
475
|
+
/respond
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
### Pattern 3: Automated Hook
|
|
479
|
+
|
|
480
|
+
```bash
|
|
481
|
+
# .git/hooks/pre-push
|
|
482
|
+
#!/bin/bash
|
|
483
|
+
echo "Checking for review comments to respond to..."
|
|
484
|
+
claude "Use pr-review-responder skill for current changes"
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
### Pattern 4: Batch Review Response
|
|
488
|
+
|
|
489
|
+
```bash
|
|
490
|
+
# After fixing multiple PRs
|
|
491
|
+
cd project1 && "Respond to PR reviews" && git push
|
|
492
|
+
cd project2 && "Respond to PR reviews" && git push
|
|
493
|
+
cd project3 && "Respond to PR reviews" && git push
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
---
|
|
497
|
+
|
|
498
|
+
## Response Quality Examples
|
|
499
|
+
|
|
500
|
+
### Good Responses
|
|
501
|
+
|
|
502
|
+
✅ **Specific and actionable**:
|
|
503
|
+
```
|
|
504
|
+
✅ **Fixed**: Extracted upload logic to storage.upload_file()
|
|
505
|
+
✅ **Fixed**: Renamed user_name to display_name to avoid User.username conflict
|
|
506
|
+
✅ **Fixed**: Moved animation timing from Python context to CSS
|
|
507
|
+
✅ **Fixed**: Added type hints (int, str, Optional[Dict])
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
✅ **Acknowledges good feedback**:
|
|
511
|
+
```
|
|
512
|
+
✅ **Fixed**: Good catch! Removed duplicate error handling
|
|
513
|
+
✅ **Fixed**: You're right, using select_related() now
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
✅ **Explains non-obvious changes**:
|
|
517
|
+
```
|
|
518
|
+
✅ **Fixed**: Using Path().read_bytes() instead of wrapper (KISS)
|
|
519
|
+
✅ **Fixed**: Extracted to shared function (DRY principle)
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
### Bad Responses
|
|
523
|
+
|
|
524
|
+
❌ **Too vague**:
|
|
525
|
+
```
|
|
526
|
+
Fixed
|
|
527
|
+
Done
|
|
528
|
+
Updated code
|
|
529
|
+
Changed it
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
❌ **Too verbose**:
|
|
533
|
+
```
|
|
534
|
+
✅ **Fixed**: I removed the FileReader wrapper class that was
|
|
535
|
+
creating unnecessary abstraction and replaced it with a direct
|
|
536
|
+
call to Path().read_bytes() which is more straightforward and
|
|
537
|
+
follows the KISS principle as discussed in CLAUDE.md...
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
❌ **Defensive**:
|
|
541
|
+
```
|
|
542
|
+
Well, I thought the wrapper was cleaner but I changed it
|
|
543
|
+
I guess we can do it your way
|
|
544
|
+
Not sure why this is a problem but fixed
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
❌ **Argues in response**:
|
|
548
|
+
```
|
|
549
|
+
The wrapper class provides better encapsulation though
|
|
550
|
+
This is actually a valid pattern from Design Patterns book
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
---
|
|
554
|
+
|
|
555
|
+
## Advanced: Handling Complex Review Threads
|
|
556
|
+
|
|
557
|
+
**Scenario**: Long conversation thread on one comment
|
|
558
|
+
|
|
559
|
+
**Review thread**:
|
|
560
|
+
```
|
|
561
|
+
Reviewer: "This should use the shared upload function"
|
|
562
|
+
You: "Which shared function? I don't see one in the codebase"
|
|
563
|
+
Reviewer: "Check storage.py, upload_file()"
|
|
564
|
+
You: [makes the change]
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
**Skill behavior**:
|
|
568
|
+
- Detects existing conversation thread
|
|
569
|
+
- Posts reply at END of thread
|
|
570
|
+
- Keeps conversation context
|
|
571
|
+
|
|
572
|
+
**Posted response**:
|
|
573
|
+
```
|
|
574
|
+
✅ **Fixed**: Using storage.upload_file() as suggested
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
This appears after the conversation, making it clear this is the resolution.
|
|
578
|
+
|
|
579
|
+
---
|
|
580
|
+
|
|
581
|
+
## Summary
|
|
582
|
+
|
|
583
|
+
The pr-review-responder skill:
|
|
584
|
+
- Finds unresponded review comments
|
|
585
|
+
- Matches them to your code changes
|
|
586
|
+
- Drafts concise, specific responses
|
|
587
|
+
- Posts them to GitHub
|
|
588
|
+
- Makes PR feedback loops faster
|
|
589
|
+
|
|
590
|
+
Use it before every push to keep reviewers informed!
|