Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,39 @@ plugins/<plugin-name>/

### 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

Expand Down
41 changes: 39 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 <username>/<repo-name>`
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 <username>/<repo-name>`

### 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)
Expand Down
68 changes: 50 additions & 18 deletions apps/web/app/components/PluginCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,44 @@
<span class="truncate">{{ plugin.source.repo }}</span>
</div>
</div>
<UBadge
v-if="displayVersion"
variant="soft"
color="primary"
size="sm"
class="shrink-0"
>
v{{ displayVersion }}
</UBadge>
<UBadge
v-else-if="loading"
variant="soft"
color="neutral"
size="sm"
class="shrink-0"
>
Loading...
</UBadge>
<div class="flex items-center gap-2 shrink-0">
<UBadge
v-if="hasContext"
variant="soft"
color="purple"
size="sm"
title="Includes Context File"
>
<UIcon name="i-heroicons-document-text" class="mr-1" />
Context
</UBadge>
<UBadge
v-if="hasMcpServer"
variant="soft"
color="blue"
size="sm"
title="Includes MCP Server"
>
<UIcon name="i-heroicons-server" class="mr-1" />
MCP
</UBadge>
<UBadge
v-if="displayVersion"
variant="soft"
color="primary"
size="sm"
>
v{{ displayVersion }}
</UBadge>
<UBadge
v-else-if="loading"
variant="soft"
color="neutral"
size="sm"
>
Loading...
</UBadge>
</div>
</div>
</template>

Expand Down Expand Up @@ -114,6 +134,8 @@ interface PluginMetadata {
description?: string
author?: string
license?: string
mcpServers?: Record<string, any>
contextFileName?: string
[key: string]: any
}

Expand Down Expand Up @@ -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()
Expand Down
147 changes: 147 additions & 0 deletions docs/adr/001-context-file-support.md
Original file line number Diff line number Diff line change
@@ -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]