Repository navigation
Description
What happens today
The skill loader reads exactly two roots: ~/.emrg/skills (labelled user) and <agent>/.emrg/skills (labelled agent). Every skill that lives anywhere else is invisible to the prompt and to the /skills screen, so a skill installed into ~/.claude/skills or ~/.agents/skills has to be copied by hand before it can be used.
Where a name exists in more than one of those places there is also no rule saying which copy is in effect. The loader resolves the one collision it knows about (agent beats user); every other overlap is decided by whichever directory happened to be read last, and nothing records that it happened.
A third defect sits in the frontmatter reader: it treats an indented line as nested YAML and skips it, and it stores a key: value verbatim. So a description written as a YAML block scalar — description: >, >- or |, the form these directories' skills actually use — comes back as the literal indicator >- with every line of the real text discarded, and a skill with a multi-line description is described by a two-character string.
What it must become
Read four roots, lowest precedence first, and let a later root's declaration of a name replace an earlier one's:
| order | root | label |
|---|---|---|
| 1 | ~/.claude/skills |
claude |
| 2 | ~/.agents/skills |
agents |
| 3 | ~/.emrg/skills |
user |
| 4 | <agent>/.emrg/skills |
agent |
- A root that does not exist is skipped silently; the other roots are unaffected.
- Each root keeps reading both layouts,
<name>.mdand<name>/SKILL.md, and the bundle wins over the flat file inside one root. - A skill's rendered entry names which of the four roots it came from — the three default roots must be distinguishable from each other, not folded into one
userlabel. - A declaration that lost its name stays listed under Shadowed names, with the source root and file path of both sides, so the agent tier can say which default root's copy it displaced.
description:written as>,>-,|or|-is read as its real text, with its lines joined; the indicator itself is never the description and no line is dropped.- The root list is a parameter of the loader whose default is the four paths above, so a test never reads a directory that happens to exist on the machine running it.
Acceptance
- A name present in all three default roots resolves to the
~/.emrg/skillscopy, with the other two reported as shadowed. - A name present only in
~/.claude/skillsand~/.agents/skillsresolves to the~/.agents/skillscopy. - A name present once loads normally and its entry names that root.
- A root that does not exist is skipped without disturbing the others.
<name>.mdand<name>/SKILL.mdin one root resolve to the bundle.- A skill in the agent root that shares a name with a default root wins, and the shadow line names the default root it displaced.
description: >-,>,|and|-all read as their real multi-line text, never as the indicator.- Reversing the read order, moving the agent root below the three defaults, and removing the block-scalar handling each turn the corresponding row red.
Activity
argszero commentedon Oct 30, 2026
Handled by #2655