1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//! Locate skill-related files under a target path. Recursive vs
//! non-recursive is driven by `ScanOptions`.
//!
//! Submodule split:
//!
//! - [`skill_discovery`] — SKILL.md / `*.skill.md` entrypoints, the
//! AGENTS / CLAUDE / SYSTEM markdown trio, MCP manifests, and
//! heuristic agent-extension candidates.
//! - [`package_artifacts`] — supporting scripts, data files,
//! manifests, and lockfiles co-located with a skill package.
//! - [`classification`] — pure path-shape predicates (constant tables,
//! `is_explicit_skill_file`, the directory skip-list), kept separate
//! so the I/O orchestration above stays focused.
use Path;
use crateFileSystemProvider;
/// Service for discovering skill markdown files.
///
/// Generic over `FileSystemProvider` so callers (the scanner composition
/// root, or tests with mocked filesystems) inject the adapter explicitly.
/// Keeping `services/` free of concrete adapter imports preserves the
/// hexagonal contract: domain/application code depends only on ports.
///
/// Discovery methods are implemented across [`skill_discovery`] and
/// [`package_artifacts`]; this module owns only the shared struct,
/// constructor, and architectural constants.
/// Hard cap on discovery descent depth. Protects against adversarial
/// or runaway directory trees that would otherwise force the walker
/// into pathological recursion (the `SKIP_DISCOVERY_DIRS` exclude-list
/// only catches well-known names like `node_modules`; an attacker can
/// nest under custom names indefinitely). 20 levels comfortably covers
/// every monorepo layout we have seen in benchmarks/corpus and leaves
/// large headroom over typical skill packages (≤ 6 levels).
pub const MAX_DISCOVERY_DEPTH: usize = 20;