claude-mpm 5.4.81__py3-none-any.whl → 5.4.83__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/VERSION +1 -1
- claude_mpm/cli/startup.py +73 -289
- claude_mpm/core/unified_config.py +1 -0
- claude_mpm/skills/bundled/pm/pm-bug-reporting/pm-bug-reporting.md +248 -0
- {claude_mpm-5.4.81.dist-info → claude_mpm-5.4.83.dist-info}/METADATA +1 -1
- {claude_mpm-5.4.81.dist-info → claude_mpm-5.4.83.dist-info}/RECORD +11 -10
- {claude_mpm-5.4.81.dist-info → claude_mpm-5.4.83.dist-info}/WHEEL +0 -0
- {claude_mpm-5.4.81.dist-info → claude_mpm-5.4.83.dist-info}/entry_points.txt +0 -0
- {claude_mpm-5.4.81.dist-info → claude_mpm-5.4.83.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.4.81.dist-info → claude_mpm-5.4.83.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.4.81.dist-info → claude_mpm-5.4.83.dist-info}/top_level.txt +0 -0
claude_mpm/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
5.4.
|
|
1
|
+
5.4.83
|
claude_mpm/cli/startup.py
CHANGED
|
@@ -234,7 +234,7 @@ def deploy_bundled_skills():
|
|
|
234
234
|
if not skills_config.get("auto_deploy", True):
|
|
235
235
|
# Auto-deploy disabled, skip silently
|
|
236
236
|
return
|
|
237
|
-
except Exception:
|
|
237
|
+
except Exception: # nosec B110
|
|
238
238
|
# If config loading fails, assume auto-deploy is enabled (default)
|
|
239
239
|
pass
|
|
240
240
|
|
|
@@ -489,7 +489,6 @@ def sync_remote_agents_on_startup(force_sync: bool = False):
|
|
|
489
489
|
from pathlib import Path
|
|
490
490
|
|
|
491
491
|
from ..core.shared.config_loader import ConfigLoader
|
|
492
|
-
from ..services.agents.deployment.agent_deployment import AgentDeploymentService
|
|
493
492
|
from ..services.agents.startup_sync import sync_agents_on_startup
|
|
494
493
|
from ..services.profile_manager import ProfileManager
|
|
495
494
|
from ..utils.progress import ProgressBar
|
|
@@ -537,304 +536,89 @@ def sync_remote_agents_on_startup(force_sync: bool = False):
|
|
|
537
536
|
logger.warning(f"Agent sync completed with {len(errors)} errors")
|
|
538
537
|
|
|
539
538
|
# Phase 2: Deploy agents from cache to ~/.claude/agents/
|
|
540
|
-
#
|
|
539
|
+
# Use reconciliation service to respect configuration.yaml settings
|
|
541
540
|
try:
|
|
542
|
-
# Initialize deployment service with profile-filtered configuration
|
|
543
|
-
from ..core.config import Config
|
|
544
|
-
|
|
545
|
-
deploy_config = None
|
|
546
|
-
if active_profile and profile_manager.active_profile:
|
|
547
|
-
# Create config with excluded agents based on profile
|
|
548
|
-
# Get all agents that should be excluded (not in enabled list)
|
|
549
|
-
from pathlib import Path
|
|
550
|
-
|
|
551
|
-
cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
|
|
552
|
-
if cache_dir.exists():
|
|
553
|
-
# Find all agent files
|
|
554
|
-
# Supports both flat cache and {owner}/{repo}/agents/ structure
|
|
555
|
-
all_agent_files = [
|
|
556
|
-
f
|
|
557
|
-
for f in cache_dir.rglob("*.md")
|
|
558
|
-
if "/agents/" in str(f)
|
|
559
|
-
and f.stem.lower() != "base-agent"
|
|
560
|
-
and f.name.lower()
|
|
561
|
-
not in {"readme.md", "changelog.md", "contributing.md"}
|
|
562
|
-
]
|
|
563
|
-
|
|
564
|
-
# Build exclusion list for agents not in profile
|
|
565
|
-
excluded_agents = []
|
|
566
|
-
for agent_file in all_agent_files:
|
|
567
|
-
agent_name = agent_file.stem
|
|
568
|
-
if not profile_manager.is_agent_enabled(agent_name):
|
|
569
|
-
excluded_agents.append(agent_name)
|
|
570
|
-
|
|
571
|
-
if excluded_agents:
|
|
572
|
-
# Get singleton config and update with profile settings
|
|
573
|
-
# BUGFIX: Config is a singleton that ignores dict parameter if already initialized.
|
|
574
|
-
# Creating Config({...}) doesn't store excluded_agents - use set() instead.
|
|
575
|
-
deploy_config = Config()
|
|
576
|
-
deploy_config.set(
|
|
577
|
-
"agent_deployment.excluded_agents", excluded_agents
|
|
578
|
-
)
|
|
579
|
-
deploy_config.set(
|
|
580
|
-
"agent_deployment.filter_non_mpm_agents", False
|
|
581
|
-
)
|
|
582
|
-
deploy_config.set("agent_deployment.case_sensitive", False)
|
|
583
|
-
deploy_config.set(
|
|
584
|
-
"agent_deployment.exclude_dependencies", False
|
|
585
|
-
)
|
|
586
|
-
logger.info(
|
|
587
|
-
f"Profile '{active_profile}': Excluding {len(excluded_agents)} agents from deployment"
|
|
588
|
-
)
|
|
589
|
-
|
|
590
|
-
deployment_service = AgentDeploymentService(config=deploy_config)
|
|
591
|
-
|
|
592
|
-
# Count agents in cache to show accurate progress
|
|
593
541
|
from pathlib import Path
|
|
594
542
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
# BUGFIX (cache-count-inflation): Clean up stale cache files
|
|
600
|
-
# from old repositories before counting to prevent inflated counts.
|
|
601
|
-
# Issue: Old caches like bobmatnyc/claude-mpm-agents/agents/
|
|
602
|
-
# were counted alongside current agents, inflating count
|
|
603
|
-
# from 44 to 85.
|
|
604
|
-
#
|
|
605
|
-
# Solution: Remove files with nested /agents/ paths
|
|
606
|
-
# (e.g., cache/agents/user/repo/agents/...)
|
|
607
|
-
# Keep only current agents (e.g., cache/agents/engineer/...)
|
|
608
|
-
removed_count = 0
|
|
609
|
-
stale_dirs = set()
|
|
610
|
-
|
|
611
|
-
for md_file in cache_dir.rglob("*.md"):
|
|
612
|
-
# Stale cache files have multiple /agents/ in their path RELATIVE to cache_dir
|
|
613
|
-
# Current: cache/agents/bobmatnyc/claude-mpm-agents/agents/engineer/...
|
|
614
|
-
# (1 occurrence in relative path: /agents/)
|
|
615
|
-
# Old flat: cache/agents/engineer/...
|
|
616
|
-
# (0 occurrences in relative path - no repo structure)
|
|
617
|
-
# The issue: str(md_file).count("/agents/") counts BOTH cache/agents/ AND repo/agents/
|
|
618
|
-
# Fix: Count /agents/ in path RELATIVE to cache_dir (after cache/agents/)
|
|
619
|
-
relative_path = str(md_file.relative_to(cache_dir))
|
|
620
|
-
if relative_path.count("/agents/") > 1:
|
|
621
|
-
# Track parent directory for cleanup
|
|
622
|
-
# Extract subdirectory under cache/agents/
|
|
623
|
-
# (e.g., "bobmatnyc")
|
|
624
|
-
parts = md_file.parts
|
|
625
|
-
cache_agents_idx = parts.index("agents")
|
|
626
|
-
if cache_agents_idx + 1 < len(parts):
|
|
627
|
-
stale_subdir = parts[cache_agents_idx + 1]
|
|
628
|
-
# Only remove if it's not a known category directory
|
|
629
|
-
if stale_subdir not in [
|
|
630
|
-
"engineer",
|
|
631
|
-
"ops",
|
|
632
|
-
"qa",
|
|
633
|
-
"universal",
|
|
634
|
-
"documentation",
|
|
635
|
-
"claude-mpm",
|
|
636
|
-
"security",
|
|
637
|
-
]:
|
|
638
|
-
stale_dirs.add(cache_dir / stale_subdir)
|
|
639
|
-
|
|
640
|
-
md_file.unlink()
|
|
641
|
-
removed_count += 1
|
|
642
|
-
|
|
643
|
-
# Remove empty stale directories
|
|
644
|
-
for stale_dir in stale_dirs:
|
|
645
|
-
if stale_dir.exists() and stale_dir.is_dir():
|
|
646
|
-
try:
|
|
647
|
-
# Remove directory and all contents
|
|
648
|
-
import shutil
|
|
649
|
-
|
|
650
|
-
shutil.rmtree(stale_dir)
|
|
651
|
-
except Exception:
|
|
652
|
-
pass # Ignore cleanup errors
|
|
653
|
-
|
|
654
|
-
if removed_count > 0:
|
|
655
|
-
from loguru import logger
|
|
656
|
-
|
|
657
|
-
logger.info(
|
|
658
|
-
f"Cleaned up {removed_count} stale cache files "
|
|
659
|
-
f"from old repositories"
|
|
660
|
-
)
|
|
543
|
+
from ..core.unified_config import UnifiedConfig
|
|
544
|
+
from ..services.agents.deployment.startup_reconciliation import (
|
|
545
|
+
perform_startup_reconciliation,
|
|
546
|
+
)
|
|
661
547
|
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
# (
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
"
|
|
675
|
-
"response_format.md",
|
|
676
|
-
"ticket_completeness_examples.md",
|
|
677
|
-
"validation_templates.md",
|
|
678
|
-
"git_file_tracking.md",
|
|
679
|
-
}
|
|
680
|
-
# Documentation files to exclude (by filename)
|
|
681
|
-
doc_files = {
|
|
682
|
-
"readme.md",
|
|
683
|
-
"changelog.md",
|
|
684
|
-
"contributing.md",
|
|
685
|
-
"implementation-summary.md",
|
|
686
|
-
"reorganization-plan.md",
|
|
687
|
-
"auto-deploy-index.md",
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
# Find all markdown files (after cleanup)
|
|
691
|
-
all_md_files = list(cache_dir.rglob("*.md"))
|
|
692
|
-
|
|
693
|
-
# Filter to only agent files:
|
|
694
|
-
# 1. Must have "/agents/" in path (current structure supports
|
|
695
|
-
# both flat and {owner}/{repo}/agents/ patterns)
|
|
696
|
-
# 2. Must not be in PM templates or doc files
|
|
697
|
-
# 3. Exclude BASE-AGENT.md which is not a deployable agent
|
|
698
|
-
# 4. Exclude build artifacts (dist/, build/, .cache/)
|
|
699
|
-
# to prevent double-counting
|
|
700
|
-
agent_files = [
|
|
701
|
-
f
|
|
702
|
-
for f in all_md_files
|
|
703
|
-
if (
|
|
704
|
-
# Must be in an agent directory
|
|
705
|
-
# Supports: cache/agents/{category}/... (flat)
|
|
706
|
-
# Supports: cache/agents/{owner}/{repo}/agents/{category}/... (GitHub sync)
|
|
707
|
-
"/agents/" in str(f)
|
|
708
|
-
# Exclude PM templates, doc files, and BASE-AGENT
|
|
709
|
-
and f.name.lower() not in pm_templates
|
|
710
|
-
and f.name.lower() not in doc_files
|
|
711
|
-
and f.name.lower() != "base-agent.md"
|
|
712
|
-
# Exclude build artifacts (prevents double-counting
|
|
713
|
-
# source + built files)
|
|
714
|
-
and not any(
|
|
715
|
-
part in str(f).split("/")
|
|
716
|
-
for part in ["dist", "build", ".cache"]
|
|
717
|
-
)
|
|
718
|
-
)
|
|
719
|
-
]
|
|
720
|
-
agent_count = len(agent_files)
|
|
721
|
-
|
|
722
|
-
if agent_count > 0:
|
|
723
|
-
# Deploy agents to project-level directory where Claude Code expects them
|
|
724
|
-
deploy_target = Path.cwd() / ".claude" / "agents"
|
|
725
|
-
deployment_result = deployment_service.deploy_agents(
|
|
726
|
-
target_dir=deploy_target,
|
|
727
|
-
force_rebuild=False, # Only deploy if versions differ
|
|
728
|
-
deployment_mode="update", # Version-aware updates
|
|
729
|
-
config=deploy_config, # Pass config to respect profile filtering
|
|
548
|
+
# Load configuration
|
|
549
|
+
unified_config = UnifiedConfig()
|
|
550
|
+
|
|
551
|
+
# Override with profile settings if active
|
|
552
|
+
if active_profile and profile_manager.active_profile:
|
|
553
|
+
# Get enabled agents from profile (returns Set[str])
|
|
554
|
+
profile_enabled_agents = (
|
|
555
|
+
profile_manager.active_profile.get_enabled_agents()
|
|
556
|
+
)
|
|
557
|
+
# Update config with profile's enabled list (convert Set to List)
|
|
558
|
+
unified_config.agents.enabled = list(profile_enabled_agents)
|
|
559
|
+
logger.info(
|
|
560
|
+
f"Profile '{active_profile}': Using {len(profile_enabled_agents)} enabled agents"
|
|
730
561
|
)
|
|
731
562
|
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
agent_count_in_target = len(
|
|
745
|
-
[
|
|
746
|
-
f
|
|
747
|
-
for f in existing_agents
|
|
748
|
-
if not f.name.startswith(("README", "INSTRUCTIONS"))
|
|
749
|
-
]
|
|
750
|
-
)
|
|
751
|
-
if agent_count_in_target > 0:
|
|
752
|
-
# All agents already deployed - count them as skipped
|
|
753
|
-
skipped = agent_count_in_target
|
|
754
|
-
total_configured = agent_count_in_target
|
|
563
|
+
# Perform reconciliation to deploy configured agents
|
|
564
|
+
project_path = Path.cwd()
|
|
565
|
+
agent_result, _skill_result = perform_startup_reconciliation(
|
|
566
|
+
project_path=project_path, config=unified_config, silent=False
|
|
567
|
+
)
|
|
568
|
+
|
|
569
|
+
# Display results with progress bar
|
|
570
|
+
total_operations = (
|
|
571
|
+
len(agent_result.deployed)
|
|
572
|
+
+ len(agent_result.removed)
|
|
573
|
+
+ len(agent_result.unchanged)
|
|
574
|
+
)
|
|
755
575
|
|
|
756
|
-
|
|
576
|
+
if total_operations > 0:
|
|
757
577
|
deploy_progress = ProgressBar(
|
|
758
|
-
total=
|
|
578
|
+
total=total_operations,
|
|
759
579
|
prefix="Deploying agents",
|
|
760
580
|
show_percentage=True,
|
|
761
581
|
show_counter=True,
|
|
762
582
|
)
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
583
|
+
deploy_progress.update(total_operations)
|
|
584
|
+
|
|
585
|
+
# Build summary message
|
|
586
|
+
deployed = len(agent_result.deployed)
|
|
587
|
+
removed = len(agent_result.removed)
|
|
588
|
+
unchanged = len(agent_result.unchanged)
|
|
589
|
+
|
|
590
|
+
summary_parts = []
|
|
591
|
+
if deployed > 0:
|
|
592
|
+
summary_parts.append(f"{deployed} new")
|
|
593
|
+
if removed > 0:
|
|
594
|
+
summary_parts.append(f"{removed} removed")
|
|
595
|
+
if unchanged > 0:
|
|
596
|
+
summary_parts.append(f"{unchanged} unchanged")
|
|
597
|
+
|
|
598
|
+
summary = f"Complete: {', '.join(summary_parts)}"
|
|
599
|
+
deploy_progress.finish(summary)
|
|
600
|
+
|
|
601
|
+
# Display errors if any
|
|
602
|
+
if agent_result.errors:
|
|
603
|
+
logger.warning(
|
|
604
|
+
f"Agent deployment completed with {len(agent_result.errors)} errors"
|
|
767
605
|
)
|
|
606
|
+
print("\n⚠️ Agent Deployment Errors:")
|
|
607
|
+
max_errors_to_show = 10
|
|
608
|
+
errors_to_display = agent_result.errors[:max_errors_to_show]
|
|
768
609
|
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
deployed_filenames = []
|
|
772
|
-
for agent_name in deployment_result.get("deployed", []):
|
|
773
|
-
deployed_filenames.append(f"{agent_name}.md")
|
|
774
|
-
for agent_name in deployment_result.get("updated", []):
|
|
775
|
-
deployed_filenames.append(f"{agent_name}.md")
|
|
776
|
-
for agent_name in deployment_result.get("skipped", []):
|
|
777
|
-
deployed_filenames.append(f"{agent_name}.md")
|
|
778
|
-
|
|
779
|
-
# Run cleanup and get count of removed agents
|
|
780
|
-
removed = _cleanup_orphaned_agents(
|
|
781
|
-
deploy_target, deployed_filenames
|
|
782
|
-
)
|
|
610
|
+
for error in errors_to_display:
|
|
611
|
+
print(f" - {error}")
|
|
783
612
|
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
if removed > 0:
|
|
788
|
-
deploy_progress.finish(
|
|
789
|
-
f"Complete: {deployed} new, {updated} updated, {skipped} unchanged, "
|
|
790
|
-
f"{removed} removed ({total_configured} configured from {agent_count} files in cache)"
|
|
791
|
-
)
|
|
792
|
-
else:
|
|
793
|
-
deploy_progress.finish(
|
|
794
|
-
f"Complete: {deployed} new, {updated} updated, {skipped} unchanged "
|
|
795
|
-
f"({total_configured} configured from {agent_count} files in cache)"
|
|
796
|
-
)
|
|
797
|
-
elif removed > 0:
|
|
798
|
-
deploy_progress.finish(
|
|
799
|
-
f"Complete: {total_configured} agents deployed, "
|
|
800
|
-
f"{removed} removed ({agent_count} files in cache)"
|
|
801
|
-
)
|
|
802
|
-
else:
|
|
803
|
-
deploy_progress.finish(
|
|
804
|
-
f"Complete: {total_configured} agents deployed "
|
|
805
|
-
f"({agent_count} files in cache)"
|
|
806
|
-
)
|
|
613
|
+
if len(agent_result.errors) > max_errors_to_show:
|
|
614
|
+
remaining = len(agent_result.errors) - max_errors_to_show
|
|
615
|
+
print(f" ... and {remaining} more error(s)")
|
|
807
616
|
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
f"Agent deployment completed with {len(deploy_errors)} errors: {deploy_errors}"
|
|
814
|
-
)
|
|
815
|
-
|
|
816
|
-
# Display errors to user with clear formatting
|
|
817
|
-
print("\n⚠️ Agent Deployment Errors:")
|
|
818
|
-
|
|
819
|
-
# Show first 10 errors to avoid overwhelming output
|
|
820
|
-
max_errors_to_show = 10
|
|
821
|
-
errors_to_display = deploy_errors[:max_errors_to_show]
|
|
822
|
-
|
|
823
|
-
for error in errors_to_display:
|
|
824
|
-
# Format error message for readability
|
|
825
|
-
# Errors typically come as strings like "agent.md: Error message"
|
|
826
|
-
print(f" - {error}")
|
|
827
|
-
|
|
828
|
-
# If more errors exist, show count
|
|
829
|
-
if len(deploy_errors) > max_errors_to_show:
|
|
830
|
-
remaining = len(deploy_errors) - max_errors_to_show
|
|
831
|
-
print(f" ... and {remaining} more error(s)")
|
|
832
|
-
|
|
833
|
-
# Show summary message
|
|
834
|
-
print(
|
|
835
|
-
f"\n❌ Failed to deploy {len(deploy_errors)} agent(s). Please check the error messages above."
|
|
836
|
-
)
|
|
837
|
-
print(" Run with --verbose for detailed error information.\n")
|
|
617
|
+
print(
|
|
618
|
+
f"\n❌ Failed to deploy {len(agent_result.errors)} agent(s). "
|
|
619
|
+
"Please check the error messages above."
|
|
620
|
+
)
|
|
621
|
+
print(" Run with --verbose for detailed error information.\n")
|
|
838
622
|
|
|
839
623
|
except Exception as e:
|
|
840
624
|
# Deployment failure shouldn't block startup
|
|
@@ -859,7 +643,7 @@ def sync_remote_agents_on_startup(force_sync: bool = False):
|
|
|
859
643
|
# Cleanup legacy cache even if sync failed
|
|
860
644
|
try:
|
|
861
645
|
cleanup_legacy_agent_cache()
|
|
862
|
-
except Exception:
|
|
646
|
+
except Exception: # nosec B110
|
|
863
647
|
pass # Ignore cleanup errors
|
|
864
648
|
|
|
865
649
|
|
|
@@ -1424,7 +1208,7 @@ def auto_install_chrome_devtools_on_startup():
|
|
|
1424
1208
|
if not chrome_devtools_config.get("auto_install", True):
|
|
1425
1209
|
# Auto-install disabled, skip silently
|
|
1426
1210
|
return
|
|
1427
|
-
except Exception:
|
|
1211
|
+
except Exception: # nosec B110
|
|
1428
1212
|
# If config loading fails, assume auto-install is enabled (default)
|
|
1429
1213
|
pass
|
|
1430
1214
|
|
|
@@ -1679,7 +1463,7 @@ def verify_mcp_gateway_startup():
|
|
|
1679
1463
|
loop.run_until_complete(
|
|
1680
1464
|
asyncio.gather(*pending, return_exceptions=True)
|
|
1681
1465
|
)
|
|
1682
|
-
except Exception:
|
|
1466
|
+
except Exception: # nosec B110
|
|
1683
1467
|
pass # Ignore cleanup errors
|
|
1684
1468
|
finally:
|
|
1685
1469
|
loop.close()
|
|
@@ -1773,7 +1557,7 @@ def check_for_updates_async():
|
|
|
1773
1557
|
|
|
1774
1558
|
logger = get_logger("upgrade_check")
|
|
1775
1559
|
logger.debug(f"Update check failed (non-critical): {e}")
|
|
1776
|
-
except Exception:
|
|
1560
|
+
except Exception: # nosec B110
|
|
1777
1561
|
pass # Avoid any errors in error handling
|
|
1778
1562
|
finally:
|
|
1779
1563
|
# Properly clean up event loop
|
|
@@ -1788,7 +1572,7 @@ def check_for_updates_async():
|
|
|
1788
1572
|
loop.run_until_complete(
|
|
1789
1573
|
asyncio.gather(*pending, return_exceptions=True)
|
|
1790
1574
|
)
|
|
1791
|
-
except Exception:
|
|
1575
|
+
except Exception: # nosec B110
|
|
1792
1576
|
pass # Ignore cleanup errors
|
|
1793
1577
|
finally:
|
|
1794
1578
|
loop.close()
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pm-bug-reporting
|
|
3
|
+
version: "1.0.0"
|
|
4
|
+
description: Bug reporting protocol for PM and agents to file GitHub issues
|
|
5
|
+
when_to_use: Framework bugs, agent errors, skill content errors detected
|
|
6
|
+
category: pm-workflow
|
|
7
|
+
tags: [bug-reporting, github, issues, pm-required]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# PM Bug Reporting Protocol
|
|
11
|
+
|
|
12
|
+
## When to Report Bugs
|
|
13
|
+
|
|
14
|
+
Report bugs when you encounter:
|
|
15
|
+
- **PM instruction errors** or missing guidance
|
|
16
|
+
- **Agent malfunction** or incorrect behavior
|
|
17
|
+
- **Skill content errors** or outdated information
|
|
18
|
+
- **Framework crashes** or unexpected behavior
|
|
19
|
+
- **Missing or incorrect documentation**
|
|
20
|
+
- **Configuration errors** or invalid defaults
|
|
21
|
+
|
|
22
|
+
## GitHub Repositories
|
|
23
|
+
|
|
24
|
+
Route bugs to the correct repository:
|
|
25
|
+
|
|
26
|
+
| Bug Type | Repository | Owner/Repo |
|
|
27
|
+
|----------|------------|------------|
|
|
28
|
+
| Core MPM (CLI, startup, config, orchestration) | claude-mpm | bobmatnyc/claude-mpm |
|
|
29
|
+
| Agent bugs (wrong behavior, errors, missing capabilities) | claude-mpm-agents | bobmatnyc/claude-mpm-agents |
|
|
30
|
+
| Skill bugs (wrong info, outdated, missing content) | claude-mpm-skills | bobmatnyc/claude-mpm-skills |
|
|
31
|
+
|
|
32
|
+
## Bug Report Template
|
|
33
|
+
|
|
34
|
+
When creating an issue, include:
|
|
35
|
+
|
|
36
|
+
### Title
|
|
37
|
+
Brief, descriptive title (50 chars max)
|
|
38
|
+
- ✅ "PM delegates to non-existent agent"
|
|
39
|
+
- ✅ "Research skill missing web search examples"
|
|
40
|
+
- ❌ "Bug in system"
|
|
41
|
+
- ❌ "Fix this"
|
|
42
|
+
|
|
43
|
+
### Labels
|
|
44
|
+
Always include:
|
|
45
|
+
- `bug` (required)
|
|
46
|
+
- `agent-reported` (required)
|
|
47
|
+
- Additional context labels:
|
|
48
|
+
- `high-priority` - Critical functionality broken
|
|
49
|
+
- `documentation` - Documentation error
|
|
50
|
+
- `agent-error` - Agent-specific issue
|
|
51
|
+
- `skill-error` - Skill content issue
|
|
52
|
+
|
|
53
|
+
### Body Structure
|
|
54
|
+
```markdown
|
|
55
|
+
## What Happened
|
|
56
|
+
[Clear description of the bug]
|
|
57
|
+
|
|
58
|
+
## Expected Behavior
|
|
59
|
+
[What should have happened]
|
|
60
|
+
|
|
61
|
+
## Steps to Reproduce
|
|
62
|
+
1. [First step]
|
|
63
|
+
2. [Second step]
|
|
64
|
+
3. [Third step]
|
|
65
|
+
|
|
66
|
+
## Context
|
|
67
|
+
- Agent: [agent name if applicable]
|
|
68
|
+
- Skill: [skill name if applicable]
|
|
69
|
+
- Error Message: [full error if available]
|
|
70
|
+
- Version: [MPM version if known]
|
|
71
|
+
|
|
72
|
+
## Impact
|
|
73
|
+
[How this affects users/workflow]
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Using gh CLI
|
|
77
|
+
|
|
78
|
+
### Prerequisites Check
|
|
79
|
+
```bash
|
|
80
|
+
gh auth status
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
If not authenticated:
|
|
84
|
+
```bash
|
|
85
|
+
gh auth login
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Creating Issues
|
|
89
|
+
|
|
90
|
+
**Delegate to ticketing agent** with:
|
|
91
|
+
```
|
|
92
|
+
Task:
|
|
93
|
+
agent: ticketing
|
|
94
|
+
task: Create GitHub issue for [bug type]
|
|
95
|
+
context: |
|
|
96
|
+
Repository: bobmatnyc/claude-mpm[-agents|-skills]
|
|
97
|
+
Title: [brief title]
|
|
98
|
+
Labels: bug, agent-reported
|
|
99
|
+
Body: |
|
|
100
|
+
## What Happened
|
|
101
|
+
[description]
|
|
102
|
+
|
|
103
|
+
## Expected Behavior
|
|
104
|
+
[expected]
|
|
105
|
+
|
|
106
|
+
## Steps to Reproduce
|
|
107
|
+
1. [step 1]
|
|
108
|
+
2. [step 2]
|
|
109
|
+
|
|
110
|
+
## Context
|
|
111
|
+
- Agent: [agent name]
|
|
112
|
+
- Error: [error message]
|
|
113
|
+
|
|
114
|
+
## Impact
|
|
115
|
+
[impact description]
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Examples
|
|
119
|
+
|
|
120
|
+
### Core MPM Bug
|
|
121
|
+
```
|
|
122
|
+
Task:
|
|
123
|
+
agent: ticketing
|
|
124
|
+
task: Create GitHub issue for core MPM bug
|
|
125
|
+
context: |
|
|
126
|
+
Repository: bobmatnyc/claude-mpm
|
|
127
|
+
Title: PM fails to load configuration on startup
|
|
128
|
+
Labels: bug, agent-reported, high-priority
|
|
129
|
+
Body: |
|
|
130
|
+
## What Happened
|
|
131
|
+
PM fails to initialize when configuration.yaml contains invalid syntax.
|
|
132
|
+
No clear error message shown to user.
|
|
133
|
+
|
|
134
|
+
## Expected Behavior
|
|
135
|
+
PM should display clear YAML syntax error with line number and fix suggestion.
|
|
136
|
+
|
|
137
|
+
## Steps to Reproduce
|
|
138
|
+
1. Add invalid YAML to .claude-mpm/configuration.yaml
|
|
139
|
+
2. Run `mpm`
|
|
140
|
+
3. Observe generic error without details
|
|
141
|
+
|
|
142
|
+
## Context
|
|
143
|
+
- Component: Configuration loader
|
|
144
|
+
- Error: "Failed to load configuration"
|
|
145
|
+
- Version: 5.4.x
|
|
146
|
+
|
|
147
|
+
## Impact
|
|
148
|
+
Users cannot diagnose configuration errors, requiring manual YAML validation.
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Agent Bug
|
|
152
|
+
```
|
|
153
|
+
Task:
|
|
154
|
+
agent: ticketing
|
|
155
|
+
task: Create GitHub issue for agent bug
|
|
156
|
+
context: |
|
|
157
|
+
Repository: bobmatnyc/claude-mpm-agents
|
|
158
|
+
Title: Research agent fails to search with special characters
|
|
159
|
+
Labels: bug, agent-reported, agent-error
|
|
160
|
+
Body: |
|
|
161
|
+
## What Happened
|
|
162
|
+
Research agent throws error when search query contains quotes or special chars.
|
|
163
|
+
|
|
164
|
+
## Expected Behavior
|
|
165
|
+
Search queries should be properly escaped and executed.
|
|
166
|
+
|
|
167
|
+
## Steps to Reproduce
|
|
168
|
+
1. Delegate to research: "Search for 'React hooks'"
|
|
169
|
+
2. Research agent attempts search
|
|
170
|
+
3. Error: "Invalid search query"
|
|
171
|
+
|
|
172
|
+
## Context
|
|
173
|
+
- Agent: research
|
|
174
|
+
- Error: grep command fails with unescaped quotes
|
|
175
|
+
|
|
176
|
+
## Impact
|
|
177
|
+
Cannot search for quoted phrases or technical terms with special characters.
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Skill Bug
|
|
181
|
+
```
|
|
182
|
+
Task:
|
|
183
|
+
agent: ticketing
|
|
184
|
+
task: Create GitHub issue for skill content error
|
|
185
|
+
context: |
|
|
186
|
+
Repository: bobmatnyc/claude-mpm-skills
|
|
187
|
+
Title: Git workflow skill contains outdated branch strategy
|
|
188
|
+
Labels: bug, agent-reported, documentation, skill-error
|
|
189
|
+
Body: |
|
|
190
|
+
## What Happened
|
|
191
|
+
Skill recommends `git flow` branching model, which project no longer uses.
|
|
192
|
+
Current standard is trunk-based development.
|
|
193
|
+
|
|
194
|
+
## Expected Behavior
|
|
195
|
+
Skill should document current trunk-based workflow.
|
|
196
|
+
|
|
197
|
+
## Context
|
|
198
|
+
- Skill: git-workflow.md
|
|
199
|
+
- Section: "Branching Strategy"
|
|
200
|
+
- Line: 45-60
|
|
201
|
+
|
|
202
|
+
## Impact
|
|
203
|
+
Agents follow outdated branching model, creating workflow friction.
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Escalation Path
|
|
207
|
+
|
|
208
|
+
When ticketing agent is unavailable or gh CLI fails:
|
|
209
|
+
|
|
210
|
+
1. **Log locally** for manual reporting:
|
|
211
|
+
```
|
|
212
|
+
echo "[BUG] $(date): [description]" >> .claude-mpm/logs/bugs.log
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
2. **Report to PM** for alternative action:
|
|
216
|
+
```
|
|
217
|
+
PM should create ticket in primary ticketing system (Linear/JIRA)
|
|
218
|
+
with note to create GitHub issue once available
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
3. **User notification**:
|
|
222
|
+
```
|
|
223
|
+
"Bug detected: [description]. Logged for manual GitHub issue creation."
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Success Criteria
|
|
227
|
+
|
|
228
|
+
Bug reporting successful when:
|
|
229
|
+
- ✅ Issue created in correct repository
|
|
230
|
+
- ✅ All required labels applied (`bug`, `agent-reported`)
|
|
231
|
+
- ✅ Body follows template structure
|
|
232
|
+
- ✅ Title is clear and concise
|
|
233
|
+
- ✅ Context includes agent/skill name if applicable
|
|
234
|
+
- ✅ Issue URL returned for tracking
|
|
235
|
+
|
|
236
|
+
## PM Enforcement
|
|
237
|
+
|
|
238
|
+
PM MUST:
|
|
239
|
+
- Detect bugs during agent interactions
|
|
240
|
+
- Delegate bug reporting to ticketing agent
|
|
241
|
+
- NOT attempt to create GitHub issues directly
|
|
242
|
+
- Follow escalation path if ticketing unavailable
|
|
243
|
+
- Log all bug reports for audit trail
|
|
244
|
+
|
|
245
|
+
## Related Skills
|
|
246
|
+
- [pm-ticketing-integration.md](pm-ticketing-integration.md) - Ticket delegation patterns
|
|
247
|
+
- [pm-delegation-patterns.md](pm-delegation-patterns.md) - General delegation guidance
|
|
248
|
+
- [ticketing-examples.md](ticketing-examples.md) - Ticketing delegation examples
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
claude_mpm/BUILD_NUMBER,sha256=9JfxhnDtr-8l3kCP2U5TVXSErptHoga8m7XA8zqgGOc,4
|
|
2
|
-
claude_mpm/VERSION,sha256=
|
|
2
|
+
claude_mpm/VERSION,sha256=SmSriwpxtB_4oESyhcAIR_2w8REB_ngYMY4CG3rVHGM,7
|
|
3
3
|
claude_mpm/__init__.py,sha256=AGfh00BHKvLYD-UVFw7qbKtl7NMRIzRXOWw7vEuZ-h4,2214
|
|
4
4
|
claude_mpm/__main__.py,sha256=Ro5UBWBoQaSAIoSqWAr7zkbLyvi4sSy28WShqAhKJG0,723
|
|
5
5
|
claude_mpm/constants.py,sha256=pz3lTrZZR5HhV3eZzYtIbtBwWo7iM6pkBHP_ixxmI6Y,6827
|
|
@@ -41,7 +41,7 @@ claude_mpm/cli/chrome_devtools_installer.py,sha256=efA_ZX1iR3oaJi3222079BQw6DEG8
|
|
|
41
41
|
claude_mpm/cli/executor.py,sha256=1MQdNPNoIewSR1q8nXjJuES3zKEi_IqVcZQzt9bsxw8,10601
|
|
42
42
|
claude_mpm/cli/helpers.py,sha256=CypEhw0tbNH6_GzVTaQdi4w7ThCWO43Ep92YbJzPR4I,3638
|
|
43
43
|
claude_mpm/cli/parser.py,sha256=Vqx9n-6Xo1uNhXR4rThmgWpZXTr0nOtkgDf3oMS9b0g,5855
|
|
44
|
-
claude_mpm/cli/startup.py,sha256=
|
|
44
|
+
claude_mpm/cli/startup.py,sha256=A1w9YWPgP0cA8d_T8ymbAbGpP7UARkRvtRcKEbXNy24,62095
|
|
45
45
|
claude_mpm/cli/startup_display.py,sha256=R_QIamjfdaY5o_VxpIeymyYj1Qde2B9hPXy1P-KmUKI,14972
|
|
46
46
|
claude_mpm/cli/startup_logging.py,sha256=RTuyd6CbhiFQz7Z07LDDhK_ZAnZfuJ9B0NghVSntHFI,29390
|
|
47
47
|
claude_mpm/cli/utils.py,sha256=FSMPftBZM8MeUyTtiB63Lz7oFOgkzwTetQs58RbRb_Q,8785
|
|
@@ -216,7 +216,7 @@ claude_mpm/core/tool_access_control.py,sha256=dpdxxp_77SuxGM2C7SsHUZbtysJmHw1rLD
|
|
|
216
216
|
claude_mpm/core/types.py,sha256=Sv62QhMYvfxbt7oIGoAhhN_jxonFTeLRf-BuhxZ4vYw,7719
|
|
217
217
|
claude_mpm/core/typing_utils.py,sha256=qny3rA9mAeXqdLgUj9DZg642shw4LmLbkPqADN-765s,13314
|
|
218
218
|
claude_mpm/core/unified_agent_registry.py,sha256=YbL-oWeHU85zdf1mF7tyMHBYKtFBupsMeH9BCdzD6ZI,34161
|
|
219
|
-
claude_mpm/core/unified_config.py,sha256=
|
|
219
|
+
claude_mpm/core/unified_config.py,sha256=WWuNWGLK0ySWQ_drR-FVb_FeL8c9HhTU_Ch3hGsPCAo,21768
|
|
220
220
|
claude_mpm/core/unified_paths.py,sha256=F2NYAK6RNtn_xsZnVHVfP7MErzDh_O9hyaa3B4OyT9A,36690
|
|
221
221
|
claude_mpm/core/framework/__init__.py,sha256=IJCp6-MQO8gW31uG8aMWHdNg54NgGvXb4GvOuwZF6Iw,736
|
|
222
222
|
claude_mpm/core/framework/formatters/__init__.py,sha256=OKkLN2x21rcbg3d3feZLixIS-UjHPlxl768uGmQy7Qc,307
|
|
@@ -863,6 +863,7 @@ claude_mpm/skills/bundled/php/espocrm-development/references/development-workflo
|
|
|
863
863
|
claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md,sha256=0h1VohuIr-El_Rj9wWWPluRynQqi2B8i0-xTaPdkGBY,17519
|
|
864
864
|
claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md,sha256=2KwnVcf5s1TCAo1GMdbLitJMVbi7cdYfDK_M5C4oBtI,20820
|
|
865
865
|
claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md,sha256=9TVZk_ZTez65kzx2R8nG-8fn9V_pIT5oTLsFQdPk2zQ,18250
|
|
866
|
+
claude_mpm/skills/bundled/pm/pm-bug-reporting/pm-bug-reporting.md,sha256=mDjGQd9ALSZ0jsuWyXSVT6_GxTudzAVTkasqwnf4zJE,6494
|
|
866
867
|
claude_mpm/skills/bundled/pm/pm-delegation-patterns/SKILL.md,sha256=kdFyy5T_70vw5XpGexlXr18VdQWIFD59A8pLmmcWiVA,5388
|
|
867
868
|
claude_mpm/skills/bundled/pm/pm-git-file-tracking/SKILL.md,sha256=bnmO9Wzoe0AYJ72yKBO_FqtxsfjIkYhUHlosPRrYgTM,3607
|
|
868
869
|
claude_mpm/skills/bundled/pm/pm-pr-workflow/SKILL.md,sha256=HSeVxw_znHqiPA95gpHnPKavNkSgSLTKuVaHqV976Ao,3369
|
|
@@ -969,10 +970,10 @@ claude_mpm/utils/subprocess_utils.py,sha256=D0izRT8anjiUb_JG72zlJR_JAw1cDkb7kalN
|
|
|
969
970
|
claude_mpm/validation/__init__.py,sha256=YZhwE3mhit-lslvRLuwfX82xJ_k4haZeKmh4IWaVwtk,156
|
|
970
971
|
claude_mpm/validation/agent_validator.py,sha256=GprtAvu80VyMXcKGsK_VhYiXWA6BjKHv7O6HKx0AB9w,20917
|
|
971
972
|
claude_mpm/validation/frontmatter_validator.py,sha256=YpJlYNNYcV8u6hIOi3_jaRsDnzhbcQpjCBE6eyBKaFY,7076
|
|
972
|
-
claude_mpm-5.4.
|
|
973
|
-
claude_mpm-5.4.
|
|
974
|
-
claude_mpm-5.4.
|
|
975
|
-
claude_mpm-5.4.
|
|
976
|
-
claude_mpm-5.4.
|
|
977
|
-
claude_mpm-5.4.
|
|
978
|
-
claude_mpm-5.4.
|
|
973
|
+
claude_mpm-5.4.83.dist-info/licenses/LICENSE,sha256=ca3y_Rk4aPrbF6f62z8Ht5MJM9OAvbGlHvEDcj9vUQ4,3867
|
|
974
|
+
claude_mpm-5.4.83.dist-info/licenses/LICENSE-FAQ.md,sha256=TxfEkXVCK98RzDOer09puc7JVCP_q_bN4dHtZKHCMcM,5104
|
|
975
|
+
claude_mpm-5.4.83.dist-info/METADATA,sha256=L9tyI9gHshp4mzDHla_5Yx1JLMkZUDPMMb1Gezu4Gd0,38503
|
|
976
|
+
claude_mpm-5.4.83.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
977
|
+
claude_mpm-5.4.83.dist-info/entry_points.txt,sha256=n-Uk4vwHPpuvu-g_I7-GHORzTnN_m6iyOsoLveKKD0E,228
|
|
978
|
+
claude_mpm-5.4.83.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
|
|
979
|
+
claude_mpm-5.4.83.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|