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
| @@ -3,7 +3,7 @@ Framework Agent Loader Service | |
| 3 3 |  | 
| 4 4 | 
             
            Implements agent profile loading logic based on directory hierarchy:
         | 
| 5 5 | 
             
            1. Project .claude-mpm (in project root): project agents - HIGHEST PRECEDENCE
         | 
| 6 | 
            -
            2. User .claude-mpm (~/.claude-mpm): user agents - MEDIUM PRECEDENCE | 
| 6 | 
            +
            2. User .claude-mpm (~/.claude-mpm): user agents - MEDIUM PRECEDENCE
         | 
| 7 7 | 
             
            3. Framework/System agents: built-in agents - LOWEST PRECEDENCE
         | 
| 8 8 |  | 
| 9 9 | 
             
            Loading precedence: Project → User → System
         | 
| @@ -12,71 +12,80 @@ This service integrates with the main agent_loader.py to provide | |
| 12 12 | 
             
            markdown-based agent profiles alongside JSON-based templates.
         | 
| 13 13 | 
             
            """
         | 
| 14 14 |  | 
| 15 | 
            -
            import os
         | 
| 16 15 | 
             
            import json
         | 
| 17 | 
            -
            from pathlib import Path
         | 
| 18 | 
            -
            from typing import Dict, Optional, Any
         | 
| 19 16 | 
             
            import logging
         | 
| 17 | 
            +
            from pathlib import Path
         | 
| 18 | 
            +
            from typing import Any, Dict, Optional
         | 
| 20 19 |  | 
| 21 | 
            -
            from claude_mpm. | 
| 22 | 
            -
             | 
| 20 | 
            +
            from claude_mpm.agents.agent_loader import (
         | 
| 21 | 
            +
                AgentTier,
         | 
| 22 | 
            +
                get_agent_tier,
         | 
| 23 | 
            +
                list_agents_by_tier,
         | 
| 24 | 
            +
            )
         | 
| 25 | 
            +
            from claude_mpm.core.unified_paths import get_path_manager
         | 
| 23 26 |  | 
| 24 27 | 
             
            logger = logging.getLogger(__name__)
         | 
| 25 28 |  | 
| 29 | 
            +
             | 
| 26 30 | 
             
            class FrameworkAgentLoader:
         | 
| 27 31 | 
             
                """Loads agent profiles from project, user, and system directories with proper precedence"""
         | 
| 28 | 
            -
             | 
| 32 | 
            +
             | 
| 29 33 | 
             
                def __init__(self):
         | 
| 30 34 | 
             
                    self.project_agents_dir = None
         | 
| 31 35 | 
             
                    self.user_agents_dir = None
         | 
| 32 36 | 
             
                    self.system_agents_dir = None
         | 
| 33 37 | 
             
                    self._profile_cache = {}
         | 
| 34 38 | 
             
                    self._tier_mapping = {
         | 
| 35 | 
            -
                        AgentTier.PROJECT:  | 
| 36 | 
            -
                        AgentTier.USER:  | 
| 37 | 
            -
                        AgentTier.SYSTEM:  | 
| 39 | 
            +
                        AgentTier.PROJECT: "project",
         | 
| 40 | 
            +
                        AgentTier.USER: "user",
         | 
| 41 | 
            +
                        AgentTier.SYSTEM: "system",
         | 
| 38 42 | 
             
                    }
         | 
| 39 | 
            -
             | 
| 43 | 
            +
             | 
| 40 44 | 
             
                def initialize(self, framework_claude_md_path: Optional[str] = None):
         | 
| 41 45 | 
             
                    """
         | 
| 42 46 | 
             
                    Initialize loader with project, user, and system directory detection
         | 
| 43 | 
            -
             | 
| 47 | 
            +
             | 
| 44 48 | 
             
                    Args:
         | 
| 45 49 | 
             
                        framework_claude_md_path: Optional explicit path to agents/INSTRUCTIONS.md or CLAUDE.md
         | 
| 46 50 | 
             
                    """
         | 
| 47 51 | 
             
                    # Find project .claude-mpm directory (highest precedence)
         | 
| 48 52 | 
             
                    project_dir = self._find_project_directory()
         | 
| 49 53 | 
             
                    if project_dir:
         | 
| 50 | 
            -
                        self.project_agents_dir =  | 
| 54 | 
            +
                        self.project_agents_dir = (
         | 
| 55 | 
            +
                            project_dir / get_path_manager().CONFIG_DIR / "agents"
         | 
| 56 | 
            +
                        )
         | 
| 51 57 | 
             
                        logger.info(f"Project agents directory: {self.project_agents_dir}")
         | 
| 52 | 
            -
             | 
| 58 | 
            +
             | 
| 53 59 | 
             
                    # Find user .claude-mpm directory (medium precedence)
         | 
| 54 | 
            -
                    user_config_dir =  | 
| 60 | 
            +
                    user_config_dir = get_path_manager().get_user_config_dir()
         | 
| 55 61 | 
             
                    if user_config_dir:
         | 
| 56 62 | 
             
                        self.user_agents_dir = user_config_dir / "agents"
         | 
| 57 63 | 
             
                        if self.user_agents_dir.exists():
         | 
| 58 64 | 
             
                            logger.info(f"User agents directory: {self.user_agents_dir}")
         | 
| 59 65 | 
             
                        else:
         | 
| 60 66 | 
             
                            self.user_agents_dir = None
         | 
| 61 | 
            -
             | 
| 67 | 
            +
             | 
| 62 68 | 
             
                    # Find system/framework agents directory (lowest precedence)
         | 
| 63 69 | 
             
                    if framework_claude_md_path:
         | 
| 64 70 | 
             
                        framework_dir = Path(framework_claude_md_path).parent.parent
         | 
| 65 71 | 
             
                    else:
         | 
| 66 72 | 
             
                        framework_dir = self._find_framework_directory()
         | 
| 67 | 
            -
             | 
| 73 | 
            +
             | 
| 68 74 | 
             
                    if framework_dir:
         | 
| 69 | 
            -
                        self.system_agents_dir =  | 
| 75 | 
            +
                        self.system_agents_dir = (
         | 
| 76 | 
            +
                            framework_dir / get_path_manager().CONFIG_DIR / "agents"
         | 
| 77 | 
            +
                        )
         | 
| 70 78 | 
             
                        logger.info(f"System agents directory: {self.system_agents_dir}")
         | 
| 71 | 
            -
             | 
| 79 | 
            +
             | 
| 72 80 | 
             
                def _find_framework_directory(self) -> Optional[Path]:
         | 
| 73 81 | 
             
                    """Find directory containing agents/INSTRUCTIONS.md (or legacy CLAUDE.md)"""
         | 
| 74 82 | 
             
                    # Check if we're running from a wheel installation
         | 
| 75 83 | 
             
                    try:
         | 
| 76 84 | 
             
                        import claude_pm
         | 
| 85 | 
            +
             | 
| 77 86 | 
             
                        package_path = Path(claude_pm.__file__).parent
         | 
| 78 87 | 
             
                        path_str = str(package_path.resolve())
         | 
| 79 | 
            -
                        if  | 
| 88 | 
            +
                        if "site-packages" in path_str or "dist-packages" in path_str:
         | 
| 80 89 | 
             
                            # For wheel installations, check data directory
         | 
| 81 90 | 
             
                            data_instructions = package_path / "data" / "agents" / "INSTRUCTIONS.md"
         | 
| 82 91 | 
             
                            data_claude = package_path / "data" / "agents" / "CLAUDE.md"
         | 
| @@ -84,40 +93,40 @@ class FrameworkAgentLoader: | |
| 84 93 | 
             
                                return package_path / "data"
         | 
| 85 94 | 
             
                    except Exception:
         | 
| 86 95 | 
             
                        pass
         | 
| 87 | 
            -
             | 
| 96 | 
            +
             | 
| 88 97 | 
             
                    current = Path.cwd()
         | 
| 89 | 
            -
             | 
| 98 | 
            +
             | 
| 90 99 | 
             
                    # Check current directory and parents
         | 
| 91 100 | 
             
                    for path in [current] + list(current.parents):
         | 
| 92 101 | 
             
                        framework_instructions = path / "agents" / "INSTRUCTIONS.md"
         | 
| 93 102 | 
             
                        framework_claude = path / "agents" / "CLAUDE.md"  # Legacy
         | 
| 94 103 | 
             
                        if framework_instructions.exists() or framework_claude.exists():
         | 
| 95 104 | 
             
                            return path
         | 
| 96 | 
            -
             | 
| 105 | 
            +
             | 
| 97 106 | 
             
                    return None
         | 
| 98 | 
            -
             | 
| 107 | 
            +
             | 
| 99 108 | 
             
                def _find_project_directory(self) -> Optional[Path]:
         | 
| 100 109 | 
             
                    """Find project directory containing .claude-mpm"""
         | 
| 101 110 | 
             
                    current = Path.cwd()
         | 
| 102 | 
            -
             | 
| 111 | 
            +
             | 
| 103 112 | 
             
                    # Check current directory and parents for .claude-mpm
         | 
| 104 113 | 
             
                    for path in [current] + list(current.parents):
         | 
| 105 | 
            -
                        claude_pm_dir = path /  | 
| 114 | 
            +
                        claude_pm_dir = path / get_path_manager().CONFIG_DIR
         | 
| 106 115 | 
             
                        if claude_pm_dir.exists():
         | 
| 107 116 | 
             
                            return path
         | 
| 108 | 
            -
             | 
| 117 | 
            +
             | 
| 109 118 | 
             
                    return None
         | 
| 110 | 
            -
             | 
| 119 | 
            +
             | 
| 111 120 | 
             
                def load_agent_profile(self, agent_type: str) -> Optional[Dict[str, Any]]:
         | 
| 112 121 | 
             
                    """
         | 
| 113 122 | 
             
                    Load agent profile with precedence: Project → User → System
         | 
| 114 | 
            -
             | 
| 123 | 
            +
             | 
| 115 124 | 
             
                    This method now properly integrates with the main agent_loader.py
         | 
| 116 125 | 
             
                    tier system for consistent precedence handling.
         | 
| 117 | 
            -
             | 
| 126 | 
            +
             | 
| 118 127 | 
             
                    Args:
         | 
| 119 128 | 
             
                        agent_type: Agent type (Engineer, Documenter, QA, etc.)
         | 
| 120 | 
            -
             | 
| 129 | 
            +
             | 
| 121 130 | 
             
                    Returns:
         | 
| 122 131 | 
             
                        Agent profile dictionary or None if not found
         | 
| 123 132 | 
             
                    """
         | 
| @@ -125,10 +134,10 @@ class FrameworkAgentLoader: | |
| 125 134 | 
             
                    cache_key = agent_type.lower()
         | 
| 126 135 | 
             
                    if cache_key in self._profile_cache:
         | 
| 127 136 | 
             
                        return self._profile_cache[cache_key]
         | 
| 128 | 
            -
             | 
| 137 | 
            +
             | 
| 129 138 | 
             
                    profile = None
         | 
| 130 139 | 
             
                    loaded_tier = None
         | 
| 131 | 
            -
             | 
| 140 | 
            +
             | 
| 132 141 | 
             
                    # 1. Try project agents first (highest precedence)
         | 
| 133 142 | 
             
                    if self.project_agents_dir:
         | 
| 134 143 | 
             
                        # Check both 'project' subdirectory and direct directory
         | 
| @@ -141,7 +150,7 @@ class FrameworkAgentLoader: | |
| 141 150 | 
             
                            )
         | 
| 142 151 | 
             
                        if profile:
         | 
| 143 152 | 
             
                            loaded_tier = AgentTier.PROJECT
         | 
| 144 | 
            -
             | 
| 153 | 
            +
             | 
| 145 154 | 
             
                    # 2. Try user agents (medium precedence)
         | 
| 146 155 | 
             
                    if not profile and self.user_agents_dir:
         | 
| 147 156 | 
             
                        # Check both 'user' subdirectory and direct directory
         | 
| @@ -154,7 +163,7 @@ class FrameworkAgentLoader: | |
| 154 163 | 
             
                            )
         | 
| 155 164 | 
             
                        if profile:
         | 
| 156 165 | 
             
                            loaded_tier = AgentTier.USER
         | 
| 157 | 
            -
             | 
| 166 | 
            +
             | 
| 158 167 | 
             
                    # 3. Try system agents (lowest precedence)
         | 
| 159 168 | 
             
                    if not profile and self.system_agents_dir:
         | 
| 160 169 | 
             
                        # Check subdirectories in order: trained → system
         | 
| @@ -165,7 +174,7 @@ class FrameworkAgentLoader: | |
| 165 174 | 
             
                            if profile:
         | 
| 166 175 | 
             
                                loaded_tier = AgentTier.SYSTEM
         | 
| 167 176 | 
             
                                break
         | 
| 168 | 
            -
             | 
| 177 | 
            +
             | 
| 169 178 | 
             
                        # Also check root system directory
         | 
| 170 179 | 
             
                        if not profile:
         | 
| 171 180 | 
             
                            profile = self._load_profile_from_directory(
         | 
| @@ -173,93 +182,95 @@ class FrameworkAgentLoader: | |
| 173 182 | 
             
                            )
         | 
| 174 183 | 
             
                            if profile:
         | 
| 175 184 | 
             
                                loaded_tier = AgentTier.SYSTEM
         | 
| 176 | 
            -
             | 
| 185 | 
            +
             | 
| 177 186 | 
             
                    # Add tier information to profile
         | 
| 178 187 | 
             
                    if profile and loaded_tier:
         | 
| 179 | 
            -
                        profile[ | 
| 188 | 
            +
                        profile["_tier"] = loaded_tier.value
         | 
| 180 189 | 
             
                        logger.debug(f"Loaded {agent_type} profile from {loaded_tier.value} tier")
         | 
| 181 | 
            -
             | 
| 190 | 
            +
             | 
| 182 191 | 
             
                    # Cache result
         | 
| 183 192 | 
             
                    if profile:
         | 
| 184 193 | 
             
                        self._profile_cache[cache_key] = profile
         | 
| 185 | 
            -
             | 
| 194 | 
            +
             | 
| 186 195 | 
             
                    return profile
         | 
| 187 | 
            -
             | 
| 188 | 
            -
                def _load_profile_from_directory( | 
| 196 | 
            +
             | 
| 197 | 
            +
                def _load_profile_from_directory(
         | 
| 198 | 
            +
                    self, directory: Path, agent_type: str
         | 
| 199 | 
            +
                ) -> Optional[Dict[str, Any]]:
         | 
| 189 200 | 
             
                    """Load agent profile from specific directory"""
         | 
| 190 201 | 
             
                    if not directory.exists():
         | 
| 191 202 | 
             
                        return None
         | 
| 192 | 
            -
             | 
| 203 | 
            +
             | 
| 193 204 | 
             
                    profile_file = directory / f"{agent_type}.md"
         | 
| 194 205 | 
             
                    if not profile_file.exists():
         | 
| 195 206 | 
             
                        return None
         | 
| 196 | 
            -
             | 
| 207 | 
            +
             | 
| 197 208 | 
             
                    try:
         | 
| 198 | 
            -
                        content = profile_file.read_text(encoding= | 
| 209 | 
            +
                        content = profile_file.read_text(encoding="utf-8")
         | 
| 199 210 | 
             
                        return self._parse_agent_profile(content, str(profile_file))
         | 
| 200 211 | 
             
                    except Exception as e:
         | 
| 201 212 | 
             
                        logger.error(f"Error loading profile {profile_file}: {e}")
         | 
| 202 213 | 
             
                        return None
         | 
| 203 | 
            -
             | 
| 214 | 
            +
             | 
| 204 215 | 
             
                def _parse_agent_profile(self, content: str, source_path: str) -> Dict[str, Any]:
         | 
| 205 216 | 
             
                    """Parse agent profile markdown into structured data"""
         | 
| 206 217 | 
             
                    profile = {
         | 
| 207 | 
            -
                         | 
| 208 | 
            -
                         | 
| 209 | 
            -
                         | 
| 210 | 
            -
                         | 
| 211 | 
            -
                         | 
| 212 | 
            -
                         | 
| 213 | 
            -
                         | 
| 214 | 
            -
                         | 
| 215 | 
            -
                         | 
| 218 | 
            +
                        "source_path": source_path,
         | 
| 219 | 
            +
                        "raw_content": content,
         | 
| 220 | 
            +
                        "role": "",
         | 
| 221 | 
            +
                        "capabilities": [],
         | 
| 222 | 
            +
                        "context_preferences": {},
         | 
| 223 | 
            +
                        "authority_scope": [],
         | 
| 224 | 
            +
                        "quality_standards": [],
         | 
| 225 | 
            +
                        "escalation_criteria": [],
         | 
| 226 | 
            +
                        "integration_patterns": {},
         | 
| 216 227 | 
             
                    }
         | 
| 217 | 
            -
             | 
| 218 | 
            -
                    lines = content.split( | 
| 228 | 
            +
             | 
| 229 | 
            +
                    lines = content.split("\n")
         | 
| 219 230 | 
             
                    current_section = None
         | 
| 220 231 | 
             
                    current_content = []
         | 
| 221 | 
            -
             | 
| 232 | 
            +
             | 
| 222 233 | 
             
                    for line in lines:
         | 
| 223 234 | 
             
                        line = line.strip()
         | 
| 224 | 
            -
             | 
| 235 | 
            +
             | 
| 225 236 | 
             
                        # Detect sections
         | 
| 226 | 
            -
                        if line.startswith( | 
| 237 | 
            +
                        if line.startswith("## Role"):
         | 
| 227 238 | 
             
                            # Process previous section
         | 
| 228 239 | 
             
                            if current_section and current_content:
         | 
| 229 240 | 
             
                                self._process_section(profile, current_section, current_content)
         | 
| 230 | 
            -
                            current_section =  | 
| 241 | 
            +
                            current_section = "role"
         | 
| 231 242 | 
             
                            current_content = []
         | 
| 232 | 
            -
                        elif line.startswith( | 
| 243 | 
            +
                        elif line.startswith("## Capabilities"):
         | 
| 233 244 | 
             
                            if current_section and current_content:
         | 
| 234 245 | 
             
                                self._process_section(profile, current_section, current_content)
         | 
| 235 | 
            -
                            current_section =  | 
| 246 | 
            +
                            current_section = "capabilities"
         | 
| 236 247 | 
             
                            current_content = []
         | 
| 237 | 
            -
                        elif line.startswith( | 
| 248 | 
            +
                        elif line.startswith("## Context Preferences"):
         | 
| 238 249 | 
             
                            if current_section and current_content:
         | 
| 239 250 | 
             
                                self._process_section(profile, current_section, current_content)
         | 
| 240 | 
            -
                            current_section =  | 
| 251 | 
            +
                            current_section = "context_preferences"
         | 
| 241 252 | 
             
                            current_content = []
         | 
| 242 | 
            -
                        elif line.startswith( | 
| 253 | 
            +
                        elif line.startswith("## Authority Scope"):
         | 
| 243 254 | 
             
                            if current_section and current_content:
         | 
| 244 255 | 
             
                                self._process_section(profile, current_section, current_content)
         | 
| 245 | 
            -
                            current_section =  | 
| 256 | 
            +
                            current_section = "authority_scope"
         | 
| 246 257 | 
             
                            current_content = []
         | 
| 247 | 
            -
                        elif line.startswith( | 
| 258 | 
            +
                        elif line.startswith("## Quality Standards"):
         | 
| 248 259 | 
             
                            if current_section and current_content:
         | 
| 249 260 | 
             
                                self._process_section(profile, current_section, current_content)
         | 
| 250 | 
            -
                            current_section =  | 
| 261 | 
            +
                            current_section = "quality_standards"
         | 
| 251 262 | 
             
                            current_content = []
         | 
| 252 | 
            -
                        elif line.startswith( | 
| 263 | 
            +
                        elif line.startswith("## Escalation Criteria"):
         | 
| 253 264 | 
             
                            if current_section and current_content:
         | 
| 254 265 | 
             
                                self._process_section(profile, current_section, current_content)
         | 
| 255 | 
            -
                            current_section =  | 
| 266 | 
            +
                            current_section = "escalation_criteria"
         | 
| 256 267 | 
             
                            current_content = []
         | 
| 257 | 
            -
                        elif line.startswith( | 
| 268 | 
            +
                        elif line.startswith("## Integration Patterns"):
         | 
| 258 269 | 
             
                            if current_section and current_content:
         | 
| 259 270 | 
             
                                self._process_section(profile, current_section, current_content)
         | 
| 260 | 
            -
                            current_section =  | 
| 271 | 
            +
                            current_section = "integration_patterns"
         | 
| 261 272 | 
             
                            current_content = []
         | 
| 262 | 
            -
                        elif line.startswith( | 
| 273 | 
            +
                        elif line.startswith("#"):
         | 
| 263 274 | 
             
                            # Process previous section before starting new one
         | 
| 264 275 | 
             
                            if current_section and current_content:
         | 
| 265 276 | 
             
                                self._process_section(profile, current_section, current_content)
         | 
| @@ -267,89 +278,103 @@ class FrameworkAgentLoader: | |
| 267 278 | 
             
                            current_content = []
         | 
| 268 279 | 
             
                        elif current_section and line:
         | 
| 269 280 | 
             
                            current_content.append(line)
         | 
| 270 | 
            -
             | 
| 281 | 
            +
             | 
| 271 282 | 
             
                    # Process final section
         | 
| 272 283 | 
             
                    if current_section and current_content:
         | 
| 273 284 | 
             
                        self._process_section(profile, current_section, current_content)
         | 
| 274 | 
            -
             | 
| 285 | 
            +
             | 
| 275 286 | 
             
                    return profile
         | 
| 276 | 
            -
             | 
| 287 | 
            +
             | 
| 277 288 | 
             
                def _process_section(self, profile: Dict[str, Any], section: str, content: list):
         | 
| 278 289 | 
             
                    """Process section content into profile structure"""
         | 
| 279 | 
            -
                    text =  | 
| 280 | 
            -
             | 
| 281 | 
            -
                    if section ==  | 
| 282 | 
            -
                        profile[ | 
| 283 | 
            -
                    elif section ==  | 
| 290 | 
            +
                    text = "\n".join(content).strip()
         | 
| 291 | 
            +
             | 
| 292 | 
            +
                    if section == "role":
         | 
| 293 | 
            +
                        profile["role"] = text
         | 
| 294 | 
            +
                    elif section == "capabilities":
         | 
| 284 295 | 
             
                        # Extract bullet points
         | 
| 285 296 | 
             
                        capabilities = []
         | 
| 286 297 | 
             
                        for line in content:
         | 
| 287 | 
            -
                            if line.startswith( | 
| 288 | 
            -
                                cap = line.split( | 
| 298 | 
            +
                            if line.startswith("- **") and "**:" in line:
         | 
| 299 | 
            +
                                cap = line.split("**:")[0].replace("- **", "").strip()
         | 
| 289 300 | 
             
                                capabilities.append(cap)
         | 
| 290 | 
            -
                        profile[ | 
| 291 | 
            -
                    elif section ==  | 
| 301 | 
            +
                        profile["capabilities"] = capabilities
         | 
| 302 | 
            +
                    elif section == "context_preferences":
         | 
| 292 303 | 
             
                        # Extract Include/Exclude/Focus
         | 
| 293 304 | 
             
                        prefs = {}
         | 
| 294 305 | 
             
                        for line in content:
         | 
| 295 | 
            -
                            if line.startswith( | 
| 296 | 
            -
                                prefs[ | 
| 297 | 
            -
                            elif line.startswith( | 
| 298 | 
            -
                                prefs[ | 
| 299 | 
            -
                            elif line.startswith( | 
| 300 | 
            -
                                prefs[ | 
| 301 | 
            -
                        profile[ | 
| 302 | 
            -
                    elif section in [ | 
| 306 | 
            +
                            if line.startswith("- **Include**:"):
         | 
| 307 | 
            +
                                prefs["include"] = line.replace("- **Include**:", "").strip()
         | 
| 308 | 
            +
                            elif line.startswith("- **Exclude**:"):
         | 
| 309 | 
            +
                                prefs["exclude"] = line.replace("- **Exclude**:", "").strip()
         | 
| 310 | 
            +
                            elif line.startswith("- **Focus**:"):
         | 
| 311 | 
            +
                                prefs["focus"] = line.replace("- **Focus**:", "").strip()
         | 
| 312 | 
            +
                        profile["context_preferences"] = prefs
         | 
| 313 | 
            +
                    elif section in ["authority_scope", "quality_standards", "escalation_criteria"]:
         | 
| 303 314 | 
             
                        # Extract bullet points
         | 
| 304 315 | 
             
                        items = []
         | 
| 305 316 | 
             
                        for line in content:
         | 
| 306 | 
            -
                            if line.startswith( | 
| 307 | 
            -
                                item = line.split( | 
| 317 | 
            +
                            if line.startswith("- **") and "**:" in line:
         | 
| 318 | 
            +
                                item = line.split("**:")[0].replace("- **", "").strip()
         | 
| 308 319 | 
             
                                items.append(item)
         | 
| 309 320 | 
             
                        profile[section] = items
         | 
| 310 | 
            -
                    elif section ==  | 
| 321 | 
            +
                    elif section == "integration_patterns":
         | 
| 311 322 | 
             
                        # Extract With X: patterns
         | 
| 312 323 | 
             
                        patterns = {}
         | 
| 313 324 | 
             
                        for line in content:
         | 
| 314 | 
            -
                            if line.startswith( | 
| 315 | 
            -
                                agent =  | 
| 316 | 
            -
             | 
| 325 | 
            +
                            if line.startswith("- **With ") and "**:" in line:
         | 
| 326 | 
            +
                                agent = (
         | 
| 327 | 
            +
                                    line.split("**:")[0]
         | 
| 328 | 
            +
                                    .replace("- **With ", "")
         | 
| 329 | 
            +
                                    .replace("**", "")
         | 
| 330 | 
            +
                                    .strip()
         | 
| 331 | 
            +
                                )
         | 
| 332 | 
            +
                                desc = line.split("**:")[1].strip()
         | 
| 317 333 | 
             
                                patterns[agent] = desc
         | 
| 318 | 
            -
                        profile[ | 
| 319 | 
            -
             | 
| 334 | 
            +
                        profile["integration_patterns"] = patterns
         | 
| 335 | 
            +
             | 
| 320 336 | 
             
                def get_available_agents(self) -> Dict[str, list]:
         | 
| 321 337 | 
             
                    """Get list of available agents by tier"""
         | 
| 322 | 
            -
                    agents = {
         | 
| 323 | 
            -
             | 
| 324 | 
            -
                        'user': [],
         | 
| 325 | 
            -
                        'system': []
         | 
| 326 | 
            -
                    }
         | 
| 327 | 
            -
                    
         | 
| 338 | 
            +
                    agents = {"project": [], "user": [], "system": []}
         | 
| 339 | 
            +
             | 
| 328 340 | 
             
                    # Project agents
         | 
| 329 341 | 
             
                    if self.project_agents_dir:
         | 
| 330 342 | 
             
                        # Check both project subdirectory and root
         | 
| 331 | 
            -
                        for search_dir in [ | 
| 343 | 
            +
                        for search_dir in [
         | 
| 344 | 
            +
                            self.project_agents_dir / "project",
         | 
| 345 | 
            +
                            self.project_agents_dir,
         | 
| 346 | 
            +
                        ]:
         | 
| 332 347 | 
             
                            if search_dir.exists():
         | 
| 333 348 | 
             
                                md_files = [f.stem for f in search_dir.glob("*.md")]
         | 
| 334 | 
            -
                                agents[ | 
| 335 | 
            -
             | 
| 349 | 
            +
                                agents["project"].extend(
         | 
| 350 | 
            +
                                    [f for f in md_files if f not in agents["project"]]
         | 
| 351 | 
            +
                                )
         | 
| 352 | 
            +
             | 
| 336 353 | 
             
                    # User agents
         | 
| 337 354 | 
             
                    if self.user_agents_dir:
         | 
| 338 355 | 
             
                        # Check both user subdirectory and root
         | 
| 339 356 | 
             
                        for search_dir in [self.user_agents_dir / "user", self.user_agents_dir]:
         | 
| 340 357 | 
             
                            if search_dir.exists():
         | 
| 341 358 | 
             
                                md_files = [f.stem for f in search_dir.glob("*.md")]
         | 
| 342 | 
            -
                                agents[ | 
| 343 | 
            -
             | 
| 359 | 
            +
                                agents["user"].extend(
         | 
| 360 | 
            +
                                    [f for f in md_files if f not in agents["user"]]
         | 
| 361 | 
            +
                                )
         | 
| 362 | 
            +
             | 
| 344 363 | 
             
                    # System agents
         | 
| 345 364 | 
             
                    if self.system_agents_dir:
         | 
| 346 365 | 
             
                        # Check subdirectories and root
         | 
| 347 366 | 
             
                        for subdir in ["trained", "system", ""]:
         | 
| 348 | 
            -
                            search_dir =  | 
| 367 | 
            +
                            search_dir = (
         | 
| 368 | 
            +
                                self.system_agents_dir / subdir
         | 
| 369 | 
            +
                                if subdir
         | 
| 370 | 
            +
                                else self.system_agents_dir
         | 
| 371 | 
            +
                            )
         | 
| 349 372 | 
             
                            if search_dir.exists():
         | 
| 350 373 | 
             
                                md_files = [f.stem for f in search_dir.glob("*.md")]
         | 
| 351 | 
            -
                                agents[ | 
| 352 | 
            -
             | 
| 374 | 
            +
                                agents["system"].extend(
         | 
| 375 | 
            +
                                    [f for f in md_files if f not in agents["system"]]
         | 
| 376 | 
            +
                                )
         | 
| 377 | 
            +
             | 
| 353 378 | 
             
                    # Also integrate with main agent_loader to get JSON-based agents
         | 
| 354 379 | 
             
                    try:
         | 
| 355 380 | 
             
                        json_agents = list_agents_by_tier()
         | 
| @@ -358,25 +383,25 @@ class FrameworkAgentLoader: | |
| 358 383 | 
             
                                # Merge lists, avoiding duplicates
         | 
| 359 384 | 
             
                                for agent in agent_list:
         | 
| 360 385 | 
             
                                    # Remove _agent suffix for consistency
         | 
| 361 | 
            -
                                    agent_name = agent.replace( | 
| 386 | 
            +
                                    agent_name = agent.replace("_agent", "")
         | 
| 362 387 | 
             
                                    if agent_name not in agents[tier]:
         | 
| 363 388 | 
             
                                        agents[tier].append(agent_name)
         | 
| 364 389 | 
             
                    except Exception as e:
         | 
| 365 390 | 
             
                        logger.debug(f"Could not integrate with agent_loader: {e}")
         | 
| 366 | 
            -
             | 
| 391 | 
            +
             | 
| 367 392 | 
             
                    return agents
         | 
| 368 | 
            -
             | 
| 393 | 
            +
             | 
| 369 394 | 
             
                def generate_profile_loading_instruction(self, agent_type: str) -> str:
         | 
| 370 395 | 
             
                    """Generate instruction for subprocess to load its own profile"""
         | 
| 371 396 | 
             
                    profile = self.load_agent_profile(agent_type)
         | 
| 372 | 
            -
             | 
| 397 | 
            +
             | 
| 373 398 | 
             
                    if not profile:
         | 
| 374 399 | 
             
                        return f"""
         | 
| 375 400 | 
             
            **{agent_type} Agent**: No profile found. Operating with basic capabilities.
         | 
| 376 401 |  | 
| 377 402 | 
             
            **Task Context**: Please proceed with the assigned task using standard practices.
         | 
| 378 403 | 
             
            """
         | 
| 379 | 
            -
             | 
| 404 | 
            +
             | 
| 380 405 | 
             
                    instruction = f"""
         | 
| 381 406 | 
             
            **{agent_type} Agent Profile Loaded**
         | 
| 382 407 |  | 
| @@ -386,10 +411,10 @@ class FrameworkAgentLoader: | |
| 386 411 |  | 
| 387 412 | 
             
            **Core Capabilities**:
         | 
| 388 413 | 
             
            """
         | 
| 389 | 
            -
             | 
| 390 | 
            -
                    for capability in profile.get( | 
| 414 | 
            +
             | 
| 415 | 
            +
                    for capability in profile.get("capabilities", [])[:5]:  # Top 5 capabilities
         | 
| 391 416 | 
             
                        instruction += f"- **{capability}**: Primary capability area\n"
         | 
| 392 | 
            -
             | 
| 417 | 
            +
             | 
| 393 418 | 
             
                    instruction += f"""
         | 
| 394 419 | 
             
            **Context Preferences**:
         | 
| 395 420 | 
             
            - **Include**: {profile.get('context_preferences', {}).get('include', 'Not specified')}
         | 
| @@ -398,10 +423,10 @@ class FrameworkAgentLoader: | |
| 398 423 |  | 
| 399 424 | 
             
            **Authority Scope**:
         | 
| 400 425 | 
             
            """
         | 
| 401 | 
            -
             | 
| 402 | 
            -
                    for authority in profile.get( | 
| 426 | 
            +
             | 
| 427 | 
            +
                    for authority in profile.get("authority_scope", [])[:3]:  # Top 3 authorities
         | 
| 403 428 | 
             
                        instruction += f"- **{authority}**: Authorized operation area\n"
         | 
| 404 | 
            -
             | 
| 429 | 
            +
             | 
| 405 430 | 
             
                    instruction += f"""
         | 
| 406 431 | 
             
            **Quality Standards**: {len(profile.get('quality_standards', []))} standards defined
         | 
| 407 432 | 
             
            **Escalation Triggers**: {len(profile.get('escalation_criteria', []))} criteria defined
         | 
| @@ -409,5 +434,5 @@ class FrameworkAgentLoader: | |
| 409 434 |  | 
| 410 435 | 
             
            Please operate according to your profile specifications and maintain quality standards.
         | 
| 411 436 | 
             
            """
         | 
| 412 | 
            -
             | 
| 413 | 
            -
                    return instruction.strip()
         | 
| 437 | 
            +
             | 
| 438 | 
            +
                    return instruction.strip()
         | 
| @@ -1,9 +1,9 @@ | |
| 1 1 | 
             
            """High-level agent management services."""
         | 
| 2 2 |  | 
| 3 | 
            -
            from .agent_management_service import AgentManager
         | 
| 4 3 | 
             
            from .agent_capabilities_generator import AgentCapabilitiesGenerator
         | 
| 4 | 
            +
            from .agent_management_service import AgentManager
         | 
| 5 5 |  | 
| 6 6 | 
             
            __all__ = [
         | 
| 7 7 | 
             
                "AgentManager",
         | 
| 8 8 | 
             
                "AgentCapabilitiesGenerator",
         | 
| 9 | 
            -
            ]
         | 
| 9 | 
            +
            ]
         |