@danielblomma/cortex-mcp 2.2.1 → 2.2.3
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/package.json +2 -2
- package/scaffold/mcp/src/contextEntities.ts +30 -19
- package/scaffold/mcp/src/loadGraph.ts +254 -242
- package/scaffold/mcp/src/search.ts +18 -7
- package/scaffold/mcp/src/searchResults.ts +138 -94
- package/scaffold/mcp/tests/search-graph-score.test.mjs +74 -1
- package/scaffold/scripts/ingest.mjs +43 -4
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danielblomma/cortex-mcp",
|
|
3
3
|
"mcpName": "io.github.DanielBlomma/cortex",
|
|
4
|
-
"version": "2.2.
|
|
4
|
+
"version": "2.2.3",
|
|
5
5
|
"description": "Local, repo-scoped context platform for coding assistants. Semantic search, graph relationships, and architectural rule context.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"author": "Daniel Blomma",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
],
|
|
65
65
|
"scripts": {
|
|
66
66
|
"pretest": "test -d scaffold/scripts/parsers/node_modules || npm --prefix scaffold/scripts/parsers install --no-fund --no-update-notifier --silent",
|
|
67
|
-
"test": "node tests/context-regressions.test.mjs && node --test tests/ingest-units.test.mjs tests/ingest-parallel.test.mjs tests/ingest-worker-crash.test.mjs tests/javascript-parser.test.mjs tests/markdown-parser.test.mjs tests/sql-parser.test.mjs tests/config-parser.test.mjs tests/resources-parser.test.mjs tests/vbnet-parser.test.mjs tests/cpp-parser.test.mjs tests/dashboard.test.mjs tests/init-config.test.mjs tests/init-agents.test.mjs tests/multi-level.test.mjs tests/no-legacy-paths.test.mjs tests/tree-sitter-error-reporting.test.mjs tests/tree-sitter-body-cap.test.mjs tests/tree-sitter-exported.test.mjs tests/tree-sitter-robustness.test.mjs tests/bootstrapbench-stats.test.mjs tests/bootstrapbench-aggregate.test.mjs tests/bootstrapbench-cleanup.test.mjs tests/query-cli-shim.test.mjs",
|
|
67
|
+
"test": "node tests/context-regressions.test.mjs && node --test tests/ingest-units.test.mjs tests/ingest-parallel.test.mjs tests/ingest-worker-crash.test.mjs tests/javascript-parser.test.mjs tests/markdown-parser.test.mjs tests/sql-parser.test.mjs tests/config-parser.test.mjs tests/resources-parser.test.mjs tests/vbnet-parser.test.mjs tests/cpp-parser.test.mjs tests/dashboard.test.mjs tests/init-config.test.mjs tests/init-agents.test.mjs tests/multi-level.test.mjs tests/no-legacy-paths.test.mjs tests/tree-sitter-error-reporting.test.mjs tests/tree-sitter-body-cap.test.mjs tests/tree-sitter-exported.test.mjs tests/tree-sitter-robustness.test.mjs tests/bootstrapbench-run.test.mjs tests/bootstrapbench-stats.test.mjs tests/bootstrapbench-aggregate.test.mjs tests/bootstrapbench-cleanup.test.mjs tests/query-cli-shim.test.mjs",
|
|
68
68
|
"release:sync-version": "node scripts/sync-release-version.mjs",
|
|
69
69
|
"release:check-version-sync": "node scripts/sync-release-version.mjs --check",
|
|
70
70
|
"prepublishOnly": "echo 'Ready to publish to npm'"
|
|
@@ -75,8 +75,12 @@ function buildRelationSearchSignals(data: ContextData): Map<string, string> {
|
|
|
75
75
|
return new Map([...signalsByEntity.entries()].map(([id, parts]) => [id, parts.join("\n")]));
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
function buildSearchEntityIndexes(data: ContextData): {
|
|
79
|
+
fileRuleLinks: Map<string, string[]>;
|
|
80
|
+
relationSignals: Map<string, string>;
|
|
81
|
+
adrPathSet: Set<string>;
|
|
82
|
+
filePathById: Map<string, string>;
|
|
83
|
+
} {
|
|
80
84
|
const fileRuleLinks = groupRuleLinks(data.relations);
|
|
81
85
|
const relationSignals = buildRelationSearchSignals(data);
|
|
82
86
|
const adrPathSet = new Set(
|
|
@@ -84,6 +88,15 @@ export function buildSearchEntities(data: ContextData, includeContent: boolean):
|
|
|
84
88
|
.map((adr) => adr.path.trim().toLowerCase())
|
|
85
89
|
.filter((adrPath) => adrPath.length > 0)
|
|
86
90
|
);
|
|
91
|
+
const filePathById = new Map(
|
|
92
|
+
data.documents.filter((document) => document.kind === "CODE").map((document) => [document.id, document.path])
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
return { fileRuleLinks, relationSignals, adrPathSet, filePathById };
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function* iterateSearchEntities(data: ContextData, includeContent: boolean): Generator<SearchEntity> {
|
|
99
|
+
const { fileRuleLinks, relationSignals, adrPathSet, filePathById } = buildSearchEntityIndexes(data);
|
|
87
100
|
|
|
88
101
|
for (const document of data.documents) {
|
|
89
102
|
const normalizedPath = document.path.trim().toLowerCase();
|
|
@@ -91,7 +104,7 @@ export function buildSearchEntities(data: ContextData, includeContent: boolean):
|
|
|
91
104
|
continue;
|
|
92
105
|
}
|
|
93
106
|
|
|
94
|
-
|
|
107
|
+
yield {
|
|
95
108
|
id: document.id,
|
|
96
109
|
entity_type: "File",
|
|
97
110
|
kind: document.kind,
|
|
@@ -105,11 +118,11 @@ export function buildSearchEntities(data: ContextData, includeContent: boolean):
|
|
|
105
118
|
snippet: document.excerpt,
|
|
106
119
|
matched_rules: fileRuleLinks.get(document.id) ?? [],
|
|
107
120
|
content: includeContent ? document.content : undefined
|
|
108
|
-
}
|
|
121
|
+
};
|
|
109
122
|
}
|
|
110
123
|
|
|
111
124
|
for (const rule of data.rules) {
|
|
112
|
-
|
|
125
|
+
yield {
|
|
113
126
|
id: rule.id,
|
|
114
127
|
entity_type: "Rule",
|
|
115
128
|
kind: "RULE",
|
|
@@ -123,11 +136,11 @@ export function buildSearchEntities(data: ContextData, includeContent: boolean):
|
|
|
123
136
|
snippet: rule.body.slice(0, 500),
|
|
124
137
|
matched_rules: [rule.id],
|
|
125
138
|
content: includeContent ? rule.body : undefined
|
|
126
|
-
}
|
|
139
|
+
};
|
|
127
140
|
}
|
|
128
141
|
|
|
129
142
|
for (const adr of data.adrs) {
|
|
130
|
-
|
|
143
|
+
yield {
|
|
131
144
|
id: adr.id,
|
|
132
145
|
entity_type: "ADR",
|
|
133
146
|
kind: "ADR",
|
|
@@ -141,16 +154,12 @@ export function buildSearchEntities(data: ContextData, includeContent: boolean):
|
|
|
141
154
|
snippet: adr.body.slice(0, 500),
|
|
142
155
|
matched_rules: [],
|
|
143
156
|
content: includeContent ? adr.body : undefined
|
|
144
|
-
}
|
|
157
|
+
};
|
|
145
158
|
}
|
|
146
159
|
|
|
147
|
-
const filePathById = new Map(
|
|
148
|
-
data.documents.filter((document) => document.kind === "CODE").map((document) => [document.id, document.path])
|
|
149
|
-
);
|
|
150
|
-
|
|
151
160
|
for (const chunk of data.chunks) {
|
|
152
161
|
const filePath = filePathById.get(chunk.file_id) ?? "";
|
|
153
|
-
|
|
162
|
+
yield {
|
|
154
163
|
id: chunk.id,
|
|
155
164
|
entity_type: "Chunk",
|
|
156
165
|
kind: chunk.kind || "chunk",
|
|
@@ -164,11 +173,11 @@ export function buildSearchEntities(data: ContextData, includeContent: boolean):
|
|
|
164
173
|
snippet: chunk.description || chunk.body.slice(0, 500),
|
|
165
174
|
matched_rules: fileRuleLinks.get(chunk.file_id) ?? [],
|
|
166
175
|
content: includeContent ? chunk.body : undefined
|
|
167
|
-
}
|
|
176
|
+
};
|
|
168
177
|
}
|
|
169
178
|
|
|
170
179
|
for (const module of data.modules) {
|
|
171
|
-
|
|
180
|
+
yield {
|
|
172
181
|
id: module.id,
|
|
173
182
|
entity_type: "Module",
|
|
174
183
|
kind: "MODULE",
|
|
@@ -182,11 +191,11 @@ export function buildSearchEntities(data: ContextData, includeContent: boolean):
|
|
|
182
191
|
snippet: (module.summary || "").slice(0, 500),
|
|
183
192
|
matched_rules: [],
|
|
184
193
|
content: includeContent ? module.summary : undefined
|
|
185
|
-
}
|
|
194
|
+
};
|
|
186
195
|
}
|
|
187
196
|
|
|
188
197
|
for (const project of data.projects) {
|
|
189
|
-
|
|
198
|
+
yield {
|
|
190
199
|
id: project.id,
|
|
191
200
|
entity_type: "Project",
|
|
192
201
|
kind: project.kind.toUpperCase() || "PROJECT",
|
|
@@ -200,10 +209,12 @@ export function buildSearchEntities(data: ContextData, includeContent: boolean):
|
|
|
200
209
|
snippet: (project.summary || "").slice(0, 500),
|
|
201
210
|
matched_rules: [],
|
|
202
211
|
content: includeContent ? project.summary : undefined
|
|
203
|
-
}
|
|
212
|
+
};
|
|
204
213
|
}
|
|
214
|
+
}
|
|
205
215
|
|
|
206
|
-
|
|
216
|
+
export function buildSearchEntities(data: ContextData, includeContent: boolean): SearchEntity[] {
|
|
217
|
+
return Array.from(iterateSearchEntities(data, includeContent));
|
|
207
218
|
}
|
|
208
219
|
|
|
209
220
|
export function buildChunkPartOfRelations(data: ContextData): RelationRecord[] {
|