gitnexus 1.0.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 +181 -0
- package/dist/cli/ai-context.d.ts +21 -0
- package/dist/cli/ai-context.js +219 -0
- package/dist/cli/analyze.d.ts +10 -0
- package/dist/cli/analyze.js +118 -0
- package/dist/cli/clean.d.ts +8 -0
- package/dist/cli/clean.js +29 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +42 -0
- package/dist/cli/list.d.ts +6 -0
- package/dist/cli/list.js +27 -0
- package/dist/cli/mcp.d.ts +7 -0
- package/dist/cli/mcp.js +85 -0
- package/dist/cli/serve.d.ts +3 -0
- package/dist/cli/serve.js +5 -0
- package/dist/cli/status.d.ts +6 -0
- package/dist/cli/status.js +27 -0
- package/dist/config/ignore-service.d.ts +1 -0
- package/dist/config/ignore-service.js +208 -0
- package/dist/config/supported-languages.d.ts +11 -0
- package/dist/config/supported-languages.js +15 -0
- package/dist/core/embeddings/embedder.d.ts +60 -0
- package/dist/core/embeddings/embedder.js +205 -0
- package/dist/core/embeddings/embedding-pipeline.d.ts +50 -0
- package/dist/core/embeddings/embedding-pipeline.js +321 -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 +61 -0
- package/dist/core/graph/types.d.ts +50 -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 +34 -0
- package/dist/core/ingestion/call-processor.d.ts +8 -0
- package/dist/core/ingestion/call-processor.js +269 -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 +269 -0
- package/dist/core/ingestion/entry-point-scoring.d.ts +39 -0
- package/dist/core/ingestion/entry-point-scoring.js +235 -0
- package/dist/core/ingestion/filesystem-walker.d.ts +5 -0
- package/dist/core/ingestion/filesystem-walker.js +26 -0
- package/dist/core/ingestion/framework-detection.d.ts +38 -0
- package/dist/core/ingestion/framework-detection.js +183 -0
- package/dist/core/ingestion/heritage-processor.d.ts +14 -0
- package/dist/core/ingestion/heritage-processor.js +134 -0
- package/dist/core/ingestion/import-processor.d.ts +8 -0
- package/dist/core/ingestion/import-processor.js +490 -0
- package/dist/core/ingestion/parsing-processor.d.ts +8 -0
- package/dist/core/ingestion/parsing-processor.js +249 -0
- package/dist/core/ingestion/pipeline.d.ts +2 -0
- package/dist/core/ingestion/pipeline.js +228 -0
- package/dist/core/ingestion/process-processor.d.ts +51 -0
- package/dist/core/ingestion/process-processor.js +278 -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 +33 -0
- package/dist/core/ingestion/symbol-table.js +38 -0
- package/dist/core/ingestion/tree-sitter-queries.d.ts +11 -0
- package/dist/core/ingestion/tree-sitter-queries.js +319 -0
- package/dist/core/ingestion/utils.d.ts +10 -0
- package/dist/core/ingestion/utils.js +44 -0
- package/dist/core/kuzu/csv-generator.d.ts +22 -0
- package/dist/core/kuzu/csv-generator.js +272 -0
- package/dist/core/kuzu/kuzu-adapter.d.ts +81 -0
- package/dist/core/kuzu/kuzu-adapter.js +568 -0
- package/dist/core/kuzu/schema.d.ts +53 -0
- package/dist/core/kuzu/schema.js +380 -0
- package/dist/core/search/bm25-index.d.ts +22 -0
- package/dist/core/search/bm25-index.js +52 -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 +4 -0
- package/dist/core/tree-sitter/parser-loader.js +42 -0
- package/dist/lib/utils.d.ts +1 -0
- package/dist/lib/utils.js +3 -0
- package/dist/mcp/core/embedder.d.ts +27 -0
- package/dist/mcp/core/embedder.js +93 -0
- package/dist/mcp/core/kuzu-adapter.d.ts +23 -0
- package/dist/mcp/core/kuzu-adapter.js +62 -0
- package/dist/mcp/local/local-backend.d.ts +73 -0
- package/dist/mcp/local/local-backend.js +752 -0
- package/dist/mcp/resources.d.ts +31 -0
- package/dist/mcp/resources.js +279 -0
- package/dist/mcp/server.d.ts +12 -0
- package/dist/mcp/server.js +130 -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 +160 -0
- package/dist/server/api.d.ts +6 -0
- package/dist/server/api.js +156 -0
- package/dist/storage/git.d.ts +7 -0
- package/dist/storage/git.js +39 -0
- package/dist/storage/repo-manager.d.ts +61 -0
- package/dist/storage/repo-manager.js +106 -0
- package/dist/types/pipeline.d.ts +28 -0
- package/dist/types/pipeline.js +16 -0
- package/package.json +80 -0
- package/skills/debugging.md +104 -0
- package/skills/exploring.md +112 -0
- package/skills/impact-analysis.md +114 -0
- package/skills/refactoring.md +119 -0
- package/vendor/leiden/index.cjs +355 -0
- package/vendor/leiden/utils.cjs +392 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import Parser from 'tree-sitter';
|
|
2
|
+
import JavaScript from 'tree-sitter-javascript';
|
|
3
|
+
import TypeScript from 'tree-sitter-typescript';
|
|
4
|
+
import Python from 'tree-sitter-python';
|
|
5
|
+
import Java from 'tree-sitter-java';
|
|
6
|
+
import C from 'tree-sitter-c';
|
|
7
|
+
import CPP from 'tree-sitter-cpp';
|
|
8
|
+
import CSharp from 'tree-sitter-c-sharp';
|
|
9
|
+
import Go from 'tree-sitter-go';
|
|
10
|
+
import Rust from 'tree-sitter-rust';
|
|
11
|
+
import { SupportedLanguages } from '../../config/supported-languages.js';
|
|
12
|
+
let parser = null;
|
|
13
|
+
const languageMap = {
|
|
14
|
+
[SupportedLanguages.JavaScript]: JavaScript,
|
|
15
|
+
[SupportedLanguages.TypeScript]: TypeScript.typescript,
|
|
16
|
+
[`${SupportedLanguages.TypeScript}:tsx`]: TypeScript.tsx,
|
|
17
|
+
[SupportedLanguages.Python]: Python,
|
|
18
|
+
[SupportedLanguages.Java]: Java,
|
|
19
|
+
[SupportedLanguages.C]: C,
|
|
20
|
+
[SupportedLanguages.CPlusPlus]: CPP,
|
|
21
|
+
[SupportedLanguages.CSharp]: CSharp,
|
|
22
|
+
[SupportedLanguages.Go]: Go,
|
|
23
|
+
[SupportedLanguages.Rust]: Rust,
|
|
24
|
+
};
|
|
25
|
+
export const loadParser = async () => {
|
|
26
|
+
if (parser)
|
|
27
|
+
return parser;
|
|
28
|
+
parser = new Parser();
|
|
29
|
+
return parser;
|
|
30
|
+
};
|
|
31
|
+
export const loadLanguage = async (language, filePath) => {
|
|
32
|
+
if (!parser)
|
|
33
|
+
await loadParser();
|
|
34
|
+
const key = language === SupportedLanguages.TypeScript && filePath?.endsWith('.tsx')
|
|
35
|
+
? `${language}:tsx`
|
|
36
|
+
: language;
|
|
37
|
+
const lang = languageMap[key];
|
|
38
|
+
if (!lang) {
|
|
39
|
+
throw new Error(`Unsupported language: ${language}`);
|
|
40
|
+
}
|
|
41
|
+
parser.setLanguage(lang);
|
|
42
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const generateId: (label: string, name: string) => string;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embedder Module (Read-Only)
|
|
3
|
+
*
|
|
4
|
+
* Singleton factory for transformers.js embedding pipeline.
|
|
5
|
+
* For MCP, we only need to compute query embeddings, not batch embed.
|
|
6
|
+
*/
|
|
7
|
+
import { type FeatureExtractionPipeline } from '@huggingface/transformers';
|
|
8
|
+
/**
|
|
9
|
+
* Initialize the embedding model (lazy, on first search)
|
|
10
|
+
*/
|
|
11
|
+
export declare const initEmbedder: () => Promise<FeatureExtractionPipeline>;
|
|
12
|
+
/**
|
|
13
|
+
* Check if embedder is ready
|
|
14
|
+
*/
|
|
15
|
+
export declare const isEmbedderReady: () => boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Embed a query text for semantic search
|
|
18
|
+
*/
|
|
19
|
+
export declare const embedQuery: (query: string) => Promise<number[]>;
|
|
20
|
+
/**
|
|
21
|
+
* Get embedding dimensions
|
|
22
|
+
*/
|
|
23
|
+
export declare const getEmbeddingDims: () => number;
|
|
24
|
+
/**
|
|
25
|
+
* Cleanup embedder
|
|
26
|
+
*/
|
|
27
|
+
export declare const disposeEmbedder: () => Promise<void>;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embedder Module (Read-Only)
|
|
3
|
+
*
|
|
4
|
+
* Singleton factory for transformers.js embedding pipeline.
|
|
5
|
+
* For MCP, we only need to compute query embeddings, not batch embed.
|
|
6
|
+
*/
|
|
7
|
+
import { pipeline, env } from '@huggingface/transformers';
|
|
8
|
+
// Model config
|
|
9
|
+
const MODEL_ID = 'Snowflake/snowflake-arctic-embed-xs';
|
|
10
|
+
const EMBEDDING_DIMS = 384;
|
|
11
|
+
// Module-level state for singleton pattern
|
|
12
|
+
let embedderInstance = null;
|
|
13
|
+
let isInitializing = false;
|
|
14
|
+
let initPromise = null;
|
|
15
|
+
/**
|
|
16
|
+
* Initialize the embedding model (lazy, on first search)
|
|
17
|
+
*/
|
|
18
|
+
export const initEmbedder = async () => {
|
|
19
|
+
if (embedderInstance) {
|
|
20
|
+
return embedderInstance;
|
|
21
|
+
}
|
|
22
|
+
if (isInitializing && initPromise) {
|
|
23
|
+
return initPromise;
|
|
24
|
+
}
|
|
25
|
+
isInitializing = true;
|
|
26
|
+
initPromise = (async () => {
|
|
27
|
+
try {
|
|
28
|
+
env.allowLocalModels = false;
|
|
29
|
+
console.error('GitNexus: Loading embedding model (first search may take a moment)...');
|
|
30
|
+
// Try WebGPU first (Windows DirectX12), fall back to CPU
|
|
31
|
+
const devicesToTry = ['webgpu', 'cpu'];
|
|
32
|
+
for (const device of devicesToTry) {
|
|
33
|
+
try {
|
|
34
|
+
embedderInstance = await pipeline('feature-extraction', MODEL_ID, {
|
|
35
|
+
device: device,
|
|
36
|
+
dtype: 'fp32',
|
|
37
|
+
});
|
|
38
|
+
console.error(`GitNexus: Embedding model loaded (${device})`);
|
|
39
|
+
return embedderInstance;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
if (device === 'cpu')
|
|
43
|
+
throw new Error('Failed to load embedding model');
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
throw new Error('No suitable device found');
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
isInitializing = false;
|
|
50
|
+
initPromise = null;
|
|
51
|
+
embedderInstance = null;
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
isInitializing = false;
|
|
56
|
+
}
|
|
57
|
+
})();
|
|
58
|
+
return initPromise;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Check if embedder is ready
|
|
62
|
+
*/
|
|
63
|
+
export const isEmbedderReady = () => embedderInstance !== null;
|
|
64
|
+
/**
|
|
65
|
+
* Embed a query text for semantic search
|
|
66
|
+
*/
|
|
67
|
+
export const embedQuery = async (query) => {
|
|
68
|
+
const embedder = await initEmbedder();
|
|
69
|
+
const result = await embedder(query, {
|
|
70
|
+
pooling: 'mean',
|
|
71
|
+
normalize: true,
|
|
72
|
+
});
|
|
73
|
+
return Array.from(result.data);
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Get embedding dimensions
|
|
77
|
+
*/
|
|
78
|
+
export const getEmbeddingDims = () => EMBEDDING_DIMS;
|
|
79
|
+
/**
|
|
80
|
+
* Cleanup embedder
|
|
81
|
+
*/
|
|
82
|
+
export const disposeEmbedder = async () => {
|
|
83
|
+
if (embedderInstance) {
|
|
84
|
+
try {
|
|
85
|
+
if ('dispose' in embedderInstance && typeof embedderInstance.dispose === 'function') {
|
|
86
|
+
await embedderInstance.dispose();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch { }
|
|
90
|
+
embedderInstance = null;
|
|
91
|
+
initPromise = null;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KuzuDB Adapter (Persistent Connection)
|
|
3
|
+
*
|
|
4
|
+
* Holds a single database connection for the lifetime of the MCP session.
|
|
5
|
+
* This is safe since the watcher has been removed -- only one process
|
|
6
|
+
* accesses the database at a time.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Initialize with a persistent connection to the database
|
|
10
|
+
*/
|
|
11
|
+
export declare const initKuzu: (path: string) => Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Execute a query using the persistent connection
|
|
14
|
+
*/
|
|
15
|
+
export declare const executeQuery: (cypher: string) => Promise<any[]>;
|
|
16
|
+
/**
|
|
17
|
+
* Close the persistent connection
|
|
18
|
+
*/
|
|
19
|
+
export declare const closeKuzu: () => Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Check if the database connection is active
|
|
22
|
+
*/
|
|
23
|
+
export declare const isKuzuReady: () => boolean;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KuzuDB Adapter (Persistent Connection)
|
|
3
|
+
*
|
|
4
|
+
* Holds a single database connection for the lifetime of the MCP session.
|
|
5
|
+
* This is safe since the watcher has been removed -- only one process
|
|
6
|
+
* accesses the database at a time.
|
|
7
|
+
*/
|
|
8
|
+
import fs from 'fs/promises';
|
|
9
|
+
import kuzu from 'kuzu';
|
|
10
|
+
let db = null;
|
|
11
|
+
let conn = null;
|
|
12
|
+
/**
|
|
13
|
+
* Initialize with a persistent connection to the database
|
|
14
|
+
*/
|
|
15
|
+
export const initKuzu = async (path) => {
|
|
16
|
+
if (conn)
|
|
17
|
+
return; // Already initialized
|
|
18
|
+
// Check if database exists
|
|
19
|
+
try {
|
|
20
|
+
await fs.stat(path);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
throw new Error(`KuzuDB not found at ${path}. Run: gitnexus analyze`);
|
|
24
|
+
}
|
|
25
|
+
db = new kuzu.Database(path);
|
|
26
|
+
conn = new kuzu.Connection(db);
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Execute a query using the persistent connection
|
|
30
|
+
*/
|
|
31
|
+
export const executeQuery = async (cypher) => {
|
|
32
|
+
if (!conn) {
|
|
33
|
+
throw new Error('KuzuDB not initialized. Call initKuzu first.');
|
|
34
|
+
}
|
|
35
|
+
const queryResult = await conn.query(cypher);
|
|
36
|
+
const result = Array.isArray(queryResult) ? queryResult[0] : queryResult;
|
|
37
|
+
const rows = await result.getAll();
|
|
38
|
+
return rows;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Close the persistent connection
|
|
42
|
+
*/
|
|
43
|
+
export const closeKuzu = async () => {
|
|
44
|
+
if (conn) {
|
|
45
|
+
try {
|
|
46
|
+
await conn.close();
|
|
47
|
+
}
|
|
48
|
+
catch { }
|
|
49
|
+
conn = null;
|
|
50
|
+
}
|
|
51
|
+
if (db) {
|
|
52
|
+
try {
|
|
53
|
+
await db.close();
|
|
54
|
+
}
|
|
55
|
+
catch { }
|
|
56
|
+
db = null;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Check if the database connection is active
|
|
61
|
+
*/
|
|
62
|
+
export const isKuzuReady = () => conn !== null && db !== null;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local Backend
|
|
3
|
+
*
|
|
4
|
+
* Provides tool implementations using local .gitnexus/ index.
|
|
5
|
+
* This enables MCP to work without the browser.
|
|
6
|
+
*/
|
|
7
|
+
export interface RepoMeta {
|
|
8
|
+
repoPath: string;
|
|
9
|
+
lastCommit: string;
|
|
10
|
+
indexedAt: string;
|
|
11
|
+
stats?: {
|
|
12
|
+
files?: number;
|
|
13
|
+
nodes?: number;
|
|
14
|
+
edges?: number;
|
|
15
|
+
communities?: number;
|
|
16
|
+
processes?: number;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export interface IndexedRepo {
|
|
20
|
+
repoPath: string;
|
|
21
|
+
storagePath: string;
|
|
22
|
+
kuzuPath: string;
|
|
23
|
+
metaPath: string;
|
|
24
|
+
meta: RepoMeta;
|
|
25
|
+
}
|
|
26
|
+
export declare function findRepo(startPath: string): Promise<IndexedRepo | null>;
|
|
27
|
+
export interface CodebaseContext {
|
|
28
|
+
projectName: string;
|
|
29
|
+
stats: {
|
|
30
|
+
fileCount: number;
|
|
31
|
+
functionCount: number;
|
|
32
|
+
classCount: number;
|
|
33
|
+
interfaceCount: number;
|
|
34
|
+
methodCount: number;
|
|
35
|
+
communityCount: number;
|
|
36
|
+
processCount: number;
|
|
37
|
+
};
|
|
38
|
+
hotspots: Array<{
|
|
39
|
+
name: string;
|
|
40
|
+
type: string;
|
|
41
|
+
filePath: string;
|
|
42
|
+
connections: number;
|
|
43
|
+
}>;
|
|
44
|
+
folderTree: string;
|
|
45
|
+
}
|
|
46
|
+
export declare class LocalBackend {
|
|
47
|
+
private repo;
|
|
48
|
+
private _context;
|
|
49
|
+
private initialized;
|
|
50
|
+
init(cwd: string): Promise<boolean>;
|
|
51
|
+
private ensureInitialized;
|
|
52
|
+
get context(): CodebaseContext | null;
|
|
53
|
+
get isReady(): boolean;
|
|
54
|
+
get repoPath(): string | null;
|
|
55
|
+
get storagePath(): string | null;
|
|
56
|
+
get meta(): any;
|
|
57
|
+
callTool(method: string, params: any): Promise<any>;
|
|
58
|
+
private search;
|
|
59
|
+
/**
|
|
60
|
+
* BM25 keyword search helper - uses KuzuDB FTS for always-fresh results
|
|
61
|
+
*/
|
|
62
|
+
private bm25Search;
|
|
63
|
+
/**
|
|
64
|
+
* Semantic vector search helper
|
|
65
|
+
*/
|
|
66
|
+
private semanticSearch;
|
|
67
|
+
private cypher;
|
|
68
|
+
private overview;
|
|
69
|
+
private explore;
|
|
70
|
+
private impact;
|
|
71
|
+
private analyze;
|
|
72
|
+
disconnect(): Promise<void>;
|
|
73
|
+
}
|