How to Load Custom Skills from Extra Paths in Reasonix
Reasonix loads custom skills from user-specified directories by resolving paths through resolveCustomPaths, deduplicating them with dedupePaths, and appending them as ScopeCustom roots in the discovery hierarchy, where they are scanned recursively for Markdown skill files.
The DeepSeek-Reasonix engine extends its agent capabilities through skills—Markdown playbooks that define specialized behaviors. While the system automatically discovers skills from built-in collections and project-local conventions, you can load custom skills from extra paths by configuring the skill.Store with additional directory roots that are resolved, deduplicated, and integrated into the discovery pipeline.
Configuring Custom Skill Paths
The entry point for loading external skills is the skill.Options struct passed when creating a new skill store.
Setting Up CustomPaths in Options
The CustomPaths field accepts a slice of strings representing directories to scan. These entries may include absolute paths, paths relative to the project root, or ~-prefixed shortcuts to the user's home directory.
In internal/skill/skill.go, the New function processes these paths before the store initializes. The resolveCustomPaths helper (lines 3939-3959) expands tilde notation to the OS home directory and joins relative entries to the project base directory, converting all entries to absolute canonical paths.
Path Deduplication and Normalization
After resolution, the system eliminates duplicate entries to prevent redundant scanning. The dedupePaths function (lines 3962-3974) filters the slice, ensuring each custom directory appears only once in the discovery list while preserving the original order of first occurrence.
Discovery Hierarchy and Root Construction
Once paths are normalized, the skill store constructs an ordered list of directories to scan, establishing priority rules for skill resolution.
How Store.roots() Orders Custom Paths
The Store.roots() method (lines 188-200 of internal/skill/skill.go) builds the discovery hierarchy by appending each processed custom path to the roots list with the ScopeCustom label. This placement ensures that custom skills take precedence over global home directory skills but yield priority to project-local convention directories (.reasonix, .agents, etc.), creating a clear override hierarchy.
The ScopeCustom Label and Priority
When custom paths are added as roots, they receive the ScopeCustom identifier. This scope tag is stored in the Skill.Scope field during parsing, allowing the system to track origin and enforce precedence rules. If duplicate skill names exist across different scopes, the discovery ordering—project-local first, then custom paths, then global—determines which version the engine selects.
Scanning and Loading Skill Files
With the root hierarchy established, the store recursively scans each custom directory for valid skill definitions.
Directory Traversal with scanDir
For every root marked as ScopeCustom, the scanDir function (lines 445-475) walks the directory tree respecting the configured maximum depth. When it encounters a skill file (Markdown) or a skill directory containing a SKILL.md file, it triggers the parsing pipeline.
Skill Parsing and Scope Assignment
The readEntry function parses discovered Markdown files into skill.Skill values, assigning the root's scope (ScopeCustom) to the resulting struct. This metadata ensures that when you invoke Store.List(), custom-loaded skills appear alongside built-in ones, with precedence rules already applied. Skills discovered in extra paths are immediately available to the model via the /skill-name command or the run_skill tool.
Implementation Example
To load skills from user-specified directories, configure the Options struct with your custom paths before initializing the store:
// Create a skill store that loads extra skills from two user‑specified dirs.
opts := skill.Options{
HomeDir: "", // use the OS home dir
ProjectRoot: "/my/project", // optional project root
CustomPaths: []string{
"~/my‑skills", // expands to $HOME/my‑skills
"./extra‑skills", // relative to the project root
},
}
store := skill.New(opts)
// List all skills, including those from the extra paths.
for _, sk := range store.List() {
fmt.Printf("%s (%s) – %s\n", sk.Name, sk.Scope, sk.Description)
}
This configuration expands ~/my-skills to the absolute home directory path and resolves ./extra-skills relative to /my/project, then scans both directories for Markdown skill files.
Summary
- Configure custom paths using
skill.Options.CustomPaths, which accepts absolute, relative, or~-prefixed directory strings. - Path resolution occurs in
resolveCustomPaths(lines 3939-3959), which expands shortcuts and normalizes entries to absolute paths. - Deduplication is handled by
dedupePaths(lines 3962-3974) to prevent redundant scanning of the same directory. - Discovery hierarchy places custom paths between project-local and global directories via
Store.roots()(lines 188-200), using theScopeCustomlabel. - Recursive scanning via
scanDir(lines 445-475) loads Markdown skills from extra directories, making them available throughStore.List()with proper precedence rules.
Frequently Asked Questions
How do I specify multiple custom skill directories in Reasonix?
Pass a slice of strings to Options.CustomPaths when creating the skill store. You can mix absolute paths, paths relative to the project root, and ~ shortcuts for the home directory. The system automatically resolves and deduplicates these entries before scanning.
What happens if a custom skill has the same name as a built-in skill?
Reasonix resolves naming conflicts through scope precedence. Project-local skills take highest priority, followed by custom paths (ScopeCustom), then global home directory skills. If your custom path skill conflicts with a built-in one, the custom version wins because custom roots are scanned before the global home directory.
Can I use relative paths for custom skill directories?
Yes. Relative paths in CustomPaths are resolved against the ProjectRoot field specified in Options. If you provide ./extra-skills and set ProjectRoot to /my/project, the system scans /my/project/extra-skills according to the resolveCustomPaths implementation.
Does Reasonix support nested directories within custom skill paths?
Yes. The scanDir function performs a recursive directory walk respecting the configured maximum depth, discovering skill files and SKILL.md entries at any level within your custom path hierarchy. This allows you to organize skills into subdirectories by category or function.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →