fix: auto-install SessionStart hook so buddy survives Claude Code updates#31
Merged
cpaczek merged 2 commits intoApr 4, 2026
Merged
Conversation
Co-Messi
added a commit
to Co-Messi/any-buddy
that referenced
this pull request
Apr 4, 2026
Hook install gaps (from code review of PR cpaczek#31): - apply.ts: hook was only installed in the ORIGINAL_SALT fallthrough path; the previousSalt and ORIGINAL_SALT early-return branches inside !oldSalt both returned before reaching it. Extract autoInstallHook() helper and call it before every successful-patch return. - apply.ts: --no-hook flag was silently dropped — runApply() had no noHook param so the flag was ignored. Add noHook param and pass it from cli.ts. - buddies.ts: runBuddies() patched the binary but never installed the hook. Stale-snapshot write (missed in PR cpaczek#24): - buddies.ts isDefault branch: config was the snapshot from the top of runBuddies(), read before saveProfile(outgoing) wrote to disk. Reload fresh immediately before savePetConfigV2 to avoid clobbering that write. - buddies.ts incoming profile read: after switchToProfile() writes to disk, reload fresh config to read the incoming profile rather than the stale pre-switch snapshot. preview.ts edge case (from code review of PR cpaczek#26): - cols - 4 can be negative when stdout.columns < 4 (piped output, very narrow TTY). String.repeat throws RangeError on negative values. Wrap with Math.max(0, cols - 4).
…ates Previously the hook prompt defaulted to 'No' (sequential flow) or required an explicit 'Y' keypress (TUI flow), so most users skipped it. Without the hook, every Claude Code auto-update silently wipes the pet patch and there is no recovery until the user manually runs `any-buddy apply`. The hook is not optional — it is the mechanism that keeps the buddy alive across updates. Install it automatically after every successful patch across all three apply paths (TUI, sequential, and `any-buddy apply` command). Users can remove it by editing ~/.claude/settings.json directly.
Hook install gaps (from code review of PR cpaczek#31): - apply.ts: hook was only installed in the ORIGINAL_SALT fallthrough path; the previousSalt and ORIGINAL_SALT early-return branches inside !oldSalt both returned before reaching it. Extract autoInstallHook() helper and call it before every successful-patch return. - apply.ts: --no-hook flag was silently dropped — runApply() had no noHook param so the flag was ignored. Add noHook param and pass it from cli.ts. - buddies.ts: runBuddies() patched the binary but never installed the hook. Stale-snapshot write (missed in PR cpaczek#24): - buddies.ts isDefault branch: config was the snapshot from the top of runBuddies(), read before saveProfile(outgoing) wrote to disk. Reload fresh immediately before savePetConfigV2 to avoid clobbering that write. - buddies.ts incoming profile read: after switchToProfile() writes to disk, reload fresh config to read the incoming profile rather than the stale pre-switch snapshot. preview.ts edge case (from code review of PR cpaczek#26): - cols - 4 can be negative when stdout.columns < 4 (piped output, very narrow TTY). String.repeat throws RangeError on negative values. Wrap with Math.max(0, cols - 4).
9635ae2 to
f56d898
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Every Claude Code auto-update resets the binary, wiping the pet patch. The existing
SessionStarthook (any-buddy apply --silent) is the correct fix — it re-patches automatically on next session start. But the hook was opt-in with a default of No, so the vast majority of users never had it installed.Sequential flow (
interactive.ts): prompt defaulted tofalse— pressing Enter skipped itTUI flow (
apply/index.ts): required an explicitYkeypress; Enter/Esc both skipped itResult: users' buddies silently disappear after every Claude update with no explanation.
Fix
The hook is not optional — it is the mechanism that keeps the buddy alive across updates. Auto-install it after every successful patch across all three apply paths:
apply/index.ts):confirm_hookstep now installs silently and advances todoneinteractive.ts): replaced the opt-in confirm prompt with auto-install + a one-line status messageany-buddy applycommand (apply.ts): installs the hook after a successful manual re-patch if not already presentThe
--no-hookflag continues to suppress installation for users who explicitly opt out.Test plan
any-buddy, complete setup — hook appears in~/.claude/settings.jsonwithout being promptedany-buddy apply --silent— pet re-applies--no-hookflag: hook is not installedpnpm test— all 203 tests pass