claude-mpm 4.15.6__py3-none-any.whl → 4.21.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.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_ENGINEER.md +286 -0
- claude_mpm/agents/BASE_PM.md +272 -23
- claude_mpm/agents/PM_INSTRUCTIONS.md +49 -0
- claude_mpm/agents/agent_loader.py +4 -4
- claude_mpm/agents/templates/engineer.json +5 -1
- claude_mpm/agents/templates/php-engineer.json +10 -4
- claude_mpm/agents/templates/python_engineer.json +8 -3
- claude_mpm/agents/templates/rust_engineer.json +12 -7
- claude_mpm/agents/templates/svelte-engineer.json +225 -0
- claude_mpm/cli/commands/__init__.py +2 -0
- claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
- claude_mpm/cli/commands/mpm_init/core.py +525 -0
- claude_mpm/cli/commands/mpm_init/display.py +341 -0
- claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
- claude_mpm/cli/commands/mpm_init/modes.py +397 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +442 -0
- claude_mpm/cli/commands/mpm_init_cli.py +396 -0
- claude_mpm/cli/commands/mpm_init_handler.py +67 -1
- claude_mpm/cli/commands/skills.py +488 -0
- claude_mpm/cli/executor.py +2 -0
- claude_mpm/cli/parsers/base_parser.py +7 -0
- claude_mpm/cli/parsers/mpm_init_parser.py +42 -0
- claude_mpm/cli/parsers/skills_parser.py +137 -0
- claude_mpm/cli/startup.py +57 -0
- claude_mpm/commands/mpm-auto-configure.md +52 -0
- claude_mpm/commands/mpm-help.md +6 -0
- claude_mpm/commands/mpm-init.md +112 -6
- claude_mpm/commands/mpm-resume.md +372 -0
- claude_mpm/commands/mpm-version.md +113 -0
- claude_mpm/commands/mpm.md +2 -0
- claude_mpm/config/agent_config.py +2 -2
- claude_mpm/constants.py +12 -0
- claude_mpm/core/config.py +42 -0
- claude_mpm/core/factories.py +1 -1
- claude_mpm/core/interfaces.py +56 -1
- claude_mpm/core/optimized_agent_loader.py +3 -3
- claude_mpm/hooks/__init__.py +8 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
- claude_mpm/hooks/session_resume_hook.py +121 -0
- claude_mpm/models/resume_log.py +340 -0
- claude_mpm/services/agents/auto_config_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_record_service.py +1 -1
- claude_mpm/services/agents/deployment/agent_validator.py +17 -1
- claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
- claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
- claude_mpm/services/agents/local_template_manager.py +1 -1
- claude_mpm/services/agents/recommender.py +47 -0
- claude_mpm/services/cli/resume_service.py +617 -0
- claude_mpm/services/cli/session_manager.py +87 -0
- claude_mpm/services/cli/session_pause_manager.py +504 -0
- claude_mpm/services/cli/session_resume_helper.py +372 -0
- claude_mpm/services/core/base.py +26 -11
- claude_mpm/services/core/interfaces.py +56 -1
- claude_mpm/services/core/models/agent_config.py +3 -0
- claude_mpm/services/core/models/process.py +4 -0
- claude_mpm/services/core/path_resolver.py +1 -1
- claude_mpm/services/diagnostics/models.py +21 -0
- claude_mpm/services/event_bus/relay.py +23 -7
- claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
- claude_mpm/services/local_ops/__init__.py +2 -0
- claude_mpm/services/mcp_config_manager.py +7 -131
- claude_mpm/services/mcp_gateway/auto_configure.py +31 -25
- claude_mpm/services/mcp_gateway/core/process_pool.py +19 -10
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +26 -21
- claude_mpm/services/memory/failure_tracker.py +19 -4
- claude_mpm/services/session_manager.py +205 -1
- claude_mpm/services/unified/deployment_strategies/local.py +1 -1
- claude_mpm/services/version_service.py +104 -1
- claude_mpm/skills/__init__.py +21 -0
- claude_mpm/skills/agent_skills_injector.py +324 -0
- claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
- claude_mpm/skills/bundled/api-documentation.md +393 -0
- claude_mpm/skills/bundled/async-testing.md +571 -0
- claude_mpm/skills/bundled/code-review.md +143 -0
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
- claude_mpm/skills/bundled/database-migration.md +199 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
- claude_mpm/skills/bundled/docker-containerization.md +194 -0
- claude_mpm/skills/bundled/express-local-dev.md +1429 -0
- claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
- claude_mpm/skills/bundled/git-workflow.md +414 -0
- claude_mpm/skills/bundled/imagemagick.md +204 -0
- claude_mpm/skills/bundled/json-data-handling.md +223 -0
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
- claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
- claude_mpm/skills/bundled/pdf.md +141 -0
- claude_mpm/skills/bundled/performance-profiling.md +567 -0
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
- claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
- claude_mpm/skills/bundled/security-scanning.md +327 -0
- claude_mpm/skills/bundled/systematic-debugging.md +473 -0
- claude_mpm/skills/bundled/test-driven-development.md +378 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
- claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
- claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
- claude_mpm/skills/bundled/xlsx.md +157 -0
- claude_mpm/skills/registry.py +97 -9
- claude_mpm/skills/skills_registry.py +348 -0
- claude_mpm/skills/skills_service.py +739 -0
- claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
- claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
- claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
- claude_mpm/tools/code_tree_analyzer/core.py +380 -0
- claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
- claude_mpm/tools/code_tree_analyzer/events.py +168 -0
- claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
- claude_mpm/tools/code_tree_analyzer/models.py +39 -0
- claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
- claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
- claude_mpm/utils/agent_dependency_loader.py +2 -2
- {claude_mpm-4.15.6.dist-info → claude_mpm-4.21.3.dist-info}/METADATA +211 -33
- {claude_mpm-4.15.6.dist-info → claude_mpm-4.21.3.dist-info}/RECORD +206 -64
- claude_mpm/agents/INSTRUCTIONS_OLD_DEPRECATED.md +0 -602
- claude_mpm/cli/commands/mpm_init.py +0 -2008
- claude_mpm/tools/code_tree_analyzer.py +0 -1825
- {claude_mpm-4.15.6.dist-info → claude_mpm-4.21.3.dist-info}/WHEEL +0 -0
- {claude_mpm-4.15.6.dist-info → claude_mpm-4.21.3.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.15.6.dist-info → claude_mpm-4.21.3.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.15.6.dist-info → claude_mpm-4.21.3.dist-info}/top_level.txt +0 -0
|
@@ -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
|
+
}
|
claude_mpm/skills/__init__.py
CHANGED
|
@@ -8,14 +8,35 @@ Skills can be:
|
|
|
8
8
|
- Bundled with MPM (in skills/bundled/)
|
|
9
9
|
- User-installed (in ~/.claude/skills/)
|
|
10
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
|
|
11
21
|
"""
|
|
12
22
|
|
|
23
|
+
# New Skills Integration System
|
|
24
|
+
from .agent_skills_injector import AgentSkillsInjector
|
|
25
|
+
|
|
26
|
+
# Legacy System (maintained for compatibility)
|
|
13
27
|
from .registry import Skill, SkillsRegistry, get_registry
|
|
14
28
|
from .skill_manager import SkillManager
|
|
29
|
+
from .skills_registry import SkillsRegistry as SkillsRegistryHelper
|
|
30
|
+
from .skills_service import SkillsService
|
|
15
31
|
|
|
16
32
|
__all__ = [
|
|
33
|
+
"AgentSkillsInjector",
|
|
34
|
+
# Legacy System
|
|
17
35
|
"Skill",
|
|
18
36
|
"SkillManager",
|
|
19
37
|
"SkillsRegistry",
|
|
38
|
+
"SkillsRegistryHelper",
|
|
39
|
+
# New Skills Integration System
|
|
40
|
+
"SkillsService",
|
|
20
41
|
"get_registry",
|
|
21
42
|
]
|
|
@@ -0,0 +1,324 @@
|
|
|
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, default_flow_style=False, sort_keys=False, allow_unicode=True
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
return f"---\n{yaml_str}---\n"
|
|
176
|
+
|
|
177
|
+
def inject_skills_documentation(self, agent_content: str, skills: List[str]) -> str:
|
|
178
|
+
"""Inject skills documentation reference into agent instructions.
|
|
179
|
+
|
|
180
|
+
Adds a "## Available Skills" section after the YAML frontmatter that
|
|
181
|
+
lists all skills available to this agent. This section informs the agent
|
|
182
|
+
about its skills and explains that Claude will auto-load them when relevant.
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
agent_content: Original agent markdown content (with frontmatter)
|
|
186
|
+
skills: List of skill names to document
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
Agent content with skills section injected after frontmatter
|
|
190
|
+
|
|
191
|
+
Example:
|
|
192
|
+
>>> content = '''---
|
|
193
|
+
... name: engineer
|
|
194
|
+
... ---
|
|
195
|
+
...
|
|
196
|
+
... # Software Engineer Agent
|
|
197
|
+
...
|
|
198
|
+
... You are a software development specialist...
|
|
199
|
+
... '''
|
|
200
|
+
>>> skills = ['test-driven-development', 'systematic-debugging']
|
|
201
|
+
>>> enhanced = injector.inject_skills_documentation(content, skills)
|
|
202
|
+
>>> assert '## Available Skills' in enhanced
|
|
203
|
+
>>> assert 'test-driven-development' in enhanced
|
|
204
|
+
"""
|
|
205
|
+
if not skills:
|
|
206
|
+
return agent_content
|
|
207
|
+
|
|
208
|
+
# Build skills section
|
|
209
|
+
skills_section = "\n\n## Available Skills\n\n"
|
|
210
|
+
skills_section += "You have access to the following skills that will be loaded when relevant:\n\n"
|
|
211
|
+
|
|
212
|
+
for skill in skills:
|
|
213
|
+
skills_section += f"- **{skill}**: Automatically activated when needed\n"
|
|
214
|
+
|
|
215
|
+
skills_section += "\nClaude will automatically read these skills when your task matches their descriptions.\n"
|
|
216
|
+
|
|
217
|
+
# Insert after frontmatter
|
|
218
|
+
if "---" in agent_content:
|
|
219
|
+
parts = agent_content.split("---", 2)
|
|
220
|
+
if len(parts) >= 3:
|
|
221
|
+
# Reconstruct: frontmatter + skills section + rest
|
|
222
|
+
return f"{parts[0]}---{parts[1]}---{skills_section}{parts[2]}"
|
|
223
|
+
|
|
224
|
+
# If no frontmatter, append at end
|
|
225
|
+
return agent_content + skills_section
|
|
226
|
+
|
|
227
|
+
def enhance_agent_with_skills(
|
|
228
|
+
self, agent_id: str, template_content: str
|
|
229
|
+
) -> Dict[str, Any]:
|
|
230
|
+
"""Convenience method to fully enhance an agent with skills.
|
|
231
|
+
|
|
232
|
+
Combines all enhancement steps:
|
|
233
|
+
1. Gets skills from registry
|
|
234
|
+
2. Generates enhanced frontmatter
|
|
235
|
+
3. Injects skills documentation
|
|
236
|
+
|
|
237
|
+
Args:
|
|
238
|
+
agent_id: Agent identifier
|
|
239
|
+
template_content: Original agent template markdown content
|
|
240
|
+
|
|
241
|
+
Returns:
|
|
242
|
+
Dict containing:
|
|
243
|
+
- agent_id: Agent identifier
|
|
244
|
+
- skills: List of skill names
|
|
245
|
+
- frontmatter: YAML frontmatter with skills
|
|
246
|
+
- content: Full enhanced markdown content
|
|
247
|
+
|
|
248
|
+
Example:
|
|
249
|
+
>>> result = injector.enhance_agent_with_skills(
|
|
250
|
+
... 'engineer',
|
|
251
|
+
... '---\nname: engineer\n---\n\n# Engineer\n...'
|
|
252
|
+
... )
|
|
253
|
+
>>> print(result['skills']) # ['test-driven-development', ...]
|
|
254
|
+
>>> print(result['content']) # Enhanced markdown with skills section
|
|
255
|
+
"""
|
|
256
|
+
# Get skills for agent
|
|
257
|
+
skills = self.skills_service.get_skills_for_agent(agent_id)
|
|
258
|
+
|
|
259
|
+
if not skills:
|
|
260
|
+
return {
|
|
261
|
+
"agent_id": agent_id,
|
|
262
|
+
"skills": [],
|
|
263
|
+
"frontmatter": "",
|
|
264
|
+
"content": template_content,
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
# Create config dict for frontmatter generation
|
|
268
|
+
agent_config = {
|
|
269
|
+
"agent_id": agent_id,
|
|
270
|
+
"skills": {
|
|
271
|
+
"required": skills[:2] if len(skills) > 2 else skills,
|
|
272
|
+
"optional": skills[2:] if len(skills) > 2 else [],
|
|
273
|
+
},
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
# Generate frontmatter
|
|
277
|
+
frontmatter = self.generate_frontmatter_with_skills(agent_config)
|
|
278
|
+
|
|
279
|
+
# Inject skills documentation
|
|
280
|
+
enhanced_content = self.inject_skills_documentation(template_content, skills)
|
|
281
|
+
|
|
282
|
+
return {
|
|
283
|
+
"agent_id": agent_id,
|
|
284
|
+
"skills": skills,
|
|
285
|
+
"frontmatter": frontmatter,
|
|
286
|
+
"content": enhanced_content,
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
def get_skills_references_for_agent(self, agent_id: str) -> List[Dict[str, str]]:
|
|
290
|
+
"""Get skill references with metadata for an agent.
|
|
291
|
+
|
|
292
|
+
Returns detailed information about each skill assigned to an agent,
|
|
293
|
+
including name, category, and description from the registry.
|
|
294
|
+
|
|
295
|
+
Args:
|
|
296
|
+
agent_id: Agent identifier
|
|
297
|
+
|
|
298
|
+
Returns:
|
|
299
|
+
List of dicts containing skill reference information:
|
|
300
|
+
- name: Skill name
|
|
301
|
+
- category: Skill category (from metadata)
|
|
302
|
+
- description: Brief description
|
|
303
|
+
|
|
304
|
+
Example:
|
|
305
|
+
>>> refs = injector.get_skills_references_for_agent('engineer')
|
|
306
|
+
>>> for ref in refs:
|
|
307
|
+
... print(f"{ref['name']}: {ref['description']}")
|
|
308
|
+
"""
|
|
309
|
+
skills = self.skills_service.get_skills_for_agent(agent_id)
|
|
310
|
+
registry = self.skills_service.registry
|
|
311
|
+
|
|
312
|
+
skill_refs = []
|
|
313
|
+
for skill_name in skills:
|
|
314
|
+
metadata = registry.get("skills_metadata", {}).get(skill_name, {})
|
|
315
|
+
|
|
316
|
+
skill_refs.append(
|
|
317
|
+
{
|
|
318
|
+
"name": skill_name,
|
|
319
|
+
"category": metadata.get("category", "unknown"),
|
|
320
|
+
"description": metadata.get("description", ""),
|
|
321
|
+
}
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
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*
|