claude-mpm 4.1.8__py3-none-any.whl → 4.1.11__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 (111) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/INSTRUCTIONS.md +26 -1
  3. claude_mpm/agents/agents_metadata.py +57 -0
  4. claude_mpm/agents/templates/.claude-mpm/memories/README.md +17 -0
  5. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +3 -0
  6. claude_mpm/agents/templates/agent-manager.json +263 -17
  7. claude_mpm/agents/templates/agentic_coder_optimizer.json +222 -0
  8. claude_mpm/agents/templates/code_analyzer.json +18 -8
  9. claude_mpm/agents/templates/engineer.json +1 -1
  10. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +39 -0
  11. claude_mpm/agents/templates/qa.json +1 -1
  12. claude_mpm/agents/templates/research.json +1 -1
  13. claude_mpm/cli/__init__.py +15 -0
  14. claude_mpm/cli/commands/__init__.py +6 -0
  15. claude_mpm/cli/commands/analyze.py +548 -0
  16. claude_mpm/cli/commands/analyze_code.py +524 -0
  17. claude_mpm/cli/commands/configure.py +78 -28
  18. claude_mpm/cli/commands/configure_tui.py +62 -60
  19. claude_mpm/cli/commands/dashboard.py +288 -0
  20. claude_mpm/cli/commands/debug.py +1386 -0
  21. claude_mpm/cli/commands/mpm_init.py +427 -0
  22. claude_mpm/cli/commands/mpm_init_handler.py +83 -0
  23. claude_mpm/cli/parsers/analyze_code_parser.py +170 -0
  24. claude_mpm/cli/parsers/analyze_parser.py +135 -0
  25. claude_mpm/cli/parsers/base_parser.py +44 -0
  26. claude_mpm/cli/parsers/dashboard_parser.py +113 -0
  27. claude_mpm/cli/parsers/debug_parser.py +319 -0
  28. claude_mpm/cli/parsers/mpm_init_parser.py +122 -0
  29. claude_mpm/constants.py +13 -1
  30. claude_mpm/core/framework_loader.py +148 -6
  31. claude_mpm/core/log_manager.py +16 -13
  32. claude_mpm/core/logger.py +1 -1
  33. claude_mpm/core/unified_agent_registry.py +1 -1
  34. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +1 -0
  35. claude_mpm/dashboard/analysis_runner.py +455 -0
  36. claude_mpm/dashboard/static/built/components/activity-tree.js +2 -0
  37. claude_mpm/dashboard/static/built/components/agent-inference.js +1 -1
  38. claude_mpm/dashboard/static/built/components/code-tree.js +2 -0
  39. claude_mpm/dashboard/static/built/components/code-viewer.js +2 -0
  40. claude_mpm/dashboard/static/built/components/event-viewer.js +1 -1
  41. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +1 -1
  42. claude_mpm/dashboard/static/built/components/module-viewer.js +1 -1
  43. claude_mpm/dashboard/static/built/components/session-manager.js +1 -1
  44. claude_mpm/dashboard/static/built/components/working-directory.js +1 -1
  45. claude_mpm/dashboard/static/built/dashboard.js +1 -1
  46. claude_mpm/dashboard/static/built/socket-client.js +1 -1
  47. claude_mpm/dashboard/static/css/activity.css +549 -0
  48. claude_mpm/dashboard/static/css/code-tree.css +1175 -0
  49. claude_mpm/dashboard/static/css/dashboard.css +245 -0
  50. claude_mpm/dashboard/static/dist/components/activity-tree.js +2 -0
  51. claude_mpm/dashboard/static/dist/components/code-tree.js +2 -0
  52. claude_mpm/dashboard/static/dist/components/code-viewer.js +2 -0
  53. claude_mpm/dashboard/static/dist/components/event-viewer.js +1 -1
  54. claude_mpm/dashboard/static/dist/components/session-manager.js +1 -1
  55. claude_mpm/dashboard/static/dist/components/working-directory.js +1 -1
  56. claude_mpm/dashboard/static/dist/dashboard.js +1 -1
  57. claude_mpm/dashboard/static/dist/socket-client.js +1 -1
  58. claude_mpm/dashboard/static/js/components/activity-tree.js +1338 -0
  59. claude_mpm/dashboard/static/js/components/code-tree.js +2535 -0
  60. claude_mpm/dashboard/static/js/components/code-viewer.js +480 -0
  61. claude_mpm/dashboard/static/js/components/event-viewer.js +59 -9
  62. claude_mpm/dashboard/static/js/components/session-manager.js +40 -4
  63. claude_mpm/dashboard/static/js/components/socket-manager.js +12 -0
  64. claude_mpm/dashboard/static/js/components/ui-state-manager.js +4 -0
  65. claude_mpm/dashboard/static/js/components/working-directory.js +17 -1
  66. claude_mpm/dashboard/static/js/dashboard.js +51 -0
  67. claude_mpm/dashboard/static/js/socket-client.js +465 -29
  68. claude_mpm/dashboard/templates/index.html +182 -4
  69. claude_mpm/hooks/claude_hooks/hook_handler.py +182 -5
  70. claude_mpm/hooks/claude_hooks/installer.py +386 -113
  71. claude_mpm/scripts/claude-hook-handler.sh +161 -0
  72. claude_mpm/scripts/socketio_daemon.py +121 -8
  73. claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +2 -2
  74. claude_mpm/services/agents/deployment/agent_record_service.py +1 -2
  75. claude_mpm/services/agents/memory/memory_format_service.py +1 -3
  76. claude_mpm/services/cli/agent_cleanup_service.py +1 -5
  77. claude_mpm/services/cli/agent_dependency_service.py +1 -1
  78. claude_mpm/services/cli/agent_validation_service.py +3 -4
  79. claude_mpm/services/cli/dashboard_launcher.py +2 -3
  80. claude_mpm/services/cli/startup_checker.py +0 -11
  81. claude_mpm/services/core/cache_manager.py +1 -3
  82. claude_mpm/services/core/path_resolver.py +1 -4
  83. claude_mpm/services/core/service_container.py +2 -2
  84. claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
  85. claude_mpm/services/infrastructure/monitoring/__init__.py +11 -11
  86. claude_mpm/services/infrastructure/monitoring.py +11 -11
  87. claude_mpm/services/project/architecture_analyzer.py +1 -1
  88. claude_mpm/services/project/dependency_analyzer.py +4 -4
  89. claude_mpm/services/project/language_analyzer.py +3 -3
  90. claude_mpm/services/project/metrics_collector.py +3 -6
  91. claude_mpm/services/socketio/event_normalizer.py +64 -0
  92. claude_mpm/services/socketio/handlers/__init__.py +2 -0
  93. claude_mpm/services/socketio/handlers/code_analysis.py +672 -0
  94. claude_mpm/services/socketio/handlers/registry.py +2 -0
  95. claude_mpm/services/socketio/server/connection_manager.py +6 -4
  96. claude_mpm/services/socketio/server/core.py +100 -11
  97. claude_mpm/services/socketio/server/main.py +8 -2
  98. claude_mpm/services/visualization/__init__.py +19 -0
  99. claude_mpm/services/visualization/mermaid_generator.py +938 -0
  100. claude_mpm/tools/__main__.py +208 -0
  101. claude_mpm/tools/code_tree_analyzer.py +1596 -0
  102. claude_mpm/tools/code_tree_builder.py +631 -0
  103. claude_mpm/tools/code_tree_events.py +416 -0
  104. claude_mpm/tools/socketio_debug.py +671 -0
  105. {claude_mpm-4.1.8.dist-info → claude_mpm-4.1.11.dist-info}/METADATA +2 -1
  106. {claude_mpm-4.1.8.dist-info → claude_mpm-4.1.11.dist-info}/RECORD +110 -74
  107. claude_mpm/agents/schema/agent_schema.json +0 -314
  108. {claude_mpm-4.1.8.dist-info → claude_mpm-4.1.11.dist-info}/WHEEL +0 -0
  109. {claude_mpm-4.1.8.dist-info → claude_mpm-4.1.11.dist-info}/entry_points.txt +0 -0
  110. {claude_mpm-4.1.8.dist-info → claude_mpm-4.1.11.dist-info}/licenses/LICENSE +0 -0
  111. {claude_mpm-4.1.8.dist-info → claude_mpm-4.1.11.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,427 @@
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 json
9
+ import logging
10
+ import subprocess
11
+ import sys
12
+ from pathlib import Path
13
+ from typing import Dict, List, Optional
14
+
15
+ import click
16
+ from rich.console import Console
17
+ from rich.panel import Panel
18
+ from rich.progress import Progress, SpinnerColumn, TextColumn
19
+
20
+ logger = logging.getLogger(__name__)
21
+ console = Console()
22
+
23
+
24
+ class MPMInitCommand:
25
+ """Initialize projects for optimal Claude Code and Claude MPM usage."""
26
+
27
+ def __init__(self, project_path: Path = None):
28
+ """Initialize the MPM-Init command."""
29
+ self.project_path = project_path or Path.cwd()
30
+ self.claude_mpm_script = self._find_claude_mpm_script()
31
+
32
+ def initialize_project(
33
+ self,
34
+ project_type: Optional[str] = None,
35
+ framework: Optional[str] = None,
36
+ force: bool = False,
37
+ verbose: bool = False,
38
+ use_venv: bool = False
39
+ ) -> Dict:
40
+ """
41
+ Initialize project with Agentic Coder Optimizer standards.
42
+
43
+ Args:
44
+ project_type: Type of project (web, api, cli, library, etc.)
45
+ framework: Specific framework if applicable
46
+ force: Force initialization even if project already configured
47
+ verbose: Show detailed output
48
+
49
+ Returns:
50
+ Dict containing initialization results
51
+ """
52
+ try:
53
+ # Check if project already initialized
54
+ claude_md = self.project_path / "CLAUDE.md"
55
+ if claude_md.exists() and not force:
56
+ console.print(
57
+ "[yellow]⚠️ Project already has CLAUDE.md file.[/yellow]"
58
+ )
59
+ console.print("[yellow]Use --force to reinitialize the project.[/yellow]")
60
+ return {"status": "cancelled", "message": "Initialization cancelled"}
61
+
62
+ # Build the delegation prompt
63
+ prompt = self._build_initialization_prompt(project_type, framework)
64
+
65
+ # Show initialization plan
66
+ console.print(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
+ # Execute via claude-mpm run command
81
+ with Progress(
82
+ SpinnerColumn(),
83
+ TextColumn("[progress.description]{task.description}"),
84
+ console=console,
85
+ ) as progress:
86
+ task = progress.add_task("[cyan]Delegating to Agentic Coder Optimizer...", total=None)
87
+
88
+ # Run the initialization through subprocess
89
+ result = self._run_initialization(prompt, verbose, use_venv)
90
+
91
+ progress.update(task, description="[green]✓ Initialization complete")
92
+
93
+ return result
94
+
95
+ except Exception as e:
96
+ logger.error(f"Failed to initialize project: {e}")
97
+ console.print(f"[red]❌ Error: {e}[/red]")
98
+ return {"status": "error", "message": str(e)}
99
+
100
+ def _find_claude_mpm_script(self) -> Path:
101
+ """Find the claude-mpm script location."""
102
+ # Try to find claude-mpm in the project scripts directory first
103
+ project_root = Path(__file__).parent.parent.parent.parent.parent
104
+ script_path = project_root / "scripts" / "claude-mpm"
105
+ if script_path.exists():
106
+ return script_path
107
+ # Otherwise assume it's in PATH
108
+ return Path("claude-mpm")
109
+
110
+ def _build_initialization_prompt(
111
+ self,
112
+ project_type: Optional[str] = None,
113
+ framework: Optional[str] = None
114
+ ) -> str:
115
+ """Build the initialization prompt for the agent."""
116
+ base_prompt = f"""Please delegate this task to the Agentic Coder Optimizer agent:
117
+
118
+ Initialize this project for optimal use with Claude Code and Claude MPM.
119
+
120
+ Project Path: {self.project_path}
121
+ """
122
+
123
+ if project_type:
124
+ base_prompt += f"Project Type: {project_type}\n"
125
+
126
+ if framework:
127
+ base_prompt += f"Framework: {framework}\n"
128
+
129
+ base_prompt += """
130
+ Please perform the following initialization tasks:
131
+
132
+ 1. **Analyze Current State**:
133
+ - Scan project structure and existing configurations
134
+ - Identify project type, language, and frameworks
135
+ - Check for existing documentation and tooling
136
+
137
+ 2. **Create/Update CLAUDE.md**:
138
+ - Project overview and purpose
139
+ - Architecture and key components
140
+ - Development guidelines
141
+ - ONE clear way to: build, test, deploy, lint, format
142
+ - Links to all relevant documentation
143
+ - Common tasks and workflows
144
+
145
+ 3. **Establish Single-Path Standards**:
146
+ - ONE command for each operation (build, test, lint, etc.)
147
+ - Clear documentation of THE way to do things
148
+ - Remove ambiguity in workflows
149
+
150
+ 4. **Configure Development Tools**:
151
+ - Set up or verify linting configuration
152
+ - Configure code formatting standards
153
+ - Establish testing framework
154
+ - Add pre-commit hooks if needed
155
+
156
+ 5. **Create Project Structure Documentation**:
157
+ - Document folder organization
158
+ - Explain where different file types belong
159
+ - Provide examples of proper file placement
160
+
161
+ 6. **Set Up GitHub Integration** (if applicable):
162
+ - Create/update .github/workflows
163
+ - Add issue and PR templates
164
+ - Configure branch protection rules documentation
165
+
166
+ 7. **Initialize Memory System**:
167
+ - Create .claude-mpm/memories/ directory
168
+ - Add initial memory files for key project knowledge
169
+ - Document memory usage patterns
170
+
171
+ 8. **Generate Quick Start Guide**:
172
+ - Step-by-step setup instructions
173
+ - Common commands reference
174
+ - Troubleshooting guide
175
+
176
+ Please ensure all documentation is clear, concise, and optimized for AI agents to understand and follow.
177
+ Focus on establishing ONE clear way to do ANYTHING in the project.
178
+ """
179
+
180
+ return base_prompt
181
+
182
+ def _build_claude_mpm_command(self, verbose: bool, use_venv: bool = False) -> List[str]:
183
+ """Build the claude-mpm run command with appropriate arguments."""
184
+ cmd = [str(self.claude_mpm_script)]
185
+
186
+ # Add venv flag if requested or if mamba issues detected
187
+ # This goes BEFORE the subcommand
188
+ if use_venv:
189
+ cmd.append("--use-venv")
190
+
191
+ # Add top-level flags that go before 'run' subcommand
192
+ cmd.append("--no-check-dependencies")
193
+
194
+ # Now add the run subcommand
195
+ cmd.append("run")
196
+
197
+ # Add non-interactive mode
198
+ # We'll pass the prompt via stdin instead of -i flag
199
+ cmd.append("--non-interactive")
200
+
201
+ # Add verbose flag if requested (run subcommand argument)
202
+ if verbose:
203
+ cmd.append("--verbose")
204
+
205
+ return cmd
206
+
207
+ def _run_initialization(self, prompt: str, verbose: bool, use_venv: bool = False) -> Dict:
208
+ """Run the initialization through subprocess calling claude-mpm."""
209
+ import tempfile
210
+
211
+ try:
212
+ # Write prompt to temporary file
213
+ with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as tmp_file:
214
+ tmp_file.write(prompt)
215
+ prompt_file = tmp_file.name
216
+
217
+ try:
218
+ # Build the command
219
+ cmd = self._build_claude_mpm_command(verbose, use_venv)
220
+ # Add the input file flag
221
+ cmd.extend(["-i", prompt_file])
222
+
223
+ # Log the command if verbose
224
+ if verbose:
225
+ console.print(f"[dim]Running: {' '.join(cmd)}[/dim]")
226
+ console.print(f"[dim]Prompt file: {prompt_file}[/dim]")
227
+
228
+ # Execute the command
229
+ result = subprocess.run(
230
+ cmd,
231
+ capture_output=True,
232
+ text=True,
233
+ cwd=str(self.project_path)
234
+ )
235
+
236
+ # Check for environment-specific errors
237
+ if "libmamba" in result.stderr or "tree-sitter" in result.stderr:
238
+ console.print("\n[yellow]⚠️ Environment dependency issue detected.[/yellow]")
239
+ console.print("[yellow]Attempting alternative initialization method...[/yellow]\n")
240
+
241
+ # Try again with venv flag to bypass mamba
242
+ cmd_venv = self._build_claude_mpm_command(verbose, use_venv=True)
243
+ cmd_venv.extend(["-i", prompt_file])
244
+
245
+ if verbose:
246
+ console.print(f"[dim]Retrying with: {' '.join(cmd_venv)}[/dim]")
247
+
248
+ result = subprocess.run(
249
+ cmd_venv,
250
+ capture_output=not verbose,
251
+ text=True,
252
+ cwd=str(self.project_path)
253
+ )
254
+ finally:
255
+ # Clean up temporary file
256
+ import os
257
+ try:
258
+ os.unlink(prompt_file)
259
+ except:
260
+ pass
261
+
262
+ # Display output if verbose
263
+ if verbose and result.stdout:
264
+ console.print(result.stdout)
265
+ if verbose and result.stderr:
266
+ console.print(f"[yellow]{result.stderr}[/yellow]")
267
+
268
+ # Check result - be more lenient with return codes
269
+ if result.returncode == 0 or (self.project_path / "CLAUDE.md").exists():
270
+ response = {
271
+ "status": "success",
272
+ "message": "Project initialized successfully",
273
+ "files_created": [],
274
+ "files_updated": [],
275
+ "next_steps": []
276
+ }
277
+
278
+ # Check if CLAUDE.md was created
279
+ claude_md = self.project_path / "CLAUDE.md"
280
+ if claude_md.exists():
281
+ response["files_created"].append("CLAUDE.md")
282
+
283
+ # Check for other common files
284
+ for file_name in ["CODE.md", "DEVELOPER.md", "STRUCTURE.md", "OPS.md"]:
285
+ file_path = self.project_path / file_name
286
+ if file_path.exists():
287
+ response["files_created"].append(file_name)
288
+
289
+ # Add next steps
290
+ response["next_steps"] = [
291
+ "Review the generated CLAUDE.md documentation",
292
+ "Verify the project structure meets your needs",
293
+ "Run 'claude-mpm run' to start using the optimized setup"
294
+ ]
295
+
296
+ # Display results
297
+ self._display_results(response, verbose)
298
+
299
+ return response
300
+ else:
301
+ # Extract meaningful error message
302
+ error_msg = result.stderr if result.stderr else result.stdout if result.stdout else "Unknown error occurred"
303
+ # Clean up mamba warnings from error message
304
+ if "libmamba" in error_msg:
305
+ lines = error_msg.split('\n')
306
+ error_lines = [l for l in lines if not l.startswith('warning') and l.strip()]
307
+ error_msg = '\n'.join(error_lines) if error_lines else error_msg
308
+
309
+ logger.error(f"claude-mpm run failed: {error_msg}")
310
+ return {
311
+ "status": "error",
312
+ "message": f"Initialization failed: {error_msg}"
313
+ }
314
+
315
+ except FileNotFoundError:
316
+ logger.error("claude-mpm command not found")
317
+ console.print("[red]Error: claude-mpm command not found. Ensure Claude MPM is properly installed.[/red]")
318
+ return {"status": "error", "message": "claude-mpm not found"}
319
+ except Exception as e:
320
+ logger.error(f"Initialization failed: {e}")
321
+ return {"status": "error", "message": str(e)}
322
+
323
+ def _display_results(self, result: Dict, verbose: bool):
324
+ """Display initialization results."""
325
+ if result["status"] == "success":
326
+ console.print("\n[green]✅ Project Initialization Complete![/green]\n")
327
+
328
+ if result.get("files_created"):
329
+ console.print("[bold]Files Created:[/bold]")
330
+ for file in result["files_created"]:
331
+ console.print(f" • {file}")
332
+ console.print()
333
+
334
+ if result.get("files_updated"):
335
+ console.print("[bold]Files Updated:[/bold]")
336
+ for file in result["files_updated"]:
337
+ console.print(f" • {file}")
338
+ console.print()
339
+
340
+ if result.get("next_steps"):
341
+ console.print("[bold]Next Steps:[/bold]")
342
+ for step in result["next_steps"]:
343
+ console.print(f" → {step}")
344
+ console.print()
345
+
346
+ console.print(Panel(
347
+ "[green]Your project is now optimized for Claude Code and Claude MPM![/green]\n\n"
348
+ "Key files:\n"
349
+ "• [cyan]CLAUDE.md[/cyan] - Main documentation for AI agents\n"
350
+ "• [cyan].claude-mpm/[/cyan] - Configuration and memories\n\n"
351
+ "[dim]Run 'claude-mpm run' to start using the optimized setup[/dim]",
352
+ title="Success",
353
+ border_style="green"
354
+ ))
355
+
356
+
357
+ @click.command(name="mpm-init")
358
+ @click.option(
359
+ "--project-type",
360
+ type=click.Choice(["web", "api", "cli", "library", "mobile", "desktop", "fullstack"]),
361
+ help="Type of project to initialize"
362
+ )
363
+ @click.option(
364
+ "--framework",
365
+ type=str,
366
+ help="Specific framework (e.g., react, django, fastapi, express)"
367
+ )
368
+ @click.option(
369
+ "--force",
370
+ is_flag=True,
371
+ help="Force reinitialization even if project is already configured"
372
+ )
373
+ @click.option(
374
+ "--verbose",
375
+ is_flag=True,
376
+ help="Show detailed output during initialization"
377
+ )
378
+ @click.argument(
379
+ "project_path",
380
+ type=click.Path(exists=True, file_okay=False, dir_okay=True),
381
+ required=False,
382
+ default="."
383
+ )
384
+ def mpm_init(project_type, framework, force, verbose, project_path):
385
+ """
386
+ Initialize a project for optimal use with Claude Code and Claude MPM.
387
+
388
+ This command uses the Agentic Coder Optimizer agent to:
389
+ - Create comprehensive CLAUDE.md documentation
390
+ - Establish single-path workflows (ONE way to do ANYTHING)
391
+ - Configure development tools and standards
392
+ - Set up memory systems for project knowledge
393
+ - Optimize for AI agent understanding
394
+
395
+ Examples:
396
+ claude-mpm mpm-init
397
+ claude-mpm mpm-init --project-type web --framework react
398
+ claude-mpm mpm-init /path/to/project --force
399
+ """
400
+ try:
401
+ # Create command instance
402
+ command = MPMInitCommand(Path(project_path))
403
+
404
+ # Run initialization (now synchronous)
405
+ result = command.initialize_project(
406
+ project_type=project_type,
407
+ framework=framework,
408
+ force=force,
409
+ verbose=verbose
410
+ )
411
+
412
+ # Exit with appropriate code
413
+ if result["status"] == "success":
414
+ sys.exit(0)
415
+ else:
416
+ sys.exit(1)
417
+
418
+ except KeyboardInterrupt:
419
+ console.print("\n[yellow]Initialization cancelled by user[/yellow]")
420
+ sys.exit(130)
421
+ except Exception as e:
422
+ console.print(f"[red]Initialization failed: {e}[/red]")
423
+ sys.exit(1)
424
+
425
+
426
+ # Export for CLI registration
427
+ __all__ = ["mpm_init"]
@@ -0,0 +1,83 @@
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
+ import sys
8
+ from pathlib import Path
9
+
10
+ from rich.console import Console
11
+
12
+ console = Console()
13
+
14
+
15
+ def manage_mpm_init(args):
16
+ """
17
+ Handle mpm-init command execution.
18
+
19
+ Args:
20
+ args: Parsed command line arguments
21
+
22
+ Returns:
23
+ Exit code (0 for success, non-zero for errors)
24
+ """
25
+ try:
26
+ # Import the command implementation
27
+ from .mpm_init import MPMInitCommand
28
+
29
+ # Handle special flags
30
+ if getattr(args, 'list_templates', False):
31
+ # List available templates
32
+ console.print("\n[bold cyan]Available Project Templates:[/bold cyan]")
33
+ console.print(" • web-react: React web application")
34
+ console.print(" • web-vue: Vue.js web application")
35
+ console.print(" • api-fastapi: FastAPI REST API")
36
+ console.print(" • api-django: Django REST framework")
37
+ console.print(" • cli-python: Python CLI application")
38
+ console.print(" • library-python: Python library")
39
+ console.print(" • fullstack-nextjs: Next.js fullstack app")
40
+ console.print(" • ml-pytorch: PyTorch ML project")
41
+ console.print(" • data-pipeline: Data pipeline with ETL")
42
+ console.print()
43
+ return 0
44
+
45
+ # Get project path
46
+ project_path = Path(args.project_path) if hasattr(args, 'project_path') else Path.cwd()
47
+
48
+ # Create command instance
49
+ command = MPMInitCommand(project_path)
50
+
51
+ # Prepare initialization parameters
52
+ init_params = {
53
+ 'project_type': getattr(args, 'project_type', None),
54
+ 'framework': getattr(args, 'framework', None),
55
+ 'force': getattr(args, 'force', False),
56
+ 'verbose': getattr(args, 'verbose', False),
57
+ 'use_venv': getattr(args, 'use_venv', False),
58
+ }
59
+
60
+ # Execute initialization (now synchronous)
61
+ result = command.initialize_project(**init_params)
62
+
63
+ # Return appropriate exit code
64
+ if result.get('status') == 'success':
65
+ return 0
66
+ elif result.get('status') == 'cancelled':
67
+ return 130 # User cancelled
68
+ else:
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
+ if getattr(args, 'verbose', False):
82
+ traceback.print_exc()
83
+ return 1
@@ -0,0 +1,170 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Analyze Code Parser
4
+ ===================
5
+
6
+ WHY: Provides argument parsing for the analyze-code command,
7
+ defining available options and their validation.
8
+
9
+ DESIGN DECISIONS:
10
+ - Support multiple output formats for flexibility
11
+ - Enable Socket.IO event emission for dashboard integration
12
+ - Allow language and pattern filtering
13
+ - Include caching control options
14
+ """
15
+
16
+ import argparse
17
+ from pathlib import Path
18
+ from typing import Optional
19
+
20
+
21
+ class AnalyzeCodeParser:
22
+ """Parser for analyze-code command arguments.
23
+
24
+ WHY: Centralizes argument definition and validation for the
25
+ code analysis command, ensuring consistent interface.
26
+ """
27
+
28
+ def __init__(self):
29
+ self.command_name = "analyze-code"
30
+ self.help_text = "Analyze code structure and generate AST tree with metrics"
31
+
32
+ def add_arguments(self, parser: argparse.ArgumentParser) -> None:
33
+ """Add analyze-code specific arguments.
34
+
35
+ Args:
36
+ parser: Argument parser to configure
37
+ """
38
+ # Required arguments
39
+ parser.add_argument(
40
+ "path",
41
+ type=str,
42
+ default=".",
43
+ nargs="?",
44
+ help="Path to analyze (default: current directory)",
45
+ )
46
+
47
+ # Output options
48
+ output_group = parser.add_argument_group("output options")
49
+ output_group.add_argument(
50
+ "-o",
51
+ "--output",
52
+ choices=["json", "tree", "stats"],
53
+ help="Output format (default: summary)",
54
+ )
55
+ output_group.add_argument(
56
+ "--save", type=str, metavar="PATH", help="Save analysis results to file"
57
+ )
58
+ output_group.add_argument(
59
+ "--emit-events",
60
+ action="store_true",
61
+ help="Emit real-time events to dashboard via Socket.IO",
62
+ )
63
+
64
+ # Filter options
65
+ filter_group = parser.add_argument_group("filter options")
66
+ filter_group.add_argument(
67
+ "-l",
68
+ "--languages",
69
+ type=str,
70
+ metavar="LANGS",
71
+ help="Comma-separated list of languages to analyze (e.g., python,javascript)",
72
+ )
73
+ filter_group.add_argument(
74
+ "-i",
75
+ "--ignore",
76
+ type=str,
77
+ metavar="PATTERNS",
78
+ help="Comma-separated list of patterns to ignore",
79
+ )
80
+ filter_group.add_argument(
81
+ "--max-depth",
82
+ type=int,
83
+ metavar="N",
84
+ help="Maximum directory depth to traverse",
85
+ )
86
+ filter_group.add_argument(
87
+ "--no-tree", action="store_true", help="Skip file tree building phase"
88
+ )
89
+
90
+ # Performance options
91
+ perf_group = parser.add_argument_group("performance options")
92
+ perf_group.add_argument(
93
+ "--no-cache",
94
+ action="store_true",
95
+ help="Disable caching of analysis results",
96
+ )
97
+ perf_group.add_argument(
98
+ "--parallel",
99
+ action="store_true",
100
+ help="Use parallel processing for large codebases",
101
+ )
102
+
103
+ # Metric options
104
+ metric_group = parser.add_argument_group("metric options")
105
+ metric_group.add_argument(
106
+ "--complexity-threshold",
107
+ type=int,
108
+ default=10,
109
+ metavar="N",
110
+ help="Complexity threshold for warnings (default: 10)",
111
+ )
112
+ metric_group.add_argument(
113
+ "--include-metrics",
114
+ action="store_true",
115
+ help="Include detailed metrics in output",
116
+ )
117
+
118
+ # Note: --verbose and --debug are already defined in base_parser
119
+ # so we don't add them here to avoid conflicts
120
+
121
+ def validate_args(self, args: argparse.Namespace) -> Optional[str]:
122
+ """Validate parsed arguments.
123
+
124
+ Args:
125
+ args: Parsed arguments
126
+
127
+ Returns:
128
+ Error message if validation fails, None otherwise
129
+ """
130
+ # Validate path
131
+ path = Path(args.path)
132
+ if not path.exists():
133
+ return f"Path does not exist: {path}"
134
+
135
+ if not path.is_dir():
136
+ return f"Path is not a directory: {path}"
137
+
138
+ # Validate save path if provided
139
+ if args.save:
140
+ save_path = Path(args.save)
141
+ save_dir = save_path.parent
142
+ if not save_dir.exists():
143
+ return f"Save directory does not exist: {save_dir}"
144
+
145
+ # Validate max depth
146
+ if args.max_depth is not None and args.max_depth < 0:
147
+ return "Max depth must be non-negative"
148
+
149
+ # Validate complexity threshold
150
+ if args.complexity_threshold < 1:
151
+ return "Complexity threshold must be at least 1"
152
+
153
+ return None
154
+
155
+ def get_examples(self) -> list:
156
+ """Get usage examples.
157
+
158
+ Returns:
159
+ List of example command strings
160
+ """
161
+ return [
162
+ "claude-mpm analyze-code",
163
+ "claude-mpm analyze-code /path/to/project",
164
+ "claude-mpm analyze-code -l python,javascript",
165
+ "claude-mpm analyze-code --output json --save analysis.json",
166
+ "claude-mpm analyze-code --emit-events",
167
+ "claude-mpm analyze-code --ignore test,vendor --max-depth 3",
168
+ "claude-mpm analyze-code -o tree",
169
+ "claude-mpm analyze-code -o stats --include-metrics",
170
+ ]