@zuvia-software-solutions/code-mapper 1.4.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 (213) hide show
  1. package/README.md +215 -0
  2. package/dist/cli/ai-context.d.ts +19 -0
  3. package/dist/cli/ai-context.js +168 -0
  4. package/dist/cli/analyze.d.ts +7 -0
  5. package/dist/cli/analyze.js +325 -0
  6. package/dist/cli/augment.d.ts +7 -0
  7. package/dist/cli/augment.js +27 -0
  8. package/dist/cli/clean.d.ts +5 -0
  9. package/dist/cli/clean.js +56 -0
  10. package/dist/cli/eval-server.d.ts +25 -0
  11. package/dist/cli/eval-server.js +365 -0
  12. package/dist/cli/index.d.ts +6 -0
  13. package/dist/cli/index.js +102 -0
  14. package/dist/cli/lazy-action.d.ts +6 -0
  15. package/dist/cli/lazy-action.js +19 -0
  16. package/dist/cli/list.d.ts +2 -0
  17. package/dist/cli/list.js +27 -0
  18. package/dist/cli/mcp.d.ts +8 -0
  19. package/dist/cli/mcp.js +35 -0
  20. package/dist/cli/refresh.d.ts +12 -0
  21. package/dist/cli/refresh.js +165 -0
  22. package/dist/cli/serve.d.ts +5 -0
  23. package/dist/cli/serve.js +8 -0
  24. package/dist/cli/setup.d.ts +6 -0
  25. package/dist/cli/setup.js +218 -0
  26. package/dist/cli/status.d.ts +2 -0
  27. package/dist/cli/status.js +33 -0
  28. package/dist/cli/tool.d.ts +28 -0
  29. package/dist/cli/tool.js +87 -0
  30. package/dist/config/ignore-service.d.ts +32 -0
  31. package/dist/config/ignore-service.js +282 -0
  32. package/dist/config/supported-languages.d.ts +23 -0
  33. package/dist/config/supported-languages.js +52 -0
  34. package/dist/core/augmentation/engine.d.ts +22 -0
  35. package/dist/core/augmentation/engine.js +232 -0
  36. package/dist/core/embeddings/embedder.d.ts +35 -0
  37. package/dist/core/embeddings/embedder.js +171 -0
  38. package/dist/core/embeddings/embedding-pipeline.d.ts +41 -0
  39. package/dist/core/embeddings/embedding-pipeline.js +402 -0
  40. package/dist/core/embeddings/index.d.ts +5 -0
  41. package/dist/core/embeddings/index.js +6 -0
  42. package/dist/core/embeddings/text-generator.d.ts +20 -0
  43. package/dist/core/embeddings/text-generator.js +159 -0
  44. package/dist/core/embeddings/types.d.ts +60 -0
  45. package/dist/core/embeddings/types.js +23 -0
  46. package/dist/core/graph/graph.d.ts +4 -0
  47. package/dist/core/graph/graph.js +65 -0
  48. package/dist/core/graph/types.d.ts +69 -0
  49. package/dist/core/graph/types.js +3 -0
  50. package/dist/core/incremental/child-process.d.ts +8 -0
  51. package/dist/core/incremental/child-process.js +649 -0
  52. package/dist/core/incremental/refresh-coordinator.d.ts +32 -0
  53. package/dist/core/incremental/refresh-coordinator.js +147 -0
  54. package/dist/core/incremental/types.d.ts +78 -0
  55. package/dist/core/incremental/types.js +153 -0
  56. package/dist/core/incremental/watcher.d.ts +63 -0
  57. package/dist/core/incremental/watcher.js +338 -0
  58. package/dist/core/ingestion/ast-cache.d.ts +12 -0
  59. package/dist/core/ingestion/ast-cache.js +34 -0
  60. package/dist/core/ingestion/call-processor.d.ts +34 -0
  61. package/dist/core/ingestion/call-processor.js +937 -0
  62. package/dist/core/ingestion/call-routing.d.ts +40 -0
  63. package/dist/core/ingestion/call-routing.js +97 -0
  64. package/dist/core/ingestion/cluster-enricher.d.ts +30 -0
  65. package/dist/core/ingestion/cluster-enricher.js +151 -0
  66. package/dist/core/ingestion/community-processor.d.ts +26 -0
  67. package/dist/core/ingestion/community-processor.js +272 -0
  68. package/dist/core/ingestion/constants.d.ts +5 -0
  69. package/dist/core/ingestion/constants.js +8 -0
  70. package/dist/core/ingestion/entry-point-scoring.d.ts +23 -0
  71. package/dist/core/ingestion/entry-point-scoring.js +317 -0
  72. package/dist/core/ingestion/export-detection.d.ts +11 -0
  73. package/dist/core/ingestion/export-detection.js +203 -0
  74. package/dist/core/ingestion/filesystem-walker.d.ts +18 -0
  75. package/dist/core/ingestion/filesystem-walker.js +64 -0
  76. package/dist/core/ingestion/framework-detection.d.ts +42 -0
  77. package/dist/core/ingestion/framework-detection.js +405 -0
  78. package/dist/core/ingestion/heritage-processor.d.ts +15 -0
  79. package/dist/core/ingestion/heritage-processor.js +237 -0
  80. package/dist/core/ingestion/import-processor.d.ts +31 -0
  81. package/dist/core/ingestion/import-processor.js +416 -0
  82. package/dist/core/ingestion/language-config.d.ts +32 -0
  83. package/dist/core/ingestion/language-config.js +161 -0
  84. package/dist/core/ingestion/mro-processor.d.ts +32 -0
  85. package/dist/core/ingestion/mro-processor.js +343 -0
  86. package/dist/core/ingestion/named-binding-extraction.d.ts +51 -0
  87. package/dist/core/ingestion/named-binding-extraction.js +343 -0
  88. package/dist/core/ingestion/parsing-processor.d.ts +20 -0
  89. package/dist/core/ingestion/parsing-processor.js +282 -0
  90. package/dist/core/ingestion/pipeline.d.ts +3 -0
  91. package/dist/core/ingestion/pipeline.js +416 -0
  92. package/dist/core/ingestion/process-processor.d.ts +42 -0
  93. package/dist/core/ingestion/process-processor.js +357 -0
  94. package/dist/core/ingestion/resolution-context.d.ts +40 -0
  95. package/dist/core/ingestion/resolution-context.js +171 -0
  96. package/dist/core/ingestion/resolvers/csharp.d.ts +10 -0
  97. package/dist/core/ingestion/resolvers/csharp.js +101 -0
  98. package/dist/core/ingestion/resolvers/go.d.ts +8 -0
  99. package/dist/core/ingestion/resolvers/go.js +33 -0
  100. package/dist/core/ingestion/resolvers/index.d.ts +14 -0
  101. package/dist/core/ingestion/resolvers/index.js +10 -0
  102. package/dist/core/ingestion/resolvers/jvm.d.ts +9 -0
  103. package/dist/core/ingestion/resolvers/jvm.js +74 -0
  104. package/dist/core/ingestion/resolvers/php.d.ts +7 -0
  105. package/dist/core/ingestion/resolvers/php.js +30 -0
  106. package/dist/core/ingestion/resolvers/ruby.d.ts +9 -0
  107. package/dist/core/ingestion/resolvers/ruby.js +13 -0
  108. package/dist/core/ingestion/resolvers/rust.d.ts +5 -0
  109. package/dist/core/ingestion/resolvers/rust.js +62 -0
  110. package/dist/core/ingestion/resolvers/standard.d.ts +16 -0
  111. package/dist/core/ingestion/resolvers/standard.js +144 -0
  112. package/dist/core/ingestion/resolvers/utils.d.ts +18 -0
  113. package/dist/core/ingestion/resolvers/utils.js +113 -0
  114. package/dist/core/ingestion/structure-processor.d.ts +4 -0
  115. package/dist/core/ingestion/structure-processor.js +39 -0
  116. package/dist/core/ingestion/symbol-table.d.ts +34 -0
  117. package/dist/core/ingestion/symbol-table.js +48 -0
  118. package/dist/core/ingestion/tree-sitter-queries.d.ts +20 -0
  119. package/dist/core/ingestion/tree-sitter-queries.js +691 -0
  120. package/dist/core/ingestion/type-env.d.ts +52 -0
  121. package/dist/core/ingestion/type-env.js +349 -0
  122. package/dist/core/ingestion/type-extractors/c-cpp.d.ts +4 -0
  123. package/dist/core/ingestion/type-extractors/c-cpp.js +214 -0
  124. package/dist/core/ingestion/type-extractors/csharp.d.ts +4 -0
  125. package/dist/core/ingestion/type-extractors/csharp.js +224 -0
  126. package/dist/core/ingestion/type-extractors/go.d.ts +4 -0
  127. package/dist/core/ingestion/type-extractors/go.js +261 -0
  128. package/dist/core/ingestion/type-extractors/index.d.ts +20 -0
  129. package/dist/core/ingestion/type-extractors/index.js +30 -0
  130. package/dist/core/ingestion/type-extractors/jvm.d.ts +5 -0
  131. package/dist/core/ingestion/type-extractors/jvm.js +386 -0
  132. package/dist/core/ingestion/type-extractors/php.d.ts +4 -0
  133. package/dist/core/ingestion/type-extractors/php.js +280 -0
  134. package/dist/core/ingestion/type-extractors/python.d.ts +4 -0
  135. package/dist/core/ingestion/type-extractors/python.js +175 -0
  136. package/dist/core/ingestion/type-extractors/ruby.d.ts +12 -0
  137. package/dist/core/ingestion/type-extractors/ruby.js +218 -0
  138. package/dist/core/ingestion/type-extractors/rust.d.ts +4 -0
  139. package/dist/core/ingestion/type-extractors/rust.js +290 -0
  140. package/dist/core/ingestion/type-extractors/shared.d.ts +81 -0
  141. package/dist/core/ingestion/type-extractors/shared.js +322 -0
  142. package/dist/core/ingestion/type-extractors/swift.d.ts +4 -0
  143. package/dist/core/ingestion/type-extractors/swift.js +140 -0
  144. package/dist/core/ingestion/type-extractors/types.d.ts +111 -0
  145. package/dist/core/ingestion/type-extractors/types.js +4 -0
  146. package/dist/core/ingestion/type-extractors/typescript.d.ts +4 -0
  147. package/dist/core/ingestion/type-extractors/typescript.js +227 -0
  148. package/dist/core/ingestion/utils.d.ts +73 -0
  149. package/dist/core/ingestion/utils.js +992 -0
  150. package/dist/core/ingestion/workers/parse-worker.d.ts +99 -0
  151. package/dist/core/ingestion/workers/parse-worker.js +1055 -0
  152. package/dist/core/ingestion/workers/worker-pool.d.ts +15 -0
  153. package/dist/core/ingestion/workers/worker-pool.js +123 -0
  154. package/dist/core/lbug/csv-generator.d.ts +28 -0
  155. package/dist/core/lbug/csv-generator.js +355 -0
  156. package/dist/core/lbug/lbug-adapter.d.ts +96 -0
  157. package/dist/core/lbug/lbug-adapter.js +753 -0
  158. package/dist/core/lbug/schema.d.ts +46 -0
  159. package/dist/core/lbug/schema.js +402 -0
  160. package/dist/core/search/bm25-index.d.ts +20 -0
  161. package/dist/core/search/bm25-index.js +123 -0
  162. package/dist/core/search/hybrid-search.d.ts +32 -0
  163. package/dist/core/search/hybrid-search.js +131 -0
  164. package/dist/core/search/query-cache.d.ts +18 -0
  165. package/dist/core/search/query-cache.js +47 -0
  166. package/dist/core/search/query-expansion.d.ts +19 -0
  167. package/dist/core/search/query-expansion.js +75 -0
  168. package/dist/core/search/reranker.d.ts +29 -0
  169. package/dist/core/search/reranker.js +122 -0
  170. package/dist/core/search/types.d.ts +154 -0
  171. package/dist/core/search/types.js +51 -0
  172. package/dist/core/semantic/tsgo-service.d.ts +67 -0
  173. package/dist/core/semantic/tsgo-service.js +355 -0
  174. package/dist/core/tree-sitter/parser-loader.d.ts +12 -0
  175. package/dist/core/tree-sitter/parser-loader.js +71 -0
  176. package/dist/lib/memory-guard.d.ts +35 -0
  177. package/dist/lib/memory-guard.js +70 -0
  178. package/dist/lib/utils.d.ts +3 -0
  179. package/dist/lib/utils.js +6 -0
  180. package/dist/mcp/compatible-stdio-transport.d.ts +32 -0
  181. package/dist/mcp/compatible-stdio-transport.js +209 -0
  182. package/dist/mcp/core/embedder.d.ts +24 -0
  183. package/dist/mcp/core/embedder.js +168 -0
  184. package/dist/mcp/core/lbug-adapter.d.ts +29 -0
  185. package/dist/mcp/core/lbug-adapter.js +330 -0
  186. package/dist/mcp/local/local-backend.d.ts +188 -0
  187. package/dist/mcp/local/local-backend.js +2759 -0
  188. package/dist/mcp/resources.d.ts +22 -0
  189. package/dist/mcp/resources.js +379 -0
  190. package/dist/mcp/server.d.ts +10 -0
  191. package/dist/mcp/server.js +217 -0
  192. package/dist/mcp/staleness.d.ts +10 -0
  193. package/dist/mcp/staleness.js +25 -0
  194. package/dist/mcp/tools.d.ts +21 -0
  195. package/dist/mcp/tools.js +202 -0
  196. package/dist/server/api.d.ts +5 -0
  197. package/dist/server/api.js +340 -0
  198. package/dist/server/mcp-http.d.ts +7 -0
  199. package/dist/server/mcp-http.js +95 -0
  200. package/dist/storage/git.d.ts +6 -0
  201. package/dist/storage/git.js +35 -0
  202. package/dist/storage/repo-manager.d.ts +87 -0
  203. package/dist/storage/repo-manager.js +249 -0
  204. package/dist/types/pipeline.d.ts +35 -0
  205. package/dist/types/pipeline.js +20 -0
  206. package/hooks/claude/code-mapper-hook.cjs +238 -0
  207. package/hooks/claude/pre-tool-use.sh +79 -0
  208. package/hooks/claude/session-start.sh +42 -0
  209. package/models/mlx-embedder.py +185 -0
  210. package/package.json +100 -0
  211. package/scripts/patch-tree-sitter-swift.cjs +74 -0
  212. package/vendor/leiden/index.cjs +355 -0
  213. package/vendor/leiden/utils.cjs +392 -0
@@ -0,0 +1,317 @@
1
+ // code-mapper/src/core/ingestion/entry-point-scoring.ts
2
+ /** @file entry-point-scoring.ts @description Scores functions as entry point candidates using call ratio, export status, name patterns, and framework detection */
3
+ import { detectFrameworkFromPath } from './framework-detection.js';
4
+ import { SupportedLanguages } from '../../config/supported-languages.js';
5
+ // Entry point naming patterns by language
6
+ const ENTRY_POINT_PATTERNS = {
7
+ // Universal patterns
8
+ '*': [
9
+ /^(main|init|bootstrap|start|run|setup|configure)$/i,
10
+ /^handle[A-Z]/, // handleLogin, handleSubmit
11
+ /^on[A-Z]/, // onClick, onSubmit
12
+ /Handler$/, // RequestHandler
13
+ /Controller$/, // UserController
14
+ /^process[A-Z]/, // processPayment
15
+ /^execute[A-Z]/, // executeQuery
16
+ /^perform[A-Z]/, // performAction
17
+ /^dispatch[A-Z]/, // dispatchEvent
18
+ /^trigger[A-Z]/, // triggerAction
19
+ /^fire[A-Z]/, // fireEvent
20
+ /^emit[A-Z]/, // emitEvent
21
+ ],
22
+ // JavaScript/TypeScript
23
+ [SupportedLanguages.JavaScript]: [
24
+ /^use[A-Z]/, // React hooks (useEffect, etc.)
25
+ ],
26
+ [SupportedLanguages.TypeScript]: [
27
+ /^use[A-Z]/, // React hooks
28
+ ],
29
+ // Python
30
+ [SupportedLanguages.Python]: [
31
+ /^app$/, // Flask/FastAPI app
32
+ /^(get|post|put|delete|patch)_/i, // REST conventions
33
+ /^api_/, // API functions
34
+ /^view_/, // Django views
35
+ ],
36
+ // Java
37
+ [SupportedLanguages.Java]: [
38
+ /^do[A-Z]/, // doGet, doPost (Servlets)
39
+ /^create[A-Z]/, // Factory patterns
40
+ /^build[A-Z]/, // Builder patterns
41
+ /Service$/, // UserService
42
+ ],
43
+ // C#
44
+ [SupportedLanguages.CSharp]: [
45
+ /^(Get|Post|Put|Delete|Patch)/, // ASP.NET action methods
46
+ /Action$/, // MVC actions
47
+ /^On[A-Z]/, // Event handlers / Blazor lifecycle
48
+ /Async$/, // Async entry points
49
+ /^Configure$/, // Startup.Configure
50
+ /^ConfigureServices$/, // Startup.ConfigureServices
51
+ /^Handle$/, // MediatR / generic handler
52
+ /^Execute$/, // Command pattern
53
+ /^Invoke$/, // Middleware Invoke
54
+ /^Map[A-Z]/, // Minimal API MapGet, MapPost
55
+ /Service$/, // Service classes
56
+ /^Seed/, // Database seeding
57
+ ],
58
+ // Go
59
+ [SupportedLanguages.Go]: [
60
+ /Handler$/, // http.Handler pattern
61
+ /^Serve/, // ServeHTTP
62
+ /^New[A-Z]/, // Constructor pattern (returns new instance)
63
+ /^Make[A-Z]/, // Make functions
64
+ ],
65
+ // Rust
66
+ [SupportedLanguages.Rust]: [
67
+ /^(get|post|put|delete)_handler$/i,
68
+ /^handle_/, // handle_request
69
+ /^new$/, // Constructor pattern
70
+ /^run$/, // run entry point
71
+ /^spawn/, // Async spawn
72
+ ],
73
+ // C - explicit main() boost plus common C entry point conventions
74
+ [SupportedLanguages.C]: [
75
+ /^main$/, // THE entry point
76
+ /^init_/, // init_server, init_client
77
+ /_init$/, // module_init, server_init
78
+ /^start_/, // start_server
79
+ /_start$/, // thread_start
80
+ /^run_/, // run_loop
81
+ /_run$/, // event_run
82
+ /^stop_/, // stop_server
83
+ /_stop$/, // service_stop
84
+ /^open_/, // open_connection
85
+ /_open$/, // file_open
86
+ /^close_/, // close_connection
87
+ /_close$/, // socket_close
88
+ /^create_/, // create_session
89
+ /_create$/, // object_create
90
+ /^destroy_/, // destroy_session
91
+ /_destroy$/, // object_destroy
92
+ /^handle_/, // handle_request
93
+ /_handler$/, // signal_handler
94
+ /_callback$/, // event_callback
95
+ /^cmd_/, // tmux: cmd_new_window, cmd_attach_session
96
+ /^server_/, // server_start, server_loop
97
+ /^client_/, // client_connect
98
+ /^session_/, // session_create
99
+ /^window_/, // window_resize (tmux)
100
+ /^key_/, // key_press
101
+ /^input_/, // input_parse
102
+ /^output_/, // output_write
103
+ /^notify_/, // notify_client
104
+ /^control_/, // control_start
105
+ ],
106
+ // C++ - same as C plus OOP/template patterns
107
+ [SupportedLanguages.CPlusPlus]: [
108
+ /^main$/, // THE entry point
109
+ /^init_/,
110
+ /_init$/,
111
+ /^Create[A-Z]/, // Factory patterns
112
+ /^create_/,
113
+ /^Run$/, // Run methods
114
+ /^run$/,
115
+ /^Start$/, // Start methods
116
+ /^start$/,
117
+ /^handle_/,
118
+ /_handler$/,
119
+ /_callback$/,
120
+ /^OnEvent/, // Event callbacks
121
+ /^on_/,
122
+ /::Run$/, // Class::Run
123
+ /::Start$/, // Class::Start
124
+ /::Init$/, // Class::Init
125
+ /::Execute$/, // Class::Execute
126
+ ],
127
+ // Swift / iOS
128
+ [SupportedLanguages.Swift]: [
129
+ /^viewDidLoad$/, // UIKit lifecycle
130
+ /^viewWillAppear$/, // UIKit lifecycle
131
+ /^viewDidAppear$/, // UIKit lifecycle
132
+ /^viewWillDisappear$/, // UIKit lifecycle
133
+ /^viewDidDisappear$/, // UIKit lifecycle
134
+ /^application\(/, // AppDelegate methods
135
+ /^scene\(/, // SceneDelegate methods
136
+ /^body$/, // SwiftUI View.body
137
+ /Coordinator$/, // Coordinator pattern
138
+ /^sceneDidBecomeActive$/, // SceneDelegate lifecycle
139
+ /^sceneWillResignActive$/, // SceneDelegate lifecycle
140
+ /^didFinishLaunchingWithOptions$/, // AppDelegate
141
+ /ViewController$/, // ViewController classes
142
+ /^configure[A-Z]/, // Configuration methods
143
+ /^setup[A-Z]/, // Setup methods
144
+ /^makeBody$/, // SwiftUI ViewModifier
145
+ ],
146
+ // PHP / Laravel
147
+ [SupportedLanguages.PHP]: [
148
+ /Controller$/, // UserController (class name convention)
149
+ /^handle$/, // Job::handle(), Listener::handle()
150
+ /^execute$/, // Command::execute()
151
+ /^boot$/, // ServiceProvider::boot()
152
+ /^register$/, // ServiceProvider::register()
153
+ /^__invoke$/, // Invokable controllers/actions
154
+ /^(index|show|store|update|destroy|create|edit)$/, // RESTful resource methods
155
+ /^(get|post|put|delete|patch)[A-Z]/, // Explicit HTTP method actions
156
+ /^run$/, // Command/Job run()
157
+ /^fire$/, // Event fire()
158
+ /^dispatch$/, // Dispatchable jobs
159
+ /Service$/, // UserService (Service layer)
160
+ /Repository$/, // UserRepository (Repository pattern)
161
+ /^find$/, // Repository::find()
162
+ /^findAll$/, // Repository::findAll()
163
+ /^save$/, // Repository::save()
164
+ /^delete$/, // Repository::delete()
165
+ ],
166
+ // Ruby
167
+ [SupportedLanguages.Ruby]: [
168
+ /^call$/, // Service objects (MyService.call)
169
+ /^perform$/, // Background jobs (Sidekiq, ActiveJob)
170
+ /^execute$/, // Command pattern
171
+ ],
172
+ };
173
+ // Pre-computed merged patterns (universal + language-specific)
174
+ const MERGED_ENTRY_POINT_PATTERNS = {};
175
+ const UNIVERSAL_PATTERNS = ENTRY_POINT_PATTERNS['*'] || [];
176
+ for (const [lang, patterns] of Object.entries(ENTRY_POINT_PATTERNS)) {
177
+ if (lang === '*')
178
+ continue;
179
+ MERGED_ENTRY_POINT_PATTERNS[lang] = [...UNIVERSAL_PATTERNS, ...patterns];
180
+ }
181
+ // Utility/helper patterns that get penalized in scoring (not entry points)
182
+ const UTILITY_PATTERNS = [
183
+ /^(get|set|is|has|can|should|will|did)[A-Z]/, // Accessors/predicates
184
+ /^_/, // Private by convention
185
+ /^(format|parse|validate|convert|transform)/i, // Transformation utilities
186
+ /^(log|debug|error|warn|info)$/i, // Logging
187
+ /^(to|from)[A-Z]/, // Conversions
188
+ /^(encode|decode)/i, // Encoding utilities
189
+ /^(serialize|deserialize)/i, // Serialization
190
+ /^(clone|copy|deep)/i, // Cloning utilities
191
+ /^(merge|extend|assign)/i, // Object utilities
192
+ /^(filter|map|reduce|sort|find)/i, // Collection utilities (standalone)
193
+ /Helper$/,
194
+ /Util$/,
195
+ /Utils$/,
196
+ /^utils?$/i,
197
+ /^helpers?$/i,
198
+ ];
199
+ /**
200
+ * Calculate an entry point score for a function/method
201
+ *
202
+ * Score = baseScore * exportMultiplier * nameMultiplier * frameworkMultiplier
203
+ *
204
+ * @param name - Function/method name
205
+ * @param language - Programming language
206
+ * @param isExported - Whether the function is exported/public
207
+ * @param callerCount - Number of callers
208
+ * @param calleeCount - Number of callees
209
+ * @returns Score and reasons explaining the score
210
+ */
211
+ export function calculateEntryPointScore(name, language, isExported, callerCount, calleeCount, filePath = '' // Optional for backwards compatibility
212
+ ) {
213
+ const reasons = [];
214
+ // Must have outgoing calls to be an entry point
215
+ if (calleeCount === 0) {
216
+ return { score: 0, reasons: ['no-outgoing-calls'] };
217
+ }
218
+ // Base score: call ratio (high = calls many, called by few)
219
+ const baseScore = calleeCount / (callerCount + 1);
220
+ reasons.push(`base:${baseScore.toFixed(2)}`);
221
+ // Export bonus
222
+ const exportMultiplier = isExported ? 2.0 : 1.0;
223
+ if (isExported) {
224
+ reasons.push('exported');
225
+ }
226
+ // Name pattern scoring: check negative patterns first
227
+ let nameMultiplier = 1.0;
228
+ if (UTILITY_PATTERNS.some(p => p.test(name))) {
229
+ nameMultiplier = 0.3;
230
+ reasons.push('utility-pattern');
231
+ }
232
+ else {
233
+ // Check positive entry point patterns
234
+ const allPatterns = MERGED_ENTRY_POINT_PATTERNS[language] || UNIVERSAL_PATTERNS;
235
+ if (allPatterns.some(p => p.test(name))) {
236
+ nameMultiplier = 1.5;
237
+ reasons.push('entry-pattern');
238
+ }
239
+ }
240
+ // Framework detection bonus
241
+ let frameworkMultiplier = 1.0;
242
+ if (filePath) {
243
+ const frameworkHint = detectFrameworkFromPath(filePath);
244
+ if (frameworkHint) {
245
+ frameworkMultiplier = frameworkHint.entryPointMultiplier;
246
+ reasons.push(`framework:${frameworkHint.reason}`);
247
+ }
248
+ }
249
+ // Final score
250
+ const finalScore = baseScore * exportMultiplier * nameMultiplier * frameworkMultiplier;
251
+ return {
252
+ score: finalScore,
253
+ reasons,
254
+ };
255
+ }
256
+ /** Check if a file path is a test file (excluded from entry points) */
257
+ export function isTestFile(filePath) {
258
+ const p = filePath.toLowerCase().replace(/\\/g, '/');
259
+ return (
260
+ // JavaScript/TypeScript test patterns
261
+ p.includes('.test.') ||
262
+ p.includes('.spec.') ||
263
+ p.includes('__tests__/') ||
264
+ p.includes('__mocks__/') ||
265
+ // Generic test folders
266
+ p.includes('/test/') ||
267
+ p.includes('/tests/') ||
268
+ p.includes('/testing/') ||
269
+ // Python test patterns
270
+ p.endsWith('_test.py') ||
271
+ p.includes('/test_') ||
272
+ // Go test patterns
273
+ p.endsWith('_test.go') ||
274
+ // Java test patterns
275
+ p.includes('/src/test/') ||
276
+ // Rust test patterns (inline tests are different, but test files)
277
+ p.includes('/tests/') ||
278
+ // Swift/iOS test patterns
279
+ p.endsWith('tests.swift') ||
280
+ p.endsWith('test.swift') ||
281
+ p.includes('uitests/') ||
282
+ // C# test patterns
283
+ p.endsWith('tests.cs') ||
284
+ p.endsWith('test.cs') ||
285
+ p.includes('.tests/') ||
286
+ p.includes('.test/') ||
287
+ p.includes('.integrationtests/') ||
288
+ p.includes('.unittests/') ||
289
+ p.includes('/testproject/') ||
290
+ // PHP/Laravel test patterns
291
+ p.endsWith('test.php') ||
292
+ p.endsWith('spec.php') ||
293
+ p.includes('/tests/feature/') ||
294
+ p.includes('/tests/unit/') ||
295
+ // Ruby test patterns
296
+ p.endsWith('_spec.rb') ||
297
+ p.endsWith('_test.rb') ||
298
+ p.includes('/spec/') ||
299
+ p.includes('/test/fixtures/'));
300
+ }
301
+ /** Check if a file path is a utility/helper file (lower entry point priority) */
302
+ export function isUtilityFile(filePath) {
303
+ const p = filePath.toLowerCase().replace(/\\/g, '/');
304
+ return (p.includes('/utils/') ||
305
+ p.includes('/util/') ||
306
+ p.includes('/helpers/') ||
307
+ p.includes('/helper/') ||
308
+ p.includes('/common/') ||
309
+ p.includes('/shared/') ||
310
+ p.includes('/lib/') ||
311
+ p.endsWith('/utils.ts') ||
312
+ p.endsWith('/utils.js') ||
313
+ p.endsWith('/helpers.ts') ||
314
+ p.endsWith('/helpers.js') ||
315
+ p.endsWith('_utils.py') ||
316
+ p.endsWith('_helpers.py'));
317
+ }
@@ -0,0 +1,11 @@
1
+ /** @file export-detection.ts @description Per-language detection of whether a symbol is exported/public, pure function safe for worker threads */
2
+ import { SyntaxNode } from './utils.js';
3
+ import { SupportedLanguages } from '../../config/supported-languages.js';
4
+ /**
5
+ * Check if a tree-sitter node is exported/public in its language
6
+ *
7
+ * @param node - The tree-sitter AST node
8
+ * @param name - The symbol name
9
+ * @param language - The programming language
10
+ */
11
+ export declare const isNodeExported: (node: SyntaxNode, name: string, language: SupportedLanguages) => boolean;
@@ -0,0 +1,203 @@
1
+ // code-mapper/src/core/ingestion/export-detection.ts
2
+ /** @file export-detection.ts @description Per-language detection of whether a symbol is exported/public, pure function safe for worker threads */
3
+ import { findSiblingChild } from './utils.js';
4
+ import { SupportedLanguages } from '../../config/supported-languages.js';
5
+ // Per-language export checkers
6
+ // JS/TS: walk ancestors looking for export_statement or export_specifier
7
+ const tsExportChecker = (node, _name) => {
8
+ let current = node;
9
+ while (current) {
10
+ const type = current.type;
11
+ if (type === 'export_statement' ||
12
+ type === 'export_specifier' ||
13
+ (type === 'lexical_declaration' && current.parent?.type === 'export_statement')) {
14
+ return true;
15
+ }
16
+ // Fallback: check if node text starts with 'export '
17
+ if (current.text?.startsWith('export ')) {
18
+ return true;
19
+ }
20
+ current = current.parent;
21
+ }
22
+ return false;
23
+ };
24
+ // Python: public if no leading underscore (convention)
25
+ const pythonExportChecker = (_node, name) => !name.startsWith('_');
26
+ // Java: check for 'public' modifier (sibling of name node)
27
+ const javaExportChecker = (node, _name) => {
28
+ let current = node;
29
+ while (current) {
30
+ if (current.parent) {
31
+ const parent = current.parent;
32
+ for (let i = 0; i < parent.childCount; i++) {
33
+ const child = parent.child(i);
34
+ if (child?.type === 'modifiers' && child.text?.includes('public')) {
35
+ return true;
36
+ }
37
+ }
38
+ if (parent.type === 'method_declaration' || parent.type === 'constructor_declaration') {
39
+ if (parent.text?.trimStart().startsWith('public')) {
40
+ return true;
41
+ }
42
+ }
43
+ }
44
+ current = current.parent;
45
+ }
46
+ return false;
47
+ };
48
+ // C# declaration node types for sibling modifier scanning
49
+ const CSHARP_DECL_TYPES = new Set([
50
+ 'method_declaration', 'local_function_statement', 'constructor_declaration',
51
+ 'class_declaration', 'interface_declaration', 'struct_declaration',
52
+ 'enum_declaration', 'record_declaration', 'record_struct_declaration',
53
+ 'record_class_declaration', 'delegate_declaration',
54
+ 'property_declaration', 'field_declaration', 'event_declaration',
55
+ 'namespace_declaration', 'file_scoped_namespace_declaration',
56
+ ]);
57
+ // C#: walk up to declaration node, scan children for 'public' modifier
58
+ const csharpExportChecker = (node, _name) => {
59
+ let current = node;
60
+ while (current) {
61
+ if (CSHARP_DECL_TYPES.has(current.type)) {
62
+ for (let i = 0; i < current.childCount; i++) {
63
+ const child = current.child(i);
64
+ if (child?.type === 'modifier' && child.text === 'public')
65
+ return true;
66
+ }
67
+ return false;
68
+ }
69
+ current = current.parent;
70
+ }
71
+ return false;
72
+ };
73
+ // Go: uppercase first letter = exported
74
+ const goExportChecker = (_node, name) => {
75
+ if (name.length === 0)
76
+ return false;
77
+ const first = name[0];
78
+ return first === first.toUpperCase() && first !== first.toLowerCase();
79
+ };
80
+ // Rust declaration node types for visibility_modifier scanning
81
+ const RUST_DECL_TYPES = new Set([
82
+ 'function_item', 'struct_item', 'enum_item', 'trait_item', 'impl_item',
83
+ 'union_item', 'type_item', 'const_item', 'static_item', 'mod_item',
84
+ 'use_declaration', 'associated_type', 'function_signature_item',
85
+ ]);
86
+ // Rust: walk up to declaration node, scan children for 'pub' visibility_modifier
87
+ const rustExportChecker = (node, _name) => {
88
+ let current = node;
89
+ while (current) {
90
+ if (RUST_DECL_TYPES.has(current.type)) {
91
+ for (let i = 0; i < current.childCount; i++) {
92
+ const child = current.child(i);
93
+ if (child?.type === 'visibility_modifier' && child.text?.startsWith('pub'))
94
+ return true;
95
+ }
96
+ return false;
97
+ }
98
+ current = current.parent;
99
+ }
100
+ return false;
101
+ };
102
+ // Kotlin: default visibility is public; check for private/internal/protected modifiers
103
+ const kotlinExportChecker = (node, _name) => {
104
+ let current = node;
105
+ while (current) {
106
+ if (current.parent) {
107
+ const visMod = findSiblingChild(current.parent, 'modifiers', 'visibility_modifier');
108
+ if (visMod) {
109
+ const text = visMod.text;
110
+ if (text === 'private' || text === 'internal' || text === 'protected')
111
+ return false;
112
+ if (text === 'public')
113
+ return true;
114
+ }
115
+ }
116
+ current = current.parent;
117
+ }
118
+ // No visibility modifier = public in Kotlin
119
+ return true;
120
+ };
121
+ // C/C++: non-static functions have external linkage (exported by default)
122
+ // C++ anonymous namespaces also give internal linkage
123
+ const cCppExportChecker = (node, _name) => {
124
+ let cur = node;
125
+ while (cur) {
126
+ if (cur.type === 'function_definition' || cur.type === 'declaration') {
127
+ // Check for 'static' storage class specifier as a direct child node
128
+ for (let i = 0; i < cur.childCount; i++) {
129
+ const child = cur.child(i);
130
+ if (child?.type === 'storage_class_specifier' && child.text === 'static')
131
+ return false;
132
+ }
133
+ }
134
+ // C++ anonymous namespace = internal linkage
135
+ if (cur.type === 'namespace_definition') {
136
+ const hasName = cur.childForFieldName?.('name');
137
+ if (!hasName)
138
+ return false;
139
+ }
140
+ cur = cur.parent;
141
+ }
142
+ return true;
143
+ };
144
+ // PHP: check for visibility modifier or top-level scope
145
+ const phpExportChecker = (node, _name) => {
146
+ let current = node;
147
+ while (current) {
148
+ if (current.type === 'class_declaration' ||
149
+ current.type === 'interface_declaration' ||
150
+ current.type === 'trait_declaration' ||
151
+ current.type === 'enum_declaration') {
152
+ return true;
153
+ }
154
+ if (current.type === 'visibility_modifier') {
155
+ return current.text === 'public';
156
+ }
157
+ current = current.parent;
158
+ }
159
+ // Top-level functions are globally accessible in PHP
160
+ return true;
161
+ };
162
+ // Swift: check for 'public' or 'open' access modifiers
163
+ const swiftExportChecker = (node, _name) => {
164
+ let current = node;
165
+ while (current) {
166
+ if (current.type === 'modifiers' || current.type === 'visibility_modifier') {
167
+ const text = current.text || '';
168
+ if (text.includes('public') || text.includes('open'))
169
+ return true;
170
+ }
171
+ current = current.parent;
172
+ }
173
+ return false;
174
+ };
175
+ // Exhaustive dispatch table covering all SupportedLanguages
176
+ const exportCheckers = {
177
+ [SupportedLanguages.JavaScript]: tsExportChecker,
178
+ [SupportedLanguages.TypeScript]: tsExportChecker,
179
+ [SupportedLanguages.Python]: pythonExportChecker,
180
+ [SupportedLanguages.Java]: javaExportChecker,
181
+ [SupportedLanguages.CSharp]: csharpExportChecker,
182
+ [SupportedLanguages.Go]: goExportChecker,
183
+ [SupportedLanguages.Rust]: rustExportChecker,
184
+ [SupportedLanguages.Kotlin]: kotlinExportChecker,
185
+ [SupportedLanguages.C]: cCppExportChecker,
186
+ [SupportedLanguages.CPlusPlus]: cCppExportChecker,
187
+ [SupportedLanguages.PHP]: phpExportChecker,
188
+ [SupportedLanguages.Swift]: swiftExportChecker,
189
+ [SupportedLanguages.Ruby]: (_node, _name) => true,
190
+ };
191
+ /**
192
+ * Check if a tree-sitter node is exported/public in its language
193
+ *
194
+ * @param node - The tree-sitter AST node
195
+ * @param name - The symbol name
196
+ * @param language - The programming language
197
+ */
198
+ export const isNodeExported = (node, name, language) => {
199
+ const checker = exportCheckers[language];
200
+ if (!checker)
201
+ return false;
202
+ return checker(node, name);
203
+ };
@@ -0,0 +1,18 @@
1
+ /** @file filesystem-walker.ts @description Scans repository files with ignore filtering and batched concurrent reads */
2
+ export interface FileEntry {
3
+ path: string;
4
+ content: string;
5
+ }
6
+ export interface ScannedFile {
7
+ path: string;
8
+ size: number;
9
+ }
10
+ export interface FilePath {
11
+ path: string;
12
+ }
13
+ /** Scan repository: stat files to get paths + sizes, no content loaded (~10MB for 100K files) */
14
+ export declare const walkRepositoryPaths: (repoPath: string, onProgress?: (current: number, total: number, filePath: string) => void) => Promise<ScannedFile[]>;
15
+ /** Read file contents for a set of relative paths, returning a Map for O(1) lookup */
16
+ export declare const readFileContents: (repoPath: string, relativePaths: string[]) => Promise<Map<string, string>>;
17
+ /** Legacy API: scans and reads everything into memory (sequential fallback only) */
18
+ export declare const walkRepository: (repoPath: string, onProgress?: (current: number, total: number, filePath: string) => void) => Promise<FileEntry[]>;
@@ -0,0 +1,64 @@
1
+ // code-mapper/src/core/ingestion/filesystem-walker.ts
2
+ /** @file filesystem-walker.ts @description Scans repository files with ignore filtering and batched concurrent reads */
3
+ import fs from 'fs/promises';
4
+ import path from 'path';
5
+ import { glob } from 'glob';
6
+ import { createIgnoreFilter } from '../../config/ignore-service.js';
7
+ const READ_CONCURRENCY = 32;
8
+ /** Scan repository: stat files to get paths + sizes, no content loaded (~10MB for 100K files) */
9
+ export const walkRepositoryPaths = async (repoPath, onProgress) => {
10
+ const ignoreFilter = await createIgnoreFilter(repoPath);
11
+ const filtered = await glob('**/*', {
12
+ cwd: repoPath,
13
+ nodir: true,
14
+ dot: false,
15
+ ignore: ignoreFilter,
16
+ });
17
+ const entries = [];
18
+ let processed = 0;
19
+ for (let start = 0; start < filtered.length; start += READ_CONCURRENCY) {
20
+ const batch = filtered.slice(start, start + READ_CONCURRENCY);
21
+ const results = await Promise.allSettled(batch.map(async (relativePath) => {
22
+ const fullPath = path.join(repoPath, relativePath);
23
+ const stat = await fs.stat(fullPath);
24
+ return { path: relativePath.replace(/\\/g, '/'), size: stat.size };
25
+ }));
26
+ for (const result of results) {
27
+ processed++;
28
+ if (result.status === 'fulfilled' && result.value !== null) {
29
+ entries.push(result.value);
30
+ onProgress?.(processed, filtered.length, result.value.path);
31
+ }
32
+ else {
33
+ onProgress?.(processed, filtered.length, batch[results.indexOf(result)]);
34
+ }
35
+ }
36
+ }
37
+ return entries;
38
+ };
39
+ /** Read file contents for a set of relative paths, returning a Map for O(1) lookup */
40
+ export const readFileContents = async (repoPath, relativePaths) => {
41
+ const contents = new Map();
42
+ for (let start = 0; start < relativePaths.length; start += READ_CONCURRENCY) {
43
+ const batch = relativePaths.slice(start, start + READ_CONCURRENCY);
44
+ const results = await Promise.allSettled(batch.map(async (relativePath) => {
45
+ const fullPath = path.join(repoPath, relativePath);
46
+ const content = await fs.readFile(fullPath, 'utf-8');
47
+ return { path: relativePath, content };
48
+ }));
49
+ for (const result of results) {
50
+ if (result.status === 'fulfilled') {
51
+ contents.set(result.value.path, result.value.content);
52
+ }
53
+ }
54
+ }
55
+ return contents;
56
+ };
57
+ /** Legacy API: scans and reads everything into memory (sequential fallback only) */
58
+ export const walkRepository = async (repoPath, onProgress) => {
59
+ const scanned = await walkRepositoryPaths(repoPath, onProgress);
60
+ const contents = await readFileContents(repoPath, scanned.map(f => f.path));
61
+ return scanned
62
+ .filter(f => contents.has(f.path))
63
+ .map(f => ({ path: f.path, content: contents.get(f.path) }));
64
+ };
@@ -0,0 +1,42 @@
1
+ /** @file framework-detection.ts @description Detects frameworks from file path patterns and AST definition text (decorators/annotations/attributes), returning entry point multipliers for process scoring. Returns null for unknown frameworks, yielding a 1.0 multiplier (no bonus, no penalty) */
2
+ export interface FrameworkHint {
3
+ framework: string;
4
+ entryPointMultiplier: number;
5
+ reason: string;
6
+ }
7
+ /** Detect framework from file path conventions, returning an entry point multiplier or null */
8
+ export declare function detectFrameworkFromPath(filePath: string): FrameworkHint | null;
9
+ export declare const FRAMEWORK_AST_PATTERNS: {
10
+ nestjs: string[];
11
+ express: string[];
12
+ fastapi: string[];
13
+ flask: string[];
14
+ spring: string[];
15
+ jaxrs: string[];
16
+ aspnet: string[];
17
+ signalr: string[];
18
+ blazor: string[];
19
+ efcore: string[];
20
+ 'go-http': string[];
21
+ laravel: string[];
22
+ actix: string[];
23
+ axum: string[];
24
+ rocket: string[];
25
+ uikit: string[];
26
+ swiftui: string[];
27
+ combine: string[];
28
+ 'nestjs-di': string[];
29
+ 'angular-di': string[];
30
+ 'spring-di': string[];
31
+ 'dagger-di': string[];
32
+ 'aspnet-di': string[];
33
+ 'python-di': string[];
34
+ };
35
+ import { SupportedLanguages } from '../../config/supported-languages.js';
36
+ /**
37
+ * Detect framework entry points from AST definition text (decorators/annotations/attributes)
38
+ * @param language - Source language
39
+ * @param definitionText - AST node text (callers should slice to ~300 chars)
40
+ * @returns FrameworkHint or null if no known pattern matches
41
+ */
42
+ export declare function detectFrameworkFromAST(language: SupportedLanguages, definitionText: string): FrameworkHint | null;