gitnexus 1.5.2 → 1.6.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 (207) hide show
  1. package/README.md +10 -0
  2. package/dist/_shared/graph/types.d.ts +1 -1
  3. package/dist/_shared/graph/types.d.ts.map +1 -1
  4. package/dist/_shared/index.d.ts +1 -0
  5. package/dist/_shared/index.d.ts.map +1 -1
  6. package/dist/_shared/language-detection.d.ts.map +1 -1
  7. package/dist/_shared/language-detection.js +2 -0
  8. package/dist/_shared/language-detection.js.map +1 -1
  9. package/dist/_shared/languages.d.ts +1 -0
  10. package/dist/_shared/languages.d.ts.map +1 -1
  11. package/dist/_shared/languages.js +1 -0
  12. package/dist/_shared/languages.js.map +1 -1
  13. package/dist/_shared/lbug/schema-constants.d.ts +1 -1
  14. package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
  15. package/dist/_shared/lbug/schema-constants.js +3 -1
  16. package/dist/_shared/lbug/schema-constants.js.map +1 -1
  17. package/dist/_shared/mro-strategy.d.ts +19 -0
  18. package/dist/_shared/mro-strategy.d.ts.map +1 -0
  19. package/dist/_shared/mro-strategy.js +2 -0
  20. package/dist/_shared/mro-strategy.js.map +1 -0
  21. package/dist/cli/ai-context.d.ts +1 -0
  22. package/dist/cli/ai-context.js +28 -4
  23. package/dist/cli/analyze.d.ts +2 -0
  24. package/dist/cli/analyze.js +2 -1
  25. package/dist/cli/group.d.ts +2 -0
  26. package/dist/cli/group.js +233 -0
  27. package/dist/cli/index.js +3 -0
  28. package/dist/cli/serve.js +4 -1
  29. package/dist/cli/setup.js +34 -3
  30. package/dist/cli/wiki.js +15 -44
  31. package/dist/config/ignore-service.js +8 -3
  32. package/dist/core/augmentation/engine.js +1 -1
  33. package/dist/core/git-staleness.d.ts +13 -0
  34. package/dist/core/git-staleness.js +29 -0
  35. package/dist/core/group/bridge-db.d.ts +82 -0
  36. package/dist/core/group/bridge-db.js +460 -0
  37. package/dist/core/group/bridge-schema.d.ts +27 -0
  38. package/dist/core/group/bridge-schema.js +55 -0
  39. package/dist/core/group/config-parser.d.ts +3 -0
  40. package/dist/core/group/config-parser.js +83 -0
  41. package/dist/core/group/contract-extractor.d.ts +7 -0
  42. package/dist/core/group/contract-extractor.js +1 -0
  43. package/dist/core/group/extractors/grpc-extractor.d.ts +16 -0
  44. package/dist/core/group/extractors/grpc-extractor.js +264 -0
  45. package/dist/core/group/extractors/http-route-extractor.d.ts +24 -0
  46. package/dist/core/group/extractors/http-route-extractor.js +428 -0
  47. package/dist/core/group/extractors/topic-extractor.d.ts +9 -0
  48. package/dist/core/group/extractors/topic-extractor.js +234 -0
  49. package/dist/core/group/matching.d.ts +13 -0
  50. package/dist/core/group/matching.js +198 -0
  51. package/dist/core/group/normalization.d.ts +3 -0
  52. package/dist/core/group/normalization.js +115 -0
  53. package/dist/core/group/service-boundary-detector.d.ts +8 -0
  54. package/dist/core/group/service-boundary-detector.js +155 -0
  55. package/dist/core/group/service.d.ts +46 -0
  56. package/dist/core/group/service.js +160 -0
  57. package/dist/core/group/storage.d.ts +9 -0
  58. package/dist/core/group/storage.js +91 -0
  59. package/dist/core/group/sync.d.ts +21 -0
  60. package/dist/core/group/sync.js +148 -0
  61. package/dist/core/group/types.d.ts +130 -0
  62. package/dist/core/group/types.js +1 -0
  63. package/dist/core/ingestion/binding-accumulator.d.ts +207 -0
  64. package/dist/core/ingestion/binding-accumulator.js +332 -0
  65. package/dist/core/ingestion/call-processor.d.ts +155 -24
  66. package/dist/core/ingestion/call-processor.js +1129 -247
  67. package/dist/core/ingestion/class-extractors/generic.d.ts +2 -0
  68. package/dist/core/ingestion/class-extractors/generic.js +135 -0
  69. package/dist/core/ingestion/class-types.d.ts +34 -0
  70. package/dist/core/ingestion/class-types.js +1 -0
  71. package/dist/core/ingestion/entry-point-scoring.d.ts +1 -0
  72. package/dist/core/ingestion/entry-point-scoring.js +1 -0
  73. package/dist/core/ingestion/field-extractors/configs/helpers.d.ts +5 -1
  74. package/dist/core/ingestion/field-extractors/configs/helpers.js +13 -3
  75. package/dist/core/ingestion/field-types.d.ts +2 -2
  76. package/dist/core/ingestion/filesystem-walker.js +8 -0
  77. package/dist/core/ingestion/framework-detection.d.ts +1 -0
  78. package/dist/core/ingestion/framework-detection.js +1 -0
  79. package/dist/core/ingestion/heritage-processor.d.ts +8 -15
  80. package/dist/core/ingestion/heritage-processor.js +15 -28
  81. package/dist/core/ingestion/import-processor.d.ts +1 -11
  82. package/dist/core/ingestion/import-processor.js +0 -12
  83. package/dist/core/ingestion/import-resolvers/utils.js +1 -0
  84. package/dist/core/ingestion/import-resolvers/vue.d.ts +8 -0
  85. package/dist/core/ingestion/import-resolvers/vue.js +9 -0
  86. package/dist/core/ingestion/language-provider.d.ts +6 -3
  87. package/dist/core/ingestion/languages/c-cpp.js +168 -1
  88. package/dist/core/ingestion/languages/csharp.js +20 -0
  89. package/dist/core/ingestion/languages/dart.js +26 -4
  90. package/dist/core/ingestion/languages/go.js +22 -0
  91. package/dist/core/ingestion/languages/index.d.ts +1 -0
  92. package/dist/core/ingestion/languages/index.js +2 -0
  93. package/dist/core/ingestion/languages/java.js +17 -0
  94. package/dist/core/ingestion/languages/kotlin.js +24 -1
  95. package/dist/core/ingestion/languages/php.js +23 -11
  96. package/dist/core/ingestion/languages/python.js +9 -0
  97. package/dist/core/ingestion/languages/ruby.js +28 -0
  98. package/dist/core/ingestion/languages/rust.js +38 -0
  99. package/dist/core/ingestion/languages/swift.js +31 -0
  100. package/dist/core/ingestion/languages/typescript.d.ts +1 -0
  101. package/dist/core/ingestion/languages/typescript.js +54 -1
  102. package/dist/core/ingestion/languages/vue.d.ts +13 -0
  103. package/dist/core/ingestion/languages/vue.js +81 -0
  104. package/dist/core/ingestion/method-extractors/configs/c-cpp.d.ts +3 -0
  105. package/dist/core/ingestion/method-extractors/configs/c-cpp.js +387 -0
  106. package/dist/core/ingestion/method-extractors/configs/csharp.js +5 -1
  107. package/dist/core/ingestion/method-extractors/configs/dart.d.ts +2 -0
  108. package/dist/core/ingestion/method-extractors/configs/dart.js +376 -0
  109. package/dist/core/ingestion/method-extractors/configs/go.d.ts +2 -0
  110. package/dist/core/ingestion/method-extractors/configs/go.js +176 -0
  111. package/dist/core/ingestion/method-extractors/configs/jvm.js +13 -4
  112. package/dist/core/ingestion/method-extractors/configs/php.d.ts +2 -0
  113. package/dist/core/ingestion/method-extractors/configs/php.js +304 -0
  114. package/dist/core/ingestion/method-extractors/configs/python.d.ts +2 -0
  115. package/dist/core/ingestion/method-extractors/configs/python.js +309 -0
  116. package/dist/core/ingestion/method-extractors/configs/ruby.d.ts +2 -0
  117. package/dist/core/ingestion/method-extractors/configs/ruby.js +285 -0
  118. package/dist/core/ingestion/method-extractors/configs/rust.d.ts +2 -0
  119. package/dist/core/ingestion/method-extractors/configs/rust.js +195 -0
  120. package/dist/core/ingestion/method-extractors/configs/swift.d.ts +2 -0
  121. package/dist/core/ingestion/method-extractors/configs/swift.js +277 -0
  122. package/dist/core/ingestion/method-extractors/configs/typescript-javascript.d.ts +3 -0
  123. package/dist/core/ingestion/method-extractors/configs/typescript-javascript.js +338 -0
  124. package/dist/core/ingestion/method-extractors/generic.js +38 -15
  125. package/dist/core/ingestion/method-types.d.ts +25 -0
  126. package/dist/core/ingestion/model/field-registry.d.ts +18 -0
  127. package/dist/core/ingestion/model/field-registry.js +22 -0
  128. package/dist/core/ingestion/model/heritage-map.d.ts +70 -0
  129. package/dist/core/ingestion/model/heritage-map.js +159 -0
  130. package/dist/core/ingestion/model/index.d.ts +20 -0
  131. package/dist/core/ingestion/model/index.js +41 -0
  132. package/dist/core/ingestion/model/method-registry.d.ts +62 -0
  133. package/dist/core/ingestion/model/method-registry.js +130 -0
  134. package/dist/core/ingestion/model/registration-table.d.ts +139 -0
  135. package/dist/core/ingestion/model/registration-table.js +224 -0
  136. package/dist/core/ingestion/model/resolution-context.d.ts +93 -0
  137. package/dist/core/ingestion/model/resolution-context.js +337 -0
  138. package/dist/core/ingestion/model/resolve.d.ts +56 -0
  139. package/dist/core/ingestion/model/resolve.js +242 -0
  140. package/dist/core/ingestion/model/semantic-model.d.ts +86 -0
  141. package/dist/core/ingestion/model/semantic-model.js +120 -0
  142. package/dist/core/ingestion/model/symbol-table.d.ts +222 -0
  143. package/dist/core/ingestion/model/symbol-table.js +206 -0
  144. package/dist/core/ingestion/model/type-registry.d.ts +39 -0
  145. package/dist/core/ingestion/model/type-registry.js +62 -0
  146. package/dist/core/ingestion/mro-processor.d.ts +4 -3
  147. package/dist/core/ingestion/mro-processor.js +310 -106
  148. package/dist/core/ingestion/parsing-processor.d.ts +5 -4
  149. package/dist/core/ingestion/parsing-processor.js +210 -85
  150. package/dist/core/ingestion/pipeline.d.ts +2 -0
  151. package/dist/core/ingestion/pipeline.js +192 -68
  152. package/dist/core/ingestion/tree-sitter-queries.d.ts +6 -6
  153. package/dist/core/ingestion/tree-sitter-queries.js +37 -0
  154. package/dist/core/ingestion/type-env.d.ts +15 -2
  155. package/dist/core/ingestion/type-env.js +163 -102
  156. package/dist/core/ingestion/type-extractors/csharp.js +17 -0
  157. package/dist/core/ingestion/type-extractors/jvm.js +11 -0
  158. package/dist/core/ingestion/type-extractors/php.js +0 -55
  159. package/dist/core/ingestion/type-extractors/ruby.js +0 -32
  160. package/dist/core/ingestion/type-extractors/swift.js +13 -0
  161. package/dist/core/ingestion/type-extractors/types.d.ts +8 -8
  162. package/dist/core/ingestion/type-extractors/typescript.js +66 -69
  163. package/dist/core/ingestion/utils/ast-helpers.d.ts +33 -43
  164. package/dist/core/ingestion/utils/ast-helpers.js +129 -565
  165. package/dist/core/ingestion/utils/method-props.d.ts +32 -0
  166. package/dist/core/ingestion/utils/method-props.js +147 -0
  167. package/dist/core/ingestion/vue-sfc-extractor.d.ts +44 -0
  168. package/dist/core/ingestion/vue-sfc-extractor.js +94 -0
  169. package/dist/core/ingestion/workers/parse-worker.d.ts +31 -19
  170. package/dist/core/ingestion/workers/parse-worker.js +463 -198
  171. package/dist/core/lbug/lbug-adapter.d.ts +6 -0
  172. package/dist/core/lbug/lbug-adapter.js +68 -3
  173. package/dist/core/lbug/pool-adapter.d.ts +76 -0
  174. package/dist/core/lbug/pool-adapter.js +522 -0
  175. package/dist/core/run-analyze.d.ts +2 -0
  176. package/dist/core/run-analyze.js +1 -1
  177. package/dist/core/search/bm25-index.js +1 -1
  178. package/dist/core/tree-sitter/parser-loader.js +1 -0
  179. package/dist/core/wiki/graph-queries.js +1 -1
  180. package/dist/core/wiki/html-viewer.js +6 -4
  181. package/dist/core/wiki/llm-client.js +4 -6
  182. package/dist/mcp/core/embedder.js +6 -5
  183. package/dist/mcp/core/lbug-adapter.d.ts +3 -63
  184. package/dist/mcp/core/lbug-adapter.js +3 -484
  185. package/dist/mcp/local/local-backend.d.ts +31 -2
  186. package/dist/mcp/local/local-backend.js +255 -46
  187. package/dist/mcp/resources.js +5 -4
  188. package/dist/mcp/staleness.d.ts +3 -13
  189. package/dist/mcp/staleness.js +2 -31
  190. package/dist/mcp/tools.js +80 -4
  191. package/dist/server/analyze-job.d.ts +2 -0
  192. package/dist/server/analyze-job.js +4 -0
  193. package/dist/server/api.d.ts +20 -1
  194. package/dist/server/api.js +306 -71
  195. package/dist/server/git-clone.d.ts +2 -1
  196. package/dist/server/git-clone.js +98 -5
  197. package/dist/storage/git.d.ts +13 -0
  198. package/dist/storage/git.js +25 -0
  199. package/dist/storage/repo-manager.js +1 -1
  200. package/package.json +8 -2
  201. package/scripts/patch-tree-sitter-swift.cjs +78 -0
  202. package/dist/core/ingestion/named-binding-processor.d.ts +0 -18
  203. package/dist/core/ingestion/named-binding-processor.js +0 -42
  204. package/dist/core/ingestion/resolution-context.d.ts +0 -58
  205. package/dist/core/ingestion/resolution-context.js +0 -135
  206. package/dist/core/ingestion/symbol-table.d.ts +0 -79
  207. package/dist/core/ingestion/symbol-table.js +0 -115
package/dist/cli/wiki.js CHANGED
@@ -197,47 +197,23 @@ export const wikiCommand = async (inputPath, options) => {
197
197
  llmConfig = { ...llmConfig, provider: 'cursor', model, apiKey: '', baseUrl: '' };
198
198
  }
199
199
  else if (choice === '3') {
200
- // Azure OpenAI guided setup
201
- console.log('\n Azure OpenAI setup.');
202
- console.log(' You need: your resource name, deployment name, and API key from the Azure portal.\n');
203
- const resourceName = (await prompt(' Azure resource name (e.g. my-openai-resource): ')).trim();
204
- if (!resourceName) {
205
- console.log('\n No resource name provided. Aborting.\n');
200
+ // Azure OpenAI guided setup — minimal prompts
201
+ console.log('\n Azure OpenAI setup.\n');
202
+ const endpoint = (await prompt(' Endpoint URL (e.g. https://my-resource.openai.azure.com): '))
203
+ .trim()
204
+ .replace(/\/+$/, '');
205
+ if (!endpoint) {
206
+ console.log('\n No endpoint provided. Aborting.\n');
206
207
  process.exitCode = 1;
207
208
  return;
208
209
  }
209
- const deploymentName = (await prompt(' Deployment name (the name you gave your model deployment): ')).trim();
210
+ const deploymentName = (await prompt(' Deployment name: ')).trim();
210
211
  if (!deploymentName) {
211
212
  console.log('\n No deployment name provided. Aborting.\n');
212
213
  process.exitCode = 1;
213
214
  return;
214
215
  }
215
- // Offer v1 or legacy URL
216
- console.log('\n API format:');
217
- console.log(' [1] v1 API — recommended (no api-version needed)');
218
- console.log(' [2] Legacy — uses api-version query param\n');
219
- const apiFormat = await prompt(' Select format (1/2, default: 1): ');
220
- let azureApiVersion;
221
- let azureBaseUrl;
222
- if (apiFormat === '2') {
223
- const versionInput = await prompt(' api-version (default: 2024-10-21): ');
224
- azureApiVersion = versionInput || '2024-10-21';
225
- azureBaseUrl = `https://${resourceName}.openai.azure.com/openai/deployments/${deploymentName}`;
226
- }
227
- else {
228
- azureBaseUrl = `https://${resourceName}.openai.azure.com/openai/v1`;
229
- azureApiVersion = undefined;
230
- }
231
- defaultModel = deploymentName;
232
- // Ask if this is a reasoning model deployment
233
- const reasoningAnswer = await prompt(' Is this a reasoning model (o1, o3, o4-mini)? (y/N): ');
234
- const isReasoningModelDeployment = ['y', 'yes'].includes(reasoningAnswer.toLowerCase());
235
- if (isReasoningModelDeployment) {
236
- console.log(' Note: temperature and max_tokens will be omitted for this deployment (Azure reasoning model requirement).\n');
237
- }
238
- const modelInput = await prompt(` Model / deployment name (default: ${defaultModel}): `);
239
- const model = modelInput || defaultModel;
240
- // API key
216
+ // API key use env var if available
241
217
  const envKey = process.env.GITNEXUS_API_KEY || process.env.OPENAI_API_KEY || '';
242
218
  let azureKey;
243
219
  if (envKey) {
@@ -258,26 +234,21 @@ export const wikiCommand = async (inputPath, options) => {
258
234
  process.exitCode = 1;
259
235
  return;
260
236
  }
261
- // Save Azure config including optional apiVersion and isReasoningModel
262
- const azureConfig = {
237
+ // Always use v1 API format no need for api-version
238
+ const azureBaseUrl = `${endpoint}/openai/v1`;
239
+ await saveCLIConfig({
263
240
  apiKey: azureKey,
264
241
  baseUrl: azureBaseUrl,
265
- model,
242
+ model: deploymentName,
266
243
  provider: 'azure',
267
- isReasoningModel: isReasoningModelDeployment,
268
- };
269
- if (azureApiVersion)
270
- azureConfig.apiVersion = azureApiVersion;
271
- await saveCLIConfig(azureConfig);
244
+ });
272
245
  console.log(' Config saved to ~/.gitnexus/config.json\n');
273
246
  llmConfig = {
274
247
  ...llmConfig,
275
248
  apiKey: azureKey,
276
249
  baseUrl: azureBaseUrl,
277
- model,
250
+ model: deploymentName,
278
251
  provider: 'azure',
279
- apiVersion: azureApiVersion,
280
- isReasoningModel: isReasoningModelDeployment,
281
252
  };
282
253
  }
283
254
  else {
@@ -351,11 +351,16 @@ export const createIgnoreFilter = async (repoPath, options) => {
351
351
  if (DEFAULT_IGNORE_LIST.has(p.name))
352
352
  return true;
353
353
  // Check against .gitignore / .gitnexusignore patterns.
354
- // Test both bare path and path with trailing slash to handle
355
- // bare-name patterns (e.g. `local`) and dir-only patterns (e.g. `local/`).
354
+ // Since childrenIgnored is only called for directories, always test with
355
+ // a trailing slash. This ensures directory-only negation patterns (e.g.
356
+ // `!iOS/`) are applied correctly — without the slash, `ig.ignores('iOS')`
357
+ // treats the path as a file and misses the negation.
358
+ // Bare-name patterns (e.g. `local`) still match `local/` per gitignore spec:
359
+ // the `ignore` package normalizes `dir` and `dir/` to match directories.
360
+ // See: https://github.com/kaelzhang/node-ignore#2-filenames-and-dirnames
356
361
  if (ig) {
357
362
  const rel = p.relative();
358
- if (rel && (ig.ignores(rel) || ig.ignores(rel + '/')))
363
+ if (rel && ig.ignores(rel + '/'))
359
364
  return true;
360
365
  }
361
366
  return false;
@@ -82,7 +82,7 @@ export async function augment(pattern, cwd) {
82
82
  if (!repo)
83
83
  return '';
84
84
  // Lazy-load lbug adapter (skip unnecessary init)
85
- const { initLbug, executeQuery, isLbugReady } = await import('../../mcp/core/lbug-adapter.js');
85
+ const { initLbug, executeQuery, isLbugReady } = await import('../lbug/pool-adapter.js');
86
86
  const { searchFTSFromLbug } = await import('../search/bm25-index.js');
87
87
  const repoId = repo.name.toLowerCase();
88
88
  // Init LadybugDB if not already
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Git working tree vs index commit staleness (used by MCP resources, group status, etc.).
3
+ * Lives in core/ so application code does not depend on the MCP package layer.
4
+ */
5
+ export interface StalenessInfo {
6
+ isStale: boolean;
7
+ commitsBehind: number;
8
+ hint?: string;
9
+ }
10
+ /**
11
+ * Check how many commits the index is behind HEAD (synchronous; uses git CLI).
12
+ */
13
+ export declare function checkStaleness(repoPath: string, lastCommit: string): StalenessInfo;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Git working tree vs index commit staleness (used by MCP resources, group status, etc.).
3
+ * Lives in core/ so application code does not depend on the MCP package layer.
4
+ */
5
+ import { execFileSync } from 'node:child_process';
6
+ /**
7
+ * Check how many commits the index is behind HEAD (synchronous; uses git CLI).
8
+ */
9
+ export function checkStaleness(repoPath, lastCommit) {
10
+ try {
11
+ const result = execFileSync('git', ['rev-list', '--count', `${lastCommit}..HEAD`], {
12
+ cwd: repoPath,
13
+ encoding: 'utf-8',
14
+ stdio: ['pipe', 'pipe', 'pipe'],
15
+ }).trim();
16
+ const commitsBehind = parseInt(result, 10) || 0;
17
+ if (commitsBehind > 0) {
18
+ return {
19
+ isStale: true,
20
+ commitsBehind,
21
+ hint: `⚠️ Index is ${commitsBehind} commit${commitsBehind > 1 ? 's' : ''} behind HEAD. Run analyze tool to update.`,
22
+ };
23
+ }
24
+ return { isStale: false, commitsBehind: 0 };
25
+ }
26
+ catch {
27
+ return { isStale: false, commitsBehind: 0 };
28
+ }
29
+ }
@@ -0,0 +1,82 @@
1
+ import type { LbugValue } from '@ladybugdb/core';
2
+ import type { BridgeHandle, BridgeMeta, StoredContract, CrossLink, RepoSnapshot } from './types.js';
3
+ export declare function contractNodeId(repo: string, contractId: string, role: string, filePath: string): string;
4
+ /**
5
+ * In-memory index of contract node IDs keyed three ways, mirroring the
6
+ * three-tier fallback lookup in {@link findContractNode}. Built once per
7
+ * `writeBridge` call after all contracts are successfully inserted, then
8
+ * consulted for every cross-link — which eliminates the former N+1 query
9
+ * pattern (up to `6 × cross-links` DB round-trips) and turns cross-link
10
+ * resolution into constant-time per link.
11
+ *
12
+ * Keys are deliberately flat strings (not tuples) so `Map<string, ...>`
13
+ * works; the separator `\0` can't occur in any legal repo path / file
14
+ * path / symbol identifier, which makes the encoding injection-safe.
15
+ */
16
+ export interface ContractLookupIndex {
17
+ /** tier 1: `repo + role + symbolUid` → contract node id */
18
+ byUid: Map<string, string>;
19
+ /** tier 2: `repo + role + filePath + symbolName` → contract node id */
20
+ byRef: Map<string, string>;
21
+ /** tier 3: `repo + role + filePath` → list of contract node ids in that file */
22
+ byFile: Map<string, string[]>;
23
+ }
24
+ export declare function createContractLookupIndex(): ContractLookupIndex;
25
+ /**
26
+ * Add a successfully-inserted contract to the lookup index. Must be called
27
+ * AFTER the DB insert succeeds (not before) so failed inserts don't poison
28
+ * the index and cause cross-links to point at non-existent rows.
29
+ */
30
+ export declare function indexContract(index: ContractLookupIndex, contract: StoredContract, nodeId: string): void;
31
+ /**
32
+ * Resolve a cross-link endpoint (consumer or provider reference) to an
33
+ * already-inserted contract node id. Returns `null` if no match — the
34
+ * caller is expected to count that as a dropped link in `WriteBridgeReport`.
35
+ *
36
+ * The resolution order matches the pre-cache DB-query behavior:
37
+ * 1. exact `symbolUid` match in the same `(repo, role)` scope
38
+ * 2. exact `(filePath, symbolName)` match
39
+ * 3. if exactly one contract lives in the file → that one (fallback for
40
+ * legacy graph-assisted extractors that couldn't resolve a symbol name)
41
+ *
42
+ * This is a pure function — no I/O, no DB — so it's trivial to unit-test
43
+ * in isolation (which was the reviewer's main clean-code concern on the
44
+ * original 35-line inner closure in `writeBridge`).
45
+ */
46
+ export declare function findContractNode(index: ContractLookupIndex, repo: string, role: 'consumer' | 'provider', symbolUid: string, filePath: string, symbolName: string): string | null;
47
+ export declare function openBridgeDb(dbPath: string): Promise<BridgeHandle>;
48
+ export declare function ensureBridgeSchema(handle: BridgeHandle): Promise<void>;
49
+ export declare function queryBridge<T>(handle: BridgeHandle, cypher: string, params?: Record<string, LbugValue>): Promise<T[]>;
50
+ export declare function closeBridgeDb(handle: BridgeHandle): Promise<void>;
51
+ export declare function retryRename(src: string, dst: string, attempts?: number): Promise<void>;
52
+ export declare function writeBridgeMeta(groupDir: string, meta: BridgeMeta): Promise<void>;
53
+ export declare function readBridgeMeta(groupDir: string): Promise<BridgeMeta>;
54
+ export interface WriteBridgeInput {
55
+ contracts: StoredContract[];
56
+ crossLinks: CrossLink[];
57
+ repoSnapshots: Record<string, RepoSnapshot>;
58
+ missingRepos: string[];
59
+ }
60
+ /**
61
+ * Non-fatal issues encountered during writeBridge. Callers can log these to
62
+ * surface partial-success state without aborting the whole sync.
63
+ * `sampleErrors` is capped at MAX_SAMPLE_ERRORS per category to bound memory.
64
+ */
65
+ export interface WriteBridgeReport {
66
+ contractsInserted: number;
67
+ contractsFailed: number;
68
+ snapshotsInserted: number;
69
+ snapshotsFailed: number;
70
+ linksInserted: number;
71
+ linksFailed: number;
72
+ /** Cross-links skipped because their from/to contract nodes weren't found. */
73
+ linksDroppedMissingNode: number;
74
+ sampleErrors: Array<{
75
+ kind: 'contract' | 'snapshot' | 'link';
76
+ id: string;
77
+ message: string;
78
+ }>;
79
+ }
80
+ export declare function writeBridge(groupDir: string, input: WriteBridgeInput): Promise<WriteBridgeReport>;
81
+ export declare function openBridgeDbReadOnly(groupDir: string): Promise<BridgeHandle | null>;
82
+ export declare function bridgeExists(groupDir: string): Promise<boolean>;