Skip to content

Global skill-mirroring step deletes unrelated user-authored skills, then erases evidence of doing so #3111

Description

@MASTERGROOT

Summary

hyperframes init/skills update deleted two unrelated, pre-existing, user-authored skills from ~/.claude/skills/ while linking into global agent directories. Root cause looks like the "link into N other agent directories" step writes lock entries in ~/.agents/.skill-lock.json for every skill folder already present in a target directory — not just the ones it just installed — attributing them to heygen-com/hyperframes. The very next removed-skill check then finds those names absent from HyperFrames' own manifest and deletes them as "no longer published," then prunes the now-orphaned lock entries — which erases the evidence of the false attribution.

Environment

  • hyperframes CLI via npx (cached at ~/.npm/_npx/2d24f54ded6cd194/node_modules/hyperframes)
  • macOS, Node via Homebrew
  • Multiple AI-tool skill directories present on the machine (~/.claude/skills, ~/.codex/skills, ~/.cursor/skills, ~/.copilot/skills, ~/.gemini/skills, ~/.continue/skills, ~/.agents/skills, etc.) — some pre-populated with unrelated, hand-authored skills unconnected to HyperFrames.

Steps to reproduce

  1. Have at least one unrelated skill already present in a global skills directory HyperFrames will target, e.g. ~/.claude/skills/my-own-skill/SKILL.md, authored independently and never installed via HyperFrames.
  2. In a project, run npx hyperframes skills update <workflow-name> (project-scoped) or npx hyperframes init <dir> --skill=<workflow-name> (which links into every detected global agent directory).
  3. Observe the CLI's own output: Linked skills into N other agent directories, followed on a subsequent check/update pass by Removing M skill(s) no longer published: ... — where the removed list can include names that were never HyperFrames skills.
  4. Check ~/.claude/skills/my-own-skill/ — deleted from disk.
  5. Check ~/.agents/.skill-lock.json — no trace of my-own-skill (pruned as an "orphaned lock entry" in the same pass), making the false attribution hard to spot after the fact.

What actually happened to me

Running npx hyperframes skills update general-video (project-scoped) followed shortly by npx hyperframes init "Video/.../hyperframes-final" --skill=general-video (which reported Linked skills into 9 other agent directories) resulted in two of my own, user-authored skills being deleted from ~/.claude/skills/ — both git-tracked in my personal skills repo and completely unrelated to HyperFrames, no shared name, no shared source. I was able to restore them with git checkout since that directory happens to be under version control; on a machine without that safety net this would be permanent, silent data loss.

Expected behavior

The "link into other agent directories" step should only ever write/attribute lock entries for skills it is actually installing in this operation. It should never treat a target directory's pre-existing, unrelated contents as something it now owns and is therefore responsible for pruning.

Suggested fix direction

In the compiled CLI (dist/cli.js), the relevant functions are detectRemoved, skillsAttributedToSource, and whatever performs the initial "link into N other agent directories" step (upstream of detectRemoved, since by the time detectRemoved/pruneOrphanedLockEntries run, ~/.agents/.skill-lock.json already (incorrectly) attributed the unrelated skills to heygen-com/hyperframes). The link step should record only skills it created/copied in that run, not enumerate and claim everything already on disk in the target directory.

Happy to provide more detail or test a fix — this cost real (recoverable, in my case) data loss and I'd guess it's silent for most users since the orphan-prune step deletes the evidence.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions