claude-mpm 4.3.22__py3-none-any.whl → 4.4.3__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 (74) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/WORKFLOW.md +2 -14
  3. claude_mpm/cli/commands/configure.py +2 -29
  4. claude_mpm/cli/commands/doctor.py +2 -2
  5. claude_mpm/cli/commands/mpm_init.py +3 -3
  6. claude_mpm/cli/parsers/configure_parser.py +4 -15
  7. claude_mpm/core/framework/__init__.py +38 -0
  8. claude_mpm/core/framework/formatters/__init__.py +11 -0
  9. claude_mpm/core/framework/formatters/capability_generator.py +356 -0
  10. claude_mpm/core/framework/formatters/content_formatter.py +283 -0
  11. claude_mpm/core/framework/formatters/context_generator.py +180 -0
  12. claude_mpm/core/framework/loaders/__init__.py +13 -0
  13. claude_mpm/core/framework/loaders/agent_loader.py +202 -0
  14. claude_mpm/core/framework/loaders/file_loader.py +213 -0
  15. claude_mpm/core/framework/loaders/instruction_loader.py +151 -0
  16. claude_mpm/core/framework/loaders/packaged_loader.py +208 -0
  17. claude_mpm/core/framework/processors/__init__.py +11 -0
  18. claude_mpm/core/framework/processors/memory_processor.py +222 -0
  19. claude_mpm/core/framework/processors/metadata_processor.py +146 -0
  20. claude_mpm/core/framework/processors/template_processor.py +238 -0
  21. claude_mpm/core/framework_loader.py +277 -1798
  22. claude_mpm/hooks/__init__.py +9 -1
  23. claude_mpm/hooks/kuzu_memory_hook.py +352 -0
  24. claude_mpm/hooks/memory_integration_hook.py +1 -1
  25. claude_mpm/services/agents/memory/content_manager.py +5 -2
  26. claude_mpm/services/agents/memory/memory_file_service.py +1 -0
  27. claude_mpm/services/agents/memory/memory_limits_service.py +1 -0
  28. claude_mpm/services/core/path_resolver.py +1 -0
  29. claude_mpm/services/diagnostics/diagnostic_runner.py +1 -0
  30. claude_mpm/services/mcp_config_manager.py +67 -4
  31. claude_mpm/services/mcp_gateway/core/process_pool.py +281 -0
  32. claude_mpm/services/mcp_gateway/core/startup_verification.py +2 -2
  33. claude_mpm/services/mcp_gateway/main.py +3 -13
  34. claude_mpm/services/mcp_gateway/server/stdio_server.py +4 -10
  35. claude_mpm/services/mcp_gateway/tools/__init__.py +13 -2
  36. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +36 -6
  37. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +542 -0
  38. claude_mpm/services/shared/__init__.py +2 -1
  39. claude_mpm/services/shared/service_factory.py +8 -5
  40. claude_mpm/services/unified/__init__.py +65 -0
  41. claude_mpm/services/unified/analyzer_strategies/__init__.py +44 -0
  42. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +473 -0
  43. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +643 -0
  44. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +804 -0
  45. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +661 -0
  46. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +696 -0
  47. claude_mpm/services/unified/config_strategies/__init__.py +190 -0
  48. claude_mpm/services/unified/config_strategies/config_schema.py +689 -0
  49. claude_mpm/services/unified/config_strategies/context_strategy.py +748 -0
  50. claude_mpm/services/unified/config_strategies/error_handling_strategy.py +999 -0
  51. claude_mpm/services/unified/config_strategies/file_loader_strategy.py +871 -0
  52. claude_mpm/services/unified/config_strategies/unified_config_service.py +802 -0
  53. claude_mpm/services/unified/config_strategies/validation_strategy.py +1105 -0
  54. claude_mpm/services/unified/deployment_strategies/__init__.py +97 -0
  55. claude_mpm/services/unified/deployment_strategies/base.py +557 -0
  56. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +486 -0
  57. claude_mpm/services/unified/deployment_strategies/local.py +594 -0
  58. claude_mpm/services/unified/deployment_strategies/utils.py +672 -0
  59. claude_mpm/services/unified/deployment_strategies/vercel.py +471 -0
  60. claude_mpm/services/unified/interfaces.py +499 -0
  61. claude_mpm/services/unified/migration.py +532 -0
  62. claude_mpm/services/unified/strategies.py +551 -0
  63. claude_mpm/services/unified/unified_analyzer.py +534 -0
  64. claude_mpm/services/unified/unified_config.py +688 -0
  65. claude_mpm/services/unified/unified_deployment.py +470 -0
  66. {claude_mpm-4.3.22.dist-info → claude_mpm-4.4.3.dist-info}/METADATA +15 -15
  67. {claude_mpm-4.3.22.dist-info → claude_mpm-4.4.3.dist-info}/RECORD +71 -32
  68. claude_mpm/cli/commands/configure_tui.py +0 -1927
  69. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +0 -645
  70. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +0 -602
  71. {claude_mpm-4.3.22.dist-info → claude_mpm-4.4.3.dist-info}/WHEEL +0 -0
  72. {claude_mpm-4.3.22.dist-info → claude_mpm-4.4.3.dist-info}/entry_points.txt +0 -0
  73. {claude_mpm-4.3.22.dist-info → claude_mpm-4.4.3.dist-info}/licenses/LICENSE +0 -0
  74. {claude_mpm-4.3.22.dist-info → claude_mpm-4.4.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,532 @@
1
+ """
2
+ Migration Utilities for Service Consolidation
3
+ =============================================
4
+
5
+ This module provides utilities for migrating from the existing 314 service files
6
+ to the consolidated unified service architecture. It includes service mapping,
7
+ backward compatibility wrappers, and feature flags for gradual rollout.
8
+
9
+ Key Components:
10
+ 1. ServiceMapper: Maps legacy services to unified services
11
+ 2. Compatibility wrappers: Maintain backward compatibility
12
+ 3. Feature flags: Control gradual migration rollout
13
+ 4. Migration status tracking: Monitor migration progress
14
+
15
+ Migration Strategy:
16
+ - Phase 1: Create unified interfaces and strategies
17
+ - Phase 2: Implement unified services with strategy pattern
18
+ - Phase 3: Create compatibility wrappers for legacy code
19
+ - Phase 4: Gradually migrate consumers to unified services
20
+ - Phase 5: Deprecate and remove legacy services
21
+ """
22
+
23
+ import inspect
24
+ from dataclasses import dataclass, field
25
+ from enum import Enum
26
+ from pathlib import Path
27
+ from typing import Any, Callable, Dict, List, Optional, Set, Type, TypeVar
28
+
29
+ from claude_mpm.core.logging_utils import get_logger
30
+
31
+ logger = get_logger(__name__)
32
+
33
+ # Type variables
34
+ T = TypeVar("T")
35
+ ServiceType = TypeVar("ServiceType")
36
+
37
+
38
+ class MigrationStatus(Enum):
39
+ """Status of service migration."""
40
+
41
+ NOT_STARTED = "not_started"
42
+ IN_PROGRESS = "in_progress"
43
+ TESTING = "testing"
44
+ COMPLETED = "completed"
45
+ DEPRECATED = "deprecated"
46
+ REMOVED = "removed"
47
+
48
+
49
+ class FeatureFlag(Enum):
50
+ """Feature flags for controlling migration rollout."""
51
+
52
+ USE_UNIFIED_DEPLOYMENT = "use_unified_deployment"
53
+ USE_UNIFIED_ANALYZER = "use_unified_analyzer"
54
+ USE_UNIFIED_CONFIG = "use_unified_config"
55
+ ENABLE_COMPATIBILITY_MODE = "enable_compatibility_mode"
56
+ LOG_MIGRATION_WARNINGS = "log_migration_warnings"
57
+ ENFORCE_NEW_INTERFACES = "enforce_new_interfaces"
58
+ ALLOW_LEGACY_FALLBACK = "allow_legacy_fallback"
59
+
60
+
61
+ @dataclass
62
+ class ServiceMapping:
63
+ """
64
+ Mapping between legacy service and unified service.
65
+
66
+ Attributes:
67
+ legacy_path: Path to legacy service module
68
+ legacy_class: Legacy service class name
69
+ unified_service: Unified service class
70
+ unified_strategy: Strategy to use in unified service
71
+ status: Migration status
72
+ compatibility_wrapper: Optional compatibility wrapper class
73
+ notes: Migration notes and considerations
74
+ """
75
+
76
+ legacy_path: str
77
+ legacy_class: str
78
+ unified_service: str
79
+ unified_strategy: Optional[str] = None
80
+ status: MigrationStatus = MigrationStatus.NOT_STARTED
81
+ compatibility_wrapper: Optional[str] = None
82
+ notes: str = ""
83
+
84
+
85
+ @dataclass
86
+ class MigrationMetrics:
87
+ """
88
+ Metrics for tracking migration progress.
89
+
90
+ Attributes:
91
+ total_services: Total number of services to migrate
92
+ migrated_services: Number of successfully migrated services
93
+ in_progress: Number of services currently being migrated
94
+ deprecated_services: Number of deprecated services
95
+ removed_services: Number of removed services
96
+ migration_errors: Count of migration errors
97
+ start_date: Migration start date
98
+ target_date: Target completion date
99
+ """
100
+
101
+ total_services: int = 314 # Current service count
102
+ migrated_services: int = 0
103
+ in_progress: int = 0
104
+ deprecated_services: int = 0
105
+ removed_services: int = 0
106
+ migration_errors: int = 0
107
+ start_date: str = ""
108
+ target_date: str = ""
109
+
110
+ @property
111
+ def completion_percentage(self) -> float:
112
+ """Calculate migration completion percentage."""
113
+ if self.total_services == 0:
114
+ return 0.0
115
+ return (self.migrated_services / self.total_services) * 100
116
+
117
+ @property
118
+ def remaining_services(self) -> int:
119
+ """Calculate remaining services to migrate."""
120
+ return self.total_services - self.migrated_services - self.removed_services
121
+
122
+
123
+ class ServiceMapper:
124
+ """
125
+ Maps legacy services to unified services and manages migration.
126
+
127
+ This class maintains the mapping between old service implementations
128
+ and new unified services, facilitating gradual migration.
129
+ """
130
+
131
+ def __init__(self):
132
+ """Initialize service mapper."""
133
+ self._mappings: Dict[str, ServiceMapping] = {}
134
+ self._feature_flags: Dict[FeatureFlag, bool] = {
135
+ flag: False for flag in FeatureFlag
136
+ }
137
+ self._metrics = MigrationMetrics()
138
+ self._logger = get_logger(f"{__name__}.ServiceMapper")
139
+ self._initialize_mappings()
140
+
141
+ def _initialize_mappings(self) -> None:
142
+ """Initialize default service mappings."""
143
+ # Example mappings for deployment services
144
+ self.add_mapping(
145
+ ServiceMapping(
146
+ legacy_path="claude_mpm.services.agent_deployment",
147
+ legacy_class="AgentDeploymentService",
148
+ unified_service="UnifiedDeploymentService",
149
+ unified_strategy="AgentDeploymentStrategy",
150
+ status=MigrationStatus.NOT_STARTED,
151
+ notes="Consolidate with other deployment services",
152
+ )
153
+ )
154
+
155
+ # Example mappings for analyzer services
156
+ self.add_mapping(
157
+ ServiceMapping(
158
+ legacy_path="claude_mpm.services.code_analyzer",
159
+ legacy_class="CodeAnalyzer",
160
+ unified_service="UnifiedAnalyzer",
161
+ unified_strategy="CodeAnalysisStrategy",
162
+ status=MigrationStatus.NOT_STARTED,
163
+ notes="Merge with complexity and dependency analyzers",
164
+ )
165
+ )
166
+
167
+ # Example mappings for configuration services
168
+ self.add_mapping(
169
+ ServiceMapping(
170
+ legacy_path="claude_mpm.services.project_config",
171
+ legacy_class="ProjectConfigService",
172
+ unified_service="UnifiedConfigManager",
173
+ unified_strategy="ProjectConfigStrategy",
174
+ status=MigrationStatus.NOT_STARTED,
175
+ notes="Consolidate all config services",
176
+ )
177
+ )
178
+
179
+ def add_mapping(self, mapping: ServiceMapping) -> None:
180
+ """
181
+ Add a service mapping.
182
+
183
+ Args:
184
+ mapping: Service mapping to add
185
+ """
186
+ key = f"{mapping.legacy_path}.{mapping.legacy_class}"
187
+ self._mappings[key] = mapping
188
+ self._logger.debug(f"Added mapping for {key}")
189
+
190
+ def get_mapping(self, legacy_service: str) -> Optional[ServiceMapping]:
191
+ """
192
+ Get mapping for a legacy service.
193
+
194
+ Args:
195
+ legacy_service: Legacy service identifier
196
+
197
+ Returns:
198
+ Optional[ServiceMapping]: Service mapping if found
199
+ """
200
+ return self._mappings.get(legacy_service)
201
+
202
+ def get_unified_service(
203
+ self, legacy_path: str, legacy_class: str
204
+ ) -> Optional[str]:
205
+ """
206
+ Get unified service for a legacy service.
207
+
208
+ Args:
209
+ legacy_path: Legacy service module path
210
+ legacy_class: Legacy service class name
211
+
212
+ Returns:
213
+ Optional[str]: Unified service name if mapped
214
+ """
215
+ key = f"{legacy_path}.{legacy_class}"
216
+ mapping = self._mappings.get(key)
217
+ return mapping.unified_service if mapping else None
218
+
219
+ def update_status(
220
+ self, legacy_service: str, status: MigrationStatus
221
+ ) -> bool:
222
+ """
223
+ Update migration status for a service.
224
+
225
+ Args:
226
+ legacy_service: Legacy service identifier
227
+ status: New migration status
228
+
229
+ Returns:
230
+ bool: True if status updated
231
+ """
232
+ mapping = self._mappings.get(legacy_service)
233
+ if not mapping:
234
+ return False
235
+
236
+ old_status = mapping.status
237
+ mapping.status = status
238
+
239
+ # Update metrics
240
+ if old_status != status:
241
+ if status == MigrationStatus.COMPLETED:
242
+ self._metrics.migrated_services += 1
243
+ elif status == MigrationStatus.IN_PROGRESS:
244
+ self._metrics.in_progress += 1
245
+ elif status == MigrationStatus.DEPRECATED:
246
+ self._metrics.deprecated_services += 1
247
+ elif status == MigrationStatus.REMOVED:
248
+ self._metrics.removed_services += 1
249
+
250
+ self._logger.info(
251
+ f"Updated {legacy_service} status: {old_status} -> {status}"
252
+ )
253
+ return True
254
+
255
+ def set_feature_flag(self, flag: FeatureFlag, enabled: bool) -> None:
256
+ """
257
+ Set a feature flag value.
258
+
259
+ Args:
260
+ flag: Feature flag to set
261
+ enabled: Whether to enable the flag
262
+ """
263
+ self._feature_flags[flag] = enabled
264
+ self._logger.info(f"Feature flag {flag.value} set to {enabled}")
265
+
266
+ def is_feature_enabled(self, flag: FeatureFlag) -> bool:
267
+ """
268
+ Check if a feature flag is enabled.
269
+
270
+ Args:
271
+ flag: Feature flag to check
272
+
273
+ Returns:
274
+ bool: True if feature is enabled
275
+ """
276
+ return self._feature_flags.get(flag, False)
277
+
278
+ def get_metrics(self) -> MigrationMetrics:
279
+ """
280
+ Get migration metrics.
281
+
282
+ Returns:
283
+ MigrationMetrics: Current migration metrics
284
+ """
285
+ return self._metrics
286
+
287
+ def list_mappings(
288
+ self, status_filter: Optional[MigrationStatus] = None
289
+ ) -> List[ServiceMapping]:
290
+ """
291
+ List all service mappings.
292
+
293
+ Args:
294
+ status_filter: Optional filter by migration status
295
+
296
+ Returns:
297
+ List[ServiceMapping]: List of service mappings
298
+ """
299
+ mappings = list(self._mappings.values())
300
+
301
+ if status_filter:
302
+ mappings = [m for m in mappings if m.status == status_filter]
303
+
304
+ return mappings
305
+
306
+
307
+ def create_compatibility_wrapper(
308
+ legacy_class: Type[T],
309
+ unified_service: Any,
310
+ method_mappings: Optional[Dict[str, str]] = None,
311
+ ) -> Type[T]:
312
+ """
313
+ Create a compatibility wrapper for a legacy service.
314
+
315
+ This function dynamically creates a wrapper class that maintains the
316
+ legacy interface while delegating to the unified service implementation.
317
+
318
+ Args:
319
+ legacy_class: Legacy service class to wrap
320
+ unified_service: Unified service instance
321
+ method_mappings: Optional mapping of legacy to unified method names
322
+
323
+ Returns:
324
+ Type[T]: Wrapper class maintaining legacy interface
325
+ """
326
+ method_mappings = method_mappings or {}
327
+
328
+ class CompatibilityWrapper:
329
+ """
330
+ Dynamic compatibility wrapper for legacy services.
331
+
332
+ This wrapper maintains the legacy interface while delegating
333
+ operations to the unified service implementation.
334
+ """
335
+
336
+ def __init__(self, *args, **kwargs):
337
+ """Initialize wrapper with unified service."""
338
+ self._unified_service = unified_service
339
+ self._logger = get_logger(
340
+ f"{__name__}.{legacy_class.__name__}Wrapper"
341
+ )
342
+ self._logger.debug(
343
+ f"Created compatibility wrapper for {legacy_class.__name__}"
344
+ )
345
+
346
+ def __getattr__(self, name: str) -> Any:
347
+ """
348
+ Delegate attribute access to unified service.
349
+
350
+ Args:
351
+ name: Attribute name
352
+
353
+ Returns:
354
+ Any: Attribute value from unified service
355
+
356
+ Raises:
357
+ AttributeError: If attribute not found
358
+ """
359
+ # Check if method is mapped to a different name
360
+ unified_name = method_mappings.get(name, name)
361
+
362
+ # Try to get from unified service
363
+ if hasattr(self._unified_service, unified_name):
364
+ attr = getattr(self._unified_service, unified_name)
365
+
366
+ # Log deprecation warning if configured
367
+ if ServiceMapper().is_feature_enabled(
368
+ FeatureFlag.LOG_MIGRATION_WARNINGS
369
+ ):
370
+ self._logger.warning(
371
+ f"Using compatibility wrapper for {legacy_class.__name__}.{name}. "
372
+ f"Please migrate to unified service."
373
+ )
374
+
375
+ return attr
376
+
377
+ # Fallback to legacy implementation if allowed
378
+ if ServiceMapper().is_feature_enabled(
379
+ FeatureFlag.ALLOW_LEGACY_FALLBACK
380
+ ):
381
+ if hasattr(legacy_class, name):
382
+ self._logger.warning(
383
+ f"Falling back to legacy implementation for {name}"
384
+ )
385
+ return getattr(legacy_class, name)
386
+
387
+ raise AttributeError(
388
+ f"'{legacy_class.__name__}' wrapper has no attribute '{name}'"
389
+ )
390
+
391
+ # Copy class metadata
392
+ CompatibilityWrapper.__name__ = legacy_class.__name__
393
+ CompatibilityWrapper.__module__ = legacy_class.__module__
394
+ CompatibilityWrapper.__doc__ = (
395
+ f"Compatibility wrapper for {legacy_class.__name__}.\n\n"
396
+ f"This class maintains backward compatibility while delegating to "
397
+ f"the unified service implementation."
398
+ )
399
+
400
+ # Copy method signatures for better IDE support
401
+ for name, method in inspect.getmembers(legacy_class, inspect.isfunction):
402
+ if not name.startswith("_"):
403
+ setattr(CompatibilityWrapper, name, method)
404
+
405
+ return CompatibilityWrapper
406
+
407
+
408
+ class MigrationValidator:
409
+ """
410
+ Validates migration compatibility and correctness.
411
+
412
+ This class ensures that unified services properly implement
413
+ the functionality of the legacy services they replace.
414
+ """
415
+
416
+ def __init__(self):
417
+ """Initialize migration validator."""
418
+ self._logger = get_logger(f"{__name__}.MigrationValidator")
419
+
420
+ def validate_interface_compatibility(
421
+ self, legacy_class: Type, unified_class: Type
422
+ ) -> List[str]:
423
+ """
424
+ Validate that unified service implements legacy interface.
425
+
426
+ Args:
427
+ legacy_class: Legacy service class
428
+ unified_class: Unified service class
429
+
430
+ Returns:
431
+ List[str]: List of compatibility issues
432
+ """
433
+ issues = []
434
+
435
+ # Get public methods from legacy class
436
+ legacy_methods = {
437
+ name for name, _ in inspect.getmembers(
438
+ legacy_class, inspect.ismethod
439
+ )
440
+ if not name.startswith("_")
441
+ }
442
+
443
+ # Get public methods from unified class
444
+ unified_methods = {
445
+ name for name, _ in inspect.getmembers(
446
+ unified_class, inspect.ismethod
447
+ )
448
+ if not name.startswith("_")
449
+ }
450
+
451
+ # Check for missing methods
452
+ missing = legacy_methods - unified_methods
453
+ if missing:
454
+ issues.append(
455
+ f"Missing methods in unified service: {', '.join(missing)}"
456
+ )
457
+
458
+ # Check method signatures
459
+ for method_name in legacy_methods & unified_methods:
460
+ legacy_sig = inspect.signature(getattr(legacy_class, method_name))
461
+ unified_sig = inspect.signature(getattr(unified_class, method_name))
462
+
463
+ if legacy_sig != unified_sig:
464
+ issues.append(
465
+ f"Method signature mismatch for {method_name}: "
466
+ f"legacy={legacy_sig}, unified={unified_sig}"
467
+ )
468
+
469
+ return issues
470
+
471
+ def validate_behavior_compatibility(
472
+ self,
473
+ legacy_instance: Any,
474
+ unified_instance: Any,
475
+ test_cases: List[Dict[str, Any]],
476
+ ) -> List[str]:
477
+ """
478
+ Validate that unified service behavior matches legacy.
479
+
480
+ Args:
481
+ legacy_instance: Legacy service instance
482
+ unified_instance: Unified service instance
483
+ test_cases: List of test cases with method, args, kwargs
484
+
485
+ Returns:
486
+ List[str]: List of behavior differences
487
+ """
488
+ differences = []
489
+
490
+ for test_case in test_cases:
491
+ method_name = test_case["method"]
492
+ args = test_case.get("args", ())
493
+ kwargs = test_case.get("kwargs", {})
494
+
495
+ try:
496
+ # Execute on legacy service
497
+ legacy_result = getattr(legacy_instance, method_name)(
498
+ *args, **kwargs
499
+ )
500
+
501
+ # Execute on unified service
502
+ unified_result = getattr(unified_instance, method_name)(
503
+ *args, **kwargs
504
+ )
505
+
506
+ # Compare results
507
+ if legacy_result != unified_result:
508
+ differences.append(
509
+ f"Different results for {method_name}: "
510
+ f"legacy={legacy_result}, unified={unified_result}"
511
+ )
512
+
513
+ except Exception as e:
514
+ differences.append(
515
+ f"Error testing {method_name}: {str(e)}"
516
+ )
517
+
518
+ return differences
519
+
520
+
521
+ # Global service mapper instance
522
+ _global_mapper = ServiceMapper()
523
+
524
+
525
+ def get_service_mapper() -> ServiceMapper:
526
+ """
527
+ Get the global service mapper instance.
528
+
529
+ Returns:
530
+ ServiceMapper: Global mapper instance
531
+ """
532
+ return _global_mapper