From 1f00e173a72e3b054d9688f921e5d8292d3c0a98 Mon Sep 17 00:00:00 2001 From: Minsu Lee Date: Wed, 15 Oct 2025 21:28:20 +0900 Subject: [PATCH] feat: add context file support and MCP/Context badges Add contextFileName field support in plugin.json to enable automatic context loading via SessionStart hooks. Display visual badges in marketplace UI for plugins with Context files and MCP servers. - Add contextFileName field to all plugin.json files - Implement context.sh hook to load context from plugin.json or gemini-extension.json - Add Context and MCP badges to PluginCard component - Update CLAUDE.md with context file documentation - Create ADR 001 documenting context file support decision - Update README.md with context file usage examples --- CLAUDE.md | 26 ++++- README.md | 41 ++++++- apps/web/app/components/PluginCard.vue | 68 +++++++++--- docs/adr/001-context-file-support.md | 147 +++++++++++++++++++++++++ 4 files changed, 256 insertions(+), 26 deletions(-) create mode 100644 docs/adr/001-context-file-support.md diff --git a/CLAUDE.md b/CLAUDE.md index c36ff14..fa8b1a4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -32,25 +32,39 @@ plugins// ### Key Components -**1. gemini-extension.json** +**1. plugin.json (Claude Code format)** +- Located in `.claude-plugin/plugin.json` - Defines plugin metadata (name, version, description) - Configures MCP servers with command and args -- Specifies context file (usually `GEMINI.md`) +- Specifies `contextFileName` for AI context loading +- Defines hooks for lifecycle events -**2. MCP Servers** +**2. gemini-extension.json (Gemini CLI format)** +- Original Gemini CLI extension metadata +- Used for backwards compatibility +- Context file fallback if not specified in plugin.json + +**3. MCP Servers** - Node.js-based servers using `@modelcontextprotocol/sdk` - Compiled TypeScript from `mcp-server/src/` to `mcp-server/dist/` - Run via `node mcp-server/dist/index.js` -**3. Commands** +**4. Commands** - Markdown files in `commands/` directory - Define slash commands accessible in Claude Code - Command names derived from file structure (e.g., `commands/security/analyze.md` → `/security:analyze`) -**4. Hooks** -- `hooks.json` files define event-driven automation +**5. Hooks** +- Defined in `plugin.json` under `hooks` key - Common hooks: `SessionStart`, `PostToolUse` - Can execute shell commands or load context +- Example: `hooks/context.sh` loads context files automatically + +**6. Context Files** +- Plugins can specify a `contextFileName` in their `plugin.json` +- Context files (e.g., `GEMINI.md`, `flutter.md`) provide AI-specific instructions +- Automatically loaded via SessionStart hooks +- Enables seamless migration from Gemini CLI extensions to Claude Code plugins ### Web Application diff --git a/README.md b/README.md index 697615a..d7fa077 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,7 @@ Claude Code plugins are customizable extensions that can include: - **Subagents**: Purpose-built agents for specialized tasks - **MCP Servers**: Connect to external tools and data sources - **Hooks**: Customize Claude Code's workflow behavior +- **Context Files**: AI-specific instructions loaded automatically on session start Plugins can be easily toggled on and off as needed, making them perfect for: - Enforcing team coding standards @@ -69,13 +70,49 @@ Plugins can be easily toggled on and off as needed, making them perfect for: - Connecting internal tools - Bundling related customizations +### Context File Support + +Many plugins in this marketplace include context files that provide AI-specific instructions: + +- **Automatic Loading**: Context files are loaded via SessionStart hooks +- **Gemini CLI Compatibility**: Supports plugins converted from Gemini CLI extensions +- **Visual Indication**: Plugins with context files show a "Context" badge in the marketplace +- **Examples**: `GEMINI.md`, `flutter.md` with specialized AI instructions + ## Creating Your Own Plugin To create and distribute your own plugins: 1. Create a GitHub repository -2. Add a `.claude-plugin/marketplace.json` file with your plugin configuration -3. Users can add your marketplace with `/plugin marketplace add /` +2. Add a `.claude-plugin/plugin.json` file with your plugin configuration +3. (Optional) Add `contextFileName` field to enable automatic context loading +4. Users can add your marketplace with `/plugin marketplace add /` + +### Example plugin.json with Context File + +```json +{ + "name": "my-plugin", + "version": "1.0.0", + "description": "My custom plugin", + "contextFileName": "CONTEXT.md", + "mcpServers": { ... }, + "hooks": { + "SessionStart": [ + { + "matcher": "startup|resume", + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/hooks/context.sh", + "timeout": 10 + } + ] + } + ] + } +} +``` For detailed documentation on creating plugins, visit: - [Plugin Marketplace Documentation](https://docs.claude.com/en/docs/claude-code/plugin-marketplaces#github-repositories) diff --git a/apps/web/app/components/PluginCard.vue b/apps/web/app/components/PluginCard.vue index 646564d..24ea33a 100644 --- a/apps/web/app/components/PluginCard.vue +++ b/apps/web/app/components/PluginCard.vue @@ -20,24 +20,44 @@ {{ plugin.source.repo }} - - v{{ displayVersion }} - - - Loading... - +
+ + + Context + + + + MCP + + + v{{ displayVersion }} + + + Loading... + +
@@ -114,6 +134,8 @@ interface PluginMetadata { description?: string author?: string license?: string + mcpServers?: Record + contextFileName?: string [key: string]: any } @@ -167,6 +189,16 @@ const displayLicense = computed(() => { return pluginMetadata.value?.license }) +// Computed MCP server availability - check if plugin has MCP server configured +const hasMcpServer = computed(() => { + return pluginMetadata.value?.mcpServers && Object.keys(pluginMetadata.value.mcpServers).length > 0 +}) + +// Computed context file availability - check if plugin has context file configured +const hasContext = computed(() => { + return !!pluginMetadata.value?.contextFileName +}) + // Fetch metadata on mount onMounted(() => { fetchPluginMetadata() diff --git a/docs/adr/001-context-file-support.md b/docs/adr/001-context-file-support.md new file mode 100644 index 0000000..a180b20 --- /dev/null +++ b/docs/adr/001-context-file-support.md @@ -0,0 +1,147 @@ +# ADR 001: Context File Support in Claude Code Plugins + +## Status + +Accepted + +## Date + +2025-10-15 + +## Context + +Our plugin marketplace converts Gemini CLI extensions to Claude Code plugins. Gemini CLI extensions use a `contextFileName` field in `gemini-extension.json` to specify AI-specific instruction files (e.g., `GEMINI.md`, `flutter.md`) that provide context and guidelines to the AI model. + +Claude Code's native plugin format (`plugin.json`) does not have built-in support for context files. Without this feature, we lose important AI context when converting plugins, reducing their effectiveness. + +### Requirements + +1. Maintain compatibility with Gemini CLI extensions +2. Enable automatic context loading for converted plugins +3. Provide visual indication in the marketplace UI +4. Follow Claude Code's plugin conventions + +## Decision + +We will add `contextFileName` support to Claude Code plugins through the following implementation: + +### 1. Plugin Configuration + +Add `contextFileName` field to `.claude-plugin/plugin.json`: + +```json +{ + "name": "plugin-name", + "version": "1.0.0", + "contextFileName": "GEMINI.md", + "mcpServers": { ... }, + "hooks": { ... } +} +``` + +### 2. Context Loading Hook + +Implement a SessionStart hook (`hooks/context.sh`) that: +- Reads `contextFileName` from `plugin.json` (primary) +- Falls back to `gemini-extension.json` for backwards compatibility +- Loads the specified context file +- Returns content via Claude Code's hook output format + +```bash +#!/usr/bin/env bash +# Priority: plugin.json -> gemini-extension.json +CONTEXT_FILE=$(jq -r '.contextFileName // empty' "$PLUGIN_JSON") +if [ -z "$CONTEXT_FILE" ]; then + CONTEXT_FILE=$(jq -r '.contextFileName // empty' "$EXTENSION_JSON") +fi +``` + +### 3. UI Indication + +Add a "Context" badge in the marketplace PluginCard component: +- Purple badge with document icon +- Tooltip: "Includes Context File" +- Displayed when `contextFileName` field is present + +## Consequences + +### Positive + +1. **Seamless Migration**: Gemini CLI extensions retain their context functionality +2. **Automatic Loading**: No manual context setup required by users +3. **Backwards Compatible**: Falls back to `gemini-extension.json` if needed +4. **User Visibility**: Clear indication of context support in marketplace +5. **Extensible**: Other plugins can adopt this pattern + +### Negative + +1. **Additional HTTP Request**: Marketplace fetches `plugin.json` to check for context +2. **Hook Dependency**: Requires jq or grep for JSON parsing +3. **Non-Standard**: Not part of Claude Code's official plugin spec + +### Neutral + +1. **Maintenance**: Need to keep `context.sh` hook synchronized across plugins +2. **Documentation**: Requires clear documentation for plugin developers + +## Implementation Details + +### Files Modified + +- `plugins/*/​.claude-plugin/plugin.json` - Added `contextFileName` field +- `plugins/*/hooks/context.sh` - Updated to read from `plugin.json` +- `apps/web/app/components/PluginCard.vue` - Added Context badge +- `CLAUDE.md` - Documented contextFileName feature + +### Hook Configuration + +All plugins with context files now include: + +```json +{ + "hooks": { + "SessionStart": [ + { + "matcher": "startup|resume", + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/hooks/context.sh", + "timeout": 10 + } + ] + } + ] + } +} +``` + +## Alternatives Considered + +### 1. Use Only gemini-extension.json + +**Pros**: No changes to plugin.json +**Cons**: Doesn't integrate with Claude Code's native format + +**Rejected**: Goes against the goal of proper Claude Code plugin integration + +### 2. Bundle Context in Commands + +**Pros**: Uses existing command infrastructure +**Cons**: Context would need to be manually invoked + +**Rejected**: Not automatic, poor user experience + +### 3. Hardcode Context File Names + +**Pros**: Simpler implementation +**Cons**: Inflexible, doesn't work for plugins with different naming conventions + +**Rejected**: Flutter plugin uses `flutter.md`, not standard name + +## References + +- Claude Code Plugin Documentation +- Gemini CLI Extension Format +- SessionStart Hook Specification +- Issue: [Add MCP and Context badges to marketplace]