gitnexus 1.6.11-rc.2 → 1.6.11-rc.21

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 (158) hide show
  1. package/README.md +43 -1
  2. package/dist/_shared/impact-risk.d.ts +37 -0
  3. package/dist/_shared/impact-risk.d.ts.map +1 -0
  4. package/dist/_shared/impact-risk.js +92 -0
  5. package/dist/_shared/impact-risk.js.map +1 -0
  6. package/dist/_shared/index.d.ts +2 -0
  7. package/dist/_shared/index.d.ts.map +1 -1
  8. package/dist/_shared/index.js +2 -0
  9. package/dist/_shared/index.js.map +1 -1
  10. package/dist/cli/ai-context.js +4 -4
  11. package/dist/cli/analyze-config.d.ts +2 -0
  12. package/dist/cli/analyze-config.js +16 -0
  13. package/dist/cli/analyze-options.d.ts +4 -0
  14. package/dist/cli/analyze.d.ts +17 -0
  15. package/dist/cli/analyze.js +43 -7
  16. package/dist/cli/eval-server.js +22 -5
  17. package/dist/cli/group.js +7 -1
  18. package/dist/cli/help-i18n.js +2 -0
  19. package/dist/cli/i18n/en.d.ts +12 -2
  20. package/dist/cli/i18n/en.js +12 -2
  21. package/dist/cli/i18n/resources.d.ts +22 -2
  22. package/dist/cli/i18n/zh-CN.d.ts +10 -0
  23. package/dist/cli/i18n/zh-CN.js +12 -2
  24. package/dist/cli/index.js +11 -4
  25. package/dist/cli/status.js +91 -6
  26. package/dist/cli/watch-queue.d.ts +41 -0
  27. package/dist/cli/watch-queue.js +184 -0
  28. package/dist/cli/watch.d.ts +20 -0
  29. package/dist/cli/watch.js +372 -0
  30. package/dist/cli/wiki.js +15 -2
  31. package/dist/config/ignore-service.d.ts +11 -0
  32. package/dist/config/ignore-service.js +41 -4
  33. package/dist/config/repo-control-file.d.ts +3 -0
  34. package/dist/config/repo-control-file.js +115 -0
  35. package/dist/core/group/config-parser.js +20 -2
  36. package/dist/core/group/cross-impact.d.ts +2 -1
  37. package/dist/core/group/cross-impact.js +33 -2
  38. package/dist/core/group/extractors/fs-utils.d.ts +2 -0
  39. package/dist/core/group/extractors/fs-utils.js +86 -0
  40. package/dist/core/group/extractors/graphql-extractor.d.ts +17 -0
  41. package/dist/core/group/extractors/graphql-extractor.js +652 -0
  42. package/dist/core/group/extractors/java-workspace-extractor.js +244 -31
  43. package/dist/core/group/extractors/manifest-extractor.d.ts +1 -1
  44. package/dist/core/group/extractors/manifest-extractor.js +1 -1
  45. package/dist/core/group/matching.js +8 -1
  46. package/dist/core/group/service.js +5 -1
  47. package/dist/core/group/storage.js +1 -0
  48. package/dist/core/group/sync.d.ts +3 -1
  49. package/dist/core/group/sync.js +43 -5
  50. package/dist/core/group/types.d.ts +19 -5
  51. package/dist/core/incremental/derived-writeback.d.ts +36 -0
  52. package/dist/core/incremental/derived-writeback.js +68 -0
  53. package/dist/core/incremental/subgraph-extract.d.ts +6 -4
  54. package/dist/core/incremental/subgraph-extract.js +7 -5
  55. package/dist/core/index-content-drift.d.ts +54 -0
  56. package/dist/core/index-content-drift.js +127 -0
  57. package/dist/core/ingestion/filesystem-walker.d.ts +15 -5
  58. package/dist/core/ingestion/filesystem-walker.js +20 -3
  59. package/dist/core/ingestion/frameworks/spring/dynamic-lookups.d.ts +22 -0
  60. package/dist/core/ingestion/frameworks/spring/dynamic-lookups.js +124 -0
  61. package/dist/core/ingestion/language-provider.d.ts +43 -0
  62. package/dist/core/ingestion/languages/csharp/razor-view-components.d.ts +62 -0
  63. package/dist/core/ingestion/languages/csharp/razor-view-components.js +954 -0
  64. package/dist/core/ingestion/languages/csharp/resolution-config.d.ts +3 -0
  65. package/dist/core/ingestion/languages/csharp/resolution-config.js +6 -1
  66. package/dist/core/ingestion/languages/csharp/scope-resolver.js +8 -0
  67. package/dist/core/ingestion/languages/java/capture-side-channel.d.ts +4 -0
  68. package/dist/core/ingestion/languages/java/capture-side-channel.js +16 -0
  69. package/dist/core/ingestion/languages/java/captures.js +14 -1
  70. package/dist/core/ingestion/languages/java/lombok-synthesizer.d.ts +42 -0
  71. package/dist/core/ingestion/languages/java/lombok-synthesizer.js +439 -0
  72. package/dist/core/ingestion/languages/java/scope-resolver.js +2 -0
  73. package/dist/core/ingestion/languages/java/spring-dynamic-lookup.d.ts +8 -0
  74. package/dist/core/ingestion/languages/java/spring-dynamic-lookup.js +62 -0
  75. package/dist/core/ingestion/languages/java.js +2 -0
  76. package/dist/core/ingestion/languages/jvm/accessor-synthesis.d.ts +99 -0
  77. package/dist/core/ingestion/languages/jvm/accessor-synthesis.js +173 -0
  78. package/dist/core/ingestion/languages/jvm/beanspec.d.ts +17 -0
  79. package/dist/core/ingestion/languages/jvm/beanspec.js +42 -0
  80. package/dist/core/ingestion/languages/kotlin/capture-side-channel.d.ts +5 -0
  81. package/dist/core/ingestion/languages/kotlin/capture-side-channel.js +16 -0
  82. package/dist/core/ingestion/languages/kotlin/captures.js +14 -1
  83. package/dist/core/ingestion/languages/kotlin/lombok-synthesizer.d.ts +26 -0
  84. package/dist/core/ingestion/languages/kotlin/lombok-synthesizer.js +417 -0
  85. package/dist/core/ingestion/languages/kotlin/scope-resolver.js +2 -0
  86. package/dist/core/ingestion/languages/kotlin/spring-dynamic-lookup.d.ts +8 -0
  87. package/dist/core/ingestion/languages/kotlin/spring-dynamic-lookup.js +77 -0
  88. package/dist/core/ingestion/languages/kotlin.js +2 -0
  89. package/dist/core/ingestion/pipeline-phases/di.js +47 -14
  90. package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +3 -1
  91. package/dist/core/ingestion/pipeline-phases/parse-impl.js +57 -86
  92. package/dist/core/ingestion/pipeline-phases/parse.d.ts +2 -0
  93. package/dist/core/ingestion/pipeline-phases/runner.d.ts +4 -1
  94. package/dist/core/ingestion/pipeline-phases/runner.js +34 -14
  95. package/dist/core/ingestion/pipeline-phases/scan.js +25 -13
  96. package/dist/core/ingestion/pipeline.d.ts +6 -0
  97. package/dist/core/ingestion/pipeline.js +44 -12
  98. package/dist/core/ingestion/scope-extractor.js +1 -0
  99. package/dist/core/ingestion/utils/symbol-labels.d.ts +2 -2
  100. package/dist/core/ingestion/utils/symbol-labels.js +2 -2
  101. package/dist/core/ingestion/workers/parse-worker.js +28 -2
  102. package/dist/core/lbug/lbug-adapter.d.ts +59 -0
  103. package/dist/core/lbug/lbug-adapter.js +154 -1
  104. package/dist/core/run-analyze.d.ts +17 -0
  105. package/dist/core/run-analyze.js +231 -23
  106. package/dist/core/search/fts-indexes.d.ts +19 -1
  107. package/dist/core/search/fts-indexes.js +28 -1
  108. package/dist/core/wiki/generator.js +8 -0
  109. package/dist/core/wiki/grok-client.d.ts +21 -0
  110. package/dist/core/wiki/grok-client.js +287 -0
  111. package/dist/core/wiki/llm-client.d.ts +1 -1
  112. package/dist/core/wiki/llm-client.js +5 -2
  113. package/dist/core/wiki/local-cli-client.d.ts +11 -0
  114. package/dist/core/wiki/local-cli-client.js +22 -9
  115. package/dist/mcp/local/local-backend.d.ts +24 -7
  116. package/dist/mcp/local/local-backend.js +190 -81
  117. package/dist/mcp/local/pdg-impact.d.ts +8 -4
  118. package/dist/mcp/local/pdg-impact.js +7 -2
  119. package/dist/mcp/repository-policy.d.ts +5 -1
  120. package/dist/mcp/repository-policy.js +48 -4
  121. package/dist/mcp/resources.js +2 -1
  122. package/dist/mcp/server.js +6 -5
  123. package/dist/mcp/tools.js +31 -19
  124. package/dist/server/api.js +23 -64
  125. package/dist/server/grep-params.d.ts +18 -0
  126. package/dist/server/grep-params.js +83 -0
  127. package/dist/server/grep-scan.d.ts +23 -0
  128. package/dist/server/grep-scan.js +107 -0
  129. package/dist/server/grep-worker.d.ts +1 -0
  130. package/dist/server/grep-worker.js +12 -0
  131. package/dist/server/mcp-http.d.ts +8 -0
  132. package/dist/server/mcp-http.js +16 -1
  133. package/dist/storage/file-hash.d.ts +5 -0
  134. package/dist/storage/file-hash.js +16 -6
  135. package/dist/storage/fs-atomic.d.ts +24 -0
  136. package/dist/storage/fs-atomic.js +86 -2
  137. package/dist/storage/git.d.ts +19 -8
  138. package/dist/storage/git.js +83 -24
  139. package/dist/storage/gitnexus-managed-paths.d.ts +36 -0
  140. package/dist/storage/gitnexus-managed-paths.js +46 -0
  141. package/dist/storage/parse-cache.d.ts +22 -4
  142. package/dist/storage/parse-cache.js +106 -29
  143. package/dist/storage/parsedfile-store.d.ts +34 -60
  144. package/dist/storage/parsedfile-store.js +177 -171
  145. package/dist/storage/repo-manager.d.ts +11 -1
  146. package/dist/storage/repo-manager.js +23 -2
  147. package/dist/storage/repo-meta.d.ts +12 -0
  148. package/dist/storage/v8-sidecar.d.ts +48 -0
  149. package/dist/storage/v8-sidecar.js +347 -0
  150. package/dist/types/pipeline.d.ts +14 -0
  151. package/package.json +4 -1
  152. package/scripts/cross-platform-shard.ts +4 -2
  153. package/scripts/cross-platform-tests.ts +7 -1
  154. package/skills/gitnexus-cli.md +11 -3
  155. package/skills/gitnexus-impact-analysis.md +9 -0
  156. package/web/assets/{agent-Dr4l5EOp.js → agent-CFqT4hjR.js} +108 -104
  157. package/web/assets/{index-2zdvEdzg.js → index-BMIniRtX.js} +3 -3
  158. package/web/index.html +1 -1
@@ -6,9 +6,12 @@
6
6
  * in `../../csharp-namespace-gate.ts` (shared with the legacy DAG resolver).
7
7
  */
8
8
  import { type CSharpProjectConfig, type CSharpNamespaceEvidence } from '../../language-config.js';
9
+ import { type RazorViewComponentConfig } from './razor-view-components.js';
9
10
  export interface CsharpResolutionConfig {
10
11
  readonly csharpConfigs: readonly CSharpProjectConfig[];
11
12
  /** In-repo declared-namespace evidence gating suffix-fallback resolution (#1881). */
12
13
  readonly namespaces?: CSharpNamespaceEvidence;
14
+ /** Razor views scanned for ASP.NET ViewComponent invocation conventions. */
15
+ readonly razorViewComponents?: RazorViewComponentConfig;
13
16
  }
14
17
  export declare function loadCsharpResolutionConfig(repoRoot: string): Promise<CsharpResolutionConfig>;
@@ -6,10 +6,15 @@
6
6
  * in `../../csharp-namespace-gate.ts` (shared with the legacy DAG resolver).
7
7
  */
8
8
  import { scanCSharpProject, csharpScanToEvidence, } from '../../language-config.js';
9
+ import { loadRazorViewComponentConfig, } from './razor-view-components.js';
9
10
  export async function loadCsharpResolutionConfig(repoRoot) {
10
- const scan = await scanCSharpProject(repoRoot);
11
+ const [scan, razorViewComponents] = await Promise.all([
12
+ scanCSharpProject(repoRoot),
13
+ loadRazorViewComponentConfig(repoRoot),
14
+ ]);
11
15
  return {
12
16
  csharpConfigs: scan.configs,
13
17
  namespaces: csharpScanToEvidence(scan),
18
+ razorViewComponents,
14
19
  };
15
20
  }
@@ -14,6 +14,7 @@ import { csharpArityCompatibility, csharpMergeBindings, resolveCsharpImportTarge
14
14
  import { populateCsharpNamespaceSiblings } from './namespace-siblings.js';
15
15
  import { loadCsharpResolutionConfig } from './resolution-config.js';
16
16
  import { unwrapCsharpElementType } from './accessor-unwrap.js';
17
+ import { emitRazorViewComponentEdges } from './razor-view-components.js';
17
18
  const csharpScopeResolver = {
18
19
  // Construction is keyword-prefixed: `new Service(db).doWork()` (#2708).
19
20
  constructionSyntax: { keyword: 'new' },
@@ -80,6 +81,13 @@ const csharpScopeResolver = {
80
81
  // `IValidator<string>` and `IValidator<String>` are one instantiation, so the
81
82
  // dispatch fan-out must not read them as two (#2912). See the alias table.
82
83
  normalizeTypeArgument: normalizeCsharpTypeArgument,
84
+ // Razor views stay out of the C# parser. Bind literal ViewComponent names
85
+ // only onto in-repo classes (Spring-style: skip the SDK type, hop to the
86
+ // workspace implementor).
87
+ emitPostResolutionEdges: (graph, parsedFiles, nodeLookup, _indexes, ctx) => {
88
+ const config = ctx.resolutionConfig;
89
+ emitRazorViewComponentEdges(graph, parsedFiles, nodeLookup, config?.razorViewComponents, ctx.fileContents);
90
+ },
83
91
  };
84
92
  /**
85
93
  * C# predefined type aliases — the 15 keywords the language defines as exact
@@ -5,6 +5,7 @@ import type { JavaSpringConfigConsumerFact } from './spring-config-bindings.js';
5
5
  import type { JavaSpringAopFact } from './spring-aop.js';
6
6
  import type { JavaSpringConditionalFact } from './spring-conditionals.js';
7
7
  import type { JavaSpringDiClassFact } from './spring-di.js';
8
+ import type { SpringDynamicLookupFact } from '../../frameworks/spring/dynamic-lookups.js';
8
9
  import type { JavaSpringNonHttpHandlerFact } from './spring-non-http-handlers.js';
9
10
  export type JavaClassAnnotationFact = ClassAnnotationFact;
10
11
  export interface JavaCaptureSideChannel {
@@ -15,6 +16,7 @@ export interface JavaCaptureSideChannel {
15
16
  readonly springConfigConsumers?: readonly JavaSpringConfigConsumerFact[];
16
17
  readonly springConditionalFacts?: readonly JavaSpringConditionalFact[];
17
18
  readonly springDiFacts?: readonly JavaSpringDiClassFact[];
19
+ readonly springDynamicLookupFacts?: readonly SpringDynamicLookupFact[];
18
20
  readonly springNonHttpHandlerFacts?: readonly JavaSpringNonHttpHandlerFact[];
19
21
  }
20
22
  /** Clear facts retained by a prior workspace pass in a long-lived process. */
@@ -29,6 +31,8 @@ export declare function setJavaSpringConditionalFacts(filePath: string, facts: r
29
31
  export declare function getJavaSpringConditionalFacts(filePath: string): readonly JavaSpringConditionalFact[];
30
32
  export declare function setJavaSpringDiFacts(filePath: string, facts: readonly JavaSpringDiClassFact[]): void;
31
33
  export declare function getJavaSpringDiFacts(filePath: string): readonly JavaSpringDiClassFact[];
34
+ export declare function setJavaSpringDynamicLookupFacts(filePath: string, facts: readonly SpringDynamicLookupFact[]): void;
35
+ export declare function getJavaSpringDynamicLookupFacts(filePath: string): readonly SpringDynamicLookupFact[];
32
36
  export declare function setJavaSpringNonHttpHandlerFacts(filePath: string, facts: readonly JavaSpringNonHttpHandlerFact[]): void;
33
37
  export declare function getJavaSpringNonHttpHandlerFacts(filePath: string): readonly JavaSpringNonHttpHandlerFact[];
34
38
  /** Snapshot worker-local Java annotation facts for ParsedFile serialization. */
@@ -6,6 +6,7 @@ const springAopFacts = new Map();
6
6
  const springConfigConsumers = new Map();
7
7
  const springConditionalFacts = new Map();
8
8
  const springDiFacts = new Map();
9
+ const springDynamicLookupFacts = new Map();
9
10
  const springNonHttpHandlerFacts = new Map();
10
11
  /** Clear facts retained by a prior workspace pass in a long-lived process. */
11
12
  export function clearJavaClassAnnotationFacts() {
@@ -14,6 +15,7 @@ export function clearJavaClassAnnotationFacts() {
14
15
  springConfigConsumers.clear();
15
16
  springConditionalFacts.clear();
16
17
  springDiFacts.clear();
18
+ springDynamicLookupFacts.clear();
17
19
  springNonHttpHandlerFacts.clear();
18
20
  }
19
21
  export function setJavaSpringAopFacts(filePath, facts) {
@@ -56,6 +58,15 @@ export function setJavaSpringDiFacts(filePath, facts) {
56
58
  export function getJavaSpringDiFacts(filePath) {
57
59
  return springDiFacts.get(filePath) ?? [];
58
60
  }
61
+ export function setJavaSpringDynamicLookupFacts(filePath, facts) {
62
+ if (facts.length === 0)
63
+ springDynamicLookupFacts.delete(filePath);
64
+ else
65
+ springDynamicLookupFacts.set(filePath, facts);
66
+ }
67
+ export function getJavaSpringDynamicLookupFacts(filePath) {
68
+ return springDynamicLookupFacts.get(filePath) ?? [];
69
+ }
59
70
  export function setJavaSpringNonHttpHandlerFacts(filePath, facts) {
60
71
  if (facts.length === 0)
61
72
  springNonHttpHandlerFacts.delete(filePath);
@@ -72,6 +83,7 @@ export function collectJavaCaptureSideChannel(filePath) {
72
83
  const configConsumers = springConfigConsumers.get(filePath) ?? [];
73
84
  const conditionFacts = springConditionalFacts.get(filePath) ?? [];
74
85
  const diFacts = springDiFacts.get(filePath) ?? [];
86
+ const dynamicLookupFacts = springDynamicLookupFacts.get(filePath) ?? [];
75
87
  const nonHttpHandlerFacts = springNonHttpHandlerFacts.get(filePath) ?? [];
76
88
  const packageFact = getJavaPackageFact(filePath);
77
89
  if (facts.length === 0 &&
@@ -79,6 +91,7 @@ export function collectJavaCaptureSideChannel(filePath) {
79
91
  configConsumers.length === 0 &&
80
92
  conditionFacts.length === 0 &&
81
93
  diFacts.length === 0 &&
94
+ dynamicLookupFacts.length === 0 &&
82
95
  nonHttpHandlerFacts.length === 0 &&
83
96
  packageFact === undefined) {
84
97
  return undefined;
@@ -91,6 +104,7 @@ export function collectJavaCaptureSideChannel(filePath) {
91
104
  ...(configConsumers.length > 0 ? { springConfigConsumers: configConsumers } : {}),
92
105
  ...(conditionFacts.length > 0 ? { springConditionalFacts: conditionFacts } : {}),
93
106
  ...(diFacts.length > 0 ? { springDiFacts: diFacts } : {}),
107
+ ...(dynamicLookupFacts.length > 0 ? { springDynamicLookupFacts: dynamicLookupFacts } : {}),
94
108
  ...(nonHttpHandlerFacts.length > 0 ? { springNonHttpHandlerFacts: nonHttpHandlerFacts } : {}),
95
109
  };
96
110
  }
@@ -110,6 +124,7 @@ export function applyJavaCaptureSideChannel(parsed) {
110
124
  setJavaSpringConfigConsumerFacts(parsed.filePath, []);
111
125
  setJavaSpringConditionalFacts(parsed.filePath, []);
112
126
  setJavaSpringDiFacts(parsed.filePath, []);
127
+ setJavaSpringDynamicLookupFacts(parsed.filePath, []);
113
128
  setJavaSpringNonHttpHandlerFacts(parsed.filePath, []);
114
129
  setJavaPackageFact(parsed.filePath, UNKNOWN_JVM_PACKAGE_FACT);
115
130
  return;
@@ -119,6 +134,7 @@ export function applyJavaCaptureSideChannel(parsed) {
119
134
  setJavaSpringConfigConsumerFacts(parsed.filePath, Array.isArray(data.springConfigConsumers) ? data.springConfigConsumers : []);
120
135
  setJavaSpringConditionalFacts(parsed.filePath, Array.isArray(data.springConditionalFacts) ? data.springConditionalFacts : []);
121
136
  setJavaSpringDiFacts(parsed.filePath, Array.isArray(data.springDiFacts) ? data.springDiFacts : []);
137
+ setJavaSpringDynamicLookupFacts(parsed.filePath, Array.isArray(data.springDynamicLookupFacts) ? data.springDynamicLookupFacts : []);
122
138
  setJavaSpringNonHttpHandlerFacts(parsed.filePath, Array.isArray(data.springNonHttpHandlerFacts) ? data.springNonHttpHandlerFacts : []);
123
139
  setJavaPackageFact(parsed.filePath, isJvmPackageFact(data.packageFact) ? data.packageFact : UNKNOWN_JVM_PACKAGE_FACT);
124
140
  }
@@ -7,16 +7,18 @@ import { getJavaParser, getJavaScopeQuery } from './query.js';
7
7
  import { recordCacheHit, recordCacheMiss } from './cache-stats.js';
8
8
  import { getTreeSitterBufferSize } from '../../constants.js';
9
9
  import { parseSourceSafe } from '../../../tree-sitter/safe-parse.js';
10
- import { setJavaClassAnnotationFacts, setJavaSpringAopFacts, setJavaSpringConfigConsumerFacts, setJavaSpringConditionalFacts, setJavaSpringDiFacts, setJavaSpringNonHttpHandlerFacts, } from './capture-side-channel.js';
10
+ import { setJavaClassAnnotationFacts, setJavaSpringAopFacts, setJavaSpringConfigConsumerFacts, setJavaSpringConditionalFacts, setJavaSpringDiFacts, setJavaSpringDynamicLookupFacts, setJavaSpringNonHttpHandlerFacts, } from './capture-side-channel.js';
11
11
  import { captureJavaPackageFact } from './package-facts.js';
12
12
  import { synthesizeCallableFlowCaptures } from '../../utils/callable-flow-captures.js';
13
13
  import { captureJavaSpringConfigConsumerFacts } from './spring-config-bindings.js';
14
14
  import { captureJavaSpringDiClassFact } from './spring-di.js';
15
+ import { captureJavaSpringDynamicLookupFact } from './spring-dynamic-lookup.js';
15
16
  import { synthesizeReceiverChainCapture } from '../../utils/receiver-chain-captures.js';
16
17
  import { captureJavaSpringAopFacts } from './spring-aop.js';
17
18
  import { captureJavaSpringConditionalFacts, } from './spring-conditionals.js';
18
19
  import { captureJavaSpringNonHttpHandlerFacts, } from './spring-non-http-handlers.js';
19
20
  import { synthesizeJavaRecordComponentAccessorCaptures } from './record-components.js';
21
+ import { synthesizeLombokAccessorCaptures } from './lombok-synthesizer.js';
20
22
  /** Declaration anchors that carry function-like arity metadata. */
21
23
  const FUNCTION_DECL_TAGS = ['@declaration.method', '@declaration.constructor'];
22
24
  /** tree-sitter-java node types that the method extractor accepts. */
@@ -98,6 +100,8 @@ export function emitJavaScopeCaptures(sourceText, filePath, cachedTree) {
98
100
  const springDiFacts = [];
99
101
  const springNonHttpHandlerFacts = [];
100
102
  const springDiClassNodeIds = new Set();
103
+ const springDynamicLookupFacts = [];
104
+ const springDynamicLookupNodeIds = new Set();
101
105
  for (const m of rawMatches) {
102
106
  const grouped = {};
103
107
  // Parallel tag -> captured SyntaxNode map. The tree-sitter query already
@@ -116,6 +120,13 @@ export function emitJavaScopeCaptures(sourceText, filePath, cachedTree) {
116
120
  }
117
121
  if (Object.keys(grouped).length === 0)
118
122
  continue;
123
+ const dynamicLookupNode = nodeIfType(nodeMap['@reference.call.member'], 'method_invocation');
124
+ if (dynamicLookupNode !== null && !springDynamicLookupNodeIds.has(dynamicLookupNode.id)) {
125
+ springDynamicLookupNodeIds.add(dynamicLookupNode.id);
126
+ const fact = captureJavaSpringDynamicLookupFact(dynamicLookupNode, filePath);
127
+ if (fact !== null)
128
+ springDynamicLookupFacts.push(fact);
129
+ }
119
130
  const springAopTypeNode = [
120
131
  nodeIfType(nodeMap['@scope.class'], 'class_declaration'),
121
132
  nodeIfType(nodeMap['@scope.class'], 'interface_declaration'),
@@ -287,6 +298,7 @@ export function emitJavaScopeCaptures(sourceText, filePath, cachedTree) {
287
298
  setJavaSpringAopFacts(filePath, springAopFacts);
288
299
  setJavaSpringConditionalFacts(filePath, springConditionalFacts);
289
300
  setJavaSpringDiFacts(filePath, springDiFacts);
301
+ setJavaSpringDynamicLookupFacts(filePath, springDynamicLookupFacts);
290
302
  setJavaSpringNonHttpHandlerFacts(filePath, springNonHttpHandlerFacts);
291
303
  return [
292
304
  ...resolveVarTypeBindings(out),
@@ -294,6 +306,7 @@ export function emitJavaScopeCaptures(sourceText, filePath, cachedTree) {
294
306
  ...synthesizeJavaExplicitConstructorReferences(tree.rootNode),
295
307
  ...synthesizeJavaAnonymousClassDeclarations(tree.rootNode),
296
308
  ...synthesizeJavaRecordComponentAccessorCaptures(tree.rootNode),
309
+ ...synthesizeLombokAccessorCaptures(tree.rootNode),
297
310
  ...synthesizeCallableFlowCaptures(tree.rootNode, JAVA_CALLABLE_CAPTURE_OPTIONS),
298
311
  ];
299
312
  }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Lombok accessor synthesizer for Java.
3
+ *
4
+ * Lombok generates getters/setters at compile time. They are absent from the
5
+ * AST, so calls like `obj.getOrderId()` on a `@Data` class would otherwise
6
+ * leave unresolved CALLS edges. This module walks the tree-sitter Java AST
7
+ * and synthesizes Method graph members for the accessors Lombok would emit
8
+ * under the supported subset.
9
+ *
10
+ * ## Supported subset (v1)
11
+ * - Proven `lombok.Data` / `lombok.Getter` / `lombok.Setter` (FQN or import).
12
+ * - Class- or field-level enable; `AccessLevel.NONE` disables.
13
+ * - Default JavaBeans naming; primitive `boolean isX` → `isX` / `setX`.
14
+ * - Access levels PUBLIC/PROTECTED/PRIVATE/PACKAGE.
15
+ * - `@Accessors(chain=true)` modeled as setter return = declaring type.
16
+ * - `@Accessors(fluent=true)` / `prefix=…`: omit affected accessors (names
17
+ * cannot be proven without full Lombok config).
18
+ * - External `lombok.config`: unsupported (may change semantics invisibly).
19
+ *
20
+ * ## Identity
21
+ * Owner lookup uses in-memory AST node ids only. Method ids are derived from
22
+ * the stable declaring-owner graph key (the Class node id's name segment),
23
+ * never from persisted tree-sitter node ids.
24
+ */
25
+ import type Parser from 'tree-sitter';
26
+ import type { CaptureMatch } from '../../../../_shared/index.js';
27
+ import { type PlannedJvmAccessor, type SyntheticAccessorResult, type SyntheticVisibility } from '../jvm/accessor-synthesis.js';
28
+ export type LombokVisibility = SyntheticVisibility;
29
+ export type SyntheticSymbol = SyntheticAccessorResult['symbols'][number];
30
+ export type SyntheticNode = SyntheticAccessorResult['nodes'][number];
31
+ export type SyntheticRelationship = SyntheticAccessorResult['relationships'][number];
32
+ export type LombokSynthesisResult = SyntheticAccessorResult;
33
+ export type PlannedLombokAccessor = PlannedJvmAccessor;
34
+ export interface AccessorConfig {
35
+ enabled: boolean;
36
+ visibility: LombokVisibility;
37
+ }
38
+ export declare function getterName(fieldName: string, fieldType: string): string;
39
+ export declare function setterName(fieldName: string, fieldType: string): string;
40
+ export declare function synthesizeLombokAccessors(tree: Parser.Tree, filePath: string, classOwnersById: ReadonlyMap<number, string>): LombokSynthesisResult;
41
+ /** Scope captures for Lombok accessors (dual-path parity with record components). */
42
+ export declare function synthesizeLombokAccessorCaptures(rootNode: Parser.SyntaxNode): CaptureMatch[];