#2630

fix(update): preserve agent symlink destinations during skill updates

Openmdsmithaustinwants to merge intofrom

Why

Updates reuse detected-agent targeting from add -y, so an existing Hermes directory can gain links for skills installed only for Claude Code. Refresh shared content while preserving each skill's existing destinations.

Refs #1718.

What changed

  • Refresh shared content without creating or restoring agent links in global and project updates. Only canonical-matching links identify shared installations.
  • Warn about preserved redirects, show their targets, and print source- and scope-correct recovery guidance for a named shell. Unrelated inspection errors remain nonfatal when shared storage already exists.
  • Retain explicit copy behavior and handle placement failures per skill, with isolated CLI regressions for link ownership, aliases, copies, notices, and batch continuation.

Scope

  • Fix symlink-mode update targeting. Explicit add, removal behavior from #1786, and direct shared-directory visibility remain unchanged.
  • No new flags or lock-schema changes. Broader copy-mode, exclusion, and well-known copy-metadata fixes remain outside scope.
  • Independent copies beside shared content remain unchanged, except existing Eve stores.

Tradeoffs

An erased installation without copy metadata has no recoverable agent selection. When selected for reinstall, it receives shared content without guessed links. Shared refreshes refuse a canonical skill directory that is itself a symlink. Foreign links remain untouched; Eve flat links require manual review before reinstalling.

Blast Radius

This changes update placement and feedback. Filesystem inference preserves current destinations but cannot distinguish accidental deletion from intentional removal.

Verification

  • The original eight CLI regressions failed before the targeting fix. Follow-up coverage produced 21 expected failures before these enhancements; the 91 destination cases now pass.
  • Isolated Linux, Node 24.20.0 and pinned pnpm 10.17.1: build, 1,143 tests in 79 files, type checking, and formatting passed. The focused macOS run passed 176 tests in six files.
  • Fixtures use temporary homes/projects, local Git, and loopback HTTP. POSIX recovery arguments were parsed through sh; PowerShell rendering was simulated. The upstream Windows and Node matrix still requires CI approval.

Activity

6
mdsmithaustin12d ago

Updating a Claude-only skill could create a Hermes link simply because Hermes was detected. This PR refreshes canonical content without rebuilding agent links, checks link ownership before choosing copy placement, and reports preserved redirects with explicit recovery guidance.

Not covered. The upstream Windows and Node matrix awaits maintainer approval; broader copy policies and shared-directory visibility isolation remain outside scope.

Details for reviewers

Risk. Medium. Update placement depends on filesystem evidence, including broken links, aliases, and mixed installations.

Base 92a9a34a on main, head 23acffbb. 6 files, +1051 -78.

Start here. placementResolver preserves destinations and reports skipped redirects. physicalPath compares paths through existing and missing ancestors.

Then.

  • CLI regressions cover global/project Git and well-known updates, deleted and foreign links, copies, aliases, warnings, and batch continuation.
  • Command reference explains preservation, recovery commands, and the Eve flat-link limitation.

Design. Placement and notices stay private to update. Existing installers and lock schemas remain unchanged. Canonical-present diagnostic errors do not block a valid shared refresh; placement errors fail the affected skill.

Proof. The PR body records local build, 1,143 tests, type-checking, and formatting results. The upstream workflow has not started its jobs because approval is required.

These pointers are a start, not the review. Read the whole diff.

vercel-internal-security-reviewer[bot]11d ago