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.
- claude_mpm/VERSION +1 -1
- claude_mpm/__init__.py +2 -2
- claude_mpm/__main__.py +3 -2
- claude_mpm/agents/__init__.py +85 -79
- claude_mpm/agents/agent_loader.py +464 -1003
- claude_mpm/agents/agent_loader_integration.py +45 -45
- claude_mpm/agents/agents_metadata.py +29 -30
- claude_mpm/agents/async_agent_loader.py +156 -138
- claude_mpm/agents/base_agent.json +1 -1
- claude_mpm/agents/base_agent_loader.py +179 -151
- claude_mpm/agents/frontmatter_validator.py +229 -130
- claude_mpm/agents/schema/agent_schema.json +1 -1
- claude_mpm/agents/system_agent_config.py +213 -147
- claude_mpm/agents/templates/__init__.py +13 -13
- claude_mpm/agents/templates/code_analyzer.json +2 -2
- claude_mpm/agents/templates/data_engineer.json +1 -1
- claude_mpm/agents/templates/documentation.json +23 -11
- claude_mpm/agents/templates/engineer.json +22 -6
- claude_mpm/agents/templates/memory_manager.json +155 -0
- claude_mpm/agents/templates/ops.json +2 -2
- claude_mpm/agents/templates/project_organizer.json +1 -1
- claude_mpm/agents/templates/qa.json +1 -1
- claude_mpm/agents/templates/refactoring_engineer.json +222 -0
- claude_mpm/agents/templates/research.json +20 -14
- claude_mpm/agents/templates/security.json +1 -1
- claude_mpm/agents/templates/ticketing.json +1 -1
- claude_mpm/agents/templates/version_control.json +1 -1
- claude_mpm/agents/templates/web_qa.json +3 -1
- claude_mpm/agents/templates/web_ui.json +2 -2
- claude_mpm/cli/__init__.py +90 -49
- claude_mpm/cli/__main__.py +3 -2
- claude_mpm/cli/commands/__init__.py +21 -18
- claude_mpm/cli/commands/agents.py +279 -247
- claude_mpm/cli/commands/aggregate.py +138 -157
- claude_mpm/cli/commands/cleanup.py +147 -147
- claude_mpm/cli/commands/config.py +93 -76
- claude_mpm/cli/commands/info.py +17 -16
- claude_mpm/cli/commands/mcp.py +143 -762
- claude_mpm/cli/commands/mcp_command_router.py +139 -0
- claude_mpm/cli/commands/mcp_config_commands.py +20 -0
- claude_mpm/cli/commands/mcp_install_commands.py +20 -0
- claude_mpm/cli/commands/mcp_server_commands.py +175 -0
- claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
- claude_mpm/cli/commands/memory.py +239 -203
- claude_mpm/cli/commands/monitor.py +203 -81
- claude_mpm/cli/commands/run.py +380 -429
- claude_mpm/cli/commands/run_config_checker.py +160 -0
- claude_mpm/cli/commands/socketio_monitor.py +235 -0
- claude_mpm/cli/commands/tickets.py +305 -197
- claude_mpm/cli/parser.py +24 -1150
- claude_mpm/cli/parsers/__init__.py +29 -0
- claude_mpm/cli/parsers/agents_parser.py +136 -0
- claude_mpm/cli/parsers/base_parser.py +331 -0
- claude_mpm/cli/parsers/config_parser.py +85 -0
- claude_mpm/cli/parsers/mcp_parser.py +152 -0
- claude_mpm/cli/parsers/memory_parser.py +138 -0
- claude_mpm/cli/parsers/monitor_parser.py +104 -0
- claude_mpm/cli/parsers/run_parser.py +147 -0
- claude_mpm/cli/parsers/tickets_parser.py +203 -0
- claude_mpm/cli/ticket_cli.py +7 -3
- claude_mpm/cli/utils.py +55 -37
- claude_mpm/cli_module/__init__.py +6 -6
- claude_mpm/cli_module/args.py +188 -140
- claude_mpm/cli_module/commands.py +79 -70
- claude_mpm/cli_module/migration_example.py +38 -60
- claude_mpm/config/__init__.py +32 -25
- claude_mpm/config/agent_config.py +151 -119
- claude_mpm/config/experimental_features.py +217 -0
- claude_mpm/config/paths.py +94 -208
- claude_mpm/config/socketio_config.py +84 -73
- claude_mpm/constants.py +36 -18
- claude_mpm/core/__init__.py +9 -6
- claude_mpm/core/agent_name_normalizer.py +68 -71
- claude_mpm/core/agent_registry.py +372 -521
- claude_mpm/core/agent_session_manager.py +74 -63
- claude_mpm/core/base_service.py +116 -87
- claude_mpm/core/cache.py +119 -153
- claude_mpm/core/claude_runner.py +425 -1120
- claude_mpm/core/config.py +263 -168
- claude_mpm/core/config_aliases.py +69 -61
- claude_mpm/core/config_constants.py +292 -0
- claude_mpm/core/constants.py +57 -99
- claude_mpm/core/container.py +211 -178
- claude_mpm/core/exceptions.py +233 -89
- claude_mpm/core/factories.py +92 -54
- claude_mpm/core/framework_loader.py +378 -220
- claude_mpm/core/hook_manager.py +198 -83
- claude_mpm/core/hook_performance_config.py +136 -0
- claude_mpm/core/injectable_service.py +61 -55
- claude_mpm/core/interactive_session.py +165 -155
- claude_mpm/core/interfaces.py +221 -195
- claude_mpm/core/lazy.py +96 -96
- claude_mpm/core/logger.py +133 -107
- claude_mpm/core/logging_config.py +185 -157
- claude_mpm/core/minimal_framework_loader.py +20 -15
- claude_mpm/core/mixins.py +30 -29
- claude_mpm/core/oneshot_session.py +215 -181
- claude_mpm/core/optimized_agent_loader.py +134 -138
- claude_mpm/core/optimized_startup.py +159 -157
- claude_mpm/core/pm_hook_interceptor.py +85 -72
- claude_mpm/core/service_registry.py +103 -101
- claude_mpm/core/session_manager.py +97 -87
- claude_mpm/core/socketio_pool.py +212 -158
- claude_mpm/core/tool_access_control.py +58 -51
- claude_mpm/core/types.py +46 -24
- claude_mpm/core/typing_utils.py +166 -82
- claude_mpm/core/unified_agent_registry.py +721 -0
- claude_mpm/core/unified_config.py +550 -0
- claude_mpm/core/unified_paths.py +549 -0
- claude_mpm/dashboard/index.html +1 -1
- claude_mpm/dashboard/open_dashboard.py +51 -17
- claude_mpm/dashboard/static/css/dashboard.css +27 -8
- claude_mpm/dashboard/static/dist/components/agent-inference.js +2 -0
- claude_mpm/dashboard/static/dist/components/event-processor.js +2 -0
- claude_mpm/dashboard/static/dist/components/event-viewer.js +2 -0
- claude_mpm/dashboard/static/dist/components/export-manager.js +2 -0
- claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +2 -0
- claude_mpm/dashboard/static/dist/components/hud-library-loader.js +2 -0
- claude_mpm/dashboard/static/dist/components/hud-manager.js +2 -0
- claude_mpm/dashboard/static/dist/components/hud-visualizer.js +2 -0
- claude_mpm/dashboard/static/dist/components/module-viewer.js +2 -0
- claude_mpm/dashboard/static/dist/components/session-manager.js +2 -0
- claude_mpm/dashboard/static/dist/components/socket-manager.js +2 -0
- claude_mpm/dashboard/static/dist/components/ui-state-manager.js +2 -0
- claude_mpm/dashboard/static/dist/components/working-directory.js +2 -0
- claude_mpm/dashboard/static/dist/dashboard.js +2 -0
- claude_mpm/dashboard/static/dist/socket-client.js +2 -0
- claude_mpm/dashboard/static/js/components/agent-inference.js +80 -76
- claude_mpm/dashboard/static/js/components/event-processor.js +71 -67
- claude_mpm/dashboard/static/js/components/event-viewer.js +74 -70
- claude_mpm/dashboard/static/js/components/export-manager.js +31 -28
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +106 -92
- claude_mpm/dashboard/static/js/components/hud-library-loader.js +11 -11
- claude_mpm/dashboard/static/js/components/hud-manager.js +73 -73
- claude_mpm/dashboard/static/js/components/hud-visualizer.js +163 -163
- claude_mpm/dashboard/static/js/components/module-viewer.js +305 -233
- claude_mpm/dashboard/static/js/components/session-manager.js +32 -29
- claude_mpm/dashboard/static/js/components/socket-manager.js +27 -20
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +21 -18
- claude_mpm/dashboard/static/js/components/working-directory.js +74 -71
- claude_mpm/dashboard/static/js/dashboard.js +178 -453
- claude_mpm/dashboard/static/js/extension-error-handler.js +164 -0
- claude_mpm/dashboard/static/js/socket-client.js +120 -54
- claude_mpm/dashboard/templates/index.html +40 -50
- claude_mpm/experimental/cli_enhancements.py +60 -58
- claude_mpm/generators/__init__.py +1 -1
- claude_mpm/generators/agent_profile_generator.py +75 -65
- claude_mpm/hooks/__init__.py +1 -1
- claude_mpm/hooks/base_hook.py +33 -28
- claude_mpm/hooks/claude_hooks/__init__.py +1 -1
- claude_mpm/hooks/claude_hooks/connection_pool.py +120 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +743 -0
- claude_mpm/hooks/claude_hooks/hook_handler.py +415 -1331
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +4 -4
- claude_mpm/hooks/claude_hooks/memory_integration.py +221 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +348 -0
- claude_mpm/hooks/claude_hooks/tool_analysis.py +230 -0
- claude_mpm/hooks/memory_integration_hook.py +140 -100
- claude_mpm/hooks/tool_call_interceptor.py +89 -76
- claude_mpm/hooks/validation_hooks.py +57 -49
- claude_mpm/init.py +145 -121
- claude_mpm/models/__init__.py +9 -9
- claude_mpm/models/agent_definition.py +33 -23
- claude_mpm/models/agent_session.py +228 -200
- claude_mpm/scripts/__init__.py +1 -1
- claude_mpm/scripts/socketio_daemon.py +192 -75
- claude_mpm/scripts/socketio_server_manager.py +328 -0
- claude_mpm/scripts/start_activity_logging.py +25 -22
- claude_mpm/services/__init__.py +68 -43
- claude_mpm/services/agent_capabilities_service.py +271 -0
- claude_mpm/services/agents/__init__.py +23 -32
- claude_mpm/services/agents/deployment/__init__.py +3 -3
- claude_mpm/services/agents/deployment/agent_config_provider.py +310 -0
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +359 -0
- claude_mpm/services/agents/deployment/agent_definition_factory.py +84 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +415 -2113
- claude_mpm/services/agents/deployment/agent_discovery_service.py +387 -0
- claude_mpm/services/agents/deployment/agent_environment_manager.py +293 -0
- claude_mpm/services/agents/deployment/agent_filesystem_manager.py +387 -0
- claude_mpm/services/agents/deployment/agent_format_converter.py +453 -0
- claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +161 -0
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +345 -495
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +279 -0
- claude_mpm/services/agents/deployment/agent_restore_handler.py +88 -0
- claude_mpm/services/agents/deployment/agent_template_builder.py +406 -0
- claude_mpm/services/agents/deployment/agent_validator.py +352 -0
- claude_mpm/services/agents/deployment/agent_version_manager.py +313 -0
- claude_mpm/services/agents/deployment/agent_versioning.py +6 -9
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +79 -0
- claude_mpm/services/agents/deployment/async_agent_deployment.py +298 -234
- claude_mpm/services/agents/deployment/config/__init__.py +13 -0
- claude_mpm/services/agents/deployment/config/deployment_config.py +182 -0
- claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
- claude_mpm/services/agents/deployment/deployment_config_loader.py +54 -0
- claude_mpm/services/agents/deployment/deployment_type_detector.py +124 -0
- claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
- claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
- claude_mpm/services/agents/deployment/facade/deployment_executor.py +73 -0
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +270 -0
- claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
- claude_mpm/services/agents/deployment/interface_adapter.py +227 -0
- claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
- claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
- claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +159 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
- claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +195 -0
- claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +119 -0
- claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +79 -0
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +90 -0
- claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +100 -0
- claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
- claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +98 -0
- claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
- claude_mpm/services/agents/deployment/processors/agent_processor.py +258 -0
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +318 -0
- claude_mpm/services/agents/deployment/results/__init__.py +13 -0
- claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
- claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
- claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
- claude_mpm/services/agents/deployment/strategies/base_strategy.py +119 -0
- claude_mpm/services/agents/deployment/strategies/project_strategy.py +150 -0
- claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
- claude_mpm/services/agents/deployment/strategies/system_strategy.py +116 -0
- claude_mpm/services/agents/deployment/strategies/user_strategy.py +137 -0
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +108 -0
- claude_mpm/services/agents/deployment/validation/__init__.py +19 -0
- claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
- claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
- claude_mpm/services/agents/deployment/validation/template_validator.py +299 -0
- claude_mpm/services/agents/deployment/validation/validation_result.py +226 -0
- claude_mpm/services/agents/loading/__init__.py +2 -2
- claude_mpm/services/agents/loading/agent_profile_loader.py +259 -229
- claude_mpm/services/agents/loading/base_agent_manager.py +90 -81
- claude_mpm/services/agents/loading/framework_agent_loader.py +154 -129
- claude_mpm/services/agents/management/__init__.py +2 -2
- claude_mpm/services/agents/management/agent_capabilities_generator.py +72 -58
- claude_mpm/services/agents/management/agent_management_service.py +209 -156
- claude_mpm/services/agents/memory/__init__.py +9 -6
- claude_mpm/services/agents/memory/agent_memory_manager.py +218 -1152
- claude_mpm/services/agents/memory/agent_persistence_service.py +20 -16
- claude_mpm/services/agents/memory/analyzer.py +430 -0
- claude_mpm/services/agents/memory/content_manager.py +376 -0
- claude_mpm/services/agents/memory/template_generator.py +468 -0
- claude_mpm/services/agents/registry/__init__.py +7 -10
- claude_mpm/services/agents/registry/deployed_agent_discovery.py +122 -97
- claude_mpm/services/agents/registry/modification_tracker.py +351 -285
- claude_mpm/services/async_session_logger.py +187 -153
- claude_mpm/services/claude_session_logger.py +87 -72
- claude_mpm/services/command_handler_service.py +217 -0
- claude_mpm/services/communication/__init__.py +3 -2
- claude_mpm/services/core/__init__.py +50 -97
- claude_mpm/services/core/base.py +60 -53
- claude_mpm/services/core/interfaces/__init__.py +188 -0
- claude_mpm/services/core/interfaces/agent.py +351 -0
- claude_mpm/services/core/interfaces/communication.py +343 -0
- claude_mpm/services/core/interfaces/infrastructure.py +413 -0
- claude_mpm/services/core/interfaces/service.py +434 -0
- claude_mpm/services/core/interfaces.py +19 -944
- claude_mpm/services/event_aggregator.py +208 -170
- claude_mpm/services/exceptions.py +387 -308
- claude_mpm/services/framework_claude_md_generator/__init__.py +75 -79
- claude_mpm/services/framework_claude_md_generator/content_assembler.py +69 -60
- claude_mpm/services/framework_claude_md_generator/content_validator.py +65 -61
- claude_mpm/services/framework_claude_md_generator/deployment_manager.py +68 -49
- claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +34 -34
- claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +25 -22
- claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +10 -10
- claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
- claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
- claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +5 -4
- claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
- claude_mpm/services/framework_claude_md_generator/version_manager.py +30 -28
- claude_mpm/services/hook_service.py +106 -114
- claude_mpm/services/infrastructure/__init__.py +7 -5
- claude_mpm/services/infrastructure/context_preservation.py +571 -0
- claude_mpm/services/infrastructure/daemon_manager.py +279 -0
- claude_mpm/services/infrastructure/logging.py +83 -76
- claude_mpm/services/infrastructure/monitoring.py +547 -404
- claude_mpm/services/mcp_gateway/__init__.py +40 -23
- claude_mpm/services/mcp_gateway/config/__init__.py +2 -2
- claude_mpm/services/mcp_gateway/config/config_loader.py +61 -56
- claude_mpm/services/mcp_gateway/config/config_schema.py +50 -41
- claude_mpm/services/mcp_gateway/config/configuration.py +82 -75
- claude_mpm/services/mcp_gateway/core/__init__.py +14 -21
- claude_mpm/services/mcp_gateway/core/base.py +80 -67
- claude_mpm/services/mcp_gateway/core/exceptions.py +60 -46
- claude_mpm/services/mcp_gateway/core/interfaces.py +97 -93
- claude_mpm/services/mcp_gateway/main.py +307 -127
- claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
- claude_mpm/services/mcp_gateway/registry/service_registry.py +100 -101
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
- claude_mpm/services/mcp_gateway/server/__init__.py +4 -4
- claude_mpm/services/mcp_gateway/server/{mcp_server.py → mcp_gateway.py} +149 -153
- claude_mpm/services/mcp_gateway/server/stdio_handler.py +105 -107
- claude_mpm/services/mcp_gateway/server/stdio_server.py +691 -0
- claude_mpm/services/mcp_gateway/tools/__init__.py +4 -2
- claude_mpm/services/mcp_gateway/tools/base_adapter.py +110 -121
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +283 -215
- claude_mpm/services/mcp_gateway/tools/hello_world.py +122 -120
- claude_mpm/services/mcp_gateway/tools/ticket_tools.py +652 -0
- claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +606 -0
- claude_mpm/services/memory/__init__.py +2 -2
- claude_mpm/services/memory/builder.py +451 -362
- claude_mpm/services/memory/cache/__init__.py +2 -2
- claude_mpm/services/memory/cache/shared_prompt_cache.py +232 -194
- claude_mpm/services/memory/cache/simple_cache.py +107 -93
- claude_mpm/services/memory/indexed_memory.py +195 -193
- claude_mpm/services/memory/optimizer.py +267 -234
- claude_mpm/services/memory/router.py +571 -263
- claude_mpm/services/memory_hook_service.py +237 -0
- claude_mpm/services/port_manager.py +223 -0
- claude_mpm/services/project/__init__.py +3 -3
- claude_mpm/services/project/analyzer.py +451 -305
- claude_mpm/services/project/registry.py +262 -240
- claude_mpm/services/recovery_manager.py +287 -231
- claude_mpm/services/response_tracker.py +87 -67
- claude_mpm/services/runner_configuration_service.py +587 -0
- claude_mpm/services/session_management_service.py +304 -0
- claude_mpm/services/socketio/__init__.py +4 -4
- claude_mpm/services/socketio/client_proxy.py +174 -0
- claude_mpm/services/socketio/handlers/__init__.py +3 -3
- claude_mpm/services/socketio/handlers/base.py +44 -30
- claude_mpm/services/socketio/handlers/connection.py +145 -65
- claude_mpm/services/socketio/handlers/file.py +123 -108
- claude_mpm/services/socketio/handlers/git.py +607 -373
- claude_mpm/services/socketio/handlers/hook.py +170 -0
- claude_mpm/services/socketio/handlers/memory.py +4 -4
- claude_mpm/services/socketio/handlers/project.py +4 -4
- claude_mpm/services/socketio/handlers/registry.py +53 -38
- claude_mpm/services/socketio/server/__init__.py +18 -0
- claude_mpm/services/socketio/server/broadcaster.py +252 -0
- claude_mpm/services/socketio/server/core.py +399 -0
- claude_mpm/services/socketio/server/main.py +323 -0
- claude_mpm/services/socketio_client_manager.py +160 -133
- claude_mpm/services/socketio_server.py +36 -1885
- claude_mpm/services/subprocess_launcher_service.py +316 -0
- claude_mpm/services/system_instructions_service.py +258 -0
- claude_mpm/services/ticket_manager.py +20 -534
- claude_mpm/services/utility_service.py +285 -0
- claude_mpm/services/version_control/__init__.py +18 -21
- claude_mpm/services/version_control/branch_strategy.py +20 -10
- claude_mpm/services/version_control/conflict_resolution.py +37 -13
- claude_mpm/services/version_control/git_operations.py +52 -21
- claude_mpm/services/version_control/semantic_versioning.py +92 -53
- claude_mpm/services/version_control/version_parser.py +145 -125
- claude_mpm/services/version_service.py +270 -0
- claude_mpm/storage/__init__.py +9 -0
- claude_mpm/storage/state_storage.py +552 -0
- claude_mpm/ticket_wrapper.py +2 -2
- claude_mpm/utils/__init__.py +2 -2
- claude_mpm/utils/agent_dependency_loader.py +453 -243
- claude_mpm/utils/config_manager.py +157 -118
- claude_mpm/utils/console.py +1 -1
- claude_mpm/utils/dependency_cache.py +102 -107
- claude_mpm/utils/dependency_manager.py +52 -47
- claude_mpm/utils/dependency_strategies.py +131 -96
- claude_mpm/utils/environment_context.py +110 -102
- claude_mpm/utils/error_handler.py +75 -55
- claude_mpm/utils/file_utils.py +80 -67
- claude_mpm/utils/framework_detection.py +12 -11
- claude_mpm/utils/import_migration_example.py +12 -60
- claude_mpm/utils/imports.py +48 -45
- claude_mpm/utils/path_operations.py +100 -93
- claude_mpm/utils/robust_installer.py +172 -164
- claude_mpm/utils/session_logging.py +30 -23
- claude_mpm/utils/subprocess_utils.py +99 -61
- claude_mpm/validation/__init__.py +1 -1
- claude_mpm/validation/agent_validator.py +151 -111
- claude_mpm/validation/frontmatter_validator.py +92 -71
- {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/METADATA +51 -2
- claude_mpm-4.0.3.dist-info/RECORD +402 -0
- {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/entry_points.txt +1 -0
- {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/licenses/LICENSE +1 -1
- claude_mpm/config/memory_guardian_config.py +0 -325
- claude_mpm/core/config_paths.py +0 -150
- claude_mpm/dashboard/static/js/dashboard-original.js +0 -4134
- claude_mpm/deployment_paths.py +0 -261
- claude_mpm/hooks/claude_hooks/hook_handler_fixed.py +0 -454
- claude_mpm/models/state_models.py +0 -433
- claude_mpm/services/agent/__init__.py +0 -24
- claude_mpm/services/agent/deployment.py +0 -2548
- claude_mpm/services/agent/management.py +0 -598
- claude_mpm/services/agent/registry.py +0 -813
- claude_mpm/services/agents/registry/agent_registry.py +0 -813
- claude_mpm/services/communication/socketio.py +0 -1935
- claude_mpm/services/communication/websocket.py +0 -479
- claude_mpm/services/framework_claude_md_generator.py +0 -624
- claude_mpm/services/health_monitor.py +0 -893
- claude_mpm/services/infrastructure/memory_guardian.py +0 -770
- claude_mpm/services/mcp_gateway/server/mcp_server_simple.py +0 -444
- claude_mpm/services/optimized_hook_service.py +0 -542
- claude_mpm/services/project_analyzer.py +0 -864
- claude_mpm/services/project_registry.py +0 -608
- claude_mpm/services/standalone_socketio_server.py +0 -1300
- claude_mpm/services/ticket_manager_di.py +0 -318
- claude_mpm/services/ticketing_service_original.py +0 -510
- claude_mpm/utils/paths.py +0 -395
- claude_mpm/utils/platform_memory.py +0 -524
- claude_mpm-3.9.9.dist-info/RECORD +0 -293
- {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/WHEEL +0 -0
- {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/top_level.txt +0 -0
| @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            /**
         | 
| 2 2 | 
             
             * Event Processor Module
         | 
| 3 | 
            -
             * | 
| 3 | 
            +
             *
         | 
| 4 4 | 
             
             * Handles event processing, filtering, and rendering for different tabs in the dashboard.
         | 
| 5 5 | 
             
             * Provides centralized event filtering and rendering logic for agents, tools, and files tabs.
         | 
| 6 | 
            -
             * | 
| 6 | 
            +
             *
         | 
| 7 7 | 
             
             * WHY: Extracted from main dashboard to isolate complex event processing logic
         | 
| 8 8 | 
             
             * that involves filtering, transforming, and rendering events across different views.
         | 
| 9 9 | 
             
             * This improves maintainability and makes the event processing logic testable.
         | 
| 10 | 
            -
             * | 
| 10 | 
            +
             *
         | 
| 11 11 | 
             
             * DESIGN DECISION: Maintains its own filtered event collections while relying on
         | 
| 12 12 | 
             
             * eventViewer for source data. Provides separate filtering logic for each tab type
         | 
| 13 13 | 
             
             * while sharing common filtering patterns and utilities.
         | 
| @@ -16,20 +16,20 @@ class EventProcessor { | |
| 16 16 | 
             
                constructor(eventViewer, agentInference) {
         | 
| 17 17 | 
             
                    this.eventViewer = eventViewer;
         | 
| 18 18 | 
             
                    this.agentInference = agentInference;
         | 
| 19 | 
            -
             | 
| 19 | 
            +
             | 
| 20 20 | 
             
                    // Processed event collections for different tabs
         | 
| 21 21 | 
             
                    this.agentEvents = [];
         | 
| 22 22 | 
             
                    this.filteredAgentEvents = [];
         | 
| 23 23 | 
             
                    this.filteredToolEvents = [];
         | 
| 24 24 | 
             
                    this.filteredFileEvents = [];
         | 
| 25 | 
            -
             | 
| 25 | 
            +
             | 
| 26 26 | 
             
                    // Session filtering
         | 
| 27 27 | 
             
                    this.selectedSessionId = null;
         | 
| 28 | 
            -
             | 
| 28 | 
            +
             | 
| 29 29 | 
             
                    // Git tracking status cache
         | 
| 30 30 | 
             
                    this.fileTrackingCache = new Map(); // file_path -> {is_tracked: boolean, timestamp: number}
         | 
| 31 31 | 
             
                    this.trackingCheckTimeout = 30000; // Cache for 30 seconds
         | 
| 32 | 
            -
             | 
| 32 | 
            +
             | 
| 33 33 | 
             
                    console.log('Event processor initialized');
         | 
| 34 34 | 
             
                }
         | 
| 35 35 |  | 
| @@ -61,10 +61,10 @@ class EventProcessor { | |
| 61 61 | 
             
                applyAgentsFilters(uniqueInstances) {
         | 
| 62 62 | 
             
                    const searchInput = document.getElementById('agents-search-input');
         | 
| 63 63 | 
             
                    const typeFilter = document.getElementById('agents-type-filter');
         | 
| 64 | 
            -
             | 
| 64 | 
            +
             | 
| 65 65 | 
             
                    const searchText = searchInput ? searchInput.value.toLowerCase() : '';
         | 
| 66 66 | 
             
                    const typeValue = typeFilter ? typeFilter.value : '';
         | 
| 67 | 
            -
             | 
| 67 | 
            +
             | 
| 68 68 | 
             
                    return uniqueInstances.filter(instance => {
         | 
| 69 69 | 
             
                        // Search filter
         | 
| 70 70 | 
             
                        if (searchText) {
         | 
| @@ -73,12 +73,12 @@ class EventProcessor { | |
| 73 73 | 
             
                                instance.type || '',
         | 
| 74 74 | 
             
                                instance.isImplied ? 'implied' : 'explicit'
         | 
| 75 75 | 
             
                            ].join(' ').toLowerCase();
         | 
| 76 | 
            -
             | 
| 76 | 
            +
             | 
| 77 77 | 
             
                            if (!searchableText.includes(searchText)) {
         | 
| 78 78 | 
             
                                return false;
         | 
| 79 79 | 
             
                            }
         | 
| 80 80 | 
             
                        }
         | 
| 81 | 
            -
             | 
| 81 | 
            +
             | 
| 82 82 | 
             
                        // Type filter
         | 
| 83 83 | 
             
                        if (typeValue) {
         | 
| 84 84 | 
             
                            const agentName = instance.agentName || 'unknown';
         | 
| @@ -86,7 +86,7 @@ class EventProcessor { | |
| 86 86 | 
             
                                return false;
         | 
| 87 87 | 
             
                            }
         | 
| 88 88 | 
             
                        }
         | 
| 89 | 
            -
             | 
| 89 | 
            +
             | 
| 90 90 | 
             
                        return true;
         | 
| 91 91 | 
             
                    });
         | 
| 92 92 | 
             
                }
         | 
| @@ -99,10 +99,10 @@ class EventProcessor { | |
| 99 99 | 
             
                applyToolsFilters(events) {
         | 
| 100 100 | 
             
                    const searchInput = document.getElementById('tools-search-input');
         | 
| 101 101 | 
             
                    const typeFilter = document.getElementById('tools-type-filter');
         | 
| 102 | 
            -
             | 
| 102 | 
            +
             | 
| 103 103 | 
             
                    const searchText = searchInput ? searchInput.value.toLowerCase() : '';
         | 
| 104 104 | 
             
                    const typeValue = typeFilter ? typeFilter.value : '';
         | 
| 105 | 
            -
             | 
| 105 | 
            +
             | 
| 106 106 | 
             
                    return events.filter(event => {
         | 
| 107 107 | 
             
                        // Search filter
         | 
| 108 108 | 
             
                        if (searchText) {
         | 
| @@ -112,12 +112,12 @@ class EventProcessor { | |
| 112 112 | 
             
                                event.type || '',
         | 
| 113 113 | 
             
                                event.subtype || ''
         | 
| 114 114 | 
             
                            ].join(' ').toLowerCase();
         | 
| 115 | 
            -
             | 
| 115 | 
            +
             | 
| 116 116 | 
             
                            if (!searchableText.includes(searchText)) {
         | 
| 117 117 | 
             
                                return false;
         | 
| 118 118 | 
             
                            }
         | 
| 119 119 | 
             
                        }
         | 
| 120 | 
            -
             | 
| 120 | 
            +
             | 
| 121 121 | 
             
                        // Type filter
         | 
| 122 122 | 
             
                        if (typeValue) {
         | 
| 123 123 | 
             
                            const toolName = event.tool_name || '';
         | 
| @@ -125,7 +125,7 @@ class EventProcessor { | |
| 125 125 | 
             
                                return false;
         | 
| 126 126 | 
             
                            }
         | 
| 127 127 | 
             
                        }
         | 
| 128 | 
            -
             | 
| 128 | 
            +
             | 
| 129 129 | 
             
                        return true;
         | 
| 130 130 | 
             
                    });
         | 
| 131 131 | 
             
                }
         | 
| @@ -138,10 +138,10 @@ class EventProcessor { | |
| 138 138 | 
             
                applyToolCallFilters(toolCallsArray) {
         | 
| 139 139 | 
             
                    const searchInput = document.getElementById('tools-search-input');
         | 
| 140 140 | 
             
                    const typeFilter = document.getElementById('tools-type-filter');
         | 
| 141 | 
            -
             | 
| 141 | 
            +
             | 
| 142 142 | 
             
                    const searchText = searchInput ? searchInput.value.toLowerCase() : '';
         | 
| 143 143 | 
             
                    const typeValue = typeFilter ? typeFilter.value : '';
         | 
| 144 | 
            -
             | 
| 144 | 
            +
             | 
| 145 145 | 
             
                    return toolCallsArray.filter(([key, toolCall]) => {
         | 
| 146 146 | 
             
                        // Search filter
         | 
| 147 147 | 
             
                        if (searchText) {
         | 
| @@ -150,12 +150,12 @@ class EventProcessor { | |
| 150 150 | 
             
                                toolCall.agent_type || '',
         | 
| 151 151 | 
             
                                'tool_call'
         | 
| 152 152 | 
             
                            ].join(' ').toLowerCase();
         | 
| 153 | 
            -
             | 
| 153 | 
            +
             | 
| 154 154 | 
             
                            if (!searchableText.includes(searchText)) {
         | 
| 155 155 | 
             
                                return false;
         | 
| 156 156 | 
             
                            }
         | 
| 157 157 | 
             
                        }
         | 
| 158 | 
            -
             | 
| 158 | 
            +
             | 
| 159 159 | 
             
                        // Type filter
         | 
| 160 160 | 
             
                        if (typeValue) {
         | 
| 161 161 | 
             
                            const toolName = toolCall.tool_name || '';
         | 
| @@ -163,7 +163,7 @@ class EventProcessor { | |
| 163 163 | 
             
                                return false;
         | 
| 164 164 | 
             
                            }
         | 
| 165 165 | 
             
                        }
         | 
| 166 | 
            -
             | 
| 166 | 
            +
             | 
| 167 167 | 
             
                        return true;
         | 
| 168 168 | 
             
                    });
         | 
| 169 169 | 
             
                }
         | 
| @@ -176,23 +176,23 @@ class EventProcessor { | |
| 176 176 | 
             
                applyFilesFilters(fileOperations) {
         | 
| 177 177 | 
             
                    const searchInput = document.getElementById('files-search-input');
         | 
| 178 178 | 
             
                    const typeFilter = document.getElementById('files-type-filter');
         | 
| 179 | 
            -
             | 
| 179 | 
            +
             | 
| 180 180 | 
             
                    const searchText = searchInput ? searchInput.value.toLowerCase() : '';
         | 
| 181 181 | 
             
                    const typeValue = typeFilter ? typeFilter.value : '';
         | 
| 182 | 
            -
             | 
| 182 | 
            +
             | 
| 183 183 | 
             
                    return fileOperations.filter(([filePath, fileData]) => {
         | 
| 184 184 | 
             
                        // Session filter - filter operations within each file
         | 
| 185 185 | 
             
                        if (this.selectedSessionId) {
         | 
| 186 186 | 
             
                            // Filter operations for this file by session
         | 
| 187 | 
            -
                            const sessionOperations = fileData.operations.filter(op => | 
| 187 | 
            +
                            const sessionOperations = fileData.operations.filter(op =>
         | 
| 188 188 | 
             
                                op.sessionId === this.selectedSessionId
         | 
| 189 189 | 
             
                            );
         | 
| 190 | 
            -
             | 
| 190 | 
            +
             | 
| 191 191 | 
             
                            // If no operations from this session, exclude the file
         | 
| 192 192 | 
             
                            if (sessionOperations.length === 0) {
         | 
| 193 193 | 
             
                                return false;
         | 
| 194 194 | 
             
                            }
         | 
| 195 | 
            -
             | 
| 195 | 
            +
             | 
| 196 196 | 
             
                            // Update the fileData to only include session-specific operations
         | 
| 197 197 | 
             
                            // (Note: This creates a filtered view without modifying the original)
         | 
| 198 198 | 
             
                            fileData = {
         | 
| @@ -201,7 +201,7 @@ class EventProcessor { | |
| 201 201 | 
             
                                lastOperation: sessionOperations[sessionOperations.length - 1]?.timestamp || fileData.lastOperation
         | 
| 202 202 | 
             
                            };
         | 
| 203 203 | 
             
                        }
         | 
| 204 | 
            -
             | 
| 204 | 
            +
             | 
| 205 205 | 
             
                        // Search filter
         | 
| 206 206 | 
             
                        if (searchText) {
         | 
| 207 207 | 
             
                            const searchableText = [
         | 
| @@ -209,12 +209,12 @@ class EventProcessor { | |
| 209 209 | 
             
                                ...fileData.operations.map(op => op.operation),
         | 
| 210 210 | 
             
                                ...fileData.operations.map(op => op.agent)
         | 
| 211 211 | 
             
                            ].join(' ').toLowerCase();
         | 
| 212 | 
            -
             | 
| 212 | 
            +
             | 
| 213 213 | 
             
                            if (!searchableText.includes(searchText)) {
         | 
| 214 214 | 
             
                                return false;
         | 
| 215 215 | 
             
                            }
         | 
| 216 216 | 
             
                        }
         | 
| 217 | 
            -
             | 
| 217 | 
            +
             | 
| 218 218 | 
             
                        // Type filter
         | 
| 219 219 | 
             
                        if (typeValue) {
         | 
| 220 220 | 
             
                            const operations = fileData.operations.map(op => op.operation);
         | 
| @@ -222,7 +222,7 @@ class EventProcessor { | |
| 222 222 | 
             
                                return false;
         | 
| 223 223 | 
             
                            }
         | 
| 224 224 | 
             
                        }
         | 
| 225 | 
            -
             | 
| 225 | 
            +
             | 
| 226 226 | 
             
                        return true;
         | 
| 227 227 | 
             
                    });
         | 
| 228 228 | 
             
                }
         | 
| @@ -234,7 +234,7 @@ class EventProcessor { | |
| 234 234 | 
             
                 */
         | 
| 235 235 | 
             
                extractOperation(eventType) {
         | 
| 236 236 | 
             
                    if (!eventType) return 'unknown';
         | 
| 237 | 
            -
             | 
| 237 | 
            +
             | 
| 238 238 | 
             
                    const type = eventType.toLowerCase();
         | 
| 239 239 | 
             
                    if (type.includes('read')) return 'read';
         | 
| 240 240 | 
             
                    if (type.includes('write')) return 'write';
         | 
| @@ -242,7 +242,7 @@ class EventProcessor { | |
| 242 242 | 
             
                    if (type.includes('create')) return 'create';
         | 
| 243 243 | 
             
                    if (type.includes('delete')) return 'delete';
         | 
| 244 244 | 
             
                    if (type.includes('move') || type.includes('rename')) return 'move';
         | 
| 245 | 
            -
             | 
| 245 | 
            +
             | 
| 246 246 | 
             
                    return 'other';
         | 
| 247 247 | 
             
                }
         | 
| 248 248 |  | 
| @@ -253,7 +253,7 @@ class EventProcessor { | |
| 253 253 | 
             
                 */
         | 
| 254 254 | 
             
                extractToolFromHook(eventType) {
         | 
| 255 255 | 
             
                    if (!eventType) return '';
         | 
| 256 | 
            -
             | 
| 256 | 
            +
             | 
| 257 257 | 
             
                    // Pattern: Pre{ToolName}Use or Post{ToolName}Use
         | 
| 258 258 | 
             
                    const match = eventType.match(/^(?:Pre|Post)(.+)Use$/);
         | 
| 259 259 | 
             
                    return match ? match[1] : '';
         | 
| @@ -266,13 +266,13 @@ class EventProcessor { | |
| 266 266 | 
             
                 */
         | 
| 267 267 | 
             
                extractToolFromSubtype(subtype) {
         | 
| 268 268 | 
             
                    if (!subtype) return '';
         | 
| 269 | 
            -
             | 
| 269 | 
            +
             | 
| 270 270 | 
             
                    // Handle various subtype patterns
         | 
| 271 271 | 
             
                    if (subtype.includes('_')) {
         | 
| 272 272 | 
             
                        const parts = subtype.split('_');
         | 
| 273 273 | 
             
                        return parts[0] || '';
         | 
| 274 274 | 
             
                    }
         | 
| 275 | 
            -
             | 
| 275 | 
            +
             | 
| 276 276 | 
             
                    return subtype;
         | 
| 277 277 | 
             
                }
         | 
| 278 278 |  | 
| @@ -285,7 +285,7 @@ class EventProcessor { | |
| 285 285 | 
             
                 */
         | 
| 286 286 | 
             
                extractToolTarget(toolName, params, toolParameters) {
         | 
| 287 287 | 
             
                    const parameters = params || toolParameters || {};
         | 
| 288 | 
            -
             | 
| 288 | 
            +
             | 
| 289 289 | 
             
                    switch (toolName?.toLowerCase()) {
         | 
| 290 290 | 
             
                        case 'read':
         | 
| 291 291 | 
             
                        case 'write':
         | 
| @@ -318,17 +318,17 @@ class EventProcessor { | |
| 318 318 | 
             
                generateAgentHTML(events) {
         | 
| 319 319 | 
             
                    // Get unique agent instances from agent inference
         | 
| 320 320 | 
             
                    const uniqueInstances = this.agentInference.getUniqueAgentInstances();
         | 
| 321 | 
            -
             | 
| 321 | 
            +
             | 
| 322 322 | 
             
                    // Apply filtering
         | 
| 323 323 | 
             
                    const filteredInstances = this.applyAgentsFilters(uniqueInstances);
         | 
| 324 | 
            -
             | 
| 324 | 
            +
             | 
| 325 325 | 
             
                    return filteredInstances.map((instance, index) => {
         | 
| 326 326 | 
             
                        const agentName = instance.agentName;
         | 
| 327 327 | 
             
                        const timestamp = this.formatTimestamp(instance.firstTimestamp || instance.timestamp);
         | 
| 328 328 | 
             
                        const delegationType = instance.isImplied ? 'implied' : 'explicit';
         | 
| 329 329 | 
             
                        // Fix: Use totalEventCount which is the actual property name from getUniqueAgentInstances()
         | 
| 330 330 | 
             
                        const eventCount = instance.totalEventCount || instance.eventCount || 0;
         | 
| 331 | 
            -
             | 
| 331 | 
            +
             | 
| 332 332 | 
             
                        const onclickString = `dashboard.selectCard('agents', ${index}, 'agent_instance', '${instance.id}'); dashboard.showAgentInstanceDetails('${instance.id}');`;
         | 
| 333 333 |  | 
| 334 334 | 
             
                        // Format: "[Agent Name] (delegationType, eventCount events)" with separate timestamp
         | 
| @@ -352,14 +352,14 @@ class EventProcessor { | |
| 352 352 | 
             
                 */
         | 
| 353 353 | 
             
                generateToolHTML(toolCalls) {
         | 
| 354 354 | 
             
                    const filteredToolCalls = this.applyToolCallFilters(toolCalls);
         | 
| 355 | 
            -
             | 
| 355 | 
            +
             | 
| 356 356 | 
             
                    return filteredToolCalls.map(([key, toolCall], index) => {
         | 
| 357 357 | 
             
                        const toolName = toolCall.tool_name || 'Unknown';
         | 
| 358 358 | 
             
                        const rawAgent = toolCall.agent_type || 'Unknown';
         | 
| 359 359 | 
             
                        const timestamp = this.formatTimestamp(toolCall.timestamp);
         | 
| 360 360 | 
             
                        const status = toolCall.post_event ? 'completed' : 'pending';
         | 
| 361 361 | 
             
                        const statusClass = status === 'completed' ? 'status-success' : 'status-pending';
         | 
| 362 | 
            -
             | 
| 362 | 
            +
             | 
| 363 363 | 
             
                        // Convert agent name: show "pm" for PM agent, otherwise show actual agent name
         | 
| 364 364 | 
             
                        const agentName = rawAgent.toLowerCase() === 'pm' ? 'pm' : rawAgent;
         | 
| 365 365 |  | 
| @@ -384,25 +384,25 @@ class EventProcessor { | |
| 384 384 | 
             
                 */
         | 
| 385 385 | 
             
                generateFileHTML(fileOperations) {
         | 
| 386 386 | 
             
                    const filteredFiles = this.applyFilesFilters(fileOperations);
         | 
| 387 | 
            -
             | 
| 387 | 
            +
             | 
| 388 388 | 
             
                    return filteredFiles.map(([filePath, fileData], index) => {
         | 
| 389 389 | 
             
                        const operations = fileData.operations.map(op => op.operation);
         | 
| 390 390 | 
             
                        const timestamp = this.formatTimestamp(fileData.lastOperation);
         | 
| 391 | 
            -
             | 
| 391 | 
            +
             | 
| 392 392 | 
             
                        // Count operations by type for display: "read(2), write(1)"
         | 
| 393 393 | 
             
                        const operationCounts = {};
         | 
| 394 394 | 
             
                        operations.forEach(op => {
         | 
| 395 395 | 
             
                            operationCounts[op] = (operationCounts[op] || 0) + 1;
         | 
| 396 396 | 
             
                        });
         | 
| 397 | 
            -
             | 
| 397 | 
            +
             | 
| 398 398 | 
             
                        const operationSummary = Object.entries(operationCounts)
         | 
| 399 399 | 
             
                            .map(([op, count]) => `${op}(${count})`)
         | 
| 400 400 | 
             
                            .join(', ');
         | 
| 401 | 
            -
             | 
| 401 | 
            +
             | 
| 402 402 | 
             
                        // Get unique agents that worked on this file
         | 
| 403 403 | 
             
                        const uniqueAgents = [...new Set(fileData.operations.map(op => op.agent))];
         | 
| 404 404 | 
             
                        const agentSummary = uniqueAgents.length > 1 ? `by ${uniqueAgents.length} agents` : `by ${uniqueAgents[0] || 'unknown'}`;
         | 
| 405 | 
            -
             | 
| 405 | 
            +
             | 
| 406 406 | 
             
                        // Format: "[file path] read(2), write(1) by agent" with separate timestamp
         | 
| 407 407 | 
             
                        const fileName = this.getRelativeFilePath(filePath);
         | 
| 408 408 | 
             
                        const fileMainContent = `${fileName} ${operationSummary} ${agentSummary}`;
         | 
| @@ -439,7 +439,7 @@ class EventProcessor { | |
| 439 439 | 
             
                 */
         | 
| 440 440 | 
             
                getRelativeFilePath(filePath) {
         | 
| 441 441 | 
             
                    if (!filePath) return '';
         | 
| 442 | 
            -
             | 
| 442 | 
            +
             | 
| 443 443 | 
             
                    // Simple relative path logic - can be enhanced
         | 
| 444 444 | 
             
                    const parts = filePath.split('/');
         | 
| 445 445 | 
             
                    if (parts.length > 3) {
         | 
| @@ -455,7 +455,7 @@ class EventProcessor { | |
| 455 455 | 
             
                 */
         | 
| 456 456 | 
             
                formatTimestamp(timestamp) {
         | 
| 457 457 | 
             
                    if (!timestamp) return '';
         | 
| 458 | 
            -
             | 
| 458 | 
            +
             | 
| 459 459 | 
             
                    const date = new Date(timestamp);
         | 
| 460 460 | 
             
                    return date.toLocaleTimeString();
         | 
| 461 461 | 
             
                }
         | 
| @@ -511,13 +511,13 @@ class EventProcessor { | |
| 511 511 | 
             
                async isFileTracked(filePath, workingDir) {
         | 
| 512 512 | 
             
                    const cacheKey = `${workingDir}:${filePath}`;
         | 
| 513 513 | 
             
                    const now = Date.now();
         | 
| 514 | 
            -
             | 
| 514 | 
            +
             | 
| 515 515 | 
             
                    // Check cache first
         | 
| 516 516 | 
             
                    const cached = this.fileTrackingCache.get(cacheKey);
         | 
| 517 517 | 
             
                    if (cached && (now - cached.timestamp) < this.trackingCheckTimeout) {
         | 
| 518 518 | 
             
                        return cached.is_tracked;
         | 
| 519 519 | 
             
                    }
         | 
| 520 | 
            -
             | 
| 520 | 
            +
             | 
| 521 521 | 
             
                    try {
         | 
| 522 522 | 
             
                        // Use the socketio connection to check tracking status
         | 
| 523 523 | 
             
                        const socket = window.socket;
         | 
| @@ -525,39 +525,39 @@ class EventProcessor { | |
| 525 525 | 
             
                            console.warn('No socket connection available for git tracking check');
         | 
| 526 526 | 
             
                            return false;
         | 
| 527 527 | 
             
                        }
         | 
| 528 | 
            -
             | 
| 528 | 
            +
             | 
| 529 529 | 
             
                        return new Promise((resolve) => {
         | 
| 530 530 | 
             
                            // Set up one-time listener for response
         | 
| 531 531 | 
             
                            const responseHandler = (data) => {
         | 
| 532 532 | 
             
                                if (data.file_path === filePath) {
         | 
| 533 533 | 
             
                                    const isTracked = data.success && data.is_tracked;
         | 
| 534 | 
            -
             | 
| 534 | 
            +
             | 
| 535 535 | 
             
                                    // Cache the result
         | 
| 536 536 | 
             
                                    this.fileTrackingCache.set(cacheKey, {
         | 
| 537 537 | 
             
                                        is_tracked: isTracked,
         | 
| 538 538 | 
             
                                        timestamp: now
         | 
| 539 539 | 
             
                                    });
         | 
| 540 | 
            -
             | 
| 540 | 
            +
             | 
| 541 541 | 
             
                                    socket.off('file_tracked_response', responseHandler);
         | 
| 542 542 | 
             
                                    resolve(isTracked);
         | 
| 543 543 | 
             
                                }
         | 
| 544 544 | 
             
                            };
         | 
| 545 | 
            -
             | 
| 545 | 
            +
             | 
| 546 546 | 
             
                            socket.on('file_tracked_response', responseHandler);
         | 
| 547 | 
            -
             | 
| 547 | 
            +
             | 
| 548 548 | 
             
                            // Send request
         | 
| 549 549 | 
             
                            socket.emit('check_file_tracked', {
         | 
| 550 550 | 
             
                                file_path: filePath,
         | 
| 551 551 | 
             
                                working_dir: workingDir
         | 
| 552 552 | 
             
                            });
         | 
| 553 | 
            -
             | 
| 553 | 
            +
             | 
| 554 554 | 
             
                            // Timeout after 5 seconds
         | 
| 555 555 | 
             
                            setTimeout(() => {
         | 
| 556 556 | 
             
                                socket.off('file_tracked_response', responseHandler);
         | 
| 557 557 | 
             
                                resolve(false); // Default to not tracked on timeout
         | 
| 558 558 | 
             
                            }, 5000);
         | 
| 559 559 | 
             
                        });
         | 
| 560 | 
            -
             | 
| 560 | 
            +
             | 
| 561 561 | 
             
                    } catch (error) {
         | 
| 562 562 | 
             
                        console.error('Error checking file tracking status:', error);
         | 
| 563 563 | 
             
                        return false;
         | 
| @@ -573,17 +573,17 @@ class EventProcessor { | |
| 573 573 | 
             
                 */
         | 
| 574 574 | 
             
                generateGitDiffIcon(filePath, timestamp, workingDir) {
         | 
| 575 575 | 
             
                    const iconId = `git-icon-${filePath.replace(/[^a-zA-Z0-9]/g, '-')}-${timestamp}`;
         | 
| 576 | 
            -
             | 
| 576 | 
            +
             | 
| 577 577 | 
             
                    // Initially show default icon
         | 
| 578 578 | 
             
                    const iconHtml = `
         | 
| 579 | 
            -
                        <span id="${iconId}" class="git-diff-icon" | 
| 579 | 
            +
                        <span id="${iconId}" class="git-diff-icon"
         | 
| 580 580 | 
             
                              onclick="event.stopPropagation(); showGitDiffModal('${filePath}', '${timestamp}')"
         | 
| 581 581 | 
             
                              title="View git diff for this file operation"
         | 
| 582 582 | 
             
                              style="margin-left: 8px; cursor: pointer; font-size: 16px;">
         | 
| 583 583 | 
             
                            📋
         | 
| 584 584 | 
             
                        </span>
         | 
| 585 585 | 
             
                    `;
         | 
| 586 | 
            -
             | 
| 586 | 
            +
             | 
| 587 587 | 
             
                    // Asynchronously check tracking status and update icon
         | 
| 588 588 | 
             
                    this.isFileTracked(filePath, workingDir).then(isTracked => {
         | 
| 589 589 | 
             
                        const iconElement = document.getElementById(iconId);
         | 
| @@ -603,7 +603,7 @@ class EventProcessor { | |
| 603 603 | 
             
                    }).catch(error => {
         | 
| 604 604 | 
             
                        console.error('Error updating git diff icon:', error);
         | 
| 605 605 | 
             
                    });
         | 
| 606 | 
            -
             | 
| 606 | 
            +
             | 
| 607 607 | 
             
                    return iconHtml;
         | 
| 608 608 | 
             
                }
         | 
| 609 609 |  | 
| @@ -614,15 +614,15 @@ class EventProcessor { | |
| 614 614 | 
             
                showAgentInstanceDetails(instanceId) {
         | 
| 615 615 | 
             
                    const pmDelegations = this.agentInference.getPMDelegations();
         | 
| 616 616 | 
             
                    const instance = pmDelegations.get(instanceId);
         | 
| 617 | 
            -
             | 
| 617 | 
            +
             | 
| 618 618 | 
             
                    if (!instance) {
         | 
| 619 619 | 
             
                        console.error('Agent instance not found:', instanceId);
         | 
| 620 620 | 
             
                        return;
         | 
| 621 621 | 
             
                    }
         | 
| 622 | 
            -
             | 
| 622 | 
            +
             | 
| 623 623 | 
             
                    // Show details about this PM delegation and its events
         | 
| 624 624 | 
             
                    console.log('Showing agent instance details for:', instanceId, instance);
         | 
| 625 | 
            -
             | 
| 625 | 
            +
             | 
| 626 626 | 
             
                    // This would integrate with the existing detail view system
         | 
| 627 627 | 
             
                    // For now, just log the details - can be expanded to show in a modal/sidebar
         | 
| 628 628 | 
             
                    const detailsHtml = `
         | 
| @@ -635,8 +635,12 @@ class EventProcessor { | |
| 635 635 | 
             
                            ${instance.pmCall ? `<p><strong>PM Call:</strong> Task delegation to ${instance.agentName}</p>` : '<p><strong>Note:</strong> Implied delegation (no explicit PM call found)</p>'}
         | 
| 636 636 | 
             
                        </div>
         | 
| 637 637 | 
             
                    `;
         | 
| 638 | 
            -
             | 
| 638 | 
            +
             | 
| 639 639 | 
             
                    // You would integrate this with your existing detail display system
         | 
| 640 640 | 
             
                    console.log('Agent instance details HTML:', detailsHtml);
         | 
| 641 641 | 
             
                }
         | 
| 642 | 
            -
            }
         | 
| 642 | 
            +
            }
         | 
| 643 | 
            +
             | 
| 644 | 
            +
            // ES6 Module export
         | 
| 645 | 
            +
            export { EventProcessor };
         | 
| 646 | 
            +
            export default EventProcessor;
         |