claude-mpm 3.4.10__py3-none-any.whl → 5.4.55__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (950) hide show
  1. claude_mpm/BUILD_NUMBER +1 -0
  2. claude_mpm/VERSION +1 -0
  3. claude_mpm/__init__.py +50 -12
  4. claude_mpm/__main__.py +7 -2
  5. claude_mpm/agents/BASE_AGENT.md +164 -0
  6. claude_mpm/agents/BASE_ENGINEER.md +658 -0
  7. claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +290 -0
  8. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +2002 -0
  9. claude_mpm/agents/MEMORY.md +72 -0
  10. claude_mpm/agents/PM_INSTRUCTIONS.md +1402 -0
  11. claude_mpm/agents/WORKFLOW.md +111 -0
  12. claude_mpm/agents/__init__.py +92 -80
  13. claude_mpm/agents/agent-template.yaml +83 -0
  14. claude_mpm/agents/agent_loader.py +560 -745
  15. claude_mpm/agents/agent_loader_integration.py +53 -55
  16. claude_mpm/agents/agents_metadata.py +186 -27
  17. claude_mpm/agents/async_agent_loader.py +436 -0
  18. claude_mpm/agents/base_agent.json +8 -4
  19. claude_mpm/agents/frontmatter_validator.py +754 -0
  20. claude_mpm/agents/system_agent_config.py +222 -155
  21. claude_mpm/agents/templates/README.md +465 -0
  22. claude_mpm/agents/templates/__init__.py +17 -13
  23. claude_mpm/agents/templates/circuit-breakers.md +1391 -0
  24. claude_mpm/agents/templates/context-management-examples.md +544 -0
  25. claude_mpm/agents/templates/git-file-tracking.md +584 -0
  26. claude_mpm/agents/templates/pm-examples.md +474 -0
  27. claude_mpm/agents/templates/pm-red-flags.md +310 -0
  28. claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
  29. claude_mpm/agents/templates/research-gate-examples.md +669 -0
  30. claude_mpm/agents/templates/response-format.md +583 -0
  31. claude_mpm/agents/templates/structured-questions-examples.md +615 -0
  32. claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
  33. claude_mpm/agents/templates/ticketing-examples.md +277 -0
  34. claude_mpm/agents/templates/validation-templates.md +312 -0
  35. claude_mpm/cli/__init__.py +90 -128
  36. claude_mpm/cli/__main__.py +33 -0
  37. claude_mpm/cli/chrome_devtools_installer.py +175 -0
  38. claude_mpm/cli/commands/__init__.py +36 -12
  39. claude_mpm/cli/commands/agent_manager.py +1403 -0
  40. claude_mpm/cli/commands/agent_source.py +774 -0
  41. claude_mpm/cli/commands/agent_state_manager.py +335 -0
  42. claude_mpm/cli/commands/agents.py +2503 -168
  43. claude_mpm/cli/commands/agents_cleanup.py +210 -0
  44. claude_mpm/cli/commands/agents_discover.py +338 -0
  45. claude_mpm/cli/commands/aggregate.py +540 -0
  46. claude_mpm/cli/commands/analyze.py +553 -0
  47. claude_mpm/cli/commands/analyze_code.py +528 -0
  48. claude_mpm/cli/commands/auto_configure.py +1053 -0
  49. claude_mpm/cli/commands/cleanup.py +588 -0
  50. claude_mpm/cli/commands/cleanup_orphaned_agents.py +150 -0
  51. claude_mpm/cli/commands/config.py +586 -0
  52. claude_mpm/cli/commands/configure.py +2654 -0
  53. claude_mpm/cli/commands/configure_agent_display.py +282 -0
  54. claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
  55. claude_mpm/cli/commands/configure_hook_manager.py +225 -0
  56. claude_mpm/cli/commands/configure_models.py +18 -0
  57. claude_mpm/cli/commands/configure_navigation.py +184 -0
  58. claude_mpm/cli/commands/configure_paths.py +104 -0
  59. claude_mpm/cli/commands/configure_persistence.py +254 -0
  60. claude_mpm/cli/commands/configure_startup_manager.py +646 -0
  61. claude_mpm/cli/commands/configure_template_editor.py +497 -0
  62. claude_mpm/cli/commands/configure_validators.py +73 -0
  63. claude_mpm/cli/commands/dashboard.py +286 -0
  64. claude_mpm/cli/commands/debug.py +1386 -0
  65. claude_mpm/cli/commands/doctor.py +243 -0
  66. claude_mpm/cli/commands/hook_errors.py +277 -0
  67. claude_mpm/cli/commands/info.py +195 -74
  68. claude_mpm/cli/commands/local_deploy.py +534 -0
  69. claude_mpm/cli/commands/mcp.py +205 -0
  70. claude_mpm/cli/commands/mcp_command_router.py +161 -0
  71. claude_mpm/cli/commands/mcp_config.py +154 -0
  72. claude_mpm/cli/commands/mcp_config_commands.py +20 -0
  73. claude_mpm/cli/commands/mcp_external_commands.py +249 -0
  74. claude_mpm/cli/commands/mcp_install_commands.py +346 -0
  75. claude_mpm/cli/commands/mcp_pipx_config.py +208 -0
  76. claude_mpm/cli/commands/mcp_server_commands.py +155 -0
  77. claude_mpm/cli/commands/mcp_setup_external.py +868 -0
  78. claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
  79. claude_mpm/cli/commands/memory.py +585 -846
  80. claude_mpm/cli/commands/monitor.py +228 -310
  81. claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
  82. claude_mpm/cli/commands/mpm_init/core.py +759 -0
  83. claude_mpm/cli/commands/mpm_init/display.py +341 -0
  84. claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
  85. claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
  86. claude_mpm/cli/commands/mpm_init/modes.py +397 -0
  87. claude_mpm/cli/commands/mpm_init/prompts.py +722 -0
  88. claude_mpm/cli/commands/mpm_init_cli.py +396 -0
  89. claude_mpm/cli/commands/mpm_init_handler.py +195 -0
  90. claude_mpm/cli/commands/postmortem.py +401 -0
  91. claude_mpm/cli/commands/profile.py +276 -0
  92. claude_mpm/cli/commands/run.py +910 -488
  93. claude_mpm/cli/commands/search.py +458 -0
  94. claude_mpm/cli/commands/skill_source.py +694 -0
  95. claude_mpm/cli/commands/skills.py +1246 -0
  96. claude_mpm/cli/commands/summarize.py +413 -0
  97. claude_mpm/cli/commands/tickets.py +536 -53
  98. claude_mpm/cli/commands/uninstall.py +176 -0
  99. claude_mpm/cli/commands/upgrade.py +152 -0
  100. claude_mpm/cli/commands/verify.py +119 -0
  101. claude_mpm/cli/executor.py +297 -0
  102. claude_mpm/cli/helpers.py +105 -0
  103. claude_mpm/cli/interactive/__init__.py +21 -0
  104. claude_mpm/cli/interactive/agent_wizard.py +1947 -0
  105. claude_mpm/cli/interactive/skills_wizard.py +491 -0
  106. claude_mpm/cli/parser.py +87 -563
  107. claude_mpm/cli/parsers/__init__.py +35 -0
  108. claude_mpm/cli/parsers/agent_manager_parser.py +393 -0
  109. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  110. claude_mpm/cli/parsers/agents_parser.py +575 -0
  111. claude_mpm/cli/parsers/analyze_code_parser.py +170 -0
  112. claude_mpm/cli/parsers/analyze_parser.py +135 -0
  113. claude_mpm/cli/parsers/auto_configure_parser.py +120 -0
  114. claude_mpm/cli/parsers/base_parser.py +644 -0
  115. claude_mpm/cli/parsers/config_parser.py +208 -0
  116. claude_mpm/cli/parsers/configure_parser.py +138 -0
  117. claude_mpm/cli/parsers/dashboard_parser.py +113 -0
  118. claude_mpm/cli/parsers/debug_parser.py +319 -0
  119. claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
  120. claude_mpm/cli/parsers/mcp_parser.py +195 -0
  121. claude_mpm/cli/parsers/memory_parser.py +138 -0
  122. claude_mpm/cli/parsers/monitor_parser.py +142 -0
  123. claude_mpm/cli/parsers/mpm_init_parser.py +311 -0
  124. claude_mpm/cli/parsers/profile_parser.py +147 -0
  125. claude_mpm/cli/parsers/run_parser.py +157 -0
  126. claude_mpm/cli/parsers/search_parser.py +245 -0
  127. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  128. claude_mpm/cli/parsers/skills_parser.py +277 -0
  129. claude_mpm/cli/parsers/source_parser.py +138 -0
  130. claude_mpm/cli/parsers/tickets_parser.py +203 -0
  131. claude_mpm/cli/shared/__init__.py +40 -0
  132. claude_mpm/cli/shared/argument_patterns.py +205 -0
  133. claude_mpm/cli/shared/base_command.py +242 -0
  134. claude_mpm/cli/shared/error_handling.py +242 -0
  135. claude_mpm/cli/shared/output_formatters.py +241 -0
  136. claude_mpm/cli/startup.py +1743 -0
  137. claude_mpm/cli/startup_display.py +480 -0
  138. claude_mpm/cli/startup_logging.py +839 -0
  139. claude_mpm/cli/utils.py +136 -47
  140. claude_mpm/cli_module/__init__.py +6 -6
  141. claude_mpm/cli_module/args.py +188 -140
  142. claude_mpm/cli_module/commands.py +79 -70
  143. claude_mpm/cli_module/migration_example.py +42 -64
  144. claude_mpm/commands/__init__.py +14 -0
  145. claude_mpm/commands/mpm-config.md +28 -0
  146. claude_mpm/commands/mpm-doctor.md +20 -0
  147. claude_mpm/commands/mpm-help.md +20 -0
  148. claude_mpm/commands/mpm-init.md +120 -0
  149. claude_mpm/commands/mpm-monitor.md +31 -0
  150. claude_mpm/commands/mpm-organize.md +120 -0
  151. claude_mpm/commands/mpm-postmortem.md +21 -0
  152. claude_mpm/commands/mpm-session-resume.md +30 -0
  153. claude_mpm/commands/mpm-status.md +20 -0
  154. claude_mpm/commands/mpm-ticket-view.md +109 -0
  155. claude_mpm/commands/mpm-version.md +20 -0
  156. claude_mpm/commands/mpm.md +31 -0
  157. claude_mpm/config/__init__.py +42 -2
  158. claude_mpm/config/agent_config.py +402 -0
  159. claude_mpm/config/agent_presets.py +488 -0
  160. claude_mpm/config/agent_sources.py +352 -0
  161. claude_mpm/config/experimental_features.py +217 -0
  162. claude_mpm/config/model_config.py +428 -0
  163. claude_mpm/config/paths.py +258 -0
  164. claude_mpm/config/skill_presets.py +392 -0
  165. claude_mpm/config/skill_sources.py +590 -0
  166. claude_mpm/config/socketio_config.py +125 -83
  167. claude_mpm/constants.py +132 -22
  168. claude_mpm/core/__init__.py +62 -36
  169. claude_mpm/core/agent_name_normalizer.py +71 -73
  170. claude_mpm/core/agent_registry.py +385 -492
  171. claude_mpm/core/agent_session_manager.py +81 -70
  172. claude_mpm/core/api_validator.py +330 -0
  173. claude_mpm/core/base_service.py +159 -122
  174. claude_mpm/core/cache.py +560 -0
  175. claude_mpm/core/claude_runner.py +696 -916
  176. claude_mpm/core/config.py +613 -122
  177. claude_mpm/core/config_aliases.py +74 -73
  178. claude_mpm/core/config_constants.py +314 -0
  179. claude_mpm/core/constants.py +361 -0
  180. claude_mpm/core/container.py +646 -104
  181. claude_mpm/core/enums.py +452 -0
  182. claude_mpm/core/error_handler.py +623 -0
  183. claude_mpm/core/exceptions.py +536 -0
  184. claude_mpm/core/factories.py +105 -109
  185. claude_mpm/core/file_utils.py +764 -0
  186. claude_mpm/core/framework/__init__.py +25 -0
  187. claude_mpm/core/framework/formatters/__init__.py +11 -0
  188. claude_mpm/core/framework/formatters/capability_generator.py +367 -0
  189. claude_mpm/core/framework/formatters/content_formatter.py +278 -0
  190. claude_mpm/core/framework/formatters/context_generator.py +185 -0
  191. claude_mpm/core/framework/loaders/__init__.py +13 -0
  192. claude_mpm/core/framework/loaders/agent_loader.py +213 -0
  193. claude_mpm/core/framework/loaders/file_loader.py +176 -0
  194. claude_mpm/core/framework/loaders/instruction_loader.py +222 -0
  195. claude_mpm/core/framework/loaders/packaged_loader.py +232 -0
  196. claude_mpm/core/framework/processors/__init__.py +11 -0
  197. claude_mpm/core/framework/processors/memory_processor.py +230 -0
  198. claude_mpm/core/framework/processors/metadata_processor.py +146 -0
  199. claude_mpm/core/framework/processors/template_processor.py +244 -0
  200. claude_mpm/core/framework_loader.py +485 -414
  201. claude_mpm/core/hook_error_memory.py +381 -0
  202. claude_mpm/core/hook_manager.py +246 -86
  203. claude_mpm/core/hook_performance_config.py +147 -0
  204. claude_mpm/core/injectable_service.py +72 -63
  205. claude_mpm/core/instruction_reinforcement_hook.py +267 -0
  206. claude_mpm/core/interactive_session.py +670 -0
  207. claude_mpm/core/interfaces.py +570 -164
  208. claude_mpm/core/lazy.py +467 -0
  209. claude_mpm/core/log_manager.py +707 -0
  210. claude_mpm/core/logger.py +295 -134
  211. claude_mpm/core/logging_config.py +474 -0
  212. claude_mpm/core/logging_utils.py +520 -0
  213. claude_mpm/core/minimal_framework_loader.py +24 -22
  214. claude_mpm/core/mixins.py +30 -29
  215. claude_mpm/core/oneshot_session.py +594 -0
  216. claude_mpm/core/optimized_agent_loader.py +479 -0
  217. claude_mpm/core/optimized_startup.py +554 -0
  218. claude_mpm/core/output_style_manager.py +483 -0
  219. claude_mpm/core/pm_hook_interceptor.py +197 -82
  220. claude_mpm/core/protocols/__init__.py +23 -0
  221. claude_mpm/core/protocols/runner_protocol.py +103 -0
  222. claude_mpm/core/protocols/session_protocol.py +131 -0
  223. claude_mpm/core/service_registry.py +153 -116
  224. claude_mpm/core/session_manager.py +179 -64
  225. claude_mpm/core/shared/__init__.py +17 -0
  226. claude_mpm/core/shared/config_loader.py +326 -0
  227. claude_mpm/core/shared/path_resolver.py +281 -0
  228. claude_mpm/core/shared/singleton_manager.py +221 -0
  229. claude_mpm/core/socketio_pool.py +400 -137
  230. claude_mpm/core/system_context.py +38 -0
  231. claude_mpm/core/tool_access_control.py +64 -57
  232. claude_mpm/core/types.py +307 -0
  233. claude_mpm/core/typing_utils.py +553 -0
  234. claude_mpm/core/unified_agent_registry.py +969 -0
  235. claude_mpm/core/unified_config.py +570 -0
  236. claude_mpm/core/unified_paths.py +941 -0
  237. claude_mpm/dashboard/__init__.py +12 -0
  238. claude_mpm/dashboard/api/simple_directory.py +261 -0
  239. claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
  240. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +1 -0
  241. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +1 -0
  242. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/4TdZjIqw.js +1 -0
  243. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +24 -0
  244. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B0uc0UOD.js +36 -0
  245. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7RN905-.js +1 -0
  246. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7xVLGWV.js +2 -0
  247. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BIF9m_hv.js +61 -0
  248. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +1 -0
  249. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BPYeabCQ.js +1 -0
  250. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
  251. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BSNlmTZj.js +1 -0
  252. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Be7GpZd6.js +7 -0
  253. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bh0LDWpI.js +145 -0
  254. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BofRWZRR.js +10 -0
  255. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BovzEFCE.js +30 -0
  256. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C30mlcqg.js +165 -0
  257. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4B-KCzX.js +1 -0
  258. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4JcI4KD.js +122 -0
  259. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CBBdVcY8.js +1 -0
  260. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CDuw-vjf.js +1 -0
  261. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C_Usid8X.js +15 -0
  262. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cfqx1Qun.js +10 -0
  263. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CiIAseT4.js +128 -0
  264. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
  265. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CnA0NrzZ.js +1 -0
  266. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cs_tUR18.js +24 -0
  267. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
  268. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CyWMqx4W.js +43 -0
  269. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzZX-COe.js +220 -0
  270. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzeYkLYB.js +65 -0
  271. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D3k0OPJN.js +4 -0
  272. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9lljYKQ.js +1 -0
  273. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DGkLK5U1.js +267 -0
  274. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DI7hHRFL.js +1 -0
  275. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DLVjFsZ3.js +139 -0
  276. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUrLdbGD.js +89 -0
  277. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
  278. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DY1XQ8fi.js +2 -0
  279. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DZX00Y4g.js +1 -0
  280. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +1 -0
  281. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DaimHw_p.js +68 -0
  282. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +323 -0
  283. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dhb8PKl3.js +1 -0
  284. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dle-35c7.js +64 -0
  285. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DmxopI1J.js +1 -0
  286. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DwBR2MJi.js +60 -0
  287. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/GYwsonyD.js +1 -0
  288. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
  289. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/NqQ1dWOy.js +1 -0
  290. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/RJiighC3.js +1 -0
  291. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Vzk33B_K.js +2 -0
  292. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ZGh7QtNv.js +7 -0
  293. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bT1r9zLR.js +1 -0
  294. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bTOqqlTd.js +1 -0
  295. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/eNVUfhuA.js +1 -0
  296. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/iEWssX7S.js +162 -0
  297. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/sQeU3Y1z.js +1 -0
  298. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uuIeMWc-.js +1 -0
  299. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.D6-I5TpK.js +2 -0
  300. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +1 -0
  301. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.m1gL8KXf.js +1 -0
  302. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.CgNOuw-d.js +1 -0
  303. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +1 -0
  304. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
  305. claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
  306. claude_mpm/dashboard/static/svelte-build/index.html +36 -0
  307. claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
  308. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
  309. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
  310. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
  311. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
  312. claude_mpm/experimental/__init__.py +10 -0
  313. claude_mpm/experimental/cli_enhancements.py +104 -89
  314. claude_mpm/generators/__init__.py +1 -1
  315. claude_mpm/generators/agent_profile_generator.py +76 -66
  316. claude_mpm/hooks/__init__.py +37 -1
  317. claude_mpm/hooks/base_hook.py +37 -32
  318. claude_mpm/hooks/claude_hooks/__init__.py +1 -1
  319. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  320. claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
  321. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  322. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  323. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  324. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  325. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  326. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
  327. claude_mpm/hooks/claude_hooks/connection_pool.py +250 -0
  328. claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
  329. claude_mpm/hooks/claude_hooks/event_handlers.py +888 -0
  330. claude_mpm/hooks/claude_hooks/hook_handler.py +652 -875
  331. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +10 -7
  332. claude_mpm/hooks/claude_hooks/installer.py +806 -0
  333. claude_mpm/hooks/claude_hooks/memory_integration.py +249 -0
  334. claude_mpm/hooks/claude_hooks/response_tracking.py +412 -0
  335. claude_mpm/hooks/claude_hooks/services/__init__.py +15 -0
  336. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  337. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  338. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
  339. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  340. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  341. claude_mpm/hooks/claude_hooks/services/connection_manager.py +229 -0
  342. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +254 -0
  343. claude_mpm/hooks/claude_hooks/services/duplicate_detector.py +106 -0
  344. claude_mpm/hooks/claude_hooks/services/state_manager.py +284 -0
  345. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +374 -0
  346. claude_mpm/hooks/claude_hooks/tool_analysis.py +224 -0
  347. claude_mpm/hooks/failure_learning/__init__.py +54 -0
  348. claude_mpm/hooks/failure_learning/failure_detection_hook.py +230 -0
  349. claude_mpm/hooks/failure_learning/fix_detection_hook.py +212 -0
  350. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +281 -0
  351. claude_mpm/hooks/instruction_reinforcement.py +301 -0
  352. claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
  353. claude_mpm/hooks/kuzu_memory_hook.py +386 -0
  354. claude_mpm/hooks/kuzu_response_hook.py +179 -0
  355. claude_mpm/hooks/memory_integration_hook.py +201 -107
  356. claude_mpm/hooks/session_resume_hook.py +121 -0
  357. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  358. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  359. claude_mpm/hooks/tool_call_interceptor.py +92 -76
  360. claude_mpm/hooks/validation_hooks.py +62 -54
  361. claude_mpm/init.py +518 -83
  362. claude_mpm/models/__init__.py +9 -9
  363. claude_mpm/models/agent_definition.py +40 -23
  364. claude_mpm/models/agent_session.py +538 -0
  365. claude_mpm/models/git_repository.py +198 -0
  366. claude_mpm/models/resume_log.py +340 -0
  367. claude_mpm/schemas/__init__.py +12 -0
  368. claude_mpm/scripts/__init__.py +15 -0
  369. claude_mpm/scripts/claude-hook-handler.sh +227 -0
  370. claude_mpm/scripts/launch_monitor.py +165 -0
  371. claude_mpm/scripts/mpm_doctor.py +322 -0
  372. claude_mpm/scripts/socketio_daemon.py +189 -200
  373. claude_mpm/scripts/start_activity_logging.py +91 -0
  374. claude_mpm/services/__init__.py +208 -39
  375. claude_mpm/services/agent_capabilities_service.py +266 -0
  376. claude_mpm/services/agents/__init__.py +89 -0
  377. claude_mpm/services/agents/agent_builder.py +514 -0
  378. claude_mpm/services/agents/agent_preset_service.py +238 -0
  379. claude_mpm/services/agents/agent_recommendation_service.py +278 -0
  380. claude_mpm/services/agents/agent_review_service.py +280 -0
  381. claude_mpm/services/agents/agent_selection_service.py +484 -0
  382. claude_mpm/services/agents/auto_config_manager.py +796 -0
  383. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  384. claude_mpm/services/agents/cache_git_manager.py +621 -0
  385. claude_mpm/services/agents/deployment/__init__.py +21 -0
  386. claude_mpm/services/agents/deployment/agent_config_provider.py +410 -0
  387. claude_mpm/services/agents/deployment/agent_configuration_manager.py +358 -0
  388. claude_mpm/services/agents/deployment/agent_definition_factory.py +80 -0
  389. claude_mpm/services/agents/deployment/agent_deployment.py +1037 -0
  390. claude_mpm/services/agents/deployment/agent_discovery_service.py +546 -0
  391. claude_mpm/services/agents/deployment/agent_environment_manager.py +288 -0
  392. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +383 -0
  393. claude_mpm/services/agents/deployment/agent_format_converter.py +505 -0
  394. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +160 -0
  395. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +957 -0
  396. claude_mpm/services/agents/deployment/agent_metrics_collector.py +273 -0
  397. claude_mpm/services/agents/deployment/agent_operation_service.py +573 -0
  398. claude_mpm/services/agents/deployment/agent_record_service.py +418 -0
  399. claude_mpm/services/agents/deployment/agent_restore_handler.py +84 -0
  400. claude_mpm/services/agents/deployment/agent_state_service.py +381 -0
  401. claude_mpm/services/agents/deployment/agent_template_builder.py +1369 -0
  402. claude_mpm/services/agents/deployment/agent_validator.py +376 -0
  403. claude_mpm/services/agents/deployment/agent_version_manager.py +322 -0
  404. claude_mpm/services/{agent_versioning.py → agents/deployment/agent_versioning.py} +10 -13
  405. claude_mpm/services/agents/deployment/agents_directory_resolver.py +149 -0
  406. claude_mpm/services/agents/deployment/async_agent_deployment.py +768 -0
  407. claude_mpm/services/agents/deployment/base_agent_locator.py +132 -0
  408. claude_mpm/services/agents/deployment/config/__init__.py +13 -0
  409. claude_mpm/services/agents/deployment/config/deployment_config.py +181 -0
  410. claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
  411. claude_mpm/services/agents/deployment/deployment_config_loader.py +178 -0
  412. claude_mpm/services/agents/deployment/deployment_results_manager.py +185 -0
  413. claude_mpm/services/agents/deployment/deployment_type_detector.py +120 -0
  414. claude_mpm/services/agents/deployment/deployment_wrapper.py +129 -0
  415. claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
  416. claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
  417. claude_mpm/services/agents/deployment/facade/deployment_executor.py +70 -0
  418. claude_mpm/services/agents/deployment/facade/deployment_facade.py +269 -0
  419. claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
  420. claude_mpm/services/agents/deployment/interface_adapter.py +226 -0
  421. claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
  422. claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
  423. claude_mpm/services/agents/deployment/local_template_deployment.py +362 -0
  424. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +1478 -0
  425. claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
  426. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
  427. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +162 -0
  428. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
  429. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
  430. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +240 -0
  431. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +110 -0
  432. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +80 -0
  433. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +92 -0
  434. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +101 -0
  435. claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
  436. claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +102 -0
  437. claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
  438. claude_mpm/services/agents/deployment/processors/agent_processor.py +269 -0
  439. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +311 -0
  440. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +862 -0
  441. claude_mpm/services/agents/deployment/results/__init__.py +13 -0
  442. claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
  443. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
  444. claude_mpm/services/agents/deployment/single_agent_deployer.py +315 -0
  445. claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
  446. claude_mpm/services/agents/deployment/strategies/base_strategy.py +113 -0
  447. claude_mpm/services/agents/deployment/strategies/project_strategy.py +148 -0
  448. claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
  449. claude_mpm/services/agents/deployment/strategies/system_strategy.py +131 -0
  450. claude_mpm/services/agents/deployment/strategies/user_strategy.py +130 -0
  451. claude_mpm/services/agents/deployment/system_instructions_deployer.py +228 -0
  452. claude_mpm/services/agents/deployment/validation/__init__.py +21 -0
  453. claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
  454. claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
  455. claude_mpm/services/agents/deployment/validation/template_validator.py +319 -0
  456. claude_mpm/services/agents/deployment/validation/validation_result.py +214 -0
  457. claude_mpm/services/agents/git_source_manager.py +682 -0
  458. claude_mpm/services/agents/loading/__init__.py +11 -0
  459. claude_mpm/services/{agent_profile_loader.py → agents/loading/agent_profile_loader.py} +306 -228
  460. claude_mpm/services/{base_agent_manager.py → agents/loading/base_agent_manager.py} +106 -91
  461. claude_mpm/services/agents/loading/framework_agent_loader.py +433 -0
  462. claude_mpm/services/agents/local_template_manager.py +784 -0
  463. claude_mpm/services/agents/management/__init__.py +9 -0
  464. claude_mpm/services/{agent_capabilities_generator.py → agents/management/agent_capabilities_generator.py} +92 -69
  465. claude_mpm/services/{agent_management_service.py → agents/management/agent_management_service.py} +219 -168
  466. claude_mpm/services/agents/memory/__init__.py +22 -0
  467. claude_mpm/services/agents/memory/agent_memory_manager.py +784 -0
  468. claude_mpm/services/{agent_persistence_service.py → agents/memory/agent_persistence_service.py} +20 -18
  469. claude_mpm/services/agents/memory/content_manager.py +470 -0
  470. claude_mpm/services/agents/memory/memory_categorization_service.py +167 -0
  471. claude_mpm/services/agents/memory/memory_file_service.py +129 -0
  472. claude_mpm/services/agents/memory/memory_format_service.py +201 -0
  473. claude_mpm/services/agents/memory/memory_limits_service.py +101 -0
  474. claude_mpm/services/agents/memory/template_generator.py +83 -0
  475. claude_mpm/services/agents/observers.py +547 -0
  476. claude_mpm/services/agents/recommender.py +617 -0
  477. claude_mpm/services/agents/registry/__init__.py +30 -0
  478. claude_mpm/services/agents/registry/deployed_agent_discovery.py +273 -0
  479. claude_mpm/services/{agent_modification_tracker.py → agents/registry/modification_tracker.py} +370 -295
  480. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  481. claude_mpm/services/agents/sources/__init__.py +13 -0
  482. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  483. claude_mpm/services/agents/sources/git_source_sync_service.py +1202 -0
  484. claude_mpm/services/agents/startup_sync.py +259 -0
  485. claude_mpm/services/agents/toolchain_detector.py +478 -0
  486. claude_mpm/services/analysis/__init__.py +35 -0
  487. claude_mpm/services/analysis/clone_detector.py +1030 -0
  488. claude_mpm/services/analysis/postmortem_reporter.py +474 -0
  489. claude_mpm/services/analysis/postmortem_service.py +765 -0
  490. claude_mpm/services/async_session_logger.py +665 -0
  491. claude_mpm/services/claude_session_logger.py +321 -0
  492. claude_mpm/services/cli/__init__.py +18 -0
  493. claude_mpm/services/cli/agent_cleanup_service.py +408 -0
  494. claude_mpm/services/cli/agent_dependency_service.py +395 -0
  495. claude_mpm/services/cli/agent_listing_service.py +463 -0
  496. claude_mpm/services/cli/agent_output_formatter.py +605 -0
  497. claude_mpm/services/cli/agent_validation_service.py +590 -0
  498. claude_mpm/services/cli/memory_crud_service.py +622 -0
  499. claude_mpm/services/cli/memory_output_formatter.py +604 -0
  500. claude_mpm/services/cli/resume_service.py +617 -0
  501. claude_mpm/services/cli/session_manager.py +604 -0
  502. claude_mpm/services/cli/session_pause_manager.py +504 -0
  503. claude_mpm/services/cli/session_resume_helper.py +372 -0
  504. claude_mpm/services/cli/startup_checker.py +362 -0
  505. claude_mpm/services/cli/unified_dashboard_manager.py +439 -0
  506. claude_mpm/services/command_deployment_service.py +446 -0
  507. claude_mpm/services/command_handler_service.py +221 -0
  508. claude_mpm/services/communication/__init__.py +22 -0
  509. claude_mpm/services/core/__init__.py +108 -0
  510. claude_mpm/services/core/base.py +269 -0
  511. claude_mpm/services/core/cache_manager.py +309 -0
  512. claude_mpm/services/core/interfaces/__init__.py +273 -0
  513. claude_mpm/services/core/interfaces/agent.py +514 -0
  514. claude_mpm/services/core/interfaces/communication.py +316 -0
  515. claude_mpm/services/core/interfaces/health.py +169 -0
  516. claude_mpm/services/core/interfaces/infrastructure.py +357 -0
  517. claude_mpm/services/core/interfaces/model.py +281 -0
  518. claude_mpm/services/core/interfaces/process.py +372 -0
  519. claude_mpm/services/core/interfaces/project.py +121 -0
  520. claude_mpm/services/core/interfaces/restart.py +307 -0
  521. claude_mpm/services/core/interfaces/service.py +405 -0
  522. claude_mpm/services/core/interfaces/stability.py +260 -0
  523. claude_mpm/services/core/interfaces.py +81 -0
  524. claude_mpm/services/core/memory_manager.py +682 -0
  525. claude_mpm/services/core/models/__init__.py +70 -0
  526. claude_mpm/services/core/models/agent_config.py +384 -0
  527. claude_mpm/services/core/models/health.py +162 -0
  528. claude_mpm/services/core/models/process.py +239 -0
  529. claude_mpm/services/core/models/restart.py +302 -0
  530. claude_mpm/services/core/models/stability.py +264 -0
  531. claude_mpm/services/core/models/toolchain.py +306 -0
  532. claude_mpm/services/core/path_resolver.py +517 -0
  533. claude_mpm/services/core/service_container.py +520 -0
  534. claude_mpm/services/core/service_interfaces.py +436 -0
  535. claude_mpm/services/diagnostics/__init__.py +18 -0
  536. claude_mpm/services/diagnostics/checks/__init__.py +38 -0
  537. claude_mpm/services/diagnostics/checks/agent_check.py +370 -0
  538. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  539. claude_mpm/services/diagnostics/checks/base_check.py +60 -0
  540. claude_mpm/services/diagnostics/checks/claude_code_check.py +270 -0
  541. claude_mpm/services/diagnostics/checks/common_issues_check.py +363 -0
  542. claude_mpm/services/diagnostics/checks/configuration_check.py +306 -0
  543. claude_mpm/services/diagnostics/checks/filesystem_check.py +233 -0
  544. claude_mpm/services/diagnostics/checks/installation_check.py +520 -0
  545. claude_mpm/services/diagnostics/checks/instructions_check.py +415 -0
  546. claude_mpm/services/diagnostics/checks/mcp_check.py +330 -0
  547. claude_mpm/services/diagnostics/checks/mcp_services_check.py +1058 -0
  548. claude_mpm/services/diagnostics/checks/monitor_check.py +281 -0
  549. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  550. claude_mpm/services/diagnostics/checks/startup_log_check.py +319 -0
  551. claude_mpm/services/diagnostics/diagnostic_runner.py +286 -0
  552. claude_mpm/services/diagnostics/doctor_reporter.py +578 -0
  553. claude_mpm/services/diagnostics/models.py +138 -0
  554. claude_mpm/services/event_aggregator.py +582 -0
  555. claude_mpm/services/event_bus/__init__.py +18 -0
  556. claude_mpm/services/event_bus/config.py +186 -0
  557. claude_mpm/services/event_bus/direct_relay.py +312 -0
  558. claude_mpm/services/event_bus/event_bus.py +396 -0
  559. claude_mpm/services/event_bus/relay.py +326 -0
  560. claude_mpm/services/events/__init__.py +44 -0
  561. claude_mpm/services/events/consumers/__init__.py +18 -0
  562. claude_mpm/services/events/consumers/dead_letter.py +306 -0
  563. claude_mpm/services/events/consumers/logging.py +184 -0
  564. claude_mpm/services/events/consumers/metrics.py +241 -0
  565. claude_mpm/services/events/consumers/socketio.py +377 -0
  566. claude_mpm/services/events/core.py +480 -0
  567. claude_mpm/services/events/interfaces.py +214 -0
  568. claude_mpm/services/events/producers/__init__.py +14 -0
  569. claude_mpm/services/events/producers/hook.py +269 -0
  570. claude_mpm/services/events/producers/system.py +329 -0
  571. claude_mpm/services/exceptions.py +433 -353
  572. claude_mpm/services/framework_claude_md_generator/__init__.py +81 -80
  573. claude_mpm/services/framework_claude_md_generator/content_assembler.py +74 -67
  574. claude_mpm/services/framework_claude_md_generator/content_validator.py +66 -62
  575. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +82 -60
  576. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +36 -37
  577. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +41 -40
  578. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +15 -15
  579. claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +5 -4
  580. claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
  581. claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
  582. claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
  583. claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
  584. claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +5 -4
  585. claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
  586. claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
  587. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +26 -30
  588. claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +6 -5
  589. claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
  590. claude_mpm/services/framework_claude_md_generator/version_manager.py +31 -30
  591. claude_mpm/services/git/__init__.py +21 -0
  592. claude_mpm/services/git/git_operations_service.py +579 -0
  593. claude_mpm/services/github/__init__.py +21 -0
  594. claude_mpm/services/github/github_cli_service.py +397 -0
  595. claude_mpm/services/hook_installer_service.py +506 -0
  596. claude_mpm/services/hook_service.py +159 -111
  597. claude_mpm/services/infrastructure/__init__.py +52 -0
  598. claude_mpm/services/infrastructure/context_preservation.py +569 -0
  599. claude_mpm/services/infrastructure/daemon_manager.py +279 -0
  600. claude_mpm/services/infrastructure/logging.py +209 -0
  601. claude_mpm/services/infrastructure/monitoring/__init__.py +39 -0
  602. claude_mpm/services/infrastructure/monitoring/aggregator.py +432 -0
  603. claude_mpm/services/infrastructure/monitoring/base.py +122 -0
  604. claude_mpm/services/infrastructure/monitoring/legacy.py +203 -0
  605. claude_mpm/services/infrastructure/monitoring/network.py +219 -0
  606. claude_mpm/services/infrastructure/monitoring/process.py +343 -0
  607. claude_mpm/services/infrastructure/monitoring/resources.py +244 -0
  608. claude_mpm/services/infrastructure/monitoring/service.py +368 -0
  609. claude_mpm/services/infrastructure/monitoring.py +71 -0
  610. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  611. claude_mpm/services/instructions/__init__.py +9 -0
  612. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  613. claude_mpm/services/local_ops/__init__.py +155 -0
  614. claude_mpm/services/local_ops/crash_detector.py +257 -0
  615. claude_mpm/services/local_ops/health_checks/__init__.py +26 -0
  616. claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
  617. claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
  618. claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
  619. claude_mpm/services/local_ops/health_manager.py +427 -0
  620. claude_mpm/services/local_ops/log_monitor.py +396 -0
  621. claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
  622. claude_mpm/services/local_ops/process_manager.py +595 -0
  623. claude_mpm/services/local_ops/resource_monitor.py +331 -0
  624. claude_mpm/services/local_ops/restart_manager.py +401 -0
  625. claude_mpm/services/local_ops/restart_policy.py +387 -0
  626. claude_mpm/services/local_ops/state_manager.py +372 -0
  627. claude_mpm/services/local_ops/unified_manager.py +600 -0
  628. claude_mpm/services/mcp_config_manager.py +1542 -0
  629. claude_mpm/services/mcp_service_verifier.py +732 -0
  630. claude_mpm/services/memory/__init__.py +19 -0
  631. claude_mpm/services/{memory_builder.py → memory/builder.py} +465 -373
  632. claude_mpm/services/memory/cache/__init__.py +14 -0
  633. claude_mpm/services/{shared_prompt_cache.py → memory/cache/shared_prompt_cache.py} +237 -200
  634. claude_mpm/services/memory/cache/simple_cache.py +331 -0
  635. claude_mpm/services/memory/failure_tracker.py +578 -0
  636. claude_mpm/services/memory/indexed_memory.py +648 -0
  637. claude_mpm/services/{memory_optimizer.py → memory/optimizer.py} +272 -243
  638. claude_mpm/services/memory/router.py +951 -0
  639. claude_mpm/services/memory_hook_service.py +470 -0
  640. claude_mpm/services/model/__init__.py +147 -0
  641. claude_mpm/services/model/base_provider.py +365 -0
  642. claude_mpm/services/model/claude_provider.py +412 -0
  643. claude_mpm/services/model/model_router.py +452 -0
  644. claude_mpm/services/model/ollama_provider.py +415 -0
  645. claude_mpm/services/monitor/__init__.py +20 -0
  646. claude_mpm/services/monitor/daemon.py +698 -0
  647. claude_mpm/services/monitor/daemon_manager.py +1076 -0
  648. claude_mpm/services/monitor/event_emitter.py +350 -0
  649. claude_mpm/services/monitor/handlers/__init__.py +21 -0
  650. claude_mpm/services/monitor/handlers/code_analysis.py +332 -0
  651. claude_mpm/services/monitor/handlers/dashboard.py +299 -0
  652. claude_mpm/services/monitor/handlers/file.py +264 -0
  653. claude_mpm/services/monitor/handlers/hooks.py +512 -0
  654. claude_mpm/services/monitor/management/__init__.py +18 -0
  655. claude_mpm/services/monitor/management/health.py +124 -0
  656. claude_mpm/services/monitor/management/lifecycle.py +730 -0
  657. claude_mpm/services/monitor/server.py +1493 -0
  658. claude_mpm/services/monitor_build_service.py +349 -0
  659. claude_mpm/services/native_agent_converter.py +356 -0
  660. claude_mpm/services/orphan_detection.py +786 -0
  661. claude_mpm/services/pm_skills_deployer.py +707 -0
  662. claude_mpm/services/port_manager.py +597 -0
  663. claude_mpm/services/pr/__init__.py +14 -0
  664. claude_mpm/services/pr/pr_template_service.py +329 -0
  665. claude_mpm/services/profile_manager.py +337 -0
  666. claude_mpm/services/project/__init__.py +44 -0
  667. claude_mpm/services/{project_analyzer.py → project/analyzer.py} +541 -291
  668. claude_mpm/services/project/analyzer_v2.py +566 -0
  669. claude_mpm/services/project/architecture_analyzer.py +461 -0
  670. claude_mpm/services/project/archive_manager.py +1045 -0
  671. claude_mpm/services/project/dependency_analyzer.py +462 -0
  672. claude_mpm/services/project/detection_strategies.py +719 -0
  673. claude_mpm/services/project/documentation_manager.py +554 -0
  674. claude_mpm/services/project/enhanced_analyzer.py +572 -0
  675. claude_mpm/services/project/language_analyzer.py +265 -0
  676. claude_mpm/services/project/metrics_collector.py +407 -0
  677. claude_mpm/services/project/project_organizer.py +1009 -0
  678. claude_mpm/services/project/registry.py +636 -0
  679. claude_mpm/services/project/toolchain_analyzer.py +583 -0
  680. claude_mpm/services/project_port_allocator.py +596 -0
  681. claude_mpm/services/recovery_manager.py +293 -240
  682. claude_mpm/services/response_tracker.py +267 -0
  683. claude_mpm/services/runner_configuration_service.py +605 -0
  684. claude_mpm/services/self_upgrade_service.py +608 -0
  685. claude_mpm/services/session_management_service.py +314 -0
  686. claude_mpm/services/session_manager.py +380 -0
  687. claude_mpm/services/shared/__init__.py +21 -0
  688. claude_mpm/services/shared/async_service_base.py +216 -0
  689. claude_mpm/services/shared/config_service_base.py +301 -0
  690. claude_mpm/services/shared/lifecycle_service_base.py +308 -0
  691. claude_mpm/services/shared/manager_base.py +315 -0
  692. claude_mpm/services/shared/service_factory.py +309 -0
  693. claude_mpm/services/skills/__init__.py +21 -0
  694. claude_mpm/services/skills/git_skill_source_manager.py +1324 -0
  695. claude_mpm/services/skills/selective_skill_deployer.py +744 -0
  696. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  697. claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
  698. claude_mpm/services/skills_config.py +547 -0
  699. claude_mpm/services/skills_deployer.py +1168 -0
  700. claude_mpm/services/socketio/__init__.py +25 -0
  701. claude_mpm/services/socketio/client_proxy.py +229 -0
  702. claude_mpm/services/socketio/dashboard_server.py +362 -0
  703. claude_mpm/services/socketio/event_normalizer.py +798 -0
  704. claude_mpm/services/socketio/handlers/__init__.py +30 -0
  705. claude_mpm/services/socketio/handlers/base.py +136 -0
  706. claude_mpm/services/socketio/handlers/code_analysis.py +682 -0
  707. claude_mpm/services/socketio/handlers/connection.py +643 -0
  708. claude_mpm/services/socketio/handlers/connection_handler.py +333 -0
  709. claude_mpm/services/socketio/handlers/file.py +263 -0
  710. claude_mpm/services/socketio/handlers/git.py +962 -0
  711. claude_mpm/services/socketio/handlers/hook.py +211 -0
  712. claude_mpm/services/socketio/handlers/memory.py +26 -0
  713. claude_mpm/services/socketio/handlers/project.py +24 -0
  714. claude_mpm/services/socketio/handlers/registry.py +214 -0
  715. claude_mpm/services/socketio/migration_utils.py +343 -0
  716. claude_mpm/services/socketio/monitor_client.py +364 -0
  717. claude_mpm/services/socketio/server/__init__.py +18 -0
  718. claude_mpm/services/socketio/server/broadcaster.py +569 -0
  719. claude_mpm/services/socketio/server/connection_manager.py +579 -0
  720. claude_mpm/services/socketio/server/core.py +1079 -0
  721. claude_mpm/services/socketio/server/eventbus_integration.py +245 -0
  722. claude_mpm/services/socketio/server/main.py +501 -0
  723. claude_mpm/services/socketio_client_manager.py +173 -143
  724. claude_mpm/services/socketio_server.py +38 -1657
  725. claude_mpm/services/subprocess_launcher_service.py +322 -0
  726. claude_mpm/services/system_instructions_service.py +270 -0
  727. claude_mpm/services/ticket_manager.py +25 -209
  728. claude_mpm/services/ticket_services/__init__.py +26 -0
  729. claude_mpm/services/ticket_services/crud_service.py +328 -0
  730. claude_mpm/services/ticket_services/formatter_service.py +290 -0
  731. claude_mpm/services/ticket_services/search_service.py +324 -0
  732. claude_mpm/services/ticket_services/validation_service.py +303 -0
  733. claude_mpm/services/ticket_services/workflow_service.py +244 -0
  734. claude_mpm/services/unified/__init__.py +65 -0
  735. claude_mpm/services/unified/analyzer_strategies/__init__.py +44 -0
  736. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +518 -0
  737. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +680 -0
  738. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +900 -0
  739. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +745 -0
  740. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +733 -0
  741. claude_mpm/services/unified/config_strategies/__init__.py +175 -0
  742. claude_mpm/services/unified/config_strategies/config_schema.py +731 -0
  743. claude_mpm/services/unified/config_strategies/context_strategy.py +747 -0
  744. claude_mpm/services/unified/config_strategies/error_handling_strategy.py +1005 -0
  745. claude_mpm/services/unified/config_strategies/file_loader_strategy.py +881 -0
  746. claude_mpm/services/unified/config_strategies/unified_config_service.py +823 -0
  747. claude_mpm/services/unified/config_strategies/validation_strategy.py +1148 -0
  748. claude_mpm/services/unified/deployment_strategies/__init__.py +97 -0
  749. claude_mpm/services/unified/deployment_strategies/base.py +553 -0
  750. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +573 -0
  751. claude_mpm/services/unified/deployment_strategies/local.py +607 -0
  752. claude_mpm/services/unified/deployment_strategies/utils.py +667 -0
  753. claude_mpm/services/unified/deployment_strategies/vercel.py +471 -0
  754. claude_mpm/services/unified/interfaces.py +475 -0
  755. claude_mpm/services/unified/migration.py +509 -0
  756. claude_mpm/services/unified/strategies.py +534 -0
  757. claude_mpm/services/unified/unified_analyzer.py +542 -0
  758. claude_mpm/services/unified/unified_config.py +691 -0
  759. claude_mpm/services/unified/unified_deployment.py +466 -0
  760. claude_mpm/services/utility_service.py +280 -0
  761. claude_mpm/services/version_control/__init__.py +34 -37
  762. claude_mpm/services/version_control/branch_strategy.py +26 -17
  763. claude_mpm/services/version_control/conflict_resolution.py +52 -36
  764. claude_mpm/services/version_control/git_operations.py +183 -49
  765. claude_mpm/services/version_control/semantic_versioning.py +172 -61
  766. claude_mpm/services/version_control/version_parser.py +546 -0
  767. claude_mpm/services/version_service.py +379 -0
  768. claude_mpm/services/visualization/__init__.py +15 -0
  769. claude_mpm/services/visualization/mermaid_generator.py +937 -0
  770. claude_mpm/skills/__init__.py +42 -0
  771. claude_mpm/skills/agent_skills_injector.py +324 -0
  772. claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
  773. claude_mpm/skills/bundled/__init__.py +6 -0
  774. claude_mpm/skills/bundled/api-documentation.md +393 -0
  775. claude_mpm/skills/bundled/async-testing.md +571 -0
  776. claude_mpm/skills/bundled/code-review.md +143 -0
  777. claude_mpm/skills/bundled/database-migration.md +199 -0
  778. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  779. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  780. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  781. claude_mpm/skills/bundled/git-workflow.md +414 -0
  782. claude_mpm/skills/bundled/imagemagick.md +204 -0
  783. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  784. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  785. claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
  786. claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
  787. claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
  788. claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
  789. claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
  790. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  791. claude_mpm/skills/bundled/pdf.md +141 -0
  792. claude_mpm/skills/bundled/performance-profiling.md +573 -0
  793. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  794. claude_mpm/skills/bundled/security-scanning.md +439 -0
  795. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  796. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  797. claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
  798. claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
  799. claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
  800. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
  801. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  802. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  803. claude_mpm/skills/bundled/xlsx.md +157 -0
  804. claude_mpm/skills/registry.py +286 -0
  805. claude_mpm/skills/skill_manager.py +405 -0
  806. claude_mpm/skills/skills_registry.py +347 -0
  807. claude_mpm/skills/skills_service.py +739 -0
  808. claude_mpm/storage/__init__.py +9 -0
  809. claude_mpm/storage/state_storage.py +546 -0
  810. claude_mpm/templates/.pre-commit-config.yaml +112 -0
  811. claude_mpm/templates/questions/__init__.py +38 -0
  812. claude_mpm/templates/questions/base.py +193 -0
  813. claude_mpm/templates/questions/pr_strategy.py +311 -0
  814. claude_mpm/templates/questions/project_init.py +385 -0
  815. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  816. claude_mpm/ticket_wrapper.py +2 -2
  817. claude_mpm/tools/__init__.py +10 -0
  818. claude_mpm/tools/__main__.py +208 -0
  819. claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
  820. claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
  821. claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
  822. claude_mpm/tools/code_tree_analyzer/core.py +380 -0
  823. claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
  824. claude_mpm/tools/code_tree_analyzer/events.py +168 -0
  825. claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
  826. claude_mpm/tools/code_tree_analyzer/models.py +39 -0
  827. claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
  828. claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
  829. claude_mpm/tools/code_tree_builder.py +631 -0
  830. claude_mpm/tools/code_tree_events.py +420 -0
  831. claude_mpm/tools/socketio_debug.py +671 -0
  832. claude_mpm/utils/__init__.py +8 -8
  833. claude_mpm/utils/agent_dependency_loader.py +1090 -0
  834. claude_mpm/utils/agent_filters.py +261 -0
  835. claude_mpm/utils/common.py +544 -0
  836. claude_mpm/utils/config_manager.py +168 -126
  837. claude_mpm/utils/console.py +11 -0
  838. claude_mpm/utils/database_connector.py +298 -0
  839. claude_mpm/utils/dependency_cache.py +373 -0
  840. claude_mpm/utils/dependency_manager.py +60 -59
  841. claude_mpm/utils/dependency_strategies.py +381 -0
  842. claude_mpm/utils/display_helper.py +260 -0
  843. claude_mpm/utils/environment_context.py +313 -0
  844. claude_mpm/utils/error_handler.py +78 -66
  845. claude_mpm/utils/file_utils.py +305 -0
  846. claude_mpm/utils/framework_detection.py +12 -11
  847. claude_mpm/utils/git_analyzer.py +407 -0
  848. claude_mpm/utils/gitignore.py +244 -0
  849. claude_mpm/utils/import_migration_example.py +12 -60
  850. claude_mpm/utils/imports.py +48 -45
  851. claude_mpm/utils/log_cleanup.py +627 -0
  852. claude_mpm/utils/migration.py +372 -0
  853. claude_mpm/utils/path_operations.py +110 -104
  854. claude_mpm/utils/progress.py +387 -0
  855. claude_mpm/utils/robust_installer.py +823 -0
  856. claude_mpm/utils/session_logging.py +121 -0
  857. claude_mpm/utils/structured_questions.py +619 -0
  858. claude_mpm/utils/subprocess_utils.py +343 -0
  859. claude_mpm/validation/__init__.py +1 -1
  860. claude_mpm/validation/agent_validator.py +214 -108
  861. claude_mpm/validation/frontmatter_validator.py +252 -0
  862. claude_mpm-5.4.55.dist-info/METADATA +999 -0
  863. claude_mpm-5.4.55.dist-info/RECORD +868 -0
  864. {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/entry_points.txt +1 -3
  865. claude_mpm-5.4.55.dist-info/licenses/LICENSE +94 -0
  866. claude_mpm-5.4.55.dist-info/licenses/LICENSE-FAQ.md +153 -0
  867. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -88
  868. claude_mpm/agents/INSTRUCTIONS.md +0 -352
  869. claude_mpm/agents/backups/INSTRUCTIONS.md +0 -352
  870. claude_mpm/agents/base_agent_loader.py +0 -529
  871. claude_mpm/agents/schema/agent_schema.json +0 -314
  872. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -36
  873. claude_mpm/agents/templates/backup/data_engineer_agent_20250726_234551.json +0 -46
  874. claude_mpm/agents/templates/backup/documentation_agent_20250726_234551.json +0 -45
  875. claude_mpm/agents/templates/backup/engineer_agent_20250726_234551.json +0 -49
  876. claude_mpm/agents/templates/backup/ops_agent_20250726_234551.json +0 -46
  877. claude_mpm/agents/templates/backup/qa_agent_20250726_234551.json +0 -45
  878. claude_mpm/agents/templates/backup/research_agent_20250726_234551.json +0 -49
  879. claude_mpm/agents/templates/backup/security_agent_20250726_234551.json +0 -46
  880. claude_mpm/agents/templates/backup/version_control_agent_20250726_234551.json +0 -46
  881. claude_mpm/agents/templates/data_engineer.json +0 -110
  882. claude_mpm/agents/templates/documentation.json +0 -109
  883. claude_mpm/agents/templates/engineer.json +0 -113
  884. claude_mpm/agents/templates/ops.json +0 -109
  885. claude_mpm/agents/templates/pm.json +0 -25
  886. claude_mpm/agents/templates/qa.json +0 -111
  887. claude_mpm/agents/templates/research.json +0 -65
  888. claude_mpm/agents/templates/security.json +0 -113
  889. claude_mpm/agents/templates/test_integration.json +0 -112
  890. claude_mpm/agents/templates/version_control.json +0 -107
  891. claude_mpm/cli/commands/ui.py +0 -57
  892. claude_mpm/core/simple_runner.py +0 -1046
  893. claude_mpm/dashboard/open_dashboard.py +0 -34
  894. claude_mpm/deployment_paths.py +0 -261
  895. claude_mpm/hooks/builtin/__init__.py +0 -1
  896. claude_mpm/hooks/builtin/logging_hook_example.py +0 -165
  897. claude_mpm/hooks/builtin/memory_hooks_example.py +0 -67
  898. claude_mpm/hooks/builtin/mpm_command_hook.py +0 -125
  899. claude_mpm/hooks/builtin/post_delegation_hook_example.py +0 -124
  900. claude_mpm/hooks/builtin/pre_delegation_hook_example.py +0 -125
  901. claude_mpm/hooks/builtin/submit_hook_example.py +0 -100
  902. claude_mpm/hooks/builtin/ticket_extraction_hook_example.py +0 -237
  903. claude_mpm/hooks/builtin/todo_agent_prefix_hook.py +0 -240
  904. claude_mpm/hooks/builtin/workflow_start_hook.py +0 -181
  905. claude_mpm/orchestration/__init__.py +0 -6
  906. claude_mpm/orchestration/archive/direct_orchestrator.py +0 -195
  907. claude_mpm/orchestration/archive/factory.py +0 -215
  908. claude_mpm/orchestration/archive/hook_enabled_orchestrator.py +0 -188
  909. claude_mpm/orchestration/archive/hook_integration_example.py +0 -178
  910. claude_mpm/orchestration/archive/interactive_subprocess_orchestrator.py +0 -826
  911. claude_mpm/orchestration/archive/orchestrator.py +0 -501
  912. claude_mpm/orchestration/archive/pexpect_orchestrator.py +0 -252
  913. claude_mpm/orchestration/archive/pty_orchestrator.py +0 -270
  914. claude_mpm/orchestration/archive/simple_orchestrator.py +0 -82
  915. claude_mpm/orchestration/archive/subprocess_orchestrator.py +0 -801
  916. claude_mpm/orchestration/archive/system_prompt_orchestrator.py +0 -278
  917. claude_mpm/orchestration/archive/wrapper_orchestrator.py +0 -187
  918. claude_mpm/schemas/workflow_validator.py +0 -411
  919. claude_mpm/services/agent_deployment.py +0 -1534
  920. claude_mpm/services/agent_lifecycle_manager.py +0 -1169
  921. claude_mpm/services/agent_memory_manager.py +0 -1415
  922. claude_mpm/services/agent_registry.py +0 -676
  923. claude_mpm/services/deployed_agent_discovery.py +0 -226
  924. claude_mpm/services/framework_agent_loader.py +0 -337
  925. claude_mpm/services/framework_claude_md_generator.py +0 -621
  926. claude_mpm/services/health_monitor.py +0 -892
  927. claude_mpm/services/memory_router.py +0 -538
  928. claude_mpm/services/parent_directory_manager/__init__.py +0 -577
  929. claude_mpm/services/parent_directory_manager/backup_manager.py +0 -258
  930. claude_mpm/services/parent_directory_manager/config_manager.py +0 -210
  931. claude_mpm/services/parent_directory_manager/deduplication_manager.py +0 -279
  932. claude_mpm/services/parent_directory_manager/framework_protector.py +0 -143
  933. claude_mpm/services/parent_directory_manager/operations.py +0 -186
  934. claude_mpm/services/parent_directory_manager/state_manager.py +0 -624
  935. claude_mpm/services/parent_directory_manager/template_deployer.py +0 -579
  936. claude_mpm/services/parent_directory_manager/validation_manager.py +0 -378
  937. claude_mpm/services/parent_directory_manager/version_control_helper.py +0 -339
  938. claude_mpm/services/parent_directory_manager/version_manager.py +0 -222
  939. claude_mpm/services/standalone_socketio_server.py +0 -1300
  940. claude_mpm/services/ticket_manager_di.py +0 -318
  941. claude_mpm/services/ticketing_service_original.py +0 -508
  942. claude_mpm/ui/__init__.py +0 -1
  943. claude_mpm/ui/rich_terminal_ui.py +0 -295
  944. claude_mpm/ui/terminal_ui.py +0 -328
  945. claude_mpm/utils/paths.py +0 -289
  946. claude_mpm-3.4.10.dist-info/METADATA +0 -183
  947. claude_mpm-3.4.10.dist-info/RECORD +0 -201
  948. claude_mpm-3.4.10.dist-info/licenses/LICENSE +0 -21
  949. {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/WHEEL +0 -0
  950. {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,1005 @@
1
+ """
2
+ Error Handling Strategy - Unifies 99 error handling patterns into composable handlers
3
+ Part of Phase 3 Configuration Consolidation
4
+ """
5
+
6
+ import json
7
+ import traceback
8
+ from abc import ABC, abstractmethod
9
+ from dataclasses import dataclass, field
10
+ from datetime import datetime
11
+ from enum import Enum
12
+ from pathlib import Path
13
+ from typing import Any, Callable, ClassVar, Dict, List, Optional, Type, Union
14
+
15
+ from claude_mpm.core.logging_utils import get_logger
16
+
17
+ from .unified_config_service import IConfigStrategy
18
+
19
+
20
+ class ErrorSeverity(Enum):
21
+ """Error severity levels"""
22
+
23
+ CRITICAL = "critical" # System failure
24
+ ERROR = "error" # Operation failure
25
+ WARNING = "warning" # Recoverable issue
26
+ INFO = "info" # Informational
27
+ DEBUG = "debug" # Debug information
28
+
29
+
30
+ class ErrorCategory(Enum):
31
+ """Categories of errors for handling strategy"""
32
+
33
+ FILE_IO = "file_io"
34
+ PARSING = "parsing"
35
+ VALIDATION = "validation"
36
+ NETWORK = "network"
37
+ PERMISSION = "permission"
38
+ TYPE_CONVERSION = "type_conversion"
39
+ MISSING_DEPENDENCY = "missing_dependency"
40
+ CONFIGURATION = "configuration"
41
+ RUNTIME = "runtime"
42
+ UNKNOWN = "unknown"
43
+
44
+
45
+ @dataclass
46
+ class ErrorContext:
47
+ """Context information for error handling"""
48
+
49
+ error: Exception
50
+ category: ErrorCategory
51
+ severity: ErrorSeverity
52
+ source: Optional[str] = None
53
+ operation: Optional[str] = None
54
+ timestamp: datetime = field(default_factory=datetime.now)
55
+ traceback: Optional[str] = None
56
+ metadata: Dict[str, Any] = field(default_factory=dict)
57
+ recovery_attempted: bool = False
58
+ recovery_successful: bool = False
59
+
60
+
61
+ @dataclass
62
+ class ErrorHandlingResult:
63
+ """Result of error handling operation"""
64
+
65
+ handled: bool
66
+ recovered: bool = False
67
+ fallback_value: Any = None
68
+ should_retry: bool = False
69
+ retry_after: Optional[int] = None # seconds
70
+ should_escalate: bool = False
71
+ message: Optional[str] = None
72
+ actions_taken: List[str] = field(default_factory=list)
73
+
74
+
75
+ class BaseErrorHandler(ABC):
76
+ """Base class for all error handlers"""
77
+
78
+ def __init__(self):
79
+ self.logger = get_logger(self.__class__.__name__)
80
+
81
+ @abstractmethod
82
+ def can_handle(self, context: ErrorContext) -> bool:
83
+ """Check if this handler can handle the error"""
84
+
85
+ @abstractmethod
86
+ def handle(self, context: ErrorContext) -> ErrorHandlingResult:
87
+ """Handle the error"""
88
+
89
+ def log_error(self, context: ErrorContext, message: Optional[str] = None):
90
+ """Log error with appropriate level"""
91
+ log_message = message or str(context.error)
92
+
93
+ if context.severity == ErrorSeverity.CRITICAL:
94
+ self.logger.critical(log_message)
95
+ elif context.severity == ErrorSeverity.ERROR:
96
+ self.logger.error(log_message)
97
+ elif context.severity == ErrorSeverity.WARNING:
98
+ self.logger.warning(log_message)
99
+ elif context.severity == ErrorSeverity.INFO:
100
+ self.logger.info(log_message)
101
+ else:
102
+ self.logger.debug(log_message)
103
+
104
+
105
+ class FileIOErrorHandler(BaseErrorHandler):
106
+ """Handles file I/O errors - consolidates 18 file error patterns"""
107
+
108
+ ERROR_MAPPING: ClassVar[dict] = {
109
+ FileNotFoundError: "File not found",
110
+ PermissionError: "Permission denied",
111
+ IsADirectoryError: "Path is a directory",
112
+ NotADirectoryError: "Path is not a directory",
113
+ IOError: "I/O operation failed",
114
+ OSError: "Operating system error",
115
+ }
116
+
117
+ def can_handle(self, context: ErrorContext) -> bool:
118
+ """Check if error is file I/O related"""
119
+ return context.category == ErrorCategory.FILE_IO or isinstance(
120
+ context.error, (FileNotFoundError, PermissionError, IOError, OSError)
121
+ )
122
+
123
+ def handle(self, context: ErrorContext) -> ErrorHandlingResult:
124
+ """Handle file I/O errors with recovery strategies"""
125
+ result = ErrorHandlingResult(handled=True)
126
+
127
+ error_type = type(context.error)
128
+ error_message = self.ERROR_MAPPING.get(error_type, "Unknown file error")
129
+
130
+ # Log the error
131
+ self.log_error(context, f"{error_message}: {context.source}")
132
+
133
+ # Try recovery strategies
134
+ if isinstance(context.error, FileNotFoundError):
135
+ result = self._handle_file_not_found(context)
136
+ elif isinstance(context.error, PermissionError):
137
+ result = self._handle_permission_error(context)
138
+ else:
139
+ result = self._handle_generic_io_error(context)
140
+
141
+ result.actions_taken.append(f"Handled {error_type.__name__}")
142
+ return result
143
+
144
+ def _handle_file_not_found(self, context: ErrorContext) -> ErrorHandlingResult:
145
+ """Handle file not found errors"""
146
+ result = ErrorHandlingResult(handled=True)
147
+
148
+ # Check for fallback locations
149
+ if context.metadata.get("fallback_paths"):
150
+ for fallback in context.metadata["fallback_paths"]:
151
+ fallback_path = Path(fallback)
152
+ if fallback_path.exists():
153
+ result.recovered = True
154
+ result.fallback_value = str(fallback_path)
155
+ result.actions_taken.append(f"Used fallback path: {fallback_path}")
156
+ self.logger.info(f"Using fallback configuration: {fallback_path}")
157
+ return result
158
+
159
+ # Check for default values
160
+ if context.metadata.get("default_config"):
161
+ result.recovered = True
162
+ result.fallback_value = context.metadata["default_config"]
163
+ result.actions_taken.append("Used default configuration")
164
+ return result
165
+
166
+ # Create file if requested
167
+ if context.metadata.get("create_if_missing"):
168
+ path = Path(context.source)
169
+ try:
170
+ path.parent.mkdir(parents=True, exist_ok=True)
171
+
172
+ # Create with default content
173
+ default_content = context.metadata.get("default_content", {})
174
+
175
+ if path.suffix == ".json":
176
+ path.write_text(json.dumps(default_content, indent=2))
177
+ else:
178
+ path.write_text(str(default_content))
179
+
180
+ result.recovered = True
181
+ result.should_retry = True
182
+ result.actions_taken.append(f"Created missing file: {path}")
183
+ self.logger.info(f"Created missing configuration file: {path}")
184
+
185
+ except Exception as e:
186
+ self.logger.error(f"Failed to create file: {e}")
187
+ result.should_escalate = True
188
+
189
+ return result
190
+
191
+ def _handle_permission_error(self, context: ErrorContext) -> ErrorHandlingResult:
192
+ """Handle permission errors"""
193
+ result = ErrorHandlingResult(handled=True)
194
+
195
+ # Try alternative location
196
+ if context.metadata.get("alt_location"):
197
+ alt_path = Path(context.metadata["alt_location"])
198
+ try:
199
+ # Test write permission
200
+ alt_path.parent.mkdir(parents=True, exist_ok=True)
201
+ test_file = alt_path.parent / ".test_write"
202
+ test_file.touch()
203
+ test_file.unlink()
204
+
205
+ result.recovered = True
206
+ result.fallback_value = str(alt_path)
207
+ result.actions_taken.append(f"Using alternative location: {alt_path}")
208
+
209
+ except (OSError, PermissionError):
210
+ result.should_escalate = True
211
+
212
+ # Use read-only mode if applicable
213
+ elif context.metadata.get("allow_readonly"):
214
+ result.recovered = True
215
+ result.fallback_value = {"readonly": True}
216
+ result.actions_taken.append("Switched to read-only mode")
217
+
218
+ return result
219
+
220
+ def _handle_generic_io_error(self, context: ErrorContext) -> ErrorHandlingResult:
221
+ """Handle generic I/O errors"""
222
+ result = ErrorHandlingResult(handled=True)
223
+
224
+ # Retry with exponential backoff
225
+ retry_count = context.metadata.get("retry_count", 0)
226
+ max_retries = context.metadata.get("max_retries", 3)
227
+
228
+ if retry_count < max_retries:
229
+ result.should_retry = True
230
+ result.retry_after = 2**retry_count # Exponential backoff
231
+ result.actions_taken.append(
232
+ f"Retry {retry_count + 1}/{max_retries} after {result.retry_after}s"
233
+ )
234
+ else:
235
+ result.should_escalate = True
236
+ result.message = f"Failed after {max_retries} retries"
237
+
238
+ return result
239
+
240
+
241
+ class ParsingErrorHandler(BaseErrorHandler):
242
+ """Handles parsing errors - consolidates 22 parsing error patterns"""
243
+
244
+ PARSER_ERRORS: ClassVar[dict] = {
245
+ json.JSONDecodeError: ErrorCategory.PARSING,
246
+ ValueError: ErrorCategory.PARSING, # Common for parsing
247
+ SyntaxError: ErrorCategory.PARSING,
248
+ }
249
+
250
+ def can_handle(self, context: ErrorContext) -> bool:
251
+ """Check if error is parsing related"""
252
+ return (
253
+ context.category == ErrorCategory.PARSING
254
+ or type(context.error) in self.PARSER_ERRORS
255
+ or "parse" in str(context.error).lower()
256
+ or "decode" in str(context.error).lower()
257
+ )
258
+
259
+ def handle(self, context: ErrorContext) -> ErrorHandlingResult:
260
+ """Handle parsing errors with recovery strategies"""
261
+ result = ErrorHandlingResult(handled=True)
262
+
263
+ # Try recovery strategies based on error type
264
+ if isinstance(context.error, json.JSONDecodeError):
265
+ result = self._handle_json_error(context)
266
+ elif "yaml" in str(context.error).lower():
267
+ result = self._handle_yaml_error(context)
268
+ else:
269
+ result = self._handle_generic_parse_error(context)
270
+
271
+ return result
272
+
273
+ def _handle_json_error(self, context: ErrorContext) -> ErrorHandlingResult:
274
+ """Handle JSON parsing errors"""
275
+ result = ErrorHandlingResult(handled=True)
276
+
277
+ content = context.metadata.get("content", "")
278
+
279
+ # Try to fix common JSON issues
280
+ fixes = [
281
+ self._fix_json_comments,
282
+ self._fix_json_quotes,
283
+ self._fix_json_trailing_commas,
284
+ self._fix_json_unquoted_keys,
285
+ ]
286
+
287
+ for fix_func in fixes:
288
+ try:
289
+ fixed_content = fix_func(content)
290
+ parsed = json.loads(fixed_content)
291
+ result.recovered = True
292
+ result.fallback_value = parsed
293
+ result.actions_taken.append(f"Fixed JSON with {fix_func.__name__}")
294
+ self.logger.info(f"Recovered from JSON error using {fix_func.__name__}")
295
+ return result
296
+ except (json.JSONDecodeError, ValueError, TypeError):
297
+ continue
298
+
299
+ # Use lenient parser if available
300
+ if context.metadata.get("allow_lenient"):
301
+ result = self._parse_lenient_json(content, result)
302
+
303
+ return result
304
+
305
+ def _fix_json_comments(self, content: str) -> str:
306
+ """Remove comments from JSON"""
307
+ import re
308
+
309
+ # Remove single-line comments
310
+ content = re.sub(r"//.*?$", "", content, flags=re.MULTILINE)
311
+ # Remove multi-line comments
312
+ return re.sub(r"/\*.*?\*/", "", content, flags=re.DOTALL)
313
+
314
+ def _fix_json_quotes(self, content: str) -> str:
315
+ """Fix quote issues in JSON"""
316
+ import re
317
+
318
+ # Replace single quotes with double quotes (careful with values)
319
+ # This is a simple approach - more sophisticated parsing might be needed
320
+ content = re.sub(r"'([^']*)':", r'"\1":', content) # Keys
321
+ return re.sub(r":\s*'([^']*)'", r': "\1"', content) # Values
322
+
323
+ def _fix_json_trailing_commas(self, content: str) -> str:
324
+ """Remove trailing commas"""
325
+ import re
326
+
327
+ content = re.sub(r",\s*}", "}", content)
328
+ return re.sub(r",\s*]", "]", content)
329
+
330
+ def _fix_json_unquoted_keys(self, content: str) -> str:
331
+ """Add quotes to unquoted keys"""
332
+ import re
333
+
334
+ # Match unquoted keys (word characters followed by colon)
335
+ return re.sub(r"(\w+):", r'"\1":', content)
336
+
337
+ def _parse_lenient_json(
338
+ self, content: str, result: ErrorHandlingResult
339
+ ) -> ErrorHandlingResult:
340
+ """Parse JSON leniently"""
341
+ try:
342
+ # Try using ast.literal_eval for Python literals
343
+ import ast
344
+
345
+ parsed = ast.literal_eval(content)
346
+ result.recovered = True
347
+ result.fallback_value = parsed
348
+ result.actions_taken.append("Parsed as Python literal")
349
+ except (ValueError, SyntaxError, TypeError):
350
+ # Return empty dict as last resort
351
+ result.recovered = True
352
+ result.fallback_value = {}
353
+ result.actions_taken.append("Used empty configuration as fallback")
354
+
355
+ return result
356
+
357
+ def _handle_yaml_error(self, context: ErrorContext) -> ErrorHandlingResult:
358
+ """Handle YAML parsing errors"""
359
+ result = ErrorHandlingResult(handled=True)
360
+
361
+ content = context.metadata.get("content", "")
362
+
363
+ # Try to fix common YAML issues
364
+ try:
365
+ import yaml
366
+
367
+ # Try with safe loader
368
+ parsed = yaml.safe_load(content)
369
+ result.recovered = True
370
+ result.fallback_value = parsed
371
+ result.actions_taken.append("Parsed with safe YAML loader")
372
+
373
+ except (yaml.YAMLError, ValueError, AttributeError):
374
+ # Try to fix tabs
375
+ content = content.replace("\t", " ")
376
+ try:
377
+ parsed = yaml.safe_load(content)
378
+ result.recovered = True
379
+ result.fallback_value = parsed
380
+ result.actions_taken.append("Fixed YAML tabs")
381
+ except (yaml.YAMLError, ValueError, AttributeError):
382
+ result.fallback_value = {}
383
+ result.actions_taken.append("Used empty configuration as fallback")
384
+
385
+ return result
386
+
387
+ def _handle_generic_parse_error(self, context: ErrorContext) -> ErrorHandlingResult:
388
+ """Handle generic parsing errors"""
389
+ result = ErrorHandlingResult(handled=True)
390
+
391
+ # Try alternative formats
392
+ content = context.metadata.get("content", "")
393
+
394
+ formats = [
395
+ ("json", json.loads),
396
+ ("yaml", self._try_yaml),
397
+ ("ini", self._try_ini),
398
+ ("properties", self._try_properties),
399
+ ]
400
+
401
+ for format_name, parser in formats:
402
+ try:
403
+ parsed = parser(content)
404
+ if parsed:
405
+ result.recovered = True
406
+ result.fallback_value = parsed
407
+ result.actions_taken.append(f"Parsed as {format_name}")
408
+ return result
409
+ except (ValueError, TypeError, AttributeError, ImportError):
410
+ continue
411
+
412
+ # Use default/empty config
413
+ result.recovered = True
414
+ result.fallback_value = context.metadata.get("default_config", {})
415
+ result.actions_taken.append("Used default configuration")
416
+
417
+ return result
418
+
419
+ def _try_yaml(self, content: str) -> Dict:
420
+ """Try parsing as YAML"""
421
+ import yaml
422
+
423
+ return yaml.safe_load(content)
424
+
425
+ def _try_ini(self, content: str) -> Dict:
426
+ """Try parsing as INI"""
427
+ import configparser
428
+
429
+ parser = configparser.ConfigParser()
430
+ parser.read_string(content)
431
+ return {s: dict(parser.items(s)) for s in parser.sections()}
432
+
433
+ def _try_properties(self, content: str) -> Dict:
434
+ """Try parsing as properties file"""
435
+ result = {}
436
+ for line in content.splitlines():
437
+ line = line.strip()
438
+ if line and not line.startswith("#") and "=" in line:
439
+ key, value = line.split("=", 1)
440
+ result[key.strip()] = value.strip()
441
+ return result
442
+
443
+
444
+ class ValidationErrorHandler(BaseErrorHandler):
445
+ """Handles validation errors - consolidates 15 validation error patterns"""
446
+
447
+ def can_handle(self, context: ErrorContext) -> bool:
448
+ """Check if error is validation related"""
449
+ return (
450
+ context.category == ErrorCategory.VALIDATION
451
+ or "validation" in str(context.error).lower()
452
+ or "invalid" in str(context.error).lower()
453
+ or "constraint" in str(context.error).lower()
454
+ )
455
+
456
+ def handle(self, context: ErrorContext) -> ErrorHandlingResult:
457
+ """Handle validation errors"""
458
+ result = ErrorHandlingResult(handled=True)
459
+
460
+ # Get validation details
461
+ field = context.metadata.get("field")
462
+ value = context.metadata.get("value")
463
+ schema = context.metadata.get("schema")
464
+
465
+ # Try to fix or provide default
466
+ if field and schema:
467
+ result = self._fix_validation_error(field, value, schema, result)
468
+ else:
469
+ result = self._handle_generic_validation(context, result)
470
+
471
+ return result
472
+
473
+ def _fix_validation_error(
474
+ self, field: str, value: Any, schema: Dict, result: ErrorHandlingResult
475
+ ) -> ErrorHandlingResult:
476
+ """Try to fix validation error"""
477
+ field_schema = schema.get("properties", {}).get(field, {})
478
+
479
+ # Try type coercion
480
+ if "type" in field_schema:
481
+ expected_type = field_schema["type"]
482
+ coerced = self._coerce_type(value, expected_type)
483
+
484
+ if coerced is not None:
485
+ result.recovered = True
486
+ result.fallback_value = {field: coerced}
487
+ result.actions_taken.append(f"Coerced {field} to {expected_type}")
488
+ return result
489
+
490
+ # Use default value if available
491
+ if "default" in field_schema:
492
+ result.recovered = True
493
+ result.fallback_value = {field: field_schema["default"]}
494
+ result.actions_taken.append(f"Used default value for {field}")
495
+ return result
496
+
497
+ # Use minimum/maximum for range errors
498
+ if "minimum" in field_schema and isinstance(value, (int, float)):
499
+ if value < field_schema["minimum"]:
500
+ result.recovered = True
501
+ result.fallback_value = {field: field_schema["minimum"]}
502
+ result.actions_taken.append(f"Clamped {field} to minimum")
503
+ return result
504
+
505
+ if "maximum" in field_schema and isinstance(value, (int, float)):
506
+ if value > field_schema["maximum"]:
507
+ result.recovered = True
508
+ result.fallback_value = {field: field_schema["maximum"]}
509
+ result.actions_taken.append(f"Clamped {field} to maximum")
510
+ return result
511
+
512
+ return result
513
+
514
+ def _coerce_type(self, value: Any, expected_type: str) -> Any:
515
+ """Attempt to coerce value to expected type"""
516
+ try:
517
+ if expected_type == "string":
518
+ return str(value)
519
+ if expected_type == "integer":
520
+ return int(value)
521
+ if expected_type == "number":
522
+ return float(value)
523
+ if expected_type == "boolean":
524
+ if isinstance(value, str):
525
+ return value.lower() in ["true", "yes", "1", "on"]
526
+ return bool(value)
527
+ if expected_type == "array":
528
+ if isinstance(value, str):
529
+ # Try comma-separated
530
+ return [v.strip() for v in value.split(",")]
531
+ return list(value)
532
+ if expected_type == "object":
533
+ if isinstance(value, str):
534
+ return json.loads(value)
535
+ return dict(value)
536
+ except (ValueError, TypeError, json.JSONDecodeError):
537
+ return None
538
+
539
+ def _handle_generic_validation(
540
+ self, context: ErrorContext, result: ErrorHandlingResult
541
+ ) -> ErrorHandlingResult:
542
+ """Handle generic validation errors"""
543
+ # Use strict vs lenient mode
544
+ if context.metadata.get("strict", True):
545
+ result.should_escalate = True
546
+ result.message = "Validation failed in strict mode"
547
+ else:
548
+ # In lenient mode, use config as-is with warnings
549
+ result.recovered = True
550
+ result.fallback_value = context.metadata.get("config", {})
551
+ result.actions_taken.append("Accepted configuration in lenient mode")
552
+ self.logger.warning(
553
+ f"Validation error ignored in lenient mode: {context.error}"
554
+ )
555
+
556
+ return result
557
+
558
+
559
+ class NetworkErrorHandler(BaseErrorHandler):
560
+ """Handles network-related errors - consolidates 12 network error patterns"""
561
+
562
+ NETWORK_ERRORS: ClassVar[list] = [
563
+ ConnectionError,
564
+ TimeoutError,
565
+ ConnectionRefusedError,
566
+ ConnectionResetError,
567
+ BrokenPipeError,
568
+ ]
569
+
570
+ def can_handle(self, context: ErrorContext) -> bool:
571
+ """Check if error is network related"""
572
+ return (
573
+ context.category == ErrorCategory.NETWORK
574
+ or any(isinstance(context.error, err) for err in self.NETWORK_ERRORS)
575
+ or "connection" in str(context.error).lower()
576
+ or "timeout" in str(context.error).lower()
577
+ )
578
+
579
+ def handle(self, context: ErrorContext) -> ErrorHandlingResult:
580
+ """Handle network errors with retry logic"""
581
+ result = ErrorHandlingResult(handled=True)
582
+
583
+ # Implement exponential backoff retry
584
+ retry_count = context.metadata.get("retry_count", 0)
585
+ max_retries = context.metadata.get("max_retries", 5)
586
+
587
+ if retry_count < max_retries:
588
+ # Calculate backoff time
589
+ backoff = min(300, 2**retry_count) # Max 5 minutes
590
+ result.should_retry = True
591
+ result.retry_after = backoff
592
+ result.actions_taken.append(
593
+ f"Retry {retry_count + 1}/{max_retries} after {backoff}s"
594
+ )
595
+
596
+ # Add jitter to prevent thundering herd
597
+ import random
598
+
599
+ result.retry_after += random.uniform(0, backoff * 0.1)
600
+
601
+ # Try offline/cached mode
602
+ elif context.metadata.get("cache_available"):
603
+ result.recovered = True
604
+ result.fallback_value = context.metadata.get("cached_config")
605
+ result.actions_taken.append("Using cached configuration")
606
+ else:
607
+ result.should_escalate = True
608
+ result.message = f"Network error after {max_retries} retries"
609
+
610
+ return result
611
+
612
+
613
+ class TypeConversionErrorHandler(BaseErrorHandler):
614
+ """Handles type conversion errors - consolidates 10 type conversion patterns"""
615
+
616
+ def can_handle(self, context: ErrorContext) -> bool:
617
+ """Check if error is type conversion related"""
618
+ return (
619
+ context.category == ErrorCategory.TYPE_CONVERSION
620
+ or isinstance(context.error, (TypeError, ValueError))
621
+ or "type" in str(context.error).lower()
622
+ or "convert" in str(context.error).lower()
623
+ )
624
+
625
+ def handle(self, context: ErrorContext) -> ErrorHandlingResult:
626
+ """Handle type conversion errors"""
627
+ result = ErrorHandlingResult(handled=True)
628
+
629
+ source_value = context.metadata.get("value")
630
+ target_type = context.metadata.get("target_type")
631
+
632
+ if source_value is not None and target_type:
633
+ # Try intelligent conversion
634
+ converted = self._smart_convert(source_value, target_type)
635
+
636
+ if converted is not None:
637
+ result.recovered = True
638
+ result.fallback_value = converted
639
+ result.actions_taken.append(f"Converted to {target_type}")
640
+ else:
641
+ # Use default for type
642
+ default = self._get_type_default(target_type)
643
+ result.recovered = True
644
+ result.fallback_value = default
645
+ result.actions_taken.append(f"Used default for {target_type}")
646
+
647
+ return result
648
+
649
+ def _smart_convert(self, value: Any, target_type: Type) -> Any:
650
+ """Smart type conversion with fallbacks"""
651
+ converters = {
652
+ str: self._to_string,
653
+ int: self._to_int,
654
+ float: self._to_float,
655
+ bool: self._to_bool,
656
+ list: self._to_list,
657
+ dict: self._to_dict,
658
+ }
659
+
660
+ converter = converters.get(target_type)
661
+ if converter:
662
+ try:
663
+ return converter(value)
664
+ except (ValueError, TypeError, AttributeError):
665
+ pass
666
+
667
+ return None
668
+
669
+ def _to_string(self, value: Any) -> str:
670
+ """Convert to string"""
671
+ if isinstance(value, bytes):
672
+ return value.decode("utf-8", errors="replace")
673
+ return str(value)
674
+
675
+ def _to_int(self, value: Any) -> int:
676
+ """Convert to integer"""
677
+ if isinstance(value, str):
678
+ # Try to extract number from string
679
+ import re
680
+
681
+ match = re.search(r"-?\d+", value)
682
+ if match:
683
+ return int(match.group())
684
+ return int(float(value))
685
+
686
+ def _to_float(self, value: Any) -> float:
687
+ """Convert to float"""
688
+ if isinstance(value, str):
689
+ # Handle percentage
690
+ if "%" in value:
691
+ return float(value.replace("%", "")) / 100
692
+ # Handle comma as decimal separator
693
+ value = value.replace(",", ".")
694
+ return float(value)
695
+
696
+ def _to_bool(self, value: Any) -> bool:
697
+ """Convert to boolean"""
698
+ if isinstance(value, str):
699
+ return value.lower() in ["true", "yes", "1", "on", "enabled"]
700
+ return bool(value)
701
+
702
+ def _to_list(self, value: Any) -> list:
703
+ """Convert to list"""
704
+ if isinstance(value, str):
705
+ # Try JSON array
706
+ if value.startswith("["):
707
+ try:
708
+ return json.loads(value)
709
+ except (json.JSONDecodeError, ValueError):
710
+ pass
711
+ # Try comma-separated
712
+ return [v.strip() for v in value.split(",")]
713
+ if hasattr(value, "__iter__") and not isinstance(value, (str, bytes, dict)):
714
+ return list(value)
715
+ return [value]
716
+
717
+ def _to_dict(self, value: Any) -> dict:
718
+ """Convert to dictionary"""
719
+ if isinstance(value, str):
720
+ # Try JSON object
721
+ try:
722
+ return json.loads(value)
723
+ except (json.JSONDecodeError, ValueError):
724
+ pass
725
+ # Try key=value pairs
726
+ result = {}
727
+ for pair in value.split(","):
728
+ if "=" in pair:
729
+ k, v = pair.split("=", 1)
730
+ result[k.strip()] = v.strip()
731
+ return result
732
+ if hasattr(value, "__dict__"):
733
+ return vars(value)
734
+ return {}
735
+
736
+ def _get_type_default(self, target_type: Type) -> Any:
737
+ """Get default value for type"""
738
+ defaults = {
739
+ str: "",
740
+ int: 0,
741
+ float: 0.0,
742
+ bool: False,
743
+ list: [],
744
+ dict: {},
745
+ type(None): None,
746
+ }
747
+ return defaults.get(target_type)
748
+
749
+
750
+ class CompositeErrorHandler(BaseErrorHandler):
751
+ """Orchestrates multiple error handlers - consolidates 22 composite patterns"""
752
+
753
+ def __init__(self):
754
+ super().__init__()
755
+ self.handlers = [
756
+ FileIOErrorHandler(),
757
+ ParsingErrorHandler(),
758
+ ValidationErrorHandler(),
759
+ NetworkErrorHandler(),
760
+ TypeConversionErrorHandler(),
761
+ ]
762
+
763
+ def can_handle(self, context: ErrorContext) -> bool:
764
+ """Composite handler can handle any error"""
765
+ return True
766
+
767
+ def handle(self, context: ErrorContext) -> ErrorHandlingResult:
768
+ """Try multiple handlers in sequence"""
769
+ # First, try specific handlers
770
+ for handler in self.handlers:
771
+ if handler.can_handle(context):
772
+ result = handler.handle(context)
773
+
774
+ if result.recovered or not result.should_escalate:
775
+ return result
776
+
777
+ # If no specific handler worked, use fallback strategies
778
+ return self._handle_unknown_error(context)
779
+
780
+ def _handle_unknown_error(self, context: ErrorContext) -> ErrorHandlingResult:
781
+ """Handle unknown errors with generic strategies"""
782
+ result = ErrorHandlingResult(handled=True)
783
+
784
+ # Log the full error
785
+ self.logger.error(
786
+ f"Unknown error in {context.operation}: {context.error}", exc_info=True
787
+ )
788
+
789
+ # Try generic recovery strategies
790
+ if context.metadata.get("default_config"):
791
+ result.recovered = True
792
+ result.fallback_value = context.metadata["default_config"]
793
+ result.actions_taken.append("Used default configuration for unknown error")
794
+ elif context.metadata.get("skip_on_error"):
795
+ result.recovered = True
796
+ result.fallback_value = {}
797
+ result.actions_taken.append("Skipped configuration due to error")
798
+ else:
799
+ result.should_escalate = True
800
+ result.message = f"Unhandled error: {context.error}"
801
+
802
+ return result
803
+
804
+
805
+ class ErrorHandlingStrategy(IConfigStrategy):
806
+ """
807
+ Main error handling strategy
808
+ Unifies 99 error handling patterns into composable handlers
809
+ """
810
+
811
+ def __init__(self):
812
+ self.logger = get_logger(self.__class__.__name__)
813
+ self.composite_handler = CompositeErrorHandler()
814
+ self.error_history: List[ErrorContext] = []
815
+ self.recovery_strategies: Dict[str, Callable] = {}
816
+
817
+ def can_handle(self, source: Union[str, Path, Dict]) -> bool:
818
+ """Error handler can handle any source"""
819
+ return True
820
+
821
+ def load(self, source: Any, **kwargs) -> Dict[str, Any]:
822
+ """Not used for error handling"""
823
+ return {}
824
+
825
+ def validate(self, config: Dict[str, Any], schema: Optional[Dict] = None) -> bool:
826
+ """Validate with error handling"""
827
+ return True
828
+
829
+ def transform(self, config: Dict[str, Any]) -> Dict[str, Any]:
830
+ """Transform config with error handling"""
831
+ return config
832
+
833
+ def handle_error(
834
+ self,
835
+ error: Exception,
836
+ source: Optional[str] = None,
837
+ operation: Optional[str] = None,
838
+ **metadata,
839
+ ) -> ErrorHandlingResult:
840
+ """Main error handling entry point"""
841
+ # Categorize error
842
+ category = self._categorize_error(error)
843
+ severity = self._determine_severity(error, category)
844
+
845
+ # Create error context
846
+ context = ErrorContext(
847
+ error=error,
848
+ category=category,
849
+ severity=severity,
850
+ source=source,
851
+ operation=operation,
852
+ traceback=traceback.format_exc(),
853
+ metadata=metadata,
854
+ )
855
+
856
+ # Record in history
857
+ self.error_history.append(context)
858
+
859
+ # Handle the error
860
+ result = self.composite_handler.handle(context)
861
+
862
+ # Apply recovery strategies if needed
863
+ if not result.recovered and self.recovery_strategies:
864
+ result = self._apply_recovery_strategies(context, result)
865
+
866
+ # Update context
867
+ context.recovery_attempted = result.recovered or result.should_retry
868
+ context.recovery_successful = result.recovered
869
+
870
+ return result
871
+
872
+ def _categorize_error(self, error: Exception) -> ErrorCategory:
873
+ """Categorize the error type"""
874
+ type(error)
875
+
876
+ # File I/O errors
877
+ if isinstance(error, (FileNotFoundError, PermissionError, IOError, OSError)):
878
+ return ErrorCategory.FILE_IO
879
+
880
+ # Parsing errors
881
+ if isinstance(error, (json.JSONDecodeError, ValueError, SyntaxError)):
882
+ if "parse" in str(error).lower() or "decode" in str(error).lower():
883
+ return ErrorCategory.PARSING
884
+
885
+ # Network errors
886
+ if isinstance(error, (ConnectionError, TimeoutError)):
887
+ return ErrorCategory.NETWORK
888
+
889
+ # Type conversion errors
890
+ if isinstance(error, TypeError):
891
+ return ErrorCategory.TYPE_CONVERSION
892
+
893
+ # Check error message for hints
894
+ error_msg = str(error).lower()
895
+
896
+ if "validation" in error_msg or "invalid" in error_msg:
897
+ return ErrorCategory.VALIDATION
898
+ if "permission" in error_msg or "access" in error_msg:
899
+ return ErrorCategory.PERMISSION
900
+ if "not found" in error_msg or "missing" in error_msg:
901
+ return ErrorCategory.MISSING_DEPENDENCY
902
+ if "config" in error_msg or "setting" in error_msg:
903
+ return ErrorCategory.CONFIGURATION
904
+
905
+ return ErrorCategory.UNKNOWN
906
+
907
+ def _determine_severity(
908
+ self, error: Exception, category: ErrorCategory
909
+ ) -> ErrorSeverity:
910
+ """Determine error severity"""
911
+ # Critical errors
912
+ critical_types = [MemoryError, SystemError, KeyboardInterrupt]
913
+ if type(error) in critical_types:
914
+ return ErrorSeverity.CRITICAL
915
+
916
+ # Category-based severity
917
+ severity_map = {
918
+ ErrorCategory.FILE_IO: ErrorSeverity.ERROR,
919
+ ErrorCategory.PARSING: ErrorSeverity.WARNING,
920
+ ErrorCategory.VALIDATION: ErrorSeverity.WARNING,
921
+ ErrorCategory.NETWORK: ErrorSeverity.ERROR,
922
+ ErrorCategory.PERMISSION: ErrorSeverity.ERROR,
923
+ ErrorCategory.TYPE_CONVERSION: ErrorSeverity.WARNING,
924
+ ErrorCategory.MISSING_DEPENDENCY: ErrorSeverity.ERROR,
925
+ ErrorCategory.CONFIGURATION: ErrorSeverity.ERROR,
926
+ ErrorCategory.RUNTIME: ErrorSeverity.ERROR,
927
+ ErrorCategory.UNKNOWN: ErrorSeverity.ERROR,
928
+ }
929
+
930
+ return severity_map.get(category, ErrorSeverity.ERROR)
931
+
932
+ def _apply_recovery_strategies(
933
+ self, context: ErrorContext, result: ErrorHandlingResult
934
+ ) -> ErrorHandlingResult:
935
+ """Apply custom recovery strategies"""
936
+ for name, strategy in self.recovery_strategies.items():
937
+ try:
938
+ recovery_result = strategy(context)
939
+ if recovery_result:
940
+ result.recovered = True
941
+ result.fallback_value = recovery_result
942
+ result.actions_taken.append(f"Applied recovery strategy: {name}")
943
+ return result
944
+ except Exception as e:
945
+ self.logger.debug(f"Recovery strategy {name} failed: {e}")
946
+
947
+ return result
948
+
949
+ def register_recovery_strategy(self, name: str, strategy: Callable):
950
+ """Register a custom recovery strategy"""
951
+ self.recovery_strategies[name] = strategy
952
+ self.logger.debug(f"Registered recovery strategy: {name}")
953
+
954
+ def get_error_statistics(self) -> Dict[str, Any]:
955
+ """Get error handling statistics"""
956
+ if not self.error_history:
957
+ return {
958
+ "total_errors": 0,
959
+ "categories": {},
960
+ "severities": {},
961
+ "recovery_rate": 0.0,
962
+ }
963
+
964
+ total = len(self.error_history)
965
+ recovered = sum(1 for e in self.error_history if e.recovery_successful)
966
+
967
+ categories = {}
968
+ severities = {}
969
+
970
+ for error in self.error_history:
971
+ # Count by category
972
+ cat_name = error.category.value
973
+ categories[cat_name] = categories.get(cat_name, 0) + 1
974
+
975
+ # Count by severity
976
+ sev_name = error.severity.value
977
+ severities[sev_name] = severities.get(sev_name, 0) + 1
978
+
979
+ return {
980
+ "total_errors": total,
981
+ "recovered": recovered,
982
+ "recovery_rate": (recovered / total) * 100 if total > 0 else 0,
983
+ "categories": categories,
984
+ "severities": severities,
985
+ "recent_errors": [
986
+ {
987
+ "timestamp": e.timestamp.isoformat(),
988
+ "category": e.category.value,
989
+ "severity": e.severity.value,
990
+ "operation": e.operation,
991
+ "recovered": e.recovery_successful,
992
+ }
993
+ for e in self.error_history[-10:] # Last 10 errors
994
+ ],
995
+ }
996
+
997
+
998
+ # Export main components
999
+ __all__ = [
1000
+ "ErrorCategory",
1001
+ "ErrorContext",
1002
+ "ErrorHandlingResult",
1003
+ "ErrorHandlingStrategy",
1004
+ "ErrorSeverity",
1005
+ ]