@zuvia-software-solutions/code-mapper 1.4.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/README.md +215 -0
- package/dist/cli/ai-context.d.ts +19 -0
- package/dist/cli/ai-context.js +168 -0
- package/dist/cli/analyze.d.ts +7 -0
- package/dist/cli/analyze.js +325 -0
- package/dist/cli/augment.d.ts +7 -0
- package/dist/cli/augment.js +27 -0
- package/dist/cli/clean.d.ts +5 -0
- package/dist/cli/clean.js +56 -0
- package/dist/cli/eval-server.d.ts +25 -0
- package/dist/cli/eval-server.js +365 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.js +102 -0
- package/dist/cli/lazy-action.d.ts +6 -0
- package/dist/cli/lazy-action.js +19 -0
- package/dist/cli/list.d.ts +2 -0
- package/dist/cli/list.js +27 -0
- package/dist/cli/mcp.d.ts +8 -0
- package/dist/cli/mcp.js +35 -0
- package/dist/cli/refresh.d.ts +12 -0
- package/dist/cli/refresh.js +165 -0
- package/dist/cli/serve.d.ts +5 -0
- package/dist/cli/serve.js +8 -0
- package/dist/cli/setup.d.ts +6 -0
- package/dist/cli/setup.js +218 -0
- package/dist/cli/status.d.ts +2 -0
- package/dist/cli/status.js +33 -0
- package/dist/cli/tool.d.ts +28 -0
- package/dist/cli/tool.js +87 -0
- package/dist/config/ignore-service.d.ts +32 -0
- package/dist/config/ignore-service.js +282 -0
- package/dist/config/supported-languages.d.ts +23 -0
- package/dist/config/supported-languages.js +52 -0
- package/dist/core/augmentation/engine.d.ts +22 -0
- package/dist/core/augmentation/engine.js +232 -0
- package/dist/core/embeddings/embedder.d.ts +35 -0
- package/dist/core/embeddings/embedder.js +171 -0
- package/dist/core/embeddings/embedding-pipeline.d.ts +41 -0
- package/dist/core/embeddings/embedding-pipeline.js +402 -0
- package/dist/core/embeddings/index.d.ts +5 -0
- package/dist/core/embeddings/index.js +6 -0
- package/dist/core/embeddings/text-generator.d.ts +20 -0
- package/dist/core/embeddings/text-generator.js +159 -0
- package/dist/core/embeddings/types.d.ts +60 -0
- package/dist/core/embeddings/types.js +23 -0
- package/dist/core/graph/graph.d.ts +4 -0
- package/dist/core/graph/graph.js +65 -0
- package/dist/core/graph/types.d.ts +69 -0
- package/dist/core/graph/types.js +3 -0
- package/dist/core/incremental/child-process.d.ts +8 -0
- package/dist/core/incremental/child-process.js +649 -0
- package/dist/core/incremental/refresh-coordinator.d.ts +32 -0
- package/dist/core/incremental/refresh-coordinator.js +147 -0
- package/dist/core/incremental/types.d.ts +78 -0
- package/dist/core/incremental/types.js +153 -0
- package/dist/core/incremental/watcher.d.ts +63 -0
- package/dist/core/incremental/watcher.js +338 -0
- package/dist/core/ingestion/ast-cache.d.ts +12 -0
- package/dist/core/ingestion/ast-cache.js +34 -0
- package/dist/core/ingestion/call-processor.d.ts +34 -0
- package/dist/core/ingestion/call-processor.js +937 -0
- package/dist/core/ingestion/call-routing.d.ts +40 -0
- package/dist/core/ingestion/call-routing.js +97 -0
- package/dist/core/ingestion/cluster-enricher.d.ts +30 -0
- package/dist/core/ingestion/cluster-enricher.js +151 -0
- package/dist/core/ingestion/community-processor.d.ts +26 -0
- package/dist/core/ingestion/community-processor.js +272 -0
- package/dist/core/ingestion/constants.d.ts +5 -0
- package/dist/core/ingestion/constants.js +8 -0
- package/dist/core/ingestion/entry-point-scoring.d.ts +23 -0
- package/dist/core/ingestion/entry-point-scoring.js +317 -0
- package/dist/core/ingestion/export-detection.d.ts +11 -0
- package/dist/core/ingestion/export-detection.js +203 -0
- package/dist/core/ingestion/filesystem-walker.d.ts +18 -0
- package/dist/core/ingestion/filesystem-walker.js +64 -0
- package/dist/core/ingestion/framework-detection.d.ts +42 -0
- package/dist/core/ingestion/framework-detection.js +405 -0
- package/dist/core/ingestion/heritage-processor.d.ts +15 -0
- package/dist/core/ingestion/heritage-processor.js +237 -0
- package/dist/core/ingestion/import-processor.d.ts +31 -0
- package/dist/core/ingestion/import-processor.js +416 -0
- package/dist/core/ingestion/language-config.d.ts +32 -0
- package/dist/core/ingestion/language-config.js +161 -0
- package/dist/core/ingestion/mro-processor.d.ts +32 -0
- package/dist/core/ingestion/mro-processor.js +343 -0
- package/dist/core/ingestion/named-binding-extraction.d.ts +51 -0
- package/dist/core/ingestion/named-binding-extraction.js +343 -0
- package/dist/core/ingestion/parsing-processor.d.ts +20 -0
- package/dist/core/ingestion/parsing-processor.js +282 -0
- package/dist/core/ingestion/pipeline.d.ts +3 -0
- package/dist/core/ingestion/pipeline.js +416 -0
- package/dist/core/ingestion/process-processor.d.ts +42 -0
- package/dist/core/ingestion/process-processor.js +357 -0
- package/dist/core/ingestion/resolution-context.d.ts +40 -0
- package/dist/core/ingestion/resolution-context.js +171 -0
- package/dist/core/ingestion/resolvers/csharp.d.ts +10 -0
- package/dist/core/ingestion/resolvers/csharp.js +101 -0
- package/dist/core/ingestion/resolvers/go.d.ts +8 -0
- package/dist/core/ingestion/resolvers/go.js +33 -0
- package/dist/core/ingestion/resolvers/index.d.ts +14 -0
- package/dist/core/ingestion/resolvers/index.js +10 -0
- package/dist/core/ingestion/resolvers/jvm.d.ts +9 -0
- package/dist/core/ingestion/resolvers/jvm.js +74 -0
- package/dist/core/ingestion/resolvers/php.d.ts +7 -0
- package/dist/core/ingestion/resolvers/php.js +30 -0
- package/dist/core/ingestion/resolvers/ruby.d.ts +9 -0
- package/dist/core/ingestion/resolvers/ruby.js +13 -0
- package/dist/core/ingestion/resolvers/rust.d.ts +5 -0
- package/dist/core/ingestion/resolvers/rust.js +62 -0
- package/dist/core/ingestion/resolvers/standard.d.ts +16 -0
- package/dist/core/ingestion/resolvers/standard.js +144 -0
- package/dist/core/ingestion/resolvers/utils.d.ts +18 -0
- package/dist/core/ingestion/resolvers/utils.js +113 -0
- package/dist/core/ingestion/structure-processor.d.ts +4 -0
- package/dist/core/ingestion/structure-processor.js +39 -0
- package/dist/core/ingestion/symbol-table.d.ts +34 -0
- package/dist/core/ingestion/symbol-table.js +48 -0
- package/dist/core/ingestion/tree-sitter-queries.d.ts +20 -0
- package/dist/core/ingestion/tree-sitter-queries.js +691 -0
- package/dist/core/ingestion/type-env.d.ts +52 -0
- package/dist/core/ingestion/type-env.js +349 -0
- package/dist/core/ingestion/type-extractors/c-cpp.d.ts +4 -0
- package/dist/core/ingestion/type-extractors/c-cpp.js +214 -0
- package/dist/core/ingestion/type-extractors/csharp.d.ts +4 -0
- package/dist/core/ingestion/type-extractors/csharp.js +224 -0
- package/dist/core/ingestion/type-extractors/go.d.ts +4 -0
- package/dist/core/ingestion/type-extractors/go.js +261 -0
- package/dist/core/ingestion/type-extractors/index.d.ts +20 -0
- package/dist/core/ingestion/type-extractors/index.js +30 -0
- package/dist/core/ingestion/type-extractors/jvm.d.ts +5 -0
- package/dist/core/ingestion/type-extractors/jvm.js +386 -0
- package/dist/core/ingestion/type-extractors/php.d.ts +4 -0
- package/dist/core/ingestion/type-extractors/php.js +280 -0
- package/dist/core/ingestion/type-extractors/python.d.ts +4 -0
- package/dist/core/ingestion/type-extractors/python.js +175 -0
- package/dist/core/ingestion/type-extractors/ruby.d.ts +12 -0
- package/dist/core/ingestion/type-extractors/ruby.js +218 -0
- package/dist/core/ingestion/type-extractors/rust.d.ts +4 -0
- package/dist/core/ingestion/type-extractors/rust.js +290 -0
- package/dist/core/ingestion/type-extractors/shared.d.ts +81 -0
- package/dist/core/ingestion/type-extractors/shared.js +322 -0
- package/dist/core/ingestion/type-extractors/swift.d.ts +4 -0
- package/dist/core/ingestion/type-extractors/swift.js +140 -0
- package/dist/core/ingestion/type-extractors/types.d.ts +111 -0
- package/dist/core/ingestion/type-extractors/types.js +4 -0
- package/dist/core/ingestion/type-extractors/typescript.d.ts +4 -0
- package/dist/core/ingestion/type-extractors/typescript.js +227 -0
- package/dist/core/ingestion/utils.d.ts +73 -0
- package/dist/core/ingestion/utils.js +992 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +99 -0
- package/dist/core/ingestion/workers/parse-worker.js +1055 -0
- package/dist/core/ingestion/workers/worker-pool.d.ts +15 -0
- package/dist/core/ingestion/workers/worker-pool.js +123 -0
- package/dist/core/lbug/csv-generator.d.ts +28 -0
- package/dist/core/lbug/csv-generator.js +355 -0
- package/dist/core/lbug/lbug-adapter.d.ts +96 -0
- package/dist/core/lbug/lbug-adapter.js +753 -0
- package/dist/core/lbug/schema.d.ts +46 -0
- package/dist/core/lbug/schema.js +402 -0
- package/dist/core/search/bm25-index.d.ts +20 -0
- package/dist/core/search/bm25-index.js +123 -0
- package/dist/core/search/hybrid-search.d.ts +32 -0
- package/dist/core/search/hybrid-search.js +131 -0
- package/dist/core/search/query-cache.d.ts +18 -0
- package/dist/core/search/query-cache.js +47 -0
- package/dist/core/search/query-expansion.d.ts +19 -0
- package/dist/core/search/query-expansion.js +75 -0
- package/dist/core/search/reranker.d.ts +29 -0
- package/dist/core/search/reranker.js +122 -0
- package/dist/core/search/types.d.ts +154 -0
- package/dist/core/search/types.js +51 -0
- package/dist/core/semantic/tsgo-service.d.ts +67 -0
- package/dist/core/semantic/tsgo-service.js +355 -0
- package/dist/core/tree-sitter/parser-loader.d.ts +12 -0
- package/dist/core/tree-sitter/parser-loader.js +71 -0
- package/dist/lib/memory-guard.d.ts +35 -0
- package/dist/lib/memory-guard.js +70 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.js +6 -0
- package/dist/mcp/compatible-stdio-transport.d.ts +32 -0
- package/dist/mcp/compatible-stdio-transport.js +209 -0
- package/dist/mcp/core/embedder.d.ts +24 -0
- package/dist/mcp/core/embedder.js +168 -0
- package/dist/mcp/core/lbug-adapter.d.ts +29 -0
- package/dist/mcp/core/lbug-adapter.js +330 -0
- package/dist/mcp/local/local-backend.d.ts +188 -0
- package/dist/mcp/local/local-backend.js +2759 -0
- package/dist/mcp/resources.d.ts +22 -0
- package/dist/mcp/resources.js +379 -0
- package/dist/mcp/server.d.ts +10 -0
- package/dist/mcp/server.js +217 -0
- package/dist/mcp/staleness.d.ts +10 -0
- package/dist/mcp/staleness.js +25 -0
- package/dist/mcp/tools.d.ts +21 -0
- package/dist/mcp/tools.js +202 -0
- package/dist/server/api.d.ts +5 -0
- package/dist/server/api.js +340 -0
- package/dist/server/mcp-http.d.ts +7 -0
- package/dist/server/mcp-http.js +95 -0
- package/dist/storage/git.d.ts +6 -0
- package/dist/storage/git.js +35 -0
- package/dist/storage/repo-manager.d.ts +87 -0
- package/dist/storage/repo-manager.js +249 -0
- package/dist/types/pipeline.d.ts +35 -0
- package/dist/types/pipeline.js +20 -0
- package/hooks/claude/code-mapper-hook.cjs +238 -0
- package/hooks/claude/pre-tool-use.sh +79 -0
- package/hooks/claude/session-start.sh +42 -0
- package/models/mlx-embedder.py +185 -0
- package/package.json +100 -0
- package/scripts/patch-tree-sitter-swift.cjs +74 -0
- package/vendor/leiden/index.cjs +355 -0
- package/vendor/leiden/utils.cjs +392 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
// code-mapper/src/core/embeddings/text-generator.ts
|
|
2
|
+
/**
|
|
3
|
+
* @file text-generator.ts
|
|
4
|
+
* @description Pure functions to generate embedding text from code nodes,
|
|
5
|
+
* combining node metadata with code snippets for semantic matching
|
|
6
|
+
*/
|
|
7
|
+
import { DEFAULT_EMBEDDING_CONFIG } from './types.js';
|
|
8
|
+
/** Extract filename from a file path */
|
|
9
|
+
const getFileName = (filePath) => {
|
|
10
|
+
const parts = filePath.split('/');
|
|
11
|
+
return parts[parts.length - 1] || filePath;
|
|
12
|
+
};
|
|
13
|
+
/** Extract directory path from a file path */
|
|
14
|
+
const getDirectory = (filePath) => {
|
|
15
|
+
const parts = filePath.split('/');
|
|
16
|
+
parts.pop();
|
|
17
|
+
return parts.join('/') || '';
|
|
18
|
+
};
|
|
19
|
+
/** Truncate content to max length, preserving word boundaries */
|
|
20
|
+
const truncateContent = (content, maxLength) => {
|
|
21
|
+
if (content.length <= maxLength) {
|
|
22
|
+
return content;
|
|
23
|
+
}
|
|
24
|
+
// Find last space before maxLength to avoid cutting words
|
|
25
|
+
const truncated = content.slice(0, maxLength);
|
|
26
|
+
const lastSpace = truncated.lastIndexOf(' ');
|
|
27
|
+
if (lastSpace > maxLength * 0.8) {
|
|
28
|
+
return truncated.slice(0, lastSpace) + '...';
|
|
29
|
+
}
|
|
30
|
+
return truncated + '...';
|
|
31
|
+
};
|
|
32
|
+
/** Clean code content — remove excessive whitespace while preserving structure */
|
|
33
|
+
const cleanContent = (content) => {
|
|
34
|
+
return content
|
|
35
|
+
// Normalize line endings
|
|
36
|
+
.replace(/\r\n/g, '\n')
|
|
37
|
+
// Remove excessive blank lines (more than 2)
|
|
38
|
+
.replace(/\n{3,}/g, '\n\n')
|
|
39
|
+
// Trim each line
|
|
40
|
+
.split('\n')
|
|
41
|
+
.map(line => line.trimEnd())
|
|
42
|
+
.join('\n')
|
|
43
|
+
.trim();
|
|
44
|
+
};
|
|
45
|
+
/** Generate embedding text for a Function node */
|
|
46
|
+
const generateFunctionText = (node, maxSnippetLength) => {
|
|
47
|
+
const parts = [
|
|
48
|
+
`Function: ${node.name}`,
|
|
49
|
+
`File: ${getFileName(node.filePath)}`,
|
|
50
|
+
];
|
|
51
|
+
const dir = getDirectory(node.filePath);
|
|
52
|
+
if (dir) {
|
|
53
|
+
parts.push(`Directory: ${dir}`);
|
|
54
|
+
}
|
|
55
|
+
if (node.content) {
|
|
56
|
+
const cleanedContent = cleanContent(node.content);
|
|
57
|
+
const snippet = truncateContent(cleanedContent, maxSnippetLength);
|
|
58
|
+
parts.push('', snippet);
|
|
59
|
+
}
|
|
60
|
+
return parts.join('\n');
|
|
61
|
+
};
|
|
62
|
+
/** Generate embedding text for a Class node */
|
|
63
|
+
const generateClassText = (node, maxSnippetLength) => {
|
|
64
|
+
const parts = [
|
|
65
|
+
`Class: ${node.name}`,
|
|
66
|
+
`File: ${getFileName(node.filePath)}`,
|
|
67
|
+
];
|
|
68
|
+
const dir = getDirectory(node.filePath);
|
|
69
|
+
if (dir) {
|
|
70
|
+
parts.push(`Directory: ${dir}`);
|
|
71
|
+
}
|
|
72
|
+
if (node.content) {
|
|
73
|
+
const cleanedContent = cleanContent(node.content);
|
|
74
|
+
const snippet = truncateContent(cleanedContent, maxSnippetLength);
|
|
75
|
+
parts.push('', snippet);
|
|
76
|
+
}
|
|
77
|
+
return parts.join('\n');
|
|
78
|
+
};
|
|
79
|
+
/** Generate embedding text for a Method node */
|
|
80
|
+
const generateMethodText = (node, maxSnippetLength) => {
|
|
81
|
+
const parts = [
|
|
82
|
+
`Method: ${node.name}`,
|
|
83
|
+
`File: ${getFileName(node.filePath)}`,
|
|
84
|
+
];
|
|
85
|
+
const dir = getDirectory(node.filePath);
|
|
86
|
+
if (dir) {
|
|
87
|
+
parts.push(`Directory: ${dir}`);
|
|
88
|
+
}
|
|
89
|
+
if (node.content) {
|
|
90
|
+
const cleanedContent = cleanContent(node.content);
|
|
91
|
+
const snippet = truncateContent(cleanedContent, maxSnippetLength);
|
|
92
|
+
parts.push('', snippet);
|
|
93
|
+
}
|
|
94
|
+
return parts.join('\n');
|
|
95
|
+
};
|
|
96
|
+
/** Generate embedding text for an Interface node */
|
|
97
|
+
const generateInterfaceText = (node, maxSnippetLength) => {
|
|
98
|
+
const parts = [
|
|
99
|
+
`Interface: ${node.name}`,
|
|
100
|
+
`File: ${getFileName(node.filePath)}`,
|
|
101
|
+
];
|
|
102
|
+
const dir = getDirectory(node.filePath);
|
|
103
|
+
if (dir) {
|
|
104
|
+
parts.push(`Directory: ${dir}`);
|
|
105
|
+
}
|
|
106
|
+
if (node.content) {
|
|
107
|
+
const cleanedContent = cleanContent(node.content);
|
|
108
|
+
const snippet = truncateContent(cleanedContent, maxSnippetLength);
|
|
109
|
+
parts.push('', snippet);
|
|
110
|
+
}
|
|
111
|
+
return parts.join('\n');
|
|
112
|
+
};
|
|
113
|
+
/** Generate embedding text for a File node (uses shorter snippet) */
|
|
114
|
+
const generateFileText = (node, maxSnippetLength) => {
|
|
115
|
+
const parts = [
|
|
116
|
+
`File: ${node.name}`,
|
|
117
|
+
`Path: ${node.filePath}`,
|
|
118
|
+
];
|
|
119
|
+
if (node.content) {
|
|
120
|
+
const cleanedContent = cleanContent(node.content);
|
|
121
|
+
// Files can be very long — cap at 300 chars
|
|
122
|
+
const snippet = truncateContent(cleanedContent, Math.min(maxSnippetLength, 300));
|
|
123
|
+
parts.push('', snippet);
|
|
124
|
+
}
|
|
125
|
+
return parts.join('\n');
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* Generate embedding text for any embeddable node (dispatches by label)
|
|
129
|
+
* @param node - The node to generate text for
|
|
130
|
+
* @param config - Optional configuration for max snippet length
|
|
131
|
+
* @returns Text suitable for embedding
|
|
132
|
+
*/
|
|
133
|
+
export const generateEmbeddingText = (node, config = {}) => {
|
|
134
|
+
const maxSnippetLength = config.maxSnippetLength ?? DEFAULT_EMBEDDING_CONFIG.maxSnippetLength;
|
|
135
|
+
switch (node.label) {
|
|
136
|
+
case 'Function':
|
|
137
|
+
return generateFunctionText(node, maxSnippetLength);
|
|
138
|
+
case 'Class':
|
|
139
|
+
return generateClassText(node, maxSnippetLength);
|
|
140
|
+
case 'Method':
|
|
141
|
+
return generateMethodText(node, maxSnippetLength);
|
|
142
|
+
case 'Interface':
|
|
143
|
+
return generateInterfaceText(node, maxSnippetLength);
|
|
144
|
+
case 'File':
|
|
145
|
+
return generateFileText(node, maxSnippetLength);
|
|
146
|
+
default:
|
|
147
|
+
// Fallback for any other embeddable type
|
|
148
|
+
return `${node.label}: ${node.name}\nPath: ${node.filePath}`;
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* Generate embedding texts for a batch of nodes
|
|
153
|
+
* @param nodes - Nodes to generate text for
|
|
154
|
+
* @param config - Optional configuration
|
|
155
|
+
* @returns Texts in the same order as input nodes
|
|
156
|
+
*/
|
|
157
|
+
export const generateBatchEmbeddingTexts = (nodes, config = {}) => {
|
|
158
|
+
return nodes.map(node => generateEmbeddingText(node, config));
|
|
159
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/** @file types.ts @description Type definitions for embedding generation and semantic search */
|
|
2
|
+
export declare const EMBEDDABLE_LABELS: readonly ["Function", "Class", "Method", "Interface"];
|
|
3
|
+
export type EmbeddableLabel = typeof EMBEDDABLE_LABELS[number];
|
|
4
|
+
/** Check if a label is embeddable */
|
|
5
|
+
export declare const isEmbeddableLabel: (label: string) => label is EmbeddableLabel;
|
|
6
|
+
/** Embedding pipeline lifecycle phases */
|
|
7
|
+
export type EmbeddingPhase = 'idle' | 'loading-model' | 'embedding' | 'indexing' | 'ready' | 'error';
|
|
8
|
+
/** Progress state emitted during embedding pipeline execution */
|
|
9
|
+
export interface EmbeddingProgress {
|
|
10
|
+
phase: EmbeddingPhase;
|
|
11
|
+
percent: number;
|
|
12
|
+
modelDownloadPercent?: number;
|
|
13
|
+
nodesProcessed?: number;
|
|
14
|
+
totalNodes?: number;
|
|
15
|
+
currentBatch?: number;
|
|
16
|
+
totalBatches?: number;
|
|
17
|
+
error?: string;
|
|
18
|
+
}
|
|
19
|
+
/** Configuration for the embedding pipeline */
|
|
20
|
+
export interface EmbeddingConfig {
|
|
21
|
+
/** Model identifier for transformers.js */
|
|
22
|
+
modelId: string;
|
|
23
|
+
/** Nodes to embed per batch */
|
|
24
|
+
batchSize: number;
|
|
25
|
+
/** Embedding vector dimensions */
|
|
26
|
+
dimensions: number;
|
|
27
|
+
/** Inference device — 'auto' tries GPU first (DirectML on Windows, CUDA on Linux), falls back to CPU */
|
|
28
|
+
device: 'auto' | 'dml' | 'cuda' | 'cpu' | 'wasm';
|
|
29
|
+
/** Max characters of code snippet to include */
|
|
30
|
+
maxSnippetLength: number;
|
|
31
|
+
}
|
|
32
|
+
export declare const DEFAULT_EMBEDDING_CONFIG: EmbeddingConfig;
|
|
33
|
+
/** Result from a semantic vector search */
|
|
34
|
+
export interface SemanticSearchResult {
|
|
35
|
+
nodeId: string;
|
|
36
|
+
name: string;
|
|
37
|
+
label: string;
|
|
38
|
+
filePath: string;
|
|
39
|
+
distance: number;
|
|
40
|
+
startLine?: number;
|
|
41
|
+
endLine?: number;
|
|
42
|
+
}
|
|
43
|
+
/** Minimal node data for embedding (from LadybugDB query) */
|
|
44
|
+
export interface EmbeddableNode {
|
|
45
|
+
id: string;
|
|
46
|
+
name: string;
|
|
47
|
+
label: string;
|
|
48
|
+
filePath: string;
|
|
49
|
+
content: string;
|
|
50
|
+
startLine?: number;
|
|
51
|
+
endLine?: number;
|
|
52
|
+
}
|
|
53
|
+
/** Model download progress from transformers.js */
|
|
54
|
+
export interface ModelProgress {
|
|
55
|
+
status: 'initiate' | 'download' | 'progress' | 'done' | 'ready';
|
|
56
|
+
file?: string;
|
|
57
|
+
progress?: number;
|
|
58
|
+
loaded?: number;
|
|
59
|
+
total?: number;
|
|
60
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// code-mapper/src/core/embeddings/types.ts
|
|
2
|
+
/** @file types.ts @description Type definitions for embedding generation and semantic search */
|
|
3
|
+
// Node labels eligible for semantic embedding
|
|
4
|
+
// File nodes removed — their embeddings were low quality (import headers, license text)
|
|
5
|
+
// and polluted semantic search. BM25 FTS already searches file content effectively.
|
|
6
|
+
export const EMBEDDABLE_LABELS = [
|
|
7
|
+
'Function',
|
|
8
|
+
'Class',
|
|
9
|
+
'Method',
|
|
10
|
+
'Interface',
|
|
11
|
+
];
|
|
12
|
+
/** Check if a label is embeddable */
|
|
13
|
+
export const isEmbeddableLabel = (label) => EMBEDDABLE_LABELS.includes(label);
|
|
14
|
+
// Jina Code 1.5B MLX — 1.54B params on Apple Silicon Metal
|
|
15
|
+
// Matryoshka truncation to 256 dims (trained at this dim, <1% quality loss vs 1536)
|
|
16
|
+
// Task-specific prefixes: nl2code queries, code passages
|
|
17
|
+
export const DEFAULT_EMBEDDING_CONFIG = {
|
|
18
|
+
modelId: 'jinaai/jina-code-embeddings-1.5b-mlx',
|
|
19
|
+
batchSize: 48,
|
|
20
|
+
dimensions: 256, // Matryoshka — 6x smaller vectors, 3x faster search vs 768
|
|
21
|
+
device: 'auto',
|
|
22
|
+
maxSnippetLength: 16000, // 32K token context — embed much more code for better understanding
|
|
23
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** @file graph.ts @description Factory for creating in-memory knowledge graphs backed by Maps for O(1) lookups */
|
|
2
|
+
import { KnowledgeGraph } from './types.js';
|
|
3
|
+
/** Create a new empty KnowledgeGraph instance */
|
|
4
|
+
export declare const createKnowledgeGraph: () => KnowledgeGraph;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// code-mapper/src/core/graph/graph.ts
|
|
2
|
+
/** @file graph.ts @description Factory for creating in-memory knowledge graphs backed by Maps for O(1) lookups */
|
|
3
|
+
/** Create a new empty KnowledgeGraph instance */
|
|
4
|
+
export const createKnowledgeGraph = () => {
|
|
5
|
+
const nodeMap = new Map();
|
|
6
|
+
const relationshipMap = new Map();
|
|
7
|
+
const addNode = (node) => {
|
|
8
|
+
if (!nodeMap.has(node.id)) {
|
|
9
|
+
nodeMap.set(node.id, node);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
const addRelationship = (relationship) => {
|
|
13
|
+
if (!relationshipMap.has(relationship.id)) {
|
|
14
|
+
relationshipMap.set(relationship.id, relationship);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
/** Remove a single node and all relationships involving it */
|
|
18
|
+
const removeNode = (nodeId) => {
|
|
19
|
+
if (!nodeMap.has(nodeId))
|
|
20
|
+
return false;
|
|
21
|
+
nodeMap.delete(nodeId);
|
|
22
|
+
// Remove all relationships referencing this node
|
|
23
|
+
for (const [relId, rel] of relationshipMap) {
|
|
24
|
+
if (rel.sourceId === nodeId || rel.targetId === nodeId) {
|
|
25
|
+
relationshipMap.delete(relId);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return true;
|
|
29
|
+
};
|
|
30
|
+
/** Remove all nodes (and their relationships) belonging to a file */
|
|
31
|
+
const removeNodesByFile = (filePath) => {
|
|
32
|
+
let removed = 0;
|
|
33
|
+
for (const [nodeId, node] of nodeMap) {
|
|
34
|
+
if (node.properties?.filePath === filePath) {
|
|
35
|
+
removeNode(nodeId);
|
|
36
|
+
removed++;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return removed;
|
|
40
|
+
};
|
|
41
|
+
return {
|
|
42
|
+
get nodes() {
|
|
43
|
+
return Array.from(nodeMap.values());
|
|
44
|
+
},
|
|
45
|
+
get relationships() {
|
|
46
|
+
return Array.from(relationshipMap.values());
|
|
47
|
+
},
|
|
48
|
+
iterNodes: () => nodeMap.values(),
|
|
49
|
+
iterRelationships: () => relationshipMap.values(),
|
|
50
|
+
forEachNode(fn) { nodeMap.forEach(fn); },
|
|
51
|
+
forEachRelationship(fn) { relationshipMap.forEach(fn); },
|
|
52
|
+
getNode: (id) => nodeMap.get(id),
|
|
53
|
+
// O(1) count getters
|
|
54
|
+
get nodeCount() {
|
|
55
|
+
return nodeMap.size;
|
|
56
|
+
},
|
|
57
|
+
get relationshipCount() {
|
|
58
|
+
return relationshipMap.size;
|
|
59
|
+
},
|
|
60
|
+
addNode,
|
|
61
|
+
addRelationship,
|
|
62
|
+
removeNode,
|
|
63
|
+
removeNodesByFile,
|
|
64
|
+
};
|
|
65
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/** @file types.ts @description Core type definitions for the knowledge graph: nodes, relationships, and the graph interface */
|
|
2
|
+
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';
|
|
3
|
+
import { SupportedLanguages } from '../../config/supported-languages.js';
|
|
4
|
+
export type NodeProperties = {
|
|
5
|
+
name: string;
|
|
6
|
+
filePath: string;
|
|
7
|
+
startLine?: number;
|
|
8
|
+
endLine?: number;
|
|
9
|
+
language?: SupportedLanguages;
|
|
10
|
+
isExported?: boolean;
|
|
11
|
+
astFrameworkMultiplier?: number;
|
|
12
|
+
astFrameworkReason?: string;
|
|
13
|
+
heuristicLabel?: string;
|
|
14
|
+
cohesion?: number;
|
|
15
|
+
symbolCount?: number;
|
|
16
|
+
keywords?: string[];
|
|
17
|
+
description?: string;
|
|
18
|
+
enrichedBy?: 'heuristic' | 'llm';
|
|
19
|
+
processType?: 'intra_community' | 'cross_community';
|
|
20
|
+
stepCount?: number;
|
|
21
|
+
communities?: string[];
|
|
22
|
+
entryPointId?: string;
|
|
23
|
+
terminalId?: string;
|
|
24
|
+
entryPointScore?: number;
|
|
25
|
+
entryPointReason?: string;
|
|
26
|
+
parameterCount?: number;
|
|
27
|
+
returnType?: string;
|
|
28
|
+
};
|
|
29
|
+
export type RelationshipType = 'CONTAINS' | 'CALLS' | 'INHERITS' | 'OVERRIDES' | 'IMPORTS' | 'USES' | 'DEFINES' | 'DECORATES' | 'IMPLEMENTS' | 'EXTENDS' | 'HAS_METHOD' | 'MEMBER_OF' | 'STEP_IN_PROCESS' | 'DEPENDS_ON' | 'PROVIDES';
|
|
30
|
+
export interface GraphNode {
|
|
31
|
+
id: string;
|
|
32
|
+
label: NodeLabel;
|
|
33
|
+
properties: NodeProperties;
|
|
34
|
+
}
|
|
35
|
+
export interface GraphRelationship {
|
|
36
|
+
id: string;
|
|
37
|
+
sourceId: string;
|
|
38
|
+
targetId: string;
|
|
39
|
+
type: RelationshipType;
|
|
40
|
+
/** Confidence score 0-1 (1.0 = certain, lower = uncertain) */
|
|
41
|
+
confidence: number;
|
|
42
|
+
/** Resolution reason: 'import-resolved', 'same-file', 'fuzzy-global', or empty for non-CALLS */
|
|
43
|
+
reason: string;
|
|
44
|
+
/** Step number for STEP_IN_PROCESS relationships (1-indexed) */
|
|
45
|
+
step?: number;
|
|
46
|
+
/** Source line number where the call occurs (for CALLS relationships) */
|
|
47
|
+
callLine?: number;
|
|
48
|
+
}
|
|
49
|
+
export interface KnowledgeGraph {
|
|
50
|
+
/** Returns a full array copy — prefer iterNodes() for iteration */
|
|
51
|
+
nodes: GraphNode[];
|
|
52
|
+
/** Returns a full array copy — prefer iterRelationships() for iteration */
|
|
53
|
+
relationships: GraphRelationship[];
|
|
54
|
+
/** Zero-copy iterator over nodes */
|
|
55
|
+
iterNodes: () => IterableIterator<GraphNode>;
|
|
56
|
+
/** Zero-copy iterator over relationships */
|
|
57
|
+
iterRelationships: () => IterableIterator<GraphRelationship>;
|
|
58
|
+
/** Zero-copy forEach — avoids iterator protocol overhead in hot loops */
|
|
59
|
+
forEachNode: (fn: (node: GraphNode) => void) => void;
|
|
60
|
+
forEachRelationship: (fn: (rel: GraphRelationship) => void) => void;
|
|
61
|
+
/** Lookup a single node by id — O(1) */
|
|
62
|
+
getNode: (id: string) => GraphNode | undefined;
|
|
63
|
+
nodeCount: number;
|
|
64
|
+
relationshipCount: number;
|
|
65
|
+
addNode: (node: GraphNode) => void;
|
|
66
|
+
addRelationship: (relationship: GraphRelationship) => void;
|
|
67
|
+
removeNode: (nodeId: string) => boolean;
|
|
68
|
+
removeNodesByFile: (filePath: string) => number;
|
|
69
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file child-process.ts
|
|
3
|
+
* @description Forked child process entry point for incremental DB updates. Opens
|
|
4
|
+
* LadybugDB in READ-WRITE mode, deletes stale nodes for changed files, re-parses
|
|
5
|
+
* them with tree-sitter, inserts new nodes/edges, resolves imports/calls/heritage,
|
|
6
|
+
* and rebuilds FTS indexes. Communicates with the parent via structured IPC messages
|
|
7
|
+
*/
|
|
8
|
+
export {};
|