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.
- claude_mpm/VERSION +1 -1
- claude_mpm/__init__.py +4 -0
- claude_mpm/agents/{PM_INSTRUCTIONS_TEACH.md → CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md} +721 -41
- claude_mpm/agents/PM_INSTRUCTIONS.md +290 -34
- claude_mpm/agents/agent_loader.py +13 -44
- claude_mpm/agents/frontmatter_validator.py +68 -0
- claude_mpm/agents/templates/circuit-breakers.md +138 -1
- claude_mpm/cli/__main__.py +4 -0
- claude_mpm/cli/chrome_devtools_installer.py +175 -0
- claude_mpm/cli/commands/agent_state_manager.py +8 -17
- claude_mpm/cli/commands/agents.py +169 -31
- claude_mpm/cli/commands/auto_configure.py +210 -25
- claude_mpm/cli/commands/config.py +88 -2
- claude_mpm/cli/commands/configure.py +1111 -161
- claude_mpm/cli/commands/configure_agent_display.py +15 -6
- claude_mpm/cli/commands/mpm_init/core.py +160 -46
- claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +280 -0
- claude_mpm/cli/commands/skills.py +214 -189
- claude_mpm/cli/commands/summarize.py +413 -0
- claude_mpm/cli/executor.py +11 -3
- claude_mpm/cli/parsers/agents_parser.py +54 -9
- claude_mpm/cli/parsers/auto_configure_parser.py +0 -138
- claude_mpm/cli/parsers/base_parser.py +5 -0
- claude_mpm/cli/parsers/config_parser.py +153 -83
- claude_mpm/cli/parsers/skills_parser.py +3 -2
- claude_mpm/cli/startup.py +550 -94
- claude_mpm/commands/mpm-config.md +265 -0
- claude_mpm/commands/mpm-help.md +14 -95
- claude_mpm/commands/mpm-organize.md +500 -0
- claude_mpm/config/agent_sources.py +27 -0
- claude_mpm/core/framework/formatters/content_formatter.py +3 -13
- claude_mpm/core/framework/loaders/agent_loader.py +8 -5
- claude_mpm/core/framework_loader.py +4 -2
- claude_mpm/core/logger.py +13 -0
- claude_mpm/core/output_style_manager.py +173 -43
- claude_mpm/core/socketio_pool.py +3 -3
- claude_mpm/core/unified_agent_registry.py +134 -16
- claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +211 -78
- claude_mpm/hooks/claude_hooks/hook_handler.py +6 -0
- claude_mpm/hooks/claude_hooks/installer.py +33 -10
- claude_mpm/hooks/claude_hooks/memory_integration.py +26 -9
- claude_mpm/hooks/claude_hooks/response_tracking.py +2 -3
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +4 -0
- claude_mpm/hooks/memory_integration_hook.py +46 -1
- claude_mpm/init.py +0 -19
- claude_mpm/models/agent_definition.py +7 -0
- claude_mpm/scripts/claude-hook-handler.sh +58 -18
- claude_mpm/scripts/launch_monitor.py +93 -13
- claude_mpm/scripts/start_activity_logging.py +0 -0
- claude_mpm/services/agents/agent_recommendation_service.py +278 -0
- claude_mpm/services/agents/agent_review_service.py +280 -0
- claude_mpm/services/agents/deployment/agent_discovery_service.py +2 -3
- claude_mpm/services/agents/deployment/agent_template_builder.py +4 -2
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +188 -12
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +531 -55
- claude_mpm/services/agents/git_source_manager.py +34 -0
- claude_mpm/services/agents/loading/base_agent_manager.py +1 -13
- claude_mpm/services/agents/sources/git_source_sync_service.py +8 -1
- claude_mpm/services/agents/toolchain_detector.py +10 -6
- claude_mpm/services/analysis/__init__.py +11 -1
- claude_mpm/services/analysis/clone_detector.py +1030 -0
- claude_mpm/services/command_deployment_service.py +81 -10
- claude_mpm/services/event_bus/config.py +3 -1
- claude_mpm/services/git/git_operations_service.py +93 -8
- claude_mpm/services/monitor/daemon.py +9 -2
- claude_mpm/services/monitor/daemon_manager.py +39 -3
- claude_mpm/services/monitor/server.py +225 -19
- claude_mpm/services/self_upgrade_service.py +120 -12
- claude_mpm/services/skills/__init__.py +3 -0
- claude_mpm/services/skills/git_skill_source_manager.py +32 -2
- claude_mpm/services/skills/selective_skill_deployer.py +704 -0
- claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
- claude_mpm/services/skills_deployer.py +126 -9
- claude_mpm/services/socketio/event_normalizer.py +15 -1
- claude_mpm/services/socketio/server/core.py +160 -21
- claude_mpm/services/version_control/git_operations.py +103 -0
- claude_mpm/utils/agent_filters.py +17 -44
- {claude_mpm-5.1.8.dist-info → claude_mpm-5.4.22.dist-info}/METADATA +47 -84
- {claude_mpm-5.1.8.dist-info → claude_mpm-5.4.22.dist-info}/RECORD +86 -176
- claude_mpm-5.4.22.dist-info/entry_points.txt +5 -0
- claude_mpm-5.4.22.dist-info/licenses/LICENSE +94 -0
- claude_mpm-5.4.22.dist-info/licenses/LICENSE-FAQ.md +153 -0
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -292
- claude_mpm/agents/BASE_DOCUMENTATION.md +0 -53
- claude_mpm/agents/BASE_ENGINEER.md +0 -658
- claude_mpm/agents/BASE_OPS.md +0 -219
- claude_mpm/agents/BASE_PM.md +0 -480
- claude_mpm/agents/BASE_PROMPT_ENGINEER.md +0 -787
- claude_mpm/agents/BASE_QA.md +0 -167
- claude_mpm/agents/BASE_RESEARCH.md +0 -53
- claude_mpm/agents/base_agent.json +0 -31
- claude_mpm/agents/base_agent_loader.py +0 -601
- claude_mpm/cli/commands/agents_detect.py +0 -380
- claude_mpm/cli/commands/agents_recommend.py +0 -309
- claude_mpm/cli/ticket_cli.py +0 -35
- claude_mpm/commands/mpm-agents-auto-configure.md +0 -278
- claude_mpm/commands/mpm-agents-detect.md +0 -177
- claude_mpm/commands/mpm-agents-list.md +0 -131
- claude_mpm/commands/mpm-agents-recommend.md +0 -223
- claude_mpm/commands/mpm-config-view.md +0 -150
- claude_mpm/commands/mpm-ticket-organize.md +0 -304
- claude_mpm/dashboard/analysis_runner.py +0 -455
- claude_mpm/dashboard/index.html +0 -13
- claude_mpm/dashboard/open_dashboard.py +0 -66
- claude_mpm/dashboard/static/css/activity.css +0 -1958
- claude_mpm/dashboard/static/css/connection-status.css +0 -370
- claude_mpm/dashboard/static/css/dashboard.css +0 -4701
- claude_mpm/dashboard/static/js/components/activity-tree.js +0 -1871
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +0 -777
- claude_mpm/dashboard/static/js/components/agent-inference.js +0 -956
- claude_mpm/dashboard/static/js/components/build-tracker.js +0 -333
- claude_mpm/dashboard/static/js/components/code-simple.js +0 -857
- claude_mpm/dashboard/static/js/components/connection-debug.js +0 -654
- claude_mpm/dashboard/static/js/components/diff-viewer.js +0 -891
- claude_mpm/dashboard/static/js/components/event-processor.js +0 -542
- claude_mpm/dashboard/static/js/components/event-viewer.js +0 -1155
- claude_mpm/dashboard/static/js/components/export-manager.js +0 -368
- claude_mpm/dashboard/static/js/components/file-change-tracker.js +0 -443
- claude_mpm/dashboard/static/js/components/file-change-viewer.js +0 -690
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +0 -724
- claude_mpm/dashboard/static/js/components/file-viewer.js +0 -580
- claude_mpm/dashboard/static/js/components/hud-library-loader.js +0 -211
- claude_mpm/dashboard/static/js/components/hud-manager.js +0 -671
- claude_mpm/dashboard/static/js/components/hud-visualizer.js +0 -1718
- claude_mpm/dashboard/static/js/components/module-viewer.js +0 -2764
- claude_mpm/dashboard/static/js/components/session-manager.js +0 -579
- claude_mpm/dashboard/static/js/components/socket-manager.js +0 -368
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +0 -749
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +0 -1824
- claude_mpm/dashboard/static/js/components/working-directory.js +0 -920
- claude_mpm/dashboard/static/js/connection-manager.js +0 -536
- claude_mpm/dashboard/static/js/dashboard.js +0 -1914
- claude_mpm/dashboard/static/js/extension-error-handler.js +0 -164
- claude_mpm/dashboard/static/js/socket-client.js +0 -1474
- claude_mpm/dashboard/static/js/tab-isolation-fix.js +0 -185
- claude_mpm/dashboard/static/socket.io.min.js +0 -7
- claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +0 -7
- claude_mpm/dashboard/templates/code_simple.html +0 -153
- claude_mpm/dashboard/templates/index.html +0 -606
- claude_mpm/dashboard/test_dashboard.html +0 -372
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
- claude_mpm/scripts/mcp_server.py +0 -75
- claude_mpm/scripts/mcp_wrapper.py +0 -39
- claude_mpm/services/mcp_gateway/__init__.py +0 -159
- claude_mpm/services/mcp_gateway/auto_configure.py +0 -369
- claude_mpm/services/mcp_gateway/config/__init__.py +0 -17
- claude_mpm/services/mcp_gateway/config/config_loader.py +0 -296
- claude_mpm/services/mcp_gateway/config/config_schema.py +0 -243
- claude_mpm/services/mcp_gateway/config/configuration.py +0 -429
- claude_mpm/services/mcp_gateway/core/__init__.py +0 -43
- claude_mpm/services/mcp_gateway/core/base.py +0 -312
- claude_mpm/services/mcp_gateway/core/exceptions.py +0 -253
- claude_mpm/services/mcp_gateway/core/interfaces.py +0 -443
- claude_mpm/services/mcp_gateway/core/process_pool.py +0 -977
- claude_mpm/services/mcp_gateway/core/singleton_manager.py +0 -315
- claude_mpm/services/mcp_gateway/core/startup_verification.py +0 -316
- claude_mpm/services/mcp_gateway/main.py +0 -589
- claude_mpm/services/mcp_gateway/registry/__init__.py +0 -12
- claude_mpm/services/mcp_gateway/registry/service_registry.py +0 -412
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +0 -489
- claude_mpm/services/mcp_gateway/server/__init__.py +0 -15
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +0 -414
- claude_mpm/services/mcp_gateway/server/stdio_handler.py +0 -372
- claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -712
- claude_mpm/services/mcp_gateway/tools/__init__.py +0 -36
- claude_mpm/services/mcp_gateway/tools/base_adapter.py +0 -485
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +0 -789
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +0 -654
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +0 -456
- claude_mpm/services/mcp_gateway/tools/hello_world.py +0 -551
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +0 -555
- claude_mpm/services/mcp_gateway/utils/__init__.py +0 -14
- claude_mpm/services/mcp_gateway/utils/package_version_checker.py +0 -160
- claude_mpm/services/mcp_gateway/utils/update_preferences.py +0 -170
- claude_mpm-5.1.8.dist-info/entry_points.txt +0 -10
- claude_mpm-5.1.8.dist-info/licenses/LICENSE +0 -21
- /claude_mpm/agents/{OUTPUT_STYLE.md → CLAUDE_MPM_OUTPUT_STYLE.md} +0 -0
- {claude_mpm-5.1.8.dist-info → claude_mpm-5.4.22.dist-info}/WHEEL +0 -0
- {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
|
|
claude_mpm/cli/__main__.py
CHANGED
|
@@ -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=
|
|
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
|
|
323
|
-
project_agents_dir = Path.cwd() / ".claude
|
|
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
|
|