You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add apm deps why <pkg> — a subcommand that explains why a given
installed package is present, walking the dependency graph back to one
or more direct dependencies that pulled it in. Inspired by npm why, yarn why, and cargo tree -i.
Motivation
After running apm install, apm_modules/ may contain transitive
packages that the consumer did not declare directly. When something
breaks — an unexpected MCP server, a skill that surprises the author,
a version that triggers a policy block — the consumer needs to know who pulled it in. Today the only way to find out is to read apm.lock.yaml by hand and trace resolved_by chains.
apm deps tree shows the graph top-down. apm deps why <pkg> shows
it bottom-up — the inverted view that answers "how did this get here?"
Proposal
A new subcommand under the existing apm deps group:
apm deps why <pkg> [--global] [--json]
<pkg> accepts the same identifier styles as apm deps info: owner/repo, full URL, package alias, or marketplace name. The
lockfile is the source of truth — the command does not refetch
remotes.
Summary
Add
apm deps why <pkg>— a subcommand that explains why a giveninstalled package is present, walking the dependency graph back to one
or more direct dependencies that pulled it in. Inspired by
npm why,yarn why, andcargo tree -i.Motivation
After running
apm install,apm_modules/may contain transitivepackages that the consumer did not declare directly. When something
breaks — an unexpected MCP server, a skill that surprises the author,
a version that triggers a policy block — the consumer needs to know
who pulled it in. Today the only way to find out is to read
apm.lock.yamlby hand and traceresolved_bychains.apm deps treeshows the graph top-down.apm deps why <pkg>showsit bottom-up — the inverted view that answers "how did this get here?"
Proposal
A new subcommand under the existing
apm depsgroup:<pkg>accepts the same identifier styles asapm deps info:owner/repo, full URL, package alias, or marketplacename. Thelockfile is the source of truth — the command does not refetch
remotes.
Output (human-readable, default):
When the target IS a direct dependency:
When the package is not installed:
JSON output (
--json) for scripting:{ "package": { "repo_url": "acme-org/shared-utils", "version": "1.4.2", "source": "git", "is_direct": false }, "paths": [ { "chain": [ {"repo_url": "acme-org/big-skills", "constraint": "^1.2.0", "is_direct": true}, {"repo_url": "acme-org/shared-utils", "constraint": "^1.4.0"} ] }, { "chain": [ {"repo_url": "acme-org/other-skills", "constraint": "^0.9.0", "is_direct": true}, {"repo_url": "acme-org/shared-utils", "constraint": "~1.4.0"} ] } ] }Examples
apm deps why shared-utils— resolve by basename when unambiguous.apm deps why acme-org/shared-utils— canonical form.apm deps why acme-org/shared-utils --json— script-friendly.apm deps why shared-utils --global— user-scope lookup.Considerations
resolved_by(parent repo URL) perdep. The constraint on each edge is not always recorded today;
feat(deps): resolve semver constraints on git-source dependencies against repo tags #1488 adds the
constraintfield onLockedDependency. Withoutit,
whyfalls back to displaying just the resolved version.shared-utilsmatches twopackages from different owners, list all matches and prompt for
the canonical form.
parent-chain BFS is microseconds; no caching needed.
Out of scope
--source git,--source registry).References
src/apm_cli/commands/deps/cli.py(
_build_dep_tree,_add_tree_children).LockedDependency.resolved_by.npm why,yarn why,cargo tree -i.Related
constraintfield onLockedDependencythat this command surfaces per edge. This issuedegrades gracefully if feat(deps): resolve semver constraints on git-source dependencies against repo tags #1488 has not landed yet (shows resolved
version without constraint annotation).
apm find(file → package provenance). Complementary,orthogonal axis: [FEATURE] apm find — trace a file back to the package that brought it #1156 answers "who put this file here?",
apm deps whyanswers "who pulled this package in?". Both belongin the
apm depsintrospection surface.