code-graph-context 2.4.0 → 2.4.2
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 +1 -1
- package/dist/core/config/fairsquare-framework-schema.js +6 -14
- package/dist/core/config/nestjs-framework-schema.js +20 -27
- package/dist/core/config/schema.js +6 -0
- package/dist/core/embeddings/natural-language-to-cypher.service.js +31 -14
- package/dist/core/parsers/typescript-parser.js +15 -7
- package/package.json +1 -1
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)', '
|
|
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);
|
|
@@ -525,13 +525,11 @@ export const FAIRSQUARE_FRAMEWORK_SCHEMA = {
|
|
|
525
525
|
{
|
|
526
526
|
type: 'function',
|
|
527
527
|
pattern: (parsedNode) => {
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
const name = node.getName();
|
|
532
|
-
const typeNode = node.getTypeNode();
|
|
528
|
+
// Use pre-extracted properties (works after AST cleanup in streaming/chunking)
|
|
529
|
+
const name = parsedNode.properties.name;
|
|
530
|
+
const typeAnnotation = parsedNode.properties.typeAnnotation;
|
|
533
531
|
// Check if variable name ends with "Routes" AND has type ModuleRoute[]
|
|
534
|
-
return !!name
|
|
532
|
+
return !!name?.endsWith('Routes') && !!typeAnnotation?.includes('ModuleRoute');
|
|
535
533
|
},
|
|
536
534
|
confidence: 1.0,
|
|
537
535
|
priority: 10,
|
|
@@ -696,14 +694,8 @@ export const FAIRSQUARE_FRAMEWORK_SCHEMA = {
|
|
|
696
694
|
if (matchingRoutes.length === 0)
|
|
697
695
|
return false;
|
|
698
696
|
// CRITICAL FIX: Verify the method belongs to the correct controller
|
|
699
|
-
//
|
|
700
|
-
const
|
|
701
|
-
if (!targetNode || !Node.isMethodDeclaration(targetNode))
|
|
702
|
-
return false;
|
|
703
|
-
const parentClass = targetNode.getParent();
|
|
704
|
-
if (!parentClass || !Node.isClassDeclaration(parentClass))
|
|
705
|
-
return false;
|
|
706
|
-
const parentClassName = parentClass.getName();
|
|
697
|
+
// Use pre-extracted parentClassName property (works after AST cleanup in streaming/chunking)
|
|
698
|
+
const parentClassName = parsedTargetNode.properties.parentClassName;
|
|
707
699
|
if (!parentClassName)
|
|
708
700
|
return false;
|
|
709
701
|
// Check if any matching route's controller name matches the parent class
|
|
@@ -434,7 +434,8 @@ export const NESTJS_FRAMEWORK_SCHEMA = {
|
|
|
434
434
|
},
|
|
435
435
|
{
|
|
436
436
|
type: 'function',
|
|
437
|
-
|
|
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,10 +517,11 @@ export const NESTJS_FRAMEWORK_SCHEMA = {
|
|
|
516
517
|
detectionPatterns: [
|
|
517
518
|
{
|
|
518
519
|
type: 'function',
|
|
519
|
-
|
|
520
|
-
|
|
520
|
+
// Use pre-extracted decoratorNames from context (works after AST cleanup in streaming/chunking)
|
|
521
|
+
pattern: (parsedNode) => {
|
|
522
|
+
const decoratorNames = parsedNode.properties?.context?.decoratorNames ?? [];
|
|
521
523
|
const messageDecorators = ['MessagePattern', 'EventPattern'];
|
|
522
|
-
return
|
|
524
|
+
return messageDecorators.some((d) => decoratorNames.includes(d));
|
|
523
525
|
},
|
|
524
526
|
confidence: 0.98,
|
|
525
527
|
priority: 15,
|
|
@@ -567,10 +569,11 @@ export const NESTJS_FRAMEWORK_SCHEMA = {
|
|
|
567
569
|
detectionPatterns: [
|
|
568
570
|
{
|
|
569
571
|
type: 'function',
|
|
570
|
-
|
|
571
|
-
|
|
572
|
+
// Use pre-extracted decoratorNames from context (works after AST cleanup in streaming/chunking)
|
|
573
|
+
pattern: (parsedNode) => {
|
|
574
|
+
const decoratorNames = parsedNode.properties?.context?.decoratorNames ?? [];
|
|
572
575
|
const httpDecorators = ['Get', 'Post', 'Put', 'Delete', 'Patch', 'Head', 'Options'];
|
|
573
|
-
return
|
|
576
|
+
return httpDecorators.some((d) => decoratorNames.includes(d));
|
|
574
577
|
},
|
|
575
578
|
confidence: 0.98,
|
|
576
579
|
priority: 15,
|
|
@@ -723,16 +726,11 @@ export const NESTJS_FRAMEWORK_SCHEMA = {
|
|
|
723
726
|
if (parsedSourceNode.properties?.filePath !== parsedTargetNode.properties?.filePath) {
|
|
724
727
|
return false;
|
|
725
728
|
}
|
|
726
|
-
//
|
|
727
|
-
|
|
728
|
-
const
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
if (methodParent === sourceNode) {
|
|
732
|
-
return true;
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
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;
|
|
736
734
|
},
|
|
737
735
|
contextExtractor: (parsedSourceNode, parsedTargetNode) => ({
|
|
738
736
|
endpointType: 'RPC',
|
|
@@ -755,16 +753,11 @@ export const NESTJS_FRAMEWORK_SCHEMA = {
|
|
|
755
753
|
if (parsedSourceNode.properties?.filePath !== parsedTargetNode.properties?.filePath) {
|
|
756
754
|
return false;
|
|
757
755
|
}
|
|
758
|
-
//
|
|
759
|
-
|
|
760
|
-
const
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
if (methodParent === sourceNode) {
|
|
764
|
-
return true;
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
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;
|
|
768
761
|
},
|
|
769
762
|
contextExtractor: (parsedSourceNode, parsedTargetNode) => ({
|
|
770
763
|
httpMethod: parsedTargetNode.properties?.context?.httpMethod ?? '',
|
|
@@ -480,6 +480,12 @@ export const CORE_TYPESCRIPT_SCHEMA = {
|
|
|
480
480
|
extraction: { method: 'static', defaultValue: false }, // We'll set this manually
|
|
481
481
|
neo4j: { indexed: true, unique: false, required: true },
|
|
482
482
|
},
|
|
483
|
+
{
|
|
484
|
+
name: 'typeAnnotation',
|
|
485
|
+
type: 'string',
|
|
486
|
+
extraction: { method: 'ast', source: 'getTypeNode', transform: 'getText' },
|
|
487
|
+
neo4j: { indexed: false, unique: false, required: false },
|
|
488
|
+
},
|
|
483
489
|
],
|
|
484
490
|
relationships: [],
|
|
485
491
|
children: {},
|
|
@@ -277,16 +277,24 @@ Provide ONLY the JSON response with no additional text, markdown formatting, or
|
|
|
277
277
|
frameworkHint = '\nFRAMEWORK DETECTED: React/functional codebase. Use Function nodes for components.';
|
|
278
278
|
}
|
|
279
279
|
return `
|
|
280
|
-
|
|
280
|
+
=== VALID NODE LABELS (use ONLY these after the colon) ===
|
|
281
|
+
${nodeTypes}
|
|
281
282
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
283
|
+
=== VALID RELATIONSHIP TYPES ===
|
|
284
|
+
${relTypes}
|
|
285
|
+
|
|
286
|
+
=== SEMANTIC TYPES (these are PROPERTY values, NOT labels) ===
|
|
287
|
+
${semTypes}
|
|
288
|
+
Query semantic types via property: WHERE n.semanticType = 'TypeName'
|
|
285
289
|
${frameworkHint}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
+
|
|
291
|
+
=== CRITICAL RULES ===
|
|
292
|
+
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'
|
|
290
298
|
`.trim();
|
|
291
299
|
}
|
|
292
300
|
catch (error) {
|
|
@@ -507,7 +515,7 @@ Remember to include WHERE n.projectId = $projectId for all node patterns.
|
|
|
507
515
|
}
|
|
508
516
|
/**
|
|
509
517
|
* Load valid labels dynamically from the schema file.
|
|
510
|
-
* Returns all keys from rawSchema which represent actual Neo4j labels.
|
|
518
|
+
* Returns all keys from rawSchema AND discoveredSchema.nodeTypes which represent actual Neo4j labels.
|
|
511
519
|
*/
|
|
512
520
|
loadValidLabelsFromSchema() {
|
|
513
521
|
// Fallback to core TypeScript labels if schema not available
|
|
@@ -535,12 +543,21 @@ Remember to include WHERE n.projectId = $projectId for all node patterns.
|
|
|
535
543
|
try {
|
|
536
544
|
const content = fs.readFileSync(this.schemaPath, 'utf-8');
|
|
537
545
|
const schema = JSON.parse(content);
|
|
538
|
-
|
|
539
|
-
|
|
546
|
+
const allLabels = new Set(coreLabels);
|
|
547
|
+
// Extract labels from rawSchema keys
|
|
548
|
+
if (schema.rawSchema?.records?.[0]?._fields?.[0]) {
|
|
549
|
+
const schemaLabels = Object.keys(schema.rawSchema.records[0]._fields[0]);
|
|
550
|
+
schemaLabels.forEach((label) => allLabels.add(label));
|
|
551
|
+
}
|
|
552
|
+
// Also extract labels from discoveredSchema.nodeTypes (includes framework labels)
|
|
553
|
+
if (schema.discoveredSchema?.nodeTypes) {
|
|
554
|
+
for (const nodeType of schema.discoveredSchema.nodeTypes) {
|
|
555
|
+
if (nodeType.label) {
|
|
556
|
+
allLabels.add(nodeType.label);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
540
559
|
}
|
|
541
|
-
|
|
542
|
-
const schemaLabels = Object.keys(schema.rawSchema.records[0]._fields[0]);
|
|
543
|
-
return new Set([...coreLabels, ...schemaLabels]);
|
|
560
|
+
return allLabels;
|
|
544
561
|
}
|
|
545
562
|
catch {
|
|
546
563
|
return coreLabels;
|
|
@@ -542,6 +542,11 @@ export class TypeScriptParser {
|
|
|
542
542
|
return astNode.getName();
|
|
543
543
|
}
|
|
544
544
|
break;
|
|
545
|
+
case CoreNodeType.VARIABLE_DECLARATION:
|
|
546
|
+
if (Node.isVariableDeclaration(astNode)) {
|
|
547
|
+
return astNode.getName();
|
|
548
|
+
}
|
|
549
|
+
break;
|
|
545
550
|
default:
|
|
546
551
|
return astNode.getKindName();
|
|
547
552
|
}
|
|
@@ -552,13 +557,18 @@ export class TypeScriptParser {
|
|
|
552
557
|
return 'Unknown';
|
|
553
558
|
}
|
|
554
559
|
extractProperty(astNode, propDef) {
|
|
555
|
-
const { method, source, defaultValue } = propDef.extraction;
|
|
560
|
+
const { method, source, defaultValue, transform } = propDef.extraction;
|
|
556
561
|
try {
|
|
557
562
|
switch (method) {
|
|
558
563
|
case 'ast':
|
|
559
564
|
if (typeof source === 'string') {
|
|
560
565
|
const fn = astNode[source];
|
|
561
|
-
|
|
566
|
+
let result = typeof fn === 'function' ? fn.call(astNode) : defaultValue;
|
|
567
|
+
// Apply transform if specified (e.g., 'getText' on a returned node)
|
|
568
|
+
if (result && transform && typeof result[transform] === 'function') {
|
|
569
|
+
result = result[transform]();
|
|
570
|
+
}
|
|
571
|
+
return result ?? defaultValue;
|
|
562
572
|
}
|
|
563
573
|
return defaultValue;
|
|
564
574
|
case 'function':
|
|
@@ -1284,11 +1294,9 @@ export class TypeScriptParser {
|
|
|
1284
1294
|
}
|
|
1285
1295
|
case 'function':
|
|
1286
1296
|
if (typeof pattern.pattern === 'function') {
|
|
1287
|
-
// Pass the
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
return false;
|
|
1291
|
-
return pattern.pattern(astNode);
|
|
1297
|
+
// Pass the ParsedNode to pattern functions
|
|
1298
|
+
// Patterns should use pre-extracted properties for cross-chunk compatibility
|
|
1299
|
+
return pattern.pattern(node);
|
|
1292
1300
|
}
|
|
1293
1301
|
return false;
|
|
1294
1302
|
case 'classname':
|
package/package.json
CHANGED