How this skill is triggered — by the user, by Claude, or both
Slash command
/plugin-tools:plugin-healthThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
---
檢查所有已安裝 plugin 的健康狀態並修復常見問題。
claude plugin list 2>&1
從輸出中分類:
claude plugin marketplace list 2>&1
對每個 failed to load 的 plugin 執行以下檢查。
最常見的錯誤。hooks.json 的正確格式:
{
"hooks": {
"EventName": [
{
"matcher": "ToolPattern",
"hooks": [
{ "type": "command", "command": "script.sh" }
]
}
]
}
}
常見錯誤:
hooks key → 整個 JSON 直接是 event mapSessionStart 直接放 hook object 而非 { matcher, hooks: [...] } 陣列hooks 陣列(直接把 type/command 放在 matcher 層級)找到 plugin 的 hooks.json 並檢查格式:
# 找到 plugin cache 路徑
ls ~/.claude/plugins/cache/{marketplace_name}/{plugin_name}/*/hooks/hooks.json 2>/dev/null
# 或從源碼檢查
cat {source_path}/hooks/hooks.json | python3 -c "
import json, sys
d = json.load(sys.stdin)
if 'hooks' not in d:
print('ERROR: Missing top-level \"hooks\" key')
sys.exit(1)
for event, entries in d['hooks'].items():
if not isinstance(entries, list):
print(f'ERROR: {event} should be an array, got {type(entries).__name__}')
continue
for i, entry in enumerate(entries):
if 'hooks' not in entry:
print(f'ERROR: {event}[{i}] missing \"hooks\" array')
elif not isinstance(entry['hooks'], list):
print(f'ERROR: {event}[{i}].hooks should be an array')
else:
print(f'OK: {event}[{i}] — {len(entry[\"hooks\"])} hook(s)')
"
Hook 和 wrapper 腳本必須有 executable 權限:
# 找所有 .sh 檔案
find {plugin_source_path} -name "*.sh" -not -perm +111 2>/dev/null
如果有未設定 +x 的腳本:
chmod +x {script_path}
claude plugin validate {plugin_source_path} 2>&1
常見問題:
name 欄位如果 plugin 有 .mcp.json,檢查 binary 是否存在:
cat {plugin_source_path}/.mcp.json | python3 -c "
import json, sys, os
d = json.load(sys.stdin)
for name, cfg in d.items():
cmd = cfg.get('command', '')
# 替換 CLAUDE_PLUGIN_ROOT
cmd = cmd.replace('\${CLAUDE_PLUGIN_ROOT}', '{plugin_source_path}')
if cmd.startswith('/') or cmd.startswith('./'):
if os.path.isfile(cmd) and os.access(cmd, os.X_OK):
print(f'OK: {name} → {cmd}')
else:
print(f'MISSING: {name} → {cmd}')
else:
# 外部命令,用 which 檢查
import shutil
if shutil.which(cmd):
print(f'OK: {name} → {cmd} (in PATH)')
else:
print(f'MISSING: {name} → {cmd} (not in PATH)')
"
確認 commands/、skills/、hooks/、agents/ 在 plugin root,不在 .claude-plugin/ 裡:
# 錯誤位置
ls {plugin_source_path}/.claude-plugin/commands/ 2>/dev/null && echo "ERROR: commands/ inside .claude-plugin/"
ls {plugin_source_path}/.claude-plugin/skills/ 2>/dev/null && echo "ERROR: skills/ inside .claude-plugin/"
ls {plugin_source_path}/.claude-plugin/hooks/ 2>/dev/null && echo "ERROR: hooks/ inside .claude-plugin/"
對已知 marketplace repo 檢查版本是否同步。
cd /Users/che/Developer/psychquant-claude-plugins
python3 -c "
import json, os
# 讀 marketplace.json
with open('.claude-plugin/marketplace.json') as f:
mp = json.load(f)
mp_versions = {p['name']: p['version'] for p in mp['plugins']}
# 讀每個 plugin 的 plugin.json
for plugin_dir in sorted(os.listdir('plugins')):
pj_path = f'plugins/{plugin_dir}/.claude-plugin/plugin.json'
if not os.path.exists(pj_path):
continue
with open(pj_path) as f:
pj = json.load(f)
pj_ver = pj.get('version', '(none)')
mp_ver = mp_versions.get(plugin_dir, '(not in marketplace)')
if mp_ver == '(not in marketplace)':
print(f'⚠️ {plugin_dir}: v{pj_ver} — not in marketplace.json')
elif pj_ver != mp_ver:
print(f'⚠️ {plugin_dir}: plugin.json={pj_ver} marketplace.json={mp_ver}')
else:
print(f'✓ {plugin_dir}: v{pj_ver}')
"
# Plugin Health Report
## 載入狀態
| Plugin | Status | Error |
|--------|--------|-------|
| ... | ✔/✘ | ... |
## 問題與修復
### 1. {plugin_name}: {error_summary}
- **原因**: ...
- **修復**: ...
### 2. ...
## 版本同步
| Plugin | plugin.json | marketplace.json | 狀態 |
|--------|-------------|------------------|------|
| ... | ... | ... | ✓/⚠️ |
## 建議動作
1. ...
2. ...
如果問題可以自動修復(如 chmod +x、hooks.json 格式調整),徵求用戶同意後執行。
修復後重新驗證:
claude plugin validate {plugin_source_path} 2>&1
"expected array, received undefined" at hooks.SessionStart.0.hooks:
原因:SessionStart entry 缺少 hooks 陣列包裝。
修復前:
{ "hooks": { "SessionStart": [{ "type": "command", "command": "script.sh" }] } }
修復後:
{ "hooks": { "SessionStart": [{ "hooks": [{ "type": "command", "command": "script.sh" }] }] } }
Plugin X not found in marketplace Y:
原因:marketplace 已移除此 plugin,或 marketplace 名稱變更。
修復:
# 先移除壞的安裝
claude plugin uninstall {plugin_name}
# 如果需要重新安裝,從正確的 marketplace
claude plugin install {plugin_name}@{correct_marketplace}
MCP server binary 找不到:
修復:重新 build 或下載 binary,確認路徑正確。
npx claudepluginhub psychquant/psychquant-claude-plugins --plugin plugin-toolsThis skill should be used when the user asks to "check dependencies", "verify plugin requirements", "what plugins am I missing", "validate plugin dependencies", "missing plugin dependencies", "unmet requirements", "are my dependencies satisfied", "which dependencies are broken", or invokes /midnight-plugin-utils:dependency-checker. Validates declared dependencies in extends-plugin.json files against installed and enabled plugins.
Guides Claude Code plugin creation, structure (plugin.json, commands/agents/skills/hooks), installation (/plugin), marketplaces, team workflows, testing, debugging, and settings. Delegates to docs-management.
Audits .claude/ structure, naming, hooks, and plugin versions. Runs hygiene and sync checks, outputs health report with fix commands.