Skip to content

Fix targets:/skills:/alias: ignored on path: dependency entries#1987

Open
sergio-sisternes-epam wants to merge 2 commits into
mainfrom
sergio-sisternes-epam-fix-issue-1982-local-path-targets-ignore
Open

Fix targets:/skills:/alias: ignored on path: dependency entries#1987
sergio-sisternes-epam wants to merge 2 commits into
mainfrom
sergio-sisternes-epam-fix-issue-1982-local-path-targets-ignore

Conversation

@sergio-sisternes-epam

Copy link
Copy Markdown
Collaborator

TL;DR

targets:, skills:, and alias: on a path: dependency entry were silently ignored during apm install. This PR fixes the two-line root cause and adds serialization symmetry plus full test coverage.

Fixes #1982


Problem (WHY)

DependencyReference.parse_from_dict handled path: entries with an early return cls.parse(local) that discarded every other field in the entry dict:

# BEFORE (buggy)
if "path" in entry and "git" not in entry:
    ...
    return cls.parse(local)   # targets:/skills:/alias: never read

For git: entries the same method reads targets_raw = entry.get("targets") and applies it. Local path: entries fell off the bottom of that block entirely.

Secondary: to_apm_yml_entry always emitted {"git": ...} when skill_subset or target_subset was set -- correct for remote deps, wrong for local ones (would round-trip as a remote git URL).


Approach (WHAT)

  • Fix 1 -- parse_from_dict: replace return cls.parse(local) with dep = cls.parse(local), then read and apply alias, skills, and targets from the entry dict before returning. Validation mirrors the git: path exactly.
  • Fix 2 -- to_apm_yml_entry: add an early-exit guard for is_local deps that emits {"path": ...} with the correct optional keys instead of falling into the {"git": ...} block.

Implementation (HOW)

Files changed

File Change
src/apm_cli/models/dependency/reference.py Fix parse_from_dict + to_apm_yml_entry
tests/unit/test_dep_targets_persistence.py TestLocalPathDepTargets -- 5 new tests
tests/unit/test_skill_subset_persistence.py 2 new path: + skills: tests
packages/apm-guide/.apm/skills/apm-usage/dependencies.md Document path: support for targets:

Trade-offs

  • No pipeline changes needed -- install/template.py already threads dep_ref.target_subset into integrate_package_primitives. The bug was entirely in the model layer.
  • The fix is deliberately minimal: only the path: branch of parse_from_dict and an early-exit guard in to_apm_yml_entry change. All git: behaviour is unchanged.

Validation evidence

tests/unit/test_dep_targets_persistence.py        72 passed
tests/unit/test_skill_subset_persistence.py       (all existing + 2 new)
tests/unit/integration/test_dep_target_intersection.py  (all existing)
ruff check / ruff format --check     -- clean
pylint R0801                         -- 10.00/10
lint-auth-signals.sh                 -- clean

How to test

python -c "
from apm_cli.models.dependency.reference import DependencyReference
dep = DependencyReference.parse_from_dict({'path': './local', 'targets': ['claude']})
assert dep.target_subset == ['claude'], f'got {dep.target_subset!r}'
print('[+] targets: on path: dep is now parsed correctly')
"

uv run --extra dev pytest tests/unit/test_dep_targets_persistence.py::TestLocalPathDepTargets -v
parse_from_dict early-returned after cls.parse(local) for local path
deps, silently discarding any targets:, skills:, or alias: fields from
the entry dict. git: deps were unaffected because their optional-field
extraction block runs after the initial cls.parse() call.

Fix 1 -- parse_from_dict: stop early-returning for path: entries
Replace the bare return cls.parse(local) with dep = cls.parse(local),
then read and apply alias, skills, and targets from the entry dict
before returning dep. Validation mirrors the git: path exactly.

Fix 2 -- to_apm_yml_entry: emit {path: ...} for local deps with subsets
The existing if self.skill_subset or self.target_subset: branch emitted
{git: ...} unconditionally, which would re-parse a local dep as a remote
git URL on the next load. Add an early-exit guard for is_local deps that
emits the correct {path: ...} key with alias/skills/targets.

No pipeline changes needed -- install/template.py already reads
dep_ref.target_subset and passes it to integrate_package_primitives.
The bug was entirely in model parsing.

Fixes #1982

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 1, 2026 16:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes a model-layer parsing/serialization bug where object-form local path: dependencies dropped targets:, skills:, and alias: during apm install, and ensures to_apm_yml_entry() round-trips local deps correctly.

Changes:

  • Preserve and validate alias:, skills:, and targets: for object-form path: dependencies in DependencyReference.parse_from_dict.
  • Serialize local path: dependencies as {path: ...} dict entries (with optional alias/skills/targets) instead of incorrectly emitting {git: ...} when subsets are present.
  • Add unit tests covering targets: / skills: persistence for local path: deps and document targets: support for path: dependencies.

Reviewed changes

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

File Description
src/apm_cli/models/dependency/reference.py Fix parsing and serialization so local path: deps honor alias/skills/targets and serialize symmetrically.
tests/unit/test_dep_targets_persistence.py Add regression coverage for targets: on local path: deps.
tests/unit/test_skill_subset_persistence.py Add regression coverage for skills: on local path: deps and dict-form emission.
packages/apm-guide/.apm/skills/apm-usage/dependencies.md Document that targets: applies to both git: and path: dependency forms.
Comment thread src/apm_cli/models/dependency/reference.py
Comment thread src/apm_cli/models/dependency/reference.py
- to_apm_yml_entry docstring now documents the local-path dict
  serialization case (path + alias/skills/targets) alongside the
  existing HTTP and git-with-subsets cases.
- Add three TestLocalPathDepTargets tests covering path: + alias:
  parsing, round-trip serialization, and invalid-alias rejection.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants