ExternalConfigs.Loader (fnord v0.9.34)
View SourceDiscovers and loads Cursor rules, Cursor skills, and Claude Code skills from the user's home directory and the current project's source root.
Project-scoped entries override user/global entries of the same name (CSS-style layering).
Summary
Functions
Clears all external-configs loader caches. Call from tests that mutate the on-disk rules/skills mid-test; production code should never need this since the escript VM is short-lived.
Remove cursor skills that duplicate a claude skill, preferring claude.
Cheap on-disk presence check, used by the coordinator's startup nudge to detect "feature is off, but the files are sitting right there." Skips parsing; just asks whether any candidate file exists under the global or project search paths for the given source.
Load all enabled external configs for the given project, honoring the
per-project external_configs settings toggles.
Load all Claude Code subagents (global + project), project overriding global by name. Cached per session and per project.
Load all Claude Code skills (global + project), project overriding global. Cached per session and per project.
Load only cursor rules (global + project) regardless of settings. Cached per session and per project. The hot path is the Injector, which reruns this on every file read/write while the rule set is stable for the life of the invocation.
Load all cursor skills (global + project), project overriding global. Cached per session and per project.
Types
@type loaded() :: %{ cursor_rules: [ExternalConfigs.CursorRule.t()], cursor_skills: [ExternalConfigs.Skill.t()], claude_skills: [ExternalConfigs.Skill.t()], claude_agents: [ExternalConfigs.Agent.t()] }
Functions
@spec clear_cache() :: :ok
Clears all external-configs loader caches. Call from tests that mutate the on-disk rules/skills mid-test; production code should never need this since the escript VM is short-lived.
@spec dedup_cross_flavor([ExternalConfigs.Skill.t()], [ExternalConfigs.Skill.t()]) :: [ ExternalConfigs.Skill.t() ]
Remove cursor skills that duplicate a claude skill, preferring claude.
Two dedup passes run in order:
Inode identity — cursor skills whose on-disk directory resolves to the same inode as a claude skill are dropped. Handles individual directory symlinks and whole-tree symlinks at any depth.
File.stat/1follows symlinks; cursor entries that cannot be stat'd are kept (conservative: don't silently drop on filesystem errors).Name identity — cursor skills whose name matches a claude skill are dropped even when stored at a distinct path. A same-name clash across flavors almost always means one is a copy or re-export of the other.
@spec has_any_on_disk?(Store.Project.t(), Settings.ExternalConfigs.source()) :: boolean()
Cheap on-disk presence check, used by the coordinator's startup nudge to detect "feature is off, but the files are sitting right there." Skips parsing; just asks whether any candidate file exists under the global or project search paths for the given source.
@spec load(Store.Project.t()) :: loaded()
Load all enabled external configs for the given project, honoring the
per-project external_configs settings toggles.
@spec load_claude_agents(Store.Project.t()) :: [ExternalConfigs.Agent.t()]
Load all Claude Code subagents (global + project), project overriding global by name. Cached per session and per project.
@spec load_claude_skills(Store.Project.t()) :: [ExternalConfigs.Skill.t()]
Load all Claude Code skills (global + project), project overriding global. Cached per session and per project.
Skills flagged for self-delegation (see ExternalConfigs.Skill -
fnord_skip) are dropped here, before any consumer sees them. The drop
is logged once per cache miss with the offending path.
@spec load_cursor_rules(Store.Project.t()) :: [ExternalConfigs.CursorRule.t()]
Load only cursor rules (global + project) regardless of settings. Cached per session and per project. The hot path is the Injector, which reruns this on every file read/write while the rule set is stable for the life of the invocation.
@spec load_cursor_skills(Store.Project.t()) :: [ExternalConfigs.Skill.t()]
Load all cursor skills (global + project), project overriding global. Cached per session and per project.
Skills flagged for self-delegation (see ExternalConfigs.Skill -
fnord_skip) are dropped here, before any consumer sees them. The drop
is logged once per cache miss with the offending path.