Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: microsoft/apm
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.8.2
Choose a base ref
...
head repository: microsoft/apm
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.8.3
Choose a head ref
  • 13 commits
  • 84 files changed
  • 10 contributors

Commits on Mar 19, 2026

  1. Configuration menu
    Copy the full SHA
    785dee5 View commit details
    Browse the repository at this point in the history
  2. refactor: extract _is_vscode_available() helper; strengthen tests; ad…

    …d docs
    
    - Extract `_is_vscode_available()` module-level helper so both the main
      runtime-detection loop and the ImportError fallback share a single
      predicate (addresses reviewer comment about duplication/drift risk).
    - Rewrite TestVSCodeRuntimeDetection to patch at the
      apm_cli.integration.mcp_integrator module boundary so tests exercise
      the real production helper rather than a re-implemented condition.
    - Document the VS Code .vscode/-directory fallback heuristic in
      docs/integrations/ide-tool-integration.md under Runtime targeting.
    sergio-sisternes-epam committed Mar 19, 2026
    Configuration menu
    Copy the full SHA
    4827454 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    7d50bb3 View commit details
    Browse the repository at this point in the history
  4. Configuration menu
    Copy the full SHA
    64a70d4 View commit details
    Browse the repository at this point in the history
  5. Align CLI docs with current compile, audit, and planned drift beh…

    …avior (#373)
    
    * Initial plan
    
    * docs: fix cli consistency report mismatches
    
    Co-authored-by: sergio-sisternes-epam <207026618+sergio-sisternes-epam@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
    Co-authored-by: sergio-sisternes-epam <207026618+sergio-sisternes-epam@users.noreply.github.com>
    Copilot and sergio-sisternes-epam authored Mar 19, 2026
    Configuration menu
    Copy the full SHA
    a408297 View commit details
    Browse the repository at this point in the history
  6. fix: Refactor command and model modules for readability and maintaina…

    …bility (#231) (#232)
    
    * refactor: split god files into focused sub-modules (#231)
    
    Phases 1-5 of command/model refactoring:
    - Extract constants and narrow exception handlers
    - Decompose god functions into focused helpers
    - Add InstallMode and VirtualPackageType enums
    - Split god files into focused sub-modules
    - Flatten nesting and add typed result dataclasses
    - Address Copilot review feedback
    - Clean-up support tasks
    
    * refactor: address Copilot review feedback — cleanup unused imports and dead code
    
    - Remove unused APM_MODULES_DIR import from compile/watcher.py
    - Remove trailing whitespace in models/dependency/types.py
    - Remove dead APM_DEPS_AVAILABLE conditional import pattern from uninstall/cli.py and engine.py
    - Remove unused shutil import from uninstall/engine.py
    - Remove unused yaml import from prune.py
    - Remove apm.code-workspace from tracking and add *.code-workspace to .gitignore
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Sergio Sisternes <sergio.sisternes@epam.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    Co-authored-by: Daniel Meppiel <51440732+danielmeppiel@users.noreply.github.com>
    4 people authored Mar 19, 2026
    Configuration menu
    Copy the full SHA
    cc4cc28 View commit details
    Browse the repository at this point in the history

Commits on Mar 20, 2026

  1. fix(security): preserve leading BOM in strip_dangerous (#372)

    * fix(security): preserve leading BOM in strip_dangerous
    
    strip_dangerous() was stripping all BOM characters (U+FEFF), including
    a leading BOM at position 0. This contradicts its documented contract
    which states that info-level characters are preserved — and scan_text()
    classifies a leading BOM as info severity since it is standard practice
    for UTF-8 files.
    
    The fix checks whether the BOM is at position 0 before deciding to
    strip it. Mid-file BOMs (warning-level) are still stripped as before.
    
    Updated the corresponding test to assert the leading BOM is preserved.
    
    * style(security): clarify BOM branch in strip_dangerous
    
    Restructure the BOM handling branch so the mid-file strip path uses an
    early continue and the leading-BOM path falls through to the common
    append, making the two behaviors self-documenting.
    
    Co-authored-by: Copilot <copilot@github.com>
    
    ---------
    
    Co-authored-by: Copilot <copilot@github.com>
    Co-authored-by: Daniel Meppiel <51440732+danielmeppiel@users.noreply.github.com>
    3 people authored Mar 20, 2026
    Configuration menu
    Copy the full SHA
    862c280 View commit details
    Browse the repository at this point in the history
  2. Use aka.ms/apm-unix and aka.ms/apm-windows short URLs for install scr…

    …ipts (#384)
    
    * Initial plan
    
    * Replace install URLs with aka.ms/apm-unix and aka.ms/apm-windows short links
    
    Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com>
    Agent-Logs-Url: https://github.com/microsoft/apm/sessions/82dde4ed-96da-4e87-8c47-06d1a52cf8d8
    
    ---------
    
    Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
    Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com>
    Copilot and danielmeppiel authored Mar 20, 2026
    Configuration menu
    Copy the full SHA
    74f4b68 View commit details
    Browse the repository at this point in the history
  3. feat: Plugin coexistence — apm pack --format plugin, `apm init --pl…

    …ugin`, devDependencies (#379)
    
    * feat: implement plugin exporter and apm pack --format plugin
    
    - Add plugin_exporter.py: transforms .apm/ layout to plugin-native directories
      (agents, skills, commands, instructions, contexts) with collision handling,
      hooks/MCP merging, devDependencies filtering, and security scanning
    - Add synthesize_plugin_json_from_apm_yml() to plugin_parser.py for generating
      plugin.json from apm.yml identity fields
    - Wire fmt='plugin' delegation in packer.py to export_plugin_bundle()
    - Add --force flag to pack CLI for last-writer-wins collision override
    - Export export_plugin_bundle from bundle __init__.py
    - Add 73 unit tests covering export engine, synthesis, and packer integration
    - Document --format plugin in pack-distribute guide with mapping table
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * feat: add apm init --plugin and devDependencies model
    
    - Add --plugin flag to init: creates plugin.json + apm.yml with devDependencies
    - Add _validate_plugin_name() for kebab-case validation (max 64 chars)
    - Add _create_plugin_json() helper for plugin.json generation
    - Extend _create_minimal_apm_yml() with plugin= parameter
    - Add dev_dependencies field to APMPackage dataclass
    - Parse devDependencies in from_apm_yml() (same logic as dependencies)
    - Add get_dev_apm_dependencies() and get_dev_mcp_dependencies() accessors
    - Add 32 unit tests for init --plugin and devDependencies model
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * docs: update documentation for plugin coexistence features
    
    - Add 'Exporting APM packages as plugins' section to plugins guide
    - Document --plugin flag on init and --format plugin on pack in CLI reference
    - Add devDependencies section (§5) to manifest schema reference
    - Add cross-references between guides and reference pages
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: address security and DX review findings in plugin exporter
    
    - Add recursion depth limit (_MAX_MERGE_DEPTH=20) to _deep_merge to prevent
      stack overflow from maliciously crafted hooks/MCP configs
    - Filter symlinks in tar archive creation (TOCTOU mitigation)
    - Add plugin format info message after successful pack
    - Add test for depth limit enforcement
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * docs: add plugin coexistence entries to changelog
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * feat: add SHA-256 content integrity hashing in lockfile (#315)
    
    - Add content_hash.py utility with deterministic package hashing
      (sorted paths, POSIX format, skips .git/__pycache__/symlinks)
    - Add content_hash field to LockedDependency with backward compat
    - Compute hash after download during lockfile generation
    - Verify hash on cached packages; re-download on mismatch
    - 22 tests covering hashing, verification, and lockfile roundtrip
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * feat: resolver devDependencies awareness and is_dev tracking
    
    - Add is_dev field to DependencyNode for dev/prod distinction
    - Resolver now loads root devDependencies into BFS queue with is_dev=True
    - Transitive deps of dev deps inherit is_dev from parent
    - Prod wins: if a dep appears in both dependencies and devDependencies,
      it is marked is_dev=False (prod takes precedence)
    - Add comprehensive tests for lockfile is_dev round-trip, resolver dev
      dep marking, prod-wins semantics, and install --dev flag behavior
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: eliminate TOCTOU in content hash verification
    
    Capture SHA-256 hashes at download/verify time (3 append points) and
    use the cached dict when enriching the lockfile, instead of re-computing
    later. Prevents an attacker with filesystem access from modifying
    package content between verification and lockfile write.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * docs: update changelog with install --dev and content hashing entries
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * docs: document install --dev flag and content integrity hashing
    
    - cli-commands: promote --dev from planned to implemented, add example
    - manifest-schema: update devDependencies and lockfile structure sections
    - lockfile-spec: add content_hash and is_dev fields, new §4.4 Content Integrity
    - pack-distribute: update devDependencies exclusion with --dev example
    - security: promote content integrity from planned to implemented
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: remove nonexistent context/memory primitives from plugin export
    
    .apm/context/ and .apm/memory/ are APM-internal conventions, not plugin
    primitives. Remove their mapping to contexts/ in plugin export output,
    the corresponding tests, and documentation references.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: address PR review — path traversal, symlink guard, error messaging
    
    - Sanitize pkg_name/pkg_version in bundle_dir to prevent path traversal
    - Clean-slate bundle_dir creation + resolve-check on each dest path
    - Distinguish invalid plugin.json from missing plugin.json in warnings
    - Remove deprecated 'apm compile' from init --plugin next steps
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * refactor: use path_security utils instead of ad-hoc traversal checks
    
    Replace inline is_relative_to checks and raw shutil.rmtree with
    ensure_path_within, safe_rmtree, and PathTraversalError from the
    existing path_security module.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: address round-2 PR review — dead code, local hash skip, dev filtering
    
    - Use sanitized bundle_dir.name for archive path + ensure_path_within
    - Remove dead _dep_install_path() from install.py
    - Skip content hash computation for local path dependencies
    - Remove unused 'import shutil as _shutil_hash'
    - Remove duplicate TestInitPluginFlag class (covered by test_init_plugin.py)
    - Use lockfile is_dev flag for dev dep filtering in plugin exporter,
      with apm.yml URL fallback for older lockfiles
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * docs: comprehensive documentation audit fixes (15 files)
    
    - Add 'Plugin authoring' section to plugins.md explaining APM as
      supply-chain layer with three modes (APM-only, Plugin-only, Hybrid)
    - Add devDependencies section to dependencies.md guide
    - Add dev dependency isolation + symlink tar filtering to security.md
    - Add is_dev prose and example to lockfile-spec.md
    - Add plugin exclusion note to pack-distribute.md and cli-commands.md
    - Add plugin CI/CD example to ci-cd.md
    - Add plugin authoring cross-references to first-package.md,
      key-concepts.md, ide-tool-integration.md
    - Fix broken table in dependencies.md (3 rows concatenated on 1 line)
    - Fix duplicate code fence in integration-testing.md
    - Fix broken link in migration.md (quickstart → quick-start)
    - Fix CHANGELOG date typo (0.7.0: 2025-12-19 → 2024-12-19)
    - Fix dead WIP file reference in dependencies.md
    - Fix duplicate sidebar order in private-packages.md (8 → 9)
    - Fix gh-aw.md contradiction (claimed install && compile)
    - Standardize apm.yaml → apm.yml in security.md
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: devDep filtering uses composite key + local plugin.json install
    
    Two bugs found during hero scenario E2E testing:
    
    1. DevDependencies URL matching used only repo_url, causing ALL
       packages from the same repo to be excluded when any one was a
       devDep (e.g., marking one github/awesome-copilot sub-package as
       dev excluded all context-engineering skills too). Fix: use
       (repo_url, virtual_path) composite key for precise matching.
    
    2. Local path dependencies with plugin.json (but no apm.yml or
       SKILL.md) were rejected as 'not a valid APM package'. Fix: also
       check for plugin.json via find_plugin_json() in both validation
       and install gates.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: bare skill export, local plugin normalization, remove context/memory docs
    
    - Add _collect_bare_skill() to plugin exporter for SKILL.md-only packages
    - Call normalize_plugin_directory() for local marketplace_plugin deps
    - Remove all .apm/context/ and .apm/memory/ references from docs (6 files)
    - Add 5 unit tests for bare skill detection (63 total plugin exporter tests)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * refactor: centralize package type detection into detect_package_type()
    
    Extract the if/elif cascade that maps disk contents → PackageType into
    a single pure function in validation.py. Replace 3 duplicate sites:
    
    - validation.py: validate_apm_package() inline cascade
    - install.py:1292: fresh local install detection (missed HOOK_PACKAGE)
    - install.py:1497: cached package detection (missed HOOK_PACKAGE)
    
    The two install.py copies were incomplete — they lacked HOOK_PACKAGE
    and plugin evidence (agents/skills/commands dirs) fallback. A hooks-only
    package installed locally would have been silently misclassified.
    
    Add 11 unit tests covering all 6 PackageType variants + precedence.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    danielmeppiel and Copilot authored Mar 20, 2026
    Configuration menu
    Copy the full SHA
    411aab5 View commit details
    Browse the repository at this point in the history
  4. docs: refresh README highlights with plugin authoring and hyperlinks (#…

    …385)
    
    * docs: refresh README highlights with plugin authoring and hyperlinks
    
    Lead with plugin authoring — the new paradigm of building Copilot,
    Claude, and Cursor plugins with full supply-chain tooling. Add
    hyperlinks on every highlight title pointing to the relevant docs page
    so users reach value fast.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * docs: add plugin authoring value prop to Why APM section
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add 1-minute product showcase video to README
    
    - Extract thumbnail from rendered video (title card at 2s mark)
    - Add play button overlay for visual affordance
    - Upload MP4 to v0.8.2 release as asset
    - Insert centered thumbnail+link block between tagline and Why APM
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * docs: reorder highlights, shorten plugin line, drop compile bullet
    
    Reorder: core value props first, then security, then authoring/distribute.
    Shorten the plugin authoring bullet to one line. Remove 'compile to
    standards' — it's a detail, not a headline value prop.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * docs: remove video embed from README
    
    The release asset approach triggers a download instead of inline playback.
    Removing until a proper inline solution is implemented.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    danielmeppiel and Copilot authored Mar 20, 2026
    Configuration menu
    Copy the full SHA
    6457eac View commit details
    Browse the repository at this point in the history
  5. fix: preserve DependencyReference through download pipeline (#382) (#383

    )
    
    * fix: preserve DependencyReference through download pipeline (#382)
    
    Subdirectory packages on non-GitHub/ADO hosts (e.g. GitLab, Gitea) failed
    because the download pipeline converted DependencyReference to a string
    via str() and re-parsed it in download_package(). The str() → parse()
    round-trip lost the repo_url / virtual_path boundary on generic hosts
    where _detect_virtual_package() uses a dynamic min_base_segments heuristic.
    
    Fix: pass the structured DependencyReference object through the pipeline
    instead of flattening to string. Specifically:
    
    - download_package() and resolve_git_reference() now accept
      Union[str, DependencyReference], skipping the parse when already
      structured
    - build_download_ref() returns a DependencyReference (via
      dataclasses.replace) instead of a flat string
    - All call sites in install.py and _utils.py updated to pass the
      object directly
    
    Closes #382
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: address Copilot review feedback
    
    - Normalize original_ref to string in resolve_git_reference() to avoid
      leaking DependencyReference objects into ResolvedReference.original_ref
    - Replace shallow test with one that verifies DependencyReference.parse()
      is NOT called when passing a structured object to download_package()
    - Update test_resolve_git_reference_branch to match normalized original_ref
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Sergio Sisternes <sergio.sisternes@epam.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    3 people authored Mar 20, 2026
    Configuration menu
    Copy the full SHA
    379b9d3 View commit details
    Browse the repository at this point in the history
  6. chore: release v0.8.3 (#386)

    * chore: bump version to 0.8.3, update changelog for release
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Update CHANGELOG.md
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    3 people authored Mar 20, 2026
    Configuration menu
    Copy the full SHA
    696e1e0 View commit details
    Browse the repository at this point in the history
  7. fix: cross-platform absolute path rejection in plugin exporter

    Use PurePosixPath + PureWindowsPath to reject absolute paths from both
    platforms regardless of the current OS. Fixes Windows CI failure where
    /etc/passwd was not detected as absolute.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    danielmeppiel and Copilot committed Mar 20, 2026
    Configuration menu
    Copy the full SHA
    138334f View commit details
    Browse the repository at this point in the history
Loading