claude-mpm 4.5.11__py3-none-any.whl → 4.5.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/BASE_ENGINEER.md +47 -0
- claude_mpm/agents/BASE_QA.md +60 -0
- claude_mpm/agents/frontmatter_validator.py +4 -4
- claude_mpm/agents/templates/nextjs_engineer.json +2 -2
- claude_mpm/agents/templates/qa.json +13 -3
- claude_mpm/agents/templates/react_engineer.json +2 -2
- claude_mpm/agents/templates/typescript_engineer.json +2 -2
- claude_mpm/agents/templates/web_qa.json +14 -3
- 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 +6 -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 +6 -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 +9 -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 +5 -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 +11 -16
- claude_mpm/services/port_manager.py +2 -2
- claude_mpm/services/project/analyzer.py +3 -3
- claude_mpm/services/project/archive_manager.py +17 -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 +19 -8
- claude_mpm/services/project/registry.py +4 -4
- claude_mpm/services/project_port_allocator.py +7 -12
- 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 +8 -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 +11 -11
- claude_mpm/services/unified/deployment_strategies/utils.py +11 -9
- claude_mpm/services/unified/deployment_strategies/vercel.py +7 -9
- 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.13.dist-info}/METADATA +1 -1
- {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.13.dist-info}/RECORD +190 -190
- {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.13.dist-info}/WHEEL +0 -0
- {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.13.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.13.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.13.dist-info}/top_level.txt +0 -0
@@ -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)
|