| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
`skill install` assumed a repository is one skill: it clones the source into `<skills-dir>/<name>` and stops. Claude and Kimi discover skills by scanning exactly one level deep, so a repository whose skills live in subdirectories lands every one of them a level too deep, where nothing will ever find them. `git clone` still exits 0, so moshcode reports the install succeeded. The user gets a green summary and zero usable skills, with nothing to suggest otherwise. - `skillCollection(dir)` reports what a clone actually contains: `single` (a SKILL.md at the root), `collection` (subdirectories holding one), or `empty` - `settleSkillClone(dir)` resolves a clone into the shape engines scan. A single skill is left alone; a collection has each skill moved up beside its siblings and the wrapper removed, since the wrapper holds the repository's README, tooling and CI, none of which is a skill; an empty clone is removed rather than left as a directory that can never resolve - claude and kimi actions carry the clone target as `settle`, so the runner resolves them after a successful clone. Gemini installs natively and is never settled - a clone containing no SKILL.md anywhere is now reported as failed with that reason, instead of counting as installed - results carry `kind`, `skills` and `kept`, so the summary can say what landed A skill whose name is already taken is left alone and reported in `kept`. This runs inside the user's real skills directory, so a name collision must never silently replace a skill they already had. `settle` is injectable alongside `run`, matching how the suite already stubs subprocesses. Three existing tests stubbed `run` without it, so the real settle correctly found an empty directory where a stubbed clone never landed; they now stub both. Verified end to end against a real 13-skill collection: 0 discoverable before, 13 after, wrapper removed. Full suite green (2171 pass, 0 fail). Extends prd/0003. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B7KVQWbU17PR2mCUn8jjpH
ThreatCrush Security Scan0 finding(s) in the 6 file(s) this pull request changes. Nothing in the files this pull request changes. 59 pre-existing finding(s) elsewhere in the repository — **HIGH/CRITICAL**: 5 | **MEDIUM**: 48 | **LOW**: 6Not introduced by this pull request. The full set is in the Security tab.
…and 39 more. Full results in the Security tab. Snippets are redacted; ThreatCrush never prints matched credential material. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
The bug
skill install assumes a repository is one skill. It clones the source into <skills-dir>/<name> and stops.
Claude and Kimi discover skills by scanning exactly one level deep. So a repository whose skills live in subdirectories — a collection — lands every one of them a level too deep, where nothing will ever find them.
git clone still exits 0, so moshcode reports the install succeeded. The user gets a green summary and zero usable skills, with nothing to suggest otherwise. That silence is the part worth fixing: a loud failure here would have been harmless.
Verified against a real 13-skill collection before the change:
The change
After:
Safety
A skill whose name is already taken is left alone and reported in kept. This runs inside the user's real skills directory, so a name collision must never silently replace a skill they already had. There's a test pinning exactly that.
On the test changes
settle is injectable alongside run, matching how the suite already stubs subprocesses.
Three existing tests stubbed run without it. With a stubbed clone nothing ever lands, so the real settle correctly found an empty directory and reported failure — the new strictness working as intended, on a fixture that was never meant to exercise it. Those tests now stub both. The skillInstallAction deep-equals were updated to assert the new settle field rather than ignore it.
Verification
Extends prd/0003, which set out the fan-out but assumed one repository is one skill.
🤖 Generated with Claude Code
https://claude.ai/code/session_01B7KVQWbU17PR2mCUn8jjpH