#2595
fix(update): honor locked paths with mirrored skills on generic Git sources
Summary
Follow-up to #2231. Fixes #2594.
#2231 let the locked skillPath win over same-name mirrors only when the install URL can carry a subpath. Generic Git and SSH sources stayed fail-closed, because the global reinstall picked the skill by name from the whole clone. This PR removes that reason instead of working around it:
- Global update: for sources that can't carry a subpath in the URL, the locked folder is now applied as
parsed.subpathafter cloning (lockedSubpathForUpdate).resolveSkillsalready handsparsed.subpathtodiscoverSkillsfor clones, so the reinstall finds exactly the locked folder. - Project update: no change needed. Since #2563 it installs the skill discovered at the resolved path from the same clone.
- Resolver: both paths now install from the locked folder for every source type, so
resolveSkillLocationschecks the exact locked path first and theexactPathDisambiguatesoption is gone. A missing locked path with several same-name candidates still fails closed, and a skill locked at the repository root still installs from the root.
Tests
npx vitest run src/skill-relocation.test.ts tests/update.test.ts src/update-source.test.ts: 72 passed.- Changed: the three tests that asserted the generic-Git fail-closed behaviour now assert the update goes through from the locked path (resolver, project update, global SSH update).
- Added: a global generic-Git update with a
.claude/skillsmirror, and unit tests forlockedSubpathForUpdate. pnpm type-checkand Prettier: pass.- Full suite: 1005 passed, 9 failed. The same 9 fail on
mainwithout this change; they are agent-detection and project-guard tests that trip because I ran them from inside an agent session. - End to end: I built
dist/and ranupdate -gin a scratchHOMEagainst a real self-hosted Forgejo repository that has each skill inskills/,.claude/skills/and.agents/skills/. Stock 1.7.4 printed the "Multiple current paths match" warning and updated nothing. This branch updated both skills, and the installed folders are byte-identical toskills/<name>/, not to the older.claude/skills/copies.
AI assistance disclosure
Developed with Claude Code: repository analysis, the change, the tests and this description, under my direction and review.