Files
global-skills/sync-skills.sh
T

68 lines
1.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# Sync skills from global-skills + JEV into each agent's skills directory.
# Idempotent. Never touches entries that are not managed symlinks (e.g. omarchy).
set -euo pipefail
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
GLOBAL_DIR="$REPO_DIR/skills"
JEV_DIR="$HOME/Projects/work/JEV/.agents/skills"
TARGETS=(
"$HOME/.agents/skills"
"$HOME/.codex/skills"
"$HOME/.claude/skills"
)
declare -A source_of
while IFS= read -r -d '' d; do
source_of["$(basename "$d")"]="global"
done < <(find "$GLOBAL_DIR" -mindepth 1 -maxdepth 1 -type d -print0 2>/dev/null)
while IFS= read -r -d '' d; do
name="$(basename "$d")"
if [[ -n "${source_of[$name]:-}" ]]; then
echo "WARN: collision: '$name' exists in both global-skills and JEV; using global-skills" >&2
continue
fi
source_of["$name"]="jev"
done < <(find "$JEV_DIR" -mindepth 1 -maxdepth 1 -type d -print0 2>/dev/null)
if [[ ${#source_of[@]} -eq 0 ]]; then
echo "nothing to sync" >&2
exit 1
fi
src_for() {
local name="$1"
if [[ "${source_of[$name]}" == "global" ]]; then
echo "$GLOBAL_DIR/$name"
else
echo "$JEV_DIR/$name"
fi
}
linked=0
skipped=0
for target in "${TARGETS[@]}"; do
mkdir -p "$target"
for name in $(printf '%s\n' "${!source_of[@]}" | sort); do
src="$(src_for "$name")"
dest="$target/$name"
if [[ -L "$dest" ]]; then
if [[ "$(readlink -f "$dest")" == "$(readlink -f "$src")" ]]; then
continue
fi
rm "$dest"
elif [[ -e "$dest" ]]; then
echo "SKIP: $dest exists and is not a managed symlink" >&2
skipped=$((skipped + 1))
continue
fi
ln -s "$src" "$dest"
echo "linked: $dest -> $src"
linked=$((linked + 1))
done
done
echo "sync complete: $linked linked, $skipped skipped"