gitnexus 1.1.8 → 1.2.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 +50 -59
- package/dist/cli/ai-context.js +9 -9
- package/dist/cli/analyze.js +139 -47
- package/dist/cli/augment.d.ts +13 -0
- package/dist/cli/augment.js +33 -0
- package/dist/cli/claude-hooks.d.ts +22 -0
- package/dist/cli/claude-hooks.js +97 -0
- package/dist/cli/eval-server.d.ts +30 -0
- package/dist/cli/eval-server.js +372 -0
- package/dist/cli/index.js +56 -1
- package/dist/cli/mcp.js +9 -0
- package/dist/cli/setup.js +184 -5
- package/dist/cli/tool.d.ts +37 -0
- package/dist/cli/tool.js +91 -0
- package/dist/cli/wiki.d.ts +13 -0
- package/dist/cli/wiki.js +199 -0
- package/dist/core/augmentation/engine.d.ts +26 -0
- package/dist/core/augmentation/engine.js +213 -0
- package/dist/core/embeddings/embedder.d.ts +2 -2
- package/dist/core/embeddings/embedder.js +11 -11
- package/dist/core/embeddings/embedding-pipeline.d.ts +2 -1
- package/dist/core/embeddings/embedding-pipeline.js +13 -5
- package/dist/core/embeddings/types.d.ts +2 -2
- package/dist/core/ingestion/call-processor.d.ts +7 -0
- package/dist/core/ingestion/call-processor.js +61 -23
- package/dist/core/ingestion/community-processor.js +34 -26
- package/dist/core/ingestion/filesystem-walker.js +15 -10
- package/dist/core/ingestion/heritage-processor.d.ts +6 -0
- package/dist/core/ingestion/heritage-processor.js +68 -5
- package/dist/core/ingestion/import-processor.d.ts +22 -0
- package/dist/core/ingestion/import-processor.js +215 -20
- package/dist/core/ingestion/parsing-processor.d.ts +8 -1
- package/dist/core/ingestion/parsing-processor.js +66 -25
- package/dist/core/ingestion/pipeline.js +104 -40
- package/dist/core/ingestion/process-processor.js +1 -1
- package/dist/core/ingestion/workers/parse-worker.d.ts +58 -0
- package/dist/core/ingestion/workers/parse-worker.js +451 -0
- package/dist/core/ingestion/workers/worker-pool.d.ts +22 -0
- package/dist/core/ingestion/workers/worker-pool.js +65 -0
- package/dist/core/kuzu/kuzu-adapter.d.ts +15 -1
- package/dist/core/kuzu/kuzu-adapter.js +177 -63
- package/dist/core/kuzu/schema.d.ts +1 -1
- package/dist/core/kuzu/schema.js +3 -0
- package/dist/core/search/bm25-index.js +13 -15
- package/dist/core/wiki/generator.d.ts +96 -0
- package/dist/core/wiki/generator.js +674 -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 +36 -0
- package/dist/core/wiki/llm-client.js +111 -0
- package/dist/core/wiki/prompts.d.ts +53 -0
- package/dist/core/wiki/prompts.js +174 -0
- package/dist/mcp/core/embedder.js +4 -2
- package/dist/mcp/core/kuzu-adapter.d.ts +2 -1
- package/dist/mcp/core/kuzu-adapter.js +35 -15
- package/dist/mcp/local/local-backend.d.ts +54 -1
- package/dist/mcp/local/local-backend.js +716 -171
- package/dist/mcp/resources.d.ts +1 -1
- package/dist/mcp/resources.js +111 -73
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +91 -22
- package/dist/mcp/tools.js +80 -61
- package/dist/storage/git.d.ts +0 -1
- package/dist/storage/git.js +1 -8
- package/dist/storage/repo-manager.d.ts +17 -0
- package/dist/storage/repo-manager.js +26 -0
- package/hooks/claude/gitnexus-hook.cjs +135 -0
- package/hooks/claude/pre-tool-use.sh +78 -0
- package/hooks/claude/session-start.sh +42 -0
- package/package.json +4 -2
- package/skills/debugging.md +24 -22
- package/skills/exploring.md +26 -24
- package/skills/impact-analysis.md +19 -13
- package/skills/refactoring.md +37 -26
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
import { createKnowledgeGraph } from '../graph/graph.js';
|
|
2
2
|
import { processStructure } from './structure-processor.js';
|
|
3
3
|
import { processParsing } from './parsing-processor.js';
|
|
4
|
-
import { processImports, createImportMap } from './import-processor.js';
|
|
5
|
-
import { processCalls } from './call-processor.js';
|
|
6
|
-
import { processHeritage } from './heritage-processor.js';
|
|
4
|
+
import { processImports, processImportsFromExtracted, createImportMap } from './import-processor.js';
|
|
5
|
+
import { processCalls, processCallsFromExtracted } from './call-processor.js';
|
|
6
|
+
import { processHeritage, processHeritageFromExtracted } from './heritage-processor.js';
|
|
7
7
|
import { processCommunities } from './community-processor.js';
|
|
8
8
|
import { processProcesses } from './process-processor.js';
|
|
9
9
|
import { createSymbolTable } from './symbol-table.js';
|
|
10
10
|
import { createASTCache } from './ast-cache.js';
|
|
11
11
|
import { walkRepository } from './filesystem-walker.js';
|
|
12
|
-
|
|
12
|
+
import { createWorkerPool } from './workers/worker-pool.js';
|
|
13
|
+
const isDev = process.env.NODE_ENV === 'development';
|
|
13
14
|
export const runPipelineFromRepo = async (repoPath, onProgress) => {
|
|
14
15
|
const graph = createKnowledgeGraph();
|
|
15
16
|
const fileContents = new Map();
|
|
16
17
|
const symbolTable = createSymbolTable();
|
|
17
|
-
|
|
18
|
+
// AST cache sized after file scan — start with a placeholder, resize after we know file count
|
|
19
|
+
let astCache = createASTCache(50);
|
|
18
20
|
const importMap = createImportMap();
|
|
19
21
|
const cleanup = () => {
|
|
20
22
|
astCache.clear();
|
|
@@ -37,6 +39,8 @@ export const runPipelineFromRepo = async (repoPath, onProgress) => {
|
|
|
37
39
|
});
|
|
38
40
|
});
|
|
39
41
|
files.forEach(f => fileContents.set(f.path, f.content));
|
|
42
|
+
// Resize AST cache to fit all files — avoids re-parsing in import/call/heritage phases
|
|
43
|
+
astCache = createASTCache(files.length);
|
|
40
44
|
onProgress({
|
|
41
45
|
phase: 'extracting',
|
|
42
46
|
percent: 15,
|
|
@@ -63,31 +67,61 @@ export const runPipelineFromRepo = async (repoPath, onProgress) => {
|
|
|
63
67
|
message: 'Parsing code definitions...',
|
|
64
68
|
stats: { filesProcessed: 0, totalFiles: files.length, nodesCreated: graph.nodeCount },
|
|
65
69
|
});
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
70
|
+
// Create worker pool for parallel parsing, with graceful fallback
|
|
71
|
+
let workerPool;
|
|
72
|
+
try {
|
|
73
|
+
const workerUrl = new URL('./workers/parse-worker.js', import.meta.url);
|
|
74
|
+
workerPool = createWorkerPool(workerUrl);
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
// Worker pool creation failed (e.g., single core) — sequential fallback
|
|
78
|
+
}
|
|
79
|
+
let workerData = null;
|
|
80
|
+
try {
|
|
81
|
+
workerData = await processParsing(graph, files, symbolTable, astCache, (current, total, filePath) => {
|
|
82
|
+
const parsingProgress = 30 + ((current / total) * 40);
|
|
83
|
+
onProgress({
|
|
84
|
+
phase: 'parsing',
|
|
85
|
+
percent: Math.round(parsingProgress),
|
|
86
|
+
message: 'Parsing code definitions...',
|
|
87
|
+
detail: filePath,
|
|
88
|
+
stats: { filesProcessed: current, totalFiles: total, nodesCreated: graph.nodeCount },
|
|
89
|
+
});
|
|
90
|
+
}, workerPool);
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
await workerPool?.terminate();
|
|
94
|
+
}
|
|
76
95
|
onProgress({
|
|
77
96
|
phase: 'imports',
|
|
78
97
|
percent: 70,
|
|
79
98
|
message: 'Resolving imports...',
|
|
80
99
|
stats: { filesProcessed: 0, totalFiles: files.length, nodesCreated: graph.nodeCount },
|
|
81
100
|
});
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
101
|
+
if (workerData) {
|
|
102
|
+
// Fast path: imports already extracted by workers, just resolve paths
|
|
103
|
+
await processImportsFromExtracted(graph, files, workerData.imports, importMap, (current, total) => {
|
|
104
|
+
const importProgress = 70 + ((current / total) * 12);
|
|
105
|
+
onProgress({
|
|
106
|
+
phase: 'imports',
|
|
107
|
+
percent: Math.round(importProgress),
|
|
108
|
+
message: 'Resolving imports...',
|
|
109
|
+
stats: { filesProcessed: current, totalFiles: total, nodesCreated: graph.nodeCount },
|
|
110
|
+
});
|
|
111
|
+
}, repoPath);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
// Fallback: full parse + resolve (sequential path)
|
|
115
|
+
await processImports(graph, files, astCache, importMap, (current, total) => {
|
|
116
|
+
const importProgress = 70 + ((current / total) * 12);
|
|
117
|
+
onProgress({
|
|
118
|
+
phase: 'imports',
|
|
119
|
+
percent: Math.round(importProgress),
|
|
120
|
+
message: 'Resolving imports...',
|
|
121
|
+
stats: { filesProcessed: current, totalFiles: total, nodesCreated: graph.nodeCount },
|
|
122
|
+
});
|
|
123
|
+
}, repoPath);
|
|
124
|
+
}
|
|
91
125
|
if (isDev) {
|
|
92
126
|
const importsCount = graph.relationships.filter(r => r.type === 'IMPORTS').length;
|
|
93
127
|
console.log(`📊 Pipeline: After import phase, graph has ${importsCount} IMPORTS relationships (total: ${graph.relationshipCount})`);
|
|
@@ -98,30 +132,60 @@ export const runPipelineFromRepo = async (repoPath, onProgress) => {
|
|
|
98
132
|
message: 'Tracing function calls...',
|
|
99
133
|
stats: { filesProcessed: 0, totalFiles: files.length, nodesCreated: graph.nodeCount },
|
|
100
134
|
});
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
135
|
+
if (workerData) {
|
|
136
|
+
// Fast path: calls already extracted by workers, just resolve targets
|
|
137
|
+
await processCallsFromExtracted(graph, workerData.calls, symbolTable, importMap, (current, total) => {
|
|
138
|
+
const callProgress = 82 + ((current / total) * 10);
|
|
139
|
+
onProgress({
|
|
140
|
+
phase: 'calls',
|
|
141
|
+
percent: Math.round(callProgress),
|
|
142
|
+
message: 'Tracing function calls...',
|
|
143
|
+
stats: { filesProcessed: current, totalFiles: total, nodesCreated: graph.nodeCount },
|
|
144
|
+
});
|
|
108
145
|
});
|
|
109
|
-
}
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
// Fallback: full parse + resolve (sequential path)
|
|
149
|
+
await processCalls(graph, files, astCache, symbolTable, importMap, (current, total) => {
|
|
150
|
+
const callProgress = 82 + ((current / total) * 10);
|
|
151
|
+
onProgress({
|
|
152
|
+
phase: 'calls',
|
|
153
|
+
percent: Math.round(callProgress),
|
|
154
|
+
message: 'Tracing function calls...',
|
|
155
|
+
stats: { filesProcessed: current, totalFiles: total, nodesCreated: graph.nodeCount },
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
}
|
|
110
159
|
onProgress({
|
|
111
160
|
phase: 'heritage',
|
|
112
161
|
percent: 92,
|
|
113
162
|
message: 'Extracting class inheritance...',
|
|
114
163
|
stats: { filesProcessed: 0, totalFiles: files.length, nodesCreated: graph.nodeCount },
|
|
115
164
|
});
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
165
|
+
if (workerData) {
|
|
166
|
+
// Fast path: heritage already extracted by workers, just resolve symbols
|
|
167
|
+
await processHeritageFromExtracted(graph, workerData.heritage, symbolTable, (current, total) => {
|
|
168
|
+
const heritageProgress = 88 + ((current / total) * 4);
|
|
169
|
+
onProgress({
|
|
170
|
+
phase: 'heritage',
|
|
171
|
+
percent: Math.round(heritageProgress),
|
|
172
|
+
message: 'Extracting class inheritance...',
|
|
173
|
+
stats: { filesProcessed: current, totalFiles: total, nodesCreated: graph.nodeCount },
|
|
174
|
+
});
|
|
123
175
|
});
|
|
124
|
-
}
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
// Fallback: full parse + resolve (sequential path)
|
|
179
|
+
await processHeritage(graph, files, astCache, symbolTable, (current, total) => {
|
|
180
|
+
const heritageProgress = 88 + ((current / total) * 4);
|
|
181
|
+
onProgress({
|
|
182
|
+
phase: 'heritage',
|
|
183
|
+
percent: Math.round(heritageProgress),
|
|
184
|
+
message: 'Extracting class inheritance...',
|
|
185
|
+
stats: { filesProcessed: current, totalFiles: total, nodesCreated: graph.nodeCount },
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
}
|
|
125
189
|
onProgress({
|
|
126
190
|
phase: 'communities',
|
|
127
191
|
percent: 92,
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* Processes help agents understand how features work through the codebase.
|
|
11
11
|
*/
|
|
12
12
|
import { calculateEntryPointScore, isTestFile } from './entry-point-scoring.js';
|
|
13
|
-
const isDev = process.env.NODE_ENV
|
|
13
|
+
const isDev = process.env.NODE_ENV === 'development';
|
|
14
14
|
const DEFAULT_CONFIG = {
|
|
15
15
|
maxTraceDepth: 10,
|
|
16
16
|
maxBranching: 4,
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
interface ParsedNode {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
properties: {
|
|
5
|
+
name: string;
|
|
6
|
+
filePath: string;
|
|
7
|
+
startLine: number;
|
|
8
|
+
endLine: number;
|
|
9
|
+
language: string;
|
|
10
|
+
isExported: boolean;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
interface ParsedRelationship {
|
|
14
|
+
id: string;
|
|
15
|
+
sourceId: string;
|
|
16
|
+
targetId: string;
|
|
17
|
+
type: 'DEFINES';
|
|
18
|
+
confidence: number;
|
|
19
|
+
reason: string;
|
|
20
|
+
}
|
|
21
|
+
interface ParsedSymbol {
|
|
22
|
+
filePath: string;
|
|
23
|
+
name: string;
|
|
24
|
+
nodeId: string;
|
|
25
|
+
type: string;
|
|
26
|
+
}
|
|
27
|
+
export interface ExtractedImport {
|
|
28
|
+
filePath: string;
|
|
29
|
+
rawImportPath: string;
|
|
30
|
+
language: string;
|
|
31
|
+
}
|
|
32
|
+
export interface ExtractedCall {
|
|
33
|
+
filePath: string;
|
|
34
|
+
calledName: string;
|
|
35
|
+
/** generateId of enclosing function, or generateId('File', filePath) for top-level */
|
|
36
|
+
sourceId: string;
|
|
37
|
+
}
|
|
38
|
+
export interface ExtractedHeritage {
|
|
39
|
+
filePath: string;
|
|
40
|
+
className: string;
|
|
41
|
+
parentName: string;
|
|
42
|
+
/** 'extends' | 'implements' | 'trait-impl' */
|
|
43
|
+
kind: string;
|
|
44
|
+
}
|
|
45
|
+
export interface ParseWorkerResult {
|
|
46
|
+
nodes: ParsedNode[];
|
|
47
|
+
relationships: ParsedRelationship[];
|
|
48
|
+
symbols: ParsedSymbol[];
|
|
49
|
+
imports: ExtractedImport[];
|
|
50
|
+
calls: ExtractedCall[];
|
|
51
|
+
heritage: ExtractedHeritage[];
|
|
52
|
+
fileCount: number;
|
|
53
|
+
}
|
|
54
|
+
export interface ParseWorkerInput {
|
|
55
|
+
path: string;
|
|
56
|
+
content: string;
|
|
57
|
+
}
|
|
58
|
+
export {};
|