@codeyam/codeyam-cli 0.1.0-staging.8e7b1bd → 0.1.0-staging.b8a55ba

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 (385) hide show
  1. package/analyzer-template/.build-info.json +7 -7
  2. package/analyzer-template/log.txt +3 -3
  3. package/analyzer-template/package.json +7 -6
  4. package/analyzer-template/packages/ai/package.json +1 -1
  5. package/analyzer-template/packages/ai/src/lib/analyzeScope.ts +2 -0
  6. package/analyzer-template/packages/ai/src/lib/astScopes/astScopeAnalyzer.ts +22 -0
  7. package/analyzer-template/packages/ai/src/lib/astScopes/patterns/switchStatementHandler.ts +23 -1
  8. package/analyzer-template/packages/ai/src/lib/astScopes/processExpression.ts +401 -106
  9. package/analyzer-template/packages/ai/src/lib/astScopes/types.ts +60 -0
  10. package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +661 -50
  11. package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.ts +14 -2
  12. package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/MuiManager.ts +715 -0
  13. package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.ts +123 -1
  14. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.ts +19 -1
  15. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.ts +23 -1
  16. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.ts +23 -0
  17. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.ts +34 -1
  18. package/analyzer-template/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.ts +236 -24
  19. package/analyzer-template/packages/ai/src/lib/generateChangesEntityKeyAttributes.ts +18 -1
  20. package/analyzer-template/packages/ai/src/lib/generateChangesEntityScenarios.ts +37 -4
  21. package/analyzer-template/packages/ai/src/lib/generateEntityDataStructure.ts +5 -0
  22. package/analyzer-template/packages/ai/src/lib/generateEntityKeyAttributes.ts +213 -12
  23. package/analyzer-template/packages/ai/src/lib/generateEntityScenarioData.ts +11 -15
  24. package/analyzer-template/packages/ai/src/lib/generateEntityScenarios.ts +114 -11
  25. package/analyzer-template/packages/ai/src/lib/getConditionalUsagesFromCode.ts +143 -31
  26. package/analyzer-template/packages/ai/src/lib/guessScenarioDataFromDescription.ts +8 -2
  27. package/analyzer-template/packages/ai/src/lib/promptGenerators/gatherAttributesMap.ts +7 -0
  28. package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.ts +42 -2
  29. package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.ts +38 -2
  30. package/analyzer-template/packages/ai/src/lib/promptGenerators/guessNewScenarioDataFromDescriptionGenerator.ts +28 -2
  31. package/analyzer-template/packages/ai/src/lib/worker/SerializableDataStructure.ts +5 -0
  32. package/analyzer-template/packages/ai/src/lib/worker/analyzeScopeWorker.ts +8 -1
  33. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +339 -145
  34. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +20 -0
  35. package/analyzer-template/packages/analyze/src/lib/files/getImportedExports.ts +8 -1
  36. package/analyzer-template/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.ts +158 -0
  37. package/analyzer-template/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.ts +107 -18
  38. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateChangesScenarioData.ts +1 -1
  39. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +223 -103
  40. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.ts +10 -5
  41. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarioData.ts +172 -83
  42. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarios.ts +2 -5
  43. package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +97 -27
  44. package/analyzer-template/packages/aws/dist/src/lib/s3/checkS3ObjectExists.d.ts +15 -0
  45. package/analyzer-template/packages/aws/dist/src/lib/s3/checkS3ObjectExists.d.ts.map +1 -0
  46. package/analyzer-template/packages/aws/dist/src/lib/s3/checkS3ObjectExists.js +31 -0
  47. package/analyzer-template/packages/aws/dist/src/lib/s3/checkS3ObjectExists.js.map +1 -0
  48. package/analyzer-template/packages/aws/package.json +1 -1
  49. package/analyzer-template/packages/aws/s3/index.ts +1 -0
  50. package/analyzer-template/packages/aws/src/lib/s3/checkS3ObjectExists.ts +47 -0
  51. package/analyzer-template/packages/database/src/lib/kysely/db.ts +4 -4
  52. package/analyzer-template/packages/database/src/lib/kysely/tableRelations.ts +2 -2
  53. package/analyzer-template/packages/database/src/lib/kysely/tables/debugReportsTable.ts +20 -9
  54. package/analyzer-template/packages/database/src/lib/loadReadyToBeCapturedAnalyses.ts +3 -2
  55. package/analyzer-template/packages/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.ts +9 -4
  56. package/analyzer-template/packages/generate/src/lib/deepMerge.ts +26 -1
  57. package/analyzer-template/packages/generate/src/lib/getComponentScenarioPath.ts +8 -3
  58. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts +2 -2
  59. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js +2 -2
  60. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tableRelations.d.ts +2 -2
  61. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/analysesTable.d.ts +8 -1
  62. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/analysesTable.d.ts.map +1 -1
  63. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.d.ts +14 -7
  64. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.d.ts.map +1 -1
  65. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.js +9 -3
  66. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.js.map +1 -1
  67. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/scenariosTable.d.ts +1 -1
  68. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/scenariosTable.d.ts.map +1 -1
  69. package/analyzer-template/packages/github/dist/database/src/lib/loadReadyToBeCapturedAnalyses.d.ts.map +1 -1
  70. package/analyzer-template/packages/github/dist/database/src/lib/loadReadyToBeCapturedAnalyses.js +4 -2
  71. package/analyzer-template/packages/github/dist/database/src/lib/loadReadyToBeCapturedAnalyses.js.map +1 -1
  72. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.d.ts.map +1 -1
  73. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js +8 -4
  74. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js.map +1 -1
  75. package/analyzer-template/packages/github/dist/generate/src/lib/deepMerge.d.ts.map +1 -1
  76. package/analyzer-template/packages/github/dist/generate/src/lib/deepMerge.js +27 -1
  77. package/analyzer-template/packages/github/dist/generate/src/lib/deepMerge.js.map +1 -1
  78. package/analyzer-template/packages/github/dist/generate/src/lib/getComponentScenarioPath.d.ts.map +1 -1
  79. package/analyzer-template/packages/github/dist/generate/src/lib/getComponentScenarioPath.js +7 -3
  80. package/analyzer-template/packages/github/dist/generate/src/lib/getComponentScenarioPath.js.map +1 -1
  81. package/analyzer-template/packages/github/dist/types/index.d.ts +4 -3
  82. package/analyzer-template/packages/github/dist/types/index.d.ts.map +1 -1
  83. package/analyzer-template/packages/github/dist/types/index.js +1 -0
  84. package/analyzer-template/packages/github/dist/types/index.js.map +1 -1
  85. package/analyzer-template/packages/github/dist/types/src/types/Analysis.d.ts +31 -1
  86. package/analyzer-template/packages/github/dist/types/src/types/Analysis.d.ts.map +1 -1
  87. package/analyzer-template/packages/github/dist/types/src/types/Scenario.d.ts +51 -1
  88. package/analyzer-template/packages/github/dist/types/src/types/Scenario.d.ts.map +1 -1
  89. package/analyzer-template/packages/github/dist/types/src/types/Scenario.js +21 -1
  90. package/analyzer-template/packages/github/dist/types/src/types/Scenario.js.map +1 -1
  91. package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts +48 -0
  92. package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
  93. package/analyzer-template/packages/github/dist/utils/src/lib/applyUniversalMocks.d.ts.map +1 -1
  94. package/analyzer-template/packages/github/dist/utils/src/lib/applyUniversalMocks.js +26 -2
  95. package/analyzer-template/packages/github/dist/utils/src/lib/applyUniversalMocks.js.map +1 -1
  96. package/analyzer-template/packages/github/dist/utils/src/lib/lightweightEntityExtractor.d.ts.map +1 -1
  97. package/analyzer-template/packages/github/dist/utils/src/lib/lightweightEntityExtractor.js +25 -0
  98. package/analyzer-template/packages/github/dist/utils/src/lib/lightweightEntityExtractor.js.map +1 -1
  99. package/analyzer-template/packages/types/index.ts +8 -0
  100. package/analyzer-template/packages/types/src/types/Analysis.ts +32 -1
  101. package/analyzer-template/packages/types/src/types/Scenario.ts +75 -6
  102. package/analyzer-template/packages/types/src/types/ScenariosDataStructure.ts +49 -0
  103. package/analyzer-template/packages/ui-components/package.json +4 -4
  104. package/analyzer-template/packages/ui-components/src/components/ScenarioDetailInteractiveView.tsx +23 -7
  105. package/analyzer-template/packages/utils/dist/types/index.d.ts +4 -3
  106. package/analyzer-template/packages/utils/dist/types/index.d.ts.map +1 -1
  107. package/analyzer-template/packages/utils/dist/types/index.js +1 -0
  108. package/analyzer-template/packages/utils/dist/types/index.js.map +1 -1
  109. package/analyzer-template/packages/utils/dist/types/src/types/Analysis.d.ts +31 -1
  110. package/analyzer-template/packages/utils/dist/types/src/types/Analysis.d.ts.map +1 -1
  111. package/analyzer-template/packages/utils/dist/types/src/types/Scenario.d.ts +51 -1
  112. package/analyzer-template/packages/utils/dist/types/src/types/Scenario.d.ts.map +1 -1
  113. package/analyzer-template/packages/utils/dist/types/src/types/Scenario.js +21 -1
  114. package/analyzer-template/packages/utils/dist/types/src/types/Scenario.js.map +1 -1
  115. package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts +48 -0
  116. package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
  117. package/analyzer-template/packages/utils/dist/utils/src/lib/applyUniversalMocks.d.ts.map +1 -1
  118. package/analyzer-template/packages/utils/dist/utils/src/lib/applyUniversalMocks.js +26 -2
  119. package/analyzer-template/packages/utils/dist/utils/src/lib/applyUniversalMocks.js.map +1 -1
  120. package/analyzer-template/packages/utils/dist/utils/src/lib/lightweightEntityExtractor.d.ts.map +1 -1
  121. package/analyzer-template/packages/utils/dist/utils/src/lib/lightweightEntityExtractor.js +25 -0
  122. package/analyzer-template/packages/utils/dist/utils/src/lib/lightweightEntityExtractor.js.map +1 -1
  123. package/analyzer-template/packages/utils/src/lib/applyUniversalMocks.ts +28 -2
  124. package/analyzer-template/packages/utils/src/lib/lightweightEntityExtractor.ts +27 -0
  125. package/analyzer-template/playwright/takeElementScreenshot.ts +26 -11
  126. package/analyzer-template/playwright/takeScreenshot.ts +9 -7
  127. package/analyzer-template/project/TESTING.md +83 -0
  128. package/analyzer-template/project/constructMockCode.ts +151 -30
  129. package/analyzer-template/project/loadReadyToBeCaptured.ts +17 -1
  130. package/analyzer-template/project/orchestrateCapture/KyselyAnalysisLoader.ts +16 -9
  131. package/analyzer-template/project/orchestrateCapture/SequentialCaptureTaskRunner.ts +77 -37
  132. package/analyzer-template/project/reconcileMockDataKeys.ts +104 -3
  133. package/analyzer-template/project/runMultiScenarioServer.ts +11 -10
  134. package/analyzer-template/project/serverOnlyModules.ts +288 -0
  135. package/analyzer-template/project/start.ts +10 -0
  136. package/analyzer-template/project/startScenarioCapture.ts +73 -41
  137. package/analyzer-template/project/writeMockDataTsx.ts +103 -40
  138. package/analyzer-template/project/writeScenarioComponents.ts +1162 -203
  139. package/analyzer-template/project/writeSimpleRoot.ts +26 -4
  140. package/analyzer-template/project/writeUniversalMocks.ts +32 -11
  141. package/background/src/lib/virtualized/project/constructMockCode.js +132 -25
  142. package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
  143. package/background/src/lib/virtualized/project/loadReadyToBeCaptured.js +15 -1
  144. package/background/src/lib/virtualized/project/loadReadyToBeCaptured.js.map +1 -1
  145. package/background/src/lib/virtualized/project/orchestrateCapture/KyselyAnalysisLoader.js +11 -6
  146. package/background/src/lib/virtualized/project/orchestrateCapture/KyselyAnalysisLoader.js.map +1 -1
  147. package/background/src/lib/virtualized/project/orchestrateCapture/SequentialCaptureTaskRunner.js +67 -32
  148. package/background/src/lib/virtualized/project/orchestrateCapture/SequentialCaptureTaskRunner.js.map +1 -1
  149. package/background/src/lib/virtualized/project/reconcileMockDataKeys.js +65 -4
  150. package/background/src/lib/virtualized/project/reconcileMockDataKeys.js.map +1 -1
  151. package/background/src/lib/virtualized/project/runMultiScenarioServer.js +11 -9
  152. package/background/src/lib/virtualized/project/runMultiScenarioServer.js.map +1 -1
  153. package/background/src/lib/virtualized/project/serverOnlyModules.js +235 -0
  154. package/background/src/lib/virtualized/project/serverOnlyModules.js.map +1 -0
  155. package/background/src/lib/virtualized/project/start.js +6 -0
  156. package/background/src/lib/virtualized/project/start.js.map +1 -1
  157. package/background/src/lib/virtualized/project/startScenarioCapture.js +54 -31
  158. package/background/src/lib/virtualized/project/startScenarioCapture.js.map +1 -1
  159. package/background/src/lib/virtualized/project/writeMockDataTsx.js +87 -34
  160. package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
  161. package/background/src/lib/virtualized/project/writeScenarioComponents.js +852 -133
  162. package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
  163. package/background/src/lib/virtualized/project/writeSimpleRoot.js +25 -2
  164. package/background/src/lib/virtualized/project/writeSimpleRoot.js.map +1 -1
  165. package/background/src/lib/virtualized/project/writeUniversalMocks.js +27 -12
  166. package/background/src/lib/virtualized/project/writeUniversalMocks.js.map +1 -1
  167. package/codeyam-cli/scripts/fixtures/formbricks/universal-mocks/apps/web/lib/instance/service.js +7 -0
  168. package/codeyam-cli/scripts/fixtures/formbricks/universal-mocks/apps/web/lib/instance/service.js.map +1 -0
  169. package/codeyam-cli/src/cli.js +2 -0
  170. package/codeyam-cli/src/cli.js.map +1 -1
  171. package/codeyam-cli/src/commands/debug.js +14 -2
  172. package/codeyam-cli/src/commands/debug.js.map +1 -1
  173. package/codeyam-cli/src/commands/recapture.js +215 -0
  174. package/codeyam-cli/src/commands/recapture.js.map +1 -0
  175. package/codeyam-cli/src/commands/report.js +26 -23
  176. package/codeyam-cli/src/commands/report.js.map +1 -1
  177. package/codeyam-cli/src/utils/backgroundServer.js +2 -2
  178. package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
  179. package/codeyam-cli/src/utils/generateReport.js +252 -106
  180. package/codeyam-cli/src/utils/generateReport.js.map +1 -1
  181. package/codeyam-cli/src/utils/install-skills.js +2 -7
  182. package/codeyam-cli/src/utils/install-skills.js.map +1 -1
  183. package/codeyam-cli/src/utils/queue/__tests__/manager.test.js +38 -0
  184. package/codeyam-cli/src/utils/queue/__tests__/manager.test.js.map +1 -1
  185. package/codeyam-cli/src/utils/queue/job.js +140 -16
  186. package/codeyam-cli/src/utils/queue/job.js.map +1 -1
  187. package/codeyam-cli/src/utils/queue/manager.js +19 -7
  188. package/codeyam-cli/src/utils/queue/manager.js.map +1 -1
  189. package/codeyam-cli/src/utils/queue/persistence.js.map +1 -1
  190. package/codeyam-cli/src/webserver/app/lib/database.js +47 -0
  191. package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
  192. package/codeyam-cli/src/webserver/app/lib/dbNotifier.js.map +1 -1
  193. package/codeyam-cli/src/webserver/backgroundServer.js +5 -10
  194. package/codeyam-cli/src/webserver/backgroundServer.js.map +1 -1
  195. package/codeyam-cli/src/webserver/bootstrap.js +9 -0
  196. package/codeyam-cli/src/webserver/bootstrap.js.map +1 -0
  197. package/codeyam-cli/src/webserver/build/client/assets/EntityItem-wXL1Z2Aq.js +1 -0
  198. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeBadge-DQeyk25_.js → EntityTypeBadge-CzGX-miz.js} +1 -1
  199. package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-CXFKsCOD.js +41 -0
  200. package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-D-9pXIaY.js +25 -0
  201. package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-CBQPrpT0.js +3 -0
  202. package/codeyam-cli/src/webserver/build/client/assets/LoadingDots-D1CdlbrV.js +6 -0
  203. package/codeyam-cli/src/webserver/build/client/assets/LogViewer-wDPcZNKx.js +3 -0
  204. package/codeyam-cli/src/webserver/build/client/assets/ReportIssueModal-4lcOlid-.js +11 -0
  205. package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-BfmDgXxG.js +1 -0
  206. package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-CUxUNEEC.js +15 -0
  207. package/codeyam-cli/src/webserver/build/client/assets/{TruncatedFilePath-ayCJdUAc.js → TruncatedFilePath-6J7zDUD5.js} +1 -1
  208. package/codeyam-cli/src/webserver/build/client/assets/_index-DHImXdXq.js +11 -0
  209. package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-2mG6mjVb.js +32 -0
  210. package/codeyam-cli/src/webserver/build/client/assets/api.link-scenario-value-l0sNRNKZ.js +1 -0
  211. package/codeyam-cli/src/webserver/build/client/assets/api.update-key-attributes-l0sNRNKZ.js +1 -0
  212. package/codeyam-cli/src/webserver/build/client/assets/api.update-valid-values-l0sNRNKZ.js +1 -0
  213. package/codeyam-cli/src/webserver/build/client/assets/chevron-down-BYimnrHg.js +6 -0
  214. package/codeyam-cli/src/webserver/build/client/assets/chunk-JMJ3UQ3L-BambyYE_.js +51 -0
  215. package/codeyam-cli/src/webserver/build/client/assets/circle-check-CaVsIRxt.js +6 -0
  216. package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-CgUsG7ib.js +21 -0
  217. package/codeyam-cli/src/webserver/build/client/assets/cy-logo-cli-CKnwPCDr.js +1 -0
  218. package/codeyam-cli/src/webserver/build/client/assets/dev.empty-DW_hdGUc.js +1 -0
  219. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-FHOVOgFN.js → entity._sha._-zUEpfPsu.js} +22 -15
  220. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.fullscreen-DyB90fWk.js +1 -0
  221. package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-D_3ero5o.js +1 -0
  222. package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-CfLCUi9S.js +5 -0
  223. package/codeyam-cli/src/webserver/build/client/assets/entry.client-DKJyZfAY.js +29 -0
  224. package/codeyam-cli/src/webserver/build/client/assets/fileTableUtils-DAtOlaWE.js +1 -0
  225. package/codeyam-cli/src/webserver/build/client/assets/files-ClR0d32A.js +1 -0
  226. package/codeyam-cli/src/webserver/build/client/assets/git-D62Lxxmv.js +15 -0
  227. package/codeyam-cli/src/webserver/build/client/assets/globals-C6vQASxy.css +1 -0
  228. package/codeyam-cli/src/webserver/build/client/assets/html2canvas-pro.esm-fmIEn3Bc.js +9 -0
  229. package/codeyam-cli/src/webserver/build/client/assets/index-BosqDOlH.js +3 -0
  230. package/codeyam-cli/src/webserver/build/client/assets/index-CzNNiTkw.js +9 -0
  231. package/codeyam-cli/src/webserver/build/client/assets/keyAttributeCoverage-CTlFMihX.js +1 -0
  232. package/codeyam-cli/src/webserver/build/client/assets/loader-circle-CNp9QFCX.js +6 -0
  233. package/codeyam-cli/src/webserver/build/client/assets/manifest-09d684be.js +1 -0
  234. package/codeyam-cli/src/webserver/build/client/assets/preload-helper-ckwbz45p.js +1 -0
  235. package/codeyam-cli/src/webserver/build/client/assets/root-BxJUvKau.js +56 -0
  236. package/codeyam-cli/src/webserver/build/client/assets/scenarioStatus-B_8jpV3e.js +1 -0
  237. package/codeyam-cli/src/webserver/build/client/assets/search-DDGjYAMJ.js +6 -0
  238. package/codeyam-cli/src/webserver/build/client/assets/settings-DgTyB-Wg.js +1 -0
  239. package/codeyam-cli/src/webserver/build/client/assets/simulations-CoNWGt0K.js +1 -0
  240. package/codeyam-cli/src/webserver/build/client/assets/triangle-alert-CBc5dE1s.js +6 -0
  241. package/codeyam-cli/src/webserver/build/client/assets/useCustomSizes-BMIGFP-m.js +1 -0
  242. package/codeyam-cli/src/webserver/build/client/assets/useInteractiveMode-Dk_FQqWJ.js +1 -0
  243. package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-DOGXmJcI.js → useLastLogLine-BqPPNjAl.js} +1 -1
  244. package/codeyam-cli/src/webserver/build/client/assets/useReportContext-DsJbgMY9.js +1 -0
  245. package/codeyam-cli/src/webserver/build/client/assets/{useToast-C07gRg7Z.js → useToast-DWHcCcl1.js} +1 -1
  246. package/codeyam-cli/src/webserver/build/server/assets/index-CV6i1S1A.js +1 -0
  247. package/codeyam-cli/src/webserver/build/server/assets/server-build-BDlyhfrv.js +175 -0
  248. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  249. package/codeyam-cli/src/webserver/build-info.json +5 -5
  250. package/codeyam-cli/src/webserver/devServer.js +1 -3
  251. package/codeyam-cli/src/webserver/devServer.js.map +1 -1
  252. package/codeyam-cli/templates/debug-codeyam.md +620 -0
  253. package/package.json +14 -14
  254. package/packages/ai/src/lib/analyzeScope.js +2 -0
  255. package/packages/ai/src/lib/analyzeScope.js.map +1 -1
  256. package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js +16 -0
  257. package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js.map +1 -1
  258. package/packages/ai/src/lib/astScopes/patterns/switchStatementHandler.js +16 -0
  259. package/packages/ai/src/lib/astScopes/patterns/switchStatementHandler.js.map +1 -1
  260. package/packages/ai/src/lib/astScopes/processExpression.js +305 -88
  261. package/packages/ai/src/lib/astScopes/processExpression.js.map +1 -1
  262. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +523 -42
  263. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
  264. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js +12 -2
  265. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js.map +1 -1
  266. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/MuiManager.js +454 -0
  267. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/MuiManager.js.map +1 -0
  268. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.js +103 -1
  269. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.js.map +1 -1
  270. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js +16 -1
  271. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js.map +1 -1
  272. package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js +19 -1
  273. package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js.map +1 -1
  274. package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js +20 -0
  275. package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js.map +1 -1
  276. package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js +28 -2
  277. package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js.map +1 -1
  278. package/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.js +179 -17
  279. package/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.js.map +1 -1
  280. package/packages/ai/src/lib/generateChangesEntityKeyAttributes.js +6 -0
  281. package/packages/ai/src/lib/generateChangesEntityKeyAttributes.js.map +1 -1
  282. package/packages/ai/src/lib/generateChangesEntityScenarios.js +37 -4
  283. package/packages/ai/src/lib/generateChangesEntityScenarios.js.map +1 -1
  284. package/packages/ai/src/lib/generateEntityDataStructure.js +4 -0
  285. package/packages/ai/src/lib/generateEntityDataStructure.js.map +1 -1
  286. package/packages/ai/src/lib/generateEntityKeyAttributes.js +176 -9
  287. package/packages/ai/src/lib/generateEntityKeyAttributes.js.map +1 -1
  288. package/packages/ai/src/lib/generateEntityScenarioData.js +11 -15
  289. package/packages/ai/src/lib/generateEntityScenarioData.js.map +1 -1
  290. package/packages/ai/src/lib/generateEntityScenarios.js +105 -9
  291. package/packages/ai/src/lib/generateEntityScenarios.js.map +1 -1
  292. package/packages/ai/src/lib/getConditionalUsagesFromCode.js +84 -14
  293. package/packages/ai/src/lib/getConditionalUsagesFromCode.js.map +1 -1
  294. package/packages/ai/src/lib/guessScenarioDataFromDescription.js +2 -1
  295. package/packages/ai/src/lib/guessScenarioDataFromDescription.js.map +1 -1
  296. package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js +6 -0
  297. package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js.map +1 -1
  298. package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.js +38 -2
  299. package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.js.map +1 -1
  300. package/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.js +38 -2
  301. package/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.js.map +1 -1
  302. package/packages/ai/src/lib/promptGenerators/guessNewScenarioDataFromDescriptionGenerator.js +16 -3
  303. package/packages/ai/src/lib/promptGenerators/guessNewScenarioDataFromDescriptionGenerator.js.map +1 -1
  304. package/packages/ai/src/lib/worker/SerializableDataStructure.js.map +1 -1
  305. package/packages/ai/src/lib/worker/analyzeScopeWorker.js +4 -0
  306. package/packages/ai/src/lib/worker/analyzeScopeWorker.js.map +1 -1
  307. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +258 -110
  308. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
  309. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +18 -0
  310. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
  311. package/packages/analyze/src/lib/files/getImportedExports.js +6 -1
  312. package/packages/analyze/src/lib/files/getImportedExports.js.map +1 -1
  313. package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js +125 -0
  314. package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js.map +1 -0
  315. package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js +74 -19
  316. package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js.map +1 -1
  317. package/packages/analyze/src/lib/files/scenarios/generateChangesScenarioData.js +1 -1
  318. package/packages/analyze/src/lib/files/scenarios/generateChangesScenarioData.js.map +1 -1
  319. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +175 -58
  320. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
  321. package/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.js +10 -5
  322. package/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.js.map +1 -1
  323. package/packages/analyze/src/lib/files/scenarios/generateScenarioData.js +127 -69
  324. package/packages/analyze/src/lib/files/scenarios/generateScenarioData.js.map +1 -1
  325. package/packages/analyze/src/lib/files/scenarios/generateScenarios.js +2 -5
  326. package/packages/analyze/src/lib/files/scenarios/generateScenarios.js.map +1 -1
  327. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +74 -23
  328. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
  329. package/packages/database/src/lib/kysely/db.js +2 -2
  330. package/packages/database/src/lib/kysely/tables/debugReportsTable.js +9 -3
  331. package/packages/database/src/lib/kysely/tables/debugReportsTable.js.map +1 -1
  332. package/packages/database/src/lib/loadReadyToBeCapturedAnalyses.js +4 -2
  333. package/packages/database/src/lib/loadReadyToBeCapturedAnalyses.js.map +1 -1
  334. package/packages/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js +8 -4
  335. package/packages/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js.map +1 -1
  336. package/packages/generate/src/lib/deepMerge.js +27 -1
  337. package/packages/generate/src/lib/deepMerge.js.map +1 -1
  338. package/packages/generate/src/lib/getComponentScenarioPath.js +7 -3
  339. package/packages/generate/src/lib/getComponentScenarioPath.js.map +1 -1
  340. package/packages/types/index.js +1 -0
  341. package/packages/types/index.js.map +1 -1
  342. package/packages/types/src/types/Scenario.js +21 -1
  343. package/packages/types/src/types/Scenario.js.map +1 -1
  344. package/packages/utils/src/lib/applyUniversalMocks.js +26 -2
  345. package/packages/utils/src/lib/applyUniversalMocks.js.map +1 -1
  346. package/packages/utils/src/lib/lightweightEntityExtractor.js +25 -0
  347. package/packages/utils/src/lib/lightweightEntityExtractor.js.map +1 -1
  348. package/scripts/finalize-analyzer.cjs +3 -1
  349. package/codeyam-cli/src/webserver/build/client/assets/EntityItem-CWKV2GEz.js +0 -1
  350. package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-D2hFeDeg.js +0 -1
  351. package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-C8K-4kKP.js +0 -26
  352. package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-DgXLv61M.js +0 -3
  353. package/codeyam-cli/src/webserver/build/client/assets/LogViewer-DFdLQbPS.js +0 -3
  354. package/codeyam-cli/src/webserver/build/client/assets/ReportIssueModal-DlRDjT4h.js +0 -1
  355. package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-7UkVL-UI.js +0 -1
  356. package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-XjtsGuPo.js +0 -5
  357. package/codeyam-cli/src/webserver/build/client/assets/_index-D2eJjWLf.js +0 -1
  358. package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-w6sbwlOd.js +0 -7
  359. package/codeyam-cli/src/webserver/build/client/assets/chevron-down-BBNQ8hup.js +0 -1
  360. package/codeyam-cli/src/webserver/build/client/assets/chunk-WWGJGFF6-Bex4RrGs.js +0 -26
  361. package/codeyam-cli/src/webserver/build/client/assets/circle-check-cdhjVtom.js +0 -1
  362. package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-DkgmwwRC.js +0 -1
  363. package/codeyam-cli/src/webserver/build/client/assets/dev.empty-CwLmCS0J.js +0 -1
  364. package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-YZ-kM3ZG.js +0 -1
  365. package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-BeQlz94_.js +0 -5
  366. package/codeyam-cli/src/webserver/build/client/assets/entry.client-DN2XXM7Z.js +0 -5
  367. package/codeyam-cli/src/webserver/build/client/assets/fileTableUtils-CUeAIQNI.js +0 -1
  368. package/codeyam-cli/src/webserver/build/client/assets/files-ccMQfhGf.js +0 -1
  369. package/codeyam-cli/src/webserver/build/client/assets/git-JmESAHx5.js +0 -12
  370. package/codeyam-cli/src/webserver/build/client/assets/globals-CO-U8Bpo.css +0 -1
  371. package/codeyam-cli/src/webserver/build/client/assets/html2canvas-pro.esm-XQCGvadH.js +0 -5
  372. package/codeyam-cli/src/webserver/build/client/assets/index-DsL9BiOc.js +0 -8
  373. package/codeyam-cli/src/webserver/build/client/assets/loader-circle-COYCR2oZ.js +0 -1
  374. package/codeyam-cli/src/webserver/build/client/assets/manifest-90adba57.js +0 -1
  375. package/codeyam-cli/src/webserver/build/client/assets/root-DfbVEEjF.js +0 -16
  376. package/codeyam-cli/src/webserver/build/client/assets/search-DvK9iMBu.js +0 -1
  377. package/codeyam-cli/src/webserver/build/client/assets/server-build-CMKNK2uU.css +0 -1
  378. package/codeyam-cli/src/webserver/build/client/assets/settings-9LTbit4Z.js +0 -1
  379. package/codeyam-cli/src/webserver/build/client/assets/simulations-BrxN5ZtV.js +0 -1
  380. package/codeyam-cli/src/webserver/build/client/assets/triangle-alert-Iv0p8T-1.js +0 -1
  381. package/codeyam-cli/src/webserver/build/client/assets/useReportContext-BWmSRPH6.js +0 -1
  382. package/codeyam-cli/src/webserver/build/server/assets/index-CE_1qXCG.js +0 -1
  383. package/codeyam-cli/src/webserver/build/server/assets/server-build-BY_VDhiD.js +0 -166
  384. package/codeyam-cli/templates/debug-command.md +0 -141
  385. /package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-CMKNK2uU.css → styles-CMKNK2uU.css} +0 -0
@@ -140,6 +140,10 @@ const ALLOWED_EQUIVALENCY_REASONS = new Set([
140
140
  'propagated function call return sub-property equivalency',
141
141
  'propagated parent-variable equivalency', // Added: propagate child scope equivalencies to parent scope when variable is defined in parent
142
142
  'where was this function called from', // Added: tracks which scope called an external function
143
+ 'MUI DataGrid renderCell params.row equivalency', // Added: links DataGrid renderCell params.row to rows array elements
144
+ 'MUI Autocomplete getOptionLabel option equivalency', // Added: links Autocomplete getOptionLabel callback param to options array
145
+ 'MUI Autocomplete renderOption option equivalency', // Added: links Autocomplete renderOption callback param to options array
146
+ 'MUI Autocomplete option property equivalency', // Added: propagates property accesses from Autocomplete callbacks
143
147
  ]);
144
148
  const SILENTLY_IGNORED_EQUIVALENCY_REASONS = new Set([
145
149
  'signature of functionCall',
@@ -183,6 +187,9 @@ export class ScopeDataStructure {
183
187
  // Index for O(1) lookup of external function calls by name
184
188
  // Invalidated by setting to null; rebuilt lazily on next access
185
189
  this.externalFunctionCallsIndex = null;
190
+ // Tracks internal functions that have been filtered out during captureCompleteSchema
191
+ // Prevents re-adding them via subsequent equivalency propagation (e.g., from getReturnValue)
192
+ this.filteredInternalFunctions = new Set();
186
193
  // Debug tracer for selective path/scope tracing
187
194
  // Enable via: CODEYAM_DEBUG=true CODEYAM_DEBUG_PATHS="user.*,signature" npm test
188
195
  this.tracer = new DebugTracer({
@@ -301,6 +308,8 @@ export class ScopeDataStructure {
301
308
  const efcName = this.pathManager.stripGenerics(efc.name);
302
309
  for (const manager of this.equivalencyManagers) {
303
310
  if (manager.internalFunctions.has(efcName)) {
311
+ // Track this so we don't re-add it via subsequent finalize calls
312
+ this.filteredInternalFunctions.add(efcName);
304
313
  return false;
305
314
  }
306
315
  }
@@ -321,11 +330,42 @@ export class ScopeDataStructure {
321
330
  });
322
331
  entry.sourceCandidates = entry.sourceCandidates.filter((candidate) => {
323
332
  const baseName = this.pathManager.stripGenerics(candidate.scopeNodeName);
333
+ // Check if this is a local variable path (doesn't contain function call pattern)
334
+ // Local variables like "surveys[]" or "items[]" are important for tracing data flow
335
+ // from parent to child components (e.g., surveys[] -> SurveyCard().signature[0].survey)
336
+ const isLocalVariablePath = !candidate.schemaPath.includes('()') &&
337
+ !candidate.schemaPath.startsWith('signature[') &&
338
+ !candidate.schemaPath.startsWith('returnValue');
324
339
  return (validExternalFacingScopeNames.has(baseName) &&
325
340
  (candidate.schemaPath.startsWith('signature[') ||
326
- candidate.schemaPath.startsWith(baseName)) &&
341
+ candidate.schemaPath.startsWith(baseName) ||
342
+ isLocalVariablePath) &&
327
343
  !containsArrayMethod(candidate.schemaPath));
328
344
  });
345
+ // If all sourceCandidates were filtered out (e.g., because they belonged to
346
+ // internal functions like useState), look for the highest-order intermediate
347
+ // that belongs to a valid external-facing scope
348
+ if (entry.sourceCandidates.length === 0 &&
349
+ Object.keys(entry.intermediatesOrder).length > 0) {
350
+ // Find intermediates that belong to valid external-facing scopes
351
+ const validIntermediates = Object.entries(entry.intermediatesOrder)
352
+ .filter(([pathId]) => {
353
+ const [scopeNodeName, schemaPath] = pathId.split('::');
354
+ if (!scopeNodeName || !schemaPath)
355
+ return false;
356
+ const baseName = this.pathManager.stripGenerics(scopeNodeName);
357
+ return (validExternalFacingScopeNames.has(baseName) &&
358
+ !containsArrayMethod(schemaPath));
359
+ })
360
+ .sort((a, b) => b[1] - a[1]); // Sort by order descending (highest first)
361
+ if (validIntermediates.length > 0) {
362
+ const [pathId] = validIntermediates[0];
363
+ const [scopeNodeName, schemaPath] = pathId.split('::');
364
+ if (scopeNodeName && schemaPath) {
365
+ entry.sourceCandidates.push({ scopeNodeName, schemaPath });
366
+ }
367
+ }
368
+ }
329
369
  }
330
370
  this.propagateSourceAndUsageEquivalencies(this.scopeNodes[this.scopeTreeManager.getRootName()]);
331
371
  for (const externalFunctionCall of this.externalFunctionCalls) {
@@ -610,12 +650,28 @@ export class ScopeDataStructure {
610
650
  return;
611
651
  }
612
652
  if (!equivalentScopeName) {
613
- console.warn('Debug Propagation: missing equivalent scope name', {
653
+ console.error('CodeYam Error: Missing equivalent scope name - FULL CONTEXT:', JSON.stringify({
614
654
  path,
615
655
  equivalentPath,
616
656
  equivalentScopeName,
617
657
  scopeNodeName: scopeNode.name,
618
- });
658
+ equivalencyReason,
659
+ tree: scopeNode.tree,
660
+ equivalencyValueChain: equivalencyValueChain?.map((ev) => ({
661
+ id: ev.id,
662
+ source: ev.source,
663
+ reason: ev.reason,
664
+ currentPath: ev.currentPath,
665
+ previousPath: ev.previousPath,
666
+ })),
667
+ scopeNodeFunctionCalls: scopeNode.functionCalls?.map((fc) => ({
668
+ name: fc.name,
669
+ callSignature: fc.callSignature,
670
+ callScope: fc.callScope,
671
+ })),
672
+ instantiatedVariables: scopeNode.instantiatedVariables,
673
+ parentInstantiatedVariables: scopeNode.parentInstantiatedVariables,
674
+ }, null, 2));
619
675
  throw new Error('CodeYam Error: Missing equivalent scope name');
620
676
  }
621
677
  (_a = scopeNode.equivalencies)[path] || (_a[path] = []);
@@ -738,10 +794,31 @@ export class ScopeDataStructure {
738
794
  const searchKey = getFunctionCallRoot(functionCallInfo.callSignature);
739
795
  const existingFunctionCall = this.getExternalFunctionCallsIndex().get(searchKey);
740
796
  if (existingFunctionCall) {
741
- existingFunctionCall.schema = {
797
+ // Preserve per-call schemas BEFORE merging to enable per-variable mock data.
798
+ // This is critical for hooks like useFetcher<UserData>() vs useFetcher<ReportData>()
799
+ // where each call returns different typed data.
800
+ if (!existingFunctionCall.perCallSignatureSchemas) {
801
+ // First merge - save the existing call's schema
802
+ existingFunctionCall.perCallSignatureSchemas = {
803
+ [existingFunctionCall.callSignature]: {
804
+ ...existingFunctionCall.schema,
805
+ },
806
+ };
807
+ }
808
+ // Save the new call's schema before it gets merged
809
+ existingFunctionCall.perCallSignatureSchemas[functionCallInfo.callSignature] = { ...functionCallInfo.schema };
810
+ // Merge schemas using selectBestValue to preserve specific types like 'null'
811
+ // over generic types like 'unknown'. This ensures ref variables detected
812
+ // earlier (marked as 'null') aren't overwritten by later 'unknown' values.
813
+ const mergedSchema = {
742
814
  ...existingFunctionCall.schema,
743
- ...functionCallInfo.schema,
744
815
  };
816
+ for (const key in functionCallInfo.schema) {
817
+ const existingValue = existingFunctionCall.schema[key];
818
+ const newValue = functionCallInfo.schema[key];
819
+ mergedSchema[key] = selectBestValue(existingValue, newValue, newValue);
820
+ }
821
+ existingFunctionCall.schema = mergedSchema;
745
822
  existingFunctionCall.equivalencies = {
746
823
  ...existingFunctionCall.equivalencies,
747
824
  ...functionCallInfo.equivalencies,
@@ -761,8 +838,13 @@ export class ScopeDataStructure {
761
838
  const isExternal = !callingScopeNode.instantiatedVariables?.includes(functionCallInfoNameParts[0]) &&
762
839
  !callingScopeNode.parentInstantiatedVariables?.includes(functionCallInfoNameParts[0]);
763
840
  if (isExternal) {
764
- this.externalFunctionCalls.push(functionCallInfo);
765
- this.invalidateExternalFunctionCallsIndex();
841
+ // Check if this function was already filtered out as an internal function
842
+ // (e.g., useState was filtered in captureCompleteSchema but finalize is trying to re-add it)
843
+ const strippedName = this.pathManager.stripGenerics(functionCallInfo.name);
844
+ if (!this.filteredInternalFunctions.has(strippedName)) {
845
+ this.externalFunctionCalls.push(functionCallInfo);
846
+ this.invalidateExternalFunctionCallsIndex();
847
+ }
766
848
  }
767
849
  }
768
850
  }
@@ -2117,7 +2199,12 @@ export class ScopeDataStructure {
2117
2199
  return acc;
2118
2200
  }, {});
2119
2201
  }
2202
+ // CRITICAL: Set onlyEquivalencies to true to prevent database modifications
2203
+ // during this "getter" method. See comment in getFunctionSignature.
2204
+ const wasOnlyEquivalencies = this.onlyEquivalencies;
2205
+ this.onlyEquivalencies = true;
2120
2206
  this.validateSchema(scopeNode, true, fillInUnknowns);
2207
+ this.onlyEquivalencies = wasOnlyEquivalencies;
2121
2208
  const { schema } = scopeNode;
2122
2209
  // For root scope, merge in external function call schemas
2123
2210
  // This ensures that imported objects used as method call targets (like logger.error())
@@ -2225,10 +2312,25 @@ export class ScopeDataStructure {
2225
2312
  }
2226
2313
  }
2227
2314
  const tempScopeNode = this.createTempScopeNode(functionName ?? this.scopeTreeManager.getRootName(), signatureInSchema, equivalencies);
2315
+ // CRITICAL: Set onlyEquivalencies to true to prevent database modifications
2316
+ // during this "getter" method. validateSchema triggers manager.finalize which
2317
+ // can call addToSchema -> addToEquivalencyDatabase -> mergeEquivalencyDatabaseEntries,
2318
+ // which would incorrectly remove entries from the database.
2319
+ const wasOnlyEquivalencies = this.onlyEquivalencies;
2320
+ this.onlyEquivalencies = true;
2228
2321
  this.validateSchema(tempScopeNode, true, fillInUnknowns);
2322
+ this.onlyEquivalencies = wasOnlyEquivalencies;
2229
2323
  return tempScopeNode.schema;
2230
2324
  }
2231
2325
  getReturnValue({ functionName, fillInUnknowns, }) {
2326
+ // Trigger finalization on all managers to apply any pending updates
2327
+ // (e.g., ref type propagation to external function call schemas)
2328
+ const rootScope = this.scopeNodes[this.scopeTreeManager.getRootName()];
2329
+ if (rootScope) {
2330
+ for (const manager of this.equivalencyManagers) {
2331
+ manager.finalize(rootScope, this);
2332
+ }
2333
+ }
2232
2334
  const scopeName = functionName ?? this.scopeTreeManager.getRootName();
2233
2335
  const scopeNode = this.scopeNodes[scopeName];
2234
2336
  let schema = {};
@@ -2239,7 +2341,8 @@ export class ScopeDataStructure {
2239
2341
  });
2240
2342
  }
2241
2343
  else {
2242
- for (const externalFunctionCall of this.externalFunctionCalls) {
2344
+ // Use getExternalFunctionCalls() which cleans cyScope from schemas
2345
+ for (const externalFunctionCall of this.getExternalFunctionCalls()) {
2243
2346
  const functionNameParts = this.splitPath(functionName).map((p) => this.functionOrScopeName(p));
2244
2347
  const nameParts = this.splitPath(externalFunctionCall.name).map((p) => this.functionOrScopeName(p));
2245
2348
  if (functionNameParts.every((part, index) => part === nameParts[index])) {
@@ -2275,12 +2378,19 @@ export class ScopeDataStructure {
2275
2378
  // Replace cyScope placeholders with actual callback text
2276
2379
  const resolvedSchema = this.replaceCyScopePlaceholders(returnValueSchema);
2277
2380
  const tempScopeNode = this.createTempScopeNode(scopeName, resolvedSchema);
2381
+ // CRITICAL: Set onlyEquivalencies to true to prevent database modifications
2382
+ // during this "getter" method. See comment in getFunctionSignature.
2383
+ const wasOnlyEquivalencies = this.onlyEquivalencies;
2384
+ this.onlyEquivalencies = true;
2278
2385
  this.validateSchema(tempScopeNode, true, fillInUnknowns);
2386
+ this.onlyEquivalencies = wasOnlyEquivalencies;
2279
2387
  return tempScopeNode.schema;
2280
2388
  }
2281
2389
  /**
2282
2390
  * Replaces cyScope placeholder references (e.g., cyScope10()) in schema keys
2283
2391
  * with the actual callback function text from the corresponding scope node.
2392
+ * If the scope text can't be found, uses a generic fallback to avoid leaking
2393
+ * internal cyScope names into stored data.
2284
2394
  */
2285
2395
  replaceCyScopePlaceholders(schema) {
2286
2396
  const cyScopePattern = /cyScope(\d+)\(\)/g;
@@ -2292,10 +2402,10 @@ export class ScopeDataStructure {
2292
2402
  for (const match of matches) {
2293
2403
  const cyScopeName = `cyScope${match[1]}`;
2294
2404
  const scopeText = this.findCyScopeText(cyScopeName);
2295
- if (scopeText) {
2296
- // Replace cyScope10() with the actual callback text
2297
- newKey = newKey.replace(match[0], scopeText);
2298
- }
2405
+ // Always replace cyScope references - use actual text if available,
2406
+ // otherwise use a generic callback placeholder
2407
+ const replacement = scopeText || '() => {}';
2408
+ newKey = newKey.replace(match[0], replacement);
2299
2409
  }
2300
2410
  result[newKey] = value;
2301
2411
  }
@@ -2383,7 +2493,12 @@ export class ScopeDataStructure {
2383
2493
  return { ...acc, ...filterdSchema };
2384
2494
  }, {});
2385
2495
  const tempScopeNode = this.createTempScopeNode(scopeName ?? this.scopeTreeManager.getRootName(), relevantSchema);
2496
+ // CRITICAL: Set onlyEquivalencies to true to prevent database modifications
2497
+ // during this "getter" method. See comment in getFunctionSignature.
2498
+ const wasOnlyEquivalencies = this.onlyEquivalencies;
2499
+ this.onlyEquivalencies = true;
2386
2500
  this.validateSchema(tempScopeNode, true, final);
2501
+ this.onlyEquivalencies = wasOnlyEquivalencies;
2387
2502
  return {
2388
2503
  name: variableName,
2389
2504
  equivalentTo: equivalents,
@@ -2391,7 +2506,96 @@ export class ScopeDataStructure {
2391
2506
  };
2392
2507
  }
2393
2508
  getExternalFunctionCalls() {
2394
- return this.externalFunctionCalls;
2509
+ // Replace cyScope placeholders in all external function call data
2510
+ // This ensures call signatures and schema paths use actual callback text
2511
+ // instead of internal cyScope names, preventing mock data merge conflicts.
2512
+ return this.externalFunctionCalls.map((efc) => this.cleanCyScopeFromFunctionCallInfo(efc));
2513
+ }
2514
+ /**
2515
+ * Cleans cyScope placeholder references from a FunctionCallInfo.
2516
+ * Replaces cyScopeN() with the actual callback text in:
2517
+ * - callSignature
2518
+ * - allCallSignatures
2519
+ * - schema keys
2520
+ */
2521
+ cleanCyScopeFromFunctionCallInfo(efc) {
2522
+ const cyScopePattern = /cyScope\d+\(\)/g;
2523
+ // Check if any cleaning is needed
2524
+ const hasCyScope = cyScopePattern.test(efc.callSignature) ||
2525
+ (efc.allCallSignatures &&
2526
+ efc.allCallSignatures.some((sig) => /cyScope\d+\(\)/.test(sig))) ||
2527
+ (efc.schema &&
2528
+ Object.keys(efc.schema).some((key) => /cyScope\d+\(\)/.test(key)));
2529
+ if (!hasCyScope) {
2530
+ return efc;
2531
+ }
2532
+ // Create cleaned copy
2533
+ const cleaned = { ...efc };
2534
+ // Clean callSignature
2535
+ cleaned.callSignature = this.replaceCyScopeInString(efc.callSignature);
2536
+ // Clean allCallSignatures
2537
+ if (efc.allCallSignatures) {
2538
+ cleaned.allCallSignatures = efc.allCallSignatures.map((sig) => this.replaceCyScopeInString(sig));
2539
+ }
2540
+ // Clean schema keys
2541
+ if (efc.schema) {
2542
+ cleaned.schema = this.replaceCyScopePlaceholders(efc.schema);
2543
+ }
2544
+ // Clean callSignatureToVariable keys
2545
+ if (efc.callSignatureToVariable) {
2546
+ cleaned.callSignatureToVariable = Object.entries(efc.callSignatureToVariable).reduce((acc, [key, value]) => {
2547
+ acc[this.replaceCyScopeInString(key)] = value;
2548
+ return acc;
2549
+ }, {});
2550
+ }
2551
+ return cleaned;
2552
+ }
2553
+ /**
2554
+ * Replaces cyScope placeholder references in a single string.
2555
+ * If the scope text can't be found, uses a generic fallback to avoid leaking
2556
+ * internal cyScope names into stored data.
2557
+ *
2558
+ * Handles two patterns:
2559
+ * 1. Function call style: cyScope7() - matched by cyScope(\d+)\(\)
2560
+ * 2. Scope name style: parentName____cyScopeXX or cyScopeXX - matched by (\w+____)?cyScope([0-9A-Fa-f]+)
2561
+ */
2562
+ replaceCyScopeInString(str) {
2563
+ let result = str;
2564
+ // Pattern 1: Function call style - cyScope7()
2565
+ const functionCallPattern = /cyScope(\d+)\(\)/g;
2566
+ const functionCallMatches = [...str.matchAll(functionCallPattern)];
2567
+ for (const match of functionCallMatches) {
2568
+ const cyScopeName = `cyScope${match[1]}`;
2569
+ const scopeText = this.findCyScopeText(cyScopeName);
2570
+ // Always replace cyScope references - use actual text if available,
2571
+ // otherwise use a generic callback placeholder
2572
+ const replacement = scopeText || '() => {}';
2573
+ result = result.replace(match[0], replacement);
2574
+ }
2575
+ // Pattern 2: Scope name style - parentName____cyScopeXX or just cyScopeXX
2576
+ // This handles hex-encoded scope IDs like cyScope1F
2577
+ const scopeNamePattern = /(\w+____)?cyScope([0-9A-Fa-f]+)/g;
2578
+ const scopeNameMatches = [...result.matchAll(scopeNamePattern)];
2579
+ for (const match of scopeNameMatches) {
2580
+ const fullMatch = match[0];
2581
+ const prefix = match[1] || ''; // e.g., "getTitleColor____"
2582
+ const cyScopeId = match[2]; // e.g., "1F"
2583
+ const cyScopeName = `cyScope${cyScopeId}`;
2584
+ // Try to find the scope text, checking both with and without prefix
2585
+ let scopeText = this.findCyScopeText(cyScopeName);
2586
+ if (!scopeText && prefix) {
2587
+ // Try looking up with the full prefixed name
2588
+ scopeText = this.findCyScopeText(`${prefix}${cyScopeName}`);
2589
+ }
2590
+ if (scopeText) {
2591
+ result = result.replace(fullMatch, scopeText);
2592
+ }
2593
+ else {
2594
+ // Replace with a generic identifier to avoid leaking internal names
2595
+ result = result.replace(fullMatch, 'callback');
2596
+ }
2597
+ }
2598
+ return result;
2395
2599
  }
2396
2600
  getEnvironmentVariables() {
2397
2601
  return this.environmentVariables;
@@ -2441,51 +2645,328 @@ export class ScopeDataStructure {
2441
2645
  return enriched;
2442
2646
  }
2443
2647
  toSerializable() {
2444
- // Helper to convert ScopeVariable to SerializableScopeVariable
2648
+ // Helper to clean cyScope from a string
2649
+ const cleanCyScope = (str) => this.replaceCyScopeInString(str);
2650
+ // Helper to convert ScopeVariable to SerializableScopeVariable (with cyScope cleaned)
2445
2651
  const toSerializableVariable = (vars) => vars.map((v) => ({
2446
- scopeNodeName: v.scopeNodeName,
2447
- schemaPath: v.schemaPath,
2652
+ scopeNodeName: cleanCyScope(v.scopeNodeName),
2653
+ schemaPath: cleanCyScope(v.schemaPath),
2448
2654
  }));
2655
+ // Helper to clean cyScope from all keys in a schema
2656
+ const cleanSchemaKeys = (schema) => {
2657
+ return Object.entries(schema).reduce((acc, [key, value]) => {
2658
+ acc[cleanCyScope(key)] = value;
2659
+ return acc;
2660
+ }, {});
2661
+ };
2449
2662
  // Helper to get function result for a given function name
2450
2663
  const getFunctionResult = (functionName) => {
2451
2664
  return {
2452
- signature: this.getFunctionSignature({ functionName }) ?? {},
2453
- signatureWithUnknowns: this.getFunctionSignature({ functionName, fillInUnknowns: true }) ??
2454
- {},
2455
- returnValue: this.getReturnValue({ functionName }) ?? {},
2456
- returnValueWithUnknowns: this.getReturnValue({ functionName, fillInUnknowns: true }) ?? {},
2665
+ signature: cleanSchemaKeys(this.getFunctionSignature({ functionName }) ?? {}),
2666
+ signatureWithUnknowns: cleanSchemaKeys(this.getFunctionSignature({ functionName, fillInUnknowns: true }) ??
2667
+ {}),
2668
+ returnValue: cleanSchemaKeys(this.getReturnValue({ functionName }) ?? {}),
2669
+ returnValueWithUnknowns: cleanSchemaKeys(this.getReturnValue({ functionName, fillInUnknowns: true }) ?? {}),
2457
2670
  usageEquivalencies: Object.entries(this.getUsageEquivalencies(functionName) ?? {}).reduce((acc, [key, vars]) => {
2458
- acc[key] = toSerializableVariable(vars);
2671
+ // Clean cyScope from the key as well as variable properties
2672
+ acc[cleanCyScope(key)] = toSerializableVariable(vars);
2459
2673
  return acc;
2460
2674
  }, {}),
2461
2675
  sourceEquivalencies: Object.entries(this.getSourceEquivalencies(functionName) ?? {}).reduce((acc, [key, vars]) => {
2462
- acc[key] = toSerializableVariable(vars);
2676
+ // Clean cyScope from the key as well as variable properties
2677
+ acc[cleanCyScope(key)] = toSerializableVariable(vars);
2463
2678
  return acc;
2464
2679
  }, {}),
2465
2680
  environmentVariables: this.getEnvironmentVariables(),
2466
2681
  };
2467
2682
  };
2468
- // Convert external function calls
2469
- const externalFunctionCalls = this.externalFunctionCalls.map((efc) => ({
2470
- name: efc.name,
2471
- callSignature: efc.callSignature,
2472
- callScope: efc.callScope,
2473
- schema: efc.schema,
2474
- equivalencies: efc.equivalencies
2475
- ? Object.entries(efc.equivalencies).reduce((acc, [key, vars]) => {
2476
- acc[key] = toSerializableVariable(vars);
2477
- return acc;
2478
- }, {})
2479
- : undefined,
2480
- allCallSignatures: efc.allCallSignatures,
2481
- receivingVariableNames: efc.receivingVariableNames,
2482
- callSignatureToVariable: efc.callSignatureToVariable,
2483
- }));
2683
+ // Convert external function calls - use getExternalFunctionCalls() which cleans cyScope
2684
+ const cleanedExternalCalls = this.getExternalFunctionCalls();
2685
+ // Get root scope schema for building per-variable return value schemas
2686
+ const rootScopeName = this.scopeTreeManager.getRootName();
2687
+ const rootScope = this.scopeNodes[rootScopeName];
2688
+ const rootSchema = rootScope?.schema ?? {};
2689
+ const externalFunctionCalls = cleanedExternalCalls.map((efc) => {
2690
+ // Build perVariableSchemas from perCallSignatureSchemas when available.
2691
+ // This preserves distinct schemas per variable when the same function is called
2692
+ // multiple times with DIFFERENT call signatures (e.g., different type parameters).
2693
+ //
2694
+ // When field accesses happen in child scopes (like JSX expressions), the
2695
+ // rootSchema doesn't contain the detailed paths - they end up in child scope
2696
+ // schemas. Using perCallSignatureSchemas ensures we get the correct schema
2697
+ // for each call, regardless of where field accesses occur.
2698
+ let perVariableSchemas;
2699
+ // Use perCallSignatureSchemas only when:
2700
+ // 1. It exists and has distinct entries for different call signatures
2701
+ // 2. The number of distinct call signatures >= number of receiving variables
2702
+ //
2703
+ // This prevents using it when all calls have the same signature (e.g., useFetcher() x 2)
2704
+ // because in that case, perCallSignatureSchemas only has one entry.
2705
+ const numCallSignatures = efc.perCallSignatureSchemas
2706
+ ? Object.keys(efc.perCallSignatureSchemas).length
2707
+ : 0;
2708
+ const numReceivingVars = efc.receivingVariableNames?.length ?? 0;
2709
+ const hasDistinctSchemas = numCallSignatures >= numReceivingVars && numCallSignatures > 1;
2710
+ // CASE 1: Multiple call signatures with distinct schemas - use indexed variable names
2711
+ if (hasDistinctSchemas &&
2712
+ efc.perCallSignatureSchemas &&
2713
+ efc.callSignatureToVariable) {
2714
+ perVariableSchemas = {};
2715
+ // Build a reverse map: variable -> array of call signatures (in order)
2716
+ // This handles the case where the same variable name is reused for different calls
2717
+ const varToCallSigs = {};
2718
+ for (const [callSig, varName] of Object.entries(efc.callSignatureToVariable)) {
2719
+ if (!varToCallSigs[varName]) {
2720
+ varToCallSigs[varName] = [];
2721
+ }
2722
+ varToCallSigs[varName].push(callSig);
2723
+ }
2724
+ // Track how many times each variable name has been seen
2725
+ const varNameCounts = {};
2726
+ // For each receiving variable, get its original schema from perCallSignatureSchemas
2727
+ for (const varName of efc.receivingVariableNames ?? []) {
2728
+ const occurrence = varNameCounts[varName] ?? 0;
2729
+ varNameCounts[varName] = occurrence + 1;
2730
+ const callSigs = varToCallSigs[varName];
2731
+ // Use the nth call signature for the nth occurrence of this variable
2732
+ const callSig = callSigs?.[occurrence];
2733
+ if (callSig && efc.perCallSignatureSchemas[callSig]) {
2734
+ // Use indexed key if this variable name is reused (e.g., fetcher, fetcher[1])
2735
+ const key = occurrence === 0 ? varName : `${varName}[${occurrence}]`;
2736
+ // Clone the schema to avoid shared references
2737
+ perVariableSchemas[key] = {
2738
+ ...efc.perCallSignatureSchemas[callSig],
2739
+ };
2740
+ }
2741
+ }
2742
+ // Only include if we have entries for ALL receiving variables
2743
+ if (Object.keys(perVariableSchemas).length < numReceivingVars) {
2744
+ // Not all variables have schemas - fall back to rootSchema extraction
2745
+ perVariableSchemas = undefined;
2746
+ }
2747
+ }
2748
+ // CASE 2: Single call signature with single variable - use perCallSignatureSchemas directly
2749
+ // This handles parameterized calls like useFetcher<ConfigData>() where each is a separate efc entry
2750
+ if (!perVariableSchemas &&
2751
+ efc.perCallSignatureSchemas &&
2752
+ numCallSignatures === 1 &&
2753
+ numReceivingVars === 1) {
2754
+ const varName = efc.receivingVariableNames[0];
2755
+ const callSig = Object.keys(efc.perCallSignatureSchemas)[0];
2756
+ const schema = efc.perCallSignatureSchemas[callSig];
2757
+ if (schema && Object.keys(schema).length > 0) {
2758
+ perVariableSchemas = { [varName]: { ...schema } };
2759
+ }
2760
+ }
2761
+ // CASE 3: Parameterized calls that create SEPARATE efc entries (no perCallSignatureSchemas)
2762
+ // When useFetcher<ConfigData>() and useFetcher<SettingsData>() are called, they create separate
2763
+ // efc entries because getFunctionCallRoot preserves type parameters. Each entry has its own
2764
+ // `schema` field, but due to variable reassignment, the schema may be contaminated with paths
2765
+ // from other calls (the tracer attributes field accesses to ALL equivalencies).
2766
+ //
2767
+ // Solution: Filter efc.schema to only include paths that match THIS entry's call signature.
2768
+ // The schema paths include the full call signature prefix, so we can filter by it.
2769
+ //
2770
+ // Example: ConfigData entry has paths like:
2771
+ // "useFetcher<{ data: ConfigData | null }>().functionCallReturnValue.data.data.theme"
2772
+ // But also (contaminated):
2773
+ // "useFetcher<{ data: ConfigData | null }>().functionCallReturnValue.data.data.notifications"
2774
+ //
2775
+ // We filter to only keep paths that should belong to THIS call by checking if the
2776
+ // receiving variable's equivalency points to this call's return value.
2777
+ if (!perVariableSchemas &&
2778
+ !efc.perCallSignatureSchemas &&
2779
+ numReceivingVars >= 1) {
2780
+ // Build the call signature prefix that paths should start with
2781
+ const callSigPrefix = `${efc.callSignature}.functionCallReturnValue`;
2782
+ // Filter efc.schema to only include paths matching this call signature
2783
+ const filteredSchema = {};
2784
+ for (const [path, type] of Object.entries(efc.schema)) {
2785
+ if (path.startsWith(callSigPrefix) || path === efc.callSignature) {
2786
+ filteredSchema[path] = type;
2787
+ }
2788
+ }
2789
+ // Build perVariableSchemas from the filtered schema
2790
+ if (Object.keys(filteredSchema).length > 0) {
2791
+ perVariableSchemas = {};
2792
+ for (const varName of efc.receivingVariableNames ?? []) {
2793
+ // For each variable, extract paths and transform to functionCallReturnValue format
2794
+ const varSchema = {};
2795
+ for (const [path, type] of Object.entries(filteredSchema)) {
2796
+ if (path.startsWith(callSigPrefix)) {
2797
+ // Transform to generic functionCallReturnValue path
2798
+ // e.g., "useFetcher<ConfigData>().functionCallReturnValue.data.data.theme"
2799
+ // -> "functionCallReturnValue.data.data.theme"
2800
+ const suffix = path.slice(callSigPrefix.length);
2801
+ const returnValuePath = `functionCallReturnValue${suffix}`;
2802
+ varSchema[returnValuePath] = type;
2803
+ }
2804
+ else if (path === efc.callSignature) {
2805
+ // Include the function call type itself
2806
+ varSchema[path] = type;
2807
+ }
2808
+ }
2809
+ if (Object.keys(varSchema).length > 0) {
2810
+ perVariableSchemas[varName] = varSchema;
2811
+ }
2812
+ }
2813
+ // Only include if we have entries
2814
+ if (Object.keys(perVariableSchemas).length === 0) {
2815
+ perVariableSchemas = undefined;
2816
+ }
2817
+ }
2818
+ }
2819
+ // Fallback: extract from root scope schema when perCallSignatureSchemas is not available
2820
+ // or doesn't have distinct entries for each variable.
2821
+ // This works when field accesses are in the root scope.
2822
+ if (!perVariableSchemas &&
2823
+ efc.receivingVariableNames &&
2824
+ efc.receivingVariableNames.length > 0) {
2825
+ perVariableSchemas = {};
2826
+ for (const varName of efc.receivingVariableNames) {
2827
+ const varSchema = {};
2828
+ for (const [path, type] of Object.entries(rootSchema)) {
2829
+ // Check if path starts with this variable name
2830
+ if (path === varName ||
2831
+ path.startsWith(varName + '.') ||
2832
+ path.startsWith(varName + '[')) {
2833
+ // Transform to functionCallReturnValue format
2834
+ // e.g., userFetcher.data.id -> functionCallReturnValue.data.id
2835
+ const suffix = path.slice(varName.length);
2836
+ const returnValuePath = `functionCallReturnValue${suffix}`;
2837
+ varSchema[returnValuePath] = type;
2838
+ }
2839
+ }
2840
+ if (Object.keys(varSchema).length > 0) {
2841
+ perVariableSchemas[varName] = varSchema;
2842
+ }
2843
+ }
2844
+ // Only include if we have any entries
2845
+ if (Object.keys(perVariableSchemas).length === 0) {
2846
+ perVariableSchemas = undefined;
2847
+ }
2848
+ }
2849
+ return {
2850
+ name: efc.name,
2851
+ callSignature: efc.callSignature,
2852
+ callScope: efc.callScope,
2853
+ schema: efc.schema,
2854
+ equivalencies: efc.equivalencies
2855
+ ? Object.entries(efc.equivalencies).reduce((acc, [key, vars]) => {
2856
+ // Clean cyScope from the key as well as variable properties
2857
+ acc[cleanCyScope(key)] = toSerializableVariable(vars);
2858
+ return acc;
2859
+ }, {})
2860
+ : undefined,
2861
+ allCallSignatures: efc.allCallSignatures,
2862
+ receivingVariableNames: efc.receivingVariableNames,
2863
+ callSignatureToVariable: efc.callSignatureToVariable,
2864
+ perVariableSchemas,
2865
+ };
2866
+ });
2867
+ // POST-PROCESSING: Deduplicate schemas across parameterized calls to same base function
2868
+ // When useFetcher<ConfigData>() and useFetcher<SettingsData>() are called, they create
2869
+ // separate entries. Due to variable reassignment, BOTH entries may have ALL fields.
2870
+ // We deduplicate by assigning each field to ONLY ONE entry based on order of appearance.
2871
+ //
2872
+ // Strategy: Fields that appear first in order belong to the first entry,
2873
+ // fields that appear later belong to later entries (split evenly).
2874
+ const deduplicateParameterizedEntries = (entries) => {
2875
+ // Group entries by base function name (without type parameters)
2876
+ const groups = new Map();
2877
+ for (const entry of entries) {
2878
+ // Extract base function name by stripping type parameters
2879
+ // e.g., "useFetcher<{ data: ConfigData | null }>" -> "useFetcher"
2880
+ const baseName = entry.name.replace(/<.*>$/, '');
2881
+ const group = groups.get(baseName) || [];
2882
+ group.push(entry);
2883
+ groups.set(baseName, group);
2884
+ }
2885
+ // Process groups with multiple parameterized entries
2886
+ for (const [, group] of groups) {
2887
+ if (group.length <= 1)
2888
+ continue;
2889
+ // Check if these are parameterized calls (have type parameters in name)
2890
+ const hasTypeParams = group.every((e) => e.name.includes('<'));
2891
+ if (!hasTypeParams)
2892
+ continue;
2893
+ // Collect ALL unique field suffixes across all entries (in order of first appearance)
2894
+ // Field suffix is the path after functionCallReturnValue, e.g., ".data.data.theme"
2895
+ const allFieldSuffixes = [];
2896
+ for (const entry of group) {
2897
+ if (!entry.perVariableSchemas)
2898
+ continue;
2899
+ for (const varSchema of Object.values(entry.perVariableSchemas)) {
2900
+ for (const path of Object.keys(varSchema)) {
2901
+ // Skip the base "functionCallReturnValue" entry
2902
+ if (path === 'functionCallReturnValue')
2903
+ continue;
2904
+ // Extract field suffix
2905
+ const match = path.match(/functionCallReturnValue(.+)/);
2906
+ if (!match)
2907
+ continue;
2908
+ const fieldSuffix = match[1];
2909
+ if (!allFieldSuffixes.includes(fieldSuffix)) {
2910
+ allFieldSuffixes.push(fieldSuffix);
2911
+ }
2912
+ }
2913
+ }
2914
+ }
2915
+ // Assign fields to entries: split evenly based on order
2916
+ // First N/2 fields go to first entry, remaining go to second entry
2917
+ const fieldToEntryMap = new Map();
2918
+ const fieldsPerEntry = Math.ceil(allFieldSuffixes.length / group.length);
2919
+ for (let i = 0; i < allFieldSuffixes.length; i++) {
2920
+ const fieldSuffix = allFieldSuffixes[i];
2921
+ const entryIdx = Math.min(Math.floor(i / fieldsPerEntry), group.length - 1);
2922
+ fieldToEntryMap.set(fieldSuffix, entryIdx);
2923
+ }
2924
+ // Filter each entry's perVariableSchemas to only include its assigned fields
2925
+ for (let i = 0; i < group.length; i++) {
2926
+ const entry = group[i];
2927
+ if (!entry.perVariableSchemas)
2928
+ continue;
2929
+ const filteredPerVarSchemas = {};
2930
+ for (const [varName, varSchema] of Object.entries(entry.perVariableSchemas)) {
2931
+ const filteredVarSchema = {};
2932
+ for (const [path, type] of Object.entries(varSchema)) {
2933
+ // Always keep the base functionCallReturnValue
2934
+ if (path === 'functionCallReturnValue') {
2935
+ filteredVarSchema[path] = type;
2936
+ continue;
2937
+ }
2938
+ // Extract field suffix
2939
+ const match = path.match(/functionCallReturnValue(.+)/);
2940
+ if (!match) {
2941
+ // Keep non-field paths
2942
+ filteredVarSchema[path] = type;
2943
+ continue;
2944
+ }
2945
+ const fieldSuffix = match[1];
2946
+ // Only include if this entry owns this field
2947
+ if (fieldToEntryMap.get(fieldSuffix) === i) {
2948
+ filteredVarSchema[path] = type;
2949
+ }
2950
+ }
2951
+ if (Object.keys(filteredVarSchema).length > 0) {
2952
+ filteredPerVarSchemas[varName] = filteredVarSchema;
2953
+ }
2954
+ }
2955
+ entry.perVariableSchemas =
2956
+ Object.keys(filteredPerVarSchemas).length > 0
2957
+ ? filteredPerVarSchemas
2958
+ : undefined;
2959
+ }
2960
+ }
2961
+ return entries;
2962
+ };
2963
+ // Apply deduplication
2964
+ const deduplicatedExternalFunctionCalls = deduplicateParameterizedEntries(externalFunctionCalls);
2484
2965
  // Get root function result
2485
2966
  const rootFunction = getFunctionResult();
2486
- // Get results for each external function
2967
+ // Get results for each external function (use cleaned calls for consistency)
2487
2968
  const functionResults = {};
2488
- for (const efc of this.externalFunctionCalls) {
2969
+ for (const efc of cleanedExternalCalls) {
2489
2970
  functionResults[efc.name] = getFunctionResult(efc.name);
2490
2971
  }
2491
2972
  // Get equivalent signature variables
@@ -2497,7 +2978,7 @@ export class ScopeDataStructure {
2497
2978
  ? enrichedConditionalUsages
2498
2979
  : undefined;
2499
2980
  return {
2500
- externalFunctionCalls,
2981
+ externalFunctionCalls: deduplicatedExternalFunctionCalls,
2501
2982
  rootFunction,
2502
2983
  functionResults,
2503
2984
  equivalentSignatureVariables,