claude-mpm 5.1.9__py3-none-any.whl → 5.4.14__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.

Potentially problematic release.


This version of claude-mpm might be problematic. Click here for more details.

Files changed (162) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/__init__.py +4 -0
  3. claude_mpm/agents/PM_INSTRUCTIONS.md +85 -0
  4. claude_mpm/agents/agent_loader.py +13 -44
  5. claude_mpm/agents/templates/circuit-breakers.md +138 -1
  6. claude_mpm/cli/__main__.py +4 -0
  7. claude_mpm/cli/commands/agent_state_manager.py +8 -17
  8. claude_mpm/cli/commands/auto_configure.py +210 -25
  9. claude_mpm/cli/commands/config.py +88 -2
  10. claude_mpm/cli/commands/configure.py +1097 -158
  11. claude_mpm/cli/commands/configure_agent_display.py +15 -6
  12. claude_mpm/cli/commands/mpm_init/core.py +160 -46
  13. claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
  14. claude_mpm/cli/commands/mpm_init/prompts.py +280 -0
  15. claude_mpm/cli/commands/skills.py +21 -2
  16. claude_mpm/cli/commands/summarize.py +413 -0
  17. claude_mpm/cli/executor.py +11 -3
  18. claude_mpm/cli/parsers/base_parser.py +5 -0
  19. claude_mpm/cli/parsers/config_parser.py +153 -83
  20. claude_mpm/cli/parsers/skills_parser.py +3 -2
  21. claude_mpm/cli/startup.py +333 -89
  22. claude_mpm/commands/mpm-config.md +266 -0
  23. claude_mpm/commands/{mpm-ticket-organize.md → mpm-organize.md} +4 -5
  24. claude_mpm/config/agent_sources.py +27 -0
  25. claude_mpm/core/framework/formatters/content_formatter.py +3 -13
  26. claude_mpm/core/framework/loaders/agent_loader.py +8 -5
  27. claude_mpm/core/framework_loader.py +4 -2
  28. claude_mpm/core/logger.py +13 -0
  29. claude_mpm/core/socketio_pool.py +3 -3
  30. claude_mpm/core/unified_agent_registry.py +5 -15
  31. claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
  32. claude_mpm/hooks/claude_hooks/event_handlers.py +206 -78
  33. claude_mpm/hooks/claude_hooks/hook_handler.py +6 -0
  34. claude_mpm/hooks/claude_hooks/installer.py +33 -10
  35. claude_mpm/hooks/claude_hooks/memory_integration.py +26 -9
  36. claude_mpm/hooks/claude_hooks/response_tracking.py +2 -3
  37. claude_mpm/hooks/claude_hooks/services/connection_manager.py +4 -0
  38. claude_mpm/hooks/memory_integration_hook.py +46 -1
  39. claude_mpm/init.py +0 -19
  40. claude_mpm/scripts/claude-hook-handler.sh +58 -18
  41. claude_mpm/scripts/launch_monitor.py +93 -13
  42. claude_mpm/services/agents/agent_recommendation_service.py +278 -0
  43. claude_mpm/services/agents/agent_review_service.py +280 -0
  44. claude_mpm/services/agents/deployment/agent_discovery_service.py +2 -3
  45. claude_mpm/services/agents/deployment/agent_template_builder.py +4 -2
  46. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +78 -9
  47. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +335 -53
  48. claude_mpm/services/agents/git_source_manager.py +34 -0
  49. claude_mpm/services/agents/loading/base_agent_manager.py +1 -13
  50. claude_mpm/services/agents/sources/git_source_sync_service.py +8 -1
  51. claude_mpm/services/agents/toolchain_detector.py +10 -6
  52. claude_mpm/services/analysis/__init__.py +11 -1
  53. claude_mpm/services/analysis/clone_detector.py +1030 -0
  54. claude_mpm/services/command_deployment_service.py +71 -10
  55. claude_mpm/services/event_bus/config.py +3 -1
  56. claude_mpm/services/git/git_operations_service.py +93 -8
  57. claude_mpm/services/monitor/daemon.py +9 -2
  58. claude_mpm/services/monitor/daemon_manager.py +39 -3
  59. claude_mpm/services/monitor/server.py +225 -19
  60. claude_mpm/services/self_upgrade_service.py +120 -12
  61. claude_mpm/services/skills/__init__.py +3 -0
  62. claude_mpm/services/skills/git_skill_source_manager.py +32 -2
  63. claude_mpm/services/skills/selective_skill_deployer.py +230 -0
  64. claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
  65. claude_mpm/services/skills_deployer.py +64 -3
  66. claude_mpm/services/socketio/event_normalizer.py +15 -1
  67. claude_mpm/services/socketio/server/core.py +160 -21
  68. claude_mpm/services/version_control/git_operations.py +103 -0
  69. claude_mpm/utils/agent_filters.py +17 -44
  70. {claude_mpm-5.1.9.dist-info → claude_mpm-5.4.14.dist-info}/METADATA +47 -84
  71. {claude_mpm-5.1.9.dist-info → claude_mpm-5.4.14.dist-info}/RECORD +76 -150
  72. claude_mpm-5.4.14.dist-info/entry_points.txt +5 -0
  73. claude_mpm-5.4.14.dist-info/licenses/LICENSE +94 -0
  74. claude_mpm-5.4.14.dist-info/licenses/LICENSE-FAQ.md +153 -0
  75. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -292
  76. claude_mpm/agents/BASE_DOCUMENTATION.md +0 -53
  77. claude_mpm/agents/BASE_ENGINEER.md +0 -658
  78. claude_mpm/agents/BASE_OPS.md +0 -219
  79. claude_mpm/agents/BASE_PM.md +0 -480
  80. claude_mpm/agents/BASE_PROMPT_ENGINEER.md +0 -787
  81. claude_mpm/agents/BASE_QA.md +0 -167
  82. claude_mpm/agents/BASE_RESEARCH.md +0 -53
  83. claude_mpm/agents/base_agent.json +0 -31
  84. claude_mpm/agents/base_agent_loader.py +0 -601
  85. claude_mpm/cli/ticket_cli.py +0 -35
  86. claude_mpm/commands/mpm-config-view.md +0 -150
  87. claude_mpm/dashboard/analysis_runner.py +0 -455
  88. claude_mpm/dashboard/index.html +0 -13
  89. claude_mpm/dashboard/open_dashboard.py +0 -66
  90. claude_mpm/dashboard/static/css/activity.css +0 -1958
  91. claude_mpm/dashboard/static/css/connection-status.css +0 -370
  92. claude_mpm/dashboard/static/css/dashboard.css +0 -4701
  93. claude_mpm/dashboard/static/js/components/activity-tree.js +0 -1871
  94. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +0 -777
  95. claude_mpm/dashboard/static/js/components/agent-inference.js +0 -956
  96. claude_mpm/dashboard/static/js/components/build-tracker.js +0 -333
  97. claude_mpm/dashboard/static/js/components/code-simple.js +0 -857
  98. claude_mpm/dashboard/static/js/components/connection-debug.js +0 -654
  99. claude_mpm/dashboard/static/js/components/diff-viewer.js +0 -891
  100. claude_mpm/dashboard/static/js/components/event-processor.js +0 -542
  101. claude_mpm/dashboard/static/js/components/event-viewer.js +0 -1155
  102. claude_mpm/dashboard/static/js/components/export-manager.js +0 -368
  103. claude_mpm/dashboard/static/js/components/file-change-tracker.js +0 -443
  104. claude_mpm/dashboard/static/js/components/file-change-viewer.js +0 -690
  105. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +0 -724
  106. claude_mpm/dashboard/static/js/components/file-viewer.js +0 -580
  107. claude_mpm/dashboard/static/js/components/hud-library-loader.js +0 -211
  108. claude_mpm/dashboard/static/js/components/hud-manager.js +0 -671
  109. claude_mpm/dashboard/static/js/components/hud-visualizer.js +0 -1718
  110. claude_mpm/dashboard/static/js/components/module-viewer.js +0 -2764
  111. claude_mpm/dashboard/static/js/components/session-manager.js +0 -579
  112. claude_mpm/dashboard/static/js/components/socket-manager.js +0 -368
  113. claude_mpm/dashboard/static/js/components/ui-state-manager.js +0 -749
  114. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +0 -1824
  115. claude_mpm/dashboard/static/js/components/working-directory.js +0 -920
  116. claude_mpm/dashboard/static/js/connection-manager.js +0 -536
  117. claude_mpm/dashboard/static/js/dashboard.js +0 -1914
  118. claude_mpm/dashboard/static/js/extension-error-handler.js +0 -164
  119. claude_mpm/dashboard/static/js/socket-client.js +0 -1474
  120. claude_mpm/dashboard/static/js/tab-isolation-fix.js +0 -185
  121. claude_mpm/dashboard/static/socket.io.min.js +0 -7
  122. claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +0 -7
  123. claude_mpm/dashboard/templates/code_simple.html +0 -153
  124. claude_mpm/dashboard/templates/index.html +0 -606
  125. claude_mpm/dashboard/test_dashboard.html +0 -372
  126. claude_mpm/scripts/mcp_server.py +0 -75
  127. claude_mpm/scripts/mcp_wrapper.py +0 -39
  128. claude_mpm/services/mcp_gateway/__init__.py +0 -159
  129. claude_mpm/services/mcp_gateway/auto_configure.py +0 -369
  130. claude_mpm/services/mcp_gateway/config/__init__.py +0 -17
  131. claude_mpm/services/mcp_gateway/config/config_loader.py +0 -296
  132. claude_mpm/services/mcp_gateway/config/config_schema.py +0 -243
  133. claude_mpm/services/mcp_gateway/config/configuration.py +0 -429
  134. claude_mpm/services/mcp_gateway/core/__init__.py +0 -43
  135. claude_mpm/services/mcp_gateway/core/base.py +0 -312
  136. claude_mpm/services/mcp_gateway/core/exceptions.py +0 -253
  137. claude_mpm/services/mcp_gateway/core/interfaces.py +0 -443
  138. claude_mpm/services/mcp_gateway/core/process_pool.py +0 -977
  139. claude_mpm/services/mcp_gateway/core/singleton_manager.py +0 -315
  140. claude_mpm/services/mcp_gateway/core/startup_verification.py +0 -316
  141. claude_mpm/services/mcp_gateway/main.py +0 -589
  142. claude_mpm/services/mcp_gateway/registry/__init__.py +0 -12
  143. claude_mpm/services/mcp_gateway/registry/service_registry.py +0 -412
  144. claude_mpm/services/mcp_gateway/registry/tool_registry.py +0 -489
  145. claude_mpm/services/mcp_gateway/server/__init__.py +0 -15
  146. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +0 -414
  147. claude_mpm/services/mcp_gateway/server/stdio_handler.py +0 -372
  148. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -712
  149. claude_mpm/services/mcp_gateway/tools/__init__.py +0 -36
  150. claude_mpm/services/mcp_gateway/tools/base_adapter.py +0 -485
  151. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +0 -789
  152. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +0 -654
  153. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +0 -456
  154. claude_mpm/services/mcp_gateway/tools/hello_world.py +0 -551
  155. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +0 -555
  156. claude_mpm/services/mcp_gateway/utils/__init__.py +0 -14
  157. claude_mpm/services/mcp_gateway/utils/package_version_checker.py +0 -160
  158. claude_mpm/services/mcp_gateway/utils/update_preferences.py +0 -170
  159. claude_mpm-5.1.9.dist-info/entry_points.txt +0 -10
  160. claude_mpm-5.1.9.dist-info/licenses/LICENSE +0 -21
  161. {claude_mpm-5.1.9.dist-info → claude_mpm-5.4.14.dist-info}/WHEEL +0 -0
  162. {claude_mpm-5.1.9.dist-info → claude_mpm-5.4.14.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,413 @@
1
+ """
2
+ Document Summarization Command.
3
+
4
+ Shell-based alternative to MCP document_summarizer tool.
5
+ Provides algorithmic summarization without ML dependencies.
6
+
7
+ Design Decision: Uses simple text processing techniques:
8
+ - Brief: First paragraph extraction
9
+ - Detailed: Key sentence extraction based on position and length
10
+ - Bullet Points: Convert to markdown bullet list
11
+ - Executive: Opening + conclusion extraction
12
+
13
+ Why: Lightweight, fast, no dependencies, works offline.
14
+ """
15
+
16
+ import json
17
+ import re
18
+ from enum import Enum
19
+ from pathlib import Path
20
+ from typing import Optional
21
+
22
+
23
+ class SummaryStyle(str, Enum):
24
+ """Summary output styles."""
25
+
26
+ BRIEF = "brief"
27
+ DETAILED = "detailed"
28
+ BULLET_POINTS = "bullet_points"
29
+ EXECUTIVE = "executive"
30
+
31
+
32
+ class OutputFormat(str, Enum):
33
+ """Output format types."""
34
+
35
+ TEXT = "text"
36
+ JSON = "json"
37
+ MARKDOWN = "markdown"
38
+
39
+
40
+ class DocumentSummarizer:
41
+ """
42
+ Algorithmic document summarizer.
43
+
44
+ Design Decision: Use simple heuristics instead of ML:
45
+ - Position-based extraction (opening, closing paragraphs)
46
+ - Length-based filtering (key sentences)
47
+ - Structure detection (headings, lists)
48
+
49
+ Trade-offs:
50
+ - Performance: O(n) single pass vs. complex NLP models
51
+ - Accuracy: ~70% vs. ~90% for ML models
52
+ - Simplicity: Zero dependencies vs. heavy ML packages
53
+ """
54
+
55
+ def __init__(self, max_words: int = 150):
56
+ """Initialize summarizer with word limit."""
57
+ self.max_words = max_words
58
+
59
+ def summarize(
60
+ self, content: str, style: SummaryStyle, lines_limit: Optional[int] = None
61
+ ) -> str:
62
+ """
63
+ Summarize document content.
64
+
65
+ Args:
66
+ content: Document text to summarize
67
+ style: Summary style (brief, detailed, bullet_points, executive)
68
+ lines_limit: Optional line limit (reads first N lines only)
69
+
70
+ Returns:
71
+ Summary text
72
+
73
+ Complexity: O(n) where n is content length
74
+ """
75
+ # Apply line limit if specified
76
+ if lines_limit:
77
+ content = self._limit_lines(content, lines_limit)
78
+
79
+ # Route to style-specific summarizer
80
+ summarizers = {
81
+ SummaryStyle.BRIEF: self._summarize_brief,
82
+ SummaryStyle.DETAILED: self._summarize_detailed,
83
+ SummaryStyle.BULLET_POINTS: self._summarize_bullet_points,
84
+ SummaryStyle.EXECUTIVE: self._summarize_executive,
85
+ }
86
+
87
+ summary = summarizers[style](content)
88
+ return self._truncate_to_word_limit(summary)
89
+
90
+ def _limit_lines(self, content: str, limit: int) -> str:
91
+ """Limit content to first N lines."""
92
+ lines = content.split("\n")
93
+ return "\n".join(lines[:limit])
94
+
95
+ def _truncate_to_word_limit(self, text: str) -> str:
96
+ """Truncate text to max_words limit."""
97
+ words = text.split()
98
+ if len(words) <= self.max_words:
99
+ return text
100
+
101
+ # Truncate and add ellipsis
102
+ truncated = " ".join(words[: self.max_words])
103
+ return f"{truncated}..."
104
+
105
+ def _summarize_brief(self, content: str) -> str:
106
+ """
107
+ Brief summary: Extract first paragraph.
108
+
109
+ Heuristic: First non-empty paragraph usually introduces document.
110
+ """
111
+ paragraphs = self._extract_paragraphs(content)
112
+ if not paragraphs:
113
+ return content.strip()
114
+
115
+ return paragraphs[0]
116
+
117
+ def _summarize_detailed(self, content: str) -> str:
118
+ """
119
+ Detailed summary: Extract key sentences.
120
+
121
+ Heuristics:
122
+ - First paragraph (introduction)
123
+ - Sentences with important markers (however, therefore, important)
124
+ - Last paragraph (conclusion)
125
+ """
126
+ paragraphs = self._extract_paragraphs(content)
127
+ if not paragraphs:
128
+ return content.strip()
129
+
130
+ key_sentences = []
131
+
132
+ # Add first paragraph
133
+ if paragraphs:
134
+ key_sentences.append(paragraphs[0])
135
+
136
+ # Add sentences with key markers from middle paragraphs
137
+ if len(paragraphs) > 2:
138
+ key_markers = [
139
+ "however",
140
+ "therefore",
141
+ "important",
142
+ "note",
143
+ "critical",
144
+ "key",
145
+ "must",
146
+ "should",
147
+ "recommended",
148
+ ]
149
+
150
+ for para in paragraphs[1:-1]:
151
+ sentences = self._split_sentences(para)
152
+ for sentence in sentences:
153
+ if any(marker in sentence.lower() for marker in key_markers):
154
+ key_sentences.append(sentence)
155
+ break # One sentence per paragraph max
156
+
157
+ # Add last paragraph
158
+ if len(paragraphs) > 1:
159
+ key_sentences.append(paragraphs[-1])
160
+
161
+ return " ".join(key_sentences)
162
+
163
+ def _summarize_bullet_points(self, content: str) -> str:
164
+ """
165
+ Bullet point summary: Convert paragraphs to markdown list.
166
+
167
+ Heuristic: Each paragraph becomes a bullet point.
168
+ """
169
+ paragraphs = self._extract_paragraphs(content)
170
+ if not paragraphs:
171
+ return content.strip()
172
+
173
+ # Take key paragraphs (first, middle with markers, last)
174
+ key_paragraphs = []
175
+
176
+ # Always include first
177
+ if paragraphs:
178
+ key_paragraphs.append(paragraphs[0])
179
+
180
+ # Include middle paragraphs with key content
181
+ if len(paragraphs) > 2:
182
+ key_markers = ["however", "therefore", "important", "note", "critical"]
183
+ for para in paragraphs[1:-1]:
184
+ if any(marker in para.lower() for marker in key_markers):
185
+ # Take first sentence only for bullet point
186
+ first_sentence = self._split_sentences(para)[0]
187
+ key_paragraphs.append(first_sentence)
188
+
189
+ # Include last if different from first
190
+ if len(paragraphs) > 1:
191
+ key_paragraphs.append(paragraphs[-1])
192
+
193
+ # Format as markdown bullets
194
+ bullets = [f"- {para}" for para in key_paragraphs]
195
+ return "\n".join(bullets)
196
+
197
+ def _summarize_executive(self, content: str) -> str:
198
+ """
199
+ Executive summary: Opening + conclusion.
200
+
201
+ Heuristic: First and last paragraphs capture overview and conclusion.
202
+ """
203
+ paragraphs = self._extract_paragraphs(content)
204
+ if not paragraphs:
205
+ return content.strip()
206
+
207
+ if len(paragraphs) == 1:
208
+ return paragraphs[0]
209
+
210
+ # Opening paragraph + conclusion paragraph
211
+ return f"{paragraphs[0]}\n\n{paragraphs[-1]}"
212
+
213
+ def _extract_paragraphs(self, content: str) -> list[str]:
214
+ """
215
+ Extract paragraphs from content.
216
+
217
+ Filters out:
218
+ - Empty lines
219
+ - Short lines (< 40 chars, likely headers/formatting artifacts)
220
+ - Code blocks (lines with multiple indentation)
221
+ - Lines that look like code (contain def, class, =, {, etc.)
222
+ """
223
+ # Split on double newlines for paragraph boundaries
224
+ raw_paragraphs = re.split(r"\n\s*\n", content)
225
+
226
+ paragraphs = []
227
+ for para in raw_paragraphs:
228
+ # Clean and normalize whitespace
229
+ para = " ".join(para.split())
230
+
231
+ # Skip empty or very short paragraphs (likely headers)
232
+ if len(para) < 40:
233
+ continue
234
+
235
+ # Skip code blocks (heuristic: contains code-like patterns)
236
+ code_indicators = ["def ", "class ", " = ", "{", "}", "return ", "import "]
237
+ if any(indicator in para for indicator in code_indicators):
238
+ continue
239
+
240
+ paragraphs.append(para)
241
+
242
+ return paragraphs
243
+
244
+ def _split_sentences(self, text: str) -> list[str]:
245
+ """
246
+ Split text into sentences.
247
+
248
+ Simple heuristic: Split on '. ' but handle common abbreviations.
249
+ """
250
+ # Handle common abbreviations to avoid false splits
251
+ text = text.replace("Dr.", "Dr<DOT>")
252
+ text = text.replace("Mr.", "Mr<DOT>")
253
+ text = text.replace("Mrs.", "Mrs<DOT>")
254
+ text = text.replace("e.g.", "e<DOT>g<DOT>")
255
+ text = text.replace("i.e.", "i<DOT>e<DOT>")
256
+
257
+ # Split on sentence boundaries
258
+ sentences = re.split(r"(?<=[.!?])\s+", text)
259
+
260
+ # Restore abbreviations
261
+ sentences = [s.replace("<DOT>", ".") for s in sentences]
262
+
263
+ return [s.strip() for s in sentences if s.strip()]
264
+
265
+
266
+ def format_output(summary: str, output_format: OutputFormat, file_path: Path) -> str:
267
+ """
268
+ Format summary output.
269
+
270
+ Args:
271
+ summary: Summary text
272
+ output_format: Output format (text, json, markdown)
273
+ file_path: Original file path for metadata
274
+
275
+ Returns:
276
+ Formatted output string
277
+ """
278
+ if output_format == OutputFormat.TEXT:
279
+ return summary
280
+
281
+ if output_format == OutputFormat.JSON:
282
+ result = {
283
+ "file": str(file_path),
284
+ "summary": summary,
285
+ "word_count": len(summary.split()),
286
+ }
287
+ return json.dumps(result, indent=2)
288
+
289
+ if output_format == OutputFormat.MARKDOWN:
290
+ return f"# Summary: {file_path.name}\n\n{summary}\n"
291
+
292
+ return summary
293
+
294
+
295
+ def summarize_command(args) -> int:
296
+ """
297
+ Execute summarize command.
298
+
299
+ Args:
300
+ args: Parsed command line arguments with:
301
+ - file_path: Path to file to summarize
302
+ - style: Summary style
303
+ - max_words: Maximum words in summary
304
+ - output: Output format
305
+ - lines: Optional line limit
306
+
307
+ Returns:
308
+ Exit code (0 for success, 1 for error)
309
+ """
310
+ file_path = Path(args.file_path)
311
+
312
+ # Validate file exists
313
+ if not file_path.exists():
314
+ print(f"Error: File not found: {file_path}")
315
+ return 1
316
+
317
+ if not file_path.is_file():
318
+ print(f"Error: Not a file: {file_path}")
319
+ return 1
320
+
321
+ try:
322
+ # Read file content
323
+ content = file_path.read_text(encoding="utf-8")
324
+
325
+ # Create summarizer
326
+ summarizer = DocumentSummarizer(max_words=args.max_words)
327
+
328
+ # Generate summary
329
+ summary = summarizer.summarize(
330
+ content, style=SummaryStyle(args.style), lines_limit=args.lines
331
+ )
332
+
333
+ # Format output
334
+ output = format_output(summary, OutputFormat(args.output), file_path)
335
+
336
+ # Print result
337
+ print(output)
338
+
339
+ return 0
340
+
341
+ except UnicodeDecodeError:
342
+ print(f"Error: Cannot read file (not valid UTF-8): {file_path}")
343
+ return 1
344
+ except Exception as e:
345
+ print(f"Error: {e}")
346
+ return 1
347
+
348
+
349
+ def add_summarize_parser(subparsers) -> None:
350
+ """
351
+ Add summarize subcommand parser.
352
+
353
+ Args:
354
+ subparsers: Subparsers object from argparse
355
+ """
356
+ parser = subparsers.add_parser(
357
+ "summarize",
358
+ help="Summarize document content (shell-based alternative to MCP document_summarizer)",
359
+ description="""
360
+ Algorithmic document summarization without ML dependencies.
361
+
362
+ Styles:
363
+ brief - First paragraph only (quick overview)
364
+ detailed - Key sentences from opening, middle, closing
365
+ bullet_points - Markdown bullet list of key points
366
+ executive - Opening + conclusion (for quick decisions)
367
+
368
+ Examples:
369
+ claude-mpm summarize README.md
370
+ claude-mpm summarize docs/guide.md --style detailed --max-words 200
371
+ claude-mpm summarize src/main.py --style bullet_points --output markdown
372
+ claude-mpm summarize large.txt --lines 100 --style brief
373
+ """,
374
+ formatter_class=lambda prog: __import__("argparse").RawDescriptionHelpFormatter(
375
+ prog, max_help_position=40
376
+ ),
377
+ )
378
+
379
+ # Required arguments
380
+ parser.add_argument("file_path", type=str, help="Path to file to summarize")
381
+
382
+ # Optional arguments
383
+ parser.add_argument(
384
+ "--style",
385
+ type=str,
386
+ choices=["brief", "detailed", "bullet_points", "executive"],
387
+ default="brief",
388
+ help="Summary style (default: brief)",
389
+ )
390
+
391
+ parser.add_argument(
392
+ "--max-words",
393
+ type=int,
394
+ default=150,
395
+ help="Maximum words in summary (default: 150)",
396
+ )
397
+
398
+ parser.add_argument(
399
+ "--output",
400
+ type=str,
401
+ choices=["text", "json", "markdown"],
402
+ default="text",
403
+ help="Output format (default: text)",
404
+ )
405
+
406
+ parser.add_argument(
407
+ "--lines",
408
+ type=int,
409
+ default=None,
410
+ help="Limit to first N lines of file (default: no limit)",
411
+ )
412
+
413
+ parser.set_defaults(command="summarize")
@@ -24,6 +24,7 @@ from .commands import (
24
24
  show_info,
25
25
  )
26
26
  from .commands.analyze_code import manage_analyze_code
27
+ from .commands.config import manage_config
27
28
  from .commands.dashboard import manage_dashboard
28
29
  from .commands.skills import manage_skills
29
30
  from .commands.upgrade import upgrade
@@ -141,6 +142,14 @@ def execute_command(command: str, args) -> int:
141
142
  result = agent_source_command(args)
142
143
  return result if result is not None else 0
143
144
 
145
+ # Handle summarize command with lazy import
146
+ if command == "summarize":
147
+ # Lazy import to avoid loading unless needed
148
+ from .commands.summarize import summarize_command
149
+
150
+ result = summarize_command(args)
151
+ return result if result is not None else 0
152
+
144
153
  # Handle auto-configure command with lazy import
145
154
  if command == "auto-configure":
146
155
  # Lazy import to avoid loading unless needed
@@ -228,9 +237,8 @@ def execute_command(command: str, args) -> int:
228
237
  CLICommands.MEMORY.value: manage_memory,
229
238
  CLICommands.MONITOR.value: manage_monitor,
230
239
  CLICommands.DASHBOARD.value: manage_dashboard,
231
- # Configuration management commands (synonymous)
232
- # Both 'config' and 'configure' launch the interactive configuration TUI
233
- CLICommands.CONFIG.value: manage_configure, # Alias to configure
240
+ # Configuration management commands
241
+ CLICommands.CONFIG.value: manage_config, # Unified config with subcommands
234
242
  CLICommands.CONFIGURE.value: manage_configure, # Interactive configuration TUI
235
243
  CLICommands.AGGREGATE.value: aggregate_command,
236
244
  CLICommands.ANALYZE_CODE.value: manage_analyze_code,
@@ -594,6 +594,11 @@ def create_parser(
594
594
  action="store_true",
595
595
  help="Skip confirmation prompts",
596
596
  )
597
+
598
+ # Add summarize command
599
+ from ..commands.summarize import add_summarize_parser
600
+
601
+ add_summarize_parser(subparsers)
597
602
  except ImportError:
598
603
  # Commands module may not be available during testing or refactoring
599
604
  pass