Installing APM Packages and Primitives
This page is for consumers — repositories that depend on APM content. Authors should read Publishing instead.
Prerequisites
| Requirement | How to get it |
|---|---|
gh CLI authenticated against github.com with repo scope on calab-ai | gh auth login and gh auth refresh -h github.com -s repo |
gh-calab extension installed | gh extension install calab-ai/gh-calab |
| Optional: a clean working tree | gh calab apm sync writes files; commit or stash local changes first |
Sanity-check everything in one command:
gh calab doctordoctor exits 0 when the toolchain is healthy and 7 if gh lacks the required scopes.
Initialize the workspace
If your repo doesn’t already have an apm.yml:
gh calab workspace init --tool copilotThis writes a minimal apm.yml. Add --force (-f) only when you intentionally want to overwrite an existing manifest.
Supported --tool values today: copilot (default). The flag tags the generated manifest with the target AI tool so the catalog can filter.
Install — three forms
A. Single-arg install (auto-detect, GA)
gh calab apm install <id-or-name>The argument is auto-classified by shape:
- A bare package name like
calab-workspace-base→ resolved as a package. - A reverse-domain id matching
^calab\.package\.[a-z][a-z0-9-]+$→ package. - A reverse-domain id matching
^calab\.(agent|instructions|prompt|skill|hook|init)\.[a-z][a-z0-9-]+$→ primitive.
Both forms are accepted for packages. Existing handbook docs (e.g. the Marketplace, [Decision 11](../../../00 Governance/Decisions/11 APM CLI Direction.md), and the APM sequence diagrams) use the short package name (
calab-workspace-base) and that is the preferred form for packages. Primitives must use the reverse-domain id because the short name alone is ambiguous across primitive types.
Examples (against the current GA catalog):
# Packages — short name (preferred) or reverse-domain id both work
gh calab apm install calab-workspace-base
gh calab apm install calab-org-agents
gh calab apm install calab.package.workspace-base # equivalent
# Primitives — reverse-domain id (required)
gh calab apm install calab.agent.build
gh calab apm install calab.agent.plan
gh calab apm install calab.instructions.coding-standards
gh calab apm install calab.instructions.security
gh calab apm install calab.skill.az-cli
gh calab apm install calab.skill.gh-cli
gh calab apm install calab.skill.summarise
gh calab apm install calab.skill.export-to-pdf
gh calab apm install calab.skill.todo-cli
gh calab apm install calab.skill.repo-calab-handbook
gh calab apm install calab.skill.repo-github-private
gh calab apm install calab.init.cloud-agent-setupUnrecognised id shapes exit 2 (usage error). Names or ids that don’t exist in the catalog exit 3 (not found).
B. Explicit subcommands (landing in calab-ai/gh-calab#7)
These make the intent unambiguous and let CI assert the kind:
gh calab apm install package <package-id>
gh calab apm install primitive <primitive-id>A subcommand asserts the kind. Mismatch — for example gh calab apm install package calab.skill.az-cli — exits 4 (validation error) rather than silently doing the wrong thing.
C. The --kind flag (also in PR #7)
For one-shot scripts where you want kind-checking without using the subcommand form:
gh calab apm install --kind package calab-workspace-base
gh calab apm install --kind primitive calab.skill.az-cli
gh calab apm install --kind=primitive calab.skill.az-cli # `=` form also worksSame exit-4 contract on mismatch.
Status: PR #7 is open (not yet merged) at the time of writing. Until it merges, only form A is live; form B/C will start working immediately on merge with no
apm.ymlmigration required.
What apm install actually does
For each install:
- Resolves the id against the current catalog (
portal-data.json, falling back to Git tag enumeration). - Adds a dependency entry to
apm.yml:dependencies: - id: calab.package.workspace-base source: repo: calab-ai/apm-registry ref: refs/tags/packages/calab-workspace-base/v1.0.0 path: packages/calab-workspace-base targets: - path: .github/copilot - Resolves the manifest into
apm.lock.yaml(commit SHA + per-file SHA-256 hashes). - Writes the resolved files to the declared
targets. - Records every written file in
.generated-from-apm.json(provenance).
The JSON envelope (with --json) returns:
{
"ok": true,
"command": "apm install",
"data": {
"kind": "package",
"kind_detected": true,
"installed": [
{
"id": "calab.package.workspace-base",
"ref": "refs/tags/packages/calab-workspace-base/v1.0.0",
"commit": "8f3c2a1...",
"files": [".github/copilot/agents/build/agent.md", "..."]
}
]
}
}kind_detected is false when the kind was asserted via subcommand or --kind.
Browsing the catalog
gh calab apm catalog # human-readable
gh calab apm catalog --json # machine-readable, schema in apm-cli-contract.mdThe handbook also renders a current snapshot at APM Marketplace, and the live portal lives at https://cautious-adventure-p3oze29.pages.github.io/.
Verifying the install
gh calab apm validate # schema + policy checks
gh calab apm validate --verify # also re-downloads + re-hashes every installed fileValidate exits non-zero on any drift (lockfile vs manifest, missing files, branch ref where tags are required, hash mismatch).
Common patterns
Install the org base for a brand-new consumer repo
gh calab workspace init --tool copilot
gh calab apm install calab-workspace-base
git add apm.yml apm.lock.yaml .github/copilot .generated-from-apm.json
git commit -m "chore(apm): adopt calab-workspace-base v1.0.0"Add a single skill to an existing manifest
gh calab apm install calab.skill.export-to-pdf
git add apm.yml apm.lock.yaml .github/copilot .generated-from-apm.json
git commit -m "chore(apm): add export-to-pdf skill"CI-side install from the lockfile (no manifest edit)
- name: Install APM dependencies
run: gh calab apm sync
env:
GH_TOKEN: ${{ github.token }}apm sync reads apm.lock.yaml and reproduces a byte-identical tree. Never call apm install from CI.