gitnexus 1.6.6-rc.2 → 1.6.6-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 (112) hide show
  1. package/dist/_shared/index.d.ts +1 -1
  2. package/dist/_shared/index.d.ts.map +1 -1
  3. package/dist/_shared/index.js.map +1 -1
  4. package/dist/_shared/scope-resolution/reference-site.d.ts +8 -0
  5. package/dist/_shared/scope-resolution/reference-site.d.ts.map +1 -1
  6. package/dist/_shared/scope-resolution/registries/context.d.ts +18 -1
  7. package/dist/_shared/scope-resolution/registries/context.d.ts.map +1 -1
  8. package/dist/_shared/scope-resolution/registries/context.js.map +1 -1
  9. package/dist/_shared/scope-resolution/registries/lookup-core.d.ts +4 -2
  10. package/dist/_shared/scope-resolution/registries/lookup-core.d.ts.map +1 -1
  11. package/dist/_shared/scope-resolution/registries/lookup-core.js +8 -23
  12. package/dist/_shared/scope-resolution/registries/lookup-core.js.map +1 -1
  13. package/dist/cli/analyze.js +65 -3
  14. package/dist/cli/eval-server.d.ts +14 -3
  15. package/dist/cli/eval-server.js +79 -9
  16. package/dist/cli/index.js +3 -1
  17. package/dist/cli/serve.js +6 -1
  18. package/dist/cli/setup.js +6 -4
  19. package/dist/cli/wiki.d.ts +1 -0
  20. package/dist/cli/wiki.js +32 -8
  21. package/dist/core/ingestion/languages/cpp/captures.js +165 -9
  22. package/dist/core/ingestion/languages/cpp/constraint-filter.js +102 -32
  23. package/dist/core/ingestion/languages/cpp/type-classifier.d.ts +9 -9
  24. package/dist/core/ingestion/languages/cpp/type-classifier.js +12 -8
  25. package/dist/core/ingestion/languages/java.js +35 -0
  26. package/dist/core/ingestion/languages/javascript/arity.d.ts +11 -0
  27. package/dist/core/ingestion/languages/javascript/arity.js +11 -0
  28. package/dist/core/ingestion/languages/javascript/captures.d.ts +30 -0
  29. package/dist/core/ingestion/languages/javascript/captures.js +655 -0
  30. package/dist/core/ingestion/languages/javascript/import-target.d.ts +29 -0
  31. package/dist/core/ingestion/languages/javascript/import-target.js +53 -0
  32. package/dist/core/ingestion/languages/javascript/index.d.ts +48 -0
  33. package/dist/core/ingestion/languages/javascript/index.js +48 -0
  34. package/dist/core/ingestion/languages/javascript/interpret.d.ts +29 -0
  35. package/dist/core/ingestion/languages/javascript/interpret.js +41 -0
  36. package/dist/core/ingestion/languages/javascript/merge-bindings.d.ts +16 -0
  37. package/dist/core/ingestion/languages/javascript/merge-bindings.js +18 -0
  38. package/dist/core/ingestion/languages/javascript/query.d.ts +52 -0
  39. package/dist/core/ingestion/languages/javascript/query.js +413 -0
  40. package/dist/core/ingestion/languages/javascript/scope-resolver.d.ts +37 -0
  41. package/dist/core/ingestion/languages/javascript/scope-resolver.js +73 -0
  42. package/dist/core/ingestion/languages/javascript/simple-hooks.d.ts +32 -0
  43. package/dist/core/ingestion/languages/javascript/simple-hooks.js +37 -0
  44. package/dist/core/ingestion/languages/typescript/simple-hooks.d.ts +10 -0
  45. package/dist/core/ingestion/languages/typescript/simple-hooks.js +4 -1
  46. package/dist/core/ingestion/languages/typescript.js +15 -0
  47. package/dist/core/ingestion/model/field-registry.d.ts +17 -3
  48. package/dist/core/ingestion/model/field-registry.js +19 -4
  49. package/dist/core/ingestion/model/owned-members-lookup.d.ts +19 -0
  50. package/dist/core/ingestion/model/owned-members-lookup.js +43 -0
  51. package/dist/core/ingestion/model/type-registry.d.ts +9 -0
  52. package/dist/core/ingestion/model/type-registry.js +18 -0
  53. package/dist/core/ingestion/registry-primary-flag.js +1 -0
  54. package/dist/core/ingestion/resolve-references.d.ts +3 -1
  55. package/dist/core/ingestion/resolve-references.js +5 -1
  56. package/dist/core/ingestion/scope-extractor.js +4 -0
  57. package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +1 -0
  58. package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +37 -7
  59. package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.d.ts +2 -0
  60. package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.js +8 -1
  61. package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +2 -0
  62. package/dist/core/ingestion/scope-resolution/pipeline/reconcile-ownership.d.ts +4 -2
  63. package/dist/core/ingestion/scope-resolution/pipeline/reconcile-ownership.js +48 -9
  64. package/dist/core/ingestion/scope-resolution/pipeline/registry.js +2 -0
  65. package/dist/core/ingestion/scope-resolution/pipeline/run.js +2 -0
  66. package/dist/core/lbug/lbug-adapter.d.ts +3 -1
  67. package/dist/core/lbug/lbug-adapter.js +33 -19
  68. package/dist/core/lbug/lbug-config.d.ts +1 -1
  69. package/dist/core/lbug/lbug-config.js +1 -1
  70. package/dist/core/lbug/pool-adapter.d.ts +19 -7
  71. package/dist/core/lbug/pool-adapter.js +70 -44
  72. package/dist/core/lbug/query-params.d.ts +1 -0
  73. package/dist/core/lbug/query-params.js +21 -0
  74. package/dist/core/search/bm25-index.js +4 -6
  75. package/dist/core/wiki/generator.d.ts +13 -0
  76. package/dist/core/wiki/generator.js +45 -4
  77. package/dist/core/wiki/llm-client.d.ts +1 -1
  78. package/dist/core/wiki/llm-client.js +23 -6
  79. package/dist/mcp/local/local-backend.d.ts +18 -3
  80. package/dist/mcp/local/local-backend.js +127 -11
  81. package/dist/mcp/tools.js +10 -0
  82. package/dist/server/api.d.ts +3 -0
  83. package/dist/server/api.js +58 -30
  84. package/package.json +3 -3
  85. package/web/assets/agent-SmDhIVj9.js +608 -0
  86. package/web/assets/{architectureDiagram-UL44E2DR-DvIkEGkp.js → architectureDiagram-UL44E2DR-ChS6kfgC.js} +1 -1
  87. package/web/assets/{chunk-LCXTWHL2-CqJ0oo1x.js → chunk-LCXTWHL2-CikfiTEP.js} +1 -1
  88. package/web/assets/{chunk-RG4AUYOV-D0M6vdq9.js → chunk-RG4AUYOV-D0pH0sP0.js} +1 -1
  89. package/web/assets/{classDiagram-KGZ6W3CR-BB-saqC1.js → classDiagram-KGZ6W3CR-VJjLBrQ3.js} +1 -1
  90. package/web/assets/{classDiagram-v2-72OJOZXJ-Bp2bAlS5.js → classDiagram-v2-72OJOZXJ-CL_v399n.js} +1 -1
  91. package/web/assets/{diagram-3NCE3AQN-BUxnDPOY.js → diagram-3NCE3AQN-DTTuOnDj.js} +1 -1
  92. package/web/assets/{diagram-GF46GFSD-BJTyqqvI.js → diagram-GF46GFSD-Di3e_png.js} +1 -1
  93. package/web/assets/{diagram-QXG6HAR7-DilMHamP.js → diagram-QXG6HAR7-CVQY1hhk.js} +1 -1
  94. package/web/assets/{diagram-WEQXMOUZ-8KUrarg1.js → diagram-WEQXMOUZ-BoxS7CN3.js} +1 -1
  95. package/web/assets/{erDiagram-L5TCEMPS-Doj9mSiW.js → erDiagram-L5TCEMPS-CLTuHusW.js} +1 -1
  96. package/web/assets/{flowDiagram-H6V6AXG4-BOSR-i3p.js → flowDiagram-H6V6AXG4-CQfVb2C4.js} +1 -1
  97. package/web/assets/{index-j4-NuleT.js → index-BuC2I_Cj.js} +5 -5
  98. package/web/assets/{infoDiagram-3YFTVSEB-Ce_TvtaV.js → infoDiagram-3YFTVSEB-BOk6LlXV.js} +1 -1
  99. package/web/assets/{ishikawaDiagram-BNXS4ZKH-4MXIDCSF.js → ishikawaDiagram-BNXS4ZKH-C0sASGB6.js} +1 -1
  100. package/web/assets/{kanban-definition-75IXJCU3-yYdfm8Kk.js → kanban-definition-75IXJCU3-DT9Lizpz.js} +1 -1
  101. package/web/assets/{mindmap-definition-2TDM6QVE-DFNEKM77.js → mindmap-definition-2TDM6QVE-BEYaB7hb.js} +1 -1
  102. package/web/assets/{pieDiagram-CU6KROY3-iZAqpvhd.js → pieDiagram-CU6KROY3-DCgHNkyY.js} +1 -1
  103. package/web/assets/{requirementDiagram-JXO7QTGE-CtDijhnf.js → requirementDiagram-JXO7QTGE-D6vDU9M2.js} +1 -1
  104. package/web/assets/{sequenceDiagram-VS2MUI6T-BdjvyCHM.js → sequenceDiagram-VS2MUI6T-CJrGCTXy.js} +1 -1
  105. package/web/assets/{stateDiagram-7D4R322I-e5odN9fG.js → stateDiagram-7D4R322I-BvxQnQyL.js} +1 -1
  106. package/web/assets/{stateDiagram-v2-36443NZ5-vPsvjR2D.js → stateDiagram-v2-36443NZ5-D8ziO9W2.js} +1 -1
  107. package/web/assets/{timeline-definition-O6YCAMPW-DPAksNQp.js → timeline-definition-O6YCAMPW-B45j2q3m.js} +1 -1
  108. package/web/assets/{vennDiagram-MWXL3ELB-Dtlfdt7J.js → vennDiagram-MWXL3ELB-CRkZRDhi.js} +1 -1
  109. package/web/assets/{wardleyDiagram-CUQ6CDDI-B23uRMUC.js → wardleyDiagram-CUQ6CDDI-BekUytZJ.js} +1 -1
  110. package/web/assets/{xychartDiagram-N2JHSOCM-DxwHeksW.js → xychartDiagram-N2JHSOCM-BeMqwSgr.js} +1 -1
  111. package/web/index.html +1 -1
  112. package/web/assets/agent-D2kLt6Dl.js +0 -597
@@ -0,0 +1,413 @@
1
+ /**
2
+ * Tree-sitter query for JavaScript scope captures (RFC §5.1, Ring 3).
3
+ *
4
+ * Subset of the TypeScript scope query (`languages/typescript/query.ts`)
5
+ * compiled against `tree-sitter-javascript`. TypeScript-only node types
6
+ * (`interface_declaration`, `type_alias_declaration`, `enum_declaration`,
7
+ * `internal_module`, `abstract_class_declaration`, `function_signature`,
8
+ * `method_signature`, `abstract_method_signature`, `type_annotation`,
9
+ * `public_field_definition`) are dropped because:
10
+ *
11
+ * 1. The JS grammar doesn't define them — the query compiler would
12
+ * throw `InvalidNodeType` if they were included.
13
+ * 2. JavaScript has no static type annotations, so the `@type-binding.*`
14
+ * patterns derived from TS annotation nodes don't apply.
15
+ *
16
+ * What IS shared with the TypeScript query:
17
+ *
18
+ * - Scope patterns: `program`, `class_declaration`, `(class)` (the JS
19
+ * grammar node for class expressions — NOT `class_expression`, which
20
+ * does not exist in `tree-sitter-javascript`), `function_declaration`,
21
+ * `generator_function_declaration`, `function_expression`,
22
+ * `arrow_function`, `method_definition`.
23
+ * - Declaration patterns for functions, classes, const/let/var,
24
+ * object-property arrows (Zustand, TanStack, etc.), and HOC-wrapped
25
+ * variable declarations (forwardRef / memo / useCallback / useMemo).
26
+ * - Import patterns: `import_statement`, `export_statement` re-exports,
27
+ * and dynamic `import()` (represented as `call_expression(import)` in
28
+ * both grammars — the `import` leaf node exists in tree-sitter-javascript
29
+ * as well as tree-sitter-typescript).
30
+ * - Type-binding patterns that work without static annotations:
31
+ * constructor inference (`new User()`), call-result alias
32
+ * (`const u = getUser()`), member-access alias (`const a = u.addr`),
33
+ * identifier alias, assignment rebind, and for-of element bindings.
34
+ * JSDoc-derived type bindings (`@param {User} u`, `@returns {User}`)
35
+ * are handled separately in `captures.ts` via comment-node scanning.
36
+ * - Reference patterns: free calls, member calls, constructor calls,
37
+ * write-access, read-access, and dynamic import.
38
+ *
39
+ * CJS `require()` is NOT captured here; it is handled in `captures.ts`
40
+ * by scanning parent context (destructured vs. namespace) of `call_expression`
41
+ * nodes whose callee is the identifier `require`.
42
+ *
43
+ * Grammar version: `tree-sitter-javascript` pinned in gitnexus/package.json.
44
+ *
45
+ * Exposes lazy `Parser` and `Query` singletons so callers don't pay
46
+ * tree-sitter init cost per file.
47
+ */
48
+ import Parser from 'tree-sitter';
49
+ import JS from 'tree-sitter-javascript';
50
+ const JS_GRAMMAR = JS;
51
+ /** True when the file should be parsed with the JSX-extended query. */
52
+ function isJsxFile(filePath) {
53
+ return filePath.endsWith('.jsx');
54
+ }
55
+ const JAVASCRIPT_SCOPE_QUERY = `
56
+ ;; Scopes — module / class-likes / function-likes
57
+ (program) @scope.module
58
+
59
+ (class_declaration) @scope.class
60
+ (class) @scope.class
61
+
62
+ (function_declaration) @scope.function
63
+ (generator_function_declaration) @scope.function
64
+ (function_expression) @scope.function
65
+ (arrow_function) @scope.function
66
+ (method_definition) @scope.function
67
+
68
+ ;; Declarations — classes
69
+ (class_declaration
70
+ name: (identifier) @declaration.name) @declaration.class
71
+
72
+ ;; Declarations — methods (inside class bodies)
73
+ (method_definition
74
+ name: (property_identifier) @declaration.name) @declaration.method
75
+
76
+ ;; Declarations — class fields (JS uses field_definition, not public_field_definition)
77
+ (field_definition
78
+ property: (property_identifier) @declaration.name) @declaration.property
79
+
80
+ ;; Declarations — free functions
81
+ (function_declaration
82
+ name: (identifier) @declaration.name) @declaration.function
83
+
84
+ (generator_function_declaration
85
+ name: (identifier) @declaration.name) @declaration.function
86
+
87
+ ;; Arrow / function-expression assigned to a const/let/var.
88
+ ;; Anchor discipline: @declaration.function sits on the INNER arrow or
89
+ ;; function_expression, NOT on the lexical_declaration wrapper. This
90
+ ;; aligns anchor.range with the @scope.function range so
91
+ ;; pass2AttachDeclarations resolves the innermost scope correctly and
92
+ ;; resolveCallerGraphId walks up to the right caller anchor.
93
+ (lexical_declaration
94
+ (variable_declarator
95
+ name: (identifier) @declaration.name
96
+ value: (arrow_function) @declaration.function))
97
+
98
+ (lexical_declaration
99
+ (variable_declarator
100
+ name: (identifier) @declaration.name
101
+ value: (function_expression) @declaration.function))
102
+
103
+ (export_statement
104
+ declaration: (lexical_declaration
105
+ (variable_declarator
106
+ name: (identifier) @declaration.name
107
+ value: (arrow_function) @declaration.function)))
108
+
109
+ (export_statement
110
+ declaration: (lexical_declaration
111
+ (variable_declarator
112
+ name: (identifier) @declaration.name
113
+ value: (function_expression) @declaration.function)))
114
+
115
+ (variable_declaration
116
+ (variable_declarator
117
+ name: (identifier) @declaration.name
118
+ value: (arrow_function) @declaration.function))
119
+
120
+ (variable_declaration
121
+ (variable_declarator
122
+ name: (identifier) @declaration.name
123
+ value: (function_expression) @declaration.function))
124
+
125
+ ;; Object-property arrows / function expressions named by their pair key.
126
+ ;; Same anchor discipline as the lexical_declaration block above: the
127
+ ;; @declaration.function capture must sit on the INNER arrow/fn-expression.
128
+ (pair
129
+ key: (property_identifier) @declaration.name
130
+ value: (arrow_function) @declaration.function)
131
+
132
+ (pair
133
+ key: (property_identifier) @declaration.name
134
+ value: (function_expression) @declaration.function)
135
+
136
+ (pair
137
+ key: (string (string_fragment) @declaration.name)
138
+ value: (arrow_function) @declaration.function)
139
+
140
+ (pair
141
+ key: (string (string_fragment) @declaration.name)
142
+ value: (function_expression) @declaration.function)
143
+
144
+ ;; HOC-wrapped variable declarations: const X = HOC((args) => { ... }).
145
+ ;; Covers React.forwardRef, memo, useCallback, useMemo, observer,
146
+ ;; debounce, and any user-defined HOC factory.
147
+ (lexical_declaration
148
+ (variable_declarator
149
+ name: (identifier) @declaration.name
150
+ value: (call_expression
151
+ arguments: (arguments
152
+ (arrow_function) @declaration.function))))
153
+
154
+ (lexical_declaration
155
+ (variable_declarator
156
+ name: (identifier) @declaration.name
157
+ value: (call_expression
158
+ arguments: (arguments
159
+ (function_expression) @declaration.function))))
160
+
161
+ (export_statement
162
+ declaration: (lexical_declaration
163
+ (variable_declarator
164
+ name: (identifier) @declaration.name
165
+ value: (call_expression
166
+ arguments: (arguments
167
+ (arrow_function) @declaration.function)))))
168
+
169
+ (export_statement
170
+ declaration: (lexical_declaration
171
+ (variable_declarator
172
+ name: (identifier) @declaration.name
173
+ value: (call_expression
174
+ arguments: (arguments
175
+ (function_expression) @declaration.function)))))
176
+
177
+ (variable_declaration
178
+ (variable_declarator
179
+ name: (identifier) @declaration.name
180
+ value: (call_expression
181
+ arguments: (arguments
182
+ (arrow_function) @declaration.function))))
183
+
184
+ (variable_declaration
185
+ (variable_declarator
186
+ name: (identifier) @declaration.name
187
+ value: (call_expression
188
+ arguments: (arguments
189
+ (function_expression) @declaration.function))))
190
+
191
+ ;; Variable / constant declarations (non-function values).
192
+ (lexical_declaration
193
+ (variable_declarator
194
+ name: (identifier) @declaration.name)) @declaration.const
195
+
196
+ (export_statement
197
+ declaration: (lexical_declaration
198
+ (variable_declarator
199
+ name: (identifier) @declaration.name))) @declaration.const
200
+
201
+ (variable_declaration
202
+ (variable_declarator
203
+ name: (identifier) @declaration.name)) @declaration.variable
204
+
205
+ ;; Imports (ESM) — single anchor per statement; decomposer emits per-specifier markers.
206
+ (import_statement) @import.statement
207
+
208
+ ;; Re-exports with a source clause.
209
+ (export_statement
210
+ source: (string)) @import.statement
211
+
212
+ ;; Dynamic imports: import('./m') — tree-sitter-javascript represents this
213
+ ;; as call_expression with a named import leaf as the function field,
214
+ ;; identical to tree-sitter-typescript.
215
+ (call_expression
216
+ function: (import)) @import.dynamic
217
+
218
+ ;; ── Type bindings (no static annotations in JS; inferred from AST shape) ──
219
+
220
+ ;; Constructor-inferred: const u = new User()
221
+ (variable_declarator
222
+ name: (identifier) @type-binding.name
223
+ value: (new_expression
224
+ constructor: (identifier) @type-binding.type)) @type-binding.constructor
225
+
226
+ ;; Qualified constructor: const u = new models.User()
227
+ (variable_declarator
228
+ name: (identifier) @type-binding.name
229
+ value: (new_expression
230
+ constructor: (member_expression) @type-binding.type)) @type-binding.constructor
231
+
232
+ ;; Call-result alias: const u = getUser()
233
+ (variable_declarator
234
+ name: (identifier) @type-binding.name
235
+ value: (call_expression
236
+ function: (identifier) @type-binding.type)) @type-binding.alias
237
+
238
+ ;; Member-call alias: const u = svc.getUser()
239
+ (variable_declarator
240
+ name: (identifier) @type-binding.name
241
+ value: (call_expression
242
+ function: (member_expression) @type-binding.type)) @type-binding.alias
243
+
244
+ ;; Await chain: const u = await getUser() / await svc.getUser()
245
+ (variable_declarator
246
+ name: (identifier) @type-binding.name
247
+ value: (await_expression
248
+ (call_expression
249
+ function: (identifier) @type-binding.type))) @type-binding.alias
250
+
251
+ (variable_declarator
252
+ name: (identifier) @type-binding.name
253
+ value: (await_expression
254
+ (call_expression
255
+ function: (member_expression) @type-binding.type))) @type-binding.alias
256
+
257
+ ;; Member-access alias: const addr = user.address
258
+ (variable_declarator
259
+ name: (identifier) @type-binding.name
260
+ value: (member_expression) @type-binding.type) @type-binding.member-alias
261
+
262
+ ;; Identifier alias: const alias = user
263
+ (variable_declarator
264
+ name: (identifier) @type-binding.name
265
+ value: (identifier) @type-binding.type) @type-binding.alias
266
+
267
+ ;; Assignment rebind: u = new User() / u = getUser()
268
+ (assignment_expression
269
+ left: (identifier) @type-binding.name
270
+ right: (new_expression
271
+ constructor: (identifier) @type-binding.type)) @type-binding.constructor
272
+
273
+ (assignment_expression
274
+ left: (identifier) @type-binding.name
275
+ right: (call_expression
276
+ function: (identifier) @type-binding.type)) @type-binding.alias
277
+
278
+ (assignment_expression
279
+ left: (identifier) @type-binding.name
280
+ right: (identifier) @type-binding.type) @type-binding.alias
281
+
282
+ ;; For-of element: for (const u of users) / for (const u of getUsers())
283
+ (for_in_statement
284
+ left: (identifier) @type-binding.name
285
+ right: (identifier) @type-binding.type) @type-binding.alias
286
+
287
+ (for_in_statement
288
+ left: (identifier) @type-binding.name
289
+ right: (call_expression
290
+ function: (identifier) @type-binding.type)) @type-binding.alias
291
+
292
+ (for_in_statement
293
+ left: (identifier) @type-binding.name
294
+ right: (call_expression
295
+ function: (member_expression) @type-binding.type)) @type-binding.alias
296
+
297
+ (for_in_statement
298
+ left: (identifier) @type-binding.name
299
+ right: (member_expression
300
+ property: (property_identifier) @type-binding.type)) @type-binding.alias
301
+
302
+ ;; ── References ────────────────────────────────────────────────────────────
303
+
304
+ ;; Free calls: fn(args). The dynamic-import filter runs in captures.ts.
305
+ (call_expression
306
+ function: (identifier) @reference.name) @reference.call.free
307
+
308
+ ;; Awaited free call: await fn<T>(...) re-associated by tree-sitter.
309
+ (call_expression
310
+ function: (await_expression
311
+ (identifier) @reference.name)) @reference.call.free
312
+
313
+ ;; Member calls: obj.method() (includes optional chain).
314
+ (call_expression
315
+ function: (member_expression
316
+ object: (_) @reference.receiver
317
+ property: (property_identifier) @reference.name)) @reference.call.member
318
+
319
+ ;; Awaited member call: await svc.m<T>(...)
320
+ (call_expression
321
+ function: (await_expression
322
+ (member_expression
323
+ object: (_) @reference.receiver
324
+ property: (property_identifier) @reference.name))) @reference.call.member
325
+
326
+ ;; Constructor calls: new User() / new ns.User()
327
+ (new_expression
328
+ constructor: (identifier) @reference.name) @reference.call.constructor
329
+
330
+ (new_expression
331
+ constructor: (member_expression) @reference.call.constructor.qualified) @reference.call.constructor
332
+
333
+ ;; Write access: obj.field = value
334
+ (assignment_expression
335
+ left: (member_expression
336
+ object: (_) @reference.receiver
337
+ property: (property_identifier) @reference.name)) @reference.write.member
338
+
339
+ (augmented_assignment_expression
340
+ left: (member_expression
341
+ object: (_) @reference.receiver
342
+ property: (property_identifier) @reference.name)) @reference.write.member
343
+
344
+ ;; Read access: obj.field (in read context; captures.ts filters non-reads).
345
+ (member_expression
346
+ object: (_) @reference.receiver
347
+ property: (property_identifier) @reference.name) @reference.read.member
348
+ `;
349
+ /** JSX-only suffix — appended when compiling against the JSX grammar for .jsx files. */
350
+ const JSX_QUERY_SUFFIX = `
351
+ ;; <Foo />
352
+ ((jsx_self_closing_element
353
+ name: (identifier) @reference.name) @reference.call.free
354
+ (#match? @reference.name "^[A-Z]"))
355
+
356
+ ;; <Foo> ... </Foo>
357
+ ((jsx_opening_element
358
+ name: (identifier) @reference.name) @reference.call.free
359
+ (#match? @reference.name "^[A-Z]"))
360
+
361
+ ;; <Foo.Bar />
362
+ (jsx_self_closing_element
363
+ name: (member_expression
364
+ object: (_) @reference.receiver
365
+ property: (property_identifier) @reference.name)) @reference.call.member
366
+
367
+ (jsx_opening_element
368
+ name: (member_expression
369
+ object: (_) @reference.receiver
370
+ property: (property_identifier) @reference.name)) @reference.call.member
371
+ `;
372
+ let _jsParser = null;
373
+ let _jsQuery = null;
374
+ let _jsxParser = null;
375
+ let _jsxQuery = null;
376
+ export function getJsParser(filePath) {
377
+ // JSX files use the same JavaScript grammar in tree-sitter-javascript;
378
+ // both .js and .jsx parse with the same grammar object. We keep separate
379
+ // singletons only to mirror the TypeScript pattern and in case a future
380
+ // version of the grammar diverges.
381
+ if (filePath !== undefined && isJsxFile(filePath)) {
382
+ if (_jsxParser === null) {
383
+ _jsxParser = new Parser();
384
+ _jsxParser.setLanguage(JS_GRAMMAR);
385
+ }
386
+ return _jsxParser;
387
+ }
388
+ if (_jsParser === null) {
389
+ _jsParser = new Parser();
390
+ _jsParser.setLanguage(JS_GRAMMAR);
391
+ }
392
+ return _jsParser;
393
+ }
394
+ export function getJsScopeQuery(filePath) {
395
+ if (filePath !== undefined && isJsxFile(filePath)) {
396
+ if (_jsxQuery === null) {
397
+ _jsxQuery = new Parser.Query(JS_GRAMMAR, JAVASCRIPT_SCOPE_QUERY + JSX_QUERY_SUFFIX);
398
+ }
399
+ return _jsxQuery;
400
+ }
401
+ if (_jsQuery === null) {
402
+ _jsQuery = new Parser.Query(JS_GRAMMAR, JAVASCRIPT_SCOPE_QUERY);
403
+ }
404
+ return _jsQuery;
405
+ }
406
+ /** Validate that a cached Tree was produced by the JS grammar. */
407
+ export function jsCachedTreeMatchesGrammar(tree) {
408
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
409
+ const lang = tree?.getLanguage?.();
410
+ if (lang === undefined || lang === null)
411
+ return true;
412
+ return lang === JS_GRAMMAR;
413
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * JavaScript `ScopeResolver` registered in `SCOPE_RESOLVERS` and
3
+ * consumed by the generic `runScopeResolution` orchestrator
4
+ * (RFC #909 Ring 3, issue #928).
5
+ *
6
+ * Follows the same minimal wiring-only pattern as TypeScript (the third
7
+ * migration). Per-hook logic lives in sibling modules:
8
+ *
9
+ * - `query.ts` — JS scope query + parser/query singletons
10
+ * - `captures.ts` — `emitJsScopeCaptures` (JS grammar, CJS, JSDoc)
11
+ * - `interpret.ts` — `interpretJsImport` (delegates to TS interpreter)
12
+ * - `simple-hooks.ts` — `jsBindingScopeFor`, `jsImportOwningScope`,
13
+ * `jsReceiverBinding` (all delegate to TS hooks)
14
+ * - `merge-bindings.ts` — `jsMergeBindings` (delegates to TS function)
15
+ * - `arity.ts` — `jsArityCompatibility` (delegates to TS function)
16
+ * - `import-target.ts` — `makeJsResolveImportTarget` (TS resolver, JS extensions)
17
+ *
18
+ * See `./index.ts` for the full per-module rationale.
19
+ *
20
+ * ## Key differences from TypeScript resolver
21
+ *
22
+ * - `fieldFallbackOnMethodLookup: true` — JavaScript is dynamically typed;
23
+ * the field-fallback heuristic is ENABLED (unlike TypeScript, which
24
+ * disables it because the type-binding layer is precise).
25
+ * - `allowGlobalFreeCallFallback: true` — CJS `require` patterns and
26
+ * global helpers (e.g. `process`, `console`) benefit from workspace-
27
+ * wide unique-name fallback. TypeScript uses explicit imports.
28
+ * - `loadResolutionConfig` is omitted — JavaScript projects don't use
29
+ * `tsconfig.json` path aliases in general. `tsconfigPaths: null` is
30
+ * threaded through the resolver adapter.
31
+ * - `hoistTypeBindingsToModule: true` — JSDoc `@returns {T}` bindings are
32
+ * synthesized on the function scope and hoisted, matching TypeScript's
33
+ * method return-type hoisting strategy for cross-file chain resolution.
34
+ */
35
+ import type { ScopeResolver } from '../../scope-resolution/contract/scope-resolver.js';
36
+ declare const javascriptScopeResolver: ScopeResolver;
37
+ export { javascriptScopeResolver };
@@ -0,0 +1,73 @@
1
+ /**
2
+ * JavaScript `ScopeResolver` registered in `SCOPE_RESOLVERS` and
3
+ * consumed by the generic `runScopeResolution` orchestrator
4
+ * (RFC #909 Ring 3, issue #928).
5
+ *
6
+ * Follows the same minimal wiring-only pattern as TypeScript (the third
7
+ * migration). Per-hook logic lives in sibling modules:
8
+ *
9
+ * - `query.ts` — JS scope query + parser/query singletons
10
+ * - `captures.ts` — `emitJsScopeCaptures` (JS grammar, CJS, JSDoc)
11
+ * - `interpret.ts` — `interpretJsImport` (delegates to TS interpreter)
12
+ * - `simple-hooks.ts` — `jsBindingScopeFor`, `jsImportOwningScope`,
13
+ * `jsReceiverBinding` (all delegate to TS hooks)
14
+ * - `merge-bindings.ts` — `jsMergeBindings` (delegates to TS function)
15
+ * - `arity.ts` — `jsArityCompatibility` (delegates to TS function)
16
+ * - `import-target.ts` — `makeJsResolveImportTarget` (TS resolver, JS extensions)
17
+ *
18
+ * See `./index.ts` for the full per-module rationale.
19
+ *
20
+ * ## Key differences from TypeScript resolver
21
+ *
22
+ * - `fieldFallbackOnMethodLookup: true` — JavaScript is dynamically typed;
23
+ * the field-fallback heuristic is ENABLED (unlike TypeScript, which
24
+ * disables it because the type-binding layer is precise).
25
+ * - `allowGlobalFreeCallFallback: true` — CJS `require` patterns and
26
+ * global helpers (e.g. `process`, `console`) benefit from workspace-
27
+ * wide unique-name fallback. TypeScript uses explicit imports.
28
+ * - `loadResolutionConfig` is omitted — JavaScript projects don't use
29
+ * `tsconfig.json` path aliases in general. `tsconfigPaths: null` is
30
+ * threaded through the resolver adapter.
31
+ * - `hoistTypeBindingsToModule: true` — JSDoc `@returns {T}` bindings are
32
+ * synthesized on the function scope and hoisted, matching TypeScript's
33
+ * method return-type hoisting strategy for cross-file chain resolution.
34
+ */
35
+ import { SupportedLanguages } from '../../../../_shared/index.js';
36
+ import { buildMro, defaultLinearize } from '../../scope-resolution/passes/mro.js';
37
+ import { populateClassOwnedMembers } from '../../scope-resolution/scope/walkers.js';
38
+ import { javascriptProvider } from '../typescript.js';
39
+ import { jsMergeBindings } from './merge-bindings.js';
40
+ import { jsArityCompatibility } from './arity.js';
41
+ import { makeJsResolveImportTarget } from './import-target.js';
42
+ const javascriptScopeResolver = {
43
+ language: SupportedLanguages.JavaScript,
44
+ languageProvider: javascriptProvider,
45
+ importEdgeReason: 'javascript-scope: import',
46
+ resolveImportTarget: makeJsResolveImportTarget(),
47
+ // JavaScript LEGB — same tier ordering as TypeScript; no declaration-
48
+ // merging across type/value/namespace spaces.
49
+ mergeBindings: (existing, incoming) => [...jsMergeBindings([...existing, ...incoming])],
50
+ // Adapter: jsArityCompatibility uses (def, callsite); contract is (callsite, def).
51
+ arityCompatibility: (callsite, def) => jsArityCompatibility(def, callsite),
52
+ buildMro: (graph, parsedFiles, nodeLookup) => buildMro(graph, parsedFiles, nodeLookup, defaultLinearize),
53
+ populateOwners: (parsed) => populateClassOwnedMembers(parsed),
54
+ // JavaScript `super` keyword: same pattern as TypeScript.
55
+ isSuperReceiver: (text) => /^super(\s*\(|\s*\.|\s*\[|\s*$)/.test(text.trim()),
56
+ // JavaScript is dynamically typed — enable the field-fallback heuristic
57
+ // so member-call receivers without type annotations can still resolve
58
+ // through declared class fields (e.g. JSDoc-typed fields).
59
+ fieldFallbackOnMethodLookup: true,
60
+ // Return-type propagation (across ESM imports) mirrors TypeScript's
61
+ // default behavior. JSDoc @returns bindings are hoisted to Module scope
62
+ // and propagated to importers via the standard mechanism.
63
+ propagatesReturnTypesAcrossImports: true,
64
+ // JSDoc @returns bindings are synthesized on the function/method node
65
+ // and hoisted to Module scope by `jsBindingScopeFor` (identical to the
66
+ // TypeScript `tsBindingScopeFor` `@type-binding.return` branch).
67
+ hoistTypeBindingsToModule: true,
68
+ // CJS-heavy codebases often have utility functions exported without
69
+ // explicit imports at the call site. Workspace-wide unique-name fallback
70
+ // recovers these edges.
71
+ allowGlobalFreeCallFallback: true,
72
+ };
73
+ export { javascriptScopeResolver };
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Simple hooks for the JavaScript scope-resolution provider.
3
+ *
4
+ * `jsBindingScopeFor` wraps `tsBindingScopeFor` and adds the JS-only
5
+ * `@type-binding.class-field` hoisting rule. The other two hooks
6
+ * (`jsImportOwningScope`, `jsReceiverBinding`) are identical to their
7
+ * TypeScript counterparts and are re-exported directly.
8
+ *
9
+ * ## Why class-field hoisting lives here (not in `tsBindingScopeFor`)
10
+ *
11
+ * `@type-binding.class-field` is emitted exclusively by
12
+ * `synthesizeConstructorFieldBindings` in `captures.ts`, which is a
13
+ * JavaScript-only synthesis pass. TypeScript uses
14
+ * `@type-binding.parameter-property` for constructor parameter
15
+ * properties instead. Keeping the JS-only rule in the JS hook file
16
+ * prevents language-specific logic from leaking into shared TypeScript
17
+ * infrastructure (DoD.md §2.2).
18
+ */
19
+ import type { CaptureMatch, Scope, ScopeId, ScopeTree } from '../../../../_shared/index.js';
20
+ export { tsImportOwningScope as jsImportOwningScope, tsReceiverBinding as jsReceiverBinding, } from '../typescript/simple-hooks.js';
21
+ /**
22
+ * Like `tsBindingScopeFor` but additionally hoists
23
+ * `@type-binding.class-field` captures to the enclosing Class scope.
24
+ *
25
+ * `@type-binding.class-field` is anchored inside the constructor body
26
+ * (by `synthesizeConstructorFieldBindings`) so that `walkToScope` can
27
+ * walk up from the Function (constructor) scope to the Class scope.
28
+ * This puts `User.address → Address` in the class's typeBindings so
29
+ * compound-receiver resolution finds it when resolving
30
+ * `user.address.save()`.
31
+ */
32
+ export declare function jsBindingScopeFor(decl: CaptureMatch, innermost: Scope, tree: ScopeTree): ScopeId | null;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Simple hooks for the JavaScript scope-resolution provider.
3
+ *
4
+ * `jsBindingScopeFor` wraps `tsBindingScopeFor` and adds the JS-only
5
+ * `@type-binding.class-field` hoisting rule. The other two hooks
6
+ * (`jsImportOwningScope`, `jsReceiverBinding`) are identical to their
7
+ * TypeScript counterparts and are re-exported directly.
8
+ *
9
+ * ## Why class-field hoisting lives here (not in `tsBindingScopeFor`)
10
+ *
11
+ * `@type-binding.class-field` is emitted exclusively by
12
+ * `synthesizeConstructorFieldBindings` in `captures.ts`, which is a
13
+ * JavaScript-only synthesis pass. TypeScript uses
14
+ * `@type-binding.parameter-property` for constructor parameter
15
+ * properties instead. Keeping the JS-only rule in the JS hook file
16
+ * prevents language-specific logic from leaking into shared TypeScript
17
+ * infrastructure (DoD.md §2.2).
18
+ */
19
+ import { tsBindingScopeFor, walkToScope } from '../typescript/simple-hooks.js';
20
+ export { tsImportOwningScope as jsImportOwningScope, tsReceiverBinding as jsReceiverBinding, } from '../typescript/simple-hooks.js';
21
+ /**
22
+ * Like `tsBindingScopeFor` but additionally hoists
23
+ * `@type-binding.class-field` captures to the enclosing Class scope.
24
+ *
25
+ * `@type-binding.class-field` is anchored inside the constructor body
26
+ * (by `synthesizeConstructorFieldBindings`) so that `walkToScope` can
27
+ * walk up from the Function (constructor) scope to the Class scope.
28
+ * This puts `User.address → Address` in the class's typeBindings so
29
+ * compound-receiver resolution finds it when resolving
30
+ * `user.address.save()`.
31
+ */
32
+ export function jsBindingScopeFor(decl, innermost, tree) {
33
+ if (decl['@type-binding.class-field'] !== undefined) {
34
+ return walkToScope(innermost, tree, 'Class');
35
+ }
36
+ return tsBindingScopeFor(decl, innermost, tree);
37
+ }
@@ -26,6 +26,16 @@ import type { CaptureMatch, ParsedImport, Scope, ScopeId, ScopeTree, TypeRef } f
26
26
  * propagation.
27
27
  */
28
28
  export declare function tsBindingScopeFor(decl: CaptureMatch, innermost: Scope, tree: ScopeTree): ScopeId | null;
29
+ /**
30
+ * Walk up the scope chain to find the first scope whose `kind` matches
31
+ * any of `kinds`. Returns the matching scope's id or `null` when no
32
+ * ancestor matches (e.g., a return type binding emitted outside any
33
+ * Module scope — shouldn't happen in well-formed input).
34
+ *
35
+ * Exported so language-specific hook wrappers (e.g. `jsBindingScopeFor`)
36
+ * can reuse it without duplicating the traversal logic.
37
+ */
38
+ export declare function walkToScope(from: Scope, tree: ScopeTree, ...kinds: readonly Scope['kind'][]): ScopeId | null;
29
39
  /**
30
40
  * TypeScript imports are syntactically top-level: `import_statement` is
31
41
  * legal only inside `program` (the module root). `namespace X { … }`
@@ -56,8 +56,11 @@ export function tsBindingScopeFor(decl, innermost, tree) {
56
56
  * any of `kinds`. Returns the matching scope's id or `null` when no
57
57
  * ancestor matches (e.g., a return type binding emitted outside any
58
58
  * Module scope — shouldn't happen in well-formed input).
59
+ *
60
+ * Exported so language-specific hook wrappers (e.g. `jsBindingScopeFor`)
61
+ * can reuse it without duplicating the traversal logic.
59
62
  */
60
- function walkToScope(from, tree, ...kinds) {
63
+ export function walkToScope(from, tree, ...kinds) {
61
64
  let cur = from;
62
65
  const kindSet = new Set(kinds);
63
66
  while (cur !== undefined) {
@@ -27,6 +27,7 @@ import { createCallExtractor } from '../call-extractors/generic.js';
27
27
  import { typescriptCallConfig, javascriptCallConfig, } from '../call-extractors/configs/typescript-javascript.js';
28
28
  import { createHeritageExtractor } from '../heritage-extractors/generic.js';
29
29
  import { emitTsScopeCaptures, interpretTsImport, interpretTsTypeBinding, tsBindingScopeFor, tsImportOwningScope, tsReceiverBinding, typescriptMergeBindings, typescriptArityCompatibility, resolveTsImportTarget, } from './typescript/index.js';
30
+ import { emitJsScopeCaptures, interpretJsImport, interpretJsTypeBinding, jsBindingScopeFor, jsImportOwningScope, jsReceiverBinding, jsMergeBindings, jsArityCompatibility, } from './javascript/index.js';
30
31
  /**
31
32
  * TypeScript/JavaScript: arrow_function and function_expression are
32
33
  * anonymous AST nodes — they take their name from the surrounding
@@ -321,4 +322,18 @@ export const javascriptProvider = defineLanguage({
321
322
  classExtractor: createClassExtractor(javascriptClassConfig),
322
323
  heritageExtractor: createHeritageExtractor(SupportedLanguages.JavaScript),
323
324
  builtInNames: BUILT_INS,
325
+ // ── RFC #909 Ring 3: scope-based resolution hooks (RFC §5) ──────────
326
+ // JavaScript is the fourth migration after Python, C#, and TypeScript.
327
+ // Hooks are thin wrappers over the TypeScript implementations where
328
+ // semantics are identical; JS-specific additions (CJS require(),
329
+ // JSDoc type bindings) live in ./javascript/captures.ts.
330
+ // See ./javascript/index.ts for the full per-module rationale.
331
+ emitScopeCaptures: emitJsScopeCaptures,
332
+ interpretImport: interpretJsImport,
333
+ interpretTypeBinding: interpretJsTypeBinding,
334
+ bindingScopeFor: jsBindingScopeFor,
335
+ importOwningScope: jsImportOwningScope,
336
+ mergeBindings: (_scope, bindings) => jsMergeBindings(bindings),
337
+ receiverBinding: jsReceiverBinding,
338
+ arityCompatibility: jsArityCompatibility,
324
339
  });