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.

Files changed (183) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/frontmatter_validator.py +4 -4
  3. claude_mpm/cli/commands/agent_manager.py +3 -3
  4. claude_mpm/cli/commands/agents.py +6 -6
  5. claude_mpm/cli/commands/aggregate.py +4 -4
  6. claude_mpm/cli/commands/analyze.py +2 -2
  7. claude_mpm/cli/commands/analyze_code.py +1 -1
  8. claude_mpm/cli/commands/cleanup.py +3 -3
  9. claude_mpm/cli/commands/config.py +2 -2
  10. claude_mpm/cli/commands/configure.py +14 -14
  11. claude_mpm/cli/commands/dashboard.py +1 -1
  12. claude_mpm/cli/commands/debug.py +3 -3
  13. claude_mpm/cli/commands/doctor.py +1 -1
  14. claude_mpm/cli/commands/mcp.py +7 -7
  15. claude_mpm/cli/commands/mcp_command_router.py +1 -1
  16. claude_mpm/cli/commands/mcp_config.py +2 -2
  17. claude_mpm/cli/commands/mcp_external_commands.py +2 -2
  18. claude_mpm/cli/commands/mcp_install_commands.py +3 -3
  19. claude_mpm/cli/commands/mcp_pipx_config.py +2 -2
  20. claude_mpm/cli/commands/mcp_setup_external.py +3 -3
  21. claude_mpm/cli/commands/monitor.py +1 -1
  22. claude_mpm/cli/commands/mpm_init_handler.py +1 -1
  23. claude_mpm/cli/interactive/agent_wizard.py +1 -1
  24. claude_mpm/cli/parsers/search_parser.py +1 -1
  25. claude_mpm/cli/shared/argument_patterns.py +2 -2
  26. claude_mpm/cli/shared/base_command.py +1 -1
  27. claude_mpm/cli/startup_logging.py +4 -4
  28. claude_mpm/config/experimental_features.py +4 -4
  29. claude_mpm/config/socketio_config.py +2 -2
  30. claude_mpm/core/agent_session_manager.py +2 -2
  31. claude_mpm/core/api_validator.py +3 -3
  32. claude_mpm/core/base_service.py +10 -1
  33. claude_mpm/core/cache.py +2 -2
  34. claude_mpm/core/config.py +4 -4
  35. claude_mpm/core/config_aliases.py +4 -4
  36. claude_mpm/core/config_constants.py +1 -1
  37. claude_mpm/core/error_handler.py +1 -1
  38. claude_mpm/core/file_utils.py +5 -5
  39. claude_mpm/core/framework/formatters/capability_generator.py +5 -5
  40. claude_mpm/core/framework/loaders/agent_loader.py +1 -1
  41. claude_mpm/core/framework/processors/metadata_processor.py +1 -1
  42. claude_mpm/core/framework/processors/template_processor.py +3 -3
  43. claude_mpm/core/framework_loader.py +2 -2
  44. claude_mpm/core/log_manager.py +4 -4
  45. claude_mpm/core/logger.py +2 -2
  46. claude_mpm/core/optimized_startup.py +1 -1
  47. claude_mpm/core/output_style_manager.py +1 -1
  48. claude_mpm/core/service_registry.py +2 -2
  49. claude_mpm/core/session_manager.py +3 -3
  50. claude_mpm/core/shared/config_loader.py +1 -1
  51. claude_mpm/core/socketio_pool.py +2 -2
  52. claude_mpm/core/unified_agent_registry.py +2 -2
  53. claude_mpm/core/unified_config.py +6 -6
  54. claude_mpm/core/unified_paths.py +2 -2
  55. claude_mpm/dashboard/api/simple_directory.py +1 -1
  56. claude_mpm/generators/agent_profile_generator.py +1 -1
  57. claude_mpm/hooks/claude_hooks/event_handlers.py +2 -2
  58. claude_mpm/hooks/claude_hooks/installer.py +9 -9
  59. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +7 -2
  60. claude_mpm/hooks/claude_hooks/tool_analysis.py +2 -2
  61. claude_mpm/hooks/memory_integration_hook.py +1 -1
  62. claude_mpm/hooks/validation_hooks.py +1 -1
  63. claude_mpm/init.py +4 -4
  64. claude_mpm/models/agent_session.py +1 -1
  65. claude_mpm/scripts/socketio_daemon.py +5 -5
  66. claude_mpm/services/__init__.py +2 -2
  67. claude_mpm/services/agent_capabilities_service.py +1 -1
  68. claude_mpm/services/agents/agent_builder.py +4 -4
  69. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -1
  70. claude_mpm/services/agents/deployment/agent_metrics_collector.py +1 -1
  71. claude_mpm/services/agents/deployment/agent_record_service.py +3 -3
  72. claude_mpm/services/agents/deployment/deployment_wrapper.py +1 -1
  73. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +2 -2
  74. claude_mpm/services/agents/loading/agent_profile_loader.py +2 -2
  75. claude_mpm/services/agents/local_template_manager.py +5 -5
  76. claude_mpm/services/agents/registry/deployed_agent_discovery.py +1 -1
  77. claude_mpm/services/agents/registry/modification_tracker.py +19 -11
  78. claude_mpm/services/async_session_logger.py +1 -1
  79. claude_mpm/services/claude_session_logger.py +1 -1
  80. claude_mpm/services/cli/agent_listing_service.py +3 -3
  81. claude_mpm/services/cli/agent_validation_service.py +1 -1
  82. claude_mpm/services/cli/session_manager.py +2 -2
  83. claude_mpm/services/core/path_resolver.py +1 -1
  84. claude_mpm/services/diagnostics/checks/agent_check.py +1 -1
  85. claude_mpm/services/diagnostics/checks/claude_code_check.py +2 -2
  86. claude_mpm/services/diagnostics/checks/common_issues_check.py +3 -3
  87. claude_mpm/services/diagnostics/checks/configuration_check.py +2 -2
  88. claude_mpm/services/diagnostics/checks/installation_check.py +1 -1
  89. claude_mpm/services/diagnostics/checks/mcp_check.py +1 -1
  90. claude_mpm/services/diagnostics/checks/mcp_services_check.py +9 -9
  91. claude_mpm/services/diagnostics/checks/monitor_check.py +1 -1
  92. claude_mpm/services/diagnostics/doctor_reporter.py +1 -1
  93. claude_mpm/services/event_aggregator.py +1 -1
  94. claude_mpm/services/event_bus/event_bus.py +7 -2
  95. claude_mpm/services/events/consumers/dead_letter.py +2 -2
  96. claude_mpm/services/framework_claude_md_generator/__init__.py +1 -1
  97. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +3 -3
  98. claude_mpm/services/framework_claude_md_generator/version_manager.py +1 -1
  99. claude_mpm/services/hook_installer_service.py +7 -7
  100. claude_mpm/services/infrastructure/context_preservation.py +7 -7
  101. claude_mpm/services/infrastructure/daemon_manager.py +5 -5
  102. claude_mpm/services/mcp_config_manager.py +10 -10
  103. claude_mpm/services/mcp_gateway/auto_configure.py +5 -5
  104. claude_mpm/services/mcp_gateway/config/config_loader.py +2 -2
  105. claude_mpm/services/mcp_gateway/config/configuration.py +3 -3
  106. claude_mpm/services/mcp_gateway/core/process_pool.py +3 -3
  107. claude_mpm/services/mcp_gateway/core/singleton_manager.py +2 -2
  108. claude_mpm/services/mcp_gateway/core/startup_verification.py +1 -1
  109. claude_mpm/services/mcp_gateway/main.py +1 -1
  110. claude_mpm/services/mcp_gateway/registry/service_registry.py +4 -2
  111. claude_mpm/services/mcp_gateway/registry/tool_registry.py +2 -1
  112. claude_mpm/services/mcp_gateway/server/stdio_handler.py +1 -1
  113. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
  114. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +1 -1
  115. claude_mpm/services/mcp_gateway/tools/hello_world.py +1 -1
  116. claude_mpm/services/mcp_gateway/utils/package_version_checker.py +5 -5
  117. claude_mpm/services/mcp_gateway/utils/update_preferences.py +2 -2
  118. claude_mpm/services/mcp_service_verifier.py +1 -1
  119. claude_mpm/services/memory/builder.py +1 -1
  120. claude_mpm/services/memory/cache/shared_prompt_cache.py +2 -1
  121. claude_mpm/services/memory/indexed_memory.py +3 -3
  122. claude_mpm/services/monitor/daemon.py +1 -1
  123. claude_mpm/services/monitor/daemon_manager.py +9 -9
  124. claude_mpm/services/monitor/handlers/file.py +1 -1
  125. claude_mpm/services/monitor/handlers/hooks.py +3 -3
  126. claude_mpm/services/monitor/management/lifecycle.py +7 -7
  127. claude_mpm/services/monitor/server.py +2 -2
  128. claude_mpm/services/orphan_detection.py +13 -16
  129. claude_mpm/services/port_manager.py +2 -2
  130. claude_mpm/services/project/analyzer.py +3 -3
  131. claude_mpm/services/project/archive_manager.py +13 -13
  132. claude_mpm/services/project/dependency_analyzer.py +4 -4
  133. claude_mpm/services/project/documentation_manager.py +4 -4
  134. claude_mpm/services/project/enhanced_analyzer.py +8 -8
  135. claude_mpm/services/project/registry.py +4 -4
  136. claude_mpm/services/project_port_allocator.py +7 -11
  137. claude_mpm/services/session_management_service.py +1 -1
  138. claude_mpm/services/socketio/event_normalizer.py +1 -1
  139. claude_mpm/services/socketio/handlers/code_analysis.py +14 -12
  140. claude_mpm/services/socketio/handlers/file.py +1 -1
  141. claude_mpm/services/socketio/migration_utils.py +1 -1
  142. claude_mpm/services/socketio/server/core.py +1 -1
  143. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +1 -1
  144. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +4 -4
  145. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +1 -1
  146. claude_mpm/services/unified/config_strategies/config_schema.py +4 -4
  147. claude_mpm/services/unified/config_strategies/context_strategy.py +6 -6
  148. claude_mpm/services/unified/config_strategies/error_handling_strategy.py +10 -10
  149. claude_mpm/services/unified/config_strategies/file_loader_strategy.py +5 -5
  150. claude_mpm/services/unified/config_strategies/unified_config_service.py +8 -8
  151. claude_mpm/services/unified/config_strategies/validation_strategy.py +15 -15
  152. claude_mpm/services/unified/deployment_strategies/base.py +4 -4
  153. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +15 -15
  154. claude_mpm/services/unified/deployment_strategies/local.py +9 -9
  155. claude_mpm/services/unified/deployment_strategies/utils.py +9 -9
  156. claude_mpm/services/unified/deployment_strategies/vercel.py +7 -7
  157. claude_mpm/services/unified/unified_config.py +5 -5
  158. claude_mpm/services/unified/unified_deployment.py +2 -2
  159. claude_mpm/services/utility_service.py +1 -1
  160. claude_mpm/services/version_control/conflict_resolution.py +2 -2
  161. claude_mpm/services/version_control/git_operations.py +3 -3
  162. claude_mpm/services/version_control/semantic_versioning.py +13 -13
  163. claude_mpm/services/version_control/version_parser.py +1 -1
  164. claude_mpm/storage/state_storage.py +12 -13
  165. claude_mpm/tools/code_tree_analyzer.py +5 -5
  166. claude_mpm/tools/code_tree_builder.py +4 -4
  167. claude_mpm/tools/socketio_debug.py +1 -1
  168. claude_mpm/utils/agent_dependency_loader.py +4 -4
  169. claude_mpm/utils/common.py +2 -2
  170. claude_mpm/utils/config_manager.py +3 -3
  171. claude_mpm/utils/dependency_cache.py +2 -2
  172. claude_mpm/utils/dependency_strategies.py +6 -6
  173. claude_mpm/utils/file_utils.py +11 -11
  174. claude_mpm/utils/log_cleanup.py +1 -1
  175. claude_mpm/utils/path_operations.py +1 -1
  176. claude_mpm/validation/agent_validator.py +2 -2
  177. claude_mpm/validation/frontmatter_validator.py +1 -1
  178. {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.12.dist-info}/METADATA +1 -1
  179. {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.12.dist-info}/RECORD +183 -183
  180. {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.12.dist-info}/WHEEL +0 -0
  181. {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.12.dist-info}/entry_points.txt +0 -0
  182. {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.12.dist-info}/licenses/LICENSE +0 -0
  183. {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.12.dist-info}/top_level.txt +0 -0
@@ -12,7 +12,7 @@ import threading
12
12
  from abc import ABC, abstractmethod
13
13
  from collections import defaultdict
14
14
  from dataclasses import dataclass, field
15
- from datetime import datetime, timedelta
15
+ from datetime import datetime, timedelta, timezone
16
16
  from enum import Enum
17
17
  from pathlib import Path
18
18
  from typing import Any, Callable, Dict, List, Optional, TypeVar, Union
@@ -216,7 +216,7 @@ class UnifiedConfigService:
216
216
  source=str(source),
217
217
  format=format,
218
218
  context=context,
219
- loaded_at=datetime.now(),
219
+ loaded_at=datetime.now(timezone.utc),
220
220
  checksum=self._calculate_checksum(config),
221
221
  hot_reload=hot_reload,
222
222
  ttl=ttl,
@@ -439,7 +439,7 @@ class UnifiedConfigService:
439
439
 
440
440
  path = Path(source)
441
441
  if path.exists():
442
- with open(path) as f:
442
+ with path.open() as f:
443
443
  return json.load(f)
444
444
 
445
445
  # Try to parse as JSON string
@@ -452,7 +452,7 @@ class UnifiedConfigService:
452
452
 
453
453
  path = Path(source)
454
454
  if path.exists():
455
- with open(path) as f:
455
+ with path.open() as f:
456
456
  return yaml.safe_load(f)
457
457
 
458
458
  # Try to parse as YAML string
@@ -476,7 +476,7 @@ class UnifiedConfigService:
476
476
  # Try to parse value
477
477
  try:
478
478
  config[clean_key] = json.loads(value)
479
- except:
479
+ except (json.JSONDecodeError, ValueError):
480
480
  config[clean_key] = value
481
481
 
482
482
  return config
@@ -508,7 +508,7 @@ class UnifiedConfigService:
508
508
 
509
509
  path = Path(source)
510
510
  if path.exists():
511
- with open(path) as f:
511
+ with path.open() as f:
512
512
  return toml.load(f)
513
513
 
514
514
  return toml.loads(str(source))
@@ -706,7 +706,7 @@ class UnifiedConfigService:
706
706
  """Check if cached configuration is still valid"""
707
707
  if metadata.ttl:
708
708
  expiry = metadata.loaded_at + metadata.ttl
709
- if datetime.now() > expiry:
709
+ if datetime.now(timezone.utc) > expiry:
710
710
  return False
711
711
  return True
712
712
 
@@ -742,7 +742,7 @@ class UnifiedConfigService:
742
742
  result = handler(error, source, context)
743
743
  if result is not None:
744
744
  return result
745
- except:
745
+ except Exception:
746
746
  continue
747
747
 
748
748
  self.logger.error(f"Failed to load config from {source}: {error}")
@@ -402,7 +402,7 @@ class FormatValidator(BaseValidator):
402
402
  try:
403
403
  result = urllib.parse.urlparse(value)
404
404
  return all([result.scheme, result.netloc])
405
- except:
405
+ except (ValueError, AttributeError, TypeError):
406
406
  return False
407
407
 
408
408
  @staticmethod
@@ -410,7 +410,7 @@ class FormatValidator(BaseValidator):
410
410
  try:
411
411
  result = urllib.parse.urlparse(value)
412
412
  return bool(result.scheme)
413
- except:
413
+ except (ValueError, AttributeError, TypeError):
414
414
  return False
415
415
 
416
416
  @staticmethod
@@ -420,7 +420,7 @@ class FormatValidator(BaseValidator):
420
420
  try:
421
421
  uuid.UUID(value)
422
422
  return True
423
- except:
423
+ except (ValueError, AttributeError, TypeError):
424
424
  return False
425
425
 
426
426
  @staticmethod
@@ -428,7 +428,7 @@ class FormatValidator(BaseValidator):
428
428
  try:
429
429
  ipaddress.IPv4Address(value)
430
430
  return True
431
- except:
431
+ except (ValueError, ipaddress.AddressValueError):
432
432
  return False
433
433
 
434
434
  @staticmethod
@@ -436,7 +436,7 @@ class FormatValidator(BaseValidator):
436
436
  try:
437
437
  ipaddress.IPv6Address(value)
438
438
  return True
439
- except:
439
+ except (ValueError, ipaddress.AddressValueError):
440
440
  return False
441
441
 
442
442
  @staticmethod
@@ -444,7 +444,7 @@ class FormatValidator(BaseValidator):
444
444
  try:
445
445
  ipaddress.ip_address(value)
446
446
  return True
447
- except:
447
+ except (ValueError, ipaddress.AddressValueError):
448
448
  return False
449
449
 
450
450
  @staticmethod
@@ -461,7 +461,7 @@ class FormatValidator(BaseValidator):
461
461
  try:
462
462
  datetime.strptime(value, "%Y-%m-%d")
463
463
  return True
464
- except:
464
+ except (ValueError, TypeError):
465
465
  return False
466
466
 
467
467
  @staticmethod
@@ -469,11 +469,11 @@ class FormatValidator(BaseValidator):
469
469
  try:
470
470
  datetime.strptime(value, "%H:%M:%S")
471
471
  return True
472
- except:
472
+ except (ValueError, TypeError):
473
473
  try:
474
474
  datetime.strptime(value, "%H:%M")
475
475
  return True
476
- except:
476
+ except (ValueError, TypeError):
477
477
  return False
478
478
 
479
479
  @staticmethod
@@ -488,7 +488,7 @@ class FormatValidator(BaseValidator):
488
488
  try:
489
489
  datetime.strptime(value, fmt)
490
490
  return True
491
- except:
491
+ except (ValueError, TypeError):
492
492
  continue
493
493
  return False
494
494
 
@@ -499,7 +499,7 @@ class FormatValidator(BaseValidator):
499
499
  try:
500
500
  json.loads(value)
501
501
  return True
502
- except:
502
+ except (json.JSONDecodeError, ValueError, TypeError):
503
503
  return False
504
504
 
505
505
  @staticmethod
@@ -509,7 +509,7 @@ class FormatValidator(BaseValidator):
509
509
  try:
510
510
  base64.b64decode(value, validate=True)
511
511
  return True
512
- except:
512
+ except (ValueError, base64.binascii.Error):
513
513
  return False
514
514
 
515
515
  @staticmethod
@@ -517,7 +517,7 @@ class FormatValidator(BaseValidator):
517
517
  try:
518
518
  Path(value)
519
519
  return True
520
- except:
520
+ except (ValueError, TypeError, OSError):
521
521
  return False
522
522
 
523
523
  @staticmethod
@@ -709,7 +709,7 @@ class ConditionalValidator(BaseValidator):
709
709
 
710
710
  try:
711
711
  return comparator(actual, expected)
712
- except:
712
+ except (TypeError, ValueError, AttributeError, KeyError):
713
713
  return False
714
714
 
715
715
  def _apply_rule(
@@ -910,7 +910,7 @@ class CrossFieldValidator(BaseValidator):
910
910
  if comparator:
911
911
  try:
912
912
  return comparator(val1, val2)
913
- except:
913
+ except (TypeError, ValueError, AttributeError, KeyError):
914
914
  return False
915
915
 
916
916
  return False
@@ -15,7 +15,7 @@ This module provides:
15
15
 
16
16
  from abc import abstractmethod
17
17
  from dataclasses import dataclass, field
18
- from datetime import datetime
18
+ from datetime import datetime, timezone
19
19
  from enum import Enum
20
20
  from pathlib import Path
21
21
  from typing import Any, Dict, List, Optional, Union
@@ -255,7 +255,7 @@ class DeploymentStrategy(BaseDeploymentStrategy):
255
255
  result = DeploymentResult(
256
256
  success=False,
257
257
  status=DeploymentStatus.PENDING,
258
- started_at=datetime.now(),
258
+ started_at=datetime.now(timezone.utc),
259
259
  )
260
260
 
261
261
  try:
@@ -334,7 +334,7 @@ class DeploymentStrategy(BaseDeploymentStrategy):
334
334
  result.errors.append(f"Rollback failed: {rollback_error!s}")
335
335
 
336
336
  finally:
337
- result.completed_at = datetime.now()
337
+ result.completed_at = datetime.now(timezone.utc)
338
338
  if result.started_at:
339
339
  result.duration_seconds = (
340
340
  result.completed_at - result.started_at
@@ -532,7 +532,7 @@ class DeploymentStrategy(BaseDeploymentStrategy):
532
532
  return {
533
533
  "deployment_id": deployment_info.get("deployment_id"),
534
534
  "deployed_path": str(deployment_info.get("deployed_path")),
535
- "timestamp": datetime.now().isoformat(),
535
+ "timestamp": datetime.now(timezone.utc).isoformat(),
536
536
  "artifacts": deployment_info.get("artifacts", []),
537
537
  }
538
538
 
@@ -8,7 +8,7 @@ Reduces duplication by sharing common cloud deployment patterns.
8
8
 
9
9
  import json
10
10
  import subprocess
11
- from datetime import datetime
11
+ from datetime import datetime, timezone
12
12
  from pathlib import Path
13
13
  from typing import Any, Dict, List
14
14
 
@@ -48,7 +48,7 @@ class RailwayDeploymentStrategy(DeploymentStrategy):
48
48
  # Check Railway CLI
49
49
  try:
50
50
  subprocess.run(["railway", "--version"], capture_output=True, check=True)
51
- except:
51
+ except (subprocess.CalledProcessError, FileNotFoundError, OSError):
52
52
  errors.append(
53
53
  "Railway CLI not installed. Install with: npm i -g @railway/cli"
54
54
  )
@@ -56,7 +56,7 @@ class RailwayDeploymentStrategy(DeploymentStrategy):
56
56
  # Check authentication
57
57
  try:
58
58
  subprocess.run(["railway", "whoami"], capture_output=True, check=True)
59
- except:
59
+ except (subprocess.CalledProcessError, FileNotFoundError, OSError):
60
60
  errors.append("Not authenticated with Railway. Run: railway login")
61
61
 
62
62
  return errors
@@ -97,13 +97,13 @@ class RailwayDeploymentStrategy(DeploymentStrategy):
97
97
  break
98
98
 
99
99
  return {
100
- "deployment_id": f"railway_{datetime.now().timestamp()}",
100
+ "deployment_id": f"railway_{datetime.now(timezone.utc).timestamp()}",
101
101
  "deployment_url": deployment_url,
102
102
  "deployed_path": deploy_dir,
103
103
  "stdout": result.stdout,
104
104
  }
105
105
  except subprocess.CalledProcessError as e:
106
- raise Exception(f"Railway deployment failed: {e.stderr}")
106
+ raise Exception(f"Railway deployment failed: {e.stderr}") from e
107
107
 
108
108
  def verify(
109
109
  self, context: DeploymentContext, deployment_info: Dict[str, Any]
@@ -150,7 +150,7 @@ class AWSDeploymentStrategy(DeploymentStrategy):
150
150
  # Check AWS CLI
151
151
  try:
152
152
  subprocess.run(["aws", "--version"], capture_output=True, check=True)
153
- except:
153
+ except (subprocess.CalledProcessError, FileNotFoundError, OSError):
154
154
  errors.append("AWS CLI not installed")
155
155
 
156
156
  # Check credentials
@@ -158,7 +158,7 @@ class AWSDeploymentStrategy(DeploymentStrategy):
158
158
  subprocess.run(
159
159
  ["aws", "sts", "get-caller-identity"], capture_output=True, check=True
160
160
  )
161
- except:
161
+ except (subprocess.CalledProcessError, FileNotFoundError, OSError):
162
162
  errors.append("AWS credentials not configured")
163
163
 
164
164
  # Validate service type
@@ -218,7 +218,7 @@ class AWSDeploymentStrategy(DeploymentStrategy):
218
218
  "--zip-file",
219
219
  f"fileb://{artifact}",
220
220
  ]
221
- except:
221
+ except (subprocess.CalledProcessError, FileNotFoundError, OSError):
222
222
  # Create new function
223
223
  cmd = [
224
224
  "aws",
@@ -277,7 +277,7 @@ class AWSDeploymentStrategy(DeploymentStrategy):
277
277
  ]
278
278
  subprocess.run(cmd, capture_output=True, check=True)
279
279
  return True
280
- except:
280
+ except (subprocess.CalledProcessError, FileNotFoundError, OSError):
281
281
  return False
282
282
 
283
283
  return True
@@ -301,7 +301,7 @@ class AWSDeploymentStrategy(DeploymentStrategy):
301
301
  try:
302
302
  subprocess.run(cmd, check=True)
303
303
  return True
304
- except:
304
+ except (subprocess.CalledProcessError, FileNotFoundError, OSError):
305
305
  pass
306
306
  return False
307
307
 
@@ -334,7 +334,7 @@ class DockerDeploymentStrategy(DeploymentStrategy):
334
334
  # Check Docker
335
335
  try:
336
336
  subprocess.run(["docker", "--version"], capture_output=True, check=True)
337
- except:
337
+ except (subprocess.CalledProcessError, FileNotFoundError, OSError):
338
338
  errors.append("Docker not installed or not running")
339
339
 
340
340
  # Check Dockerfile exists
@@ -356,7 +356,7 @@ class DockerDeploymentStrategy(DeploymentStrategy):
356
356
  """Execute Docker deployment."""
357
357
  source_dir = artifacts[0] if artifacts[0].is_dir() else artifacts[0].parent
358
358
  image_name = context.config.get(
359
- "image_name", f"app_{datetime.now().timestamp()}"
359
+ "image_name", f"app_{datetime.now(timezone.utc).timestamp()}"
360
360
  )
361
361
  container_name = context.config.get("container_name", image_name)
362
362
 
@@ -444,7 +444,7 @@ class GitDeploymentStrategy(DeploymentStrategy):
444
444
  # Check Git
445
445
  try:
446
446
  subprocess.run(["git", "--version"], capture_output=True, check=True)
447
- except:
447
+ except (subprocess.CalledProcessError, FileNotFoundError, OSError):
448
448
  errors.append("Git not installed")
449
449
 
450
450
  # Check remote URL
@@ -529,7 +529,7 @@ class GitDeploymentStrategy(DeploymentStrategy):
529
529
  check=True,
530
530
  )
531
531
  return True
532
- except:
532
+ except (subprocess.CalledProcessError, FileNotFoundError, OSError):
533
533
  return False
534
534
 
535
535
  def rollback(self, context: DeploymentContext, result: DeploymentResult) -> bool:
@@ -553,7 +553,7 @@ class GitDeploymentStrategy(DeploymentStrategy):
553
553
  check=True,
554
554
  )
555
555
  return True
556
- except:
556
+ except (subprocess.CalledProcessError, FileNotFoundError, OSError):
557
557
  pass
558
558
  return False
559
559
 
@@ -13,7 +13,7 @@ Consolidates functionality from:
13
13
  import json
14
14
  import shutil
15
15
  import tempfile
16
- from datetime import datetime
16
+ from datetime import datetime, timezone
17
17
  from pathlib import Path
18
18
  from typing import Any, Dict, List, Optional
19
19
 
@@ -183,7 +183,7 @@ class LocalDeploymentStrategy(DeploymentStrategy):
183
183
  "deployed_path": target_path,
184
184
  "deployed_files": deployed_files,
185
185
  "artifacts": [str(a) for a in artifacts],
186
- "timestamp": datetime.now().isoformat(),
186
+ "timestamp": datetime.now(timezone.utc).isoformat(),
187
187
  }
188
188
 
189
189
  def verify(
@@ -300,7 +300,7 @@ class LocalDeploymentStrategy(DeploymentStrategy):
300
300
  def _check_write_permission(self, path: Path) -> bool:
301
301
  """Check if we have write permission to path."""
302
302
  try:
303
- test_file = path / f".write_test_{datetime.now().timestamp()}"
303
+ test_file = path / f".write_test_{datetime.now(timezone.utc).timestamp()}"
304
304
  test_file.touch()
305
305
  test_file.unlink()
306
306
  return True
@@ -310,7 +310,7 @@ class LocalDeploymentStrategy(DeploymentStrategy):
310
310
  def _generate_deployment_id(self) -> str:
311
311
  """Generate unique deployment ID."""
312
312
  return (
313
- f"local_{datetime.now().strftime('%Y%m%d_%H%M%S')}_{id(self) % 10000:04d}"
313
+ f"local_{datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S')}_{id(self) % 10000:04d}"
314
314
  )
315
315
 
316
316
  def _create_backup(self, context: DeploymentContext) -> Optional[Path]:
@@ -324,7 +324,7 @@ class LocalDeploymentStrategy(DeploymentStrategy):
324
324
  backup_dir = Path(tempfile.gettempdir()) / "claude_mpm_backups"
325
325
  backup_dir.mkdir(parents=True, exist_ok=True)
326
326
 
327
- timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
327
+ timestamp = datetime.now(timezone.utc).strftime("%Y%m%d_%H%M%S")
328
328
  backup_name = f"{target_path.name}.backup_{timestamp}"
329
329
  backup_path = backup_dir / backup_name
330
330
 
@@ -343,7 +343,7 @@ class LocalDeploymentStrategy(DeploymentStrategy):
343
343
  def _write_version_file(self, target_path: Path, version: str) -> None:
344
344
  """Write version file to deployment."""
345
345
  version_file = target_path / ".version"
346
- version_file.write_text(f"{version}\n{datetime.now().isoformat()}\n")
346
+ version_file.write_text(f"{version}\n{datetime.now(timezone.utc).isoformat()}\n")
347
347
 
348
348
  # Agent deployment methods (consolidating agent_deployment.py patterns)
349
349
 
@@ -409,7 +409,7 @@ class LocalDeploymentStrategy(DeploymentStrategy):
409
409
 
410
410
  for yaml_file in yaml_files:
411
411
  try:
412
- with open(yaml_file) as f:
412
+ with yaml_file.open() as f:
413
413
  data = yaml.safe_load(f)
414
414
  # Basic agent structure validation
415
415
  if not isinstance(data, dict):
@@ -425,11 +425,11 @@ class LocalDeploymentStrategy(DeploymentStrategy):
425
425
 
426
426
  def _convert_json_to_yaml(self, json_path: Path) -> Path:
427
427
  """Convert JSON agent to YAML format."""
428
- with open(json_path) as f:
428
+ with json_path.open() as f:
429
429
  data = json.load(f)
430
430
 
431
431
  yaml_path = Path(tempfile.gettempdir()) / f"{json_path.stem}.yaml"
432
- with open(yaml_path, "w") as f:
432
+ with yaml_path.open("w") as f:
433
433
  yaml.dump(data, f, default_flow_style=False, sort_keys=False)
434
434
 
435
435
  return yaml_path
@@ -19,7 +19,7 @@ import json
19
19
  import shutil
20
20
  import subprocess
21
21
  import tempfile
22
- from datetime import datetime
22
+ from datetime import datetime, timezone
23
23
  from pathlib import Path
24
24
  from typing import Any, Dict, List, Optional, Tuple, Union
25
25
 
@@ -162,7 +162,7 @@ def prepare_deployment_artifact(
162
162
  metadata = {
163
163
  "source": str(source_path),
164
164
  "type": artifact_type,
165
- "created_at": datetime.now().isoformat(),
165
+ "created_at": datetime.now(timezone.utc).isoformat(),
166
166
  }
167
167
 
168
168
  # Auto-detect type
@@ -257,7 +257,7 @@ def verify_deployment_health(
257
257
  """
258
258
  health = {
259
259
  "status": "unknown",
260
- "timestamp": datetime.now().isoformat(),
260
+ "timestamp": datetime.now(timezone.utc).isoformat(),
261
261
  "checks": {},
262
262
  "errors": [],
263
263
  }
@@ -464,7 +464,7 @@ def get_version_info(path: Union[str, Path]) -> Dict[str, Any]:
464
464
 
465
465
  if file_path.exists():
466
466
  if version_file == "package.json":
467
- with open(file_path) as f:
467
+ with file_path.open() as f:
468
468
  data = json.load(f)
469
469
  version_info["version"] = data.get("version")
470
470
  version_info["source"] = "package.json"
@@ -512,7 +512,7 @@ def update_version(
512
512
  shutil.copy2(version_file, backup_file)
513
513
 
514
514
  # Write new version
515
- version_file.write_text(f"{new_version}\n{datetime.now().isoformat()}\n")
515
+ version_file.write_text(f"{new_version}\n{datetime.now(timezone.utc).isoformat()}\n")
516
516
  return True
517
517
 
518
518
  except Exception as e:
@@ -539,7 +539,7 @@ def calculate_checksum(path: Union[str, Path], algorithm: str = "sha256") -> str
539
539
  hasher = hashlib.new(algorithm)
540
540
 
541
541
  if path.is_file():
542
- with open(path, "rb") as f:
542
+ with path.open("rb") as f:
543
543
  for chunk in iter(lambda: f.read(4096), b""):
544
544
  hasher.update(chunk)
545
545
  elif path.is_dir():
@@ -547,7 +547,7 @@ def calculate_checksum(path: Union[str, Path], algorithm: str = "sha256") -> str
547
547
  for file_path in sorted(path.rglob("*")):
548
548
  if file_path.is_file():
549
549
  hasher.update(str(file_path.relative_to(path)).encode())
550
- with open(file_path, "rb") as f:
550
+ with file_path.open("rb") as f:
551
551
  for chunk in iter(lambda: f.read(4096), b""):
552
552
  hasher.update(chunk)
553
553
 
@@ -616,7 +616,7 @@ def load_env_file(env_file: Union[str, Path]) -> Dict[str, str]:
616
616
  env_path = Path(env_file)
617
617
 
618
618
  if env_path.exists():
619
- with open(env_path) as f:
619
+ with env_path.open() as f:
620
620
  for line in f:
621
621
  line = line.strip()
622
622
  if line and not line.startswith("#") and "=" in line:
@@ -656,7 +656,7 @@ def export_env_to_file(env_vars: Dict[str, str], output_file: Union[str, Path])
656
656
  output_path = Path(output_file)
657
657
  output_path.parent.mkdir(parents=True, exist_ok=True)
658
658
 
659
- with open(output_path, "w") as f:
659
+ with output_path.open("w") as f:
660
660
  for key, value in env_vars.items():
661
661
  # Escape special characters in value
662
662
  if " " in value or '"' in value:
@@ -9,7 +9,7 @@ Consolidates Vercel deployment patterns from multiple services.
9
9
  import json
10
10
  import subprocess
11
11
  import tempfile
12
- from datetime import datetime
12
+ from datetime import datetime, timezone
13
13
  from pathlib import Path
14
14
  from typing import Any, Dict, List, Optional
15
15
 
@@ -203,13 +203,13 @@ class VercelDeploymentStrategy(DeploymentStrategy):
203
203
  "deployed_path": deploy_dir,
204
204
  "production": context.config.get("production", False),
205
205
  "stdout": result.stdout,
206
- "timestamp": datetime.now().isoformat(),
206
+ "timestamp": datetime.now(timezone.utc).isoformat(),
207
207
  }
208
208
  raise Exception("Could not parse deployment URL from Vercel output")
209
209
 
210
210
  except subprocess.CalledProcessError as e:
211
211
  self._logger.error(f"Vercel deployment failed: {e.stderr}")
212
- raise Exception(f"Deployment failed: {e.stderr}")
212
+ raise Exception(f"Deployment failed: {e.stderr}") from e
213
213
 
214
214
  def verify(
215
215
  self, context: DeploymentContext, deployment_info: Dict[str, Any]
@@ -336,7 +336,7 @@ class VercelDeploymentStrategy(DeploymentStrategy):
336
336
  health["checks"][f"function_{func_name}"] = (
337
337
  response.status < 500
338
338
  )
339
- except:
339
+ except (urllib.error.URLError, OSError, TimeoutError):
340
340
  health["checks"][f"function_{func_name}"] = False
341
341
 
342
342
  # Determine overall status
@@ -416,7 +416,7 @@ class VercelDeploymentStrategy(DeploymentStrategy):
416
416
 
417
417
  if vercel_config:
418
418
  config_path = deploy_dir / "vercel.json"
419
- with open(config_path, "w") as f:
419
+ with config_path.open("w") as f:
420
420
  json.dump(vercel_config, f, indent=2)
421
421
  return config_path
422
422
 
@@ -430,7 +430,7 @@ class VercelDeploymentStrategy(DeploymentStrategy):
430
430
 
431
431
  if env_vars:
432
432
  env_file = deploy_dir / ".env"
433
- with open(env_file, "w") as f:
433
+ with env_file.open("w") as f:
434
434
  for key, value in env_vars.items():
435
435
  f.write(f"{key}={value}\n")
436
436
  return env_file
@@ -472,5 +472,5 @@ class VercelDeploymentStrategy(DeploymentStrategy):
472
472
  def _generate_deployment_id(self) -> str:
473
473
  """Generate unique deployment ID."""
474
474
  return (
475
- f"vercel_{datetime.now().strftime('%Y%m%d_%H%M%S')}_{id(self) % 10000:04d}"
475
+ f"vercel_{datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S')}_{id(self) % 10000:04d}"
476
476
  )
@@ -335,14 +335,14 @@ class UnifiedConfigManager(IConfigurationService, IUnifiedService):
335
335
 
336
336
  # Save based on file extension
337
337
  if target_path.suffix == ".json":
338
- with open(target_path, "w") as f:
338
+ with target_path.open("w") as f:
339
339
  json.dump(transformed_config, f, indent=2)
340
340
  elif target_path.suffix in [".yaml", ".yml"]:
341
341
  # Would use yaml library here
342
- with open(target_path, "w") as f:
342
+ with target_path.open("w") as f:
343
343
  f.write(str(transformed_config))
344
344
  else:
345
- with open(target_path, "w") as f:
345
+ with target_path.open("w") as f:
346
346
  f.write(str(transformed_config))
347
347
 
348
348
  return ConfigurationResult(
@@ -685,6 +685,6 @@ class UnifiedConfigManager(IConfigurationService, IUnifiedService):
685
685
 
686
686
  def _get_timestamp(self) -> str:
687
687
  """Get current timestamp."""
688
- from datetime import datetime
688
+ from datetime import datetime, timezone
689
689
 
690
- return datetime.now().isoformat()
690
+ return datetime.now(timezone.utc).isoformat()
@@ -460,6 +460,6 @@ class UnifiedDeploymentService(IDeploymentService, IUnifiedService):
460
460
 
461
461
  def _get_timestamp(self) -> str:
462
462
  """Get current timestamp."""
463
- from datetime import datetime
463
+ from datetime import datetime, timezone
464
464
 
465
- return datetime.now().isoformat()
465
+ return datetime.now(timezone.utc).isoformat()
@@ -110,7 +110,7 @@ class UtilityService(BaseService, UtilityServiceInterface):
110
110
  **event_data,
111
111
  }
112
112
 
113
- with open(log_file, "a") as f:
113
+ with log_file.open("a") as f:
114
114
  f.write(json.dumps(log_entry) + "\n")
115
115
 
116
116
  except OSError as e:
@@ -321,7 +321,7 @@ class ConflictResolutionManager:
321
321
 
322
322
  # Check content (simple heuristic)
323
323
  try:
324
- with open(file_path, "rb") as f:
324
+ with file_path.open("rb") as f:
325
325
  chunk = f.read(1024)
326
326
  if b"\0" in chunk:
327
327
  return True
@@ -596,7 +596,7 @@ class ConflictResolutionManager:
596
596
  )
597
597
 
598
598
  # Write resolved content
599
- with open(file_path, "w", encoding="utf-8") as f:
599
+ with file_path.open("w", encoding="utf-8") as f:
600
600
  f.write(resolved_content)
601
601
 
602
602
  return ConflictResolution(
@@ -147,10 +147,10 @@ class GitOperationsManager:
147
147
 
148
148
  return result
149
149
 
150
- except FileNotFoundError:
151
- raise GitOperationError("Git is not installed or not in PATH")
150
+ except FileNotFoundError as e:
151
+ raise GitOperationError("Git is not installed or not in PATH") from e
152
152
  except Exception as e:
153
- raise GitOperationError(f"Error running Git command: {e}")
153
+ raise GitOperationError(f"Error running Git command: {e}") from e
154
154
 
155
155
  def get_current_branch(self) -> str:
156
156
  """Get the current Git branch name."""