fix(curator): scan nested archive subdirs in restore_skill

restore_skill() in tools/skill_usage.py used archive_root.iterdir(), which
only walked the top level of .archive/. Skills archived under nested layouts
(e.g. .archive/openclaw-imports/<skill>/ from older archive paths or
external imports) were invisible to both the exact-match and prefix-match
candidate scans, surfacing as a misleading "skill '<name>' not found in
archive" error even though the directory existed on disk.

Switch both candidate scans to archive_root.rglob('*') so the lookup
descends into category subdirectories.

Fixes #17942
This commit is contained in:
0xDevNinja 2026-04-30 17:55:27 +05:30 committed by Teknium
parent 7913d6a90f
commit 564a649e6a
2 changed files with 40 additions and 3 deletions

View file

@ -385,11 +385,13 @@ def restore_skill(skill_name: str) -> Tuple[bool, str]:
if not archive_root.exists():
return False, "no archive directory"
# Try exact name match first, then any prefix match (for timestamped dupes)
candidates = [p for p in archive_root.iterdir() if p.is_dir() and p.name == skill_name]
# Try exact name match first, then any prefix match (for timestamped dupes).
# Recursive walk handles nested archive layouts (e.g. .archive/<category>/<skill>/)
# left behind by older archive paths or external imports.
candidates = [p for p in archive_root.rglob("*") if p.is_dir() and p.name == skill_name]
if not candidates:
candidates = sorted(
[p for p in archive_root.iterdir()
[p for p in archive_root.rglob("*")
if p.is_dir() and p.name.startswith(f"{skill_name}-")],
reverse=True,
)