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
| @@ -4,35 +4,35 @@ This module provides a centralized PathOperations class for common path validati | |
| 4 4 | 
             
            and file operations, reducing code duplication across the codebase.
         | 
| 5 5 | 
             
            """
         | 
| 6 6 |  | 
| 7 | 
            +
            import logging
         | 
| 7 8 | 
             
            import os
         | 
| 8 9 | 
             
            import shutil
         | 
| 9 10 | 
             
            import tempfile
         | 
| 10 11 | 
             
            from pathlib import Path
         | 
| 11 | 
            -
            from typing import  | 
| 12 | 
            -
            import logging
         | 
| 12 | 
            +
            from typing import Callable, List, Optional, Union
         | 
| 13 13 |  | 
| 14 14 | 
             
            logger = logging.getLogger(__name__)
         | 
| 15 15 |  | 
| 16 16 |  | 
| 17 17 | 
             
            class PathOperations:
         | 
| 18 18 | 
             
                """Utility class for path validation and safe file operations."""
         | 
| 19 | 
            -
             | 
| 20 | 
            -
                def __init__(self, default_encoding: str =  | 
| 19 | 
            +
             | 
| 20 | 
            +
                def __init__(self, default_encoding: str = "utf-8"):
         | 
| 21 21 | 
             
                    """Initialize PathOperations with default encoding.
         | 
| 22 | 
            -
             | 
| 22 | 
            +
             | 
| 23 23 | 
             
                    Args:
         | 
| 24 24 | 
             
                        default_encoding: Default encoding for file operations
         | 
| 25 25 | 
             
                    """
         | 
| 26 26 | 
             
                    self.default_encoding = default_encoding
         | 
| 27 | 
            -
             | 
| 27 | 
            +
             | 
| 28 28 | 
             
                # Path Validation Methods
         | 
| 29 | 
            -
             | 
| 29 | 
            +
             | 
| 30 30 | 
             
                def validate_exists(self, path: Union[str, Path]) -> bool:
         | 
| 31 31 | 
             
                    """Check if path exists.
         | 
| 32 | 
            -
             | 
| 32 | 
            +
             | 
| 33 33 | 
             
                    Args:
         | 
| 34 34 | 
             
                        path: Path to validate
         | 
| 35 | 
            -
             | 
| 35 | 
            +
             | 
| 36 36 | 
             
                    Returns:
         | 
| 37 37 | 
             
                        True if path exists, False otherwise
         | 
| 38 38 | 
             
                    """
         | 
| @@ -41,13 +41,13 @@ class PathOperations: | |
| 41 41 | 
             
                    except Exception as e:
         | 
| 42 42 | 
             
                        logger.error(f"Error checking path existence: {e}")
         | 
| 43 43 | 
             
                        return False
         | 
| 44 | 
            -
             | 
| 44 | 
            +
             | 
| 45 45 | 
             
                def validate_is_file(self, path: Union[str, Path]) -> bool:
         | 
| 46 46 | 
             
                    """Check if path is a file.
         | 
| 47 | 
            -
             | 
| 47 | 
            +
             | 
| 48 48 | 
             
                    Args:
         | 
| 49 49 | 
             
                        path: Path to validate
         | 
| 50 | 
            -
             | 
| 50 | 
            +
             | 
| 51 51 | 
             
                    Returns:
         | 
| 52 52 | 
             
                        True if path is a file, False otherwise
         | 
| 53 53 | 
             
                    """
         | 
| @@ -56,13 +56,13 @@ class PathOperations: | |
| 56 56 | 
             
                    except Exception as e:
         | 
| 57 57 | 
             
                        logger.error(f"Error checking if path is file: {e}")
         | 
| 58 58 | 
             
                        return False
         | 
| 59 | 
            -
             | 
| 59 | 
            +
             | 
| 60 60 | 
             
                def validate_is_dir(self, path: Union[str, Path]) -> bool:
         | 
| 61 61 | 
             
                    """Check if path is a directory.
         | 
| 62 | 
            -
             | 
| 62 | 
            +
             | 
| 63 63 | 
             
                    Args:
         | 
| 64 64 | 
             
                        path: Path to validate
         | 
| 65 | 
            -
             | 
| 65 | 
            +
             | 
| 66 66 | 
             
                    Returns:
         | 
| 67 67 | 
             
                        True if path is a directory, False otherwise
         | 
| 68 68 | 
             
                    """
         | 
| @@ -71,13 +71,13 @@ class PathOperations: | |
| 71 71 | 
             
                    except Exception as e:
         | 
| 72 72 | 
             
                        logger.error(f"Error checking if path is directory: {e}")
         | 
| 73 73 | 
             
                        return False
         | 
| 74 | 
            -
             | 
| 74 | 
            +
             | 
| 75 75 | 
             
                def validate_readable(self, path: Union[str, Path]) -> bool:
         | 
| 76 76 | 
             
                    """Check if path has read permissions.
         | 
| 77 | 
            -
             | 
| 77 | 
            +
             | 
| 78 78 | 
             
                    Args:
         | 
| 79 79 | 
             
                        path: Path to validate
         | 
| 80 | 
            -
             | 
| 80 | 
            +
             | 
| 81 81 | 
             
                    Returns:
         | 
| 82 82 | 
             
                        True if path is readable, False otherwise
         | 
| 83 83 | 
             
                    """
         | 
| @@ -89,13 +89,13 @@ class PathOperations: | |
| 89 89 | 
             
                    except Exception as e:
         | 
| 90 90 | 
             
                        logger.error(f"Error checking read permissions: {e}")
         | 
| 91 91 | 
             
                        return False
         | 
| 92 | 
            -
             | 
| 92 | 
            +
             | 
| 93 93 | 
             
                def validate_writable(self, path: Union[str, Path]) -> bool:
         | 
| 94 94 | 
             
                    """Check if path has write permissions.
         | 
| 95 | 
            -
             | 
| 95 | 
            +
             | 
| 96 96 | 
             
                    Args:
         | 
| 97 97 | 
             
                        path: Path to validate
         | 
| 98 | 
            -
             | 
| 98 | 
            +
             | 
| 99 99 | 
             
                    Returns:
         | 
| 100 100 | 
             
                        True if path is writable, False otherwise
         | 
| 101 101 | 
             
                    """
         | 
| @@ -109,19 +109,22 @@ class PathOperations: | |
| 109 109 | 
             
                    except Exception as e:
         | 
| 110 110 | 
             
                        logger.error(f"Error checking write permissions: {e}")
         | 
| 111 111 | 
             
                        return False
         | 
| 112 | 
            -
             | 
| 112 | 
            +
             | 
| 113 113 | 
             
                # Safe File Operations
         | 
| 114 | 
            -
             | 
| 115 | 
            -
                def safe_read( | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 114 | 
            +
             | 
| 115 | 
            +
                def safe_read(
         | 
| 116 | 
            +
                    self,
         | 
| 117 | 
            +
                    path: Union[str, Path],
         | 
| 118 | 
            +
                    encoding: Optional[str] = None,
         | 
| 119 | 
            +
                    default: Optional[str] = None,
         | 
| 120 | 
            +
                ) -> Optional[str]:
         | 
| 118 121 | 
             
                    """Read file with error handling.
         | 
| 119 | 
            -
             | 
| 122 | 
            +
             | 
| 120 123 | 
             
                    Args:
         | 
| 121 124 | 
             
                        path: Path to read
         | 
| 122 125 | 
             
                        encoding: File encoding (uses default if None)
         | 
| 123 126 | 
             
                        default: Default value if read fails
         | 
| 124 | 
            -
             | 
| 127 | 
            +
             | 
| 125 128 | 
             
                    Returns:
         | 
| 126 129 | 
             
                        File contents or default value
         | 
| 127 130 | 
             
                    """
         | 
| @@ -131,76 +134,77 @@ class PathOperations: | |
| 131 134 | 
             
                        if not self.validate_readable(path_obj):
         | 
| 132 135 | 
             
                            logger.warning(f"File not readable: {path}")
         | 
| 133 136 | 
             
                            return default
         | 
| 134 | 
            -
             | 
| 135 | 
            -
                        with open(path_obj,  | 
| 137 | 
            +
             | 
| 138 | 
            +
                        with open(path_obj, "r", encoding=encoding) as f:
         | 
| 136 139 | 
             
                            return f.read()
         | 
| 137 140 | 
             
                    except Exception as e:
         | 
| 138 141 | 
             
                        logger.error(f"Error reading file {path}: {e}")
         | 
| 139 142 | 
             
                        return default
         | 
| 140 | 
            -
             | 
| 141 | 
            -
                def safe_write( | 
| 142 | 
            -
             | 
| 143 | 
            -
             | 
| 144 | 
            -
             | 
| 145 | 
            -
             | 
| 143 | 
            +
             | 
| 144 | 
            +
                def safe_write(
         | 
| 145 | 
            +
                    self,
         | 
| 146 | 
            +
                    path: Union[str, Path],
         | 
| 147 | 
            +
                    content: str,
         | 
| 148 | 
            +
                    encoding: Optional[str] = None,
         | 
| 149 | 
            +
                    backup: bool = False,
         | 
| 150 | 
            +
                    atomic: bool = False,
         | 
| 151 | 
            +
                ) -> bool:
         | 
| 146 152 | 
             
                    """Write file with error handling and optional backup.
         | 
| 147 | 
            -
             | 
| 153 | 
            +
             | 
| 148 154 | 
             
                    Args:
         | 
| 149 155 | 
             
                        path: Path to write
         | 
| 150 156 | 
             
                        content: Content to write
         | 
| 151 157 | 
             
                        encoding: File encoding (uses default if None)
         | 
| 152 158 | 
             
                        backup: Create backup before writing
         | 
| 153 159 | 
             
                        atomic: Use atomic write (write to temp file and move)
         | 
| 154 | 
            -
             | 
| 160 | 
            +
             | 
| 155 161 | 
             
                    Returns:
         | 
| 156 162 | 
             
                        True if write successful, False otherwise
         | 
| 157 163 | 
             
                    """
         | 
| 158 164 | 
             
                    encoding = encoding or self.default_encoding
         | 
| 159 165 | 
             
                    path_obj = Path(path)
         | 
| 160 | 
            -
             | 
| 166 | 
            +
             | 
| 161 167 | 
             
                    try:
         | 
| 162 168 | 
             
                        # Create backup if requested
         | 
| 163 169 | 
             
                        if backup and path_obj.exists():
         | 
| 164 | 
            -
                            backup_path = path_obj.with_suffix(path_obj.suffix +  | 
| 170 | 
            +
                            backup_path = path_obj.with_suffix(path_obj.suffix + ".bak")
         | 
| 165 171 | 
             
                            shutil.copy2(str(path_obj), str(backup_path))
         | 
| 166 172 | 
             
                            logger.info(f"Created backup: {backup_path}")
         | 
| 167 | 
            -
             | 
| 173 | 
            +
             | 
| 168 174 | 
             
                        # Ensure parent directory exists
         | 
| 169 175 | 
             
                        path_obj.parent.mkdir(parents=True, exist_ok=True)
         | 
| 170 | 
            -
             | 
| 176 | 
            +
             | 
| 171 177 | 
             
                        if atomic:
         | 
| 172 178 | 
             
                            # Atomic write: write to temp file then move
         | 
| 173 179 | 
             
                            with tempfile.NamedTemporaryFile(
         | 
| 174 | 
            -
                                mode= | 
| 175 | 
            -
                                encoding=encoding,
         | 
| 176 | 
            -
                                dir=path_obj.parent,
         | 
| 177 | 
            -
                                delete=False
         | 
| 180 | 
            +
                                mode="w", encoding=encoding, dir=path_obj.parent, delete=False
         | 
| 178 181 | 
             
                            ) as tmp_file:
         | 
| 179 182 | 
             
                                tmp_file.write(content)
         | 
| 180 183 | 
             
                                tmp_path = tmp_file.name
         | 
| 181 | 
            -
             | 
| 184 | 
            +
             | 
| 182 185 | 
             
                            # Move temp file to target
         | 
| 183 186 | 
             
                            shutil.move(tmp_path, str(path_obj))
         | 
| 184 187 | 
             
                        else:
         | 
| 185 188 | 
             
                            # Direct write
         | 
| 186 | 
            -
                            with open(path_obj,  | 
| 189 | 
            +
                            with open(path_obj, "w", encoding=encoding) as f:
         | 
| 187 190 | 
             
                                f.write(content)
         | 
| 188 | 
            -
             | 
| 191 | 
            +
             | 
| 189 192 | 
             
                        logger.info(f"Successfully wrote to {path}")
         | 
| 190 193 | 
             
                        return True
         | 
| 191 | 
            -
             | 
| 194 | 
            +
             | 
| 192 195 | 
             
                    except Exception as e:
         | 
| 193 196 | 
             
                        logger.error(f"Error writing file {path}: {e}")
         | 
| 194 197 | 
             
                        return False
         | 
| 195 | 
            -
             | 
| 196 | 
            -
                def safe_delete( | 
| 197 | 
            -
             | 
| 198 | 
            +
             | 
| 199 | 
            +
                def safe_delete(
         | 
| 200 | 
            +
                    self, path: Union[str, Path], confirm: Optional[Callable[[], bool]] = None
         | 
| 201 | 
            +
                ) -> bool:
         | 
| 198 202 | 
             
                    """Delete file/directory with optional confirmation.
         | 
| 199 | 
            -
             | 
| 203 | 
            +
             | 
| 200 204 | 
             
                    Args:
         | 
| 201 205 | 
             
                        path: Path to delete
         | 
| 202 206 | 
             
                        confirm: Optional confirmation callback
         | 
| 203 | 
            -
             | 
| 207 | 
            +
             | 
| 204 208 | 
             
                    Returns:
         | 
| 205 209 | 
             
                        True if delete successful, False otherwise
         | 
| 206 210 | 
             
                    """
         | 
| @@ -209,74 +213,74 @@ class PathOperations: | |
| 209 213 | 
             
                        if not path_obj.exists():
         | 
| 210 214 | 
             
                            logger.warning(f"Path does not exist: {path}")
         | 
| 211 215 | 
             
                            return True
         | 
| 212 | 
            -
             | 
| 216 | 
            +
             | 
| 213 217 | 
             
                        # Confirm if callback provided
         | 
| 214 218 | 
             
                        if confirm and not confirm():
         | 
| 215 219 | 
             
                            logger.info(f"Delete cancelled by user: {path}")
         | 
| 216 220 | 
             
                            return False
         | 
| 217 | 
            -
             | 
| 221 | 
            +
             | 
| 218 222 | 
             
                        if path_obj.is_file():
         | 
| 219 223 | 
             
                            path_obj.unlink()
         | 
| 220 224 | 
             
                        else:
         | 
| 221 225 | 
             
                            shutil.rmtree(str(path_obj))
         | 
| 222 | 
            -
             | 
| 226 | 
            +
             | 
| 223 227 | 
             
                        logger.info(f"Successfully deleted: {path}")
         | 
| 224 228 | 
             
                        return True
         | 
| 225 | 
            -
             | 
| 229 | 
            +
             | 
| 226 230 | 
             
                    except Exception as e:
         | 
| 227 231 | 
             
                        logger.error(f"Error deleting {path}: {e}")
         | 
| 228 232 | 
             
                        return False
         | 
| 229 | 
            -
             | 
| 230 | 
            -
                def safe_copy( | 
| 231 | 
            -
             | 
| 232 | 
            -
             | 
| 233 | 
            +
             | 
| 234 | 
            +
                def safe_copy(
         | 
| 235 | 
            +
                    self, src: Union[str, Path], dst: Union[str, Path], overwrite: bool = False
         | 
| 236 | 
            +
                ) -> bool:
         | 
| 233 237 | 
             
                    """Copy file/directory with overwrite protection.
         | 
| 234 | 
            -
             | 
| 238 | 
            +
             | 
| 235 239 | 
             
                    Args:
         | 
| 236 240 | 
             
                        src: Source path
         | 
| 237 241 | 
             
                        dst: Destination path
         | 
| 238 242 | 
             
                        overwrite: Allow overwriting existing files
         | 
| 239 | 
            -
             | 
| 243 | 
            +
             | 
| 240 244 | 
             
                    Returns:
         | 
| 241 245 | 
             
                        True if copy successful, False otherwise
         | 
| 242 246 | 
             
                    """
         | 
| 243 247 | 
             
                    try:
         | 
| 244 248 | 
             
                        src_path = Path(src)
         | 
| 245 249 | 
             
                        dst_path = Path(dst)
         | 
| 246 | 
            -
             | 
| 250 | 
            +
             | 
| 247 251 | 
             
                        if not src_path.exists():
         | 
| 248 252 | 
             
                            logger.error(f"Source does not exist: {src}")
         | 
| 249 253 | 
             
                            return False
         | 
| 250 | 
            -
             | 
| 254 | 
            +
             | 
| 251 255 | 
             
                        if dst_path.exists() and not overwrite:
         | 
| 252 256 | 
             
                            logger.error(f"Destination exists and overwrite=False: {dst}")
         | 
| 253 257 | 
             
                            return False
         | 
| 254 | 
            -
             | 
| 258 | 
            +
             | 
| 255 259 | 
             
                        # Ensure parent directory exists
         | 
| 256 260 | 
             
                        dst_path.parent.mkdir(parents=True, exist_ok=True)
         | 
| 257 | 
            -
             | 
| 261 | 
            +
             | 
| 258 262 | 
             
                        if src_path.is_file():
         | 
| 259 263 | 
             
                            shutil.copy2(str(src_path), str(dst_path))
         | 
| 260 264 | 
             
                        else:
         | 
| 261 265 | 
             
                            if dst_path.exists():
         | 
| 262 266 | 
             
                                shutil.rmtree(str(dst_path))
         | 
| 263 267 | 
             
                            shutil.copytree(str(src_path), str(dst_path))
         | 
| 264 | 
            -
             | 
| 268 | 
            +
             | 
| 265 269 | 
             
                        logger.info(f"Successfully copied {src} to {dst}")
         | 
| 266 270 | 
             
                        return True
         | 
| 267 | 
            -
             | 
| 271 | 
            +
             | 
| 268 272 | 
             
                    except Exception as e:
         | 
| 269 273 | 
             
                        logger.error(f"Error copying {src} to {dst}: {e}")
         | 
| 270 274 | 
             
                        return False
         | 
| 271 | 
            -
             | 
| 275 | 
            +
             | 
| 272 276 | 
             
                # Common Patterns
         | 
| 273 | 
            -
             | 
| 277 | 
            +
             | 
| 274 278 | 
             
                def ensure_dir(self, path: Union[str, Path]) -> bool:
         | 
| 275 279 | 
             
                    """Create directory if it doesn't exist.
         | 
| 276 | 
            -
             | 
| 280 | 
            +
             | 
| 277 281 | 
             
                    Args:
         | 
| 278 282 | 
             
                        path: Directory path to ensure
         | 
| 279 | 
            -
             | 
| 283 | 
            +
             | 
| 280 284 | 
             
                    Returns:
         | 
| 281 285 | 
             
                        True if directory exists or was created, False otherwise
         | 
| 282 286 | 
             
                    """
         | 
| @@ -286,13 +290,13 @@ class PathOperations: | |
| 286 290 | 
             
                    except Exception as e:
         | 
| 287 291 | 
             
                        logger.error(f"Error creating directory {path}: {e}")
         | 
| 288 292 | 
             
                        return False
         | 
| 289 | 
            -
             | 
| 293 | 
            +
             | 
| 290 294 | 
             
                def get_size(self, path: Union[str, Path]) -> int:
         | 
| 291 295 | 
             
                    """Get size of file or directory in bytes.
         | 
| 292 | 
            -
             | 
| 296 | 
            +
             | 
| 293 297 | 
             
                    Args:
         | 
| 294 298 | 
             
                        path: Path to measure
         | 
| 295 | 
            -
             | 
| 299 | 
            +
             | 
| 296 300 | 
             
                    Returns:
         | 
| 297 301 | 
             
                        Size in bytes, or -1 on error
         | 
| 298 302 | 
             
                    """
         | 
| @@ -300,33 +304,36 @@ class PathOperations: | |
| 300 304 | 
             
                        path_obj = Path(path)
         | 
| 301 305 | 
             
                        if not path_obj.exists():
         | 
| 302 306 | 
             
                            return -1
         | 
| 303 | 
            -
             | 
| 307 | 
            +
             | 
| 304 308 | 
             
                        if path_obj.is_file():
         | 
| 305 309 | 
             
                            return path_obj.stat().st_size
         | 
| 306 310 | 
             
                        else:
         | 
| 307 311 | 
             
                            # Calculate total size for directory
         | 
| 308 312 | 
             
                            total = 0
         | 
| 309 | 
            -
                            for item in path_obj.rglob( | 
| 313 | 
            +
                            for item in path_obj.rglob("*"):
         | 
| 310 314 | 
             
                                if item.is_file():
         | 
| 311 315 | 
             
                                    total += item.stat().st_size
         | 
| 312 316 | 
             
                            return total
         | 
| 313 | 
            -
             | 
| 317 | 
            +
             | 
| 314 318 | 
             
                    except Exception as e:
         | 
| 315 319 | 
             
                        logger.error(f"Error getting size of {path}: {e}")
         | 
| 316 320 | 
             
                        return -1
         | 
| 317 | 
            -
             | 
| 318 | 
            -
                def list_files( | 
| 319 | 
            -
             | 
| 320 | 
            -
             | 
| 321 | 
            -
             | 
| 321 | 
            +
             | 
| 322 | 
            +
                def list_files(
         | 
| 323 | 
            +
                    self,
         | 
| 324 | 
            +
                    path: Union[str, Path],
         | 
| 325 | 
            +
                    pattern: str = "*",
         | 
| 326 | 
            +
                    recursive: bool = False,
         | 
| 327 | 
            +
                    include_dirs: bool = False,
         | 
| 328 | 
            +
                ) -> List[Path]:
         | 
| 322 329 | 
             
                    """List files in directory with filtering.
         | 
| 323 | 
            -
             | 
| 330 | 
            +
             | 
| 324 331 | 
             
                    Args:
         | 
| 325 332 | 
             
                        path: Directory path
         | 
| 326 333 | 
             
                        pattern: Glob pattern for filtering
         | 
| 327 334 | 
             
                        recursive: Search recursively
         | 
| 328 335 | 
             
                        include_dirs: Include directories in results
         | 
| 329 | 
            -
             | 
| 336 | 
            +
             | 
| 330 337 | 
             
                    Returns:
         | 
| 331 338 | 
             
                        List of matching paths
         | 
| 332 339 | 
             
                    """
         | 
| @@ -335,23 +342,23 @@ class PathOperations: | |
| 335 342 | 
             
                        if not path_obj.is_dir():
         | 
| 336 343 | 
             
                            logger.error(f"Not a directory: {path}")
         | 
| 337 344 | 
             
                            return []
         | 
| 338 | 
            -
             | 
| 345 | 
            +
             | 
| 339 346 | 
             
                        if recursive:
         | 
| 340 347 | 
             
                            items = path_obj.rglob(pattern)
         | 
| 341 348 | 
             
                        else:
         | 
| 342 349 | 
             
                            items = path_obj.glob(pattern)
         | 
| 343 | 
            -
             | 
| 350 | 
            +
             | 
| 344 351 | 
             
                        results = []
         | 
| 345 352 | 
             
                        for item in items:
         | 
| 346 353 | 
             
                            if item.is_file() or (include_dirs and item.is_dir()):
         | 
| 347 354 | 
             
                                results.append(item)
         | 
| 348 | 
            -
             | 
| 355 | 
            +
             | 
| 349 356 | 
             
                        return sorted(results)
         | 
| 350 | 
            -
             | 
| 357 | 
            +
             | 
| 351 358 | 
             
                    except Exception as e:
         | 
| 352 359 | 
             
                        logger.error(f"Error listing files in {path}: {e}")
         | 
| 353 360 | 
             
                        return []
         | 
| 354 361 |  | 
| 355 362 |  | 
| 356 363 | 
             
            # Convenience instance for direct imports
         | 
| 357 | 
            -
            path_ops = PathOperations()
         | 
| 364 | 
            +
            path_ops = PathOperations()
         |