claude-mpm 3.9.11__py3-none-any.whl → 4.0.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +1 -1
- 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 +2 -2
- 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 +79 -51
- claude_mpm/cli/__main__.py +3 -2
- claude_mpm/cli/commands/__init__.py +20 -20
- 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 +140 -905
- 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 +330 -86
- 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 +363 -220
- claude_mpm/cli/parser.py +24 -1156
- 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 +124 -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 +71 -73
- claude_mpm/config/paths.py +94 -208
- claude_mpm/config/socketio_config.py +84 -73
- claude_mpm/constants.py +35 -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/built/components/agent-inference.js +2 -0
- claude_mpm/dashboard/static/built/components/event-processor.js +2 -0
- claude_mpm/dashboard/static/built/components/event-viewer.js +2 -0
- claude_mpm/dashboard/static/built/components/export-manager.js +2 -0
- claude_mpm/dashboard/static/built/components/file-tool-tracker.js +2 -0
- claude_mpm/dashboard/static/built/components/hud-library-loader.js +2 -0
- claude_mpm/dashboard/static/built/components/hud-manager.js +2 -0
- claude_mpm/dashboard/static/built/components/hud-visualizer.js +2 -0
- claude_mpm/dashboard/static/built/components/module-viewer.js +2 -0
- claude_mpm/dashboard/static/built/components/session-manager.js +2 -0
- claude_mpm/dashboard/static/built/components/socket-manager.js +2 -0
- claude_mpm/dashboard/static/built/components/ui-state-manager.js +2 -0
- claude_mpm/dashboard/static/built/components/working-directory.js +2 -0
- claude_mpm/dashboard/static/built/dashboard.js +2 -0
- claude_mpm/dashboard/static/built/socket-client.js +2 -0
- 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 +93 -72
- claude_mpm/dashboard/static/js/components/export-manager.js +31 -28
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +110 -96
- 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 +133 -53
- 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 +233 -199
- 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 +30 -13
- 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 +13 -20
- 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 +87 -84
- claude_mpm/services/mcp_gateway/main.py +287 -137
- claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
- claude_mpm/services/mcp_gateway/registry/service_registry.py +97 -94
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
- claude_mpm/services/mcp_gateway/server/__init__.py +2 -2
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +105 -110
- 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 +109 -119
- 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 +575 -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 +166 -64
- 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 +185 -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 +19 -533
- 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 +2 -2
- claude_mpm/storage/state_storage.py +177 -181
- 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.11.dist-info → claude_mpm-4.0.4.dist-info}/METADATA +90 -22
- claude_mpm-4.0.4.dist-info/RECORD +417 -0
- {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/entry_points.txt +1 -0
- {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/licenses/LICENSE +1 -1
- claude_mpm/cli/commands/run_guarded.py +0 -511
- claude_mpm/config/memory_guardian_config.py +0 -325
- claude_mpm/config/memory_guardian_yaml.py +0 -335
- claude_mpm/core/config_paths.py +0 -150
- claude_mpm/core/memory_aware_runner.py +0 -353
- 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/graceful_degradation.py +0 -616
- claude_mpm/services/infrastructure/health_monitor.py +0 -775
- claude_mpm/services/infrastructure/memory_dashboard.py +0 -479
- claude_mpm/services/infrastructure/memory_guardian.py +0 -944
- claude_mpm/services/infrastructure/restart_protection.py +0 -642
- claude_mpm/services/infrastructure/state_manager.py +0 -774
- claude_mpm/services/mcp_gateway/manager.py +0 -334
- 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.11.dist-info/RECORD +0 -306
- {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/WHEEL +0 -0
- {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/top_level.txt +0 -0
| @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            /**
         | 
| 2 2 | 
             
             * Working Directory Module
         | 
| 3 | 
            -
             * | 
| 3 | 
            +
             *
         | 
| 4 4 | 
             
             * Manages working directory state, session-specific directory tracking,
         | 
| 5 5 | 
             
             * and git branch monitoring for the dashboard.
         | 
| 6 | 
            -
             * | 
| 6 | 
            +
             *
         | 
| 7 7 | 
             
             * WHY: Extracted from main dashboard to isolate working directory management
         | 
| 8 8 | 
             
             * logic that involves coordination between UI updates, local storage persistence,
         | 
| 9 9 | 
             
             * and git integration. This provides better maintainability for directory state.
         | 
| 10 | 
            -
             * | 
| 10 | 
            +
             *
         | 
| 11 11 | 
             
             * DESIGN DECISION: Maintains per-session working directories with persistence
         | 
| 12 12 | 
             
             * in localStorage, provides git branch integration, and coordinates with
         | 
| 13 13 | 
             
             * footer directory display for consistent state management.
         | 
| @@ -18,10 +18,10 @@ class WorkingDirectoryManager { | |
| 18 18 | 
             
                    this.currentWorkingDir = null;
         | 
| 19 19 | 
             
                    this.footerDirObserver = null;
         | 
| 20 20 | 
             
                    this._updatingFooter = false;
         | 
| 21 | 
            -
             | 
| 21 | 
            +
             | 
| 22 22 | 
             
                    this.setupEventHandlers();
         | 
| 23 23 | 
             
                    this.initialize();
         | 
| 24 | 
            -
             | 
| 24 | 
            +
             | 
| 25 25 | 
             
                    console.log('Working directory manager initialized');
         | 
| 26 26 | 
             
                }
         | 
| 27 27 |  | 
| @@ -39,13 +39,13 @@ class WorkingDirectoryManager { | |
| 39 39 | 
             
                setupEventHandlers() {
         | 
| 40 40 | 
             
                    const changeDirBtn = document.getElementById('change-dir-btn');
         | 
| 41 41 | 
             
                    const workingDirPath = document.getElementById('working-dir-path');
         | 
| 42 | 
            -
             | 
| 42 | 
            +
             | 
| 43 43 | 
             
                    if (changeDirBtn) {
         | 
| 44 44 | 
             
                        changeDirBtn.addEventListener('click', () => {
         | 
| 45 45 | 
             
                            this.showChangeDirDialog();
         | 
| 46 46 | 
             
                        });
         | 
| 47 47 | 
             
                    }
         | 
| 48 | 
            -
             | 
| 48 | 
            +
             | 
| 49 49 | 
             
                    if (workingDirPath) {
         | 
| 50 50 | 
             
                        workingDirPath.addEventListener('click', (e) => {
         | 
| 51 51 | 
             
                            // Check if Shift key is held for directory change, otherwise show file viewer
         | 
| @@ -65,7 +65,7 @@ class WorkingDirectoryManager { | |
| 65 65 | 
             
                            this.loadWorkingDirectoryForSession(sessionId);
         | 
| 66 66 | 
             
                        }
         | 
| 67 67 | 
             
                    });
         | 
| 68 | 
            -
             | 
| 68 | 
            +
             | 
| 69 69 | 
             
                    // Listen for git branch responses
         | 
| 70 70 | 
             
                    if (this.socketManager && this.socketManager.getSocket) {
         | 
| 71 71 | 
             
                        const socket = this.socketManager.getSocket();
         | 
| @@ -88,7 +88,7 @@ class WorkingDirectoryManager { | |
| 88 88 | 
             
                    if (pathElement && !pathElement.textContent.trim()) {
         | 
| 89 89 | 
             
                        pathElement.textContent = 'Loading...';
         | 
| 90 90 | 
             
                    }
         | 
| 91 | 
            -
             | 
| 91 | 
            +
             | 
| 92 92 | 
             
                    // Check if there's a selected session
         | 
| 93 93 | 
             
                    const sessionSelect = document.getElementById('session-select');
         | 
| 94 94 | 
             
                    if (sessionSelect && sessionSelect.value && sessionSelect.value !== 'all') {
         | 
| @@ -106,17 +106,17 @@ class WorkingDirectoryManager { | |
| 106 106 | 
             
                watchFooterDirectory() {
         | 
| 107 107 | 
             
                    const footerDir = document.getElementById('footer-working-dir');
         | 
| 108 108 | 
             
                    if (!footerDir) return;
         | 
| 109 | 
            -
             | 
| 109 | 
            +
             | 
| 110 110 | 
             
                    // Store observer reference for later use
         | 
| 111 111 | 
             
                    this.footerDirObserver = new MutationObserver((mutations) => {
         | 
| 112 112 | 
             
                        // Skip if we're updating from setWorkingDirectory
         | 
| 113 113 | 
             
                        if (this._updatingFooter) return;
         | 
| 114 | 
            -
             | 
| 114 | 
            +
             | 
| 115 115 | 
             
                        mutations.forEach((mutation) => {
         | 
| 116 116 | 
             
                            if (mutation.type === 'childList' || mutation.type === 'characterData') {
         | 
| 117 117 | 
             
                                const newDir = footerDir.textContent.trim();
         | 
| 118 118 | 
             
                                console.log('Footer directory changed to:', newDir);
         | 
| 119 | 
            -
             | 
| 119 | 
            +
             | 
| 120 120 | 
             
                                // Only update if it's different from current
         | 
| 121 121 | 
             
                                if (newDir && newDir !== this.currentWorkingDir) {
         | 
| 122 122 | 
             
                                    console.log('Syncing working directory from footer change');
         | 
| @@ -125,14 +125,14 @@ class WorkingDirectoryManager { | |
| 125 125 | 
             
                            }
         | 
| 126 126 | 
             
                        });
         | 
| 127 127 | 
             
                    });
         | 
| 128 | 
            -
             | 
| 128 | 
            +
             | 
| 129 129 | 
             
                    // Observe changes to footer directory
         | 
| 130 130 | 
             
                    this.footerDirObserver.observe(footerDir, {
         | 
| 131 131 | 
             
                        childList: true,
         | 
| 132 132 | 
             
                        characterData: true,
         | 
| 133 133 | 
             
                        subtree: true
         | 
| 134 134 | 
             
                    });
         | 
| 135 | 
            -
             | 
| 135 | 
            +
             | 
| 136 136 | 
             
                    console.log('Started watching footer directory for changes');
         | 
| 137 137 | 
             
                }
         | 
| 138 138 |  | 
| @@ -142,7 +142,7 @@ class WorkingDirectoryManager { | |
| 142 142 | 
             
                 */
         | 
| 143 143 | 
             
                loadWorkingDirectoryForSession(sessionId) {
         | 
| 144 144 | 
             
                    console.log('[WORKING-DIR-DEBUG] loadWorkingDirectoryForSession called with sessionId:', this.repr(sessionId));
         | 
| 145 | 
            -
             | 
| 145 | 
            +
             | 
| 146 146 | 
             
                    if (!sessionId || sessionId === 'all') {
         | 
| 147 147 | 
             
                        console.log('[WORKING-DIR-DEBUG] No sessionId or sessionId is "all", using default working dir');
         | 
| 148 148 | 
             
                        const defaultDir = this.getDefaultWorkingDir();
         | 
| @@ -150,22 +150,22 @@ class WorkingDirectoryManager { | |
| 150 150 | 
             
                        this.setWorkingDirectory(defaultDir);
         | 
| 151 151 | 
             
                        return;
         | 
| 152 152 | 
             
                    }
         | 
| 153 | 
            -
             | 
| 153 | 
            +
             | 
| 154 154 | 
             
                    // Load from localStorage
         | 
| 155 155 | 
             
                    const sessionDirs = JSON.parse(localStorage.getItem('sessionWorkingDirs') || '{}');
         | 
| 156 156 | 
             
                    console.log('[WORKING-DIR-DEBUG] Session directories from localStorage:', sessionDirs);
         | 
| 157 | 
            -
             | 
| 157 | 
            +
             | 
| 158 158 | 
             
                    const sessionDir = sessionDirs[sessionId];
         | 
| 159 159 | 
             
                    const defaultDir = this.getDefaultWorkingDir();
         | 
| 160 160 | 
             
                    const dir = sessionDir || defaultDir;
         | 
| 161 | 
            -
             | 
| 161 | 
            +
             | 
| 162 162 | 
             
                    console.log('[WORKING-DIR-DEBUG] Directory selection:', {
         | 
| 163 163 | 
             
                        sessionId: sessionId,
         | 
| 164 164 | 
             
                        sessionDir: this.repr(sessionDir),
         | 
| 165 165 | 
             
                        defaultDir: this.repr(defaultDir),
         | 
| 166 166 | 
             
                        finalDir: this.repr(dir)
         | 
| 167 167 | 
             
                    });
         | 
| 168 | 
            -
             | 
| 168 | 
            +
             | 
| 169 169 | 
             
                    this.setWorkingDirectory(dir);
         | 
| 170 170 | 
             
                }
         | 
| 171 171 |  | 
| @@ -175,9 +175,9 @@ class WorkingDirectoryManager { | |
| 175 175 | 
             
                 */
         | 
| 176 176 | 
             
                setWorkingDirectory(dir) {
         | 
| 177 177 | 
             
                    console.log('[WORKING-DIR-DEBUG] setWorkingDirectory called with:', this.repr(dir));
         | 
| 178 | 
            -
             | 
| 178 | 
            +
             | 
| 179 179 | 
             
                    this.currentWorkingDir = dir;
         | 
| 180 | 
            -
             | 
| 180 | 
            +
             | 
| 181 181 | 
             
                    // Update UI
         | 
| 182 182 | 
             
                    const pathElement = document.getElementById('working-dir-path');
         | 
| 183 183 | 
             
                    if (pathElement) {
         | 
| @@ -186,19 +186,19 @@ class WorkingDirectoryManager { | |
| 186 186 | 
             
                    } else {
         | 
| 187 187 | 
             
                        console.warn('[WORKING-DIR-DEBUG] working-dir-path element not found');
         | 
| 188 188 | 
             
                    }
         | 
| 189 | 
            -
             | 
| 189 | 
            +
             | 
| 190 190 | 
             
                    // Update footer directory (sync across components)
         | 
| 191 191 | 
             
                    const footerDir = document.getElementById('footer-working-dir');
         | 
| 192 192 | 
             
                    if (footerDir) {
         | 
| 193 193 | 
             
                        const currentFooterText = footerDir.textContent;
         | 
| 194 194 | 
             
                        console.log('[WORKING-DIR-DEBUG] Footer directory current text:', this.repr(currentFooterText), 'new text:', this.repr(dir));
         | 
| 195 | 
            -
             | 
| 195 | 
            +
             | 
| 196 196 | 
             
                        if (currentFooterText !== dir) {
         | 
| 197 197 | 
             
                            // Set flag to prevent observer from triggering
         | 
| 198 198 | 
             
                            this._updatingFooter = true;
         | 
| 199 199 | 
             
                            footerDir.textContent = dir;
         | 
| 200 200 | 
             
                            console.log('[WORKING-DIR-DEBUG] Updated footer directory to:', dir);
         | 
| 201 | 
            -
             | 
| 201 | 
            +
             | 
| 202 202 | 
             
                            // Clear flag after a short delay
         | 
| 203 203 | 
             
                            setTimeout(() => {
         | 
| 204 204 | 
             
                                this._updatingFooter = false;
         | 
| @@ -210,7 +210,7 @@ class WorkingDirectoryManager { | |
| 210 210 | 
             
                    } else {
         | 
| 211 211 | 
             
                        console.warn('[WORKING-DIR-DEBUG] footer-working-dir element not found');
         | 
| 212 212 | 
             
                    }
         | 
| 213 | 
            -
             | 
| 213 | 
            +
             | 
| 214 214 | 
             
                    // Save to localStorage for session persistence
         | 
| 215 215 | 
             
                    const sessionSelect = document.getElementById('session-select');
         | 
| 216 216 | 
             
                    if (sessionSelect && sessionSelect.value && sessionSelect.value !== 'all') {
         | 
| @@ -222,7 +222,7 @@ class WorkingDirectoryManager { | |
| 222 222 | 
             
                    } else {
         | 
| 223 223 | 
             
                        console.log('[WORKING-DIR-DEBUG] No session selected or session is "all", not saving to localStorage');
         | 
| 224 224 | 
             
                    }
         | 
| 225 | 
            -
             | 
| 225 | 
            +
             | 
| 226 226 | 
             
                    // Update git branch for new directory - only if it's a valid path
         | 
| 227 227 | 
             
                    console.log('[WORKING-DIR-DEBUG] About to call updateGitBranch with:', this.repr(dir));
         | 
| 228 228 | 
             
                    if (this.validateDirectoryPath(dir)) {
         | 
| @@ -230,12 +230,12 @@ class WorkingDirectoryManager { | |
| 230 230 | 
             
                    } else {
         | 
| 231 231 | 
             
                        console.log('[WORKING-DIR-DEBUG] Skipping git branch update for invalid directory:', this.repr(dir));
         | 
| 232 232 | 
             
                    }
         | 
| 233 | 
            -
             | 
| 233 | 
            +
             | 
| 234 234 | 
             
                    // Dispatch event for other modules
         | 
| 235 235 | 
             
                    document.dispatchEvent(new CustomEvent('workingDirectoryChanged', {
         | 
| 236 236 | 
             
                        detail: { directory: dir }
         | 
| 237 237 | 
             
                    }));
         | 
| 238 | 
            -
             | 
| 238 | 
            +
             | 
| 239 239 | 
             
                    console.log('[WORKING-DIR-DEBUG] Working directory set to:', dir);
         | 
| 240 240 | 
             
                }
         | 
| 241 241 |  | 
| @@ -245,7 +245,7 @@ class WorkingDirectoryManager { | |
| 245 245 | 
             
                 */
         | 
| 246 246 | 
             
                updateGitBranch(dir) {
         | 
| 247 247 | 
             
                    console.log('[GIT-BRANCH-DEBUG] updateGitBranch called with dir:', this.repr(dir), 'type:', typeof dir);
         | 
| 248 | 
            -
             | 
| 248 | 
            +
             | 
| 249 249 | 
             
                    if (!this.socketManager || !this.socketManager.isConnected()) {
         | 
| 250 250 | 
             
                        console.log('[GIT-BRANCH-DEBUG] Not connected to socket server');
         | 
| 251 251 | 
             
                        // Not connected, set to unknown
         | 
| @@ -256,13 +256,13 @@ class WorkingDirectoryManager { | |
| 256 256 | 
             
                        }
         | 
| 257 257 | 
             
                        return;
         | 
| 258 258 | 
             
                    }
         | 
| 259 | 
            -
             | 
| 259 | 
            +
             | 
| 260 260 | 
             
                    // Enhanced validation with specific checks for common invalid states
         | 
| 261 261 | 
             
                    const isValidPath = this.validateDirectoryPath(dir);
         | 
| 262 262 | 
             
                    const isLoadingState = dir === 'Loading...' || dir === 'Loading';
         | 
| 263 263 | 
             
                    const isUnknown = dir === 'Unknown';
         | 
| 264 264 | 
             
                    const isEmptyOrWhitespace = !dir || (typeof dir === 'string' && dir.trim() === '');
         | 
| 265 | 
            -
             | 
| 265 | 
            +
             | 
| 266 266 | 
             
                    console.log('[GIT-BRANCH-DEBUG] Validation results:', {
         | 
| 267 267 | 
             
                        dir: dir,
         | 
| 268 268 | 
             
                        isValidPath: isValidPath,
         | 
| @@ -271,7 +271,7 @@ class WorkingDirectoryManager { | |
| 271 271 | 
             
                        isEmptyOrWhitespace: isEmptyOrWhitespace,
         | 
| 272 272 | 
             
                        shouldReject: !isValidPath || isLoadingState || isUnknown || isEmptyOrWhitespace
         | 
| 273 273 | 
             
                    });
         | 
| 274 | 
            -
             | 
| 274 | 
            +
             | 
| 275 275 | 
             
                    // Validate directory before sending to server - reject common invalid states
         | 
| 276 276 | 
             
                    if (!isValidPath || isLoadingState || isUnknown || isEmptyOrWhitespace) {
         | 
| 277 277 | 
             
                        console.warn('[GIT-BRANCH-DEBUG] Invalid working directory for git branch request:', dir);
         | 
| @@ -288,7 +288,7 @@ class WorkingDirectoryManager { | |
| 288 288 | 
             
                        }
         | 
| 289 289 | 
             
                        return;
         | 
| 290 290 | 
             
                    }
         | 
| 291 | 
            -
             | 
| 291 | 
            +
             | 
| 292 292 | 
             
                    // Request git branch from server
         | 
| 293 293 | 
             
                    const socket = this.socketManager.getSocket();
         | 
| 294 294 | 
             
                    if (socket) {
         | 
| @@ -310,24 +310,24 @@ class WorkingDirectoryManager { | |
| 310 310 | 
             
                 */
         | 
| 311 311 | 
             
                getDefaultWorkingDir() {
         | 
| 312 312 | 
             
                    console.log('[WORKING-DIR-DEBUG] getDefaultWorkingDir called');
         | 
| 313 | 
            -
             | 
| 313 | 
            +
             | 
| 314 314 | 
             
                    // Try to get from footer first
         | 
| 315 315 | 
             
                    const footerDir = document.getElementById('footer-working-dir');
         | 
| 316 316 | 
             
                    if (footerDir?.textContent?.trim()) {
         | 
| 317 317 | 
             
                        const footerPath = footerDir.textContent.trim();
         | 
| 318 318 | 
             
                        console.log('[WORKING-DIR-DEBUG] Footer path found:', this.repr(footerPath));
         | 
| 319 | 
            -
             | 
| 319 | 
            +
             | 
| 320 320 | 
             
                        // Don't use 'Unknown' as a valid directory
         | 
| 321 321 | 
             
                        const isUnknown = footerPath === 'Unknown';
         | 
| 322 322 | 
             
                        const isValid = this.validateDirectoryPath(footerPath);
         | 
| 323 | 
            -
             | 
| 323 | 
            +
             | 
| 324 324 | 
             
                        console.log('[WORKING-DIR-DEBUG] Footer path validation:', {
         | 
| 325 325 | 
             
                            footerPath: this.repr(footerPath),
         | 
| 326 326 | 
             
                            isUnknown: isUnknown,
         | 
| 327 327 | 
             
                            isValid: isValid,
         | 
| 328 328 | 
             
                            shouldUse: !isUnknown && isValid
         | 
| 329 329 | 
             
                        });
         | 
| 330 | 
            -
             | 
| 330 | 
            +
             | 
| 331 331 | 
             
                        if (!isUnknown && isValid) {
         | 
| 332 332 | 
             
                            console.log('[WORKING-DIR-DEBUG] Using footer path as default:', footerPath);
         | 
| 333 333 | 
             
                            return footerPath;
         | 
| @@ -335,10 +335,10 @@ class WorkingDirectoryManager { | |
| 335 335 | 
             
                    } else {
         | 
| 336 336 | 
             
                        console.log('[WORKING-DIR-DEBUG] No footer directory element or no text content');
         | 
| 337 337 | 
             
                    }
         | 
| 338 | 
            -
             | 
| 338 | 
            +
             | 
| 339 339 | 
             
                    // Fallback to a reasonable default - try to get the current project directory
         | 
| 340 340 | 
             
                    // This should be set when the dashboard initializes
         | 
| 341 | 
            -
             | 
| 341 | 
            +
             | 
| 342 342 | 
             
                    // Try getting from the browser's URL or any other hint about the current project
         | 
| 343 343 | 
             
                    if (window.location.pathname.includes('claude-mpm')) {
         | 
| 344 344 | 
             
                        // We can infer we're in a claude-mpm project
         | 
| @@ -355,7 +355,7 @@ class WorkingDirectoryManager { | |
| 355 355 | 
             
                            return pathText;
         | 
| 356 356 | 
             
                        }
         | 
| 357 357 | 
             
                    }
         | 
| 358 | 
            -
             | 
| 358 | 
            +
             | 
| 359 359 | 
             
                    // Final fallback to current directory indicator
         | 
| 360 360 | 
             
                    const fallback = process?.cwd?.() || '/Users/masa/Projects/claude-mpm';
         | 
| 361 361 | 
             
                    console.log('[WORKING-DIR-DEBUG] Using hard-coded fallback directory:', this.repr(fallback));
         | 
| @@ -390,15 +390,15 @@ class WorkingDirectoryManager { | |
| 390 390 | 
             
                createDirectoryViewerOverlay() {
         | 
| 391 391 | 
             
                    // Remove existing overlay if present
         | 
| 392 392 | 
             
                    this.removeDirectoryViewerOverlay();
         | 
| 393 | 
            -
             | 
| 393 | 
            +
             | 
| 394 394 | 
             
                    const workingDirDisplay = document.querySelector('.working-dir-display');
         | 
| 395 395 | 
             
                    if (!workingDirDisplay) return;
         | 
| 396 | 
            -
             | 
| 396 | 
            +
             | 
| 397 397 | 
             
                    // Create overlay element
         | 
| 398 398 | 
             
                    const overlay = document.createElement('div');
         | 
| 399 399 | 
             
                    overlay.id = 'directory-viewer-overlay';
         | 
| 400 400 | 
             
                    overlay.className = 'directory-viewer-overlay';
         | 
| 401 | 
            -
             | 
| 401 | 
            +
             | 
| 402 402 | 
             
                    // Create overlay content
         | 
| 403 403 | 
             
                    overlay.innerHTML = `
         | 
| 404 404 | 
             
                        <div class="directory-viewer-content">
         | 
| @@ -416,7 +416,7 @@ class WorkingDirectoryManager { | |
| 416 416 | 
             
                            </div>
         | 
| 417 417 | 
             
                        </div>
         | 
| 418 418 | 
             
                    `;
         | 
| 419 | 
            -
             | 
| 419 | 
            +
             | 
| 420 420 | 
             
                    // Position overlay below the working directory display
         | 
| 421 421 | 
             
                    const rect = workingDirDisplay.getBoundingClientRect();
         | 
| 422 422 | 
             
                    overlay.style.cssText = `
         | 
| @@ -432,13 +432,13 @@ class WorkingDirectoryManager { | |
| 432 432 | 
             
                        box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
         | 
| 433 433 | 
             
                        border: 1px solid #e2e8f0;
         | 
| 434 434 | 
             
                    `;
         | 
| 435 | 
            -
             | 
| 435 | 
            +
             | 
| 436 436 | 
             
                    // Add to document
         | 
| 437 437 | 
             
                    document.body.appendChild(overlay);
         | 
| 438 | 
            -
             | 
| 438 | 
            +
             | 
| 439 439 | 
             
                    // Load directory contents
         | 
| 440 440 | 
             
                    this.loadDirectoryContents();
         | 
| 441 | 
            -
             | 
| 441 | 
            +
             | 
| 442 442 | 
             
                    // Add click outside to close
         | 
| 443 443 | 
             
                    setTimeout(() => {
         | 
| 444 444 | 
             
                        document.addEventListener('click', this.handleOutsideClick.bind(this), true);
         | 
| @@ -463,7 +463,7 @@ class WorkingDirectoryManager { | |
| 463 463 | 
             
                handleOutsideClick(event) {
         | 
| 464 464 | 
             
                    const overlay = document.getElementById('directory-viewer-overlay');
         | 
| 465 465 | 
             
                    const workingDirPath = document.getElementById('working-dir-path');
         | 
| 466 | 
            -
             | 
| 466 | 
            +
             | 
| 467 467 | 
             
                    if (overlay && !overlay.contains(event.target) && event.target !== workingDirPath) {
         | 
| 468 468 | 
             
                        this.removeDirectoryViewerOverlay();
         | 
| 469 469 | 
             
                    }
         | 
| @@ -558,7 +558,7 @@ class WorkingDirectoryManager { | |
| 558 558 | 
             
                        const filePath = `${this.currentWorkingDir}/${file}`.replace(/\/+/g, '/');
         | 
| 559 559 | 
             
                        const fileExt = file.split('.').pop().toLowerCase();
         | 
| 560 560 | 
             
                        const fileIcon = this.getFileIcon(fileExt);
         | 
| 561 | 
            -
             | 
| 561 | 
            +
             | 
| 562 562 | 
             
                        html += `
         | 
| 563 563 | 
             
                            <div class="file-item" onclick="workingDirectoryManager.viewFile('${filePath}')">
         | 
| 564 564 | 
             
                                <span class="file-icon">${fileIcon}</span>
         | 
| @@ -622,7 +622,7 @@ class WorkingDirectoryManager { | |
| 622 622 | 
             
                        'exe': '⚙️',
         | 
| 623 623 | 
             
                        'dll': '⚙️'
         | 
| 624 624 | 
             
                    };
         | 
| 625 | 
            -
             | 
| 625 | 
            +
             | 
| 626 626 | 
             
                    return iconMap[extension] || '📄';
         | 
| 627 627 | 
             
                }
         | 
| 628 628 |  | 
| @@ -633,7 +633,7 @@ class WorkingDirectoryManager { | |
| 633 633 | 
             
                viewFile(filePath) {
         | 
| 634 634 | 
             
                    // Close the directory viewer overlay
         | 
| 635 635 | 
             
                    this.removeDirectoryViewerOverlay();
         | 
| 636 | 
            -
             | 
| 636 | 
            +
             | 
| 637 637 | 
             
                    // Use the existing file viewer modal functionality
         | 
| 638 638 | 
             
                    if (window.showFileViewerModal) {
         | 
| 639 639 | 
             
                        window.showFileViewerModal(filePath);
         | 
| @@ -667,7 +667,7 @@ class WorkingDirectoryManager { | |
| 667 667 | 
             
                    const sessionDirs = this.getSessionDirectories();
         | 
| 668 668 | 
             
                    sessionDirs[sessionId] = directory;
         | 
| 669 669 | 
             
                    localStorage.setItem('sessionWorkingDirs', JSON.stringify(sessionDirs));
         | 
| 670 | 
            -
             | 
| 670 | 
            +
             | 
| 671 671 | 
             
                    // If this is the current session, update the current directory
         | 
| 672 672 | 
             
                    const sessionSelect = document.getElementById('session-select');
         | 
| 673 673 | 
             
                    if (sessionSelect && sessionSelect.value === sessionId) {
         | 
| @@ -704,7 +704,7 @@ class WorkingDirectoryManager { | |
| 704 704 | 
             
                    if (pair.post?.working_dir) return pair.post.working_dir;
         | 
| 705 705 | 
             
                    if (pair.pre?.data?.working_dir) return pair.pre.data.working_dir;
         | 
| 706 706 | 
             
                    if (pair.post?.data?.working_dir) return pair.post.data.working_dir;
         | 
| 707 | 
            -
             | 
| 707 | 
            +
             | 
| 708 708 | 
             
                    // Fallback to current working directory
         | 
| 709 709 | 
             
                    return this.currentWorkingDir || this.getDefaultWorkingDir();
         | 
| 710 710 | 
             
                }
         | 
| @@ -716,14 +716,14 @@ class WorkingDirectoryManager { | |
| 716 716 | 
             
                 */
         | 
| 717 717 | 
             
                validateDirectoryPath(path) {
         | 
| 718 718 | 
             
                    if (!path || typeof path !== 'string') return false;
         | 
| 719 | 
            -
             | 
| 719 | 
            +
             | 
| 720 720 | 
             
                    // Basic path validation
         | 
| 721 721 | 
             
                    const trimmed = path.trim();
         | 
| 722 722 | 
             
                    if (trimmed.length === 0) return false;
         | 
| 723 | 
            -
             | 
| 723 | 
            +
             | 
| 724 724 | 
             
                    // Check for obviously invalid paths
         | 
| 725 725 | 
             
                    if (trimmed.includes('\0')) return false;
         | 
| 726 | 
            -
             | 
| 726 | 
            +
             | 
| 727 727 | 
             
                    // Check for common invalid placeholder states
         | 
| 728 728 | 
             
                    const invalidStates = [
         | 
| 729 729 | 
             
                        'Loading...',
         | 
| @@ -735,19 +735,19 @@ class WorkingDirectoryManager { | |
| 735 735 | 
             
                        'Invalid Directory',
         | 
| 736 736 | 
             
                        'No Directory'
         | 
| 737 737 | 
             
                    ];
         | 
| 738 | 
            -
             | 
| 738 | 
            +
             | 
| 739 739 | 
             
                    if (invalidStates.includes(trimmed)) return false;
         | 
| 740 | 
            -
             | 
| 740 | 
            +
             | 
| 741 741 | 
             
                    // Basic path structure validation - should start with / or drive letter on Windows
         | 
| 742 742 | 
             
                    if (!trimmed.startsWith('/') && !(/^[A-Za-z]:/.test(trimmed))) {
         | 
| 743 743 | 
             
                        // Allow relative paths that look reasonable
         | 
| 744 | 
            -
                        if (trimmed.startsWith('./') || trimmed.startsWith('../') || | 
| 744 | 
            +
                        if (trimmed.startsWith('./') || trimmed.startsWith('../') ||
         | 
| 745 745 | 
             
                            /^[a-zA-Z0-9._-]+/.test(trimmed)) {
         | 
| 746 746 | 
             
                            return true;
         | 
| 747 747 | 
             
                        }
         | 
| 748 748 | 
             
                        return false;
         | 
| 749 749 | 
             
                    }
         | 
| 750 | 
            -
             | 
| 750 | 
            +
             | 
| 751 751 | 
             
                    return true;
         | 
| 752 752 | 
             
                }
         | 
| 753 753 |  | 
| @@ -757,18 +757,18 @@ class WorkingDirectoryManager { | |
| 757 757 | 
             
                 */
         | 
| 758 758 | 
             
                handleGitBranchResponse(response) {
         | 
| 759 759 | 
             
                    console.log('[GIT-BRANCH-DEBUG] handleGitBranchResponse called with:', response);
         | 
| 760 | 
            -
             | 
| 760 | 
            +
             | 
| 761 761 | 
             
                    const footerBranch = document.getElementById('footer-git-branch');
         | 
| 762 762 | 
             
                    if (!footerBranch) {
         | 
| 763 763 | 
             
                        console.warn('[GIT-BRANCH-DEBUG] footer-git-branch element not found');
         | 
| 764 764 | 
             
                        return;
         | 
| 765 765 | 
             
                    }
         | 
| 766 | 
            -
             | 
| 766 | 
            +
             | 
| 767 767 | 
             
                    if (response.success) {
         | 
| 768 768 | 
             
                        console.log('[GIT-BRANCH-DEBUG] Git branch request successful, branch:', response.branch);
         | 
| 769 769 | 
             
                        footerBranch.textContent = response.branch;
         | 
| 770 770 | 
             
                        footerBranch.style.display = 'inline';
         | 
| 771 | 
            -
             | 
| 771 | 
            +
             | 
| 772 772 | 
             
                        // Optional: Add a class to indicate successful git status
         | 
| 773 773 | 
             
                        footerBranch.classList.remove('git-error');
         | 
| 774 774 | 
             
                        footerBranch.classList.add('git-success');
         | 
| @@ -776,7 +776,7 @@ class WorkingDirectoryManager { | |
| 776 776 | 
             
                        // Handle different error types more gracefully
         | 
| 777 777 | 
             
                        let displayText = 'Git Error';
         | 
| 778 778 | 
             
                        const error = response.error || 'Unknown error';
         | 
| 779 | 
            -
             | 
| 779 | 
            +
             | 
| 780 780 | 
             
                        if (error.includes('Directory not found') || error.includes('does not exist')) {
         | 
| 781 781 | 
             
                            displayText = 'Dir Not Found';
         | 
| 782 782 | 
             
                        } else if (error.includes('Not a directory')) {
         | 
| @@ -788,16 +788,16 @@ class WorkingDirectoryManager { | |
| 788 788 | 
             
                        } else {
         | 
| 789 789 | 
             
                            displayText = 'Unknown';
         | 
| 790 790 | 
             
                        }
         | 
| 791 | 
            -
             | 
| 791 | 
            +
             | 
| 792 792 | 
             
                        console.log('[GIT-BRANCH-DEBUG] Git branch request failed:', error, '- showing as:', displayText);
         | 
| 793 793 | 
             
                        footerBranch.textContent = displayText;
         | 
| 794 794 | 
             
                        footerBranch.style.display = 'inline';
         | 
| 795 | 
            -
             | 
| 795 | 
            +
             | 
| 796 796 | 
             
                        // Optional: Add a class to indicate error state
         | 
| 797 797 | 
             
                        footerBranch.classList.remove('git-success');
         | 
| 798 798 | 
             
                        footerBranch.classList.add('git-error');
         | 
| 799 799 | 
             
                    }
         | 
| 800 | 
            -
             | 
| 800 | 
            +
             | 
| 801 801 | 
             
                    // Log additional debug info from server
         | 
| 802 802 | 
             
                    if (response.original_working_dir) {
         | 
| 803 803 | 
             
                        console.log('[GIT-BRANCH-DEBUG] Server received original working_dir:', this.repr(response.original_working_dir));
         | 
| @@ -826,7 +826,7 @@ class WorkingDirectoryManager { | |
| 826 826 | 
             
                 */
         | 
| 827 827 | 
             
                whenDirectoryReady(callback, timeout = 5000) {
         | 
| 828 828 | 
             
                    const startTime = Date.now();
         | 
| 829 | 
            -
             | 
| 829 | 
            +
             | 
| 830 830 | 
             
                    const checkReady = () => {
         | 
| 831 831 | 
             
                        if (this.isWorkingDirectoryReady()) {
         | 
| 832 832 | 
             
                            callback();
         | 
| @@ -836,7 +836,7 @@ class WorkingDirectoryManager { | |
| 836 836 | 
             
                            console.warn('[WORKING-DIR-DEBUG] Timeout waiting for directory to be ready');
         | 
| 837 837 | 
             
                        }
         | 
| 838 838 | 
             
                    };
         | 
| 839 | 
            -
             | 
| 839 | 
            +
             | 
| 840 840 | 
             
                    checkReady();
         | 
| 841 841 | 
             
                }
         | 
| 842 842 |  | 
| @@ -860,7 +860,10 @@ class WorkingDirectoryManager { | |
| 860 860 | 
             
                        this.footerDirObserver.disconnect();
         | 
| 861 861 | 
             
                        this.footerDirObserver = null;
         | 
| 862 862 | 
             
                    }
         | 
| 863 | 
            -
             | 
| 863 | 
            +
             | 
| 864 864 | 
             
                    console.log('Working directory manager cleaned up');
         | 
| 865 865 | 
             
                }
         | 
| 866 | 
            -
            }
         | 
| 866 | 
            +
            }
         | 
| 867 | 
            +
            // ES6 Module export
         | 
| 868 | 
            +
            export { WorkingDirectoryManager };
         | 
| 869 | 
            +
            export default WorkingDirectoryManager;
         |