|
ce0374a…
|
lmata
|
1 |
# Agent Hooks |
|
ce0374a…
|
lmata
|
2 |
|
|
ce0374a…
|
lmata
|
3 |
Agent hooks keep the navegador graph in sync as AI coding agents work. Without hooks, the graph goes stale the moment an agent edits a file. With hooks, the graph is re-ingested automatically after every file write, and architectural decisions in `DECISIONS.md` are synced into the knowledge layer. |
|
ce0374a…
|
lmata
|
4 |
|
|
ce0374a…
|
lmata
|
5 |
--- |
|
ce0374a…
|
lmata
|
6 |
|
|
ce0374a…
|
lmata
|
7 |
## Why hooks |
|
ce0374a…
|
lmata
|
8 |
|
|
ce0374a…
|
lmata
|
9 |
A stale graph gives wrong answers. If an agent adds a new function and then asks `navegador function` about a caller, the graph needs to reflect the edit. Hooks solve this by triggering `navegador ingest` on the modified files immediately after the agent writes them. |
|
ce0374a…
|
lmata
|
10 |
|
|
ce0374a…
|
lmata
|
11 |
Hooks also enforce the habit: every agent session starts with the graph as ground truth, not a stale snapshot. |
|
ce0374a…
|
lmata
|
12 |
|
|
ce0374a…
|
lmata
|
13 |
--- |
|
ce0374a…
|
lmata
|
14 |
|
|
ce0374a…
|
lmata
|
15 |
## Claude Code |
|
ce0374a…
|
lmata
|
16 |
|
|
ce0374a…
|
lmata
|
17 |
### Install |
|
ce0374a…
|
lmata
|
18 |
|
|
ce0374a…
|
lmata
|
19 |
The hook file lives at `.claude/hooks/claude-hook.py`. Bootstrap installs it automatically: |
|
ce0374a…
|
lmata
|
20 |
|
|
ce0374a…
|
lmata
|
21 |
```bash |
|
ce0374a…
|
lmata
|
22 |
./bootstrap.sh --repo owner/repo --agent claude |
|
ce0374a…
|
lmata
|
23 |
``` |
|
ce0374a…
|
lmata
|
24 |
|
|
ce0374a…
|
lmata
|
25 |
To install manually, copy `hooks/claude-hook.py` from the navegador repo into your project's `.claude/hooks/` directory. |
|
ce0374a…
|
lmata
|
26 |
|
|
ce0374a…
|
lmata
|
27 |
### settings.json config |
|
ce0374a…
|
lmata
|
28 |
|
|
ce0374a…
|
lmata
|
29 |
In your project's `.claude/settings.json`, register the hook: |
|
ce0374a…
|
lmata
|
30 |
|
|
ce0374a…
|
lmata
|
31 |
```json |
|
ce0374a…
|
lmata
|
32 |
{ |
|
ce0374a…
|
lmata
|
33 |
"hooks": { |
|
ce0374a…
|
lmata
|
34 |
"PostToolUse": [ |
|
ce0374a…
|
lmata
|
35 |
{ |
|
ce0374a…
|
lmata
|
36 |
"matcher": "Write|Edit|MultiEdit", |
|
ce0374a…
|
lmata
|
37 |
"hooks": [ |
|
ce0374a…
|
lmata
|
38 |
{ |
|
ce0374a…
|
lmata
|
39 |
"type": "command", |
|
ce0374a…
|
lmata
|
40 |
"command": "python .claude/hooks/claude-hook.py" |
|
ce0374a…
|
lmata
|
41 |
} |
|
ce0374a…
|
lmata
|
42 |
] |
|
ce0374a…
|
lmata
|
43 |
} |
|
ce0374a…
|
lmata
|
44 |
] |
|
ce0374a…
|
lmata
|
45 |
} |
|
ce0374a…
|
lmata
|
46 |
} |
|
ce0374a…
|
lmata
|
47 |
``` |
|
ce0374a…
|
lmata
|
48 |
|
|
ce0374a…
|
lmata
|
49 |
### What the hook does |
|
ce0374a…
|
lmata
|
50 |
|
|
ce0374a…
|
lmata
|
51 |
On every `Write`, `Edit`, or `MultiEdit` tool call: |
|
ce0374a…
|
lmata
|
52 |
|
|
ce0374a…
|
lmata
|
53 |
1. Reads the list of modified file paths from the tool result |
|
ce0374a…
|
lmata
|
54 |
2. Runs `navegador ingest` scoped to those files (fast incremental update) |
|
ce0374a…
|
lmata
|
55 |
3. Checks for changes to `DECISIONS.md` — if found, syncs any new ADR entries into the graph as `Decision` nodes |
|
ce0374a…
|
lmata
|
56 |
4. Logs a one-line summary to stderr (visible in Claude's tool output) |
|
ce0374a…
|
lmata
|
57 |
|
|
ce0374a…
|
lmata
|
58 |
--- |
|
ce0374a…
|
lmata
|
59 |
|
|
ce0374a…
|
lmata
|
60 |
## Gemini CLI |
|
ce0374a…
|
lmata
|
61 |
|
|
ce0374a…
|
lmata
|
62 |
### Install |
|
ce0374a…
|
lmata
|
63 |
|
|
ce0374a…
|
lmata
|
64 |
The hook file lives at `.gemini/hooks/gemini-hook.py`. Bootstrap installs it automatically: |
|
ce0374a…
|
lmata
|
65 |
|
|
ce0374a…
|
lmata
|
66 |
```bash |
|
ce0374a…
|
lmata
|
67 |
./bootstrap.sh --repo owner/repo --agent gemini |
|
ce0374a…
|
lmata
|
68 |
``` |
|
ce0374a…
|
lmata
|
69 |
|
|
ce0374a…
|
lmata
|
70 |
To install manually, copy `hooks/gemini-hook.py` from the navegador repo into your project's `.gemini/hooks/` directory. |
|
ce0374a…
|
lmata
|
71 |
|
|
ce0374a…
|
lmata
|
72 |
### GEMINI.md config |
|
ce0374a…
|
lmata
|
73 |
|
|
ce0374a…
|
lmata
|
74 |
Add to your project's `GEMINI.md`: |
|
ce0374a…
|
lmata
|
75 |
|
|
ce0374a…
|
lmata
|
76 |
```markdown |
|
ce0374a…
|
lmata
|
77 |
## Tool Hooks |
|
ce0374a…
|
lmata
|
78 |
|
|
ce0374a…
|
lmata
|
79 |
After writing or editing any source file, run: |
|
ce0374a…
|
lmata
|
80 |
``` |
|
ce0374a…
|
lmata
|
81 |
python .gemini/hooks/gemini-hook.py <file_path> |
|
ce0374a…
|
lmata
|
82 |
``` |
|
ce0374a…
|
lmata
|
83 |
|
|
ce0374a…
|
lmata
|
84 |
This keeps the navegador knowledge graph in sync. The graph is your source of truth for code structure and project decisions. |
|
ce0374a…
|
lmata
|
85 |
``` |
|
ce0374a…
|
lmata
|
86 |
|
|
ce0374a…
|
lmata
|
87 |
The Gemini CLI does not have a declarative hook registry like Claude. The `GEMINI.md` instruction tells the model to call the hook script explicitly as a tool after file writes. |
|
ce0374a…
|
lmata
|
88 |
|
|
ce0374a…
|
lmata
|
89 |
--- |
|
ce0374a…
|
lmata
|
90 |
|
|
ce0374a…
|
lmata
|
91 |
## OpenAI |
|
ce0374a…
|
lmata
|
92 |
|
|
ce0374a…
|
lmata
|
93 |
OpenAI agents use a dispatcher script and a tool definition JSON file. |
|
ce0374a…
|
lmata
|
94 |
|
|
ce0374a…
|
lmata
|
95 |
### Install |
|
ce0374a…
|
lmata
|
96 |
|
|
ce0374a…
|
lmata
|
97 |
```bash |
|
ce0374a…
|
lmata
|
98 |
./bootstrap.sh --repo owner/repo --agent openai |
|
ce0374a…
|
lmata
|
99 |
``` |
|
ce0374a…
|
lmata
|
100 |
|
|
ce0374a…
|
lmata
|
101 |
This places: |
|
ce0374a…
|
lmata
|
102 |
- `openai-hook.py` — dispatcher script |
|
ce0374a…
|
lmata
|
103 |
- `openai-tools.json` — tool schema for the OpenAI function-calling API |
|
ce0374a…
|
lmata
|
104 |
|
|
ce0374a…
|
lmata
|
105 |
### openai-tools.json |
|
ce0374a…
|
lmata
|
106 |
|
|
ce0374a…
|
lmata
|
107 |
The tool schema exposes navegador commands as callable functions: |
|
ce0374a…
|
lmata
|
108 |
|
|
ce0374a…
|
lmata
|
109 |
```json |
|
ce0374a…
|
lmata
|
110 |
[ |
|
ce0374a…
|
lmata
|
111 |
{ |
|
ce0374a…
|
lmata
|
112 |
"type": "function", |
|
ce0374a…
|
lmata
|
113 |
"function": { |
|
ce0374a…
|
lmata
|
114 |
"name": "navegador_explain", |
|
ce0374a…
|
lmata
|
115 |
"description": "Look up any code or knowledge node by name", |
|
ce0374a…
|
lmata
|
116 |
"parameters": { |
|
ce0374a…
|
lmata
|
117 |
"type": "object", |
|
ce0374a…
|
lmata
|
118 |
"properties": { |
|
ce0374a…
|
lmata
|
119 |
"name": { "type": "string", "description": "Node name to explain" }, |
|
ce0374a…
|
lmata
|
120 |
"file": { "type": "string", "description": "Optional file path to disambiguate" } |
|
ce0374a…
|
lmata
|
121 |
}, |
|
ce0374a…
|
lmata
|
122 |
"required": ["name"] |
|
ce0374a…
|
lmata
|
123 |
} |
|
ce0374a…
|
lmata
|
124 |
} |
|
ce0374a…
|
lmata
|
125 |
}, |
|
ce0374a…
|
lmata
|
126 |
{ |
|
ce0374a…
|
lmata
|
127 |
"type": "function", |
|
ce0374a…
|
lmata
|
128 |
"function": { |
|
ce0374a…
|
lmata
|
129 |
"name": "navegador_ingest", |
|
ce0374a…
|
lmata
|
130 |
"description": "Re-ingest a file or directory into the knowledge graph", |
|
ce0374a…
|
lmata
|
131 |
"parameters": { |
|
ce0374a…
|
lmata
|
132 |
"type": "object", |
|
ce0374a…
|
lmata
|
133 |
"properties": { |
|
ce0374a…
|
lmata
|
134 |
"path": { "type": "string", "description": "File or directory path to ingest" } |
|
ce0374a…
|
lmata
|
135 |
}, |
|
ce0374a…
|
lmata
|
136 |
"required": ["path"] |
|
ce0374a…
|
lmata
|
137 |
} |
|
ce0374a…
|
lmata
|
138 |
} |
|
ce0374a…
|
lmata
|
139 |
} |
|
ce0374a…
|
lmata
|
140 |
] |
|
ce0374a…
|
lmata
|
141 |
``` |
|
ce0374a…
|
lmata
|
142 |
|
|
ce0374a…
|
lmata
|
143 |
### Dispatcher script |
|
ce0374a…
|
lmata
|
144 |
|
|
ce0374a…
|
lmata
|
145 |
`openai-hook.py` receives function call JSON on stdin and dispatches to `navegador` CLI commands: |
|
ce0374a…
|
lmata
|
146 |
|
|
ce0374a…
|
lmata
|
147 |
```python |
|
ce0374a…
|
lmata
|
148 |
# openai-hook.py dispatches tool calls to the navegador CLI |
|
ce0374a…
|
lmata
|
149 |
# usage: echo '{"name": "navegador_explain", "arguments": {"name": "AuthService"}}' | python openai-hook.py |
|
ce0374a…
|
lmata
|
150 |
``` |
|
ce0374a…
|
lmata
|
151 |
|
|
ce0374a…
|
lmata
|
152 |
Register `openai-tools.json` in your OpenAI assistant configuration and point function call handling at `openai-hook.py`. |
|
ce0374a…
|
lmata
|
153 |
|
|
ce0374a…
|
lmata
|
154 |
--- |
|
ce0374a…
|
lmata
|
155 |
|
|
ce0374a…
|
lmata
|
156 |
## NAVEGADOR.md template |
|
ce0374a…
|
lmata
|
157 |
|
|
ce0374a…
|
lmata
|
158 |
Drop a `NAVEGADOR.md` in your project root so agents know the graph exists and how to use it. Example template: |
|
ce0374a…
|
lmata
|
159 |
|
|
ce0374a…
|
lmata
|
160 |
```markdown |
|
ce0374a…
|
lmata
|
161 |
# Navegador Knowledge Graph |
|
ce0374a…
|
lmata
|
162 |
|
|
ce0374a…
|
lmata
|
163 |
This project has a navegador knowledge graph at `.navegador/navegador.db`. |
|
ce0374a…
|
lmata
|
164 |
|
|
ce0374a…
|
lmata
|
165 |
## Before editing code |
|
ce0374a…
|
lmata
|
166 |
|
|
ce0374a…
|
lmata
|
167 |
Run the relevant context command first: |
|
ce0374a…
|
lmata
|
168 |
|
|
ce0374a…
|
lmata
|
169 |
```bash |
|
ce0374a…
|
lmata
|
170 |
navegador context <file> # full file context |
|
ce0374a…
|
lmata
|
171 |
navegador function <name> # function + call graph |
|
ce0374a…
|
lmata
|
172 |
navegador class <name> # class + hierarchy |
|
ce0374a…
|
lmata
|
173 |
navegador explain <name> # anything by name |
|
ce0374a…
|
lmata
|
174 |
``` |
|
ce0374a…
|
lmata
|
175 |
|
|
ce0374a…
|
lmata
|
176 |
## Before adding new patterns |
|
ce0374a…
|
lmata
|
177 |
|
|
ce0374a…
|
lmata
|
178 |
Check if a concept or rule already exists: |
|
ce0374a…
|
lmata
|
179 |
|
|
ce0374a…
|
lmata
|
180 |
```bash |
|
ce0374a…
|
lmata
|
181 |
navegador search "<topic>" --all |
|
ce0374a…
|
lmata
|
182 |
navegador domain <domain-name> |
|
ce0374a…
|
lmata
|
183 |
``` |
|
ce0374a…
|
lmata
|
184 |
|
|
ce0374a…
|
lmata
|
185 |
## After editing code |
|
ce0374a…
|
lmata
|
186 |
|
|
ce0374a…
|
lmata
|
187 |
The agent hook re-ingests automatically. If you disabled hooks, run: |
|
ce0374a…
|
lmata
|
188 |
|
|
ce0374a…
|
lmata
|
189 |
```bash |
|
ce0374a…
|
lmata
|
190 |
navegador ingest ./src --clear |
|
ce0374a…
|
lmata
|
191 |
``` |
|
ce0374a…
|
lmata
|
192 |
|
|
ce0374a…
|
lmata
|
193 |
## Key domains |
|
ce0374a…
|
lmata
|
194 |
|
|
ce0374a…
|
lmata
|
195 |
- **Payments** — payment processing, billing, idempotency rules |
|
ce0374a…
|
lmata
|
196 |
- **Auth** — authentication, session management, permissions |
|
ce0374a…
|
lmata
|
197 |
- **Infrastructure** — deployment, database, caching decisions |
|
ce0374a…
|
lmata
|
198 |
``` |
|
ce0374a…
|
lmata
|
199 |
|
|
ce0374a…
|
lmata
|
200 |
--- |
|
ce0374a…
|
lmata
|
201 |
|
|
ce0374a…
|
lmata
|
202 |
## Bootstrap reference |
|
ce0374a…
|
lmata
|
203 |
|
|
ce0374a…
|
lmata
|
204 |
```bash |
|
ce0374a…
|
lmata
|
205 |
./bootstrap.sh [options] |
|
ce0374a…
|
lmata
|
206 |
``` |
|
ce0374a…
|
lmata
|
207 |
|
|
ce0374a…
|
lmata
|
208 |
| Option | Description | |
|
ce0374a…
|
lmata
|
209 |
|---|---| |
|
ce0374a…
|
lmata
|
210 |
| `--repo owner/repo` | GitHub repo to clone and ingest | |
|
ce0374a…
|
lmata
|
211 |
| `--wiki` | Also ingest the GitHub wiki | |
|
ce0374a…
|
lmata
|
212 |
| `--agent claude` | Install Claude Code hook + settings.json config | |
|
ce0374a…
|
lmata
|
213 |
| `--agent gemini` | Install Gemini CLI hook + GEMINI.md instruction | |
|
ce0374a…
|
lmata
|
214 |
| `--agent openai` | Install openai-hook.py + openai-tools.json | |
|
ce0374a…
|
lmata
|
215 |
| `--db <path>` | Custom database path (default: `.navegador/navegador.db`) | |