codebase-context 1.6.1 → 1.7.0

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.
Files changed (149) hide show
  1. package/README.md +142 -46
  2. package/dist/analyzers/angular/index.d.ts +4 -0
  3. package/dist/analyzers/angular/index.d.ts.map +1 -1
  4. package/dist/analyzers/angular/index.js +51 -10
  5. package/dist/analyzers/angular/index.js.map +1 -1
  6. package/dist/analyzers/generic/index.d.ts +1 -0
  7. package/dist/analyzers/generic/index.d.ts.map +1 -1
  8. package/dist/analyzers/generic/index.js +89 -10
  9. package/dist/analyzers/generic/index.js.map +1 -1
  10. package/dist/cli.d.ts +8 -0
  11. package/dist/cli.d.ts.map +1 -0
  12. package/dist/cli.js +352 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/constants/codebase-context.d.ts +13 -0
  15. package/dist/constants/codebase-context.d.ts.map +1 -1
  16. package/dist/constants/codebase-context.js +13 -0
  17. package/dist/constants/codebase-context.js.map +1 -1
  18. package/dist/core/index-meta.d.ts +24 -0
  19. package/dist/core/index-meta.d.ts.map +1 -0
  20. package/dist/core/index-meta.js +204 -0
  21. package/dist/core/index-meta.js.map +1 -0
  22. package/dist/core/indexer.d.ts +0 -5
  23. package/dist/core/indexer.d.ts.map +1 -1
  24. package/dist/core/indexer.js +265 -60
  25. package/dist/core/indexer.js.map +1 -1
  26. package/dist/core/search.d.ts +1 -0
  27. package/dist/core/search.d.ts.map +1 -1
  28. package/dist/core/search.js +60 -5
  29. package/dist/core/search.js.map +1 -1
  30. package/dist/core/symbol-references.d.ts +21 -0
  31. package/dist/core/symbol-references.d.ts.map +1 -0
  32. package/dist/core/symbol-references.js +91 -0
  33. package/dist/core/symbol-references.js.map +1 -0
  34. package/dist/eval/harness.d.ts +5 -0
  35. package/dist/eval/harness.d.ts.map +1 -0
  36. package/dist/eval/harness.js +153 -0
  37. package/dist/eval/harness.js.map +1 -0
  38. package/dist/eval/types.d.ts +59 -0
  39. package/dist/eval/types.d.ts.map +1 -0
  40. package/dist/eval/types.js +2 -0
  41. package/dist/eval/types.js.map +1 -0
  42. package/dist/grammars/manifest.d.ts +26 -0
  43. package/dist/grammars/manifest.d.ts.map +1 -0
  44. package/dist/grammars/manifest.js +63 -0
  45. package/dist/grammars/manifest.js.map +1 -0
  46. package/dist/index.d.ts +12 -2
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +146 -1231
  49. package/dist/index.js.map +1 -1
  50. package/dist/memory/store.d.ts +3 -0
  51. package/dist/memory/store.d.ts.map +1 -1
  52. package/dist/memory/store.js +9 -0
  53. package/dist/memory/store.js.map +1 -1
  54. package/dist/patterns/semantics.d.ts +6 -0
  55. package/dist/patterns/semantics.d.ts.map +1 -1
  56. package/dist/patterns/semantics.js +22 -6
  57. package/dist/patterns/semantics.js.map +1 -1
  58. package/dist/preflight/evidence-lock.d.ts +8 -0
  59. package/dist/preflight/evidence-lock.d.ts.map +1 -1
  60. package/dist/preflight/evidence-lock.js +49 -3
  61. package/dist/preflight/evidence-lock.js.map +1 -1
  62. package/dist/storage/lancedb.d.ts +9 -1
  63. package/dist/storage/lancedb.d.ts.map +1 -1
  64. package/dist/storage/lancedb.js +26 -8
  65. package/dist/storage/lancedb.js.map +1 -1
  66. package/dist/tools/detect-circular-dependencies.d.ts +5 -0
  67. package/dist/tools/detect-circular-dependencies.d.ts.map +1 -0
  68. package/dist/tools/detect-circular-dependencies.js +117 -0
  69. package/dist/tools/detect-circular-dependencies.js.map +1 -0
  70. package/dist/tools/get-codebase-metadata.d.ts +5 -0
  71. package/dist/tools/get-codebase-metadata.d.ts.map +1 -0
  72. package/dist/tools/get-codebase-metadata.js +53 -0
  73. package/dist/tools/get-codebase-metadata.js.map +1 -0
  74. package/dist/tools/get-component-usage.d.ts +5 -0
  75. package/dist/tools/get-component-usage.d.ts.map +1 -0
  76. package/dist/tools/get-component-usage.js +83 -0
  77. package/dist/tools/get-component-usage.js.map +1 -0
  78. package/dist/tools/get-indexing-status.d.ts +5 -0
  79. package/dist/tools/get-indexing-status.d.ts.map +1 -0
  80. package/dist/tools/get-indexing-status.js +44 -0
  81. package/dist/tools/get-indexing-status.js.map +1 -0
  82. package/dist/tools/get-memory.d.ts +5 -0
  83. package/dist/tools/get-memory.d.ts.map +1 -0
  84. package/dist/tools/get-memory.js +89 -0
  85. package/dist/tools/get-memory.js.map +1 -0
  86. package/dist/tools/get-style-guide.d.ts +5 -0
  87. package/dist/tools/get-style-guide.d.ts.map +1 -0
  88. package/dist/tools/get-style-guide.js +151 -0
  89. package/dist/tools/get-style-guide.js.map +1 -0
  90. package/dist/tools/get-symbol-references.d.ts +5 -0
  91. package/dist/tools/get-symbol-references.d.ts.map +1 -0
  92. package/dist/tools/get-symbol-references.js +70 -0
  93. package/dist/tools/get-symbol-references.js.map +1 -0
  94. package/dist/tools/get-team-patterns.d.ts +5 -0
  95. package/dist/tools/get-team-patterns.d.ts.map +1 -0
  96. package/dist/tools/get-team-patterns.js +131 -0
  97. package/dist/tools/get-team-patterns.js.map +1 -0
  98. package/dist/tools/index.d.ts +6 -0
  99. package/dist/tools/index.d.ts.map +1 -0
  100. package/dist/tools/index.js +41 -0
  101. package/dist/tools/index.js.map +1 -0
  102. package/dist/tools/refresh-index.d.ts +5 -0
  103. package/dist/tools/refresh-index.d.ts.map +1 -0
  104. package/dist/tools/refresh-index.js +40 -0
  105. package/dist/tools/refresh-index.js.map +1 -0
  106. package/dist/tools/remember.d.ts +5 -0
  107. package/dist/tools/remember.d.ts.map +1 -0
  108. package/dist/tools/remember.js +101 -0
  109. package/dist/tools/remember.js.map +1 -0
  110. package/dist/tools/search-codebase.d.ts +5 -0
  111. package/dist/tools/search-codebase.d.ts.map +1 -0
  112. package/dist/tools/search-codebase.js +638 -0
  113. package/dist/tools/search-codebase.js.map +1 -0
  114. package/dist/tools/types.d.ts +31 -0
  115. package/dist/tools/types.d.ts.map +1 -0
  116. package/dist/tools/types.js +2 -0
  117. package/dist/tools/types.js.map +1 -0
  118. package/dist/types/index.d.ts +8 -0
  119. package/dist/types/index.d.ts.map +1 -1
  120. package/dist/utils/ast-chunker.d.ts +71 -0
  121. package/dist/utils/ast-chunker.d.ts.map +1 -0
  122. package/dist/utils/ast-chunker.js +453 -0
  123. package/dist/utils/ast-chunker.js.map +1 -0
  124. package/dist/utils/chunking.d.ts.map +1 -1
  125. package/dist/utils/chunking.js +10 -3
  126. package/dist/utils/chunking.js.map +1 -1
  127. package/dist/utils/dependency-detection.d.ts +2 -1
  128. package/dist/utils/dependency-detection.d.ts.map +1 -1
  129. package/dist/utils/dependency-detection.js.map +1 -1
  130. package/dist/utils/language-detection.d.ts.map +1 -1
  131. package/dist/utils/language-detection.js +20 -0
  132. package/dist/utils/language-detection.js.map +1 -1
  133. package/dist/utils/tree-sitter.d.ts +17 -0
  134. package/dist/utils/tree-sitter.d.ts.map +1 -0
  135. package/dist/utils/tree-sitter.js +311 -0
  136. package/dist/utils/tree-sitter.js.map +1 -0
  137. package/docs/capabilities.md +131 -37
  138. package/grammars/.gitkeep +0 -0
  139. package/grammars/tree-sitter-c.wasm +0 -0
  140. package/grammars/tree-sitter-c_sharp.wasm +0 -0
  141. package/grammars/tree-sitter-cpp.wasm +0 -0
  142. package/grammars/tree-sitter-go.wasm +0 -0
  143. package/grammars/tree-sitter-java.wasm +0 -0
  144. package/grammars/tree-sitter-javascript.wasm +0 -0
  145. package/grammars/tree-sitter-python.wasm +0 -0
  146. package/grammars/tree-sitter-rust.wasm +0 -0
  147. package/grammars/tree-sitter-tsx.wasm +0 -0
  148. package/grammars/tree-sitter-typescript.wasm +0 -0
  149. package/package.json +12 -5
@@ -0,0 +1,17 @@
1
+ export interface TreeSitterSymbol {
2
+ name: string;
3
+ kind: string;
4
+ startLine: number;
5
+ endLine: number;
6
+ startIndex: number;
7
+ endIndex: number;
8
+ content: string;
9
+ nodeType: string;
10
+ }
11
+ export interface TreeSitterSymbolExtraction {
12
+ grammarFile: string;
13
+ symbols: TreeSitterSymbol[];
14
+ }
15
+ export declare function supportsTreeSitter(language: string): boolean;
16
+ export declare function extractTreeSitterSymbols(content: string, language: string): Promise<TreeSitterSymbolExtraction | null>;
17
+ //# sourceMappingURL=tree-sitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-sitter.d.ts","sourceRoot":"","sources":["../../src/utils/tree-sitter.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B;AAmGD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE5D;AA2KD,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,0BAA0B,GAAG,IAAI,CAAC,CAqF5C"}
@@ -0,0 +1,311 @@
1
+ import { createRequire } from 'module';
2
+ import { Language, Parser } from 'web-tree-sitter';
3
+ import { CURATED_LANGUAGE_TO_WASM, supportsCuratedTreeSitter, resolveGrammarPath } from '../grammars/manifest.js';
4
+ const require = createRequire(import.meta.url);
5
+ const CORE_WASM_PATH = require.resolve('web-tree-sitter/tree-sitter.wasm');
6
+ const SYMBOL_CANDIDATE_NODE_TYPES = [
7
+ 'class_declaration',
8
+ 'class_definition',
9
+ 'class_specifier',
10
+ 'constructor_declaration',
11
+ 'enum_declaration',
12
+ 'enum_item',
13
+ 'function_declaration',
14
+ 'function_definition',
15
+ 'function_item',
16
+ 'generator_function_declaration',
17
+ 'interface_declaration',
18
+ 'lexical_declaration',
19
+ 'method',
20
+ 'method_declaration',
21
+ 'method_definition',
22
+ 'struct_item',
23
+ 'struct_specifier',
24
+ 'trait_item',
25
+ 'type_alias_declaration',
26
+ 'type_declaration',
27
+ 'type_spec',
28
+ 'variable_declarator'
29
+ ];
30
+ const NAME_FIELD_CANDIDATES = ['name', 'declarator', 'property', 'path'];
31
+ const NAME_NODE_TYPE_HINTS = [
32
+ 'identifier',
33
+ 'type_identifier',
34
+ 'property_identifier',
35
+ 'scoped_identifier',
36
+ 'constant',
37
+ 'name'
38
+ ];
39
+ const MAX_TREE_SITTER_PARSE_BYTES = 1024 * 1024;
40
+ const TREE_SITTER_PARSE_TIMEOUT_MICROS = 30000000n;
41
+ let initPromise = null;
42
+ const languageCache = new Map();
43
+ const parserCache = new Map();
44
+ function maybeResetParser(parser) {
45
+ const maybeReset = parser.reset;
46
+ if (typeof maybeReset === 'function') {
47
+ maybeReset.call(parser);
48
+ }
49
+ }
50
+ function evictParser(language, parser) {
51
+ if (parser) {
52
+ maybeResetParser(parser);
53
+ }
54
+ parserCache.delete(language);
55
+ }
56
+ function setParseTimeout(parser) {
57
+ const maybeSetTimeout = parser.setTimeoutMicros;
58
+ if (typeof maybeSetTimeout === 'function') {
59
+ try {
60
+ maybeSetTimeout.call(parser, TREE_SITTER_PARSE_TIMEOUT_MICROS);
61
+ }
62
+ catch {
63
+ try {
64
+ maybeSetTimeout.call(parser, Number(TREE_SITTER_PARSE_TIMEOUT_MICROS));
65
+ }
66
+ catch {
67
+ // Ignore timeout wiring failures; parser execution still proceeds.
68
+ }
69
+ }
70
+ }
71
+ }
72
+ function sliceUtf8(content, startIndex, endIndex) {
73
+ const utf8 = Buffer.from(content, 'utf8');
74
+ return utf8.subarray(startIndex, endIndex).toString('utf8');
75
+ }
76
+ function extractNodeContent(node, content) {
77
+ const byteSlice = sliceUtf8(content, node.startIndex, node.endIndex);
78
+ const codeUnitSlice = content.slice(node.startIndex, node.endIndex);
79
+ if (node.text === codeUnitSlice && node.text !== byteSlice) {
80
+ return codeUnitSlice;
81
+ }
82
+ return byteSlice;
83
+ }
84
+ function isTreeSitterDebugEnabled() {
85
+ return Boolean(process.env.CODEBASE_CONTEXT_DEBUG);
86
+ }
87
+ export function supportsTreeSitter(language) {
88
+ return supportsCuratedTreeSitter(language);
89
+ }
90
+ async function ensureParserInitialized() {
91
+ if (!initPromise) {
92
+ initPromise = Parser.init({
93
+ locateFile(scriptName) {
94
+ if (scriptName === 'tree-sitter.wasm') {
95
+ return CORE_WASM_PATH;
96
+ }
97
+ return scriptName;
98
+ }
99
+ });
100
+ }
101
+ await initPromise;
102
+ }
103
+ async function loadLanguage(language) {
104
+ const wasmFile = CURATED_LANGUAGE_TO_WASM[language];
105
+ if (!wasmFile) {
106
+ throw new Error(`Tree-sitter grammar is not configured for '${language}'.`);
107
+ }
108
+ let cachedLanguage = languageCache.get(language);
109
+ if (!cachedLanguage) {
110
+ const { wasmPath } = resolveGrammarPath(language, import.meta.url);
111
+ cachedLanguage = Language.load(wasmPath).catch((err) => {
112
+ // Evict failed entry so later calls can retry after fixes
113
+ languageCache.delete(language);
114
+ throw err;
115
+ });
116
+ languageCache.set(language, cachedLanguage);
117
+ }
118
+ return cachedLanguage;
119
+ }
120
+ async function getParserForLanguage(language) {
121
+ let cachedParser = parserCache.get(language);
122
+ if (!cachedParser) {
123
+ cachedParser = (async () => {
124
+ await ensureParserInitialized();
125
+ const parser = new Parser();
126
+ try {
127
+ parser.setLanguage(await loadLanguage(language));
128
+ }
129
+ catch (err) {
130
+ // setLanguage failed — evict both caches so retry is possible
131
+ parserCache.delete(language);
132
+ languageCache.delete(language);
133
+ throw err;
134
+ }
135
+ return parser;
136
+ })();
137
+ parserCache.set(language, cachedParser);
138
+ }
139
+ return cachedParser;
140
+ }
141
+ function getNodeKind(nodeType) {
142
+ if (nodeType.includes('class'))
143
+ return 'class';
144
+ if (nodeType.includes('interface'))
145
+ return 'interface';
146
+ if (nodeType.includes('enum'))
147
+ return 'enum';
148
+ if (nodeType.includes('struct'))
149
+ return 'struct';
150
+ if (nodeType.includes('trait'))
151
+ return 'trait';
152
+ if (nodeType.includes('constructor'))
153
+ return 'method';
154
+ if (nodeType.includes('method'))
155
+ return 'method';
156
+ if (nodeType.includes('type_alias') || nodeType === 'type_spec')
157
+ return 'type';
158
+ return 'function';
159
+ }
160
+ function normalizeSymbolName(rawName) {
161
+ return rawName
162
+ .replace(/[\s\n\t]+/g, ' ')
163
+ .trim()
164
+ .replace(/^[:@#]+/, '');
165
+ }
166
+ function maybeGetNameNode(node) {
167
+ for (const fieldName of NAME_FIELD_CANDIDATES) {
168
+ const field = node.childForFieldName(fieldName);
169
+ if (field) {
170
+ return field;
171
+ }
172
+ }
173
+ for (const child of node.namedChildren) {
174
+ if (!child)
175
+ continue;
176
+ if (NAME_NODE_TYPE_HINTS.some((hint) => child.type.includes(hint))) {
177
+ return child;
178
+ }
179
+ }
180
+ return null;
181
+ }
182
+ function extractNodeName(node) {
183
+ const nameNode = maybeGetNameNode(node);
184
+ if (nameNode?.text) {
185
+ const normalized = normalizeSymbolName(nameNode.text);
186
+ if (normalized) {
187
+ return normalized;
188
+ }
189
+ }
190
+ const compact = node.text.slice(0, 120).replace(/\s+/g, ' ').trim();
191
+ const match = compact.match(/(?:class|interface|enum|struct|trait|function|def|fn)\s+([A-Za-z_][\w$]*)/);
192
+ if (match?.[1]) {
193
+ return match[1];
194
+ }
195
+ return 'anonymous';
196
+ }
197
+ function isFunctionVariableDeclarator(node) {
198
+ if (node.type !== 'variable_declarator') {
199
+ return false;
200
+ }
201
+ const valueNode = node.childForFieldName('value');
202
+ if (!valueNode) {
203
+ return false;
204
+ }
205
+ return valueNode.type === 'arrow_function' || valueNode.type === 'function_expression';
206
+ }
207
+ function shouldSkipNode(language, node) {
208
+ if (node.type === 'variable_declarator') {
209
+ return (!['javascript', 'javascriptreact', 'typescript', 'typescriptreact'].includes(language) ||
210
+ !isFunctionVariableDeclarator(node));
211
+ }
212
+ if (node.type === 'lexical_declaration') {
213
+ return true;
214
+ }
215
+ if (node.type === 'type_declaration') {
216
+ return true;
217
+ }
218
+ return false;
219
+ }
220
+ function getSymbolRangeNode(node) {
221
+ const parent = node.parent;
222
+ if (parent?.type === 'export_statement') {
223
+ return parent;
224
+ }
225
+ return node;
226
+ }
227
+ function buildSymbol(node, content) {
228
+ const rangeNode = getSymbolRangeNode(node);
229
+ return {
230
+ name: extractNodeName(node),
231
+ kind: getNodeKind(node.type),
232
+ startLine: rangeNode.startPosition.row + 1,
233
+ endLine: rangeNode.endPosition.row + 1,
234
+ startIndex: rangeNode.startIndex,
235
+ endIndex: rangeNode.endIndex,
236
+ content: extractNodeContent(rangeNode, content),
237
+ nodeType: node.type
238
+ };
239
+ }
240
+ export async function extractTreeSitterSymbols(content, language) {
241
+ if (!supportsTreeSitter(language) || !content.trim()) {
242
+ return null;
243
+ }
244
+ if (Buffer.byteLength(content, 'utf8') > MAX_TREE_SITTER_PARSE_BYTES) {
245
+ return null;
246
+ }
247
+ try {
248
+ const parser = await getParserForLanguage(language);
249
+ setParseTimeout(parser);
250
+ let tree;
251
+ try {
252
+ tree = parser.parse(content);
253
+ }
254
+ catch (error) {
255
+ evictParser(language, parser);
256
+ throw error;
257
+ }
258
+ if (!tree) {
259
+ evictParser(language, parser);
260
+ return null;
261
+ }
262
+ try {
263
+ const hasErrorValue = tree.rootNode.hasError;
264
+ const rootHasError = typeof hasErrorValue === 'function'
265
+ ? Boolean(hasErrorValue())
266
+ : Boolean(hasErrorValue);
267
+ if (rootHasError) {
268
+ return null;
269
+ }
270
+ const nodes = tree.rootNode.descendantsOfType([...SYMBOL_CANDIDATE_NODE_TYPES]);
271
+ const seen = new Set();
272
+ const symbols = [];
273
+ for (const node of nodes) {
274
+ if (!node || !node.isNamed || shouldSkipNode(language, node)) {
275
+ continue;
276
+ }
277
+ const symbol = buildSymbol(node, content);
278
+ if (symbol.name === 'anonymous') {
279
+ continue;
280
+ }
281
+ const key = `${symbol.kind}:${symbol.name}:${symbol.startLine}:${symbol.endLine}`;
282
+ if (seen.has(key)) {
283
+ continue;
284
+ }
285
+ seen.add(key);
286
+ symbols.push(symbol);
287
+ }
288
+ symbols.sort((a, b) => {
289
+ if (a.startLine !== b.startLine) {
290
+ return a.startLine - b.startLine;
291
+ }
292
+ return a.endLine - b.endLine;
293
+ });
294
+ return {
295
+ grammarFile: CURATED_LANGUAGE_TO_WASM[language] ?? language,
296
+ symbols
297
+ };
298
+ }
299
+ finally {
300
+ tree.delete();
301
+ }
302
+ }
303
+ catch (error) {
304
+ evictParser(language);
305
+ if (isTreeSitterDebugEnabled()) {
306
+ console.error(`[DEBUG] Tree-sitter symbol extraction failed for '${language}':`, error instanceof Error ? error.message : String(error));
307
+ }
308
+ return null;
309
+ }
310
+ }
311
+ //# sourceMappingURL=tree-sitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-sitter.js","sourceRoot":"","sources":["../../src/utils/tree-sitter.ts"],"names":[],"mappings":"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"}
@@ -2,29 +2,58 @@
2
2
 
3
3
  Technical reference for what `codebase-context` ships today. For the user-facing overview, see [README.md](../README.md).
4
4
 
5
+ ## CLI Reference
6
+
7
+ All 10 MCP tools are exposed as CLI subcommands. Set `CODEBASE_ROOT` or run from the project directory.
8
+
9
+ | Command | Flags | Maps to |
10
+ |---|---|---|
11
+ | `search --query <q>` | `--intent explore\|edit\|refactor\|migrate`, `--limit <n>`, `--lang <l>`, `--framework <f>`, `--layer <l>` | `search_codebase` |
12
+ | `metadata` | — | `get_codebase_metadata` |
13
+ | `status` | — | `get_indexing_status` |
14
+ | `reindex` | `--incremental`, `--reason <r>` | `refresh_index` |
15
+ | `style-guide` | `--query <q>`, `--category <c>` | `get_style_guide` |
16
+ | `patterns` | `--category all\|di\|state\|testing\|libraries` | `get_team_patterns` |
17
+ | `refs --symbol <name>` | `--limit <n>` | `get_symbol_references` |
18
+ | `cycles` | `--scope <path>` | `detect_circular_dependencies` |
19
+ | `memory list` | `--category`, `--type`, `--query`, `--json` | — |
20
+ | `memory add` | `--type`, `--category`, `--memory`, `--reason` | `remember` |
21
+ | `memory remove <id>` | — | — |
22
+
23
+ All commands accept `--json` for raw JSON output. Errors go to stderr with exit code 1.
24
+
25
+ ```bash
26
+ # Quick examples
27
+ npx codebase-context status
28
+ npx codebase-context search --query "auth middleware" --intent edit
29
+ npx codebase-context refs --symbol "UserService" --limit 10
30
+ npx codebase-context cycles --scope src/features
31
+ npx codebase-context reindex --incremental
32
+ ```
33
+
5
34
  ## Tool Surface
6
35
 
7
- 10 MCP tools + 1 optional resource (`codebase://context`).
36
+ 10 MCP tools + 1 optional resource (`codebase://context`). **Migration:** `get_component_usage` was removed; use `get_symbol_references` for symbol usage evidence.
8
37
 
9
38
  ### Core Tools
10
39
 
11
- | Tool | Input | Output |
12
- | --- | --- | --- |
13
- | `search_codebase` | `query`, optional `intent`, `limit`, `filters` | Ranked results with enrichment. Preflight card when `intent` is `edit`/`refactor`/`migrate`. |
14
- | `get_team_patterns` | optional `category` | Pattern frequencies, trends, golden files, conflicts |
15
- | `get_component_usage` | `name` (import source) | Files importing the given package/module |
16
- | `remember` | `type`, `category`, `memory`, `reason` | Persists to `.codebase-context/memory.json` |
17
- | `get_memory` | optional `category`, `type`, `query`, `limit` | Memories with confidence decay scoring |
40
+ | Tool | Input | Output |
41
+ | ----------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
42
+ | `search_codebase` | `query`, optional `intent`, `limit`, `filters`, `includeSnippets` | Ranked results (`file`, `summary`, `score`, `type`, `trend`, `patternWarning`, `relationships`, `hints`) + `searchQuality` + decision card (`ready`, `nextAction`, `patterns`, `bestExample`, `impact`, `whatWouldHelp`) when `intent="edit"`. Hints capped at 3 per category. |
43
+ | `get_team_patterns` | optional `category` | Pattern frequencies, trends, golden files, conflicts |
44
+ | `get_symbol_references` | `symbol`, optional `limit` | Concrete symbol usage evidence: `usageCount` + top usage snippets + `confidence` + `isComplete`. `confidence: "syntactic"` means static/source-based only (no runtime or dynamic dispatch). Replaces the removed `get_component_usage`. |
45
+ | `remember` | `type`, `category`, `memory`, `reason` | Persists to `.codebase-context/memory.json` |
46
+ | `get_memory` | optional `category`, `type`, `query`, `limit` | Memories with confidence decay scoring |
18
47
 
19
48
  ### Utility Tools
20
49
 
21
- | Tool | Purpose |
22
- | --- | --- |
23
- | `get_codebase_metadata` | Framework, dependencies, project stats |
24
- | `get_style_guide` | Style rules from project documentation |
25
- | `detect_circular_dependencies` | Import cycles in the file graph |
26
- | `refresh_index` | Full or incremental re-index + git memory extraction |
27
- | `get_indexing_status` | Index state, progress, last stats |
50
+ | Tool | Purpose |
51
+ | ------------------------------ | ---------------------------------------------------- |
52
+ | `get_codebase_metadata` | Framework, dependencies, project stats |
53
+ | `get_style_guide` | Style rules from project documentation |
54
+ | `detect_circular_dependencies` | Import cycles in the file graph |
55
+ | `refresh_index` | Full or incremental re-index + git memory extraction |
56
+ | `get_indexing_status` | Index state, progress, last stats |
28
57
 
29
58
  ## Retrieval Pipeline
30
59
 
@@ -34,25 +63,71 @@ Ordered by execution:
34
63
  2. **Query expansion** — bounded domain term expansion for conceptual queries.
35
64
  3. **Dual retrieval** — keyword (Fuse.js) + semantic (local embeddings or OpenAI).
36
65
  4. **RRF fusion** — Reciprocal Rank Fusion (k=60) across all retrieval channels.
37
- 5. **Structure-aware boosting** — import centrality, composition root boost, path overlap, definition demotion for action queries.
38
- 6. **Contamination control** — test file filtering for non-test queries.
39
- 7. **File deduplication** — best chunk per file.
40
- 8. **Stage-2 reranking** — cross-encoder (`Xenova/ms-marco-MiniLM-L-6-v2`) triggers when the score between the top files are very close. CPU-only, top-10 bounded.
41
- 9. **Result enrichment** — pattern momentum (`trend`/`patternWarning`), relationships (`importedBy`/`imports`/`testedIn`/`lastModified`), related memories, search quality assessment.
42
-
43
- ## Preflight Card (Edit Intent)
44
-
45
- Returned when search `intent` is `edit`, `refactor`, or `migrate`:
46
-
47
- - `riskLevel`: low / medium / high (based on circular deps + impact breadth + failure memories)
48
- - `confidence`: fresh / aging / stale (based on index age)
49
- - `evidenceLock`: triangulated score (0-100) from code + patterns + memories, with `readyToEdit` boolean
50
- - `epistemicStress`: triggers (pattern conflicts, stale memories, thin evidence), abstain signal
51
- - `preferredPatterns` / `avoidPatterns`: from team pattern analysis with adoption % and trend
52
- - `goldenFiles`: top exemplar files by modern pattern density
53
- - `impactCandidates`: files importing the result files (from import graph)
54
- - `failureWarnings`: recent failure memories related to the query
55
- - `patternConflicts`: when two patterns in the same category are both > 20% adoption
66
+ 5. **Definition-first boost** — for EXACT_NAME intent, results matching the symbol name get +15% score boost (e.g., defining file ranks above using files).
67
+ 6. **Structure-aware boosting** — import centrality, composition root boost, path overlap, definition demotion for action queries.
68
+ 7. **Contamination control** — test file filtering for non-test queries.
69
+ 8. **File deduplication** — best chunk per file.
70
+ 9. **Symbol-level deduplication** — within each `symbolPath` group, keep only the highest-scoring chunk (prevents duplicate methods from same class clogging results).
71
+ 10. **Stage-2 reranking** — cross-encoder (`Xenova/ms-marco-MiniLM-L-6-v2`) triggers when the score between the top files are very close. CPU-only, top-10 bounded.
72
+ 11. **Result enrichment** — compact type (`componentType:layer`), pattern momentum (`trend` Rising/Declining only, Stable omitted), `patternWarning`, condensed relationships (`importedByCount`/`hasTests`), structured hints (capped callers/consumers/tests ranked by frequency), scope header for symbol-aware snippets (`// ClassName.methodName`), related memories (capped to 3), search quality assessment with `hint` when low confidence.
73
+
74
+ ### Defaults
75
+
76
+ - **Chunk size**: 50 lines, 0 overlap
77
+ - **Reranker trigger**: activates when top-3 results are within 0.08 score of each other
78
+ - **Embedding model**: Granite (`ibm-granite/granite-embedding-30m-english`, 8192 token context) via `@huggingface/transformers` v3
79
+ - **Vector DB**: LanceDB with cosine distance
80
+
81
+ ## Decision Card (Edit Intent)
82
+
83
+ Returned as `preflight` when search `intent` is `edit`, `refactor`, or `migrate`.
84
+
85
+ **Output shape:**
86
+
87
+ ```typescript
88
+ {
89
+ ready: boolean;
90
+ nextAction?: string; // Only when ready=false; what to search for next
91
+ warnings?: string[]; // Failure memories (capped at 3)
92
+ patterns?: {
93
+ do: string[]; // Top 3 preferred patterns with adoption %
94
+ avoid: string[]; // Top 3 declining patterns
95
+ };
96
+ bestExample?: string; // Top 1 golden file (path format)
97
+ impact?: {
98
+ coverage: string; // "X/Y callers in results"
99
+ files: string[]; // Top 3 impact candidates (files importing results)
100
+ };
101
+ whatWouldHelp?: string[]; // Concrete next steps (max 4) when ready=false
102
+ }
103
+ ```
104
+
105
+ **Fields explained:**
106
+
107
+ - `ready`: boolean, whether evidence is sufficient to proceed
108
+ - `nextAction`: actionable reason why `ready=false` (e.g., "2 of 5 callers missing")
109
+ - `warnings`: failure memories from team (auto-surfaces past mistakes)
110
+ - `patterns.do`: patterns the team is adopting, ranked by adoption %
111
+ - `patterns.avoid`: declining patterns, ranked by % (useful for migrations)
112
+ - `bestExample`: exemplar file for the area under edit
113
+ - `impact.coverage`: shows caller visibility ("3/5 callers in results" means 2 callers weren't searched yet)
114
+ - `impact.files`: which files import the results (helps find blind spots)
115
+ - `whatWouldHelp`: specific next searches, tool calls, or files to check that would close evidence gaps
116
+
117
+ ### How `ready` is determined
118
+
119
+ 1. **Evidence triangulation** — scores code match (45%), pattern alignment (30%), and memory support (25%). Needs combined score ≥ 40 to pass.
120
+ 2. **Epistemic stress check** — if pattern conflicts, stale memories, thin evidence, or low caller coverage are detected, `ready` is set to false.
121
+ 3. **Search quality gate** — if `searchQuality.status` is `low_confidence`, `ready` is forced to false regardless of evidence scores. This prevents the "confidently wrong" problem.
122
+
123
+ ### Internal signals (not in output, feed `ready` computation)
124
+
125
+ - Risk level from circular deps, impact breadth, and failure memories
126
+ - Preferred/avoid patterns from team pattern analysis
127
+ - Golden files ranked by pattern density
128
+ - Caller coverage from import graph (X of Y callers appearing in results)
129
+ - Pattern conflicts when two patterns in the same category are both > 20% adoption
130
+ - Confidence decay of related memories
56
131
 
57
132
  ## Memory System
58
133
 
@@ -60,16 +135,35 @@ Returned when search `intent` is `edit`, `refactor`, or `migrate`:
60
135
  - Confidence decay: conventions never decay, decisions 180-day half-life, gotchas/failures 90-day half-life
61
136
  - Stale threshold: memories below 30% confidence are flagged
62
137
  - Git auto-extraction: conventional commits from last 90 days
63
- - Surface locations: `search_codebase` results, `get_team_patterns` responses, preflight cards
138
+ - Surface locations: `search_codebase` results (as `relatedMemories`), `get_team_patterns` responses, preflight analysis
64
139
 
65
140
  ## Indexing
66
141
 
67
- - Initial: full scan → chunking → embedding → vector DB (LanceDB) + keyword index (Fuse.js)
142
+ - Initial: full scan → chunking (50 lines, 0 overlap) → embedding → vector DB (LanceDB) + keyword index (Fuse.js)
68
143
  - Incremental: SHA-256 manifest diffing, selective embed/delete, full intelligence regeneration
144
+ - Version gating: `index-meta.json` tracks format version; mismatches trigger automatic rebuild
145
+ - Crash-safe rebuilds: full rebuilds write to `.staging/` and swap atomically only on success
69
146
  - Auto-heal: corrupted index triggers automatic full re-index on next search
147
+ - Relationships sidecar: `relationships.json` contains file import graph and symbol export index
70
148
  - Storage: `.codebase-context/` directory (memory.json + generated files)
71
149
 
72
150
  ## Analyzers
73
151
 
74
152
  - **Angular**: signals, standalone components, control flow syntax, lifecycle hooks, DI patterns, component metadata
75
- - **Generic**: 30+ languages TypeScript, JavaScript, Python, Java, Kotlin, C/C++, C#, Go, Rust, PHP, Ruby, Swift, Scala, Shell, config/markup formats
153
+ - **Generic**: 30+ have indexing/retrieval coverage including PHP, Ruby, Swift, Scala, Shell, config/markup., 10 languages have full symbol extraction (Tree-sitter: TypeScript, JavaScript, Python, Java, Kotlin, C, C++, C#, Go, Rust).
154
+
155
+ Notes:
156
+
157
+ - Language detection covers common extensions including `.pyi`, `.kt`/`.kts`, `.cc`/`.cxx`, and config formats like `.toml`/`.xml`.
158
+ - When Tree-sitter grammars are present, the Generic analyzer uses AST-aligned chunking and scope-aware prefixes for symbol-aware snippets (with fallbacks).
159
+
160
+ ## Evaluation Harness
161
+
162
+ Reproducible evaluation is shipped as a CLI entrypoint backed by shared scoring/reporting code.
163
+
164
+ - **Command:** `npm run eval -- <codebaseA> <codebaseB>` (builds first, then runs `scripts/run-eval.mjs`)
165
+ - **Shared implementation:** `src/eval/harness.ts` + `src/eval/types.ts` (tests and CLI use the same scoring)
166
+ - **Frozen fixtures:**
167
+ - `tests/fixtures/eval-angular-spotify.json` (real-world)
168
+ - `tests/fixtures/eval-controlled.json` + `tests/fixtures/codebases/eval-controlled/` (offline controlled)
169
+ - **Reported metrics:** Top-1 accuracy, Top-3 recall, spec contamination rate, and a gate pass/fail
File without changes
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "codebase-context",
3
- "version": "1.6.1",
4
- "description": "Local-first MCP server that gives AI agents team context: patterns and conventions, memory to remember decisions and failures, preflight checks, and hybrid search with evidence quality scoring",
3
+ "version": "1.7.0",
4
+ "description": "Second brain for AI agents working on your codebase - team coding patterns detection, persistent memory, preflight checks, and hybrid search with evidence scoring. Local-first MCP server",
5
5
  "type": "module",
6
6
  "main": "./dist/lib.js",
7
7
  "types": "./dist/lib.d.ts",
@@ -36,6 +36,7 @@
36
36
  },
37
37
  "files": [
38
38
  "dist",
39
+ "grammars",
39
40
  "README.md",
40
41
  "LICENSE",
41
42
  "docs"
@@ -106,10 +107,11 @@
106
107
  "@typescript-eslint/typescript-estree": "^7.0.0",
107
108
  "fuse.js": "^7.0.0",
108
109
  "glob": "^10.3.10",
109
- "hono": "4.11.7",
110
+ "hono": "^4.11.10",
110
111
  "ignore": "^5.3.1",
111
112
  "typescript": "^5.3.3",
112
113
  "uuid": "^9.0.1",
114
+ "web-tree-sitter": "^0.25.10",
113
115
  "zod": "^4.3.4"
114
116
  },
115
117
  "devDependencies": {
@@ -119,18 +121,22 @@
119
121
  "@types/uuid": "^9.0.8",
120
122
  "@typescript-eslint/eslint-plugin": "^8.51.0",
121
123
  "@typescript-eslint/parser": "^8.51.0",
122
- "eslint": "^9.39.2",
124
+ "eslint": "^9.0.0",
123
125
  "eslint-config-prettier": "^10.1.8",
124
126
  "eslint-plugin-import": "^2.32.0",
125
127
  "globals": "^17.0.0",
126
128
  "prettier": "^3.7.4",
129
+ "tree-sitter-wasms": "^0.1.13",
127
130
  "tsx": "^4.21.0",
128
131
  "typescript-eslint": "^8.51.0",
129
132
  "vitest": "^4.0.16"
130
133
  },
131
134
  "scripts": {
132
135
  "preinstall": "npx only-allow pnpm",
136
+ "sync:grammars": "node scripts/sync-grammars.mjs",
137
+ "prebuild": "pnpm run sync:grammars",
133
138
  "build": "tsc",
139
+ "pretest": "pnpm run sync:grammars",
134
140
  "start": "node dist/index.js",
135
141
  "dev": "tsx src/index.ts",
136
142
  "watch": "tsc -w",
@@ -140,6 +146,7 @@
140
146
  "format": "prettier --write \"src/**/*.ts\"",
141
147
  "format:check": "prettier --check \"src/**/*.ts\"",
142
148
  "type-check": "tsc --noEmit",
143
- "mcp:inspect": "npx -y @modelcontextprotocol/inspector node dist/index.js ."
149
+ "mcp:inspect": "npx -y @modelcontextprotocol/inspector node dist/index.js .",
150
+ "eval": "pnpm run build && node scripts/run-eval.mjs"
144
151
  }
145
152
  }