diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 1293baf..aaea0c4 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -20,7 +20,6 @@ }, "homepage": "https://gitea.hotserv.cloud/personal-projects/leo-claude-mktplace/src/branch/main/plugins/projman/README.md", "repository": "https://gitea.hotserv.cloud/personal-projects/leo-claude-mktplace.git", - "mcpServers": ["./.mcp.json"], "category": "development", "tags": ["sprint", "agile", "gitea", "project-management"], "license": "MIT" @@ -84,7 +83,6 @@ }, "homepage": "https://gitea.hotserv.cloud/personal-projects/leo-claude-mktplace/src/branch/main/plugins/cmdb-assistant/README.md", "repository": "https://gitea.hotserv.cloud/personal-projects/leo-claude-mktplace.git", - "mcpServers": ["./.mcp.json"], "category": "infrastructure", "tags": ["cmdb", "netbox", "dcim", "ipam", "data-quality", "validation"], "license": "MIT" @@ -145,7 +143,6 @@ }, "homepage": "https://gitea.hotserv.cloud/personal-projects/leo-claude-mktplace/src/branch/main/plugins/pr-review/README.md", "repository": "https://gitea.hotserv.cloud/personal-projects/leo-claude-mktplace.git", - "mcpServers": ["./.mcp.json"], "category": "development", "tags": ["code-review", "pull-requests", "security", "quality"], "license": "MIT" @@ -161,7 +158,6 @@ }, "homepage": "https://gitea.hotserv.cloud/personal-projects/leo-claude-mktplace/src/branch/main/plugins/data-platform/README.md", "repository": "https://gitea.hotserv.cloud/personal-projects/leo-claude-mktplace.git", - "mcpServers": ["./.mcp.json"], "category": "data", "tags": ["pandas", "postgresql", "postgis", "dbt", "data-engineering", "etl"], "license": "MIT" @@ -177,7 +173,6 @@ }, "homepage": "https://gitea.hotserv.cloud/personal-projects/leo-claude-mktplace/src/branch/main/plugins/viz-platform/README.md", "repository": "https://gitea.hotserv.cloud/personal-projects/leo-claude-mktplace.git", - "mcpServers": ["./.mcp.json"], "category": "visualization", "tags": ["dash", "plotly", "mantine", "charts", "dashboards", "theming", "dmc"], "license": "MIT" @@ -193,7 +188,6 @@ }, "homepage": "https://gitea.hotserv.cloud/personal-projects/leo-claude-mktplace/src/branch/main/plugins/contract-validator/README.md", "repository": "https://gitea.hotserv.cloud/personal-projects/leo-claude-mktplace.git", - "mcpServers": ["./.mcp.json"], "category": "development", "tags": ["validation", "contracts", "compatibility", "agents", "interfaces", "cross-plugin"], "license": "MIT" diff --git a/plugins/cmdb-assistant/.claude-plugin/plugin.json b/plugins/cmdb-assistant/.claude-plugin/plugin.json index bff85eb..801eb77 100644 --- a/plugins/cmdb-assistant/.claude-plugin/plugin.json +++ b/plugins/cmdb-assistant/.claude-plugin/plugin.json @@ -19,6 +19,5 @@ "data-quality", "validation" ], - "commands": ["./commands/"], - "mcpServers": ["./.mcp.json"] + "commands": ["./commands/"] } diff --git a/plugins/contract-validator/.claude-plugin/plugin.json b/plugins/contract-validator/.claude-plugin/plugin.json index d859b8e..e42e775 100644 --- a/plugins/contract-validator/.claude-plugin/plugin.json +++ b/plugins/contract-validator/.claude-plugin/plugin.json @@ -18,6 +18,5 @@ "interfaces", "cross-plugin" ], - "commands": ["./commands/"], - "mcpServers": ["./.mcp.json"] + "commands": ["./commands/"] } diff --git a/plugins/data-platform/.claude-plugin/plugin.json b/plugins/data-platform/.claude-plugin/plugin.json index 2d1f223..29e0402 100644 --- a/plugins/data-platform/.claude-plugin/plugin.json +++ b/plugins/data-platform/.claude-plugin/plugin.json @@ -19,6 +19,5 @@ "etl", "dataframe" ], - "commands": ["./commands/"], - "mcpServers": ["./.mcp.json"] + "commands": ["./commands/"] } diff --git a/plugins/pr-review/.claude-plugin/plugin.json b/plugins/pr-review/.claude-plugin/plugin.json index 3339a3c..71b6f34 100644 --- a/plugins/pr-review/.claude-plugin/plugin.json +++ b/plugins/pr-review/.claude-plugin/plugin.json @@ -17,6 +17,5 @@ "performance", "multi-agent" ], - "commands": ["./commands/"], - "mcpServers": ["./.mcp.json"] + "commands": ["./commands/"] } diff --git a/plugins/projman/.claude-plugin/plugin.json b/plugins/projman/.claude-plugin/plugin.json index 31ab203..9597da0 100644 --- a/plugins/projman/.claude-plugin/plugin.json +++ b/plugins/projman/.claude-plugin/plugin.json @@ -17,6 +17,5 @@ "agile", "lessons-learned" ], - "commands": ["./commands/"], - "mcpServers": ["./.mcp.json"] + "commands": ["./commands/"] } diff --git a/plugins/viz-platform/.claude-plugin/plugin.json b/plugins/viz-platform/.claude-plugin/plugin.json index c08b6e0..c343af8 100644 --- a/plugins/viz-platform/.claude-plugin/plugin.json +++ b/plugins/viz-platform/.claude-plugin/plugin.json @@ -20,6 +20,5 @@ "visualization", "dmc" ], - "commands": ["./commands/"], - "mcpServers": ["./.mcp.json"] + "commands": ["./commands/"] } diff --git a/scripts/validate-marketplace.sh b/scripts/validate-marketplace.sh index c97249a..f64bba5 100755 --- a/scripts/validate-marketplace.sh +++ b/scripts/validate-marketplace.sh @@ -158,9 +158,106 @@ for plugin_dir in "$PLUGINS_DIR"/*/; do echo "WARNING: Missing README.md in $plugin_name/" fi + # CRITICAL: Validate file references exist (mcpServers, hooks, commands) + # This prevents broken references that silently break plugin loading + + # Check mcpServers references + mcp_servers=$(jq -r '.mcpServers // [] | .[]' "$plugin_json" 2>/dev/null) + for mcp_ref in $mcp_servers; do + mcp_path="$plugin_dir/$mcp_ref" + if [[ ! -f "$mcp_path" ]]; then + echo "ERROR: BROKEN REFERENCE in $plugin_name/plugin.json" + echo " mcpServers references '$mcp_ref' but file does not exist at:" + echo " $mcp_path" + echo "" + echo " FIX: Either create the file or remove the mcpServers entry" + exit 1 + fi + echo " ✓ mcpServers reference: $mcp_ref exists" + done + + # Check hooks references (can be array of file paths OR object with handlers) + hooks_type=$(jq -r '.hooks | type' "$plugin_json" 2>/dev/null) + if [[ "$hooks_type" == "array" ]]; then + # Array format: ["./hooks/hooks.json"] + hooks=$(jq -r '.hooks[]' "$plugin_json" 2>/dev/null) + for hook_ref in $hooks; do + hook_path="$plugin_dir/$hook_ref" + if [[ ! -f "$hook_path" ]]; then + echo "ERROR: BROKEN REFERENCE in $plugin_name/plugin.json" + echo " hooks references '$hook_ref' but file does not exist at:" + echo " $hook_path" + echo "" + echo " FIX: Either create the file or remove the hooks entry" + exit 1 + fi + echo " ✓ hooks reference: $hook_ref exists" + done + elif [[ "$hooks_type" == "object" ]]; then + # Object format: { "PostToolUse": [...] } - inline hooks, no file reference to validate + echo " ✓ hooks: inline object format (no file references)" + fi + + # Check commands directory references + commands=$(jq -r '.commands // [] | .[]' "$plugin_json" 2>/dev/null) + for cmd_ref in $commands; do + cmd_path="$plugin_dir/$cmd_ref" + if [[ ! -d "$cmd_path" ]] && [[ ! -f "$cmd_path" ]]; then + echo "ERROR: BROKEN REFERENCE in $plugin_name/plugin.json" + echo " commands references '$cmd_ref' but path does not exist at:" + echo " $cmd_path" + echo "" + echo " FIX: Either create the path or remove the commands entry" + exit 1 + fi + echo " ✓ commands reference: $cmd_ref exists" + done + echo "✓ $plugin_name valid" done +# CRITICAL: Validate marketplace.json file references +echo "" +echo "=== Validating Marketplace File References (CRITICAL) ===" + +for i in $(seq 0 $((PLUGIN_COUNT - 1))); do + PLUGIN_NAME=$(jq -r ".plugins[$i].name" "$MARKETPLACE_JSON") + PLUGIN_SOURCE=$(jq -r ".plugins[$i].source" "$MARKETPLACE_JSON") + PLUGIN_DIR="$ROOT_DIR/$PLUGIN_SOURCE" + + # Check mcpServers in marketplace.json + mcp_servers=$(jq -r ".plugins[$i].mcpServers // [] | .[]" "$MARKETPLACE_JSON" 2>/dev/null) + for mcp_ref in $mcp_servers; do + mcp_path="$PLUGIN_DIR/$mcp_ref" + if [[ ! -f "$mcp_path" ]]; then + echo "ERROR: BROKEN REFERENCE in marketplace.json for $PLUGIN_NAME" + echo " mcpServers references '$mcp_ref' but file does not exist at:" + echo " $mcp_path" + echo "" + echo " FIX: Either create the file or remove the mcpServers entry from marketplace.json" + exit 1 + fi + echo "✓ $PLUGIN_NAME: mcpServers reference $mcp_ref exists" + done + + # Check hooks in marketplace.json + hooks=$(jq -r ".plugins[$i].hooks // [] | .[]" "$MARKETPLACE_JSON" 2>/dev/null) + for hook_ref in $hooks; do + hook_path="$PLUGIN_DIR/$hook_ref" + if [[ ! -f "$hook_path" ]]; then + echo "ERROR: BROKEN REFERENCE in marketplace.json for $PLUGIN_NAME" + echo " hooks references '$hook_ref' but file does not exist at:" + echo " $hook_path" + echo "" + echo " FIX: Either create the file or remove the hooks entry from marketplace.json" + exit 1 + fi + echo "✓ $PLUGIN_NAME: hooks reference $hook_ref exists" + done +done + +echo "✓ All file references validated" + # v5.4.0: Validate agent model fields echo "" echo "=== Validating Agent Model Fields (v5.4.0+) ==="