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
|
@@ -21,7 +21,6 @@ from typing import Optional
|
|
|
21
21
|
|
|
22
22
|
try:
|
|
23
23
|
from rich.console import Console
|
|
24
|
-
from rich.panel import Panel
|
|
25
24
|
from rich.progress import BarColumn, Progress, SpinnerColumn, TextColumn
|
|
26
25
|
from rich.table import Table
|
|
27
26
|
|
|
@@ -267,6 +266,15 @@ class AutoConfigureCommand(BaseCommand):
|
|
|
267
266
|
project_path, min_confidence
|
|
268
267
|
)
|
|
269
268
|
|
|
269
|
+
# Review existing project agents
|
|
270
|
+
agent_review_results = None
|
|
271
|
+
if configure_agents:
|
|
272
|
+
if self.console and not json_output:
|
|
273
|
+
with self.console.status("[bold green]Reviewing existing agents..."):
|
|
274
|
+
agent_review_results = self._review_project_agents(agent_preview)
|
|
275
|
+
else:
|
|
276
|
+
agent_review_results = self._review_project_agents(agent_preview)
|
|
277
|
+
|
|
270
278
|
# Get skills recommendations
|
|
271
279
|
skills_recommendations = None
|
|
272
280
|
if configure_skills:
|
|
@@ -283,9 +291,14 @@ class AutoConfigureCommand(BaseCommand):
|
|
|
283
291
|
skills_recommendations,
|
|
284
292
|
configure_agents,
|
|
285
293
|
configure_skills,
|
|
294
|
+
agent_review_results,
|
|
286
295
|
)
|
|
287
296
|
return self._display_preview(
|
|
288
|
-
agent_preview,
|
|
297
|
+
agent_preview,
|
|
298
|
+
skills_recommendations,
|
|
299
|
+
configure_agents,
|
|
300
|
+
configure_skills,
|
|
301
|
+
agent_review_results,
|
|
289
302
|
)
|
|
290
303
|
|
|
291
304
|
def _run_full_configuration(
|
|
@@ -311,6 +324,15 @@ class AutoConfigureCommand(BaseCommand):
|
|
|
311
324
|
project_path, min_confidence
|
|
312
325
|
)
|
|
313
326
|
|
|
327
|
+
# Review existing project agents
|
|
328
|
+
agent_review_results = None
|
|
329
|
+
if configure_agents:
|
|
330
|
+
if self.console and not json_output:
|
|
331
|
+
with self.console.status("[bold green]Reviewing existing agents..."):
|
|
332
|
+
agent_review_results = self._review_project_agents(agent_preview)
|
|
333
|
+
else:
|
|
334
|
+
agent_review_results = self._review_project_agents(agent_preview)
|
|
335
|
+
|
|
314
336
|
# Get skills recommendations
|
|
315
337
|
skills_recommendations = None
|
|
316
338
|
if configure_skills:
|
|
@@ -327,6 +349,7 @@ class AutoConfigureCommand(BaseCommand):
|
|
|
327
349
|
skills_recommendations,
|
|
328
350
|
configure_agents,
|
|
329
351
|
configure_skills,
|
|
352
|
+
agent_review_results,
|
|
330
353
|
)
|
|
331
354
|
|
|
332
355
|
# Ask for confirmation (unless skipped)
|
|
@@ -336,6 +359,7 @@ class AutoConfigureCommand(BaseCommand):
|
|
|
336
359
|
skills_recommendations,
|
|
337
360
|
configure_agents,
|
|
338
361
|
configure_skills,
|
|
362
|
+
agent_review_results,
|
|
339
363
|
):
|
|
340
364
|
if self.console:
|
|
341
365
|
self.console.print("\n❌ Operation cancelled by user")
|
|
@@ -343,6 +367,17 @@ class AutoConfigureCommand(BaseCommand):
|
|
|
343
367
|
print("\nOperation cancelled by user")
|
|
344
368
|
return CommandResult.error_result("Operation cancelled", exit_code=0)
|
|
345
369
|
|
|
370
|
+
# Archive unused agents (before deploying new ones)
|
|
371
|
+
archive_result = None
|
|
372
|
+
if configure_agents and agent_review_results:
|
|
373
|
+
agents_to_archive = agent_review_results.get("unused", [])
|
|
374
|
+
if agents_to_archive:
|
|
375
|
+
if self.console and not json_output:
|
|
376
|
+
self.console.print(
|
|
377
|
+
"\n[bold yellow]Archiving unused agents...[/bold yellow]\n"
|
|
378
|
+
)
|
|
379
|
+
archive_result = self._archive_agents(agents_to_archive)
|
|
380
|
+
|
|
346
381
|
# Execute agent configuration
|
|
347
382
|
agent_result = None
|
|
348
383
|
if configure_agents and agent_preview:
|
|
@@ -368,8 +403,8 @@ class AutoConfigureCommand(BaseCommand):
|
|
|
368
403
|
|
|
369
404
|
# Output results
|
|
370
405
|
if json_output:
|
|
371
|
-
return self._output_result_json(agent_result, skills_result)
|
|
372
|
-
return self._display_result(agent_result, skills_result)
|
|
406
|
+
return self._output_result_json(agent_result, skills_result, archive_result)
|
|
407
|
+
return self._display_result(agent_result, skills_result, archive_result)
|
|
373
408
|
|
|
374
409
|
def _display_preview(
|
|
375
410
|
self,
|
|
@@ -377,6 +412,7 @@ class AutoConfigureCommand(BaseCommand):
|
|
|
377
412
|
skills_recommendations=None,
|
|
378
413
|
configure_agents=True,
|
|
379
414
|
configure_skills=True,
|
|
415
|
+
agent_review_results=None,
|
|
380
416
|
) -> CommandResult:
|
|
381
417
|
"""Display configuration preview with Rich formatting."""
|
|
382
418
|
if not self.console:
|
|
@@ -386,6 +422,7 @@ class AutoConfigureCommand(BaseCommand):
|
|
|
386
422
|
skills_recommendations,
|
|
387
423
|
configure_agents,
|
|
388
424
|
configure_skills,
|
|
425
|
+
agent_review_results,
|
|
389
426
|
)
|
|
390
427
|
|
|
391
428
|
# Only show toolchain and agents if configuring agents
|
|
@@ -457,6 +494,10 @@ class AutoConfigureCommand(BaseCommand):
|
|
|
457
494
|
f" {severity_icon} {issue.message}", style="yellow"
|
|
458
495
|
)
|
|
459
496
|
|
|
497
|
+
# Display agent review results
|
|
498
|
+
if configure_agents and agent_review_results:
|
|
499
|
+
self._display_agent_review(agent_review_results)
|
|
500
|
+
|
|
460
501
|
# Display recommended skills
|
|
461
502
|
if configure_skills and skills_recommendations:
|
|
462
503
|
self.console.print("\n🎯 Recommended Skills:", style="bold blue")
|
|
@@ -471,6 +512,7 @@ class AutoConfigureCommand(BaseCommand):
|
|
|
471
512
|
skills_recommendations=None,
|
|
472
513
|
configure_agents=True,
|
|
473
514
|
configure_skills=True,
|
|
515
|
+
agent_review_results=None,
|
|
474
516
|
) -> CommandResult:
|
|
475
517
|
"""Display preview in plain text (fallback when Rich not available)."""
|
|
476
518
|
if configure_agents and agent_preview:
|
|
@@ -517,6 +559,7 @@ class AutoConfigureCommand(BaseCommand):
|
|
|
517
559
|
skills_recommendations=None,
|
|
518
560
|
configure_agents=True,
|
|
519
561
|
configure_skills=True,
|
|
562
|
+
agent_review_results=None,
|
|
520
563
|
) -> bool:
|
|
521
564
|
"""Ask user to confirm deployment."""
|
|
522
565
|
has_agents = (
|
|
@@ -566,11 +609,16 @@ class AutoConfigureCommand(BaseCommand):
|
|
|
566
609
|
return False
|
|
567
610
|
|
|
568
611
|
def _display_result(
|
|
569
|
-
self,
|
|
612
|
+
self,
|
|
613
|
+
agent_result: Optional = None,
|
|
614
|
+
skills_result: Optional[dict] = None,
|
|
615
|
+
archive_result: Optional[dict] = None,
|
|
570
616
|
) -> CommandResult:
|
|
571
617
|
"""Display configuration result."""
|
|
572
618
|
if not self.console:
|
|
573
|
-
return self._display_result_plain(
|
|
619
|
+
return self._display_result_plain(
|
|
620
|
+
agent_result, skills_result, archive_result
|
|
621
|
+
)
|
|
574
622
|
|
|
575
623
|
# Determine overall success
|
|
576
624
|
agent_success = (
|
|
@@ -581,26 +629,11 @@ class AutoConfigureCommand(BaseCommand):
|
|
|
581
629
|
skills_success = not skills_result or (
|
|
582
630
|
skills_result and not skills_result.get("errors")
|
|
583
631
|
)
|
|
584
|
-
|
|
632
|
+
archive_success = not archive_result or not archive_result.get("errors")
|
|
633
|
+
overall_success = agent_success and skills_success and archive_success
|
|
585
634
|
|
|
586
635
|
# Display summary
|
|
587
636
|
if overall_success:
|
|
588
|
-
# Build summary message
|
|
589
|
-
deployed_items = []
|
|
590
|
-
if agent_result and agent_result.deployed_agents:
|
|
591
|
-
deployed_items.append(f"{len(agent_result.deployed_agents)} agent(s)")
|
|
592
|
-
if skills_result and skills_result.get("deployed"):
|
|
593
|
-
deployed_items.append(f"{len(skills_result['deployed'])} skill(s)")
|
|
594
|
-
|
|
595
|
-
panel_text = "✅ Auto-configuration completed successfully!\n\n"
|
|
596
|
-
if deployed_items:
|
|
597
|
-
panel_text += f"Deployed {' and '.join(deployed_items)}"
|
|
598
|
-
else:
|
|
599
|
-
panel_text += "No deployments needed"
|
|
600
|
-
|
|
601
|
-
panel = Panel(panel_text, title="Success", border_style="green")
|
|
602
|
-
self.console.print(panel)
|
|
603
|
-
|
|
604
637
|
# Show deployed agents
|
|
605
638
|
if agent_result and agent_result.deployed_agents:
|
|
606
639
|
self.console.print("\n📦 Deployed Agents:", style="bold green")
|
|
@@ -613,6 +646,15 @@ class AutoConfigureCommand(BaseCommand):
|
|
|
613
646
|
for skill in skills_result["deployed"]:
|
|
614
647
|
self.console.print(f" ✓ {skill}")
|
|
615
648
|
|
|
649
|
+
# Show archived agents
|
|
650
|
+
if archive_result and archive_result.get("archived"):
|
|
651
|
+
self.console.print("\n📁 Archived Agents:", style="bold yellow")
|
|
652
|
+
for archived in archive_result["archived"]:
|
|
653
|
+
self.console.print(f" → {archived['name']}")
|
|
654
|
+
|
|
655
|
+
# Show restart notification
|
|
656
|
+
self._show_restart_notification(agent_result, skills_result, archive_result)
|
|
657
|
+
|
|
616
658
|
return CommandResult.success_result()
|
|
617
659
|
|
|
618
660
|
# Partial or complete failure
|
|
@@ -654,7 +696,10 @@ class AutoConfigureCommand(BaseCommand):
|
|
|
654
696
|
)
|
|
655
697
|
|
|
656
698
|
def _display_result_plain(
|
|
657
|
-
self,
|
|
699
|
+
self,
|
|
700
|
+
agent_result: Optional = None,
|
|
701
|
+
skills_result: Optional[dict] = None,
|
|
702
|
+
archive_result: Optional[dict] = None,
|
|
658
703
|
) -> CommandResult:
|
|
659
704
|
"""Display result in plain text (fallback)."""
|
|
660
705
|
# Determine overall success
|
|
@@ -725,6 +770,7 @@ class AutoConfigureCommand(BaseCommand):
|
|
|
725
770
|
skills_recommendations=None,
|
|
726
771
|
configure_agents=True,
|
|
727
772
|
configure_skills=True,
|
|
773
|
+
agent_review_results=None,
|
|
728
774
|
) -> CommandResult:
|
|
729
775
|
"""Output preview as JSON."""
|
|
730
776
|
output = {}
|
|
@@ -790,7 +836,10 @@ class AutoConfigureCommand(BaseCommand):
|
|
|
790
836
|
return CommandResult.success_result(data=output)
|
|
791
837
|
|
|
792
838
|
def _output_result_json(
|
|
793
|
-
self,
|
|
839
|
+
self,
|
|
840
|
+
agent_result: Optional = None,
|
|
841
|
+
skills_result: Optional[dict] = None,
|
|
842
|
+
archive_result: Optional[dict] = None,
|
|
794
843
|
) -> CommandResult:
|
|
795
844
|
"""Output result as JSON."""
|
|
796
845
|
output = {}
|
|
@@ -866,3 +915,139 @@ class AutoConfigureCommand(BaseCommand):
|
|
|
866
915
|
except Exception as e:
|
|
867
916
|
self.logger.error(f"Failed to deploy skills: {e}")
|
|
868
917
|
return {"deployed": [], "errors": [str(e)]}
|
|
918
|
+
|
|
919
|
+
def _review_project_agents(self, agent_preview) -> Optional[dict]:
|
|
920
|
+
"""Review existing project agents and categorize them.
|
|
921
|
+
|
|
922
|
+
Args:
|
|
923
|
+
agent_preview: Agent preview result with recommendations
|
|
924
|
+
|
|
925
|
+
Returns:
|
|
926
|
+
Dictionary with categorized agents or None if no preview
|
|
927
|
+
"""
|
|
928
|
+
if not agent_preview:
|
|
929
|
+
return None
|
|
930
|
+
|
|
931
|
+
from ...services.agents.agent_review_service import AgentReviewService
|
|
932
|
+
from ...services.agents.deployment.remote_agent_discovery_service import (
|
|
933
|
+
RemoteAgentDiscoveryService,
|
|
934
|
+
)
|
|
935
|
+
|
|
936
|
+
# Get managed agents from cache
|
|
937
|
+
remote_agents_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
|
|
938
|
+
if not remote_agents_dir.exists():
|
|
939
|
+
self.logger.debug("No remote agents cache found")
|
|
940
|
+
return None
|
|
941
|
+
|
|
942
|
+
# Discover managed agents
|
|
943
|
+
discovery_service = RemoteAgentDiscoveryService(remote_agents_dir)
|
|
944
|
+
managed_agents = discovery_service.discover_remote_agents()
|
|
945
|
+
|
|
946
|
+
if not managed_agents:
|
|
947
|
+
self.logger.debug("No managed agents found in cache")
|
|
948
|
+
return None
|
|
949
|
+
|
|
950
|
+
# Get recommended agent IDs
|
|
951
|
+
recommended_ids = set()
|
|
952
|
+
if agent_preview.recommendations:
|
|
953
|
+
recommended_ids = {rec.agent_id for rec in agent_preview.recommendations}
|
|
954
|
+
|
|
955
|
+
# Review project agents
|
|
956
|
+
project_agents_dir = Path.cwd() / ".claude" / "agents"
|
|
957
|
+
review_service = AgentReviewService()
|
|
958
|
+
return review_service.review_project_agents(
|
|
959
|
+
project_agents_dir, managed_agents, recommended_ids
|
|
960
|
+
)
|
|
961
|
+
|
|
962
|
+
def _archive_agents(self, agents_to_archive: list[dict]) -> dict:
|
|
963
|
+
"""Archive unused agents by moving them to .claude/agents/unused/.
|
|
964
|
+
|
|
965
|
+
Args:
|
|
966
|
+
agents_to_archive: List of agent dicts to archive
|
|
967
|
+
|
|
968
|
+
Returns:
|
|
969
|
+
Dictionary with archival results
|
|
970
|
+
"""
|
|
971
|
+
from ...services.agents.agent_review_service import AgentReviewService
|
|
972
|
+
|
|
973
|
+
project_agents_dir = Path.cwd() / ".claude" / "agents"
|
|
974
|
+
review_service = AgentReviewService()
|
|
975
|
+
return review_service.archive_agents(agents_to_archive, project_agents_dir)
|
|
976
|
+
|
|
977
|
+
def _display_agent_review(self, review_results: dict) -> None:
|
|
978
|
+
"""Display agent review results in the preview.
|
|
979
|
+
|
|
980
|
+
Args:
|
|
981
|
+
review_results: Dictionary with categorized agents
|
|
982
|
+
"""
|
|
983
|
+
if not self.console:
|
|
984
|
+
return
|
|
985
|
+
|
|
986
|
+
# Count agents to archive
|
|
987
|
+
unused_count = len(review_results.get("unused", []))
|
|
988
|
+
outdated_count = len(review_results.get("outdated", []))
|
|
989
|
+
custom_count = len(review_results.get("custom", []))
|
|
990
|
+
|
|
991
|
+
if unused_count > 0 or outdated_count > 0 or custom_count > 0:
|
|
992
|
+
self.console.print("\n📋 Existing Agents Review:", style="bold blue")
|
|
993
|
+
|
|
994
|
+
# Show custom agents (will be preserved)
|
|
995
|
+
if custom_count > 0:
|
|
996
|
+
self.console.print(
|
|
997
|
+
"\n [green]Custom agents (will be preserved):[/green]"
|
|
998
|
+
)
|
|
999
|
+
for agent in review_results["custom"]:
|
|
1000
|
+
self.console.print(f" ✓ {agent['name']} (v{agent['version']})")
|
|
1001
|
+
|
|
1002
|
+
# Show agents to be archived
|
|
1003
|
+
if unused_count > 0:
|
|
1004
|
+
self.console.print(
|
|
1005
|
+
"\n [yellow]Agents to archive (not needed for this toolchain):[/yellow]"
|
|
1006
|
+
)
|
|
1007
|
+
for agent in review_results["unused"]:
|
|
1008
|
+
reason = (
|
|
1009
|
+
f"outdated (v{agent['current_version']} → v{agent['available_version']})"
|
|
1010
|
+
if "current_version" in agent
|
|
1011
|
+
else "not recommended"
|
|
1012
|
+
)
|
|
1013
|
+
self.console.print(f" → {agent['name']} ({reason})")
|
|
1014
|
+
self.console.print(
|
|
1015
|
+
" [dim]Will be moved to .claude/agents/unused/[/dim]"
|
|
1016
|
+
)
|
|
1017
|
+
|
|
1018
|
+
def _show_restart_notification(
|
|
1019
|
+
self, agent_result=None, skills_result=None, archive_result=None
|
|
1020
|
+
) -> None:
|
|
1021
|
+
"""Show restart notification after configuration is complete.
|
|
1022
|
+
|
|
1023
|
+
Args:
|
|
1024
|
+
agent_result: Agent deployment results
|
|
1025
|
+
skills_result: Skills deployment results
|
|
1026
|
+
archive_result: Agent archival results
|
|
1027
|
+
"""
|
|
1028
|
+
if not self.console:
|
|
1029
|
+
return
|
|
1030
|
+
|
|
1031
|
+
# Build summary of changes
|
|
1032
|
+
changes = []
|
|
1033
|
+
if agent_result and agent_result.deployed_agents:
|
|
1034
|
+
changes.append(f"Deployed {len(agent_result.deployed_agents)} agent(s)")
|
|
1035
|
+
if skills_result and skills_result.get("deployed"):
|
|
1036
|
+
changes.append(f"Deployed {len(skills_result['deployed'])} skill(s)")
|
|
1037
|
+
if archive_result and archive_result.get("archived"):
|
|
1038
|
+
changes.append(
|
|
1039
|
+
f"Archived {len(archive_result['archived'])} unused agent(s) to .claude/agents/unused/"
|
|
1040
|
+
)
|
|
1041
|
+
|
|
1042
|
+
if changes:
|
|
1043
|
+
self.console.print("\n" + "=" * 70)
|
|
1044
|
+
self.console.print("✅ [bold green]Configuration complete![/bold green]")
|
|
1045
|
+
self.console.print(
|
|
1046
|
+
"\n🔄 [bold yellow]Please restart Claude Code to apply changes:[/bold yellow]"
|
|
1047
|
+
)
|
|
1048
|
+
self.console.print(" - Quit Claude Code completely")
|
|
1049
|
+
self.console.print(" - Relaunch Claude Code")
|
|
1050
|
+
self.console.print("\n[bold]Changes applied:[/bold]")
|
|
1051
|
+
for change in changes:
|
|
1052
|
+
self.console.print(f" • {change}")
|
|
1053
|
+
self.console.print("=" * 70 + "\n")
|
|
@@ -68,10 +68,12 @@ class ConfigCommand(BaseCommand):
|
|
|
68
68
|
|
|
69
69
|
def validate_args(self, args) -> str:
|
|
70
70
|
"""Validate command arguments."""
|
|
71
|
+
# If no config_command specified, default to 'auto' (preview mode)
|
|
71
72
|
if not hasattr(args, "config_command") or not args.config_command:
|
|
72
|
-
|
|
73
|
+
args.config_command = "auto"
|
|
74
|
+
args.preview = True # Default to preview when no args
|
|
73
75
|
|
|
74
|
-
valid_commands = ["validate", "view", "status"]
|
|
76
|
+
valid_commands = ["validate", "view", "status", "auto", "gitignore"]
|
|
75
77
|
if args.config_command not in valid_commands:
|
|
76
78
|
return f"Unknown config command: {args.config_command}. Valid commands: {', '.join(valid_commands)}"
|
|
77
79
|
|
|
@@ -85,6 +87,11 @@ class ConfigCommand(BaseCommand):
|
|
|
85
87
|
return self._view_config(args)
|
|
86
88
|
if args.config_command == "status":
|
|
87
89
|
return self._show_config_status(args)
|
|
90
|
+
if args.config_command == "gitignore":
|
|
91
|
+
self._show_gitignore_recommendations()
|
|
92
|
+
return CommandResult.success_result("Gitignore recommendations displayed")
|
|
93
|
+
if args.config_command == "auto":
|
|
94
|
+
return self._auto_configure(args)
|
|
88
95
|
return CommandResult.error_result(
|
|
89
96
|
f"Unknown config command: {args.config_command}"
|
|
90
97
|
)
|
|
@@ -450,6 +457,85 @@ class ConfigCommand(BaseCommand):
|
|
|
450
457
|
|
|
451
458
|
return flattened
|
|
452
459
|
|
|
460
|
+
def _show_gitignore_recommendations(self) -> None:
|
|
461
|
+
"""Show recommended .gitignore patterns for Claude MPM projects.
|
|
462
|
+
|
|
463
|
+
This displays recommended gitignore patterns without making any changes
|
|
464
|
+
to the user's .gitignore file. Users can choose to apply these manually.
|
|
465
|
+
"""
|
|
466
|
+
console.print(
|
|
467
|
+
"\n[bold cyan]Recommended .gitignore Patterns for Claude MPM[/bold cyan]\n"
|
|
468
|
+
)
|
|
469
|
+
|
|
470
|
+
console.print("[bold]Track agent memories, ignore runtime data:[/bold]")
|
|
471
|
+
console.print("[dim]# Add this to your .gitignore:[/dim]\n")
|
|
472
|
+
|
|
473
|
+
# The recommended gitignore block
|
|
474
|
+
recommended_patterns = """# Claude MPM - Track memories, ignore runtime data
|
|
475
|
+
.claude-mpm/*
|
|
476
|
+
!.claude-mpm/memories/
|
|
477
|
+
.claude-mpm/memories/*
|
|
478
|
+
!.claude-mpm/memories/*.md"""
|
|
479
|
+
|
|
480
|
+
# Display in a panel for clarity
|
|
481
|
+
from rich.panel import Panel
|
|
482
|
+
|
|
483
|
+
panel = Panel(
|
|
484
|
+
recommended_patterns,
|
|
485
|
+
title="Recommended .gitignore Patterns",
|
|
486
|
+
border_style="green",
|
|
487
|
+
padding=(1, 2),
|
|
488
|
+
)
|
|
489
|
+
console.print(panel)
|
|
490
|
+
|
|
491
|
+
# Explanation
|
|
492
|
+
console.print("\n[bold]What this does:[/bold]")
|
|
493
|
+
console.print(
|
|
494
|
+
" • Track [cyan].claude-mpm/memories/*.md[/cyan] (agent memories are valuable)"
|
|
495
|
+
)
|
|
496
|
+
console.print(
|
|
497
|
+
" • Ignore everything else in [dim].claude-mpm/[/dim] (cache, logs, sessions, tmp)"
|
|
498
|
+
)
|
|
499
|
+
console.print(
|
|
500
|
+
" • Services (mcp-vector-search, kuzu-memory, etc.) handle their own .gitignore"
|
|
501
|
+
)
|
|
502
|
+
|
|
503
|
+
console.print(
|
|
504
|
+
"\n[yellow]Note:[/yellow] These patterns are recommendations only."
|
|
505
|
+
)
|
|
506
|
+
console.print(" Add them manually to your .gitignore if desired.\n")
|
|
507
|
+
|
|
508
|
+
def _auto_configure(self, args) -> CommandResult:
|
|
509
|
+
"""
|
|
510
|
+
Run auto-configuration to detect toolchain and recommend agents/skills.
|
|
511
|
+
|
|
512
|
+
This delegates to the AutoConfigureCommand for the actual implementation.
|
|
513
|
+
"""
|
|
514
|
+
# Check if user wants gitignore recommendations
|
|
515
|
+
if hasattr(args, "gitignore") and args.gitignore:
|
|
516
|
+
self._show_gitignore_recommendations()
|
|
517
|
+
return CommandResult.success_result("Gitignore recommendations displayed")
|
|
518
|
+
|
|
519
|
+
try:
|
|
520
|
+
# Import AutoConfigureCommand
|
|
521
|
+
from .auto_configure import AutoConfigureCommand
|
|
522
|
+
|
|
523
|
+
# Create auto-configure command instance
|
|
524
|
+
auto_cmd = AutoConfigureCommand()
|
|
525
|
+
|
|
526
|
+
# Run auto-configuration
|
|
527
|
+
return auto_cmd.run(args)
|
|
528
|
+
|
|
529
|
+
except ImportError as e:
|
|
530
|
+
self.logger.error(f"AutoConfigureCommand not available: {e}")
|
|
531
|
+
return CommandResult.error_result(
|
|
532
|
+
"Auto-configuration feature not available. "
|
|
533
|
+
"Please ensure all dependencies are installed."
|
|
534
|
+
)
|
|
535
|
+
except Exception as e:
|
|
536
|
+
self.logger.error(f"Auto-configuration failed: {e}", exc_info=True)
|
|
537
|
+
return CommandResult.error_result(f"Auto-configuration failed: {e}")
|
|
538
|
+
|
|
453
539
|
|
|
454
540
|
def manage_config(args) -> int:
|
|
455
541
|
"""Main entry point for configuration management commands.
|