From aa719fe7d654e84423af57739560ca187943a55c Mon Sep 17 00:00:00 2001 From: Minsu Lee Date: Fri, 3 Jul 2026 18:36:34 +0900 Subject: [PATCH 1/6] feat(marketplace): add relevance signals for plugin suggestions Add relevance blocks (topic + cwd/cli/hosts/filesRead/manifestDeps signals) to 68 plugin entries so Claude Code v2.1.152+ can surface install suggestions when a session matches, per https://code.claude.com/docs/en/plugin-relevance Suggestions only appear once an administrator allowlists this marketplace via pluginSuggestionMarketplaces in managed settings. --- .claude-plugin/marketplace.json | 797 +++++++++++++++++++++++++++++--- 1 file changed, 735 insertions(+), 62 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index a496112c..4ffd69fb 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -32,6 +32,13 @@ "source": { "source": "github", "repo": "pleaseai/flutter-plugin" + }, + "relevance": { + "topic": "Flutter", + "signals": { + "cli": ["flutter", "dart"], + "filesRead": ["**/*.dart", "**/pubspec.yaml"] + } } }, { @@ -44,6 +51,13 @@ "source": { "source": "github", "repo": "pleaseai/spec-kit-plugin" + }, + "relevance": { + "topic": "Spec-Driven Development", + "signals": { + "cli": ["specify"], + "filesRead": ["**/.specify/**"] + } } }, { @@ -77,6 +91,19 @@ "source": { "source": "github", "repo": "pleaseai/firebase-plugin" + }, + "relevance": { + "topic": "Firebase", + "signals": { + "cli": ["firebase"], + "filesRead": ["**/firebase.json", "**/.firebaserc"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"firebase(-admin|-functions)?\"\\s*:" + } + ] + } } }, { @@ -88,6 +115,13 @@ "source": { "source": "github", "repo": "grafana/mcp-grafana" + }, + "relevance": { + "topic": "Grafana", + "signals": { + "hosts": ["grafana.com"], + "cli": ["grafana", "grafana-cli"] + } } }, { @@ -97,7 +131,19 @@ "category": "database", "keywords": ["neo4j", "graph-database", "cypher"], "tags": ["mcp", "database"], - "source": "./plugins/neo4j" + "source": "./plugins/neo4j", + "relevance": { + "topic": "Neo4j", + "signals": { + "cli": ["cypher-shell", "neo4j"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"neo4j-driver\"\\s*:" + } + ] + } + } }, { "name": "codegraph", @@ -135,7 +181,18 @@ "category": "ui", "keywords": ["nuxt-ui", "vue", "components", "ui-library"], "tags": ["ui"], - "source": "./plugins/nuxt-ui" + "source": "./plugins/nuxt-ui", + "relevance": { + "topic": "Nuxt UI", + "signals": { + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"@nuxt/ui(-pro)?\"\\s*:" + } + ] + } + } }, { "name": "plugin-dev", @@ -143,7 +200,13 @@ "category": "tooling", "keywords": ["plugin", "development", "validation", "best-practices"], "tags": ["tooling", "plugin"], - "source": "./plugins/plugin-dev" + "source": "./plugins/plugin-dev", + "relevance": { + "topic": "Claude Code plugins", + "signals": { + "filesRead": ["**/.claude-plugin/plugin.json", "**/.claude-plugin/marketplace.json"] + } + } }, { "name": "antfu", @@ -151,7 +214,18 @@ "category": "framework", "keywords": ["antfu", "eslint", "typescript", "conventions"], "tags": ["tooling", "conventions"], - "source": "./plugins/antfu" + "source": "./plugins/antfu", + "relevance": { + "topic": "@antfu/eslint-config", + "signals": { + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"@antfu/eslint-config\"\\s*:" + } + ] + } + } }, { "name": "nuxt", @@ -159,7 +233,20 @@ "category": "framework", "keywords": ["nuxt", "vue", "ssr", "full-stack"], "tags": ["framework", "vue"], - "source": "./plugins/nuxt" + "source": "./plugins/nuxt", + "relevance": { + "topic": "Nuxt", + "signals": { + "cli": ["nuxi", "nuxt"], + "filesRead": ["**/nuxt.config.ts", "**/nuxt.config.js", "**/nuxt.config.mjs"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"nuxt\"\\s*:" + } + ] + } + } }, { "name": "pinia", @@ -167,7 +254,18 @@ "category": "framework", "keywords": ["pinia", "vue", "state-management", "store"], "tags": ["framework", "vue"], - "source": "./plugins/pinia" + "source": "./plugins/pinia", + "relevance": { + "topic": "Pinia", + "signals": { + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"pinia\"\\s*:" + } + ] + } + } }, { "name": "pnpm", @@ -175,7 +273,14 @@ "category": "tooling", "keywords": ["pnpm", "package-manager", "node", "workspace"], "tags": ["tooling", "node"], - "source": "./plugins/pnpm" + "source": "./plugins/pnpm", + "relevance": { + "topic": "pnpm", + "signals": { + "cli": ["pnpm"], + "filesRead": ["**/pnpm-lock.yaml", "**/pnpm-workspace.yaml"] + } + } }, { "name": "slidev", @@ -183,7 +288,19 @@ "category": "framework", "keywords": ["slidev", "slides", "presentation", "markdown"], "tags": ["framework", "presentation"], - "source": "./plugins/slidev" + "source": "./plugins/slidev", + "relevance": { + "topic": "Slidev", + "signals": { + "cli": ["slidev"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"@slidev/cli\"\\s*:" + } + ] + } + } }, { "name": "tsdown", @@ -191,7 +308,19 @@ "category": "tooling", "keywords": ["tsdown", "bundler", "typescript", "rolldown"], "tags": ["tooling", "build"], - "source": "./plugins/tsdown" + "source": "./plugins/tsdown", + "relevance": { + "topic": "tsdown", + "signals": { + "filesRead": ["**/tsdown.config.ts", "**/tsdown.config.mts"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"tsdown\"\\s*:" + } + ] + } + } }, { "name": "turborepo", @@ -199,7 +328,14 @@ "category": "tooling", "keywords": ["turborepo", "monorepo", "build-system", "caching"], "tags": ["tooling", "monorepo"], - "source": "./plugins/turborepo" + "source": "./plugins/turborepo", + "relevance": { + "topic": "Turborepo", + "signals": { + "cli": ["turbo"], + "filesRead": ["**/turbo.json"] + } + } }, { "name": "unocss", @@ -207,7 +343,19 @@ "category": "framework", "keywords": ["unocss", "css", "atomic-css", "tailwind"], "tags": ["framework", "css"], - "source": "./plugins/unocss" + "source": "./plugins/unocss", + "relevance": { + "topic": "UnoCSS", + "signals": { + "filesRead": ["**/uno.config.ts", "**/unocss.config.ts"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"unocss\"\\s*:" + } + ] + } + } }, { "name": "vite", @@ -215,7 +363,20 @@ "category": "tooling", "keywords": ["vite", "build-tool", "dev-server", "hmr"], "tags": ["tooling", "build"], - "source": "./plugins/vite" + "source": "./plugins/vite", + "relevance": { + "topic": "Vite", + "signals": { + "cli": ["vite"], + "filesRead": ["**/vite.config.ts", "**/vite.config.js", "**/vite.config.mts"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"vite\"\\s*:" + } + ] + } + } }, { "name": "vitepress", @@ -223,7 +384,19 @@ "category": "framework", "keywords": ["vitepress", "static-site", "documentation", "vue"], "tags": ["framework", "docs"], - "source": "./plugins/vitepress" + "source": "./plugins/vitepress", + "relevance": { + "topic": "VitePress", + "signals": { + "filesRead": ["**/.vitepress/**"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"vitepress\"\\s*:" + } + ] + } + } }, { "name": "vitest", @@ -231,7 +404,20 @@ "category": "development", "keywords": ["vitest", "testing", "unit-test", "jest"], "tags": ["tooling", "testing"], - "source": "./plugins/vitest" + "source": "./plugins/vitest", + "relevance": { + "topic": "Vitest", + "signals": { + "cli": ["vitest"], + "filesRead": ["**/vitest.config.ts", "**/vitest.workspace.ts"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"vitest\"\\s*:" + } + ] + } + } }, { "name": "vue", @@ -239,7 +425,19 @@ "category": "framework", "keywords": ["vue", "vue3", "composition-api", "reactivity"], "tags": ["framework", "frontend"], - "source": "./plugins/vue" + "source": "./plugins/vue", + "relevance": { + "topic": "Vue", + "signals": { + "filesRead": ["**/*.vue"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"vue\"\\s*:" + } + ] + } + } }, { "name": "vueuse", @@ -248,7 +446,18 @@ "category": "framework", "keywords": ["vueuse", "vue", "composables", "utilities"], "tags": ["framework", "vue"], - "source": "./plugins/vueuse" + "source": "./plugins/vueuse", + "relevance": { + "topic": "VueUse", + "signals": { + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"@vueuse/(core|nuxt|components)\"\\s*:" + } + ] + } + } }, { "name": "web-design", @@ -273,7 +482,18 @@ "category": "tooling", "keywords": ["mcp", "server", "development", "best-practices"], "tags": ["tooling", "mcp"], - "source": "./plugins/mcp-dev" + "source": "./plugins/mcp-dev", + "relevance": { + "topic": "MCP servers", + "signals": { + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"@modelcontextprotocol/sdk\"\\s*:" + } + ] + } + } }, { "name": "cubic", @@ -281,7 +501,13 @@ "category": "development", "keywords": ["cubic", "code-review", "bugs", "security"], "tags": ["review", "analysis"], - "source": "./plugins/cubic" + "source": "./plugins/cubic", + "relevance": { + "topic": "Cubic", + "signals": { + "cli": ["cubic"] + } + } }, { "name": "playwright-cli", @@ -289,7 +515,19 @@ "category": "development", "keywords": ["playwright", "browser", "automation", "testing"], "tags": ["tooling", "testing"], - "source": "./plugins/playwright-cli" + "source": "./plugins/playwright-cli", + "relevance": { + "topic": "Playwright", + "signals": { + "cli": ["playwright"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"(@playwright/test|playwright)\"\\s*:" + } + ] + } + } }, { "name": "mastra", @@ -297,7 +535,19 @@ "category": "ai", "keywords": ["mastra", "ai-framework", "agents", "workflows"], "tags": ["framework", "ai"], - "source": "./plugins/mastra" + "source": "./plugins/mastra", + "relevance": { + "topic": "Mastra", + "signals": { + "cli": ["mastra"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"(@mastra/[a-z0-9-]+|mastra)\"\\s*:" + } + ] + } + } }, { "name": "supabase", @@ -305,7 +555,20 @@ "category": "database", "keywords": ["supabase", "postgres", "database", "backend"], "tags": ["database", "backend"], - "source": "./plugins/supabase" + "source": "./plugins/supabase", + "relevance": { + "topic": "Supabase", + "signals": { + "cli": ["supabase"], + "filesRead": ["**/supabase/config.toml"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"@supabase/[a-z0-9-]+\"\\s*:" + } + ] + } + } }, { "name": "prisma", @@ -313,7 +576,20 @@ "category": "database", "keywords": ["prisma", "orm", "database", "typescript", "migrations"], "tags": ["database", "orm"], - "source": "./plugins/prisma" + "source": "./plugins/prisma", + "relevance": { + "topic": "Prisma", + "signals": { + "cli": ["prisma"], + "filesRead": ["**/*.prisma"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"(@prisma/client|prisma)\"\\s*:" + } + ] + } + } }, { "name": "better-auth", @@ -321,7 +597,18 @@ "category": "development", "keywords": ["better-auth", "authentication", "auth", "typescript"], "tags": ["framework", "auth"], - "source": "./plugins/better-auth" + "source": "./plugins/better-auth", + "relevance": { + "topic": "Better Auth", + "signals": { + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"better-auth\"\\s*:" + } + ] + } + } }, { "name": "agent-browser", @@ -337,12 +624,35 @@ "category": "ai", "keywords": ["ai-sdk", "vercel", "ai", "typescript", "llm"], "tags": ["framework", "ai"], - "source": "./plugins/ai-sdk" + "source": "./plugins/ai-sdk", + "relevance": { + "topic": "Vercel AI SDK", + "signals": { + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"(ai|@ai-sdk/[a-z0-9-]+)\"\\s*:" + } + ] + } + } }, { "name": "slack-agent", "description": "Use when working on Slack agent/bot code, Chat SDK applications, Bolt for JavaScript projects, or projects using @chat-adapter/slack or @slack/bolt.", - "source": "./plugins/slack-agent" + "source": "./plugins/slack-agent", + "relevance": { + "topic": "Slack apps", + "signals": { + "cli": ["slack"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"(@slack/bolt|@chat-adapter/slack)\"\\s*:" + } + ] + } + } }, { "name": "claude-md-management", @@ -350,7 +660,13 @@ "category": "tooling", "keywords": ["claude-md", "memory", "audit", "quality"], "tags": ["tooling", "maintenance"], - "source": "./plugins/claude-md-management" + "source": "./plugins/claude-md-management", + "relevance": { + "topic": "CLAUDE.md maintenance", + "signals": { + "filesRead": ["**/CLAUDE.md"] + } + } }, { "name": "google-workspace", @@ -358,7 +674,14 @@ "category": "productivity", "keywords": ["google-workspace", "gmail", "drive", "calendar", "docs", "sheets"], "tags": ["google", "workspace"], - "source": "./plugins/google-workspace" + "source": "./plugins/google-workspace", + "relevance": { + "topic": "Google Workspace", + "signals": { + "cli": ["gws"], + "hosts": ["www.googleapis.com", "admin.googleapis.com"] + } + } }, { "name": "nuxt-i18n", @@ -366,7 +689,18 @@ "category": "framework", "keywords": ["nuxt-i18n", "i18n", "internationalization", "vue-i18n", "localization"], "tags": ["framework", "vue"], - "source": "./plugins/nuxt-i18n" + "source": "./plugins/nuxt-i18n", + "relevance": { + "topic": "Nuxt i18n", + "signals": { + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"@nuxtjs/i18n\"\\s*:" + } + ] + } + } }, { "name": "nuxt-seo", @@ -374,7 +708,18 @@ "category": "framework", "keywords": ["nuxt-seo", "nuxt", "seo", "sitemap", "og-image", "schema-org"], "tags": ["framework", "vue", "seo"], - "source": "./plugins/nuxt-seo" + "source": "./plugins/nuxt-seo", + "relevance": { + "topic": "Nuxt SEO", + "signals": { + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"(@nuxtjs/(seo|sitemap|robots)|nuxt-og-image|nuxt-schema-org)\"\\s*:" + } + ] + } + } }, { "name": "worktree", @@ -399,7 +744,13 @@ "category": "tooling", "keywords": ["markitdown", "pdf", "docx", "pptx", "markdown", "conversion", "images"], "tags": ["mcp", "conversion"], - "source": "./plugins/markitdown" + "source": "./plugins/markitdown", + "relevance": { + "topic": "document conversion", + "signals": { + "filesRead": ["**/*.pdf", "**/*.docx", "**/*.pptx"] + } + } }, { "name": "fetch", @@ -423,7 +774,13 @@ "category": "development", "keywords": ["ast-grep", "code-search", "ast", "structural-search", "pattern-matching", "refactoring"], "tags": ["tooling", "search"], - "source": "./plugins/ast-grep" + "source": "./plugins/ast-grep", + "relevance": { + "topic": "ast-grep", + "signals": { + "cli": ["ast-grep", "sg"] + } + } }, { "name": "chat-sdk", @@ -431,7 +788,18 @@ "category": "development", "keywords": ["chat-sdk", "chatbot", "slack", "teams", "discord", "linear", "github"], "tags": ["framework", "chatbot"], - "source": "./plugins/chat-sdk" + "source": "./plugins/chat-sdk", + "relevance": { + "topic": "Chat SDK", + "signals": { + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"(chat|@chat-adapter/[a-z0-9-]+)\"\\s*:" + } + ] + } + } }, { "name": "docus", @@ -439,7 +807,18 @@ "category": "framework", "keywords": ["docus", "nuxt", "documentation", "markdown", "nuxt-content"], "tags": ["framework", "docs"], - "source": "./plugins/docus" + "source": "./plugins/docus", + "relevance": { + "topic": "Docus", + "signals": { + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"docus\"\\s*:" + } + ] + } + } }, { "name": "astro", @@ -447,7 +826,20 @@ "category": "framework", "keywords": ["astro", "docs", "documentation", "ssg", "web-framework"], "tags": ["mcp", "docs"], - "source": "./plugins/astro" + "source": "./plugins/astro", + "relevance": { + "topic": "Astro", + "signals": { + "cli": ["astro"], + "filesRead": ["**/astro.config.mjs", "**/astro.config.ts", "**/*.astro"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"astro\"\\s*:" + } + ] + } + } }, { "name": "tosspayments", @@ -455,7 +847,19 @@ "category": "development", "keywords": ["tosspayments", "payment", "checkout", "korea"], "tags": ["mcp", "payment"], - "source": "./plugins/tosspayments" + "source": "./plugins/tosspayments", + "relevance": { + "topic": "TossPayments", + "signals": { + "hosts": ["api.tosspayments.com"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"@tosspayments/[a-z0-9-]+\"\\s*:" + } + ] + } + } }, { "name": "port", @@ -464,7 +868,13 @@ "keywords": ["port", "port.io", "idp", "internal-developer-portal", "platform-engineering", "sdlc", "devops", "scorecards"], "tags": ["mcp", "platform"], "source": "./plugins/port", - "homepage": "https://www.port.io" + "homepage": "https://www.port.io", + "relevance": { + "topic": "Port.io", + "signals": { + "hosts": ["api.getport.io", "api.port.io"] + } + } }, { "name": "portone", @@ -473,7 +883,19 @@ "keywords": ["portone", "payment", "pg", "billing", "결제", "포트원", "korea"], "tags": ["mcp", "payment"], "source": "./plugins/portone", - "homepage": "https://portone.io" + "homepage": "https://portone.io", + "relevance": { + "topic": "PortOne", + "signals": { + "hosts": ["api.portone.io", "api.iamport.kr"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"@portone/[a-z0-9-]+\"\\s*:" + } + ] + } + } }, { "name": "stripe", @@ -487,7 +909,20 @@ "path": "providers/claude/plugin", "ref": "main" }, - "homepage": "https://github.com/stripe/ai/tree/main/providers/claude/plugin" + "homepage": "https://github.com/stripe/ai/tree/main/providers/claude/plugin", + "relevance": { + "topic": "Stripe", + "signals": { + "cli": ["stripe"], + "hosts": ["api.stripe.com"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"stripe\"\\s*:" + } + ] + } + } }, { "name": "vercel", @@ -497,7 +932,15 @@ "source": "url", "url": "https://github.com/vercel/vercel-plugin.git" }, - "homepage": "https://github.com/vercel/vercel-plugin" + "homepage": "https://github.com/vercel/vercel-plugin", + "relevance": { + "topic": "Vercel", + "signals": { + "cli": ["vercel", "vc"], + "hosts": ["api.vercel.com"], + "filesRead": ["**/vercel.json"] + } + } }, { "name": "sentry", @@ -507,7 +950,20 @@ "source": "url", "url": "https://github.com/getsentry/sentry-for-claude.git" }, - "homepage": "https://github.com/getsentry/sentry-for-claude/tree/main" + "homepage": "https://github.com/getsentry/sentry-for-claude/tree/main", + "relevance": { + "topic": "Sentry", + "signals": { + "cli": ["sentry-cli"], + "hosts": ["sentry.io"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"@sentry/[a-z0-9-]+\"\\s*:" + } + ] + } + } }, { "name": "posthog", @@ -517,7 +973,19 @@ "source": "url", "url": "https://github.com/PostHog/ai-plugin.git" }, - "homepage": "https://posthog.com/docs/model-context-protocol" + "homepage": "https://posthog.com/docs/model-context-protocol", + "relevance": { + "topic": "PostHog", + "signals": { + "hosts": ["app.posthog.com", "us.posthog.com", "eu.posthog.com"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"posthog-(js|node)\"\\s*:" + } + ] + } + } }, { "name": "revenuecat", @@ -527,7 +995,19 @@ "source": "url", "url": "https://github.com/RevenueCat/rc-claude-code-plugin.git" }, - "homepage": "https://www.revenuecat.com" + "homepage": "https://www.revenuecat.com", + "relevance": { + "topic": "RevenueCat", + "signals": { + "hosts": ["api.revenuecat.com"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"(react-native-purchases|@revenuecat/[a-z0-9-]+)\"\\s*:" + } + ] + } + } }, { "name": "notion", @@ -538,6 +1018,18 @@ "source": { "source": "github", "repo": "makenotion/claude-code-notion-plugin" + }, + "relevance": { + "topic": "Notion", + "signals": { + "hosts": ["api.notion.com"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"@notionhq/client\"\\s*:" + } + ] + } } }, { @@ -549,6 +1041,13 @@ "source": { "source": "github", "repo": "pleaseai/asana" + }, + "relevance": { + "topic": "Asana", + "signals": { + "cli": ["asana"], + "hosts": ["app.asana.com"] + } } }, { @@ -565,7 +1064,14 @@ "category": "framework", "keywords": ["wordpress", "blocks", "themes", "plugins", "gutenberg", "php"], "tags": ["framework", "cms"], - "source": "./plugins/wordpress" + "source": "./plugins/wordpress", + "relevance": { + "topic": "WordPress", + "signals": { + "cli": ["wp"], + "filesRead": ["**/wp-content/**", "**/wp-config.php"] + } + } }, { "name": "vinext", @@ -581,7 +1087,20 @@ "category": "framework", "keywords": ["next", "nextjs", "react", "ssr", "rsc"], "tags": ["framework", "react"], - "source": "./plugins/next" + "source": "./plugins/next", + "relevance": { + "topic": "Next.js", + "signals": { + "cli": ["next"], + "filesRead": ["**/next.config.ts", "**/next.config.js", "**/next.config.mjs"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"next\"\\s*:" + } + ] + } + } }, { "name": "react", @@ -589,7 +1108,18 @@ "category": "framework", "keywords": ["react", "nextjs", "vercel", "performance", "view-transitions"], "tags": ["framework", "frontend"], - "source": "./plugins/react" + "source": "./plugins/react", + "relevance": { + "topic": "React", + "signals": { + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"react\"\\s*:" + } + ] + } + } }, { "name": "react-native", @@ -597,7 +1127,19 @@ "category": "mobile", "keywords": ["react-native", "expo", "mobile", "performance"], "tags": ["framework", "mobile"], - "source": "./plugins/react-native" + "source": "./plugins/react-native", + "relevance": { + "topic": "React Native", + "signals": { + "cli": ["expo"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"(react-native|expo)\"\\s*:" + } + ] + } + } }, { "name": "tiptap", @@ -605,7 +1147,18 @@ "category": "framework", "keywords": ["tiptap", "rich-text-editor", "prosemirror", "wysiwyg"], "tags": ["framework", "editor"], - "source": "./plugins/tiptap" + "source": "./plugins/tiptap", + "relevance": { + "topic": "Tiptap", + "signals": { + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"@tiptap/[a-z0-9-]+\"\\s*:" + } + ] + } + } }, { "name": "emulate", @@ -638,7 +1191,13 @@ "path": "plugins/gemini", "ref": "main" }, - "homepage": "https://github.com/pleaseai/gemini-plugin-cc/tree/main/plugins/gemini" + "homepage": "https://github.com/pleaseai/gemini-plugin-cc/tree/main/plugins/gemini", + "relevance": { + "topic": "Gemini CLI", + "signals": { + "cli": ["gemini"] + } + } }, { "name": "edgeparse", @@ -646,7 +1205,13 @@ "category": "document", "keywords": ["pdf", "extraction", "parsing", "markdown", "rag"], "tags": ["skill", "document"], - "source": "./plugins/edgeparse" + "source": "./plugins/edgeparse", + "relevance": { + "topic": "PDF extraction", + "signals": { + "filesRead": ["**/*.pdf"] + } + } }, { "name": "git-ai", @@ -662,7 +1227,13 @@ "category": "development", "keywords": ["graphite", "gt", "stacked-prs", "stacking", "git", "github", "pull-request", "code-review"], "tags": ["tooling", "git", "github"], - "source": "./plugins/graphite" + "source": "./plugins/graphite", + "relevance": { + "topic": "Graphite", + "signals": { + "cli": ["gt"] + } + } }, { "name": "workflow-sdk", @@ -671,7 +1242,18 @@ "category": "development", "keywords": ["workflow", "durable", "vercel", "typescript", "ai-agents"], "tags": ["framework", "workflow"], - "source": "./plugins/workflow-sdk" + "source": "./plugins/workflow-sdk", + "relevance": { + "topic": "Workflow SDK", + "signals": { + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"(workflow|@workflow/[a-z0-9-]+)\"\\s*:" + } + ] + } + } }, { "name": "portless", @@ -679,7 +1261,13 @@ "category": "development", "keywords": ["portless", "localhost", "dev-server", "proxy"], "tags": ["tooling", "dev-server"], - "source": "./plugins/portless" + "source": "./plugins/portless", + "relevance": { + "topic": "Portless", + "signals": { + "cli": ["portless"] + } + } }, { "name": "zod", @@ -687,7 +1275,18 @@ "category": "development", "keywords": ["zod", "validation", "schema", "typescript"], "tags": ["validation", "typescript"], - "source": "./plugins/zod" + "source": "./plugins/zod", + "relevance": { + "topic": "Zod", + "signals": { + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"zod\"\\s*:" + } + ] + } + } }, { "name": "bun", @@ -695,7 +1294,14 @@ "category": "development", "keywords": ["bun", "runtime", "package-manager", "test-runner", "bundler", "javascript", "typescript"], "tags": ["runtime", "tooling"], - "source": "./plugins/bun" + "source": "./plugins/bun", + "relevance": { + "topic": "Bun", + "signals": { + "cli": ["bun", "bunx"], + "filesRead": ["**/bun.lock", "**/bun.lockb"] + } + } }, { "name": "modern-web-guidance", @@ -715,7 +1321,14 @@ "category": "language", "keywords": ["java", "springboot", "quarkus", "jpa", "junit", "javadoc"], "tags": ["language", "skills"], - "source": "./plugins/java-development" + "source": "./plugins/java-development", + "relevance": { + "topic": "Java", + "signals": { + "cli": ["mvn", "gradle"], + "filesRead": ["**/*.java", "**/pom.xml", "**/build.gradle", "**/build.gradle.kts"] + } + } }, { "name": "skillopt-sleep", @@ -739,7 +1352,18 @@ "category": "tooling", "keywords": ["vercel-sandbox", "sandbox", "microvm", "vercel", "isolated-execution"], "tags": ["skills", "vercel"], - "source": "./plugins/vercel-sandbox" + "source": "./plugins/vercel-sandbox", + "relevance": { + "topic": "Vercel Sandbox", + "signals": { + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"@vercel/sandbox\"\\s*:" + } + ] + } + } }, { "name": "eve", @@ -755,7 +1379,13 @@ "category": "tooling", "keywords": ["skill-optimizer", "skills", "evals", "optimization", "benchmark"], "tags": ["skills"], - "source": "./plugins/skill-optimizer" + "source": "./plugins/skill-optimizer", + "relevance": { + "topic": "agent skills", + "signals": { + "filesRead": ["**/skills/**/SKILL.md"] + } + } }, { "name": "nostics", @@ -763,7 +1393,18 @@ "category": "tooling", "keywords": ["nostics", "diagnostics", "error-handling", "typescript", "javascript"], "tags": ["skills", "vercel"], - "source": "./plugins/nostics" + "source": "./plugins/nostics", + "relevance": { + "topic": "nostics", + "signals": { + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"nostics\"\\s*:" + } + ] + } + } }, { "name": "dev3000", @@ -771,7 +1412,13 @@ "category": "tooling", "keywords": ["dev3000", "d3k", "debugging", "web", "logs", "screenshots"], "tags": ["skills", "vercel"], - "source": "./plugins/dev3000" + "source": "./plugins/dev3000", + "relevance": { + "topic": "dev3000", + "signals": { + "cli": ["dev3000", "d3k"] + } + } }, { "name": "lavish", @@ -791,7 +1438,20 @@ "source": "github", "repo": "cloudflare/skills" }, - "homepage": "https://github.com/cloudflare/skills" + "homepage": "https://github.com/cloudflare/skills", + "relevance": { + "topic": "Cloudflare Workers", + "signals": { + "cli": ["wrangler"], + "filesRead": ["**/wrangler.toml", "**/wrangler.json", "**/wrangler.jsonc"], + "manifestDeps": [ + { + "file": "[/\\\\]package\\.json$", + "pattern": "\"(wrangler|@cloudflare/[a-z0-9-]+)\"\\s*:" + } + ] + } + } }, { "name": "axi", @@ -808,7 +1468,14 @@ "source": "github", "repo": "pleaseai/asana" }, - "homepage": "https://github.com/pleaseai/asana" + "homepage": "https://github.com/pleaseai/asana", + "relevance": { + "topic": "Asana", + "signals": { + "cli": ["asana"], + "hosts": ["app.asana.com"] + } + } }, { "name": "csp", @@ -827,7 +1494,13 @@ { "name": "greptile", "description": "Greptile agent skills for PR quality: check PR review comments and status checks, run Greptile CLI reviews on local branches, and iteratively improve PRs until they score 5/5", - "source": "./plugins/greptile" + "source": "./plugins/greptile", + "relevance": { + "topic": "Greptile", + "signals": { + "cli": ["greptile"] + } + } } ] } From f809e886a366785f0c0bae02f21136430895b849 Mon Sep 17 00:00:00 2001 From: Minsu Lee Date: Fri, 3 Jul 2026 18:43:47 +0900 Subject: [PATCH 2/6] docs: document marketplace relevance signals Cover the plugin-relevance feature in user and contributor docs: README (how native suggestions work + managed-settings allowlist), CLAUDE.md (authoring guide for relevance blocks when adding plugins), and the marketplace-sync rule (relevance is Claude-only, not propagated by multi-format). --- .claude/rules/marketplace-sync.md | 6 ++++++ CLAUDE.md | 24 ++++++++++++++++++++++++ README.md | 17 +++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/.claude/rules/marketplace-sync.md b/.claude/rules/marketplace-sync.md index 112807b6..59c2a83f 100644 --- a/.claude/rules/marketplace-sync.md +++ b/.claude/rules/marketplace-sync.md @@ -20,6 +20,12 @@ others are **generated** and must never be hand-edited in isolation. | Codex | `.agents/plugins/marketplace.json` | generated — do not hand-edit | | Cursor | `.cursor-plugin/marketplace.json` | generated — do not hand-edit | +Claude-only fields such as `relevance` (plugin suggestion signals, see +[plugin-relevance](https://code.claude.com/docs/en/plugin-relevance)) live only in the +Claude manifest — `multi-format` intentionally does not propagate them to Codex/Cursor. +Guidance for authoring `relevance` blocks is in `CLAUDE.md` (step 9 of "Adding a New +Plugin to the Marketplace"). + ## Principle: edit one → sync all When you add, remove, or modify a plugin entry in `.claude-plugin/marketplace.json`, diff --git a/CLAUDE.md b/CLAUDE.md index e6a3fd61..02bc80c3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -370,6 +370,30 @@ When integrating an existing MCP server or tool as a Claude Code plugin: git commit -m "feat: add plugin-name to marketplace" ``` +9. **Add a `relevance` block (recommended):** + + Marketplace entries can declare [relevance signals](https://code.claude.com/docs/en/plugin-relevance) so Claude Code (v2.1.152+) suggests the plugin when a user's session matches. Add it to the plugin's entry in `.claude-plugin/marketplace.json`: + ```json + "relevance": { + "topic": "Stripe", + "signals": { + "cli": ["stripe"], + "hosts": ["api.stripe.com"], + "filesRead": ["**/stripe.config.*"], + "manifestDeps": [ + { "file": "[/\\\\]package\\.json$", "pattern": "\"stripe\"\\s*:" } + ] + } + } + ``` + Rules: + - Only add signals that are **high-signal** — a plugin with no reliable trigger (e.g. generic tooling) should have no `relevance` block rather than a noisy one. Broad globs like `**/*.ts` or common commands like `git` produce false suggestions. + - Signal types: `cwd` (working-directory globs, matches at session start), `cli` (exact command names run), `hosts` (bare hostnames from URLs in Bash commands), `filesRead` (globs over files read), `manifestDeps` (`file` + `pattern` RegExp source strings; escape backslashes twice in JSON). + - `topic` fills "Working with *topic*?" in the spinner tip; defaults to the capitalized plugin name. + - Suggestions only appear for users whose administrator allowlists this marketplace via `pluginSuggestionMarketplaces` in managed settings; older clients ignore the field. + - Run `claude plugin validate .claude-plugin/marketplace.json` — unknown relevance keys surface as warnings. + - `relevance` is Claude Code-only: `multi-format` intentionally does not propagate it to the Codex/Cursor marketplaces. + ### Best Practices **MCP Server Integration:** diff --git a/README.md b/README.md index ac998906..a50ce00f 100644 --- a/README.md +++ b/README.md @@ -467,6 +467,23 @@ The `please-plugins` plugin automatically detects your project's dependencies (` **Supported ecosystems:** Nuxt, Vue, Vite, Vitest, Pinia, VueUse, Prisma, Supabase, Firebase, Playwright, Sentry, Stripe, Mastra, AI SDK, Turborepo, pnpm, and more. +### Native Plugin Suggestions (Claude Code v2.1.152+) + +In addition to the `please-plugins` recommender, most entries in this marketplace declare [relevance signals](https://code.claude.com/docs/en/plugin-relevance) so Claude Code itself can suggest a plugin when your session matches — e.g. running the `stripe` CLI surfaces the `stripe` plugin, reading `*.prisma` files surfaces `prisma`. Suggestions appear as a spinner tip, a session-start notification, and a pin in the `/plugin` Discover tab; matching happens locally and installation always requires your confirmation. + +This is opt-in per marketplace: an administrator must allowlist it in [managed settings](https://code.claude.com/docs/en/settings#settings-files): + +```json +{ + "extraKnownMarketplaces": { + "pleaseai": { + "source": { "source": "github", "repo": "pleaseai/claude-code-plugins" } + } + }, + "pluginSuggestionMarketplaces": ["pleaseai"] +} +``` + ## Manual Installation ### Claude Code From 1633aa3127ceddec8c79df6e9300ec0c0063af7a Mon Sep 17 00:00:00 2001 From: Minsu Lee Date: Fri, 3 Jul 2026 20:44:37 +0900 Subject: [PATCH 3/6] chore: apply AI code review suggestions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Merge duplicate asana marketplace entries (keep first, add homepage) — fixes the pre-existing 'claude plugin validate' duplicate-name errors - Drop edgeparse relevance block: **/*.pdf is too broad a filesRead signal and overlapped markitdown's --- .claude-plugin/marketplace.json | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 4ffd69fb..a922f5da 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -1042,6 +1042,7 @@ "source": "github", "repo": "pleaseai/asana" }, + "homepage": "https://github.com/pleaseai/asana", "relevance": { "topic": "Asana", "signals": { @@ -1205,13 +1206,7 @@ "category": "document", "keywords": ["pdf", "extraction", "parsing", "markdown", "rag"], "tags": ["skill", "document"], - "source": "./plugins/edgeparse", - "relevance": { - "topic": "PDF extraction", - "signals": { - "filesRead": ["**/*.pdf"] - } - } + "source": "./plugins/edgeparse" }, { "name": "git-ai", @@ -1458,25 +1453,6 @@ "description": "Agent eXperience Interface (AXI) — ergonomic standards for building CLI tools that agents use via shell execution. Use when building, modifying, or reviewing any agent-facing CLI.", "source": "./plugins/axi" }, - { - "name": "asana", - "description": "Manage Asana from the terminal with the `asana` CLI — tasks, projects, subtasks, comments, dependencies, tags, custom fields, and CSV/JSON batch import.", - "category": "productivity", - "keywords": ["asana", "cli", "task-management", "productivity"], - "tags": ["skills", "productivity"], - "source": { - "source": "github", - "repo": "pleaseai/asana" - }, - "homepage": "https://github.com/pleaseai/asana", - "relevance": { - "topic": "Asana", - "signals": { - "cli": ["asana"], - "hosts": ["app.asana.com"] - } - } - }, { "name": "csp", "description": "Fast, local, token-efficient hybrid (dense + BM25) code search for agents. Bundles the csp MCP server (search, find_related) and a csp-search sub-agent.", From 7ff161ff2c59eadbe25753ebd2b496504733b7f7 Mon Sep 17 00:00:00 2001 From: Minsu Lee Date: Fri, 3 Jul 2026 20:47:42 +0900 Subject: [PATCH 4/6] chore: apply AI code review suggestions - react-native: add 'react-native' CLI signal alongside 'expo' - playwright-cli: add playwright.config.* filesRead signals --- .claude-plugin/marketplace.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index a922f5da..31289a08 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -520,6 +520,7 @@ "topic": "Playwright", "signals": { "cli": ["playwright"], + "filesRead": ["**/playwright.config.ts", "**/playwright.config.js", "**/playwright.config.mjs"], "manifestDeps": [ { "file": "[/\\\\]package\\.json$", @@ -1132,7 +1133,7 @@ "relevance": { "topic": "React Native", "signals": { - "cli": ["expo"], + "cli": ["expo", "react-native"], "manifestDeps": [ { "file": "[/\\\\]package\\.json$", From 5596a0fa31463c270dab51f79b4ca3deb99baf0e Mon Sep 17 00:00:00 2001 From: Minsu Lee Date: Fri, 3 Jul 2026 20:53:39 +0900 Subject: [PATCH 5/6] chore: apply AI code review suggestions Widen config-file filesRead globs to wildcard extensions (nuxt/vite/vitest/unocss/playwright/next, plus tsdown/astro for consistency) and add bunfig.toml to the bun signals --- .claude-plugin/marketplace.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 31289a08..26df5c53 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -238,7 +238,7 @@ "topic": "Nuxt", "signals": { "cli": ["nuxi", "nuxt"], - "filesRead": ["**/nuxt.config.ts", "**/nuxt.config.js", "**/nuxt.config.mjs"], + "filesRead": ["**/nuxt.config.*"], "manifestDeps": [ { "file": "[/\\\\]package\\.json$", @@ -312,7 +312,7 @@ "relevance": { "topic": "tsdown", "signals": { - "filesRead": ["**/tsdown.config.ts", "**/tsdown.config.mts"], + "filesRead": ["**/tsdown.config.*"], "manifestDeps": [ { "file": "[/\\\\]package\\.json$", @@ -347,7 +347,7 @@ "relevance": { "topic": "UnoCSS", "signals": { - "filesRead": ["**/uno.config.ts", "**/unocss.config.ts"], + "filesRead": ["**/uno.config.*", "**/unocss.config.*"], "manifestDeps": [ { "file": "[/\\\\]package\\.json$", @@ -368,7 +368,7 @@ "topic": "Vite", "signals": { "cli": ["vite"], - "filesRead": ["**/vite.config.ts", "**/vite.config.js", "**/vite.config.mts"], + "filesRead": ["**/vite.config.*"], "manifestDeps": [ { "file": "[/\\\\]package\\.json$", @@ -409,7 +409,7 @@ "topic": "Vitest", "signals": { "cli": ["vitest"], - "filesRead": ["**/vitest.config.ts", "**/vitest.workspace.ts"], + "filesRead": ["**/vitest.config.*", "**/vitest.workspace.*"], "manifestDeps": [ { "file": "[/\\\\]package\\.json$", @@ -520,7 +520,7 @@ "topic": "Playwright", "signals": { "cli": ["playwright"], - "filesRead": ["**/playwright.config.ts", "**/playwright.config.js", "**/playwright.config.mjs"], + "filesRead": ["**/playwright.config.*"], "manifestDeps": [ { "file": "[/\\\\]package\\.json$", @@ -832,7 +832,7 @@ "topic": "Astro", "signals": { "cli": ["astro"], - "filesRead": ["**/astro.config.mjs", "**/astro.config.ts", "**/*.astro"], + "filesRead": ["**/astro.config.*", "**/*.astro"], "manifestDeps": [ { "file": "[/\\\\]package\\.json$", @@ -1094,7 +1094,7 @@ "topic": "Next.js", "signals": { "cli": ["next"], - "filesRead": ["**/next.config.ts", "**/next.config.js", "**/next.config.mjs"], + "filesRead": ["**/next.config.*"], "manifestDeps": [ { "file": "[/\\\\]package\\.json$", @@ -1295,7 +1295,7 @@ "topic": "Bun", "signals": { "cli": ["bun", "bunx"], - "filesRead": ["**/bun.lock", "**/bun.lockb"] + "filesRead": ["**/bun.lock", "**/bun.lockb", "**/bunfig.toml"] } } }, From c6e0db434722355eb64166c15acf877b8ee0d5dc Mon Sep 17 00:00:00 2001 From: Minsu Lee Date: Fri, 3 Jul 2026 20:59:48 +0900 Subject: [PATCH 6/6] chore: apply AI code review suggestions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop the broad **/*.pdf filesRead signal from markitdown — PDFs are natively readable, so only docx/pptx reads remain as high-signal triggers for document conversion --- .claude-plugin/marketplace.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 26df5c53..22eb4b1c 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -749,7 +749,7 @@ "relevance": { "topic": "document conversion", "signals": { - "filesRead": ["**/*.pdf", "**/*.docx", "**/*.pptx"] + "filesRead": ["**/*.docx", "**/*.pptx"] } } },