Skip to content

Plugin with a standard $schema root manifest + native/legacy components fails to install #161

Description

@mohdhassaan

Summary

Installing a plugin whose repo root has an Agent Plugins $schema manifest and also ships native manifests (.claude-plugin/plugin.json) plus legacy component dirs (commands/, agents/, hooks/) fails. The same plugin installs fine before the $schema line is added. So adding a spec-conformant $schema to a manifest that coexists with a native/legacy layout — a very common intermediate state during migration — makes the plugin uninstallable.

Repro

agents.toml:

version = 1
agents = ["claude"]

[[plugins]]
name = "agent-skills"
# addyosmani/agent-skills#463 head — adds `$schema` to the root plugin.json
source = "addyosmani/agent-skills@0290b86c3dc998c22636a6a408f82ae05e16988c"
targets = ["claude"]
npx @sentry/dotagents@2.2.0 install
# 3.0.0: npx @sentry/dotagents@3.0.0 --project install

→

Failed to resolve plugin "agent-skills": Plugin "agent-skills" not found in
addyosmani/agent-skills@0290b86c... Matching marketplace entries use unsupported
source types: local, github. Only local marketplace sources are supported.

Control (same repo, the commit immediately before $schema was added) installs cleanly, commands + skills present:

source = "addyosmani/agent-skills@0.6.6"   # ✅ installs

Adding path = "." swaps the (misleading) marketplace error for the real one:

Failed to resolve plugin "agent-skills": Agent Plugins v1 bundle contains legacy
root components: agents, commands, hooks, .claude-plugin, .codex-plugin.
Move client-specific resources into reverse-domain extension directories.

Root cause (traced in plugins/store.ts)

The upstream commit changes only the root plugin.json, adding:

"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json"

This flips the root candidate to a standard manifest, so validateStandardBundleLayout runs and rejects the root because the same repo also has agents/, commands/, hooks/, .claude-plugin/, .codex-plugin/ at the root. With the root candidate rejected, resolveNamedPluginCandidate falls through to the marketplace outcome; addyosmani's .claude-plugin/marketplace.json entry uses a github source (unsupported), so the surfaced error is the marketplace one. Without $schema (the 0.6.6 state) the root is handled as a native/legacy plugin and installs fine.

Expected

A "hybrid" bundle — a standard $schema root manifest coexisting with native manifests (.claude-plugin/plugin.json) and/or legacy root dirs — should still install, ideally by falling back to native/legacy handling (exactly what happens today when $schema is absent) rather than hard-failing. Adding a spec-conformant $schema to an otherwise-working plugin shouldn't make it uninstallable.

Impact

Latent breakage for any consumer that pins such a plugin and later bumps to a release that adds $schema. Reproduces on 2.2.0 and 3.0.0. Real-world trigger: addyosmani/agent-skills#463.

Environment

  • @sentry/dotagents 2.2.0 and 3.0.0
  • macOS, Node 20+

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions