claude-mpm 4.1.10__py3-none-any.whl → 4.1.12__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 (56) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/INSTRUCTIONS.md +8 -0
  3. claude_mpm/cli/__init__.py +11 -0
  4. claude_mpm/cli/commands/analyze.py +2 -1
  5. claude_mpm/cli/commands/configure.py +9 -8
  6. claude_mpm/cli/commands/configure_tui.py +3 -1
  7. claude_mpm/cli/commands/dashboard.py +288 -0
  8. claude_mpm/cli/commands/debug.py +0 -1
  9. claude_mpm/cli/commands/mpm_init.py +442 -0
  10. claude_mpm/cli/commands/mpm_init_handler.py +84 -0
  11. claude_mpm/cli/parsers/base_parser.py +15 -0
  12. claude_mpm/cli/parsers/dashboard_parser.py +113 -0
  13. claude_mpm/cli/parsers/mpm_init_parser.py +128 -0
  14. claude_mpm/constants.py +10 -0
  15. claude_mpm/core/config.py +18 -0
  16. claude_mpm/core/instruction_reinforcement_hook.py +266 -0
  17. claude_mpm/core/pm_hook_interceptor.py +105 -8
  18. claude_mpm/dashboard/analysis_runner.py +52 -25
  19. claude_mpm/dashboard/static/built/components/activity-tree.js +1 -1
  20. claude_mpm/dashboard/static/built/components/code-tree.js +2 -0
  21. claude_mpm/dashboard/static/built/components/code-viewer.js +2 -0
  22. claude_mpm/dashboard/static/built/components/event-viewer.js +1 -1
  23. claude_mpm/dashboard/static/built/dashboard.js +1 -1
  24. claude_mpm/dashboard/static/built/socket-client.js +1 -1
  25. claude_mpm/dashboard/static/css/code-tree.css +330 -1
  26. claude_mpm/dashboard/static/dist/components/activity-tree.js +1 -1
  27. claude_mpm/dashboard/static/dist/components/code-tree.js +2593 -2
  28. claude_mpm/dashboard/static/dist/components/event-viewer.js +1 -1
  29. claude_mpm/dashboard/static/dist/dashboard.js +1 -1
  30. claude_mpm/dashboard/static/dist/socket-client.js +1 -1
  31. claude_mpm/dashboard/static/js/components/activity-tree.js +212 -13
  32. claude_mpm/dashboard/static/js/components/build-tracker.js +15 -13
  33. claude_mpm/dashboard/static/js/components/code-tree.js +2503 -917
  34. claude_mpm/dashboard/static/js/components/event-viewer.js +58 -19
  35. claude_mpm/dashboard/static/js/dashboard.js +46 -44
  36. claude_mpm/dashboard/static/js/socket-client.js +74 -32
  37. claude_mpm/dashboard/templates/index.html +25 -20
  38. claude_mpm/services/agents/deployment/agent_template_builder.py +11 -7
  39. claude_mpm/services/agents/memory/memory_format_service.py +3 -1
  40. claude_mpm/services/cli/agent_cleanup_service.py +1 -4
  41. claude_mpm/services/cli/socketio_manager.py +39 -8
  42. claude_mpm/services/cli/startup_checker.py +0 -1
  43. claude_mpm/services/core/cache_manager.py +0 -1
  44. claude_mpm/services/infrastructure/monitoring.py +1 -1
  45. claude_mpm/services/socketio/event_normalizer.py +64 -0
  46. claude_mpm/services/socketio/handlers/code_analysis.py +449 -0
  47. claude_mpm/services/socketio/server/connection_manager.py +3 -1
  48. claude_mpm/tools/code_tree_analyzer.py +930 -24
  49. claude_mpm/tools/code_tree_builder.py +0 -1
  50. claude_mpm/tools/code_tree_events.py +113 -15
  51. {claude_mpm-4.1.10.dist-info → claude_mpm-4.1.12.dist-info}/METADATA +2 -1
  52. {claude_mpm-4.1.10.dist-info → claude_mpm-4.1.12.dist-info}/RECORD +56 -48
  53. {claude_mpm-4.1.10.dist-info → claude_mpm-4.1.12.dist-info}/WHEEL +0 -0
  54. {claude_mpm-4.1.10.dist-info → claude_mpm-4.1.12.dist-info}/entry_points.txt +0 -0
  55. {claude_mpm-4.1.10.dist-info → claude_mpm-4.1.12.dist-info}/licenses/LICENSE +0 -0
  56. {claude_mpm-4.1.10.dist-info → claude_mpm-4.1.12.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,442 @@
1
+ """
2
+ MPM-Init Command - Initialize projects for optimal Claude Code and Claude MPM success.
3
+
4
+ This command delegates to the Agentic Coder Optimizer agent to establish clear,
5
+ single-path project standards for documentation, tooling, and workflows.
6
+ """
7
+
8
+ import logging
9
+ import subprocess
10
+ import sys
11
+ from pathlib import Path
12
+ from typing import Dict, List, Optional
13
+
14
+ import click
15
+ from rich.console import Console
16
+ from rich.panel import Panel
17
+ from rich.progress import Progress, SpinnerColumn, TextColumn
18
+
19
+ logger = logging.getLogger(__name__)
20
+ console = Console()
21
+
22
+
23
+ class MPMInitCommand:
24
+ """Initialize projects for optimal Claude Code and Claude MPM usage."""
25
+
26
+ def __init__(self, project_path: Path = None):
27
+ """Initialize the MPM-Init command."""
28
+ self.project_path = project_path or Path.cwd()
29
+ self.claude_mpm_script = self._find_claude_mpm_script()
30
+
31
+ def initialize_project(
32
+ self,
33
+ project_type: Optional[str] = None,
34
+ framework: Optional[str] = None,
35
+ force: bool = False,
36
+ verbose: bool = False,
37
+ use_venv: bool = False,
38
+ ) -> Dict:
39
+ """
40
+ Initialize project with Agentic Coder Optimizer standards.
41
+
42
+ Args:
43
+ project_type: Type of project (web, api, cli, library, etc.)
44
+ framework: Specific framework if applicable
45
+ force: Force initialization even if project already configured
46
+ verbose: Show detailed output
47
+
48
+ Returns:
49
+ Dict containing initialization results
50
+ """
51
+ try:
52
+ # Check if project already initialized
53
+ claude_md = self.project_path / "CLAUDE.md"
54
+ if claude_md.exists() and not force:
55
+ console.print("[yellow]⚠️ Project already has CLAUDE.md file.[/yellow]")
56
+ console.print(
57
+ "[yellow]Use --force to reinitialize the project.[/yellow]"
58
+ )
59
+ return {"status": "cancelled", "message": "Initialization cancelled"}
60
+
61
+ # Build the delegation prompt
62
+ prompt = self._build_initialization_prompt(project_type, framework)
63
+
64
+ # Show initialization plan
65
+ console.print(
66
+ Panel(
67
+ "[bold cyan]🤖👥 Claude MPM Project Initialization[/bold cyan]\n\n"
68
+ "This will set up your project with:\n"
69
+ "• Clear CLAUDE.md documentation for AI agents\n"
70
+ "• Single-path workflows (ONE way to do ANYTHING)\n"
71
+ "• Optimized project structure\n"
72
+ "• Tool configurations (linting, formatting, testing)\n"
73
+ "• GitHub workflows and CI/CD setup\n"
74
+ "• Memory system initialization\n\n"
75
+ "[dim]Powered by Agentic Coder Optimizer Agent[/dim]",
76
+ title="MPM-Init",
77
+ border_style="cyan",
78
+ )
79
+ )
80
+
81
+ # Execute via claude-mpm run command
82
+ with Progress(
83
+ SpinnerColumn(),
84
+ TextColumn("[progress.description]{task.description}"),
85
+ console=console,
86
+ ) as progress:
87
+ task = progress.add_task(
88
+ "[cyan]Delegating to Agentic Coder Optimizer...", total=None
89
+ )
90
+
91
+ # Run the initialization through subprocess
92
+ result = self._run_initialization(prompt, verbose, use_venv)
93
+
94
+ progress.update(task, description="[green]✓ Initialization complete")
95
+
96
+ return result
97
+
98
+ except Exception as e:
99
+ logger.error(f"Failed to initialize project: {e}")
100
+ console.print(f"[red]❌ Error: {e}[/red]")
101
+ return {"status": "error", "message": str(e)}
102
+
103
+ def _find_claude_mpm_script(self) -> Path:
104
+ """Find the claude-mpm script location."""
105
+ # Try to find claude-mpm in the project scripts directory first
106
+ project_root = Path(__file__).parent.parent.parent.parent.parent
107
+ script_path = project_root / "scripts" / "claude-mpm"
108
+ if script_path.exists():
109
+ return script_path
110
+ # Otherwise assume it's in PATH
111
+ return Path("claude-mpm")
112
+
113
+ def _build_initialization_prompt(
114
+ self, project_type: Optional[str] = None, framework: Optional[str] = None
115
+ ) -> str:
116
+ """Build the initialization prompt for the agent."""
117
+ base_prompt = f"""Please delegate this task to the Agentic Coder Optimizer agent:
118
+
119
+ Initialize this project for optimal use with Claude Code and Claude MPM.
120
+
121
+ Project Path: {self.project_path}
122
+ """
123
+
124
+ if project_type:
125
+ base_prompt += f"Project Type: {project_type}\n"
126
+
127
+ if framework:
128
+ base_prompt += f"Framework: {framework}\n"
129
+
130
+ base_prompt += """
131
+ Please perform the following initialization tasks:
132
+
133
+ 1. **Analyze Current State**:
134
+ - Scan project structure and existing configurations
135
+ - Identify project type, language, and frameworks
136
+ - Check for existing documentation and tooling
137
+
138
+ 2. **Create/Update CLAUDE.md**:
139
+ - Project overview and purpose
140
+ - Architecture and key components
141
+ - Development guidelines
142
+ - ONE clear way to: build, test, deploy, lint, format
143
+ - Links to all relevant documentation
144
+ - Common tasks and workflows
145
+
146
+ 3. **Establish Single-Path Standards**:
147
+ - ONE command for each operation (build, test, lint, etc.)
148
+ - Clear documentation of THE way to do things
149
+ - Remove ambiguity in workflows
150
+
151
+ 4. **Configure Development Tools**:
152
+ - Set up or verify linting configuration
153
+ - Configure code formatting standards
154
+ - Establish testing framework
155
+ - Add pre-commit hooks if needed
156
+
157
+ 5. **Create Project Structure Documentation**:
158
+ - Document folder organization
159
+ - Explain where different file types belong
160
+ - Provide examples of proper file placement
161
+
162
+ 6. **Set Up GitHub Integration** (if applicable):
163
+ - Create/update .github/workflows
164
+ - Add issue and PR templates
165
+ - Configure branch protection rules documentation
166
+
167
+ 7. **Initialize Memory System**:
168
+ - Create .claude-mpm/memories/ directory
169
+ - Add initial memory files for key project knowledge
170
+ - Document memory usage patterns
171
+
172
+ 8. **Generate Quick Start Guide**:
173
+ - Step-by-step setup instructions
174
+ - Common commands reference
175
+ - Troubleshooting guide
176
+
177
+ Please ensure all documentation is clear, concise, and optimized for AI agents to understand and follow.
178
+ Focus on establishing ONE clear way to do ANYTHING in the project.
179
+ """
180
+
181
+ return base_prompt
182
+
183
+ def _build_claude_mpm_command(
184
+ self, verbose: bool, use_venv: bool = False
185
+ ) -> List[str]:
186
+ """Build the claude-mpm run command with appropriate arguments."""
187
+ cmd = [str(self.claude_mpm_script)]
188
+
189
+ # Add venv flag if requested or if mamba issues detected
190
+ # This goes BEFORE the subcommand
191
+ if use_venv:
192
+ cmd.append("--use-venv")
193
+
194
+ # Add top-level flags that go before 'run' subcommand
195
+ cmd.append("--no-check-dependencies")
196
+
197
+ # Now add the run subcommand
198
+ cmd.append("run")
199
+
200
+ # Add non-interactive mode
201
+ # We'll pass the prompt via stdin instead of -i flag
202
+ cmd.append("--non-interactive")
203
+
204
+ # Add verbose flag if requested (run subcommand argument)
205
+ if verbose:
206
+ cmd.append("--verbose")
207
+
208
+ return cmd
209
+
210
+ def _run_initialization(
211
+ self, prompt: str, verbose: bool, use_venv: bool = False
212
+ ) -> Dict:
213
+ """Run the initialization through subprocess calling claude-mpm."""
214
+ import tempfile
215
+
216
+ try:
217
+ # Write prompt to temporary file
218
+ with tempfile.NamedTemporaryFile(
219
+ mode="w", suffix=".txt", delete=False
220
+ ) as tmp_file:
221
+ tmp_file.write(prompt)
222
+ prompt_file = tmp_file.name
223
+
224
+ try:
225
+ # Build the command
226
+ cmd = self._build_claude_mpm_command(verbose, use_venv)
227
+ # Add the input file flag
228
+ cmd.extend(["-i", prompt_file])
229
+
230
+ # Log the command if verbose
231
+ if verbose:
232
+ console.print(f"[dim]Running: {' '.join(cmd)}[/dim]")
233
+ console.print(f"[dim]Prompt file: {prompt_file}[/dim]")
234
+
235
+ # Execute the command
236
+ result = subprocess.run(
237
+ cmd, capture_output=True, text=True, cwd=str(self.project_path), check=False
238
+ )
239
+
240
+ # Check for environment-specific errors
241
+ if "libmamba" in result.stderr or "tree-sitter" in result.stderr:
242
+ console.print(
243
+ "\n[yellow]⚠️ Environment dependency issue detected.[/yellow]"
244
+ )
245
+ console.print(
246
+ "[yellow]Attempting alternative initialization method...[/yellow]\n"
247
+ )
248
+
249
+ # Try again with venv flag to bypass mamba
250
+ cmd_venv = self._build_claude_mpm_command(verbose, use_venv=True)
251
+ cmd_venv.extend(["-i", prompt_file])
252
+
253
+ if verbose:
254
+ console.print(f"[dim]Retrying with: {' '.join(cmd_venv)}[/dim]")
255
+
256
+ result = subprocess.run(
257
+ cmd_venv,
258
+ capture_output=not verbose,
259
+ text=True,
260
+ cwd=str(self.project_path), check=False,
261
+ )
262
+ finally:
263
+ # Clean up temporary file
264
+ import os
265
+
266
+ try:
267
+ os.unlink(prompt_file)
268
+ except:
269
+ pass
270
+
271
+ # Display output if verbose
272
+ if verbose and result.stdout:
273
+ console.print(result.stdout)
274
+ if verbose and result.stderr:
275
+ console.print(f"[yellow]{result.stderr}[/yellow]")
276
+
277
+ # Check result - be more lenient with return codes
278
+ if result.returncode == 0 or (self.project_path / "CLAUDE.md").exists():
279
+ response = {
280
+ "status": "success",
281
+ "message": "Project initialized successfully",
282
+ "files_created": [],
283
+ "files_updated": [],
284
+ "next_steps": [],
285
+ }
286
+
287
+ # Check if CLAUDE.md was created
288
+ claude_md = self.project_path / "CLAUDE.md"
289
+ if claude_md.exists():
290
+ response["files_created"].append("CLAUDE.md")
291
+
292
+ # Check for other common files
293
+ for file_name in ["CODE.md", "DEVELOPER.md", "STRUCTURE.md", "OPS.md"]:
294
+ file_path = self.project_path / file_name
295
+ if file_path.exists():
296
+ response["files_created"].append(file_name)
297
+
298
+ # Add next steps
299
+ response["next_steps"] = [
300
+ "Review the generated CLAUDE.md documentation",
301
+ "Verify the project structure meets your needs",
302
+ "Run 'claude-mpm run' to start using the optimized setup",
303
+ ]
304
+
305
+ # Display results
306
+ self._display_results(response, verbose)
307
+
308
+ return response
309
+ # Extract meaningful error message
310
+ error_msg = (
311
+ result.stderr
312
+ if result.stderr
313
+ else result.stdout if result.stdout else "Unknown error occurred"
314
+ )
315
+ # Clean up mamba warnings from error message
316
+ if "libmamba" in error_msg:
317
+ lines = error_msg.split("\n")
318
+ error_lines = [
319
+ l for l in lines if not l.startswith("warning") and l.strip()
320
+ ]
321
+ error_msg = "\n".join(error_lines) if error_lines else error_msg
322
+
323
+ logger.error(f"claude-mpm run failed: {error_msg}")
324
+ return {
325
+ "status": "error",
326
+ "message": f"Initialization failed: {error_msg}",
327
+ }
328
+
329
+ except FileNotFoundError:
330
+ logger.error("claude-mpm command not found")
331
+ console.print(
332
+ "[red]Error: claude-mpm command not found. Ensure Claude MPM is properly installed.[/red]"
333
+ )
334
+ return {"status": "error", "message": "claude-mpm not found"}
335
+ except Exception as e:
336
+ logger.error(f"Initialization failed: {e}")
337
+ return {"status": "error", "message": str(e)}
338
+
339
+ def _display_results(self, result: Dict, verbose: bool):
340
+ """Display initialization results."""
341
+ if result["status"] == "success":
342
+ console.print("\n[green]✅ Project Initialization Complete![/green]\n")
343
+
344
+ if result.get("files_created"):
345
+ console.print("[bold]Files Created:[/bold]")
346
+ for file in result["files_created"]:
347
+ console.print(f" • {file}")
348
+ console.print()
349
+
350
+ if result.get("files_updated"):
351
+ console.print("[bold]Files Updated:[/bold]")
352
+ for file in result["files_updated"]:
353
+ console.print(f" • {file}")
354
+ console.print()
355
+
356
+ if result.get("next_steps"):
357
+ console.print("[bold]Next Steps:[/bold]")
358
+ for step in result["next_steps"]:
359
+ console.print(f" → {step}")
360
+ console.print()
361
+
362
+ console.print(
363
+ Panel(
364
+ "[green]Your project is now optimized for Claude Code and Claude MPM![/green]\n\n"
365
+ "Key files:\n"
366
+ "• [cyan]CLAUDE.md[/cyan] - Main documentation for AI agents\n"
367
+ "• [cyan].claude-mpm/[/cyan] - Configuration and memories\n\n"
368
+ "[dim]Run 'claude-mpm run' to start using the optimized setup[/dim]",
369
+ title="Success",
370
+ border_style="green",
371
+ )
372
+ )
373
+
374
+
375
+ @click.command(name="mpm-init")
376
+ @click.option(
377
+ "--project-type",
378
+ type=click.Choice(
379
+ ["web", "api", "cli", "library", "mobile", "desktop", "fullstack"]
380
+ ),
381
+ help="Type of project to initialize",
382
+ )
383
+ @click.option(
384
+ "--framework",
385
+ type=str,
386
+ help="Specific framework (e.g., react, django, fastapi, express)",
387
+ )
388
+ @click.option(
389
+ "--force",
390
+ is_flag=True,
391
+ help="Force reinitialization even if project is already configured",
392
+ )
393
+ @click.option(
394
+ "--verbose", is_flag=True, help="Show detailed output during initialization"
395
+ )
396
+ @click.argument(
397
+ "project_path",
398
+ type=click.Path(exists=True, file_okay=False, dir_okay=True),
399
+ required=False,
400
+ default=".",
401
+ )
402
+ def mpm_init(project_type, framework, force, verbose, project_path):
403
+ """
404
+ Initialize a project for optimal use with Claude Code and Claude MPM.
405
+
406
+ This command uses the Agentic Coder Optimizer agent to:
407
+ - Create comprehensive CLAUDE.md documentation
408
+ - Establish single-path workflows (ONE way to do ANYTHING)
409
+ - Configure development tools and standards
410
+ - Set up memory systems for project knowledge
411
+ - Optimize for AI agent understanding
412
+
413
+ Examples:
414
+ claude-mpm mpm-init
415
+ claude-mpm mpm-init --project-type web --framework react
416
+ claude-mpm mpm-init /path/to/project --force
417
+ """
418
+ try:
419
+ # Create command instance
420
+ command = MPMInitCommand(Path(project_path))
421
+
422
+ # Run initialization (now synchronous)
423
+ result = command.initialize_project(
424
+ project_type=project_type, framework=framework, force=force, verbose=verbose
425
+ )
426
+
427
+ # Exit with appropriate code
428
+ if result["status"] == "success":
429
+ sys.exit(0)
430
+ else:
431
+ sys.exit(1)
432
+
433
+ except KeyboardInterrupt:
434
+ console.print("\n[yellow]Initialization cancelled by user[/yellow]")
435
+ sys.exit(130)
436
+ except Exception as e:
437
+ console.print(f"[red]Initialization failed: {e}[/red]")
438
+ sys.exit(1)
439
+
440
+
441
+ # Export for CLI registration
442
+ __all__ = ["mpm_init"]
@@ -0,0 +1,84 @@
1
+ """
2
+ MPM-Init command handler for claude-mpm CLI.
3
+
4
+ This module handles the execution of the mpm-init command.
5
+ """
6
+
7
+ from pathlib import Path
8
+
9
+ from rich.console import Console
10
+
11
+ console = Console()
12
+
13
+
14
+ def manage_mpm_init(args):
15
+ """
16
+ Handle mpm-init command execution.
17
+
18
+ Args:
19
+ args: Parsed command line arguments
20
+
21
+ Returns:
22
+ Exit code (0 for success, non-zero for errors)
23
+ """
24
+ try:
25
+ # Import the command implementation
26
+ from .mpm_init import MPMInitCommand
27
+
28
+ # Handle special flags
29
+ if getattr(args, "list_templates", False):
30
+ # List available templates
31
+ console.print("\n[bold cyan]Available Project Templates:[/bold cyan]")
32
+ console.print(" • web-react: React web application")
33
+ console.print(" • web-vue: Vue.js web application")
34
+ console.print(" • api-fastapi: FastAPI REST API")
35
+ console.print(" • api-django: Django REST framework")
36
+ console.print(" • cli-python: Python CLI application")
37
+ console.print(" • library-python: Python library")
38
+ console.print(" • fullstack-nextjs: Next.js fullstack app")
39
+ console.print(" • ml-pytorch: PyTorch ML project")
40
+ console.print(" • data-pipeline: Data pipeline with ETL")
41
+ console.print()
42
+ return 0
43
+
44
+ # Get project path
45
+ project_path = (
46
+ Path(args.project_path) if hasattr(args, "project_path") else Path.cwd()
47
+ )
48
+
49
+ # Create command instance
50
+ command = MPMInitCommand(project_path)
51
+
52
+ # Prepare initialization parameters
53
+ init_params = {
54
+ "project_type": getattr(args, "project_type", None),
55
+ "framework": getattr(args, "framework", None),
56
+ "force": getattr(args, "force", False),
57
+ "verbose": getattr(args, "verbose", False),
58
+ "use_venv": getattr(args, "use_venv", False),
59
+ }
60
+
61
+ # Execute initialization (now synchronous)
62
+ result = command.initialize_project(**init_params)
63
+
64
+ # Return appropriate exit code
65
+ if result.get("status") == "success":
66
+ return 0
67
+ if result.get("status") == "cancelled":
68
+ return 130 # User cancelled
69
+ return 1 # Error
70
+
71
+ except ImportError as e:
72
+ console.print(f"[red]Error: Required module not available: {e}[/red]")
73
+ console.print("[yellow]Ensure claude-mpm is properly installed[/yellow]")
74
+ return 1
75
+ except KeyboardInterrupt:
76
+ console.print("\n[yellow]Initialization cancelled by user[/yellow]")
77
+ return 130
78
+ except Exception as e:
79
+ console.print(f"[red]Error executing mpm-init: {e}[/red]")
80
+ import traceback
81
+
82
+ if getattr(args, "verbose", False):
83
+ traceback.print_exc()
84
+ return 1
@@ -317,6 +317,13 @@ def create_parser(
317
317
  except ImportError:
318
318
  pass
319
319
 
320
+ try:
321
+ from .dashboard_parser import add_dashboard_subparser
322
+
323
+ add_dashboard_subparser(subparsers)
324
+ except ImportError:
325
+ pass
326
+
320
327
  try:
321
328
  from .mcp_parser import add_mcp_subparser
322
329
 
@@ -367,6 +374,14 @@ def create_parser(
367
374
  except ImportError:
368
375
  pass
369
376
 
377
+ # Add mpm-init command parser
378
+ try:
379
+ from .mpm_init_parser import add_mpm_init_subparser
380
+
381
+ add_mpm_init_subparser(subparsers)
382
+ except ImportError:
383
+ pass
384
+
370
385
  # Import and add additional command parsers from commands module
371
386
  try:
372
387
  from ..commands.aggregate import add_aggregate_parser
@@ -0,0 +1,113 @@
1
+ """
2
+ Dashboard command parser for claude-mpm CLI.
3
+
4
+ WHY: This module contains all arguments specific to dashboard management,
5
+ providing a clean interface for starting, stopping, and managing the web dashboard.
6
+
7
+ DESIGN DECISION: Dashboard commands handle web interface management and
8
+ have their own subcommand structure similar to monitor commands.
9
+ """
10
+
11
+ import argparse
12
+
13
+ from ...constants import CLICommands, DashboardCommands
14
+ from .base_parser import add_common_arguments
15
+
16
+
17
+ def add_dashboard_subparser(subparsers) -> argparse.ArgumentParser:
18
+ """
19
+ Add the dashboard subparser with all dashboard management commands.
20
+
21
+ WHY: Dashboard management has multiple subcommands for starting, stopping,
22
+ checking status, and opening the web interface in a browser.
23
+
24
+ Args:
25
+ subparsers: The subparsers object from the main parser
26
+
27
+ Returns:
28
+ The configured dashboard subparser
29
+ """
30
+ # Dashboard command with subcommands
31
+ dashboard_parser = subparsers.add_parser(
32
+ CLICommands.DASHBOARD.value,
33
+ help="Manage the web dashboard interface for monitoring and analysis",
34
+ )
35
+ add_common_arguments(dashboard_parser)
36
+
37
+ dashboard_subparsers = dashboard_parser.add_subparsers(
38
+ dest="dashboard_command", help="Dashboard commands", metavar="SUBCOMMAND"
39
+ )
40
+
41
+ # Start dashboard
42
+ start_dashboard_parser = dashboard_subparsers.add_parser(
43
+ DashboardCommands.START.value,
44
+ help="Start the web dashboard server",
45
+ )
46
+ start_dashboard_parser.add_argument(
47
+ "--port",
48
+ type=int,
49
+ default=8765,
50
+ help="Port to start dashboard on (default: 8765)",
51
+ )
52
+ start_dashboard_parser.add_argument(
53
+ "--host",
54
+ default="localhost",
55
+ help="Host to bind to (default: localhost)",
56
+ )
57
+ start_dashboard_parser.add_argument(
58
+ "--background",
59
+ action="store_true",
60
+ help="Run dashboard server in background",
61
+ )
62
+ start_dashboard_parser.add_argument(
63
+ "--no-browser",
64
+ action="store_true",
65
+ help="Don't open browser automatically",
66
+ )
67
+
68
+ # Stop dashboard
69
+ stop_dashboard_parser = dashboard_subparsers.add_parser(
70
+ DashboardCommands.STOP.value,
71
+ help="Stop the web dashboard server",
72
+ )
73
+ stop_dashboard_parser.add_argument(
74
+ "--port",
75
+ type=int,
76
+ default=8765,
77
+ help="Port of dashboard to stop (default: 8765)",
78
+ )
79
+ stop_dashboard_parser.add_argument(
80
+ "--all",
81
+ action="store_true",
82
+ help="Stop all running dashboard instances",
83
+ )
84
+
85
+ # Status dashboard
86
+ status_dashboard_parser = dashboard_subparsers.add_parser(
87
+ DashboardCommands.STATUS.value,
88
+ help="Check dashboard server status",
89
+ )
90
+ status_dashboard_parser.add_argument(
91
+ "--verbose",
92
+ action="store_true",
93
+ help="Show detailed status information",
94
+ )
95
+ status_dashboard_parser.add_argument(
96
+ "--show-ports",
97
+ action="store_true",
98
+ help="Show status of all ports in the range (8765-8785)",
99
+ )
100
+
101
+ # Open dashboard
102
+ open_dashboard_parser = dashboard_subparsers.add_parser(
103
+ DashboardCommands.OPEN.value,
104
+ help="Open the dashboard in a web browser (starts if not running)",
105
+ )
106
+ open_dashboard_parser.add_argument(
107
+ "--port",
108
+ type=int,
109
+ default=8765,
110
+ help="Port of dashboard to open (default: 8765)",
111
+ )
112
+
113
+ return dashboard_parser