Skip to content

refactor: migrate cursor to the target registry - #14

Merged
steve-calvert-glean merged 2 commits into
mainfrom
refactor/cursor-target-registry
Jul 26, 2026
Merged

refactor: migrate cursor to the target registry#14
steve-calvert-glean merged 2 commits into
mainfrom
refactor/cursor-target-registry

Conversation

@steve-calvert-glean

Copy link
Copy Markdown
Contributor

Summary

Migrates the cursor target onto PluginTargetDefinition (see #13). No behavior change — the originally planned "fixes" for Cursor turned out to be wrong once checked against this repo's own vendored conformance oracle (tests/fixtures/cursor/*.schema.json), which was already passing against the current shape:

  • displayName/category/tags are valid plugin.json fields (the schema explicitly lists them, with additionalProperties: false) — not marketplace-entry-only fields as I'd assumed from docs research.
  • Marketplace owner is genuinely optional (required: ["name", "plugins"] doesn't include it).
  • Moving category/tags onto the marketplace entry — the original plan — would have been actively wrong: entries only allow name/source/description (also additionalProperties: false).

The tell I should have caught before writing the plan: a docs-derived "fix" that would break an already-oracle-verified passing test is a signal the fix is wrong, not the test. None of that field-placement stuff is touched here.

What this PR actually does:

  • Migrates cursor onto the registry, preserving every field/behavior — verified by the vendored-schema conformance test staying green throughout.
  • Fixes one real, low-risk issue: the manifest builder had its own hardcoded default-components list, separate from (and able to diverge from) this target's actual defaultComponents. Unified to one list of schema-valid pointer fields, checked against the plugin's real resolved component set. No observable behavior change (confirmed via a new test on the one case that could have differed — an explicit components: [...] override).
  • Ports update-check's hook-injection into the shared engine (src/targets/engine.ts) — this only existed in the legacy emitCursor/emitClaude path before. Migrating cursor without doing this would have silently dropped update-check support for it.

Test plan

  • New tests: displayName/category/tags preserved in plugin.json; an explicit components: ["skills", "commands"] override correctly gets a commands pointer
  • npm run check green — 58/58 tests, including the vendored-schema conformance test and the update-check conformance test (both exercise the new registry path now)
  • Verified the Claude-target "fix" from the same original plan against claude plugin validate --strict directly (the real oracle) — a plugin.json with only name fails --strict on missing version/description/author warnings-as-errors, meaning pluginpack's existing stricter validation was already correct. That fix is dropped too; the claude migration (next PR) will be a pure structural port with no behavior change.

🤖 Generated with Claude Code

steve-calvert-glean and others added 2 commits July 26, 2026 13:42
Re-checking the originally planned Cursor "fixes" against the vendored
plugin.schema.json / marketplace.schema.json (this repo's own
conformance oracle, already passing against the current shape) showed
they were wrong:

- displayName/category/tags ARE valid plugin.json fields per the
  schema (additionalProperties: false, and they're explicitly listed)
  — not marketplace-entry-only fields as previously assumed.
- Marketplace `owner` is genuinely optional (required: ["name",
  "plugins"] does not include it) — not required as previously
  assumed. Moving category/tags to the marketplace entry would have
  been actively wrong: entries only allow name/source/description
  (additionalProperties: false).

None of that is changed here. What this commit actually does:

- Migrates cursor onto PluginTargetDefinition, preserving every
  existing field and behavior (verified by the vendored-schema
  conformance test staying green).
- Fixes one genuine, low-risk issue: the manifest builder's own
  hardcoded default-components list could diverge from this target's
  actual defaultComponents (components.ts). Replaced both with one
  list of schema-valid pointer fields, checked directly against the
  plugin's real resolved componentDirs — eliminates the divergence
  risk with no observable behavior change (confirmed via a new test
  exercising the one case that could have differed: an explicit
  `components: [...]` override).
- Ports update-check's hook-injection into the new shared engine
  (src/targets/engine.ts), which previously only existed in the
  legacy emitCursor/emitClaude path — migrating cursor without this
  would have silently dropped update-check support.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
buildPluginManifest used the target-level `version` param directly
instead of `pluginConfig.version ?? version`, silently dropping a
per-plugin version override — a real regression from the pre-migration
behavior, caught by porting the equivalent test from the claude
migration (no test previously covered this for cursor specifically).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

internal Internal refactoring, cleanup, or maintenance work

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant