Skip to content

Deploy a local bundle

You have a bundle on disk — a directory or .zip someone handed you (or a legacy .tar.gz), or the output of apm pack --format plugin. Drop it into a project with one command:

Terminal window
apm install ./path/to/bundle
apm install ./dist/my-pkg-1.0.0.zip

This is a sibling flow to Install packages. Instead of declaring a dependency in apm.yml and resolving it from a registry, you deploy a self-contained bundle directly. apm.yml is not modified — the install is imperative, like dpkg -i next to apt install.

A plugin-format bundle is a directory, zip archive, or legacy gzipped tarball with a plugin.json at the root and primitive folders alongside it:

my-bundle/
+-- plugin.json
+-- agents/
+-- skills/
+-- commands/
+-- hooks/
+-- apm.lock.yaml # optional: bundle integrity manifest

plugin.json requires only a name. APM also recognises plugin.json under .github/plugin/, .claude-plugin/, or .cursor-plugin/. For the full schema see Package anatomy.

The optional apm.lock.yaml carries pack.bundle_files — a SHA-256 manifest written by apm pack --format plugin. When present, APM verifies every listed file before deploying. When absent, older bundles still install with a warning unless policy requires hashes. With security.integrity.require_hashes: true, APM fails closed before deploy.

$ apm install ./dist/my-pkg-1.0.0.zip --target copilot
[>] Installing local bundle from ./dist/my-pkg-1.0.0.zip
[+] Bundle integrity verified
[+] Deployed 7 files to .github/

Steps APM runs:

  1. Detect. Path exists and contains plugin.json at the bundle root (zip archives and legacy tarballs are extracted to a temp directory first).
  2. Apply cached policy. Resolve the actual targets, then apply any cached org policy to bundle MCP entries and targets before files are written. Bundle install never fetches policy from the network. --no-policy skips this local gate for one invocation.
  3. Verify integrity. Hash every file listed in pack.bundle_files; reject any symlink, hash mismatch, or unlisted file.
  4. Deploy. Map agents/, skills/, commands/, hooks/ into the harness layout for each --target you passed.
  5. Record. Write a lockfile entry under the project’s apm.lock.yaml so drift detection can audit the deployed files later.

apm.yml is never touched. Re-running the same command re-deploys (use --force to overwrite locally-edited files). For centrally governed installs, warm the policy cache before distributing an offline bundle. See APM policy.

Most apm install flags target the registry/resolver pipeline and are rejected with a single error when used with a local bundle. The flags that do work:

FlagUse
--target, -tPick which harness layouts receive files.
--global, -gDeploy to ~/.apm/ instead of the current project.
--forceOverwrite locally-edited files on collision.
--dry-runShow what would be deployed; write nothing.
--no-policySkip policy preflight for this invocation only.
--verbose, -vPrint per-file deploy details.
--as ALIASOverride the display label in logs (local-bundle only).

Flags like --update, --only, --dev, --mcp, --registry, and --allow-insecure are not meaningful here — the imperative deploy path does not run the dependency resolver or registry lookup that those flags configure. APM rejects them up front with one consolidated error.

For the full flag list see the apm install reference.

Pass --target to scope the deploy. Without it APM auto-detects from the current project. If the bundle was packed for targets you are not installing into, APM prints a warning naming the missing targets and proceeds with what it can deploy.

A bundle packed with pack.target: all is target-agnostic and installs cleanly into any harness layout.

Bundles produced by the older apm pack --format apm carry an apm.lock.yaml at their root but no plugin.json. apm install rejects these with a targeted error:

'./dist/my-pkg-0.1.0.tar.gz' was packed with '--format apm' (legacy
format). 'apm install <bundle>' requires the plugin format. Repack with
'apm pack --format plugin --archive', or use 'apm unpack' to deploy the
legacy bundle.

Two ways forward:

  • Repack. If you own the bundle, run apm pack --format plugin --archive and install the new artifact.
  • Unpack. If you only have the legacy artifact, use apm unpack <bundle> to extract it. apm unpack is deprecated and will be removed in a future release; prefer repacking when you can.

A plain directory without plugin.json is not treated as a bundle at all. APM falls through to the dependency resolver and treats the path as a local-path dependency — a different flow covered in Install packages.