claude-mpm 4.1.26__py3-none-any.whl → 4.24.0__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 (845) hide show
  1. claude_mpm/BUILD_NUMBER +1 -1
  2. claude_mpm/VERSION +1 -1
  3. claude_mpm/__init__.py +20 -5
  4. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +118 -0
  5. claude_mpm/agents/BASE_DOCUMENTATION.md +53 -0
  6. claude_mpm/agents/BASE_ENGINEER.md +658 -0
  7. claude_mpm/agents/BASE_OPS.md +219 -0
  8. claude_mpm/agents/BASE_PM.md +420 -158
  9. claude_mpm/agents/BASE_PROMPT_ENGINEER.md +787 -0
  10. claude_mpm/agents/BASE_QA.md +167 -0
  11. claude_mpm/agents/BASE_RESEARCH.md +53 -0
  12. claude_mpm/agents/OUTPUT_STYLE.md +299 -29
  13. claude_mpm/agents/PM_INSTRUCTIONS.md +1159 -0
  14. claude_mpm/agents/WORKFLOW.md +355 -191
  15. claude_mpm/agents/agent_loader.py +40 -10
  16. claude_mpm/agents/agent_loader_integration.py +3 -2
  17. claude_mpm/agents/async_agent_loader.py +3 -3
  18. claude_mpm/agents/base_agent_loader.py +11 -9
  19. claude_mpm/agents/frontmatter_validator.py +291 -251
  20. claude_mpm/agents/system_agent_config.py +3 -2
  21. claude_mpm/agents/templates/README.md +465 -0
  22. claude_mpm/agents/templates/agent-manager.json +7 -4
  23. claude_mpm/agents/templates/{agentic_coder_optimizer.json → agentic-coder-optimizer.json} +33 -7
  24. claude_mpm/agents/templates/api_qa.json +16 -4
  25. claude_mpm/agents/templates/circuit_breakers.md +638 -0
  26. claude_mpm/agents/templates/clerk-ops.json +235 -0
  27. claude_mpm/agents/templates/code_analyzer.json +10 -4
  28. claude_mpm/agents/templates/content-agent.json +358 -0
  29. claude_mpm/agents/templates/dart_engineer.json +307 -0
  30. claude_mpm/agents/templates/data_engineer.json +87 -14
  31. claude_mpm/agents/templates/documentation.json +76 -13
  32. claude_mpm/agents/templates/engineer.json +43 -9
  33. claude_mpm/agents/templates/gcp_ops_agent.json +253 -0
  34. claude_mpm/agents/templates/git_file_tracking.md +584 -0
  35. claude_mpm/agents/templates/golang_engineer.json +270 -0
  36. claude_mpm/agents/templates/imagemagick.json +5 -2
  37. claude_mpm/agents/templates/java_engineer.json +346 -0
  38. claude_mpm/agents/templates/javascript_engineer_agent.json +380 -0
  39. claude_mpm/agents/templates/local_ops_agent.json +1840 -0
  40. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +400 -0
  41. claude_mpm/agents/templates/memory_manager.json +6 -3
  42. claude_mpm/agents/templates/nextjs_engineer.json +285 -0
  43. claude_mpm/agents/templates/ops.json +14 -4
  44. claude_mpm/agents/templates/php-engineer.json +287 -0
  45. claude_mpm/agents/templates/pm_examples.md +474 -0
  46. claude_mpm/agents/templates/pm_red_flags.md +262 -0
  47. claude_mpm/agents/templates/product_owner.json +338 -0
  48. claude_mpm/agents/templates/project_organizer.json +19 -5
  49. claude_mpm/agents/templates/prompt-engineer.json +737 -0
  50. claude_mpm/agents/templates/python_engineer.json +387 -0
  51. claude_mpm/agents/templates/qa.json +25 -5
  52. claude_mpm/agents/templates/react_engineer.json +239 -0
  53. claude_mpm/agents/templates/refactoring_engineer.json +15 -5
  54. claude_mpm/agents/templates/research.json +46 -21
  55. claude_mpm/agents/templates/response_format.md +583 -0
  56. claude_mpm/agents/templates/ruby-engineer.json +280 -0
  57. claude_mpm/agents/templates/rust_engineer.json +275 -0
  58. claude_mpm/agents/templates/security.json +59 -10
  59. claude_mpm/agents/templates/svelte-engineer.json +225 -0
  60. claude_mpm/agents/templates/tauri_engineer.json +274 -0
  61. claude_mpm/agents/templates/ticketing.json +16 -7
  62. claude_mpm/agents/templates/typescript_engineer.json +285 -0
  63. claude_mpm/agents/templates/validation_templates.md +312 -0
  64. claude_mpm/agents/templates/vercel_ops_agent.json +164 -33
  65. claude_mpm/agents/templates/version_control.json +16 -4
  66. claude_mpm/agents/templates/web_qa.json +167 -21
  67. claude_mpm/agents/templates/web_ui.json +18 -5
  68. claude_mpm/cli/__init__.py +38 -378
  69. claude_mpm/cli/commands/__init__.py +2 -0
  70. claude_mpm/cli/commands/agent_manager.py +675 -20
  71. claude_mpm/cli/commands/agent_state_manager.py +186 -0
  72. claude_mpm/cli/commands/agents.py +722 -150
  73. claude_mpm/cli/commands/agents_detect.py +380 -0
  74. claude_mpm/cli/commands/agents_recommend.py +309 -0
  75. claude_mpm/cli/commands/aggregate.py +10 -6
  76. claude_mpm/cli/commands/analyze.py +15 -10
  77. claude_mpm/cli/commands/analyze_code.py +8 -4
  78. claude_mpm/cli/commands/auto_configure.py +570 -0
  79. claude_mpm/cli/commands/cleanup.py +12 -12
  80. claude_mpm/cli/commands/config.py +47 -13
  81. claude_mpm/cli/commands/configure.py +469 -1064
  82. claude_mpm/cli/commands/configure_agent_display.py +261 -0
  83. claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
  84. claude_mpm/cli/commands/configure_hook_manager.py +225 -0
  85. claude_mpm/cli/commands/configure_models.py +18 -0
  86. claude_mpm/cli/commands/configure_navigation.py +167 -0
  87. claude_mpm/cli/commands/configure_paths.py +104 -0
  88. claude_mpm/cli/commands/configure_persistence.py +254 -0
  89. claude_mpm/cli/commands/configure_startup_manager.py +646 -0
  90. claude_mpm/cli/commands/configure_template_editor.py +497 -0
  91. claude_mpm/cli/commands/configure_validators.py +73 -0
  92. claude_mpm/cli/commands/dashboard.py +50 -52
  93. claude_mpm/cli/commands/debug.py +7 -7
  94. claude_mpm/cli/commands/doctor.py +43 -7
  95. claude_mpm/cli/commands/info.py +3 -4
  96. claude_mpm/cli/commands/local_deploy.py +537 -0
  97. claude_mpm/cli/commands/mcp.py +17 -10
  98. claude_mpm/cli/commands/mcp_command_router.py +11 -0
  99. claude_mpm/cli/commands/mcp_config.py +154 -0
  100. claude_mpm/cli/commands/mcp_external_commands.py +249 -0
  101. claude_mpm/cli/commands/mcp_install_commands.py +101 -32
  102. claude_mpm/cli/commands/mcp_pipx_config.py +2 -2
  103. claude_mpm/cli/commands/mcp_setup_external.py +868 -0
  104. claude_mpm/cli/commands/memory.py +55 -21
  105. claude_mpm/cli/commands/monitor.py +160 -70
  106. claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
  107. claude_mpm/cli/commands/mpm_init/core.py +525 -0
  108. claude_mpm/cli/commands/mpm_init/display.py +341 -0
  109. claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
  110. claude_mpm/cli/commands/mpm_init/modes.py +397 -0
  111. claude_mpm/cli/commands/mpm_init/prompts.py +442 -0
  112. claude_mpm/cli/commands/mpm_init_cli.py +396 -0
  113. claude_mpm/cli/commands/mpm_init_handler.py +114 -4
  114. claude_mpm/cli/commands/run.py +169 -42
  115. claude_mpm/cli/commands/search.py +458 -0
  116. claude_mpm/cli/commands/skills.py +488 -0
  117. claude_mpm/cli/commands/uninstall.py +176 -0
  118. claude_mpm/cli/commands/upgrade.py +152 -0
  119. claude_mpm/cli/commands/verify.py +119 -0
  120. claude_mpm/cli/executor.py +204 -0
  121. claude_mpm/cli/helpers.py +105 -0
  122. claude_mpm/cli/interactive/__init__.py +21 -0
  123. claude_mpm/cli/interactive/agent_wizard.py +962 -0
  124. claude_mpm/cli/interactive/skills_wizard.py +491 -0
  125. claude_mpm/cli/parser.py +79 -2
  126. claude_mpm/cli/parsers/__init__.py +7 -1
  127. claude_mpm/cli/parsers/agent_manager_parser.py +161 -1
  128. claude_mpm/cli/parsers/agents_parser.py +116 -0
  129. claude_mpm/cli/parsers/auto_configure_parser.py +245 -0
  130. claude_mpm/cli/parsers/base_parser.py +143 -3
  131. claude_mpm/cli/parsers/configure_parser.py +11 -15
  132. claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
  133. claude_mpm/cli/parsers/mcp_parser.py +15 -0
  134. claude_mpm/cli/parsers/monitor_parser.py +12 -2
  135. claude_mpm/cli/parsers/mpm_init_parser.py +179 -9
  136. claude_mpm/cli/parsers/run_parser.py +5 -0
  137. claude_mpm/cli/parsers/search_parser.py +245 -0
  138. claude_mpm/cli/parsers/skills_parser.py +137 -0
  139. claude_mpm/cli/shared/argument_patterns.py +20 -13
  140. claude_mpm/cli/shared/base_command.py +2 -2
  141. claude_mpm/cli/shared/output_formatters.py +28 -19
  142. claude_mpm/cli/startup.py +562 -0
  143. claude_mpm/cli/startup_logging.py +179 -13
  144. claude_mpm/cli/utils.py +53 -2
  145. claude_mpm/commands/mpm-agents-detect.md +168 -0
  146. claude_mpm/commands/mpm-agents-recommend.md +214 -0
  147. claude_mpm/commands/mpm-agents.md +118 -8
  148. claude_mpm/commands/mpm-auto-configure.md +269 -0
  149. claude_mpm/commands/mpm-config.md +137 -14
  150. claude_mpm/commands/mpm-help.md +285 -5
  151. claude_mpm/commands/mpm-init.md +374 -15
  152. claude_mpm/commands/mpm-monitor.md +409 -0
  153. claude_mpm/commands/mpm-organize.md +295 -0
  154. claude_mpm/commands/mpm-resume.md +372 -0
  155. claude_mpm/commands/mpm-status.md +71 -9
  156. claude_mpm/commands/mpm-tickets.md +56 -7
  157. claude_mpm/commands/mpm-version.md +113 -0
  158. claude_mpm/commands/mpm.md +2 -0
  159. claude_mpm/config/agent_config.py +4 -4
  160. claude_mpm/config/experimental_features.py +7 -7
  161. claude_mpm/config/model_config.py +428 -0
  162. claude_mpm/config/paths.py +3 -2
  163. claude_mpm/config/socketio_config.py +3 -3
  164. claude_mpm/constants.py +15 -1
  165. claude_mpm/core/__init__.py +53 -17
  166. claude_mpm/core/agent_name_normalizer.py +3 -2
  167. claude_mpm/core/agent_registry.py +2 -2
  168. claude_mpm/core/agent_session_manager.py +10 -10
  169. claude_mpm/core/api_validator.py +330 -0
  170. claude_mpm/core/base_service.py +33 -23
  171. claude_mpm/core/cache.py +9 -9
  172. claude_mpm/core/claude_runner.py +19 -8
  173. claude_mpm/core/config.py +85 -8
  174. claude_mpm/core/config_aliases.py +7 -6
  175. claude_mpm/core/constants.py +65 -0
  176. claude_mpm/core/container.py +11 -5
  177. claude_mpm/core/enums.py +452 -0
  178. claude_mpm/core/error_handler.py +623 -0
  179. claude_mpm/core/factories.py +1 -1
  180. claude_mpm/core/file_utils.py +764 -0
  181. claude_mpm/core/framework/__init__.py +38 -0
  182. claude_mpm/core/framework/formatters/__init__.py +11 -0
  183. claude_mpm/core/framework/formatters/capability_generator.py +367 -0
  184. claude_mpm/core/framework/formatters/content_formatter.py +288 -0
  185. claude_mpm/core/framework/formatters/context_generator.py +185 -0
  186. claude_mpm/core/framework/loaders/__init__.py +13 -0
  187. claude_mpm/core/framework/loaders/agent_loader.py +210 -0
  188. claude_mpm/core/framework/loaders/file_loader.py +223 -0
  189. claude_mpm/core/framework/loaders/instruction_loader.py +161 -0
  190. claude_mpm/core/framework/loaders/packaged_loader.py +232 -0
  191. claude_mpm/core/framework/processors/__init__.py +11 -0
  192. claude_mpm/core/framework/processors/memory_processor.py +230 -0
  193. claude_mpm/core/framework/processors/metadata_processor.py +146 -0
  194. claude_mpm/core/framework/processors/template_processor.py +244 -0
  195. claude_mpm/core/framework_loader.py +321 -1631
  196. claude_mpm/core/hook_manager.py +8 -6
  197. claude_mpm/core/injectable_service.py +11 -8
  198. claude_mpm/core/instruction_reinforcement_hook.py +4 -3
  199. claude_mpm/core/interactive_session.py +55 -8
  200. claude_mpm/core/interfaces.py +56 -1
  201. claude_mpm/core/lazy.py +3 -3
  202. claude_mpm/core/log_manager.py +92 -23
  203. claude_mpm/core/logger.py +19 -14
  204. claude_mpm/core/logging_config.py +6 -2
  205. claude_mpm/core/logging_utils.py +520 -0
  206. claude_mpm/core/oneshot_session.py +51 -7
  207. claude_mpm/core/optimized_agent_loader.py +9 -9
  208. claude_mpm/core/optimized_startup.py +1 -1
  209. claude_mpm/core/output_style_manager.py +12 -192
  210. claude_mpm/core/pm_hook_interceptor.py +18 -12
  211. claude_mpm/core/service_registry.py +7 -3
  212. claude_mpm/core/session_manager.py +14 -12
  213. claude_mpm/core/shared/config_loader.py +1 -1
  214. claude_mpm/core/socketio_pool.py +15 -15
  215. claude_mpm/core/tool_access_control.py +3 -2
  216. claude_mpm/core/types.py +4 -11
  217. claude_mpm/core/typing_utils.py +7 -6
  218. claude_mpm/core/unified_agent_registry.py +115 -11
  219. claude_mpm/core/unified_config.py +6 -6
  220. claude_mpm/core/unified_paths.py +23 -20
  221. claude_mpm/dashboard/analysis_runner.py +4 -4
  222. claude_mpm/dashboard/api/simple_directory.py +261 -0
  223. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +188 -0
  224. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +156 -0
  225. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +38 -0
  226. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +92 -0
  227. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +248 -0
  228. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +61 -0
  229. claude_mpm/dashboard/static/archive/test_activity_connection.html +179 -0
  230. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +68 -0
  231. claude_mpm/dashboard/static/archive/test_dashboard.html +409 -0
  232. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +519 -0
  233. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +181 -0
  234. claude_mpm/dashboard/static/archive/test_file_data.html +315 -0
  235. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +243 -0
  236. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +234 -0
  237. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +117 -0
  238. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +115 -0
  239. claude_mpm/dashboard/static/archive/test_file_viewer.html +224 -0
  240. claude_mpm/dashboard/static/archive/test_final_activity.html +220 -0
  241. claude_mpm/dashboard/static/archive/test_tab_fix.html +139 -0
  242. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +1 -0
  243. claude_mpm/dashboard/static/built/components/activity-tree.js +1 -1
  244. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +777 -0
  245. claude_mpm/dashboard/static/built/components/agent-inference.js +1 -1
  246. claude_mpm/dashboard/static/built/components/build-tracker.js +333 -0
  247. claude_mpm/dashboard/static/built/components/code-simple.js +857 -0
  248. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +353 -0
  249. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +235 -0
  250. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +409 -0
  251. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +435 -0
  252. claude_mpm/dashboard/static/built/components/code-tree.js +1 -1
  253. claude_mpm/dashboard/static/built/components/code-viewer.js +1 -1
  254. claude_mpm/dashboard/static/built/components/connection-debug.js +654 -0
  255. claude_mpm/dashboard/static/built/components/diff-viewer.js +891 -0
  256. claude_mpm/dashboard/static/built/components/event-processor.js +1 -1
  257. claude_mpm/dashboard/static/built/components/event-viewer.js +1 -1
  258. claude_mpm/dashboard/static/built/components/export-manager.js +1 -1
  259. claude_mpm/dashboard/static/built/components/file-change-tracker.js +443 -0
  260. claude_mpm/dashboard/static/built/components/file-change-viewer.js +690 -0
  261. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +1 -1
  262. claude_mpm/dashboard/static/built/components/file-viewer.js +2 -0
  263. claude_mpm/dashboard/static/built/components/module-viewer.js +1 -1
  264. claude_mpm/dashboard/static/built/components/nav-bar.js +145 -0
  265. claude_mpm/dashboard/static/built/components/page-structure.js +429 -0
  266. claude_mpm/dashboard/static/built/components/session-manager.js +1 -1
  267. claude_mpm/dashboard/static/built/components/unified-data-viewer.js +1 -1
  268. claude_mpm/dashboard/static/built/components/working-directory.js +1 -1
  269. claude_mpm/dashboard/static/built/connection-manager.js +536 -0
  270. claude_mpm/dashboard/static/built/dashboard.js +1 -1
  271. claude_mpm/dashboard/static/built/extension-error-handler.js +164 -0
  272. claude_mpm/dashboard/static/built/react/events.js +30 -0
  273. claude_mpm/dashboard/static/built/shared/dom-helpers.js +396 -0
  274. claude_mpm/dashboard/static/built/shared/event-bus.js +330 -0
  275. claude_mpm/dashboard/static/built/shared/event-filter-service.js +540 -0
  276. claude_mpm/dashboard/static/built/shared/logger.js +385 -0
  277. claude_mpm/dashboard/static/built/shared/page-structure.js +249 -0
  278. claude_mpm/dashboard/static/built/shared/tooltip-service.js +253 -0
  279. claude_mpm/dashboard/static/built/socket-client.js +1 -1
  280. claude_mpm/dashboard/static/built/tab-isolation-fix.js +185 -0
  281. claude_mpm/dashboard/static/css/dashboard.css +588 -6
  282. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +1 -0
  283. claude_mpm/dashboard/static/dist/components/activity-tree.js +1 -1
  284. claude_mpm/dashboard/static/dist/components/agent-inference.js +1 -1
  285. claude_mpm/dashboard/static/dist/components/code-tree.js +1 -1
  286. claude_mpm/dashboard/static/dist/components/code-viewer.js +1 -1
  287. claude_mpm/dashboard/static/dist/components/event-processor.js +1 -1
  288. claude_mpm/dashboard/static/dist/components/event-viewer.js +1 -1
  289. claude_mpm/dashboard/static/dist/components/export-manager.js +1 -1
  290. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +1 -1
  291. claude_mpm/dashboard/static/dist/components/file-viewer.js +2 -0
  292. claude_mpm/dashboard/static/dist/components/module-viewer.js +1 -1
  293. claude_mpm/dashboard/static/dist/components/session-manager.js +1 -1
  294. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +1 -1
  295. claude_mpm/dashboard/static/dist/components/working-directory.js +1 -1
  296. claude_mpm/dashboard/static/dist/dashboard.js +1 -1
  297. claude_mpm/dashboard/static/dist/react/events.js +30 -0
  298. claude_mpm/dashboard/static/dist/socket-client.js +1 -1
  299. claude_mpm/dashboard/static/events.html +607 -0
  300. claude_mpm/dashboard/static/index.html +635 -0
  301. claude_mpm/dashboard/static/js/components/activity-tree.js +3 -17
  302. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +4 -1
  303. claude_mpm/dashboard/static/js/components/agent-inference.js +3 -0
  304. claude_mpm/dashboard/static/js/components/build-tracker.js +8 -0
  305. claude_mpm/dashboard/static/js/components/code-simple.js +857 -0
  306. claude_mpm/dashboard/static/js/components/diff-viewer.js +891 -0
  307. claude_mpm/dashboard/static/js/components/event-processor.js +3 -0
  308. claude_mpm/dashboard/static/js/components/event-viewer.js +39 -2
  309. claude_mpm/dashboard/static/js/components/export-manager.js +3 -0
  310. claude_mpm/dashboard/static/js/components/file-change-tracker.js +443 -0
  311. claude_mpm/dashboard/static/js/components/file-change-viewer.js +690 -0
  312. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +30 -10
  313. claude_mpm/dashboard/static/js/components/file-viewer.js +580 -0
  314. claude_mpm/dashboard/static/js/components/module-viewer.js +26 -0
  315. claude_mpm/dashboard/static/js/components/session-manager.js +7 -7
  316. claude_mpm/dashboard/static/js/components/socket-manager.js +4 -0
  317. claude_mpm/dashboard/static/js/components/ui-state-manager.js +356 -41
  318. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +455 -23
  319. claude_mpm/dashboard/static/js/components/working-directory.js +44 -9
  320. claude_mpm/dashboard/static/js/dashboard.js +245 -132
  321. claude_mpm/dashboard/static/js/shared/dom-helpers.js +396 -0
  322. claude_mpm/dashboard/static/js/shared/event-bus.js +330 -0
  323. claude_mpm/dashboard/static/js/shared/logger.js +385 -0
  324. claude_mpm/dashboard/static/js/shared/tooltip-service.js +253 -0
  325. claude_mpm/dashboard/static/js/socket-client.js +49 -22
  326. claude_mpm/dashboard/static/js/stores/dashboard-store.js +562 -0
  327. claude_mpm/dashboard/static/js/tab-isolation-fix.js +185 -0
  328. claude_mpm/dashboard/static/legacy/activity.html +736 -0
  329. claude_mpm/dashboard/static/legacy/agents.html +786 -0
  330. claude_mpm/dashboard/static/legacy/files.html +747 -0
  331. claude_mpm/dashboard/static/legacy/tools.html +831 -0
  332. claude_mpm/dashboard/static/monitors.html +431 -0
  333. claude_mpm/dashboard/static/production/events.html +659 -0
  334. claude_mpm/dashboard/static/production/main.html +698 -0
  335. claude_mpm/dashboard/static/production/monitors.html +483 -0
  336. claude_mpm/dashboard/static/socket.io.min.js +7 -0
  337. claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +7 -0
  338. claude_mpm/dashboard/static/test-archive/dashboard.html +635 -0
  339. claude_mpm/dashboard/static/test-archive/debug-events.html +147 -0
  340. claude_mpm/dashboard/static/test-archive/test-navigation.html +256 -0
  341. claude_mpm/dashboard/static/test-archive/test-react-exports.html +180 -0
  342. claude_mpm/dashboard/static/test-archive/test_debug.html +25 -0
  343. claude_mpm/dashboard/templates/code_simple.html +153 -0
  344. claude_mpm/dashboard/templates/index.html +112 -109
  345. claude_mpm/experimental/cli_enhancements.py +4 -2
  346. claude_mpm/generators/agent_profile_generator.py +5 -3
  347. claude_mpm/hooks/__init__.py +37 -1
  348. claude_mpm/hooks/base_hook.py +5 -4
  349. claude_mpm/hooks/claude_hooks/connection_pool.py +4 -4
  350. claude_mpm/hooks/claude_hooks/event_handlers.py +21 -18
  351. claude_mpm/hooks/claude_hooks/hook_handler.py +29 -22
  352. claude_mpm/hooks/claude_hooks/installer.py +67 -22
  353. claude_mpm/hooks/claude_hooks/memory_integration.py +3 -3
  354. claude_mpm/hooks/claude_hooks/response_tracking.py +57 -17
  355. claude_mpm/hooks/claude_hooks/services/connection_manager.py +62 -64
  356. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +140 -76
  357. claude_mpm/hooks/claude_hooks/services/state_manager.py +11 -9
  358. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +3 -3
  359. claude_mpm/hooks/failure_learning/__init__.py +60 -0
  360. claude_mpm/hooks/failure_learning/failure_detection_hook.py +235 -0
  361. claude_mpm/hooks/failure_learning/fix_detection_hook.py +217 -0
  362. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +286 -0
  363. claude_mpm/hooks/instruction_reinforcement.py +301 -0
  364. claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
  365. claude_mpm/hooks/kuzu_memory_hook.py +386 -0
  366. claude_mpm/hooks/kuzu_response_hook.py +183 -0
  367. claude_mpm/hooks/memory_integration_hook.py +1 -1
  368. claude_mpm/hooks/session_resume_hook.py +121 -0
  369. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  370. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  371. claude_mpm/hooks/tool_call_interceptor.py +8 -5
  372. claude_mpm/hooks/validation_hooks.py +3 -3
  373. claude_mpm/init.py +23 -4
  374. claude_mpm/models/agent_session.py +8 -6
  375. claude_mpm/models/resume_log.py +340 -0
  376. claude_mpm/scripts/claude-hook-handler.sh +33 -7
  377. claude_mpm/scripts/launch_monitor.py +85 -0
  378. claude_mpm/scripts/mcp_server.py +3 -5
  379. claude_mpm/scripts/mpm_doctor.py +3 -2
  380. claude_mpm/scripts/socketio_daemon.py +159 -512
  381. claude_mpm/services/__init__.py +144 -160
  382. claude_mpm/services/agents/__init__.py +18 -5
  383. claude_mpm/services/agents/agent_builder.py +13 -11
  384. claude_mpm/services/agents/auto_config_manager.py +796 -0
  385. claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
  386. claude_mpm/services/agents/deployment/agent_deployment.py +38 -15
  387. claude_mpm/services/agents/deployment/agent_discovery_service.py +125 -7
  388. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +5 -5
  389. claude_mpm/services/agents/deployment/agent_format_converter.py +56 -12
  390. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +4 -2
  391. claude_mpm/services/agents/deployment/agent_operation_service.py +2 -2
  392. claude_mpm/services/agents/deployment/agent_record_service.py +4 -4
  393. claude_mpm/services/agents/deployment/agent_state_service.py +2 -2
  394. claude_mpm/services/agents/deployment/agent_template_builder.py +715 -47
  395. claude_mpm/services/agents/deployment/agent_validator.py +31 -7
  396. claude_mpm/services/agents/deployment/agent_version_manager.py +8 -5
  397. claude_mpm/services/agents/deployment/agent_versioning.py +1 -1
  398. claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
  399. claude_mpm/services/agents/deployment/deployment_config_loader.py +131 -7
  400. claude_mpm/services/agents/deployment/deployment_type_detector.py +10 -14
  401. claude_mpm/services/agents/deployment/deployment_wrapper.py +58 -0
  402. claude_mpm/services/agents/deployment/interface_adapter.py +3 -2
  403. claude_mpm/services/agents/deployment/local_template_deployment.py +360 -0
  404. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +134 -38
  405. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +8 -7
  406. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +7 -16
  407. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +4 -3
  408. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +7 -5
  409. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +6 -5
  410. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +9 -6
  411. claude_mpm/services/agents/deployment/system_instructions_deployer.py +9 -6
  412. claude_mpm/services/agents/deployment/validation/__init__.py +3 -1
  413. claude_mpm/services/agents/deployment/validation/template_validator.py +64 -44
  414. claude_mpm/services/agents/deployment/validation/validation_result.py +1 -9
  415. claude_mpm/services/agents/loading/agent_profile_loader.py +10 -9
  416. claude_mpm/services/agents/loading/base_agent_manager.py +16 -6
  417. claude_mpm/services/agents/loading/framework_agent_loader.py +2 -2
  418. claude_mpm/services/agents/local_template_manager.py +744 -0
  419. claude_mpm/services/agents/management/agent_capabilities_generator.py +3 -2
  420. claude_mpm/services/agents/management/agent_management_service.py +5 -5
  421. claude_mpm/services/agents/memory/agent_memory_manager.py +32 -29
  422. claude_mpm/services/agents/memory/content_manager.py +17 -9
  423. claude_mpm/services/agents/memory/memory_categorization_service.py +4 -2
  424. claude_mpm/services/agents/memory/memory_file_service.py +32 -6
  425. claude_mpm/services/agents/memory/memory_format_service.py +6 -4
  426. claude_mpm/services/agents/memory/memory_limits_service.py +4 -2
  427. claude_mpm/services/agents/memory/template_generator.py +3 -3
  428. claude_mpm/services/agents/observers.py +547 -0
  429. claude_mpm/services/agents/recommender.py +615 -0
  430. claude_mpm/services/agents/registry/deployed_agent_discovery.py +3 -3
  431. claude_mpm/services/agents/registry/modification_tracker.py +30 -19
  432. claude_mpm/services/async_session_logger.py +141 -98
  433. claude_mpm/services/claude_session_logger.py +82 -74
  434. claude_mpm/services/cli/agent_cleanup_service.py +5 -0
  435. claude_mpm/services/cli/agent_listing_service.py +5 -5
  436. claude_mpm/services/cli/agent_validation_service.py +3 -1
  437. claude_mpm/services/cli/memory_crud_service.py +12 -7
  438. claude_mpm/services/cli/memory_output_formatter.py +2 -2
  439. claude_mpm/services/cli/resume_service.py +617 -0
  440. claude_mpm/services/cli/session_manager.py +104 -13
  441. claude_mpm/services/cli/session_pause_manager.py +504 -0
  442. claude_mpm/services/cli/session_resume_helper.py +372 -0
  443. claude_mpm/services/cli/startup_checker.py +13 -10
  444. claude_mpm/services/cli/unified_dashboard_manager.py +439 -0
  445. claude_mpm/services/command_deployment_service.py +9 -7
  446. claude_mpm/services/command_handler_service.py +11 -5
  447. claude_mpm/services/core/__init__.py +33 -1
  448. claude_mpm/services/core/base.py +26 -11
  449. claude_mpm/services/core/interfaces/__init__.py +90 -3
  450. claude_mpm/services/core/interfaces/agent.py +184 -0
  451. claude_mpm/services/core/interfaces/health.py +172 -0
  452. claude_mpm/services/core/interfaces/model.py +281 -0
  453. claude_mpm/services/core/interfaces/process.py +372 -0
  454. claude_mpm/services/core/interfaces/project.py +121 -0
  455. claude_mpm/services/core/interfaces/restart.py +307 -0
  456. claude_mpm/services/core/interfaces/stability.py +260 -0
  457. claude_mpm/services/core/interfaces.py +56 -1
  458. claude_mpm/services/core/memory_manager.py +92 -47
  459. claude_mpm/services/core/models/__init__.py +79 -0
  460. claude_mpm/services/core/models/agent_config.py +384 -0
  461. claude_mpm/services/core/models/health.py +162 -0
  462. claude_mpm/services/core/models/process.py +239 -0
  463. claude_mpm/services/core/models/restart.py +302 -0
  464. claude_mpm/services/core/models/stability.py +264 -0
  465. claude_mpm/services/core/models/toolchain.py +306 -0
  466. claude_mpm/services/core/path_resolver.py +36 -14
  467. claude_mpm/services/diagnostics/__init__.py +2 -2
  468. claude_mpm/services/diagnostics/checks/__init__.py +4 -2
  469. claude_mpm/services/diagnostics/checks/agent_check.py +30 -32
  470. claude_mpm/services/diagnostics/checks/claude_code_check.py +270 -0
  471. claude_mpm/services/diagnostics/checks/common_issues_check.py +28 -27
  472. claude_mpm/services/diagnostics/checks/configuration_check.py +26 -25
  473. claude_mpm/services/diagnostics/checks/filesystem_check.py +18 -17
  474. claude_mpm/services/diagnostics/checks/installation_check.py +165 -60
  475. claude_mpm/services/diagnostics/checks/instructions_check.py +20 -19
  476. claude_mpm/services/diagnostics/checks/mcp_check.py +57 -43
  477. claude_mpm/services/diagnostics/checks/mcp_services_check.py +1066 -0
  478. claude_mpm/services/diagnostics/checks/monitor_check.py +24 -23
  479. claude_mpm/services/diagnostics/checks/startup_log_check.py +14 -11
  480. claude_mpm/services/diagnostics/diagnostic_runner.py +22 -13
  481. claude_mpm/services/diagnostics/doctor_reporter.py +275 -47
  482. claude_mpm/services/diagnostics/models.py +37 -21
  483. claude_mpm/services/event_aggregator.py +5 -3
  484. claude_mpm/services/event_bus/direct_relay.py +8 -4
  485. claude_mpm/services/event_bus/event_bus.py +51 -9
  486. claude_mpm/services/event_bus/relay.py +33 -14
  487. claude_mpm/services/events/consumers/dead_letter.py +7 -5
  488. claude_mpm/services/events/core.py +5 -6
  489. claude_mpm/services/events/producers/hook.py +6 -6
  490. claude_mpm/services/events/producers/system.py +8 -8
  491. claude_mpm/services/exceptions.py +5 -5
  492. claude_mpm/services/framework_claude_md_generator/__init__.py +1 -1
  493. claude_mpm/services/framework_claude_md_generator/content_assembler.py +5 -5
  494. claude_mpm/services/framework_claude_md_generator/content_validator.py +2 -2
  495. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +3 -3
  496. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +2 -2
  497. claude_mpm/services/framework_claude_md_generator/version_manager.py +1 -1
  498. claude_mpm/services/hook_installer_service.py +506 -0
  499. claude_mpm/services/hook_service.py +5 -6
  500. claude_mpm/services/infrastructure/context_preservation.py +13 -11
  501. claude_mpm/services/infrastructure/daemon_manager.py +9 -9
  502. claude_mpm/services/infrastructure/logging.py +2 -2
  503. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -1
  504. claude_mpm/services/infrastructure/monitoring/aggregator.py +12 -12
  505. claude_mpm/services/infrastructure/monitoring/base.py +5 -13
  506. claude_mpm/services/infrastructure/monitoring/network.py +7 -6
  507. claude_mpm/services/infrastructure/monitoring/process.py +13 -12
  508. claude_mpm/services/infrastructure/monitoring/resources.py +8 -7
  509. claude_mpm/services/infrastructure/monitoring/service.py +16 -15
  510. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  511. claude_mpm/services/local_ops/__init__.py +165 -0
  512. claude_mpm/services/local_ops/crash_detector.py +257 -0
  513. claude_mpm/services/local_ops/health_checks/__init__.py +28 -0
  514. claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
  515. claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
  516. claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
  517. claude_mpm/services/local_ops/health_manager.py +430 -0
  518. claude_mpm/services/local_ops/log_monitor.py +396 -0
  519. claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
  520. claude_mpm/services/local_ops/process_manager.py +595 -0
  521. claude_mpm/services/local_ops/resource_monitor.py +331 -0
  522. claude_mpm/services/local_ops/restart_manager.py +401 -0
  523. claude_mpm/services/local_ops/restart_policy.py +387 -0
  524. claude_mpm/services/local_ops/state_manager.py +372 -0
  525. claude_mpm/services/local_ops/unified_manager.py +600 -0
  526. claude_mpm/services/mcp_config_manager.py +1612 -0
  527. claude_mpm/services/mcp_gateway/__init__.py +97 -93
  528. claude_mpm/services/mcp_gateway/auto_configure.py +43 -38
  529. claude_mpm/services/mcp_gateway/config/config_loader.py +3 -3
  530. claude_mpm/services/mcp_gateway/config/configuration.py +23 -4
  531. claude_mpm/services/mcp_gateway/core/__init__.py +1 -2
  532. claude_mpm/services/mcp_gateway/core/base.py +20 -33
  533. claude_mpm/services/mcp_gateway/core/process_pool.py +585 -31
  534. claude_mpm/services/mcp_gateway/core/singleton_manager.py +2 -2
  535. claude_mpm/services/mcp_gateway/core/startup_verification.py +3 -3
  536. claude_mpm/services/mcp_gateway/main.py +90 -15
  537. claude_mpm/services/mcp_gateway/registry/service_registry.py +4 -2
  538. claude_mpm/services/mcp_gateway/registry/tool_registry.py +12 -9
  539. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +4 -4
  540. claude_mpm/services/mcp_gateway/server/stdio_server.py +9 -15
  541. claude_mpm/services/mcp_gateway/tools/__init__.py +14 -2
  542. claude_mpm/services/mcp_gateway/tools/base_adapter.py +15 -15
  543. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +10 -9
  544. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +654 -0
  545. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +36 -34
  546. claude_mpm/services/mcp_gateway/tools/hello_world.py +8 -8
  547. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +551 -0
  548. claude_mpm/services/mcp_gateway/utils/__init__.py +14 -0
  549. claude_mpm/services/mcp_gateway/utils/package_version_checker.py +160 -0
  550. claude_mpm/services/mcp_gateway/utils/update_preferences.py +170 -0
  551. claude_mpm/services/mcp_service_verifier.py +729 -0
  552. claude_mpm/services/memory/builder.py +9 -8
  553. claude_mpm/services/memory/cache/shared_prompt_cache.py +2 -1
  554. claude_mpm/services/memory/cache/simple_cache.py +2 -2
  555. claude_mpm/services/memory/failure_tracker.py +578 -0
  556. claude_mpm/services/memory/indexed_memory.py +8 -8
  557. claude_mpm/services/memory/optimizer.py +8 -9
  558. claude_mpm/services/memory/router.py +3 -3
  559. claude_mpm/services/memory_hook_service.py +165 -4
  560. claude_mpm/services/model/__init__.py +147 -0
  561. claude_mpm/services/model/base_provider.py +365 -0
  562. claude_mpm/services/model/claude_provider.py +412 -0
  563. claude_mpm/services/model/model_router.py +453 -0
  564. claude_mpm/services/model/ollama_provider.py +415 -0
  565. claude_mpm/services/monitor/__init__.py +20 -0
  566. claude_mpm/services/monitor/daemon.py +671 -0
  567. claude_mpm/services/monitor/daemon_manager.py +963 -0
  568. claude_mpm/services/monitor/event_emitter.py +350 -0
  569. claude_mpm/services/monitor/handlers/__init__.py +21 -0
  570. claude_mpm/services/monitor/handlers/code_analysis.py +332 -0
  571. claude_mpm/services/monitor/handlers/dashboard.py +299 -0
  572. claude_mpm/services/monitor/handlers/file.py +264 -0
  573. claude_mpm/services/monitor/handlers/hooks.py +512 -0
  574. claude_mpm/services/monitor/management/__init__.py +18 -0
  575. claude_mpm/services/monitor/management/health.py +124 -0
  576. claude_mpm/services/monitor/management/lifecycle.py +724 -0
  577. claude_mpm/services/monitor/server.py +817 -0
  578. claude_mpm/services/monitor_build_service.py +2 -2
  579. claude_mpm/services/native_agent_converter.py +356 -0
  580. claude_mpm/services/orphan_detection.py +786 -0
  581. claude_mpm/services/port_manager.py +2 -2
  582. claude_mpm/services/project/__init__.py +23 -0
  583. claude_mpm/services/project/analyzer.py +3 -3
  584. claude_mpm/services/project/architecture_analyzer.py +5 -5
  585. claude_mpm/services/project/archive_manager.py +1045 -0
  586. claude_mpm/services/project/dependency_analyzer.py +4 -4
  587. claude_mpm/services/project/detection_strategies.py +719 -0
  588. claude_mpm/services/project/documentation_manager.py +553 -0
  589. claude_mpm/services/project/enhanced_analyzer.py +572 -0
  590. claude_mpm/services/project/metrics_collector.py +4 -4
  591. claude_mpm/services/project/project_organizer.py +1005 -0
  592. claude_mpm/services/project/registry.py +13 -7
  593. claude_mpm/services/project/toolchain_analyzer.py +581 -0
  594. claude_mpm/services/project_port_allocator.py +596 -0
  595. claude_mpm/services/response_tracker.py +21 -10
  596. claude_mpm/services/runner_configuration_service.py +1 -0
  597. claude_mpm/services/self_upgrade_service.py +500 -0
  598. claude_mpm/services/session_management_service.py +7 -5
  599. claude_mpm/services/session_manager.py +380 -0
  600. claude_mpm/services/shared/__init__.py +2 -1
  601. claude_mpm/services/shared/async_service_base.py +16 -27
  602. claude_mpm/services/shared/config_service_base.py +17 -14
  603. claude_mpm/services/shared/lifecycle_service_base.py +1 -14
  604. claude_mpm/services/shared/service_factory.py +8 -5
  605. claude_mpm/services/socketio/client_proxy.py +60 -5
  606. claude_mpm/services/socketio/dashboard_server.py +361 -0
  607. claude_mpm/services/socketio/event_normalizer.py +10 -6
  608. claude_mpm/services/socketio/handlers/__init__.py +5 -2
  609. claude_mpm/services/socketio/handlers/base.py +2 -2
  610. claude_mpm/services/socketio/handlers/code_analysis.py +90 -27
  611. claude_mpm/services/socketio/handlers/connection.py +21 -40
  612. claude_mpm/services/socketio/handlers/connection_handler.py +13 -10
  613. claude_mpm/services/socketio/handlers/file.py +46 -10
  614. claude_mpm/services/socketio/handlers/git.py +8 -8
  615. claude_mpm/services/socketio/handlers/hook.py +29 -17
  616. claude_mpm/services/socketio/handlers/registry.py +4 -2
  617. claude_mpm/services/socketio/monitor_client.py +364 -0
  618. claude_mpm/services/socketio/server/broadcaster.py +9 -7
  619. claude_mpm/services/socketio/server/connection_manager.py +2 -2
  620. claude_mpm/services/socketio/server/core.py +141 -4
  621. claude_mpm/services/socketio/server/eventbus_integration.py +20 -14
  622. claude_mpm/services/socketio/server/main.py +23 -21
  623. claude_mpm/services/socketio_client_manager.py +4 -4
  624. claude_mpm/services/subprocess_launcher_service.py +19 -15
  625. claude_mpm/services/system_instructions_service.py +2 -2
  626. claude_mpm/services/ticket_services/formatter_service.py +1 -1
  627. claude_mpm/services/ticket_services/validation_service.py +5 -5
  628. claude_mpm/services/unified/__init__.py +65 -0
  629. claude_mpm/services/unified/analyzer_strategies/__init__.py +44 -0
  630. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +518 -0
  631. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +680 -0
  632. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +903 -0
  633. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +746 -0
  634. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +733 -0
  635. claude_mpm/services/unified/config_strategies/__init__.py +175 -0
  636. claude_mpm/services/unified/config_strategies/config_schema.py +731 -0
  637. claude_mpm/services/unified/config_strategies/context_strategy.py +747 -0
  638. claude_mpm/services/unified/config_strategies/error_handling_strategy.py +1005 -0
  639. claude_mpm/services/unified/config_strategies/file_loader_strategy.py +881 -0
  640. claude_mpm/services/unified/config_strategies/unified_config_service.py +823 -0
  641. claude_mpm/services/unified/config_strategies/validation_strategy.py +1148 -0
  642. claude_mpm/services/unified/deployment_strategies/__init__.py +97 -0
  643. claude_mpm/services/unified/deployment_strategies/base.py +553 -0
  644. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +573 -0
  645. claude_mpm/services/unified/deployment_strategies/local.py +607 -0
  646. claude_mpm/services/unified/deployment_strategies/utils.py +667 -0
  647. claude_mpm/services/unified/deployment_strategies/vercel.py +475 -0
  648. claude_mpm/services/unified/interfaces.py +475 -0
  649. claude_mpm/services/unified/migration.py +509 -0
  650. claude_mpm/services/unified/strategies.py +534 -0
  651. claude_mpm/services/unified/unified_analyzer.py +542 -0
  652. claude_mpm/services/unified/unified_config.py +691 -0
  653. claude_mpm/services/unified/unified_deployment.py +470 -0
  654. claude_mpm/services/utility_service.py +6 -3
  655. claude_mpm/services/version_control/branch_strategy.py +2 -2
  656. claude_mpm/services/version_control/conflict_resolution.py +8 -4
  657. claude_mpm/services/version_control/git_operations.py +26 -24
  658. claude_mpm/services/version_control/semantic_versioning.py +14 -14
  659. claude_mpm/services/version_control/version_parser.py +14 -11
  660. claude_mpm/services/version_service.py +104 -1
  661. claude_mpm/skills/__init__.py +42 -0
  662. claude_mpm/skills/agent_skills_injector.py +324 -0
  663. claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
  664. claude_mpm/skills/bundled/__init__.py +6 -0
  665. claude_mpm/skills/bundled/api-documentation.md +393 -0
  666. claude_mpm/skills/bundled/async-testing.md +571 -0
  667. claude_mpm/skills/bundled/code-review.md +143 -0
  668. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  669. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  670. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  671. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  672. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  673. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  674. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  675. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  676. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  677. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  678. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  679. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  680. claude_mpm/skills/bundled/database-migration.md +199 -0
  681. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  682. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  683. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  684. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  685. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  686. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  687. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  688. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  689. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  690. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  691. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  692. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  693. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  694. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  695. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  696. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  697. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  698. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  699. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  700. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  701. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  702. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  703. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  704. claude_mpm/skills/bundled/git-workflow.md +414 -0
  705. claude_mpm/skills/bundled/imagemagick.md +204 -0
  706. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  707. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  708. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  709. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  710. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  711. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  712. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  713. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  714. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  715. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  716. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  717. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  718. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  719. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  720. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  721. claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
  722. claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
  723. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  724. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  725. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  726. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  727. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  728. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  729. claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
  730. claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
  731. claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
  732. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  733. claude_mpm/skills/bundled/pdf.md +141 -0
  734. claude_mpm/skills/bundled/performance-profiling.md +573 -0
  735. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  736. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  737. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  738. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  739. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  740. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  741. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  742. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  743. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  744. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  745. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  746. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  747. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  748. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  749. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  750. claude_mpm/skills/bundled/security-scanning.md +327 -0
  751. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  752. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  753. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  754. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  755. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  756. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  757. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  758. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  759. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  760. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  761. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  762. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  763. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  764. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  765. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  766. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  767. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  768. claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
  769. claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
  770. claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
  771. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  772. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  773. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
  774. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  775. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  776. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  777. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  778. claude_mpm/skills/bundled/xlsx.md +157 -0
  779. claude_mpm/skills/registry.py +286 -0
  780. claude_mpm/skills/skill_manager.py +310 -0
  781. claude_mpm/skills/skills_registry.py +348 -0
  782. claude_mpm/skills/skills_service.py +739 -0
  783. claude_mpm/storage/state_storage.py +31 -31
  784. claude_mpm/tools/__main__.py +1 -1
  785. claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
  786. claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
  787. claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
  788. claude_mpm/tools/code_tree_analyzer/core.py +380 -0
  789. claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
  790. claude_mpm/tools/code_tree_analyzer/events.py +168 -0
  791. claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
  792. claude_mpm/tools/code_tree_analyzer/models.py +39 -0
  793. claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
  794. claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
  795. claude_mpm/tools/code_tree_builder.py +6 -6
  796. claude_mpm/tools/code_tree_events.py +14 -10
  797. claude_mpm/tools/socketio_debug.py +11 -11
  798. claude_mpm/utils/agent_dependency_loader.py +108 -27
  799. claude_mpm/utils/common.py +544 -0
  800. claude_mpm/utils/config_manager.py +12 -6
  801. claude_mpm/utils/database_connector.py +298 -0
  802. claude_mpm/utils/dependency_cache.py +2 -2
  803. claude_mpm/utils/dependency_strategies.py +15 -10
  804. claude_mpm/utils/display_helper.py +260 -0
  805. claude_mpm/utils/environment_context.py +4 -3
  806. claude_mpm/utils/error_handler.py +5 -3
  807. claude_mpm/utils/file_utils.py +13 -14
  808. claude_mpm/utils/git_analyzer.py +407 -0
  809. claude_mpm/utils/log_cleanup.py +627 -0
  810. claude_mpm/utils/path_operations.py +7 -4
  811. claude_mpm/utils/robust_installer.py +133 -24
  812. claude_mpm/utils/session_logging.py +2 -2
  813. claude_mpm/utils/subprocess_utils.py +9 -8
  814. claude_mpm/validation/agent_validator.py +6 -6
  815. claude_mpm/validation/frontmatter_validator.py +6 -6
  816. claude_mpm-4.24.0.dist-info/METADATA +675 -0
  817. claude_mpm-4.24.0.dist-info/RECORD +1018 -0
  818. {claude_mpm-4.1.26.dist-info → claude_mpm-4.24.0.dist-info}/entry_points.txt +1 -0
  819. claude_mpm/agents/INSTRUCTIONS.md +0 -261
  820. claude_mpm/agents/templates/agent-manager.md +0 -619
  821. claude_mpm/cli/commands/configure_tui.py +0 -1927
  822. claude_mpm/cli/commands/mpm_init.py +0 -594
  823. claude_mpm/cli/commands/socketio_monitor.py +0 -233
  824. claude_mpm/dashboard/static/css/code-tree.css +0 -1408
  825. claude_mpm/dashboard/static/js/components/code-tree.js +0 -3220
  826. claude_mpm/dashboard/static/js/components/code-viewer.js +0 -480
  827. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +0 -425
  828. claude_mpm/hooks/claude_hooks/hook_handler_original.py +0 -1040
  829. claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +0 -347
  830. claude_mpm/scripts/socketio_daemon_hardened.py +0 -937
  831. claude_mpm/scripts/socketio_daemon_wrapper.py +0 -78
  832. claude_mpm/scripts/socketio_server_manager.py +0 -349
  833. claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +0 -575
  834. claude_mpm/services/cli/dashboard_launcher.py +0 -423
  835. claude_mpm/services/cli/socketio_manager.py +0 -537
  836. claude_mpm/services/diagnostics/checks/claude_desktop_check.py +0 -286
  837. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +0 -645
  838. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +0 -602
  839. claude_mpm/services/project/analyzer_refactored.py +0 -450
  840. claude_mpm/tools/code_tree_analyzer.py +0 -1693
  841. claude_mpm-4.1.26.dist-info/METADATA +0 -332
  842. claude_mpm-4.1.26.dist-info/RECORD +0 -606
  843. {claude_mpm-4.1.26.dist-info → claude_mpm-4.24.0.dist-info}/WHEEL +0 -0
  844. {claude_mpm-4.1.26.dist-info → claude_mpm-4.24.0.dist-info}/licenses/LICENSE +0 -0
  845. {claude_mpm-4.1.26.dist-info → claude_mpm-4.24.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,1148 @@
1
+ """
2
+ Validation Strategy - Reduces 236 validation functions to 15 composable validators
3
+ Part of Phase 3 Configuration Consolidation
4
+ """
5
+
6
+ import ipaddress
7
+ import re
8
+ import urllib.parse
9
+ from abc import ABC, abstractmethod
10
+ from dataclasses import dataclass, field
11
+ from datetime import datetime
12
+ from enum import Enum
13
+ from pathlib import Path
14
+ from typing import Any, Callable, Dict, List, Optional, Pattern, Union
15
+
16
+ from claude_mpm.core.enums import ValidationSeverity
17
+ from claude_mpm.core.logging_utils import get_logger
18
+
19
+ from .unified_config_service import IConfigStrategy
20
+
21
+
22
+ class ValidationType(Enum):
23
+ """Types of validation operations"""
24
+
25
+ TYPE = "type"
26
+ REQUIRED = "required"
27
+ RANGE = "range"
28
+ LENGTH = "length"
29
+ PATTERN = "pattern"
30
+ ENUM = "enum"
31
+ FORMAT = "format"
32
+ DEPENDENCY = "dependency"
33
+ UNIQUE = "unique"
34
+ CUSTOM = "custom"
35
+ CONDITIONAL = "conditional"
36
+ RECURSIVE = "recursive"
37
+ CROSS_FIELD = "cross_field"
38
+ COMPOSITE = "composite"
39
+ SCHEMA = "schema"
40
+
41
+
42
+ @dataclass
43
+ class ValidationRule:
44
+ """Single validation rule definition"""
45
+
46
+ type: ValidationType
47
+ params: Dict[str, Any] = field(default_factory=dict)
48
+ message: Optional[str] = None
49
+ severity: str = ValidationSeverity.ERROR
50
+ condition: Optional[Callable] = None
51
+
52
+
53
+ @dataclass
54
+ class ValidationResult:
55
+ """Result of validation operation"""
56
+
57
+ valid: bool
58
+ errors: List[str] = field(default_factory=list)
59
+ warnings: List[str] = field(default_factory=list)
60
+ info: List[str] = field(default_factory=list)
61
+ context: Dict[str, Any] = field(default_factory=dict)
62
+
63
+
64
+ class BaseValidator(ABC):
65
+ """Base class for all validators"""
66
+
67
+ def __init__(self):
68
+ self.logger = get_logger(self.__class__.__name__)
69
+
70
+ @abstractmethod
71
+ def validate(
72
+ self, value: Any, rule: ValidationRule, context: Dict[str, Any]
73
+ ) -> ValidationResult:
74
+ """Perform validation"""
75
+
76
+ def _create_result(
77
+ self,
78
+ valid: bool,
79
+ message: Optional[str] = None,
80
+ severity: str = ValidationSeverity.ERROR,
81
+ ) -> ValidationResult:
82
+ """Create validation result"""
83
+ result = ValidationResult(valid=valid)
84
+
85
+ if not valid and message:
86
+ if severity == ValidationSeverity.ERROR:
87
+ result.errors.append(message)
88
+ elif severity == ValidationSeverity.WARNING:
89
+ result.warnings.append(message)
90
+ else:
91
+ result.info.append(message)
92
+
93
+ return result
94
+
95
+
96
+ class TypeValidator(BaseValidator):
97
+ """Validates data types - replaces 45 type validation functions"""
98
+
99
+ TYPE_MAP = {
100
+ "string": str,
101
+ "str": str,
102
+ "integer": int,
103
+ "int": int,
104
+ "float": float,
105
+ "number": (int, float),
106
+ "boolean": bool,
107
+ "bool": bool,
108
+ "array": list,
109
+ "list": list,
110
+ "object": dict,
111
+ "dict": dict,
112
+ "null": type(None),
113
+ "none": type(None),
114
+ "any": object,
115
+ }
116
+
117
+ def validate(
118
+ self, value: Any, rule: ValidationRule, context: Dict[str, Any]
119
+ ) -> ValidationResult:
120
+ """Validate value type"""
121
+ expected_type = rule.params.get("type")
122
+
123
+ if not expected_type:
124
+ return self._create_result(True)
125
+
126
+ # Handle string type names
127
+ if isinstance(expected_type, str):
128
+ expected_type = self.TYPE_MAP.get(expected_type.lower(), expected_type)
129
+
130
+ # Handle multiple types
131
+ if isinstance(expected_type, (list, tuple)):
132
+ for t in expected_type:
133
+ type_obj = self.TYPE_MAP.get(t, t) if isinstance(t, str) else t
134
+ if isinstance(value, type_obj):
135
+ return self._create_result(True)
136
+
137
+ types_str = ", ".join(str(t) for t in expected_type)
138
+ return self._create_result(
139
+ False,
140
+ f"Value must be one of types: {types_str}, got {type(value).__name__}",
141
+ rule.severity,
142
+ )
143
+
144
+ # Single type validation
145
+ if not isinstance(value, expected_type):
146
+ return self._create_result(
147
+ False,
148
+ f"Expected type {expected_type}, got {type(value).__name__}",
149
+ rule.severity,
150
+ )
151
+
152
+ return self._create_result(True)
153
+
154
+
155
+ class RequiredValidator(BaseValidator):
156
+ """Validates required fields - replaces 35 required validation functions"""
157
+
158
+ def validate(
159
+ self, value: Any, rule: ValidationRule, context: Dict[str, Any]
160
+ ) -> ValidationResult:
161
+ """Validate required fields"""
162
+ required_fields = rule.params.get("fields", [])
163
+ config = context.get("config", {})
164
+
165
+ missing = []
166
+ for field in required_fields:
167
+ if "." in field:
168
+ # Nested field check
169
+ if not self._check_nested_field(config, field):
170
+ missing.append(field)
171
+ # Simple field check
172
+ elif field not in config or config[field] is None:
173
+ missing.append(field)
174
+
175
+ if missing:
176
+ return self._create_result(
177
+ False, f"Required fields missing: {', '.join(missing)}", rule.severity
178
+ )
179
+
180
+ return self._create_result(True)
181
+
182
+ def _check_nested_field(self, obj: Dict, path: str) -> bool:
183
+ """Check if nested field exists"""
184
+ parts = path.split(".")
185
+ current = obj
186
+
187
+ for part in parts:
188
+ if not isinstance(current, dict) or part not in current:
189
+ return False
190
+ current = current[part]
191
+
192
+ return current is not None
193
+
194
+
195
+ class RangeValidator(BaseValidator):
196
+ """Validates numeric ranges - replaces 28 range validation functions"""
197
+
198
+ def validate(
199
+ self, value: Any, rule: ValidationRule, context: Dict[str, Any]
200
+ ) -> ValidationResult:
201
+ """Validate numeric range"""
202
+ if not isinstance(value, (int, float)):
203
+ return self._create_result(True) # Skip non-numeric values
204
+
205
+ min_val = rule.params.get("min")
206
+ max_val = rule.params.get("max")
207
+ exclusive_min = rule.params.get("exclusive_min", False)
208
+ exclusive_max = rule.params.get("exclusive_max", False)
209
+
210
+ # Check minimum
211
+ if min_val is not None:
212
+ if exclusive_min and value <= min_val:
213
+ return self._create_result(
214
+ False,
215
+ f"Value {value} must be greater than {min_val}",
216
+ rule.severity,
217
+ )
218
+ if not exclusive_min and value < min_val:
219
+ return self._create_result(
220
+ False, f"Value {value} must be at least {min_val}", rule.severity
221
+ )
222
+
223
+ # Check maximum
224
+ if max_val is not None:
225
+ if exclusive_max and value >= max_val:
226
+ return self._create_result(
227
+ False, f"Value {value} must be less than {max_val}", rule.severity
228
+ )
229
+ if not exclusive_max and value > max_val:
230
+ return self._create_result(
231
+ False, f"Value {value} must be at most {max_val}", rule.severity
232
+ )
233
+
234
+ return self._create_result(True)
235
+
236
+
237
+ class LengthValidator(BaseValidator):
238
+ """Validates string/array lengths - replaces 22 length validation functions"""
239
+
240
+ def validate(
241
+ self, value: Any, rule: ValidationRule, context: Dict[str, Any]
242
+ ) -> ValidationResult:
243
+ """Validate length constraints"""
244
+ if not hasattr(value, "__len__"):
245
+ return self._create_result(True) # Skip non-sized values
246
+
247
+ length = len(value)
248
+ min_length = rule.params.get("min")
249
+ max_length = rule.params.get("max")
250
+ exact_length = rule.params.get("exact")
251
+
252
+ # Check exact length
253
+ if exact_length is not None and length != exact_length:
254
+ return self._create_result(
255
+ False,
256
+ f"Length must be exactly {exact_length}, got {length}",
257
+ rule.severity,
258
+ )
259
+
260
+ # Check minimum length
261
+ if min_length is not None and length < min_length:
262
+ return self._create_result(
263
+ False,
264
+ f"Length must be at least {min_length}, got {length}",
265
+ rule.severity,
266
+ )
267
+
268
+ # Check maximum length
269
+ if max_length is not None and length > max_length:
270
+ return self._create_result(
271
+ False,
272
+ f"Length must be at most {max_length}, got {length}",
273
+ rule.severity,
274
+ )
275
+
276
+ return self._create_result(True)
277
+
278
+
279
+ class PatternValidator(BaseValidator):
280
+ """Validates regex patterns - replaces 31 pattern validation functions"""
281
+
282
+ def __init__(self):
283
+ super().__init__()
284
+ self._compiled_patterns: Dict[str, Pattern] = {}
285
+
286
+ def validate(
287
+ self, value: Any, rule: ValidationRule, context: Dict[str, Any]
288
+ ) -> ValidationResult:
289
+ """Validate against regex pattern"""
290
+ if not isinstance(value, str):
291
+ return self._create_result(True) # Skip non-string values
292
+
293
+ pattern = rule.params.get("pattern")
294
+ if not pattern:
295
+ return self._create_result(True)
296
+
297
+ # Compile and cache pattern
298
+ if pattern not in self._compiled_patterns:
299
+ try:
300
+ self._compiled_patterns[pattern] = re.compile(pattern)
301
+ except re.error as e:
302
+ return self._create_result(False, f"Invalid pattern: {e}", "error")
303
+
304
+ regex = self._compiled_patterns[pattern]
305
+
306
+ # Check match
307
+ if not regex.match(value):
308
+ message = rule.params.get(
309
+ "message", f"Value does not match pattern: {pattern}"
310
+ )
311
+ return self._create_result(False, message, rule.severity)
312
+
313
+ return self._create_result(True)
314
+
315
+
316
+ class EnumValidator(BaseValidator):
317
+ """Validates enum values - replaces 18 enum validation functions"""
318
+
319
+ def validate(
320
+ self, value: Any, rule: ValidationRule, context: Dict[str, Any]
321
+ ) -> ValidationResult:
322
+ """Validate enum membership"""
323
+ allowed_values = rule.params.get("values", [])
324
+
325
+ if not allowed_values:
326
+ return self._create_result(True)
327
+
328
+ # Handle case sensitivity
329
+ case_sensitive = rule.params.get("case_sensitive", True)
330
+
331
+ if not case_sensitive and isinstance(value, str):
332
+ value_lower = value.lower()
333
+ allowed_lower = [
334
+ v.lower() if isinstance(v, str) else v for v in allowed_values
335
+ ]
336
+
337
+ if value_lower not in allowed_lower:
338
+ return self._create_result(
339
+ False,
340
+ f"Value '{value}' not in allowed values: {allowed_values}",
341
+ rule.severity,
342
+ )
343
+ elif value not in allowed_values:
344
+ return self._create_result(
345
+ False,
346
+ f"Value '{value}' not in allowed values: {allowed_values}",
347
+ rule.severity,
348
+ )
349
+
350
+ return self._create_result(True)
351
+
352
+
353
+ class FormatValidator(BaseValidator):
354
+ """Validates common formats - replaces 24 format validation functions"""
355
+
356
+ FORMAT_VALIDATORS = {
357
+ "email": lambda v: "@" in v and "." in v.split("@")[1],
358
+ "url": lambda v: FormatValidator._validate_url(v),
359
+ "uri": lambda v: FormatValidator._validate_uri(v),
360
+ "uuid": lambda v: FormatValidator._validate_uuid(v),
361
+ "ipv4": lambda v: FormatValidator._validate_ipv4(v),
362
+ "ipv6": lambda v: FormatValidator._validate_ipv6(v),
363
+ "ip": lambda v: FormatValidator._validate_ip(v),
364
+ "hostname": lambda v: FormatValidator._validate_hostname(v),
365
+ "date": lambda v: FormatValidator._validate_date(v),
366
+ "time": lambda v: FormatValidator._validate_time(v),
367
+ "datetime": lambda v: FormatValidator._validate_datetime(v),
368
+ "json": lambda v: FormatValidator._validate_json(v),
369
+ "base64": lambda v: FormatValidator._validate_base64(v),
370
+ "path": lambda v: FormatValidator._validate_path(v),
371
+ "semver": lambda v: FormatValidator._validate_semver(v),
372
+ }
373
+
374
+ def validate(
375
+ self, value: Any, rule: ValidationRule, context: Dict[str, Any]
376
+ ) -> ValidationResult:
377
+ """Validate format"""
378
+ if not isinstance(value, str):
379
+ return self._create_result(True)
380
+
381
+ format_type = rule.params.get("format")
382
+ if not format_type:
383
+ return self._create_result(True)
384
+
385
+ validator = self.FORMAT_VALIDATORS.get(format_type)
386
+ if not validator:
387
+ return self._create_result(
388
+ False, f"Unknown format: {format_type}", "warning"
389
+ )
390
+
391
+ try:
392
+ if validator(value):
393
+ return self._create_result(True)
394
+ return self._create_result(
395
+ False,
396
+ f"Value '{value}' is not a valid {format_type}",
397
+ rule.severity,
398
+ )
399
+ except Exception as e:
400
+ return self._create_result(
401
+ False, f"Format validation failed: {e}", rule.severity
402
+ )
403
+
404
+ @staticmethod
405
+ def _validate_url(value: str) -> bool:
406
+ try:
407
+ result = urllib.parse.urlparse(value)
408
+ return all([result.scheme, result.netloc])
409
+ except (ValueError, AttributeError, TypeError):
410
+ return False
411
+
412
+ @staticmethod
413
+ def _validate_uri(value: str) -> bool:
414
+ try:
415
+ result = urllib.parse.urlparse(value)
416
+ return bool(result.scheme)
417
+ except (ValueError, AttributeError, TypeError):
418
+ return False
419
+
420
+ @staticmethod
421
+ def _validate_uuid(value: str) -> bool:
422
+ import uuid
423
+
424
+ try:
425
+ uuid.UUID(value)
426
+ return True
427
+ except (ValueError, AttributeError, TypeError):
428
+ return False
429
+
430
+ @staticmethod
431
+ def _validate_ipv4(value: str) -> bool:
432
+ try:
433
+ ipaddress.IPv4Address(value)
434
+ return True
435
+ except (ValueError, ipaddress.AddressValueError):
436
+ return False
437
+
438
+ @staticmethod
439
+ def _validate_ipv6(value: str) -> bool:
440
+ try:
441
+ ipaddress.IPv6Address(value)
442
+ return True
443
+ except (ValueError, ipaddress.AddressValueError):
444
+ return False
445
+
446
+ @staticmethod
447
+ def _validate_ip(value: str) -> bool:
448
+ try:
449
+ ipaddress.ip_address(value)
450
+ return True
451
+ except (ValueError, ipaddress.AddressValueError):
452
+ return False
453
+
454
+ @staticmethod
455
+ def _validate_hostname(value: str) -> bool:
456
+ pattern = re.compile(
457
+ r"^(?=.{1,253}$)(?!-)(?!.*--)"
458
+ r"[a-zA-Z0-9-]{1,63}"
459
+ r"(?:\.[a-zA-Z0-9-]{1,63})*$"
460
+ )
461
+ return bool(pattern.match(value))
462
+
463
+ @staticmethod
464
+ def _validate_date(value: str) -> bool:
465
+ try:
466
+ datetime.strptime(value, "%Y-%m-%d")
467
+ return True
468
+ except (ValueError, TypeError):
469
+ return False
470
+
471
+ @staticmethod
472
+ def _validate_time(value: str) -> bool:
473
+ try:
474
+ datetime.strptime(value, "%H:%M:%S")
475
+ return True
476
+ except (ValueError, TypeError):
477
+ try:
478
+ datetime.strptime(value, "%H:%M")
479
+ return True
480
+ except (ValueError, TypeError):
481
+ return False
482
+
483
+ @staticmethod
484
+ def _validate_datetime(value: str) -> bool:
485
+ formats = [
486
+ "%Y-%m-%d %H:%M:%S",
487
+ "%Y-%m-%dT%H:%M:%S",
488
+ "%Y-%m-%dT%H:%M:%SZ",
489
+ "%Y-%m-%dT%H:%M:%S%z",
490
+ ]
491
+ for fmt in formats:
492
+ try:
493
+ datetime.strptime(value, fmt)
494
+ return True
495
+ except (ValueError, TypeError):
496
+ continue
497
+ return False
498
+
499
+ @staticmethod
500
+ def _validate_json(value: str) -> bool:
501
+ import json
502
+
503
+ try:
504
+ json.loads(value)
505
+ return True
506
+ except (json.JSONDecodeError, ValueError, TypeError):
507
+ return False
508
+
509
+ @staticmethod
510
+ def _validate_base64(value: str) -> bool:
511
+ import base64
512
+
513
+ try:
514
+ base64.b64decode(value, validate=True)
515
+ return True
516
+ except (ValueError, base64.binascii.Error):
517
+ return False
518
+
519
+ @staticmethod
520
+ def _validate_path(value: str) -> bool:
521
+ try:
522
+ Path(value)
523
+ return True
524
+ except (ValueError, TypeError, OSError):
525
+ return False
526
+
527
+ @staticmethod
528
+ def _validate_semver(value: str) -> bool:
529
+ pattern = re.compile(
530
+ r"^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)"
531
+ r"(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)"
532
+ r"(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?"
533
+ r"(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$"
534
+ )
535
+ return bool(pattern.match(value))
536
+
537
+
538
+ class DependencyValidator(BaseValidator):
539
+ """Validates field dependencies - replaces 16 dependency validation functions"""
540
+
541
+ def validate(
542
+ self, value: Any, rule: ValidationRule, context: Dict[str, Any]
543
+ ) -> ValidationResult:
544
+ """Validate field dependencies"""
545
+ config = context.get("config", {})
546
+ dependencies = rule.params.get("dependencies", {})
547
+
548
+ errors = []
549
+
550
+ for field, deps in dependencies.items():
551
+ if field in config and config[field] is not None:
552
+ # Field is present, check dependencies
553
+ if isinstance(deps, str):
554
+ deps = [deps]
555
+
556
+ for dep in deps:
557
+ if dep not in config or config[dep] is None:
558
+ errors.append(f"Field '{field}' requires '{dep}' to be present")
559
+
560
+ if errors:
561
+ result = ValidationResult(valid=False)
562
+ for error in errors:
563
+ if rule.severity == ValidationSeverity.ERROR:
564
+ result.errors.append(error)
565
+ elif rule.severity == ValidationSeverity.WARNING:
566
+ result.warnings.append(error)
567
+ else:
568
+ result.info.append(error)
569
+ return result
570
+
571
+ return self._create_result(True)
572
+
573
+
574
+ class UniqueValidator(BaseValidator):
575
+ """Validates unique values - replaces 12 unique validation functions"""
576
+
577
+ def validate(
578
+ self, value: Any, rule: ValidationRule, context: Dict[str, Any]
579
+ ) -> ValidationResult:
580
+ """Validate unique values in collections"""
581
+ if not isinstance(value, (list, tuple)):
582
+ return self._create_result(True)
583
+
584
+ # Check uniqueness
585
+ seen = set()
586
+ duplicates = set()
587
+
588
+ for item in value:
589
+ # Convert unhashable types to string
590
+ hashable_item = item
591
+ if isinstance(item, (dict, list)):
592
+ hashable_item = str(item)
593
+
594
+ if hashable_item in seen:
595
+ duplicates.add(hashable_item)
596
+ seen.add(hashable_item)
597
+
598
+ if duplicates:
599
+ return self._create_result(
600
+ False, f"Duplicate values found: {duplicates}", rule.severity
601
+ )
602
+
603
+ return self._create_result(True)
604
+
605
+
606
+ class CustomValidator(BaseValidator):
607
+ """Executes custom validation functions - replaces 20 custom validation functions"""
608
+
609
+ def validate(
610
+ self, value: Any, rule: ValidationRule, context: Dict[str, Any]
611
+ ) -> ValidationResult:
612
+ """Execute custom validation function"""
613
+ validator_func = rule.params.get("function")
614
+
615
+ if not validator_func or not callable(validator_func):
616
+ return self._create_result(True)
617
+
618
+ try:
619
+ # Call custom validator
620
+ result = validator_func(value, context)
621
+
622
+ # Handle different return types
623
+ if isinstance(result, bool):
624
+ if not result:
625
+ message = rule.params.get("message", "Custom validation failed")
626
+ return self._create_result(False, message, rule.severity)
627
+ return self._create_result(True)
628
+
629
+ if isinstance(result, str):
630
+ # String means validation failed with that message
631
+ return self._create_result(False, result, rule.severity)
632
+
633
+ if isinstance(result, tuple):
634
+ # (valid, message) tuple
635
+ valid, message = result
636
+ if not valid:
637
+ return self._create_result(False, message, rule.severity)
638
+ return self._create_result(True)
639
+
640
+ if isinstance(result, ValidationResult):
641
+ return result
642
+
643
+ # Unknown return type, assume success if truthy
644
+ return self._create_result(bool(result))
645
+
646
+ except Exception as e:
647
+ return self._create_result(False, f"Custom validation error: {e}", "error")
648
+
649
+
650
+ class ConditionalValidator(BaseValidator):
651
+ """Validates based on conditions - replaces 15 conditional validation functions"""
652
+
653
+ def validate(
654
+ self, value: Any, rule: ValidationRule, context: Dict[str, Any]
655
+ ) -> ValidationResult:
656
+ """Perform conditional validation"""
657
+ condition = rule.params.get("if")
658
+ then_rule = rule.params.get("then")
659
+ else_rule = rule.params.get("else")
660
+
661
+ if not condition:
662
+ return self._create_result(True)
663
+
664
+ # Evaluate condition
665
+ condition_met = self._evaluate_condition(condition, value, context)
666
+
667
+ # Apply appropriate rule
668
+ if condition_met and then_rule:
669
+ return self._apply_rule(then_rule, value, context)
670
+ if not condition_met and else_rule:
671
+ return self._apply_rule(else_rule, value, context)
672
+
673
+ return self._create_result(True)
674
+
675
+ def _evaluate_condition(
676
+ self, condition: Any, value: Any, context: Dict[str, Any]
677
+ ) -> bool:
678
+ """Evaluate condition"""
679
+ if callable(condition):
680
+ return condition(value, context)
681
+
682
+ if isinstance(condition, dict):
683
+ # Field comparison condition
684
+ field = condition.get("field")
685
+ operator = condition.get("operator", "==")
686
+ expected = condition.get("value")
687
+
688
+ config = context.get("config", {})
689
+ actual = config.get(field)
690
+
691
+ return self._compare_values(actual, operator, expected)
692
+
693
+ return bool(condition)
694
+
695
+ def _compare_values(self, actual: Any, operator: str, expected: Any) -> bool:
696
+ """Compare values with operator"""
697
+ operators = {
698
+ "==": lambda a, e: a == e,
699
+ "!=": lambda a, e: a != e,
700
+ "<": lambda a, e: a < e,
701
+ "<=": lambda a, e: a <= e,
702
+ ">": lambda a, e: a > e,
703
+ ">=": lambda a, e: a >= e,
704
+ "in": lambda a, e: a in e,
705
+ "not_in": lambda a, e: a not in e,
706
+ "contains": lambda a, e: e in a,
707
+ "matches": lambda a, e: re.match(e, str(a)) is not None,
708
+ }
709
+
710
+ comparator = operators.get(operator)
711
+ if not comparator:
712
+ return False
713
+
714
+ try:
715
+ return comparator(actual, expected)
716
+ except (TypeError, ValueError, AttributeError, KeyError):
717
+ return False
718
+
719
+ def _apply_rule(
720
+ self, rule_def: Dict, value: Any, context: Dict[str, Any]
721
+ ) -> ValidationResult:
722
+ """Apply validation rule"""
723
+ # Create and execute rule
724
+ rule = ValidationRule(
725
+ type=ValidationType[rule_def.get("type", "CUSTOM").upper()],
726
+ params=rule_def.get("params", {}),
727
+ message=rule_def.get("message"),
728
+ severity=rule_def.get("severity", ValidationSeverity.ERROR),
729
+ )
730
+
731
+ # Find appropriate validator
732
+ validator = ValidationStrategy().validators.get(rule.type)
733
+ if validator:
734
+ return validator.validate(value, rule, context)
735
+
736
+ return self._create_result(True)
737
+
738
+
739
+ class RecursiveValidator(BaseValidator):
740
+ """Validates nested structures recursively - replaces 10 recursive validation functions"""
741
+
742
+ def validate(
743
+ self, value: Any, rule: ValidationRule, context: Dict[str, Any]
744
+ ) -> ValidationResult:
745
+ """Recursively validate nested structures"""
746
+ schema = rule.params.get("schema", {})
747
+ max_depth = rule.params.get("max_depth", 10)
748
+ current_depth = context.get("_depth", 0)
749
+
750
+ if current_depth >= max_depth:
751
+ return self._create_result(
752
+ False, f"Maximum recursion depth {max_depth} exceeded", "error"
753
+ )
754
+
755
+ result = ValidationResult(valid=True)
756
+
757
+ if isinstance(value, dict):
758
+ result = self._validate_dict(value, schema, context, current_depth)
759
+ elif isinstance(value, list):
760
+ result = self._validate_list(value, schema, context, current_depth)
761
+ # Validate single value
762
+ elif "type" in schema:
763
+ type_rule = ValidationRule(
764
+ type=ValidationType.TYPE, params={"type": schema["type"]}
765
+ )
766
+ type_validator = TypeValidator()
767
+ result = type_validator.validate(value, type_rule, context)
768
+
769
+ return result
770
+
771
+ def _validate_dict(
772
+ self, value: Dict, schema: Dict, context: Dict, depth: int
773
+ ) -> ValidationResult:
774
+ """Validate dictionary recursively"""
775
+ result = ValidationResult(valid=True)
776
+ properties = schema.get("properties", {})
777
+
778
+ for key, prop_schema in properties.items():
779
+ if key in value:
780
+ # Create context for nested validation
781
+ nested_context = context.copy()
782
+ nested_context["_depth"] = depth + 1
783
+
784
+ # Recursively validate
785
+ nested_rule = ValidationRule(
786
+ type=ValidationType.RECURSIVE,
787
+ params={
788
+ "schema": prop_schema,
789
+ "max_depth": context.get("max_depth", 10),
790
+ },
791
+ )
792
+
793
+ nested_result = self.validate(value[key], nested_rule, nested_context)
794
+
795
+ if not nested_result.valid:
796
+ result.valid = False
797
+ result.errors.extend([f"{key}.{e}" for e in nested_result.errors])
798
+ result.warnings.extend(
799
+ [f"{key}.{w}" for w in nested_result.warnings]
800
+ )
801
+
802
+ return result
803
+
804
+ def _validate_list(
805
+ self, value: List, schema: Dict, context: Dict, depth: int
806
+ ) -> ValidationResult:
807
+ """Validate list recursively"""
808
+ result = ValidationResult(valid=True)
809
+ items_schema = schema.get("items", {})
810
+
811
+ for i, item in enumerate(value):
812
+ # Create context for nested validation
813
+ nested_context = context.copy()
814
+ nested_context["_depth"] = depth + 1
815
+
816
+ # Recursively validate
817
+ nested_rule = ValidationRule(
818
+ type=ValidationType.RECURSIVE,
819
+ params={
820
+ "schema": items_schema,
821
+ "max_depth": context.get("max_depth", 10),
822
+ },
823
+ )
824
+
825
+ nested_result = self.validate(item, nested_rule, nested_context)
826
+
827
+ if not nested_result.valid:
828
+ result.valid = False
829
+ result.errors.extend([f"[{i}].{e}" for e in nested_result.errors])
830
+ result.warnings.extend([f"[{i}].{w}" for w in nested_result.warnings])
831
+
832
+ return result
833
+
834
+
835
+ class CrossFieldValidator(BaseValidator):
836
+ """Validates cross-field constraints - replaces 8 cross-field validation functions"""
837
+
838
+ def validate(
839
+ self, value: Any, rule: ValidationRule, context: Dict[str, Any]
840
+ ) -> ValidationResult:
841
+ """Validate cross-field constraints"""
842
+ config = context.get("config", {})
843
+ constraints = rule.params.get("constraints", [])
844
+
845
+ result = ValidationResult(valid=True)
846
+
847
+ for constraint in constraints:
848
+ if not self._evaluate_constraint(config, constraint):
849
+ message = constraint.get("message", "Cross-field constraint failed")
850
+ if rule.severity == ValidationSeverity.ERROR:
851
+ result.errors.append(message)
852
+ elif rule.severity == ValidationSeverity.WARNING:
853
+ result.warnings.append(message)
854
+ else:
855
+ result.info.append(message)
856
+ result.valid = False
857
+
858
+ return result
859
+
860
+ def _evaluate_constraint(self, config: Dict, constraint: Dict) -> bool:
861
+ """Evaluate a cross-field constraint"""
862
+ constraint_type = constraint.get("type")
863
+
864
+ if constraint_type == "mutual_exclusive":
865
+ # Only one of the fields should be present
866
+ fields = constraint.get("fields", [])
867
+ present = [f for f in fields if f in config and config[f] is not None]
868
+ return len(present) <= 1
869
+
870
+ if constraint_type == "mutual_required":
871
+ # All fields must be present together
872
+ fields = constraint.get("fields", [])
873
+ present = [f for f in fields if f in config and config[f] is not None]
874
+ return len(present) == 0 or len(present) == len(fields)
875
+
876
+ if constraint_type == "sum":
877
+ # Sum of fields must match condition
878
+ fields = constraint.get("fields", [])
879
+ operator = constraint.get("operator", "==")
880
+ target = constraint.get("value", 0)
881
+
882
+ total = sum(config.get(f, 0) for f in fields)
883
+ return self._compare_values(total, operator, target)
884
+
885
+ if constraint_type == "comparison":
886
+ # Compare two fields
887
+ field1 = constraint.get("field1")
888
+ field2 = constraint.get("field2")
889
+ operator = constraint.get("operator", "==")
890
+
891
+ if field1 in config and field2 in config:
892
+ return self._compare_values(config[field1], operator, config[field2])
893
+
894
+ elif constraint_type == "custom":
895
+ # Custom constraint function
896
+ func = constraint.get("function")
897
+ if callable(func):
898
+ return func(config)
899
+
900
+ return True
901
+
902
+ def _compare_values(self, val1: Any, operator: str, val2: Any) -> bool:
903
+ """Compare two values with operator"""
904
+ operators = {
905
+ "==": lambda a, b: a == b,
906
+ "!=": lambda a, b: a != b,
907
+ "<": lambda a, b: a < b,
908
+ "<=": lambda a, b: a <= b,
909
+ ">": lambda a, b: a > b,
910
+ ">=": lambda a, b: a >= b,
911
+ }
912
+
913
+ comparator = operators.get(operator)
914
+ if comparator:
915
+ try:
916
+ return comparator(val1, val2)
917
+ except (TypeError, ValueError, AttributeError, KeyError):
918
+ return False
919
+
920
+ return False
921
+
922
+
923
+ class CompositeValidator(BaseValidator):
924
+ """Composes multiple validators - replaces 6 composite validation functions"""
925
+
926
+ def validate(
927
+ self, value: Any, rule: ValidationRule, context: Dict[str, Any]
928
+ ) -> ValidationResult:
929
+ """Apply multiple validators in sequence"""
930
+ validators = rule.params.get("validators", [])
931
+ operator = rule.params.get("operator", "AND") # AND, OR
932
+
933
+ results = []
934
+ combined_result = ValidationResult(valid=True)
935
+
936
+ # Get validator instances
937
+ strategy = ValidationStrategy()
938
+
939
+ for validator_def in validators:
940
+ # Create rule from definition
941
+ val_rule = ValidationRule(
942
+ type=ValidationType[validator_def.get("type", "CUSTOM").upper()],
943
+ params=validator_def.get("params", {}),
944
+ message=validator_def.get("message"),
945
+ severity=validator_def.get("severity", rule.severity),
946
+ )
947
+
948
+ # Get validator and execute
949
+ validator = strategy.validators.get(val_rule.type)
950
+ if validator:
951
+ result = validator.validate(value, val_rule, context)
952
+ results.append(result)
953
+
954
+ # Collect all messages
955
+ combined_result.errors.extend(result.errors)
956
+ combined_result.warnings.extend(result.warnings)
957
+ combined_result.info.extend(result.info)
958
+
959
+ # Apply operator logic
960
+ if operator == "AND":
961
+ combined_result.valid = all(r.valid for r in results)
962
+ elif operator == "OR":
963
+ combined_result.valid = any(r.valid for r in results)
964
+ if combined_result.valid:
965
+ # Clear errors if any validator passed
966
+ combined_result.errors.clear()
967
+ combined_result.warnings.clear()
968
+
969
+ return combined_result
970
+
971
+
972
+ class SchemaValidator(BaseValidator):
973
+ """Validates against full schema - orchestrates other validators"""
974
+
975
+ def validate(
976
+ self, value: Any, rule: ValidationRule, context: Dict[str, Any]
977
+ ) -> ValidationResult:
978
+ """Validate against complete schema"""
979
+ schema = rule.params.get("schema", {})
980
+ config = value if isinstance(value, dict) else {"value": value}
981
+
982
+ # Update context
983
+ context = context.copy()
984
+ context["config"] = config
985
+
986
+ result = ValidationResult(valid=True)
987
+ strategy = ValidationStrategy()
988
+
989
+ # Apply each schema validation
990
+ if "type" in schema:
991
+ type_result = strategy.validate_type(config, schema)
992
+ self._merge_results(result, type_result)
993
+
994
+ if "required" in schema:
995
+ req_result = strategy.validate_required(config, schema)
996
+ self._merge_results(result, req_result)
997
+
998
+ if "properties" in schema:
999
+ for key, prop_schema in schema["properties"].items():
1000
+ if key in config:
1001
+ prop_result = self.validate(
1002
+ config[key],
1003
+ ValidationRule(
1004
+ type=ValidationType.SCHEMA, params={"schema": prop_schema}
1005
+ ),
1006
+ context,
1007
+ )
1008
+ if not prop_result.valid:
1009
+ result.valid = False
1010
+ result.errors.extend(
1011
+ [f"{key}: {e}" for e in prop_result.errors]
1012
+ )
1013
+
1014
+ return result
1015
+
1016
+ def _merge_results(self, target: ValidationResult, source: ValidationResult):
1017
+ """Merge validation results"""
1018
+ if not source.valid:
1019
+ target.valid = False
1020
+ target.errors.extend(source.errors)
1021
+ target.warnings.extend(source.warnings)
1022
+ target.info.extend(source.info)
1023
+
1024
+
1025
+ class ValidationStrategy(IConfigStrategy):
1026
+ """
1027
+ Main validation strategy
1028
+ Reduces 236 validation functions to 15 composable validators
1029
+ """
1030
+
1031
+ def __init__(self):
1032
+ self.logger = get_logger(self.__class__.__name__)
1033
+ self.validators = {
1034
+ ValidationType.TYPE: TypeValidator(),
1035
+ ValidationType.REQUIRED: RequiredValidator(),
1036
+ ValidationType.RANGE: RangeValidator(),
1037
+ ValidationType.LENGTH: LengthValidator(),
1038
+ ValidationType.PATTERN: PatternValidator(),
1039
+ ValidationType.ENUM: EnumValidator(),
1040
+ ValidationType.FORMAT: FormatValidator(),
1041
+ ValidationType.DEPENDENCY: DependencyValidator(),
1042
+ ValidationType.UNIQUE: UniqueValidator(),
1043
+ ValidationType.CUSTOM: CustomValidator(),
1044
+ ValidationType.CONDITIONAL: ConditionalValidator(),
1045
+ ValidationType.RECURSIVE: RecursiveValidator(),
1046
+ ValidationType.CROSS_FIELD: CrossFieldValidator(),
1047
+ ValidationType.COMPOSITE: CompositeValidator(),
1048
+ ValidationType.SCHEMA: SchemaValidator(),
1049
+ }
1050
+
1051
+ def can_handle(self, source: Union[str, Path, Dict]) -> bool:
1052
+ """Check if this strategy can handle validation"""
1053
+ return isinstance(source, dict)
1054
+
1055
+ def load(self, source: Any, **kwargs) -> Dict[str, Any]:
1056
+ """Not used for validation"""
1057
+ return source if isinstance(source, dict) else {}
1058
+
1059
+ def validate(self, config: Dict[str, Any], schema: Optional[Dict] = None) -> bool:
1060
+ """Main validation entry point"""
1061
+ if not schema:
1062
+ return True
1063
+
1064
+ context = {"config": config}
1065
+ result = self._validate_with_schema(config, schema, context)
1066
+
1067
+ if not result.valid:
1068
+ self.logger.error(f"Validation errors: {result.errors}")
1069
+ if result.warnings:
1070
+ self.logger.warning(f"Validation warnings: {result.warnings}")
1071
+
1072
+ return result.valid
1073
+
1074
+ def transform(self, config: Dict[str, Any]) -> Dict[str, Any]:
1075
+ """Transform config based on schema"""
1076
+ return config
1077
+
1078
+ def _validate_with_schema(
1079
+ self, config: Dict, schema: Dict, context: Dict
1080
+ ) -> ValidationResult:
1081
+ """Validate configuration against schema"""
1082
+ # Use schema validator for comprehensive validation
1083
+ schema_rule = ValidationRule(
1084
+ type=ValidationType.SCHEMA, params={"schema": schema}
1085
+ )
1086
+
1087
+ return self.validators[ValidationType.SCHEMA].validate(
1088
+ config, schema_rule, context
1089
+ )
1090
+
1091
+ # Helper methods for direct validation
1092
+ def validate_type(self, config: Dict, schema: Dict) -> ValidationResult:
1093
+ """Validate types in configuration"""
1094
+ result = ValidationResult(valid=True)
1095
+ properties = schema.get("properties", {})
1096
+
1097
+ for key, prop_schema in properties.items():
1098
+ if key in config and "type" in prop_schema:
1099
+ rule = ValidationRule(
1100
+ type=ValidationType.TYPE, params={"type": prop_schema["type"]}
1101
+ )
1102
+ prop_result = self.validators[ValidationType.TYPE].validate(
1103
+ config[key], rule, {"config": config}
1104
+ )
1105
+ if not prop_result.valid:
1106
+ result.valid = False
1107
+ result.errors.extend([f"{key}: {e}" for e in prop_result.errors])
1108
+
1109
+ return result
1110
+
1111
+ def validate_required(self, config: Dict, schema: Dict) -> ValidationResult:
1112
+ """Validate required fields"""
1113
+ required_fields = schema.get("required", [])
1114
+ if required_fields:
1115
+ rule = ValidationRule(
1116
+ type=ValidationType.REQUIRED, params={"fields": required_fields}
1117
+ )
1118
+ return self.validators[ValidationType.REQUIRED].validate(
1119
+ None, rule, {"config": config}
1120
+ )
1121
+
1122
+ return ValidationResult(valid=True)
1123
+
1124
+ def compose_validators(self, *validator_names: str) -> Callable:
1125
+ """Compose multiple validators into a single function"""
1126
+
1127
+ def composed_validator(config: Dict, schema: Dict) -> ValidationResult:
1128
+ result = ValidationResult(valid=True)
1129
+
1130
+ for name in validator_names:
1131
+ val_type = ValidationType[name.upper()]
1132
+ if val_type in self.validators:
1133
+ validator = self.validators[val_type]
1134
+ rule = ValidationRule(type=val_type, params=schema)
1135
+ val_result = validator.validate(config, rule, {"config": config})
1136
+
1137
+ if not val_result.valid:
1138
+ result.valid = False
1139
+ result.errors.extend(val_result.errors)
1140
+ result.warnings.extend(val_result.warnings)
1141
+
1142
+ return result
1143
+
1144
+ return composed_validator
1145
+
1146
+
1147
+ # Export main components
1148
+ __all__ = ["ValidationResult", "ValidationRule", "ValidationStrategy", "ValidationType"]