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:

  1. Read lockfile – readSkillLock loads the current state, handling missing or corrupted files gracefully.
  2. Fetch registry – The CLI downloads the latest skills-registry.json containing { name β†’ { version, … } } entries.
  3. Compare versions – For each installed skill, if registryVersion > lockVersion, a conflict is detected.
  4. 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:

  1. Download the new skill files from the registry source.
  2. Copy or symlink files into the agent's skill directory using the specified method (copy or symlink).
  3. Call addSkillToLock with the new version string to update the metadata.
  4. 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.md front-matter updated – Always include accurate metadata.version fields. The generator in tools/skill-plugin/src/generators/skill/skill.ts defaults new skills to 1.0.0.
  • Regenerate the registry – Run npm run generate:data to refresh skills-registry.json via packages/skills-catalog/src/generate-registry.ts after publishing updates.
  • Commit lockfile changes – Treat the lockfile as a dependency manifest. The migrateLockFile function automatically upgrades older lockfile schemas (v1) to the current version (v2) without data loss.
  • Schedule periodic updates – Regularly invoke agent-skills install to allow the CLI to detect and apply newer versions automatically.
  • Use --force sparingly – 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too β†’