hooks: warn at push time when skill/ changes are not yet mirrored
Editing skill/ here is only half the job: skillset mirrors it at skills/pi-extensions/, and that copy is what most consumers actually read -- each Mac's host-side ~/.agents/skills/pi-extensions symlinks into it, and a workstation with only skillset cloned has no other copy. The refresh is a manual cp in another repo and it has now been forgotten on two consecutive edits, so the mirror drifted 4890 B behind, then 9579 B. hooks/pre-push compares the PUSHED content (git show <sha>:skill/...) against the mirror on disk and prints the exact cp/sed/commit sequence when they differ. Pushed content rather than the worktree: uncommitted local edits are not what this push publishes. It warns and exits 0 rather than blocking, for two reasons that are not squeamishness: the direction rule is "edit upstream, THEN refresh", so the refresh legitimately comes after this push, and it is a commit in a different repo that cannot be made from here. Enforcement belongs downstream and already exists -- skillset's pre-commit gate refuses a commit that leaves the mirror stale. This hook only shortens time-to-detection from "next skillset commit" to "seconds, to the person who caused it". Silent when the mirror already matches, when the push does not touch skill/, on branch deletions, and when no skillset clone is on disk -- a reminder that cannot be acted on is noise that trains people to skim hook output. install.sh activates it (core.hooksPath=hooks, per-clone config that cannot be tracked), preserves a foreign hooksPath rather than clobbering it, and does NOT undo the activation on --uninstall: removing a safety gate as a side effect of uninstalling extensions would be a surprise in the wrong direction. Verified: all three activate_hooks branches in a throwaway repo, and five pre-push scenarios driven through the real stdin protocol (stale -> warns, in-sync -> silent, non-skill push -> silent, branch deletion -> silent, no skillset clone -> silent).
This commit is contained in:
+28
@@ -176,10 +176,38 @@ do_install() {
|
||||
ok "Linked ${name} → ${src}"
|
||||
done
|
||||
|
||||
echo
|
||||
activate_hooks
|
||||
|
||||
echo
|
||||
ok "Done. Reload pi with /reload or restart to pick up new extensions."
|
||||
}
|
||||
|
||||
# ── commit/push hooks ────────────────────────────────
|
||||
# core.hooksPath is per-clone git CONFIG and cannot be tracked, so a fresh clone
|
||||
# has no hooks until something sets it. This is that something.
|
||||
#
|
||||
# Deliberately NOT undone by --uninstall: uninstall means "stop managing my pi
|
||||
# extensions", and silently removing a safety gate as a side effect of that would
|
||||
# be a surprise in the wrong direction. Unset it by hand if you want it gone.
|
||||
activate_hooks() {
|
||||
[[ -d "${SCRIPT_DIR}/hooks" ]] || return 0
|
||||
|
||||
local cur
|
||||
cur="$(git -C "$SCRIPT_DIR" config --local core.hooksPath 2>/dev/null || true)"
|
||||
|
||||
if [[ -z "$cur" ]]; then
|
||||
git -C "$SCRIPT_DIR" config core.hooksPath hooks
|
||||
ok "Activated repo hooks (core.hooksPath=hooks)"
|
||||
ok " pre-push warns when a skill/ change needs mirroring into skillset"
|
||||
elif [[ "$cur" == "hooks" ]]; then
|
||||
ok "Repo hooks already active (core.hooksPath=hooks)"
|
||||
else
|
||||
warn "core.hooksPath is '$cur', leaving it alone -- the skill-mirror"
|
||||
warn "pre-push reminder will not run. Copy hooks/pre-push into '$cur' to keep it."
|
||||
fi
|
||||
}
|
||||
|
||||
# ── uninstall ────────────────────────────────────────
|
||||
do_uninstall() {
|
||||
echo
|
||||
|
||||
Reference in New Issue
Block a user