feat(sync): add install-skills.sh + install metadata to all 62 plugins
- 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>
This commit is contained in:
119
update-plugin-meta.py
Normal file
119
update-plugin-meta.py
Normal file
@@ -0,0 +1,119 @@
|
||||
#!/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)
|
||||
Reference in New Issue
Block a user