claude-mpm 4.20.3__py3-none-any.whl → 5.1.8__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 (520) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_PM.md +35 -6
  3. claude_mpm/agents/OUTPUT_STYLE.md +3 -48
  4. claude_mpm/agents/PM_INSTRUCTIONS.md +1241 -667
  5. claude_mpm/agents/PM_INSTRUCTIONS_TEACH.md +1322 -0
  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 +1 -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 +959 -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 +924 -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/__init__.py +73 -0
  41. claude_mpm/cli/commands/mpm_init/core.py +573 -0
  42. claude_mpm/cli/commands/mpm_init/display.py +341 -0
  43. claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
  44. claude_mpm/cli/commands/mpm_init/modes.py +397 -0
  45. claude_mpm/cli/commands/mpm_init/prompts.py +442 -0
  46. claude_mpm/cli/commands/mpm_init_cli.py +396 -0
  47. claude_mpm/cli/commands/mpm_init_handler.py +67 -1
  48. claude_mpm/cli/commands/postmortem.py +401 -0
  49. claude_mpm/cli/commands/run.py +125 -167
  50. claude_mpm/cli/commands/skill_source.py +694 -0
  51. claude_mpm/cli/commands/skills.py +835 -44
  52. claude_mpm/cli/executor.py +78 -3
  53. claude_mpm/cli/interactive/agent_wizard.py +1032 -47
  54. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  55. claude_mpm/cli/parsers/agents_parser.py +256 -4
  56. claude_mpm/cli/parsers/auto_configure_parser.py +13 -0
  57. claude_mpm/cli/parsers/base_parser.py +53 -0
  58. claude_mpm/cli/parsers/config_parser.py +96 -43
  59. claude_mpm/cli/parsers/mpm_init_parser.py +42 -0
  60. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  61. claude_mpm/cli/parsers/skills_parser.py +145 -0
  62. claude_mpm/cli/parsers/source_parser.py +138 -0
  63. claude_mpm/cli/startup.py +564 -108
  64. claude_mpm/cli/startup_display.py +480 -0
  65. claude_mpm/cli/utils.py +1 -1
  66. claude_mpm/cli_module/commands.py +1 -1
  67. claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
  68. claude_mpm/commands/mpm-agents-detect.md +9 -0
  69. claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
  70. claude_mpm/commands/mpm-agents-recommend.md +9 -0
  71. claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
  72. claude_mpm/commands/mpm-doctor.md +9 -0
  73. claude_mpm/commands/mpm-help.md +17 -2
  74. claude_mpm/commands/mpm-init.md +28 -3
  75. claude_mpm/commands/mpm-monitor.md +9 -0
  76. claude_mpm/commands/mpm-postmortem.md +123 -0
  77. claude_mpm/commands/mpm-session-resume.md +381 -0
  78. claude_mpm/commands/mpm-status.md +9 -0
  79. claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
  80. claude_mpm/commands/mpm-ticket-view.md +552 -0
  81. claude_mpm/commands/mpm-version.md +9 -0
  82. claude_mpm/commands/mpm.md +11 -0
  83. claude_mpm/config/agent_presets.py +488 -0
  84. claude_mpm/config/agent_sources.py +325 -0
  85. claude_mpm/config/skill_presets.py +392 -0
  86. claude_mpm/config/skill_sources.py +590 -0
  87. claude_mpm/constants.py +13 -0
  88. claude_mpm/core/api_validator.py +1 -1
  89. claude_mpm/core/claude_runner.py +19 -35
  90. claude_mpm/core/config.py +24 -0
  91. claude_mpm/core/constants.py +1 -1
  92. claude_mpm/core/framework/__init__.py +3 -16
  93. claude_mpm/core/framework/loaders/file_loader.py +54 -101
  94. claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
  95. claude_mpm/core/framework/processors/metadata_processor.py +1 -1
  96. claude_mpm/core/hook_error_memory.py +381 -0
  97. claude_mpm/core/hook_manager.py +41 -2
  98. claude_mpm/core/interactive_session.py +131 -10
  99. claude_mpm/core/interfaces.py +56 -1
  100. claude_mpm/core/logger.py +3 -1
  101. claude_mpm/core/oneshot_session.py +110 -8
  102. claude_mpm/core/protocols/__init__.py +23 -0
  103. claude_mpm/core/protocols/runner_protocol.py +103 -0
  104. claude_mpm/core/protocols/session_protocol.py +131 -0
  105. claude_mpm/core/shared/singleton_manager.py +11 -4
  106. claude_mpm/core/system_context.py +38 -0
  107. claude_mpm/core/unified_config.py +22 -0
  108. claude_mpm/dashboard/static/css/activity.css +69 -69
  109. claude_mpm/dashboard/static/css/connection-status.css +10 -10
  110. claude_mpm/dashboard/static/css/dashboard.css +15 -15
  111. claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
  112. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
  113. claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
  114. claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
  115. claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
  116. claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
  117. claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
  118. claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
  119. claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
  120. claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
  121. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
  122. claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
  123. claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
  124. claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
  125. claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
  126. claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
  127. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
  128. claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
  129. claude_mpm/dashboard/static/js/connection-manager.js +76 -76
  130. claude_mpm/dashboard/static/js/dashboard.js +76 -58
  131. claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
  132. claude_mpm/dashboard/static/js/socket-client.js +138 -121
  133. claude_mpm/dashboard/templates/code_simple.html +23 -23
  134. claude_mpm/dashboard/templates/index.html +18 -18
  135. claude_mpm/experimental/cli_enhancements.py +1 -5
  136. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
  137. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
  138. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
  139. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
  140. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
  141. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
  142. claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
  143. claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
  144. claude_mpm/hooks/claude_hooks/installer.py +45 -0
  145. claude_mpm/hooks/claude_hooks/memory_integration.py +12 -1
  146. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
  147. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
  148. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
  149. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
  150. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
  151. claude_mpm/hooks/failure_learning/__init__.py +2 -8
  152. claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
  153. claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
  154. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
  155. claude_mpm/hooks/kuzu_response_hook.py +1 -5
  156. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  157. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  158. claude_mpm/models/git_repository.py +198 -0
  159. claude_mpm/scripts/claude-hook-handler.sh +3 -3
  160. claude_mpm/scripts/start_activity_logging.py +3 -1
  161. claude_mpm/services/agents/agent_builder.py +45 -9
  162. claude_mpm/services/agents/agent_preset_service.py +238 -0
  163. claude_mpm/services/agents/agent_selection_service.py +484 -0
  164. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  165. claude_mpm/services/agents/cache_git_manager.py +621 -0
  166. claude_mpm/services/agents/deployment/agent_deployment.py +126 -2
  167. claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
  168. claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
  169. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
  170. claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
  171. claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
  172. claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
  173. claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
  174. claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
  175. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
  176. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +115 -15
  177. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
  178. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
  179. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +363 -0
  180. claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
  181. claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
  182. claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
  183. claude_mpm/services/agents/git_source_manager.py +629 -0
  184. claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
  185. claude_mpm/services/agents/local_template_manager.py +50 -10
  186. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  187. claude_mpm/services/agents/sources/__init__.py +13 -0
  188. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  189. claude_mpm/services/agents/sources/git_source_sync_service.py +1087 -0
  190. claude_mpm/services/agents/startup_sync.py +239 -0
  191. claude_mpm/services/agents/toolchain_detector.py +474 -0
  192. claude_mpm/services/analysis/__init__.py +25 -0
  193. claude_mpm/services/analysis/postmortem_reporter.py +474 -0
  194. claude_mpm/services/analysis/postmortem_service.py +765 -0
  195. claude_mpm/services/cli/session_pause_manager.py +504 -0
  196. claude_mpm/services/cli/session_resume_helper.py +36 -16
  197. claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
  198. claude_mpm/services/command_deployment_service.py +200 -6
  199. claude_mpm/services/core/base.py +31 -11
  200. claude_mpm/services/core/interfaces/__init__.py +1 -3
  201. claude_mpm/services/core/interfaces/health.py +1 -4
  202. claude_mpm/services/core/interfaces.py +56 -1
  203. claude_mpm/services/core/models/__init__.py +2 -11
  204. claude_mpm/services/core/models/agent_config.py +3 -0
  205. claude_mpm/services/core/models/process.py +4 -0
  206. claude_mpm/services/diagnostics/checks/__init__.py +4 -0
  207. claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
  208. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  209. claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
  210. claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
  211. claude_mpm/services/diagnostics/checks/mcp_services_check.py +7 -15
  212. claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
  213. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  214. claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
  215. claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
  216. claude_mpm/services/diagnostics/models.py +21 -0
  217. claude_mpm/services/event_bus/direct_relay.py +3 -3
  218. claude_mpm/services/event_bus/event_bus.py +36 -3
  219. claude_mpm/services/event_bus/relay.py +23 -7
  220. claude_mpm/services/events/consumers/logging.py +1 -2
  221. claude_mpm/services/git/__init__.py +21 -0
  222. claude_mpm/services/git/git_operations_service.py +494 -0
  223. claude_mpm/services/github/__init__.py +21 -0
  224. claude_mpm/services/github/github_cli_service.py +397 -0
  225. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
  226. claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
  227. claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
  228. claude_mpm/services/instructions/__init__.py +9 -0
  229. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  230. claude_mpm/services/local_ops/__init__.py +5 -13
  231. claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
  232. claude_mpm/services/local_ops/health_manager.py +1 -4
  233. claude_mpm/services/local_ops/process_manager.py +1 -1
  234. claude_mpm/services/local_ops/resource_monitor.py +2 -2
  235. claude_mpm/services/mcp_config_manager.py +75 -145
  236. claude_mpm/services/mcp_gateway/auto_configure.py +31 -25
  237. claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
  238. claude_mpm/services/mcp_gateway/core/process_pool.py +41 -26
  239. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
  240. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
  241. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
  242. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +26 -21
  243. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
  244. claude_mpm/services/mcp_service_verifier.py +6 -3
  245. claude_mpm/services/memory/failure_tracker.py +19 -4
  246. claude_mpm/services/memory/optimizer.py +1 -1
  247. claude_mpm/services/model/model_router.py +8 -9
  248. claude_mpm/services/monitor/daemon.py +29 -9
  249. claude_mpm/services/monitor/daemon_manager.py +96 -19
  250. claude_mpm/services/monitor/server.py +2 -2
  251. claude_mpm/services/native_agent_converter.py +356 -0
  252. claude_mpm/services/port_manager.py +1 -1
  253. claude_mpm/services/pr/__init__.py +14 -0
  254. claude_mpm/services/pr/pr_template_service.py +329 -0
  255. claude_mpm/services/project/documentation_manager.py +2 -1
  256. claude_mpm/services/project/project_organizer.py +4 -0
  257. claude_mpm/services/project/toolchain_analyzer.py +3 -1
  258. claude_mpm/services/runner_configuration_service.py +17 -3
  259. claude_mpm/services/self_upgrade_service.py +165 -7
  260. claude_mpm/services/session_management_service.py +16 -4
  261. claude_mpm/services/skills/__init__.py +18 -0
  262. claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
  263. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  264. claude_mpm/services/skills_config.py +547 -0
  265. claude_mpm/services/skills_deployer.py +955 -0
  266. claude_mpm/services/socketio/handlers/connection.py +1 -1
  267. claude_mpm/services/socketio/handlers/git.py +2 -2
  268. claude_mpm/services/socketio/server/core.py +1 -4
  269. claude_mpm/services/socketio/server/main.py +1 -3
  270. claude_mpm/services/system_instructions_service.py +1 -3
  271. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
  272. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
  273. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
  274. claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
  275. claude_mpm/services/unified/unified_deployment.py +1 -5
  276. claude_mpm/services/version_control/conflict_resolution.py +6 -4
  277. claude_mpm/services/visualization/__init__.py +1 -5
  278. claude_mpm/services/visualization/mermaid_generator.py +2 -3
  279. claude_mpm/skills/__init__.py +3 -3
  280. claude_mpm/skills/agent_skills_injector.py +42 -49
  281. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  282. claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +17 -10
  283. claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +92 -39
  284. claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +13 -12
  285. claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +5 -3
  286. claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +19 -12
  287. claude_mpm/skills/bundled/performance-profiling.md +6 -0
  288. claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +6 -6
  289. claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +13 -9
  290. claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +8 -8
  291. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +37 -15
  292. claude_mpm/skills/skills_registry.py +44 -48
  293. claude_mpm/skills/skills_service.py +117 -108
  294. claude_mpm/templates/questions/__init__.py +38 -0
  295. claude_mpm/templates/questions/base.py +193 -0
  296. claude_mpm/templates/questions/pr_strategy.py +311 -0
  297. claude_mpm/templates/questions/project_init.py +385 -0
  298. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  299. claude_mpm/tools/__main__.py +8 -8
  300. claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
  301. claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
  302. claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
  303. claude_mpm/tools/code_tree_analyzer/core.py +380 -0
  304. claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
  305. claude_mpm/tools/code_tree_analyzer/events.py +168 -0
  306. claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
  307. claude_mpm/tools/code_tree_analyzer/models.py +39 -0
  308. claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
  309. claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
  310. claude_mpm/utils/agent_dependency_loader.py +80 -13
  311. claude_mpm/utils/agent_filters.py +288 -0
  312. claude_mpm/utils/dependency_cache.py +3 -1
  313. claude_mpm/utils/gitignore.py +244 -0
  314. claude_mpm/utils/log_cleanup.py +3 -3
  315. claude_mpm/utils/migration.py +372 -0
  316. claude_mpm/utils/progress.py +387 -0
  317. claude_mpm/utils/robust_installer.py +3 -5
  318. claude_mpm/utils/structured_questions.py +619 -0
  319. {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/METADATA +496 -65
  320. {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/RECORD +328 -416
  321. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
  322. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
  323. claude_mpm/agents/templates/agent-manager.json +0 -273
  324. claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
  325. claude_mpm/agents/templates/api_qa.json +0 -180
  326. claude_mpm/agents/templates/circuit_breakers.md +0 -638
  327. claude_mpm/agents/templates/clerk-ops.json +0 -235
  328. claude_mpm/agents/templates/code_analyzer.json +0 -101
  329. claude_mpm/agents/templates/content-agent.json +0 -358
  330. claude_mpm/agents/templates/dart_engineer.json +0 -307
  331. claude_mpm/agents/templates/data_engineer.json +0 -225
  332. claude_mpm/agents/templates/documentation.json +0 -211
  333. claude_mpm/agents/templates/engineer.json +0 -210
  334. claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
  335. claude_mpm/agents/templates/golang_engineer.json +0 -270
  336. claude_mpm/agents/templates/imagemagick.json +0 -264
  337. claude_mpm/agents/templates/java_engineer.json +0 -346
  338. claude_mpm/agents/templates/local_ops_agent.json +0 -1840
  339. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
  340. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
  341. claude_mpm/agents/templates/memory_manager.json +0 -158
  342. claude_mpm/agents/templates/nextjs_engineer.json +0 -285
  343. claude_mpm/agents/templates/ops.json +0 -185
  344. claude_mpm/agents/templates/php-engineer.json +0 -281
  345. claude_mpm/agents/templates/product_owner.json +0 -338
  346. claude_mpm/agents/templates/project_organizer.json +0 -140
  347. claude_mpm/agents/templates/prompt-engineer.json +0 -737
  348. claude_mpm/agents/templates/python_engineer.json +0 -387
  349. claude_mpm/agents/templates/qa.json +0 -242
  350. claude_mpm/agents/templates/react_engineer.json +0 -238
  351. claude_mpm/agents/templates/refactoring_engineer.json +0 -276
  352. claude_mpm/agents/templates/research.json +0 -188
  353. claude_mpm/agents/templates/ruby-engineer.json +0 -280
  354. claude_mpm/agents/templates/rust_engineer.json +0 -275
  355. claude_mpm/agents/templates/security.json +0 -202
  356. claude_mpm/agents/templates/svelte-engineer.json +0 -225
  357. claude_mpm/agents/templates/ticketing.json +0 -177
  358. claude_mpm/agents/templates/typescript_engineer.json +0 -285
  359. claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
  360. claude_mpm/agents/templates/version_control.json +0 -157
  361. claude_mpm/agents/templates/web_qa.json +0 -399
  362. claude_mpm/agents/templates/web_ui.json +0 -189
  363. claude_mpm/cli/commands/mpm_init.py +0 -2093
  364. claude_mpm/commands/mpm-tickets.md +0 -102
  365. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
  366. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
  367. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
  368. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
  369. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
  370. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
  371. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
  372. claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
  373. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
  374. claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
  375. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
  376. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
  377. claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
  378. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
  379. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
  380. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
  381. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
  382. claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
  383. claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
  384. claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
  385. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
  386. claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
  387. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
  388. claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
  389. claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
  390. claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
  391. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
  392. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
  393. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
  394. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
  395. claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
  396. claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
  397. claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
  398. claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
  399. claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
  400. claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
  401. claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
  402. claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
  403. claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
  404. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
  405. claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
  406. claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
  407. claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
  408. claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
  409. claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
  410. claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
  411. claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
  412. claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
  413. claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
  414. claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
  415. claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
  416. claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
  417. claude_mpm/dashboard/static/built/connection-manager.js +0 -536
  418. claude_mpm/dashboard/static/built/dashboard.js +0 -2
  419. claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
  420. claude_mpm/dashboard/static/built/react/events.js +0 -30
  421. claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
  422. claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
  423. claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
  424. claude_mpm/dashboard/static/built/shared/logger.js +0 -385
  425. claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
  426. claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
  427. claude_mpm/dashboard/static/built/socket-client.js +0 -2
  428. claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
  429. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
  430. claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
  431. claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
  432. claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
  433. claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
  434. claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
  435. claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
  436. claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
  437. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
  438. claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
  439. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
  440. claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
  441. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
  442. claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
  443. claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
  444. claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
  445. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
  446. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
  447. claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
  448. claude_mpm/dashboard/static/dist/dashboard.js +0 -2
  449. claude_mpm/dashboard/static/dist/react/events.js +0 -30
  450. claude_mpm/dashboard/static/dist/socket-client.js +0 -2
  451. claude_mpm/dashboard/static/events.html +0 -607
  452. claude_mpm/dashboard/static/index.html +0 -635
  453. claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
  454. claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
  455. claude_mpm/dashboard/static/js/shared/logger.js +0 -385
  456. claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
  457. claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
  458. claude_mpm/dashboard/static/legacy/activity.html +0 -736
  459. claude_mpm/dashboard/static/legacy/agents.html +0 -786
  460. claude_mpm/dashboard/static/legacy/files.html +0 -747
  461. claude_mpm/dashboard/static/legacy/tools.html +0 -831
  462. claude_mpm/dashboard/static/monitors.html +0 -431
  463. claude_mpm/dashboard/static/production/events.html +0 -659
  464. claude_mpm/dashboard/static/production/main.html +0 -698
  465. claude_mpm/dashboard/static/production/monitors.html +0 -483
  466. claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
  467. claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
  468. claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
  469. claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
  470. claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
  471. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -75
  472. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -184
  473. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -107
  474. claude_mpm/skills/bundled/collaboration/requesting-code-review/code-reviewer.md +0 -146
  475. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -118
  476. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -177
  477. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
  478. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
  479. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
  480. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
  481. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
  482. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
  483. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
  484. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
  485. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
  486. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
  487. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -175
  488. claude_mpm/skills/bundled/debugging/verification-before-completion/references/common-failures.md +0 -213
  489. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -314
  490. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -227
  491. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -74
  492. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -32
  493. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
  494. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
  495. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
  496. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
  497. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -328
  498. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
  499. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
  500. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
  501. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
  502. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -209
  503. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -123
  504. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
  505. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
  506. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
  507. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
  508. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
  509. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
  510. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -304
  511. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -96
  512. claude_mpm/tools/code_tree_analyzer.py +0 -1825
  513. /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
  514. /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
  515. /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
  516. /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
  517. {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/WHEEL +0 -0
  518. {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/entry_points.txt +0 -0
  519. {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/licenses/LICENSE +0 -0
  520. {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,323 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ PreToolUse Hook Template for Claude Code v2.0.30+
4
+
5
+ This template demonstrates how to create PreToolUse hooks that can modify
6
+ tool inputs before execution. Use cases include:
7
+
8
+ 1. Context Injection: Add project context to Read/Edit operations
9
+ 2. Security Guards: Validate file paths before operations
10
+ 3. Logging: Log tool invocations before execution
11
+ 4. Parameter Enhancement: Add default parameters to tool calls
12
+
13
+ Requirements:
14
+ - Claude Code v2.0.30 or higher
15
+ - Hook must be configured with "modifyInput": true in settings.json
16
+
17
+ Input Format (stdin):
18
+ {
19
+ "hook_event_name": "PreToolUse",
20
+ "tool_name": "Edit",
21
+ "tool_input": {
22
+ "file_path": "/path/to/file.py",
23
+ "old_string": "foo",
24
+ "new_string": "bar"
25
+ },
26
+ "session_id": "abc123...",
27
+ "cwd": "/working/directory"
28
+ }
29
+
30
+ Output Format (stdout):
31
+ {
32
+ "action": "continue",
33
+ "tool_input": {
34
+ "file_path": "/path/to/file.py",
35
+ "old_string": "foo",
36
+ "new_string": "bar_modified"
37
+ }
38
+ }
39
+
40
+ Or to block execution:
41
+ {
42
+ "action": "block",
43
+ "message": "Reason for blocking"
44
+ }
45
+
46
+ Or to continue without modification:
47
+ {
48
+ "action": "continue"
49
+ }
50
+ """
51
+
52
+ import json
53
+ import os
54
+ import sys
55
+ from pathlib import Path
56
+ from typing import Any, Dict, Optional
57
+
58
+
59
+ class PreToolUseHook:
60
+ """Base class for PreToolUse hooks with input modification support."""
61
+
62
+ def __init__(self):
63
+ """Initialize the hook."""
64
+ self.debug = os.environ.get("CLAUDE_MPM_HOOK_DEBUG", "false").lower() == "true"
65
+
66
+ def log_debug(self, message: str) -> None:
67
+ """Log debug message to stderr."""
68
+ if self.debug:
69
+ print(f"[PreToolUse Hook] {message}", file=sys.stderr)
70
+
71
+ def read_event(self) -> Optional[Dict[str, Any]]:
72
+ """Read and parse the hook event from stdin."""
73
+ try:
74
+ event_data = sys.stdin.read()
75
+ if not event_data.strip():
76
+ return None
77
+ return json.loads(event_data)
78
+ except json.JSONDecodeError as e:
79
+ self.log_debug(f"Failed to parse event: {e}")
80
+ return None
81
+ except Exception as e:
82
+ self.log_debug(f"Error reading event: {e}")
83
+ return None
84
+
85
+ def continue_execution(
86
+ self, modified_input: Optional[Dict[str, Any]] = None
87
+ ) -> None:
88
+ """Continue execution with optional modified input."""
89
+ response = {"action": "continue"}
90
+ if modified_input is not None:
91
+ response["tool_input"] = modified_input
92
+ print(json.dumps(response))
93
+
94
+ def block_execution(self, message: str) -> None:
95
+ """Block execution with a message."""
96
+ response = {"action": "block", "message": message}
97
+ print(json.dumps(response))
98
+
99
+ def modify_input(
100
+ self, tool_name: str, tool_input: Dict[str, Any], event: Dict[str, Any]
101
+ ) -> Optional[Dict[str, Any]]:
102
+ """
103
+ Modify tool input before execution.
104
+
105
+ Override this method in subclasses to implement custom logic.
106
+
107
+ Args:
108
+ tool_name: Name of the tool being invoked
109
+ tool_input: Original tool input parameters
110
+ event: Full event data including session_id, cwd, etc.
111
+
112
+ Returns:
113
+ Modified tool input dict, or None to continue without modification
114
+ """
115
+ # Default: no modification
116
+ return None
117
+
118
+ def should_block(
119
+ self, tool_name: str, tool_input: Dict[str, Any], event: Dict[str, Any]
120
+ ) -> tuple[bool, str]:
121
+ """
122
+ Check if execution should be blocked.
123
+
124
+ Override this method in subclasses to implement validation logic.
125
+
126
+ Args:
127
+ tool_name: Name of the tool being invoked
128
+ tool_input: Original tool input parameters
129
+ event: Full event data including session_id, cwd, etc.
130
+
131
+ Returns:
132
+ Tuple of (should_block, reason)
133
+ """
134
+ # Default: don't block
135
+ return False, ""
136
+
137
+ def run(self) -> None:
138
+ """Main entry point for the hook."""
139
+ try:
140
+ # Read event from stdin
141
+ event = self.read_event()
142
+ if not event:
143
+ self.continue_execution()
144
+ return
145
+
146
+ tool_name = event.get("tool_name", "")
147
+ tool_input = event.get("tool_input", {})
148
+
149
+ self.log_debug(
150
+ f"Processing {tool_name} with input: {list(tool_input.keys())}"
151
+ )
152
+
153
+ # Check if execution should be blocked
154
+ should_block, reason = self.should_block(tool_name, tool_input, event)
155
+ if should_block:
156
+ self.log_debug(f"Blocking {tool_name}: {reason}")
157
+ self.block_execution(reason)
158
+ return
159
+
160
+ # Try to modify input
161
+ modified_input = self.modify_input(tool_name, tool_input, event)
162
+ if modified_input is not None:
163
+ self.log_debug(f"Modified {tool_name} input")
164
+ self.continue_execution(modified_input)
165
+ else:
166
+ self.log_debug(f"No modification for {tool_name}")
167
+ self.continue_execution()
168
+
169
+ except Exception as e:
170
+ self.log_debug(f"Hook error: {e}")
171
+ # Always continue on error to avoid blocking Claude
172
+ self.continue_execution()
173
+
174
+
175
+ # ============================================================================
176
+ # Example Implementations
177
+ # ============================================================================
178
+
179
+
180
+ class ContextInjectionHook(PreToolUseHook):
181
+ """
182
+ Example: Auto-inject project context into Read/Edit tool calls.
183
+
184
+ This hook adds project-specific context as comments to file operations.
185
+ """
186
+
187
+ def __init__(self):
188
+ super().__init__()
189
+ self.project_context = self._load_project_context()
190
+
191
+ def _load_project_context(self) -> str:
192
+ """Load project context from a file or environment."""
193
+ # Example: Load from .claude-context file
194
+ context_file = Path.cwd() / ".claude-context"
195
+ if context_file.exists():
196
+ return context_file.read_text()
197
+ return ""
198
+
199
+ def modify_input(
200
+ self, tool_name: str, tool_input: Dict[str, Any], event: Dict[str, Any]
201
+ ) -> Optional[Dict[str, Any]]:
202
+ """Inject context into Read operations."""
203
+ if tool_name == "Read" and self.project_context:
204
+ # Add context as a note (this is conceptual - actual implementation depends on use case)
205
+ modified = tool_input.copy()
206
+ # You could add context to a metadata field if the tool supports it
207
+ modified["_context"] = self.project_context[:200]
208
+ return modified
209
+ return None
210
+
211
+
212
+ class SecurityGuardHook(PreToolUseHook):
213
+ """
214
+ Example: Validate file paths before file operations.
215
+
216
+ This hook blocks operations on sensitive files or directories.
217
+ """
218
+
219
+ BLOCKED_PATHS = [
220
+ ".env",
221
+ "credentials.json",
222
+ "secrets/",
223
+ ".ssh/",
224
+ "id_rsa",
225
+ ]
226
+
227
+ def should_block(
228
+ self, tool_name: str, tool_input: Dict[str, Any], event: Dict[str, Any]
229
+ ) -> tuple[bool, str]:
230
+ """Block operations on sensitive files."""
231
+ if tool_name in ["Write", "Edit", "Read"]:
232
+ file_path = tool_input.get("file_path", "")
233
+ if any(blocked in file_path for blocked in self.BLOCKED_PATHS):
234
+ return True, f"Access to sensitive file blocked: {file_path}"
235
+ return False, ""
236
+
237
+
238
+ class LoggingHook(PreToolUseHook):
239
+ """
240
+ Example: Log all tool invocations before execution.
241
+
242
+ This hook logs tool calls to a file for debugging and audit purposes.
243
+ """
244
+
245
+ def __init__(self):
246
+ super().__init__()
247
+ self.log_file = Path.home() / ".claude-mpm" / "tool-calls.log"
248
+ self.log_file.parent.mkdir(exist_ok=True)
249
+
250
+ def modify_input(
251
+ self, tool_name: str, tool_input: Dict[str, Any], event: Dict[str, Any]
252
+ ) -> Optional[Dict[str, Any]]:
253
+ """Log the tool call."""
254
+ try:
255
+ from datetime import datetime, timezone
256
+
257
+ log_entry = {
258
+ "timestamp": datetime.now(timezone.utc).isoformat(),
259
+ "tool_name": tool_name,
260
+ "session_id": event.get("session_id", ""),
261
+ "cwd": event.get("cwd", ""),
262
+ "parameters": list(tool_input.keys()),
263
+ }
264
+ with self.log_file.open("a") as f:
265
+ f.write(json.dumps(log_entry) + "\n")
266
+ except Exception as e:
267
+ self.log_debug(f"Failed to log tool call: {e}")
268
+
269
+ # Don't modify input, just log
270
+ return None
271
+
272
+
273
+ class ParameterEnhancementHook(PreToolUseHook):
274
+ """
275
+ Example: Add default parameters to tool calls.
276
+
277
+ This hook adds default values to tool parameters if not provided.
278
+ """
279
+
280
+ def modify_input(
281
+ self, tool_name: str, tool_input: Dict[str, Any], event: Dict[str, Any]
282
+ ) -> Optional[Dict[str, Any]]:
283
+ """Add default parameters."""
284
+ modified = tool_input.copy()
285
+
286
+ if tool_name == "Bash":
287
+ # Add default timeout if not specified
288
+ if "timeout" not in modified:
289
+ modified["timeout"] = 30000 # 30 seconds
290
+ return modified
291
+
292
+ elif tool_name == "Grep":
293
+ # Add line numbers by default
294
+ if "-n" not in modified:
295
+ modified["-n"] = True
296
+ return modified
297
+
298
+ return None
299
+
300
+
301
+ # ============================================================================
302
+ # Main Entry Point
303
+ # ============================================================================
304
+
305
+
306
+ def main():
307
+ """Main entry point - choose which hook implementation to use."""
308
+ # Select which hook implementation to use
309
+ # Uncomment the one you want to use:
310
+
311
+ # hook = ContextInjectionHook()
312
+ # hook = SecurityGuardHook()
313
+ # hook = LoggingHook()
314
+ # hook = ParameterEnhancementHook()
315
+
316
+ # Default: use base hook (no modification)
317
+ hook = PreToolUseHook()
318
+
319
+ hook.run()
320
+
321
+
322
+ if __name__ == "__main__":
323
+ main()
@@ -0,0 +1,198 @@
1
+ """Git repository model for agent sources."""
2
+
3
+ from dataclasses import dataclass
4
+ from datetime import datetime
5
+ from pathlib import Path
6
+ from typing import Optional
7
+ from urllib.parse import urlparse
8
+
9
+
10
+ @dataclass
11
+ class GitRepository:
12
+ """Represents a Git repository configuration for agent sources.
13
+
14
+ This model tracks Git repositories that contain agent markdown files.
15
+ Repositories are cached locally and synced using ETag-based HTTP caching.
16
+
17
+ Attributes:
18
+ url: Full GitHub repository URL (e.g., https://github.com/owner/repo)
19
+ subdirectory: Optional subdirectory within repository (e.g., "agents/backend")
20
+ enabled: Whether this repository should be synced
21
+ priority: Priority for agent resolution (lower = higher precedence)
22
+ last_synced: Timestamp of last successful sync
23
+ etag: HTTP ETag from last sync for incremental updates
24
+ """
25
+
26
+ url: str
27
+ subdirectory: Optional[str] = None
28
+ enabled: bool = True
29
+ priority: int = 100
30
+ last_synced: Optional[datetime] = None
31
+ etag: Optional[str] = None
32
+
33
+ @property
34
+ def cache_path(self) -> Path:
35
+ """Return cache directory path for this repository.
36
+
37
+ Cache structure: ~/.claude-mpm/cache/remote-agents/{owner}/{repo}/{subdirectory}/
38
+
39
+ Returns:
40
+ Absolute path to cache directory for this repository
41
+
42
+ Example:
43
+ >>> repo = GitRepository(
44
+ ... url="https://github.com/bobmatnyc/claude-mpm-agents",
45
+ ... subdirectory="agents"
46
+ ... )
47
+ >>> repo.cache_path
48
+ Path('/Users/user/.claude-mpm/cache/remote-agents/bobmatnyc/claude-mpm-agents/agents')
49
+ """
50
+ home = Path.home()
51
+ base_cache = home / ".claude-mpm" / "cache" / "remote-agents"
52
+
53
+ # Extract owner and repo from URL
54
+ owner, repo = self._parse_github_url(self.url)
55
+
56
+ # Build cache path: base/owner/repo/subdirectory
57
+ cache_path = base_cache / owner / repo
58
+
59
+ if self.subdirectory:
60
+ # Normalize subdirectory path (remove leading/trailing slashes)
61
+ normalized_subdir = self.subdirectory.strip("/")
62
+ cache_path = cache_path / normalized_subdir
63
+
64
+ return cache_path
65
+
66
+ @property
67
+ def identifier(self) -> str:
68
+ """Return unique identifier for this repository.
69
+
70
+ Format: {owner}/{repo}/{subdirectory} or {owner}/{repo}
71
+
72
+ Returns:
73
+ Unique identifier string
74
+
75
+ Example:
76
+ >>> repo = GitRepository(
77
+ ... url="https://github.com/owner/repo",
78
+ ... subdirectory="agents"
79
+ ... )
80
+ >>> repo.identifier
81
+ 'owner/repo/agents'
82
+ """
83
+ owner, repo = self._parse_github_url(self.url)
84
+ base_id = f"{owner}/{repo}"
85
+
86
+ if self.subdirectory:
87
+ normalized_subdir = self.subdirectory.strip("/")
88
+ return f"{base_id}/{normalized_subdir}"
89
+
90
+ return base_id
91
+
92
+ def validate(self) -> list[str]:
93
+ """Validate repository configuration.
94
+
95
+ Returns:
96
+ List of validation error messages (empty if valid)
97
+
98
+ Validation checks:
99
+ - URL is not empty
100
+ - URL is valid HTTP/HTTPS format
101
+ - URL is a GitHub repository URL
102
+ - Priority is non-negative
103
+ - Priority is reasonable (<= 1000, warning only)
104
+ - Subdirectory is relative path (not absolute)
105
+ """
106
+ errors = []
107
+
108
+ # Validate URL
109
+ if not self.url or not self.url.strip():
110
+ errors.append("URL cannot be empty")
111
+ return errors # Can't continue validation without URL
112
+
113
+ # Check URL format
114
+ try:
115
+ parsed = urlparse(self.url)
116
+
117
+ # Must be HTTP or HTTPS
118
+ if parsed.scheme not in ("http", "https"):
119
+ errors.append(
120
+ f"URL must use http:// or https:// protocol, got: {parsed.scheme}"
121
+ )
122
+
123
+ # Must be GitHub (for now)
124
+ if not parsed.netloc.endswith("github.com"):
125
+ errors.append(f"URL must be a GitHub repository, got: {parsed.netloc}")
126
+
127
+ # Should have owner/repo path structure
128
+ path_parts = [p for p in parsed.path.strip("/").split("/") if p]
129
+ if len(path_parts) < 2:
130
+ errors.append(f"URL must include owner/repo path, got: {parsed.path}")
131
+
132
+ except Exception as e:
133
+ errors.append(f"Invalid URL format: {e}")
134
+
135
+ # Validate priority
136
+ if self.priority < 0:
137
+ errors.append("Priority must be non-negative (0 or greater)")
138
+
139
+ if self.priority > 1000:
140
+ errors.append(
141
+ f"Priority {self.priority} is unusually high (recommended: 0-1000). "
142
+ "Lower priority numbers have higher precedence."
143
+ )
144
+
145
+ # Validate subdirectory
146
+ if self.subdirectory:
147
+ # Must be relative path
148
+ if Path(self.subdirectory).is_absolute():
149
+ errors.append(
150
+ f"Subdirectory must be a relative path, got absolute: {self.subdirectory}"
151
+ )
152
+
153
+ # Should not start with slash
154
+ if self.subdirectory.startswith("/"):
155
+ errors.append(
156
+ f"Subdirectory should not start with '/', got: {self.subdirectory}"
157
+ )
158
+
159
+ return errors
160
+
161
+ def _parse_github_url(self, url: str) -> tuple[str, str]:
162
+ """Parse GitHub URL to extract owner and repository name.
163
+
164
+ Args:
165
+ url: GitHub repository URL
166
+
167
+ Returns:
168
+ Tuple of (owner, repository_name)
169
+
170
+ Example:
171
+ >>> repo = GitRepository(url="https://github.com/owner/repo")
172
+ >>> repo._parse_github_url(repo.url)
173
+ ('owner', 'repo')
174
+ """
175
+ # Remove .git suffix if present
176
+ url = url.rstrip("/")
177
+ if url.endswith(".git"):
178
+ url = url[:-4]
179
+
180
+ # Parse URL
181
+ parsed = urlparse(url)
182
+ path_parts = [p for p in parsed.path.strip("/").split("/") if p]
183
+
184
+ if len(path_parts) >= 2:
185
+ owner = path_parts[0]
186
+ repo = path_parts[1]
187
+ return owner, repo
188
+
189
+ # Fallback: Use URL as-is if parsing fails
190
+ # This will be caught by validation
191
+ return "unknown", "unknown"
192
+
193
+ def __repr__(self) -> str:
194
+ """Return string representation of repository."""
195
+ return (
196
+ f"GitRepository(identifier='{self.identifier}', "
197
+ f"priority={self.priority}, enabled={self.enabled})"
198
+ )
@@ -89,7 +89,7 @@ fi
89
89
  # STRATEGY:
90
90
  # This function implements a fallback chain to find Python with claude-mpm dependencies:
91
91
  # 1. Project-specific virtual environments (venv, .venv)
92
- # 2. Currently active virtual environment ($VIRTUAL_ENV)
92
+ # 2. Currently active virtual environment ($VIRTUAL_ENV)
93
93
  # 3. System python3 (may lack dependencies)
94
94
  # 4. System python (last resort)
95
95
  #
@@ -121,7 +121,7 @@ find_python_command() {
121
121
  return
122
122
  fi
123
123
  fi
124
-
124
+
125
125
  # 2. Check for project-local virtual environment (common in development)
126
126
  if [ -f "$CLAUDE_MPM_ROOT/venv/bin/activate" ]; then
127
127
  source "$CLAUDE_MPM_ROOT/venv/bin/activate"
@@ -152,7 +152,7 @@ if [[ "$SCRIPT_DIR" == *"/.local/pipx/venvs/claude-mpm/"* ]]; then
152
152
  elif [ -d "$CLAUDE_MPM_ROOT/src" ]; then
153
153
  # Development install - add src to PYTHONPATH
154
154
  export PYTHONPATH="$CLAUDE_MPM_ROOT/src:$PYTHONPATH"
155
-
155
+
156
156
  if [ "${CLAUDE_MPM_HOOK_DEBUG}" = "true" ]; then
157
157
  echo "[$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)] Development environment detected" >> /tmp/claude-mpm-hook.log
158
158
  fi
@@ -51,7 +51,9 @@ if __name__ == "__main__":
51
51
 
52
52
  # Initialize aggregator
53
53
  aggregator = EventAggregator(
54
- host="localhost", port=dashboard_port, save_dir=None # Will use config value
54
+ host="localhost",
55
+ port=dashboard_port,
56
+ save_dir=None, # Will use config value
55
57
  )
56
58
 
57
59
  # Set up signal handlers
@@ -8,12 +8,13 @@ This service provides comprehensive agent lifecycle management including:
8
8
  - Integration with deployment services
9
9
  """
10
10
 
11
- import json
12
11
  import re
13
12
  from datetime import datetime, timezone
14
13
  from pathlib import Path
15
14
  from typing import Any, ClassVar, Dict, List, Optional, Tuple
16
15
 
16
+ import yaml
17
+
17
18
  from claude_mpm.core.exceptions import AgentDeploymentError
18
19
  from claude_mpm.core.logging_config import get_logger
19
20
 
@@ -285,10 +286,15 @@ class AgentBuilderService:
285
286
  if not self.templates_dir.exists():
286
287
  return templates
287
288
 
288
- for template_file in self.templates_dir.glob("*.json"):
289
+ # Agent templates migrated to Markdown with YAML frontmatter (v4.26.0+)
290
+ for template_file in self.templates_dir.glob("*.md"):
289
291
  try:
290
- with template_file.open() as f:
291
- config = json.load(f)
292
+ # Read markdown content and extract YAML frontmatter
293
+ content = template_file.read_text()
294
+ config = self._extract_yaml_frontmatter(content)
295
+ if not config:
296
+ self.logger.warning(f"No YAML frontmatter in {template_file.name}")
297
+ continue
292
298
 
293
299
  # Use filename stem as ID if not specified in config
294
300
  template_id = config.get("id") or template_file.stem
@@ -308,6 +314,30 @@ class AgentBuilderService:
308
314
 
309
315
  return templates
310
316
 
317
+ def _extract_yaml_frontmatter(self, content: str) -> Optional[Dict[str, Any]]:
318
+ """
319
+ Extract and parse YAML frontmatter from markdown content.
320
+
321
+ Args:
322
+ content: File content to parse
323
+
324
+ Returns:
325
+ Parsed YAML frontmatter as dict, or None if not found/invalid
326
+ """
327
+ if not content.strip().startswith("---"):
328
+ return None
329
+
330
+ # Split on --- delimiters
331
+ parts = content.split("---", 2)
332
+ if len(parts) < 3:
333
+ return None
334
+
335
+ try:
336
+ return yaml.safe_load(parts[1])
337
+ except yaml.YAMLError as e:
338
+ self.logger.warning(f"Failed to parse YAML frontmatter: {e}")
339
+ return None
340
+
311
341
  def _validate_agent_id(self, agent_id: str) -> None:
312
342
  """Validate agent ID format.
313
343
 
@@ -371,16 +401,22 @@ class AgentBuilderService:
371
401
  if template_id in self._template_cache:
372
402
  return self._template_cache[template_id].copy()
373
403
 
374
- template_file = self.templates_dir / f"{template_id}.json"
404
+ # Agent templates migrated to Markdown with YAML frontmatter (v4.26.0+)
405
+ template_file = self.templates_dir / f"{template_id}.md"
375
406
 
376
407
  if not template_file.exists():
377
408
  raise AgentDeploymentError(f"Template '{template_id}' not found")
378
409
 
379
410
  try:
380
- with template_file.open() as f:
381
- config = json.load(f)
382
- self._template_cache[template_id] = config
383
- return config.copy()
411
+ # Read markdown content and extract YAML frontmatter
412
+ content = template_file.read_text()
413
+ config = self._extract_yaml_frontmatter(content)
414
+ if not config:
415
+ raise AgentDeploymentError(
416
+ f"No YAML frontmatter in template '{template_id}'"
417
+ )
418
+ self._template_cache[template_id] = config
419
+ return config.copy()
384
420
  except Exception as e:
385
421
  raise AgentDeploymentError(
386
422
  f"Failed to load template '{template_id}': {e}"