pub struct Registry { /* private fields */ }Expand description
Builder for a skills ResolvedRegistry. Downstream binaries
(kglite-mcp-server, etc.) construct one of these in their
boot path, layer in their bundled + operator-declared skills,
then call Registry::finalise to get the resolved set
ready for MCP prompts/list + prompts/get wiring.
See the module docs for the canonical usage pattern.
Implementations§
Source§impl Registry
impl Registry
Sourcepub fn new() -> Self
pub fn new() -> Self
Construct an empty registry. Chain in add_bundled,
merge_framework_defaults, layer_dirs,
auto_detect_project_layer, and optionally
with_predicate_evaluator, then call finalise().
Sourcepub fn with_predicate_evaluator(
self,
evaluator: impl SkillPredicateEvaluator + 'static,
) -> Self
pub fn with_predicate_evaluator( self, evaluator: impl SkillPredicateEvaluator + 'static, ) -> Self
Register a domain-specific predicate evaluator for the
applies_when: machinery. The evaluator only sees domain
predicates (graph_has_node_type, graph_has_property);
framework-internal ones (tool_registered,
extension_enabled) are dispatched against the
McpServer’s runtime state at
serve_prompts time.
Without an evaluator, skills using domain predicates resolve
to inactive (predicate Unknown → skill suppressed). This
is the safe default: a typo’d predicate or a missing
evaluator must not silently activate the wrong-domain skill.
Sourcepub fn add_bundled(self, skill: BundledSkill) -> Self
pub fn add_bundled(self, skill: BundledSkill) -> Self
Add a compile-time bundled skill. Typically called by
downstream binaries with their own include_str!’d skills,
once per custom tool.
Bundled skills sit at the bottom of the three-layer
composition; later layers override them when names collide.
Within the bundled set, the downstream binary’s skills win
over framework defaults (the downstream calls add_bundled
before or after merge_framework_defaults — order doesn’t
matter; resolution dedupes by name with downstream-first
priority).
Malformed bundled skills are reported at finalise() time
via SkillError::BundledSkillInvalid. The framework’s
own bundled-skill CI test should catch this for the library
defaults; downstream binaries should write equivalent tests
for their own bundled set.
Sourcepub fn add_bundled_many(
self,
skills: impl IntoIterator<Item = BundledSkill>,
) -> Self
pub fn add_bundled_many( self, skills: impl IntoIterator<Item = BundledSkill>, ) -> Self
Add a batch of compile-time bundled skills.
Sourcepub fn merge_framework_defaults(self) -> Self
pub fn merge_framework_defaults(self) -> Self
Merge in the framework’s own bundled defaults (returned by
library_bundled_skills). Idempotent — calling twice is
harmless (later calls add duplicates which the finalise
deduper drops, downstream-first).
Sourcepub fn layer_dirs(
self,
source: &SkillsSource,
yaml_path: &Path,
) -> Result<Self, SkillError>
pub fn layer_dirs( self, source: &SkillsSource, yaml_path: &Path, ) -> Result<Self, SkillError>
Layer in skill directories declared in the manifest’s
skills: field, walked in declaration order. Each path
becomes a domain-pack-layer source; the bundled marker
true is acknowledged but its skills are already in the
bundled layer via add_bundled/merge_framework_defaults.
Path resolution uses the same conventions as the rest of the
manifest (./foo relative to YAML dir, ~/foo home-relative,
/foo absolute). Non-existent paths are reported as
SkillError::PathNotFound at this call site so operators
see typos immediately.
Sourcepub fn auto_detect_project_layer(self, yaml_path: &Path) -> Self
pub fn auto_detect_project_layer(self, yaml_path: &Path) -> Self
Auto-detect the project layer at <basename>.skills/
adjacent to the manifest YAML. Always called; the directory
is optional — if it doesn’t exist, the project layer is
simply empty.
Sourcepub fn finalise(self) -> Result<ResolvedRegistry, SkillError>
pub fn finalise(self) -> Result<ResolvedRegistry, SkillError>
Resolve all three layers and return the final registry.
Resolution order per skill name: project > root layer (in declaration order) > bundled. The first source that contributes a skill with the given name wins; later sources are ignored for that name (no merging, no inheritance — full-file replacement).
At this point the framework:
- Parses all skill files (frontmatter validation)
- Logs collision-resolution info via
tracing::info!per skill - Enforces per-skill hard size limits (
HARD_SIZE_LIMIT_BYTES) - Warns on per-skill soft size limit (
SOFT_SIZE_LIMIT_BYTES) - Warns on session total exceeding
SESSION_TOTAL_LIMIT_BYTES