How to Handle Skill Version Conflicts and Manage Updates in Agent-Skills
Agent-skills detects version conflicts by comparing semantic versions stored in a shared lockfile against the skills registry, automatically triggering updates when the registry version is newer while supporting manual overrides for edge cases.
The agent-skills framework maintains consistency across distributed skill installations through a sophisticated versioning system centered on a shared lockfile (LOCK_FILE). By tracking semantic versions and content metadata in libs/core/src/lib/services/lockfile.service.ts, the system automates conflict detection and update management. Understanding how to handle skill version conflicts ensures your agents always run compatible, up-to-date capabilities.
Understanding the Lockfile Architecture
The lockfile serves as the single source of truth for installed skills. It stores each skill's semantic version in the version field, alongside installation metadata. The schema is versioned itself (CURRENT_VERSION = 2) and supports automatic migration from older formats.
When a skill is installed, the addSkillToLock function in libs/core/src/lib/services/lockfile.service.ts records the version extracted from the skill's front-matter:
export async function addSkillToLock(
ports: CorePorts,
skillName: string,
agents: AgentType[],
options: {
source?: string
contentHash?: string
method?: 'copy' | 'symlink'
global?: boolean
version?: string // β version from SKILL.md metadata
} = {},
) { β¦ }
The lockfile is written atomically via writeSkillLock, which creates a backup copy before persisting changes. This guarantees that failed updates never corrupt the lockfile state.
How Conflict Detection Works
During skill-install or skill-update operations, the CLI compares installed versions against the skills registry (skills-registry.json). This registry is generated by packages/skills-catalog/src/generate-registry.ts and maps each skill name to its latest published version.
The detection logic follows these steps:
- Read lockfile β
readSkillLockloads the current state, handling missing or corrupted files gracefully. - Fetch registry β The CLI downloads the latest
skills-registry.jsoncontaining{ name β { version, β¦ } }entries. - Compare versions β For each installed skill, if
registryVersion > lockVersion, a conflict is detected. - Trigger update β The system automatically queues the skill for replacement.
The Automatic Update Flow
When a newer version is detected, the installer executes a transactional update:
- Download the new skill files from the registry source.
- Copy or symlink files into the agent's skill directory using the specified method (
copyorsymlink). - Call
addSkillToLockwith the newversionstring to update the metadata. - Persist changes atomically via
writeSkillLock.
Version Comparison Logic
The system uses standard semantic versioning (MAJOR.MINOR.PATCH) for comparisons. The implementation in the codebase splits version strings and performs numeric comparison:
function isNewer(registryVersion: string, lockVersion: string): boolean {
// Simple semver compare β works for MAJOR.MINOR.PATCH
const [rM, rN, rP] = registryVersion.split('.').map(Number);
const [lM, lN, lP] = lockVersion.split('.').map(Number);
return rM > lM || (rM === lM && (rN > lN || (rN === lN && rP > lP)));
}
This logic ensures that 1.2.0 is correctly identified as older than 1.3.1, while 2.0.0 takes precedence over any 1.x.x release.
Handling Prerelease Versions
The updater automatically skips automatic upgrades for prerelease versions to prevent instability. The detection logic in packages/cli/src/services/update-check.ts identifies prerelease tags using a regex pattern:
function isPrerelease(version: string): boolean {
return /-(alpha|beta|rc|snapshot|dev|canary|next)/i.test(version);
}
If you have version 1.0.0-beta installed, the CLI will not auto-update it even if 1.0.0 stable is published. This mirrors the CLI's own update-check behavior and prevents accidental migrations to untested releases.
Manual Conflict Resolution
For edge cases where a skill author publishes a critical patch without changing the version number, the CLI provides a force-update mechanism. When invoked with the appropriate flag, the installer overwrites the lock entry regardless of version comparison results.
You can also force-update prerelease skills that would otherwise be skipped:
await addSkillToLock(ports, 'my-skill', ['cursor'], {
source: 'registry',
version: '2.0.0',
method: 'copy',
// The `global` flag can be set if the skill lives in the global cache.
});
Direct lockfile editing is also supported for advanced scenarios, though the atomic write mechanisms in writeSkillLock should be respected to prevent corruption.
Best Practices for Skill Developers
Maintaining version integrity requires coordination between skill authors and consumers:
- Keep
SKILL.mdfront-matter updated β Always include accuratemetadata.versionfields. The generator intools/skill-plugin/src/generators/skill/skill.tsdefaults new skills to1.0.0. - Regenerate the registry β Run
npm run generate:datato refreshskills-registry.jsonviapackages/skills-catalog/src/generate-registry.tsafter publishing updates. - Commit lockfile changes β Treat the lockfile as a dependency manifest. The
migrateLockFilefunction automatically upgrades older lockfile schemas (v1) to the current version (v2) without data loss. - Schedule periodic updates β Regularly invoke
agent-skills installto allow the CLI to detect and apply newer versions automatically. - Use
--forcesparingly β Reserve manual overrides for emergency patches or prerelease testing scenarios.
Summary
- Version storage occurs in a shared lockfile managed by
lockfile.service.ts, with each skill's semantic version recorded during installation. - Conflict detection compares lockfile entries against
skills-registry.json, treating newer registry versions as update triggers. - Atomic updates ensure lockfile integrity through backup-and-replace logic in
writeSkillLock, preventing corruption during failed operations. - Prerelease protection automatically skips versions matching
-(alpha|beta|rc|snapshot|dev|canary|next)patterns to maintain stability. - Manual overrides via force-update flags allow administrators to bypass version checks when necessary.
Frequently Asked Questions
How does agent-skills determine if a skill needs updating?
The system compares the version string stored in the lockfile against the version published in skills-registry.json. If the registry version is semantically greater (e.g., 1.2.0 vs 1.1.5), the CLI flags a conflict and queues the skill for automatic update. This comparison uses numeric parsing of MAJOR.MINOR.PATCH segments in libs/core/src/lib/services/lockfile.service.ts.
What happens if the lockfile becomes corrupted?
The readSkillLock function handles missing or corrupted lockfiles gracefully by returning a default empty state or attempting recovery. When writing updates, writeSkillLock creates a backup copy before persisting changes, ensuring you can restore the previous state if the write operation fails mid-process.
Can I prevent automatic updates for specific skills?
Yes. Installing a prerelease version (e.g., 2.0.0-beta) automatically opts that skill out of automatic updates, as detected by the isPrerelease function in packages/cli/src/services/update-check.ts. For stable versions, you can pin skills by avoiding agent-skills install operations or manually editing the lockfile version field to mismatch the registry (though this is not recommended for production environments).
How do I migrate from an old lockfile format?
The system handles migration automatically. When readSkillLock detects a lockfile with schema version 1 (or older), it invokes migrateLockFile to upgrade the structure to CURRENT_VERSION = 2 while preserving all version data and agent assignments. No manual intervention is required.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too β