claude-mpm 3.9.9__py3-none-any.whl → 4.0.3__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 (411) 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 +155 -0
  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 +1 -1
  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 +90 -49
  31. claude_mpm/cli/__main__.py +3 -2
  32. claude_mpm/cli/commands/__init__.py +21 -18
  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 +143 -762
  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 +203 -81
  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 +305 -197
  50. claude_mpm/cli/parser.py +24 -1150
  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 +104 -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 +217 -0
  69. claude_mpm/config/paths.py +94 -208
  70. claude_mpm/config/socketio_config.py +84 -73
  71. claude_mpm/constants.py +36 -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/css/dashboard.css +27 -8
  113. claude_mpm/dashboard/static/dist/components/agent-inference.js +2 -0
  114. claude_mpm/dashboard/static/dist/components/event-processor.js +2 -0
  115. claude_mpm/dashboard/static/dist/components/event-viewer.js +2 -0
  116. claude_mpm/dashboard/static/dist/components/export-manager.js +2 -0
  117. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +2 -0
  118. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +2 -0
  119. claude_mpm/dashboard/static/dist/components/hud-manager.js +2 -0
  120. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +2 -0
  121. claude_mpm/dashboard/static/dist/components/module-viewer.js +2 -0
  122. claude_mpm/dashboard/static/dist/components/session-manager.js +2 -0
  123. claude_mpm/dashboard/static/dist/components/socket-manager.js +2 -0
  124. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +2 -0
  125. claude_mpm/dashboard/static/dist/components/working-directory.js +2 -0
  126. claude_mpm/dashboard/static/dist/dashboard.js +2 -0
  127. claude_mpm/dashboard/static/dist/socket-client.js +2 -0
  128. claude_mpm/dashboard/static/js/components/agent-inference.js +80 -76
  129. claude_mpm/dashboard/static/js/components/event-processor.js +71 -67
  130. claude_mpm/dashboard/static/js/components/event-viewer.js +74 -70
  131. claude_mpm/dashboard/static/js/components/export-manager.js +31 -28
  132. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +106 -92
  133. claude_mpm/dashboard/static/js/components/hud-library-loader.js +11 -11
  134. claude_mpm/dashboard/static/js/components/hud-manager.js +73 -73
  135. claude_mpm/dashboard/static/js/components/hud-visualizer.js +163 -163
  136. claude_mpm/dashboard/static/js/components/module-viewer.js +305 -233
  137. claude_mpm/dashboard/static/js/components/session-manager.js +32 -29
  138. claude_mpm/dashboard/static/js/components/socket-manager.js +27 -20
  139. claude_mpm/dashboard/static/js/components/ui-state-manager.js +21 -18
  140. claude_mpm/dashboard/static/js/components/working-directory.js +74 -71
  141. claude_mpm/dashboard/static/js/dashboard.js +178 -453
  142. claude_mpm/dashboard/static/js/extension-error-handler.js +164 -0
  143. claude_mpm/dashboard/static/js/socket-client.js +120 -54
  144. claude_mpm/dashboard/templates/index.html +40 -50
  145. claude_mpm/experimental/cli_enhancements.py +60 -58
  146. claude_mpm/generators/__init__.py +1 -1
  147. claude_mpm/generators/agent_profile_generator.py +75 -65
  148. claude_mpm/hooks/__init__.py +1 -1
  149. claude_mpm/hooks/base_hook.py +33 -28
  150. claude_mpm/hooks/claude_hooks/__init__.py +1 -1
  151. claude_mpm/hooks/claude_hooks/connection_pool.py +120 -0
  152. claude_mpm/hooks/claude_hooks/event_handlers.py +743 -0
  153. claude_mpm/hooks/claude_hooks/hook_handler.py +415 -1331
  154. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +4 -4
  155. claude_mpm/hooks/claude_hooks/memory_integration.py +221 -0
  156. claude_mpm/hooks/claude_hooks/response_tracking.py +348 -0
  157. claude_mpm/hooks/claude_hooks/tool_analysis.py +230 -0
  158. claude_mpm/hooks/memory_integration_hook.py +140 -100
  159. claude_mpm/hooks/tool_call_interceptor.py +89 -76
  160. claude_mpm/hooks/validation_hooks.py +57 -49
  161. claude_mpm/init.py +145 -121
  162. claude_mpm/models/__init__.py +9 -9
  163. claude_mpm/models/agent_definition.py +33 -23
  164. claude_mpm/models/agent_session.py +228 -200
  165. claude_mpm/scripts/__init__.py +1 -1
  166. claude_mpm/scripts/socketio_daemon.py +192 -75
  167. claude_mpm/scripts/socketio_server_manager.py +328 -0
  168. claude_mpm/scripts/start_activity_logging.py +25 -22
  169. claude_mpm/services/__init__.py +68 -43
  170. claude_mpm/services/agent_capabilities_service.py +271 -0
  171. claude_mpm/services/agents/__init__.py +23 -32
  172. claude_mpm/services/agents/deployment/__init__.py +3 -3
  173. claude_mpm/services/agents/deployment/agent_config_provider.py +310 -0
  174. claude_mpm/services/agents/deployment/agent_configuration_manager.py +359 -0
  175. claude_mpm/services/agents/deployment/agent_definition_factory.py +84 -0
  176. claude_mpm/services/agents/deployment/agent_deployment.py +415 -2113
  177. claude_mpm/services/agents/deployment/agent_discovery_service.py +387 -0
  178. claude_mpm/services/agents/deployment/agent_environment_manager.py +293 -0
  179. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +387 -0
  180. claude_mpm/services/agents/deployment/agent_format_converter.py +453 -0
  181. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +161 -0
  182. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +345 -495
  183. claude_mpm/services/agents/deployment/agent_metrics_collector.py +279 -0
  184. claude_mpm/services/agents/deployment/agent_restore_handler.py +88 -0
  185. claude_mpm/services/agents/deployment/agent_template_builder.py +406 -0
  186. claude_mpm/services/agents/deployment/agent_validator.py +352 -0
  187. claude_mpm/services/agents/deployment/agent_version_manager.py +313 -0
  188. claude_mpm/services/agents/deployment/agent_versioning.py +6 -9
  189. claude_mpm/services/agents/deployment/agents_directory_resolver.py +79 -0
  190. claude_mpm/services/agents/deployment/async_agent_deployment.py +298 -234
  191. claude_mpm/services/agents/deployment/config/__init__.py +13 -0
  192. claude_mpm/services/agents/deployment/config/deployment_config.py +182 -0
  193. claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
  194. claude_mpm/services/agents/deployment/deployment_config_loader.py +54 -0
  195. claude_mpm/services/agents/deployment/deployment_type_detector.py +124 -0
  196. claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
  197. claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
  198. claude_mpm/services/agents/deployment/facade/deployment_executor.py +73 -0
  199. claude_mpm/services/agents/deployment/facade/deployment_facade.py +270 -0
  200. claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
  201. claude_mpm/services/agents/deployment/interface_adapter.py +227 -0
  202. claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
  203. claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
  204. claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
  205. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
  206. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +159 -0
  207. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
  208. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
  209. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +195 -0
  210. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +119 -0
  211. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +79 -0
  212. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +90 -0
  213. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +100 -0
  214. claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
  215. claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +98 -0
  216. claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
  217. claude_mpm/services/agents/deployment/processors/agent_processor.py +258 -0
  218. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +318 -0
  219. claude_mpm/services/agents/deployment/results/__init__.py +13 -0
  220. claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
  221. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
  222. claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
  223. claude_mpm/services/agents/deployment/strategies/base_strategy.py +119 -0
  224. claude_mpm/services/agents/deployment/strategies/project_strategy.py +150 -0
  225. claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
  226. claude_mpm/services/agents/deployment/strategies/system_strategy.py +116 -0
  227. claude_mpm/services/agents/deployment/strategies/user_strategy.py +137 -0
  228. claude_mpm/services/agents/deployment/system_instructions_deployer.py +108 -0
  229. claude_mpm/services/agents/deployment/validation/__init__.py +19 -0
  230. claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
  231. claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
  232. claude_mpm/services/agents/deployment/validation/template_validator.py +299 -0
  233. claude_mpm/services/agents/deployment/validation/validation_result.py +226 -0
  234. claude_mpm/services/agents/loading/__init__.py +2 -2
  235. claude_mpm/services/agents/loading/agent_profile_loader.py +259 -229
  236. claude_mpm/services/agents/loading/base_agent_manager.py +90 -81
  237. claude_mpm/services/agents/loading/framework_agent_loader.py +154 -129
  238. claude_mpm/services/agents/management/__init__.py +2 -2
  239. claude_mpm/services/agents/management/agent_capabilities_generator.py +72 -58
  240. claude_mpm/services/agents/management/agent_management_service.py +209 -156
  241. claude_mpm/services/agents/memory/__init__.py +9 -6
  242. claude_mpm/services/agents/memory/agent_memory_manager.py +218 -1152
  243. claude_mpm/services/agents/memory/agent_persistence_service.py +20 -16
  244. claude_mpm/services/agents/memory/analyzer.py +430 -0
  245. claude_mpm/services/agents/memory/content_manager.py +376 -0
  246. claude_mpm/services/agents/memory/template_generator.py +468 -0
  247. claude_mpm/services/agents/registry/__init__.py +7 -10
  248. claude_mpm/services/agents/registry/deployed_agent_discovery.py +122 -97
  249. claude_mpm/services/agents/registry/modification_tracker.py +351 -285
  250. claude_mpm/services/async_session_logger.py +187 -153
  251. claude_mpm/services/claude_session_logger.py +87 -72
  252. claude_mpm/services/command_handler_service.py +217 -0
  253. claude_mpm/services/communication/__init__.py +3 -2
  254. claude_mpm/services/core/__init__.py +50 -97
  255. claude_mpm/services/core/base.py +60 -53
  256. claude_mpm/services/core/interfaces/__init__.py +188 -0
  257. claude_mpm/services/core/interfaces/agent.py +351 -0
  258. claude_mpm/services/core/interfaces/communication.py +343 -0
  259. claude_mpm/services/core/interfaces/infrastructure.py +413 -0
  260. claude_mpm/services/core/interfaces/service.py +434 -0
  261. claude_mpm/services/core/interfaces.py +19 -944
  262. claude_mpm/services/event_aggregator.py +208 -170
  263. claude_mpm/services/exceptions.py +387 -308
  264. claude_mpm/services/framework_claude_md_generator/__init__.py +75 -79
  265. claude_mpm/services/framework_claude_md_generator/content_assembler.py +69 -60
  266. claude_mpm/services/framework_claude_md_generator/content_validator.py +65 -61
  267. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +68 -49
  268. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +34 -34
  269. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +25 -22
  270. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +10 -10
  271. claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +4 -3
  272. claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
  273. claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
  274. claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
  275. claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
  276. claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +4 -3
  277. claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
  278. claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
  279. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +4 -3
  280. claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +5 -4
  281. claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
  282. claude_mpm/services/framework_claude_md_generator/version_manager.py +30 -28
  283. claude_mpm/services/hook_service.py +106 -114
  284. claude_mpm/services/infrastructure/__init__.py +7 -5
  285. claude_mpm/services/infrastructure/context_preservation.py +571 -0
  286. claude_mpm/services/infrastructure/daemon_manager.py +279 -0
  287. claude_mpm/services/infrastructure/logging.py +83 -76
  288. claude_mpm/services/infrastructure/monitoring.py +547 -404
  289. claude_mpm/services/mcp_gateway/__init__.py +40 -23
  290. claude_mpm/services/mcp_gateway/config/__init__.py +2 -2
  291. claude_mpm/services/mcp_gateway/config/config_loader.py +61 -56
  292. claude_mpm/services/mcp_gateway/config/config_schema.py +50 -41
  293. claude_mpm/services/mcp_gateway/config/configuration.py +82 -75
  294. claude_mpm/services/mcp_gateway/core/__init__.py +14 -21
  295. claude_mpm/services/mcp_gateway/core/base.py +80 -67
  296. claude_mpm/services/mcp_gateway/core/exceptions.py +60 -46
  297. claude_mpm/services/mcp_gateway/core/interfaces.py +97 -93
  298. claude_mpm/services/mcp_gateway/main.py +307 -127
  299. claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
  300. claude_mpm/services/mcp_gateway/registry/service_registry.py +100 -101
  301. claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
  302. claude_mpm/services/mcp_gateway/server/__init__.py +4 -4
  303. claude_mpm/services/mcp_gateway/server/{mcp_server.py → mcp_gateway.py} +149 -153
  304. claude_mpm/services/mcp_gateway/server/stdio_handler.py +105 -107
  305. claude_mpm/services/mcp_gateway/server/stdio_server.py +691 -0
  306. claude_mpm/services/mcp_gateway/tools/__init__.py +4 -2
  307. claude_mpm/services/mcp_gateway/tools/base_adapter.py +110 -121
  308. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +283 -215
  309. claude_mpm/services/mcp_gateway/tools/hello_world.py +122 -120
  310. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +652 -0
  311. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +606 -0
  312. claude_mpm/services/memory/__init__.py +2 -2
  313. claude_mpm/services/memory/builder.py +451 -362
  314. claude_mpm/services/memory/cache/__init__.py +2 -2
  315. claude_mpm/services/memory/cache/shared_prompt_cache.py +232 -194
  316. claude_mpm/services/memory/cache/simple_cache.py +107 -93
  317. claude_mpm/services/memory/indexed_memory.py +195 -193
  318. claude_mpm/services/memory/optimizer.py +267 -234
  319. claude_mpm/services/memory/router.py +571 -263
  320. claude_mpm/services/memory_hook_service.py +237 -0
  321. claude_mpm/services/port_manager.py +223 -0
  322. claude_mpm/services/project/__init__.py +3 -3
  323. claude_mpm/services/project/analyzer.py +451 -305
  324. claude_mpm/services/project/registry.py +262 -240
  325. claude_mpm/services/recovery_manager.py +287 -231
  326. claude_mpm/services/response_tracker.py +87 -67
  327. claude_mpm/services/runner_configuration_service.py +587 -0
  328. claude_mpm/services/session_management_service.py +304 -0
  329. claude_mpm/services/socketio/__init__.py +4 -4
  330. claude_mpm/services/socketio/client_proxy.py +174 -0
  331. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  332. claude_mpm/services/socketio/handlers/base.py +44 -30
  333. claude_mpm/services/socketio/handlers/connection.py +145 -65
  334. claude_mpm/services/socketio/handlers/file.py +123 -108
  335. claude_mpm/services/socketio/handlers/git.py +607 -373
  336. claude_mpm/services/socketio/handlers/hook.py +170 -0
  337. claude_mpm/services/socketio/handlers/memory.py +4 -4
  338. claude_mpm/services/socketio/handlers/project.py +4 -4
  339. claude_mpm/services/socketio/handlers/registry.py +53 -38
  340. claude_mpm/services/socketio/server/__init__.py +18 -0
  341. claude_mpm/services/socketio/server/broadcaster.py +252 -0
  342. claude_mpm/services/socketio/server/core.py +399 -0
  343. claude_mpm/services/socketio/server/main.py +323 -0
  344. claude_mpm/services/socketio_client_manager.py +160 -133
  345. claude_mpm/services/socketio_server.py +36 -1885
  346. claude_mpm/services/subprocess_launcher_service.py +316 -0
  347. claude_mpm/services/system_instructions_service.py +258 -0
  348. claude_mpm/services/ticket_manager.py +20 -534
  349. claude_mpm/services/utility_service.py +285 -0
  350. claude_mpm/services/version_control/__init__.py +18 -21
  351. claude_mpm/services/version_control/branch_strategy.py +20 -10
  352. claude_mpm/services/version_control/conflict_resolution.py +37 -13
  353. claude_mpm/services/version_control/git_operations.py +52 -21
  354. claude_mpm/services/version_control/semantic_versioning.py +92 -53
  355. claude_mpm/services/version_control/version_parser.py +145 -125
  356. claude_mpm/services/version_service.py +270 -0
  357. claude_mpm/storage/__init__.py +9 -0
  358. claude_mpm/storage/state_storage.py +552 -0
  359. claude_mpm/ticket_wrapper.py +2 -2
  360. claude_mpm/utils/__init__.py +2 -2
  361. claude_mpm/utils/agent_dependency_loader.py +453 -243
  362. claude_mpm/utils/config_manager.py +157 -118
  363. claude_mpm/utils/console.py +1 -1
  364. claude_mpm/utils/dependency_cache.py +102 -107
  365. claude_mpm/utils/dependency_manager.py +52 -47
  366. claude_mpm/utils/dependency_strategies.py +131 -96
  367. claude_mpm/utils/environment_context.py +110 -102
  368. claude_mpm/utils/error_handler.py +75 -55
  369. claude_mpm/utils/file_utils.py +80 -67
  370. claude_mpm/utils/framework_detection.py +12 -11
  371. claude_mpm/utils/import_migration_example.py +12 -60
  372. claude_mpm/utils/imports.py +48 -45
  373. claude_mpm/utils/path_operations.py +100 -93
  374. claude_mpm/utils/robust_installer.py +172 -164
  375. claude_mpm/utils/session_logging.py +30 -23
  376. claude_mpm/utils/subprocess_utils.py +99 -61
  377. claude_mpm/validation/__init__.py +1 -1
  378. claude_mpm/validation/agent_validator.py +151 -111
  379. claude_mpm/validation/frontmatter_validator.py +92 -71
  380. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/METADATA +51 -2
  381. claude_mpm-4.0.3.dist-info/RECORD +402 -0
  382. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/entry_points.txt +1 -0
  383. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/licenses/LICENSE +1 -1
  384. claude_mpm/config/memory_guardian_config.py +0 -325
  385. claude_mpm/core/config_paths.py +0 -150
  386. claude_mpm/dashboard/static/js/dashboard-original.js +0 -4134
  387. claude_mpm/deployment_paths.py +0 -261
  388. claude_mpm/hooks/claude_hooks/hook_handler_fixed.py +0 -454
  389. claude_mpm/models/state_models.py +0 -433
  390. claude_mpm/services/agent/__init__.py +0 -24
  391. claude_mpm/services/agent/deployment.py +0 -2548
  392. claude_mpm/services/agent/management.py +0 -598
  393. claude_mpm/services/agent/registry.py +0 -813
  394. claude_mpm/services/agents/registry/agent_registry.py +0 -813
  395. claude_mpm/services/communication/socketio.py +0 -1935
  396. claude_mpm/services/communication/websocket.py +0 -479
  397. claude_mpm/services/framework_claude_md_generator.py +0 -624
  398. claude_mpm/services/health_monitor.py +0 -893
  399. claude_mpm/services/infrastructure/memory_guardian.py +0 -770
  400. claude_mpm/services/mcp_gateway/server/mcp_server_simple.py +0 -444
  401. claude_mpm/services/optimized_hook_service.py +0 -542
  402. claude_mpm/services/project_analyzer.py +0 -864
  403. claude_mpm/services/project_registry.py +0 -608
  404. claude_mpm/services/standalone_socketio_server.py +0 -1300
  405. claude_mpm/services/ticket_manager_di.py +0 -318
  406. claude_mpm/services/ticketing_service_original.py +0 -510
  407. claude_mpm/utils/paths.py +0 -395
  408. claude_mpm/utils/platform_memory.py +0 -524
  409. claude_mpm-3.9.9.dist-info/RECORD +0 -293
  410. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/WHEEL +0 -0
  411. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/top_level.txt +0 -0
@@ -9,7 +9,7 @@ class SessionManager {
9
9
  this.sessions = new Map();
10
10
  this.currentSessionId = null;
11
11
  this.selectedSessionId = '';
12
-
12
+
13
13
  this.init();
14
14
  }
15
15
 
@@ -32,7 +32,7 @@ class SessionManager {
32
32
  sessionSelect.addEventListener('change', (e) => {
33
33
  this.selectedSessionId = e.target.value;
34
34
  this.onSessionFilterChanged();
35
-
35
+
36
36
  // Load working directory for this session
37
37
  if (window.dashboard && window.dashboard.loadWorkingDirectoryForSession) {
38
38
  window.dashboard.loadWorkingDirectoryForSession(e.target.value);
@@ -93,12 +93,12 @@ class SessionManager {
93
93
  sortedSessions.forEach(session => {
94
94
  const option = document.createElement('option');
95
95
  option.value = session.id;
96
-
96
+
97
97
  // Format session display text
98
98
  const startTime = new Date(session.startTime || session.last_activity).toLocaleString();
99
99
  const eventCount = session.eventCount || session.event_count || 0;
100
100
  const isActive = session.id === this.currentSessionId;
101
-
101
+
102
102
  option.textContent = `${session.id.substring(0, 8)}... (${eventCount} events, ${startTime})${isActive ? ' [ACTIVE]' : ''}`;
103
103
  sessionSelect.appendChild(option);
104
104
  });
@@ -136,7 +136,7 @@ class SessionManager {
136
136
  document.dispatchEvent(new CustomEvent('sessionFilterChanged', {
137
137
  detail: { sessionId: this.selectedSessionId }
138
138
  }));
139
-
139
+
140
140
  // Also dispatch sessionChanged for backward compatibility with other components
141
141
  document.dispatchEvent(new CustomEvent('sessionChanged', {
142
142
  detail: { sessionId: this.selectedSessionId }
@@ -160,7 +160,7 @@ class SessionManager {
160
160
  */
161
161
  updateFooterInfo() {
162
162
  console.log('[SESSION-DEBUG] updateFooterInfo called, selectedSessionId:', this.selectedSessionId);
163
-
163
+
164
164
  const footerSessionEl = document.getElementById('footer-session');
165
165
  const footerWorkingDirEl = document.getElementById('footer-working-dir');
166
166
  const footerGitBranchEl = document.getElementById('footer-git-branch');
@@ -173,14 +173,14 @@ class SessionManager {
173
173
  let sessionInfo = 'All Sessions';
174
174
  let workingDir = window.dashboard?.workingDirectoryManager?.getDefaultWorkingDir() || process?.cwd?.() || '/Users/masa/Projects/claude-mpm';
175
175
  let gitBranch = 'Unknown';
176
-
176
+
177
177
  console.log('[SESSION-DEBUG] Initial values - sessionInfo:', sessionInfo, 'workingDir:', workingDir, 'gitBranch:', gitBranch);
178
178
 
179
179
  if (this.selectedSessionId === 'current') {
180
- sessionInfo = this.currentSessionId ?
181
- `Current: ${this.currentSessionId.substring(0, 8)}...` :
180
+ sessionInfo = this.currentSessionId ?
181
+ `Current: ${this.currentSessionId.substring(0, 8)}...` :
182
182
  'Current: None';
183
-
183
+
184
184
  // For current session, try to extract info from recent events
185
185
  if (this.currentSessionId) {
186
186
  const sessionData = this.extractSessionInfoFromEvents(this.currentSessionId);
@@ -193,7 +193,7 @@ class SessionManager {
193
193
  sessionInfo = `${this.selectedSessionId.substring(0, 8)}...`;
194
194
  workingDir = session.working_directory || session.workingDirectory || '';
195
195
  gitBranch = session.git_branch || session.gitBranch || '';
196
-
196
+
197
197
  // If session doesn't have these values, extract from events
198
198
  if (!workingDir || !gitBranch) {
199
199
  const sessionData = this.extractSessionInfoFromEvents(this.selectedSessionId);
@@ -204,7 +204,7 @@ class SessionManager {
204
204
  }
205
205
 
206
206
  console.log('[SESSION-DEBUG] Final values before setting footer - sessionInfo:', sessionInfo, 'workingDir:', workingDir, 'gitBranch:', gitBranch);
207
-
207
+
208
208
  footerSessionEl.textContent = sessionInfo;
209
209
  if (footerWorkingDirEl) {
210
210
  console.log('[SESSION-DEBUG] Setting footer working dir to:', workingDir);
@@ -235,9 +235,9 @@ class SessionManager {
235
235
  const socketClient = this.socketClient;
236
236
  if (socketClient && socketClient.events) {
237
237
  console.log(`[DEBUG] Total events available: ${socketClient.events.length}`);
238
-
238
+
239
239
  // Look for session start events or recent events with this session ID
240
- const sessionEvents = socketClient.events.filter(event =>
240
+ const sessionEvents = socketClient.events.filter(event =>
241
241
  event.data && event.data.session_id === sessionId
242
242
  );
243
243
 
@@ -246,7 +246,7 @@ class SessionManager {
246
246
  // Log a few sample events to see their structure
247
247
  if (sessionEvents.length > 0) {
248
248
  console.log(`[DEBUG] Sample events for session ${sessionId}:`);
249
-
249
+
250
250
  // Show first 3 events
251
251
  sessionEvents.slice(0, 3).forEach((event, index) => {
252
252
  console.log(`[DEBUG] Event ${index + 1}:`, {
@@ -276,7 +276,7 @@ class SessionManager {
276
276
  const event = sessionEvents[i];
277
277
  if (event.data) {
278
278
  console.log(`[DEBUG] Examining event ${i} data:`, event.data);
279
-
279
+
280
280
  // Check for working directory info
281
281
  if (!workingDir) {
282
282
  if (event.data.working_directory) {
@@ -295,13 +295,13 @@ class SessionManager {
295
295
  if (!gitBranch) {
296
296
  const possibleBranchFields = [
297
297
  'git_branch',
298
- 'gitBranch',
298
+ 'gitBranch',
299
299
  'branch',
300
300
  'git.branch',
301
301
  'vcs_branch',
302
302
  'current_branch'
303
303
  ];
304
-
304
+
305
305
  for (const field of possibleBranchFields) {
306
306
  if (event.data[field]) {
307
307
  gitBranch = event.data[field];
@@ -309,7 +309,7 @@ class SessionManager {
309
309
  break;
310
310
  }
311
311
  }
312
-
312
+
313
313
  // Check nested locations
314
314
  if (!gitBranch) {
315
315
  if (event.data.instance_info) {
@@ -322,7 +322,7 @@ class SessionManager {
322
322
  }
323
323
  }
324
324
  }
325
-
325
+
326
326
  if (!gitBranch && event.data.git) {
327
327
  console.log(`[DEBUG] Checking git object:`, event.data.git);
328
328
  if (event.data.git.branch) {
@@ -364,7 +364,7 @@ class SessionManager {
364
364
  */
365
365
  addSession(sessionData) {
366
366
  if (!sessionData.id) return;
367
-
367
+
368
368
  const existingSession = this.sessions.get(sessionData.id);
369
369
  if (existingSession) {
370
370
  // Update existing session
@@ -382,7 +382,7 @@ class SessionManager {
382
382
  ...sessionData
383
383
  });
384
384
  }
385
-
385
+
386
386
  this.updateSessionSelect();
387
387
  }
388
388
 
@@ -393,7 +393,7 @@ class SessionManager {
393
393
  removeSession(sessionId) {
394
394
  if (this.sessions.has(sessionId)) {
395
395
  this.sessions.delete(sessionId);
396
-
396
+
397
397
  // If the removed session was selected, reset to all sessions
398
398
  if (this.selectedSessionId === sessionId) {
399
399
  this.selectedSessionId = '';
@@ -403,7 +403,7 @@ class SessionManager {
403
403
  }
404
404
  this.onSessionFilterChanged();
405
405
  }
406
-
406
+
407
407
  this.updateSessionSelect();
408
408
  }
409
409
  }
@@ -475,15 +475,15 @@ class SessionManager {
475
475
  this.sessions.set(id, sessionData);
476
476
  });
477
477
  }
478
-
478
+
479
479
  if (data.currentSessionId) {
480
480
  this.currentSessionId = data.currentSessionId;
481
481
  }
482
-
482
+
483
483
  if (data.selectedSessionId !== undefined) {
484
484
  this.selectedSessionId = data.selectedSessionId;
485
485
  }
486
-
486
+
487
487
  this.updateSessionSelect();
488
488
  this.updateFooterInfo();
489
489
  }
@@ -501,7 +501,7 @@ class SessionManager {
501
501
  const allEvents = this.socketClient.events || [];
502
502
  return allEvents.filter(event => {
503
503
  // Check for session ID in various possible locations
504
- const eventSessionId = event.session_id ||
504
+ const eventSessionId = event.session_id ||
505
505
  (event.data && event.data.session_id) ||
506
506
  null;
507
507
  return eventSessionId === sessionId;
@@ -517,4 +517,7 @@ window.refreshSessions = function() {
517
517
  };
518
518
 
519
519
  // Export for global use
520
- window.SessionManager = SessionManager;
520
+ window.SessionManager = SessionManager;
521
+ // ES6 Module export
522
+ export { SessionManager };
523
+ export default SessionManager;
@@ -1,36 +1,39 @@
1
1
  /**
2
2
  * Socket Manager Module
3
- *
3
+ *
4
4
  * Handles all socket connection management, event dispatching, and connection state.
5
5
  * Provides a centralized interface for socket operations across the dashboard.
6
- *
6
+ *
7
7
  * WHY: Extracted from main dashboard to centralize socket connection logic and
8
8
  * provide better separation of concerns. This allows for easier testing and
9
9
  * maintenance of connection handling code.
10
- *
10
+ *
11
11
  * DESIGN DECISION: Acts as a wrapper around SocketClient to provide dashboard-specific
12
12
  * connection management while maintaining the existing SocketClient interface.
13
13
  * Uses event dispatching to notify other modules of connection state changes.
14
14
  */
15
+
16
+ // Import SocketClient (assuming it will be converted to ES6 modules too)
17
+ import { SocketClient } from '../socket-client.js';
15
18
  class SocketManager {
16
19
  constructor() {
17
20
  this.socketClient = null;
18
21
  this.connectionCallbacks = new Set();
19
22
  this.eventUpdateCallbacks = new Set();
20
-
23
+
21
24
  // Initialize socket client
22
25
  this.socketClient = new SocketClient();
23
-
26
+
24
27
  // Make socketClient globally available (for backward compatibility)
25
28
  window.socketClient = this.socketClient;
26
-
29
+
27
30
  this.setupSocketEventHandlers();
28
-
31
+
29
32
  // Force initial status update after a short delay to ensure DOM is ready
30
33
  setTimeout(() => {
31
34
  this.updateInitialConnectionStatus();
32
35
  }, 100);
33
-
36
+
34
37
  console.log('Socket manager initialized');
35
38
  }
36
39
 
@@ -42,7 +45,7 @@ class SocketManager {
42
45
  document.addEventListener('socketConnectionStatus', (e) => {
43
46
  console.log(`SocketManager: Processing connection status update: ${e.detail.status} (${e.detail.type})`);
44
47
  this.handleConnectionStatusChange(e.detail.status, e.detail.type);
45
-
48
+
46
49
  // Notify all registered callbacks
47
50
  this.connectionCallbacks.forEach(callback => {
48
51
  try {
@@ -75,7 +78,7 @@ class SocketManager {
75
78
  */
76
79
  handleConnectionStatusChange(status, type) {
77
80
  this.updateConnectionStatus(status, type);
78
-
81
+
79
82
  // Set up git branch listener when connected
80
83
  if (type === 'connected' && this.socketClient && this.socketClient.socket) {
81
84
  this.setupGitBranchListener();
@@ -87,7 +90,7 @@ class SocketManager {
87
90
  */
88
91
  updateInitialConnectionStatus() {
89
92
  console.log('SocketManager: Updating initial connection status');
90
-
93
+
91
94
  // Force status check on socket client (uses fallback mechanism)
92
95
  if (this.socketClient && typeof this.socketClient.checkAndUpdateStatus === 'function') {
93
96
  console.log('SocketManager: Using socket client checkAndUpdateStatus method');
@@ -99,7 +102,7 @@ class SocketManager {
99
102
  isConnecting: this.socketClient.isConnecting,
100
103
  isConnected: this.socketClient.isConnected
101
104
  });
102
-
105
+
103
106
  if (this.socketClient.socket.connected) {
104
107
  console.log('SocketManager: Socket is already connected, updating status');
105
108
  this.updateConnectionStatus('Connected', 'connected');
@@ -114,7 +117,7 @@ class SocketManager {
114
117
  console.log('SocketManager: No socket client or socket found, setting disconnected status');
115
118
  this.updateConnectionStatus('Disconnected', 'disconnected');
116
119
  }
117
-
120
+
118
121
  // Additional fallback - check again after a longer delay in case connection is still establishing
119
122
  setTimeout(() => {
120
123
  console.log('SocketManager: Secondary status check after 1 second');
@@ -131,7 +134,7 @@ class SocketManager {
131
134
  setupGitBranchListener() {
132
135
  // Remove any existing listener first
133
136
  this.socketClient.socket.off('git_branch_response');
134
-
137
+
135
138
  // Add the listener
136
139
  this.socketClient.socket.on('git_branch_response', (data) => {
137
140
  if (data.success) {
@@ -166,7 +169,7 @@ class SocketManager {
166
169
  // If no span, just update text content
167
170
  statusElement.textContent = status;
168
171
  }
169
-
172
+
170
173
  statusElement.className = `status-badge status-${type}`;
171
174
  console.log(`SocketManager: UI updated - status: '${status}' (${type})`);
172
175
  } else {
@@ -263,10 +266,10 @@ class SocketManager {
263
266
  toggleConnectionControls() {
264
267
  const controlsRow = document.getElementById('connection-controls-row');
265
268
  const toggleBtn = document.getElementById('connection-toggle-btn');
266
-
269
+
267
270
  if (controlsRow && toggleBtn) {
268
271
  const isVisible = controlsRow.classList.contains('show');
269
-
272
+
270
273
  if (isVisible) {
271
274
  controlsRow.classList.remove('show');
272
275
  controlsRow.style.display = 'none';
@@ -315,7 +318,7 @@ class SocketManager {
315
318
  initializeFromURL(params) {
316
319
  const port = params.get('port');
317
320
  const portInput = document.getElementById('port-input');
318
-
321
+
319
322
  // Determine the port to use:
320
323
  // 1. URL parameter 'port'
321
324
  // 2. Current page port (if served via HTTP)
@@ -328,7 +331,7 @@ class SocketManager {
328
331
  if (!connectPort) {
329
332
  connectPort = portInput?.value || '8765';
330
333
  }
331
-
334
+
332
335
  // Update the port input field with the determined port
333
336
  if (portInput) {
334
337
  portInput.value = connectPort;
@@ -340,4 +343,8 @@ class SocketManager {
340
343
  this.connect(connectPort);
341
344
  }
342
345
  }
343
- }
346
+ }
347
+
348
+ // ES6 Module export
349
+ export { SocketManager };
350
+ export default SocketManager;
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * UI State Manager Module
3
- *
3
+ *
4
4
  * Manages UI state including tab switching, card selection, keyboard navigation,
5
5
  * and visual feedback across the dashboard interface.
6
- *
6
+ *
7
7
  * WHY: Extracted from main dashboard to centralize UI state management and
8
8
  * provide better separation between business logic and UI state. This makes
9
9
  * the UI behavior more predictable and easier to test.
10
- *
10
+ *
11
11
  * DESIGN DECISION: Maintains centralized state for current tab, selected cards,
12
12
  * and navigation context while providing a clean API for other modules to
13
13
  * interact with UI state changes.
@@ -16,10 +16,10 @@ class UIStateManager {
16
16
  constructor() {
17
17
  // Current active tab
18
18
  this.currentTab = 'events';
19
-
19
+
20
20
  // Auto-scroll behavior
21
21
  this.autoScroll = true;
22
-
22
+
23
23
  // Selection state - tracks the currently selected card across all tabs
24
24
  this.selectedCard = {
25
25
  tab: null, // which tab the selection is in
@@ -27,7 +27,7 @@ class UIStateManager {
27
27
  type: null, // 'event', 'agent', 'tool', 'file'
28
28
  data: null // the actual data object
29
29
  };
30
-
30
+
31
31
  // Navigation state for each tab
32
32
  this.tabNavigation = {
33
33
  events: { selectedIndex: -1, items: [] },
@@ -67,7 +67,7 @@ class UIStateManager {
67
67
  setupUnifiedKeyboardNavigation() {
68
68
  document.addEventListener('keydown', (e) => {
69
69
  // Only handle if not in an input field
70
- if (document.activeElement &&
70
+ if (document.activeElement &&
71
71
  ['INPUT', 'TEXTAREA', 'SELECT'].includes(document.activeElement.tagName)) {
72
72
  return;
73
73
  }
@@ -130,7 +130,7 @@ class UIStateManager {
130
130
 
131
131
  // Trigger tab change event for other modules
132
132
  document.dispatchEvent(new CustomEvent('tabChanged', {
133
- detail: {
133
+ detail: {
134
134
  newTab: tabName,
135
135
  previousTab: previousTab
136
136
  }
@@ -153,10 +153,10 @@ class UIStateManager {
153
153
  if (!tabNav) return;
154
154
 
155
155
  let newIndex = tabNav.selectedIndex + direction;
156
-
156
+
157
157
  // Handle bounds
158
158
  if (tabNav.items.length === 0) return;
159
-
159
+
160
160
  if (newIndex < 0) {
161
161
  newIndex = tabNav.items.length - 1;
162
162
  } else if (newIndex >= tabNav.items.length) {
@@ -187,7 +187,7 @@ class UIStateManager {
187
187
  Object.keys(this.tabNavigation).forEach(tabName => {
188
188
  this.tabNavigation[tabName].selectedIndex = -1;
189
189
  });
190
-
190
+
191
191
  // Clear card selection
192
192
  this.clearCardSelection();
193
193
  }
@@ -232,7 +232,7 @@ class UIStateManager {
232
232
 
233
233
  // Update navigation state
234
234
  tabNav.selectedIndex = index;
235
-
235
+
236
236
  // Update visual selection
237
237
  this.updateUnifiedSelectionUI();
238
238
 
@@ -288,7 +288,7 @@ class UIStateManager {
288
288
  selectCard(tabName, index, type, data) {
289
289
  // Clear previous selection
290
290
  this.clearCardSelection();
291
-
291
+
292
292
  // Update selection state
293
293
  this.selectedCard = {
294
294
  tab: tabName,
@@ -298,7 +298,7 @@ class UIStateManager {
298
298
  };
299
299
 
300
300
  this.updateCardSelectionUI();
301
-
301
+
302
302
  console.log('Card selected:', this.selectedCard);
303
303
  }
304
304
 
@@ -310,7 +310,7 @@ class UIStateManager {
310
310
  document.querySelectorAll('.event-item.selected, .file-item.selected').forEach(el => {
311
311
  el.classList.remove('selected');
312
312
  });
313
-
313
+
314
314
  // Reset selection state
315
315
  this.selectedCard = {
316
316
  tab: null,
@@ -325,7 +325,7 @@ class UIStateManager {
325
325
  */
326
326
  updateCardSelectionUI() {
327
327
  if (!this.selectedCard.tab || this.selectedCard.index === null) return;
328
-
328
+
329
329
  // Get the list container for the selected tab
330
330
  let listContainer;
331
331
  switch (this.selectedCard.tab) {
@@ -342,7 +342,7 @@ class UIStateManager {
342
342
  listContainer = document.getElementById('files-list');
343
343
  break;
344
344
  }
345
-
345
+
346
346
  if (listContainer) {
347
347
  const items = listContainer.querySelectorAll('.event-item, .file-item');
348
348
  if (items[this.selectedCard.index]) {
@@ -424,4 +424,7 @@ class UIStateManager {
424
424
  getAutoScroll() {
425
425
  return this.autoScroll;
426
426
  }
427
- }
427
+ }
428
+ // ES6 Module export
429
+ export { UIStateManager };
430
+ export default UIStateManager;