claude-mpm 3.5.4__py3-none-any.whl → 3.5.6__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 (35) hide show
  1. claude_mpm/.claude-mpm/logs/hooks_20250728.log +10 -0
  2. claude_mpm/VERSION +1 -1
  3. claude_mpm/agents/INSTRUCTIONS.md +12 -11
  4. claude_mpm/agents/agent-template.yaml +83 -0
  5. claude_mpm/cli/README.md +108 -0
  6. claude_mpm/cli/commands/agents.py +21 -3
  7. claude_mpm/cli/commands/run.py +4 -11
  8. claude_mpm/cli/utils.py +9 -1
  9. claude_mpm/cli_module/refactoring_guide.md +253 -0
  10. claude_mpm/config/async_logging_config.yaml +145 -0
  11. claude_mpm/core/.claude-mpm/logs/hooks_20250730.log +34 -0
  12. claude_mpm/core/claude_runner.py +94 -33
  13. claude_mpm/core/config_paths.py +0 -1
  14. claude_mpm/core/factories.py +9 -3
  15. claude_mpm/dashboard/.claude-mpm/memories/README.md +36 -0
  16. claude_mpm/dashboard/README.md +121 -0
  17. claude_mpm/dashboard/static/js/dashboard.js.backup +1973 -0
  18. claude_mpm/dashboard/templates/.claude-mpm/memories/README.md +36 -0
  19. claude_mpm/dashboard/templates/.claude-mpm/memories/engineer_agent.md +39 -0
  20. claude_mpm/dashboard/templates/.claude-mpm/memories/version_control_agent.md +38 -0
  21. claude_mpm/hooks/README.md +96 -0
  22. claude_mpm/init.py +83 -13
  23. claude_mpm/schemas/agent_schema.json +435 -0
  24. claude_mpm/services/agents/deployment/agent_deployment.py +165 -9
  25. claude_mpm/services/agents/management/agent_management_service.py +2 -1
  26. claude_mpm/services/framework_claude_md_generator/README.md +92 -0
  27. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +3 -3
  28. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +2 -2
  29. claude_mpm/services/version_control/VERSION +1 -0
  30. {claude_mpm-3.5.4.dist-info → claude_mpm-3.5.6.dist-info}/METADATA +43 -1
  31. {claude_mpm-3.5.4.dist-info → claude_mpm-3.5.6.dist-info}/RECORD +35 -19
  32. {claude_mpm-3.5.4.dist-info → claude_mpm-3.5.6.dist-info}/WHEEL +0 -0
  33. {claude_mpm-3.5.4.dist-info → claude_mpm-3.5.6.dist-info}/entry_points.txt +0 -0
  34. {claude_mpm-3.5.4.dist-info → claude_mpm-3.5.6.dist-info}/licenses/LICENSE +0 -0
  35. {claude_mpm-3.5.4.dist-info → claude_mpm-3.5.6.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,145 @@
1
+ # Async Logging Configuration
2
+ # Optimized logging configuration for high-performance scenarios
3
+
4
+ logging:
5
+ # Enable async logging for improved performance
6
+ async:
7
+ enabled: true
8
+
9
+ # Log format options: json, syslog, journald
10
+ format: json
11
+
12
+ # Maximum queue size for async writes
13
+ max_queue_size: 10000
14
+
15
+ # Enable compression for JSON logs (reduces disk usage)
16
+ compression: false
17
+
18
+ # Worker threads for async processing
19
+ worker_threads: 4
20
+
21
+ # Flush timeout in seconds
22
+ flush_timeout: 5.0
23
+
24
+ # Session logger settings
25
+ session:
26
+ # Base directory for logs
27
+ base_dir: ".claude-mpm/responses"
28
+
29
+ # Use timestamp-based filenames (eliminates race conditions)
30
+ timestamp_filenames: true
31
+
32
+ # Include microseconds in timestamps for uniqueness
33
+ microsecond_precision: true
34
+
35
+ # Filename format with available variables:
36
+ # {agent} - Agent name
37
+ # {timestamp} - ISO timestamp
38
+ # {microseconds} - Microsecond component
39
+ # {session} - Session ID
40
+ filename_format: "{agent}_{timestamp}_{microseconds}.json"
41
+
42
+ # OS-native logging options (for extreme performance)
43
+ syslog:
44
+ # Syslog address (auto-detected by default)
45
+ # address: /var/run/syslog # macOS
46
+ # address: /dev/log # Linux
47
+ # address: ["localhost", 514] # Network
48
+
49
+ # Syslog facility
50
+ facility: local0
51
+
52
+ # Include structured data
53
+ structured_data: true
54
+
55
+ # Performance tuning
56
+ performance:
57
+ # Fire-and-forget mode (don't wait for write confirmation)
58
+ fire_and_forget: true
59
+
60
+ # Drop logs if queue is full (prevents blocking)
61
+ drop_on_full: true
62
+
63
+ # Batch writes for efficiency
64
+ batch_writes: true
65
+ batch_size: 10
66
+ batch_timeout_ms: 100
67
+
68
+ # Hook system optimization
69
+ hooks:
70
+ # Enable hook system
71
+ enabled: true
72
+
73
+ # Optimization settings
74
+ optimization:
75
+ # Cache hook configurations at startup
76
+ cache_configs: true
77
+
78
+ # Lazy load hook implementations
79
+ lazy_loading: true
80
+
81
+ # Use singleton pattern for hook service
82
+ singleton: true
83
+
84
+ # Enable async hook execution
85
+ async_execution: true
86
+
87
+ # Maximum workers for parallel hook execution
88
+ max_workers: 4
89
+
90
+ # Pre-delegation hooks
91
+ pre_delegation:
92
+ enabled: true
93
+
94
+ # Parallel execution for independent hooks
95
+ parallel_safe_hooks:
96
+ - memory_context_hook
97
+ - validation_hook
98
+ - auth_hook
99
+
100
+ # Post-delegation hooks
101
+ post_delegation:
102
+ enabled: true
103
+
104
+ # Parallel execution for independent hooks
105
+ parallel_safe_hooks:
106
+ - logging_hook
107
+ - metrics_hook
108
+ - cleanup_hook
109
+
110
+ # Registered hooks with lazy loading
111
+ registered:
112
+ # NOTE: The builtin hooks have been deprecated and removed
113
+ # These references are kept commented for historical reference
114
+ # memory_context_hook:
115
+ # module: claude_mpm.hooks.builtin.memory_hooks
116
+ # class: MemoryContextHook
117
+ # priority: 10
118
+ # enabled: true
119
+ # params:
120
+ # cache_size: 1000
121
+ #
122
+ # response_logger_hook:
123
+ # module: claude_mpm.hooks.builtin.logging_hooks
124
+ # class: ResponseLoggerHook
125
+ # priority: 90
126
+ # enabled: true
127
+ # params:
128
+ # async: true
129
+ #
130
+ # metrics_hook:
131
+ # module: claude_mpm.hooks.builtin.metrics_hooks
132
+ # class: MetricsCollectorHook
133
+ # priority: 95
134
+ # enabled: true
135
+ # params:
136
+ # buffer_size: 100
137
+
138
+ # Environment variable overrides
139
+ # These can override any setting above:
140
+ #
141
+ # CLAUDE_USE_ASYNC_LOG=true # Enable async logging
142
+ # CLAUDE_LOG_FORMAT=syslog # Use syslog format
143
+ # CLAUDE_LOG_SYNC=true # Disable async (for debugging)
144
+ # CLAUDE_HOOKS_CACHE=true # Enable hook caching
145
+ # CLAUDE_HOOKS_ASYNC=true # Enable async hooks
@@ -0,0 +1,34 @@
1
+ 2025-07-30 12:40:20,992 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PostToolUse (session: df539357)
2
+ 2025-07-30 12:40:20,992 - claude_mpm_hooks_core - INFO - hook_handler.py:254 - PostToolUse: Bash (exit code: N/A)
3
+ 2025-07-30 12:40:33,117 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PreToolUse (session: df539357)
4
+ 2025-07-30 12:40:33,117 - claude_mpm_hooks_core - INFO - hook_handler.py:247 - PreToolUse: Edit
5
+ 2025-07-30 12:40:33,276 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PostToolUse (session: df539357)
6
+ 2025-07-30 12:40:33,276 - claude_mpm_hooks_core - INFO - hook_handler.py:254 - PostToolUse: Edit (exit code: N/A)
7
+ 2025-07-30 12:40:39,276 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PreToolUse (session: df539357)
8
+ 2025-07-30 12:40:39,276 - claude_mpm_hooks_core - INFO - hook_handler.py:247 - PreToolUse: Bash
9
+ 2025-07-30 12:40:39,541 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PostToolUse (session: df539357)
10
+ 2025-07-30 12:40:39,541 - claude_mpm_hooks_core - INFO - hook_handler.py:254 - PostToolUse: Bash (exit code: N/A)
11
+ 2025-07-30 12:40:48,610 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PreToolUse (session: df539357)
12
+ 2025-07-30 12:40:48,610 - claude_mpm_hooks_core - INFO - hook_handler.py:247 - PreToolUse: Bash
13
+ 2025-07-30 12:40:49,941 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PostToolUse (session: df539357)
14
+ 2025-07-30 12:40:49,941 - claude_mpm_hooks_core - INFO - hook_handler.py:254 - PostToolUse: Bash (exit code: N/A)
15
+ 2025-07-30 12:44:50,358 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: UserPromptSubmit (session: df539357)
16
+ 2025-07-30 12:44:50,358 - claude_mpm_hooks_core - INFO - hook_handler.py:244 - UserPromptSubmit: OK. Let's make the subprocess the default method
17
+ 2025-07-30 13:05:35,872 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: UserPromptSubmit (session: df539357)
18
+ 2025-07-30 13:05:35,872 - claude_mpm_hooks_core - INFO - hook_handler.py:244 - UserPromptSubmit: actually leave as is. I want to figure out a simple test to trigger the terminal flow. Use docs/de...
19
+ 2025-07-30 13:05:42,930 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PreToolUse (session: df539357)
20
+ 2025-07-30 13:05:42,930 - claude_mpm_hooks_core - INFO - hook_handler.py:247 - PreToolUse: Read
21
+ 2025-07-30 13:05:43,133 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PostToolUse (session: df539357)
22
+ 2025-07-30 13:05:43,133 - claude_mpm_hooks_core - INFO - hook_handler.py:254 - PostToolUse: Read (exit code: N/A)
23
+ 2025-07-30 13:05:49,996 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PreToolUse (session: df539357)
24
+ 2025-07-30 13:05:49,996 - claude_mpm_hooks_core - INFO - hook_handler.py:247 - PreToolUse: Grep
25
+ 2025-07-30 13:05:50,548 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PostToolUse (session: df539357)
26
+ 2025-07-30 13:05:50,548 - claude_mpm_hooks_core - INFO - hook_handler.py:254 - PostToolUse: Grep (exit code: N/A)
27
+ 2025-07-30 13:05:56,341 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PreToolUse (session: df539357)
28
+ 2025-07-30 13:05:56,341 - claude_mpm_hooks_core - INFO - hook_handler.py:247 - PreToolUse: Read
29
+ 2025-07-30 13:05:56,527 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PostToolUse (session: df539357)
30
+ 2025-07-30 13:05:56,528 - claude_mpm_hooks_core - INFO - hook_handler.py:254 - PostToolUse: Read (exit code: N/A)
31
+ 2025-07-30 13:06:01,890 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PreToolUse (session: df539357)
32
+ 2025-07-30 13:06:01,890 - claude_mpm_hooks_core - INFO - hook_handler.py:247 - PreToolUse: Bash
33
+ 2025-07-30 13:06:08,115 - claude_mpm_hooks_core - INFO - hook_handler.py:231 - Claude Code hook event: PreToolUse (session: df539357)
34
+ 2025-07-30 13:06:08,115 - claude_mpm_hooks_core - INFO - hook_handler.py:247 - PreToolUse: Bash
@@ -74,8 +74,16 @@ class ClaudeRunner:
74
74
  self.logger.warning(f"Failed to initialize project logger: {e}")
75
75
 
76
76
  # Initialize services with proper error handling
77
+ # Determine the user's working directory from environment
78
+ user_working_dir = None
79
+ if 'CLAUDE_MPM_USER_PWD' in os.environ:
80
+ user_working_dir = Path(os.environ['CLAUDE_MPM_USER_PWD'])
81
+ self.logger.info(f"Using user working directory from CLAUDE_MPM_USER_PWD: {user_working_dir}")
82
+
77
83
  try:
78
- self.deployment_service = AgentDeploymentService()
84
+ # Pass the user working directory to the deployment service
85
+ # This ensures agents are deployed to the correct user directory, not the framework directory
86
+ self.deployment_service = AgentDeploymentService(working_directory=user_working_dir)
79
87
  except ImportError as e:
80
88
  self.logger.error(f"Failed to import AgentDeploymentService: {e}")
81
89
  raise RuntimeError("Required module AgentDeploymentService not available. Please reinstall claude-mpm.") from e
@@ -253,8 +261,12 @@ class ClaudeRunner:
253
261
  bool: True if agents are available, False on error
254
262
  """
255
263
  try:
256
- # Check if we're in a project directory
257
- project_dir = Path.cwd()
264
+ # Use the correct user directory, not the framework directory
265
+ if 'CLAUDE_MPM_USER_PWD' in os.environ:
266
+ project_dir = Path(os.environ['CLAUDE_MPM_USER_PWD'])
267
+ else:
268
+ project_dir = Path.cwd()
269
+
258
270
  project_agents_dir = project_dir / ".claude-mpm" / "agents"
259
271
 
260
272
  # Create directory if it doesn't exist
@@ -321,7 +333,12 @@ class ClaudeRunner:
321
333
  bool: True if deployment successful or no agents to deploy, False on error
322
334
  """
323
335
  try:
324
- project_dir = Path.cwd()
336
+ # Use the correct user directory, not the framework directory
337
+ if 'CLAUDE_MPM_USER_PWD' in os.environ:
338
+ project_dir = Path(os.environ['CLAUDE_MPM_USER_PWD'])
339
+ else:
340
+ project_dir = Path.cwd()
341
+
325
342
  project_agents_dir = project_dir / ".claude-mpm" / "agents"
326
343
  claude_agents_dir = project_dir / ".claude" / "agents"
327
344
 
@@ -352,9 +369,41 @@ class ClaudeRunner:
352
369
  errors = []
353
370
 
354
371
  # Deploy each JSON agent
372
+ # CRITICAL: PM (Project Manager) must NEVER be deployed as it's the main Claude instance
373
+ EXCLUDED_AGENTS = {'pm', 'project_manager'}
374
+
375
+ # Initialize deployment service with proper base agent path
376
+ # Use the existing deployment service's base agent path if available
377
+ base_agent_path = project_agents_dir / "base_agent.json"
378
+ if not base_agent_path.exists():
379
+ # Fall back to system base agent
380
+ base_agent_path = self.deployment_service.base_agent_path
381
+
382
+ # Create a single deployment service instance for all agents
383
+ project_deployment = AgentDeploymentService(
384
+ templates_dir=project_agents_dir,
385
+ base_agent_path=base_agent_path,
386
+ working_directory=project_dir # Pass the project directory
387
+ )
388
+
389
+ # Load base agent data once
390
+ base_agent_data = {}
391
+ if base_agent_path and base_agent_path.exists():
392
+ try:
393
+ import json
394
+ base_agent_data = json.loads(base_agent_path.read_text())
395
+ except Exception as e:
396
+ self.logger.warning(f"Could not load base agent: {e}")
397
+
355
398
  for json_file in json_files:
356
399
  try:
357
400
  agent_name = json_file.stem
401
+
402
+ # Skip PM agent - it's the main Claude instance, not a subagent
403
+ if agent_name.lower() in EXCLUDED_AGENTS:
404
+ self.logger.info(f"Skipping {agent_name} (PM is the main Claude instance)")
405
+ continue
406
+
358
407
  target_file = claude_agents_dir / f"{agent_name}.md"
359
408
 
360
409
  # Check if agent needs update
@@ -369,26 +418,7 @@ class ClaudeRunner:
369
418
  self.logger.debug(f"Project agent {agent_name} is up to date")
370
419
 
371
420
  if needs_update:
372
- # Use deployment service to build the agent
373
- from claude_mpm.services.agents.deployment.agent_deployment import AgentDeploymentService
374
-
375
- # Create a temporary deployment service for this specific task
376
- project_deployment = AgentDeploymentService(
377
- templates_dir=project_agents_dir,
378
- base_agent_path=project_dir / ".claude-mpm" / "agents" / "base_agent.json"
379
- )
380
-
381
- # Load base agent data if available
382
- base_agent_data = {}
383
- base_agent_path = project_dir / ".claude-mpm" / "agents" / "base_agent.json"
384
- if base_agent_path.exists():
385
- import json
386
- try:
387
- base_agent_data = json.loads(base_agent_path.read_text())
388
- except Exception as e:
389
- self.logger.warning(f"Could not load project base agent: {e}")
390
-
391
- # Build the agent markdown
421
+ # Build the agent markdown using the pre-initialized service and base agent data
392
422
  agent_content = project_deployment._build_agent_markdown(
393
423
  agent_name, json_file, base_agent_data
394
424
  )
@@ -1063,17 +1093,46 @@ class ClaudeRunner:
1063
1093
  def _load_system_instructions(self) -> Optional[str]:
1064
1094
  """Load and process system instructions from agents/INSTRUCTIONS.md.
1065
1095
 
1066
- WHY: Process template variables like {{capabilities-list}} to include
1067
- dynamic agent capabilities in the PM's system instructions.
1096
+ Implements project > framework precedence:
1097
+ 1. First check for project-specific instructions in .claude-mpm/agents/INSTRUCTIONS.md
1098
+ 2. If not found, fall back to framework instructions in src/claude_mpm/agents/INSTRUCTIONS.md
1099
+
1100
+ WHY: Allows projects to override the default PM instructions with project-specific
1101
+ guidance, while maintaining backward compatibility with the framework defaults.
1102
+
1103
+ DESIGN DECISION: Using CLAUDE_MPM_USER_PWD environment variable to locate the
1104
+ correct project directory, ensuring we check the right location even when
1105
+ claude-mpm is invoked from a different directory.
1068
1106
  """
1069
1107
  try:
1070
- # Find the INSTRUCTIONS.md file
1071
- module_path = Path(__file__).parent.parent
1072
- instructions_path = module_path / "agents" / "INSTRUCTIONS.md"
1108
+ # Determine the user's project directory
1109
+ if 'CLAUDE_MPM_USER_PWD' in os.environ:
1110
+ project_dir = Path(os.environ['CLAUDE_MPM_USER_PWD'])
1111
+ else:
1112
+ project_dir = Path.cwd()
1113
+
1114
+ # Check for project-specific INSTRUCTIONS.md first
1115
+ project_instructions_path = project_dir / ".claude-mpm" / "agents" / "INSTRUCTIONS.md"
1116
+
1117
+ instructions_path = None
1118
+ instructions_source = None
1073
1119
 
1074
- if not instructions_path.exists():
1075
- self.logger.warning(f"System instructions not found: {instructions_path}")
1076
- return None
1120
+ if project_instructions_path.exists():
1121
+ instructions_path = project_instructions_path
1122
+ instructions_source = "PROJECT"
1123
+ self.logger.info(f"Found project-specific INSTRUCTIONS.md: {instructions_path}")
1124
+ else:
1125
+ # Fall back to framework instructions
1126
+ module_path = Path(__file__).parent.parent
1127
+ framework_instructions_path = module_path / "agents" / "INSTRUCTIONS.md"
1128
+
1129
+ if framework_instructions_path.exists():
1130
+ instructions_path = framework_instructions_path
1131
+ instructions_source = "FRAMEWORK"
1132
+ self.logger.info(f"Using framework INSTRUCTIONS.md: {instructions_path}")
1133
+ else:
1134
+ self.logger.warning(f"No INSTRUCTIONS.md found in project or framework")
1135
+ return None
1077
1136
 
1078
1137
  # Read raw instructions
1079
1138
  raw_instructions = instructions_path.read_text()
@@ -1083,13 +1142,15 @@ class ClaudeRunner:
1083
1142
  from claude_mpm.services.framework_claude_md_generator.content_assembler import ContentAssembler
1084
1143
  assembler = ContentAssembler()
1085
1144
  processed_instructions = assembler.apply_template_variables(raw_instructions)
1086
- self.logger.info("Loaded and processed PM framework system instructions with dynamic capabilities")
1145
+ self.logger.info(f"Loaded and processed {instructions_source} PM instructions with dynamic capabilities")
1087
1146
  return processed_instructions
1088
1147
  except ImportError:
1089
1148
  self.logger.warning("ContentAssembler not available, using raw instructions")
1149
+ self.logger.info(f"Loaded {instructions_source} PM instructions (raw)")
1090
1150
  return raw_instructions
1091
1151
  except Exception as e:
1092
1152
  self.logger.warning(f"Failed to process template variables: {e}, using raw instructions")
1153
+ self.logger.info(f"Loaded {instructions_source} PM instructions (raw, processing failed)")
1093
1154
  return raw_instructions
1094
1155
 
1095
1156
  except Exception as e:
@@ -35,7 +35,6 @@ class ConfigPaths:
35
35
  RESPONSES_DIR = "responses"
36
36
 
37
37
  # Agent subdirectories
38
- AGENT_PROJECT_SPECIFIC = "project-specific"
39
38
  AGENT_USER_AGENTS = "user-agents"
40
39
  AGENT_USER_DEFINED = "user-defined"
41
40
  AGENT_SYSTEM = "templates"
@@ -57,14 +57,20 @@ class AgentServiceFactory(ServiceFactory):
57
57
  config = container.resolve(Config)
58
58
 
59
59
  # Get directories from config if not provided
60
+ import os
61
+
60
62
  if framework_dir is None:
61
63
  framework_dir = Path(config.get('framework.dir', 'framework'))
62
64
 
63
65
  if project_dir is None:
64
- project_dir = Path(config.get('project.dir', '.'))
66
+ # Check for user working directory from environment
67
+ if 'CLAUDE_MPM_USER_PWD' in os.environ:
68
+ project_dir = Path(os.environ['CLAUDE_MPM_USER_PWD'])
69
+ else:
70
+ project_dir = Path(config.get('project.dir', '.'))
65
71
 
66
- # Create service with dependencies
67
- service = AgentDeploymentService()
72
+ # Create service with proper working directory
73
+ service = AgentDeploymentService(working_directory=project_dir)
68
74
 
69
75
  # Inject any required dependencies
70
76
  if hasattr(service, 'set_directories'):
@@ -0,0 +1,36 @@
1
+ # Agent Memory System
2
+
3
+ ## Purpose
4
+ Each agent maintains project-specific knowledge in these files. Agents read their memory file before tasks and update it when they learn something new.
5
+
6
+ ## Manual Editing
7
+ Feel free to edit these files to:
8
+ - Add project-specific guidelines
9
+ - Remove outdated information
10
+ - Reorganize for better clarity
11
+ - Add domain-specific knowledge
12
+
13
+ ## Memory Limits
14
+ - Max file size: 8KB (~2000 tokens)
15
+ - Max sections: 10
16
+ - Max items per section: 15
17
+ - Files auto-truncate when limits exceeded
18
+
19
+ ## File Format
20
+ Standard markdown with structured sections. Agents expect:
21
+ - Project Architecture
22
+ - Implementation Guidelines
23
+ - Common Mistakes to Avoid
24
+ - Current Technical Context
25
+
26
+ ## How It Works
27
+ 1. Agents read their memory file before starting tasks
28
+ 2. Agents add learnings during or after task completion
29
+ 3. Files automatically enforce size limits
30
+ 4. Developers can manually edit for accuracy
31
+
32
+ ## Memory File Lifecycle
33
+ - Created automatically when agent first runs
34
+ - Updated through hook system after delegations
35
+ - Manually editable by developers
36
+ - Version controlled with project
@@ -0,0 +1,121 @@
1
+ # Claude MPM Web Dashboard
2
+
3
+ This directory contains the modular web dashboard for Claude MPM monitoring and management.
4
+
5
+ ## Structure
6
+
7
+ ```
8
+ src/claude_mpm/dashboard/
9
+ ├── static/
10
+ │ ├── css/
11
+ │ │ └── dashboard.css # Main stylesheet
12
+ │ └── js/
13
+ │ ├── socket-client.js # Socket.IO connection management
14
+ │ ├── dashboard.js # Main dashboard application
15
+ │ └── components/
16
+ │ ├── event-viewer.js # Event display and filtering
17
+ │ ├── module-viewer.js # Event detail viewer
18
+ │ └── session-manager.js # Session management
19
+ ├── templates/
20
+ │ └── index.html # Main dashboard HTML
21
+ ├── index.html # Root index with redirect
22
+ ├── test_dashboard.html # Test version for verification
23
+ └── README.md # This file
24
+ ```
25
+
26
+ ## Components
27
+
28
+ ### SocketClient (`socket-client.js`)
29
+ - Manages WebSocket connections to the Claude MPM server
30
+ - Handles event reception and processing
31
+ - Provides callbacks for connection state changes
32
+ - Maintains event history and session tracking
33
+
34
+ ### EventViewer (`components/event-viewer.js`)
35
+ - Displays events in a filterable list
36
+ - Supports search, type filtering, and session filtering
37
+ - Handles event selection and keyboard navigation
38
+ - Updates metrics display (total events, events per minute, etc.)
39
+
40
+ ### ModuleViewer (`components/module-viewer.js`)
41
+ - Shows detailed information about selected events
42
+ - Provides structured views for different event types
43
+ - Displays raw JSON data for debugging
44
+ - Organizes events by class/category
45
+
46
+ ### SessionManager (`components/session-manager.js`)
47
+ - Manages session selection and filtering
48
+ - Updates session dropdown with available sessions
49
+ - Tracks current active session
50
+ - Updates footer information
51
+
52
+ ### Dashboard (`dashboard.js`)
53
+ - Main application coordinator
54
+ - Handles tab switching between Events, Agents, Tools, and Files
55
+ - Manages component interactions
56
+ - Provides global functions for backward compatibility
57
+
58
+ ## Features
59
+
60
+ ### File-Centric Files Tab
61
+ The Files tab now shows a file-centric view where:
62
+ - Each file appears only once in the list
63
+ - Files show read/write icons based on operations performed
64
+ - Most recently accessed files appear at the bottom
65
+ - Clicking a file shows all operations performed on it with timestamps and agent information
66
+
67
+ ### Tab Organization
68
+ - **Events**: All events with filtering and search
69
+ - **Agents**: Agent-specific events and operations
70
+ - **Tools**: Tool usage and parameters
71
+ - **Files**: File operations organized by file path
72
+
73
+ ### Enhanced Event Details
74
+ - Structured views for different event types
75
+ - Todo checklists with status indicators
76
+ - Agent and tool information
77
+ - Session tracking and filtering
78
+
79
+ ## Usage
80
+
81
+ ### Development
82
+ For development and testing, use `test_dashboard.html` which includes module verification.
83
+
84
+ ### Production
85
+ Use `templates/dashboard.html` as the main template, ensuring all static files are served correctly.
86
+
87
+ ### Integration
88
+ The dashboard can be integrated into a Flask/FastAPI application by serving the static files and using the template.
89
+
90
+ ## Migration from Original
91
+
92
+ The original monolithic `claude_mpm_socketio_dashboard.html` has been replaced with a modular structure:
93
+
94
+ 1. **CSS**: Extracted to `static/css/dashboard.css`
95
+ 2. **JavaScript**: Split into logical modules in `static/js/`
96
+ 3. **HTML**: Clean template in `templates/dashboard.html`
97
+
98
+ All original functionality has been preserved while improving:
99
+ - Code organization and maintainability
100
+ - Module reusability
101
+ - Easier debugging and development
102
+ - Better separation of concerns
103
+
104
+ ## Backward Compatibility
105
+
106
+ Global functions are maintained for compatibility:
107
+ - `connectSocket()`
108
+ - `disconnectSocket()`
109
+ - `clearEvents()`
110
+ - `exportEvents()`
111
+ - `clearSelection()`
112
+ - `switchTab(tabName)`
113
+
114
+ ## Browser Support
115
+
116
+ Requires modern browsers with support for:
117
+ - ES6 Classes
118
+ - Fetch API
119
+ - Custom Events
120
+ - CSS Grid/Flexbox
121
+ - Socket.IO 4.x