claude-mpm 3.9.11__py3-none-any.whl → 4.0.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 (434) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/__init__.py +2 -2
  3. claude_mpm/__main__.py +3 -2
  4. claude_mpm/agents/__init__.py +85 -79
  5. claude_mpm/agents/agent_loader.py +464 -1003
  6. claude_mpm/agents/agent_loader_integration.py +45 -45
  7. claude_mpm/agents/agents_metadata.py +29 -30
  8. claude_mpm/agents/async_agent_loader.py +156 -138
  9. claude_mpm/agents/base_agent.json +1 -1
  10. claude_mpm/agents/base_agent_loader.py +179 -151
  11. claude_mpm/agents/frontmatter_validator.py +229 -130
  12. claude_mpm/agents/schema/agent_schema.json +1 -1
  13. claude_mpm/agents/system_agent_config.py +213 -147
  14. claude_mpm/agents/templates/__init__.py +13 -13
  15. claude_mpm/agents/templates/code_analyzer.json +2 -2
  16. claude_mpm/agents/templates/data_engineer.json +1 -1
  17. claude_mpm/agents/templates/documentation.json +23 -11
  18. claude_mpm/agents/templates/engineer.json +22 -6
  19. claude_mpm/agents/templates/memory_manager.json +1 -1
  20. claude_mpm/agents/templates/ops.json +2 -2
  21. claude_mpm/agents/templates/project_organizer.json +1 -1
  22. claude_mpm/agents/templates/qa.json +1 -1
  23. claude_mpm/agents/templates/refactoring_engineer.json +222 -0
  24. claude_mpm/agents/templates/research.json +20 -14
  25. claude_mpm/agents/templates/security.json +1 -1
  26. claude_mpm/agents/templates/ticketing.json +2 -2
  27. claude_mpm/agents/templates/version_control.json +1 -1
  28. claude_mpm/agents/templates/web_qa.json +3 -1
  29. claude_mpm/agents/templates/web_ui.json +2 -2
  30. claude_mpm/cli/__init__.py +79 -51
  31. claude_mpm/cli/__main__.py +3 -2
  32. claude_mpm/cli/commands/__init__.py +20 -20
  33. claude_mpm/cli/commands/agents.py +279 -247
  34. claude_mpm/cli/commands/aggregate.py +138 -157
  35. claude_mpm/cli/commands/cleanup.py +147 -147
  36. claude_mpm/cli/commands/config.py +93 -76
  37. claude_mpm/cli/commands/info.py +17 -16
  38. claude_mpm/cli/commands/mcp.py +140 -905
  39. claude_mpm/cli/commands/mcp_command_router.py +139 -0
  40. claude_mpm/cli/commands/mcp_config_commands.py +20 -0
  41. claude_mpm/cli/commands/mcp_install_commands.py +20 -0
  42. claude_mpm/cli/commands/mcp_server_commands.py +175 -0
  43. claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
  44. claude_mpm/cli/commands/memory.py +239 -203
  45. claude_mpm/cli/commands/monitor.py +330 -86
  46. claude_mpm/cli/commands/run.py +380 -429
  47. claude_mpm/cli/commands/run_config_checker.py +160 -0
  48. claude_mpm/cli/commands/socketio_monitor.py +235 -0
  49. claude_mpm/cli/commands/tickets.py +363 -220
  50. claude_mpm/cli/parser.py +24 -1156
  51. claude_mpm/cli/parsers/__init__.py +29 -0
  52. claude_mpm/cli/parsers/agents_parser.py +136 -0
  53. claude_mpm/cli/parsers/base_parser.py +331 -0
  54. claude_mpm/cli/parsers/config_parser.py +85 -0
  55. claude_mpm/cli/parsers/mcp_parser.py +152 -0
  56. claude_mpm/cli/parsers/memory_parser.py +138 -0
  57. claude_mpm/cli/parsers/monitor_parser.py +124 -0
  58. claude_mpm/cli/parsers/run_parser.py +147 -0
  59. claude_mpm/cli/parsers/tickets_parser.py +203 -0
  60. claude_mpm/cli/ticket_cli.py +7 -3
  61. claude_mpm/cli/utils.py +55 -37
  62. claude_mpm/cli_module/__init__.py +6 -6
  63. claude_mpm/cli_module/args.py +188 -140
  64. claude_mpm/cli_module/commands.py +79 -70
  65. claude_mpm/cli_module/migration_example.py +38 -60
  66. claude_mpm/config/__init__.py +32 -25
  67. claude_mpm/config/agent_config.py +151 -119
  68. claude_mpm/config/experimental_features.py +71 -73
  69. claude_mpm/config/paths.py +94 -208
  70. claude_mpm/config/socketio_config.py +84 -73
  71. claude_mpm/constants.py +35 -18
  72. claude_mpm/core/__init__.py +9 -6
  73. claude_mpm/core/agent_name_normalizer.py +68 -71
  74. claude_mpm/core/agent_registry.py +372 -521
  75. claude_mpm/core/agent_session_manager.py +74 -63
  76. claude_mpm/core/base_service.py +116 -87
  77. claude_mpm/core/cache.py +119 -153
  78. claude_mpm/core/claude_runner.py +425 -1120
  79. claude_mpm/core/config.py +263 -168
  80. claude_mpm/core/config_aliases.py +69 -61
  81. claude_mpm/core/config_constants.py +292 -0
  82. claude_mpm/core/constants.py +57 -99
  83. claude_mpm/core/container.py +211 -178
  84. claude_mpm/core/exceptions.py +233 -89
  85. claude_mpm/core/factories.py +92 -54
  86. claude_mpm/core/framework_loader.py +378 -220
  87. claude_mpm/core/hook_manager.py +198 -83
  88. claude_mpm/core/hook_performance_config.py +136 -0
  89. claude_mpm/core/injectable_service.py +61 -55
  90. claude_mpm/core/interactive_session.py +165 -155
  91. claude_mpm/core/interfaces.py +221 -195
  92. claude_mpm/core/lazy.py +96 -96
  93. claude_mpm/core/logger.py +133 -107
  94. claude_mpm/core/logging_config.py +185 -157
  95. claude_mpm/core/minimal_framework_loader.py +20 -15
  96. claude_mpm/core/mixins.py +30 -29
  97. claude_mpm/core/oneshot_session.py +215 -181
  98. claude_mpm/core/optimized_agent_loader.py +134 -138
  99. claude_mpm/core/optimized_startup.py +159 -157
  100. claude_mpm/core/pm_hook_interceptor.py +85 -72
  101. claude_mpm/core/service_registry.py +103 -101
  102. claude_mpm/core/session_manager.py +97 -87
  103. claude_mpm/core/socketio_pool.py +212 -158
  104. claude_mpm/core/tool_access_control.py +58 -51
  105. claude_mpm/core/types.py +46 -24
  106. claude_mpm/core/typing_utils.py +166 -82
  107. claude_mpm/core/unified_agent_registry.py +721 -0
  108. claude_mpm/core/unified_config.py +550 -0
  109. claude_mpm/core/unified_paths.py +549 -0
  110. claude_mpm/dashboard/index.html +1 -1
  111. claude_mpm/dashboard/open_dashboard.py +51 -17
  112. claude_mpm/dashboard/static/built/components/agent-inference.js +2 -0
  113. claude_mpm/dashboard/static/built/components/event-processor.js +2 -0
  114. claude_mpm/dashboard/static/built/components/event-viewer.js +2 -0
  115. claude_mpm/dashboard/static/built/components/export-manager.js +2 -0
  116. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +2 -0
  117. claude_mpm/dashboard/static/built/components/hud-library-loader.js +2 -0
  118. claude_mpm/dashboard/static/built/components/hud-manager.js +2 -0
  119. claude_mpm/dashboard/static/built/components/hud-visualizer.js +2 -0
  120. claude_mpm/dashboard/static/built/components/module-viewer.js +2 -0
  121. claude_mpm/dashboard/static/built/components/session-manager.js +2 -0
  122. claude_mpm/dashboard/static/built/components/socket-manager.js +2 -0
  123. claude_mpm/dashboard/static/built/components/ui-state-manager.js +2 -0
  124. claude_mpm/dashboard/static/built/components/working-directory.js +2 -0
  125. claude_mpm/dashboard/static/built/dashboard.js +2 -0
  126. claude_mpm/dashboard/static/built/socket-client.js +2 -0
  127. claude_mpm/dashboard/static/css/dashboard.css +27 -8
  128. claude_mpm/dashboard/static/dist/components/agent-inference.js +2 -0
  129. claude_mpm/dashboard/static/dist/components/event-processor.js +2 -0
  130. claude_mpm/dashboard/static/dist/components/event-viewer.js +2 -0
  131. claude_mpm/dashboard/static/dist/components/export-manager.js +2 -0
  132. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +2 -0
  133. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +2 -0
  134. claude_mpm/dashboard/static/dist/components/hud-manager.js +2 -0
  135. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +2 -0
  136. claude_mpm/dashboard/static/dist/components/module-viewer.js +2 -0
  137. claude_mpm/dashboard/static/dist/components/session-manager.js +2 -0
  138. claude_mpm/dashboard/static/dist/components/socket-manager.js +2 -0
  139. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +2 -0
  140. claude_mpm/dashboard/static/dist/components/working-directory.js +2 -0
  141. claude_mpm/dashboard/static/dist/dashboard.js +2 -0
  142. claude_mpm/dashboard/static/dist/socket-client.js +2 -0
  143. claude_mpm/dashboard/static/js/components/agent-inference.js +80 -76
  144. claude_mpm/dashboard/static/js/components/event-processor.js +71 -67
  145. claude_mpm/dashboard/static/js/components/event-viewer.js +93 -72
  146. claude_mpm/dashboard/static/js/components/export-manager.js +31 -28
  147. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +110 -96
  148. claude_mpm/dashboard/static/js/components/hud-library-loader.js +11 -11
  149. claude_mpm/dashboard/static/js/components/hud-manager.js +73 -73
  150. claude_mpm/dashboard/static/js/components/hud-visualizer.js +163 -163
  151. claude_mpm/dashboard/static/js/components/module-viewer.js +305 -233
  152. claude_mpm/dashboard/static/js/components/session-manager.js +32 -29
  153. claude_mpm/dashboard/static/js/components/socket-manager.js +27 -20
  154. claude_mpm/dashboard/static/js/components/ui-state-manager.js +21 -18
  155. claude_mpm/dashboard/static/js/components/working-directory.js +74 -71
  156. claude_mpm/dashboard/static/js/dashboard.js +178 -453
  157. claude_mpm/dashboard/static/js/extension-error-handler.js +164 -0
  158. claude_mpm/dashboard/static/js/socket-client.js +133 -53
  159. claude_mpm/dashboard/templates/index.html +40 -50
  160. claude_mpm/experimental/cli_enhancements.py +60 -58
  161. claude_mpm/generators/__init__.py +1 -1
  162. claude_mpm/generators/agent_profile_generator.py +75 -65
  163. claude_mpm/hooks/__init__.py +1 -1
  164. claude_mpm/hooks/base_hook.py +33 -28
  165. claude_mpm/hooks/claude_hooks/__init__.py +1 -1
  166. claude_mpm/hooks/claude_hooks/connection_pool.py +120 -0
  167. claude_mpm/hooks/claude_hooks/event_handlers.py +743 -0
  168. claude_mpm/hooks/claude_hooks/hook_handler.py +415 -1331
  169. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +4 -4
  170. claude_mpm/hooks/claude_hooks/memory_integration.py +221 -0
  171. claude_mpm/hooks/claude_hooks/response_tracking.py +348 -0
  172. claude_mpm/hooks/claude_hooks/tool_analysis.py +230 -0
  173. claude_mpm/hooks/memory_integration_hook.py +140 -100
  174. claude_mpm/hooks/tool_call_interceptor.py +89 -76
  175. claude_mpm/hooks/validation_hooks.py +57 -49
  176. claude_mpm/init.py +145 -121
  177. claude_mpm/models/__init__.py +9 -9
  178. claude_mpm/models/agent_definition.py +33 -23
  179. claude_mpm/models/agent_session.py +228 -200
  180. claude_mpm/scripts/__init__.py +1 -1
  181. claude_mpm/scripts/socketio_daemon.py +192 -75
  182. claude_mpm/scripts/socketio_server_manager.py +328 -0
  183. claude_mpm/scripts/start_activity_logging.py +25 -22
  184. claude_mpm/services/__init__.py +68 -43
  185. claude_mpm/services/agent_capabilities_service.py +271 -0
  186. claude_mpm/services/agents/__init__.py +23 -32
  187. claude_mpm/services/agents/deployment/__init__.py +3 -3
  188. claude_mpm/services/agents/deployment/agent_config_provider.py +310 -0
  189. claude_mpm/services/agents/deployment/agent_configuration_manager.py +359 -0
  190. claude_mpm/services/agents/deployment/agent_definition_factory.py +84 -0
  191. claude_mpm/services/agents/deployment/agent_deployment.py +415 -2113
  192. claude_mpm/services/agents/deployment/agent_discovery_service.py +387 -0
  193. claude_mpm/services/agents/deployment/agent_environment_manager.py +293 -0
  194. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +387 -0
  195. claude_mpm/services/agents/deployment/agent_format_converter.py +453 -0
  196. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +161 -0
  197. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +345 -495
  198. claude_mpm/services/agents/deployment/agent_metrics_collector.py +279 -0
  199. claude_mpm/services/agents/deployment/agent_restore_handler.py +88 -0
  200. claude_mpm/services/agents/deployment/agent_template_builder.py +406 -0
  201. claude_mpm/services/agents/deployment/agent_validator.py +352 -0
  202. claude_mpm/services/agents/deployment/agent_version_manager.py +313 -0
  203. claude_mpm/services/agents/deployment/agent_versioning.py +6 -9
  204. claude_mpm/services/agents/deployment/agents_directory_resolver.py +79 -0
  205. claude_mpm/services/agents/deployment/async_agent_deployment.py +298 -234
  206. claude_mpm/services/agents/deployment/config/__init__.py +13 -0
  207. claude_mpm/services/agents/deployment/config/deployment_config.py +182 -0
  208. claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
  209. claude_mpm/services/agents/deployment/deployment_config_loader.py +54 -0
  210. claude_mpm/services/agents/deployment/deployment_type_detector.py +124 -0
  211. claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
  212. claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
  213. claude_mpm/services/agents/deployment/facade/deployment_executor.py +73 -0
  214. claude_mpm/services/agents/deployment/facade/deployment_facade.py +270 -0
  215. claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
  216. claude_mpm/services/agents/deployment/interface_adapter.py +227 -0
  217. claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
  218. claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
  219. claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
  220. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
  221. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +159 -0
  222. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
  223. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
  224. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +195 -0
  225. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +119 -0
  226. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +79 -0
  227. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +90 -0
  228. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +100 -0
  229. claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
  230. claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +98 -0
  231. claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
  232. claude_mpm/services/agents/deployment/processors/agent_processor.py +258 -0
  233. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +318 -0
  234. claude_mpm/services/agents/deployment/results/__init__.py +13 -0
  235. claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
  236. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
  237. claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
  238. claude_mpm/services/agents/deployment/strategies/base_strategy.py +119 -0
  239. claude_mpm/services/agents/deployment/strategies/project_strategy.py +150 -0
  240. claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
  241. claude_mpm/services/agents/deployment/strategies/system_strategy.py +116 -0
  242. claude_mpm/services/agents/deployment/strategies/user_strategy.py +137 -0
  243. claude_mpm/services/agents/deployment/system_instructions_deployer.py +108 -0
  244. claude_mpm/services/agents/deployment/validation/__init__.py +19 -0
  245. claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
  246. claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
  247. claude_mpm/services/agents/deployment/validation/template_validator.py +299 -0
  248. claude_mpm/services/agents/deployment/validation/validation_result.py +226 -0
  249. claude_mpm/services/agents/loading/__init__.py +2 -2
  250. claude_mpm/services/agents/loading/agent_profile_loader.py +259 -229
  251. claude_mpm/services/agents/loading/base_agent_manager.py +90 -81
  252. claude_mpm/services/agents/loading/framework_agent_loader.py +154 -129
  253. claude_mpm/services/agents/management/__init__.py +2 -2
  254. claude_mpm/services/agents/management/agent_capabilities_generator.py +72 -58
  255. claude_mpm/services/agents/management/agent_management_service.py +209 -156
  256. claude_mpm/services/agents/memory/__init__.py +9 -6
  257. claude_mpm/services/agents/memory/agent_memory_manager.py +218 -1152
  258. claude_mpm/services/agents/memory/agent_persistence_service.py +20 -16
  259. claude_mpm/services/agents/memory/analyzer.py +430 -0
  260. claude_mpm/services/agents/memory/content_manager.py +376 -0
  261. claude_mpm/services/agents/memory/template_generator.py +468 -0
  262. claude_mpm/services/agents/registry/__init__.py +7 -10
  263. claude_mpm/services/agents/registry/deployed_agent_discovery.py +122 -97
  264. claude_mpm/services/agents/registry/modification_tracker.py +351 -285
  265. claude_mpm/services/async_session_logger.py +187 -153
  266. claude_mpm/services/claude_session_logger.py +87 -72
  267. claude_mpm/services/command_handler_service.py +217 -0
  268. claude_mpm/services/communication/__init__.py +3 -2
  269. claude_mpm/services/core/__init__.py +50 -97
  270. claude_mpm/services/core/base.py +60 -53
  271. claude_mpm/services/core/interfaces/__init__.py +188 -0
  272. claude_mpm/services/core/interfaces/agent.py +351 -0
  273. claude_mpm/services/core/interfaces/communication.py +343 -0
  274. claude_mpm/services/core/interfaces/infrastructure.py +413 -0
  275. claude_mpm/services/core/interfaces/service.py +434 -0
  276. claude_mpm/services/core/interfaces.py +19 -944
  277. claude_mpm/services/event_aggregator.py +208 -170
  278. claude_mpm/services/exceptions.py +387 -308
  279. claude_mpm/services/framework_claude_md_generator/__init__.py +75 -79
  280. claude_mpm/services/framework_claude_md_generator/content_assembler.py +69 -60
  281. claude_mpm/services/framework_claude_md_generator/content_validator.py +65 -61
  282. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +68 -49
  283. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +34 -34
  284. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +25 -22
  285. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +10 -10
  286. claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +4 -3
  287. claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
  288. claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
  289. claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
  290. claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
  291. claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +4 -3
  292. claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
  293. claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
  294. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +4 -3
  295. claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +5 -4
  296. claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
  297. claude_mpm/services/framework_claude_md_generator/version_manager.py +30 -28
  298. claude_mpm/services/hook_service.py +106 -114
  299. claude_mpm/services/infrastructure/__init__.py +7 -5
  300. claude_mpm/services/infrastructure/context_preservation.py +233 -199
  301. claude_mpm/services/infrastructure/daemon_manager.py +279 -0
  302. claude_mpm/services/infrastructure/logging.py +83 -76
  303. claude_mpm/services/infrastructure/monitoring.py +547 -404
  304. claude_mpm/services/mcp_gateway/__init__.py +30 -13
  305. claude_mpm/services/mcp_gateway/config/__init__.py +2 -2
  306. claude_mpm/services/mcp_gateway/config/config_loader.py +61 -56
  307. claude_mpm/services/mcp_gateway/config/config_schema.py +50 -41
  308. claude_mpm/services/mcp_gateway/config/configuration.py +82 -75
  309. claude_mpm/services/mcp_gateway/core/__init__.py +13 -20
  310. claude_mpm/services/mcp_gateway/core/base.py +80 -67
  311. claude_mpm/services/mcp_gateway/core/exceptions.py +60 -46
  312. claude_mpm/services/mcp_gateway/core/interfaces.py +87 -84
  313. claude_mpm/services/mcp_gateway/main.py +287 -137
  314. claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
  315. claude_mpm/services/mcp_gateway/registry/service_registry.py +97 -94
  316. claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
  317. claude_mpm/services/mcp_gateway/server/__init__.py +2 -2
  318. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +105 -110
  319. claude_mpm/services/mcp_gateway/server/stdio_handler.py +105 -107
  320. claude_mpm/services/mcp_gateway/server/stdio_server.py +691 -0
  321. claude_mpm/services/mcp_gateway/tools/__init__.py +4 -2
  322. claude_mpm/services/mcp_gateway/tools/base_adapter.py +109 -119
  323. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +283 -215
  324. claude_mpm/services/mcp_gateway/tools/hello_world.py +122 -120
  325. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +652 -0
  326. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +606 -0
  327. claude_mpm/services/memory/__init__.py +2 -2
  328. claude_mpm/services/memory/builder.py +451 -362
  329. claude_mpm/services/memory/cache/__init__.py +2 -2
  330. claude_mpm/services/memory/cache/shared_prompt_cache.py +232 -194
  331. claude_mpm/services/memory/cache/simple_cache.py +107 -93
  332. claude_mpm/services/memory/indexed_memory.py +195 -193
  333. claude_mpm/services/memory/optimizer.py +267 -234
  334. claude_mpm/services/memory/router.py +571 -263
  335. claude_mpm/services/memory_hook_service.py +237 -0
  336. claude_mpm/services/port_manager.py +575 -0
  337. claude_mpm/services/project/__init__.py +3 -3
  338. claude_mpm/services/project/analyzer.py +451 -305
  339. claude_mpm/services/project/registry.py +262 -240
  340. claude_mpm/services/recovery_manager.py +287 -231
  341. claude_mpm/services/response_tracker.py +87 -67
  342. claude_mpm/services/runner_configuration_service.py +587 -0
  343. claude_mpm/services/session_management_service.py +304 -0
  344. claude_mpm/services/socketio/__init__.py +4 -4
  345. claude_mpm/services/socketio/client_proxy.py +174 -0
  346. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  347. claude_mpm/services/socketio/handlers/base.py +44 -30
  348. claude_mpm/services/socketio/handlers/connection.py +166 -64
  349. claude_mpm/services/socketio/handlers/file.py +123 -108
  350. claude_mpm/services/socketio/handlers/git.py +607 -373
  351. claude_mpm/services/socketio/handlers/hook.py +185 -0
  352. claude_mpm/services/socketio/handlers/memory.py +4 -4
  353. claude_mpm/services/socketio/handlers/project.py +4 -4
  354. claude_mpm/services/socketio/handlers/registry.py +53 -38
  355. claude_mpm/services/socketio/server/__init__.py +18 -0
  356. claude_mpm/services/socketio/server/broadcaster.py +252 -0
  357. claude_mpm/services/socketio/server/core.py +399 -0
  358. claude_mpm/services/socketio/server/main.py +323 -0
  359. claude_mpm/services/socketio_client_manager.py +160 -133
  360. claude_mpm/services/socketio_server.py +36 -1885
  361. claude_mpm/services/subprocess_launcher_service.py +316 -0
  362. claude_mpm/services/system_instructions_service.py +258 -0
  363. claude_mpm/services/ticket_manager.py +19 -533
  364. claude_mpm/services/utility_service.py +285 -0
  365. claude_mpm/services/version_control/__init__.py +18 -21
  366. claude_mpm/services/version_control/branch_strategy.py +20 -10
  367. claude_mpm/services/version_control/conflict_resolution.py +37 -13
  368. claude_mpm/services/version_control/git_operations.py +52 -21
  369. claude_mpm/services/version_control/semantic_versioning.py +92 -53
  370. claude_mpm/services/version_control/version_parser.py +145 -125
  371. claude_mpm/services/version_service.py +270 -0
  372. claude_mpm/storage/__init__.py +2 -2
  373. claude_mpm/storage/state_storage.py +177 -181
  374. claude_mpm/ticket_wrapper.py +2 -2
  375. claude_mpm/utils/__init__.py +2 -2
  376. claude_mpm/utils/agent_dependency_loader.py +453 -243
  377. claude_mpm/utils/config_manager.py +157 -118
  378. claude_mpm/utils/console.py +1 -1
  379. claude_mpm/utils/dependency_cache.py +102 -107
  380. claude_mpm/utils/dependency_manager.py +52 -47
  381. claude_mpm/utils/dependency_strategies.py +131 -96
  382. claude_mpm/utils/environment_context.py +110 -102
  383. claude_mpm/utils/error_handler.py +75 -55
  384. claude_mpm/utils/file_utils.py +80 -67
  385. claude_mpm/utils/framework_detection.py +12 -11
  386. claude_mpm/utils/import_migration_example.py +12 -60
  387. claude_mpm/utils/imports.py +48 -45
  388. claude_mpm/utils/path_operations.py +100 -93
  389. claude_mpm/utils/robust_installer.py +172 -164
  390. claude_mpm/utils/session_logging.py +30 -23
  391. claude_mpm/utils/subprocess_utils.py +99 -61
  392. claude_mpm/validation/__init__.py +1 -1
  393. claude_mpm/validation/agent_validator.py +151 -111
  394. claude_mpm/validation/frontmatter_validator.py +92 -71
  395. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/METADATA +90 -22
  396. claude_mpm-4.0.4.dist-info/RECORD +417 -0
  397. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/entry_points.txt +1 -0
  398. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/licenses/LICENSE +1 -1
  399. claude_mpm/cli/commands/run_guarded.py +0 -511
  400. claude_mpm/config/memory_guardian_config.py +0 -325
  401. claude_mpm/config/memory_guardian_yaml.py +0 -335
  402. claude_mpm/core/config_paths.py +0 -150
  403. claude_mpm/core/memory_aware_runner.py +0 -353
  404. claude_mpm/dashboard/static/js/dashboard-original.js +0 -4134
  405. claude_mpm/deployment_paths.py +0 -261
  406. claude_mpm/hooks/claude_hooks/hook_handler_fixed.py +0 -454
  407. claude_mpm/models/state_models.py +0 -433
  408. claude_mpm/services/agent/__init__.py +0 -24
  409. claude_mpm/services/agent/deployment.py +0 -2548
  410. claude_mpm/services/agent/management.py +0 -598
  411. claude_mpm/services/agent/registry.py +0 -813
  412. claude_mpm/services/agents/registry/agent_registry.py +0 -813
  413. claude_mpm/services/communication/socketio.py +0 -1935
  414. claude_mpm/services/communication/websocket.py +0 -479
  415. claude_mpm/services/framework_claude_md_generator.py +0 -624
  416. claude_mpm/services/health_monitor.py +0 -893
  417. claude_mpm/services/infrastructure/graceful_degradation.py +0 -616
  418. claude_mpm/services/infrastructure/health_monitor.py +0 -775
  419. claude_mpm/services/infrastructure/memory_dashboard.py +0 -479
  420. claude_mpm/services/infrastructure/memory_guardian.py +0 -944
  421. claude_mpm/services/infrastructure/restart_protection.py +0 -642
  422. claude_mpm/services/infrastructure/state_manager.py +0 -774
  423. claude_mpm/services/mcp_gateway/manager.py +0 -334
  424. claude_mpm/services/optimized_hook_service.py +0 -542
  425. claude_mpm/services/project_analyzer.py +0 -864
  426. claude_mpm/services/project_registry.py +0 -608
  427. claude_mpm/services/standalone_socketio_server.py +0 -1300
  428. claude_mpm/services/ticket_manager_di.py +0 -318
  429. claude_mpm/services/ticketing_service_original.py +0 -510
  430. claude_mpm/utils/paths.py +0 -395
  431. claude_mpm/utils/platform_memory.py +0 -524
  432. claude_mpm-3.9.11.dist-info/RECORD +0 -306
  433. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/WHEEL +0 -0
  434. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,606 @@
1
+ """
2
+ Unified Ticket Tool for MCP Gateway
3
+ ====================================
4
+
5
+ Provides a single, unified interface for all ticket management operations
6
+ through the MCP Gateway, consolidating create, list, update, view, and search
7
+ functionality into one tool with an operation parameter.
8
+
9
+ WHY: Having 5 separate ticket tools creates unnecessary complexity. A single
10
+ tool with an operation parameter provides a cleaner, more intuitive API that
11
+ matches the mental model of "ticket operations" better.
12
+
13
+ DESIGN DECISIONS:
14
+ - Single tool with operation parameter for cleaner API
15
+ - Conditional parameter validation based on operation type
16
+ - Reuses existing logic from separate tools for consistency
17
+ - Maintains same error handling and metrics tracking patterns
18
+ - Uses JSON Schema oneOf for operation-specific parameter validation
19
+ """
20
+
21
+ import asyncio
22
+ import json
23
+ import re
24
+ import subprocess
25
+ from datetime import datetime
26
+ from typing import Any, Dict, List, Optional
27
+
28
+ from claude_mpm.services.mcp_gateway.core.interfaces import (
29
+ MCPToolDefinition,
30
+ MCPToolInvocation,
31
+ MCPToolResult,
32
+ )
33
+ from claude_mpm.services.mcp_gateway.tools.base_adapter import BaseToolAdapter
34
+
35
+
36
+ class UnifiedTicketTool(BaseToolAdapter):
37
+ """
38
+ Unified ticket management tool for aitrackdown operations.
39
+
40
+ WHY: Consolidates all ticket operations (create, list, update, view, search)
41
+ into a single tool with an operation parameter, providing a cleaner and more
42
+ intuitive interface for ticket management.
43
+
44
+ DESIGN DECISIONS:
45
+ - Use operation parameter to route to appropriate handler
46
+ - Implement conditional parameter validation per operation
47
+ - Maintain backward compatibility with existing aitrackdown CLI
48
+ - Preserve all error handling and metrics from original tools
49
+ """
50
+
51
+ def __init__(self):
52
+ """Initialize the unified ticket tool with comprehensive schema."""
53
+ definition = MCPToolDefinition(
54
+ name="ticket",
55
+ description="Unified ticket management tool for all aitrackdown operations",
56
+ input_schema={
57
+ "type": "object",
58
+ "properties": {
59
+ "operation": {
60
+ "type": "string",
61
+ "enum": ["create", "list", "update", "view", "search"],
62
+ "description": "The ticket operation to perform",
63
+ },
64
+ # Create operation parameters
65
+ "type": {
66
+ "type": "string",
67
+ "enum": ["task", "issue", "epic"],
68
+ "description": "Type of ticket (for create operation)",
69
+ },
70
+ "title": {
71
+ "type": "string",
72
+ "description": "Title of the ticket (for create operation)",
73
+ },
74
+ "description": {
75
+ "type": "string",
76
+ "description": "Detailed description (for create operation)",
77
+ },
78
+ "priority": {
79
+ "type": "string",
80
+ "enum": ["low", "medium", "high", "critical"],
81
+ "description": "Priority level",
82
+ },
83
+ "tags": {
84
+ "type": "array",
85
+ "items": {"type": "string"},
86
+ "description": "Tags to associate with the ticket (for create)",
87
+ },
88
+ "parent_epic": {
89
+ "type": "string",
90
+ "description": "Parent epic ID for issues (create operation)",
91
+ },
92
+ "parent_issue": {
93
+ "type": "string",
94
+ "description": "Parent issue ID for tasks (create operation)",
95
+ },
96
+ # List operation parameters
97
+ "limit": {
98
+ "type": "number",
99
+ "description": "Maximum number of results to return",
100
+ "default": 10,
101
+ },
102
+ # Update operation parameters
103
+ "ticket_id": {
104
+ "type": "string",
105
+ "description": "Ticket ID (for update/view operations)",
106
+ },
107
+ "status": {
108
+ "type": "string",
109
+ "enum": [
110
+ "all",
111
+ "open",
112
+ "in-progress",
113
+ "ready",
114
+ "tested",
115
+ "done",
116
+ "waiting",
117
+ "closed",
118
+ "blocked",
119
+ ],
120
+ "description": "Status filter or new status",
121
+ },
122
+ "comment": {
123
+ "type": "string",
124
+ "description": "Comment for update operation",
125
+ },
126
+ # View operation parameters
127
+ "format": {
128
+ "type": "string",
129
+ "enum": ["json", "text"],
130
+ "description": "Output format (for view operation)",
131
+ "default": "json",
132
+ },
133
+ # Search operation parameters
134
+ "query": {
135
+ "type": "string",
136
+ "description": "Search query keywords (for search operation)",
137
+ },
138
+ },
139
+ "required": ["operation"],
140
+ # Note: Additional validation is handled in the invoke method
141
+ # to avoid using allOf/oneOf/anyOf at the top level which is not
142
+ # supported by the Claude API
143
+ },
144
+ )
145
+ super().__init__(definition)
146
+
147
+ async def invoke(self, invocation: MCPToolInvocation) -> MCPToolResult:
148
+ """
149
+ Route the invocation to the appropriate operation handler.
150
+
151
+ Args:
152
+ invocation: Tool invocation request
153
+
154
+ Returns:
155
+ Tool execution result from the specific operation
156
+ """
157
+ operation = invocation.parameters.get("operation")
158
+
159
+ if not operation:
160
+ return MCPToolResult(
161
+ success=False,
162
+ error="Operation parameter is required",
163
+ execution_time=0.0,
164
+ )
165
+
166
+ # Validate required parameters based on operation type
167
+ validation_error = self._validate_parameters(operation, invocation.parameters)
168
+ if validation_error:
169
+ return MCPToolResult(
170
+ success=False,
171
+ error=validation_error,
172
+ execution_time=0.0,
173
+ )
174
+
175
+ # Route to appropriate handler based on operation
176
+ handlers = {
177
+ "create": self._handle_create,
178
+ "list": self._handle_list,
179
+ "update": self._handle_update,
180
+ "view": self._handle_view,
181
+ "search": self._handle_search,
182
+ }
183
+
184
+ handler = handlers.get(operation)
185
+ if not handler:
186
+ return MCPToolResult(
187
+ success=False,
188
+ error=f"Unknown operation: {operation}",
189
+ execution_time=0.0,
190
+ )
191
+
192
+ return await handler(invocation.parameters)
193
+
194
+ def _validate_parameters(self, operation: str, params: Dict[str, Any]) -> Optional[str]:
195
+ """
196
+ Validate parameters based on the operation type.
197
+
198
+ Args:
199
+ operation: The operation being performed
200
+ params: Parameters provided for the operation
201
+
202
+ Returns:
203
+ Error message if validation fails, None if valid
204
+ """
205
+ if operation == "create":
206
+ if "type" not in params:
207
+ return "'type' parameter is required for create operation"
208
+ if "title" not in params:
209
+ return "'title' parameter is required for create operation"
210
+ if params["type"] not in ["task", "issue", "epic"]:
211
+ return f"Invalid type '{params['type']}'. Must be 'task', 'issue', or 'epic'"
212
+
213
+ elif operation == "update":
214
+ if "ticket_id" not in params:
215
+ return "'ticket_id' parameter is required for update operation"
216
+
217
+ elif operation == "view":
218
+ if "ticket_id" not in params:
219
+ return "'ticket_id' parameter is required for view operation"
220
+
221
+ elif operation == "search":
222
+ if "query" not in params:
223
+ return "'query' parameter is required for search operation"
224
+
225
+ elif operation == "list":
226
+ # List operation has no required parameters beyond operation itself
227
+ pass
228
+
229
+ else:
230
+ return f"Unknown operation: {operation}"
231
+
232
+ return None
233
+
234
+ async def _handle_create(self, params: Dict[str, Any]) -> MCPToolResult:
235
+ """
236
+ Handle ticket creation operation.
237
+
238
+ Args:
239
+ params: Parameters for ticket creation
240
+
241
+ Returns:
242
+ Tool execution result with created ticket ID
243
+ """
244
+ start_time = datetime.now()
245
+
246
+ try:
247
+ # Build aitrackdown command
248
+ cmd = ["aitrackdown", "create", params["type"], params["title"]]
249
+
250
+ # Add optional parameters
251
+ if "description" in params:
252
+ cmd.extend(["--description", params["description"]])
253
+
254
+ if "priority" in params:
255
+ cmd.extend(["--priority", params["priority"]])
256
+
257
+ if "tags" in params and params["tags"]:
258
+ for tag in params["tags"]:
259
+ cmd.extend(["--tag", tag])
260
+
261
+ # For tasks, use --issue to associate with parent issue
262
+ if params["type"] == "task" and "parent_issue" in params:
263
+ cmd.extend(["--issue", params["parent_issue"]])
264
+
265
+ # Execute command asynchronously
266
+ process = await asyncio.create_subprocess_exec(
267
+ *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
268
+ )
269
+
270
+ stdout, stderr = await process.communicate()
271
+ execution_time = (datetime.now() - start_time).total_seconds()
272
+
273
+ if process.returncode == 0:
274
+ # Parse ticket ID from output
275
+ output = stdout.decode().strip()
276
+ ticket_id = None
277
+ for line in output.split("\n"):
278
+ if "TSK-" in line or "ISS-" in line or "EP-" in line:
279
+ match = re.search(r"(TSK|ISS|EP)-\d+", line)
280
+ if match:
281
+ ticket_id = match.group(0)
282
+ break
283
+
284
+ self._update_metrics(True, execution_time)
285
+
286
+ return MCPToolResult(
287
+ success=True,
288
+ data={
289
+ "ticket_id": ticket_id or "Unknown",
290
+ "type": params["type"],
291
+ "title": params["title"],
292
+ "message": output,
293
+ },
294
+ execution_time=execution_time,
295
+ metadata={"tool": "ticket", "operation": "create"},
296
+ )
297
+ else:
298
+ error_msg = stderr.decode() if stderr else stdout.decode()
299
+ self._update_metrics(False, execution_time)
300
+
301
+ return MCPToolResult(
302
+ success=False,
303
+ error=f"Failed to create ticket: {error_msg}",
304
+ execution_time=execution_time,
305
+ )
306
+
307
+ except Exception as e:
308
+ execution_time = (datetime.now() - start_time).total_seconds()
309
+ self._update_metrics(False, execution_time)
310
+
311
+ return MCPToolResult(
312
+ success=False,
313
+ error=f"Ticket creation failed: {str(e)}",
314
+ execution_time=execution_time,
315
+ )
316
+
317
+ async def _handle_list(self, params: Dict[str, Any]) -> MCPToolResult:
318
+ """
319
+ Handle ticket listing operation.
320
+
321
+ Args:
322
+ params: Parameters for ticket listing
323
+
324
+ Returns:
325
+ Tool execution result with list of tickets
326
+ """
327
+ start_time = datetime.now()
328
+
329
+ try:
330
+ limit = params.get("limit", 10)
331
+
332
+ # Build aitrackdown command - use status tasks for listing
333
+ cmd = ["aitrackdown", "status", "tasks", "--limit", str(limit)]
334
+
335
+ # Add filters
336
+ if params.get("status") and params["status"] != "all":
337
+ cmd.extend(["--status", params["status"]])
338
+
339
+ # Execute command asynchronously
340
+ process = await asyncio.create_subprocess_exec(
341
+ *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
342
+ )
343
+
344
+ stdout, stderr = await process.communicate()
345
+ execution_time = (datetime.now() - start_time).total_seconds()
346
+
347
+ if process.returncode == 0:
348
+ try:
349
+ # Try to parse JSON output
350
+ tickets = json.loads(stdout.decode())
351
+ except json.JSONDecodeError:
352
+ # Fallback to text parsing if JSON fails
353
+ output = stdout.decode().strip()
354
+ tickets = {"raw_output": output, "count": output.count("\n") + 1}
355
+
356
+ self._update_metrics(True, execution_time)
357
+
358
+ return MCPToolResult(
359
+ success=True,
360
+ data=tickets,
361
+ execution_time=execution_time,
362
+ metadata={
363
+ "tool": "ticket",
364
+ "operation": "list",
365
+ "count": len(tickets) if isinstance(tickets, list) else 1,
366
+ },
367
+ )
368
+ else:
369
+ error_msg = stderr.decode() if stderr else stdout.decode()
370
+ self._update_metrics(False, execution_time)
371
+
372
+ return MCPToolResult(
373
+ success=False,
374
+ error=f"Failed to list tickets: {error_msg}",
375
+ execution_time=execution_time,
376
+ )
377
+
378
+ except Exception as e:
379
+ execution_time = (datetime.now() - start_time).total_seconds()
380
+ self._update_metrics(False, execution_time)
381
+
382
+ return MCPToolResult(
383
+ success=False,
384
+ error=f"Ticket listing failed: {str(e)}",
385
+ execution_time=execution_time,
386
+ )
387
+
388
+ async def _handle_update(self, params: Dict[str, Any]) -> MCPToolResult:
389
+ """
390
+ Handle ticket update operation.
391
+
392
+ Args:
393
+ params: Parameters for ticket update
394
+
395
+ Returns:
396
+ Tool execution result
397
+ """
398
+ start_time = datetime.now()
399
+
400
+ try:
401
+ ticket_id = params["ticket_id"]
402
+
403
+ # Determine which update to perform
404
+ if "status" in params and params["status"] != "all":
405
+ # Use transition command for status updates
406
+ cmd = ["aitrackdown", "transition", ticket_id, params["status"]]
407
+
408
+ if "comment" in params:
409
+ cmd.extend(["--comment", params["comment"]])
410
+ elif "priority" in params:
411
+ # For priority updates, use transition with comment
412
+ cmd = ["aitrackdown", "transition", ticket_id, "open"]
413
+ cmd.extend(["--comment", f"Priority changed to {params['priority']}"])
414
+
415
+ if "comment" in params:
416
+ cmd.extend(["--comment", params["comment"]])
417
+ else:
418
+ return MCPToolResult(
419
+ success=False,
420
+ error="No update fields provided (status or priority required)",
421
+ execution_time=0.0,
422
+ )
423
+
424
+ # Execute command asynchronously
425
+ process = await asyncio.create_subprocess_exec(
426
+ *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
427
+ )
428
+
429
+ stdout, stderr = await process.communicate()
430
+ execution_time = (datetime.now() - start_time).total_seconds()
431
+
432
+ if process.returncode == 0:
433
+ self._update_metrics(True, execution_time)
434
+
435
+ return MCPToolResult(
436
+ success=True,
437
+ data={
438
+ "ticket_id": ticket_id,
439
+ "updated_fields": [
440
+ k for k in ["status", "priority"] if k in params
441
+ ],
442
+ "message": stdout.decode().strip(),
443
+ },
444
+ execution_time=execution_time,
445
+ metadata={"tool": "ticket", "operation": "update"},
446
+ )
447
+ else:
448
+ error_msg = stderr.decode() if stderr else stdout.decode()
449
+ self._update_metrics(False, execution_time)
450
+
451
+ return MCPToolResult(
452
+ success=False,
453
+ error=f"Failed to update ticket: {error_msg}",
454
+ execution_time=execution_time,
455
+ )
456
+
457
+ except Exception as e:
458
+ execution_time = (datetime.now() - start_time).total_seconds()
459
+ self._update_metrics(False, execution_time)
460
+
461
+ return MCPToolResult(
462
+ success=False,
463
+ error=f"Ticket update failed: {str(e)}",
464
+ execution_time=execution_time,
465
+ )
466
+
467
+ async def _handle_view(self, params: Dict[str, Any]) -> MCPToolResult:
468
+ """
469
+ Handle ticket viewing operation.
470
+
471
+ Args:
472
+ params: Parameters for ticket viewing
473
+
474
+ Returns:
475
+ Tool execution result with ticket details
476
+ """
477
+ start_time = datetime.now()
478
+
479
+ try:
480
+ ticket_id = params["ticket_id"]
481
+ format_type = params.get("format", "json")
482
+
483
+ # Build aitrackdown command - use show for viewing
484
+ cmd = ["aitrackdown", "show", ticket_id]
485
+
486
+ # Execute command asynchronously
487
+ process = await asyncio.create_subprocess_exec(
488
+ *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
489
+ )
490
+
491
+ stdout, stderr = await process.communicate()
492
+ execution_time = (datetime.now() - start_time).total_seconds()
493
+
494
+ if process.returncode == 0:
495
+ output = stdout.decode().strip()
496
+
497
+ if format_type == "json":
498
+ try:
499
+ ticket_data = json.loads(output)
500
+ except json.JSONDecodeError:
501
+ ticket_data = {"raw_output": output}
502
+ else:
503
+ ticket_data = {"raw_output": output}
504
+
505
+ self._update_metrics(True, execution_time)
506
+
507
+ return MCPToolResult(
508
+ success=True,
509
+ data=ticket_data,
510
+ execution_time=execution_time,
511
+ metadata={
512
+ "tool": "ticket",
513
+ "operation": "view",
514
+ "ticket_id": ticket_id,
515
+ },
516
+ )
517
+ else:
518
+ error_msg = stderr.decode() if stderr else stdout.decode()
519
+ self._update_metrics(False, execution_time)
520
+
521
+ return MCPToolResult(
522
+ success=False,
523
+ error=f"Failed to view ticket: {error_msg}",
524
+ execution_time=execution_time,
525
+ )
526
+
527
+ except Exception as e:
528
+ execution_time = (datetime.now() - start_time).total_seconds()
529
+ self._update_metrics(False, execution_time)
530
+
531
+ return MCPToolResult(
532
+ success=False,
533
+ error=f"Ticket view failed: {str(e)}",
534
+ execution_time=execution_time,
535
+ )
536
+
537
+ async def _handle_search(self, params: Dict[str, Any]) -> MCPToolResult:
538
+ """
539
+ Handle ticket search operation.
540
+
541
+ Args:
542
+ params: Parameters for ticket search
543
+
544
+ Returns:
545
+ Tool execution result with matching tickets
546
+ """
547
+ start_time = datetime.now()
548
+
549
+ try:
550
+ query = params["query"]
551
+ limit = params.get("limit", 10)
552
+
553
+ # Build aitrackdown command - use search tasks
554
+ cmd = ["aitrackdown", "search", "tasks", query, "--limit", str(limit)]
555
+
556
+ if params.get("type") and params["type"] != "all":
557
+ cmd.extend(["--type", params["type"]])
558
+
559
+ # Execute command asynchronously
560
+ process = await asyncio.create_subprocess_exec(
561
+ *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
562
+ )
563
+
564
+ stdout, stderr = await process.communicate()
565
+ execution_time = (datetime.now() - start_time).total_seconds()
566
+
567
+ if process.returncode == 0:
568
+ try:
569
+ # Try to parse JSON output
570
+ results = json.loads(stdout.decode())
571
+ except json.JSONDecodeError:
572
+ # Fallback to text parsing if JSON fails
573
+ output = stdout.decode().strip()
574
+ results = {"raw_output": output, "query": query}
575
+
576
+ self._update_metrics(True, execution_time)
577
+
578
+ return MCPToolResult(
579
+ success=True,
580
+ data=results,
581
+ execution_time=execution_time,
582
+ metadata={"tool": "ticket", "operation": "search", "query": query},
583
+ )
584
+ else:
585
+ error_msg = stderr.decode() if stderr else stdout.decode()
586
+ self._update_metrics(False, execution_time)
587
+
588
+ return MCPToolResult(
589
+ success=False,
590
+ error=f"Failed to search tickets: {error_msg}",
591
+ execution_time=execution_time,
592
+ )
593
+
594
+ except Exception as e:
595
+ execution_time = (datetime.now() - start_time).total_seconds()
596
+ self._update_metrics(False, execution_time)
597
+
598
+ return MCPToolResult(
599
+ success=False,
600
+ error=f"Ticket search failed: {str(e)}",
601
+ execution_time=execution_time,
602
+ )
603
+
604
+
605
+ # Export the unified ticket tool
606
+ __all__ = ["UnifiedTicketTool"]
@@ -7,11 +7,11 @@ This module provides memory management services including:
7
7
  """
8
8
 
9
9
  from .builder import MemoryBuilder
10
- from .router import MemoryRouter
11
10
  from .optimizer import MemoryOptimizer
11
+ from .router import MemoryRouter
12
12
 
13
13
  __all__ = [
14
14
  "MemoryBuilder",
15
15
  "MemoryRouter",
16
16
  "MemoryOptimizer",
17
- ]
17
+ ]