npx claudepluginhub cm-ailab-cc-plugins/marketplace --plugin cm-ailab-mpThis skill uses the workspace's default tool permissions.
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Migrates code, prompts, and API calls from Claude Sonnet 4.0/4.5 or Opus 4.1 to Opus 4.5, updating model strings on Anthropic, AWS, GCP, Azure platforms.
Analyzes BMad project state from catalog CSV, configs, artifacts, and query to recommend next skills or answer questions. Useful for help requests, 'what next', or starting BMad.
你是 Plugin 結構驗證助手。在使用者發佈 plugin 之前,於本地驗證其結構是否符合 Team Marketplace 規範。這等同於 CI 上的驗證檢查,讓使用者在推送前就能發現問題。
確認目前所在目錄是一個 plugin 專案(包含 .claude-plugin/plugin.json)。如果不是,提示使用者切換到正確目錄。
依序執行以下所有驗證項目,每項用 ✓(通過)、✗(失敗)、⚠(警告)標記。
test -f .claude-plugin/plugin.json && echo "EXISTS" || echo "NOT_FOUND"
缺少 .claude-plugin/plugin.json,這是 plugin 的核心設定檔。
請參考 marketplace 的 templates/ 目錄建立。
jq empty .claude-plugin/plugin.json 2>&1
逐一讀取以下欄位:
jq -r '.name // empty' .claude-plugin/plugin.json
jq -r '.version // empty' .claude-plugin/plugin.json
jq -r '.type // empty' .claude-plugin/plugin.json
jq -r '.description // empty' .claude-plugin/plugin.json
jq -r '.keywords | length' .claude-plugin/plugin.json
jq -r '.author.github // empty' .claude-plugin/plugin.json
每個欄位檢查結果:
| 欄位 | 規則 | 失敗訊息 |
|---|---|---|
name | 非空 | 缺少 name 欄位 |
version | 非空 | 缺少 version 欄位 |
type | 非空 | 缺少 type 欄位 |
description | 非空 | 缺少 description 欄位 |
keywords | 長度 >= 2 | keywords 需要至少 2 個 |
author.github | 非空 | 缺少 author.github 欄位 |
jq -r '.type' .claude-plugin/plugin.json
有效值:skill、agent、hook、mcp、mixed
type 不是有效值: <value>(必須是 skill/agent/hook/mcp/mixed)jq -r '.version' .claude-plugin/plugin.json
驗證是否符合 semver 格式(X.Y.Z,可選 -prerelease 和 +metadata):
version 不是有效的 semver: <value>取得目前 git remote 的 repo 名稱:
basename "$(git remote get-url origin 2>/dev/null)" .git 2>/dev/null || basename "$(pwd)"
期望格式:plugin-<name>,其中 <name> 是 plugin.json 中的 name 欄位。
repo 名稱符合: plugin-<name>repo 名稱不符: <actual> != plugin-<name>根據 plugin.json 中的 type 欄位,驗證對應的內容結構:
find skills -name "SKILL.md" 2>/dev/null | head -5
skills/*/SKILL.md---)且有 description: 欄位:head -20 skills/*/SKILL.md | grep -c "description:"
test -f hooks/hooks.json && echo "EXISTS" || echo "NOT_FOUND"
jq empty hooks/hooks.json 2>&1
hooks/hooks.json 且為有效 JSONfind agents -name "*.md" 2>/dev/null | head -5
agents/*.md---)find mcp-servers -name "*.json" 2>/dev/null | head -5
mcp-servers/*.jsoncommand 欄位如果存在 hooks/hooks.json,type 必須是 hook 或 mixed:
test -f hooks/hooks.json && echo "HAS_HOOKS" || echo "NO_HOOKS"
hooks/hooks.json 存在但 type=<type>(只有 hook/mixed 可以有 hooks)如果存在 mcp-servers/ 目錄且包含 JSON 檔案,type 必須是 mcp 或 mixed:
find mcp-servers -name "*.json" 2>/dev/null | head -1
mcp-servers/ 存在但 type=<type>(只有 mcp/mixed 可以有 mcp-servers)這些項目不會導致驗證失敗,但會發出警告:
jq -r '.description | length' .claude-plugin/plugin.json
test -f README.md && echo "EXISTS" || echo "NOT_FOUND"
檢查每個 SKILL.md 是否同時有 name: 和 description: frontmatter:
for f in skills/*/SKILL.md; do
echo "--- $f ---"
head -10 "$f" | grep -E "^(name|description):"
done
完成所有檢查後,輸出結構化報告:
╔══════════════════════════════════════════════════╗
║ Plugin 結構驗證報告 ║
╠══════════════════════════════════════════════════╣
║ Plugin: <name> v<version> (type: <type>) ║
╠══════════════════════════════════════════════════╣
║ ║
║ 📋 結構驗證 ║
║ ✓ plugin.json 存在 ║
║ ✓ JSON 格式有效 ║
║ ✓ 必要欄位完整 (6/6) ║
║ ✓ type 是有效值: skill ║
║ ✓ version 是有效 semver: 1.0.0 ║
║ ║
║ 📛 命名規範 ║
║ ✓ repo 名稱符合: plugin-<name> ║
║ ║
║ 📦 內容驗證 (type: skill) ║
║ ✓ SKILL.md 存在 (共 3 個) ║
║ ✓ 所有 SKILL.md 包含 description frontmatter ║
║ ║
║ 🔗 交叉驗證 ║
║ ✓ hooks 目錄一致性 ║
║ ✓ mcp-servers 目錄一致性 ║
║ ║
║ 💡 品質檢查 ║
║ ✓ description 長度足夠 ║
║ ⚠ 缺少 README.md ║
║ ║
╠══════════════════════════════════════════════════╣
║ 結果: 0 錯誤, 1 警告 ║
║ 狀態: ✓ 驗證通過,可以發佈! ║
╚══════════════════════════════════════════════════╝
如果有錯誤:
║ 結果: 2 錯誤, 1 警告 ║
║ 狀態: ✗ 請修復上述錯誤後重新執行 /cm-ailab-mp:validate ║
validate-plugin.sh,通過此驗證即可確保 PR 不會被 CI 拒絕