@danielblomma/cortex-mcp 0.4.5 → 0.6.5

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 (62) hide show
  1. package/README.md +38 -42
  2. package/bin/cortex.mjs +32 -60
  3. package/package.json +15 -3
  4. package/scaffold/.context/ontology.cypher +47 -0
  5. package/scaffold/.githooks/post-commit +14 -0
  6. package/scaffold/.githooks/post-rewrite +23 -0
  7. package/scaffold/mcp/package-lock.json +16 -16
  8. package/scaffold/mcp/package.json +4 -1
  9. package/scaffold/mcp/src/contextEntities.ts +311 -0
  10. package/scaffold/mcp/src/defaults.ts +6 -0
  11. package/scaffold/mcp/src/embed.ts +163 -37
  12. package/scaffold/mcp/src/frontmatter.ts +39 -0
  13. package/scaffold/mcp/src/graph.ts +253 -130
  14. package/scaffold/mcp/src/graphMetrics.ts +12 -0
  15. package/scaffold/mcp/src/impactPresentation.ts +202 -0
  16. package/scaffold/mcp/src/impactRanking.ts +237 -0
  17. package/scaffold/mcp/src/impactResponse.ts +47 -0
  18. package/scaffold/mcp/src/impactResults.ts +173 -0
  19. package/scaffold/mcp/src/impactSeed.ts +33 -0
  20. package/scaffold/mcp/src/impactTraversal.ts +83 -0
  21. package/scaffold/mcp/src/jsonl.ts +34 -0
  22. package/scaffold/mcp/src/loadGraph.ts +345 -86
  23. package/scaffold/mcp/src/paths.ts +17 -1
  24. package/scaffold/mcp/src/presets.ts +137 -0
  25. package/scaffold/mcp/src/relatedResponse.ts +30 -0
  26. package/scaffold/mcp/src/relatedTraversal.ts +101 -0
  27. package/scaffold/mcp/src/rules.ts +27 -0
  28. package/scaffold/mcp/src/search.ts +186 -455
  29. package/scaffold/mcp/src/searchCore.ts +274 -0
  30. package/scaffold/mcp/src/searchResults.ts +133 -0
  31. package/scaffold/mcp/src/server.ts +95 -3
  32. package/scaffold/mcp/src/types.ts +82 -3
  33. package/scaffold/scripts/context.sh +12 -46
  34. package/scaffold/scripts/dashboard.mjs +797 -0
  35. package/scaffold/scripts/dashboard.sh +13 -0
  36. package/scaffold/scripts/ingest.mjs +2227 -59
  37. package/scaffold/scripts/install-git-hooks.sh +3 -1
  38. package/scaffold/scripts/memory-compile.mjs +232 -0
  39. package/scaffold/scripts/memory-compile.sh +20 -0
  40. package/scaffold/scripts/memory-lint.mjs +375 -0
  41. package/scaffold/scripts/memory-lint.sh +20 -0
  42. package/scaffold/scripts/parsers/config.mjs +178 -0
  43. package/scaffold/scripts/parsers/cpp.mjs +316 -0
  44. package/scaffold/scripts/parsers/dotnet/VbNetParser/Program.cs +374 -0
  45. package/scaffold/scripts/parsers/dotnet/VbNetParser/VbNetParser.csproj +13 -0
  46. package/scaffold/scripts/parsers/javascript/ast.mjs +61 -0
  47. package/scaffold/scripts/parsers/javascript/calls.mjs +53 -0
  48. package/scaffold/scripts/parsers/javascript/chunks.mjs +388 -0
  49. package/scaffold/scripts/parsers/javascript/imports.mjs +162 -0
  50. package/scaffold/scripts/parsers/javascript/patterns.mjs +82 -0
  51. package/scaffold/scripts/parsers/javascript/scope-analysis.mjs +3 -0
  52. package/scaffold/scripts/parsers/javascript/scope-builder.mjs +305 -0
  53. package/scaffold/scripts/parsers/javascript/scope-resolver.mjs +82 -0
  54. package/scaffold/scripts/parsers/javascript.mjs +27 -350
  55. package/scaffold/scripts/parsers/resources.mjs +166 -0
  56. package/scaffold/scripts/parsers/rust.mjs +515 -0
  57. package/scaffold/scripts/parsers/sql.mjs +137 -0
  58. package/scaffold/scripts/parsers/vbnet.mjs +143 -0
  59. package/scaffold/scripts/status.sh +0 -7
  60. package/scaffold/scripts/capture-note.sh +0 -55
  61. package/scaffold/scripts/plan-state-engine.cjs +0 -310
  62. package/scaffold/scripts/plan-state.sh +0 -71
@@ -0,0 +1,374 @@
1
+ using System.Text.Json;
2
+ using Microsoft.CodeAnalysis;
3
+ using Microsoft.CodeAnalysis.Text;
4
+ using Microsoft.CodeAnalysis.VisualBasic;
5
+ using Microsoft.CodeAnalysis.VisualBasic.Syntax;
6
+
7
+ var options = ParseArgs(args);
8
+ if (string.IsNullOrWhiteSpace(options.FilePath))
9
+ {
10
+ Console.Error.WriteLine("Missing required --file argument.");
11
+ Environment.Exit(1);
12
+ }
13
+
14
+ var source = options.UseStdin
15
+ ? Console.In.ReadToEnd()
16
+ : File.ReadAllText(options.FilePath);
17
+
18
+ var parseResult = ParseVisualBasic(source, options.FilePath, options.Language);
19
+ var json = JsonSerializer.Serialize(parseResult, new JsonSerializerOptions
20
+ {
21
+ PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
22
+ WriteIndented = false
23
+ });
24
+
25
+ Console.WriteLine(json);
26
+
27
+ return;
28
+
29
+ static ParseOptions ParseArgs(string[] args)
30
+ {
31
+ var options = new ParseOptions();
32
+ for (var index = 0; index < args.Length; index += 1)
33
+ {
34
+ var arg = args[index];
35
+ switch (arg)
36
+ {
37
+ case "--stdin":
38
+ options.UseStdin = true;
39
+ break;
40
+ case "--file":
41
+ if (index + 1 < args.Length)
42
+ {
43
+ options.FilePath = args[++index];
44
+ }
45
+ break;
46
+ case "--language":
47
+ if (index + 1 < args.Length)
48
+ {
49
+ options.Language = args[++index];
50
+ }
51
+ break;
52
+ }
53
+ }
54
+
55
+ return options;
56
+ }
57
+
58
+ static ParserOutput ParseVisualBasic(string source, string filePath, string language)
59
+ {
60
+ var tree = VisualBasicSyntaxTree.ParseText(SourceText.From(source), path: filePath);
61
+ var root = tree.GetCompilationUnitRoot();
62
+ var diagnostics = tree.GetDiagnostics()
63
+ .Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)
64
+ .Select(diagnostic => new ParserError(
65
+ diagnostic.GetMessage(),
66
+ diagnostic.Location.GetLineSpan().StartLinePosition.Line + 1,
67
+ diagnostic.Location.GetLineSpan().StartLinePosition.Character + 1
68
+ ))
69
+ .ToList();
70
+
71
+ if (diagnostics.Count > 0)
72
+ {
73
+ return new ParserOutput(new List<ChunkOutput>(), diagnostics);
74
+ }
75
+
76
+ var collector = new VbChunkCollector(tree, root, source, language);
77
+ return new ParserOutput(collector.Collect(), diagnostics);
78
+ }
79
+
80
+ sealed class VbChunkCollector
81
+ {
82
+ private readonly SyntaxTree _tree;
83
+ private readonly CompilationUnitSyntax _root;
84
+ private readonly string _source;
85
+ private readonly string _language;
86
+ private readonly string[] _imports;
87
+
88
+ public VbChunkCollector(SyntaxTree tree, CompilationUnitSyntax root, string source, string language)
89
+ {
90
+ _tree = tree;
91
+ _root = root;
92
+ _source = source;
93
+ _language = language;
94
+ _imports = root.Imports
95
+ .SelectMany(importStatement => importStatement.ImportsClauses)
96
+ .Select(GetImportName)
97
+ .Where(name => !string.IsNullOrWhiteSpace(name))
98
+ .Distinct(StringComparer.Ordinal)
99
+ .ToArray();
100
+ }
101
+
102
+ public List<ChunkOutput> Collect()
103
+ {
104
+ var chunks = new List<ChunkOutput>();
105
+
106
+ foreach (var declaration in _root.Members)
107
+ {
108
+ CollectMember(chunks, declaration, null);
109
+ }
110
+
111
+ return chunks;
112
+ }
113
+
114
+ private void CollectMember(List<ChunkOutput> chunks, StatementSyntax member, string? parentName)
115
+ {
116
+ switch (member)
117
+ {
118
+ case NamespaceBlockSyntax namespaceBlock:
119
+ foreach (var nested in namespaceBlock.Members)
120
+ {
121
+ CollectMember(chunks, nested, parentName);
122
+ }
123
+ break;
124
+
125
+ case ClassBlockSyntax classBlock:
126
+ AddTypeChunk(chunks, classBlock.ClassStatement.Identifier.Text, "class", classBlock, parentName);
127
+ foreach (var nested in classBlock.Members)
128
+ {
129
+ CollectTypeMember(chunks, nested, classBlock.ClassStatement.Identifier.Text);
130
+ }
131
+ break;
132
+
133
+ case ModuleBlockSyntax moduleBlock:
134
+ AddTypeChunk(chunks, moduleBlock.ModuleStatement.Identifier.Text, "module", moduleBlock, parentName);
135
+ foreach (var nested in moduleBlock.Members)
136
+ {
137
+ CollectTypeMember(chunks, nested, moduleBlock.ModuleStatement.Identifier.Text);
138
+ }
139
+ break;
140
+
141
+ case StructureBlockSyntax structureBlock:
142
+ AddTypeChunk(chunks, structureBlock.StructureStatement.Identifier.Text, "structure", structureBlock, parentName);
143
+ foreach (var nested in structureBlock.Members)
144
+ {
145
+ CollectTypeMember(chunks, nested, structureBlock.StructureStatement.Identifier.Text);
146
+ }
147
+ break;
148
+
149
+ case InterfaceBlockSyntax interfaceBlock:
150
+ AddTypeChunk(chunks, interfaceBlock.InterfaceStatement.Identifier.Text, "interface", interfaceBlock, parentName);
151
+ break;
152
+ }
153
+ }
154
+
155
+ private void CollectTypeMember(List<ChunkOutput> chunks, StatementSyntax member, string parentTypeName)
156
+ {
157
+ switch (member)
158
+ {
159
+ case MethodBlockSyntax methodBlock:
160
+ AddMethodChunk(chunks, methodBlock, parentTypeName);
161
+ break;
162
+ case ConstructorBlockSyntax constructorBlock:
163
+ AddConstructorChunk(chunks, constructorBlock, parentTypeName);
164
+ break;
165
+ case PropertyBlockSyntax propertyBlock:
166
+ AddPropertyChunk(chunks, propertyBlock, parentTypeName);
167
+ break;
168
+ case PropertyStatementSyntax propertyStatement:
169
+ AddSimplePropertyChunk(chunks, propertyStatement, parentTypeName);
170
+ break;
171
+ case EventBlockSyntax eventBlock:
172
+ AddTypeChunk(chunks, $"{parentTypeName}.{eventBlock.EventStatement.Identifier.Text}", "event", eventBlock, null);
173
+ break;
174
+ case FieldDeclarationSyntax fieldDeclaration:
175
+ foreach (var declarator in fieldDeclaration.Declarators)
176
+ {
177
+ foreach (var name in declarator.Names)
178
+ {
179
+ AddTypeChunk(chunks, $"{parentTypeName}.{name.Identifier.Text}", "field", fieldDeclaration, null);
180
+ }
181
+ }
182
+ break;
183
+ case ClassBlockSyntax nestedClass:
184
+ AddTypeChunk(chunks, $"{parentTypeName}.{nestedClass.ClassStatement.Identifier.Text}", "class", nestedClass, null);
185
+ foreach (var nested in nestedClass.Members)
186
+ {
187
+ CollectTypeMember(chunks, nested, nestedClass.ClassStatement.Identifier.Text);
188
+ }
189
+ break;
190
+ }
191
+ }
192
+
193
+ private void AddTypeChunk(List<ChunkOutput> chunks, string name, string kind, SyntaxNode node, string? parentName)
194
+ {
195
+ chunks.Add(BuildChunk(
196
+ parentName is null ? name : $"{parentName}.{name}",
197
+ kind,
198
+ BuildSignature(kind, name, node),
199
+ node,
200
+ GetCalls(node),
201
+ _imports,
202
+ IsExported(node)
203
+ ));
204
+ }
205
+
206
+ private void AddMethodChunk(List<ChunkOutput> chunks, MethodBlockSyntax node, string parentTypeName)
207
+ {
208
+ var statement = node.BlockStatement;
209
+ var name = $"{parentTypeName}.{statement.Identifier.Text}";
210
+ var kind = statement.Kind() == SyntaxKind.SubStatement ? "method" : "function";
211
+ chunks.Add(BuildChunk(
212
+ name,
213
+ kind,
214
+ statement.ToString(),
215
+ node,
216
+ GetCalls(node),
217
+ _imports,
218
+ IsExported(statement)
219
+ ));
220
+ }
221
+
222
+ private void AddConstructorChunk(List<ChunkOutput> chunks, ConstructorBlockSyntax node, string parentTypeName)
223
+ {
224
+ chunks.Add(BuildChunk(
225
+ $"{parentTypeName}.New",
226
+ "constructor",
227
+ node.BlockStatement.ToString(),
228
+ node,
229
+ GetCalls(node),
230
+ _imports,
231
+ IsExported(node.BlockStatement)
232
+ ));
233
+ }
234
+
235
+ private void AddPropertyChunk(List<ChunkOutput> chunks, PropertyBlockSyntax node, string parentTypeName)
236
+ {
237
+ chunks.Add(BuildChunk(
238
+ $"{parentTypeName}.{node.PropertyStatement.Identifier.Text}",
239
+ "property",
240
+ node.PropertyStatement.ToString(),
241
+ node,
242
+ GetCalls(node),
243
+ _imports,
244
+ IsExported(node.PropertyStatement)
245
+ ));
246
+ }
247
+
248
+ private void AddSimplePropertyChunk(List<ChunkOutput> chunks, PropertyStatementSyntax node, string parentTypeName)
249
+ {
250
+ chunks.Add(BuildChunk(
251
+ $"{parentTypeName}.{node.Identifier.Text}",
252
+ "property",
253
+ node.ToString(),
254
+ node,
255
+ Array.Empty<string>(),
256
+ _imports,
257
+ IsExported(node)
258
+ ));
259
+ }
260
+
261
+ private ChunkOutput BuildChunk(
262
+ string name,
263
+ string kind,
264
+ string signature,
265
+ SyntaxNode node,
266
+ IReadOnlyCollection<string> calls,
267
+ IReadOnlyCollection<string> imports,
268
+ bool exported)
269
+ {
270
+ var span = node.GetLocation().GetLineSpan();
271
+ return new ChunkOutput(
272
+ name,
273
+ kind,
274
+ signature,
275
+ node.ToFullString(),
276
+ span.StartLinePosition.Line + 1,
277
+ span.EndLinePosition.Line + 1,
278
+ _language,
279
+ exported,
280
+ calls.ToArray(),
281
+ imports.ToArray()
282
+ );
283
+ }
284
+
285
+ private static string BuildSignature(string kind, string name, SyntaxNode node)
286
+ {
287
+ return node switch
288
+ {
289
+ ClassBlockSyntax classBlock => classBlock.ClassStatement.ToString(),
290
+ ModuleBlockSyntax moduleBlock => moduleBlock.ModuleStatement.ToString(),
291
+ StructureBlockSyntax structureBlock => structureBlock.StructureStatement.ToString(),
292
+ InterfaceBlockSyntax interfaceBlock => interfaceBlock.InterfaceStatement.ToString(),
293
+ _ => $"{kind} {name}"
294
+ };
295
+ }
296
+
297
+ private static string GetImportName(ImportsClauseSyntax clause)
298
+ {
299
+ return clause switch
300
+ {
301
+ SimpleImportsClauseSyntax simpleClause => simpleClause.Name.ToString(),
302
+ XmlNamespaceImportsClauseSyntax xmlClause => xmlClause.XmlNamespace.ToString(),
303
+ AliasImportsClauseSyntax aliasClause => aliasClause.Name.ToString(),
304
+ _ => clause.ToString()
305
+ };
306
+ }
307
+
308
+ private static bool IsExported(SyntaxNode node)
309
+ {
310
+ SyntaxTokenList modifiers = node switch
311
+ {
312
+ TypeStatementSyntax typeStatement => typeStatement.Modifiers,
313
+ MethodStatementSyntax methodStatement => methodStatement.Modifiers,
314
+ PropertyStatementSyntax propertyStatement => propertyStatement.Modifiers,
315
+ EventStatementSyntax eventStatement => eventStatement.Modifiers,
316
+ FieldDeclarationSyntax fieldDeclaration => fieldDeclaration.Modifiers,
317
+ _ => default
318
+ };
319
+
320
+ if (modifiers.Count == 0)
321
+ {
322
+ return false;
323
+ }
324
+
325
+ return modifiers.Any(modifier => modifier.IsKind(SyntaxKind.PublicKeyword));
326
+ }
327
+
328
+ private static IReadOnlyCollection<string> GetCalls(SyntaxNode node)
329
+ {
330
+ return node.DescendantNodes()
331
+ .OfType<InvocationExpressionSyntax>()
332
+ .Select(invocation => invocation.Expression)
333
+ .Select(GetInvocationName)
334
+ .Where(name => !string.IsNullOrWhiteSpace(name))
335
+ .Distinct(StringComparer.Ordinal)
336
+ .ToArray();
337
+ }
338
+
339
+ private static string? GetInvocationName(ExpressionSyntax expression)
340
+ {
341
+ return expression switch
342
+ {
343
+ IdentifierNameSyntax identifier => identifier.Identifier.Text,
344
+ GenericNameSyntax genericName => genericName.Identifier.Text,
345
+ MemberAccessExpressionSyntax memberAccess => memberAccess.Name.Identifier.Text,
346
+ InvocationExpressionSyntax nestedInvocation => GetInvocationName(nestedInvocation.Expression),
347
+ _ => null
348
+ };
349
+ }
350
+ }
351
+
352
+ sealed record ParseOptions
353
+ {
354
+ public bool UseStdin { get; set; }
355
+ public string FilePath { get; set; } = "";
356
+ public string Language { get; set; } = "vbnet";
357
+ }
358
+
359
+ sealed record ChunkOutput(
360
+ string Name,
361
+ string Kind,
362
+ string Signature,
363
+ string Body,
364
+ int StartLine,
365
+ int EndLine,
366
+ string Language,
367
+ bool Exported,
368
+ string[] Calls,
369
+ string[] Imports
370
+ );
371
+
372
+ sealed record ParserError(string Message, int Line, int Column);
373
+
374
+ sealed record ParserOutput(List<ChunkOutput> Chunks, List<ParserError> Errors);
@@ -0,0 +1,13 @@
1
+ <Project Sdk="Microsoft.NET.Sdk">
2
+ <PropertyGroup>
3
+ <OutputType>Exe</OutputType>
4
+ <TargetFramework>net8.0</TargetFramework>
5
+ <ImplicitUsings>enable</ImplicitUsings>
6
+ <Nullable>enable</Nullable>
7
+ <LangVersion>latest</LangVersion>
8
+ </PropertyGroup>
9
+
10
+ <ItemGroup>
11
+ <PackageReference Include="Microsoft.CodeAnalysis.VisualBasic" Version="4.11.0" />
12
+ </ItemGroup>
13
+ </Project>
@@ -0,0 +1,61 @@
1
+ import { Parser } from "acorn";
2
+ import tsPlugin from "acorn-typescript";
3
+ import { base } from "acorn-walk";
4
+
5
+ const tsNodeHandlers = {
6
+ TSAsExpression(node, st, visit) { visit(node.expression, st); },
7
+ TSTypeAnnotation() {},
8
+ TSTypeParameterInstantiation() {},
9
+ TSTypeParameterDeclaration() {},
10
+ TSTypeReference() {},
11
+ TSInterfaceDeclaration() {},
12
+ TSTypeAliasDeclaration() {},
13
+ TSEnumDeclaration() {},
14
+ TSModuleDeclaration() {},
15
+ TSDeclareFunction() {},
16
+ TSPropertySignature() {},
17
+ TSMethodSignature() {},
18
+ TSIndexSignature() {},
19
+ TSTypeLiteral() {},
20
+ TSUnionType() {},
21
+ TSIntersectionType() {},
22
+ TSArrayType() {},
23
+ TSTupleType() {},
24
+ TSOptionalType() {},
25
+ TSRestType() {},
26
+ TSFunctionType() {},
27
+ TSConstructorType() {},
28
+ TSNonNullExpression(node, st, visit) { visit(node.expression, st); },
29
+ TSInstantiationExpression(node, st, visit) { visit(node.expression, st); }
30
+ };
31
+
32
+ Object.assign(base, tsNodeHandlers);
33
+
34
+ export const WALK_BASE = base;
35
+
36
+ export function parseAst(code) {
37
+ try {
38
+ const TSParser = Parser.extend(tsPlugin());
39
+ const ast = TSParser.parse(code, {
40
+ ecmaVersion: "latest",
41
+ sourceType: "module",
42
+ locations: true,
43
+ allowHashBang: true,
44
+ allowImportExportEverywhere: true,
45
+ allowAwaitOutsideFunction: true
46
+ });
47
+
48
+ return { ast, errors: [] };
49
+ } catch (error) {
50
+ return {
51
+ ast: null,
52
+ errors: [
53
+ {
54
+ message: `Parse error: ${error.message}`,
55
+ line: error.loc?.line,
56
+ column: error.loc?.column
57
+ }
58
+ ]
59
+ };
60
+ }
61
+ }
@@ -0,0 +1,53 @@
1
+ import { simple as walkSimple } from "acorn-walk";
2
+
3
+ import { WALK_BASE } from "./ast.mjs";
4
+
5
+ export function extractCalls(bodyNode) {
6
+ if (!bodyNode) {
7
+ return [];
8
+ }
9
+
10
+ const calls = new Set();
11
+
12
+ try {
13
+ walkSimple(
14
+ bodyNode,
15
+ {
16
+ CallExpression(node) {
17
+ const callee = node.callee;
18
+
19
+ if (callee.type === "Identifier") {
20
+ calls.add(callee.name);
21
+ return;
22
+ }
23
+
24
+ if (callee.type === "MemberExpression" && callee.property.type === "Identifier") {
25
+ const objectName = getObjectName(callee.object);
26
+ calls.add(objectName ? `${objectName}.${callee.property.name}` : callee.property.name);
27
+ }
28
+ }
29
+ },
30
+ WALK_BASE
31
+ );
32
+ } catch (error) {
33
+ // Ignore walk errors for incomplete ASTs.
34
+ }
35
+
36
+ return [...calls].sort();
37
+ }
38
+
39
+ function getObjectName(node) {
40
+ if (node.type === "Identifier") {
41
+ return node.name;
42
+ }
43
+
44
+ if (node.type === "ThisExpression") {
45
+ return "this";
46
+ }
47
+
48
+ if (node.type === "MemberExpression" && node.property.type === "Identifier") {
49
+ return node.property.name;
50
+ }
51
+
52
+ return null;
53
+ }