Skip to content

skill_manage patch/edit/delete can't find skills from external_dirs #4759

@BongSuCHOI

Description

@BongSuCHOI

Problem

skill_manage operations (patch, edit, delete, write_file, remove_file) fail with "Skill not found" for skills loaded from external_dirs.

The root cause is that _find_skill() in tools/skill_manager_tool.py only scans SKILLS_DIR (~/.hermes/skills/) via rglob("SKILL.md"), but:

  1. rglob does not follow symlinks on Python 3.11+, so symlinked skill directories (pointing to an external git repo) are invisible
  2. external_dirs are never scanned by _find_skill(), even though _find_all_skills() (used for listing/viewing) correctly scans them

This creates an inconsistency where skills are visible and loadable, but not editable via skill_manage.

Steps to Reproduce

# 1. Set up external_dirs in config.yaml
# skills:
#   external_dirs:
#     - ~/skills/skills

# 2. Skills from external_dirs are visible
# hermes skills list  # shows all skills from external_dirs ✅

# 3. But skill_manage can't find them
# In a session:
skill_manage(action='patch', name='cron-gateway-restart', old_string='...', new_string='...')
# → {"success": false, "error": "Skill 'cron-gateway-restart' not found."} ❌

Relevant Code

  • _find_skill() at tools/skill_manager_tool.py:209 — only uses SKILLS_DIR.rglob()
  • _find_all_skills() at tools/skills_tool.py:512 — correctly scans both SKILLS_DIR and external_dirs
  • _resolve_skill_dir() at tools/skill_manager_tool.py:197 — only builds paths under SKILLS_DIR

Expected Behavior

skill_manage should be able to patch/edit/delete skills that are discoverable via _find_all_skills(). If a skill appears in the skill list, all operations should work on it.

Possible Approaches

  1. Reuse _find_all_skills() lookup_find_skill() could leverage the same scanning logic (or its result) to locate skill directories, including external_dirs
  2. Add external_dirs scanning to _find_skill() — mirror the dirs_to_scan pattern from _find_all_skills()
  3. Resolve symlink paths — use os.walk(followlinks=True) instead of rglob to follow symlinks

Note: Approach 1 would also need to return the actual Path to the skill directory (not just metadata), which _find_all_skills() currently does not do.

Environment

  • Python 3.11.15
  • Hermes Agent v0.6.0 (latest main as of 2026-04-03)
  • OS: Oracle Linux 9 (aarch64)

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — degraded but workaround existstool/skillsSkills system (list, view, manage)type/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions