Skip to content

feat(registry/types): add Plugin catalog type (Phase 5a, THV-0077)#153

Merged
JAORMX merged 1 commit into
mainfrom
feat/phase5a-plugin-type
Jul 8, 2026
Merged

feat(registry/types): add Plugin catalog type (Phase 5a, THV-0077)#153
JAORMX merged 1 commit into
mainfrom
feat/phase5a-plugin-type

Conversation

@JAORMX

@JAORMX JAORMX commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Add the registry Plugin type to toolhive-core so both toolhive and toolhive-registry-server can surface plugins in the catalog. This is Phase 5a of the plugin lifecycle epic and the GATE-C3 cross-repo fan-out gate — once this is tagged and go.mod is bumped, it unblocks Phase 5b (toolhive) and Phase 5d (toolhive-registry-server).

Closes #132. Part of stacklok/toolhive#5525. Refs RFC stacklok/toolhive-rfcs#77.

What changed

  • registry/types/plugins_types.go (new) — Plugin struct mirroring Skill, dropping the skill-specific Compatibility/AllowedTools fields. Reuses the existing SkillPackage/SkillIcon/SkillRepository distribution-primitive types.
  • registry/types/data/plugin.schema.json (new) — JSON schema mirroring skill.schema.json with plugin_* $defs; required fields (namespace, name, description, version); enum-constrained status; pattern-constrained name.
  • registry/types/schema_validation.godata/plugin.schema.json added to //go:embed and referencedSchemas; (*Plugin).Validate() and ValidatePluginBytes() hooks wired in.
  • registry/types/upstream_registry.goPlugins []Plugin (omitempty) added to UpstreamData so the type has a place in the registry contract.
  • registry/types/data/upstream-registry.schema.json — optional plugins array $ref-ing plugin.schema.json.
  • Tests — marshal round-trip, Validate(), ValidatePluginBytes(), upstream-registry-with-plugins e2e validation, plus boundary cases (name pattern, status enum values, missing registryType, invalid plugin in registry). Table-driven, t.Parallel().
  • CLAUDE.md — added registry/types row to the package table.

Out of scope (later phases)

Per the RFC and the issue scope, this PR does not add: provider interface methods (ListAvailablePlugins/GetPlugin/SearchPlugins), HTTP routes (/v0.1/x/dev.toolhive/plugins), the PluginsClient, or toolhive-registry-server catalog wiring — those are Phase 5b/5d in their respective repos. It also does not duplicate the build-time PluginManifest (that lives in toolhive/pkg/plugins/parser.go).

Design note for reviewers

Plugin reuses SkillPackage/SkillIcon/SkillRepository (rather than introducing PluginPackage etc.) and the plugin schema duplicates the $defs locally (rather than cross-$refing skill.schema.json). This is a deliberate choice to keep the change scoped and non-breaking for the Alpha registry/types package, but it surfaces a follow-up worth discussing: extracting domain-neutral names (Package/Icon/Repository) + a shared $defs schema so the Skill domain doesn't leak into the plugin contract. Flagged as a judgement call; not done here because it touches exported types (CLAUDE.md "Boundaries → Ask First").

Verification

  • task lint — 0 issues
  • task test — all pass with -race
  • task test-coverageregistry/types at 81.1% (≥70%)
  • task license-check — passes (SPDX headers present)
  • TestExternalRefsHaveEmbeddedSchemas invariant still passes (the new plugins $ref resolves from embedded bytes, no network fetch)

Add the registry Plugin type to toolhive-core so toolhive and
toolhive-registry-server can surface plugins in the catalog. This is
GATE-C3 for the plugin lifecycle epic (stacklok/toolhive#5525).

- registry/types/plugins_types.go: Plugin struct mirroring Skill
  (drops skill-only Compatibility/AllowedTools), reuses
  SkillPackage/SkillIcon/SkillRepository.
- registry/types/data/plugin.schema.json: JSON schema mirroring
  skill.schema.json with plugin_* $defs.
- registry/types/schema_validation.go: embed + preload plugin schema;
  add (*Plugin).Validate() and ValidatePluginBytes().
- registry/types/upstream_registry.go: add Plugins []Plugin (omitempty)
  to UpstreamData.
- registry/types/data/upstream-registry.schema.json: optional plugins
  array $ref-ing plugin.schema.json.
- Tests: marshal round-trip, Validate, ValidatePluginBytes,
  upstream-registry-with-plugins validation, boundary cases.

Package coverage: 81.1%. Part of stacklok/toolhive#5525.
Refs RFC stacklok/toolhive-rfcs#77.

@jhrozek jhrozek left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved. Clean, well-tested mirror of the existing Skill type/schema. Verified locally: go test -race ./registry/types/, golangci-lint, and task license-check all green; schema $id/$ref URLs align and the plugin schema is correctly wired into the embed + preload path.

One non-blocking note: Plugin reuses SkillRepository/SkillIcon/SkillPackage — fine as-is (structurally identical, both Alpha), but if these are expected to diverge, consider renaming the shared structs to neutral names before graduation.

@JAORMX JAORMX merged commit 8feae89 into main Jul 8, 2026
5 checks passed
@JAORMX JAORMX deleted the feat/phase5a-plugin-type branch July 8, 2026 18:38
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.

[plugins] Phase 5a: registry/types.Plugin (THV-0077)

2 participants