seer-mcp 0.1.0 → 0.1.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/STRESS_TEST_REPORT.md +219 -0
- package/adding-new-languages.md +647 -0
- package/dist/cli/index.js +1 -1
- package/package.json +3 -2
- package/research-papers.md +117 -0
- package/.vscode/settings.json +0 -3
- package/src/bundle/ci.ts +0 -141
- package/src/bundle/contract.ts +0 -387
- package/src/bundle/export.ts +0 -175
- package/src/bundle/external.ts +0 -285
- package/src/bundle/format.ts +0 -92
- package/src/bundle/import.ts +0 -157
- package/src/cli/index.ts +0 -1249
- package/src/cli/init.ts +0 -389
- package/src/db/schema.ts +0 -614
- package/src/db/store.ts +0 -4306
- package/src/graph/pagerank.ts +0 -53
- package/src/indexer/architecture.ts +0 -148
- package/src/indexer/behavior.ts +0 -466
- package/src/indexer/boundaries.ts +0 -374
- package/src/indexer/churn.ts +0 -58
- package/src/indexer/classify.ts +0 -96
- package/src/indexer/context.ts +0 -340
- package/src/indexer/continuity.ts +0 -322
- package/src/indexer/detectchanges.ts +0 -94
- package/src/indexer/discovery.ts +0 -176
- package/src/indexer/externaldeps.ts +0 -243
- package/src/indexer/freshness.ts +0 -166
- package/src/indexer/git.ts +0 -453
- package/src/indexer/index.ts +0 -1092
- package/src/indexer/modules.ts +0 -358
- package/src/indexer/preflight.ts +0 -548
- package/src/indexer/protoScanner.ts +0 -147
- package/src/indexer/risk.ts +0 -304
- package/src/indexer/serviceHostScanner.ts +0 -92
- package/src/indexer/serviceLinks.ts +0 -543
- package/src/indexer/shapehash.ts +0 -370
- package/src/indexer/skeleton.ts +0 -169
- package/src/indexer/symbolhistory.ts +0 -172
- package/src/indexer/watcher.ts +0 -206
- package/src/mcp/server.ts +0 -1659
- package/src/parser/index.ts +0 -37
- package/src/parser/languages/cpp.ts +0 -361
- package/src/parser/languages/csharp.ts +0 -235
- package/src/parser/languages/go.ts +0 -259
- package/src/parser/languages/java.ts +0 -382
- package/src/parser/languages/python.ts +0 -370
- package/src/parser/languages/rust.ts +0 -164
- package/src/parser/languages/typescript.ts +0 -1435
- package/src/parser/parserContext.ts +0 -392
- package/src/parser/walker.ts +0 -306
- package/src/parser/worker.ts +0 -181
- package/src/parser/workerpool.ts +0 -448
- package/src/scip/format.ts +0 -83
- package/src/scip/import.ts +0 -216
- package/src/types.ts +0 -457
- package/tests/benchmark-service-links.ts +0 -244
- package/tests/bug-regressions.ts +0 -626
- package/tests/filters.ts +0 -264
- package/tests/fixtures/Counter.tsx +0 -38
- package/tests/fixtures/caller.ts +0 -7
- package/tests/fixtures/collisions.ts +0 -23
- package/tests/fixtures/local_helper.ts +0 -5
- package/tests/fixtures/overloads.java +0 -17
- package/tests/fixtures/remote_helper.ts +0 -4
- package/tests/fixtures/sample.c +0 -15
- package/tests/fixtures/sample.cpp +0 -47
- package/tests/fixtures/sample.cs +0 -62
- package/tests/fixtures/sample.go +0 -68
- package/tests/fixtures/sample.h +0 -30
- package/tests/fixtures/sample.java +0 -85
- package/tests/fixtures/sample.py +0 -46
- package/tests/fixtures/sample.rs +0 -78
- package/tests/fixtures/sample.ts +0 -76
- package/tests/fixtures-service/HttpClients.cs +0 -30
- package/tests/fixtures-service/HttpClients.java +0 -24
- package/tests/fixtures-service/billing.ts +0 -15
- package/tests/fixtures-service/docker-compose.yml +0 -15
- package/tests/fixtures-service/gateway.ts +0 -10
- package/tests/fixtures-service/get_user.ts +0 -11
- package/tests/fixtures-service/graphql_client.ts +0 -63
- package/tests/fixtures-service/graphql_server.ts +0 -30
- package/tests/fixtures-service/grpc_client.go +0 -30
- package/tests/fixtures-service/http_clients.go +0 -23
- package/tests/fixtures-service/http_clients.py +0 -38
- package/tests/fixtures-service/http_clients.ts +0 -49
- package/tests/fixtures-service/k8s/payment-service.yaml +0 -22
- package/tests/fixtures-service/k8s_calls.ts +0 -20
- package/tests/fixtures-service/messaging.ts +0 -87
- package/tests/fixtures-service/trpc_client.ts +0 -39
- package/tests/fixtures-service/trpc_server.ts +0 -39
- package/tests/fixtures-service/user_service.proto +0 -33
- package/tests/fixtures-trackcd/Cargo.toml +0 -11
- package/tests/fixtures-trackcd/SpringController.java +0 -36
- package/tests/fixtures-trackcd/auth_service.ts +0 -19
- package/tests/fixtures-trackcd/complex_module.py +0 -50
- package/tests/fixtures-trackcd/express_app.js +0 -30
- package/tests/fixtures-trackcd/fastapi_app.py +0 -49
- package/tests/fixtures-trackcd/fastify_object_routes.js +0 -32
- package/tests/fixtures-trackcd/go.mod +0 -8
- package/tests/fixtures-trackcd/package.json +0 -15
- package/tests/fixtures-trackcd/requirements.txt +0 -4
- package/tests/fixtures-trackcd/tests/auth_service.test.ts +0 -13
- package/tests/fixtures-tracke/auth/AuthService.ts +0 -23
- package/tests/fixtures-tracke/auth/crypto.ts +0 -7
- package/tests/fixtures-tracke/billing/Billing.ts +0 -20
- package/tests/fixtures-tracke/billing/Invoice.ts +0 -10
- package/tests/fixtures-tracke/billing/server.ts +0 -17
- package/tests/fixtures-tracke/package.json +0 -7
- package/tests/fixtures-tracke/tests/auth.test.ts +0 -23
- package/tests/fixtures-tracke/tests/billing.test.ts +0 -14
- package/tests/fixtures-trackf/package.json +0 -5
- package/tests/fixtures-trackf/src/auth.ts +0 -26
- package/tests/fixtures-trackf/src/handlers.ts +0 -35
- package/tests/fixtures-tracki/billing/routes.ts +0 -12
- package/tests/fixtures-tracki/gateway/client.ts +0 -13
- package/tests/git-features.ts +0 -267
- package/tests/init.ts +0 -141
- package/tests/mcp-jit.ts +0 -130
- package/tests/mcp-smoke.ts +0 -191
- package/tests/mcp-trackcd.ts +0 -169
- package/tests/mcp-tracke.ts +0 -229
- package/tests/mcp-trackf.ts +0 -330
- package/tests/mcp-trackg.ts +0 -219
- package/tests/mcp-tracki.ts +0 -174
- package/tests/mcp-watcher.ts +0 -126
- package/tests/optspec.ts +0 -194
- package/tests/parallel-index.ts +0 -333
- package/tests/parallel-read.ts +0 -125
- package/tests/parallel-recovery.ts +0 -241
- package/tests/perf-callers.ts +0 -145
- package/tests/query-parity.ts +0 -184
- package/tests/query-perf.ts +0 -55
- package/tests/scale-parallel-parity.ts +0 -225
- package/tests/scale-test.ts +0 -523
- package/tests/smoke.ts +0 -396
- package/tests/trackcd.ts +0 -325
- package/tests/tracke-collisions.ts +0 -255
- package/tests/tracke.ts +0 -314
- package/tests/trackf-bugs.ts +0 -406
- package/tests/trackf.ts +0 -390
- package/tests/trackg.ts +0 -1372
- package/tests/tracki-boundaries.ts +0 -202
- package/tests/tracki-continuity.ts +0 -253
- package/tests/tracki-contract-diff.ts +0 -249
- package/tests/tracki-external-bundles.ts +0 -341
- package/tests/tracki-preflight.ts +0 -251
- package/tests/verify-roles.ts +0 -51
- package/tests/worker-parity.ts +0 -286
- package/tests/worker-pool.ts +0 -262
- package/tsconfig.json +0 -20
|
@@ -0,0 +1,647 @@
|
|
|
1
|
+
# Adding New Languages To Seer
|
|
2
|
+
|
|
3
|
+
This is the full engineering checklist for adding a programming language to
|
|
4
|
+
Seer-Core. Seer language support is not just "parse a file and grab function
|
|
5
|
+
names"; a language extension touches discovery, Tree-sitter grammar loading,
|
|
6
|
+
symbol extraction, call attribution, imports, optional routes/config/service
|
|
7
|
+
calls, complexity, cache behavior, and tests.
|
|
8
|
+
|
|
9
|
+
The current language surface is:
|
|
10
|
+
|
|
11
|
+
- Python
|
|
12
|
+
- JavaScript
|
|
13
|
+
- TypeScript / TSX / JSX
|
|
14
|
+
- Go
|
|
15
|
+
- Java
|
|
16
|
+
- Rust
|
|
17
|
+
- C
|
|
18
|
+
- C++
|
|
19
|
+
- C#
|
|
20
|
+
|
|
21
|
+
Core files to read before starting:
|
|
22
|
+
|
|
23
|
+
- `src/types.ts`
|
|
24
|
+
- `src/parser/walker.ts`
|
|
25
|
+
- `src/parser/parserContext.ts`
|
|
26
|
+
- `src/parser/index.ts`
|
|
27
|
+
- `src/parser/languages/*.ts`
|
|
28
|
+
- `src/indexer/index.ts`
|
|
29
|
+
- `src/db/store.ts`
|
|
30
|
+
|
|
31
|
+
## 1. Decide The Scope
|
|
32
|
+
|
|
33
|
+
Before writing code, decide what "language support" means for this language.
|
|
34
|
+
At minimum, Seer needs:
|
|
35
|
+
|
|
36
|
+
- file extension detection
|
|
37
|
+
- Tree-sitter grammar loading
|
|
38
|
+
- definitions
|
|
39
|
+
- call/reference names
|
|
40
|
+
- imports
|
|
41
|
+
- basic complexity metrics
|
|
42
|
+
- fixture coverage
|
|
43
|
+
- smoke and parser parity tests
|
|
44
|
+
|
|
45
|
+
Optional but important for agent usefulness:
|
|
46
|
+
|
|
47
|
+
- routes/endpoints
|
|
48
|
+
- config/env reads
|
|
49
|
+
- outbound service calls
|
|
50
|
+
- declarations vs definitions
|
|
51
|
+
- test-file conventions
|
|
52
|
+
- package/dependency manifest support
|
|
53
|
+
- scale-test coverage on a real repository
|
|
54
|
+
|
|
55
|
+
Do not start by adding every possible AST node. Seer defaults should optimize
|
|
56
|
+
for AI navigation: first-party, non-generated, rankable definitions and useful
|
|
57
|
+
edges. Type aliases, declarations, and type-reference rows are useful only when
|
|
58
|
+
they are role-labelled and filtered correctly.
|
|
59
|
+
|
|
60
|
+
## 2. Confirm The Tree-Sitter Grammar Exists
|
|
61
|
+
|
|
62
|
+
Seer loads WASM grammars from `tree-sitter-wasms`:
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
tree-sitter-wasms/out/tree-sitter-<grammar>.wasm
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Check the installed package before wiring a language:
|
|
69
|
+
|
|
70
|
+
```powershell
|
|
71
|
+
Get-ChildItem node_modules\tree-sitter-wasms\out | Select-String "<language>"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
If the grammar does not exist, do not just add an extension mapping. You either
|
|
75
|
+
need to add a dependency that ships the WASM grammar or defer the language.
|
|
76
|
+
|
|
77
|
+
Some languages need grammar aliases:
|
|
78
|
+
|
|
79
|
+
- TypeScript uses `typescript`.
|
|
80
|
+
- TSX uses `tsx`.
|
|
81
|
+
- JavaScript/JSX use `javascript`.
|
|
82
|
+
- C# uses `c_sharp`.
|
|
83
|
+
- C and C++ use different grammars but share one C-family extractor.
|
|
84
|
+
|
|
85
|
+
## 3. Update Shared Types
|
|
86
|
+
|
|
87
|
+
Edit `src/types.ts`:
|
|
88
|
+
|
|
89
|
+
1. Add the language to the `Language` union.
|
|
90
|
+
2. If the language needs new symbol kinds, update `SymbolKind`. Prefer existing
|
|
91
|
+
kinds first: `function`, `method`, `constructor`, `class`, `struct`, `enum`,
|
|
92
|
+
`interface`, `type`, `variable`.
|
|
93
|
+
3. If the language introduces a genuinely new edge kind, update `EdgeKind`,
|
|
94
|
+
schema, Store methods, and tests. Avoid this unless necessary.
|
|
95
|
+
4. If it adds a new service protocol, update `ServiceProtocol`, route/service
|
|
96
|
+
call fields, schema persistence, MCP/CLI output, and Track G/H tests.
|
|
97
|
+
|
|
98
|
+
Most new languages should only need a new `Language` value.
|
|
99
|
+
|
|
100
|
+
## 4. Add The Extractor
|
|
101
|
+
|
|
102
|
+
Create:
|
|
103
|
+
|
|
104
|
+
```text
|
|
105
|
+
src/parser/languages/<language>.ts
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Export a `LanguageExtractor`:
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
import type Parser from 'web-tree-sitter';
|
|
112
|
+
import type { SymbolDef } from '../../types.js';
|
|
113
|
+
import type { LanguageExtractor } from '../walker.js';
|
|
114
|
+
import { firstLine } from '../walker.js';
|
|
115
|
+
|
|
116
|
+
const BRANCH_NODES = new Set<string>([
|
|
117
|
+
'if_statement',
|
|
118
|
+
'while_statement',
|
|
119
|
+
]);
|
|
120
|
+
|
|
121
|
+
const NESTING_NODES = new Set<string>([
|
|
122
|
+
'if_statement',
|
|
123
|
+
'while_statement',
|
|
124
|
+
]);
|
|
125
|
+
|
|
126
|
+
const CANDIDATE_NODE_TYPES = [
|
|
127
|
+
'function_definition',
|
|
128
|
+
'call_expression',
|
|
129
|
+
'import_statement',
|
|
130
|
+
] as const;
|
|
131
|
+
|
|
132
|
+
export const myLanguageExtractor: LanguageExtractor = {
|
|
133
|
+
languageName: 'my_language',
|
|
134
|
+
extensions: ['.mine'],
|
|
135
|
+
branchNodeTypes: BRANCH_NODES,
|
|
136
|
+
nestingNodeTypes: NESTING_NODES,
|
|
137
|
+
candidateNodeTypes: CANDIDATE_NODE_TYPES,
|
|
138
|
+
|
|
139
|
+
tryExtractDefinition(node: Parser.SyntaxNode): SymbolDef | null {
|
|
140
|
+
return null;
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
tryExtractCallName(node: Parser.SyntaxNode): string | null {
|
|
144
|
+
return null;
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
tryExtractImport(node: Parser.SyntaxNode): string | null {
|
|
148
|
+
return null;
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Extractor Contract
|
|
154
|
+
|
|
155
|
+
`LanguageExtractor` is defined in `src/parser/walker.ts`.
|
|
156
|
+
|
|
157
|
+
Implement these required methods:
|
|
158
|
+
|
|
159
|
+
- `tryExtractDefinition(node)`
|
|
160
|
+
- `tryExtractCallName(node)`
|
|
161
|
+
- `tryExtractImport(node)`
|
|
162
|
+
|
|
163
|
+
Optional methods:
|
|
164
|
+
|
|
165
|
+
- `tryExtractContextName(node)`
|
|
166
|
+
- `tryExtractRoute(node)`
|
|
167
|
+
- `tryExtractConfigKey(node)`
|
|
168
|
+
- `tryExtractServiceCalls(node)`
|
|
169
|
+
|
|
170
|
+
Optional complexity fields:
|
|
171
|
+
|
|
172
|
+
- `branchNodeTypes`
|
|
173
|
+
- `nestingNodeTypes`
|
|
174
|
+
- `candidateNodeTypes`
|
|
175
|
+
|
|
176
|
+
The extractor should return `null` unless it is certain. Conservative misses
|
|
177
|
+
are better than noisy symbols that pollute PageRank, search, and module
|
|
178
|
+
clustering.
|
|
179
|
+
|
|
180
|
+
## 5. Wire ParserContext
|
|
181
|
+
|
|
182
|
+
Edit `src/parser/parserContext.ts`:
|
|
183
|
+
|
|
184
|
+
1. Import the extractor.
|
|
185
|
+
2. Add extensions to `EXT_TO_LANGUAGE`.
|
|
186
|
+
3. Add the extractor to `EXTRACTORS`.
|
|
187
|
+
4. Add the grammar name to `GRAMMAR_NAME`.
|
|
188
|
+
5. Update `grammarForExtension()` if the language has multiple grammar variants.
|
|
189
|
+
|
|
190
|
+
Example:
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
import { myLanguageExtractor } from './languages/my_language.js';
|
|
194
|
+
|
|
195
|
+
export const EXT_TO_LANGUAGE = {
|
|
196
|
+
'.mine': 'my_language',
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
export const EXTRACTORS = {
|
|
200
|
+
my_language: myLanguageExtractor,
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
export const GRAMMAR_NAME = {
|
|
204
|
+
my_language: 'my_language',
|
|
205
|
+
};
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
If one extractor supports multiple grammars, follow the TypeScript/JavaScript
|
|
209
|
+
or C/C++ patterns. Do not duplicate logic just because extensions differ.
|
|
210
|
+
|
|
211
|
+
## 6. Definitions: The Hard Part
|
|
212
|
+
|
|
213
|
+
Definitions must be stable, useful, and not too noisy.
|
|
214
|
+
|
|
215
|
+
Rules:
|
|
216
|
+
|
|
217
|
+
- Return short names only. The walker computes `qualifiedName`.
|
|
218
|
+
- Use `symbolRole='definition'` for body-bearing canonical definitions.
|
|
219
|
+
- Use `symbolRole='declaration'` for prototypes/forward declarations.
|
|
220
|
+
- Use `symbolRole='type_ref'` only if you intentionally index bare type
|
|
221
|
+
references and also add query filters/tests for them.
|
|
222
|
+
- Do not index local variables as symbols unless there is a strong agent use
|
|
223
|
+
case.
|
|
224
|
+
- Prefer body-bearing definitions for rankable rows.
|
|
225
|
+
|
|
226
|
+
Rankable symbols are generally:
|
|
227
|
+
|
|
228
|
+
- `function`
|
|
229
|
+
- `method`
|
|
230
|
+
- `constructor`
|
|
231
|
+
- `class`
|
|
232
|
+
|
|
233
|
+
Non-rankable or lower-value symbols should still be queryable only when useful,
|
|
234
|
+
but should not dominate PageRank/search defaults.
|
|
235
|
+
|
|
236
|
+
### C/C++ Pitfall: Body Gates
|
|
237
|
+
|
|
238
|
+
The C/C++ extractor had a real large-repo bug:
|
|
239
|
+
|
|
240
|
+
```c
|
|
241
|
+
int foo(struct device *dev);
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Tree-sitter parses `struct device` as a `struct_specifier`, the same node type
|
|
245
|
+
used by a real definition:
|
|
246
|
+
|
|
247
|
+
```c
|
|
248
|
+
struct device {
|
|
249
|
+
int id;
|
|
250
|
+
};
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Without a body check, Seer emitted tens of thousands of fake `struct device`
|
|
254
|
+
symbols on Linux. The fix in `src/parser/languages/cpp.ts` is:
|
|
255
|
+
|
|
256
|
+
```ts
|
|
257
|
+
if (!node.childForFieldName('body')) return null;
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Apply the same discipline to any language where the grammar reuses definition
|
|
261
|
+
node types for references, declarations, or type annotations.
|
|
262
|
+
|
|
263
|
+
Examples to watch for:
|
|
264
|
+
|
|
265
|
+
- C/C++ `struct_specifier`, `class_specifier`, `enum_specifier`, `union_specifier`
|
|
266
|
+
- languages where `type_identifier` appears both in declarations and references
|
|
267
|
+
- annotations/decorators that look like calls but are not behavior
|
|
268
|
+
- interface declarations that contain method signatures but no method bodies
|
|
269
|
+
- generated partial classes or metadata-only declarations
|
|
270
|
+
|
|
271
|
+
### Declarations vs Definitions
|
|
272
|
+
|
|
273
|
+
If a language has declaration sites separate from implementation sites, label
|
|
274
|
+
them:
|
|
275
|
+
|
|
276
|
+
```ts
|
|
277
|
+
const def = mkDef(name, 'function', node);
|
|
278
|
+
def.symbolRole = 'declaration';
|
|
279
|
+
return def;
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Then add tests that default queries hide the declaration and
|
|
283
|
+
`includeDeclarations=true` brings it back.
|
|
284
|
+
|
|
285
|
+
## 7. Qualified Names And Overloads
|
|
286
|
+
|
|
287
|
+
Do not manually build `qualifiedName` in the extractor. The walker owns it.
|
|
288
|
+
|
|
289
|
+
The walker keeps a definition stack and appends `#N` when sibling definitions
|
|
290
|
+
share the same short name:
|
|
291
|
+
|
|
292
|
+
```text
|
|
293
|
+
Overload.run
|
|
294
|
+
Overload.run#1
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
This protects Java/C++/C#/TypeScript overloads and same-short-name methods like
|
|
298
|
+
`Alpha.run` and `Beta.run`.
|
|
299
|
+
|
|
300
|
+
Use `tryExtractContextName()` only for scopes that provide naming context but
|
|
301
|
+
are not themselves symbols. Rust `impl AuthService { ... }` is the model:
|
|
302
|
+
|
|
303
|
+
- the `impl` block is not a symbol
|
|
304
|
+
- it should still push `AuthService` so methods become `AuthService.login`
|
|
305
|
+
|
|
306
|
+
Context names should usually be raw names. They should not increment the
|
|
307
|
+
sibling overload counters unless they are actual definitions.
|
|
308
|
+
|
|
309
|
+
## 8. Calls And Caller Attribution
|
|
310
|
+
|
|
311
|
+
`tryExtractCallName(node)` should return the callee short name only:
|
|
312
|
+
|
|
313
|
+
```ts
|
|
314
|
+
foo() -> "foo"
|
|
315
|
+
obj.method() -> "method"
|
|
316
|
+
new User() -> "User"
|
|
317
|
+
Namespace.run() -> "run"
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
The walker sets `callerName` from the current qualified definition stack. This
|
|
321
|
+
is important: older bugs came from using only the short caller name, which made
|
|
322
|
+
`Alpha.run` and `Beta.run` collapse into one caller.
|
|
323
|
+
|
|
324
|
+
Do not attempt type inference inside the extractor. Seer resolves what it can
|
|
325
|
+
after all files are parsed. If a call cannot be resolved, keeping the unresolved
|
|
326
|
+
edge is still useful.
|
|
327
|
+
|
|
328
|
+
## 9. Imports
|
|
329
|
+
|
|
330
|
+
`tryExtractImport(node)` should return the module/path exactly enough for the
|
|
331
|
+
indexer to resolve or display it:
|
|
332
|
+
|
|
333
|
+
- relative imports: `./foo`, `../bar`
|
|
334
|
+
- package imports: `react`, `lodash`
|
|
335
|
+
- language module imports: `java.util.List`, `github.com/x/y`
|
|
336
|
+
|
|
337
|
+
If the language has non-standard import resolution, add or update resolver
|
|
338
|
+
tests. Do not assume Java/Go/Rust package systems behave like TS/Python
|
|
339
|
+
relative imports.
|
|
340
|
+
|
|
341
|
+
## 10. Routes, Config, And Service Calls
|
|
342
|
+
|
|
343
|
+
These are optional but valuable.
|
|
344
|
+
|
|
345
|
+
### Routes
|
|
346
|
+
|
|
347
|
+
`tryExtractRoute(node)` returns `RouteDef[]`.
|
|
348
|
+
|
|
349
|
+
Use it for server-side registrations:
|
|
350
|
+
|
|
351
|
+
```text
|
|
352
|
+
app.get('/users', handler)
|
|
353
|
+
@router.post('/users')
|
|
354
|
+
@GetMapping("/users")
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
Rules:
|
|
358
|
+
|
|
359
|
+
- only emit deterministic routes
|
|
360
|
+
- record framework
|
|
361
|
+
- record handler name when statically known
|
|
362
|
+
- handle class/router prefixes carefully
|
|
363
|
+
- do not emit class-level route prefixes as standalone routes
|
|
364
|
+
|
|
365
|
+
The Spring class-level `@RequestMapping("/api")` bug is the cautionary tale:
|
|
366
|
+
class annotations should prefix method routes, not create bogus independent
|
|
367
|
+
routes.
|
|
368
|
+
|
|
369
|
+
### Config Keys
|
|
370
|
+
|
|
371
|
+
`tryExtractConfigKey(node)` returns `ConfigKeyRead`.
|
|
372
|
+
|
|
373
|
+
Examples:
|
|
374
|
+
|
|
375
|
+
```text
|
|
376
|
+
process.env.DB_URL
|
|
377
|
+
os.getenv("DB_URL")
|
|
378
|
+
System.getenv("DB_URL")
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
The walker fills `callerName` from the def stack.
|
|
382
|
+
|
|
383
|
+
### Service Calls
|
|
384
|
+
|
|
385
|
+
`tryExtractServiceCalls(node)` returns `ServiceCallDef[]`.
|
|
386
|
+
|
|
387
|
+
Use it for outbound client calls:
|
|
388
|
+
|
|
389
|
+
```text
|
|
390
|
+
fetch('/api/users')
|
|
391
|
+
axios.post('/checkout')
|
|
392
|
+
requests.get('/health')
|
|
393
|
+
http.Get("http://payment/api/charge")
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
Rules:
|
|
397
|
+
|
|
398
|
+
- server-side route registrations are not service calls
|
|
399
|
+
- keep `rawTarget` even when the target is dynamic
|
|
400
|
+
- fill `normalizedPath` only when statically extractable
|
|
401
|
+
- record method/protocol/host hints when known
|
|
402
|
+
- stay conservative; false links are worse than unresolved calls
|
|
403
|
+
|
|
404
|
+
The walker skips service-call extraction on nodes already classified as route
|
|
405
|
+
registrations, so a route mount does not link to itself.
|
|
406
|
+
|
|
407
|
+
## 11. Candidate Node Types
|
|
408
|
+
|
|
409
|
+
Every extractor should declare `candidateNodeTypes`.
|
|
410
|
+
|
|
411
|
+
This list must be a superset of every node type any extractor method may
|
|
412
|
+
accept:
|
|
413
|
+
|
|
414
|
+
- definitions
|
|
415
|
+
- calls
|
|
416
|
+
- imports
|
|
417
|
+
- context nodes
|
|
418
|
+
- routes
|
|
419
|
+
- config reads
|
|
420
|
+
- service calls
|
|
421
|
+
|
|
422
|
+
Missing a node type is dangerous because the Tree-sitter query path will never
|
|
423
|
+
call the extractor for that node. The baseline walker may still work, which is
|
|
424
|
+
why `tests/query-parity.ts` exists.
|
|
425
|
+
|
|
426
|
+
For grammars shared by multiple languages, a superset is okay. C/C++ uses one
|
|
427
|
+
candidate list even though some node types only exist in the C++ grammar; the
|
|
428
|
+
parser probes node types and drops those rejected by the active grammar.
|
|
429
|
+
|
|
430
|
+
When you add or change candidate nodes, run:
|
|
431
|
+
|
|
432
|
+
```powershell
|
|
433
|
+
npm run test:query-parity
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
Also consider extending `tests/query-parity.ts` if the new feature category is
|
|
437
|
+
not included in its canonical comparison.
|
|
438
|
+
|
|
439
|
+
## 12. Complexity Metrics
|
|
440
|
+
|
|
441
|
+
If the language has function-like bodies, add `branchNodeTypes` and
|
|
442
|
+
`nestingNodeTypes`.
|
|
443
|
+
|
|
444
|
+
Cyclomatic complexity increments on branches like:
|
|
445
|
+
|
|
446
|
+
- `if`
|
|
447
|
+
- `for`
|
|
448
|
+
- `while`
|
|
449
|
+
- `catch`
|
|
450
|
+
- `case`
|
|
451
|
+
- ternary/conditional
|
|
452
|
+
|
|
453
|
+
Cognitive complexity uses nesting depth. Keep these lists conservative and
|
|
454
|
+
language-specific.
|
|
455
|
+
|
|
456
|
+
If `branchNodeTypes` is omitted, Seer still records LOC for function-like
|
|
457
|
+
symbols, but leaves cyclomatic/cognitive/max nesting null.
|
|
458
|
+
|
|
459
|
+
## 13. Cache And Migration Gotchas
|
|
460
|
+
|
|
461
|
+
Changing an extractor does not automatically update already-cached files. If
|
|
462
|
+
file hashes are unchanged, `upsertFileWithCache()` can skip parsing.
|
|
463
|
+
|
|
464
|
+
This matters when a new language or new extraction category is introduced after
|
|
465
|
+
DBs already exist. Track G hit this exact bug: migrated pre-v8 DBs had empty
|
|
466
|
+
`service_calls` because unchanged files were hash-cached before service-call
|
|
467
|
+
extraction existed.
|
|
468
|
+
|
|
469
|
+
If a new extractor feature needs to backfill existing DBs, add a marker:
|
|
470
|
+
|
|
471
|
+
- store a version or completion marker in schema metadata/state
|
|
472
|
+
- detect missing backfill before indexing
|
|
473
|
+
- bypass parse cache for one full pass
|
|
474
|
+
- mark backfill complete only after the post-pass succeeds
|
|
475
|
+
|
|
476
|
+
Patterns to inspect:
|
|
477
|
+
|
|
478
|
+
- shape-hash backfill in Track F
|
|
479
|
+
- service-call backfill in Track G
|
|
480
|
+
- `Store.hasMissingShapeHashes()`
|
|
481
|
+
- `Store.needsServiceCallBackfill()`
|
|
482
|
+
|
|
483
|
+
## 14. Discovery And Classification
|
|
484
|
+
|
|
485
|
+
Most languages only need extension mapping. But check whether the language has:
|
|
486
|
+
|
|
487
|
+
- generated files with conventional suffixes
|
|
488
|
+
- vendored package roots
|
|
489
|
+
- build-output roots
|
|
490
|
+
- test-file naming conventions
|
|
491
|
+
|
|
492
|
+
Update these if necessary:
|
|
493
|
+
|
|
494
|
+
- `src/indexer/discovery.ts`
|
|
495
|
+
- `src/indexer/classify.ts`
|
|
496
|
+
- scale-test role assertions if the language appears in large repos
|
|
497
|
+
|
|
498
|
+
Default queries should stay project-first and should not let vendor/generated
|
|
499
|
+
symbols dominate PageRank.
|
|
500
|
+
|
|
501
|
+
## 15. Tests To Add
|
|
502
|
+
|
|
503
|
+
At minimum, add one fixture file:
|
|
504
|
+
|
|
505
|
+
```text
|
|
506
|
+
tests/fixtures/sample.<ext>
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
It should include:
|
|
510
|
+
|
|
511
|
+
- at least one top-level function
|
|
512
|
+
- at least one class/struct/module-level container if the language has one
|
|
513
|
+
- at least one method
|
|
514
|
+
- at least one call that resolves
|
|
515
|
+
- at least one call that remains unresolved
|
|
516
|
+
- at least one import
|
|
517
|
+
- one same-short-name collision or overload case if the language supports it
|
|
518
|
+
- one declaration-vs-definition case if the language has declarations
|
|
519
|
+
|
|
520
|
+
Then update or add tests:
|
|
521
|
+
|
|
522
|
+
### Smoke
|
|
523
|
+
|
|
524
|
+
Update `tests/smoke.ts`:
|
|
525
|
+
|
|
526
|
+
- assert the language appears in `store.getStats().languages`
|
|
527
|
+
- assert important symbols are found
|
|
528
|
+
- assert at least one caller/callee relationship
|
|
529
|
+
- assert qualified names are correct
|
|
530
|
+
- assert overloads/collisions do not collapse
|
|
531
|
+
|
|
532
|
+
Run:
|
|
533
|
+
|
|
534
|
+
```powershell
|
|
535
|
+
npm run test:smoke
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
### Query Parity
|
|
539
|
+
|
|
540
|
+
Update `tests/query-parity.ts` extension allowlist and fixture coverage.
|
|
541
|
+
|
|
542
|
+
Run:
|
|
543
|
+
|
|
544
|
+
```powershell
|
|
545
|
+
npm run test:query-parity
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
### Worker Parity
|
|
549
|
+
|
|
550
|
+
Parser workers must produce byte-identical extraction to in-process parsing.
|
|
551
|
+
If the fixture walker does not already pick up the new extension, update it.
|
|
552
|
+
|
|
553
|
+
Run:
|
|
554
|
+
|
|
555
|
+
```powershell
|
|
556
|
+
npm run test:worker-parity
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
### Filters
|
|
560
|
+
|
|
561
|
+
If the language emits declarations, type refs, tests, vendor/generated files,
|
|
562
|
+
or non-rankable symbol kinds, update:
|
|
563
|
+
|
|
564
|
+
```powershell
|
|
565
|
+
npm run test:filters
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
### Feature Tests
|
|
569
|
+
|
|
570
|
+
If the language adds routes/config/service calls, add focused tests in the
|
|
571
|
+
relevant suite:
|
|
572
|
+
|
|
573
|
+
- `tests/trackcd.ts` for routes/config/deps/complexity
|
|
574
|
+
- `tests/trackg.ts` for service calls/links
|
|
575
|
+
- `tests/mcp-trackg.ts` if the feature is exposed through MCP
|
|
576
|
+
|
|
577
|
+
### Full Suite
|
|
578
|
+
|
|
579
|
+
Always end with:
|
|
580
|
+
|
|
581
|
+
```powershell
|
|
582
|
+
npm run build
|
|
583
|
+
npm test
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
If the new language is intended for large repos, also run:
|
|
587
|
+
|
|
588
|
+
```powershell
|
|
589
|
+
npm run test:scale-parallel-parity
|
|
590
|
+
npm run scale-test -- --only <repo>
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
## 16. Manual Inspection Checklist
|
|
594
|
+
|
|
595
|
+
After indexing a fixture or real repo, inspect:
|
|
596
|
+
|
|
597
|
+
- total files by language
|
|
598
|
+
- top symbols by PageRank
|
|
599
|
+
- role counts
|
|
600
|
+
- declarations hidden by default
|
|
601
|
+
- test symbols hidden by default
|
|
602
|
+
- vendor/generated paths not appearing in top results
|
|
603
|
+
- qualified names for methods
|
|
604
|
+
- callers/callees on same-short-name methods
|
|
605
|
+
- service calls not duplicating server route registrations
|
|
606
|
+
- route prefixes applied correctly
|
|
607
|
+
- cache re-run does not delete or duplicate rows
|
|
608
|
+
|
|
609
|
+
Useful commands:
|
|
610
|
+
|
|
611
|
+
```powershell
|
|
612
|
+
npm run dev -- index tests/fixtures --reset
|
|
613
|
+
npm run dev -- stats
|
|
614
|
+
npm run dev -- symbols <name> --include-declarations
|
|
615
|
+
npm run dev -- callers <name> --limit 20
|
|
616
|
+
npm run dev -- callees <name> --limit 20
|
|
617
|
+
npm run dev -- routes
|
|
618
|
+
npm run dev -- service-calls
|
|
619
|
+
npm run dev -- service-links
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
## 17. Final Review Checklist
|
|
623
|
+
|
|
624
|
+
Before calling the language done:
|
|
625
|
+
|
|
626
|
+
- `Language` union updated
|
|
627
|
+
- extension detection works
|
|
628
|
+
- grammar loads from `tree-sitter-wasms`
|
|
629
|
+
- extractor added and wired in `EXTRACTORS`
|
|
630
|
+
- `GRAMMAR_NAME` and `grammarForExtension()` are correct
|
|
631
|
+
- `candidateNodeTypes` is a true superset
|
|
632
|
+
- body-bearing definitions are not confused with references/declarations
|
|
633
|
+
- declarations use `symbolRole='declaration'`
|
|
634
|
+
- noisy type refs are avoided or role-labelled
|
|
635
|
+
- qualified names come from the walker, not extractor-local strings
|
|
636
|
+
- overloads/same-short-name symbols stay distinct
|
|
637
|
+
- calls get correct caller attribution
|
|
638
|
+
- imports are captured
|
|
639
|
+
- complexity is populated for function-like symbols
|
|
640
|
+
- optional route/config/service extraction is conservative and tested
|
|
641
|
+
- cache/backfill implications are handled
|
|
642
|
+
- smoke/query-parity/worker-parity/full suite pass
|
|
643
|
+
- scale/parity tests pass if the language targets large repos
|
|
644
|
+
|
|
645
|
+
The guiding principle: add enough language intelligence for agents to navigate
|
|
646
|
+
with confidence, while avoiding noisy rows that make the graph look bigger but
|
|
647
|
+
less true.
|
package/dist/cli/index.js
CHANGED
|
@@ -46,7 +46,7 @@ const behavior_js_1 = require("../indexer/behavior.js");
|
|
|
46
46
|
const risk_js_1 = require("../indexer/risk.js");
|
|
47
47
|
const context_js_1 = require("../indexer/context.js");
|
|
48
48
|
const init_js_1 = require("./init.js");
|
|
49
|
-
const VERSION = '0.1.
|
|
49
|
+
const VERSION = '0.1.2';
|
|
50
50
|
const KNOWN_CLIENTS = ['claude', 'cursor', 'vscode', 'codex', 'gemini', 'antigravity'];
|
|
51
51
|
function resolveDb(repoPath, customDb) {
|
|
52
52
|
if (customDb)
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "seer-mcp",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Give your AI agents a map of your repo before they edit.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
5
6
|
"private": false,
|
|
6
7
|
"type": "commonjs",
|
|
7
8
|
"bin": {
|