graph-indexer 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -677
- package/PROMPT.md +160 -133
- package/README.md +244 -335
- package/core-engine.mjs +396 -121
- package/indexer.mjs +19 -19
- package/init.mjs +241 -0
- package/mcp-server.mjs +441 -117
- package/package.json +16 -4
- package/parser-utils.mjs +357 -17
- package/watch-daemon.mjs +25 -16
package/PROMPT.md
CHANGED
|
@@ -1,191 +1,218 @@
|
|
|
1
|
-
#
|
|
1
|
+
# graph-indexer — Agent System Prompt
|
|
2
2
|
|
|
3
|
-
You
|
|
4
|
-
|
|
5
|
-
> **Core Principle:** You have a surgical search tool. Use it like a scalpel, not a shovel. Never read files blindly. Every action starts with `search_code`.
|
|
3
|
+
You have access to a **graph-indexer MCP server** that has pre-indexed this entire codebase into a searchable AST graph. It is always faster, cheaper, and more accurate than reading files directly.
|
|
6
4
|
|
|
7
5
|
---
|
|
8
6
|
|
|
9
|
-
##
|
|
10
|
-
|
|
11
|
-
### Rule 1: search_code FIRST, ALWAYS
|
|
12
|
-
- **NEVER** read a file, list a directory, or glob for files as a first step.
|
|
13
|
-
- **ALWAYS** call `search_code` before touching any file.
|
|
14
|
-
- Only read a file directly when `search_code` has already returned the exact `file_path` and you need surrounding context beyond the returned chunk.
|
|
7
|
+
## ABSOLUTE RULES — No Exceptions
|
|
15
8
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
- `get_chunk("id")` → read the *full body* of one specific chunk
|
|
19
|
-
- `get_file_skeleton("path")` → inspect a *file's structure* without reading all code
|
|
20
|
-
- `get_call_graph("fnName")` → find *every caller* before refactoring
|
|
21
|
-
- `graph://dependencies/path` → inspect *import topology* of a file
|
|
9
|
+
**Rule 1 — Search before you read.**
|
|
10
|
+
NEVER use `readFile`, `listDir`, `grep`, `find`, or any native file tool as your first step. Every code discovery task starts with a graph-indexer tool. Violating this wastes 10–100× more tokens and is strictly forbidden.
|
|
22
11
|
|
|
23
|
-
|
|
12
|
+
**Rule 2 — Never read a full file to find one function.**
|
|
13
|
+
If you know a chunk ID from search results, call `get_chunk(id)` directly. If you need one function from a file, search for it — do not read the whole file.
|
|
24
14
|
|
|
25
|
-
|
|
26
|
-
Before
|
|
27
|
-
1. Call `get_call_graph("functionName")` to find all callers across the repo.
|
|
28
|
-
2. Check the `⬆️ Used by` field in the `search_code` response.
|
|
29
|
-
3. Only then proceed with the edit — and update all callers if the signature changes.
|
|
15
|
+
**Rule 3 — Never modify an exported function without checking its callers.**
|
|
16
|
+
Before changing any function or class signature, call `get_call_graph("functionName")` to find all callers repo-wide. This takes 1 tool call. Skipping it risks breaking code you cannot see.
|
|
30
17
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
- Use `token_budget` when you need more complete code bodies; omit it when signature cards suffice.
|
|
34
|
-
- Prefer `get_chunk("id")` for deep dives over raising `top_k`.
|
|
18
|
+
**Rule 4 — Use `resolve_symbol` for exact names, not search.**
|
|
19
|
+
If you know the exact function or class name (e.g. `validateToken`, `UserService`), call `resolve_symbol("validateToken")` — it is O(1) and returns the definition instantly. Do not use `search_code` for names you already know.
|
|
35
20
|
|
|
36
21
|
---
|
|
37
22
|
|
|
38
|
-
##
|
|
39
|
-
|
|
40
|
-
### `search_code` — Primary Search Tool
|
|
23
|
+
## Decision Tree — Which Tool to Use
|
|
41
24
|
|
|
42
25
|
```
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
)
|
|
26
|
+
Task Tool
|
|
27
|
+
──────────────────────────────────────────────────────────────────
|
|
28
|
+
Unfamiliar codebase, need overview → get_repo_map()
|
|
29
|
+
Focus on a subsystem → get_repo_map(path_filter="auth")
|
|
30
|
+
Know exact symbol name → resolve_symbol("ExactName")
|
|
31
|
+
Find concept / behavior → search_code(query, detail="signatures")
|
|
32
|
+
Need interface only (no body) → get_chunk_summary(chunk_id)
|
|
33
|
+
Need full implementation → get_chunk(chunk_id)
|
|
34
|
+
See all exports in one file → get_file_skeleton("src/file.ts")
|
|
35
|
+
Find who calls a function → get_call_graph("functionName")
|
|
36
|
+
Check index health / search mode → list_index_stats()
|
|
37
|
+
Browse file dependencies → resource graph://dependencies/{file_path}
|
|
51
38
|
```
|
|
52
39
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
- When the semantic query alone might return related but not exact results
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Token Cost — Always Choose the Cheapest Sufficient Tool
|
|
57
43
|
|
|
58
|
-
|
|
59
|
-
|
|
|
60
|
-
|
|
61
|
-
|
|
|
62
|
-
|
|
|
63
|
-
|
|
|
64
|
-
|
|
|
65
|
-
|
|
|
44
|
+
| Action | Tokens | Use when |
|
|
45
|
+
| :--- | ---: | :--- |
|
|
46
|
+
| `get_repo_map()` | ~1,500 | Orienting in an unknown codebase |
|
|
47
|
+
| `resolve_symbol("Name")` | ~50 | You know the exact name |
|
|
48
|
+
| `search_code(detail="signatures", top_k=5)` | ~100 | Finding candidates to inspect |
|
|
49
|
+
| `get_chunk_summary(id)` | ~50 | You need the interface, not the body |
|
|
50
|
+
| `search_code(detail="smart", top_k=5)` | ~750 | You need to understand the logic |
|
|
51
|
+
| `get_chunk(id)` | ~300 | You need the complete implementation |
|
|
52
|
+
| `get_file_skeleton("file.ts")` | ~80 | You need all exports in one file |
|
|
53
|
+
| `search_code(detail="full", top_k=5)` | ~1,500 | Rarely; full bodies for all results |
|
|
54
|
+
| **Direct file read (forbidden first step)** | ~5,000 | Never — use the tools above |
|
|
55
|
+
|
|
56
|
+
**Escalation ladder** — always start at the cheapest level and escalate only if you need more:
|
|
66
57
|
|
|
67
|
-
**Reading the response:**
|
|
68
58
|
```
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
⬆️ Used by: src/routes/api.ts, src/app.ts
|
|
74
|
-
🔗 Calls: validateToken, refreshSession, logEvent
|
|
75
|
-
↩️ Expand body: get_chunk("abc123")
|
|
59
|
+
1. search_code(detail="signatures") ← start here: names + types only
|
|
60
|
+
2. get_chunk_summary(id) ← escalate: add docstring + calls
|
|
61
|
+
3. search_code(detail="smart") ← escalate: add query-relevant snippets
|
|
62
|
+
4. get_chunk(id) ← last resort: full body when you must
|
|
76
63
|
```
|
|
77
64
|
|
|
78
|
-
- `RRF` is the relevance score (higher = more relevant)
|
|
79
|
-
- `Deps` shows what this file imports (with key symbols)
|
|
80
|
-
- `Used by` shows what imports this file — READ THIS before editing
|
|
81
|
-
- `Calls` shows what functions this chunk calls internally
|
|
82
|
-
- **Always prefer `get_chunk("id")` over reading the whole file**
|
|
83
|
-
|
|
84
65
|
---
|
|
85
66
|
|
|
86
|
-
|
|
67
|
+
## Standard Workflows
|
|
68
|
+
|
|
69
|
+
### Orienting in a new codebase
|
|
70
|
+
```
|
|
71
|
+
get_repo_map()
|
|
72
|
+
→ files sorted by importance (PageRank — most-imported first)
|
|
73
|
+
→ identify key files, pick relevant ones
|
|
74
|
+
→ resolve_symbol or search_code to drill in
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Finding where a concept is implemented
|
|
78
|
+
```
|
|
79
|
+
search_code(query="<semantic description>", detail="signatures", top_k=5)
|
|
80
|
+
→ read signature cards + topology (deps, calls, usedBy)
|
|
81
|
+
→ if a result looks right: get_chunk_summary(id) to check interface
|
|
82
|
+
→ if confirmed: get_chunk(id) for the full body
|
|
83
|
+
```
|
|
87
84
|
|
|
88
|
-
|
|
85
|
+
### Looking up a specific function or class
|
|
86
|
+
```
|
|
87
|
+
resolve_symbol("ExactName")
|
|
88
|
+
→ definition + type signature + cross-file topology
|
|
89
|
+
→ get_chunk(id) if you need the body
|
|
90
|
+
```
|
|
89
91
|
|
|
92
|
+
### Understanding a file's structure
|
|
90
93
|
```
|
|
91
|
-
|
|
94
|
+
get_file_skeleton("src/module.ts")
|
|
95
|
+
→ all exported symbols with line numbers (no bodies)
|
|
96
|
+
→ resolve_symbol or get_chunk for specific items
|
|
92
97
|
```
|
|
93
98
|
|
|
94
|
-
|
|
99
|
+
### Safe refactoring
|
|
100
|
+
```
|
|
101
|
+
get_call_graph("targetFunction")
|
|
102
|
+
→ all callers repo-wide
|
|
103
|
+
→ review impact before changing signature
|
|
104
|
+
→ get_chunk for each caller if you need to update call sites
|
|
105
|
+
```
|
|
95
106
|
|
|
96
107
|
---
|
|
97
108
|
|
|
98
|
-
|
|
109
|
+
## Writing Effective Queries
|
|
99
110
|
|
|
100
|
-
|
|
111
|
+
`search_code` uses BM25 hybrid search. Query quality determines result quality.
|
|
101
112
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
113
|
+
**Good queries — specific and semantic:**
|
|
114
|
+
- `"JWT token validation and expiry check middleware"`
|
|
115
|
+
- `"HTTP adapter XMLHttpRequest browser send request"`
|
|
116
|
+
- `"dependency injection container resolve provider"`
|
|
117
|
+
- `"route registration path method handler"`
|
|
118
|
+
|
|
119
|
+
**Bad queries — too generic:**
|
|
120
|
+
- `"auth"` → matches everything with the word auth
|
|
121
|
+
- `"request"` → thousands of results, meaningless ranking
|
|
122
|
+
- `"handler"` → too broad
|
|
105
123
|
|
|
106
|
-
|
|
107
|
-
|
|
124
|
+
**Rules for good queries:**
|
|
125
|
+
1. Describe the behavior, not just the noun: `"parse and validate request body schema"` not `"validation"`
|
|
126
|
+
2. Include language context: `"TypeScript interface generic constraint"` not `"interface"`
|
|
127
|
+
3. If you know the name, use `exact_tokens`: `search_code(query="token validation", exact_tokens="validateToken")`
|
|
128
|
+
4. For files: include path segments in query: `"middleware auth route"` will boost `auth/middleware.ts`
|
|
108
129
|
|
|
109
130
|
---
|
|
110
131
|
|
|
111
|
-
|
|
132
|
+
## The `detail` Parameter on `search_code`
|
|
112
133
|
|
|
113
|
-
|
|
134
|
+
| Value | What you get | Token cost | When to use |
|
|
135
|
+
| :--- | :--- | ---: | :--- |
|
|
136
|
+
| `"signatures"` | Name, type, params, return, topology — no body | ~20/result | First pass: finding candidates |
|
|
137
|
+
| `"smart"` (default) | Signature + query-matching lines only, boilerplate removed | ~150/result | Understanding logic without full body |
|
|
138
|
+
| `"full"` | Complete source body | ~300/result | When you must see the full implementation |
|
|
139
|
+
|
|
140
|
+
Always start with `"signatures"`, escalate only when you need more.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Anti-Patterns — Never Do These
|
|
114
145
|
|
|
115
146
|
```
|
|
116
|
-
|
|
117
|
-
|
|
147
|
+
# WRONG: Reading files to discover code
|
|
148
|
+
readFile("src/auth/jwt.ts") ← never as a first step
|
|
149
|
+
|
|
150
|
+
# WRONG: Searching for what you already have
|
|
151
|
+
search_code("validateToken") ← you already have the chunk ID from search results
|
|
152
|
+
|
|
153
|
+
# WRONG: Using full detail by default
|
|
154
|
+
search_code(query="...", detail="full") ← only when you need all bodies
|
|
118
155
|
|
|
119
|
-
|
|
120
|
-
|
|
156
|
+
# WRONG: Modifying exported functions without impact check
|
|
157
|
+
# Edit function → push → find 12 other files break
|
|
158
|
+
# Correct: get_call_graph("functionName") first
|
|
159
|
+
|
|
160
|
+
# WRONG: Generic one-word queries
|
|
161
|
+
search_code(query="error") ← use "HTTP error response handler middleware"
|
|
162
|
+
|
|
163
|
+
# WRONG: Ignoring topology in search results
|
|
164
|
+
# Results show "⬆️ Used by: auth.ts, routes.ts" — read that, don't re-search
|
|
165
|
+
|
|
166
|
+
# WRONG: Re-searching for the same concept
|
|
167
|
+
# search_code returns chunk ID → call get_chunk(id), not another search_code
|
|
168
|
+
```
|
|
121
169
|
|
|
122
170
|
---
|
|
123
171
|
|
|
124
|
-
|
|
172
|
+
## Topology Is Free Information — Read It
|
|
125
173
|
|
|
126
|
-
|
|
174
|
+
Every `search_code` and `resolve_symbol` result includes topology for free:
|
|
127
175
|
|
|
128
176
|
```
|
|
129
|
-
|
|
177
|
+
⬇️ Deps: src/config/env.ts [JWT_SECRET] | src/utils/errors.ts [AuthError]
|
|
178
|
+
⬆️ Used by: src/middleware/auth.ts, src/routes/api.ts
|
|
179
|
+
🔗 Calls: verify, decodePayload, throwIfExpired
|
|
130
180
|
```
|
|
131
181
|
|
|
132
|
-
|
|
182
|
+
- **Deps** → what this file imports (and which symbols it uses from each)
|
|
183
|
+
- **Used by** → which other files import this file
|
|
184
|
+
- **Calls** → functions this chunk calls directly
|
|
133
185
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
## 🔄 Standard Workflows
|
|
137
|
-
|
|
138
|
-
### Workflow A: Answer a Question About the Code
|
|
139
|
-
1. `search_code(query: "...")` → identify the relevant chunk
|
|
140
|
-
2. `get_chunk("id")` → read the full code if needed
|
|
141
|
-
3. Answer from the returned context. Do not read other files speculatively.
|
|
142
|
-
|
|
143
|
-
### Workflow B: Implement a New Feature
|
|
144
|
-
1. `search_code` → find where to add the new code (nearest component/module)
|
|
145
|
-
2. `get_file_skeleton` → understand the file structure before editing
|
|
146
|
-
3. `get_call_graph` → check if any shared utilities you'll use are already called elsewhere
|
|
147
|
-
4. Implement in the correct file. Do not create new files unless no existing one fits.
|
|
148
|
-
|
|
149
|
-
### Workflow C: Refactor an Existing Function
|
|
150
|
-
1. `search_code(exact_tokens: "functionName")` → locate the function
|
|
151
|
-
2. `get_call_graph("functionName")` → find ALL callers
|
|
152
|
-
3. `get_chunk("id")` → read the current implementation
|
|
153
|
-
4. Modify the function AND update all callers identified in step 2.
|
|
154
|
-
|
|
155
|
-
### Workflow D: Debug an Error
|
|
156
|
-
1. Extract the exact error message / function name from the stack trace
|
|
157
|
-
2. `search_code(query: "<error description>", exact_tokens: "<functionName>")` → find the source
|
|
158
|
-
3. `get_chunk("id")` → read the code
|
|
159
|
-
4. `get_call_graph("functionName")` → trace upstream if the bug is in a caller
|
|
160
|
-
5. Fix and propagate.
|
|
161
|
-
|
|
162
|
-
### Workflow E: Understand a File's Role
|
|
163
|
-
1. `get_file_skeleton("src/path/file.ts")` → see all exports
|
|
164
|
-
2. `graph://dependencies/src/path/file.ts` → see what it depends on and what depends on it
|
|
165
|
-
3. Use this information to answer architecture questions without reading the full file.
|
|
186
|
+
Use this topology to navigate without additional tool calls. `get_call_graph` gives the full list when the truncated view is insufficient.
|
|
166
187
|
|
|
167
188
|
---
|
|
168
189
|
|
|
169
|
-
##
|
|
190
|
+
## Index Health
|
|
191
|
+
|
|
192
|
+
If search results seem wrong or stale:
|
|
193
|
+
1. Call `list_index_stats()` — check chunk count, vector status, daemon status, index age
|
|
194
|
+
2. If index age > 1h with no activity, ask the user to run `npm run mcp:index`
|
|
195
|
+
3. If a symbol is missing from `resolve_symbol`, fall back to `search_code`
|
|
170
196
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
| `listDir("src/stores")` to find a store | `search_code("zustand store for auth state")` |
|
|
175
|
-
| `search_code(top_k: 20)` to "see everything" | Search with a specific query; raise top_k only if 5 results miss the target |
|
|
176
|
-
| Editing a function without checking callers | `get_call_graph("fnName")` first |
|
|
177
|
-
| Re-running `search_code` with the same query | Refine the query or use `exact_tokens` |
|
|
178
|
-
| Reading a full file to understand its structure | `get_file_skeleton("path")` |
|
|
197
|
+
Search modes reported:
|
|
198
|
+
- `🧠 Hybrid (semantic + lexical RRF)` — full quality, Ollama running
|
|
199
|
+
- `🔤 Lexical only` — BM25 only, Ollama unavailable; still high quality (R@5=1.00)
|
|
179
200
|
|
|
180
201
|
---
|
|
181
202
|
|
|
182
|
-
##
|
|
203
|
+
## Quick Reference
|
|
183
204
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
205
|
+
```
|
|
206
|
+
get_repo_map() → full codebase overview, ~1500 tok
|
|
207
|
+
get_repo_map(path_filter="auth") → subsystem overview, ~300 tok
|
|
208
|
+
resolve_symbol("ExactName") → instant definition + topology
|
|
209
|
+
search_code("concept", "signatures") → find candidates, ~100 tok
|
|
210
|
+
get_chunk_summary(id) → interface view, ~50 tok
|
|
211
|
+
get_chunk(id) → full body, ~300 tok
|
|
212
|
+
get_file_skeleton("path/file.ts") → all exports in file, ~80 tok
|
|
213
|
+
get_call_graph("name") → all callers, pre-refactor check
|
|
214
|
+
list_index_stats() → index health
|
|
215
|
+
graph://dependencies/{file_path} → bidirectional dep graph
|
|
216
|
+
```
|
|
190
217
|
|
|
191
|
-
|
|
218
|
+
graph-indexer v1.0.3 · BM25 + hybrid RRF · R@5=1.00, MRR=0.95 across 5 major frameworks
|