Skip to content

fix: skill integration bugs, transitive dep cleanup, and skill_integrator simplification#107

Merged
danielmeppiel merged 1 commit intomainfrom
fix/skills-support
Feb 26, 2026
Merged

fix: skill integration bugs, transitive dep cleanup, and skill_integrator simplification#107
danielmeppiel merged 1 commit intomainfrom
fix/skills-support

Conversation

@danielmeppiel
Copy link
Collaborator

@danielmeppiel danielmeppiel commented Feb 25, 2026

Bug fixes:

  • Fix silent skill integration failure when packages are resolved via dependency callback (package_type=None in cached install path — ALL skill integration was silently skipped)
  • Fix missing resolved_commit in lockfile for callback-downloaded transitive deps
  • Remove incorrect .claude/prompts/ dual-targeting from PromptIntegrator (Claude Code uses .claude/commands/, already handled by CommandIntegrator)
  • Fix deps tree showing @latest instead of actual resolved reference

Features:

  • apm uninstall now recursively removes orphaned transitive dependencies and updates lockfile (npm-style cleanup)
  • apm uninstall --dry-run shows transitive deps that would be removed

Simplification:

  • Remove SKILL.md auto-generation from primitives in skill_integrator.py (~300 lines removed). Only native SKILL.md files shipped by packages are promoted. Packages without SKILL.md are compiled to AGENTS.md/CLAUDE.md only.

Changed files

  • src/apm_cli/cli.py — P0 fix (package_type detection from disk), P2 fix (resolved_commit capture via callback dict), transitive dep cleanup on uninstall
  • src/apm_cli/commands/deps.py — Better version display in deps tree (resolved_commit > resolved_ref > version > "latest")
  • src/apm_cli/integration/skill_integrator.py — Removed SKILL.md generation from primitives, only promote native SKILL.md + sub-skills
  • src/apm_cli/integration/prompt_integrator.py — Removed incorrect .claude/prompts/ dual-targeting
  • src/apm_cli/deps/github_downloader.py — Minor fixes for subdirectory package handling
  • Updated docs and tests to match

@danielmeppiel danielmeppiel force-pushed the fix/skills-support branch 3 times, most recently from 2b9ca27 to bcbb71e Compare February 26, 2026 15:41
@danielmeppiel danielmeppiel marked this pull request as ready for review February 26, 2026 15:51
Copilot AI review requested due to automatic review settings February 26, 2026 15:51
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates APM’s dependency installation/uninstall and integration flows to support native skills and virtual subdirectory package layouts (e.g. owner/repo/skills/foo), including improved lockfile usage and updated docs/tests.

Changes:

  • Adds npm-style transitive dependency pruning during apm uninstall, including lockfile updates and dry-run visibility.
  • Adjusts skill integration to focus on native SKILL.md packages and promotes .apm/skills/* sub-skills to top-level skills.
  • Updates apm deps list/tree to account for subdirectory packages and show per-primitive counts; refreshes related docs/tests.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/apm_cli/cli.py Implements transitive uninstall pruning + lockfile updates; improves cached install/integration flow.
src/apm_cli/commands/deps.py Enhances deps list/tree with lockfile-aware orphan detection and primitive counts.
src/apm_cli/integration/skill_integrator.py Integrates native skills and promotes sub-skills; tracks sub_skills_promoted.
src/apm_cli/integration/agent_integrator.py Adds dual-target integration/cleanup and gitignore patterns for .claude/agents/.
src/apm_cli/integration/prompt_integrator.py Refactors cleanup + gitignore writing logic for integrated prompts.
src/apm_cli/deps/github_downloader.py Captures resolved commit SHA for subdirectory downloads.
tests/unit/test_uninstall_transitive_cleanup.py Adds unit tests for uninstall transitive pruning + lockfile behavior.
tests/unit/integration/test_skill_integrator.py Updates skill integrator tests; adds coverage for sub-skill promotion from non-skill packages.
tests/unit/integration/test_agent_integrator.py Updates gitignore test expectations for .claude/agents/ patterns.
tests/integration/test_apm_dependencies.py Tweaks integration assertion order for subdirectory package installs.
docs/cli-reference.md Documents uninstall behavior for transitive deps + lockfile updates; updates deps list/tree docs.
docs/dependencies.md Updates skills behavior and documents uninstall transitive pruning.
docs/integrations.md Updates skill integration description (native-only, integrated skills).
docs/skills.md Clarifies SKILL.md-only packages are treated as native skills.
Comments suppressed due to low confidence (3)

src/apm_cli/commands/deps.py:108

  • When populating declared_sources from the lockfile, the code assigns 'github' unconditionally. This mislabels Azure DevOps dependencies (which can appear in apm.lock with host set) and can cause incorrect Source values in apm deps list. Use the locked dependency's host (or the same hostname check used by DependencyReference.is_azure_devops()) to set 'azure-devops' vs 'github' instead of hardcoding 'github'.
                for dep in lockfile.dependencies.values():
                    # Lockfile keys match declared_sources format (owner/repo)
                    dep_key = dep.get_unique_key()
                    if dep_key and dep_key not in declared_sources:
                        declared_sources[dep_key] = 'github'
        except Exception:

src/apm_cli/commands/deps.py:351

  • In the no-lockfile fallback scan for apm deps tree, directories under .apm/ (e.g., .apm/skills/<sub-skill>/) can contain SKILL.md and will be incorrectly treated as top-level installed packages. Mirror the skip logic used in deps list (ignore candidates whose relative path parts include .apm) so sub-skills/internal package metadata don’t show up as separate dependencies.
                    for candidate in sorted(apm_modules_path.rglob("*")):
                        if not candidate.is_dir() or candidate.name.startswith('.'):
                            continue
                        has_apm = (candidate / "apm.yml").exists()
                        has_skill = (candidate / "SKILL.md").exists()
                        if not has_apm and not has_skill:
                            continue

tests/unit/test_uninstall_transitive_cleanup.py:94

  • The test name/docstring says the shared transitive dependency is not removed, but the assertions and inline comments below expect it to be removed. Rename the test and/or update the docstring to match the actual expected behavior so the intent is unambiguous.
    def test_uninstall_keeps_shared_transitive_dep(self):
        """Transitive dep used by another remaining package is NOT removed."""
        with tempfile.TemporaryDirectory() as tmp_dir:

@danielmeppiel danielmeppiel changed the title fix: skills support and virtual subdirectory packages fix: skill integration bugs, transitive dep cleanup, and skill_integrator simplification Feb 26, 2026
@danielmeppiel danielmeppiel added the bug Something isn't working label Feb 26, 2026
@danielmeppiel danielmeppiel merged commit e5e4aac into main Feb 26, 2026
6 checks passed
@danielmeppiel danielmeppiel deleted the fix/skills-support branch February 27, 2026 09:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants