Turns a plain-language request into the body of the skill that handles it.
config.json maps each skill to the keywords that trigger it and the file
paths where that skill’s SKILL.md lives. The resolver matches keywords
against a message, loads the matching skill bodies, and prints them — ready to
be injected into the agent’s context before the task is attempted.
python3 resolver.py "query the sqlite db for open invoices"
Other flags:
python3 resolver.py "extract this PDF" --json # machine-readable output
python3 resolver.py "check the weather" --debug # show what matched, and why
python3 resolver.py "render a mermaid diagram" --skills-dir ~/.openclaw/skills
With no message argument the resolver reads stdin:
echo "make a spreadsheet of this data" | python3 resolver.py
Exit code is always 0 — an unmatched message is a valid result, not an error.
pdf, csv).db does not fire on
“database” but database does not fire on “databases” either.config.json whose keyword list matches wins for each
distinct match — several skills can match one message.For each match, the resolver tries the skill’s paths from config.json in
order (with ~ expanded), then falls back to
<skills-dir>/<slug>/SKILL.md. If no body is found the match is skipped
rather than emitted empty.
Add an entry under "skills" in config.json:
"weather": {
"keywords": ["weather", "forecast", "temperature"],
"slug": "weather",
"paths": ["~/.openclaw/skills/weather/SKILL.md"]
}
keywords — the phrases that should trigger this skill.slug — the directory name used for the <skills-dir>/<slug>/SKILL.md
fallback.paths — explicit locations to search first, most specific first.Then verify it resolves:
python3 resolver.py "what's the weather" --debug
config.json — keyword and path mappings.resolver.py — the matcher and loader.