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.
Files changed (497) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_PM.md +12 -0
  3. claude_mpm/agents/OUTPUT_STYLE.md +3 -48
  4. claude_mpm/agents/PM_INSTRUCTIONS.md +632 -334
  5. claude_mpm/agents/WORKFLOW.md +75 -2
  6. claude_mpm/agents/__init__.py +6 -0
  7. claude_mpm/agents/agent_loader.py +1 -4
  8. claude_mpm/agents/base_agent.json +6 -3
  9. claude_mpm/agents/frontmatter_validator.py +1 -1
  10. claude_mpm/agents/templates/{circuit_breakers.md → circuit-breakers.md} +370 -3
  11. claude_mpm/agents/templates/context-management-examples.md +544 -0
  12. claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +89 -19
  13. claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
  14. claude_mpm/agents/templates/research-gate-examples.md +669 -0
  15. claude_mpm/agents/templates/structured-questions-examples.md +615 -0
  16. claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
  17. claude_mpm/agents/templates/ticketing-examples.md +277 -0
  18. claude_mpm/cli/__init__.py +38 -2
  19. claude_mpm/cli/commands/agent_source.py +774 -0
  20. claude_mpm/cli/commands/agent_state_manager.py +125 -20
  21. claude_mpm/cli/commands/agents.py +684 -13
  22. claude_mpm/cli/commands/agents_cleanup.py +210 -0
  23. claude_mpm/cli/commands/agents_discover.py +338 -0
  24. claude_mpm/cli/commands/aggregate.py +1 -1
  25. claude_mpm/cli/commands/analyze.py +3 -3
  26. claude_mpm/cli/commands/auto_configure.py +2 -6
  27. claude_mpm/cli/commands/cleanup.py +1 -1
  28. claude_mpm/cli/commands/config.py +7 -4
  29. claude_mpm/cli/commands/configure.py +478 -44
  30. claude_mpm/cli/commands/configure_agent_display.py +4 -4
  31. claude_mpm/cli/commands/configure_navigation.py +63 -46
  32. claude_mpm/cli/commands/debug.py +12 -12
  33. claude_mpm/cli/commands/doctor.py +10 -2
  34. claude_mpm/cli/commands/hook_errors.py +277 -0
  35. claude_mpm/cli/commands/local_deploy.py +1 -4
  36. claude_mpm/cli/commands/mcp_install_commands.py +1 -1
  37. claude_mpm/cli/commands/mpm_init/core.py +50 -2
  38. claude_mpm/cli/commands/mpm_init/git_activity.py +10 -10
  39. claude_mpm/cli/commands/mpm_init/prompts.py +6 -6
  40. claude_mpm/cli/commands/run.py +124 -128
  41. claude_mpm/cli/commands/skill_source.py +694 -0
  42. claude_mpm/cli/commands/skills.py +435 -1
  43. claude_mpm/cli/executor.py +78 -3
  44. claude_mpm/cli/interactive/agent_wizard.py +919 -41
  45. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  46. claude_mpm/cli/parsers/agents_parser.py +173 -4
  47. claude_mpm/cli/parsers/base_parser.py +49 -0
  48. claude_mpm/cli/parsers/config_parser.py +96 -43
  49. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  50. claude_mpm/cli/parsers/skills_parser.py +138 -0
  51. claude_mpm/cli/parsers/source_parser.py +138 -0
  52. claude_mpm/cli/startup.py +499 -84
  53. claude_mpm/cli/startup_display.py +480 -0
  54. claude_mpm/cli/utils.py +1 -1
  55. claude_mpm/cli_module/commands.py +1 -1
  56. claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
  57. claude_mpm/commands/mpm-agents-detect.md +9 -0
  58. claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
  59. claude_mpm/commands/mpm-agents-recommend.md +9 -0
  60. claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
  61. claude_mpm/commands/mpm-doctor.md +9 -0
  62. claude_mpm/commands/mpm-help.md +14 -2
  63. claude_mpm/commands/mpm-init.md +27 -2
  64. claude_mpm/commands/mpm-monitor.md +9 -0
  65. claude_mpm/commands/mpm-session-resume.md +381 -0
  66. claude_mpm/commands/mpm-status.md +9 -0
  67. claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
  68. claude_mpm/commands/mpm-ticket-view.md +552 -0
  69. claude_mpm/commands/mpm-version.md +9 -0
  70. claude_mpm/commands/mpm.md +11 -0
  71. claude_mpm/config/agent_presets.py +258 -0
  72. claude_mpm/config/agent_sources.py +325 -0
  73. claude_mpm/config/skill_sources.py +590 -0
  74. claude_mpm/constants.py +12 -0
  75. claude_mpm/core/api_validator.py +1 -1
  76. claude_mpm/core/claude_runner.py +17 -10
  77. claude_mpm/core/config.py +24 -0
  78. claude_mpm/core/constants.py +1 -1
  79. claude_mpm/core/framework/__init__.py +3 -16
  80. claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
  81. claude_mpm/core/framework/processors/metadata_processor.py +1 -1
  82. claude_mpm/core/hook_error_memory.py +381 -0
  83. claude_mpm/core/hook_manager.py +41 -2
  84. claude_mpm/core/interactive_session.py +112 -5
  85. claude_mpm/core/logger.py +3 -1
  86. claude_mpm/core/oneshot_session.py +94 -4
  87. claude_mpm/dashboard/static/css/activity.css +69 -69
  88. claude_mpm/dashboard/static/css/connection-status.css +10 -10
  89. claude_mpm/dashboard/static/css/dashboard.css +15 -15
  90. claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
  91. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
  92. claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
  93. claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
  94. claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
  95. claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
  96. claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
  97. claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
  98. claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
  99. claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
  100. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
  101. claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
  102. claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
  103. claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
  104. claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
  105. claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
  106. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
  107. claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
  108. claude_mpm/dashboard/static/js/connection-manager.js +76 -76
  109. claude_mpm/dashboard/static/js/dashboard.js +76 -58
  110. claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
  111. claude_mpm/dashboard/static/js/socket-client.js +138 -121
  112. claude_mpm/dashboard/templates/code_simple.html +23 -23
  113. claude_mpm/dashboard/templates/index.html +18 -18
  114. claude_mpm/experimental/cli_enhancements.py +1 -5
  115. claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
  116. claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
  117. claude_mpm/hooks/claude_hooks/installer.py +45 -0
  118. claude_mpm/hooks/failure_learning/__init__.py +2 -8
  119. claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
  120. claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
  121. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
  122. claude_mpm/hooks/kuzu_response_hook.py +1 -5
  123. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  124. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  125. claude_mpm/models/git_repository.py +198 -0
  126. claude_mpm/scripts/claude-hook-handler.sh +3 -3
  127. claude_mpm/scripts/start_activity_logging.py +3 -1
  128. claude_mpm/services/agents/agent_builder.py +45 -9
  129. claude_mpm/services/agents/agent_preset_service.py +238 -0
  130. claude_mpm/services/agents/agent_selection_service.py +484 -0
  131. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  132. claude_mpm/services/agents/deployment/agent_deployment.py +126 -2
  133. claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
  134. claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
  135. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
  136. claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
  137. claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
  138. claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
  139. claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
  140. claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
  141. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
  142. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +115 -15
  143. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
  144. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
  145. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +363 -0
  146. claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
  147. claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
  148. claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
  149. claude_mpm/services/agents/git_source_manager.py +629 -0
  150. claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
  151. claude_mpm/services/agents/local_template_manager.py +50 -10
  152. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  153. claude_mpm/services/agents/sources/__init__.py +13 -0
  154. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  155. claude_mpm/services/agents/sources/git_source_sync_service.py +1055 -0
  156. claude_mpm/services/agents/startup_sync.py +239 -0
  157. claude_mpm/services/agents/toolchain_detector.py +474 -0
  158. claude_mpm/services/cli/session_pause_manager.py +1 -1
  159. claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
  160. claude_mpm/services/command_deployment_service.py +92 -1
  161. claude_mpm/services/core/base.py +26 -11
  162. claude_mpm/services/core/interfaces/__init__.py +1 -3
  163. claude_mpm/services/core/interfaces/health.py +1 -4
  164. claude_mpm/services/core/models/__init__.py +2 -11
  165. claude_mpm/services/diagnostics/checks/__init__.py +4 -0
  166. claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
  167. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  168. claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
  169. claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
  170. claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
  171. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  172. claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
  173. claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
  174. claude_mpm/services/event_bus/direct_relay.py +3 -3
  175. claude_mpm/services/event_bus/event_bus.py +36 -3
  176. claude_mpm/services/event_bus/relay.py +23 -7
  177. claude_mpm/services/events/consumers/logging.py +1 -2
  178. claude_mpm/services/git/__init__.py +21 -0
  179. claude_mpm/services/git/git_operations_service.py +494 -0
  180. claude_mpm/services/github/__init__.py +21 -0
  181. claude_mpm/services/github/github_cli_service.py +397 -0
  182. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
  183. claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
  184. claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
  185. claude_mpm/services/instructions/__init__.py +9 -0
  186. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  187. claude_mpm/services/local_ops/__init__.py +3 -13
  188. claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
  189. claude_mpm/services/local_ops/health_manager.py +1 -4
  190. claude_mpm/services/local_ops/process_manager.py +1 -1
  191. claude_mpm/services/local_ops/resource_monitor.py +2 -2
  192. claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
  193. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
  194. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
  195. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
  196. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
  197. claude_mpm/services/memory/failure_tracker.py +19 -4
  198. claude_mpm/services/memory/optimizer.py +1 -1
  199. claude_mpm/services/model/model_router.py +8 -9
  200. claude_mpm/services/monitor/daemon.py +1 -1
  201. claude_mpm/services/monitor/server.py +2 -2
  202. claude_mpm/services/native_agent_converter.py +356 -0
  203. claude_mpm/services/port_manager.py +1 -1
  204. claude_mpm/services/pr/__init__.py +14 -0
  205. claude_mpm/services/pr/pr_template_service.py +329 -0
  206. claude_mpm/services/project/documentation_manager.py +2 -1
  207. claude_mpm/services/project/toolchain_analyzer.py +3 -1
  208. claude_mpm/services/runner_configuration_service.py +1 -0
  209. claude_mpm/services/self_upgrade_service.py +165 -7
  210. claude_mpm/services/skills/__init__.py +18 -0
  211. claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
  212. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  213. claude_mpm/services/skills_config.py +547 -0
  214. claude_mpm/services/skills_deployer.py +955 -0
  215. claude_mpm/services/socketio/handlers/connection.py +1 -1
  216. claude_mpm/services/socketio/handlers/git.py +2 -2
  217. claude_mpm/services/socketio/server/core.py +1 -4
  218. claude_mpm/services/socketio/server/main.py +1 -3
  219. claude_mpm/services/system_instructions_service.py +1 -3
  220. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
  221. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
  222. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
  223. claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
  224. claude_mpm/services/unified/unified_deployment.py +1 -5
  225. claude_mpm/services/version_control/conflict_resolution.py +6 -4
  226. claude_mpm/services/visualization/__init__.py +1 -5
  227. claude_mpm/services/visualization/mermaid_generator.py +2 -3
  228. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  229. claude_mpm/skills/bundled/performance-profiling.md +6 -0
  230. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +2 -2
  231. claude_mpm/skills/skills_registry.py +0 -1
  232. claude_mpm/templates/questions/__init__.py +38 -0
  233. claude_mpm/templates/questions/base.py +193 -0
  234. claude_mpm/templates/questions/pr_strategy.py +311 -0
  235. claude_mpm/templates/questions/project_init.py +385 -0
  236. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  237. claude_mpm/tools/__main__.py +8 -8
  238. claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
  239. claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
  240. claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
  241. claude_mpm/tools/code_tree_analyzer/core.py +380 -0
  242. claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
  243. claude_mpm/tools/code_tree_analyzer/events.py +168 -0
  244. claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
  245. claude_mpm/tools/code_tree_analyzer/models.py +39 -0
  246. claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
  247. claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
  248. claude_mpm/utils/agent_dependency_loader.py +80 -13
  249. claude_mpm/utils/dependency_cache.py +3 -1
  250. claude_mpm/utils/gitignore.py +241 -0
  251. claude_mpm/utils/log_cleanup.py +3 -3
  252. claude_mpm/utils/progress.py +383 -0
  253. claude_mpm/utils/robust_installer.py +3 -5
  254. claude_mpm/utils/structured_questions.py +619 -0
  255. {claude_mpm-4.21.0.dist-info → claude_mpm-5.0.2.dist-info}/METADATA +429 -59
  256. {claude_mpm-4.21.0.dist-info → claude_mpm-5.0.2.dist-info}/RECORD +264 -427
  257. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
  258. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
  259. claude_mpm/agents/templates/agent-manager.json +0 -273
  260. claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
  261. claude_mpm/agents/templates/api_qa.json +0 -180
  262. claude_mpm/agents/templates/clerk-ops.json +0 -235
  263. claude_mpm/agents/templates/code_analyzer.json +0 -101
  264. claude_mpm/agents/templates/content-agent.json +0 -358
  265. claude_mpm/agents/templates/dart_engineer.json +0 -307
  266. claude_mpm/agents/templates/data_engineer.json +0 -225
  267. claude_mpm/agents/templates/documentation.json +0 -211
  268. claude_mpm/agents/templates/engineer.json +0 -210
  269. claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
  270. claude_mpm/agents/templates/golang_engineer.json +0 -270
  271. claude_mpm/agents/templates/imagemagick.json +0 -264
  272. claude_mpm/agents/templates/java_engineer.json +0 -346
  273. claude_mpm/agents/templates/local_ops_agent.json +0 -1840
  274. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
  275. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
  276. claude_mpm/agents/templates/memory_manager.json +0 -158
  277. claude_mpm/agents/templates/nextjs_engineer.json +0 -285
  278. claude_mpm/agents/templates/ops.json +0 -185
  279. claude_mpm/agents/templates/php-engineer.json +0 -287
  280. claude_mpm/agents/templates/product_owner.json +0 -338
  281. claude_mpm/agents/templates/project_organizer.json +0 -140
  282. claude_mpm/agents/templates/prompt-engineer.json +0 -737
  283. claude_mpm/agents/templates/python_engineer.json +0 -387
  284. claude_mpm/agents/templates/qa.json +0 -242
  285. claude_mpm/agents/templates/react_engineer.json +0 -238
  286. claude_mpm/agents/templates/refactoring_engineer.json +0 -276
  287. claude_mpm/agents/templates/research.json +0 -188
  288. claude_mpm/agents/templates/ruby-engineer.json +0 -280
  289. claude_mpm/agents/templates/rust_engineer.json +0 -275
  290. claude_mpm/agents/templates/security.json +0 -202
  291. claude_mpm/agents/templates/svelte-engineer.json +0 -225
  292. claude_mpm/agents/templates/ticketing.json +0 -177
  293. claude_mpm/agents/templates/typescript_engineer.json +0 -285
  294. claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
  295. claude_mpm/agents/templates/version_control.json +0 -157
  296. claude_mpm/agents/templates/web_qa.json +0 -399
  297. claude_mpm/agents/templates/web_ui.json +0 -189
  298. claude_mpm/commands/mpm-tickets.md +0 -102
  299. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
  300. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
  301. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
  302. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
  303. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
  304. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
  305. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
  306. claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
  307. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
  308. claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
  309. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
  310. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
  311. claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
  312. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
  313. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
  314. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
  315. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
  316. claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
  317. claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
  318. claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
  319. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
  320. claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
  321. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
  322. claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
  323. claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
  324. claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
  325. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
  326. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
  327. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
  328. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
  329. claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
  330. claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
  331. claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
  332. claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
  333. claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
  334. claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
  335. claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
  336. claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
  337. claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
  338. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
  339. claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
  340. claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
  341. claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
  342. claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
  343. claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
  344. claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
  345. claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
  346. claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
  347. claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
  348. claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
  349. claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
  350. claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
  351. claude_mpm/dashboard/static/built/connection-manager.js +0 -536
  352. claude_mpm/dashboard/static/built/dashboard.js +0 -2
  353. claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
  354. claude_mpm/dashboard/static/built/react/events.js +0 -30
  355. claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
  356. claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
  357. claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
  358. claude_mpm/dashboard/static/built/shared/logger.js +0 -385
  359. claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
  360. claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
  361. claude_mpm/dashboard/static/built/socket-client.js +0 -2
  362. claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
  363. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
  364. claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
  365. claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
  366. claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
  367. claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
  368. claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
  369. claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
  370. claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
  371. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
  372. claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
  373. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
  374. claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
  375. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
  376. claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
  377. claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
  378. claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
  379. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
  380. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
  381. claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
  382. claude_mpm/dashboard/static/dist/dashboard.js +0 -2
  383. claude_mpm/dashboard/static/dist/react/events.js +0 -30
  384. claude_mpm/dashboard/static/dist/socket-client.js +0 -2
  385. claude_mpm/dashboard/static/events.html +0 -607
  386. claude_mpm/dashboard/static/index.html +0 -635
  387. claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
  388. claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
  389. claude_mpm/dashboard/static/js/shared/logger.js +0 -385
  390. claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
  391. claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
  392. claude_mpm/dashboard/static/legacy/activity.html +0 -736
  393. claude_mpm/dashboard/static/legacy/agents.html +0 -786
  394. claude_mpm/dashboard/static/legacy/files.html +0 -747
  395. claude_mpm/dashboard/static/legacy/tools.html +0 -831
  396. claude_mpm/dashboard/static/monitors.html +0 -431
  397. claude_mpm/dashboard/static/production/events.html +0 -659
  398. claude_mpm/dashboard/static/production/main.html +0 -698
  399. claude_mpm/dashboard/static/production/monitors.html +0 -483
  400. claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
  401. claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
  402. claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
  403. claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
  404. claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
  405. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -79
  406. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -178
  407. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +0 -577
  408. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +0 -467
  409. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +0 -537
  410. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +0 -730
  411. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -112
  412. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +0 -146
  413. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +0 -412
  414. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -81
  415. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +0 -362
  416. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +0 -312
  417. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -152
  418. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +0 -668
  419. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +0 -587
  420. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +0 -438
  421. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +0 -391
  422. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
  423. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
  424. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
  425. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
  426. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
  427. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
  428. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
  429. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
  430. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
  431. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
  432. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -131
  433. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -325
  434. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +0 -490
  435. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +0 -425
  436. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -499
  437. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -86
  438. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -43
  439. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
  440. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
  441. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
  442. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
  443. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -160
  444. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +0 -412
  445. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
  446. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
  447. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
  448. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
  449. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +0 -1237
  450. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -189
  451. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +0 -500
  452. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +0 -464
  453. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +0 -619
  454. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +0 -437
  455. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +0 -231
  456. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +0 -170
  457. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +0 -602
  458. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +0 -821
  459. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +0 -742
  460. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +0 -726
  461. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +0 -764
  462. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +0 -831
  463. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +0 -226
  464. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +0 -901
  465. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +0 -901
  466. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +0 -775
  467. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +0 -937
  468. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +0 -770
  469. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +0 -961
  470. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -119
  471. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +0 -253
  472. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
  473. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
  474. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
  475. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
  476. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
  477. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
  478. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -140
  479. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +0 -572
  480. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +0 -411
  481. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +0 -569
  482. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +0 -695
  483. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -184
  484. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +0 -459
  485. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +0 -479
  486. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +0 -687
  487. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +0 -758
  488. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +0 -868
  489. claude_mpm/tools/code_tree_analyzer.py +0 -1825
  490. /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
  491. /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
  492. /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
  493. /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
  494. {claude_mpm-4.21.0.dist-info → claude_mpm-5.0.2.dist-info}/WHEEL +0 -0
  495. {claude_mpm-4.21.0.dist-info → claude_mpm-5.0.2.dist-info}/entry_points.txt +0 -0
  496. {claude_mpm-4.21.0.dist-info → claude_mpm-5.0.2.dist-info}/licenses/LICENSE +0 -0
  497. {claude_mpm-4.21.0.dist-info → claude_mpm-5.0.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,576 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Environment variable validation script.
4
+
5
+ This script validates .env files for:
6
+ - Structure (valid key-value format, no duplicates, proper quoting)
7
+ - Completeness (compare with .env.example)
8
+ - Naming conventions (UPPERCASE_WITH_UNDERSCORES)
9
+ - Framework-specific rules (Next.js, Express, Flask, etc.)
10
+
11
+ Security: NEVER logs actual secret values.
12
+ """
13
+
14
+ import argparse
15
+ import json
16
+ import re
17
+ import sys
18
+ from pathlib import Path
19
+ from typing import Dict, List, Optional
20
+
21
+
22
+ class ValidationError:
23
+ """Represents a validation error."""
24
+
25
+ def __init__(
26
+ self, line: Optional[int], key: str, message: str, severity: str = "error"
27
+ ):
28
+ self.line = line
29
+ self.key = key
30
+ self.message = message
31
+ self.severity = severity # "error" or "warning"
32
+
33
+ def to_dict(self) -> Dict:
34
+ return {
35
+ "line": self.line,
36
+ "key": self.key,
37
+ "message": self.message,
38
+ "severity": self.severity,
39
+ }
40
+
41
+ def __str__(self) -> str:
42
+ prefix = "❌" if self.severity == "error" else "⚠️ "
43
+ line_info = f"Line {self.line}: " if self.line else ""
44
+ return f"{prefix} {line_info}{self.key}: {self.message}"
45
+
46
+
47
+ class EnvValidator:
48
+ """Validates environment variable files."""
49
+
50
+ # Valid variable name pattern: UPPERCASE_WITH_UNDERSCORES
51
+ VALID_NAME_PATTERN = re.compile(r"^[A-Z][A-Z0-9_]*$")
52
+
53
+ # Framework-specific prefixes
54
+ FRAMEWORK_PREFIXES = {
55
+ "nextjs": ["NEXT_PUBLIC_", "NEXT_"],
56
+ "vite": ["VITE_"],
57
+ "react": ["REACT_APP_"],
58
+ }
59
+
60
+ # Secret indicators (variables that should never be in NEXT_PUBLIC_, etc.)
61
+ SECRET_INDICATORS = ["secret", "key", "password", "token", "private", "api_key"]
62
+
63
+ def __init__(self, framework: Optional[str] = None, strict: bool = False):
64
+ self.framework = framework
65
+ self.strict = strict
66
+ self.errors: List[ValidationError] = []
67
+ self.warnings: List[ValidationError] = []
68
+
69
+ def parse_env_file(self, env_file: Path) -> Dict[str, str]:
70
+ """Parse .env file safely. Returns dict of key-value pairs."""
71
+ vars_dict = {}
72
+
73
+ with open(env_file) as f:
74
+ for line_num, line in enumerate(f, 1):
75
+ line = line.strip()
76
+
77
+ # Skip empty lines and comments
78
+ if not line or line.startswith("#"):
79
+ continue
80
+
81
+ # Check for valid format
82
+ if "=" not in line:
83
+ self.errors.append(
84
+ ValidationError(
85
+ line_num,
86
+ "",
87
+ f"Invalid format (missing =): {line[:50]}",
88
+ "error",
89
+ )
90
+ )
91
+ continue
92
+
93
+ # Split on first = only
94
+ key, value = line.split("=", 1)
95
+ key = key.strip()
96
+
97
+ # Remove quotes from value
98
+ value = value.strip()
99
+ if value and value[0] == value[-1] and value[0] in ('"', "'"):
100
+ value = value[1:-1]
101
+
102
+ vars_dict[key] = value
103
+
104
+ return vars_dict
105
+
106
+ def validate_structure(self, env_file: Path) -> List[ValidationError]:
107
+ """Validate basic file structure."""
108
+ errors = []
109
+
110
+ with open(env_file) as f:
111
+ for line_num, line in enumerate(f, 1):
112
+ line = line.strip()
113
+
114
+ # Skip empty lines and comments
115
+ if not line or line.startswith("#"):
116
+ continue
117
+
118
+ # Check for inline comments (warning)
119
+ if "#" in line and not line.startswith("#"):
120
+ key_value = line.split("#", 1)[0]
121
+ if "=" in key_value:
122
+ key, value = key_value.split("=", 1)
123
+ # Check if # is inside quotes
124
+ value = value.strip()
125
+ if not (value.startswith('"') or value.startswith("'")):
126
+ errors.append(
127
+ ValidationError(
128
+ line_num,
129
+ key.strip(),
130
+ "Possible inline comment (not all parsers support this)",
131
+ "warning",
132
+ )
133
+ )
134
+
135
+ # Check format
136
+ if "=" not in line:
137
+ errors.append(
138
+ ValidationError(
139
+ line_num,
140
+ "",
141
+ f"Invalid format (missing =): {line[:50]}",
142
+ "error",
143
+ )
144
+ )
145
+ continue
146
+
147
+ key, value = line.split("=", 1)
148
+ key = key.strip()
149
+
150
+ # Validate key name
151
+ if not self.VALID_NAME_PATTERN.match(key):
152
+ errors.append(
153
+ ValidationError(
154
+ line_num,
155
+ key,
156
+ "Invalid naming (use UPPERCASE_WITH_UNDERSCORES)",
157
+ "error",
158
+ )
159
+ )
160
+
161
+ # Check for spaces without quotes
162
+ value = value.strip()
163
+ if value and " " in value:
164
+ if not (value.startswith('"') or value.startswith("'")):
165
+ errors.append(
166
+ ValidationError(
167
+ line_num,
168
+ key,
169
+ "Value with spaces should be quoted",
170
+ "warning",
171
+ )
172
+ )
173
+
174
+ return errors
175
+
176
+ def check_duplicates(self, env_file: Path) -> Dict[str, List[int]]:
177
+ """Find duplicate keys and their line numbers."""
178
+ keys: Dict[str, List[int]] = {}
179
+
180
+ with open(env_file) as f:
181
+ for line_num, line in enumerate(f, 1):
182
+ line = line.strip()
183
+ if not line or line.startswith("#"):
184
+ continue
185
+
186
+ if "=" in line:
187
+ key = line.split("=", 1)[0].strip()
188
+ if key in keys:
189
+ keys[key].append(line_num)
190
+ else:
191
+ keys[key] = [line_num]
192
+
193
+ # Return only duplicates
194
+ duplicates = {k: v for k, v in keys.items() if len(v) > 1}
195
+
196
+ # Add errors for duplicates
197
+ for key, lines in duplicates.items():
198
+ self.errors.append(
199
+ ValidationError(
200
+ None,
201
+ key,
202
+ f"Duplicate key found on lines: {', '.join(map(str, lines))}",
203
+ "error",
204
+ )
205
+ )
206
+
207
+ return duplicates
208
+
209
+ def compare_env_files(self, env_file: Path, example_file: Path) -> Dict:
210
+ """Compare .env against .env.example."""
211
+ if not example_file.exists():
212
+ self.warnings.append(
213
+ ValidationError(
214
+ None, "", f".env.example not found: {example_file}", "warning"
215
+ )
216
+ )
217
+ return {"missing": set(), "extra": set(), "common": set()}
218
+
219
+ env_vars = set(self.parse_env_file(env_file).keys())
220
+ example_vars = set(self.parse_env_file(example_file).keys())
221
+
222
+ missing = example_vars - env_vars
223
+ extra = env_vars - example_vars
224
+ common = env_vars & example_vars
225
+
226
+ # Add errors for missing required variables
227
+ for var in missing:
228
+ self.errors.append(
229
+ ValidationError(
230
+ None,
231
+ var,
232
+ "Required variable missing (defined in .env.example)",
233
+ "error",
234
+ )
235
+ )
236
+
237
+ # Add warnings for undocumented variables
238
+ for var in extra:
239
+ self.warnings.append(
240
+ ValidationError(
241
+ None, var, "Variable not documented in .env.example", "warning"
242
+ )
243
+ )
244
+
245
+ return {"missing": missing, "extra": extra, "common": common}
246
+
247
+ def validate_framework_specific(self, env_file: Path) -> List[ValidationError]:
248
+ """Validate framework-specific rules."""
249
+ errors = []
250
+ vars_dict = self.parse_env_file(env_file)
251
+
252
+ if self.framework == "nextjs":
253
+ errors.extend(self._validate_nextjs(vars_dict))
254
+ elif self.framework == "vite":
255
+ errors.extend(self._validate_vite(vars_dict))
256
+ elif self.framework == "react":
257
+ errors.extend(self._validate_react(vars_dict))
258
+ elif self.framework == "nodejs":
259
+ errors.extend(self._validate_nodejs(vars_dict))
260
+ elif self.framework == "flask":
261
+ errors.extend(self._validate_flask(vars_dict))
262
+
263
+ return errors
264
+
265
+ def _validate_nextjs(self, vars_dict: Dict[str, str]) -> List[ValidationError]:
266
+ """Validate Next.js environment variables."""
267
+ errors = []
268
+
269
+ for key, value in vars_dict.items():
270
+ # Check for secrets in NEXT_PUBLIC_ vars
271
+ if key.startswith("NEXT_PUBLIC_"):
272
+ if any(
273
+ indicator in key.lower() for indicator in self.SECRET_INDICATORS
274
+ ):
275
+ errors.append(
276
+ ValidationError(
277
+ None,
278
+ key,
279
+ "SECURITY: Secret in NEXT_PUBLIC_ variable (exposed to browser)",
280
+ "error",
281
+ )
282
+ )
283
+
284
+ # Check for API URLs without NEXT_PUBLIC_ prefix
285
+ if "api" in key.lower() and "url" in key.lower():
286
+ if not key.startswith("NEXT_PUBLIC_") and not key.endswith("_SECRET"):
287
+ errors.append(
288
+ ValidationError(
289
+ None,
290
+ key,
291
+ "API URL without NEXT_PUBLIC_ prefix (not accessible client-side)",
292
+ "warning",
293
+ )
294
+ )
295
+
296
+ return errors
297
+
298
+ def _validate_vite(self, vars_dict: Dict[str, str]) -> List[ValidationError]:
299
+ """Validate Vite environment variables."""
300
+ errors = []
301
+
302
+ for key in vars_dict:
303
+ # Check for secrets in VITE_ vars
304
+ if key.startswith("VITE_"):
305
+ if any(
306
+ indicator in key.lower() for indicator in self.SECRET_INDICATORS
307
+ ):
308
+ errors.append(
309
+ ValidationError(
310
+ None,
311
+ key,
312
+ "SECURITY: Secret in VITE_ variable (exposed to browser)",
313
+ "error",
314
+ )
315
+ )
316
+
317
+ # Warn about non-VITE_ vars
318
+ elif key not in ["NODE_ENV", "PORT"]:
319
+ errors.append(
320
+ ValidationError(
321
+ None,
322
+ key,
323
+ "Variable not prefixed with VITE_ (not accessible in client code)",
324
+ "warning",
325
+ )
326
+ )
327
+
328
+ return errors
329
+
330
+ def _validate_react(self, vars_dict: Dict[str, str]) -> List[ValidationError]:
331
+ """Validate Create React App environment variables."""
332
+ errors = []
333
+
334
+ for key in vars_dict:
335
+ # Check for secrets in REACT_APP_ vars
336
+ if key.startswith("REACT_APP_"):
337
+ if any(
338
+ indicator in key.lower() for indicator in self.SECRET_INDICATORS
339
+ ):
340
+ errors.append(
341
+ ValidationError(
342
+ None,
343
+ key,
344
+ "SECURITY: Secret in REACT_APP_ variable (exposed to browser)",
345
+ "error",
346
+ )
347
+ )
348
+
349
+ return errors
350
+
351
+ def _validate_nodejs(self, vars_dict: Dict[str, str]) -> List[ValidationError]:
352
+ """Validate Node.js environment variables."""
353
+ errors = []
354
+
355
+ # Check NODE_ENV value
356
+ if "NODE_ENV" in vars_dict:
357
+ valid_values = ["development", "production", "test"]
358
+ if vars_dict["NODE_ENV"] not in valid_values:
359
+ # SECURITY: Never expose actual variable values in error messages
360
+ # to prevent accidental secret leakage in logs/CI output
361
+ errors.append(
362
+ ValidationError(
363
+ None,
364
+ "NODE_ENV",
365
+ f"Invalid value for NODE_ENV, expected one of {valid_values}",
366
+ "error",
367
+ )
368
+ )
369
+
370
+ # Check PORT is numeric
371
+ if "PORT" in vars_dict:
372
+ try:
373
+ port = int(vars_dict["PORT"])
374
+ if not (1 <= port <= 65535):
375
+ errors.append(
376
+ ValidationError(
377
+ None, "PORT", "PORT must be between 1 and 65535", "error"
378
+ )
379
+ )
380
+ except ValueError:
381
+ errors.append(
382
+ ValidationError(None, "PORT", "PORT must be numeric", "error")
383
+ )
384
+
385
+ return errors
386
+
387
+ def _validate_flask(self, vars_dict: Dict[str, str]) -> List[ValidationError]:
388
+ """Validate Flask environment variables."""
389
+ errors = []
390
+
391
+ # Check required vars
392
+ required = ["FLASK_APP", "SECRET_KEY"]
393
+ for var in required:
394
+ if var not in vars_dict:
395
+ errors.append(
396
+ ValidationError(
397
+ None, var, "Required Flask variable missing", "error"
398
+ )
399
+ )
400
+
401
+ # Check FLASK_APP ends with .py
402
+ if "FLASK_APP" in vars_dict:
403
+ if not vars_dict["FLASK_APP"].endswith(".py"):
404
+ errors.append(
405
+ ValidationError(
406
+ None,
407
+ "FLASK_APP",
408
+ "FLASK_APP should point to a .py file",
409
+ "warning",
410
+ )
411
+ )
412
+
413
+ # Check FLASK_ENV value
414
+ if "FLASK_ENV" in vars_dict:
415
+ valid_values = ["development", "production"]
416
+ if vars_dict["FLASK_ENV"] not in valid_values:
417
+ errors.append(
418
+ ValidationError(
419
+ None,
420
+ "FLASK_ENV",
421
+ f"Invalid value, expected one of {valid_values}",
422
+ "error",
423
+ )
424
+ )
425
+
426
+ return errors
427
+
428
+ def validate(self, env_file: Path, example_file: Optional[Path] = None) -> Dict:
429
+ """Run all validations. Returns summary dict."""
430
+ self.errors = []
431
+ self.warnings = []
432
+
433
+ # 1. Structure validation
434
+ structure_errors = self.validate_structure(env_file)
435
+ self.errors.extend([e for e in structure_errors if e.severity == "error"])
436
+ self.warnings.extend([e for e in structure_errors if e.severity == "warning"])
437
+
438
+ # 2. Check duplicates
439
+ self.check_duplicates(env_file)
440
+
441
+ # 3. Compare with .env.example
442
+ if example_file:
443
+ self.compare_env_files(env_file, example_file)
444
+
445
+ # 4. Framework-specific validation
446
+ if self.framework:
447
+ framework_errors = self.validate_framework_specific(env_file)
448
+ self.errors.extend([e for e in framework_errors if e.severity == "error"])
449
+ self.warnings.extend(
450
+ [e for e in framework_errors if e.severity == "warning"]
451
+ )
452
+
453
+ return {
454
+ "valid": len(self.errors) == 0,
455
+ "errors": self.errors,
456
+ "warnings": self.warnings,
457
+ "error_count": len(self.errors),
458
+ "warning_count": len(self.warnings),
459
+ }
460
+
461
+
462
+ def generate_example(env_file: Path, output_file: Path) -> None:
463
+ """Generate .env.example from .env file (with values removed)."""
464
+ with open(env_file) as f:
465
+ lines = f.readlines()
466
+
467
+ with open(output_file, "w") as f:
468
+ for line in lines:
469
+ line = line.strip()
470
+
471
+ # Keep comments and empty lines
472
+ if not line or line.startswith("#"):
473
+ f.write(line + "\n")
474
+ continue
475
+
476
+ # Replace values with placeholders
477
+ if "=" in line:
478
+ key, _ = line.split("=", 1)
479
+ f.write(f"{key}=your-{key.lower().replace('_', '-')}-here\n")
480
+
481
+ print(f"✅ Generated {output_file}")
482
+
483
+
484
+ def main():
485
+ parser = argparse.ArgumentParser(description="Validate environment variable files")
486
+ parser.add_argument("file", type=Path, help="Path to .env file to validate")
487
+ parser.add_argument(
488
+ "--compare-with",
489
+ type=Path,
490
+ help="Compare with .env.example file",
491
+ metavar="FILE",
492
+ )
493
+ parser.add_argument(
494
+ "--framework",
495
+ choices=["nextjs", "vite", "react", "nodejs", "flask", "generic"],
496
+ help="Framework-specific validation",
497
+ )
498
+ parser.add_argument(
499
+ "--strict", action="store_true", help="Treat warnings as errors"
500
+ )
501
+ parser.add_argument("--json", action="store_true", help="Output results as JSON")
502
+ parser.add_argument(
503
+ "--quiet", action="store_true", help="Only show errors, not warnings"
504
+ )
505
+ parser.add_argument(
506
+ "--generate-example",
507
+ type=Path,
508
+ help="Generate .env.example file",
509
+ metavar="OUTPUT",
510
+ )
511
+
512
+ args = parser.parse_args()
513
+
514
+ # Check input file exists
515
+ if not args.file.exists():
516
+ print(f"❌ Error: File not found: {args.file}")
517
+ sys.exit(2)
518
+
519
+ # Generate example if requested
520
+ if args.generate_example:
521
+ generate_example(args.file, args.generate_example)
522
+ return
523
+
524
+ # Run validation
525
+ validator = EnvValidator(framework=args.framework, strict=args.strict)
526
+ result = validator.validate(args.file, example_file=args.compare_with)
527
+
528
+ # Output results
529
+ if args.json:
530
+ output = {
531
+ "valid": result["valid"],
532
+ "file": str(args.file),
533
+ "errors": [e.to_dict() for e in result["errors"]],
534
+ "warnings": [w.to_dict() for w in result["warnings"]],
535
+ }
536
+ print(json.dumps(output, indent=2))
537
+ else:
538
+ print(f"\n🔍 Validating: {args.file}")
539
+ if args.framework:
540
+ print(f"📦 Framework: {args.framework}")
541
+ print()
542
+
543
+ # Show errors
544
+ if result["errors"]:
545
+ print("❌ Errors:")
546
+ for error in result["errors"]:
547
+ print(f" {error}")
548
+ print()
549
+
550
+ # Show warnings (unless quiet)
551
+ if result["warnings"] and not args.quiet:
552
+ print("⚠️ Warnings:")
553
+ for warning in result["warnings"]:
554
+ print(f" {warning}")
555
+ print()
556
+
557
+ # Summary
558
+ if result["valid"]:
559
+ print("✅ Validation passed!")
560
+ else:
561
+ print(f"❌ Validation failed: {result['error_count']} error(s)")
562
+
563
+ if not args.quiet:
564
+ print(
565
+ f"📊 Summary: {result['error_count']} errors, {result['warning_count']} warnings"
566
+ )
567
+
568
+ # Exit code
569
+ if result["errors"] or (args.strict and result["warnings"]):
570
+ sys.exit(1)
571
+ else:
572
+ sys.exit(0)
573
+
574
+
575
+ if __name__ == "__main__":
576
+ main()
@@ -433,6 +433,12 @@ def sort_items(items):
433
433
 
434
434
  ### Load Testing
435
435
 
436
+ > **Note:** Locust is an optional dependency. Install it separately if you need load testing capabilities:
437
+ > ```bash
438
+ > pip install "claude-mpm[agents-load-testing]"
439
+ > ```
440
+ > Or install locust directly: `pip install locust>=2.15.0`
441
+
436
442
  ```python
437
443
  # Using locust for load testing
438
444
  from locust import HttpUser, task, between
@@ -84,7 +84,7 @@ def main():
84
84
  try:
85
85
  # Start all servers
86
86
  for i, server in enumerate(servers):
87
- print(f"Starting server {i+1}/{len(servers)}: {server['cmd']}")
87
+ print(f"Starting server {i + 1}/{len(servers)}: {server['cmd']}")
88
88
 
89
89
  # Use shell=True to support commands with cd and &&
90
90
  process = subprocess.Popen(
@@ -121,7 +121,7 @@ def main():
121
121
  except subprocess.TimeoutExpired:
122
122
  process.kill()
123
123
  process.wait()
124
- print(f"Server {i+1} stopped")
124
+ print(f"Server {i + 1} stopped")
125
125
  print("All servers stopped")
126
126
 
127
127
 
@@ -342,7 +342,6 @@ class SkillsRegistry(LoggerMixin):
342
342
  query_lower in skill_name.lower()
343
343
  or query_lower in metadata.get("description", "").lower()
344
344
  ):
345
-
346
345
  results.append({"name": skill_name, **metadata})
347
346
 
348
347
  return results
@@ -0,0 +1,38 @@
1
+ """Structured question templates for common PM workflows.
2
+
3
+ This package provides reusable question templates that PM agents can use to gather
4
+ user input in a structured way. Templates are pre-configured QuestionSet objects
5
+ that can be customized based on context.
6
+
7
+ Available Templates:
8
+ - PR Strategy: Questions about PR workflow, draft preferences, auto-merge
9
+ - Project Initialization: Questions about project type, language, frameworks
10
+ - Ticket Management: Questions about ticket prioritization and scope
11
+
12
+ Example Usage:
13
+ >>> from claude_mpm.templates.questions.pr_strategy import PRWorkflowTemplate
14
+ >>> template = PRWorkflowTemplate(num_tickets=3)
15
+ >>> question_set = template.build()
16
+ >>> params = question_set.to_ask_user_question_params()
17
+ """
18
+
19
+ from claude_mpm.templates.questions.base import ConditionalTemplate, QuestionTemplate
20
+ from claude_mpm.templates.questions.pr_strategy import PRWorkflowTemplate
21
+ from claude_mpm.templates.questions.project_init import (
22
+ DevelopmentWorkflowTemplate,
23
+ ProjectTypeTemplate,
24
+ )
25
+ from claude_mpm.templates.questions.ticket_mgmt import (
26
+ TicketPrioritizationTemplate,
27
+ TicketScopeTemplate,
28
+ )
29
+
30
+ __all__ = [
31
+ "ConditionalTemplate",
32
+ "DevelopmentWorkflowTemplate",
33
+ "PRWorkflowTemplate",
34
+ "ProjectTypeTemplate",
35
+ "QuestionTemplate",
36
+ "TicketPrioritizationTemplate",
37
+ "TicketScopeTemplate",
38
+ ]