Skip to content

[BUG] Global install with CLAUDE_CONFIG_DIR deletes skills deployed to the default Claude profile #3423

Open

Description

Describe the bug

User-scope skills deploy to $CLAUDE_CONFIG_DIR/skills (or ~/.claude/skills when the variable is unset), but deployment tracking is shared per HOME: one ~/.apm/apm.lock.yaml with one deployed_files list. Installing the same package into a second Claude profile treats the default profile's files as stale and deletes them. The reverse install, without CLAUDE_CONFIG_DIR, leaves the second profile's files in place and lists them next to its own in deployed_files.

As a result, one package cannot stay installed in two Claude profiles: installing it into a non-default profile removes it from the default one, silently.

APM_HOME cannot separate the state, because global commands do not read it (#2884). #3128 covers the same shared state for MCP configuration; this report is about skills and file deletion.

To Reproduce

Isolated HOME, a local package with one skill:

#!/bin/bash
set -e
R=$(mktemp -d)
export HOME=$R/home
unset CLAUDE_CONFIG_DIR APM_HOME
mkdir -p $HOME $R/pkg/.apm/skills/demo
printf 'name: demo\nversion: 0.1.0\ndescription: repro\nauthor: repro\n' > $R/pkg/apm.yml
printf -- '---\nname: demo\ndescription: Demo skill.\n---\nDemo.\n' > $R/pkg/.apm/skills/demo/SKILL.md
apm config set target claude

show() { (cd $HOME && find .claude/skills profiles/b/skills -type f 2>/dev/null | sort); }

echo "1) default profile";  apm install -g $R/pkg >/dev/null; show
echo "2) profile b";        CLAUDE_CONFIG_DIR=$HOME/profiles/b apm install -g $R/pkg >/dev/null; show
echo "3) default profile";  apm install -g $R/pkg >/dev/null; show
echo "4) profile b";        CLAUDE_CONFIG_DIR=$HOME/profiles/b apm install -g $R/pkg >/dev/null; show

Output:

1) default profile
.claude/skills/demo/SKILL.md
2) profile b
profiles/b/skills/demo/SKILL.md
3) default profile
.claude/skills/demo/SKILL.md
profiles/b/skills/demo/SKILL.md
4) profile b
profiles/b/skills/demo/SKILL.md

After step 3, deployed_files lists the files of both profiles. After steps 2 and 4 it lists only profiles/b/..., and ~/.claude/skills/demo is gone. Every install ends with Installed 1 APM dependency and no warning.

Expected behavior

Installing into one Claude profile does not delete files deployed to another. Either of these would do:

Environment

  • OS: Linux x86_64
  • Python Version: 3.12 (bundled in the release binary)
  • APM Version: 0.35.0 (17a2fc4), target claude

Additional context

Two Claude Code accounts on one machine: the first uses the default ~/.claude, the second runs with CLAUDE_CONFIG_DIR pointing to its own directory. Running apm install -g for a local skill package from a session of the second account removed the skill from the first one.

Activity

  1. xronos-i-am commented on Oct 30, 2026

    @xronos-i-am
    Author

    I'd like to propose a bounded fix: for claude and hermes (user root selected by CLAUDE_CONFIG_DIR / HERMES_HOME), an install treats a deployed_files row as stale only when it lies under the currently selected root. Rows of other profiles stay in the lockfile untouched. No lockfile schema change and no APM_HOME work (#2884). Uninstall across profiles is out of scope; I'll report it separately.

    The fix with a regression test is in #3424. Could a maintainer record a scope decision?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions