Split monolithic plugin into product-axis plugins#51
Open
CarterPape wants to merge 7 commits into
Open
Conversation
Adds plugins/<plugin-name>/ skeletons for the 9-plugin partition (8 product plugins + 1 umbrella). Updates both marketplace.json files to list the new plugins. The Claude side (.claude-plugin/marketplace.json) declares all 9 plugins, with the umbrella `cloudflare` plugin depending on the 8 product plugins so existing `/plugin install cloudflare@cloudflare` users keep working transparently. The Cursor side (.cursor-plugin/marketplace.json) declares only the 8 product plugins. Cursor's plugin system has no dependency mechanism, so the umbrella plugin doesn't translate; existing Cursor users will need to install the per-product plugins individually. Skill content, command files, rules, and MCP configs are still at the repo root and unchanged. Subsequent commits move them into the new plugin subtrees. Removes the now-stale root-level plugin.json files; multi-plugin marketplaces only need marketplace.json at the root. Refs cloudflare#50 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
All 8 skill directories relocate from skills/ at repo root into plugins/<plugin-name>/skills/. Skill content is unchanged; this is purely a packaging move so each skill ships under the appropriate product plugin: skills/cloudflare -> plugins/cloudflare-core skills/wrangler -> plugins/cloudflare-workers skills/workers-best-practices -> plugins/cloudflare-workers skills/durable-objects -> plugins/cloudflare-durable-objects skills/agents-sdk -> plugins/cloudflare-agents skills/sandbox-sdk -> plugins/cloudflare-sandbox skills/cloudflare-email-service -> plugins/cloudflare-email skills/web-perf -> plugins/cloudflare-web-perf Refs cloudflare#50 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Both slash commands directly invoke the agents-sdk skill, so they relocate alongside it under plugins/cloudflare-agents/commands/. Refs cloudflare#50 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Workers-scoped Cursor rule (alwaysApply with .ts/.js/wrangler glob matchers) relocates into plugins/cloudflare-workers/rules/. Cursor discovers rules at <plugin-root>/rules/ the same way it discovers skills at <plugin-root>/skills/. Refs cloudflare#50 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The 5 MCP servers previously declared at the repo root are now split across the three plugins that own them: cloudflare-api, cloudflare-docs -> cloudflare-core cloudflare-bindings, cloudflare-builds -> cloudflare-workers cloudflare-observability -> cloudflare-observability The per-plugin .mcp.json files were added in the scaffolding commit; this removes the now-redundant root file. Refs cloudflare#50 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Documents the 9-plugin Claude / 8-plugin Cursor partition, both install paths (umbrella for full experience, per-product for narrower scope), and which plugin owns each skill, MCP server, and command. The ``/plugin install cloudflare@cloudflare`` command continues to work and gives users the same content as before via the umbrella plugin's dependencies. Users who want lower per-session token usage can install only the product plugins they need. Cursor users get a brief migration note since the monolithic ``cloudflare`` Cursor plugin entry has been removed (Cursor's plugin system has no dependency mechanism, so the umbrella pattern doesn't translate). Refs cloudflare#50 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The split-into-product-plugins refactor removed the root cloudflare Cursor plugin, which would orphan existing cloudflare@cloudflare Cursor installs (no skills, no MCP servers — silent breakage). Restore the root cloudflare plugin while keeping the canonical content under plugins/<product>/ by using inverted symlinks: - skills/<X>, commands/<X>, rules/<X>: 11 symlinks pointing into plugins/<product>/. The Cursor cloudflare plugin (rooted at ./) resolves content through these. Claude never scans the repo root, so the Claude umbrella plugin is unaffected. - .cursor-plugin/plugin.json: restored verbatim from upstream. - .mcp.json: hand-merged from the 3 product .mcp.json files (5 servers, identical content + ordering to upstream pre-PR). - .cursor-plugin/marketplace.json: re-add cloudflare → ./ entry alongside the 8 per-product entries. - README: document the inverted-symlink layout, the hand-maintained root .mcp.json, and the Cursor monolith install option. Empirically validated: Cursor's git-clone-based install pipeline preserves internal symlinks (Cursor 3.3.27 against a throwaway repo on 2026-05-09), and git's rename detection auto-merges upstream edits to moved files even with a co-located symlink ADD at the original parent path (verified on two scratch repos at /tmp). Rationale and architecture: pape-docs/0003 (local-only, not in PR diff). Closes the gap pape-docs/0002 flagged.
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
Splits the monolithic
cloudflareplugin into 9 plugins (8 product plugins + 1 umbrella) per the request in #50. Existing users keep working transparently — on Claude Code via the umbrella's plugin dependencies, on Cursor via an inverted-symlink layout that keeps the rootcloudflareplugin functional. Users who want narrower scope and lower per-session token usage can install only the per-product plugins they need.What changed
The marketplace ships these plugins (canonical content under
plugins/<plugin-name>/):cloudflare-corecloudflarecloudflare-api,cloudflare-docscloudflare-workerswrangler,workers-best-practicescloudflare-bindings,cloudflare-buildscloudflare-corecloudflare-observabilitycloudflare-observabilitycloudflare-workerscloudflare-durable-objectsdurable-objectscloudflare-workerscloudflare-agentsagents-sdk/build-agent,/build-mcpcloudflare-workerscloudflare-sandboxsandbox-sdkcloudflare-workerscloudflare-emailcloudflare-email-servicecloudflare-corecloudflare-web-perfweb-perfcloudflareEach MCP server lives in exactly one plugin. Other plugins reach those MCPs transitively via the dependency tree. (Verified empirically: Claude Code silently dedupes duplicate MCP server names across plugins, so duplicating servers across plugins is unsafe.)
No skill, command, or rule content has changed — all files are pure git renames into
plugins/<plugin-name>/. The only content additions are the new manifests.Cursor monolith continuity (inverted-symlink layout)
Cursor's plugin system has no plugin-to-plugin dependency mechanism (verified against the Cursor docs and the
cursor/pluginsrepo — none of the 11 official plugins declare dependencies, and the Plugins Reference doesn't list adependenciesfield). The Claude umbrella pattern doesn't translate.To keep existing
cloudflare@cloudflareCursor installs working without forcing a migration, the repo root keeps a thin "Cursor monolith" plugin layout that resolves into the per-product plugins via symlinks:skills/<X>→../plugins/<product>/skills/<X>(8 skill symlinks)commands/<X>.md→../plugins/<product>/commands/<X>.md(2 command symlinks)rules/workers.mdc→../plugins/cloudflare-workers/rules/workers.mdc(1 rule symlink).cursor-plugin/plugin.json— the Cursor monolith manifest (unchanged from upstream).cursor-plugin/marketplace.json— re-addscloudflare→./alongside the 8 per-product entries.mcp.json— hand-merged from the 3 product.mcp.jsonfiles (5 servers, identical to upstream pre-PR)Symlinks point inside the Cursor monolith plugin's source dir (
./), satisfying the empirically-verified "internal symlinks are preserved throughgit clone" constraint. Claude Code never scans the repo root, so the Claude umbrella plugin (deps-only atplugins/cloudflare/) is unaffected — content is loaded once via the per-product plugins, not twice.The root
.mcp.jsonis hand-maintained: when a product's.mcp.jsonchanges, the root file needs to be updated to match. The README's "Repository layout" section documents this for contributors.Migration: Claude Code (smooth)
The new
cloudflareumbrella plugin depends on all 8 product plugins. Existing users running/plugin install cloudflare@cloudflareget the same content as before, transparently — Claude Code auto-installs the 8 dependencies. No user action required.Users who want lower per-session token usage can uninstall the umbrella and install only the product plugins they need:
Installing
cloudflare-workersautomatically pulls incloudflare-corevia the dep graph.Migration: Cursor (smooth)
Existing Cursor users with the
cloudflaremonolith plugin keep working — same skills, same MCP servers, same install path. No user action required.Users who want narrower scope can install per-product Cursor plugins from the same marketplace. Note that without dependency resolution, each Cursor plugin ships only its own MCP servers — installing only
cloudflare-workersgivescloudflare-bindingsandcloudflare-buildsbut notcloudflare-api/cloudflare-docs/cloudflare-observability. Users who want the full MCP surface should keep thecloudflareumbrella.Verification
claude plugin validate.claude plugin install cloudflare@cloudflare→ installs umbrella + auto-installs 8 dependencies.claude plugin install cloudflare-workers@cloudflare(without the umbrella) → installs onlycloudflare-workers+cloudflare-core(transitive).plugin:cloudflare-core:cloudflare-api, etc.).git clone --depth 1of this branch produces a working tree where the 11 root symlinks are intact (mode-120000), and Cursor's runtime loader follows them when scanning<plugin-root>/skills/*/.Open questions for maintainers
.mcp.jsonvsmcp.jsonfor Cursor. The repo uses.mcp.json(Claude Code convention). Cursor's plugin docs documentmcp.json(no leading dot) as the auto-discovery filename. Today the repo uses.mcp.jsonand apparently works for both ecosystems, but if Cursor's auto-discovery actually needsmcp.jsonfor plugin-scoped configs, please let me know and I'll either rename the files or add an explicitmcpServers: "./.mcp.json"to each Cursor manifest.plugin.jsonreferenceslogo.svgat the repo root, which still works (the file is present). Per-product Cursor plugins don't reference a logo because plugin source paths can't reach files outside the plugin's own directory after install. Happy to duplicatelogo.svginto each plugin if branding consistency matters..mcp.json. The 5 server entries are duplicated between the root file and the 3 product.mcp.jsonfiles. Tolerable as long as MCP server adds/removes are infrequent. A future PR could add a CI check that asserts the union matches the root if drift becomes a concern.Test plan
.mcp.jsonfilename works for Cursor plugin auto-discovery (or asks formcp.json).cloudflare-workers, confirm transitivecloudflare-coreinstall and that observability MCP is NOT loaded.cloudflareumbrella, confirm all 8 skills + 5 MCP servers load (matches pre-PR behavior).Closes #50
🤖 Generated with Claude Code