claude-mpm 4.21.3__py3-none-any.whl → 5.1.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (517) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_PM.md +12 -0
  3. claude_mpm/agents/{OUTPUT_STYLE.md → CLAUDE_MPM_OUTPUT_STYLE.md} +3 -48
  4. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +2002 -0
  5. claude_mpm/agents/PM_INSTRUCTIONS.md +1239 -674
  6. claude_mpm/agents/WORKFLOW.md +75 -2
  7. claude_mpm/agents/__init__.py +6 -0
  8. claude_mpm/agents/agent_loader.py +1 -4
  9. claude_mpm/agents/base_agent.json +6 -3
  10. claude_mpm/agents/base_agent_loader.py +10 -35
  11. claude_mpm/agents/frontmatter_validator.py +69 -1
  12. claude_mpm/agents/templates/circuit-breakers.md +1254 -0
  13. claude_mpm/agents/templates/context-management-examples.md +544 -0
  14. claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +89 -19
  15. claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
  16. claude_mpm/agents/templates/research-gate-examples.md +669 -0
  17. claude_mpm/agents/templates/structured-questions-examples.md +615 -0
  18. claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
  19. claude_mpm/agents/templates/ticketing-examples.md +277 -0
  20. claude_mpm/cli/__init__.py +37 -2
  21. claude_mpm/cli/commands/__init__.py +2 -0
  22. claude_mpm/cli/commands/agent_source.py +774 -0
  23. claude_mpm/cli/commands/agent_state_manager.py +188 -30
  24. claude_mpm/cli/commands/agents.py +1128 -36
  25. claude_mpm/cli/commands/agents_cleanup.py +210 -0
  26. claude_mpm/cli/commands/agents_discover.py +338 -0
  27. claude_mpm/cli/commands/aggregate.py +1 -1
  28. claude_mpm/cli/commands/analyze.py +3 -3
  29. claude_mpm/cli/commands/auto_configure.py +537 -239
  30. claude_mpm/cli/commands/cleanup.py +1 -1
  31. claude_mpm/cli/commands/config.py +7 -4
  32. claude_mpm/cli/commands/configure.py +935 -45
  33. claude_mpm/cli/commands/configure_agent_display.py +4 -4
  34. claude_mpm/cli/commands/configure_navigation.py +63 -46
  35. claude_mpm/cli/commands/debug.py +12 -12
  36. claude_mpm/cli/commands/doctor.py +10 -2
  37. claude_mpm/cli/commands/hook_errors.py +277 -0
  38. claude_mpm/cli/commands/local_deploy.py +1 -4
  39. claude_mpm/cli/commands/mcp_install_commands.py +1 -1
  40. claude_mpm/cli/commands/mpm_init/core.py +50 -2
  41. claude_mpm/cli/commands/mpm_init/git_activity.py +10 -10
  42. claude_mpm/cli/commands/mpm_init/prompts.py +6 -6
  43. claude_mpm/cli/commands/postmortem.py +401 -0
  44. claude_mpm/cli/commands/run.py +125 -167
  45. claude_mpm/cli/commands/skill_source.py +694 -0
  46. claude_mpm/cli/commands/skills.py +757 -20
  47. claude_mpm/cli/executor.py +78 -3
  48. claude_mpm/cli/interactive/agent_wizard.py +1032 -47
  49. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  50. claude_mpm/cli/parsers/agents_parser.py +310 -4
  51. claude_mpm/cli/parsers/auto_configure_parser.py +13 -0
  52. claude_mpm/cli/parsers/base_parser.py +53 -0
  53. claude_mpm/cli/parsers/config_parser.py +96 -43
  54. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  55. claude_mpm/cli/parsers/skills_parser.py +145 -0
  56. claude_mpm/cli/parsers/source_parser.py +138 -0
  57. claude_mpm/cli/startup.py +564 -108
  58. claude_mpm/cli/startup_display.py +480 -0
  59. claude_mpm/cli/utils.py +1 -1
  60. claude_mpm/cli_module/commands.py +1 -1
  61. claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
  62. claude_mpm/commands/mpm-agents-detect.md +9 -0
  63. claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
  64. claude_mpm/commands/mpm-agents-recommend.md +9 -0
  65. claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
  66. claude_mpm/commands/mpm-doctor.md +9 -0
  67. claude_mpm/commands/mpm-help.md +14 -2
  68. claude_mpm/commands/mpm-init.md +27 -2
  69. claude_mpm/commands/mpm-monitor.md +9 -0
  70. claude_mpm/commands/mpm-postmortem.md +123 -0
  71. claude_mpm/commands/{mpm-resume.md → mpm-session-resume.md} +9 -0
  72. claude_mpm/commands/mpm-status.md +9 -0
  73. claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
  74. claude_mpm/commands/mpm-ticket-view.md +552 -0
  75. claude_mpm/commands/mpm-version.md +9 -0
  76. claude_mpm/commands/mpm.md +10 -0
  77. claude_mpm/config/agent_presets.py +488 -0
  78. claude_mpm/config/agent_sources.py +325 -0
  79. claude_mpm/config/skill_presets.py +392 -0
  80. claude_mpm/config/skill_sources.py +590 -0
  81. claude_mpm/constants.py +13 -0
  82. claude_mpm/core/api_validator.py +1 -1
  83. claude_mpm/core/claude_runner.py +19 -35
  84. claude_mpm/core/config.py +24 -0
  85. claude_mpm/core/constants.py +1 -1
  86. claude_mpm/core/framework/__init__.py +3 -16
  87. claude_mpm/core/framework/loaders/file_loader.py +54 -101
  88. claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
  89. claude_mpm/core/framework/processors/metadata_processor.py +1 -1
  90. claude_mpm/core/hook_error_memory.py +381 -0
  91. claude_mpm/core/hook_manager.py +41 -2
  92. claude_mpm/core/interactive_session.py +131 -10
  93. claude_mpm/core/logger.py +3 -1
  94. claude_mpm/core/oneshot_session.py +110 -8
  95. claude_mpm/core/output_style_manager.py +173 -43
  96. claude_mpm/core/protocols/__init__.py +23 -0
  97. claude_mpm/core/protocols/runner_protocol.py +103 -0
  98. claude_mpm/core/protocols/session_protocol.py +131 -0
  99. claude_mpm/core/shared/singleton_manager.py +11 -4
  100. claude_mpm/core/system_context.py +38 -0
  101. claude_mpm/core/unified_agent_registry.py +129 -1
  102. claude_mpm/core/unified_config.py +22 -0
  103. claude_mpm/dashboard/static/css/activity.css +69 -69
  104. claude_mpm/dashboard/static/css/connection-status.css +10 -10
  105. claude_mpm/dashboard/static/css/dashboard.css +15 -15
  106. claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
  107. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
  108. claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
  109. claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
  110. claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
  111. claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
  112. claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
  113. claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
  114. claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
  115. claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
  116. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
  117. claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
  118. claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
  119. claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
  120. claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
  121. claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
  122. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
  123. claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
  124. claude_mpm/dashboard/static/js/connection-manager.js +76 -76
  125. claude_mpm/dashboard/static/js/dashboard.js +76 -58
  126. claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
  127. claude_mpm/dashboard/static/js/socket-client.js +138 -121
  128. claude_mpm/dashboard/templates/code_simple.html +23 -23
  129. claude_mpm/dashboard/templates/index.html +18 -18
  130. claude_mpm/experimental/cli_enhancements.py +1 -5
  131. claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
  132. claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
  133. claude_mpm/hooks/claude_hooks/installer.py +45 -0
  134. claude_mpm/hooks/claude_hooks/memory_integration.py +12 -1
  135. claude_mpm/hooks/failure_learning/__init__.py +2 -8
  136. claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
  137. claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
  138. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
  139. claude_mpm/hooks/kuzu_response_hook.py +1 -5
  140. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  141. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  142. claude_mpm/models/agent_definition.py +7 -0
  143. claude_mpm/models/git_repository.py +198 -0
  144. claude_mpm/scripts/claude-hook-handler.sh +3 -3
  145. claude_mpm/scripts/start_activity_logging.py +3 -1
  146. claude_mpm/services/agents/agent_builder.py +45 -9
  147. claude_mpm/services/agents/agent_preset_service.py +238 -0
  148. claude_mpm/services/agents/agent_selection_service.py +484 -0
  149. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  150. claude_mpm/services/agents/cache_git_manager.py +621 -0
  151. claude_mpm/services/agents/deployment/agent_deployment.py +126 -2
  152. claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
  153. claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
  154. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
  155. claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
  156. claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
  157. claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
  158. claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
  159. claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
  160. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
  161. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +225 -18
  162. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
  163. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
  164. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +557 -0
  165. claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
  166. claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
  167. claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
  168. claude_mpm/services/agents/git_source_manager.py +629 -0
  169. claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
  170. claude_mpm/services/agents/local_template_manager.py +50 -10
  171. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  172. claude_mpm/services/agents/sources/__init__.py +13 -0
  173. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  174. claude_mpm/services/agents/sources/git_source_sync_service.py +1087 -0
  175. claude_mpm/services/agents/startup_sync.py +239 -0
  176. claude_mpm/services/agents/toolchain_detector.py +474 -0
  177. claude_mpm/services/analysis/__init__.py +25 -0
  178. claude_mpm/services/analysis/postmortem_reporter.py +474 -0
  179. claude_mpm/services/analysis/postmortem_service.py +765 -0
  180. claude_mpm/services/cli/session_pause_manager.py +1 -1
  181. claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
  182. claude_mpm/services/command_deployment_service.py +200 -6
  183. claude_mpm/services/core/base.py +7 -2
  184. claude_mpm/services/core/interfaces/__init__.py +1 -3
  185. claude_mpm/services/core/interfaces/health.py +1 -4
  186. claude_mpm/services/core/models/__init__.py +2 -11
  187. claude_mpm/services/diagnostics/checks/__init__.py +4 -0
  188. claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
  189. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  190. claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
  191. claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
  192. claude_mpm/services/diagnostics/checks/mcp_services_check.py +7 -15
  193. claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
  194. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  195. claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
  196. claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
  197. claude_mpm/services/event_bus/direct_relay.py +3 -3
  198. claude_mpm/services/event_bus/event_bus.py +36 -3
  199. claude_mpm/services/events/consumers/logging.py +1 -2
  200. claude_mpm/services/git/__init__.py +21 -0
  201. claude_mpm/services/git/git_operations_service.py +494 -0
  202. claude_mpm/services/github/__init__.py +21 -0
  203. claude_mpm/services/github/github_cli_service.py +397 -0
  204. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
  205. claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
  206. claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
  207. claude_mpm/services/instructions/__init__.py +9 -0
  208. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  209. claude_mpm/services/local_ops/__init__.py +3 -13
  210. claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
  211. claude_mpm/services/local_ops/health_manager.py +1 -4
  212. claude_mpm/services/local_ops/process_manager.py +1 -1
  213. claude_mpm/services/local_ops/resource_monitor.py +2 -2
  214. claude_mpm/services/mcp_config_manager.py +75 -145
  215. claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
  216. claude_mpm/services/mcp_gateway/core/process_pool.py +22 -16
  217. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
  218. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
  219. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
  220. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
  221. claude_mpm/services/mcp_service_verifier.py +6 -3
  222. claude_mpm/services/memory/optimizer.py +1 -1
  223. claude_mpm/services/model/model_router.py +8 -9
  224. claude_mpm/services/monitor/daemon.py +29 -9
  225. claude_mpm/services/monitor/daemon_manager.py +96 -19
  226. claude_mpm/services/monitor/server.py +2 -2
  227. claude_mpm/services/native_agent_converter.py +356 -0
  228. claude_mpm/services/port_manager.py +1 -1
  229. claude_mpm/services/pr/__init__.py +14 -0
  230. claude_mpm/services/pr/pr_template_service.py +329 -0
  231. claude_mpm/services/project/documentation_manager.py +2 -1
  232. claude_mpm/services/project/project_organizer.py +4 -0
  233. claude_mpm/services/project/toolchain_analyzer.py +3 -1
  234. claude_mpm/services/runner_configuration_service.py +17 -3
  235. claude_mpm/services/self_upgrade_service.py +165 -7
  236. claude_mpm/services/session_management_service.py +16 -4
  237. claude_mpm/services/skills/__init__.py +18 -0
  238. claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
  239. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  240. claude_mpm/services/skills_config.py +547 -0
  241. claude_mpm/services/skills_deployer.py +955 -0
  242. claude_mpm/services/socketio/handlers/connection.py +1 -1
  243. claude_mpm/services/socketio/handlers/git.py +2 -2
  244. claude_mpm/services/socketio/server/core.py +1 -4
  245. claude_mpm/services/socketio/server/main.py +1 -3
  246. claude_mpm/services/system_instructions_service.py +1 -3
  247. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
  248. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
  249. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
  250. claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
  251. claude_mpm/services/unified/unified_deployment.py +1 -5
  252. claude_mpm/services/version_control/conflict_resolution.py +6 -4
  253. claude_mpm/services/visualization/__init__.py +1 -5
  254. claude_mpm/services/visualization/mermaid_generator.py +2 -3
  255. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  256. claude_mpm/skills/bundled/performance-profiling.md +6 -0
  257. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +2 -2
  258. claude_mpm/skills/skills_registry.py +0 -1
  259. claude_mpm/templates/questions/__init__.py +38 -0
  260. claude_mpm/templates/questions/base.py +193 -0
  261. claude_mpm/templates/questions/pr_strategy.py +311 -0
  262. claude_mpm/templates/questions/project_init.py +385 -0
  263. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  264. claude_mpm/tools/__main__.py +8 -8
  265. claude_mpm/tools/code_tree_analyzer/analysis.py +1 -1
  266. claude_mpm/utils/agent_dependency_loader.py +80 -13
  267. claude_mpm/utils/agent_filters.py +288 -0
  268. claude_mpm/utils/dependency_cache.py +3 -1
  269. claude_mpm/utils/gitignore.py +244 -0
  270. claude_mpm/utils/log_cleanup.py +3 -3
  271. claude_mpm/utils/migration.py +372 -0
  272. claude_mpm/utils/progress.py +387 -0
  273. claude_mpm/utils/robust_installer.py +3 -5
  274. claude_mpm/utils/structured_questions.py +619 -0
  275. {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/METADATA +496 -65
  276. {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/RECORD +284 -443
  277. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
  278. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
  279. claude_mpm/agents/templates/agent-manager.json +0 -273
  280. claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
  281. claude_mpm/agents/templates/api_qa.json +0 -180
  282. claude_mpm/agents/templates/circuit_breakers.md +0 -638
  283. claude_mpm/agents/templates/clerk-ops.json +0 -235
  284. claude_mpm/agents/templates/code_analyzer.json +0 -101
  285. claude_mpm/agents/templates/content-agent.json +0 -358
  286. claude_mpm/agents/templates/dart_engineer.json +0 -307
  287. claude_mpm/agents/templates/data_engineer.json +0 -225
  288. claude_mpm/agents/templates/documentation.json +0 -211
  289. claude_mpm/agents/templates/engineer.json +0 -210
  290. claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
  291. claude_mpm/agents/templates/golang_engineer.json +0 -270
  292. claude_mpm/agents/templates/imagemagick.json +0 -264
  293. claude_mpm/agents/templates/java_engineer.json +0 -346
  294. claude_mpm/agents/templates/local_ops_agent.json +0 -1840
  295. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
  296. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
  297. claude_mpm/agents/templates/memory_manager.json +0 -158
  298. claude_mpm/agents/templates/nextjs_engineer.json +0 -285
  299. claude_mpm/agents/templates/ops.json +0 -185
  300. claude_mpm/agents/templates/php-engineer.json +0 -287
  301. claude_mpm/agents/templates/product_owner.json +0 -338
  302. claude_mpm/agents/templates/project_organizer.json +0 -140
  303. claude_mpm/agents/templates/prompt-engineer.json +0 -737
  304. claude_mpm/agents/templates/python_engineer.json +0 -387
  305. claude_mpm/agents/templates/qa.json +0 -242
  306. claude_mpm/agents/templates/react_engineer.json +0 -238
  307. claude_mpm/agents/templates/refactoring_engineer.json +0 -276
  308. claude_mpm/agents/templates/research.json +0 -188
  309. claude_mpm/agents/templates/ruby-engineer.json +0 -280
  310. claude_mpm/agents/templates/rust_engineer.json +0 -275
  311. claude_mpm/agents/templates/security.json +0 -202
  312. claude_mpm/agents/templates/svelte-engineer.json +0 -225
  313. claude_mpm/agents/templates/ticketing.json +0 -177
  314. claude_mpm/agents/templates/typescript_engineer.json +0 -285
  315. claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
  316. claude_mpm/agents/templates/version_control.json +0 -157
  317. claude_mpm/agents/templates/web_qa.json +0 -399
  318. claude_mpm/agents/templates/web_ui.json +0 -189
  319. claude_mpm/commands/mpm-tickets.md +0 -102
  320. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
  321. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
  322. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
  323. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
  324. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
  325. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
  326. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
  327. claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
  328. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
  329. claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
  330. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
  331. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
  332. claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
  333. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
  334. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
  335. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
  336. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
  337. claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
  338. claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
  339. claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
  340. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
  341. claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
  342. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
  343. claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
  344. claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
  345. claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
  346. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
  347. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
  348. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
  349. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
  350. claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
  351. claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
  352. claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
  353. claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
  354. claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
  355. claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
  356. claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
  357. claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
  358. claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
  359. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
  360. claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
  361. claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
  362. claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
  363. claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
  364. claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
  365. claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
  366. claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
  367. claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
  368. claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
  369. claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
  370. claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
  371. claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
  372. claude_mpm/dashboard/static/built/connection-manager.js +0 -536
  373. claude_mpm/dashboard/static/built/dashboard.js +0 -2
  374. claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
  375. claude_mpm/dashboard/static/built/react/events.js +0 -30
  376. claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
  377. claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
  378. claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
  379. claude_mpm/dashboard/static/built/shared/logger.js +0 -385
  380. claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
  381. claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
  382. claude_mpm/dashboard/static/built/socket-client.js +0 -2
  383. claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
  384. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
  385. claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
  386. claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
  387. claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
  388. claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
  389. claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
  390. claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
  391. claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
  392. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
  393. claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
  394. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
  395. claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
  396. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
  397. claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
  398. claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
  399. claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
  400. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
  401. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
  402. claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
  403. claude_mpm/dashboard/static/dist/dashboard.js +0 -2
  404. claude_mpm/dashboard/static/dist/react/events.js +0 -30
  405. claude_mpm/dashboard/static/dist/socket-client.js +0 -2
  406. claude_mpm/dashboard/static/events.html +0 -607
  407. claude_mpm/dashboard/static/index.html +0 -635
  408. claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
  409. claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
  410. claude_mpm/dashboard/static/js/shared/logger.js +0 -385
  411. claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
  412. claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
  413. claude_mpm/dashboard/static/legacy/activity.html +0 -736
  414. claude_mpm/dashboard/static/legacy/agents.html +0 -786
  415. claude_mpm/dashboard/static/legacy/files.html +0 -747
  416. claude_mpm/dashboard/static/legacy/tools.html +0 -831
  417. claude_mpm/dashboard/static/monitors.html +0 -431
  418. claude_mpm/dashboard/static/production/events.html +0 -659
  419. claude_mpm/dashboard/static/production/main.html +0 -698
  420. claude_mpm/dashboard/static/production/monitors.html +0 -483
  421. claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
  422. claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
  423. claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
  424. claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
  425. claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
  426. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -79
  427. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -178
  428. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +0 -577
  429. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +0 -467
  430. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +0 -537
  431. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +0 -730
  432. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -112
  433. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +0 -146
  434. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +0 -412
  435. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -81
  436. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +0 -362
  437. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +0 -312
  438. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -152
  439. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +0 -668
  440. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +0 -587
  441. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +0 -438
  442. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +0 -391
  443. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
  444. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
  445. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
  446. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
  447. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
  448. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
  449. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
  450. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
  451. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
  452. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
  453. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -131
  454. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -325
  455. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +0 -490
  456. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +0 -425
  457. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -499
  458. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -86
  459. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -43
  460. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
  461. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
  462. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
  463. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
  464. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -160
  465. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +0 -412
  466. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
  467. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
  468. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
  469. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
  470. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +0 -1237
  471. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -189
  472. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +0 -500
  473. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +0 -464
  474. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +0 -619
  475. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +0 -437
  476. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +0 -231
  477. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +0 -170
  478. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +0 -602
  479. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +0 -821
  480. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +0 -742
  481. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +0 -726
  482. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +0 -764
  483. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +0 -831
  484. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +0 -226
  485. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +0 -901
  486. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +0 -901
  487. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +0 -775
  488. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +0 -937
  489. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +0 -770
  490. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +0 -961
  491. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -119
  492. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +0 -253
  493. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
  494. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
  495. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
  496. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
  497. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
  498. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
  499. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -140
  500. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +0 -572
  501. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +0 -411
  502. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +0 -569
  503. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +0 -695
  504. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -184
  505. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +0 -459
  506. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +0 -479
  507. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +0 -687
  508. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +0 -758
  509. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +0 -868
  510. /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
  511. /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
  512. /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
  513. /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
  514. {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/WHEEL +0 -0
  515. {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/entry_points.txt +0 -0
  516. {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/licenses/LICENSE +0 -0
  517. {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.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
+ ]