development #450

Merged
lmiranda merged 2 commits from development into main 2026-02-07 22:05:28 +00:00
46 changed files with 192 additions and 129 deletions
Showing only changes of commit 1fe19b85e3 - Show all commits

View File

@@ -6,7 +6,7 @@
},
"metadata": {
"description": "Project management plugins with Gitea and NetBox integrations",
"version": "9.1.1"
"version": "9.1.2"
},
"plugins": [
{
@@ -27,8 +27,7 @@
"gitea",
"project-management"
],
"license": "MIT",
"domain": "core"
"license": "MIT"
},
{
"name": "doc-guardian",
@@ -47,8 +46,7 @@
"drift-detection",
"sync"
],
"license": "MIT",
"domain": "core"
"license": "MIT"
},
{
"name": "code-sentinel",
@@ -70,8 +68,7 @@
"refactoring",
"vulnerabilities"
],
"license": "MIT",
"domain": "core"
"license": "MIT"
},
{
"name": "project-hygiene",
@@ -91,8 +88,7 @@
"maintenance",
"manual-check"
],
"license": "MIT",
"domain": "core"
"license": "MIT"
},
{
"name": "cmdb-assistant",
@@ -117,8 +113,7 @@
"data-quality",
"validation"
],
"license": "MIT",
"domain": "ops"
"license": "MIT"
},
{
"name": "claude-config-maintainer",
@@ -137,8 +132,7 @@
"configuration",
"optimization"
],
"license": "MIT",
"domain": "core"
"license": "MIT"
},
{
"name": "clarity-assist",
@@ -161,8 +155,7 @@
"clarification",
"nd-friendly"
],
"license": "MIT",
"domain": "core"
"license": "MIT"
},
{
"name": "git-flow",
@@ -185,8 +178,7 @@
"commits",
"branching"
],
"license": "MIT",
"domain": "core"
"license": "MIT"
},
{
"name": "pr-review",
@@ -206,8 +198,7 @@
"security",
"quality"
],
"license": "MIT",
"domain": "core"
"license": "MIT"
},
{
"name": "data-platform",
@@ -229,8 +220,7 @@
"data-engineering",
"etl"
],
"license": "MIT",
"domain": "data"
"license": "MIT"
},
{
"name": "viz-platform",
@@ -253,8 +243,7 @@
"theming",
"dmc"
],
"license": "MIT",
"domain": "data"
"license": "MIT"
},
{
"name": "contract-validator",
@@ -276,8 +265,7 @@
"interfaces",
"cross-plugin"
],
"license": "MIT",
"domain": "core"
"license": "MIT"
},
{
"name": "saas-api-platform",
@@ -299,8 +287,7 @@
"express",
"openapi"
],
"license": "MIT",
"domain": "saas"
"license": "MIT"
},
{
"name": "saas-db-migrate",
@@ -322,8 +309,7 @@
"sql",
"schema"
],
"license": "MIT",
"domain": "saas"
"license": "MIT"
},
{
"name": "saas-react-platform",
@@ -345,8 +331,7 @@
"frontend",
"components"
],
"license": "MIT",
"domain": "saas"
"license": "MIT"
},
{
"name": "saas-test-pilot",
@@ -368,8 +353,7 @@
"playwright",
"coverage"
],
"license": "MIT",
"domain": "saas"
"license": "MIT"
},
{
"name": "data-seed",
@@ -390,8 +374,7 @@
"fixtures",
"database"
],
"license": "MIT",
"domain": "data"
"license": "MIT"
},
{
"name": "ops-release-manager",
@@ -412,8 +395,7 @@
"versioning",
"tags"
],
"license": "MIT",
"domain": "ops"
"license": "MIT"
},
{
"name": "ops-deploy-pipeline",
@@ -434,8 +416,7 @@
"caddy",
"cicd"
],
"license": "MIT",
"domain": "ops"
"license": "MIT"
},
{
"name": "debug-mcp",
@@ -456,8 +437,7 @@
"server",
"development"
],
"license": "MIT",
"domain": "debug"
"license": "MIT"
}
]
}

View File

@@ -6,6 +6,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Unreleased]
## [9.1.2] - 2026-02-07
### Fixed
- **BREAKING FIX:** Removed `"domain"` field from all `marketplace.json` and `plugin.json` files — Claude Code's strict schema validator rejects unrecognized keys, causing `Failed to load marketplace` error
- Domain metadata moved to `metadata.json` per plugin (same pattern as `mcp_servers`)
- `validate-marketplace.sh` updated to read domain from `metadata.json` instead of `marketplace.json`/`plugin.json`
- All documentation updated to reference `metadata.json` as domain source
## [9.1.1] - 2026-02-07
### Changed

View File

@@ -154,7 +154,7 @@ When user says "fix the sprint plan command", edit the SOURCE code.
## Project Overview
**Repository:** leo-claude-mktplace
**Version:** 9.1.1
**Version:** 9.1.2
**Status:** Production Ready
A plugin marketplace for Claude Code containing:
@@ -424,19 +424,18 @@ Stored in Gitea Wiki under `lessons-learned/sprints/`.
### Adding a New Plugin
1. Create `plugins/{name}/.claude-plugin/plugin.json` — must include `"domain"` field (`core`, `data`, `saas`, `ops`, or `debug`)
2. Add entry to `.claude-plugin/marketplace.json` with category, tags, license, and `"domain"` field (must match plugin.json)
3. Create `claude-md-integration.md`
4. If using new MCP server, add to root `mcp-servers/` and update `.mcp.json`
5. Run `./scripts/validate-marketplace.sh` — rejects plugins without valid `domain` field
6. Update `CHANGELOG.md`
1. Create `plugins/{name}/.claude-plugin/plugin.json` (standard schema fields only — no custom fields)
2. Create `plugins/{name}/.claude-plugin/metadata.json` — must include `"domain"` field (`core`, `data`, `saas`, `ops`, or `debug`)
3. Add entry to `.claude-plugin/marketplace.json` with category, tags, license (no custom fields — Claude Code schema is strict)
4. Create `claude-md-integration.md`
5. If using new MCP server, add to root `mcp-servers/` and update `.mcp.json`
6. Run `./scripts/validate-marketplace.sh` — rejects plugins without valid `domain` field
7. Update `CHANGELOG.md`
**Domain field is required (v8.0.0+):**
**Domain field is required in metadata.json (v8.0.0+, moved from plugin.json in v9.1.2):**
```json
{
"name": "plugin-name",
"domain": "core",
...
"domain": "core"
}
```

View File

@@ -1,4 +1,4 @@
# Leo Claude Marketplace — v9.1.1
# Leo Claude Marketplace — v9.1.2
A plugin marketplace for Claude Code providing sprint management, code review, security scanning, infrastructure automation, and development workflow tools. 20 plugins across 5 domains, backed by 5 shared MCP servers.

View File

@@ -384,14 +384,13 @@ All MCP servers are defined in `.mcp.json` at repository root:
## Domain Metadata
### Domain Field Locations
### Domain Field Location
Both manifest files require a `domain` field (v8.0.0+):
Domain metadata is stored in `metadata.json` (v9.1.2+, moved from plugin.json/marketplace.json for Claude Code schema compliance):
| Location | Field | Example |
|----------|-------|---------|
| `plugins/{name}/.claude-plugin/plugin.json` | `"domain": "core"` | `plugins/projman/.claude-plugin/plugin.json` |
| `.claude-plugin/marketplace.json` | `"domain": "core"` per plugin entry | `.claude-plugin/marketplace.json` |
| `plugins/{name}/.claude-plugin/metadata.json` | `"domain": "core"` | `plugins/projman/.claude-plugin/metadata.json` |
### Allowed Domain Values
@@ -413,10 +412,15 @@ Both manifest files require a `domain` field (v8.0.0+):
```bash
# List all plugins in a domain
jq '.plugins[] | select(.domain=="saas") | .name' .claude-plugin/marketplace.json
for p in plugins/*; do
d=$(jq -r '.domain // empty' "$p/.claude-plugin/metadata.json" 2>/dev/null)
[[ "$d" == "saas" ]] && basename "$p"
done
# Count plugins per domain
jq '[.plugins[] | .domain] | group_by(.) | map({domain: .[0], count: length})' .claude-plugin/marketplace.json
for p in plugins/*; do
jq -r '.domain // empty' "$p/.claude-plugin/metadata.json" 2>/dev/null
done | sort | uniq -c | sort -rn
```
---
@@ -425,6 +429,7 @@ jq '[.plugins[] | .domain] | group_by(.) | map({domain: .[0], count: length})' .
| Date | Change | By |
|------|--------|-----|
| 2026-02-07 | v9.1.2: Moved domain field from plugin.json/marketplace.json to metadata.json for Claude Code schema compliance | Claude Code |
| 2026-02-07 | v9.1.0: Removed deleted dirs (architecture/, prompts/, project-lessons-learned/), added Phase 3 plugins, added ARCHITECTURE.md, MIGRATION-v9.md, updated Domain table, removed stale hooks/ dirs | Claude Code |
| 2026-02-06 | v8.0.0: Added domain metadata section, Phase 1a paths, future plugin paths | Claude Code |
| 2026-02-04 | v7.1.0: Added profile configs, prompts/, project-lessons-learned/, metadata.json, deprecated switch-profile.sh | Claude Code |

View File

@@ -0,0 +1,3 @@
{
"domain": "core"
}

View File

@@ -18,6 +18,5 @@
],
"commands": [
"./commands/"
],
"domain": "core"
]
}

View File

@@ -0,0 +1,3 @@
{
"domain": "core"
}

View File

@@ -20,6 +20,5 @@
],
"commands": [
"./commands/"
],
"domain": "core"
]
}

View File

@@ -1 +1,6 @@
{"mcp_servers": ["netbox"]}
{
"mcp_servers": [
"netbox"
],
"domain": "ops"
}

View File

@@ -21,6 +21,5 @@
],
"commands": [
"./commands/"
],
"domain": "ops"
]
}

View File

@@ -0,0 +1,3 @@
{
"domain": "core"
}

View File

@@ -18,6 +18,5 @@
],
"commands": [
"./commands/"
],
"domain": "core"
]
}

View File

@@ -1 +1,6 @@
{"mcp_servers": ["contract-validator"]}
{
"mcp_servers": [
"contract-validator"
],
"domain": "core"
}

View File

@@ -19,6 +19,5 @@
],
"commands": [
"./commands/"
],
"domain": "core"
]
}

View File

@@ -1 +1,6 @@
{"mcp_servers": ["data-platform"]}
{
"mcp_servers": [
"data-platform"
],
"domain": "data"
}

View File

@@ -20,6 +20,5 @@
],
"commands": [
"./commands/"
],
"domain": "data"
]
}

View File

@@ -0,0 +1,3 @@
{
"domain": "data"
}

View File

@@ -20,6 +20,5 @@
],
"commands": [
"./commands/"
],
"domain": "data"
]
}

View File

@@ -0,0 +1,3 @@
{
"domain": "debug"
}

View File

@@ -20,6 +20,5 @@
],
"commands": [
"./commands/"
],
"domain": "debug"
]
}

View File

@@ -1 +1,6 @@
{"mcp_servers": ["gitea"]}
{
"mcp_servers": [
"gitea"
],
"domain": "core"
}

View File

@@ -18,6 +18,5 @@
],
"commands": [
"./commands/"
],
"domain": "core"
]
}

View File

@@ -1 +1,6 @@
{"mcp_servers": ["gitea"]}
{
"mcp_servers": [
"gitea"
],
"domain": "core"
}

View File

@@ -18,6 +18,5 @@
],
"commands": [
"./commands/"
],
"domain": "core"
]
}

View File

@@ -0,0 +1,3 @@
{
"domain": "ops"
}

View File

@@ -20,6 +20,5 @@
],
"commands": [
"./commands/"
],
"domain": "ops"
]
}

View File

@@ -0,0 +1,3 @@
{
"domain": "ops"
}

View File

@@ -20,6 +20,5 @@
],
"commands": [
"./commands/"
],
"domain": "ops"
]
}

View File

@@ -1 +1,6 @@
{"mcp_servers": ["gitea"]}
{
"mcp_servers": [
"gitea"
],
"domain": "core"
}

View File

@@ -18,6 +18,5 @@
],
"commands": [
"./commands/"
],
"domain": "core"
]
}

View File

@@ -0,0 +1,3 @@
{
"domain": "core"
}

View File

@@ -15,7 +15,6 @@
"maintenance",
"manual-check"
],
"domain": "core",
"commands": [
"./commands/"
]

View File

@@ -1 +1,6 @@
{"mcp_servers": ["gitea"]}
{
"mcp_servers": [
"gitea"
],
"domain": "core"
}

View File

@@ -18,6 +18,5 @@
],
"commands": [
"./commands/"
],
"domain": "core"
]
}

View File

@@ -0,0 +1,3 @@
{
"domain": "saas"
}

View File

@@ -21,6 +21,5 @@
],
"commands": [
"./commands/"
],
"domain": "saas"
]
}

View File

@@ -0,0 +1,3 @@
{
"domain": "saas"
}

View File

@@ -20,6 +20,5 @@
],
"commands": [
"./commands/"
],
"domain": "saas"
]
}

View File

@@ -0,0 +1,3 @@
{
"domain": "saas"
}

View File

@@ -21,6 +21,5 @@
],
"commands": [
"./commands/"
],
"domain": "saas"
]
}

View File

@@ -0,0 +1,3 @@
{
"domain": "saas"
}

View File

@@ -21,6 +21,5 @@
],
"commands": [
"./commands/"
],
"domain": "saas"
]
}

View File

@@ -1 +1,6 @@
{"mcp_servers": ["viz-platform"]}
{
"mcp_servers": [
"viz-platform"
],
"domain": "data"
}

View File

@@ -21,6 +21,5 @@
],
"commands": [
"./commands/"
],
"domain": "data"
]
}

View File

@@ -92,17 +92,23 @@ for i in $(seq 0 $((PLUGIN_COUNT - 1))); do
exit 1
fi
# v8.0.0: Check domain field
PLUGIN_DOMAIN=$(jq -r ".plugins[$i].domain // empty" "$MARKETPLACE_JSON")
# v8.0.0/v9.1.2: Check domain field in metadata.json (moved from marketplace.json for schema compliance)
PLUGIN_SOURCE=$(jq -r ".plugins[$i].source" "$MARKETPLACE_JSON")
METADATA_JSON="$ROOT_DIR/$PLUGIN_SOURCE/.claude-plugin/metadata.json"
if [[ -f "$METADATA_JSON" ]]; then
PLUGIN_DOMAIN=$(jq -r '.domain // empty' "$METADATA_JSON")
else
PLUGIN_DOMAIN=""
fi
if [[ -z "$PLUGIN_DOMAIN" ]]; then
echo "ERROR: Missing 'domain' in marketplace entry for $PLUGIN_NAME (required v8.0.0+)"
echo "ERROR: Missing 'domain' in $PLUGIN_NAME/.claude-plugin/metadata.json (required v8.0.0+)"
exit 1
fi
if ! echo "$VALID_DOMAINS" | grep -qw "$PLUGIN_DOMAIN"; then
echo "ERROR: Invalid domain '$PLUGIN_DOMAIN' in marketplace entry for $PLUGIN_NAME (allowed: $VALID_DOMAINS)"
echo "ERROR: Invalid domain '$PLUGIN_DOMAIN' in $PLUGIN_NAME/metadata.json (allowed: $VALID_DOMAINS)"
exit 1
fi
echo " ✓ domain: $PLUGIN_DOMAIN"
echo " ✓ domain: $PLUGIN_DOMAIN (from metadata.json)"
echo "✓ Marketplace entry $PLUGIN_NAME valid"
done
@@ -158,17 +164,22 @@ for plugin_dir in "$PLUGINS_DIR"/*/; do
echo "WARNING: Missing 'keywords' array in $plugin_name/plugin.json"
fi
# v8.0.0: Check domain field in plugin.json
PLUGIN_DOMAIN_PJ=$(jq -r '.domain // empty' "$plugin_json")
if [[ -z "$PLUGIN_DOMAIN_PJ" ]]; then
echo "ERROR: Missing 'domain' in $plugin_name/plugin.json (required v8.0.0+)"
# v8.0.0/v9.1.2: Check domain field in metadata.json (moved from plugin.json for schema compliance)
metadata_json="$plugin_dir.claude-plugin/metadata.json"
if [[ -f "$metadata_json" ]]; then
PLUGIN_DOMAIN_MD=$(jq -r '.domain // empty' "$metadata_json")
else
PLUGIN_DOMAIN_MD=""
fi
if [[ -z "$PLUGIN_DOMAIN_MD" ]]; then
echo "ERROR: Missing 'domain' in $plugin_name/.claude-plugin/metadata.json (required v8.0.0+)"
exit 1
fi
if ! echo "$VALID_DOMAINS" | grep -qw "$PLUGIN_DOMAIN_PJ"; then
echo "ERROR: Invalid domain '$PLUGIN_DOMAIN_PJ' in $plugin_name/plugin.json (allowed: $VALID_DOMAINS)"
if ! echo "$VALID_DOMAINS" | grep -qw "$PLUGIN_DOMAIN_MD"; then
echo "ERROR: Invalid domain '$PLUGIN_DOMAIN_MD' in $plugin_name/metadata.json (allowed: $VALID_DOMAINS)"
exit 1
fi
echo " ✓ domain: $PLUGIN_DOMAIN_PJ"
echo " ✓ domain: $PLUGIN_DOMAIN_MD (from metadata.json)"
# Check README exists
if [[ ! -f "$plugin_dir/README.md" ]]; then
@@ -324,20 +335,23 @@ if [[ ! -f "$ROOT_DIR/.mcp.json" ]]; then
fi
echo "✓ .mcp.json configuration exists"
# v8.0.0: Cross-validate domains match between marketplace.json and plugin.json
# v8.0.0/v9.1.2: Validate domain in metadata.json for all plugins (single source of truth)
echo ""
echo "=== Cross-Validating Domain Fields ==="
for i in $(seq 0 $((PLUGIN_COUNT - 1))); do
PLUGIN_NAME=$(jq -r ".plugins[$i].name" "$MARKETPLACE_JSON")
MARKETPLACE_DOMAIN=$(jq -r ".plugins[$i].domain" "$MARKETPLACE_JSON")
PLUGIN_JSON_PATH="$PLUGINS_DIR/$PLUGIN_NAME/.claude-plugin/plugin.json"
if [[ -f "$PLUGIN_JSON_PATH" ]]; then
PLUGIN_DOMAIN=$(jq -r '.domain' "$PLUGIN_JSON_PATH")
if [[ "$MARKETPLACE_DOMAIN" != "$PLUGIN_DOMAIN" ]]; then
echo "ERROR: Domain mismatch for $PLUGIN_NAME: marketplace.json='$MARKETPLACE_DOMAIN' vs plugin.json='$PLUGIN_DOMAIN'"
echo "=== Validating Domain Fields (metadata.json) ==="
for plugin_dir in "$PLUGINS_DIR"/*/; do
plugin_name=$(basename "$plugin_dir")
metadata_file="$plugin_dir.claude-plugin/metadata.json"
if [[ -f "$metadata_file" ]]; then
domain=$(jq -r '.domain // empty' "$metadata_file")
if [[ -n "$domain" ]]; then
echo "$plugin_name domain: $domain"
else
echo "ERROR: $plugin_name/metadata.json exists but missing domain field"
exit 1
fi
echo "$PLUGIN_NAME domain consistent: $MARKETPLACE_DOMAIN"
else
echo "ERROR: $plugin_name missing .claude-plugin/metadata.json"
exit 1
fi
done