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
@@ -1,14 +1,14 @@
1
1
  /**
2
2
  * File and Tool Tracker Module
3
- *
3
+ *
4
4
  * Tracks file operations and tool calls by pairing pre/post events and maintaining
5
5
  * organized collections for the files and tools tabs. Provides analysis of
6
6
  * tool execution patterns and file operation history.
7
- *
7
+ *
8
8
  * WHY: Extracted from main dashboard to isolate complex event pairing logic
9
9
  * that groups related events into meaningful operations. This provides better
10
10
  * maintainability for the intricate logic of matching tool events with their results.
11
- *
11
+ *
12
12
  * DESIGN DECISION: Uses intelligent correlation strategy for tool calls that:
13
13
  * - Separates pre_tool and post_tool events first
14
14
  * - Correlates based on temporal proximity, parameter similarity, and context
@@ -20,13 +20,13 @@ class FileToolTracker {
20
20
  constructor(agentInference, workingDirectoryManager) {
21
21
  this.agentInference = agentInference;
22
22
  this.workingDirectoryManager = workingDirectoryManager;
23
-
23
+
24
24
  // File tracking for files tab
25
25
  this.fileOperations = new Map(); // Map of file paths to operations
26
-
26
+
27
27
  // Tool call tracking for tools tab
28
28
  this.toolCalls = new Map(); // Map of tool call keys to paired pre/post events
29
-
29
+
30
30
  console.log('File-tool tracker initialized');
31
31
  }
32
32
 
@@ -43,12 +43,12 @@ class FileToolTracker {
43
43
  // Group events by session and timestamp to match pre/post pairs
44
44
  const eventPairs = new Map(); // Key: session_id + timestamp + tool_name
45
45
  let fileOperationCount = 0;
46
-
46
+
47
47
  // First pass: collect all tool events and group them
48
48
  events.forEach((event, index) => {
49
49
  const isFileOp = this.isFileOperation(event);
50
50
  if (isFileOp) fileOperationCount++;
51
-
51
+
52
52
  if (index < 5) { // Debug first 5 events with more detail
53
53
  console.log(`Event ${index}:`, {
54
54
  type: event.type,
@@ -58,12 +58,12 @@ class FileToolTracker {
58
58
  isFileOp: isFileOp
59
59
  });
60
60
  }
61
-
61
+
62
62
  if (isFileOp) {
63
- const toolName = event.tool_name;
64
- const sessionId = event.session_id || 'unknown';
63
+ const toolName = event.tool_name || (event.data && event.data.tool_name);
64
+ const sessionId = event.session_id || (event.data && event.data.session_id) || 'unknown';
65
65
  const eventKey = `${sessionId}_${toolName}_${Math.floor(new Date(event.timestamp).getTime() / 1000)}`; // Group by second
66
-
66
+
67
67
  if (!eventPairs.has(eventKey)) {
68
68
  eventPairs.set(eventKey, {
69
69
  pre_event: null,
@@ -72,7 +72,7 @@ class FileToolTracker {
72
72
  session_id: sessionId
73
73
  });
74
74
  }
75
-
75
+
76
76
  const pair = eventPairs.get(eventKey);
77
77
  if (event.subtype === 'pre_tool' || event.type === 'hook' && !event.subtype.includes('post')) {
78
78
  pair.pre_event = event;
@@ -85,16 +85,16 @@ class FileToolTracker {
85
85
  }
86
86
  }
87
87
  });
88
-
88
+
89
89
  console.log('updateFileOperations - found', fileOperationCount, 'file operations in', eventPairs.size, 'event pairs');
90
-
90
+
91
91
  // Second pass: extract file paths and operations from paired events
92
92
  eventPairs.forEach((pair, key) => {
93
93
  const filePath = this.extractFilePathFromPair(pair);
94
-
94
+
95
95
  if (filePath) {
96
96
  console.log('File operation detected for:', filePath, 'from pair:', key);
97
-
97
+
98
98
  if (!this.fileOperations.has(filePath)) {
99
99
  this.fileOperations.set(filePath, {
100
100
  path: filePath,
@@ -106,10 +106,10 @@ class FileToolTracker {
106
106
  const fileData = this.fileOperations.get(filePath);
107
107
  const operation = this.getFileOperationFromPair(pair);
108
108
  const timestamp = pair.post_event?.timestamp || pair.pre_event?.timestamp;
109
-
109
+
110
110
  const agentInfo = this.extractAgentFromPair(pair);
111
111
  const workingDirectory = this.workingDirectoryManager.extractWorkingDirectoryFromPair(pair);
112
-
112
+
113
113
  fileData.operations.push({
114
114
  operation: operation,
115
115
  timestamp: timestamp,
@@ -124,7 +124,7 @@ class FileToolTracker {
124
124
  console.log('No file path found for pair:', key, pair);
125
125
  }
126
126
  });
127
-
127
+
128
128
  console.log('updateFileOperations - final result:', this.fileOperations.size, 'file operations');
129
129
  if (this.fileOperations.size > 0) {
130
130
  console.log('File operations map:', Array.from(this.fileOperations.entries()));
@@ -145,12 +145,12 @@ class FileToolTracker {
145
145
  const preToolEvents = [];
146
146
  const postToolEvents = [];
147
147
  let toolOperationCount = 0;
148
-
148
+
149
149
  // First pass: separate pre_tool and post_tool events
150
150
  events.forEach((event, index) => {
151
151
  const isToolOp = this.isToolOperation(event);
152
152
  if (isToolOp) toolOperationCount++;
153
-
153
+
154
154
  if (index < 5) { // Debug first 5 events with more detail
155
155
  console.log(`Tool Event ${index}:`, {
156
156
  type: event.type,
@@ -160,7 +160,7 @@ class FileToolTracker {
160
160
  isToolOp: isToolOp
161
161
  });
162
162
  }
163
-
163
+
164
164
  if (isToolOp) {
165
165
  if (event.subtype === 'pre_tool' || (event.type === 'hook' && !event.subtype.includes('post'))) {
166
166
  preToolEvents.push(event);
@@ -173,18 +173,18 @@ class FileToolTracker {
173
173
  }
174
174
  }
175
175
  });
176
-
176
+
177
177
  console.log('updateToolCalls - found', toolOperationCount, 'tool operations:', preToolEvents.length, 'pre_tool,', postToolEvents.length, 'post_tool');
178
-
178
+
179
179
  // Second pass: correlate pre_tool events with post_tool events
180
180
  const toolCallPairs = new Map();
181
181
  const usedPostEvents = new Set();
182
-
182
+
183
183
  preToolEvents.forEach((preEvent, preIndex) => {
184
- const toolName = preEvent.tool_name;
185
- const sessionId = preEvent.session_id || 'unknown';
184
+ const toolName = preEvent.tool_name || (preEvent.data && preEvent.data.tool_name);
185
+ const sessionId = preEvent.session_id || (preEvent.data && preEvent.data.session_id) || 'unknown';
186
186
  const preTimestamp = new Date(preEvent.timestamp).getTime();
187
-
187
+
188
188
  // Create a base pair for this pre_tool event
189
189
  const pairKey = `${sessionId}_${toolName}_${preIndex}_${preTimestamp}`;
190
190
  const pair = {
@@ -201,53 +201,55 @@ class FileToolTracker {
201
201
  agent_type: null,
202
202
  agent_confidence: null
203
203
  };
204
-
204
+
205
205
  // Get agent info from pre_event
206
206
  const agentInfo = this.extractAgentFromEvent(preEvent);
207
207
  pair.agent_type = agentInfo.name;
208
208
  pair.agent_confidence = agentInfo.confidence;
209
-
209
+
210
210
  // Try to find matching post_tool event
211
211
  let bestMatchIndex = -1;
212
212
  let bestMatchScore = -1;
213
213
  const maxTimeDiffMs = 300000; // 5 minutes max time difference
214
-
214
+
215
215
  postToolEvents.forEach((postEvent, postIndex) => {
216
216
  // Skip already used post events
217
217
  if (usedPostEvents.has(postIndex)) return;
218
-
218
+
219
219
  // Must match tool name and session
220
- if (postEvent.tool_name !== toolName || postEvent.session_id !== sessionId) return;
221
-
220
+ const postToolName = postEvent.tool_name || (postEvent.data && postEvent.data.tool_name);
221
+ const postSessionId = postEvent.session_id || (postEvent.data && postEvent.data.session_id) || 'unknown';
222
+ if (postToolName !== toolName || postSessionId !== sessionId) return;
223
+
222
224
  const postTimestamp = new Date(postEvent.timestamp).getTime();
223
225
  const timeDiff = Math.abs(postTimestamp - preTimestamp);
224
-
226
+
225
227
  // Post event should generally come after pre event (or very close)
226
228
  const isTemporallyValid = postTimestamp >= preTimestamp - 1000; // Allow 1s clock skew
227
-
229
+
228
230
  // Calculate correlation score (higher is better)
229
231
  let score = 0;
230
232
  if (isTemporallyValid && timeDiff <= maxTimeDiffMs) {
231
233
  score = 1000 - (timeDiff / 1000); // Prefer closer timestamps
232
-
234
+
233
235
  // Boost score for parameter similarity (if available)
234
236
  if (this.compareToolParameters(preEvent, postEvent)) {
235
237
  score += 500;
236
238
  }
237
-
239
+
238
240
  // Boost score for same working directory
239
- if (preEvent.working_directory && postEvent.working_directory &&
241
+ if (preEvent.working_directory && postEvent.working_directory &&
240
242
  preEvent.working_directory === postEvent.working_directory) {
241
243
  score += 100;
242
244
  }
243
245
  }
244
-
246
+
245
247
  if (score > bestMatchScore) {
246
248
  bestMatchScore = score;
247
249
  bestMatchIndex = postIndex;
248
250
  }
249
251
  });
250
-
252
+
251
253
  // If we found a good match, pair them
252
254
  if (bestMatchIndex >= 0 && bestMatchScore > 0) {
253
255
  const postEvent = postToolEvents[bestMatchIndex];
@@ -256,26 +258,26 @@ class FileToolTracker {
256
258
  pair.success = postEvent.success;
257
259
  pair.exit_code = postEvent.exit_code;
258
260
  pair.result_summary = postEvent.result_summary;
259
-
261
+
260
262
  usedPostEvents.add(bestMatchIndex);
261
263
  console.log(`Paired pre_tool ${toolName} at ${preEvent.timestamp} with post_tool at ${postEvent.timestamp} (score: ${bestMatchScore})`);
262
264
  } else {
263
265
  console.log(`No matching post_tool found for ${toolName} at ${preEvent.timestamp} (still running or orphaned)`);
264
266
  }
265
-
267
+
266
268
  toolCallPairs.set(pairKey, pair);
267
269
  });
268
-
270
+
269
271
  // Third pass: handle any orphaned post_tool events (shouldn't happen but be safe)
270
272
  postToolEvents.forEach((postEvent, postIndex) => {
271
273
  if (usedPostEvents.has(postIndex)) return;
272
-
273
- console.log('Orphaned post_tool event found:', postEvent.tool_name, 'at', postEvent.timestamp);
274
-
275
- const toolName = postEvent.tool_name;
276
- const sessionId = postEvent.session_id || 'unknown';
274
+
275
+ const toolName = postEvent.tool_name || (postEvent.data && postEvent.data.tool_name);
276
+ console.log('Orphaned post_tool event found:', toolName, 'at', postEvent.timestamp);
277
+
278
+ const sessionId = postEvent.session_id || (postEvent.data && postEvent.data.session_id) || 'unknown';
277
279
  const postTimestamp = new Date(postEvent.timestamp).getTime();
278
-
280
+
279
281
  const pairKey = `orphaned_${sessionId}_${toolName}_${postIndex}_${postTimestamp}`;
280
282
  const pair = {
281
283
  pre_event: null,
@@ -291,17 +293,17 @@ class FileToolTracker {
291
293
  agent_type: null,
292
294
  agent_confidence: null
293
295
  };
294
-
296
+
295
297
  const agentInfo = this.extractAgentFromEvent(postEvent);
296
298
  pair.agent_type = agentInfo.name;
297
299
  pair.agent_confidence = agentInfo.confidence;
298
-
300
+
299
301
  toolCallPairs.set(pairKey, pair);
300
302
  });
301
-
303
+
302
304
  // Store the correlated tool calls
303
305
  this.toolCalls = toolCallPairs;
304
-
306
+
305
307
  console.log('updateToolCalls - final result:', this.toolCalls.size, 'tool calls');
306
308
  if (this.toolCalls.size > 0) {
307
309
  console.log('Tool calls map keys:', Array.from(this.toolCalls.keys()));
@@ -315,10 +317,13 @@ class FileToolTracker {
315
317
  */
316
318
  isToolOperation(event) {
317
319
  // Tool operations have tool_name and are hook events with pre_tool or post_tool subtype
318
- return event.tool_name &&
319
- event.type === 'hook' &&
320
- (event.subtype === 'pre_tool' || event.subtype === 'post_tool' ||
321
- event.subtype.includes('tool'));
320
+ // Check both top-level and data.tool_name for compatibility
321
+ const hasToolName = event.tool_name || (event.data && event.data.tool_name);
322
+ const isHookEvent = event.type === 'hook';
323
+ const isToolSubtype = event.subtype === 'pre_tool' || event.subtype === 'post_tool' ||
324
+ (event.subtype && event.subtype.includes('tool'));
325
+
326
+ return hasToolName && isHookEvent && isToolSubtype;
322
327
  }
323
328
 
324
329
  /**
@@ -328,19 +333,25 @@ class FileToolTracker {
328
333
  */
329
334
  isFileOperation(event) {
330
335
  // File operations are tool events with tools that operate on files
336
+ // Check both top-level and data for tool_name
337
+ let toolName = event.tool_name || (event.data && event.data.tool_name) || '';
338
+ toolName = toolName.toLowerCase();
339
+
331
340
  // Check case-insensitively since tool names can come in different cases
332
341
  const fileTools = ['read', 'write', 'edit', 'grep', 'multiedit', 'glob', 'ls', 'bash', 'notebookedit'];
333
- const toolName = event.tool_name ? event.tool_name.toLowerCase() : '';
334
342
 
343
+ // Get tool parameters from either location
344
+ const toolParams = event.tool_parameters || (event.data && event.data.tool_parameters);
345
+
335
346
  // Also check if Bash commands involve file operations
336
- if (toolName === 'bash' && event.tool_parameters) {
337
- const command = event.tool_parameters.command || '';
347
+ if (toolName === 'bash' && toolParams) {
348
+ const command = toolParams.command || '';
338
349
  // Check for common file operations in bash commands
339
350
  if (command.match(/\b(cat|less|more|head|tail|touch|mv|cp|rm|mkdir|ls|find)\b/)) {
340
351
  return true;
341
352
  }
342
353
  }
343
-
354
+
344
355
  return toolName && fileTools.includes(toolName);
345
356
  }
346
357
 
@@ -359,12 +370,12 @@ class FileToolTracker {
359
370
  if (event.data?.tool_parameters?.notebook_path) return event.data.tool_parameters.notebook_path;
360
371
  if (event.file_path) return event.file_path;
361
372
  if (event.path) return event.path;
362
-
373
+
363
374
  // For Glob tool, use the pattern as a pseudo-path
364
375
  if (event.tool_name?.toLowerCase() === 'glob' && event.tool_parameters?.pattern) {
365
376
  return `[glob] ${event.tool_parameters.pattern}`;
366
377
  }
367
-
378
+
368
379
  // For Bash commands, try to extract file paths from the command
369
380
  if (event.tool_name?.toLowerCase() === 'bash' && event.tool_parameters?.command) {
370
381
  const command = event.tool_parameters.command;
@@ -374,7 +385,7 @@ class FileToolTracker {
374
385
  return fileMatch[1];
375
386
  }
376
387
  }
377
-
388
+
378
389
  return null;
379
390
  }
380
391
 
@@ -386,15 +397,15 @@ class FileToolTracker {
386
397
  extractFilePathFromPair(pair) {
387
398
  // Try pre_event first, then post_event
388
399
  let filePath = null;
389
-
400
+
390
401
  if (pair.pre_event) {
391
402
  filePath = this.extractFilePath(pair.pre_event);
392
403
  }
393
-
404
+
394
405
  if (!filePath && pair.post_event) {
395
406
  filePath = this.extractFilePath(pair.post_event);
396
407
  }
397
-
408
+
398
409
  return filePath;
399
410
  }
400
411
 
@@ -405,7 +416,7 @@ class FileToolTracker {
405
416
  */
406
417
  getFileOperation(event) {
407
418
  if (!event.tool_name) return 'unknown';
408
-
419
+
409
420
  const toolName = event.tool_name.toLowerCase();
410
421
  switch (toolName) {
411
422
  case 'read': return 'read';
@@ -416,7 +427,7 @@ class FileToolTracker {
416
427
  case 'grep': return 'search';
417
428
  case 'glob': return 'search';
418
429
  case 'ls': return 'list';
419
- case 'bash':
430
+ case 'bash':
420
431
  // Check bash command for file operation type
421
432
  const command = event.tool_parameters?.command || '';
422
433
  if (command.match(/\b(cat|less|more|head|tail)\b/)) return 'read';
@@ -442,11 +453,11 @@ class FileToolTracker {
442
453
  if (pair.pre_event) {
443
454
  return this.getFileOperation(pair.pre_event);
444
455
  }
445
-
456
+
446
457
  if (pair.post_event) {
447
458
  return this.getFileOperation(pair.post_event);
448
459
  }
449
-
460
+
450
461
  return 'unknown';
451
462
  }
452
463
 
@@ -467,11 +478,11 @@ class FileToolTracker {
467
478
  };
468
479
  }
469
480
  }
470
-
481
+
471
482
  // Fallback to direct event properties
472
- const agentName = event?.agent_type || event?.subagent_type ||
483
+ const agentName = event?.agent_type || event?.subagent_type ||
473
484
  pair.pre_event?.agent_type || pair.post_event?.agent_type || 'PM';
474
-
485
+
475
486
  return {
476
487
  name: agentName,
477
488
  confidence: 'direct'
@@ -485,14 +496,14 @@ class FileToolTracker {
485
496
  */
486
497
  getFileOperationDetailsFromPair(pair) {
487
498
  const details = {};
488
-
499
+
489
500
  // Extract details from pre_event (parameters)
490
501
  if (pair.pre_event) {
491
502
  const params = pair.pre_event.tool_parameters || pair.pre_event.data?.tool_parameters || {};
492
503
  details.parameters = params;
493
504
  details.tool_input = pair.pre_event.tool_input;
494
505
  }
495
-
506
+
496
507
  // Extract details from post_event (results)
497
508
  if (pair.post_event) {
498
509
  details.result = pair.post_event.result;
@@ -501,7 +512,7 @@ class FileToolTracker {
501
512
  details.exit_code = pair.post_event.exit_code;
502
513
  details.duration_ms = pair.post_event.duration_ms;
503
514
  }
504
-
515
+
505
516
  return details;
506
517
  }
507
518
 
@@ -582,21 +593,21 @@ class FileToolTracker {
582
593
  // Extract parameters from both events
583
594
  const preParams = preEvent.tool_parameters || preEvent.data?.tool_parameters || {};
584
595
  const postParams = postEvent.tool_parameters || postEvent.data?.tool_parameters || {};
585
-
596
+
586
597
  // If no parameters in either event, can't compare meaningfully
587
598
  if (Object.keys(preParams).length === 0 && Object.keys(postParams).length === 0) {
588
599
  return false; // No boost for empty parameters
589
600
  }
590
-
601
+
591
602
  // Compare key parameters that are likely to be the same
592
603
  const importantParams = ['file_path', 'path', 'pattern', 'command', 'notebook_path'];
593
604
  let matchedParams = 0;
594
605
  let totalComparableParams = 0;
595
-
606
+
596
607
  importantParams.forEach(param => {
597
608
  const preValue = preParams[param];
598
609
  const postValue = postParams[param];
599
-
610
+
600
611
  if (preValue !== undefined || postValue !== undefined) {
601
612
  totalComparableParams++;
602
613
  if (preValue === postValue) {
@@ -604,26 +615,26 @@ class FileToolTracker {
604
615
  }
605
616
  }
606
617
  });
607
-
618
+
608
619
  // If we found comparable parameters, check if most match
609
620
  if (totalComparableParams > 0) {
610
621
  return (matchedParams / totalComparableParams) >= 0.8; // 80% parameter match threshold
611
622
  }
612
-
623
+
613
624
  // If no important parameters to compare, check if the parameter structure is similar
614
625
  const preKeys = Object.keys(preParams).sort();
615
626
  const postKeys = Object.keys(postParams).sort();
616
-
627
+
617
628
  if (preKeys.length === 0 && postKeys.length === 0) {
618
629
  return false;
619
630
  }
620
-
631
+
621
632
  // Simple structural similarity check
622
633
  if (preKeys.length === postKeys.length) {
623
634
  const keyMatches = preKeys.filter(key => postKeys.includes(key)).length;
624
635
  return keyMatches >= Math.max(1, preKeys.length * 0.5); // At least 50% key overlap
625
636
  }
626
-
637
+
627
638
  return false;
628
639
  }
629
640
 
@@ -642,14 +653,17 @@ class FileToolTracker {
642
653
  };
643
654
  }
644
655
  }
645
-
656
+
646
657
  // Fallback to direct event properties
647
- const agentName = event.agent_type || event.subagent_type ||
658
+ const agentName = event.agent_type || event.subagent_type ||
648
659
  event.data?.agent_type || event.data?.subagent_type || 'PM';
649
-
660
+
650
661
  return {
651
662
  name: agentName,
652
663
  confidence: 'direct'
653
664
  };
654
665
  }
655
- }
666
+ }
667
+ // ES6 Module export
668
+ export { FileToolTracker };
669
+ export default FileToolTracker;
@@ -8,7 +8,7 @@ class HUDLibraryLoader {
8
8
  this.loadedLibraries = new Set();
9
9
  this.loadingPromises = new Map();
10
10
  this.loadingCallbacks = new Map();
11
-
11
+
12
12
  // Define library configurations with proper loading order
13
13
  this.libraries = [
14
14
  {
@@ -55,7 +55,7 @@ class HUDLibraryLoader {
55
55
  const script = document.createElement('script');
56
56
  script.src = library.url;
57
57
  script.async = true;
58
-
58
+
59
59
  script.onload = () => {
60
60
  if (library.globalCheck()) {
61
61
  console.log(`Successfully loaded library: ${library.name}`);
@@ -69,14 +69,14 @@ class HUDLibraryLoader {
69
69
  reject(error);
70
70
  }
71
71
  };
72
-
72
+
73
73
  script.onerror = () => {
74
74
  const error = new Error(`Failed to load library: ${library.name} from ${library.url}`);
75
75
  console.error(error);
76
76
  this.loadingPromises.delete(library.name);
77
77
  reject(error);
78
78
  };
79
-
79
+
80
80
  document.head.appendChild(script);
81
81
  });
82
82
 
@@ -123,12 +123,12 @@ class HUDLibraryLoader {
123
123
  */
124
124
  async loadHUDLibraries(onProgress = null) {
125
125
  console.log('Starting HUD libraries loading...');
126
-
126
+
127
127
  try {
128
128
  // Load libraries in dependency order
129
129
  for (let i = 0; i < this.libraries.length; i++) {
130
130
  const library = this.libraries[i];
131
-
131
+
132
132
  if (onProgress) {
133
133
  onProgress({
134
134
  library: library.name,
@@ -137,7 +137,7 @@ class HUDLibraryLoader {
137
137
  message: `Loading ${library.name}...`
138
138
  });
139
139
  }
140
-
140
+
141
141
  await this.loadLibraryWithDependencies(library);
142
142
  }
143
143
 
@@ -148,7 +148,7 @@ class HUDLibraryLoader {
148
148
  }
149
149
 
150
150
  console.log('All HUD libraries loaded successfully');
151
-
151
+
152
152
  if (onProgress) {
153
153
  onProgress({
154
154
  library: 'complete',
@@ -161,7 +161,7 @@ class HUDLibraryLoader {
161
161
  return true;
162
162
  } catch (error) {
163
163
  console.error('Failed to load HUD libraries:', error);
164
-
164
+
165
165
  if (onProgress) {
166
166
  onProgress({
167
167
  library: 'error',
@@ -171,7 +171,7 @@ class HUDLibraryLoader {
171
171
  error: error
172
172
  });
173
173
  }
174
-
174
+
175
175
  throw error;
176
176
  }
177
177
  }
@@ -208,4 +208,4 @@ class HUDLibraryLoader {
208
208
  }
209
209
 
210
210
  // Create singleton instance
211
- window.HUDLibraryLoader = new HUDLibraryLoader();
211
+ window.HUDLibraryLoader = new HUDLibraryLoader();