claude-mpm 4.5.8__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.
- claude_mpm/VERSION +1 -1
- claude_mpm/__init__.py +20 -5
- claude_mpm/agents/agent_loader.py +19 -2
- claude_mpm/agents/base_agent_loader.py +5 -5
- claude_mpm/agents/frontmatter_validator.py +4 -4
- claude_mpm/agents/templates/agent-manager.json +3 -3
- claude_mpm/agents/templates/agentic-coder-optimizer.json +3 -3
- claude_mpm/agents/templates/api_qa.json +1 -1
- claude_mpm/agents/templates/clerk-ops.json +3 -3
- claude_mpm/agents/templates/code_analyzer.json +3 -3
- claude_mpm/agents/templates/dart_engineer.json +294 -0
- claude_mpm/agents/templates/data_engineer.json +3 -3
- claude_mpm/agents/templates/documentation.json +2 -2
- claude_mpm/agents/templates/engineer.json +2 -2
- claude_mpm/agents/templates/gcp_ops_agent.json +2 -2
- claude_mpm/agents/templates/imagemagick.json +1 -1
- claude_mpm/agents/templates/local_ops_agent.json +319 -41
- claude_mpm/agents/templates/memory_manager.json +2 -2
- claude_mpm/agents/templates/nextjs_engineer.json +2 -2
- claude_mpm/agents/templates/ops.json +2 -2
- claude_mpm/agents/templates/php-engineer.json +1 -1
- claude_mpm/agents/templates/project_organizer.json +1 -1
- claude_mpm/agents/templates/prompt-engineer.json +6 -4
- claude_mpm/agents/templates/python_engineer.json +2 -2
- claude_mpm/agents/templates/qa.json +1 -1
- claude_mpm/agents/templates/react_engineer.json +3 -3
- claude_mpm/agents/templates/refactoring_engineer.json +3 -3
- claude_mpm/agents/templates/research.json +2 -2
- claude_mpm/agents/templates/security.json +2 -2
- claude_mpm/agents/templates/ticketing.json +2 -2
- claude_mpm/agents/templates/typescript_engineer.json +2 -2
- claude_mpm/agents/templates/vercel_ops_agent.json +2 -2
- claude_mpm/agents/templates/version_control.json +2 -2
- claude_mpm/agents/templates/web_qa.json +6 -6
- claude_mpm/agents/templates/web_ui.json +3 -3
- claude_mpm/cli/__init__.py +49 -19
- 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 +605 -21
- 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/configure_parser.py +5 -0
- 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/__init__.py +53 -17
- 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 +5 -5
- 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 +11 -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/response_tracking.py +16 -11
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +16 -13
- 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 +145 -161
- 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_config_loader.py +21 -0
- 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/loading/base_agent_manager.py +12 -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 +3 -3
- claude_mpm/services/claude_session_logger.py +4 -4
- 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 +169 -48
- claude_mpm/services/mcp_gateway/__init__.py +98 -94
- 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/event_emitter.py +1 -1
- 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 +788 -0
- 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 +597 -0
- claude_mpm/services/response_tracker.py +1 -1
- claude_mpm/services/session_management_service.py +1 -1
- claude_mpm/services/session_manager.py +6 -4
- 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.8.dist-info → claude_mpm-4.5.12.dist-info}/METADATA +1 -1
- {claude_mpm-4.5.8.dist-info → claude_mpm-4.5.12.dist-info}/RECORD +226 -223
- {claude_mpm-4.5.8.dist-info → claude_mpm-4.5.12.dist-info}/WHEEL +0 -0
- {claude_mpm-4.5.8.dist-info → claude_mpm-4.5.12.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.5.8.dist-info → claude_mpm-4.5.12.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.5.8.dist-info → claude_mpm-4.5.12.dist-info}/top_level.txt +0 -0
@@ -474,7 +474,7 @@ class PortManager:
|
|
474
474
|
"""Load registered instances from file."""
|
475
475
|
try:
|
476
476
|
if self.instances_file.exists():
|
477
|
-
with
|
477
|
+
with self.instances_file.open() as f:
|
478
478
|
return json.load(f)
|
479
479
|
except Exception as e:
|
480
480
|
self.logger.warning(f"Failed to load instances file: {e}")
|
@@ -484,7 +484,7 @@ class PortManager:
|
|
484
484
|
def save_instances(self, instances: Dict) -> None:
|
485
485
|
"""Save registered instances to file."""
|
486
486
|
try:
|
487
|
-
with
|
487
|
+
with self.instances_file.open("w") as f:
|
488
488
|
json.dump(instances, f, indent=2)
|
489
489
|
except Exception as e:
|
490
490
|
self.logger.error(f"Failed to save instances file: {e}")
|
@@ -313,7 +313,7 @@ class ProjectAnalyzer(ProjectAnalyzerInterface):
|
|
313
313
|
) -> None:
|
314
314
|
"""Parse package.json for Node.js project details."""
|
315
315
|
try:
|
316
|
-
with open(
|
316
|
+
with package_path.open() as f:
|
317
317
|
package_data = json.load(f)
|
318
318
|
|
319
319
|
# Extract dependencies
|
@@ -382,7 +382,7 @@ class ProjectAnalyzer(ProjectAnalyzerInterface):
|
|
382
382
|
f"TOML parsing not available for {deps_path}"
|
383
383
|
)
|
384
384
|
return
|
385
|
-
with open(
|
385
|
+
with deps_path.open("rb") as f:
|
386
386
|
data = tomllib.load(f)
|
387
387
|
deps = list(data.get("project", {}).get("dependencies", []))
|
388
388
|
deps.extend(
|
@@ -430,7 +430,7 @@ class ProjectAnalyzer(ProjectAnalyzerInterface):
|
|
430
430
|
except ImportError:
|
431
431
|
self.logger.warning(f"TOML parsing not available for {cargo_path}")
|
432
432
|
return
|
433
|
-
with open(
|
433
|
+
with cargo_path.open("rb") as f:
|
434
434
|
cargo_data = tomllib.load(f)
|
435
435
|
|
436
436
|
deps = cargo_data.get("dependencies", {})
|
@@ -24,7 +24,7 @@ import json
|
|
24
24
|
import re
|
25
25
|
import shutil
|
26
26
|
import subprocess
|
27
|
-
from datetime import datetime, timedelta
|
27
|
+
from datetime import datetime, timedelta, timezone
|
28
28
|
from pathlib import Path
|
29
29
|
from typing import Dict, List, Optional, Tuple
|
30
30
|
|
@@ -116,7 +116,7 @@ Generated by Claude MPM Archive Manager
|
|
116
116
|
|
117
117
|
try:
|
118
118
|
# Generate archive filename
|
119
|
-
timestamp = datetime.now().strftime("%Y-%m-%dT%H-%M-%S")
|
119
|
+
timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H-%M-%S")
|
120
120
|
archive_name = f"{file_path.name}.{timestamp}{file_path.suffix}"
|
121
121
|
archive_file_path = self.archive_path / archive_name
|
122
122
|
|
@@ -130,7 +130,7 @@ Generated by Claude MPM Archive Manager
|
|
130
130
|
meta_data.update(
|
131
131
|
{
|
132
132
|
"original_path": str(file_path),
|
133
|
-
"archived_at": datetime.now().isoformat(),
|
133
|
+
"archived_at": datetime.now(timezone.utc).isoformat(),
|
134
134
|
"reason": reason or "Manual archive",
|
135
135
|
"file_size": file_path.stat().st_size,
|
136
136
|
"file_hash": self._calculate_file_hash(file_path),
|
@@ -152,7 +152,7 @@ Generated by Claude MPM Archive Manager
|
|
152
152
|
def _calculate_file_hash(self, file_path: Path) -> str:
|
153
153
|
"""Calculate MD5 hash of file."""
|
154
154
|
hasher = hashlib.md5()
|
155
|
-
with open(
|
155
|
+
with file_path.open("rb") as f:
|
156
156
|
for chunk in iter(lambda: f.read(4096), b""):
|
157
157
|
hasher.update(chunk)
|
158
158
|
return hasher.hexdigest()
|
@@ -172,7 +172,7 @@ Generated by Claude MPM Archive Manager
|
|
172
172
|
logger.info(f"Removed old archive: {archive.name}")
|
173
173
|
|
174
174
|
# Compress old archives
|
175
|
-
cutoff_compress = datetime.now() - timedelta(days=self.COMPRESS_AFTER_DAYS)
|
175
|
+
cutoff_compress = datetime.now(timezone.utc) - timedelta(days=self.COMPRESS_AFTER_DAYS)
|
176
176
|
for archive in archives:
|
177
177
|
if archive.suffix != ".gz":
|
178
178
|
mtime = datetime.fromtimestamp(archive.stat().st_mtime)
|
@@ -180,7 +180,7 @@ Generated by Claude MPM Archive Manager
|
|
180
180
|
self._compress_archive(archive)
|
181
181
|
|
182
182
|
# Delete very old archives
|
183
|
-
cutoff_delete = datetime.now() - timedelta(days=self.DELETE_AFTER_DAYS)
|
183
|
+
cutoff_delete = datetime.now(timezone.utc) - timedelta(days=self.DELETE_AFTER_DAYS)
|
184
184
|
for archive in archives:
|
185
185
|
mtime = datetime.fromtimestamp(archive.stat().st_mtime)
|
186
186
|
if mtime < cutoff_delete:
|
@@ -204,7 +204,7 @@ Generated by Claude MPM Archive Manager
|
|
204
204
|
try:
|
205
205
|
compressed_path = archive_path.with_suffix(archive_path.suffix + ".gz")
|
206
206
|
|
207
|
-
with open(
|
207
|
+
with archive_path.open("rb") as f_in:
|
208
208
|
with gzip.open(compressed_path, "wb") as f_out:
|
209
209
|
shutil.copyfileobj(f_in, f_out)
|
210
210
|
|
@@ -321,7 +321,7 @@ Generated by Claude MPM Archive Manager
|
|
321
321
|
if archive_file.suffix == ".gz":
|
322
322
|
# Decompress first
|
323
323
|
with gzip.open(archive_file, "rb") as f_in:
|
324
|
-
with open(
|
324
|
+
with target_path.open("wb") as f_out:
|
325
325
|
shutil.copyfileobj(f_in, f_out)
|
326
326
|
else:
|
327
327
|
shutil.copy2(archive_file, target_path)
|
@@ -519,7 +519,7 @@ Generated by Claude MPM Archive Manager
|
|
519
519
|
def review_documentation(self, check_git: bool = True) -> Dict:
|
520
520
|
"""Comprehensive documentation review with outdated detection."""
|
521
521
|
report = {
|
522
|
-
"timestamp": datetime.now().isoformat(),
|
522
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
523
523
|
"files_reviewed": {},
|
524
524
|
"outdated_sections": [],
|
525
525
|
"synchronization_issues": [],
|
@@ -698,7 +698,7 @@ Generated by Claude MPM Archive Manager
|
|
698
698
|
if changelog_path.exists():
|
699
699
|
last_modified = self.get_file_last_modified(changelog_path)
|
700
700
|
if last_modified:
|
701
|
-
days_old = (datetime.now() - last_modified).days
|
701
|
+
days_old = (datetime.now(timezone.utc) - last_modified).days
|
702
702
|
if days_old > 30:
|
703
703
|
issues.append(
|
704
704
|
{
|
@@ -800,7 +800,7 @@ Generated by Claude MPM Archive Manager
|
|
800
800
|
# Check if file hasn't been updated in git for long time
|
801
801
|
if file_report.get("last_git_update"):
|
802
802
|
last_update = datetime.fromisoformat(file_report["last_git_update"])
|
803
|
-
days_old = (datetime.now() - last_update).days
|
803
|
+
days_old = (datetime.now(timezone.utc) - last_update).days
|
804
804
|
if days_old > 90:
|
805
805
|
should_archive = True
|
806
806
|
archive_reason.append(f"No updates for {days_old} days")
|
@@ -913,7 +913,7 @@ Generated by Claude MPM Archive Manager
|
|
913
913
|
changelog_content = changelog_path.read_text()
|
914
914
|
if f"## [{current_version}]" not in changelog_content:
|
915
915
|
# Add new version section
|
916
|
-
today = datetime.now().strftime("%Y-%m-%d")
|
916
|
+
today = datetime.now(timezone.utc).strftime("%Y-%m-%d")
|
917
917
|
new_section = f"\n## [{current_version}] - {today}\n\n### Added\n\n### Changed\n\n### Fixed\n\n"
|
918
918
|
|
919
919
|
# Insert after header
|
@@ -981,7 +981,7 @@ Generated by Claude MPM Archive Manager
|
|
981
981
|
last_updated = "Unknown"
|
982
982
|
if report.get("last_git_update"):
|
983
983
|
last_date = datetime.fromisoformat(report["last_git_update"])
|
984
|
-
days_ago = (datetime.now() - last_date).days
|
984
|
+
days_ago = (datetime.now(timezone.utc) - last_date).days
|
985
985
|
last_updated = f"{days_ago} days ago"
|
986
986
|
|
987
987
|
table.add_row(filename, status, str(issues), last_updated)
|
@@ -279,7 +279,7 @@ class DependencyAnalyzerService:
|
|
279
279
|
package_json_path = self.working_directory / "package.json"
|
280
280
|
if package_json_path.exists():
|
281
281
|
try:
|
282
|
-
with open(
|
282
|
+
with package_json_path.open() as f:
|
283
283
|
package_data = json.load(f)
|
284
284
|
except Exception as e:
|
285
285
|
self.logger.warning(f"Error reading package.json: {e}")
|
@@ -324,7 +324,7 @@ class DependencyAnalyzerService:
|
|
324
324
|
) -> None:
|
325
325
|
"""Parse package.json for dependencies."""
|
326
326
|
try:
|
327
|
-
with open(
|
327
|
+
with path.open() as f:
|
328
328
|
data = json.load(f)
|
329
329
|
|
330
330
|
# Production dependencies
|
@@ -382,7 +382,7 @@ class DependencyAnalyzerService:
|
|
382
382
|
except ImportError:
|
383
383
|
return
|
384
384
|
|
385
|
-
with open(
|
385
|
+
with path.open("rb") as f:
|
386
386
|
data = tomllib.load(f)
|
387
387
|
|
388
388
|
# PEP 621 dependencies
|
@@ -433,7 +433,7 @@ class DependencyAnalyzerService:
|
|
433
433
|
except ImportError:
|
434
434
|
return
|
435
435
|
|
436
|
-
with open(
|
436
|
+
with path.open("rb") as f:
|
437
437
|
data = tomllib.load(f)
|
438
438
|
|
439
439
|
# Production dependencies
|
@@ -19,7 +19,7 @@ Created: 2025-01-26
|
|
19
19
|
import difflib
|
20
20
|
import hashlib
|
21
21
|
import re
|
22
|
-
from datetime import datetime
|
22
|
+
from datetime import datetime, timezone
|
23
23
|
from pathlib import Path
|
24
24
|
from typing import Dict, List, Tuple
|
25
25
|
|
@@ -384,7 +384,7 @@ class DocumentationManager:
|
|
384
384
|
|
385
385
|
def _add_metadata(self, content: str) -> str:
|
386
386
|
"""Add metadata to the document."""
|
387
|
-
timestamp = datetime.now().isoformat()
|
387
|
+
timestamp = datetime.now(timezone.utc).isoformat()
|
388
388
|
|
389
389
|
# Check if meta section exists
|
390
390
|
if "## 📝 Meta:" not in content and "## Meta:" not in content:
|
@@ -417,7 +417,7 @@ class DocumentationManager:
|
|
417
417
|
def generate_update_report(self, old_content: str, new_content: str) -> Dict:
|
418
418
|
"""Generate a report of changes between old and new content."""
|
419
419
|
report = {
|
420
|
-
"timestamp": datetime.now().isoformat(),
|
420
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
421
421
|
"changes": [],
|
422
422
|
"additions": [],
|
423
423
|
"deletions": [],
|
@@ -547,7 +547,7 @@ class DocumentationManager:
|
|
547
547
|
|
548
548
|
## 📝 Meta: Maintaining This Document
|
549
549
|
|
550
|
-
- **Last Updated**: {datetime.now().isoformat()}
|
550
|
+
- **Last Updated**: {datetime.now(timezone.utc).isoformat()}
|
551
551
|
- **Created By**: Claude MPM /mpm-init
|
552
552
|
- **Update Frequency**: As needed when requirements change
|
553
553
|
"""
|
@@ -17,7 +17,7 @@ Created: 2025-01-26
|
|
17
17
|
"""
|
18
18
|
|
19
19
|
import subprocess
|
20
|
-
from datetime import datetime, timedelta
|
20
|
+
from datetime import datetime, timedelta, timezone
|
21
21
|
from pathlib import Path
|
22
22
|
from typing import Dict, List, Optional
|
23
23
|
|
@@ -74,7 +74,7 @@ class EnhancedProjectAnalyzer:
|
|
74
74
|
|
75
75
|
def _get_recent_commits(self, days: int) -> List[Dict]:
|
76
76
|
"""Get recent commits within specified days."""
|
77
|
-
since_date = (datetime.now() - timedelta(days=days)).strftime("%Y-%m-%d")
|
77
|
+
since_date = (datetime.now(timezone.utc) - timedelta(days=days)).strftime("%Y-%m-%d")
|
78
78
|
|
79
79
|
# Get commit log with structured format
|
80
80
|
output = self._run_git_command(
|
@@ -107,7 +107,7 @@ class EnhancedProjectAnalyzer:
|
|
107
107
|
|
108
108
|
def _get_changed_files(self, days: int) -> Dict:
|
109
109
|
"""Get files changed in recent commits."""
|
110
|
-
since_date = (datetime.now() - timedelta(days=days)).strftime("%Y-%m-%d")
|
110
|
+
since_date = (datetime.now(timezone.utc) - timedelta(days=days)).strftime("%Y-%m-%d")
|
111
111
|
|
112
112
|
output = self._run_git_command(
|
113
113
|
[
|
@@ -138,7 +138,7 @@ class EnhancedProjectAnalyzer:
|
|
138
138
|
|
139
139
|
def _get_recently_added_files(self, days: int) -> List[str]:
|
140
140
|
"""Get files added in recent commits."""
|
141
|
-
since_date = (datetime.now() - timedelta(days=days)).strftime("%Y-%m-%d")
|
141
|
+
since_date = (datetime.now(timezone.utc) - timedelta(days=days)).strftime("%Y-%m-%d")
|
142
142
|
|
143
143
|
output = self._run_git_command(
|
144
144
|
[
|
@@ -162,7 +162,7 @@ class EnhancedProjectAnalyzer:
|
|
162
162
|
|
163
163
|
def _get_author_stats(self, days: int) -> Dict:
|
164
164
|
"""Get author contribution statistics."""
|
165
|
-
since_date = (datetime.now() - timedelta(days=days)).strftime("%Y-%m-%d")
|
165
|
+
since_date = (datetime.now(timezone.utc) - timedelta(days=days)).strftime("%Y-%m-%d")
|
166
166
|
|
167
167
|
output = self._run_git_command(
|
168
168
|
[
|
@@ -228,7 +228,7 @@ class EnhancedProjectAnalyzer:
|
|
228
228
|
|
229
229
|
def _get_documentation_changes(self, days: int) -> Dict:
|
230
230
|
"""Track changes to documentation files."""
|
231
|
-
since_date = (datetime.now() - timedelta(days=days)).strftime("%Y-%m-%d")
|
231
|
+
since_date = (datetime.now(timezone.utc) - timedelta(days=days)).strftime("%Y-%m-%d")
|
232
232
|
|
233
233
|
# Get changes to documentation files
|
234
234
|
doc_patterns = ["*.md", "*.rst", "*.txt", "docs/*", "README*", "CLAUDE*"]
|
@@ -448,7 +448,7 @@ class EnhancedProjectAnalyzer:
|
|
448
448
|
)
|
449
449
|
if first_commit:
|
450
450
|
age_days = (
|
451
|
-
datetime.now() - datetime.fromtimestamp(int(first_commit))
|
451
|
+
datetime.now(timezone.utc) - datetime.fromtimestamp(int(first_commit))
|
452
452
|
).days
|
453
453
|
indicators.append(f"{age_days} days old")
|
454
454
|
|
@@ -470,7 +470,7 @@ class EnhancedProjectAnalyzer:
|
|
470
470
|
"""Generate comprehensive project analysis report."""
|
471
471
|
report = {
|
472
472
|
"project_path": str(self.project_path),
|
473
|
-
"timestamp": datetime.now().isoformat(),
|
473
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
474
474
|
}
|
475
475
|
|
476
476
|
# Basic project info
|
@@ -69,7 +69,7 @@ class ProjectRegistry:
|
|
69
69
|
self.registry_dir.mkdir(parents=True, exist_ok=True)
|
70
70
|
except Exception as e:
|
71
71
|
self.logger.error(f"Failed to create registry directory: {e}")
|
72
|
-
raise ProjectRegistryError(f"Cannot create registry directory: {e}")
|
72
|
+
raise ProjectRegistryError(f"Cannot create registry directory: {e}") from e
|
73
73
|
|
74
74
|
def get_or_create_project_entry(self) -> Dict[str, Any]:
|
75
75
|
"""
|
@@ -104,7 +104,7 @@ class ProjectRegistry:
|
|
104
104
|
|
105
105
|
except Exception as e:
|
106
106
|
self.logger.error(f"Failed to get or create project entry: {e}")
|
107
|
-
raise ProjectRegistryError(f"Registry operation failed: {e}")
|
107
|
+
raise ProjectRegistryError(f"Registry operation failed: {e}") from e
|
108
108
|
|
109
109
|
def _find_existing_entry(self) -> Optional[Dict[str, Any]]:
|
110
110
|
"""
|
@@ -491,7 +491,7 @@ class ProjectRegistry:
|
|
491
491
|
# Remove internal fields before saving
|
492
492
|
save_data = {k: v for k, v in data.items() if not k.startswith("_")}
|
493
493
|
|
494
|
-
with open(
|
494
|
+
with registry_file.open("w", encoding="utf-8") as f:
|
495
495
|
yaml.dump(
|
496
496
|
save_data, f, default_flow_style=False, sort_keys=False, indent=2
|
497
497
|
)
|
@@ -500,7 +500,7 @@ class ProjectRegistry:
|
|
500
500
|
|
501
501
|
except Exception as e:
|
502
502
|
self.logger.error(f"Failed to save registry data: {e}")
|
503
|
-
raise ProjectRegistryError(f"Failed to save registry: {e}")
|
503
|
+
raise ProjectRegistryError(f"Failed to save registry: {e}") from e
|
504
504
|
|
505
505
|
def list_projects(self) -> List[Dict[str, Any]]:
|
506
506
|
"""
|