14 Commits

Author SHA1 Message Date
61907b78db chore: release v5.9.0
- Plugin installation scripts for consumer projects
- MCP server mapping via mcp_servers field in plugin.json
- CLAUDE.md section markers for install/uninstall
- Agent model selection (25 agents with model frontmatter)
- Agent frontmatter standardization

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 02:38:31 -05:00
c4037f505c Merge pull request 'fix(plugins): remove invalid mcp_servers key from plugin.json files' (#405) from fix/startup-hook-venv-cache-path into development
Reviewed-on: #405
2026-02-03 07:14:24 +00:00
dbf3fa7e0d fix(plugins): remove invalid mcp_servers key from plugin.json files
The mcp_servers key is not a valid key in the Claude plugin manifest
schema. MCP servers are configured in the root .mcp.json file instead.

Affected plugins:
- cmdb-assistant
- contract-validator
- data-platform
- pr-review
- projman
- viz-platform

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 02:13:46 -05:00
6d093e83b6 Merge pull request 'fix(hooks): add auto-symlink creation in data-platform startup hook' (#403) from fix/startup-hook-venv-cache-path into development
Reviewed-on: #403
2026-02-03 03:40:00 +00:00
13de992638 fix(hooks): add auto-symlink creation in data-platform startup hook
Note: This fix may not help because MCP servers fail BEFORE hooks run.
See lessons learned wiki page for full debug trace.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 22:38:27 -05:00
ef28f172d6 fix(plugins): sync plugin.json versions with marketplace.json
Plugin load failures were caused by version mismatch between
marketplace.json and individual plugin.json files:
- contract-validator: 1.2.0 vs 1.1.0
- git-flow: 1.2.0 vs 1.0.0
- projman: 3.4.0 vs 3.3.0
- clarity-assist: 1.2.0 vs 1.0.0
- doc-guardian: 1.1.0 vs 1.0.0

Claude Code silently fails to load plugins when versions don't match.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 22:26:24 -05:00
39556dbb59 Merge pull request 'fix(hooks): check venv cache path before marketplace path' (#401) from fix/startup-hook-venv-cache-path into development
Reviewed-on: #401
2026-02-03 03:15:00 +00:00
c9e054e013 fix(hooks): check venv cache path before marketplace path
Startup hooks in data-platform and pr-review were checking for venvs
at the marketplace path (~/.claude/plugins/marketplaces/.../mcp-servers/)
which gets wiped on updates. The actual venvs live in the cache directory
(~/.cache/claude-mcp-venvs/) which survives updates.

This caused false "MCP venv missing" errors even when venvs existed,
wasting hours of debugging time.

Fixed hooks now check cache path first, matching the pattern used
by run.sh scripts.

Also updated docs/CANONICAL-PATHS.md with the correct venv path pattern
to prevent future occurrences.

Lesson learned: lessons/patterns/startup-hooks-must-check-venv-cache-path-first

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 22:13:40 -05:00
db8fec42f2 Merge pull request 'fix(hooks): correct venv path in startup-check scripts' (#399) from fix/startup-hook-venv-paths into development
Reviewed-on: #399
2026-02-03 02:58:09 +00:00
ba1dee4553 fix(hooks): correct venv path in startup-check scripts
The startup hooks were looking for MCP venvs relative to the plugin
directory instead of the marketplace root, causing false "venv missing"
errors on every session start.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 21:56:43 -05:00
01e184b68f Merge pull request 'feat(agents): add model selection and standardize frontmatter' (#397) from fix/plugin-install-mcp-mapping into development
Reviewed-on: #397
2026-02-03 01:39:32 +00:00
c0d62f4957 feat(agents): add model selection and standardize frontmatter
Add per-agent model selection using Claude Code's now-supported `model`
frontmatter field, and standardize all agent frontmatter across the
marketplace.

Changes:
- Add `model` field to all 25 agents (18 sonnet, 7 haiku)
- Fix viz-platform/data-platform agents using `agent:` instead of `name:`
- Remove non-standard `triggers:` field from domain agents
- Add missing frontmatter to 13 agents
- Document model selection in CLAUDE.md and CONFIGURATION.md
- Fix undocumented commands in README.md

Model assignments based on reasoning depth, tool complexity, and latency:
- sonnet: Planner, Orchestrator, Executor, Coordinator, Security Reviewers
- haiku: Maintainability Auditor, Test Validator, Git Assistant, etc.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 20:37:58 -05:00
5b1dde694c Merge pull request 'fix(scripts): MCP server mapping and CLAUDE.md section markers' (#395) from fix/plugin-install-mcp-mapping into development
Reviewed-on: #395
2026-02-03 00:37:15 +00:00
eafcfe5bd1 fix(scripts): MCP server mapping and CLAUDE.md section markers
Issue 1 - MCP Server Mapping:
- Add mcp_servers field to plugin.json for plugins using shared MCP servers
- projman/pr-review now install gitea MCP server
- cmdb-assistant now installs netbox MCP server
- Scripts read MCP server names from plugin.json

Issue 2 - CLAUDE.md Section Markers:
- Install wraps content with HTML comment markers for precise removal
- Uninstall uses markers first, falls back to legacy header detection
- Fixes code block false positives during uninstall

Bug fix:
- Change ((servers_added++)) to ((++servers_added)) to avoid exit code 1
  with set -e when incrementing from 0

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 19:33:45 -05:00
42 changed files with 577 additions and 130 deletions

View File

@@ -6,7 +6,7 @@
},
"metadata": {
"description": "Project management plugins with Gitea and NetBox integrations",
"version": "5.8.0"
"version": "5.9.0"
},
"plugins": [
{

View File

@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Unreleased]
---
## [5.9.0] - 2026-02-03
### Added
#### Plugin Installation Scripts
@@ -34,6 +38,55 @@ New scripts for installing marketplace plugins into consumer projects:
**Documentation:** `docs/CONFIGURATION.md` updated with "Installing Plugins to Consumer Projects" section.
### Fixed
#### Plugin Installation Scripts — MCP Mapping & Section Markers
**MCP Server Mapping:**
- Added `mcp_servers` field to plugin.json for plugins that use shared MCP servers
- `projman` and `pr-review` now correctly install `gitea` MCP server
- `cmdb-assistant` now correctly installs `netbox` MCP server
- Scripts read MCP server names from plugin.json instead of assuming plugin name = server name
**CLAUDE.md Section Markers:**
- Install script now wraps integration content with HTML comment markers:
`<!-- BEGIN marketplace-plugin: {name} -->` and `<!-- END marketplace-plugin: {name} -->`
- Uninstall script uses markers for precise section removal (no more code block false positives)
- Backward compatible: falls back to legacy header detection for pre-marker installations
**Plugins updated with `mcp_servers` field:**
- `projman``["gitea"]`
- `pr-review``["gitea"]`
- `cmdb-assistant``["netbox"]`
- `data-platform``["data-platform"]`
- `viz-platform``["viz-platform"]`
- `contract-validator``["contract-validator"]`
#### Agent Model Selection
Per-agent model selection using Claude Code's now-supported `model` frontmatter field.
- All 25 marketplace agents assigned appropriate model (`sonnet`, `haiku`, or `inherit`)
- Model assignment based on reasoning depth, tool complexity, and latency requirements
- Documentation added to `CLAUDE.md` and `docs/CONFIGURATION.md`
**Supported values:** `sonnet` (default), `opus`, `haiku`, `inherit`
**Model assignments:**
| Model | Agent Types |
|-------|-------------|
| sonnet | Planner, Orchestrator, Executor, Code Reviewer, Coordinator, Security Reviewers, Data Advisor, Design Reviewer, etc. |
| haiku | Maintainability Auditor, Test Validator, Component Check, Theme Setup, Git Assistant, Data Ingestion, Agent Check |
### Fixed
#### Agent Frontmatter Standardization
- Fixed viz-platform and data-platform agents using non-standard `agent:` field (now `name:`)
- Removed non-standard `triggers:` field from domain agents (trigger info already in agent body)
- Added missing frontmatter to 13 agents across pr-review, viz-platform, contract-validator, clarity-assist, git-flow, doc-guardian, code-sentinel, cmdb-assistant, and data-platform
- All 25 agents now have consistent `name`, `description`, and `model` fields
---
## [5.8.0] - 2026-02-02

View File

@@ -146,7 +146,7 @@ When user says "fix the sprint-plan command", edit the SOURCE code.
## Project Overview
**Repository:** leo-claude-mktplace
**Version:** 5.8.0
**Version:** 5.9.0
**Status:** Production Ready
A plugin marketplace for Claude Code containing:
@@ -271,6 +271,40 @@ leo-claude-mktplace/
| **Executor** | Implementation-focused | Code implementation, branch management, MR creation |
| **Code Reviewer** | Thorough, practical | Pre-close quality review, security scan, test verification |
### Agent Model Selection
Agents specify their model in frontmatter using Claude Code's `model` field. Supported values: `sonnet` (default), `opus`, `haiku`, `inherit`.
| Plugin | Agent | Model | Rationale |
|--------|-------|-------|-----------|
| projman | Planner | sonnet | Architectural analysis, sprint planning |
| projman | Orchestrator | sonnet | Coordination and tool dispatch |
| projman | Executor | sonnet | Code generation and implementation |
| projman | Code Reviewer | sonnet | Quality gate, pattern detection |
| pr-review | Coordinator | sonnet | Orchestrates sub-agents, aggregates findings |
| pr-review | Security Reviewer | sonnet | Security analysis |
| pr-review | Performance Analyst | sonnet | Performance pattern detection |
| pr-review | Maintainability Auditor | haiku | Pattern matching (complexity, duplication) |
| pr-review | Test Validator | haiku | Coverage gap detection |
| data-platform | Data Advisor | sonnet | Schema validation, dbt orchestration |
| data-platform | Data Analysis | sonnet | Data exploration and profiling |
| data-platform | Data Ingestion | haiku | Data loading operations |
| viz-platform | Design Reviewer | sonnet | DMC validation + accessibility |
| viz-platform | Layout Builder | sonnet | Dashboard design guidance |
| viz-platform | Component Check | haiku | Quick component validation |
| viz-platform | Theme Setup | haiku | Theme configuration |
| contract-validator | Agent Check | haiku | Reference checking |
| contract-validator | Full Validation | sonnet | Marketplace sweep |
| code-sentinel | Security Reviewer | sonnet | Security analysis |
| code-sentinel | Refactor Advisor | sonnet | Code refactoring advice |
| doc-guardian | Doc Analyzer | sonnet | Documentation drift detection |
| clarity-assist | Clarity Coach | sonnet | Conversational coaching |
| git-flow | Git Assistant | haiku | Git operations |
| claude-config-maintainer | Maintainer | sonnet | CLAUDE.md optimization |
| cmdb-assistant | CMDB Assistant | sonnet | NetBox operations |
Override by editing the `model:` field in `plugins/{plugin}/agents/{agent}.md`.
### MCP Server Tools (Gitea)
| Category | Tools |

View File

@@ -1,4 +1,4 @@
# Leo Claude Marketplace - v5.8.0
# Leo Claude Marketplace - v5.9.0
A collection of Claude Code plugins for project management, infrastructure automation, and development workflows.
@@ -47,11 +47,11 @@ Comprehensive pull request review using specialized agents.
**Commands:** `/pr-review`, `/pr-summary`, `/pr-findings`, `/pr-diff`, `/initial-setup`, `/project-init`, `/project-sync`
#### [claude-config-maintainer](./plugins/claude-config-maintainer)
**CLAUDE.md Optimization and Maintenance**
**CLAUDE.md and Settings Optimization**
Analyze, optimize, and create CLAUDE.md configuration files for Claude Code projects.
Analyze, optimize, and create CLAUDE.md configuration files. Audit and optimize settings.local.json permissions.
**Commands:** `/config-analyze`, `/config-optimize`, `/config-init`, `/config-diff`, `/config-lint`
**Commands:** `/analyze`, `/optimize`, `/init`, `/config-diff`, `/config-lint`, `/config-audit-settings`, `/config-optimize-settings`, `/config-permissions-map`
#### [contract-validator](./plugins/contract-validator) *NEW in v5.0.0*
**Cross-Plugin Compatibility Validation**
@@ -122,7 +122,7 @@ Comprehensive data engineering toolkit with persistent DataFrame storage.
- 100k row limit with chunking support
- Auto-detection of dbt projects
**Commands:** `/ingest`, `/profile`, `/schema`, `/explain`, `/lineage`, `/lineage-viz`, `/run`, `/dbt-test`, `/data-quality`, `/initial-setup`
**Commands:** `/ingest`, `/profile`, `/schema`, `/explain`, `/lineage`, `/lineage-viz`, `/run`, `/dbt-test`, `/data-quality`, `/data-review`, `/data-gate`, `/initial-setup`
### Visualization
@@ -312,7 +312,7 @@ After installing plugins, the `/plugin` command may show `(no content)` - this i
| clarity-assist | `/clarity-assist:clarify` |
| doc-guardian | `/doc-guardian:doc-audit` |
| code-sentinel | `/code-sentinel:security-scan` |
| claude-config-maintainer | `/claude-config-maintainer:config-analyze` |
| claude-config-maintainer | `/claude-config-maintainer:analyze` |
| cmdb-assistant | `/cmdb-assistant:cmdb-search` |
| data-platform | `/data-platform:ingest` |
| viz-platform | `/viz-platform:chart` |

View File

@@ -182,10 +182,42 @@ MCP servers are **shared at repository root** and configured in `.mcp.json`.
| MCP configuration | `.mcp.json` | `.mcp.json` (at repo root) |
| Shared MCP server | `mcp-servers/{server}/` | `mcp-servers/gitea/` |
| MCP server code | `mcp-servers/{server}/mcp_server/` | `mcp-servers/gitea/mcp_server/` |
| MCP venv | `mcp-servers/{server}/.venv/` | `mcp-servers/gitea/.venv/` |
| MCP venv (local) | `mcp-servers/{server}/.venv/` | `mcp-servers/gitea/.venv/` |
**Note:** Plugins do NOT have their own `mcp-servers/` directories. All MCP servers are shared at root and configured via `.mcp.json`.
### MCP Venv Paths - CRITICAL
**Venvs live in a CACHE directory that SURVIVES marketplace updates.**
When checking for venvs, ALWAYS check in this order:
| Priority | Path | Survives Updates? |
|----------|------|-------------------|
| 1 (CHECK FIRST) | `~/.cache/claude-mcp-venvs/leo-claude-mktplace/{server}/.venv/` | YES |
| 2 (fallback) | `{marketplace}/mcp-servers/{server}/.venv/` | NO |
**Why cache first?**
- Marketplace directory gets WIPED on every update/reinstall
- Cache directory SURVIVES updates
- False "venv missing" errors waste hours of debugging
**Pattern for hooks checking venvs:**
```bash
CACHE_VENV="$HOME/.cache/claude-mcp-venvs/leo-claude-mktplace/{server}/.venv/bin/python"
LOCAL_VENV="$MARKETPLACE_ROOT/mcp-servers/{server}/.venv/bin/python"
if [[ -f "$CACHE_VENV" ]]; then
VENV_PATH="$CACHE_VENV"
elif [[ -f "$LOCAL_VENV" ]]; then
VENV_PATH="$LOCAL_VENV"
else
echo "venv missing"
fi
```
**See lesson learned:** [Startup Hooks Must Check Venv Cache Path First](https://gitea.hotserv.cloud/personal-projects/leo-claude-mktplace/wiki/lessons/patterns/startup-hooks-must-check-venv-cache-path-first)
### Documentation Paths
| Type | Location |

View File

@@ -496,6 +496,63 @@ Not all plugins have MCP servers. The install script handles this automatically:
---
## Agent Model Selection
Marketplace agents specify their preferred model using Claude Code's `model` frontmatter field. This allows cost/performance optimization per agent.
### Supported Values
| Value | Description |
|-------|-------------|
| `sonnet` | Default. Balanced performance and cost. |
| `opus` | Higher reasoning depth. Use for complex analysis. |
| `haiku` | Faster, lower cost. Use for mechanical tasks. |
| `inherit` | Use session's current model setting. |
### How It Works
Each agent in `plugins/{plugin}/agents/{agent}.md` has frontmatter like:
```yaml
---
name: planner
description: Sprint planning agent - thoughtful architecture analysis
model: sonnet
---
```
Claude Code reads this field when invoking the agent as a subagent.
### Model Assignments
Agents are assigned models based on their task complexity:
| Model | Agents | Rationale |
|-------|--------|-----------|
| **sonnet** | Planner, Orchestrator, Executor, Code Reviewer, Coordinator, Security Reviewers, Performance Analyst, Data Advisor, Data Analysis, Design Reviewer, Layout Builder, Full Validation, Doc Analyzer, Clarity Coach, Maintainer, CMDB Assistant, Refactor Advisor | Standard reasoning, tool orchestration, code generation |
| **haiku** | Maintainability Auditor, Test Validator, Component Check, Theme Setup, Agent Check, Data Ingestion, Git Assistant | Pattern matching, quick validation, mechanical tasks |
### Overriding Model Selection
**Per-agent override:** Edit the `model:` field in the agent file:
```bash
# Change executor to use opus for heavy implementation work
nano plugins/projman/agents/executor.md
# Change model: sonnet to model: opus
```
**Session-level:** Users on Opus subscription can change the agent's model to `inherit` to use whatever model the session is using.
### Best Practices
1. **Default to sonnet** - Good balance for most tasks
2. **Use haiku for speed-sensitive agents** - Sub-agents dispatched in parallel, read-only tasks
3. **Reserve opus for heavy analysis** - Only when sonnet's reasoning isn't sufficient
4. **Use inherit sparingly** - Only when you want session-level control
---
## Automatic Validation Features
### API Validation

View File

@@ -1,6 +1,6 @@
{
"name": "clarity-assist",
"version": "1.0.0",
"version": "1.2.0",
"description": "Prompt optimization and requirement clarification with ND-friendly accommodations",
"author": {
"name": "Leo Miranda",

View File

@@ -1,3 +1,9 @@
---
name: clarity-coach
description: Patient, structured coach helping users articulate requirements clearly. Uses neurodivergent-friendly communication patterns.
model: sonnet
---
# Clarity Coach Agent
## Visual Output Requirements

View File

@@ -1,6 +1,7 @@
---
name: maintainer
description: CLAUDE.md optimization and maintenance agent
model: sonnet
---
# CLAUDE.md Maintainer Agent

View File

@@ -1,3 +1,9 @@
---
name: cmdb-assistant
description: Infrastructure management assistant specialized in NetBox CMDB operations. Use for device management, IP addressing, and infrastructure queries.
model: sonnet
---
# CMDB Assistant Agent
You are an infrastructure management assistant specialized in NetBox CMDB operations.

View File

@@ -1,5 +1,7 @@
---
description: Code structure and refactoring specialist
name: refactor-advisor
description: Code structure and refactoring specialist. Use when analyzing code quality, design patterns, or planning refactoring work.
model: sonnet
---
# Refactor Advisor Agent

View File

@@ -1,6 +1,7 @@
---
name: security-reviewer
description: Security-focused code review agent
model: sonnet
---
# Security Reviewer Agent

View File

@@ -1,6 +1,6 @@
{
"name": "contract-validator",
"version": "1.1.0",
"version": "1.2.0",
"description": "Cross-plugin compatibility validation and Claude.md agent verification",
"author": {
"name": "Leo Miranda",

View File

@@ -1,6 +1,7 @@
---
name: agent-check
description: Agent definition validator for quick verification
model: haiku
---
# Agent Check Agent

View File

@@ -1,3 +1,9 @@
---
name: full-validation
description: Contract validation specialist for comprehensive cross-plugin compatibility validation of the entire marketplace.
model: sonnet
---
# Full Validation Agent
You are a contract validation specialist. Your role is to perform comprehensive cross-plugin compatibility validation for the entire marketplace.

View File

@@ -1,10 +1,7 @@
---
agent: data-advisor
description: Reviews code for data integrity, schema validity, and dbt compliance using data-platform MCP tools
triggers:
- /data-review command
- /data-gate command
- projman orchestrator domain gate
name: data-advisor
description: Reviews code for data integrity, schema validity, and dbt compliance using data-platform MCP tools. Use when validating database operations or data pipelines.
model: sonnet
---
# Data Advisor Agent

View File

@@ -1,6 +1,7 @@
---
name: data-analysis
description: Data analysis specialist for exploration and profiling
model: sonnet
---
# Data Analysis Agent

View File

@@ -1,3 +1,9 @@
---
name: data-ingestion
description: Data ingestion specialist for loading, transforming, and preparing data for analysis.
model: haiku
---
# Data Ingestion Agent
You are a data ingestion specialist. Your role is to help users load, transform, and prepare data for analysis.

View File

@@ -5,11 +5,26 @@
PREFIX="[data-platform]"
# Check if MCP venv exists
# Check if MCP venv exists - check cache first, then local
CACHE_VENV="$HOME/.cache/claude-mcp-venvs/leo-claude-mktplace/data-platform/.venv/bin/python"
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(dirname "$(dirname "$(realpath "$0")")")}"
VENV_PATH="$PLUGIN_ROOT/mcp-servers/data-platform/.venv/bin/python"
MARKETPLACE_ROOT="$(dirname "$(dirname "$PLUGIN_ROOT")")"
LOCAL_VENV="$MARKETPLACE_ROOT/mcp-servers/data-platform/.venv/bin/python"
if [[ ! -f "$VENV_PATH" ]]; then
# Check cache first (preferred), then local symlink
CACHE_VENV_DIR="$HOME/.cache/claude-mcp-venvs/leo-claude-mktplace/data-platform/.venv"
LOCAL_VENV_DIR="$MARKETPLACE_ROOT/mcp-servers/data-platform/.venv"
if [[ -f "$CACHE_VENV" ]]; then
VENV_PATH="$CACHE_VENV"
# Auto-create symlink in installed marketplace if missing
if [[ ! -e "$LOCAL_VENV_DIR" && -d "$CACHE_VENV_DIR" ]]; then
mkdir -p "$(dirname "$LOCAL_VENV_DIR")" 2>/dev/null
ln -sf "$CACHE_VENV_DIR" "$LOCAL_VENV_DIR" 2>/dev/null
fi
elif [[ -f "$LOCAL_VENV" ]]; then
VENV_PATH="$LOCAL_VENV"
else
echo "$PREFIX MCP venv missing - run /initial-setup or setup.sh"
exit 0
fi

View File

@@ -1,7 +1,7 @@
{
"name": "doc-guardian",
"description": "Automatic documentation drift detection and synchronization",
"version": "1.0.0",
"version": "1.1.0",
"author": {
"name": "Leo Miranda",
"email": "leobmiranda@gmail.com"

View File

@@ -1,5 +1,7 @@
---
description: Specialized agent for documentation analysis and drift detection
name: doc-analyzer
description: Specialized agent for documentation analysis and drift detection. Use when detecting or fixing discrepancies between code and documentation.
model: sonnet
---
# Documentation Analyzer Agent

View File

@@ -1,6 +1,6 @@
{
"name": "git-flow",
"version": "1.0.0",
"version": "1.2.0",
"description": "Git workflow automation with intelligent commit messages and branch management",
"author": {
"name": "Leo Miranda",

View File

@@ -1,3 +1,9 @@
---
name: git-assistant
description: Git workflow assistant for complex git operations, conflict resolution, and repository history management.
model: haiku
---
# Git Assistant Agent
## Visual Output Requirements

View File

@@ -1,3 +1,9 @@
---
name: coordinator
description: Review coordinator that orchestrates the multi-agent PR review process. Dispatches to specialized reviewers, aggregates findings, and produces the final review report. Use proactively after code changes.
model: sonnet
---
# Coordinator Agent
## Visual Output Requirements

View File

@@ -1,3 +1,9 @@
---
name: maintainability-auditor
description: Identifies code complexity, duplication, naming issues, and architecture concerns in PR changes.
model: haiku
---
# Maintainability Auditor Agent
## Visual Output Requirements

View File

@@ -1,3 +1,9 @@
---
name: performance-analyst
description: Performance-focused code reviewer that identifies performance issues, inefficiencies, and optimization opportunities.
model: sonnet
---
# Performance Analyst Agent
## Visual Output Requirements

View File

@@ -1,6 +1,7 @@
---
name: security-reviewer
description: Security-focused code reviewer for PR analysis
model: sonnet
---
# Security Reviewer Agent

View File

@@ -1,3 +1,9 @@
---
name: test-validator
description: Test quality reviewer that validates test coverage, test quality, and testing practices in PR changes.
model: haiku
---
# Test Validator Agent
## Visual Output Requirements

View File

@@ -5,11 +5,18 @@
PREFIX="[pr-review]"
# Check if MCP venv exists
# Check if MCP venv exists - check cache first, then local
CACHE_VENV="$HOME/.cache/claude-mcp-venvs/leo-claude-mktplace/gitea/.venv/bin/python"
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(dirname "$(dirname "$(realpath "$0")")")}"
VENV_PATH="$PLUGIN_ROOT/mcp-servers/gitea/.venv/bin/python"
MARKETPLACE_ROOT="$(dirname "$(dirname "$PLUGIN_ROOT")")"
LOCAL_VENV="$MARKETPLACE_ROOT/mcp-servers/gitea/.venv/bin/python"
if [[ ! -f "$VENV_PATH" ]]; then
# Check cache first (preferred), then local
if [[ -f "$CACHE_VENV" ]]; then
VENV_PATH="$CACHE_VENV"
elif [[ -f "$LOCAL_VENV" ]]; then
VENV_PATH="$LOCAL_VENV"
else
echo "$PREFIX MCP venvs missing - run setup.sh from installed marketplace"
exit 0
fi

View File

@@ -1,6 +1,6 @@
{
"name": "projman",
"version": "3.3.0",
"version": "3.4.0",
"description": "Sprint planning and project management with Gitea integration",
"author": {
"name": "Leo Miranda",

View File

@@ -1,6 +1,7 @@
---
name: code-reviewer
description: Pre-sprint code quality review agent
model: sonnet
---
# Code Reviewer Agent

View File

@@ -1,6 +1,7 @@
---
name: executor
description: Implementation executor agent - precise implementation guidance and code quality
model: sonnet
---
# Implementation Executor Agent

View File

@@ -1,6 +1,7 @@
---
name: orchestrator
description: Sprint orchestration agent - coordinates execution and tracks progress
model: sonnet
---
# Sprint Orchestration Agent

View File

@@ -1,6 +1,7 @@
---
name: planner
description: Sprint planning agent - thoughtful architecture analysis and issue creation
model: sonnet
---
# Sprint Planning Agent

View File

@@ -29,17 +29,19 @@ if [[ -f ".env" ]]; then
if [[ -n "$GITEA_API_URL" && -n "$GITEA_API_TOKEN" && -n "$GITEA_REPO" ]]; then
# Quick check for open issues without milestone (unplanned work)
# Note: grep -c returns 0 on no match but exits non-zero, causing || to also fire
# Use subshell to ensure single value
OPEN_ISSUES=$(curl -s -m 5 \
-H "Authorization: token $GITEA_API_TOKEN" \
"${GITEA_API_URL}/repos/${GITEA_REPO}/issues?state=open&milestone=none&limit=1" 2>/dev/null | \
grep -c '"number"' || echo "0")
grep -c '"number"' 2>/dev/null) || OPEN_ISSUES=0
if [[ "$OPEN_ISSUES" -gt 0 ]]; then
# Count total unplanned issues
TOTAL_UNPLANNED=$(curl -s -m 5 \
-H "Authorization: token $GITEA_API_TOKEN" \
"${GITEA_API_URL}/repos/${GITEA_REPO}/issues?state=open&milestone=none" 2>/dev/null | \
grep -c '"number"' || echo "?")
grep -c '"number"' 2>/dev/null) || TOTAL_UNPLANNED="?"
echo "$PREFIX ${TOTAL_UNPLANNED} open issues without milestone - consider /sprint-plan"
fi
fi

View File

@@ -1,6 +1,7 @@
---
name: component-check
description: DMC component validation specialist
model: haiku
---
# Component Check Agent

View File

@@ -1,10 +1,7 @@
---
agent: design-reviewer
description: Reviews code for design system compliance using viz-platform MCP tools
triggers:
- /design-review command
- /design-gate command
- projman orchestrator domain gate
name: design-reviewer
description: Reviews code for design system compliance using viz-platform MCP tools. Use when validating DMC components, theme tokens, or accessibility standards.
model: sonnet
---
# Design Reviewer Agent

View File

@@ -1,3 +1,9 @@
---
name: layout-builder
description: Practical dashboard layout specialist for creating well-structured layouts with filtering, grid systems, and responsive design.
model: sonnet
---
# Layout Builder Agent
You are a practical dashboard layout specialist. Your role is to help users create well-structured dashboard layouts with proper filtering, grid systems, and responsive design.

View File

@@ -1,3 +1,9 @@
---
name: theme-setup
description: Design-focused theme setup specialist for creating consistent, brand-aligned themes for Dash Mantine Components applications.
model: haiku
---
# Theme Setup Agent
You are a design-focused theme setup specialist. Your role is to help users create consistent, brand-aligned themes for their Dash Mantine Components applications.

View File

@@ -7,7 +7,7 @@
#
# This script:
# 1. Validates plugin exists in the marketplace
# 2. Updates target project's .mcp.json with MCP server entry (if applicable)
# 2. Updates target project's .mcp.json with MCP server entries (if applicable)
# 3. Appends CLAUDE.md integration snippet to target project
# 4. Is idempotent (safe to run multiple times)
#
@@ -39,6 +39,7 @@ log_warning() { echo -e "${YELLOW}[WARN]${NC} $1"; }
# --- Track Changes ---
CHANGES_MADE=()
SKIPPED=()
MCP_SERVERS_INSTALLED=()
# --- Usage ---
usage() {
@@ -114,15 +115,28 @@ validate_target() {
fi
}
# --- Check if MCP Server Exists for Plugin ---
has_mcp_server() {
# --- Get MCP Servers for Plugin ---
# Reads the mcp_servers array from plugin.json
# Returns newline-separated list of MCP server names, or empty if none
get_mcp_servers() {
local plugin_name="$1"
local mcp_dir="$REPO_ROOT/mcp-servers/$plugin_name"
local plugin_json="$REPO_ROOT/plugins/$plugin_name/.claude-plugin/plugin.json"
if [[ -d "$mcp_dir" && -f "$mcp_dir/run.sh" ]]; then
return 0
if [[ ! -f "$plugin_json" ]]; then
return
fi
return 1
# Read mcp_servers array from plugin.json
# Returns empty if field doesn't exist or is empty
jq -r '.mcp_servers // [] | .[]' "$plugin_json" 2>/dev/null || true
}
# --- Check if plugin has any MCP servers ---
has_mcp_servers() {
local plugin_name="$1"
local servers
servers=$(get_mcp_servers "$plugin_name")
[[ -n "$servers" ]]
}
# --- Update .mcp.json ---
@@ -130,12 +144,14 @@ update_mcp_json() {
local plugin_name="$1"
local target_path="$2"
local mcp_json="$target_path/.mcp.json"
local mcp_server_path="$REPO_ROOT/mcp-servers/$plugin_name/run.sh"
# Check if plugin has MCP server
if ! has_mcp_server "$plugin_name"; then
log_skip "Plugin '$plugin_name' has no MCP server - skipping .mcp.json update"
SKIPPED+=(".mcp.json: No MCP server for $plugin_name")
# Get MCP servers for this plugin
local mcp_servers
mcp_servers=$(get_mcp_servers "$plugin_name")
if [[ -z "$mcp_servers" ]]; then
log_skip "Plugin '$plugin_name' has no MCP servers - skipping .mcp.json update"
SKIPPED+=(".mcp.json: No MCP servers for $plugin_name")
return 0
fi
@@ -146,21 +162,37 @@ update_mcp_json() {
CHANGES_MADE+=("Created .mcp.json")
fi
# Check if entry already exists
if jq -e ".mcpServers[\"$plugin_name\"]" "$mcp_json" > /dev/null 2>&1; then
log_skip "MCP server '$plugin_name' already in .mcp.json"
SKIPPED+=(".mcp.json: $plugin_name already present")
return 0
fi
# Add each MCP server
local servers_added=0
while IFS= read -r server_name; do
[[ -z "$server_name" ]] && continue
# Add MCP server entry
log_info "Adding MCP server '$plugin_name' to .mcp.json"
local tmp_file=$(mktemp)
jq ".mcpServers[\"$plugin_name\"] = {\"command\": \"$mcp_server_path\", \"args\": []}" "$mcp_json" > "$tmp_file"
mv "$tmp_file" "$mcp_json"
local mcp_server_path="$REPO_ROOT/mcp-servers/$server_name/run.sh"
CHANGES_MADE+=("Added $plugin_name to .mcp.json")
log_success "Added MCP server entry for '$plugin_name'"
# Verify server exists
if [[ ! -f "$mcp_server_path" ]]; then
log_warning "MCP server '$server_name' not found at $mcp_server_path"
continue
fi
# Check if entry already exists
if jq -e ".mcpServers[\"$server_name\"]" "$mcp_json" > /dev/null 2>&1; then
log_skip "MCP server '$server_name' already in .mcp.json"
SKIPPED+=(".mcp.json: $server_name already present")
continue
fi
# Add MCP server entry
log_info "Adding MCP server '$server_name' to .mcp.json"
local tmp_file=$(mktemp)
jq ".mcpServers[\"$server_name\"] = {\"command\": \"$mcp_server_path\", \"args\": []}" "$mcp_json" > "$tmp_file"
mv "$tmp_file" "$mcp_json"
CHANGES_MADE+=("Added $server_name to .mcp.json")
MCP_SERVERS_INSTALLED+=("$server_name")
log_success "Added MCP server entry for '$server_name'"
((++servers_added))
done <<< "$mcp_servers"
}
# --- Update CLAUDE.md ---
@@ -189,22 +221,25 @@ EOF
CHANGES_MADE+=("Created CLAUDE.md")
fi
# Read integration content
local integration_content
integration_content=$(cat "$integration_file")
# Extract the first line (# header) to use as marker for detection
local header_marker
header_marker=$(head -1 "$integration_file")
# Check if already integrated - look for the integration file's header
# Handles both formats: "# {name} Plugin - CLAUDE.md Integration" and "# {name} CLAUDE.md Integration"
if grep -qE "^# ${plugin_name}( Plugin)? -? ?CLAUDE\.md Integration" "$target_claude_md" 2>/dev/null; then
# Check if already integrated using HTML comment marker (preferred)
local begin_marker="<!-- BEGIN marketplace-plugin: $plugin_name -->"
if grep -qF "$begin_marker" "$target_claude_md" 2>/dev/null; then
log_skip "Plugin '$plugin_name' integration already in CLAUDE.md"
SKIPPED+=("CLAUDE.md: $plugin_name already present")
return 0
fi
# Fallback: check for legacy header format (backward compatibility)
if grep -qE "^# ${plugin_name}( Plugin)? -? ?CLAUDE\.md Integration" "$target_claude_md" 2>/dev/null; then
log_skip "Plugin '$plugin_name' integration already in CLAUDE.md (legacy format)"
SKIPPED+=("CLAUDE.md: $plugin_name already present")
return 0
fi
# Read integration content
local integration_content
integration_content=$(cat "$integration_file")
# Check for or create Marketplace Plugin Integration section
local section_header="## Marketplace Plugin Integration"
@@ -217,12 +252,18 @@ EOF
echo "" >> "$target_claude_md"
fi
# Append integration content
# Append integration content with HTML comment markers
log_info "Adding '$plugin_name' integration to CLAUDE.md"
local end_marker="<!-- END marketplace-plugin: $plugin_name -->"
echo "" >> "$target_claude_md"
echo "---" >> "$target_claude_md"
echo "" >> "$target_claude_md"
echo "$begin_marker" >> "$target_claude_md"
echo "" >> "$target_claude_md"
echo "$integration_content" >> "$target_claude_md"
echo "" >> "$target_claude_md"
echo "$end_marker" >> "$target_claude_md"
CHANGES_MADE+=("Added $plugin_name integration to CLAUDE.md")
log_success "Added CLAUDE.md integration for '$plugin_name'"
@@ -287,8 +328,14 @@ print_summary() {
fi
echo ""
# MCP tools reminder
if has_mcp_server "$plugin_name"; then
# MCP servers info
if [[ ${#MCP_SERVERS_INSTALLED[@]} -gt 0 ]]; then
echo -e "${CYAN}MCP Servers Installed:${NC}"
for server in "${MCP_SERVERS_INSTALLED[@]}"; do
echo " - $server"
done
echo ""
elif has_mcp_servers "$plugin_name"; then
echo -e "${CYAN}MCP Tools:${NC}"
echo " This plugin includes MCP server tools. Use ToolSearch to discover them."
echo ""

View File

@@ -67,13 +67,25 @@ get_available_plugins() {
done
}
# --- Get Plugins with MCP Servers ---
get_mcp_plugins() {
for dir in "$REPO_ROOT"/mcp-servers/*/; do
if [[ -d "$dir" && -f "$dir/run.sh" ]]; then
basename "$dir"
fi
done
# --- Get MCP Servers for Plugin ---
# Reads the mcp_servers array from plugin.json
get_mcp_servers() {
local plugin_name="$1"
local plugin_json="$REPO_ROOT/plugins/$plugin_name/.claude-plugin/plugin.json"
if [[ ! -f "$plugin_json" ]]; then
return
fi
jq -r '.mcp_servers // [] | .[]' "$plugin_json" 2>/dev/null || true
}
# --- Check if plugin has any MCP servers defined ---
has_mcp_servers() {
local plugin_name="$1"
local servers
servers=$(get_mcp_servers "$plugin_name")
[[ -n "$servers" ]]
}
# --- Check MCP Installation ---
@@ -86,18 +98,28 @@ check_mcp_installed() {
return 1
fi
# Check if this plugin's MCP server is referenced
if jq -e ".mcpServers[\"$plugin_name\"]" "$mcp_json" > /dev/null 2>&1; then
# Get MCP servers for this plugin from plugin.json
local mcp_servers
mcp_servers=$(get_mcp_servers "$plugin_name")
if [[ -z "$mcp_servers" ]]; then
# Plugin has no MCP servers defined, so MCP check passes
return 0
fi
# Also check if any entry points to this marketplace's mcp-servers
if grep -q "leo-claude-mktplace.*mcp-servers/$plugin_name" "$mcp_json" 2>/dev/null || \
grep -q "claude-plugins-work.*mcp-servers/$plugin_name" "$mcp_json" 2>/dev/null; then
return 0
fi
# Check if ALL required MCP servers are present
while IFS= read -r server_name; do
[[ -z "$server_name" ]] && continue
return 1
if ! jq -e ".mcpServers[\"$server_name\"]" "$mcp_json" > /dev/null 2>&1; then
# Also check if any entry points to this marketplace's mcp-servers
if ! grep -q "mcp-servers/$server_name" "$mcp_json" 2>/dev/null; then
return 1
fi
fi
done <<< "$mcp_servers"
return 0
}
# --- Check CLAUDE.md Integration ---
@@ -110,11 +132,13 @@ check_claude_md_installed() {
return 1
fi
# Look for plugin-specific headers that install-plugin.sh adds
# Formats vary by plugin:
# "# {plugin-name} Plugin - CLAUDE.md Integration"
# "# {plugin-name} CLAUDE.md Integration"
# Use regex to match both patterns
# Check for HTML comment marker (preferred, new format)
local begin_marker="<!-- BEGIN marketplace-plugin: $plugin_name -->"
if grep -qF "$begin_marker" "$target_claude_md" 2>/dev/null; then
return 0
fi
# Fallback: check for legacy header format
if grep -qE "^# ${plugin_name}( Plugin)? -? ?CLAUDE\.md Integration" "$target_claude_md" 2>/dev/null; then
return 0
fi
@@ -185,15 +209,15 @@ NOT_INSTALLED=()
for plugin in $(get_available_plugins); do
mcp_installed=false
claude_installed=false
has_mcp_server=false
needs_mcp=false
# Check if plugin has MCP server
if [[ -d "$REPO_ROOT/mcp-servers/$plugin" ]]; then
has_mcp_server=true
# Check if plugin has MCP servers defined
if has_mcp_servers "$plugin"; then
needs_mcp=true
fi
# Check MCP installation (only if plugin has MCP server)
if $has_mcp_server && check_mcp_installed "$plugin" "$TARGET_PATH"; then
# Check MCP installation
if check_mcp_installed "$plugin" "$TARGET_PATH"; then
mcp_installed=true
INSTALLED_MCP[$plugin]=true
fi
@@ -205,19 +229,20 @@ for plugin in $(get_available_plugins); do
fi
# Categorize
if $mcp_installed || $claude_installed; then
if $has_mcp_server; then
if $mcp_installed && $claude_installed; then
if $claude_installed; then
if $needs_mcp; then
if $mcp_installed; then
INSTALLED_PLUGINS+=("$plugin")
else
PARTIAL_PLUGINS+=("$plugin")
fi
else
# Plugins without MCP servers just need CLAUDE.md
if $claude_installed; then
INSTALLED_PLUGINS+=("$plugin")
fi
INSTALLED_PLUGINS+=("$plugin")
fi
elif $mcp_installed && $needs_mcp; then
# Has MCP but missing CLAUDE.md
PARTIAL_PLUGINS+=("$plugin")
else
NOT_INSTALLED+=("$plugin")
fi
@@ -247,7 +272,11 @@ if [[ ${#PARTIAL_PLUGINS[@]} -gt 0 ]]; then
if [[ -v INSTALLED_MCP[$plugin] ]]; then
echo " ✓ MCP server configured in .mcp.json"
else
echo " ✗ MCP server NOT in .mcp.json"
# Show which MCP servers are missing
mcp_servers=$(get_mcp_servers "$plugin")
if [[ -n "$mcp_servers" ]]; then
echo " ✗ MCP server(s) NOT in .mcp.json: $mcp_servers"
fi
fi
if [[ -v INSTALLED_CLAUDE_MD[$plugin] ]]; then
echo " ✓ Integration in CLAUDE.md"

View File

@@ -6,7 +6,7 @@
# Usage: ./scripts/uninstall-plugin.sh <plugin-name> <target-project-path>
#
# This script:
# 1. Removes MCP server entry from target project's .mcp.json
# 1. Removes MCP server entries from target project's .mcp.json
# 2. Removes CLAUDE.md integration section for the plugin
# 3. Is idempotent (safe to run multiple times)
#
@@ -76,6 +76,22 @@ validate_target() {
log_success "Target project found: $target_path"
}
# --- Get MCP Servers for Plugin ---
# Reads the mcp_servers array from plugin.json
# Returns newline-separated list of MCP server names, or empty if none
get_mcp_servers() {
local plugin_name="$1"
local plugin_json="$REPO_ROOT/plugins/$plugin_name/.claude-plugin/plugin.json"
if [[ ! -f "$plugin_json" ]]; then
return
fi
# Read mcp_servers array from plugin.json
# Returns empty if field doesn't exist or is empty
jq -r '.mcp_servers // [] | .[]' "$plugin_json" 2>/dev/null || true
}
# --- Remove from .mcp.json ---
remove_from_mcp_json() {
local plugin_name="$1"
@@ -89,21 +105,48 @@ remove_from_mcp_json() {
return 0
fi
# Check if entry exists
if ! jq -e ".mcpServers[\"$plugin_name\"]" "$mcp_json" > /dev/null 2>&1; then
log_skip "MCP server '$plugin_name' not in .mcp.json"
SKIPPED+=(".mcp.json: $plugin_name not present")
# Get MCP servers for this plugin
local mcp_servers
mcp_servers=$(get_mcp_servers "$plugin_name")
if [[ -z "$mcp_servers" ]]; then
# Fallback: try to remove entry with plugin name (backward compatibility)
if jq -e ".mcpServers[\"$plugin_name\"]" "$mcp_json" > /dev/null 2>&1; then
log_info "Removing MCP server '$plugin_name' from .mcp.json"
local tmp_file=$(mktemp)
jq "del(.mcpServers[\"$plugin_name\"])" "$mcp_json" > "$tmp_file"
mv "$tmp_file" "$mcp_json"
CHANGES_MADE+=("Removed $plugin_name from .mcp.json")
log_success "Removed MCP server entry for '$plugin_name'"
else
log_skip "Plugin '$plugin_name' has no MCP servers configured"
SKIPPED+=(".mcp.json: No MCP servers for $plugin_name")
fi
return 0
fi
# Remove MCP server entry
log_info "Removing MCP server '$plugin_name' from .mcp.json"
local tmp_file=$(mktemp)
jq "del(.mcpServers[\"$plugin_name\"])" "$mcp_json" > "$tmp_file"
mv "$tmp_file" "$mcp_json"
# Remove each MCP server
local servers_removed=0
while IFS= read -r server_name; do
[[ -z "$server_name" ]] && continue
CHANGES_MADE+=("Removed $plugin_name from .mcp.json")
log_success "Removed MCP server entry for '$plugin_name'"
# Check if entry exists
if ! jq -e ".mcpServers[\"$server_name\"]" "$mcp_json" > /dev/null 2>&1; then
log_skip "MCP server '$server_name' not in .mcp.json"
SKIPPED+=(".mcp.json: $server_name not present")
continue
fi
# Remove MCP server entry
log_info "Removing MCP server '$server_name' from .mcp.json"
local tmp_file=$(mktemp)
jq "del(.mcpServers[\"$server_name\"])" "$mcp_json" > "$tmp_file"
mv "$tmp_file" "$mcp_json"
CHANGES_MADE+=("Removed $server_name from .mcp.json")
log_success "Removed MCP server entry for '$server_name'"
((++servers_removed))
done <<< "$mcp_servers"
}
# --- Remove from CLAUDE.md ---
@@ -119,8 +162,64 @@ remove_from_claude_md() {
return 0
fi
# Look for the plugin section header (handles multiple formats)
# Formats: "# {plugin-name} Plugin - CLAUDE.md Integration" or "# {plugin-name} CLAUDE.md Integration"
# Try HTML comment markers first (preferred method)
local begin_marker="<!-- BEGIN marketplace-plugin: $plugin_name -->"
local end_marker="<!-- END marketplace-plugin: $plugin_name -->"
if grep -qF "$begin_marker" "$target_claude_md" 2>/dev/null; then
log_info "Removing '$plugin_name' section from CLAUDE.md (using markers)"
# Remove everything between markers (inclusive) and preceding ---
local tmp_file=$(mktemp)
awk -v begin="$begin_marker" -v end="$end_marker" '
BEGIN { skip = 0; prev_hr = 0; buffer = "" }
{
is_hr = /^---[[:space:]]*$/
if ($0 == begin) {
skip = 1
# If previous line was ---, dont print it
if (prev_hr) {
buffer = ""
}
next
}
if (skip) {
if ($0 == end) {
skip = 0
}
next
}
# Print buffered content
if (buffer != "") {
print buffer
}
# Buffer current line (in case its --- before a marker)
buffer = $0
prev_hr = is_hr
}
END {
# Print final buffered content
if (buffer != "") {
print buffer
}
}
' "$target_claude_md" > "$tmp_file"
# Clean up multiple consecutive blank lines
awk 'NF{blank=0} !NF{blank++} blank<=2' "$tmp_file" > "${tmp_file}.clean"
mv "${tmp_file}.clean" "$target_claude_md"
rm -f "$tmp_file"
CHANGES_MADE+=("Removed $plugin_name section from CLAUDE.md")
log_success "Removed CLAUDE.md section for '$plugin_name'"
return 0
fi
# Fallback: try legacy header-based detection
local section_header
section_header=$(grep -E "^# ${plugin_name}( Plugin)? -? ?CLAUDE\.md Integration" "$target_claude_md" 2>/dev/null | head -1)
@@ -130,10 +229,9 @@ remove_from_claude_md() {
return 0
fi
log_info "Removing '$plugin_name' section from CLAUDE.md"
log_info "Removing '$plugin_name' section from CLAUDE.md (legacy format)"
# Create temp file and use awk to remove section
# Remove from header to next "---" divider or next plugin header
local tmp_file=$(mktemp)
awk -v header="$section_header" '
@@ -155,25 +253,24 @@ remove_from_claude_md() {
is_hr = /^---[[:space:]]*$/ && !in_code_block
# Check if this is a new plugin section header (only outside code blocks)
# Patterns: "# {name} Plugin - CLAUDE.md Integration" or "# {name} CLAUDE.md Integration"
is_new_plugin_section = /^# [a-z-]+( Plugin)? -? ?CLAUDE\.md Integration/ && !in_code_block && $0 != header
# Check for HTML marker (new format)
is_begin_marker = /^<!-- BEGIN marketplace-plugin:/ && !in_code_block
if (skip) {
# Stop skipping when we hit --- (outside code block) or a new plugin section
# Stop skipping when we hit --- or a new section
if (is_hr) {
# This --- ends the section we are removing, skip it too
skip = 0
next
}
if (is_new_plugin_section) {
# New plugin section starts, stop skipping and print it
if (is_new_plugin_section || is_begin_marker) {
skip = 0
print
}
next
}
# Not skipping - print the line
print
}
END { if (!found) exit 1 }