Files
bootstrap/bin/mosaic-sync-skills
2026-02-17 10:56:48 -06:00

127 lines
3.1 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
MOSAIC_HOME="${MOSAIC_HOME:-$HOME/.mosaic}"
SKILLS_REPO_URL="${MOSAIC_SKILLS_REPO_URL:-https://git.mosaicstack.dev/mosaic/agent-skills.git}"
SKILLS_REPO_DIR="${MOSAIC_SKILLS_REPO_DIR:-$MOSAIC_HOME/sources/agent-skills}"
MOSAIC_SKILLS_DIR="$MOSAIC_HOME/skills"
fetch=1
link_only=0
usage() {
cat <<USAGE
Usage: $(basename "$0") [options]
Sync canonical skills into ~/.mosaic/skills and link them into runtime skill directories.
Options:
--link-only Skip git clone/pull and only relink from ~/.mosaic/skills
--no-link Sync canonical skills but do not update runtime links
-h, --help Show help
Env:
MOSAIC_HOME Default: ~/.mosaic
MOSAIC_SKILLS_REPO_URL Default: https://git.mosaicstack.dev/mosaic/agent-skills.git
MOSAIC_SKILLS_REPO_DIR Default: ~/.mosaic/sources/agent-skills
USAGE
}
while [[ $# -gt 0 ]]; do
case "$1" in
--link-only)
fetch=0
shift
;;
--no-link)
link_only=1
shift
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown argument: $1" >&2
usage >&2
exit 1
;;
esac
done
mkdir -p "$MOSAIC_HOME" "$MOSAIC_SKILLS_DIR"
if [[ $fetch -eq 1 ]]; then
if [[ -d "$SKILLS_REPO_DIR/.git" ]]; then
echo "[mosaic-skills] Updating skills source: $SKILLS_REPO_DIR"
git -C "$SKILLS_REPO_DIR" pull --rebase
else
echo "[mosaic-skills] Cloning skills source to: $SKILLS_REPO_DIR"
mkdir -p "$(dirname "$SKILLS_REPO_DIR")"
git clone "$SKILLS_REPO_URL" "$SKILLS_REPO_DIR"
fi
SOURCE_SKILLS_DIR="$SKILLS_REPO_DIR/skills"
if [[ ! -d "$SOURCE_SKILLS_DIR" ]]; then
echo "[mosaic-skills] Missing source skills dir: $SOURCE_SKILLS_DIR" >&2
exit 1
fi
if command -v rsync >/dev/null 2>&1; then
rsync -a --delete "$SOURCE_SKILLS_DIR/" "$MOSAIC_SKILLS_DIR/"
else
rm -rf "$MOSAIC_SKILLS_DIR"/*
cp -R "$SOURCE_SKILLS_DIR"/* "$MOSAIC_SKILLS_DIR"/
fi
fi
if [[ ! -d "$MOSAIC_SKILLS_DIR" ]]; then
echo "[mosaic-skills] Canonical skills dir missing: $MOSAIC_SKILLS_DIR" >&2
exit 1
fi
if [[ $link_only -eq 1 ]]; then
echo "[mosaic-skills] Canonical sync completed (link update skipped)"
exit 0
fi
link_targets=(
"$HOME/.claude/skills"
"$HOME/.codex/skills"
"$HOME/.config/opencode/skills"
)
link_skill_into_target() {
local skill_path="$1"
local target_dir="$2"
local name
name="$(basename "$skill_path")"
local link_path="$target_dir/$name"
if [[ -L "$link_path" ]]; then
ln -sfn "$skill_path" "$link_path"
return
fi
if [[ -e "$link_path" ]]; then
local backup="$link_path.mosaic-backup.$(date +%Y%m%d%H%M%S)"
mv "$link_path" "$backup"
echo "[mosaic-skills] Backed up existing entry: $link_path -> $backup"
fi
ln -s "$skill_path" "$link_path"
}
for target in "${link_targets[@]}"; do
mkdir -p "$target"
while IFS= read -r -d '' skill; do
link_skill_into_target "$skill" "$target"
done < <(find "$MOSAIC_SKILLS_DIR" -mindepth 1 -maxdepth 1 -type d -print0)
echo "[mosaic-skills] Linked skills into: $target"
done
echo "[mosaic-skills] Complete"