claude-mpm 4.4.0__py3-none-any.whl → 4.4.4__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 (129) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/WORKFLOW.md +2 -14
  3. claude_mpm/agents/agent_loader.py +3 -2
  4. claude_mpm/agents/agent_loader_integration.py +2 -1
  5. claude_mpm/agents/async_agent_loader.py +2 -2
  6. claude_mpm/agents/base_agent_loader.py +2 -2
  7. claude_mpm/agents/frontmatter_validator.py +1 -0
  8. claude_mpm/agents/system_agent_config.py +2 -1
  9. claude_mpm/cli/commands/configure.py +2 -29
  10. claude_mpm/cli/commands/doctor.py +44 -5
  11. claude_mpm/cli/commands/mpm_init.py +117 -63
  12. claude_mpm/cli/parsers/configure_parser.py +6 -15
  13. claude_mpm/cli/startup_logging.py +1 -3
  14. claude_mpm/config/agent_config.py +1 -1
  15. claude_mpm/config/paths.py +2 -1
  16. claude_mpm/core/agent_name_normalizer.py +1 -0
  17. claude_mpm/core/config.py +2 -1
  18. claude_mpm/core/config_aliases.py +2 -1
  19. claude_mpm/core/file_utils.py +0 -1
  20. claude_mpm/core/framework/__init__.py +38 -0
  21. claude_mpm/core/framework/formatters/__init__.py +11 -0
  22. claude_mpm/core/framework/formatters/capability_generator.py +367 -0
  23. claude_mpm/core/framework/formatters/content_formatter.py +288 -0
  24. claude_mpm/core/framework/formatters/context_generator.py +184 -0
  25. claude_mpm/core/framework/loaders/__init__.py +13 -0
  26. claude_mpm/core/framework/loaders/agent_loader.py +206 -0
  27. claude_mpm/core/framework/loaders/file_loader.py +223 -0
  28. claude_mpm/core/framework/loaders/instruction_loader.py +161 -0
  29. claude_mpm/core/framework/loaders/packaged_loader.py +232 -0
  30. claude_mpm/core/framework/processors/__init__.py +11 -0
  31. claude_mpm/core/framework/processors/memory_processor.py +230 -0
  32. claude_mpm/core/framework/processors/metadata_processor.py +146 -0
  33. claude_mpm/core/framework/processors/template_processor.py +244 -0
  34. claude_mpm/core/framework_loader.py +298 -1795
  35. claude_mpm/core/log_manager.py +2 -1
  36. claude_mpm/core/tool_access_control.py +1 -0
  37. claude_mpm/core/unified_agent_registry.py +2 -1
  38. claude_mpm/core/unified_paths.py +1 -0
  39. claude_mpm/experimental/cli_enhancements.py +1 -0
  40. claude_mpm/hooks/__init__.py +9 -1
  41. claude_mpm/hooks/base_hook.py +1 -0
  42. claude_mpm/hooks/instruction_reinforcement.py +1 -0
  43. claude_mpm/hooks/kuzu_memory_hook.py +359 -0
  44. claude_mpm/hooks/validation_hooks.py +1 -1
  45. claude_mpm/scripts/mpm_doctor.py +1 -0
  46. claude_mpm/services/agents/loading/agent_profile_loader.py +1 -1
  47. claude_mpm/services/agents/loading/base_agent_manager.py +1 -1
  48. claude_mpm/services/agents/loading/framework_agent_loader.py +1 -1
  49. claude_mpm/services/agents/management/agent_capabilities_generator.py +1 -0
  50. claude_mpm/services/agents/management/agent_management_service.py +1 -1
  51. claude_mpm/services/agents/memory/memory_categorization_service.py +0 -1
  52. claude_mpm/services/agents/memory/memory_file_service.py +6 -2
  53. claude_mpm/services/agents/memory/memory_format_service.py +0 -1
  54. claude_mpm/services/agents/registry/deployed_agent_discovery.py +1 -1
  55. claude_mpm/services/async_session_logger.py +1 -1
  56. claude_mpm/services/claude_session_logger.py +1 -0
  57. claude_mpm/services/core/path_resolver.py +2 -0
  58. claude_mpm/services/diagnostics/checks/__init__.py +2 -0
  59. claude_mpm/services/diagnostics/checks/installation_check.py +126 -25
  60. claude_mpm/services/diagnostics/checks/mcp_services_check.py +399 -0
  61. claude_mpm/services/diagnostics/diagnostic_runner.py +4 -0
  62. claude_mpm/services/diagnostics/doctor_reporter.py +259 -32
  63. claude_mpm/services/event_bus/direct_relay.py +2 -1
  64. claude_mpm/services/event_bus/event_bus.py +1 -0
  65. claude_mpm/services/event_bus/relay.py +3 -2
  66. claude_mpm/services/framework_claude_md_generator/content_assembler.py +1 -1
  67. claude_mpm/services/infrastructure/daemon_manager.py +1 -1
  68. claude_mpm/services/mcp_config_manager.py +67 -4
  69. claude_mpm/services/mcp_gateway/core/process_pool.py +320 -0
  70. claude_mpm/services/mcp_gateway/core/startup_verification.py +2 -2
  71. claude_mpm/services/mcp_gateway/main.py +3 -13
  72. claude_mpm/services/mcp_gateway/server/stdio_server.py +4 -10
  73. claude_mpm/services/mcp_gateway/tools/__init__.py +14 -2
  74. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +38 -6
  75. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +527 -0
  76. claude_mpm/services/memory/cache/simple_cache.py +1 -1
  77. claude_mpm/services/project/archive_manager.py +159 -96
  78. claude_mpm/services/project/documentation_manager.py +64 -45
  79. claude_mpm/services/project/enhanced_analyzer.py +132 -89
  80. claude_mpm/services/project/project_organizer.py +225 -131
  81. claude_mpm/services/response_tracker.py +1 -1
  82. claude_mpm/services/shared/__init__.py +2 -1
  83. claude_mpm/services/shared/service_factory.py +8 -5
  84. claude_mpm/services/socketio/server/eventbus_integration.py +1 -1
  85. claude_mpm/services/unified/__init__.py +1 -1
  86. claude_mpm/services/unified/analyzer_strategies/__init__.py +3 -3
  87. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +97 -53
  88. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +81 -40
  89. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +277 -178
  90. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +196 -112
  91. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +83 -49
  92. claude_mpm/services/unified/config_strategies/__init__.py +175 -0
  93. claude_mpm/services/unified/config_strategies/config_schema.py +735 -0
  94. claude_mpm/services/unified/config_strategies/context_strategy.py +750 -0
  95. claude_mpm/services/unified/config_strategies/error_handling_strategy.py +1009 -0
  96. claude_mpm/services/unified/config_strategies/file_loader_strategy.py +879 -0
  97. claude_mpm/services/unified/config_strategies/unified_config_service.py +814 -0
  98. claude_mpm/services/unified/config_strategies/validation_strategy.py +1144 -0
  99. claude_mpm/services/unified/deployment_strategies/__init__.py +7 -7
  100. claude_mpm/services/unified/deployment_strategies/base.py +24 -28
  101. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +168 -88
  102. claude_mpm/services/unified/deployment_strategies/local.py +49 -34
  103. claude_mpm/services/unified/deployment_strategies/utils.py +39 -43
  104. claude_mpm/services/unified/deployment_strategies/vercel.py +30 -24
  105. claude_mpm/services/unified/interfaces.py +0 -26
  106. claude_mpm/services/unified/migration.py +17 -40
  107. claude_mpm/services/unified/strategies.py +9 -26
  108. claude_mpm/services/unified/unified_analyzer.py +48 -44
  109. claude_mpm/services/unified/unified_config.py +21 -19
  110. claude_mpm/services/unified/unified_deployment.py +21 -26
  111. claude_mpm/storage/state_storage.py +1 -0
  112. claude_mpm/utils/agent_dependency_loader.py +18 -6
  113. claude_mpm/utils/common.py +14 -12
  114. claude_mpm/utils/database_connector.py +15 -12
  115. claude_mpm/utils/error_handler.py +1 -0
  116. claude_mpm/utils/log_cleanup.py +1 -0
  117. claude_mpm/utils/path_operations.py +1 -0
  118. claude_mpm/utils/session_logging.py +1 -1
  119. claude_mpm/utils/subprocess_utils.py +1 -0
  120. claude_mpm/validation/agent_validator.py +1 -1
  121. {claude_mpm-4.4.0.dist-info → claude_mpm-4.4.4.dist-info}/METADATA +23 -17
  122. {claude_mpm-4.4.0.dist-info → claude_mpm-4.4.4.dist-info}/RECORD +126 -105
  123. claude_mpm/cli/commands/configure_tui.py +0 -1927
  124. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +0 -645
  125. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +0 -602
  126. {claude_mpm-4.4.0.dist-info → claude_mpm-4.4.4.dist-info}/WHEEL +0 -0
  127. {claude_mpm-4.4.0.dist-info → claude_mpm-4.4.4.dist-info}/entry_points.txt +0 -0
  128. {claude_mpm-4.4.0.dist-info → claude_mpm-4.4.4.dist-info}/licenses/LICENSE +0 -0
  129. {claude_mpm-4.4.0.dist-info → claude_mpm-4.4.4.dist-info}/top_level.txt +0 -0
@@ -23,10 +23,11 @@ from queue import Full, Queue
23
23
  from threading import Lock, Thread
24
24
  from typing import Any, Dict, Optional
25
25
 
26
+ from claude_mpm.core.logging_utils import get_logger
27
+
26
28
  from ..core.config import Config
27
29
  from ..core.constants import SystemLimits
28
30
 
29
- from claude_mpm.core.logging_utils import get_logger
30
31
  logger = get_logger(__name__)
31
32
 
32
33
  # Import cleanup utility for automatic cleanup
@@ -3,6 +3,7 @@
3
3
  from typing import Dict, List, Set
4
4
 
5
5
  from claude_mpm.core.logging_utils import get_logger
6
+
6
7
  logger = get_logger(__name__)
7
8
 
8
9
 
@@ -34,9 +34,10 @@ from enum import Enum
34
34
  from pathlib import Path
35
35
  from typing import Any, Dict, List, Optional, Set, Union
36
36
 
37
+ from claude_mpm.core.logging_utils import get_logger
38
+
37
39
  from .unified_paths import get_path_manager
38
40
 
39
- from claude_mpm.core.logging_utils import get_logger
40
41
  logger = get_logger(__name__)
41
42
 
42
43
 
@@ -32,6 +32,7 @@ from pathlib import Path
32
32
  from typing import Optional, Union
33
33
 
34
34
  from claude_mpm.core.logging_utils import get_logger
35
+
35
36
  logger = get_logger(__name__)
36
37
 
37
38
 
@@ -54,6 +54,7 @@ class CLIContext:
54
54
  def setup_logging(self, debug: bool = False) -> None:
55
55
  """Setup logging based on debug flag."""
56
56
  import logging
57
+
57
58
  level = logging.DEBUG if debug else logging.INFO
58
59
  format_str = (
59
60
  "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
@@ -1,5 +1,13 @@
1
1
  """Hook system for claude-mpm."""
2
2
 
3
3
  from .base_hook import BaseHook, HookContext, HookResult, HookType
4
+ from .kuzu_memory_hook import KuzuMemoryHook, get_kuzu_memory_hook
4
5
 
5
- __all__ = ["BaseHook", "HookContext", "HookResult", "HookType"]
6
+ __all__ = [
7
+ "BaseHook",
8
+ "HookContext",
9
+ "HookResult",
10
+ "HookType",
11
+ "KuzuMemoryHook",
12
+ "get_kuzu_memory_hook",
13
+ ]
@@ -8,6 +8,7 @@ from enum import Enum
8
8
  from typing import Any, Dict, Optional
9
9
 
10
10
  from claude_mpm.core.logging_utils import get_logger
11
+
11
12
  logger = get_logger(__name__)
12
13
 
13
14
 
@@ -11,6 +11,7 @@ from enum import Enum
11
11
  from typing import Dict, List, Optional, Tuple
12
12
 
13
13
  from claude_mpm.core.logging_utils import get_logger
14
+
14
15
  logger = get_logger(__name__)
15
16
 
16
17
 
@@ -0,0 +1,359 @@
1
+ """
2
+ Kuzu-Memory Integration Hook
3
+ ============================
4
+
5
+ Integrates kuzu-memory knowledge graph with Claude MPM for persistent memory
6
+ across conversations. This hook intercepts user prompts to enrich them with
7
+ relevant memories and stores new learnings after responses.
8
+
9
+ WHY: Claude MPM needs a way to persistently remember information across
10
+ different conversations and sessions. Kuzu-memory provides a graph database
11
+ for structured memory storage with semantic search capabilities.
12
+
13
+ DESIGN DECISIONS:
14
+ - Priority 10 for early execution to enrich prompts before other hooks
15
+ - Uses subprocess to call kuzu-memory directly for maximum compatibility
16
+ - Graceful degradation if kuzu-memory is not installed
17
+ - Automatic extraction and storage of important information
18
+ """
19
+
20
+ import json
21
+ import re
22
+ import shutil
23
+ import subprocess
24
+ from pathlib import Path
25
+ from typing import Any, Dict, List, Optional
26
+
27
+ from claude_mpm.core.logging_utils import get_logger
28
+ from claude_mpm.hooks.base_hook import HookContext, HookResult, SubmitHook
29
+
30
+ logger = get_logger(__name__)
31
+
32
+
33
+ class KuzuMemoryHook(SubmitHook):
34
+ """
35
+ Hook that integrates kuzu-memory for persistent knowledge management.
36
+
37
+ This hook:
38
+ 1. Checks if kuzu-memory is installed via pipx
39
+ 2. Enriches user prompts with relevant memories
40
+ 3. Stores important information from conversations
41
+ 4. Provides context-aware memory retrieval
42
+ """
43
+
44
+ def __init__(self):
45
+ """Initialize the kuzu-memory integration hook."""
46
+ super().__init__(name="kuzu_memory_integration", priority=10)
47
+
48
+ # Check if kuzu-memory is available
49
+ self.kuzu_memory_cmd = self._detect_kuzu_memory()
50
+ self.enabled = self.kuzu_memory_cmd is not None
51
+
52
+ if not self.enabled:
53
+ logger.info("Kuzu-memory not found. Install with: pipx install kuzu-memory")
54
+ else:
55
+ logger.info(f"Kuzu-memory integration enabled: {self.kuzu_memory_cmd}")
56
+
57
+ # Use current project directory (kuzu-memory works with project-specific databases)
58
+ self.project_path = Path.cwd()
59
+
60
+ # Memory extraction patterns
61
+ self.memory_patterns = [
62
+ r"#\s*(?:Remember|Memorize|Store):\s*(.+?)(?:#|$)",
63
+ r"(?:Important|Note|Key point):\s*(.+?)(?:\n|$)",
64
+ r"(?:Learned|Discovered|Found that):\s*(.+?)(?:\n|$)",
65
+ ]
66
+
67
+ def _detect_kuzu_memory(self) -> Optional[str]:
68
+ """
69
+ Detect if kuzu-memory is installed and return its command path.
70
+
71
+ Priority:
72
+ 1. Check pipx installation
73
+ 2. Check system PATH
74
+ 3. Return None if not found
75
+ """
76
+ # Check pipx installation
77
+ pipx_path = (
78
+ Path.home()
79
+ / ".local"
80
+ / "pipx"
81
+ / "venvs"
82
+ / "kuzu-memory"
83
+ / "bin"
84
+ / "kuzu-memory"
85
+ )
86
+ if pipx_path.exists():
87
+ return str(pipx_path)
88
+
89
+ # Check system PATH
90
+ kuzu_cmd = shutil.which("kuzu-memory")
91
+ if kuzu_cmd:
92
+ return kuzu_cmd
93
+
94
+ return None
95
+
96
+ def execute(self, context: HookContext) -> HookResult:
97
+ """
98
+ Process user prompts with kuzu-memory integration.
99
+
100
+ This method:
101
+ 1. Retrieves relevant memories for the prompt
102
+ 2. Enriches the prompt with memory context
103
+ 3. Stores new memories after processing
104
+ """
105
+ if not self.enabled:
106
+ return HookResult(success=True, data=context.data, modified=False)
107
+
108
+ try:
109
+ # Extract user prompt
110
+ prompt = context.data.get("prompt", "")
111
+ if not prompt:
112
+ return HookResult(success=True, data=context.data, modified=False)
113
+
114
+ # Retrieve relevant memories
115
+ memories = self._retrieve_memories(prompt)
116
+
117
+ if memories:
118
+ # Enrich prompt with memories
119
+ enriched_data = self._enrich_prompt(context.data, prompt, memories)
120
+
121
+ logger.info(f"Enriched prompt with {len(memories)} memories")
122
+
123
+ # Store the original prompt for later processing
124
+ enriched_data["_original_prompt"] = prompt
125
+ enriched_data["_memory_enriched"] = True
126
+
127
+ return HookResult(
128
+ success=True,
129
+ data=enriched_data,
130
+ modified=True,
131
+ metadata={
132
+ "memories_added": len(memories),
133
+ "memory_source": "kuzu",
134
+ },
135
+ )
136
+
137
+ return HookResult(success=True, data=context.data, modified=False)
138
+
139
+ except Exception as e:
140
+ logger.error(f"Kuzu-memory hook failed: {e}")
141
+ # Don't fail the request if memory integration fails
142
+ return HookResult(
143
+ success=True,
144
+ data=context.data,
145
+ modified=False,
146
+ error=f"Memory integration failed: {e}",
147
+ )
148
+
149
+ def _retrieve_memories(self, query: str) -> List[Dict[str, Any]]:
150
+ """
151
+ Retrieve relevant memories for the given query.
152
+
153
+ Args:
154
+ query: The user prompt to find memories for
155
+
156
+ Returns:
157
+ List of relevant memory dictionaries
158
+ """
159
+ try:
160
+ # Use kuzu-memory recall command
161
+ result = subprocess.run(
162
+ [self.kuzu_memory_cmd, "recall", query, "--format", "json"],
163
+ capture_output=True,
164
+ text=True,
165
+ timeout=5,
166
+ cwd=str(self.project_path), check=False,
167
+ )
168
+
169
+ if result.returncode == 0 and result.stdout:
170
+ memories = json.loads(result.stdout)
171
+ return memories if isinstance(memories, list) else []
172
+
173
+ except (subprocess.TimeoutExpired, json.JSONDecodeError, Exception) as e:
174
+ logger.debug(f"Memory retrieval failed: {e}")
175
+
176
+ return []
177
+
178
+ def _enrich_prompt(
179
+ self, original_data: Dict[str, Any], prompt: str, memories: List[Dict[str, Any]]
180
+ ) -> Dict[str, Any]:
181
+ """
182
+ Enrich the user prompt with relevant memories.
183
+
184
+ Args:
185
+ original_data: Original hook context data
186
+ prompt: User prompt
187
+ memories: Retrieved memories
188
+
189
+ Returns:
190
+ Enriched context data
191
+ """
192
+ # Format memories for context
193
+ memory_context = self._format_memories(memories)
194
+
195
+ # Create enriched prompt
196
+ enriched_prompt = f"""
197
+ ## RELEVANT MEMORIES FROM KUZU KNOWLEDGE GRAPH
198
+
199
+ {memory_context}
200
+
201
+ ## USER REQUEST
202
+
203
+ {prompt}
204
+
205
+ Note: Use the memories above to provide more informed and contextual responses.
206
+ """
207
+
208
+ # Create new data with enriched prompt
209
+ enriched_data = original_data.copy()
210
+ enriched_data["prompt"] = enriched_prompt
211
+
212
+ return enriched_data
213
+
214
+ def _format_memories(self, memories: List[Dict[str, Any]]) -> str:
215
+ """
216
+ Format memories into a readable context string.
217
+
218
+ Args:
219
+ memories: List of memory dictionaries
220
+
221
+ Returns:
222
+ Formatted memory context
223
+ """
224
+ if not memories:
225
+ return "No relevant memories found."
226
+
227
+ formatted = []
228
+ for i, memory in enumerate(memories, 1):
229
+ # Extract memory content and metadata
230
+ content = memory.get("content", "")
231
+ tags = memory.get("tags", [])
232
+ timestamp = memory.get("timestamp", "")
233
+ relevance = memory.get("relevance", 0.0)
234
+
235
+ # Format memory entry
236
+ entry = f"{i}. {content}"
237
+ if tags:
238
+ entry += f" [Tags: {', '.join(tags)}]"
239
+ if relevance > 0:
240
+ entry += f" (Relevance: {relevance:.2f})"
241
+
242
+ formatted.append(entry)
243
+
244
+ return "\n".join(formatted)
245
+
246
+ def store_memory(self, content: str, tags: Optional[List[str]] = None) -> bool:
247
+ """
248
+ Store a memory using kuzu-memory.
249
+
250
+ Args:
251
+ content: The memory content to store
252
+ tags: Optional tags for categorization
253
+
254
+ Returns:
255
+ True if storage was successful
256
+ """
257
+ if not self.enabled:
258
+ return False
259
+
260
+ try:
261
+ # Use kuzu-memory remember command (synchronous)
262
+ cmd = [self.kuzu_memory_cmd, "remember", content]
263
+
264
+ # Execute store command in project directory
265
+ result = subprocess.run(
266
+ cmd,
267
+ capture_output=True,
268
+ text=True,
269
+ timeout=5,
270
+ cwd=str(self.project_path), check=False,
271
+ )
272
+
273
+ if result.returncode == 0:
274
+ logger.debug(f"Stored memory: {content[:50]}...")
275
+ return True
276
+
277
+ except Exception as e:
278
+ logger.error(f"Failed to store memory: {e}")
279
+
280
+ return False
281
+
282
+ def extract_and_store_learnings(self, text: str) -> int:
283
+ """
284
+ Extract learnings from text and store them as memories.
285
+
286
+ Args:
287
+ text: Text to extract learnings from
288
+
289
+ Returns:
290
+ Number of learnings stored
291
+ """
292
+ if not self.enabled:
293
+ return 0
294
+
295
+ stored_count = 0
296
+
297
+ # Extract learnings using patterns
298
+ for pattern in self.memory_patterns:
299
+ matches = re.finditer(pattern, text, re.IGNORECASE | re.MULTILINE)
300
+ for match in matches:
301
+ learning = match.group(1).strip()
302
+ if learning and len(learning) > 10: # Minimum length check
303
+ # Determine tags based on content
304
+ tags = self._infer_tags(learning)
305
+
306
+ # Store the learning
307
+ if self.store_memory(learning, tags):
308
+ stored_count += 1
309
+
310
+ return stored_count
311
+
312
+ def _infer_tags(self, content: str) -> List[str]:
313
+ """
314
+ Infer tags based on memory content.
315
+
316
+ Args:
317
+ content: Memory content
318
+
319
+ Returns:
320
+ List of inferred tags
321
+ """
322
+ tags = []
323
+ content_lower = content.lower()
324
+
325
+ # Technical tags
326
+ if any(
327
+ word in content_lower for word in ["code", "function", "class", "module"]
328
+ ):
329
+ tags.append("technical")
330
+ if any(word in content_lower for word in ["bug", "error", "fix", "issue"]):
331
+ tags.append("debugging")
332
+ if any(word in content_lower for word in ["pattern", "architecture", "design"]):
333
+ tags.append("architecture")
334
+ if any(word in content_lower for word in ["performance", "optimize", "speed"]):
335
+ tags.append("performance")
336
+
337
+ # Project context tags
338
+ if "claude-mpm" in content_lower or "mpm" in content_lower:
339
+ tags.append("claude-mpm")
340
+ if any(word in content_lower for word in ["hook", "agent", "service"]):
341
+ tags.append("framework")
342
+
343
+ # Default tag if no others found
344
+ if not tags:
345
+ tags.append("general")
346
+
347
+ return tags
348
+
349
+
350
+ # Create a singleton instance
351
+ _kuzu_memory_hook = None
352
+
353
+
354
+ def get_kuzu_memory_hook() -> KuzuMemoryHook:
355
+ """Get the singleton kuzu-memory hook instance."""
356
+ global _kuzu_memory_hook
357
+ if _kuzu_memory_hook is None:
358
+ _kuzu_memory_hook = KuzuMemoryHook()
359
+ return _kuzu_memory_hook
@@ -10,9 +10,9 @@ from typing import Any, Callable, Dict, List, Optional
10
10
 
11
11
  import yaml
12
12
 
13
+ from claude_mpm.core.logging_utils import get_logger
13
14
  from claude_mpm.validation import AgentValidator, ValidationResult
14
15
 
15
- from claude_mpm.core.logging_utils import get_logger
16
16
  logger = get_logger(__name__)
17
17
 
18
18
 
@@ -52,6 +52,7 @@ def run_diagnostics(
52
52
  - message: str - optional error message if failed
53
53
  """
54
54
  from claude_mpm.core.logging_utils import get_logger
55
+
55
56
  logger = get_logger(__name__)
56
57
 
57
58
  # Create diagnostic runner
@@ -32,11 +32,11 @@ import yaml
32
32
 
33
33
  from claude_mpm.core.base_service import BaseService
34
34
  from claude_mpm.core.config import Config
35
+ from claude_mpm.core.logging_utils import get_logger
35
36
  from claude_mpm.core.unified_paths import get_path_manager
36
37
  from claude_mpm.services.agents.registry import AgentRegistry
37
38
  from claude_mpm.services.memory.cache.shared_prompt_cache import SharedPromptCache
38
39
 
39
- from claude_mpm.core.logging_utils import get_logger
40
40
  logger = get_logger(__name__)
41
41
 
42
42
  # ============================================================================
@@ -14,10 +14,10 @@ from pathlib import Path
14
14
  from typing import Any, Dict, List, Optional
15
15
 
16
16
  from claude_mpm.agents.base_agent_loader import clear_base_agent_cache
17
+ from claude_mpm.core.logging_utils import get_logger
17
18
  from claude_mpm.services.memory.cache.shared_prompt_cache import SharedPromptCache
18
19
  from claude_mpm.services.shared import ConfigServiceBase
19
20
 
20
- from claude_mpm.core.logging_utils import get_logger
21
21
  logger = get_logger(__name__)
22
22
 
23
23
 
@@ -19,9 +19,9 @@ from claude_mpm.agents.agent_loader import (
19
19
  AgentTier,
20
20
  list_agents_by_tier,
21
21
  )
22
+ from claude_mpm.core.logging_utils import get_logger
22
23
  from claude_mpm.core.unified_paths import get_path_manager
23
24
 
24
- from claude_mpm.core.logging_utils import get_logger
25
25
  logger = get_logger(__name__)
26
26
 
27
27
 
@@ -9,6 +9,7 @@ from typing import Any, Dict, List
9
9
  from jinja2 import Template
10
10
 
11
11
  from claude_mpm.core.logging_utils import get_logger
12
+
12
13
  logger = get_logger(__name__)
13
14
 
14
15
 
@@ -19,6 +19,7 @@ import frontmatter
19
19
  import mistune
20
20
  import yaml
21
21
 
22
+ from claude_mpm.core.logging_utils import get_logger
22
23
  from claude_mpm.core.unified_paths import get_path_manager
23
24
  from claude_mpm.models.agent_definition import (
24
25
  AgentDefinition,
@@ -32,7 +33,6 @@ from claude_mpm.services.memory.cache.shared_prompt_cache import SharedPromptCac
32
33
 
33
34
  from ..deployment.agent_versioning import AgentVersionManager
34
35
 
35
- from claude_mpm.core.logging_utils import get_logger
36
36
  logger = get_logger(__name__)
37
37
 
38
38
 
@@ -85,7 +85,6 @@ class MemoryCategorizationService:
85
85
 
86
86
  def __init__(self):
87
87
  """Initialize the categorization service."""
88
- pass
89
88
 
90
89
  def categorize_learning(self, learning: str) -> str:
91
90
  """Categorize a learning item based on its content.
@@ -41,14 +41,18 @@ class MemoryFileService:
41
41
  old_file = directory / f"{normalized_id}_memory.md"
42
42
 
43
43
  # Also check for legacy hyphenated versions
44
- hyphenated_file = directory / f"{agent_id}_memories.md" if "-" in agent_id else None
44
+ hyphenated_file = (
45
+ directory / f"{agent_id}_memories.md" if "-" in agent_id else None
46
+ )
45
47
 
46
48
  # Migration priority:
47
49
  # 1. If hyphenated version exists and normalized doesn't, migrate it
48
50
  if hyphenated_file and hyphenated_file.exists() and not new_file.exists():
49
51
  try:
50
52
  hyphenated_file.rename(new_file)
51
- self.logger.info(f"Migrated hyphenated memory file: {hyphenated_file} -> {new_file}")
53
+ self.logger.info(
54
+ f"Migrated hyphenated memory file: {hyphenated_file} -> {new_file}"
55
+ )
52
56
  except Exception as e:
53
57
  self.logger.warning(f"Could not migrate hyphenated memory file: {e}")
54
58
  # Fall back to using the hyphenated version
@@ -15,7 +15,6 @@ class MemoryFormatService:
15
15
 
16
16
  def __init__(self):
17
17
  """Initialize the memory format service."""
18
- pass
19
18
 
20
19
  def build_simple_memory_content(self, agent_id: str, items: List[str]) -> str:
21
20
  """Build memory content as a simple list with header and timestamp.
@@ -9,10 +9,10 @@ from pathlib import Path
9
9
  from typing import Any, Dict, List, Optional
10
10
 
11
11
  from claude_mpm.core.agent_registry import AgentRegistryAdapter
12
+ from claude_mpm.core.logging_utils import get_logger
12
13
  from claude_mpm.core.unified_paths import get_path_manager
13
14
  from claude_mpm.services.shared import ConfigServiceBase
14
15
 
15
- from claude_mpm.core.logging_utils import get_logger
16
16
  logger = get_logger(__name__)
17
17
 
18
18
 
@@ -29,11 +29,11 @@ from threading import Lock, Thread
29
29
  from typing import Any, Dict, Optional
30
30
 
31
31
  from claude_mpm.core.constants import PerformanceConfig, SystemLimits, TimeoutConfig
32
+ from claude_mpm.core.logging_utils import get_logger
32
33
 
33
34
  # Import configuration manager
34
35
  from ..core.config import Config
35
36
 
36
- from claude_mpm.core.logging_utils import get_logger
37
37
  logger = get_logger(__name__)
38
38
 
39
39
 
@@ -31,6 +31,7 @@ except ImportError:
31
31
  ASYNC_AVAILABLE = False
32
32
 
33
33
  from claude_mpm.core.logging_utils import get_logger
34
+
34
35
  logger = get_logger(__name__)
35
36
 
36
37
 
@@ -19,6 +19,7 @@ from pathlib import Path
19
19
  from typing import Dict, Optional, Tuple
20
20
 
21
21
  from claude_mpm.core.logging_utils import get_logger
22
+
22
23
  from .service_interfaces import ICacheManager, IPathResolver
23
24
 
24
25
  logger = get_logger(__name__)
@@ -50,6 +51,7 @@ class PathResolver(IPathResolver):
50
51
  Args:
51
52
  cache_manager: Optional cache manager for caching resolved paths
52
53
  """
54
+ self.logger = get_logger("path_resolver")
53
55
  self.cache_manager = cache_manager
54
56
  self._framework_path: Optional[Path] = None
55
57
  self._deployment_context: Optional[DeploymentContext] = None
@@ -14,6 +14,7 @@ from .filesystem_check import FilesystemCheck
14
14
  from .installation_check import InstallationCheck
15
15
  from .instructions_check import InstructionsCheck
16
16
  from .mcp_check import MCPCheck
17
+ from .mcp_services_check import MCPServicesCheck
17
18
  from .monitor_check import MonitorCheck
18
19
  from .startup_log_check import StartupLogCheck
19
20
 
@@ -27,6 +28,7 @@ __all__ = [
27
28
  "InstallationCheck",
28
29
  "InstructionsCheck",
29
30
  "MCPCheck",
31
+ "MCPServicesCheck",
30
32
  "MonitorCheck",
31
33
  "StartupLogCheck",
32
34
  ]