Skip to content

[BUG] sync_integration() hard-codes skill prefixes -- misses user-scope paths during uninstall #539

@sergio-sisternes-epam

Description

@sergio-sisternes-epam

Describe the bug
sync_integration() in skill_integrator.py hard-codes skill directory
prefixes (e.g. ".opencode/skills/") when scanning managed files for
removal. User-scope deployments can produce roots with nested path separators
(e.g. ".config/opencode/skills/"), which do not match the hard-coded
prefixes. This means user-scope skill directories are not cleaned up during
uninstall/sync.

To Reproduce

  1. apm install -g --target opencode (deploys to ~/.config/opencode/skills/)
  2. apm uninstall -g <package> (sync_integration tries to remove orphaned skills)
  3. Hard-coded prefix ".opencode/skills/" does not match ".config/opencode/skills/"
  4. Orphaned skill directories remain under ~/.config/opencode/skills/

Expected behavior
sync_integration() should derive allowed skill prefixes from KNOWN_TARGETS
using target.effective_root(user_scope=...) (and deploy_root overrides)
instead of hard-coded strings.

Environment (please complete the following information):

  • OS: All (code-level bug, not platform-specific)
  • Python Version: 3.12
  • APM Version: 0.8.9
  • Affected file: src/apm_cli/integration/skill_integrator.py
    (sync_integration() method)

Logs
N/A -- no runtime error; orphaned directories silently remain.

Additional context
Pre-existing issue not introduced by #537, but surfaced during Copilot code
review. Affects any target where user_root_dir != root_dir (currently
Copilot and OpenCode).

Suggested approach: build the prefix set dynamically from
KNOWN_TARGETS.values() iterating over each target's effective_root()
for both scopes, similar to how get_integration_prefixes() works in
base_integrator.py.

Related: #537, #530

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugDeprecated: use type/bug. Kept for issue history; will be removed in milestone 0.10.0.needs-triageDeprecated: use status/needs-triage. Kept for issue history; will be removed in milestone 0.10.0.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions