- Add install_name, install_type, dir_category fields to all 62 plugin.json files to resolve name-mapping and skill-vs-command routing issues - Add install-skills.sh: idempotent cross-machine skill sync script - Routes skill→~/.claude/skills/<name>/, command→~/.claude/commands/<name>.md - rsync full skills/ directory (preserves multi-file skills like dev-test, req-deploy) - State file ~/.claude/.installed-skills.json tracks installed versions - Conflict detection: warns before overwriting locally modified files - --dry-run, --category, --force, --cleanup, --list flags - Add 9 new plugins migrated from local ~/.claude (agent-swarm, ai-chat, defect-analysis, executing-plans, finishing-branch, frontend-design, req-audit, req-lookback, req-retro) - Add update-plugin-meta.py helper used to bulk-update plugin.json - Fix siyuan SKILL.md: remove hardcoded server credentials, use env vars Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
120 lines
7.0 KiB
Python
120 lines
7.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Update all plugin.json files with install_name, install_type, and dir_category fields.
|
|
"""
|
|
import json
|
|
import os
|
|
|
|
# Mapping: plugin_dir_name -> (install_name, install_type, dir_category)
|
|
# install_type: "skill" -> ~/.claude/skills/<install_name>/
|
|
# "command" -> ~/.claude/commands/<install_name>.md
|
|
PLUGIN_MAP = {
|
|
# skills-biz
|
|
"biz-contract-plugin": ("biz-contract", "skill", "biz"),
|
|
"biz-ops-plugin": ("biz-ops", "skill", "biz"),
|
|
"biz-plan-plugin": ("biz-plan", "skill", "biz"),
|
|
"finance-plugin": ("finance", "skill", "biz"),
|
|
|
|
# skills-core
|
|
"ai-proj-plugin": ("ai-proj", "skill", "core"),
|
|
"pm-ask-plugin": ("pm-ask", "skill", "core"),
|
|
"pm-risk-plugin": ("pm-risk", "skill", "core"),
|
|
"publish-plugin": ("publish", "skill", "core"),
|
|
|
|
# skills-dev
|
|
"agent-browser-plugin": ("agent-browser", "skill", "dev"),
|
|
"agent-swarm-plugin": ("agent-swarm", "skill", "dev"),
|
|
"ai-chat-plugin": ("ai-chat", "skill", "dev"),
|
|
"db-migration-plugin": ("db-migration", "skill", "dev"),
|
|
"defect-analysis-plugin": ("defect-analysis", "command", "dev"),
|
|
"deploy-rollback-plugin": ("deploy-rollback", "skill", "dev"),
|
|
"dev-android-plugin": ("dev-android", "skill", "dev"),
|
|
"dev-arch-plugin": ("dev-arch", "skill", "dev"),
|
|
"dev-cicd-plugin": ("dev-cicd", "skill", "dev"),
|
|
"dev-coding-plugin": ("dev-coding", "skill", "dev"),
|
|
"dev-commit-plugin": ("dev-commit", "skill", "dev"),
|
|
"dev-deploy-plugin": ("dev-deploy", "skill", "dev"),
|
|
"dev-integration-plugin": ("dev-integration", "skill", "dev"),
|
|
"dev-ios-plugin": ("dev-ios", "skill", "dev"),
|
|
"dev-mcp-plugin": ("dev-mcp", "skill", "dev"),
|
|
"dev-pda-plugin": ("dev-pda", "skill", "dev"),
|
|
"dev-review-plugin": ("dev-review", "skill", "dev"),
|
|
"dev-scaffold-plugin": ("dev-scaffold", "skill", "dev"),
|
|
"dev-test-plugin": ("dev-test", "skill", "dev"),
|
|
"executing-plans-plugin": ("executing-plans", "skill", "dev"),
|
|
"finishing-branch-plugin": ("finishing-a-development-branch","skill", "dev"), # name mismatch!
|
|
"frontend-design-plugin": ("frontend-design", "skill", "dev"),
|
|
"pull-request-plugin": ("pull-request", "skill", "dev"),
|
|
"review-checklist-plugin": ("review-checklist", "skill", "dev"),
|
|
|
|
# skills-integration
|
|
"data-excel-plugin": ("data-excel", "skill", "integration"),
|
|
"doubao-voice-plugin": ("doubao-voice", "skill", "integration"),
|
|
"feishu-bitable-plugin": ("feishu-bitable", "skill", "integration"),
|
|
"feishu-docx-plugin": ("feishu-docx", "skill", "integration"),
|
|
"feishu-plugin": ("feishu", "skill", "integration"),
|
|
"siyuan-plugin": ("siyuan", "skill", "integration"),
|
|
"siyuan-to-feishu-plugin": ("siyuan-to-feishu", "skill", "integration"),
|
|
"wecom-plugin": ("wecom", "skill", "integration"),
|
|
|
|
# skills-personal
|
|
"gitea-plugin": ("gitea", "skill", "personal"),
|
|
"openclaw-plugin": ("openclaw", "skill", "personal"),
|
|
"ops-servers-plugin": ("ops-servers", "skill", "personal"),
|
|
"ops-tools-plugin": ("ops-tools", "skill", "personal"),
|
|
"qiudl-personal-plugin": ("qiudl-personal", "skill", "personal"),
|
|
"reload-session-plugin": ("reload-session", "skill", "personal"),
|
|
"req-deploy-plugin": ("req-deploy", "skill", "personal"),
|
|
"save-session-plugin": ("save-session", "skill", "personal"),
|
|
"search-sessions-plugin": ("search-sessions", "skill", "personal"),
|
|
|
|
# skills-req
|
|
"req-audit-plugin": ("req-audit", "command", "req"),
|
|
"req-compare-plugin": ("req-compare", "skill", "req"),
|
|
"req-design-plugin": ("req-design", "skill", "req"),
|
|
"req-dev-plugin": ("req-dev", "skill", "req"),
|
|
"req-lookback-plugin": ("req-lookback", "command", "req"),
|
|
"req-plugin": ("req", "skill", "req"),
|
|
"req-prd-plugin": ("req-prd", "skill", "req"),
|
|
"req-prototype-plugin": ("req-prototype", "skill", "req"),
|
|
"req-research-plugin": ("req-research", "skill", "req"),
|
|
"req-retro-plugin": ("req-retro", "command", "req"),
|
|
"req-review-plugin": ("req-review", "skill", "req"),
|
|
"req-test-gate-plugin": ("req-test-gate", "skill", "req"),
|
|
"req-workflow-plugin": ("req-workflow", "skill", "req"),
|
|
}
|
|
|
|
BASE = os.path.dirname(os.path.abspath(__file__))
|
|
updated = 0
|
|
skipped = 0
|
|
missing = []
|
|
|
|
for plugin_name, (install_name, install_type, dir_category) in PLUGIN_MAP.items():
|
|
# Find the plugin directory
|
|
found = False
|
|
for cat_dir in os.listdir(BASE):
|
|
if not cat_dir.startswith("skills-"):
|
|
continue
|
|
plugin_dir = os.path.join(BASE, cat_dir, plugin_name)
|
|
if os.path.isdir(plugin_dir):
|
|
json_path = os.path.join(plugin_dir, ".claude-plugin", "plugin.json")
|
|
if os.path.exists(json_path):
|
|
with open(json_path) as f:
|
|
data = json.load(f)
|
|
data["install_name"] = install_name
|
|
data["install_type"] = install_type
|
|
data["dir_category"] = dir_category
|
|
with open(json_path, "w") as f:
|
|
json.dump(data, f, indent=2, ensure_ascii=False)
|
|
f.write("\n")
|
|
print(f" ✓ {plugin_name} → {install_type}:{install_name}")
|
|
updated += 1
|
|
found = True
|
|
break
|
|
if not found:
|
|
missing.append(plugin_name)
|
|
|
|
print(f"\nUpdated: {updated}, Missing plugin dirs: {len(missing)}")
|
|
if missing:
|
|
print("Missing:", missing)
|