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.
Files changed (110) hide show
  1. package/README.md +181 -0
  2. package/dist/cli/ai-context.d.ts +21 -0
  3. package/dist/cli/ai-context.js +219 -0
  4. package/dist/cli/analyze.d.ts +10 -0
  5. package/dist/cli/analyze.js +118 -0
  6. package/dist/cli/clean.d.ts +8 -0
  7. package/dist/cli/clean.js +29 -0
  8. package/dist/cli/index.d.ts +2 -0
  9. package/dist/cli/index.js +42 -0
  10. package/dist/cli/list.d.ts +6 -0
  11. package/dist/cli/list.js +27 -0
  12. package/dist/cli/mcp.d.ts +7 -0
  13. package/dist/cli/mcp.js +85 -0
  14. package/dist/cli/serve.d.ts +3 -0
  15. package/dist/cli/serve.js +5 -0
  16. package/dist/cli/status.d.ts +6 -0
  17. package/dist/cli/status.js +27 -0
  18. package/dist/config/ignore-service.d.ts +1 -0
  19. package/dist/config/ignore-service.js +208 -0
  20. package/dist/config/supported-languages.d.ts +11 -0
  21. package/dist/config/supported-languages.js +15 -0
  22. package/dist/core/embeddings/embedder.d.ts +60 -0
  23. package/dist/core/embeddings/embedder.js +205 -0
  24. package/dist/core/embeddings/embedding-pipeline.d.ts +50 -0
  25. package/dist/core/embeddings/embedding-pipeline.js +321 -0
  26. package/dist/core/embeddings/index.d.ts +9 -0
  27. package/dist/core/embeddings/index.js +9 -0
  28. package/dist/core/embeddings/text-generator.d.ts +24 -0
  29. package/dist/core/embeddings/text-generator.js +182 -0
  30. package/dist/core/embeddings/types.d.ts +87 -0
  31. package/dist/core/embeddings/types.js +32 -0
  32. package/dist/core/graph/graph.d.ts +2 -0
  33. package/dist/core/graph/graph.js +61 -0
  34. package/dist/core/graph/types.d.ts +50 -0
  35. package/dist/core/graph/types.js +1 -0
  36. package/dist/core/ingestion/ast-cache.d.ts +11 -0
  37. package/dist/core/ingestion/ast-cache.js +34 -0
  38. package/dist/core/ingestion/call-processor.d.ts +8 -0
  39. package/dist/core/ingestion/call-processor.js +269 -0
  40. package/dist/core/ingestion/cluster-enricher.d.ts +38 -0
  41. package/dist/core/ingestion/cluster-enricher.js +170 -0
  42. package/dist/core/ingestion/community-processor.d.ts +39 -0
  43. package/dist/core/ingestion/community-processor.js +269 -0
  44. package/dist/core/ingestion/entry-point-scoring.d.ts +39 -0
  45. package/dist/core/ingestion/entry-point-scoring.js +235 -0
  46. package/dist/core/ingestion/filesystem-walker.d.ts +5 -0
  47. package/dist/core/ingestion/filesystem-walker.js +26 -0
  48. package/dist/core/ingestion/framework-detection.d.ts +38 -0
  49. package/dist/core/ingestion/framework-detection.js +183 -0
  50. package/dist/core/ingestion/heritage-processor.d.ts +14 -0
  51. package/dist/core/ingestion/heritage-processor.js +134 -0
  52. package/dist/core/ingestion/import-processor.d.ts +8 -0
  53. package/dist/core/ingestion/import-processor.js +490 -0
  54. package/dist/core/ingestion/parsing-processor.d.ts +8 -0
  55. package/dist/core/ingestion/parsing-processor.js +249 -0
  56. package/dist/core/ingestion/pipeline.d.ts +2 -0
  57. package/dist/core/ingestion/pipeline.js +228 -0
  58. package/dist/core/ingestion/process-processor.d.ts +51 -0
  59. package/dist/core/ingestion/process-processor.js +278 -0
  60. package/dist/core/ingestion/structure-processor.d.ts +2 -0
  61. package/dist/core/ingestion/structure-processor.js +36 -0
  62. package/dist/core/ingestion/symbol-table.d.ts +33 -0
  63. package/dist/core/ingestion/symbol-table.js +38 -0
  64. package/dist/core/ingestion/tree-sitter-queries.d.ts +11 -0
  65. package/dist/core/ingestion/tree-sitter-queries.js +319 -0
  66. package/dist/core/ingestion/utils.d.ts +10 -0
  67. package/dist/core/ingestion/utils.js +44 -0
  68. package/dist/core/kuzu/csv-generator.d.ts +22 -0
  69. package/dist/core/kuzu/csv-generator.js +272 -0
  70. package/dist/core/kuzu/kuzu-adapter.d.ts +81 -0
  71. package/dist/core/kuzu/kuzu-adapter.js +568 -0
  72. package/dist/core/kuzu/schema.d.ts +53 -0
  73. package/dist/core/kuzu/schema.js +380 -0
  74. package/dist/core/search/bm25-index.d.ts +22 -0
  75. package/dist/core/search/bm25-index.js +52 -0
  76. package/dist/core/search/hybrid-search.d.ts +49 -0
  77. package/dist/core/search/hybrid-search.js +118 -0
  78. package/dist/core/tree-sitter/parser-loader.d.ts +4 -0
  79. package/dist/core/tree-sitter/parser-loader.js +42 -0
  80. package/dist/lib/utils.d.ts +1 -0
  81. package/dist/lib/utils.js +3 -0
  82. package/dist/mcp/core/embedder.d.ts +27 -0
  83. package/dist/mcp/core/embedder.js +93 -0
  84. package/dist/mcp/core/kuzu-adapter.d.ts +23 -0
  85. package/dist/mcp/core/kuzu-adapter.js +62 -0
  86. package/dist/mcp/local/local-backend.d.ts +73 -0
  87. package/dist/mcp/local/local-backend.js +752 -0
  88. package/dist/mcp/resources.d.ts +31 -0
  89. package/dist/mcp/resources.js +279 -0
  90. package/dist/mcp/server.d.ts +12 -0
  91. package/dist/mcp/server.js +130 -0
  92. package/dist/mcp/staleness.d.ts +15 -0
  93. package/dist/mcp/staleness.js +29 -0
  94. package/dist/mcp/tools.d.ts +24 -0
  95. package/dist/mcp/tools.js +160 -0
  96. package/dist/server/api.d.ts +6 -0
  97. package/dist/server/api.js +156 -0
  98. package/dist/storage/git.d.ts +7 -0
  99. package/dist/storage/git.js +39 -0
  100. package/dist/storage/repo-manager.d.ts +61 -0
  101. package/dist/storage/repo-manager.js +106 -0
  102. package/dist/types/pipeline.d.ts +28 -0
  103. package/dist/types/pipeline.js +16 -0
  104. package/package.json +80 -0
  105. package/skills/debugging.md +104 -0
  106. package/skills/exploring.md +112 -0
  107. package/skills/impact-analysis.md +114 -0
  108. package/skills/refactoring.md +119 -0
  109. package/vendor/leiden/index.cjs +355 -0
  110. 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,3 @@
1
+ export const generateId = (label, name) => {
2
+ return `${label}:${name}`;
3
+ };
@@ -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
+ }