@veewo/gitnexus 1.3.11-rc.1 → 1.4.6-rc

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 (181) hide show
  1. package/README.md +36 -79
  2. package/dist/benchmark/agent-context/tool-runner.js +2 -2
  3. package/dist/benchmark/neonspark-candidates.js +3 -3
  4. package/dist/benchmark/tool-runner.js +2 -2
  5. package/dist/cli/ai-context.d.ts +2 -1
  6. package/dist/cli/ai-context.js +16 -12
  7. package/dist/cli/analyze.d.ts +2 -0
  8. package/dist/cli/analyze.js +68 -48
  9. package/dist/cli/augment.js +1 -1
  10. package/dist/cli/eval-server.d.ts +8 -1
  11. package/dist/cli/eval-server.js +30 -13
  12. package/dist/cli/index.js +28 -82
  13. package/dist/cli/lazy-action.d.ts +6 -0
  14. package/dist/cli/lazy-action.js +18 -0
  15. package/dist/cli/mcp.js +3 -1
  16. package/dist/cli/setup.js +87 -48
  17. package/dist/cli/setup.test.js +18 -13
  18. package/dist/cli/skill-gen.d.ts +26 -0
  19. package/dist/cli/skill-gen.js +549 -0
  20. package/dist/cli/status.js +13 -4
  21. package/dist/cli/tool.d.ts +3 -2
  22. package/dist/cli/tool.js +50 -16
  23. package/dist/cli/wiki.js +8 -4
  24. package/dist/config/ignore-service.d.ts +25 -0
  25. package/dist/config/ignore-service.js +76 -0
  26. package/dist/config/supported-languages.d.ts +4 -1
  27. package/dist/config/supported-languages.js +3 -2
  28. package/dist/core/augmentation/engine.js +94 -67
  29. package/dist/core/embeddings/embedder.d.ts +1 -1
  30. package/dist/core/embeddings/embedder.js +1 -1
  31. package/dist/core/embeddings/embedding-pipeline.d.ts +3 -3
  32. package/dist/core/embeddings/embedding-pipeline.js +52 -25
  33. package/dist/core/embeddings/types.d.ts +1 -1
  34. package/dist/core/graph/types.d.ts +7 -2
  35. package/dist/core/ingestion/ast-cache.js +3 -2
  36. package/dist/core/ingestion/call-processor.d.ts +8 -6
  37. package/dist/core/ingestion/call-processor.js +468 -206
  38. package/dist/core/ingestion/call-routing.d.ts +53 -0
  39. package/dist/core/ingestion/call-routing.js +108 -0
  40. package/dist/core/ingestion/constants.d.ts +16 -0
  41. package/dist/core/ingestion/constants.js +16 -0
  42. package/dist/core/ingestion/entry-point-scoring.d.ts +2 -1
  43. package/dist/core/ingestion/entry-point-scoring.js +116 -23
  44. package/dist/core/ingestion/export-detection.d.ts +18 -0
  45. package/dist/core/ingestion/export-detection.js +231 -0
  46. package/dist/core/ingestion/filesystem-walker.js +4 -3
  47. package/dist/core/ingestion/framework-detection.d.ts +19 -4
  48. package/dist/core/ingestion/framework-detection.js +182 -6
  49. package/dist/core/ingestion/heritage-processor.d.ts +13 -5
  50. package/dist/core/ingestion/heritage-processor.js +109 -55
  51. package/dist/core/ingestion/import-processor.d.ts +16 -20
  52. package/dist/core/ingestion/import-processor.js +199 -579
  53. package/dist/core/ingestion/language-config.d.ts +46 -0
  54. package/dist/core/ingestion/language-config.js +167 -0
  55. package/dist/core/ingestion/mro-processor.d.ts +45 -0
  56. package/dist/core/ingestion/mro-processor.js +369 -0
  57. package/dist/core/ingestion/named-binding-extraction.d.ts +61 -0
  58. package/dist/core/ingestion/named-binding-extraction.js +363 -0
  59. package/dist/core/ingestion/parsing-processor.d.ts +4 -1
  60. package/dist/core/ingestion/parsing-processor.js +107 -109
  61. package/dist/core/ingestion/pipeline.d.ts +6 -3
  62. package/dist/core/ingestion/pipeline.js +208 -114
  63. package/dist/core/ingestion/process-processor.js +8 -2
  64. package/dist/core/ingestion/resolution-context.d.ts +53 -0
  65. package/dist/core/ingestion/resolution-context.js +132 -0
  66. package/dist/core/ingestion/resolvers/csharp.d.ts +22 -0
  67. package/dist/core/ingestion/resolvers/csharp.js +109 -0
  68. package/dist/core/ingestion/resolvers/go.d.ts +19 -0
  69. package/dist/core/ingestion/resolvers/go.js +42 -0
  70. package/dist/core/ingestion/resolvers/index.d.ts +18 -0
  71. package/dist/core/ingestion/resolvers/index.js +13 -0
  72. package/dist/core/ingestion/resolvers/jvm.d.ts +23 -0
  73. package/dist/core/ingestion/resolvers/jvm.js +87 -0
  74. package/dist/core/ingestion/resolvers/php.d.ts +15 -0
  75. package/dist/core/ingestion/resolvers/php.js +35 -0
  76. package/dist/core/ingestion/resolvers/python.d.ts +19 -0
  77. package/dist/core/ingestion/resolvers/python.js +52 -0
  78. package/dist/core/ingestion/resolvers/ruby.d.ts +12 -0
  79. package/dist/core/ingestion/resolvers/ruby.js +15 -0
  80. package/dist/core/ingestion/resolvers/rust.d.ts +15 -0
  81. package/dist/core/ingestion/resolvers/rust.js +73 -0
  82. package/dist/core/ingestion/resolvers/standard.d.ts +28 -0
  83. package/dist/core/ingestion/resolvers/standard.js +123 -0
  84. package/dist/core/ingestion/resolvers/utils.d.ts +33 -0
  85. package/dist/core/ingestion/resolvers/utils.js +122 -0
  86. package/dist/core/ingestion/symbol-table.d.ts +21 -1
  87. package/dist/core/ingestion/symbol-table.js +40 -12
  88. package/dist/core/ingestion/tree-sitter-queries.d.ts +13 -10
  89. package/dist/core/ingestion/tree-sitter-queries.js +297 -7
  90. package/dist/core/ingestion/type-env.d.ts +49 -0
  91. package/dist/core/ingestion/type-env.js +611 -0
  92. package/dist/core/ingestion/type-extractors/c-cpp.d.ts +2 -0
  93. package/dist/core/ingestion/type-extractors/c-cpp.js +385 -0
  94. package/dist/core/ingestion/type-extractors/csharp.d.ts +2 -0
  95. package/dist/core/ingestion/type-extractors/csharp.js +383 -0
  96. package/dist/core/ingestion/type-extractors/go.d.ts +2 -0
  97. package/dist/core/ingestion/type-extractors/go.js +467 -0
  98. package/dist/core/ingestion/type-extractors/index.d.ts +22 -0
  99. package/dist/core/ingestion/type-extractors/index.js +31 -0
  100. package/dist/core/ingestion/type-extractors/jvm.d.ts +3 -0
  101. package/dist/core/ingestion/type-extractors/jvm.js +681 -0
  102. package/dist/core/ingestion/type-extractors/php.d.ts +2 -0
  103. package/dist/core/ingestion/type-extractors/php.js +549 -0
  104. package/dist/core/ingestion/type-extractors/python.d.ts +2 -0
  105. package/dist/core/ingestion/type-extractors/python.js +406 -0
  106. package/dist/core/ingestion/type-extractors/ruby.d.ts +2 -0
  107. package/dist/core/ingestion/type-extractors/ruby.js +389 -0
  108. package/dist/core/ingestion/type-extractors/rust.d.ts +2 -0
  109. package/dist/core/ingestion/type-extractors/rust.js +449 -0
  110. package/dist/core/ingestion/type-extractors/shared.d.ts +133 -0
  111. package/dist/core/ingestion/type-extractors/shared.js +703 -0
  112. package/dist/core/ingestion/type-extractors/swift.d.ts +2 -0
  113. package/dist/core/ingestion/type-extractors/swift.js +137 -0
  114. package/dist/core/ingestion/type-extractors/types.d.ts +127 -0
  115. package/dist/core/ingestion/type-extractors/typescript.d.ts +2 -0
  116. package/dist/core/ingestion/type-extractors/typescript.js +494 -0
  117. package/dist/core/ingestion/utils.d.ts +103 -0
  118. package/dist/core/ingestion/utils.js +1085 -4
  119. package/dist/core/ingestion/workers/parse-worker.d.ts +51 -4
  120. package/dist/core/ingestion/workers/parse-worker.js +634 -222
  121. package/dist/core/ingestion/workers/worker-pool.js +8 -0
  122. package/dist/core/{kuzu → lbug}/csv-generator.d.ts +12 -10
  123. package/dist/core/{kuzu → lbug}/csv-generator.js +82 -101
  124. package/dist/core/{kuzu/kuzu-adapter.d.ts → lbug/lbug-adapter.d.ts} +20 -25
  125. package/dist/core/{kuzu/kuzu-adapter.js → lbug/lbug-adapter.js} +150 -122
  126. package/dist/core/{kuzu → lbug}/schema.d.ts +4 -4
  127. package/dist/core/{kuzu → lbug}/schema.js +23 -22
  128. package/dist/core/lbug/schema.test.d.ts +1 -0
  129. package/dist/core/search/bm25-index.d.ts +4 -4
  130. package/dist/core/search/bm25-index.js +12 -11
  131. package/dist/core/search/hybrid-search.d.ts +2 -2
  132. package/dist/core/search/hybrid-search.js +6 -6
  133. package/dist/core/tree-sitter/parser-loader.d.ts +1 -0
  134. package/dist/core/tree-sitter/parser-loader.js +19 -0
  135. package/dist/core/wiki/generator.d.ts +2 -2
  136. package/dist/core/wiki/generator.js +6 -6
  137. package/dist/core/wiki/graph-queries.d.ts +4 -4
  138. package/dist/core/wiki/graph-queries.js +7 -7
  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} +11 -10
  142. package/dist/mcp/core/lbug-adapter.js +327 -0
  143. package/dist/mcp/local/local-backend.d.ts +21 -16
  144. package/dist/mcp/local/local-backend.js +306 -706
  145. package/dist/mcp/local/unity-parity-seed-loader.d.ts +6 -1
  146. package/dist/mcp/local/unity-parity-seed-loader.js +119 -9
  147. package/dist/mcp/local/unity-parity-seed-loader.test.js +95 -7
  148. package/dist/mcp/resources.js +2 -2
  149. package/dist/mcp/server.js +28 -13
  150. package/dist/mcp/staleness.js +2 -2
  151. package/dist/mcp/tools.js +12 -3
  152. package/dist/server/api.js +12 -12
  153. package/dist/server/mcp-http.d.ts +1 -1
  154. package/dist/server/mcp-http.js +1 -1
  155. package/dist/storage/git.js +4 -1
  156. package/dist/storage/repo-manager.d.ts +20 -2
  157. package/dist/storage/repo-manager.js +74 -4
  158. package/dist/types/pipeline.d.ts +1 -1
  159. package/hooks/claude/gitnexus-hook.cjs +149 -46
  160. package/hooks/claude/pre-tool-use.sh +2 -1
  161. package/hooks/claude/session-start.sh +0 -0
  162. package/package.json +20 -4
  163. package/scripts/patch-tree-sitter-swift.cjs +74 -0
  164. package/skills/gitnexus-cli.md +8 -8
  165. package/skills/gitnexus-debugging.md +1 -1
  166. package/skills/gitnexus-exploring.md +1 -1
  167. package/skills/gitnexus-guide.md +1 -1
  168. package/skills/gitnexus-impact-analysis.md +1 -1
  169. package/skills/gitnexus-pr-review.md +163 -0
  170. package/skills/gitnexus-refactoring.md +1 -1
  171. package/dist/cli/claude-hooks.d.ts +0 -22
  172. package/dist/cli/claude-hooks.js +0 -97
  173. package/dist/mcp/core/kuzu-adapter.js +0 -231
  174. /package/dist/core/{kuzu/csv-generator.test.d.ts → ingestion/type-extractors/types.js} +0 -0
  175. /package/dist/core/{kuzu/relationship-pair-buckets.test.d.ts → lbug/csv-generator.test.d.ts} +0 -0
  176. /package/dist/core/{kuzu → lbug}/csv-generator.test.js +0 -0
  177. /package/dist/core/{kuzu → lbug}/relationship-pair-buckets.d.ts +0 -0
  178. /package/dist/core/{kuzu → lbug}/relationship-pair-buckets.js +0 -0
  179. /package/dist/core/{kuzu/schema.test.d.ts → lbug/relationship-pair-buckets.test.d.ts} +0 -0
  180. /package/dist/core/{kuzu → lbug}/relationship-pair-buckets.test.js +0 -0
  181. /package/dist/core/{kuzu → lbug}/schema.test.js +0 -0
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  **Graph-powered code intelligence for AI agents.** Index any codebase into a knowledge graph, then query it via MCP or CLI.
4
4
 
5
- Works with **Cursor**, **Claude Code**, **Codex**, **Windsurf**, **Cline**, **OpenCode**, and any MCP-compatible tool.
5
+ Works with **Cursor**, **Claude Code**, **Windsurf**, **Cline**, **OpenCode**, and any MCP-compatible tool.
6
6
 
7
7
  [![npm version](https://img.shields.io/npm/v/gitnexus.svg)](https://www.npmjs.com/package/gitnexus)
8
8
  [![License: PolyForm Noncommercial](https://img.shields.io/badge/License-PolyForm%20Noncommercial-blue.svg)](https://polyformproject.org/licenses/noncommercial/1.0.0/)
@@ -19,31 +19,14 @@ AI coding tools don't understand your codebase structure. They edit a function w
19
19
 
20
20
  ```bash
21
21
  # Index your repo (run from repo root)
22
- npx gitnexus analyze
22
+ npx -y @veewo/gitnexus@latest analyze
23
23
  ```
24
24
 
25
- That's it. This indexes the codebase, updates `AGENTS.md` / `CLAUDE.md` context files, and (when using project scope) installs repo-local agent skills.
25
+ That's it. This indexes the codebase, installs agent skills, registers Claude Code hooks, and creates `AGENTS.md` / `CLAUDE.md` context files all in one command.
26
26
 
27
- To configure MCP + skills, run `npx gitnexus setup --agent <claude|opencode|codex>` once (default global mode), or add `--scope project` for project-local mode.
27
+ To configure MCP for your editor, run `npx -y @veewo/gitnexus@latest setup` once or set it up manually below.
28
28
 
29
- `gitnexus setup` requires an agent selection:
30
- - `--agent claude`: configure Claude MCP only
31
- - `--agent opencode`: configure OpenCode MCP only
32
- - `--agent codex`: configure Codex MCP only
33
-
34
- It also supports two scopes:
35
- - `global` (default): writes MCP to the selected agent's global config + installs global skills
36
- - `project`: writes MCP to the selected agent's project-local config + installs repo-local skills
37
-
38
- ## Team Deployment and Distribution
39
-
40
- For small-team rollout (single stable channel only), follow:
41
- - [CLI Deployment and Distribution](../docs/cli-release-distribution.md)
42
-
43
- Key links:
44
- - [npm publish workflow](../.github/workflows/publish.yml)
45
- - [CLI package config](./package.json)
46
- - [Agent install + acceptance runbook](../INSTALL-GUIDE.md)
29
+ `gitnexus setup` auto-detects your editors and writes the correct global MCP config. You only need to run it once.
47
30
 
48
31
  ### Editor Support
49
32
 
@@ -51,7 +34,6 @@ Key links:
51
34
  |--------|-----|--------|---------------------|---------|
52
35
  | **Claude Code** | Yes | Yes | Yes (PreToolUse) | **Full** |
53
36
  | **Cursor** | Yes | Yes | — | MCP + Skills |
54
- | **Codex** | Yes | Yes | — | MCP + Skills |
55
37
  | **Windsurf** | Yes | — | — | MCP |
56
38
  | **OpenCode** | Yes | Yes | — | MCP + Skills |
57
39
 
@@ -90,25 +72,19 @@ Add to `~/.cursor/mcp.json` (global — works for all projects):
90
72
 
91
73
  ### OpenCode
92
74
 
93
- Add to `~/.config/opencode/opencode.json`:
75
+ Add to `~/.config/opencode/config.json`:
94
76
 
95
77
  ```json
96
78
  {
97
79
  "mcp": {
98
80
  "gitnexus": {
99
- "type": "local",
100
- "command": ["npx", "-y", "@veewo/gitnexus@latest", "mcp"]
81
+ "command": "npx",
82
+ "args": ["-y", "@veewo/gitnexus@latest", "mcp"]
101
83
  }
102
84
  }
103
85
  }
104
86
  ```
105
87
 
106
- ### Codex
107
-
108
- ```bash
109
- codex mcp add gitnexus -- npx -y @veewo/gitnexus@latest mcp
110
- ```
111
-
112
88
  ## How It Works
113
89
 
114
90
  GitNexus builds a complete knowledge graph of your codebase through a multi-phase indexing pipeline:
@@ -120,7 +96,7 @@ GitNexus builds a complete knowledge graph of your codebase through a multi-phas
120
96
  5. **Processes** — Traces execution flows from entry points through call chains
121
97
  6. **Search** — Builds hybrid search indexes for fast retrieval
122
98
 
123
- The result is a **KuzuDB graph database** stored locally in `.gitnexus/` with full-text search and semantic embeddings.
99
+ The result is a **LadybugDB graph database** stored locally in `.gitnexus/` with full-text search and semantic embeddings.
124
100
 
125
101
  ## MCP Tools
126
102
 
@@ -160,14 +136,11 @@ Your AI agent gets these tools automatically:
160
136
  ## CLI Commands
161
137
 
162
138
  ```bash
163
- gitnexus setup --agent claude # Global setup for Claude
164
- gitnexus setup --agent codex # Global setup for Codex
165
- gitnexus setup --scope project --agent opencode # Project-local setup for OpenCode
166
- gitnexus analyze [path] # Index a repository (or update stale index)
167
- gitnexus analyze --force # Force full re-index
168
- gitnexus analyze --embeddings # Enable semantic embeddings (off by default)
169
- gitnexus analyze --scope-prefix Assets/NEON/Code --scope-prefix Packages/com.veewo.* # Scoped multi-directory indexing
170
- gitnexus analyze --scope-manifest .gitnexus/sync-manifest.txt --repo-alias neonspark-v1-subset # Scoped indexing + stable repo alias
139
+ gitnexus setup # Configure MCP for your editors (one-time)
140
+ npx -y @veewo/gitnexus@latest analyze [path] # Index a repository (or update stale index)
141
+ npx -y @veewo/gitnexus@latest analyze --force # Force full re-index
142
+ npx -y @veewo/gitnexus@latest analyze --embeddings # Enable embedding generation (slower, better search)
143
+ npx -y @veewo/gitnexus@latest analyze --verbose # Log skipped files when parsers are unavailable
171
144
  gitnexus mcp # Start MCP server (stdio) — serves all indexed repos
172
145
  gitnexus serve # Start local HTTP server (multi-repo) for web UI
173
146
  gitnexus list # List all indexed repositories
@@ -176,45 +149,35 @@ gitnexus clean # Delete index for current repo
176
149
  gitnexus clean --all --force # Delete all indexes
177
150
  gitnexus wiki [path] # Generate LLM-powered docs from knowledge graph
178
151
  gitnexus wiki --model <model> # Wiki with custom LLM model (default: gpt-4o-mini)
179
- gitnexus unity-bindings <symbol> --target-path <path> [--json] # Experimental Unity C# <-> prefab/scene/asset cross-reference
180
- gitnexus context <symbol> --unity-resources on # Include graph-native Unity resource data (opt-in)
181
- gitnexus query <symbol> --unity-resources on # Enrich query symbol hits with Unity resource data (opt-in)
182
- gitnexus benchmark-unity ../benchmarks/unity-baseline/v1 --profile quick --target-path ../benchmarks/fixtures/unity-mini
183
- gitnexus benchmark-unity ../benchmarks/unity-baseline/v1 --profile full --target-path ../benchmarks/fixtures/unity-mini
184
- ```
185
-
186
- For scoped indexing, `analyze` logs scope overlap dedupe counts and any normalized path collisions to help diagnose multi-directory merge safety.
187
-
188
- Unity resource retrieval is opt-in on `query/context` via `unity_resources: off|on|auto` (default: `off`). Use `--unity-resources on` when you need `resourceBindings`, `serializedFields`, `resolvedReferences`, and `unityDiagnostics` in output.
189
-
190
- ## Unity Benchmark
191
-
192
- Run reproducible Unity/C# accuracy and regression checks:
193
-
194
- ```bash
195
- gitnexus benchmark-unity ../benchmarks/unity-baseline/v1 --profile quick --target-path ../benchmarks/fixtures/unity-mini
196
- gitnexus benchmark-unity ../benchmarks/unity-baseline/v1 --profile full --target-path ../benchmarks/fixtures/unity-mini
197
152
  ```
198
153
 
199
- Reports are written to `.gitnexus/benchmark/benchmark-report.json` and `.gitnexus/benchmark/benchmark-summary.md`.
154
+ ## Multi-Repo Support
200
155
 
201
- Hard gates:
156
+ GitNexus supports indexing multiple repositories. Each `npx -y @veewo/gitnexus@latest analyze` registers the repo in a global registry (`~/.gitnexus/registry.json`). The MCP server serves all indexed repos automatically.
202
157
 
203
- | Metric | Threshold |
204
- |--------|-----------|
205
- | Query precision | `>= 0.90` |
206
- | Query recall | `>= 0.85` |
207
- | Context/impact F1 | `>= 0.80` |
208
- | Smoke pass rate | `= 1.00` |
209
- | Analyze time regression | `<= +15%` |
158
+ ## Supported Languages
210
159
 
211
- ## Multi-Repo Support
160
+ TypeScript, JavaScript, Python, Java, C, C++, C#, Go, Rust, PHP, Kotlin, Swift, Ruby
212
161
 
213
- GitNexus supports indexing multiple repositories. Each `gitnexus analyze` registers the repo in a global registry (`~/.gitnexus/registry.json`). The MCP server serves all indexed repos automatically.
162
+ ### Language Feature Matrix
214
163
 
215
- ## Supported Languages
164
+ | Language | Imports | Named Bindings | Exports | Heritage | Type Annotations | Constructor Inference | Config | Frameworks | Entry Points |
165
+ |----------|---------|----------------|---------|----------|-----------------|---------------------|--------|------------|-------------|
166
+ | TypeScript | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
167
+ | JavaScript | ✓ | ✓ | ✓ | ✓ | — | ✓ | ✓ | ✓ | ✓ |
168
+ | Python | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
169
+ | Java | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | ✓ | ✓ |
170
+ | Kotlin | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | ✓ | ✓ |
171
+ | C# | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
172
+ | Go | ✓ | — | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
173
+ | Rust | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | ✓ | ✓ |
174
+ | PHP | ✓ | ✓ | ✓ | — | ✓ | ✓ | ✓ | ✓ | ✓ |
175
+ | Ruby | ✓ | — | ✓ | ✓ | — | ✓ | — | ✓ | ✓ |
176
+ | Swift | — | — | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
177
+ | C | — | — | ✓ | — | ✓ | ✓ | — | ✓ | ✓ |
178
+ | C++ | — | — | ✓ | ✓ | ✓ | ✓ | — | ✓ | ✓ |
216
179
 
217
- TypeScript, JavaScript, Python, Java, C, C++, C#, Go, Rust
180
+ **Imports** — cross-file import resolution · **Named Bindings** — `import { X as Y }` / re-export tracking · **Exports** — public/exported symbol detection · **Heritage** — class inheritance, interfaces, mixins · **Type Annotations** — explicit type extraction for receiver resolution · **Constructor Inference** — infer receiver type from constructor calls (`self`/`this` resolution included for all languages) · **Config** — language toolchain config parsing (tsconfig, go.mod, etc.) · **Frameworks** — AST-based framework pattern detection · **Entry Points** — entry point scoring heuristics
218
181
 
219
182
  ## Agent Skills
220
183
 
@@ -225,13 +188,7 @@ GitNexus ships with skill files that teach AI agents how to use the tools effect
225
188
  - **Impact Analysis** — Analyze blast radius before changes
226
189
  - **Refactoring** — Plan safe refactors using dependency mapping
227
190
 
228
- Installation rules:
229
-
230
- - `gitnexus setup` controls skill scope:
231
- - requires `--agent <claude|opencode|codex>`
232
- - default `global`: installs to `~/.agents/skills/gitnexus/`
233
- - `--scope project`: installs to `.agents/skills/gitnexus/` in current repo
234
- - `gitnexus analyze` always updates `AGENTS.md` / `CLAUDE.md`; skill install follows configured setup scope.
191
+ Installed automatically by both `npx -y @veewo/gitnexus@latest analyze` (per-repo) and `gitnexus setup` (global).
235
192
 
236
193
  ## Requirements
237
194
 
@@ -1,4 +1,4 @@
1
- import { closeKuzu } from '../../mcp/core/kuzu-adapter.js';
1
+ import { closeLbug } from '../../mcp/core/lbug-adapter.js';
2
2
  import { LocalBackend } from '../../mcp/local/local-backend.js';
3
3
  export async function createAgentContextToolRunner() {
4
4
  const backend = new LocalBackend();
@@ -12,7 +12,7 @@ export async function createAgentContextToolRunner() {
12
12
  impact: (params) => backend.callTool('impact', params),
13
13
  cypher: (params) => backend.callTool('cypher', params),
14
14
  close: async () => {
15
- await closeKuzu();
15
+ await closeLbug();
16
16
  },
17
17
  };
18
18
  }
@@ -2,7 +2,7 @@ import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import { pathToFileURL } from 'node:url';
4
4
  import { listRegisteredRepos } from '../storage/repo-manager.js';
5
- import { closeKuzu, executeQuery, initKuzu } from '../mcp/core/kuzu-adapter.js';
5
+ import { closeLbug, executeQuery, initLbug } from '../mcp/core/lbug-adapter.js';
6
6
  const ALLOWED_PREFIXES = ['Assets/NEON/Code/', 'Packages/com.veewo.', 'Packages/com.neonspark.'];
7
7
  export function filterNeonsparkPaths(rows) {
8
8
  return rows.filter((r) => {
@@ -25,7 +25,7 @@ export async function extractCandidates(repoName, outFile) {
25
25
  const repo = repos.find((r) => r.name === repoName);
26
26
  if (!repo)
27
27
  throw new Error(`repo not indexed: ${repoName}`);
28
- await initKuzu(repoName, path.join(repo.storagePath, 'kuzu'));
28
+ await initLbug(repoName, path.join(repo.storagePath, 'lbug'));
29
29
  try {
30
30
  const rows = await executeQuery(repoName, `
31
31
  MATCH (s:Class)
@@ -67,7 +67,7 @@ export async function extractCandidates(repoName, outFile) {
67
67
  return normalized.length;
68
68
  }
69
69
  finally {
70
- await closeKuzu(repoName);
70
+ await closeLbug(repoName);
71
71
  }
72
72
  }
73
73
  export function parseCandidatesCliArgs(argv) {
@@ -1,4 +1,4 @@
1
- import { closeKuzu } from '../mcp/core/kuzu-adapter.js';
1
+ import { closeLbug } from '../mcp/core/lbug-adapter.js';
2
2
  import { LocalBackend } from '../mcp/local/local-backend.js';
3
3
  export async function createToolRunner() {
4
4
  const backend = new LocalBackend();
@@ -11,7 +11,7 @@ export async function createToolRunner() {
11
11
  context: (params) => backend.callTool('context', params),
12
12
  impact: (params) => backend.callTool('impact', params),
13
13
  close: async () => {
14
- await closeKuzu();
14
+ await closeLbug();
15
15
  },
16
16
  };
17
17
  }
@@ -5,6 +5,7 @@
5
5
  * AGENTS.md is the standard read by Cursor, Windsurf, OpenCode, Codex, Cline, etc.
6
6
  * CLAUDE.md is for Claude Code which only reads that file.
7
7
  */
8
+ import { type GeneratedSkillInfo } from './skill-gen.js';
8
9
  type SkillScope = 'project' | 'global';
9
10
  interface RepoStats {
10
11
  files?: number;
@@ -19,7 +20,7 @@ interface RepoStats {
19
20
  */
20
21
  export declare function generateAIContextFiles(repoPath: string, _storagePath: string, projectName: string, stats: RepoStats, options?: {
21
22
  skillScope?: SkillScope;
22
- }): Promise<{
23
+ }, generatedSkills?: GeneratedSkillInfo[]): Promise<{
23
24
  files: string[];
24
25
  }>;
25
26
  export {};
@@ -16,17 +16,21 @@ const GITNEXUS_END_MARKER = '<!-- gitnexus:end -->';
16
16
  /**
17
17
  * Generate the full GitNexus context content.
18
18
  *
19
- * Design principles (learned from real agent behavior):
20
- * - AGENTS.md is the ROUTER it tells the agent WHICH skill to read
21
- * - Skills contain the actual workflowsAGENTS.md does NOT duplicate them
22
- * - Bold **IMPORTANT** block + "Skills Read First" heading agents skip soft suggestions
23
- * - One-line quick start (read context resource) gives agents an entry point
24
- * - Tools/Resources sections are labeled "Reference"agents treat them as lookup, not workflow
19
+ * Design principles (learned from real agent behavior and industry research):
20
+ * - Inline critical workflowsskills are skipped 56% of the time (Vercel eval data)
21
+ * - Use RFC 2119 language (MUST, NEVER, ALWAYS) models follow imperative rules
22
+ * - Three-tier boundaries (Always/When/Never)proven to change model behavior
23
+ * - Keep under 120 lines adherence degrades past 150 lines
24
+ * - Exact tool commands with parametersvague directives get ignored
25
+ * - Self-review checklist — forces model to verify its own work
25
26
  */
26
- function generateGitNexusContent(projectName, stats, skillScope) {
27
+ function generateGitNexusContent(projectName, stats, skillScope, generatedSkills) {
27
28
  const skillRoot = skillScope === 'global'
28
29
  ? '~/.agents/skills/gitnexus'
29
30
  : '.agents/skills/gitnexus';
31
+ const generatedRows = (generatedSkills && generatedSkills.length > 0)
32
+ ? `\n${generatedSkills.map((s) => `| Work in the ${s.label} area (${s.symbolCount} symbols) | \`.claude/skills/generated/${s.name}/SKILL.md\` |`).join('\n')}`
33
+ : '';
30
34
  return `${GITNEXUS_START_MARKER}
31
35
  # GitNexus MCP
32
36
 
@@ -38,7 +42,7 @@ This project is indexed by GitNexus as **${projectName}** (${stats.nodes || 0} s
38
42
  2. **Match your task to a skill below** and **read that skill file**
39
43
  3. **Follow the skill's workflow and checklist**
40
44
 
41
- > If step 1 warns the index is stale, ask user whether to rebuild index via \`npx -y gitnexus analyze\` first (it reuses previous analyze scope/options by default; add \`--no-reuse-options\` to reset). If user declines, explicitly warn that retrieval may not reflect current codebase. For build/analyze/test commands, use a 10-30 minute timeout; on failure/timeout, report exact tool output and do not auto-retry or silently fall back to glob/grep.
45
+ > If step 1 warns the index is stale, ask user whether to rebuild index via \`npx -y @veewo/gitnexus@latest analyze\` first (it reuses previous analyze scope/options by default; add \`--no-reuse-options\` to reset). If user declines, explicitly warn that retrieval may not reflect current codebase. For build/analyze/test commands, use a 10-30 minute timeout; on failure/timeout, report exact tool output and do not auto-retry or silently fall back to glob/grep.
42
46
 
43
47
  ## Skills
44
48
 
@@ -49,7 +53,7 @@ This project is indexed by GitNexus as **${projectName}** (${stats.nodes || 0} s
49
53
  | Trace bugs / "Why is X failing?" | \`${skillRoot}/gitnexus-debugging/SKILL.md\` |
50
54
  | Rename / extract / split / refactor | \`${skillRoot}/gitnexus-refactoring/SKILL.md\` |
51
55
  | Tools, resources, schema reference | \`${skillRoot}/gitnexus-guide/SKILL.md\` |
52
- | Index, status, clean, wiki CLI commands | \`${skillRoot}/gitnexus-cli/SKILL.md\` |
56
+ | Index, status, clean, wiki CLI commands | \`${skillRoot}/gitnexus-cli/SKILL.md\` |${generatedRows}
53
57
 
54
58
  ${GITNEXUS_END_MARKER}`;
55
59
  }
@@ -81,7 +85,7 @@ async function upsertGitNexusSection(filePath, content) {
81
85
  // Check if GitNexus section already exists
82
86
  const startIdx = existingContent.indexOf(GITNEXUS_START_MARKER);
83
87
  const endIdx = existingContent.indexOf(GITNEXUS_END_MARKER);
84
- if (startIdx !== -1 && endIdx !== -1) {
88
+ if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
85
89
  // Replace existing section
86
90
  const before = existingContent.substring(0, startIdx);
87
91
  const after = existingContent.substring(endIdx + GITNEXUS_END_MARKER.length);
@@ -167,9 +171,9 @@ Use GitNexus tools to accomplish this task.
167
171
  /**
168
172
  * Generate AI context files after indexing
169
173
  */
170
- export async function generateAIContextFiles(repoPath, _storagePath, projectName, stats, options) {
174
+ export async function generateAIContextFiles(repoPath, _storagePath, projectName, stats, options, generatedSkills) {
171
175
  const skillScope = options?.skillScope === 'global' ? 'global' : 'project';
172
- const content = generateGitNexusContent(projectName, stats, skillScope);
176
+ const content = generateGitNexusContent(projectName, stats, skillScope, generatedSkills);
173
177
  const createdFiles = [];
174
178
  // Create AGENTS.md (standard for Cursor, Windsurf, OpenCode, Codex, Cline, etc.)
175
179
  const agentsPath = path.join(repoPath, 'AGENTS.md');
@@ -11,5 +11,7 @@ export interface AnalyzeOptions {
11
11
  scopeManifest?: string;
12
12
  scopePrefix?: string[];
13
13
  reuseOptions?: boolean;
14
+ skills?: boolean;
15
+ verbose?: boolean;
14
16
  }
15
17
  export declare const analyzeCommand: (inputPath?: string, options?: AnalyzeOptions) => Promise<void>;
@@ -8,20 +8,19 @@ import { execFileSync } from 'child_process';
8
8
  import v8 from 'v8';
9
9
  import cliProgress from 'cli-progress';
10
10
  import { runPipelineFromRepo } from '../core/ingestion/pipeline.js';
11
- import { initKuzu, loadGraphToKuzu, getKuzuStats, executeQuery, executeWithReusedStatement, closeKuzu, createFTSIndex, loadCachedEmbeddings } from '../core/kuzu/kuzu-adapter.js';
11
+ import { initLbug, loadGraphToLbug, getLbugStats, executeQuery, executeWithReusedStatement, closeLbug, createFTSIndex, loadCachedEmbeddings } from '../core/lbug/lbug-adapter.js';
12
12
  // Embedding imports are lazy (dynamic import) so onnxruntime-node is never
13
13
  // loaded when embeddings are not requested. This avoids crashes on Node
14
14
  // versions whose ABI is not yet supported by the native binary (#89).
15
15
  // disposeEmbedder intentionally not called — ONNX Runtime segfaults on cleanup (see #38)
16
- import { getStoragePaths, saveMeta, loadMeta, addToGitignore, registerRepo, getGlobalRegistryPath, loadCLIConfig } from '../storage/repo-manager.js';
16
+ import { getStoragePaths, saveMeta, loadMeta, addToGitignore, registerRepo, getGlobalRegistryPath, loadCLIConfig, cleanupOldKuzuFiles } from '../storage/repo-manager.js';
17
17
  import { getCurrentCommit, isGitRepo, getGitRoot } from '../storage/git.js';
18
18
  import { generateAIContextFiles } from './ai-context.js';
19
+ import { generateSkillFiles } from './skill-gen.js';
19
20
  import fs from 'fs/promises';
20
- import { registerClaudeHook } from './claude-hooks.js';
21
21
  import { resolveEffectiveAnalyzeOptions } from './analyze-options.js';
22
22
  import { formatFallbackSummary, formatUnityDiagnosticsSummary } from './analyze-summary.js';
23
23
  import { resolveChildProcessExit } from './exit-code.js';
24
- import { shouldCloseKuzuOnAnalyzeExit } from './analyze-close-policy.js';
25
24
  import { toPipelineRuntimeSummary } from './analyze-runtime-summary.js';
26
25
  const HEAP_MB = 8192;
27
26
  const HEAP_FLAG = `--max-old-space-size=${HEAP_MB}`;
@@ -60,7 +59,7 @@ const PHASE_LABELS = {
60
59
  communities: 'Detecting communities',
61
60
  processes: 'Detecting processes',
62
61
  complete: 'Pipeline complete',
63
- kuzu: 'Loading into KuzuDB',
62
+ lbug: 'Loading into LadybugDB',
64
63
  fts: 'Creating search indexes',
65
64
  embeddings: 'Generating embeddings',
66
65
  done: 'Done',
@@ -68,6 +67,9 @@ const PHASE_LABELS = {
68
67
  export const analyzeCommand = async (inputPath, options) => {
69
68
  if (ensureHeap())
70
69
  return;
70
+ if (options?.verbose) {
71
+ process.env.GITNEXUS_VERBOSE = '1';
72
+ }
71
73
  console.log('\n GitNexus Analyzer\n');
72
74
  let repoPath;
73
75
  if (inputPath) {
@@ -87,7 +89,13 @@ export const analyzeCommand = async (inputPath, options) => {
87
89
  process.exitCode = 1;
88
90
  return;
89
91
  }
90
- const { storagePath, kuzuPath } = getStoragePaths(repoPath);
92
+ const { storagePath, lbugPath } = getStoragePaths(repoPath);
93
+ // Clean up stale KuzuDB files from before the LadybugDB migration.
94
+ // If kuzu existed but lbug doesn't, we're doing a migration re-index — say so.
95
+ const kuzuResult = await cleanupOldKuzuFiles(storagePath);
96
+ if (kuzuResult.found && kuzuResult.needsReindex) {
97
+ console.log(' Migrating from KuzuDB to LadybugDB — rebuilding index...\n');
98
+ }
91
99
  const currentCommit = getCurrentCommit(repoPath);
92
100
  const existingMeta = await loadMeta(storagePath);
93
101
  let includeExtensions = [];
@@ -113,7 +121,7 @@ export const analyzeCommand = async (inputPath, options) => {
113
121
  process.exitCode = 1;
114
122
  return;
115
123
  }
116
- if (existingMeta && !options?.force && existingMeta.lastCommit === currentCommit) {
124
+ if (existingMeta && !options?.force && existingMeta.lastCommit === currentCommit && !options?.skills) {
117
125
  const hasScopePrefixInput = Array.isArray(options?.scopePrefix)
118
126
  ? options.scopePrefix.length > 0
119
127
  : Boolean(options?.scopePrefix);
@@ -136,6 +144,9 @@ export const analyzeCommand = async (inputPath, options) => {
136
144
  return;
137
145
  }
138
146
  }
147
+ if (process.env.GITNEXUS_NO_GITIGNORE) {
148
+ console.log(' GITNEXUS_NO_GITIGNORE is set — skipping .gitignore (still reading .gitnexusignore)\n');
149
+ }
139
150
  // Single progress bar for entire pipeline
140
151
  const bar = new cliProgress.SingleBar({
141
152
  format: ' {bar} {percentage}% | {phase}',
@@ -156,11 +167,7 @@ export const analyzeCommand = async (inputPath, options) => {
156
167
  aborted = true;
157
168
  bar.stop();
158
169
  console.log('\n Interrupted — cleaning up...');
159
- if (!shouldCloseKuzuOnAnalyzeExit()) {
160
- process.exit(130);
161
- return;
162
- }
163
- closeKuzu().catch(() => { }).finally(() => process.exit(130));
170
+ closeLbug().catch(() => { }).finally(() => process.exit(130));
164
171
  };
165
172
  process.on('SIGINT', sigintHandler);
166
173
  // Route all console output through bar.log() so the bar doesn't stamp itself
@@ -206,15 +213,15 @@ export const analyzeCommand = async (inputPath, options) => {
206
213
  if (embeddingsEnabled && existingMeta && !options?.force) {
207
214
  try {
208
215
  updateBar(0, 'Caching embeddings...');
209
- await initKuzu(kuzuPath);
216
+ await initLbug(lbugPath);
210
217
  const cached = await loadCachedEmbeddings();
211
218
  cachedEmbeddingNodeIds = cached.embeddingNodeIds;
212
219
  cachedEmbeddings = cached.embeddings;
213
- await closeKuzu();
220
+ await closeLbug();
214
221
  }
215
222
  catch {
216
223
  try {
217
- await closeKuzu();
224
+ await closeLbug();
218
225
  }
219
226
  catch { }
220
227
  }
@@ -239,28 +246,29 @@ export const analyzeCommand = async (inputPath, options) => {
239
246
  process.exitCode = 1;
240
247
  return;
241
248
  }
242
- // ── Phase 2: KuzuDB (60–85%) ──────────────────────────────────────
243
- updateBar(60, 'Loading into KuzuDB...');
244
- await closeKuzu();
245
- const kuzuFiles = [kuzuPath, `${kuzuPath}.wal`, `${kuzuPath}.lock`];
246
- for (const f of kuzuFiles) {
249
+ // ── Phase 2: LadybugDB (60–85%) ──────────────────────────────────────
250
+ updateBar(60, 'Loading into LadybugDB...');
251
+ await closeLbug();
252
+ const lbugFiles = [lbugPath, `${lbugPath}.wal`, `${lbugPath}.lock`];
253
+ for (const f of lbugFiles) {
247
254
  try {
248
255
  await fs.rm(f, { recursive: true, force: true });
249
256
  }
250
257
  catch { }
251
258
  }
252
- const t0Kuzu = Date.now();
253
- await initKuzu(kuzuPath);
254
- let kuzuMsgCount = 0;
255
- const kuzuResult = await loadGraphToKuzu(pipelineResult.graph, pipelineResult.repoPath, storagePath, (msg) => {
256
- kuzuMsgCount++;
257
- const progress = Math.min(84, 60 + Math.round((kuzuMsgCount / (kuzuMsgCount + 10)) * 24));
259
+ const t0Lbug = Date.now();
260
+ await initLbug(lbugPath);
261
+ let lbugMsgCount = 0;
262
+ const lbugResult = await loadGraphToLbug(pipelineResult.graph, pipelineResult.repoPath, storagePath, (msg) => {
263
+ lbugMsgCount++;
264
+ const progress = Math.min(84, 60 + Math.round((lbugMsgCount / (lbugMsgCount + 10)) * 24));
258
265
  updateBar(progress, msg);
259
266
  });
267
+ const pipelineForSkills = pipelineResult;
260
268
  const pipelineRuntime = toPipelineRuntimeSummary(pipelineResult);
261
269
  pipelineResult = undefined;
262
- const kuzuTime = ((Date.now() - t0Kuzu) / 1000).toFixed(1);
263
- const kuzuWarnings = kuzuResult.warnings;
270
+ const lbugTime = ((Date.now() - t0Lbug) / 1000).toFixed(1);
271
+ const lbugWarnings = lbugResult.warnings;
264
272
  // ── Phase 3: FTS (85–90%) ─────────────────────────────────────────
265
273
  updateBar(85, 'Creating search indexes...');
266
274
  const t0Fts = Date.now();
@@ -289,7 +297,7 @@ export const analyzeCommand = async (inputPath, options) => {
289
297
  }
290
298
  }
291
299
  // ── Phase 4: Embeddings (90–98%) ──────────────────────────────────
292
- const stats = await getKuzuStats();
300
+ const stats = await getLbugStats();
293
301
  let embeddingTime = '0.0';
294
302
  let embeddingSkipped = true;
295
303
  let embeddingSkipReason = 'off (use --embeddings to enable)';
@@ -314,6 +322,13 @@ export const analyzeCommand = async (inputPath, options) => {
314
322
  }
315
323
  // ── Phase 5: Finalize (98–100%) ───────────────────────────────────
316
324
  updateBar(98, 'Saving metadata...');
325
+ // Count embeddings in the index (cached + newly generated)
326
+ let embeddingCount = 0;
327
+ try {
328
+ const embResult = await executeQuery(`MATCH (e:CodeEmbedding) RETURN count(e) AS cnt`);
329
+ embeddingCount = embResult?.[0]?.cnt ?? 0;
330
+ }
331
+ catch { /* table may not exist if embeddings never ran */ }
317
332
  const meta = {
318
333
  repoPath,
319
334
  lastCommit: currentCommit,
@@ -330,13 +345,13 @@ export const analyzeCommand = async (inputPath, options) => {
330
345
  edges: stats.edges,
331
346
  communities: pipelineRuntime.communityResult?.stats.totalCommunities,
332
347
  processes: pipelineRuntime.processResult?.stats.totalProcesses,
348
+ embeddings: embeddingCount,
333
349
  },
334
350
  };
335
351
  await saveMeta(storagePath, meta);
336
352
  await persistUnityParitySeed(storagePath, pipelineRuntime.unityResult?.paritySeed);
337
353
  const registeredRepo = await registerRepo(repoPath, meta, { repoAlias });
338
354
  await addToGitignore(repoPath);
339
- const hookResult = await registerClaudeHook();
340
355
  const projectName = path.basename(repoPath);
341
356
  let aggregatedClusterCount = 0;
342
357
  if (pipelineRuntime.communityResult?.communities) {
@@ -347,6 +362,12 @@ export const analyzeCommand = async (inputPath, options) => {
347
362
  }
348
363
  aggregatedClusterCount = Array.from(groups.values()).filter(count => count >= 5).length;
349
364
  }
365
+ let generatedSkills = [];
366
+ if (options?.skills && pipelineForSkills.communityResult) {
367
+ updateBar(99, 'Generating skill files...');
368
+ const skillResult = await generateSkillFiles(repoPath, projectName, pipelineForSkills);
369
+ generatedSkills = skillResult.skills;
370
+ }
350
371
  const aiContext = await generateAIContextFiles(repoPath, storagePath, projectName, {
351
372
  files: pipelineRuntime.totalFileCount,
352
373
  nodes: stats.nodes,
@@ -356,10 +377,8 @@ export const analyzeCommand = async (inputPath, options) => {
356
377
  processes: pipelineRuntime.processResult?.stats.totalProcesses,
357
378
  }, {
358
379
  skillScope: ((await loadCLIConfig()).setupScope === 'global') ? 'global' : 'project',
359
- });
360
- if (shouldCloseKuzuOnAnalyzeExit()) {
361
- await closeKuzu();
362
- }
380
+ }, generatedSkills);
381
+ await closeLbug();
363
382
  // Note: we intentionally do NOT call disposeEmbedder() here.
364
383
  // ONNX Runtime's native cleanup segfaults on macOS and some Linux configs.
365
384
  // Since the process exits immediately after, Node.js reclaims everything.
@@ -399,7 +418,7 @@ export const analyzeCommand = async (inputPath, options) => {
399
418
  console.log(` ${line}`);
400
419
  }
401
420
  console.log(` ${stats.nodes.toLocaleString()} nodes | ${stats.edges.toLocaleString()} edges | ${pipelineRuntime.communityResult?.stats.totalCommunities || 0} clusters | ${pipelineRuntime.processResult?.stats.totalProcesses || 0} flows`);
402
- console.log(` KuzuDB ${kuzuTime}s | FTS ${ftsTime}s | Embeddings ${embeddingSkipped ? embeddingSkipReason : embeddingTime + 's'}`);
421
+ console.log(` LadybugDB ${lbugTime}s | FTS ${ftsTime}s | Embeddings ${embeddingSkipped ? embeddingSkipReason : embeddingTime + 's'}`);
403
422
  if (includeExtensions.length > 0) {
404
423
  console.log(` File filter: ${includeExtensions.join(', ')}`);
405
424
  }
@@ -407,16 +426,19 @@ export const analyzeCommand = async (inputPath, options) => {
407
426
  if (aiContext.files.length > 0) {
408
427
  console.log(` Context: ${aiContext.files.join(', ')}`);
409
428
  }
410
- if (hookResult.registered) {
411
- console.log(` Hooks: ${hookResult.message}`);
412
- }
413
- // Show fallback summary with pair-level preview and explicit outcomes
414
- if (kuzuWarnings.length > 0) {
415
- const fallbackLines = formatFallbackSummary(kuzuWarnings, kuzuResult.fallbackStats);
429
+ if (lbugWarnings.length > 0) {
430
+ const totalFallback = lbugWarnings.reduce((sum, warning) => {
431
+ const match = warning.match(/\((\d+) edges\)/);
432
+ return sum + (match ? Number.parseInt(match[1], 10) : 0);
433
+ }, 0);
434
+ const fallbackLines = formatFallbackSummary(lbugWarnings, {
435
+ attempted: totalFallback,
436
+ succeeded: totalFallback,
437
+ failed: 0,
438
+ });
416
439
  for (const line of fallbackLines) {
417
440
  console.log(` ${line}`);
418
441
  }
419
- console.log(' Note: schema pair coverage should be updated when fallback failures are non-zero');
420
442
  }
421
443
  try {
422
444
  await fs.access(getGlobalRegistryPath());
@@ -425,12 +447,10 @@ export const analyzeCommand = async (inputPath, options) => {
425
447
  console.log('\n Tip: Run `gitnexus setup` to configure MCP for your editor.');
426
448
  }
427
449
  console.log('');
428
- // ONNX Runtime registers native atexit hooks that segfault during process
429
- // shutdown on macOS (#38) and some Linux configs (#40). Force-exit to
430
- // bypass them when embeddings were loaded.
431
- if (!embeddingSkipped) {
432
- process.exit(0);
433
- }
450
+ // LadybugDB's native module holds open handles that prevent Node from exiting.
451
+ // ONNX Runtime also registers native atexit hooks that segfault on some
452
+ // platforms (#38, #40). Force-exit to ensure clean termination.
453
+ process.exit(0);
434
454
  };
435
455
  async function persistUnityParitySeed(storagePath, seed) {
436
456
  const seedPath = path.join(storagePath, 'unity-parity-seed.json');
@@ -19,7 +19,7 @@ export async function augmentCommand(pattern) {
19
19
  const result = await augment(pattern, process.cwd());
20
20
  if (result) {
21
21
  // IMPORTANT: Write to stderr, NOT stdout.
22
- // KuzuDB's native module captures stdout fd at OS level during init,
22
+ // LadybugDB's native module captures stdout fd at OS level during init,
23
23
  // which makes stdout permanently broken in subprocess contexts.
24
24
  // stderr is never captured, so it works reliably everywhere.
25
25
  // The hook reads from the subprocess's stderr.
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Eval Server — Lightweight HTTP server for SWE-bench evaluation
3
3
  *
4
- * Keeps KuzuDB warm in memory so tool calls from the agent are near-instant.
4
+ * Keeps LadybugDB warm in memory so tool calls from the agent are near-instant.
5
5
  * Designed to run inside Docker containers during SWE-bench evaluation.
6
6
  *
7
7
  * KEY DESIGN: Returns LLM-friendly text, not raw JSON.
@@ -27,4 +27,11 @@ export interface EvalServerOptions {
27
27
  port?: string;
28
28
  idleTimeout?: string;
29
29
  }
30
+ export declare function formatQueryResult(result: any): string;
31
+ export declare function formatContextResult(result: any): string;
32
+ export declare function formatImpactResult(result: any): string;
33
+ export declare function formatCypherResult(result: any): string;
34
+ export declare function formatDetectChangesResult(result: any): string;
35
+ export declare function formatListReposResult(result: any): string;
30
36
  export declare function evalServerCommand(options?: EvalServerOptions): Promise<void>;
37
+ export declare const MAX_BODY_SIZE: number;