claude-mpm 5.1.8__py3-none-any.whl → 5.4.22__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 (191) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/__init__.py +4 -0
  3. claude_mpm/agents/{PM_INSTRUCTIONS_TEACH.md → CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md} +721 -41
  4. claude_mpm/agents/PM_INSTRUCTIONS.md +290 -34
  5. claude_mpm/agents/agent_loader.py +13 -44
  6. claude_mpm/agents/frontmatter_validator.py +68 -0
  7. claude_mpm/agents/templates/circuit-breakers.md +138 -1
  8. claude_mpm/cli/__main__.py +4 -0
  9. claude_mpm/cli/chrome_devtools_installer.py +175 -0
  10. claude_mpm/cli/commands/agent_state_manager.py +8 -17
  11. claude_mpm/cli/commands/agents.py +169 -31
  12. claude_mpm/cli/commands/auto_configure.py +210 -25
  13. claude_mpm/cli/commands/config.py +88 -2
  14. claude_mpm/cli/commands/configure.py +1111 -161
  15. claude_mpm/cli/commands/configure_agent_display.py +15 -6
  16. claude_mpm/cli/commands/mpm_init/core.py +160 -46
  17. claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
  18. claude_mpm/cli/commands/mpm_init/prompts.py +280 -0
  19. claude_mpm/cli/commands/skills.py +214 -189
  20. claude_mpm/cli/commands/summarize.py +413 -0
  21. claude_mpm/cli/executor.py +11 -3
  22. claude_mpm/cli/parsers/agents_parser.py +54 -9
  23. claude_mpm/cli/parsers/auto_configure_parser.py +0 -138
  24. claude_mpm/cli/parsers/base_parser.py +5 -0
  25. claude_mpm/cli/parsers/config_parser.py +153 -83
  26. claude_mpm/cli/parsers/skills_parser.py +3 -2
  27. claude_mpm/cli/startup.py +550 -94
  28. claude_mpm/commands/mpm-config.md +265 -0
  29. claude_mpm/commands/mpm-help.md +14 -95
  30. claude_mpm/commands/mpm-organize.md +500 -0
  31. claude_mpm/config/agent_sources.py +27 -0
  32. claude_mpm/core/framework/formatters/content_formatter.py +3 -13
  33. claude_mpm/core/framework/loaders/agent_loader.py +8 -5
  34. claude_mpm/core/framework_loader.py +4 -2
  35. claude_mpm/core/logger.py +13 -0
  36. claude_mpm/core/output_style_manager.py +173 -43
  37. claude_mpm/core/socketio_pool.py +3 -3
  38. claude_mpm/core/unified_agent_registry.py +134 -16
  39. claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
  40. claude_mpm/hooks/claude_hooks/event_handlers.py +211 -78
  41. claude_mpm/hooks/claude_hooks/hook_handler.py +6 -0
  42. claude_mpm/hooks/claude_hooks/installer.py +33 -10
  43. claude_mpm/hooks/claude_hooks/memory_integration.py +26 -9
  44. claude_mpm/hooks/claude_hooks/response_tracking.py +2 -3
  45. claude_mpm/hooks/claude_hooks/services/connection_manager.py +4 -0
  46. claude_mpm/hooks/memory_integration_hook.py +46 -1
  47. claude_mpm/init.py +0 -19
  48. claude_mpm/models/agent_definition.py +7 -0
  49. claude_mpm/scripts/claude-hook-handler.sh +58 -18
  50. claude_mpm/scripts/launch_monitor.py +93 -13
  51. claude_mpm/scripts/start_activity_logging.py +0 -0
  52. claude_mpm/services/agents/agent_recommendation_service.py +278 -0
  53. claude_mpm/services/agents/agent_review_service.py +280 -0
  54. claude_mpm/services/agents/deployment/agent_discovery_service.py +2 -3
  55. claude_mpm/services/agents/deployment/agent_template_builder.py +4 -2
  56. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +188 -12
  57. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +531 -55
  58. claude_mpm/services/agents/git_source_manager.py +34 -0
  59. claude_mpm/services/agents/loading/base_agent_manager.py +1 -13
  60. claude_mpm/services/agents/sources/git_source_sync_service.py +8 -1
  61. claude_mpm/services/agents/toolchain_detector.py +10 -6
  62. claude_mpm/services/analysis/__init__.py +11 -1
  63. claude_mpm/services/analysis/clone_detector.py +1030 -0
  64. claude_mpm/services/command_deployment_service.py +81 -10
  65. claude_mpm/services/event_bus/config.py +3 -1
  66. claude_mpm/services/git/git_operations_service.py +93 -8
  67. claude_mpm/services/monitor/daemon.py +9 -2
  68. claude_mpm/services/monitor/daemon_manager.py +39 -3
  69. claude_mpm/services/monitor/server.py +225 -19
  70. claude_mpm/services/self_upgrade_service.py +120 -12
  71. claude_mpm/services/skills/__init__.py +3 -0
  72. claude_mpm/services/skills/git_skill_source_manager.py +32 -2
  73. claude_mpm/services/skills/selective_skill_deployer.py +704 -0
  74. claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
  75. claude_mpm/services/skills_deployer.py +126 -9
  76. claude_mpm/services/socketio/event_normalizer.py +15 -1
  77. claude_mpm/services/socketio/server/core.py +160 -21
  78. claude_mpm/services/version_control/git_operations.py +103 -0
  79. claude_mpm/utils/agent_filters.py +17 -44
  80. {claude_mpm-5.1.8.dist-info → claude_mpm-5.4.22.dist-info}/METADATA +47 -84
  81. {claude_mpm-5.1.8.dist-info → claude_mpm-5.4.22.dist-info}/RECORD +86 -176
  82. claude_mpm-5.4.22.dist-info/entry_points.txt +5 -0
  83. claude_mpm-5.4.22.dist-info/licenses/LICENSE +94 -0
  84. claude_mpm-5.4.22.dist-info/licenses/LICENSE-FAQ.md +153 -0
  85. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -292
  86. claude_mpm/agents/BASE_DOCUMENTATION.md +0 -53
  87. claude_mpm/agents/BASE_ENGINEER.md +0 -658
  88. claude_mpm/agents/BASE_OPS.md +0 -219
  89. claude_mpm/agents/BASE_PM.md +0 -480
  90. claude_mpm/agents/BASE_PROMPT_ENGINEER.md +0 -787
  91. claude_mpm/agents/BASE_QA.md +0 -167
  92. claude_mpm/agents/BASE_RESEARCH.md +0 -53
  93. claude_mpm/agents/base_agent.json +0 -31
  94. claude_mpm/agents/base_agent_loader.py +0 -601
  95. claude_mpm/cli/commands/agents_detect.py +0 -380
  96. claude_mpm/cli/commands/agents_recommend.py +0 -309
  97. claude_mpm/cli/ticket_cli.py +0 -35
  98. claude_mpm/commands/mpm-agents-auto-configure.md +0 -278
  99. claude_mpm/commands/mpm-agents-detect.md +0 -177
  100. claude_mpm/commands/mpm-agents-list.md +0 -131
  101. claude_mpm/commands/mpm-agents-recommend.md +0 -223
  102. claude_mpm/commands/mpm-config-view.md +0 -150
  103. claude_mpm/commands/mpm-ticket-organize.md +0 -304
  104. claude_mpm/dashboard/analysis_runner.py +0 -455
  105. claude_mpm/dashboard/index.html +0 -13
  106. claude_mpm/dashboard/open_dashboard.py +0 -66
  107. claude_mpm/dashboard/static/css/activity.css +0 -1958
  108. claude_mpm/dashboard/static/css/connection-status.css +0 -370
  109. claude_mpm/dashboard/static/css/dashboard.css +0 -4701
  110. claude_mpm/dashboard/static/js/components/activity-tree.js +0 -1871
  111. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +0 -777
  112. claude_mpm/dashboard/static/js/components/agent-inference.js +0 -956
  113. claude_mpm/dashboard/static/js/components/build-tracker.js +0 -333
  114. claude_mpm/dashboard/static/js/components/code-simple.js +0 -857
  115. claude_mpm/dashboard/static/js/components/connection-debug.js +0 -654
  116. claude_mpm/dashboard/static/js/components/diff-viewer.js +0 -891
  117. claude_mpm/dashboard/static/js/components/event-processor.js +0 -542
  118. claude_mpm/dashboard/static/js/components/event-viewer.js +0 -1155
  119. claude_mpm/dashboard/static/js/components/export-manager.js +0 -368
  120. claude_mpm/dashboard/static/js/components/file-change-tracker.js +0 -443
  121. claude_mpm/dashboard/static/js/components/file-change-viewer.js +0 -690
  122. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +0 -724
  123. claude_mpm/dashboard/static/js/components/file-viewer.js +0 -580
  124. claude_mpm/dashboard/static/js/components/hud-library-loader.js +0 -211
  125. claude_mpm/dashboard/static/js/components/hud-manager.js +0 -671
  126. claude_mpm/dashboard/static/js/components/hud-visualizer.js +0 -1718
  127. claude_mpm/dashboard/static/js/components/module-viewer.js +0 -2764
  128. claude_mpm/dashboard/static/js/components/session-manager.js +0 -579
  129. claude_mpm/dashboard/static/js/components/socket-manager.js +0 -368
  130. claude_mpm/dashboard/static/js/components/ui-state-manager.js +0 -749
  131. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +0 -1824
  132. claude_mpm/dashboard/static/js/components/working-directory.js +0 -920
  133. claude_mpm/dashboard/static/js/connection-manager.js +0 -536
  134. claude_mpm/dashboard/static/js/dashboard.js +0 -1914
  135. claude_mpm/dashboard/static/js/extension-error-handler.js +0 -164
  136. claude_mpm/dashboard/static/js/socket-client.js +0 -1474
  137. claude_mpm/dashboard/static/js/tab-isolation-fix.js +0 -185
  138. claude_mpm/dashboard/static/socket.io.min.js +0 -7
  139. claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +0 -7
  140. claude_mpm/dashboard/templates/code_simple.html +0 -153
  141. claude_mpm/dashboard/templates/index.html +0 -606
  142. claude_mpm/dashboard/test_dashboard.html +0 -372
  143. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
  144. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
  145. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
  146. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
  147. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
  148. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
  149. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
  150. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
  151. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
  152. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
  153. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
  154. claude_mpm/scripts/mcp_server.py +0 -75
  155. claude_mpm/scripts/mcp_wrapper.py +0 -39
  156. claude_mpm/services/mcp_gateway/__init__.py +0 -159
  157. claude_mpm/services/mcp_gateway/auto_configure.py +0 -369
  158. claude_mpm/services/mcp_gateway/config/__init__.py +0 -17
  159. claude_mpm/services/mcp_gateway/config/config_loader.py +0 -296
  160. claude_mpm/services/mcp_gateway/config/config_schema.py +0 -243
  161. claude_mpm/services/mcp_gateway/config/configuration.py +0 -429
  162. claude_mpm/services/mcp_gateway/core/__init__.py +0 -43
  163. claude_mpm/services/mcp_gateway/core/base.py +0 -312
  164. claude_mpm/services/mcp_gateway/core/exceptions.py +0 -253
  165. claude_mpm/services/mcp_gateway/core/interfaces.py +0 -443
  166. claude_mpm/services/mcp_gateway/core/process_pool.py +0 -977
  167. claude_mpm/services/mcp_gateway/core/singleton_manager.py +0 -315
  168. claude_mpm/services/mcp_gateway/core/startup_verification.py +0 -316
  169. claude_mpm/services/mcp_gateway/main.py +0 -589
  170. claude_mpm/services/mcp_gateway/registry/__init__.py +0 -12
  171. claude_mpm/services/mcp_gateway/registry/service_registry.py +0 -412
  172. claude_mpm/services/mcp_gateway/registry/tool_registry.py +0 -489
  173. claude_mpm/services/mcp_gateway/server/__init__.py +0 -15
  174. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +0 -414
  175. claude_mpm/services/mcp_gateway/server/stdio_handler.py +0 -372
  176. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -712
  177. claude_mpm/services/mcp_gateway/tools/__init__.py +0 -36
  178. claude_mpm/services/mcp_gateway/tools/base_adapter.py +0 -485
  179. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +0 -789
  180. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +0 -654
  181. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +0 -456
  182. claude_mpm/services/mcp_gateway/tools/hello_world.py +0 -551
  183. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +0 -555
  184. claude_mpm/services/mcp_gateway/utils/__init__.py +0 -14
  185. claude_mpm/services/mcp_gateway/utils/package_version_checker.py +0 -160
  186. claude_mpm/services/mcp_gateway/utils/update_preferences.py +0 -170
  187. claude_mpm-5.1.8.dist-info/entry_points.txt +0 -10
  188. claude_mpm-5.1.8.dist-info/licenses/LICENSE +0 -21
  189. /claude_mpm/agents/{OUTPUT_STYLE.md → CLAUDE_MPM_OUTPUT_STYLE.md} +0 -0
  190. {claude_mpm-5.1.8.dist-info → claude_mpm-5.4.22.dist-info}/WHEEL +0 -0
  191. {claude_mpm-5.1.8.dist-info → claude_mpm-5.4.22.dist-info}/top_level.txt +0 -0
@@ -1154,6 +1154,139 @@ Before delegating implementation, PM MUST verify:
1154
1154
 
1155
1155
  ---
1156
1156
 
1157
+ ## Circuit Breaker #8: Skills Management Violation
1158
+
1159
+ **Purpose**: Prevent PM from performing skill operations directly instead of delegating to mpm-skills-manager
1160
+
1161
+ ### Trigger Conditions
1162
+
1163
+ **IF PM attempts ANY of the following:**
1164
+
1165
+ #### Direct Skill Operations
1166
+ - PM creates SKILL.md files directly (using Write/Edit tools)
1167
+ - PM modifies manifest.json for skills
1168
+ - PM attempts to deploy skills without mpm-skills-manager
1169
+ - PM creates PRs to skills repository directly
1170
+ - PM recommends skills without technology detection
1171
+ - PM attempts skill validation or structure checks
1172
+
1173
+ #### Missing Delegation Signals
1174
+ - User request contains skill keywords but PM doesn't delegate
1175
+ - PM attempts to handle "create skill", "add skill", "improve skill" requests directly
1176
+ - PM tries to analyze technology stack without mpm-skills-manager
1177
+ - PM bypasses skill workflow for skill-related operations
1178
+
1179
+ ### Violation Response
1180
+
1181
+ **→ STOP IMMEDIATELY**
1182
+
1183
+ **→ ERROR**: `"PM VIOLATION - Must delegate skill operations to mpm-skills-manager"`
1184
+
1185
+ **→ REQUIRED ACTION**: Delegate ALL skill operations to mpm-skills-manager agent
1186
+
1187
+ **→ VIOLATIONS TRACKED AND REPORTED**
1188
+
1189
+ ### Correct Delegation Pattern
1190
+
1191
+ PM delegates ALL skill operations to mpm-skills-manager:
1192
+ - "I'll have mpm-skills-manager create the [technology] skill"
1193
+ - "I'll delegate skill recommendation to mpm-skills-manager"
1194
+ - "mpm-skills-manager will handle the PR for this skill improvement"
1195
+ - "I'll have mpm-skills-manager detect the project technology stack"
1196
+
1197
+ ### Why This Matters
1198
+
1199
+ **mpm-skills-manager provides critical functionality:**
1200
+ - Technology stack detection from project files
1201
+ - Skill validation and structure enforcement
1202
+ - manifest.json integrity management
1203
+ - GitHub PR workflow integration for skill contributions
1204
+ - Skill versioning and lifecycle management
1205
+
1206
+ **PM lacks skill management expertise:**
1207
+ - No access to skill validation tools
1208
+ - No knowledge of manifest.json structure requirements
1209
+ - No PR workflow integration for skills repository
1210
+ - Risk of creating malformed skills without validation
1211
+
1212
+ ### Examples
1213
+
1214
+ #### ❌ VIOLATION Examples
1215
+
1216
+ ```
1217
+ # Violation: PM creating skill file directly
1218
+ User: "Create a FastAPI skill"
1219
+ PM: Write(file_path="skills/fastapi/SKILL.md", ...) # ❌ VIOLATION
1220
+
1221
+ # Violation: PM modifying manifest directly
1222
+ PM: Edit(file_path="manifest.json", ...) # ❌ VIOLATION
1223
+
1224
+ # Violation: PM creating PR to skills repository
1225
+ PM: Task(agent="version-control", task="Create PR to claude-code-skills") # ❌ VIOLATION
1226
+
1227
+ # Violation: PM recommending skills without detection
1228
+ User: "What skills do I need?"
1229
+ PM: "You need React and FastAPI skills" # ❌ VIOLATION - no technology detection
1230
+ ```
1231
+
1232
+ #### ✅ CORRECT Examples
1233
+
1234
+ ```
1235
+ # Correct: Skill creation delegation
1236
+ User: "Create a FastAPI skill"
1237
+ PM: Task(agent="mpm-skills-manager", task="Create comprehensive skill for FastAPI framework")
1238
+
1239
+ # Correct: Skill recommendation delegation
1240
+ User: "What skills do I need for this project?"
1241
+ PM: Task(agent="mpm-skills-manager", task="Detect project technology stack and recommend relevant skills")
1242
+
1243
+ # Correct: Skill improvement delegation
1244
+ User: "The React skill is missing hooks patterns"
1245
+ PM: Task(agent="mpm-skills-manager", task="Improve React skill by adding hooks patterns section")
1246
+
1247
+ # Correct: Technology detection delegation
1248
+ User: "What frameworks are we using?"
1249
+ PM: Task(agent="mpm-skills-manager", task="Analyze project files and identify all frameworks and technologies")
1250
+ ```
1251
+
1252
+ ### Enforcement Levels
1253
+
1254
+ | Violation Count | Response | Action |
1255
+ |----------------|----------|--------|
1256
+ | **Violation #1** | ⚠️ WARNING | PM reminded to delegate skill operations to mpm-skills-manager |
1257
+ | **Violation #2** | 🚨 ESCALATION | PM must STOP and delegate to mpm-skills-manager immediately |
1258
+ | **Violation #3+** | ❌ FAILURE | Session marked as non-compliant, skill operations blocked |
1259
+
1260
+ ### Skill-Related Trigger Keywords
1261
+
1262
+ **PM should detect these keywords and delegate to mpm-skills-manager:**
1263
+
1264
+ **Skill Operations**:
1265
+ - "skill", "add skill", "create skill", "new skill"
1266
+ - "improve skill", "update skill", "skill is missing"
1267
+ - "deploy skill", "install skill", "remove skill"
1268
+
1269
+ **Technology Detection**:
1270
+ - "detect stack", "analyze technologies", "what frameworks"
1271
+ - "project stack", "identify dependencies"
1272
+ - "what are we using", "technology analysis"
1273
+
1274
+ **Skill Discovery**:
1275
+ - "recommend skills", "suggest skills", "what skills"
1276
+ - "skills for [framework]", "need skills for"
1277
+
1278
+ ### Integration with PM Workflow
1279
+
1280
+ **When PM sees skill keywords → IMMEDIATELY delegate to mpm-skills-manager**
1281
+
1282
+ **No exceptions for:**
1283
+ - "Simple" skill operations (all require validation)
1284
+ - "Quick" manifest updates (integrity critical)
1285
+ - "Minor" skill improvements (still need PR workflow)
1286
+ - Technology stack "guesses" (detection required)
1287
+
1288
+ ---
1289
+
1157
1290
  ## Violation Tracking Format
1158
1291
 
1159
1292
  When PM attempts forbidden action, use this format:
@@ -1173,6 +1306,7 @@ When PM attempts forbidden action, use this format:
1173
1306
  | **FILE TRACKING** | PM didn't track new files | `PM ended session without tracking 2 new files` |
1174
1307
  | **TICKETING** | PM used ticketing tools directly | `PM used mcp-ticketer tool - Must delegate to ticketing` |
1175
1308
  | **RESEARCH GATE** | PM skipped Research for ambiguous task | `PM delegated to Engineer without Research - Must delegate to Research first` |
1309
+ | **SKILLS** | PM attempted skill operations directly | `PM created SKILL.md directly - Must delegate to mpm-skills-manager` |
1176
1310
 
1177
1311
  ---
1178
1312
 
@@ -1207,6 +1341,8 @@ Violations are tracked and escalated based on severity:
1207
1341
  - "Is this task ambiguous? Should I delegate to Research BEFORE Engineer?"
1208
1342
  - "Did Research validate the approach before implementation?"
1209
1343
  - "Does my delegation include Research context?"
1344
+ - "Is this a skill-related request? Should I delegate to mpm-skills-manager?"
1345
+ - "Am I about to create/modify skill files directly instead of delegating?"
1210
1346
  - "Did any agent create a new file during this session?"
1211
1347
  - "Have I run `git status` to check for untracked files?"
1212
1348
  - "Are all trackable files staged in git?"
@@ -1232,6 +1368,7 @@ Violations are tracked and escalated based on severity:
1232
1368
  - [ ] No ticketing tool misuse (Circuit Breaker #6)
1233
1369
  - [ ] **Research delegated for all ambiguous tasks** ← Circuit Breaker #7
1234
1370
  - [ ] **Implementation references Research findings** ← Circuit Breaker #7
1371
+ - [ ] **All skill operations delegated to mpm-skills-manager** ← Circuit Breaker #8
1235
1372
  - [ ] Unresolved issues documented
1236
1373
  - [ ] Violation report provided (if violations occurred)
1237
1374
 
@@ -1241,7 +1378,7 @@ Violations are tracked and escalated based on severity:
1241
1378
 
1242
1379
  ## The PM Mantra
1243
1380
 
1244
- **"I don't investigate. I don't implement. I don't assert. I research-first for ambiguous tasks. I delegate, verify, and track files."**
1381
+ **"I don't investigate. I don't implement. I don't assert. I research-first for ambiguous tasks. I delegate skills to mpm-skills-manager. I delegate, verify, and track files."**
1245
1382
 
1246
1383
  ---
1247
1384
 
@@ -1,3 +1,7 @@
1
+ # Copyright (c) 2024-2025 Bob Matsuoka
2
+ # Licensed under the Elastic License 2.0
3
+ # See LICENSE file in the project root for full license information.
4
+
1
5
  """
2
6
  Entry point for executing the CLI module with python -m claude_mpm.cli.
3
7
 
@@ -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)
@@ -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
 
@@ -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,
@@ -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" / "remote-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" / "remote-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" / "remote-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