Skip to content

Claude skills silently skipped when CLAUDE.md exists but .claude/ directory does not #1154

@tillig

Description

@tillig

Summary

When a project has a CLAUDE.md file (strong signal that Claude Code is in use) but no .claude/ directory, apm install and apm compile --targets all silently skip Claude skill deployment. No warning is emitted, and the user has no indication that Claude was excluded from skill integration.

To Reproduce

  1. Start with a repo that has CLAUDE.md and .github/ but no .claude/ directory:

    CLAUDE.md          ← exists (file)
    .github/           ← exists (directory)
    apm.yml            ← no explicit target: field
    
  2. Run apm install followed by apm compile --targets all

  3. Observe that .agents/skills/ is populated (for Copilot, Cursor, Codex, etc.) but .claude/skills/ is never created.

Expected behavior

One of:

  • .claude/skills/ is created and populated (since CLAUDE.md indicates Claude Code usage), OR
  • A warning is emitted explaining that Claude skill deployment was skipped because .claude/ does not exist, with guidance on how to enable it (e.g., "create .claude/ or set target: claude in apm.yml")

Root cause

Three factors combine to produce the silent skip:

  1. Auto-detection doesn't see Claude. target_detection.py:167 checks (project_root / ".claude").exists() — this looks for a path literally named .claude, not for CLAUDE.md. A project with only CLAUDE.md (no .claude/ directory) does not register Claude as a detected target.

  2. auto_create=False for Claude. Even when --targets all resolves and includes Claude in the target list, the directory-creation loop in install/phases/targets.py:161 skips it:

    if not _t.auto_create and not _explicit:
        continue

    The --targets all value from auto-detection (triggered by ≥2 detected folders) is not considered "explicit" in the _explicit variable sense (which tracks --target CLI flag or apm.yml target: field).

  3. Skill integrator bails out. skill_integrator.py:341 independently guards on the directory:

    if not target.auto_create and not target_root_dir.is_dir():
        continue

    So even if Claude somehow ends up in the resolved target set, skills aren't deployed.

Relationship to existing issues

Workarounds

Any of:

  • mkdir .claude before running apm install
  • Add target: claude (or target: all) to apm.yml

Neither is documented, and the behavior is surprising for users who expect CLAUDE.md to be sufficient signal.

Possible approaches

A few options (not prescriptive — just thinking out loud):

  1. Expand auto-detection: Treat the existence of CLAUDE.md as equivalent to .claude/ for target detection purposes.
  2. Emit a warning: When Claude is in the resolved target set but .claude/ doesn't exist, log a message suggesting the user create it or set an explicit target.
  3. Treat --targets all as explicit: When the user passes --targets all on the CLI, treat it the same as an explicit target for the auto_create guard (distinct from auto-detected "all").

Environment

  • APM: v0.12.2 (2b1fb6b)
  • OS: macOS 15.5 (Darwin 25.4.0)
  • Claude Code: 1.0.33

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions