claude-mpm 4.16.3__py3-none-any.whl → 4.17.1__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 (32) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/commands/mpm-help.md +3 -0
  3. claude_mpm/commands/mpm-version.md +113 -0
  4. claude_mpm/commands/mpm.md +1 -0
  5. claude_mpm/services/version_service.py +104 -1
  6. claude_mpm/skills/bundled/api-documentation.md +393 -0
  7. claude_mpm/skills/bundled/async-testing.md +571 -0
  8. claude_mpm/skills/bundled/code-review.md +143 -0
  9. claude_mpm/skills/bundled/database-migration.md +199 -0
  10. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  11. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  12. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  13. claude_mpm/skills/bundled/git-workflow.md +414 -0
  14. claude_mpm/skills/bundled/imagemagick.md +204 -0
  15. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  16. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  17. claude_mpm/skills/bundled/pdf.md +141 -0
  18. claude_mpm/skills/bundled/performance-profiling.md +567 -0
  19. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  20. claude_mpm/skills/bundled/security-scanning.md +327 -0
  21. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  22. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  23. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  24. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  25. claude_mpm/skills/bundled/xlsx.md +157 -0
  26. claude_mpm/skills/registry.py +97 -9
  27. {claude_mpm-4.16.3.dist-info → claude_mpm-4.17.1.dist-info}/METADATA +7 -2
  28. {claude_mpm-4.16.3.dist-info → claude_mpm-4.17.1.dist-info}/RECORD +32 -11
  29. {claude_mpm-4.16.3.dist-info → claude_mpm-4.17.1.dist-info}/WHEEL +0 -0
  30. {claude_mpm-4.16.3.dist-info → claude_mpm-4.17.1.dist-info}/entry_points.txt +0 -0
  31. {claude_mpm-4.16.3.dist-info → claude_mpm-4.17.1.dist-info}/licenses/LICENSE +0 -0
  32. {claude_mpm-4.16.3.dist-info → claude_mpm-4.17.1.dist-info}/top_level.txt +0 -0
claude_mpm/VERSION CHANGED
@@ -1 +1 @@
1
- 4.16.3
1
+ 4.17.1
@@ -90,6 +90,9 @@ Available Commands:
90
90
  /mpm-monitor [start|stop|restart|status|port]
91
91
  Manage Socket.IO monitoring server and dashboard
92
92
 
93
+ /mpm-version
94
+ Display comprehensive version information including project version, all agents with versions, and all skills with versions
95
+
93
96
  Use '/mpm-help <command>' for detailed help on a specific command.
94
97
  ```
95
98
 
@@ -0,0 +1,113 @@
1
+ # Display Claude MPM Version Information
2
+
3
+ Show comprehensive version information for Claude MPM project, agents, and skills.
4
+
5
+ ## Usage
6
+
7
+ ```
8
+ /mpm-version
9
+ ```
10
+
11
+ ## Description
12
+
13
+ Display version information including:
14
+ - Project version and build number
15
+ - All deployed agents with their versions (grouped by tier: system/user/project)
16
+ - All available skills with their versions (grouped by source: bundled/user/project)
17
+ - Summary statistics
18
+
19
+ ## Implementation
20
+
21
+ When you run `/mpm-version`, the PM will:
22
+
23
+ 1. **Collect Version Information**
24
+ - Use VersionService to gather all version data
25
+ - Project version from pyproject.toml
26
+ - Build number from BUILD_NUMBER file
27
+ - Agent versions from AgentRegistry
28
+ - Skills versions from SkillRegistry
29
+
30
+ 2. **Format Output**
31
+ - Hierarchical display: Project → Agents → Skills
32
+ - Grouped by tier/source for clarity
33
+ - Sorted alphabetically within groups
34
+ - Summary statistics at the end
35
+
36
+ 3. **Display Results**
37
+ - Well-formatted tree structure
38
+ - Easy to scan and read
39
+ - Includes totals and counts
40
+
41
+ ## Example Output
42
+
43
+ ```
44
+ Claude MPM Version Information
45
+ ==============================
46
+
47
+ Project Version: 4.16.3
48
+ Build: 481
49
+
50
+ Agents (35 total)
51
+ -----------------
52
+
53
+ System Agents (30):
54
+ ├─ agent-manager (1.0.0)
55
+ ├─ engineer (3.9.1)
56
+ ├─ research-agent (4.5.1)
57
+ ├─ documentation (2.1.0)
58
+ ├─ qa (2.0.3)
59
+ └─ ... (25 more)
60
+
61
+ User Agents (3):
62
+ ├─ custom-agent (1.0.0)
63
+ ├─ testing-agent (0.5.0)
64
+ └─ prototype-agent (0.1.0)
65
+
66
+ Project Agents (2):
67
+ ├─ project-specific (2.0.0)
68
+ └─ domain-expert (1.1.0)
69
+
70
+ Skills (20 total)
71
+ -----------------
72
+
73
+ Bundled Skills (20):
74
+ ├─ test-driven-development (0.1.0)
75
+ ├─ systematic-debugging (0.1.0)
76
+ ├─ async-testing (0.1.0)
77
+ ├─ performance-profiling (0.1.0)
78
+ ├─ security-scanning (0.1.0)
79
+ └─ ... (15 more)
80
+
81
+ User Skills (0):
82
+ (none)
83
+
84
+ Project Skills (0):
85
+ (none)
86
+
87
+ Summary
88
+ -------
89
+ • Project: v4.16.3 (build 481)
90
+ • Agents: 35 total (30 system, 3 user, 2 project)
91
+ • Skills: 20 total (20 bundled, 0 user, 0 project)
92
+ ```
93
+
94
+ ## PM Implementation Instructions
95
+
96
+ To execute this command, PM should:
97
+
98
+ 1. Import and use VersionService:
99
+ ```python
100
+ from claude_mpm.services.version_service import VersionService
101
+
102
+ service = VersionService()
103
+ summary = service.get_version_summary()
104
+ ```
105
+
106
+ 2. Format output following the example structure above
107
+ 3. Handle missing data gracefully (show "unknown" for missing versions)
108
+ 4. Include all tiers/sources even if counts are zero
109
+
110
+ ## Related Commands
111
+
112
+ - `/mpm-help` - Show all available MPM commands
113
+ - `/mpm-status` - Show system status information
@@ -8,6 +8,7 @@ Available MPM commands:
8
8
  - /mpm-help - Show command help
9
9
  - /mpm-status - Show MPM status
10
10
  - /mpm-config - Manage configuration
11
+ - /mpm-version - Display version information for project, agents, and skills
11
12
 
12
13
  Claude MPM extends Claude Code with:
13
14
  - Multi-agent orchestration
@@ -9,7 +9,7 @@ Extracted from ClaudeRunner to follow Single Responsibility Principle.
9
9
  """
10
10
 
11
11
  from pathlib import Path
12
- from typing import Any, Dict, Optional
12
+ from typing import Any, Dict, List, Optional
13
13
 
14
14
  from claude_mpm.config.paths import paths
15
15
  from claude_mpm.core.base_service import BaseService
@@ -274,3 +274,106 @@ class VersionService(BaseService, VersionServiceInterface):
274
274
  "message": "Update checking not implemented",
275
275
  "checked_at": None,
276
276
  }
277
+
278
+ def get_agents_versions(self) -> Dict[str, List[Dict[str, str]]]:
279
+ """Get all agents grouped by tier with versions.
280
+
281
+ Returns:
282
+ Dict with keys: system, user, project
283
+ Each value is list of agent dicts with: name, version, id
284
+ """
285
+ from claude_mpm.core.unified_agent_registry import get_agent_registry
286
+
287
+ agents_by_tier = {"system": [], "user": [], "project": []}
288
+
289
+ try:
290
+ registry = get_agent_registry()
291
+ all_agents = registry.list_agents()
292
+
293
+ for agent in all_agents:
294
+ agent_info = {
295
+ "name": agent.name,
296
+ "version": agent.version,
297
+ "id": agent.name, # Use name as ID since agent_id doesn't exist
298
+ }
299
+ tier = (
300
+ agent.tier.value
301
+ if hasattr(agent.tier, "value")
302
+ else str(agent.tier)
303
+ )
304
+ if tier in agents_by_tier:
305
+ agents_by_tier[tier].append(agent_info)
306
+ else:
307
+ agents_by_tier["system"].append(agent_info)
308
+
309
+ # Sort each tier alphabetically by name
310
+ for tier, agents in agents_by_tier.items():
311
+ agents.sort(key=lambda x: x["name"])
312
+
313
+ except Exception as e:
314
+ self.logger.error(f"Failed to get agent versions: {e}")
315
+
316
+ return agents_by_tier
317
+
318
+ def get_skills_versions(self) -> Dict[str, List[Dict[str, str]]]:
319
+ """Get all skills grouped by source with versions.
320
+
321
+ Returns:
322
+ Dict with keys: bundled, user, project
323
+ Each value is list of skill dicts with: name, version, description
324
+ """
325
+ from claude_mpm.skills.registry import get_registry
326
+
327
+ skills_by_source = {"bundled": [], "user": [], "project": []}
328
+
329
+ try:
330
+ registry = get_registry()
331
+
332
+ for skill in registry.list_skills():
333
+ skill_info = {
334
+ "name": skill.name,
335
+ "version": skill.version,
336
+ "description": (
337
+ skill.description[:60] + "..."
338
+ if len(skill.description) > 60
339
+ else skill.description
340
+ ),
341
+ }
342
+ source = skill.source if skill.source in skills_by_source else "bundled"
343
+ skills_by_source[source].append(skill_info)
344
+
345
+ # Sort each source alphabetically by name
346
+ for source, skills in skills_by_source.items():
347
+ skills.sort(key=lambda x: x["name"])
348
+
349
+ except Exception as e:
350
+ self.logger.error(f"Failed to get skill versions: {e}")
351
+
352
+ return skills_by_source
353
+
354
+ def get_version_summary(self) -> Dict:
355
+ """Get complete version summary.
356
+
357
+ Returns:
358
+ Dict with project_version, build, agents, skills, and counts
359
+ """
360
+ agents = self.get_agents_versions()
361
+ skills = self.get_skills_versions()
362
+ build = self.get_build_number()
363
+
364
+ return {
365
+ "project_version": self.get_base_version(),
366
+ "build": build,
367
+ "agents": agents,
368
+ "skills": skills,
369
+ "counts": {
370
+ "agents_total": sum(len(v) for v in agents.values()),
371
+ "agents_system": len(agents.get("system", [])),
372
+ "agents_user": len(agents.get("user", [])),
373
+ "agents_project": len(agents.get("project", [])),
374
+ "skills_total": sum(len(v) for v in skills.values()),
375
+ "skills_bundled": len(skills.get("bundled", [])),
376
+ "skills_user": len(skills.get("user", [])),
377
+ "skills_project": len(skills.get("project", [])),
378
+ },
379
+ }
@@ -0,0 +1,393 @@
1
+ ---
2
+ skill_id: api-documentation
3
+ skill_version: 0.1.0
4
+ description: Best practices for documenting APIs and code interfaces, eliminating redundant documentation guidance per agent.
5
+ updated_at: 2025-10-30T17:00:00Z
6
+ tags: [api, documentation, best-practices, interfaces]
7
+ ---
8
+
9
+ # API Documentation
10
+
11
+ Best practices for documenting APIs and code interfaces. Eliminates ~100-150 lines of redundant documentation guidance per agent.
12
+
13
+ ## Core Documentation Principles
14
+
15
+ 1. **Document the why, not just the what** - Explain intent and rationale
16
+ 2. **Keep docs close to code** - Inline documentation stays synchronized
17
+ 3. **Document contracts, not implementation** - Focus on behavior
18
+ 4. **Examples are essential** - Show real usage
19
+ 5. **Update docs with code** - Outdated docs are worse than no docs
20
+
21
+ ## Function/Method Documentation
22
+
23
+ ### Python (Docstrings)
24
+
25
+ ```python
26
+ def calculate_discount(price: float, discount_percent: float) -> float:
27
+ """
28
+ Calculate discounted price with percentage off.
29
+
30
+ Args:
31
+ price: Original price in dollars (must be positive)
32
+ discount_percent: Discount percentage (0-100)
33
+
34
+ Returns:
35
+ Final price after discount, rounded to 2 decimals
36
+
37
+ Raises:
38
+ ValueError: If price is negative or discount > 100
39
+
40
+ Examples:
41
+ >>> calculate_discount(100.0, 20.0)
42
+ 80.0
43
+ >>> calculate_discount(50.0, 50.0)
44
+ 25.0
45
+
46
+ Note:
47
+ Discount percent is capped at 100% (minimum price of 0)
48
+ """
49
+ if price < 0:
50
+ raise ValueError("Price cannot be negative")
51
+ if discount_percent > 100:
52
+ raise ValueError("Discount cannot exceed 100%")
53
+
54
+ discount_amount = price * (discount_percent / 100)
55
+ return round(price - discount_amount, 2)
56
+ ```
57
+
58
+ ### JavaScript (JSDoc)
59
+
60
+ ```javascript
61
+ /**
62
+ * Calculate discounted price with percentage off
63
+ *
64
+ * @param {number} price - Original price in dollars (must be positive)
65
+ * @param {number} discountPercent - Discount percentage (0-100)
66
+ * @returns {number} Final price after discount, rounded to 2 decimals
67
+ * @throws {Error} If price is negative or discount > 100
68
+ *
69
+ * @example
70
+ * calculateDiscount(100.0, 20.0)
71
+ * // returns 80.0
72
+ *
73
+ * @example
74
+ * calculateDiscount(50.0, 50.0)
75
+ * // returns 25.0
76
+ */
77
+ function calculateDiscount(price, discountPercent) {
78
+ if (price < 0) {
79
+ throw new Error('Price cannot be negative');
80
+ }
81
+ if (discountPercent > 100) {
82
+ throw new Error('Discount cannot exceed 100%');
83
+ }
84
+
85
+ const discountAmount = price * (discountPercent / 100);
86
+ return Math.round((price - discountAmount) * 100) / 100;
87
+ }
88
+ ```
89
+
90
+ ### Go (Godoc)
91
+
92
+ ```go
93
+ // CalculateDiscount calculates discounted price with percentage off.
94
+ //
95
+ // The function applies the given discount percentage to the original price
96
+ // and returns the final price rounded to 2 decimal places.
97
+ //
98
+ // Parameters:
99
+ // - price: Original price in dollars (must be positive)
100
+ // - discountPercent: Discount percentage (0-100)
101
+ //
102
+ // Returns the final price after discount.
103
+ //
104
+ // Returns an error if price is negative or discount exceeds 100%.
105
+ //
106
+ // Example:
107
+ //
108
+ // finalPrice, err := CalculateDiscount(100.0, 20.0)
109
+ // // finalPrice = 80.0
110
+ func CalculateDiscount(price, discountPercent float64) (float64, error) {
111
+ if price < 0 {
112
+ return 0, errors.New("price cannot be negative")
113
+ }
114
+ if discountPercent > 100 {
115
+ return 0, errors.New("discount cannot exceed 100%")
116
+ }
117
+
118
+ discountAmount := price * (discountPercent / 100)
119
+ return math.Round((price-discountAmount)*100) / 100, nil
120
+ }
121
+ ```
122
+
123
+ ## API Endpoint Documentation
124
+
125
+ ### REST API (OpenAPI/Swagger)
126
+
127
+ ```yaml
128
+ openapi: 3.0.0
129
+ info:
130
+ title: User Management API
131
+ version: 1.0.0
132
+
133
+ paths:
134
+ /users/{userId}:
135
+ get:
136
+ summary: Get user by ID
137
+ description: Retrieves detailed information for a specific user
138
+ parameters:
139
+ - name: userId
140
+ in: path
141
+ required: true
142
+ schema:
143
+ type: integer
144
+ minimum: 1
145
+ description: Unique user identifier
146
+ responses:
147
+ '200':
148
+ description: User found successfully
149
+ content:
150
+ application/json:
151
+ schema:
152
+ $ref: '#/components/schemas/User'
153
+ example:
154
+ id: 123
155
+ name: "John Doe"
156
+ email: "john@example.com"
157
+ '404':
158
+ description: User not found
159
+ '401':
160
+ description: Unauthorized - authentication required
161
+ ```
162
+
163
+ ### GraphQL
164
+
165
+ ```graphql
166
+ """
167
+ Represents a user in the system
168
+ """
169
+ type User {
170
+ """Unique identifier for the user"""
171
+ id: ID!
172
+
173
+ """User's full name"""
174
+ name: String!
175
+
176
+ """User's email address (validated)"""
177
+ email: String!
178
+
179
+ """User's posts (paginated)"""
180
+ posts(limit: Int = 10, offset: Int = 0): [Post!]!
181
+ }
182
+
183
+ """
184
+ Query a specific user by ID
185
+ """
186
+ type Query {
187
+ """
188
+ Get user by unique identifier
189
+
190
+ Returns null if user not found
191
+ """
192
+ user(id: ID!): User
193
+ }
194
+ ```
195
+
196
+ ## Class/Module Documentation
197
+
198
+ ```python
199
+ class UserManager:
200
+ """
201
+ Manages user accounts and authentication.
202
+
203
+ This class provides a high-level interface for user management
204
+ operations including creation, authentication, and profile updates.
205
+
206
+ Attributes:
207
+ db: Database connection instance
208
+ cache: Redis cache for session management
209
+
210
+ Example:
211
+ >>> manager = UserManager(db=get_db(), cache=get_cache())
212
+ >>> user = manager.create_user("john@example.com", "password")
213
+ >>> authenticated = manager.authenticate("john@example.com", "password")
214
+ >>> authenticated is not None
215
+ True
216
+
217
+ Thread Safety:
218
+ This class is thread-safe. Multiple threads can safely call
219
+ methods concurrently.
220
+
221
+ Note:
222
+ All passwords are automatically hashed using bcrypt before
223
+ storage. Never pass pre-hashed passwords to methods.
224
+ """
225
+
226
+ def __init__(self, db: Database, cache: Cache):
227
+ """
228
+ Initialize UserManager with database and cache.
229
+
230
+ Args:
231
+ db: Database connection for persistent storage
232
+ cache: Redis cache for session management
233
+
234
+ Raises:
235
+ ConnectionError: If unable to connect to database or cache
236
+ """
237
+ self.db = db
238
+ self.cache = cache
239
+ ```
240
+
241
+ ## README Documentation Structure
242
+
243
+ ```markdown
244
+ # Project Name
245
+
246
+ Brief description of what the project does (1-2 sentences).
247
+
248
+ ## Features
249
+
250
+ - Key feature 1
251
+ - Key feature 2
252
+ - Key feature 3
253
+
254
+ ## Installation
255
+
256
+ ```bash
257
+ pip install project-name
258
+ ```
259
+
260
+ ## Quick Start
261
+
262
+ ```python
263
+ from project import MainClass
264
+
265
+ # Simple usage example
266
+ client = MainClass(api_key="your-key")
267
+ result = client.do_something()
268
+ print(result)
269
+ ```
270
+
271
+ ## Configuration
272
+
273
+ | Option | Type | Default | Description |
274
+ |--------|------|---------|-------------|
275
+ | `api_key` | str | None | API authentication key |
276
+ | `timeout` | int | 30 | Request timeout in seconds |
277
+
278
+ ## API Reference
279
+
280
+ See full [API Documentation](docs/api.md)
281
+
282
+ ### Main Methods
283
+
284
+ #### `do_something(param1, param2)`
285
+
286
+ Description of what this does.
287
+
288
+ **Parameters:**
289
+ - `param1` (str): Description of param1
290
+ - `param2` (int): Description of param2
291
+
292
+ **Returns:** Description of return value
293
+
294
+ **Example:**
295
+ ```python
296
+ result = client.do_something("value", 42)
297
+ ```
298
+
299
+ ## Contributing
300
+
301
+ See [CONTRIBUTING.md](CONTRIBUTING.md)
302
+
303
+ ## License
304
+
305
+ MIT License - see [LICENSE](LICENSE)
306
+ ```
307
+
308
+ ## Documentation Anti-Patterns
309
+
310
+ ### ❌ Redundant Comments
311
+
312
+ ```python
313
+ # Bad: Obvious comment adds no value
314
+ i = i + 1 # Increment i
315
+
316
+ # Good: Comment explains WHY
317
+ i = i + 1 # Skip header row
318
+ ```
319
+
320
+ ### ❌ Outdated Documentation
321
+
322
+ ```python
323
+ # Bad: Comment doesn't match code
324
+ def get_users(limit=10): # Comment says: Returns all users
325
+ """Returns all users in the system.""" # But limit is 10!
326
+ return User.query.limit(limit).all()
327
+
328
+ # Good: Keep docs synchronized
329
+ def get_users(limit=10):
330
+ """
331
+ Returns up to 'limit' users from the system.
332
+
333
+ Args:
334
+ limit: Maximum number of users to return (default: 10)
335
+ """
336
+ return User.query.limit(limit).all()
337
+ ```
338
+
339
+ ### ❌ Implementation Documentation
340
+
341
+ ```python
342
+ # Bad: Documents HOW (implementation)
343
+ def sort_users(users):
344
+ """Uses bubble sort algorithm to sort users.""" # Don't care!
345
+ ...
346
+
347
+ # Good: Documents WHAT (contract)
348
+ def sort_users(users):
349
+ """Returns users sorted alphabetically by name."""
350
+ ...
351
+ ```
352
+
353
+ ## Documentation Tools
354
+
355
+ ### Python
356
+ - **Sphinx**: Generate HTML docs from docstrings
357
+ - **pdoc**: Simpler alternative to Sphinx
358
+ - **MkDocs**: Markdown-based documentation
359
+
360
+ ### JavaScript
361
+ - **JSDoc**: Generate HTML from JSDoc comments
362
+ - **TypeDoc**: For TypeScript projects
363
+ - **Docusaurus**: Full documentation websites
364
+
365
+ ### Go
366
+ - **godoc**: Built-in documentation tool
367
+ - **pkgsite**: Go package documentation
368
+
369
+ ### Rust
370
+ - **rustdoc**: Built-in documentation with `cargo doc`
371
+
372
+ ## Quick Documentation Checklist
373
+
374
+ ```
375
+ □ Public APIs have docstrings/comments
376
+ □ Parameters and return values documented
377
+ □ Exceptions/errors documented
378
+ □ Usage examples provided
379
+ □ Edge cases and limitations noted
380
+ □ README includes quick start
381
+ □ API reference available
382
+ □ Configuration options documented
383
+ □ Docs are up to date with code
384
+ □ Breaking changes documented
385
+ ```
386
+
387
+ ## Remember
388
+
389
+ - **Code is read more than written** - Good docs save time
390
+ - **Examples speak louder than descriptions** - Show, don't just tell
391
+ - **The best docs are no docs** - Write self-documenting code
392
+ - **Keep it DRY** - Don't repeat what the code already says
393
+ - **Update docs with code** - Outdated docs mislead developers