fix(install): generate copilot hooks with absolute paths

Instead of symlinking ~/.copilot/hooks/agent-support.json to dotfiles
hooks.json (which uses relative paths resolved from workspace root),
generate the file at install time with absolute paths to dotfiles hooks.

This means projects no longer need per-project hook stubs or symlinks.
A project only needs .agents/hooks/post-tool-use-remnant.sh (or similar)
for its own overlay, wired as a second PostToolUse in .github/hooks/.
This commit is contained in:
Brydon DeWitt 2026-05-22 21:15:42 -04:00
parent 88435d6b51
commit f4017abf45

View File

@ -11,16 +11,38 @@ warn() { printf '\033[0;33m⚠\033[0m %s\n' "$1"; }
skip() { printf '\033[0;34m\033[0m %s\n' "$1"; } skip() { printf '\033[0;34m\033[0m %s\n' "$1"; }
# ── 1. Copilot global hooks ────────────────────────────────────────────────── # ── 1. Copilot global hooks ──────────────────────────────────────────────────
# Generate ~/.copilot/hooks/agent-support.json with absolute paths so the hooks
# work from any workspace — no per-project symlinks or stubs needed.
COPILOT_HOOKS_DIR="$HOME/.copilot/hooks" COPILOT_HOOKS_DIR="$HOME/.copilot/hooks"
COPILOT_HOOK_TARGET="$DOTFILES_AGENTS/frameworks/github/hooks.json" COPILOT_HOOK_FILE="$COPILOT_HOOKS_DIR/agent-support.json"
COPILOT_HOOK_LINK="$COPILOT_HOOKS_DIR/agent-support.json"
mkdir -p "$COPILOT_HOOKS_DIR" mkdir -p "$COPILOT_HOOKS_DIR"
if [[ -L "$COPILOT_HOOK_LINK" && "$(readlink "$COPILOT_HOOK_LINK")" == "$COPILOT_HOOK_TARGET" ]]; then
skip "Copilot hook symlink already set: $COPILOT_HOOK_LINK" # Migrate: remove old symlink if present
if [[ -L "$COPILOT_HOOK_FILE" ]]; then
rm "$COPILOT_HOOK_FILE"
log "Removed old Copilot hook symlink (migrating to generated file)"
fi
EXPECTED_PRE="$DOTFILES_AGENTS/hooks/pre-tool-use.sh"
if [[ -f "$COPILOT_HOOK_FILE" ]] && \
node -e "const c=JSON.parse(require('fs').readFileSync('$COPILOT_HOOK_FILE','utf8')); process.exit(c.hooks&&c.hooks.PreToolUse&&c.hooks.PreToolUse[0].command==='$EXPECTED_PRE'?0:1);" 2>/dev/null; then
skip "Copilot global hooks already up-to-date: $COPILOT_HOOK_FILE"
else else
ln -sf "$COPILOT_HOOK_TARGET" "$COPILOT_HOOK_LINK" node -e "
log "Copilot hook symlink: $COPILOT_HOOK_LINK$COPILOT_HOOK_TARGET" const fs = require('fs');
const d = '$DOTFILES_AGENTS/hooks';
const hooks = {
UserPromptSubmit: [{type:'command',command:d+'/user-prompt-submit.sh',timeout:5}],
SessionStart: [{type:'command',command:d+'/session-start.sh',timeout:10}],
PreToolUse: [{type:'command',command:d+'/pre-tool-use.sh',timeout:5}],
PostToolUse: [{type:'command',command:d+'/post-tool-use.sh',timeout:5}],
PreCompact: [{type:'command',command:d+'/pre-compact.sh',timeout:10}],
Stop: [{type:'command',command:d+'/stop.sh',timeout:5}]
};
fs.writeFileSync('$COPILOT_HOOK_FILE', JSON.stringify({hooks}, null, 2) + '\n');
"
log "Copilot global hooks generated with absolute paths: $COPILOT_HOOK_FILE"
fi fi
# ── 2. OpenCode global plugin ──────────────────────────────────────────────── # ── 2. OpenCode global plugin ────────────────────────────────────────────────