gitnexus 1.4.1 → 1.4.6

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 (169) hide show
  1. package/README.md +215 -194
  2. package/dist/cli/ai-context.d.ts +2 -1
  3. package/dist/cli/ai-context.js +117 -90
  4. package/dist/cli/analyze.d.ts +2 -0
  5. package/dist/cli/analyze.js +57 -30
  6. package/dist/cli/augment.js +1 -1
  7. package/dist/cli/eval-server.d.ts +1 -1
  8. package/dist/cli/eval-server.js +14 -6
  9. package/dist/cli/index.js +18 -25
  10. package/dist/cli/lazy-action.d.ts +6 -0
  11. package/dist/cli/lazy-action.js +18 -0
  12. package/dist/cli/mcp.js +1 -1
  13. package/dist/cli/setup.js +42 -32
  14. package/dist/cli/skill-gen.d.ts +26 -0
  15. package/dist/cli/skill-gen.js +549 -0
  16. package/dist/cli/status.js +13 -4
  17. package/dist/cli/tool.d.ts +3 -2
  18. package/dist/cli/tool.js +48 -13
  19. package/dist/cli/wiki.js +2 -2
  20. package/dist/config/ignore-service.d.ts +25 -0
  21. package/dist/config/ignore-service.js +76 -0
  22. package/dist/config/supported-languages.d.ts +1 -0
  23. package/dist/config/supported-languages.js +1 -1
  24. package/dist/core/augmentation/engine.js +99 -72
  25. package/dist/core/embeddings/embedder.d.ts +1 -1
  26. package/dist/core/embeddings/embedder.js +1 -1
  27. package/dist/core/embeddings/embedding-pipeline.d.ts +3 -3
  28. package/dist/core/embeddings/embedding-pipeline.js +74 -47
  29. package/dist/core/embeddings/types.d.ts +1 -1
  30. package/dist/core/graph/types.d.ts +5 -2
  31. package/dist/core/ingestion/ast-cache.js +3 -2
  32. package/dist/core/ingestion/call-processor.d.ts +5 -7
  33. package/dist/core/ingestion/call-processor.js +430 -283
  34. package/dist/core/ingestion/call-routing.d.ts +53 -0
  35. package/dist/core/ingestion/call-routing.js +108 -0
  36. package/dist/core/ingestion/cluster-enricher.js +16 -16
  37. package/dist/core/ingestion/constants.d.ts +16 -0
  38. package/dist/core/ingestion/constants.js +16 -0
  39. package/dist/core/ingestion/entry-point-scoring.d.ts +2 -1
  40. package/dist/core/ingestion/entry-point-scoring.js +94 -24
  41. package/dist/core/ingestion/export-detection.d.ts +18 -0
  42. package/dist/core/ingestion/export-detection.js +231 -0
  43. package/dist/core/ingestion/filesystem-walker.js +4 -3
  44. package/dist/core/ingestion/framework-detection.d.ts +5 -1
  45. package/dist/core/ingestion/framework-detection.js +48 -8
  46. package/dist/core/ingestion/heritage-processor.d.ts +13 -5
  47. package/dist/core/ingestion/heritage-processor.js +109 -55
  48. package/dist/core/ingestion/import-processor.d.ts +16 -20
  49. package/dist/core/ingestion/import-processor.js +202 -696
  50. package/dist/core/ingestion/language-config.d.ts +46 -0
  51. package/dist/core/ingestion/language-config.js +167 -0
  52. package/dist/core/ingestion/mro-processor.d.ts +45 -0
  53. package/dist/core/ingestion/mro-processor.js +369 -0
  54. package/dist/core/ingestion/named-binding-extraction.d.ts +61 -0
  55. package/dist/core/ingestion/named-binding-extraction.js +363 -0
  56. package/dist/core/ingestion/parsing-processor.d.ts +3 -11
  57. package/dist/core/ingestion/parsing-processor.js +85 -181
  58. package/dist/core/ingestion/pipeline.d.ts +5 -1
  59. package/dist/core/ingestion/pipeline.js +192 -116
  60. package/dist/core/ingestion/process-processor.js +2 -1
  61. package/dist/core/ingestion/resolution-context.d.ts +53 -0
  62. package/dist/core/ingestion/resolution-context.js +132 -0
  63. package/dist/core/ingestion/resolvers/csharp.d.ts +22 -0
  64. package/dist/core/ingestion/resolvers/csharp.js +109 -0
  65. package/dist/core/ingestion/resolvers/go.d.ts +19 -0
  66. package/dist/core/ingestion/resolvers/go.js +42 -0
  67. package/dist/core/ingestion/resolvers/index.d.ts +18 -0
  68. package/dist/core/ingestion/resolvers/index.js +13 -0
  69. package/dist/core/ingestion/resolvers/jvm.d.ts +23 -0
  70. package/dist/core/ingestion/resolvers/jvm.js +87 -0
  71. package/dist/core/ingestion/resolvers/php.d.ts +15 -0
  72. package/dist/core/ingestion/resolvers/php.js +35 -0
  73. package/dist/core/ingestion/resolvers/python.d.ts +19 -0
  74. package/dist/core/ingestion/resolvers/python.js +52 -0
  75. package/dist/core/ingestion/resolvers/ruby.d.ts +12 -0
  76. package/dist/core/ingestion/resolvers/ruby.js +15 -0
  77. package/dist/core/ingestion/resolvers/rust.d.ts +15 -0
  78. package/dist/core/ingestion/resolvers/rust.js +73 -0
  79. package/dist/core/ingestion/resolvers/standard.d.ts +28 -0
  80. package/dist/core/ingestion/resolvers/standard.js +123 -0
  81. package/dist/core/ingestion/resolvers/utils.d.ts +33 -0
  82. package/dist/core/ingestion/resolvers/utils.js +122 -0
  83. package/dist/core/ingestion/symbol-table.d.ts +21 -1
  84. package/dist/core/ingestion/symbol-table.js +40 -12
  85. package/dist/core/ingestion/tree-sitter-queries.d.ts +12 -11
  86. package/dist/core/ingestion/tree-sitter-queries.js +642 -485
  87. package/dist/core/ingestion/type-env.d.ts +49 -0
  88. package/dist/core/ingestion/type-env.js +611 -0
  89. package/dist/core/ingestion/type-extractors/c-cpp.d.ts +2 -0
  90. package/dist/core/ingestion/type-extractors/c-cpp.js +385 -0
  91. package/dist/core/ingestion/type-extractors/csharp.d.ts +2 -0
  92. package/dist/core/ingestion/type-extractors/csharp.js +383 -0
  93. package/dist/core/ingestion/type-extractors/go.d.ts +2 -0
  94. package/dist/core/ingestion/type-extractors/go.js +467 -0
  95. package/dist/core/ingestion/type-extractors/index.d.ts +22 -0
  96. package/dist/core/ingestion/type-extractors/index.js +31 -0
  97. package/dist/core/ingestion/type-extractors/jvm.d.ts +3 -0
  98. package/dist/core/ingestion/type-extractors/jvm.js +681 -0
  99. package/dist/core/ingestion/type-extractors/php.d.ts +2 -0
  100. package/dist/core/ingestion/type-extractors/php.js +549 -0
  101. package/dist/core/ingestion/type-extractors/python.d.ts +2 -0
  102. package/dist/core/ingestion/type-extractors/python.js +406 -0
  103. package/dist/core/ingestion/type-extractors/ruby.d.ts +2 -0
  104. package/dist/core/ingestion/type-extractors/ruby.js +389 -0
  105. package/dist/core/ingestion/type-extractors/rust.d.ts +2 -0
  106. package/dist/core/ingestion/type-extractors/rust.js +449 -0
  107. package/dist/core/ingestion/type-extractors/shared.d.ts +133 -0
  108. package/dist/core/ingestion/type-extractors/shared.js +703 -0
  109. package/dist/core/ingestion/type-extractors/swift.d.ts +2 -0
  110. package/dist/core/ingestion/type-extractors/swift.js +137 -0
  111. package/dist/core/ingestion/type-extractors/types.d.ts +127 -0
  112. package/dist/core/ingestion/type-extractors/types.js +1 -0
  113. package/dist/core/ingestion/type-extractors/typescript.d.ts +2 -0
  114. package/dist/core/ingestion/type-extractors/typescript.js +494 -0
  115. package/dist/core/ingestion/utils.d.ts +98 -0
  116. package/dist/core/ingestion/utils.js +1064 -9
  117. package/dist/core/ingestion/workers/parse-worker.d.ts +38 -4
  118. package/dist/core/ingestion/workers/parse-worker.js +251 -359
  119. package/dist/core/ingestion/workers/worker-pool.js +8 -0
  120. package/dist/core/{kuzu → lbug}/csv-generator.d.ts +1 -1
  121. package/dist/core/{kuzu → lbug}/csv-generator.js +20 -4
  122. package/dist/core/{kuzu/kuzu-adapter.d.ts → lbug/lbug-adapter.d.ts} +19 -19
  123. package/dist/core/{kuzu/kuzu-adapter.js → lbug/lbug-adapter.js} +82 -82
  124. package/dist/core/{kuzu → lbug}/schema.d.ts +4 -4
  125. package/dist/core/{kuzu → lbug}/schema.js +304 -289
  126. package/dist/core/search/bm25-index.d.ts +4 -4
  127. package/dist/core/search/bm25-index.js +17 -16
  128. package/dist/core/search/hybrid-search.d.ts +2 -2
  129. package/dist/core/search/hybrid-search.js +9 -9
  130. package/dist/core/tree-sitter/parser-loader.js +9 -2
  131. package/dist/core/wiki/generator.d.ts +4 -52
  132. package/dist/core/wiki/generator.js +53 -552
  133. package/dist/core/wiki/graph-queries.d.ts +4 -46
  134. package/dist/core/wiki/graph-queries.js +103 -282
  135. package/dist/core/wiki/html-viewer.js +192 -192
  136. package/dist/core/wiki/llm-client.js +11 -73
  137. package/dist/core/wiki/prompts.d.ts +8 -52
  138. package/dist/core/wiki/prompts.js +86 -200
  139. package/dist/mcp/compatible-stdio-transport.d.ts +25 -0
  140. package/dist/mcp/compatible-stdio-transport.js +200 -0
  141. package/dist/mcp/core/{kuzu-adapter.d.ts → lbug-adapter.d.ts} +7 -9
  142. package/dist/mcp/core/{kuzu-adapter.js → lbug-adapter.js} +77 -79
  143. package/dist/mcp/local/local-backend.d.ts +7 -6
  144. package/dist/mcp/local/local-backend.js +176 -147
  145. package/dist/mcp/resources.js +42 -42
  146. package/dist/mcp/server.js +18 -19
  147. package/dist/mcp/tools.js +103 -104
  148. package/dist/server/api.js +12 -12
  149. package/dist/server/mcp-http.d.ts +1 -1
  150. package/dist/server/mcp-http.js +1 -1
  151. package/dist/storage/repo-manager.d.ts +20 -2
  152. package/dist/storage/repo-manager.js +55 -1
  153. package/dist/types/pipeline.d.ts +1 -1
  154. package/hooks/claude/gitnexus-hook.cjs +238 -155
  155. package/hooks/claude/pre-tool-use.sh +79 -79
  156. package/hooks/claude/session-start.sh +42 -42
  157. package/package.json +99 -96
  158. package/scripts/patch-tree-sitter-swift.cjs +74 -74
  159. package/skills/gitnexus-cli.md +82 -82
  160. package/skills/gitnexus-debugging.md +89 -89
  161. package/skills/gitnexus-exploring.md +78 -78
  162. package/skills/gitnexus-guide.md +64 -64
  163. package/skills/gitnexus-impact-analysis.md +97 -97
  164. package/skills/gitnexus-pr-review.md +163 -163
  165. package/skills/gitnexus-refactoring.md +121 -121
  166. package/vendor/leiden/index.cjs +355 -355
  167. package/vendor/leiden/utils.cjs +392 -392
  168. package/dist/core/wiki/diagrams.d.ts +0 -27
  169. package/dist/core/wiki/diagrams.js +0 -163
@@ -256,48 +256,48 @@ async function getProcessesResource(backend, repoName) {
256
256
  * Schema resource — graph structure for Cypher queries
257
257
  */
258
258
  function getSchemaResource() {
259
- return `# GitNexus Graph Schema
260
-
261
- nodes:
262
- - File: Source code files
263
- - Folder: Directory containers
264
- - Function: Functions and arrow functions
265
- - Class: Class definitions
266
- - Interface: Interface/type definitions
267
- - Method: Class methods
268
- - CodeElement: Catch-all for other code elements
269
- - Community: Auto-detected functional area (Leiden algorithm)
270
- - Process: Execution flow trace
271
-
272
- additional_node_types: "Multi-language: Struct, Enum, Macro, Typedef, Union, Namespace, Trait, Impl, TypeAlias, Const, Static, Property, Record, Delegate, Annotation, Constructor, Template, Module (use backticks in queries: \`Struct\`, \`Enum\`, etc.)"
273
-
274
- relationships:
275
- - CONTAINS: File/Folder contains child
276
- - DEFINES: File defines a symbol
277
- - CALLS: Function/method invocation
278
- - IMPORTS: Module imports
279
- - EXTENDS: Class inheritance
280
- - IMPLEMENTS: Interface implementation
281
- - MEMBER_OF: Symbol belongs to community
282
- - STEP_IN_PROCESS: Symbol is step N in process
283
-
284
- relationship_table: "All relationships use a single CodeRelation table with a 'type' property. Properties: type (STRING), confidence (DOUBLE), reason (STRING), step (INT32)"
285
-
286
- example_queries:
287
- find_callers: |
288
- MATCH (caller)-[:CodeRelation {type: 'CALLS'}]->(f:Function {name: "myFunc"})
289
- RETURN caller.name, caller.filePath
290
-
291
- find_community_members: |
292
- MATCH (s)-[:CodeRelation {type: 'MEMBER_OF'}]->(c:Community)
293
- WHERE c.heuristicLabel = "Auth"
294
- RETURN s.name, labels(s)[0] AS type
295
-
296
- trace_process: |
297
- MATCH (s)-[r:CodeRelation {type: 'STEP_IN_PROCESS'}]->(p:Process)
298
- WHERE p.heuristicLabel = "LoginFlow"
299
- RETURN s.name, r.step
300
- ORDER BY r.step
259
+ return `# GitNexus Graph Schema
260
+
261
+ nodes:
262
+ - File: Source code files
263
+ - Folder: Directory containers
264
+ - Function: Functions and arrow functions
265
+ - Class: Class definitions
266
+ - Interface: Interface/type definitions
267
+ - Method: Class methods
268
+ - CodeElement: Catch-all for other code elements
269
+ - Community: Auto-detected functional area (Leiden algorithm)
270
+ - Process: Execution flow trace
271
+
272
+ additional_node_types: "Multi-language: Struct, Enum, Macro, Typedef, Union, Namespace, Trait, Impl, TypeAlias, Const, Static, Property, Record, Delegate, Annotation, Constructor, Template, Module (use backticks in queries: \`Struct\`, \`Enum\`, etc.)"
273
+
274
+ relationships:
275
+ - CONTAINS: File/Folder contains child
276
+ - DEFINES: File defines a symbol
277
+ - CALLS: Function/method invocation
278
+ - IMPORTS: Module imports
279
+ - EXTENDS: Class inheritance
280
+ - IMPLEMENTS: Interface implementation
281
+ - MEMBER_OF: Symbol belongs to community
282
+ - STEP_IN_PROCESS: Symbol is step N in process
283
+
284
+ relationship_table: "All relationships use a single CodeRelation table with a 'type' property. Properties: type (STRING), confidence (DOUBLE), reason (STRING), step (INT32)"
285
+
286
+ example_queries:
287
+ find_callers: |
288
+ MATCH (caller)-[:CodeRelation {type: 'CALLS'}]->(f:Function {name: "myFunc"})
289
+ RETURN caller.name, caller.filePath
290
+
291
+ find_community_members: |
292
+ MATCH (s)-[:CodeRelation {type: 'MEMBER_OF'}]->(c:Community)
293
+ WHERE c.heuristicLabel = "Auth"
294
+ RETURN s.name, labels(s)[0] AS type
295
+
296
+ trace_process: |
297
+ MATCH (s)-[r:CodeRelation {type: 'STEP_IN_PROCESS'}]->(p:Process)
298
+ WHERE p.heuristicLabel = "LoginFlow"
299
+ RETURN s.name, r.step
300
+ ORDER BY r.step
301
301
  `;
302
302
  }
303
303
  /**
@@ -12,7 +12,7 @@
12
12
  */
13
13
  import { createRequire } from 'module';
14
14
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
15
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
15
+ import { CompatibleStdioServerTransport } from './compatible-stdio-transport.js';
16
16
  import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListResourceTemplatesRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
17
17
  import { GITNEXUS_TOOLS } from './tools.js';
18
18
  import { getResourceDefinitions, getResourceTemplates, readResource } from './resources.js';
@@ -192,15 +192,14 @@ export function createMCPServer(backend) {
192
192
  role: 'user',
193
193
  content: {
194
194
  type: 'text',
195
- text: `Analyze the impact of my current code changes before committing.
196
-
197
- Follow these steps:
198
- 1. First, run \`git diff ${scope === 'staged' ? '--staged' : scope === 'compare' && baseRef ? baseRef : 'HEAD'} --name-only\` locally to get the list of changed files
199
- 2. Run \`detect_changes({ changed_files: [<files from step 1>]${baseRef ? `, base_ref: "${baseRef}"` : ''} })\` to map changed files to symbols and find affected processes
200
- 3. For each changed symbol in critical processes, run \`context({name: "<symbol>"})\` to see its full reference graph
201
- 4. For any high-risk items (many callers or cross-process), run \`impact({target: "<symbol>", direction: "upstream"})\` for blast radius
202
- 5. Summarize: changes, affected processes, risk level, and recommended actions
203
-
195
+ text: `Analyze the impact of my current code changes before committing.
196
+
197
+ Follow these steps:
198
+ 1. Run \`detect_changes(${JSON.stringify({ scope, ...(baseRef ? { base_ref: baseRef } : {}) })})\` to find what changed and affected processes
199
+ 2. For each changed symbol in critical processes, run \`context({name: "<symbol>"})\` to see its full reference graph
200
+ 3. For any high-risk items (many callers or cross-process), run \`impact({target: "<symbol>", direction: "upstream"})\` for blast radius
201
+ 4. Summarize: changes, affected processes, risk level, and recommended actions
202
+
204
203
  Present the analysis as a clear risk report.`,
205
204
  },
206
205
  },
@@ -215,14 +214,14 @@ Present the analysis as a clear risk report.`,
215
214
  role: 'user',
216
215
  content: {
217
216
  type: 'text',
218
- text: `Generate architecture documentation for this codebase using the knowledge graph.
219
-
220
- Follow these steps:
221
- 1. READ \`gitnexus://repo/${repo || '{name}'}/context\` for codebase stats
222
- 2. READ \`gitnexus://repo/${repo || '{name}'}/clusters\` to see all functional areas
223
- 3. READ \`gitnexus://repo/${repo || '{name}'}/processes\` to see all execution flows
224
- 4. For the top 5 most important processes, READ \`gitnexus://repo/${repo || '{name}'}/process/{name}\` for step-by-step traces
225
- 5. Generate a mermaid architecture diagram showing the major areas and their connections
217
+ text: `Generate architecture documentation for this codebase using the knowledge graph.
218
+
219
+ Follow these steps:
220
+ 1. READ \`gitnexus://repo/${repo || '{name}'}/context\` for codebase stats
221
+ 2. READ \`gitnexus://repo/${repo || '{name}'}/clusters\` to see all functional areas
222
+ 3. READ \`gitnexus://repo/${repo || '{name}'}/processes\` to see all execution flows
223
+ 4. For the top 5 most important processes, READ \`gitnexus://repo/${repo || '{name}'}/process/{name}\` for step-by-step traces
224
+ 5. Generate a mermaid architecture diagram showing the major areas and their connections
226
225
  6. Write an ARCHITECTURE.md file with: overview, functional areas, key execution flows, and the mermaid diagram`,
227
226
  },
228
227
  },
@@ -239,7 +238,7 @@ Follow these steps:
239
238
  export async function startMCPServer(backend) {
240
239
  const server = createMCPServer(backend);
241
240
  // Connect to stdio transport
242
- const transport = new StdioServerTransport();
241
+ const transport = new CompatibleStdioServerTransport();
243
242
  await server.connect(transport);
244
243
  // Graceful shutdown helper
245
244
  let shuttingDown = false;
package/dist/mcp/tools.js CHANGED
@@ -7,19 +7,15 @@
7
7
  export const GITNEXUS_TOOLS = [
8
8
  {
9
9
  name: 'list_repos',
10
- description: `List all indexed repositories available to GitNexus.
11
-
12
- Returns each repo's name, branch, indexed date, last commit, and stats.
13
-
14
- WHEN TO USE: First step when multiple repos are indexed, or to discover available repos.
15
- AFTER THIS: READ gitnexus://repo/{name}/context for the repo you want to work with.
16
-
17
- When multiple repos are indexed, you MUST specify the "repo" parameter
18
- on other tools (query, context, impact, etc.) to target the correct one.
19
-
20
- BRANCH HANDLING: The same repo can be indexed on different branches. Non-default
21
- branches appear as "owner/repo@branch" in the list. Use that exact name as the
22
- "repo" parameter in other tools to target the correct branch's graph.`,
10
+ description: `List all indexed repositories available to GitNexus.
11
+
12
+ Returns each repo's name, path, indexed date, last commit, and stats.
13
+
14
+ WHEN TO USE: First step when multiple repos are indexed, or to discover available repos.
15
+ AFTER THIS: READ gitnexus://repo/{name}/context for the repo you want to work with.
16
+
17
+ When multiple repos are indexed, you MUST specify the "repo" parameter
18
+ on other tools (query, context, impact, etc.) to target the correct one.`,
23
19
  inputSchema: {
24
20
  type: 'object',
25
21
  properties: {},
@@ -28,17 +24,17 @@ branches appear as "owner/repo@branch" in the list. Use that exact name as the
28
24
  },
29
25
  {
30
26
  name: 'query',
31
- description: `Query the code knowledge graph for execution flows related to a concept.
32
- Returns processes (call chains) ranked by relevance, each with its symbols and file locations.
33
-
34
- WHEN TO USE: Understanding how code works together. Use this when you need execution flows and relationships, not just file matches. Complements grep/IDE search.
35
- AFTER THIS: Use context() on a specific symbol for 360-degree view (callers, callees, categorized refs).
36
-
37
- Returns results grouped by process (execution flow):
38
- - processes: ranked execution flows with relevance priority
39
- - process_symbols: all symbols in those flows with file locations and module (functional area)
40
- - definitions: standalone types/interfaces not in any process
41
-
27
+ description: `Query the code knowledge graph for execution flows related to a concept.
28
+ Returns processes (call chains) ranked by relevance, each with its symbols and file locations.
29
+
30
+ WHEN TO USE: Understanding how code works together. Use this when you need execution flows and relationships, not just file matches. Complements grep/IDE search.
31
+ AFTER THIS: Use context() on a specific symbol for 360-degree view (callers, callees, categorized refs).
32
+
33
+ Returns results grouped by process (execution flow):
34
+ - processes: ranked execution flows with relevance priority
35
+ - process_symbols: all symbols in those flows with file locations and module (functional area)
36
+ - definitions: standalone types/interfaces not in any process
37
+
42
38
  Hybrid ranking: BM25 keyword + semantic vector search, ranked by Reciprocal Rank Fusion.`,
43
39
  inputSchema: {
44
40
  type: 'object',
@@ -49,59 +45,68 @@ Hybrid ranking: BM25 keyword + semantic vector search, ranked by Reciprocal Rank
49
45
  limit: { type: 'number', description: 'Max processes to return (default: 5)', default: 5 },
50
46
  max_symbols: { type: 'number', description: 'Max symbols per process (default: 10)', default: 10 },
51
47
  include_content: { type: 'boolean', description: 'Include full symbol source code (default: false)', default: false },
52
- repo: { type: 'string', description: 'Repository name (e.g. "owner/repo"). For repos indexed on a specific branch, append @branch (e.g. "owner/repo@develop"). Omit if only one repo is indexed. Use list_repos to see available repos.' },
48
+ repo: { type: 'string', description: 'Repository name or path. Omit if only one repo is indexed.' },
53
49
  },
54
50
  required: ['query'],
55
51
  },
56
52
  },
57
53
  {
58
54
  name: 'cypher',
59
- description: `Execute Cypher query against the code knowledge graph.
60
-
61
- WHEN TO USE: Complex structural queries that search/explore can't answer. READ gitnexus://repo/{name}/schema first for the full schema.
62
- AFTER THIS: Use context() on result symbols for deeper context.
63
-
64
- SCHEMA:
65
- - Nodes: File, Folder, Function, Class, Interface, Method, CodeElement, Community, Process
66
- - Multi-language nodes (use backticks): \`Struct\`, \`Enum\`, \`Trait\`, \`Impl\`, etc.
67
- - All edges via single CodeRelation table with 'type' property
68
- - Edge types: CONTAINS, DEFINES, CALLS, IMPORTS, EXTENDS, IMPLEMENTS, MEMBER_OF, STEP_IN_PROCESS
69
- - Edge properties: type (STRING), confidence (DOUBLE), reason (STRING), step (INT32)
70
-
71
- EXAMPLES:
72
- • Find callers of a function:
73
- MATCH (a)-[:CodeRelation {type: 'CALLS'}]->(b:Function {name: "validateUser"}) RETURN a.name, a.filePath
74
-
75
- • Find community members:
76
- MATCH (f)-[:CodeRelation {type: 'MEMBER_OF'}]->(c:Community) WHERE c.heuristicLabel = "Auth" RETURN f.name
77
-
78
- • Trace a process:
79
- MATCH (s)-[r:CodeRelation {type: 'STEP_IN_PROCESS'}]->(p:Process) WHERE p.heuristicLabel = "UserLogin" RETURN s.name, r.step ORDER BY r.step
80
-
81
- OUTPUT: Returns { markdown, row_count } — results formatted as a Markdown table for easy reading.
82
-
83
- TIPS:
84
- - All relationships use single CodeRelation table — filter with {type: 'CALLS'} etc.
85
- - Community = auto-detected functional area (Leiden algorithm)
86
- - Process = execution flow trace from entry point to terminal
55
+ description: `Execute Cypher query against the code knowledge graph.
56
+
57
+ WHEN TO USE: Complex structural queries that search/explore can't answer. READ gitnexus://repo/{name}/schema first for the full schema.
58
+ AFTER THIS: Use context() on result symbols for deeper context.
59
+
60
+ SCHEMA:
61
+ - Nodes: File, Folder, Function, Class, Interface, Method, CodeElement, Community, Process
62
+ - Multi-language nodes (use backticks): \`Struct\`, \`Enum\`, \`Trait\`, \`Impl\`, etc.
63
+ - All edges via single CodeRelation table with 'type' property
64
+ - Edge types: CONTAINS, DEFINES, CALLS, IMPORTS, EXTENDS, IMPLEMENTS, HAS_METHOD, OVERRIDES, MEMBER_OF, STEP_IN_PROCESS
65
+ - Edge properties: type (STRING), confidence (DOUBLE), reason (STRING), step (INT32)
66
+
67
+ EXAMPLES:
68
+ • Find callers of a function:
69
+ MATCH (a)-[:CodeRelation {type: 'CALLS'}]->(b:Function {name: "validateUser"}) RETURN a.name, a.filePath
70
+
71
+ • Find community members:
72
+ MATCH (f)-[:CodeRelation {type: 'MEMBER_OF'}]->(c:Community) WHERE c.heuristicLabel = "Auth" RETURN f.name
73
+
74
+ • Trace a process:
75
+ MATCH (s)-[r:CodeRelation {type: 'STEP_IN_PROCESS'}]->(p:Process) WHERE p.heuristicLabel = "UserLogin" RETURN s.name, r.step ORDER BY r.step
76
+
77
+ Find all methods of a class:
78
+ MATCH (c:Class {name: "UserService"})-[r:CodeRelation {type: 'HAS_METHOD'}]->(m:Method) RETURN m.name, m.parameterCount, m.returnType
79
+
80
+ Find method overrides (MRO resolution):
81
+ MATCH (winner:Method)-[r:CodeRelation {type: 'OVERRIDES'}]->(loser:Method) RETURN winner.name, winner.filePath, loser.filePath, r.reason
82
+
83
+ • Detect diamond inheritance:
84
+ MATCH (d:Class)-[:CodeRelation {type: 'EXTENDS'}]->(b1), (d)-[:CodeRelation {type: 'EXTENDS'}]->(b2), (b1)-[:CodeRelation {type: 'EXTENDS'}]->(a), (b2)-[:CodeRelation {type: 'EXTENDS'}]->(a) WHERE b1 <> b2 RETURN d.name, b1.name, b2.name, a.name
85
+
86
+ OUTPUT: Returns { markdown, row_count } — results formatted as a Markdown table for easy reading.
87
+
88
+ TIPS:
89
+ - All relationships use single CodeRelation table — filter with {type: 'CALLS'} etc.
90
+ - Community = auto-detected functional area (Leiden algorithm)
91
+ - Process = execution flow trace from entry point to terminal
87
92
  - Use heuristicLabel (not label) for human-readable community/process names`,
88
93
  inputSchema: {
89
94
  type: 'object',
90
95
  properties: {
91
96
  query: { type: 'string', description: 'Cypher query to execute' },
92
- repo: { type: 'string', description: 'Repository name (e.g. "owner/repo"). For repos indexed on a specific branch, append @branch (e.g. "owner/repo@develop"). Omit if only one repo is indexed. Use list_repos to see available repos.' },
97
+ repo: { type: 'string', description: 'Repository name or path. Omit if only one repo is indexed.' },
93
98
  },
94
99
  required: ['query'],
95
100
  },
96
101
  },
97
102
  {
98
103
  name: 'context',
99
- description: `360-degree view of a single code symbol.
100
- Shows categorized incoming/outgoing references (calls, imports, extends, implements), process participation, and file location.
101
-
102
- WHEN TO USE: After query() to understand a specific symbol in depth. When you need to know all callers, callees, and what execution flows a symbol participates in.
103
- AFTER THIS: Use impact() if planning changes, or READ gitnexus://repo/{name}/process/{processName} for full execution trace.
104
-
104
+ description: `360-degree view of a single code symbol.
105
+ Shows categorized incoming/outgoing references (calls, imports, extends, implements), process participation, and file location.
106
+
107
+ WHEN TO USE: After query() to understand a specific symbol in depth. When you need to know all callers, callees, and what execution flows a symbol participates in.
108
+ AFTER THIS: Use impact() if planning changes, or READ gitnexus://repo/{name}/process/{processName} for full execution trace.
109
+
105
110
  Handles disambiguation: if multiple symbols share the same name, returns candidates for you to pick from. Use uid param for zero-ambiguity lookup from prior results.`,
106
111
  inputSchema: {
107
112
  type: 'object',
@@ -110,46 +115,40 @@ Handles disambiguation: if multiple symbols share the same name, returns candida
110
115
  uid: { type: 'string', description: 'Direct symbol UID from prior tool results (zero-ambiguity lookup)' },
111
116
  file_path: { type: 'string', description: 'File path to disambiguate common names' },
112
117
  include_content: { type: 'boolean', description: 'Include full symbol source code (default: false)', default: false },
113
- repo: { type: 'string', description: 'Repository name (e.g. "owner/repo"). For repos indexed on a specific branch, append @branch (e.g. "owner/repo@develop"). Omit if only one repo is indexed. Use list_repos to see available repos.' },
118
+ repo: { type: 'string', description: 'Repository name or path. Omit if only one repo is indexed.' },
114
119
  },
115
120
  required: [],
116
121
  },
117
122
  },
118
123
  {
119
124
  name: 'detect_changes',
120
- description: `Analyze code changes and find affected execution flows.
121
- Maps changed files to indexed symbols, then traces which processes are impacted.
122
-
123
- WHEN TO USE: Before committing — to understand what your changes affect. Pre-commit review, PR preparation.
124
- AFTER THIS: Review affected processes. Use context() on high-risk symbols. READ gitnexus://repo/{name}/process/{name} for full traces.
125
-
126
- FOR HUB USERS: The Hub server has no local git checkout. You MUST provide the changed_files
127
- parameter by running git diff locally first and passing the file list. Example:
128
- 1. Run \`git diff --name-only\` (or \`git diff HEAD --name-only\` for all changes)
129
- 2. Pass the resulting file paths as the changed_files array
130
-
125
+ description: `Analyze uncommitted git changes and find affected execution flows.
126
+ Maps git diff hunks to indexed symbols, then traces which processes are impacted.
127
+
128
+ WHEN TO USE: Before committing — to understand what your changes affect. Pre-commit review, PR preparation.
129
+ AFTER THIS: Review affected processes. Use context() on high-risk symbols. READ gitnexus://repo/{name}/process/{name} for full traces.
130
+
131
131
  Returns: changed symbols, affected processes, and a risk summary.`,
132
132
  inputSchema: {
133
133
  type: 'object',
134
134
  properties: {
135
135
  scope: { type: 'string', description: 'What to analyze: "unstaged" (default), "staged", "all", or "compare"', enum: ['unstaged', 'staged', 'all', 'compare'], default: 'unstaged' },
136
136
  base_ref: { type: 'string', description: 'Branch/commit for "compare" scope (e.g., "main")' },
137
- changed_files: { type: 'array', items: { type: 'string' }, description: 'Pre-computed list of changed file paths (from local git diff). Required for Hub MCP the server has no git checkout. The local MCP server ignores this and runs git diff itself.' },
138
- repo: { type: 'string', description: 'Repository name (e.g. "owner/repo"). For repos indexed on a specific branch, append @branch (e.g. "owner/repo@develop"). Omit if only one repo is indexed. Use list_repos to see available repos.' },
137
+ repo: { type: 'string', description: 'Repository name or path. Omit if only one repo is indexed.' },
139
138
  },
140
139
  required: [],
141
140
  },
142
141
  },
143
142
  {
144
143
  name: 'rename',
145
- description: `Multi-file coordinated rename using the knowledge graph + text search.
146
- Finds all references via graph (high confidence) and regex text search (lower confidence). Preview by default.
147
-
148
- WHEN TO USE: Renaming a function, class, method, or variable across the codebase. Safer than find-and-replace.
149
- AFTER THIS: Run detect_changes() to verify no unexpected side effects.
150
-
151
- Each edit is tagged with confidence:
152
- - "graph": found via knowledge graph relationships (high confidence, safe to accept)
144
+ description: `Multi-file coordinated rename using the knowledge graph + text search.
145
+ Finds all references via graph (high confidence) and regex text search (lower confidence). Preview by default.
146
+
147
+ WHEN TO USE: Renaming a function, class, method, or variable across the codebase. Safer than find-and-replace.
148
+ AFTER THIS: Run detect_changes() to verify no unexpected side effects.
149
+
150
+ Each edit is tagged with confidence:
151
+ - "graph": found via knowledge graph relationships (high confidence, safe to accept)
153
152
  - "text_search": found via regex text search (lower confidence, review carefully)`,
154
153
  inputSchema: {
155
154
  type: 'object',
@@ -159,32 +158,32 @@ Each edit is tagged with confidence:
159
158
  new_name: { type: 'string', description: 'The new name for the symbol' },
160
159
  file_path: { type: 'string', description: 'File path to disambiguate common names' },
161
160
  dry_run: { type: 'boolean', description: 'Preview edits without modifying files (default: true)', default: true },
162
- repo: { type: 'string', description: 'Repository name (e.g. "owner/repo"). For repos indexed on a specific branch, append @branch (e.g. "owner/repo@develop"). Omit if only one repo is indexed. Use list_repos to see available repos.' },
161
+ repo: { type: 'string', description: 'Repository name or path. Omit if only one repo is indexed.' },
163
162
  },
164
163
  required: ['new_name'],
165
164
  },
166
165
  },
167
166
  {
168
167
  name: 'impact',
169
- description: `Analyze the blast radius of changing a code symbol.
170
- Returns affected symbols grouped by depth, plus risk assessment, affected execution flows, and affected modules.
171
-
172
- WHEN TO USE: Before making code changes — especially refactoring, renaming, or modifying shared code. Shows what would break.
173
- AFTER THIS: Review d=1 items (WILL BREAK). Use context() on high-risk symbols.
174
-
175
- Output includes:
176
- - risk: LOW / MEDIUM / HIGH / CRITICAL
177
- - summary: direct callers, processes affected, modules affected
178
- - affected_processes: which execution flows break and at which step
179
- - affected_modules: which functional areas are hit (direct vs indirect)
180
- - byDepth: all affected symbols grouped by traversal depth
181
-
182
- Depth groups:
183
- - d=1: WILL BREAK (direct callers/importers)
184
- - d=2: LIKELY AFFECTED (indirect)
185
- - d=3: MAY NEED TESTING (transitive)
186
-
187
- EdgeType: CALLS, IMPORTS, EXTENDS, IMPLEMENTS
168
+ description: `Analyze the blast radius of changing a code symbol.
169
+ Returns affected symbols grouped by depth, plus risk assessment, affected execution flows, and affected modules.
170
+
171
+ WHEN TO USE: Before making code changes — especially refactoring, renaming, or modifying shared code. Shows what would break.
172
+ AFTER THIS: Review d=1 items (WILL BREAK). Use context() on high-risk symbols.
173
+
174
+ Output includes:
175
+ - risk: LOW / MEDIUM / HIGH / CRITICAL
176
+ - summary: direct callers, processes affected, modules affected
177
+ - affected_processes: which execution flows break and at which step
178
+ - affected_modules: which functional areas are hit (direct vs indirect)
179
+ - byDepth: all affected symbols grouped by traversal depth
180
+
181
+ Depth groups:
182
+ - d=1: WILL BREAK (direct callers/importers)
183
+ - d=2: LIKELY AFFECTED (indirect)
184
+ - d=3: MAY NEED TESTING (transitive)
185
+
186
+ EdgeType: CALLS, IMPORTS, EXTENDS, IMPLEMENTS, HAS_METHOD, OVERRIDES
188
187
  Confidence: 1.0 = certain, <0.8 = fuzzy match`,
189
188
  inputSchema: {
190
189
  type: 'object',
@@ -192,10 +191,10 @@ Confidence: 1.0 = certain, <0.8 = fuzzy match`,
192
191
  target: { type: 'string', description: 'Name of function, class, or file to analyze' },
193
192
  direction: { type: 'string', description: 'upstream (what depends on this) or downstream (what this depends on)' },
194
193
  maxDepth: { type: 'number', description: 'Max relationship depth (default: 3)', default: 3 },
195
- relationTypes: { type: 'array', items: { type: 'string' }, description: 'Filter: CALLS, IMPORTS, EXTENDS, IMPLEMENTS (default: usage-based)' },
194
+ relationTypes: { type: 'array', items: { type: 'string' }, description: 'Filter: CALLS, IMPORTS, EXTENDS, IMPLEMENTS, HAS_METHOD, OVERRIDES (default: usage-based)' },
196
195
  includeTests: { type: 'boolean', description: 'Include test files (default: false)' },
197
196
  minConfidence: { type: 'number', description: 'Minimum confidence 0-1 (default: 0.7)' },
198
- repo: { type: 'string', description: 'Repository name (e.g. "owner/repo"). For repos indexed on a specific branch, append @branch (e.g. "owner/repo@develop"). Omit if only one repo is indexed. Use list_repos to see available repos.' },
197
+ repo: { type: 'string', description: 'Repository name or path. Omit if only one repo is indexed.' },
199
198
  },
200
199
  required: ['target', 'direction'],
201
200
  },
@@ -12,9 +12,9 @@ import cors from 'cors';
12
12
  import path from 'path';
13
13
  import fs from 'fs/promises';
14
14
  import { loadMeta, listRegisteredRepos } from '../storage/repo-manager.js';
15
- import { executeQuery, closeKuzu, withKuzuDb } from '../core/kuzu/kuzu-adapter.js';
16
- import { NODE_TABLES } from '../core/kuzu/schema.js';
17
- import { searchFTSFromKuzu } from '../core/search/bm25-index.js';
15
+ import { executeQuery, closeLbug, withLbugDb } from '../core/lbug/lbug-adapter.js';
16
+ import { NODE_TABLES } from '../core/lbug/schema.js';
17
+ import { searchFTSFromLbug } from '../core/search/bm25-index.js';
18
18
  import { hybridSearch } from '../core/search/hybrid-search.js';
19
19
  // Embedding imports are lazy (dynamic import) to avoid loading onnxruntime-node
20
20
  // at server startup — crashes on unsupported Node ABI versions (#89)
@@ -171,8 +171,8 @@ export const createServer = async (port, host = '127.0.0.1') => {
171
171
  res.status(404).json({ error: 'Repository not found' });
172
172
  return;
173
173
  }
174
- const kuzuPath = path.join(entry.storagePath, 'kuzu');
175
- const graph = await withKuzuDb(kuzuPath, async () => buildGraph());
174
+ const lbugPath = path.join(entry.storagePath, 'lbug');
175
+ const graph = await withLbugDb(lbugPath, async () => buildGraph());
176
176
  res.json(graph);
177
177
  }
178
178
  catch (err) {
@@ -192,8 +192,8 @@ export const createServer = async (port, host = '127.0.0.1') => {
192
192
  res.status(404).json({ error: 'Repository not found' });
193
193
  return;
194
194
  }
195
- const kuzuPath = path.join(entry.storagePath, 'kuzu');
196
- const result = await withKuzuDb(kuzuPath, () => executeQuery(cypher));
195
+ const lbugPath = path.join(entry.storagePath, 'lbug');
196
+ const result = await withLbugDb(lbugPath, () => executeQuery(cypher));
197
197
  res.json({ result });
198
198
  }
199
199
  catch (err) {
@@ -213,19 +213,19 @@ export const createServer = async (port, host = '127.0.0.1') => {
213
213
  res.status(404).json({ error: 'Repository not found' });
214
214
  return;
215
215
  }
216
- const kuzuPath = path.join(entry.storagePath, 'kuzu');
216
+ const lbugPath = path.join(entry.storagePath, 'lbug');
217
217
  const parsedLimit = Number(req.body.limit ?? 10);
218
218
  const limit = Number.isFinite(parsedLimit)
219
219
  ? Math.max(1, Math.min(100, Math.trunc(parsedLimit)))
220
220
  : 10;
221
- const results = await withKuzuDb(kuzuPath, async () => {
221
+ const results = await withLbugDb(lbugPath, async () => {
222
222
  const { isEmbedderReady } = await import('../core/embeddings/embedder.js');
223
223
  if (isEmbedderReady()) {
224
224
  const { semanticSearch } = await import('../core/embeddings/embedding-pipeline.js');
225
225
  return hybridSearch(query, limit, executeQuery, semanticSearch);
226
226
  }
227
227
  // FTS-only fallback when embeddings aren't loaded
228
- return searchFTSFromKuzu(query, limit);
228
+ return searchFTSFromLbug(query, limit);
229
229
  });
230
230
  res.json({ results });
231
231
  }
@@ -331,11 +331,11 @@ export const createServer = async (port, host = '127.0.0.1') => {
331
331
  const server = app.listen(port, host, () => {
332
332
  console.log(`GitNexus server running on http://${host}:${port}`);
333
333
  });
334
- // Graceful shutdown — close Express + KuzuDB cleanly
334
+ // Graceful shutdown — close Express + LadybugDB cleanly
335
335
  const shutdown = async () => {
336
336
  server.close();
337
337
  await cleanupMcp();
338
- await closeKuzu();
338
+ await closeLbug();
339
339
  await backend.disconnect();
340
340
  process.exit(0);
341
341
  };
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Mounts the GitNexus MCP server on Express using StreamableHTTP transport.
5
5
  * Each connecting client gets its own stateful session; the LocalBackend
6
- * is shared across all sessions (thread-safe — lazy KuzuDB per repo).
6
+ * is shared across all sessions (thread-safe — lazy LadybugDB per repo).
7
7
  *
8
8
  * Sessions are cleaned up on explicit close or after SESSION_TTL_MS of inactivity
9
9
  * (guards against network drops that never trigger onclose).
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Mounts the GitNexus MCP server on Express using StreamableHTTP transport.
5
5
  * Each connecting client gets its own stateful session; the LocalBackend
6
- * is shared across all sessions (thread-safe — lazy KuzuDB per repo).
6
+ * is shared across all sessions (thread-safe — lazy LadybugDB per repo).
7
7
  *
8
8
  * Sessions are cleaned up on explicit close or after SESSION_TTL_MS of inactivity
9
9
  * (guards against network drops that never trigger onclose).
@@ -21,7 +21,7 @@ export interface RepoMeta {
21
21
  export interface IndexedRepo {
22
22
  repoPath: string;
23
23
  storagePath: string;
24
- kuzuPath: string;
24
+ lbugPath: string;
25
25
  metaPath: string;
26
26
  meta: RepoMeta;
27
27
  }
@@ -45,9 +45,27 @@ export declare const getStoragePath: (repoPath: string) => string;
45
45
  */
46
46
  export declare const getStoragePaths: (repoPath: string) => {
47
47
  storagePath: string;
48
- kuzuPath: string;
48
+ lbugPath: string;
49
49
  metaPath: string;
50
50
  };
51
+ /**
52
+ * Check whether a KuzuDB index exists in the given storage path.
53
+ * Non-destructive — safe to call from status commands.
54
+ */
55
+ export declare const hasKuzuIndex: (storagePath: string) => Promise<boolean>;
56
+ /**
57
+ * Clean up stale KuzuDB files after migration to LadybugDB.
58
+ *
59
+ * Returns:
60
+ * found — true if .gitnexus/kuzu existed and was deleted
61
+ * needsReindex — true if kuzu existed but lbug does not (re-analyze required)
62
+ *
63
+ * Callers own the user-facing messaging; this function only deletes files.
64
+ */
65
+ export declare const cleanupOldKuzuFiles: (storagePath: string) => Promise<{
66
+ found: boolean;
67
+ needsReindex: boolean;
68
+ }>;
51
69
  /**
52
70
  * Load metadata from an indexed repo
53
71
  */