claude-mpm 5.0.2__py3-none-any.whl → 5.1.9__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/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +2002 -0
- claude_mpm/agents/PM_INSTRUCTIONS.md +1176 -909
- claude_mpm/agents/base_agent_loader.py +10 -35
- claude_mpm/agents/frontmatter_validator.py +68 -0
- claude_mpm/agents/templates/circuit-breakers.md +293 -44
- claude_mpm/cli/__init__.py +0 -1
- claude_mpm/cli/commands/__init__.py +2 -0
- claude_mpm/cli/commands/agent_state_manager.py +64 -11
- claude_mpm/cli/commands/agents.py +446 -25
- claude_mpm/cli/commands/auto_configure.py +535 -233
- claude_mpm/cli/commands/configure.py +545 -89
- claude_mpm/cli/commands/postmortem.py +401 -0
- claude_mpm/cli/commands/run.py +1 -39
- claude_mpm/cli/commands/skills.py +322 -19
- claude_mpm/cli/interactive/agent_wizard.py +302 -195
- claude_mpm/cli/parsers/agents_parser.py +137 -0
- claude_mpm/cli/parsers/auto_configure_parser.py +13 -0
- claude_mpm/cli/parsers/base_parser.py +4 -0
- claude_mpm/cli/parsers/skills_parser.py +7 -0
- claude_mpm/cli/startup.py +73 -32
- claude_mpm/commands/mpm-agents-auto-configure.md +2 -2
- claude_mpm/commands/mpm-agents-list.md +2 -2
- claude_mpm/commands/mpm-config-view.md +2 -2
- claude_mpm/commands/mpm-help.md +3 -0
- claude_mpm/commands/mpm-postmortem.md +123 -0
- claude_mpm/commands/mpm-session-resume.md +2 -2
- claude_mpm/commands/mpm-ticket-organize.md +2 -2
- claude_mpm/commands/mpm-ticket-view.md +2 -2
- claude_mpm/config/agent_presets.py +312 -82
- claude_mpm/config/skill_presets.py +392 -0
- claude_mpm/constants.py +1 -0
- claude_mpm/core/claude_runner.py +2 -25
- claude_mpm/core/framework/loaders/file_loader.py +54 -101
- claude_mpm/core/interactive_session.py +19 -5
- claude_mpm/core/oneshot_session.py +16 -4
- claude_mpm/core/output_style_manager.py +173 -43
- claude_mpm/core/protocols/__init__.py +23 -0
- claude_mpm/core/protocols/runner_protocol.py +103 -0
- claude_mpm/core/protocols/session_protocol.py +131 -0
- claude_mpm/core/shared/singleton_manager.py +11 -4
- claude_mpm/core/system_context.py +38 -0
- claude_mpm/core/unified_agent_registry.py +129 -1
- claude_mpm/core/unified_config.py +22 -0
- claude_mpm/hooks/claude_hooks/memory_integration.py +12 -1
- claude_mpm/models/agent_definition.py +7 -0
- claude_mpm/services/agents/cache_git_manager.py +621 -0
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +110 -3
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +195 -1
- claude_mpm/services/agents/sources/git_source_sync_service.py +37 -5
- claude_mpm/services/analysis/__init__.py +25 -0
- claude_mpm/services/analysis/postmortem_reporter.py +474 -0
- claude_mpm/services/analysis/postmortem_service.py +765 -0
- claude_mpm/services/command_deployment_service.py +108 -5
- claude_mpm/services/core/base.py +7 -2
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +7 -15
- claude_mpm/services/git/git_operations_service.py +8 -8
- claude_mpm/services/mcp_config_manager.py +75 -145
- claude_mpm/services/mcp_gateway/core/process_pool.py +22 -16
- claude_mpm/services/mcp_service_verifier.py +6 -3
- claude_mpm/services/monitor/daemon.py +28 -8
- claude_mpm/services/monitor/daemon_manager.py +96 -19
- claude_mpm/services/project/project_organizer.py +4 -0
- claude_mpm/services/runner_configuration_service.py +16 -3
- claude_mpm/services/session_management_service.py +16 -4
- claude_mpm/utils/agent_filters.py +288 -0
- claude_mpm/utils/gitignore.py +3 -0
- claude_mpm/utils/migration.py +372 -0
- claude_mpm/utils/progress.py +5 -1
- {claude_mpm-5.0.2.dist-info → claude_mpm-5.1.9.dist-info}/METADATA +69 -8
- {claude_mpm-5.0.2.dist-info → claude_mpm-5.1.9.dist-info}/RECORD +76 -62
- /claude_mpm/agents/{OUTPUT_STYLE.md → CLAUDE_MPM_OUTPUT_STYLE.md} +0 -0
- {claude_mpm-5.0.2.dist-info → claude_mpm-5.1.9.dist-info}/WHEEL +0 -0
- {claude_mpm-5.0.2.dist-info → claude_mpm-5.1.9.dist-info}/entry_points.txt +0 -0
- {claude_mpm-5.0.2.dist-info → claude_mpm-5.1.9.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.0.2.dist-info → claude_mpm-5.1.9.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Postmortem command implementation for claude-mpm.
|
|
3
|
+
|
|
4
|
+
WHY: Provide a comprehensive analysis tool to help users identify, categorize,
|
|
5
|
+
and fix errors encountered during their session, with automated improvements
|
|
6
|
+
for framework code and suggestions for user code.
|
|
7
|
+
|
|
8
|
+
DESIGN DECISIONS:
|
|
9
|
+
- Leverages existing FailureTracker for error data
|
|
10
|
+
- Categorizes errors by source (script/skill/agent/user)
|
|
11
|
+
- Provides action-specific handling (auto-fix/update/PR/suggest)
|
|
12
|
+
- Supports dry-run mode for safety
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import sys
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
from claude_mpm.core.logging_utils import get_logger
|
|
19
|
+
from claude_mpm.services.analysis import get_postmortem_service
|
|
20
|
+
from claude_mpm.services.analysis.postmortem_reporter import PostmortemReporter
|
|
21
|
+
|
|
22
|
+
logger = get_logger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def add_postmortem_parser(subparsers):
|
|
26
|
+
"""Add postmortem command parser.
|
|
27
|
+
|
|
28
|
+
WHY: This command helps users analyze session errors and generate
|
|
29
|
+
actionable improvement suggestions based on error source.
|
|
30
|
+
"""
|
|
31
|
+
parser = subparsers.add_parser(
|
|
32
|
+
"postmortem",
|
|
33
|
+
aliases=["pm-analysis"],
|
|
34
|
+
help="Analyze session errors and suggest improvements",
|
|
35
|
+
description="Perform comprehensive analysis of errors encountered during the session",
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
parser.add_argument(
|
|
39
|
+
"--dry-run",
|
|
40
|
+
action="store_true",
|
|
41
|
+
help="Preview analysis without making changes (default for destructive operations)",
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
parser.add_argument(
|
|
45
|
+
"--auto-fix",
|
|
46
|
+
action="store_true",
|
|
47
|
+
help="Automatically apply fixes to scripts and skills",
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
parser.add_argument(
|
|
51
|
+
"--create-prs",
|
|
52
|
+
action="store_true",
|
|
53
|
+
help="Create pull requests for agent improvements",
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
parser.add_argument(
|
|
57
|
+
"--session-id",
|
|
58
|
+
type=str,
|
|
59
|
+
help="Analyze specific session (default: current session)",
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
parser.add_argument(
|
|
63
|
+
"--format",
|
|
64
|
+
choices=["terminal", "json", "markdown"],
|
|
65
|
+
default="terminal",
|
|
66
|
+
help="Output format (default: terminal)",
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
parser.add_argument(
|
|
70
|
+
"--output",
|
|
71
|
+
"-o",
|
|
72
|
+
type=Path,
|
|
73
|
+
help="Save report to file",
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
parser.add_argument(
|
|
77
|
+
"--verbose",
|
|
78
|
+
"-v",
|
|
79
|
+
action="store_true",
|
|
80
|
+
help="Include detailed error traces and analysis",
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
parser.add_argument(
|
|
84
|
+
"--no-color",
|
|
85
|
+
action="store_true",
|
|
86
|
+
help="Disable colored output",
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
parser.set_defaults(func=postmortem_command)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def run_postmortem(args):
|
|
93
|
+
"""Main entry point for postmortem command (used by CLI).
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
args: Parsed command-line arguments
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
Exit code (0 for success, 1 for warnings, 2 for errors)
|
|
100
|
+
"""
|
|
101
|
+
return postmortem_command(args)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def postmortem_command(args):
|
|
105
|
+
"""Execute the postmortem command.
|
|
106
|
+
|
|
107
|
+
WHY: Provides comprehensive error analysis with categorization and
|
|
108
|
+
actionable improvements, helping users understand and fix issues
|
|
109
|
+
encountered during their session.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
args: Parsed command-line arguments
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
Exit code (0 for success, 1 for warnings, 2 for errors)
|
|
116
|
+
"""
|
|
117
|
+
logger.info("Starting postmortem analysis")
|
|
118
|
+
|
|
119
|
+
# Get postmortem service
|
|
120
|
+
service = get_postmortem_service()
|
|
121
|
+
|
|
122
|
+
try:
|
|
123
|
+
# Analyze session
|
|
124
|
+
report = service.analyze_session(session_id=args.session_id)
|
|
125
|
+
|
|
126
|
+
# Handle output file
|
|
127
|
+
output_file = args.output
|
|
128
|
+
if output_file:
|
|
129
|
+
# Ensure file extension matches format
|
|
130
|
+
if args.format == "json" and not str(output_file).endswith(".json"):
|
|
131
|
+
output_file = Path(str(output_file) + ".json")
|
|
132
|
+
elif args.format == "markdown" and not str(output_file).endswith(".md"):
|
|
133
|
+
output_file = Path(str(output_file) + ".md")
|
|
134
|
+
|
|
135
|
+
# Create parent directories
|
|
136
|
+
output_file = output_file.absolute()
|
|
137
|
+
output_file.parent.mkdir(parents=True, exist_ok=True)
|
|
138
|
+
|
|
139
|
+
# Determine output format
|
|
140
|
+
output_format = args.format
|
|
141
|
+
|
|
142
|
+
# Create reporter
|
|
143
|
+
reporter = PostmortemReporter(
|
|
144
|
+
use_color=not args.no_color,
|
|
145
|
+
verbose=args.verbose,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
# Output results
|
|
149
|
+
if output_file:
|
|
150
|
+
# Save to file
|
|
151
|
+
try:
|
|
152
|
+
with output_file.open("w") as f:
|
|
153
|
+
original_output = reporter.output
|
|
154
|
+
reporter.output = f
|
|
155
|
+
reporter.report(report, format=output_format)
|
|
156
|
+
reporter.output = original_output
|
|
157
|
+
|
|
158
|
+
print(f"✅ Report saved to: {output_file}")
|
|
159
|
+
|
|
160
|
+
# Print brief summary to terminal
|
|
161
|
+
if report.total_errors > 0:
|
|
162
|
+
print(f"\n{report.total_errors} error(s) analyzed")
|
|
163
|
+
print(
|
|
164
|
+
f"{report.stats['total_actions']} improvement action(s) generated"
|
|
165
|
+
)
|
|
166
|
+
else:
|
|
167
|
+
print("\n✅ No errors detected in session!")
|
|
168
|
+
|
|
169
|
+
except Exception as e:
|
|
170
|
+
logger.error(f"Failed to save report: {e}")
|
|
171
|
+
print(f"❌ Failed to save report: {e!s}")
|
|
172
|
+
# Still output to terminal
|
|
173
|
+
reporter.report(report, format="terminal")
|
|
174
|
+
else:
|
|
175
|
+
# Output to terminal
|
|
176
|
+
reporter.report(report, format=output_format)
|
|
177
|
+
|
|
178
|
+
# Apply fixes if requested
|
|
179
|
+
if args.auto_fix and not args.dry_run:
|
|
180
|
+
exit_code = _apply_auto_fixes(report, args.verbose)
|
|
181
|
+
if exit_code != 0:
|
|
182
|
+
return exit_code
|
|
183
|
+
|
|
184
|
+
# Create PRs if requested
|
|
185
|
+
if args.create_prs and not args.dry_run:
|
|
186
|
+
exit_code = _create_prs(report, args.verbose)
|
|
187
|
+
if exit_code != 0:
|
|
188
|
+
return exit_code
|
|
189
|
+
|
|
190
|
+
# Dry-run message
|
|
191
|
+
if args.dry_run and (args.auto_fix or args.create_prs):
|
|
192
|
+
print("\n🔍 Dry-run mode: No changes applied")
|
|
193
|
+
print(" Remove --dry-run to apply changes")
|
|
194
|
+
|
|
195
|
+
# Determine exit code
|
|
196
|
+
if report.total_errors == 0:
|
|
197
|
+
return 0 # No errors
|
|
198
|
+
|
|
199
|
+
if report.stats.get("critical_priority", 0) > 0:
|
|
200
|
+
return 2 # Critical errors found
|
|
201
|
+
|
|
202
|
+
return 1 # Non-critical errors found
|
|
203
|
+
|
|
204
|
+
except KeyboardInterrupt:
|
|
205
|
+
print("\nPostmortem analysis interrupted by user")
|
|
206
|
+
return 130
|
|
207
|
+
|
|
208
|
+
except Exception as e:
|
|
209
|
+
logger.error(f"Postmortem analysis failed: {e}", exc_info=True)
|
|
210
|
+
print(f"\n❌ Postmortem analysis failed: {e!s}")
|
|
211
|
+
if args.verbose:
|
|
212
|
+
import traceback
|
|
213
|
+
|
|
214
|
+
traceback.print_exc()
|
|
215
|
+
return 2
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def _apply_auto_fixes(report, verbose: bool) -> int:
|
|
219
|
+
"""Apply auto-fix actions from report.
|
|
220
|
+
|
|
221
|
+
Args:
|
|
222
|
+
report: Postmortem report
|
|
223
|
+
verbose: Show detailed output
|
|
224
|
+
|
|
225
|
+
Returns:
|
|
226
|
+
Exit code (0 for success, non-zero for errors)
|
|
227
|
+
"""
|
|
228
|
+
from claude_mpm.services.analysis import ActionType
|
|
229
|
+
|
|
230
|
+
auto_fix_actions = report.get_actions_by_type(ActionType.AUTO_FIX)
|
|
231
|
+
|
|
232
|
+
if not auto_fix_actions:
|
|
233
|
+
print("\n✅ No auto-fixable errors found")
|
|
234
|
+
return 0
|
|
235
|
+
|
|
236
|
+
print(f"\n🔧 Applying {len(auto_fix_actions)} auto-fix action(s)...")
|
|
237
|
+
|
|
238
|
+
import subprocess
|
|
239
|
+
|
|
240
|
+
success_count = 0
|
|
241
|
+
fail_count = 0
|
|
242
|
+
|
|
243
|
+
for i, action in enumerate(auto_fix_actions, 1):
|
|
244
|
+
print(f"\n[{i}/{len(auto_fix_actions)}] {action.description}")
|
|
245
|
+
|
|
246
|
+
# Run each command
|
|
247
|
+
for cmd in action.commands:
|
|
248
|
+
if verbose:
|
|
249
|
+
print(f" Running: {cmd}")
|
|
250
|
+
|
|
251
|
+
try:
|
|
252
|
+
result = subprocess.run(
|
|
253
|
+
cmd,
|
|
254
|
+
check=False,
|
|
255
|
+
shell=True,
|
|
256
|
+
capture_output=True,
|
|
257
|
+
text=True,
|
|
258
|
+
timeout=30,
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
if result.returncode == 0:
|
|
262
|
+
action.status = "completed"
|
|
263
|
+
if verbose:
|
|
264
|
+
print(f" ✅ Success: {cmd}")
|
|
265
|
+
else:
|
|
266
|
+
action.status = "failed"
|
|
267
|
+
action.error_message = result.stderr or result.stdout
|
|
268
|
+
print(f" ❌ Failed: {cmd}")
|
|
269
|
+
if verbose and result.stderr:
|
|
270
|
+
print(f" {result.stderr}")
|
|
271
|
+
fail_count += 1
|
|
272
|
+
break # Stop on first failure for this action
|
|
273
|
+
|
|
274
|
+
except subprocess.TimeoutExpired:
|
|
275
|
+
action.status = "failed"
|
|
276
|
+
action.error_message = "Command timed out"
|
|
277
|
+
print(f" ❌ Timeout: {cmd}")
|
|
278
|
+
fail_count += 1
|
|
279
|
+
break
|
|
280
|
+
|
|
281
|
+
except Exception as e:
|
|
282
|
+
action.status = "failed"
|
|
283
|
+
action.error_message = str(e)
|
|
284
|
+
print(f" ❌ Error: {e}")
|
|
285
|
+
fail_count += 1
|
|
286
|
+
break
|
|
287
|
+
|
|
288
|
+
if action.status == "completed":
|
|
289
|
+
success_count += 1
|
|
290
|
+
|
|
291
|
+
# Summary
|
|
292
|
+
print("\n📊 Auto-fix Results:")
|
|
293
|
+
print(f" ✅ Successful: {success_count}")
|
|
294
|
+
print(f" ❌ Failed: {fail_count}")
|
|
295
|
+
|
|
296
|
+
return 0 if fail_count == 0 else 1
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
def _create_prs(report, verbose: bool) -> int:
|
|
300
|
+
"""Create PRs for agent improvements.
|
|
301
|
+
|
|
302
|
+
Args:
|
|
303
|
+
report: Postmortem report
|
|
304
|
+
verbose: Show detailed output
|
|
305
|
+
|
|
306
|
+
Returns:
|
|
307
|
+
Exit code (0 for success, non-zero for errors)
|
|
308
|
+
"""
|
|
309
|
+
from claude_mpm.services.analysis import ActionType
|
|
310
|
+
|
|
311
|
+
pr_actions = report.get_actions_by_type(ActionType.CREATE_PR)
|
|
312
|
+
|
|
313
|
+
if not pr_actions:
|
|
314
|
+
print("\n✅ No PR actions needed")
|
|
315
|
+
return 0
|
|
316
|
+
|
|
317
|
+
print(f"\n🤖 Creating {len(pr_actions)} PR(s) for agent improvements...")
|
|
318
|
+
|
|
319
|
+
# Check if we're in the agent cache git repo
|
|
320
|
+
agent_cache_path = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
|
|
321
|
+
|
|
322
|
+
if not agent_cache_path.exists():
|
|
323
|
+
print(f"❌ Agent cache not found at: {agent_cache_path}")
|
|
324
|
+
print(" Run 'claude-mpm agents sync' first")
|
|
325
|
+
return 2
|
|
326
|
+
|
|
327
|
+
success_count = 0
|
|
328
|
+
fail_count = 0
|
|
329
|
+
|
|
330
|
+
for i, action in enumerate(pr_actions, 1):
|
|
331
|
+
print(f"\n[{i}/{len(pr_actions)}] {action.description}")
|
|
332
|
+
|
|
333
|
+
try:
|
|
334
|
+
# Check if file is in agent cache
|
|
335
|
+
analysis = action.error_analysis
|
|
336
|
+
if not analysis.affected_file:
|
|
337
|
+
print(" ⚠️ Cannot determine affected file, skipping")
|
|
338
|
+
action.status = "failed"
|
|
339
|
+
action.error_message = "No affected file identified"
|
|
340
|
+
fail_count += 1
|
|
341
|
+
continue
|
|
342
|
+
|
|
343
|
+
# For MVP, print PR template instead of actually creating
|
|
344
|
+
# Full implementation would use GitHub CLI or API
|
|
345
|
+
print(" 📝 PR Template Generated:")
|
|
346
|
+
print(f" Branch: {action.pr_branch}")
|
|
347
|
+
print(f" Title: {action.pr_title}")
|
|
348
|
+
|
|
349
|
+
if verbose:
|
|
350
|
+
print("\n--- PR Body ---")
|
|
351
|
+
print(action.pr_body)
|
|
352
|
+
print("--- End PR Body ---\n")
|
|
353
|
+
|
|
354
|
+
print("\n ℹ️ To create PR manually:")
|
|
355
|
+
print(f" cd {agent_cache_path}")
|
|
356
|
+
print(f" git checkout -b {action.pr_branch}")
|
|
357
|
+
print(f" # Make your changes to {analysis.affected_file}")
|
|
358
|
+
print(f" git add {analysis.affected_file}")
|
|
359
|
+
print(f' git commit -m "{action.pr_title}"')
|
|
360
|
+
print(f" git push origin {action.pr_branch}")
|
|
361
|
+
print(
|
|
362
|
+
f' gh pr create --title "{action.pr_title}" --body-file pr_body.md'
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
action.status = "completed"
|
|
366
|
+
success_count += 1
|
|
367
|
+
|
|
368
|
+
except Exception as e:
|
|
369
|
+
logger.error(f"Failed to create PR: {e}")
|
|
370
|
+
print(f" ❌ Error: {e}")
|
|
371
|
+
action.status = "failed"
|
|
372
|
+
action.error_message = str(e)
|
|
373
|
+
fail_count += 1
|
|
374
|
+
|
|
375
|
+
# Summary
|
|
376
|
+
print("\n📊 PR Creation Results:")
|
|
377
|
+
print(f" ✅ Templates generated: {success_count}")
|
|
378
|
+
print(f" ❌ Failed: {fail_count}")
|
|
379
|
+
|
|
380
|
+
return 0 if fail_count == 0 else 1
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
# Optional: Standalone execution for testing
|
|
384
|
+
if __name__ == "__main__":
|
|
385
|
+
import argparse
|
|
386
|
+
|
|
387
|
+
parser = argparse.ArgumentParser(description="Claude MPM Postmortem Analysis")
|
|
388
|
+
parser.add_argument("--dry-run", action="store_true")
|
|
389
|
+
parser.add_argument("--auto-fix", action="store_true")
|
|
390
|
+
parser.add_argument("--create-prs", action="store_true")
|
|
391
|
+
parser.add_argument("--session-id", type=str)
|
|
392
|
+
parser.add_argument(
|
|
393
|
+
"--format", choices=["terminal", "json", "markdown"], default="terminal"
|
|
394
|
+
)
|
|
395
|
+
parser.add_argument("--output", "-o", type=Path)
|
|
396
|
+
parser.add_argument("--verbose", "-v", action="store_true")
|
|
397
|
+
parser.add_argument("--no-color", action="store_true")
|
|
398
|
+
|
|
399
|
+
args = parser.parse_args()
|
|
400
|
+
|
|
401
|
+
sys.exit(postmortem_command(args))
|
claude_mpm/cli/commands/run.py
CHANGED
|
@@ -569,41 +569,6 @@ class RunCommand(BaseCommand):
|
|
|
569
569
|
return False
|
|
570
570
|
|
|
571
571
|
|
|
572
|
-
def _ensure_mcp_services_configured(logger):
|
|
573
|
-
"""
|
|
574
|
-
Ensure MCP services are configured in .mcp.json on startup.
|
|
575
|
-
|
|
576
|
-
This function automatically configures the core MCP services
|
|
577
|
-
(mcp-vector-search, mcp-browser, mcp-ticketer) if they're not
|
|
578
|
-
already configured in the project's .mcp.json file.
|
|
579
|
-
|
|
580
|
-
Args:
|
|
581
|
-
logger: Logger instance for output
|
|
582
|
-
"""
|
|
583
|
-
try:
|
|
584
|
-
from ...services.mcp_config_manager import MCPConfigManager
|
|
585
|
-
|
|
586
|
-
logger.debug("Checking MCP service configuration...")
|
|
587
|
-
manager = MCPConfigManager()
|
|
588
|
-
|
|
589
|
-
# Check and auto-configure missing MCP services
|
|
590
|
-
success, message = manager.ensure_mcp_services_configured()
|
|
591
|
-
|
|
592
|
-
if success:
|
|
593
|
-
if "already configured" not in message.lower():
|
|
594
|
-
logger.info(message)
|
|
595
|
-
print(f"✅ {message}")
|
|
596
|
-
else:
|
|
597
|
-
logger.debug(message)
|
|
598
|
-
else:
|
|
599
|
-
logger.warning(f"MCP auto-configuration issue: {message}")
|
|
600
|
-
# Don't fail the session, just warn
|
|
601
|
-
|
|
602
|
-
except Exception as e:
|
|
603
|
-
logger.debug(f"MCP auto-configuration skipped: {e}")
|
|
604
|
-
# Don't fail the session if auto-configuration fails
|
|
605
|
-
|
|
606
|
-
|
|
607
572
|
def _handle_reload_agents(logger):
|
|
608
573
|
"""
|
|
609
574
|
Handle the --reload-agents flag by deleting all local claude-mpm system agents.
|
|
@@ -738,10 +703,7 @@ def run_session_legacy(args):
|
|
|
738
703
|
if getattr(args, "reload_agents", False):
|
|
739
704
|
_handle_reload_agents(logger)
|
|
740
705
|
|
|
741
|
-
#
|
|
742
|
-
_ensure_mcp_services_configured(logger)
|
|
743
|
-
|
|
744
|
-
# Trigger vector search indexing after MCP is configured
|
|
706
|
+
# Trigger vector search indexing
|
|
745
707
|
try:
|
|
746
708
|
from ...cli.startup_logging import start_vector_search_indexing
|
|
747
709
|
|