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.
Files changed (192) hide show
  1. agents/__init__.py +2 -0
  2. agents/coder/__init__.py +0 -0
  3. agents/coder/agent.json +4 -0
  4. agents/coder/api-integration.md +2150 -0
  5. agents/coder/cli-pretty.md +765 -0
  6. agents/coder/code-review.md +1092 -0
  7. agents/coder/database-design.md +1525 -0
  8. agents/coder/debugging.md +1102 -0
  9. agents/coder/dependency-management.md +1397 -0
  10. agents/coder/git-workflow.md +1099 -0
  11. agents/coder/refactoring.md +1454 -0
  12. agents/coder/security-hardening.md +1732 -0
  13. agents/coder/system_prompt.md +1448 -0
  14. agents/coder/tdd.md +1367 -0
  15. agents/creative-writer/__init__.py +0 -0
  16. agents/creative-writer/agent.json +4 -0
  17. agents/creative-writer/character-development.md +1852 -0
  18. agents/creative-writer/dialogue-craft.md +1122 -0
  19. agents/creative-writer/plot-structure.md +1073 -0
  20. agents/creative-writer/revision-editing.md +1484 -0
  21. agents/creative-writer/system_prompt.md +690 -0
  22. agents/creative-writer/worldbuilding.md +2049 -0
  23. agents/data-analyst/__init__.py +30 -0
  24. agents/data-analyst/agent.json +4 -0
  25. agents/data-analyst/data-visualization.md +992 -0
  26. agents/data-analyst/exploratory-data-analysis.md +1110 -0
  27. agents/data-analyst/pandas-data-manipulation.md +1081 -0
  28. agents/data-analyst/sql-query-optimization.md +881 -0
  29. agents/data-analyst/statistical-analysis.md +1118 -0
  30. agents/data-analyst/system_prompt.md +928 -0
  31. agents/default/__init__.py +0 -0
  32. agents/default/agent.json +4 -0
  33. agents/default/dead-code.md +794 -0
  34. agents/default/explore-agent-system.md +585 -0
  35. agents/default/system_prompt.md +1448 -0
  36. agents/kollabor/__init__.py +0 -0
  37. agents/kollabor/analyze-plugin-lifecycle.md +175 -0
  38. agents/kollabor/analyze-terminal-rendering.md +388 -0
  39. agents/kollabor/code-review.md +1092 -0
  40. agents/kollabor/debug-mcp-integration.md +521 -0
  41. agents/kollabor/debug-plugin-hooks.md +547 -0
  42. agents/kollabor/debugging.md +1102 -0
  43. agents/kollabor/dependency-management.md +1397 -0
  44. agents/kollabor/git-workflow.md +1099 -0
  45. agents/kollabor/inspect-llm-conversation.md +148 -0
  46. agents/kollabor/monitor-event-bus.md +558 -0
  47. agents/kollabor/profile-performance.md +576 -0
  48. agents/kollabor/refactoring.md +1454 -0
  49. agents/kollabor/system_prompt copy.md +1448 -0
  50. agents/kollabor/system_prompt.md +757 -0
  51. agents/kollabor/trace-command-execution.md +178 -0
  52. agents/kollabor/validate-config.md +879 -0
  53. agents/research/__init__.py +0 -0
  54. agents/research/agent.json +4 -0
  55. agents/research/architecture-mapping.md +1099 -0
  56. agents/research/codebase-analysis.md +1077 -0
  57. agents/research/dependency-audit.md +1027 -0
  58. agents/research/performance-profiling.md +1047 -0
  59. agents/research/security-review.md +1359 -0
  60. agents/research/system_prompt.md +492 -0
  61. agents/technical-writer/__init__.py +0 -0
  62. agents/technical-writer/agent.json +4 -0
  63. agents/technical-writer/api-documentation.md +2328 -0
  64. agents/technical-writer/changelog-management.md +1181 -0
  65. agents/technical-writer/readme-writing.md +1360 -0
  66. agents/technical-writer/style-guide.md +1410 -0
  67. agents/technical-writer/system_prompt.md +653 -0
  68. agents/technical-writer/tutorial-creation.md +1448 -0
  69. core/__init__.py +0 -2
  70. core/application.py +343 -88
  71. core/cli.py +229 -10
  72. core/commands/menu_renderer.py +463 -59
  73. core/commands/registry.py +14 -9
  74. core/commands/system_commands.py +2461 -14
  75. core/config/loader.py +151 -37
  76. core/config/service.py +18 -6
  77. core/events/bus.py +29 -9
  78. core/events/executor.py +205 -75
  79. core/events/models.py +27 -8
  80. core/fullscreen/command_integration.py +20 -24
  81. core/fullscreen/components/__init__.py +10 -1
  82. core/fullscreen/components/matrix_components.py +1 -2
  83. core/fullscreen/components/space_shooter_components.py +654 -0
  84. core/fullscreen/plugin.py +5 -0
  85. core/fullscreen/renderer.py +52 -13
  86. core/fullscreen/session.py +52 -15
  87. core/io/__init__.py +29 -5
  88. core/io/buffer_manager.py +6 -1
  89. core/io/config_status_view.py +7 -29
  90. core/io/core_status_views.py +267 -347
  91. core/io/input/__init__.py +25 -0
  92. core/io/input/command_mode_handler.py +711 -0
  93. core/io/input/display_controller.py +128 -0
  94. core/io/input/hook_registrar.py +286 -0
  95. core/io/input/input_loop_manager.py +421 -0
  96. core/io/input/key_press_handler.py +502 -0
  97. core/io/input/modal_controller.py +1011 -0
  98. core/io/input/paste_processor.py +339 -0
  99. core/io/input/status_modal_renderer.py +184 -0
  100. core/io/input_errors.py +5 -1
  101. core/io/input_handler.py +211 -2452
  102. core/io/key_parser.py +7 -0
  103. core/io/layout.py +15 -3
  104. core/io/message_coordinator.py +111 -2
  105. core/io/message_renderer.py +129 -4
  106. core/io/status_renderer.py +147 -607
  107. core/io/terminal_renderer.py +97 -51
  108. core/io/terminal_state.py +21 -4
  109. core/io/visual_effects.py +816 -165
  110. core/llm/agent_manager.py +1063 -0
  111. core/llm/api_adapters/__init__.py +44 -0
  112. core/llm/api_adapters/anthropic_adapter.py +432 -0
  113. core/llm/api_adapters/base.py +241 -0
  114. core/llm/api_adapters/openai_adapter.py +326 -0
  115. core/llm/api_communication_service.py +167 -113
  116. core/llm/conversation_logger.py +322 -16
  117. core/llm/conversation_manager.py +556 -30
  118. core/llm/file_operations_executor.py +84 -32
  119. core/llm/llm_service.py +934 -103
  120. core/llm/mcp_integration.py +541 -57
  121. core/llm/message_display_service.py +135 -18
  122. core/llm/plugin_sdk.py +1 -2
  123. core/llm/profile_manager.py +1183 -0
  124. core/llm/response_parser.py +274 -56
  125. core/llm/response_processor.py +16 -3
  126. core/llm/tool_executor.py +6 -1
  127. core/logging/__init__.py +2 -0
  128. core/logging/setup.py +34 -6
  129. core/models/resume.py +54 -0
  130. core/plugins/__init__.py +4 -2
  131. core/plugins/base.py +127 -0
  132. core/plugins/collector.py +23 -161
  133. core/plugins/discovery.py +37 -3
  134. core/plugins/factory.py +6 -12
  135. core/plugins/registry.py +5 -17
  136. core/ui/config_widgets.py +128 -28
  137. core/ui/live_modal_renderer.py +2 -1
  138. core/ui/modal_actions.py +5 -0
  139. core/ui/modal_overlay_renderer.py +0 -60
  140. core/ui/modal_renderer.py +268 -7
  141. core/ui/modal_state_manager.py +29 -4
  142. core/ui/widgets/base_widget.py +7 -0
  143. core/updates/__init__.py +10 -0
  144. core/updates/version_check_service.py +348 -0
  145. core/updates/version_comparator.py +103 -0
  146. core/utils/config_utils.py +685 -526
  147. core/utils/plugin_utils.py +1 -1
  148. core/utils/session_naming.py +111 -0
  149. fonts/LICENSE +21 -0
  150. fonts/README.md +46 -0
  151. fonts/SymbolsNerdFont-Regular.ttf +0 -0
  152. fonts/SymbolsNerdFontMono-Regular.ttf +0 -0
  153. fonts/__init__.py +44 -0
  154. {kollabor-0.4.9.dist-info → kollabor-0.4.15.dist-info}/METADATA +54 -4
  155. kollabor-0.4.15.dist-info/RECORD +228 -0
  156. {kollabor-0.4.9.dist-info → kollabor-0.4.15.dist-info}/top_level.txt +2 -0
  157. plugins/agent_orchestrator/__init__.py +39 -0
  158. plugins/agent_orchestrator/activity_monitor.py +181 -0
  159. plugins/agent_orchestrator/file_attacher.py +77 -0
  160. plugins/agent_orchestrator/message_injector.py +135 -0
  161. plugins/agent_orchestrator/models.py +48 -0
  162. plugins/agent_orchestrator/orchestrator.py +403 -0
  163. plugins/agent_orchestrator/plugin.py +976 -0
  164. plugins/agent_orchestrator/xml_parser.py +191 -0
  165. plugins/agent_orchestrator_plugin.py +9 -0
  166. plugins/enhanced_input/box_styles.py +1 -0
  167. plugins/enhanced_input/color_engine.py +19 -4
  168. plugins/enhanced_input/config.py +2 -2
  169. plugins/enhanced_input_plugin.py +61 -11
  170. plugins/fullscreen/__init__.py +6 -2
  171. plugins/fullscreen/example_plugin.py +1035 -222
  172. plugins/fullscreen/setup_wizard_plugin.py +592 -0
  173. plugins/fullscreen/space_shooter_plugin.py +131 -0
  174. plugins/hook_monitoring_plugin.py +436 -78
  175. plugins/query_enhancer_plugin.py +66 -30
  176. plugins/resume_conversation_plugin.py +1494 -0
  177. plugins/save_conversation_plugin.py +98 -32
  178. plugins/system_commands_plugin.py +70 -56
  179. plugins/tmux_plugin.py +154 -78
  180. plugins/workflow_enforcement_plugin.py +94 -92
  181. system_prompt/default.md +952 -886
  182. core/io/input_mode_manager.py +0 -402
  183. core/io/modal_interaction_handler.py +0 -315
  184. core/io/raw_input_processor.py +0 -946
  185. core/storage/__init__.py +0 -5
  186. core/storage/state_manager.py +0 -84
  187. core/ui/widget_integration.py +0 -222
  188. core/utils/key_reader.py +0 -171
  189. kollabor-0.4.9.dist-info/RECORD +0 -128
  190. {kollabor-0.4.9.dist-info → kollabor-0.4.15.dist-info}/WHEEL +0 -0
  191. {kollabor-0.4.9.dist-info → kollabor-0.4.15.dist-info}/entry_points.txt +0 -0
  192. {kollabor-0.4.9.dist-info → kollabor-0.4.15.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,1102 @@
1
+ <!-- Systematic Debugging skill - find and fix bugs efficiently using proven methodologies -->
2
+
3
+ debugging mode: SYSTEMATIC ELIMINATION
4
+
5
+ when this skill is active, you follow methodical debugging discipline.
6
+ this is a comprehensive guide to finding and fixing bugs systematically.
7
+
8
+
9
+ PHASE 0: DEBUGGING ENVIRONMENT VERIFICATION
10
+
11
+ before attempting ANY debugging, verify your tools are ready.
12
+
13
+
14
+ check python debugger availability
15
+
16
+ <terminal>python -c "import pdb; print('pdb available')"</terminal>
17
+
18
+ if pdb not available:
19
+ <terminal>pip install --upgrade pdb</terminal>
20
+
21
+ verify enhanced debugger:
22
+ <terminal>python -c "import ipdb; print('ipdb available')" 2>/dev/null || echo "ipdb not installed"</terminal>
23
+
24
+ if ipdb not installed (recommended but optional):
25
+ <terminal>pip install ipdb</terminal>
26
+
27
+
28
+ check logging configuration
29
+
30
+ <terminal>python -c "import logging; print('logging module ready')"</terminal>
31
+
32
+ verify log file locations:
33
+ <terminal>ls -la logs/ 2>/dev/null || ls -la .kollabor-cli/logs/ 2>/dev/null || echo "no logs directory"</terminal>
34
+
35
+ verify log levels:
36
+ <terminal>grep -r "logging.setLevel\|LOG_LEVEL" . --include="*.py" 2>/dev/null | head -5</terminal>
37
+
38
+
39
+ check git for bisecting
40
+
41
+ <terminal>git --version</terminal>
42
+
43
+ verify git repo:
44
+ <terminal>git status</terminal>
45
+
46
+ check for clean bisect state:
47
+ <terminal>git bisect reset 2>/dev/null || echo "no bisect in progress"</terminal>
48
+
49
+
50
+ check project structure
51
+
52
+ <terminal>ls -la</terminal>
53
+ <terminal>find . -name "*.py" -type f | head -20</terminal>
54
+
55
+ identify entry points:
56
+ <terminal>cat main.py 2>/dev/null | head -30</terminal>
57
+
58
+
59
+ check test coverage for regression tests
60
+
61
+ <terminal>python -m pytest --collect-only 2>&1 | head -20</terminal>
62
+
63
+ verify tests can run:
64
+ <terminal>python -m pytest tests/ --collect-only -q 2>&1 | tail -5</terminal>
65
+
66
+
67
+ check for existing error logs
68
+
69
+ <terminal>tail -50 .kollabor-cli/logs/kollabor.log 2>/dev/null || tail -50 logs/*.log 2>/dev/null || echo "no recent logs"</terminal>
70
+
71
+ check for crash reports:
72
+ <terminal>find . -name "*.crash" -o -name "*.stackdump" -o -name "core.*" 2>/dev/null</terminal>
73
+
74
+
75
+ verify strace/ltrace for system call tracing (linux)
76
+
77
+ <terminal>which strace ltrace 2>/dev/null || echo "system tracing not available"</terminal>
78
+
79
+ macos alternative:
80
+ <terminal>which dtruss 2>/dev/null || echo "dtruss not available (requires sudo)"</terminal>
81
+
82
+
83
+ PHASE 1: THE DEBUGGING MINDSET
84
+
85
+
86
+ understand before fixing
87
+
88
+ debugging is about understanding, not changing code.
89
+ every bug teaches you something about the system.
90
+ rush to fix = introduce more bugs.
91
+
92
+ the scientific method:
93
+
94
+ [1] observe - what is actually happening
95
+ [2] hypothesize - what could cause this
96
+ [3] predict - if hypothesis is true, then X should happen
97
+ [4] test - run experiment to verify prediction
98
+ [5] refine - update hypothesis based on results
99
+
100
+ repeat until you understand the root cause.
101
+ only then fix the code.
102
+
103
+
104
+ reproduce first
105
+
106
+ before touching any code:
107
+
108
+ [ ] can you reproduce the bug consistently?
109
+ [ ] what are the exact steps to reproduce?
110
+ [ ] what is the expected behavior?
111
+ [ ] what is the actual behavior?
112
+ [ ] what error messages appear?
113
+ [ ] when did this start happening?
114
+
115
+ if you cannot reproduce it:
116
+ - gather more information from user
117
+ - check logs for patterns
118
+ - identify conditions that might trigger it
119
+ - create hypothesis and test it
120
+
121
+ a bug you cannot reproduce is a bug you cannot verify is fixed.
122
+
123
+
124
+ isolate the problem
125
+
126
+ narrow down the scope:
127
+
128
+ is it in production or development only?
129
+ is it specific to certain data?
130
+ is it timing-related?
131
+ is it platform-specific?
132
+ is it configuration-dependent?
133
+
134
+ use binary search thinking:
135
+ - half the code, test, still broken?
136
+ - yes: bug is in that half
137
+ - no: bug is in other half
138
+ - repeat
139
+
140
+
141
+ PHASE 2: PRINT DEBUGGING
142
+
143
+
144
+ when to use print debugging
145
+
146
+ print debugging is appropriate for:
147
+ [ok] quick investigations
148
+ [ok] understanding control flow
149
+ [ok] verifying variable values
150
+ [ok] one-off debugging
151
+ [ok] situations without debugger access
152
+
153
+ not appropriate for:
154
+ [x] complex async code
155
+ [x] production debugging
156
+ [x] performance issues
157
+ [x] race conditions
158
+
159
+
160
+ effective print statements
161
+
162
+ bad prints:
163
+ print("here")
164
+ print("debug")
165
+ print(x)
166
+
167
+ good prints:
168
+ print(f"[DEBUG] process_data: input={input_data}, length={len(input_data)}")
169
+ print(f"[DEBUG] process_data: step 1 complete, processed={count} items")
170
+ print(f"[DEBUG] process_data: result={result}, errors={len(errors)}")
171
+
172
+ include:
173
+ - function name
174
+ - step or phase
175
+ - relevant variable values
176
+ - context about what you expect
177
+
178
+
179
+ structured logging instead of prints
180
+
181
+ use logging module:
182
+ import logging
183
+
184
+ logger = logging.getLogger(__name__)
185
+
186
+ def process_data(data):
187
+ logger.debug("process_data called with %d items", len(data))
188
+ logger.info("starting data processing")
189
+
190
+ for item in data:
191
+ logger.debug("processing item: %s", item)
192
+
193
+ logger.info("completed processing, result=%s", result)
194
+ return result
195
+
196
+ configure logging level:
197
+ logging.basicConfig(level=logging.DEBUG)
198
+
199
+ advantages over print:
200
+ - can be turned on/off globally
201
+ - includes timestamps
202
+ - includes file/line information
203
+ - can log to file
204
+ - different levels for different purposes
205
+
206
+
207
+ log levels guide
208
+
209
+ DEBUG: detailed diagnostic information
210
+ - variable values
211
+ - function entry/exit
212
+ - loop iterations
213
+
214
+ INFO: confirmation of expected progress
215
+ - application startup
216
+ - major milestones
217
+ - successful completions
218
+
219
+ WARNING: unexpected but recoverable
220
+ - missing optional data
221
+ - retries happening
222
+ - fallback behavior used
223
+
224
+ ERROR: serious failure
225
+ - exceptions caught
226
+ - failed operations
227
+ - data corruption
228
+
229
+ CRITICAL: severe failure
230
+ - application crash
231
+ - data loss
232
+ - cannot continue
233
+
234
+
235
+ log viewing techniques
236
+
237
+ view last N lines:
238
+ <terminal>tail -100 logs/app.log</terminal>
239
+
240
+ follow log in real-time:
241
+ <terminal>tail -f logs/app.log</terminal>
242
+
243
+ filter for errors:
244
+ <terminal>grep -i error logs/app.log</terminal>
245
+
246
+ filter for specific component:
247
+ <terminal>grep "process_data" logs/app.log</terminal>
248
+
249
+ view context around match:
250
+ <terminal>grep -C 5 "ERROR" logs/app.log</terminal>
251
+
252
+ count occurrences:
253
+ <terminal>grep -c "ERROR" logs/app.log</terminal>
254
+
255
+
256
+ PHASE 3: USING PDB DEBUGGER
257
+
258
+
259
+ basic pdb commands
260
+
261
+ start pdb:
262
+ <terminal>python -m pdb script.py</terminal>
263
+
264
+ or insert in code:
265
+ import pdb; pdb.set_trace()
266
+
267
+ essential commands:
268
+ l(ist) - show current code context
269
+ n(ext) - execute current line, move to next
270
+ s(tep) - step into function calls
271
+ c(ontinue) - run until next breakpoint
272
+ p(rint) - print expression
273
+ pp - pretty print expression
274
+ w(here) - show current stack frame
275
+ u(p) - move up stack frame
276
+ d(own) - move down stack frame
277
+ b(reak) - set breakpoint
278
+ cl(ear) - clear breakpoint
279
+ h(elp) - show help
280
+ q(uit) - quit debugger
281
+
282
+
283
+ setting breakpoints
284
+
285
+ set by line number:
286
+ (Pdb) break script.py:42
287
+
288
+ set by function:
289
+ (Pdb) break my_function
290
+
291
+ set conditional breakpoint:
292
+ (Pdb) break script.py:42, x > 100
293
+
294
+ view breakpoints:
295
+ (Pdb) break
296
+
297
+ clear breakpoint:
298
+ (Pdb) clear 1
299
+
300
+ clear all breakpoints:
301
+ (Pdb) clear
302
+
303
+
304
+ breakpoint() builtin (python 3.7+)
305
+
306
+ modern replacement for pdb.set_trace():
307
+
308
+ def complex_function(data):
309
+ result = process(data)
310
+ breakpoint() # drops into debugger
311
+ return analyze(result)
312
+
313
+ advantages:
314
+ - cleaner syntax
315
+ - can be disabled via PYTHONBREAKPOINT=0 env var
316
+ - works with custom debugger
317
+
318
+
319
+ inspecting variables
320
+
321
+ print variable:
322
+ (Pdb) p variable_name
323
+
324
+ pretty print:
325
+ (Pdb) pp complex_dict
326
+
327
+ examine attributes:
328
+ (Pdb) p object.__dict__
329
+
330
+ get type:
331
+ (Pdb) p type(variable)
332
+
333
+ get length:
334
+ (Pdb) p len(my_list)
335
+
336
+ call methods:
337
+ (Pdb) p my_dict.keys()
338
+
339
+ examine expression:
340
+ (Pdb) p x + y * 2
341
+
342
+
343
+ navigating the stack
344
+
345
+ show stack trace:
346
+ (Pdb) where
347
+
348
+ move to calling frame:
349
+ (Pdb) up
350
+
351
+ move back to callee:
352
+ (Pdb) down
353
+
354
+ view frame at level:
355
+ (Pdb) frame 2
356
+
357
+ examine variables in different frame:
358
+ (Pdb) up
359
+ (Pdb) p local_variable
360
+ (Pdb) down
361
+
362
+
363
+ modifying state
364
+
365
+ change variable value:
366
+ (Pdb) variable_name = new_value
367
+
368
+ execute statement:
369
+ (Pdb) import math; x = math.sqrt(16)
370
+
371
+ call function:
372
+ (Pdb) result = helper_function(x)
373
+
374
+ return from function early:
375
+ (Pdb) return value
376
+
377
+
378
+ post-mortem debugging
379
+
380
+ debug after crash:
381
+ import pdb
382
+ import sys
383
+
384
+ try:
385
+ risky_operation()
386
+ except Exception:
387
+ pdb.post_mortem()
388
+
389
+ or from command line:
390
+ <terminal>python -m pdb script.py</terminal>
391
+ # let it crash
392
+ (Pdb) where # shows crash location
393
+
394
+ or with exception:
395
+ <terminal>python -m pdb -c continue script.py</terminal>
396
+
397
+
398
+ PHASE 4: USING IPDB (ENHANCED DEBUGGER)
399
+
400
+
401
+ install and configure ipdb
402
+
403
+ <terminal>pip install ipdb</terminal>
404
+
405
+ set as default:
406
+ export PYTHONBREAKPOINT=ipdb.set_trace
407
+
408
+ use in code:
409
+ import ipdb; ipdb.set_trace()
410
+
411
+
412
+ ipdb advantages over pdb
413
+
414
+ - syntax highlighting
415
+ - tab completion
416
+ - better stack trace display
417
+ - context aware code display
418
+ - easier to read
419
+
420
+
421
+ ipdb-specific commands
422
+
423
+ h(elp) - show help with categories
424
+ ll - show more source code context
425
+ st(ep) - step into, showing code
426
+ n(ext) - next, skipping function calls
427
+ c(ontinue) - continue to next breakpoint
428
+ r(eturn) - continue until function returns
429
+ j(ump) lineno - jump to line number
430
+
431
+
432
+ ipdb configuration
433
+
434
+ create ~/.ipdbrc:
435
+ # ipdb configuration
436
+ alias st step
437
+ alias n next
438
+ alias c continue
439
+ alias list ll 50
440
+
441
+
442
+ PHASE 5: LOG ANALYSIS
443
+
444
+
445
+ reading log files effectively
446
+
447
+ start from the end:
448
+ <terminal>tail -500 logs/app.log | less</terminal>
449
+
450
+ search backward in less:
451
+ - use ? to search backward
452
+ - use n for next match
453
+ - use N for previous match
454
+
455
+
456
+ correlating timestamps
457
+
458
+ grep specific time range:
459
+ <terminal>grep "2024-01-15 10:2[3-4]" logs/app.log</terminal>
460
+
461
+ find time-adjacent entries:
462
+ <terminal>grep -A 10 -B 10 "ERROR" logs/app.log | head -30</terminal>
463
+
464
+
465
+ log pattern analysis
466
+
467
+ find unique error types:
468
+ <terminal>grep -o "ERROR: [A-Z].*" logs/app.log | sort -u</terminal>
469
+
470
+ count error frequency:
471
+ <terminal>grep "ERROR" logs/app.log | sort | uniq -c | sort -rn</terminal>
472
+
473
+ find exceptions:
474
+ <terminal>grep -i "exception\|traceback" logs/app.log -A 5</terminal>
475
+
476
+
477
+ structured logging with json
478
+
479
+ use json format for parsing:
480
+ import json
481
+ import logging
482
+
483
+ class JSONFormatter(logging.Formatter):
484
+ def format(self, record):
485
+ log_data = {
486
+ "timestamp": self.formatTime(record),
487
+ "level": record.levelname,
488
+ "logger": record.name,
489
+ "message": record.getMessage(),
490
+ "file": record.pathname,
491
+ "line": record.lineno
492
+ }
493
+ return json.dumps(log_data)
494
+
495
+ query json logs:
496
+ <terminal>grep "process_data" logs/app.log | jq '.level, .message'</terminal>
497
+
498
+
499
+ PHASE 6: GIT BISECT FOR REGRESSIONS
500
+
501
+
502
+ when to use git bisect
503
+
504
+ use when:
505
+ - bug appeared at some point in history
506
+ - you know a working version exists
507
+ - you cannot identify the problematic commit
508
+
509
+ bisect uses binary search through commits.
510
+
511
+
512
+ bisect workflow
513
+
514
+ start bisect:
515
+ <terminal>git bisect start</terminal>
516
+
517
+ mark current as bad:
518
+ <terminal>git bisect bad</terminal>
519
+
520
+ mark known good version:
521
+ <terminal>git bisect good <commit-hash></terminal>
522
+ or
523
+ <terminal>git bisect good v1.2.0</terminal>
524
+
525
+ git will checkout a middle commit.
526
+ test if bug exists:
527
+ [ ] if bug present: git bisect bad
528
+ [ ] if bug absent: git bisect good
529
+
530
+ repeat until git identifies the problematic commit.
531
+
532
+
533
+ automated bisect with script
534
+
535
+ create test script:
536
+ #!/bin/bash
537
+ # test_bug.sh
538
+ python -m pytest tests/test_specific.py -q
539
+ exit $? # exit 0 if pass, 1 if fail
540
+
541
+ make executable:
542
+ <terminal>chmod +x test_bug.sh</terminal>
543
+
544
+ run automated bisect:
545
+ <terminal>git bisect run ./test_bug.sh</terminal>
546
+
547
+
548
+ bisect cleanup
549
+
550
+ always reset when done:
551
+ <terminal>git bisect reset</terminal>
552
+
553
+ view bisect log:
554
+ <terminal>git bisect log</terminal>
555
+
556
+ replay bisect session:
557
+ <terminal>git bisect replay < logfile</terminal>
558
+
559
+
560
+ PHASE 7: MEMORY DEBUGGING
561
+
562
+
563
+ detecting memory leaks
564
+
565
+ use tracemalloc:
566
+ import tracemalloc
567
+
568
+ tracemalloc.start()
569
+
570
+ # ... code ...
571
+
572
+ snapshot = tracemalloc.take_snapshot()
573
+ top_stats = snapshot.statistics('lineno')
574
+
575
+ for stat in top_stats[:10]:
576
+ print(stat)
577
+
578
+
579
+ memory profiling with memory_profiler
580
+
581
+ <terminal>pip install memory_profiler</terminal>
582
+
583
+ decorate function:
584
+ from memory_profiler import profile
585
+
586
+ @profile
587
+ def memory_intensive_function():
588
+ # ...
589
+ pass
590
+
591
+ run profiler:
592
+ <terminal>python -m memory_profiler script.py</terminal>
593
+
594
+
595
+ finding reference cycles
596
+
597
+ use gc module:
598
+ import gc
599
+
600
+ # collect garbage
601
+ gc.collect()
602
+
603
+ # get unreachable objects
604
+ unreachable = gc.collect()
605
+ print(f"collected {unreachable} objects")
606
+
607
+ # get all objects
608
+ all_objects = gc.get_objects()
609
+ print(f"total objects: {len(all_objects)}")
610
+
611
+ # find ref cycles
612
+ cycles = gc.collect()
613
+ print(f"found {cycles} cycles")
614
+
615
+
616
+ debugging with objgraph
617
+
618
+ <terminal>pip install objgraph</terminal>
619
+
620
+ find growth:
621
+ import objgraph
622
+
623
+ objgraph.show_growth()
624
+
625
+ show references:
626
+ objgraph.show_backrefs(some_object)
627
+
628
+ find common types:
629
+ objgraph.show_most_common_types()
630
+
631
+
632
+ PHASE 8: PERFORMANCE DEBUGGING
633
+
634
+
635
+ profiling with cProfile
636
+
637
+ <terminal>python -m cProfile -o profile.stats script.py</terminal>
638
+
639
+ view results:
640
+ <terminal>python -c "import pstats; p=pstats.Stats('profile.stats'); p.sort_stats('cumulative'); p.print_stats(20)"</terminal>
641
+
642
+
643
+ profiling specific function
644
+
645
+ import cProfile
646
+ import pstats
647
+
648
+ def profile_function(func, *args, **kwargs):
649
+ profiler = cProfile.Profile()
650
+ profiler.enable()
651
+ result = func(*args, **kwargs)
652
+ profiler.disable()
653
+ stats = pstats.Stats(profiler)
654
+ stats.sort_stats('cumulative')
655
+ stats.print_stats(20)
656
+ return result
657
+
658
+
659
+ line profiling
660
+
661
+ <terminal>pip install line_profiler</terminal>
662
+
663
+ decorate:
664
+ from line_profiler import LineProfiler
665
+
666
+ @profile
667
+ def my_function():
668
+ # ...
669
+
670
+ profile:
671
+ <terminal>python -m kernprof -l -v script.py</terminal>
672
+
673
+
674
+ finding hot spots
675
+
676
+ common performance issues:
677
+ - nested loops with heavy computation
678
+ - repeated database queries in loops
679
+ - excessive string concatenation
680
+ - inefficient data structure choices
681
+ - missing indexes
682
+
683
+ identify by:
684
+ - looking for high cumulative time
685
+ - checking call counts (unusually high?)
686
+ - examining functions called in loops
687
+
688
+
689
+ PHASE 9: CONCURRENCY DEBUGGING
690
+
691
+
692
+ debugging race conditions
693
+
694
+ signs of race conditions:
695
+ - intermittent failures
696
+ - different results each run
697
+ - crashes only under load
698
+ - works on dev, fails in production
699
+
700
+ debugging techniques:
701
+ - add delays to expose timing issues
702
+ - add logging with timestamps
703
+ - use thread sanitizers
704
+ - increase concurrency to make it more likely
705
+
706
+
707
+ using logging for race conditions
708
+
709
+ add thread ID to logs:
710
+ import logging
711
+ import threading
712
+
713
+ formatter = logging.Formatter(
714
+ '%(asctime)s [%(threadName)s] %(message)s'
715
+ )
716
+
717
+ this shows which thread did what.
718
+
719
+
720
+ deadlock detection
721
+
722
+ look for:
723
+ - multiple threads acquiring locks in different orders
724
+ - locks held during I/O operations
725
+ - nested lock acquisition
726
+
727
+ prevention:
728
+ - always acquire locks in consistent order
729
+ - use timeout for lock acquisition
730
+ - minimize lock holding time
731
+
732
+
733
+ asyncio debugging
734
+
735
+ enable asyncio debug mode:
736
+ import asyncio
737
+
738
+ asyncio.run(main(), debug=True)
739
+
740
+ check for:
741
+ - missing await on coroutines
742
+ - blocking calls in async functions
743
+ - never-awaited coroutines
744
+
745
+ use:
746
+ <terminal>python -X dev script.py</terminal>
747
+
748
+
749
+ PHASE 10: COMMON BUG PATTERNS
750
+
751
+
752
+ pattern: off-by-one errors
753
+
754
+ symptoms:
755
+ - index out of range
756
+ - missing first/last element
757
+ - fencepost errors
758
+
759
+ examples:
760
+ for i in range(len(items)): # processes all items
761
+ for i in range(len(items) - 1): # misses last item!
762
+ for i in range(1, len(items)): # misses first item!
763
+
764
+ check:
765
+ [ ] loop boundaries
766
+ [ ] slice indices
767
+ [ ] range() arguments
768
+
769
+
770
+ pattern: None reference errors
771
+
772
+ symptoms:
773
+ - AttributeError: 'NoneType' object has no attribute
774
+ - TypeError: object of type 'None' has no len()
775
+
776
+ prevention:
777
+ def process(data):
778
+ if data is None:
779
+ return None
780
+ return data.transform()
781
+
782
+ or use exceptions:
783
+ def process(data):
784
+ if data is None:
785
+ raise ValueError("data cannot be None")
786
+ return data.transform()
787
+
788
+
789
+ pattern: mutation while iterating
790
+
791
+ symptoms:
792
+ - unexpected behavior in loops
793
+ - skipped or duplicated items
794
+
795
+ wrong:
796
+ for item in items:
797
+ if condition(item):
798
+ items.remove(item)
799
+
800
+ correct:
801
+ items = [item for item in items if not condition(item)]
802
+
803
+ or:
804
+ for item in items[:]: # iterate over copy
805
+ if condition(item):
806
+ items.remove(item)
807
+
808
+
809
+ pattern: string concatenation in loops
810
+
811
+ symptoms:
812
+ - slow performance
813
+ - high memory usage
814
+
815
+ wrong:
816
+ result = ""
817
+ for item in large_list:
818
+ result += str(item) # creates new string each time
819
+
820
+ correct:
821
+ parts = []
822
+ for item in large_list:
823
+ parts.append(str(item))
824
+ result = "".join(parts)
825
+
826
+
827
+ pattern: mutable default arguments
828
+
829
+ symptoms:
830
+ - state persists between calls
831
+ - unexpected data accumulation
832
+
833
+ wrong:
834
+ def append_item(item, items=[]):
835
+ items.append(item)
836
+ return items
837
+
838
+ correct:
839
+ def append_item(item, items=None):
840
+ if items is None:
841
+ items = []
842
+ items.append(item)
843
+ return items
844
+
845
+
846
+ pattern: catching too broad exceptions
847
+
848
+ wrong:
849
+ try:
850
+ complex_operation()
851
+ except: # catches everything, including SystemExit
852
+ pass
853
+
854
+ correct:
855
+ try:
856
+ complex_operation()
857
+ except (ValueError, TypeError) as e:
858
+ logger.error("specific error: %s", e)
859
+ raise # or handle appropriately
860
+
861
+
862
+ PHASE 11: SYSTEMATIC ELIMINATION
863
+
864
+
865
+ divide and conquer
866
+
867
+ half the problem space:
868
+ 1. identify midpoint in code flow
869
+ 2. add logging/checkpoint
870
+ 3. run and observe
871
+ 4. is bug before or after checkpoint?
872
+ 5. repeat in affected half
873
+
874
+ example:
875
+ def process_workflow(input_data):
876
+ logger.debug("step 1: validate")
877
+ validate(input_data)
878
+ logger.debug("step 2: transform")
879
+ result = transform(input_data)
880
+ logger.debug("step 3: save")
881
+ save(result)
882
+ logger.debug("step 4: notify")
883
+ notify(result)
884
+
885
+ if bug appears between step 2 and 3:
886
+ - focus on transform()
887
+ - add more granular logging inside transform()
888
+
889
+
890
+ minimization
891
+
892
+ reduce to minimal reproducible case:
893
+ 1. remove unnecessary code
894
+ 2. simplify input data
895
+ 3. isolate from dependencies
896
+ 4. create standalone test case
897
+
898
+ goal: smallest program that still shows the bug.
899
+
900
+
901
+ control the variables
902
+
903
+ change one thing at a time:
904
+ [ ] fix one potential issue
905
+ [ ] test
906
+ [ ] if fixed: done
907
+ [ ] if not fixed: revert, try next issue
908
+
909
+ multiple simultaneous changes confuse cause and effect.
910
+
911
+
912
+ PHASE 12: DEBUGGING CHECKLIST
913
+
914
+
915
+ initial investigation
916
+
917
+ [ ] can you reproduce the bug?
918
+ [ ] what are the exact steps?
919
+ [ ] what is the expected vs actual behavior?
920
+ [ ] when did this start happening?
921
+ [ ] has anything changed recently?
922
+
923
+
924
+ information gathering
925
+
926
+ [ ] check error messages and stack traces
927
+ [ ] check logs for related errors
928
+ [ ] check logs for warnings leading up to error
929
+ [ ] check system resources (memory, disk, cpu)
930
+ [ ] check configuration files
931
+ [ ] check environment variables
932
+
933
+
934
+ hypothesis formation
935
+
936
+ [ ] what is the most likely cause?
937
+ [ ] what evidence supports this?
938
+ [ ] what evidence contradicts this?
939
+ [ ] what test will confirm or deny?
940
+
941
+
942
+ verification
943
+
944
+ [ ] does your hypothesis explain all symptoms?
945
+ [ ] can you prove the hypothesis with a test?
946
+ [ ] does fixing the suspected issue resolve it?
947
+ [ ] does the fix break anything else?
948
+
949
+
950
+ documentation
951
+
952
+ [ ] document root cause
953
+ [ ] document how to reproduce
954
+ [ ] document the fix
955
+ [ ] add test to prevent regression
956
+
957
+
958
+ PHASE 13: REMOTE/PRODUCTION DEBUGGING
959
+
960
+
961
+ safe production debugging
962
+
963
+ rules:
964
+ [1] never add code that might crash
965
+ [2] never enable expensive operations
966
+ [3] never expose sensitive data
967
+ [4] always use logging level changes
968
+ [5] always have rollback plan
969
+
970
+
971
+ enable debug logging temporarily
972
+
973
+ change log level:
974
+ import logging
975
+
976
+ logging.getLogger('my.module').setLevel(logging.DEBUG)
977
+
978
+ reload config:
979
+ <terminal>kill -HUP <pid></terminal>
980
+
981
+ remember to revert after debugging.
982
+
983
+
984
+ using debug endpoints
985
+
986
+ add guarded debug endpoint:
987
+ @app.route('/debug/info')
988
+ def debug_info():
989
+ if not current_app.debug:
990
+ abort(404)
991
+ return jsonify({
992
+ "version": VERSION,
993
+ "config": {k: v for k, v in config.items()
994
+ if 'secret' not in k.lower()},
995
+ "stats": get_stats()
996
+ })
997
+
998
+ only available in debug mode.
999
+
1000
+
1001
+ core dumps for crashes
1002
+
1003
+ enable core dumps:
1004
+ <terminal>ulimit -c unlimited</terminal>
1005
+
1006
+ analyze with gdb:
1007
+ <terminal>gdb python core</terminal>
1008
+
1009
+ common gdb commands:
1010
+ bt - backtrace
1011
+ f 0 - select frame 0
1012
+ p var - print variable
1013
+
1014
+
1015
+ PHASE 14: DEBUGGING RULES (MANDATORY)
1016
+
1017
+
1018
+ while this skill is active, these rules are MANDATORY:
1019
+
1020
+ [1] REPRODUCE FIRST before attempting fixes
1021
+ if you cannot reproduce it, you cannot verify the fix
1022
+ gather more information until you can reproduce
1023
+
1024
+ [2] ONE CHANGE AT A TIME
1025
+ never change multiple things simultaneously
1026
+ test each change independently
1027
+
1028
+ [3] UNDERSTAND ROOT CAUSE before fixing
1029
+ a fix that "just works" without understanding
1030
+ will create more problems later
1031
+
1032
+ [4] ADD TEST FOR BUG before fixing
1033
+ this ensures you can verify the fix
1034
+ and prevents regression
1035
+
1036
+ [5] MINIMIZE THE REPRODUCTION CASE
1037
+ smaller test cases are easier to debug
1038
+ and prove you understand the issue
1039
+
1040
+ [6] DOCUMENT YOUR FINDINGS
1041
+ write down what you found
1042
+ future debuggers will thank you
1043
+
1044
+ [7] USE APPROPRIATE TOOLS
1045
+ print debugging for simple cases
1046
+ debugger for complex control flow
1047
+ logging for production issues
1048
+
1049
+ [8] NEVER IGNORE WARNINGS
1050
+ warnings often precede errors
1051
+ fix the warning, not just the error
1052
+
1053
+ [9] CHECK ASSUMPTIONS
1054
+ what you think is true might not be
1055
+ verify with code/tests
1056
+
1057
+ [10] FIX THE ROOT, NOT THE SYMPTOM
1058
+ error handling that swallows exceptions
1059
+ masks the real problem
1060
+
1061
+
1062
+ FINAL REMINDERS
1063
+
1064
+
1065
+ debugging is learning
1066
+
1067
+ every bug improves your understanding.
1068
+ the system is teaching you something.
1069
+ listen to what it says.
1070
+
1071
+
1072
+ slow is smooth, smooth is fast
1073
+
1074
+ systematic debugging beats quick fixes.
1075
+ the time you spend understanding
1076
+ saves time later.
1077
+
1078
+
1079
+ the answer is in the code
1080
+
1081
+ not in changing things randomly.
1082
+ not in trying random solutions.
1083
+ read the code, understand the flow.
1084
+
1085
+
1086
+ when stuck
1087
+
1088
+ [ ] step away, take a break
1089
+ [ ] explain the problem to someone else
1090
+ [ ] write down what you know
1091
+ [ ] question your assumptions
1092
+ [ ] try a different tool or approach
1093
+
1094
+
1095
+ the goal
1096
+
1097
+ not just to fix the bug.
1098
+ to understand why it happened.
1099
+ to prevent similar bugs.
1100
+ to improve the system.
1101
+
1102
+ now go find that bug.