Skip to content

[FEATURE] apm install should clean up stale deployed files when files are renamed within a package #666

@Boubalou

Description

@Boubalou

Problem

When a file is renamed inside an APM package (e.g., a prompt file my-command.prompt.md → my-new-command.prompt.md), running apm install generates the new target files but leaves the old ones on disk as stale artifacts.

Steps to reproduce

  1. Have a package with a prompt file my-command.prompt.md
  2. Run apm install — files are deployed to .claude/commands/my-command.md, .opencode/commands/my-command.md, .github/prompts/my-command.prompt.md
  3. Rename the source to my-new-command.prompt.md
  4. Run apm install again

Expected: Old files (my-command.md, my-command.prompt.md) are removed, new files (my-new-command.md, my-new-command.prompt.md) are created.

Actual: Both old and new files exist on disk. The old files must be manually deleted.

Why this happens

The install loop writes the new deployed_files list to the lockfile, overwriting the previous one — but never computes the diff between old and new to remove orphaned files. The existing detect_orphans() in drift.py only operates at the package level (is the package still in apm.yml?), not at the file level within a package.

Suggested approach

The infrastructure is already in place — apm.lock.yaml tracks deployed_files per dependency. During apm install, for each package:

  1. Read the old deployed_files from the existing lockfile
  2. Integrate the package (existing logic)
  3. Collect the new deployed_files
  4. Compute stale = old - new
  5. Delete stale files from disk

This would cover renames, deleted prompts, and any other case where a package's output file set changes between installs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    acceptedDeprecated: use status/accepted. Kept for issue history; will be removed in milestone 0.10.0.enhancementDeprecated: use type/feature. Kept for issue history; will be removed in milestone 0.10.0.good first issueGood for newcomers

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions