claude-mpm 4.21.0__py3-none-any.whl → 5.0.2__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.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_PM.md +12 -0
- claude_mpm/agents/OUTPUT_STYLE.md +3 -48
- claude_mpm/agents/PM_INSTRUCTIONS.md +632 -334
- claude_mpm/agents/WORKFLOW.md +75 -2
- claude_mpm/agents/__init__.py +6 -0
- claude_mpm/agents/agent_loader.py +1 -4
- claude_mpm/agents/base_agent.json +6 -3
- claude_mpm/agents/frontmatter_validator.py +1 -1
- claude_mpm/agents/templates/{circuit_breakers.md → circuit-breakers.md} +370 -3
- claude_mpm/agents/templates/context-management-examples.md +544 -0
- claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +89 -19
- claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
- claude_mpm/agents/templates/research-gate-examples.md +669 -0
- claude_mpm/agents/templates/structured-questions-examples.md +615 -0
- claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
- claude_mpm/agents/templates/ticketing-examples.md +277 -0
- claude_mpm/cli/__init__.py +38 -2
- claude_mpm/cli/commands/agent_source.py +774 -0
- claude_mpm/cli/commands/agent_state_manager.py +125 -20
- claude_mpm/cli/commands/agents.py +684 -13
- claude_mpm/cli/commands/agents_cleanup.py +210 -0
- claude_mpm/cli/commands/agents_discover.py +338 -0
- claude_mpm/cli/commands/aggregate.py +1 -1
- claude_mpm/cli/commands/analyze.py +3 -3
- claude_mpm/cli/commands/auto_configure.py +2 -6
- claude_mpm/cli/commands/cleanup.py +1 -1
- claude_mpm/cli/commands/config.py +7 -4
- claude_mpm/cli/commands/configure.py +478 -44
- claude_mpm/cli/commands/configure_agent_display.py +4 -4
- claude_mpm/cli/commands/configure_navigation.py +63 -46
- claude_mpm/cli/commands/debug.py +12 -12
- claude_mpm/cli/commands/doctor.py +10 -2
- claude_mpm/cli/commands/hook_errors.py +277 -0
- claude_mpm/cli/commands/local_deploy.py +1 -4
- claude_mpm/cli/commands/mcp_install_commands.py +1 -1
- claude_mpm/cli/commands/mpm_init/core.py +50 -2
- claude_mpm/cli/commands/mpm_init/git_activity.py +10 -10
- claude_mpm/cli/commands/mpm_init/prompts.py +6 -6
- claude_mpm/cli/commands/run.py +124 -128
- claude_mpm/cli/commands/skill_source.py +694 -0
- claude_mpm/cli/commands/skills.py +435 -1
- claude_mpm/cli/executor.py +78 -3
- claude_mpm/cli/interactive/agent_wizard.py +919 -41
- claude_mpm/cli/parsers/agent_source_parser.py +171 -0
- claude_mpm/cli/parsers/agents_parser.py +173 -4
- claude_mpm/cli/parsers/base_parser.py +49 -0
- claude_mpm/cli/parsers/config_parser.py +96 -43
- claude_mpm/cli/parsers/skill_source_parser.py +169 -0
- claude_mpm/cli/parsers/skills_parser.py +138 -0
- claude_mpm/cli/parsers/source_parser.py +138 -0
- claude_mpm/cli/startup.py +499 -84
- claude_mpm/cli/startup_display.py +480 -0
- claude_mpm/cli/utils.py +1 -1
- claude_mpm/cli_module/commands.py +1 -1
- claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
- claude_mpm/commands/mpm-agents-detect.md +9 -0
- claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
- claude_mpm/commands/mpm-agents-recommend.md +9 -0
- claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
- claude_mpm/commands/mpm-doctor.md +9 -0
- claude_mpm/commands/mpm-help.md +14 -2
- claude_mpm/commands/mpm-init.md +27 -2
- claude_mpm/commands/mpm-monitor.md +9 -0
- claude_mpm/commands/mpm-session-resume.md +381 -0
- claude_mpm/commands/mpm-status.md +9 -0
- claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
- claude_mpm/commands/mpm-ticket-view.md +552 -0
- claude_mpm/commands/mpm-version.md +9 -0
- claude_mpm/commands/mpm.md +11 -0
- claude_mpm/config/agent_presets.py +258 -0
- claude_mpm/config/agent_sources.py +325 -0
- claude_mpm/config/skill_sources.py +590 -0
- claude_mpm/constants.py +12 -0
- claude_mpm/core/api_validator.py +1 -1
- claude_mpm/core/claude_runner.py +17 -10
- claude_mpm/core/config.py +24 -0
- claude_mpm/core/constants.py +1 -1
- claude_mpm/core/framework/__init__.py +3 -16
- claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
- claude_mpm/core/framework/processors/metadata_processor.py +1 -1
- claude_mpm/core/hook_error_memory.py +381 -0
- claude_mpm/core/hook_manager.py +41 -2
- claude_mpm/core/interactive_session.py +112 -5
- claude_mpm/core/logger.py +3 -1
- claude_mpm/core/oneshot_session.py +94 -4
- claude_mpm/dashboard/static/css/activity.css +69 -69
- claude_mpm/dashboard/static/css/connection-status.css +10 -10
- claude_mpm/dashboard/static/css/dashboard.css +15 -15
- claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
- claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
- claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
- claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
- claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
- claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
- claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
- claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
- claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
- claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
- claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
- claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
- claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
- claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
- claude_mpm/dashboard/static/js/connection-manager.js +76 -76
- claude_mpm/dashboard/static/js/dashboard.js +76 -58
- claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
- claude_mpm/dashboard/static/js/socket-client.js +138 -121
- claude_mpm/dashboard/templates/code_simple.html +23 -23
- claude_mpm/dashboard/templates/index.html +18 -18
- claude_mpm/experimental/cli_enhancements.py +1 -5
- claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
- claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
- claude_mpm/hooks/claude_hooks/installer.py +45 -0
- claude_mpm/hooks/failure_learning/__init__.py +2 -8
- claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
- claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
- claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
- claude_mpm/hooks/kuzu_response_hook.py +1 -5
- claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
- claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
- claude_mpm/models/git_repository.py +198 -0
- claude_mpm/scripts/claude-hook-handler.sh +3 -3
- claude_mpm/scripts/start_activity_logging.py +3 -1
- claude_mpm/services/agents/agent_builder.py +45 -9
- claude_mpm/services/agents/agent_preset_service.py +238 -0
- claude_mpm/services/agents/agent_selection_service.py +484 -0
- claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +126 -2
- claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
- claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
- claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
- claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
- claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +115 -15
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +363 -0
- claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
- claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
- claude_mpm/services/agents/git_source_manager.py +629 -0
- claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
- claude_mpm/services/agents/local_template_manager.py +50 -10
- claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
- claude_mpm/services/agents/sources/__init__.py +13 -0
- claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
- claude_mpm/services/agents/sources/git_source_sync_service.py +1055 -0
- claude_mpm/services/agents/startup_sync.py +239 -0
- claude_mpm/services/agents/toolchain_detector.py +474 -0
- claude_mpm/services/cli/session_pause_manager.py +1 -1
- claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
- claude_mpm/services/command_deployment_service.py +92 -1
- claude_mpm/services/core/base.py +26 -11
- claude_mpm/services/core/interfaces/__init__.py +1 -3
- claude_mpm/services/core/interfaces/health.py +1 -4
- claude_mpm/services/core/models/__init__.py +2 -11
- claude_mpm/services/diagnostics/checks/__init__.py +4 -0
- claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
- claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
- claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
- claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
- claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
- claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
- claude_mpm/services/event_bus/direct_relay.py +3 -3
- claude_mpm/services/event_bus/event_bus.py +36 -3
- claude_mpm/services/event_bus/relay.py +23 -7
- claude_mpm/services/events/consumers/logging.py +1 -2
- claude_mpm/services/git/__init__.py +21 -0
- claude_mpm/services/git/git_operations_service.py +494 -0
- claude_mpm/services/github/__init__.py +21 -0
- claude_mpm/services/github/github_cli_service.py +397 -0
- claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
- claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
- claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
- claude_mpm/services/instructions/__init__.py +9 -0
- claude_mpm/services/instructions/instruction_cache_service.py +374 -0
- claude_mpm/services/local_ops/__init__.py +3 -13
- claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
- claude_mpm/services/local_ops/health_manager.py +1 -4
- claude_mpm/services/local_ops/process_manager.py +1 -1
- claude_mpm/services/local_ops/resource_monitor.py +2 -2
- claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
- claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
- claude_mpm/services/memory/failure_tracker.py +19 -4
- claude_mpm/services/memory/optimizer.py +1 -1
- claude_mpm/services/model/model_router.py +8 -9
- claude_mpm/services/monitor/daemon.py +1 -1
- claude_mpm/services/monitor/server.py +2 -2
- claude_mpm/services/native_agent_converter.py +356 -0
- claude_mpm/services/port_manager.py +1 -1
- claude_mpm/services/pr/__init__.py +14 -0
- claude_mpm/services/pr/pr_template_service.py +329 -0
- claude_mpm/services/project/documentation_manager.py +2 -1
- claude_mpm/services/project/toolchain_analyzer.py +3 -1
- claude_mpm/services/runner_configuration_service.py +1 -0
- claude_mpm/services/self_upgrade_service.py +165 -7
- claude_mpm/services/skills/__init__.py +18 -0
- claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
- claude_mpm/services/skills/skill_discovery_service.py +568 -0
- claude_mpm/services/skills_config.py +547 -0
- claude_mpm/services/skills_deployer.py +955 -0
- claude_mpm/services/socketio/handlers/connection.py +1 -1
- claude_mpm/services/socketio/handlers/git.py +2 -2
- claude_mpm/services/socketio/server/core.py +1 -4
- claude_mpm/services/socketio/server/main.py +1 -3
- claude_mpm/services/system_instructions_service.py +1 -3
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
- claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
- claude_mpm/services/unified/unified_deployment.py +1 -5
- claude_mpm/services/version_control/conflict_resolution.py +6 -4
- claude_mpm/services/visualization/__init__.py +1 -5
- claude_mpm/services/visualization/mermaid_generator.py +2 -3
- claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
- claude_mpm/skills/bundled/performance-profiling.md +6 -0
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +2 -2
- claude_mpm/skills/skills_registry.py +0 -1
- claude_mpm/templates/questions/__init__.py +38 -0
- claude_mpm/templates/questions/base.py +193 -0
- claude_mpm/templates/questions/pr_strategy.py +311 -0
- claude_mpm/templates/questions/project_init.py +385 -0
- claude_mpm/templates/questions/ticket_mgmt.py +394 -0
- claude_mpm/tools/__main__.py +8 -8
- claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
- claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
- claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
- claude_mpm/tools/code_tree_analyzer/core.py +380 -0
- claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
- claude_mpm/tools/code_tree_analyzer/events.py +168 -0
- claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
- claude_mpm/tools/code_tree_analyzer/models.py +39 -0
- claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
- claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
- claude_mpm/utils/agent_dependency_loader.py +80 -13
- claude_mpm/utils/dependency_cache.py +3 -1
- claude_mpm/utils/gitignore.py +241 -0
- claude_mpm/utils/log_cleanup.py +3 -3
- claude_mpm/utils/progress.py +383 -0
- claude_mpm/utils/robust_installer.py +3 -5
- claude_mpm/utils/structured_questions.py +619 -0
- {claude_mpm-4.21.0.dist-info → claude_mpm-5.0.2.dist-info}/METADATA +429 -59
- {claude_mpm-4.21.0.dist-info → claude_mpm-5.0.2.dist-info}/RECORD +264 -427
- claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
- claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
- claude_mpm/agents/templates/agent-manager.json +0 -273
- claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
- claude_mpm/agents/templates/api_qa.json +0 -180
- claude_mpm/agents/templates/clerk-ops.json +0 -235
- claude_mpm/agents/templates/code_analyzer.json +0 -101
- claude_mpm/agents/templates/content-agent.json +0 -358
- claude_mpm/agents/templates/dart_engineer.json +0 -307
- claude_mpm/agents/templates/data_engineer.json +0 -225
- claude_mpm/agents/templates/documentation.json +0 -211
- claude_mpm/agents/templates/engineer.json +0 -210
- claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
- claude_mpm/agents/templates/golang_engineer.json +0 -270
- claude_mpm/agents/templates/imagemagick.json +0 -264
- claude_mpm/agents/templates/java_engineer.json +0 -346
- claude_mpm/agents/templates/local_ops_agent.json +0 -1840
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
- claude_mpm/agents/templates/memory_manager.json +0 -158
- claude_mpm/agents/templates/nextjs_engineer.json +0 -285
- claude_mpm/agents/templates/ops.json +0 -185
- claude_mpm/agents/templates/php-engineer.json +0 -287
- claude_mpm/agents/templates/product_owner.json +0 -338
- claude_mpm/agents/templates/project_organizer.json +0 -140
- claude_mpm/agents/templates/prompt-engineer.json +0 -737
- claude_mpm/agents/templates/python_engineer.json +0 -387
- claude_mpm/agents/templates/qa.json +0 -242
- claude_mpm/agents/templates/react_engineer.json +0 -238
- claude_mpm/agents/templates/refactoring_engineer.json +0 -276
- claude_mpm/agents/templates/research.json +0 -188
- claude_mpm/agents/templates/ruby-engineer.json +0 -280
- claude_mpm/agents/templates/rust_engineer.json +0 -275
- claude_mpm/agents/templates/security.json +0 -202
- claude_mpm/agents/templates/svelte-engineer.json +0 -225
- claude_mpm/agents/templates/ticketing.json +0 -177
- claude_mpm/agents/templates/typescript_engineer.json +0 -285
- claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
- claude_mpm/agents/templates/version_control.json +0 -157
- claude_mpm/agents/templates/web_qa.json +0 -399
- claude_mpm/agents/templates/web_ui.json +0 -189
- claude_mpm/commands/mpm-tickets.md +0 -102
- claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
- claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
- claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
- claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
- claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
- claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
- claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
- claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
- claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
- claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
- claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
- claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
- claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
- claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
- claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
- claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
- claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
- claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
- claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
- claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
- claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
- claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
- claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
- claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
- claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
- claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
- claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
- claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
- claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
- claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
- claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
- claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
- claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
- claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/built/connection-manager.js +0 -536
- claude_mpm/dashboard/static/built/dashboard.js +0 -2
- claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
- claude_mpm/dashboard/static/built/react/events.js +0 -30
- claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
- claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
- claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
- claude_mpm/dashboard/static/built/shared/logger.js +0 -385
- claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
- claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
- claude_mpm/dashboard/static/built/socket-client.js +0 -2
- claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
- claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/dist/dashboard.js +0 -2
- claude_mpm/dashboard/static/dist/react/events.js +0 -30
- claude_mpm/dashboard/static/dist/socket-client.js +0 -2
- claude_mpm/dashboard/static/events.html +0 -607
- claude_mpm/dashboard/static/index.html +0 -635
- claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
- claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
- claude_mpm/dashboard/static/js/shared/logger.js +0 -385
- claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
- claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
- claude_mpm/dashboard/static/legacy/activity.html +0 -736
- claude_mpm/dashboard/static/legacy/agents.html +0 -786
- claude_mpm/dashboard/static/legacy/files.html +0 -747
- claude_mpm/dashboard/static/legacy/tools.html +0 -831
- claude_mpm/dashboard/static/monitors.html +0 -431
- claude_mpm/dashboard/static/production/events.html +0 -659
- claude_mpm/dashboard/static/production/main.html +0 -698
- claude_mpm/dashboard/static/production/monitors.html +0 -483
- claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
- claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
- claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
- claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
- claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -79
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -178
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +0 -577
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +0 -467
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +0 -537
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +0 -730
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -112
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +0 -146
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +0 -412
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -81
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +0 -362
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +0 -312
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -152
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +0 -668
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +0 -587
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +0 -438
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +0 -391
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -131
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -325
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +0 -490
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +0 -425
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -499
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -86
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -43
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -160
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +0 -412
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +0 -1237
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -189
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +0 -500
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +0 -464
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +0 -619
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +0 -437
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +0 -231
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +0 -170
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +0 -602
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +0 -821
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +0 -742
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +0 -726
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +0 -764
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +0 -831
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +0 -226
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +0 -901
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +0 -901
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +0 -775
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +0 -937
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +0 -770
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +0 -961
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -119
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +0 -253
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -140
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +0 -572
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +0 -411
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +0 -569
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +0 -695
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -184
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +0 -459
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +0 -479
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +0 -687
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +0 -758
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +0 -868
- claude_mpm/tools/code_tree_analyzer.py +0 -1825
- /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
- /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
- /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
- /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
- {claude_mpm-4.21.0.dist-info → claude_mpm-5.0.2.dist-info}/WHEEL +0 -0
- {claude_mpm-4.21.0.dist-info → claude_mpm-5.0.2.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.21.0.dist-info → claude_mpm-5.0.2.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.21.0.dist-info → claude_mpm-5.0.2.dist-info}/top_level.txt +0 -0
|
@@ -1,695 +0,0 @@
|
|
|
1
|
-
# How TDD Prevents Testing Anti-Patterns
|
|
2
|
-
|
|
3
|
-
Test-Driven Development (TDD) is not just a testing methodology - it's a design methodology that naturally prevents all five testing anti-patterns. This guide explains the deep connection between TDD and anti-pattern prevention.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
**Core insight:** If you follow strict TDD, testing anti-patterns become nearly impossible to create.
|
|
8
|
-
|
|
9
|
-
**Why:** TDD forces you to think about real behavior before implementation, making mock-testing and test-only methods unnatural.
|
|
10
|
-
|
|
11
|
-
## TDD Fundamentals
|
|
12
|
-
|
|
13
|
-
### The RED/GREEN/REFACTOR Cycle
|
|
14
|
-
|
|
15
|
-
```
|
|
16
|
-
1. RED: Write failing test
|
|
17
|
-
- Test doesn't compile or fails
|
|
18
|
-
- Verify failure reason is correct
|
|
19
|
-
- No implementation exists yet
|
|
20
|
-
|
|
21
|
-
2. GREEN: Write minimal code to pass
|
|
22
|
-
- Simplest implementation
|
|
23
|
-
- Just enough to pass test
|
|
24
|
-
- No gold plating
|
|
25
|
-
|
|
26
|
-
3. REFACTOR: Improve code
|
|
27
|
-
- Clean up duplication
|
|
28
|
-
- Improve names
|
|
29
|
-
- Tests still pass
|
|
30
|
-
|
|
31
|
-
4. REPEAT: Next test
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
**Critical rule:** Never write implementation without failing test first.
|
|
35
|
-
|
|
36
|
-
See [test-driven-development skill](../../test-driven-development/) for complete workflow.
|
|
37
|
-
|
|
38
|
-
## How TDD Prevents Each Anti-Pattern
|
|
39
|
-
|
|
40
|
-
### Anti-Pattern 1: Testing Mock Behavior
|
|
41
|
-
|
|
42
|
-
**How TDD prevents it:**
|
|
43
|
-
|
|
44
|
-
```
|
|
45
|
-
TDD Step 1: Write test for real behavior
|
|
46
|
-
↓
|
|
47
|
-
Test fails because feature doesn't exist
|
|
48
|
-
↓
|
|
49
|
-
TDD Step 2: Implement minimal code
|
|
50
|
-
↓
|
|
51
|
-
Test passes - you tested real code, not mock
|
|
52
|
-
|
|
53
|
-
If you tested mock:
|
|
54
|
-
↓
|
|
55
|
-
Test would pass immediately (mock exists)
|
|
56
|
-
↓
|
|
57
|
-
Violation of TDD - didn't see failure
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
**Example workflow:**
|
|
61
|
-
|
|
62
|
-
```typescript
|
|
63
|
-
// TDD Step 1: Write failing test
|
|
64
|
-
test('renders sidebar with navigation', () => {
|
|
65
|
-
render(<Page />);
|
|
66
|
-
expect(screen.getByRole('navigation')).toBeInTheDocument();
|
|
67
|
-
});
|
|
68
|
-
// ❌ Fails - Page doesn't render sidebar yet
|
|
69
|
-
|
|
70
|
-
// TDD Step 2: Implement
|
|
71
|
-
function Page() {
|
|
72
|
-
return <div><Sidebar role="navigation" /></div>;
|
|
73
|
-
}
|
|
74
|
-
// ✅ Passes - tested real component
|
|
75
|
-
|
|
76
|
-
// WRONG way (not TDD):
|
|
77
|
-
test('renders sidebar mock', () => {
|
|
78
|
-
render(<Page />);
|
|
79
|
-
expect(screen.getByTestId('sidebar-mock')).toBeInTheDocument();
|
|
80
|
-
});
|
|
81
|
-
// ✅ Passes immediately - you never saw it fail!
|
|
82
|
-
// This violates TDD - test must fail first
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
**TDD guarantee:** If test passes immediately, you're testing mock behavior.
|
|
86
|
-
|
|
87
|
-
### Anti-Pattern 2: Test-Only Methods in Production
|
|
88
|
-
|
|
89
|
-
**How TDD prevents it:**
|
|
90
|
-
|
|
91
|
-
```
|
|
92
|
-
TDD Step 1: Write test for needed behavior
|
|
93
|
-
↓
|
|
94
|
-
Test describes what production needs
|
|
95
|
-
↓
|
|
96
|
-
TDD Step 2: Minimal implementation
|
|
97
|
-
↓
|
|
98
|
-
Only code test needs is written
|
|
99
|
-
|
|
100
|
-
If method only for tests:
|
|
101
|
-
↓
|
|
102
|
-
No production test would need it
|
|
103
|
-
↓
|
|
104
|
-
TDD wouldn't add it
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
**Example workflow:**
|
|
108
|
-
|
|
109
|
-
```typescript
|
|
110
|
-
// TDD Step 1: Write test for production behavior
|
|
111
|
-
test('session expires after timeout', async () => {
|
|
112
|
-
const session = new Session();
|
|
113
|
-
await advanceTime(SESSION_TIMEOUT);
|
|
114
|
-
expect(session.isActive()).toBe(false);
|
|
115
|
-
});
|
|
116
|
-
// ❌ Fails - Session doesn't handle expiry
|
|
117
|
-
|
|
118
|
-
// TDD Step 2: Implement expiry (production feature)
|
|
119
|
-
class Session {
|
|
120
|
-
isActive() {
|
|
121
|
-
return Date.now() < this.expiresAt;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
// ✅ Passes - implemented real behavior
|
|
125
|
-
|
|
126
|
-
// WRONG way (not TDD):
|
|
127
|
-
// "I need to cleanup in tests"
|
|
128
|
-
class Session {
|
|
129
|
-
destroy() { /* for tests */ } // ❌ Not driven by test!
|
|
130
|
-
}
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
**TDD guarantee:** Minimal implementation doesn't add untested code.
|
|
134
|
-
|
|
135
|
-
**Test cleanup belongs in test utilities:**
|
|
136
|
-
```typescript
|
|
137
|
-
// test-utils/session.ts
|
|
138
|
-
export async function cleanupSession(session: Session) {
|
|
139
|
-
// Use public API for cleanup
|
|
140
|
-
session.logout();
|
|
141
|
-
// Clear any test-specific state
|
|
142
|
-
}
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
### Anti-Pattern 3: Mocking Without Understanding
|
|
146
|
-
|
|
147
|
-
**How TDD prevents it:**
|
|
148
|
-
|
|
149
|
-
```
|
|
150
|
-
TDD Step 1: Write test with real implementation
|
|
151
|
-
↓
|
|
152
|
-
Test runs - you see what it does
|
|
153
|
-
↓
|
|
154
|
-
Identify what's slow/external
|
|
155
|
-
↓
|
|
156
|
-
TDD Step 2: Mock at correct level
|
|
157
|
-
↓
|
|
158
|
-
Mock only slow part, preserve behavior
|
|
159
|
-
|
|
160
|
-
If you mock first:
|
|
161
|
-
↓
|
|
162
|
-
Never saw real behavior
|
|
163
|
-
↓
|
|
164
|
-
Don't understand dependencies
|
|
165
|
-
↓
|
|
166
|
-
Mock breaks test logic
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
**Example workflow:**
|
|
170
|
-
|
|
171
|
-
```typescript
|
|
172
|
-
// TDD Step 1: Write test with real implementation
|
|
173
|
-
test('detects duplicate server', async () => {
|
|
174
|
-
await addServer(config);
|
|
175
|
-
await expect(addServer(config))
|
|
176
|
-
.rejects.toThrow('already exists');
|
|
177
|
-
});
|
|
178
|
-
// Run test - takes 2 seconds (server startup slow)
|
|
179
|
-
// Observe: Config written, duplicate detected
|
|
180
|
-
// Understand: Test depends on config persistence
|
|
181
|
-
|
|
182
|
-
// TDD Step 2: Mock at correct level
|
|
183
|
-
test('detects duplicate server', async () => {
|
|
184
|
-
vi.mock('MCPServerManager'); // Mock slow startup only
|
|
185
|
-
// Config writing preserved - test logic intact
|
|
186
|
-
|
|
187
|
-
await addServer(config);
|
|
188
|
-
await expect(addServer(config))
|
|
189
|
-
.rejects.toThrow('already exists');
|
|
190
|
-
});
|
|
191
|
-
// ✅ Fast test, correct behavior
|
|
192
|
-
|
|
193
|
-
// WRONG way (not TDD):
|
|
194
|
-
// "Let me mock this upfront"
|
|
195
|
-
vi.mock('ToolCatalog', () => ({
|
|
196
|
-
discoverAndCacheTools: vi.fn() // Breaks test logic!
|
|
197
|
-
}));
|
|
198
|
-
// Never saw real behavior - don't know what test needs
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
**TDD guarantee:** You understand dependencies before mocking them.
|
|
202
|
-
|
|
203
|
-
### Anti-Pattern 4: Incomplete Mocks
|
|
204
|
-
|
|
205
|
-
**How TDD prevents it:**
|
|
206
|
-
|
|
207
|
-
```
|
|
208
|
-
TDD Step 1: Write test with real API
|
|
209
|
-
↓
|
|
210
|
-
See complete response structure
|
|
211
|
-
↓
|
|
212
|
-
TDD Step 2: Mock with complete structure
|
|
213
|
-
↓
|
|
214
|
-
Test still passes - mock is complete
|
|
215
|
-
|
|
216
|
-
If mock incomplete:
|
|
217
|
-
↓
|
|
218
|
-
Test fails - mock missing fields
|
|
219
|
-
↓
|
|
220
|
-
TDD forces you to complete mock
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
**Example workflow:**
|
|
224
|
-
|
|
225
|
-
```typescript
|
|
226
|
-
// TDD Step 1: Test with real API (or type)
|
|
227
|
-
test('displays user profile', async () => {
|
|
228
|
-
const user = await api.getUser('123');
|
|
229
|
-
// TypeScript shows complete User type
|
|
230
|
-
render(<Profile user={user} />);
|
|
231
|
-
expect(screen.getByText(user.name)).toBeInTheDocument();
|
|
232
|
-
expect(screen.getByText(user.profile.timezone)).toBeInTheDocument();
|
|
233
|
-
});
|
|
234
|
-
// Observe complete structure
|
|
235
|
-
|
|
236
|
-
// TDD Step 2: Mock with complete structure
|
|
237
|
-
test('displays user profile', async () => {
|
|
238
|
-
const mockUser: User = { // TypeScript enforces completeness
|
|
239
|
-
id: '123',
|
|
240
|
-
name: 'Alice',
|
|
241
|
-
email: 'alice@example.com',
|
|
242
|
-
profile: {
|
|
243
|
-
timezone: 'UTC',
|
|
244
|
-
locale: 'en-US',
|
|
245
|
-
avatar: null
|
|
246
|
-
},
|
|
247
|
-
metadata: { /* complete */ }
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
render(<Profile user={mockUser} />);
|
|
251
|
-
expect(screen.getByText('Alice')).toBeInTheDocument();
|
|
252
|
-
});
|
|
253
|
-
// ✅ Complete mock, test passes
|
|
254
|
-
|
|
255
|
-
// WRONG way (not TDD):
|
|
256
|
-
const mockUser = { id: '123', name: 'Alice' }; // Incomplete
|
|
257
|
-
// Later breaks when profile.timezone accessed
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
**TDD guarantee:** Test with real data first reveals complete structure.
|
|
261
|
-
|
|
262
|
-
**Use TypeScript to enforce completeness:**
|
|
263
|
-
```typescript
|
|
264
|
-
// Define complete type from API
|
|
265
|
-
interface User {
|
|
266
|
-
id: string;
|
|
267
|
-
name: string;
|
|
268
|
-
email: string;
|
|
269
|
-
profile: UserProfile;
|
|
270
|
-
metadata: UserMetadata;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// TypeScript errors if incomplete
|
|
274
|
-
const mock: User = {
|
|
275
|
-
id: '123',
|
|
276
|
-
name: 'Alice'
|
|
277
|
-
// ❌ TypeScript error - missing fields
|
|
278
|
-
};
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
### Anti-Pattern 5: Tests as Afterthought
|
|
282
|
-
|
|
283
|
-
**How TDD prevents it:**
|
|
284
|
-
|
|
285
|
-
```
|
|
286
|
-
TDD Step 1: MUST write test first
|
|
287
|
-
↓
|
|
288
|
-
No implementation without test
|
|
289
|
-
↓
|
|
290
|
-
Test IS implementation process
|
|
291
|
-
|
|
292
|
-
If implementation first:
|
|
293
|
-
↓
|
|
294
|
-
Violated TDD - broke the cycle
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
**TDD makes tests as afterthought impossible:**
|
|
298
|
-
|
|
299
|
-
```typescript
|
|
300
|
-
// TDD Way - tests ARE implementation
|
|
301
|
-
// 1. RED
|
|
302
|
-
test('user registration validates email', async () => {
|
|
303
|
-
await expect(registerUser('invalid'))
|
|
304
|
-
.rejects.toThrow('Invalid email');
|
|
305
|
-
});
|
|
306
|
-
// ❌ Fails - registerUser doesn't exist
|
|
307
|
-
|
|
308
|
-
// 2. GREEN
|
|
309
|
-
async function registerUser(email: string) {
|
|
310
|
-
if (!isValidEmail(email)) {
|
|
311
|
-
throw new Error('Invalid email');
|
|
312
|
-
}
|
|
313
|
-
// ... registration
|
|
314
|
-
}
|
|
315
|
-
// ✅ Passes
|
|
316
|
-
|
|
317
|
-
// 3. REFACTOR
|
|
318
|
-
// Improve validation logic, tests still pass
|
|
319
|
-
|
|
320
|
-
// NOT TDD (anti-pattern):
|
|
321
|
-
// 1. Implement registerUser
|
|
322
|
-
// 2. "Feature complete, need to add tests" ← Afterthought
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
**TDD workflow:**
|
|
326
|
-
- Tests first = tests are implementation
|
|
327
|
-
- No "testing phase" - tests are development
|
|
328
|
-
- Feature complete = tests passing
|
|
329
|
-
- Can't forget tests - can't write code without them
|
|
330
|
-
|
|
331
|
-
## TDD Workflow Prevents Anti-Patterns
|
|
332
|
-
|
|
333
|
-
### Complete TDD Cycle
|
|
334
|
-
|
|
335
|
-
```typescript
|
|
336
|
-
// Feature: User registration with email validation
|
|
337
|
-
|
|
338
|
-
// ========================================
|
|
339
|
-
// CYCLE 1: Email validation
|
|
340
|
-
// ========================================
|
|
341
|
-
|
|
342
|
-
// RED: Write failing test
|
|
343
|
-
test('rejects invalid email', async () => {
|
|
344
|
-
await expect(registerUser('invalid'))
|
|
345
|
-
.rejects.toThrow('Invalid email');
|
|
346
|
-
});
|
|
347
|
-
// ❌ Fails - registerUser doesn't exist
|
|
348
|
-
|
|
349
|
-
// GREEN: Minimal implementation
|
|
350
|
-
async function registerUser(email: string) {
|
|
351
|
-
if (!email.includes('@')) {
|
|
352
|
-
throw new Error('Invalid email');
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
// ✅ Passes
|
|
356
|
-
|
|
357
|
-
// REFACTOR: Improve validation
|
|
358
|
-
async function registerUser(email: string) {
|
|
359
|
-
if (!isValidEmail(email)) { // Better validator
|
|
360
|
-
throw new Error('Invalid email');
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
// ✅ Still passes
|
|
364
|
-
|
|
365
|
-
// ========================================
|
|
366
|
-
// CYCLE 2: Database integration
|
|
367
|
-
// ========================================
|
|
368
|
-
|
|
369
|
-
// RED: Write failing test
|
|
370
|
-
test('saves user to database', async () => {
|
|
371
|
-
const user = await registerUser('alice@example.com');
|
|
372
|
-
const saved = await db.users.findById(user.id);
|
|
373
|
-
expect(saved.email).toBe('alice@example.com');
|
|
374
|
-
});
|
|
375
|
-
// ❌ Fails - no database integration
|
|
376
|
-
|
|
377
|
-
// GREEN: Add database
|
|
378
|
-
async function registerUser(email: string) {
|
|
379
|
-
if (!isValidEmail(email)) {
|
|
380
|
-
throw new Error('Invalid email');
|
|
381
|
-
}
|
|
382
|
-
const user = await db.users.create({ email }); // Added
|
|
383
|
-
return user;
|
|
384
|
-
}
|
|
385
|
-
// ✅ Passes
|
|
386
|
-
|
|
387
|
-
// REFACTOR: Extract repository pattern
|
|
388
|
-
// Tests still pass
|
|
389
|
-
|
|
390
|
-
// ========================================
|
|
391
|
-
// CYCLE 3: Duplicate prevention
|
|
392
|
-
// ========================================
|
|
393
|
-
|
|
394
|
-
// RED: Write failing test
|
|
395
|
-
test('prevents duplicate email', async () => {
|
|
396
|
-
await registerUser('alice@example.com');
|
|
397
|
-
await expect(registerUser('alice@example.com'))
|
|
398
|
-
.rejects.toThrow('Email already exists');
|
|
399
|
-
});
|
|
400
|
-
// ❌ Fails - no duplicate check
|
|
401
|
-
|
|
402
|
-
// GREEN: Add check
|
|
403
|
-
async function registerUser(email: string) {
|
|
404
|
-
if (!isValidEmail(email)) {
|
|
405
|
-
throw new Error('Invalid email');
|
|
406
|
-
}
|
|
407
|
-
const existing = await db.users.findByEmail(email);
|
|
408
|
-
if (existing) {
|
|
409
|
-
throw new Error('Email already exists'); // Added
|
|
410
|
-
}
|
|
411
|
-
return await db.users.create({ email });
|
|
412
|
-
}
|
|
413
|
-
// ✅ Passes
|
|
414
|
-
|
|
415
|
-
// REFACTOR: Improve error handling
|
|
416
|
-
// Tests still pass
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
**Notice:**
|
|
420
|
-
- ✅ No mock behavior testing - real code tested
|
|
421
|
-
- ✅ No test-only methods - only what tests needed
|
|
422
|
-
- ✅ No uninformed mocking - saw real behavior first
|
|
423
|
-
- ✅ No incomplete mocks - used real structures
|
|
424
|
-
- ✅ No afterthought tests - tests first always
|
|
425
|
-
|
|
426
|
-
## TDD Mindset: Test-First Thinking
|
|
427
|
-
|
|
428
|
-
### Mental Model
|
|
429
|
-
|
|
430
|
-
**NOT TDD thinking:**
|
|
431
|
-
```
|
|
432
|
-
"How do I implement this feature?"
|
|
433
|
-
↓
|
|
434
|
-
Implement code
|
|
435
|
-
↓
|
|
436
|
-
"How do I test this?"
|
|
437
|
-
↓
|
|
438
|
-
Write tests
|
|
439
|
-
↓
|
|
440
|
-
Anti-patterns emerge
|
|
441
|
-
```
|
|
442
|
-
|
|
443
|
-
**TDD thinking:**
|
|
444
|
-
```
|
|
445
|
-
"How will I verify this works?"
|
|
446
|
-
↓
|
|
447
|
-
Write test
|
|
448
|
-
↓
|
|
449
|
-
"What's minimal code to pass?"
|
|
450
|
-
↓
|
|
451
|
-
Implement
|
|
452
|
-
↓
|
|
453
|
-
Anti-patterns prevented
|
|
454
|
-
```
|
|
455
|
-
|
|
456
|
-
### Test-First Benefits
|
|
457
|
-
|
|
458
|
-
**Design benefits:**
|
|
459
|
-
- API designed from consumer perspective
|
|
460
|
-
- Testable code (loose coupling)
|
|
461
|
-
- Clear interfaces
|
|
462
|
-
- Minimal implementation
|
|
463
|
-
|
|
464
|
-
**Quality benefits:**
|
|
465
|
-
- Verified behavior
|
|
466
|
-
- Edge cases caught early
|
|
467
|
-
- Regression prevention
|
|
468
|
-
- Living documentation
|
|
469
|
-
|
|
470
|
-
**Anti-pattern prevention:**
|
|
471
|
-
- Can't test mocks (test fails first against real code)
|
|
472
|
-
- No test-only methods (minimal implementation)
|
|
473
|
-
- Must understand dependencies (see real behavior)
|
|
474
|
-
- Complete structures (test with real data first)
|
|
475
|
-
- Tests ARE implementation (not afterthought)
|
|
476
|
-
|
|
477
|
-
## When TDD is Violated
|
|
478
|
-
|
|
479
|
-
**Signs you're not following TDD:**
|
|
480
|
-
|
|
481
|
-
```
|
|
482
|
-
🚩 Writing implementation before test
|
|
483
|
-
🚩 Test passes immediately
|
|
484
|
-
🚩 Skipping "watch it fail" step
|
|
485
|
-
🚩 Mocking before running test
|
|
486
|
-
🚩 "Implementation done, adding tests"
|
|
487
|
-
```
|
|
488
|
-
|
|
489
|
-
**Consequences:**
|
|
490
|
-
- All five anti-patterns become possible
|
|
491
|
-
- Test quality degrades
|
|
492
|
-
- False confidence
|
|
493
|
-
- Design issues
|
|
494
|
-
|
|
495
|
-
**Recovery:**
|
|
496
|
-
1. Stop adding features
|
|
497
|
-
2. Return to TDD workflow
|
|
498
|
-
3. Write test first for next feature
|
|
499
|
-
4. Watch it fail
|
|
500
|
-
5. Minimal implementation
|
|
501
|
-
6. Maintain discipline
|
|
502
|
-
|
|
503
|
-
## TDD and Mocking Strategy
|
|
504
|
-
|
|
505
|
-
### TDD-Compliant Mocking
|
|
506
|
-
|
|
507
|
-
**The right way:**
|
|
508
|
-
|
|
509
|
-
```typescript
|
|
510
|
-
// 1. Write test with real implementation
|
|
511
|
-
test('user registration sends welcome email', async () => {
|
|
512
|
-
await registerUser('alice@example.com');
|
|
513
|
-
// Observe: Email sending is slow (2 seconds)
|
|
514
|
-
});
|
|
515
|
-
|
|
516
|
-
// 2. Identify slow operation
|
|
517
|
-
// emailService.send() is slow (network call)
|
|
518
|
-
|
|
519
|
-
// 3. Mock at correct level
|
|
520
|
-
test('user registration sends welcome email', async () => {
|
|
521
|
-
vi.spyOn(emailService, 'send').mockResolvedValue();
|
|
522
|
-
|
|
523
|
-
await registerUser('alice@example.com');
|
|
524
|
-
|
|
525
|
-
expect(emailService.send).toHaveBeenCalledWith({
|
|
526
|
-
to: 'alice@example.com',
|
|
527
|
-
subject: 'Welcome'
|
|
528
|
-
});
|
|
529
|
-
});
|
|
530
|
-
// Test runs fast, verifies email logic
|
|
531
|
-
```
|
|
532
|
-
|
|
533
|
-
**TDD mocking principles:**
|
|
534
|
-
|
|
535
|
-
1. **Run with real implementation first** - See actual behavior
|
|
536
|
-
2. **Measure performance** - Mock only if slow
|
|
537
|
-
3. **Mock at boundaries** - I/O, network, filesystem
|
|
538
|
-
4. **Preserve business logic** - Don't mock what you're testing
|
|
539
|
-
5. **Verify behavior, not mocks** - Test results, not mock calls
|
|
540
|
-
|
|
541
|
-
### Mocking Levels in TDD
|
|
542
|
-
|
|
543
|
-
```
|
|
544
|
-
Layer 1: Business Logic
|
|
545
|
-
→ NEVER mock (this is what you're testing)
|
|
546
|
-
|
|
547
|
-
Layer 2: Application Services
|
|
548
|
-
→ RARELY mock (needed for assertions)
|
|
549
|
-
|
|
550
|
-
Layer 3: Adapters
|
|
551
|
-
→ SOMETIMES mock (if slow)
|
|
552
|
-
|
|
553
|
-
Layer 4: External I/O
|
|
554
|
-
→ USUALLY mock (network, DB, filesystem)
|
|
555
|
-
|
|
556
|
-
Layer 5: Infrastructure
|
|
557
|
-
→ ALWAYS mock in unit tests (servers, APIs)
|
|
558
|
-
```
|
|
559
|
-
|
|
560
|
-
## Common TDD Mistakes
|
|
561
|
-
|
|
562
|
-
### Mistake 1: Not Watching Test Fail
|
|
563
|
-
|
|
564
|
-
```typescript
|
|
565
|
-
// ❌ WRONG
|
|
566
|
-
test('feature works', () => {
|
|
567
|
-
expect(true).toBe(true); // Passes immediately
|
|
568
|
-
});
|
|
569
|
-
// Didn't verify test tests right thing
|
|
570
|
-
|
|
571
|
-
// ✅ RIGHT
|
|
572
|
-
test('validates email', async () => {
|
|
573
|
-
await expect(register('invalid'))
|
|
574
|
-
.rejects.toThrow('Invalid email');
|
|
575
|
-
});
|
|
576
|
-
// ❌ Fails first - register doesn't exist
|
|
577
|
-
// Then implement
|
|
578
|
-
// ✅ Passes - verified test works
|
|
579
|
-
```
|
|
580
|
-
|
|
581
|
-
### Mistake 2: Overly Complex Implementation
|
|
582
|
-
|
|
583
|
-
```typescript
|
|
584
|
-
// ❌ WRONG (not minimal)
|
|
585
|
-
test('adds numbers', () => {
|
|
586
|
-
expect(add(2, 3)).toBe(5);
|
|
587
|
-
});
|
|
588
|
-
|
|
589
|
-
function add(a: number, b: number): number {
|
|
590
|
-
// Not minimal - over-engineered
|
|
591
|
-
return Array(b).fill(a).reduce((sum, n) => sum + n, 0);
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
// ✅ RIGHT (minimal)
|
|
595
|
-
function add(a: number, b: number): number {
|
|
596
|
-
return a + b; // Simplest solution
|
|
597
|
-
}
|
|
598
|
-
```
|
|
599
|
-
|
|
600
|
-
### Mistake 3: Testing Implementation Details
|
|
601
|
-
|
|
602
|
-
```typescript
|
|
603
|
-
// ❌ WRONG
|
|
604
|
-
test('uses cache', () => {
|
|
605
|
-
const cache = new Cache();
|
|
606
|
-
service.setCache(cache); // Testing how it works
|
|
607
|
-
expect(service.cache).toBe(cache);
|
|
608
|
-
});
|
|
609
|
-
|
|
610
|
-
// ✅ RIGHT
|
|
611
|
-
test('returns cached result', () => {
|
|
612
|
-
service.get('key');
|
|
613
|
-
service.get('key');
|
|
614
|
-
expect(slowOperation).toHaveBeenCalledOnce(); // Testing behavior
|
|
615
|
-
});
|
|
616
|
-
```
|
|
617
|
-
|
|
618
|
-
## TDD Discipline
|
|
619
|
-
|
|
620
|
-
### Maintaining TDD Practice
|
|
621
|
-
|
|
622
|
-
**Commit to:**
|
|
623
|
-
- Test first, always
|
|
624
|
-
- Watch it fail, every time
|
|
625
|
-
- Minimal implementation, no gold plating
|
|
626
|
-
- Refactor with confidence
|
|
627
|
-
|
|
628
|
-
**When tempted to skip TDD:**
|
|
629
|
-
- "Just a small change" → Write test first
|
|
630
|
-
- "I know it works" → Write test to prove it
|
|
631
|
-
- "This is hard to test" → Design issue, fix it
|
|
632
|
-
- "Tests can wait" → No, they can't
|
|
633
|
-
|
|
634
|
-
**TDD is not optional:**
|
|
635
|
-
- Not a suggestion
|
|
636
|
-
- Not for later
|
|
637
|
-
- Not just for new features
|
|
638
|
-
- Not "when I have time"
|
|
639
|
-
|
|
640
|
-
**TDD is how you write code.**
|
|
641
|
-
|
|
642
|
-
## Integration with Other Skills
|
|
643
|
-
|
|
644
|
-
**Prerequisite skills:**
|
|
645
|
-
- [test-driven-development](../../test-driven-development/) - Complete TDD workflow
|
|
646
|
-
|
|
647
|
-
**Complementary skills:**
|
|
648
|
-
- [verification-before-completion](../../../productivity/verification-before-completion/) - Definition of "done"
|
|
649
|
-
|
|
650
|
-
**Anti-pattern prevention:**
|
|
651
|
-
- This skill - What TDD prevents
|
|
652
|
-
|
|
653
|
-
## Summary: TDD as Anti-Pattern Prevention
|
|
654
|
-
|
|
655
|
-
| Anti-Pattern | TDD Prevention Mechanism |
|
|
656
|
-
|--------------|---------------------------|
|
|
657
|
-
| Testing Mock Behavior | Must watch test fail against real code first |
|
|
658
|
-
| Test-Only Methods | Minimal implementation doesn't add them |
|
|
659
|
-
| Mocking Without Understanding | Run with real impl first, understand dependencies |
|
|
660
|
-
| Incomplete Mocks | Test with real data first, see complete structure |
|
|
661
|
-
| Tests as Afterthought | Tests first is the workflow, impossible to skip |
|
|
662
|
-
|
|
663
|
-
**The bottom line:** Strict TDD adherence makes testing anti-patterns nearly impossible to create.
|
|
664
|
-
|
|
665
|
-
If you find yourself with these anti-patterns, you've violated TDD. Return to the RED/GREEN/REFACTOR cycle.
|
|
666
|
-
|
|
667
|
-
## Quick Reference
|
|
668
|
-
|
|
669
|
-
**TDD Cycle:**
|
|
670
|
-
```
|
|
671
|
-
RED → Write failing test
|
|
672
|
-
GREEN → Minimal implementation
|
|
673
|
-
REFACTOR → Improve code
|
|
674
|
-
REPEAT → Next test
|
|
675
|
-
```
|
|
676
|
-
|
|
677
|
-
**Anti-pattern prevention:**
|
|
678
|
-
```
|
|
679
|
-
Test first → Prevents afterthought
|
|
680
|
-
Watch fail → Prevents mock testing
|
|
681
|
-
Minimal code → Prevents test-only methods
|
|
682
|
-
Real impl first → Prevents uninformed mocking
|
|
683
|
-
Real data first → Prevents incomplete mocks
|
|
684
|
-
```
|
|
685
|
-
|
|
686
|
-
**TDD discipline:**
|
|
687
|
-
```
|
|
688
|
-
Always test first
|
|
689
|
-
Always watch fail
|
|
690
|
-
Always minimal implementation
|
|
691
|
-
Always refactor
|
|
692
|
-
Never skip the cycle
|
|
693
|
-
```
|
|
694
|
-
|
|
695
|
-
See [test-driven-development skill](../../test-driven-development/) for complete TDD workflow and examples.
|