Repository navigation
fix: hooks need only bash and node; missing tools fail visibly (GIT-116) - #51
Merged
3 commits merged intoSep 23, 2026
Merged
3 commits merged into
3 commits merged into
Conversation
auto-retrieve-hook.sh ran `timeout 2.5 node …`. macOS ships no timeout, the error went to /dev/null, and the hook exited as "nothing relevant", so auto-retrieve never ran on a stock Mac. - quick-retrieve bounds its own run (armDeadline, 2.5 s, unref'd); the hook calls node directly. - Hooks copied into <repo>/.gitmem/hooks looked for a package named "gitmem"; it is gitmem-mcp. The lookup now tries the gitmem-mcp bin, npx's cache (how most installs run it) and the global node_modules. - A missing node or quick-retrieve module is a visible non-blocking hook error (exit 1, reason on stderr), not a silent empty result. The node check runs before prompt extraction, which needed node too. - session-start.sh: debug log per user in $TMPDIR and never fatal under set -e; no pgrep skips the 7 s readiness gate instead of stalling; `which` -> `command -v`; no GNU-only `date +%N`. - resolve-root.sh: pid liveness via kill -0, then /proc (Linux) or ps (macOS), not kill's English error text; host from bash's $HOSTNAME. - credential-guard.sh: the path is JSON-escaped. A quote in it made the block output invalid JSON, which Claude Code treats as allow. test-hooks.sh: +7 portability tests using PATHs with the tool removed (53/53; main fails 6). Unit: +4 (deadline, unref, no timeout call left). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sh depends on it (GIT-116) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…q (GIT-116) macos-latest (macOS 15) has /usr/bin/jq as a system tool, so asserting its absence failed the job. The jq-less path stays covered by hooks-without-jq on Linux; the macOS leg now reports whether stock jq is present. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
What
The hooks need only
bashandnode, and a missing tool is now a visible failure instead of a silent "nothing relevant" (GIT-116).quick-retrieve(armDeadline: 2.5 s, unref'd, reason on stderr);auto-retrieve-hook.shcallsnodedirectly, with notimeoutwrapper.quick-retrieve.jsfrom hooks copied into<repo>/.gitmem/hooks(byinit/install-hooks): the lookup searched for a package calledgitmem, but it isgitmem-mcp. It now tries thegitmem-mcpbin, npx's cache (how most installs run it, newest first) and the globalnode_modules.node, or no module found, is a non-blocking hook error: exit 1 with the reason on stderr (exit 2 would block the prompt). The node check now runs before prompt extraction, which also needed node.session-start.sh:$TMPDIR, never fatal underset -e(an unwritable/tmplog killed the hook);pgrep→ skip the 7 s readiness gate rather than stall;which→command -v;date +%N.resolve-root.sh: pid liveness viakill -0, then/proc(Linux) orps(macOS), instead of matching kill's English error text; host from bash's$HOSTNAME.credential-guard.sh: the path is JSON-escaped. A quote in it made the block output invalid JSON, which Claude Code treats as allow, so the RED LINE block silently disappeared.hooks-macosjob runs the suite onmacos-latestwith a stock PATH (system dirs plus a node-only dir, so no Homebrew). It assertstimeout/gtimeoutare absent. Publish depends on it. Found on the first run: macOS 15 ships/usr/bin/jq, so the job reports stockjqrather than asserting its absence; the jq-less path is covered byhooks-without-jqon Linux.Tool sweep (audit class D, category 6)
timeout/gtimeoutnodenpm root -g,which gitmemnpmnot always on PATH; wrong package namecommand -v gitmem-mcp, npx cache, thennpm root -g(correct name)pgrepwhichcommand -v(builtin)hostname$HOSTNAMEfirstkill -0text match/procorpsps/procis absentjqdate +%s%NN)date +%sgrep -Ewith\b,\s;sed(no-i);awk;tr;mktemp;idOut of scope and noted:
display-hook.shis shipped but not wired anywhere (dead code);/tmp/gitmem-hooks-$SESSION_IDkeying belongs to GIT-103.How to test
bash hooks/tests/test-hooks.sh: +7 portability tests, each using a PATH with the tool removed so they fail on any OS. There are also +4 unit tests: deadline timing, unref, and no hook callingtimeout.origin/mainhookshooks-without-jq(Linux) /hooks-macosOn
mainthe new tests fail as follows: auto-retrieve withouttimeoutreturns nothing; no node exits 0 silently; module not found exits 0 silently; the npx cache is not searched; nopgrepstalls about 7 s; the credential block with a quoted path is invalid JSON. The unwritable-log test passes vacuously onmain, becausemainwrites to a fixed/tmppath the test can't make unwritable.Venue: not applicable; hooks only. Unit: 1361/1361.
Checklist
🤖 Generated with Claude Code