claude-mpm 4.0.23__py3-none-any.whl → 4.0.28__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. claude_mpm/BUILD_NUMBER +1 -1
  2. claude_mpm/VERSION +1 -1
  3. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +4 -1
  4. claude_mpm/agents/BASE_PM.md +3 -0
  5. claude_mpm/agents/templates/code_analyzer.json +2 -2
  6. claude_mpm/cli/commands/agents.py +453 -113
  7. claude_mpm/cli/commands/aggregate.py +107 -15
  8. claude_mpm/cli/commands/cleanup.py +142 -10
  9. claude_mpm/cli/commands/config.py +358 -224
  10. claude_mpm/cli/commands/info.py +184 -75
  11. claude_mpm/cli/commands/mcp_command_router.py +5 -76
  12. claude_mpm/cli/commands/mcp_install_commands.py +68 -36
  13. claude_mpm/cli/commands/mcp_server_commands.py +30 -37
  14. claude_mpm/cli/commands/memory.py +331 -61
  15. claude_mpm/cli/commands/monitor.py +101 -7
  16. claude_mpm/cli/commands/run.py +368 -8
  17. claude_mpm/cli/commands/tickets.py +206 -24
  18. claude_mpm/cli/parsers/mcp_parser.py +3 -0
  19. claude_mpm/cli/shared/__init__.py +40 -0
  20. claude_mpm/cli/shared/argument_patterns.py +212 -0
  21. claude_mpm/cli/shared/command_base.py +234 -0
  22. claude_mpm/cli/shared/error_handling.py +238 -0
  23. claude_mpm/cli/shared/output_formatters.py +231 -0
  24. claude_mpm/config/agent_config.py +29 -8
  25. claude_mpm/core/container.py +6 -4
  26. claude_mpm/core/service_registry.py +4 -2
  27. claude_mpm/core/shared/__init__.py +17 -0
  28. claude_mpm/core/shared/config_loader.py +320 -0
  29. claude_mpm/core/shared/path_resolver.py +277 -0
  30. claude_mpm/core/shared/singleton_manager.py +208 -0
  31. claude_mpm/hooks/claude_hooks/memory_integration.py +4 -2
  32. claude_mpm/hooks/claude_hooks/response_tracking.py +14 -3
  33. claude_mpm/hooks/memory_integration_hook.py +11 -2
  34. claude_mpm/services/agents/deployment/agent_deployment.py +49 -23
  35. claude_mpm/services/agents/deployment/deployment_wrapper.py +71 -0
  36. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +1 -0
  37. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +43 -0
  38. claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +4 -0
  39. claude_mpm/services/agents/deployment/processors/agent_processor.py +1 -1
  40. claude_mpm/services/agents/loading/base_agent_manager.py +11 -3
  41. claude_mpm/services/agents/registry/deployed_agent_discovery.py +14 -5
  42. claude_mpm/services/event_aggregator.py +4 -2
  43. claude_mpm/services/mcp_gateway/config/config_loader.py +89 -28
  44. claude_mpm/services/mcp_gateway/config/configuration.py +29 -0
  45. claude_mpm/services/mcp_gateway/registry/service_registry.py +22 -5
  46. claude_mpm/services/memory/builder.py +6 -1
  47. claude_mpm/services/response_tracker.py +3 -1
  48. claude_mpm/services/runner_configuration_service.py +15 -6
  49. claude_mpm/services/shared/__init__.py +20 -0
  50. claude_mpm/services/shared/async_service_base.py +219 -0
  51. claude_mpm/services/shared/config_service_base.py +292 -0
  52. claude_mpm/services/shared/lifecycle_service_base.py +317 -0
  53. claude_mpm/services/shared/manager_base.py +303 -0
  54. claude_mpm/services/shared/service_factory.py +308 -0
  55. {claude_mpm-4.0.23.dist-info → claude_mpm-4.0.28.dist-info}/METADATA +19 -13
  56. {claude_mpm-4.0.23.dist-info → claude_mpm-4.0.28.dist-info}/RECORD +60 -44
  57. {claude_mpm-4.0.23.dist-info → claude_mpm-4.0.28.dist-info}/WHEEL +0 -0
  58. {claude_mpm-4.0.23.dist-info → claude_mpm-4.0.28.dist-info}/entry_points.txt +0 -0
  59. {claude_mpm-4.0.23.dist-info → claude_mpm-4.0.28.dist-info}/licenses/LICENSE +0 -0
  60. {claude_mpm-4.0.23.dist-info → claude_mpm-4.0.28.dist-info}/top_level.txt +0 -0
@@ -2,10 +2,18 @@
2
2
  Agents command implementation for claude-mpm.
3
3
 
4
4
  WHY: This module manages Claude Code native agents, including listing, deploying,
5
- and cleaning agent deployments.
5
+ and cleaning agent deployments. Refactored to use shared utilities for consistency.
6
+
7
+ DESIGN DECISIONS:
8
+ - Use AgentCommand base class for consistent CLI patterns
9
+ - Leverage shared utilities for argument parsing and output formatting
10
+ - Maintain backward compatibility with existing functionality
11
+ - Support multiple output formats (json, yaml, table, text)
6
12
  """
7
13
 
8
14
  import json
15
+ import os
16
+ from pathlib import Path
9
17
  from typing import Any, Dict, Optional
10
18
 
11
19
  import yaml
@@ -14,145 +22,476 @@ from ...agents.frontmatter_validator import FrontmatterValidator
14
22
  from ...constants import AgentCommands
15
23
  from ...core.agent_registry import AgentRegistryAdapter
16
24
  from ...core.config import Config
17
- from ...core.logger import get_logger
25
+ from ...core.shared.config_loader import ConfigLoader
26
+ from ..shared import AgentCommand, CommandResult, add_agent_arguments, add_output_arguments
18
27
  from ..utils import get_agent_versions_display
19
28
 
20
29
 
21
- def manage_agents(args):
22
- """
23
- Manage Claude Code native agents.
30
+ class AgentsCommand(AgentCommand):
31
+ """Agent management command using shared utilities."""
24
32
 
25
- WHY: Claude Code agents need to be deployed and managed. This command provides
26
- a unified interface for all agent-related operations.
33
+ def __init__(self):
34
+ super().__init__("agents")
35
+ self._deployment_service = None
27
36
 
28
- DESIGN DECISION: When no subcommand is provided, we show the current agent
29
- versions as a quick status check. This matches the behavior users see at startup.
37
+ @property
38
+ def deployment_service(self):
39
+ """Get deployment service instance (lazy loaded)."""
40
+ if self._deployment_service is None:
41
+ try:
42
+ from ...services import AgentDeploymentService
43
+ from ...services.agents.deployment.deployment_wrapper import DeploymentServiceWrapper
44
+ base_service = AgentDeploymentService()
45
+ self._deployment_service = DeploymentServiceWrapper(base_service)
46
+ except ImportError:
47
+ raise ImportError("Agent deployment service not available")
48
+ return self._deployment_service
49
+
50
+ def validate_args(self, args) -> str:
51
+ """Validate command arguments."""
52
+ # Most agent commands are optional, so basic validation
53
+ return None
54
+
55
+ def run(self, args) -> CommandResult:
56
+ """Execute the agent command."""
57
+ try:
58
+ # Handle default case (no subcommand)
59
+ if not hasattr(args, 'agents_command') or not args.agents_command:
60
+ return self._show_agent_versions(args)
61
+
62
+ # Route to appropriate subcommand
63
+ command_map = {
64
+ AgentCommands.LIST.value: self._list_agents,
65
+ AgentCommands.DEPLOY.value: lambda a: self._deploy_agents(a, force=False),
66
+ AgentCommands.FORCE_DEPLOY.value: lambda a: self._deploy_agents(a, force=True),
67
+ AgentCommands.CLEAN.value: self._clean_agents,
68
+ AgentCommands.VIEW.value: self._view_agent,
69
+ AgentCommands.FIX.value: self._fix_agents,
70
+ "deps-check": self._check_agent_dependencies,
71
+ "deps-install": self._install_agent_dependencies,
72
+ "deps-list": self._list_agent_dependencies,
73
+ "deps-fix": self._fix_agent_dependencies,
74
+ }
75
+
76
+ if args.agents_command in command_map:
77
+ return command_map[args.agents_command](args)
78
+ else:
79
+ return CommandResult.error_result(f"Unknown agent command: {args.agents_command}")
80
+
81
+ except ImportError as e:
82
+ self.logger.error("Agent deployment service not available")
83
+ return CommandResult.error_result("Agent deployment service not available")
84
+ except Exception as e:
85
+ self.logger.error(f"Error managing agents: {e}", exc_info=True)
86
+ return CommandResult.error_result(f"Error managing agents: {e}")
87
+
88
+ def _show_agent_versions(self, args) -> CommandResult:
89
+ """Show current agent versions as default action."""
90
+ try:
91
+ agent_versions = get_agent_versions_display()
30
92
 
31
- Args:
32
- args: Parsed command line arguments with agents_command attribute
33
- """
34
- logger = get_logger("cli")
93
+ output_format = getattr(args, 'format', 'text')
94
+ if output_format in ['json', 'yaml']:
95
+ # Parse the agent versions display into structured data
96
+ if agent_versions:
97
+ data = {"agent_versions": agent_versions, "has_agents": True}
98
+ return CommandResult.success_result("Agent versions retrieved", data=data)
99
+ else:
100
+ data = {"agent_versions": None, "has_agents": False, "suggestion": "To deploy agents, run: claude-mpm --mpm:agents deploy"}
101
+ return CommandResult.success_result("No deployed agents found", data=data)
102
+ else:
103
+ # Text output
104
+ if agent_versions:
105
+ print(agent_versions)
106
+ return CommandResult.success_result("Agent versions displayed")
107
+ else:
108
+ print("No deployed agents found")
109
+ print("\nTo deploy agents, run: claude-mpm --mpm:agents deploy")
110
+ return CommandResult.success_result("No deployed agents found")
111
+
112
+ except Exception as e:
113
+ self.logger.error(f"Error getting agent versions: {e}", exc_info=True)
114
+ return CommandResult.error_result(f"Error getting agent versions: {e}")
115
+
116
+
117
+ def _list_agents(self, args) -> CommandResult:
118
+ """List available or deployed agents."""
119
+ try:
120
+ output_format = getattr(args, 'format', 'text')
121
+
122
+ if hasattr(args, "by_tier") and args.by_tier:
123
+ return self._list_agents_by_tier(args)
124
+ elif getattr(args, 'system', False):
125
+ return self._list_system_agents(args)
126
+ elif getattr(args, 'deployed', False):
127
+ return self._list_deployed_agents(args)
128
+ else:
129
+ # Default: show usage
130
+ usage_msg = "Use --system to list system agents, --deployed to list deployed agents, or --by-tier to group by precedence"
35
131
 
36
- try:
37
- import os
38
- from pathlib import Path
132
+ if output_format in ['json', 'yaml']:
133
+ return CommandResult.error_result(
134
+ "No list option specified",
135
+ data={"usage": usage_msg, "available_options": ["--system", "--deployed", "--by-tier"]}
136
+ )
137
+ else:
138
+ print(usage_msg)
139
+ return CommandResult.error_result("No list option specified")
140
+
141
+ except Exception as e:
142
+ self.logger.error(f"Error listing agents: {e}", exc_info=True)
143
+ return CommandResult.error_result(f"Error listing agents: {e}")
144
+
145
+ def _list_system_agents(self, args) -> CommandResult:
146
+ """List available agent templates."""
147
+ try:
148
+ agents = self.deployment_service.list_available_agents()
149
+ output_format = getattr(args, 'format', 'text')
150
+
151
+ if output_format in ['json', 'yaml']:
152
+ return CommandResult.success_result(
153
+ f"Found {len(agents)} agent templates",
154
+ data={"agents": agents, "count": len(agents)}
155
+ )
156
+ else:
157
+ # Text output
158
+ print("Available Agent Templates:")
159
+ print("-" * 80)
160
+ if not agents:
161
+ print("No agent templates found")
162
+ else:
163
+ for agent in agents:
164
+ print(f"📄 {agent['file']}")
165
+ if "name" in agent:
166
+ print(f" Name: {agent['name']}")
167
+ if "description" in agent:
168
+ print(f" Description: {agent['description']}")
169
+ if "version" in agent:
170
+ print(f" Version: {agent['version']}")
171
+ print()
172
+
173
+ return CommandResult.success_result(f"Listed {len(agents)} agent templates")
174
+
175
+ except Exception as e:
176
+ self.logger.error(f"Error listing system agents: {e}", exc_info=True)
177
+ return CommandResult.error_result(f"Error listing system agents: {e}")
178
+
179
+ def _list_deployed_agents(self, args) -> CommandResult:
180
+ """List deployed agents."""
181
+ try:
182
+ verification = self.deployment_service.verify_deployment()
183
+ output_format = getattr(args, 'format', 'text')
184
+
185
+ if output_format in ['json', 'yaml']:
186
+ return CommandResult.success_result(
187
+ f"Found {len(verification['agents_found'])} deployed agents",
188
+ data={
189
+ "agents": verification["agents_found"],
190
+ "warnings": verification.get("warnings", []),
191
+ "count": len(verification["agents_found"])
192
+ }
193
+ )
194
+ else:
195
+ # Text output
196
+ print("Deployed Agents:")
197
+ print("-" * 80)
198
+ if not verification["agents_found"]:
199
+ print("No deployed agents found")
200
+ else:
201
+ for agent in verification["agents_found"]:
202
+ print(f"📄 {agent['file']}")
203
+ if "name" in agent:
204
+ print(f" Name: {agent['name']}")
205
+ print(f" Path: {agent['path']}")
206
+ print()
207
+
208
+ if verification["warnings"]:
209
+ print("\nWarnings:")
210
+ for warning in verification["warnings"]:
211
+ print(f" ⚠️ {warning}")
212
+
213
+ return CommandResult.success_result(f"Listed {len(verification['agents_found'])} deployed agents")
214
+
215
+ except Exception as e:
216
+ self.logger.error(f"Error listing deployed agents: {e}", exc_info=True)
217
+ return CommandResult.error_result(f"Error listing deployed agents: {e}")
218
+
219
+ def _list_agents_by_tier(self, args) -> CommandResult:
220
+ """List agents grouped by tier/precedence."""
221
+ try:
222
+ agents_by_tier = self.deployment_service.list_agents_by_tier()
223
+ output_format = getattr(args, 'format', 'text')
224
+
225
+ if output_format in ['json', 'yaml']:
226
+ return CommandResult.success_result(
227
+ "Agents listed by tier",
228
+ data=agents_by_tier
229
+ )
230
+ else:
231
+ # Text output
232
+ print("Agents by Tier/Precedence:")
233
+ print("=" * 50)
234
+
235
+ for tier, agents in agents_by_tier.items():
236
+ print(f"\n{tier.upper()}:")
237
+ print("-" * 20)
238
+ if agents:
239
+ for agent in agents:
240
+ print(f" • {agent}")
241
+ else:
242
+ print(" (none)")
243
+
244
+ return CommandResult.success_result("Agents listed by tier")
245
+
246
+ except Exception as e:
247
+ self.logger.error(f"Error listing agents by tier: {e}", exc_info=True)
248
+ return CommandResult.error_result(f"Error listing agents by tier: {e}")
249
+
250
+ def _deploy_agents(self, args, force=False) -> CommandResult:
251
+ """Deploy both system and project agents."""
252
+ try:
253
+ # Deploy system agents
254
+ system_result = self.deployment_service.deploy_system_agents(force=force)
255
+
256
+ # Deploy project agents if they exist
257
+ project_result = self.deployment_service.deploy_project_agents(force=force)
258
+
259
+ # Combine results
260
+ total_deployed = system_result.get('deployed_count', 0) + project_result.get('deployed_count', 0)
261
+
262
+ output_format = getattr(args, 'format', 'text')
263
+ if output_format in ['json', 'yaml']:
264
+ return CommandResult.success_result(
265
+ f"Deployed {total_deployed} agents",
266
+ data={
267
+ "system_agents": system_result,
268
+ "project_agents": project_result,
269
+ "total_deployed": total_deployed
270
+ }
271
+ )
272
+ else:
273
+ # Text output
274
+ if system_result.get('deployed_count', 0) > 0:
275
+ print(f"✓ Deployed {system_result['deployed_count']} system agents")
276
+ if project_result.get('deployed_count', 0) > 0:
277
+ print(f"✓ Deployed {project_result['deployed_count']} project agents")
278
+
279
+ if total_deployed == 0:
280
+ print("No agents were deployed (all up to date)")
281
+
282
+ return CommandResult.success_result(f"Deployed {total_deployed} agents")
283
+
284
+ except Exception as e:
285
+ self.logger.error(f"Error deploying agents: {e}", exc_info=True)
286
+ return CommandResult.error_result(f"Error deploying agents: {e}")
287
+
288
+ def _clean_agents(self, args) -> CommandResult:
289
+ """Clean deployed agents."""
290
+ try:
291
+ result = self.deployment_service.clean_deployment()
292
+
293
+ output_format = getattr(args, 'format', 'text')
294
+ if output_format in ['json', 'yaml']:
295
+ return CommandResult.success_result(
296
+ f"Cleaned {result.get('cleaned_count', 0)} agents",
297
+ data=result
298
+ )
299
+ else:
300
+ # Text output
301
+ cleaned_count = result.get('cleaned_count', 0)
302
+ if cleaned_count > 0:
303
+ print(f"✓ Cleaned {cleaned_count} deployed agents")
304
+ else:
305
+ print("No deployed agents to clean")
39
306
 
40
- from ...services import AgentDeploymentService
307
+ return CommandResult.success_result(f"Cleaned {cleaned_count} agents")
41
308
 
42
- # Determine the user's working directory from environment
43
- # This ensures agents are deployed to the correct directory
44
- user_working_dir = None
45
- if "CLAUDE_MPM_USER_PWD" in os.environ:
46
- user_working_dir = Path(os.environ["CLAUDE_MPM_USER_PWD"])
309
+ except Exception as e:
310
+ self.logger.error(f"Error cleaning agents: {e}", exc_info=True)
311
+ return CommandResult.error_result(f"Error cleaning agents: {e}")
47
312
 
48
- # For system agents, don't pass working_directory so they deploy to ~/.claude/agents/
49
- # The service will determine the correct path based on the agent source
50
- deployment_service = AgentDeploymentService()
313
+ def _view_agent(self, args) -> CommandResult:
314
+ """View details of a specific agent."""
315
+ try:
316
+ agent_name = getattr(args, 'agent_name', None)
317
+ if not agent_name:
318
+ return CommandResult.error_result("Agent name is required for view command")
51
319
 
52
- if not args.agents_command:
53
- agent_versions = get_agent_versions_display()
54
- if agent_versions:
55
- print(agent_versions)
320
+ # Get agent details from deployment service
321
+ agent_details = self.deployment_service.get_agent_details(agent_name)
322
+
323
+ output_format = getattr(args, 'format', 'text')
324
+ if output_format in ['json', 'yaml']:
325
+ return CommandResult.success_result(
326
+ f"Agent details for {agent_name}",
327
+ data=agent_details
328
+ )
56
329
  else:
57
- print("No deployed agents found")
58
- print("\nTo deploy agents, run: claude-mpm --mpm:agents deploy")
59
- return
330
+ # Text output
331
+ print(f"Agent: {agent_name}")
332
+ print("-" * 40)
333
+ for key, value in agent_details.items():
334
+ print(f"{key}: {value}")
335
+
336
+ return CommandResult.success_result(f"Displayed details for {agent_name}")
337
+
338
+ except Exception as e:
339
+ self.logger.error(f"Error viewing agent: {e}", exc_info=True)
340
+ return CommandResult.error_result(f"Error viewing agent: {e}")
341
+
342
+ def _fix_agents(self, args) -> CommandResult:
343
+ """Fix agent deployment issues."""
344
+ try:
345
+ result = self.deployment_service.fix_deployment()
346
+
347
+ output_format = getattr(args, 'format', 'text')
348
+ if output_format in ['json', 'yaml']:
349
+ return CommandResult.success_result(
350
+ "Agent deployment fixed",
351
+ data=result
352
+ )
353
+ else:
354
+ # Text output
355
+ print("✓ Agent deployment issues fixed")
356
+ if result.get('fixes_applied'):
357
+ for fix in result['fixes_applied']:
358
+ print(f" - {fix}")
359
+
360
+ return CommandResult.success_result("Agent deployment fixed")
361
+
362
+ except Exception as e:
363
+ self.logger.error(f"Error fixing agents: {e}", exc_info=True)
364
+ return CommandResult.error_result(f"Error fixing agents: {e}")
365
+
366
+ def _check_agent_dependencies(self, args) -> CommandResult:
367
+ """Check agent dependencies."""
368
+ try:
369
+ result = self.deployment_service.check_dependencies()
370
+
371
+ output_format = getattr(args, 'format', 'text')
372
+ if output_format in ['json', 'yaml']:
373
+ return CommandResult.success_result(
374
+ "Dependency check completed",
375
+ data=result
376
+ )
377
+ else:
378
+ # Text output
379
+ print("Agent Dependencies Check:")
380
+ print("-" * 40)
381
+ if result.get('missing_dependencies'):
382
+ print("Missing dependencies:")
383
+ for dep in result['missing_dependencies']:
384
+ print(f" - {dep}")
385
+ else:
386
+ print("✓ All dependencies satisfied")
60
387
 
61
- if args.agents_command == AgentCommands.LIST.value:
62
- _list_agents(args, deployment_service)
388
+ return CommandResult.success_result("Dependency check completed")
63
389
 
64
- elif args.agents_command == AgentCommands.DEPLOY.value:
65
- _deploy_agents(args, deployment_service, force=False)
390
+ except Exception as e:
391
+ self.logger.error(f"Error checking dependencies: {e}", exc_info=True)
392
+ return CommandResult.error_result(f"Error checking dependencies: {e}")
66
393
 
67
- elif args.agents_command == AgentCommands.FORCE_DEPLOY.value:
68
- _deploy_agents(args, deployment_service, force=True)
394
+ def _install_agent_dependencies(self, args) -> CommandResult:
395
+ """Install agent dependencies."""
396
+ try:
397
+ result = self.deployment_service.install_dependencies()
69
398
 
70
- elif args.agents_command == AgentCommands.CLEAN.value:
71
- _clean_agents(args, deployment_service)
399
+ output_format = getattr(args, 'format', 'text')
400
+ if output_format in ['json', 'yaml']:
401
+ return CommandResult.success_result(
402
+ f"Installed {result.get('installed_count', 0)} dependencies",
403
+ data=result
404
+ )
405
+ else:
406
+ # Text output
407
+ installed_count = result.get('installed_count', 0)
408
+ if installed_count > 0:
409
+ print(f"✓ Installed {installed_count} dependencies")
410
+ else:
411
+ print("No dependencies needed installation")
72
412
 
73
- elif args.agents_command == AgentCommands.VIEW.value:
74
- _view_agent(args)
413
+ return CommandResult.success_result(f"Installed {installed_count} dependencies")
75
414
 
76
- elif args.agents_command == AgentCommands.FIX.value:
77
- _fix_agents(args)
415
+ except Exception as e:
416
+ self.logger.error(f"Error installing dependencies: {e}", exc_info=True)
417
+ return CommandResult.error_result(f"Error installing dependencies: {e}")
78
418
 
79
- elif args.agents_command == "deps-check":
80
- _check_agent_dependencies(args)
419
+ def _list_agent_dependencies(self, args) -> CommandResult:
420
+ """List agent dependencies."""
421
+ try:
422
+ result = self.deployment_service.list_dependencies()
81
423
 
82
- elif args.agents_command == "deps-install":
83
- _install_agent_dependencies(args)
424
+ output_format = getattr(args, 'format', 'text')
425
+ if output_format in ['json', 'yaml']:
426
+ return CommandResult.success_result(
427
+ f"Found {len(result.get('dependencies', []))} dependencies",
428
+ data=result
429
+ )
430
+ else:
431
+ # Text output
432
+ dependencies = result.get('dependencies', [])
433
+ print("Agent Dependencies:")
434
+ print("-" * 40)
435
+ if dependencies:
436
+ for dep in dependencies:
437
+ status = "✓" if dep.get('installed') else "✗"
438
+ print(f"{status} {dep.get('name', 'Unknown')}")
439
+ else:
440
+ print("No dependencies found")
84
441
 
85
- elif args.agents_command == "deps-list":
86
- _list_agent_dependencies(args)
442
+ return CommandResult.success_result(f"Listed {len(dependencies)} dependencies")
87
443
 
88
- elif args.agents_command == "deps-fix":
89
- _fix_agent_dependencies(args)
444
+ except Exception as e:
445
+ self.logger.error(f"Error listing dependencies: {e}", exc_info=True)
446
+ return CommandResult.error_result(f"Error listing dependencies: {e}")
90
447
 
91
- except ImportError:
92
- logger.error("Agent deployment service not available")
93
- print("Error: Agent deployment service not available")
94
- except Exception as e:
95
- logger.error(f"Error managing agents: {e}")
96
- print(f"Error: {e}")
448
+ def _fix_agent_dependencies(self, args) -> CommandResult:
449
+ """Fix agent dependency issues."""
450
+ try:
451
+ result = self.deployment_service.fix_dependencies()
97
452
 
453
+ output_format = getattr(args, 'format', 'text')
454
+ if output_format in ['json', 'yaml']:
455
+ return CommandResult.success_result(
456
+ "Dependency issues fixed",
457
+ data=result
458
+ )
459
+ else:
460
+ # Text output
461
+ print("✓ Agent dependency issues fixed")
462
+ if result.get('fixes_applied'):
463
+ for fix in result['fixes_applied']:
464
+ print(f" - {fix}")
98
465
 
99
- def _list_agents(args, deployment_service):
100
- """
101
- List available or deployed agents.
466
+ return CommandResult.success_result("Dependency issues fixed")
102
467
 
103
- WHY: Users need to see what agents are available in the system and what's
104
- currently deployed. This helps them understand the agent ecosystem.
468
+ except Exception as e:
469
+ self.logger.error(f"Error fixing dependencies: {e}", exc_info=True)
470
+ return CommandResult.error_result(f"Error fixing dependencies: {e}")
105
471
 
106
- Args:
107
- args: Command arguments with 'system', 'deployed', and 'by_tier' flags
108
- deployment_service: Agent deployment service instance
472
+
473
+ def manage_agents(args):
109
474
  """
110
- if hasattr(args, "by_tier") and args.by_tier:
111
- # List agents grouped by tier
112
- _list_agents_by_tier()
113
- elif args.system:
114
- # List available agent templates
115
- print("Available Agent Templates:")
116
- print("-" * 80)
117
- agents = deployment_service.list_available_agents()
118
- if not agents:
119
- print("No agent templates found")
120
- else:
121
- for agent in agents:
122
- print(f"📄 {agent['file']}")
123
- if "name" in agent:
124
- print(f" Name: {agent['name']}")
125
- if "description" in agent:
126
- print(f" Description: {agent['description']}")
127
- if "version" in agent:
128
- print(f" Version: {agent['version']}")
129
- print()
130
-
131
- elif args.deployed:
132
- # List deployed agents
133
- print("Deployed Agents:")
134
- print("-" * 80)
135
- verification = deployment_service.verify_deployment()
136
- if not verification["agents_found"]:
137
- print("No deployed agents found")
138
- else:
139
- for agent in verification["agents_found"]:
140
- print(f"📄 {agent['file']}")
141
- if "name" in agent:
142
- print(f" Name: {agent['name']}")
143
- print(f" Path: {agent['path']}")
144
- print()
145
-
146
- if verification["warnings"]:
147
- print("\nWarnings:")
148
- for warning in verification["warnings"]:
149
- print(f" ⚠️ {warning}")
475
+ Main entry point for agent management commands.
150
476
 
151
- else:
152
- # Default: show usage
153
- print(
154
- "Use --system to list system agents, --deployed to list deployed agents, or --by-tier to group by precedence"
155
- )
477
+ This function maintains backward compatibility while using the new AgentCommand pattern.
478
+ """
479
+ command = AgentsCommand()
480
+ result = command.execute(args)
481
+
482
+ # Print result if structured output format is requested
483
+ if hasattr(args, 'format') and args.format in ['json', 'yaml']:
484
+ command.print_result(result, args)
485
+
486
+ return result.exit_code
487
+
488
+
489
+ def _list_agents(args, deployment_service):
490
+ """Legacy function for backward compatibility."""
491
+ command = AgentsCommand()
492
+ command._deployment_service = deployment_service
493
+ result = command._list_agents(args)
494
+ return result.exit_code
156
495
 
157
496
 
158
497
  def _deploy_agents(args, deployment_service, force=False):
@@ -167,8 +506,9 @@ def _deploy_agents(args, deployment_service, force=False):
167
506
  deployment_service: Agent deployment service instance
168
507
  force: Whether to force rebuild all agents
169
508
  """
170
- # Load configuration to get exclusion settings
171
- config = Config()
509
+ # Load configuration to get exclusion settings using ConfigLoader
510
+ config_loader = ConfigLoader()
511
+ config = config_loader.load_main_config()
172
512
 
173
513
  # Check if user wants to override exclusions
174
514
  if hasattr(args, "include_all") and args.include_all: