You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Claude Code Bash searches bypass codebase-memory hook augmentation #1082
Claude Code commonly runs rg, grep, and find through the Bash tool, so code discovery silently bypasses graph augmentation when the PreToolUse matcher only covers Grep|Glob.
Expected behavior
Bash-based code searches should receive the same graph augmentation as native Grep searches, or the installer should provide a reliable Claude Code integration that detects these searches.
Workaround
A Bash PreToolUse adapter that extracts the search pattern, reshapes the payload as Grep, and forwards it to hook-augment restores the expected context.
This is an integration/installer issue: the MCP graph query itself works, but Claude Code's common Bash search path bypasses it.
Thanks for the concrete hook payload comparison. This is triaged as a 0.9.1-rc editor-integration bug. Any fix must recognize only well-defined Bash search invocations and must not evaluate or rewrite arbitrary shell commands; review will also check that native Grep/Glob behavior remains unchanged.
I can take this. Already have a working version: it pulls the search pattern out of the bash command with shlex (no exec, doesn't touch the command itself) and feeds it to the same augment path Grep already uses, so it's purely additive and leaves Grep/Glob alone. When it can't get one clear pattern out (-f pattern files, multiple -es) it just does nothing rather than guessing.
Couple things before I open a PR:
Would you rather this live in hook-augment itself (detecting the Bash payload), or as a separate Bash hook? I'd lean toward the former.
Scope right now is grep/rg/ag/ack/ugrep plus git grep. Anything else you'd want covered?
Worth covering token-saver wrappers too — plenty of us prefix every shell command with one, so searches reach the hook as rtk grep -n foo . (rtk) or tokf run rg -n foo . (tokf), and argv[0] is the wrapper rather than a search binary. Popping leading VAR=value assignments plus a tiny allowlist (rtk, env, nice, time, command, and the two-token tokf run) before your binary check would cover those and plain env FOO=1 rg ... alike. Heads up on rtk though: rtk grep adds its own -l <N> that shadows grep's valueless -l, so rtk grep -l 80 pattern probably wants the same bail-out you're doing for -f.
Thanks @dergachoff for the wrapper cases and especially the rtk -l ambiguity.
Current main has no wrapper-unwrapping layer in hook-augment, so these commands remain outside the proposed direct grep/rg recognition. Any extension must parse tokens without executing the shell, unwrap only an explicit allowlist, and fail open when wrapper and underlying-option grammars conflict. rtk grep -l 80 is therefore a required negative test, not just an implementation note.
I have recorded this as review scope for the existing 0.9.1 integration bug. It does not add a runtime dependency on either wrapper. Thank you for supplying concrete argv shapes.
Environment: v0.9.0 (also reproduced after the 2026-08-10 18:05 self-update), Claude Code 2.1.220 installMethod: native, macOS 26.5.2 (25F84) arm64.
Confirming this, and adding the cause plus a reason the obvious one-line fix is not sufficient.
The tools are gone, not merely bypassed
Claude Code v2.1.117 (April 2026) removed the Glob and Grep tools from native macOS and Linux builds, replacing them with embedded bfs and ugrep reached through the Bash tool. Windows and npm-installed builds are unaffected.
So on those builds the hook is not being bypassed by a user preferring Bash — the matcher targets tools that do not exist in the session at all.
Verified on 2.1.220, installMethod: native:
/hooks shows the entry registered as [Local] Grep|Glob — 1 hook. Registration is fine.
The session reports no Grep or Glob in its tool list, checked via ToolSearch in two independent sessions. Read is present and works, so this is specific to the search tools.
The Claude Code binary embeds bfs (36 string occurrences including bfs_ctx_new, bfs_expr_new, bfs_fork_spawn) and ugrep (43).
Retargeting the matcher alone will not fix it
The augmenter hard-codes Grep and Glob as literals in its own tool_name check. Changing only the matcher in settings.json leaves the internal check unmatched and the hook still does nothing. Both need changing together.
#858 was closed suspecting HA_DEADLINE_MS (300ms) was too tight, on the evidence that additionalContext never appeared in 24 observed sessions. If the reporter was on a native macOS or Linux build, the hook could not have fired regardless of the deadline. Worth re-checking that closure against installMethod.
On the Read exclusion
The README excludes Read because "gating Read breaks the read-before-edit invariant". That reasoning concerns gating. This hook is non-blocking by design — exit 0 on every path, exit code discarded — so it is structurally incapable of breaking that invariant. Worth revisiting whether Read is a legitimate target for a purely additive hook, since on these builds it is one of only three file-access tools left.
Note on the silence
The shim discards stderr, discards hook-augment's exit code, and returns exit 0 unconditionally. Combined with a matcher that cannot match, the tool installs cleanly, reports no error, and does nothing indefinitely. A diagnostic path — even a --verify-hooks subcommand — would have surfaced this long before it reached two separate projects (graphify #578 is the same defect).
The project already treats Bash as a legitimate matcher target: #715 proposes matcher = "Grep|Glob|Bash" for Codex.
Thank you for adding the current Claude Code behavior. Current main still installs a PreToolUse matcher for Grep|Glob, so a native client that routes discovery through Bash and Read can bypass augmentation exactly as described. I have linked this under the editor and agent integration epic and kept it in the immediate bug train.
Activity
DeusData commentedon Jul 14, 2026
Thanks for the concrete hook payload comparison. This is triaged as a 0.9.1-rc editor-integration bug. Any fix must recognize only well-defined Bash search invocations and must not evaluate or rewrite arbitrary shell commands; review will also check that native Grep/Glob behavior remains unchanged.
abendrothj commentedon Jul 15, 2026
I can take this. Already have a working version: it pulls the search pattern out of the bash command with shlex (no exec, doesn't touch the command itself) and feeds it to the same augment path Grep already uses, so it's purely additive and leaves Grep/Glob alone. When it can't get one clear pattern out (
-fpattern files, multiple-es) it just does nothing rather than guessing.Couple things before I open a PR:
hook-augmentitself (detecting the Bash payload), or as a separate Bash hook? I'd lean toward the former.git grep. Anything else you'd want covered?Can target 0.9.1-rc.
dergachoff commentedon Jul 27, 2026
Worth covering token-saver wrappers too — plenty of us prefix every shell command with one, so searches reach the hook as
rtk grep -n foo .(rtk) ortokf run rg -n foo .(tokf), andargv[0]is the wrapper rather than a search binary. Popping leadingVAR=valueassignments plus a tiny allowlist (rtk,env,nice,time,command, and the two-tokentokf run) before your binary check would cover those and plainenv FOO=1 rg ...alike. Heads up on rtk though:rtk grepadds its own-l <N>that shadows grep's valueless-l, sortk grep -l 80 patternprobably wants the same bail-out you're doing for-f.DeusData commentedon Jul 28, 2026
Thanks @dergachoff for the wrapper cases and especially the rtk -l ambiguity.
Current main has no wrapper-unwrapping layer in hook-augment, so these commands remain outside the proposed direct grep/rg recognition. Any extension must parse tokens without executing the shell, unwrap only an explicit allowlist, and fail open when wrapper and underlying-option grammars conflict. rtk grep -l 80 is therefore a required negative test, not just an implementation note.
I have recorded this as review scope for the existing 0.9.1 integration bug. It does not add a runtime dependency on either wrapper. Thank you for supplying concrete argv shapes.
feat(hook-augment): augment Bash tool searches via graph
feat(hook-augment): augment Bash tool searches via graph
maheshmirchandani commentedon Aug 10, 2026
Environment: v0.9.0 (also reproduced after the 2026-08-10 18:05 self-update), Claude Code 2.1.220
installMethod: native, macOS 26.5.2 (25F84) arm64.Confirming this, and adding the cause plus a reason the obvious one-line fix is not sufficient.
The tools are gone, not merely bypassed
Claude Code v2.1.117 (April 2026) removed the
GlobandGreptools from native macOS and Linux builds, replacing them with embeddedbfsandugrepreached through theBashtool. Windows and npm-installed builds are unaffected.So on those builds the hook is not being bypassed by a user preferring Bash — the matcher targets tools that do not exist in the session at all.
Verified on 2.1.220,
installMethod: native:/hooksshows the entry registered as[Local] Grep|Glob — 1 hook. Registration is fine.GreporGlobin its tool list, checked via ToolSearch in two independent sessions.Readis present and works, so this is specific to the search tools.bfs(36 string occurrences includingbfs_ctx_new,bfs_expr_new,bfs_fork_spawn) andugrep(43).Retargeting the matcher alone will not fix it
The augmenter hard-codes
GrepandGlobas literals in its owntool_namecheck. Changing only the matcher insettings.jsonleaves the internal check unmatched and the hook still does nothing. Both need changing together.Possible bearing on #858
#858 was closed suspecting
HA_DEADLINE_MS(300ms) was too tight, on the evidence thatadditionalContextnever appeared in 24 observed sessions. If the reporter was on a native macOS or Linux build, the hook could not have fired regardless of the deadline. Worth re-checking that closure againstinstallMethod.On the Read exclusion
The README excludes
Readbecause "gating Read breaks the read-before-edit invariant". That reasoning concerns gating. This hook is non-blocking by design —exit 0on every path, exit code discarded — so it is structurally incapable of breaking that invariant. Worth revisiting whetherReadis a legitimate target for a purely additive hook, since on these builds it is one of only three file-access tools left.Note on the silence
The shim discards stderr, discards
hook-augment's exit code, and returnsexit 0unconditionally. Combined with a matcher that cannot match, the tool installs cleanly, reports no error, and does nothing indefinitely. A diagnostic path — even a--verify-hookssubcommand — would have surfaced this long before it reached two separate projects (graphify #578 is the same defect).The project already treats
Bashas a legitimate matcher target: #715 proposesmatcher = "Grep|Glob|Bash"for Codex.DeusData commentedon Aug 10, 2026
Thank you for adding the current Claude Code behavior. Current
mainstill installs aPreToolUsematcher forGrep|Glob, so a native client that routes discovery throughBashandReadcan bypass augmentation exactly as described. I have linked this under the editor and agent integration epic and kept it in the immediate bug train.