Skip to content

Fix transitive dependency handling in compile and orphan detection#111

Merged
danielmeppiel merged 10 commits intomainfrom
copilot/fix-transitive-dependencies-issue
Feb 26, 2026
Merged

Fix transitive dependency handling in compile and orphan detection#111
danielmeppiel merged 10 commits intomainfrom
copilot/fix-transitive-dependencies-issue

Conversation

Copy link
Contributor

Copilot AI commented Feb 25, 2026

🐛 Bug Fix

Problem

apm compile only scans direct dependencies from apm.yml, silently skipping transitive deps. Orphan detection (_check_orphaned_packages) and apm prune also only check apm.yml, incorrectly flagging transitive deps as orphaned.

Example: package A → B → C. Only A is in apm.yml. After apm install, B and C are installed and tracked in apm.lock with depth: 2+, but apm compile ignores their primitives and reports them as orphans.

Solution

Read apm.lock (which already tracks transitive deps with depth info) in addition to apm.yml in the three affected code paths:

  • get_dependency_declaration_order() (discovery.py): Appends transitive deps from lockfile after direct deps, preserving priority ordering
  • _check_orphaned_packages() (cli.py): Includes lockfile deps in expected_installed set
  • prune() command (cli.py): Same lockfile inclusion for expected deps
  • get_lockfile_installed_paths() (lockfile.py): New helper that converts LockedDependency entries to their filesystem install paths via DependencyReference.get_install_path(), handling regular, virtual, and ADO package layouts

Testing

  • Bug reproduction confirmed
  • Fix verified locally
  • Regression tests added (if applicable)
  • All existing tests pass

17 new unit tests across two files:

  • tests/unit/test_transitive_deps.py — lockfile path resolution, multi-level transitive discovery, orphan detection with/without lockfile
  • tests/test_enhanced_discovery.py — 4 additional tests for transitive primitive scanning

817 total unit tests pass, CodeQL clean.

Checklist

  • LABEL: Apply bug or fix label to this PR
  • Root cause identified and addressed
  • Edge cases considered
Original prompt

This section details on the original issue you should resolve

<issue_title>[BUG] transitive packages</issue_title>
<issue_description>Describe the bug
I don't have the same result if I use transitive dependencies or direct dependencies of the same packages.

dependencies

  • package team-cot-agent-instructions
name: team-cot-agent-instructions
version: 0.0.1
description: the instructions of the Centralized Operation Team of the IME division

dependencies:
  apm:
    - git.autodesk.com/rieraj/division-ime-agent-instructions
  • package division-ime-agent-instructions
name: division-ime-agent-instructions
version: 0.0.1
description: This document is the main page of the instructions of the Interactive Media Entertainment division (IME)

dependencies:
  apm:
    - git.autodesk.com/rieraj/autodesk-agent-instructions
  • package autodesk-agent-instructions
name: autodesk-agent-instructions
version: 0.0.1
description: This document is the main page of the instructions of the Autodesk company.

apm.yml files

  • direct dependencies
name: drect
version: 1.0.0
description: direct
author: Jordi Riera
dependencies:
  apm:
  - git.autodesk.com/rieraj/team-cot-agent-instructions
  - git.autodesk.com/rieraj/division-ime-agent-instructions
  - git.autodesk.com/rieraj/autodesk-agent-instructions
  mcp: []
scripts: {}
  • transitive dependencies
name: transitives
version: 1.0.0
description: APM project for transitives
author: Jordi Riera
dependencies:
  apm:
  - git.autodesk.com/rieraj/team-cot-agent-instructions
  mcp: []
scripts: {}

To Reproduce
Steps to reproduce the behaviour:

  1. Run command 'apm install' in both cases
  2. With parameters 'None'
  3. See error

Expected behaviour

In the case of direct dependencies

❯ apm install
Installing dependencies from apm.yml...
Installing APM dependencies (3)...
  └─ Resolved transitive: rieraj/team-cot-agent-instructions
  └─ Resolved transitive: rieraj/division-ime-agent-instructions
  └─ Resolved transitive: rieraj/autodesk-agent-instructions
Created .github/ as standard skills root (.github/skills/) and to enable
VSCode/Copilot integration
✓ rieraj/autodesk-agent-instructions
✓ rieraj/division-ime-agent-instructions
✓ rieraj/team-cot-agent-instructions
  └─ 1 agents integrated → .github/agents/

Generated apm.lock with 3 dependencies
Installed 3 APM dependencies
No MCP dependencies found in apm.yml


╭─────────────────────────── ✨ Installation complete ───────────────────────────╮
│                                                                                │
│  Next steps:                                                                   │
│    apm compile              # Generate AGENTS.md guardrails                    │
│    apm list                 # Show all prompts                                 │
│                                                                                │
╰────────────────────────────────────────────────────────────────────────────────╯
❯ apm compile
⚙️ Starting context compilation...
Compiling for AGENTS.md (VSCode/Copilot) - detected .github/ folder
Analyzing project structure...
├─ 4 directories scanned (max depth: 3)
├─ 9 files analyzed across 3 file types (lock, md, yml)
└─ 3 instruction patterns detected

Optimizing placements...

  Pattern              Source          Co…   Placement             Metrics
 ────────────────────────────────────────────────────────────────────────────────
  **                   IME-ruler.in…   4/4   ./AGENTS.md           rel: 100%
  **                   design-stand…   4/4   ./AGENTS.md           rel: 100%
  **                   autodesk-sta…   4/4   ./AGENTS.md           rel: 100%



Generated 1 AGENTS.md file
┌─ Context efficiency:    100.0%
└─ Generation time:       4ms

Placement Distribution
└─ .                              3 instructions from 2 sources
✅ Compilation completed successfully!

In the case of transitive dependencies

❯ apm install
Installing dependencies from apm.yml...
Installing APM dependencies (1)...
  └─ Resolved transitive: rieraj/team-cot-agent-instructions
  └─ Resolved transitive: rieraj/division-ime-agent-instructions
  └─ Resolved transitive: rieraj/autodesk-agent-instructions
Created .github/ as standard skills root (.github/skills/) and to enable
VSCode/Copilot integration
✓ rieraj/team-cot-agent-instructions
  └─ 1 agents integrated → .github/agents/
✓ rieraj/division-ime-agent-instructions
✓ rieraj/autodesk-agent-instructions

Added apm_modules/ to .gitignore
Generated apm.lock with 3 dependencies
Updated .gitignore for integrated agents (*-apm.agent.md, *-apm.chatmode.md)
Installed 3 APM dependencies
No MCP dependencies found in apm.yml


╭─────────────────────────── ✨ Installation complete ───────────────────────────╮
│                                                                                │
│  Next steps:                                                        ...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes microsoft/apm#110

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

Copilot AI and others added 2 commits February 25, 2026 23:21
Read from apm.lock (which tracks transitive deps) in addition to apm.yml:
- get_dependency_declaration_order() now includes transitive deps for compile
- _check_orphaned_packages() no longer flags transitive deps as orphaned
- prune command accounts for transitive deps in expected_installed set
- Added get_lockfile_installed_paths() helper to lockfile module
- Added 17 unit tests covering all transitive dependency scenarios

Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com>
- Wrap get_lockfile_installed_paths() in try/except to handle all errors
- Use ImportError instead of broad Exception in callers
- Update docs for transitive dep discovery

Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix issue with transitive package dependencies Fix transitive dependency handling in compile and orphan detection Feb 25, 2026
@danielmeppiel danielmeppiel added the bug Something isn't working label Feb 25, 2026
@danielmeppiel danielmeppiel linked an issue Feb 25, 2026 that may be closed by this pull request
@danielmeppiel danielmeppiel marked this pull request as ready for review February 25, 2026 23:50
Copilot AI review requested due to automatic review settings February 25, 2026 23:50
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

Fixes apm compile, orphan detection, and apm prune so they account for transitive dependencies by incorporating apm.lock (in addition to apm.yml) when determining expected installed dependency paths.

Changes:

  • Extend dependency discovery order to append transitive deps from apm.lock after direct deps from apm.yml.
  • Update orphan detection and prune logic to treat lockfile-listed deps as expected (avoiding false orphan reports).
  • Add a lockfile helper for resolving installed paths and introduce targeted unit/integration tests + docs update.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/unit/test_transitive_deps.py Adds unit tests covering lockfile path resolution, transitive ordering, and orphan detection behavior.
tests/test_enhanced_discovery.py Expands discovery tests to validate transitive dependency inclusion and primitive scanning.
src/apm_cli/primitives/discovery.py Appends transitive dependency install paths from apm.lock to discovery order.
src/apm_cli/deps/lockfile.py Adds get_lockfile_installed_paths() helper to convert lock entries into install paths.
src/apm_cli/deps/init.py Exposes get_lockfile_installed_paths as part of the deps package API.
src/apm_cli/cli.py Updates orphan detection and prune to include lockfile dependencies as expected installs.
docs/enhanced-primitive-discovery.md Documents updated behavior: direct deps from apm.yml, transitives appended from apm.lock.

- Move get_lockfile_installed_paths logic into LockFile.get_installed_paths()
  method (foutoucour review)
- Use .as_posix() for Windows-safe path normalization (copilot-reviewer)
- Narrow except Exception to specific error types (copilot-reviewer)
- Move inline imports to top-level in discovery.py and cli.py (foutoucour)
- Remove unused imports in test file (tempfile, pytest)
@danielmeppiel danielmeppiel added this to the 0.7.4 milestone Feb 26, 2026
@danielmeppiel
Copy link
Collaborator

danielmeppiel commented Feb 26, 2026

Summary of additional fixes since initial PR

Beyond the original transitive dependency fix, this PR now includes several follow-up fixes addressing review feedback and CI issues:

1. deps list console width fix (48d87c0)

CI was failing on test_deps_list_shows_correct_path and test_mixed_deps_list in ADO E2E tests. Root cause: PR #107 added 4 new columns (Prompts, Instructions, Agents, Skills) to the deps list table, expanding it from 5 to 7 columns. At CI's default 80-col terminal, Rich truncated the Package and Source columns, breaking assertions.
Fix: Set Console(width=max(120, term_width)) in list_packages() to guarantee minimum 120-col rendering.

2. LockFile classmethod refactor (bd8794c)

Per review feedback, refactored the standalone get_lockfile_installed_paths() function into a LockFile.installed_paths_for_project() classmethod — better cohesion since it operates on lockfile data. Updated all 4 callers (cli.py ×2, discovery.py ×1, test_transitive_deps.py ×7 call sites). Old function kept as a deprecated one-line alias for backward compat.

3. Integration test assertion fix (640ebbb)

test_skill_detection_in_output was asserting for "Claude Skill" or "SKILL.md detected" in CLI output, but the current output format is "Skill integrated → .github/skills/". Updated assertion to match.

Test verification

  • 812 unit tests — all pass ✅
  • 9 ADO E2E tests — all pass ✅
  • 30 integration tests (the 4 test files that were previously failing) — all pass ✅

The "Integration Tests (PR) — Integration tests failed" will keep showing until the above CI fixes (1 and 3) are merged with this PR.

@danielmeppiel danielmeppiel merged commit 5aea357 into main Feb 26, 2026
5 of 6 checks passed
@danielmeppiel danielmeppiel deleted the copilot/fix-transitive-dependencies-issue 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.

[BUG] transitive packages

5 participants