The MCP tools wait to be called. Hooks don't. They fire from editor lifecycle and tool-use events and push context to your agent with zero effort on its part, and keep your index fresh on every commit.
This page is about the proactive context hooks below (SessionStart,
PostToolUse, the command-rewrite hook). For the git post-commit hook that
auto-syncs your index on every commit, see repowise hook.
repowise init installs that one for you by default; --no-hook skips it.
Every agent hook shares the same guarantees: no LLM calls, no network, only
local SQLite (wiki.db) and git reads. They are import-isolated (cold start
under ~500ms) and any failure exits 0 silently, so a broken environment never
crashes or blocks the agent.
The hooks at a glance
| Hook | Family | Installed by | Fires on | What it does |
|---|---|---|---|---|
| Post-commit auto-sync | git | repowise init by default (--no-hook skips it), or repowise hook install | every git commit | Runs repowise update in the background |
| SessionStart context | Claude Code | repowise init | startup / resume / clear | Live index freshness + the standing decisions relevant to this session |
| PostToolUse enrichment | Claude Code | repowise init | Grep / Glob / Read / Edit / Write / repowise MCP calls | Graph context on searches, read-intelligence notices, edit-time "governed by" notices |
| Command-rewrite (distill) | Claude Code | repowise hook rewrite install (opt-in) | shell commands | Rewrites noisy commands to repowise distill <cmd> and runs them automatically, no approval prompt by default |
| Codex context + staleness | Codex | repowise init --codex | lifecycle / edit / shell | Reminds Codex to use the MCP tools and flags stale context after edits |
The git hook is documented under the hook CLI command; the
rest are covered below.
SessionStart: live freshness and relevant decisions
The generated CLAUDE.md is static between reindexes, so it can't say whether
the index is current right now. This hook adds a short per-session block so the
agent starts with calibrated trust instead of discovering staleness mid-task:
- Index current → one line saying so, plus the core-tool pointer.
- Update running → a positive "catching up" notice, never a stale scare.
- Index behind → indexed vs
HEADwith a changed-file count, and the target-scoped trust rule (a stale warning fires only when a file a response actually served has changed).
It also carries the relevance-ranked standing decisions for this session.
repowise scores the repo's active decisions against the session's likely working
set (dirty and staged files, files changed on the branch vs main, the previous
session's edited files, and branch-name tokens) expanded one hop through import
edges and co-change partners. The top few land under a hard token cap. Relevance
or silence: nothing clears the floor, nothing is injected, and decisions are
never shown just for being high-confidence.
PostToolUse: enrichment on every tool call
One hook covers several jobs, matched on the agent's Grep / Glob / Read /
Edit / Write and repowise MCP calls:
Grep/Glob enrichment. When the agent runs a broad or zero-result search,
repowise appends focused context pulled straight from wiki.db: the symbols
defined in each related file, what imports it, what it depends on, and its git
signals (hotspot, bus factor, owner). An agent that greps for PageGenerator
immediately knows what depends on it and that it's a hotspot, without a separate
MCP call:
[repowise] 2 related file(s) found:
packages/core/.../page_generator.py
Symbols: function:_now_iso, class:PageGenerator, method:__init__
Imported by: init_cmd.py, update_cmd.py, generation/__init__.py
Depends on: context_assembler.py, base.py, models.py
Git: HOTSPOT, bus-factor=1Read-intelligence. On a read of an indexed file, repowise can nudge the agent
toward the cheaper get_context(..., include=["skeleton"]) for structure-level
questions, and emit a per-file stale-read notice when the file changed after
indexing.
Edit-time "governed by" decisions. When the agent edits a file governed by an architectural decision, it gets a one-line notice with the rationale, at most once per session per decision, so the decision reaches the agent right when it's about to honor or violate it.
Command-rewrite (distill), opt-in
The rewrite hook intercepts noisy shell commands and rewrites them to
repowise distill <cmd>, which compresses the output
errors-first before the agent reads it, exit code preserved and every omission
reversible.
The default permission is allow, not ask. Once you install the hook,
a recognized command (test/lint/build/git/search/listing/log) is rewritten
and run automatically, with no approval prompt, for the main agent and every
subagent. This is deliberate: the hook only ever rewrites a closed set of
recognized command families, with no redirects, compound commands,
substitution, or interactive commands, and at most a single trailing
head/tail/grep/rg filter, so the rewritten command is always
repowise distill <one recognized command>, never something else smuggled
through. If you want to review every rewrite before it runs, set
permission: ask in .repowise/config.yaml; setting a family to off
exempts it from rewriting entirely.
The hook never touches pipes it doesn't recognize, compound commands, or watch
modes. Install and manage it via repowise hook rewrite.
Codex hooks
repowise init --codex writes project-local Codex hooks (it does not touch
your global ~/.codex/config.toml):
- SessionStart reminds Codex to use the repowise MCP tools for architecture, search, risk, decisions, and dead-code analysis, and carries the same relevance-ranked standing decisions Claude Code receives.
- PostToolUse, on the shell tool and on
apply_patch/Edit/Write, comparesHEADagainst the last indexed commit after a successfulgit commit,merge,rebase,cherry-pickorpulland flags that indexed context may be stale.
Nothing is registered on UserPromptSubmit. Firing on every prompt only
repeats the MCP-usage note SessionStart already delivered, at the cost of a
hook run per turn. If an older install of ours is still on that event,
repowise agents refresh rewrites this repo's .codex/hooks.json and clears
it. A hook you wrote there is left alone.
Codex names its shell tool shell_command on current releases and Bash on
older ones, so the matcher covers both. The Claude Code PostToolUse hook
deliberately does not watch shell commands: it has Read / Grep / Glob
and a SessionStart freshness line, so the shell adds cost without adding
reach. Codex has neither. See
Connecting Codex for setup.
Learns from how you actually use it
The hooks aren't just delivery; they close a loop. Injected decision ids are
recorded locally, and on the next repowise update the session miner checks
whether each piece of guidance was followed or contradicted by your corrections,
relaxing or bumping the decision's staleness so guidance that stops being true
stops being injected.
That feedback is one half of a flywheel that makes repowise adapt to your repo, all local and deterministic:
- Decisions mined from your own sessions: the corrections and conventions you actually enforce become tracked decisions, delivered back at session start and edit time.
- Docs that follow your questions: the wiki generation budget tilts toward the modules you and your agent ask about most, so depth lands where you actually work.
Hooks and MCP tools are complementary. Hooks are passive, automatic, and free: they fire whether or not the agent is thinking about graph context. MCP tools are active and richer, for when the agent needs full documentation, a risk assessment, or dependency tracing.