gitnexus 1.4.7 → 1.4.8

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 (92) hide show
  1. package/README.md +22 -1
  2. package/dist/cli/ai-context.d.ts +1 -1
  3. package/dist/cli/ai-context.js +1 -1
  4. package/dist/cli/analyze.d.ts +2 -0
  5. package/dist/cli/analyze.js +54 -21
  6. package/dist/cli/index.js +2 -1
  7. package/dist/cli/setup.js +78 -1
  8. package/dist/config/supported-languages.d.ts +30 -0
  9. package/dist/config/supported-languages.js +30 -0
  10. package/dist/core/embeddings/embedder.d.ts +6 -1
  11. package/dist/core/embeddings/embedder.js +65 -5
  12. package/dist/core/embeddings/embedding-pipeline.js +11 -9
  13. package/dist/core/embeddings/http-client.d.ts +31 -0
  14. package/dist/core/embeddings/http-client.js +179 -0
  15. package/dist/core/embeddings/index.d.ts +1 -0
  16. package/dist/core/embeddings/index.js +1 -0
  17. package/dist/core/embeddings/types.d.ts +1 -1
  18. package/dist/core/graph/types.d.ts +2 -1
  19. package/dist/core/ingestion/ast-helpers.d.ts +80 -0
  20. package/dist/core/ingestion/ast-helpers.js +738 -0
  21. package/dist/core/ingestion/call-analysis.d.ts +73 -0
  22. package/dist/core/ingestion/call-analysis.js +490 -0
  23. package/dist/core/ingestion/call-processor.d.ts +48 -1
  24. package/dist/core/ingestion/call-processor.js +368 -7
  25. package/dist/core/ingestion/call-routing.d.ts +6 -0
  26. package/dist/core/ingestion/entry-point-scoring.js +36 -26
  27. package/dist/core/ingestion/framework-detection.d.ts +10 -2
  28. package/dist/core/ingestion/framework-detection.js +49 -12
  29. package/dist/core/ingestion/heritage-processor.js +47 -49
  30. package/dist/core/ingestion/import-processor.d.ts +1 -1
  31. package/dist/core/ingestion/import-processor.js +103 -194
  32. package/dist/core/ingestion/import-resolution.d.ts +101 -0
  33. package/dist/core/ingestion/import-resolution.js +251 -0
  34. package/dist/core/ingestion/language-config.d.ts +3 -0
  35. package/dist/core/ingestion/language-config.js +13 -0
  36. package/dist/core/ingestion/markdown-processor.d.ts +17 -0
  37. package/dist/core/ingestion/markdown-processor.js +124 -0
  38. package/dist/core/ingestion/mro-processor.js +8 -3
  39. package/dist/core/ingestion/named-binding-extraction.d.ts +9 -43
  40. package/dist/core/ingestion/named-binding-extraction.js +89 -79
  41. package/dist/core/ingestion/parsing-processor.d.ts +2 -2
  42. package/dist/core/ingestion/parsing-processor.js +14 -73
  43. package/dist/core/ingestion/pipeline.d.ts +10 -0
  44. package/dist/core/ingestion/pipeline.js +421 -4
  45. package/dist/core/ingestion/resolution-context.d.ts +5 -0
  46. package/dist/core/ingestion/resolution-context.js +7 -4
  47. package/dist/core/ingestion/resolvers/index.d.ts +1 -1
  48. package/dist/core/ingestion/resolvers/index.js +1 -1
  49. package/dist/core/ingestion/resolvers/jvm.d.ts +2 -1
  50. package/dist/core/ingestion/resolvers/jvm.js +25 -9
  51. package/dist/core/ingestion/resolvers/php.d.ts +14 -0
  52. package/dist/core/ingestion/resolvers/php.js +43 -3
  53. package/dist/core/ingestion/resolvers/utils.d.ts +5 -0
  54. package/dist/core/ingestion/resolvers/utils.js +16 -0
  55. package/dist/core/ingestion/symbol-table.d.ts +16 -0
  56. package/dist/core/ingestion/symbol-table.js +20 -6
  57. package/dist/core/ingestion/tree-sitter-queries.d.ts +4 -4
  58. package/dist/core/ingestion/tree-sitter-queries.js +43 -2
  59. package/dist/core/ingestion/type-env.d.ts +28 -1
  60. package/dist/core/ingestion/type-env.js +419 -96
  61. package/dist/core/ingestion/type-extractors/c-cpp.d.ts +5 -0
  62. package/dist/core/ingestion/type-extractors/c-cpp.js +119 -0
  63. package/dist/core/ingestion/type-extractors/csharp.js +149 -16
  64. package/dist/core/ingestion/type-extractors/index.d.ts +1 -1
  65. package/dist/core/ingestion/type-extractors/index.js +1 -1
  66. package/dist/core/ingestion/type-extractors/jvm.js +169 -66
  67. package/dist/core/ingestion/type-extractors/rust.js +35 -1
  68. package/dist/core/ingestion/type-extractors/shared.d.ts +0 -2
  69. package/dist/core/ingestion/type-extractors/shared.js +5 -10
  70. package/dist/core/ingestion/type-extractors/swift.js +7 -6
  71. package/dist/core/ingestion/type-extractors/types.d.ts +37 -7
  72. package/dist/core/ingestion/type-extractors/typescript.js +141 -9
  73. package/dist/core/ingestion/utils.d.ts +2 -120
  74. package/dist/core/ingestion/utils.js +3 -1051
  75. package/dist/core/ingestion/workers/parse-worker.d.ts +13 -4
  76. package/dist/core/ingestion/workers/parse-worker.js +66 -87
  77. package/dist/core/lbug/csv-generator.js +18 -1
  78. package/dist/core/lbug/lbug-adapter.d.ts +10 -0
  79. package/dist/core/lbug/lbug-adapter.js +69 -4
  80. package/dist/core/lbug/schema.d.ts +5 -3
  81. package/dist/core/lbug/schema.js +26 -2
  82. package/dist/mcp/core/embedder.js +11 -3
  83. package/dist/mcp/core/lbug-adapter.js +12 -1
  84. package/dist/mcp/local/local-backend.d.ts +22 -0
  85. package/dist/mcp/local/local-backend.js +133 -29
  86. package/dist/mcp/resources.js +2 -0
  87. package/dist/mcp/tools.js +2 -2
  88. package/dist/server/api.d.ts +19 -1
  89. package/dist/server/api.js +66 -6
  90. package/dist/storage/git.d.ts +12 -0
  91. package/dist/storage/git.js +21 -0
  92. package/package.json +10 -2
@@ -9,6 +9,7 @@
9
9
  * DESIGN: Returns null for unknown frameworks, which causes a 1.0 multiplier
10
10
  * (no bonus, no penalty) - same behavior as before this feature.
11
11
  */
12
+ import { SupportedLanguages } from '../../config/supported-languages.js';
12
13
  // ============================================================================
13
14
  // PATH-BASED FRAMEWORK DETECTION
14
15
  // ============================================================================
@@ -180,8 +181,8 @@ export function detectFrameworkFromPath(filePath) {
180
181
  if (p.includes('/controllers/') && p.endsWith('.go')) {
181
182
  return { framework: 'go-mvc', entryPointMultiplier: 2.5, reason: 'go-controller' };
182
183
  }
183
- // Go main.go files (THE entry point)
184
- if (p.endsWith('/main.go') || p.endsWith('/cmd/') && p.endsWith('.go')) {
184
+ // Go main.go files (THE entry point) — only match main.go, not arbitrary .go files under cmd/
185
+ if (p.endsWith('/main.go')) {
185
186
  return { framework: 'go', entryPointMultiplier: 3.0, reason: 'go-main' };
186
187
  }
187
188
  // ========== RUST FRAMEWORKS ==========
@@ -333,21 +334,31 @@ export const FRAMEWORK_AST_PATTERNS = {
333
334
  'signalr': ['[HubMethodName]', ': Hub', ': Hub<'],
334
335
  'blazor': ['@page', '[Parameter]', '@inject'],
335
336
  'efcore': ['DbContext', 'DbSet<', 'OnModelCreating'],
336
- // Go patterns (function signatures)
337
- 'go-http': ['http.Handler', 'http.HandlerFunc', 'ServeHTTP'],
337
+ // Go patterns (function signatures include framework types)
338
+ 'go-http': ['http.Handler', 'http.HandlerFunc', 'ServeHTTP', 'http.ResponseWriter', 'http.Request'],
339
+ 'gin': ['gin.Context', 'gin.Default', 'gin.New'],
340
+ 'echo': ['echo.Context', 'echo.New'],
341
+ 'fiber': ['fiber.Ctx', 'fiber.New', 'fiber.App'],
342
+ 'go-grpc': ['grpc.Server', 'RegisterServer', 'pb.Unimplemented'],
338
343
  // PHP/Laravel
339
344
  'laravel': ['Route::get', 'Route::post', 'Route::put', 'Route::delete',
340
345
  'Route::resource', 'Route::apiResource', '#[Route('],
341
- // Rust macros
342
- 'actix': ['#[get', '#[post', '#[put', '#[delete'],
343
- 'axum': ['Router::new'],
344
- 'rocket': ['#[get', '#[post'],
346
+ // Rust macros (proc-macro attributes in definition text)
347
+ 'actix': ['#[get', '#[post', '#[put', '#[delete', '#[actix_web', 'HttpRequest', 'HttpResponse'],
348
+ 'axum': ['Router::new', 'axum::extract', 'axum::routing'],
349
+ 'rocket': ['#[get', '#[post', '#[launch', 'rocket::'],
350
+ 'tokio': ['#[tokio::main]', '#[tokio::test]'],
351
+ // C++ patterns (Qt, Boost)
352
+ 'qt': ['Q_OBJECT', 'Q_INVOKABLE', 'Q_PROPERTY', 'Q_SIGNALS', 'Q_SLOTS', 'Q_SIGNAL', 'Q_SLOT', 'QWidget', 'QApplication'],
345
353
  // Swift/iOS
346
- 'uikit': ['viewDidLoad', 'viewWillAppear', 'viewDidAppear', 'UIViewController'],
347
- 'swiftui': ['@main', 'WindowGroup', 'ContentView', '@StateObject', '@ObservedObject'],
348
- 'combine': ['sink', 'assign', 'Publisher', 'Subscriber'],
354
+ 'uikit': ['viewDidLoad', 'viewWillAppear', 'viewDidAppear', 'UIViewController', '@IBOutlet', '@IBAction', '@objc'],
355
+ 'swiftui': ['@main', 'WindowGroup', 'ContentView', '@StateObject', '@ObservedObject', '@EnvironmentObject', '@Published'],
356
+ 'vapor': ['app.get', 'app.post', 'req.content.decode', 'Vapor'],
357
+ // Ruby patterns (class-level macros in definition text)
358
+ 'rails': ['ApplicationController', 'ApplicationRecord', 'ActiveRecord::Base',
359
+ 'before_action', 'after_action', 'has_many', 'belongs_to', 'has_one', 'validates'],
360
+ 'sinatra': ['Sinatra::Base', 'Sinatra::Application'],
349
361
  };
350
- import { SupportedLanguages } from '../../config/supported-languages.js';
351
362
  const AST_FRAMEWORK_PATTERNS_BY_LANGUAGE = {
352
363
  [SupportedLanguages.JavaScript]: [
353
364
  { framework: 'nestjs', entryPointMultiplier: 3.2, reason: 'nestjs-decorator', patterns: FRAMEWORK_AST_PATTERNS.nestjs },
@@ -378,6 +389,32 @@ const AST_FRAMEWORK_PATTERNS_BY_LANGUAGE = {
378
389
  [SupportedLanguages.PHP]: [
379
390
  { framework: 'laravel', entryPointMultiplier: 3.0, reason: 'php-route-attribute', patterns: FRAMEWORK_AST_PATTERNS.laravel },
380
391
  ],
392
+ [SupportedLanguages.Go]: [
393
+ { framework: 'go-http', entryPointMultiplier: 2.5, reason: 'go-http-handler', patterns: FRAMEWORK_AST_PATTERNS['go-http'] },
394
+ { framework: 'gin', entryPointMultiplier: 3.0, reason: 'gin-handler', patterns: FRAMEWORK_AST_PATTERNS.gin },
395
+ { framework: 'echo', entryPointMultiplier: 3.0, reason: 'echo-handler', patterns: FRAMEWORK_AST_PATTERNS.echo },
396
+ { framework: 'fiber', entryPointMultiplier: 3.0, reason: 'fiber-handler', patterns: FRAMEWORK_AST_PATTERNS.fiber },
397
+ { framework: 'go-grpc', entryPointMultiplier: 2.8, reason: 'grpc-service', patterns: FRAMEWORK_AST_PATTERNS['go-grpc'] },
398
+ ],
399
+ [SupportedLanguages.Rust]: [
400
+ { framework: 'actix-web', entryPointMultiplier: 3.0, reason: 'actix-attribute', patterns: FRAMEWORK_AST_PATTERNS.actix },
401
+ { framework: 'axum', entryPointMultiplier: 3.0, reason: 'axum-routing', patterns: FRAMEWORK_AST_PATTERNS.axum },
402
+ { framework: 'rocket', entryPointMultiplier: 3.0, reason: 'rocket-attribute', patterns: FRAMEWORK_AST_PATTERNS.rocket },
403
+ { framework: 'tokio', entryPointMultiplier: 2.5, reason: 'tokio-runtime', patterns: FRAMEWORK_AST_PATTERNS.tokio },
404
+ ],
405
+ [SupportedLanguages.C]: [], // C has no framework-specific AST patterns (POSIX/socket patterns are in entry-point-scoring)
406
+ [SupportedLanguages.CPlusPlus]: [
407
+ { framework: 'qt', entryPointMultiplier: 2.8, reason: 'qt-macro', patterns: FRAMEWORK_AST_PATTERNS.qt },
408
+ ],
409
+ [SupportedLanguages.Swift]: [
410
+ { framework: 'uikit', entryPointMultiplier: 2.5, reason: 'uikit-lifecycle', patterns: FRAMEWORK_AST_PATTERNS.uikit },
411
+ { framework: 'swiftui', entryPointMultiplier: 2.8, reason: 'swiftui-pattern', patterns: FRAMEWORK_AST_PATTERNS.swiftui },
412
+ { framework: 'vapor', entryPointMultiplier: 3.0, reason: 'vapor-routing', patterns: FRAMEWORK_AST_PATTERNS.vapor },
413
+ ],
414
+ [SupportedLanguages.Ruby]: [
415
+ { framework: 'rails', entryPointMultiplier: 3.0, reason: 'rails-pattern', patterns: FRAMEWORK_AST_PATTERNS.rails },
416
+ { framework: 'sinatra', entryPointMultiplier: 2.8, reason: 'sinatra-pattern', patterns: FRAMEWORK_AST_PATTERNS.sinatra },
417
+ ],
381
418
  };
382
419
  /** Pre-lowercased patterns for O(1) pattern matching at runtime */
383
420
  const AST_PATTERNS_LOWERED = Object.fromEntries(Object.entries(AST_FRAMEWORK_PATTERNS_BY_LANGUAGE).map(([lang, cfgs]) => [
@@ -20,6 +20,7 @@ import { generateId } from '../../lib/utils.js';
20
20
  import { getLanguageFromFilename, isVerboseIngestionEnabled, yieldToEventLoop } from './utils.js';
21
21
  import { SupportedLanguages } from '../../config/supported-languages.js';
22
22
  import { getTreeSitterBufferSize } from './constants.js';
23
+ import { TIER_CONFIDENCE } from './resolution-context.js';
23
24
  /** C#/Java convention: interfaces start with I followed by an uppercase letter */
24
25
  const INTERFACE_NAME_RE = /^I[A-Z]/;
25
26
  /**
@@ -50,20 +51,17 @@ const resolveExtendsType = (parentName, currentFilePath, ctx, language) => {
50
51
  }
51
52
  return { type: 'EXTENDS', idPrefix: 'Class' };
52
53
  };
53
- /**
54
- * Resolve a symbol ID for heritage, with fallback to generated ID.
55
- * Uses ctx.resolve() → pick first candidate's nodeId → generate synthetic ID.
56
- */
57
54
  const resolveHeritageId = (name, filePath, ctx, fallbackLabel, fallbackKey) => {
58
55
  const resolved = ctx.resolve(name, filePath);
59
56
  if (resolved && resolved.candidates.length > 0) {
60
57
  // For global with multiple candidates, refuse (a wrong edge is worse than no edge)
61
58
  if (resolved.tier === 'global' && resolved.candidates.length > 1) {
62
- return generateId(fallbackLabel, fallbackKey ?? name);
59
+ return { id: generateId(fallbackLabel, fallbackKey ?? name), confidence: TIER_CONFIDENCE['global'] };
63
60
  }
64
- return resolved.candidates[0].nodeId;
61
+ return { id: resolved.candidates[0].nodeId, confidence: TIER_CONFIDENCE[resolved.tier] };
65
62
  }
66
- return generateId(fallbackLabel, fallbackKey ?? name);
63
+ // Unresolved: use global-tier confidence as fallback
64
+ return { id: generateId(fallbackLabel, fallbackKey ?? name), confidence: TIER_CONFIDENCE['global'] };
67
65
  };
68
66
  export const processHeritage = async (graph, files, astCache, ctx, onProgress) => {
69
67
  const parser = await loadParser();
@@ -132,15 +130,15 @@ export const processHeritage = async (graph, files, astCache, ctx, onProgress) =
132
130
  const className = captureMap['heritage.class'].text;
133
131
  const parentClassName = captureMap['heritage.extends'].text;
134
132
  const { type: relType, idPrefix } = resolveExtendsType(parentClassName, file.path, ctx, language);
135
- const childId = resolveHeritageId(className, file.path, ctx, 'Class', `${file.path}:${className}`);
136
- const parentId = resolveHeritageId(parentClassName, file.path, ctx, idPrefix);
137
- if (childId && parentId && childId !== parentId) {
133
+ const child = resolveHeritageId(className, file.path, ctx, 'Class', `${file.path}:${className}`);
134
+ const parent = resolveHeritageId(parentClassName, file.path, ctx, idPrefix);
135
+ if (child.id && parent.id && child.id !== parent.id) {
138
136
  graph.addRelationship({
139
- id: generateId(relType, `${childId}->${parentId}`),
140
- sourceId: childId,
141
- targetId: parentId,
137
+ id: generateId(relType, `${child.id}->${parent.id}`),
138
+ sourceId: child.id,
139
+ targetId: parent.id,
142
140
  type: relType,
143
- confidence: 1.0,
141
+ confidence: Math.sqrt(child.confidence * parent.confidence),
144
142
  reason: '',
145
143
  });
146
144
  }
@@ -149,15 +147,15 @@ export const processHeritage = async (graph, files, astCache, ctx, onProgress) =
149
147
  if (captureMap['heritage.class'] && captureMap['heritage.implements']) {
150
148
  const className = captureMap['heritage.class'].text;
151
149
  const interfaceName = captureMap['heritage.implements'].text;
152
- const classId = resolveHeritageId(className, file.path, ctx, 'Class', `${file.path}:${className}`);
153
- const interfaceId = resolveHeritageId(interfaceName, file.path, ctx, 'Interface');
154
- if (classId && interfaceId) {
150
+ const cls = resolveHeritageId(className, file.path, ctx, 'Class', `${file.path}:${className}`);
151
+ const iface = resolveHeritageId(interfaceName, file.path, ctx, 'Interface');
152
+ if (cls.id && iface.id) {
155
153
  graph.addRelationship({
156
- id: generateId('IMPLEMENTS', `${classId}->${interfaceId}`),
157
- sourceId: classId,
158
- targetId: interfaceId,
154
+ id: generateId('IMPLEMENTS', `${cls.id}->${iface.id}`),
155
+ sourceId: cls.id,
156
+ targetId: iface.id,
159
157
  type: 'IMPLEMENTS',
160
- confidence: 1.0,
158
+ confidence: Math.sqrt(cls.confidence * iface.confidence),
161
159
  reason: '',
162
160
  });
163
161
  }
@@ -166,15 +164,15 @@ export const processHeritage = async (graph, files, astCache, ctx, onProgress) =
166
164
  if (captureMap['heritage.trait'] && captureMap['heritage.class']) {
167
165
  const structName = captureMap['heritage.class'].text;
168
166
  const traitName = captureMap['heritage.trait'].text;
169
- const structId = resolveHeritageId(structName, file.path, ctx, 'Struct', `${file.path}:${structName}`);
170
- const traitId = resolveHeritageId(traitName, file.path, ctx, 'Trait');
171
- if (structId && traitId) {
167
+ const strct = resolveHeritageId(structName, file.path, ctx, 'Struct', `${file.path}:${structName}`);
168
+ const trait = resolveHeritageId(traitName, file.path, ctx, 'Trait');
169
+ if (strct.id && trait.id) {
172
170
  graph.addRelationship({
173
- id: generateId('IMPLEMENTS', `${structId}->${traitId}`),
174
- sourceId: structId,
175
- targetId: traitId,
171
+ id: generateId('IMPLEMENTS', `${strct.id}->${trait.id}`),
172
+ sourceId: strct.id,
173
+ targetId: trait.id,
176
174
  type: 'IMPLEMENTS',
177
- confidence: 1.0,
175
+ confidence: Math.sqrt(strct.confidence * trait.confidence),
178
176
  reason: 'trait-impl',
179
177
  });
180
178
  }
@@ -205,43 +203,43 @@ export const processHeritageFromExtracted = async (graph, extractedHeritage, ctx
205
203
  if (!fileLanguage)
206
204
  continue;
207
205
  const { type: relType, idPrefix } = resolveExtendsType(h.parentName, h.filePath, ctx, fileLanguage);
208
- const childId = resolveHeritageId(h.className, h.filePath, ctx, 'Class', `${h.filePath}:${h.className}`);
209
- const parentId = resolveHeritageId(h.parentName, h.filePath, ctx, idPrefix);
210
- if (childId && parentId && childId !== parentId) {
206
+ const child = resolveHeritageId(h.className, h.filePath, ctx, 'Class', `${h.filePath}:${h.className}`);
207
+ const parent = resolveHeritageId(h.parentName, h.filePath, ctx, idPrefix);
208
+ if (child.id && parent.id && child.id !== parent.id) {
211
209
  graph.addRelationship({
212
- id: generateId(relType, `${childId}->${parentId}`),
213
- sourceId: childId,
214
- targetId: parentId,
210
+ id: generateId(relType, `${child.id}->${parent.id}`),
211
+ sourceId: child.id,
212
+ targetId: parent.id,
215
213
  type: relType,
216
- confidence: 1.0,
214
+ confidence: Math.sqrt(child.confidence * parent.confidence),
217
215
  reason: '',
218
216
  });
219
217
  }
220
218
  }
221
219
  else if (h.kind === 'implements') {
222
- const classId = resolveHeritageId(h.className, h.filePath, ctx, 'Class', `${h.filePath}:${h.className}`);
223
- const interfaceId = resolveHeritageId(h.parentName, h.filePath, ctx, 'Interface');
224
- if (classId && interfaceId) {
220
+ const cls = resolveHeritageId(h.className, h.filePath, ctx, 'Class', `${h.filePath}:${h.className}`);
221
+ const iface = resolveHeritageId(h.parentName, h.filePath, ctx, 'Interface');
222
+ if (cls.id && iface.id) {
225
223
  graph.addRelationship({
226
- id: generateId('IMPLEMENTS', `${classId}->${interfaceId}`),
227
- sourceId: classId,
228
- targetId: interfaceId,
224
+ id: generateId('IMPLEMENTS', `${cls.id}->${iface.id}`),
225
+ sourceId: cls.id,
226
+ targetId: iface.id,
229
227
  type: 'IMPLEMENTS',
230
- confidence: 1.0,
228
+ confidence: Math.sqrt(cls.confidence * iface.confidence),
231
229
  reason: '',
232
230
  });
233
231
  }
234
232
  }
235
233
  else if (h.kind === 'trait-impl' || h.kind === 'include' || h.kind === 'extend' || h.kind === 'prepend') {
236
- const structId = resolveHeritageId(h.className, h.filePath, ctx, 'Struct', `${h.filePath}:${h.className}`);
237
- const traitId = resolveHeritageId(h.parentName, h.filePath, ctx, 'Trait');
238
- if (structId && traitId) {
234
+ const strct = resolveHeritageId(h.className, h.filePath, ctx, 'Struct', `${h.filePath}:${h.className}`);
235
+ const trait = resolveHeritageId(h.parentName, h.filePath, ctx, 'Trait');
236
+ if (strct.id && trait.id) {
239
237
  graph.addRelationship({
240
- id: generateId('IMPLEMENTS', `${structId}->${traitId}:${h.kind}`),
241
- sourceId: structId,
242
- targetId: traitId,
238
+ id: generateId('IMPLEMENTS', `${strct.id}->${trait.id}:${h.kind}`),
239
+ sourceId: strct.id,
240
+ targetId: trait.id,
243
241
  type: 'IMPLEMENTS',
244
- confidence: 1.0,
242
+ confidence: Math.sqrt(strct.confidence * trait.confidence),
245
243
  reason: h.kind,
246
244
  });
247
245
  }
@@ -21,7 +21,7 @@ export interface ImportResolutionContext {
21
21
  allFilePaths: Set<string>;
22
22
  allFileList: string[];
23
23
  normalizedFileList: string[];
24
- suffixIndex: SuffixIndex;
24
+ index: SuffixIndex;
25
25
  resolveCache: Map<string, string | null>;
26
26
  }
27
27
  export declare function buildImportResolutionContext(allPaths: string[]): ImportResolutionContext;