claude-mpm 4.1.26__py3-none-any.whl → 4.24.0__py3-none-any.whl

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

Potentially problematic release.


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

Files changed (845) hide show
  1. claude_mpm/BUILD_NUMBER +1 -1
  2. claude_mpm/VERSION +1 -1
  3. claude_mpm/__init__.py +20 -5
  4. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +118 -0
  5. claude_mpm/agents/BASE_DOCUMENTATION.md +53 -0
  6. claude_mpm/agents/BASE_ENGINEER.md +658 -0
  7. claude_mpm/agents/BASE_OPS.md +219 -0
  8. claude_mpm/agents/BASE_PM.md +420 -158
  9. claude_mpm/agents/BASE_PROMPT_ENGINEER.md +787 -0
  10. claude_mpm/agents/BASE_QA.md +167 -0
  11. claude_mpm/agents/BASE_RESEARCH.md +53 -0
  12. claude_mpm/agents/OUTPUT_STYLE.md +299 -29
  13. claude_mpm/agents/PM_INSTRUCTIONS.md +1159 -0
  14. claude_mpm/agents/WORKFLOW.md +355 -191
  15. claude_mpm/agents/agent_loader.py +40 -10
  16. claude_mpm/agents/agent_loader_integration.py +3 -2
  17. claude_mpm/agents/async_agent_loader.py +3 -3
  18. claude_mpm/agents/base_agent_loader.py +11 -9
  19. claude_mpm/agents/frontmatter_validator.py +291 -251
  20. claude_mpm/agents/system_agent_config.py +3 -2
  21. claude_mpm/agents/templates/README.md +465 -0
  22. claude_mpm/agents/templates/agent-manager.json +7 -4
  23. claude_mpm/agents/templates/{agentic_coder_optimizer.json → agentic-coder-optimizer.json} +33 -7
  24. claude_mpm/agents/templates/api_qa.json +16 -4
  25. claude_mpm/agents/templates/circuit_breakers.md +638 -0
  26. claude_mpm/agents/templates/clerk-ops.json +235 -0
  27. claude_mpm/agents/templates/code_analyzer.json +10 -4
  28. claude_mpm/agents/templates/content-agent.json +358 -0
  29. claude_mpm/agents/templates/dart_engineer.json +307 -0
  30. claude_mpm/agents/templates/data_engineer.json +87 -14
  31. claude_mpm/agents/templates/documentation.json +76 -13
  32. claude_mpm/agents/templates/engineer.json +43 -9
  33. claude_mpm/agents/templates/gcp_ops_agent.json +253 -0
  34. claude_mpm/agents/templates/git_file_tracking.md +584 -0
  35. claude_mpm/agents/templates/golang_engineer.json +270 -0
  36. claude_mpm/agents/templates/imagemagick.json +5 -2
  37. claude_mpm/agents/templates/java_engineer.json +346 -0
  38. claude_mpm/agents/templates/javascript_engineer_agent.json +380 -0
  39. claude_mpm/agents/templates/local_ops_agent.json +1840 -0
  40. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +400 -0
  41. claude_mpm/agents/templates/memory_manager.json +6 -3
  42. claude_mpm/agents/templates/nextjs_engineer.json +285 -0
  43. claude_mpm/agents/templates/ops.json +14 -4
  44. claude_mpm/agents/templates/php-engineer.json +287 -0
  45. claude_mpm/agents/templates/pm_examples.md +474 -0
  46. claude_mpm/agents/templates/pm_red_flags.md +262 -0
  47. claude_mpm/agents/templates/product_owner.json +338 -0
  48. claude_mpm/agents/templates/project_organizer.json +19 -5
  49. claude_mpm/agents/templates/prompt-engineer.json +737 -0
  50. claude_mpm/agents/templates/python_engineer.json +387 -0
  51. claude_mpm/agents/templates/qa.json +25 -5
  52. claude_mpm/agents/templates/react_engineer.json +239 -0
  53. claude_mpm/agents/templates/refactoring_engineer.json +15 -5
  54. claude_mpm/agents/templates/research.json +46 -21
  55. claude_mpm/agents/templates/response_format.md +583 -0
  56. claude_mpm/agents/templates/ruby-engineer.json +280 -0
  57. claude_mpm/agents/templates/rust_engineer.json +275 -0
  58. claude_mpm/agents/templates/security.json +59 -10
  59. claude_mpm/agents/templates/svelte-engineer.json +225 -0
  60. claude_mpm/agents/templates/tauri_engineer.json +274 -0
  61. claude_mpm/agents/templates/ticketing.json +16 -7
  62. claude_mpm/agents/templates/typescript_engineer.json +285 -0
  63. claude_mpm/agents/templates/validation_templates.md +312 -0
  64. claude_mpm/agents/templates/vercel_ops_agent.json +164 -33
  65. claude_mpm/agents/templates/version_control.json +16 -4
  66. claude_mpm/agents/templates/web_qa.json +167 -21
  67. claude_mpm/agents/templates/web_ui.json +18 -5
  68. claude_mpm/cli/__init__.py +38 -378
  69. claude_mpm/cli/commands/__init__.py +2 -0
  70. claude_mpm/cli/commands/agent_manager.py +675 -20
  71. claude_mpm/cli/commands/agent_state_manager.py +186 -0
  72. claude_mpm/cli/commands/agents.py +722 -150
  73. claude_mpm/cli/commands/agents_detect.py +380 -0
  74. claude_mpm/cli/commands/agents_recommend.py +309 -0
  75. claude_mpm/cli/commands/aggregate.py +10 -6
  76. claude_mpm/cli/commands/analyze.py +15 -10
  77. claude_mpm/cli/commands/analyze_code.py +8 -4
  78. claude_mpm/cli/commands/auto_configure.py +570 -0
  79. claude_mpm/cli/commands/cleanup.py +12 -12
  80. claude_mpm/cli/commands/config.py +47 -13
  81. claude_mpm/cli/commands/configure.py +469 -1064
  82. claude_mpm/cli/commands/configure_agent_display.py +261 -0
  83. claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
  84. claude_mpm/cli/commands/configure_hook_manager.py +225 -0
  85. claude_mpm/cli/commands/configure_models.py +18 -0
  86. claude_mpm/cli/commands/configure_navigation.py +167 -0
  87. claude_mpm/cli/commands/configure_paths.py +104 -0
  88. claude_mpm/cli/commands/configure_persistence.py +254 -0
  89. claude_mpm/cli/commands/configure_startup_manager.py +646 -0
  90. claude_mpm/cli/commands/configure_template_editor.py +497 -0
  91. claude_mpm/cli/commands/configure_validators.py +73 -0
  92. claude_mpm/cli/commands/dashboard.py +50 -52
  93. claude_mpm/cli/commands/debug.py +7 -7
  94. claude_mpm/cli/commands/doctor.py +43 -7
  95. claude_mpm/cli/commands/info.py +3 -4
  96. claude_mpm/cli/commands/local_deploy.py +537 -0
  97. claude_mpm/cli/commands/mcp.py +17 -10
  98. claude_mpm/cli/commands/mcp_command_router.py +11 -0
  99. claude_mpm/cli/commands/mcp_config.py +154 -0
  100. claude_mpm/cli/commands/mcp_external_commands.py +249 -0
  101. claude_mpm/cli/commands/mcp_install_commands.py +101 -32
  102. claude_mpm/cli/commands/mcp_pipx_config.py +2 -2
  103. claude_mpm/cli/commands/mcp_setup_external.py +868 -0
  104. claude_mpm/cli/commands/memory.py +55 -21
  105. claude_mpm/cli/commands/monitor.py +160 -70
  106. claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
  107. claude_mpm/cli/commands/mpm_init/core.py +525 -0
  108. claude_mpm/cli/commands/mpm_init/display.py +341 -0
  109. claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
  110. claude_mpm/cli/commands/mpm_init/modes.py +397 -0
  111. claude_mpm/cli/commands/mpm_init/prompts.py +442 -0
  112. claude_mpm/cli/commands/mpm_init_cli.py +396 -0
  113. claude_mpm/cli/commands/mpm_init_handler.py +114 -4
  114. claude_mpm/cli/commands/run.py +169 -42
  115. claude_mpm/cli/commands/search.py +458 -0
  116. claude_mpm/cli/commands/skills.py +488 -0
  117. claude_mpm/cli/commands/uninstall.py +176 -0
  118. claude_mpm/cli/commands/upgrade.py +152 -0
  119. claude_mpm/cli/commands/verify.py +119 -0
  120. claude_mpm/cli/executor.py +204 -0
  121. claude_mpm/cli/helpers.py +105 -0
  122. claude_mpm/cli/interactive/__init__.py +21 -0
  123. claude_mpm/cli/interactive/agent_wizard.py +962 -0
  124. claude_mpm/cli/interactive/skills_wizard.py +491 -0
  125. claude_mpm/cli/parser.py +79 -2
  126. claude_mpm/cli/parsers/__init__.py +7 -1
  127. claude_mpm/cli/parsers/agent_manager_parser.py +161 -1
  128. claude_mpm/cli/parsers/agents_parser.py +116 -0
  129. claude_mpm/cli/parsers/auto_configure_parser.py +245 -0
  130. claude_mpm/cli/parsers/base_parser.py +143 -3
  131. claude_mpm/cli/parsers/configure_parser.py +11 -15
  132. claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
  133. claude_mpm/cli/parsers/mcp_parser.py +15 -0
  134. claude_mpm/cli/parsers/monitor_parser.py +12 -2
  135. claude_mpm/cli/parsers/mpm_init_parser.py +179 -9
  136. claude_mpm/cli/parsers/run_parser.py +5 -0
  137. claude_mpm/cli/parsers/search_parser.py +245 -0
  138. claude_mpm/cli/parsers/skills_parser.py +137 -0
  139. claude_mpm/cli/shared/argument_patterns.py +20 -13
  140. claude_mpm/cli/shared/base_command.py +2 -2
  141. claude_mpm/cli/shared/output_formatters.py +28 -19
  142. claude_mpm/cli/startup.py +562 -0
  143. claude_mpm/cli/startup_logging.py +179 -13
  144. claude_mpm/cli/utils.py +53 -2
  145. claude_mpm/commands/mpm-agents-detect.md +168 -0
  146. claude_mpm/commands/mpm-agents-recommend.md +214 -0
  147. claude_mpm/commands/mpm-agents.md +118 -8
  148. claude_mpm/commands/mpm-auto-configure.md +269 -0
  149. claude_mpm/commands/mpm-config.md +137 -14
  150. claude_mpm/commands/mpm-help.md +285 -5
  151. claude_mpm/commands/mpm-init.md +374 -15
  152. claude_mpm/commands/mpm-monitor.md +409 -0
  153. claude_mpm/commands/mpm-organize.md +295 -0
  154. claude_mpm/commands/mpm-resume.md +372 -0
  155. claude_mpm/commands/mpm-status.md +71 -9
  156. claude_mpm/commands/mpm-tickets.md +56 -7
  157. claude_mpm/commands/mpm-version.md +113 -0
  158. claude_mpm/commands/mpm.md +2 -0
  159. claude_mpm/config/agent_config.py +4 -4
  160. claude_mpm/config/experimental_features.py +7 -7
  161. claude_mpm/config/model_config.py +428 -0
  162. claude_mpm/config/paths.py +3 -2
  163. claude_mpm/config/socketio_config.py +3 -3
  164. claude_mpm/constants.py +15 -1
  165. claude_mpm/core/__init__.py +53 -17
  166. claude_mpm/core/agent_name_normalizer.py +3 -2
  167. claude_mpm/core/agent_registry.py +2 -2
  168. claude_mpm/core/agent_session_manager.py +10 -10
  169. claude_mpm/core/api_validator.py +330 -0
  170. claude_mpm/core/base_service.py +33 -23
  171. claude_mpm/core/cache.py +9 -9
  172. claude_mpm/core/claude_runner.py +19 -8
  173. claude_mpm/core/config.py +85 -8
  174. claude_mpm/core/config_aliases.py +7 -6
  175. claude_mpm/core/constants.py +65 -0
  176. claude_mpm/core/container.py +11 -5
  177. claude_mpm/core/enums.py +452 -0
  178. claude_mpm/core/error_handler.py +623 -0
  179. claude_mpm/core/factories.py +1 -1
  180. claude_mpm/core/file_utils.py +764 -0
  181. claude_mpm/core/framework/__init__.py +38 -0
  182. claude_mpm/core/framework/formatters/__init__.py +11 -0
  183. claude_mpm/core/framework/formatters/capability_generator.py +367 -0
  184. claude_mpm/core/framework/formatters/content_formatter.py +288 -0
  185. claude_mpm/core/framework/formatters/context_generator.py +185 -0
  186. claude_mpm/core/framework/loaders/__init__.py +13 -0
  187. claude_mpm/core/framework/loaders/agent_loader.py +210 -0
  188. claude_mpm/core/framework/loaders/file_loader.py +223 -0
  189. claude_mpm/core/framework/loaders/instruction_loader.py +161 -0
  190. claude_mpm/core/framework/loaders/packaged_loader.py +232 -0
  191. claude_mpm/core/framework/processors/__init__.py +11 -0
  192. claude_mpm/core/framework/processors/memory_processor.py +230 -0
  193. claude_mpm/core/framework/processors/metadata_processor.py +146 -0
  194. claude_mpm/core/framework/processors/template_processor.py +244 -0
  195. claude_mpm/core/framework_loader.py +321 -1631
  196. claude_mpm/core/hook_manager.py +8 -6
  197. claude_mpm/core/injectable_service.py +11 -8
  198. claude_mpm/core/instruction_reinforcement_hook.py +4 -3
  199. claude_mpm/core/interactive_session.py +55 -8
  200. claude_mpm/core/interfaces.py +56 -1
  201. claude_mpm/core/lazy.py +3 -3
  202. claude_mpm/core/log_manager.py +92 -23
  203. claude_mpm/core/logger.py +19 -14
  204. claude_mpm/core/logging_config.py +6 -2
  205. claude_mpm/core/logging_utils.py +520 -0
  206. claude_mpm/core/oneshot_session.py +51 -7
  207. claude_mpm/core/optimized_agent_loader.py +9 -9
  208. claude_mpm/core/optimized_startup.py +1 -1
  209. claude_mpm/core/output_style_manager.py +12 -192
  210. claude_mpm/core/pm_hook_interceptor.py +18 -12
  211. claude_mpm/core/service_registry.py +7 -3
  212. claude_mpm/core/session_manager.py +14 -12
  213. claude_mpm/core/shared/config_loader.py +1 -1
  214. claude_mpm/core/socketio_pool.py +15 -15
  215. claude_mpm/core/tool_access_control.py +3 -2
  216. claude_mpm/core/types.py +4 -11
  217. claude_mpm/core/typing_utils.py +7 -6
  218. claude_mpm/core/unified_agent_registry.py +115 -11
  219. claude_mpm/core/unified_config.py +6 -6
  220. claude_mpm/core/unified_paths.py +23 -20
  221. claude_mpm/dashboard/analysis_runner.py +4 -4
  222. claude_mpm/dashboard/api/simple_directory.py +261 -0
  223. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +188 -0
  224. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +156 -0
  225. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +38 -0
  226. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +92 -0
  227. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +248 -0
  228. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +61 -0
  229. claude_mpm/dashboard/static/archive/test_activity_connection.html +179 -0
  230. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +68 -0
  231. claude_mpm/dashboard/static/archive/test_dashboard.html +409 -0
  232. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +519 -0
  233. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +181 -0
  234. claude_mpm/dashboard/static/archive/test_file_data.html +315 -0
  235. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +243 -0
  236. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +234 -0
  237. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +117 -0
  238. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +115 -0
  239. claude_mpm/dashboard/static/archive/test_file_viewer.html +224 -0
  240. claude_mpm/dashboard/static/archive/test_final_activity.html +220 -0
  241. claude_mpm/dashboard/static/archive/test_tab_fix.html +139 -0
  242. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +1 -0
  243. claude_mpm/dashboard/static/built/components/activity-tree.js +1 -1
  244. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +777 -0
  245. claude_mpm/dashboard/static/built/components/agent-inference.js +1 -1
  246. claude_mpm/dashboard/static/built/components/build-tracker.js +333 -0
  247. claude_mpm/dashboard/static/built/components/code-simple.js +857 -0
  248. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +353 -0
  249. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +235 -0
  250. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +409 -0
  251. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +435 -0
  252. claude_mpm/dashboard/static/built/components/code-tree.js +1 -1
  253. claude_mpm/dashboard/static/built/components/code-viewer.js +1 -1
  254. claude_mpm/dashboard/static/built/components/connection-debug.js +654 -0
  255. claude_mpm/dashboard/static/built/components/diff-viewer.js +891 -0
  256. claude_mpm/dashboard/static/built/components/event-processor.js +1 -1
  257. claude_mpm/dashboard/static/built/components/event-viewer.js +1 -1
  258. claude_mpm/dashboard/static/built/components/export-manager.js +1 -1
  259. claude_mpm/dashboard/static/built/components/file-change-tracker.js +443 -0
  260. claude_mpm/dashboard/static/built/components/file-change-viewer.js +690 -0
  261. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +1 -1
  262. claude_mpm/dashboard/static/built/components/file-viewer.js +2 -0
  263. claude_mpm/dashboard/static/built/components/module-viewer.js +1 -1
  264. claude_mpm/dashboard/static/built/components/nav-bar.js +145 -0
  265. claude_mpm/dashboard/static/built/components/page-structure.js +429 -0
  266. claude_mpm/dashboard/static/built/components/session-manager.js +1 -1
  267. claude_mpm/dashboard/static/built/components/unified-data-viewer.js +1 -1
  268. claude_mpm/dashboard/static/built/components/working-directory.js +1 -1
  269. claude_mpm/dashboard/static/built/connection-manager.js +536 -0
  270. claude_mpm/dashboard/static/built/dashboard.js +1 -1
  271. claude_mpm/dashboard/static/built/extension-error-handler.js +164 -0
  272. claude_mpm/dashboard/static/built/react/events.js +30 -0
  273. claude_mpm/dashboard/static/built/shared/dom-helpers.js +396 -0
  274. claude_mpm/dashboard/static/built/shared/event-bus.js +330 -0
  275. claude_mpm/dashboard/static/built/shared/event-filter-service.js +540 -0
  276. claude_mpm/dashboard/static/built/shared/logger.js +385 -0
  277. claude_mpm/dashboard/static/built/shared/page-structure.js +249 -0
  278. claude_mpm/dashboard/static/built/shared/tooltip-service.js +253 -0
  279. claude_mpm/dashboard/static/built/socket-client.js +1 -1
  280. claude_mpm/dashboard/static/built/tab-isolation-fix.js +185 -0
  281. claude_mpm/dashboard/static/css/dashboard.css +588 -6
  282. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +1 -0
  283. claude_mpm/dashboard/static/dist/components/activity-tree.js +1 -1
  284. claude_mpm/dashboard/static/dist/components/agent-inference.js +1 -1
  285. claude_mpm/dashboard/static/dist/components/code-tree.js +1 -1
  286. claude_mpm/dashboard/static/dist/components/code-viewer.js +1 -1
  287. claude_mpm/dashboard/static/dist/components/event-processor.js +1 -1
  288. claude_mpm/dashboard/static/dist/components/event-viewer.js +1 -1
  289. claude_mpm/dashboard/static/dist/components/export-manager.js +1 -1
  290. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +1 -1
  291. claude_mpm/dashboard/static/dist/components/file-viewer.js +2 -0
  292. claude_mpm/dashboard/static/dist/components/module-viewer.js +1 -1
  293. claude_mpm/dashboard/static/dist/components/session-manager.js +1 -1
  294. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +1 -1
  295. claude_mpm/dashboard/static/dist/components/working-directory.js +1 -1
  296. claude_mpm/dashboard/static/dist/dashboard.js +1 -1
  297. claude_mpm/dashboard/static/dist/react/events.js +30 -0
  298. claude_mpm/dashboard/static/dist/socket-client.js +1 -1
  299. claude_mpm/dashboard/static/events.html +607 -0
  300. claude_mpm/dashboard/static/index.html +635 -0
  301. claude_mpm/dashboard/static/js/components/activity-tree.js +3 -17
  302. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +4 -1
  303. claude_mpm/dashboard/static/js/components/agent-inference.js +3 -0
  304. claude_mpm/dashboard/static/js/components/build-tracker.js +8 -0
  305. claude_mpm/dashboard/static/js/components/code-simple.js +857 -0
  306. claude_mpm/dashboard/static/js/components/diff-viewer.js +891 -0
  307. claude_mpm/dashboard/static/js/components/event-processor.js +3 -0
  308. claude_mpm/dashboard/static/js/components/event-viewer.js +39 -2
  309. claude_mpm/dashboard/static/js/components/export-manager.js +3 -0
  310. claude_mpm/dashboard/static/js/components/file-change-tracker.js +443 -0
  311. claude_mpm/dashboard/static/js/components/file-change-viewer.js +690 -0
  312. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +30 -10
  313. claude_mpm/dashboard/static/js/components/file-viewer.js +580 -0
  314. claude_mpm/dashboard/static/js/components/module-viewer.js +26 -0
  315. claude_mpm/dashboard/static/js/components/session-manager.js +7 -7
  316. claude_mpm/dashboard/static/js/components/socket-manager.js +4 -0
  317. claude_mpm/dashboard/static/js/components/ui-state-manager.js +356 -41
  318. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +455 -23
  319. claude_mpm/dashboard/static/js/components/working-directory.js +44 -9
  320. claude_mpm/dashboard/static/js/dashboard.js +245 -132
  321. claude_mpm/dashboard/static/js/shared/dom-helpers.js +396 -0
  322. claude_mpm/dashboard/static/js/shared/event-bus.js +330 -0
  323. claude_mpm/dashboard/static/js/shared/logger.js +385 -0
  324. claude_mpm/dashboard/static/js/shared/tooltip-service.js +253 -0
  325. claude_mpm/dashboard/static/js/socket-client.js +49 -22
  326. claude_mpm/dashboard/static/js/stores/dashboard-store.js +562 -0
  327. claude_mpm/dashboard/static/js/tab-isolation-fix.js +185 -0
  328. claude_mpm/dashboard/static/legacy/activity.html +736 -0
  329. claude_mpm/dashboard/static/legacy/agents.html +786 -0
  330. claude_mpm/dashboard/static/legacy/files.html +747 -0
  331. claude_mpm/dashboard/static/legacy/tools.html +831 -0
  332. claude_mpm/dashboard/static/monitors.html +431 -0
  333. claude_mpm/dashboard/static/production/events.html +659 -0
  334. claude_mpm/dashboard/static/production/main.html +698 -0
  335. claude_mpm/dashboard/static/production/monitors.html +483 -0
  336. claude_mpm/dashboard/static/socket.io.min.js +7 -0
  337. claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +7 -0
  338. claude_mpm/dashboard/static/test-archive/dashboard.html +635 -0
  339. claude_mpm/dashboard/static/test-archive/debug-events.html +147 -0
  340. claude_mpm/dashboard/static/test-archive/test-navigation.html +256 -0
  341. claude_mpm/dashboard/static/test-archive/test-react-exports.html +180 -0
  342. claude_mpm/dashboard/static/test-archive/test_debug.html +25 -0
  343. claude_mpm/dashboard/templates/code_simple.html +153 -0
  344. claude_mpm/dashboard/templates/index.html +112 -109
  345. claude_mpm/experimental/cli_enhancements.py +4 -2
  346. claude_mpm/generators/agent_profile_generator.py +5 -3
  347. claude_mpm/hooks/__init__.py +37 -1
  348. claude_mpm/hooks/base_hook.py +5 -4
  349. claude_mpm/hooks/claude_hooks/connection_pool.py +4 -4
  350. claude_mpm/hooks/claude_hooks/event_handlers.py +21 -18
  351. claude_mpm/hooks/claude_hooks/hook_handler.py +29 -22
  352. claude_mpm/hooks/claude_hooks/installer.py +67 -22
  353. claude_mpm/hooks/claude_hooks/memory_integration.py +3 -3
  354. claude_mpm/hooks/claude_hooks/response_tracking.py +57 -17
  355. claude_mpm/hooks/claude_hooks/services/connection_manager.py +62 -64
  356. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +140 -76
  357. claude_mpm/hooks/claude_hooks/services/state_manager.py +11 -9
  358. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +3 -3
  359. claude_mpm/hooks/failure_learning/__init__.py +60 -0
  360. claude_mpm/hooks/failure_learning/failure_detection_hook.py +235 -0
  361. claude_mpm/hooks/failure_learning/fix_detection_hook.py +217 -0
  362. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +286 -0
  363. claude_mpm/hooks/instruction_reinforcement.py +301 -0
  364. claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
  365. claude_mpm/hooks/kuzu_memory_hook.py +386 -0
  366. claude_mpm/hooks/kuzu_response_hook.py +183 -0
  367. claude_mpm/hooks/memory_integration_hook.py +1 -1
  368. claude_mpm/hooks/session_resume_hook.py +121 -0
  369. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  370. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  371. claude_mpm/hooks/tool_call_interceptor.py +8 -5
  372. claude_mpm/hooks/validation_hooks.py +3 -3
  373. claude_mpm/init.py +23 -4
  374. claude_mpm/models/agent_session.py +8 -6
  375. claude_mpm/models/resume_log.py +340 -0
  376. claude_mpm/scripts/claude-hook-handler.sh +33 -7
  377. claude_mpm/scripts/launch_monitor.py +85 -0
  378. claude_mpm/scripts/mcp_server.py +3 -5
  379. claude_mpm/scripts/mpm_doctor.py +3 -2
  380. claude_mpm/scripts/socketio_daemon.py +159 -512
  381. claude_mpm/services/__init__.py +144 -160
  382. claude_mpm/services/agents/__init__.py +18 -5
  383. claude_mpm/services/agents/agent_builder.py +13 -11
  384. claude_mpm/services/agents/auto_config_manager.py +796 -0
  385. claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
  386. claude_mpm/services/agents/deployment/agent_deployment.py +38 -15
  387. claude_mpm/services/agents/deployment/agent_discovery_service.py +125 -7
  388. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +5 -5
  389. claude_mpm/services/agents/deployment/agent_format_converter.py +56 -12
  390. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +4 -2
  391. claude_mpm/services/agents/deployment/agent_operation_service.py +2 -2
  392. claude_mpm/services/agents/deployment/agent_record_service.py +4 -4
  393. claude_mpm/services/agents/deployment/agent_state_service.py +2 -2
  394. claude_mpm/services/agents/deployment/agent_template_builder.py +715 -47
  395. claude_mpm/services/agents/deployment/agent_validator.py +31 -7
  396. claude_mpm/services/agents/deployment/agent_version_manager.py +8 -5
  397. claude_mpm/services/agents/deployment/agent_versioning.py +1 -1
  398. claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
  399. claude_mpm/services/agents/deployment/deployment_config_loader.py +131 -7
  400. claude_mpm/services/agents/deployment/deployment_type_detector.py +10 -14
  401. claude_mpm/services/agents/deployment/deployment_wrapper.py +58 -0
  402. claude_mpm/services/agents/deployment/interface_adapter.py +3 -2
  403. claude_mpm/services/agents/deployment/local_template_deployment.py +360 -0
  404. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +134 -38
  405. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +8 -7
  406. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +7 -16
  407. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +4 -3
  408. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +7 -5
  409. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +6 -5
  410. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +9 -6
  411. claude_mpm/services/agents/deployment/system_instructions_deployer.py +9 -6
  412. claude_mpm/services/agents/deployment/validation/__init__.py +3 -1
  413. claude_mpm/services/agents/deployment/validation/template_validator.py +64 -44
  414. claude_mpm/services/agents/deployment/validation/validation_result.py +1 -9
  415. claude_mpm/services/agents/loading/agent_profile_loader.py +10 -9
  416. claude_mpm/services/agents/loading/base_agent_manager.py +16 -6
  417. claude_mpm/services/agents/loading/framework_agent_loader.py +2 -2
  418. claude_mpm/services/agents/local_template_manager.py +744 -0
  419. claude_mpm/services/agents/management/agent_capabilities_generator.py +3 -2
  420. claude_mpm/services/agents/management/agent_management_service.py +5 -5
  421. claude_mpm/services/agents/memory/agent_memory_manager.py +32 -29
  422. claude_mpm/services/agents/memory/content_manager.py +17 -9
  423. claude_mpm/services/agents/memory/memory_categorization_service.py +4 -2
  424. claude_mpm/services/agents/memory/memory_file_service.py +32 -6
  425. claude_mpm/services/agents/memory/memory_format_service.py +6 -4
  426. claude_mpm/services/agents/memory/memory_limits_service.py +4 -2
  427. claude_mpm/services/agents/memory/template_generator.py +3 -3
  428. claude_mpm/services/agents/observers.py +547 -0
  429. claude_mpm/services/agents/recommender.py +615 -0
  430. claude_mpm/services/agents/registry/deployed_agent_discovery.py +3 -3
  431. claude_mpm/services/agents/registry/modification_tracker.py +30 -19
  432. claude_mpm/services/async_session_logger.py +141 -98
  433. claude_mpm/services/claude_session_logger.py +82 -74
  434. claude_mpm/services/cli/agent_cleanup_service.py +5 -0
  435. claude_mpm/services/cli/agent_listing_service.py +5 -5
  436. claude_mpm/services/cli/agent_validation_service.py +3 -1
  437. claude_mpm/services/cli/memory_crud_service.py +12 -7
  438. claude_mpm/services/cli/memory_output_formatter.py +2 -2
  439. claude_mpm/services/cli/resume_service.py +617 -0
  440. claude_mpm/services/cli/session_manager.py +104 -13
  441. claude_mpm/services/cli/session_pause_manager.py +504 -0
  442. claude_mpm/services/cli/session_resume_helper.py +372 -0
  443. claude_mpm/services/cli/startup_checker.py +13 -10
  444. claude_mpm/services/cli/unified_dashboard_manager.py +439 -0
  445. claude_mpm/services/command_deployment_service.py +9 -7
  446. claude_mpm/services/command_handler_service.py +11 -5
  447. claude_mpm/services/core/__init__.py +33 -1
  448. claude_mpm/services/core/base.py +26 -11
  449. claude_mpm/services/core/interfaces/__init__.py +90 -3
  450. claude_mpm/services/core/interfaces/agent.py +184 -0
  451. claude_mpm/services/core/interfaces/health.py +172 -0
  452. claude_mpm/services/core/interfaces/model.py +281 -0
  453. claude_mpm/services/core/interfaces/process.py +372 -0
  454. claude_mpm/services/core/interfaces/project.py +121 -0
  455. claude_mpm/services/core/interfaces/restart.py +307 -0
  456. claude_mpm/services/core/interfaces/stability.py +260 -0
  457. claude_mpm/services/core/interfaces.py +56 -1
  458. claude_mpm/services/core/memory_manager.py +92 -47
  459. claude_mpm/services/core/models/__init__.py +79 -0
  460. claude_mpm/services/core/models/agent_config.py +384 -0
  461. claude_mpm/services/core/models/health.py +162 -0
  462. claude_mpm/services/core/models/process.py +239 -0
  463. claude_mpm/services/core/models/restart.py +302 -0
  464. claude_mpm/services/core/models/stability.py +264 -0
  465. claude_mpm/services/core/models/toolchain.py +306 -0
  466. claude_mpm/services/core/path_resolver.py +36 -14
  467. claude_mpm/services/diagnostics/__init__.py +2 -2
  468. claude_mpm/services/diagnostics/checks/__init__.py +4 -2
  469. claude_mpm/services/diagnostics/checks/agent_check.py +30 -32
  470. claude_mpm/services/diagnostics/checks/claude_code_check.py +270 -0
  471. claude_mpm/services/diagnostics/checks/common_issues_check.py +28 -27
  472. claude_mpm/services/diagnostics/checks/configuration_check.py +26 -25
  473. claude_mpm/services/diagnostics/checks/filesystem_check.py +18 -17
  474. claude_mpm/services/diagnostics/checks/installation_check.py +165 -60
  475. claude_mpm/services/diagnostics/checks/instructions_check.py +20 -19
  476. claude_mpm/services/diagnostics/checks/mcp_check.py +57 -43
  477. claude_mpm/services/diagnostics/checks/mcp_services_check.py +1066 -0
  478. claude_mpm/services/diagnostics/checks/monitor_check.py +24 -23
  479. claude_mpm/services/diagnostics/checks/startup_log_check.py +14 -11
  480. claude_mpm/services/diagnostics/diagnostic_runner.py +22 -13
  481. claude_mpm/services/diagnostics/doctor_reporter.py +275 -47
  482. claude_mpm/services/diagnostics/models.py +37 -21
  483. claude_mpm/services/event_aggregator.py +5 -3
  484. claude_mpm/services/event_bus/direct_relay.py +8 -4
  485. claude_mpm/services/event_bus/event_bus.py +51 -9
  486. claude_mpm/services/event_bus/relay.py +33 -14
  487. claude_mpm/services/events/consumers/dead_letter.py +7 -5
  488. claude_mpm/services/events/core.py +5 -6
  489. claude_mpm/services/events/producers/hook.py +6 -6
  490. claude_mpm/services/events/producers/system.py +8 -8
  491. claude_mpm/services/exceptions.py +5 -5
  492. claude_mpm/services/framework_claude_md_generator/__init__.py +1 -1
  493. claude_mpm/services/framework_claude_md_generator/content_assembler.py +5 -5
  494. claude_mpm/services/framework_claude_md_generator/content_validator.py +2 -2
  495. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +3 -3
  496. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +2 -2
  497. claude_mpm/services/framework_claude_md_generator/version_manager.py +1 -1
  498. claude_mpm/services/hook_installer_service.py +506 -0
  499. claude_mpm/services/hook_service.py +5 -6
  500. claude_mpm/services/infrastructure/context_preservation.py +13 -11
  501. claude_mpm/services/infrastructure/daemon_manager.py +9 -9
  502. claude_mpm/services/infrastructure/logging.py +2 -2
  503. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -1
  504. claude_mpm/services/infrastructure/monitoring/aggregator.py +12 -12
  505. claude_mpm/services/infrastructure/monitoring/base.py +5 -13
  506. claude_mpm/services/infrastructure/monitoring/network.py +7 -6
  507. claude_mpm/services/infrastructure/monitoring/process.py +13 -12
  508. claude_mpm/services/infrastructure/monitoring/resources.py +8 -7
  509. claude_mpm/services/infrastructure/monitoring/service.py +16 -15
  510. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  511. claude_mpm/services/local_ops/__init__.py +165 -0
  512. claude_mpm/services/local_ops/crash_detector.py +257 -0
  513. claude_mpm/services/local_ops/health_checks/__init__.py +28 -0
  514. claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
  515. claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
  516. claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
  517. claude_mpm/services/local_ops/health_manager.py +430 -0
  518. claude_mpm/services/local_ops/log_monitor.py +396 -0
  519. claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
  520. claude_mpm/services/local_ops/process_manager.py +595 -0
  521. claude_mpm/services/local_ops/resource_monitor.py +331 -0
  522. claude_mpm/services/local_ops/restart_manager.py +401 -0
  523. claude_mpm/services/local_ops/restart_policy.py +387 -0
  524. claude_mpm/services/local_ops/state_manager.py +372 -0
  525. claude_mpm/services/local_ops/unified_manager.py +600 -0
  526. claude_mpm/services/mcp_config_manager.py +1612 -0
  527. claude_mpm/services/mcp_gateway/__init__.py +97 -93
  528. claude_mpm/services/mcp_gateway/auto_configure.py +43 -38
  529. claude_mpm/services/mcp_gateway/config/config_loader.py +3 -3
  530. claude_mpm/services/mcp_gateway/config/configuration.py +23 -4
  531. claude_mpm/services/mcp_gateway/core/__init__.py +1 -2
  532. claude_mpm/services/mcp_gateway/core/base.py +20 -33
  533. claude_mpm/services/mcp_gateway/core/process_pool.py +585 -31
  534. claude_mpm/services/mcp_gateway/core/singleton_manager.py +2 -2
  535. claude_mpm/services/mcp_gateway/core/startup_verification.py +3 -3
  536. claude_mpm/services/mcp_gateway/main.py +90 -15
  537. claude_mpm/services/mcp_gateway/registry/service_registry.py +4 -2
  538. claude_mpm/services/mcp_gateway/registry/tool_registry.py +12 -9
  539. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +4 -4
  540. claude_mpm/services/mcp_gateway/server/stdio_server.py +9 -15
  541. claude_mpm/services/mcp_gateway/tools/__init__.py +14 -2
  542. claude_mpm/services/mcp_gateway/tools/base_adapter.py +15 -15
  543. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +10 -9
  544. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +654 -0
  545. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +36 -34
  546. claude_mpm/services/mcp_gateway/tools/hello_world.py +8 -8
  547. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +551 -0
  548. claude_mpm/services/mcp_gateway/utils/__init__.py +14 -0
  549. claude_mpm/services/mcp_gateway/utils/package_version_checker.py +160 -0
  550. claude_mpm/services/mcp_gateway/utils/update_preferences.py +170 -0
  551. claude_mpm/services/mcp_service_verifier.py +729 -0
  552. claude_mpm/services/memory/builder.py +9 -8
  553. claude_mpm/services/memory/cache/shared_prompt_cache.py +2 -1
  554. claude_mpm/services/memory/cache/simple_cache.py +2 -2
  555. claude_mpm/services/memory/failure_tracker.py +578 -0
  556. claude_mpm/services/memory/indexed_memory.py +8 -8
  557. claude_mpm/services/memory/optimizer.py +8 -9
  558. claude_mpm/services/memory/router.py +3 -3
  559. claude_mpm/services/memory_hook_service.py +165 -4
  560. claude_mpm/services/model/__init__.py +147 -0
  561. claude_mpm/services/model/base_provider.py +365 -0
  562. claude_mpm/services/model/claude_provider.py +412 -0
  563. claude_mpm/services/model/model_router.py +453 -0
  564. claude_mpm/services/model/ollama_provider.py +415 -0
  565. claude_mpm/services/monitor/__init__.py +20 -0
  566. claude_mpm/services/monitor/daemon.py +671 -0
  567. claude_mpm/services/monitor/daemon_manager.py +963 -0
  568. claude_mpm/services/monitor/event_emitter.py +350 -0
  569. claude_mpm/services/monitor/handlers/__init__.py +21 -0
  570. claude_mpm/services/monitor/handlers/code_analysis.py +332 -0
  571. claude_mpm/services/monitor/handlers/dashboard.py +299 -0
  572. claude_mpm/services/monitor/handlers/file.py +264 -0
  573. claude_mpm/services/monitor/handlers/hooks.py +512 -0
  574. claude_mpm/services/monitor/management/__init__.py +18 -0
  575. claude_mpm/services/monitor/management/health.py +124 -0
  576. claude_mpm/services/monitor/management/lifecycle.py +724 -0
  577. claude_mpm/services/monitor/server.py +817 -0
  578. claude_mpm/services/monitor_build_service.py +2 -2
  579. claude_mpm/services/native_agent_converter.py +356 -0
  580. claude_mpm/services/orphan_detection.py +786 -0
  581. claude_mpm/services/port_manager.py +2 -2
  582. claude_mpm/services/project/__init__.py +23 -0
  583. claude_mpm/services/project/analyzer.py +3 -3
  584. claude_mpm/services/project/architecture_analyzer.py +5 -5
  585. claude_mpm/services/project/archive_manager.py +1045 -0
  586. claude_mpm/services/project/dependency_analyzer.py +4 -4
  587. claude_mpm/services/project/detection_strategies.py +719 -0
  588. claude_mpm/services/project/documentation_manager.py +553 -0
  589. claude_mpm/services/project/enhanced_analyzer.py +572 -0
  590. claude_mpm/services/project/metrics_collector.py +4 -4
  591. claude_mpm/services/project/project_organizer.py +1005 -0
  592. claude_mpm/services/project/registry.py +13 -7
  593. claude_mpm/services/project/toolchain_analyzer.py +581 -0
  594. claude_mpm/services/project_port_allocator.py +596 -0
  595. claude_mpm/services/response_tracker.py +21 -10
  596. claude_mpm/services/runner_configuration_service.py +1 -0
  597. claude_mpm/services/self_upgrade_service.py +500 -0
  598. claude_mpm/services/session_management_service.py +7 -5
  599. claude_mpm/services/session_manager.py +380 -0
  600. claude_mpm/services/shared/__init__.py +2 -1
  601. claude_mpm/services/shared/async_service_base.py +16 -27
  602. claude_mpm/services/shared/config_service_base.py +17 -14
  603. claude_mpm/services/shared/lifecycle_service_base.py +1 -14
  604. claude_mpm/services/shared/service_factory.py +8 -5
  605. claude_mpm/services/socketio/client_proxy.py +60 -5
  606. claude_mpm/services/socketio/dashboard_server.py +361 -0
  607. claude_mpm/services/socketio/event_normalizer.py +10 -6
  608. claude_mpm/services/socketio/handlers/__init__.py +5 -2
  609. claude_mpm/services/socketio/handlers/base.py +2 -2
  610. claude_mpm/services/socketio/handlers/code_analysis.py +90 -27
  611. claude_mpm/services/socketio/handlers/connection.py +21 -40
  612. claude_mpm/services/socketio/handlers/connection_handler.py +13 -10
  613. claude_mpm/services/socketio/handlers/file.py +46 -10
  614. claude_mpm/services/socketio/handlers/git.py +8 -8
  615. claude_mpm/services/socketio/handlers/hook.py +29 -17
  616. claude_mpm/services/socketio/handlers/registry.py +4 -2
  617. claude_mpm/services/socketio/monitor_client.py +364 -0
  618. claude_mpm/services/socketio/server/broadcaster.py +9 -7
  619. claude_mpm/services/socketio/server/connection_manager.py +2 -2
  620. claude_mpm/services/socketio/server/core.py +141 -4
  621. claude_mpm/services/socketio/server/eventbus_integration.py +20 -14
  622. claude_mpm/services/socketio/server/main.py +23 -21
  623. claude_mpm/services/socketio_client_manager.py +4 -4
  624. claude_mpm/services/subprocess_launcher_service.py +19 -15
  625. claude_mpm/services/system_instructions_service.py +2 -2
  626. claude_mpm/services/ticket_services/formatter_service.py +1 -1
  627. claude_mpm/services/ticket_services/validation_service.py +5 -5
  628. claude_mpm/services/unified/__init__.py +65 -0
  629. claude_mpm/services/unified/analyzer_strategies/__init__.py +44 -0
  630. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +518 -0
  631. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +680 -0
  632. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +903 -0
  633. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +746 -0
  634. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +733 -0
  635. claude_mpm/services/unified/config_strategies/__init__.py +175 -0
  636. claude_mpm/services/unified/config_strategies/config_schema.py +731 -0
  637. claude_mpm/services/unified/config_strategies/context_strategy.py +747 -0
  638. claude_mpm/services/unified/config_strategies/error_handling_strategy.py +1005 -0
  639. claude_mpm/services/unified/config_strategies/file_loader_strategy.py +881 -0
  640. claude_mpm/services/unified/config_strategies/unified_config_service.py +823 -0
  641. claude_mpm/services/unified/config_strategies/validation_strategy.py +1148 -0
  642. claude_mpm/services/unified/deployment_strategies/__init__.py +97 -0
  643. claude_mpm/services/unified/deployment_strategies/base.py +553 -0
  644. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +573 -0
  645. claude_mpm/services/unified/deployment_strategies/local.py +607 -0
  646. claude_mpm/services/unified/deployment_strategies/utils.py +667 -0
  647. claude_mpm/services/unified/deployment_strategies/vercel.py +475 -0
  648. claude_mpm/services/unified/interfaces.py +475 -0
  649. claude_mpm/services/unified/migration.py +509 -0
  650. claude_mpm/services/unified/strategies.py +534 -0
  651. claude_mpm/services/unified/unified_analyzer.py +542 -0
  652. claude_mpm/services/unified/unified_config.py +691 -0
  653. claude_mpm/services/unified/unified_deployment.py +470 -0
  654. claude_mpm/services/utility_service.py +6 -3
  655. claude_mpm/services/version_control/branch_strategy.py +2 -2
  656. claude_mpm/services/version_control/conflict_resolution.py +8 -4
  657. claude_mpm/services/version_control/git_operations.py +26 -24
  658. claude_mpm/services/version_control/semantic_versioning.py +14 -14
  659. claude_mpm/services/version_control/version_parser.py +14 -11
  660. claude_mpm/services/version_service.py +104 -1
  661. claude_mpm/skills/__init__.py +42 -0
  662. claude_mpm/skills/agent_skills_injector.py +324 -0
  663. claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
  664. claude_mpm/skills/bundled/__init__.py +6 -0
  665. claude_mpm/skills/bundled/api-documentation.md +393 -0
  666. claude_mpm/skills/bundled/async-testing.md +571 -0
  667. claude_mpm/skills/bundled/code-review.md +143 -0
  668. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  669. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  670. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  671. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  672. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  673. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  674. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  675. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  676. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  677. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  678. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  679. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  680. claude_mpm/skills/bundled/database-migration.md +199 -0
  681. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  682. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  683. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  684. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  685. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  686. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  687. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  688. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  689. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  690. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  691. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  692. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  693. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  694. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  695. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  696. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  697. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  698. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  699. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  700. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  701. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  702. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  703. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  704. claude_mpm/skills/bundled/git-workflow.md +414 -0
  705. claude_mpm/skills/bundled/imagemagick.md +204 -0
  706. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  707. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  708. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  709. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  710. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  711. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  712. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  713. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  714. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  715. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  716. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  717. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  718. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  719. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  720. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  721. claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
  722. claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
  723. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  724. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  725. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  726. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  727. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  728. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  729. claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
  730. claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
  731. claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
  732. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  733. claude_mpm/skills/bundled/pdf.md +141 -0
  734. claude_mpm/skills/bundled/performance-profiling.md +573 -0
  735. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  736. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  737. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  738. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  739. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  740. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  741. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  742. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  743. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  744. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  745. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  746. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  747. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  748. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  749. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  750. claude_mpm/skills/bundled/security-scanning.md +327 -0
  751. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  752. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  753. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  754. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  755. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  756. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  757. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  758. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  759. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  760. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  761. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  762. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  763. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  764. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  765. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  766. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  767. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  768. claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
  769. claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
  770. claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
  771. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  772. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  773. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
  774. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  775. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  776. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  777. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  778. claude_mpm/skills/bundled/xlsx.md +157 -0
  779. claude_mpm/skills/registry.py +286 -0
  780. claude_mpm/skills/skill_manager.py +310 -0
  781. claude_mpm/skills/skills_registry.py +348 -0
  782. claude_mpm/skills/skills_service.py +739 -0
  783. claude_mpm/storage/state_storage.py +31 -31
  784. claude_mpm/tools/__main__.py +1 -1
  785. claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
  786. claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
  787. claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
  788. claude_mpm/tools/code_tree_analyzer/core.py +380 -0
  789. claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
  790. claude_mpm/tools/code_tree_analyzer/events.py +168 -0
  791. claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
  792. claude_mpm/tools/code_tree_analyzer/models.py +39 -0
  793. claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
  794. claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
  795. claude_mpm/tools/code_tree_builder.py +6 -6
  796. claude_mpm/tools/code_tree_events.py +14 -10
  797. claude_mpm/tools/socketio_debug.py +11 -11
  798. claude_mpm/utils/agent_dependency_loader.py +108 -27
  799. claude_mpm/utils/common.py +544 -0
  800. claude_mpm/utils/config_manager.py +12 -6
  801. claude_mpm/utils/database_connector.py +298 -0
  802. claude_mpm/utils/dependency_cache.py +2 -2
  803. claude_mpm/utils/dependency_strategies.py +15 -10
  804. claude_mpm/utils/display_helper.py +260 -0
  805. claude_mpm/utils/environment_context.py +4 -3
  806. claude_mpm/utils/error_handler.py +5 -3
  807. claude_mpm/utils/file_utils.py +13 -14
  808. claude_mpm/utils/git_analyzer.py +407 -0
  809. claude_mpm/utils/log_cleanup.py +627 -0
  810. claude_mpm/utils/path_operations.py +7 -4
  811. claude_mpm/utils/robust_installer.py +133 -24
  812. claude_mpm/utils/session_logging.py +2 -2
  813. claude_mpm/utils/subprocess_utils.py +9 -8
  814. claude_mpm/validation/agent_validator.py +6 -6
  815. claude_mpm/validation/frontmatter_validator.py +6 -6
  816. claude_mpm-4.24.0.dist-info/METADATA +675 -0
  817. claude_mpm-4.24.0.dist-info/RECORD +1018 -0
  818. {claude_mpm-4.1.26.dist-info → claude_mpm-4.24.0.dist-info}/entry_points.txt +1 -0
  819. claude_mpm/agents/INSTRUCTIONS.md +0 -261
  820. claude_mpm/agents/templates/agent-manager.md +0 -619
  821. claude_mpm/cli/commands/configure_tui.py +0 -1927
  822. claude_mpm/cli/commands/mpm_init.py +0 -594
  823. claude_mpm/cli/commands/socketio_monitor.py +0 -233
  824. claude_mpm/dashboard/static/css/code-tree.css +0 -1408
  825. claude_mpm/dashboard/static/js/components/code-tree.js +0 -3220
  826. claude_mpm/dashboard/static/js/components/code-viewer.js +0 -480
  827. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +0 -425
  828. claude_mpm/hooks/claude_hooks/hook_handler_original.py +0 -1040
  829. claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +0 -347
  830. claude_mpm/scripts/socketio_daemon_hardened.py +0 -937
  831. claude_mpm/scripts/socketio_daemon_wrapper.py +0 -78
  832. claude_mpm/scripts/socketio_server_manager.py +0 -349
  833. claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +0 -575
  834. claude_mpm/services/cli/dashboard_launcher.py +0 -423
  835. claude_mpm/services/cli/socketio_manager.py +0 -537
  836. claude_mpm/services/diagnostics/checks/claude_desktop_check.py +0 -286
  837. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +0 -645
  838. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +0 -602
  839. claude_mpm/services/project/analyzer_refactored.py +0 -450
  840. claude_mpm/tools/code_tree_analyzer.py +0 -1693
  841. claude_mpm-4.1.26.dist-info/METADATA +0 -332
  842. claude_mpm-4.1.26.dist-info/RECORD +0 -606
  843. {claude_mpm-4.1.26.dist-info → claude_mpm-4.24.0.dist-info}/WHEEL +0 -0
  844. {claude_mpm-4.1.26.dist-info → claude_mpm-4.24.0.dist-info}/licenses/LICENSE +0 -0
  845. {claude_mpm-4.1.26.dist-info → claude_mpm-4.24.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,963 @@
1
+ """
2
+ Unified Daemon Manager Service
3
+ ==============================
4
+
5
+ WHY: This service consolidates ALL daemon lifecycle operations into a single place,
6
+ eliminating duplicate code and race conditions from having daemon management logic
7
+ scattered across multiple files.
8
+
9
+ DESIGN DECISIONS:
10
+ - Single source of truth for all daemon operations
11
+ - Robust port cleanup with retry logic
12
+ - Thread-safe operations with proper locking
13
+ - Comprehensive error handling and recovery
14
+ - Supports both foreground and background/daemon modes
15
+ - Manages PID files, port conflicts, and process lifecycle
16
+
17
+ This replaces duplicate logic that was in:
18
+ - UnifiedMonitorDaemon._cleanup_port_conflicts()
19
+ - UnifiedDashboardManager._cleanup_port_conflicts()
20
+ - Various daemon startup/stop logic spread across files
21
+ """
22
+
23
+ import os
24
+ import signal
25
+ import socket
26
+ import subprocess
27
+ import sys
28
+ import tempfile
29
+ import threading
30
+ import time
31
+ from pathlib import Path
32
+ from typing import Optional, Tuple
33
+
34
+ from ...core.enums import OperationResult
35
+ from ...core.logging_config import get_logger
36
+
37
+
38
+ class DaemonManager:
39
+ """Centralized manager for all daemon lifecycle operations.
40
+
41
+ This is the SINGLE source of truth for:
42
+ - Port conflict resolution
43
+ - Process cleanup
44
+ - Daemon startup/stop
45
+ - PID file management
46
+ - Service detection
47
+ """
48
+
49
+ # Class-level lock for thread safety
50
+ _lock = threading.Lock()
51
+
52
+ def __init__(
53
+ self,
54
+ port: int = 8765,
55
+ host: str = "localhost",
56
+ pid_file: Optional[str] = None,
57
+ log_file: Optional[str] = None,
58
+ ):
59
+ """Initialize the daemon manager.
60
+
61
+ Args:
62
+ port: Port number for the daemon
63
+ host: Host to bind to
64
+ pid_file: Path to PID file (uses default if None)
65
+ log_file: Path to log file for daemon mode
66
+ """
67
+ self.port = port
68
+ self.host = host
69
+ self.logger = get_logger(__name__)
70
+
71
+ # Set up paths
72
+ if pid_file:
73
+ self.pid_file = Path(pid_file)
74
+ else:
75
+ self.pid_file = self._get_default_pid_file()
76
+
77
+ self.log_file = Path(log_file) if log_file else self._get_default_log_file()
78
+
79
+ # Startup status communication
80
+ self.startup_status_file = None
81
+
82
+ def _get_default_pid_file(self) -> Path:
83
+ """Get default PID file path."""
84
+ project_root = Path.cwd()
85
+ claude_mpm_dir = project_root / ".claude-mpm"
86
+ claude_mpm_dir.mkdir(exist_ok=True)
87
+ return claude_mpm_dir / "monitor-daemon.pid"
88
+
89
+ def _get_default_log_file(self) -> Path:
90
+ """Get default log file path."""
91
+ project_root = Path.cwd()
92
+ claude_mpm_dir = project_root / ".claude-mpm"
93
+ claude_mpm_dir.mkdir(exist_ok=True)
94
+ return claude_mpm_dir / "monitor-daemon.log"
95
+
96
+ def cleanup_port_conflicts(self, max_retries: int = 3) -> bool:
97
+ """Clean up any processes using the daemon port.
98
+
99
+ This is the SINGLE implementation for port cleanup, replacing
100
+ duplicate logic in multiple files.
101
+
102
+ Args:
103
+ max_retries: Maximum number of cleanup attempts
104
+
105
+ Returns:
106
+ True if port is available after cleanup, False otherwise
107
+ """
108
+ with self._lock:
109
+ for attempt in range(max_retries):
110
+ if attempt > 0:
111
+ self.logger.info(
112
+ f"Port cleanup attempt {attempt + 1}/{max_retries}"
113
+ )
114
+
115
+ # First check if port is actually in use
116
+ if self._is_port_available():
117
+ self.logger.debug(f"Port {self.port} is available")
118
+ return True
119
+
120
+ self.logger.info(f"Port {self.port} is in use, attempting cleanup")
121
+
122
+ # Try to find and kill processes using the port
123
+ if self._kill_processes_on_port():
124
+ # Wait for port to be released
125
+ time.sleep(2 if attempt == 0 else 3)
126
+
127
+ # Verify port is now free
128
+ if self._is_port_available():
129
+ self.logger.info(f"Port {self.port} successfully cleaned up")
130
+ return True
131
+
132
+ if attempt < max_retries - 1:
133
+ # Wait longer between attempts
134
+ time.sleep(3)
135
+
136
+ self.logger.error(
137
+ f"Failed to clean up port {self.port} after {max_retries} attempts"
138
+ )
139
+ return False
140
+
141
+ def _is_port_available(self) -> bool:
142
+ """Check if the port is available for binding.
143
+
144
+ Returns:
145
+ True if port is available, False otherwise
146
+ """
147
+ # Try to bind to the port using the same method as the actual server
148
+ # We only need to check if we can bind to at least one address family
149
+ try:
150
+ # Try IPv4 first (most common)
151
+ test_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
152
+ test_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
153
+
154
+ # Use 127.0.0.1 for localhost to match what the server does
155
+ bind_host = "127.0.0.1" if self.host == "localhost" else self.host
156
+ test_sock.bind((bind_host, self.port))
157
+ test_sock.close()
158
+ return True
159
+ except OSError:
160
+ # IPv4 failed, try IPv6
161
+ try:
162
+ test_sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
163
+ test_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
164
+ test_sock.bind(("::1", self.port))
165
+ test_sock.close()
166
+ return True
167
+ except Exception:
168
+ # Both IPv4 and IPv6 failed - port is in use
169
+ return False
170
+
171
+ def _kill_processes_on_port(self) -> bool:
172
+ """Kill processes using the daemon port.
173
+
174
+ Returns:
175
+ True if processes were killed or none found, False on error
176
+ """
177
+ try:
178
+ # Try using lsof first (most reliable)
179
+ if self._kill_using_lsof():
180
+ return True
181
+
182
+ # Fallback to checking our known PID file
183
+ if self._kill_using_pid_file():
184
+ return True
185
+
186
+ # Try to identify claude-mpm processes
187
+ return bool(self._kill_claude_mpm_processes())
188
+
189
+ except Exception as e:
190
+ self.logger.error(f"Error killing processes on port: {e}")
191
+ return False
192
+
193
+ def _kill_using_lsof(self) -> bool:
194
+ """Kill processes using lsof to find them.
195
+
196
+ Returns:
197
+ True if successful or lsof not available, False on error
198
+ """
199
+ try:
200
+ # Find processes using the port
201
+ result = subprocess.run(
202
+ ["lsof", "-ti", f":{self.port}"],
203
+ capture_output=True,
204
+ text=True,
205
+ check=False,
206
+ )
207
+
208
+ if result.returncode != 0 or not result.stdout.strip():
209
+ self.logger.debug(f"No processes found using port {self.port}")
210
+ return True
211
+
212
+ pids = result.stdout.strip().split("\n")
213
+ self.logger.info(f"Found processes using port {self.port}: {pids}")
214
+
215
+ # Kill each process
216
+ for pid_str in pids:
217
+ try:
218
+ pid = int(pid_str.strip())
219
+
220
+ # Check if it's a Python/Claude process
221
+ process_info = subprocess.run(
222
+ ["ps", "-p", str(pid), "-o", "comm="],
223
+ capture_output=True,
224
+ text=True,
225
+ check=False,
226
+ )
227
+
228
+ # Get full command to check if it's our monitor process
229
+ cmd_info = subprocess.run(
230
+ ["ps", "-p", str(pid), "-o", "command="],
231
+ capture_output=True,
232
+ text=True,
233
+ check=False,
234
+ )
235
+
236
+ if cmd_info.returncode != 0:
237
+ continue
238
+
239
+ full_command = cmd_info.stdout.strip().lower()
240
+ process_name = process_info.stdout.strip().lower()
241
+
242
+ # Check if this is our monitor/socketio process specifically
243
+ # Look for monitor, socketio, dashboard, or our specific port
244
+ is_monitor = any(
245
+ [
246
+ "monitor" in full_command,
247
+ "socketio" in full_command,
248
+ "dashboard" in full_command,
249
+ f"port={self.port}" in full_command,
250
+ f":{self.port}" in full_command,
251
+ "unified_monitor" in full_command,
252
+ ]
253
+ )
254
+
255
+ if is_monitor and "python" in process_name:
256
+ self.logger.info(
257
+ f"Killing monitor process {pid}: {full_command[:100]}"
258
+ )
259
+ os.kill(pid, signal.SIGTERM)
260
+
261
+ # Wait briefly for graceful shutdown
262
+ time.sleep(1)
263
+
264
+ # Check if still alive and force kill if needed
265
+ try:
266
+ os.kill(pid, 0) # Check if process exists
267
+ self.logger.warning(
268
+ f"Process {pid} didn't terminate, force killing"
269
+ )
270
+ os.kill(pid, signal.SIGKILL)
271
+ time.sleep(0.5)
272
+ except ProcessLookupError:
273
+ pass # Process already dead
274
+ else:
275
+ # Not a monitor process - log but don't fail
276
+ self.logger.info(
277
+ f"Skipping non-monitor process {pid} ({process_name})"
278
+ )
279
+ # Continue to next PID - don't return False
280
+ continue
281
+
282
+ except (ValueError, ProcessLookupError) as e:
283
+ self.logger.debug(f"Error handling PID {pid_str}: {e}")
284
+ continue
285
+
286
+ return True
287
+
288
+ except FileNotFoundError:
289
+ # lsof not available
290
+ self.logger.debug("lsof not available, using alternative methods")
291
+ return True
292
+ except Exception as e:
293
+ self.logger.error(f"Error using lsof: {e}")
294
+ return False
295
+
296
+ def _kill_using_pid_file(self) -> bool:
297
+ """Kill process using PID file.
298
+
299
+ Returns:
300
+ True if successful or no PID file, False on error
301
+ """
302
+ try:
303
+ if not self.pid_file.exists():
304
+ return True
305
+
306
+ with self.pid_file.open() as f:
307
+ pid = int(f.read().strip())
308
+
309
+ self.logger.info(f"Found PID {pid} in PID file")
310
+
311
+ # Kill the process
312
+ try:
313
+ os.kill(pid, signal.SIGTERM)
314
+ time.sleep(1)
315
+
316
+ # Check if still alive
317
+ try:
318
+ os.kill(pid, 0)
319
+ os.kill(pid, signal.SIGKILL)
320
+ time.sleep(0.5)
321
+ except ProcessLookupError:
322
+ pass
323
+
324
+ # Remove PID file
325
+ self.pid_file.unlink(missing_ok=True)
326
+ return True
327
+
328
+ except ProcessLookupError:
329
+ # Process doesn't exist, just remove PID file
330
+ self.pid_file.unlink(missing_ok=True)
331
+ return True
332
+
333
+ except Exception as e:
334
+ self.logger.error(f"Error killing process from PID file: {e}")
335
+ return False
336
+
337
+ def _kill_claude_mpm_processes(self) -> bool:
338
+ """Kill any claude-mpm monitor processes specifically.
339
+
340
+ This targets monitor/dashboard/socketio processes only,
341
+ NOT general Claude instances.
342
+
343
+ Returns:
344
+ True if successful, False on error
345
+ """
346
+ try:
347
+ # Look for monitor-specific processes
348
+ result = subprocess.run(
349
+ ["ps", "aux"], capture_output=True, text=True, check=False
350
+ )
351
+
352
+ if result.returncode != 0:
353
+ return False
354
+
355
+ lines = result.stdout.strip().split("\n")
356
+ killed_any = False
357
+
358
+ for line in lines:
359
+ line_lower = line.lower()
360
+ # Only target monitor/dashboard/socketio processes
361
+ if any(
362
+ [
363
+ "monitor" in line_lower and "claude" in line_lower,
364
+ "dashboard" in line_lower and "claude" in line_lower,
365
+ "socketio" in line_lower,
366
+ f":{self.port}" in line_lower and "python" in line_lower,
367
+ ]
368
+ ):
369
+ parts = line.split()
370
+ if len(parts) > 1:
371
+ try:
372
+ pid = int(parts[1])
373
+ self.logger.info(
374
+ f"Killing claude-mpm monitor process {pid}"
375
+ )
376
+ os.kill(pid, signal.SIGTERM)
377
+ killed_any = True
378
+ time.sleep(0.5)
379
+ except (ValueError, ProcessLookupError):
380
+ continue
381
+
382
+ if killed_any:
383
+ time.sleep(1) # Give processes time to exit
384
+
385
+ return True
386
+
387
+ except Exception as e:
388
+ self.logger.error(f"Error killing claude-mpm processes: {e}")
389
+ return False
390
+
391
+ def is_our_service(self) -> Tuple[bool, Optional[int]]:
392
+ """Check if the service on the port is our claude-mpm monitor.
393
+
394
+ Returns:
395
+ Tuple of (is_ours, pid) where is_ours is True if it's our service
396
+ """
397
+ try:
398
+ # First check PID file
399
+ if self.pid_file.exists():
400
+ try:
401
+ with self.pid_file.open() as f:
402
+ pid = int(f.read().strip())
403
+
404
+ # Verify process exists
405
+ os.kill(pid, 0)
406
+
407
+ # Check if it's a Python process
408
+ process_info = subprocess.run(
409
+ ["ps", "-p", str(pid), "-o", "comm="],
410
+ capture_output=True,
411
+ text=True,
412
+ check=False,
413
+ )
414
+
415
+ if "python" in process_info.stdout.lower():
416
+ return True, pid
417
+
418
+ except (ValueError, ProcessLookupError, subprocess.CalledProcessError):
419
+ # PID file exists but process doesn't or isn't Python
420
+ self.pid_file.unlink(missing_ok=True)
421
+
422
+ # Check if service responds to our health endpoint
423
+ try:
424
+ import requests
425
+
426
+ response = requests.get(
427
+ f"http://{self.host}:{self.port}/health", timeout=2
428
+ )
429
+
430
+ if response.status_code == 200:
431
+ # Try to get service info
432
+ try:
433
+ data = response.json()
434
+ if "claude" in str(data).lower() or "mpm" in str(data).lower():
435
+ # It's likely our service, try to find PID
436
+ pid = self._find_service_pid()
437
+ return True, pid
438
+ except Exception:
439
+ pass
440
+
441
+ except Exception:
442
+ pass
443
+
444
+ return False, None
445
+
446
+ except Exception as e:
447
+ self.logger.error(f"Error checking service ownership: {e}")
448
+ return False, None
449
+
450
+ def _find_service_pid(self) -> Optional[int]:
451
+ """Find PID of service on our port using lsof.
452
+
453
+ Returns:
454
+ PID if found, None otherwise
455
+ """
456
+ try:
457
+ result = subprocess.run(
458
+ ["lsof", "-ti", f":{self.port}"],
459
+ capture_output=True,
460
+ text=True,
461
+ check=False,
462
+ )
463
+
464
+ if result.returncode == 0 and result.stdout.strip():
465
+ pids = result.stdout.strip().split("\n")
466
+ if pids:
467
+ return int(pids[0].strip())
468
+
469
+ except Exception:
470
+ pass
471
+
472
+ return None
473
+
474
+ def start_daemon(self, force_restart: bool = False) -> bool:
475
+ """Start the daemon with automatic cleanup and retry.
476
+
477
+ Args:
478
+ force_restart: Force restart even if already running
479
+
480
+ Returns:
481
+ True if daemon started successfully
482
+ """
483
+ with self._lock:
484
+ # Check if already running
485
+ if self.is_running():
486
+ if not force_restart:
487
+ pid = self.get_pid()
488
+ self.logger.info(f"Daemon already running with PID {pid}")
489
+ return True
490
+
491
+ # Stop existing daemon
492
+ self.logger.info("Force restarting daemon")
493
+ if not self.stop_daemon():
494
+ self.logger.error("Failed to stop existing daemon")
495
+ return False
496
+
497
+ # Wait for cleanup
498
+ time.sleep(2)
499
+
500
+ # Clean up port conflicts
501
+ if not self.cleanup_port_conflicts():
502
+ self.logger.error(f"Cannot start daemon - port {self.port} is in use")
503
+ return False
504
+
505
+ # Use subprocess for clean daemon startup (v4.2.40)
506
+ # This avoids fork() issues with Python threading
507
+ if self.use_subprocess_daemon():
508
+ return self.start_daemon_subprocess()
509
+ # Fallback to traditional fork (kept for compatibility)
510
+ return self.daemonize()
511
+
512
+ def use_subprocess_daemon(self) -> bool:
513
+ """Check if we should use subprocess instead of fork for daemonization.
514
+
515
+ Returns:
516
+ True to use subprocess (safer), False to use traditional fork
517
+ """
518
+ # Check if we're already in a subprocess to prevent infinite recursion
519
+ if os.environ.get("CLAUDE_MPM_SUBPROCESS_DAEMON") == "1":
520
+ # We're already in a subprocess, use traditional fork
521
+ return False
522
+
523
+ # Otherwise, use subprocess for monitor daemon to avoid threading issues
524
+ return True
525
+
526
+ def start_daemon_subprocess(self) -> bool:
527
+ """Start daemon using subprocess.Popen for clean process isolation.
528
+
529
+ This avoids all the fork() + threading issues by starting the monitor
530
+ in a completely fresh process with no inherited threads or locks.
531
+
532
+ Returns:
533
+ True if daemon started successfully
534
+ """
535
+ try:
536
+ # Build command to run monitor in foreground mode in subprocess
537
+ import sys
538
+
539
+ python_exe = sys.executable
540
+
541
+ # Run 'claude-mpm monitor start' in subprocess with environment variable
542
+ # to indicate we're already in a subprocess (prevents infinite recursion)
543
+ cmd = [
544
+ python_exe,
545
+ "-m",
546
+ "claude_mpm.cli",
547
+ "monitor",
548
+ "start",
549
+ "--background", # Run as daemon
550
+ "--port",
551
+ str(self.port),
552
+ "--host",
553
+ self.host,
554
+ ]
555
+
556
+ # Set environment variable to prevent recursive subprocess creation
557
+ env = os.environ.copy()
558
+ env["CLAUDE_MPM_SUBPROCESS_DAEMON"] = "1"
559
+
560
+ self.logger.info(f"Starting monitor daemon via subprocess: {' '.join(cmd)}")
561
+
562
+ # Open log file for output redirection
563
+ log_file_handle = None
564
+ if self.log_file:
565
+ log_file_handle = Path(self.log_file).open("a")
566
+ log_file = log_file_handle
567
+ else:
568
+ log_file = subprocess.DEVNULL
569
+
570
+ try:
571
+ # Start the subprocess detached from parent
572
+ # Redirect stdout/stderr to log file to capture output
573
+ process = subprocess.Popen(
574
+ cmd,
575
+ stdin=subprocess.DEVNULL,
576
+ stdout=log_file,
577
+ stderr=subprocess.STDOUT if self.log_file else subprocess.DEVNULL,
578
+ start_new_session=True, # Create new process group
579
+ close_fds=(not self.log_file), # Keep log file open if redirecting
580
+ env=env, # Pass modified environment
581
+ )
582
+
583
+ # Close the log file handle now that subprocess has it
584
+ if log_file_handle:
585
+ log_file_handle.close()
586
+
587
+ # Get the process PID
588
+ pid = process.pid
589
+ self.logger.info(f"Monitor subprocess started with PID {pid}")
590
+
591
+ # Wait for the subprocess to write its PID file
592
+ # The subprocess will write the PID file after it starts successfully
593
+ max_wait = 10 # seconds
594
+ start_time = time.time()
595
+
596
+ while time.time() - start_time < max_wait:
597
+ # Check if process is still running
598
+ if process.poll() is not None:
599
+ # Process exited
600
+ self.logger.error(
601
+ f"Monitor daemon exited with code {process.returncode}"
602
+ )
603
+ return False
604
+
605
+ # Check if PID file was written
606
+ if self.pid_file.exists():
607
+ try:
608
+ with self.pid_file.open() as f:
609
+ written_pid = int(f.read().strip())
610
+ if written_pid == pid:
611
+ # PID file written correctly, check port
612
+ if (
613
+ not self._is_port_available()
614
+ ): # Port NOT available means it's in use (good!)
615
+ self.logger.info(
616
+ f"Monitor daemon successfully started on port {self.port}"
617
+ )
618
+ return True
619
+ except Exception:
620
+ pass # PID file not ready yet
621
+
622
+ time.sleep(0.5)
623
+
624
+ # Timeout waiting for daemon to start
625
+ self.logger.error("Timeout waiting for monitor daemon to start")
626
+ # Try to kill the process if it's still running
627
+ if process.poll() is None:
628
+ process.terminate()
629
+ time.sleep(1)
630
+ if process.poll() is None:
631
+ process.kill()
632
+ return False
633
+ finally:
634
+ # Clean up log file handle if still open
635
+ if log_file_handle and not log_file_handle.closed:
636
+ log_file_handle.close()
637
+
638
+ except Exception as e:
639
+ self.logger.error(f"Failed to start daemon via subprocess: {e}")
640
+ return False
641
+
642
+ def daemonize(self) -> bool:
643
+ """Daemonize the current process.
644
+
645
+ Returns:
646
+ True if successful (in parent), doesn't return in child
647
+ """
648
+ # Guard against re-entrant execution after fork
649
+ if hasattr(self, "_forking_in_progress"):
650
+ self.logger.error(
651
+ "CRITICAL: Detected re-entrant daemonize call after fork!"
652
+ )
653
+ return False
654
+
655
+ self._forking_in_progress = True
656
+
657
+ try:
658
+ # Clean up asyncio event loops before forking
659
+ self._cleanup_event_loops()
660
+
661
+ # Create status file for communication
662
+ with tempfile.NamedTemporaryFile(
663
+ mode="w", delete=False, suffix=".status"
664
+ ) as f:
665
+ self.startup_status_file = f.name
666
+ f.write("starting")
667
+
668
+ # First fork
669
+ pid = os.fork()
670
+ if pid > 0:
671
+ # Parent process - wait for child to confirm startup
672
+ del self._forking_in_progress # Clean up in parent
673
+ return self._parent_wait_for_startup(pid)
674
+
675
+ except OSError as e:
676
+ self.logger.error(f"First fork failed: {e}")
677
+ return False
678
+
679
+ # Child process continues...
680
+
681
+ # Decouple from parent
682
+ os.chdir("/")
683
+ os.setsid()
684
+ os.umask(0)
685
+
686
+ try:
687
+ # Second fork
688
+ pid = os.fork()
689
+ if pid > 0:
690
+ # First child exits
691
+ sys.exit(0)
692
+ except OSError as e:
693
+ self.logger.error(f"Second fork failed: {e}")
694
+ self._report_startup_error(f"Second fork failed: {e}")
695
+ sys.exit(1)
696
+
697
+ # Grandchild process - the actual daemon
698
+
699
+ # Write PID file
700
+ self.write_pid_file()
701
+
702
+ # Redirect streams
703
+ self._redirect_streams()
704
+
705
+ # Setup signal handlers
706
+ self._setup_signal_handlers()
707
+
708
+ self.logger.info(f"Daemon process started with PID {os.getpid()}")
709
+
710
+ # DO NOT report success here - let the caller report after starting the service
711
+ # This prevents race conditions where we report success before the server starts
712
+ # self._report_startup_success() # REMOVED - caller must report
713
+
714
+ # Note: Daemon process continues running
715
+ # Caller is responsible for running the actual service AND reporting status
716
+ return True
717
+
718
+ def stop_daemon(self, timeout: int = 10) -> bool:
719
+ """Stop the daemon process.
720
+
721
+ Args:
722
+ timeout: Maximum time to wait for daemon to stop
723
+
724
+ Returns:
725
+ True if stopped successfully
726
+ """
727
+ with self._lock:
728
+ try:
729
+ pid = self.get_pid()
730
+ if not pid:
731
+ self.logger.info("No daemon PID found")
732
+ # Still try to clean up port
733
+ self.cleanup_port_conflicts()
734
+ return True
735
+
736
+ self.logger.info(f"Stopping daemon with PID {pid}")
737
+
738
+ # Send SIGTERM for graceful shutdown
739
+ try:
740
+ os.kill(pid, signal.SIGTERM)
741
+ except ProcessLookupError:
742
+ # Process already dead
743
+ self.cleanup_pid_file()
744
+ return True
745
+
746
+ # Wait for process to exit
747
+ start_time = time.time()
748
+ while time.time() - start_time < timeout:
749
+ try:
750
+ os.kill(pid, 0) # Check if still alive
751
+ time.sleep(0.5)
752
+ except ProcessLookupError:
753
+ # Process exited
754
+ self.cleanup_pid_file()
755
+ return True
756
+
757
+ # Force kill if still running
758
+ self.logger.warning("Daemon didn't stop gracefully, force killing")
759
+ try:
760
+ os.kill(pid, signal.SIGKILL)
761
+ time.sleep(1)
762
+ except ProcessLookupError:
763
+ pass
764
+
765
+ self.cleanup_pid_file()
766
+ return True
767
+
768
+ except Exception as e:
769
+ self.logger.error(f"Error stopping daemon: {e}")
770
+ return False
771
+
772
+ def is_running(self) -> bool:
773
+ """Check if daemon is running.
774
+
775
+ Returns:
776
+ True if daemon is running
777
+ """
778
+ try:
779
+ pid = self.get_pid()
780
+ if not pid:
781
+ return False
782
+
783
+ # Check if process exists
784
+ os.kill(pid, 0)
785
+ return True
786
+
787
+ except ProcessLookupError:
788
+ # Process doesn't exist
789
+ self.cleanup_pid_file()
790
+ return False
791
+
792
+ def get_pid(self) -> Optional[int]:
793
+ """Get daemon PID from PID file.
794
+
795
+ Returns:
796
+ PID if found, None otherwise
797
+ """
798
+ try:
799
+ if not self.pid_file.exists():
800
+ return None
801
+
802
+ with self.pid_file.open() as f:
803
+ return int(f.read().strip())
804
+
805
+ except Exception as e:
806
+ self.logger.error(f"Error reading PID file: {e}")
807
+ return None
808
+
809
+ def write_pid_file(self):
810
+ """Write current PID to PID file."""
811
+ try:
812
+ self.pid_file.parent.mkdir(parents=True, exist_ok=True)
813
+ with self.pid_file.open("w") as f:
814
+ f.write(str(os.getpid()))
815
+ self.logger.debug(f"PID file written: {self.pid_file}")
816
+ except Exception as e:
817
+ self.logger.error(f"Error writing PID file: {e}")
818
+ raise
819
+
820
+ def cleanup_pid_file(self):
821
+ """Remove PID file."""
822
+ try:
823
+ self.pid_file.unlink(missing_ok=True)
824
+ self.logger.debug("PID file removed")
825
+ except Exception as e:
826
+ self.logger.error(f"Error removing PID file: {e}")
827
+
828
+ def _cleanup_event_loops(self):
829
+ """Clean up asyncio event loops before forking."""
830
+ try:
831
+ import asyncio
832
+
833
+ try:
834
+ loop = asyncio.get_event_loop()
835
+ if loop and not loop.is_closed():
836
+ # Cancel pending tasks
837
+ pending = asyncio.all_tasks(loop)
838
+ for task in pending:
839
+ task.cancel()
840
+
841
+ # Stop and close loop
842
+ if loop.is_running():
843
+ loop.stop()
844
+
845
+ asyncio.set_event_loop(None)
846
+ loop.close()
847
+
848
+ except RuntimeError:
849
+ # No event loop
850
+ pass
851
+
852
+ except Exception as e:
853
+ self.logger.debug(f"Error cleaning up event loops: {e}")
854
+
855
+ def _redirect_streams(self):
856
+ """Redirect standard streams for daemon mode."""
857
+ try:
858
+ sys.stdout.flush()
859
+ sys.stderr.flush()
860
+
861
+ # Redirect stdin to /dev/null
862
+ with Path("/dev/null").open() as null_in:
863
+ os.dup2(null_in.fileno(), sys.stdin.fileno())
864
+
865
+ # Redirect stdout and stderr to log file
866
+ self.log_file.parent.mkdir(parents=True, exist_ok=True)
867
+ with self.log_file.open("a") as log_out:
868
+ os.dup2(log_out.fileno(), sys.stdout.fileno())
869
+ os.dup2(log_out.fileno(), sys.stderr.fileno())
870
+
871
+ except Exception as e:
872
+ self.logger.error(f"Error redirecting streams: {e}")
873
+
874
+ def _setup_signal_handlers(self):
875
+ """Setup signal handlers for graceful shutdown."""
876
+
877
+ def signal_handler(signum, frame):
878
+ self.logger.info(f"Received signal {signum}, shutting down")
879
+ self.cleanup_pid_file()
880
+ sys.exit(0)
881
+
882
+ signal.signal(signal.SIGTERM, signal_handler)
883
+ signal.signal(signal.SIGINT, signal_handler)
884
+
885
+ def _parent_wait_for_startup(self, child_pid: int, timeout: float = 10.0) -> bool:
886
+ """Parent process waits for child to confirm startup.
887
+
888
+ Args:
889
+ child_pid: PID of child process
890
+ timeout: Maximum time to wait
891
+
892
+ Returns:
893
+ True if child started successfully
894
+ """
895
+ try:
896
+ start_time = time.time()
897
+
898
+ while time.time() - start_time < timeout:
899
+ if (
900
+ not self.startup_status_file
901
+ or not Path(self.startup_status_file).exists()
902
+ ):
903
+ time.sleep(0.1)
904
+ continue
905
+
906
+ try:
907
+ with self.startup_status_file.open() as f:
908
+ status = f.read().strip()
909
+
910
+ if status == OperationResult.SUCCESS:
911
+ # Cleanup status file
912
+ Path(self.startup_status_file).unlink(missing_ok=True)
913
+ return True
914
+
915
+ if status.startswith("error:"):
916
+ error_msg = status[6:]
917
+ self.logger.error(f"Daemon startup failed: {error_msg}")
918
+ Path(self.startup_status_file).unlink(missing_ok=True)
919
+ return False
920
+
921
+ except Exception:
922
+ pass
923
+
924
+ time.sleep(0.1)
925
+
926
+ self.logger.error("Daemon startup timed out")
927
+ return False
928
+
929
+ except Exception as e:
930
+ self.logger.error(f"Error waiting for daemon startup: {e}")
931
+ return False
932
+
933
+ def _report_startup_success(self):
934
+ """Report successful startup to parent process."""
935
+ if self.startup_status_file:
936
+ try:
937
+ # Don't check if file exists - we need to write to it regardless
938
+ # The parent created it and is waiting for us to update it
939
+ with self.startup_status_file.open("w") as f:
940
+ f.write(OperationResult.SUCCESS)
941
+ f.flush() # Ensure it's written immediately
942
+ os.fsync(f.fileno()) # Force write to disk
943
+ except Exception:
944
+ # Logging might not work in daemon process after fork
945
+ pass
946
+
947
+ def _report_startup_error(self, error: str):
948
+ """Report startup error to parent process."""
949
+ if self.startup_status_file:
950
+ try:
951
+ # Don't check if file exists - we need to write to it regardless
952
+ with self.startup_status_file.open("w") as f:
953
+ f.write(f"error:{error}")
954
+ f.flush() # Ensure it's written immediately
955
+ os.fsync(f.fileno()) # Force write to disk
956
+ except Exception as e:
957
+ # Try to write error to a debug file since logging might not work
958
+ try:
959
+ with Path("/tmp/daemon_debug_error.txt").open("a") as debug:
960
+ debug.write(f"Error reporting error: {e}\n")
961
+ debug.write(f"Status file: {self.startup_status_file}\n")
962
+ except Exception:
963
+ pass