Repository navigation
Description
Hey Squad team — first off, thanks for shipping #876 and following up so cleanly with #963. Squad reaching for APM as the distribution layer is a milestone, and the framing in the PR description (".squad/ remains the source of truth — APM is an export layer") nails the architecture I'd hoped third-party tools would land on.
I'm Daniel, the maintainer of microsoft/apm. Working through the merged code, I noticed the integration drifts from APM's current contract in a handful of spots. Each one has a documented APM-side answer, and most would simplify Squad's code in the process. Writing this up so it's all in one place — happy to send a PR for the mechanical bits if it's useful.
Summary
| # | Area | Squad today | APM contract |
|---|---|---|---|
| 1 | apm.yml schema |
Top-level skills: / instructions: / prompts: |
Not valid keys; primitives are discovered from .apm/ |
| 2 | Install | Reimplemented via gh api + a regex YAML parser |
Shell out to apm install owner/repo[/skill-name] |
| 3 | Publish/portability | Custom apm.yml regen |
apm pack --format plugin produces a portable bundle |
| 4 | Distribution model | "APM registry" / apm publish |
Git-native; no registry; apm publish doesn't exist |
| 5 | Skill source path | .copilot/skills/<name>/skill.md |
.apm/skills/<name>/SKILL.md (then APM deploys to .copilot/, .github/, etc.) |
1. apm.yml doesn't have skills: / instructions: / prompts: top-level keys
The manifest only recognizes name, version, description, author, license, target, type, scripts, dependencies, devDependencies, compilation (manifest-schema §2). Primitives aren't declared in the manifest — they're discovered from .apm/<primitive>/ directories (primitive-types). The blocks Squad emits are silently ignored by apm install, and the target: paths inside them aren't honored — APM's integrators decide deployment paths based on the consumer's target: setting.
Suggested: emit only the fields APM reads — typically name, version, and (when relevant) a dependencies.apm: block. Skill content goes in .apm/skills/<name>/SKILL.md and is picked up automatically.
2. squad skill install reimplements apm install
The current path uses gh api to fetch the upstream apm.yml, parses it with a regex YAML reader, then gh api-fetches each skill.md. APM's apm install already does this and a lot more (cli-commands):
apm install owner/repo # whole package
apm install owner/repo/skill-name # virtual subdirectory (selective)
apm install owner/repo/path/skill.md # single fileYou also get lockfile pinning (apm.lock.yaml), transitive resolution, content-hash verification, and security scanning — none of which are reachable via the gh api path. The lockfile also tracks provenance, so .apm-source.json becomes redundant.
Suggested: swap the install internals for execFile('apm', ['install', source]). Drops ~200 LOC including the YAML parser flagged in #963.
3. The actual feature for "make this Squad portable" is apm pack --format plugin
squad skill publish regenerates apm.yml to advertise local skills. The intent — "make this skill bundle portable so others can use it" — is exactly what apm pack --format plugin solves (pack-distribute §plugin format):
"
apm pack --format plugintransforms your project into a standalone plugin directory consumable by Copilot CLI, Claude Code, or other plugin hosts. The output contains no APM-specific files."
Mapping:
| Source | Plugin output |
|---|---|
.apm/skills/*/SKILL.md |
skills/*/SKILL.md |
.apm/agents/*.agent.md |
agents/*.agent.md |
.apm/prompts/*.prompt.md |
commands/*.md |
.apm/instructions/*.instructions.md |
instructions/*.instructions.md |
Suggested: squad skill publish shells out to apm pack --format plugin after laying skills out under .apm/skills/<name>/SKILL.md. Users git push the resulting bundle. This also unlocks "hybrid mode" (guides/plugins) — Squad packages can declare dev-only deps that get excluded from the published bundle.
4. There's no APM registry and no apm publish
A few user-facing strings reference both:
skill.ts:173— "push to GitHub to share via APM registry"skill.ts:183— "Run 'apm publish' to push to the APM registry"skill.ts:298(help) — "APM registry: https://github.com/microsoft/apm"
APM is git-native by design (what-is-apm):
"Distribute. Any git repository is a valid APM package. Publish by pushing to a git remote — no registry required."
microsoft/apm is the source repo, not a registry endpoint. Marketplaces (guides/marketplaces) exist as optional curated indexes for discovery, but there's no apm publish and no plan to add one — the model is intentionally git push.
Suggested: update the strings to "Run apm pack --format plugin to produce a portable bundle, then git push to share."
5. Skill source location: .apm/skills/, not .copilot/skills/
Worth being precise on the directory model since the doc has been ambiguous on this:
.apm/<primitive>/is where a project's own primitives live (the project itself is a package). APM discovers them automatically..copilot/,.github/,.claude/,.cursor/are deploy targets thatapm installpopulates, both from local.apm/content and from installed dependencies. They're outputs, not sources.
Today resolveSkillsDir writes skills to .copilot/skills/<name>/skill.md as the source location, which inverts that model. (Side note: @Omzig already noted in #924 that Copilot CLI doesn't actually read .copilot/skills/ either, so users probably aren't getting what they expect on the consumer side.)
Suggested: treat .apm/skills/<name>/SKILL.md as the source of truth. APM's integrators handle the per-target deployment.
On the APM side
A few things shipping in parallel that should make this easier going forward:
- JSON Schema for
apm.yml(warns rather than errors on unknown top-level keys, so existing Squad-generated manifests in the wild won't break overnight). - A short doc page aimed at framework authors integrating with APM, with Squad as the worked example if you're OK with that.
Offer
Items 1, 2, 4, 5 are mechanical and I'd estimate ~150 LOC net delta (negative once the YAML parser comes out). Happy to PR them in one or split across a few. Item 3 is a UX shift for squad skill publish so I'd defer to you on direction before opening anything.
Let me know what's useful — no obligation either way, and again, really nice to see APM integration in Squad.
— Daniel
Activity
bradygaster commentedon Apr 25, 2026
Closed by #theSquadsquad triage — verified fixed/superseded in v0.9.4.