gitnexus 1.6.0 → 1.6.2-rc.1

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 (145) hide show
  1. package/README.md +73 -0
  2. package/dist/cli/analyze.js +50 -3
  3. package/dist/core/group/extractors/fs-utils.d.ts +10 -0
  4. package/dist/core/group/extractors/fs-utils.js +24 -0
  5. package/dist/core/group/extractors/grpc-extractor.d.ts +17 -8
  6. package/dist/core/group/extractors/grpc-extractor.js +328 -191
  7. package/dist/core/group/extractors/grpc-patterns/go.d.ts +2 -0
  8. package/dist/core/group/extractors/grpc-patterns/go.js +97 -0
  9. package/dist/core/group/extractors/grpc-patterns/index.d.ts +19 -0
  10. package/dist/core/group/extractors/grpc-patterns/index.js +46 -0
  11. package/dist/core/group/extractors/grpc-patterns/java.d.ts +2 -0
  12. package/dist/core/group/extractors/grpc-patterns/java.js +173 -0
  13. package/dist/core/group/extractors/grpc-patterns/node.d.ts +4 -0
  14. package/dist/core/group/extractors/grpc-patterns/node.js +290 -0
  15. package/dist/core/group/extractors/grpc-patterns/proto.d.ts +9 -0
  16. package/dist/core/group/extractors/grpc-patterns/proto.js +134 -0
  17. package/dist/core/group/extractors/grpc-patterns/python.d.ts +2 -0
  18. package/dist/core/group/extractors/grpc-patterns/python.js +67 -0
  19. package/dist/core/group/extractors/grpc-patterns/types.d.ts +50 -0
  20. package/dist/core/group/extractors/grpc-patterns/types.js +1 -0
  21. package/dist/core/group/extractors/http-patterns/go.d.ts +2 -0
  22. package/dist/core/group/extractors/http-patterns/go.js +215 -0
  23. package/dist/core/group/extractors/http-patterns/index.d.ts +17 -0
  24. package/dist/core/group/extractors/http-patterns/index.js +44 -0
  25. package/dist/core/group/extractors/http-patterns/java.d.ts +2 -0
  26. package/dist/core/group/extractors/http-patterns/java.js +253 -0
  27. package/dist/core/group/extractors/http-patterns/node.d.ts +4 -0
  28. package/dist/core/group/extractors/http-patterns/node.js +354 -0
  29. package/dist/core/group/extractors/http-patterns/php.d.ts +2 -0
  30. package/dist/core/group/extractors/http-patterns/php.js +70 -0
  31. package/dist/core/group/extractors/http-patterns/python.d.ts +2 -0
  32. package/dist/core/group/extractors/http-patterns/python.js +133 -0
  33. package/dist/core/group/extractors/http-patterns/types.d.ts +61 -0
  34. package/dist/core/group/extractors/http-patterns/types.js +1 -0
  35. package/dist/core/group/extractors/http-route-extractor.d.ts +10 -13
  36. package/dist/core/group/extractors/http-route-extractor.js +231 -238
  37. package/dist/core/group/extractors/manifest-extractor.d.ts +54 -0
  38. package/dist/core/group/extractors/manifest-extractor.js +277 -0
  39. package/dist/core/group/extractors/topic-extractor.d.ts +0 -1
  40. package/dist/core/group/extractors/topic-extractor.js +55 -192
  41. package/dist/core/group/extractors/topic-patterns/go.d.ts +2 -0
  42. package/dist/core/group/extractors/topic-patterns/go.js +120 -0
  43. package/dist/core/group/extractors/topic-patterns/index.d.ts +14 -0
  44. package/dist/core/group/extractors/topic-patterns/index.js +38 -0
  45. package/dist/core/group/extractors/topic-patterns/java.d.ts +2 -0
  46. package/dist/core/group/extractors/topic-patterns/java.js +80 -0
  47. package/dist/core/group/extractors/topic-patterns/node.d.ts +4 -0
  48. package/dist/core/group/extractors/topic-patterns/node.js +155 -0
  49. package/dist/core/group/extractors/topic-patterns/python.d.ts +2 -0
  50. package/dist/core/group/extractors/topic-patterns/python.js +116 -0
  51. package/dist/core/group/extractors/topic-patterns/types.d.ts +25 -0
  52. package/dist/core/group/extractors/topic-patterns/types.js +10 -0
  53. package/dist/core/group/extractors/tree-sitter-scanner.d.ts +113 -0
  54. package/dist/core/group/extractors/tree-sitter-scanner.js +94 -0
  55. package/dist/core/ingestion/binding-accumulator.d.ts +22 -17
  56. package/dist/core/ingestion/binding-accumulator.js +29 -25
  57. package/dist/core/ingestion/cobol-processor.d.ts +1 -1
  58. package/dist/core/ingestion/import-processor.js +1 -1
  59. package/dist/core/ingestion/language-config.js +1 -1
  60. package/dist/core/ingestion/language-provider.d.ts +32 -5
  61. package/dist/core/ingestion/languages/c-cpp.js +2 -2
  62. package/dist/core/ingestion/languages/dart.d.ts +1 -1
  63. package/dist/core/ingestion/languages/dart.js +2 -2
  64. package/dist/core/ingestion/languages/go.d.ts +1 -1
  65. package/dist/core/ingestion/languages/go.js +2 -2
  66. package/dist/core/ingestion/languages/ruby.js +16 -1
  67. package/dist/core/ingestion/languages/swift.d.ts +1 -1
  68. package/dist/core/ingestion/languages/swift.js +2 -2
  69. package/dist/core/ingestion/markdown-processor.d.ts +1 -1
  70. package/dist/core/ingestion/method-extractors/configs/jvm.js +1 -0
  71. package/dist/core/ingestion/method-extractors/configs/ruby.js +1 -0
  72. package/dist/core/ingestion/method-extractors/generic.d.ts +6 -0
  73. package/dist/core/ingestion/method-extractors/generic.js +48 -4
  74. package/dist/core/ingestion/method-types.d.ts +4 -0
  75. package/dist/core/ingestion/model/resolve.js +103 -48
  76. package/dist/core/ingestion/model/semantic-model.d.ts +1 -1
  77. package/dist/core/ingestion/model/semantic-model.js +1 -1
  78. package/dist/core/ingestion/model/symbol-table.d.ts +7 -7
  79. package/dist/core/ingestion/model/symbol-table.js +7 -7
  80. package/dist/core/ingestion/mro-processor.d.ts +1 -1
  81. package/dist/core/ingestion/mro-processor.js +1 -1
  82. package/dist/core/ingestion/parsing-processor.js +54 -42
  83. package/dist/core/ingestion/pipeline-phases/cobol.d.ts +16 -0
  84. package/dist/core/ingestion/pipeline-phases/cobol.js +45 -0
  85. package/dist/core/ingestion/pipeline-phases/communities.d.ts +16 -0
  86. package/dist/core/ingestion/pipeline-phases/communities.js +62 -0
  87. package/dist/core/ingestion/pipeline-phases/cross-file-impl.d.ts +17 -0
  88. package/dist/core/ingestion/pipeline-phases/cross-file-impl.js +156 -0
  89. package/dist/core/ingestion/pipeline-phases/cross-file.d.ts +37 -0
  90. package/dist/core/ingestion/pipeline-phases/cross-file.js +63 -0
  91. package/dist/core/ingestion/pipeline-phases/index.d.ts +21 -0
  92. package/dist/core/ingestion/pipeline-phases/index.js +22 -0
  93. package/dist/core/ingestion/pipeline-phases/markdown.d.ts +17 -0
  94. package/dist/core/ingestion/pipeline-phases/markdown.js +33 -0
  95. package/dist/core/ingestion/pipeline-phases/mro.d.ts +18 -0
  96. package/dist/core/ingestion/pipeline-phases/mro.js +36 -0
  97. package/dist/core/ingestion/pipeline-phases/orm-extraction.d.ts +22 -0
  98. package/dist/core/ingestion/pipeline-phases/orm-extraction.js +92 -0
  99. package/dist/core/ingestion/pipeline-phases/orm.d.ts +15 -0
  100. package/dist/core/ingestion/pipeline-phases/orm.js +74 -0
  101. package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +47 -0
  102. package/dist/core/ingestion/pipeline-phases/parse-impl.js +437 -0
  103. package/dist/core/ingestion/pipeline-phases/parse.d.ts +49 -0
  104. package/dist/core/ingestion/pipeline-phases/parse.js +33 -0
  105. package/dist/core/ingestion/pipeline-phases/processes.d.ts +16 -0
  106. package/dist/core/ingestion/pipeline-phases/processes.js +143 -0
  107. package/dist/core/ingestion/pipeline-phases/routes.d.ts +21 -0
  108. package/dist/core/ingestion/pipeline-phases/routes.js +243 -0
  109. package/dist/core/ingestion/pipeline-phases/runner.d.ts +22 -0
  110. package/dist/core/ingestion/pipeline-phases/runner.js +203 -0
  111. package/dist/core/ingestion/pipeline-phases/scan.d.ts +21 -0
  112. package/dist/core/ingestion/pipeline-phases/scan.js +46 -0
  113. package/dist/core/ingestion/pipeline-phases/structure.d.ts +27 -0
  114. package/dist/core/ingestion/pipeline-phases/structure.js +35 -0
  115. package/dist/core/ingestion/pipeline-phases/tools.d.ts +20 -0
  116. package/dist/core/ingestion/pipeline-phases/tools.js +79 -0
  117. package/dist/core/ingestion/pipeline-phases/types.d.ts +79 -0
  118. package/dist/core/ingestion/pipeline-phases/types.js +37 -0
  119. package/dist/core/ingestion/pipeline-phases/wildcard-synthesis.d.ts +70 -0
  120. package/dist/core/ingestion/pipeline-phases/wildcard-synthesis.js +312 -0
  121. package/dist/core/ingestion/pipeline.d.ts +16 -10
  122. package/dist/core/ingestion/pipeline.js +66 -1534
  123. package/dist/core/ingestion/process-processor.js +1 -1
  124. package/dist/core/ingestion/tree-sitter-queries.d.ts +2 -2
  125. package/dist/core/ingestion/tree-sitter-queries.js +69 -0
  126. package/dist/core/ingestion/utils/ast-helpers.d.ts +1 -3
  127. package/dist/core/ingestion/utils/ast-helpers.js +48 -21
  128. package/dist/core/ingestion/utils/env.d.ts +10 -0
  129. package/dist/core/ingestion/utils/env.js +10 -0
  130. package/dist/core/ingestion/utils/graph-sort.d.ts +58 -0
  131. package/dist/core/ingestion/utils/graph-sort.js +100 -0
  132. package/dist/core/ingestion/workers/parse-worker.js +12 -8
  133. package/dist/core/lbug/lbug-adapter.d.ts +28 -0
  134. package/dist/core/lbug/lbug-adapter.js +162 -57
  135. package/package.json +3 -3
  136. package/vendor/tree-sitter-proto/binding.gyp +30 -0
  137. package/vendor/tree-sitter-proto/bindings/node/binding.cc +20 -0
  138. package/vendor/tree-sitter-proto/bindings/node/index.d.ts +28 -0
  139. package/vendor/tree-sitter-proto/bindings/node/index.js +7 -0
  140. package/vendor/tree-sitter-proto/package.json +18 -0
  141. package/vendor/tree-sitter-proto/src/node-types.json +1145 -0
  142. package/vendor/tree-sitter-proto/src/parser.c +10149 -0
  143. package/vendor/tree-sitter-proto/src/tree_sitter/alloc.h +54 -0
  144. package/vendor/tree-sitter-proto/src/tree_sitter/array.h +291 -0
  145. package/vendor/tree-sitter-proto/src/tree_sitter/parser.h +266 -0
@@ -0,0 +1,312 @@
1
+ /**
2
+ * Wildcard import binding synthesis.
3
+ *
4
+ * Languages with whole-module import semantics (Go, Ruby, C/C++, Swift)
5
+ * import all exported symbols from a file, not specific named symbols.
6
+ * After parsing, we know which symbols each file exports (via graph
7
+ * `isExported`), so we can expand IMPORTS edges into per-symbol bindings
8
+ * that the cross-file propagation phase can use for type resolution.
9
+ *
10
+ * Also builds Python module-alias maps for namespace-import languages
11
+ * (`import models` → `models.User()` resolves to `models.py:User`).
12
+ *
13
+ * @module
14
+ */
15
+ import { getLanguageFromFilename } from '../../../_shared/index.js';
16
+ import { providers, getProviderForFile } from '../languages/index.js';
17
+ // ── Constants ──────────────────────────────────────────────────────────────
18
+ /** Node labels that represent top-level importable symbols. */
19
+ const IMPORTABLE_SYMBOL_LABELS = new Set([
20
+ 'Function',
21
+ 'Class',
22
+ 'Interface',
23
+ 'Struct',
24
+ 'Enum',
25
+ 'Trait',
26
+ 'TypeAlias',
27
+ 'Const',
28
+ 'Static',
29
+ 'Record',
30
+ 'Union',
31
+ 'Typedef',
32
+ 'Macro',
33
+ ]);
34
+ /** Max synthetic bindings per importing file — prevents memory bloat
35
+ * for C/C++ files that include many large headers. */
36
+ const MAX_SYNTHETIC_BINDINGS_PER_FILE = 1000;
37
+ /** Max files allowed in a single transitive include closure. Guards against
38
+ * OOM on pathological C/C++ codebases (boost, Linux kernel-style monoheaders)
39
+ * where a single translation unit can transitively reach many thousands of
40
+ * headers. When the cap is hit, BFS expansion stops early — the file still
41
+ * synthesizes bindings from the partial closure rather than failing. */
42
+ const MAX_TRANSITIVE_CLOSURE_SIZE = 5000;
43
+ /** Import semantics tags whose languages need synthesis of whole-module imports.
44
+ * `wildcard-transitive` (C/C++) and `wildcard-leaf` (Go, Ruby, Swift, Dart) are
45
+ * the file-based wildcard strategies. `explicit-reexport` is a scaffold tag —
46
+ * no provider uses it yet, but it goes through the same leaf-style synthesis
47
+ * path today because a re-exporter is still an importer; only the extra DAG
48
+ * walk to surface re-exported symbols is missing (future work). */
49
+ const WILDCARD_SEMANTICS = new Set([
50
+ 'wildcard-transitive',
51
+ 'wildcard-leaf',
52
+ 'explicit-reexport',
53
+ ]);
54
+ /** Languages with whole-module import semantics (derived from providers at module load). */
55
+ const WILDCARD_LANGUAGES = new Set(Object.values(providers)
56
+ .filter((p) => WILDCARD_SEMANTICS.has(p.importSemantics))
57
+ .map((p) => p.id));
58
+ /** Languages that need binding synthesis before call resolution. */
59
+ const SYNTHESIS_LANGUAGES = new Set(Object.values(providers)
60
+ .filter((p) => p.importSemantics !== 'named')
61
+ .map((p) => p.id));
62
+ /** Check if a language uses wildcard (whole-module) import semantics. */
63
+ export function isWildcardImportLanguage(lang) {
64
+ return WILDCARD_LANGUAGES.has(lang);
65
+ }
66
+ /** Check if a language needs synthesis before call resolution.
67
+ * True for wildcard-import languages AND namespace-import languages (Python). */
68
+ export function needsSynthesis(lang) {
69
+ return SYNTHESIS_LANGUAGES.has(lang);
70
+ }
71
+ // ── Strategy implementations ───────────────────────────────────────────────
72
+ /**
73
+ * Strategy implementation for `importSemantics: 'wildcard-transitive'` (C, C++).
74
+ *
75
+ * Textual-include languages chain symbols through files: if `dict.c` includes
76
+ * `server.h` and `server.h` includes `dict.h`, then `dict.c` sees symbols from
77
+ * all three files. This helper walks the include graph (combining both the
78
+ * ingestion-context `importMap` and the graph-level IMPORTS edges) until the
79
+ * closure is stable.
80
+ *
81
+ * **Order matters.** The returned `Set` preserves iteration order (insertion
82
+ * order). `synthesizeWildcardImportBindings` dedupes bindings by symbol name
83
+ * on a first-seen-wins basis, so this closure's ordering determines which
84
+ * declaration wins when multiple headers export the same name (e.g. overloaded
85
+ * free functions like `write_audit()` vs `write_audit(const char*)` in
86
+ * different headers). We therefore:
87
+ * 1. Seed the closure with direct imports in declaration order (matches the
88
+ * order of `#include` directives in the source file).
89
+ * 2. Use FIFO / true BFS (`queue.shift()`) for transitive expansion, so
90
+ * closer headers are seen before deeper ones.
91
+ *
92
+ * Cycle-safe: the `closure.has(file)` guard prevents infinite loops on circular
93
+ * header includes, which are valid C/C++ when paired with `#pragma once` or
94
+ * include guards.
95
+ *
96
+ * Size-bounded: the closure is capped at `MAX_TRANSITIVE_CLOSURE_SIZE` files to
97
+ * prevent OOM on pathological codebases (e.g. boost, monoheader kernel code)
98
+ * where one translation unit can transitively reach tens of thousands of
99
+ * headers. Partial closures still yield useful bindings for the cluster of
100
+ * headers closest to the importer, which is what overload resolution and
101
+ * cross-file call resolution care about.
102
+ *
103
+ * Queue implementation: uses a head-index over a growing array (O(1) dequeue)
104
+ * instead of `Array.prototype.shift()` (O(n)) so deep chains stay linear.
105
+ */
106
+ export function expandTransitiveIncludeClosure(directImports, importMap, graphImports) {
107
+ const closure = new Set();
108
+ const queue = [];
109
+ let head = 0; // O(1) dequeue: advance the head index instead of shift()-ing.
110
+ const tryEnqueue = (file) => {
111
+ if (closure.has(file))
112
+ return true;
113
+ if (closure.size >= MAX_TRANSITIVE_CLOSURE_SIZE)
114
+ return false;
115
+ closure.add(file);
116
+ queue.push(file);
117
+ return true;
118
+ };
119
+ // Seed direct imports in declaration order (see JSDoc on order-sensitivity).
120
+ for (const f of directImports) {
121
+ if (!tryEnqueue(f))
122
+ break;
123
+ }
124
+ // True BFS for transitive reach: head-index FIFO preserves the "closer
125
+ // headers first" ordering that overload resolution depends on.
126
+ while (head < queue.length) {
127
+ if (closure.size >= MAX_TRANSITIVE_CLOSURE_SIZE)
128
+ break;
129
+ const file = queue[head++];
130
+ const nested = importMap.get(file);
131
+ if (nested) {
132
+ for (const n of nested) {
133
+ if (!tryEnqueue(n))
134
+ break;
135
+ }
136
+ }
137
+ const nestedGraph = graphImports.get(file);
138
+ if (nestedGraph) {
139
+ for (const n of nestedGraph) {
140
+ if (!tryEnqueue(n))
141
+ break;
142
+ }
143
+ }
144
+ }
145
+ return closure;
146
+ }
147
+ // ── Main synthesis function ────────────────────────────────────────────────
148
+ /**
149
+ * Synthesize namedImportMap entries for languages with whole-module imports.
150
+ *
151
+ * For each file that imports another file via wildcard semantics:
152
+ * 1. Look up all exported symbols from the imported file (via graph nodes)
153
+ * 2. Create synthetic named bindings: `{ name → { sourcePath, exportedName } }`
154
+ * 3. Build Python module-alias maps for namespace-import languages
155
+ *
156
+ * @param graph The knowledge graph with parsed symbol nodes
157
+ * @param ctx Resolution context with importMap and namedImportMap
158
+ * @returns Number of synthetic bindings created
159
+ */
160
+ export function synthesizeWildcardImportBindings(graph, ctx) {
161
+ // Build exported symbols index from graph nodes (single pass)
162
+ const exportedSymbolsByFile = new Map();
163
+ graph.forEachNode((node) => {
164
+ if (!node.properties?.isExported)
165
+ return;
166
+ if (!IMPORTABLE_SYMBOL_LABELS.has(node.label))
167
+ return;
168
+ const fp = node.properties.filePath;
169
+ const name = node.properties.name;
170
+ if (!fp || !name)
171
+ return;
172
+ let symbols = exportedSymbolsByFile.get(fp);
173
+ if (!symbols) {
174
+ symbols = [];
175
+ exportedSymbolsByFile.set(fp, symbols);
176
+ }
177
+ symbols.push({ name, filePath: fp });
178
+ });
179
+ if (exportedSymbolsByFile.size === 0)
180
+ return 0;
181
+ // Collect graph-level IMPORTS edges for wildcard languages missing from ctx.importMap
182
+ const FILE_PREFIX = 'File:';
183
+ const graphImports = new Map();
184
+ graph.forEachRelationship((rel) => {
185
+ if (rel.type !== 'IMPORTS')
186
+ return;
187
+ if (!rel.sourceId.startsWith(FILE_PREFIX) || !rel.targetId.startsWith(FILE_PREFIX))
188
+ return;
189
+ const srcFile = rel.sourceId.slice(FILE_PREFIX.length);
190
+ const tgtFile = rel.targetId.slice(FILE_PREFIX.length);
191
+ const lang = getLanguageFromFilename(srcFile);
192
+ if (!lang || !isWildcardImportLanguage(lang))
193
+ return;
194
+ if (ctx.importMap.get(srcFile)?.has(tgtFile))
195
+ return;
196
+ let set = graphImports.get(srcFile);
197
+ if (!set) {
198
+ set = new Set();
199
+ graphImports.set(srcFile, set);
200
+ }
201
+ set.add(tgtFile);
202
+ });
203
+ let totalSynthesized = 0;
204
+ const synthesizeForFile = (filePath, importedFiles) => {
205
+ let fileBindings = ctx.namedImportMap.get(filePath);
206
+ let fileCount = fileBindings?.size ?? 0;
207
+ for (const importedFile of importedFiles) {
208
+ const exportedSymbols = exportedSymbolsByFile.get(importedFile);
209
+ if (!exportedSymbols)
210
+ continue;
211
+ for (const sym of exportedSymbols) {
212
+ if (fileCount >= MAX_SYNTHETIC_BINDINGS_PER_FILE)
213
+ return;
214
+ if (fileBindings?.has(sym.name))
215
+ continue;
216
+ if (!fileBindings) {
217
+ fileBindings = new Map();
218
+ ctx.namedImportMap.set(filePath, fileBindings);
219
+ }
220
+ fileBindings.set(sym.name, {
221
+ sourcePath: importedFile,
222
+ exportedName: sym.name,
223
+ });
224
+ fileCount++;
225
+ totalSynthesized++;
226
+ }
227
+ }
228
+ };
229
+ /**
230
+ * Dispatch wildcard synthesis by the file's language provider strategy.
231
+ *
232
+ * Strategy tags (see `ImportSemantics`):
233
+ * - `wildcard-transitive`: expand the include closure first (C/C++ #include
234
+ * chains — e.g. `dict.c` → `server.h` → `dict.h` so `dictFind` resolves
235
+ * across header chains)
236
+ * - `wildcard-leaf`: synthesize from direct imports only (Go, Ruby, Swift, Dart)
237
+ * - `explicit-reexport`: scaffold tag; falls through to leaf behavior.
238
+ * TODO(#821): implement re-export DAG walk for TS `export *` / Rust
239
+ * `pub use`. The leaf fallthrough preserves today's TS/Rust behavior
240
+ * (their direct imports still synthesize correctly); only the extra
241
+ * re-export DAG walk for barrel-file correctness is missing.
242
+ * - `namespace` / `named`: no-op here (namespace handled in Loop 3 below,
243
+ * named needs no synthesis).
244
+ *
245
+ * Used by both Loop 1 (ctx.importMap) and Loop 2 (graphImports) so a future
246
+ * transitive-import language whose edges arrive via graphImports gets closure
247
+ * expansion consistently regardless of edge source.
248
+ */
249
+ const dispatchSynthesis = (filePath, importedFiles, provider) => {
250
+ switch (provider.importSemantics) {
251
+ case 'wildcard-transitive':
252
+ synthesizeForFile(filePath, expandTransitiveIncludeClosure(importedFiles, ctx.importMap, graphImports));
253
+ return;
254
+ case 'wildcard-leaf':
255
+ case 'explicit-reexport':
256
+ synthesizeForFile(filePath, importedFiles);
257
+ return;
258
+ case 'namespace':
259
+ case 'named':
260
+ return;
261
+ default: {
262
+ const _exhaustive = provider.importSemantics;
263
+ void _exhaustive;
264
+ }
265
+ }
266
+ };
267
+ // Loop 1: synthesize from ctx.importMap (Ruby, C/C++, Swift, Dart file-based imports).
268
+ for (const [filePath, importedFiles] of ctx.importMap) {
269
+ const lang = getLanguageFromFilename(filePath);
270
+ if (!lang || !isWildcardImportLanguage(lang))
271
+ continue;
272
+ const provider = getProviderForFile(filePath);
273
+ if (!provider)
274
+ continue;
275
+ dispatchSynthesis(filePath, importedFiles, provider);
276
+ }
277
+ // Loop 2: synthesize from graph IMPORTS edges (Go and other wildcard-import
278
+ // languages whose edges live in the graph rather than ctx.importMap).
279
+ for (const [filePath, importedFiles] of graphImports) {
280
+ const provider = getProviderForFile(filePath);
281
+ if (!provider)
282
+ continue;
283
+ dispatchSynthesis(filePath, importedFiles, provider);
284
+ }
285
+ // Build Python module-alias maps for namespace-import languages.
286
+ // `import models` in app.py → moduleAliasMap['app.py']['models'] = 'models.py'
287
+ // Enables `models.User()` to resolve without ambiguous symbol expansion.
288
+ for (const [filePath, importedFiles] of ctx.importMap) {
289
+ const provider = getProviderForFile(filePath);
290
+ if (!provider || provider.importSemantics !== 'namespace')
291
+ continue;
292
+ buildPythonModuleAliasForFile(ctx, filePath, importedFiles);
293
+ }
294
+ return totalSynthesized;
295
+ }
296
+ /** Build module alias entries for namespace-import files (e.g. Python). */
297
+ function buildPythonModuleAliasForFile(ctx, callerFile, importedFiles) {
298
+ let aliasMap = ctx.moduleAliasMap.get(callerFile);
299
+ for (const importedFile of importedFiles) {
300
+ const lastSlash = importedFile.lastIndexOf('/');
301
+ const base = lastSlash >= 0 ? importedFile.slice(lastSlash + 1) : importedFile;
302
+ const dot = base.lastIndexOf('.');
303
+ const stem = dot >= 0 ? base.slice(0, dot) : base;
304
+ if (!stem)
305
+ continue;
306
+ if (!aliasMap) {
307
+ aliasMap = new Map();
308
+ ctx.moduleAliasMap.set(callerFile, aliasMap);
309
+ }
310
+ aliasMap.set(stem, importedFile);
311
+ }
312
+ }
@@ -1,14 +1,21 @@
1
+ /**
2
+ * Pipeline orchestrator — dependency-ordered ingestion pipeline.
3
+ *
4
+ * The pipeline is composed of named phases with explicit dependencies.
5
+ * Each phase is defined in its own file under `pipeline-phases/`.
6
+ * The runner in `pipeline-phases/runner.ts` executes phases in
7
+ * topological order, passing typed outputs from upstream phases as
8
+ * inputs to downstream phases.
9
+ *
10
+ * To add a new phase:
11
+ * 1. Create a new file in `pipeline-phases/` following the pattern
12
+ * 2. Export it from `pipeline-phases/index.ts`
13
+ * 3. Add it to the `ALL_PHASES` array below
14
+ *
15
+ * See ARCHITECTURE.md for the full phase dependency diagram.
16
+ */
1
17
  import { type PipelineProgress } from '../../_shared/index.js';
2
18
  import { PipelineResult } from '../../types/pipeline.js';
3
- /** A group of files with no mutual dependencies, safe to process in parallel. */
4
- type IndependentFileGroup = readonly string[];
5
- /** Kahn's algorithm: returns files grouped by topological level.
6
- * Files in the same level have no mutual dependencies — safe to process in parallel.
7
- * Files in cycles are returned as a final group (no cross-cycle propagation). */
8
- export declare function topologicalLevelSort(importMap: ReadonlyMap<string, ReadonlySet<string>>): {
9
- levels: readonly IndependentFileGroup[];
10
- cycleCount: number;
11
- };
12
19
  export interface PipelineOptions {
13
20
  /** Skip MRO, community detection, and process extraction for faster test runs. */
14
21
  skipGraphPhases?: boolean;
@@ -16,4 +23,3 @@ export interface PipelineOptions {
16
23
  skipWorkers?: boolean;
17
24
  }
18
25
  export declare const runPipelineFromRepo: (repoPath: string, onProgress: (progress: PipelineProgress) => void, options?: PipelineOptions) => Promise<PipelineResult>;
19
- export {};