#!/usr/bin/env bash
# Push-time reminder: skill/ changed, so the skillset MIRROR needs refreshing.
#
# WHY THIS EXISTS
#   skill/ is canonical for the pi-extensions agent skill, but it is not the copy
#   most consumers read. skillset mirrors it at skills/pi-extensions/, and every
#   Mac's host-side ~/.agents/skills/pi-extensions symlinks into that mirror. So a
#   skill/ edit that is pushed without refreshing the mirror is invisible to the
#   people it was written for.
#
#   That has now happened on two consecutive edits: the mirror sat 4890 B behind,
#   then 9579 B behind. Both times the edit was correct and the omission was the
#   follow-up step in another repo.
#
# WHAT IT DOES
#   On push, if the pushed commits touch skill/, compare the PUSHED content
#   against the mirror on disk. If they differ, print the refresh commands.
#
#   It WARNS, it does not block. The direction rule is "edit upstream, THEN
#   refresh" -- the refresh is chronologically after this push, and it is a commit
#   in a different repo, so refusing this push would be both wrong-ordered and
#   unfixable from here. Enforcement lives downstream, in skillset's own
#   pre-commit gate, which refuses a commit that leaves the mirror stale.
#
#   Silent when the mirror already matches, and silent when no skillset clone is
#   on disk -- a machine without one cannot act on the reminder, and a warning it
#   cannot act on is noise that trains people to skim hook output.
#
# ACTIVATION (per clone, cannot be tracked in git)
#   ./install.sh   -- or --   git config core.hooksPath hooks
#
# ESCAPE HATCH
#   git push --no-verify
set -euo pipefail

tag="[mirror]"
MIRROR_SUBPATH="skills/pi-extensions"
ZERO="0000000000000000000000000000000000000000"

# Locate the skillset clone. Explicit override, then the layouts this fleet has.
skillset=""
repo_root="$(git rev-parse --show-toplevel)"
for cand in "${PI_EXTENSIONS_SKILLSET:-}" "$repo_root/../skillset" "/workspace/skillset"; do
    [ -n "$cand" ] || continue
    if [ -d "$cand/$MIRROR_SUBPATH" ]; then skillset="$(cd "$cand" && pwd)"; break; fi
done
[ -n "$skillset" ] || exit 0   # nothing actionable on this machine

# pre-push feeds ref updates on stdin: <local ref> <local sha> <remote ref> <remote sha>
touched=""
pushed_sha=""
while read -r _local_ref local_sha _remote_ref remote_sha; do
    [ -n "${local_sha:-}" ] || continue
    [ "$local_sha" = "$ZERO" ] && continue        # branch deletion

    if [ "$remote_sha" = "$ZERO" ]; then
        # New ref on the remote: consider commits not already on any remote, so a
        # first push of a branch does not diff against the whole of history.
        range_args=("$local_sha" "--not" "--remotes=origin")
    else
        range_args=("$remote_sha..$local_sha")
    fi

    if git log --format= --name-only "${range_args[@]}" -- skill/ 2>/dev/null | grep -q .; then
        touched="yes"
        pushed_sha="$local_sha"
    fi
done

[ -n "$touched" ] || exit 0

# Compare what is being PUSHED (committed content at that sha) against the mirror
# on disk -- the file consumers actually read. Not the worktree: uncommitted local
# edits are not what this push publishes.
differ=""
while read -r path; do
    base="$(basename "$path")"
    mirror_file="$skillset/$MIRROR_SUBPATH/$base"
    if [ ! -f "$mirror_file" ]; then
        differ="${differ}${base} (missing from mirror)"$'\n'
        continue
    fi
    if ! git show "$pushed_sha:$path" 2>/dev/null | diff -q - "$mirror_file" >/dev/null 2>&1; then
        differ="${differ}${base}"$'\n'
    fi
done < <(git ls-tree -r --name-only "$pushed_sha" skill/)

[ -n "$differ" ] || exit 0   # mirror already refreshed; nothing to say

short="$(git rev-parse --short "$pushed_sha")"
echo "$tag this push changes skill/, and skillset's mirror does not match it yet." >&2
echo "$tag" >&2
printf '%s' "$differ" | sed 's/^/'"$tag"'   differs: /' >&2
echo "$tag" >&2
echo "$tag Consumers read the MIRROR, not this repo: each Mac's host-side" >&2
echo "$tag ~/.agents/skills/pi-extensions symlinks into it, and a workstation with" >&2
echo "$tag only skillset cloned has no other copy. Refresh it:" >&2
echo "$tag" >&2
echo "$tag   cp $repo_root/skill/SKILL.md $repo_root/skill/evaluate-extension-usage.py $skillset/$MIRROR_SUBPATH/" >&2
echo "$tag   sed -i 's/^# Last refreshed from: .*/# Last refreshed from: pi-extensions $short/' $skillset/$MIRROR_SUBPATH/.skill-source" >&2
echo "$tag   git -C $skillset commit -m 'skills(pi-extensions): refresh mirror from upstream $short' $MIRROR_SUBPATH" >&2
echo "$tag" >&2
echo "$tag Not blocking this push -- the refresh comes after it. skillset's own" >&2
echo "$tag pre-commit gate will refuse a commit that leaves the mirror stale." >&2
exit 0
