fix: harden skill linking to avoid canonical path corruption

This commit is contained in:
Jason Woltje
2026-02-17 11:07:03 -06:00
parent bf911e4042
commit a1c2efef1c

View File

@@ -91,13 +91,21 @@ link_targets=(
"$HOME/.config/opencode/skills"
)
canonical_real="$(readlink -f "$MOSAIC_SKILLS_DIR")"
link_skill_into_target() {
local skill_path="$1"
local target_dir="$2"
local name
local name link_path
name="$(basename "$skill_path")"
local link_path="$target_dir/$name"
# Do not distribute hidden/system skill directories globally.
if [[ "$name" == .* ]]; then
return
fi
link_path="$target_dir/$name"
if [[ -L "$link_path" ]]; then
ln -sfn "$skill_path" "$link_path"
@@ -105,9 +113,8 @@ link_skill_into_target() {
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"
echo "[mosaic-skills] Preserve existing runtime-specific entry: $link_path"
return
fi
ln -s "$skill_path" "$link_path"
@@ -116,6 +123,13 @@ link_skill_into_target() {
for target in "${link_targets[@]}"; do
mkdir -p "$target"
# If target already resolves to canonical dir, skip to avoid self-link recursion/corruption.
target_real="$(readlink -f "$target" 2>/dev/null || true)"
if [[ -n "$target_real" && "$target_real" == "$canonical_real" ]]; then
echo "[mosaic-skills] Skip target (already canonical): $target"
continue
fi
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)