claude-mpm 4.7.4__py3-none-any.whl → 4.18.2__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 (308) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +118 -0
  3. claude_mpm/agents/BASE_ENGINEER.md +286 -0
  4. claude_mpm/agents/BASE_PM.md +106 -1
  5. claude_mpm/agents/OUTPUT_STYLE.md +329 -11
  6. claude_mpm/agents/PM_INSTRUCTIONS.md +397 -459
  7. claude_mpm/agents/agent_loader.py +17 -5
  8. claude_mpm/agents/frontmatter_validator.py +284 -253
  9. claude_mpm/agents/templates/README.md +465 -0
  10. claude_mpm/agents/templates/agent-manager.json +4 -1
  11. claude_mpm/agents/templates/agentic-coder-optimizer.json +13 -3
  12. claude_mpm/agents/templates/api_qa.json +11 -2
  13. claude_mpm/agents/templates/circuit_breakers.md +638 -0
  14. claude_mpm/agents/templates/clerk-ops.json +12 -2
  15. claude_mpm/agents/templates/code_analyzer.json +8 -2
  16. claude_mpm/agents/templates/content-agent.json +358 -0
  17. claude_mpm/agents/templates/dart_engineer.json +15 -2
  18. claude_mpm/agents/templates/data_engineer.json +15 -2
  19. claude_mpm/agents/templates/documentation.json +10 -2
  20. claude_mpm/agents/templates/engineer.json +21 -1
  21. claude_mpm/agents/templates/gcp_ops_agent.json +12 -2
  22. claude_mpm/agents/templates/git_file_tracking.md +584 -0
  23. claude_mpm/agents/templates/golang_engineer.json +270 -0
  24. claude_mpm/agents/templates/imagemagick.json +4 -1
  25. claude_mpm/agents/templates/java_engineer.json +346 -0
  26. claude_mpm/agents/templates/local_ops_agent.json +1227 -6
  27. claude_mpm/agents/templates/memory_manager.json +4 -1
  28. claude_mpm/agents/templates/nextjs_engineer.json +141 -133
  29. claude_mpm/agents/templates/ops.json +12 -2
  30. claude_mpm/agents/templates/php-engineer.json +270 -174
  31. claude_mpm/agents/templates/pm_examples.md +474 -0
  32. claude_mpm/agents/templates/pm_red_flags.md +240 -0
  33. claude_mpm/agents/templates/product_owner.json +338 -0
  34. claude_mpm/agents/templates/project_organizer.json +14 -4
  35. claude_mpm/agents/templates/prompt-engineer.json +13 -2
  36. claude_mpm/agents/templates/python_engineer.json +174 -81
  37. claude_mpm/agents/templates/qa.json +11 -2
  38. claude_mpm/agents/templates/react_engineer.json +16 -3
  39. claude_mpm/agents/templates/refactoring_engineer.json +12 -2
  40. claude_mpm/agents/templates/research.json +34 -21
  41. claude_mpm/agents/templates/response_format.md +583 -0
  42. claude_mpm/agents/templates/ruby-engineer.json +129 -192
  43. claude_mpm/agents/templates/rust_engineer.json +270 -0
  44. claude_mpm/agents/templates/security.json +10 -2
  45. claude_mpm/agents/templates/svelte-engineer.json +225 -0
  46. claude_mpm/agents/templates/ticketing.json +10 -2
  47. claude_mpm/agents/templates/typescript_engineer.json +116 -125
  48. claude_mpm/agents/templates/validation_templates.md +312 -0
  49. claude_mpm/agents/templates/vercel_ops_agent.json +12 -2
  50. claude_mpm/agents/templates/version_control.json +12 -2
  51. claude_mpm/agents/templates/web_qa.json +11 -2
  52. claude_mpm/agents/templates/web_ui.json +15 -2
  53. claude_mpm/cli/__init__.py +34 -614
  54. claude_mpm/cli/commands/agent_manager.py +25 -12
  55. claude_mpm/cli/commands/agent_state_manager.py +186 -0
  56. claude_mpm/cli/commands/agents.py +235 -148
  57. claude_mpm/cli/commands/agents_detect.py +380 -0
  58. claude_mpm/cli/commands/agents_recommend.py +309 -0
  59. claude_mpm/cli/commands/aggregate.py +7 -3
  60. claude_mpm/cli/commands/analyze.py +9 -4
  61. claude_mpm/cli/commands/analyze_code.py +7 -2
  62. claude_mpm/cli/commands/auto_configure.py +570 -0
  63. claude_mpm/cli/commands/config.py +47 -13
  64. claude_mpm/cli/commands/configure.py +419 -1571
  65. claude_mpm/cli/commands/configure_agent_display.py +261 -0
  66. claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
  67. claude_mpm/cli/commands/configure_hook_manager.py +225 -0
  68. claude_mpm/cli/commands/configure_models.py +18 -0
  69. claude_mpm/cli/commands/configure_navigation.py +167 -0
  70. claude_mpm/cli/commands/configure_paths.py +104 -0
  71. claude_mpm/cli/commands/configure_persistence.py +254 -0
  72. claude_mpm/cli/commands/configure_startup_manager.py +646 -0
  73. claude_mpm/cli/commands/configure_template_editor.py +497 -0
  74. claude_mpm/cli/commands/configure_validators.py +73 -0
  75. claude_mpm/cli/commands/local_deploy.py +537 -0
  76. claude_mpm/cli/commands/memory.py +54 -20
  77. claude_mpm/cli/commands/mpm_init.py +585 -196
  78. claude_mpm/cli/commands/mpm_init_handler.py +37 -3
  79. claude_mpm/cli/commands/search.py +170 -4
  80. claude_mpm/cli/commands/upgrade.py +152 -0
  81. claude_mpm/cli/executor.py +202 -0
  82. claude_mpm/cli/helpers.py +105 -0
  83. claude_mpm/cli/interactive/__init__.py +3 -0
  84. claude_mpm/cli/interactive/skills_wizard.py +491 -0
  85. claude_mpm/cli/parsers/__init__.py +7 -1
  86. claude_mpm/cli/parsers/agents_parser.py +9 -0
  87. claude_mpm/cli/parsers/auto_configure_parser.py +245 -0
  88. claude_mpm/cli/parsers/base_parser.py +110 -3
  89. claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
  90. claude_mpm/cli/parsers/mpm_init_parser.py +65 -5
  91. claude_mpm/cli/shared/output_formatters.py +28 -19
  92. claude_mpm/cli/startup.py +481 -0
  93. claude_mpm/cli/utils.py +52 -1
  94. claude_mpm/commands/mpm-agents-detect.md +168 -0
  95. claude_mpm/commands/mpm-agents-recommend.md +214 -0
  96. claude_mpm/commands/mpm-agents.md +75 -1
  97. claude_mpm/commands/mpm-auto-configure.md +217 -0
  98. claude_mpm/commands/mpm-help.md +163 -0
  99. claude_mpm/commands/mpm-init.md +148 -3
  100. claude_mpm/commands/mpm-version.md +113 -0
  101. claude_mpm/commands/mpm.md +1 -0
  102. claude_mpm/config/agent_config.py +2 -2
  103. claude_mpm/config/model_config.py +428 -0
  104. claude_mpm/constants.py +1 -0
  105. claude_mpm/core/base_service.py +13 -12
  106. claude_mpm/core/enums.py +452 -0
  107. claude_mpm/core/factories.py +1 -1
  108. claude_mpm/core/instruction_reinforcement_hook.py +2 -1
  109. claude_mpm/core/interactive_session.py +9 -3
  110. claude_mpm/core/log_manager.py +2 -0
  111. claude_mpm/core/logging_config.py +6 -2
  112. claude_mpm/core/oneshot_session.py +8 -4
  113. claude_mpm/core/optimized_agent_loader.py +3 -3
  114. claude_mpm/core/output_style_manager.py +12 -192
  115. claude_mpm/core/service_registry.py +5 -1
  116. claude_mpm/core/types.py +2 -9
  117. claude_mpm/core/typing_utils.py +7 -6
  118. claude_mpm/dashboard/static/js/dashboard.js +0 -14
  119. claude_mpm/dashboard/templates/index.html +3 -41
  120. claude_mpm/hooks/__init__.py +20 -0
  121. claude_mpm/hooks/claude_hooks/event_handlers.py +4 -2
  122. claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
  123. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +23 -2
  124. claude_mpm/hooks/failure_learning/__init__.py +60 -0
  125. claude_mpm/hooks/failure_learning/failure_detection_hook.py +235 -0
  126. claude_mpm/hooks/failure_learning/fix_detection_hook.py +217 -0
  127. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +286 -0
  128. claude_mpm/hooks/instruction_reinforcement.py +7 -2
  129. claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
  130. claude_mpm/hooks/kuzu_memory_hook.py +37 -12
  131. claude_mpm/hooks/kuzu_response_hook.py +183 -0
  132. claude_mpm/models/resume_log.py +340 -0
  133. claude_mpm/services/agents/__init__.py +18 -5
  134. claude_mpm/services/agents/auto_config_manager.py +796 -0
  135. claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
  136. claude_mpm/services/agents/deployment/agent_record_service.py +1 -1
  137. claude_mpm/services/agents/deployment/agent_validator.py +17 -1
  138. claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
  139. claude_mpm/services/agents/deployment/interface_adapter.py +3 -2
  140. claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
  141. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +7 -6
  142. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +7 -16
  143. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +4 -3
  144. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +5 -3
  145. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +6 -5
  146. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +9 -6
  147. claude_mpm/services/agents/deployment/validation/__init__.py +3 -1
  148. claude_mpm/services/agents/deployment/validation/validation_result.py +1 -9
  149. claude_mpm/services/agents/local_template_manager.py +1 -1
  150. claude_mpm/services/agents/memory/agent_memory_manager.py +5 -2
  151. claude_mpm/services/agents/observers.py +547 -0
  152. claude_mpm/services/agents/recommender.py +568 -0
  153. claude_mpm/services/agents/registry/modification_tracker.py +5 -2
  154. claude_mpm/services/command_handler_service.py +11 -5
  155. claude_mpm/services/core/__init__.py +33 -1
  156. claude_mpm/services/core/interfaces/__init__.py +90 -3
  157. claude_mpm/services/core/interfaces/agent.py +184 -0
  158. claude_mpm/services/core/interfaces/health.py +172 -0
  159. claude_mpm/services/core/interfaces/model.py +281 -0
  160. claude_mpm/services/core/interfaces/process.py +372 -0
  161. claude_mpm/services/core/interfaces/project.py +121 -0
  162. claude_mpm/services/core/interfaces/restart.py +307 -0
  163. claude_mpm/services/core/interfaces/stability.py +260 -0
  164. claude_mpm/services/core/memory_manager.py +11 -24
  165. claude_mpm/services/core/models/__init__.py +79 -0
  166. claude_mpm/services/core/models/agent_config.py +381 -0
  167. claude_mpm/services/core/models/health.py +162 -0
  168. claude_mpm/services/core/models/process.py +235 -0
  169. claude_mpm/services/core/models/restart.py +302 -0
  170. claude_mpm/services/core/models/stability.py +264 -0
  171. claude_mpm/services/core/models/toolchain.py +306 -0
  172. claude_mpm/services/core/path_resolver.py +23 -7
  173. claude_mpm/services/diagnostics/__init__.py +2 -2
  174. claude_mpm/services/diagnostics/checks/agent_check.py +25 -24
  175. claude_mpm/services/diagnostics/checks/claude_code_check.py +24 -23
  176. claude_mpm/services/diagnostics/checks/common_issues_check.py +25 -24
  177. claude_mpm/services/diagnostics/checks/configuration_check.py +24 -23
  178. claude_mpm/services/diagnostics/checks/filesystem_check.py +18 -17
  179. claude_mpm/services/diagnostics/checks/installation_check.py +30 -29
  180. claude_mpm/services/diagnostics/checks/instructions_check.py +20 -19
  181. claude_mpm/services/diagnostics/checks/mcp_check.py +50 -36
  182. claude_mpm/services/diagnostics/checks/mcp_services_check.py +38 -33
  183. claude_mpm/services/diagnostics/checks/monitor_check.py +23 -22
  184. claude_mpm/services/diagnostics/checks/startup_log_check.py +9 -8
  185. claude_mpm/services/diagnostics/diagnostic_runner.py +6 -5
  186. claude_mpm/services/diagnostics/doctor_reporter.py +28 -25
  187. claude_mpm/services/diagnostics/models.py +19 -24
  188. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -1
  189. claude_mpm/services/infrastructure/monitoring/aggregator.py +12 -12
  190. claude_mpm/services/infrastructure/monitoring/base.py +5 -13
  191. claude_mpm/services/infrastructure/monitoring/network.py +7 -6
  192. claude_mpm/services/infrastructure/monitoring/process.py +13 -12
  193. claude_mpm/services/infrastructure/monitoring/resources.py +7 -6
  194. claude_mpm/services/infrastructure/monitoring/service.py +16 -15
  195. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  196. claude_mpm/services/local_ops/__init__.py +163 -0
  197. claude_mpm/services/local_ops/crash_detector.py +257 -0
  198. claude_mpm/services/local_ops/health_checks/__init__.py +28 -0
  199. claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
  200. claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
  201. claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
  202. claude_mpm/services/local_ops/health_manager.py +430 -0
  203. claude_mpm/services/local_ops/log_monitor.py +396 -0
  204. claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
  205. claude_mpm/services/local_ops/process_manager.py +595 -0
  206. claude_mpm/services/local_ops/resource_monitor.py +331 -0
  207. claude_mpm/services/local_ops/restart_manager.py +401 -0
  208. claude_mpm/services/local_ops/restart_policy.py +387 -0
  209. claude_mpm/services/local_ops/state_manager.py +372 -0
  210. claude_mpm/services/local_ops/unified_manager.py +600 -0
  211. claude_mpm/services/mcp_config_manager.py +9 -4
  212. claude_mpm/services/mcp_gateway/core/__init__.py +1 -2
  213. claude_mpm/services/mcp_gateway/core/base.py +18 -31
  214. claude_mpm/services/mcp_gateway/main.py +30 -0
  215. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +206 -32
  216. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +30 -28
  217. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +25 -5
  218. claude_mpm/services/mcp_service_verifier.py +1 -1
  219. claude_mpm/services/memory/failure_tracker.py +563 -0
  220. claude_mpm/services/memory_hook_service.py +165 -4
  221. claude_mpm/services/model/__init__.py +147 -0
  222. claude_mpm/services/model/base_provider.py +365 -0
  223. claude_mpm/services/model/claude_provider.py +412 -0
  224. claude_mpm/services/model/model_router.py +453 -0
  225. claude_mpm/services/model/ollama_provider.py +415 -0
  226. claude_mpm/services/monitor/daemon_manager.py +3 -2
  227. claude_mpm/services/monitor/handlers/dashboard.py +2 -1
  228. claude_mpm/services/monitor/handlers/hooks.py +2 -1
  229. claude_mpm/services/monitor/management/lifecycle.py +3 -2
  230. claude_mpm/services/monitor/server.py +2 -1
  231. claude_mpm/services/project/__init__.py +23 -0
  232. claude_mpm/services/project/detection_strategies.py +719 -0
  233. claude_mpm/services/project/toolchain_analyzer.py +581 -0
  234. claude_mpm/services/self_upgrade_service.py +342 -0
  235. claude_mpm/services/session_management_service.py +3 -2
  236. claude_mpm/services/session_manager.py +205 -1
  237. claude_mpm/services/shared/async_service_base.py +16 -27
  238. claude_mpm/services/shared/lifecycle_service_base.py +1 -14
  239. claude_mpm/services/socketio/handlers/__init__.py +5 -2
  240. claude_mpm/services/socketio/handlers/hook.py +13 -2
  241. claude_mpm/services/socketio/handlers/registry.py +4 -2
  242. claude_mpm/services/socketio/server/main.py +10 -8
  243. claude_mpm/services/subprocess_launcher_service.py +14 -5
  244. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +8 -7
  245. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +6 -5
  246. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +8 -7
  247. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +7 -6
  248. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +5 -4
  249. claude_mpm/services/unified/config_strategies/validation_strategy.py +13 -9
  250. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +10 -3
  251. claude_mpm/services/unified/deployment_strategies/local.py +6 -5
  252. claude_mpm/services/unified/deployment_strategies/utils.py +6 -5
  253. claude_mpm/services/unified/deployment_strategies/vercel.py +7 -6
  254. claude_mpm/services/unified/interfaces.py +3 -1
  255. claude_mpm/services/unified/unified_analyzer.py +14 -10
  256. claude_mpm/services/unified/unified_config.py +2 -1
  257. claude_mpm/services/unified/unified_deployment.py +9 -4
  258. claude_mpm/services/version_service.py +104 -1
  259. claude_mpm/skills/__init__.py +21 -0
  260. claude_mpm/skills/bundled/__init__.py +6 -0
  261. claude_mpm/skills/bundled/api-documentation.md +393 -0
  262. claude_mpm/skills/bundled/async-testing.md +571 -0
  263. claude_mpm/skills/bundled/code-review.md +143 -0
  264. claude_mpm/skills/bundled/database-migration.md +199 -0
  265. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  266. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  267. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  268. claude_mpm/skills/bundled/git-workflow.md +414 -0
  269. claude_mpm/skills/bundled/imagemagick.md +204 -0
  270. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  271. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  272. claude_mpm/skills/bundled/pdf.md +141 -0
  273. claude_mpm/skills/bundled/performance-profiling.md +567 -0
  274. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  275. claude_mpm/skills/bundled/security-scanning.md +327 -0
  276. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  277. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  278. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  279. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  280. claude_mpm/skills/bundled/xlsx.md +157 -0
  281. claude_mpm/skills/registry.py +286 -0
  282. claude_mpm/skills/skill_manager.py +310 -0
  283. claude_mpm/storage/state_storage.py +15 -15
  284. claude_mpm/tools/code_tree_analyzer.py +177 -141
  285. claude_mpm/tools/code_tree_events.py +4 -2
  286. claude_mpm/utils/agent_dependency_loader.py +40 -20
  287. claude_mpm/utils/display_helper.py +260 -0
  288. claude_mpm/utils/git_analyzer.py +407 -0
  289. claude_mpm/utils/robust_installer.py +73 -19
  290. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/METADATA +129 -12
  291. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/RECORD +295 -193
  292. claude_mpm/dashboard/static/css/code-tree.css +0 -1639
  293. claude_mpm/dashboard/static/index-hub-backup.html +0 -713
  294. claude_mpm/dashboard/static/js/components/code-tree/tree-breadcrumb.js +0 -353
  295. claude_mpm/dashboard/static/js/components/code-tree/tree-constants.js +0 -235
  296. claude_mpm/dashboard/static/js/components/code-tree/tree-search.js +0 -409
  297. claude_mpm/dashboard/static/js/components/code-tree/tree-utils.js +0 -435
  298. claude_mpm/dashboard/static/js/components/code-tree.js +0 -5869
  299. claude_mpm/dashboard/static/js/components/code-viewer.js +0 -1386
  300. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +0 -425
  301. claude_mpm/hooks/claude_hooks/hook_handler_original.py +0 -1041
  302. claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +0 -347
  303. claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +0 -575
  304. claude_mpm/services/project/analyzer_refactored.py +0 -450
  305. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/WHEEL +0 -0
  306. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/entry_points.txt +0 -0
  307. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/licenses/LICENSE +0 -0
  308. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/top_level.txt +0 -0
@@ -4,23 +4,12 @@ Base class for asynchronous services to reduce duplication.
4
4
 
5
5
  import asyncio
6
6
  from abc import ABC, abstractmethod
7
- from enum import Enum
8
7
  from typing import Any, Dict, Optional
9
8
 
9
+ from ...core.enums import ServiceState
10
10
  from ...core.mixins import LoggerMixin
11
11
 
12
12
 
13
- class AsyncServiceState(Enum):
14
- """Standard states for async services."""
15
-
16
- UNINITIALIZED = "uninitialized"
17
- INITIALIZING = "initializing"
18
- RUNNING = "running"
19
- STOPPING = "stopping"
20
- STOPPED = "stopped"
21
- ERROR = "error"
22
-
23
-
24
13
  class AsyncServiceBase(LoggerMixin, ABC):
25
14
  """
26
15
  Base class for asynchronous services.
@@ -45,7 +34,7 @@ class AsyncServiceBase(LoggerMixin, ABC):
45
34
  self.config = config or {}
46
35
 
47
36
  # State management
48
- self._state = AsyncServiceState.UNINITIALIZED
37
+ self._state = ServiceState.UNINITIALIZED
49
38
  self._state_lock = asyncio.Lock()
50
39
 
51
40
  # Background tasks
@@ -57,19 +46,19 @@ class AsyncServiceBase(LoggerMixin, ABC):
57
46
  self._error_count = 0
58
47
 
59
48
  @property
60
- def state(self) -> AsyncServiceState:
49
+ def state(self) -> ServiceState:
61
50
  """Get current service state."""
62
51
  return self._state
63
52
 
64
53
  @property
65
54
  def is_running(self) -> bool:
66
55
  """Check if service is running."""
67
- return self._state == AsyncServiceState.RUNNING
56
+ return self._state == ServiceState.RUNNING
68
57
 
69
58
  @property
70
59
  def is_healthy(self) -> bool:
71
60
  """Check if service is healthy."""
72
- return self._state == AsyncServiceState.RUNNING and self._last_error is None
61
+ return self._state == ServiceState.RUNNING and self._last_error is None
73
62
 
74
63
  async def initialize(self) -> bool:
75
64
  """
@@ -79,22 +68,22 @@ class AsyncServiceBase(LoggerMixin, ABC):
79
68
  True if initialization successful
80
69
  """
81
70
  async with self._state_lock:
82
- if self._state != AsyncServiceState.UNINITIALIZED:
71
+ if self._state != ServiceState.UNINITIALIZED:
83
72
  self.logger.warning(f"Service {self.service_name} already initialized")
84
- return self._state == AsyncServiceState.RUNNING
73
+ return self._state == ServiceState.RUNNING
85
74
 
86
- self._state = AsyncServiceState.INITIALIZING
75
+ self._state = ServiceState.INITIALIZING
87
76
  self.logger.info(f"Initializing service: {self.service_name}")
88
77
 
89
78
  try:
90
79
  success = await self._do_initialize()
91
80
  if success:
92
- self._state = AsyncServiceState.RUNNING
81
+ self._state = ServiceState.RUNNING
93
82
  self.logger.info(
94
83
  f"Service {self.service_name} initialized successfully"
95
84
  )
96
85
  else:
97
- self._state = AsyncServiceState.ERROR
86
+ self._state = ServiceState.ERROR
98
87
  self.logger.error(
99
88
  f"Service {self.service_name} initialization failed"
100
89
  )
@@ -102,7 +91,7 @@ class AsyncServiceBase(LoggerMixin, ABC):
102
91
  return success
103
92
 
104
93
  except Exception as e:
105
- self._state = AsyncServiceState.ERROR
94
+ self._state = ServiceState.ERROR
106
95
  self._last_error = e
107
96
  self._error_count += 1
108
97
  self.logger.error(
@@ -114,10 +103,10 @@ class AsyncServiceBase(LoggerMixin, ABC):
114
103
  async def shutdown(self) -> None:
115
104
  """Shutdown the service gracefully."""
116
105
  async with self._state_lock:
117
- if self._state in (AsyncServiceState.STOPPED, AsyncServiceState.STOPPING):
106
+ if self._state in (ServiceState.STOPPED, ServiceState.STOPPING):
118
107
  return
119
108
 
120
- self._state = AsyncServiceState.STOPPING
109
+ self._state = ServiceState.STOPPING
121
110
  self.logger.info(f"Shutting down service: {self.service_name}")
122
111
 
123
112
  try:
@@ -130,11 +119,11 @@ class AsyncServiceBase(LoggerMixin, ABC):
130
119
  # Service-specific shutdown
131
120
  await self._do_shutdown()
132
121
 
133
- self._state = AsyncServiceState.STOPPED
122
+ self._state = ServiceState.STOPPED
134
123
  self.logger.info(f"Service {self.service_name} shut down successfully")
135
124
 
136
125
  except Exception as e:
137
- self._state = AsyncServiceState.ERROR
126
+ self._state = ServiceState.ERROR
138
127
  self._last_error = e
139
128
  self.logger.error(
140
129
  f"Service {self.service_name} shutdown error: {e}", exc_info=True
@@ -146,7 +135,7 @@ class AsyncServiceBase(LoggerMixin, ABC):
146
135
  await self.shutdown()
147
136
 
148
137
  # Reset state for restart
149
- self._state = AsyncServiceState.UNINITIALIZED
138
+ self._state = ServiceState.UNINITIALIZED
150
139
  self._shutdown_event.clear()
151
140
  self._last_error = None
152
141
 
@@ -4,25 +4,12 @@ Base class for services with complex lifecycle management.
4
4
 
5
5
  import time
6
6
  from abc import ABC, abstractmethod
7
- from enum import Enum
8
7
  from typing import Any, Dict, List, Optional
9
8
 
9
+ from ...core.enums import ServiceState
10
10
  from ...core.mixins import LoggerMixin
11
11
 
12
12
 
13
- class ServiceState(Enum):
14
- """Standard service states."""
15
-
16
- UNINITIALIZED = "uninitialized"
17
- INITIALIZING = "initializing"
18
- INITIALIZED = "initialized"
19
- STARTING = "starting"
20
- RUNNING = "running"
21
- STOPPING = "stopping"
22
- STOPPED = "stopped"
23
- ERROR = "error"
24
-
25
-
26
13
  class LifecycleServiceBase(LoggerMixin, ABC):
27
14
  """
28
15
  Base class for services with complex lifecycle management.
@@ -7,7 +7,9 @@ and maintainability.
7
7
  """
8
8
 
9
9
  from .base import BaseEventHandler
10
- from .code_analysis import CodeAnalysisEventHandler
10
+
11
+ # DISABLED: File Tree interface removed from dashboard
12
+ # from .code_analysis import CodeAnalysisEventHandler
11
13
  from .connection import ConnectionEventHandler
12
14
  from .file import FileEventHandler
13
15
  from .git import GitEventHandler
@@ -17,7 +19,8 @@ from .registry import EventHandlerRegistry
17
19
 
18
20
  __all__ = [
19
21
  "BaseEventHandler",
20
- "CodeAnalysisEventHandler",
22
+ # DISABLED: File Tree interface removed from dashboard
23
+ # "CodeAnalysisEventHandler",
21
24
  "ConnectionEventHandler",
22
25
  "EventHandlerRegistry",
23
26
  "FileEventHandler",
@@ -7,6 +7,7 @@ agent delegations, and other hook-based activity for the system heartbeat.
7
7
  from datetime import datetime, timezone
8
8
  from typing import Any, Dict
9
9
 
10
+ from ....core.enums import ServiceState
10
11
  from .base import BaseEventHandler
11
12
 
12
13
 
@@ -60,6 +61,10 @@ class HookEventHandler(BaseEventHandler):
60
61
 
61
62
  hook_data = data.get("data", {})
62
63
 
64
+ # Log hook event processing
65
+ tool_name = hook_data.get("tool_name", "N/A")
66
+ self.logger.info(f"Processing hook event: {hook_event} - tool: {tool_name}")
67
+
63
68
  # Create properly formatted event for history
64
69
  # Note: add_to_history expects the event data directly, not wrapped
65
70
  history_event = {
@@ -76,6 +81,12 @@ class HookEventHandler(BaseEventHandler):
76
81
 
77
82
  # Broadcast the original event to all connected clients
78
83
  # (preserves all original fields)
84
+ connected_clients = (
85
+ len(self.server.clients) if hasattr(self.server, "clients") else 0
86
+ )
87
+ self.logger.info(
88
+ f"Broadcasting claude_event to {connected_clients} clients: {hook_event}"
89
+ )
79
90
  await self.broadcast_event("claude_event", data)
80
91
 
81
92
  # Track sessions based on hook events
@@ -108,7 +119,7 @@ class HookEventHandler(BaseEventHandler):
108
119
  "session_id": session_id,
109
120
  "start_time": datetime.now(timezone.utc).isoformat(),
110
121
  "agent": agent_type,
111
- "status": "active",
122
+ "status": ServiceState.RUNNING,
112
123
  "prompt": data.get("prompt", "")[:100], # First 100 chars
113
124
  "last_activity": datetime.now(timezone.utc).isoformat(),
114
125
  }
@@ -159,7 +170,7 @@ class HookEventHandler(BaseEventHandler):
159
170
  "session_id": session_id,
160
171
  "start_time": datetime.now(timezone.utc).isoformat(),
161
172
  "agent": "pm", # Default to PM
162
- "status": "active",
173
+ "status": ServiceState.RUNNING,
163
174
  "prompt": data.get("prompt_text", "")[:100],
164
175
  "working_directory": data.get("working_directory", ""),
165
176
  "last_activity": datetime.now(timezone.utc).isoformat(),
@@ -15,7 +15,8 @@ if TYPE_CHECKING:
15
15
 
16
16
  from ..server import SocketIOServer
17
17
 
18
- from .code_analysis import CodeAnalysisEventHandler
18
+ # DISABLED: File Tree interface removed from dashboard
19
+ # from .code_analysis import CodeAnalysisEventHandler
19
20
  from .connection import ConnectionEventHandler
20
21
  from .file import FileEventHandler
21
22
  from .git import GitEventHandler
@@ -38,7 +39,8 @@ class EventHandlerRegistry:
38
39
  HookEventHandler, # Hook events for session tracking
39
40
  GitEventHandler, # Git operations
40
41
  FileEventHandler, # File operations
41
- CodeAnalysisEventHandler, # Code analysis for dashboard
42
+ # DISABLED: File Tree interface removed from dashboard
43
+ # CodeAnalysisEventHandler, # Code analysis for dashboard
42
44
  ProjectEventHandler, # Project management (future)
43
45
  MemoryEventHandler, # Memory management (future)
44
46
  ]
@@ -16,6 +16,8 @@ from collections import deque
16
16
  from datetime import datetime, timezone
17
17
  from typing import Any, Dict, List, Optional, Set
18
18
 
19
+ from ....core.enums import ServiceState
20
+
19
21
  try:
20
22
  import aiohttp
21
23
  import socketio
@@ -265,15 +267,15 @@ class SocketIOServer(SocketIOServiceInterface):
265
267
  except Exception as e:
266
268
  self.logger.error(f"Error during EventBus teardown: {e}")
267
269
 
268
- # Stop code analysis handler
270
+ # Stop event handlers
269
271
  if self.event_registry:
270
- from ..handlers import CodeAnalysisEventHandler, ConnectionEventHandler
271
-
272
- # Stop analysis runner
273
- analysis_handler = self.event_registry.get_handler(CodeAnalysisEventHandler)
274
- if analysis_handler and hasattr(analysis_handler, "cleanup"):
275
- analysis_handler.cleanup()
272
+ from ..handlers import ConnectionEventHandler
276
273
 
274
+ # DISABLED: File Tree interface removed from dashboard
275
+ # Stop analysis runner (code analysis handler is disabled)
276
+ # analysis_handler = self.event_registry.get_handler(CodeAnalysisEventHandler)
277
+ # if analysis_handler and hasattr(analysis_handler, "cleanup"):
278
+ # analysis_handler.cleanup()
277
279
  # Stop health monitoring in connection handler
278
280
  conn_handler = self.event_registry.get_handler(ConnectionEventHandler)
279
281
  if conn_handler and hasattr(conn_handler, "stop_health_monitoring"):
@@ -384,7 +386,7 @@ class SocketIOServer(SocketIOServiceInterface):
384
386
  "session_id": session_id,
385
387
  "start_time": datetime.now(timezone.utc).isoformat(),
386
388
  "agent": "pm", # Default to PM, will be updated if delegated
387
- "status": "active",
389
+ "status": ServiceState.RUNNING,
388
390
  "launch_method": launch_method,
389
391
  "working_dir": working_dir,
390
392
  }
@@ -22,6 +22,7 @@ import tty
22
22
  from typing import Any, Dict, List, Optional
23
23
 
24
24
  from claude_mpm.core.base_service import BaseService
25
+ from claude_mpm.core.enums import OperationResult, ServiceState
25
26
  from claude_mpm.services.core.interfaces import SubprocessLauncherInterface
26
27
 
27
28
 
@@ -62,9 +63,17 @@ class SubprocessLauncherService(BaseService, SubprocessLauncherInterface):
62
63
  try:
63
64
  env = kwargs.get("env", self.prepare_subprocess_environment())
64
65
  self.launch_subprocess_interactive(command, env)
65
- return {"status": "launched", "command": command, "method": "interactive"}
66
+ return {
67
+ "status": OperationResult.SUCCESS,
68
+ "command": command,
69
+ "method": "interactive",
70
+ }
66
71
  except Exception as e:
67
- return {"status": "failed", "error": str(e), "command": command}
72
+ return {
73
+ "status": OperationResult.FAILED,
74
+ "error": str(e),
75
+ "command": command,
76
+ }
68
77
 
69
78
  async def launch_subprocess_async(
70
79
  self, command: List[str], **kwargs
@@ -109,7 +118,7 @@ class SubprocessLauncherService(BaseService, SubprocessLauncherInterface):
109
118
  # For now, return unknown status
110
119
  return {
111
120
  "process_id": process_id,
112
- "status": "unknown",
121
+ "status": OperationResult.UNKNOWN,
113
122
  "message": "Process tracking not implemented",
114
123
  }
115
124
 
@@ -160,7 +169,7 @@ class SubprocessLauncherService(BaseService, SubprocessLauncherInterface):
160
169
  # Notify WebSocket clients
161
170
  if self.websocket_server:
162
171
  self.websocket_server.claude_status_changed(
163
- status="running",
172
+ status=ServiceState.RUNNING,
164
173
  pid=process.pid,
165
174
  message="Claude subprocess started",
166
175
  )
@@ -195,7 +204,7 @@ class SubprocessLauncherService(BaseService, SubprocessLauncherInterface):
195
204
  # Notify WebSocket clients
196
205
  if self.websocket_server:
197
206
  self.websocket_server.claude_status_changed(
198
- status="stopped",
207
+ status=ServiceState.STOPPED,
199
208
  message=f"Claude subprocess exited with code {process.returncode}",
200
209
  )
201
210
 
@@ -14,6 +14,7 @@ import re
14
14
  from pathlib import Path
15
15
  from typing import Any, Dict, List, Optional
16
16
 
17
+ from claude_mpm.core.enums import OperationResult
17
18
  from claude_mpm.core.logging_utils import get_logger
18
19
 
19
20
  from ..strategies import (
@@ -120,7 +121,7 @@ class CodeAnalyzerStrategy(AnalyzerStrategy):
120
121
  return self._analyze_ast(target, options)
121
122
 
122
123
  return {
123
- "status": "error",
124
+ "status": OperationResult.ERROR,
124
125
  "message": f"Unsupported target type: {type(target).__name__}",
125
126
  }
126
127
 
@@ -159,7 +160,7 @@ class CodeAnalyzerStrategy(AnalyzerStrategy):
159
160
  metrics["maintainability_index"] = self._calculate_maintainability(metrics)
160
161
 
161
162
  return {
162
- "status": "success",
163
+ "status": OperationResult.SUCCESS,
163
164
  "type": "file",
164
165
  "path": str(file_path),
165
166
  "metrics": metrics,
@@ -168,7 +169,7 @@ class CodeAnalyzerStrategy(AnalyzerStrategy):
168
169
  except Exception as e:
169
170
  logger.error(f"Error analyzing file {file_path}: {e}")
170
171
  return {
171
- "status": "error",
172
+ "status": OperationResult.ERROR,
172
173
  "path": str(file_path),
173
174
  "error": str(e),
174
175
  }
@@ -178,7 +179,7 @@ class CodeAnalyzerStrategy(AnalyzerStrategy):
178
179
  ) -> Dict[str, Any]:
179
180
  """Analyze all code files in a directory."""
180
181
  results = {
181
- "status": "success",
182
+ "status": OperationResult.SUCCESS,
182
183
  "type": "directory",
183
184
  "path": str(dir_path),
184
185
  "files": [],
@@ -195,7 +196,7 @@ class CodeAnalyzerStrategy(AnalyzerStrategy):
195
196
  total_metrics = {}
196
197
  for file_path in code_files:
197
198
  file_result = self._analyze_file(file_path, options)
198
- if file_result["status"] == "success":
199
+ if file_result["status"] == OperationResult.SUCCESS:
199
200
  results["files"].append(file_result)
200
201
 
201
202
  # Aggregate metrics
@@ -285,7 +286,7 @@ class CodeAnalyzerStrategy(AnalyzerStrategy):
285
286
  )
286
287
 
287
288
  return {
288
- "status": "success",
289
+ "status": OperationResult.SUCCESS,
289
290
  "type": "ast",
290
291
  "metrics": metrics,
291
292
  }
@@ -426,7 +427,7 @@ class CodeAnalyzerStrategy(AnalyzerStrategy):
426
427
  """Extract key metrics from analysis results."""
427
428
  metrics = {}
428
429
 
429
- if analysis_result.get("status") != "success":
430
+ if analysis_result.get("status") != OperationResult.SUCCESS:
430
431
  return metrics
431
432
 
432
433
  # Extract relevant metrics
@@ -14,6 +14,7 @@ import re
14
14
  from pathlib import Path
15
15
  from typing import Any, ClassVar, Dict, List, Optional
16
16
 
17
+ from claude_mpm.core.enums import OperationResult
17
18
  from claude_mpm.core.logging_utils import get_logger
18
19
 
19
20
  from ..strategies import (
@@ -166,7 +167,7 @@ class DependencyAnalyzerStrategy(AnalyzerStrategy):
166
167
  return self._analyze_manifest(target_path, options)
167
168
 
168
169
  return {
169
- "status": "error",
170
+ "status": OperationResult.ERROR,
170
171
  "message": f"Unsupported target type: {type(target).__name__}",
171
172
  }
172
173
 
@@ -175,7 +176,7 @@ class DependencyAnalyzerStrategy(AnalyzerStrategy):
175
176
  ) -> Dict[str, Any]:
176
177
  """Analyze dependencies in a project directory."""
177
178
  results = {
178
- "status": "success",
179
+ "status": OperationResult.SUCCESS,
179
180
  "type": "project",
180
181
  "path": str(project_path),
181
182
  "package_managers": [],
@@ -221,7 +222,7 @@ class DependencyAnalyzerStrategy(AnalyzerStrategy):
221
222
  ) -> Dict[str, Any]:
222
223
  """Analyze a specific package manifest file."""
223
224
  results = {
224
- "status": "success",
225
+ "status": OperationResult.SUCCESS,
225
226
  "type": "manifest",
226
227
  "path": str(manifest_path),
227
228
  "dependencies": {},
@@ -238,7 +239,7 @@ class DependencyAnalyzerStrategy(AnalyzerStrategy):
238
239
 
239
240
  if not manager:
240
241
  return {
241
- "status": "error",
242
+ "status": OperationResult.ERROR,
242
243
  "message": f"Unknown manifest file: {manifest_path.name}",
243
244
  }
244
245
 
@@ -598,7 +599,7 @@ class DependencyAnalyzerStrategy(AnalyzerStrategy):
598
599
  """Extract key metrics from analysis results."""
599
600
  metrics = {}
600
601
 
601
- if analysis_result.get("status") != "success":
602
+ if analysis_result.get("status") != OperationResult.SUCCESS:
602
603
  return metrics
603
604
 
604
605
  # Extract dependency counts
@@ -14,6 +14,7 @@ import re
14
14
  from pathlib import Path
15
15
  from typing import Any, ClassVar, Dict, List, Optional
16
16
 
17
+ from claude_mpm.core.enums import OperationResult
17
18
  from claude_mpm.core.logging_utils import get_logger
18
19
 
19
20
  from ..strategies import (
@@ -188,14 +189,14 @@ class PerformanceAnalyzerStrategy(AnalyzerStrategy):
188
189
  return self._analyze_ast_performance(target, options)
189
190
 
190
191
  return {
191
- "status": "error",
192
+ "status": OperationResult.ERROR,
192
193
  "message": f"Unsupported target type: {type(target).__name__}",
193
194
  }
194
195
 
195
196
  def _analyze_file(self, file_path: Path, options: Dict[str, Any]) -> Dict[str, Any]:
196
197
  """Analyze a single file for performance issues."""
197
198
  results = {
198
- "status": "success",
199
+ "status": OperationResult.SUCCESS,
199
200
  "type": "file",
200
201
  "path": str(file_path),
201
202
  "issues": [],
@@ -240,7 +241,7 @@ class PerformanceAnalyzerStrategy(AnalyzerStrategy):
240
241
 
241
242
  except Exception as e:
242
243
  logger.error(f"Error analyzing file {file_path}: {e}")
243
- results["status"] = "error"
244
+ results["status"] = OperationResult.ERROR
244
245
  results["error"] = str(e)
245
246
 
246
247
  return results
@@ -250,7 +251,7 @@ class PerformanceAnalyzerStrategy(AnalyzerStrategy):
250
251
  ) -> Dict[str, Any]:
251
252
  """Analyze all files in a directory for performance issues."""
252
253
  results = {
253
- "status": "success",
254
+ "status": OperationResult.SUCCESS,
254
255
  "type": "directory",
255
256
  "path": str(dir_path),
256
257
  "files_analyzed": 0,
@@ -291,7 +292,7 @@ class PerformanceAnalyzerStrategy(AnalyzerStrategy):
291
292
  continue
292
293
 
293
294
  file_result = self._analyze_file(file_path, options)
294
- if file_result["status"] == "success":
295
+ if file_result["status"] == OperationResult.SUCCESS:
295
296
  results["files_analyzed"] += 1
296
297
  total_score += file_result["performance_score"]
297
298
 
@@ -654,7 +655,7 @@ class PerformanceAnalyzerStrategy(AnalyzerStrategy):
654
655
  ) -> Dict[str, Any]:
655
656
  """Analyze performance of an AST node."""
656
657
  results = {
657
- "status": "success",
658
+ "status": OperationResult.SUCCESS,
658
659
  "type": "ast",
659
660
  "complexity": {},
660
661
  "issues": [],
@@ -802,7 +803,7 @@ class PerformanceAnalyzerStrategy(AnalyzerStrategy):
802
803
  """Extract key metrics from analysis results."""
803
804
  metrics = {}
804
805
 
805
- if analysis_result.get("status") != "success":
806
+ if analysis_result.get("status") != OperationResult.SUCCESS:
806
807
  return metrics
807
808
 
808
809
  if analysis_result.get("type") == "file":
@@ -14,6 +14,7 @@ import re
14
14
  from pathlib import Path
15
15
  from typing import Any, ClassVar, Dict, List, Optional
16
16
 
17
+ from claude_mpm.core.enums import OperationResult
17
18
  from claude_mpm.core.logging_utils import get_logger
18
19
 
19
20
  from ..strategies import (
@@ -198,14 +199,14 @@ class SecurityAnalyzerStrategy(AnalyzerStrategy):
198
199
  return self._analyze_directory(target_path, options)
199
200
 
200
201
  return {
201
- "status": "error",
202
+ "status": OperationResult.ERROR,
202
203
  "message": f"Unsupported target type: {type(target).__name__}",
203
204
  }
204
205
 
205
206
  def _analyze_file(self, file_path: Path, options: Dict[str, Any]) -> Dict[str, Any]:
206
207
  """Analyze a single file for security issues."""
207
208
  results = {
208
- "status": "success",
209
+ "status": OperationResult.SUCCESS,
209
210
  "type": "file",
210
211
  "path": str(file_path),
211
212
  "vulnerabilities": [],
@@ -241,7 +242,7 @@ class SecurityAnalyzerStrategy(AnalyzerStrategy):
241
242
 
242
243
  except Exception as e:
243
244
  logger.error(f"Error analyzing file {file_path}: {e}")
244
- results["status"] = "error"
245
+ results["status"] = OperationResult.ERROR
245
246
  results["error"] = str(e)
246
247
 
247
248
  return results
@@ -251,7 +252,7 @@ class SecurityAnalyzerStrategy(AnalyzerStrategy):
251
252
  ) -> Dict[str, Any]:
252
253
  """Analyze all files in a directory for security issues."""
253
254
  results = {
254
- "status": "success",
255
+ "status": OperationResult.SUCCESS,
255
256
  "type": "directory",
256
257
  "path": str(dir_path),
257
258
  "files_analyzed": 0,
@@ -301,7 +302,7 @@ class SecurityAnalyzerStrategy(AnalyzerStrategy):
301
302
 
302
303
  file_result = self._analyze_file(file_path, options)
303
304
  if (
304
- file_result["status"] == "success"
305
+ file_result["status"] == OperationResult.SUCCESS
305
306
  and file_result["vulnerabilities"]
306
307
  ):
307
308
  results["files"].append(file_result)
@@ -645,7 +646,7 @@ class SecurityAnalyzerStrategy(AnalyzerStrategy):
645
646
  """Extract key metrics from analysis results."""
646
647
  metrics = {}
647
648
 
648
- if analysis_result.get("status") != "success":
649
+ if analysis_result.get("status") != OperationResult.SUCCESS:
649
650
  return metrics
650
651
 
651
652
  if analysis_result.get("type") == "file":
@@ -13,6 +13,7 @@ import fnmatch
13
13
  from pathlib import Path
14
14
  from typing import Any, ClassVar, Dict, List, Optional, Tuple
15
15
 
16
+ from claude_mpm.core.enums import OperationResult
16
17
  from claude_mpm.core.logging_utils import get_logger
17
18
 
18
19
  from ..strategies import (
@@ -174,14 +175,14 @@ class StructureAnalyzerStrategy(AnalyzerStrategy):
174
175
 
175
176
  if not target_path.is_dir():
176
177
  return {
177
- "status": "error",
178
+ "status": OperationResult.ERROR,
178
179
  "message": "Target must be a directory",
179
180
  }
180
181
 
181
182
  return self._analyze_structure(target_path, options)
182
183
 
183
184
  return {
184
- "status": "error",
185
+ "status": OperationResult.ERROR,
185
186
  "message": f"Unsupported target type: {type(target).__name__}",
186
187
  }
187
188
 
@@ -190,7 +191,7 @@ class StructureAnalyzerStrategy(AnalyzerStrategy):
190
191
  ) -> Dict[str, Any]:
191
192
  """Analyze the structure of a project directory."""
192
193
  results = {
193
- "status": "success",
194
+ "status": OperationResult.SUCCESS,
194
195
  "type": "structure",
195
196
  "path": str(root_path),
196
197
  "tree": {},
@@ -640,7 +641,7 @@ class StructureAnalyzerStrategy(AnalyzerStrategy):
640
641
  """Extract key metrics from analysis results."""
641
642
  metrics = {}
642
643
 
643
- if analysis_result.get("status") != "success":
644
+ if analysis_result.get("status") != OperationResult.SUCCESS:
644
645
  return metrics
645
646
 
646
647
  # Extract structure statistics