claude-mpm 4.3.11__py3-none-any.whl → 4.3.13__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/agents/PM_INSTRUCTIONS.md +390 -28
- claude_mpm/agents/templates/data_engineer.json +39 -14
- claude_mpm/agents/templates/research.json +20 -8
- claude_mpm/agents/templates/web_qa.json +25 -10
- claude_mpm/cli/__init__.py +1 -0
- claude_mpm/cli/commands/agent_manager.py +3 -3
- claude_mpm/cli/commands/agents.py +2 -2
- claude_mpm/cli/commands/aggregate.py +1 -1
- claude_mpm/cli/commands/config.py +2 -2
- claude_mpm/cli/commands/configure.py +5 -5
- claude_mpm/cli/commands/configure_tui.py +7 -7
- claude_mpm/cli/commands/dashboard.py +1 -1
- claude_mpm/cli/commands/debug.py +5 -5
- claude_mpm/cli/commands/mcp.py +1 -1
- claude_mpm/cli/commands/mcp_command_router.py +12 -1
- claude_mpm/cli/commands/mcp_config.py +154 -0
- claude_mpm/cli/commands/mcp_external_commands.py +249 -0
- claude_mpm/cli/commands/mcp_install_commands.py +93 -24
- claude_mpm/cli/commands/mcp_setup_external.py +870 -0
- claude_mpm/cli/commands/monitor.py +2 -2
- claude_mpm/cli/commands/mpm_init_handler.py +1 -1
- claude_mpm/cli/commands/run.py +114 -0
- claude_mpm/cli/commands/search.py +292 -0
- claude_mpm/cli/interactive/agent_wizard.py +2 -2
- claude_mpm/cli/parsers/base_parser.py +13 -0
- claude_mpm/cli/parsers/mcp_parser.py +15 -0
- claude_mpm/cli/parsers/run_parser.py +5 -0
- claude_mpm/cli/parsers/search_parser.py +245 -0
- claude_mpm/cli/startup_logging.py +3 -5
- claude_mpm/cli/utils.py +1 -1
- claude_mpm/constants.py +1 -0
- claude_mpm/core/agent_registry.py +12 -8
- claude_mpm/core/agent_session_manager.py +8 -8
- claude_mpm/core/api_validator.py +4 -4
- claude_mpm/core/base_service.py +10 -10
- claude_mpm/core/cache.py +5 -5
- claude_mpm/core/config_constants.py +1 -1
- claude_mpm/core/container.py +1 -1
- claude_mpm/core/error_handler.py +2 -2
- claude_mpm/core/file_utils.py +1 -1
- claude_mpm/core/framework_loader.py +3 -3
- claude_mpm/core/hook_manager.py +8 -6
- claude_mpm/core/instruction_reinforcement_hook.py +2 -2
- claude_mpm/core/interactive_session.py +1 -1
- claude_mpm/core/lazy.py +3 -3
- claude_mpm/core/log_manager.py +16 -12
- claude_mpm/core/logger.py +16 -11
- claude_mpm/core/logging_config.py +4 -2
- claude_mpm/core/oneshot_session.py +1 -1
- claude_mpm/core/optimized_agent_loader.py +6 -6
- claude_mpm/core/output_style_manager.py +1 -1
- claude_mpm/core/pm_hook_interceptor.py +3 -3
- claude_mpm/core/service_registry.py +1 -1
- claude_mpm/core/session_manager.py +11 -9
- claude_mpm/core/socketio_pool.py +13 -13
- claude_mpm/core/types.py +2 -2
- claude_mpm/core/unified_agent_registry.py +9 -2
- claude_mpm/core/unified_paths.py +1 -1
- claude_mpm/dashboard/analysis_runner.py +4 -4
- claude_mpm/dashboard/api/simple_directory.py +1 -1
- claude_mpm/generators/agent_profile_generator.py +4 -2
- claude_mpm/hooks/base_hook.py +2 -2
- claude_mpm/hooks/claude_hooks/connection_pool.py +4 -4
- claude_mpm/hooks/claude_hooks/event_handlers.py +12 -12
- claude_mpm/hooks/claude_hooks/hook_handler.py +4 -4
- claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +3 -3
- claude_mpm/hooks/claude_hooks/hook_handler_original.py +15 -14
- claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +4 -4
- claude_mpm/hooks/claude_hooks/installer.py +3 -3
- claude_mpm/hooks/claude_hooks/memory_integration.py +3 -3
- claude_mpm/hooks/claude_hooks/response_tracking.py +3 -3
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +5 -5
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +3 -3
- claude_mpm/hooks/claude_hooks/services/state_manager.py +8 -7
- claude_mpm/hooks/claude_hooks/services/subagent_processor.py +3 -3
- claude_mpm/hooks/claude_hooks/tool_analysis.py +2 -2
- claude_mpm/hooks/memory_integration_hook.py +1 -1
- claude_mpm/hooks/tool_call_interceptor.py +2 -2
- claude_mpm/models/agent_session.py +5 -5
- claude_mpm/services/__init__.py +1 -1
- claude_mpm/services/agent_capabilities_service.py +1 -1
- claude_mpm/services/agents/agent_builder.py +3 -3
- claude_mpm/services/agents/deployment/agent_deployment.py +29 -13
- claude_mpm/services/agents/deployment/agent_discovery_service.py +22 -6
- claude_mpm/services/agents/deployment/agent_filesystem_manager.py +7 -5
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +3 -1
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +1 -1
- claude_mpm/services/agents/deployment/agent_operation_service.py +2 -2
- claude_mpm/services/agents/deployment/agent_state_service.py +2 -2
- claude_mpm/services/agents/deployment/agent_template_builder.py +1 -1
- claude_mpm/services/agents/deployment/agent_versioning.py +1 -1
- claude_mpm/services/agents/deployment/deployment_wrapper.py +2 -3
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +6 -4
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +1 -1
- claude_mpm/services/agents/loading/agent_profile_loader.py +5 -3
- claude_mpm/services/agents/loading/base_agent_manager.py +2 -2
- claude_mpm/services/agents/local_template_manager.py +6 -6
- claude_mpm/services/agents/management/agent_management_service.py +3 -3
- claude_mpm/services/agents/memory/content_manager.py +3 -3
- claude_mpm/services/agents/memory/memory_format_service.py +2 -2
- claude_mpm/services/agents/memory/template_generator.py +3 -3
- claude_mpm/services/agents/registry/__init__.py +1 -1
- claude_mpm/services/agents/registry/modification_tracker.py +2 -2
- claude_mpm/services/async_session_logger.py +3 -3
- claude_mpm/services/claude_session_logger.py +4 -4
- claude_mpm/services/cli/agent_cleanup_service.py +5 -0
- claude_mpm/services/cli/agent_listing_service.py +1 -1
- claude_mpm/services/cli/agent_validation_service.py +1 -0
- claude_mpm/services/cli/memory_crud_service.py +11 -6
- claude_mpm/services/cli/memory_output_formatter.py +1 -1
- claude_mpm/services/cli/session_manager.py +15 -11
- claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
- claude_mpm/services/core/memory_manager.py +81 -23
- claude_mpm/services/core/path_resolver.py +2 -2
- claude_mpm/services/diagnostics/checks/installation_check.py +1 -1
- claude_mpm/services/event_aggregator.py +4 -2
- claude_mpm/services/event_bus/direct_relay.py +5 -3
- claude_mpm/services/event_bus/event_bus.py +3 -3
- claude_mpm/services/event_bus/relay.py +6 -4
- claude_mpm/services/events/consumers/dead_letter.py +5 -3
- claude_mpm/services/events/core.py +3 -3
- claude_mpm/services/events/producers/hook.py +6 -6
- claude_mpm/services/events/producers/system.py +8 -8
- claude_mpm/services/exceptions.py +5 -5
- claude_mpm/services/framework_claude_md_generator/content_assembler.py +3 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +2 -2
- claude_mpm/services/hook_installer_service.py +1 -1
- claude_mpm/services/infrastructure/context_preservation.py +6 -4
- claude_mpm/services/infrastructure/daemon_manager.py +2 -2
- claude_mpm/services/infrastructure/logging.py +2 -2
- claude_mpm/services/mcp_config_manager.py +439 -0
- claude_mpm/services/mcp_gateway/__init__.py +1 -1
- claude_mpm/services/mcp_gateway/auto_configure.py +3 -3
- claude_mpm/services/mcp_gateway/config/config_loader.py +1 -1
- claude_mpm/services/mcp_gateway/config/configuration.py +18 -1
- claude_mpm/services/mcp_gateway/core/base.py +2 -2
- claude_mpm/services/mcp_gateway/main.py +52 -0
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +10 -8
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +4 -4
- claude_mpm/services/mcp_gateway/server/stdio_handler.py +1 -1
- claude_mpm/services/mcp_gateway/server/stdio_server.py +4 -3
- claude_mpm/services/mcp_gateway/tools/base_adapter.py +15 -15
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +7 -5
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +443 -0
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +5 -5
- claude_mpm/services/mcp_gateway/tools/hello_world.py +9 -9
- claude_mpm/services/mcp_gateway/tools/ticket_tools.py +16 -16
- claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +17 -17
- claude_mpm/services/memory/builder.py +7 -5
- claude_mpm/services/memory/indexed_memory.py +4 -4
- claude_mpm/services/memory/optimizer.py +6 -6
- claude_mpm/services/memory/router.py +3 -3
- claude_mpm/services/monitor/daemon.py +1 -1
- claude_mpm/services/monitor/daemon_manager.py +6 -6
- claude_mpm/services/monitor/event_emitter.py +2 -2
- claude_mpm/services/monitor/handlers/file.py +1 -1
- claude_mpm/services/monitor/management/lifecycle.py +1 -1
- claude_mpm/services/monitor/server.py +4 -4
- claude_mpm/services/monitor_build_service.py +2 -2
- claude_mpm/services/port_manager.py +2 -2
- claude_mpm/services/response_tracker.py +2 -2
- claude_mpm/services/session_management_service.py +3 -2
- claude_mpm/services/socketio/client_proxy.py +2 -2
- claude_mpm/services/socketio/dashboard_server.py +4 -3
- claude_mpm/services/socketio/event_normalizer.py +12 -8
- claude_mpm/services/socketio/handlers/base.py +2 -2
- claude_mpm/services/socketio/handlers/connection.py +10 -10
- claude_mpm/services/socketio/handlers/connection_handler.py +13 -10
- claude_mpm/services/socketio/handlers/file.py +1 -1
- claude_mpm/services/socketio/handlers/git.py +1 -1
- claude_mpm/services/socketio/handlers/hook.py +16 -15
- claude_mpm/services/socketio/migration_utils.py +1 -1
- claude_mpm/services/socketio/monitor_client.py +5 -5
- claude_mpm/services/socketio/server/broadcaster.py +9 -7
- claude_mpm/services/socketio/server/connection_manager.py +2 -2
- claude_mpm/services/socketio/server/core.py +7 -5
- claude_mpm/services/socketio/server/eventbus_integration.py +18 -11
- claude_mpm/services/socketio/server/main.py +13 -13
- claude_mpm/services/socketio_client_manager.py +4 -4
- claude_mpm/services/system_instructions_service.py +2 -2
- claude_mpm/services/ticket_services/validation_service.py +1 -1
- claude_mpm/services/utility_service.py +5 -2
- claude_mpm/services/version_control/branch_strategy.py +2 -2
- claude_mpm/services/version_control/git_operations.py +22 -20
- claude_mpm/services/version_control/semantic_versioning.py +3 -3
- claude_mpm/services/version_control/version_parser.py +7 -5
- claude_mpm/services/visualization/mermaid_generator.py +1 -1
- claude_mpm/storage/state_storage.py +1 -1
- claude_mpm/tools/code_tree_analyzer.py +19 -18
- claude_mpm/tools/code_tree_builder.py +2 -2
- claude_mpm/tools/code_tree_events.py +10 -8
- claude_mpm/tools/socketio_debug.py +3 -3
- claude_mpm/utils/agent_dependency_loader.py +2 -2
- claude_mpm/utils/dependency_strategies.py +8 -3
- claude_mpm/utils/environment_context.py +2 -2
- claude_mpm/utils/error_handler.py +2 -2
- claude_mpm/utils/file_utils.py +1 -1
- claude_mpm/utils/imports.py +1 -1
- claude_mpm/utils/log_cleanup.py +21 -7
- claude_mpm/validation/agent_validator.py +2 -2
- {claude_mpm-4.3.11.dist-info → claude_mpm-4.3.13.dist-info}/METADATA +4 -1
- {claude_mpm-4.3.11.dist-info → claude_mpm-4.3.13.dist-info}/RECORD +207 -200
- {claude_mpm-4.3.11.dist-info → claude_mpm-4.3.13.dist-info}/WHEEL +0 -0
- {claude_mpm-4.3.11.dist-info → claude_mpm-4.3.13.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.3.11.dist-info → claude_mpm-4.3.13.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.3.11.dist-info → claude_mpm-4.3.13.dist-info}/top_level.txt +0 -0
|
@@ -19,6 +19,7 @@ import hashlib
|
|
|
19
19
|
import json
|
|
20
20
|
import time
|
|
21
21
|
from dataclasses import dataclass
|
|
22
|
+
from datetime import datetime, timezone
|
|
22
23
|
from pathlib import Path
|
|
23
24
|
from typing import Any, Dict, List, Optional
|
|
24
25
|
|
|
@@ -272,7 +273,7 @@ class GitignoreManager:
|
|
|
272
273
|
|
|
273
274
|
return patterns
|
|
274
275
|
|
|
275
|
-
def _basic_should_ignore(self, path: Path, working_dir: Path) -> bool:
|
|
276
|
+
def _basic_should_ignore(self, path: Path, working_dir: Path) -> bool: # noqa: PLR0911
|
|
276
277
|
"""Basic pattern matching fallback when pathspec is not available.
|
|
277
278
|
|
|
278
279
|
Args:
|
|
@@ -608,7 +609,7 @@ class PythonAnalyzer:
|
|
|
608
609
|
|
|
609
610
|
return nodes
|
|
610
611
|
|
|
611
|
-
def _get_assignment_signature(self, node: ast.Assign, var_name: str) -> str:
|
|
612
|
+
def _get_assignment_signature(self, node: ast.Assign, var_name: str) -> str: # noqa: PLR0911
|
|
612
613
|
"""Get assignment signature string."""
|
|
613
614
|
try:
|
|
614
615
|
# Try to get a simple representation of the value
|
|
@@ -623,7 +624,7 @@ class PythonAnalyzer:
|
|
|
623
624
|
if isinstance(node.value, ast.Dict):
|
|
624
625
|
return f"{var_name} = {{...}}"
|
|
625
626
|
return f"{var_name} = ..."
|
|
626
|
-
except:
|
|
627
|
+
except Exception:
|
|
627
628
|
return f"{var_name} = ..."
|
|
628
629
|
|
|
629
630
|
|
|
@@ -1292,7 +1293,7 @@ class CodeTreeAnalyzer:
|
|
|
1292
1293
|
|
|
1293
1294
|
# Emit discovery start event
|
|
1294
1295
|
if self.emitter:
|
|
1295
|
-
from datetime import datetime
|
|
1296
|
+
from datetime import datetime, timezone
|
|
1296
1297
|
|
|
1297
1298
|
self.emitter.emit(
|
|
1298
1299
|
"info",
|
|
@@ -1301,7 +1302,7 @@ class CodeTreeAnalyzer:
|
|
|
1301
1302
|
"action": "scanning_directory",
|
|
1302
1303
|
"path": str(directory),
|
|
1303
1304
|
"message": f"Starting discovery of {directory.name}",
|
|
1304
|
-
"timestamp": datetime.now().isoformat(),
|
|
1305
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
1305
1306
|
},
|
|
1306
1307
|
)
|
|
1307
1308
|
|
|
@@ -1336,7 +1337,7 @@ class CodeTreeAnalyzer:
|
|
|
1336
1337
|
"path": str(item),
|
|
1337
1338
|
"reason": "gitignore pattern",
|
|
1338
1339
|
"message": f"Ignored by gitignore: {item.name}",
|
|
1339
|
-
"timestamp": datetime.now().isoformat(),
|
|
1340
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
1340
1341
|
},
|
|
1341
1342
|
)
|
|
1342
1343
|
ignored_count += 1
|
|
@@ -1354,7 +1355,7 @@ class CodeTreeAnalyzer:
|
|
|
1354
1355
|
"path": str(item),
|
|
1355
1356
|
"reason": "custom pattern",
|
|
1356
1357
|
"message": f"Ignored by pattern: {item.name}",
|
|
1357
|
-
"timestamp": datetime.now().isoformat(),
|
|
1358
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
1358
1359
|
},
|
|
1359
1360
|
)
|
|
1360
1361
|
ignored_count += 1
|
|
@@ -1375,7 +1376,7 @@ class CodeTreeAnalyzer:
|
|
|
1375
1376
|
"path": str(item.name),
|
|
1376
1377
|
"reason": "no code files",
|
|
1377
1378
|
"message": f"Skipped directory without code: {item.name}",
|
|
1378
|
-
"timestamp": datetime.now().isoformat(),
|
|
1379
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
1379
1380
|
},
|
|
1380
1381
|
)
|
|
1381
1382
|
ignored_count += 1
|
|
@@ -1395,7 +1396,7 @@ class CodeTreeAnalyzer:
|
|
|
1395
1396
|
"type": "discovery.directory",
|
|
1396
1397
|
"path": str(item),
|
|
1397
1398
|
"message": f"Found directory: {item.name}",
|
|
1398
|
-
"timestamp": datetime.now().isoformat(),
|
|
1399
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
1399
1400
|
},
|
|
1400
1401
|
)
|
|
1401
1402
|
dirs_count += 1
|
|
@@ -1441,7 +1442,7 @@ class CodeTreeAnalyzer:
|
|
|
1441
1442
|
"language": language,
|
|
1442
1443
|
"size": item.stat().st_size,
|
|
1443
1444
|
"message": f"Found file: {item.name} ({language})",
|
|
1444
|
-
"timestamp": datetime.now().isoformat(),
|
|
1445
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
1445
1446
|
},
|
|
1446
1447
|
)
|
|
1447
1448
|
files_count += 1
|
|
@@ -1481,7 +1482,7 @@ class CodeTreeAnalyzer:
|
|
|
1481
1482
|
"ignored": ignored_count,
|
|
1482
1483
|
},
|
|
1483
1484
|
"message": f"Discovery complete: {files_count} files, {dirs_count} directories, {ignored_count} ignored",
|
|
1484
|
-
"timestamp": datetime.now().isoformat(),
|
|
1485
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
1485
1486
|
},
|
|
1486
1487
|
)
|
|
1487
1488
|
|
|
@@ -1538,7 +1539,7 @@ class CodeTreeAnalyzer:
|
|
|
1538
1539
|
"file": str(path),
|
|
1539
1540
|
"language": language,
|
|
1540
1541
|
"message": f"Analyzing: {path.name}",
|
|
1541
|
-
"timestamp": datetime.now().isoformat(),
|
|
1542
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
1542
1543
|
},
|
|
1543
1544
|
)
|
|
1544
1545
|
|
|
@@ -1557,7 +1558,7 @@ class CodeTreeAnalyzer:
|
|
|
1557
1558
|
"type": "cache.hit",
|
|
1558
1559
|
"file": str(path),
|
|
1559
1560
|
"message": f"Using cached analysis for {path.name}",
|
|
1560
|
-
"timestamp": datetime.now().isoformat(),
|
|
1561
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
1561
1562
|
},
|
|
1562
1563
|
)
|
|
1563
1564
|
else:
|
|
@@ -1571,7 +1572,7 @@ class CodeTreeAnalyzer:
|
|
|
1571
1572
|
"type": "cache.miss",
|
|
1572
1573
|
"file": str(path),
|
|
1573
1574
|
"message": f"Cache miss, analyzing fresh: {path.name}",
|
|
1574
|
-
"timestamp": datetime.now().isoformat(),
|
|
1575
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
1575
1576
|
},
|
|
1576
1577
|
)
|
|
1577
1578
|
|
|
@@ -1594,7 +1595,7 @@ class CodeTreeAnalyzer:
|
|
|
1594
1595
|
"type": "analysis.parse",
|
|
1595
1596
|
"file": str(path),
|
|
1596
1597
|
"message": f"Parsing file content: {path.name}",
|
|
1597
|
-
"timestamp": datetime.now().isoformat(),
|
|
1598
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
1598
1599
|
},
|
|
1599
1600
|
)
|
|
1600
1601
|
|
|
@@ -1626,7 +1627,7 @@ class CodeTreeAnalyzer:
|
|
|
1626
1627
|
"line_start": node.line_start,
|
|
1627
1628
|
"complexity": node.complexity,
|
|
1628
1629
|
"message": f"Found {node.node_type}: {node.name}",
|
|
1629
|
-
"timestamp": datetime.now().isoformat(),
|
|
1630
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
1630
1631
|
},
|
|
1631
1632
|
)
|
|
1632
1633
|
|
|
@@ -1667,7 +1668,7 @@ class CodeTreeAnalyzer:
|
|
|
1667
1668
|
},
|
|
1668
1669
|
"duration": duration,
|
|
1669
1670
|
"message": f"Analysis complete: {classes_count} classes, {functions_count} functions, {methods_count} methods",
|
|
1670
|
-
"timestamp": datetime.now().isoformat(),
|
|
1671
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
1671
1672
|
},
|
|
1672
1673
|
)
|
|
1673
1674
|
|
|
@@ -1725,7 +1726,7 @@ class CodeTreeAnalyzer:
|
|
|
1725
1726
|
},
|
|
1726
1727
|
}
|
|
1727
1728
|
|
|
1728
|
-
def _is_internal_node(self, node: CodeNode) -> bool:
|
|
1729
|
+
def _is_internal_node(self, node: CodeNode) -> bool: # noqa: PLR0911
|
|
1729
1730
|
"""Check if node is an internal function that should be filtered."""
|
|
1730
1731
|
# Don't filter classes - always show them
|
|
1731
1732
|
if node.node_type == "class":
|
|
@@ -17,7 +17,7 @@ import fnmatch
|
|
|
17
17
|
import hashlib
|
|
18
18
|
import json
|
|
19
19
|
from dataclasses import dataclass, field
|
|
20
|
-
from datetime import datetime
|
|
20
|
+
from datetime import datetime, timezone
|
|
21
21
|
from pathlib import Path
|
|
22
22
|
from typing import Any, Dict, List, Optional, Set
|
|
23
23
|
|
|
@@ -505,7 +505,7 @@ class CodeTreeBuilder:
|
|
|
505
505
|
"files_ignored": self.stats["files_ignored"],
|
|
506
506
|
"total_size": self.stats["total_size"],
|
|
507
507
|
"languages": list(self.stats["languages"]),
|
|
508
|
-
"generated_at": datetime.
|
|
508
|
+
"generated_at": datetime.now(timezone.utc).isoformat(),
|
|
509
509
|
}
|
|
510
510
|
|
|
511
511
|
with open(output_path, "w") as f:
|
|
@@ -19,7 +19,7 @@ import threading
|
|
|
19
19
|
import time
|
|
20
20
|
from collections import deque
|
|
21
21
|
from dataclasses import asdict, dataclass
|
|
22
|
-
from datetime import datetime
|
|
22
|
+
from datetime import datetime, timezone
|
|
23
23
|
from typing import Any, Dict, List, Optional
|
|
24
24
|
|
|
25
25
|
try:
|
|
@@ -54,7 +54,7 @@ class CodeNodeEvent:
|
|
|
54
54
|
def to_dict(self) -> Dict[str, Any]:
|
|
55
55
|
"""Convert to dictionary for JSON serialization."""
|
|
56
56
|
data = asdict(self)
|
|
57
|
-
data["timestamp"] = datetime.
|
|
57
|
+
data["timestamp"] = datetime.now(timezone.utc).isoformat()
|
|
58
58
|
return data
|
|
59
59
|
|
|
60
60
|
|
|
@@ -157,7 +157,7 @@ class CodeTreeEventEmitter:
|
|
|
157
157
|
|
|
158
158
|
def start(self):
|
|
159
159
|
"""Start the event emitter and background tasks."""
|
|
160
|
-
self.stats["start_time"] = datetime.
|
|
160
|
+
self.stats["start_time"] = datetime.now(timezone.utc)
|
|
161
161
|
self._stop_event.clear()
|
|
162
162
|
|
|
163
163
|
# Start background emit task
|
|
@@ -168,7 +168,7 @@ class CodeTreeEventEmitter:
|
|
|
168
168
|
self.emit(
|
|
169
169
|
self.EVENT_ANALYSIS_START,
|
|
170
170
|
{
|
|
171
|
-
"timestamp": datetime.
|
|
171
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
172
172
|
"batch_size": self.batch_size,
|
|
173
173
|
"batch_timeout": self.batch_timeout,
|
|
174
174
|
},
|
|
@@ -183,9 +183,11 @@ class CodeTreeEventEmitter:
|
|
|
183
183
|
self.emit(
|
|
184
184
|
self.EVENT_ANALYSIS_COMPLETE,
|
|
185
185
|
{
|
|
186
|
-
"timestamp": datetime.
|
|
186
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
187
187
|
"duration": (
|
|
188
|
-
(
|
|
188
|
+
(
|
|
189
|
+
datetime.now(timezone.utc) - self.stats["start_time"]
|
|
190
|
+
).total_seconds()
|
|
189
191
|
if self.stats["start_time"]
|
|
190
192
|
else 0
|
|
191
193
|
),
|
|
@@ -213,7 +215,7 @@ class CodeTreeEventEmitter:
|
|
|
213
215
|
event = {
|
|
214
216
|
"type": event_type,
|
|
215
217
|
"data": data,
|
|
216
|
-
"timestamp": datetime.
|
|
218
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
217
219
|
}
|
|
218
220
|
|
|
219
221
|
if batch:
|
|
@@ -393,7 +395,7 @@ class CodeTreeEventEmitter:
|
|
|
393
395
|
"events": list(self.event_buffer),
|
|
394
396
|
"count": len(self.event_buffer),
|
|
395
397
|
},
|
|
396
|
-
"timestamp": datetime.
|
|
398
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
397
399
|
}
|
|
398
400
|
|
|
399
401
|
self._emit_event(batch_event)
|
|
@@ -13,7 +13,7 @@ import signal
|
|
|
13
13
|
import sys
|
|
14
14
|
import time
|
|
15
15
|
from dataclasses import dataclass, field
|
|
16
|
-
from datetime import datetime
|
|
16
|
+
from datetime import datetime, timezone
|
|
17
17
|
from enum import Enum
|
|
18
18
|
from pathlib import Path
|
|
19
19
|
from typing import Any, Dict, List, Optional, Set
|
|
@@ -232,7 +232,7 @@ class SocketIODebugger:
|
|
|
232
232
|
|
|
233
233
|
def _display_event(self, data: Dict[str, Any]):
|
|
234
234
|
"""Display an event based on current mode."""
|
|
235
|
-
timestamp = datetime.now().strftime("%H:%M:%S.%f")[:-3]
|
|
235
|
+
timestamp = datetime.now(timezone.utc).strftime("%H:%M:%S.%f")[:-3]
|
|
236
236
|
event_type = data.get("type", "unknown")
|
|
237
237
|
event_data = data.get("data", {})
|
|
238
238
|
|
|
@@ -449,7 +449,7 @@ class SocketIODebugger:
|
|
|
449
449
|
if self.quiet and level not in ["error", "critical"]:
|
|
450
450
|
return
|
|
451
451
|
|
|
452
|
-
timestamp = datetime.now().strftime("%H:%M:%S")
|
|
452
|
+
timestamp = datetime.now(timezone.utc).strftime("%H:%M:%S")
|
|
453
453
|
|
|
454
454
|
if RICH_AVAILABLE:
|
|
455
455
|
styles = {
|
|
@@ -107,7 +107,7 @@ class AgentDependencyLoader:
|
|
|
107
107
|
logger.info(f"Loaded dependencies for {len(agent_dependencies)} agents")
|
|
108
108
|
return agent_dependencies
|
|
109
109
|
|
|
110
|
-
def check_python_dependency(self, package_spec: str) -> Tuple[bool, Optional[str]]:
|
|
110
|
+
def check_python_dependency(self, package_spec: str) -> Tuple[bool, Optional[str]]: # noqa: PLR0911
|
|
111
111
|
"""
|
|
112
112
|
Check if a Python package dependency is satisfied.
|
|
113
113
|
|
|
@@ -442,7 +442,7 @@ class AgentDependencyLoader:
|
|
|
442
442
|
|
|
443
443
|
return compatible, incompatible
|
|
444
444
|
|
|
445
|
-
def install_missing_dependencies(self, dependencies: List[str]) -> Tuple[bool, str]:
|
|
445
|
+
def install_missing_dependencies(self, dependencies: List[str]) -> Tuple[bool, str]: # noqa: PLR0911
|
|
446
446
|
"""
|
|
447
447
|
Install missing Python dependencies using robust retry logic.
|
|
448
448
|
|
|
@@ -10,7 +10,7 @@ based on the execution context and user preferences.
|
|
|
10
10
|
import json
|
|
11
11
|
import os
|
|
12
12
|
import sys
|
|
13
|
-
from datetime import datetime, timedelta
|
|
13
|
+
from datetime import datetime, timedelta, timezone
|
|
14
14
|
from enum import Enum
|
|
15
15
|
from typing import Any, Dict, Optional, Tuple
|
|
16
16
|
|
|
@@ -160,7 +160,9 @@ class DependencyStrategy:
|
|
|
160
160
|
last_check = datetime.fromisoformat(cache.get("timestamp", ""))
|
|
161
161
|
|
|
162
162
|
# Check if cache is still valid
|
|
163
|
-
if datetime.now() - last_check < timedelta(
|
|
163
|
+
if datetime.now(timezone.utc) - last_check < timedelta(
|
|
164
|
+
seconds=cache_ttl
|
|
165
|
+
):
|
|
164
166
|
logger.debug(f"Using cached dependency check from {last_check}")
|
|
165
167
|
return False
|
|
166
168
|
|
|
@@ -179,7 +181,10 @@ class DependencyStrategy:
|
|
|
179
181
|
try:
|
|
180
182
|
self.cache_path.parent.mkdir(parents=True, exist_ok=True)
|
|
181
183
|
|
|
182
|
-
cache_data = {
|
|
184
|
+
cache_data = {
|
|
185
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
186
|
+
"results": results,
|
|
187
|
+
}
|
|
183
188
|
|
|
184
189
|
with open(self.cache_path, "w") as f:
|
|
185
190
|
json.dump(cache_data, f, indent=2)
|
|
@@ -189,7 +189,7 @@ class EnvironmentContext:
|
|
|
189
189
|
get_ipython = globals().get("get_ipython")
|
|
190
190
|
if get_ipython is not None:
|
|
191
191
|
return True
|
|
192
|
-
except:
|
|
192
|
+
except Exception:
|
|
193
193
|
pass
|
|
194
194
|
|
|
195
195
|
# Check for Jupyter-specific environment variables
|
|
@@ -208,7 +208,7 @@ class EnvironmentContext:
|
|
|
208
208
|
@classmethod
|
|
209
209
|
def should_prompt_for_dependencies(
|
|
210
210
|
cls, force_prompt: bool = False, force_skip: bool = False
|
|
211
|
-
) -> Tuple[bool, str]:
|
|
211
|
+
) -> Tuple[bool, str]: # noqa: PLR0911
|
|
212
212
|
"""
|
|
213
213
|
Determine if we should prompt for dependency installation.
|
|
214
214
|
|
|
@@ -6,7 +6,7 @@ Inspired by awesome-claude-code's comprehensive error handling approach.
|
|
|
6
6
|
|
|
7
7
|
import logging
|
|
8
8
|
import sys
|
|
9
|
-
from datetime import datetime
|
|
9
|
+
from datetime import datetime, timezone
|
|
10
10
|
from functools import wraps
|
|
11
11
|
from typing import Any, Callable, Dict, List, Optional, Type
|
|
12
12
|
|
|
@@ -26,7 +26,7 @@ class MPMError(Exception):
|
|
|
26
26
|
super().__init__(message)
|
|
27
27
|
self.details = details or {}
|
|
28
28
|
self.suggestions = suggestions or []
|
|
29
|
-
self.timestamp = datetime.now()
|
|
29
|
+
self.timestamp = datetime.now(timezone.utc)
|
|
30
30
|
|
|
31
31
|
def get_user_friendly_message(self) -> str:
|
|
32
32
|
"""Get a user-friendly error message."""
|
claude_mpm/utils/file_utils.py
CHANGED
claude_mpm/utils/imports.py
CHANGED
|
@@ -15,7 +15,7 @@ def safe_import(
|
|
|
15
15
|
fallback_name: Optional[str] = None,
|
|
16
16
|
from_list: Optional[List[str]] = None,
|
|
17
17
|
logger: Optional[logging.Logger] = None,
|
|
18
|
-
) -> Optional[Any]:
|
|
18
|
+
) -> Optional[Any]: # noqa: PLR0911
|
|
19
19
|
"""
|
|
20
20
|
Safely import a module with fallback support.
|
|
21
21
|
|
claude_mpm/utils/log_cleanup.py
CHANGED
|
@@ -107,7 +107,9 @@ class LogCleanupUtility:
|
|
|
107
107
|
|
|
108
108
|
try:
|
|
109
109
|
# Check directory modification time
|
|
110
|
-
mtime = datetime.fromtimestamp(
|
|
110
|
+
mtime = datetime.fromtimestamp(
|
|
111
|
+
session_dir.stat().st_mtime, tz=timezone.utc
|
|
112
|
+
)
|
|
111
113
|
|
|
112
114
|
if mtime < cutoff_time:
|
|
113
115
|
# Calculate directory size
|
|
@@ -169,7 +171,9 @@ class LogCleanupUtility:
|
|
|
169
171
|
for ext in LogCleanupConfig.ARCHIVE_EXTENSIONS:
|
|
170
172
|
for archive_file in self.base_log_dir.rglob(f"*{ext}"):
|
|
171
173
|
try:
|
|
172
|
-
mtime = datetime.fromtimestamp(
|
|
174
|
+
mtime = datetime.fromtimestamp(
|
|
175
|
+
archive_file.stat().st_mtime, tz=timezone.utc
|
|
176
|
+
)
|
|
173
177
|
|
|
174
178
|
if mtime < cutoff_time:
|
|
175
179
|
file_size = archive_file.stat().st_size / (1024 * 1024) # MB
|
|
@@ -238,7 +242,9 @@ class LogCleanupUtility:
|
|
|
238
242
|
|
|
239
243
|
for log_file in log_dir.glob(pattern):
|
|
240
244
|
try:
|
|
241
|
-
mtime = datetime.fromtimestamp(
|
|
245
|
+
mtime = datetime.fromtimestamp(
|
|
246
|
+
log_file.stat().st_mtime, tz=timezone.utc
|
|
247
|
+
)
|
|
242
248
|
|
|
243
249
|
if mtime < cutoff_time:
|
|
244
250
|
file_size = log_file.stat().st_size / (1024 * 1024) # MB
|
|
@@ -283,7 +289,7 @@ class LogCleanupUtility:
|
|
|
283
289
|
removed_count = 0
|
|
284
290
|
|
|
285
291
|
# Walk bottom-up to remove empty parent directories
|
|
286
|
-
for root,
|
|
292
|
+
for root, _dirs, _files in os.walk(self.base_log_dir, topdown=False):
|
|
287
293
|
root_path = Path(root)
|
|
288
294
|
|
|
289
295
|
# Skip the base log directory itself
|
|
@@ -331,7 +337,9 @@ class LogCleanupUtility:
|
|
|
331
337
|
continue
|
|
332
338
|
|
|
333
339
|
try:
|
|
334
|
-
mtime = datetime.fromtimestamp(
|
|
340
|
+
mtime = datetime.fromtimestamp(
|
|
341
|
+
log_file.stat().st_mtime, tz=timezone.utc
|
|
342
|
+
)
|
|
335
343
|
|
|
336
344
|
if mtime < cutoff_time:
|
|
337
345
|
original_size = log_file.stat().st_size / (1024 * 1024) # MB
|
|
@@ -408,7 +416,10 @@ class LogCleanupUtility:
|
|
|
408
416
|
stats["oldest_session"] = {
|
|
409
417
|
"name": oldest.name,
|
|
410
418
|
"age_days": (
|
|
411
|
-
datetime.now(timezone.utc)
|
|
419
|
+
datetime.now(timezone.utc)
|
|
420
|
+
- datetime.fromtimestamp(
|
|
421
|
+
oldest.stat().st_mtime, tz=timezone.utc
|
|
422
|
+
)
|
|
412
423
|
).days,
|
|
413
424
|
}
|
|
414
425
|
|
|
@@ -429,7 +440,10 @@ class LogCleanupUtility:
|
|
|
429
440
|
"name": oldest_log.name,
|
|
430
441
|
"path": str(oldest_log.relative_to(self.base_log_dir)),
|
|
431
442
|
"age_days": (
|
|
432
|
-
datetime.now(timezone.utc)
|
|
443
|
+
datetime.now(timezone.utc)
|
|
444
|
+
- datetime.fromtimestamp(
|
|
445
|
+
oldest_log.stat().st_mtime, tz=timezone.utc
|
|
446
|
+
)
|
|
433
447
|
).days,
|
|
434
448
|
}
|
|
435
449
|
|
|
@@ -22,7 +22,7 @@ Security Considerations:
|
|
|
22
22
|
import json
|
|
23
23
|
import logging
|
|
24
24
|
from dataclasses import dataclass, field
|
|
25
|
-
from datetime import datetime
|
|
25
|
+
from datetime import datetime, timezone
|
|
26
26
|
from pathlib import Path
|
|
27
27
|
from typing import Any, Dict, List, Optional, Tuple
|
|
28
28
|
|
|
@@ -182,7 +182,7 @@ class AgentValidator:
|
|
|
182
182
|
|
|
183
183
|
# Add metadata
|
|
184
184
|
result.metadata = {
|
|
185
|
-
"validated_at": datetime.
|
|
185
|
+
"validated_at": datetime.now(timezone.utc).isoformat(),
|
|
186
186
|
"schema_version": self.schema.get("version", "1.1.0"),
|
|
187
187
|
"agent_id": agent_data.get("id", "unknown"),
|
|
188
188
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: claude-mpm
|
|
3
|
-
Version: 4.3.
|
|
3
|
+
Version: 4.3.13
|
|
4
4
|
Summary: Claude Multi-Agent Project Manager - Orchestrate Claude with agent delegation and ticket tracking
|
|
5
5
|
Author-email: Bob Matsuoka <bob@matsuoka.com>
|
|
6
6
|
Maintainer: Claude MPM Team
|
|
@@ -42,6 +42,9 @@ Requires-Dist: mistune>=3.0.0
|
|
|
42
42
|
Requires-Dist: tree-sitter>=0.21.0
|
|
43
43
|
Requires-Dist: ijson>=3.2.0
|
|
44
44
|
Requires-Dist: mcp>=0.1.0
|
|
45
|
+
Requires-Dist: mcp-vector-search>=0.1.0
|
|
46
|
+
Requires-Dist: mcp-browser>=0.1.0
|
|
47
|
+
Requires-Dist: mcp-ticketer>=0.1.0
|
|
45
48
|
Requires-Dist: toml>=0.10.2
|
|
46
49
|
Requires-Dist: packaging>=21.0
|
|
47
50
|
Requires-Dist: pydantic>=2.0.0
|