139 lines
5.8 KiB
Python
139 lines
5.8 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Fixed Hermes Skills Inventory Tool
|
|
Lists all available skills with their descriptions and linked files.
|
|
Corrected to scan the correct profile-specific skills directory.
|
|
"""
|
|
|
|
import os
|
|
import json
|
|
from pathlib import Path
|
|
|
|
def get_skills(profile="spark"):
|
|
"""Get list of skills from the profile-specific skills directory."""
|
|
skills_dir = f"/root/.hermes/profiles/{profile}/skills"
|
|
if not os.path.exists(skills_dir):
|
|
print(f"No skills directory found at {skills_dir}")
|
|
return []
|
|
|
|
skills = []
|
|
base_path = Path(skills_dir)
|
|
|
|
# Category directories that contain skill subdirectories
|
|
category_names = {'apple', 'autonomous-ai-agents', 'creative', 'devops',
|
|
'email', 'media', 'note-taking', 'productivity',
|
|
'research', 'social-media', 'software-development', 'web'}
|
|
|
|
for item in base_path.iterdir():
|
|
if item.is_dir():
|
|
# Case 1: Category directory (has DESCRIPTION.md, contains skill subdirs)
|
|
if item.name in category_names:
|
|
desc_md = item / 'DESCRIPTION.md'
|
|
if desc_md.exists():
|
|
with open(desc_md, 'r') as f:
|
|
content = f.read()
|
|
# Parse frontmatter for description
|
|
lines = content.split('\n')
|
|
description = ""
|
|
for line in lines:
|
|
if line.startswith('description:'):
|
|
description = line.split(':', 1)[1].strip()
|
|
break
|
|
|
|
# List skill subdirectories within this category
|
|
for subdir in item.iterdir():
|
|
if subdir.is_dir():
|
|
skill_md = subdir / 'SKILL.md'
|
|
if skill_md.exists():
|
|
with open(skill_md, 'r') as f:
|
|
skill_content = f.read()
|
|
skill_lines = skill_content.split('\n')
|
|
skill_desc = ""
|
|
for sline in skill_lines:
|
|
if sline.startswith('description:'):
|
|
skill_desc = sline.split(':', 1)[1].strip().strip('"\'')
|
|
break
|
|
link_files = {"references": [], "templates": [], "scripts": [], "assets": []}
|
|
for link_dir in ["references", "templates", "scripts", "assets"]:
|
|
link_path = subdir / link_dir
|
|
if link_path.exists():
|
|
for f in link_path.iterdir():
|
|
if f.is_file():
|
|
link_files[link_dir].append(f.name)
|
|
skills.append({
|
|
"name": subdir.name,
|
|
"description": skill_desc,
|
|
"has_skill_md": True,
|
|
"linked_files": link_files,
|
|
"category": item.name
|
|
})
|
|
# Case 2: Direct skill directory
|
|
else:
|
|
skill_md = item / 'SKILL.md'
|
|
if skill_md.exists():
|
|
with open(skill_md, 'r') as f:
|
|
content = f.read()
|
|
lines = content.split('\n')
|
|
description = ""
|
|
for line in lines:
|
|
if line.startswith('description:'):
|
|
description = line.split(':', 1)[1].strip().strip('"\'')
|
|
break
|
|
|
|
link_files = {"references": [], "templates": [], "scripts": [], "assets": []}
|
|
for link_dir in ["references", "templates", "scripts", "assets"]:
|
|
link_path = item / link_dir
|
|
if link_path.exists():
|
|
for f in link_path.iterdir():
|
|
if f.is_file():
|
|
link_files[link_dir].append(f.name)
|
|
|
|
skills.append({
|
|
"name": item.name,
|
|
"description": description,
|
|
"has_skill_md": True,
|
|
"linked_files": link_files,
|
|
"category": None
|
|
})
|
|
|
|
return sorted(skills, key=lambda x: x['name'])
|
|
|
|
def main():
|
|
skills = get_skills("spark")
|
|
|
|
print(f"Hermes Skills Inventory (spark profile)")
|
|
print(f"=" * 60)
|
|
print(f"Total skills found: {len(skills)}")
|
|
print()
|
|
|
|
for skill in skills:
|
|
print(f"• {skill['name']}")
|
|
print(f" {skill['description']}")
|
|
if skill.get('category'):
|
|
print(f" Category: {skill['category']}")
|
|
if skill.get('linked_files'):
|
|
has_content = []
|
|
for link_type, files in skill['linked_files'].items():
|
|
if files:
|
|
has_content.append(f"{link_type}({len(files)})")
|
|
if has_content:
|
|
print(f" Linked: {', '.join(has_content)}")
|
|
print()
|
|
|
|
# Write JSON output
|
|
output = {
|
|
"profile": "spark",
|
|
"generated_at": __import__('datetime').datetime.now().isoformat(),
|
|
"total_skills": len(skills),
|
|
"skills": skills
|
|
}
|
|
|
|
output_path = "/root/.hermes/wizard-outputs/spark/skills_inventory_fixed.json"
|
|
with open(output_path, 'w') as f:
|
|
json.dump(output, f, indent=2)
|
|
|
|
print(f"JSON inventory written to: {output_path}")
|
|
return 0
|
|
|
|
if __name__ == "__main__":
|
|
exit(main()) |