claude-mpm 4.5.11__py3-none-any.whl → 4.5.12__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.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/frontmatter_validator.py +4 -4
- claude_mpm/cli/commands/agent_manager.py +3 -3
- claude_mpm/cli/commands/agents.py +6 -6
- claude_mpm/cli/commands/aggregate.py +4 -4
- claude_mpm/cli/commands/analyze.py +2 -2
- claude_mpm/cli/commands/analyze_code.py +1 -1
- claude_mpm/cli/commands/cleanup.py +3 -3
- claude_mpm/cli/commands/config.py +2 -2
- claude_mpm/cli/commands/configure.py +14 -14
- claude_mpm/cli/commands/dashboard.py +1 -1
- claude_mpm/cli/commands/debug.py +3 -3
- claude_mpm/cli/commands/doctor.py +1 -1
- claude_mpm/cli/commands/mcp.py +7 -7
- claude_mpm/cli/commands/mcp_command_router.py +1 -1
- claude_mpm/cli/commands/mcp_config.py +2 -2
- claude_mpm/cli/commands/mcp_external_commands.py +2 -2
- claude_mpm/cli/commands/mcp_install_commands.py +3 -3
- claude_mpm/cli/commands/mcp_pipx_config.py +2 -2
- claude_mpm/cli/commands/mcp_setup_external.py +3 -3
- claude_mpm/cli/commands/monitor.py +1 -1
- claude_mpm/cli/commands/mpm_init_handler.py +1 -1
- claude_mpm/cli/interactive/agent_wizard.py +1 -1
- claude_mpm/cli/parsers/search_parser.py +1 -1
- claude_mpm/cli/shared/argument_patterns.py +2 -2
- claude_mpm/cli/shared/base_command.py +1 -1
- claude_mpm/cli/startup_logging.py +4 -4
- claude_mpm/config/experimental_features.py +4 -4
- claude_mpm/config/socketio_config.py +2 -2
- claude_mpm/core/agent_session_manager.py +2 -2
- claude_mpm/core/api_validator.py +3 -3
- claude_mpm/core/base_service.py +10 -1
- claude_mpm/core/cache.py +2 -2
- claude_mpm/core/config.py +4 -4
- claude_mpm/core/config_aliases.py +4 -4
- claude_mpm/core/config_constants.py +1 -1
- claude_mpm/core/error_handler.py +1 -1
- claude_mpm/core/file_utils.py +5 -5
- claude_mpm/core/framework/formatters/capability_generator.py +5 -5
- claude_mpm/core/framework/loaders/agent_loader.py +1 -1
- claude_mpm/core/framework/processors/metadata_processor.py +1 -1
- claude_mpm/core/framework/processors/template_processor.py +3 -3
- claude_mpm/core/framework_loader.py +2 -2
- claude_mpm/core/log_manager.py +4 -4
- claude_mpm/core/logger.py +2 -2
- claude_mpm/core/optimized_startup.py +1 -1
- claude_mpm/core/output_style_manager.py +1 -1
- claude_mpm/core/service_registry.py +2 -2
- claude_mpm/core/session_manager.py +3 -3
- claude_mpm/core/shared/config_loader.py +1 -1
- claude_mpm/core/socketio_pool.py +2 -2
- claude_mpm/core/unified_agent_registry.py +2 -2
- claude_mpm/core/unified_config.py +6 -6
- claude_mpm/core/unified_paths.py +2 -2
- claude_mpm/dashboard/api/simple_directory.py +1 -1
- claude_mpm/generators/agent_profile_generator.py +1 -1
- claude_mpm/hooks/claude_hooks/event_handlers.py +2 -2
- claude_mpm/hooks/claude_hooks/installer.py +9 -9
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +7 -2
- claude_mpm/hooks/claude_hooks/tool_analysis.py +2 -2
- claude_mpm/hooks/memory_integration_hook.py +1 -1
- claude_mpm/hooks/validation_hooks.py +1 -1
- claude_mpm/init.py +4 -4
- claude_mpm/models/agent_session.py +1 -1
- claude_mpm/scripts/socketio_daemon.py +5 -5
- claude_mpm/services/__init__.py +2 -2
- claude_mpm/services/agent_capabilities_service.py +1 -1
- claude_mpm/services/agents/agent_builder.py +4 -4
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +1 -1
- claude_mpm/services/agents/deployment/agent_record_service.py +3 -3
- claude_mpm/services/agents/deployment/deployment_wrapper.py +1 -1
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +2 -2
- claude_mpm/services/agents/loading/agent_profile_loader.py +2 -2
- claude_mpm/services/agents/local_template_manager.py +5 -5
- claude_mpm/services/agents/registry/deployed_agent_discovery.py +1 -1
- claude_mpm/services/agents/registry/modification_tracker.py +19 -11
- claude_mpm/services/async_session_logger.py +1 -1
- claude_mpm/services/claude_session_logger.py +1 -1
- claude_mpm/services/cli/agent_listing_service.py +3 -3
- claude_mpm/services/cli/agent_validation_service.py +1 -1
- claude_mpm/services/cli/session_manager.py +2 -2
- claude_mpm/services/core/path_resolver.py +1 -1
- claude_mpm/services/diagnostics/checks/agent_check.py +1 -1
- claude_mpm/services/diagnostics/checks/claude_code_check.py +2 -2
- claude_mpm/services/diagnostics/checks/common_issues_check.py +3 -3
- claude_mpm/services/diagnostics/checks/configuration_check.py +2 -2
- claude_mpm/services/diagnostics/checks/installation_check.py +1 -1
- claude_mpm/services/diagnostics/checks/mcp_check.py +1 -1
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +9 -9
- claude_mpm/services/diagnostics/checks/monitor_check.py +1 -1
- claude_mpm/services/diagnostics/doctor_reporter.py +1 -1
- claude_mpm/services/event_aggregator.py +1 -1
- claude_mpm/services/event_bus/event_bus.py +7 -2
- claude_mpm/services/events/consumers/dead_letter.py +2 -2
- claude_mpm/services/framework_claude_md_generator/__init__.py +1 -1
- claude_mpm/services/framework_claude_md_generator/deployment_manager.py +3 -3
- claude_mpm/services/framework_claude_md_generator/version_manager.py +1 -1
- claude_mpm/services/hook_installer_service.py +7 -7
- claude_mpm/services/infrastructure/context_preservation.py +7 -7
- claude_mpm/services/infrastructure/daemon_manager.py +5 -5
- claude_mpm/services/mcp_config_manager.py +10 -10
- claude_mpm/services/mcp_gateway/auto_configure.py +5 -5
- claude_mpm/services/mcp_gateway/config/config_loader.py +2 -2
- claude_mpm/services/mcp_gateway/config/configuration.py +3 -3
- claude_mpm/services/mcp_gateway/core/process_pool.py +3 -3
- claude_mpm/services/mcp_gateway/core/singleton_manager.py +2 -2
- claude_mpm/services/mcp_gateway/core/startup_verification.py +1 -1
- claude_mpm/services/mcp_gateway/main.py +1 -1
- claude_mpm/services/mcp_gateway/registry/service_registry.py +4 -2
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +2 -1
- claude_mpm/services/mcp_gateway/server/stdio_handler.py +1 -1
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +1 -1
- claude_mpm/services/mcp_gateway/tools/hello_world.py +1 -1
- claude_mpm/services/mcp_gateway/utils/package_version_checker.py +5 -5
- claude_mpm/services/mcp_gateway/utils/update_preferences.py +2 -2
- claude_mpm/services/mcp_service_verifier.py +1 -1
- claude_mpm/services/memory/builder.py +1 -1
- claude_mpm/services/memory/cache/shared_prompt_cache.py +2 -1
- claude_mpm/services/memory/indexed_memory.py +3 -3
- claude_mpm/services/monitor/daemon.py +1 -1
- claude_mpm/services/monitor/daemon_manager.py +9 -9
- claude_mpm/services/monitor/handlers/file.py +1 -1
- claude_mpm/services/monitor/handlers/hooks.py +3 -3
- claude_mpm/services/monitor/management/lifecycle.py +7 -7
- claude_mpm/services/monitor/server.py +2 -2
- claude_mpm/services/orphan_detection.py +13 -16
- claude_mpm/services/port_manager.py +2 -2
- claude_mpm/services/project/analyzer.py +3 -3
- claude_mpm/services/project/archive_manager.py +13 -13
- claude_mpm/services/project/dependency_analyzer.py +4 -4
- claude_mpm/services/project/documentation_manager.py +4 -4
- claude_mpm/services/project/enhanced_analyzer.py +8 -8
- claude_mpm/services/project/registry.py +4 -4
- claude_mpm/services/project_port_allocator.py +7 -11
- claude_mpm/services/session_management_service.py +1 -1
- claude_mpm/services/socketio/event_normalizer.py +1 -1
- claude_mpm/services/socketio/handlers/code_analysis.py +14 -12
- claude_mpm/services/socketio/handlers/file.py +1 -1
- claude_mpm/services/socketio/migration_utils.py +1 -1
- claude_mpm/services/socketio/server/core.py +1 -1
- claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +1 -1
- claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +4 -4
- claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +1 -1
- claude_mpm/services/unified/config_strategies/config_schema.py +4 -4
- claude_mpm/services/unified/config_strategies/context_strategy.py +6 -6
- claude_mpm/services/unified/config_strategies/error_handling_strategy.py +10 -10
- claude_mpm/services/unified/config_strategies/file_loader_strategy.py +5 -5
- claude_mpm/services/unified/config_strategies/unified_config_service.py +8 -8
- claude_mpm/services/unified/config_strategies/validation_strategy.py +15 -15
- claude_mpm/services/unified/deployment_strategies/base.py +4 -4
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +15 -15
- claude_mpm/services/unified/deployment_strategies/local.py +9 -9
- claude_mpm/services/unified/deployment_strategies/utils.py +9 -9
- claude_mpm/services/unified/deployment_strategies/vercel.py +7 -7
- claude_mpm/services/unified/unified_config.py +5 -5
- claude_mpm/services/unified/unified_deployment.py +2 -2
- claude_mpm/services/utility_service.py +1 -1
- claude_mpm/services/version_control/conflict_resolution.py +2 -2
- claude_mpm/services/version_control/git_operations.py +3 -3
- claude_mpm/services/version_control/semantic_versioning.py +13 -13
- claude_mpm/services/version_control/version_parser.py +1 -1
- claude_mpm/storage/state_storage.py +12 -13
- claude_mpm/tools/code_tree_analyzer.py +5 -5
- claude_mpm/tools/code_tree_builder.py +4 -4
- claude_mpm/tools/socketio_debug.py +1 -1
- claude_mpm/utils/agent_dependency_loader.py +4 -4
- claude_mpm/utils/common.py +2 -2
- claude_mpm/utils/config_manager.py +3 -3
- claude_mpm/utils/dependency_cache.py +2 -2
- claude_mpm/utils/dependency_strategies.py +6 -6
- claude_mpm/utils/file_utils.py +11 -11
- claude_mpm/utils/log_cleanup.py +1 -1
- claude_mpm/utils/path_operations.py +1 -1
- claude_mpm/validation/agent_validator.py +2 -2
- claude_mpm/validation/frontmatter_validator.py +1 -1
- {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.12.dist-info}/METADATA +1 -1
- {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.12.dist-info}/RECORD +183 -183
- {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.12.dist-info}/WHEEL +0 -0
- {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.12.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.12.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.12.dist-info}/top_level.txt +0 -0
|
@@ -100,7 +100,7 @@ class SemanticVersion:
|
|
|
100
100
|
version += f"+{self.build}"
|
|
101
101
|
return version
|
|
102
102
|
|
|
103
|
-
def __lt__(self, other: "SemanticVersion") -> bool:
|
|
103
|
+
def __lt__(self, other: "SemanticVersion") -> bool:
|
|
104
104
|
"""Compare versions for sorting according to semver precedence.
|
|
105
105
|
|
|
106
106
|
Comparison Rules:
|
|
@@ -416,7 +416,7 @@ class SemanticVersionManager:
|
|
|
416
416
|
return self._parse_toml_version_regex(file_path)
|
|
417
417
|
|
|
418
418
|
try:
|
|
419
|
-
with open(
|
|
419
|
+
with file_path.open("rb") as f:
|
|
420
420
|
data = tomllib.load(f)
|
|
421
421
|
|
|
422
422
|
# Try different locations for version
|
|
@@ -437,7 +437,7 @@ class SemanticVersionManager:
|
|
|
437
437
|
def _parse_toml_version_regex(self, file_path: Path) -> Optional[str]:
|
|
438
438
|
"""Parse version from TOML file using regex."""
|
|
439
439
|
try:
|
|
440
|
-
with open(
|
|
440
|
+
with file_path.open() as f:
|
|
441
441
|
content = f.read()
|
|
442
442
|
|
|
443
443
|
# Look for version = "x.y.z" pattern
|
|
@@ -463,7 +463,7 @@ class SemanticVersionManager:
|
|
|
463
463
|
def _parse_version_file(self, file_path: Path) -> Optional[str]:
|
|
464
464
|
"""Parse version from simple version file."""
|
|
465
465
|
try:
|
|
466
|
-
with open(
|
|
466
|
+
with file_path.open() as f:
|
|
467
467
|
return f.read().strip()
|
|
468
468
|
except Exception:
|
|
469
469
|
return None
|
|
@@ -471,7 +471,7 @@ class SemanticVersionManager:
|
|
|
471
471
|
def _parse_pom_xml_version(self, file_path: Path) -> Optional[str]:
|
|
472
472
|
"""Parse version from Maven pom.xml."""
|
|
473
473
|
try:
|
|
474
|
-
with open(
|
|
474
|
+
with file_path.open() as f:
|
|
475
475
|
content = f.read()
|
|
476
476
|
|
|
477
477
|
# Simple regex to find version in pom.xml
|
|
@@ -673,7 +673,7 @@ class SemanticVersionManager:
|
|
|
673
673
|
def _update_toml_version(self, file_path: Path, new_version: str) -> bool:
|
|
674
674
|
"""Update version in TOML file."""
|
|
675
675
|
try:
|
|
676
|
-
with open(
|
|
676
|
+
with file_path.open() as f:
|
|
677
677
|
content = f.read()
|
|
678
678
|
|
|
679
679
|
# Replace version field
|
|
@@ -691,7 +691,7 @@ class SemanticVersionManager:
|
|
|
691
691
|
break
|
|
692
692
|
|
|
693
693
|
if updated:
|
|
694
|
-
with open(
|
|
694
|
+
with file_path.open("w") as f:
|
|
695
695
|
f.write(content)
|
|
696
696
|
return True
|
|
697
697
|
|
|
@@ -703,7 +703,7 @@ class SemanticVersionManager:
|
|
|
703
703
|
def _update_simple_version_file(self, file_path: Path, new_version: str) -> bool:
|
|
704
704
|
"""Update version in simple version file."""
|
|
705
705
|
try:
|
|
706
|
-
with open(
|
|
706
|
+
with file_path.open("w") as f:
|
|
707
707
|
f.write(new_version + "\n")
|
|
708
708
|
return True
|
|
709
709
|
except Exception:
|
|
@@ -712,7 +712,7 @@ class SemanticVersionManager:
|
|
|
712
712
|
def _update_pom_xml_version(self, file_path: Path, new_version: str) -> bool:
|
|
713
713
|
"""Update version in Maven pom.xml."""
|
|
714
714
|
try:
|
|
715
|
-
with open(
|
|
715
|
+
with file_path.open() as f:
|
|
716
716
|
content = f.read()
|
|
717
717
|
|
|
718
718
|
# Replace first version tag (project version)
|
|
@@ -722,7 +722,7 @@ class SemanticVersionManager:
|
|
|
722
722
|
new_content = re.sub(pattern, replacement, content, count=1)
|
|
723
723
|
|
|
724
724
|
if new_content != content:
|
|
725
|
-
with open(
|
|
725
|
+
with file_path.open("w") as f:
|
|
726
726
|
f.write(new_content)
|
|
727
727
|
return True
|
|
728
728
|
|
|
@@ -841,7 +841,7 @@ class SemanticVersionManager:
|
|
|
841
841
|
|
|
842
842
|
# Read existing changelog or create new one
|
|
843
843
|
if changelog_path.exists():
|
|
844
|
-
with open(
|
|
844
|
+
with changelog_path.open() as f:
|
|
845
845
|
existing_content = f.read()
|
|
846
846
|
|
|
847
847
|
# Insert new entry after title
|
|
@@ -864,7 +864,7 @@ class SemanticVersionManager:
|
|
|
864
864
|
content = f"# Changelog\n\n{new_entry}\n"
|
|
865
865
|
|
|
866
866
|
# Write updated changelog
|
|
867
|
-
with open(
|
|
867
|
+
with changelog_path.open("w") as f:
|
|
868
868
|
f.write(content)
|
|
869
869
|
|
|
870
870
|
self.logger.info(f"Updated {changelog_file} with version {version}")
|
|
@@ -945,7 +945,7 @@ class SemanticVersionManager:
|
|
|
945
945
|
versions = []
|
|
946
946
|
|
|
947
947
|
try:
|
|
948
|
-
with open(
|
|
948
|
+
with changelog_path.open() as f:
|
|
949
949
|
content = f.read()
|
|
950
950
|
|
|
951
951
|
# Find version entries
|
|
@@ -365,7 +365,7 @@ class EnhancedVersionParser:
|
|
|
365
365
|
package_file = self.project_root / "package.json"
|
|
366
366
|
if package_file.exists():
|
|
367
367
|
try:
|
|
368
|
-
with open(
|
|
368
|
+
with package_file.open() as f:
|
|
369
369
|
data = json.load(f)
|
|
370
370
|
version = data.get("version")
|
|
371
371
|
if version and self._version_pattern.match(version):
|
|
@@ -24,6 +24,10 @@ import time
|
|
|
24
24
|
from contextlib import contextmanager, suppress
|
|
25
25
|
from typing import Any, Dict, Optional, Tuple, Union
|
|
26
26
|
|
|
27
|
+
from claude_mpm.core.logging_utils import get_logger
|
|
28
|
+
|
|
29
|
+
logger = get_logger(__name__)
|
|
30
|
+
|
|
27
31
|
|
|
28
32
|
class StateStorage:
|
|
29
33
|
"""Reliable state storage with atomic operations."""
|
|
@@ -37,11 +41,6 @@ class StateStorage:
|
|
|
37
41
|
self.storage_dir = storage_dir or Path.home() / ".claude-mpm" / "storage"
|
|
38
42
|
self.storage_dir.mkdir(parents=True, exist_ok=True)
|
|
39
43
|
|
|
40
|
-
# Logging
|
|
41
|
-
from claude_mpm.core.logging_utils import get_logger
|
|
42
|
-
|
|
43
|
-
logger = get_logger(__name__)
|
|
44
|
-
|
|
45
44
|
# File locking support (Unix-like systems)
|
|
46
45
|
self.supports_locking = platform.system() != "Windows"
|
|
47
46
|
|
|
@@ -80,7 +79,7 @@ logger = get_logger(__name__)
|
|
|
80
79
|
with gzip.open(file_path, "wt", encoding="utf-8") as f:
|
|
81
80
|
json.dump(data, f, indent=2, default=str)
|
|
82
81
|
else:
|
|
83
|
-
with open(
|
|
82
|
+
with file_path.open("w") as f:
|
|
84
83
|
json.dump(data, f, indent=2, default=str)
|
|
85
84
|
|
|
86
85
|
self.write_count += 1
|
|
@@ -119,7 +118,7 @@ logger = get_logger(__name__)
|
|
|
119
118
|
with gzip.open(file_path, "rt", encoding="utf-8") as f:
|
|
120
119
|
data = json.load(f)
|
|
121
120
|
else:
|
|
122
|
-
with open(
|
|
121
|
+
with file_path.open() as f:
|
|
123
122
|
data = json.load(f)
|
|
124
123
|
|
|
125
124
|
self.read_count += 1
|
|
@@ -160,7 +159,7 @@ logger = get_logger(__name__)
|
|
|
160
159
|
with gzip.open(file_path, "wb") as f:
|
|
161
160
|
pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)
|
|
162
161
|
else:
|
|
163
|
-
with open(
|
|
162
|
+
with file_path.open("wb") as f:
|
|
164
163
|
pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)
|
|
165
164
|
|
|
166
165
|
self.write_count += 1
|
|
@@ -199,7 +198,7 @@ logger = get_logger(__name__)
|
|
|
199
198
|
with gzip.open(file_path, "rb") as f:
|
|
200
199
|
data = pickle.load(f)
|
|
201
200
|
else:
|
|
202
|
-
with open(
|
|
201
|
+
with file_path.open("rb") as f:
|
|
203
202
|
data = pickle.load(f)
|
|
204
203
|
|
|
205
204
|
self.read_count += 1
|
|
@@ -328,7 +327,7 @@ logger = get_logger(__name__)
|
|
|
328
327
|
|
|
329
328
|
# Calculate checksum
|
|
330
329
|
hasher = hashlib.sha256()
|
|
331
|
-
with open(
|
|
330
|
+
with file_path.open("rb") as f:
|
|
332
331
|
for chunk in iter(lambda: f.read(4096), b""):
|
|
333
332
|
hasher.update(chunk)
|
|
334
333
|
|
|
@@ -336,7 +335,7 @@ logger = get_logger(__name__)
|
|
|
336
335
|
|
|
337
336
|
# Write checksum file
|
|
338
337
|
checksum_path = file_path.with_suffix(file_path.suffix + ".sha256")
|
|
339
|
-
with open(
|
|
338
|
+
with checksum_path.open("w") as f:
|
|
340
339
|
f.write(checksum)
|
|
341
340
|
|
|
342
341
|
except Exception as e:
|
|
@@ -359,12 +358,12 @@ logger = get_logger(__name__)
|
|
|
359
358
|
return True # No checksum to verify
|
|
360
359
|
|
|
361
360
|
# Read expected checksum
|
|
362
|
-
with open(
|
|
361
|
+
with checksum_path.open() as f:
|
|
363
362
|
expected = f.read().strip()
|
|
364
363
|
|
|
365
364
|
# Calculate actual checksum
|
|
366
365
|
hasher = hashlib.sha256()
|
|
367
|
-
with open(
|
|
366
|
+
with file_path.open("rb") as f:
|
|
368
367
|
for chunk in iter(lambda: f.read(4096), b""):
|
|
369
368
|
hasher.update(chunk)
|
|
370
369
|
|
|
@@ -692,7 +692,7 @@ class MultiLanguageAnalyzer:
|
|
|
692
692
|
nodes = []
|
|
693
693
|
|
|
694
694
|
try:
|
|
695
|
-
with open(
|
|
695
|
+
with file_path.open("rb") as f:
|
|
696
696
|
source = f.read()
|
|
697
697
|
|
|
698
698
|
parser = self.parsers[language]
|
|
@@ -1099,7 +1099,7 @@ class CodeTreeAnalyzer:
|
|
|
1099
1099
|
def _get_file_hash(self, file_path: Path) -> str:
|
|
1100
1100
|
"""Get hash of file contents for caching."""
|
|
1101
1101
|
hasher = hashlib.md5()
|
|
1102
|
-
with open(
|
|
1102
|
+
with file_path.open("rb") as f:
|
|
1103
1103
|
hasher.update(f.read())
|
|
1104
1104
|
return hasher.hexdigest()
|
|
1105
1105
|
|
|
@@ -1166,7 +1166,7 @@ class CodeTreeAnalyzer:
|
|
|
1166
1166
|
cache_file = self.cache_dir / "code_tree_cache.json"
|
|
1167
1167
|
if cache_file.exists():
|
|
1168
1168
|
try:
|
|
1169
|
-
with open(
|
|
1169
|
+
with cache_file.open() as f:
|
|
1170
1170
|
cache_data = json.load(f)
|
|
1171
1171
|
# Reconstruct CodeNode objects
|
|
1172
1172
|
for key, nodes_data in cache_data.items():
|
|
@@ -1203,7 +1203,7 @@ class CodeTreeAnalyzer:
|
|
|
1203
1203
|
for n in nodes
|
|
1204
1204
|
]
|
|
1205
1205
|
|
|
1206
|
-
with open(
|
|
1206
|
+
with cache_file.open("w") as f:
|
|
1207
1207
|
json.dump(cache_data, f, indent=2)
|
|
1208
1208
|
|
|
1209
1209
|
self.logger.info(f"Saved cache with {len(self.cache)} entries")
|
|
@@ -1726,7 +1726,7 @@ class CodeTreeAnalyzer:
|
|
|
1726
1726
|
},
|
|
1727
1727
|
}
|
|
1728
1728
|
|
|
1729
|
-
def _is_internal_node(self, node: CodeNode) -> bool:
|
|
1729
|
+
def _is_internal_node(self, node: CodeNode) -> bool:
|
|
1730
1730
|
"""Check if node is an internal function that should be filtered."""
|
|
1731
1731
|
# Don't filter classes - always show them
|
|
1732
1732
|
if node.node_type == "class":
|
|
@@ -81,7 +81,7 @@ class GitignoreParser:
|
|
|
81
81
|
|
|
82
82
|
if gitignore_path.exists():
|
|
83
83
|
try:
|
|
84
|
-
with open(
|
|
84
|
+
with gitignore_path.open() as f:
|
|
85
85
|
for line in f:
|
|
86
86
|
line = line.strip()
|
|
87
87
|
# Skip comments and empty lines
|
|
@@ -481,7 +481,7 @@ class CodeTreeBuilder:
|
|
|
481
481
|
hasher = hashlib.md5()
|
|
482
482
|
|
|
483
483
|
try:
|
|
484
|
-
with open(
|
|
484
|
+
with path.open("rb") as f:
|
|
485
485
|
# Read in chunks for large files
|
|
486
486
|
while chunk := f.read(8192):
|
|
487
487
|
hasher.update(chunk)
|
|
@@ -508,7 +508,7 @@ class CodeTreeBuilder:
|
|
|
508
508
|
"generated_at": datetime.now(timezone.utc).isoformat(),
|
|
509
509
|
}
|
|
510
510
|
|
|
511
|
-
with open(
|
|
511
|
+
with output_path.open("w") as f:
|
|
512
512
|
json.dump(tree_dict, f, indent=2)
|
|
513
513
|
|
|
514
514
|
self.logger.info(f"Saved tree to {output_path}")
|
|
@@ -522,7 +522,7 @@ class CodeTreeBuilder:
|
|
|
522
522
|
Returns:
|
|
523
523
|
Root tree node
|
|
524
524
|
"""
|
|
525
|
-
with open(
|
|
525
|
+
with input_path.open() as f:
|
|
526
526
|
tree_dict = json.load(f)
|
|
527
527
|
|
|
528
528
|
# Remove stats if present
|
|
@@ -430,7 +430,7 @@ class SocketIODebugger:
|
|
|
430
430
|
return
|
|
431
431
|
|
|
432
432
|
try:
|
|
433
|
-
with
|
|
433
|
+
with self.output_file.open("a") as f:
|
|
434
434
|
f.write(json.dumps(data) + "\n")
|
|
435
435
|
except Exception as e:
|
|
436
436
|
self._log("error", f"Failed to write to file: {e}")
|
|
@@ -111,7 +111,7 @@ class AgentDependencyLoader:
|
|
|
111
111
|
config_file = config_dir / f"{agent_id}.json"
|
|
112
112
|
if config_file.exists():
|
|
113
113
|
try:
|
|
114
|
-
with open(
|
|
114
|
+
with config_file.open() as f:
|
|
115
115
|
config = json.load(f)
|
|
116
116
|
if "dependencies" in config:
|
|
117
117
|
agent_dependencies[agent_id] = config["dependencies"]
|
|
@@ -835,7 +835,7 @@ class AgentDependencyLoader:
|
|
|
835
835
|
hash_obj.update(str(stat.st_size).encode("utf-8"))
|
|
836
836
|
|
|
837
837
|
# Include file content for comprehensive change detection
|
|
838
|
-
with open(
|
|
838
|
+
with agent_path.open("rb") as f:
|
|
839
839
|
hash_obj.update(f.read())
|
|
840
840
|
except Exception as e:
|
|
841
841
|
logger.debug(f"Could not hash agent file {agent_path}: {e}")
|
|
@@ -855,7 +855,7 @@ class AgentDependencyLoader:
|
|
|
855
855
|
return {}
|
|
856
856
|
|
|
857
857
|
try:
|
|
858
|
-
with
|
|
858
|
+
with self.deployment_state_file.open() as f:
|
|
859
859
|
return json.load(f)
|
|
860
860
|
except Exception as e:
|
|
861
861
|
logger.debug(f"Could not load deployment state: {e}")
|
|
@@ -872,7 +872,7 @@ class AgentDependencyLoader:
|
|
|
872
872
|
# Ensure directory exists
|
|
873
873
|
self.deployment_state_file.parent.mkdir(parents=True, exist_ok=True)
|
|
874
874
|
|
|
875
|
-
with
|
|
875
|
+
with self.deployment_state_file.open("w") as f:
|
|
876
876
|
json.dump(state, f, indent=2)
|
|
877
877
|
except Exception as e:
|
|
878
878
|
logger.debug(f"Could not save deployment state: {e}")
|
claude_mpm/utils/common.py
CHANGED
|
@@ -85,7 +85,7 @@ def save_json_safe(
|
|
|
85
85
|
if create_parents:
|
|
86
86
|
file_path.parent.mkdir(parents=True, exist_ok=True)
|
|
87
87
|
|
|
88
|
-
with open(
|
|
88
|
+
with file_path.open("w", encoding=encoding) as f:
|
|
89
89
|
json.dump(data, f, indent=indent, ensure_ascii=False)
|
|
90
90
|
return True
|
|
91
91
|
except Exception as e:
|
|
@@ -149,7 +149,7 @@ def save_yaml_safe(
|
|
|
149
149
|
if create_parents:
|
|
150
150
|
file_path.parent.mkdir(parents=True, exist_ok=True)
|
|
151
151
|
|
|
152
|
-
with open(
|
|
152
|
+
with file_path.open("w", encoding=encoding) as f:
|
|
153
153
|
yaml.safe_dump(data, f, default_flow_style=False, allow_unicode=True)
|
|
154
154
|
return True
|
|
155
155
|
except Exception as e:
|
|
@@ -242,7 +242,7 @@ class ConfigurationManager:
|
|
|
242
242
|
# Create parent directories if needed
|
|
243
243
|
file_path.parent.mkdir(parents=True, exist_ok=True)
|
|
244
244
|
|
|
245
|
-
with open(
|
|
245
|
+
with file_path.open("w", encoding="utf-8") as f:
|
|
246
246
|
json.dump(config, f, indent=indent, sort_keys=sort_keys)
|
|
247
247
|
logger.info(f"Configuration saved to {file_path}")
|
|
248
248
|
except Exception as e:
|
|
@@ -279,7 +279,7 @@ class ConfigurationManager:
|
|
|
279
279
|
# Create parent directories if needed
|
|
280
280
|
file_path.parent.mkdir(parents=True, exist_ok=True)
|
|
281
281
|
|
|
282
|
-
with open(
|
|
282
|
+
with file_path.open("w", encoding="utf-8") as f:
|
|
283
283
|
yaml.dump(
|
|
284
284
|
config,
|
|
285
285
|
f,
|
|
@@ -313,7 +313,7 @@ class ConfigurationManager:
|
|
|
313
313
|
# Create parent directories if needed
|
|
314
314
|
file_path.parent.mkdir(parents=True, exist_ok=True)
|
|
315
315
|
|
|
316
|
-
with open(
|
|
316
|
+
with file_path.open("w", encoding="utf-8") as f:
|
|
317
317
|
toml.dump(config, f)
|
|
318
318
|
logger.info(f"Configuration saved to {file_path}")
|
|
319
319
|
except Exception as e:
|
|
@@ -66,7 +66,7 @@ class DependencyCache:
|
|
|
66
66
|
return self._cache_data
|
|
67
67
|
|
|
68
68
|
try:
|
|
69
|
-
with
|
|
69
|
+
with self.cache_file.open() as f:
|
|
70
70
|
self._cache_data = json.load(f)
|
|
71
71
|
return self._cache_data
|
|
72
72
|
except Exception as e:
|
|
@@ -85,7 +85,7 @@ class DependencyCache:
|
|
|
85
85
|
# Ensure directory exists
|
|
86
86
|
self.cache_dir.mkdir(parents=True, exist_ok=True)
|
|
87
87
|
|
|
88
|
-
with
|
|
88
|
+
with self.cache_file.open("w") as f:
|
|
89
89
|
json.dump(cache_data, f, indent=2)
|
|
90
90
|
|
|
91
91
|
self._cache_data = cache_data
|
|
@@ -128,7 +128,7 @@ class DependencyStrategy:
|
|
|
128
128
|
# Try to load YAML config
|
|
129
129
|
import yaml
|
|
130
130
|
|
|
131
|
-
with
|
|
131
|
+
with self.config_path.open() as f:
|
|
132
132
|
config = yaml.safe_load(f)
|
|
133
133
|
mode_str = config.get("dependency_mode")
|
|
134
134
|
if mode_str:
|
|
@@ -155,7 +155,7 @@ class DependencyStrategy:
|
|
|
155
155
|
return True
|
|
156
156
|
|
|
157
157
|
try:
|
|
158
|
-
with
|
|
158
|
+
with self.cache_path.open() as f:
|
|
159
159
|
cache = json.load(f)
|
|
160
160
|
last_check = datetime.fromisoformat(cache.get("timestamp", ""))
|
|
161
161
|
|
|
@@ -186,7 +186,7 @@ class DependencyStrategy:
|
|
|
186
186
|
"results": results,
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
-
with
|
|
189
|
+
with self.cache_path.open("w") as f:
|
|
190
190
|
json.dump(cache_data, f, indent=2)
|
|
191
191
|
|
|
192
192
|
logger.debug(f"Cached dependency results to {self.cache_path}")
|
|
@@ -205,7 +205,7 @@ class DependencyStrategy:
|
|
|
205
205
|
return None
|
|
206
206
|
|
|
207
207
|
try:
|
|
208
|
-
with
|
|
208
|
+
with self.cache_path.open() as f:
|
|
209
209
|
cache = json.load(f)
|
|
210
210
|
return cache.get("results")
|
|
211
211
|
except Exception:
|
|
@@ -285,7 +285,7 @@ class DependencyStrategy:
|
|
|
285
285
|
if self.config_path.exists():
|
|
286
286
|
import yaml
|
|
287
287
|
|
|
288
|
-
with
|
|
288
|
+
with self.config_path.open() as f:
|
|
289
289
|
config = yaml.safe_load(f) or {}
|
|
290
290
|
|
|
291
291
|
# Update dependency mode
|
|
@@ -294,7 +294,7 @@ class DependencyStrategy:
|
|
|
294
294
|
# Save config
|
|
295
295
|
import yaml
|
|
296
296
|
|
|
297
|
-
with
|
|
297
|
+
with self.config_path.open("w") as f:
|
|
298
298
|
yaml.dump(config, f, default_flow_style=False)
|
|
299
299
|
|
|
300
300
|
print(f"✓ Saved preference: {mode.value}")
|
claude_mpm/utils/file_utils.py
CHANGED
|
@@ -41,7 +41,7 @@ def ensure_directory(path: Union[str, Path]) -> Path:
|
|
|
41
41
|
"operation": "mkdir",
|
|
42
42
|
"error_type": type(e).__name__,
|
|
43
43
|
},
|
|
44
|
-
)
|
|
44
|
+
) from e
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
def safe_read_file(path: Union[str, Path], encoding: str = "utf-8") -> str:
|
|
@@ -61,7 +61,7 @@ def safe_read_file(path: Union[str, Path], encoding: str = "utf-8") -> str:
|
|
|
61
61
|
path = Path(path)
|
|
62
62
|
try:
|
|
63
63
|
return path.read_text(encoding=encoding)
|
|
64
|
-
except FileNotFoundError:
|
|
64
|
+
except FileNotFoundError as e:
|
|
65
65
|
raise FileOperationError(
|
|
66
66
|
f"File not found: {path}",
|
|
67
67
|
context={
|
|
@@ -70,7 +70,7 @@ def safe_read_file(path: Union[str, Path], encoding: str = "utf-8") -> str:
|
|
|
70
70
|
"encoding": encoding,
|
|
71
71
|
"error_type": "FileNotFoundError",
|
|
72
72
|
},
|
|
73
|
-
)
|
|
73
|
+
) from e
|
|
74
74
|
except (OSError, PermissionError, UnicodeDecodeError) as e:
|
|
75
75
|
raise FileOperationError(
|
|
76
76
|
f"Failed to read file: {e}",
|
|
@@ -80,7 +80,7 @@ def safe_read_file(path: Union[str, Path], encoding: str = "utf-8") -> str:
|
|
|
80
80
|
"encoding": encoding,
|
|
81
81
|
"error_type": type(e).__name__,
|
|
82
82
|
},
|
|
83
|
-
)
|
|
83
|
+
) from e
|
|
84
84
|
|
|
85
85
|
|
|
86
86
|
def safe_write_file(
|
|
@@ -107,7 +107,7 @@ def safe_write_file(
|
|
|
107
107
|
ensure_directory(path.parent)
|
|
108
108
|
path.write_text(content, encoding=encoding)
|
|
109
109
|
except Exception as e:
|
|
110
|
-
raise FileOperationError(f"Failed to write file {path}: {e}")
|
|
110
|
+
raise FileOperationError(f"Failed to write file {path}: {e}") from e
|
|
111
111
|
|
|
112
112
|
|
|
113
113
|
def atomic_write(
|
|
@@ -152,7 +152,7 @@ def atomic_write(
|
|
|
152
152
|
os.unlink(temp_path)
|
|
153
153
|
except Exception:
|
|
154
154
|
pass
|
|
155
|
-
raise FileOperationError(f"Failed to atomically write file {path}: {e}")
|
|
155
|
+
raise FileOperationError(f"Failed to atomically write file {path}: {e}") from e
|
|
156
156
|
|
|
157
157
|
|
|
158
158
|
def get_file_info(path: Union[str, Path]) -> Optional[Dict[str, Any]]:
|
|
@@ -211,7 +211,7 @@ def safe_copy_file(
|
|
|
211
211
|
shutil.copy2(src, dst)
|
|
212
212
|
|
|
213
213
|
except Exception as e:
|
|
214
|
-
raise FileOperationError(f"Failed to copy {src} to {dst}: {e}")
|
|
214
|
+
raise FileOperationError(f"Failed to copy {src} to {dst}: {e}") from e
|
|
215
215
|
|
|
216
216
|
|
|
217
217
|
def safe_remove_file(path: Union[str, Path]) -> bool:
|
|
@@ -234,7 +234,7 @@ def safe_remove_file(path: Union[str, Path]) -> bool:
|
|
|
234
234
|
path.unlink()
|
|
235
235
|
return True
|
|
236
236
|
except Exception as e:
|
|
237
|
-
raise FileOperationError(f"Failed to remove file {path}: {e}")
|
|
237
|
+
raise FileOperationError(f"Failed to remove file {path}: {e}") from e
|
|
238
238
|
|
|
239
239
|
|
|
240
240
|
def read_json_file(path: Union[str, Path]) -> Any:
|
|
@@ -254,7 +254,7 @@ def read_json_file(path: Union[str, Path]) -> Any:
|
|
|
254
254
|
content = safe_read_file(path)
|
|
255
255
|
return json.loads(content)
|
|
256
256
|
except json.JSONDecodeError as e:
|
|
257
|
-
raise FileOperationError(f"Invalid JSON in file {path}: {e}")
|
|
257
|
+
raise FileOperationError(f"Invalid JSON in file {path}: {e}") from e
|
|
258
258
|
|
|
259
259
|
|
|
260
260
|
def write_json_file(
|
|
@@ -279,7 +279,7 @@ def write_json_file(
|
|
|
279
279
|
else:
|
|
280
280
|
safe_write_file(path, content)
|
|
281
281
|
except Exception as e:
|
|
282
|
-
raise FileOperationError(f"Failed to write JSON file {path}: {e}")
|
|
282
|
+
raise FileOperationError(f"Failed to write JSON file {path}: {e}") from e
|
|
283
283
|
|
|
284
284
|
|
|
285
285
|
def backup_file(path: Union[str, Path], backup_suffix: str = ".backup") -> Path:
|
|
@@ -303,4 +303,4 @@ def backup_file(path: Union[str, Path], backup_suffix: str = ".backup") -> Path:
|
|
|
303
303
|
safe_copy_file(path, backup_path)
|
|
304
304
|
return backup_path
|
|
305
305
|
except Exception as e:
|
|
306
|
-
raise FileOperationError(f"Failed to create backup of {path}: {e}")
|
|
306
|
+
raise FileOperationError(f"Failed to create backup of {path}: {e}") from e
|
claude_mpm/utils/log_cleanup.py
CHANGED
|
@@ -357,7 +357,7 @@ class LogCleanupUtility:
|
|
|
357
357
|
space_saved += estimated_saved
|
|
358
358
|
else:
|
|
359
359
|
# Actually compress the file
|
|
360
|
-
with open(
|
|
360
|
+
with log_file.open("rb") as f_in:
|
|
361
361
|
with gzip.open(
|
|
362
362
|
compressed_path, "wb", compresslevel=9
|
|
363
363
|
) as f_out:
|
|
@@ -187,7 +187,7 @@ class PathOperations:
|
|
|
187
187
|
shutil.move(tmp_path, str(path_obj))
|
|
188
188
|
else:
|
|
189
189
|
# Direct write
|
|
190
|
-
with open(
|
|
190
|
+
with path_obj.open("w", encoding=encoding) as f:
|
|
191
191
|
f.write(content)
|
|
192
192
|
|
|
193
193
|
logger.info(f"Successfully wrote to {path}")
|
|
@@ -102,7 +102,7 @@ class AgentValidator:
|
|
|
102
102
|
if not self.schema_path.is_file():
|
|
103
103
|
raise ValueError(f"Schema path is not a file: {self.schema_path}")
|
|
104
104
|
|
|
105
|
-
with
|
|
105
|
+
with self.schema_path.open() as f:
|
|
106
106
|
return json.load(f)
|
|
107
107
|
except Exception as e:
|
|
108
108
|
logger.error(f"Failed to load schema from {self.schema_path}: {e}")
|
|
@@ -392,7 +392,7 @@ class AgentValidator:
|
|
|
392
392
|
max_size = SystemLimits.MAX_AGENT_CONFIG_SIZE
|
|
393
393
|
if file_size > max_size:
|
|
394
394
|
raise ValueError(ErrorMessages.FILE_TOO_LARGE.format(limit=max_size))
|
|
395
|
-
with open(
|
|
395
|
+
with file_path.open() as f:
|
|
396
396
|
agent_data = json.load(f)
|
|
397
397
|
|
|
398
398
|
result = self.validate_agent(agent_data)
|