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.
Files changed (76) hide show
  1. package/README.md +50 -59
  2. package/dist/cli/ai-context.js +9 -9
  3. package/dist/cli/analyze.js +139 -47
  4. package/dist/cli/augment.d.ts +13 -0
  5. package/dist/cli/augment.js +33 -0
  6. package/dist/cli/claude-hooks.d.ts +22 -0
  7. package/dist/cli/claude-hooks.js +97 -0
  8. package/dist/cli/eval-server.d.ts +30 -0
  9. package/dist/cli/eval-server.js +372 -0
  10. package/dist/cli/index.js +56 -1
  11. package/dist/cli/mcp.js +9 -0
  12. package/dist/cli/setup.js +184 -5
  13. package/dist/cli/tool.d.ts +37 -0
  14. package/dist/cli/tool.js +91 -0
  15. package/dist/cli/wiki.d.ts +13 -0
  16. package/dist/cli/wiki.js +199 -0
  17. package/dist/core/augmentation/engine.d.ts +26 -0
  18. package/dist/core/augmentation/engine.js +213 -0
  19. package/dist/core/embeddings/embedder.d.ts +2 -2
  20. package/dist/core/embeddings/embedder.js +11 -11
  21. package/dist/core/embeddings/embedding-pipeline.d.ts +2 -1
  22. package/dist/core/embeddings/embedding-pipeline.js +13 -5
  23. package/dist/core/embeddings/types.d.ts +2 -2
  24. package/dist/core/ingestion/call-processor.d.ts +7 -0
  25. package/dist/core/ingestion/call-processor.js +61 -23
  26. package/dist/core/ingestion/community-processor.js +34 -26
  27. package/dist/core/ingestion/filesystem-walker.js +15 -10
  28. package/dist/core/ingestion/heritage-processor.d.ts +6 -0
  29. package/dist/core/ingestion/heritage-processor.js +68 -5
  30. package/dist/core/ingestion/import-processor.d.ts +22 -0
  31. package/dist/core/ingestion/import-processor.js +215 -20
  32. package/dist/core/ingestion/parsing-processor.d.ts +8 -1
  33. package/dist/core/ingestion/parsing-processor.js +66 -25
  34. package/dist/core/ingestion/pipeline.js +104 -40
  35. package/dist/core/ingestion/process-processor.js +1 -1
  36. package/dist/core/ingestion/workers/parse-worker.d.ts +58 -0
  37. package/dist/core/ingestion/workers/parse-worker.js +451 -0
  38. package/dist/core/ingestion/workers/worker-pool.d.ts +22 -0
  39. package/dist/core/ingestion/workers/worker-pool.js +65 -0
  40. package/dist/core/kuzu/kuzu-adapter.d.ts +15 -1
  41. package/dist/core/kuzu/kuzu-adapter.js +177 -63
  42. package/dist/core/kuzu/schema.d.ts +1 -1
  43. package/dist/core/kuzu/schema.js +3 -0
  44. package/dist/core/search/bm25-index.js +13 -15
  45. package/dist/core/wiki/generator.d.ts +96 -0
  46. package/dist/core/wiki/generator.js +674 -0
  47. package/dist/core/wiki/graph-queries.d.ts +80 -0
  48. package/dist/core/wiki/graph-queries.js +238 -0
  49. package/dist/core/wiki/html-viewer.d.ts +10 -0
  50. package/dist/core/wiki/html-viewer.js +297 -0
  51. package/dist/core/wiki/llm-client.d.ts +36 -0
  52. package/dist/core/wiki/llm-client.js +111 -0
  53. package/dist/core/wiki/prompts.d.ts +53 -0
  54. package/dist/core/wiki/prompts.js +174 -0
  55. package/dist/mcp/core/embedder.js +4 -2
  56. package/dist/mcp/core/kuzu-adapter.d.ts +2 -1
  57. package/dist/mcp/core/kuzu-adapter.js +35 -15
  58. package/dist/mcp/local/local-backend.d.ts +54 -1
  59. package/dist/mcp/local/local-backend.js +716 -171
  60. package/dist/mcp/resources.d.ts +1 -1
  61. package/dist/mcp/resources.js +111 -73
  62. package/dist/mcp/server.d.ts +1 -1
  63. package/dist/mcp/server.js +91 -22
  64. package/dist/mcp/tools.js +80 -61
  65. package/dist/storage/git.d.ts +0 -1
  66. package/dist/storage/git.js +1 -8
  67. package/dist/storage/repo-manager.d.ts +17 -0
  68. package/dist/storage/repo-manager.js +26 -0
  69. package/hooks/claude/gitnexus-hook.cjs +135 -0
  70. package/hooks/claude/pre-tool-use.sh +78 -0
  71. package/hooks/claude/session-start.sh +42 -0
  72. package/package.json +4 -2
  73. package/skills/debugging.md +24 -22
  74. package/skills/exploring.md +26 -24
  75. package/skills/impact-analysis.md +19 -13
  76. 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
- const isDev = process.env.NODE_ENV !== 'production';
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
- const astCache = createASTCache(50);
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
- await processParsing(graph, files, symbolTable, astCache, (current, total, filePath) => {
67
- const parsingProgress = 30 + ((current / total) * 40);
68
- onProgress({
69
- phase: 'parsing',
70
- percent: Math.round(parsingProgress),
71
- message: 'Parsing code definitions...',
72
- detail: filePath,
73
- stats: { filesProcessed: current, totalFiles: total, nodesCreated: graph.nodeCount },
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
- await processImports(graph, files, astCache, importMap, (current, total) => {
83
- const importProgress = 70 + ((current / total) * 12);
84
- onProgress({
85
- phase: 'imports',
86
- percent: Math.round(importProgress),
87
- message: 'Resolving imports...',
88
- stats: { filesProcessed: current, totalFiles: total, nodesCreated: graph.nodeCount },
89
- });
90
- }, repoPath);
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
- await processCalls(graph, files, astCache, symbolTable, importMap, (current, total) => {
102
- const callProgress = 82 + ((current / total) * 10);
103
- onProgress({
104
- phase: 'calls',
105
- percent: Math.round(callProgress),
106
- message: 'Tracing function calls...',
107
- stats: { filesProcessed: current, totalFiles: total, nodesCreated: graph.nodeCount },
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
- await processHeritage(graph, files, astCache, symbolTable, (current, total) => {
117
- const heritageProgress = 88 + ((current / total) * 4);
118
- onProgress({
119
- phase: 'heritage',
120
- percent: Math.round(heritageProgress),
121
- message: 'Extracting class inheritance...',
122
- stats: { filesProcessed: current, totalFiles: total, nodesCreated: graph.nodeCount },
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 !== 'production';
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 {};