@duytransipher/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 (230) hide show
  1. package/LICENSE +73 -0
  2. package/README.md +261 -0
  3. package/dist/cli/ai-context.d.ts +23 -0
  4. package/dist/cli/ai-context.js +265 -0
  5. package/dist/cli/analyze.d.ts +12 -0
  6. package/dist/cli/analyze.js +345 -0
  7. package/dist/cli/augment.d.ts +13 -0
  8. package/dist/cli/augment.js +33 -0
  9. package/dist/cli/clean.d.ts +10 -0
  10. package/dist/cli/clean.js +60 -0
  11. package/dist/cli/eval-server.d.ts +37 -0
  12. package/dist/cli/eval-server.js +389 -0
  13. package/dist/cli/index.d.ts +2 -0
  14. package/dist/cli/index.js +137 -0
  15. package/dist/cli/lazy-action.d.ts +6 -0
  16. package/dist/cli/lazy-action.js +18 -0
  17. package/dist/cli/list.d.ts +6 -0
  18. package/dist/cli/list.js +30 -0
  19. package/dist/cli/mcp.d.ts +8 -0
  20. package/dist/cli/mcp.js +36 -0
  21. package/dist/cli/serve.d.ts +4 -0
  22. package/dist/cli/serve.js +6 -0
  23. package/dist/cli/setup.d.ts +8 -0
  24. package/dist/cli/setup.js +367 -0
  25. package/dist/cli/sipher-patched.d.ts +2 -0
  26. package/dist/cli/sipher-patched.js +77 -0
  27. package/dist/cli/skill-gen.d.ts +26 -0
  28. package/dist/cli/skill-gen.js +549 -0
  29. package/dist/cli/status.d.ts +6 -0
  30. package/dist/cli/status.js +36 -0
  31. package/dist/cli/tool.d.ts +60 -0
  32. package/dist/cli/tool.js +180 -0
  33. package/dist/cli/wiki.d.ts +15 -0
  34. package/dist/cli/wiki.js +365 -0
  35. package/dist/config/ignore-service.d.ts +26 -0
  36. package/dist/config/ignore-service.js +284 -0
  37. package/dist/config/supported-languages.d.ts +15 -0
  38. package/dist/config/supported-languages.js +16 -0
  39. package/dist/core/augmentation/engine.d.ts +26 -0
  40. package/dist/core/augmentation/engine.js +240 -0
  41. package/dist/core/embeddings/embedder.d.ts +60 -0
  42. package/dist/core/embeddings/embedder.js +251 -0
  43. package/dist/core/embeddings/embedding-pipeline.d.ts +51 -0
  44. package/dist/core/embeddings/embedding-pipeline.js +356 -0
  45. package/dist/core/embeddings/index.d.ts +9 -0
  46. package/dist/core/embeddings/index.js +9 -0
  47. package/dist/core/embeddings/text-generator.d.ts +24 -0
  48. package/dist/core/embeddings/text-generator.js +182 -0
  49. package/dist/core/embeddings/types.d.ts +87 -0
  50. package/dist/core/embeddings/types.js +32 -0
  51. package/dist/core/graph/graph.d.ts +2 -0
  52. package/dist/core/graph/graph.js +66 -0
  53. package/dist/core/graph/types.d.ts +66 -0
  54. package/dist/core/graph/types.js +1 -0
  55. package/dist/core/ingestion/ast-cache.d.ts +11 -0
  56. package/dist/core/ingestion/ast-cache.js +35 -0
  57. package/dist/core/ingestion/call-processor.d.ts +23 -0
  58. package/dist/core/ingestion/call-processor.js +793 -0
  59. package/dist/core/ingestion/call-routing.d.ts +68 -0
  60. package/dist/core/ingestion/call-routing.js +129 -0
  61. package/dist/core/ingestion/cluster-enricher.d.ts +38 -0
  62. package/dist/core/ingestion/cluster-enricher.js +170 -0
  63. package/dist/core/ingestion/community-processor.d.ts +39 -0
  64. package/dist/core/ingestion/community-processor.js +312 -0
  65. package/dist/core/ingestion/constants.d.ts +16 -0
  66. package/dist/core/ingestion/constants.js +16 -0
  67. package/dist/core/ingestion/entry-point-scoring.d.ts +40 -0
  68. package/dist/core/ingestion/entry-point-scoring.js +353 -0
  69. package/dist/core/ingestion/export-detection.d.ts +18 -0
  70. package/dist/core/ingestion/export-detection.js +231 -0
  71. package/dist/core/ingestion/filesystem-walker.d.ts +28 -0
  72. package/dist/core/ingestion/filesystem-walker.js +81 -0
  73. package/dist/core/ingestion/framework-detection.d.ts +54 -0
  74. package/dist/core/ingestion/framework-detection.js +411 -0
  75. package/dist/core/ingestion/heritage-processor.d.ts +28 -0
  76. package/dist/core/ingestion/heritage-processor.js +251 -0
  77. package/dist/core/ingestion/import-processor.d.ts +34 -0
  78. package/dist/core/ingestion/import-processor.js +398 -0
  79. package/dist/core/ingestion/language-config.d.ts +46 -0
  80. package/dist/core/ingestion/language-config.js +167 -0
  81. package/dist/core/ingestion/mro-processor.d.ts +45 -0
  82. package/dist/core/ingestion/mro-processor.js +369 -0
  83. package/dist/core/ingestion/named-binding-extraction.d.ts +61 -0
  84. package/dist/core/ingestion/named-binding-extraction.js +363 -0
  85. package/dist/core/ingestion/parsing-processor.d.ts +19 -0
  86. package/dist/core/ingestion/parsing-processor.js +315 -0
  87. package/dist/core/ingestion/pipeline.d.ts +6 -0
  88. package/dist/core/ingestion/pipeline.js +401 -0
  89. package/dist/core/ingestion/process-processor.d.ts +51 -0
  90. package/dist/core/ingestion/process-processor.js +315 -0
  91. package/dist/core/ingestion/resolution-context.d.ts +53 -0
  92. package/dist/core/ingestion/resolution-context.js +132 -0
  93. package/dist/core/ingestion/resolvers/csharp.d.ts +22 -0
  94. package/dist/core/ingestion/resolvers/csharp.js +109 -0
  95. package/dist/core/ingestion/resolvers/go.d.ts +19 -0
  96. package/dist/core/ingestion/resolvers/go.js +42 -0
  97. package/dist/core/ingestion/resolvers/index.d.ts +18 -0
  98. package/dist/core/ingestion/resolvers/index.js +13 -0
  99. package/dist/core/ingestion/resolvers/jvm.d.ts +23 -0
  100. package/dist/core/ingestion/resolvers/jvm.js +87 -0
  101. package/dist/core/ingestion/resolvers/php.d.ts +15 -0
  102. package/dist/core/ingestion/resolvers/php.js +35 -0
  103. package/dist/core/ingestion/resolvers/python.d.ts +19 -0
  104. package/dist/core/ingestion/resolvers/python.js +52 -0
  105. package/dist/core/ingestion/resolvers/ruby.d.ts +12 -0
  106. package/dist/core/ingestion/resolvers/ruby.js +15 -0
  107. package/dist/core/ingestion/resolvers/rust.d.ts +15 -0
  108. package/dist/core/ingestion/resolvers/rust.js +73 -0
  109. package/dist/core/ingestion/resolvers/standard.d.ts +28 -0
  110. package/dist/core/ingestion/resolvers/standard.js +123 -0
  111. package/dist/core/ingestion/resolvers/utils.d.ts +33 -0
  112. package/dist/core/ingestion/resolvers/utils.js +122 -0
  113. package/dist/core/ingestion/structure-processor.d.ts +2 -0
  114. package/dist/core/ingestion/structure-processor.js +36 -0
  115. package/dist/core/ingestion/symbol-table.d.ts +63 -0
  116. package/dist/core/ingestion/symbol-table.js +85 -0
  117. package/dist/core/ingestion/tree-sitter-queries.d.ts +15 -0
  118. package/dist/core/ingestion/tree-sitter-queries.js +888 -0
  119. package/dist/core/ingestion/type-env.d.ts +49 -0
  120. package/dist/core/ingestion/type-env.js +613 -0
  121. package/dist/core/ingestion/type-extractors/c-cpp.d.ts +2 -0
  122. package/dist/core/ingestion/type-extractors/c-cpp.js +385 -0
  123. package/dist/core/ingestion/type-extractors/csharp.d.ts +2 -0
  124. package/dist/core/ingestion/type-extractors/csharp.js +383 -0
  125. package/dist/core/ingestion/type-extractors/go.d.ts +2 -0
  126. package/dist/core/ingestion/type-extractors/go.js +467 -0
  127. package/dist/core/ingestion/type-extractors/index.d.ts +22 -0
  128. package/dist/core/ingestion/type-extractors/index.js +31 -0
  129. package/dist/core/ingestion/type-extractors/jvm.d.ts +3 -0
  130. package/dist/core/ingestion/type-extractors/jvm.js +681 -0
  131. package/dist/core/ingestion/type-extractors/php.d.ts +2 -0
  132. package/dist/core/ingestion/type-extractors/php.js +549 -0
  133. package/dist/core/ingestion/type-extractors/python.d.ts +2 -0
  134. package/dist/core/ingestion/type-extractors/python.js +455 -0
  135. package/dist/core/ingestion/type-extractors/ruby.d.ts +2 -0
  136. package/dist/core/ingestion/type-extractors/ruby.js +389 -0
  137. package/dist/core/ingestion/type-extractors/rust.d.ts +2 -0
  138. package/dist/core/ingestion/type-extractors/rust.js +456 -0
  139. package/dist/core/ingestion/type-extractors/shared.d.ts +145 -0
  140. package/dist/core/ingestion/type-extractors/shared.js +810 -0
  141. package/dist/core/ingestion/type-extractors/swift.d.ts +2 -0
  142. package/dist/core/ingestion/type-extractors/swift.js +137 -0
  143. package/dist/core/ingestion/type-extractors/types.d.ts +127 -0
  144. package/dist/core/ingestion/type-extractors/types.js +1 -0
  145. package/dist/core/ingestion/type-extractors/typescript.d.ts +2 -0
  146. package/dist/core/ingestion/type-extractors/typescript.js +494 -0
  147. package/dist/core/ingestion/utils.d.ts +138 -0
  148. package/dist/core/ingestion/utils.js +1290 -0
  149. package/dist/core/ingestion/workers/parse-worker.d.ts +122 -0
  150. package/dist/core/ingestion/workers/parse-worker.js +1126 -0
  151. package/dist/core/ingestion/workers/worker-pool.d.ts +16 -0
  152. package/dist/core/ingestion/workers/worker-pool.js +128 -0
  153. package/dist/core/lbug/csv-generator.d.ts +33 -0
  154. package/dist/core/lbug/csv-generator.js +366 -0
  155. package/dist/core/lbug/lbug-adapter.d.ts +103 -0
  156. package/dist/core/lbug/lbug-adapter.js +769 -0
  157. package/dist/core/lbug/schema.d.ts +53 -0
  158. package/dist/core/lbug/schema.js +430 -0
  159. package/dist/core/search/bm25-index.d.ts +23 -0
  160. package/dist/core/search/bm25-index.js +96 -0
  161. package/dist/core/search/hybrid-search.d.ts +49 -0
  162. package/dist/core/search/hybrid-search.js +118 -0
  163. package/dist/core/tree-sitter/parser-loader.d.ts +5 -0
  164. package/dist/core/tree-sitter/parser-loader.js +63 -0
  165. package/dist/core/wiki/generator.d.ts +120 -0
  166. package/dist/core/wiki/generator.js +939 -0
  167. package/dist/core/wiki/graph-queries.d.ts +80 -0
  168. package/dist/core/wiki/graph-queries.js +238 -0
  169. package/dist/core/wiki/html-viewer.d.ts +10 -0
  170. package/dist/core/wiki/html-viewer.js +297 -0
  171. package/dist/core/wiki/llm-client.d.ts +43 -0
  172. package/dist/core/wiki/llm-client.js +186 -0
  173. package/dist/core/wiki/prompts.d.ts +53 -0
  174. package/dist/core/wiki/prompts.js +174 -0
  175. package/dist/lib/utils.d.ts +1 -0
  176. package/dist/lib/utils.js +3 -0
  177. package/dist/mcp/compatible-stdio-transport.d.ts +25 -0
  178. package/dist/mcp/compatible-stdio-transport.js +200 -0
  179. package/dist/mcp/core/embedder.d.ts +27 -0
  180. package/dist/mcp/core/embedder.js +108 -0
  181. package/dist/mcp/core/lbug-adapter.d.ts +57 -0
  182. package/dist/mcp/core/lbug-adapter.js +455 -0
  183. package/dist/mcp/local/local-backend.d.ts +181 -0
  184. package/dist/mcp/local/local-backend.js +1722 -0
  185. package/dist/mcp/resources.d.ts +31 -0
  186. package/dist/mcp/resources.js +411 -0
  187. package/dist/mcp/server.d.ts +23 -0
  188. package/dist/mcp/server.js +296 -0
  189. package/dist/mcp/staleness.d.ts +15 -0
  190. package/dist/mcp/staleness.js +29 -0
  191. package/dist/mcp/tools.d.ts +24 -0
  192. package/dist/mcp/tools.js +292 -0
  193. package/dist/server/api.d.ts +10 -0
  194. package/dist/server/api.js +344 -0
  195. package/dist/server/mcp-http.d.ts +13 -0
  196. package/dist/server/mcp-http.js +100 -0
  197. package/dist/storage/git.d.ts +6 -0
  198. package/dist/storage/git.js +35 -0
  199. package/dist/storage/repo-manager.d.ts +138 -0
  200. package/dist/storage/repo-manager.js +299 -0
  201. package/dist/types/pipeline.d.ts +32 -0
  202. package/dist/types/pipeline.js +18 -0
  203. package/dist/unreal/bridge.d.ts +4 -0
  204. package/dist/unreal/bridge.js +113 -0
  205. package/dist/unreal/config.d.ts +6 -0
  206. package/dist/unreal/config.js +55 -0
  207. package/dist/unreal/types.d.ts +105 -0
  208. package/dist/unreal/types.js +1 -0
  209. package/hooks/claude/gitnexus-hook.cjs +238 -0
  210. package/hooks/claude/pre-tool-use.sh +79 -0
  211. package/hooks/claude/session-start.sh +42 -0
  212. package/package.json +100 -0
  213. package/scripts/ensure-cli-executable.cjs +21 -0
  214. package/scripts/patch-tree-sitter-swift.cjs +74 -0
  215. package/scripts/setup-unreal-gitnexus.ps1 +191 -0
  216. package/skills/gitnexus-cli.md +82 -0
  217. package/skills/gitnexus-debugging.md +89 -0
  218. package/skills/gitnexus-exploring.md +78 -0
  219. package/skills/gitnexus-guide.md +64 -0
  220. package/skills/gitnexus-impact-analysis.md +97 -0
  221. package/skills/gitnexus-pr-review.md +163 -0
  222. package/skills/gitnexus-refactoring.md +121 -0
  223. package/vendor/GitNexusUnreal/GitNexusUnreal.uplugin +18 -0
  224. package/vendor/GitNexusUnreal/Source/GitNexusUnreal/GitNexusUnreal.Build.cs +29 -0
  225. package/vendor/GitNexusUnreal/Source/GitNexusUnreal/Private/GitNexusBlueprintAnalyzerCommandlet.cpp +465 -0
  226. package/vendor/GitNexusUnreal/Source/GitNexusUnreal/Private/GitNexusUnrealModule.cpp +15 -0
  227. package/vendor/GitNexusUnreal/Source/GitNexusUnreal/Public/GitNexusBlueprintAnalyzerCommandlet.h +46 -0
  228. package/vendor/GitNexusUnreal/Source/GitNexusUnreal/Public/GitNexusUnrealModule.h +10 -0
  229. package/vendor/leiden/index.cjs +355 -0
  230. package/vendor/leiden/utils.cjs +392 -0
@@ -0,0 +1,296 @@
1
+ /**
2
+ * MCP Server (Multi-Repo)
3
+ *
4
+ * Model Context Protocol server that runs on stdio.
5
+ * External AI tools (Cursor, Claude) spawn this process and
6
+ * communicate via stdin/stdout using the MCP protocol.
7
+ *
8
+ * Supports multiple indexed repositories via the global registry.
9
+ *
10
+ * Tools: list_repos, query, cypher, context, impact, detect_changes, rename
11
+ * Resources: repos, repo/{name}/context, repo/{name}/clusters, ...
12
+ */
13
+ import { createRequire } from 'module';
14
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
15
+ import { CompatibleStdioServerTransport } from './compatible-stdio-transport.js';
16
+ import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListResourceTemplatesRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
17
+ import { GITNEXUS_TOOLS } from './tools.js';
18
+ import { realStdoutWrite } from './core/lbug-adapter.js';
19
+ import { getResourceDefinitions, getResourceTemplates, readResource } from './resources.js';
20
+ /**
21
+ * Next-step hints appended to tool responses.
22
+ *
23
+ * Agents often stop after one tool call. These hints guide them to the
24
+ * logical next action, creating a self-guiding workflow without hooks.
25
+ *
26
+ * Design: Each hint is a short, actionable instruction (not a suggestion).
27
+ * The hint references the specific tool/resource to use next.
28
+ */
29
+ function getNextStepHint(toolName, args) {
30
+ const repo = args?.repo;
31
+ const repoParam = repo ? `, repo: "${repo}"` : '';
32
+ const repoPath = repo || '{name}';
33
+ switch (toolName) {
34
+ case 'list_repos':
35
+ return `\n\n---\n**Next:** READ gitnexus://repo/{name}/context for any repo above to get its overview and check staleness.`;
36
+ case 'sync_unreal_asset_manifest':
37
+ return `\n\n---\n**Next:** Use find_native_blueprint_references({function: "<Class::Function>"${repoParam}}) to confirm Blueprint call sites from the refreshed manifest.`;
38
+ case 'find_native_blueprint_references':
39
+ return `\n\n---\n**Next:** Use expand_blueprint_chain({asset_path: "<asset_path>", chain_anchor_id: "<chain_anchor_id>"${repoParam}}) on any confirmed reference to walk the local Blueprint chain.`;
40
+ case 'expand_blueprint_chain':
41
+ return `\n\n---\n**Next:** Inspect adjacent anchor nodes from the returned chain, or rerun find_native_blueprint_references() for another native entry point.`;
42
+ case 'find_blueprints_derived_from_native_class':
43
+ return `\n\n---\n**Next:** Choose a native function on that class and run find_native_blueprint_references({function: "<Class::Function>"${repoParam}}).`;
44
+ case 'query':
45
+ return `\n\n---\n**Next:** To understand a specific symbol in depth, use context({name: "<symbol_name>"${repoParam}}) to see categorized refs and process participation.`;
46
+ case 'context':
47
+ return `\n\n---\n**Next:** If planning changes, use impact({target: "${args?.name || '<name>'}", direction: "upstream"${repoParam}}) to check blast radius. To see execution flows, READ gitnexus://repo/${repoPath}/processes.`;
48
+ case 'impact':
49
+ return `\n\n---\n**Next:** Review d=1 items first (WILL BREAK). To check affected execution flows, READ gitnexus://repo/${repoPath}/processes.`;
50
+ case 'detect_changes':
51
+ return `\n\n---\n**Next:** Review affected processes. Use context() on high-risk changed symbols. READ gitnexus://repo/${repoPath}/process/{name} for full execution traces.`;
52
+ case 'rename':
53
+ return `\n\n---\n**Next:** Run detect_changes(${repoParam ? `{repo: "${repo}"}` : ''}) to verify no unexpected side effects from the rename.`;
54
+ case 'cypher':
55
+ return `\n\n---\n**Next:** To explore a result symbol, use context({name: "<name>"${repoParam}}). For schema reference, READ gitnexus://repo/${repoPath}/schema.`;
56
+ // Legacy tool names — still return useful hints
57
+ case 'search':
58
+ return `\n\n---\n**Next:** To understand a result in context, use context({name: "<symbol_name>"${repoParam}}).`;
59
+ case 'explore':
60
+ return `\n\n---\n**Next:** If planning changes, use impact({target: "<name>", direction: "upstream"${repoParam}}).`;
61
+ case 'overview':
62
+ return `\n\n---\n**Next:** To drill into an area, READ gitnexus://repo/${repoPath}/cluster/{name}. To see execution flows, READ gitnexus://repo/${repoPath}/processes.`;
63
+ default:
64
+ return '';
65
+ }
66
+ }
67
+ /**
68
+ * Create a configured MCP Server with all handlers registered.
69
+ * Transport-agnostic — caller connects the desired transport.
70
+ */
71
+ export function createMCPServer(backend) {
72
+ const require = createRequire(import.meta.url);
73
+ const pkgVersion = require('../../package.json').version;
74
+ const server = new Server({
75
+ name: 'gitnexus',
76
+ version: pkgVersion,
77
+ }, {
78
+ capabilities: {
79
+ tools: {},
80
+ resources: {},
81
+ prompts: {},
82
+ },
83
+ });
84
+ // Handle list resources request
85
+ server.setRequestHandler(ListResourcesRequestSchema, async () => {
86
+ const resources = getResourceDefinitions();
87
+ return {
88
+ resources: resources.map(r => ({
89
+ uri: r.uri,
90
+ name: r.name,
91
+ description: r.description,
92
+ mimeType: r.mimeType,
93
+ })),
94
+ };
95
+ });
96
+ // Handle list resource templates request (for dynamic resources)
97
+ server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => {
98
+ const templates = getResourceTemplates();
99
+ return {
100
+ resourceTemplates: templates.map(t => ({
101
+ uriTemplate: t.uriTemplate,
102
+ name: t.name,
103
+ description: t.description,
104
+ mimeType: t.mimeType,
105
+ })),
106
+ };
107
+ });
108
+ // Handle read resource request
109
+ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
110
+ const { uri } = request.params;
111
+ try {
112
+ const content = await readResource(uri, backend);
113
+ return {
114
+ contents: [
115
+ {
116
+ uri,
117
+ mimeType: 'text/yaml',
118
+ text: content,
119
+ },
120
+ ],
121
+ };
122
+ }
123
+ catch (err) {
124
+ return {
125
+ contents: [
126
+ {
127
+ uri,
128
+ mimeType: 'text/plain',
129
+ text: `Error: ${err.message}`,
130
+ },
131
+ ],
132
+ };
133
+ }
134
+ });
135
+ // Handle list tools request
136
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
137
+ tools: GITNEXUS_TOOLS.map((tool) => ({
138
+ name: tool.name,
139
+ description: tool.description,
140
+ inputSchema: tool.inputSchema,
141
+ })),
142
+ }));
143
+ // Handle tool calls — append next-step hints to guide agent workflow
144
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
145
+ const { name, arguments: args } = request.params;
146
+ try {
147
+ const result = await backend.callTool(name, args);
148
+ const resultText = typeof result === 'string' ? result : JSON.stringify(result, null, 2);
149
+ const hint = getNextStepHint(name, args);
150
+ return {
151
+ content: [
152
+ {
153
+ type: 'text',
154
+ text: resultText + hint,
155
+ },
156
+ ],
157
+ };
158
+ }
159
+ catch (error) {
160
+ const message = error instanceof Error ? error.message : 'Unknown error';
161
+ return {
162
+ content: [
163
+ {
164
+ type: 'text',
165
+ text: `Error: ${message}`,
166
+ },
167
+ ],
168
+ isError: true,
169
+ };
170
+ }
171
+ });
172
+ // Handle list prompts request
173
+ server.setRequestHandler(ListPromptsRequestSchema, async () => ({
174
+ prompts: [
175
+ {
176
+ name: 'detect_impact',
177
+ description: 'Analyze the impact of your current changes before committing. Guides through scope selection, change detection, process analysis, and risk assessment.',
178
+ arguments: [
179
+ { name: 'scope', description: 'What to analyze: unstaged, staged, all, or compare', required: false },
180
+ { name: 'base_ref', description: 'Branch/commit for compare scope', required: false },
181
+ ],
182
+ },
183
+ {
184
+ name: 'generate_map',
185
+ description: 'Generate architecture documentation from the knowledge graph. Creates a codebase overview with execution flows and mermaid diagrams.',
186
+ arguments: [
187
+ { name: 'repo', description: 'Repository name (omit if only one indexed)', required: false },
188
+ ],
189
+ },
190
+ ],
191
+ }));
192
+ // Handle get prompt request
193
+ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
194
+ const { name, arguments: args } = request.params;
195
+ if (name === 'detect_impact') {
196
+ const scope = args?.scope || 'all';
197
+ const baseRef = args?.base_ref || '';
198
+ return {
199
+ messages: [
200
+ {
201
+ role: 'user',
202
+ content: {
203
+ type: 'text',
204
+ text: `Analyze the impact of my current code changes before committing.
205
+
206
+ Follow these steps:
207
+ 1. Run \`detect_changes(${JSON.stringify({ scope, ...(baseRef ? { base_ref: baseRef } : {}) })})\` to find what changed and affected processes
208
+ 2. For each changed symbol in critical processes, run \`context({name: "<symbol>"})\` to see its full reference graph
209
+ 3. For any high-risk items (many callers or cross-process), run \`impact({target: "<symbol>", direction: "upstream"})\` for blast radius
210
+ 4. Summarize: changes, affected processes, risk level, and recommended actions
211
+
212
+ Present the analysis as a clear risk report.`,
213
+ },
214
+ },
215
+ ],
216
+ };
217
+ }
218
+ if (name === 'generate_map') {
219
+ const repo = args?.repo || '';
220
+ return {
221
+ messages: [
222
+ {
223
+ role: 'user',
224
+ content: {
225
+ type: 'text',
226
+ text: `Generate architecture documentation for this codebase using the knowledge graph.
227
+
228
+ Follow these steps:
229
+ 1. READ \`gitnexus://repo/${repo || '{name}'}/context\` for codebase stats
230
+ 2. READ \`gitnexus://repo/${repo || '{name}'}/clusters\` to see all functional areas
231
+ 3. READ \`gitnexus://repo/${repo || '{name}'}/processes\` to see all execution flows
232
+ 4. For the top 5 most important processes, READ \`gitnexus://repo/${repo || '{name}'}/process/{name}\` for step-by-step traces
233
+ 5. Generate a mermaid architecture diagram showing the major areas and their connections
234
+ 6. Write an ARCHITECTURE.md file with: overview, functional areas, key execution flows, and the mermaid diagram`,
235
+ },
236
+ },
237
+ ],
238
+ };
239
+ }
240
+ throw new Error(`Unknown prompt: ${name}`);
241
+ });
242
+ return server;
243
+ }
244
+ /**
245
+ * Start the MCP server on stdio transport (for CLI use).
246
+ */
247
+ export async function startMCPServer(backend) {
248
+ const server = createMCPServer(backend);
249
+ // Use the shared stdout reference captured at module-load time by the
250
+ // lbug-adapter. Avoids divergence if anything patches stdout between
251
+ // module load and server start.
252
+ const _safeStdout = new Proxy(process.stdout, {
253
+ get(target, prop, receiver) {
254
+ if (prop === 'write')
255
+ return realStdoutWrite;
256
+ const val = Reflect.get(target, prop, receiver);
257
+ return typeof val === 'function' ? val.bind(target) : val;
258
+ }
259
+ });
260
+ const transport = new CompatibleStdioServerTransport(process.stdin, _safeStdout);
261
+ await server.connect(transport);
262
+ // Graceful shutdown helper
263
+ let shuttingDown = false;
264
+ const shutdown = async (exitCode = 0) => {
265
+ if (shuttingDown)
266
+ return;
267
+ shuttingDown = true;
268
+ try {
269
+ await backend.disconnect();
270
+ }
271
+ catch { }
272
+ try {
273
+ await server.close();
274
+ }
275
+ catch { }
276
+ process.exit(exitCode);
277
+ };
278
+ // Handle graceful shutdown
279
+ process.on('SIGINT', shutdown);
280
+ process.on('SIGTERM', shutdown);
281
+ // Log crashes to stderr so they aren't silently lost.
282
+ // uncaughtException is fatal — shut down.
283
+ // unhandledRejection is logged but kept non-fatal (availability-first):
284
+ // killing the server for one missed catch would be worse than logging it.
285
+ process.on('uncaughtException', (err) => {
286
+ process.stderr.write(`GitNexus MCP uncaughtException: ${err?.stack || err}\n`);
287
+ shutdown(1);
288
+ });
289
+ process.on('unhandledRejection', (reason) => {
290
+ process.stderr.write(`GitNexus MCP unhandledRejection: ${reason?.stack || reason}\n`);
291
+ });
292
+ // Handle stdio errors — stdin close means the parent process is gone
293
+ process.stdin.on('end', shutdown);
294
+ process.stdin.on('error', () => shutdown());
295
+ process.stdout.on('error', () => shutdown());
296
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Staleness Check
3
+ *
4
+ * Checks if the GitNexus index is behind the current git HEAD.
5
+ * Returns a hint for the LLM to call analyze if stale.
6
+ */
7
+ export interface StalenessInfo {
8
+ isStale: boolean;
9
+ commitsBehind: number;
10
+ hint?: string;
11
+ }
12
+ /**
13
+ * Check how many commits the index is behind HEAD
14
+ */
15
+ export declare function checkStaleness(repoPath: string, lastCommit: string): StalenessInfo;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Staleness Check
3
+ *
4
+ * Checks if the GitNexus index is behind the current git HEAD.
5
+ * Returns a hint for the LLM to call analyze if stale.
6
+ */
7
+ import { execFileSync } from 'child_process';
8
+ /**
9
+ * Check how many commits the index is behind HEAD
10
+ */
11
+ export function checkStaleness(repoPath, lastCommit) {
12
+ try {
13
+ // Get count of commits between lastCommit and HEAD
14
+ const result = execFileSync('git', ['rev-list', '--count', `${lastCommit}..HEAD`], { cwd: repoPath, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
15
+ const commitsBehind = parseInt(result, 10) || 0;
16
+ if (commitsBehind > 0) {
17
+ return {
18
+ isStale: true,
19
+ commitsBehind,
20
+ hint: `⚠️ Index is ${commitsBehind} commit${commitsBehind > 1 ? 's' : ''} behind HEAD. Run analyze tool to update.`,
21
+ };
22
+ }
23
+ return { isStale: false, commitsBehind: 0 };
24
+ }
25
+ catch {
26
+ // If git command fails, assume not stale (fail open)
27
+ return { isStale: false, commitsBehind: 0 };
28
+ }
29
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * MCP Tool Definitions
3
+ *
4
+ * Defines the tools that GitNexus exposes to external AI agents.
5
+ * All tools support an optional `repo` parameter for multi-repo setups.
6
+ */
7
+ export interface ToolDefinition {
8
+ name: string;
9
+ description: string;
10
+ inputSchema: {
11
+ type: 'object';
12
+ properties: Record<string, {
13
+ type: string;
14
+ description?: string;
15
+ default?: any;
16
+ items?: {
17
+ type: string;
18
+ };
19
+ enum?: string[];
20
+ }>;
21
+ required: string[];
22
+ };
23
+ }
24
+ export declare const GITNEXUS_TOOLS: ToolDefinition[];
@@ -0,0 +1,292 @@
1
+ /**
2
+ * MCP Tool Definitions
3
+ *
4
+ * Defines the tools that GitNexus exposes to external AI agents.
5
+ * All tools support an optional `repo` parameter for multi-repo setups.
6
+ */
7
+ export const GITNEXUS_TOOLS = [
8
+ {
9
+ name: 'list_repos',
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.`,
19
+ inputSchema: {
20
+ type: 'object',
21
+ properties: {},
22
+ required: [],
23
+ },
24
+ },
25
+ {
26
+ name: 'sync_unreal_asset_manifest',
27
+ description: `Refresh the Unreal Blueprint asset manifest for a repository.
28
+
29
+ Uses the configured Unreal Editor commandlet to enumerate Blueprint assets and
30
+ store a manifest under .gitnexus/unreal/asset-manifest.json.
31
+
32
+ WHEN TO USE: Before Blueprint-reference queries, after large Blueprint changes, or
33
+ to validate Unreal analyzer configuration.
34
+ AFTER THIS: Use find_native_blueprint_references() or find_blueprints_derived_from_native_class().`,
35
+ inputSchema: {
36
+ type: 'object',
37
+ properties: {
38
+ repo: { type: 'string', description: 'Repository name or path. Omit if only one repo is indexed.' },
39
+ },
40
+ required: [],
41
+ },
42
+ },
43
+ {
44
+ name: 'find_native_blueprint_references',
45
+ description: `Find direct Blueprint graph references to a native C++ function using the Unreal analyzer.
46
+
47
+ This is a hybrid query: GitNexus uses the local Blueprint asset manifest to shortlist
48
+ candidates, then invokes the Unreal Editor-side analyzer to confirm exact graph nodes.
49
+
50
+ WHEN TO USE: You have a C++ UFUNCTION or native method and need the Blueprint call sites.
51
+ AFTER THIS: Use expand_blueprint_chain() on a returned chain_anchor_id to walk the Blueprint flow.`,
52
+ inputSchema: {
53
+ type: 'object',
54
+ properties: {
55
+ function: { type: 'string', description: 'Native function name or qualified name (for example "ULyraWeaponSpawner::GetPickupInstigator").' },
56
+ symbol_uid: { type: 'string', description: 'Direct symbol UID from prior GitNexus results.' },
57
+ class_name: { type: 'string', description: 'Owning native class name to disambiguate overloaded or same-name functions.' },
58
+ file_path: { type: 'string', description: 'Source file path to disambiguate the target function.' },
59
+ refresh_manifest: { type: 'boolean', description: 'Refresh the Unreal asset manifest before searching.', default: false },
60
+ max_candidates: { type: 'number', description: 'Cap the manifest-derived Blueprint candidates passed to the Unreal analyzer.', default: 200 },
61
+ repo: { type: 'string', description: 'Repository name or path. Omit if only one repo is indexed.' },
62
+ },
63
+ required: [],
64
+ },
65
+ },
66
+ {
67
+ name: 'expand_blueprint_chain',
68
+ description: `Expand a Blueprint execution/call chain from a previously confirmed reference node.
69
+
70
+ Uses the Unreal analyzer to walk graph links upstream or downstream starting from
71
+ a chain anchor returned by find_native_blueprint_references().
72
+
73
+ WHEN TO USE: After finding a direct Blueprint call node and you need local Blueprint flow context.
74
+ AFTER THIS: Inspect returned nodes or continue expansion from another anchor.`,
75
+ inputSchema: {
76
+ type: 'object',
77
+ properties: {
78
+ asset_path: { type: 'string', description: 'Blueprint asset path containing the anchor node.' },
79
+ chain_anchor_id: { type: 'string', description: 'Anchor identifier returned from find_native_blueprint_references().' },
80
+ direction: { type: 'string', description: 'Chain traversal direction.', enum: ['upstream', 'downstream'], default: 'downstream' },
81
+ max_depth: { type: 'number', description: 'Maximum Blueprint traversal depth.', default: 5 },
82
+ repo: { type: 'string', description: 'Repository name or path. Omit if only one repo is indexed.' },
83
+ },
84
+ required: ['asset_path', 'chain_anchor_id'],
85
+ },
86
+ },
87
+ {
88
+ name: 'find_blueprints_derived_from_native_class',
89
+ description: `List Blueprint assets derived from a native C++ class using the Unreal asset manifest.
90
+
91
+ WHEN TO USE: To discover candidate Blueprint assets for a native class before deeper graph analysis,
92
+ or to validate manifest coverage for a gameplay type.
93
+ AFTER THIS: Use find_native_blueprint_references() for function-level graph references.`,
94
+ inputSchema: {
95
+ type: 'object',
96
+ properties: {
97
+ class_name: { type: 'string', description: 'Native class name to search for in Blueprint ancestry.' },
98
+ refresh_manifest: { type: 'boolean', description: 'Refresh the Unreal asset manifest before searching.', default: false },
99
+ max_results: { type: 'number', description: 'Maximum Blueprint assets to return.', default: 200 },
100
+ repo: { type: 'string', description: 'Repository name or path. Omit if only one repo is indexed.' },
101
+ },
102
+ required: ['class_name'],
103
+ },
104
+ },
105
+ {
106
+ name: 'query',
107
+ description: `Query the code knowledge graph for execution flows related to a concept.
108
+ Returns processes (call chains) ranked by relevance, each with its symbols and file locations.
109
+
110
+ 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.
111
+ AFTER THIS: Use context() on a specific symbol for 360-degree view (callers, callees, categorized refs).
112
+
113
+ Returns results grouped by process (execution flow):
114
+ - processes: ranked execution flows with relevance priority
115
+ - process_symbols: all symbols in those flows with file locations and module (functional area)
116
+ - definitions: standalone types/interfaces not in any process
117
+
118
+ Hybrid ranking: BM25 keyword + semantic vector search, ranked by Reciprocal Rank Fusion.`,
119
+ inputSchema: {
120
+ type: 'object',
121
+ properties: {
122
+ query: { type: 'string', description: 'Natural language or keyword search query' },
123
+ task_context: { type: 'string', description: 'What you are working on (e.g., "adding OAuth support"). Helps ranking.' },
124
+ goal: { type: 'string', description: 'What you want to find (e.g., "existing auth validation logic"). Helps ranking.' },
125
+ limit: { type: 'number', description: 'Max processes to return (default: 5)', default: 5 },
126
+ max_symbols: { type: 'number', description: 'Max symbols per process (default: 10)', default: 10 },
127
+ include_content: { type: 'boolean', description: 'Include full symbol source code (default: false)', default: false },
128
+ repo: { type: 'string', description: 'Repository name or path. Omit if only one repo is indexed.' },
129
+ },
130
+ required: ['query'],
131
+ },
132
+ },
133
+ {
134
+ name: 'cypher',
135
+ description: `Execute Cypher query against the code knowledge graph.
136
+
137
+ WHEN TO USE: Complex structural queries that search/explore can't answer. READ gitnexus://repo/{name}/schema first for the full schema.
138
+ AFTER THIS: Use context() on result symbols for deeper context.
139
+
140
+ SCHEMA:
141
+ - Nodes: File, Folder, Function, Class, Interface, Method, CodeElement, Community, Process
142
+ - Multi-language nodes (use backticks): \`Struct\`, \`Enum\`, \`Trait\`, \`Impl\`, etc.
143
+ - All edges via single CodeRelation table with 'type' property
144
+ - Edge types: CONTAINS, DEFINES, CALLS, IMPORTS, EXTENDS, IMPLEMENTS, HAS_METHOD, HAS_PROPERTY, ACCESSES, OVERRIDES, MEMBER_OF, STEP_IN_PROCESS
145
+ - Edge properties: type (STRING), confidence (DOUBLE), reason (STRING), step (INT32)
146
+
147
+ EXAMPLES:
148
+ • Find callers of a function:
149
+ MATCH (a)-[:CodeRelation {type: 'CALLS'}]->(b:Function {name: "validateUser"}) RETURN a.name, a.filePath
150
+
151
+ • Find community members:
152
+ MATCH (f)-[:CodeRelation {type: 'MEMBER_OF'}]->(c:Community) WHERE c.heuristicLabel = "Auth" RETURN f.name
153
+
154
+ • Trace a process:
155
+ MATCH (s)-[r:CodeRelation {type: 'STEP_IN_PROCESS'}]->(p:Process) WHERE p.heuristicLabel = "UserLogin" RETURN s.name, r.step ORDER BY r.step
156
+
157
+ • Find all methods of a class:
158
+ MATCH (c:Class {name: "UserService"})-[r:CodeRelation {type: 'HAS_METHOD'}]->(m:Method) RETURN m.name, m.parameterCount, m.returnType
159
+
160
+ • Find all properties of a class:
161
+ MATCH (c:Class {name: "User"})-[r:CodeRelation {type: 'HAS_PROPERTY'}]->(p:Property) RETURN p.name, p.description
162
+
163
+ • Find all writers of a field:
164
+ MATCH (f:Function)-[r:CodeRelation {type: 'ACCESSES', reason: 'write'}]->(p:Property) WHERE p.name = "address" RETURN f.name, f.filePath
165
+
166
+ • Find method overrides (MRO resolution):
167
+ MATCH (winner:Method)-[r:CodeRelation {type: 'OVERRIDES'}]->(loser:Method) RETURN winner.name, winner.filePath, loser.filePath, r.reason
168
+
169
+ • Detect diamond inheritance:
170
+ 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
171
+
172
+ OUTPUT: Returns { markdown, row_count } — results formatted as a Markdown table for easy reading.
173
+
174
+ TIPS:
175
+ - All relationships use single CodeRelation table — filter with {type: 'CALLS'} etc.
176
+ - Community = auto-detected functional area (Leiden algorithm)
177
+ - Process = execution flow trace from entry point to terminal
178
+ - Use heuristicLabel (not label) for human-readable community/process names`,
179
+ inputSchema: {
180
+ type: 'object',
181
+ properties: {
182
+ query: { type: 'string', description: 'Cypher query to execute' },
183
+ repo: { type: 'string', description: 'Repository name or path. Omit if only one repo is indexed.' },
184
+ },
185
+ required: ['query'],
186
+ },
187
+ },
188
+ {
189
+ name: 'context',
190
+ description: `360-degree view of a single code symbol.
191
+ Shows categorized incoming/outgoing references (calls, imports, extends, implements, methods, properties, overrides), process participation, and file location.
192
+
193
+ 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.
194
+ AFTER THIS: Use impact() if planning changes, or READ gitnexus://repo/{name}/process/{processName} for full execution trace.
195
+
196
+ 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.
197
+
198
+ NOTE: ACCESSES edges (field read/write tracking) are included in context results. Coverage: reads detected during call chain resolution (e.g., user.address.save() emits a read on 'address'). Standalone reads and writes require Phase 2.`,
199
+ inputSchema: {
200
+ type: 'object',
201
+ properties: {
202
+ name: { type: 'string', description: 'Symbol name (e.g., "validateUser", "AuthService")' },
203
+ uid: { type: 'string', description: 'Direct symbol UID from prior tool results (zero-ambiguity lookup)' },
204
+ file_path: { type: 'string', description: 'File path to disambiguate common names' },
205
+ include_content: { type: 'boolean', description: 'Include full symbol source code (default: false)', default: false },
206
+ repo: { type: 'string', description: 'Repository name or path. Omit if only one repo is indexed.' },
207
+ },
208
+ required: [],
209
+ },
210
+ },
211
+ {
212
+ name: 'detect_changes',
213
+ description: `Analyze uncommitted git changes and find affected execution flows.
214
+ Maps git diff hunks to indexed symbols, then traces which processes are impacted.
215
+
216
+ WHEN TO USE: Before committing — to understand what your changes affect. Pre-commit review, PR preparation.
217
+ AFTER THIS: Review affected processes. Use context() on high-risk symbols. READ gitnexus://repo/{name}/process/{name} for full traces.
218
+
219
+ Returns: changed symbols, affected processes, and a risk summary.`,
220
+ inputSchema: {
221
+ type: 'object',
222
+ properties: {
223
+ scope: { type: 'string', description: 'What to analyze: "unstaged" (default), "staged", "all", or "compare"', enum: ['unstaged', 'staged', 'all', 'compare'], default: 'unstaged' },
224
+ base_ref: { type: 'string', description: 'Branch/commit for "compare" scope (e.g., "main")' },
225
+ repo: { type: 'string', description: 'Repository name or path. Omit if only one repo is indexed.' },
226
+ },
227
+ required: [],
228
+ },
229
+ },
230
+ {
231
+ name: 'rename',
232
+ description: `Multi-file coordinated rename using the knowledge graph + text search.
233
+ Finds all references via graph (high confidence) and regex text search (lower confidence). Preview by default.
234
+
235
+ WHEN TO USE: Renaming a function, class, method, or variable across the codebase. Safer than find-and-replace.
236
+ AFTER THIS: Run detect_changes() to verify no unexpected side effects.
237
+
238
+ Each edit is tagged with confidence:
239
+ - "graph": found via knowledge graph relationships (high confidence, safe to accept)
240
+ - "text_search": found via regex text search (lower confidence, review carefully)`,
241
+ inputSchema: {
242
+ type: 'object',
243
+ properties: {
244
+ symbol_name: { type: 'string', description: 'Current symbol name to rename' },
245
+ symbol_uid: { type: 'string', description: 'Direct symbol UID from prior tool results (zero-ambiguity)' },
246
+ new_name: { type: 'string', description: 'The new name for the symbol' },
247
+ file_path: { type: 'string', description: 'File path to disambiguate common names' },
248
+ dry_run: { type: 'boolean', description: 'Preview edits without modifying files (default: true)', default: true },
249
+ repo: { type: 'string', description: 'Repository name or path. Omit if only one repo is indexed.' },
250
+ },
251
+ required: ['new_name'],
252
+ },
253
+ },
254
+ {
255
+ name: 'impact',
256
+ description: `Analyze the blast radius of changing a code symbol.
257
+ Returns affected symbols grouped by depth, plus risk assessment, affected execution flows, and affected modules.
258
+
259
+ WHEN TO USE: Before making code changes — especially refactoring, renaming, or modifying shared code. Shows what would break.
260
+ AFTER THIS: Review d=1 items (WILL BREAK). Use context() on high-risk symbols.
261
+
262
+ Output includes:
263
+ - risk: LOW / MEDIUM / HIGH / CRITICAL
264
+ - summary: direct callers, processes affected, modules affected
265
+ - affected_processes: which execution flows break and at which step
266
+ - affected_modules: which functional areas are hit (direct vs indirect)
267
+ - byDepth: all affected symbols grouped by traversal depth
268
+
269
+ Depth groups:
270
+ - d=1: WILL BREAK (direct callers/importers)
271
+ - d=2: LIKELY AFFECTED (indirect)
272
+ - d=3: MAY NEED TESTING (transitive)
273
+
274
+ TIP: Default traversal uses CALLS/IMPORTS/EXTENDS/IMPLEMENTS. For class members, include HAS_METHOD and HAS_PROPERTY in relationTypes. For field access analysis, include ACCESSES in relationTypes.
275
+
276
+ EdgeType: CALLS, IMPORTS, EXTENDS, IMPLEMENTS, HAS_METHOD, HAS_PROPERTY, OVERRIDES, ACCESSES
277
+ Confidence: 1.0 = certain, <0.8 = fuzzy match`,
278
+ inputSchema: {
279
+ type: 'object',
280
+ properties: {
281
+ target: { type: 'string', description: 'Name of function, class, or file to analyze' },
282
+ direction: { type: 'string', description: 'upstream (what depends on this) or downstream (what this depends on)' },
283
+ maxDepth: { type: 'number', description: 'Max relationship depth (default: 3)', default: 3 },
284
+ relationTypes: { type: 'array', items: { type: 'string' }, description: 'Filter: CALLS, IMPORTS, EXTENDS, IMPLEMENTS, HAS_METHOD, HAS_PROPERTY, OVERRIDES, ACCESSES (default: usage-based, ACCESSES excluded by default)' },
285
+ includeTests: { type: 'boolean', description: 'Include test files (default: false)' },
286
+ minConfidence: { type: 'number', description: 'Minimum confidence 0-1 (default: 0.7)' },
287
+ repo: { type: 'string', description: 'Repository name or path. Omit if only one repo is indexed.' },
288
+ },
289
+ required: ['target', 'direction'],
290
+ },
291
+ },
292
+ ];
@@ -0,0 +1,10 @@
1
+ /**
2
+ * HTTP API Server
3
+ *
4
+ * REST API for browser-based clients to query the local .gitnexus/ index.
5
+ * Also hosts the MCP server over StreamableHTTP for remote AI tool access.
6
+ *
7
+ * Security: binds to 127.0.0.1 by default (use --host to override).
8
+ * CORS is restricted to localhost and the deployed site.
9
+ */
10
+ export declare const createServer: (port: number, host?: string) => Promise<void>;