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.
Files changed (190) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_ENGINEER.md +47 -0
  3. claude_mpm/agents/BASE_QA.md +60 -0
  4. claude_mpm/agents/frontmatter_validator.py +4 -4
  5. claude_mpm/agents/templates/nextjs_engineer.json +2 -2
  6. claude_mpm/agents/templates/qa.json +13 -3
  7. claude_mpm/agents/templates/react_engineer.json +2 -2
  8. claude_mpm/agents/templates/typescript_engineer.json +2 -2
  9. claude_mpm/agents/templates/web_qa.json +14 -3
  10. claude_mpm/cli/commands/agent_manager.py +3 -3
  11. claude_mpm/cli/commands/agents.py +6 -6
  12. claude_mpm/cli/commands/aggregate.py +4 -4
  13. claude_mpm/cli/commands/analyze.py +2 -2
  14. claude_mpm/cli/commands/analyze_code.py +1 -1
  15. claude_mpm/cli/commands/cleanup.py +3 -3
  16. claude_mpm/cli/commands/config.py +2 -2
  17. claude_mpm/cli/commands/configure.py +14 -14
  18. claude_mpm/cli/commands/dashboard.py +1 -1
  19. claude_mpm/cli/commands/debug.py +3 -3
  20. claude_mpm/cli/commands/doctor.py +1 -1
  21. claude_mpm/cli/commands/mcp.py +7 -7
  22. claude_mpm/cli/commands/mcp_command_router.py +1 -1
  23. claude_mpm/cli/commands/mcp_config.py +2 -2
  24. claude_mpm/cli/commands/mcp_external_commands.py +2 -2
  25. claude_mpm/cli/commands/mcp_install_commands.py +3 -3
  26. claude_mpm/cli/commands/mcp_pipx_config.py +2 -2
  27. claude_mpm/cli/commands/mcp_setup_external.py +3 -3
  28. claude_mpm/cli/commands/monitor.py +1 -1
  29. claude_mpm/cli/commands/mpm_init_handler.py +1 -1
  30. claude_mpm/cli/interactive/agent_wizard.py +1 -1
  31. claude_mpm/cli/parsers/search_parser.py +1 -1
  32. claude_mpm/cli/shared/argument_patterns.py +2 -2
  33. claude_mpm/cli/shared/base_command.py +1 -1
  34. claude_mpm/cli/startup_logging.py +6 -4
  35. claude_mpm/config/experimental_features.py +4 -4
  36. claude_mpm/config/socketio_config.py +2 -2
  37. claude_mpm/core/agent_session_manager.py +2 -2
  38. claude_mpm/core/api_validator.py +3 -3
  39. claude_mpm/core/base_service.py +10 -1
  40. claude_mpm/core/cache.py +2 -2
  41. claude_mpm/core/config.py +4 -4
  42. claude_mpm/core/config_aliases.py +4 -4
  43. claude_mpm/core/config_constants.py +1 -1
  44. claude_mpm/core/error_handler.py +1 -1
  45. claude_mpm/core/file_utils.py +5 -5
  46. claude_mpm/core/framework/formatters/capability_generator.py +5 -5
  47. claude_mpm/core/framework/loaders/agent_loader.py +1 -1
  48. claude_mpm/core/framework/processors/metadata_processor.py +1 -1
  49. claude_mpm/core/framework/processors/template_processor.py +3 -3
  50. claude_mpm/core/framework_loader.py +2 -2
  51. claude_mpm/core/log_manager.py +4 -4
  52. claude_mpm/core/logger.py +2 -2
  53. claude_mpm/core/optimized_startup.py +1 -1
  54. claude_mpm/core/output_style_manager.py +1 -1
  55. claude_mpm/core/service_registry.py +2 -2
  56. claude_mpm/core/session_manager.py +3 -3
  57. claude_mpm/core/shared/config_loader.py +1 -1
  58. claude_mpm/core/socketio_pool.py +2 -2
  59. claude_mpm/core/unified_agent_registry.py +2 -2
  60. claude_mpm/core/unified_config.py +6 -6
  61. claude_mpm/core/unified_paths.py +2 -2
  62. claude_mpm/dashboard/api/simple_directory.py +1 -1
  63. claude_mpm/generators/agent_profile_generator.py +1 -1
  64. claude_mpm/hooks/claude_hooks/event_handlers.py +2 -2
  65. claude_mpm/hooks/claude_hooks/installer.py +9 -9
  66. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +7 -2
  67. claude_mpm/hooks/claude_hooks/tool_analysis.py +2 -2
  68. claude_mpm/hooks/memory_integration_hook.py +1 -1
  69. claude_mpm/hooks/validation_hooks.py +1 -1
  70. claude_mpm/init.py +4 -4
  71. claude_mpm/models/agent_session.py +1 -1
  72. claude_mpm/scripts/socketio_daemon.py +5 -5
  73. claude_mpm/services/__init__.py +2 -2
  74. claude_mpm/services/agent_capabilities_service.py +1 -1
  75. claude_mpm/services/agents/agent_builder.py +6 -4
  76. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -1
  77. claude_mpm/services/agents/deployment/agent_metrics_collector.py +1 -1
  78. claude_mpm/services/agents/deployment/agent_record_service.py +3 -3
  79. claude_mpm/services/agents/deployment/deployment_wrapper.py +1 -1
  80. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +2 -2
  81. claude_mpm/services/agents/loading/agent_profile_loader.py +2 -2
  82. claude_mpm/services/agents/local_template_manager.py +5 -5
  83. claude_mpm/services/agents/registry/deployed_agent_discovery.py +1 -1
  84. claude_mpm/services/agents/registry/modification_tracker.py +19 -11
  85. claude_mpm/services/async_session_logger.py +1 -1
  86. claude_mpm/services/claude_session_logger.py +1 -1
  87. claude_mpm/services/cli/agent_listing_service.py +3 -3
  88. claude_mpm/services/cli/agent_validation_service.py +1 -1
  89. claude_mpm/services/cli/session_manager.py +2 -2
  90. claude_mpm/services/core/path_resolver.py +1 -1
  91. claude_mpm/services/diagnostics/checks/agent_check.py +1 -1
  92. claude_mpm/services/diagnostics/checks/claude_code_check.py +2 -2
  93. claude_mpm/services/diagnostics/checks/common_issues_check.py +3 -3
  94. claude_mpm/services/diagnostics/checks/configuration_check.py +2 -2
  95. claude_mpm/services/diagnostics/checks/installation_check.py +1 -1
  96. claude_mpm/services/diagnostics/checks/mcp_check.py +1 -1
  97. claude_mpm/services/diagnostics/checks/mcp_services_check.py +9 -9
  98. claude_mpm/services/diagnostics/checks/monitor_check.py +1 -1
  99. claude_mpm/services/diagnostics/doctor_reporter.py +1 -1
  100. claude_mpm/services/event_aggregator.py +1 -1
  101. claude_mpm/services/event_bus/event_bus.py +9 -2
  102. claude_mpm/services/events/consumers/dead_letter.py +2 -2
  103. claude_mpm/services/framework_claude_md_generator/__init__.py +1 -1
  104. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +3 -3
  105. claude_mpm/services/framework_claude_md_generator/version_manager.py +1 -1
  106. claude_mpm/services/hook_installer_service.py +7 -7
  107. claude_mpm/services/infrastructure/context_preservation.py +7 -7
  108. claude_mpm/services/infrastructure/daemon_manager.py +5 -5
  109. claude_mpm/services/mcp_config_manager.py +10 -10
  110. claude_mpm/services/mcp_gateway/auto_configure.py +5 -5
  111. claude_mpm/services/mcp_gateway/config/config_loader.py +2 -2
  112. claude_mpm/services/mcp_gateway/config/configuration.py +5 -3
  113. claude_mpm/services/mcp_gateway/core/process_pool.py +3 -3
  114. claude_mpm/services/mcp_gateway/core/singleton_manager.py +2 -2
  115. claude_mpm/services/mcp_gateway/core/startup_verification.py +1 -1
  116. claude_mpm/services/mcp_gateway/main.py +1 -1
  117. claude_mpm/services/mcp_gateway/registry/service_registry.py +4 -2
  118. claude_mpm/services/mcp_gateway/registry/tool_registry.py +2 -1
  119. claude_mpm/services/mcp_gateway/server/stdio_handler.py +1 -1
  120. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
  121. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +1 -1
  122. claude_mpm/services/mcp_gateway/tools/hello_world.py +1 -1
  123. claude_mpm/services/mcp_gateway/utils/package_version_checker.py +5 -5
  124. claude_mpm/services/mcp_gateway/utils/update_preferences.py +2 -2
  125. claude_mpm/services/mcp_service_verifier.py +1 -1
  126. claude_mpm/services/memory/builder.py +1 -1
  127. claude_mpm/services/memory/cache/shared_prompt_cache.py +2 -1
  128. claude_mpm/services/memory/indexed_memory.py +3 -3
  129. claude_mpm/services/monitor/daemon.py +1 -1
  130. claude_mpm/services/monitor/daemon_manager.py +9 -9
  131. claude_mpm/services/monitor/handlers/file.py +1 -1
  132. claude_mpm/services/monitor/handlers/hooks.py +3 -3
  133. claude_mpm/services/monitor/management/lifecycle.py +7 -7
  134. claude_mpm/services/monitor/server.py +2 -2
  135. claude_mpm/services/orphan_detection.py +11 -16
  136. claude_mpm/services/port_manager.py +2 -2
  137. claude_mpm/services/project/analyzer.py +3 -3
  138. claude_mpm/services/project/archive_manager.py +17 -13
  139. claude_mpm/services/project/dependency_analyzer.py +4 -4
  140. claude_mpm/services/project/documentation_manager.py +4 -4
  141. claude_mpm/services/project/enhanced_analyzer.py +19 -8
  142. claude_mpm/services/project/registry.py +4 -4
  143. claude_mpm/services/project_port_allocator.py +7 -12
  144. claude_mpm/services/session_management_service.py +1 -1
  145. claude_mpm/services/socketio/event_normalizer.py +1 -1
  146. claude_mpm/services/socketio/handlers/code_analysis.py +14 -12
  147. claude_mpm/services/socketio/handlers/file.py +1 -1
  148. claude_mpm/services/socketio/migration_utils.py +1 -1
  149. claude_mpm/services/socketio/server/core.py +1 -1
  150. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +1 -1
  151. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +4 -4
  152. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +1 -1
  153. claude_mpm/services/unified/config_strategies/config_schema.py +4 -4
  154. claude_mpm/services/unified/config_strategies/context_strategy.py +8 -6
  155. claude_mpm/services/unified/config_strategies/error_handling_strategy.py +10 -10
  156. claude_mpm/services/unified/config_strategies/file_loader_strategy.py +5 -5
  157. claude_mpm/services/unified/config_strategies/unified_config_service.py +8 -8
  158. claude_mpm/services/unified/config_strategies/validation_strategy.py +15 -15
  159. claude_mpm/services/unified/deployment_strategies/base.py +4 -4
  160. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +15 -15
  161. claude_mpm/services/unified/deployment_strategies/local.py +11 -11
  162. claude_mpm/services/unified/deployment_strategies/utils.py +11 -9
  163. claude_mpm/services/unified/deployment_strategies/vercel.py +7 -9
  164. claude_mpm/services/unified/unified_config.py +5 -5
  165. claude_mpm/services/unified/unified_deployment.py +2 -2
  166. claude_mpm/services/utility_service.py +1 -1
  167. claude_mpm/services/version_control/conflict_resolution.py +2 -2
  168. claude_mpm/services/version_control/git_operations.py +3 -3
  169. claude_mpm/services/version_control/semantic_versioning.py +13 -13
  170. claude_mpm/services/version_control/version_parser.py +1 -1
  171. claude_mpm/storage/state_storage.py +12 -13
  172. claude_mpm/tools/code_tree_analyzer.py +5 -5
  173. claude_mpm/tools/code_tree_builder.py +4 -4
  174. claude_mpm/tools/socketio_debug.py +1 -1
  175. claude_mpm/utils/agent_dependency_loader.py +4 -4
  176. claude_mpm/utils/common.py +2 -2
  177. claude_mpm/utils/config_manager.py +3 -3
  178. claude_mpm/utils/dependency_cache.py +2 -2
  179. claude_mpm/utils/dependency_strategies.py +6 -6
  180. claude_mpm/utils/file_utils.py +11 -11
  181. claude_mpm/utils/log_cleanup.py +1 -1
  182. claude_mpm/utils/path_operations.py +1 -1
  183. claude_mpm/validation/agent_validator.py +2 -2
  184. claude_mpm/validation/frontmatter_validator.py +1 -1
  185. {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.13.dist-info}/METADATA +1 -1
  186. {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.13.dist-info}/RECORD +190 -190
  187. {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.13.dist-info}/WHEEL +0 -0
  188. {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.13.dist-info}/entry_points.txt +0 -0
  189. {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.13.dist-info}/licenses/LICENSE +0 -0
  190. {claude_mpm-4.5.11.dist-info → claude_mpm-4.5.13.dist-info}/top_level.txt +0 -0
@@ -143,9 +143,7 @@ class ProjectPortAllocator(SyncBaseService):
143
143
 
144
144
  # Map to port range
145
145
  port_range = self.port_range_end - self.port_range_start + 1
146
- port = self.port_range_start + (hash_int % port_range)
147
-
148
- return port
146
+ return self.port_range_start + (hash_int % port_range)
149
147
 
150
148
  def _is_port_available(self, port: int) -> bool:
151
149
  """
@@ -177,10 +175,7 @@ class ProjectPortAllocator(SyncBaseService):
177
175
  Returns:
178
176
  True if port is protected
179
177
  """
180
- for start, end in self.PROTECTED_PORT_RANGES:
181
- if start <= port <= end:
182
- return True
183
- return False
178
+ return any(start <= port <= end for start, end in self.PROTECTED_PORT_RANGES)
184
179
 
185
180
  def _load_project_state(self) -> Dict[str, Any]:
186
181
  """
@@ -191,7 +186,7 @@ class ProjectPortAllocator(SyncBaseService):
191
186
  """
192
187
  try:
193
188
  if self.state_file.exists():
194
- with open(self.state_file) as f:
189
+ with self.state_file.open() as f:
195
190
  return json.load(f)
196
191
  except Exception as e:
197
192
  self.log_warning(f"Failed to load project state: {e}")
@@ -208,7 +203,7 @@ class ProjectPortAllocator(SyncBaseService):
208
203
  try:
209
204
  # Write to temporary file first
210
205
  temp_file = self.state_file.with_suffix(".tmp")
211
- with open(temp_file, "w") as f:
206
+ with temp_file.open("w") as f:
212
207
  json.dump(state, f, indent=2)
213
208
 
214
209
  # Atomic rename
@@ -227,7 +222,7 @@ class ProjectPortAllocator(SyncBaseService):
227
222
  """
228
223
  try:
229
224
  if self.global_registry_file.exists():
230
- with open(self.global_registry_file) as f:
225
+ with self.global_registry_file.open() as f:
231
226
  return json.load(f)
232
227
  except Exception as e:
233
228
  self.log_warning(f"Failed to load global registry: {e}")
@@ -247,7 +242,7 @@ class ProjectPortAllocator(SyncBaseService):
247
242
 
248
243
  # Write to temporary file first
249
244
  temp_file = self.global_registry_file.with_suffix(".tmp")
250
- with open(temp_file, "w") as f:
245
+ with temp_file.open("w") as f:
251
246
  json.dump(registry, f, indent=2)
252
247
 
253
248
  # Atomic rename
@@ -507,7 +502,7 @@ class ProjectPortAllocator(SyncBaseService):
507
502
  state_file = project_path / ".claude-mpm" / self.STATE_FILE_NAME
508
503
  if state_file.exists():
509
504
  try:
510
- with open(state_file) as f:
505
+ with state_file.open() as f:
511
506
  project_state = json.load(f)
512
507
 
513
508
  # Check if service still registered
@@ -187,7 +187,7 @@ class SessionManagementService(BaseService, SessionManagementInterface):
187
187
  event_data["timestamp"] = datetime.now(timezone.utc).isoformat()
188
188
 
189
189
  # Append to log file as JSONL
190
- with open(log_file, "a") as f:
190
+ with log_file.open("a") as f:
191
191
  f.write(json.dumps(event_data) + "\n")
192
192
 
193
193
  except Exception as e:
@@ -342,7 +342,7 @@ class EventNormalizer:
342
342
 
343
343
  return "unknown"
344
344
 
345
- def _map_event_name(self, event_name: str) -> Tuple[str, str]: # noqa: PLR0911
345
+ def _map_event_name(self, event_name: str) -> Tuple[str, str]:
346
346
  """Map event name to (type, subtype) tuple.
347
347
 
348
348
  WHY: Consistent categorization helps clients filter and handle events.
@@ -41,6 +41,14 @@ class CodeAnalysisEventHandler(BaseEventHandler):
41
41
  self.logger = get_logger(__name__)
42
42
  self.analysis_runner = None
43
43
  self.code_analyzer = None # For lazy loading operations
44
+ self._emit_tasks: set = set() # Track emit tasks to prevent GC
45
+
46
+ def _create_emit_task(self, coro):
47
+ """Create a tracked emit task to prevent garbage collection."""
48
+ task = asyncio.get_event_loop().create_task(coro)
49
+ self._emit_tasks.add(task)
50
+ task.add_done_callback(self._emit_tasks.discard)
51
+ return task
44
52
 
45
53
  def initialize(self):
46
54
  """Initialize the analysis runner."""
@@ -246,16 +254,14 @@ class CodeAnalysisEventHandler(BaseEventHandler):
246
254
  # Special handling for 'info' events - they should be passed through directly
247
255
  if event_type == "info":
248
256
  # INFO events for granular tracking
249
- loop = asyncio.get_event_loop()
250
- loop.create_task(
257
+ self._create_emit_task(
251
258
  self.server.core.sio.emit(
252
259
  "info", {"request_id": request_id, **event_data}
253
260
  )
254
261
  )
255
262
  else:
256
263
  # Regular code analysis events
257
- loop = asyncio.get_event_loop()
258
- loop.create_task(
264
+ self._create_emit_task(
259
265
  self.server.core.sio.emit(
260
266
  event_type, {"request_id": request_id, **event_data}
261
267
  )
@@ -437,16 +443,14 @@ class CodeAnalysisEventHandler(BaseEventHandler):
437
443
  # Special handling for 'info' events - they should be passed through directly
438
444
  if event_type == "info":
439
445
  # INFO events for granular tracking
440
- loop = asyncio.get_event_loop()
441
- loop.create_task(
446
+ self._create_emit_task(
442
447
  self.server.core.sio.emit(
443
448
  "info", {"request_id": request_id, **event_data}
444
449
  )
445
450
  )
446
451
  else:
447
452
  # Regular code analysis events
448
- loop = asyncio.get_event_loop()
449
- loop.create_task(
453
+ self._create_emit_task(
450
454
  self.server.core.sio.emit(
451
455
  event_type, {"request_id": request_id, **event_data}
452
456
  )
@@ -609,16 +613,14 @@ class CodeAnalysisEventHandler(BaseEventHandler):
609
613
  # Special handling for 'info' events - they should be passed through directly
610
614
  if event_type == "info":
611
615
  # INFO events for granular tracking
612
- loop = asyncio.get_event_loop()
613
- loop.create_task(
616
+ self._create_emit_task(
614
617
  self.server.core.sio.emit(
615
618
  "info", {"request_id": request_id, **event_data}
616
619
  )
617
620
  )
618
621
  else:
619
622
  # Regular code analysis events
620
- loop = asyncio.get_event_loop()
621
- loop.create_task(
623
+ self._create_emit_task(
622
624
  self.server.core.sio.emit(
623
625
  event_type, {"request_id": request_id, **event_data}
624
626
  )
@@ -224,7 +224,7 @@ class FileEventHandler(BaseEventHandler):
224
224
  be displayed as text.
225
225
  """
226
226
  try:
227
- with open(real_path, "rb") as f:
227
+ with real_path.open("rb") as f:
228
228
  binary_content = f.read()
229
229
 
230
230
  # Check if it's a text file by looking for common text patterns
@@ -223,7 +223,7 @@ class EventTypeMapper:
223
223
  }
224
224
 
225
225
  @classmethod
226
- def map_event_type(cls, old_type: str) -> Tuple[str, str]: # noqa: PLR0911
226
+ def map_event_type(cls, old_type: str) -> Tuple[str, str]:
227
227
  """Map an old event type to new type/subtype.
228
228
 
229
229
  WHY: Provides consistent categorization for all events.
@@ -428,7 +428,7 @@ class SocketIOServerCore:
428
428
  )
429
429
 
430
430
  # Add file reading endpoint for source viewer
431
- async def file_read_handler(request): # noqa: PLR0911
431
+ async def file_read_handler(request):
432
432
  """Handle GET /api/file/read for reading source files."""
433
433
  import os
434
434
 
@@ -305,7 +305,7 @@ class CodeAnalyzerStrategy(AnalyzerStrategy):
305
305
  tree = ast.parse(content)
306
306
  complexity["cyclomatic"] = self._calculate_cyclomatic_complexity(tree)
307
307
  complexity["cognitive"] = self._calculate_cognitive_complexity(tree)
308
- except:
308
+ except (SyntaxError, ValueError):
309
309
  pass
310
310
 
311
311
  return complexity
@@ -372,7 +372,7 @@ class DependencyAnalyzerStrategy(AnalyzerStrategy):
372
372
  def _parse_package_json(self, path: Path) -> Dict[str, Any]:
373
373
  """Parse package.json file."""
374
374
  try:
375
- with open(path) as f:
375
+ with path.open() as f:
376
376
  data = json.load(f)
377
377
 
378
378
  return {
@@ -417,7 +417,7 @@ class DependencyAnalyzerStrategy(AnalyzerStrategy):
417
417
  return {}
418
418
 
419
419
  try:
420
- with open(path, "rb") as f:
420
+ with path.open("rb") as f:
421
421
  data = tomllib.load(f)
422
422
 
423
423
  dependencies = {}
@@ -459,7 +459,7 @@ class DependencyAnalyzerStrategy(AnalyzerStrategy):
459
459
  return {}
460
460
 
461
461
  try:
462
- with open(path, "rb") as f:
462
+ with path.open("rb") as f:
463
463
  data = tomllib.load(f)
464
464
 
465
465
  return {
@@ -481,7 +481,7 @@ class DependencyAnalyzerStrategy(AnalyzerStrategy):
481
481
  return {}
482
482
 
483
483
  try:
484
- with open(path, "rb") as f:
484
+ with path.open("rb") as f:
485
485
  data = tomllib.load(f)
486
486
 
487
487
  return {
@@ -292,7 +292,7 @@ class StructureAnalyzerStrategy(AnalyzerStrategy):
292
292
  # Get file info
293
293
  try:
294
294
  size = item.stat().st_size
295
- except:
295
+ except (OSError, PermissionError):
296
296
  size = 0
297
297
 
298
298
  child_node = {
@@ -471,7 +471,7 @@ class SchemaValidator:
471
471
  try:
472
472
  datetime.strptime(value, format)
473
473
  return True
474
- except:
474
+ except (ValueError, TypeError):
475
475
  return False
476
476
 
477
477
  def _validate_uuid(self, value: str) -> bool:
@@ -481,7 +481,7 @@ class SchemaValidator:
481
481
  try:
482
482
  uuid.UUID(value)
483
483
  return True
484
- except:
484
+ except (ValueError, TypeError, AttributeError):
485
485
  return False
486
486
 
487
487
  def _validate_ipv4(self, value: str) -> bool:
@@ -491,7 +491,7 @@ class SchemaValidator:
491
491
  try:
492
492
  ipaddress.IPv4Address(value)
493
493
  return True
494
- except:
494
+ except (ValueError, TypeError, ipaddress.AddressValueError):
495
495
  return False
496
496
 
497
497
  def _validate_ipv6(self, value: str) -> bool:
@@ -501,7 +501,7 @@ class SchemaValidator:
501
501
  try:
502
502
  ipaddress.IPv6Address(value)
503
503
  return True
504
- except:
504
+ except (ValueError, TypeError, ipaddress.AddressValueError):
505
505
  return False
506
506
 
507
507
  def _validate_semver(self, value: str) -> bool:
@@ -9,7 +9,7 @@ from abc import ABC, abstractmethod
9
9
  from collections import OrderedDict
10
10
  from contextlib import contextmanager
11
11
  from dataclasses import dataclass, field
12
- from datetime import datetime, timedelta
12
+ from datetime import datetime, timedelta, timezone
13
13
  from enum import Enum
14
14
  from pathlib import Path
15
15
  from typing import Any, Callable, Dict, List, Optional, Set, Union
@@ -124,11 +124,11 @@ class HierarchicalContextManager(BaseContextManager):
124
124
  id=context_id,
125
125
  scope=scope,
126
126
  lifecycle=ContextLifecycle.CREATED,
127
- created_at=datetime.now(),
128
- updated_at=datetime.now(),
127
+ created_at=datetime.now(timezone.utc),
128
+ updated_at=datetime.now(timezone.utc),
129
129
  parent_id=parent_id,
130
130
  ttl=ttl,
131
- expires_at=datetime.now() + ttl if ttl else None,
131
+ expires_at=datetime.now(timezone.utc) + ttl if ttl else None,
132
132
  attributes=kwargs,
133
133
  )
134
134
 
@@ -158,7 +158,7 @@ class HierarchicalContextManager(BaseContextManager):
158
158
 
159
159
  # Check expiration
160
160
  if context and context.expires_at:
161
- if datetime.now() > context.expires_at:
161
+ if datetime.now(timezone.utc) > context.expires_at:
162
162
  self.close_context(context_id)
163
163
  return None
164
164
 
@@ -299,7 +299,9 @@ class ScopedConfigManager:
299
299
 
300
300
  # Update context metadata
301
301
  if context_id in self.context_manager.contexts:
302
- self.context_manager.contexts[context_id].updated_at = datetime.now()
302
+ self.context_manager.contexts[context_id].updated_at = datetime.now(
303
+ timezone.utc
304
+ )
303
305
 
304
306
  def _get_inherited_config(self, context_id: str) -> Dict[str, Any]:
305
307
  """Get merged configuration from context hierarchy"""
@@ -206,7 +206,7 @@ class FileIOErrorHandler(BaseErrorHandler):
206
206
  result.fallback_value = str(alt_path)
207
207
  result.actions_taken.append(f"Using alternative location: {alt_path}")
208
208
 
209
- except:
209
+ except (OSError, PermissionError):
210
210
  result.should_escalate = True
211
211
 
212
212
  # Use read-only mode if applicable
@@ -293,7 +293,7 @@ class ParsingErrorHandler(BaseErrorHandler):
293
293
  result.actions_taken.append(f"Fixed JSON with {fix_func.__name__}")
294
294
  self.logger.info(f"Recovered from JSON error using {fix_func.__name__}")
295
295
  return result
296
- except:
296
+ except (json.JSONDecodeError, ValueError, TypeError):
297
297
  continue
298
298
 
299
299
  # Use lenient parser if available
@@ -346,7 +346,7 @@ class ParsingErrorHandler(BaseErrorHandler):
346
346
  result.recovered = True
347
347
  result.fallback_value = parsed
348
348
  result.actions_taken.append("Parsed as Python literal")
349
- except:
349
+ except (ValueError, SyntaxError, TypeError):
350
350
  # Return empty dict as last resort
351
351
  result.recovered = True
352
352
  result.fallback_value = {}
@@ -370,7 +370,7 @@ class ParsingErrorHandler(BaseErrorHandler):
370
370
  result.fallback_value = parsed
371
371
  result.actions_taken.append("Parsed with safe YAML loader")
372
372
 
373
- except:
373
+ except (yaml.YAMLError, ValueError, AttributeError):
374
374
  # Try to fix tabs
375
375
  content = content.replace("\t", " ")
376
376
  try:
@@ -378,7 +378,7 @@ class ParsingErrorHandler(BaseErrorHandler):
378
378
  result.recovered = True
379
379
  result.fallback_value = parsed
380
380
  result.actions_taken.append("Fixed YAML tabs")
381
- except:
381
+ except (yaml.YAMLError, ValueError, AttributeError):
382
382
  result.fallback_value = {}
383
383
  result.actions_taken.append("Used empty configuration as fallback")
384
384
 
@@ -406,7 +406,7 @@ class ParsingErrorHandler(BaseErrorHandler):
406
406
  result.fallback_value = parsed
407
407
  result.actions_taken.append(f"Parsed as {format_name}")
408
408
  return result
409
- except:
409
+ except (ValueError, TypeError, AttributeError, ImportError):
410
410
  continue
411
411
 
412
412
  # Use default/empty config
@@ -533,7 +533,7 @@ class ValidationErrorHandler(BaseErrorHandler):
533
533
  if isinstance(value, str):
534
534
  return json.loads(value)
535
535
  return dict(value)
536
- except:
536
+ except (ValueError, TypeError, json.JSONDecodeError):
537
537
  return None
538
538
 
539
539
  def _handle_generic_validation(
@@ -661,7 +661,7 @@ class TypeConversionErrorHandler(BaseErrorHandler):
661
661
  if converter:
662
662
  try:
663
663
  return converter(value)
664
- except:
664
+ except (ValueError, TypeError, AttributeError):
665
665
  pass
666
666
 
667
667
  return None
@@ -706,7 +706,7 @@ class TypeConversionErrorHandler(BaseErrorHandler):
706
706
  if value.startswith("["):
707
707
  try:
708
708
  return json.loads(value)
709
- except:
709
+ except (json.JSONDecodeError, ValueError):
710
710
  pass
711
711
  # Try comma-separated
712
712
  return [v.strip() for v in value.split(",")]
@@ -720,7 +720,7 @@ class TypeConversionErrorHandler(BaseErrorHandler):
720
720
  # Try JSON object
721
721
  try:
722
722
  return json.loads(value)
723
- except:
723
+ except (json.JSONDecodeError, ValueError):
724
724
  pass
725
725
  # Try key=value pairs
726
726
  result = {}
@@ -75,7 +75,7 @@ class BaseFileLoader(ABC):
75
75
  f"Read {path} with fallback encoding: {enc}"
76
76
  )
77
77
  return f.read()
78
- except:
78
+ except (UnicodeDecodeError, OSError):
79
79
  continue
80
80
  raise
81
81
 
@@ -185,8 +185,8 @@ class StructuredFileLoader(BaseFileLoader):
185
185
  import tomli
186
186
 
187
187
  return tomli.loads(content)
188
- except ImportError:
189
- raise ImportError("Neither toml nor tomli package is installed")
188
+ except ImportError as e:
189
+ raise ImportError("Neither toml nor tomli package is installed") from e
190
190
  except Exception as e:
191
191
  if context.strict:
192
192
  raise
@@ -209,7 +209,7 @@ class StructuredFileLoader(BaseFileLoader):
209
209
 
210
210
  try:
211
211
  return json.loads(content)
212
- except:
212
+ except (json.JSONDecodeError, ValueError):
213
213
  return {}
214
214
 
215
215
  def _process_includes(
@@ -411,7 +411,7 @@ class EnvironmentFileLoader(BaseFileLoader):
411
411
  if value.startswith(("[", "{")):
412
412
  try:
413
413
  return json.loads(value)
414
- except:
414
+ except (json.JSONDecodeError, ValueError):
415
415
  pass
416
416
 
417
417
  # Comma-separated list
@@ -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