#2544
perf(install): restore each repository once in install
skills experimental_install cloned and discovered the whole source once per skill. A lock with many skills from the same repository paid for the same clone over and over. Restoring 81 skills into an empty .agents/skills/ took 95 seconds. With this change, it takes 10 seconds.
What changes
- Lock entries now group by repository, ref, and source type. Each group clones and discovers its source once, then installs every locked skill it contains.
- When every entry in a group records a
skillPath, the installer reads only thoseSKILL.mdfiles. It no longer walks the whole repository. If a path no longer exists, it falls back to a full walk and finds the moved skill by name. - Up to 4 repositories restore at a time (
SKILLS_INSTALL_CONCURRENCYoverrides this). - If a skill has disappeared upstream, the restore reports it as missing and continues with the rest. The command still exits with code 1.
well-knownentries no longer go throughrunAdd. A newrestoreWellKnownSkillsrestores them from the published index without prompting or exiting.- At the end, the installer writes
skills-lock.jsononce. It skips the write entirely when nothing changed.
What changed in the installer:
installToTargetswrites each skill's canonical copy once per batch instead of once per agent (reuseCanonicalCopy). This also applies toskills addwith more than one agent. The result on disk is the same. It skips the repeated delete-and-copy.- The "no symlink needed" check now compares the agent folder with the canonical folder. It no longer checks
isGlobal && isUniversalAgent. Universal agents already point to the canonical folder, so this covers the same cases and project scope now.
| Before | After | |
|---|---|---|
81 skills, empty .agents/skills/ | 95.4 seconds | 10.0 seconds |
Tests
tests/install.test.ts: every skill from one repository restores through one source install, and well-known sources restore without exiting on a missing skill.tests/install-from-lock.test.ts: a skill deleted upstream does not stop the others. Broken skills elsewhere in the repository do not cause warnings. A moved skill reinstalls with its locked path updated.tests/install-wellknown.test.ts: well-known restore reports a missing skill and an unreachable index without exiting.tests/local-lock.test.ts:addSkillsToLocalLockwrites once and leaves an up-to-date lock untouched.
The full suite passes (989). TypeScript and Prettier pass.
Security review details