codebase-context 1.6.2 → 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 (137) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +358 -282
  3. package/dist/analyzers/angular/index.d.ts.map +1 -1
  4. package/dist/analyzers/angular/index.js +7 -2
  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 +2 -0
  11. package/dist/cli.d.ts.map +1 -1
  12. package/dist/cli.js +240 -1
  13. package/dist/cli.js.map +1 -1
  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.map +1 -1
  23. package/dist/core/indexer.js +253 -14
  24. package/dist/core/indexer.js.map +1 -1
  25. package/dist/core/search.d.ts +1 -0
  26. package/dist/core/search.d.ts.map +1 -1
  27. package/dist/core/search.js +60 -5
  28. package/dist/core/search.js.map +1 -1
  29. package/dist/core/symbol-references.d.ts +21 -0
  30. package/dist/core/symbol-references.d.ts.map +1 -0
  31. package/dist/core/symbol-references.js +91 -0
  32. package/dist/core/symbol-references.js.map +1 -0
  33. package/dist/eval/harness.d.ts +5 -0
  34. package/dist/eval/harness.d.ts.map +1 -0
  35. package/dist/eval/harness.js +153 -0
  36. package/dist/eval/harness.js.map +1 -0
  37. package/dist/eval/types.d.ts +59 -0
  38. package/dist/eval/types.d.ts.map +1 -0
  39. package/dist/eval/types.js +2 -0
  40. package/dist/eval/types.js.map +1 -0
  41. package/dist/grammars/manifest.d.ts +26 -0
  42. package/dist/grammars/manifest.d.ts.map +1 -0
  43. package/dist/grammars/manifest.js +63 -0
  44. package/dist/grammars/manifest.js.map +1 -0
  45. package/dist/index.d.ts +12 -2
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +136 -1298
  48. package/dist/index.js.map +1 -1
  49. package/dist/preflight/evidence-lock.d.ts +6 -0
  50. package/dist/preflight/evidence-lock.d.ts.map +1 -1
  51. package/dist/preflight/evidence-lock.js +33 -1
  52. package/dist/preflight/evidence-lock.js.map +1 -1
  53. package/dist/storage/lancedb.d.ts +9 -1
  54. package/dist/storage/lancedb.d.ts.map +1 -1
  55. package/dist/storage/lancedb.js +26 -8
  56. package/dist/storage/lancedb.js.map +1 -1
  57. package/dist/tools/detect-circular-dependencies.d.ts +5 -0
  58. package/dist/tools/detect-circular-dependencies.d.ts.map +1 -0
  59. package/dist/tools/detect-circular-dependencies.js +117 -0
  60. package/dist/tools/detect-circular-dependencies.js.map +1 -0
  61. package/dist/tools/get-codebase-metadata.d.ts +5 -0
  62. package/dist/tools/get-codebase-metadata.d.ts.map +1 -0
  63. package/dist/tools/get-codebase-metadata.js +53 -0
  64. package/dist/tools/get-codebase-metadata.js.map +1 -0
  65. package/dist/tools/get-component-usage.d.ts +5 -0
  66. package/dist/tools/get-component-usage.d.ts.map +1 -0
  67. package/dist/tools/get-component-usage.js +83 -0
  68. package/dist/tools/get-component-usage.js.map +1 -0
  69. package/dist/tools/get-indexing-status.d.ts +5 -0
  70. package/dist/tools/get-indexing-status.d.ts.map +1 -0
  71. package/dist/tools/get-indexing-status.js +44 -0
  72. package/dist/tools/get-indexing-status.js.map +1 -0
  73. package/dist/tools/get-memory.d.ts +5 -0
  74. package/dist/tools/get-memory.d.ts.map +1 -0
  75. package/dist/tools/get-memory.js +89 -0
  76. package/dist/tools/get-memory.js.map +1 -0
  77. package/dist/tools/get-style-guide.d.ts +5 -0
  78. package/dist/tools/get-style-guide.d.ts.map +1 -0
  79. package/dist/tools/get-style-guide.js +151 -0
  80. package/dist/tools/get-style-guide.js.map +1 -0
  81. package/dist/tools/get-symbol-references.d.ts +5 -0
  82. package/dist/tools/get-symbol-references.d.ts.map +1 -0
  83. package/dist/tools/get-symbol-references.js +70 -0
  84. package/dist/tools/get-symbol-references.js.map +1 -0
  85. package/dist/tools/get-team-patterns.d.ts +5 -0
  86. package/dist/tools/get-team-patterns.d.ts.map +1 -0
  87. package/dist/tools/get-team-patterns.js +131 -0
  88. package/dist/tools/get-team-patterns.js.map +1 -0
  89. package/dist/tools/index.d.ts +6 -0
  90. package/dist/tools/index.d.ts.map +1 -0
  91. package/dist/tools/index.js +41 -0
  92. package/dist/tools/index.js.map +1 -0
  93. package/dist/tools/refresh-index.d.ts +5 -0
  94. package/dist/tools/refresh-index.d.ts.map +1 -0
  95. package/dist/tools/refresh-index.js +40 -0
  96. package/dist/tools/refresh-index.js.map +1 -0
  97. package/dist/tools/remember.d.ts +5 -0
  98. package/dist/tools/remember.d.ts.map +1 -0
  99. package/dist/tools/remember.js +101 -0
  100. package/dist/tools/remember.js.map +1 -0
  101. package/dist/tools/search-codebase.d.ts +5 -0
  102. package/dist/tools/search-codebase.d.ts.map +1 -0
  103. package/dist/tools/search-codebase.js +638 -0
  104. package/dist/tools/search-codebase.js.map +1 -0
  105. package/dist/tools/types.d.ts +31 -0
  106. package/dist/tools/types.d.ts.map +1 -0
  107. package/dist/tools/types.js +2 -0
  108. package/dist/tools/types.js.map +1 -0
  109. package/dist/types/index.d.ts +6 -0
  110. package/dist/types/index.d.ts.map +1 -1
  111. package/dist/utils/ast-chunker.d.ts +71 -0
  112. package/dist/utils/ast-chunker.d.ts.map +1 -0
  113. package/dist/utils/ast-chunker.js +453 -0
  114. package/dist/utils/ast-chunker.js.map +1 -0
  115. package/dist/utils/chunking.d.ts.map +1 -1
  116. package/dist/utils/chunking.js +10 -3
  117. package/dist/utils/chunking.js.map +1 -1
  118. package/dist/utils/language-detection.d.ts.map +1 -1
  119. package/dist/utils/language-detection.js +20 -0
  120. package/dist/utils/language-detection.js.map +1 -1
  121. package/dist/utils/tree-sitter.d.ts +17 -0
  122. package/dist/utils/tree-sitter.d.ts.map +1 -0
  123. package/dist/utils/tree-sitter.js +311 -0
  124. package/dist/utils/tree-sitter.js.map +1 -0
  125. package/docs/capabilities.md +169 -92
  126. package/grammars/.gitkeep +0 -0
  127. package/grammars/tree-sitter-c.wasm +0 -0
  128. package/grammars/tree-sitter-c_sharp.wasm +0 -0
  129. package/grammars/tree-sitter-cpp.wasm +0 -0
  130. package/grammars/tree-sitter-go.wasm +0 -0
  131. package/grammars/tree-sitter-java.wasm +0 -0
  132. package/grammars/tree-sitter-javascript.wasm +0 -0
  133. package/grammars/tree-sitter-python.wasm +0 -0
  134. package/grammars/tree-sitter-rust.wasm +0 -0
  135. package/grammars/tree-sitter-tsx.wasm +0 -0
  136. package/grammars/tree-sitter-typescript.wasm +0 -0
  137. package/package.json +151 -157
@@ -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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"}
@@ -1,92 +1,169 @@
1
- # Capabilities Reference
2
-
3
- Technical reference for what `codebase-context` ships today. For the user-facing overview, see [README.md](../README.md).
4
-
5
- ## Tool Surface
6
-
7
- 10 MCP tools + 1 optional resource (`codebase://context`).
8
-
9
- ### Core Tools
10
-
11
- | Tool | Input | Output |
12
- | --- | --- | --- |
13
- | `search_codebase` | `query`, optional `intent`, `limit`, `filters`, `includeSnippets` | Ranked results (`file`, `summary`, `score`, `type`, `trend`, `patternWarning`) + `searchQuality` (with `hint` when low confidence) + `preflight` ({ready, reason}). Snippets opt-in. |
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 |
18
-
19
- ### Utility Tools
20
-
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 |
28
-
29
- ## Retrieval Pipeline
30
-
31
- Ordered by execution:
32
-
33
- 1. **Intent classification** — EXACT_NAME (for symbols), CONCEPTUAL, FLOW, CONFIG, WIRING. Sets keyword/semantic weight ratio.
34
- 2. **Query expansion** — bounded domain term expansion for conceptual queries.
35
- 3. **Dual retrieval** — keyword (Fuse.js) + semantic (local embeddings or OpenAI).
36
- 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** compact type (`componentType:layer`), pattern momentum (`trend` Rising/Declining only, Stable omitted), `patternWarning`, condensed relationships (`importedByCount`/`hasTests`), related memories (capped to 3), search quality assessment with `hint` when low confidence.
42
-
43
- ### Defaults
44
-
45
- - **Chunk size**: 50 lines, 0 overlap
46
- - **Reranker trigger**: activates when top-3 results are within 0.08 score of each other
47
- - **Embedding model**: Granite (`ibm-granite/granite-embedding-30m-english`, 8192 token context) via `@huggingface/transformers` v3
48
- - **Vector DB**: LanceDB with cosine distance
49
-
50
- ## Preflight (Edit Intent)
51
-
52
- Returned as `preflight` when search `intent` is `edit`, `refactor`, or `migrate`. Also returned for default searches when intelligence is available.
53
-
54
- Output: `{ ready: boolean, reason?: string }`
55
-
56
- - `ready`: whether evidence is sufficient to proceed with edits
57
- - `reason`: when `ready` is false, explains why (e.g., "Search quality is low", "Insufficient pattern evidence")
58
-
59
- ### How `ready` is determined
60
-
61
- 1. **Evidence triangulation** — scores code match (45%), pattern alignment (30%), and memory support (25%). Needs combined score ≥ 40 to pass.
62
- 2. **Epistemic stress check** — if pattern conflicts, stale memories, or thin evidence are detected, `ready` is set to false with an abstain signal.
63
- 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 where evidence counts look good but retrieval quality is poor.
64
-
65
- ### Internal analysis (not in output, used to compute `ready`)
66
-
67
- - Risk level from circular deps + impact breadth + failure memories
68
- - Preferred/avoid patterns from team pattern analysis
69
- - Golden files by pattern density
70
- - Impact candidates from import graph
71
- - Failure warnings from related memories
72
- - Pattern conflicts when two patterns in the same category are both > 20% adoption
73
-
74
- ## Memory System
75
-
76
- - 4 types: `convention`, `decision`, `gotcha`, `failure`
77
- - Confidence decay: conventions never decay, decisions 180-day half-life, gotchas/failures 90-day half-life
78
- - Stale threshold: memories below 30% confidence are flagged
79
- - Git auto-extraction: conventional commits from last 90 days
80
- - Surface locations: `search_codebase` results (as `relatedMemories`), `get_team_patterns` responses, preflight analysis
81
-
82
- ## Indexing
83
-
84
- - Initial: full scan → chunking (50 lines, 0 overlap) → embedding → vector DB (LanceDB) + keyword index (Fuse.js)
85
- - Incremental: SHA-256 manifest diffing, selective embed/delete, full intelligence regeneration
86
- - Auto-heal: corrupted index triggers automatic full re-index on next search
87
- - Storage: `.codebase-context/` directory (memory.json + generated files)
88
-
89
- ## Analyzers
90
-
91
- - **Angular**: signals, standalone components, control flow syntax, lifecycle hooks, DI patterns, component metadata
92
- - **Generic**: 30+ languages — TypeScript, JavaScript, Python, Java, Kotlin, C/C++, C#, Go, Rust, PHP, Ruby, Swift, Scala, Shell, config/markup formats
1
+ # Capabilities Reference
2
+
3
+ Technical reference for what `codebase-context` ships today. For the user-facing overview, see [README.md](../README.md).
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
+
34
+ ## Tool Surface
35
+
36
+ 10 MCP tools + 1 optional resource (`codebase://context`). **Migration:** `get_component_usage` was removed; use `get_symbol_references` for symbol usage evidence.
37
+
38
+ ### Core Tools
39
+
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 |
47
+
48
+ ### Utility Tools
49
+
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 |
57
+
58
+ ## Retrieval Pipeline
59
+
60
+ Ordered by execution:
61
+
62
+ 1. **Intent classification** — EXACT_NAME (for symbols), CONCEPTUAL, FLOW, CONFIG, WIRING. Sets keyword/semantic weight ratio.
63
+ 2. **Query expansion** — bounded domain term expansion for conceptual queries.
64
+ 3. **Dual retrieval** — keyword (Fuse.js) + semantic (local embeddings or OpenAI).
65
+ 4. **RRF fusion** Reciprocal Rank Fusion (k=60) across all retrieval channels.
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
131
+
132
+ ## Memory System
133
+
134
+ - 4 types: `convention`, `decision`, `gotcha`, `failure`
135
+ - Confidence decay: conventions never decay, decisions 180-day half-life, gotchas/failures 90-day half-life
136
+ - Stale threshold: memories below 30% confidence are flagged
137
+ - Git auto-extraction: conventional commits from last 90 days
138
+ - Surface locations: `search_codebase` results (as `relatedMemories`), `get_team_patterns` responses, preflight analysis
139
+
140
+ ## Indexing
141
+
142
+ - Initial: full scan → chunking (50 lines, 0 overlap) → embedding → vector DB (LanceDB) + keyword index (Fuse.js)
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
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
148
+ - Storage: `.codebase-context/` directory (memory.json + generated files)
149
+
150
+ ## Analyzers
151
+
152
+ - **Angular**: signals, standalone components, control flow syntax, lifecycle hooks, DI patterns, component metadata
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