claude-mpm 4.2.43__py3-none-any.whl → 4.2.51__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_PM.md +117 -12
  3. claude_mpm/agents/INSTRUCTIONS.md +154 -10
  4. claude_mpm/agents/WORKFLOW.md +46 -1
  5. claude_mpm/agents/frontmatter_validator.py +20 -12
  6. claude_mpm/agents/templates/nextjs_engineer.json +277 -0
  7. claude_mpm/agents/templates/python_engineer.json +289 -0
  8. claude_mpm/agents/templates/react_engineer.json +11 -3
  9. claude_mpm/agents/templates/security.json +50 -9
  10. claude_mpm/cli/commands/agents.py +2 -2
  11. claude_mpm/cli/commands/uninstall.py +1 -2
  12. claude_mpm/cli/interactive/agent_wizard.py +3 -3
  13. claude_mpm/cli/parsers/agent_manager_parser.py +3 -3
  14. claude_mpm/cli/parsers/agents_parser.py +1 -1
  15. claude_mpm/constants.py +1 -1
  16. claude_mpm/core/api_validator.py +330 -0
  17. claude_mpm/core/error_handler.py +2 -4
  18. claude_mpm/core/file_utils.py +4 -12
  19. claude_mpm/core/framework_loader.py +22 -0
  20. claude_mpm/core/log_manager.py +8 -5
  21. claude_mpm/core/logger.py +1 -1
  22. claude_mpm/core/logging_utils.py +6 -6
  23. claude_mpm/core/unified_agent_registry.py +18 -4
  24. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +188 -0
  25. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +156 -0
  26. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +38 -0
  27. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +92 -0
  28. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +248 -0
  29. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +61 -0
  30. claude_mpm/dashboard/static/archive/test_activity_connection.html +179 -0
  31. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +68 -0
  32. claude_mpm/dashboard/static/archive/test_dashboard.html +409 -0
  33. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +519 -0
  34. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +181 -0
  35. claude_mpm/dashboard/static/archive/test_file_data.html +315 -0
  36. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +243 -0
  37. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +234 -0
  38. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +117 -0
  39. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +115 -0
  40. claude_mpm/dashboard/static/archive/test_file_viewer.html +224 -0
  41. claude_mpm/dashboard/static/archive/test_final_activity.html +220 -0
  42. claude_mpm/dashboard/static/archive/test_tab_fix.html +139 -0
  43. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +1 -0
  44. claude_mpm/dashboard/static/built/components/activity-tree.js +1 -1
  45. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +777 -0
  46. claude_mpm/dashboard/static/built/components/agent-inference.js +1 -1
  47. claude_mpm/dashboard/static/built/components/build-tracker.js +333 -0
  48. claude_mpm/dashboard/static/built/components/code-simple.js +857 -0
  49. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +353 -0
  50. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +235 -0
  51. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +409 -0
  52. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +435 -0
  53. claude_mpm/dashboard/static/built/components/code-viewer.js +2 -1076
  54. claude_mpm/dashboard/static/built/components/connection-debug.js +654 -0
  55. claude_mpm/dashboard/static/built/components/diff-viewer.js +891 -0
  56. claude_mpm/dashboard/static/built/components/event-processor.js +1 -1
  57. claude_mpm/dashboard/static/built/components/event-viewer.js +1 -1
  58. claude_mpm/dashboard/static/built/components/export-manager.js +1 -1
  59. claude_mpm/dashboard/static/built/components/file-change-tracker.js +443 -0
  60. claude_mpm/dashboard/static/built/components/file-change-viewer.js +690 -0
  61. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +1 -1
  62. claude_mpm/dashboard/static/built/components/module-viewer.js +1 -1
  63. claude_mpm/dashboard/static/built/components/nav-bar.js +145 -0
  64. claude_mpm/dashboard/static/built/components/page-structure.js +429 -0
  65. claude_mpm/dashboard/static/built/components/session-manager.js +1 -1
  66. claude_mpm/dashboard/static/built/components/ui-state-manager.js +2 -465
  67. claude_mpm/dashboard/static/built/components/working-directory.js +1 -1
  68. claude_mpm/dashboard/static/built/connection-manager.js +536 -0
  69. claude_mpm/dashboard/static/built/dashboard.js +1 -1
  70. claude_mpm/dashboard/static/built/extension-error-handler.js +164 -0
  71. claude_mpm/dashboard/static/built/react/events.js +30 -0
  72. claude_mpm/dashboard/static/built/shared/dom-helpers.js +396 -0
  73. claude_mpm/dashboard/static/built/shared/event-bus.js +330 -0
  74. claude_mpm/dashboard/static/built/shared/event-filter-service.js +540 -0
  75. claude_mpm/dashboard/static/built/shared/logger.js +385 -0
  76. claude_mpm/dashboard/static/built/shared/page-structure.js +251 -0
  77. claude_mpm/dashboard/static/built/shared/tooltip-service.js +253 -0
  78. claude_mpm/dashboard/static/built/socket-client.js +1 -1
  79. claude_mpm/dashboard/static/built/tab-isolation-fix.js +185 -0
  80. claude_mpm/dashboard/static/css/dashboard.css +28 -5
  81. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +1 -0
  82. claude_mpm/dashboard/static/dist/components/activity-tree.js +1 -1
  83. claude_mpm/dashboard/static/dist/components/agent-inference.js +1 -1
  84. claude_mpm/dashboard/static/dist/components/code-viewer.js +2 -0
  85. claude_mpm/dashboard/static/dist/components/event-processor.js +1 -1
  86. claude_mpm/dashboard/static/dist/components/event-viewer.js +1 -1
  87. claude_mpm/dashboard/static/dist/components/export-manager.js +1 -1
  88. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +1 -1
  89. claude_mpm/dashboard/static/dist/components/module-viewer.js +1 -1
  90. claude_mpm/dashboard/static/dist/components/session-manager.js +1 -1
  91. claude_mpm/dashboard/static/dist/components/working-directory.js +1 -1
  92. claude_mpm/dashboard/static/dist/dashboard.js +1 -1
  93. claude_mpm/dashboard/static/dist/react/events.js +30 -0
  94. claude_mpm/dashboard/static/dist/socket-client.js +1 -1
  95. claude_mpm/dashboard/static/events.html +607 -0
  96. claude_mpm/dashboard/static/index.html +713 -0
  97. claude_mpm/dashboard/static/js/components/activity-tree.js +3 -17
  98. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +4 -1
  99. claude_mpm/dashboard/static/js/components/agent-inference.js +3 -0
  100. claude_mpm/dashboard/static/js/components/build-tracker.js +8 -0
  101. claude_mpm/dashboard/static/js/components/code-viewer.js +387 -72
  102. claude_mpm/dashboard/static/js/components/event-processor.js +3 -0
  103. claude_mpm/dashboard/static/js/components/event-viewer.js +39 -2
  104. claude_mpm/dashboard/static/js/components/export-manager.js +3 -0
  105. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +30 -10
  106. claude_mpm/dashboard/static/js/components/socket-manager.js +4 -0
  107. claude_mpm/dashboard/static/js/components/ui-state-manager.js +286 -108
  108. claude_mpm/dashboard/static/js/components/working-directory.js +3 -0
  109. claude_mpm/dashboard/static/js/dashboard.js +61 -49
  110. claude_mpm/dashboard/static/js/socket-client.js +12 -8
  111. claude_mpm/dashboard/static/js/stores/dashboard-store.js +562 -0
  112. claude_mpm/dashboard/static/js/tab-isolation-fix.js +185 -0
  113. claude_mpm/dashboard/static/legacy/activity.html +736 -0
  114. claude_mpm/dashboard/static/legacy/agents.html +786 -0
  115. claude_mpm/dashboard/static/legacy/files.html +747 -0
  116. claude_mpm/dashboard/static/legacy/tools.html +831 -0
  117. claude_mpm/dashboard/static/monitors-index.html +218 -0
  118. claude_mpm/dashboard/static/monitors.html +431 -0
  119. claude_mpm/dashboard/static/production/events.html +659 -0
  120. claude_mpm/dashboard/static/production/main.html +715 -0
  121. claude_mpm/dashboard/static/production/monitors.html +483 -0
  122. claude_mpm/dashboard/static/socket.io.min.js +7 -0
  123. claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +7 -0
  124. claude_mpm/dashboard/static/test-archive/dashboard.html +635 -0
  125. claude_mpm/dashboard/static/test-archive/debug-events.html +147 -0
  126. claude_mpm/dashboard/static/test-archive/test-navigation.html +256 -0
  127. claude_mpm/dashboard/static/test-archive/test-react-exports.html +180 -0
  128. claude_mpm/dashboard/templates/index.html +82 -38
  129. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +1 -1
  130. claude_mpm/services/agents/deployment/agent_discovery_service.py +3 -0
  131. claude_mpm/services/agents/deployment/agent_template_builder.py +25 -8
  132. claude_mpm/services/agents/deployment/agent_validator.py +3 -0
  133. claude_mpm/services/agents/deployment/validation/template_validator.py +13 -4
  134. claude_mpm/services/agents/local_template_manager.py +2 -6
  135. claude_mpm/services/monitor/daemon.py +1 -2
  136. claude_mpm/services/monitor/daemon_manager.py +2 -5
  137. claude_mpm/services/monitor/event_emitter.py +2 -2
  138. claude_mpm/services/monitor/handlers/code_analysis.py +4 -6
  139. claude_mpm/services/monitor/handlers/hooks.py +2 -4
  140. claude_mpm/services/monitor/server.py +23 -226
  141. claude_mpm/tools/code_tree_analyzer.py +2 -2
  142. {claude_mpm-4.2.43.dist-info → claude_mpm-4.2.51.dist-info}/METADATA +1 -1
  143. {claude_mpm-4.2.43.dist-info → claude_mpm-4.2.51.dist-info}/RECORD +148 -87
  144. claude_mpm/commands/mpm-browser-monitor.md +0 -370
  145. claude_mpm/commands/mpm-monitor.md +0 -177
  146. claude_mpm/dashboard/static/js/browser-console-monitor.js +0 -495
  147. claude_mpm/dashboard/static/js/components/browser-log-viewer.js +0 -763
  148. claude_mpm/dashboard/static/test-browser-monitor.html +0 -470
  149. claude_mpm/dashboard/static/test-simple.html +0 -97
  150. claude_mpm/services/monitor/handlers/browser.py +0 -451
  151. /claude_mpm/dashboard/static/{test_debug.html → test-archive/test_debug.html} +0 -0
  152. {claude_mpm-4.2.43.dist-info → claude_mpm-4.2.51.dist-info}/WHEEL +0 -0
  153. {claude_mpm-4.2.43.dist-info → claude_mpm-4.2.51.dist-info}/entry_points.txt +0 -0
  154. {claude_mpm-4.2.43.dist-info → claude_mpm-4.2.51.dist-info}/licenses/LICENSE +0 -0
  155. {claude_mpm-4.2.43.dist-info → claude_mpm-4.2.51.dist-info}/top_level.txt +0 -0
@@ -15,6 +15,7 @@ DESIGN DECISIONS:
15
15
  """
16
16
 
17
17
  import asyncio
18
+ import contextlib
18
19
  import os
19
20
  import threading
20
21
  import time
@@ -28,7 +29,6 @@ from aiohttp import web
28
29
  from ...core.logging_config import get_logger
29
30
  from ...dashboard.api.simple_directory import list_directory
30
31
  from .event_emitter import get_event_emitter
31
- from .handlers.browser import BrowserHandler
32
32
  from .handlers.code_analysis import CodeAnalysisHandler
33
33
  from .handlers.dashboard import DashboardHandler
34
34
  from .handlers.file import FileHandler
@@ -69,7 +69,6 @@ class UnifiedMonitorServer:
69
69
  self.site = None
70
70
 
71
71
  # Event handlers
72
- self.browser_handler = None
73
72
  self.code_analysis_handler = None
74
73
  self.dashboard_handler = None
75
74
  self.file_handler = None
@@ -272,14 +271,12 @@ class UnifiedMonitorServer:
272
271
  """Setup Socket.IO event handlers."""
273
272
  try:
274
273
  # Create event handlers
275
- self.browser_handler = BrowserHandler(self.sio)
276
274
  self.code_analysis_handler = CodeAnalysisHandler(self.sio)
277
275
  self.dashboard_handler = DashboardHandler(self.sio)
278
276
  self.file_handler = FileHandler(self.sio)
279
277
  self.hook_handler = HookHandler(self.sio)
280
278
 
281
279
  # Register handlers
282
- self.browser_handler.register()
283
280
  self.code_analysis_handler.register()
284
281
  self.dashboard_handler.register()
285
282
  self.file_handler.register()
@@ -352,7 +349,7 @@ class UnifiedMonitorServer:
352
349
  data = await request.json()
353
350
 
354
351
  # Extract event data
355
- namespace = data.get("namespace", "hook")
352
+ data.get("namespace", "hook")
356
353
  event = data.get("event", "claude_event")
357
354
  event_data = data.get("data", {})
358
355
 
@@ -512,218 +509,18 @@ class UnifiedMonitorServer:
512
509
  {"working_directory": os.getcwd(), "success": True}
513
510
  )
514
511
 
515
- # Browser monitor script endpoint
516
- async def browser_monitor_script_handler(request):
517
- """Serve the browser console monitoring script with dynamic port injection."""
518
- try:
519
- # Read the browser monitor script template
520
- script_path = (
521
- dashboard_dir / "static" / "js" / "browser-console-monitor.js"
522
- )
523
-
524
- if not script_path.exists():
525
- return web.Response(
526
- text="Browser monitor script not found",
527
- status=404,
528
- content_type="text/javascript",
529
- )
530
-
531
- # Read script content
532
- with open(script_path, encoding="utf-8") as f:
533
- script_content = f.read()
534
-
535
- # Replace the port placeholder with actual monitor port
536
- script_content = script_content.replace(
537
- "__MONITOR_PORT__", str(self.port)
538
- )
539
-
540
- # Set appropriate headers for JavaScript
541
- headers = {
542
- "Content-Type": "application/javascript; charset=utf-8",
543
- "Access-Control-Allow-Origin": "*",
544
- "Access-Control-Allow-Methods": "GET, OPTIONS",
545
- "Access-Control-Allow-Headers": "Content-Type",
546
- "Cache-Control": "no-cache, no-store, must-revalidate",
547
- "Pragma": "no-cache",
548
- "Expires": "0",
549
- }
550
-
551
- return web.Response(text=script_content, headers=headers)
552
-
553
- except Exception as e:
554
- self.logger.error(f"Error serving browser monitor script: {e}")
555
- return web.Response(
556
- text=f"// Error loading browser monitor script: {e}",
557
- status=500,
558
- content_type="application/javascript",
559
- )
560
-
561
- # Browser log endpoints
562
- async def api_browser_logs_handler(request):
563
- """Return list of browser log files."""
564
- try:
565
- from pathlib import Path
566
-
567
- # Get browser log directory
568
- log_dir = Path.home() / ".claude-mpm" / "logs" / "client"
569
-
570
- if not log_dir.exists():
571
- return web.json_response({"files": [], "total": 0})
572
-
573
- # Get all log files
574
- log_files = []
575
- for file_path in log_dir.glob("*.log"):
576
- stat = file_path.stat()
577
- log_files.append(
578
- {
579
- "name": file_path.name,
580
- "size": stat.st_size,
581
- "modified": stat.st_mtime,
582
- "modified_iso": datetime.fromtimestamp(
583
- stat.st_mtime
584
- ).isoformat(),
585
- }
586
- )
587
-
588
- # Sort by modification time (newest first)
589
- log_files.sort(key=lambda x: x["modified"], reverse=True)
590
-
591
- return web.json_response(
592
- {
593
- "files": log_files,
594
- "total": len(log_files),
595
- "directory": str(log_dir),
596
- }
597
- )
598
-
599
- except Exception as e:
600
- self.logger.error(f"Error listing browser logs: {e}")
601
- return web.json_response(
602
- {"error": str(e), "files": [], "total": 0}, status=500
603
- )
604
-
605
- async def api_browser_log_file_handler(request):
606
- """Return contents of specific browser log file."""
607
- try:
608
- import json
609
- from pathlib import Path
610
-
611
- filename = request.match_info.get("filename", "")
612
-
613
- # Security: ensure filename is safe (no path traversal)
614
- if (
615
- not filename
616
- or "/" in filename
617
- or "\\" in filename
618
- or ".." in filename
619
- ):
620
- return web.json_response(
621
- {"error": "Invalid filename"}, status=400
622
- )
623
-
624
- # Get log file path
625
- log_dir = Path.home() / ".claude-mpm" / "logs" / "client"
626
- log_file = log_dir / filename
627
-
628
- # Check if file exists and is within log directory
629
- if not log_file.exists() or not log_file.is_file():
630
- return web.json_response(
631
- {"error": "Log file not found"}, status=404
632
- )
633
-
634
- # Ensure file is within the log directory (security check)
635
- try:
636
- log_file.resolve().relative_to(log_dir.resolve())
637
- except ValueError:
638
- return web.json_response(
639
- {"error": "Invalid file path"}, status=403
640
- )
641
-
642
- # Read log entries
643
- entries = []
644
- with open(log_file, encoding="utf-8") as f:
645
- for line in f:
646
- line = line.strip()
647
- if line:
648
- try:
649
- entry = json.loads(line)
650
- entries.append(entry)
651
- except json.JSONDecodeError:
652
- # If not JSON, treat as plain text log
653
- entries.append(
654
- {
655
- "timestamp": "",
656
- "level": "INFO",
657
- "message": line,
658
- }
659
- )
660
-
661
- # Limit entries for performance
662
- max_entries = 1000
663
- if len(entries) > max_entries:
664
- entries = entries[-max_entries:] # Get last N entries
665
-
666
- return web.json_response(
667
- {
668
- "filename": filename,
669
- "entries": entries,
670
- "total": len(entries),
671
- "truncated": len(entries) == max_entries,
672
- }
673
- )
674
-
675
- except Exception as e:
676
- self.logger.error(f"Error reading browser log file: {e}")
677
- return web.json_response(
678
- {"error": str(e), "entries": []}, status=500
679
- )
680
-
681
- async def api_browser_log_handler(request):
682
- """Handle browser log submissions from injected monitoring script."""
683
- try:
684
- import json
685
- from pathlib import Path
686
-
687
- data = await request.json()
512
+ # Monitor page routes
513
+ async def monitor_page_handler(request):
514
+ """Serve monitor HTML pages."""
515
+ page_name = request.match_info.get("page", "agents")
516
+ static_dir = dashboard_dir / "static"
517
+ file_path = static_dir / f"{page_name}.html"
688
518
 
689
- # Extract log data
690
- browser_id = data.get("browser_id", "unknown")
691
- timestamp = data.get("timestamp", datetime.utcnow().isoformat())
692
- level = data.get("level", "INFO")
693
- message = data.get("message", "")
694
- url = data.get("url", "")
695
- user_agent = data.get("userAgent", "")
696
-
697
- # Create log entry
698
- log_entry = {
699
- "browser_id": browser_id,
700
- "timestamp": timestamp,
701
- "level": level,
702
- "message": message,
703
- "url": url,
704
- "user_agent": user_agent,
705
- }
706
-
707
- # Save to file
708
- log_dir = Path.home() / ".claude-mpm" / "logs" / "client"
709
- log_dir.mkdir(parents=True, exist_ok=True)
710
-
711
- # Use browser ID in filename for easy filtering
712
- log_file = log_dir / f"{browser_id}.log"
713
-
714
- # Append to log file
715
- with open(log_file, "a", encoding="utf-8") as f:
716
- f.write(json.dumps(log_entry) + "\n")
717
-
718
- # Also emit to Socket.IO for real-time viewing
719
- if self.sio:
720
- await self.sio.emit("browser_log", log_entry)
721
-
722
- return web.Response(status=204) # No content
723
-
724
- except Exception as e:
725
- self.logger.error(f"Error handling browser log: {e}")
726
- return web.Response(text=str(e), status=500)
519
+ if file_path.exists() and file_path.is_file():
520
+ with open(file_path, encoding="utf-8") as f:
521
+ content = f.read()
522
+ return web.Response(text=content, content_type="text/html")
523
+ return web.Response(text="Page not found", status=404)
727
524
 
728
525
  # Register routes
729
526
  self.app.router.add_get("/", dashboard_index)
@@ -732,16 +529,19 @@ class UnifiedMonitorServer:
732
529
  self.app.router.add_get("/api/config", config_handler)
733
530
  self.app.router.add_get("/api/working-directory", working_directory_handler)
734
531
  self.app.router.add_get("/api/directory", list_directory)
532
+ self.app.router.add_post("/api/events", api_events_handler)
533
+ self.app.router.add_post("/api/file", api_file_handler)
534
+
535
+ # Monitor page routes
536
+ self.app.router.add_get("/monitor", lambda r: monitor_page_handler(r))
735
537
  self.app.router.add_get(
736
- "/api/browser-monitor.js", browser_monitor_script_handler
538
+ "/monitor/agents", lambda r: monitor_page_handler(r)
737
539
  )
738
- self.app.router.add_get("/api/browser-logs", api_browser_logs_handler)
540
+ self.app.router.add_get("/monitor/tools", lambda r: monitor_page_handler(r))
541
+ self.app.router.add_get("/monitor/files", lambda r: monitor_page_handler(r))
739
542
  self.app.router.add_get(
740
- "/api/browser-logs/{filename}", api_browser_log_file_handler
543
+ "/monitor/events", lambda r: monitor_page_handler(r)
741
544
  )
742
- self.app.router.add_post("/api/browser-log", api_browser_log_handler)
743
- self.app.router.add_post("/api/events", api_events_handler)
744
- self.app.router.add_post("/api/file", api_file_handler)
745
545
 
746
546
  # Static files with cache busting headers for development
747
547
  static_dir = dashboard_dir / "static"
@@ -891,10 +691,8 @@ class UnifiedMonitorServer:
891
691
  # Cancel heartbeat task if running
892
692
  if self.heartbeat_task and not self.heartbeat_task.done():
893
693
  self.heartbeat_task.cancel()
894
- try:
694
+ with contextlib.suppress(asyncio.CancelledError):
895
695
  await self.heartbeat_task
896
- except asyncio.CancelledError:
897
- pass
898
696
  self.logger.debug("Heartbeat task cancelled")
899
697
 
900
698
  # Close the Socket.IO server first to stop accepting new connections
@@ -961,7 +759,6 @@ class UnifiedMonitorServer:
961
759
  "host": self.host,
962
760
  "port": self.port,
963
761
  "handlers": {
964
- "browser": self.browser_handler is not None,
965
762
  "code_analysis": self.code_analysis_handler is not None,
966
763
  "dashboard": self.dashboard_handler is not None,
967
764
  "file": self.file_handler is not None,
@@ -1739,7 +1739,7 @@ class CodeTreeAnalyzer:
1739
1739
 
1740
1740
  # Filter only very specific internal patterns
1741
1741
  # Be more conservative - only filter obvious internal handlers
1742
- if name_lower.startswith("handle_") or name_lower.startswith("on_"):
1742
+ if name_lower.startswith(("handle_", "on_")):
1743
1743
  return True
1744
1744
 
1745
1745
  # Filter Python magic methods except important ones
@@ -1756,7 +1756,7 @@ class CodeTreeAnalyzer:
1756
1756
  return node.name not in important_magic
1757
1757
 
1758
1758
  # Filter very generic getters/setters only if they're trivial
1759
- if (name_lower.startswith("get_") or name_lower.startswith("set_")) and len(
1759
+ if (name_lower.startswith(("get_", "set_"))) and len(
1760
1760
  node.name
1761
1761
  ) <= 8:
1762
1762
  return True
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: claude-mpm
3
- Version: 4.2.43
3
+ Version: 4.2.51
4
4
  Summary: Claude Multi-Agent Project Manager - Orchestrate Claude with agent delegation and ticket tracking
5
5
  Author-email: Bob Matsuoka <bob@matsuoka.com>
6
6
  Maintainer: Claude MPM Team