Skip to main content

Module enrich

Module enrich 

Source
Expand description

mushroomdb enrich — the optional PostToolUse hook body for Grep.

Claude Code runs this after a Grep has returned, handing it the tool call and its result as JSON on stdin. A grep answers “where does this name appear”; the graph answers “what is it” — where it is defined, how many places call it, who owns the file. This hook appends the second answer to the first, so the names the search just surfaced arrive with their definitions rather than as a list of line numbers.

Unlike crate::intercept, which replaces a search, this only ever adds to one: adoption is by construction, since nothing has to be chosen.

§What it looks at

The pattern first — a grep for a bare name is usually a grep for that symbol — and then the identifiers in the result text, which is where a regex search’s real subjects are. A token earns a line only if it resolves to a Symbol the graph holds, through the same lookup context uses for a bare name, so a token that is merely a word costs nothing but a map lookup.

Everything else — a store that will not open, a payload that will not parse, a pattern that names nothing — is silence, like every other hook this binary writes.

§Where the facts land

The text goes out as additionalContext on a hookSpecificOutput object, which puts it in the turn beside the tool result — not inside it. Claude Code also documents updatedToolOutput for PostToolUse, which would rewrite the result itself, but the reference’s list of the tools that support it could not be retrieved when this was written, and a key the host ignores is a hook that silently does nothing. Anyone reading the grep- enrichment arm’s numbers should read them as “the facts arrived in the same turn, adjacent to the matches”, not “the matches came back annotated”.

§Cost

One pass over the Symbol nodes builds the name index ([name_index]), and every candidate is answered out of it. Asking the graph per candidate instead would be up to [MAX_CANDIDATES] full scans of the symbol table on every single Grep, which is the whole budget spent on names that mostly turn out to be ordinary words.

Constants§

MAX_CONTEXT_BYTES
The most this hook may append to a tool result. Wider than the pre-edit budget because a grep result is already long and the facts have to be distinguishable from it, and still small enough that a search-heavy session does not pay for it twice over.

Functions§

run
The whole hook body: parse the payload, open the store, describe whatever the search named that the graph holds.