关于 swain-update
swain-update 是用于更新本地 swain 技能并协调治理配置的 Agent 技能。它检测已安装的平台、备份修改过的文件、安装对应技能,并报告安装版本。
主要功能
- 01检测已安装的 Agent 平台
- 02备份本地修改过的技能文件
- 03通过 npx 安装,失败时回退到 Git
- 04协调并检查治理配置
- 05报告已安装技能的版本
适用场景
- 01更新现有的 swain 技能安装
- 02在新环境中安装 swain 技能
- 03更新时保留并检查本地修改
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ cristoslc/ swain --skill swain-update安装后在 Claude Code 中输入/swain-update确认已加载。
附带文件references/agent-platforms.json
详细介绍
更新 Swain
将本地安装的 swain skills 更新到最新版本,然后协调治理配置。
步骤 1 — 检测当前安装
检查 .claude/skills/ 是否包含任何 swain-* 目录:
ls -d .claude/skills/swain-* 2>/dev/null
如果未找到 swain 技能目录,告知用户这看起来是全新安装,而非更新,然后仍继续操作——以下步骤适用于这两种情况。
步骤 2 — 备份本地修改
覆盖技能目录之前,检查是否有应予保留的用户修改。
检测已修改的文件
将本地技能文件与已安装版本的 git 源进行比较:
# Create a temporary reference copy
tmp=$(mktemp -d)
git clone --depth 1 https://github.com/cristoslc/swain.git "$tmp/swain" 2>/dev/null
# Find locally modified files
modified_files=()
for skill_dir in .claude/skills/swain-*/; do
skill_name=$(basename "$skill_dir")
ref_dir="$tmp/swain/skills/$skill_name"
[ -d "$ref_dir" ] || continue
while IFS= read -r file; do
rel="${file#$skill_dir}"
ref_file="$ref_dir/$rel"
if [ -f "$ref_file" ]; then
if ! diff -q "$file" "$ref_file" >/dev/null 2>&1; then
modified_files+=("$file")
fi
else
# File exists locally but not in upstream — user-added file
modified_files+=("$file")
fi
done < <(find "$skill_dir" -type f)
done
备份已修改的文件
如果发现已修改的文件:
- 创建备份目录:
.agents/update-backup/<ISO-date>/ - 复制每个已修改的文件,并保留目录结构
- 告知用户:“发现 N 个本地修改的文件——已备份到
.agents/update-backup/<date>/” - 列出已修改的文件
如果没有发现已修改的文件,则跳过并继续。
此步骤中的参考克隆可在步骤 3 中用作备用来源。
步骤 3 — 检测已安装的 Agent 平台
安装之前,检测系统上存在哪些 Agent 平台。这样可以避免为每个受支持的平台都创建点目录桩(参见 GitHub issue #21)。
从 references/agent-platforms.json 读取 Agent 平台数据。agents 数组中的每个条目都包含一个 name(skills CLI 标识符)、一个可选的 command(CLI 二进制文件)和一个 detection 路径(HOME 配置目录)。只要任一检查成功,就视为检测到该平台。always_include 中的条目会无条件添加。
SKILL_DIR="$(find . .claude skills -path '*/swain-update/references' -print -quit 2>/dev/null | sed 's|/references$||')"
detected_agents=()
# Always-include platforms (we're running inside claude-code)
for name in $(jq -r '.always_include[]' "$SKILL_DIR/references/agent-platforms.json"); do
detected_agents+=("$name")
done
# Detect remaining platforms via command -v or HOME dotfolder
while IFS= read -r entry; do
name=$(echo "$entry" | jq -r '.name')
cmd=$(echo "$entry" | jq -r '.command // empty')
det=$(echo "$entry" | jq -r '.detection // empty')
# Skip always-include (already added)
for ai in "${detected_agents[@]}"; do [[ "$ai" == "$name" ]] && continue 2; done
found=false
if [[ -n "$cmd" ]] && command -v "$cmd" &>/dev/null; then
found=true
fi
if [[ -n "$det" ]] && ! $found; then
det_expanded=$(echo "$det" | sed "s|~|$HOME|g")
det_expanded=$(eval echo "$det_expanded" 2>/dev/null)
[[ -d "$det_expanded" ]] && found=true
fi
$found && detected_agents+=("$name")
done < <(jq -c '.agents[]' "$SKILL_DIR/references/agent-platforms.json")
根据检测到的 Agent 构建 -a 标志:
agent_flags=""
for agent in "${detected_agents[@]}"; do
agent_flags="$agent_flags -a $agent"
done
告知用户检测到的平台:
检测到 N 个 Agent 平台:claude-code、codex、gemini-cli、...
步骤 4 — 通过 npx 更新
仅针对检测到的平台运行 skills 包管理器:
npx skills add cristoslc/swain $agent_flags -s '*' -y
这会为检测到的平台安装所有技能(-s '*'),并跳过确认(-y)。不会为未安装的平台创建点目录桩。
如果 npx 执行失败(找不到命令、网络错误或退出码非零),则回退到直接 git clone:
tmp=$(mktemp -d)
git clone --depth 1 https://github.com/cristoslc/swain.git "$tmp/swain"
# Detect skill install location
INSTALL_DIR=$(find . -maxdepth 2 -name "swain-doctor" -type d -print -quit 2>/dev/null | sed 's|/swain-doctor$||')
INSTALL_DIR="${INSTALL_DIR:-.claude/skills}"
cp -r "$tmp/swain/skills/"* "$INSTALL_DIR/"
rm -rf "$tmp"
步骤 5 — 协调治理配置
调用 swain-doctor 技能。该技能会验证治理规则、清理旧版技能目录(包括此版本中重命名的目录)、验证 .tickets/,并取消跟踪任何意外进入 git 的运行时文件。该技能具有幂等性,因此每次更新后运行都是安全的。
步骤 6 — 恢复指南
如果在步骤 2 中备份了文件:
- 列出备份文件及其路径
- 逐个说明情况:
- 用户添加的配置文件(例如
config/yazi/yazi.toml):建议将其移至.agents/config/<skill-name>/或swain.settings.json,以便在未来更新时保留 - 已打补丁的脚本:显示备份文件与新版本之间的差异。如果上游版本包含此修复,确认不再需要该补丁;否则,提出重新应用补丁
- 用户添加的配置文件(例如
- 提醒用户:“为避免今后出现这种情况,请将自定义内容存放在
.agents/config/或swain.settings.json中——这些内容在更新后仍会保留。”
步骤 7 — 报告
显示当前发行版本(来自最新的 git 标签):
release_tag=$(git tag --sort=-v:refname | head -1)
echo "swain ${release_tag:-(unreleased)}"
然后列出已安装的 swain 技能目录,并从各自的 SKILL.md frontmatter 中提取版本:
for skill in .claude/skills/swain-*/SKILL.md; do
name=$(grep '^name:' "$skill" | head -1 | sed 's/name: *//')
version=$(grep 'version:' "$skill" | head -1 | sed 's/.*version: *//')
echo " $name v$version"
done
向用户显示列表,并确认更新已完成。
如果在步骤 2 中创建了备份,还需显示:“已将 N 个修改文件备份到 .agents/update-backup/<date>/。恢复指南请参见步骤 5。”