claude-mpm 5.4.56__py3-none-any.whl → 5.4.57__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.
- claude_mpm/VERSION +1 -1
- claude_mpm/services/skills/selective_skill_deployer.py +91 -82
- {claude_mpm-5.4.56.dist-info → claude_mpm-5.4.57.dist-info}/METADATA +1 -1
- {claude_mpm-5.4.56.dist-info → claude_mpm-5.4.57.dist-info}/RECORD +9 -9
- {claude_mpm-5.4.56.dist-info → claude_mpm-5.4.57.dist-info}/WHEEL +0 -0
- {claude_mpm-5.4.56.dist-info → claude_mpm-5.4.57.dist-info}/entry_points.txt +0 -0
- {claude_mpm-5.4.56.dist-info → claude_mpm-5.4.57.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.4.56.dist-info → claude_mpm-5.4.57.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.4.56.dist-info → claude_mpm-5.4.57.dist-info}/top_level.txt +0 -0
claude_mpm/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
5.4.
|
|
1
|
+
5.4.57
|
|
@@ -51,6 +51,59 @@ logger = get_logger(__name__)
|
|
|
51
51
|
# Deployment tracking index file
|
|
52
52
|
DEPLOYED_INDEX_FILE = ".mpm-deployed-skills.json"
|
|
53
53
|
|
|
54
|
+
# Core skills that are universally useful across all projects
|
|
55
|
+
# These are deployed when skill mapping returns too many skills (>60)
|
|
56
|
+
# Target: ~25-30 core skills for balanced functionality
|
|
57
|
+
CORE_SKILLS = {
|
|
58
|
+
# Universal debugging and verification (4 skills)
|
|
59
|
+
"universal-debugging-systematic-debugging",
|
|
60
|
+
"universal-debugging-verification-before-completion",
|
|
61
|
+
"universal-verification-pre-merge",
|
|
62
|
+
"universal-verification-screenshot",
|
|
63
|
+
|
|
64
|
+
# Universal testing patterns (2 skills)
|
|
65
|
+
"universal-testing-test-driven-development",
|
|
66
|
+
"universal-testing-testing-anti-patterns",
|
|
67
|
+
|
|
68
|
+
# Universal architecture and design (1 skill)
|
|
69
|
+
"universal-architecture-software-patterns",
|
|
70
|
+
|
|
71
|
+
# Universal infrastructure (3 skills)
|
|
72
|
+
"universal-infrastructure-env-manager",
|
|
73
|
+
"universal-infrastructure-docker",
|
|
74
|
+
"universal-infrastructure-github-actions",
|
|
75
|
+
|
|
76
|
+
# Universal collaboration (1 skill)
|
|
77
|
+
"universal-collaboration-stacked-prs",
|
|
78
|
+
|
|
79
|
+
# Universal emergency/operations (1 skill)
|
|
80
|
+
"toolchains-universal-emergency-release",
|
|
81
|
+
"toolchains-universal-dependency-audit",
|
|
82
|
+
|
|
83
|
+
# Common language toolchains (6 skills)
|
|
84
|
+
"toolchains-typescript-core",
|
|
85
|
+
"toolchains-python-core",
|
|
86
|
+
"toolchains-javascript-tooling-biome",
|
|
87
|
+
"toolchains-python-tooling-mypy",
|
|
88
|
+
"toolchains-typescript-testing-vitest",
|
|
89
|
+
"toolchains-python-frameworks-flask",
|
|
90
|
+
|
|
91
|
+
# Common web frameworks (4 skills)
|
|
92
|
+
"toolchains-javascript-frameworks-nextjs",
|
|
93
|
+
"toolchains-nextjs-core",
|
|
94
|
+
"toolchains-typescript-frameworks-nodejs-backend",
|
|
95
|
+
"toolchains-javascript-frameworks-react-state-machine",
|
|
96
|
+
|
|
97
|
+
# Common testing tools (2 skills)
|
|
98
|
+
"toolchains-javascript-testing-playwright",
|
|
99
|
+
"toolchains-typescript-testing-jest",
|
|
100
|
+
|
|
101
|
+
# Common data/UI tools (3 skills)
|
|
102
|
+
"universal-data-xlsx",
|
|
103
|
+
"toolchains-ui-styling-tailwind",
|
|
104
|
+
"toolchains-ui-components-headlessui",
|
|
105
|
+
}
|
|
106
|
+
|
|
54
107
|
|
|
55
108
|
def parse_agent_frontmatter(agent_file: Path) -> Dict[str, Any]:
|
|
56
109
|
"""Parse YAML frontmatter from agent markdown file.
|
|
@@ -140,22 +193,14 @@ def get_skills_from_agent(frontmatter: Dict[str, Any]) -> Set[str]:
|
|
|
140
193
|
def get_skills_from_mapping(agent_ids: List[str]) -> Set[str]:
|
|
141
194
|
"""Get skills for agents using SkillToAgentMapper inference.
|
|
142
195
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
CRITICAL DESIGN DECISION: This function ONLY returns skills for the DEPLOYED agents
|
|
147
|
-
provided in agent_ids. It does NOT return skills for all agents in the mapping
|
|
148
|
-
configuration (skill_to_agent_mapping.yaml lists 41 agents, but only 33 may be deployed).
|
|
196
|
+
DEPRECATED: This function is deprecated as of Phase 3 refactor.
|
|
197
|
+
Skills are now declared exclusively in agent frontmatter.
|
|
149
198
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
specialized agents exist, we skip "engineer" if specialized agents are present.
|
|
199
|
+
The static skill_to_agent_mapping.yaml is no longer used for skill deployment.
|
|
200
|
+
Each agent must declare its skills in frontmatter or it gets zero skills.
|
|
153
201
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
- User may only have 33 agents deployed in ~/.claude/agents/
|
|
157
|
-
- Without filtering, we'd deploy skills for all 41 agents (over-deployment)
|
|
158
|
-
- Solution: Only query skills for DEPLOYED agents (passed in agent_ids)
|
|
202
|
+
This function remains for backward compatibility but is NO LONGER CALLED
|
|
203
|
+
by get_required_skills_from_agents().
|
|
159
204
|
|
|
160
205
|
Args:
|
|
161
206
|
agent_ids: List of DEPLOYED agent identifiers (e.g., ["python-engineer", "typescript-engineer"])
|
|
@@ -163,67 +208,34 @@ def get_skills_from_mapping(agent_ids: List[str]) -> Set[str]:
|
|
|
163
208
|
|
|
164
209
|
Returns:
|
|
165
210
|
Set of unique skill names inferred from mapping configuration for DEPLOYED agents only
|
|
211
|
+
NOTE: This is now an empty set as the function is deprecated.
|
|
166
212
|
|
|
167
213
|
Example:
|
|
168
|
-
>>> #
|
|
214
|
+
>>> # DEPRECATED - use frontmatter instead
|
|
169
215
|
>>> deployed_agent_ids = ["python-engineer", "typescript-engineer", "qa"]
|
|
170
|
-
>>> skills = get_skills_from_mapping(deployed_agent_ids)
|
|
171
|
-
>>> print(f"Found {len(skills)} skills for {len(deployed_agent_ids)} deployed agents")
|
|
216
|
+
>>> skills = get_skills_from_mapping(deployed_agent_ids) # Returns empty set
|
|
172
217
|
"""
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
# agents like "python-engineer", "typescript-engineer", etc.
|
|
181
|
-
#
|
|
182
|
-
# Solution: Filter out "engineer" from agent_ids if specialized agents exist
|
|
183
|
-
specialized_engineers = [
|
|
184
|
-
aid for aid in agent_ids if aid.endswith("-engineer") and aid != "engineer"
|
|
185
|
-
]
|
|
186
|
-
|
|
187
|
-
# If specialized engineers exist, exclude generic "engineer" from skill mapping
|
|
188
|
-
# This prevents deploying 100+ skills when only a subset is needed
|
|
189
|
-
agents_to_query = agent_ids
|
|
190
|
-
if specialized_engineers and "engineer" in agent_ids:
|
|
191
|
-
agents_to_query = [aid for aid in agent_ids if aid != "engineer"]
|
|
192
|
-
logger.info(
|
|
193
|
-
f"Excluding generic 'engineer' agent from skill mapping "
|
|
194
|
-
f"(found {len(specialized_engineers)} specialized engineers: "
|
|
195
|
-
f"{', '.join(specialized_engineers[:5])}{'...' if len(specialized_engineers) > 5 else ''})"
|
|
196
|
-
)
|
|
197
|
-
|
|
198
|
-
# IMPORTANT: Only query skills for DEPLOYED agents (those in agent_ids)
|
|
199
|
-
# Do NOT query all agents from skill_to_agent_mapping.yaml (that's 41 agents)
|
|
200
|
-
for agent_id in agents_to_query:
|
|
201
|
-
agent_skills = mapper.get_skills_for_agent(agent_id)
|
|
202
|
-
if agent_skills:
|
|
203
|
-
all_skills.update(agent_skills)
|
|
204
|
-
logger.debug(f"Mapped {len(agent_skills)} skills to {agent_id}")
|
|
205
|
-
|
|
206
|
-
logger.info(
|
|
207
|
-
f"Mapped {len(all_skills)} unique skills for {len(agents_to_query)} deployed agents "
|
|
208
|
-
f"(out of {len(agent_ids)} total deployed, excluding generic 'engineer' if specialized exist)"
|
|
209
|
-
)
|
|
210
|
-
return all_skills
|
|
211
|
-
|
|
212
|
-
except Exception as e:
|
|
213
|
-
logger.warning(f"Failed to load SkillToAgentMapper: {e}")
|
|
214
|
-
logger.info("Falling back to frontmatter-only skill discovery")
|
|
215
|
-
return set()
|
|
218
|
+
# DEPRECATED: Return empty set
|
|
219
|
+
logger.warning(
|
|
220
|
+
"get_skills_from_mapping() is DEPRECATED and returns empty set. "
|
|
221
|
+
"Skills are now declared in agent frontmatter only. "
|
|
222
|
+
"Update your agents with 'skills:' field in frontmatter."
|
|
223
|
+
)
|
|
224
|
+
return set()
|
|
216
225
|
|
|
217
226
|
|
|
218
227
|
def get_required_skills_from_agents(agents_dir: Path) -> Set[str]:
|
|
219
228
|
"""Extract all skills referenced by deployed agents.
|
|
220
229
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
230
|
+
MAJOR CHANGE (Phase 3): Now ONLY uses frontmatter-declared skills.
|
|
231
|
+
The static skill_to_agent_mapping.yaml is DEPRECATED. Each agent must
|
|
232
|
+
declare its skills in frontmatter or it gets zero skills deployed.
|
|
224
233
|
|
|
225
|
-
This
|
|
226
|
-
|
|
234
|
+
This change:
|
|
235
|
+
- Eliminates dual-source complexity (frontmatter + mapping)
|
|
236
|
+
- Makes skill requirements explicit per agent
|
|
237
|
+
- Enables per-agent customization via frontmatter
|
|
238
|
+
- Removes dependency on static YAML mapping
|
|
227
239
|
|
|
228
240
|
Args:
|
|
229
241
|
agents_dir: Path to deployed agents directory (e.g., .claude/agents/)
|
|
@@ -244,13 +256,11 @@ def get_required_skills_from_agents(agents_dir: Path) -> Set[str]:
|
|
|
244
256
|
agent_files = list(agents_dir.glob("*.md"))
|
|
245
257
|
logger.debug(f"Scanning {len(agent_files)} agent files in {agents_dir}")
|
|
246
258
|
|
|
247
|
-
#
|
|
259
|
+
# ONLY use frontmatter skills - no more mapping inference
|
|
248
260
|
frontmatter_skills = set()
|
|
249
|
-
agent_ids = []
|
|
250
261
|
|
|
251
262
|
for agent_file in agent_files:
|
|
252
263
|
agent_id = agent_file.stem
|
|
253
|
-
agent_ids.append(agent_id)
|
|
254
264
|
|
|
255
265
|
frontmatter = parse_agent_frontmatter(agent_file)
|
|
256
266
|
agent_skills = get_skills_from_agent(frontmatter)
|
|
@@ -260,24 +270,23 @@ def get_required_skills_from_agents(agents_dir: Path) -> Set[str]:
|
|
|
260
270
|
logger.debug(
|
|
261
271
|
f"Agent {agent_id}: {len(agent_skills)} skills from frontmatter"
|
|
262
272
|
)
|
|
273
|
+
else:
|
|
274
|
+
logger.debug(f"Agent {agent_id}: No skills declared in frontmatter")
|
|
263
275
|
|
|
264
|
-
logger.info(
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
# Combine both sources
|
|
270
|
-
required_skills = frontmatter_skills | mapped_skills
|
|
276
|
+
logger.info(
|
|
277
|
+
f"Found {len(frontmatter_skills)} unique skills from agent frontmatter "
|
|
278
|
+
f"(static mapping no longer used)"
|
|
279
|
+
)
|
|
271
280
|
|
|
272
281
|
# Normalize skill paths: convert slashes to dashes for compatibility with deployment
|
|
273
|
-
#
|
|
274
|
-
|
|
275
|
-
normalized_skills = {skill.replace("/", "-") for skill in required_skills}
|
|
282
|
+
# Some skills may use slash format, normalize to dashes
|
|
283
|
+
normalized_skills = {skill.replace("/", "-") for skill in frontmatter_skills}
|
|
276
284
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
285
|
+
if normalized_skills != frontmatter_skills:
|
|
286
|
+
logger.debug(
|
|
287
|
+
f"Normalized {len(frontmatter_skills)} skills to {len(normalized_skills)} "
|
|
288
|
+
"(converted slashes to dashes)"
|
|
289
|
+
)
|
|
281
290
|
|
|
282
291
|
return normalized_skills
|
|
283
292
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
claude_mpm/BUILD_NUMBER,sha256=9JfxhnDtr-8l3kCP2U5TVXSErptHoga8m7XA8zqgGOc,4
|
|
2
|
-
claude_mpm/VERSION,sha256=
|
|
2
|
+
claude_mpm/VERSION,sha256=hPaPbcOTW6MtG4jAk-rO_X3DLacWiuZPeOwlRGpkqWw,7
|
|
3
3
|
claude_mpm/__init__.py,sha256=AGfh00BHKvLYD-UVFw7qbKtl7NMRIzRXOWw7vEuZ-h4,2214
|
|
4
4
|
claude_mpm/__main__.py,sha256=Ro5UBWBoQaSAIoSqWAr7zkbLyvi4sSy28WShqAhKJG0,723
|
|
5
5
|
claude_mpm/constants.py,sha256=CU7v8LZT-cFCNNLZU4dpaMD-4c3ib16v8fVE620wUjk,6761
|
|
@@ -702,7 +702,7 @@ claude_mpm/services/shared/manager_base.py,sha256=kmjhpVqgfYC1N4YQnPAilCfdrSpAh9
|
|
|
702
702
|
claude_mpm/services/shared/service_factory.py,sha256=9yvnD62urrNQCGmtk_3OcR5tVUCnoS6wHkaI5PK34mg,9891
|
|
703
703
|
claude_mpm/services/skills/__init__.py,sha256=X1fPRCGZjteLd35HlhWv2M6tAJ_WbYrEv84kbaqBAiU,742
|
|
704
704
|
claude_mpm/services/skills/git_skill_source_manager.py,sha256=H0MEug2lCix6RHqF4nVt3-Olfe9DM9bKlm_Bw9OJC4g,51529
|
|
705
|
-
claude_mpm/services/skills/selective_skill_deployer.py,sha256=
|
|
705
|
+
claude_mpm/services/skills/selective_skill_deployer.py,sha256=XfNmNn4U8LL6nIPbRhB7j_yMaFsR7tv9bGvx6BrobIU,25836
|
|
706
706
|
claude_mpm/services/skills/skill_discovery_service.py,sha256=riy0PTnJS8e5R2ai8y1KPhBIR7SxlYIa9bnI9YccRMQ,20247
|
|
707
707
|
claude_mpm/services/skills/skill_to_agent_mapper.py,sha256=4PRwcSDSNGS55lg4t-VmBK2ottE_cGFq1zsvjiumAlI,14847
|
|
708
708
|
claude_mpm/services/socketio/__init__.py,sha256=PS-2twllga-2mhSfKdu4MgpikfKp_730gMLAqU_9YX4,556
|
|
@@ -859,10 +859,10 @@ claude_mpm/utils/subprocess_utils.py,sha256=D0izRT8anjiUb_JG72zlJR_JAw1cDkb7kalN
|
|
|
859
859
|
claude_mpm/validation/__init__.py,sha256=YZhwE3mhit-lslvRLuwfX82xJ_k4haZeKmh4IWaVwtk,156
|
|
860
860
|
claude_mpm/validation/agent_validator.py,sha256=GprtAvu80VyMXcKGsK_VhYiXWA6BjKHv7O6HKx0AB9w,20917
|
|
861
861
|
claude_mpm/validation/frontmatter_validator.py,sha256=YpJlYNNYcV8u6hIOi3_jaRsDnzhbcQpjCBE6eyBKaFY,7076
|
|
862
|
-
claude_mpm-5.4.
|
|
863
|
-
claude_mpm-5.4.
|
|
864
|
-
claude_mpm-5.4.
|
|
865
|
-
claude_mpm-5.4.
|
|
866
|
-
claude_mpm-5.4.
|
|
867
|
-
claude_mpm-5.4.
|
|
868
|
-
claude_mpm-5.4.
|
|
862
|
+
claude_mpm-5.4.57.dist-info/licenses/LICENSE,sha256=ca3y_Rk4aPrbF6f62z8Ht5MJM9OAvbGlHvEDcj9vUQ4,3867
|
|
863
|
+
claude_mpm-5.4.57.dist-info/licenses/LICENSE-FAQ.md,sha256=TxfEkXVCK98RzDOer09puc7JVCP_q_bN4dHtZKHCMcM,5104
|
|
864
|
+
claude_mpm-5.4.57.dist-info/METADATA,sha256=Ri9BtdOI3pQPHjXWE67QjqbQ8hfF9qJz2R2YwW-5vpg,37997
|
|
865
|
+
claude_mpm-5.4.57.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
866
|
+
claude_mpm-5.4.57.dist-info/entry_points.txt,sha256=n-Uk4vwHPpuvu-g_I7-GHORzTnN_m6iyOsoLveKKD0E,228
|
|
867
|
+
claude_mpm-5.4.57.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
|
|
868
|
+
claude_mpm-5.4.57.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|