claude-mpm 4.15.6__py3-none-any.whl → 4.21.0__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.

Potentially problematic release.


This version of claude-mpm might be problematic. Click here for more details.

Files changed (194) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_ENGINEER.md +286 -0
  3. claude_mpm/agents/BASE_PM.md +272 -23
  4. claude_mpm/agents/PM_INSTRUCTIONS.md +49 -0
  5. claude_mpm/agents/agent_loader.py +4 -4
  6. claude_mpm/agents/templates/engineer.json +5 -1
  7. claude_mpm/agents/templates/php-engineer.json +10 -4
  8. claude_mpm/agents/templates/python_engineer.json +8 -3
  9. claude_mpm/agents/templates/rust_engineer.json +12 -7
  10. claude_mpm/agents/templates/svelte-engineer.json +225 -0
  11. claude_mpm/cli/commands/__init__.py +2 -0
  12. claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
  13. claude_mpm/cli/commands/mpm_init/core.py +525 -0
  14. claude_mpm/cli/commands/mpm_init/display.py +341 -0
  15. claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
  16. claude_mpm/cli/commands/mpm_init/modes.py +397 -0
  17. claude_mpm/cli/commands/mpm_init/prompts.py +442 -0
  18. claude_mpm/cli/commands/mpm_init_cli.py +396 -0
  19. claude_mpm/cli/commands/mpm_init_handler.py +67 -1
  20. claude_mpm/cli/commands/skills.py +488 -0
  21. claude_mpm/cli/executor.py +2 -0
  22. claude_mpm/cli/parsers/base_parser.py +7 -0
  23. claude_mpm/cli/parsers/mpm_init_parser.py +42 -0
  24. claude_mpm/cli/parsers/skills_parser.py +137 -0
  25. claude_mpm/cli/startup.py +57 -0
  26. claude_mpm/commands/mpm-auto-configure.md +52 -0
  27. claude_mpm/commands/mpm-help.md +3 -0
  28. claude_mpm/commands/mpm-init.md +112 -6
  29. claude_mpm/commands/mpm-version.md +113 -0
  30. claude_mpm/commands/mpm.md +1 -0
  31. claude_mpm/config/agent_config.py +2 -2
  32. claude_mpm/constants.py +12 -0
  33. claude_mpm/core/config.py +42 -0
  34. claude_mpm/core/factories.py +1 -1
  35. claude_mpm/core/interfaces.py +56 -1
  36. claude_mpm/core/optimized_agent_loader.py +3 -3
  37. claude_mpm/hooks/__init__.py +8 -0
  38. claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
  39. claude_mpm/hooks/session_resume_hook.py +121 -0
  40. claude_mpm/models/resume_log.py +340 -0
  41. claude_mpm/services/agents/auto_config_manager.py +1 -1
  42. claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
  43. claude_mpm/services/agents/deployment/agent_record_service.py +1 -1
  44. claude_mpm/services/agents/deployment/agent_validator.py +17 -1
  45. claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
  46. claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
  47. claude_mpm/services/agents/local_template_manager.py +1 -1
  48. claude_mpm/services/agents/recommender.py +47 -0
  49. claude_mpm/services/cli/resume_service.py +617 -0
  50. claude_mpm/services/cli/session_manager.py +87 -0
  51. claude_mpm/services/cli/session_pause_manager.py +504 -0
  52. claude_mpm/services/cli/session_resume_helper.py +372 -0
  53. claude_mpm/services/core/interfaces.py +56 -1
  54. claude_mpm/services/core/models/agent_config.py +3 -0
  55. claude_mpm/services/core/models/process.py +4 -0
  56. claude_mpm/services/core/path_resolver.py +1 -1
  57. claude_mpm/services/diagnostics/models.py +21 -0
  58. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  59. claude_mpm/services/local_ops/__init__.py +2 -0
  60. claude_mpm/services/mcp_config_manager.py +7 -131
  61. claude_mpm/services/mcp_gateway/auto_configure.py +31 -25
  62. claude_mpm/services/mcp_gateway/core/process_pool.py +19 -10
  63. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +26 -21
  64. claude_mpm/services/session_manager.py +205 -1
  65. claude_mpm/services/unified/deployment_strategies/local.py +1 -1
  66. claude_mpm/services/version_service.py +104 -1
  67. claude_mpm/skills/__init__.py +21 -0
  68. claude_mpm/skills/agent_skills_injector.py +324 -0
  69. claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
  70. claude_mpm/skills/bundled/api-documentation.md +393 -0
  71. claude_mpm/skills/bundled/async-testing.md +571 -0
  72. claude_mpm/skills/bundled/code-review.md +143 -0
  73. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  74. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  75. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  76. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  77. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  78. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  79. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  80. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  81. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  82. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  83. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  84. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  85. claude_mpm/skills/bundled/database-migration.md +199 -0
  86. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  87. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  88. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  89. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  90. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  91. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  92. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  93. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  94. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  95. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  96. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  97. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  98. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  99. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  100. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  101. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  102. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  103. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  104. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  105. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  106. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  107. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  108. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  109. claude_mpm/skills/bundled/git-workflow.md +414 -0
  110. claude_mpm/skills/bundled/imagemagick.md +204 -0
  111. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  112. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  113. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  114. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  115. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  116. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  117. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  118. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  119. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  120. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  121. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  122. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  123. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  124. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  125. claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
  126. claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
  127. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  128. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  129. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  130. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  131. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  132. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  133. claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
  134. claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
  135. claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
  136. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  137. claude_mpm/skills/bundled/pdf.md +141 -0
  138. claude_mpm/skills/bundled/performance-profiling.md +567 -0
  139. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  140. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  141. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  142. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  143. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  144. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  145. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  146. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  147. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  148. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  149. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  150. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  151. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  152. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  153. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  154. claude_mpm/skills/bundled/security-scanning.md +327 -0
  155. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  156. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  157. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  158. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  159. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  160. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  161. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  162. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  163. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  164. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  165. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  166. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  167. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  168. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  169. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  170. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  171. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  172. claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
  173. claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
  174. claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
  175. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  176. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  177. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
  178. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  179. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  180. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  181. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  182. claude_mpm/skills/bundled/xlsx.md +157 -0
  183. claude_mpm/skills/registry.py +97 -9
  184. claude_mpm/skills/skills_registry.py +348 -0
  185. claude_mpm/skills/skills_service.py +739 -0
  186. claude_mpm/utils/agent_dependency_loader.py +2 -2
  187. {claude_mpm-4.15.6.dist-info → claude_mpm-4.21.0.dist-info}/METADATA +211 -33
  188. {claude_mpm-4.15.6.dist-info → claude_mpm-4.21.0.dist-info}/RECORD +192 -60
  189. claude_mpm/agents/INSTRUCTIONS_OLD_DEPRECATED.md +0 -602
  190. claude_mpm/cli/commands/mpm_init.py +0 -2008
  191. {claude_mpm-4.15.6.dist-info → claude_mpm-4.21.0.dist-info}/WHEEL +0 -0
  192. {claude_mpm-4.15.6.dist-info → claude_mpm-4.21.0.dist-info}/entry_points.txt +0 -0
  193. {claude_mpm-4.15.6.dist-info → claude_mpm-4.21.0.dist-info}/licenses/LICENSE +0 -0
  194. {claude_mpm-4.15.6.dist-info → claude_mpm-4.21.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,411 @@
1
+ # Core Testing Anti-Patterns
2
+
3
+ The three most critical testing anti-patterns that violate fundamental testing principles. These patterns test mock behavior instead of real behavior, pollute production code with test concerns, or mock without understanding dependencies.
4
+
5
+ ## Anti-Pattern 1: Testing Mock Behavior
6
+
7
+ **The violation:**
8
+ ```typescript
9
+ // ❌ BAD: Testing that the mock exists
10
+ test('renders sidebar', () => {
11
+ render(<Page />);
12
+ expect(screen.getByTestId('sidebar-mock')).toBeInTheDocument();
13
+ });
14
+ ```
15
+
16
+ **Why this is wrong:**
17
+ - You're verifying the mock works, not that the component works
18
+ - Test passes when mock is present, fails when it's not
19
+ - Tells you nothing about real behavior
20
+ - False confidence - production may still be broken
21
+
22
+ **your human partner's correction:** "Are we testing the behavior of a mock?"
23
+
24
+ **The fix:**
25
+ ```typescript
26
+ // ✅ GOOD: Test real component or don't mock it
27
+ test('renders sidebar', () => {
28
+ render(<Page />); // Don't mock sidebar
29
+ expect(screen.getByRole('navigation')).toBeInTheDocument();
30
+ });
31
+
32
+ // OR if sidebar must be mocked for isolation:
33
+ // Don't assert on the mock - test Page's behavior with sidebar present
34
+ test('page layout includes sidebar area', () => {
35
+ render(<Page />); // Sidebar mocked for speed
36
+ expect(screen.getByRole('main')).toHaveClass('with-sidebar-layout');
37
+ });
38
+ ```
39
+
40
+ ### Detection Strategy
41
+
42
+ **Red flags:**
43
+ - Assertions check for `*-mock` in test IDs
44
+ - Test IDs contain "mock", "stub", "fake"
45
+ - Test fails when you remove the mock
46
+ - Can't explain what real behavior you're testing
47
+
48
+ **Gate Function:**
49
+
50
+ ```
51
+ BEFORE asserting on any mock element:
52
+ Ask: "Am I testing real component behavior or just mock existence?"
53
+
54
+ IF testing mock existence:
55
+ STOP - Delete the assertion or unmock the component
56
+
57
+ Ask: "What would this test verify in production?"
58
+
59
+ IF answer is "nothing" or unclear:
60
+ STOP - Rethink what you're testing
61
+
62
+ Test real behavior instead
63
+ ```
64
+
65
+ ### When Mocking is Appropriate
66
+
67
+ **Good reasons to mock:**
68
+ - Isolate slow external dependencies (network, filesystem, DB)
69
+ - Control non-deterministic behavior (time, randomness)
70
+ - Simulate error conditions hard to trigger
71
+ - Speed up test execution
72
+
73
+ **Bad reasons to mock:**
74
+ - "Might be slow" (without measuring)
75
+ - "To be safe"
76
+ - "Everyone mocks this"
77
+ - To avoid understanding dependencies
78
+
79
+ **Rule:** Mock at the boundary of slow/external operations, not high-level application logic.
80
+
81
+ ## Anti-Pattern 2: Test-Only Methods in Production
82
+
83
+ **The violation:**
84
+ ```typescript
85
+ // ❌ BAD: destroy() only used in tests
86
+ class Session {
87
+ async destroy() { // Looks like production API!
88
+ await this._workspaceManager?.destroyWorkspace(this.id);
89
+ await this._messageRouter?.cleanup();
90
+ this._isDestroyed = true;
91
+ }
92
+ }
93
+
94
+ // In tests
95
+ afterEach(() => session.destroy());
96
+ ```
97
+
98
+ **Why this is wrong:**
99
+ - Production class polluted with test-only code
100
+ - Dangerous if accidentally called in production
101
+ - Violates YAGNI (You Aren't Gonna Need It)
102
+ - Violates separation of concerns
103
+ - Confuses object lifecycle with entity lifecycle
104
+ - Creates maintenance burden (unused code in production)
105
+
106
+ **The fix:**
107
+ ```typescript
108
+ // ✅ GOOD: Test utilities handle test cleanup
109
+ // Session has no destroy() - it's stateless in production
110
+
111
+ // In test-utils/session-helpers.ts
112
+ export async function cleanupSession(session: Session) {
113
+ const workspace = session.getWorkspaceInfo();
114
+ if (workspace) {
115
+ await workspaceManager.destroyWorkspace(workspace.id);
116
+ }
117
+
118
+ const router = session.getMessageRouter();
119
+ if (router) {
120
+ await router.cleanup();
121
+ }
122
+ }
123
+
124
+ // In tests
125
+ afterEach(() => cleanupSession(session));
126
+ ```
127
+
128
+ ### When Test Utilities Make Sense
129
+
130
+ **Good candidates for test utilities:**
131
+ - Setup/teardown operations
132
+ - Test data builders
133
+ - Assertion helpers
134
+ - Test-specific configurations
135
+ - Lifecycle management for tests
136
+
137
+ **Keep in production:**
138
+ - Methods used by application code
139
+ - Proper public API
140
+ - Business logic
141
+ - Real lifecycle methods (close, dispose)
142
+
143
+ **Key distinction:** If it's never called outside test files, it shouldn't be in production code.
144
+
145
+ ### Detection Strategy
146
+
147
+ **Red flags:**
148
+ - Method only called in `*.test.*` or `*.spec.*` files
149
+ - Method name suggests testing (reset, clear, destroy, mock)
150
+ - Comments say "for testing only"
151
+ - Method has no production use case
152
+
153
+ **Gate Function:**
154
+
155
+ ```
156
+ BEFORE adding any method to production class:
157
+ Ask: "Is this only used by tests?"
158
+
159
+ IF yes:
160
+ STOP - Don't add it
161
+ Put it in test utilities instead (test-utils/, test-helpers/)
162
+
163
+ Ask: "Does this class own this resource's lifecycle?"
164
+
165
+ IF no:
166
+ STOP - Wrong class for this method
167
+ Resource owner should manage lifecycle
168
+
169
+ Ask: "Would production code ever call this?"
170
+
171
+ IF no:
172
+ STOP - Belongs in test utilities
173
+ ```
174
+
175
+ ### Refactoring Existing Test-Only Methods
176
+
177
+ **Step-by-step:**
178
+
179
+ 1. **Identify** - Find methods only called in test files
180
+ 2. **Extract** - Create test utility function with same logic
181
+ 3. **Migrate** - Update tests to use utility
182
+ 4. **Remove** - Delete test-only method from production
183
+ 5. **Verify** - Production builds/bundles are cleaner
184
+
185
+ **Example refactoring:**
186
+
187
+ ```typescript
188
+ // Before: Production class polluted
189
+ class Database {
190
+ async reset() { /* only for tests */ }
191
+ }
192
+
193
+ // After: Clean separation
194
+ // database.ts - production
195
+ class Database {
196
+ // No reset() method
197
+ }
198
+
199
+ // test-utils/database.ts - tests only
200
+ export async function resetTestDatabase(db: Database) {
201
+ // Use public API to achieve reset
202
+ await db.executeRaw('TRUNCATE ALL TABLES');
203
+ }
204
+ ```
205
+
206
+ ## Anti-Pattern 3: Mocking Without Understanding
207
+
208
+ **The violation:**
209
+ ```typescript
210
+ // ❌ BAD: Mock breaks test logic
211
+ test('detects duplicate server', async () => {
212
+ // Mock prevents config write that test depends on!
213
+ vi.mock('ToolCatalog', () => ({
214
+ discoverAndCacheTools: vi.fn().mockResolvedValue(undefined)
215
+ }));
216
+
217
+ await addServer(config);
218
+ await addServer(config); // Should throw - but won't!
219
+ // Test expects duplicate detection, but mock broke it
220
+ });
221
+ ```
222
+
223
+ **Why this is wrong:**
224
+ - Mocked method had side effect test depended on (writing config)
225
+ - Over-mocking to "be safe" breaks actual behavior
226
+ - Test passes for wrong reason or fails mysteriously
227
+ - You're testing mock behavior, not real behavior
228
+
229
+ **The fix:**
230
+ ```typescript
231
+ // ✅ GOOD: Mock at correct level
232
+ test('detects duplicate server', async () => {
233
+ // Mock the slow part, preserve behavior test needs
234
+ vi.mock('MCPServerManager'); // Just mock slow server startup
235
+ // Config writing preserved - duplicate detection works
236
+
237
+ await addServer(config); // Config written
238
+ await expect(addServer(config)).rejects.toThrow('already exists');
239
+ });
240
+ ```
241
+
242
+ ### Understanding Dependencies Before Mocking
243
+
244
+ **Questions to ask BEFORE mocking:**
245
+
246
+ 1. **What does the real method do?**
247
+ - Read the implementation
248
+ - Check for side effects
249
+ - Identify return values
250
+ - Note error conditions
251
+
252
+ 2. **What side effects exist?**
253
+ - Filesystem writes
254
+ - Database updates
255
+ - Cache modifications
256
+ - State changes
257
+ - Event emissions
258
+
259
+ 3. **What does THIS test need?**
260
+ - Which side effects matter?
261
+ - What behavior am I testing?
262
+ - What can be safely isolated?
263
+
264
+ 4. **Where should I mock?**
265
+ - At the boundary of slow operations
266
+ - Below the logic being tested
267
+ - At external system interfaces
268
+
269
+ ### Dependency Analysis Example
270
+
271
+ ```typescript
272
+ // Analyzing: Should I mock discoverAndCacheTools()?
273
+
274
+ // 1. Read implementation
275
+ async function discoverAndCacheTools(serverConfig) {
276
+ const tools = await fetchToolsFromServer(serverConfig); // Slow
277
+ await cacheTools(serverConfig.id, tools); // Side effect!
278
+ return tools;
279
+ }
280
+
281
+ // 2. Identify side effects
282
+ // - Network call (slow)
283
+ // - Cache write (side effect tests may depend on)
284
+
285
+ // 3. Determine test needs
286
+ test('server registration prevents duplicates', () => {
287
+ // Needs: Config persistence to detect duplicate
288
+ // Doesn't need: Actual tool discovery (slow)
289
+ });
290
+
291
+ // 4. Mock at correct level
292
+ // ✅ Mock network, preserve cache
293
+ vi.mock('server-connection', () => ({
294
+ fetchToolsFromServer: vi.fn().mockResolvedValue([])
295
+ }));
296
+ // cacheTools() runs - test logic intact
297
+ ```
298
+
299
+ ### Gate Function
300
+
301
+ ```
302
+ BEFORE mocking any method:
303
+ STOP - Don't mock yet
304
+
305
+ 1. Ask: "What side effects does the real method have?"
306
+ Action: Read implementation, list all side effects
307
+
308
+ 2. Ask: "Does this test depend on any of those side effects?"
309
+ Action: Identify which side effects test logic needs
310
+
311
+ 3. Ask: "Do I fully understand what this test needs?"
312
+ Action: Write down test's dependencies
313
+
314
+ IF depends on side effects:
315
+ Mock at lower level (the actual slow/external operation)
316
+ OR use test doubles that preserve necessary behavior
317
+ NOT the high-level method the test depends on
318
+
319
+ IF unsure what test depends on:
320
+ Run test with real implementation FIRST
321
+ Observe what actually needs to happen
322
+ THEN add minimal mocking at the right level
323
+
324
+ Red flags:
325
+ - "I'll mock this to be safe"
326
+ - "This might be slow, better mock it"
327
+ - Mocking without reading implementation
328
+ - Mocking without understanding dependency chain
329
+ ```
330
+
331
+ ### Levels of Mocking
332
+
333
+ **Choose the right level:**
334
+
335
+ ```typescript
336
+ // ❌ Too high - breaks test logic
337
+ vi.mock('UserService'); // Mocks everything, including state changes
338
+
339
+ // ❌ Too high - over-mocking
340
+ vi.mock('DatabaseAdapter'); // Could use in-memory DB instead
341
+
342
+ // ✅ Right level - isolates slow operation
343
+ vi.mock('HTTPClient'); // Mock network, preserve business logic
344
+
345
+ // ✅ Right level - controls non-determinism
346
+ vi.spyOn(Date, 'now').mockReturnValue(fixedTimestamp);
347
+ ```
348
+
349
+ **Mocking hierarchy (top to bottom):**
350
+ 1. **Application logic** - Never mock (this is what you're testing)
351
+ 2. **Business layer** - Rarely mock (needed for test assertions)
352
+ 3. **Adapter layer** - Sometimes mock (if slow, use test doubles)
353
+ 4. **I/O boundaries** - Usually mock (network, filesystem, external APIs)
354
+ 5. **Infrastructure** - Always mock (actual servers, databases in unit tests)
355
+
356
+ ### Common Mocking Mistakes
357
+
358
+ **Mistake 1: Mocking what you're testing**
359
+ ```typescript
360
+ // ❌ BAD
361
+ test('user registration validates email', () => {
362
+ vi.mock('UserValidator'); // You're testing this!
363
+ await registerUser(email);
364
+ });
365
+
366
+ // ✅ GOOD
367
+ test('user registration validates email', () => {
368
+ vi.mock('EmailService'); // Mock email sending, test validation
369
+ await expect(registerUser('invalid')).rejects.toThrow();
370
+ });
371
+ ```
372
+
373
+ **Mistake 2: Mocking too broadly**
374
+ ```typescript
375
+ // ❌ BAD - mocks entire module
376
+ vi.mock('./user-service');
377
+
378
+ // ✅ GOOD - mocks specific slow operation
379
+ vi.mock('./email-client', () => ({
380
+ sendEmail: vi.fn() // Just the network call
381
+ }));
382
+ ```
383
+
384
+ **Mistake 3: Mocking based on assumptions**
385
+ ```typescript
386
+ // ❌ BAD - assumption without measurement
387
+ // "Database queries are slow, better mock"
388
+ vi.mock('./database');
389
+
390
+ // ✅ GOOD - measure first
391
+ // Run test unmocked: 2ms (fast enough!)
392
+ // Don't mock unless proven slow
393
+ ```
394
+
395
+ ## Prevention Through TDD
396
+
397
+ **How TDD prevents these anti-patterns:**
398
+
399
+ 1. **Write test first** → Forces you to think about what you're actually testing
400
+ 2. **Watch it fail** → Confirms test tests real behavior, not mocks
401
+ 3. **Minimal implementation** → No test-only methods creep in
402
+ 4. **Real dependencies** → You see what the test actually needs before mocking
403
+
404
+ **If you're testing mock behavior, you violated TDD** - you added mocks without watching test fail against real code first.
405
+
406
+ **TDD workflow prevents:**
407
+ - Testing mock behavior (test fails for real reasons first)
408
+ - Test-only methods (minimal implementation doesn't add them)
409
+ - Uninformed mocking (you understand needs before mocking)
410
+
411
+ See [test-driven-development skill](../../test-driven-development/) for complete TDD workflow.