claude-mpm 3.9.11__py3-none-any.whl → 4.0.4__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 (434) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/__init__.py +2 -2
  3. claude_mpm/__main__.py +3 -2
  4. claude_mpm/agents/__init__.py +85 -79
  5. claude_mpm/agents/agent_loader.py +464 -1003
  6. claude_mpm/agents/agent_loader_integration.py +45 -45
  7. claude_mpm/agents/agents_metadata.py +29 -30
  8. claude_mpm/agents/async_agent_loader.py +156 -138
  9. claude_mpm/agents/base_agent.json +1 -1
  10. claude_mpm/agents/base_agent_loader.py +179 -151
  11. claude_mpm/agents/frontmatter_validator.py +229 -130
  12. claude_mpm/agents/schema/agent_schema.json +1 -1
  13. claude_mpm/agents/system_agent_config.py +213 -147
  14. claude_mpm/agents/templates/__init__.py +13 -13
  15. claude_mpm/agents/templates/code_analyzer.json +2 -2
  16. claude_mpm/agents/templates/data_engineer.json +1 -1
  17. claude_mpm/agents/templates/documentation.json +23 -11
  18. claude_mpm/agents/templates/engineer.json +22 -6
  19. claude_mpm/agents/templates/memory_manager.json +1 -1
  20. claude_mpm/agents/templates/ops.json +2 -2
  21. claude_mpm/agents/templates/project_organizer.json +1 -1
  22. claude_mpm/agents/templates/qa.json +1 -1
  23. claude_mpm/agents/templates/refactoring_engineer.json +222 -0
  24. claude_mpm/agents/templates/research.json +20 -14
  25. claude_mpm/agents/templates/security.json +1 -1
  26. claude_mpm/agents/templates/ticketing.json +2 -2
  27. claude_mpm/agents/templates/version_control.json +1 -1
  28. claude_mpm/agents/templates/web_qa.json +3 -1
  29. claude_mpm/agents/templates/web_ui.json +2 -2
  30. claude_mpm/cli/__init__.py +79 -51
  31. claude_mpm/cli/__main__.py +3 -2
  32. claude_mpm/cli/commands/__init__.py +20 -20
  33. claude_mpm/cli/commands/agents.py +279 -247
  34. claude_mpm/cli/commands/aggregate.py +138 -157
  35. claude_mpm/cli/commands/cleanup.py +147 -147
  36. claude_mpm/cli/commands/config.py +93 -76
  37. claude_mpm/cli/commands/info.py +17 -16
  38. claude_mpm/cli/commands/mcp.py +140 -905
  39. claude_mpm/cli/commands/mcp_command_router.py +139 -0
  40. claude_mpm/cli/commands/mcp_config_commands.py +20 -0
  41. claude_mpm/cli/commands/mcp_install_commands.py +20 -0
  42. claude_mpm/cli/commands/mcp_server_commands.py +175 -0
  43. claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
  44. claude_mpm/cli/commands/memory.py +239 -203
  45. claude_mpm/cli/commands/monitor.py +330 -86
  46. claude_mpm/cli/commands/run.py +380 -429
  47. claude_mpm/cli/commands/run_config_checker.py +160 -0
  48. claude_mpm/cli/commands/socketio_monitor.py +235 -0
  49. claude_mpm/cli/commands/tickets.py +363 -220
  50. claude_mpm/cli/parser.py +24 -1156
  51. claude_mpm/cli/parsers/__init__.py +29 -0
  52. claude_mpm/cli/parsers/agents_parser.py +136 -0
  53. claude_mpm/cli/parsers/base_parser.py +331 -0
  54. claude_mpm/cli/parsers/config_parser.py +85 -0
  55. claude_mpm/cli/parsers/mcp_parser.py +152 -0
  56. claude_mpm/cli/parsers/memory_parser.py +138 -0
  57. claude_mpm/cli/parsers/monitor_parser.py +124 -0
  58. claude_mpm/cli/parsers/run_parser.py +147 -0
  59. claude_mpm/cli/parsers/tickets_parser.py +203 -0
  60. claude_mpm/cli/ticket_cli.py +7 -3
  61. claude_mpm/cli/utils.py +55 -37
  62. claude_mpm/cli_module/__init__.py +6 -6
  63. claude_mpm/cli_module/args.py +188 -140
  64. claude_mpm/cli_module/commands.py +79 -70
  65. claude_mpm/cli_module/migration_example.py +38 -60
  66. claude_mpm/config/__init__.py +32 -25
  67. claude_mpm/config/agent_config.py +151 -119
  68. claude_mpm/config/experimental_features.py +71 -73
  69. claude_mpm/config/paths.py +94 -208
  70. claude_mpm/config/socketio_config.py +84 -73
  71. claude_mpm/constants.py +35 -18
  72. claude_mpm/core/__init__.py +9 -6
  73. claude_mpm/core/agent_name_normalizer.py +68 -71
  74. claude_mpm/core/agent_registry.py +372 -521
  75. claude_mpm/core/agent_session_manager.py +74 -63
  76. claude_mpm/core/base_service.py +116 -87
  77. claude_mpm/core/cache.py +119 -153
  78. claude_mpm/core/claude_runner.py +425 -1120
  79. claude_mpm/core/config.py +263 -168
  80. claude_mpm/core/config_aliases.py +69 -61
  81. claude_mpm/core/config_constants.py +292 -0
  82. claude_mpm/core/constants.py +57 -99
  83. claude_mpm/core/container.py +211 -178
  84. claude_mpm/core/exceptions.py +233 -89
  85. claude_mpm/core/factories.py +92 -54
  86. claude_mpm/core/framework_loader.py +378 -220
  87. claude_mpm/core/hook_manager.py +198 -83
  88. claude_mpm/core/hook_performance_config.py +136 -0
  89. claude_mpm/core/injectable_service.py +61 -55
  90. claude_mpm/core/interactive_session.py +165 -155
  91. claude_mpm/core/interfaces.py +221 -195
  92. claude_mpm/core/lazy.py +96 -96
  93. claude_mpm/core/logger.py +133 -107
  94. claude_mpm/core/logging_config.py +185 -157
  95. claude_mpm/core/minimal_framework_loader.py +20 -15
  96. claude_mpm/core/mixins.py +30 -29
  97. claude_mpm/core/oneshot_session.py +215 -181
  98. claude_mpm/core/optimized_agent_loader.py +134 -138
  99. claude_mpm/core/optimized_startup.py +159 -157
  100. claude_mpm/core/pm_hook_interceptor.py +85 -72
  101. claude_mpm/core/service_registry.py +103 -101
  102. claude_mpm/core/session_manager.py +97 -87
  103. claude_mpm/core/socketio_pool.py +212 -158
  104. claude_mpm/core/tool_access_control.py +58 -51
  105. claude_mpm/core/types.py +46 -24
  106. claude_mpm/core/typing_utils.py +166 -82
  107. claude_mpm/core/unified_agent_registry.py +721 -0
  108. claude_mpm/core/unified_config.py +550 -0
  109. claude_mpm/core/unified_paths.py +549 -0
  110. claude_mpm/dashboard/index.html +1 -1
  111. claude_mpm/dashboard/open_dashboard.py +51 -17
  112. claude_mpm/dashboard/static/built/components/agent-inference.js +2 -0
  113. claude_mpm/dashboard/static/built/components/event-processor.js +2 -0
  114. claude_mpm/dashboard/static/built/components/event-viewer.js +2 -0
  115. claude_mpm/dashboard/static/built/components/export-manager.js +2 -0
  116. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +2 -0
  117. claude_mpm/dashboard/static/built/components/hud-library-loader.js +2 -0
  118. claude_mpm/dashboard/static/built/components/hud-manager.js +2 -0
  119. claude_mpm/dashboard/static/built/components/hud-visualizer.js +2 -0
  120. claude_mpm/dashboard/static/built/components/module-viewer.js +2 -0
  121. claude_mpm/dashboard/static/built/components/session-manager.js +2 -0
  122. claude_mpm/dashboard/static/built/components/socket-manager.js +2 -0
  123. claude_mpm/dashboard/static/built/components/ui-state-manager.js +2 -0
  124. claude_mpm/dashboard/static/built/components/working-directory.js +2 -0
  125. claude_mpm/dashboard/static/built/dashboard.js +2 -0
  126. claude_mpm/dashboard/static/built/socket-client.js +2 -0
  127. claude_mpm/dashboard/static/css/dashboard.css +27 -8
  128. claude_mpm/dashboard/static/dist/components/agent-inference.js +2 -0
  129. claude_mpm/dashboard/static/dist/components/event-processor.js +2 -0
  130. claude_mpm/dashboard/static/dist/components/event-viewer.js +2 -0
  131. claude_mpm/dashboard/static/dist/components/export-manager.js +2 -0
  132. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +2 -0
  133. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +2 -0
  134. claude_mpm/dashboard/static/dist/components/hud-manager.js +2 -0
  135. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +2 -0
  136. claude_mpm/dashboard/static/dist/components/module-viewer.js +2 -0
  137. claude_mpm/dashboard/static/dist/components/session-manager.js +2 -0
  138. claude_mpm/dashboard/static/dist/components/socket-manager.js +2 -0
  139. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +2 -0
  140. claude_mpm/dashboard/static/dist/components/working-directory.js +2 -0
  141. claude_mpm/dashboard/static/dist/dashboard.js +2 -0
  142. claude_mpm/dashboard/static/dist/socket-client.js +2 -0
  143. claude_mpm/dashboard/static/js/components/agent-inference.js +80 -76
  144. claude_mpm/dashboard/static/js/components/event-processor.js +71 -67
  145. claude_mpm/dashboard/static/js/components/event-viewer.js +93 -72
  146. claude_mpm/dashboard/static/js/components/export-manager.js +31 -28
  147. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +110 -96
  148. claude_mpm/dashboard/static/js/components/hud-library-loader.js +11 -11
  149. claude_mpm/dashboard/static/js/components/hud-manager.js +73 -73
  150. claude_mpm/dashboard/static/js/components/hud-visualizer.js +163 -163
  151. claude_mpm/dashboard/static/js/components/module-viewer.js +305 -233
  152. claude_mpm/dashboard/static/js/components/session-manager.js +32 -29
  153. claude_mpm/dashboard/static/js/components/socket-manager.js +27 -20
  154. claude_mpm/dashboard/static/js/components/ui-state-manager.js +21 -18
  155. claude_mpm/dashboard/static/js/components/working-directory.js +74 -71
  156. claude_mpm/dashboard/static/js/dashboard.js +178 -453
  157. claude_mpm/dashboard/static/js/extension-error-handler.js +164 -0
  158. claude_mpm/dashboard/static/js/socket-client.js +133 -53
  159. claude_mpm/dashboard/templates/index.html +40 -50
  160. claude_mpm/experimental/cli_enhancements.py +60 -58
  161. claude_mpm/generators/__init__.py +1 -1
  162. claude_mpm/generators/agent_profile_generator.py +75 -65
  163. claude_mpm/hooks/__init__.py +1 -1
  164. claude_mpm/hooks/base_hook.py +33 -28
  165. claude_mpm/hooks/claude_hooks/__init__.py +1 -1
  166. claude_mpm/hooks/claude_hooks/connection_pool.py +120 -0
  167. claude_mpm/hooks/claude_hooks/event_handlers.py +743 -0
  168. claude_mpm/hooks/claude_hooks/hook_handler.py +415 -1331
  169. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +4 -4
  170. claude_mpm/hooks/claude_hooks/memory_integration.py +221 -0
  171. claude_mpm/hooks/claude_hooks/response_tracking.py +348 -0
  172. claude_mpm/hooks/claude_hooks/tool_analysis.py +230 -0
  173. claude_mpm/hooks/memory_integration_hook.py +140 -100
  174. claude_mpm/hooks/tool_call_interceptor.py +89 -76
  175. claude_mpm/hooks/validation_hooks.py +57 -49
  176. claude_mpm/init.py +145 -121
  177. claude_mpm/models/__init__.py +9 -9
  178. claude_mpm/models/agent_definition.py +33 -23
  179. claude_mpm/models/agent_session.py +228 -200
  180. claude_mpm/scripts/__init__.py +1 -1
  181. claude_mpm/scripts/socketio_daemon.py +192 -75
  182. claude_mpm/scripts/socketio_server_manager.py +328 -0
  183. claude_mpm/scripts/start_activity_logging.py +25 -22
  184. claude_mpm/services/__init__.py +68 -43
  185. claude_mpm/services/agent_capabilities_service.py +271 -0
  186. claude_mpm/services/agents/__init__.py +23 -32
  187. claude_mpm/services/agents/deployment/__init__.py +3 -3
  188. claude_mpm/services/agents/deployment/agent_config_provider.py +310 -0
  189. claude_mpm/services/agents/deployment/agent_configuration_manager.py +359 -0
  190. claude_mpm/services/agents/deployment/agent_definition_factory.py +84 -0
  191. claude_mpm/services/agents/deployment/agent_deployment.py +415 -2113
  192. claude_mpm/services/agents/deployment/agent_discovery_service.py +387 -0
  193. claude_mpm/services/agents/deployment/agent_environment_manager.py +293 -0
  194. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +387 -0
  195. claude_mpm/services/agents/deployment/agent_format_converter.py +453 -0
  196. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +161 -0
  197. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +345 -495
  198. claude_mpm/services/agents/deployment/agent_metrics_collector.py +279 -0
  199. claude_mpm/services/agents/deployment/agent_restore_handler.py +88 -0
  200. claude_mpm/services/agents/deployment/agent_template_builder.py +406 -0
  201. claude_mpm/services/agents/deployment/agent_validator.py +352 -0
  202. claude_mpm/services/agents/deployment/agent_version_manager.py +313 -0
  203. claude_mpm/services/agents/deployment/agent_versioning.py +6 -9
  204. claude_mpm/services/agents/deployment/agents_directory_resolver.py +79 -0
  205. claude_mpm/services/agents/deployment/async_agent_deployment.py +298 -234
  206. claude_mpm/services/agents/deployment/config/__init__.py +13 -0
  207. claude_mpm/services/agents/deployment/config/deployment_config.py +182 -0
  208. claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
  209. claude_mpm/services/agents/deployment/deployment_config_loader.py +54 -0
  210. claude_mpm/services/agents/deployment/deployment_type_detector.py +124 -0
  211. claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
  212. claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
  213. claude_mpm/services/agents/deployment/facade/deployment_executor.py +73 -0
  214. claude_mpm/services/agents/deployment/facade/deployment_facade.py +270 -0
  215. claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
  216. claude_mpm/services/agents/deployment/interface_adapter.py +227 -0
  217. claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
  218. claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
  219. claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
  220. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
  221. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +159 -0
  222. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
  223. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
  224. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +195 -0
  225. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +119 -0
  226. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +79 -0
  227. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +90 -0
  228. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +100 -0
  229. claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
  230. claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +98 -0
  231. claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
  232. claude_mpm/services/agents/deployment/processors/agent_processor.py +258 -0
  233. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +318 -0
  234. claude_mpm/services/agents/deployment/results/__init__.py +13 -0
  235. claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
  236. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
  237. claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
  238. claude_mpm/services/agents/deployment/strategies/base_strategy.py +119 -0
  239. claude_mpm/services/agents/deployment/strategies/project_strategy.py +150 -0
  240. claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
  241. claude_mpm/services/agents/deployment/strategies/system_strategy.py +116 -0
  242. claude_mpm/services/agents/deployment/strategies/user_strategy.py +137 -0
  243. claude_mpm/services/agents/deployment/system_instructions_deployer.py +108 -0
  244. claude_mpm/services/agents/deployment/validation/__init__.py +19 -0
  245. claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
  246. claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
  247. claude_mpm/services/agents/deployment/validation/template_validator.py +299 -0
  248. claude_mpm/services/agents/deployment/validation/validation_result.py +226 -0
  249. claude_mpm/services/agents/loading/__init__.py +2 -2
  250. claude_mpm/services/agents/loading/agent_profile_loader.py +259 -229
  251. claude_mpm/services/agents/loading/base_agent_manager.py +90 -81
  252. claude_mpm/services/agents/loading/framework_agent_loader.py +154 -129
  253. claude_mpm/services/agents/management/__init__.py +2 -2
  254. claude_mpm/services/agents/management/agent_capabilities_generator.py +72 -58
  255. claude_mpm/services/agents/management/agent_management_service.py +209 -156
  256. claude_mpm/services/agents/memory/__init__.py +9 -6
  257. claude_mpm/services/agents/memory/agent_memory_manager.py +218 -1152
  258. claude_mpm/services/agents/memory/agent_persistence_service.py +20 -16
  259. claude_mpm/services/agents/memory/analyzer.py +430 -0
  260. claude_mpm/services/agents/memory/content_manager.py +376 -0
  261. claude_mpm/services/agents/memory/template_generator.py +468 -0
  262. claude_mpm/services/agents/registry/__init__.py +7 -10
  263. claude_mpm/services/agents/registry/deployed_agent_discovery.py +122 -97
  264. claude_mpm/services/agents/registry/modification_tracker.py +351 -285
  265. claude_mpm/services/async_session_logger.py +187 -153
  266. claude_mpm/services/claude_session_logger.py +87 -72
  267. claude_mpm/services/command_handler_service.py +217 -0
  268. claude_mpm/services/communication/__init__.py +3 -2
  269. claude_mpm/services/core/__init__.py +50 -97
  270. claude_mpm/services/core/base.py +60 -53
  271. claude_mpm/services/core/interfaces/__init__.py +188 -0
  272. claude_mpm/services/core/interfaces/agent.py +351 -0
  273. claude_mpm/services/core/interfaces/communication.py +343 -0
  274. claude_mpm/services/core/interfaces/infrastructure.py +413 -0
  275. claude_mpm/services/core/interfaces/service.py +434 -0
  276. claude_mpm/services/core/interfaces.py +19 -944
  277. claude_mpm/services/event_aggregator.py +208 -170
  278. claude_mpm/services/exceptions.py +387 -308
  279. claude_mpm/services/framework_claude_md_generator/__init__.py +75 -79
  280. claude_mpm/services/framework_claude_md_generator/content_assembler.py +69 -60
  281. claude_mpm/services/framework_claude_md_generator/content_validator.py +65 -61
  282. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +68 -49
  283. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +34 -34
  284. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +25 -22
  285. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +10 -10
  286. claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +4 -3
  287. claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
  288. claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
  289. claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
  290. claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
  291. claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +4 -3
  292. claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
  293. claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
  294. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +4 -3
  295. claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +5 -4
  296. claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
  297. claude_mpm/services/framework_claude_md_generator/version_manager.py +30 -28
  298. claude_mpm/services/hook_service.py +106 -114
  299. claude_mpm/services/infrastructure/__init__.py +7 -5
  300. claude_mpm/services/infrastructure/context_preservation.py +233 -199
  301. claude_mpm/services/infrastructure/daemon_manager.py +279 -0
  302. claude_mpm/services/infrastructure/logging.py +83 -76
  303. claude_mpm/services/infrastructure/monitoring.py +547 -404
  304. claude_mpm/services/mcp_gateway/__init__.py +30 -13
  305. claude_mpm/services/mcp_gateway/config/__init__.py +2 -2
  306. claude_mpm/services/mcp_gateway/config/config_loader.py +61 -56
  307. claude_mpm/services/mcp_gateway/config/config_schema.py +50 -41
  308. claude_mpm/services/mcp_gateway/config/configuration.py +82 -75
  309. claude_mpm/services/mcp_gateway/core/__init__.py +13 -20
  310. claude_mpm/services/mcp_gateway/core/base.py +80 -67
  311. claude_mpm/services/mcp_gateway/core/exceptions.py +60 -46
  312. claude_mpm/services/mcp_gateway/core/interfaces.py +87 -84
  313. claude_mpm/services/mcp_gateway/main.py +287 -137
  314. claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
  315. claude_mpm/services/mcp_gateway/registry/service_registry.py +97 -94
  316. claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
  317. claude_mpm/services/mcp_gateway/server/__init__.py +2 -2
  318. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +105 -110
  319. claude_mpm/services/mcp_gateway/server/stdio_handler.py +105 -107
  320. claude_mpm/services/mcp_gateway/server/stdio_server.py +691 -0
  321. claude_mpm/services/mcp_gateway/tools/__init__.py +4 -2
  322. claude_mpm/services/mcp_gateway/tools/base_adapter.py +109 -119
  323. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +283 -215
  324. claude_mpm/services/mcp_gateway/tools/hello_world.py +122 -120
  325. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +652 -0
  326. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +606 -0
  327. claude_mpm/services/memory/__init__.py +2 -2
  328. claude_mpm/services/memory/builder.py +451 -362
  329. claude_mpm/services/memory/cache/__init__.py +2 -2
  330. claude_mpm/services/memory/cache/shared_prompt_cache.py +232 -194
  331. claude_mpm/services/memory/cache/simple_cache.py +107 -93
  332. claude_mpm/services/memory/indexed_memory.py +195 -193
  333. claude_mpm/services/memory/optimizer.py +267 -234
  334. claude_mpm/services/memory/router.py +571 -263
  335. claude_mpm/services/memory_hook_service.py +237 -0
  336. claude_mpm/services/port_manager.py +575 -0
  337. claude_mpm/services/project/__init__.py +3 -3
  338. claude_mpm/services/project/analyzer.py +451 -305
  339. claude_mpm/services/project/registry.py +262 -240
  340. claude_mpm/services/recovery_manager.py +287 -231
  341. claude_mpm/services/response_tracker.py +87 -67
  342. claude_mpm/services/runner_configuration_service.py +587 -0
  343. claude_mpm/services/session_management_service.py +304 -0
  344. claude_mpm/services/socketio/__init__.py +4 -4
  345. claude_mpm/services/socketio/client_proxy.py +174 -0
  346. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  347. claude_mpm/services/socketio/handlers/base.py +44 -30
  348. claude_mpm/services/socketio/handlers/connection.py +166 -64
  349. claude_mpm/services/socketio/handlers/file.py +123 -108
  350. claude_mpm/services/socketio/handlers/git.py +607 -373
  351. claude_mpm/services/socketio/handlers/hook.py +185 -0
  352. claude_mpm/services/socketio/handlers/memory.py +4 -4
  353. claude_mpm/services/socketio/handlers/project.py +4 -4
  354. claude_mpm/services/socketio/handlers/registry.py +53 -38
  355. claude_mpm/services/socketio/server/__init__.py +18 -0
  356. claude_mpm/services/socketio/server/broadcaster.py +252 -0
  357. claude_mpm/services/socketio/server/core.py +399 -0
  358. claude_mpm/services/socketio/server/main.py +323 -0
  359. claude_mpm/services/socketio_client_manager.py +160 -133
  360. claude_mpm/services/socketio_server.py +36 -1885
  361. claude_mpm/services/subprocess_launcher_service.py +316 -0
  362. claude_mpm/services/system_instructions_service.py +258 -0
  363. claude_mpm/services/ticket_manager.py +19 -533
  364. claude_mpm/services/utility_service.py +285 -0
  365. claude_mpm/services/version_control/__init__.py +18 -21
  366. claude_mpm/services/version_control/branch_strategy.py +20 -10
  367. claude_mpm/services/version_control/conflict_resolution.py +37 -13
  368. claude_mpm/services/version_control/git_operations.py +52 -21
  369. claude_mpm/services/version_control/semantic_versioning.py +92 -53
  370. claude_mpm/services/version_control/version_parser.py +145 -125
  371. claude_mpm/services/version_service.py +270 -0
  372. claude_mpm/storage/__init__.py +2 -2
  373. claude_mpm/storage/state_storage.py +177 -181
  374. claude_mpm/ticket_wrapper.py +2 -2
  375. claude_mpm/utils/__init__.py +2 -2
  376. claude_mpm/utils/agent_dependency_loader.py +453 -243
  377. claude_mpm/utils/config_manager.py +157 -118
  378. claude_mpm/utils/console.py +1 -1
  379. claude_mpm/utils/dependency_cache.py +102 -107
  380. claude_mpm/utils/dependency_manager.py +52 -47
  381. claude_mpm/utils/dependency_strategies.py +131 -96
  382. claude_mpm/utils/environment_context.py +110 -102
  383. claude_mpm/utils/error_handler.py +75 -55
  384. claude_mpm/utils/file_utils.py +80 -67
  385. claude_mpm/utils/framework_detection.py +12 -11
  386. claude_mpm/utils/import_migration_example.py +12 -60
  387. claude_mpm/utils/imports.py +48 -45
  388. claude_mpm/utils/path_operations.py +100 -93
  389. claude_mpm/utils/robust_installer.py +172 -164
  390. claude_mpm/utils/session_logging.py +30 -23
  391. claude_mpm/utils/subprocess_utils.py +99 -61
  392. claude_mpm/validation/__init__.py +1 -1
  393. claude_mpm/validation/agent_validator.py +151 -111
  394. claude_mpm/validation/frontmatter_validator.py +92 -71
  395. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/METADATA +90 -22
  396. claude_mpm-4.0.4.dist-info/RECORD +417 -0
  397. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/entry_points.txt +1 -0
  398. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/licenses/LICENSE +1 -1
  399. claude_mpm/cli/commands/run_guarded.py +0 -511
  400. claude_mpm/config/memory_guardian_config.py +0 -325
  401. claude_mpm/config/memory_guardian_yaml.py +0 -335
  402. claude_mpm/core/config_paths.py +0 -150
  403. claude_mpm/core/memory_aware_runner.py +0 -353
  404. claude_mpm/dashboard/static/js/dashboard-original.js +0 -4134
  405. claude_mpm/deployment_paths.py +0 -261
  406. claude_mpm/hooks/claude_hooks/hook_handler_fixed.py +0 -454
  407. claude_mpm/models/state_models.py +0 -433
  408. claude_mpm/services/agent/__init__.py +0 -24
  409. claude_mpm/services/agent/deployment.py +0 -2548
  410. claude_mpm/services/agent/management.py +0 -598
  411. claude_mpm/services/agent/registry.py +0 -813
  412. claude_mpm/services/agents/registry/agent_registry.py +0 -813
  413. claude_mpm/services/communication/socketio.py +0 -1935
  414. claude_mpm/services/communication/websocket.py +0 -479
  415. claude_mpm/services/framework_claude_md_generator.py +0 -624
  416. claude_mpm/services/health_monitor.py +0 -893
  417. claude_mpm/services/infrastructure/graceful_degradation.py +0 -616
  418. claude_mpm/services/infrastructure/health_monitor.py +0 -775
  419. claude_mpm/services/infrastructure/memory_dashboard.py +0 -479
  420. claude_mpm/services/infrastructure/memory_guardian.py +0 -944
  421. claude_mpm/services/infrastructure/restart_protection.py +0 -642
  422. claude_mpm/services/infrastructure/state_manager.py +0 -774
  423. claude_mpm/services/mcp_gateway/manager.py +0 -334
  424. claude_mpm/services/optimized_hook_service.py +0 -542
  425. claude_mpm/services/project_analyzer.py +0 -864
  426. claude_mpm/services/project_registry.py +0 -608
  427. claude_mpm/services/standalone_socketio_server.py +0 -1300
  428. claude_mpm/services/ticket_manager_di.py +0 -318
  429. claude_mpm/services/ticketing_service_original.py +0 -510
  430. claude_mpm/utils/paths.py +0 -395
  431. claude_mpm/utils/platform_memory.py +0 -524
  432. claude_mpm-3.9.11.dist-info/RECORD +0 -306
  433. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/WHEEL +0 -0
  434. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/top_level.txt +0 -0
@@ -12,4 +12,4 @@ claude_mpm module and can be distributed with the package.
12
12
  # Export commonly used scripts for programmatic access
13
13
  from .start_activity_logging import signal_handler
14
14
 
15
- __all__ = ['signal_handler']
15
+ __all__ = ["signal_handler"]
@@ -1,59 +1,69 @@
1
+ from pathlib import Path
2
+
1
3
  #!/usr/bin/env python3
2
4
  """
3
5
  Pure Python daemon management for Socket.IO server.
4
6
  No external dependencies required.
5
7
  """
6
8
 
9
+ import json
7
10
  import os
8
- import sys
9
- import time
10
11
  import signal
11
12
  import subprocess
13
+ import sys
14
+ import time
15
+
12
16
  import psutil
13
- import json
14
- from pathlib import Path
15
17
 
16
18
  # Handle imports for both development and installed scenarios
17
19
  script_dir = Path(__file__).parent
18
20
  try:
19
21
  # When installed as package, this should work directly
20
- from claude_mpm.services.socketio_server import SocketIOServer
22
+ from claude_mpm.services.port_manager import PortManager
23
+ from claude_mpm.services.socketio.server.main import SocketIOServer
21
24
  except ImportError:
22
25
  # Need to add the appropriate directory to sys.path
23
26
  import sys
24
-
27
+
25
28
  # Get the absolute path of this script
26
29
  script_path = Path(__file__).resolve()
27
-
30
+
28
31
  # Determine if we're in development or installed environment
29
32
  if "site-packages" in str(script_path):
30
33
  # Installed environment: ~/.local/pipx/venvs/claude-mpm/lib/python3.13/site-packages/claude_mpm/scripts/socketio_daemon.py
31
34
  # Need to add site-packages directory to path
32
35
  parts = script_path.parts
33
- site_packages_idx = next(i for i, part in enumerate(parts) if part == "site-packages")
34
- site_packages_path = Path(*parts[:site_packages_idx + 1])
35
-
36
+ site_packages_idx = next(
37
+ i for i, part in enumerate(parts) if part == "site-packages"
38
+ )
39
+ site_packages_path = Path(*parts[: site_packages_idx + 1])
40
+
36
41
  if site_packages_path.exists() and str(site_packages_path) not in sys.path:
37
42
  sys.path.insert(0, str(site_packages_path))
38
43
  else:
39
- # Development environment: Project/src/claude_mpm/scripts/socketio_daemon.py
44
+ # Development environment: Project/src/claude_mpm/scripts/socketio_daemon.py
40
45
  # Need to add src directory to path
41
46
  # Go up: scripts -> claude_mpm -> src
42
47
  src_path = script_path.parent.parent.parent
43
-
44
- if src_path.exists() and (src_path / "claude_mpm").exists() and str(src_path) not in sys.path:
48
+
49
+ if (
50
+ src_path.exists()
51
+ and (src_path / "claude_mpm").exists()
52
+ and str(src_path) not in sys.path
53
+ ):
45
54
  sys.path.insert(0, str(src_path))
46
-
55
+
47
56
  # Try importing again after path modification
48
57
  try:
49
- from claude_mpm.services.socketio_server import SocketIOServer
58
+ from claude_mpm.services.port_manager import PortManager
59
+ from claude_mpm.services.socketio.server.main import SocketIOServer
50
60
  except ImportError as e:
51
61
  print(f"❌ Failed to import SocketIOServer after path adjustment: {e}")
52
62
  print(f"📍 Script path: {script_path}")
53
63
  print(f"🐍 Python path entries: {len(sys.path)}")
54
64
  for i, path in enumerate(sys.path):
55
65
  print(f" [{i}] {path}")
56
-
66
+
57
67
  # Check if claude_mpm directory exists in any path
58
68
  claude_mpm_found = False
59
69
  for path_str in sys.path:
@@ -61,10 +71,10 @@ except ImportError:
61
71
  if claude_mpm_path.exists():
62
72
  print(f"✅ Found claude_mpm at: {claude_mpm_path}")
63
73
  claude_mpm_found = True
64
-
74
+
65
75
  if not claude_mpm_found:
66
76
  print("❌ claude_mpm directory not found in any sys.path entry")
67
-
77
+
68
78
  print("\n💡 Troubleshooting tips:")
69
79
  print(" 1. Ensure claude-mpm is properly installed: pip install claude-mpm")
70
80
  print(" 2. If in development, ensure you're in the project root directory")
@@ -72,25 +82,27 @@ except ImportError:
72
82
  sys.exit(1)
73
83
 
74
84
  # Use deployment root for daemon files to keep everything centralized
75
- from claude_mpm.deployment_paths import get_project_root
85
+ from claude_mpm.core.unified_paths import get_project_root
76
86
 
77
87
  deployment_root = get_project_root()
78
88
  PID_FILE = deployment_root / ".claude-mpm" / "socketio-server.pid"
79
89
  LOG_FILE = deployment_root / ".claude-mpm" / "socketio-server.log"
80
90
 
91
+
81
92
  def ensure_dirs():
82
93
  """Ensure required directories exist."""
83
94
  PID_FILE.parent.mkdir(parents=True, exist_ok=True)
84
95
 
96
+
85
97
  def is_running():
86
98
  """Check if server is already running."""
87
99
  if not PID_FILE.exists():
88
100
  return False
89
-
101
+
90
102
  try:
91
103
  with open(PID_FILE) as f:
92
104
  pid = int(f.read().strip())
93
-
105
+
94
106
  # Check if process exists
95
107
  process = psutil.Process(pid)
96
108
  return process.is_running()
@@ -99,67 +111,104 @@ def is_running():
99
111
  PID_FILE.unlink(missing_ok=True)
100
112
  return False
101
113
 
114
+
102
115
  def start_server():
103
- """Start the Socket.IO server as a daemon with conflict detection."""
116
+ """Start the Socket.IO server as a daemon with dynamic port selection."""
117
+ # Initialize port manager
118
+ port_manager = PortManager()
119
+
120
+ # Clean up any dead instances first
121
+ port_manager.cleanup_dead_instances()
122
+
123
+ # Check if we already have a running instance
104
124
  if is_running():
105
125
  print("Socket.IO daemon server is already running.")
106
126
  print(f"Use '{__file__} status' for details")
107
127
  return
108
-
109
- # Check for HTTP-managed server conflict
110
- try:
111
- import requests
112
- response = requests.get("http://localhost:8765/health", timeout=1.0)
113
- if response.status_code == 200:
114
- data = response.json()
115
- if 'server_id' in data:
116
- print(f"⚠️ HTTP-managed server already running: {data.get('server_id')}")
117
- print(f" Stop it first: socketio_server_manager.py stop --port 8765")
118
- print(f" Or diagnose: socketio_server_manager.py diagnose")
119
- return
120
- except:
121
- pass # No HTTP server, continue
122
-
128
+
129
+ # Find an available port
130
+ selected_port = port_manager.find_available_port()
131
+ if not selected_port:
132
+ print("❌ No available ports in range 8765-8785")
133
+ print(" All ports are either in use or blocked")
134
+ return
135
+
136
+ print(f"🔍 Selected port: {selected_port}")
137
+
138
+ # Check for existing instances on this port
139
+ existing_instance = port_manager.get_instance_by_port(selected_port)
140
+ if existing_instance:
141
+ print(f"⚠️ Port {selected_port} is already used by claude-mpm instance:")
142
+ print(f" PID: {existing_instance.get('pid')}")
143
+ print(f" Started: {time.ctime(existing_instance.get('start_time', 0))}")
144
+ return
145
+
123
146
  ensure_dirs()
124
-
147
+
125
148
  # Fork to create daemon
126
149
  pid = os.fork()
127
150
  if pid > 0:
128
151
  # Parent process
129
- print(f"Starting Socket.IO server (PID: {pid})...")
130
- with open(PID_FILE, 'w') as f:
152
+ print(f"Starting Socket.IO server on port {selected_port} (PID: {pid})...")
153
+
154
+ # Register the instance
155
+ instance_id = port_manager.register_instance(selected_port, pid)
156
+
157
+ # Save PID and port info
158
+ with open(PID_FILE, "w") as f:
131
159
  f.write(str(pid))
160
+
161
+ # Save port info for other tools
162
+ port_file = PID_FILE.parent / "socketio-port"
163
+ with open(port_file, "w") as f:
164
+ f.write(str(selected_port))
165
+
132
166
  print("Socket.IO server started successfully.")
167
+ print(f"Port: {selected_port}")
168
+ print(f"Instance ID: {instance_id}")
133
169
  print(f"PID file: {PID_FILE}")
134
170
  print(f"Log file: {LOG_FILE}")
135
171
  sys.exit(0)
136
-
172
+
137
173
  # Child process - become daemon
138
174
  os.setsid()
139
175
  os.umask(0)
140
-
176
+
141
177
  # Redirect stdout/stderr to log file
142
- with open(LOG_FILE, 'a') as log:
178
+ with open(LOG_FILE, "a") as log:
143
179
  os.dup2(log.fileno(), sys.stdout.fileno())
144
180
  os.dup2(log.fileno(), sys.stderr.fileno())
145
-
181
+
146
182
  # Start server
147
- print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Starting Socket.IO server...")
148
- server = SocketIOServer(host="localhost", port=8765)
149
-
183
+ print(
184
+ f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Starting Socket.IO server on port {selected_port}..."
185
+ )
186
+ server = SocketIOServer(host="localhost", port=selected_port)
187
+
150
188
  # Handle signals
151
189
  def signal_handler(signum, frame):
152
- print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Received signal {signum}, shutting down...")
153
- server.stop()
190
+ print(
191
+ f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Received signal {signum}, shutting down..."
192
+ )
193
+ server.stop_sync()
194
+
195
+ # Clean up instance registration
196
+ port_manager_cleanup = PortManager()
197
+ instances = port_manager_cleanup.load_instances()
198
+ for instance_id, instance_info in instances.items():
199
+ if instance_info.get("pid") == os.getpid():
200
+ port_manager_cleanup.remove_instance(instance_id)
201
+ break
202
+
154
203
  PID_FILE.unlink(missing_ok=True)
155
204
  sys.exit(0)
156
-
205
+
157
206
  signal.signal(signal.SIGTERM, signal_handler)
158
207
  signal.signal(signal.SIGINT, signal_handler)
159
-
160
- # Start server
161
- server.start()
162
-
208
+
209
+ # Start server using synchronous method
210
+ server.start_sync()
211
+
163
212
  # Keep running
164
213
  try:
165
214
  while True:
@@ -167,20 +216,21 @@ def start_server():
167
216
  except KeyboardInterrupt:
168
217
  signal_handler(signal.SIGINT, None)
169
218
 
219
+
170
220
  def stop_server():
171
221
  """Stop the Socket.IO daemon server."""
172
222
  if not is_running():
173
223
  print("Socket.IO daemon server is not running.")
174
224
  print(f"Check for other servers: socketio_server_manager.py status")
175
225
  return
176
-
226
+
177
227
  try:
178
228
  with open(PID_FILE) as f:
179
229
  pid = int(f.read().strip())
180
-
230
+
181
231
  print(f"Stopping Socket.IO server (PID: {pid})...")
182
232
  os.kill(pid, signal.SIGTERM)
183
-
233
+
184
234
  # Wait for process to stop
185
235
  for _ in range(10):
186
236
  if not is_running():
@@ -188,69 +238,133 @@ def stop_server():
188
238
  PID_FILE.unlink(missing_ok=True)
189
239
  return
190
240
  time.sleep(0.5)
191
-
241
+
192
242
  # Force kill if still running
193
243
  print("Server didn't stop gracefully, forcing...")
194
244
  os.kill(pid, signal.SIGKILL)
195
245
  PID_FILE.unlink(missing_ok=True)
196
-
246
+
197
247
  except Exception as e:
198
248
  print(f"Error stopping server: {e}")
199
249
 
250
+
200
251
  def status_server():
201
- """Check server status with manager integration info."""
252
+ """Check server status with port manager integration."""
253
+ port_manager = PortManager()
254
+
255
+ # Clean up dead instances first
256
+ port_manager.cleanup_dead_instances()
257
+
202
258
  if is_running():
203
259
  with open(PID_FILE) as f:
204
260
  pid = int(f.read().strip())
205
261
  print(f"Socket.IO daemon server is running (PID: {pid})")
206
262
  print(f"PID file: {PID_FILE}")
207
-
263
+
264
+ # Get port information
265
+ port_file = PID_FILE.parent / "socketio-port"
266
+ current_port = 8765 # default
267
+ if port_file.exists():
268
+ try:
269
+ with open(port_file) as f:
270
+ current_port = int(f.read().strip())
271
+ except:
272
+ pass
273
+
208
274
  # Check if port is listening
209
275
  try:
210
276
  import socket
277
+
211
278
  sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
212
- result = sock.connect_ex(('localhost', 8765))
279
+ result = sock.connect_ex(("localhost", current_port))
213
280
  sock.close()
214
281
  if result == 0:
215
- print("✅ Server is listening on port 8765")
282
+ print(f"✅ Server is listening on port {current_port}")
216
283
  print("🔧 Management style: daemon")
217
284
  else:
218
- print("⚠️ WARNING: Server process exists but port 8765 is not accessible")
285
+ print(
286
+ f"⚠️ WARNING: Server process exists but port {current_port} is not accessible"
287
+ )
219
288
  except:
220
289
  pass
221
-
290
+
291
+ # Show instance information
292
+ instance = port_manager.get_instance_by_port(current_port)
293
+ if instance:
294
+ print(f"\n📊 Instance Information:")
295
+ print(f" • Port: {instance.get('port')}")
296
+ print(f" • Started: {time.ctime(instance.get('start_time', 0))}")
297
+ print(f" • Instance ID: {instance.get('instance_id')}")
298
+
222
299
  # Show management commands
223
300
  print("\n🔧 Management Commands:")
224
301
  print(f" • Stop: {__file__} stop")
225
302
  print(f" • Restart: {__file__} restart")
226
-
303
+ print(f" • List all: {__file__} list")
304
+
227
305
  # Check for manager conflicts
228
306
  try:
229
307
  import requests
308
+
230
309
  response = requests.get("http://localhost:8765/health", timeout=1.0)
231
310
  if response.status_code == 200:
232
311
  data = response.json()
233
- if 'server_id' in data and data.get('server_id') != 'daemon-socketio':
234
- print(f"\n⚠️ POTENTIAL CONFLICT: HTTP-managed server also detected")
312
+ if "server_id" in data and data.get("server_id") != "daemon-socketio":
313
+ print(
314
+ f"\n⚠️ POTENTIAL CONFLICT: HTTP-managed server also detected"
315
+ )
235
316
  print(f" Server ID: {data.get('server_id')}")
236
317
  print(f" Use 'socketio_server_manager.py diagnose' to resolve")
237
318
  except:
238
319
  pass
239
-
320
+
240
321
  else:
241
322
  print("Socket.IO daemon server is not running")
242
323
  print(f"\n🔧 Start Commands:")
243
324
  print(f" • Daemon: {__file__} start")
244
325
  print(f" • HTTP-managed: socketio_server_manager.py start")
245
326
 
327
+
328
+ def list_instances():
329
+ """List all active SocketIO instances."""
330
+ port_manager = PortManager()
331
+
332
+ # Clean up dead instances first
333
+ cleaned = port_manager.cleanup_dead_instances()
334
+ if cleaned > 0:
335
+ print(f"🧹 Cleaned up {cleaned} dead instances")
336
+
337
+ instances = port_manager.list_active_instances()
338
+
339
+ if not instances:
340
+ print("No active SocketIO instances found.")
341
+ return
342
+
343
+ print(f"📊 Active SocketIO Instances ({len(instances)}):")
344
+ print()
345
+
346
+ for instance in instances:
347
+ port = instance.get("port")
348
+ pid = instance.get("pid")
349
+ start_time = instance.get("start_time", 0)
350
+ instance_id = instance.get("instance_id", "unknown")
351
+
352
+ print(f"🔌 Port {port}:")
353
+ print(f" • PID: {pid}")
354
+ print(f" • Started: {time.ctime(start_time)}")
355
+ print(f" • Instance ID: {instance_id}")
356
+ print(f" • Project: {instance.get('project_root', 'unknown')}")
357
+ print()
358
+
359
+
246
360
  def main():
247
361
  """Main entry point."""
248
362
  if len(sys.argv) < 2:
249
- print("Usage: socketio-daemon.py {start|stop|restart|status}")
363
+ print("Usage: socketio-daemon.py {start|stop|restart|status|list}")
250
364
  sys.exit(1)
251
-
365
+
252
366
  command = sys.argv[1]
253
-
367
+
254
368
  if command == "start":
255
369
  start_server()
256
370
  elif command == "stop":
@@ -261,11 +375,14 @@ def main():
261
375
  start_server()
262
376
  elif command == "status":
263
377
  status_server()
378
+ elif command == "list":
379
+ list_instances()
264
380
  else:
265
381
  print(f"Unknown command: {command}")
266
- print("Usage: socketio-daemon.py {start|stop|restart|status}")
382
+ print("Usage: socketio-daemon.py {start|stop|restart|status|list}")
267
383
  sys.exit(1)
268
384
 
385
+
269
386
  if __name__ == "__main__":
270
387
  # Install psutil if not available
271
388
  try:
@@ -274,5 +391,5 @@ if __name__ == "__main__":
274
391
  print("Installing psutil...")
275
392
  subprocess.check_call([sys.executable, "-m", "pip", "install", "psutil"])
276
393
  import psutil
277
-
278
- main()
394
+
395
+ main()