Skip to content

feat: support project-local .apm/ content during apm install#644

Merged
sergio-sisternes-epam merged 2 commits intomicrosoft:mainfrom
sergio-sisternes-epam:feat/626-local-apm-content-install
Apr 10, 2026
Merged

feat: support project-local .apm/ content during apm install#644
sergio-sisternes-epam merged 2 commits intomicrosoft:mainfrom
sergio-sisternes-epam:feat/626-local-apm-content-install

Conversation

@sergio-sisternes-epam
Copy link
Copy Markdown
Collaborator

Closes #626

Summary

apm install now automatically discovers and deploys primitives from the project's own .apm/ directory to target directories (.github/, .claude/, .cursor/, .opencode/) alongside dependency content. Local content takes priority over dependencies on collision.

Motivation

Users expect .apm/ to be the single canonical location for all AI primitives in a project. Before this change, only content from installed dependency packages was deployed — the project's own .apm/ content was ignored unless manually installed as a local path dependency. This was confusing and required workarounds.

What changed

src/apm_cli/commands/install.py (+228 lines)

  • _has_local_apm_content() — detects primitives in .apm/ (skills, instructions, agents, prompts, hooks, commands, chatmodes)
  • _integrate_local_content() — deploys local content via the existing _integrate_package_primitives() pipeline using a synthetic PackageInfo
  • Local integration block wired into install() after dependency integration

src/apm_cli/deps/lockfile.py (+6 lines)

  • local_deployed_files: List[str] field for stale file cleanup across installs

tests/unit/test_local_content_install.py (20 new tests)

  • Detection, integration, lockfile serialization, edge cases

7 documentation files updated (CLI reference, guides, quick-start, workflow skill, cross-reference anchors)

Design decisions

  • Runs after dependency integration so local content wins on collision
  • Gated at install() level (not inside _install_apm_dependencies()) so zero-dep projects work
  • Uses PackageType.APM_PACKAGE for synthetic PackageInfo to prevent root SKILL.md from being deployed as a skill
  • Dedicated local_deployed_files lockfile section instead of a fake dependency entry — avoids polluting dep-specific logic
  • Skipped for --global, --only=mcp, and --dry-run

Testing

  • 20 new unit tests covering all code paths
  • Full suite: 3810 passed, 0 regressions

…ft#626)

apm install now automatically discovers and deploys primitives (skills,
instructions, agents, prompts, hooks, commands) from the project's own
.apm/ directory to target directories (.github/, .claude/, .cursor/,
.opencode/) alongside dependency content. Local content takes priority
over dependencies on collision.

Key changes:
- Add _has_local_apm_content() to detect local .apm/ primitives
- Add _integrate_local_content() to deploy local content via the
  existing _integrate_package_primitives() pipeline
- Add local_deployed_files section to LockFile for stale file cleanup
- Wire local integration into install() after dependency integration
- Skip local integration for --global, --only=mcp, and dry-run
- Root SKILL.md excluded (describes the project, not a deployable skill)

Includes 20 unit tests and documentation updates.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@sergio-sisternes-epam sergio-sisternes-epam marked this pull request as ready for review April 9, 2026 16:40
Copilot AI review requested due to automatic review settings April 9, 2026 16:40
Copy link
Copy Markdown
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

Adds first-class support for integrating a project's own .apm/ primitives during apm install, aligning local project configuration with dependency-driven installation and improving collision precedence.

Changes:

  • Integrate project-local .apm/ primitives after dependency integration so local content wins on collisions, and track deployed local files for cleanup.
  • Extend the lockfile schema with local_deployed_files and update semantic equivalence/YAML serialization accordingly.
  • Add unit tests and update docs/changelog to reflect the new apm install behavior.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/apm_cli/commands/install.py Detects and integrates local .apm/ content via the existing primitive integration pipeline; attempts stale cleanup and persists local_deployed_files.
src/apm_cli/deps/lockfile.py Adds local_deployed_files to the lockfile schema + YAML (de)serialization and semantic equivalence checks.
tests/unit/test_local_content_install.py New unit tests covering detection, integration plumbing, and lockfile serialization/semantics.
packages/apm-guide/.apm/skills/apm-usage/workflow.md Documents that apm install deploys local .apm/ content and local wins on collision.
docs/src/content/docs/reference/manifest-schema.md Updates cross-reference anchor to the updated apm install section.
docs/src/content/docs/reference/cli-commands.md Updates apm install reference to include local .apm/ deployment behavior and exceptions.
docs/src/content/docs/guides/skills.md Documents local .apm/skills promotion behavior and root SKILL.md exception.
docs/src/content/docs/guides/pack-distribute.md Updates CLI reference anchor for apm install --dev.
docs/src/content/docs/guides/dependencies.md Notes local .apm/ deployment as part of apm install.
docs/src/content/docs/getting-started/quick-start.md Mentions local .apm/ content being deployed alongside dependencies.
CHANGELOG.md Adds an Unreleased entry describing the new apm install behavior.

Comment thread src/apm_cli/commands/install.py Outdated
Comment thread src/apm_cli/commands/install.py
Comment thread src/apm_cli/commands/install.py
Comment thread src/apm_cli/commands/install.py Outdated
Comment thread CHANGELOG.md
- Gate local integration on old_local_deployed too (cleanup when .apm/ removed)
- Track error_count delta instead of object identity for error detection
- Retain failed-delete paths in local_deployed_files for retry
- Log stale file deletion failures
- Use rglob('*') with is_file() check in _has_local_apm_content()
- CHANGELOG references both issue and PR (microsoft#626, microsoft#644)
- Add test for subdirectory-only (no files) false positive

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@sergio-sisternes-epam sergio-sisternes-epam merged commit 1cf9acb into microsoft:main Apr 10, 2026
20 checks passed
@sergio-sisternes-epam sergio-sisternes-epam deleted the feat/626-local-apm-content-install branch April 10, 2026 09:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Support project-local .apm/ content during apm install

4 participants