claude-mpm 5.0.9__py3-none-any.whl → 5.4.41__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 (263) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/__init__.py +4 -0
  3. claude_mpm/agents/BASE_AGENT.md +164 -0
  4. claude_mpm/agents/{PM_INSTRUCTIONS_TEACH.md → CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md} +721 -41
  5. claude_mpm/agents/MEMORY.md +1 -1
  6. claude_mpm/agents/PM_INSTRUCTIONS.md +468 -468
  7. claude_mpm/agents/WORKFLOW.md +5 -254
  8. claude_mpm/agents/agent_loader.py +13 -44
  9. claude_mpm/agents/base_agent.json +1 -1
  10. claude_mpm/agents/frontmatter_validator.py +70 -2
  11. claude_mpm/agents/templates/circuit-breakers.md +431 -45
  12. claude_mpm/cli/__init__.py +0 -1
  13. claude_mpm/cli/__main__.py +4 -0
  14. claude_mpm/cli/chrome_devtools_installer.py +175 -0
  15. claude_mpm/cli/commands/agent_state_manager.py +18 -27
  16. claude_mpm/cli/commands/agents.py +175 -37
  17. claude_mpm/cli/commands/auto_configure.py +723 -236
  18. claude_mpm/cli/commands/config.py +88 -2
  19. claude_mpm/cli/commands/configure.py +1262 -157
  20. claude_mpm/cli/commands/configure_agent_display.py +25 -6
  21. claude_mpm/cli/commands/mpm_init/core.py +225 -46
  22. claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
  23. claude_mpm/cli/commands/mpm_init/prompts.py +280 -0
  24. claude_mpm/cli/commands/postmortem.py +1 -1
  25. claude_mpm/cli/commands/profile.py +277 -0
  26. claude_mpm/cli/commands/skills.py +214 -189
  27. claude_mpm/cli/commands/summarize.py +413 -0
  28. claude_mpm/cli/executor.py +21 -3
  29. claude_mpm/cli/interactive/agent_wizard.py +85 -10
  30. claude_mpm/cli/parsers/agents_parser.py +54 -9
  31. claude_mpm/cli/parsers/auto_configure_parser.py +13 -138
  32. claude_mpm/cli/parsers/base_parser.py +12 -0
  33. claude_mpm/cli/parsers/config_parser.py +153 -83
  34. claude_mpm/cli/parsers/profile_parser.py +148 -0
  35. claude_mpm/cli/parsers/skills_parser.py +3 -2
  36. claude_mpm/cli/startup.py +879 -149
  37. claude_mpm/commands/mpm-config.md +28 -0
  38. claude_mpm/commands/mpm-doctor.md +9 -22
  39. claude_mpm/commands/mpm-help.md +5 -287
  40. claude_mpm/commands/mpm-init.md +81 -507
  41. claude_mpm/commands/mpm-monitor.md +15 -402
  42. claude_mpm/commands/mpm-organize.md +120 -0
  43. claude_mpm/commands/mpm-postmortem.md +6 -108
  44. claude_mpm/commands/mpm-session-resume.md +12 -363
  45. claude_mpm/commands/mpm-status.md +5 -69
  46. claude_mpm/commands/mpm-ticket-view.md +52 -495
  47. claude_mpm/commands/mpm-version.md +5 -107
  48. claude_mpm/config/agent_sources.py +27 -0
  49. claude_mpm/core/config.py +2 -4
  50. claude_mpm/core/framework/formatters/content_formatter.py +3 -13
  51. claude_mpm/core/framework/loaders/agent_loader.py +8 -5
  52. claude_mpm/core/framework/loaders/instruction_loader.py +52 -11
  53. claude_mpm/core/framework_loader.py +4 -2
  54. claude_mpm/core/logger.py +13 -0
  55. claude_mpm/core/optimized_startup.py +59 -0
  56. claude_mpm/core/output_style_manager.py +173 -43
  57. claude_mpm/core/shared/config_loader.py +1 -1
  58. claude_mpm/core/socketio_pool.py +3 -3
  59. claude_mpm/core/unified_agent_registry.py +134 -16
  60. claude_mpm/core/unified_config.py +22 -0
  61. claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
  62. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +1 -0
  63. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +1 -0
  64. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +1 -0
  65. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +1 -0
  66. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +1 -0
  67. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +2 -0
  68. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DjhvlsAc.js +1 -0
  69. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/N4qtv3Hx.js +2 -0
  70. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uj46x2Wr.js +1 -0
  71. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +2 -0
  72. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +1 -0
  73. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.CAGBuiOw.js +1 -0
  74. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +1 -0
  75. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +10 -0
  76. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
  77. claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
  78. claude_mpm/dashboard/static/svelte-build/index.html +36 -0
  79. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  80. claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
  81. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  82. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  83. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  84. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  85. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  86. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
  87. claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
  88. claude_mpm/hooks/claude_hooks/event_handlers.py +211 -78
  89. claude_mpm/hooks/claude_hooks/hook_handler.py +155 -1
  90. claude_mpm/hooks/claude_hooks/installer.py +33 -10
  91. claude_mpm/hooks/claude_hooks/memory_integration.py +28 -0
  92. claude_mpm/hooks/claude_hooks/response_tracking.py +2 -3
  93. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  94. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
  95. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  96. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
  97. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  98. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  99. claude_mpm/hooks/claude_hooks/services/connection_manager.py +30 -6
  100. claude_mpm/hooks/memory_integration_hook.py +46 -1
  101. claude_mpm/init.py +63 -19
  102. claude_mpm/models/agent_definition.py +7 -0
  103. claude_mpm/models/git_repository.py +3 -3
  104. claude_mpm/scripts/claude-hook-handler.sh +58 -18
  105. claude_mpm/scripts/launch_monitor.py +93 -13
  106. claude_mpm/scripts/start_activity_logging.py +0 -0
  107. claude_mpm/services/agents/agent_builder.py +3 -3
  108. claude_mpm/services/agents/agent_recommendation_service.py +278 -0
  109. claude_mpm/services/agents/agent_review_service.py +280 -0
  110. claude_mpm/services/agents/cache_git_manager.py +6 -6
  111. claude_mpm/services/agents/deployment/agent_deployment.py +29 -7
  112. claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -5
  113. claude_mpm/services/agents/deployment/agent_template_builder.py +5 -3
  114. claude_mpm/services/agents/deployment/agents_directory_resolver.py +2 -2
  115. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +320 -29
  116. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +546 -68
  117. claude_mpm/services/agents/git_source_manager.py +36 -2
  118. claude_mpm/services/agents/loading/base_agent_manager.py +1 -13
  119. claude_mpm/services/agents/recommender.py +5 -3
  120. claude_mpm/services/agents/single_tier_deployment_service.py +2 -2
  121. claude_mpm/services/agents/sources/git_source_sync_service.py +13 -6
  122. claude_mpm/services/agents/startup_sync.py +22 -2
  123. claude_mpm/services/agents/toolchain_detector.py +10 -6
  124. claude_mpm/services/analysis/__init__.py +11 -1
  125. claude_mpm/services/analysis/clone_detector.py +1030 -0
  126. claude_mpm/services/command_deployment_service.py +81 -10
  127. claude_mpm/services/diagnostics/checks/agent_check.py +2 -2
  128. claude_mpm/services/diagnostics/checks/agent_sources_check.py +1 -1
  129. claude_mpm/services/event_bus/config.py +3 -1
  130. claude_mpm/services/git/git_operations_service.py +101 -16
  131. claude_mpm/services/monitor/daemon.py +9 -2
  132. claude_mpm/services/monitor/daemon_manager.py +39 -3
  133. claude_mpm/services/monitor/management/lifecycle.py +8 -1
  134. claude_mpm/services/monitor/server.py +698 -22
  135. claude_mpm/services/pm_skills_deployer.py +676 -0
  136. claude_mpm/services/profile_manager.py +331 -0
  137. claude_mpm/services/project/project_organizer.py +4 -0
  138. claude_mpm/services/self_upgrade_service.py +120 -12
  139. claude_mpm/services/skills/__init__.py +3 -0
  140. claude_mpm/services/skills/git_skill_source_manager.py +130 -2
  141. claude_mpm/services/skills/selective_skill_deployer.py +704 -0
  142. claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
  143. claude_mpm/services/skills_deployer.py +126 -9
  144. claude_mpm/services/socketio/dashboard_server.py +1 -0
  145. claude_mpm/services/socketio/event_normalizer.py +51 -6
  146. claude_mpm/services/socketio/server/core.py +386 -108
  147. claude_mpm/services/version_control/git_operations.py +103 -0
  148. claude_mpm/skills/skill_manager.py +92 -3
  149. claude_mpm/utils/agent_dependency_loader.py +14 -2
  150. claude_mpm/utils/agent_filters.py +17 -44
  151. claude_mpm/utils/gitignore.py +3 -0
  152. claude_mpm/utils/migration.py +4 -4
  153. claude_mpm/utils/robust_installer.py +47 -3
  154. {claude_mpm-5.0.9.dist-info → claude_mpm-5.4.41.dist-info}/METADATA +57 -87
  155. {claude_mpm-5.0.9.dist-info → claude_mpm-5.4.41.dist-info}/RECORD +160 -211
  156. claude_mpm-5.4.41.dist-info/entry_points.txt +5 -0
  157. claude_mpm-5.4.41.dist-info/licenses/LICENSE +94 -0
  158. claude_mpm-5.4.41.dist-info/licenses/LICENSE-FAQ.md +153 -0
  159. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -292
  160. claude_mpm/agents/BASE_DOCUMENTATION.md +0 -53
  161. claude_mpm/agents/BASE_OPS.md +0 -219
  162. claude_mpm/agents/BASE_PM.md +0 -480
  163. claude_mpm/agents/BASE_PROMPT_ENGINEER.md +0 -787
  164. claude_mpm/agents/BASE_QA.md +0 -167
  165. claude_mpm/agents/BASE_RESEARCH.md +0 -53
  166. claude_mpm/agents/base_agent_loader.py +0 -601
  167. claude_mpm/cli/commands/agents_detect.py +0 -380
  168. claude_mpm/cli/commands/agents_recommend.py +0 -309
  169. claude_mpm/cli/ticket_cli.py +0 -35
  170. claude_mpm/commands/mpm-agents-auto-configure.md +0 -278
  171. claude_mpm/commands/mpm-agents-detect.md +0 -177
  172. claude_mpm/commands/mpm-agents-list.md +0 -131
  173. claude_mpm/commands/mpm-agents-recommend.md +0 -223
  174. claude_mpm/commands/mpm-config-view.md +0 -150
  175. claude_mpm/commands/mpm-ticket-organize.md +0 -304
  176. claude_mpm/dashboard/analysis_runner.py +0 -455
  177. claude_mpm/dashboard/index.html +0 -13
  178. claude_mpm/dashboard/open_dashboard.py +0 -66
  179. claude_mpm/dashboard/static/css/activity.css +0 -1958
  180. claude_mpm/dashboard/static/css/connection-status.css +0 -370
  181. claude_mpm/dashboard/static/css/dashboard.css +0 -4701
  182. claude_mpm/dashboard/static/js/components/activity-tree.js +0 -1871
  183. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +0 -777
  184. claude_mpm/dashboard/static/js/components/agent-inference.js +0 -956
  185. claude_mpm/dashboard/static/js/components/build-tracker.js +0 -333
  186. claude_mpm/dashboard/static/js/components/code-simple.js +0 -857
  187. claude_mpm/dashboard/static/js/components/connection-debug.js +0 -654
  188. claude_mpm/dashboard/static/js/components/diff-viewer.js +0 -891
  189. claude_mpm/dashboard/static/js/components/event-processor.js +0 -542
  190. claude_mpm/dashboard/static/js/components/event-viewer.js +0 -1155
  191. claude_mpm/dashboard/static/js/components/export-manager.js +0 -368
  192. claude_mpm/dashboard/static/js/components/file-change-tracker.js +0 -443
  193. claude_mpm/dashboard/static/js/components/file-change-viewer.js +0 -690
  194. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +0 -724
  195. claude_mpm/dashboard/static/js/components/file-viewer.js +0 -580
  196. claude_mpm/dashboard/static/js/components/hud-library-loader.js +0 -211
  197. claude_mpm/dashboard/static/js/components/hud-manager.js +0 -671
  198. claude_mpm/dashboard/static/js/components/hud-visualizer.js +0 -1718
  199. claude_mpm/dashboard/static/js/components/module-viewer.js +0 -2764
  200. claude_mpm/dashboard/static/js/components/session-manager.js +0 -579
  201. claude_mpm/dashboard/static/js/components/socket-manager.js +0 -368
  202. claude_mpm/dashboard/static/js/components/ui-state-manager.js +0 -749
  203. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +0 -1824
  204. claude_mpm/dashboard/static/js/components/working-directory.js +0 -920
  205. claude_mpm/dashboard/static/js/connection-manager.js +0 -536
  206. claude_mpm/dashboard/static/js/dashboard.js +0 -1914
  207. claude_mpm/dashboard/static/js/extension-error-handler.js +0 -164
  208. claude_mpm/dashboard/static/js/socket-client.js +0 -1474
  209. claude_mpm/dashboard/static/js/tab-isolation-fix.js +0 -185
  210. claude_mpm/dashboard/static/socket.io.min.js +0 -7
  211. claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +0 -7
  212. claude_mpm/dashboard/templates/code_simple.html +0 -153
  213. claude_mpm/dashboard/templates/index.html +0 -606
  214. claude_mpm/dashboard/test_dashboard.html +0 -372
  215. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
  216. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
  217. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
  218. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
  219. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
  220. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
  221. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
  222. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
  223. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
  224. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
  225. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
  226. claude_mpm/scripts/mcp_server.py +0 -75
  227. claude_mpm/scripts/mcp_wrapper.py +0 -39
  228. claude_mpm/services/mcp_gateway/__init__.py +0 -159
  229. claude_mpm/services/mcp_gateway/auto_configure.py +0 -369
  230. claude_mpm/services/mcp_gateway/config/__init__.py +0 -17
  231. claude_mpm/services/mcp_gateway/config/config_loader.py +0 -296
  232. claude_mpm/services/mcp_gateway/config/config_schema.py +0 -243
  233. claude_mpm/services/mcp_gateway/config/configuration.py +0 -429
  234. claude_mpm/services/mcp_gateway/core/__init__.py +0 -43
  235. claude_mpm/services/mcp_gateway/core/base.py +0 -312
  236. claude_mpm/services/mcp_gateway/core/exceptions.py +0 -253
  237. claude_mpm/services/mcp_gateway/core/interfaces.py +0 -443
  238. claude_mpm/services/mcp_gateway/core/process_pool.py +0 -977
  239. claude_mpm/services/mcp_gateway/core/singleton_manager.py +0 -315
  240. claude_mpm/services/mcp_gateway/core/startup_verification.py +0 -316
  241. claude_mpm/services/mcp_gateway/main.py +0 -589
  242. claude_mpm/services/mcp_gateway/registry/__init__.py +0 -12
  243. claude_mpm/services/mcp_gateway/registry/service_registry.py +0 -412
  244. claude_mpm/services/mcp_gateway/registry/tool_registry.py +0 -489
  245. claude_mpm/services/mcp_gateway/server/__init__.py +0 -15
  246. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +0 -414
  247. claude_mpm/services/mcp_gateway/server/stdio_handler.py +0 -372
  248. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -712
  249. claude_mpm/services/mcp_gateway/tools/__init__.py +0 -36
  250. claude_mpm/services/mcp_gateway/tools/base_adapter.py +0 -485
  251. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +0 -789
  252. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +0 -654
  253. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +0 -456
  254. claude_mpm/services/mcp_gateway/tools/hello_world.py +0 -551
  255. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +0 -555
  256. claude_mpm/services/mcp_gateway/utils/__init__.py +0 -14
  257. claude_mpm/services/mcp_gateway/utils/package_version_checker.py +0 -160
  258. claude_mpm/services/mcp_gateway/utils/update_preferences.py +0 -170
  259. claude_mpm-5.0.9.dist-info/entry_points.txt +0 -10
  260. claude_mpm-5.0.9.dist-info/licenses/LICENSE +0 -21
  261. /claude_mpm/agents/{OUTPUT_STYLE.md → CLAUDE_MPM_OUTPUT_STYLE.md} +0 -0
  262. {claude_mpm-5.0.9.dist-info → claude_mpm-5.4.41.dist-info}/WHEEL +0 -0
  263. {claude_mpm-5.0.9.dist-info → claude_mpm-5.4.41.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,175 @@
1
+ """
2
+ Chrome DevTools MCP Auto-Installer
3
+ ===================================
4
+
5
+ Automatically installs and configures chrome-devtools-mcp on startup
6
+ to enable browser automation and web interaction capabilities in Claude Code.
7
+
8
+ WHY: Users should have browser automation capabilities out-of-the-box without
9
+ manual MCP server configuration.
10
+
11
+ DESIGN DECISION: Non-blocking installation that doesn't prevent startup if it fails.
12
+ Uses the `claude mcp add` command for native Claude Code integration.
13
+ """
14
+
15
+ import json
16
+ import subprocess
17
+ from pathlib import Path
18
+ from typing import Optional, Tuple
19
+
20
+ from ..core.logger import get_logger
21
+
22
+
23
+ class ChromeDevToolsInstaller:
24
+ """Manages automatic installation of chrome-devtools-mcp."""
25
+
26
+ MCP_SERVER_NAME = "chrome-devtools"
27
+ INSTALL_COMMAND = ["npx", "chrome-devtools-mcp@latest"]
28
+
29
+ def __init__(self):
30
+ """Initialize the chrome-devtools installer."""
31
+ self.logger = get_logger(__name__)
32
+ self.claude_config_path = Path.home() / ".claude.json"
33
+
34
+ def is_already_configured(self) -> bool:
35
+ """
36
+ Check if chrome-devtools-mcp is already configured in Claude.
37
+
38
+ Returns:
39
+ True if already configured, False otherwise
40
+ """
41
+ try:
42
+ if not self.claude_config_path.exists():
43
+ self.logger.debug("Claude config file not found")
44
+ return False
45
+
46
+ with open(self.claude_config_path) as f:
47
+ config = json.load(f)
48
+
49
+ # Check if chrome-devtools is in mcpServers
50
+ mcp_servers = config.get("mcpServers", {})
51
+ is_configured = self.MCP_SERVER_NAME in mcp_servers
52
+
53
+ if is_configured:
54
+ self.logger.debug(
55
+ f"{self.MCP_SERVER_NAME} already configured in Claude"
56
+ )
57
+ else:
58
+ self.logger.debug(f"{self.MCP_SERVER_NAME} not found in Claude config")
59
+
60
+ return is_configured
61
+
62
+ except json.JSONDecodeError as e:
63
+ self.logger.warning(f"Failed to parse Claude config: {e}")
64
+ return False
65
+ except Exception as e:
66
+ self.logger.debug(f"Error checking Chrome DevTools configuration: {e}")
67
+ return False
68
+
69
+ def install_mcp_server(self) -> Tuple[bool, Optional[str]]:
70
+ """
71
+ Install chrome-devtools-mcp using the claude CLI.
72
+
73
+ Returns:
74
+ Tuple of (success: bool, error_message: Optional[str])
75
+ """
76
+ try:
77
+ # Build the command: claude mcp add chrome-devtools -- npx chrome-devtools-mcp@latest
78
+ command = [
79
+ "claude",
80
+ "mcp",
81
+ "add",
82
+ self.MCP_SERVER_NAME,
83
+ "--",
84
+ ] + self.INSTALL_COMMAND
85
+
86
+ self.logger.debug(f"Running: {' '.join(command)}")
87
+
88
+ # Run the command with timeout
89
+ result = subprocess.run(
90
+ command,
91
+ capture_output=True,
92
+ text=True,
93
+ timeout=30, # 30 second timeout
94
+ check=False,
95
+ )
96
+
97
+ if result.returncode == 0:
98
+ self.logger.info(
99
+ f"Successfully installed {self.MCP_SERVER_NAME} MCP server"
100
+ )
101
+ return True, None
102
+
103
+ # Command failed
104
+ error_msg = (
105
+ f"Failed to install {self.MCP_SERVER_NAME}: {result.stderr.strip()}"
106
+ )
107
+ self.logger.warning(error_msg)
108
+ return False, error_msg
109
+
110
+ except subprocess.TimeoutExpired:
111
+ error_msg = (
112
+ f"Installation of {self.MCP_SERVER_NAME} timed out after 30 seconds"
113
+ )
114
+ self.logger.warning(error_msg)
115
+ return False, error_msg
116
+
117
+ except FileNotFoundError:
118
+ error_msg = "Claude CLI not found. Is Claude Code installed?"
119
+ self.logger.warning(error_msg)
120
+ return False, error_msg
121
+
122
+ except Exception as e:
123
+ error_msg = f"Unexpected error installing {self.MCP_SERVER_NAME}: {e}"
124
+ self.logger.warning(error_msg)
125
+ return False, error_msg
126
+
127
+ def auto_install(self, quiet: bool = False) -> bool:
128
+ """
129
+ Automatically install chrome-devtools-mcp if not already configured.
130
+
131
+ Args:
132
+ quiet: If True, suppress console output
133
+
134
+ Returns:
135
+ True if installation succeeded or already configured, False otherwise
136
+ """
137
+ # Check if already configured
138
+ if self.is_already_configured():
139
+ if not quiet:
140
+ print("✓ Chrome DevTools MCP ready", flush=True)
141
+ return True
142
+
143
+ # Show progress feedback
144
+ if not quiet:
145
+ print("Installing Chrome DevTools MCP...", end=" ", flush=True)
146
+
147
+ # Install the MCP server
148
+ success, error = self.install_mcp_server()
149
+
150
+ if success:
151
+ if not quiet:
152
+ print("✓", flush=True)
153
+ return True
154
+
155
+ # Installation failed
156
+ if not quiet:
157
+ print("(skipped)", flush=True)
158
+
159
+ # Log the error but don't fail startup
160
+ self.logger.debug(f"Chrome DevTools installation skipped: {error}")
161
+ return False
162
+
163
+
164
+ def auto_install_chrome_devtools(quiet: bool = False) -> bool:
165
+ """
166
+ Convenience function to auto-install chrome-devtools-mcp.
167
+
168
+ Args:
169
+ quiet: If True, suppress console output
170
+
171
+ Returns:
172
+ True if installation succeeded or already configured, False otherwise
173
+ """
174
+ installer = ChromeDevToolsInstaller()
175
+ return installer.auto_install(quiet=quiet)
@@ -111,14 +111,14 @@ class SimpleAgentManager:
111
111
  local_agents = self._discover_local_template_agents()
112
112
  agents.extend(local_agents)
113
113
 
114
- # Discover remote agents if requested
114
+ # Discover Git-sourced agents if requested
115
115
  if include_remote:
116
116
  try:
117
- remote_agents = self._discover_remote_agents()
118
- agents.extend(remote_agents)
119
- self.logger.info(f"Discovered {len(remote_agents)} remote agents")
117
+ git_agents = self._discover_git_agents()
118
+ agents.extend(git_agents)
119
+ self.logger.info(f"Discovered {len(git_agents)} Git-sourced agents")
120
120
  except Exception as e:
121
- self.logger.warning(f"Failed to discover remote agents: {e}")
121
+ self.logger.warning(f"Failed to discover Git-sourced agents: {e}")
122
122
 
123
123
  # Sort agents by name for consistent display
124
124
  agents.sort(key=lambda a: a.name)
@@ -152,7 +152,7 @@ class SimpleAgentManager:
152
152
 
153
153
  # Get metadata for display info
154
154
  metadata = template_data.get("metadata", {})
155
- metadata.get("name", agent_id)
155
+ display_name = metadata.get("name", agent_id)
156
156
  description = metadata.get(
157
157
  "description", "No description available"
158
158
  )
@@ -182,9 +182,10 @@ class SimpleAgentManager:
182
182
  dependencies=display_tools,
183
183
  )
184
184
 
185
- # Set deployment status
185
+ # Set deployment status and display name
186
186
  agent_config.is_deployed = is_deployed
187
187
  agent_config.source_type = "local"
188
+ agent_config.display_name = display_name
188
189
 
189
190
  agents.append(agent_config)
190
191
 
@@ -207,20 +208,20 @@ class SimpleAgentManager:
207
208
 
208
209
  return agents
209
210
 
210
- def _discover_remote_agents(self) -> List[AgentConfig]:
211
- """Discover agents from remote Git sources using GitSourceManager."""
211
+ def _discover_git_agents(self) -> List[AgentConfig]:
212
+ """Discover agents from Git sources using GitSourceManager."""
212
213
  try:
213
214
  from claude_mpm.services.agents.git_source_manager import GitSourceManager
214
215
 
215
- # Initialize source manager (uses ~/.claude-mpm/cache/remote-agents by default)
216
+ # Initialize source manager (uses ~/.claude-mpm/cache/agents by default)
216
217
  source_manager = GitSourceManager()
217
218
 
218
219
  # Discover all cached agents from all repositories
219
- remote_agent_dicts = source_manager.list_cached_agents()
220
+ git_agent_dicts = source_manager.list_cached_agents()
220
221
 
221
222
  # Convert to AgentConfig objects for UI display
222
223
  agents = []
223
- for agent_dict in remote_agent_dicts:
224
+ for agent_dict in git_agent_dicts:
224
225
  # Extract metadata
225
226
  metadata = agent_dict.get("metadata", {})
226
227
  agent_id = agent_dict.get("agent_id", "unknown")
@@ -235,7 +236,7 @@ class SimpleAgentManager:
235
236
  # Create AgentConfig with source information
236
237
  # Store full agent_dict for later use in deployment
237
238
  agent_config = AgentConfig(
238
- name=agent_id, # Use agent_id as name for uniqueness
239
+ name=name, # Use display name for UI
239
240
  description=(
240
241
  f"[{category}] {description[:60]}..."
241
242
  if len(description) > 60
@@ -248,6 +249,7 @@ class SimpleAgentManager:
248
249
  agent_config.source_type = "remote"
249
250
  agent_config.is_deployed = is_deployed
250
251
  agent_config.display_name = name
252
+ agent_config.agent_id = agent_id # Store technical ID for reference
251
253
  agent_config.full_agent_id = agent_id
252
254
  agent_config.source_dict = agent_dict # Store full dict for deployment
253
255
 
@@ -272,9 +274,9 @@ class SimpleAgentManager:
272
274
  True if agent is deployed, False otherwise
273
275
  """
274
276
  # Check virtual deployment state (primary method)
277
+ # Only checking project-level deployment in simplified architecture
275
278
  deployment_state_paths = [
276
279
  Path.cwd() / ".claude" / "agents" / ".mpm_deployment_state",
277
- Path.home() / ".claude" / "agents" / ".mpm_deployment_state",
278
280
  ]
279
281
 
280
282
  for state_path in deployment_state_paths:
@@ -319,8 +321,8 @@ class SimpleAgentManager:
319
321
  leaf_name = agent_id.split("/")[-1]
320
322
  agent_file_names.append(f"{leaf_name}.md")
321
323
 
322
- # Check .claude-mpm/agents/ directory (project level)
323
- project_agents_dir = Path.cwd() / ".claude-mpm" / "agents"
324
+ # Check .claude/agents/ directory (project deployment)
325
+ project_agents_dir = Path.cwd() / ".claude" / "agents"
324
326
  if project_agents_dir.exists():
325
327
  for agent_file_name in agent_file_names:
326
328
  agent_file = project_agents_dir / agent_file_name
@@ -330,15 +332,4 @@ class SimpleAgentManager:
330
332
  )
331
333
  return True
332
334
 
333
- # Check ~/.claude/agents/ directory (user level)
334
- user_agents_dir = Path.home() / ".claude" / "agents"
335
- if user_agents_dir.exists():
336
- for agent_file_name in agent_file_names:
337
- agent_file = user_agents_dir / agent_file_name
338
- if agent_file.exists():
339
- self.logger.debug(
340
- f"Agent {agent_id} found as physical file: {agent_file}"
341
- )
342
- return True
343
-
344
335
  return False
@@ -157,9 +157,6 @@ class AgentsCommand(AgentCommand):
157
157
  "configure": self._configure_deployment,
158
158
  # Migration command (DEPRECATION support)
159
159
  "migrate-to-project": self._migrate_to_project,
160
- # Auto-configuration commands (TSK-0054 Phase 5)
161
- "detect": self._detect_toolchain,
162
- "recommend": self._recommend_agents,
163
160
  # Agent selection modes (Phase 3: 1M-382)
164
161
  "deploy-minimal": self._deploy_minimal_configuration,
165
162
  "deploy-auto": self._deploy_auto_configure,
@@ -167,6 +164,10 @@ class AgentsCommand(AgentCommand):
167
164
  "available": self._list_available_from_sources,
168
165
  # Agent discovery with rich filtering (Phase 1: Discovery & Browsing)
169
166
  "discover": self._discover_agents,
167
+ # NEW: Collection-based agent management
168
+ "list-collections": self._list_collections,
169
+ "deploy-collection": self._deploy_collection,
170
+ "list-by-collection": self._list_by_collection,
170
171
  # Cache git management commands
171
172
  "cache-status": self._cache_status,
172
173
  "cache-pull": self._cache_pull,
@@ -560,7 +561,7 @@ class AgentsCommand(AgentCommand):
560
561
  """Deploy agents using two-phase sync: cache → deploy.
561
562
 
562
563
  Phase 3 Integration (1M-486): Uses Git sync service for deployment.
563
- - Phase 1: Sync agents to ~/.claude-mpm/cache/remote-agents/ (if needed)
564
+ - Phase 1: Sync agents to ~/.claude-mpm/cache/agents/ (if needed)
564
565
  - Phase 2: Deploy from cache to project .claude-mpm/agents/
565
566
 
566
567
  This replaces the old single-tier deployment with a multi-project
@@ -1821,34 +1822,6 @@ class AgentsCommand(AgentCommand):
1821
1822
  f"Error in interactive configuration: {e}"
1822
1823
  )
1823
1824
 
1824
- def _detect_toolchain(self, args) -> CommandResult:
1825
- """Detect project toolchain without deploying agents.
1826
-
1827
- Part of TSK-0054 Phase 5: Auto-configuration CLI integration.
1828
- """
1829
- try:
1830
- from .agents_detect import AgentsDetectCommand
1831
-
1832
- cmd = AgentsDetectCommand()
1833
- return cmd.run(args)
1834
- except Exception as e:
1835
- self.logger.error(f"Error detecting toolchain: {e}", exc_info=True)
1836
- return CommandResult.error_result(f"Error detecting toolchain: {e}")
1837
-
1838
- def _recommend_agents(self, args) -> CommandResult:
1839
- """Recommend agents based on project toolchain.
1840
-
1841
- Part of TSK-0054 Phase 5: Auto-configuration CLI integration.
1842
- """
1843
- try:
1844
- from .agents_recommend import AgentsRecommendCommand
1845
-
1846
- cmd = AgentsRecommendCommand()
1847
- return cmd.run(args)
1848
- except Exception as e:
1849
- self.logger.error(f"Error recommending agents: {e}", exc_info=True)
1850
- return CommandResult.error_result(f"Error recommending agents: {e}")
1851
-
1852
1825
  def _migrate_to_project(self, args) -> CommandResult:
1853
1826
  """Migrate user-level agents to project-level.
1854
1827
 
@@ -2157,6 +2130,171 @@ class AgentsCommand(AgentCommand):
2157
2130
  self.logger.error(f"Error in auto-configure: {e}", exc_info=True)
2158
2131
  return CommandResult.error_result(f"Error in auto-configure: {e}")
2159
2132
 
2133
+ def _list_collections(self, args) -> CommandResult:
2134
+ """List all available agent collections.
2135
+
2136
+ NEW: Shows all collections with agent counts and metadata.
2137
+ Enables discovery of available agent collections before deployment.
2138
+ """
2139
+ try:
2140
+ from pathlib import Path
2141
+
2142
+ from ...services.agents.deployment.remote_agent_discovery_service import (
2143
+ RemoteAgentDiscoveryService,
2144
+ )
2145
+
2146
+ # Get remote agents cache directory
2147
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
2148
+
2149
+ if not cache_dir.exists():
2150
+ return CommandResult.error_result(
2151
+ "No remote agent collections found. Run 'claude-mpm agents deploy' first."
2152
+ )
2153
+
2154
+ # Use RemoteAgentDiscoveryService to list collections
2155
+ remote_service = RemoteAgentDiscoveryService(cache_dir)
2156
+ collections = remote_service.list_collections()
2157
+
2158
+ if not collections:
2159
+ return CommandResult.success_result(
2160
+ "No agent collections found in cache.", data={"collections": []}
2161
+ )
2162
+
2163
+ # Format output
2164
+ output_lines = ["Available Agent Collections:\n"]
2165
+ for collection in collections:
2166
+ output_lines.append(
2167
+ f" • {collection['collection_id']} ({collection['agent_count']} agents)"
2168
+ )
2169
+
2170
+ return CommandResult.success_result(
2171
+ "\n".join(output_lines), data={"collections": collections}
2172
+ )
2173
+
2174
+ except Exception as e:
2175
+ self.logger.error(f"Error listing collections: {e}", exc_info=True)
2176
+ return CommandResult.error_result(f"Error listing collections: {e}")
2177
+
2178
+ def _deploy_collection(self, args) -> CommandResult:
2179
+ """Deploy all agents from a specific collection.
2180
+
2181
+ NEW: Enables bulk deployment of all agents from a named collection.
2182
+ Useful for deploying entire agent sets at once.
2183
+ """
2184
+ try:
2185
+ from pathlib import Path
2186
+
2187
+ from ...services.agents.deployment.multi_source_deployment_service import (
2188
+ MultiSourceAgentDeploymentService,
2189
+ )
2190
+
2191
+ collection_id = args.collection_id
2192
+
2193
+ # Get agents from collection
2194
+ service = MultiSourceAgentDeploymentService()
2195
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
2196
+ agents = service.get_agents_by_collection(collection_id, cache_dir)
2197
+
2198
+ if not agents:
2199
+ return CommandResult.error_result(
2200
+ f"No agents found in collection '{collection_id}'"
2201
+ )
2202
+
2203
+ # Dry run mode
2204
+ if getattr(args, "dry_run", False):
2205
+ agent_names = [
2206
+ agent.get("metadata", {}).get("name", "Unknown") for agent in agents
2207
+ ]
2208
+ output = f"Would deploy {len(agents)} agents from collection '{collection_id}':\n"
2209
+ for name in agent_names:
2210
+ output += f" • {name}\n"
2211
+ return CommandResult.success_result(
2212
+ output,
2213
+ data={"collection_id": collection_id, "agent_count": len(agents)},
2214
+ )
2215
+
2216
+ # Deploy agents
2217
+ # TODO: Implement actual deployment logic using deployment service
2218
+ # For now, show what would be deployed
2219
+ return CommandResult.success_result(
2220
+ f"Deployment of collection '{collection_id}' would deploy {len(agents)} agents.\n"
2221
+ f"(Full deployment implementation pending)",
2222
+ data={
2223
+ "collection_id": collection_id,
2224
+ "agent_count": len(agents),
2225
+ "status": "pending_implementation",
2226
+ },
2227
+ )
2228
+
2229
+ except Exception as e:
2230
+ self.logger.error(f"Error deploying collection: {e}", exc_info=True)
2231
+ return CommandResult.error_result(f"Error deploying collection: {e}")
2232
+
2233
+ def _list_by_collection(self, args) -> CommandResult:
2234
+ """List agents from a specific collection.
2235
+
2236
+ NEW: Shows detailed information about agents in a collection.
2237
+ Supports multiple output formats (table, json, yaml).
2238
+ """
2239
+ try:
2240
+ import json as json_lib
2241
+ from pathlib import Path
2242
+
2243
+ from ...services.agents.deployment.multi_source_deployment_service import (
2244
+ MultiSourceAgentDeploymentService,
2245
+ )
2246
+
2247
+ collection_id = args.collection_id
2248
+ output_format = getattr(args, "format", "table")
2249
+
2250
+ # Get agents from collection
2251
+ service = MultiSourceAgentDeploymentService()
2252
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
2253
+ agents = service.get_agents_by_collection(collection_id, cache_dir)
2254
+
2255
+ if not agents:
2256
+ return CommandResult.error_result(
2257
+ f"No agents found in collection '{collection_id}'"
2258
+ )
2259
+
2260
+ # Format output based on requested format
2261
+ if output_format == "json":
2262
+ return CommandResult.success_result(
2263
+ json_lib.dumps(agents, indent=2),
2264
+ data={"collection_id": collection_id, "agents": agents},
2265
+ )
2266
+ if output_format == "yaml":
2267
+ try:
2268
+ import yaml
2269
+
2270
+ return CommandResult.success_result(
2271
+ yaml.dump(agents, default_flow_style=False),
2272
+ data={"collection_id": collection_id, "agents": agents},
2273
+ )
2274
+ except ImportError:
2275
+ return CommandResult.error_result(
2276
+ "YAML support not available (install PyYAML)"
2277
+ )
2278
+
2279
+ # Table format (default)
2280
+ output_lines = [f"Agents in collection '{collection_id}':\n"]
2281
+ for agent in agents:
2282
+ metadata = agent.get("metadata", {})
2283
+ name = metadata.get("name", "Unknown")
2284
+ description = metadata.get("description", "No description")
2285
+ version = agent.get("version", "unknown")
2286
+ output_lines.append(f" • {name} (v{version})")
2287
+ output_lines.append(f" {description}\n")
2288
+
2289
+ return CommandResult.success_result(
2290
+ "\n".join(output_lines),
2291
+ data={"collection_id": collection_id, "agent_count": len(agents)},
2292
+ )
2293
+
2294
+ except Exception as e:
2295
+ self.logger.error(f"Error listing collection agents: {e}", exc_info=True)
2296
+ return CommandResult.error_result(f"Error listing collection agents: {e}")
2297
+
2160
2298
  def _cache_status(self, args) -> CommandResult:
2161
2299
  """Show git status of agent cache.
2162
2300
 
@@ -2166,7 +2304,7 @@ class AgentsCommand(AgentCommand):
2166
2304
  try:
2167
2305
  from ...services.agents.cache_git_manager import CacheGitManager
2168
2306
 
2169
- cache_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
2307
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
2170
2308
  manager = CacheGitManager(cache_dir)
2171
2309
 
2172
2310
  if not manager.is_git_repo():
@@ -2239,7 +2377,7 @@ class AgentsCommand(AgentCommand):
2239
2377
  try:
2240
2378
  from ...services.agents.cache_git_manager import CacheGitManager
2241
2379
 
2242
- cache_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
2380
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
2243
2381
  manager = CacheGitManager(cache_dir)
2244
2382
 
2245
2383
  if not manager.is_git_repo():
@@ -2266,7 +2404,7 @@ class AgentsCommand(AgentCommand):
2266
2404
  try:
2267
2405
  from ...services.agents.cache_git_manager import CacheGitManager
2268
2406
 
2269
- cache_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
2407
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
2270
2408
  manager = CacheGitManager(cache_dir)
2271
2409
 
2272
2410
  if not manager.is_git_repo():
@@ -2298,7 +2436,7 @@ class AgentsCommand(AgentCommand):
2298
2436
  try:
2299
2437
  from ...services.agents.cache_git_manager import CacheGitManager
2300
2438
 
2301
- cache_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
2439
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
2302
2440
  manager = CacheGitManager(cache_dir)
2303
2441
 
2304
2442
  if not manager.is_git_repo():
@@ -2346,7 +2484,7 @@ class AgentsCommand(AgentCommand):
2346
2484
  try:
2347
2485
  from ...services.agents.cache_git_manager import CacheGitManager
2348
2486
 
2349
- cache_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
2487
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
2350
2488
  manager = CacheGitManager(cache_dir)
2351
2489
 
2352
2490
  if not manager.is_git_repo():