kollabor 0.4.9__py3-none-any.whl → 0.4.15__py3-none-any.whl
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.
- agents/__init__.py +2 -0
- agents/coder/__init__.py +0 -0
- agents/coder/agent.json +4 -0
- agents/coder/api-integration.md +2150 -0
- agents/coder/cli-pretty.md +765 -0
- agents/coder/code-review.md +1092 -0
- agents/coder/database-design.md +1525 -0
- agents/coder/debugging.md +1102 -0
- agents/coder/dependency-management.md +1397 -0
- agents/coder/git-workflow.md +1099 -0
- agents/coder/refactoring.md +1454 -0
- agents/coder/security-hardening.md +1732 -0
- agents/coder/system_prompt.md +1448 -0
- agents/coder/tdd.md +1367 -0
- agents/creative-writer/__init__.py +0 -0
- agents/creative-writer/agent.json +4 -0
- agents/creative-writer/character-development.md +1852 -0
- agents/creative-writer/dialogue-craft.md +1122 -0
- agents/creative-writer/plot-structure.md +1073 -0
- agents/creative-writer/revision-editing.md +1484 -0
- agents/creative-writer/system_prompt.md +690 -0
- agents/creative-writer/worldbuilding.md +2049 -0
- agents/data-analyst/__init__.py +30 -0
- agents/data-analyst/agent.json +4 -0
- agents/data-analyst/data-visualization.md +992 -0
- agents/data-analyst/exploratory-data-analysis.md +1110 -0
- agents/data-analyst/pandas-data-manipulation.md +1081 -0
- agents/data-analyst/sql-query-optimization.md +881 -0
- agents/data-analyst/statistical-analysis.md +1118 -0
- agents/data-analyst/system_prompt.md +928 -0
- agents/default/__init__.py +0 -0
- agents/default/agent.json +4 -0
- agents/default/dead-code.md +794 -0
- agents/default/explore-agent-system.md +585 -0
- agents/default/system_prompt.md +1448 -0
- agents/kollabor/__init__.py +0 -0
- agents/kollabor/analyze-plugin-lifecycle.md +175 -0
- agents/kollabor/analyze-terminal-rendering.md +388 -0
- agents/kollabor/code-review.md +1092 -0
- agents/kollabor/debug-mcp-integration.md +521 -0
- agents/kollabor/debug-plugin-hooks.md +547 -0
- agents/kollabor/debugging.md +1102 -0
- agents/kollabor/dependency-management.md +1397 -0
- agents/kollabor/git-workflow.md +1099 -0
- agents/kollabor/inspect-llm-conversation.md +148 -0
- agents/kollabor/monitor-event-bus.md +558 -0
- agents/kollabor/profile-performance.md +576 -0
- agents/kollabor/refactoring.md +1454 -0
- agents/kollabor/system_prompt copy.md +1448 -0
- agents/kollabor/system_prompt.md +757 -0
- agents/kollabor/trace-command-execution.md +178 -0
- agents/kollabor/validate-config.md +879 -0
- agents/research/__init__.py +0 -0
- agents/research/agent.json +4 -0
- agents/research/architecture-mapping.md +1099 -0
- agents/research/codebase-analysis.md +1077 -0
- agents/research/dependency-audit.md +1027 -0
- agents/research/performance-profiling.md +1047 -0
- agents/research/security-review.md +1359 -0
- agents/research/system_prompt.md +492 -0
- agents/technical-writer/__init__.py +0 -0
- agents/technical-writer/agent.json +4 -0
- agents/technical-writer/api-documentation.md +2328 -0
- agents/technical-writer/changelog-management.md +1181 -0
- agents/technical-writer/readme-writing.md +1360 -0
- agents/technical-writer/style-guide.md +1410 -0
- agents/technical-writer/system_prompt.md +653 -0
- agents/technical-writer/tutorial-creation.md +1448 -0
- core/__init__.py +0 -2
- core/application.py +343 -88
- core/cli.py +229 -10
- core/commands/menu_renderer.py +463 -59
- core/commands/registry.py +14 -9
- core/commands/system_commands.py +2461 -14
- core/config/loader.py +151 -37
- core/config/service.py +18 -6
- core/events/bus.py +29 -9
- core/events/executor.py +205 -75
- core/events/models.py +27 -8
- core/fullscreen/command_integration.py +20 -24
- core/fullscreen/components/__init__.py +10 -1
- core/fullscreen/components/matrix_components.py +1 -2
- core/fullscreen/components/space_shooter_components.py +654 -0
- core/fullscreen/plugin.py +5 -0
- core/fullscreen/renderer.py +52 -13
- core/fullscreen/session.py +52 -15
- core/io/__init__.py +29 -5
- core/io/buffer_manager.py +6 -1
- core/io/config_status_view.py +7 -29
- core/io/core_status_views.py +267 -347
- core/io/input/__init__.py +25 -0
- core/io/input/command_mode_handler.py +711 -0
- core/io/input/display_controller.py +128 -0
- core/io/input/hook_registrar.py +286 -0
- core/io/input/input_loop_manager.py +421 -0
- core/io/input/key_press_handler.py +502 -0
- core/io/input/modal_controller.py +1011 -0
- core/io/input/paste_processor.py +339 -0
- core/io/input/status_modal_renderer.py +184 -0
- core/io/input_errors.py +5 -1
- core/io/input_handler.py +211 -2452
- core/io/key_parser.py +7 -0
- core/io/layout.py +15 -3
- core/io/message_coordinator.py +111 -2
- core/io/message_renderer.py +129 -4
- core/io/status_renderer.py +147 -607
- core/io/terminal_renderer.py +97 -51
- core/io/terminal_state.py +21 -4
- core/io/visual_effects.py +816 -165
- core/llm/agent_manager.py +1063 -0
- core/llm/api_adapters/__init__.py +44 -0
- core/llm/api_adapters/anthropic_adapter.py +432 -0
- core/llm/api_adapters/base.py +241 -0
- core/llm/api_adapters/openai_adapter.py +326 -0
- core/llm/api_communication_service.py +167 -113
- core/llm/conversation_logger.py +322 -16
- core/llm/conversation_manager.py +556 -30
- core/llm/file_operations_executor.py +84 -32
- core/llm/llm_service.py +934 -103
- core/llm/mcp_integration.py +541 -57
- core/llm/message_display_service.py +135 -18
- core/llm/plugin_sdk.py +1 -2
- core/llm/profile_manager.py +1183 -0
- core/llm/response_parser.py +274 -56
- core/llm/response_processor.py +16 -3
- core/llm/tool_executor.py +6 -1
- core/logging/__init__.py +2 -0
- core/logging/setup.py +34 -6
- core/models/resume.py +54 -0
- core/plugins/__init__.py +4 -2
- core/plugins/base.py +127 -0
- core/plugins/collector.py +23 -161
- core/plugins/discovery.py +37 -3
- core/plugins/factory.py +6 -12
- core/plugins/registry.py +5 -17
- core/ui/config_widgets.py +128 -28
- core/ui/live_modal_renderer.py +2 -1
- core/ui/modal_actions.py +5 -0
- core/ui/modal_overlay_renderer.py +0 -60
- core/ui/modal_renderer.py +268 -7
- core/ui/modal_state_manager.py +29 -4
- core/ui/widgets/base_widget.py +7 -0
- core/updates/__init__.py +10 -0
- core/updates/version_check_service.py +348 -0
- core/updates/version_comparator.py +103 -0
- core/utils/config_utils.py +685 -526
- core/utils/plugin_utils.py +1 -1
- core/utils/session_naming.py +111 -0
- fonts/LICENSE +21 -0
- fonts/README.md +46 -0
- fonts/SymbolsNerdFont-Regular.ttf +0 -0
- fonts/SymbolsNerdFontMono-Regular.ttf +0 -0
- fonts/__init__.py +44 -0
- {kollabor-0.4.9.dist-info → kollabor-0.4.15.dist-info}/METADATA +54 -4
- kollabor-0.4.15.dist-info/RECORD +228 -0
- {kollabor-0.4.9.dist-info → kollabor-0.4.15.dist-info}/top_level.txt +2 -0
- plugins/agent_orchestrator/__init__.py +39 -0
- plugins/agent_orchestrator/activity_monitor.py +181 -0
- plugins/agent_orchestrator/file_attacher.py +77 -0
- plugins/agent_orchestrator/message_injector.py +135 -0
- plugins/agent_orchestrator/models.py +48 -0
- plugins/agent_orchestrator/orchestrator.py +403 -0
- plugins/agent_orchestrator/plugin.py +976 -0
- plugins/agent_orchestrator/xml_parser.py +191 -0
- plugins/agent_orchestrator_plugin.py +9 -0
- plugins/enhanced_input/box_styles.py +1 -0
- plugins/enhanced_input/color_engine.py +19 -4
- plugins/enhanced_input/config.py +2 -2
- plugins/enhanced_input_plugin.py +61 -11
- plugins/fullscreen/__init__.py +6 -2
- plugins/fullscreen/example_plugin.py +1035 -222
- plugins/fullscreen/setup_wizard_plugin.py +592 -0
- plugins/fullscreen/space_shooter_plugin.py +131 -0
- plugins/hook_monitoring_plugin.py +436 -78
- plugins/query_enhancer_plugin.py +66 -30
- plugins/resume_conversation_plugin.py +1494 -0
- plugins/save_conversation_plugin.py +98 -32
- plugins/system_commands_plugin.py +70 -56
- plugins/tmux_plugin.py +154 -78
- plugins/workflow_enforcement_plugin.py +94 -92
- system_prompt/default.md +952 -886
- core/io/input_mode_manager.py +0 -402
- core/io/modal_interaction_handler.py +0 -315
- core/io/raw_input_processor.py +0 -946
- core/storage/__init__.py +0 -5
- core/storage/state_manager.py +0 -84
- core/ui/widget_integration.py +0 -222
- core/utils/key_reader.py +0 -171
- kollabor-0.4.9.dist-info/RECORD +0 -128
- {kollabor-0.4.9.dist-info → kollabor-0.4.15.dist-info}/WHEEL +0 -0
- {kollabor-0.4.9.dist-info → kollabor-0.4.15.dist-info}/entry_points.txt +0 -0
- {kollabor-0.4.9.dist-info → kollabor-0.4.15.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,1092 @@
|
|
|
1
|
+
<!-- Code Review skill - thorough reviews for security, performance, and maintainability -->
|
|
2
|
+
|
|
3
|
+
code-review mode: CRITICAL EYE, CONSTRUCTIVE VOICE
|
|
4
|
+
|
|
5
|
+
when this skill is active, you conduct systematic code reviews.
|
|
6
|
+
this is a comprehensive guide to reviewing code effectively.
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
PHASE 0: REVIEW ENVIRONMENT VERIFICATION
|
|
10
|
+
|
|
11
|
+
before conducting ANY review, verify your tools are ready.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
check git for diff viewing
|
|
15
|
+
|
|
16
|
+
<terminal>git --version</terminal>
|
|
17
|
+
|
|
18
|
+
verify git config for review:
|
|
19
|
+
<terminal>git config --get core.pager</terminal>
|
|
20
|
+
|
|
21
|
+
if pager not set or causing issues:
|
|
22
|
+
<terminal>git config --global core.pager "less -FRX"</terminal>
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
check for review tooling
|
|
26
|
+
|
|
27
|
+
verify GitHub CLI:
|
|
28
|
+
<terminal>gh --version 2>/dev/null || echo "gh not installed"</terminal>
|
|
29
|
+
|
|
30
|
+
if gh not installed (optional but recommended):
|
|
31
|
+
<terminal>brew install gh # macOS</terminal>
|
|
32
|
+
<terminal> # or: https://cli.github.com/</terminal>
|
|
33
|
+
|
|
34
|
+
verify authentication:
|
|
35
|
+
<terminal>gh auth status 2>/dev/null || echo "not authenticated"</terminal>
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
check diff tools
|
|
39
|
+
|
|
40
|
+
verify diff-highlight or similar:
|
|
41
|
+
<terminal>which diff-highlight 2>/dev/null || echo "diff-highlight not available"</terminal>
|
|
42
|
+
|
|
43
|
+
check for colordiff:
|
|
44
|
+
<terminal>which colordiff 2>/dev/null || echo "colordiff not available"</terminal>
|
|
45
|
+
|
|
46
|
+
if using delta (recommended):
|
|
47
|
+
<terminal>which delta 2>/dev/null || echo "delta not installed"</terminal>
|
|
48
|
+
|
|
49
|
+
install delta:
|
|
50
|
+
<terminal>brew install git-delta # macOS</terminal>
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
configure git for better diffs
|
|
54
|
+
|
|
55
|
+
add to ~/.gitconfig:
|
|
56
|
+
[core]
|
|
57
|
+
pager = delta
|
|
58
|
+
|
|
59
|
+
[delta]
|
|
60
|
+
side-by-side = true
|
|
61
|
+
line-numbers = true
|
|
62
|
+
syntax-theme = Monokai Extended
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
check for linters and formatters
|
|
66
|
+
|
|
67
|
+
verify python tools:
|
|
68
|
+
<terminal>python -m flake8 --version 2>/dev/null || echo "flake8 not installed"</terminal>
|
|
69
|
+
<terminal>python -m black --version 2>/dev/null || echo "black not installed"</terminal>
|
|
70
|
+
<terminal>python -m mypy --version 2>/dev/null || echo "mypy not installed"</terminal>
|
|
71
|
+
<terminal>python -m pylint --version 2>/dev/null || echo "pylint not installed"</terminal>
|
|
72
|
+
|
|
73
|
+
install if needed:
|
|
74
|
+
<terminal>pip install flake8 black mypy pylint isort</terminal>
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
check for security scanners
|
|
78
|
+
|
|
79
|
+
verify bandit:
|
|
80
|
+
<terminal>python -m bandit --version 2>/dev/null || echo "bandit not installed"</terminal>
|
|
81
|
+
|
|
82
|
+
if not installed:
|
|
83
|
+
<terminal>pip install bandit</terminal>
|
|
84
|
+
|
|
85
|
+
verify safety:
|
|
86
|
+
<terminal>python -m safety --version 2>/dev/null || echo "safety not installed"</terminal>
|
|
87
|
+
|
|
88
|
+
if not installed:
|
|
89
|
+
<terminal>pip install safety</terminal>
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
verify project access
|
|
93
|
+
|
|
94
|
+
<terminal>ls -la</terminal>
|
|
95
|
+
|
|
96
|
+
check for recent changes:
|
|
97
|
+
<terminal>git log --oneline -10</terminal>
|
|
98
|
+
|
|
99
|
+
check for uncommitted changes:
|
|
100
|
+
<terminal>git status</terminal>
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
check review checklist availability
|
|
104
|
+
|
|
105
|
+
<terminal>ls -la .github/*.md 2>/dev/null || echo "no github templates"</terminal>
|
|
106
|
+
<terminal>ls -la docs/*review*.md 2>/dev/null || echo "no review docs"</terminal>
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
PHASE 1: UNDERSTANDING THE CONTEXT
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
before reviewing code
|
|
113
|
+
|
|
114
|
+
understand the purpose:
|
|
115
|
+
[ ] what problem does this change solve?
|
|
116
|
+
[ ] what is the expected behavior?
|
|
117
|
+
[ ] what are the requirements/user stories?
|
|
118
|
+
[ ] are there related issues or tickets?
|
|
119
|
+
|
|
120
|
+
review the description:
|
|
121
|
+
[ ] is there a clear description of changes?
|
|
122
|
+
[ ] are the motivations explained?
|
|
123
|
+
[ ] are there edge cases mentioned?
|
|
124
|
+
[ ] is testing strategy described?
|
|
125
|
+
|
|
126
|
+
check the scope:
|
|
127
|
+
[ ] is the change too large?
|
|
128
|
+
[ ] should it be split into smaller reviews?
|
|
129
|
+
[ ] are unrelated changes included?
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
read the diff strategically
|
|
133
|
+
|
|
134
|
+
first pass - understanding:
|
|
135
|
+
1. read files changed, not lines changed
|
|
136
|
+
2. understand the overall structure
|
|
137
|
+
3. identify main components affected
|
|
138
|
+
4. note any architectural concerns
|
|
139
|
+
|
|
140
|
+
second pass - detailed review:
|
|
141
|
+
1. line-by-line examination
|
|
142
|
+
2. check for specific issues
|
|
143
|
+
3. verify implementation correctness
|
|
144
|
+
4. suggest improvements
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
viewing the diff effectively
|
|
148
|
+
|
|
149
|
+
view entire change:
|
|
150
|
+
<terminal>git diff HEAD~1</terminal>
|
|
151
|
+
|
|
152
|
+
view specific file:
|
|
153
|
+
<terminal>git diff HEAD~1 -- path/to/file.py</terminal>
|
|
154
|
+
|
|
155
|
+
view with context:
|
|
156
|
+
<terminal>git diff -U5 HEAD~1</terminal>
|
|
157
|
+
|
|
158
|
+
view word-based diff:
|
|
159
|
+
<terminal>git diff --word-diff HEAD~1</terminal>
|
|
160
|
+
|
|
161
|
+
view changed files only:
|
|
162
|
+
<terminal>git diff --name-only HEAD~1</terminal>
|
|
163
|
+
|
|
164
|
+
view stats:
|
|
165
|
+
<terminal>git diff --stat HEAD~1</terminal>
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
PHASE 2: SECURITY REVIEW
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
sql injection vulnerabilities
|
|
172
|
+
|
|
173
|
+
check for string concatenation in queries:
|
|
174
|
+
|
|
175
|
+
BAD:
|
|
176
|
+
query = f"SELECT * FROM users WHERE name = '{user_input}'"
|
|
177
|
+
cursor.execute(query)
|
|
178
|
+
|
|
179
|
+
GOOD:
|
|
180
|
+
query = "SELECT * FROM users WHERE name = %s"
|
|
181
|
+
cursor.execute(query, (user_input,))
|
|
182
|
+
|
|
183
|
+
checklist:
|
|
184
|
+
[ ] are all queries parameterized?
|
|
185
|
+
[ ] is any SQL built via string formatting?
|
|
186
|
+
[ ] are ORM methods used properly?
|
|
187
|
+
[ ] is raw SQL necessary and safe?
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
command injection vulnerabilities
|
|
191
|
+
|
|
192
|
+
check for shell command execution:
|
|
193
|
+
|
|
194
|
+
BAD:
|
|
195
|
+
os.system(f"process {filename}")
|
|
196
|
+
subprocess.call(f"cat {filename}", shell=True)
|
|
197
|
+
|
|
198
|
+
GOOD:
|
|
199
|
+
subprocess.call(["cat", filename])
|
|
200
|
+
subprocess.call("cat", filename, check=True)
|
|
201
|
+
|
|
202
|
+
checklist:
|
|
203
|
+
[ ] is shell=True avoided?
|
|
204
|
+
[ ] are commands passed as lists?
|
|
205
|
+
[ ] is user input validated before use?
|
|
206
|
+
[ ] is input sanitized/escaped?
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
cross-site scripting (xss)
|
|
210
|
+
|
|
211
|
+
check for unescaped output:
|
|
212
|
+
|
|
213
|
+
BAD:
|
|
214
|
+
return f"<div>{user_input}</div>"
|
|
215
|
+
|
|
216
|
+
GOOD:
|
|
217
|
+
return html.escape(f"<div>{user_input}</div>")
|
|
218
|
+
|
|
219
|
+
checklist:
|
|
220
|
+
[ ] is template auto-escaping enabled?
|
|
221
|
+
[ ] are manual escapes used where needed?
|
|
222
|
+
[ ] is user input sanitized?
|
|
223
|
+
[ ] are Content-Type headers set correctly?
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
authentication and authorization
|
|
227
|
+
|
|
228
|
+
check for auth issues:
|
|
229
|
+
[ ] is authentication enforced on protected endpoints?
|
|
230
|
+
[ ] is authorization checked before resource access?
|
|
231
|
+
[ ] are sessions managed securely?
|
|
232
|
+
[ ] are password requirements enforced?
|
|
233
|
+
[ ] are credentials hashed (bcrypt, argon2)?
|
|
234
|
+
[ ] is HTTPS enforced?
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
sensitive data exposure
|
|
238
|
+
|
|
239
|
+
check for data leaks:
|
|
240
|
+
[ ] are secrets in logs?
|
|
241
|
+
[ ] are secrets hardcoded?
|
|
242
|
+
[ ] are errors too verbose?
|
|
243
|
+
[ ] is sensitive data in URLs?
|
|
244
|
+
[ ] are API keys in repo?
|
|
245
|
+
[ ] is data encrypted at rest?
|
|
246
|
+
[ ] is data encrypted in transit?
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
check for hardcoded secrets
|
|
250
|
+
|
|
251
|
+
<terminal>grep -r "api[_-]key\|secret\|password\|token" . --include="*.py" | grep -v "# "</terminal>
|
|
252
|
+
<terminal>grep -r "sk_\|pk_\|ghp_\|AKIA" . --include="*.py"</terminal>
|
|
253
|
+
|
|
254
|
+
use environment variables instead:
|
|
255
|
+
import os
|
|
256
|
+
|
|
257
|
+
API_KEY = os.getenv("API_KEY")
|
|
258
|
+
if not API_KEY:
|
|
259
|
+
raise ValueError("API_KEY environment variable required")
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
common security vulnerabilities (owasp top 10)
|
|
263
|
+
|
|
264
|
+
[1] broken access control
|
|
265
|
+
- can users access others' data?
|
|
266
|
+
- is IDOR possible?
|
|
267
|
+
|
|
268
|
+
[2] cryptographic failures
|
|
269
|
+
- are outdated algorithms used (MD5, SHA1)?
|
|
270
|
+
- is encryption missing?
|
|
271
|
+
|
|
272
|
+
[3] injection
|
|
273
|
+
- SQL, NoSQL, OS, LDAP injection
|
|
274
|
+
- all user input must be validated
|
|
275
|
+
|
|
276
|
+
[4] insecure design
|
|
277
|
+
- are there missing security controls?
|
|
278
|
+
- is rate limiting implemented?
|
|
279
|
+
|
|
280
|
+
[5] security misconfiguration
|
|
281
|
+
- default credentials changed?
|
|
282
|
+
- debug mode off in production?
|
|
283
|
+
- unnecessary features disabled?
|
|
284
|
+
|
|
285
|
+
[6] vulnerable and outdated components
|
|
286
|
+
- are dependencies up to date?
|
|
287
|
+
- are known vulnerabilities present?
|
|
288
|
+
|
|
289
|
+
[7] identification and authentication failures
|
|
290
|
+
- password policies enforced?
|
|
291
|
+
- session timeout configured?
|
|
292
|
+
- multi-factor available?
|
|
293
|
+
|
|
294
|
+
[8] software and data integrity failures
|
|
295
|
+
- are updates verified?
|
|
296
|
+
- is CI/CD pipeline secure?
|
|
297
|
+
|
|
298
|
+
[9] security logging and monitoring
|
|
299
|
+
- are suspicious activities logged?
|
|
300
|
+
- is log tampering prevented?
|
|
301
|
+
|
|
302
|
+
[10] server-side request forgery (SSRF)
|
|
303
|
+
- can users trigger requests to internal systems?
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
PHASE 3: PERFORMANCE REVIEW
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
algorithmic complexity
|
|
310
|
+
|
|
311
|
+
check for:
|
|
312
|
+
[ ] nested loops (O(n^2) or worse)
|
|
313
|
+
[ ] repeated work in loops
|
|
314
|
+
[ ] inefficient data structures
|
|
315
|
+
[ ] missing indexes on database queries
|
|
316
|
+
|
|
317
|
+
examples:
|
|
318
|
+
|
|
319
|
+
BAD - O(n^2):
|
|
320
|
+
for item in items:
|
|
321
|
+
if item in other_items: # O(n) lookup
|
|
322
|
+
process(item)
|
|
323
|
+
|
|
324
|
+
GOOD - O(n):
|
|
325
|
+
other_set = set(other_items) # O(n) once
|
|
326
|
+
for item in items:
|
|
327
|
+
if item in other_set: # O(1) lookup
|
|
328
|
+
process(item)
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
database query patterns
|
|
332
|
+
|
|
333
|
+
check for:
|
|
334
|
+
[ ] N+1 queries (query in loop)
|
|
335
|
+
[ ] missing indexes
|
|
336
|
+
[ ] select * usage
|
|
337
|
+
[ ] missing pagination
|
|
338
|
+
|
|
339
|
+
examples:
|
|
340
|
+
|
|
341
|
+
BAD - N+1:
|
|
342
|
+
for user in users:
|
|
343
|
+
orders = get_orders(user.id) # N queries
|
|
344
|
+
|
|
345
|
+
GOOD - single query:
|
|
346
|
+
user_ids = [u.id for u in users]
|
|
347
|
+
orders = get_orders_for_users(user_ids) # 1 query
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
caching opportunities
|
|
351
|
+
|
|
352
|
+
look for:
|
|
353
|
+
[ ] repeated expensive calculations
|
|
354
|
+
[ ] repeated database queries
|
|
355
|
+
[ ] repeated API calls
|
|
356
|
+
[ ] expensive file reads
|
|
357
|
+
|
|
358
|
+
examples:
|
|
359
|
+
|
|
360
|
+
WITHOUT CACHE:
|
|
361
|
+
def get_user_data(user_id):
|
|
362
|
+
return fetch_from_database(user_id) # slow
|
|
363
|
+
|
|
364
|
+
WITH CACHE:
|
|
365
|
+
from functools import lru_cache
|
|
366
|
+
|
|
367
|
+
@lru_cache(maxsize=128)
|
|
368
|
+
def get_user_data(user_id):
|
|
369
|
+
return fetch_from_database(user_id)
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
memory efficiency
|
|
373
|
+
|
|
374
|
+
check for:
|
|
375
|
+
[ ] loading entire files into memory
|
|
376
|
+
[ ] holding references to large objects
|
|
377
|
+
[ ] memory leaks (unclosed connections)
|
|
378
|
+
[ ] unnecessary data copying
|
|
379
|
+
|
|
380
|
+
examples:
|
|
381
|
+
|
|
382
|
+
BAD - loads all at once:
|
|
383
|
+
with open("large_file.txt") as f:
|
|
384
|
+
data = f.readlines() # entire file in memory
|
|
385
|
+
for line in data:
|
|
386
|
+
process(line)
|
|
387
|
+
|
|
388
|
+
GOOD - streams:
|
|
389
|
+
with open("large_file.txt") as f:
|
|
390
|
+
for line in f: # one line at a time
|
|
391
|
+
process(line)
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
async/concurrency review
|
|
395
|
+
|
|
396
|
+
check async code:
|
|
397
|
+
[ ] blocking calls in async functions
|
|
398
|
+
[ ] missing await on coroutines
|
|
399
|
+
[ ] proper error handling in async
|
|
400
|
+
[ ] resource cleanup (closers, aclosers)
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
PHASE 4: CODE QUALITY REVIEW
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
naming and readability
|
|
407
|
+
|
|
408
|
+
check naming:
|
|
409
|
+
[ ] are variables self-descriptive?
|
|
410
|
+
[ ] is function name a verb phrase?
|
|
411
|
+
[ ] are constants UPPER_CASE?
|
|
412
|
+
[ ] are classes PascalCase?
|
|
413
|
+
[ ] are functions snake_case?
|
|
414
|
+
|
|
415
|
+
examples:
|
|
416
|
+
|
|
417
|
+
BAD:
|
|
418
|
+
def calc(x, y, z):
|
|
419
|
+
return x * y / z
|
|
420
|
+
|
|
421
|
+
GOOD:
|
|
422
|
+
def calculate_monthly_payment(
|
|
423
|
+
principal: float,
|
|
424
|
+
annual_rate: float,
|
|
425
|
+
months: int
|
|
426
|
+
) -> float:
|
|
427
|
+
return principal * annual_rate / months
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
function and class size
|
|
431
|
+
|
|
432
|
+
check for:
|
|
433
|
+
[ ] functions over 20-30 lines
|
|
434
|
+
[ ] classes over 200-300 lines
|
|
435
|
+
[ ] files over 500 lines
|
|
436
|
+
[ ] parameter lists over 4-5 parameters
|
|
437
|
+
|
|
438
|
+
if too large:
|
|
439
|
+
[ ] extract smaller functions
|
|
440
|
+
[ ] group related functions
|
|
441
|
+
[ ] split into multiple files
|
|
442
|
+
[ ] use parameter objects
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
duplication
|
|
446
|
+
|
|
447
|
+
check for:
|
|
448
|
+
[ ] copy-pasted code blocks
|
|
449
|
+
[ ] similar logic with slight variations
|
|
450
|
+
[ ] repeated patterns
|
|
451
|
+
|
|
452
|
+
dri principle - don't repeat yourself:
|
|
453
|
+
extract common logic
|
|
454
|
+
use functions/classes
|
|
455
|
+
use templates/composition
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
comments and documentation
|
|
459
|
+
|
|
460
|
+
check for:
|
|
461
|
+
[ ] confusing code without comments
|
|
462
|
+
[ ] outdated comments
|
|
463
|
+
[ ] obvious comments (noise)
|
|
464
|
+
[ ] missing docstrings on public functions
|
|
465
|
+
|
|
466
|
+
good comments explain WHY, not WHAT:
|
|
467
|
+
|
|
468
|
+
BAD - comments the obvious:
|
|
469
|
+
# increment the counter
|
|
470
|
+
count += 1
|
|
471
|
+
|
|
472
|
+
GOOD - explains the why:
|
|
473
|
+
# offset by 1 because database is 1-indexed
|
|
474
|
+
# but python arrays are 0-indexed
|
|
475
|
+
index = db_index - 1
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
type hints
|
|
479
|
+
|
|
480
|
+
check for:
|
|
481
|
+
[ ] missing type hints on public functions
|
|
482
|
+
[ ] inconsistent type hints
|
|
483
|
+
[ ] incorrect type hints
|
|
484
|
+
|
|
485
|
+
benefits:
|
|
486
|
+
- self-documenting
|
|
487
|
+
- catch errors early
|
|
488
|
+
- better IDE support
|
|
489
|
+
- easier refactoring
|
|
490
|
+
|
|
491
|
+
BAD:
|
|
492
|
+
def calculate(a, b):
|
|
493
|
+
return a + b
|
|
494
|
+
|
|
495
|
+
GOOD:
|
|
496
|
+
def calculate(a: int, b: int) -> int:
|
|
497
|
+
return a + b
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
PHASE 5: ERROR HANDLING REVIEW
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
exception handling
|
|
504
|
+
|
|
505
|
+
check for:
|
|
506
|
+
[ ] bare except clauses
|
|
507
|
+
[ ] catching Exception too broadly
|
|
508
|
+
[ ] swallowing exceptions
|
|
509
|
+
[ ] missing error handling
|
|
510
|
+
|
|
511
|
+
examples:
|
|
512
|
+
|
|
513
|
+
BAD:
|
|
514
|
+
try:
|
|
515
|
+
risky_operation()
|
|
516
|
+
except:
|
|
517
|
+
pass # silent failure
|
|
518
|
+
|
|
519
|
+
GOOD:
|
|
520
|
+
try:
|
|
521
|
+
risky_operation()
|
|
522
|
+
except (ValueError, TypeError) as e:
|
|
523
|
+
logger.error("operation failed: %s", e)
|
|
524
|
+
raise # or handle appropriately
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
resource cleanup
|
|
528
|
+
|
|
529
|
+
check for:
|
|
530
|
+
[ ] unclosed files
|
|
531
|
+
[ ] unclosed database connections
|
|
532
|
+
[ ] unclosed network sockets
|
|
533
|
+
[ ] unreleased locks
|
|
534
|
+
|
|
535
|
+
use context managers:
|
|
536
|
+
with open("file.txt") as f:
|
|
537
|
+
data = f.read()
|
|
538
|
+
# file automatically closed
|
|
539
|
+
|
|
540
|
+
with database.transaction():
|
|
541
|
+
# operations
|
|
542
|
+
pass
|
|
543
|
+
# transaction automatically committed/rolled back
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
validation
|
|
547
|
+
|
|
548
|
+
check for:
|
|
549
|
+
[ ] input validation at boundaries
|
|
550
|
+
[ ] validation of external data
|
|
551
|
+
[ ] type checking
|
|
552
|
+
[ ] range checking
|
|
553
|
+
[ ] sanitization of user input
|
|
554
|
+
|
|
555
|
+
examples:
|
|
556
|
+
|
|
557
|
+
BAD:
|
|
558
|
+
def process_age(age):
|
|
559
|
+
return age * 365 # what if age is negative?
|
|
560
|
+
|
|
561
|
+
GOOD:
|
|
562
|
+
def process_age(age: int) -> int:
|
|
563
|
+
if not isinstance(age, int):
|
|
564
|
+
raise TypeError("age must be an integer")
|
|
565
|
+
if age < 0 or age > 150:
|
|
566
|
+
raise ValueError("age must be between 0 and 150")
|
|
567
|
+
return age * 365
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
PHASE 6: TESTING REVIEW
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
test coverage
|
|
574
|
+
|
|
575
|
+
check for:
|
|
576
|
+
[ ] new code has tests
|
|
577
|
+
[ ] edge cases are tested
|
|
578
|
+
[ ] error paths are tested
|
|
579
|
+
[ ] tests are readable
|
|
580
|
+
|
|
581
|
+
run coverage:
|
|
582
|
+
<terminal>python -m pytest tests/ --cov=src --cov-report=term-missing</terminal>
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
test quality
|
|
586
|
+
|
|
587
|
+
check tests for:
|
|
588
|
+
[ ] clear intent (what is being tested?)
|
|
589
|
+
[ ] independence (no test pollution)
|
|
590
|
+
[ ] meaningful assertions
|
|
591
|
+
[ ] appropriate use of mocks
|
|
592
|
+
|
|
593
|
+
examples:
|
|
594
|
+
|
|
595
|
+
BAD:
|
|
596
|
+
def test_it_works():
|
|
597
|
+
# what does "it" refer to?
|
|
598
|
+
assert function() is not None
|
|
599
|
+
|
|
600
|
+
GOOD:
|
|
601
|
+
def test_calculate_discount_returns_zero_for_invalid_code():
|
|
602
|
+
result = calculate_discount("INVALID_CODE", 100)
|
|
603
|
+
assert result == 0
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
test organization
|
|
607
|
+
|
|
608
|
+
check for:
|
|
609
|
+
[ ] tests mirror code structure
|
|
610
|
+
[ ] related tests grouped
|
|
611
|
+
[ ] descriptive test names
|
|
612
|
+
[ ] proper fixtures used
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
PHASE 7: MAINTAINABILITY REVIEW
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
coupling and cohesion
|
|
619
|
+
|
|
620
|
+
check for:
|
|
621
|
+
[ ] high coupling (too many dependencies)
|
|
622
|
+
[ ] low cohesion (unrelated things together)
|
|
623
|
+
[ ] circular dependencies
|
|
624
|
+
|
|
625
|
+
signs of high coupling:
|
|
626
|
+
- changes require touching many files
|
|
627
|
+
- classes know too much about each other
|
|
628
|
+
- difficult to test in isolation
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
separation of concerns
|
|
632
|
+
|
|
633
|
+
check for:
|
|
634
|
+
[ ] business logic mixed with I/O
|
|
635
|
+
[ ] UI mixed with business logic
|
|
636
|
+
[ ] data access mixed with business rules
|
|
637
|
+
[ ] configuration mixed with code
|
|
638
|
+
|
|
639
|
+
layers should be separate:
|
|
640
|
+
- presentation (UI)
|
|
641
|
+
- business logic (domain)
|
|
642
|
+
- data access (persistence)
|
|
643
|
+
- infrastructure
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
extensibility
|
|
647
|
+
|
|
648
|
+
check for:
|
|
649
|
+
[ ] hard to change code
|
|
650
|
+
[ ] hard to add features
|
|
651
|
+
[ ] hard to reuse code
|
|
652
|
+
|
|
653
|
+
good signs:
|
|
654
|
+
- open/closed principle (open for extension, closed for modification)
|
|
655
|
+
- dependency injection
|
|
656
|
+
- strategy pattern for variations
|
|
657
|
+
- hooks/callbacks for customization
|
|
658
|
+
|
|
659
|
+
|
|
660
|
+
technical debt
|
|
661
|
+
|
|
662
|
+
identify debt:
|
|
663
|
+
[ ] TODO comments (are they stale?)
|
|
664
|
+
[ ] FIXME comments (urgent issues?)
|
|
665
|
+
[ ] HACK comments (workarounds?)
|
|
666
|
+
[ ] commented out code (remove or uncomment)
|
|
667
|
+
|
|
668
|
+
decide:
|
|
669
|
+
- should this be fixed now?
|
|
670
|
+
- can it be deferred?
|
|
671
|
+
- should there be an issue?
|
|
672
|
+
|
|
673
|
+
|
|
674
|
+
PHASE 8: PROJECT CONVENTIONS REVIEW
|
|
675
|
+
|
|
676
|
+
|
|
677
|
+
style guide compliance
|
|
678
|
+
|
|
679
|
+
check for:
|
|
680
|
+
[ ] PEP 8 compliance (Python)
|
|
681
|
+
[ ] project-specific style guide
|
|
682
|
+
[ ] consistent formatting
|
|
683
|
+
[ ] consistent naming
|
|
684
|
+
|
|
685
|
+
run linters:
|
|
686
|
+
<terminal>python -m flake8 src/</terminal>
|
|
687
|
+
<terminal>python -m black --check src/</terminal>
|
|
688
|
+
<terminal>python -m isort --check-only src/</terminal>
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
import organization
|
|
692
|
+
|
|
693
|
+
check for:
|
|
694
|
+
[ ] imports grouped (stdlib, third-party, local)
|
|
695
|
+
[ ] imports sorted alphabetically
|
|
696
|
+
[ ] no unused imports
|
|
697
|
+
[ ] no circular imports
|
|
698
|
+
|
|
699
|
+
correct order:
|
|
700
|
+
# standard library
|
|
701
|
+
import os
|
|
702
|
+
import sys
|
|
703
|
+
|
|
704
|
+
# third party
|
|
705
|
+
import requests
|
|
706
|
+
from fastapi import FastAPI
|
|
707
|
+
|
|
708
|
+
# local
|
|
709
|
+
from myapp.models import User
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
dependency management
|
|
713
|
+
|
|
714
|
+
check for:
|
|
715
|
+
[ ] new dependencies are necessary
|
|
716
|
+
[ ] alternatives in stdlib?
|
|
717
|
+
[ ] dependency is well-maintained
|
|
718
|
+
[ ] license compatibility
|
|
719
|
+
|
|
720
|
+
check for vulnerabilities:
|
|
721
|
+
<terminal>python -m safety check</terminal>
|
|
722
|
+
<terminal>pip-audit 2>/dev/null || echo "pip-audit not installed"</terminal>
|
|
723
|
+
|
|
724
|
+
|
|
725
|
+
PHASE 9: GIT WORKFLOW REVIEW
|
|
726
|
+
|
|
727
|
+
|
|
728
|
+
commit quality
|
|
729
|
+
|
|
730
|
+
check commits:
|
|
731
|
+
[ ] are commits atomic (one logical change)?
|
|
732
|
+
[ ] are commit messages clear?
|
|
733
|
+
[ ] is there a single squashed commit?
|
|
734
|
+
[ ] are merge commits avoided?
|
|
735
|
+
|
|
736
|
+
good commit format:
|
|
737
|
+
type(scope): brief description
|
|
738
|
+
|
|
739
|
+
detailed explanation of what and why
|
|
740
|
+
|
|
741
|
+
closes #123
|
|
742
|
+
|
|
743
|
+
|
|
744
|
+
PR/branch strategy
|
|
745
|
+
|
|
746
|
+
check:
|
|
747
|
+
[ ] is branch from main?
|
|
748
|
+
[ ] is PR description clear?
|
|
749
|
+
[ ] are related issues linked?
|
|
750
|
+
[ ] is PR size reasonable?
|
|
751
|
+
|
|
752
|
+
|
|
753
|
+
conflict resolution
|
|
754
|
+
|
|
755
|
+
check merge commits:
|
|
756
|
+
[ ] are conflicts resolved properly?
|
|
757
|
+
[ ] are conflict markers removed?
|
|
758
|
+
[ ] is the result tested?
|
|
759
|
+
|
|
760
|
+
|
|
761
|
+
PHASE 10: DOCUMENTATION REVIEW
|
|
762
|
+
|
|
763
|
+
|
|
764
|
+
code documentation
|
|
765
|
+
|
|
766
|
+
check for:
|
|
767
|
+
[ ] docstrings on public functions
|
|
768
|
+
[ ] docstrings on classes
|
|
769
|
+
[ ] docstrings on modules
|
|
770
|
+
[ ] parameter types documented
|
|
771
|
+
[ ] return types documented
|
|
772
|
+
[ ] exceptions documented
|
|
773
|
+
|
|
774
|
+
google style docstring:
|
|
775
|
+
def calculate_discount(price: float, discount_pct: float) -> float:
|
|
776
|
+
"""Calculate discounted price.
|
|
777
|
+
|
|
778
|
+
Args:
|
|
779
|
+
price: Original price.
|
|
780
|
+
discount_pct: Discount percentage (0-100).
|
|
781
|
+
|
|
782
|
+
Returns:
|
|
783
|
+
Discounted price.
|
|
784
|
+
|
|
785
|
+
Raises:
|
|
786
|
+
ValueError: If discount_pct is negative or > 100.
|
|
787
|
+
"""
|
|
788
|
+
|
|
789
|
+
|
|
790
|
+
readme and changelog
|
|
791
|
+
|
|
792
|
+
check:
|
|
793
|
+
[ ] is README updated for user-facing changes?
|
|
794
|
+
[ ] is CHANGELOG updated?
|
|
795
|
+
[ ] are breaking changes documented?
|
|
796
|
+
[ ] are migration guides provided?
|
|
797
|
+
|
|
798
|
+
|
|
799
|
+
inline comments
|
|
800
|
+
|
|
801
|
+
check for:
|
|
802
|
+
[ ] non-obvious logic explained
|
|
803
|
+
[ ] workarounds documented
|
|
804
|
+
[ ] external references cited
|
|
805
|
+
[ ] TODO/FIXME with context
|
|
806
|
+
|
|
807
|
+
|
|
808
|
+
PHASE 11: GIVING FEEDBACK
|
|
809
|
+
|
|
810
|
+
|
|
811
|
+
feedback principles
|
|
812
|
+
|
|
813
|
+
be constructive:
|
|
814
|
+
- focus on the code, not the person
|
|
815
|
+
- explain why, not just what
|
|
816
|
+
- suggest improvements, don't just criticize
|
|
817
|
+
- acknowledge good work
|
|
818
|
+
|
|
819
|
+
be specific:
|
|
820
|
+
- point to exact lines
|
|
821
|
+
- provide examples
|
|
822
|
+
- link to documentation
|
|
823
|
+
|
|
824
|
+
be prioritized:
|
|
825
|
+
- must fix vs nice to have
|
|
826
|
+
- security/performance vs style
|
|
827
|
+
|
|
828
|
+
|
|
829
|
+
comment templates
|
|
830
|
+
|
|
831
|
+
for issues:
|
|
832
|
+
[ISSUE] In `file.py:123`, this creates a security vulnerability.
|
|
833
|
+
The problem is that user_input is not sanitized before being used in
|
|
834
|
+
the SQL query. An attacker could inject malicious SQL.
|
|
835
|
+
|
|
836
|
+
Consider using parameterized queries instead:
|
|
837
|
+
```python
|
|
838
|
+
cursor.execute("SELECT * FROM users WHERE name = %s", (user_input,))
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
for suggestions:
|
|
842
|
+
[SUGGESTION] In `file.py:456`, we could improve readability by
|
|
843
|
+
extracting this logic into a named function. This would also make
|
|
844
|
+
it easier to test.
|
|
845
|
+
|
|
846
|
+
for questions:
|
|
847
|
+
[QUESTION] In `file.py:789`, what's the reason for using a list
|
|
848
|
+
comprehension here instead of a generator? Is the intermediate
|
|
849
|
+
list needed?
|
|
850
|
+
|
|
851
|
+
|
|
852
|
+
responding to feedback
|
|
853
|
+
|
|
854
|
+
as reviewer:
|
|
855
|
+
[ ] be open to discussion
|
|
856
|
+
[ ] admit if you're wrong
|
|
857
|
+
[ ] learn from others
|
|
858
|
+
[ ] be patient with explanations
|
|
859
|
+
|
|
860
|
+
as author:
|
|
861
|
+
[ ] address each comment
|
|
862
|
+
[ ] explain if not making change
|
|
863
|
+
[ ] thank the reviewer
|
|
864
|
+
[ ] update PR as discussed
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
PHASE 12: COMMON REVIEW ISSUES
|
|
868
|
+
|
|
869
|
+
|
|
870
|
+
frequently overlooked issues
|
|
871
|
+
|
|
872
|
+
[1] off-by-one errors
|
|
873
|
+
loops that skip first/last element
|
|
874
|
+
range() arguments incorrect
|
|
875
|
+
|
|
876
|
+
[2] mutation of default arguments
|
|
877
|
+
def foo(items=[]):
|
|
878
|
+
pass # list is shared across calls!
|
|
879
|
+
|
|
880
|
+
[3] missing error handling
|
|
881
|
+
no try/except on risky operations
|
|
882
|
+
no validation of inputs
|
|
883
|
+
|
|
884
|
+
[4] resource leaks
|
|
885
|
+
unclosed files/connections
|
|
886
|
+
missing cleanup code
|
|
887
|
+
|
|
888
|
+
[5] race conditions
|
|
889
|
+
shared state without locks
|
|
890
|
+
missing atomic operations
|
|
891
|
+
|
|
892
|
+
[6] unhandled edge cases
|
|
893
|
+
empty inputs
|
|
894
|
+
None values
|
|
895
|
+
boundary conditions
|
|
896
|
+
|
|
897
|
+
|
|
898
|
+
red flags in code
|
|
899
|
+
|
|
900
|
+
- TODO or FIXME comments in production code
|
|
901
|
+
- commented out code (delete or uncomment)
|
|
902
|
+
- large copy-pasted blocks
|
|
903
|
+
- deeply nested code (indent > 4)
|
|
904
|
+
- functions longer than a page
|
|
905
|
+
- many parameters (>5)
|
|
906
|
+
- global variables
|
|
907
|
+
- multiple returns
|
|
908
|
+
- complex boolean expressions
|
|
909
|
+
- magic numbers without explanation
|
|
910
|
+
|
|
911
|
+
|
|
912
|
+
PHASE 13: AUTOMATED REVIEW CHECKS
|
|
913
|
+
|
|
914
|
+
|
|
915
|
+
run linters
|
|
916
|
+
|
|
917
|
+
flake8 (style and errors):
|
|
918
|
+
<terminal>python -m flake8 src/ --max-line-length=100</terminal>
|
|
919
|
+
|
|
920
|
+
black (formatting):
|
|
921
|
+
<terminal>python -m black --check src/</terminal>
|
|
922
|
+
|
|
923
|
+
isort (import sorting):
|
|
924
|
+
<terminal>python -m isort --check-only src/</terminal>
|
|
925
|
+
|
|
926
|
+
mypy (type checking):
|
|
927
|
+
<terminal>python -m mypy src/</terminal>
|
|
928
|
+
|
|
929
|
+
pylint (comprehensive):
|
|
930
|
+
<terminal>python -m pylint src/</terminal>
|
|
931
|
+
|
|
932
|
+
|
|
933
|
+
run security scanners
|
|
934
|
+
|
|
935
|
+
bandit (security issues):
|
|
936
|
+
<terminal>python -m bandit -r src/</terminal>
|
|
937
|
+
|
|
938
|
+
safety (dependency vulnerabilities):
|
|
939
|
+
<terminal>python -m safety check --full-report</terminal>
|
|
940
|
+
|
|
941
|
+
|
|
942
|
+
run tests
|
|
943
|
+
|
|
944
|
+
<terminal>python -m pytest tests/ -v</terminal>
|
|
945
|
+
|
|
946
|
+
with coverage:
|
|
947
|
+
<terminal>python -m pytest tests/ --cov=src --cov-report=term-missing</terminal>
|
|
948
|
+
|
|
949
|
+
|
|
950
|
+
check for common patterns
|
|
951
|
+
|
|
952
|
+
grep for potential issues:
|
|
953
|
+
<terminal>grep -r "print(" src/ --include="*.py" | grep -v "# "</terminal>
|
|
954
|
+
<terminal>grep -r "import \*" src/ --include="*.py"</terminal>
|
|
955
|
+
<terminal>grep -r "except:" src/ --include="*.py"</terminal>
|
|
956
|
+
<terminal>grep -r "TODO\|FIXME\|XXX\|HACK" src/ --include="*.py"</terminal>
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
PHASE 14: REVIEW CHECKLIST
|
|
960
|
+
|
|
961
|
+
|
|
962
|
+
before approval
|
|
963
|
+
|
|
964
|
+
must have:
|
|
965
|
+
[ ] tests for new functionality
|
|
966
|
+
[ ] tests pass locally
|
|
967
|
+
[ ] linters pass
|
|
968
|
+
[ ] documentation updated
|
|
969
|
+
[ ] changelog updated
|
|
970
|
+
[ ] no secrets committed
|
|
971
|
+
[ ] no debug prints left
|
|
972
|
+
[ ] security review passed
|
|
973
|
+
[ ] performance considered
|
|
974
|
+
[ ] error handling in place
|
|
975
|
+
|
|
976
|
+
|
|
977
|
+
for each file changed
|
|
978
|
+
|
|
979
|
+
[ ] purpose is clear
|
|
980
|
+
[ ] implementation is correct
|
|
981
|
+
[ ] style is consistent
|
|
982
|
+
[ ] no obvious bugs
|
|
983
|
+
[ ] error handling present
|
|
984
|
+
[ ] tests are adequate
|
|
985
|
+
[ ] docs are updated
|
|
986
|
+
|
|
987
|
+
|
|
988
|
+
before requesting changes
|
|
989
|
+
|
|
990
|
+
categorize your comments:
|
|
991
|
+
[MUST] blocking issues (security, bugs, critical)
|
|
992
|
+
[SHOULD] important improvements
|
|
993
|
+
[COULD] optional enhancements
|
|
994
|
+
[NIT] minor style issues (optional to fix)
|
|
995
|
+
|
|
996
|
+
|
|
997
|
+
PHASE 15: CODE REVIEW RULES (MANDATORY)
|
|
998
|
+
|
|
999
|
+
|
|
1000
|
+
while this skill is active, these rules are MANDATORY:
|
|
1001
|
+
|
|
1002
|
+
[1] REVIEW THE CHANGE, NOT THE PERSON
|
|
1003
|
+
focus on code quality, not coder ability
|
|
1004
|
+
be constructive, not critical
|
|
1005
|
+
suggest, don't command
|
|
1006
|
+
|
|
1007
|
+
[2] UNDERSTAND BEFORE CRITIQUING
|
|
1008
|
+
read the whole change first
|
|
1009
|
+
understand the context
|
|
1010
|
+
ask questions before judging
|
|
1011
|
+
|
|
1012
|
+
[3] EXPLAIN THE WHY
|
|
1013
|
+
don't just say "change this"
|
|
1014
|
+
explain the reasoning
|
|
1015
|
+
provide examples
|
|
1016
|
+
|
|
1017
|
+
[4] PRIORITIZE ISSUES
|
|
1018
|
+
flag security and correctness issues
|
|
1019
|
+
note performance concerns
|
|
1020
|
+
suggest style improvements separately
|
|
1021
|
+
|
|
1022
|
+
[5] BE SPECIFIC
|
|
1023
|
+
point to exact lines
|
|
1024
|
+
provide code examples
|
|
1025
|
+
link to documentation
|
|
1026
|
+
|
|
1027
|
+
[6] ACKNOWLEDGE GOOD WORK
|
|
1028
|
+
note what you like
|
|
1029
|
+
appreciate effort
|
|
1030
|
+
encourage good patterns
|
|
1031
|
+
|
|
1032
|
+
[7] BE THOROUGH BUT EFFICIENT
|
|
1033
|
+
review all changed code
|
|
1034
|
+
focus on what matters
|
|
1035
|
+
don't bikeshed
|
|
1036
|
+
|
|
1037
|
+
[8] FOLLOW UP
|
|
1038
|
+
re-review after changes
|
|
1039
|
+
ensure all issues addressed
|
|
1040
|
+
close the loop
|
|
1041
|
+
|
|
1042
|
+
[9] LEARN AND TEACH
|
|
1043
|
+
share knowledge
|
|
1044
|
+
explain concepts
|
|
1045
|
+
be open to learning yourself
|
|
1046
|
+
|
|
1047
|
+
[10] DOCUMENT YOUR REVIEW
|
|
1048
|
+
keep notes of common issues
|
|
1049
|
+
update checklists
|
|
1050
|
+
improve the process
|
|
1051
|
+
|
|
1052
|
+
|
|
1053
|
+
FINAL REMINDERS
|
|
1054
|
+
|
|
1055
|
+
|
|
1056
|
+
code review is mentoring
|
|
1057
|
+
|
|
1058
|
+
the goal is better code and better developers.
|
|
1059
|
+
teach and learn in every review.
|
|
1060
|
+
invest in your team's growth.
|
|
1061
|
+
|
|
1062
|
+
|
|
1063
|
+
quality takes time
|
|
1064
|
+
|
|
1065
|
+
a rushed review misses issues.
|
|
1066
|
+
thorough review prevents bugs later.
|
|
1067
|
+
the time invested pays dividends.
|
|
1068
|
+
|
|
1069
|
+
|
|
1070
|
+
be human
|
|
1071
|
+
|
|
1072
|
+
code review can be stressful.
|
|
1073
|
+
be kind and constructive.
|
|
1074
|
+
appreciate the effort behind every PR.
|
|
1075
|
+
|
|
1076
|
+
|
|
1077
|
+
when in doubt
|
|
1078
|
+
|
|
1079
|
+
[ ] ask questions instead of asserting
|
|
1080
|
+
[ ] suggest rather than demand
|
|
1081
|
+
[ ] discuss in person if needed
|
|
1082
|
+
[ ] offer to pair on solutions
|
|
1083
|
+
|
|
1084
|
+
|
|
1085
|
+
the goal
|
|
1086
|
+
|
|
1087
|
+
shipping quality software.
|
|
1088
|
+
building a learning team.
|
|
1089
|
+
creating shared understanding.
|
|
1090
|
+
maintaining code health.
|
|
1091
|
+
|
|
1092
|
+
now go review some code.
|