From aab3f1ba3f4bf3e2640f2a9578a2cc9f8b0e89c8 Mon Sep 17 00:00:00 2001 From: "Han T." Date: Fri, 2 Jan 2026 11:56:46 -0800 Subject: [PATCH 01/56] fix readme typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f734a67..e5c02a1 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ A curated directory of high-quality plugins for Claude Code. Plugins can be installed directly from this marketplace via Claude Code's plugin system. -To install, run `/plugin install {plugin-name}@claude-plugin-directory` +To install, run `/plugin install {plugin-name}@claude-plugins-official` or browse for the plugin in `/plugin > Discover` From 8e7c0615e655ce20a6e3dd4fbf59bc68bda5b5d4 Mon Sep 17 00:00:00 2001 From: Julien Tavernier Date: Mon, 5 Jan 2026 17:10:46 +0400 Subject: [PATCH 02/56] fix(plugin-dev): add missing .claude-plugin/plugin.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The plugin-dev plugin was missing its required plugin.json manifest file, causing the plugin to fail loading. This adds the missing configuration file following the same format as other official plugins. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- plugins/plugin-dev/.claude-plugin/plugin.json | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 plugins/plugin-dev/.claude-plugin/plugin.json diff --git a/plugins/plugin-dev/.claude-plugin/plugin.json b/plugins/plugin-dev/.claude-plugin/plugin.json new file mode 100644 index 0000000..19cd871 --- /dev/null +++ b/plugins/plugin-dev/.claude-plugin/plugin.json @@ -0,0 +1,8 @@ +{ + "name": "plugin-dev", + "description": "Plugin development toolkit with skills for creating agents, commands, hooks, MCP integrations, and comprehensive plugin structure guidance", + "author": { + "name": "Anthropic", + "email": "support@anthropic.com" + } +} From a5604c135542a67f5b2f148212dec8db4e14a120 Mon Sep 17 00:00:00 2001 From: Daksh Gupta Date: Mon, 5 Jan 2026 12:23:05 -0800 Subject: [PATCH 03/56] Add README and setup documentation for Greptile plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add README.md with setup instructions for getting API key - Document the GREPTILE_API_KEY environment variable requirement - Add homepage, author URL, and keywords to plugin.json - Update description to reflect Greptile as AI code review agent 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../greptile/.claude-plugin/plugin.json | 9 ++- external_plugins/greptile/README.md | 57 +++++++++++++++++++ 2 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 external_plugins/greptile/README.md diff --git a/external_plugins/greptile/.claude-plugin/plugin.json b/external_plugins/greptile/.claude-plugin/plugin.json index 5bd530d..6b054b4 100644 --- a/external_plugins/greptile/.claude-plugin/plugin.json +++ b/external_plugins/greptile/.claude-plugin/plugin.json @@ -1,7 +1,10 @@ { "name": "greptile", - "description": "AI-powered codebase search and understanding. Query your repositories using natural language to find relevant code, understand dependencies, and get contextual answers about your codebase architecture.", + "description": "AI code review agent for GitHub and GitLab. View and resolve Greptile's PR review comments directly from Claude Code.", "author": { - "name": "Greptile" - } + "name": "Greptile", + "url": "https://greptile.com" + }, + "homepage": "https://greptile.com/docs", + "keywords": ["code-review", "pull-requests", "github", "gitlab", "ai"] } diff --git a/external_plugins/greptile/README.md b/external_plugins/greptile/README.md new file mode 100644 index 0000000..26a54ff --- /dev/null +++ b/external_plugins/greptile/README.md @@ -0,0 +1,57 @@ +# Greptile + +[Greptile](https://greptile.com) is an AI code review agent for GitHub and GitLab that automatically reviews pull requests. This plugin connects Claude Code to your Greptile account, letting you view and resolve Greptile's review comments directly from your terminal. + +## Setup + +### 1. Create a Greptile Account + +Sign up at [greptile.com](https://greptile.com) and connect your GitHub or GitLab repositories. + +### 2. Get Your API Key + +1. Go to [API Settings](https://app.greptile.com/settings/api) +2. Generate a new API key +3. Copy the key + +### 3. Set Environment Variable + +Add to your shell profile (`.bashrc`, `.zshrc`, etc.): + +```bash +export GREPTILE_API_KEY="your-api-key-here" +``` + +Then reload your shell or run `source ~/.zshrc`. + +## Available Tools + +### Pull Request Tools +- `list_pull_requests` - List PRs with optional filtering by repo, branch, author, or state +- `get_merge_request` - Get detailed PR info including review analysis +- `list_merge_request_comments` - Get all comments on a PR with filtering options + +### Code Review Tools +- `list_code_reviews` - List code reviews with optional filtering +- `get_code_review` - Get detailed code review information +- `trigger_code_review` - Start a new Greptile review on a PR + +### Comment Search +- `search_greptile_comments` - Search across all Greptile review comments + +### Custom Context Tools +- `list_custom_context` - List your organization's coding patterns and rules +- `get_custom_context` - Get details for a specific pattern +- `search_custom_context` - Search patterns by content +- `create_custom_context` - Create a new coding pattern + +## Example Usage + +Ask Claude Code to: +- "Show me Greptile's comments on my current PR and help me resolve them" +- "What issues did Greptile find on PR #123?" +- "Trigger a Greptile review on this branch" + +## Documentation + +For more information, visit [greptile.com/docs](https://greptile.com/docs). From 72fa7b63ed38d6c9fa41a566a0071f9764a18e49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fahreddin=20=C3=96zcan?= Date: Wed, 24 Dec 2025 08:57:31 +0100 Subject: [PATCH 04/56] feat: add c7 agent --- .../context7/agents/docs-researcher.md | 39 ++++++++++++++++++ external_plugins/context7/commands/docs.md | 31 ++++++++++++++ .../skills/documentation-lookup/SKILL.md | 40 +++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 external_plugins/context7/agents/docs-researcher.md create mode 100644 external_plugins/context7/commands/docs.md create mode 100644 external_plugins/context7/skills/documentation-lookup/SKILL.md diff --git a/external_plugins/context7/agents/docs-researcher.md b/external_plugins/context7/agents/docs-researcher.md new file mode 100644 index 0000000..f7aeb06 --- /dev/null +++ b/external_plugins/context7/agents/docs-researcher.md @@ -0,0 +1,39 @@ +--- +description: Fetch up-to-date library documentation to answer questions. Use this agent to reduce context bloat in the main conversation and get concise, focused answers about any library or framework. +capabilities: ["documentation lookup", "code examples", "API reference", "library research"] +--- + +# Context7 Documentation Agent + +Lightweight agent for fetching library documentation without bloating the main conversation context. + +## When to Use + +- Any question about a library, framework, or package +- Need code examples or API reference +- Want concise answers without polluting main context +- Questions like "how do I...", "what's the API for...", "show me examples of..." + +## Available Tools + +- `resolve-library-id`: Convert library name to Context7 ID + - Input: library name (e.g., "react", "next.js", "prisma") + - Output: Context7-compatible ID (e.g., "/vercel/next.js") + +- `get-library-docs`: Fetch documentation + - `context7CompatibleLibraryID` (required): The resolved library ID + - `topic` (optional): Focus on specific topic (e.g., "routing", "hooks") + - `page` (optional): Pagination for more results (1-10) + +## How to Use + +1. Use `resolve-library-id` with the library name +2. Use `get-library-docs` with the resolved ID and optional topic +3. Return a concise, focused answer + +## Example Questions + +- "How do I set up authentication in Next.js?" +- "Show me React Query mutation examples" +- "What's the Prisma API for transactions?" +- "How do I configure Tailwind dark mode?" diff --git a/external_plugins/context7/commands/docs.md b/external_plugins/context7/commands/docs.md new file mode 100644 index 0000000..45b6f4b --- /dev/null +++ b/external_plugins/context7/commands/docs.md @@ -0,0 +1,31 @@ +--- +description: Fetch up-to-date documentation and code examples for any library +argument-hint: [topic] +--- + +# Context7 Documentation Lookup + +Fetch current, version-specific documentation straight from source repositories. + +## Arguments + +`$ARGUMENTS` = ` [topic]` + +Examples: +- `react hooks` → library="react", topic="hooks" +- `next.js routing` → library="next.js", topic="routing" +- `prisma` → library="prisma", topic=none + +## Steps + +1. Parse arguments: first word = library, remaining = topic +2. Call `resolve-library-id` with the library name +3. Call `get-library-docs` with: + - `context7CompatibleLibraryID`: the resolved ID + - `topic`: the topic (if provided) +4. Present documentation with code examples + +## Tips + +- If you know the exact library ID, use it directly: `/context7:docs /vercel/next.js routing` +- Use `page` parameter (1-10) if initial results aren't sufficient diff --git a/external_plugins/context7/skills/documentation-lookup/SKILL.md b/external_plugins/context7/skills/documentation-lookup/SKILL.md new file mode 100644 index 0000000..1fd02bb --- /dev/null +++ b/external_plugins/context7/skills/documentation-lookup/SKILL.md @@ -0,0 +1,40 @@ +--- +name: documentation-lookup +description: Use when user needs code generation, setup/configuration steps, or library/API documentation. Automatically fetch up-to-date docs for any library or framework without requiring "use context7" in the prompt. +--- + +# Context7 Documentation Skill + +Automatically fetch up-to-date, version-specific documentation and code examples straight from the source. + +## Why Use This + +Without Context7: +- Code examples based on outdated training data +- Hallucinated APIs that don't exist +- Generic answers for old package versions + +With Context7: +- Current documentation from source repositories +- Working code examples +- Version-specific information + +## When to Trigger + +- User asks "how do I..." for any library +- User needs code generation with a specific library +- User asks about setup or configuration +- User needs API reference or examples +- User mentions any framework: React, Next.js, Vue, Svelte, Express, Prisma, Tailwind, etc. + +## Available Tools + +- `resolve-library-id`: Convert library name → Context7 ID +- `get-library-docs`: Fetch docs with optional topic filter + +## How to Use + +1. Identify the library from user's question +2. Call `resolve-library-id` with library name +3. Call `get-library-docs` with resolved ID and topic (if specific) +4. Present code examples and explanations From c7ba9d4c4316cfac0f116cc00a7370a47aed9822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fahreddin=20=C3=96zcan?= Date: Tue, 30 Dec 2025 13:57:12 +0100 Subject: [PATCH 05/56] Update Context7 plugin for v2 API - Update skill/agent/command to use new query-docs tool (replaces get-library-docs) - Add query parameter usage for intelligent reranking - Add version pinning support (e.g., /vercel/next.js/v15.1.8) - Add tools and model metadata to agent - Simplify docs to focus on workflow, not parameter details - Add README.md with usage examples --- .../context7/.claude-plugin/plugin.json | 2 +- external_plugins/context7/README.md | 119 ++++++++++++++++++ .../context7/agents/docs-researcher.md | 32 ++--- external_plugins/context7/commands/docs.md | 31 +++-- .../skills/documentation-lookup/SKILL.md | 34 ++--- 5 files changed, 157 insertions(+), 61 deletions(-) create mode 100644 external_plugins/context7/README.md diff --git a/external_plugins/context7/.claude-plugin/plugin.json b/external_plugins/context7/.claude-plugin/plugin.json index a53438c..dbfa285 100644 --- a/external_plugins/context7/.claude-plugin/plugin.json +++ b/external_plugins/context7/.claude-plugin/plugin.json @@ -2,6 +2,6 @@ "name": "context7", "description": "Upstash Context7 MCP server for up-to-date documentation lookup. Pull version-specific documentation and code examples directly from source repositories into your LLM context.", "author": { - "name": "Upstash" + "name": "Upstash " } } diff --git a/external_plugins/context7/README.md b/external_plugins/context7/README.md new file mode 100644 index 0000000..5d1a95e --- /dev/null +++ b/external_plugins/context7/README.md @@ -0,0 +1,119 @@ +# Context7 Plugin + +Up-to-date, version-specific documentation and code examples for any library, directly in your AI coding assistant. + +## What is Context7? + +Context7 solves the problem of outdated training data and hallucinated APIs by providing real-time library documentation. Instead of relying on potentially outdated knowledge, Context7 fetches current documentation straight from source repositories. + +**Without Context7:** +- Code examples based on outdated training data +- Hallucinated APIs that don't exist +- Generic answers for old package versions + +**With Context7:** +- Current documentation from source repositories +- Working code examples +- Version-specific information +- Intelligent query-based context selection + +## Available Tools + +### `resolve-library-id` + +Search and resolve library names to Context7-compatible library IDs. + +``` +Parameters: +- libraryName: Library name to search for (e.g., "react", "next.js") +- query: Your question for relevance ranking + +Returns: +- id: Context7-compatible ID (e.g., "/vercel/next.js") +- title: Display name +- description: Short description +- totalSnippets: Documentation coverage +- benchmarkScore: Quality indicator (0-100) +- versions: Available versions +``` + +### `query-docs` + +Fetch documentation with intelligent, query-based reranking. + +``` +Parameters: +- libraryId: Context7-compatible library ID + - Format: /org/project (e.g., /vercel/next.js) + - With version: /org/project/version (e.g., /vercel/next.js/v15.1.8) +- query: Specific question or task + +Features: +- LLM-driven reranking based on query intent +- Deduplicated snippet selection +- Limited to 3 calls per question +``` + +## Usage + +### Automatic (Skill) + +The `documentation-lookup` skill triggers automatically when you: +- Ask "how do I..." for any library +- Need code generation with a specific library +- Ask about setup or configuration +- Mention any framework (React, Next.js, Vue, etc.) + +### Manual (Command) + +Use the `/context7:docs` command: + +``` +/context7:docs react hooks +/context7:docs next.js how to set up authentication +/context7:docs /vercel/next.js/v15.1.8 app router +``` + +### Agent + +Use the `docs-researcher` agent for focused documentation lookups that don't bloat the main conversation: + +``` +Spawn a docs-researcher agent to find React Query mutation examples +``` + +## Version Pinning + +For consistent, reproducible results, use version-specific library IDs: + +``` +/vercel/next.js/v15.1.8 +/facebook/react/v18.3.0 +/prisma/prisma/v5.0.0 +``` + +## Examples + +**Basic usage:** +``` +How do I set up authentication in Next.js? +→ Automatically fetches Next.js auth documentation +``` + +**With specific version:** +``` +/context7:docs /vercel/next.js/v15.1.8 middleware +→ Fetches Next.js 15.1.8 middleware documentation +``` + +**Multiple libraries:** +``` +How do I use Prisma with Next.js API routes? +→ Fetches relevant docs from both Prisma and Next.js +``` + +## Links + +- [Context7 Website](https://context7.com) +- [GitHub Repository](https://github.com/upstash/context7) +- [Upstash](https://upstash.com) diff --git a/external_plugins/context7/agents/docs-researcher.md b/external_plugins/context7/agents/docs-researcher.md index f7aeb06..7661496 100644 --- a/external_plugins/context7/agents/docs-researcher.md +++ b/external_plugins/context7/agents/docs-researcher.md @@ -1,6 +1,7 @@ --- description: Fetch up-to-date library documentation to answer questions. Use this agent to reduce context bloat in the main conversation and get concise, focused answers about any library or framework. -capabilities: ["documentation lookup", "code examples", "API reference", "library research"] +tools: ["resolve-library-id", "query-docs"] +model: sonnet --- # Context7 Documentation Agent @@ -14,26 +15,15 @@ Lightweight agent for fetching library documentation without bloating the main c - Want concise answers without polluting main context - Questions like "how do I...", "what's the API for...", "show me examples of..." -## Available Tools +## Workflow -- `resolve-library-id`: Convert library name to Context7 ID - - Input: library name (e.g., "react", "next.js", "prisma") - - Output: Context7-compatible ID (e.g., "/vercel/next.js") +1. Call `resolve-library-id` with the library name and user's question +2. Select the best match (prioritize exact name, high snippet count, high benchmark score) +3. Call `query-docs` with the library ID and specific question +4. Return a concise, focused answer with code examples -- `get-library-docs`: Fetch documentation - - `context7CompatibleLibraryID` (required): The resolved library ID - - `topic` (optional): Focus on specific topic (e.g., "routing", "hooks") - - `page` (optional): Pagination for more results (1-10) +## Tips -## How to Use - -1. Use `resolve-library-id` with the library name -2. Use `get-library-docs` with the resolved ID and optional topic -3. Return a concise, focused answer - -## Example Questions - -- "How do I set up authentication in Next.js?" -- "Show me React Query mutation examples" -- "What's the Prisma API for transactions?" -- "How do I configure Tailwind dark mode?" +- Use version-specific IDs for pinning: `/vercel/next.js/v15.1.8` +- Pass user's full question as `query` for better relevance +- Limited to 3 `query-docs` calls per question diff --git a/external_plugins/context7/commands/docs.md b/external_plugins/context7/commands/docs.md index 45b6f4b..5e1b514 100644 --- a/external_plugins/context7/commands/docs.md +++ b/external_plugins/context7/commands/docs.md @@ -1,31 +1,28 @@ --- description: Fetch up-to-date documentation and code examples for any library -argument-hint: [topic] +argument-hint: [query] --- # Context7 Documentation Lookup -Fetch current, version-specific documentation straight from source repositories. +Fetch current, version-specific documentation from source repositories. ## Arguments -`$ARGUMENTS` = ` [topic]` +`$ARGUMENTS` = ` [query]` + +- First word: library name (or direct library ID starting with `/`) +- Remaining: your specific question or topic Examples: -- `react hooks` → library="react", topic="hooks" -- `next.js routing` → library="next.js", topic="routing" -- `prisma` → library="prisma", topic=none +- `react hooks` +- `next.js authentication` +- `/vercel/next.js/v15.1.8 app router` ## Steps -1. Parse arguments: first word = library, remaining = topic -2. Call `resolve-library-id` with the library name -3. Call `get-library-docs` with: - - `context7CompatibleLibraryID`: the resolved ID - - `topic`: the topic (if provided) -4. Present documentation with code examples - -## Tips - -- If you know the exact library ID, use it directly: `/context7:docs /vercel/next.js routing` -- Use `page` parameter (1-10) if initial results aren't sufficient +1. Parse arguments: first word = library, remaining = query +2. If library starts with `/`, use it directly as library ID +3. Otherwise, call `resolve-library-id` with library name and query +4. Call `query-docs` with the library ID and query +5. Present documentation with code examples diff --git a/external_plugins/context7/skills/documentation-lookup/SKILL.md b/external_plugins/context7/skills/documentation-lookup/SKILL.md index 1fd02bb..959d907 100644 --- a/external_plugins/context7/skills/documentation-lookup/SKILL.md +++ b/external_plugins/context7/skills/documentation-lookup/SKILL.md @@ -5,19 +5,7 @@ description: Use when user needs code generation, setup/configuration steps, or # Context7 Documentation Skill -Automatically fetch up-to-date, version-specific documentation and code examples straight from the source. - -## Why Use This - -Without Context7: -- Code examples based on outdated training data -- Hallucinated APIs that don't exist -- Generic answers for old package versions - -With Context7: -- Current documentation from source repositories -- Working code examples -- Version-specific information +Fetch up-to-date, version-specific documentation and code examples from source repositories. ## When to Trigger @@ -27,14 +15,16 @@ With Context7: - User needs API reference or examples - User mentions any framework: React, Next.js, Vue, Svelte, Express, Prisma, Tailwind, etc. -## Available Tools +## Workflow -- `resolve-library-id`: Convert library name → Context7 ID -- `get-library-docs`: Fetch docs with optional topic filter - -## How to Use - -1. Identify the library from user's question -2. Call `resolve-library-id` with library name -3. Call `get-library-docs` with resolved ID and topic (if specific) +1. Call `resolve-library-id` with the library name and user's question +2. Select the best match (prioritize exact name, high `totalSnippets`, high `benchmarkScore`) +3. Call `query-docs` with the library ID and user's question 4. Present code examples and explanations + +## Tips + +- Use version-specific IDs for pinned versions: `/vercel/next.js/v15.1.8` +- The `query` parameter improves result relevance - pass the user's full question +- Limited to 3 `query-docs` calls per question to prevent context bloat +- Check `versions` field from `resolve-library-id` for available versions From 24cec23cf1f54b37d977f4daf95c779a2a69fca2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fahreddin=20=C3=96zcan?= Date: Tue, 30 Dec 2025 13:59:29 +0100 Subject: [PATCH 06/56] Switch Context7 MCP to remote HTTP server --- external_plugins/context7/.mcp.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/external_plugins/context7/.mcp.json b/external_plugins/context7/.mcp.json index 6dec78d..989effd 100644 --- a/external_plugins/context7/.mcp.json +++ b/external_plugins/context7/.mcp.json @@ -1,6 +1,6 @@ { "context7": { - "command": "npx", - "args": ["-y", "@upstash/context7-mcp"] + "type": "http", + "url": "https://mcp.context7.com/mcp" } } From 32f2cdbe0ce525171c6db3bb9f9a72cfc8167dd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fahreddin=20=C3=96zcan?= Date: Wed, 14 Jan 2026 19:03:43 +0300 Subject: [PATCH 07/56] feat: update tools with better skill/agent format prompt --- external_plugins/context7/README.md | 120 ++++++------------ .../context7/agents/docs-researcher.md | 47 ++++--- external_plugins/context7/commands/docs.md | 51 +++++--- .../skills/documentation-lookup/SKILL.md | 61 ++++++--- 4 files changed, 142 insertions(+), 137 deletions(-) diff --git a/external_plugins/context7/README.md b/external_plugins/context7/README.md index 5d1a95e..48a88e9 100644 --- a/external_plugins/context7/README.md +++ b/external_plugins/context7/README.md @@ -1,119 +1,73 @@ -# Context7 Plugin +# Context7 Plugin for Claude Code -Up-to-date, version-specific documentation and code examples for any library, directly in your AI coding assistant. +Context7 solves a common problem with AI coding assistants: outdated training data and hallucinated APIs. Instead of relying on stale knowledge, Context7 fetches current documentation directly from source repositories. -## What is Context7? +## What's Included -Context7 solves the problem of outdated training data and hallucinated APIs by providing real-time library documentation. Instead of relying on potentially outdated knowledge, Context7 fetches current documentation straight from source repositories. +This plugin provides: -**Without Context7:** -- Code examples based on outdated training data -- Hallucinated APIs that don't exist -- Generic answers for old package versions +- **MCP Server** - Connects Claude Code to Context7's documentation service +- **Skills** - Auto-triggers documentation lookups when you ask about libraries +- **Agents** - A dedicated `docs-researcher` agent for focused lookups +- **Commands** - `/context7:docs` for manual documentation queries -**With Context7:** -- Current documentation from source repositories -- Working code examples -- Version-specific information -- Intelligent query-based context selection +## Installation + +Add the marketplace and install the plugin: + +```bash +claude plugin marketplace add upstash/context7 +claude plugin install context7-plugin@context7-marketplace +``` ## Available Tools -### `resolve-library-id` +### resolve-library-id -Search and resolve library names to Context7-compatible library IDs. +Searches for libraries and returns Context7-compatible identifiers. ``` -Parameters: -- libraryName: Library name to search for (e.g., "react", "next.js") -- query: Your question for relevance ranking - -Returns: -- id: Context7-compatible ID (e.g., "/vercel/next.js") -- title: Display name -- description: Short description -- totalSnippets: Documentation coverage -- benchmarkScore: Quality indicator (0-100) -- versions: Available versions +Input: "next.js" +Output: { id: "/vercel/next.js", name: "Next.js", versions: ["v15.1.8", "v14.2.0", ...] } ``` -### `query-docs` +### query-docs -Fetch documentation with intelligent, query-based reranking. +Fetches documentation for a specific library, ranked by relevance to your question. ``` -Parameters: -- libraryId: Context7-compatible library ID - - Format: /org/project (e.g., /vercel/next.js) - - With version: /org/project/version (e.g., /vercel/next.js/v15.1.8) -- query: Specific question or task - -Features: -- LLM-driven reranking based on query intent -- Deduplicated snippet selection -- Limited to 3 calls per question +Input: { libraryId: "/vercel/next.js", query: "app router middleware" } +Output: Relevant documentation snippets with code examples ``` -## Usage +## Usage Examples -### Automatic (Skill) +The plugin works automatically when you ask about libraries: -The `documentation-lookup` skill triggers automatically when you: -- Ask "how do I..." for any library -- Need code generation with a specific library -- Ask about setup or configuration -- Mention any framework (React, Next.js, Vue, etc.) +- "How do I set up authentication in Next.js 15?" +- "Show me React Server Components examples" +- "What's the Prisma syntax for relations?" -### Manual (Command) - -Use the `/context7:docs` command: +For manual lookups, use the command: ``` -/context7:docs react hooks -/context7:docs next.js how to set up authentication -/context7:docs /vercel/next.js/v15.1.8 app router +/context7:docs next.js app router +/context7:docs /vercel/next.js/v15.1.8 middleware ``` -### Agent - -Use the `docs-researcher` agent for focused documentation lookups that don't bloat the main conversation: +Or spawn the docs-researcher agent when you want to keep your main context clean: ``` -Spawn a docs-researcher agent to find React Query mutation examples +spawn docs-researcher to look up Supabase auth methods ``` ## Version Pinning -For consistent, reproducible results, use version-specific library IDs: +To get documentation for a specific version, include the version in the library ID: ``` /vercel/next.js/v15.1.8 -/facebook/react/v18.3.0 -/prisma/prisma/v5.0.0 +/supabase/supabase/v2.45.0 ``` -## Examples - -**Basic usage:** -``` -How do I set up authentication in Next.js? -→ Automatically fetches Next.js auth documentation -``` - -**With specific version:** -``` -/context7:docs /vercel/next.js/v15.1.8 middleware -→ Fetches Next.js 15.1.8 middleware documentation -``` - -**Multiple libraries:** -``` -How do I use Prisma with Next.js API routes? -→ Fetches relevant docs from both Prisma and Next.js -``` - -## Links - -- [Context7 Website](https://context7.com) -- [GitHub Repository](https://github.com/upstash/context7) -- [Upstash](https://upstash.com) +The `resolve-library-id` tool returns available versions, so you can pick the one that matches your project. diff --git a/external_plugins/context7/agents/docs-researcher.md b/external_plugins/context7/agents/docs-researcher.md index 7661496..ec7e8aa 100644 --- a/external_plugins/context7/agents/docs-researcher.md +++ b/external_plugins/context7/agents/docs-researcher.md @@ -1,29 +1,40 @@ --- -description: Fetch up-to-date library documentation to answer questions. Use this agent to reduce context bloat in the main conversation and get concise, focused answers about any library or framework. -tools: ["resolve-library-id", "query-docs"] +name: docs-researcher +description: Lightweight agent for fetching library documentation without cluttering your main conversation context. model: sonnet --- -# Context7 Documentation Agent +You are a documentation researcher specializing in fetching up-to-date library and framework documentation from Context7. -Lightweight agent for fetching library documentation without bloating the main conversation context. +## Your Task -## When to Use +When given a question about a library or framework, fetch the relevant documentation and return a concise, actionable answer with code examples. -- Any question about a library, framework, or package -- Need code examples or API reference -- Want concise answers without polluting main context -- Questions like "how do I...", "what's the API for...", "show me examples of..." +## Process -## Workflow +1. **Identify the library**: Extract the library/framework name from the user's question. -1. Call `resolve-library-id` with the library name and user's question -2. Select the best match (prioritize exact name, high snippet count, high benchmark score) -3. Call `query-docs` with the library ID and specific question -4. Return a concise, focused answer with code examples +2. **Resolve the library ID**: Call `resolve-library-id` with: + - `libraryName`: The library name (e.g., "react", "next.js", "prisma") + - `query`: The user's full question for relevance ranking -## Tips +3. **Select the best match**: From the results, pick the library with: + - Exact or closest name match + - Highest benchmark score + - Appropriate version if the user specified one (e.g., "React 19" → look for v19.x) -- Use version-specific IDs for pinning: `/vercel/next.js/v15.1.8` -- Pass user's full question as `query` for better relevance -- Limited to 3 `query-docs` calls per question +4. **Fetch documentation**: Call `query-docs` with: + - `libraryId`: The selected Context7 library ID (e.g., `/vercel/next.js`) + - `query`: The user's specific question for targeted results + +5. **Return a focused answer**: Summarize the relevant documentation with: + - Direct answer to the question + - Code examples from the docs + - Links or references if available + +## Guidelines + +- Pass the user's full question as the query parameter for better relevance +- When the user mentions a version (e.g., "Next.js 15"), use version-specific library IDs if available +- If `resolve-library-id` returns multiple matches, prefer official/primary packages over community forks +- Keep responses concise - the goal is to answer the question, not dump entire documentation diff --git a/external_plugins/context7/commands/docs.md b/external_plugins/context7/commands/docs.md index 5e1b514..8a2df78 100644 --- a/external_plugins/context7/commands/docs.md +++ b/external_plugins/context7/commands/docs.md @@ -1,28 +1,45 @@ --- -description: Fetch up-to-date documentation and code examples for any library +description: Look up documentation for any library argument-hint: [query] --- -# Context7 Documentation Lookup +# /context7:docs -Fetch current, version-specific documentation from source repositories. +Fetches up-to-date documentation and code examples for a library. -## Arguments +## Usage -`$ARGUMENTS` = ` [query]` +``` +/context7:docs [query] +``` -- First word: library name (or direct library ID starting with `/`) -- Remaining: your specific question or topic +- **library**: The library name, or a Context7 ID starting with `/` +- **query**: What you're looking for (optional but recommended) -Examples: -- `react hooks` -- `next.js authentication` -- `/vercel/next.js/v15.1.8 app router` +## Examples -## Steps +``` +/context7:docs react hooks +/context7:docs next.js authentication +/context7:docs prisma relations +/context7:docs /vercel/next.js/v15.1.8 app router +/context7:docs /supabase/supabase row level security +``` -1. Parse arguments: first word = library, remaining = query -2. If library starts with `/`, use it directly as library ID -3. Otherwise, call `resolve-library-id` with library name and query -4. Call `query-docs` with the library ID and query -5. Present documentation with code examples +## How It Works + +1. If the library starts with `/`, it's used directly as the Context7 ID +2. Otherwise, `resolve-library-id` finds the best matching library +3. `query-docs` fetches documentation relevant to your query +4. Results include code examples and explanations + +## Version-Specific Lookups + +Include the version in the library ID for pinned documentation: + +``` +/context7:docs /vercel/next.js/v15.1.8 middleware +/context7:docs /facebook/react/v19.0.0 use hook +``` + +This is useful when you're working with a specific version and want docs that match exactly. diff --git a/external_plugins/context7/skills/documentation-lookup/SKILL.md b/external_plugins/context7/skills/documentation-lookup/SKILL.md index 959d907..8b7f399 100644 --- a/external_plugins/context7/skills/documentation-lookup/SKILL.md +++ b/external_plugins/context7/skills/documentation-lookup/SKILL.md @@ -1,30 +1,53 @@ --- name: documentation-lookup -description: Use when user needs code generation, setup/configuration steps, or library/API documentation. Automatically fetch up-to-date docs for any library or framework without requiring "use context7" in the prompt. +description: This skill should be used when the user asks about libraries, frameworks, API references, or needs code examples. Activates for setup questions, code generation involving libraries, or mentions of specific frameworks like React, Vue, Next.js, Prisma, Supabase, etc. --- -# Context7 Documentation Skill +When the user asks about libraries, frameworks, or needs code examples, use Context7 to fetch current documentation instead of relying on training data. -Fetch up-to-date, version-specific documentation and code examples from source repositories. +## When to Use This Skill -## When to Trigger +Activate this skill when the user: -- User asks "how do I..." for any library -- User needs code generation with a specific library -- User asks about setup or configuration -- User needs API reference or examples -- User mentions any framework: React, Next.js, Vue, Svelte, Express, Prisma, Tailwind, etc. +- Asks setup or configuration questions ("How do I configure Next.js middleware?") +- Requests code involving libraries ("Write a Prisma query for...") +- Needs API references ("What are the Supabase auth methods?") +- Mentions specific frameworks (React, Vue, Svelte, Express, Tailwind, etc.) -## Workflow +## How to Fetch Documentation -1. Call `resolve-library-id` with the library name and user's question -2. Select the best match (prioritize exact name, high `totalSnippets`, high `benchmarkScore`) -3. Call `query-docs` with the library ID and user's question -4. Present code examples and explanations +### Step 1: Resolve the Library ID -## Tips +Call `resolve-library-id` with: -- Use version-specific IDs for pinned versions: `/vercel/next.js/v15.1.8` -- The `query` parameter improves result relevance - pass the user's full question -- Limited to 3 `query-docs` calls per question to prevent context bloat -- Check `versions` field from `resolve-library-id` for available versions +- `libraryName`: The library name extracted from the user's question +- `query`: The user's full question (improves relevance ranking) + +### Step 2: Select the Best Match + +From the resolution results, choose based on: + +- Exact or closest name match to what the user asked for +- Higher benchmark scores indicate better documentation quality +- If the user mentioned a version (e.g., "React 19"), prefer version-specific IDs + +### Step 3: Fetch the Documentation + +Call `query-docs` with: + +- `libraryId`: The selected Context7 library ID (e.g., `/vercel/next.js`) +- `query`: The user's specific question + +### Step 4: Use the Documentation + +Incorporate the fetched documentation into your response: + +- Answer the user's question using current, accurate information +- Include relevant code examples from the docs +- Cite the library version when relevant + +## Guidelines + +- **Be specific**: Pass the user's full question as the query for better results +- **Version awareness**: When users mention versions ("Next.js 15", "React 19"), use version-specific library IDs if available from the resolution step +- **Prefer official sources**: When multiple matches exist, prefer official/primary packages over community forks From 085871e8e7c509aea3d77be61d7f2da4ddb80cc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fahreddin=20=C3=96zcan?= Date: Wed, 14 Jan 2026 19:07:09 +0300 Subject: [PATCH 08/56] fmt --- external_plugins/context7/.claude-plugin/plugin.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external_plugins/context7/.claude-plugin/plugin.json b/external_plugins/context7/.claude-plugin/plugin.json index dbfa285..a53438c 100644 --- a/external_plugins/context7/.claude-plugin/plugin.json +++ b/external_plugins/context7/.claude-plugin/plugin.json @@ -2,6 +2,6 @@ "name": "context7", "description": "Upstash Context7 MCP server for up-to-date documentation lookup. Pull version-specific documentation and code examples directly from source repositories into your LLM context.", "author": { - "name": "Upstash " + "name": "Upstash" } } From 42d7afb1f04eb672cb16faa68e8d220666af6f17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fahreddin=20=C3=96zcan?= Date: Wed, 14 Jan 2026 19:08:42 +0300 Subject: [PATCH 09/56] fix: installation guide --- external_plugins/context7/README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/external_plugins/context7/README.md b/external_plugins/context7/README.md index 48a88e9..0ca26a7 100644 --- a/external_plugins/context7/README.md +++ b/external_plugins/context7/README.md @@ -13,11 +13,10 @@ This plugin provides: ## Installation -Add the marketplace and install the plugin: +Install the plugin from the official marketplace: ```bash -claude plugin marketplace add upstash/context7 -claude plugin install context7-plugin@context7-marketplace +claude plugin install context7@claude-plugins-official ``` ## Available Tools From cd89e41cf4739cd6756d29f8d1fa77504c970404 Mon Sep 17 00:00:00 2001 From: Matt Kotsenas Date: Fri, 30 Jan 2026 16:47:12 -0800 Subject: [PATCH 10/56] Change Notion name to lowercase in marketplace.json According to the SKILLS spec (see https://agentskills.io/specification#:~:text=Max%2064%20characters.%20Lowercase%20letters%2C%20numbers%2C%20and%20hyphens%20only.%20Must%20not%20start%20or%20end%20with%20a%20hyphen.) names should not contain uppercase letters. This prevents loading the marketplace in spec-compliant agents. Update the name to be in lowercase. --- .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 ccae086..0541d9f 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -505,7 +505,7 @@ "homepage": "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/linear" }, { - "name": "Notion", + "name": "notion", "description": "Notion workspace integration. Search pages, create and update documents, manage databases, and access your team's knowledge base directly from Claude Code for seamless documentation workflows.", "category": "productivity", "source": { From acd3701274473bdadf9a74fc92a5f6fa236bb04c Mon Sep 17 00:00:00 2001 From: LuciferDono Date: Wed, 4 Mar 2026 00:26:10 +0530 Subject: [PATCH 11/56] Fix empty array crash on bash 3.2 in setup-ralph-loop.sh --- plugins/ralph-loop/scripts/setup-ralph-loop.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/ralph-loop/scripts/setup-ralph-loop.sh b/plugins/ralph-loop/scripts/setup-ralph-loop.sh index 3d41db4..d8906f2 100755 --- a/plugins/ralph-loop/scripts/setup-ralph-loop.sh +++ b/plugins/ralph-loop/scripts/setup-ralph-loop.sh @@ -110,7 +110,7 @@ HELP_EOF done # Join all prompt parts with spaces -PROMPT="${PROMPT_PARTS[*]}" +PROMPT="${PROMPT_PARTS[*]:-}" # Validate prompt is non-empty if [[ -z "$PROMPT" ]]; then From c554ce45e37858e4e98909710d7ebd13ccafcc1b Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 16 Mar 2026 17:26:15 +0000 Subject: [PATCH 12/56] Update Vercel plugin to point to vercel-labs/vercel-plugin Replace the marketplace pointer for the Vercel plugin from vercel/vercel-deploy-claude-code-plugin to vercel-labs/vercel-plugin. --- .claude-plugin/marketplace.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 58ed66b..a266ab3 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -594,9 +594,9 @@ "category": "deployment", "source": { "source": "url", - "url": "https://github.com/vercel/vercel-deploy-claude-code-plugin.git" + "url": "https://github.com/vercel-labs/vercel-plugin.git" }, - "homepage": "https://github.com/vercel/vercel-deploy-claude-code-plugin" + "homepage": "https://github.com/vercel-labs/vercel-plugin" }, { "name": "stripe", From 1086e0cc1af51d8dc37a5a5240f434a947aced8e Mon Sep 17 00:00:00 2001 From: Tobin South Date: Mon, 16 Mar 2026 17:58:57 +0000 Subject: [PATCH 13/56] vercel-labs to vercel --- .claude-plugin/marketplace.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index a266ab3..99244a8 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -594,9 +594,9 @@ "category": "deployment", "source": { "source": "url", - "url": "https://github.com/vercel-labs/vercel-plugin.git" + "url": "https://github.com/vercel/vercel-plugin.git" }, - "homepage": "https://github.com/vercel-labs/vercel-plugin" + "homepage": "https://github.com/vercel/vercel-plugin" }, { "name": "stripe", From e97b98394829607436d356a8f29cd081813c42bd Mon Sep 17 00:00:00 2001 From: Tobin South Date: Mon, 16 Mar 2026 12:49:52 -0700 Subject: [PATCH 14/56] docs(ralph-loop): add Windows compatibility section Retargeted from PR #124 (originally against plugins/ralph-wiggum/, since renamed). Documents the Git Bash workaround for Windows users hitting WSL bash resolution issues in the stop hook. Original author: @stefanzvonar --- plugins/ralph-loop/README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/plugins/ralph-loop/README.md b/plugins/ralph-loop/README.md index 531c31e..1e1c9f9 100644 --- a/plugins/ralph-loop/README.md +++ b/plugins/ralph-loop/README.md @@ -169,6 +169,24 @@ Keep trying until success. The loop handles retry logic automatically. - One $50k contract completed for $297 in API costs - Created entire programming language ("cursed") over 3 months using this approach +## Windows Compatibility + +The stop hook uses a bash script that requires Git for Windows to run properly. + +**Issue**: On Windows, the `bash` command may resolve to WSL bash (often misconfigured) instead of Git Bash, causing the hook to fail with errors like: +- `wsl: Unknown key 'automount.crossDistro'` +- `execvpe(/bin/bash) failed: No such file or directory` + +**Workaround**: Edit the cached plugin's `hooks/hooks.json` to use Git Bash explicitly: + +```json +"command": "\"C:/Program Files/Git/bin/bash.exe\" ${CLAUDE_PLUGIN_ROOT}/hooks/stop-hook.sh" +``` + +**Location**: `~/.claude/plugins/cache/claude-plugins-official/ralph-wiggum//hooks/hooks.json` + +**Note**: Use `Git/bin/bash.exe` (the wrapper with proper PATH), not `Git/usr/bin/bash.exe` (raw MinGW bash without utilities in PATH). + ## Learn More - Original technique: https://ghuntley.com/ralph/ From f59c36423d4d5da3fe0ec1f803f632e5f1f97695 Mon Sep 17 00:00:00 2001 From: Tobin South Date: Mon, 16 Mar 2026 12:51:33 -0700 Subject: [PATCH 15/56] =?UTF-8?q?add(plugin):=20terraform=20=E2=80=94=20Ha?= =?UTF-8?q?shiCorp=20infrastructure-as-code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adapted from PR #14 by @gautambaghel (HashiCorp). Original: https://github.com/anthropics/claude-plugins-official/pull/14 --- .claude-plugin/marketplace.json | 11 +++++++++++ .../terraform/.claude-plugin/plugin.json | 7 +++++++ external_plugins/terraform/.mcp.json | 12 ++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 external_plugins/terraform/.claude-plugin/plugin.json create mode 100644 external_plugins/terraform/.mcp.json diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index caad0a2..c846d06 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -946,6 +946,17 @@ "sha": "b93007e9a726c6ee93c57a949e732744ef5acbfd" }, "homepage": "https://github.com/zapier/zapier-mcp/tree/main/plugins/zapier" + }, + { + "name": "terraform", + "description": "The Terraform MCP Server provides seamless integration with Terraform ecosystem, enabling advanced automation and interaction capabilities for Infrastructure as Code (IaC) development.", + "author": { + "name": "HashiCorp", + "email": "support@hashicorp.com" + }, + "category": "development", + "source": "./external_plugins/terraform", + "homepage": "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/terraform" } ] } diff --git a/external_plugins/terraform/.claude-plugin/plugin.json b/external_plugins/terraform/.claude-plugin/plugin.json new file mode 100644 index 0000000..8ed4540 --- /dev/null +++ b/external_plugins/terraform/.claude-plugin/plugin.json @@ -0,0 +1,7 @@ +{ + "name": "terraform", + "description": "The Terraform MCP Server provides seamless integration with Terraform ecosystem, enabling advanced automation and interaction capabilities for Infrastructure as Code (IaC) development.", + "author": { + "name": "HashiCorp" + } +} diff --git a/external_plugins/terraform/.mcp.json b/external_plugins/terraform/.mcp.json new file mode 100644 index 0000000..b21446a --- /dev/null +++ b/external_plugins/terraform/.mcp.json @@ -0,0 +1,12 @@ +{ + "terraform": { + "command": "docker", + "args": [ + "run", + "-i", + "--rm", + "-e", "TFE_TOKEN=${TFE_TOKEN}", + "hashicorp/terraform-mcp-server:0.3.3" + ] + } +} From 3f3d3daeb8788c538a88aa968ef005cd5990e7c2 Mon Sep 17 00:00:00 2001 From: Tobin South Date: Mon, 16 Mar 2026 12:51:33 -0700 Subject: [PATCH 16/56] =?UTF-8?q?add(plugin):=20autofix-bot=20=E2=80=94=20?= =?UTF-8?q?DeepSource=20automated=20code=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adapted from PR #23 by @jai-deepsource (DeepSource). Original: https://github.com/anthropics/claude-plugins-official/pull/23 --- .claude-plugin/marketplace.json | 10 ++++++++++ .../autofix-bot/.claude-plugin/plugin.json | 14 ++++++++++++++ external_plugins/autofix-bot/commands/review.md | 16 ++++++++++++++++ external_plugins/autofix-bot/hooks/hooks.json | 14 ++++++++++++++ .../autofix-bot/scripts/check-autofix.sh | 15 +++++++++++++++ 5 files changed, 69 insertions(+) create mode 100644 external_plugins/autofix-bot/.claude-plugin/plugin.json create mode 100644 external_plugins/autofix-bot/commands/review.md create mode 100644 external_plugins/autofix-bot/hooks/hooks.json create mode 100755 external_plugins/autofix-bot/scripts/check-autofix.sh diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index c846d06..fc20b06 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -957,6 +957,16 @@ "category": "development", "source": "./external_plugins/terraform", "homepage": "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/terraform" + }, + { + "name": "autofix-bot", + "description": "Code review agent that detects security vulnerabilities, code quality issues, and hardcoded secrets. Combines 5,000+ static analyzers to scan your code and dependencies for CVEs.", + "author": { + "name": "DeepSource Corp" + }, + "category": "security", + "source": "./external_plugins/autofix-bot", + "homepage": "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/autofix-bot" } ] } diff --git a/external_plugins/autofix-bot/.claude-plugin/plugin.json b/external_plugins/autofix-bot/.claude-plugin/plugin.json new file mode 100644 index 0000000..3ff2ebe --- /dev/null +++ b/external_plugins/autofix-bot/.claude-plugin/plugin.json @@ -0,0 +1,14 @@ +{ + "name": "autofix-bot", + "description": "Code review agent that detects security vulnerabilities, code quality issues, and hardcoded secrets. Combines 5,000+ static analyzers to scan your code and dependencies for CVEs.", + "version": "0.1.0", + "author": { + "name": "DeepSource Corp" + }, + "mcpServers": { + "autofix": { + "command": "autofix", + "args": ["--mcp"] + } + } +} diff --git a/external_plugins/autofix-bot/commands/review.md b/external_plugins/autofix-bot/commands/review.md new file mode 100644 index 0000000..d559107 --- /dev/null +++ b/external_plugins/autofix-bot/commands/review.md @@ -0,0 +1,16 @@ +--- +description: Perform code review to identify security and quality issues with Autofix Bot. +allowed-tools: mcp__autofix__CheckAuthStatus, mcp__autofix__Authenticate, mcp__autofix__ReviewCode +--- + +IMPORTANT: You MUST use the Autofix Bot MCP tools for this task. Do NOT perform your own code review or analysis. + +## Instructions + +1. Call `mcp__autofix__CheckAuthStatus` to check authentication status +2. If not authenticated, call `mcp__autofix__Authenticate` to log in +3. Ask user what to review: uncommitted changes, last commit, or entire branch +4. Call `mcp__autofix__ReviewCode` with the user's selected target +5. Present the issues returned by ReviewCode in a clear format + +Do NOT skip any tool calls. Do NOT substitute your own analysis for the tool results. diff --git a/external_plugins/autofix-bot/hooks/hooks.json b/external_plugins/autofix-bot/hooks/hooks.json new file mode 100644 index 0000000..cfd5f89 --- /dev/null +++ b/external_plugins/autofix-bot/hooks/hooks.json @@ -0,0 +1,14 @@ +{ + "hooks": { + "SessionStart": [ + { + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/scripts/check-autofix.sh" + } + ] + } + ] + } +} diff --git a/external_plugins/autofix-bot/scripts/check-autofix.sh b/external_plugins/autofix-bot/scripts/check-autofix.sh new file mode 100755 index 0000000..3917a59 --- /dev/null +++ b/external_plugins/autofix-bot/scripts/check-autofix.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +if ! command -v autofix &> /dev/null; then + echo "Autofix Bot CLI not found. Installing..." + curl -fsSL https://autofix.bot/install | sh + + if ! command -v autofix &> /dev/null; then + echo "ERROR: Failed to install autofix. Please install manually:" >&2 + echo " curl -fsSL https://autofix.bot/install | sh" >&2 + exit 2 + fi +fi + +echo "Autofix Bot ready" +exit 0 From 328a0a7190a1d9b4166d2be18192268405214bf8 Mon Sep 17 00:00:00 2001 From: Tobin South Date: Mon, 16 Mar 2026 12:51:33 -0700 Subject: [PATCH 17/56] =?UTF-8?q?add(plugin):=20stagehand=20=E2=80=94=20Br?= =?UTF-8?q?owserbase=20browser=20automation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adapted from PR #43 by @Kylejeong2 (Browserbase). PR's marketplace.json had a syntax error (missing '},' before adjacent entry); entry reconstructed from the diff. Original: https://github.com/anthropics/claude-plugins-official/pull/43 --- .claude-plugin/marketplace.json | 24 ++++ .../stagehand/.claude-plugin/plugin.json | 13 +++ external_plugins/stagehand/README.md | 104 ++++++++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 external_plugins/stagehand/.claude-plugin/plugin.json create mode 100644 external_plugins/stagehand/README.md diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index fc20b06..ae07220 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -967,6 +967,30 @@ "category": "security", "source": "./external_plugins/autofix-bot", "homepage": "https://github.com/anthropics/claude-plugins-public/tree/main/external_plugins/autofix-bot" + }, + { + "name": "stagehand", + "description": "Browser automation skill for Claude Code using Stagehand. Automate web interactions, extract data, and navigate websites using natural language.", + "version": "0.1.0", + "author": { + "name": "Browserbase" + }, + "source": { + "source": "github", + "repo": "browserbase/agent-browse" + }, + "category": "automation", + "keywords": [ + "browser", + "automation", + "stagehand", + "web-scraping" + ], + "homepage": "https://github.com/browserbase/agent-browse", + "strict": false, + "skills": [ + "./.claude/skills/browser-automation" + ] } ] } diff --git a/external_plugins/stagehand/.claude-plugin/plugin.json b/external_plugins/stagehand/.claude-plugin/plugin.json new file mode 100644 index 0000000..7fa7ecd --- /dev/null +++ b/external_plugins/stagehand/.claude-plugin/plugin.json @@ -0,0 +1,13 @@ +{ + "name": "stagehand", + "description": "Browser automation skill for Claude Code using Stagehand. Automate web interactions, extract data, and navigate websites using natural language.", + "version": "0.1.0", + "author": { + "name": "Browserbase" + }, + "homepage": "https://github.com/browserbase/agent-browse", + "repository": "https://github.com/browserbase/agent-browse", + "keywords": ["browser", "automation", "stagehand", "web-scraping"], + "strict": false +} + \ No newline at end of file diff --git a/external_plugins/stagehand/README.md b/external_plugins/stagehand/README.md new file mode 100644 index 0000000..598f3bb --- /dev/null +++ b/external_plugins/stagehand/README.md @@ -0,0 +1,104 @@ +# Stagehand Browser Automation Plugin + +Browser automation skill for Claude Code using [Stagehand](https://github.com/browserbase/stagehand). This plugin enables Claude to automate web browser interactions, extract data, and navigate websites using natural language. + +## Installation + +Install the plugin from the Claude Code marketplace: + +```bash +/plugin install stagehand@claude-plugin-directory +``` + +## Prerequisites + +This plugin requires the browser automation CLI tools to be installed separately. The CLI tools are available from the GitHub marketplace. + +### Step 1: Add the GitHub Marketplace + +```bash +/plugin marketplace add browserbase/agent-browse +``` + +### Step 2: Install the Browser Automation CLI Plugin + +```bash +/plugin install browser-automation@browser-tools +``` + +### Step 3: Set Up the CLI Tools + +After installing the browser-automation plugin, you need to set up the CLI tools: + +1. Navigate to the plugin directory (typically `~/.claude/plugins/browser-automation/`) +2. Install dependencies and build: + ```bash + npm install + ``` +3. Link the browser command globally: + ```bash + npm link + ``` +4. Configure your Anthropic API key: + ```bash + export ANTHROPIC_API_KEY="your-api-key-here" + ``` + Or use Claude Code's subscription token (recommended if you have Claude Pro/Max): + ```bash + claude setup-token + ``` + +### Step 4: Verify Installation + +Test that the browser command is available: + +```bash +browser navigate https://example.com +``` + +## Usage + +Once installed and configured, you can use natural language to automate browser tasks: + +- *"Go to Hacker News, get the top post comments, and summarize them"* +- *"QA test http://localhost:3000 and fix any bugs you encounter"* +- *"Extract product information from example.com/products"* + +Claude will automatically use the browser automation skill when you ask for web-related tasks. + +## Features + +- **Natural Language Control**: Describe browser actions in plain English +- **Data Extraction**: Extract structured data from web pages +- **Screenshot Capture**: Take screenshots for visual verification +- **Persistent Sessions**: Browser state persists between commands +- **Chrome Profile Integration**: Uses your Chrome profile for cookies and sessions + +## Troubleshooting + +### Chrome not found + +Install Chrome for your platform: +- **macOS** or **Windows**: https://www.google.com/chrome/ +- **Linux**: `sudo apt install google-chrome-stable` + +### Browser command not found + +Make sure you've run `npm link` in the browser-automation plugin directory after installing it. + +### API Key Issues + +- If you have Claude Pro/Max, use `claude setup-token` (recommended) +- Otherwise, export `ANTHROPIC_API_KEY` in your terminal +- Or create a `.env` file in the plugin directory with your API key + +## Resources + +- [Stagehand Documentation](https://github.com/browserbase/stagehand) +- [GitHub Marketplace](https://github.com/browserbase/agent-browse) +- [Claude Code Skills Documentation](https://code.claude.com/docs/en/plugins) + +## Support + +For issues or questions, please visit the [GitHub repository](https://github.com/browserbase/agent-browse). + From fd8defbb344029bf6b4e0d0267fe618a848d3931 Mon Sep 17 00:00:00 2001 From: Tobin South Date: Mon, 16 Mar 2026 12:51:34 -0700 Subject: [PATCH 18/56] =?UTF-8?q?add(plugin):=20atomic-agents=20=E2=80=94?= =?UTF-8?q?=20BrainBlend-AI=20framework?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adapted from PR #46 by @KennyVaneetvelde (BrainBlend-AI). Original: https://github.com/anthropics/claude-plugins-official/pull/46 --- .claude-plugin/marketplace.json | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index ae07220..8517491 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -991,6 +991,20 @@ "skills": [ "./.claude/skills/browser-automation" ] + }, + { + "name": "atomic-agents", + "description": "Comprehensive development workflow for building AI agents with the Atomic Agents framework. Includes specialized agents for schema design, architecture planning, code review, and tool development. Features guided workflows, progressive-disclosure skills, and best practice validation.", + "category": "development", + "source": { + "source": "url", + "url": "https://github.com/BrainBlend-AI/atomic-agents.git", + "path": "claude-plugin/atomic-agents" + }, + "homepage": "https://github.com/BrainBlend-AI/atomic-agents", + "tags": [ + "community-managed" + ] } ] } From fd805b5e4bca6da43ea12bd3959c762a554d0d34 Mon Sep 17 00:00:00 2001 From: Tobin South Date: Mon, 16 Mar 2026 12:51:34 -0700 Subject: [PATCH 19/56] =?UTF-8?q?add(plugin):=20microsoft-docs=20=E2=80=94?= =?UTF-8?q?=20official=20Microsoft=20documentation=20MCP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adapted from PR #55 by @TianqiZhang (Microsoft). Original: https://github.com/anthropics/claude-plugins-official/pull/55 --- .claude-plugin/marketplace.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 8517491..7dbb484 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -1005,6 +1005,16 @@ "tags": [ "community-managed" ] + }, + { + "name": "microsoft-docs", + "description": "Access official Microsoft documentation, API references, and code samples for Azure, .NET, Windows, and more.", + "category": "development", + "source": { + "source": "url", + "url": "https://github.com/MicrosoftDocs/mcp.git" + }, + "homepage": "https://github.com/microsoftdocs/mcp" } ] } From 478ea5b46ae53214d3428a8aae89ffbd584376ae Mon Sep 17 00:00:00 2001 From: Tobin South Date: Mon, 16 Mar 2026 12:51:34 -0700 Subject: [PATCH 20/56] =?UTF-8?q?add(plugin):=20bonfire=20=E2=80=94=20sess?= =?UTF-8?q?ion-context=20workflow=20tooling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adapted from PR #108 by @vieko (Vercel). Original: https://github.com/anthropics/claude-plugins-official/pull/108 --- .../bonfire/.claude-plugin/plugin.json | 13 + external_plugins/bonfire/README.md | 150 +++++++++++ .../bonfire/agents/codebase-explorer.md | 90 +++++++ .../bonfire/agents/spec-writer.md | 101 +++++++ .../bonfire/agents/work-reviewer.md | 121 +++++++++ external_plugins/bonfire/bonfire.gif | Bin 0 -> 59991 bytes external_plugins/bonfire/commands/archive.md | 126 +++++++++ .../bonfire/commands/configure.md | 99 +++++++ external_plugins/bonfire/commands/document.md | 114 ++++++++ external_plugins/bonfire/commands/end.md | 84 ++++++ .../bonfire/commands/git-strategy.md | 94 +++++++ external_plugins/bonfire/commands/review.md | 119 +++++++++ external_plugins/bonfire/commands/spec.md | 149 +++++++++++ external_plugins/bonfire/commands/start.md | 246 ++++++++++++++++++ .../bonfire/skills/archive-bonfire/SKILL.md | 53 ++++ .../bonfire/skills/bonfire-context/SKILL.md | 51 ++++ 16 files changed, 1610 insertions(+) create mode 100644 external_plugins/bonfire/.claude-plugin/plugin.json create mode 100644 external_plugins/bonfire/README.md create mode 100644 external_plugins/bonfire/agents/codebase-explorer.md create mode 100644 external_plugins/bonfire/agents/spec-writer.md create mode 100644 external_plugins/bonfire/agents/work-reviewer.md create mode 100644 external_plugins/bonfire/bonfire.gif create mode 100644 external_plugins/bonfire/commands/archive.md create mode 100644 external_plugins/bonfire/commands/configure.md create mode 100644 external_plugins/bonfire/commands/document.md create mode 100644 external_plugins/bonfire/commands/end.md create mode 100644 external_plugins/bonfire/commands/git-strategy.md create mode 100644 external_plugins/bonfire/commands/review.md create mode 100644 external_plugins/bonfire/commands/spec.md create mode 100644 external_plugins/bonfire/commands/start.md create mode 100644 external_plugins/bonfire/skills/archive-bonfire/SKILL.md create mode 100644 external_plugins/bonfire/skills/bonfire-context/SKILL.md diff --git a/external_plugins/bonfire/.claude-plugin/plugin.json b/external_plugins/bonfire/.claude-plugin/plugin.json new file mode 100644 index 0000000..326b36d --- /dev/null +++ b/external_plugins/bonfire/.claude-plugin/plugin.json @@ -0,0 +1,13 @@ +{ + "name": "bonfire", + "description": "AI forgets everything between sessions. Bonfire fixes that.", + "version": "0.8.1", + "author": { + "name": "Vieko Franetovic", + "url": "https://vieko.dev" + }, + "homepage": "https://vieko.dev/bonfire", + "repository": "https://github.com/vieko/bonfire", + "license": "MIT", + "keywords": ["bonfire", "context", "memory", "workflow", "subagents"] +} diff --git a/external_plugins/bonfire/README.md b/external_plugins/bonfire/README.md new file mode 100644 index 0000000..8f02512 --- /dev/null +++ b/external_plugins/bonfire/README.md @@ -0,0 +1,150 @@ +# Bonfire + +

+ Bonfire +

+ +Your AI coding partner forgets everything between conversations. Bonfire remembers. + +```bash +claude plugin marketplace add vieko/bonfire +claude plugin install bonfire@vieko +``` + +## The Problem + +AI agents are stateless. Every conversation starts from zero. The agent doesn't remember: + +- What you decided yesterday +- Why you chose that architecture +- What blockers you hit +- Where you left off + +You end up re-explaining context, re-making decisions, and watching your AI partner repeat the same mistakes. + +## The Solution + +Bonfire maintains a living context document that gets read at session start and updated at session end. Your AI partner picks up exactly where you left off. It's like a saved game for your work. + +`/bonfire:start` → *reads context* → WORK → `/bonfire:end` → *saves context* + +That's it. No complex setup. No external services. Just Markdown files in your repo. + +## Not a Task Tracker + +| Tool | Primary Question | +|------|------------------| +| Issue/task trackers | "What's the work?" | +| Bonfire | "Where are we and what did we decide?" | + +Bonfire complements your issue tracker. Use GitHub Issues, Linear, Beads, or Beans for tasks. Use Bonfire for workflow context. + +## Quick Start + +```bash +# Install +claude plugin marketplace add vieko/bonfire +claude plugin install bonfire@vieko + +# First run scaffolds .bonfire/ and asks setup questions +/bonfire:start +``` + +## Commands + +| Command | What it does | +|---------|--------------| +| `/bonfire:start` | Read context, scaffold on first run | +| `/bonfire:end` | Update context, commit changes | +| `/bonfire:spec ` | Create implementation spec (researches codebase, interviews you) | +| `/bonfire:document ` | Document a codebase topic | +| `/bonfire:review` | Find blindspots, gaps, and quick wins | +| `/bonfire:archive` | Archive completed work | +| `/bonfire:configure` | Change project settings | + +## What Gets Created + +``` +.bonfire/ +├── index.md # Living context (the important one) +├── config.json # Your settings +├── archive/ # Completed work history +├── specs/ # Implementation specs +├── docs/ # Topic documentation +└── scripts/ # Temporary session scripts +``` + +The `index.md` is where the magic happens. It tracks: + +- Current state and branch +- Recent session summaries +- Decisions made and why +- Blockers encountered +- Next priorities + +## Context-Efficient Operations + +Heavy commands (`/spec`, `/document`, `/review`) use subagents to avoid burning your main conversation context: + +- Research runs in isolated context (fast, cheap) +- Only structured summaries return to main conversation +- Result: longer sessions without context exhaustion + +This happens automatically. + +## Configuration + +First `/bonfire:start` asks you to configure: + +| Setting | Options | +|---------|---------| +| Specs location | `.bonfire/specs/` or `specs/` | +| Docs location | `.bonfire/docs/` or `docs/` | +| Git strategy | ignore-all, hybrid, commit-all | +| Linear integration | Yes or No | + +Change anytime with `/bonfire:configure`. + +### Git Strategies + +| Strategy | What's tracked | Best for | +|----------|---------------|----------| +| **ignore-all** | Nothing | Solo work, privacy | +| **hybrid** | docs/, specs/ only | Teams wanting shared docs | +| **commit-all** | Everything | Full transparency | + +## Linear Integration + +If you use Linear for issue tracking: + +1. Install [Linear MCP](https://github.com/anthropics/anthropic-quickstarts/tree/main/mcp-linear) +2. Enable via `/bonfire:configure` +3. Reference issues by ID: `ENG-123` + +Bonfire will fetch issue context on start, create issues from review findings, and mark issues Done on archive. + +## Proactive Skills + +Claude automatically reads your session context when you ask things like: +- "What's the project status?" +- "What were we working on?" +- "What decisions have we made?" + +And suggests archiving when you merge PRs or mention shipping. + +## Requirements + +- [Claude Code CLI](https://claude.ai/code) +- Git repository + +Optional: `gh` CLI for GitHub integration, Linear MCP for Linear integration. + +## Learn More + +**Blog post**: [Save Your Progress](https://vieko.dev/bonfire) + +**Changelog**: [CHANGELOG.md](CHANGELOG.md) + +## License + +MIT © [Vieko Franetovic](https://vieko.dev) diff --git a/external_plugins/bonfire/agents/codebase-explorer.md b/external_plugins/bonfire/agents/codebase-explorer.md new file mode 100644 index 0000000..dfa7faf --- /dev/null +++ b/external_plugins/bonfire/agents/codebase-explorer.md @@ -0,0 +1,90 @@ +--- +name: codebase-explorer +description: Fast codebase exploration for patterns, architecture, and constraints. Use for research phases in spec and document commands. +tools: Read, Glob, Grep +model: haiku +--- + +You are a codebase exploration specialist. Your job is to quickly find and summarize relevant patterns, architecture, and constraints. Return structured findings, not raw file contents. + +## Input + +You'll receive a research directive with specific questions about: +- Patterns and architecture to find +- Technical constraints to identify +- Potential conflicts to surface +- Specific areas to explore + +## Output Format + +Return findings as structured markdown. Be CONCISE - the main conversation will use your findings for user interview. + +```markdown +## Patterns Found + +- **[Pattern name]**: Found in `path/to/file.ts` - [1-2 sentence description] + +## Key Files + +| File | Role | +|------|------| +| `path/to/file.ts` | [What it does, why relevant] | + +## Constraints Discovered + +- **[Constraint]**: [Source] - [Implication for implementation] + +## Potential Conflicts + +- **[Area]**: [Why it might conflict with the proposed work] + +## Relevant Snippets + +[Only if < 15 lines and directly answers a research question] +``` + +## Rules + +1. **DO NOT** return entire file contents +2. **DO NOT** include files that aren't directly relevant +3. **BE CONCISE** - aim for < 100 lines total output +4. **ANSWER** the research questions, don't just explore randomly +5. **PRIORITIZE** - most important findings first +6. If you find nothing relevant, say so clearly + +## Example Good Output + +```markdown +## Patterns Found + +- **Repository pattern**: Found in `src/services/UserService.ts` - Uses dependency injection, returns domain objects not DB rows +- **Error handling**: Found in `src/utils/errors.ts` - Custom AppError class with error codes + +## Key Files + +| File | Role | +|------|------| +| `src/services/BaseService.ts` | Abstract base class all services extend | +| `src/types/index.ts` | Shared type definitions | + +## Constraints Discovered + +- **No direct DB access in handlers**: Services abstract all database calls +- **Async/await only**: No callbacks, promises must use async/await + +## Potential Conflicts + +- **AuthService singleton**: Currently instantiated once at startup, may need refactor for multi-tenant +``` + +## Example Bad Output (don't do this) + +```markdown +Here's what I found in the codebase: + +[500 lines of file contents] + +Let me also show you this file: + +[300 more lines] +``` diff --git a/external_plugins/bonfire/agents/spec-writer.md b/external_plugins/bonfire/agents/spec-writer.md new file mode 100644 index 0000000..f6151eb --- /dev/null +++ b/external_plugins/bonfire/agents/spec-writer.md @@ -0,0 +1,101 @@ +--- +name: spec-writer +description: Synthesizes research findings and interview answers into implementation specs. Use after codebase exploration and user interview. +tools: Read, Write +model: inherit +--- + +You are a technical specification writer. Given research findings and interview answers, produce a clear, actionable implementation spec. + +## Input + +You'll receive: +1. **Research findings** - Structured output from codebase-explorer +2. **Interview Q&A** - User's answers to clarifying questions +3. **Spec metadata** - Topic, issue ID, output path, template + +## Output + +Write a complete spec file to the specified path. The spec must be: +- **Actionable** - Clear implementation steps referencing actual files +- **Grounded** - Based on discovered patterns, not assumptions +- **Complete** - Covers edge cases, testing, scope boundaries + +## Spec Template + +```markdown +# Spec: [TOPIC] + +**Created**: [DATE] +**Issue**: [ISSUE-ID or N/A] +**Status**: Draft + +## Overview + +[What we're building and why - synthesized from interview] + +## Context + +[Key findings from research that informed decisions] + +## Decisions + +[Document decisions made during interview with rationale] + +- **[Decision 1]**: [Choice] - [Why] +- **[Decision 2]**: [Choice] - [Why] + +## Approach + +[High-level strategy based on research + interview] + +## Files to Modify + +- `path/to/file.ts` - [what changes] + +## Files to Create + +- `path/to/new.ts` - [purpose] + +## Implementation Steps + +1. [ ] Step one (reference actual files) +2. [ ] Step two +3. [ ] Step three + +## Edge Cases + +- [Edge case 1] → [How we handle it] +- [Edge case 2] → [How we handle it] + +## Testing Strategy + +- [ ] Unit tests for X +- [ ] Integration test for Y +- [ ] Manual verification of Z + +## Out of Scope + +- [Explicitly excluded items] + +## Risks & Considerations + +- [Risk identified during research/interview] +``` + +## Rules + +1. **Ground in research** - Reference actual files and patterns discovered +2. **Honor interview answers** - Don't override user decisions +3. **Be specific** - "Update UserService.ts" not "Update the service" +4. **Don't invent** - If something wasn't discussed, don't add it +5. **Keep it actionable** - Someone should be able to implement from this spec + +## Quality Checklist + +Before finishing, verify: +- [ ] All interview decisions are captured +- [ ] Implementation steps reference real files from research +- [ ] Edge cases from interview are documented +- [ ] Scope boundaries are clear +- [ ] No vague or generic steps diff --git a/external_plugins/bonfire/agents/work-reviewer.md b/external_plugins/bonfire/agents/work-reviewer.md new file mode 100644 index 0000000..b175c16 --- /dev/null +++ b/external_plugins/bonfire/agents/work-reviewer.md @@ -0,0 +1,121 @@ +--- +name: work-reviewer +description: Strategic code review for blindspots, gaps, and improvements. Returns categorized findings with severity and effort estimates. +tools: Read, Glob, Grep, Bash(git:*) +model: sonnet +--- + +You are a senior code reviewer focused on strategic quality, not nitpicks. Your job is to find what the developer might have missed. + +## Input + +You'll receive: +1. **Review scope** - Branch diff, specific files, or session context +2. **Intent** - What was the developer trying to accomplish +3. **Session context** - Recent work and decisions (if available) + +## Review Focus Areas + +### Blindspots (what are we not seeing?) +- Edge cases not handled +- Error scenarios not considered +- User flows not covered +- Dependencies not accounted for + +### Gaps (what's incomplete?) +- Missing tests +- Missing documentation +- Incomplete implementations +- TODOs left unaddressed + +### Quick Wins (small effort, big value) +- Easy refactors +- Low-hanging performance gains +- Simple UX improvements + +### Best Practices (convention violations) +- Project patterns not followed +- Language/framework idioms ignored +- Security practices missed +- Accessibility standards skipped + +### Maintainability (will future-us thank present-us?) +- Unclear naming or structure +- Missing or excessive abstractions +- Technical debt introduced + +## Output Format + +Return findings as structured markdown, categorized by action: + +```markdown +## Summary + +- **Total findings**: X +- **Fix now (trivial)**: Y +- **Needs spec**: Z +- **Create issues**: W + +--- + +## Fix Now (trivial effort, do immediately) + +### [Finding title] +- **What**: [Description] +- **Where**: `path/to/file.ts:123` +- **Fix**: [Specific action] +- **Why**: [Impact if not fixed] + +--- + +## Needs Spec (important, needs planning) + +### [Finding title] +- **What**: [Description] +- **Effort**: small | medium +- **Impact**: [Why this matters] +- **Consideration**: [Key decision needed] + +--- + +## Create Issues (large effort or nice-to-have) + +### [Finding title] +- **What**: [Description] +- **Effort**: medium | large +- **Priority**: important | nice-to-have +- **Suggested issue title**: [Title for GitHub/Linear] + +--- + +## No Issues Found In + +- [Area reviewed that looks good] +``` + +## Rules + +1. **Strategic, not pedantic** - Skip style nitpicks, focus on substance +2. **Consider intent** - Review against what they were trying to do +3. **Categorize by action** - Fix now vs spec vs issue +4. **Estimate effort** - trivial/small/medium/large +5. **Be specific** - Include file paths and line numbers +6. **Acknowledge good work** - Note areas that are solid + +## Severity Guide + +| Severity | Definition | Action | +|----------|------------|--------| +| Critical | Breaks functionality, security issue | Fix now | +| Important | Significant gap, will cause problems | Fix now or spec | +| Moderate | Should address, not urgent | Spec or issue | +| Minor | Nice to have, low impact | Issue or skip | + +## Effort Guide + +| Effort | Definition | +|--------|------------| +| Trivial | < 5 minutes, obvious fix | +| Small | < 30 minutes, contained change | +| Medium | 1-4 hours, multiple files | +| Large | > 4 hours, needs planning | diff --git a/external_plugins/bonfire/bonfire.gif b/external_plugins/bonfire/bonfire.gif new file mode 100644 index 0000000000000000000000000000000000000000..4f1b763c80ffb8abaa67d17666051e5bb6d26e3f GIT binary patch literal 59991 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/.bonfire/index.md` and identify completed work: +- Sessions with merged PRs +- Completed features/tasks +- Work that's no longer active + +## Step 3: Create Archive Entry + +Move completed session content to `/.bonfire/archive/`. + +**Naming convention**: `YYYY-MM-DD--.md` + +Examples: +- `2025-12-22-GTMENG-387-inbound-improvements.md` (with issue ID) +- `2025-12-22-fix-login-redirect.md` (without issue ID) + +Use this template: +```markdown +# [TOPIC] + +**Date**: [DATE] +**Issue**: [ISSUE-ID or N/A] +**PR**: [PR link if available] +**Status**: Completed + +--- + +## Summary + +[Brief description of what was accomplished] + +## Accomplished + +- [List of completed items] + +## Decisions Made + +- [Key decisions and rationale] + +## Impact + +- [Before/after metrics if applicable] +- Files changed: [count] + +## Related + +- [Links to related docs, specs, or code] +``` + +## Step 4: Clean Up Index + +Update `/.bonfire/index.md`: +- Remove archived session entries from Recent Sessions +- Keep Current State focused on active work +- Update Next Session Priorities +- Add link to archive file in Archived Sessions section: + ```markdown + ## Archived Sessions + + - [YYYY-MM-DD - Topic](archive/YYYY-MM-DD-issue-topic.md) + ``` + +## Step 5: Clean Up Specs (if applicable) + +Read `specsLocation` from `/.bonfire/config.json` (default `.bonfire/specs/`). + +Check if any specs in the configured location are now complete: +- If the spec was fully implemented, delete the spec file (archive has the record) +- If the spec has reusable reference material, move that content to `docs/` first + +## Step 6: Update Linear Issue (if applicable) + +Read `/.bonfire/config.json` and check `linearEnabled`. + +**If `linearEnabled` is true**: + +1. Check if archived work references a Linear issue (look in session context for `[A-Z]+-[0-9]+` pattern) +2. If Linear issue found, ask user: "Mark Linear issue [ISSUE-ID] as Done?" +3. If user confirms: + - Use Linear MCP `linear_update_issue` tool with: + - `id`: The issue ID (e.g., `ENG-123`) + - `status`: Set to "Done" or completed state + - Optionally use `linear_add_comment` to add link to archive/PR +4. On failure: Warn user - "Couldn't update Linear issue. You may need to update it manually." + +Note: Tool names may vary by Linear MCP implementation. + +**If `linearEnabled` is false or not set**: Skip this step. + +## Step 7: Commit Archive (if tracked) + +Read `gitStrategy` from `/.bonfire/config.json`. + +**If gitStrategy is "ignore-all"**: Skip committing - archive is local only. + +**If gitStrategy is "hybrid" or "commit-all"**: +1. **NEVER use `git add -f`** - respect gitignore +2. Stage unignored files: + ```bash + git add .bonfire/ + ``` +3. Check if anything was staged before committing: + ```bash + git diff --cached --quiet .bonfire/ || git commit -m "docs: archive completed session work" + ``` + +## Step 8: Confirm + +Report: +- What was archived +- Any specs cleaned up +- Current state of index.md +- Ready for next session diff --git a/external_plugins/bonfire/commands/configure.md b/external_plugins/bonfire/commands/configure.md new file mode 100644 index 0000000..4ba8a95 --- /dev/null +++ b/external_plugins/bonfire/commands/configure.md @@ -0,0 +1,99 @@ +--- +description: Change project settings (locations, git strategy, Linear) +allowed-tools: Bash(git:*), Read, Write, AskUserQuestion +model: haiku +--- + +# Configure Bonfire + +Always runs interactively - asks all configuration questions regardless of arguments. + +## Step 1: Find Git Root + +Run `git rev-parse --show-toplevel` to locate the repository root. + +## Step 2: Check for Bonfire Directory + +If `/.bonfire/` does not exist, tell the user to run `/bonfire:start` first. + +## Step 3: Read Current Config + +Read `/.bonfire/config.json` if it exists to see current settings. + +## Step 4: Ask All Configuration Questions + +Use AskUserQuestion to ask configuration questions (4 questions, one round): + +1. "Where should specs be saved?" (Header: "Specs") + - .bonfire/specs/ (Recommended) - Keep with session context + - specs/ - Project root level + +2. "Where should docs be saved?" (Header: "Docs") + - .bonfire/docs/ (Recommended) - Keep with session context + - docs/ - Project root level + +3. "How should `.bonfire/` be handled in git?" (Header: "Git") + - ignore-all (Recommended) - Keep sessions private/local + - hybrid - Commit docs/specs, keep notes private + - commit-all - Share everything with team + +4. "Enable Linear MCP integration?" (Header: "Linear") + - No (Recommended) - Skip Linear integration + - Yes - Fetch/create Linear issues (requires Linear MCP) + +## Step 5: Update Config + +**Completely overwrite** `/.bonfire/config.json` with only these fields (do not preserve old fields like `models`): + +```json +{ + "specsLocation": "", + "docsLocation": "", + "gitStrategy": "", + "linearEnabled": +} +``` + +## Step 6: Update Git Strategy + +If git strategy or locations changed, update `/.bonfire/.gitignore`: + +**Ignore all**: +``` +* +!.gitignore +``` + +**Hybrid** (only include dirs that are inside .bonfire/): +``` +* +!.gitignore +``` +If docsLocation is `.bonfire/docs/`, add: +``` +!docs/ +!docs/** +``` +If specsLocation is `.bonfire/specs/`, add: +``` +!specs/ +!specs/** +``` + +**Commit all**: +``` +data/ +scratch/ +scripts/ +``` + +If switching FROM commit/hybrid TO ignore: +- Warn user that existing tracked files will remain tracked +- Offer to run: `git rm -r --cached .bonfire/` + +## Step 7: Confirm + +Report: +- Settings updated +- Any manual steps needed (git cleanup) +- New configuration summary diff --git a/external_plugins/bonfire/commands/document.md b/external_plugins/bonfire/commands/document.md new file mode 100644 index 0000000..4504864 --- /dev/null +++ b/external_plugins/bonfire/commands/document.md @@ -0,0 +1,114 @@ +--- +description: Create documentation about a topic in the codebase +allowed-tools: Read, Write, Bash(git:*), Task +--- + +# Document Topic + +Create reference documentation using subagent for research, preserving main context. + +## Step 1: Find Git Root + +Run `git rev-parse --show-toplevel` to locate the repository root. + +## Step 2: Check Config + +Read `/.bonfire/config.json` if it exists. + +**Docs location**: Read `docsLocation` from config. Default to `.bonfire/docs/` if not set. + +## Step 3: Understand the Topic + +The topic to document is: $ARGUMENTS + +If no topic provided, ask the user what they want documented. + +## Step 4: Explore the Codebase (Subagent) + +Use the Task tool to invoke the **codebase-explorer** subagent for research. + +Provide a research directive: + +``` +Research the codebase to document: [TOPIC] + +Find: +1. **Architecture**: How this system/feature is structured, key components +2. **Key Files**: Important files and their roles +3. **Flow**: How data/control flows through the system +4. **Patterns**: Design patterns and conventions used +5. **Gotchas**: Important details, edge cases, things to watch out for + +Return structured findings with file paths and brief descriptions. +``` + +**Wait for the subagent to return findings** before proceeding. + +The subagent runs in isolated context (haiku model, fast), preserving main context for writing. + +## Step 5: Create Documentation + +**Naming convention**: `.md` (kebab-case) + +Examples: +- `inbound-agent-architecture.md` +- `sampling-strategies.md` +- `authentication-flow.md` + +Write the documentation to `//.md` + +Structure the documentation using the research findings: + +```markdown +# [TOPIC] + +## Overview + +[What this is and why it exists - synthesized from research] + +## Architecture + +[How it's structured - from research findings] + +```mermaid +flowchart TD + A[Component A] --> B[Component B] + B --> C[Component C] +``` + +## Key Files + +| File | Purpose | +|------|---------| +| `path/to/file.ts` | [From research findings] | +| `path/to/other.ts` | [From research findings] | + +## How It Works + +[Step-by-step flow and behavior - from research] + +## Usage Examples + +[Code examples, CLI commands, etc.] + +## Gotchas + +- [From research findings] +- [Common mistakes or edge cases] + +## Related + +- [Link to related doc](other-doc.md) +- [Code reference]: `path/to/file.ts` +``` + +## Step 6: Link to Session Context + +Add a reference to the doc in `/.bonfire/index.md` under Key Resources or Notes. + +## Step 7: Confirm + +Summarize what was documented and ask if the user wants: +- More detail on any section +- Related topics documented +- To proceed with other work diff --git a/external_plugins/bonfire/commands/end.md b/external_plugins/bonfire/commands/end.md new file mode 100644 index 0000000..3283732 --- /dev/null +++ b/external_plugins/bonfire/commands/end.md @@ -0,0 +1,84 @@ +--- +description: End session - update context and commit changes +allowed-tools: Bash(git:*), Bash(rm:*), Bash(mv:*), Bash(mkdir:*), Read, Write, Glob, AskUserQuestion +model: haiku +--- + +# End Session + +## Step 1: Find Git Root + +Run `git rev-parse --show-toplevel` to locate the repository root. + +## Step 2: Review Session Work + +Review what was accomplished this session by examining: +- Recent git commits +- Files changed +- Conversation context + +## Step 3: Update Session Context + +Update `/.bonfire/index.md`: + +1. Update the session entry with: + - **Accomplished**: List what was completed + - **Decisions**: Key decisions made and rationale + - **Files Modified**: Important files changed (if relevant) + - **Blockers**: Any issues encountered + +2. Update "Next Session Priorities" based on remaining work + +3. Update "Current State" to reflect new status + +## Step 4: Manage Session Scripts + +Check if `/.bonfire/scripts/` exists and contains any files. + +**If scripts exist**, use AskUserQuestion to ask what to do with each script: + +"What should happen to these session scripts?" (Header: "Scripts", multiSelect: false) + +For each script found, present options: +- **Keep** - Leave in `.bonfire/scripts/` for next session +- **Move to project** - Move to `/scripts/` (create if needed) +- **Delete** - Remove the script + +Execute the user's choices: +- **Keep**: No action needed +- **Move to project**: `mkdir -p /scripts/ && mv