claude-mpm 4.15.2__py3-none-any.whl → 4.20.3__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 (203) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_ENGINEER.md +286 -0
  3. claude_mpm/agents/BASE_PM.md +255 -23
  4. claude_mpm/agents/PM_INSTRUCTIONS.md +40 -0
  5. claude_mpm/agents/agent_loader.py +4 -4
  6. claude_mpm/agents/templates/agentic-coder-optimizer.json +9 -2
  7. claude_mpm/agents/templates/api_qa.json +7 -1
  8. claude_mpm/agents/templates/clerk-ops.json +8 -1
  9. claude_mpm/agents/templates/code_analyzer.json +4 -1
  10. claude_mpm/agents/templates/dart_engineer.json +11 -1
  11. claude_mpm/agents/templates/data_engineer.json +11 -1
  12. claude_mpm/agents/templates/documentation.json +6 -1
  13. claude_mpm/agents/templates/engineer.json +18 -1
  14. claude_mpm/agents/templates/gcp_ops_agent.json +8 -1
  15. claude_mpm/agents/templates/golang_engineer.json +11 -1
  16. claude_mpm/agents/templates/java_engineer.json +12 -2
  17. claude_mpm/agents/templates/local_ops_agent.json +216 -37
  18. claude_mpm/agents/templates/nextjs_engineer.json +11 -1
  19. claude_mpm/agents/templates/ops.json +8 -1
  20. claude_mpm/agents/templates/php-engineer.json +11 -1
  21. claude_mpm/agents/templates/project_organizer.json +9 -2
  22. claude_mpm/agents/templates/prompt-engineer.json +5 -1
  23. claude_mpm/agents/templates/python_engineer.json +19 -4
  24. claude_mpm/agents/templates/qa.json +7 -1
  25. claude_mpm/agents/templates/react_engineer.json +11 -1
  26. claude_mpm/agents/templates/refactoring_engineer.json +8 -1
  27. claude_mpm/agents/templates/research.json +4 -1
  28. claude_mpm/agents/templates/ruby-engineer.json +11 -1
  29. claude_mpm/agents/templates/rust_engineer.json +23 -8
  30. claude_mpm/agents/templates/security.json +6 -1
  31. claude_mpm/agents/templates/svelte-engineer.json +225 -0
  32. claude_mpm/agents/templates/ticketing.json +6 -1
  33. claude_mpm/agents/templates/typescript_engineer.json +11 -1
  34. claude_mpm/agents/templates/vercel_ops_agent.json +8 -1
  35. claude_mpm/agents/templates/version_control.json +8 -1
  36. claude_mpm/agents/templates/web_qa.json +7 -1
  37. claude_mpm/agents/templates/web_ui.json +11 -1
  38. claude_mpm/cli/commands/__init__.py +2 -0
  39. claude_mpm/cli/commands/configure.py +164 -16
  40. claude_mpm/cli/commands/configure_agent_display.py +6 -6
  41. claude_mpm/cli/commands/configure_behavior_manager.py +8 -8
  42. claude_mpm/cli/commands/configure_navigation.py +20 -18
  43. claude_mpm/cli/commands/configure_startup_manager.py +14 -14
  44. claude_mpm/cli/commands/configure_template_editor.py +8 -8
  45. claude_mpm/cli/commands/mpm_init.py +109 -24
  46. claude_mpm/cli/commands/skills.py +434 -0
  47. claude_mpm/cli/executor.py +2 -0
  48. claude_mpm/cli/interactive/__init__.py +3 -0
  49. claude_mpm/cli/interactive/skills_wizard.py +491 -0
  50. claude_mpm/cli/parsers/base_parser.py +7 -0
  51. claude_mpm/cli/parsers/skills_parser.py +137 -0
  52. claude_mpm/cli/startup.py +83 -0
  53. claude_mpm/commands/mpm-auto-configure.md +52 -0
  54. claude_mpm/commands/mpm-help.md +3 -0
  55. claude_mpm/commands/mpm-init.md +112 -6
  56. claude_mpm/commands/mpm-version.md +113 -0
  57. claude_mpm/commands/mpm.md +1 -0
  58. claude_mpm/config/agent_config.py +2 -2
  59. claude_mpm/constants.py +12 -0
  60. claude_mpm/core/config.py +42 -0
  61. claude_mpm/core/enums.py +18 -0
  62. claude_mpm/core/factories.py +1 -1
  63. claude_mpm/core/optimized_agent_loader.py +3 -3
  64. claude_mpm/core/types.py +2 -9
  65. claude_mpm/dashboard/static/js/dashboard.js +0 -14
  66. claude_mpm/dashboard/templates/index.html +3 -41
  67. claude_mpm/hooks/__init__.py +8 -0
  68. claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
  69. claude_mpm/hooks/session_resume_hook.py +121 -0
  70. claude_mpm/models/resume_log.py +340 -0
  71. claude_mpm/services/agents/auto_config_manager.py +1 -1
  72. claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
  73. claude_mpm/services/agents/deployment/agent_record_service.py +1 -1
  74. claude_mpm/services/agents/deployment/agent_validator.py +17 -1
  75. claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
  76. claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
  77. claude_mpm/services/agents/deployment/validation/__init__.py +3 -1
  78. claude_mpm/services/agents/deployment/validation/validation_result.py +1 -9
  79. claude_mpm/services/agents/local_template_manager.py +1 -1
  80. claude_mpm/services/agents/recommender.py +47 -0
  81. claude_mpm/services/cli/resume_service.py +617 -0
  82. claude_mpm/services/cli/session_manager.py +87 -0
  83. claude_mpm/services/cli/session_resume_helper.py +352 -0
  84. claude_mpm/services/core/models/health.py +1 -28
  85. claude_mpm/services/core/path_resolver.py +1 -1
  86. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -1
  87. claude_mpm/services/infrastructure/monitoring/aggregator.py +12 -12
  88. claude_mpm/services/infrastructure/monitoring/base.py +5 -13
  89. claude_mpm/services/infrastructure/monitoring/network.py +7 -6
  90. claude_mpm/services/infrastructure/monitoring/process.py +13 -12
  91. claude_mpm/services/infrastructure/monitoring/resources.py +7 -6
  92. claude_mpm/services/infrastructure/monitoring/service.py +16 -15
  93. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  94. claude_mpm/services/local_ops/__init__.py +1 -1
  95. claude_mpm/services/local_ops/crash_detector.py +1 -1
  96. claude_mpm/services/local_ops/health_checks/http_check.py +2 -1
  97. claude_mpm/services/local_ops/health_checks/process_check.py +2 -1
  98. claude_mpm/services/local_ops/health_checks/resource_check.py +2 -1
  99. claude_mpm/services/local_ops/health_manager.py +1 -1
  100. claude_mpm/services/local_ops/restart_manager.py +1 -1
  101. claude_mpm/services/mcp_config_manager.py +7 -131
  102. claude_mpm/services/session_manager.py +205 -1
  103. claude_mpm/services/shared/async_service_base.py +16 -27
  104. claude_mpm/services/shared/lifecycle_service_base.py +1 -14
  105. claude_mpm/services/socketio/handlers/__init__.py +5 -2
  106. claude_mpm/services/socketio/handlers/hook.py +10 -0
  107. claude_mpm/services/socketio/handlers/registry.py +4 -2
  108. claude_mpm/services/socketio/server/main.py +7 -7
  109. claude_mpm/services/unified/deployment_strategies/local.py +1 -1
  110. claude_mpm/services/version_service.py +104 -1
  111. claude_mpm/skills/__init__.py +42 -0
  112. claude_mpm/skills/agent_skills_injector.py +331 -0
  113. claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
  114. claude_mpm/skills/bundled/__init__.py +6 -0
  115. claude_mpm/skills/bundled/api-documentation.md +393 -0
  116. claude_mpm/skills/bundled/async-testing.md +571 -0
  117. claude_mpm/skills/bundled/code-review.md +143 -0
  118. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +75 -0
  119. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +184 -0
  120. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +107 -0
  121. claude_mpm/skills/bundled/collaboration/requesting-code-review/code-reviewer.md +146 -0
  122. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +118 -0
  123. claude_mpm/skills/bundled/database-migration.md +199 -0
  124. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +177 -0
  125. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  126. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  127. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  128. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  129. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  130. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  131. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  132. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  133. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  134. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  135. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +175 -0
  136. claude_mpm/skills/bundled/debugging/verification-before-completion/references/common-failures.md +213 -0
  137. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +314 -0
  138. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +227 -0
  139. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  140. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  141. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  142. claude_mpm/skills/bundled/git-workflow.md +414 -0
  143. claude_mpm/skills/bundled/imagemagick.md +204 -0
  144. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  145. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +74 -0
  146. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +32 -0
  147. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  148. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  149. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  150. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  151. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +328 -0
  152. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  153. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  154. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  155. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  156. claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +150 -0
  157. claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +372 -0
  158. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +209 -0
  159. claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +302 -0
  160. claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +111 -0
  161. claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +65 -0
  162. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  163. claude_mpm/skills/bundled/pdf.md +141 -0
  164. claude_mpm/skills/bundled/performance-profiling.md +567 -0
  165. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  166. claude_mpm/skills/bundled/security-scanning.md +327 -0
  167. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  168. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  169. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +123 -0
  170. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  171. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  172. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  173. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  174. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  175. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  176. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +304 -0
  177. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +96 -0
  178. claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
  179. claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +40 -0
  180. claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
  181. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +107 -0
  182. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  183. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  184. claude_mpm/skills/bundled/xlsx.md +157 -0
  185. claude_mpm/skills/registry.py +286 -0
  186. claude_mpm/skills/skill_manager.py +310 -0
  187. claude_mpm/skills/skills_registry.py +351 -0
  188. claude_mpm/skills/skills_service.py +730 -0
  189. claude_mpm/utils/agent_dependency_loader.py +2 -2
  190. {claude_mpm-4.15.2.dist-info → claude_mpm-4.20.3.dist-info}/METADATA +211 -33
  191. {claude_mpm-4.15.2.dist-info → claude_mpm-4.20.3.dist-info}/RECORD +195 -115
  192. claude_mpm/agents/INSTRUCTIONS_OLD_DEPRECATED.md +0 -602
  193. claude_mpm/dashboard/static/css/code-tree.css +0 -1639
  194. claude_mpm/dashboard/static/js/components/code-tree/tree-breadcrumb.js +0 -353
  195. claude_mpm/dashboard/static/js/components/code-tree/tree-constants.js +0 -235
  196. claude_mpm/dashboard/static/js/components/code-tree/tree-search.js +0 -409
  197. claude_mpm/dashboard/static/js/components/code-tree/tree-utils.js +0 -435
  198. claude_mpm/dashboard/static/js/components/code-tree.js +0 -5869
  199. claude_mpm/dashboard/static/js/components/code-viewer.js +0 -1386
  200. {claude_mpm-4.15.2.dist-info → claude_mpm-4.20.3.dist-info}/WHEEL +0 -0
  201. {claude_mpm-4.15.2.dist-info → claude_mpm-4.20.3.dist-info}/entry_points.txt +0 -0
  202. {claude_mpm-4.15.2.dist-info → claude_mpm-4.20.3.dist-info}/licenses/LICENSE +0 -0
  203. {claude_mpm-4.15.2.dist-info → claude_mpm-4.20.3.dist-info}/top_level.txt +0 -0
@@ -61,6 +61,10 @@ class HookEventHandler(BaseEventHandler):
61
61
 
62
62
  hook_data = data.get("data", {})
63
63
 
64
+ # Log hook event processing
65
+ tool_name = hook_data.get("tool_name", "N/A")
66
+ self.logger.info(f"Processing hook event: {hook_event} - tool: {tool_name}")
67
+
64
68
  # Create properly formatted event for history
65
69
  # Note: add_to_history expects the event data directly, not wrapped
66
70
  history_event = {
@@ -77,6 +81,12 @@ class HookEventHandler(BaseEventHandler):
77
81
 
78
82
  # Broadcast the original event to all connected clients
79
83
  # (preserves all original fields)
84
+ connected_clients = (
85
+ len(self.server.clients) if hasattr(self.server, "clients") else 0
86
+ )
87
+ self.logger.info(
88
+ f"Broadcasting claude_event to {connected_clients} clients: {hook_event}"
89
+ )
80
90
  await self.broadcast_event("claude_event", data)
81
91
 
82
92
  # Track sessions based on hook events
@@ -15,7 +15,8 @@ if TYPE_CHECKING:
15
15
 
16
16
  from ..server import SocketIOServer
17
17
 
18
- from .code_analysis import CodeAnalysisEventHandler
18
+ # DISABLED: File Tree interface removed from dashboard
19
+ # from .code_analysis import CodeAnalysisEventHandler
19
20
  from .connection import ConnectionEventHandler
20
21
  from .file import FileEventHandler
21
22
  from .git import GitEventHandler
@@ -38,7 +39,8 @@ class EventHandlerRegistry:
38
39
  HookEventHandler, # Hook events for session tracking
39
40
  GitEventHandler, # Git operations
40
41
  FileEventHandler, # File operations
41
- CodeAnalysisEventHandler, # Code analysis for dashboard
42
+ # DISABLED: File Tree interface removed from dashboard
43
+ # CodeAnalysisEventHandler, # Code analysis for dashboard
42
44
  ProjectEventHandler, # Project management (future)
43
45
  MemoryEventHandler, # Memory management (future)
44
46
  ]
@@ -267,15 +267,15 @@ class SocketIOServer(SocketIOServiceInterface):
267
267
  except Exception as e:
268
268
  self.logger.error(f"Error during EventBus teardown: {e}")
269
269
 
270
- # Stop code analysis handler
270
+ # Stop event handlers
271
271
  if self.event_registry:
272
- from ..handlers import CodeAnalysisEventHandler, ConnectionEventHandler
273
-
274
- # Stop analysis runner
275
- analysis_handler = self.event_registry.get_handler(CodeAnalysisEventHandler)
276
- if analysis_handler and hasattr(analysis_handler, "cleanup"):
277
- analysis_handler.cleanup()
272
+ from ..handlers import ConnectionEventHandler
278
273
 
274
+ # DISABLED: File Tree interface removed from dashboard
275
+ # Stop analysis runner (code analysis handler is disabled)
276
+ # analysis_handler = self.event_registry.get_handler(CodeAnalysisEventHandler)
277
+ # if analysis_handler and hasattr(analysis_handler, "cleanup"):
278
+ # analysis_handler.cleanup()
279
279
  # Stop health monitoring in connection handler
280
280
  conn_handler = self.event_registry.get_handler(ConnectionEventHandler)
281
281
  if conn_handler and hasattr(conn_handler, "stop_health_monitoring"):
@@ -395,7 +395,7 @@ class LocalDeploymentStrategy(DeploymentStrategy):
395
395
  shutil.copy2(artifact, dest)
396
396
  deployed.append(dest)
397
397
 
398
- self._logger.info(f"Deployed agent: {dest}")
398
+ self._logger.debug(f"Deployed agent: {dest}")
399
399
 
400
400
  return deployed
401
401
 
@@ -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,42 @@
1
+ """
2
+ Claude MPM Skills Package
3
+
4
+ Skills system for sharing common capabilities across agents.
5
+ This reduces redundancy by extracting shared patterns into reusable skills.
6
+
7
+ Skills can be:
8
+ - Bundled with MPM (in skills/bundled/)
9
+ - User-installed (in ~/.claude/skills/)
10
+ - Project-specific (in .claude/skills/)
11
+
12
+ New Skills Integration System:
13
+ - SkillsService: Core service for skill management
14
+ - AgentSkillsInjector: Dynamic skill injection into agent templates
15
+ - SkillsRegistry: Helper class for registry operations
16
+
17
+ Legacy System (maintained for compatibility):
18
+ - Skill: Dataclass for skill representation
19
+ - SkillManager: Legacy skill manager
20
+ - get_registry: Legacy registry access
21
+ """
22
+
23
+ # New Skills Integration System
24
+ from .agent_skills_injector import AgentSkillsInjector
25
+
26
+ # Legacy System (maintained for compatibility)
27
+ from .registry import Skill, SkillsRegistry, get_registry
28
+ from .skill_manager import SkillManager
29
+ from .skills_registry import SkillsRegistry as SkillsRegistryHelper
30
+ from .skills_service import SkillsService
31
+
32
+ __all__ = [
33
+ # New Skills Integration System
34
+ "SkillsService",
35
+ "AgentSkillsInjector",
36
+ "SkillsRegistryHelper",
37
+ # Legacy System
38
+ "Skill",
39
+ "SkillManager",
40
+ "SkillsRegistry",
41
+ "get_registry",
42
+ ]
@@ -0,0 +1,331 @@
1
+ """Agent Skills Injector - Dynamically inject skills into agent templates.
2
+
3
+ This module implements dynamic skill injection into agent templates and frontmatter.
4
+ It reads skill assignments from the registry and enhances agent definitions at runtime
5
+ without modifying template files on disk.
6
+
7
+ Design Principles:
8
+ - Dynamic injection (no template file modifications)
9
+ - Registry is source of truth (not templates)
10
+ - Return enhanced templates as dicts
11
+ - Generate clean YAML frontmatter
12
+ - Inject skills docs after frontmatter
13
+
14
+ References:
15
+ - Design: docs/design/claude-mpm-skills-integration-design.md (lines 632-711)
16
+ """
17
+
18
+ import json
19
+ from pathlib import Path
20
+ from typing import Any, Dict, List
21
+
22
+ import yaml
23
+
24
+ from claude_mpm.core.mixins import LoggerMixin
25
+
26
+ from .skills_service import SkillsService
27
+
28
+
29
+ class AgentSkillsInjector(LoggerMixin):
30
+ """Injects skill references into agent templates and frontmatter.
31
+
32
+ This class provides methods to:
33
+ - Enhance agent JSON templates with skills field
34
+ - Generate YAML frontmatter with skills included
35
+ - Inject skills documentation into agent markdown content
36
+
37
+ The injector reads from the skills registry (not template files) to determine
38
+ which skills should be assigned to each agent, then dynamically injects this
39
+ information when agents are loaded.
40
+
41
+ Example:
42
+ >>> service = SkillsService()
43
+ >>> injector = AgentSkillsInjector(service)
44
+ >>>
45
+ >>> # Enhance template
46
+ >>> template = injector.enhance_agent_template(Path('engineer.json'))
47
+ >>> print(template['skills']) # {'required': [...], 'optional': [...]}
48
+ >>>
49
+ >>> # Generate frontmatter
50
+ >>> frontmatter = injector.generate_frontmatter_with_skills(template)
51
+ >>> print(frontmatter) # ---\nname: engineer\nskills:\n - ...\n---
52
+ """
53
+
54
+ def __init__(self, skills_service: SkillsService) -> None:
55
+ """Initialize Agent Skills Injector.
56
+
57
+ Args:
58
+ skills_service: SkillsService instance for accessing registry
59
+ """
60
+ super().__init__()
61
+ self.skills_service: SkillsService = skills_service
62
+
63
+ def enhance_agent_template(self, template_path: Path) -> Dict[str, Any]:
64
+ """Add skills field to agent template JSON.
65
+
66
+ Reads an agent JSON template, determines which skills should be assigned
67
+ from the registry, and adds a 'skills' field to the template dict.
68
+
69
+ The skills field structure:
70
+ {
71
+ "required": [skill1, skill2], # First 2 skills
72
+ "optional": [skill3, skill4], # Remaining skills
73
+ "auto_load": true
74
+ }
75
+
76
+ Args:
77
+ template_path: Path to agent JSON template file
78
+
79
+ Returns:
80
+ Enhanced template dict with 'skills' field added
81
+
82
+ Example:
83
+ >>> template = injector.enhance_agent_template(
84
+ ... Path('src/claude_mpm/agents/templates/engineer.json')
85
+ ... )
86
+ >>> assert 'skills' in template
87
+ >>> assert 'required' in template['skills']
88
+ """
89
+ try:
90
+ with open(template_path, encoding='utf-8') as f:
91
+ template = json.load(f)
92
+ except (OSError, json.JSONDecodeError) as e:
93
+ self.logger.error(f"Failed to load template {template_path}: {e}")
94
+ raise ValueError(f"Cannot load template {template_path}") from e
95
+
96
+ agent_id = template.get('agent_id')
97
+ if not agent_id:
98
+ self.logger.error(f"Template missing agent_id: {template_path}")
99
+ return template
100
+
101
+ # Get skills for this agent from registry
102
+ skills = self.skills_service.get_skills_for_agent(agent_id)
103
+
104
+ if skills:
105
+ # Split into required (first 2) and optional (rest)
106
+ required = skills[:2] if len(skills) > 2 else skills
107
+ optional = skills[2:] if len(skills) > 2 else []
108
+
109
+ template['skills'] = {
110
+ 'required': required,
111
+ 'optional': optional,
112
+ 'auto_load': True
113
+ }
114
+
115
+ self.logger.info(f"Enhanced {agent_id} with {len(skills)} skills")
116
+ else:
117
+ self.logger.debug(f"No skills assigned to {agent_id}")
118
+
119
+ return template
120
+
121
+ def generate_frontmatter_with_skills(self, agent_config: Dict[str, Any]) -> str:
122
+ """Generate YAML frontmatter including skills field.
123
+
124
+ Creates clean YAML frontmatter for agent markdown files, including:
125
+ - name: Agent ID
126
+ - description: Agent description
127
+ - version: Agent version
128
+ - tools: List of tools
129
+ - skills: List of all skills (required + optional)
130
+
131
+ Args:
132
+ agent_config: Agent configuration dict (from JSON template)
133
+
134
+ Returns:
135
+ YAML frontmatter string with delimiters (---\n...yaml...\n---)
136
+
137
+ Example:
138
+ >>> config = {
139
+ ... 'agent_id': 'engineer',
140
+ ... 'metadata': {'description': 'Software development'},
141
+ ... 'version': '2.1.0',
142
+ ... 'capabilities': {'tools': ['Read', 'Write']},
143
+ ... 'skills': {
144
+ ... 'required': ['test-driven-development'],
145
+ ... 'optional': ['code-review']
146
+ ... }
147
+ ... }
148
+ >>> frontmatter = injector.generate_frontmatter_with_skills(config)
149
+ >>> assert 'skills:' in frontmatter
150
+ >>> assert 'test-driven-development' in frontmatter
151
+ """
152
+ # Build frontmatter dict
153
+ frontmatter = {
154
+ 'name': agent_config.get('agent_id'),
155
+ 'description': agent_config.get('metadata', {}).get('description'),
156
+ 'version': agent_config.get('version'),
157
+ 'tools': agent_config.get('capabilities', {}).get('tools', [])
158
+ }
159
+
160
+ # Add skills if present
161
+ if 'skills' in agent_config:
162
+ skills_config = agent_config['skills']
163
+ required = skills_config.get('required', [])
164
+ optional = skills_config.get('optional', [])
165
+ all_skills = required + optional
166
+
167
+ if all_skills:
168
+ frontmatter['skills'] = all_skills
169
+
170
+ # Convert to YAML with clean formatting
171
+ yaml_str = yaml.dump(
172
+ frontmatter,
173
+ default_flow_style=False,
174
+ sort_keys=False,
175
+ allow_unicode=True
176
+ )
177
+
178
+ return f"---\n{yaml_str}---\n"
179
+
180
+ def inject_skills_documentation(
181
+ self,
182
+ agent_content: str,
183
+ skills: List[str]
184
+ ) -> str:
185
+ """Inject skills documentation reference into agent instructions.
186
+
187
+ Adds a "## Available Skills" section after the YAML frontmatter that
188
+ lists all skills available to this agent. This section informs the agent
189
+ about its skills and explains that Claude will auto-load them when relevant.
190
+
191
+ Args:
192
+ agent_content: Original agent markdown content (with frontmatter)
193
+ skills: List of skill names to document
194
+
195
+ Returns:
196
+ Agent content with skills section injected after frontmatter
197
+
198
+ Example:
199
+ >>> content = '''---
200
+ ... name: engineer
201
+ ... ---
202
+ ...
203
+ ... # Software Engineer Agent
204
+ ...
205
+ ... You are a software development specialist...
206
+ ... '''
207
+ >>> skills = ['test-driven-development', 'systematic-debugging']
208
+ >>> enhanced = injector.inject_skills_documentation(content, skills)
209
+ >>> assert '## Available Skills' in enhanced
210
+ >>> assert 'test-driven-development' in enhanced
211
+ """
212
+ if not skills:
213
+ return agent_content
214
+
215
+ # Build skills section
216
+ skills_section = "\n\n## Available Skills\n\n"
217
+ skills_section += "You have access to the following skills that will be loaded when relevant:\n\n"
218
+
219
+ for skill in skills:
220
+ skills_section += f"- **{skill}**: Automatically activated when needed\n"
221
+
222
+ skills_section += "\nClaude will automatically read these skills when your task matches their descriptions.\n"
223
+
224
+ # Insert after frontmatter
225
+ if '---' in agent_content:
226
+ parts = agent_content.split('---', 2)
227
+ if len(parts) >= 3:
228
+ # Reconstruct: frontmatter + skills section + rest
229
+ return f"{parts[0]}---{parts[1]}---{skills_section}{parts[2]}"
230
+
231
+ # If no frontmatter, append at end
232
+ return agent_content + skills_section
233
+
234
+ def enhance_agent_with_skills(
235
+ self,
236
+ agent_id: str,
237
+ template_content: str
238
+ ) -> Dict[str, Any]:
239
+ """Convenience method to fully enhance an agent with skills.
240
+
241
+ Combines all enhancement steps:
242
+ 1. Gets skills from registry
243
+ 2. Generates enhanced frontmatter
244
+ 3. Injects skills documentation
245
+
246
+ Args:
247
+ agent_id: Agent identifier
248
+ template_content: Original agent template markdown content
249
+
250
+ Returns:
251
+ Dict containing:
252
+ - agent_id: Agent identifier
253
+ - skills: List of skill names
254
+ - frontmatter: YAML frontmatter with skills
255
+ - content: Full enhanced markdown content
256
+
257
+ Example:
258
+ >>> result = injector.enhance_agent_with_skills(
259
+ ... 'engineer',
260
+ ... '---\nname: engineer\n---\n\n# Engineer\n...'
261
+ ... )
262
+ >>> print(result['skills']) # ['test-driven-development', ...]
263
+ >>> print(result['content']) # Enhanced markdown with skills section
264
+ """
265
+ # Get skills for agent
266
+ skills = self.skills_service.get_skills_for_agent(agent_id)
267
+
268
+ if not skills:
269
+ return {
270
+ 'agent_id': agent_id,
271
+ 'skills': [],
272
+ 'frontmatter': '',
273
+ 'content': template_content
274
+ }
275
+
276
+ # Create config dict for frontmatter generation
277
+ agent_config = {
278
+ 'agent_id': agent_id,
279
+ 'skills': {
280
+ 'required': skills[:2] if len(skills) > 2 else skills,
281
+ 'optional': skills[2:] if len(skills) > 2 else []
282
+ }
283
+ }
284
+
285
+ # Generate frontmatter
286
+ frontmatter = self.generate_frontmatter_with_skills(agent_config)
287
+
288
+ # Inject skills documentation
289
+ enhanced_content = self.inject_skills_documentation(template_content, skills)
290
+
291
+ return {
292
+ 'agent_id': agent_id,
293
+ 'skills': skills,
294
+ 'frontmatter': frontmatter,
295
+ 'content': enhanced_content
296
+ }
297
+
298
+ def get_skills_references_for_agent(self, agent_id: str) -> List[Dict[str, str]]:
299
+ """Get skill references with metadata for an agent.
300
+
301
+ Returns detailed information about each skill assigned to an agent,
302
+ including name, category, and description from the registry.
303
+
304
+ Args:
305
+ agent_id: Agent identifier
306
+
307
+ Returns:
308
+ List of dicts containing skill reference information:
309
+ - name: Skill name
310
+ - category: Skill category (from metadata)
311
+ - description: Brief description
312
+
313
+ Example:
314
+ >>> refs = injector.get_skills_references_for_agent('engineer')
315
+ >>> for ref in refs:
316
+ ... print(f"{ref['name']}: {ref['description']}")
317
+ """
318
+ skills = self.skills_service.get_skills_for_agent(agent_id)
319
+ registry = self.skills_service.registry
320
+
321
+ skill_refs = []
322
+ for skill_name in skills:
323
+ metadata = registry.get('skills_metadata', {}).get(skill_name, {})
324
+
325
+ skill_refs.append({
326
+ 'name': skill_name,
327
+ 'category': metadata.get('category', 'unknown'),
328
+ 'description': metadata.get('description', '')
329
+ })
330
+
331
+ return skill_refs
@@ -0,0 +1,79 @@
1
+ # License Attributions for Bundled Skills
2
+
3
+ This document provides license information and attributions for all skills bundled with Claude MPM.
4
+
5
+ ---
6
+
7
+ ## Summary
8
+
9
+ - **Total Skills**: 15
10
+ - **Unique Licenses**: 3
11
+
12
+ - **UNKNOWN**: 8 skill(s)
13
+ - **Complete terms in LICENSE.txt**: 5 skill(s)
14
+ - **MIT**: 2 skill(s)
15
+
16
+ ---
17
+
18
+ ## Complete terms in LICENSE.txt Licensed Skills
19
+
20
+ | Skill Name | Author | Category | Description | Source |
21
+ |------------|--------|----------|-------------|--------|
22
+ | artifacts-builder | Unknown | main | Suite of tools for creating elaborate, multi-component claud... | N/A |
23
+ | internal-comms | Unknown | main | A set of resources to help me write all kinds of internal co... | N/A |
24
+ | mcp-builder | Unknown | main | Guide for creating high-quality MCP (Model Context Protocol)... | N/A |
25
+ | skill-creator | Unknown | main | Guide for creating effective skills. This skill should be us... | N/A |
26
+ | webapp-testing | Unknown | testing | Toolkit for interacting with and testing local web applicati... | N/A |
27
+
28
+ ---
29
+
30
+ ## MIT Licensed Skills
31
+
32
+ | Skill Name | Author | Category | Description | Source |
33
+ |------------|--------|----------|-------------|--------|
34
+ | systematic-debugging | Jesse Vincent | debugging | Methodical debugging instead of random changes | [Link](https://github.com/obra/superpowers-skills/tree/main/skills/debugging/systematic-debugging) |
35
+ | test-driven-development | Jesse Vincent | testing | Write the test first, watch it fail, write minimal code to p... | [Link](https://github.com/obra/superpowers-skills/tree/main/skills/testing/test-driven-development) |
36
+
37
+ ---
38
+
39
+ ## UNKNOWN Licensed Skills
40
+
41
+ | Skill Name | Author | Category | Description | Source |
42
+ |------------|--------|----------|-------------|--------|
43
+ | Brainstorming Ideas Into Designs | Unknown | collaboration | Interactive idea refinement using Socratic method to develop... | N/A |
44
+ | Condition-Based Waiting | Unknown | testing | Replace arbitrary timeouts with condition polling for reliab... | N/A |
45
+ | Dispatching Parallel Agents | Unknown | collaboration | Use multiple Claude agents to investigate and fix independen... | N/A |
46
+ | Requesting Code Review | Unknown | collaboration | Dispatch code-reviewer subagent to review implementation aga... | N/A |
47
+ | Root Cause Tracing | Unknown | debugging | Systematically trace bugs backward through call stack to fin... | N/A |
48
+ | Testing Anti-Patterns | Unknown | testing | Never test mock behavior. Never add test-only methods to pro... | N/A |
49
+ | Verification Before Completion | Unknown | debugging | Run verification commands and confirm output before claiming... | N/A |
50
+ | Writing Plans | Unknown | collaboration | Create detailed implementation plans with bite-sized tasks f... | N/A |
51
+
52
+ ---
53
+
54
+ ## ⚠️ Missing License Information
55
+
56
+ The following skills do not have license information in their SKILL.md:
57
+
58
+ - Brainstorming Ideas Into Designs
59
+ - Condition-Based Waiting
60
+ - Dispatching Parallel Agents
61
+ - Requesting Code Review
62
+ - Root Cause Tracing
63
+ - Testing Anti-Patterns
64
+ - Verification Before Completion
65
+ - Writing Plans
66
+
67
+ ---
68
+
69
+ ## How to Update
70
+
71
+ To update this file, run:
72
+
73
+ ```bash
74
+ python scripts/generate_license_attributions.py
75
+ ```
76
+
77
+ ---
78
+
79
+ *Generated automatically by Claude MPM*
@@ -0,0 +1,6 @@
1
+ """
2
+ Bundled skills shipped with Claude MPM.
3
+
4
+ These skills provide reusable patterns and practices that eliminate
5
+ redundancy across agent templates.
6
+ """