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.
- claude_mpm/BUILD_NUMBER +1 -1
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +4 -1
- claude_mpm/agents/BASE_PM.md +3 -0
- claude_mpm/agents/templates/code_analyzer.json +2 -2
- claude_mpm/cli/commands/agents.py +453 -113
- claude_mpm/cli/commands/aggregate.py +107 -15
- claude_mpm/cli/commands/cleanup.py +142 -10
- claude_mpm/cli/commands/config.py +358 -224
- claude_mpm/cli/commands/info.py +184 -75
- claude_mpm/cli/commands/mcp_command_router.py +5 -76
- claude_mpm/cli/commands/mcp_install_commands.py +68 -36
- claude_mpm/cli/commands/mcp_server_commands.py +30 -37
- claude_mpm/cli/commands/memory.py +331 -61
- claude_mpm/cli/commands/monitor.py +101 -7
- claude_mpm/cli/commands/run.py +368 -8
- claude_mpm/cli/commands/tickets.py +206 -24
- claude_mpm/cli/parsers/mcp_parser.py +3 -0
- claude_mpm/cli/shared/__init__.py +40 -0
- claude_mpm/cli/shared/argument_patterns.py +212 -0
- claude_mpm/cli/shared/command_base.py +234 -0
- claude_mpm/cli/shared/error_handling.py +238 -0
- claude_mpm/cli/shared/output_formatters.py +231 -0
- claude_mpm/config/agent_config.py +29 -8
- claude_mpm/core/container.py +6 -4
- claude_mpm/core/service_registry.py +4 -2
- claude_mpm/core/shared/__init__.py +17 -0
- claude_mpm/core/shared/config_loader.py +320 -0
- claude_mpm/core/shared/path_resolver.py +277 -0
- claude_mpm/core/shared/singleton_manager.py +208 -0
- claude_mpm/hooks/claude_hooks/memory_integration.py +4 -2
- claude_mpm/hooks/claude_hooks/response_tracking.py +14 -3
- claude_mpm/hooks/memory_integration_hook.py +11 -2
- claude_mpm/services/agents/deployment/agent_deployment.py +49 -23
- claude_mpm/services/agents/deployment/deployment_wrapper.py +71 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +1 -0
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +43 -0
- claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +4 -0
- claude_mpm/services/agents/deployment/processors/agent_processor.py +1 -1
- claude_mpm/services/agents/loading/base_agent_manager.py +11 -3
- claude_mpm/services/agents/registry/deployed_agent_discovery.py +14 -5
- claude_mpm/services/event_aggregator.py +4 -2
- claude_mpm/services/mcp_gateway/config/config_loader.py +89 -28
- claude_mpm/services/mcp_gateway/config/configuration.py +29 -0
- claude_mpm/services/mcp_gateway/registry/service_registry.py +22 -5
- claude_mpm/services/memory/builder.py +6 -1
- claude_mpm/services/response_tracker.py +3 -1
- claude_mpm/services/runner_configuration_service.py +15 -6
- claude_mpm/services/shared/__init__.py +20 -0
- claude_mpm/services/shared/async_service_base.py +219 -0
- claude_mpm/services/shared/config_service_base.py +292 -0
- claude_mpm/services/shared/lifecycle_service_base.py +317 -0
- claude_mpm/services/shared/manager_base.py +303 -0
- claude_mpm/services/shared/service_factory.py +308 -0
- {claude_mpm-4.0.23.dist-info → claude_mpm-4.0.28.dist-info}/METADATA +19 -13
- {claude_mpm-4.0.23.dist-info → claude_mpm-4.0.28.dist-info}/RECORD +60 -44
- {claude_mpm-4.0.23.dist-info → claude_mpm-4.0.28.dist-info}/WHEEL +0 -0
- {claude_mpm-4.0.23.dist-info → claude_mpm-4.0.28.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.0.23.dist-info → claude_mpm-4.0.28.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.0.23.dist-info → claude_mpm-4.0.28.dist-info}/top_level.txt +0 -0
|
@@ -5,9 +5,12 @@ WHY: This module provides comprehensive ticket management functionality, allowin
|
|
|
5
5
|
to create, view, update, and manage tickets through the CLI. It integrates with
|
|
6
6
|
ai-trackdown-pytools for persistent ticket storage.
|
|
7
7
|
|
|
8
|
-
DESIGN
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
DESIGN DECISIONS:
|
|
9
|
+
- Use BaseCommand for consistent CLI patterns
|
|
10
|
+
- Leverage shared utilities for argument parsing and output formatting
|
|
11
|
+
- Maintain backward compatibility with existing ai-trackdown integration
|
|
12
|
+
- Support multiple output formats (json, yaml, table, text)
|
|
13
|
+
- Implement full CRUD operations plus search and workflow management
|
|
11
14
|
"""
|
|
12
15
|
|
|
13
16
|
import json
|
|
@@ -17,14 +20,193 @@ from typing import Any, Dict, List, Optional
|
|
|
17
20
|
|
|
18
21
|
from ...constants import TicketCommands
|
|
19
22
|
from ...core.logger import get_logger
|
|
23
|
+
from ..shared import BaseCommand, CommandResult
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class TicketsCommand(BaseCommand):
|
|
27
|
+
"""Tickets command using shared utilities."""
|
|
28
|
+
|
|
29
|
+
def __init__(self):
|
|
30
|
+
super().__init__("tickets")
|
|
31
|
+
|
|
32
|
+
def validate_args(self, args) -> Optional[str]:
|
|
33
|
+
"""Validate command arguments."""
|
|
34
|
+
if not hasattr(args, 'tickets_command') or not args.tickets_command:
|
|
35
|
+
return "No tickets subcommand specified"
|
|
36
|
+
|
|
37
|
+
valid_commands = [cmd.value for cmd in TicketCommands]
|
|
38
|
+
if args.tickets_command not in valid_commands:
|
|
39
|
+
return f"Unknown tickets command: {args.tickets_command}. Valid commands: {', '.join(valid_commands)}"
|
|
40
|
+
|
|
41
|
+
return None
|
|
42
|
+
|
|
43
|
+
def run(self, args) -> CommandResult:
|
|
44
|
+
"""Execute the tickets command."""
|
|
45
|
+
try:
|
|
46
|
+
# Route to specific subcommand handlers
|
|
47
|
+
command_map = {
|
|
48
|
+
TicketCommands.CREATE.value: self._create_ticket,
|
|
49
|
+
TicketCommands.LIST.value: self._list_tickets,
|
|
50
|
+
TicketCommands.VIEW.value: self._view_ticket,
|
|
51
|
+
TicketCommands.UPDATE.value: self._update_ticket,
|
|
52
|
+
TicketCommands.CLOSE.value: self._close_ticket,
|
|
53
|
+
TicketCommands.DELETE.value: self._delete_ticket,
|
|
54
|
+
TicketCommands.SEARCH.value: self._search_tickets,
|
|
55
|
+
TicketCommands.COMMENT.value: self._add_comment,
|
|
56
|
+
TicketCommands.WORKFLOW.value: self._update_workflow,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if args.tickets_command in command_map:
|
|
60
|
+
return command_map[args.tickets_command](args)
|
|
61
|
+
else:
|
|
62
|
+
return CommandResult.error_result(f"Unknown tickets command: {args.tickets_command}")
|
|
63
|
+
|
|
64
|
+
except Exception as e:
|
|
65
|
+
self.logger.error(f"Error executing tickets command: {e}", exc_info=True)
|
|
66
|
+
return CommandResult.error_result(f"Error executing tickets command: {e}")
|
|
67
|
+
|
|
68
|
+
def _create_ticket(self, args) -> CommandResult:
|
|
69
|
+
"""Create a new ticket."""
|
|
70
|
+
try:
|
|
71
|
+
exit_code = create_ticket_legacy(args)
|
|
72
|
+
if exit_code == 0:
|
|
73
|
+
return CommandResult.success_result("Ticket created successfully")
|
|
74
|
+
else:
|
|
75
|
+
return CommandResult.error_result("Failed to create ticket", exit_code=exit_code)
|
|
76
|
+
except Exception as e:
|
|
77
|
+
self.logger.error(f"Error creating ticket: {e}")
|
|
78
|
+
return CommandResult.error_result(f"Error creating ticket: {e}")
|
|
79
|
+
|
|
80
|
+
def _list_tickets(self, args) -> CommandResult:
|
|
81
|
+
"""List tickets."""
|
|
82
|
+
try:
|
|
83
|
+
exit_code = list_tickets_legacy(args)
|
|
84
|
+
if exit_code == 0:
|
|
85
|
+
return CommandResult.success_result("Tickets listed successfully")
|
|
86
|
+
else:
|
|
87
|
+
return CommandResult.error_result("Failed to list tickets", exit_code=exit_code)
|
|
88
|
+
except Exception as e:
|
|
89
|
+
self.logger.error(f"Error listing tickets: {e}")
|
|
90
|
+
return CommandResult.error_result(f"Error listing tickets: {e}")
|
|
91
|
+
|
|
92
|
+
def _view_ticket(self, args) -> CommandResult:
|
|
93
|
+
"""View a specific ticket."""
|
|
94
|
+
try:
|
|
95
|
+
exit_code = view_ticket_legacy(args)
|
|
96
|
+
if exit_code == 0:
|
|
97
|
+
return CommandResult.success_result("Ticket viewed successfully")
|
|
98
|
+
else:
|
|
99
|
+
return CommandResult.error_result("Failed to view ticket", exit_code=exit_code)
|
|
100
|
+
except Exception as e:
|
|
101
|
+
self.logger.error(f"Error viewing ticket: {e}")
|
|
102
|
+
return CommandResult.error_result(f"Error viewing ticket: {e}")
|
|
103
|
+
|
|
104
|
+
def _update_ticket(self, args) -> CommandResult:
|
|
105
|
+
"""Update a ticket."""
|
|
106
|
+
try:
|
|
107
|
+
exit_code = update_ticket_legacy(args)
|
|
108
|
+
if exit_code == 0:
|
|
109
|
+
return CommandResult.success_result("Ticket updated successfully")
|
|
110
|
+
else:
|
|
111
|
+
return CommandResult.error_result("Failed to update ticket", exit_code=exit_code)
|
|
112
|
+
except Exception as e:
|
|
113
|
+
self.logger.error(f"Error updating ticket: {e}")
|
|
114
|
+
return CommandResult.error_result(f"Error updating ticket: {e}")
|
|
115
|
+
|
|
116
|
+
def _close_ticket(self, args) -> CommandResult:
|
|
117
|
+
"""Close a ticket."""
|
|
118
|
+
try:
|
|
119
|
+
exit_code = close_ticket_legacy(args)
|
|
120
|
+
if exit_code == 0:
|
|
121
|
+
return CommandResult.success_result("Ticket closed successfully")
|
|
122
|
+
else:
|
|
123
|
+
return CommandResult.error_result("Failed to close ticket", exit_code=exit_code)
|
|
124
|
+
except Exception as e:
|
|
125
|
+
self.logger.error(f"Error closing ticket: {e}")
|
|
126
|
+
return CommandResult.error_result(f"Error closing ticket: {e}")
|
|
127
|
+
|
|
128
|
+
def _delete_ticket(self, args) -> CommandResult:
|
|
129
|
+
"""Delete a ticket."""
|
|
130
|
+
try:
|
|
131
|
+
exit_code = delete_ticket_legacy(args)
|
|
132
|
+
if exit_code == 0:
|
|
133
|
+
return CommandResult.success_result("Ticket deleted successfully")
|
|
134
|
+
else:
|
|
135
|
+
return CommandResult.error_result("Failed to delete ticket", exit_code=exit_code)
|
|
136
|
+
except Exception as e:
|
|
137
|
+
self.logger.error(f"Error deleting ticket: {e}")
|
|
138
|
+
return CommandResult.error_result(f"Error deleting ticket: {e}")
|
|
139
|
+
|
|
140
|
+
def _search_tickets(self, args) -> CommandResult:
|
|
141
|
+
"""Search tickets."""
|
|
142
|
+
try:
|
|
143
|
+
exit_code = search_tickets_legacy(args)
|
|
144
|
+
if exit_code == 0:
|
|
145
|
+
return CommandResult.success_result("Tickets searched successfully")
|
|
146
|
+
else:
|
|
147
|
+
return CommandResult.error_result("Failed to search tickets", exit_code=exit_code)
|
|
148
|
+
except Exception as e:
|
|
149
|
+
self.logger.error(f"Error searching tickets: {e}")
|
|
150
|
+
return CommandResult.error_result(f"Error searching tickets: {e}")
|
|
151
|
+
|
|
152
|
+
def _add_comment(self, args) -> CommandResult:
|
|
153
|
+
"""Add a comment to a ticket."""
|
|
154
|
+
try:
|
|
155
|
+
exit_code = add_comment_legacy(args)
|
|
156
|
+
if exit_code == 0:
|
|
157
|
+
return CommandResult.success_result("Comment added successfully")
|
|
158
|
+
else:
|
|
159
|
+
return CommandResult.error_result("Failed to add comment", exit_code=exit_code)
|
|
160
|
+
except Exception as e:
|
|
161
|
+
self.logger.error(f"Error adding comment: {e}")
|
|
162
|
+
return CommandResult.error_result(f"Error adding comment: {e}")
|
|
163
|
+
|
|
164
|
+
def _update_workflow(self, args) -> CommandResult:
|
|
165
|
+
"""Update workflow state."""
|
|
166
|
+
try:
|
|
167
|
+
exit_code = update_workflow_legacy(args)
|
|
168
|
+
if exit_code == 0:
|
|
169
|
+
return CommandResult.success_result("Workflow updated successfully")
|
|
170
|
+
else:
|
|
171
|
+
return CommandResult.error_result("Failed to update workflow", exit_code=exit_code)
|
|
172
|
+
except Exception as e:
|
|
173
|
+
self.logger.error(f"Error updating workflow: {e}")
|
|
174
|
+
return CommandResult.error_result(f"Error updating workflow: {e}")
|
|
20
175
|
|
|
21
176
|
|
|
22
177
|
def manage_tickets(args):
|
|
23
178
|
"""
|
|
24
|
-
Main
|
|
179
|
+
Main entry point for tickets command.
|
|
180
|
+
|
|
181
|
+
This function maintains backward compatibility while using the new BaseCommand pattern.
|
|
182
|
+
"""
|
|
183
|
+
command = TicketsCommand()
|
|
184
|
+
result = command.execute(args)
|
|
25
185
|
|
|
26
|
-
|
|
27
|
-
|
|
186
|
+
# Print result if structured output format is requested
|
|
187
|
+
if hasattr(args, 'format') and args.format in ['json', 'yaml']:
|
|
188
|
+
command.print_result(result, args)
|
|
189
|
+
|
|
190
|
+
return result.exit_code
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def list_tickets(args):
|
|
194
|
+
"""
|
|
195
|
+
Compatibility function for list_tickets.
|
|
196
|
+
|
|
197
|
+
This maintains backward compatibility for imports while using the new TicketsCommand pattern.
|
|
198
|
+
"""
|
|
199
|
+
# Create a tickets command and execute the list subcommand
|
|
200
|
+
args.tickets_command = TicketCommands.LIST.value
|
|
201
|
+
return manage_tickets(args)
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def manage_tickets_legacy(args):
|
|
205
|
+
"""
|
|
206
|
+
Legacy ticket command dispatcher.
|
|
207
|
+
|
|
208
|
+
WHY: This contains the original manage_tickets logic, preserved during migration
|
|
209
|
+
to BaseCommand pattern. Will be gradually refactored into the TicketsCommand class.
|
|
28
210
|
|
|
29
211
|
DESIGN DECISION: We use a subcommand pattern similar to git, allowing for
|
|
30
212
|
intuitive command structure like 'claude-mpm tickets create "title"'.
|
|
@@ -49,15 +231,15 @@ def manage_tickets(args):
|
|
|
49
231
|
|
|
50
232
|
# Map subcommands to handler functions
|
|
51
233
|
handlers = {
|
|
52
|
-
TicketCommands.CREATE.value:
|
|
53
|
-
TicketCommands.LIST.value:
|
|
54
|
-
TicketCommands.VIEW.value:
|
|
55
|
-
TicketCommands.UPDATE.value:
|
|
56
|
-
TicketCommands.CLOSE.value:
|
|
57
|
-
TicketCommands.DELETE.value:
|
|
58
|
-
TicketCommands.SEARCH.value:
|
|
59
|
-
TicketCommands.COMMENT.value:
|
|
60
|
-
TicketCommands.WORKFLOW.value:
|
|
234
|
+
TicketCommands.CREATE.value: create_ticket_legacy,
|
|
235
|
+
TicketCommands.LIST.value: list_tickets_legacy,
|
|
236
|
+
TicketCommands.VIEW.value: view_ticket_legacy,
|
|
237
|
+
TicketCommands.UPDATE.value: update_ticket_legacy,
|
|
238
|
+
TicketCommands.CLOSE.value: close_ticket_legacy,
|
|
239
|
+
TicketCommands.DELETE.value: delete_ticket_legacy,
|
|
240
|
+
TicketCommands.SEARCH.value: search_tickets_legacy,
|
|
241
|
+
TicketCommands.COMMENT.value: add_comment_legacy,
|
|
242
|
+
TicketCommands.WORKFLOW.value: update_workflow_legacy,
|
|
61
243
|
}
|
|
62
244
|
|
|
63
245
|
# Execute the appropriate handler
|
|
@@ -80,7 +262,7 @@ def manage_tickets(args):
|
|
|
80
262
|
return 1
|
|
81
263
|
|
|
82
264
|
|
|
83
|
-
def
|
|
265
|
+
def create_ticket_legacy(args):
|
|
84
266
|
"""
|
|
85
267
|
Create a new ticket.
|
|
86
268
|
|
|
@@ -140,7 +322,7 @@ def create_ticket(args):
|
|
|
140
322
|
return 1
|
|
141
323
|
|
|
142
324
|
|
|
143
|
-
def
|
|
325
|
+
def list_tickets_legacy(args):
|
|
144
326
|
"""
|
|
145
327
|
List recent tickets with optional filtering.
|
|
146
328
|
|
|
@@ -306,7 +488,7 @@ def list_tickets(args):
|
|
|
306
488
|
return 1
|
|
307
489
|
|
|
308
490
|
|
|
309
|
-
def
|
|
491
|
+
def view_ticket_legacy(args):
|
|
310
492
|
"""
|
|
311
493
|
View a specific ticket in detail.
|
|
312
494
|
|
|
@@ -379,7 +561,7 @@ def view_ticket(args):
|
|
|
379
561
|
return 0
|
|
380
562
|
|
|
381
563
|
|
|
382
|
-
def
|
|
564
|
+
def update_ticket_legacy(args):
|
|
383
565
|
"""
|
|
384
566
|
Update a ticket's properties.
|
|
385
567
|
|
|
@@ -470,7 +652,7 @@ def update_ticket(args):
|
|
|
470
652
|
return 1
|
|
471
653
|
|
|
472
654
|
|
|
473
|
-
def
|
|
655
|
+
def close_ticket_legacy(args):
|
|
474
656
|
"""
|
|
475
657
|
Close a ticket.
|
|
476
658
|
|
|
@@ -521,7 +703,7 @@ def close_ticket(args):
|
|
|
521
703
|
return 1
|
|
522
704
|
|
|
523
705
|
|
|
524
|
-
def
|
|
706
|
+
def delete_ticket_legacy(args):
|
|
525
707
|
"""
|
|
526
708
|
Delete a ticket.
|
|
527
709
|
|
|
@@ -592,7 +774,7 @@ def delete_ticket(args):
|
|
|
592
774
|
return 1
|
|
593
775
|
|
|
594
776
|
|
|
595
|
-
def
|
|
777
|
+
def search_tickets_legacy(args):
|
|
596
778
|
"""
|
|
597
779
|
Search tickets by query string.
|
|
598
780
|
|
|
@@ -680,7 +862,7 @@ def search_tickets(args):
|
|
|
680
862
|
return 0
|
|
681
863
|
|
|
682
864
|
|
|
683
|
-
def
|
|
865
|
+
def add_comment_legacy(args):
|
|
684
866
|
"""
|
|
685
867
|
Add a comment to a ticket.
|
|
686
868
|
|
|
@@ -719,7 +901,7 @@ def add_comment(args):
|
|
|
719
901
|
return 1
|
|
720
902
|
|
|
721
903
|
|
|
722
|
-
def
|
|
904
|
+
def update_workflow_legacy(args):
|
|
723
905
|
"""
|
|
724
906
|
Update ticket workflow state.
|
|
725
907
|
|
|
@@ -171,5 +171,8 @@ def add_mcp_subparser(subparsers) -> argparse.ArgumentParser:
|
|
|
171
171
|
server_mcp_parser.add_argument(
|
|
172
172
|
"--test", action="store_true", help="Run in test mode with debug output"
|
|
173
173
|
)
|
|
174
|
+
server_mcp_parser.add_argument(
|
|
175
|
+
"--instructions", action="store_true", help="Show setup instructions for Claude Desktop"
|
|
176
|
+
)
|
|
174
177
|
|
|
175
178
|
return mcp_parser
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Shared CLI utilities for claude-mpm.
|
|
3
|
+
|
|
4
|
+
This module provides common utilities to reduce code duplication across CLI commands.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .argument_patterns import (
|
|
8
|
+
CommonArguments,
|
|
9
|
+
add_agent_arguments,
|
|
10
|
+
add_common_arguments,
|
|
11
|
+
add_config_arguments,
|
|
12
|
+
add_logging_arguments,
|
|
13
|
+
add_memory_arguments,
|
|
14
|
+
add_output_arguments,
|
|
15
|
+
)
|
|
16
|
+
from .command_base import AgentCommand, BaseCommand, CommandResult, MemoryCommand
|
|
17
|
+
from .error_handling import CLIErrorHandler, handle_cli_errors
|
|
18
|
+
from .output_formatters import OutputFormatter, format_output
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
# Argument patterns
|
|
22
|
+
"CommonArguments",
|
|
23
|
+
"add_agent_arguments",
|
|
24
|
+
"add_common_arguments",
|
|
25
|
+
"add_config_arguments",
|
|
26
|
+
"add_logging_arguments",
|
|
27
|
+
"add_memory_arguments",
|
|
28
|
+
"add_output_arguments",
|
|
29
|
+
# Command base
|
|
30
|
+
"AgentCommand",
|
|
31
|
+
"BaseCommand",
|
|
32
|
+
"CommandResult",
|
|
33
|
+
"MemoryCommand",
|
|
34
|
+
# Error handling
|
|
35
|
+
"CLIErrorHandler",
|
|
36
|
+
"handle_cli_errors",
|
|
37
|
+
# Output formatting
|
|
38
|
+
"OutputFormatter",
|
|
39
|
+
"format_output",
|
|
40
|
+
]
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Common CLI argument patterns to reduce duplication.
|
|
3
|
+
|
|
4
|
+
This module provides reusable argument definitions that are commonly used
|
|
5
|
+
across multiple CLI commands.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import argparse
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Any, Dict, List, Optional
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class CommonArguments:
|
|
14
|
+
"""Registry of common argument patterns used across CLI commands."""
|
|
15
|
+
|
|
16
|
+
# Logging arguments
|
|
17
|
+
VERBOSE = {
|
|
18
|
+
"flags": ["-v", "--verbose"],
|
|
19
|
+
"action": "store_true",
|
|
20
|
+
"help": "Enable verbose output"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
QUIET = {
|
|
24
|
+
"flags": ["-q", "--quiet"],
|
|
25
|
+
"action": "store_true",
|
|
26
|
+
"help": "Suppress non-error output"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
DEBUG = {
|
|
30
|
+
"flags": ["--debug"],
|
|
31
|
+
"action": "store_true",
|
|
32
|
+
"help": "Enable debug logging"
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
# Configuration arguments
|
|
36
|
+
CONFIG_FILE = {
|
|
37
|
+
"flags": ["-c", "--config"],
|
|
38
|
+
"type": Path,
|
|
39
|
+
"help": "Path to configuration file"
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
CONFIG_DIR = {
|
|
43
|
+
"flags": ["--config-dir"],
|
|
44
|
+
"type": Path,
|
|
45
|
+
"help": "Configuration directory path"
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
# Output arguments
|
|
49
|
+
OUTPUT_FORMAT = {
|
|
50
|
+
"flags": ["-f", "--format"],
|
|
51
|
+
"choices": ["json", "yaml", "table", "text"],
|
|
52
|
+
"default": "text",
|
|
53
|
+
"help": "Output format"
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
OUTPUT_FILE = {
|
|
57
|
+
"flags": ["-o", "--output"],
|
|
58
|
+
"type": Path,
|
|
59
|
+
"help": "Output file path"
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
# Common flags
|
|
63
|
+
FORCE = {
|
|
64
|
+
"flags": ["--force"],
|
|
65
|
+
"action": "store_true",
|
|
66
|
+
"help": "Force operation without confirmation"
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
DRY_RUN = {
|
|
70
|
+
"flags": ["--dry-run"],
|
|
71
|
+
"action": "store_true",
|
|
72
|
+
"help": "Show what would be done without executing"
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
# Agent-related arguments
|
|
76
|
+
AGENT_NAME = {
|
|
77
|
+
"flags": ["--agent"],
|
|
78
|
+
"help": "Agent name or pattern"
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
AGENT_DIR = {
|
|
82
|
+
"flags": ["--agent-dir"],
|
|
83
|
+
"type": Path,
|
|
84
|
+
"help": "Agent directory path"
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
# Memory-related arguments
|
|
88
|
+
MEMORY_DIR = {
|
|
89
|
+
"flags": ["--memory-dir"],
|
|
90
|
+
"type": Path,
|
|
91
|
+
"help": "Memory directory path"
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def add_argument_from_pattern(parser: argparse.ArgumentParser, pattern: Dict[str, Any]) -> None:
|
|
96
|
+
"""Add an argument to parser from a pattern definition."""
|
|
97
|
+
flags = pattern.pop("flags")
|
|
98
|
+
parser.add_argument(*flags, **pattern)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def add_common_arguments(parser: argparse.ArgumentParser,
|
|
102
|
+
include: Optional[List[str]] = None,
|
|
103
|
+
exclude: Optional[List[str]] = None) -> None:
|
|
104
|
+
"""
|
|
105
|
+
Add common arguments to a parser.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
parser: ArgumentParser to add arguments to
|
|
109
|
+
include: List of argument names to include (if None, includes all)
|
|
110
|
+
exclude: List of argument names to exclude
|
|
111
|
+
"""
|
|
112
|
+
# Default common arguments
|
|
113
|
+
common_args = ["verbose", "quiet", "debug", "config_file", "output_format"]
|
|
114
|
+
|
|
115
|
+
if include is not None:
|
|
116
|
+
common_args = [arg for arg in common_args if arg in include]
|
|
117
|
+
|
|
118
|
+
if exclude is not None:
|
|
119
|
+
common_args = [arg for arg in common_args if arg not in exclude]
|
|
120
|
+
|
|
121
|
+
# Map argument names to patterns
|
|
122
|
+
arg_patterns = {
|
|
123
|
+
"verbose": CommonArguments.VERBOSE.copy(),
|
|
124
|
+
"quiet": CommonArguments.QUIET.copy(),
|
|
125
|
+
"debug": CommonArguments.DEBUG.copy(),
|
|
126
|
+
"config_file": CommonArguments.CONFIG_FILE.copy(),
|
|
127
|
+
"output_format": CommonArguments.OUTPUT_FORMAT.copy(),
|
|
128
|
+
"force": CommonArguments.FORCE.copy(),
|
|
129
|
+
"dry_run": CommonArguments.DRY_RUN.copy(),
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
for arg_name in common_args:
|
|
133
|
+
if arg_name in arg_patterns:
|
|
134
|
+
add_argument_from_pattern(parser, arg_patterns[arg_name])
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def add_logging_arguments(parser: argparse.ArgumentParser) -> None:
|
|
138
|
+
"""Add logging-related arguments."""
|
|
139
|
+
group = parser.add_argument_group("logging options")
|
|
140
|
+
|
|
141
|
+
patterns = [
|
|
142
|
+
CommonArguments.VERBOSE.copy(),
|
|
143
|
+
CommonArguments.QUIET.copy(),
|
|
144
|
+
CommonArguments.DEBUG.copy()
|
|
145
|
+
]
|
|
146
|
+
|
|
147
|
+
for pattern in patterns:
|
|
148
|
+
add_argument_from_pattern(group, pattern)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def add_config_arguments(parser: argparse.ArgumentParser) -> None:
|
|
152
|
+
"""Add configuration-related arguments."""
|
|
153
|
+
group = parser.add_argument_group("configuration options")
|
|
154
|
+
|
|
155
|
+
patterns = [
|
|
156
|
+
CommonArguments.CONFIG_FILE.copy(),
|
|
157
|
+
CommonArguments.CONFIG_DIR.copy()
|
|
158
|
+
]
|
|
159
|
+
|
|
160
|
+
for pattern in patterns:
|
|
161
|
+
add_argument_from_pattern(group, pattern)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def add_output_arguments(parser: argparse.ArgumentParser) -> None:
|
|
165
|
+
"""Add output-related arguments."""
|
|
166
|
+
group = parser.add_argument_group("output options")
|
|
167
|
+
|
|
168
|
+
patterns = [
|
|
169
|
+
CommonArguments.OUTPUT_FORMAT.copy(),
|
|
170
|
+
CommonArguments.OUTPUT_FILE.copy()
|
|
171
|
+
]
|
|
172
|
+
|
|
173
|
+
for pattern in patterns:
|
|
174
|
+
add_argument_from_pattern(group, pattern)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def add_agent_arguments(parser: argparse.ArgumentParser) -> None:
|
|
178
|
+
"""Add agent-related arguments."""
|
|
179
|
+
group = parser.add_argument_group("agent options")
|
|
180
|
+
|
|
181
|
+
patterns = [
|
|
182
|
+
CommonArguments.AGENT_NAME.copy(),
|
|
183
|
+
CommonArguments.AGENT_DIR.copy()
|
|
184
|
+
]
|
|
185
|
+
|
|
186
|
+
for pattern in patterns:
|
|
187
|
+
add_argument_from_pattern(group, pattern)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def add_memory_arguments(parser: argparse.ArgumentParser) -> None:
|
|
191
|
+
"""Add memory-related arguments."""
|
|
192
|
+
group = parser.add_argument_group("memory options")
|
|
193
|
+
|
|
194
|
+
patterns = [
|
|
195
|
+
CommonArguments.MEMORY_DIR.copy()
|
|
196
|
+
]
|
|
197
|
+
|
|
198
|
+
for pattern in patterns:
|
|
199
|
+
add_argument_from_pattern(group, pattern)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def add_operation_arguments(parser: argparse.ArgumentParser) -> None:
|
|
203
|
+
"""Add operation control arguments."""
|
|
204
|
+
group = parser.add_argument_group("operation options")
|
|
205
|
+
|
|
206
|
+
patterns = [
|
|
207
|
+
CommonArguments.FORCE.copy(),
|
|
208
|
+
CommonArguments.DRY_RUN.copy()
|
|
209
|
+
]
|
|
210
|
+
|
|
211
|
+
for pattern in patterns:
|
|
212
|
+
add_argument_from_pattern(group, pattern)
|