claude-mpm 4.14.6__py3-none-any.whl → 4.14.8__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 (79) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/frontmatter_validator.py +284 -253
  3. claude_mpm/cli/__init__.py +34 -740
  4. claude_mpm/cli/commands/agent_manager.py +25 -12
  5. claude_mpm/cli/commands/agent_state_manager.py +186 -0
  6. claude_mpm/cli/commands/agents.py +204 -148
  7. claude_mpm/cli/commands/aggregate.py +7 -3
  8. claude_mpm/cli/commands/analyze.py +9 -4
  9. claude_mpm/cli/commands/analyze_code.py +7 -2
  10. claude_mpm/cli/commands/config.py +47 -13
  11. claude_mpm/cli/commands/configure.py +159 -1801
  12. claude_mpm/cli/commands/configure_agent_display.py +261 -0
  13. claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
  14. claude_mpm/cli/commands/configure_hook_manager.py +225 -0
  15. claude_mpm/cli/commands/configure_models.py +18 -0
  16. claude_mpm/cli/commands/configure_navigation.py +165 -0
  17. claude_mpm/cli/commands/configure_paths.py +104 -0
  18. claude_mpm/cli/commands/configure_persistence.py +254 -0
  19. claude_mpm/cli/commands/configure_startup_manager.py +646 -0
  20. claude_mpm/cli/commands/configure_template_editor.py +497 -0
  21. claude_mpm/cli/commands/configure_validators.py +73 -0
  22. claude_mpm/cli/commands/memory.py +54 -20
  23. claude_mpm/cli/commands/mpm_init.py +35 -21
  24. claude_mpm/cli/executor.py +202 -0
  25. claude_mpm/cli/helpers.py +105 -0
  26. claude_mpm/cli/shared/output_formatters.py +28 -19
  27. claude_mpm/cli/startup.py +455 -0
  28. claude_mpm/core/enums.py +322 -0
  29. claude_mpm/core/instruction_reinforcement_hook.py +2 -1
  30. claude_mpm/core/interactive_session.py +6 -3
  31. claude_mpm/core/logging_config.py +6 -2
  32. claude_mpm/core/oneshot_session.py +8 -4
  33. claude_mpm/core/output_style_manager.py +12 -192
  34. claude_mpm/core/service_registry.py +5 -1
  35. claude_mpm/core/typing_utils.py +7 -6
  36. claude_mpm/hooks/instruction_reinforcement.py +7 -2
  37. claude_mpm/services/agents/deployment/interface_adapter.py +3 -2
  38. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +3 -2
  39. claude_mpm/services/agents/memory/agent_memory_manager.py +5 -2
  40. claude_mpm/services/diagnostics/checks/installation_check.py +3 -2
  41. claude_mpm/services/diagnostics/checks/mcp_check.py +20 -6
  42. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +8 -7
  43. claude_mpm/services/memory_hook_service.py +4 -1
  44. claude_mpm/services/monitor/daemon_manager.py +3 -2
  45. claude_mpm/services/monitor/handlers/dashboard.py +2 -1
  46. claude_mpm/services/monitor/handlers/hooks.py +2 -1
  47. claude_mpm/services/monitor/management/lifecycle.py +3 -2
  48. claude_mpm/services/monitor/server.py +2 -1
  49. claude_mpm/services/session_management_service.py +3 -2
  50. claude_mpm/services/socketio/handlers/hook.py +3 -2
  51. claude_mpm/services/socketio/server/main.py +3 -1
  52. claude_mpm/services/subprocess_launcher_service.py +14 -5
  53. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +6 -5
  54. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +5 -4
  55. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +5 -4
  56. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +4 -3
  57. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +4 -3
  58. claude_mpm/services/unified/config_strategies/validation_strategy.py +13 -9
  59. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +10 -3
  60. claude_mpm/services/unified/deployment_strategies/local.py +3 -2
  61. claude_mpm/services/unified/deployment_strategies/utils.py +2 -1
  62. claude_mpm/services/unified/deployment_strategies/vercel.py +2 -1
  63. claude_mpm/services/unified/interfaces.py +3 -1
  64. claude_mpm/services/unified/unified_analyzer.py +7 -6
  65. claude_mpm/services/unified/unified_config.py +2 -1
  66. claude_mpm/services/unified/unified_deployment.py +7 -2
  67. claude_mpm/tools/code_tree_analyzer.py +177 -141
  68. claude_mpm/tools/code_tree_events.py +4 -2
  69. {claude_mpm-4.14.6.dist-info → claude_mpm-4.14.8.dist-info}/METADATA +1 -1
  70. {claude_mpm-4.14.6.dist-info → claude_mpm-4.14.8.dist-info}/RECORD +74 -64
  71. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +0 -425
  72. claude_mpm/hooks/claude_hooks/hook_handler_original.py +0 -1041
  73. claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +0 -347
  74. claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +0 -575
  75. claude_mpm/services/project/analyzer_refactored.py +0 -450
  76. {claude_mpm-4.14.6.dist-info → claude_mpm-4.14.8.dist-info}/WHEEL +0 -0
  77. {claude_mpm-4.14.6.dist-info → claude_mpm-4.14.8.dist-info}/entry_points.txt +0 -0
  78. {claude_mpm-4.14.6.dist-info → claude_mpm-4.14.8.dist-info}/licenses/LICENSE +0 -0
  79. {claude_mpm-4.14.6.dist-info → claude_mpm-4.14.8.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,322 @@
1
+ """
2
+ Centralized enums for type-safe string constants across Claude MPM.
3
+
4
+ This module provides enumerated types to replace magic strings throughout the codebase,
5
+ improving type safety, IDE autocomplete, and preventing typos.
6
+
7
+ Created: 2025-10-25
8
+ Priority: Phase 1 of systematic enum migration (3-4 week plan)
9
+ Impact: Replaces 2,050+ magic string occurrences
10
+
11
+ Usage:
12
+ from claude_mpm.core.enums import OperationResult, OutputFormat, ServiceState
13
+
14
+ # Type-safe operation results
15
+ result = OperationResult.SUCCESS
16
+ if result == OperationResult.SUCCESS:
17
+ print("Operation completed successfully")
18
+
19
+ # Type-safe output formatting
20
+ format_type = OutputFormat.JSON
21
+
22
+ # Type-safe service state management
23
+ state = ServiceState.RUNNING
24
+ """
25
+
26
+ from enum import StrEnum
27
+
28
+
29
+ class OperationResult(StrEnum):
30
+ """
31
+ Standard result codes for operations throughout Claude MPM.
32
+
33
+ Replaces 876+ occurrences of magic strings like "success", "error", "failed".
34
+ Used in: CLI commands, service operations, API responses, hook handlers.
35
+
36
+ Migration Priority: HIGH (Week 1)
37
+ Coverage: ~42% of all magic strings
38
+ """
39
+
40
+ SUCCESS = "success"
41
+ """Operation completed successfully."""
42
+
43
+ ERROR = "error"
44
+ """Operation encountered an error."""
45
+
46
+ FAILED = "failed"
47
+ """Operation failed to complete."""
48
+
49
+ PENDING = "pending"
50
+ """Operation is waiting to execute."""
51
+
52
+ COMPLETED = "completed"
53
+ """Operation has been completed."""
54
+
55
+ TIMEOUT = "timeout"
56
+ """Operation exceeded time limit."""
57
+
58
+ CANCELLED = "cancelled"
59
+ """Operation was cancelled before completion."""
60
+
61
+ CONTEXT_READY = "context_ready"
62
+ """Context is prepared and ready for use."""
63
+
64
+ SKIPPED = "skipped"
65
+ """Operation was intentionally skipped."""
66
+
67
+ RETRY = "retry"
68
+ """Operation should be retried."""
69
+
70
+ PARTIAL = "partial"
71
+ """Operation completed partially."""
72
+
73
+ UNKNOWN = "unknown"
74
+ """Operation result is unknown or indeterminate."""
75
+
76
+
77
+ class OutputFormat(StrEnum):
78
+ """
79
+ Output format options for CLI commands and logging.
80
+
81
+ Replaces 200+ occurrences of format strings.
82
+ Used in: CLI output, logging, configuration exports, API responses.
83
+
84
+ Migration Priority: HIGH (Week 1)
85
+ Coverage: ~10% of all magic strings
86
+ """
87
+
88
+ JSON = "json"
89
+ """JavaScript Object Notation format."""
90
+
91
+ YAML = "yaml"
92
+ """YAML Ain't Markup Language format."""
93
+
94
+ TEXT = "text"
95
+ """Plain text format."""
96
+
97
+ MARKDOWN = "markdown"
98
+ """Markdown formatted text."""
99
+
100
+ RAW = "raw"
101
+ """Raw unformatted output."""
102
+
103
+ TABLE = "table"
104
+ """Tabular format for display."""
105
+
106
+ CSV = "csv"
107
+ """Comma-separated values format."""
108
+
109
+ HTML = "html"
110
+ """HyperText Markup Language format."""
111
+
112
+ XML = "xml"
113
+ """eXtensible Markup Language format."""
114
+
115
+
116
+ class ServiceState(StrEnum):
117
+ """
118
+ Service lifecycle states for all Claude MPM services.
119
+
120
+ Replaces 150+ occurrences of service state strings.
121
+ Used in: Hook services, MCP servers, monitoring, health checks.
122
+
123
+ Migration Priority: HIGH (Week 1)
124
+ Coverage: ~7% of all magic strings
125
+ """
126
+
127
+ STOPPED = "stopped"
128
+ """Service is completely stopped."""
129
+
130
+ STARTING = "starting"
131
+ """Service is in the process of starting."""
132
+
133
+ RUNNING = "running"
134
+ """Service is actively running."""
135
+
136
+ STOPPING = "stopping"
137
+ """Service is in the process of stopping."""
138
+
139
+ RESTARTING = "restarting"
140
+ """Service is restarting."""
141
+
142
+ ERROR = "error"
143
+ """Service encountered an error."""
144
+
145
+ UNKNOWN = "unknown"
146
+ """Service state cannot be determined."""
147
+
148
+ DEGRADED = "degraded"
149
+ """Service is running but with reduced functionality."""
150
+
151
+ IDLE = "idle"
152
+ """Service is running but not actively processing."""
153
+
154
+
155
+ class ValidationSeverity(StrEnum):
156
+ """
157
+ Severity levels for validation and error reporting.
158
+
159
+ Replaces validation severity strings across validators and error handlers.
160
+ Used in: Frontmatter validation, API validation, config validation.
161
+
162
+ Migration Priority: MEDIUM (Week 2)
163
+ Coverage: ~5% of all magic strings
164
+ """
165
+
166
+ INFO = "info"
167
+ """Informational message, no action required."""
168
+
169
+ WARNING = "warning"
170
+ """Warning that should be addressed but not critical."""
171
+
172
+ ERROR = "error"
173
+ """Error that prevents operation completion."""
174
+
175
+ CRITICAL = "critical"
176
+ """Critical error requiring immediate attention."""
177
+
178
+ DEBUG = "debug"
179
+ """Debug-level information for troubleshooting."""
180
+
181
+
182
+ class ModelTier(StrEnum):
183
+ """
184
+ Claude model tier classifications and identifiers.
185
+
186
+ Replaces model name strings and enables model normalization.
187
+ Used in: Agent configuration, API calls, capability detection.
188
+
189
+ Migration Priority: MEDIUM (Week 2)
190
+ Coverage: ~4% of all magic strings
191
+
192
+ Notes:
193
+ - Replaces manual model normalization code
194
+ - Enables type-safe model selection
195
+ - Provides both tier names and full model identifiers
196
+ """
197
+
198
+ # Tier names (simplified)
199
+ OPUS = "opus"
200
+ """Claude Opus tier (highest capability)."""
201
+
202
+ SONNET = "sonnet"
203
+ """Claude Sonnet tier (balanced)."""
204
+
205
+ HAIKU = "haiku"
206
+ """Claude Haiku tier (fastest)."""
207
+
208
+ # Full model identifiers (Claude 4.x)
209
+ OPUS_4 = "claude-opus-4-20250514"
210
+ """Claude 4 Opus - May 2025 release."""
211
+
212
+ SONNET_4 = "claude-sonnet-4-20250514"
213
+ """Claude 4 Sonnet - May 2025 release."""
214
+
215
+ SONNET_4_5 = "claude-sonnet-4-5-20250929"
216
+ """Claude 4.5 Sonnet - September 2025 release."""
217
+
218
+ # Legacy model identifiers (Claude 3.x)
219
+ OPUS_3 = "claude-3-opus-20240229"
220
+ """Claude 3 Opus - February 2024 release."""
221
+
222
+ SONNET_3_5 = "claude-3-5-sonnet-20241022"
223
+ """Claude 3.5 Sonnet - October 2024 release."""
224
+
225
+ HAIKU_3 = "claude-3-haiku-20240307"
226
+ """Claude 3 Haiku - March 2024 release."""
227
+
228
+ @classmethod
229
+ def normalize(cls, model_name: str) -> "ModelTier":
230
+ """
231
+ Normalize a model name to its canonical tier.
232
+
233
+ Args:
234
+ model_name: Any model name variant (e.g., "opus", "claude-opus-4", "OPUS")
235
+
236
+ Returns:
237
+ Normalized ModelTier enum value
238
+
239
+ Examples:
240
+ >>> ModelTier.normalize("OPUS")
241
+ ModelTier.OPUS
242
+ >>> ModelTier.normalize("claude-sonnet-4-20250514")
243
+ ModelTier.SONNET_4
244
+ >>> ModelTier.normalize("sonnet")
245
+ ModelTier.SONNET
246
+ """
247
+ normalized = model_name.lower().strip()
248
+
249
+ # Direct enum value match
250
+ for tier in cls:
251
+ if tier.value == normalized:
252
+ return tier
253
+
254
+ # Tier name extraction
255
+ if "opus" in normalized:
256
+ return cls.OPUS
257
+ if "sonnet" in normalized:
258
+ return cls.SONNET
259
+ if "haiku" in normalized:
260
+ return cls.HAIKU
261
+
262
+ # Default to sonnet for unknown models
263
+ return cls.SONNET
264
+
265
+
266
+ class AgentCategory(StrEnum):
267
+ """
268
+ Agent specialization categories for classification and routing.
269
+
270
+ Replaces category strings in agent configurations and routing logic.
271
+ Used in: Agent templates, capability detection, routing decisions.
272
+
273
+ Migration Priority: MEDIUM (Week 3)
274
+ Coverage: ~3% of all magic strings
275
+ """
276
+
277
+ RESEARCH = "research"
278
+ """Research and analysis agents."""
279
+
280
+ ENGINEERING = "engineering"
281
+ """Software engineering and implementation agents."""
282
+
283
+ QA = "qa"
284
+ """Quality assurance and testing agents."""
285
+
286
+ SECURITY = "security"
287
+ """Security analysis and vulnerability assessment agents."""
288
+
289
+ DOCUMENTATION = "documentation"
290
+ """Documentation and technical writing agents."""
291
+
292
+ OPERATIONS = "operations"
293
+ """DevOps and infrastructure management agents."""
294
+
295
+ DATA = "data"
296
+ """Data engineering and analytics agents."""
297
+
298
+ VERSION_CONTROL = "version_control"
299
+ """Version control and release management agents."""
300
+
301
+ GENERAL = "general"
302
+ """General-purpose agents without specific specialization."""
303
+
304
+ CUSTOM = "custom"
305
+ """User-defined custom agent categories."""
306
+
307
+ PROJECT_MANAGEMENT = "project_management"
308
+ """Project management and coordination agents."""
309
+
310
+ DESIGN = "design"
311
+ """UI/UX design and frontend agents."""
312
+
313
+
314
+ # Export all enums for convenient access
315
+ __all__ = [
316
+ "AgentCategory",
317
+ "ModelTier",
318
+ "OperationResult",
319
+ "OutputFormat",
320
+ "ServiceState",
321
+ "ValidationSeverity",
322
+ ]
@@ -21,6 +21,7 @@ import threading
21
21
  from datetime import datetime, timezone
22
22
  from typing import Any, Dict, List, Optional
23
23
 
24
+ from ..core.enums import OperationResult
24
25
  from ..core.logger import get_logger
25
26
 
26
27
 
@@ -158,7 +159,7 @@ class InstructionReinforcementHook:
158
159
  # Create reminder todo
159
160
  reminder_todo = {
160
161
  "content": message,
161
- "status": "pending",
162
+ "status": OperationResult.PENDING,
162
163
  "activeForm": "Processing instruction reminder",
163
164
  }
164
165
 
@@ -11,6 +11,7 @@ import uuid
11
11
  from pathlib import Path
12
12
  from typing import Any, Dict, Optional, Tuple
13
13
 
14
+ from claude_mpm.core.enums import ServiceState
14
15
  from claude_mpm.core.logger import get_logger
15
16
 
16
17
 
@@ -179,7 +180,8 @@ class InteractiveSession:
179
180
  # Notify WebSocket if connected
180
181
  if self.runner.websocket_server:
181
182
  self.runner.websocket_server.claude_status_changed(
182
- status="starting", message="Launching Claude interactive session"
183
+ status=ServiceState.STARTING,
184
+ message="Launching Claude interactive session",
183
185
  )
184
186
 
185
187
  # Launch using selected method
@@ -454,7 +456,8 @@ class InteractiveSession:
454
456
  # Notify WebSocket before exec
455
457
  if self.runner.websocket_server:
456
458
  self.runner.websocket_server.claude_status_changed(
457
- status="running", message="Claude process started (exec mode)"
459
+ status=ServiceState.RUNNING,
460
+ message="Claude process started (exec mode)",
458
461
  )
459
462
 
460
463
  # This will not return if successful
@@ -494,7 +497,7 @@ class InteractiveSession:
494
497
  # Notify WebSocket of error
495
498
  if self.runner.websocket_server:
496
499
  self.runner.websocket_server.claude_status_changed(
497
- status="error", message=f"Failed to launch Claude: {error}"
500
+ status=ServiceState.ERROR, message=f"Failed to launch Claude: {error}"
498
501
  )
499
502
 
500
503
  def _handle_keyboard_interrupt(self) -> None:
@@ -24,6 +24,7 @@ from contextlib import contextmanager
24
24
  from pathlib import Path
25
25
  from typing import Any, Dict, Optional, Union
26
26
 
27
+ from claude_mpm.core.enums import OperationResult
27
28
  from claude_mpm.core.logger import (
28
29
  JsonFormatter,
29
30
  finalize_streaming_logs,
@@ -234,7 +235,10 @@ def log_operation(
234
235
  execution_time = time.time() - start_time
235
236
  logger.info(
236
237
  f"Completed {operation}",
237
- extra={"execution_time": execution_time, "status": "success"},
238
+ extra={
239
+ "execution_time": execution_time,
240
+ "status": OperationResult.SUCCESS,
241
+ },
238
242
  )
239
243
  except Exception as e:
240
244
  execution_time = time.time() - start_time
@@ -242,7 +246,7 @@ def log_operation(
242
246
  f"Failed {operation}: {e}",
243
247
  extra={
244
248
  "execution_time": execution_time,
245
- "status": "failure",
249
+ "status": OperationResult.FAILED,
246
250
  "error": str(e),
247
251
  },
248
252
  )
@@ -12,6 +12,7 @@ import uuid
12
12
  from pathlib import Path
13
13
  from typing import Any, Dict, Optional, Tuple
14
14
 
15
+ from claude_mpm.core.enums import OperationResult, ServiceState
15
16
  from claude_mpm.core.logger import get_logger
16
17
 
17
18
 
@@ -162,7 +163,7 @@ class OneshotSession:
162
163
 
163
164
  if self.runner.websocket_server:
164
165
  self.runner.websocket_server.claude_status_changed(
165
- status="running", message="Executing Claude oneshot command"
166
+ status=ServiceState.RUNNING, message="Executing Claude oneshot command"
166
167
  )
167
168
 
168
169
  def _run_subprocess(
@@ -222,7 +223,7 @@ class OneshotSession:
222
223
  # End WebSocket session
223
224
  if self.runner.websocket_server:
224
225
  self.runner.websocket_server.claude_status_changed(
225
- status="stopped", message="Session completed"
226
+ status=ServiceState.STOPPED, message="Session completed"
226
227
  )
227
228
  self.runner.websocket_server.session_ended()
228
229
 
@@ -299,7 +300,9 @@ class OneshotSession:
299
300
  agent_name = self.runner._extract_agent_from_response(response)
300
301
  if agent_name:
301
302
  self.runner.websocket_server.agent_delegated(
302
- agent=agent_name, task=prompt[:100], status="detected"
303
+ agent=agent_name,
304
+ task=prompt[:100],
305
+ status=OperationResult.PENDING,
303
306
  )
304
307
 
305
308
  # Log completion
@@ -335,7 +338,8 @@ class OneshotSession:
335
338
  if self.runner.websocket_server:
336
339
  self.runner.websocket_server.claude_output(error_msg, "stderr")
337
340
  self.runner.websocket_server.claude_status_changed(
338
- status="error", message=f"Command failed with code {return_code}"
341
+ status=ServiceState.ERROR,
342
+ message=f"Command failed with code {return_code}",
339
343
  )
340
344
 
341
345
  # Log error
@@ -160,203 +160,23 @@ class OutputStyleManager:
160
160
 
161
161
  def extract_output_style_content(self, framework_loader=None) -> str:
162
162
  """
163
- Extract output style content from framework instructions.
164
-
165
- This extracts PM delegation behavior, tone, communication standards,
166
- response formats, TodoWrite requirements, and workflow rules from:
167
- - INSTRUCTIONS.md
168
- - BASE_PM.md
163
+ Read output style content from OUTPUT_STYLE.md.
169
164
 
170
165
  Args:
171
- framework_loader: Optional FrameworkLoader instance to reuse loaded content
166
+ framework_loader: Optional framework loader (kept for compatibility, not used)
172
167
 
173
168
  Returns:
174
- Formatted output style content in YAML frontmatter + markdown format
169
+ Complete output style content from file
175
170
  """
176
- # Build the content sections
177
- sections = []
178
-
179
- # Add YAML frontmatter
180
- sections.append("---")
181
- sections.append("name: Claude MPM")
182
- sections.append(
183
- "description: Multi-Agent Project Manager orchestration mode for delegation and coordination"
184
- )
185
- sections.append("---")
186
- sections.append("")
187
-
188
- # Header
189
- sections.append(
190
- "You are Claude Multi-Agent PM, a PROJECT MANAGER whose SOLE PURPOSE is to delegate work to specialized agents."
191
- )
192
- sections.append("")
193
-
194
- # Extract from INSTRUCTIONS.md
195
- if framework_loader and framework_loader.framework_content.get(
196
- "framework_instructions"
197
- ):
198
- instructions = framework_loader.framework_content["framework_instructions"]
199
- sections.extend(self._extract_instructions_sections(instructions))
200
- else:
201
- # Load from file if no framework_loader provided
202
- instructions_path = (
203
- Path(__file__).parent.parent / "agents" / "INSTRUCTIONS.md"
204
- )
205
- if instructions_path.exists():
206
- instructions = instructions_path.read_text()
207
- sections.extend(self._extract_instructions_sections(instructions))
208
-
209
- # Extract from BASE_PM.md
210
- if framework_loader and framework_loader.framework_content.get(
211
- "base_pm_instructions"
212
- ):
213
- base_pm = framework_loader.framework_content["base_pm_instructions"]
214
- sections.extend(self._extract_base_pm_sections(base_pm))
215
- else:
216
- # Load from file if no framework_loader provided
217
- base_pm_path = Path(__file__).parent.parent / "agents" / "BASE_PM.md"
218
- if base_pm_path.exists():
219
- base_pm = base_pm_path.read_text()
220
- sections.extend(self._extract_base_pm_sections(base_pm))
221
-
222
- return "\n".join(sections)
223
-
224
- def _extract_instructions_sections(self, content: str) -> list:
225
- """Extract relevant sections from INSTRUCTIONS.md."""
226
- sections = []
227
-
228
- # Extract Primary Directive
229
- if "## 🔴 PRIMARY DIRECTIVE" in content:
230
- sections.append("## 🔴 PRIMARY DIRECTIVE - MANDATORY DELEGATION 🔴")
231
- sections.append("")
232
- sections.append(
233
- "**YOU ARE STRICTLY FORBIDDEN FROM DOING ANY WORK DIRECTLY.**"
234
- )
235
- sections.append("")
236
- sections.append(
237
- "Direct implementation is ABSOLUTELY PROHIBITED unless the user EXPLICITLY overrides with phrases like:"
238
- )
239
- sections.append('- "do this yourself"')
240
- sections.append('- "don\'t delegate"')
241
- sections.append('- "implement directly"')
242
- sections.append('- "you do it"')
243
- sections.append('- "no delegation"')
244
- sections.append("")
245
-
246
- # Extract Core Identity and Rules
247
- if "## Core Identity" in content:
248
- sections.append("## Core Operating Rules")
249
- sections.append("")
250
- sections.append("**DEFAULT BEHAVIOR - ALWAYS DELEGATE**:")
251
- sections.append(
252
- "- 🔴 You MUST delegate 100% of ALL work to specialized agents by default"
253
- )
254
- sections.append(
255
- "- 🔴 Direct action is STRICTLY FORBIDDEN without explicit user override"
256
- )
257
- sections.append(
258
- "- 🔴 Even the simplest tasks MUST be delegated - NO EXCEPTIONS"
259
- )
260
- sections.append("- 🔴 When in doubt, ALWAYS DELEGATE - never act directly")
261
- sections.append("")
262
- sections.append("**Allowed Tools**:")
263
- sections.append("- **Task** for delegation (YOUR PRIMARY FUNCTION)")
264
- sections.append("- **TodoWrite** for tracking delegation progress ONLY")
265
- sections.append(
266
- "- **WebSearch/WebFetch** for gathering context BEFORE delegation"
267
- )
268
- sections.append(
269
- "- **Direct answers** ONLY for questions about PM capabilities"
270
- )
271
- sections.append("")
272
-
273
- # Extract Communication Standards
274
- if "## Communication Standards" in content:
275
- sections.append("## Communication Standards")
276
- sections.append("")
277
- sections.append("- **Tone**: Professional, neutral by default")
278
- sections.append('- **Use**: "Understood", "Confirmed", "Noted"')
279
- sections.append("- **No simplification** without explicit user request")
280
- sections.append("- **No mocks** outside test environments")
281
- sections.append("- **Complete implementations** only - no placeholders")
282
- sections.append(
283
- '- **FORBIDDEN**: Overeager enthusiasm ("Excellent!", "Perfect!", "Amazing!")'
284
- )
285
- sections.append("")
286
-
287
- # Extract Error Handling
288
- if "## Error Handling Protocol" in content:
289
- sections.append("## Error Handling Protocol")
290
- sections.append("")
291
- sections.append("**3-Attempt Process**:")
292
- sections.append("1. **First Failure**: Re-delegate with enhanced context")
293
- sections.append(
294
- '2. **Second Failure**: Mark "ERROR - Attempt 2/3", escalate if needed'
295
- )
296
- sections.append(
297
- "3. **Third Failure**: TodoWrite escalation with user decision required"
298
- )
299
- sections.append("")
300
-
301
- # Extract Standard Operating Procedure
302
- if "## Standard Operating Procedure" in content:
303
- sections.append("## Standard Operating Procedure")
304
- sections.append("")
305
- sections.append("1. **Analysis**: Parse request, assess context (NO TOOLS)")
306
- sections.append(
307
- "2. **Planning**: Agent selection, task breakdown, priority assignment"
308
- )
309
- sections.append("3. **Delegation**: Task Tool with enhanced format")
310
- sections.append("4. **Monitoring**: Track progress via TodoWrite")
311
- sections.append("5. **Integration**: Synthesize results, validate, report")
312
- sections.append("")
313
-
314
- return sections
315
-
316
- def _extract_base_pm_sections(self, content: str) -> list:
317
- """Extract relevant sections from BASE_PM.md."""
318
- sections = []
319
-
320
- # Extract TodoWrite Requirements
321
- if "## TodoWrite Framework Requirements" in content:
322
- sections.append("## TodoWrite Requirements")
323
- sections.append("")
324
- sections.append("### Mandatory [Agent] Prefix Rules")
325
- sections.append("")
326
- sections.append("**ALWAYS use [Agent] prefix for delegated tasks**:")
327
- sections.append("- ✅ `[Research] Analyze authentication patterns`")
328
- sections.append("- ✅ `[Engineer] Implement user registration`")
329
- sections.append("- ✅ `[QA] Test payment flow`")
330
- sections.append("- ✅ `[Documentation] Update API docs`")
331
- sections.append("")
332
- sections.append("**NEVER use [PM] prefix for implementation tasks**")
333
- sections.append("")
334
- sections.append("### Task Status Management")
335
- sections.append("")
336
- sections.append("- `pending` - Task not yet started")
337
- sections.append(
338
- "- `in_progress` - Currently being worked on (ONE at a time)"
339
- )
340
- sections.append("- `completed` - Task finished successfully")
341
- sections.append("")
342
-
343
- # Extract PM Response Format
344
- if "## PM Response Format" in content:
345
- sections.append("## Response Format")
346
- sections.append("")
347
- sections.append(
348
- "When completing delegations, provide structured summaries including:"
349
- )
350
- sections.append("- Request summary")
351
- sections.append("- Agents used and task counts")
352
- sections.append("- Tasks completed with [Agent] prefixes")
353
- sections.append("- Files affected across all agents")
354
- sections.append("- Blockers encountered and resolutions")
355
- sections.append("- Next steps for user")
356
- sections.append("- Key information to remember")
357
- sections.append("")
358
-
359
- return sections
171
+ # Always read from the complete OUTPUT_STYLE.md file
172
+ if self.mpm_output_style_path.exists():
173
+ content = self.mpm_output_style_path.read_text()
174
+ self.logger.info(f"Read OUTPUT_STYLE.md directly ({len(content)} chars)")
175
+ return content
176
+ # Fallback error
177
+ error_msg = f"OUTPUT_STYLE.md not found at {self.mpm_output_style_path}"
178
+ self.logger.error(error_msg)
179
+ raise FileNotFoundError(error_msg)
360
180
 
361
181
  def save_output_style(self, content: str) -> Path:
362
182
  """
@@ -10,6 +10,7 @@ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Type, Union
10
10
  from .base_service import BaseService
11
11
  from .config import Config
12
12
  from .container import DIContainer, ServiceLifetime, get_container
13
+ from .enums import OperationResult
13
14
  from .logger import get_logger
14
15
  from .shared.config_loader import ConfigLoader
15
16
 
@@ -249,7 +250,10 @@ class ServiceRegistry:
249
250
  "metrics": health.metrics,
250
251
  }
251
252
  except Exception as e:
252
- health_status[name] = {"status": "error", "message": str(e)}
253
+ health_status[name] = {
254
+ "status": OperationResult.ERROR,
255
+ "message": str(e),
256
+ }
253
257
 
254
258
  return health_status
255
259