@duytransipher/gitnexus 1.4.6-sipher.0
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/LICENSE +73 -0
- package/README.md +261 -0
- package/dist/cli/ai-context.d.ts +23 -0
- package/dist/cli/ai-context.js +265 -0
- package/dist/cli/analyze.d.ts +12 -0
- package/dist/cli/analyze.js +345 -0
- package/dist/cli/augment.d.ts +13 -0
- package/dist/cli/augment.js +33 -0
- package/dist/cli/clean.d.ts +10 -0
- package/dist/cli/clean.js +60 -0
- package/dist/cli/eval-server.d.ts +37 -0
- package/dist/cli/eval-server.js +389 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +137 -0
- package/dist/cli/lazy-action.d.ts +6 -0
- package/dist/cli/lazy-action.js +18 -0
- package/dist/cli/list.d.ts +6 -0
- package/dist/cli/list.js +30 -0
- package/dist/cli/mcp.d.ts +8 -0
- package/dist/cli/mcp.js +36 -0
- package/dist/cli/serve.d.ts +4 -0
- package/dist/cli/serve.js +6 -0
- package/dist/cli/setup.d.ts +8 -0
- package/dist/cli/setup.js +367 -0
- package/dist/cli/sipher-patched.d.ts +2 -0
- package/dist/cli/sipher-patched.js +77 -0
- package/dist/cli/skill-gen.d.ts +26 -0
- package/dist/cli/skill-gen.js +549 -0
- package/dist/cli/status.d.ts +6 -0
- package/dist/cli/status.js +36 -0
- package/dist/cli/tool.d.ts +60 -0
- package/dist/cli/tool.js +180 -0
- package/dist/cli/wiki.d.ts +15 -0
- package/dist/cli/wiki.js +365 -0
- package/dist/config/ignore-service.d.ts +26 -0
- package/dist/config/ignore-service.js +284 -0
- package/dist/config/supported-languages.d.ts +15 -0
- package/dist/config/supported-languages.js +16 -0
- package/dist/core/augmentation/engine.d.ts +26 -0
- package/dist/core/augmentation/engine.js +240 -0
- package/dist/core/embeddings/embedder.d.ts +60 -0
- package/dist/core/embeddings/embedder.js +251 -0
- package/dist/core/embeddings/embedding-pipeline.d.ts +51 -0
- package/dist/core/embeddings/embedding-pipeline.js +356 -0
- package/dist/core/embeddings/index.d.ts +9 -0
- package/dist/core/embeddings/index.js +9 -0
- package/dist/core/embeddings/text-generator.d.ts +24 -0
- package/dist/core/embeddings/text-generator.js +182 -0
- package/dist/core/embeddings/types.d.ts +87 -0
- package/dist/core/embeddings/types.js +32 -0
- package/dist/core/graph/graph.d.ts +2 -0
- package/dist/core/graph/graph.js +66 -0
- package/dist/core/graph/types.d.ts +66 -0
- package/dist/core/graph/types.js +1 -0
- package/dist/core/ingestion/ast-cache.d.ts +11 -0
- package/dist/core/ingestion/ast-cache.js +35 -0
- package/dist/core/ingestion/call-processor.d.ts +23 -0
- package/dist/core/ingestion/call-processor.js +793 -0
- package/dist/core/ingestion/call-routing.d.ts +68 -0
- package/dist/core/ingestion/call-routing.js +129 -0
- package/dist/core/ingestion/cluster-enricher.d.ts +38 -0
- package/dist/core/ingestion/cluster-enricher.js +170 -0
- package/dist/core/ingestion/community-processor.d.ts +39 -0
- package/dist/core/ingestion/community-processor.js +312 -0
- package/dist/core/ingestion/constants.d.ts +16 -0
- package/dist/core/ingestion/constants.js +16 -0
- package/dist/core/ingestion/entry-point-scoring.d.ts +40 -0
- package/dist/core/ingestion/entry-point-scoring.js +353 -0
- package/dist/core/ingestion/export-detection.d.ts +18 -0
- package/dist/core/ingestion/export-detection.js +231 -0
- package/dist/core/ingestion/filesystem-walker.d.ts +28 -0
- package/dist/core/ingestion/filesystem-walker.js +81 -0
- package/dist/core/ingestion/framework-detection.d.ts +54 -0
- package/dist/core/ingestion/framework-detection.js +411 -0
- package/dist/core/ingestion/heritage-processor.d.ts +28 -0
- package/dist/core/ingestion/heritage-processor.js +251 -0
- package/dist/core/ingestion/import-processor.d.ts +34 -0
- package/dist/core/ingestion/import-processor.js +398 -0
- package/dist/core/ingestion/language-config.d.ts +46 -0
- package/dist/core/ingestion/language-config.js +167 -0
- package/dist/core/ingestion/mro-processor.d.ts +45 -0
- package/dist/core/ingestion/mro-processor.js +369 -0
- package/dist/core/ingestion/named-binding-extraction.d.ts +61 -0
- package/dist/core/ingestion/named-binding-extraction.js +363 -0
- package/dist/core/ingestion/parsing-processor.d.ts +19 -0
- package/dist/core/ingestion/parsing-processor.js +315 -0
- package/dist/core/ingestion/pipeline.d.ts +6 -0
- package/dist/core/ingestion/pipeline.js +401 -0
- package/dist/core/ingestion/process-processor.d.ts +51 -0
- package/dist/core/ingestion/process-processor.js +315 -0
- package/dist/core/ingestion/resolution-context.d.ts +53 -0
- package/dist/core/ingestion/resolution-context.js +132 -0
- package/dist/core/ingestion/resolvers/csharp.d.ts +22 -0
- package/dist/core/ingestion/resolvers/csharp.js +109 -0
- package/dist/core/ingestion/resolvers/go.d.ts +19 -0
- package/dist/core/ingestion/resolvers/go.js +42 -0
- package/dist/core/ingestion/resolvers/index.d.ts +18 -0
- package/dist/core/ingestion/resolvers/index.js +13 -0
- package/dist/core/ingestion/resolvers/jvm.d.ts +23 -0
- package/dist/core/ingestion/resolvers/jvm.js +87 -0
- package/dist/core/ingestion/resolvers/php.d.ts +15 -0
- package/dist/core/ingestion/resolvers/php.js +35 -0
- package/dist/core/ingestion/resolvers/python.d.ts +19 -0
- package/dist/core/ingestion/resolvers/python.js +52 -0
- package/dist/core/ingestion/resolvers/ruby.d.ts +12 -0
- package/dist/core/ingestion/resolvers/ruby.js +15 -0
- package/dist/core/ingestion/resolvers/rust.d.ts +15 -0
- package/dist/core/ingestion/resolvers/rust.js +73 -0
- package/dist/core/ingestion/resolvers/standard.d.ts +28 -0
- package/dist/core/ingestion/resolvers/standard.js +123 -0
- package/dist/core/ingestion/resolvers/utils.d.ts +33 -0
- package/dist/core/ingestion/resolvers/utils.js +122 -0
- package/dist/core/ingestion/structure-processor.d.ts +2 -0
- package/dist/core/ingestion/structure-processor.js +36 -0
- package/dist/core/ingestion/symbol-table.d.ts +63 -0
- package/dist/core/ingestion/symbol-table.js +85 -0
- package/dist/core/ingestion/tree-sitter-queries.d.ts +15 -0
- package/dist/core/ingestion/tree-sitter-queries.js +888 -0
- package/dist/core/ingestion/type-env.d.ts +49 -0
- package/dist/core/ingestion/type-env.js +613 -0
- package/dist/core/ingestion/type-extractors/c-cpp.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/c-cpp.js +385 -0
- package/dist/core/ingestion/type-extractors/csharp.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/csharp.js +383 -0
- package/dist/core/ingestion/type-extractors/go.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/go.js +467 -0
- package/dist/core/ingestion/type-extractors/index.d.ts +22 -0
- package/dist/core/ingestion/type-extractors/index.js +31 -0
- package/dist/core/ingestion/type-extractors/jvm.d.ts +3 -0
- package/dist/core/ingestion/type-extractors/jvm.js +681 -0
- package/dist/core/ingestion/type-extractors/php.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/php.js +549 -0
- package/dist/core/ingestion/type-extractors/python.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/python.js +455 -0
- package/dist/core/ingestion/type-extractors/ruby.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/ruby.js +389 -0
- package/dist/core/ingestion/type-extractors/rust.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/rust.js +456 -0
- package/dist/core/ingestion/type-extractors/shared.d.ts +145 -0
- package/dist/core/ingestion/type-extractors/shared.js +810 -0
- package/dist/core/ingestion/type-extractors/swift.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/swift.js +137 -0
- package/dist/core/ingestion/type-extractors/types.d.ts +127 -0
- package/dist/core/ingestion/type-extractors/types.js +1 -0
- package/dist/core/ingestion/type-extractors/typescript.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/typescript.js +494 -0
- package/dist/core/ingestion/utils.d.ts +138 -0
- package/dist/core/ingestion/utils.js +1290 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +122 -0
- package/dist/core/ingestion/workers/parse-worker.js +1126 -0
- package/dist/core/ingestion/workers/worker-pool.d.ts +16 -0
- package/dist/core/ingestion/workers/worker-pool.js +128 -0
- package/dist/core/lbug/csv-generator.d.ts +33 -0
- package/dist/core/lbug/csv-generator.js +366 -0
- package/dist/core/lbug/lbug-adapter.d.ts +103 -0
- package/dist/core/lbug/lbug-adapter.js +769 -0
- package/dist/core/lbug/schema.d.ts +53 -0
- package/dist/core/lbug/schema.js +430 -0
- package/dist/core/search/bm25-index.d.ts +23 -0
- package/dist/core/search/bm25-index.js +96 -0
- package/dist/core/search/hybrid-search.d.ts +49 -0
- package/dist/core/search/hybrid-search.js +118 -0
- package/dist/core/tree-sitter/parser-loader.d.ts +5 -0
- package/dist/core/tree-sitter/parser-loader.js +63 -0
- package/dist/core/wiki/generator.d.ts +120 -0
- package/dist/core/wiki/generator.js +939 -0
- package/dist/core/wiki/graph-queries.d.ts +80 -0
- package/dist/core/wiki/graph-queries.js +238 -0
- package/dist/core/wiki/html-viewer.d.ts +10 -0
- package/dist/core/wiki/html-viewer.js +297 -0
- package/dist/core/wiki/llm-client.d.ts +43 -0
- package/dist/core/wiki/llm-client.js +186 -0
- package/dist/core/wiki/prompts.d.ts +53 -0
- package/dist/core/wiki/prompts.js +174 -0
- package/dist/lib/utils.d.ts +1 -0
- package/dist/lib/utils.js +3 -0
- package/dist/mcp/compatible-stdio-transport.d.ts +25 -0
- package/dist/mcp/compatible-stdio-transport.js +200 -0
- package/dist/mcp/core/embedder.d.ts +27 -0
- package/dist/mcp/core/embedder.js +108 -0
- package/dist/mcp/core/lbug-adapter.d.ts +57 -0
- package/dist/mcp/core/lbug-adapter.js +455 -0
- package/dist/mcp/local/local-backend.d.ts +181 -0
- package/dist/mcp/local/local-backend.js +1722 -0
- package/dist/mcp/resources.d.ts +31 -0
- package/dist/mcp/resources.js +411 -0
- package/dist/mcp/server.d.ts +23 -0
- package/dist/mcp/server.js +296 -0
- package/dist/mcp/staleness.d.ts +15 -0
- package/dist/mcp/staleness.js +29 -0
- package/dist/mcp/tools.d.ts +24 -0
- package/dist/mcp/tools.js +292 -0
- package/dist/server/api.d.ts +10 -0
- package/dist/server/api.js +344 -0
- package/dist/server/mcp-http.d.ts +13 -0
- package/dist/server/mcp-http.js +100 -0
- package/dist/storage/git.d.ts +6 -0
- package/dist/storage/git.js +35 -0
- package/dist/storage/repo-manager.d.ts +138 -0
- package/dist/storage/repo-manager.js +299 -0
- package/dist/types/pipeline.d.ts +32 -0
- package/dist/types/pipeline.js +18 -0
- package/dist/unreal/bridge.d.ts +4 -0
- package/dist/unreal/bridge.js +113 -0
- package/dist/unreal/config.d.ts +6 -0
- package/dist/unreal/config.js +55 -0
- package/dist/unreal/types.d.ts +105 -0
- package/dist/unreal/types.js +1 -0
- package/hooks/claude/gitnexus-hook.cjs +238 -0
- package/hooks/claude/pre-tool-use.sh +79 -0
- package/hooks/claude/session-start.sh +42 -0
- package/package.json +100 -0
- package/scripts/ensure-cli-executable.cjs +21 -0
- package/scripts/patch-tree-sitter-swift.cjs +74 -0
- package/scripts/setup-unreal-gitnexus.ps1 +191 -0
- package/skills/gitnexus-cli.md +82 -0
- package/skills/gitnexus-debugging.md +89 -0
- package/skills/gitnexus-exploring.md +78 -0
- package/skills/gitnexus-guide.md +64 -0
- package/skills/gitnexus-impact-analysis.md +97 -0
- package/skills/gitnexus-pr-review.md +163 -0
- package/skills/gitnexus-refactoring.md +121 -0
- package/vendor/leiden/index.cjs +355 -0
- package/vendor/leiden/utils.cjs +392 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text Generator Module
|
|
3
|
+
*
|
|
4
|
+
* Pure functions to generate embedding text from code nodes.
|
|
5
|
+
* Combines node metadata with code snippets for semantic matching.
|
|
6
|
+
*/
|
|
7
|
+
import type { EmbeddableNode, EmbeddingConfig } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Generate embedding text for any embeddable node
|
|
10
|
+
* Dispatches to the appropriate generator based on node label
|
|
11
|
+
*
|
|
12
|
+
* @param node - The node to generate text for
|
|
13
|
+
* @param config - Optional configuration for max snippet length
|
|
14
|
+
* @returns Text suitable for embedding
|
|
15
|
+
*/
|
|
16
|
+
export declare const generateEmbeddingText: (node: EmbeddableNode, config?: Partial<EmbeddingConfig>) => string;
|
|
17
|
+
/**
|
|
18
|
+
* Generate embedding texts for a batch of nodes
|
|
19
|
+
*
|
|
20
|
+
* @param nodes - Array of nodes to generate text for
|
|
21
|
+
* @param config - Optional configuration
|
|
22
|
+
* @returns Array of texts in the same order as input nodes
|
|
23
|
+
*/
|
|
24
|
+
export declare const generateBatchEmbeddingTexts: (nodes: EmbeddableNode[], config?: Partial<EmbeddingConfig>) => string[];
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text Generator Module
|
|
3
|
+
*
|
|
4
|
+
* Pure functions to generate embedding text from code nodes.
|
|
5
|
+
* Combines node metadata with code snippets for semantic matching.
|
|
6
|
+
*/
|
|
7
|
+
import { DEFAULT_EMBEDDING_CONFIG } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Extract the filename from a file path
|
|
10
|
+
*/
|
|
11
|
+
const getFileName = (filePath) => {
|
|
12
|
+
const parts = filePath.split('/');
|
|
13
|
+
return parts[parts.length - 1] || filePath;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Extract the directory path from a file path
|
|
17
|
+
*/
|
|
18
|
+
const getDirectory = (filePath) => {
|
|
19
|
+
const parts = filePath.split('/');
|
|
20
|
+
parts.pop();
|
|
21
|
+
return parts.join('/') || '';
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Truncate content to max length, preserving word boundaries
|
|
25
|
+
*/
|
|
26
|
+
const truncateContent = (content, maxLength) => {
|
|
27
|
+
if (content.length <= maxLength) {
|
|
28
|
+
return content;
|
|
29
|
+
}
|
|
30
|
+
// Find last space before maxLength to avoid cutting words
|
|
31
|
+
const truncated = content.slice(0, maxLength);
|
|
32
|
+
const lastSpace = truncated.lastIndexOf(' ');
|
|
33
|
+
if (lastSpace > maxLength * 0.8) {
|
|
34
|
+
return truncated.slice(0, lastSpace) + '...';
|
|
35
|
+
}
|
|
36
|
+
return truncated + '...';
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Clean code content for embedding
|
|
40
|
+
* Removes excessive whitespace while preserving structure
|
|
41
|
+
*/
|
|
42
|
+
const cleanContent = (content) => {
|
|
43
|
+
return content
|
|
44
|
+
// Normalize line endings
|
|
45
|
+
.replace(/\r\n/g, '\n')
|
|
46
|
+
// Remove excessive blank lines (more than 2)
|
|
47
|
+
.replace(/\n{3,}/g, '\n\n')
|
|
48
|
+
// Trim each line
|
|
49
|
+
.split('\n')
|
|
50
|
+
.map(line => line.trimEnd())
|
|
51
|
+
.join('\n')
|
|
52
|
+
.trim();
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Generate embedding text for a Function node
|
|
56
|
+
*/
|
|
57
|
+
const generateFunctionText = (node, maxSnippetLength) => {
|
|
58
|
+
const parts = [
|
|
59
|
+
`Function: ${node.name}`,
|
|
60
|
+
`File: ${getFileName(node.filePath)}`,
|
|
61
|
+
];
|
|
62
|
+
const dir = getDirectory(node.filePath);
|
|
63
|
+
if (dir) {
|
|
64
|
+
parts.push(`Directory: ${dir}`);
|
|
65
|
+
}
|
|
66
|
+
if (node.content) {
|
|
67
|
+
const cleanedContent = cleanContent(node.content);
|
|
68
|
+
const snippet = truncateContent(cleanedContent, maxSnippetLength);
|
|
69
|
+
parts.push('', snippet);
|
|
70
|
+
}
|
|
71
|
+
return parts.join('\n');
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Generate embedding text for a Class node
|
|
75
|
+
*/
|
|
76
|
+
const generateClassText = (node, maxSnippetLength) => {
|
|
77
|
+
const parts = [
|
|
78
|
+
`Class: ${node.name}`,
|
|
79
|
+
`File: ${getFileName(node.filePath)}`,
|
|
80
|
+
];
|
|
81
|
+
const dir = getDirectory(node.filePath);
|
|
82
|
+
if (dir) {
|
|
83
|
+
parts.push(`Directory: ${dir}`);
|
|
84
|
+
}
|
|
85
|
+
if (node.content) {
|
|
86
|
+
const cleanedContent = cleanContent(node.content);
|
|
87
|
+
const snippet = truncateContent(cleanedContent, maxSnippetLength);
|
|
88
|
+
parts.push('', snippet);
|
|
89
|
+
}
|
|
90
|
+
return parts.join('\n');
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Generate embedding text for a Method node
|
|
94
|
+
*/
|
|
95
|
+
const generateMethodText = (node, maxSnippetLength) => {
|
|
96
|
+
const parts = [
|
|
97
|
+
`Method: ${node.name}`,
|
|
98
|
+
`File: ${getFileName(node.filePath)}`,
|
|
99
|
+
];
|
|
100
|
+
const dir = getDirectory(node.filePath);
|
|
101
|
+
if (dir) {
|
|
102
|
+
parts.push(`Directory: ${dir}`);
|
|
103
|
+
}
|
|
104
|
+
if (node.content) {
|
|
105
|
+
const cleanedContent = cleanContent(node.content);
|
|
106
|
+
const snippet = truncateContent(cleanedContent, maxSnippetLength);
|
|
107
|
+
parts.push('', snippet);
|
|
108
|
+
}
|
|
109
|
+
return parts.join('\n');
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* Generate embedding text for an Interface node
|
|
113
|
+
*/
|
|
114
|
+
const generateInterfaceText = (node, maxSnippetLength) => {
|
|
115
|
+
const parts = [
|
|
116
|
+
`Interface: ${node.name}`,
|
|
117
|
+
`File: ${getFileName(node.filePath)}`,
|
|
118
|
+
];
|
|
119
|
+
const dir = getDirectory(node.filePath);
|
|
120
|
+
if (dir) {
|
|
121
|
+
parts.push(`Directory: ${dir}`);
|
|
122
|
+
}
|
|
123
|
+
if (node.content) {
|
|
124
|
+
const cleanedContent = cleanContent(node.content);
|
|
125
|
+
const snippet = truncateContent(cleanedContent, maxSnippetLength);
|
|
126
|
+
parts.push('', snippet);
|
|
127
|
+
}
|
|
128
|
+
return parts.join('\n');
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* Generate embedding text for a File node
|
|
132
|
+
* Uses file name and first N characters of content
|
|
133
|
+
*/
|
|
134
|
+
const generateFileText = (node, maxSnippetLength) => {
|
|
135
|
+
const parts = [
|
|
136
|
+
`File: ${node.name}`,
|
|
137
|
+
`Path: ${node.filePath}`,
|
|
138
|
+
];
|
|
139
|
+
if (node.content) {
|
|
140
|
+
const cleanedContent = cleanContent(node.content);
|
|
141
|
+
// For files, use a shorter snippet since they can be very long
|
|
142
|
+
const snippet = truncateContent(cleanedContent, Math.min(maxSnippetLength, 300));
|
|
143
|
+
parts.push('', snippet);
|
|
144
|
+
}
|
|
145
|
+
return parts.join('\n');
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* Generate embedding text for any embeddable node
|
|
149
|
+
* Dispatches to the appropriate generator based on node label
|
|
150
|
+
*
|
|
151
|
+
* @param node - The node to generate text for
|
|
152
|
+
* @param config - Optional configuration for max snippet length
|
|
153
|
+
* @returns Text suitable for embedding
|
|
154
|
+
*/
|
|
155
|
+
export const generateEmbeddingText = (node, config = {}) => {
|
|
156
|
+
const maxSnippetLength = config.maxSnippetLength ?? DEFAULT_EMBEDDING_CONFIG.maxSnippetLength;
|
|
157
|
+
switch (node.label) {
|
|
158
|
+
case 'Function':
|
|
159
|
+
return generateFunctionText(node, maxSnippetLength);
|
|
160
|
+
case 'Class':
|
|
161
|
+
return generateClassText(node, maxSnippetLength);
|
|
162
|
+
case 'Method':
|
|
163
|
+
return generateMethodText(node, maxSnippetLength);
|
|
164
|
+
case 'Interface':
|
|
165
|
+
return generateInterfaceText(node, maxSnippetLength);
|
|
166
|
+
case 'File':
|
|
167
|
+
return generateFileText(node, maxSnippetLength);
|
|
168
|
+
default:
|
|
169
|
+
// Fallback for any other embeddable type
|
|
170
|
+
return `${node.label}: ${node.name}\nPath: ${node.filePath}`;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
/**
|
|
174
|
+
* Generate embedding texts for a batch of nodes
|
|
175
|
+
*
|
|
176
|
+
* @param nodes - Array of nodes to generate text for
|
|
177
|
+
* @param config - Optional configuration
|
|
178
|
+
* @returns Array of texts in the same order as input nodes
|
|
179
|
+
*/
|
|
180
|
+
export const generateBatchEmbeddingTexts = (nodes, config = {}) => {
|
|
181
|
+
return nodes.map(node => generateEmbeddingText(node, config));
|
|
182
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embedding Pipeline Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for the embedding generation and semantic search system.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Node labels that should be embedded for semantic search
|
|
8
|
+
* These are code elements that benefit from semantic matching
|
|
9
|
+
*/
|
|
10
|
+
export declare const EMBEDDABLE_LABELS: readonly ["Function", "Class", "Method", "Interface", "File"];
|
|
11
|
+
export type EmbeddableLabel = typeof EMBEDDABLE_LABELS[number];
|
|
12
|
+
/**
|
|
13
|
+
* Check if a label should be embedded
|
|
14
|
+
*/
|
|
15
|
+
export declare const isEmbeddableLabel: (label: string) => label is EmbeddableLabel;
|
|
16
|
+
/**
|
|
17
|
+
* Embedding pipeline phases
|
|
18
|
+
*/
|
|
19
|
+
export type EmbeddingPhase = 'idle' | 'loading-model' | 'embedding' | 'indexing' | 'ready' | 'error';
|
|
20
|
+
/**
|
|
21
|
+
* Progress information for the embedding pipeline
|
|
22
|
+
*/
|
|
23
|
+
export interface EmbeddingProgress {
|
|
24
|
+
phase: EmbeddingPhase;
|
|
25
|
+
percent: number;
|
|
26
|
+
modelDownloadPercent?: number;
|
|
27
|
+
nodesProcessed?: number;
|
|
28
|
+
totalNodes?: number;
|
|
29
|
+
currentBatch?: number;
|
|
30
|
+
totalBatches?: number;
|
|
31
|
+
error?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Configuration for the embedding pipeline
|
|
35
|
+
*/
|
|
36
|
+
export interface EmbeddingConfig {
|
|
37
|
+
/** Model identifier for transformers.js */
|
|
38
|
+
modelId: string;
|
|
39
|
+
/** Number of nodes to embed in each batch */
|
|
40
|
+
batchSize: number;
|
|
41
|
+
/** Embedding vector dimensions */
|
|
42
|
+
dimensions: number;
|
|
43
|
+
/** Device to use for inference: 'auto' tries GPU first (DirectML on Windows, CUDA on Linux), falls back to CPU */
|
|
44
|
+
device: 'auto' | 'dml' | 'cuda' | 'cpu' | 'wasm';
|
|
45
|
+
/** Maximum characters of code snippet to include */
|
|
46
|
+
maxSnippetLength: number;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Default embedding configuration
|
|
50
|
+
* Uses snowflake-arctic-embed-xs for browser efficiency
|
|
51
|
+
* Tries WebGPU first (fast), user can choose WASM fallback if unavailable
|
|
52
|
+
*/
|
|
53
|
+
export declare const DEFAULT_EMBEDDING_CONFIG: EmbeddingConfig;
|
|
54
|
+
/**
|
|
55
|
+
* Result from semantic search
|
|
56
|
+
*/
|
|
57
|
+
export interface SemanticSearchResult {
|
|
58
|
+
nodeId: string;
|
|
59
|
+
name: string;
|
|
60
|
+
label: string;
|
|
61
|
+
filePath: string;
|
|
62
|
+
distance: number;
|
|
63
|
+
startLine?: number;
|
|
64
|
+
endLine?: number;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Node data for embedding (minimal structure from LadybugDB query)
|
|
68
|
+
*/
|
|
69
|
+
export interface EmbeddableNode {
|
|
70
|
+
id: string;
|
|
71
|
+
name: string;
|
|
72
|
+
label: string;
|
|
73
|
+
filePath: string;
|
|
74
|
+
content: string;
|
|
75
|
+
startLine?: number;
|
|
76
|
+
endLine?: number;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Model download progress from transformers.js
|
|
80
|
+
*/
|
|
81
|
+
export interface ModelProgress {
|
|
82
|
+
status: 'initiate' | 'download' | 'progress' | 'done' | 'ready';
|
|
83
|
+
file?: string;
|
|
84
|
+
progress?: number;
|
|
85
|
+
loaded?: number;
|
|
86
|
+
total?: number;
|
|
87
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embedding Pipeline Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for the embedding generation and semantic search system.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Node labels that should be embedded for semantic search
|
|
8
|
+
* These are code elements that benefit from semantic matching
|
|
9
|
+
*/
|
|
10
|
+
export const EMBEDDABLE_LABELS = [
|
|
11
|
+
'Function',
|
|
12
|
+
'Class',
|
|
13
|
+
'Method',
|
|
14
|
+
'Interface',
|
|
15
|
+
'File',
|
|
16
|
+
];
|
|
17
|
+
/**
|
|
18
|
+
* Check if a label should be embedded
|
|
19
|
+
*/
|
|
20
|
+
export const isEmbeddableLabel = (label) => EMBEDDABLE_LABELS.includes(label);
|
|
21
|
+
/**
|
|
22
|
+
* Default embedding configuration
|
|
23
|
+
* Uses snowflake-arctic-embed-xs for browser efficiency
|
|
24
|
+
* Tries WebGPU first (fast), user can choose WASM fallback if unavailable
|
|
25
|
+
*/
|
|
26
|
+
export const DEFAULT_EMBEDDING_CONFIG = {
|
|
27
|
+
modelId: 'Snowflake/snowflake-arctic-embed-xs',
|
|
28
|
+
batchSize: 16,
|
|
29
|
+
dimensions: 384,
|
|
30
|
+
device: 'auto',
|
|
31
|
+
maxSnippetLength: 500,
|
|
32
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export const createKnowledgeGraph = () => {
|
|
2
|
+
const nodeMap = new Map();
|
|
3
|
+
const relationshipMap = new Map();
|
|
4
|
+
const addNode = (node) => {
|
|
5
|
+
if (!nodeMap.has(node.id)) {
|
|
6
|
+
nodeMap.set(node.id, node);
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
const addRelationship = (relationship) => {
|
|
10
|
+
if (!relationshipMap.has(relationship.id)) {
|
|
11
|
+
relationshipMap.set(relationship.id, relationship);
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Remove a single node and all relationships involving it
|
|
16
|
+
*/
|
|
17
|
+
const removeNode = (nodeId) => {
|
|
18
|
+
if (!nodeMap.has(nodeId))
|
|
19
|
+
return false;
|
|
20
|
+
nodeMap.delete(nodeId);
|
|
21
|
+
// Remove all relationships involving this node
|
|
22
|
+
for (const [relId, rel] of relationshipMap) {
|
|
23
|
+
if (rel.sourceId === nodeId || rel.targetId === nodeId) {
|
|
24
|
+
relationshipMap.delete(relId);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return true;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Remove all nodes (and their relationships) belonging to a file
|
|
31
|
+
*/
|
|
32
|
+
const removeNodesByFile = (filePath) => {
|
|
33
|
+
let removed = 0;
|
|
34
|
+
for (const [nodeId, node] of nodeMap) {
|
|
35
|
+
if (node.properties?.filePath === filePath) {
|
|
36
|
+
removeNode(nodeId);
|
|
37
|
+
removed++;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return removed;
|
|
41
|
+
};
|
|
42
|
+
return {
|
|
43
|
+
get nodes() {
|
|
44
|
+
return Array.from(nodeMap.values());
|
|
45
|
+
},
|
|
46
|
+
get relationships() {
|
|
47
|
+
return Array.from(relationshipMap.values());
|
|
48
|
+
},
|
|
49
|
+
iterNodes: () => nodeMap.values(),
|
|
50
|
+
iterRelationships: () => relationshipMap.values(),
|
|
51
|
+
forEachNode(fn) { nodeMap.forEach(fn); },
|
|
52
|
+
forEachRelationship(fn) { relationshipMap.forEach(fn); },
|
|
53
|
+
getNode: (id) => nodeMap.get(id),
|
|
54
|
+
// O(1) count getters - avoid creating arrays just for length
|
|
55
|
+
get nodeCount() {
|
|
56
|
+
return nodeMap.size;
|
|
57
|
+
},
|
|
58
|
+
get relationshipCount() {
|
|
59
|
+
return relationshipMap.size;
|
|
60
|
+
},
|
|
61
|
+
addNode,
|
|
62
|
+
addRelationship,
|
|
63
|
+
removeNode,
|
|
64
|
+
removeNodesByFile,
|
|
65
|
+
};
|
|
66
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export type NodeLabel = 'Project' | 'Package' | 'Module' | 'Folder' | 'File' | 'Class' | 'Function' | 'Method' | 'Variable' | 'Interface' | 'Enum' | 'Decorator' | 'Import' | 'Type' | 'CodeElement' | 'Community' | 'Process' | 'Struct' | 'Macro' | 'Typedef' | 'Union' | 'Namespace' | 'Trait' | 'Impl' | 'TypeAlias' | 'Const' | 'Static' | 'Property' | 'Record' | 'Delegate' | 'Annotation' | 'Constructor' | 'Template';
|
|
2
|
+
import { SupportedLanguages } from '../../config/supported-languages.js';
|
|
3
|
+
export type NodeProperties = {
|
|
4
|
+
name: string;
|
|
5
|
+
filePath: string;
|
|
6
|
+
startLine?: number;
|
|
7
|
+
endLine?: number;
|
|
8
|
+
language?: SupportedLanguages;
|
|
9
|
+
isExported?: boolean;
|
|
10
|
+
astFrameworkMultiplier?: number;
|
|
11
|
+
astFrameworkReason?: string;
|
|
12
|
+
heuristicLabel?: string;
|
|
13
|
+
cohesion?: number;
|
|
14
|
+
symbolCount?: number;
|
|
15
|
+
keywords?: string[];
|
|
16
|
+
description?: string;
|
|
17
|
+
enrichedBy?: 'heuristic' | 'llm';
|
|
18
|
+
processType?: 'intra_community' | 'cross_community';
|
|
19
|
+
stepCount?: number;
|
|
20
|
+
communities?: string[];
|
|
21
|
+
entryPointId?: string;
|
|
22
|
+
terminalId?: string;
|
|
23
|
+
entryPointScore?: number;
|
|
24
|
+
entryPointReason?: string;
|
|
25
|
+
parameterCount?: number;
|
|
26
|
+
returnType?: string;
|
|
27
|
+
};
|
|
28
|
+
export type RelationshipType = 'CONTAINS' | 'CALLS' | 'INHERITS' | 'OVERRIDES' | 'IMPORTS' | 'USES' | 'DEFINES' | 'DECORATES' | 'IMPLEMENTS' | 'EXTENDS' | 'HAS_METHOD' | 'HAS_PROPERTY' | 'ACCESSES' | 'MEMBER_OF' | 'STEP_IN_PROCESS';
|
|
29
|
+
export interface GraphNode {
|
|
30
|
+
id: string;
|
|
31
|
+
label: NodeLabel;
|
|
32
|
+
properties: NodeProperties;
|
|
33
|
+
}
|
|
34
|
+
export interface GraphRelationship {
|
|
35
|
+
id: string;
|
|
36
|
+
sourceId: string;
|
|
37
|
+
targetId: string;
|
|
38
|
+
type: RelationshipType;
|
|
39
|
+
/** Confidence score 0-1 (1.0 = certain, lower = uncertain resolution) */
|
|
40
|
+
confidence: number;
|
|
41
|
+
/** Semantics are edge-type-dependent: CALLS uses resolution tier, ACCESSES uses 'read'/'write', OVERRIDES uses MRO reason */
|
|
42
|
+
reason: string;
|
|
43
|
+
/** Step number for STEP_IN_PROCESS relationships (1-indexed) */
|
|
44
|
+
step?: number;
|
|
45
|
+
}
|
|
46
|
+
export interface KnowledgeGraph {
|
|
47
|
+
/** Returns a full array copy — prefer iterNodes() for iteration */
|
|
48
|
+
nodes: GraphNode[];
|
|
49
|
+
/** Returns a full array copy — prefer iterRelationships() for iteration */
|
|
50
|
+
relationships: GraphRelationship[];
|
|
51
|
+
/** Zero-copy iterator over nodes */
|
|
52
|
+
iterNodes: () => IterableIterator<GraphNode>;
|
|
53
|
+
/** Zero-copy iterator over relationships */
|
|
54
|
+
iterRelationships: () => IterableIterator<GraphRelationship>;
|
|
55
|
+
/** Zero-copy forEach — avoids iterator protocol overhead in hot loops */
|
|
56
|
+
forEachNode: (fn: (node: GraphNode) => void) => void;
|
|
57
|
+
forEachRelationship: (fn: (rel: GraphRelationship) => void) => void;
|
|
58
|
+
/** Lookup a single node by id — O(1) */
|
|
59
|
+
getNode: (id: string) => GraphNode | undefined;
|
|
60
|
+
nodeCount: number;
|
|
61
|
+
relationshipCount: number;
|
|
62
|
+
addNode: (node: GraphNode) => void;
|
|
63
|
+
addRelationship: (relationship: GraphRelationship) => void;
|
|
64
|
+
removeNode: (nodeId: string) => boolean;
|
|
65
|
+
removeNodesByFile: (filePath: string) => number;
|
|
66
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import Parser from 'tree-sitter';
|
|
2
|
+
export interface ASTCache {
|
|
3
|
+
get: (filePath: string) => Parser.Tree | undefined;
|
|
4
|
+
set: (filePath: string, tree: Parser.Tree) => void;
|
|
5
|
+
clear: () => void;
|
|
6
|
+
stats: () => {
|
|
7
|
+
size: number;
|
|
8
|
+
maxSize: number;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export declare const createASTCache: (maxSize?: number) => ASTCache;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { LRUCache } from 'lru-cache';
|
|
2
|
+
export const createASTCache = (maxSize = 50) => {
|
|
3
|
+
const effectiveMax = Math.max(maxSize, 1);
|
|
4
|
+
// Initialize the cache with a 'dispose' handler
|
|
5
|
+
// This is the magic: When an item is evicted (dropped), this runs automatically.
|
|
6
|
+
const cache = new LRUCache({
|
|
7
|
+
max: effectiveMax,
|
|
8
|
+
dispose: (tree) => {
|
|
9
|
+
try {
|
|
10
|
+
// NOTE: web-tree-sitter has tree.delete(); native tree-sitter trees are GC-managed.
|
|
11
|
+
// Keep this try/catch so we don't crash on either runtime.
|
|
12
|
+
tree.delete?.();
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
console.warn('Failed to delete tree from WASM memory', e);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
return {
|
|
20
|
+
get: (filePath) => {
|
|
21
|
+
const tree = cache.get(filePath);
|
|
22
|
+
return tree; // Returns undefined if not found
|
|
23
|
+
},
|
|
24
|
+
set: (filePath, tree) => {
|
|
25
|
+
cache.set(filePath, tree);
|
|
26
|
+
},
|
|
27
|
+
clear: () => {
|
|
28
|
+
cache.clear();
|
|
29
|
+
},
|
|
30
|
+
stats: () => ({
|
|
31
|
+
size: cache.size,
|
|
32
|
+
maxSize: effectiveMax
|
|
33
|
+
})
|
|
34
|
+
};
|
|
35
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { KnowledgeGraph } from '../graph/types.js';
|
|
2
|
+
import { ASTCache } from './ast-cache.js';
|
|
3
|
+
import type { ResolutionContext } from './resolution-context.js';
|
|
4
|
+
import type { ExtractedCall, ExtractedAssignment, ExtractedHeritage, ExtractedRoute, FileConstructorBindings } from './workers/parse-worker.js';
|
|
5
|
+
export declare const processCalls: (graph: KnowledgeGraph, files: {
|
|
6
|
+
path: string;
|
|
7
|
+
content: string;
|
|
8
|
+
}[], astCache: ASTCache, ctx: ResolutionContext, onProgress?: (current: number, total: number) => void) => Promise<ExtractedHeritage[]>;
|
|
9
|
+
/**
|
|
10
|
+
* Fast path: resolve pre-extracted call sites from workers.
|
|
11
|
+
* No AST parsing — workers already extracted calledName + sourceId.
|
|
12
|
+
*/
|
|
13
|
+
export declare const processCallsFromExtracted: (graph: KnowledgeGraph, extractedCalls: ExtractedCall[], ctx: ResolutionContext, onProgress?: (current: number, total: number) => void, constructorBindings?: FileConstructorBindings[]) => Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Resolve pre-extracted field write assignments to ACCESSES {reason: 'write'} edges.
|
|
16
|
+
* Accepts optional constructorBindings for return-type-aware receiver inference,
|
|
17
|
+
* mirroring processCallsFromExtracted's verified binding lookup.
|
|
18
|
+
*/
|
|
19
|
+
export declare const processAssignmentsFromExtracted: (graph: KnowledgeGraph, assignments: ExtractedAssignment[], ctx: ResolutionContext, constructorBindings?: FileConstructorBindings[]) => void;
|
|
20
|
+
/**
|
|
21
|
+
* Resolve pre-extracted Laravel routes to CALLS edges from route files to controller methods.
|
|
22
|
+
*/
|
|
23
|
+
export declare const processRoutesFromExtracted: (graph: KnowledgeGraph, extractedRoutes: ExtractedRoute[], ctx: ResolutionContext, onProgress?: (current: number, total: number) => void) => Promise<void>;
|