gitnexus 1.3.2 → 1.3.4
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/ai-context.js +23 -52
- package/dist/cli/analyze.js +4 -1
- package/dist/cli/index.js +1 -0
- package/dist/cli/mcp.js +11 -22
- package/dist/cli/serve.d.ts +1 -0
- package/dist/cli/serve.js +2 -1
- package/dist/cli/setup.js +2 -2
- package/dist/cli/wiki.js +6 -2
- package/dist/config/supported-languages.d.ts +2 -1
- package/dist/config/supported-languages.js +1 -1
- package/dist/core/embeddings/embedder.js +40 -1
- package/dist/core/graph/types.d.ts +2 -0
- package/dist/core/ingestion/entry-point-scoring.js +26 -1
- package/dist/core/ingestion/filesystem-walker.js +3 -3
- package/dist/core/ingestion/framework-detection.d.ts +12 -4
- package/dist/core/ingestion/framework-detection.js +105 -5
- package/dist/core/ingestion/import-processor.js +77 -0
- package/dist/core/ingestion/parsing-processor.js +51 -9
- package/dist/core/ingestion/process-processor.js +7 -1
- package/dist/core/ingestion/tree-sitter-queries.d.ts +1 -0
- package/dist/core/ingestion/tree-sitter-queries.js +361 -282
- package/dist/core/ingestion/utils.js +6 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +3 -0
- package/dist/core/ingestion/workers/parse-worker.js +192 -1
- package/dist/core/kuzu/csv-generator.js +4 -2
- package/dist/core/kuzu/kuzu-adapter.d.ts +9 -0
- package/dist/core/kuzu/kuzu-adapter.js +68 -9
- package/dist/core/kuzu/schema.d.ts +6 -6
- package/dist/core/kuzu/schema.js +8 -0
- package/dist/core/tree-sitter/parser-loader.js +2 -0
- package/dist/core/wiki/generator.js +2 -2
- package/dist/mcp/local/local-backend.js +25 -13
- package/dist/mcp/server.d.ts +9 -0
- package/dist/mcp/server.js +13 -2
- package/dist/mcp/staleness.js +2 -2
- package/dist/server/api.d.ts +7 -5
- package/dist/server/api.js +145 -127
- package/dist/server/mcp-http.d.ts +13 -0
- package/dist/server/mcp-http.js +100 -0
- package/package.json +2 -1
- package/skills/gitnexus-cli.md +82 -0
- package/skills/{debugging.md → gitnexus-debugging.md} +12 -8
- package/skills/{exploring.md → gitnexus-exploring.md} +10 -7
- package/skills/gitnexus-guide.md +64 -0
- package/skills/{impact-analysis.md → gitnexus-impact-analysis.md} +14 -11
- package/skills/{refactoring.md → gitnexus-refactoring.md} +15 -7
|
@@ -40,5 +40,11 @@ export const getLanguageFromFilename = (filename) => {
|
|
|
40
40
|
// Rust
|
|
41
41
|
if (filename.endsWith('.rs'))
|
|
42
42
|
return SupportedLanguages.Rust;
|
|
43
|
+
// PHP (all common extensions)
|
|
44
|
+
if (filename.endsWith('.php') || filename.endsWith('.phtml') ||
|
|
45
|
+
filename.endsWith('.php3') || filename.endsWith('.php4') ||
|
|
46
|
+
filename.endsWith('.php5') || filename.endsWith('.php8')) {
|
|
47
|
+
return SupportedLanguages.PHP;
|
|
48
|
+
}
|
|
43
49
|
return null;
|
|
44
50
|
};
|
|
@@ -9,9 +9,11 @@ import CPP from 'tree-sitter-cpp';
|
|
|
9
9
|
import CSharp from 'tree-sitter-c-sharp';
|
|
10
10
|
import Go from 'tree-sitter-go';
|
|
11
11
|
import Rust from 'tree-sitter-rust';
|
|
12
|
+
import PHP from 'tree-sitter-php';
|
|
12
13
|
import { SupportedLanguages } from '../../../config/supported-languages.js';
|
|
13
14
|
import { LANGUAGE_QUERIES } from '../tree-sitter-queries.js';
|
|
14
15
|
import { getLanguageFromFilename } from '../utils.js';
|
|
16
|
+
import { detectFrameworkFromAST } from '../framework-detection.js';
|
|
15
17
|
import { generateId } from '../../../lib/utils.js';
|
|
16
18
|
// ============================================================================
|
|
17
19
|
// Worker-local parser + language map
|
|
@@ -28,6 +30,7 @@ const languageMap = {
|
|
|
28
30
|
[SupportedLanguages.CSharp]: CSharp,
|
|
29
31
|
[SupportedLanguages.Go]: Go,
|
|
30
32
|
[SupportedLanguages.Rust]: Rust,
|
|
33
|
+
[SupportedLanguages.PHP]: PHP.php_only,
|
|
31
34
|
};
|
|
32
35
|
const setLanguage = (language, filePath) => {
|
|
33
36
|
const key = language === SupportedLanguages.TypeScript && filePath.endsWith('.tsx')
|
|
@@ -106,6 +109,23 @@ const isNodeExported = (node, name, language) => {
|
|
|
106
109
|
case 'c':
|
|
107
110
|
case 'cpp':
|
|
108
111
|
return false;
|
|
112
|
+
case 'php':
|
|
113
|
+
// Top-level classes/interfaces/traits are always accessible
|
|
114
|
+
// Methods/properties are exported only if they have 'public' modifier
|
|
115
|
+
while (current) {
|
|
116
|
+
if (current.type === 'class_declaration' ||
|
|
117
|
+
current.type === 'interface_declaration' ||
|
|
118
|
+
current.type === 'trait_declaration' ||
|
|
119
|
+
current.type === 'enum_declaration') {
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
if (current.type === 'visibility_modifier') {
|
|
123
|
+
return current.text === 'public';
|
|
124
|
+
}
|
|
125
|
+
current = current.parent;
|
|
126
|
+
}
|
|
127
|
+
// Top-level functions (no parent class) are globally accessible
|
|
128
|
+
return true;
|
|
109
129
|
default:
|
|
110
130
|
return false;
|
|
111
131
|
}
|
|
@@ -119,6 +139,7 @@ const FUNCTION_NODE_TYPES = new Set([
|
|
|
119
139
|
'function_definition', 'async_function_declaration', 'async_arrow_function',
|
|
120
140
|
'method_declaration', 'constructor_declaration',
|
|
121
141
|
'local_function_statement', 'function_item', 'impl_item',
|
|
142
|
+
'anonymous_function_creation_expression', // PHP anonymous functions
|
|
122
143
|
]);
|
|
123
144
|
/** Walk up AST to find enclosing function, return its generateId or null for top-level */
|
|
124
145
|
const findEnclosingFunctionId = (node, filePath) => {
|
|
@@ -216,6 +237,23 @@ const BUILT_INS = new Set([
|
|
|
216
237
|
'mutex_lock', 'mutex_unlock', 'mutex_init',
|
|
217
238
|
'kfree', 'kmalloc', 'kzalloc', 'kcalloc', 'krealloc', 'kvmalloc', 'kvfree',
|
|
218
239
|
'get', 'put',
|
|
240
|
+
// PHP built-ins
|
|
241
|
+
'echo', 'isset', 'empty', 'unset', 'list', 'array', 'compact', 'extract',
|
|
242
|
+
'count', 'strlen', 'strpos', 'strrpos', 'substr', 'strtolower', 'strtoupper', 'trim',
|
|
243
|
+
'ltrim', 'rtrim', 'str_replace', 'str_contains', 'str_starts_with', 'str_ends_with',
|
|
244
|
+
'sprintf', 'vsprintf', 'printf', 'number_format',
|
|
245
|
+
'array_map', 'array_filter', 'array_reduce', 'array_push', 'array_pop', 'array_shift',
|
|
246
|
+
'array_unshift', 'array_slice', 'array_splice', 'array_merge', 'array_keys', 'array_values',
|
|
247
|
+
'array_key_exists', 'in_array', 'array_search', 'array_unique', 'usort', 'rsort',
|
|
248
|
+
'json_encode', 'json_decode', 'serialize', 'unserialize',
|
|
249
|
+
'intval', 'floatval', 'strval', 'boolval', 'is_null', 'is_string', 'is_int', 'is_array',
|
|
250
|
+
'is_object', 'is_numeric', 'is_bool', 'is_float',
|
|
251
|
+
'var_dump', 'print_r', 'var_export',
|
|
252
|
+
'date', 'time', 'strtotime', 'mktime', 'microtime',
|
|
253
|
+
'file_exists', 'file_get_contents', 'file_put_contents', 'is_file', 'is_dir',
|
|
254
|
+
'preg_match', 'preg_match_all', 'preg_replace', 'preg_split',
|
|
255
|
+
'header', 'session_start', 'session_destroy', 'ob_start', 'ob_end_clean', 'ob_get_clean',
|
|
256
|
+
'dd', 'dump',
|
|
219
257
|
]);
|
|
220
258
|
// ============================================================================
|
|
221
259
|
// Label detection from capture map
|
|
@@ -272,6 +310,37 @@ const getLabelFromCaptures = (captureMap) => {
|
|
|
272
310
|
return 'Template';
|
|
273
311
|
return 'CodeElement';
|
|
274
312
|
};
|
|
313
|
+
const getDefinitionNodeFromCaptures = (captureMap) => {
|
|
314
|
+
const definitionKeys = [
|
|
315
|
+
'definition.function',
|
|
316
|
+
'definition.class',
|
|
317
|
+
'definition.interface',
|
|
318
|
+
'definition.method',
|
|
319
|
+
'definition.struct',
|
|
320
|
+
'definition.enum',
|
|
321
|
+
'definition.namespace',
|
|
322
|
+
'definition.module',
|
|
323
|
+
'definition.trait',
|
|
324
|
+
'definition.impl',
|
|
325
|
+
'definition.type',
|
|
326
|
+
'definition.const',
|
|
327
|
+
'definition.static',
|
|
328
|
+
'definition.typedef',
|
|
329
|
+
'definition.macro',
|
|
330
|
+
'definition.union',
|
|
331
|
+
'definition.property',
|
|
332
|
+
'definition.record',
|
|
333
|
+
'definition.delegate',
|
|
334
|
+
'definition.annotation',
|
|
335
|
+
'definition.constructor',
|
|
336
|
+
'definition.template',
|
|
337
|
+
];
|
|
338
|
+
for (const key of definitionKeys) {
|
|
339
|
+
if (captureMap[key])
|
|
340
|
+
return captureMap[key];
|
|
341
|
+
}
|
|
342
|
+
return null;
|
|
343
|
+
};
|
|
275
344
|
// ============================================================================
|
|
276
345
|
// Process a batch of files
|
|
277
346
|
// ============================================================================
|
|
@@ -341,6 +410,110 @@ const processBatch = (files, onProgress) => {
|
|
|
341
410
|
}
|
|
342
411
|
return result;
|
|
343
412
|
};
|
|
413
|
+
// ============================================================================
|
|
414
|
+
// PHP Eloquent metadata extraction
|
|
415
|
+
// ============================================================================
|
|
416
|
+
/** Eloquent model properties whose array values are worth indexing */
|
|
417
|
+
const ELOQUENT_ARRAY_PROPS = new Set(['fillable', 'casts', 'hidden', 'guarded', 'with', 'appends']);
|
|
418
|
+
/** Eloquent relationship method names */
|
|
419
|
+
const ELOQUENT_RELATIONS = new Set([
|
|
420
|
+
'hasMany', 'hasOne', 'belongsTo', 'belongsToMany',
|
|
421
|
+
'morphTo', 'morphMany', 'morphOne', 'morphToMany', 'morphedByMany',
|
|
422
|
+
'hasManyThrough', 'hasOneThrough',
|
|
423
|
+
]);
|
|
424
|
+
function findDescendant(node, type) {
|
|
425
|
+
if (node.type === type)
|
|
426
|
+
return node;
|
|
427
|
+
for (const child of (node.children ?? [])) {
|
|
428
|
+
const found = findDescendant(child, type);
|
|
429
|
+
if (found)
|
|
430
|
+
return found;
|
|
431
|
+
}
|
|
432
|
+
return null;
|
|
433
|
+
}
|
|
434
|
+
function extractStringContent(node) {
|
|
435
|
+
if (!node)
|
|
436
|
+
return null;
|
|
437
|
+
const content = node.children?.find((c) => c.type === 'string_content');
|
|
438
|
+
if (content)
|
|
439
|
+
return content.text;
|
|
440
|
+
if (node.type === 'string_content')
|
|
441
|
+
return node.text;
|
|
442
|
+
return null;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* For a PHP property_declaration node, extract array values as a description string.
|
|
446
|
+
* Returns null if not an Eloquent model property or no array values found.
|
|
447
|
+
*/
|
|
448
|
+
function extractPhpPropertyDescription(propName, propDeclNode) {
|
|
449
|
+
if (!ELOQUENT_ARRAY_PROPS.has(propName))
|
|
450
|
+
return null;
|
|
451
|
+
const arrayNode = findDescendant(propDeclNode, 'array_creation_expression');
|
|
452
|
+
if (!arrayNode)
|
|
453
|
+
return null;
|
|
454
|
+
const items = [];
|
|
455
|
+
for (const child of (arrayNode.children ?? [])) {
|
|
456
|
+
if (child.type !== 'array_element_initializer')
|
|
457
|
+
continue;
|
|
458
|
+
const children = child.children ?? [];
|
|
459
|
+
const arrowIdx = children.findIndex((c) => c.type === '=>');
|
|
460
|
+
if (arrowIdx !== -1) {
|
|
461
|
+
// key => value pair (used in $casts)
|
|
462
|
+
const key = extractStringContent(children[arrowIdx - 1]);
|
|
463
|
+
const val = extractStringContent(children[arrowIdx + 1]);
|
|
464
|
+
if (key && val)
|
|
465
|
+
items.push(`${key}:${val}`);
|
|
466
|
+
}
|
|
467
|
+
else {
|
|
468
|
+
// Simple value (used in $fillable, $hidden, etc.)
|
|
469
|
+
const val = extractStringContent(children[0]);
|
|
470
|
+
if (val)
|
|
471
|
+
items.push(val);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
return items.length > 0 ? items.join(', ') : null;
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* For a PHP method_declaration node, detect if it defines an Eloquent relationship.
|
|
478
|
+
* Returns description like "hasMany(Post)" or null.
|
|
479
|
+
*/
|
|
480
|
+
function extractEloquentRelationDescription(methodNode) {
|
|
481
|
+
function findRelationCall(node) {
|
|
482
|
+
if (node.type === 'member_call_expression') {
|
|
483
|
+
const children = node.children ?? [];
|
|
484
|
+
const objectNode = children.find((c) => c.type === 'variable_name' && c.text === '$this');
|
|
485
|
+
const nameNode = children.find((c) => c.type === 'name');
|
|
486
|
+
if (objectNode && nameNode && ELOQUENT_RELATIONS.has(nameNode.text))
|
|
487
|
+
return node;
|
|
488
|
+
}
|
|
489
|
+
for (const child of (node.children ?? [])) {
|
|
490
|
+
const found = findRelationCall(child);
|
|
491
|
+
if (found)
|
|
492
|
+
return found;
|
|
493
|
+
}
|
|
494
|
+
return null;
|
|
495
|
+
}
|
|
496
|
+
const callNode = findRelationCall(methodNode);
|
|
497
|
+
if (!callNode)
|
|
498
|
+
return null;
|
|
499
|
+
const relType = callNode.children?.find((c) => c.type === 'name')?.text;
|
|
500
|
+
const argsNode = callNode.children?.find((c) => c.type === 'arguments');
|
|
501
|
+
let targetModel = null;
|
|
502
|
+
if (argsNode) {
|
|
503
|
+
const firstArg = argsNode.children?.find((c) => c.type === 'argument');
|
|
504
|
+
if (firstArg) {
|
|
505
|
+
const classConstant = firstArg.children?.find((c) => c.type === 'class_constant_access_expression');
|
|
506
|
+
if (classConstant) {
|
|
507
|
+
targetModel = classConstant.children?.find((c) => c.type === 'name')?.text ?? null;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
if (relType && targetModel)
|
|
512
|
+
return `${relType}(${targetModel})`;
|
|
513
|
+
if (relType)
|
|
514
|
+
return relType;
|
|
515
|
+
return null;
|
|
516
|
+
}
|
|
344
517
|
const processFileGroup = (files, language, queryString, result, onFileProcessed) => {
|
|
345
518
|
let query;
|
|
346
519
|
try {
|
|
@@ -352,7 +525,7 @@ const processFileGroup = (files, language, queryString, result, onFileProcessed)
|
|
|
352
525
|
}
|
|
353
526
|
for (const file of files) {
|
|
354
527
|
// Skip very large files — they can crash tree-sitter or cause OOM
|
|
355
|
-
if (file.content.length >
|
|
528
|
+
if (file.content.length > 512 * 1024)
|
|
356
529
|
continue;
|
|
357
530
|
let tree;
|
|
358
531
|
try {
|
|
@@ -435,6 +608,19 @@ const processFileGroup = (files, language, queryString, result, onFileProcessed)
|
|
|
435
608
|
const nameNode = captureMap['name'];
|
|
436
609
|
const nodeName = nameNode.text;
|
|
437
610
|
const nodeId = generateId(nodeLabel, `${file.path}:${nodeName}`);
|
|
611
|
+
let description;
|
|
612
|
+
if (language === SupportedLanguages.PHP) {
|
|
613
|
+
if (nodeLabel === 'Property' && captureMap['definition.property']) {
|
|
614
|
+
description = extractPhpPropertyDescription(nodeName, captureMap['definition.property']) ?? undefined;
|
|
615
|
+
}
|
|
616
|
+
else if (nodeLabel === 'Method' && captureMap['definition.method']) {
|
|
617
|
+
description = extractEloquentRelationDescription(captureMap['definition.method']) ?? undefined;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
const definitionNode = getDefinitionNodeFromCaptures(captureMap);
|
|
621
|
+
const frameworkHint = definitionNode
|
|
622
|
+
? detectFrameworkFromAST(language, definitionNode.text || '')
|
|
623
|
+
: null;
|
|
438
624
|
result.nodes.push({
|
|
439
625
|
id: nodeId,
|
|
440
626
|
label: nodeLabel,
|
|
@@ -445,6 +631,11 @@ const processFileGroup = (files, language, queryString, result, onFileProcessed)
|
|
|
445
631
|
endLine: nameNode.endPosition.row,
|
|
446
632
|
language: language,
|
|
447
633
|
isExported: isNodeExported(nameNode, nodeName, language),
|
|
634
|
+
...(frameworkHint ? {
|
|
635
|
+
astFrameworkMultiplier: frameworkHint.entryPointMultiplier,
|
|
636
|
+
astFrameworkReason: frameworkHint.reason,
|
|
637
|
+
} : {}),
|
|
638
|
+
...(description !== undefined ? { description } : {}),
|
|
448
639
|
},
|
|
449
640
|
});
|
|
450
641
|
result.symbols.push({
|
|
@@ -185,7 +185,7 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
|
|
|
185
185
|
// Create writers for every node type up-front
|
|
186
186
|
const fileWriter = new BufferedCSVWriter(path.join(csvDir, 'file.csv'), 'id,name,filePath,content');
|
|
187
187
|
const folderWriter = new BufferedCSVWriter(path.join(csvDir, 'folder.csv'), 'id,name,filePath');
|
|
188
|
-
const codeElementHeader = 'id,name,filePath,startLine,endLine,isExported,content';
|
|
188
|
+
const codeElementHeader = 'id,name,filePath,startLine,endLine,isExported,content,description';
|
|
189
189
|
const functionWriter = new BufferedCSVWriter(path.join(csvDir, 'function.csv'), codeElementHeader);
|
|
190
190
|
const classWriter = new BufferedCSVWriter(path.join(csvDir, 'class.csv'), codeElementHeader);
|
|
191
191
|
const interfaceWriter = new BufferedCSVWriter(path.join(csvDir, 'interface.csv'), codeElementHeader);
|
|
@@ -194,7 +194,7 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
|
|
|
194
194
|
const communityWriter = new BufferedCSVWriter(path.join(csvDir, 'community.csv'), 'id,label,heuristicLabel,keywords,description,enrichedBy,cohesion,symbolCount');
|
|
195
195
|
const processWriter = new BufferedCSVWriter(path.join(csvDir, 'process.csv'), 'id,label,heuristicLabel,processType,stepCount,communities,entryPointId,terminalId');
|
|
196
196
|
// Multi-language node types share the same CSV shape (no isExported column)
|
|
197
|
-
const multiLangHeader = 'id,name,filePath,startLine,endLine,content';
|
|
197
|
+
const multiLangHeader = 'id,name,filePath,startLine,endLine,content,description';
|
|
198
198
|
const MULTI_LANG_TYPES = ['Struct', 'Enum', 'Macro', 'Typedef', 'Union', 'Namespace', 'Trait', 'Impl',
|
|
199
199
|
'TypeAlias', 'Const', 'Static', 'Property', 'Record', 'Delegate', 'Annotation', 'Constructor', 'Template', 'Module'];
|
|
200
200
|
const multiLangWriters = new Map();
|
|
@@ -275,6 +275,7 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
|
|
|
275
275
|
escapeCSVNumber(node.properties.endLine, -1),
|
|
276
276
|
node.properties.isExported ? 'true' : 'false',
|
|
277
277
|
escapeCSVField(content),
|
|
278
|
+
escapeCSVField(node.properties.description || ''),
|
|
278
279
|
].join(','));
|
|
279
280
|
}
|
|
280
281
|
else {
|
|
@@ -289,6 +290,7 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
|
|
|
289
290
|
escapeCSVNumber(node.properties.startLine, -1),
|
|
290
291
|
escapeCSVNumber(node.properties.endLine, -1),
|
|
291
292
|
escapeCSVField(content),
|
|
293
|
+
escapeCSVField(node.properties.description || ''),
|
|
292
294
|
].join(','));
|
|
293
295
|
}
|
|
294
296
|
}
|
|
@@ -4,6 +4,11 @@ export declare const initKuzu: (dbPath: string) => Promise<{
|
|
|
4
4
|
db: kuzu.Database;
|
|
5
5
|
conn: kuzu.Connection;
|
|
6
6
|
}>;
|
|
7
|
+
/**
|
|
8
|
+
* Execute multiple queries against one repo DB atomically.
|
|
9
|
+
* While the callback runs, no other request can switch the active DB.
|
|
10
|
+
*/
|
|
11
|
+
export declare const withKuzuDb: <T>(dbPath: string, operation: () => Promise<T>) => Promise<T>;
|
|
7
12
|
export type KuzuProgressCallback = (message: string) => void;
|
|
8
13
|
export declare const loadGraphToKuzu: (graph: KnowledgeGraph, repoPath: string, storagePath: string, onProgress?: KuzuProgressCallback) => Promise<{
|
|
9
14
|
success: boolean;
|
|
@@ -61,6 +66,10 @@ export declare const deleteNodesForFile: (filePath: string, dbPath?: string) =>
|
|
|
61
66
|
deletedNodes: number;
|
|
62
67
|
}>;
|
|
63
68
|
export declare const getEmbeddingTableName: () => string;
|
|
69
|
+
/**
|
|
70
|
+
* Load the FTS extension (required before using FTS functions).
|
|
71
|
+
* Safe to call multiple times — tracks loaded state via module-level ftsLoaded.
|
|
72
|
+
*/
|
|
64
73
|
export declare const loadFTSExtension: () => Promise<void>;
|
|
65
74
|
/**
|
|
66
75
|
* Create a full-text search index on a table
|
|
@@ -7,10 +7,64 @@ import { NODE_TABLES, REL_TABLE_NAME, SCHEMA_QUERIES, EMBEDDING_TABLE_NAME, } fr
|
|
|
7
7
|
import { streamAllCSVsToDisk } from './csv-generator.js';
|
|
8
8
|
let db = null;
|
|
9
9
|
let conn = null;
|
|
10
|
+
let currentDbPath = null;
|
|
11
|
+
let ftsLoaded = false;
|
|
12
|
+
// Global session lock for operations that touch module-level kuzu globals.
|
|
13
|
+
// This guarantees no DB switch can happen while an operation is running.
|
|
14
|
+
let sessionLock = Promise.resolve();
|
|
15
|
+
const runWithSessionLock = async (operation) => {
|
|
16
|
+
const previous = sessionLock;
|
|
17
|
+
let release = null;
|
|
18
|
+
sessionLock = new Promise(resolve => {
|
|
19
|
+
release = resolve;
|
|
20
|
+
});
|
|
21
|
+
await previous;
|
|
22
|
+
try {
|
|
23
|
+
return await operation();
|
|
24
|
+
}
|
|
25
|
+
finally {
|
|
26
|
+
release?.();
|
|
27
|
+
}
|
|
28
|
+
};
|
|
10
29
|
const normalizeCopyPath = (filePath) => filePath.replace(/\\/g, '/');
|
|
11
30
|
export const initKuzu = async (dbPath) => {
|
|
12
|
-
|
|
31
|
+
return runWithSessionLock(() => ensureKuzuInitialized(dbPath));
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Execute multiple queries against one repo DB atomically.
|
|
35
|
+
* While the callback runs, no other request can switch the active DB.
|
|
36
|
+
*/
|
|
37
|
+
export const withKuzuDb = async (dbPath, operation) => {
|
|
38
|
+
return runWithSessionLock(async () => {
|
|
39
|
+
await ensureKuzuInitialized(dbPath);
|
|
40
|
+
return operation();
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
const ensureKuzuInitialized = async (dbPath) => {
|
|
44
|
+
if (conn && currentDbPath === dbPath) {
|
|
13
45
|
return { db, conn };
|
|
46
|
+
}
|
|
47
|
+
await doInitKuzu(dbPath);
|
|
48
|
+
return { db, conn };
|
|
49
|
+
};
|
|
50
|
+
const doInitKuzu = async (dbPath) => {
|
|
51
|
+
// Different database requested — close the old one first
|
|
52
|
+
if (conn || db) {
|
|
53
|
+
try {
|
|
54
|
+
if (conn)
|
|
55
|
+
await conn.close();
|
|
56
|
+
}
|
|
57
|
+
catch { }
|
|
58
|
+
try {
|
|
59
|
+
if (db)
|
|
60
|
+
await db.close();
|
|
61
|
+
}
|
|
62
|
+
catch { }
|
|
63
|
+
conn = null;
|
|
64
|
+
db = null;
|
|
65
|
+
currentDbPath = null;
|
|
66
|
+
ftsLoaded = false;
|
|
67
|
+
}
|
|
14
68
|
// kuzu v0.11 stores the database as a single file (not a directory).
|
|
15
69
|
// If the path already exists, it must be a valid kuzu database file.
|
|
16
70
|
// Remove stale empty directories or files from older versions.
|
|
@@ -49,6 +103,7 @@ export const initKuzu = async (dbPath) => {
|
|
|
49
103
|
}
|
|
50
104
|
}
|
|
51
105
|
}
|
|
106
|
+
currentDbPath = dbPath;
|
|
52
107
|
return { db, conn };
|
|
53
108
|
};
|
|
54
109
|
export const loadGraphToKuzu = async (graph, repoPath, storagePath, onProgress) => {
|
|
@@ -263,10 +318,10 @@ const getCopyQuery = (table, filePath) => {
|
|
|
263
318
|
}
|
|
264
319
|
// TypeScript/JS code element tables have isExported; multi-language tables do not
|
|
265
320
|
if (TABLES_WITH_EXPORTED.has(table)) {
|
|
266
|
-
return `COPY ${t}(id, name, filePath, startLine, endLine, isExported, content) FROM "${filePath}" ${COPY_CSV_OPTS}`;
|
|
321
|
+
return `COPY ${t}(id, name, filePath, startLine, endLine, isExported, content, description) FROM "${filePath}" ${COPY_CSV_OPTS}`;
|
|
267
322
|
}
|
|
268
323
|
// Multi-language tables (Struct, Impl, Trait, Macro, etc.)
|
|
269
|
-
return `COPY ${t}(id, name, filePath, startLine, endLine, content) FROM "${filePath}" ${COPY_CSV_OPTS}`;
|
|
324
|
+
return `COPY ${t}(id, name, filePath, startLine, endLine, content, description) FROM "${filePath}" ${COPY_CSV_OPTS}`;
|
|
270
325
|
};
|
|
271
326
|
/**
|
|
272
327
|
* Insert a single node to KuzuDB
|
|
@@ -299,11 +354,13 @@ export const insertNodeToKuzu = async (label, properties, dbPath) => {
|
|
|
299
354
|
query = `CREATE (n:Folder {id: ${escapeValue(properties.id)}, name: ${escapeValue(properties.name)}, filePath: ${escapeValue(properties.filePath)}})`;
|
|
300
355
|
}
|
|
301
356
|
else if (TABLES_WITH_EXPORTED.has(label)) {
|
|
302
|
-
|
|
357
|
+
const descPart = properties.description ? `, description: ${escapeValue(properties.description)}` : '';
|
|
358
|
+
query = `CREATE (n:${t} {id: ${escapeValue(properties.id)}, name: ${escapeValue(properties.name)}, filePath: ${escapeValue(properties.filePath)}, startLine: ${properties.startLine || 0}, endLine: ${properties.endLine || 0}, isExported: ${!!properties.isExported}, content: ${escapeValue(properties.content || '')}${descPart}})`;
|
|
303
359
|
}
|
|
304
360
|
else {
|
|
305
361
|
// Multi-language tables (Struct, Impl, Trait, Macro, etc.) — no isExported
|
|
306
|
-
|
|
362
|
+
const descPart = properties.description ? `, description: ${escapeValue(properties.description)}` : '';
|
|
363
|
+
query = `CREATE (n:${t} {id: ${escapeValue(properties.id)}, name: ${escapeValue(properties.name)}, filePath: ${escapeValue(properties.filePath)}, startLine: ${properties.startLine || 0}, endLine: ${properties.endLine || 0}, content: ${escapeValue(properties.content || '')}${descPart}})`;
|
|
307
364
|
}
|
|
308
365
|
// Use per-query connection if dbPath provided (avoids lock conflicts)
|
|
309
366
|
if (targetDbPath) {
|
|
@@ -372,10 +429,12 @@ export const batchInsertNodesToKuzu = async (nodes, dbPath) => {
|
|
|
372
429
|
query = `MERGE (n:Folder {id: ${escapeValue(properties.id)}}) SET n.name = ${escapeValue(properties.name)}, n.filePath = ${escapeValue(properties.filePath)}`;
|
|
373
430
|
}
|
|
374
431
|
else if (TABLES_WITH_EXPORTED.has(label)) {
|
|
375
|
-
|
|
432
|
+
const descPart = properties.description ? `, n.description = ${escapeValue(properties.description)}` : '';
|
|
433
|
+
query = `MERGE (n:${t} {id: ${escapeValue(properties.id)}}) SET n.name = ${escapeValue(properties.name)}, n.filePath = ${escapeValue(properties.filePath)}, n.startLine = ${properties.startLine || 0}, n.endLine = ${properties.endLine || 0}, n.isExported = ${!!properties.isExported}, n.content = ${escapeValue(properties.content || '')}${descPart}`;
|
|
376
434
|
}
|
|
377
435
|
else {
|
|
378
|
-
|
|
436
|
+
const descPart = properties.description ? `, n.description = ${escapeValue(properties.description)}` : '';
|
|
437
|
+
query = `MERGE (n:${t} {id: ${escapeValue(properties.id)}}) SET n.name = ${escapeValue(properties.name)}, n.filePath = ${escapeValue(properties.filePath)}, n.startLine = ${properties.startLine || 0}, n.endLine = ${properties.endLine || 0}, n.content = ${escapeValue(properties.content || '')}${descPart}`;
|
|
379
438
|
}
|
|
380
439
|
await tempConn.query(query);
|
|
381
440
|
inserted++;
|
|
@@ -512,6 +571,7 @@ export const closeKuzu = async () => {
|
|
|
512
571
|
catch { }
|
|
513
572
|
db = null;
|
|
514
573
|
}
|
|
574
|
+
currentDbPath = null;
|
|
515
575
|
ftsLoaded = false;
|
|
516
576
|
};
|
|
517
577
|
export const isKuzuReady = () => conn !== null && db !== null;
|
|
@@ -592,9 +652,8 @@ export const getEmbeddingTableName = () => EMBEDDING_TABLE_NAME;
|
|
|
592
652
|
// ============================================================================
|
|
593
653
|
/**
|
|
594
654
|
* Load the FTS extension (required before using FTS functions).
|
|
595
|
-
* Safe to call multiple times — tracks loaded state.
|
|
655
|
+
* Safe to call multiple times — tracks loaded state via module-level ftsLoaded.
|
|
596
656
|
*/
|
|
597
|
-
let ftsLoaded = false;
|
|
598
657
|
export const loadFTSExtension = async () => {
|
|
599
658
|
if (ftsLoaded)
|
|
600
659
|
return;
|
|
@@ -16,11 +16,11 @@ export type RelType = typeof REL_TYPES[number];
|
|
|
16
16
|
export declare const EMBEDDING_TABLE_NAME = "CodeEmbedding";
|
|
17
17
|
export declare const FILE_SCHEMA = "\nCREATE NODE TABLE File (\n id STRING,\n name STRING,\n filePath STRING,\n content STRING,\n PRIMARY KEY (id)\n)";
|
|
18
18
|
export declare const FOLDER_SCHEMA = "\nCREATE NODE TABLE Folder (\n id STRING,\n name STRING,\n filePath STRING,\n PRIMARY KEY (id)\n)";
|
|
19
|
-
export declare const FUNCTION_SCHEMA = "\nCREATE NODE TABLE Function (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n isExported BOOLEAN,\n content STRING,\n PRIMARY KEY (id)\n)";
|
|
20
|
-
export declare const CLASS_SCHEMA = "\nCREATE NODE TABLE Class (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n isExported BOOLEAN,\n content STRING,\n PRIMARY KEY (id)\n)";
|
|
21
|
-
export declare const INTERFACE_SCHEMA = "\nCREATE NODE TABLE Interface (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n isExported BOOLEAN,\n content STRING,\n PRIMARY KEY (id)\n)";
|
|
22
|
-
export declare const METHOD_SCHEMA = "\nCREATE NODE TABLE Method (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n isExported BOOLEAN,\n content STRING,\n PRIMARY KEY (id)\n)";
|
|
23
|
-
export declare const CODE_ELEMENT_SCHEMA = "\nCREATE NODE TABLE CodeElement (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n isExported BOOLEAN,\n content STRING,\n PRIMARY KEY (id)\n)";
|
|
19
|
+
export declare const FUNCTION_SCHEMA = "\nCREATE NODE TABLE Function (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n isExported BOOLEAN,\n content STRING,\n description STRING,\n PRIMARY KEY (id)\n)";
|
|
20
|
+
export declare const CLASS_SCHEMA = "\nCREATE NODE TABLE Class (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n isExported BOOLEAN,\n content STRING,\n description STRING,\n PRIMARY KEY (id)\n)";
|
|
21
|
+
export declare const INTERFACE_SCHEMA = "\nCREATE NODE TABLE Interface (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n isExported BOOLEAN,\n content STRING,\n description STRING,\n PRIMARY KEY (id)\n)";
|
|
22
|
+
export declare const METHOD_SCHEMA = "\nCREATE NODE TABLE Method (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n isExported BOOLEAN,\n content STRING,\n description STRING,\n PRIMARY KEY (id)\n)";
|
|
23
|
+
export declare const CODE_ELEMENT_SCHEMA = "\nCREATE NODE TABLE CodeElement (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n isExported BOOLEAN,\n content STRING,\n description STRING,\n PRIMARY KEY (id)\n)";
|
|
24
24
|
export declare const COMMUNITY_SCHEMA = "\nCREATE NODE TABLE Community (\n id STRING,\n label STRING,\n heuristicLabel STRING,\n keywords STRING[],\n description STRING,\n enrichedBy STRING,\n cohesion DOUBLE,\n symbolCount INT32,\n PRIMARY KEY (id)\n)";
|
|
25
25
|
export declare const PROCESS_SCHEMA = "\nCREATE NODE TABLE Process (\n id STRING,\n label STRING,\n heuristicLabel STRING,\n processType STRING,\n stepCount INT32,\n communities STRING[],\n entryPointId STRING,\n terminalId STRING,\n PRIMARY KEY (id)\n)";
|
|
26
26
|
export declare const STRUCT_SCHEMA: string;
|
|
@@ -41,7 +41,7 @@ export declare const ANNOTATION_SCHEMA: string;
|
|
|
41
41
|
export declare const CONSTRUCTOR_SCHEMA: string;
|
|
42
42
|
export declare const TEMPLATE_SCHEMA: string;
|
|
43
43
|
export declare const MODULE_SCHEMA: string;
|
|
44
|
-
export declare const RELATION_SCHEMA = "\nCREATE REL TABLE CodeRelation (\n FROM File TO File,\n FROM File TO Folder,\n FROM File TO Function,\n FROM File TO Class,\n FROM File TO Interface,\n FROM File TO Method,\n FROM File TO CodeElement,\n FROM File TO `Struct`,\n FROM File TO `Enum`,\n FROM File TO `Macro`,\n FROM File TO `Typedef`,\n FROM File TO `Union`,\n FROM File TO `Namespace`,\n FROM File TO `Trait`,\n FROM File TO `Impl`,\n FROM File TO `TypeAlias`,\n FROM File TO `Const`,\n FROM File TO `Static`,\n FROM File TO `Property`,\n FROM File TO `Record`,\n FROM File TO `Delegate`,\n FROM File TO `Annotation`,\n FROM File TO `Constructor`,\n FROM File TO `Template`,\n FROM File TO `Module`,\n FROM Folder TO Folder,\n FROM Folder TO File,\n FROM Function TO Function,\n FROM Function TO Method,\n FROM Function TO Class,\n FROM Function TO Community,\n FROM Function TO `Macro`,\n FROM Function TO `Struct`,\n FROM Function TO `Template`,\n FROM Function TO `Enum`,\n FROM Function TO `Namespace`,\n FROM Function TO `TypeAlias`,\n FROM Function TO `Module`,\n FROM Function TO `Impl`,\n FROM Function TO Interface,\n FROM Function TO `Constructor`,\n FROM Function TO `Const`,\n FROM Function TO `Typedef`,\n FROM Function TO `Union`,\n FROM Class TO Method,\n FROM Class TO Function,\n FROM Class TO Class,\n FROM Class TO Interface,\n FROM Class TO Community,\n FROM Class TO `Template`,\n FROM Class TO `TypeAlias`,\n FROM Class TO `Struct`,\n FROM Class TO `Enum`,\n FROM Class TO `Annotation`,\n FROM Class TO `Constructor`,\n FROM Class TO `Trait`,\n FROM Class TO `Macro`,\n FROM Class TO `Impl`,\n FROM Class TO `Union`,\n FROM Class TO `Namespace`,\n FROM Class TO `Typedef`,\n FROM Method TO Function,\n FROM Method TO Method,\n FROM Method TO Class,\n FROM Method TO Community,\n FROM Method TO `Template`,\n FROM Method TO `Struct`,\n FROM Method TO `TypeAlias`,\n FROM Method TO `Enum`,\n FROM Method TO `Macro`,\n FROM Method TO `Namespace`,\n FROM Method TO `Module`,\n FROM Method TO `Impl`,\n FROM Method TO Interface,\n FROM Method TO `Constructor`,\n FROM `Template` TO `Template`,\n FROM `Template` TO Function,\n FROM `Template` TO Method,\n FROM `Template` TO Class,\n FROM `Template` TO `Struct`,\n FROM `Template` TO `TypeAlias`,\n FROM `Template` TO `Enum`,\n FROM `Template` TO `Macro`,\n FROM `Template` TO Interface,\n FROM `Template` TO `Constructor`,\n FROM `Module` TO `Module`,\n FROM CodeElement TO Community,\n FROM Interface TO Community,\n FROM Interface TO Function,\n FROM Interface TO Method,\n FROM Interface TO Class,\n FROM Interface TO Interface,\n FROM Interface TO `TypeAlias`,\n FROM Interface TO `Struct`,\n FROM Interface TO `Constructor`,\n FROM `Struct` TO Community,\n FROM `Struct` TO `Trait`,\n FROM `Struct` TO `Struct`,\n FROM `Struct` TO Class,\n FROM `Struct` TO `Enum`,\n FROM `Struct` TO Function,\n FROM `Struct` TO Method,\n FROM `Enum` TO Community,\n FROM `Macro` TO Community,\n FROM `Macro` TO Function,\n FROM `Macro` TO Method,\n FROM `Module` TO Function,\n FROM `Module` TO Method,\n FROM `Typedef` TO Community,\n FROM `Union` TO Community,\n FROM `Namespace` TO Community,\n FROM `Namespace` TO `Struct`,\n FROM `Trait` TO Community,\n FROM `Impl` TO Community,\n FROM `Impl` TO `Trait`,\n FROM `Impl` TO `Struct`,\n FROM `Impl` TO `Impl`,\n FROM `TypeAlias` TO Community,\n FROM `TypeAlias` TO `Trait`,\n FROM `Const` TO Community,\n FROM `Static` TO Community,\n FROM `Property` TO Community,\n FROM `Record` TO Community,\n FROM `Delegate` TO Community,\n FROM `Annotation` TO Community,\n FROM `Constructor` TO Community,\n FROM `Constructor` TO Interface,\n FROM `Constructor` TO Class,\n FROM `Constructor` TO Method,\n FROM `Constructor` TO Function,\n FROM `Constructor` TO `Constructor`,\n FROM `Constructor` TO `Struct`,\n FROM `Constructor` TO `Macro`,\n FROM `Constructor` TO `Template`,\n FROM `Constructor` TO `TypeAlias`,\n FROM `Constructor` TO `Enum`,\n FROM `Constructor` TO `Annotation`,\n FROM `Constructor` TO `Impl`,\n FROM `Constructor` TO `Namespace`,\n FROM `Constructor` TO `Module`,\n FROM `Template` TO Community,\n FROM `Module` TO Community,\n FROM Function TO Process,\n FROM Method TO Process,\n FROM Class TO Process,\n FROM Interface TO Process,\n FROM `Struct` TO Process,\n FROM `Constructor` TO Process,\n FROM `Module` TO Process,\n FROM `Macro` TO Process,\n FROM `Impl` TO Process,\n FROM `Typedef` TO Process,\n FROM `TypeAlias` TO Process,\n FROM `Enum` TO Process,\n FROM `Union` TO Process,\n FROM `Namespace` TO Process,\n FROM `Trait` TO Process,\n FROM `Const` TO Process,\n FROM `Static` TO Process,\n FROM `Property` TO Process,\n FROM `Record` TO Process,\n FROM `Delegate` TO Process,\n FROM `Annotation` TO Process,\n FROM `Template` TO Process,\n FROM CodeElement TO Process,\n type STRING,\n confidence DOUBLE,\n reason STRING,\n step INT32\n)";
|
|
44
|
+
export declare const RELATION_SCHEMA = "\nCREATE REL TABLE CodeRelation (\n FROM File TO File,\n FROM File TO Folder,\n FROM File TO Function,\n FROM File TO Class,\n FROM File TO Interface,\n FROM File TO Method,\n FROM File TO CodeElement,\n FROM File TO `Struct`,\n FROM File TO `Enum`,\n FROM File TO `Macro`,\n FROM File TO `Typedef`,\n FROM File TO `Union`,\n FROM File TO `Namespace`,\n FROM File TO `Trait`,\n FROM File TO `Impl`,\n FROM File TO `TypeAlias`,\n FROM File TO `Const`,\n FROM File TO `Static`,\n FROM File TO `Property`,\n FROM File TO `Record`,\n FROM File TO `Delegate`,\n FROM File TO `Annotation`,\n FROM File TO `Constructor`,\n FROM File TO `Template`,\n FROM File TO `Module`,\n FROM Folder TO Folder,\n FROM Folder TO File,\n FROM Function TO Function,\n FROM Function TO Method,\n FROM Function TO Class,\n FROM Function TO Community,\n FROM Function TO `Macro`,\n FROM Function TO `Struct`,\n FROM Function TO `Template`,\n FROM Function TO `Enum`,\n FROM Function TO `Namespace`,\n FROM Function TO `TypeAlias`,\n FROM Function TO `Module`,\n FROM Function TO `Impl`,\n FROM Function TO Interface,\n FROM Function TO `Constructor`,\n FROM Function TO `Const`,\n FROM Function TO `Typedef`,\n FROM Function TO `Union`,\n FROM Class TO Method,\n FROM Class TO Function,\n FROM Class TO Class,\n FROM Class TO Interface,\n FROM Class TO Community,\n FROM Class TO `Template`,\n FROM Class TO `TypeAlias`,\n FROM Class TO `Struct`,\n FROM Class TO `Enum`,\n FROM Class TO `Annotation`,\n FROM Class TO `Constructor`,\n FROM Class TO `Trait`,\n FROM Class TO `Macro`,\n FROM Class TO `Impl`,\n FROM Class TO `Union`,\n FROM Class TO `Namespace`,\n FROM Class TO `Typedef`,\n FROM Method TO Function,\n FROM Method TO Method,\n FROM Method TO Class,\n FROM Method TO Community,\n FROM Method TO `Template`,\n FROM Method TO `Struct`,\n FROM Method TO `TypeAlias`,\n FROM Method TO `Enum`,\n FROM Method TO `Macro`,\n FROM Method TO `Namespace`,\n FROM Method TO `Module`,\n FROM Method TO `Impl`,\n FROM Method TO Interface,\n FROM Method TO `Constructor`,\n FROM Method TO `Property`,\n FROM `Template` TO `Template`,\n FROM `Template` TO Function,\n FROM `Template` TO Method,\n FROM `Template` TO Class,\n FROM `Template` TO `Struct`,\n FROM `Template` TO `TypeAlias`,\n FROM `Template` TO `Enum`,\n FROM `Template` TO `Macro`,\n FROM `Template` TO Interface,\n FROM `Template` TO `Constructor`,\n FROM `Module` TO `Module`,\n FROM CodeElement TO Community,\n FROM Interface TO Community,\n FROM Interface TO Function,\n FROM Interface TO Method,\n FROM Interface TO Class,\n FROM Interface TO Interface,\n FROM Interface TO `TypeAlias`,\n FROM Interface TO `Struct`,\n FROM Interface TO `Constructor`,\n FROM `Struct` TO Community,\n FROM `Struct` TO `Trait`,\n FROM `Struct` TO `Struct`,\n FROM `Struct` TO Class,\n FROM `Struct` TO `Enum`,\n FROM `Struct` TO Function,\n FROM `Struct` TO Method,\n FROM `Enum` TO Community,\n FROM `Macro` TO Community,\n FROM `Macro` TO Function,\n FROM `Macro` TO Method,\n FROM `Module` TO Function,\n FROM `Module` TO Method,\n FROM `Typedef` TO Community,\n FROM `Union` TO Community,\n FROM `Namespace` TO Community,\n FROM `Namespace` TO `Struct`,\n FROM `Trait` TO Community,\n FROM `Impl` TO Community,\n FROM `Impl` TO `Trait`,\n FROM `Impl` TO `Struct`,\n FROM `Impl` TO `Impl`,\n FROM `TypeAlias` TO Community,\n FROM `TypeAlias` TO `Trait`,\n FROM `Const` TO Community,\n FROM `Static` TO Community,\n FROM `Property` TO Community,\n FROM `Record` TO Community,\n FROM `Delegate` TO Community,\n FROM `Annotation` TO Community,\n FROM `Constructor` TO Community,\n FROM `Constructor` TO Interface,\n FROM `Constructor` TO Class,\n FROM `Constructor` TO Method,\n FROM `Constructor` TO Function,\n FROM `Constructor` TO `Constructor`,\n FROM `Constructor` TO `Struct`,\n FROM `Constructor` TO `Macro`,\n FROM `Constructor` TO `Template`,\n FROM `Constructor` TO `TypeAlias`,\n FROM `Constructor` TO `Enum`,\n FROM `Constructor` TO `Annotation`,\n FROM `Constructor` TO `Impl`,\n FROM `Constructor` TO `Namespace`,\n FROM `Constructor` TO `Module`,\n FROM `Template` TO Community,\n FROM `Module` TO Community,\n FROM Function TO Process,\n FROM Method TO Process,\n FROM Class TO Process,\n FROM Interface TO Process,\n FROM `Struct` TO Process,\n FROM `Constructor` TO Process,\n FROM `Module` TO Process,\n FROM `Macro` TO Process,\n FROM `Impl` TO Process,\n FROM `Typedef` TO Process,\n FROM `TypeAlias` TO Process,\n FROM `Enum` TO Process,\n FROM `Union` TO Process,\n FROM `Namespace` TO Process,\n FROM `Trait` TO Process,\n FROM `Const` TO Process,\n FROM `Static` TO Process,\n FROM `Property` TO Process,\n FROM `Record` TO Process,\n FROM `Delegate` TO Process,\n FROM `Annotation` TO Process,\n FROM `Template` TO Process,\n FROM CodeElement TO Process,\n type STRING,\n confidence DOUBLE,\n reason STRING,\n step INT32\n)";
|
|
45
45
|
export declare const EMBEDDING_SCHEMA = "\nCREATE NODE TABLE CodeEmbedding (\n nodeId STRING,\n embedding FLOAT[384],\n PRIMARY KEY (nodeId)\n)";
|
|
46
46
|
/**
|
|
47
47
|
* Create vector index for semantic search
|
package/dist/core/kuzu/schema.js
CHANGED
|
@@ -54,6 +54,7 @@ CREATE NODE TABLE Function (
|
|
|
54
54
|
endLine INT64,
|
|
55
55
|
isExported BOOLEAN,
|
|
56
56
|
content STRING,
|
|
57
|
+
description STRING,
|
|
57
58
|
PRIMARY KEY (id)
|
|
58
59
|
)`;
|
|
59
60
|
export const CLASS_SCHEMA = `
|
|
@@ -65,6 +66,7 @@ CREATE NODE TABLE Class (
|
|
|
65
66
|
endLine INT64,
|
|
66
67
|
isExported BOOLEAN,
|
|
67
68
|
content STRING,
|
|
69
|
+
description STRING,
|
|
68
70
|
PRIMARY KEY (id)
|
|
69
71
|
)`;
|
|
70
72
|
export const INTERFACE_SCHEMA = `
|
|
@@ -76,6 +78,7 @@ CREATE NODE TABLE Interface (
|
|
|
76
78
|
endLine INT64,
|
|
77
79
|
isExported BOOLEAN,
|
|
78
80
|
content STRING,
|
|
81
|
+
description STRING,
|
|
79
82
|
PRIMARY KEY (id)
|
|
80
83
|
)`;
|
|
81
84
|
export const METHOD_SCHEMA = `
|
|
@@ -87,6 +90,7 @@ CREATE NODE TABLE Method (
|
|
|
87
90
|
endLine INT64,
|
|
88
91
|
isExported BOOLEAN,
|
|
89
92
|
content STRING,
|
|
93
|
+
description STRING,
|
|
90
94
|
PRIMARY KEY (id)
|
|
91
95
|
)`;
|
|
92
96
|
export const CODE_ELEMENT_SCHEMA = `
|
|
@@ -98,6 +102,7 @@ CREATE NODE TABLE CodeElement (
|
|
|
98
102
|
endLine INT64,
|
|
99
103
|
isExported BOOLEAN,
|
|
100
104
|
content STRING,
|
|
105
|
+
description STRING,
|
|
101
106
|
PRIMARY KEY (id)
|
|
102
107
|
)`;
|
|
103
108
|
// ============================================================================
|
|
@@ -134,6 +139,7 @@ CREATE NODE TABLE Process (
|
|
|
134
139
|
// MULTI-LANGUAGE NODE TABLE SCHEMAS
|
|
135
140
|
// ============================================================================
|
|
136
141
|
// Generic code element with startLine/endLine for C, C++, Rust, Go, Java, C#
|
|
142
|
+
// description: optional metadata (e.g. Eloquent $fillable fields, relationship targets)
|
|
137
143
|
const CODE_ELEMENT_BASE = (name) => `
|
|
138
144
|
CREATE NODE TABLE \`${name}\` (
|
|
139
145
|
id STRING,
|
|
@@ -142,6 +148,7 @@ CREATE NODE TABLE \`${name}\` (
|
|
|
142
148
|
startLine INT64,
|
|
143
149
|
endLine INT64,
|
|
144
150
|
content STRING,
|
|
151
|
+
description STRING,
|
|
145
152
|
PRIMARY KEY (id)
|
|
146
153
|
)`;
|
|
147
154
|
export const STRUCT_SCHEMA = CODE_ELEMENT_BASE('Struct');
|
|
@@ -243,6 +250,7 @@ CREATE REL TABLE ${REL_TABLE_NAME} (
|
|
|
243
250
|
FROM Method TO \`Impl\`,
|
|
244
251
|
FROM Method TO Interface,
|
|
245
252
|
FROM Method TO \`Constructor\`,
|
|
253
|
+
FROM Method TO \`Property\`,
|
|
246
254
|
FROM \`Template\` TO \`Template\`,
|
|
247
255
|
FROM \`Template\` TO Function,
|
|
248
256
|
FROM \`Template\` TO Method,
|
|
@@ -8,6 +8,7 @@ import CPP from 'tree-sitter-cpp';
|
|
|
8
8
|
import CSharp from 'tree-sitter-c-sharp';
|
|
9
9
|
import Go from 'tree-sitter-go';
|
|
10
10
|
import Rust from 'tree-sitter-rust';
|
|
11
|
+
import PHP from 'tree-sitter-php';
|
|
11
12
|
import { SupportedLanguages } from '../../config/supported-languages.js';
|
|
12
13
|
let parser = null;
|
|
13
14
|
const languageMap = {
|
|
@@ -21,6 +22,7 @@ const languageMap = {
|
|
|
21
22
|
[SupportedLanguages.CSharp]: CSharp,
|
|
22
23
|
[SupportedLanguages.Go]: Go,
|
|
23
24
|
[SupportedLanguages.Rust]: Rust,
|
|
25
|
+
[SupportedLanguages.PHP]: PHP.php_only,
|
|
24
26
|
};
|
|
25
27
|
export const loadParser = async () => {
|
|
26
28
|
if (parser)
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import fs from 'fs/promises';
|
|
13
13
|
import path from 'path';
|
|
14
|
-
import { execSync } from 'child_process';
|
|
14
|
+
import { execSync, execFileSync } from 'child_process';
|
|
15
15
|
import { initWikiDb, closeWikiDb, getFilesWithExports, getAllFiles, getIntraModuleCallEdges, getInterModuleCallEdges, getProcessesForFiles, getAllProcesses, getInterModuleEdgesForOverview, } from './graph-queries.js';
|
|
16
16
|
import { generateHTMLViewer } from './html-viewer.js';
|
|
17
17
|
import { callLLM, estimateTokens, } from './llm-client.js';
|
|
@@ -561,7 +561,7 @@ export class WikiGenerator {
|
|
|
561
561
|
}
|
|
562
562
|
getChangedFiles(fromCommit, toCommit) {
|
|
563
563
|
try {
|
|
564
|
-
const output =
|
|
564
|
+
const output = execFileSync('git', ['diff', `${fromCommit}..${toCommit}`, '--name-only'], { cwd: this.repoPath }).toString().trim();
|
|
565
565
|
return output ? output.split('\n').filter(Boolean) : [];
|
|
566
566
|
}
|
|
567
567
|
catch {
|