All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- CI: add
APM Self-Checktoci.ymlforapm audit --ci, regeneration-drift validation, andmerge-gate.ymlEXPECTED_CHECKScoverage. (#885)
- CI: smoke tests in
build-release.yml'sbuild-and-testjob (Linux x86_64, Linux arm64, Windows) are now gated to promotion boundaries (tag/schedule/dispatch) instead of running on every push to main. Push-time smoke duplicated the merge-time smoke gate inci-integration.ymland burned ~15 redundant codex-binary downloads/day. Tag-cut releases still run smoke as a pre-ship gate; nightly catches upstream codex URL drift; merge-time still gates merges into main. (#878) - CI docs: clarify that branch-protection ruleset must store the check-run name (
gate), not the workflow display string (Merge Gate / gate); document the merge-gate aggregator incicd.instructions.mdand mark the legacy stub workflow as deprecated.
- CI: deleted
ci-integration-pr-stub.yml. The four stubs were a holdover from the pre-merge-gate model where branch protection required each Tier 2 check name directly. After #867, branch protection requires onlygate, so the stubs are dead weight. ReducedEXPECTED_CHECKSinmerge-gate.ymlto justBuild & Test (Linux).
apm installsupports Azure DevOps AAD bearer-token auth viaaz account get-access-token, with PAT-first fallback for orgs that disable PAT creation. Closes #852 (#856)- New
enterprise/governance-guide.md: flagship governance reference for CISO / VPE / Platform Tech Lead audiences; trims duplication acrossgovernance.md,apm-policy.md,integrations/github-rulesets.md; addstemplates/apm-policy-starter.yml. (#851) - Enterprise docs IA refactor: hub page + merged team guides, deduped governance content. (#858)
- Landing page rewritten around the three-pillar spine. (#855)
- First-package tutorial rewritten end-to-end; fixes
.apm/anatomy hallucinations. (#866)
- gh-aw workflows now use
imports:for shared APM context instead of the deprecateddependencies:field. (#864) - CI:
merge-gate.ymlorchestrator turns droppedpull_requestwebhook deliveries into clear red checks instead of stuckExpected -- Waiting for status to be reported. (#865) - CI:
Merge Gate / gateaggregates all PR-time required checks (Build & Test (Linux)+ 4 stubs) into a single verdict; branch protection requires only this one check, decoupling the ruleset from CI workflow topology (Tide / bors pattern). (#867, #868) - CI:
merge-gate.ymlsimplified to a singlepull_requesttrigger withworkflow_dispatchfor manual recovery; the dual-trigger redundancy attempt was poisoning the branch-protection rollup withCANCELLEDcheck-runs. (#868)
apm installsurfaces the custom port in clone /ls-remoteerror messages for generic git hosts. (#804)
apm installenforces orgapm-policy.ymlat install time (deps deny/allow/require, MCP deny/transport/trust-transitive,compilation.target.allow,extends:chains,policy.fetch_failureknob,policy.hashpin);--no-policy/APM_POLICY_DISABLE=1escape hatch;--dry-runpreviews verdicts; failed package installs roll backapm.yml. Newapm policy statusdiagnostic (table /--json, exit-0 by default,--checkfor CI).apm audit --ciauto-discovers org policy. Migration: orgs publishingenforcement: blockmay see installs that previously succeeded now fail -- preview withapm install --dry-run. Closes #827, #829, #831, #834 (#832)apm experimentalcommand group - a feature-flag registry withlist/enable/disable/resetsubcommands. Opt in to new behaviour before it graduates to default. Ships with one built-in flag (verbose-version) and a contributor recipe for proposing new flags (#845)pr-review-panelgh-aw workflow: runs theapm-review-panelskill on PRs labelledpanel-reviewand posts a synthesized verdict (#824)
- Docs site publishes only on stable APM releases, not on every push to
main. Closes #641 (#822) - Dogfood APM: authored skills, agents, and instructions live in
.apm/;.github/{skills,agents,instructions}/are regenerated byapm install --target copilotand committed (#823)
pr-review-panelworkflow now runs on PRs from forks: switched topull_request_targetwith label-only triggering and a workflow-dispatch path (#826, #836, #837)
- Lowercase the host axis of the
_fallback_port_warneddedup key so deps that differ only in hostname casing collapse to one cross-protocol fallback warning, matching theAuthResolver._cacheconvention (RFC 4343). Closes #800 (#815)
- Strict-by-default git transport selection: explicit
ssh:///https://URLs no longer silently cross-fall back; shorthand defaults to HTTPS (consultsurl.<base>.insteadOf). Opt back into the legacy chain with--allow-protocol-fallbackorAPM_ALLOW_PROTOCOL_FALLBACK=1. Adds--ssh/--https/APM_GIT_PROTOCOLfor explicit shorthand selection. Closes #328 (#778) - MCP entry validation hardened: names must match
^[a-zA-Z0-9@_][a-zA-Z0-9._@/:=-]{0,127}$, URLs limited tohttp/https, headers reject CR/LF, stdio commands reject... Error messages now include a valid positive example. (#807) - Stdio MCP entries with whitespace in
commandand noargsare rejected at parse time with a fix-it error pointing at the canonicalcommand: <binary>, args: [...]shape. Closes #806 (#809)
apm install --mcp NAME(andapm mcp installalias) for declaratively adding MCP servers toapm.yml, with--transport/--url/--env/--header/--mcp-version/--registryflags and stdio passthrough. TTY prompts on replace,--forcerequired in CI. Includes--registry URLandMCP_REGISTRY_URLenv for custom (enterprise) MCP registries. Closes #807 (#810)- HTTP dependency support via
--allow-insecure+allow_insecure: truedual opt-in;--allow-insecure-hostfor transitive HTTP from new hosts; credential-helper suppression on HTTP attempts to prevent token leakage; newapm deps list --insecureview withOrigincolumn. Threat model inenterprise/security.md. Thanks @arika0093! (#700) - Multi-target support:
apm.ymltargetaccepts a list ([claude, copilot]) and CLI--targetaccepts comma-separated values; only specified targets are compiled/installed/packed. Single-string form remains backward compatible. (#628) - Marketplace UX overhaul:
apm view plugin@marketplace,apm outdatedSource column,apm marketplace validate, ref-immutability advisory, multi-marketplace shadow detection. (#514) - New MCP Servers guide (
docs/guides/mcp-servers.md) consolidating stdio / registry / remote shapes, flag reference, validation rules, and the conflict matrix in one page; assorted MCP doc drift fixes (#808) - Build-time
update_policymodule so package-manager distributions (conda-forge, brew, pixi) can disableapm updateand show custom guidance. Thanks @joostsijm! (#675) - APM Review Panel skill (
.github/skills/apm-review-panel/) plus four specialist personas (devx-ux, supply-chain-security, apm-ceo, oss-growth-hacker) routing through an APM CEO arbiter (#777)
- Preserve custom git ports across protocols: non-default ports on
ssh:///https://dependency URLs (e.g. Bitbucket Datacenter SSH 7999, self-hosted GitLab HTTPS 8443) are captured asDependencyReference.portand reused on HTTPS fallback. Closes #661, #731 (#665) - Token resolution now discriminates by port, fixing credential collisions across multiple self-hosted Git instances on the same host. Thanks @edenfunf! Closes #785 (#788)
- Detect port-like first path segment in SCP shorthand (
git@host:7999/path) and raise an actionable error suggesting thessh://form. Closes #784 (#787) --allow-protocol-fallbackemits a one-shot[!]warning when a dependency's custom port is about to be tried across both SSH and HTTPS, recommending pinning the scheme. Closes #786 (#789)apm install --globalnow installs MCP servers to global-capable runtimes (Copilot CLI, Codex CLI) instead of skipping all MCP at user scope;--trust-transitive-mcpno longer ignored under--global. Lockfile-path behavior at--globaltracked in #794 (#638)apm installno longer silently drops skills/agents/commands when a Claude Code plugin also shipshooks/*.json: detection cascade now classifies plugin-shaped packages asMARKETPLACE_PLUGINfirst; emits a[!]warning when a hook-only classification disagrees with package contents (#780)apm mcp search/list/shownow honourMCP_REGISTRY_URL(previously hardcoded to the public registry), print aRegistry: <url>diagnostic when set, and surface the configured URL in network-error messages (#813)- VS Code adapter defaults to
httptransport whentransport_typeis missing from remote registry data, matching Copilot adapter behavior (#654) apm initno longer prompts to overwrite three times on Windows CP950 terminals. Closes #602 (#647)apm initNext Steps panel surfaces install/marketplace/plugin workflows instead of the dead-endapm run startreference. Closes #603 (#649)
MCP_REGISTRY_URLvalidated at startup (schemeless / unsupported schemes rejected;http://rejected by default, opt in viaMCP_REGISTRY_ALLOW_HTTP=1); APM fails closed when a custom registry is unreachable during install pre-flight, instead of silently approving every MCP dep. Default registry keeps assume-valid for transient errors. (#814)apm install --mcpdefense-in-depth: rejects embedded..in dep names with a valid positive example, redacts URL credentials in diagnostic output (https://user:token@host/->https://host/), warns on--registry/MCP_REGISTRY_URLpointing at loopback / link-local / RFC1918 / cloud-metadata hosts (including decimal-encoded loopback). (#810)SimpleRegistryClientapplies a(connect=10s, read=30s)timeout on every registry HTTP call, removing the unbounded-hang failure mode. Tunable viaMCP_REGISTRY_CONNECT_TIMEOUT/MCP_REGISTRY_READ_TIMEOUT. (#810)
apm installnow automatically discovers and deploys local.apm/primitives (skills, instructions, agents, prompts, hooks, commands) to target directories, with local content taking priority over dependencies on collision (#626, #644)- Deploy primitives from the project root's own
.apm/directory alongside declared dependencies, so single-package projects no longer need a sub-package stub to install their own content (#715) - Add
temp-dirconfiguration key (apm config set temp-dir PATH) to override the system temporary directory, resolving[WinError 5] Access is deniedin corporate Windows environments (#629)
- Refactor
apm installinto a modular engine package (apm_cli/install/) with discrete phases and apply Strategy / Template Method / Application Service patterns; public CLI behaviour and the#762cleanup chokepoint unchanged (#764) apm marketplace browse/search/add/updatenow route through the registry proxy whenPROXY_REGISTRY_URLis set;PROXY_REGISTRY_ONLY=1blocks direct GitHub API calls (#506, #617)- CI: adopt GitHub Merge Queue with tiered CI (Tier 1 unit + binary on
pull_request+merge_group; Tier 2 integration + release-validation onmerge_grouponly) plus an inertpull_request_targetstub workflow for required-check satisfaction. CODEOWNERS now requires Lead Maintainer review for any change to.github/workflows/**(#770, #771) - Bump
pytestfrom 8.4.2 to 9.0.3 (#698) - Bump
dompurifyfrom 3.3.2 to 3.4.0 in/docs(#730) - Bump
lodash-esandlangiumin/docs(#761) - Add
.editorconfigto standardize charset, line endings, indentation, and trailing whitespace across contributions (#671) - Add
@sergio-sisternes-epamas maintainer (#623) - Close install/uninstall/update CLI integration coverage gaps surfaced by the
#764review (#767) - Add 55 unit tests for
commands/deps/_utils.pyandcommands/view.pyto address Test Improver backlog items #4 and #5 (#682)
- Harden
apm installstale-file cleanup to prevent unsafe lockfile deletions, preserve user-edited files via per-file SHA-256 provenance, and improve cleanup reporting during install and--dry-run(#666, #750, #762) - Local
.apm/stale-cleanup now uses pre-install content hashes for provenance verification. Previously the lockfile was re-read after regeneration, which always yielded empty hashes, causing the user-edit safety gate to be silently skipped for project-local files (#764) - Fix
apm install --target claudenot creating.claude/when the directory does not already exist (auto_create=Falsetargets now get their root directory created when explicitly requested) (#763) - Fix content hash mismatch on re-install when
.git/is absent from installed packages by falling back to content-hash verification before re-downloading (#763) - Make
apm installidempotent for hook entries: upsert by_apm_sourceownership marker instead of unconditionally appending, so re-running install no longer duplicates per-event hook commands (#709) - Rewrite Windows backslash paths in hook commands'
windowskey during integration; previously only Unix-style./references were rewritten, leavingwindowsscript paths unresolved at runtime (#609) - Add explicit
encoding="utf-8"to.prompt.mdopen()calls inscript_runnerto preventUnicodeDecodeErroron Windows non-UTF-8 locales (CP950/CP936/CP932) (#607) - Validate the
project_nameargument toapm initand reject/and\to prevent confusing[WinError 3]and silent path-traversal behaviour (#724) - Use
yaml.safe_dumpwhen generatingapm.ymlfor virtual-file and collection packages, sodescriptionvalues containing:no longer breakapm installwith a YAML parse error (#707) _count_package_filesinapm deps listnow reads the canonical.apm/context/(singular) directory; previously it scanned.apm/contexts/and always reported0 context filesper package (#748)apm pack --format pluginno longer emits duplicatedskills/skills/nesting for bare-skill dependencies referenced through virtual paths likeskills/<name>(#738)- Provide an ADO-specific authentication error message for
dev.azure.comremotes so users get actionable guidance instead of a generic GitHub-flavored hint (#742) - Fix
apm compile --target codex(andopencode,minimal) being a silent no-op;AgentsCompiler.compile()now routes these through the AGENTS.md compiler instead of returning an empty success result that left staleAGENTS.mdfiles (#766) - Support
codeload.github.com-style archive URLs in Artifactory archive URL generation, unblocking JFrog Artifactory proxies configured againstcodeload.github.com(#712) _parse_artifactory_base_url()now readsPROXY_REGISTRY_URLfirst (withARTIFACTORY_BASE_URLfallback +DeprecationWarning), and the virtual-subdirectory download path checksdep_ref.is_artifactory()before falling back to env-var detection, fixing lockfile reinstall failures when proxy config is only on the lockfile entry (#616)- Fall back to SSH URLs when validating git remotes for generic / self-hosted hosts so
apm installno longer fails the pre-install validation step against private SSH-only servers (#584) - Suppress internal config keys (e.g.
default_client) fromapm config getoutput, removing the get/set asymmetry that confused users and was flagged as a Medium security issue (#571) - Include dependency instructions stored in
.github/instructions/(not only.apm/instructions/) when runningapm compile --target claudewithout--local-only(#631, #642) - Fix
apm marketplace addsilently failing for private repos by using credentials when probingmarketplace.json(#701) - Harden marketplace plugin normalization to enforce that manifest-declared
agents/skills/commands/hookspaths resolve inside the plugin root (#760) - Pin codex setup to
rust-v0.118.0for security and reproducibility; update config towire_api = "responses"(#663) - Propagate headers and environment variables through OpenCode MCP adapter with defensive copies to prevent mutation (#622)
- Fix
apm installhanging indefinitely when corporate firewalls silently drop SSH packets by settingGIT_SSH_COMMANDwithConnectTimeout=30(#652, #653) - Stop
test_auto_detect_through_proxyfrom making realapi.github.comcalls by passing a mockauth_resolver, fixing flaky macOS CI rate-limit failures (#759) - Fix the Daily Test Improver workflow creating duplicate monthly activity issues; Task 7 now finds and updates the existing month's issue instead of opening a new one each run (#681)
- Artifactory archive entry download for virtual file packages (#525)
apm view <package> [field]command for viewing package metadata and remote refs (#613)apm view <package> versionsfield selector lists remote tags and branches viagit ls-remote(#613)apm outdatedcommand compares locked dependencies against remote refs (#613)--parallel-checks(-j) option onapm outdatedfor concurrent remote checks (default: 4) (#613)- Rich progress feedback during
apm outdateddependency checking (#613) --globalflag onapm viewfor inspecting user-scope packages (#613)
- Rename
apm infotoapm viewfor npm convention alignment;apm infokept as hidden alias (#613) - Scope resolution now happens once via
TargetProfile.for_scope()andresolve_targets()-- integrators no longer need scope-aware parameters (#562) - Unified integration dispatch table in
dispatch.py-- both install and uninstall import from one source of truth (#562) - Hook merge logic deduplicated: three copy-pasted JSON-merge methods replaced with
_integrate_merged_hooks()+ config dict (#562) apm outdateduses SHA comparison for branch-pinned deps instead of reporting them asunknown(#613)
- Reject symlinked primitive files in all discovery and resolution paths to prevent symlink-based traversal attacks (#596)
apm install -gnow deploys hooks to the scope-resolved target directory instead of hardcoding.github/hooks/(#565, #566)- Hook sync/cleanup derives prefixes dynamically from
KNOWN_TARGETSinstead of hardcoded paths (#565) auto_create=Falsetargets no longer get directories unconditionally created during install (#576)apm deps update -gnow correctly passes scope, preventing user-scope updates from silently using project-scope paths (#562)- Subprocess encoding failures on Windows non-UTF-8 consoles (CP950/CP936) -- all subprocess calls now use explicit UTF-8 encoding (#591)
- PowerShell 5.1 compatibility: replace multi-argument
Join-Pathcalls with nested two-argument calls (#593) apm marketplace addnow respectsGITHUB_HOSTenvironment variable for GitHub Enterprise users (#589)compilation.excludepatterns now filter primitive discovery, preventing excluded files from leaking into compiled output (#477)- Runtime detection in script runner now uses anchored patterns to prevent false positives when runtime keywords appear in flag values (#563)
apm compilenow warns when instructions are missingapplyToacross all compilation modes (#449)- Detect remote default branch instead of hardcoding
main(#574) - Warn when two packages deploy a native skill with the same name (#545)
- Hook integrator now processes the
windowsproperty in hook JSON files, copying referenced scripts and rewriting paths during install/compile (#311) - Standardized
--targetchoices, replaced Unicode with ASCII for cp1252 compatibility, and documented missing CLI flags (#519) apm install -gnow correctly deploys to user-scope directories, skips unsupported primitives, and cleans up on uninstall -- including multi-level paths like~/.config/opencode/(#542)apm deps updatenow correctly re-resolves transitive dependencies instead of reusing stale locked SHAs (#548)
apm installnow deploys.instructions.mdfiles to.claude/rules/*.mdfor Claude Code, convertingapplyTo:frontmatter to Claude'spaths:format (#516)
- Artifactory virtual file downloads now use the Archive Entry Download API to fetch individual files without downloading the full archive; falls back to full-archive extraction when the entry API is unavailable (#525)
apm install NAME@MARKETPLACEnow respectsmetadata.pluginRootfrom marketplace manifests, fixing resolution of bare-name plugins in marketplaces likeawesome-copilot(#512)- Windows unit test assertion tolerates Rich console line-wrapping on long temp paths (#510)
- Release validation scripts match updated
apm deps listscope output (#510)
apm install -g/--globalfor user-scope package installation with per-target support matrix andapm uninstall -glifecycle (#452)- Marketplace integration:
apm install NAME@MARKETPLACEsyntax,apm marketplace add/list/browse/update/remove,apm searchacross registered marketplaces (#503) - Codex as integration target: skills to
.agents/skills/, agents to.codex/agents/*.toml, hooks to.codex/hooks.json,--target codexon install/compile/pack (#504) - Lockfile-driven reproducible installs for registry proxies with
content_hashverification andRegistryConfig-- by @chkp-roniz (#401)
apm deps updateskips download when resolved SHA matches lockfile SHA, making the common "nothing changed" case near-instant (#500)
apm install -g ./local-pkgrejects local path dependencies at user scope with a clear error (#452)- Orphan documentation pages (
ci-policy-setup,policy-reference) added to sidebar navigation; stale GitHub Rulesets content updated (#505, #507)
--target opencodeno longer writes prompts/agents to.github/; dispatch loop now only fires primitives declared by the selected target (#488, #494)--target cursornow correctly deploys skills to.cursor/skills/instead of.github/skills/--SkillIntegratorrespects the explicit target list end-to-end (#482, #494)- Misleading "transitive dep" error message for direct dependency download failures (#478)
- Sparse checkout using global token instead of per-org token from
GITHUB_APM_PAT_<ORG>(#478) - Duplicate error count when a dependency fails during both resolution and install phases (#478)
- Windows Defender false-positive (
Trojan:Win32/Bearfoos.B!ml) mitigation: embed PE version info in Windows binary and disable UPX compression on Windows builds -- by @sergio-sisternes-epam (#490) apm deps updatewas a no-op -- rewrote to delegate to the install engine so lockfile, deployed files, and integration state are all refreshed correctly -- by @webmaxru (#493)
- Integration dispatch is now data-driven:
KNOWN_TARGETSdefines each target's primitives and directory layout; adding a target requires zero code changes (#494) partition_managed_files()uses O(1) component-based path routing instead of linear prefix scan (#494)- Uninstall sync uses pre-partitioned buckets via
partition_bucket_key()instead of re-scanning the full managed-files set (#494)
- Bump
pygmentsfrom 2.19.2 to 2.20.0 (#495)
apm install --targetflag to force deployment to a specific target (copilot, claude, cursor, opencode, all) (#456)- Global
apm install --global/-gandapm uninstall --globalflags for user-scope package installation, backed byInstallScope-based scope resolution incore/scope.py; deploys primitives to~/.copilot/,~/.claude/,~/.cursor/,~/.config/opencode/and tracks metadata under~/.apm/(#452)
- Windows antivirus file-lock errors (
WinError 32) duringapm installwithfile_opsretry utility (#440) - Installer fallback to pip in devcontainers, target registry, and lockfile idempotency fixes (#456)
- Reject path traversal sequences in SSH-style Git URLs — by @thakoreh (#458)
- Exclude bundled OpenSSL libs from Linux binary to prevent ABI conflicts (#466)
- Allow spaces in ADO repository names when parsing URLs (#437)
- Gate
.claude/commands/deployment behindintegrate_claudeflag (#443) - Sort instruction discovery order for deterministic Build IDs across platforms (#468)
- Share
AuthResolveracross install to prevent duplicate auth popups (#424)
- Consolidated path-segment traversal checks into
validate_path_segments()inpath_security.py(#458)
apm audit --ciorg-level policy engine -- experimental Phase 1 for enterprise governance over agents in the SDLC; GitHub / GitHub Enterprise only (#365)-vshorthand for--verbose,show_defaulton boolean options,deps clean --dry-run/--yesflags (#303)--verboseonapm installnow shows auth source diagnostics for virtual package validation failures (#414)- Nightly runtime inference tests decoupled from release pipeline via
ci-runtime.yml(#407)
- CI pipeline optimization: merged test+build jobs, macOS as root nodes, native
setup-uvcaching, removed unnecessarysetup-nodesteps (#407) - Encoding instructions enforce ASCII-only source and CLI output with bracket status symbols (#282)
- Windows path hardening:
portable_relpath()utility, ~23relative_to()call-site migrations, CI lint guard (#411, #422) - Centralized YAML I/O with UTF-8 encoding via
yaml_iohelpers, preventing Windows cp1252 mojibake, based on prior work by @alopezsanchez (#433, #388) - SSL certificate verification in PyInstaller binary via
certifiruntime hook (#429) apm pack --target claudecross-target path mapping for skills/agents installed under.github/(#426)ARTIFACTORY_ONLYenforcement for virtual package types (files, collections, subdirectories) (#418)- Local path install: descriptive failure messages and Windows drive-letter path recognition (#431, #435)
- Windows test fixes in config command and agents compiler (#410)
- Removed stale WIP folder from tracking, strengthened
.gitignore(#420)
- Centralized
AuthResolverwith per-(host, org) token resolution, cached and thread-safe — replaces 4 scattered auth implementations (#394) CommandLoggerandInstallLoggerbase classes for structured CLI output with validation, resolution, and download phases (#394)--verboseflag onuninstall,pack, andunpackcommands (#394)- Verbose output: dependency tree resolution, auth source/type per download, lockfile SHA, package type, inline per-package diagnostics (#394)
- Parent chain breadcrumb in transitive dependency error messages — "root-pkg > mid-pkg > failing-dep" (#394)
DiagnosticCollector.count_for_package()for inline per-package verbose hints (#394)- Auth flow diagram and package source behavior matrix in authentication docs (#394)
- Documented
${input:...}variable support inheadersandenvMCP server fields (#349)
- All CLI output now uses ASCII symbols (
[+],[x],[!]) instead of Unicode characters (#394) - Migrated
_rich_*calls toCommandLoggeracross install, compile, uninstall, audit, pack, and bundle modules (#394) - Verbose ref display uses clean
#tag @shaformat instead of nested parentheses (#394) - Integration tree lines (
└─) no longer have[i]prefix — clean visual hierarchy (#394) - Global env vars (
GITHUB_APM_PAT,GITHUB_TOKEN,GH_TOKEN) apply to all hosts — HTTPS is the security boundary, not host-gating (#394) - Credential-fill timeout increased from 5s to 60s (configurable via
APM_GIT_CREDENTIAL_TIMEOUT, max 180s) — fixes Windows credential picker timeouts (#394)
- Bundle lockfile includes non-target
deployed_filescausingapm unpackverification failure when packing with--target(#394) - Verbose lockfile iteration crashed with
'str' object has no attribute 'resolved_commit'(#394) - CodeQL incomplete URL substring sanitization in test assertions (#394)
- Bumped
h3from 1.15.6 to 1.15.9 in docs (#400)
- Unused image files:
copilot-banner.png,copilot-cli-screenshot.png(#391)
- Plugin authoring —
apm pack --format pluginexports APM packages as standalone plugin directories (plugin.json, agents, skills, commands) consumable by Copilot CLI, Claude Code, and Cursor without APM installed (#379) apm init --pluginscaffolds a hybrid project with bothapm.ymlandplugin.json, including adevDependenciessection (#379)devDependenciesinapm.yml— dev deps install normally but are excluded fromapm packoutput;apm install --devwrites to the dev section (#379)- VS Code runtime detection now falls back to
.vscode/directory presence when thecodebinary is not on PATH — by @sergio-sisternes-epam (#359)
- Content integrity hashing — SHA-256
content_hashper dependency inapm.lock.yaml, verified on subsequent installs to detect tampering or force-pushed commits (#315, #379) apm audit --stripnow preserves a leading BOM while stripping suspicious mid-file BOMs, preventing false negatives — by @dadavidtseng (#372)
- Install URLs now use short
aka.ms/apm-unixandaka.ms/apm-windowsredirects across README, docs, and CLI output (#384) - README highlights link to relevant docs pages; plugin authoring featured as a key value proposition (#385)
DependencyReferencepreserved through the download pipeline so lockfile records the original ref, not an empty object — by @sergio-sisternes-epam (#383)- Refactor command and model modules for readability and maintainability — by @sergio-sisternes-epam (#232)
- CLI docs align
compile --target opencode,audit --dry-run, and plannedaudit --driftwith current behavior (#373)
- JFrog Artifactory VCS repository support — explicit FQDN, transparent proxy via
ARTIFACTORY_BASE_URL, and air-gappedARTIFACTORY_ONLYmode (#354) - GH-AW compatibility gate in release pipeline —
gh-aw-compatjob tests tokenless install + pack before publishing (#356) - Release validation now includes
test_ghaw_compatscenario (#356)
- Credential fill returning garbage token in tokenless CI environments — broke
apm installfor public repos in GitHub Actions (#356)
- Harden dependency path validation — reject invalid path segments at parse time, enforce install-path containment, safe deletion wrappers across
uninstall,prune, andinstall(#364)
- Audit hardening —
apm unpackcontent scanning, SARIF/JSON/Markdown--format/--outputfor CI capture,SecurityGatepolicy engine, non-zero exits on critical findings (#330) - Install output now shows resolved git ref alongside package name (e.g.
✓ owner/repo#main (a1b2c3d4)) (#340) ${input:...}variable resolution for self-defined MCP server headers and env values — by @sergio-sisternes-epam (#344)
- Pinning hint moved from inline tip to
── Diagnostics ──section with aggregated count (#347) - Install ref display uses
#separator instead of@for consistency with dependency syntax (#340) - Shorthand
@aliassyntax removed from dependency strings — use the dict formatalias:field instead (#340)
- File-level downloads from private repos now use OS credential helpers (macOS Keychain,
gh auth login, Windows Credential Manager) (#332) - Lockfile now preserves the host for GitHub Enterprise custom domains so subsequent
apm installclones from the correct server (#338) - MCP registry validation no longer fails on transient network errors (#337)
- Native Cursor IDE integration —
apm installdeploys instructions→rules (.mdc), agents, skills, hooks (hooks.json), and MCP (mcp.json) to.cursor/(#301) - Native OpenCode integration —
apm installdeploys agents, commands, skills, and MCP (opencode.json) to.opencode/— inspired by @timvw (#306) - Content security scanning with
apm auditcommand —--file,--strip,--dry-run; install-time pre-deployment gate blocks critical hidden Unicode characters (#313) - Detect variation selectors (Glassworm attack vector), invisible math operators, bidi marks, annotation markers, and deprecated formatting in content scanning — by @raye-deng (#321, #320)
- Context-aware ZWJ detection — emoji joiners preserved by
--strip;--strip --dry-runpreview mode (#321) TargetProfiledata layer for scalable multi-target architecture (#301)CursorClientAdapterfor MCP server management in.cursor/mcp.json(#301)OpenCodeClientAdapterfor MCP server management inopencode.json(#306)- Private packages guide and enhanced authentication documentation (#314)
- Updated docs landing page to include Cursor and OpenCode (#310)
- Updated all doc pages to reflect full Cursor native support (#304)
- Added OpenCode to README headline and compile description (#308)
- GitHub API rate-limit 403 responses no longer misdiagnosed as authentication failures — unauthenticated users now see actionable "rate limit exceeded" guidance instead of misleading "private repository" errors
- Local filesystem path dependencies — install packages from relative/absolute paths with
apm install ./my-package(#270) - Windows native support (Phase 1 & 2) — cross-platform runtime management, PowerShell helpers, and CI parity — by @sergio-sisternes-epam (#227)
- CLI logging UX agent skill for consistent CLI output conventions (#289)
- Resolve
UnboundLocalErrorinapm prunecrashing all prune operations (#283) - Restore CWD before
TemporaryDirectorycleanup on Windows — by @sergio-sisternes-epam (#281) - Fix Codex runtime download 404 on Windows — asset naming uses
.exe.tar.gz— by @sergio-sisternes-epam (#287) - Fix
UnicodeEncodeErroron Windows cp1252 consoles via UTF-8 codepage configuration — by @sergio-sisternes-epam (#287) - Fix
WinError 2when resolving.cmd/.ps1shell wrappers viashutil.which()— by @sergio-sisternes-epam (#287) - Fix
GIT_CONFIG_GLOBAL=NULfailure on some Windows git versions — by @sergio-sisternes-epam (#287) - Improve sub-skill overwrite UX with content skip and collision protection (#289)
- Lockfile renamed from
apm.locktoapm.lock.yamlfor IDE syntax highlighting; existingapm.lockfiles are automatically migrated on the nextapm install(#280) - Add Windows as first-class install option across documentation site (#278)
- Clarify that
.github/deployed files should be committed (#290)
- Diff-aware
apm install— manifest as source of truth: removed packages, ref/version changes, and MCP config drift inapm.ymlall self-correct on the nextapm installwithout--updateor--force; introducesdrift.pywith pure helper functions (#260) DiagnosticCollectorfor structured install diagnostics (#267)- Detailed file-level logging to
apm unpackcommand (#252) - Astro Starlight documentation site with narrative redesign (#243)
- Resolve WinError 32 during sparse-checkout fallback on Windows — by @JanDeDobbeleer (#235)
- CLI consistency: docs alignment, emoji removal,
show_defaultflags (#266)
- Minimum Python version bumped to 3.10; Black upgraded to 26.3.1 (#269)
- Refactor
cli.pyandapm_package.pyinto focused modules — by @sergio-sisternes-epam (#224) - Revamp README as storefront for documentation site (#251, #256, #258)
- Remove duplicated content from CLI reference page (#261)
- Bump devalue 5.6.3 → 5.6.4 in docs (#263)
- Primitives models coverage 78% → 100%; add discovery and parser coverage tests (#240, #254)
copilotas the primary user-facing target name for GitHub Copilot / Cursor / Codex / Gemini output format;vscodeandagentsremain as aliases (#228)
- Consolidate pack/unpack documentation into cli-reference, rename Key Commands section
apm packandapm unpackcommands for portable bundle creation and extraction with target filtering, archive support, and verification (#218)- Plugin MCP Server installation — extract, convert, and deploy MCP servers defined in plugin packages (#217)
- Plugin agents not deployed due to directory nesting in custom agent paths (#214)
- Skip already-configured self-defined MCP servers on re-install (#191)
- CLI consistency: remove emojis from help strings, fix
apm configbare invocation, update descriptions (#212)
- Extract
MCPIntegratorfromcli.py— move MCP lifecycle orchestration (~760 lines) into standalone module with hardened error handling (#215)
- Plugin management system with CLI commands for installing and managing plugins from marketplaces (#83)
- Generic git URL support for GitLab, Bitbucket, and any self-hosted git provider (#150)
- InstructionIntegrator for
apm install— deploy.instructions.mdfiles alongside existing integrators (#162) - Transitive MCP dependency propagation (#123)
- MCP dependency config overlays, transitive trust flag, and related bug fixes (#166)
- Display build commit SHA in CLI version output (#176)
- Documentation: apm.yml manifest schema reference for integrators (#186)
- Handle multiple brace groups in
applyToglob patterns (#155) - Replace substring matching with path-component matching in directory exclusions (#159)
- Handle commit SHA refs in subdirectory package clones (#178)
- Infer
registry_namewhen MCP registry API returns empty values (#181) - Resolve
set()shadowing and sparse checkout ref issues (#184) - CLI consistency — align help text with docs (#188)
--updateflag now bypasses lockfile SHA to fetch latest content (#192)- Clean stale MCP servers on install/update/uninstall and prevent
.claudefolder creation (#201) - Harden plugin security, validation, tests, and docs (#208)
- Use
CREATE_PR_PATfor agentic workflows in Microsoft org (#144)
- Unified
deployed_filesmanifest for safe integration lifecycle (#163) - Exclude
apm_modulesfrom compilation scanning and cacheSet[Path]for performance (#157) - Performance optimization for deep dependency trees (#173)
- Upgrade GitHub Agentic Workflows to v0.52.1 (#141)
- Fix CLI reference drift from consistency reports (#160, #161)
- Replace CHANGELOG link with roadmap discussion in docs index (#196)
- Update documentation for features from 2026-03-07 (#195)
- Support hooks as an agent primitive with install-time integration and dependency display (hooks execute at agent runtime, not during
apm install) (#97) - Deploy agents to
.claude/agents/duringapm install(#95) - Promote sub-skills inside packages to top-level
.github/skills/entries (#102)
- Fix skill integration bugs, transitive dep cleanup, and simplification (#107)
- Fix transitive dependency handling in compile and orphan detection (#111)
- Fix virtual subdirectory deps marked as orphaned, skipping instruction processing (#100)
- Improve multi-host error guidance when
GITHUB_HOSTis set (#113, #130) - Support spaces in Azure DevOps project names (#92)
- Fix GitHub Actions workflow permissions, integration test skip-propagation, and test corrections (#87, #106, #109)
- Migrated to Microsoft OSS organization (#85, #105)
- Added CODEOWNERS, simplified PR/issue templates, triage labels, and updated CONTRIBUTING.md (#115, #118)
- Added missing
versionfield in the apm.yml README example (#108) - Slim PR pipelines to Linux-only, auto-approve integration tests, added agentic workflows for maintenance (#98, #103, #104, #119)
- SUPPORT.md: Added Microsoft repo-template support file directing users to GitHub Issues and Discussions for community support
- README Rewording: Clarified APM as "an open-source, community-driven dependency manager" to set correct expectations under Microsoft GitHub org
- Microsoft Open Source Compliance: Updated LICENSE, SECURITY.md, CODE_OF_CONDUCT.md, CONTRIBUTING.md, and added Trademark Notice to README
- Source Integrity: Fixed source integrity for all integrators and restructured README
- Install Script: Use
grep -ofor single-line JSON extraction in install.sh - CI: Fixed integration test script to handle existing venv from CI workflow
- Bumped
azure-core1.35.1 → 1.38.0,aiohttp3.12.15 → 3.13.3,pip25.2 → 26.0,urllib32.5.0 → 2.6.3
- Transitive Dependencies: Full dependency resolution with
apm.locklockfile generation
- Install Script and
apm update: Repaired corrupted header in install.sh. Use awk instead of sed for shell subprocess compatibility. Directed shell output to terminal for password input during update process.
- Collection Extension Handling: Prevent double
.collection.ymlextension when user specifies full path - SKILL.md Parsing: Parse SKILL.md directly without requiring apm.yml generation
- Git Host Errors: Actionable error messages for unsupported Git hosts
- Native Skills Support: Skills now install to
.github/skills/as the primary target (per agentskills.io standard) - Skills ≠ Agents: Removed skill → agent transformation; skills and agents are now separate primitives
- Explicit Package Types: Added
typefield to apm.yml (instructions,skill,hybrid,prompts) for routing control - Skill Name Validation: Validates and normalizes skill names per agentskills.io spec (lowercase, hyphens, 1-64 chars)
- Claude Compatibility: Skills also copy to
.claude/skills/when.claude/folder exists
- Auto-creates
.github/directory on install if neither.github/nor.claude/exists
- Selective Package Install:
apm install <package>now only installs the specified package instead of all packages from apm.yml. Previously, installing a single package would also install unrelated packages.apm install(no args) continues to install all packages from the manifest.
- Claude Skills Integration: Virtual subdirectory packages (like
ComposioHQ/awesome-claude-skills/mcp-builder) now correctly trigger skill generation. Previously all virtual packages were skipped, but only virtual files and collections should be skipped—subdirectory packages are complete skill packages.
- SKILL.md as first-class primitive: meta-description of what an APM Package does for agents to read
- Claude Skills Installation: Install Claude Skills directly as APM Packages
- Bidirectional Format Support:
- APM packages → SKILL.md (for Claude target)
- Claude Skills → .agent.md (for VSCode target)
- Skills Documentation: New
docs/skills.mdguide
-
Claude Integration: First-class support for Claude Code and Claude Desktop
CLAUDE.mdgeneration alongsideAGENTS.md.claude/commands/auto-integration from installed packagesSKILL.mdgeneration for Claude Skills format- Commands get
-apmsuffix (same pattern as VSCode prompts)
-
Target Auto-Detection: Smart compilation based on project structure
.github/only → generatesAGENTS.md+ VSCode integration.claude/only → generatesCLAUDE.md+ Claude integration- Both folders → generates all formats
- Neither folder → generates
AGENTS.mdonly (universal format)
-
targetfield in apm.yml: Persistent target configurationtarget: vscode # or claude, or all
Applies to both
apm compileandapm install -
--targetflag: Override auto-detectionapm compile --target claude apm compile --target vscode apm compile --target all
- Virtual package uninstall sync:
apm uninstallnow correctly removes only the specific virtual package's integrated files (usesget_unique_key()for proper path matching)
apm compiledefault: Changed from--target allto auto-detect- README refactored with npm-style zero-friction onboarding
- Documentation reorganized with Claude integration guide
- ADO Package Commands:
compile,prune, anddeps listnow work correctly with Azure DevOps packages
- ADO Path Structure: Azure DevOps packages now use correct 3-level paths (
org/project/repo) throughout install, discovery, update, prune, and uninstall commands - Virtual Packages: ADO collections and individual files install to correct 3-level paths
- Prune Command: Fixed undefined variable bug in directory cleanup
- Azure DevOps Support: Install packages from Azure DevOps Services and Server
- New
ADO_APM_PATenvironment variable for ADO authentication (separate from GitHub tokens) - Supports
dev.azure.com/org/project/_git/repoURL format - Works alongside GitHub and GitHub Enterprise in mixed-source projects
- New
- Debug Mode: Set
APM_DEBUG=1to see detailed authentication and URL resolution output
- GitHub Enterprise Private Repos: Fixed authentication for
git ls-remotevalidation on non-github.com hosts - Token Selection: Correct token now used per-platform (GitHub vs ADO) in mixed-source installations
- Enterprise GitHub host support: fallback clone now respects
GITHUB_HOSTenv var instead of hardcoding github.com - Version validation crash when YAML parses version as numeric type (e.g.,
1.0vs"1.0")
- CI/CD: Updated runner from macos-13 and macos-14 to macos-15 for both x86_64 and ARM64 builds
- Context Link Resolution: Automatic markdown link resolution for
.context.mdfiles across installation and compilation- Links in prompts/agents automatically resolve to actual source locations (
apm_modules/or.apm/context/) - Works everywhere: IDE, GitHub, all coding agents supporting AGENTS.md
- No file copying needed—links point directly to source files
- Links in prompts/agents automatically resolve to actual source locations (
- Agent Integration: Automatic sync of
.agent.mdfiles to.github/agents/with-apmsuffix (same pattern as prompt integration)
sync_integrationURL normalization bug that caused ALL integrated files to be removed during uninstall instead of only the uninstalled package's files- Root cause: Metadata stored full URLs (
https://github.com/owner/repo) while dependency list used short form (owner/repo) - Impact: Uninstalling one package would incorrectly remove prompts/agents from ALL other packages
- Fix: Normalize both URL formats to
owner/repobefore comparison - Added comprehensive test coverage for multi-package scenarios
- Root cause: Metadata stored full URLs (
- Uninstall command now correctly removes only
apm_modules/owner/repo/directory (notapm_modules/owner/)
- Prompt Naming Pattern: Migrated from
@prefix to-apmsuffix for integrated prompts - GitIgnore Pattern: Updated from
.github/prompts/@*.prompt.mdto.github/prompts/*-apm.prompt.md
- Existing Users: Old
@-prefixed files will not be automatically removed - Action Required: Manually delete old
@*.prompt.mdfiles from.github/prompts/after upgrading
- Prompt Integration with GitHub - Automatically sync downloaded prompts to
.github/prompts/for GitHub Copilot
- Improved installer UX and console output
- Package FQDN support - install from any Git host using fully qualified domain names (thanks @richgo for PR #25)
- Security: CWE-20 URL validation vulnerability - proper hostname validation using
urllib.parseprevents malicious URL bypass attacks - Package validation HTTPS URL construction for git ls-remote checks
- Virtual package orphan detection in
apm deps listcommand
- GitHub Enterprise support via
GITHUB_HOSTenvironment variable (thanks @richgo for PR #25) - Build pipeline updates for macOS compatibility
- Virtual Package Support: Install individual files directly from any repository without requiring full APM package structure
- Individual file packages:
apm install owner/repo/path/to/file.prompt.md
- Individual file packages:
- Collection Support: Install curated collections of primitives from Awesome Copilot:
apm install github/awesome-copilot/collections/collection-name- Collection manifest parser for
.collection.ymlformat - Batch download of collection items into organized
.apm/structure - Integration with github/awesome-copilot collections
- Collection manifest parser for
- Auto-Discovery of Prompts: Run installed prompts without manual script configuration
apm run <prompt-name>automatically discovers and executes prompts without having to wire a script inapm.yml- Search priority: local root → .apm/prompts → .github/prompts → dependencies
- Qualified path support:
apm run owner/repo/prompt-namefor disambiguation - Collision detection with helpful error messages when multiple prompts found
- Explicit scripts in apm.yml always take precedence over auto-discovery
- Automatic Runtime Detection: Detects installed runtime (copilot > codex) and generates proper commands
- Zero-Configuration Execution: Install and run prompts immediately without apm.yml scripts section
- Enhanced dependency resolution to support virtual package unique keys
- Improved GitHub downloader with virtual file and collection package support
- Extended
DependencyReference.parse()to detect and validate virtual packages (3+ path segments) - Script runner now falls back to prompt discovery when script not found in apm.yml
- Streamlined workflow:
apm install <file>→apm run <name>works immediately - No manual script configuration needed for simple use cases
- Power users retain full control via explicit scripts in apm.yml
- Better error messages for ambiguous prompt names with disambiguation guidance
- Auto-bootstrap
apm.ymlwhen runningapm install <package>without existing config - GitHub Enterprise Server and Data Residency Cloud support via
GITHUB_HOSTenvironment variable - ARM64 Linux support
- Refactored
apm initto initialize projects minimally without templated prompts and instructions - Improved next steps formatting in project initialization output
- GitHub token fallback handling for Codex runtime setup
- Environment variable passing to subprocess in smoke tests and runtime setup
- Copilot CLI Support
- Fix prompt file resolution for dependencies in org/repo directory structure
- APM dependency prompt files now correctly resolve from
apm_modules/org/repo/paths apm runcommands can now find and execute prompt files from installed dependencies- Updated unit tests to match org/repo directory structure for dependency resolution
- Context Packaging
- Context Dependencies
- Context Compilation
- GitHub MCP Registry integration
- Codex CLI Support