gitnexus 1.6.2-rc.2 → 1.6.2-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.
- package/dist/_shared/lbug/schema-constants.d.ts +1 -1
- package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
- package/dist/_shared/lbug/schema-constants.js +1 -0
- package/dist/_shared/lbug/schema-constants.js.map +1 -1
- package/dist/cli/analyze.js +3 -0
- package/dist/core/embeddings/ast-utils.d.ts +22 -0
- package/dist/core/embeddings/ast-utils.js +105 -0
- package/dist/core/embeddings/character-chunk.d.ts +12 -0
- package/dist/core/embeddings/character-chunk.js +43 -0
- package/dist/core/embeddings/chunker.d.ts +14 -0
- package/dist/core/embeddings/chunker.js +234 -0
- package/dist/core/embeddings/embedder.js +5 -0
- package/dist/core/embeddings/embedding-pipeline.d.ts +29 -24
- package/dist/core/embeddings/embedding-pipeline.js +244 -125
- package/dist/core/embeddings/line-index.d.ts +7 -0
- package/dist/core/embeddings/line-index.js +42 -0
- package/dist/core/embeddings/server-mapping.d.ts +15 -0
- package/dist/core/embeddings/server-mapping.js +33 -0
- package/dist/core/embeddings/structural-extractor.d.ts +15 -0
- package/dist/core/embeddings/structural-extractor.js +58 -0
- package/dist/core/embeddings/text-generator.d.ts +20 -13
- package/dist/core/embeddings/text-generator.js +151 -119
- package/dist/core/embeddings/types.d.ts +81 -3
- package/dist/core/embeddings/types.js +105 -3
- package/dist/core/group/extractors/http-patterns/node.js +130 -0
- package/dist/core/group/extractors/manifest-extractor.js +20 -5
- package/dist/core/group/sync.js +49 -1
- package/dist/core/ingestion/call-extractors/configs/c-cpp.d.ts +3 -0
- package/dist/core/ingestion/call-extractors/configs/c-cpp.js +8 -0
- package/dist/core/ingestion/call-extractors/configs/csharp.d.ts +2 -0
- package/dist/core/ingestion/call-extractors/configs/csharp.js +6 -0
- package/dist/core/ingestion/call-extractors/configs/dart.d.ts +2 -0
- package/dist/core/ingestion/call-extractors/configs/dart.js +5 -0
- package/dist/core/ingestion/call-extractors/configs/go.d.ts +2 -0
- package/dist/core/ingestion/call-extractors/configs/go.js +5 -0
- package/dist/core/ingestion/call-extractors/configs/jvm.d.ts +3 -0
- package/dist/core/ingestion/call-extractors/configs/jvm.js +51 -0
- package/dist/core/ingestion/call-extractors/configs/php.d.ts +2 -0
- package/dist/core/ingestion/call-extractors/configs/php.js +5 -0
- package/dist/core/ingestion/call-extractors/configs/python.d.ts +2 -0
- package/dist/core/ingestion/call-extractors/configs/python.js +5 -0
- package/dist/core/ingestion/call-extractors/configs/ruby.d.ts +2 -0
- package/dist/core/ingestion/call-extractors/configs/ruby.js +5 -0
- package/dist/core/ingestion/call-extractors/configs/rust.d.ts +2 -0
- package/dist/core/ingestion/call-extractors/configs/rust.js +5 -0
- package/dist/core/ingestion/call-extractors/configs/swift.d.ts +2 -0
- package/dist/core/ingestion/call-extractors/configs/swift.js +5 -0
- package/dist/core/ingestion/call-extractors/configs/typescript-javascript.d.ts +3 -0
- package/dist/core/ingestion/call-extractors/configs/typescript-javascript.js +8 -0
- package/dist/core/ingestion/call-extractors/generic.d.ts +5 -0
- package/dist/core/ingestion/call-extractors/generic.js +59 -0
- package/dist/core/ingestion/call-processor.d.ts +1 -3
- package/dist/core/ingestion/call-processor.js +49 -47
- package/dist/core/ingestion/call-types.d.ts +60 -0
- package/dist/core/ingestion/call-types.js +2 -0
- package/dist/core/ingestion/class-extractors/configs/c-cpp.d.ts +3 -0
- package/dist/core/ingestion/class-extractors/configs/c-cpp.js +11 -0
- package/dist/core/ingestion/class-extractors/configs/csharp.d.ts +2 -0
- package/dist/core/ingestion/class-extractors/configs/csharp.js +21 -0
- package/dist/core/ingestion/class-extractors/configs/dart.d.ts +2 -0
- package/dist/core/ingestion/class-extractors/configs/dart.js +7 -0
- package/dist/core/ingestion/class-extractors/configs/go.d.ts +2 -0
- package/dist/core/ingestion/class-extractors/configs/go.js +20 -0
- package/dist/core/ingestion/class-extractors/configs/jvm.d.ts +3 -0
- package/dist/core/ingestion/class-extractors/configs/jvm.js +35 -0
- package/dist/core/ingestion/class-extractors/configs/php.d.ts +2 -0
- package/dist/core/ingestion/class-extractors/configs/php.js +7 -0
- package/dist/core/ingestion/class-extractors/configs/python.d.ts +2 -0
- package/dist/core/ingestion/class-extractors/configs/python.js +7 -0
- package/dist/core/ingestion/class-extractors/configs/ruby.d.ts +2 -0
- package/dist/core/ingestion/class-extractors/configs/ruby.js +7 -0
- package/dist/core/ingestion/class-extractors/configs/rust.d.ts +2 -0
- package/dist/core/ingestion/class-extractors/configs/rust.js +7 -0
- package/dist/core/ingestion/class-extractors/configs/swift.d.ts +2 -0
- package/dist/core/ingestion/class-extractors/configs/swift.js +18 -0
- package/dist/core/ingestion/class-extractors/configs/typescript-javascript.d.ts +4 -0
- package/dist/core/ingestion/class-extractors/configs/typescript-javascript.js +28 -0
- package/dist/core/ingestion/field-types.d.ts +1 -1
- package/dist/core/ingestion/import-resolvers/configs/c-cpp.d.ts +7 -0
- package/dist/core/ingestion/import-resolvers/configs/c-cpp.js +14 -0
- package/dist/core/ingestion/import-resolvers/configs/csharp.d.ts +8 -0
- package/dist/core/ingestion/import-resolvers/configs/csharp.js +27 -0
- package/dist/core/ingestion/import-resolvers/configs/dart.d.ts +17 -0
- package/dist/core/ingestion/import-resolvers/{dart.js → configs/dart.js} +26 -16
- package/dist/core/ingestion/import-resolvers/configs/go.d.ts +8 -0
- package/dist/core/ingestion/import-resolvers/configs/go.js +26 -0
- package/dist/core/ingestion/import-resolvers/configs/jvm.d.ts +13 -0
- package/dist/core/ingestion/import-resolvers/configs/jvm.js +68 -0
- package/dist/core/ingestion/import-resolvers/configs/php.d.ts +8 -0
- package/dist/core/ingestion/import-resolvers/configs/php.js +15 -0
- package/dist/core/ingestion/import-resolvers/configs/python.d.ts +12 -0
- package/dist/core/ingestion/import-resolvers/configs/python.js +41 -0
- package/dist/core/ingestion/import-resolvers/configs/ruby.d.ts +8 -0
- package/dist/core/ingestion/import-resolvers/configs/ruby.js +16 -0
- package/dist/core/ingestion/import-resolvers/configs/rust.d.ts +8 -0
- package/dist/core/ingestion/import-resolvers/configs/rust.js +54 -0
- package/dist/core/ingestion/import-resolvers/configs/swift.d.ts +8 -0
- package/dist/core/ingestion/import-resolvers/{swift.js → configs/swift.js} +10 -5
- package/dist/core/ingestion/import-resolvers/configs/typescript-javascript.d.ts +9 -0
- package/dist/core/ingestion/import-resolvers/configs/typescript-javascript.js +23 -0
- package/dist/core/ingestion/import-resolvers/csharp.d.ts +4 -5
- package/dist/core/ingestion/import-resolvers/csharp.js +4 -20
- package/dist/core/ingestion/import-resolvers/go.d.ts +4 -5
- package/dist/core/ingestion/import-resolvers/go.js +4 -19
- package/dist/core/ingestion/import-resolvers/jvm.d.ts +5 -10
- package/dist/core/ingestion/import-resolvers/jvm.js +5 -58
- package/dist/core/ingestion/import-resolvers/php.d.ts +4 -5
- package/dist/core/ingestion/import-resolvers/php.js +4 -7
- package/dist/core/ingestion/import-resolvers/python.d.ts +3 -6
- package/dist/core/ingestion/import-resolvers/python.js +3 -18
- package/dist/core/ingestion/import-resolvers/resolver-factory.d.ts +24 -0
- package/dist/core/ingestion/import-resolvers/resolver-factory.js +33 -0
- package/dist/core/ingestion/import-resolvers/ruby.d.ts +4 -5
- package/dist/core/ingestion/import-resolvers/ruby.js +4 -7
- package/dist/core/ingestion/import-resolvers/rust.d.ts +4 -5
- package/dist/core/ingestion/import-resolvers/rust.js +4 -47
- package/dist/core/ingestion/import-resolvers/standard.d.ts +3 -9
- package/dist/core/ingestion/import-resolvers/standard.js +7 -8
- package/dist/core/ingestion/import-resolvers/types.d.ts +24 -0
- package/dist/core/ingestion/language-provider.d.ts +12 -0
- package/dist/core/ingestion/languages/c-cpp.js +15 -12
- package/dist/core/ingestion/languages/csharp.js +11 -21
- package/dist/core/ingestion/languages/dart.js +11 -7
- package/dist/core/ingestion/languages/go.js +11 -20
- package/dist/core/ingestion/languages/java.js +11 -18
- package/dist/core/ingestion/languages/kotlin.js +11 -13
- package/dist/core/ingestion/languages/php.js +11 -7
- package/dist/core/ingestion/languages/python.js +11 -7
- package/dist/core/ingestion/languages/ruby.js +11 -7
- package/dist/core/ingestion/languages/rust.js +11 -7
- package/dist/core/ingestion/languages/swift.js +11 -18
- package/dist/core/ingestion/languages/typescript.js +15 -23
- package/dist/core/ingestion/languages/vue.js +11 -17
- package/dist/core/ingestion/model/index.d.ts +2 -2
- package/dist/core/ingestion/model/index.js +1 -1
- package/dist/core/ingestion/model/resolve.d.ts +3 -0
- package/dist/core/ingestion/model/resolve.js +6 -2
- package/dist/core/ingestion/parsing-processor.d.ts +1 -2
- package/dist/core/ingestion/tree-sitter-queries.d.ts +11 -11
- package/dist/core/ingestion/tree-sitter-queries.js +81 -0
- package/dist/core/ingestion/type-env.d.ts +1 -1
- package/dist/core/ingestion/utils/ast-helpers.d.ts +1 -1
- package/dist/core/ingestion/utils/ast-helpers.js +3 -0
- package/dist/core/ingestion/variable-extractors/configs/c-cpp.d.ts +3 -0
- package/dist/core/ingestion/variable-extractors/configs/c-cpp.js +81 -0
- package/dist/core/ingestion/variable-extractors/configs/csharp.d.ts +9 -0
- package/dist/core/ingestion/variable-extractors/configs/csharp.js +63 -0
- package/dist/core/ingestion/variable-extractors/configs/dart.d.ts +2 -0
- package/dist/core/ingestion/variable-extractors/configs/dart.js +94 -0
- package/dist/core/ingestion/variable-extractors/configs/go.d.ts +2 -0
- package/dist/core/ingestion/variable-extractors/configs/go.js +83 -0
- package/dist/core/ingestion/variable-extractors/configs/jvm.d.ts +18 -0
- package/dist/core/ingestion/variable-extractors/configs/jvm.js +115 -0
- package/dist/core/ingestion/variable-extractors/configs/php.d.ts +14 -0
- package/dist/core/ingestion/variable-extractors/configs/php.js +58 -0
- package/dist/core/ingestion/variable-extractors/configs/python.d.ts +2 -0
- package/dist/core/ingestion/variable-extractors/configs/python.js +101 -0
- package/dist/core/ingestion/variable-extractors/configs/ruby.d.ts +11 -0
- package/dist/core/ingestion/variable-extractors/configs/ruby.js +52 -0
- package/dist/core/ingestion/variable-extractors/configs/rust.d.ts +2 -0
- package/dist/core/ingestion/variable-extractors/configs/rust.js +76 -0
- package/dist/core/ingestion/variable-extractors/configs/swift.d.ts +2 -0
- package/dist/core/ingestion/variable-extractors/configs/swift.js +88 -0
- package/dist/core/ingestion/variable-extractors/configs/typescript-javascript.d.ts +3 -0
- package/dist/core/ingestion/variable-extractors/configs/typescript-javascript.js +83 -0
- package/dist/core/ingestion/variable-extractors/generic.d.ts +5 -0
- package/dist/core/ingestion/variable-extractors/generic.js +80 -0
- package/dist/core/ingestion/variable-types.d.ts +82 -0
- package/dist/core/ingestion/variable-types.js +2 -0
- package/dist/core/ingestion/workers/parse-worker.js +196 -166
- package/dist/core/ingestion/workers/worker-pool.js +3 -0
- package/dist/core/lbug/csv-generator.js +1 -0
- package/dist/core/lbug/lbug-adapter.d.ts +13 -4
- package/dist/core/lbug/lbug-adapter.js +166 -81
- package/dist/core/lbug/schema.d.ts +9 -1
- package/dist/core/lbug/schema.js +19 -2
- package/dist/core/run-analyze.js +17 -4
- package/dist/core/tree-sitter/parser-loader.d.ts +3 -0
- package/dist/core/tree-sitter/parser-loader.js +17 -8
- package/dist/mcp/core/embedder.js +5 -0
- package/dist/mcp/local/local-backend.js +29 -19
- package/dist/server/api.js +10 -21
- package/package.json +5 -3
- package/scripts/build-tree-sitter-proto.cjs +82 -0
- package/vendor/node_modules/node-addon-api/node_addon_api.Makefile +6 -0
- package/vendor/node_modules/node-addon-api/node_addon_api.target.mk +104 -0
- package/vendor/node_modules/node-addon-api/node_addon_api_except.target.mk +108 -0
- package/vendor/node_modules/node-addon-api/node_addon_api_except_all.target.mk +104 -0
- package/vendor/node_modules/node-addon-api/node_addon_api_maybe.target.mk +104 -0
- package/vendor/tree-sitter-proto/package.json +1 -7
- package/dist/core/ingestion/call-sites/extract-language-call-site.d.ts +0 -10
- package/dist/core/ingestion/call-sites/extract-language-call-site.js +0 -22
- package/dist/core/ingestion/call-sites/java.d.ts +0 -9
- package/dist/core/ingestion/call-sites/java.js +0 -30
- package/dist/core/ingestion/import-resolvers/dart.d.ts +0 -7
- package/dist/core/ingestion/import-resolvers/swift.d.ts +0 -7
- package/dist/core/ingestion/import-resolvers/vue.d.ts +0 -8
- package/dist/core/ingestion/import-resolvers/vue.js +0 -9
|
@@ -7,6 +7,9 @@ import { compilePatterns, runCompiledPatterns, unquoteLiteral, } from '../tree-s
|
|
|
7
7
|
* - Express `router.get(...)` / `app.post(...)` providers
|
|
8
8
|
* - `fetch(url)` / `fetch(url, { method: 'POST' })` consumers
|
|
9
9
|
* - `axios.get(url)` / `axios.delete(url)` consumers
|
|
10
|
+
* - `axios({ method, url })` object-form consumers
|
|
11
|
+
* - jQuery `$.get(url)` / `$.post(url, ...)` shorthand consumers
|
|
12
|
+
* - jQuery `$.ajax({ url, method | type })` consumers
|
|
10
13
|
*
|
|
11
14
|
* Because the JavaScript and TypeScript tree-sitter grammars share
|
|
12
15
|
* node type names for every construct we query, pattern sources are
|
|
@@ -86,6 +89,45 @@ const AXIOS_SPEC = {
|
|
|
86
89
|
arguments: (arguments . [(string) (template_string)] @path))
|
|
87
90
|
`,
|
|
88
91
|
};
|
|
92
|
+
// ─── Consumer: jQuery shorthand $.get(url) / $.post(url, ...) ────────
|
|
93
|
+
// `$` is a valid JS identifier, so tree-sitter parses `$.get(...)` as a
|
|
94
|
+
// call_expression whose function is a member_expression on identifier `$`.
|
|
95
|
+
const JQUERY_SHORTHAND_SPEC = {
|
|
96
|
+
meta: {},
|
|
97
|
+
query: `
|
|
98
|
+
(call_expression
|
|
99
|
+
function: (member_expression
|
|
100
|
+
object: (identifier) @obj (#eq? @obj "$")
|
|
101
|
+
property: (property_identifier) @http_method (#match? @http_method "^(get|post)$"))
|
|
102
|
+
arguments: (arguments . [(string) (template_string)] @path))
|
|
103
|
+
`,
|
|
104
|
+
};
|
|
105
|
+
// ─── Consumer: jQuery $.ajax({ url, method|type }) ───────────────────
|
|
106
|
+
// The query captures the options object only; key/value pairs are read
|
|
107
|
+
// programmatically via `readStringProp` below, which tolerates any key
|
|
108
|
+
// order and accepts either `method:` or `type:` (jQuery supports both).
|
|
109
|
+
const JQUERY_AJAX_SPEC = {
|
|
110
|
+
meta: {},
|
|
111
|
+
query: `
|
|
112
|
+
(call_expression
|
|
113
|
+
function: (member_expression
|
|
114
|
+
object: (identifier) @obj (#eq? @obj "$")
|
|
115
|
+
property: (property_identifier) @fn (#eq? @fn "ajax"))
|
|
116
|
+
arguments: (arguments (object) @options))
|
|
117
|
+
`,
|
|
118
|
+
};
|
|
119
|
+
// ─── Consumer: axios({ method, url }) object form ────────────────────
|
|
120
|
+
// Distinct from AXIOS_SPEC above because the call target is an identifier
|
|
121
|
+
// (`axios`) rather than a member expression (`axios.get`). As with the
|
|
122
|
+
// jQuery ajax form, option keys are resolved programmatically.
|
|
123
|
+
const AXIOS_OBJECT_SPEC = {
|
|
124
|
+
meta: {},
|
|
125
|
+
query: `
|
|
126
|
+
(call_expression
|
|
127
|
+
function: (identifier) @fn (#eq? @fn "axios")
|
|
128
|
+
arguments: (arguments (object) @options))
|
|
129
|
+
`,
|
|
130
|
+
};
|
|
89
131
|
function compileBundle(language, name) {
|
|
90
132
|
const mk = (spec, suffix) => compilePatterns({
|
|
91
133
|
name: `${name}-${suffix}`,
|
|
@@ -99,6 +141,9 @@ function compileBundle(language, name) {
|
|
|
99
141
|
fetchNoOptions: mk(FETCH_NO_OPTIONS_SPEC, 'fetch-no-options'),
|
|
100
142
|
fetchWithOptions: mk(FETCH_WITH_OPTIONS_SPEC, 'fetch-with-options'),
|
|
101
143
|
axios: mk(AXIOS_SPEC, 'axios'),
|
|
144
|
+
jqueryShorthand: mk(JQUERY_SHORTHAND_SPEC, 'jquery-shorthand'),
|
|
145
|
+
jqueryAjax: mk(JQUERY_AJAX_SPEC, 'jquery-ajax'),
|
|
146
|
+
axiosObject: mk(AXIOS_OBJECT_SPEC, 'axios-object'),
|
|
102
147
|
};
|
|
103
148
|
}
|
|
104
149
|
const JAVASCRIPT_BUNDLE = compileBundle(JavaScript, 'javascript-http');
|
|
@@ -130,6 +175,32 @@ function joinPath(prefix, sub) {
|
|
|
130
175
|
return `/${cleanSub}`;
|
|
131
176
|
return `/${cleanPrefix}/${cleanSub}`;
|
|
132
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* Walk `pair` children of an `object` literal and return the unquoted
|
|
180
|
+
* string/template_string value for the first pair whose key matches one
|
|
181
|
+
* of `keyNames`. Returns null when no matching pair is present or the
|
|
182
|
+
* value is not a string literal. Used by the jQuery ajax / axios object
|
|
183
|
+
* consumers to resolve `url` / `method` / `type` keys in any order.
|
|
184
|
+
*/
|
|
185
|
+
function readStringProp(objectNode, keyNames) {
|
|
186
|
+
for (let i = 0; i < objectNode.namedChildCount; i++) {
|
|
187
|
+
const pair = objectNode.namedChild(i);
|
|
188
|
+
if (!pair || pair.type !== 'pair')
|
|
189
|
+
continue;
|
|
190
|
+
const keyNode = pair.childForFieldName('key');
|
|
191
|
+
const valueNode = pair.childForFieldName('value');
|
|
192
|
+
if (!keyNode || !valueNode)
|
|
193
|
+
continue;
|
|
194
|
+
if (!keyNames.includes(keyNode.text))
|
|
195
|
+
continue;
|
|
196
|
+
if (valueNode.type !== 'string' && valueNode.type !== 'template_string')
|
|
197
|
+
continue;
|
|
198
|
+
const lit = unquoteLiteral(valueNode.text);
|
|
199
|
+
if (lit !== null)
|
|
200
|
+
return lit;
|
|
201
|
+
}
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
133
204
|
/**
|
|
134
205
|
* For a standalone `decorator` node (child of class_body / program),
|
|
135
206
|
* find the related `class_declaration` node that it decorates. In
|
|
@@ -335,6 +406,65 @@ function scanBundle(bundle, tree) {
|
|
|
335
406
|
confidence: 0.7,
|
|
336
407
|
});
|
|
337
408
|
}
|
|
409
|
+
// Consumer: jQuery shorthand $.get(url) / $.post(url, ...)
|
|
410
|
+
for (const match of runCompiledPatterns(bundle.jqueryShorthand, tree)) {
|
|
411
|
+
const methodNode = match.captures.http_method;
|
|
412
|
+
const pathNode = match.captures.path;
|
|
413
|
+
if (!methodNode || !pathNode)
|
|
414
|
+
continue;
|
|
415
|
+
const path = unquoteLiteral(pathNode.text);
|
|
416
|
+
if (path === null)
|
|
417
|
+
continue;
|
|
418
|
+
out.push({
|
|
419
|
+
role: 'consumer',
|
|
420
|
+
framework: 'jquery',
|
|
421
|
+
method: methodNode.text.toUpperCase(),
|
|
422
|
+
path,
|
|
423
|
+
name: null,
|
|
424
|
+
confidence: 0.7,
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
// Consumer: jQuery $.ajax({ url, method|type }). jQuery accepts either
|
|
428
|
+
// `method:` or `type:`; both default to GET when absent.
|
|
429
|
+
for (const match of runCompiledPatterns(bundle.jqueryAjax, tree)) {
|
|
430
|
+
const optionsNode = match.captures.options;
|
|
431
|
+
if (!optionsNode)
|
|
432
|
+
continue;
|
|
433
|
+
const path = readStringProp(optionsNode, ['url']);
|
|
434
|
+
if (path === null)
|
|
435
|
+
continue;
|
|
436
|
+
const rawMethod = readStringProp(optionsNode, ['method', 'type']);
|
|
437
|
+
const method = (rawMethod ?? 'GET').toUpperCase();
|
|
438
|
+
out.push({
|
|
439
|
+
role: 'consumer',
|
|
440
|
+
framework: 'jquery',
|
|
441
|
+
method,
|
|
442
|
+
path,
|
|
443
|
+
name: null,
|
|
444
|
+
confidence: 0.7,
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
// Consumer: axios({ method, url }) object form. Structurally distinct
|
|
448
|
+
// from axios.<verb>(url) (identifier vs member_expression call), so no
|
|
449
|
+
// dedup against the member-form loop above is required.
|
|
450
|
+
for (const match of runCompiledPatterns(bundle.axiosObject, tree)) {
|
|
451
|
+
const optionsNode = match.captures.options;
|
|
452
|
+
if (!optionsNode)
|
|
453
|
+
continue;
|
|
454
|
+
const path = readStringProp(optionsNode, ['url']);
|
|
455
|
+
if (path === null)
|
|
456
|
+
continue;
|
|
457
|
+
const rawMethod = readStringProp(optionsNode, ['method']);
|
|
458
|
+
const method = (rawMethod ?? 'GET').toUpperCase();
|
|
459
|
+
out.push({
|
|
460
|
+
role: 'consumer',
|
|
461
|
+
framework: 'axios',
|
|
462
|
+
method,
|
|
463
|
+
path,
|
|
464
|
+
name: null,
|
|
465
|
+
confidence: 0.7,
|
|
466
|
+
});
|
|
467
|
+
}
|
|
338
468
|
return out;
|
|
339
469
|
}
|
|
340
470
|
export const JAVASCRIPT_HTTP_PLUGIN = {
|
|
@@ -68,14 +68,29 @@ export function manifestSymbolUid(repo, contractId) {
|
|
|
68
68
|
}
|
|
69
69
|
export class ManifestExtractor {
|
|
70
70
|
async extractFromManifest(links, dbExecutors) {
|
|
71
|
-
const
|
|
72
|
-
const
|
|
73
|
-
|
|
71
|
+
const resolveCache = new Map();
|
|
72
|
+
const resolveOnce = (repo, link) => {
|
|
73
|
+
const key = `${repo}\u0000${link.type}\u0000${link.contract}`;
|
|
74
|
+
let pending = resolveCache.get(key);
|
|
75
|
+
if (!pending) {
|
|
76
|
+
pending = this.resolveSymbol(repo, link, dbExecutors);
|
|
77
|
+
resolveCache.set(key, pending);
|
|
78
|
+
}
|
|
79
|
+
return pending;
|
|
80
|
+
};
|
|
81
|
+
const perLink = await Promise.all(links.map(async (link) => {
|
|
74
82
|
const contractId = this.buildContractId(link.type, link.contract);
|
|
75
83
|
const providerRepo = link.role === 'provider' ? link.from : link.to;
|
|
76
84
|
const consumerRepo = link.role === 'provider' ? link.to : link.from;
|
|
77
|
-
const providerSymbol = await
|
|
78
|
-
|
|
85
|
+
const [providerSymbol, consumerSymbol] = await Promise.all([
|
|
86
|
+
resolveOnce(providerRepo, link),
|
|
87
|
+
resolveOnce(consumerRepo, link),
|
|
88
|
+
]);
|
|
89
|
+
return { link, contractId, providerRepo, consumerRepo, providerSymbol, consumerSymbol };
|
|
90
|
+
}));
|
|
91
|
+
const contracts = [];
|
|
92
|
+
const crossLinks = [];
|
|
93
|
+
for (const { link, contractId, providerRepo, consumerRepo, providerSymbol, consumerSymbol, } of perLink) {
|
|
79
94
|
const providerRef = providerSymbol || { filePath: '', name: link.contract };
|
|
80
95
|
const consumerRef = consumerSymbol || { filePath: '', name: link.contract };
|
|
81
96
|
// When the resolver finds a real graph symbol we keep its uid, otherwise
|
package/dist/core/group/sync.js
CHANGED
|
@@ -6,6 +6,7 @@ import { readRegistry } from '../../storage/repo-manager.js';
|
|
|
6
6
|
import { HttpRouteExtractor } from './extractors/http-route-extractor.js';
|
|
7
7
|
import { GrpcExtractor } from './extractors/grpc-extractor.js';
|
|
8
8
|
import { TopicExtractor } from './extractors/topic-extractor.js';
|
|
9
|
+
import { ManifestExtractor } from './extractors/manifest-extractor.js';
|
|
9
10
|
import { runExactMatch } from './matching.js';
|
|
10
11
|
import { detectServiceBoundaries, assignService } from './service-boundary-detector.js';
|
|
11
12
|
import { writeContractRegistry } from './storage.js';
|
|
@@ -34,10 +35,28 @@ function defaultResolveHandle(allEntries) {
|
|
|
34
35
|
};
|
|
35
36
|
};
|
|
36
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Dedupe cross-links that point from the same consumer endpoint to the same
|
|
40
|
+
* provider endpoint for the same contract. Preserves first-seen order so the
|
|
41
|
+
* caller controls precedence (e.g., pass manifest links first).
|
|
42
|
+
*/
|
|
43
|
+
function dedupeCrossLinks(links) {
|
|
44
|
+
const seen = new Set();
|
|
45
|
+
const out = [];
|
|
46
|
+
for (const link of links) {
|
|
47
|
+
const key = `${link.from.repo}::${link.from.symbolUid}|${link.to.repo}::${link.to.symbolUid}|${link.type}|${link.contractId}`;
|
|
48
|
+
if (seen.has(key))
|
|
49
|
+
continue;
|
|
50
|
+
seen.add(key);
|
|
51
|
+
out.push(link);
|
|
52
|
+
}
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
37
55
|
export async function syncGroup(config, opts) {
|
|
38
56
|
const missingRepos = [];
|
|
39
57
|
const repoSnapshots = {};
|
|
40
58
|
let autoContracts = [];
|
|
59
|
+
let manifestCrossLinks = [];
|
|
41
60
|
let dbExecutors;
|
|
42
61
|
const eo = opts?.extractorOverride;
|
|
43
62
|
if (eo && eo.length === 0) {
|
|
@@ -124,8 +143,37 @@ export async function syncGroup(config, opts) {
|
|
|
124
143
|
}
|
|
125
144
|
}
|
|
126
145
|
}
|
|
146
|
+
// Process manifest links declared in group.yaml.
|
|
147
|
+
// ManifestExtractor is fully implemented but was never wired into this
|
|
148
|
+
// pipeline — config.links were parsed and validated but silently dropped.
|
|
149
|
+
// Placed after the DB try/finally: resolveSymbol falls back to synthetic
|
|
150
|
+
// UIDs when dbExecutors is undefined or a pool is closed, so cross-links
|
|
151
|
+
// are always generated regardless of whether real DB executors are available.
|
|
152
|
+
if (config.links.length > 0) {
|
|
153
|
+
// Warn about dangling links that reference repos not declared in config.repos.
|
|
154
|
+
// They still generate cross-links via synthetic UIDs (determinism is preserved),
|
|
155
|
+
// but the operator probably meant something that now silently does nothing useful.
|
|
156
|
+
const knownRepos = new Set(Object.keys(config.repos));
|
|
157
|
+
for (const link of config.links) {
|
|
158
|
+
const dangling = [link.from, link.to].filter((r) => !knownRepos.has(r));
|
|
159
|
+
if (dangling.length > 0) {
|
|
160
|
+
console.warn(`[group/sync] manifest link ${link.type}:${link.contract} references repos not in config.repos: ${dangling.join(', ')} — cross-links will use synthetic UIDs`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
const manifestEx = new ManifestExtractor();
|
|
164
|
+
const manifestResult = await manifestEx.extractFromManifest(config.links, dbExecutors);
|
|
165
|
+
autoContracts.push(...manifestResult.contracts);
|
|
166
|
+
manifestCrossLinks = manifestResult.crossLinks;
|
|
167
|
+
if (opts?.verbose) {
|
|
168
|
+
console.log(` manifest: ${manifestCrossLinks.length} cross-links from ${config.links.length} declared links`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
127
171
|
const { matched, unmatched } = runExactMatch(autoContracts);
|
|
128
|
-
|
|
172
|
+
// Dedupe cross-links. Manifest contracts participate in runExactMatch, so a
|
|
173
|
+
// manifest-declared link can also emit a matchType:'exact' CrossLink with the
|
|
174
|
+
// same endpoints. Prefer the manifest version — it reflects operator intent
|
|
175
|
+
// and carries matchType:'manifest' which downstream consumers may rely on.
|
|
176
|
+
const crossLinks = dedupeCrossLinks([...manifestCrossLinks, ...matched]);
|
|
129
177
|
const allContracts = autoContracts;
|
|
130
178
|
const registry = {
|
|
131
179
|
version: 1,
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// gitnexus/src/core/ingestion/call-extractors/configs/c-cpp.ts
|
|
2
|
+
import { SupportedLanguages } from '../../../../_shared/index.js';
|
|
3
|
+
export const cCallConfig = {
|
|
4
|
+
language: SupportedLanguages.C,
|
|
5
|
+
};
|
|
6
|
+
export const cppCallConfig = {
|
|
7
|
+
language: SupportedLanguages.CPlusPlus,
|
|
8
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// gitnexus/src/core/ingestion/call-extractors/configs/jvm.ts
|
|
2
|
+
import { SupportedLanguages } from '../../../../_shared/index.js';
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Java method_reference (::) parsing — absorbs call-sites/java.ts
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
/**
|
|
7
|
+
* Parse Java `method_reference` nodes (`expr::method`, `Type::new`,
|
|
8
|
+
* `this::m`, `super::m`).
|
|
9
|
+
*/
|
|
10
|
+
function parseJavaMethodReference(callNode) {
|
|
11
|
+
if (callNode.type !== 'method_reference')
|
|
12
|
+
return null;
|
|
13
|
+
const recv = callNode.namedChild(0);
|
|
14
|
+
if (!recv)
|
|
15
|
+
return null;
|
|
16
|
+
// Type::new → constructor call
|
|
17
|
+
for (const c of callNode.children) {
|
|
18
|
+
if (c.type === 'new') {
|
|
19
|
+
if (recv.type !== 'identifier')
|
|
20
|
+
return null;
|
|
21
|
+
return { calledName: recv.text, callForm: 'constructor' };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// expr::method → member call with receiver
|
|
25
|
+
const rhs = callNode.child(callNode.childCount - 1);
|
|
26
|
+
if (!rhs || rhs.type !== 'identifier')
|
|
27
|
+
return null;
|
|
28
|
+
const methodName = rhs.text;
|
|
29
|
+
if (recv.type === 'identifier') {
|
|
30
|
+
return { calledName: methodName, callForm: 'member', receiverName: recv.text };
|
|
31
|
+
}
|
|
32
|
+
if (recv.type === 'this') {
|
|
33
|
+
return { calledName: methodName, callForm: 'member', receiverName: 'this' };
|
|
34
|
+
}
|
|
35
|
+
if (recv.type === 'super') {
|
|
36
|
+
return { calledName: methodName, callForm: 'member', receiverName: 'super' };
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// Configs
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
export const javaCallConfig = {
|
|
44
|
+
language: SupportedLanguages.Java,
|
|
45
|
+
extractLanguageCallSite: parseJavaMethodReference,
|
|
46
|
+
typeAsReceiverHeuristic: true,
|
|
47
|
+
};
|
|
48
|
+
export const kotlinCallConfig = {
|
|
49
|
+
language: SupportedLanguages.Kotlin,
|
|
50
|
+
typeAsReceiverHeuristic: true,
|
|
51
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// gitnexus/src/core/ingestion/call-extractors/configs/typescript-javascript.ts
|
|
2
|
+
import { SupportedLanguages } from '../../../../_shared/index.js';
|
|
3
|
+
export const typescriptCallConfig = {
|
|
4
|
+
language: SupportedLanguages.TypeScript,
|
|
5
|
+
};
|
|
6
|
+
export const javascriptCallConfig = {
|
|
7
|
+
language: SupportedLanguages.JavaScript,
|
|
8
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// gitnexus/src/core/ingestion/call-extractors/generic.ts
|
|
2
|
+
import { inferCallForm, extractReceiverName, extractReceiverNode, extractMixedChain, countCallArguments, } from '../utils/call-analysis.js';
|
|
3
|
+
/**
|
|
4
|
+
* Create a CallExtractor from a declarative config.
|
|
5
|
+
*/
|
|
6
|
+
export function createCallExtractor(config) {
|
|
7
|
+
return {
|
|
8
|
+
language: config.language,
|
|
9
|
+
extract(callNode, callNameNode) {
|
|
10
|
+
// ── Path 1: Language-specific call site ──────────────────────────
|
|
11
|
+
// Non-standard call shapes (e.g. Java `::` method references) are
|
|
12
|
+
// handled entirely by the config hook. When it returns a result,
|
|
13
|
+
// the generic path is skipped — no argCount, no mixed chain.
|
|
14
|
+
//
|
|
15
|
+
// Note: `extractLanguageCallSite` is called on every `extract()`
|
|
16
|
+
// invocation — both `extract(callNode, undefined)` (parse-worker
|
|
17
|
+
// Path 1) and `extract(callNode, callNameNode)` (Path 2).
|
|
18
|
+
// Language hooks must therefore be idempotent and cheap (e.g. a
|
|
19
|
+
// single node-type check).
|
|
20
|
+
if (config.extractLanguageCallSite) {
|
|
21
|
+
const seed = config.extractLanguageCallSite(callNode);
|
|
22
|
+
if (seed) {
|
|
23
|
+
return {
|
|
24
|
+
...seed,
|
|
25
|
+
...(config.typeAsReceiverHeuristic ? { typeAsReceiverHeuristic: true } : {}),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// ── Path 2: Generic extraction via @call.name ────────────────────
|
|
30
|
+
if (!callNameNode)
|
|
31
|
+
return null;
|
|
32
|
+
const calledName = callNameNode.text;
|
|
33
|
+
const callForm = inferCallForm(callNode, callNameNode);
|
|
34
|
+
let receiverName = callForm === 'member' ? extractReceiverName(callNameNode) : undefined;
|
|
35
|
+
let receiverMixedChain;
|
|
36
|
+
// When the receiver is a complex expression (call chain, field chain,
|
|
37
|
+
// or mixed), extractReceiverName returns undefined. Walk the receiver
|
|
38
|
+
// node to build a unified mixed chain for deferred resolution.
|
|
39
|
+
if (callForm === 'member' && receiverName === undefined) {
|
|
40
|
+
const receiverNode = extractReceiverNode(callNameNode);
|
|
41
|
+
if (receiverNode) {
|
|
42
|
+
const extracted = extractMixedChain(receiverNode);
|
|
43
|
+
if (extracted && extracted.chain.length > 0) {
|
|
44
|
+
receiverMixedChain = extracted.chain;
|
|
45
|
+
receiverName = extracted.baseReceiverName;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
calledName,
|
|
51
|
+
...(callForm !== undefined ? { callForm } : {}),
|
|
52
|
+
...(receiverName !== undefined ? { receiverName } : {}),
|
|
53
|
+
argCount: countCallArguments(callNode),
|
|
54
|
+
...(receiverMixedChain !== undefined ? { receiverMixedChain } : {}),
|
|
55
|
+
...(config.typeAsReceiverHeuristic ? { typeAsReceiverHeuristic: true } : {}),
|
|
56
|
+
};
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { KnowledgeGraph } from '../graph/types.js';
|
|
2
2
|
import { ASTCache } from './ast-cache.js';
|
|
3
|
-
import type { SymbolDefinition, SymbolTableReader } from './model/
|
|
3
|
+
import type { SymbolDefinition, SymbolTableReader, HeritageMap, ExtractedHeritage } from './model/index.js';
|
|
4
4
|
import type { ResolutionContext } from './model/resolution-context.js';
|
|
5
5
|
import type { TieredCandidates } from './model/resolution-context.js';
|
|
6
6
|
import type { TypeEnvironment } from './type-env.js';
|
|
7
|
-
import type { HeritageMap } from './model/heritage-map.js';
|
|
8
7
|
import type { BindingAccumulator } from './binding-accumulator.js';
|
|
9
8
|
import type { ExtractedCall, ExtractedAssignment, ExtractedRoute, ExtractedFetchCall, FileConstructorBindings } from './workers/parse-worker.js';
|
|
10
|
-
import type { ExtractedHeritage } from './model/heritage-map.js';
|
|
11
9
|
import type { LiteralTypeInferrer } from './type-extractors/types.js';
|
|
12
10
|
import type { SyntaxNode } from './utils/ast-helpers.js';
|
|
13
11
|
/** Per-file resolved type bindings for exported symbols.
|