@zuvia-software-solutions/code-mapper 1.4.0 → 2.0.0

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 (137) hide show
  1. package/dist/cli/ai-context.js +1 -1
  2. package/dist/cli/analyze.d.ts +1 -0
  3. package/dist/cli/analyze.js +73 -82
  4. package/dist/cli/augment.js +0 -2
  5. package/dist/cli/eval-server.d.ts +2 -2
  6. package/dist/cli/eval-server.js +6 -6
  7. package/dist/cli/index.js +6 -10
  8. package/dist/cli/mcp.d.ts +1 -3
  9. package/dist/cli/mcp.js +3 -3
  10. package/dist/cli/refresh.d.ts +2 -2
  11. package/dist/cli/refresh.js +24 -29
  12. package/dist/cli/status.js +4 -13
  13. package/dist/cli/tool.d.ts +5 -4
  14. package/dist/cli/tool.js +8 -10
  15. package/dist/config/ignore-service.js +14 -34
  16. package/dist/core/augmentation/engine.js +53 -83
  17. package/dist/core/db/adapter.d.ts +99 -0
  18. package/dist/core/db/adapter.js +402 -0
  19. package/dist/core/db/graph-loader.d.ts +27 -0
  20. package/dist/core/db/graph-loader.js +148 -0
  21. package/dist/core/db/queries.d.ts +160 -0
  22. package/dist/core/db/queries.js +441 -0
  23. package/dist/core/db/schema.d.ts +108 -0
  24. package/dist/core/db/schema.js +136 -0
  25. package/dist/core/embeddings/embedder.d.ts +21 -12
  26. package/dist/core/embeddings/embedder.js +104 -50
  27. package/dist/core/embeddings/embedding-pipeline.d.ts +48 -22
  28. package/dist/core/embeddings/embedding-pipeline.js +220 -262
  29. package/dist/core/embeddings/text-generator.js +4 -19
  30. package/dist/core/embeddings/types.d.ts +1 -1
  31. package/dist/core/graph/graph.d.ts +1 -1
  32. package/dist/core/graph/graph.js +1 -0
  33. package/dist/core/graph/types.d.ts +11 -9
  34. package/dist/core/graph/types.js +4 -1
  35. package/dist/core/incremental/refresh.d.ts +46 -0
  36. package/dist/core/incremental/refresh.js +464 -0
  37. package/dist/core/incremental/types.d.ts +2 -1
  38. package/dist/core/incremental/types.js +42 -44
  39. package/dist/core/ingestion/ast-cache.js +1 -0
  40. package/dist/core/ingestion/call-processor.d.ts +15 -3
  41. package/dist/core/ingestion/call-processor.js +448 -60
  42. package/dist/core/ingestion/cluster-enricher.d.ts +1 -1
  43. package/dist/core/ingestion/cluster-enricher.js +2 -0
  44. package/dist/core/ingestion/community-processor.d.ts +1 -1
  45. package/dist/core/ingestion/community-processor.js +8 -3
  46. package/dist/core/ingestion/export-detection.d.ts +1 -1
  47. package/dist/core/ingestion/export-detection.js +1 -1
  48. package/dist/core/ingestion/filesystem-walker.js +1 -1
  49. package/dist/core/ingestion/heritage-processor.d.ts +2 -2
  50. package/dist/core/ingestion/heritage-processor.js +22 -11
  51. package/dist/core/ingestion/import-processor.d.ts +2 -2
  52. package/dist/core/ingestion/import-processor.js +24 -9
  53. package/dist/core/ingestion/language-config.js +7 -4
  54. package/dist/core/ingestion/mro-processor.d.ts +1 -1
  55. package/dist/core/ingestion/mro-processor.js +23 -11
  56. package/dist/core/ingestion/named-binding-extraction.js +5 -5
  57. package/dist/core/ingestion/parsing-processor.d.ts +4 -4
  58. package/dist/core/ingestion/parsing-processor.js +26 -18
  59. package/dist/core/ingestion/pipeline.d.ts +4 -2
  60. package/dist/core/ingestion/pipeline.js +50 -20
  61. package/dist/core/ingestion/process-processor.d.ts +2 -2
  62. package/dist/core/ingestion/process-processor.js +28 -14
  63. package/dist/core/ingestion/resolution-context.d.ts +1 -1
  64. package/dist/core/ingestion/resolution-context.js +14 -4
  65. package/dist/core/ingestion/resolvers/csharp.js +4 -3
  66. package/dist/core/ingestion/resolvers/go.js +3 -1
  67. package/dist/core/ingestion/resolvers/jvm.js +13 -4
  68. package/dist/core/ingestion/resolvers/standard.js +2 -2
  69. package/dist/core/ingestion/resolvers/utils.js +6 -2
  70. package/dist/core/ingestion/route-stitcher.d.ts +15 -0
  71. package/dist/core/ingestion/route-stitcher.js +92 -0
  72. package/dist/core/ingestion/structure-processor.d.ts +1 -1
  73. package/dist/core/ingestion/structure-processor.js +3 -2
  74. package/dist/core/ingestion/symbol-table.d.ts +2 -0
  75. package/dist/core/ingestion/symbol-table.js +5 -1
  76. package/dist/core/ingestion/tree-sitter-queries.d.ts +2 -2
  77. package/dist/core/ingestion/tree-sitter-queries.js +177 -0
  78. package/dist/core/ingestion/type-env.js +20 -0
  79. package/dist/core/ingestion/type-extractors/csharp.js +4 -3
  80. package/dist/core/ingestion/type-extractors/go.js +23 -12
  81. package/dist/core/ingestion/type-extractors/php.js +18 -10
  82. package/dist/core/ingestion/type-extractors/ruby.js +15 -3
  83. package/dist/core/ingestion/type-extractors/rust.js +3 -2
  84. package/dist/core/ingestion/type-extractors/shared.js +3 -2
  85. package/dist/core/ingestion/type-extractors/typescript.js +11 -5
  86. package/dist/core/ingestion/utils.d.ts +27 -4
  87. package/dist/core/ingestion/utils.js +145 -100
  88. package/dist/core/ingestion/workers/parse-worker.d.ts +1 -0
  89. package/dist/core/ingestion/workers/parse-worker.js +97 -29
  90. package/dist/core/ingestion/workers/worker-pool.js +3 -0
  91. package/dist/core/search/bm25-index.d.ts +15 -8
  92. package/dist/core/search/bm25-index.js +48 -98
  93. package/dist/core/search/hybrid-search.d.ts +9 -3
  94. package/dist/core/search/hybrid-search.js +30 -25
  95. package/dist/core/search/reranker.js +9 -7
  96. package/dist/core/search/types.d.ts +0 -4
  97. package/dist/core/semantic/tsgo-service.d.ts +5 -1
  98. package/dist/core/semantic/tsgo-service.js +161 -66
  99. package/dist/lib/tsgo-test.d.ts +2 -0
  100. package/dist/lib/tsgo-test.js +6 -0
  101. package/dist/lib/type-utils.d.ts +25 -0
  102. package/dist/lib/type-utils.js +22 -0
  103. package/dist/lib/utils.d.ts +3 -2
  104. package/dist/lib/utils.js +3 -2
  105. package/dist/mcp/compatible-stdio-transport.js +1 -1
  106. package/dist/mcp/local/local-backend.d.ts +29 -56
  107. package/dist/mcp/local/local-backend.js +808 -1118
  108. package/dist/mcp/resources.js +35 -25
  109. package/dist/mcp/server.d.ts +1 -1
  110. package/dist/mcp/server.js +5 -5
  111. package/dist/mcp/tools.js +24 -25
  112. package/dist/storage/repo-manager.d.ts +2 -12
  113. package/dist/storage/repo-manager.js +1 -47
  114. package/dist/types/pipeline.d.ts +8 -5
  115. package/dist/types/pipeline.js +5 -0
  116. package/package.json +18 -11
  117. package/dist/cli/serve.d.ts +0 -5
  118. package/dist/cli/serve.js +0 -8
  119. package/dist/core/incremental/child-process.d.ts +0 -8
  120. package/dist/core/incremental/child-process.js +0 -649
  121. package/dist/core/incremental/refresh-coordinator.d.ts +0 -32
  122. package/dist/core/incremental/refresh-coordinator.js +0 -147
  123. package/dist/core/lbug/csv-generator.d.ts +0 -28
  124. package/dist/core/lbug/csv-generator.js +0 -355
  125. package/dist/core/lbug/lbug-adapter.d.ts +0 -96
  126. package/dist/core/lbug/lbug-adapter.js +0 -753
  127. package/dist/core/lbug/schema.d.ts +0 -46
  128. package/dist/core/lbug/schema.js +0 -402
  129. package/dist/mcp/core/embedder.d.ts +0 -24
  130. package/dist/mcp/core/embedder.js +0 -168
  131. package/dist/mcp/core/lbug-adapter.d.ts +0 -29
  132. package/dist/mcp/core/lbug-adapter.js +0 -330
  133. package/dist/server/api.d.ts +0 -5
  134. package/dist/server/api.js +0 -340
  135. package/dist/server/mcp-http.d.ts +0 -7
  136. package/dist/server/mcp-http.js +0 -95
  137. package/models/mlx-embedder.py +0 -185
@@ -84,50 +84,44 @@ export const FUNCTION_DECLARATION_TYPES = new Set([
84
84
  'generator_function_declaration',
85
85
  'function_item',
86
86
  ]);
87
- /** Built-in function/method names that should not be tracked as call targets */
88
- export const BUILT_IN_NAMES = new Set([
89
- // JavaScript/TypeScript
90
- 'console', 'log', 'warn', 'error', 'info', 'debug',
87
+ /**
88
+ * Built-in names that are noise when called as FREE functions: `list()`, `print()`, `console()`.
89
+ * These are ONLY filtered for free calls (callForm !== 'member').
90
+ * Member calls like `obj.list()`, `obj.set()`, `obj.map()` are NEVER filtered —
91
+ * they are real method calls on user-defined objects.
92
+ *
93
+ * Names that appear in multiple languages are kept only if they are universally noise.
94
+ * Names that are valid user method names in some languages (list, set, type, get, put,
95
+ * map, filter, etc.) are excluded — they belong in MEMBER_NOISE_NAMES for member-only filtering.
96
+ */
97
+ export const FREE_CALL_BUILTINS = new Set([
98
+ // === Universal (all languages) ===
99
+ 'console',
100
+ // === JavaScript/TypeScript — free call builtins ===
91
101
  'setTimeout', 'setInterval', 'clearTimeout', 'clearInterval',
92
102
  'parseInt', 'parseFloat', 'isNaN', 'isFinite',
93
103
  'encodeURI', 'decodeURI', 'encodeURIComponent', 'decodeURIComponent',
94
- 'JSON', 'parse', 'stringify',
95
- 'Object', 'Array', 'String', 'Number', 'Boolean', 'Symbol', 'BigInt',
104
+ 'JSON', 'Object', 'Array', 'String', 'Number', 'Boolean', 'Symbol', 'BigInt',
96
105
  'Map', 'Set', 'WeakMap', 'WeakSet',
97
- 'Promise', 'resolve', 'reject', 'then', 'catch', 'finally',
98
- 'Math', 'Date', 'RegExp', 'Error',
106
+ 'Promise', 'Math', 'Date', 'RegExp', 'Error',
99
107
  'require', 'import', 'export', 'fetch', 'Response', 'Request',
108
+ // React hooks (framework built-ins, never user-defined)
100
109
  'useState', 'useEffect', 'useCallback', 'useMemo', 'useRef', 'useContext',
101
110
  'useReducer', 'useLayoutEffect', 'useImperativeHandle', 'useDebugValue',
102
111
  'createElement', 'createContext', 'createRef', 'forwardRef', 'memo', 'lazy',
103
- 'map', 'filter', 'reduce', 'forEach', 'find', 'findIndex', 'some', 'every',
104
- 'includes', 'indexOf', 'slice', 'splice', 'concat', 'join', 'split',
105
- 'push', 'pop', 'shift', 'unshift', 'sort', 'reverse',
106
- 'keys', 'values', 'entries', 'assign', 'freeze', 'seal',
107
- 'hasOwnProperty', 'toString', 'valueOf',
108
- // Python
112
+ // === Python free call builtins ===
109
113
  'print', 'len', 'range', 'str', 'int', 'float', 'list', 'dict', 'set', 'tuple',
110
- 'append', 'extend', 'update',
111
- // NOTE: 'open', 'read', 'write', 'close' removed — these are real C POSIX syscalls
112
114
  'type', 'isinstance', 'issubclass', 'getattr', 'setattr', 'hasattr',
113
115
  'enumerate', 'zip', 'sorted', 'reversed', 'min', 'max', 'sum', 'abs',
114
- // Kotlin stdlib
115
- 'println', 'print', 'readLine', 'require', 'requireNotNull', 'check', 'assert', 'lazy', 'error',
116
+ // === Kotlin — free call builtins ===
117
+ 'println', 'readLine', 'requireNotNull', 'check',
116
118
  'listOf', 'mapOf', 'setOf', 'mutableListOf', 'mutableMapOf', 'mutableSetOf',
117
- 'arrayOf', 'sequenceOf', 'also', 'apply', 'run', 'with', 'takeIf', 'takeUnless',
119
+ 'arrayOf', 'sequenceOf',
118
120
  'TODO', 'buildString', 'buildList', 'buildMap', 'buildSet',
119
- 'repeat', 'synchronized',
120
- // Kotlin coroutine builders & scope functions
121
- 'launch', 'async', 'runBlocking', 'withContext', 'coroutineScope',
122
- 'supervisorScope', 'delay',
123
- // Kotlin Flow operators
124
- 'flow', 'flowOf', 'collect', 'emit', 'onEach', 'catch',
125
- 'buffer', 'conflate', 'distinctUntilChanged',
126
- 'flatMapLatest', 'flatMapMerge', 'combine',
127
- 'stateIn', 'shareIn', 'launchIn',
128
- // Kotlin infix stdlib functions
129
- 'to', 'until', 'downTo', 'step',
130
- // C/C++ standard library
121
+ // Kotlin coroutine builders (free calls)
122
+ 'runBlocking', 'withContext', 'coroutineScope', 'supervisorScope',
123
+ 'flow', 'flowOf',
124
+ // === C/C++ — free call builtins ===
131
125
  'printf', 'fprintf', 'sprintf', 'snprintf', 'vprintf', 'vfprintf', 'vsprintf', 'vsnprintf',
132
126
  'scanf', 'fscanf', 'sscanf',
133
127
  'malloc', 'calloc', 'realloc', 'free', 'memcpy', 'memmove', 'memset', 'memcmp',
@@ -136,42 +130,23 @@ export const BUILT_IN_NAMES = new Set([
136
130
  'sizeof', 'offsetof', 'typeof',
137
131
  'assert', 'abort', 'exit', '_exit',
138
132
  'fopen', 'fclose', 'fread', 'fwrite', 'fseek', 'ftell', 'rewind', 'fflush', 'fgets', 'fputs',
139
- // Linux kernel common macros/helpers (not real call targets)
133
+ // Linux kernel macros (not real call targets)
140
134
  'likely', 'unlikely', 'BUG', 'BUG_ON', 'WARN', 'WARN_ON', 'WARN_ONCE',
141
135
  'IS_ERR', 'PTR_ERR', 'ERR_PTR', 'IS_ERR_OR_NULL',
142
136
  'ARRAY_SIZE', 'container_of', 'list_for_each_entry', 'list_for_each_entry_safe',
143
- 'min', 'max', 'clamp', 'abs', 'swap',
144
137
  'pr_info', 'pr_warn', 'pr_err', 'pr_debug', 'pr_notice', 'pr_crit', 'pr_emerg',
145
138
  'printk', 'dev_info', 'dev_warn', 'dev_err', 'dev_dbg',
146
139
  'GFP_KERNEL', 'GFP_ATOMIC',
147
140
  'spin_lock', 'spin_unlock', 'spin_lock_irqsave', 'spin_unlock_irqrestore',
148
141
  'mutex_lock', 'mutex_unlock', 'mutex_init',
149
142
  'kfree', 'kmalloc', 'kzalloc', 'kcalloc', 'krealloc', 'kvmalloc', 'kvfree',
150
- 'get', 'put',
151
- // C# / .NET built-ins
152
- 'Console', 'WriteLine', 'ReadLine', 'Write',
153
- 'Task', 'Run', 'Wait', 'WhenAll', 'WhenAny', 'FromResult', 'Delay', 'ContinueWith',
154
- 'ConfigureAwait', 'GetAwaiter', 'GetResult',
155
- 'ToString', 'GetType', 'Equals', 'GetHashCode', 'ReferenceEquals',
156
- 'Add', 'Remove', 'Contains', 'Clear', 'Count', 'Any', 'All',
157
- 'Where', 'Select', 'SelectMany', 'OrderBy', 'OrderByDescending', 'GroupBy',
158
- 'First', 'FirstOrDefault', 'Single', 'SingleOrDefault', 'Last', 'LastOrDefault',
159
- 'ToList', 'ToArray', 'ToDictionary', 'AsEnumerable', 'AsQueryable',
160
- 'Aggregate', 'Sum', 'Average', 'Min', 'Max', 'Distinct', 'Skip', 'Take',
161
- 'String', 'Format', 'IsNullOrEmpty', 'IsNullOrWhiteSpace', 'Concat', 'Join',
162
- 'Trim', 'TrimStart', 'TrimEnd', 'Split', 'Replace', 'StartsWith', 'EndsWith',
163
- 'Convert', 'ToInt32', 'ToDouble', 'ToBoolean', 'ToByte',
164
- 'Math', 'Abs', 'Ceiling', 'Floor', 'Round', 'Pow', 'Sqrt',
165
- 'Dispose', 'Close',
166
- 'TryParse', 'Parse',
167
- 'AddRange', 'RemoveAt', 'RemoveAll', 'FindAll', 'Exists', 'TrueForAll',
168
- 'ContainsKey', 'TryGetValue', 'AddOrUpdate',
169
- 'Throw', 'ThrowIfNull',
170
- // PHP built-ins
171
- 'echo', 'isset', 'empty', 'unset', 'list', 'array', 'compact', 'extract',
143
+ // === C# / .NET — free call builtins ===
144
+ 'Console', 'Convert',
145
+ // === PHP — free call builtins ===
146
+ 'echo', 'isset', 'empty', 'unset', 'array', 'compact', 'extract',
172
147
  'count', 'strlen', 'strpos', 'strrpos', 'substr', 'strtolower', 'strtoupper', 'trim',
173
148
  'ltrim', 'rtrim', 'str_replace', 'str_contains', 'str_starts_with', 'str_ends_with',
174
- 'sprintf', 'vsprintf', 'printf', 'number_format',
149
+ 'number_format',
175
150
  'array_map', 'array_filter', 'array_reduce', 'array_push', 'array_pop', 'array_shift',
176
151
  'array_unshift', 'array_slice', 'array_splice', 'array_merge', 'array_keys', 'array_values',
177
152
  'array_key_exists', 'in_array', 'array_search', 'array_unique', 'usort', 'rsort',
@@ -184,66 +159,136 @@ export const BUILT_IN_NAMES = new Set([
184
159
  'preg_match', 'preg_match_all', 'preg_replace', 'preg_split',
185
160
  'header', 'session_start', 'session_destroy', 'ob_start', 'ob_end_clean', 'ob_get_clean',
186
161
  'dd', 'dump',
187
- // Swift/iOS built-ins and standard library
188
- 'print', 'debugPrint', 'dump', 'fatalError', 'precondition', 'preconditionFailure',
189
- 'assert', 'assertionFailure', 'NSLog',
190
- 'abs', 'min', 'max', 'zip', 'stride', 'sequence', 'repeatElement',
191
- 'swap', 'withUnsafePointer', 'withUnsafeMutablePointer', 'withUnsafeBytes',
162
+ // === Swift free call builtins ===
163
+ 'debugPrint', 'fatalError', 'precondition', 'preconditionFailure',
164
+ 'assertionFailure', 'NSLog',
165
+ 'stride', 'sequence', 'repeatElement',
166
+ 'withUnsafePointer', 'withUnsafeMutablePointer', 'withUnsafeBytes',
192
167
  'autoreleasepool', 'unsafeBitCast', 'unsafeDowncast', 'numericCast',
193
- 'type', 'MemoryLayout',
194
- // Swift collection/string methods (common noise)
195
- 'map', 'flatMap', 'compactMap', 'filter', 'reduce', 'forEach', 'contains',
196
- 'first', 'last', 'prefix', 'suffix', 'dropFirst', 'dropLast',
197
- 'sorted', 'reversed', 'enumerated', 'joined', 'split',
198
- 'append', 'insert', 'remove', 'removeAll', 'removeFirst', 'removeLast',
168
+ 'MemoryLayout', 'NSLocalizedString', 'Bundle',
169
+ 'DispatchQueue',
170
+ 'withCheckedContinuation', 'withCheckedThrowingContinuation',
171
+ 'NotificationCenter',
172
+ // === Rust free call builtins ===
173
+ 'panic', 'unreachable', 'todo', 'unimplemented',
174
+ 'vec', 'println', 'eprintln', 'dbg', 'format',
175
+ 'Some', 'None', 'Ok', 'Err',
176
+ // === Ruby — free call builtins ===
177
+ 'puts', 'p', 'pp', 'raise', 'fail',
178
+ 'require', 'require_relative', 'load', 'autoload',
179
+ 'include', 'extend', 'prepend',
180
+ 'attr_accessor', 'attr_reader', 'attr_writer',
181
+ 'public', 'private', 'protected', 'module_function',
182
+ 'lambda', 'proc', 'block_given?',
183
+ ]);
184
+ /**
185
+ * Method names that are noise ONLY when called as MEMBER calls on unknown receivers.
186
+ * These are generic methods on built-in types (Array, Promise, Map, etc.) that would
187
+ * falsely resolve to user-defined functions of the same name.
188
+ *
189
+ * Only filtered when receiver type is unknown — if receiver type IS resolved,
190
+ * the call is kept because we know it's on a specific user type.
191
+ */
192
+ export const MEMBER_NOISE_NAMES = new Set([
193
+ // Array/collection methods
194
+ 'map', 'filter', 'reduce', 'forEach', 'find', 'findIndex', 'some', 'every',
195
+ 'includes', 'indexOf', 'slice', 'splice', 'concat', 'join', 'split',
196
+ 'push', 'pop', 'shift', 'unshift', 'sort', 'reverse',
197
+ 'keys', 'values', 'entries', 'flat', 'flatMap',
198
+ // Object methods
199
+ 'assign', 'freeze', 'seal', 'hasOwnProperty', 'toString', 'valueOf',
200
+ // Promise methods
201
+ 'then', 'catch', 'finally', 'all', 'any', 'race', 'resolve', 'reject', 'allSettled',
202
+ // Map/Set methods
203
+ 'has', 'get', 'set', 'add', 'delete', 'clear',
204
+ // Iterator/generator
205
+ 'next', 'return', 'throw',
206
+ // Console
207
+ 'log', 'warn', 'error', 'info', 'debug',
208
+ // HTTP response (Express/Fastify/Koa)
209
+ 'json', 'text', 'blob', 'status', 'send', 'end', 'redirect', 'render',
210
+ // EventEmitter — NOTE: emit/subscribe/on removed; they are real calls on typed event systems
211
+ 'off', 'removeListener', 'removeAllListeners',
212
+ // Stream
213
+ 'pipe', 'unpipe', 'pause', 'resume', 'destroy',
214
+ // Kotlin scope functions (member form: obj.also {}, obj.apply {})
215
+ 'also', 'apply', 'run', 'with', 'let', 'takeIf', 'takeUnless',
216
+ // Kotlin coroutines (member form: scope.launch {})
217
+ 'launch', 'async', 'delay',
218
+ // Kotlin Flow (member form)
219
+ 'collect', 'onEach', 'buffer', 'conflate', 'distinctUntilChanged',
220
+ 'flatMapLatest', 'flatMapMerge', 'combine', 'stateIn', 'shareIn', 'launchIn',
221
+ // Rust method noise
222
+ 'unwrap', 'expect', 'unwrap_or', 'unwrap_or_else', 'unwrap_or_default',
223
+ 'ok', 'err', 'is_ok', 'is_err', 'map_err', 'and_then', 'or_else',
224
+ 'clone', 'to_string', 'to_owned', 'into', 'from', 'as_ref', 'as_mut',
225
+ 'iter', 'into_iter', 'collect', 'fold', 'for_each',
226
+ 'len', 'is_empty', 'contains', 'insert', 'remove',
227
+ 'write', 'writeln', 'read', 'lock', 'try_lock',
228
+ 'spawn', 'join', 'sleep',
229
+ // C# LINQ / collection methods
230
+ 'Where', 'Select', 'SelectMany', 'OrderBy', 'OrderByDescending', 'GroupBy',
231
+ 'First', 'FirstOrDefault', 'Single', 'SingleOrDefault', 'Last', 'LastOrDefault',
232
+ 'ToList', 'ToArray', 'ToDictionary', 'AsEnumerable', 'AsQueryable',
233
+ 'Aggregate', 'Sum', 'Average', 'Min', 'Max', 'Distinct', 'Skip', 'Take',
234
+ 'Add', 'Remove', 'Contains', 'Clear', 'Count', 'Any', 'All',
235
+ 'AddRange', 'RemoveAt', 'RemoveAll', 'FindAll', 'Exists', 'TrueForAll',
236
+ 'ContainsKey', 'TryGetValue', 'AddOrUpdate',
237
+ 'ToString', 'GetType', 'Equals', 'GetHashCode', 'ReferenceEquals',
238
+ 'Dispose', 'Close',
239
+ 'Run', 'Wait', 'WhenAll', 'WhenAny', 'FromResult', 'Delay', 'ContinueWith',
240
+ 'ConfigureAwait', 'GetAwaiter', 'GetResult',
241
+ 'Format', 'IsNullOrEmpty', 'IsNullOrWhiteSpace', 'Concat', 'Join',
242
+ 'Trim', 'TrimStart', 'TrimEnd', 'Split', 'Replace', 'StartsWith', 'EndsWith',
243
+ 'TryParse', 'Parse', 'Throw', 'ThrowIfNull',
244
+ // Swift collection/string methods
245
+ 'compactMap', 'contains', 'first', 'last', 'prefix', 'suffix',
246
+ 'dropFirst', 'dropLast', 'sorted', 'reversed', 'enumerated', 'joined',
247
+ 'append', 'removeAll', 'removeFirst', 'removeLast',
199
248
  'isEmpty', 'count', 'index', 'startIndex', 'endIndex',
200
- // UIKit/Foundation common methods (noise in call graph)
249
+ // Swift UIKit
201
250
  'addSubview', 'removeFromSuperview', 'layoutSubviews', 'setNeedsLayout',
202
251
  'layoutIfNeeded', 'setNeedsDisplay', 'invalidateIntrinsicContentSize',
203
252
  'addTarget', 'removeTarget', 'addGestureRecognizer',
204
253
  'addConstraint', 'addConstraints', 'removeConstraint', 'removeConstraints',
205
- 'NSLocalizedString', 'Bundle',
206
254
  'reloadData', 'reloadSections', 'reloadRows', 'performBatchUpdates',
207
255
  'register', 'dequeueReusableCell', 'dequeueReusableSupplementaryView',
208
256
  'beginUpdates', 'endUpdates', 'insertRows', 'deleteRows', 'insertSections', 'deleteSections',
209
257
  'present', 'dismiss', 'pushViewController', 'popViewController', 'popToRootViewController',
210
258
  'performSegue', 'prepare',
211
- // GCD / async
212
- 'DispatchQueue', 'async', 'sync', 'asyncAfter',
213
- 'Task', 'withCheckedContinuation', 'withCheckedThrowingContinuation',
214
- // Combine
215
- 'sink', 'store', 'assign', 'receive', 'subscribe',
216
- // Notification / KVO
217
- 'addObserver', 'removeObserver', 'post', 'NotificationCenter',
218
- // Rust standard library (common noise in call graphs)
219
- 'unwrap', 'expect', 'unwrap_or', 'unwrap_or_else', 'unwrap_or_default',
220
- 'ok', 'err', 'is_ok', 'is_err', 'map', 'map_err', 'and_then', 'or_else',
221
- 'clone', 'to_string', 'to_owned', 'into', 'from', 'as_ref', 'as_mut',
222
- 'iter', 'into_iter', 'collect', 'map', 'filter', 'fold', 'for_each',
223
- 'len', 'is_empty', 'push', 'pop', 'insert', 'remove', 'contains',
224
- 'format', 'write', 'writeln', 'panic', 'unreachable', 'todo', 'unimplemented',
225
- 'vec', 'println', 'eprintln', 'dbg',
226
- 'lock', 'read', 'write', 'try_lock',
227
- 'spawn', 'join', 'sleep',
228
- 'Some', 'None', 'Ok', 'Err',
229
- // Ruby built-ins and Kernel methods
230
- 'puts', 'p', 'pp', 'raise', 'fail',
231
- 'require', 'require_relative', 'load', 'autoload',
232
- 'include', 'extend', 'prepend',
233
- 'attr_accessor', 'attr_reader', 'attr_writer',
234
- 'public', 'private', 'protected', 'module_function',
235
- 'lambda', 'proc', 'block_given?',
236
- 'nil?', 'is_a?', 'kind_of?', 'instance_of?', 'respond_to?',
237
- 'freeze', 'frozen?', 'dup', 'tap', 'yield_self',
238
- // Ruby enumerables
259
+ // Swift Combine
260
+ 'sink', 'store', 'assign', 'receive',
261
+ 'addObserver', 'removeObserver', 'post',
262
+ // Ruby enumerables (member form)
239
263
  'each', 'select', 'reject', 'detect', 'collect',
240
264
  'inject', 'flat_map', 'each_with_object', 'each_with_index',
241
265
  'any?', 'all?', 'none?', 'count', 'first', 'last',
242
266
  'sort_by', 'min_by', 'max_by',
243
267
  'group_by', 'partition', 'compact', 'flatten', 'uniq',
268
+ 'nil?', 'is_a?', 'kind_of?', 'instance_of?', 'respond_to?',
269
+ 'freeze', 'frozen?', 'dup', 'tap', 'yield_self',
270
+ // PHP method noise
271
+ 'stringify', 'parse',
244
272
  ]);
245
- /** Check if a name is a built-in or common noise that should be filtered out */
246
- export const isBuiltInOrNoise = (name) => BUILT_IN_NAMES.has(name);
273
+ /** Legacy flat set kept for backward compatibility with existing `isBuiltInOrNoise` callers */
274
+ const BUILT_IN_NAMES = new Set([...FREE_CALL_BUILTINS, ...MEMBER_NOISE_NAMES]);
275
+ /**
276
+ * Check if a name should be filtered based on call form.
277
+ * - Free calls: filtered if name is a known built-in free function
278
+ * - Member calls: filtered ONLY if name is a known noise method AND receiver type is unknown
279
+ * - Constructor calls: never filtered
280
+ */
281
+ export const isBuiltInOrNoise = (name, callForm) => {
282
+ // Constructor calls are never noise — `new Foo()` is always intentional
283
+ if (callForm === 'constructor')
284
+ return false;
285
+ // Member calls are only noise if the name is in the member noise set
286
+ // (actual filtering for unknown receivers happens in call-processor, not here)
287
+ if (callForm === 'member')
288
+ return MEMBER_NOISE_NAMES.has(name);
289
+ // Free calls (or unknown form): check both sets
290
+ return BUILT_IN_NAMES.has(name);
291
+ };
247
292
  /** AST node types representing class-like containers (for HAS_METHOD edges) */
248
293
  export const CLASS_CONTAINER_TYPES = new Set([
249
294
  'class_declaration', 'abstract_class_declaration',
@@ -900,7 +945,7 @@ export const extractReceiverNode = (nameNode) => {
900
945
  return receiver ?? undefined;
901
946
  };
902
947
  export const isVerboseIngestionEnabled = () => {
903
- const raw = process.env.CODE_MAPPER_VERBOSE;
948
+ const raw = process.env['CODE_MAPPER_VERBOSE'];
904
949
  if (!raw)
905
950
  return false;
906
951
  const value = raw.toLowerCase();
@@ -59,6 +59,7 @@ export interface ExtractedCall {
59
59
  receiverTypeName?: string;
60
60
  receiverCallChain?: string[];
61
61
  callLine?: number;
62
+ callColumn?: number;
62
63
  }
63
64
  export interface ExtractedHeritage {
64
65
  filePath: string;
@@ -203,10 +203,11 @@ const processBatch = (files, onProgress) => {
203
203
  regularFiles.push(...langFiles);
204
204
  }
205
205
  // Process regular files for this language
206
- if (regularFiles.length > 0) {
207
- if (isLanguageAvailable(language, regularFiles[0].path)) {
206
+ const firstRegular = regularFiles[0];
207
+ if (firstRegular !== undefined) {
208
+ if (isLanguageAvailable(language, firstRegular.path)) {
208
209
  try {
209
- setLanguage(language, regularFiles[0].path);
210
+ setLanguage(language, firstRegular.path);
210
211
  processFileGroup(regularFiles, language, queryString, result, onFileProcessed);
211
212
  }
212
213
  catch {
@@ -218,10 +219,11 @@ const processBatch = (files, onProgress) => {
218
219
  }
219
220
  }
220
221
  // Process tsx files separately (different grammar)
221
- if (tsxFiles.length > 0) {
222
- if (isLanguageAvailable(language, tsxFiles[0].path)) {
222
+ const firstTsx = tsxFiles[0];
223
+ if (firstTsx !== undefined) {
224
+ if (isLanguageAvailable(language, firstTsx.path)) {
223
225
  try {
224
- setLanguage(language, tsxFiles[0].path);
226
+ setLanguage(language, firstTsx.path);
225
227
  processFileGroup(tsxFiles, language, queryString, result, onFileProcessed);
226
228
  }
227
229
  catch {
@@ -470,7 +472,7 @@ function extractControllerTarget(argsNode) {
470
472
  const text = extractStringContent(handlerNode);
471
473
  if (text?.includes('@')) {
472
474
  const [controller, method] = text.split('@');
473
- return { controller, method };
475
+ return { controller: controller ?? null, method: method ?? null };
474
476
  }
475
477
  }
476
478
  // Class reference: UserController::class (invokable controller)
@@ -817,43 +819,109 @@ const processFileGroup = (files, language, queryString, result, onFileProcessed)
817
819
  }
818
820
  // kind === 'call' — fall through to normal call processing below
819
821
  }
820
- if (!isBuiltInOrNoise(calledName)) {
822
+ // RC3: Extract function references from arguments BEFORE the built-in filter
823
+ // e.g. router.get('/path', requireAuth, getBooking) — 'get' is built-in noise,
824
+ // but requireAuth/getBooking are real function references we must capture
825
+ {
821
826
  const callNode = captureMap['call'];
827
+ const argsNode = callNode.childForFieldName?.('arguments');
828
+ if (argsNode) {
829
+ const argSourceId = findEnclosingFunctionId(callNode, file.path)
830
+ || generateId('File', file.path);
831
+ for (const arg of (argsNode.children ?? [])) {
832
+ if (arg.type === 'identifier' && arg.text && !isBuiltInOrNoise(arg.text)) {
833
+ result.calls.push({
834
+ filePath: file.path,
835
+ calledName: arg.text,
836
+ sourceId: argSourceId,
837
+ callForm: 'free',
838
+ callLine: arg.startPosition?.row != null ? arg.startPosition.row + 1 : undefined,
839
+ callColumn: arg.startPosition?.column,
840
+ });
841
+ }
842
+ }
843
+ }
844
+ }
845
+ const callNode_pre = captureMap['call'];
846
+ const callForm_pre = inferCallForm(callNode_pre, callNameNode);
847
+ if (!isBuiltInOrNoise(calledName, callForm_pre)) {
848
+ const callNode = callNode_pre;
822
849
  const sourceId = findEnclosingFunctionId(callNode, file.path)
823
850
  || generateId('File', file.path);
824
- const callForm = inferCallForm(callNode, callNameNode);
851
+ const callForm = callForm_pre;
825
852
  let receiverName = callForm === 'member' ? extractReceiverName(callNameNode) : undefined;
826
853
  let receiverTypeName = receiverName ? typeEnv.lookup(receiverName, callNode) : undefined;
827
854
  let receiverCallChain;
828
- // When the receiver is a call_expression (e.g. svc.getUser().save()),
829
- // extractReceiverName refuses complex expressions, so walk the receiver node
830
- // to build a call chain for deferred resolution in processCallsFromExtracted
855
+ // When the receiver is complex (call chain or member chain),
856
+ // extractReceiverName returns undefined. Walk the AST to extract
857
+ // the chain and base receiver for deferred resolution.
831
858
  if (callForm === 'member' && receiverName === undefined && !receiverTypeName) {
832
859
  const receiverNode = extractReceiverNode(callNameNode);
833
- if (receiverNode && CALL_EXPRESSION_TYPES.has(receiverNode.type)) {
834
- const extracted = extractCallChain(receiverNode);
835
- if (extracted) {
836
- receiverCallChain = extracted.chain;
837
- // Set receiverName to the base object for constructor binding resolution
838
- receiverName = extracted.baseReceiverName;
839
- // Try the type environment immediately for explicitly-typed locals/params
840
- if (receiverName) {
841
- receiverTypeName = typeEnv.lookup(receiverName, callNode);
860
+ if (receiverNode) {
861
+ if (CALL_EXPRESSION_TYPES.has(receiverNode.type)) {
862
+ // Call chain: svc.getUser().save() → chain=['getUser'], base='svc'
863
+ const extracted = extractCallChain(receiverNode);
864
+ if (extracted) {
865
+ receiverCallChain = extracted.chain;
866
+ receiverName = extracted.baseReceiverName;
867
+ if (receiverName) {
868
+ receiverTypeName = typeEnv.lookup(receiverName, callNode);
869
+ }
870
+ }
871
+ }
872
+ else if (receiverNode.type === 'member_expression') {
873
+ // Member chain: prisma.booking.findMany() → chain=['booking'], base='prisma'
874
+ const innerObject = receiverNode.childForFieldName?.('object');
875
+ const innerProp = receiverNode.childForFieldName?.('property');
876
+ if (innerObject && innerProp) {
877
+ if (innerObject.type === 'identifier' || innerObject.type === 'this') {
878
+ // 3-level: a.b.c() or this.b.c() → base=a/this, chain=[b]
879
+ // For 'this', resolve the property name directly from type env
880
+ receiverCallChain = [innerProp.text];
881
+ receiverName = innerObject.text;
882
+ if (!receiverTypeName) {
883
+ // For this.x.method(), look up 'x' not 'this' in the type env
884
+ const lookupName = innerObject.type === 'this' ? innerProp.text : receiverName;
885
+ receiverTypeName = typeEnv.lookup(lookupName, callNode);
886
+ }
887
+ }
888
+ else if (innerObject.type === 'member_expression') {
889
+ // 4-level: a.b.c.d() → base=a, chain=[b,c]
890
+ const deepObj = innerObject.childForFieldName?.('object');
891
+ const deepProp = innerObject.childForFieldName?.('property');
892
+ if (deepObj?.type === 'identifier' && deepProp) {
893
+ receiverCallChain = [deepProp.text, innerProp.text];
894
+ receiverName = deepObj.text;
895
+ if (!receiverTypeName) {
896
+ receiverTypeName = typeEnv.lookup(receiverName, callNode);
897
+ }
898
+ }
899
+ }
842
900
  }
843
901
  }
844
902
  }
845
903
  }
846
- result.calls.push({
904
+ const call = {
847
905
  filePath: file.path,
848
906
  calledName,
849
907
  sourceId,
850
- argCount: countCallArguments(callNode),
851
- callLine: callNode.startPosition?.row != null ? callNode.startPosition.row + 1 : undefined,
852
- ...(callForm !== undefined ? { callForm } : {}),
853
- ...(receiverName !== undefined ? { receiverName } : {}),
854
- ...(receiverTypeName !== undefined ? { receiverTypeName } : {}),
855
- ...(receiverCallChain !== undefined ? { receiverCallChain } : {}),
856
- });
908
+ };
909
+ const argCount = countCallArguments(callNode);
910
+ if (argCount !== undefined)
911
+ call.argCount = argCount;
912
+ if (callNode.startPosition?.row != null)
913
+ call.callLine = callNode.startPosition.row + 1;
914
+ if (callNameNode.startPosition?.column !== undefined)
915
+ call.callColumn = callNameNode.startPosition.column;
916
+ if (callForm !== undefined)
917
+ call.callForm = callForm;
918
+ if (receiverName !== undefined)
919
+ call.receiverName = receiverName;
920
+ if (receiverTypeName !== undefined)
921
+ call.receiverTypeName = receiverTypeName;
922
+ if (receiverCallChain !== undefined)
923
+ call.receiverCallChain = receiverCallChain;
924
+ result.calls.push(call);
857
925
  }
858
926
  }
859
927
  continue;
@@ -31,6 +31,9 @@ export const createWorkerPool = (workerUrl, poolSize) => {
31
31
  const workerProgress = new Array(chunks.length).fill(0);
32
32
  const promises = chunks.map((chunk, i) => {
33
33
  const worker = workers[i];
34
+ if (worker === undefined) {
35
+ return Promise.reject(new Error(`Worker ${i} not available`));
36
+ }
34
37
  return new Promise((resolve, reject) => {
35
38
  let settled = false;
36
39
  let subBatchTimer = null;
@@ -1,20 +1,27 @@
1
1
  /**
2
2
  * @file bm25-index.ts
3
- * @description Symbol-level full-text search via LadybugDB FTS indexes.
3
+ * @description Symbol-level full-text search via SQLite FTS5 index.
4
4
  *
5
5
  * Returns individual symbols (functions, classes, methods, interfaces, files)
6
- * with their nodeId, name, type NOT just filePaths.
6
+ * with their nodeId, name, type -- NOT just filePaths.
7
7
  * This gives the RRF merge symbol-level granularity for accurate ranking.
8
8
  *
9
- * All FTS tables are driven from FTS_TABLES in types.ts single source of truth.
9
+ * Backed by the unified FTS5 index on the `nodes` table (see adapter.searchFTS).
10
10
  */
11
+ import type Database from 'better-sqlite3';
11
12
  import { type BM25SearchResult } from './types.js';
12
13
  export type { BM25SearchResult } from './types.js';
13
14
  /**
14
- * Symbol-level BM25 search via LadybugDB FTS.
15
+ * Symbol-level BM25 search via SQLite FTS5.
15
16
  *
16
- * Queries all FTS_TABLES in parallel. Returns individual symbols (not filePaths).
17
- * Deduplicates by nodeId if the same symbol matches in multiple indexes,
18
- * take the highest score.
17
+ * Queries the unified `nodes_fts` virtual table, deduplicates by nodeId,
18
+ * applies type-based weighting, and returns ranked results.
19
+ *
20
+ * Synchronous under the hood (better-sqlite3), but the function is sync --
21
+ * callers that `await` it still work (await on a non-Promise is a no-op).
22
+ *
23
+ * @param query - Search text
24
+ * @param limit - Max results to return (default 20)
25
+ * @param db - Open SQLite database instance (required; returns [] if undefined)
19
26
  */
20
- export declare function searchFTSFromLbug(query: string, limit?: number, repoId?: string): Promise<BM25SearchResult[]>;
27
+ export declare function searchFTSSymbols(query: string, limit?: number, db?: Database.Database): BM25SearchResult[];