feat(cursor): add Marketplace plugin packaging#489
Merged
Conversation
Mirror the Claude Code plugin layout for Cursor's plugin marketplace:
- .cursor-plugin/plugin.json: manifest pointing at ./configs/cursor/context-mode.mdc, ./skills/, ./hooks/cursor/hooks.json, and an MCP server entry running 'npx -y context-mode'.
- hooks/cursor/hooks.json: registers preToolUse, postToolUse, sessionStart, afterAgentResponse, and stop, all dispatched through 'npx -y context-mode hook cursor <event>' so users do not need a local clone.
- src/adapters/cursor/index.ts: doctor now detects plugin installs under ~/.cursor/plugins/{local,cache} and warns when both the plugin and a native .cursor/hooks.json register context-mode hooks.
- scripts/version-sync.mjs: keeps .cursor-plugin/plugin.json in lockstep with package.json.
- README.md, docs/platform-support.md: document the Marketplace install path alongside the existing manual install.
Refs mksglu#485
added 3 commits
May 9, 2026 21:57
- Add .cursor-plugin/README.md so the Marketplace tile has a dedicated landing page (project root README is unchanged). - Remove 'displayName' from .cursor-plugin/plugin.json: the field is not in Cursor's plugin manifest schema (https://cursor.com/docs/reference/plugins) and would be flagged by the validator. Validated all manifest keys against the official schema; no other extra fields. Cursor adapter test suite: 50/50 pass.
Adds .cursor-plugin/assets/logo.png and references it via the manifest 'logo' field. Cursor resolves relative paths to raw.githubusercontent.com URLs at the commit SHA, so the Marketplace tile renders the snowflake icon directly from the repo.
Document the robocopy/symlink workflow so reviewers (and early adopters) can try the plugin from the repo before Marketplace acceptance. Calls out the Windows symlink limitation explicitly so testers do not waste time debugging mklink.
Per maintainer feedback: until Cursor's review team lists the plugin, the README needs an explicit 'work in progress' notice plus copy-pasteable local-install commands for both Windows (robocopy) and macOS/Linux (ln -s). Calls out the Windows symlink limitation directly so testers do not waste time debugging mklink. Refs mksglu#485, mksglu#489
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds Cursor Marketplace plugin packaging for context-mode, mirroring the
existing Claude Code plugin layout. Refs #485.
Full research, decision tree, and grill-me self-questioning are in
.github/drafts/cursor-plugin-proposal.md(kept on a separate
docs/cursor-plugin-proposalbranch on the fork toavoid drafts in the main tree). It walks through:
have a first-party plugin format we can target.
routing strength, runtime distribution) and why only the first is
packaging-fixable.
additional_contextnot-surfaced bug (forum #155689, #156157)and why the
.mdcrule file remains the routing primary.What this PR ships (scope = PR-B from the proposal + 2 zero-cost PR-A items)
.cursor-plugin/plugin.jsonat repo root, single-plugin layout per Cursor template guidance. Points at./configs/cursor/context-mode.mdc,./skills/,./hooks/cursor/hooks.json, and registers an MCP server vianpx -y context-mode.hooks/cursor/hooks.json(separate from the existinghooks/hooks.jsonClaude file to avoid collision). Registers 5 events:preToolUse,postToolUse,sessionStart,afterAgentResponse,stop.src/adapters/cursor/index.tsnow scans~/.cursor/plugins/{local,cache}forname === "context-mode"and reportsPlugin install: pass. When both the plugin and a native.cursor/hooks.jsonregister context-mode hooks, doctor emits awarnso users can de-duplicate.scripts/version-sync.mjskeeps.cursor-plugin/plugin.jsonin lockstep withpackage.json(alongside the 6 existing manifests).README.mdCursor section now has "Option A — Marketplace plugin" + "Option B — Manual install" (existing path preserved).docs/platform-support.mddocuments the Marketplace install path and the duplicate-hook warning.Two items from PR-A in the proposal landed here because they are pure
config registrations (the hook scripts already exist in
hooks/cursor/sessionstart.mjsand
hooks/cursor/afteragentresponse.mjsbut the existing
configs/cursor/hooks.jsonnever wired them up):sessionStart— proposal Q5 flagged validator acceptance asNEEDS VERIFICATION; manual smoke test on Cursor v3.3.27 (custom
variant) accepted the registration and fired the hook.
afterAgentResponse— proposal Q4: the script existed but was deadcode; this PR wires it up.
What this PR does NOT ship (kept for follow-up PRs)
The remaining PR-A coverage expansion (6 events) is not included:
beforeShellExecution,afterShellExecutionbeforeReadFile,afterFileEditbeforeSubmitPromptpreCompactpostToolUseFailureEach requires a new hook script under
hooks/cursor/and correspondingadapter routing logic, plus tests. Sized as a separate PR so this one
stays narrowly focused on Marketplace packaging.
The runtime-distribution gap (proposal §2c — Cursor manifest has no
${PLUGIN_ROOT}equivalent, so the plugin still requiresnpm i -g context-modeornpx -y) is not addressed. That needs upstreamCursor work.
Backward compatibility
Pure addition. Existing users with
.cursor/{mcp,hooks}.jsonfrom themanual install are untouched. If they later install the plugin too,
doctor surfaces the duplication as a
warnwith remediation text.Local validation
Tested end-to-end on Cursor v3.3.27 (Windows 11) by mirroring this branch
into
~/.cursor/plugins/local/context-mode/via robocopy (Cursor doesnot follow Windows symlinks/junctions, so
mklinkdoes not work forlocal plugin testing — documented for reviewers reproducing locally).
Confirmed in the IDE:
context-modegreen dot, 11 tools enabledctx-doctor, ctx-insight, ctx-purge, +2)
firing on the corresponding agent action (4–5s each due to
npx -ycold start, acceptable trade-off for distribution)Cursor adapter test suite: 50/50 pass (
tests/adapters/cursor.test.ts+tests/hooks/cursor-hooks.test.ts).Try it locally before merge (for reviewers)
Cursor does not follow Windows symlinks or junctions for plugin
folders, so the standard
ln -s/mklinkapproach fails on Windows.Use a mirror copy instead.
Windows (PowerShell):
macOS / Linux:
Then restart Cursor and open the Plugins panel — "Context Mode
(Local)" should appear with 1 MCP server, 7 skills, and 5 hooks. To
smoke-test the routing, ask the agent to read a large file or run a
shell command; the Hooks panel's Execution Log should show
preToolUsefiring.To update after pulling new commits, re-run the same
robocopy/ln -sline (the/MIRflag handles updates and deletions).Submission checklist (cursor.com/docs/reference/plugins)
.cursor-plugin/plugin.jsoncontext-mode).cursor-plugin/assets/logo.png(snowflake mark, 49 KB).., no absolutes)marketplace.json)Follow-up plan
After this lands, planned follow-ups in priority order:
listed above, with new scripts under
hooks/cursor/and tests.Highest expected context-saving impact.
next, submit toCursor's review queue. Logo asset needed first.
--fixfor duplicates — currently doctor warns; couldoffer to delete the matching entries in
.cursor/hooks.jsonautomatically.
bin/context-mode-cursor-install.mjs(proposal §6 PR-C, lowpriority) — copy plugin files into
~/.cursor/plugins/local/forusers who want plugin behavior before Marketplace acceptance.
Marketplace submission (after merge)
Only the repo owner can submit to the public Marketplace. Once this PR
lands on
next(and gets promoted tomain), submission is a one-timestep at https://cursor.com/marketplace/publish:
mksglu/context-mode.https://github.com/mksglu/context-mode.checks, and renders the logo from
raw.githubusercontent.com/mksglu/context-mode/<sha>/.cursor-plugin/assets/logo.png.and at https://cursor.com/marketplace.
I cannot file the submission from the fork — Cursor verifies repo
ownership during the publish flow.
Open questions for maintainer
Mert Koseoğlu(matching.claude-plugin/plugin.json)is what I used. Confirm or change?
items), or do you want me to split sessionStart/afterAgentResponse
into a separate PR?
Refs #485