Skip to content

feat: check plugin dependencies when validating and publishing to a marketplace - #156

Merged
unional merged 4 commits into
mainfrom
feat/marketplace-plugin-dependencies
Oct 5, 2026
Merged

unional merged 4 commits into
mainfrom
feat/marketplace-plugin-dependencies

Conversation

@unional

@unional unional commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Why

A plugin that declares a dependency (e.g. buddy-agent-harness → agent-harness) published to a marketplace that does not list the dependency fails to install in Claude Code. Neither the publish-plugin skill nor marketplace validate noticed.

What

  • publish-plugin skill — new step 2f reads the declaration Claude Code receives (built .claude-plugin/plugin.json, else the canonical declaration, claude-code harness override first).

    • A plain dependency (bare name, or object with no marketplace) that the target catalog does not list is listed in the same PR, with its own pre-flight and entries. If it cannot be listed, the skill stops and asks for it to be published first.
    • A dependency that names a marketplace gets no entry, even when it names this marketplace. When it names a different marketplace, the skill explains that allowCrossMarketplaceDependenciesOn is needed and offers to add it.
    • Adds an eval for this.
  • marketplace validate (Claude catalog only) — reports issues offline: a plain dependency the catalog does not list, and a dependency on a marketplace missing from allowCrossMarketplaceDependenciesOn. It reads each entry's own dependencies and the manifest of any plugin at a ./ source. These are issues (exit 1), graded like a dangling ./ source, because the plugin cannot install from that catalog. npm/git sources are not fetched.

  • marketplace init --force — no longer drops allowCrossMarketplaceDependenciesOn when it regenerates the catalog.

  • Spec nodes (marketplace/validate, marketplace/init), the docs site, and two minor changesets are updated.

  • plugin build follows the same narrower rule. Only a plain dependency has to be listed in the catalog it refreshes. A dependency that names a marketplace is the author's explicit choice, so it isn't checked against the listing, even when it names this catalog. ADR-0018 records this as a revision. validate and build now share one check (catalogDependencyIssues).

Grading: validate fails, build warns

validate fails because a catalog that lists a plugin without that plugin's plain dependency gives every installer a plugin that fails to load. build only warns, as ADR-0018 already decided, because it runs before any catalog exists. --strict-dependencies still turns the warning into a failure.

🤖 Generated with Claude Code

unional and others added 3 commits October 4, 2026 17:43
…generation

Discovery cannot derive the allowlist, and `marketplace init --force` dropped it,
making every cross-marketplace dependency refused at install.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…talog

In the Claude catalog, a listed plugin's plain dependency the catalog does not
list, or a dependency on a marketplace missing from
allowCrossMarketplaceDependenciesOn, is an issue. Reads only what is on disk:
the entry's own dependencies and the manifest of a plugin at a ./ source.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ting

A plain dependency the target marketplace does not list is listed in the same
PR, or the skill stops; a dependency on another marketplace gets an offer to
add it to allowCrossMarketplaceDependenciesOn.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 602e1c8

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
universal-plugin Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Claude Code resolves a plain dependency against the installing marketplace; a
named marketplace is the author's explicit choice, so it is not held to the
catalog's listing even when it names this catalog. Revises ADR-0018 §1, and
validate now shares the check instead of filtering on its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@unional
unional merged commit c5c31a8 into main Oct 5, 2026
6 checks passed
@unional
unional deleted the feat/marketplace-plugin-dependencies branch October 5, 2026 01:03
unional added a commit to repobuddy/buddy-agent-harness that referenced this pull request Oct 5, 2026
…226)

The `reference` skill now ships from the `agent-harness` plugin
(cyber-uni/cyber-agentkit#55), which is being renamed
`cyber-agent-harness`. If both plugins ship it, they collide. So this PR
removes it from `buddy-agent-harness` and adds a plugin-level dependency
on `agent-harness`.

## Plugin dependency, per harness

| Harness | Plugin dependency | What this PR does |
| --- | --- | --- |
| Claude Code | yes, a `dependencies` field in
`.claude-plugin/plugin.json`
([docs](https://code.claude.com/docs/en/plugin-dependencies)) |
`"cyber-agent-harness"`, resolved from the marketplace the plugin is
installed from |
| Cursor | no | `universal-plugin` drops the field and warns |
| Codex | no | `universal-plugin` drops the field and warns |
| Copilot CLI | no | `plugin.json` is read as-is; the field is ignored
at runtime |

The dependency is declared once, in the universal `plugin.json` under
`extensions["org.cyberuni.universal-plugin"].dependencies`.
`universal-plugin` added that field in 0.5.0, so the `version` script
now runs every step at 0.10.0, which rebuilds the existing manifests
unchanged. 0.8.0's `marketplace init --force` drops the npm-sourced
catalog entry; 0.10.0 keeps it. 0.12.0, which validates dependencies, is
newer than the repo's one-day minimum release age. The READMEs and docs
tell Cursor, Codex, and Copilot CLI users to install
`cyber-agent-harness` themselves.

**No version range on the dependency.** Claude Code resolves a range
against git tags named `<plugin>--v<version>`. agent-harness tags its
releases `@cyberuni/agent-harness@<version>`, so a range would match no
tag. Without a range, the dependency takes the latest version the
marketplace offers.

**Plain dependency, no marketplace named.** Claude Code resolves it from
the marketplace `buddy-agent-harness` was installed from. So cyberplace
lists `cyber-agent-harness`, and so does this repo's own `repobuddy`
catalog (an npm entry for `@cyberuni/agent-harness`).
`universal-plugin@0.12.0 marketplace validate` fails a catalog without
it.

## What's removed

- `skills/reference/`, along with its bundled `scripts/reference.mjs`
build (the `tsdown` entry, `src/skill-scripts/reference.ts`, and the
launchers entry), the generated invocation table
(`src/references/reference-invocation.ts`), its tests, the pack-check
probe, the `skills/reference` spec node, and the `skills/reference` docs
page. The `/skills/reference` and `/skills/load-reference` URLs now
redirect to `/agent-configuration/references/`.
- The npm `files` list didn't need a change: `skills` still covers the
remaining skills.
- No other shipped skill wires itself to `reference`, so no caller lines
needed changing.
- The `buddy-agent-harness reference` CLI command is unchanged. It runs
on `buddy-agent-reference`, not on the removed skill.

## Changeset

`minor`. Removing a shipped skill breaks plugin users, and before 1.0 a
breaking change goes in a minor bump. That matches 0.14.0, which removed
`load-reference`.

## Release dependency

- `@cyberuni/agent-harness` 0.5.0 is published; its plugin is now
`cyber-agent-harness` (cyber-uni/cyber-agentkit#58).
- universal-plugin 0.12.0 is published with the dependency checks
(cyberuni/universal-plugin#156).
- cyberplace must list `cyber-agent-harness` before this merges (a
cyberplace PR is in progress).

## Verification

- `pnpm verify` passes.
- `universal-plugin@0.12.0 marketplace validate` passes: 0 invalid of 4.
- `pnpm pack:check` passes.
- `universal-plugin@0.12.0 plugin validate` reports 0 schema violations
and 0 vendor violations.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant