claude-mpm 5.0.2__py3-none-any.whl → 5.4.3__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 +1218 -905
- claude_mpm/agents/agent_loader.py +10 -17
- claude_mpm/agents/base_agent_loader.py +10 -35
- claude_mpm/agents/frontmatter_validator.py +68 -0
- claude_mpm/agents/templates/circuit-breakers.md +431 -45
- claude_mpm/cli/__init__.py +0 -1
- claude_mpm/cli/commands/__init__.py +2 -0
- claude_mpm/cli/commands/agent_state_manager.py +67 -23
- claude_mpm/cli/commands/agents.py +446 -25
- claude_mpm/cli/commands/auto_configure.py +535 -233
- claude_mpm/cli/commands/configure.py +1500 -147
- claude_mpm/cli/commands/configure_agent_display.py +13 -6
- claude_mpm/cli/commands/mpm_init/core.py +158 -1
- 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/postmortem.py +401 -0
- claude_mpm/cli/commands/run.py +1 -39
- claude_mpm/cli/commands/skills.py +322 -19
- claude_mpm/cli/commands/summarize.py +413 -0
- claude_mpm/cli/executor.py +8 -0
- 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 +9 -0
- claude_mpm/cli/parsers/skills_parser.py +7 -0
- claude_mpm/cli/startup.py +133 -85
- 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-ticket-organize.md → mpm-organize.md} +4 -5
- claude_mpm/commands/mpm-postmortem.md +123 -0
- claude_mpm/commands/mpm-session-resume.md +2 -2
- claude_mpm/commands/mpm-ticket-view.md +2 -2
- claude_mpm/config/agent_presets.py +312 -82
- claude_mpm/config/agent_sources.py +27 -0
- 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/agent_loader.py +8 -5
- 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/socketio_pool.py +3 -3
- claude_mpm/core/system_context.py +38 -0
- claude_mpm/core/unified_agent_registry.py +134 -16
- claude_mpm/core/unified_config.py +22 -0
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.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/correlation_manager.py +60 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +35 -2
- claude_mpm/hooks/claude_hooks/hook_handler.py +4 -0
- claude_mpm/hooks/claude_hooks/memory_integration.py +12 -1
- 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/hooks/claude_hooks/services/connection_manager.py +4 -0
- claude_mpm/models/agent_definition.py +7 -0
- claude_mpm/scripts/launch_monitor.py +93 -13
- claude_mpm/services/agents/agent_recommendation_service.py +279 -0
- claude_mpm/services/agents/cache_git_manager.py +621 -0
- claude_mpm/services/agents/deployment/agent_template_builder.py +3 -2
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +110 -3
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +518 -55
- claude_mpm/services/agents/git_source_manager.py +20 -0
- claude_mpm/services/agents/sources/git_source_sync_service.py +45 -6
- claude_mpm/services/agents/toolchain_detector.py +6 -5
- claude_mpm/services/analysis/__init__.py +35 -0
- claude_mpm/services/analysis/clone_detector.py +1030 -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 +106 -5
- claude_mpm/services/core/base.py +7 -2
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +7 -15
- claude_mpm/services/event_bus/config.py +3 -1
- claude_mpm/services/git/git_operations_service.py +8 -8
- claude_mpm/services/mcp_config_manager.py +75 -145
- claude_mpm/services/mcp_service_verifier.py +6 -3
- claude_mpm/services/monitor/daemon.py +37 -10
- claude_mpm/services/monitor/daemon_manager.py +134 -21
- claude_mpm/services/monitor/server.py +225 -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/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 +261 -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.4.3.dist-info}/METADATA +69 -84
- {claude_mpm-5.0.2.dist-info → claude_mpm-5.4.3.dist-info}/RECORD +112 -153
- {claude_mpm-5.0.2.dist-info → claude_mpm-5.4.3.dist-info}/entry_points.txt +0 -2
- 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/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 -971
- 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/agents/{OUTPUT_STYLE.md → CLAUDE_MPM_OUTPUT_STYLE.md} +0 -0
- {claude_mpm-5.0.2.dist-info → claude_mpm-5.4.3.dist-info}/WHEEL +0 -0
- {claude_mpm-5.0.2.dist-info → claude_mpm-5.4.3.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.0.2.dist-info → claude_mpm-5.4.3.dist-info}/top_level.txt +0 -0
|
@@ -10,7 +10,9 @@ from pathlib import Path
|
|
|
10
10
|
from typing import Any, Dict, Optional
|
|
11
11
|
|
|
12
12
|
__all__ = [
|
|
13
|
+
"build_enhanced_update_prompt",
|
|
13
14
|
"build_initialization_prompt",
|
|
15
|
+
"build_prompt_engineer_optimization_prompt",
|
|
14
16
|
"build_research_context_prompt",
|
|
15
17
|
"build_update_prompt",
|
|
16
18
|
]
|
|
@@ -305,6 +307,208 @@ preserving valuable project-specific information while refreshing standard secti
|
|
|
305
307
|
return prompt
|
|
306
308
|
|
|
307
309
|
|
|
310
|
+
def build_enhanced_update_prompt(
|
|
311
|
+
project_path: Path,
|
|
312
|
+
doc_analysis: Dict[str, Any],
|
|
313
|
+
git_insights: Dict[str, Any],
|
|
314
|
+
log_insights: Dict[str, Any],
|
|
315
|
+
memory_insights: Dict[str, Any],
|
|
316
|
+
project_type: Optional[str] = None,
|
|
317
|
+
framework: Optional[str] = None,
|
|
318
|
+
ast_analysis: bool = True,
|
|
319
|
+
preserve_custom: bool = True,
|
|
320
|
+
) -> str:
|
|
321
|
+
"""
|
|
322
|
+
Build enhanced update prompt with extracted knowledge from multiple sources.
|
|
323
|
+
|
|
324
|
+
This is the AUTO-DETECTED update mode that enriches CLAUDE.md with:
|
|
325
|
+
- Git history insights (architectural decisions, tech changes, workflows)
|
|
326
|
+
- Session log learnings (completed work, patterns)
|
|
327
|
+
- Memory file knowledge (accumulated project wisdom)
|
|
328
|
+
|
|
329
|
+
Args:
|
|
330
|
+
project_path: Path to the project directory
|
|
331
|
+
doc_analysis: Analysis results from DocumentationManager
|
|
332
|
+
git_insights: Extracted git history insights
|
|
333
|
+
log_insights: Extracted session log insights
|
|
334
|
+
memory_insights: Extracted memory file insights
|
|
335
|
+
project_type: Type of project (web, api, cli, library, etc.)
|
|
336
|
+
framework: Specific framework if applicable
|
|
337
|
+
ast_analysis: Enable AST analysis for enhanced documentation
|
|
338
|
+
preserve_custom: Preserve custom sections when updating
|
|
339
|
+
|
|
340
|
+
Returns:
|
|
341
|
+
Formatted prompt string for enhanced update mode
|
|
342
|
+
"""
|
|
343
|
+
prompt = f"""Please delegate this task to the Agentic Coder Optimizer agent:
|
|
344
|
+
|
|
345
|
+
ENHANCED UPDATE of existing CLAUDE.md documentation with extracted project knowledge.
|
|
346
|
+
|
|
347
|
+
Project Path: {project_path}
|
|
348
|
+
Update Mode: Knowledge-enriched smart merge
|
|
349
|
+
"""
|
|
350
|
+
if project_type:
|
|
351
|
+
prompt += f"Project Type: {project_type}\n"
|
|
352
|
+
if framework:
|
|
353
|
+
prompt += f"Framework: {framework}\n"
|
|
354
|
+
|
|
355
|
+
prompt += f"""
|
|
356
|
+
Existing Documentation Analysis:
|
|
357
|
+
- Current CLAUDE.md: {doc_analysis.get("size", 0):,} characters, {doc_analysis.get("lines", 0)} lines
|
|
358
|
+
- Has Priority Index: {"Yes" if doc_analysis.get("has_priority_index") else "No"}
|
|
359
|
+
- Custom Sections: {len(doc_analysis.get("custom_sections", []))} found
|
|
360
|
+
"""
|
|
361
|
+
if preserve_custom and doc_analysis.get("custom_sections"):
|
|
362
|
+
prompt += f"- Preserve Custom Sections: {', '.join(doc_analysis['custom_sections'][:5])}\n"
|
|
363
|
+
|
|
364
|
+
# Add extracted knowledge sections
|
|
365
|
+
prompt += "\n## Extracted Project Knowledge\n\n"
|
|
366
|
+
|
|
367
|
+
# Git insights
|
|
368
|
+
if git_insights.get("available"):
|
|
369
|
+
prompt += "### From Git History (last 90 days):\n\n"
|
|
370
|
+
|
|
371
|
+
if git_insights.get("architectural_decisions"):
|
|
372
|
+
prompt += "**Architectural Patterns Detected:**\n"
|
|
373
|
+
for decision in git_insights["architectural_decisions"][:10]:
|
|
374
|
+
prompt += f"- {decision}\n"
|
|
375
|
+
prompt += "\n"
|
|
376
|
+
|
|
377
|
+
if git_insights.get("tech_stack_changes"):
|
|
378
|
+
prompt += "**Tech Stack Changes:**\n"
|
|
379
|
+
for change in git_insights["tech_stack_changes"][:10]:
|
|
380
|
+
prompt += f"- {change}\n"
|
|
381
|
+
prompt += "\n"
|
|
382
|
+
|
|
383
|
+
if git_insights.get("workflow_patterns"):
|
|
384
|
+
prompt += "**Common Workflows:**\n"
|
|
385
|
+
for workflow in git_insights["workflow_patterns"][:8]:
|
|
386
|
+
prompt += f"- {workflow}\n"
|
|
387
|
+
prompt += "\n"
|
|
388
|
+
|
|
389
|
+
if git_insights.get("hot_files"):
|
|
390
|
+
prompt += "**Hot Files (frequently modified):**\n"
|
|
391
|
+
for file_info in git_insights["hot_files"][:10]:
|
|
392
|
+
prompt += (
|
|
393
|
+
f"- {file_info['path']} ({file_info['modifications']} changes)\n"
|
|
394
|
+
)
|
|
395
|
+
prompt += "\n"
|
|
396
|
+
|
|
397
|
+
# Session log insights
|
|
398
|
+
if log_insights.get("available") and log_insights.get("learnings"):
|
|
399
|
+
prompt += "### From Session Logs:\n\n"
|
|
400
|
+
prompt += "**Recent Learnings from PM Summaries:**\n"
|
|
401
|
+
for learning in log_insights["learnings"][:10]:
|
|
402
|
+
source = learning.get("source", "unknown")
|
|
403
|
+
content = learning.get("content", "")
|
|
404
|
+
# Truncate long content
|
|
405
|
+
if len(content) > 200:
|
|
406
|
+
content = content[:200] + "..."
|
|
407
|
+
prompt += f"- [{source}] {content}\n"
|
|
408
|
+
prompt += "\n"
|
|
409
|
+
|
|
410
|
+
if log_insights.get("common_patterns"):
|
|
411
|
+
prompt += "**Common Task Patterns:**\n"
|
|
412
|
+
prompt += f"- {', '.join(log_insights['common_patterns'][:10])}\n\n"
|
|
413
|
+
|
|
414
|
+
# Memory insights
|
|
415
|
+
if memory_insights.get("available"):
|
|
416
|
+
has_content = False
|
|
417
|
+
|
|
418
|
+
if memory_insights.get("architectural_knowledge"):
|
|
419
|
+
has_content = True
|
|
420
|
+
prompt += "### From Agent Memories:\n\n"
|
|
421
|
+
prompt += "**Architectural Knowledge:**\n"
|
|
422
|
+
for item in memory_insights["architectural_knowledge"][:8]:
|
|
423
|
+
prompt += f"- {item}\n"
|
|
424
|
+
prompt += "\n"
|
|
425
|
+
|
|
426
|
+
if memory_insights.get("implementation_guidelines"):
|
|
427
|
+
if not has_content:
|
|
428
|
+
prompt += "### From Agent Memories:\n\n"
|
|
429
|
+
has_content = True
|
|
430
|
+
prompt += "**Implementation Guidelines:**\n"
|
|
431
|
+
for item in memory_insights["implementation_guidelines"][:8]:
|
|
432
|
+
prompt += f"- {item}\n"
|
|
433
|
+
prompt += "\n"
|
|
434
|
+
|
|
435
|
+
if memory_insights.get("common_mistakes"):
|
|
436
|
+
if not has_content:
|
|
437
|
+
prompt += "### From Agent Memories:\n\n"
|
|
438
|
+
has_content = True
|
|
439
|
+
prompt += "**Common Mistakes to Avoid:**\n"
|
|
440
|
+
for item in memory_insights["common_mistakes"][:8]:
|
|
441
|
+
prompt += f"- {item}\n"
|
|
442
|
+
prompt += "\n"
|
|
443
|
+
|
|
444
|
+
if memory_insights.get("technical_context"):
|
|
445
|
+
if not has_content:
|
|
446
|
+
prompt += "### From Agent Memories:\n\n"
|
|
447
|
+
prompt += "**Current Technical Context:**\n"
|
|
448
|
+
for item in memory_insights["technical_context"][:8]:
|
|
449
|
+
prompt += f"- {item}\n"
|
|
450
|
+
prompt += "\n"
|
|
451
|
+
|
|
452
|
+
# Add update instructions
|
|
453
|
+
prompt += """
|
|
454
|
+
## UPDATE Tasks with Knowledge Integration:
|
|
455
|
+
|
|
456
|
+
1. **Review Existing Content**:
|
|
457
|
+
- Analyze current CLAUDE.md structure and content
|
|
458
|
+
- Identify outdated or missing information
|
|
459
|
+
- Preserve valuable custom sections and project-specific knowledge
|
|
460
|
+
|
|
461
|
+
2. **Integrate Extracted Knowledge**:
|
|
462
|
+
- Merge architectural decisions from git history into Architecture section
|
|
463
|
+
- Add tech stack changes to Technology/Dependencies sections
|
|
464
|
+
- Update workflow patterns in Development Guidelines
|
|
465
|
+
- Incorporate session learnings into relevant sections
|
|
466
|
+
- Merge memory insights into appropriate documentation areas
|
|
467
|
+
- Highlight hot files as critical components
|
|
468
|
+
|
|
469
|
+
3. **Smart Content Merge**:
|
|
470
|
+
- Update project overview with recent developments
|
|
471
|
+
- Refresh architecture documentation with detected patterns
|
|
472
|
+
- Update development workflows with discovered common patterns
|
|
473
|
+
- Ensure single-path principle (ONE way to do each task)
|
|
474
|
+
- Remove duplicate or contradictory information
|
|
475
|
+
|
|
476
|
+
4. **Update Priority Organization**:
|
|
477
|
+
- Reorganize content with priority markers (🔴🟡🟢⚪)
|
|
478
|
+
- Ensure critical instructions are at the top
|
|
479
|
+
- Update priority index with all important items
|
|
480
|
+
- Promote frequently-modified files to IMPORTANT sections
|
|
481
|
+
|
|
482
|
+
5. **Refresh Technical Content**:
|
|
483
|
+
- Update build/test/deploy commands based on workflow patterns
|
|
484
|
+
- Verify tool configurations match tech stack changes
|
|
485
|
+
- Update dependency information with detected changes
|
|
486
|
+
- Refresh API documentation if applicable
|
|
487
|
+
"""
|
|
488
|
+
if ast_analysis:
|
|
489
|
+
prompt += """
|
|
490
|
+
6. **Update Code Documentation** (using Code Analyzer agent):
|
|
491
|
+
- Re-analyze code structure for changes
|
|
492
|
+
- Update API documentation
|
|
493
|
+
- Refresh architecture diagrams
|
|
494
|
+
- Document hot files and critical components
|
|
495
|
+
"""
|
|
496
|
+
prompt += """
|
|
497
|
+
7. **Final Optimization**:
|
|
498
|
+
- Ensure single-path principle throughout
|
|
499
|
+
- Validate all links and references
|
|
500
|
+
- Add/update timestamp in meta section
|
|
501
|
+
- Add "Last Updated" note mentioning knowledge extraction
|
|
502
|
+
- Verify AI agent readability
|
|
503
|
+
|
|
504
|
+
IMPORTANT: This is an ENHANCED UPDATE operation with extracted knowledge.
|
|
505
|
+
Intelligently merge insights from git history, session logs, and agent memories
|
|
506
|
+
into the existing CLAUDE.md while preserving valuable custom content.
|
|
507
|
+
The goal is to create a living document that reflects actual project evolution.
|
|
508
|
+
"""
|
|
509
|
+
return prompt
|
|
510
|
+
|
|
511
|
+
|
|
308
512
|
def build_research_context_prompt(git_analysis: Dict[str, Any], days: int) -> str:
|
|
309
513
|
"""
|
|
310
514
|
Build structured Research agent delegation prompt from git analysis.
|
|
@@ -440,3 +644,79 @@ Keep it concise (<1000 words) but actionable.
|
|
|
440
644
|
"""
|
|
441
645
|
|
|
442
646
|
return prompt
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
def build_prompt_engineer_optimization_prompt(
|
|
650
|
+
content: str, estimated_tokens: int
|
|
651
|
+
) -> str:
|
|
652
|
+
"""
|
|
653
|
+
Build prompt for prompt-engineer to optimize CLAUDE.md.
|
|
654
|
+
|
|
655
|
+
Args:
|
|
656
|
+
content: Current CLAUDE.md content to optimize
|
|
657
|
+
estimated_tokens: Estimated token count of current content
|
|
658
|
+
|
|
659
|
+
Returns:
|
|
660
|
+
Formatted prompt string for prompt-engineer optimization
|
|
661
|
+
"""
|
|
662
|
+
return f"""Please delegate this task to the Prompt Engineer agent:
|
|
663
|
+
|
|
664
|
+
Optimize this CLAUDE.md file for conciseness, clarity, and token efficiency while preserving all critical information.
|
|
665
|
+
|
|
666
|
+
## Current CLAUDE.md Statistics
|
|
667
|
+
- Estimated tokens: {estimated_tokens:,}
|
|
668
|
+
- Target reduction: 20-30% if possible
|
|
669
|
+
- Priority: Preserve ALL CRITICAL (🔴) and IMPORTANT (🟡) information
|
|
670
|
+
|
|
671
|
+
## Optimization Goals
|
|
672
|
+
|
|
673
|
+
1. **Remove Redundancy**:
|
|
674
|
+
- Eliminate duplicate information across sections
|
|
675
|
+
- Consolidate similar instructions
|
|
676
|
+
- Remove verbose explanations where brevity suffices
|
|
677
|
+
|
|
678
|
+
2. **Tighten Language**:
|
|
679
|
+
- Use fewer words to convey the same meaning
|
|
680
|
+
- Replace wordy phrases with concise alternatives
|
|
681
|
+
- Remove filler words and unnecessary qualifiers
|
|
682
|
+
|
|
683
|
+
3. **Improve Structure**:
|
|
684
|
+
- Ensure clear hierarchical organization
|
|
685
|
+
- Use priority markers (🔴 🟡 🟢 ⚪) effectively
|
|
686
|
+
- Group related information logically
|
|
687
|
+
- Maintain scannable headings
|
|
688
|
+
|
|
689
|
+
4. **Preserve Critical Content**:
|
|
690
|
+
- Keep ALL security and data handling rules (🔴)
|
|
691
|
+
- Maintain core business logic and constraints (🔴)
|
|
692
|
+
- Preserve architectural decisions (🟡)
|
|
693
|
+
- Keep essential workflows intact (🟡)
|
|
694
|
+
|
|
695
|
+
5. **Apply Claude Best Practices**:
|
|
696
|
+
- Use high-level guidance over prescriptive checklists
|
|
697
|
+
- Provide context for WHY, not just WHAT
|
|
698
|
+
- Ensure instructions are actionable and unambiguous
|
|
699
|
+
- Optimize for AI agent understanding
|
|
700
|
+
|
|
701
|
+
## Current CLAUDE.md Content
|
|
702
|
+
|
|
703
|
+
{content}
|
|
704
|
+
|
|
705
|
+
## Output Requirements
|
|
706
|
+
|
|
707
|
+
Return ONLY the optimized CLAUDE.md content with NO additional explanations.
|
|
708
|
+
The optimized version should:
|
|
709
|
+
- Reduce token count by 20-30% if feasible
|
|
710
|
+
- Maintain all CRITICAL and IMPORTANT instructions
|
|
711
|
+
- Improve clarity and scannability
|
|
712
|
+
- Follow the same structural template (Priority Index, sections with markers)
|
|
713
|
+
|
|
714
|
+
## Quality Criteria
|
|
715
|
+
|
|
716
|
+
✅ All 🔴 CRITICAL items preserved
|
|
717
|
+
✅ All 🟡 IMPORTANT items preserved
|
|
718
|
+
✅ No contradictory instructions
|
|
719
|
+
✅ Clear, concise language throughout
|
|
720
|
+
✅ Logical organization maintained
|
|
721
|
+
✅ Token count reduced meaningfully
|
|
722
|
+
"""
|
|
@@ -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))
|