Pack
Pack an apm.yml project into an Agent Plugins 1.0 bundle for offline apply.
ht pack is the producer side of handing a project to a consumer without publishing to a catalog. From a tree that has apm.yml, it writes an Agent Plugins 1.0 package — the same plugin.json layout HarnessTap already uses for publish, cut, migrate export, and apply-from-path. There is no second catalog package format and no --format apm flag.
ht pack
ht pack --archive -o ./dist
ht pack --dry-run --verboseRequires apm.yml (ht config init if you do not have one). --project defaults to ..
Output
Default output is a directory under ./build/:
build/<name>/
plugin.json
agents/
skills/
commands/
hooks/
apm.lock.yaml--archive writes build/<name>-<version>.zip (zip only). -o / --output changes the output directory (default build).
plugin.json is synthesized from apm.yml (name, version, description, author, license, homepage, repository, keywords) unless you already authored one at the project root or under .github/plugin/, .claude-plugin/, or .cursor-plugin/.
The embedded apm.lock.yaml carries pack.bundle_files: SHA-256 for every packed file except the lockfile itself.
Primitives
When .apm/ exists, local primitives are taken from .apm/agents, .apm/skills, .apm/commands, and .apm/hooks. Root-level agents/ / skills/ / commands/ / hooks/ are skipped with a warning. Without .apm/, those root directories are pack sources. Root .mcp.json (or mcp.json) is packed as mcp.json regardless of layout. ht install / ht apply use the same .apm/-wins-over-root rule and compile those primitives into the consumer's target harness directories. See Install and Apply. Use ht apply <plugin> for a packed bundle; ht install is the repo-manifest path.
Dependency files are packed only from lockfile-attested deployed_files, never from apm_modules. A hash mismatch or a missing attested file fails the pack. Symlinks in the bundle fail the pack. Critical hidden-Unicode (tag characters, bidi overrides, SMP variation selectors) fails the pack; warnings are printed and packing continues.
Bundles are target-agnostic. The consumer's project decides which harness layouts receive files at apply time.
Apply a packed dir or zip
Share the directory or zip. The consumer runs:
ht apply ./build/my-pkg
ht apply ./dist/my-pkg-1.0.0.zipApply rehashes every pack.bundle_files entry and fails closed on mismatch, extra files, missing files, or symlinks. plugin.json is bundle metadata and is never deployed as a harness file.
--dry-run prints the file list without writing. --verbose lists every packed file and remapping. --format json is available.
For a library plugin that is not an apm.yml project tree, migrate export --plugin still writes an Agent Plugins package. For catalog distribution, publish.