refactor: 通用技能按类别拆分为独立目录
skills/ → skills-dev(9), skills-req(10), skills-ops(4), skills-integration(8), skills-biz(4), skills-workflow(7) generate-marketplace.py 改为自动扫描所有 skills-* 目录。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
393
skills-workflow/skill-manager-plugin/skill.sh
Executable file
393
skills-workflow/skill-manager-plugin/skill.sh
Executable file
@@ -0,0 +1,393 @@
|
||||
#!/bin/bash
|
||||
# skill.sh - Skills 管理器主入口
|
||||
# 用法:
|
||||
# ./skill.sh list - 列出已安装技能
|
||||
# ./skill.sh install <repo> - 安装新技能
|
||||
# ./skill.sh upgrade [name] - 升级技能
|
||||
# ./skill.sh uninstall <name> - 卸载技能
|
||||
# ./skill.sh rollback <name> <version> - 回滚版本
|
||||
# ./skill.sh info <name> - 查看技能详情
|
||||
# ./skill.sh enable <name> - 启用技能
|
||||
# ./skill.sh disable <name> - 禁用技能
|
||||
# ./skill.sh check - 检查所有技能更新
|
||||
|
||||
set -e
|
||||
|
||||
SKILLS_DIR="$HOME/.claude/skills"
|
||||
REPOS_DIR="$SKILLS_DIR/repos"
|
||||
SCRIPTS_DIR="$SKILLS_DIR/skill-manager/scripts"
|
||||
REGISTRY_SCRIPT="$SCRIPTS_DIR/registry.sh"
|
||||
GIT_OPS_SCRIPT="$SCRIPTS_DIR/git-ops.sh"
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m'
|
||||
|
||||
# 显示 banner
|
||||
show_banner() {
|
||||
echo -e "${CYAN}"
|
||||
echo "╔═══════════════════════════════════════╗"
|
||||
echo "║ Skills Manager v1.0.0 ║"
|
||||
echo "║ 自我进化技能管理器 ║"
|
||||
echo "╚═══════════════════════════════════════╝"
|
||||
echo -e "${NC}"
|
||||
}
|
||||
|
||||
# 从 URL 提取技能名称
|
||||
extract_name() {
|
||||
local repo="$1"
|
||||
echo "$repo" | sed -E 's|.*/([^/]+)(\.git)?$|\1|' | sed 's/\.git$//'
|
||||
}
|
||||
|
||||
# 列出所有技能
|
||||
cmd_list() {
|
||||
echo -e "${BLUE}已安装技能:${NC}"
|
||||
echo "════════════════════════════════════════"
|
||||
"$REGISTRY_SCRIPT" list
|
||||
}
|
||||
|
||||
# 安装技能
|
||||
cmd_install() {
|
||||
local repo="$1"
|
||||
|
||||
if [ -z "$repo" ]; then
|
||||
echo -e "${RED}用法: skill install <repo>${NC}"
|
||||
echo "示例: skill install https://github.com/org/skill-name.git"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local name=$(extract_name "$repo")
|
||||
|
||||
echo -e "${BLUE}安装技能: $name${NC}"
|
||||
echo "════════════════════════════════════════"
|
||||
|
||||
# 检查是否已安装
|
||||
if [ -d "$REPOS_DIR/$name" ]; then
|
||||
echo -e "${YELLOW}技能已安装,使用 'skill upgrade $name' 更新${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 克隆仓库
|
||||
"$GIT_OPS_SCRIPT" clone "$repo" "$name"
|
||||
|
||||
# 验证 skill.yaml
|
||||
local skill_yaml="$REPOS_DIR/$name/skill.yaml"
|
||||
if [ -f "$skill_yaml" ]; then
|
||||
"$SCRIPTS_DIR/validate.sh" "$REPOS_DIR/$name"
|
||||
fi
|
||||
|
||||
# 创建符号链接到 skills 目录
|
||||
local skill_dir="$SKILLS_DIR/$name"
|
||||
if [ ! -d "$skill_dir" ]; then
|
||||
mkdir -p "$skill_dir"
|
||||
# 复制 SKILL.md
|
||||
local prompt_file=$(yq e '.prompt_file // "SKILL.md"' "$skill_yaml" 2>/dev/null || echo "SKILL.md")
|
||||
if [ -f "$REPOS_DIR/$name/$prompt_file" ]; then
|
||||
cp "$REPOS_DIR/$name/$prompt_file" "$skill_dir/SKILL.md"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 执行 post_install 钩子
|
||||
if command -v yq &> /dev/null && [ -f "$skill_yaml" ]; then
|
||||
local hooks=$(yq e '.hooks.post_install[]' "$skill_yaml" 2>/dev/null || echo "")
|
||||
if [ -n "$hooks" ]; then
|
||||
echo -e "${YELLOW}执行安装后钩子...${NC}"
|
||||
echo "$hooks" | while read -r cmd; do
|
||||
[ -n "$cmd" ] && eval "$cmd"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}✓ 技能安装完成: $name${NC}"
|
||||
}
|
||||
|
||||
# 升级技能
|
||||
cmd_upgrade() {
|
||||
local name="$1"
|
||||
|
||||
echo -e "${BLUE}升级技能${NC}"
|
||||
echo "════════════════════════════════════════"
|
||||
|
||||
if [ -z "$name" ]; then
|
||||
# 升级所有技能
|
||||
echo "升级所有技能..."
|
||||
local skills=$(ls -1 "$REPOS_DIR" 2>/dev/null || echo "")
|
||||
|
||||
if [ -z "$skills" ]; then
|
||||
echo "没有已安装的技能"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
for skill in $skills; do
|
||||
echo ""
|
||||
echo -e "${CYAN}>>> $skill${NC}"
|
||||
"$GIT_OPS_SCRIPT" pull "$skill" || echo -e "${YELLOW}跳过 $skill${NC}"
|
||||
done
|
||||
else
|
||||
# 升级指定技能
|
||||
if [ ! -d "$REPOS_DIR/$name" ]; then
|
||||
echo -e "${RED}技能不存在: $name${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
"$GIT_OPS_SCRIPT" pull "$name"
|
||||
|
||||
# 同步 SKILL.md
|
||||
local skill_yaml="$REPOS_DIR/$name/skill.yaml"
|
||||
if [ -f "$skill_yaml" ]; then
|
||||
local prompt_file=$(yq e '.prompt_file // "SKILL.md"' "$skill_yaml" 2>/dev/null || echo "SKILL.md")
|
||||
if [ -f "$REPOS_DIR/$name/$prompt_file" ]; then
|
||||
mkdir -p "$SKILLS_DIR/$name"
|
||||
cp "$REPOS_DIR/$name/$prompt_file" "$SKILLS_DIR/$name/SKILL.md"
|
||||
fi
|
||||
|
||||
# 执行 post_update 钩子
|
||||
local hooks=$(yq e '.hooks.post_update[]' "$skill_yaml" 2>/dev/null || echo "")
|
||||
if [ -n "$hooks" ]; then
|
||||
echo -e "${YELLOW}执行更新后钩子...${NC}"
|
||||
echo "$hooks" | while read -r cmd; do
|
||||
[ -n "$cmd" ] && eval "$cmd"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}✓ 升级完成${NC}"
|
||||
}
|
||||
|
||||
# 卸载技能
|
||||
cmd_uninstall() {
|
||||
local name="$1"
|
||||
|
||||
if [ -z "$name" ]; then
|
||||
echo -e "${RED}用法: skill uninstall <name>${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}卸载技能: $name${NC}"
|
||||
echo "════════════════════════════════════════"
|
||||
|
||||
if [ ! -d "$REPOS_DIR/$name" ]; then
|
||||
echo -e "${YELLOW}技能不存在: $name${NC}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 确认
|
||||
echo -e "${YELLOW}确认卸载 $name? [y/N]${NC}"
|
||||
read -r confirm
|
||||
if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
|
||||
echo "取消卸载"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 执行 post_uninstall 钩子
|
||||
local skill_yaml="$REPOS_DIR/$name/skill.yaml"
|
||||
if command -v yq &> /dev/null && [ -f "$skill_yaml" ]; then
|
||||
local hooks=$(yq e '.hooks.post_uninstall[]' "$skill_yaml" 2>/dev/null || echo "")
|
||||
if [ -n "$hooks" ]; then
|
||||
echo -e "${YELLOW}执行卸载钩子...${NC}"
|
||||
echo "$hooks" | while read -r cmd; do
|
||||
[ -n "$cmd" ] && eval "$cmd"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
# 删除仓库
|
||||
rm -rf "$REPOS_DIR/$name"
|
||||
echo -e "${GREEN}✓ 已删除仓库: $REPOS_DIR/$name${NC}"
|
||||
|
||||
# 删除技能目录
|
||||
rm -rf "$SKILLS_DIR/$name"
|
||||
echo -e "${GREEN}✓ 已删除技能目录: $SKILLS_DIR/$name${NC}"
|
||||
|
||||
# 从 registry 移除
|
||||
"$REGISTRY_SCRIPT" remove "$name"
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}✓ 技能已卸载: $name${NC}"
|
||||
}
|
||||
|
||||
# 回滚版本
|
||||
cmd_rollback() {
|
||||
local name="$1"
|
||||
local version="$2"
|
||||
|
||||
if [ -z "$name" ] || [ -z "$version" ]; then
|
||||
echo -e "${RED}用法: skill rollback <name> <version>${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}回滚技能: $name → $version${NC}"
|
||||
echo "════════════════════════════════════════"
|
||||
|
||||
"$GIT_OPS_SCRIPT" checkout "$name" "$version"
|
||||
|
||||
# 同步 SKILL.md
|
||||
local skill_yaml="$REPOS_DIR/$name/skill.yaml"
|
||||
if [ -f "$skill_yaml" ]; then
|
||||
local prompt_file=$(yq e '.prompt_file // "SKILL.md"' "$skill_yaml" 2>/dev/null || echo "SKILL.md")
|
||||
if [ -f "$REPOS_DIR/$name/$prompt_file" ]; then
|
||||
mkdir -p "$SKILLS_DIR/$name"
|
||||
cp "$REPOS_DIR/$name/$prompt_file" "$SKILLS_DIR/$name/SKILL.md"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}✓ 回滚完成${NC}"
|
||||
}
|
||||
|
||||
# 查看技能详情
|
||||
cmd_info() {
|
||||
local name="$1"
|
||||
|
||||
if [ -z "$name" ]; then
|
||||
echo -e "${RED}用法: skill info <name>${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}技能详情: $name${NC}"
|
||||
echo "════════════════════════════════════════"
|
||||
|
||||
"$GIT_OPS_SCRIPT" status "$name"
|
||||
|
||||
# 显示 skill.yaml 信息
|
||||
local skill_yaml="$REPOS_DIR/$name/skill.yaml"
|
||||
if [ -f "$skill_yaml" ] && command -v yq &> /dev/null; then
|
||||
echo ""
|
||||
echo "技能配置:"
|
||||
echo "----------------------------------------"
|
||||
echo "描述: $(yq e '.description' "$skill_yaml" | head -1)"
|
||||
echo "作者: $(yq e '.author // "未知"' "$skill_yaml")"
|
||||
|
||||
local deps=$(yq e '.dependencies[]' "$skill_yaml" 2>/dev/null || echo "")
|
||||
if [ -n "$deps" ]; then
|
||||
echo "依赖: $deps"
|
||||
fi
|
||||
|
||||
local keywords=$(yq e '.triggers.keywords[]' "$skill_yaml" 2>/dev/null | tr '\n' ', ' | sed 's/,$//')
|
||||
if [ -n "$keywords" ]; then
|
||||
echo "关键词: $keywords"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# 启用技能
|
||||
cmd_enable() {
|
||||
local name="$1"
|
||||
|
||||
if [ -z "$name" ]; then
|
||||
echo -e "${RED}用法: skill enable <name>${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
"$REGISTRY_SCRIPT" update "$name" status "active"
|
||||
echo -e "${GREEN}✓ 已启用技能: $name${NC}"
|
||||
}
|
||||
|
||||
# 禁用技能
|
||||
cmd_disable() {
|
||||
local name="$1"
|
||||
|
||||
if [ -z "$name" ]; then
|
||||
echo -e "${RED}用法: skill disable <name>${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
"$REGISTRY_SCRIPT" update "$name" status "disabled"
|
||||
echo -e "${GREEN}✓ 已禁用技能: $name${NC}"
|
||||
}
|
||||
|
||||
# 检查更新
|
||||
cmd_check() {
|
||||
echo -e "${BLUE}检查技能更新${NC}"
|
||||
echo "════════════════════════════════════════"
|
||||
|
||||
local skills=$(ls -1 "$REPOS_DIR" 2>/dev/null || echo "")
|
||||
|
||||
if [ -z "$skills" ]; then
|
||||
echo "没有已安装的技能"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
local has_updates=0
|
||||
|
||||
for skill in $skills; do
|
||||
local result=$("$GIT_OPS_SCRIPT" has-updates "$skill" 2>/dev/null | head -1)
|
||||
if [ "$result" == "yes" ]; then
|
||||
local behind=$("$GIT_OPS_SCRIPT" has-updates "$skill" 2>/dev/null | tail -1)
|
||||
echo -e "${YELLOW}✓ $skill 有更新 ($behind)${NC}"
|
||||
has_updates=1
|
||||
else
|
||||
echo -e "${GREEN}✓ $skill 已是最新${NC}"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
if [ $has_updates -eq 1 ]; then
|
||||
echo -e "${YELLOW}执行 'skill upgrade' 升级所有技能${NC}"
|
||||
else
|
||||
echo -e "${GREEN}所有技能已是最新版本${NC}"
|
||||
fi
|
||||
}
|
||||
|
||||
# 主命令分发
|
||||
case "${1:-help}" in
|
||||
list|ls)
|
||||
cmd_list
|
||||
;;
|
||||
install|add)
|
||||
cmd_install "$2"
|
||||
;;
|
||||
upgrade|update)
|
||||
cmd_upgrade "$2"
|
||||
;;
|
||||
uninstall|remove)
|
||||
cmd_uninstall "$2"
|
||||
;;
|
||||
rollback)
|
||||
cmd_rollback "$2" "$3"
|
||||
;;
|
||||
info|show)
|
||||
cmd_info "$2"
|
||||
;;
|
||||
enable)
|
||||
cmd_enable "$2"
|
||||
;;
|
||||
disable)
|
||||
cmd_disable "$2"
|
||||
;;
|
||||
check)
|
||||
cmd_check
|
||||
;;
|
||||
help|--help|-h)
|
||||
show_banner
|
||||
echo "用法: skill <command> [args]"
|
||||
echo ""
|
||||
echo "命令:"
|
||||
echo " list 列出已安装技能"
|
||||
echo " install <repo> 安装新技能"
|
||||
echo " upgrade [name] 升级技能(不指定则升级全部)"
|
||||
echo " uninstall <name> 卸载技能"
|
||||
echo " rollback <name> <version> 回滚到指定版本"
|
||||
echo " info <name> 查看技能详情"
|
||||
echo " enable <name> 启用技能"
|
||||
echo " disable <name> 禁用技能"
|
||||
echo " check 检查所有技能更新"
|
||||
echo ""
|
||||
echo "示例:"
|
||||
echo " skill install https://github.com/org/skill-name.git"
|
||||
echo " skill upgrade coolbuy-paas"
|
||||
echo " skill rollback coolbuy-paas v1.1.0"
|
||||
;;
|
||||
*)
|
||||
echo -e "${RED}未知命令: $1${NC}"
|
||||
echo "使用 'skill help' 查看帮助"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user