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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (484) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_PM.md +12 -0
  3. claude_mpm/agents/OUTPUT_STYLE.md +3 -48
  4. claude_mpm/agents/PM_INSTRUCTIONS.md +632 -334
  5. claude_mpm/agents/WORKFLOW.md +75 -2
  6. claude_mpm/agents/__init__.py +6 -0
  7. claude_mpm/agents/agent_loader.py +1 -4
  8. claude_mpm/agents/base_agent.json +6 -3
  9. claude_mpm/agents/frontmatter_validator.py +1 -1
  10. claude_mpm/agents/templates/{circuit_breakers.md → circuit-breakers.md} +370 -3
  11. claude_mpm/agents/templates/context-management-examples.md +544 -0
  12. claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +89 -19
  13. claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
  14. claude_mpm/agents/templates/research-gate-examples.md +669 -0
  15. claude_mpm/agents/templates/structured-questions-examples.md +615 -0
  16. claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
  17. claude_mpm/agents/templates/ticketing-examples.md +277 -0
  18. claude_mpm/cli/__init__.py +38 -2
  19. claude_mpm/cli/commands/agent_source.py +774 -0
  20. claude_mpm/cli/commands/agent_state_manager.py +125 -20
  21. claude_mpm/cli/commands/agents.py +684 -13
  22. claude_mpm/cli/commands/agents_cleanup.py +210 -0
  23. claude_mpm/cli/commands/agents_discover.py +338 -0
  24. claude_mpm/cli/commands/aggregate.py +1 -1
  25. claude_mpm/cli/commands/analyze.py +3 -3
  26. claude_mpm/cli/commands/auto_configure.py +2 -6
  27. claude_mpm/cli/commands/cleanup.py +1 -1
  28. claude_mpm/cli/commands/config.py +7 -4
  29. claude_mpm/cli/commands/configure.py +478 -44
  30. claude_mpm/cli/commands/configure_agent_display.py +4 -4
  31. claude_mpm/cli/commands/configure_navigation.py +63 -46
  32. claude_mpm/cli/commands/debug.py +12 -12
  33. claude_mpm/cli/commands/doctor.py +10 -2
  34. claude_mpm/cli/commands/hook_errors.py +277 -0
  35. claude_mpm/cli/commands/local_deploy.py +1 -4
  36. claude_mpm/cli/commands/mcp_install_commands.py +1 -1
  37. claude_mpm/cli/commands/mpm_init/core.py +50 -2
  38. claude_mpm/cli/commands/mpm_init/git_activity.py +10 -10
  39. claude_mpm/cli/commands/mpm_init/prompts.py +6 -6
  40. claude_mpm/cli/commands/run.py +124 -128
  41. claude_mpm/cli/commands/skill_source.py +694 -0
  42. claude_mpm/cli/commands/skills.py +435 -1
  43. claude_mpm/cli/executor.py +78 -3
  44. claude_mpm/cli/interactive/agent_wizard.py +919 -41
  45. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  46. claude_mpm/cli/parsers/agents_parser.py +173 -4
  47. claude_mpm/cli/parsers/base_parser.py +49 -0
  48. claude_mpm/cli/parsers/config_parser.py +96 -43
  49. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  50. claude_mpm/cli/parsers/skills_parser.py +138 -0
  51. claude_mpm/cli/parsers/source_parser.py +138 -0
  52. claude_mpm/cli/startup.py +499 -84
  53. claude_mpm/cli/startup_display.py +480 -0
  54. claude_mpm/cli/utils.py +1 -1
  55. claude_mpm/cli_module/commands.py +1 -1
  56. claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
  57. claude_mpm/commands/mpm-agents-detect.md +9 -0
  58. claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
  59. claude_mpm/commands/mpm-agents-recommend.md +9 -0
  60. claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
  61. claude_mpm/commands/mpm-doctor.md +9 -0
  62. claude_mpm/commands/mpm-help.md +11 -2
  63. claude_mpm/commands/mpm-init.md +27 -2
  64. claude_mpm/commands/mpm-monitor.md +9 -0
  65. claude_mpm/commands/{mpm-resume.md → mpm-session-resume.md} +9 -0
  66. claude_mpm/commands/mpm-status.md +9 -0
  67. claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
  68. claude_mpm/commands/mpm-ticket-view.md +552 -0
  69. claude_mpm/commands/mpm-version.md +9 -0
  70. claude_mpm/commands/mpm.md +10 -0
  71. claude_mpm/config/agent_presets.py +258 -0
  72. claude_mpm/config/agent_sources.py +325 -0
  73. claude_mpm/config/skill_sources.py +590 -0
  74. claude_mpm/constants.py +12 -0
  75. claude_mpm/core/api_validator.py +1 -1
  76. claude_mpm/core/claude_runner.py +17 -10
  77. claude_mpm/core/config.py +24 -0
  78. claude_mpm/core/constants.py +1 -1
  79. claude_mpm/core/framework/__init__.py +3 -16
  80. claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
  81. claude_mpm/core/framework/processors/metadata_processor.py +1 -1
  82. claude_mpm/core/hook_error_memory.py +381 -0
  83. claude_mpm/core/hook_manager.py +41 -2
  84. claude_mpm/core/interactive_session.py +112 -5
  85. claude_mpm/core/logger.py +3 -1
  86. claude_mpm/core/oneshot_session.py +94 -4
  87. claude_mpm/dashboard/static/css/activity.css +69 -69
  88. claude_mpm/dashboard/static/css/connection-status.css +10 -10
  89. claude_mpm/dashboard/static/css/dashboard.css +15 -15
  90. claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
  91. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
  92. claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
  93. claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
  94. claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
  95. claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
  96. claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
  97. claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
  98. claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
  99. claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
  100. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
  101. claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
  102. claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
  103. claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
  104. claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
  105. claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
  106. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
  107. claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
  108. claude_mpm/dashboard/static/js/connection-manager.js +76 -76
  109. claude_mpm/dashboard/static/js/dashboard.js +76 -58
  110. claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
  111. claude_mpm/dashboard/static/js/socket-client.js +138 -121
  112. claude_mpm/dashboard/templates/code_simple.html +23 -23
  113. claude_mpm/dashboard/templates/index.html +18 -18
  114. claude_mpm/experimental/cli_enhancements.py +1 -5
  115. claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
  116. claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
  117. claude_mpm/hooks/claude_hooks/installer.py +45 -0
  118. claude_mpm/hooks/failure_learning/__init__.py +2 -8
  119. claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
  120. claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
  121. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
  122. claude_mpm/hooks/kuzu_response_hook.py +1 -5
  123. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  124. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  125. claude_mpm/models/git_repository.py +198 -0
  126. claude_mpm/scripts/claude-hook-handler.sh +3 -3
  127. claude_mpm/scripts/start_activity_logging.py +3 -1
  128. claude_mpm/services/agents/agent_builder.py +45 -9
  129. claude_mpm/services/agents/agent_preset_service.py +238 -0
  130. claude_mpm/services/agents/agent_selection_service.py +484 -0
  131. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  132. claude_mpm/services/agents/deployment/agent_deployment.py +126 -2
  133. claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
  134. claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
  135. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
  136. claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
  137. claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
  138. claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
  139. claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
  140. claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
  141. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
  142. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +115 -15
  143. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
  144. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
  145. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +363 -0
  146. claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
  147. claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
  148. claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
  149. claude_mpm/services/agents/git_source_manager.py +629 -0
  150. claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
  151. claude_mpm/services/agents/local_template_manager.py +50 -10
  152. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  153. claude_mpm/services/agents/sources/__init__.py +13 -0
  154. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  155. claude_mpm/services/agents/sources/git_source_sync_service.py +1055 -0
  156. claude_mpm/services/agents/startup_sync.py +239 -0
  157. claude_mpm/services/agents/toolchain_detector.py +474 -0
  158. claude_mpm/services/cli/session_pause_manager.py +1 -1
  159. claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
  160. claude_mpm/services/command_deployment_service.py +92 -1
  161. claude_mpm/services/core/interfaces/__init__.py +1 -3
  162. claude_mpm/services/core/interfaces/health.py +1 -4
  163. claude_mpm/services/core/models/__init__.py +2 -11
  164. claude_mpm/services/diagnostics/checks/__init__.py +4 -0
  165. claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
  166. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  167. claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
  168. claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
  169. claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
  170. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  171. claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
  172. claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
  173. claude_mpm/services/event_bus/direct_relay.py +3 -3
  174. claude_mpm/services/event_bus/event_bus.py +36 -3
  175. claude_mpm/services/events/consumers/logging.py +1 -2
  176. claude_mpm/services/git/__init__.py +21 -0
  177. claude_mpm/services/git/git_operations_service.py +494 -0
  178. claude_mpm/services/github/__init__.py +21 -0
  179. claude_mpm/services/github/github_cli_service.py +397 -0
  180. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
  181. claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
  182. claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
  183. claude_mpm/services/instructions/__init__.py +9 -0
  184. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  185. claude_mpm/services/local_ops/__init__.py +3 -13
  186. claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
  187. claude_mpm/services/local_ops/health_manager.py +1 -4
  188. claude_mpm/services/local_ops/process_manager.py +1 -1
  189. claude_mpm/services/local_ops/resource_monitor.py +2 -2
  190. claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
  191. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
  192. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
  193. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
  194. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
  195. claude_mpm/services/memory/optimizer.py +1 -1
  196. claude_mpm/services/model/model_router.py +8 -9
  197. claude_mpm/services/monitor/daemon.py +1 -1
  198. claude_mpm/services/monitor/server.py +2 -2
  199. claude_mpm/services/native_agent_converter.py +356 -0
  200. claude_mpm/services/port_manager.py +1 -1
  201. claude_mpm/services/pr/__init__.py +14 -0
  202. claude_mpm/services/pr/pr_template_service.py +329 -0
  203. claude_mpm/services/project/documentation_manager.py +2 -1
  204. claude_mpm/services/project/toolchain_analyzer.py +3 -1
  205. claude_mpm/services/runner_configuration_service.py +1 -0
  206. claude_mpm/services/self_upgrade_service.py +165 -7
  207. claude_mpm/services/skills/__init__.py +18 -0
  208. claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
  209. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  210. claude_mpm/services/skills_config.py +547 -0
  211. claude_mpm/services/skills_deployer.py +955 -0
  212. claude_mpm/services/socketio/handlers/connection.py +1 -1
  213. claude_mpm/services/socketio/handlers/git.py +2 -2
  214. claude_mpm/services/socketio/server/core.py +1 -4
  215. claude_mpm/services/socketio/server/main.py +1 -3
  216. claude_mpm/services/system_instructions_service.py +1 -3
  217. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
  218. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
  219. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
  220. claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
  221. claude_mpm/services/unified/unified_deployment.py +1 -5
  222. claude_mpm/services/version_control/conflict_resolution.py +6 -4
  223. claude_mpm/services/visualization/__init__.py +1 -5
  224. claude_mpm/services/visualization/mermaid_generator.py +2 -3
  225. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  226. claude_mpm/skills/bundled/performance-profiling.md +6 -0
  227. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +2 -2
  228. claude_mpm/skills/skills_registry.py +0 -1
  229. claude_mpm/templates/questions/__init__.py +38 -0
  230. claude_mpm/templates/questions/base.py +193 -0
  231. claude_mpm/templates/questions/pr_strategy.py +311 -0
  232. claude_mpm/templates/questions/project_init.py +385 -0
  233. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  234. claude_mpm/tools/__main__.py +8 -8
  235. claude_mpm/tools/code_tree_analyzer/analysis.py +1 -1
  236. claude_mpm/utils/agent_dependency_loader.py +80 -13
  237. claude_mpm/utils/dependency_cache.py +3 -1
  238. claude_mpm/utils/gitignore.py +241 -0
  239. claude_mpm/utils/log_cleanup.py +3 -3
  240. claude_mpm/utils/progress.py +383 -0
  241. claude_mpm/utils/robust_installer.py +3 -5
  242. claude_mpm/utils/structured_questions.py +619 -0
  243. {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/METADATA +429 -59
  244. {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/RECORD +252 -425
  245. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
  246. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
  247. claude_mpm/agents/templates/agent-manager.json +0 -273
  248. claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
  249. claude_mpm/agents/templates/api_qa.json +0 -180
  250. claude_mpm/agents/templates/clerk-ops.json +0 -235
  251. claude_mpm/agents/templates/code_analyzer.json +0 -101
  252. claude_mpm/agents/templates/content-agent.json +0 -358
  253. claude_mpm/agents/templates/dart_engineer.json +0 -307
  254. claude_mpm/agents/templates/data_engineer.json +0 -225
  255. claude_mpm/agents/templates/documentation.json +0 -211
  256. claude_mpm/agents/templates/engineer.json +0 -210
  257. claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
  258. claude_mpm/agents/templates/golang_engineer.json +0 -270
  259. claude_mpm/agents/templates/imagemagick.json +0 -264
  260. claude_mpm/agents/templates/java_engineer.json +0 -346
  261. claude_mpm/agents/templates/local_ops_agent.json +0 -1840
  262. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
  263. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
  264. claude_mpm/agents/templates/memory_manager.json +0 -158
  265. claude_mpm/agents/templates/nextjs_engineer.json +0 -285
  266. claude_mpm/agents/templates/ops.json +0 -185
  267. claude_mpm/agents/templates/php-engineer.json +0 -287
  268. claude_mpm/agents/templates/product_owner.json +0 -338
  269. claude_mpm/agents/templates/project_organizer.json +0 -140
  270. claude_mpm/agents/templates/prompt-engineer.json +0 -737
  271. claude_mpm/agents/templates/python_engineer.json +0 -387
  272. claude_mpm/agents/templates/qa.json +0 -242
  273. claude_mpm/agents/templates/react_engineer.json +0 -238
  274. claude_mpm/agents/templates/refactoring_engineer.json +0 -276
  275. claude_mpm/agents/templates/research.json +0 -188
  276. claude_mpm/agents/templates/ruby-engineer.json +0 -280
  277. claude_mpm/agents/templates/rust_engineer.json +0 -275
  278. claude_mpm/agents/templates/security.json +0 -202
  279. claude_mpm/agents/templates/svelte-engineer.json +0 -225
  280. claude_mpm/agents/templates/ticketing.json +0 -177
  281. claude_mpm/agents/templates/typescript_engineer.json +0 -285
  282. claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
  283. claude_mpm/agents/templates/version_control.json +0 -157
  284. claude_mpm/agents/templates/web_qa.json +0 -399
  285. claude_mpm/agents/templates/web_ui.json +0 -189
  286. claude_mpm/commands/mpm-tickets.md +0 -102
  287. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
  288. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
  289. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
  290. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
  291. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
  292. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
  293. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
  294. claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
  295. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
  296. claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
  297. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
  298. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
  299. claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
  300. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
  301. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
  302. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
  303. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
  304. claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
  305. claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
  306. claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
  307. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
  308. claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
  309. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
  310. claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
  311. claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
  312. claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
  313. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
  314. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
  315. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
  316. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
  317. claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
  318. claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
  319. claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
  320. claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
  321. claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
  322. claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
  323. claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
  324. claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
  325. claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
  326. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
  327. claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
  328. claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
  329. claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
  330. claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
  331. claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
  332. claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
  333. claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
  334. claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
  335. claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
  336. claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
  337. claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
  338. claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
  339. claude_mpm/dashboard/static/built/connection-manager.js +0 -536
  340. claude_mpm/dashboard/static/built/dashboard.js +0 -2
  341. claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
  342. claude_mpm/dashboard/static/built/react/events.js +0 -30
  343. claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
  344. claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
  345. claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
  346. claude_mpm/dashboard/static/built/shared/logger.js +0 -385
  347. claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
  348. claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
  349. claude_mpm/dashboard/static/built/socket-client.js +0 -2
  350. claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
  351. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
  352. claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
  353. claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
  354. claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
  355. claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
  356. claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
  357. claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
  358. claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
  359. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
  360. claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
  361. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
  362. claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
  363. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
  364. claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
  365. claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
  366. claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
  367. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
  368. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
  369. claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
  370. claude_mpm/dashboard/static/dist/dashboard.js +0 -2
  371. claude_mpm/dashboard/static/dist/react/events.js +0 -30
  372. claude_mpm/dashboard/static/dist/socket-client.js +0 -2
  373. claude_mpm/dashboard/static/events.html +0 -607
  374. claude_mpm/dashboard/static/index.html +0 -635
  375. claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
  376. claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
  377. claude_mpm/dashboard/static/js/shared/logger.js +0 -385
  378. claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
  379. claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
  380. claude_mpm/dashboard/static/legacy/activity.html +0 -736
  381. claude_mpm/dashboard/static/legacy/agents.html +0 -786
  382. claude_mpm/dashboard/static/legacy/files.html +0 -747
  383. claude_mpm/dashboard/static/legacy/tools.html +0 -831
  384. claude_mpm/dashboard/static/monitors.html +0 -431
  385. claude_mpm/dashboard/static/production/events.html +0 -659
  386. claude_mpm/dashboard/static/production/main.html +0 -698
  387. claude_mpm/dashboard/static/production/monitors.html +0 -483
  388. claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
  389. claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
  390. claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
  391. claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
  392. claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
  393. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -79
  394. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -178
  395. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +0 -577
  396. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +0 -467
  397. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +0 -537
  398. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +0 -730
  399. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -112
  400. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +0 -146
  401. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +0 -412
  402. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -81
  403. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +0 -362
  404. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +0 -312
  405. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -152
  406. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +0 -668
  407. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +0 -587
  408. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +0 -438
  409. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +0 -391
  410. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
  411. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
  412. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
  413. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
  414. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
  415. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
  416. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
  417. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
  418. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
  419. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
  420. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -131
  421. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -325
  422. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +0 -490
  423. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +0 -425
  424. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -499
  425. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -86
  426. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -43
  427. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
  428. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
  429. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
  430. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
  431. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -160
  432. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +0 -412
  433. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
  434. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
  435. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
  436. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
  437. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +0 -1237
  438. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -189
  439. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +0 -500
  440. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +0 -464
  441. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +0 -619
  442. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +0 -437
  443. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +0 -231
  444. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +0 -170
  445. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +0 -602
  446. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +0 -821
  447. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +0 -742
  448. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +0 -726
  449. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +0 -764
  450. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +0 -831
  451. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +0 -226
  452. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +0 -901
  453. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +0 -901
  454. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +0 -775
  455. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +0 -937
  456. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +0 -770
  457. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +0 -961
  458. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -119
  459. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +0 -253
  460. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
  461. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
  462. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
  463. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
  464. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
  465. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
  466. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -140
  467. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +0 -572
  468. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +0 -411
  469. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +0 -569
  470. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +0 -695
  471. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -184
  472. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +0 -459
  473. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +0 -479
  474. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +0 -687
  475. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +0 -758
  476. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +0 -868
  477. /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
  478. /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
  479. /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
  480. /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
  481. {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/WHEEL +0 -0
  482. {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/entry_points.txt +0 -0
  483. {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/licenses/LICENSE +0 -0
  484. {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/top_level.txt +0 -0
@@ -1,602 +0,0 @@
1
- # EspoCRM Architecture Reference
2
-
3
- ## Metadata-Driven Architecture
4
-
5
- EspoCRM's core architecture is built on metadata - JSON configuration files that define entities, fields, relationships, and behaviors.
6
-
7
- ### Metadata Structure
8
-
9
- Metadata lives in several locations with a priority order:
10
-
11
- ```
12
- 1. custom/Espo/Custom/Resources/metadata/ (highest priority)
13
- 2. custom/Espo/Modules/{ModuleName}/Resources/metadata/
14
- 3. application/Espo/Modules/{ModuleName}/Resources/metadata/
15
- 4. application/Espo/Resources/metadata/ (lowest priority)
16
- ```
17
-
18
- ### Key Metadata Types
19
-
20
- **Entity Definitions** (`entityDefs/{EntityType}.json`):
21
- ```json
22
- {
23
- "fields": {
24
- "name": {
25
- "type": "varchar",
26
- "required": true,
27
- "maxLength": 255
28
- },
29
- "status": {
30
- "type": "enum",
31
- "options": ["New", "In Progress", "Complete"],
32
- "default": "New"
33
- }
34
- },
35
- "links": {
36
- "account": {
37
- "type": "belongsTo",
38
- "entity": "Account",
39
- "foreign": "contacts"
40
- }
41
- }
42
- }
43
- ```
44
-
45
- **Client Definitions** (`clientDefs/{EntityType}.json`):
46
- ```json
47
- {
48
- "controller": "custom:controllers/my-entity",
49
- "views": {
50
- "detail": "custom:views/my-entity/detail"
51
- },
52
- "recordViews": {
53
- "detail": "custom:views/my-entity/record/detail"
54
- },
55
- "sidePanels": {
56
- "detail": [
57
- {
58
- "name": "activities",
59
- "label": "Activities",
60
- "view": "crm:views/record/panels/activities"
61
- }
62
- ]
63
- }
64
- }
65
- ```
66
-
67
- **Scopes** (`scopes/{EntityType}.json`):
68
- ```json
69
- {
70
- "entity": true,
71
- "object": true,
72
- "layouts": true,
73
- "tab": true,
74
- "acl": true,
75
- "module": "MyModule",
76
- "stream": true
77
- }
78
- ```
79
-
80
- ### Metadata Access in Code
81
-
82
- ```php
83
- use Espo\Core\Utils\Metadata;
84
-
85
- class MyService {
86
- public function __construct(private Metadata $metadata) {}
87
-
88
- public function getEntityFields(string $entityType): array {
89
- return $this->metadata->get(['entityDefs', $entityType, 'fields']) ?? [];
90
- }
91
-
92
- public function isFieldRequired(string $entityType, string $field): bool {
93
- return $this->metadata
94
- ->get(['entityDefs', $entityType, 'fields', $field, 'required']) ?? false;
95
- }
96
- }
97
- ```
98
-
99
- ## ORM EntityManager
100
-
101
- EntityManager is the central access point for ALL database operations in EspoCRM.
102
-
103
- ### Core EntityManager Methods
104
-
105
- ```php
106
- use Espo\ORM\EntityManager;
107
-
108
- class DataService {
109
- public function __construct(private EntityManager $entityManager) {}
110
-
111
- // Get entity by ID
112
- public function getById(string $entityType, string $id): ?Entity {
113
- return $this->entityManager->getEntityById($entityType, $id);
114
- }
115
-
116
- // Create new entity
117
- public function create(string $entityType): Entity {
118
- return $this->entityManager->getNewEntity($entityType);
119
- }
120
-
121
- // Save entity
122
- public function save(Entity $entity): void {
123
- $this->entityManager->saveEntity($entity);
124
- }
125
-
126
- // Delete entity
127
- public function delete(Entity $entity): void {
128
- $this->entityManager->removeEntity($entity);
129
- }
130
-
131
- // Get repository
132
- public function getRepository(string $entityType): RDBRepository {
133
- return $this->entityManager->getRDBRepository($entityType);
134
- }
135
- }
136
- ```
137
-
138
- ### Repository Pattern
139
-
140
- Never access repositories directly - always through EntityManager:
141
-
142
- ```php
143
- // Query with conditions
144
- $contacts = $this->entityManager
145
- ->getRDBRepository('Contact')
146
- ->where([
147
- 'accountId' => $accountId,
148
- 'deleted' => false
149
- ])
150
- ->find();
151
-
152
- // Complex queries
153
- $query = $this->entityManager
154
- ->getQueryBuilder()
155
- ->select()
156
- ->from('Opportunity')
157
- ->where([
158
- 'stage' => ['Proposal', 'Negotiation'],
159
- 'amount>=' => 10000
160
- ])
161
- ->order('createdAt', 'DESC')
162
- ->build();
163
-
164
- $collection = $this->entityManager
165
- ->getRDBRepository('Opportunity')
166
- ->clone($query)
167
- ->find();
168
- ```
169
-
170
- ### Transaction Handling
171
-
172
- ```php
173
- use Espo\ORM\TransactionManager;
174
-
175
- class TransactionalService {
176
- public function __construct(
177
- private EntityManager $entityManager,
178
- private TransactionManager $transactionManager
179
- ) {}
180
-
181
- public function performComplexOperation(): void {
182
- $this->transactionManager->run(function () {
183
- // All operations within this closure are transactional
184
- $entity1 = $this->entityManager->getNewEntity('Account');
185
- $entity1->set('name', 'Test');
186
- $this->entityManager->saveEntity($entity1);
187
-
188
- $entity2 = $this->entityManager->getNewEntity('Contact');
189
- $entity2->set('accountId', $entity1->getId());
190
- $this->entityManager->saveEntity($entity2);
191
-
192
- // If any exception is thrown, all changes are rolled back
193
- });
194
- }
195
- }
196
- ```
197
-
198
- ### STH Collections for Large Datasets
199
-
200
- For operations on large datasets, use STH (Statement Handle) collections to avoid memory issues:
201
-
202
- ```php
203
- $sthCollection = $this->entityManager
204
- ->getRDBRepository('Contact')
205
- ->sth() // Returns STH collection instead of loading all into memory
206
- ->where(['accountId' => $accountId])
207
- ->find();
208
-
209
- foreach ($sthCollection as $contact) {
210
- // Process one at a time
211
- $contact->set('status', 'Active');
212
- $this->entityManager->saveEntity($contact);
213
- }
214
- ```
215
-
216
- ## Dependency Injection Container
217
-
218
- EspoCRM uses a DI container for dependency management.
219
-
220
- ### Constructor Injection (CORRECT)
221
-
222
- ```php
223
- namespace Espo\Modules\MyModule\Services;
224
-
225
- use Espo\ORM\EntityManager;
226
- use Espo\Core\Utils\Metadata;
227
- use Espo\Core\Mail\EmailSender;
228
-
229
- class MyService {
230
- public function __construct(
231
- private EntityManager $entityManager,
232
- private Metadata $metadata,
233
- private EmailSender $emailSender
234
- ) {}
235
- }
236
- ```
237
-
238
- ### NEVER Pass Container
239
-
240
- ```php
241
- // ❌ WRONG - Never do this
242
- use Espo\Core\Container;
243
-
244
- class BadService {
245
- public function __construct(private Container $container) {}
246
- }
247
-
248
- // ✅ CORRECT - Inject specific dependencies
249
- class GoodService {
250
- public function __construct(
251
- private EntityManager $entityManager,
252
- private Metadata $metadata
253
- ) {}
254
- }
255
- ```
256
-
257
- ### Injectable Services
258
-
259
- Common services available for injection:
260
-
261
- - `EntityManager` - ORM access
262
- - `Metadata` - Metadata access
263
- - `Config` - Application configuration
264
- - `FileStorageManager` - File operations
265
- - `InjectableFactory` - Create objects with DI
266
- - `ServiceFactory` - Access record services
267
- - `EmailSender` - Send emails
268
- - `Acl` - Access control
269
- - `User` - Current user
270
- - `DateTime` - Date/time utilities
271
- - `Language` - Translations
272
- - `TransactionManager` - Database transactions
273
-
274
- ## Service Layer Architecture
275
-
276
- Business logic belongs in Service classes, not hooks or controllers.
277
-
278
- ### Service Hierarchy
279
-
280
- ```
281
- Record Service (base for all entity services)
282
-
283
- Custom Service (your entity-specific logic)
284
- ```
285
-
286
- ### Extending Record Service
287
-
288
- ```php
289
- namespace Espo\Modules\MyModule\Services;
290
-
291
- use Espo\Services\Record;
292
- use Espo\ORM\Entity;
293
-
294
- class Opportunity extends Record {
295
- // Override to add custom logic before create
296
- protected function beforeCreateEntity(Entity $entity, array $data): void {
297
- parent::beforeCreateEntity($entity, $data);
298
-
299
- // Custom logic
300
- if ($entity->get('amount') > 100000) {
301
- $entity->set('priority', 'High');
302
- }
303
- }
304
-
305
- // Custom action
306
- public function markAsWon(string $id): Entity {
307
- $entity = $this->getEntity($id);
308
-
309
- if (!$entity) {
310
- throw new NotFound();
311
- }
312
-
313
- $entity->set('stage', 'Closed Won');
314
- $this->entityManager->saveEntity($entity);
315
-
316
- // Trigger additional business logic
317
- $this->createWinNotification($entity);
318
-
319
- return $entity;
320
- }
321
-
322
- private function createWinNotification(Entity $opportunity): void {
323
- // Implementation
324
- }
325
- }
326
- ```
327
-
328
- ### Service Access
329
-
330
- ```php
331
- use Espo\Core\ServiceFactory;
332
-
333
- class MyClass {
334
- public function __construct(private ServiceFactory $serviceFactory) {}
335
-
336
- public function useService(): void {
337
- $opportunityService = $this->serviceFactory->create('Opportunity');
338
- $opportunityService->markAsWon($id);
339
- }
340
- }
341
- ```
342
-
343
- ## Hook System Architecture
344
-
345
- Hooks are for lifecycle events - validation and side effects ONLY. Business logic belongs in Services.
346
-
347
- ### The 7 Hook Interfaces
348
-
349
- ```php
350
- namespace Espo\Core\Hook\Hook;
351
-
352
- interface BeforeSave {
353
- public function beforeSave(Entity $entity, array $options): void;
354
- }
355
-
356
- interface AfterSave {
357
- public function afterSave(Entity $entity, array $options): void;
358
- }
359
-
360
- interface BeforeRemove {
361
- public function beforeRemove(Entity $entity, array $options): void;
362
- }
363
-
364
- interface AfterRemove {
365
- public function afterRemove(Entity $entity, array $options): void;
366
- }
367
-
368
- interface AfterRelate {
369
- public function afterRelate(Entity $entity, string $relationName, Entity $foreign, ?array $columnData, array $options): void;
370
- }
371
-
372
- interface AfterUnrelate {
373
- public function afterUnrelate(Entity $entity, string $relationName, Entity $foreign, array $options): void;
374
- }
375
-
376
- interface AfterMassRelate {
377
- public function afterMassRelate(Entity $entity, string $relationName, array $params, array $options): void;
378
- }
379
- ```
380
-
381
- ### Hook Implementation Example
382
-
383
- ```php
384
- namespace Espo\Modules\MyModule\Hooks\Account;
385
-
386
- use Espo\ORM\Entity;
387
- use Espo\Core\Hook\Hook\BeforeSave;
388
- use Espo\Core\ServiceFactory;
389
-
390
- class ValidateWebsite implements BeforeSave {
391
- public function __construct(private ServiceFactory $serviceFactory) {}
392
-
393
- public function beforeSave(Entity $entity, array $options): void {
394
- // Validation only
395
- if ($entity->isAttributeChanged('website')) {
396
- $website = $entity->get('website');
397
- if ($website && !filter_var($website, FILTER_VALIDATE_URL)) {
398
- throw new \Espo\Core\Exceptions\BadRequest('Invalid website URL');
399
- }
400
- }
401
- }
402
- }
403
- ```
404
-
405
- ### Hook Registration
406
-
407
- Hooks are auto-discovered in:
408
- ```
409
- custom/Espo/Modules/{ModuleName}/Hooks/{EntityType}/{HookName}.php
410
- ```
411
-
412
- ## Coding Standards
413
-
414
- ### Type Declarations (Required)
415
-
416
- ```php
417
- // ✅ CORRECT - All types declared
418
- class MyService {
419
- public function processData(string $id, array $data): object {
420
- return $this->entityManager->getEntityById('Account', $id);
421
- }
422
- }
423
-
424
- // ❌ WRONG - Missing types
425
- class BadService {
426
- public function processData($id, $data) {
427
- return $this->entityManager->getEntityById('Account', $id);
428
- }
429
- }
430
- ```
431
-
432
- ### Exception Handling (Not Booleans)
433
-
434
- ```php
435
- // ✅ CORRECT - Use exceptions
436
- use Espo\Core\Exceptions\{NotFound, Forbidden, BadRequest};
437
-
438
- public function getAccount(string $id): Entity {
439
- $account = $this->entityManager->getEntityById('Account', $id);
440
-
441
- if (!$account) {
442
- throw new NotFound();
443
- }
444
-
445
- if (!$this->acl->check($account, 'read')) {
446
- throw new Forbidden();
447
- }
448
-
449
- return $account;
450
- }
451
-
452
- // ❌ WRONG - Returning booleans for errors
453
- public function getAccount(string $id): ?Entity {
454
- $account = $this->entityManager->getEntityById('Account', $id);
455
- if (!$account) {
456
- return null; // Lost error context
457
- }
458
- return $account;
459
- }
460
- ```
461
-
462
- ### Composition Over Inheritance
463
-
464
- ```php
465
- // ✅ CORRECT - Composition with traits/utilities
466
- class MyService extends Record {
467
- use ValidationTrait;
468
-
469
- public function __construct(
470
- private ValidationHelper $validationHelper,
471
- private NotificationHelper $notificationHelper
472
- ) {
473
- parent::__construct();
474
- }
475
- }
476
-
477
- // ❌ WRONG - Deep inheritance hierarchy
478
- class MyService extends IntermediateService extends BaseService extends Record {
479
- // Too many levels
480
- }
481
- ```
482
-
483
- ### DTOs Over Arrays
484
-
485
- ```php
486
- // ✅ CORRECT - Use DTOs
487
- class CreateAccountData {
488
- public function __construct(
489
- public readonly string $name,
490
- public readonly ?string $website,
491
- public readonly array $tags
492
- ) {}
493
- }
494
-
495
- public function createAccount(CreateAccountData $data): Entity {
496
- // Type-safe operations
497
- }
498
-
499
- // ❌ WRONG - Untyped arrays
500
- public function createAccount(array $data): Entity {
501
- $name = $data['name'] ?? ''; // Fragile, no IDE support
502
- }
503
- ```
504
-
505
- ### Maximum 2 Indentation Levels
506
-
507
- ```php
508
- // ✅ CORRECT - Early returns, extracted methods
509
- public function process(Entity $entity): void {
510
- if (!$this->validate($entity)) {
511
- return;
512
- }
513
-
514
- $this->performUpdate($entity);
515
- }
516
-
517
- private function performUpdate(Entity $entity): void {
518
- if ($entity->isNew()) {
519
- $this->handleNew($entity);
520
- return;
521
- }
522
-
523
- $this->handleExisting($entity);
524
- }
525
-
526
- // ❌ WRONG - Deep nesting
527
- public function process(Entity $entity): void {
528
- if ($this->validate($entity)) {
529
- if ($entity->isNew()) {
530
- if ($this->hasPermission()) {
531
- // Three levels deep - hard to read
532
- }
533
- }
534
- }
535
- }
536
- ```
537
-
538
- ## Formula Scripting
539
-
540
- EspoCRM supports declarative logic through Formula scripts - use for simple field calculations instead of hooks.
541
-
542
- ### Formula in Metadata
543
-
544
- ```json
545
- {
546
- "fields": {
547
- "totalPrice": {
548
- "type": "currency",
549
- "formula": "quantity * unitPrice"
550
- },
551
- "displayName": {
552
- "type": "varchar",
553
- "formula": "string\\concatenate(firstName, ' ', lastName)"
554
- }
555
- }
556
- }
557
- ```
558
-
559
- ### When to Use Formula vs. Hooks
560
-
561
- **Use Formula for:**
562
- - Simple field calculations
563
- - String concatenation
564
- - Conditional field values
565
- - Date calculations
566
-
567
- **Use Hooks/Services for:**
568
- - Complex business logic
569
- - External API calls
570
- - Multi-entity operations
571
- - Validation requiring database queries
572
-
573
- ## Cache Management
574
-
575
- ### Rebuild Cache After Metadata Changes
576
-
577
- ```bash
578
- # Always run after changing metadata
579
- bin/command rebuild
580
- ```
581
-
582
- ### Clear Cache Programmatically
583
-
584
- ```php
585
- use Espo\Core\Utils\DataCache;
586
-
587
- class MyService {
588
- public function __construct(private DataCache $dataCache) {}
589
-
590
- public function clearCache(): void {
591
- $this->dataCache->clear();
592
- }
593
- }
594
- ```
595
-
596
- ### Cache Keys
597
-
598
- Common cache keys to be aware of:
599
- - `metadata` - All metadata
600
- - `entityDefs` - Entity definitions
601
- - `clientDefs` - Client definitions
602
- - `aclDefs` - ACL definitions