Skip to content

Commit bc2e83f

Browse files
committed
fix(discovery): retain siblings beside symlink
Signed-off-by: Deepak Jain <[email protected]>
1 parent 84b41e2 commit bc2e83f

2 files changed

Lines changed: 15 additions & 7 deletions

File tree

‎src/skillspector/multi_skill.py‎

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -231,10 +231,10 @@ def detect_skills(directory: Path) -> MultiSkillDetectionResult:
231231
232232
A directory is considered multi-skill when it has no root ``SKILL.md`` and
233233
at least two immediate child directories contain a manifest or supported
234-
structured skill bundle. Any discovery limit or filesystem ambiguity
235-
discards all partial classifications and returns ``complete == False``.
236-
Callers can then fall back to a bounded monolithic scan and propagate the
237-
supplied limitation to their public completeness surfaces.
234+
structured skill bundle. Discovery limits and filesystem ambiguities return
235+
``complete == False``. A symlinked immediate child is the narrow exception:
236+
it is never traversed, but already classified non-link siblings remain
237+
available for a bounded recursive scan with the supplied limitation.
238238
"""
239239
absolute_directory = Path(os.path.abspath(directory))
240240
try:
@@ -273,12 +273,19 @@ def detect_skills(directory: Path) -> MultiSkillDetectionResult:
273273
return MultiSkillDetectionResult(is_multi_skill=False, has_root_skill=True)
274274

275275
skills: list[SkillDirectory] = []
276+
limitations: list[MultiSkillDetectionLimitation] = []
276277
for entry in _bounded_scandir(directory, budget=budget):
277278
budget.check_runtime()
278279
child = Path(entry.path)
279280
try:
280281
if entry.is_symlink() or _is_link_or_junction(child):
281-
raise _read_error("multi_skill_symlinked_entry")
282+
limitations.append(
283+
MultiSkillDetectionLimitation(
284+
reason_code="read_error",
285+
resource="multi_skill_symlinked_entry",
286+
)
287+
)
288+
continue
282289
if not entry.is_dir(follow_symlinks=False):
283290
continue
284291
except OSError as exc:
@@ -310,6 +317,7 @@ def detect_skills(directory: Path) -> MultiSkillDetectionResult:
310317
is_multi_skill=len(skills) >= 2,
311318
skills=skills,
312319
has_root_skill=False,
320+
limitations=tuple(limitations),
313321
entries_examined=budget.entries,
314322
structured_candidates_examined=budget.structured_candidates,
315323
structured_input_bytes_examined=budget.structured_bytes,

‎tests/test_multi_skill.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,8 @@ def test_symlinked_skill_directory_marks_discovery_incomplete(self, tmp_path: Pa
310310

311311
result = detect_skills(tmp_path)
312312

313-
assert result.is_multi_skill is False
314-
assert result.skills == []
313+
assert result.is_multi_skill is True
314+
assert {skill.name for skill in result.skills} == {"skill-a", "skill-b"}
315315
assert result.complete is False
316316
assert result.limitations[0].reason_code == "read_error"
317317
assert result.limitations[0].resource == "multi_skill_symlinked_entry"

0 commit comments

Comments
 (0)