code-graph-context 2.4.1 → 2.4.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/dist/cli/cli.js CHANGED
@@ -246,7 +246,7 @@ program
246
246
  .option('-p, --port <port>', 'Neo4j Bolt port', '7687')
247
247
  .option('--http-port <port>', 'Neo4j Browser port', '7474')
248
248
  .option('--password <password>', 'Neo4j password', 'PASSWORD')
249
- .option('-m, --memory <size>', 'Max heap memory (e.g., 2G, 4G)', '2G')
249
+ .option('-m, --memory <size>', 'Max heap memory (e.g., 2G, 4G)', '4G')
250
250
  .option('-f, --force', 'Recreate container even if exists')
251
251
  .action(runInit);
252
252
  program.command('status').description('Check Neo4j and Docker status').action(runStatus);
@@ -434,7 +434,8 @@ export const NESTJS_FRAMEWORK_SCHEMA = {
434
434
  },
435
435
  {
436
436
  type: 'function',
437
- pattern: (parsedNode) => parsedNode.sourceNode?.getName()?.endsWith('Service'),
437
+ // Use pre-extracted name property (works after AST cleanup in streaming/chunking)
438
+ pattern: (parsedNode) => parsedNode.properties?.name?.endsWith('Service'),
438
439
  confidence: 0.7,
439
440
  priority: 7,
440
441
  },
@@ -516,13 +517,11 @@ export const NESTJS_FRAMEWORK_SCHEMA = {
516
517
  detectionPatterns: [
517
518
  {
518
519
  type: 'function',
520
+ // Use pre-extracted decoratorNames from context (works after AST cleanup in streaming/chunking)
519
521
  pattern: (parsedNode) => {
520
- const node = parsedNode.sourceNode;
521
- if (!node)
522
- return false;
523
- const decorators = node.getDecorators?.() ?? [];
522
+ const decoratorNames = parsedNode.properties?.context?.decoratorNames ?? [];
524
523
  const messageDecorators = ['MessagePattern', 'EventPattern'];
525
- return decorators.some((d) => messageDecorators.includes(d.getName()));
524
+ return messageDecorators.some((d) => decoratorNames.includes(d));
526
525
  },
527
526
  confidence: 0.98,
528
527
  priority: 15,
@@ -570,13 +569,11 @@ export const NESTJS_FRAMEWORK_SCHEMA = {
570
569
  detectionPatterns: [
571
570
  {
572
571
  type: 'function',
572
+ // Use pre-extracted decoratorNames from context (works after AST cleanup in streaming/chunking)
573
573
  pattern: (parsedNode) => {
574
- const node = parsedNode.sourceNode;
575
- if (!node)
576
- return false;
577
- const decorators = node.getDecorators?.() ?? [];
574
+ const decoratorNames = parsedNode.properties?.context?.decoratorNames ?? [];
578
575
  const httpDecorators = ['Get', 'Post', 'Put', 'Delete', 'Patch', 'Head', 'Options'];
579
- return decorators.some((d) => httpDecorators.includes(d.getName()));
576
+ return httpDecorators.some((d) => decoratorNames.includes(d));
580
577
  },
581
578
  confidence: 0.98,
582
579
  priority: 15,
@@ -729,16 +726,11 @@ export const NESTJS_FRAMEWORK_SCHEMA = {
729
726
  if (parsedSourceNode.properties?.filePath !== parsedTargetNode.properties?.filePath) {
730
727
  return false;
731
728
  }
732
- // Access AST nodes to check parent relationship
733
- const sourceNode = parsedSourceNode.sourceNode;
734
- const targetNode = parsedTargetNode.sourceNode;
735
- if (sourceNode && targetNode) {
736
- const methodParent = targetNode.getParent();
737
- if (methodParent === sourceNode) {
738
- return true;
739
- }
740
- }
741
- return false;
729
+ // CRITICAL FIX: Use pre-extracted parentClassName property (works after AST cleanup in streaming/chunking)
730
+ // The method's parentClassName should match the controller's name
731
+ const targetParentClassName = parsedTargetNode.properties?.parentClassName;
732
+ const sourceName = parsedSourceNode.properties?.name;
733
+ return !!targetParentClassName && targetParentClassName === sourceName;
742
734
  },
743
735
  contextExtractor: (parsedSourceNode, parsedTargetNode) => ({
744
736
  endpointType: 'RPC',
@@ -761,16 +753,11 @@ export const NESTJS_FRAMEWORK_SCHEMA = {
761
753
  if (parsedSourceNode.properties?.filePath !== parsedTargetNode.properties?.filePath) {
762
754
  return false;
763
755
  }
764
- // Access AST nodes to check parent relationship
765
- const sourceNode = parsedSourceNode.sourceNode;
766
- const targetNode = parsedTargetNode.sourceNode;
767
- if (sourceNode && targetNode) {
768
- const methodParent = targetNode.getParent();
769
- if (methodParent === sourceNode) {
770
- return true;
771
- }
772
- }
773
- return false;
756
+ // CRITICAL FIX: Use pre-extracted parentClassName property (works after AST cleanup in streaming/chunking)
757
+ // The method's parentClassName should match the controller's name
758
+ const targetParentClassName = parsedTargetNode.properties?.parentClassName;
759
+ const sourceName = parsedSourceNode.properties?.name;
760
+ return !!targetParentClassName && targetParentClassName === sourceName;
774
761
  },
775
762
  contextExtractor: (parsedSourceNode, parsedTargetNode) => ({
776
763
  httpMethod: parsedTargetNode.properties?.context?.httpMethod ?? '',
@@ -20,12 +20,12 @@ Check rawSchema keys for ALL valid labels. Labels fall into two categories:
20
20
  SourceFile, Class, Function, Method, Interface, Property, Parameter, Constructor, Import, Export, Decorator, Enum, Variable, TypeAlias
21
21
 
22
22
  2. FRAMEWORK LABELS (from framework enhancements - check rawSchema keys):
23
- These REPLACE the core label for enhanced nodes. Examples: Service, Controller, Module, Entity, DTO, Repository, HttpEndpoint, MessageHandler
24
- A node with label "Service" was originally a Class but got enhanced - use the framework label.
23
+ These REPLACE the core label for enhanced nodes. Check rawSchema keys for available framework labels in this project.
24
+ A node with a framework label was originally a Class but got enhanced - always use the actual label from rawSchema.
25
25
 
26
26
  === AST TYPE NAME MAPPING ===
27
27
  AST type names are NOT valid labels. Always map them:
28
- - ClassDeclaration → Class (or framework label: Service, Controller, etc.)
28
+ - ClassDeclaration → Class (or a framework label from rawSchema if enhanced)
29
29
  - FunctionDeclaration → Function
30
30
  - MethodDeclaration → Method
31
31
  - InterfaceDeclaration → Interface
@@ -33,15 +33,15 @@ AST type names are NOT valid labels. Always map them:
33
33
  - ParameterDeclaration → Parameter
34
34
 
35
35
  === FINDING SPECIFIC NODES ===
36
- Class/service names are property values, NOT labels:
37
- WRONG: (n:DbService), (n:UserController) - class names as labels
38
- CORRECT: (n:Service {name: 'DbService'}), (n:Controller {name: 'UserController'})
39
- CORRECT: (n:Class {name: 'SomeClass'}) - if no framework enhancement
36
+ Class/entity names are property values, NOT labels:
37
+ WRONG: (n:MyClassName) - using class names as labels
38
+ CORRECT: (n:Class {name: 'MyClassName'}) - use label from rawSchema, name as property
39
+ CORRECT: (n:LabelFromSchema {name: 'EntityName'}) - always check rawSchema for valid labels
40
40
 
41
41
  Examples:
42
42
  - "Count all classes" -> MATCH (n:Class) WHERE n.projectId = $projectId RETURN count(n)
43
- - "Find DbService" -> MATCH (n:Service {name: 'DbService'}) WHERE n.projectId = $projectId RETURN n
44
- - "Methods in UserController" -> MATCH (c:Controller {name: 'UserController'})-[:HAS_MEMBER]->(m:Method) WHERE c.projectId = $projectId RETURN m
43
+ - "Find class by name" -> MATCH (n:Class {name: 'ClassName'}) WHERE n.projectId = $projectId RETURN n
44
+ - "Methods in a class" -> MATCH (c:Class {name: 'ClassName'})-[:HAS_MEMBER]->(m:Method) WHERE c.projectId = $projectId RETURN m
45
45
 
46
46
  === PROJECT ISOLATION (REQUIRED) ===
47
47
  ALL queries MUST filter by projectId on every node pattern:
@@ -58,12 +58,12 @@ Do NOT include projectId in parameters - it's injected automatically.
58
58
 
59
59
  Query Generation Process - FOLLOW THIS EXACTLY:
60
60
  1. SEARCH THE SCHEMA FILE FIRST: Use file_search to read neo4j-apoc-schema.json BEFORE generating any query
61
- 2. EXTRACT VALID LABELS: The keys in rawSchema ARE the valid labels (e.g., "Service", "Controller", "Class", "Method")
61
+ 2. EXTRACT VALID LABELS: The keys in rawSchema ARE the valid labels (e.g., "Class", "Method", "Function", etc.)
62
62
  - rawSchema is ALWAYS available and contains all labels currently in the graph
63
63
  - discoveredSchema.nodeTypes (if available) provides counts and sample properties
64
64
  3. CHECK RELATIONSHIPS: Look at rawSchema[label].relationships for each label to see available relationship types
65
65
  4. CHECK SEMANTIC TYPES: Look at discoveredSchema.semanticTypes (if available) for framework-specific classifications
66
- - semanticTypes are PROPERTY values (e.g., semanticType = 'NestController'), not labels
66
+ - semanticTypes are PROPERTY values stored in n.semanticType, NOT labels - check discoveredSchema for valid values
67
67
  5. REVIEW PATTERNS: Check discoveredSchema.commonPatterns (if available) for frequent relationship patterns
68
68
  6. EXAMINE PROPERTIES: Use rawSchema[label].properties for exact property names and types
69
69
  7. GENERATE QUERY: Write the Cypher query using ONLY labels, relationships, and properties from the schema
@@ -99,14 +99,14 @@ CRITICAL: Do NOT confuse EXTENDS (inheritance) with HAS_MEMBER (composition). "e
99
99
 
100
100
  EXTENDS DIRECTION - CRITICAL:
101
101
  The arrow points FROM child TO parent. The child "extends" toward the parent.
102
- - CORRECT: (child:Class)-[:EXTENDS]->(parent:Class {name: 'BaseService'})
103
- - WRONG: (parent:Class {name: 'BaseService'})-[:EXTENDS]->(child:Class)
102
+ - CORRECT: (child:Class)-[:EXTENDS]->(parent:Class {name: 'ParentClassName'})
103
+ - WRONG: (parent:Class {name: 'ParentClassName'})-[:EXTENDS]->(child:Class)
104
104
 
105
105
  Examples:
106
- - "Classes extending DbService" -> MATCH (c:Class)-[:EXTENDS]->(p:Class {name: 'DbService'}) WHERE c.projectId = $projectId RETURN c
107
- - "What extends BaseController" -> MATCH (c:Class)-[:EXTENDS]->(p:Class {name: 'BaseController'}) WHERE c.projectId = $projectId RETURN c
108
- - "Services that extend DbService with >5 methods" ->
109
- MATCH (c:Class)-[:EXTENDS]->(p:Class {name: 'DbService'})
106
+ - "Classes extending X" -> MATCH (c:Class)-[:EXTENDS]->(p:Class {name: 'X'}) WHERE c.projectId = $projectId RETURN c
107
+ - "What extends Y" -> MATCH (c:Class)-[:EXTENDS]->(p:Class {name: 'Y'}) WHERE c.projectId = $projectId RETURN c
108
+ - "Classes that extend X with >5 methods" ->
109
+ MATCH (c:Class)-[:EXTENDS]->(p:Class {name: 'X'})
110
110
  WHERE c.projectId = $projectId
111
111
  WITH c
112
112
  MATCH (c)-[:HAS_MEMBER]->(m:Method)
@@ -114,27 +114,30 @@ Examples:
114
114
  WHERE methodCount > 5
115
115
  RETURN c, methodCount
116
116
 
117
- === SEMANTIC TYPES (Framework Classifications) ===
118
- Nodes have a semanticType property set by framework detection. Check discoveredSchema.semanticTypes for actual values in this project.
117
+ === SEMANTIC TYPES (Framework Classifications) - PRIMARY QUERY METHOD ===
118
+ *** MOST QUERIES SHOULD USE SEMANTIC TYPES - CHECK discoveredSchema.semanticTypes FIRST ***
119
119
 
120
- The semanticType is a PROPERTY, not a label. Query it like:
121
- - MATCH (c) WHERE c.projectId = $projectId AND c.semanticType = 'NestController' RETURN c
122
- - MATCH (c) WHERE c.projectId = $projectId AND c.semanticType CONTAINS 'Service' RETURN c
120
+ Semantic types are the PRIMARY way to find framework-specific nodes. They are stored in:
121
+ discoveredSchema.semanticTypes -> Array of all semantic type values in this project
123
122
 
124
- Common semantic type patterns (but ALWAYS verify against discoveredSchema.semanticTypes):
123
+ The semanticType is a PROPERTY on nodes, not a label. Query patterns:
124
+ - EXACT MATCH: MATCH (c) WHERE c.projectId = $projectId AND c.semanticType = 'ExactTypeFromSchema' RETURN c
125
+ - PARTIAL MATCH: MATCH (c) WHERE c.projectId = $projectId AND c.semanticType CONTAINS 'Pattern' RETURN c
126
+
127
+ Common semantic type patterns (verify against discoveredSchema.semanticTypes):
125
128
  - Controllers: types containing 'Controller'
126
129
  - Services: types containing 'Service', 'Provider', or 'Injectable'
127
130
  - Repositories: types containing 'Repository', 'DAL', or 'DAO'
128
131
  - Modules: types containing 'Module'
129
132
 
130
- FALLBACK - If no semantic types are discovered, use name patterns:
133
+ FALLBACK - If semantic type doesn't exist, use name patterns:
131
134
  - "Find all controllers" -> MATCH (c:Class) WHERE c.projectId = $projectId AND c.name CONTAINS 'Controller' RETURN c
132
135
  - "Find all services" -> MATCH (c:Class) WHERE c.projectId = $projectId AND c.name CONTAINS 'Service' RETURN c
133
136
 
134
137
  === DECORATOR QUERIES ===
135
138
  Use DECORATED_WITH relationship to find nodes with specific decorators:
136
- - "Classes with @Controller" -> MATCH (c:Class)-[:DECORATED_WITH]->(d:Decorator {name: 'Controller'}) WHERE c.projectId = $projectId RETURN c
137
- - "Methods with @Get" -> MATCH (m:Method)-[:DECORATED_WITH]->(d:Decorator {name: 'Get'}) WHERE m.projectId = $projectId RETURN m
139
+ - "Classes with @X" -> MATCH (c:Class)-[:DECORATED_WITH]->(d:Decorator {name: 'X'}) WHERE c.projectId = $projectId RETURN c
140
+ - "Methods with @Y" -> MATCH (m:Method)-[:DECORATED_WITH]->(d:Decorator {name: 'Y'}) WHERE m.projectId = $projectId RETURN m
138
141
 
139
142
  === MODULE/DIRECTORY QUERIES ===
140
143
  Use filePath property for location-based queries:
@@ -142,15 +145,15 @@ Use filePath property for location-based queries:
142
145
  - "in auth folder" -> WHERE n.filePath CONTAINS '/auth/'
143
146
 
144
147
  Examples:
145
- - "Services in account folder" ->
146
- MATCH (s:Service) WHERE s.projectId = $projectId AND s.filePath CONTAINS '/account/' RETURN s
148
+ - "Items in account folder" ->
149
+ MATCH (c:Class) WHERE c.projectId = $projectId AND c.filePath CONTAINS '/account/' RETURN c
147
150
  - FALLBACK (if no framework labels):
148
151
  MATCH (c:Class) WHERE c.projectId = $projectId AND c.name CONTAINS 'Service' AND c.filePath CONTAINS '/account/' RETURN c
149
152
 
150
153
  === FRAMEWORK-SPECIFIC PATTERNS ===
151
154
 
152
- Backend Projects (decorator-based like NestJS):
153
- - Check rawSchema for framework labels (Service, Controller, Module, etc.) that REPLACE Class label
155
+ Backend Projects (decorator-based frameworks):
156
+ - Check rawSchema for framework labels that REPLACE the Class label
154
157
  - Use framework relationships (INJECTS, EXPOSES, etc.) from rawSchema[label].relationships
155
158
  - Check discoveredSchema.semanticTypes for framework classifications
156
159
 
@@ -283,18 +286,21 @@ ${nodeTypes}
283
286
  === VALID RELATIONSHIP TYPES ===
284
287
  ${relTypes}
285
288
 
286
- === SEMANTIC TYPES (these are PROPERTY values, NOT labels) ===
287
- ${semTypes}
288
- Query semantic types via property: WHERE n.semanticType = 'TypeName'
289
+ === SEMANTIC TYPES - USE THESE FOR FRAMEWORK QUERIES ===
290
+ Available semantic types in this project: ${semTypes}
291
+
292
+ *** SEMANTIC TYPES ARE THE PRIMARY WAY TO QUERY FRAMEWORK-SPECIFIC NODES ***
293
+ Query pattern: WHERE n.semanticType = 'TypeFromListAbove'
294
+ Example: MATCH (n:Class) WHERE n.projectId = $projectId AND n.semanticType = '${semanticTypeList[0] ?? 'SemanticType'}' RETURN n
289
295
  ${frameworkHint}
290
296
 
291
297
  === CRITICAL RULES ===
292
298
  1. Use ONLY the labels listed above after the colon (:Label)
293
- 2. Semantic types are PROPERTY values, NOT labels
294
- 3. Class/service names are PROPERTY values, NOT labels
295
- 4. WRONG: (n:MyService), (n:MyController) - names as labels
296
- 5. CORRECT: (n:Service {name: 'MyService'}), (n:Controller {name: 'MyController'})
297
- 6. CORRECT: (n:Class) WHERE n.semanticType = 'Service'
299
+ 2. Semantic types are PROPERTY values, NOT labels - use WHERE n.semanticType = 'Type'
300
+ 3. Class/entity names are PROPERTY values, NOT labels - use WHERE n.name = 'Name'
301
+ 4. WRONG: (n:ClassName) - using names as labels
302
+ 5. CORRECT: (n:Class {name: 'ClassName'}) or (n:LabelFromSchema {name: 'Name'})
303
+ 6. CORRECT: (n:Class) WHERE n.semanticType = 'TypeFromSemanticTypesList'
298
304
  `.trim();
299
305
  }
300
306
  catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "code-graph-context",
3
- "version": "2.4.1",
3
+ "version": "2.4.3",
4
4
  "description": "MCP server that builds code graphs to provide rich context to LLMs",
5
5
  "type": "module",
6
6
  "homepage": "https://github.com/drewdrewH/code-graph-context#readme",