Skip to content

Commit b00b850

Browse files
James Zhuclaude
andcommitted
Fix skill installation to accept both stored keys and install key format from list command
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 67be90f commit b00b850

1 file changed

Lines changed: 71 additions & 6 deletions

File tree

code_assistant_manager/skills/manager.py

Lines changed: 71 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -229,9 +229,25 @@ def get_all(self) -> Dict[str, Skill]:
229229
return self._load_skills()
230230

231231
def get(self, skill_key: str) -> Optional[Skill]:
232-
"""Get a specific skill."""
232+
"""Get a specific skill by key (can be actual key or install key format repo:directory)."""
233233
skills = self._load_skills()
234-
return skills.get(skill_key)
234+
235+
# First try direct lookup with the provided key
236+
skill = skills.get(skill_key)
237+
if skill:
238+
return skill
239+
240+
# If not found, try to find by install key format (repo:directory)
241+
if ":" in skill_key:
242+
repo_part, directory_part = skill_key.rsplit(":", 1)
243+
# Look for skills that match this repo and directory
244+
for stored_skill in skills.values():
245+
if (stored_skill.repo_owner and stored_skill.repo_name and
246+
f"{stored_skill.repo_owner}/{stored_skill.repo_name}" == repo_part and
247+
stored_skill.directory == directory_part):
248+
return stored_skill
249+
250+
return None
235251

236252
def create(self, skill: Skill) -> None:
237253
"""Create a new skill."""
@@ -259,10 +275,24 @@ def upsert(self, skill: Skill) -> None:
259275
logger.info(f"Upserted skill: {skill.key}")
260276

261277
def delete(self, skill_key: str) -> None:
262-
"""Delete a skill."""
278+
"""Delete a skill by key (can be actual key or install key format repo:directory)."""
263279
skills = self._load_skills()
280+
281+
# First try direct lookup with the provided key
264282
if skill_key not in skills:
265-
raise ValueError(f"Skill with key '{skill_key}' not found")
283+
# If not found, try to find by install key format (repo:directory)
284+
if ":" in skill_key:
285+
repo_part, directory_part = skill_key.rsplit(":", 1)
286+
# Look for skills that match this repo and directory
287+
for stored_key, skill in skills.items():
288+
if (skill.repo_owner and skill.repo_name and
289+
f"{skill.repo_owner}/{skill.repo_name}" == repo_part and
290+
skill.directory == directory_part):
291+
skill_key = stored_key
292+
break
293+
else:
294+
raise ValueError(f"Skill with key '{skill_key}' not found")
295+
266296
del skills[skill_key]
267297
self._save_skills(skills)
268298
logger.info(f"Deleted skill: {skill_key}")
@@ -294,13 +324,32 @@ def install(self, skill_key: str, app_type: str = "claude") -> Path:
294324
"""Install a skill for a specific app.
295325
296326
Args:
297-
skill_key: The skill identifier
327+
skill_key: The skill identifier (can be actual key or install key format repo:directory)
298328
app_type: The app type to install to
299329
300330
Returns:
301331
Path to the installed skill directory
332+
333+
Raises:
334+
ValueError: If skill_key is not found
302335
"""
303336
skills = self._load_skills()
337+
338+
# First try direct lookup with the provided key
339+
if skill_key not in skills:
340+
# If not found, try to find by install key format (repo:directory)
341+
if ":" in skill_key:
342+
repo_part, directory_part = skill_key.rsplit(":", 1)
343+
# Look for skills that match this repo and directory
344+
for stored_key, skill in skills.items():
345+
if (skill.repo_owner and skill.repo_name and
346+
f"{skill.repo_owner}/{skill.repo_name}" == repo_part and
347+
skill.directory == directory_part):
348+
skill_key = stored_key
349+
break
350+
else:
351+
raise ValueError(f"Skill with key '{skill_key}' not found")
352+
304353
if skill_key not in skills:
305354
raise ValueError(f"Skill with key '{skill_key}' not found")
306355

@@ -320,10 +369,26 @@ def uninstall(self, skill_key: str, app_type: str = "claude") -> None:
320369
"""Uninstall a skill from a specific app.
321370
322371
Args:
323-
skill_key: The skill identifier
372+
skill_key: The skill identifier (can be actual key or install key format repo:directory)
324373
app_type: The app type to uninstall from
325374
"""
326375
skills = self._load_skills()
376+
377+
# First try direct lookup with the provided key
378+
if skill_key not in skills:
379+
# If not found, try to find by install key format (repo:directory)
380+
if ":" in skill_key:
381+
repo_part, directory_part = skill_key.rsplit(":", 1)
382+
# Look for skills that match this repo and directory
383+
for stored_key, skill in skills.items():
384+
if (skill.repo_owner and skill.repo_name and
385+
f"{skill.repo_owner}/{skill.repo_name}" == repo_part and
386+
skill.directory == directory_part):
387+
skill_key = stored_key
388+
break
389+
else:
390+
raise ValueError(f"Skill with key '{skill_key}' not found")
391+
327392
if skill_key not in skills:
328393
raise ValueError(f"Skill with key '{skill_key}' not found")
329394

0 commit comments

Comments
 (0)