@codeyam/codeyam-cli 0.1.0-staging.15d0f46 → 0.1.0-staging.1669d45

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 (625) hide show
  1. package/analyzer-template/.build-info.json +7 -7
  2. package/analyzer-template/common/execAsync.ts +1 -1
  3. package/analyzer-template/log.txt +3 -3
  4. package/analyzer-template/package.json +9 -5
  5. package/analyzer-template/packages/ai/index.ts +5 -3
  6. package/analyzer-template/packages/ai/package.json +1 -1
  7. package/analyzer-template/packages/ai/src/lib/__mocks__/completionCall.ts +122 -0
  8. package/analyzer-template/packages/ai/src/lib/analyzeScope.ts +152 -6
  9. package/analyzer-template/packages/ai/src/lib/astScopes/astScopeAnalyzer.ts +107 -1
  10. package/analyzer-template/packages/ai/src/lib/astScopes/conditionalEffectsExtractor.ts +644 -0
  11. package/analyzer-template/packages/ai/src/lib/astScopes/methodSemantics.ts +42 -0
  12. package/analyzer-template/packages/ai/src/lib/astScopes/patterns/ifStatementHandler.ts +18 -0
  13. package/analyzer-template/packages/ai/src/lib/astScopes/patterns/switchStatementHandler.ts +38 -1
  14. package/analyzer-template/packages/ai/src/lib/astScopes/patterns/variableDeclarationHandler.ts +301 -1
  15. package/analyzer-template/packages/ai/src/lib/astScopes/processExpression.ts +972 -106
  16. package/analyzer-template/packages/ai/src/lib/astScopes/types.ts +232 -0
  17. package/analyzer-template/packages/ai/src/lib/checkAllAttributes.ts +29 -10
  18. package/analyzer-template/packages/ai/src/lib/completionCall.ts +18 -2
  19. package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +1409 -138
  20. package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.ts +2 -1
  21. package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/MuiManager.ts +771 -0
  22. package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.ts +233 -75
  23. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.ts +19 -1
  24. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.ts +39 -4
  25. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.ts +23 -0
  26. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertNullToUndefinedBySchema.ts +98 -0
  27. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.ts +42 -2
  28. package/analyzer-template/packages/ai/src/lib/deepEqual.ts +30 -0
  29. package/analyzer-template/packages/ai/src/lib/generateChangesEntityScenarioData.ts +74 -7
  30. package/analyzer-template/packages/ai/src/lib/generateChangesEntityScenarios.ts +89 -112
  31. package/analyzer-template/packages/ai/src/lib/generateEntityDataStructure.ts +6 -0
  32. package/analyzer-template/packages/ai/src/lib/generateEntityScenarioData.ts +486 -86
  33. package/analyzer-template/packages/ai/src/lib/generateEntityScenarios.ts +182 -104
  34. package/analyzer-template/packages/ai/src/lib/generateExecutionFlows.ts +201 -0
  35. package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromConditionalEffects.ts +528 -0
  36. package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromConditionals.ts +1019 -0
  37. package/analyzer-template/packages/ai/src/lib/getConditionalUsagesFromCode.ts +143 -31
  38. package/analyzer-template/packages/ai/src/lib/guessScenarioDataFromDescription.ts +8 -2
  39. package/analyzer-template/packages/ai/src/lib/isolateScopes.ts +276 -3
  40. package/analyzer-template/packages/ai/src/lib/mergeStatements.ts +33 -3
  41. package/analyzer-template/packages/ai/src/lib/promptGenerators/gatherAttributesMap.ts +7 -0
  42. package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChangesEntityScenarioDataGenerator.ts +1 -1
  43. package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.ts +32 -102
  44. package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.ts +71 -4
  45. package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.ts +14 -53
  46. package/analyzer-template/packages/ai/src/lib/promptGenerators/generateMissingKeysPrompt.ts +58 -0
  47. package/analyzer-template/packages/ai/src/lib/promptGenerators/guessNewScenarioDataFromDescriptionGenerator.ts +28 -2
  48. package/analyzer-template/packages/ai/src/lib/resolvePathToControllable.ts +690 -0
  49. package/analyzer-template/packages/ai/src/lib/splitOutsideParentheses.ts +5 -1
  50. package/analyzer-template/packages/ai/src/lib/validateExecutionFlowPaths.ts +531 -0
  51. package/analyzer-template/packages/ai/src/lib/worker/SerializableDataStructure.ts +102 -0
  52. package/analyzer-template/packages/ai/src/lib/worker/analyzeScopeWorker.ts +8 -1
  53. package/analyzer-template/packages/analyze/src/lib/FileAnalyzer.ts +14 -0
  54. package/analyzer-template/packages/analyze/src/lib/asts/nodes/index.ts +1 -0
  55. package/analyzer-template/packages/analyze/src/lib/asts/nodes/isAsyncFunction.ts +67 -0
  56. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +458 -267
  57. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +18 -0
  58. package/analyzer-template/packages/analyze/src/lib/files/analyze/findOrCreateEntity.ts +3 -0
  59. package/analyzer-template/packages/analyze/src/lib/files/analyzeChange.ts +31 -15
  60. package/analyzer-template/packages/analyze/src/lib/files/analyzeEntity.ts +11 -7
  61. package/analyzer-template/packages/analyze/src/lib/files/analyzeInitial.ts +11 -12
  62. package/analyzer-template/packages/analyze/src/lib/files/enums/steps.ts +1 -1
  63. package/analyzer-template/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.ts +196 -0
  64. package/analyzer-template/packages/analyze/src/lib/files/scenarios/enrichUnknownTypesFromSourceEquivalencies.ts +102 -0
  65. package/analyzer-template/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.ts +588 -52
  66. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateChangesScenarioData.ts +1 -1
  67. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateChangesScenarios.ts +28 -62
  68. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +299 -133
  69. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.ts +156 -0
  70. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarioData.ts +78 -83
  71. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarios.ts +4 -8
  72. package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +384 -94
  73. package/analyzer-template/packages/aws/codebuild/index.ts +1 -0
  74. package/analyzer-template/packages/aws/dist/src/lib/codebuild/waitForBuild.d.ts +11 -1
  75. package/analyzer-template/packages/aws/dist/src/lib/codebuild/waitForBuild.d.ts.map +1 -1
  76. package/analyzer-template/packages/aws/dist/src/lib/codebuild/waitForBuild.js +29 -18
  77. package/analyzer-template/packages/aws/dist/src/lib/codebuild/waitForBuild.js.map +1 -1
  78. package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsDefineContainer.d.ts +2 -2
  79. package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsDefineContainer.d.ts.map +1 -1
  80. package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsDefineContainer.js +2 -2
  81. package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsDefineContainer.js.map +1 -1
  82. package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsTaskFactory.d.ts +8 -18
  83. package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsTaskFactory.d.ts.map +1 -1
  84. package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsTaskFactory.js +17 -61
  85. package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsTaskFactory.js.map +1 -1
  86. package/analyzer-template/packages/aws/dist/src/lib/s3/checkS3ObjectExists.d.ts +15 -0
  87. package/analyzer-template/packages/aws/dist/src/lib/s3/checkS3ObjectExists.d.ts.map +1 -0
  88. package/analyzer-template/packages/aws/dist/src/lib/s3/checkS3ObjectExists.js +31 -0
  89. package/analyzer-template/packages/aws/dist/src/lib/s3/checkS3ObjectExists.js.map +1 -0
  90. package/analyzer-template/packages/aws/dist/src/lib/s3/uploadFileToS3.d.ts.map +1 -1
  91. package/analyzer-template/packages/aws/dist/src/lib/s3/uploadFileToS3.js +8 -1
  92. package/analyzer-template/packages/aws/dist/src/lib/s3/uploadFileToS3.js.map +1 -1
  93. package/analyzer-template/packages/aws/package.json +2 -2
  94. package/analyzer-template/packages/aws/s3/index.ts +1 -0
  95. package/analyzer-template/packages/aws/src/lib/codebuild/waitForBuild.ts +43 -19
  96. package/analyzer-template/packages/aws/src/lib/ecs/ecsDefineContainer.ts +3 -3
  97. package/analyzer-template/packages/aws/src/lib/ecs/ecsTaskFactory.ts +17 -69
  98. package/analyzer-template/packages/aws/src/lib/s3/checkS3ObjectExists.ts +47 -0
  99. package/analyzer-template/packages/aws/src/lib/s3/uploadFileToS3.ts +8 -1
  100. package/analyzer-template/packages/database/src/lib/kysely/db.ts +4 -4
  101. package/analyzer-template/packages/database/src/lib/kysely/tableRelations.ts +2 -2
  102. package/analyzer-template/packages/database/src/lib/kysely/tables/debugReportsTable.ts +36 -9
  103. package/analyzer-template/packages/database/src/lib/loadReadyToBeCapturedAnalyses.ts +7 -3
  104. package/analyzer-template/packages/generate/index.ts +3 -0
  105. package/analyzer-template/packages/generate/src/lib/componentScenarioPage/componentScenarioPageNext.ts +17 -1
  106. package/analyzer-template/packages/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.ts +193 -0
  107. package/analyzer-template/packages/generate/src/lib/componentScenarioPage/generateScenarioServerComponent.ts +73 -0
  108. package/analyzer-template/packages/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.ts +9 -4
  109. package/analyzer-template/packages/generate/src/lib/deepMerge.ts +26 -1
  110. package/analyzer-template/packages/generate/src/lib/scenarioComponentForServer.ts +114 -0
  111. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts +2 -2
  112. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js +2 -2
  113. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tableRelations.d.ts +2 -2
  114. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/analysesTable.d.ts +1 -11
  115. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/analysesTable.d.ts.map +1 -1
  116. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.d.ts +30 -7
  117. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.d.ts.map +1 -1
  118. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.js +9 -3
  119. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.js.map +1 -1
  120. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/entitiesTable.d.ts +1 -0
  121. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/entitiesTable.d.ts.map +1 -1
  122. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/scenariosTable.d.ts +2 -6
  123. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/scenariosTable.d.ts.map +1 -1
  124. package/analyzer-template/packages/github/dist/database/src/lib/loadReadyToBeCapturedAnalyses.d.ts.map +1 -1
  125. package/analyzer-template/packages/github/dist/database/src/lib/loadReadyToBeCapturedAnalyses.js +7 -4
  126. package/analyzer-template/packages/github/dist/database/src/lib/loadReadyToBeCapturedAnalyses.js.map +1 -1
  127. package/analyzer-template/packages/github/dist/generate/index.d.ts +3 -0
  128. package/analyzer-template/packages/github/dist/generate/index.d.ts.map +1 -1
  129. package/analyzer-template/packages/github/dist/generate/index.js +3 -0
  130. package/analyzer-template/packages/github/dist/generate/index.js.map +1 -1
  131. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageNext.d.ts.map +1 -1
  132. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageNext.js +16 -1
  133. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageNext.js.map +1 -1
  134. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.d.ts +9 -0
  135. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.d.ts.map +1 -0
  136. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.js +189 -0
  137. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.js.map +1 -0
  138. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioServerComponent.d.ts +20 -0
  139. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioServerComponent.d.ts.map +1 -0
  140. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioServerComponent.js +53 -0
  141. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioServerComponent.js.map +1 -0
  142. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.d.ts.map +1 -1
  143. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js +8 -4
  144. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js.map +1 -1
  145. package/analyzer-template/packages/github/dist/generate/src/lib/deepMerge.d.ts.map +1 -1
  146. package/analyzer-template/packages/github/dist/generate/src/lib/deepMerge.js +27 -1
  147. package/analyzer-template/packages/github/dist/generate/src/lib/deepMerge.js.map +1 -1
  148. package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponentForServer.d.ts +8 -0
  149. package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponentForServer.d.ts.map +1 -0
  150. package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponentForServer.js +89 -0
  151. package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponentForServer.js.map +1 -0
  152. package/analyzer-template/packages/github/dist/github/src/lib/loadOrCreateCommit.d.ts.map +1 -1
  153. package/analyzer-template/packages/github/dist/github/src/lib/loadOrCreateCommit.js +10 -0
  154. package/analyzer-template/packages/github/dist/github/src/lib/loadOrCreateCommit.js.map +1 -1
  155. package/analyzer-template/packages/github/dist/github/src/lib/syncPrimaryBranch.d.ts.map +1 -1
  156. package/analyzer-template/packages/github/dist/github/src/lib/syncPrimaryBranch.js +3 -0
  157. package/analyzer-template/packages/github/dist/github/src/lib/syncPrimaryBranch.js.map +1 -1
  158. package/analyzer-template/packages/github/dist/types/index.d.ts +2 -2
  159. package/analyzer-template/packages/github/dist/types/index.d.ts.map +1 -1
  160. package/analyzer-template/packages/github/dist/types/index.js.map +1 -1
  161. package/analyzer-template/packages/github/dist/types/src/types/Analysis.d.ts +63 -13
  162. package/analyzer-template/packages/github/dist/types/src/types/Analysis.d.ts.map +1 -1
  163. package/analyzer-template/packages/github/dist/types/src/types/Entity.d.ts +2 -0
  164. package/analyzer-template/packages/github/dist/types/src/types/Entity.d.ts.map +1 -1
  165. package/analyzer-template/packages/github/dist/types/src/types/Scenario.d.ts +11 -6
  166. package/analyzer-template/packages/github/dist/types/src/types/Scenario.d.ts.map +1 -1
  167. package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts +146 -0
  168. package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
  169. package/analyzer-template/packages/github/dist/types/src/types/StatementInfo.d.ts +2 -0
  170. package/analyzer-template/packages/github/dist/types/src/types/StatementInfo.d.ts.map +1 -1
  171. package/analyzer-template/packages/github/src/lib/loadOrCreateCommit.ts +14 -0
  172. package/analyzer-template/packages/github/src/lib/syncPrimaryBranch.ts +2 -0
  173. package/analyzer-template/packages/process/index.ts +2 -0
  174. package/analyzer-template/packages/process/package.json +12 -0
  175. package/analyzer-template/packages/process/tsconfig.json +8 -0
  176. package/analyzer-template/packages/types/index.ts +4 -0
  177. package/analyzer-template/packages/types/src/types/Analysis.ts +79 -13
  178. package/analyzer-template/packages/types/src/types/Entity.ts +2 -0
  179. package/analyzer-template/packages/types/src/types/Scenario.ts +11 -10
  180. package/analyzer-template/packages/types/src/types/ScenariosDataStructure.ts +161 -0
  181. package/analyzer-template/packages/types/src/types/StatementInfo.ts +2 -0
  182. package/analyzer-template/packages/utils/dist/types/index.d.ts +2 -2
  183. package/analyzer-template/packages/utils/dist/types/index.d.ts.map +1 -1
  184. package/analyzer-template/packages/utils/dist/types/index.js.map +1 -1
  185. package/analyzer-template/packages/utils/dist/types/src/types/Analysis.d.ts +63 -13
  186. package/analyzer-template/packages/utils/dist/types/src/types/Analysis.d.ts.map +1 -1
  187. package/analyzer-template/packages/utils/dist/types/src/types/Entity.d.ts +2 -0
  188. package/analyzer-template/packages/utils/dist/types/src/types/Entity.d.ts.map +1 -1
  189. package/analyzer-template/packages/utils/dist/types/src/types/Scenario.d.ts +11 -6
  190. package/analyzer-template/packages/utils/dist/types/src/types/Scenario.d.ts.map +1 -1
  191. package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts +146 -0
  192. package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
  193. package/analyzer-template/packages/utils/dist/types/src/types/StatementInfo.d.ts +2 -0
  194. package/analyzer-template/packages/utils/dist/types/src/types/StatementInfo.d.ts.map +1 -1
  195. package/analyzer-template/playwright/capture.ts +37 -18
  196. package/analyzer-template/playwright/getCodeYamInfo.ts +12 -7
  197. package/analyzer-template/playwright/takeElementScreenshot.ts +26 -11
  198. package/analyzer-template/playwright/waitForServer.ts +21 -6
  199. package/analyzer-template/project/analyzeBaselineCommit.ts +4 -0
  200. package/analyzer-template/project/analyzeBranchCommit.ts +4 -0
  201. package/analyzer-template/project/analyzeFileEntities.ts +4 -0
  202. package/analyzer-template/project/analyzeRegularCommit.ts +4 -0
  203. package/analyzer-template/project/constructMockCode.ts +868 -132
  204. package/analyzer-template/project/controller/startController.ts +16 -1
  205. package/analyzer-template/project/executeLibraryFunctionDirect.ts +7 -3
  206. package/analyzer-template/project/mocks/analyzeFileMock.ts +8 -7
  207. package/analyzer-template/project/orchestrateCapture/KyselyAnalysisLoader.ts +3 -6
  208. package/analyzer-template/project/orchestrateCapture/SequentialCaptureTaskRunner.ts +49 -33
  209. package/analyzer-template/project/orchestrateCapture.ts +10 -3
  210. package/analyzer-template/project/reconcileMockDataKeys.ts +102 -2
  211. package/analyzer-template/project/runAnalysis.ts +7 -0
  212. package/analyzer-template/project/serverOnlyModules.ts +127 -2
  213. package/analyzer-template/project/start.ts +26 -4
  214. package/analyzer-template/project/startScenarioCapture.ts +72 -40
  215. package/analyzer-template/project/writeMockDataTsx.ts +118 -55
  216. package/analyzer-template/project/writeScenarioClientWrapper.ts +21 -0
  217. package/analyzer-template/project/writeScenarioComponents.ts +263 -92
  218. package/analyzer-template/project/writeScenarioFiles.ts +26 -0
  219. package/analyzer-template/project/writeSimpleRoot.ts +13 -15
  220. package/analyzer-template/scripts/comboWorkerLoop.cjs +1 -0
  221. package/analyzer-template/scripts/defaultCmd.sh +9 -0
  222. package/analyzer-template/tsconfig.json +2 -1
  223. package/background/src/lib/local/createLocalAnalyzer.js +1 -29
  224. package/background/src/lib/local/createLocalAnalyzer.js.map +1 -1
  225. package/background/src/lib/local/execAsync.js +1 -1
  226. package/background/src/lib/local/execAsync.js.map +1 -1
  227. package/background/src/lib/virtualized/common/execAsync.js +1 -1
  228. package/background/src/lib/virtualized/common/execAsync.js.map +1 -1
  229. package/background/src/lib/virtualized/project/analyzeBaselineCommit.js +2 -1
  230. package/background/src/lib/virtualized/project/analyzeBaselineCommit.js.map +1 -1
  231. package/background/src/lib/virtualized/project/analyzeBranchCommit.js +2 -1
  232. package/background/src/lib/virtualized/project/analyzeBranchCommit.js.map +1 -1
  233. package/background/src/lib/virtualized/project/analyzeFileEntities.js +2 -1
  234. package/background/src/lib/virtualized/project/analyzeFileEntities.js.map +1 -1
  235. package/background/src/lib/virtualized/project/analyzeRegularCommit.js +2 -1
  236. package/background/src/lib/virtualized/project/analyzeRegularCommit.js.map +1 -1
  237. package/background/src/lib/virtualized/project/constructMockCode.js +799 -121
  238. package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
  239. package/background/src/lib/virtualized/project/controller/startController.js +11 -1
  240. package/background/src/lib/virtualized/project/controller/startController.js.map +1 -1
  241. package/background/src/lib/virtualized/project/executeLibraryFunctionDirect.js +6 -3
  242. package/background/src/lib/virtualized/project/executeLibraryFunctionDirect.js.map +1 -1
  243. package/background/src/lib/virtualized/project/mocks/analyzeFileMock.js +7 -7
  244. package/background/src/lib/virtualized/project/mocks/analyzeFileMock.js.map +1 -1
  245. package/background/src/lib/virtualized/project/orchestrateCapture/KyselyAnalysisLoader.js +3 -2
  246. package/background/src/lib/virtualized/project/orchestrateCapture/KyselyAnalysisLoader.js.map +1 -1
  247. package/background/src/lib/virtualized/project/orchestrateCapture/SequentialCaptureTaskRunner.js +42 -28
  248. package/background/src/lib/virtualized/project/orchestrateCapture/SequentialCaptureTaskRunner.js.map +1 -1
  249. package/background/src/lib/virtualized/project/orchestrateCapture.js +7 -4
  250. package/background/src/lib/virtualized/project/orchestrateCapture.js.map +1 -1
  251. package/background/src/lib/virtualized/project/reconcileMockDataKeys.js +87 -2
  252. package/background/src/lib/virtualized/project/reconcileMockDataKeys.js.map +1 -1
  253. package/background/src/lib/virtualized/project/runAnalysis.js +6 -0
  254. package/background/src/lib/virtualized/project/runAnalysis.js.map +1 -1
  255. package/background/src/lib/virtualized/project/serverOnlyModules.js +106 -3
  256. package/background/src/lib/virtualized/project/serverOnlyModules.js.map +1 -1
  257. package/background/src/lib/virtualized/project/start.js +21 -4
  258. package/background/src/lib/virtualized/project/start.js.map +1 -1
  259. package/background/src/lib/virtualized/project/startScenarioCapture.js +56 -30
  260. package/background/src/lib/virtualized/project/startScenarioCapture.js.map +1 -1
  261. package/background/src/lib/virtualized/project/writeMockDataTsx.js +110 -48
  262. package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
  263. package/background/src/lib/virtualized/project/writeScenarioClientWrapper.js +15 -0
  264. package/background/src/lib/virtualized/project/writeScenarioClientWrapper.js.map +1 -0
  265. package/background/src/lib/virtualized/project/writeScenarioComponents.js +211 -75
  266. package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
  267. package/background/src/lib/virtualized/project/writeScenarioFiles.js +19 -0
  268. package/background/src/lib/virtualized/project/writeScenarioFiles.js.map +1 -1
  269. package/background/src/lib/virtualized/project/writeSimpleRoot.js +13 -13
  270. package/background/src/lib/virtualized/project/writeSimpleRoot.js.map +1 -1
  271. package/codeyam-cli/src/cli.js +5 -1
  272. package/codeyam-cli/src/cli.js.map +1 -1
  273. package/codeyam-cli/src/commands/analyze.js +1 -1
  274. package/codeyam-cli/src/commands/analyze.js.map +1 -1
  275. package/codeyam-cli/src/commands/baseline.js +174 -0
  276. package/codeyam-cli/src/commands/baseline.js.map +1 -0
  277. package/codeyam-cli/src/commands/debug.js +28 -18
  278. package/codeyam-cli/src/commands/debug.js.map +1 -1
  279. package/codeyam-cli/src/commands/default.js +0 -15
  280. package/codeyam-cli/src/commands/default.js.map +1 -1
  281. package/codeyam-cli/src/commands/recapture.js +44 -23
  282. package/codeyam-cli/src/commands/recapture.js.map +1 -1
  283. package/codeyam-cli/src/commands/report.js +72 -24
  284. package/codeyam-cli/src/commands/report.js.map +1 -1
  285. package/codeyam-cli/src/commands/start.js +8 -12
  286. package/codeyam-cli/src/commands/start.js.map +1 -1
  287. package/codeyam-cli/src/commands/status.js +23 -1
  288. package/codeyam-cli/src/commands/status.js.map +1 -1
  289. package/codeyam-cli/src/commands/test-startup.js +1 -1
  290. package/codeyam-cli/src/commands/test-startup.js.map +1 -1
  291. package/codeyam-cli/src/commands/wipe.js +108 -0
  292. package/codeyam-cli/src/commands/wipe.js.map +1 -0
  293. package/codeyam-cli/src/utils/__tests__/serverVersionStaleness.test.js +81 -0
  294. package/codeyam-cli/src/utils/__tests__/serverVersionStaleness.test.js.map +1 -0
  295. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js +27 -27
  296. package/codeyam-cli/src/utils/analysisRunner.js +8 -13
  297. package/codeyam-cli/src/utils/analysisRunner.js.map +1 -1
  298. package/codeyam-cli/src/utils/backgroundServer.js +12 -2
  299. package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
  300. package/codeyam-cli/src/utils/database.js +91 -5
  301. package/codeyam-cli/src/utils/database.js.map +1 -1
  302. package/codeyam-cli/src/utils/generateReport.js +253 -106
  303. package/codeyam-cli/src/utils/generateReport.js.map +1 -1
  304. package/codeyam-cli/src/utils/git.js +79 -0
  305. package/codeyam-cli/src/utils/git.js.map +1 -0
  306. package/codeyam-cli/src/utils/install-skills.js +11 -11
  307. package/codeyam-cli/src/utils/install-skills.js.map +1 -1
  308. package/codeyam-cli/src/utils/queue/__tests__/manager.test.js +38 -0
  309. package/codeyam-cli/src/utils/queue/__tests__/manager.test.js.map +1 -1
  310. package/codeyam-cli/src/utils/queue/job.js +239 -16
  311. package/codeyam-cli/src/utils/queue/job.js.map +1 -1
  312. package/codeyam-cli/src/utils/queue/manager.js +19 -7
  313. package/codeyam-cli/src/utils/queue/manager.js.map +1 -1
  314. package/codeyam-cli/src/utils/queue/persistence.js.map +1 -1
  315. package/codeyam-cli/src/utils/serverState.js.map +1 -1
  316. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +5 -5
  317. package/codeyam-cli/src/utils/versionInfo.js +25 -19
  318. package/codeyam-cli/src/utils/versionInfo.js.map +1 -1
  319. package/codeyam-cli/src/utils/wipe.js +128 -0
  320. package/codeyam-cli/src/utils/wipe.js.map +1 -0
  321. package/codeyam-cli/src/webserver/app/lib/database.js +96 -0
  322. package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
  323. package/codeyam-cli/src/webserver/app/lib/dbNotifier.js.map +1 -1
  324. package/codeyam-cli/src/webserver/backgroundServer.js +2 -5
  325. package/codeyam-cli/src/webserver/backgroundServer.js.map +1 -1
  326. package/codeyam-cli/src/webserver/build/client/assets/EntityItem-vauWK972.js +1 -0
  327. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeBadge-DKdsUF7Y.js → EntityTypeBadge-COi5OvsN.js} +1 -1
  328. package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-BwdQv49w.js +41 -0
  329. package/codeyam-cli/src/webserver/build/client/assets/InlineSpinner-CEleMv_j.js +34 -0
  330. package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-D68KarMg.js +25 -0
  331. package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-L75Wvqgw.js +3 -0
  332. package/codeyam-cli/src/webserver/build/client/assets/LoadingDots-C53WM8qn.js +6 -0
  333. package/codeyam-cli/src/webserver/build/client/assets/LogViewer-CrNkmy4i.js +3 -0
  334. package/codeyam-cli/src/webserver/build/client/assets/ReportIssueModal-DzJRkCkr.js +11 -0
  335. package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-CQifa1n-.js +1 -0
  336. package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-CyaBFX7l.js +20 -0
  337. package/codeyam-cli/src/webserver/build/client/assets/{TruncatedFilePath-CWjSsLqY.js → TruncatedFilePath-D36O1rzU.js} +1 -1
  338. package/codeyam-cli/src/webserver/build/client/assets/_index-Be83mo_j.js +11 -0
  339. package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-BN6wu6Y-.js +37 -0
  340. package/codeyam-cli/src/webserver/build/client/assets/chevron-down-DgTPh8H-.js +6 -0
  341. package/codeyam-cli/src/webserver/build/client/assets/chunk-EPOLDU6W-DdQKK6on.js +51 -0
  342. package/codeyam-cli/src/webserver/build/client/assets/circle-check-Dmr2bb1R.js +6 -0
  343. package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-Do4ZLUYa.js +21 -0
  344. package/codeyam-cli/src/webserver/build/client/assets/{cy-logo-cli-C1gnJVOL.svg → cy-logo-cli-CCKUIm0S.svg} +2 -2
  345. package/codeyam-cli/src/webserver/build/client/assets/cy-logo-cli-DcX-ZS3p.js +1 -0
  346. package/codeyam-cli/src/webserver/build/client/assets/dev.empty-Bn6aCAy_.js +1 -0
  347. package/codeyam-cli/src/webserver/build/client/assets/entity._sha._-CbdFyxZh.js +23 -0
  348. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.fullscreen-B4iCfs5M.js +6 -0
  349. package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-wDWZZO1W.js +6 -0
  350. package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-BMbl7MeQ.js +5 -0
  351. package/codeyam-cli/src/webserver/build/client/assets/entry.client-5wRKRIH9.js +29 -0
  352. package/codeyam-cli/src/webserver/build/client/assets/executionFlowCoverage-BWhdfn70.js +1 -0
  353. package/codeyam-cli/src/webserver/build/client/assets/fileTableUtils-DD3SDH7t.js +1 -0
  354. package/codeyam-cli/src/webserver/build/client/assets/files-DKyMFI90.js +1 -0
  355. package/codeyam-cli/src/webserver/build/client/assets/git-zXjT7J0G.js +15 -0
  356. package/codeyam-cli/src/webserver/build/client/assets/globals-DTTQ3gY7.css +1 -0
  357. package/codeyam-cli/src/webserver/build/client/assets/html2canvas-pro.esm-fmIEn3Bc.js +9 -0
  358. package/codeyam-cli/src/webserver/build/client/assets/index-DLbXwndH.js +9 -0
  359. package/codeyam-cli/src/webserver/build/client/assets/index-gPZ-lad1.js +3 -0
  360. package/codeyam-cli/src/webserver/build/client/assets/loader-circle-BsPXJ81F.js +6 -0
  361. package/codeyam-cli/src/webserver/build/client/assets/manifest-22590fcf.js +1 -0
  362. package/codeyam-cli/src/webserver/build/client/assets/preload-helper-ckwbz45p.js +1 -0
  363. package/codeyam-cli/src/webserver/build/client/assets/root-BsAarjAM.js +57 -0
  364. package/codeyam-cli/src/webserver/build/client/assets/scenarioStatus-B_8jpV3e.js +1 -0
  365. package/codeyam-cli/src/webserver/build/client/assets/search-P2FKIUql.js +6 -0
  366. package/codeyam-cli/src/webserver/build/client/assets/settings-B2eDuBj8.js +1 -0
  367. package/codeyam-cli/src/webserver/build/client/assets/simulations-L18M6-kN.js +1 -0
  368. package/codeyam-cli/src/webserver/build/client/assets/triangle-alert-BDz7kbVA.js +6 -0
  369. package/codeyam-cli/src/webserver/build/client/assets/useCustomSizes-29dDmbH8.js +1 -0
  370. package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-CmrTPlIB.js → useLastLogLine-BUm0UVJm.js} +1 -1
  371. package/codeyam-cli/src/webserver/build/client/assets/useReportContext-CkIOKTrZ.js +1 -0
  372. package/codeyam-cli/src/webserver/build/client/assets/{useToast-C1ig_BmP.js → useToast-KKw5kTn-.js} +1 -1
  373. package/codeyam-cli/src/webserver/build/server/assets/index-BND5I5fv.js +1 -0
  374. package/codeyam-cli/src/webserver/build/server/assets/server-build-CFXnd7MG.js +228 -0
  375. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  376. package/codeyam-cli/src/webserver/build-info.json +5 -5
  377. package/codeyam-cli/src/webserver/devServer.js +1 -3
  378. package/codeyam-cli/src/webserver/devServer.js.map +1 -1
  379. package/codeyam-cli/src/webserver/server.js +35 -25
  380. package/codeyam-cli/src/webserver/server.js.map +1 -1
  381. package/codeyam-cli/templates/{codeyam-debug-skill.md → codeyam:debug.md} +1 -1
  382. package/codeyam-cli/templates/codeyam:diagnose.md +625 -0
  383. package/codeyam-cli/templates/{codeyam-setup-skill.md → codeyam:setup.md} +139 -4
  384. package/codeyam-cli/templates/{codeyam-sim-skill.md → codeyam:sim.md} +1 -1
  385. package/codeyam-cli/templates/{codeyam-test-skill.md → codeyam:test.md} +1 -1
  386. package/codeyam-cli/templates/{codeyam-verify-skill.md → codeyam:verify.md} +1 -1
  387. package/package.json +8 -8
  388. package/packages/ai/index.js +2 -4
  389. package/packages/ai/index.js.map +1 -1
  390. package/packages/ai/src/lib/analyzeScope.js +107 -0
  391. package/packages/ai/src/lib/analyzeScope.js.map +1 -1
  392. package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js +76 -1
  393. package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js.map +1 -1
  394. package/packages/ai/src/lib/astScopes/conditionalEffectsExtractor.js +435 -0
  395. package/packages/ai/src/lib/astScopes/conditionalEffectsExtractor.js.map +1 -0
  396. package/packages/ai/src/lib/astScopes/methodSemantics.js +29 -0
  397. package/packages/ai/src/lib/astScopes/methodSemantics.js.map +1 -1
  398. package/packages/ai/src/lib/astScopes/patterns/ifStatementHandler.js +8 -0
  399. package/packages/ai/src/lib/astScopes/patterns/ifStatementHandler.js.map +1 -1
  400. package/packages/ai/src/lib/astScopes/patterns/switchStatementHandler.js +23 -0
  401. package/packages/ai/src/lib/astScopes/patterns/switchStatementHandler.js.map +1 -1
  402. package/packages/ai/src/lib/astScopes/patterns/variableDeclarationHandler.js +239 -1
  403. package/packages/ai/src/lib/astScopes/patterns/variableDeclarationHandler.js.map +1 -1
  404. package/packages/ai/src/lib/astScopes/processExpression.js +728 -87
  405. package/packages/ai/src/lib/astScopes/processExpression.js.map +1 -1
  406. package/packages/ai/src/lib/checkAllAttributes.js +24 -9
  407. package/packages/ai/src/lib/checkAllAttributes.js.map +1 -1
  408. package/packages/ai/src/lib/completionCall.js +17 -1
  409. package/packages/ai/src/lib/completionCall.js.map +1 -1
  410. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +1126 -82
  411. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
  412. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js +2 -1
  413. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js.map +1 -1
  414. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/MuiManager.js +482 -0
  415. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/MuiManager.js.map +1 -0
  416. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.js +173 -55
  417. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.js.map +1 -1
  418. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js +16 -1
  419. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js.map +1 -1
  420. package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js +35 -2
  421. package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js.map +1 -1
  422. package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js +20 -0
  423. package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js.map +1 -1
  424. package/packages/ai/src/lib/dataStructure/helpers/convertNullToUndefinedBySchema.js +86 -0
  425. package/packages/ai/src/lib/dataStructure/helpers/convertNullToUndefinedBySchema.js.map +1 -0
  426. package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js +34 -3
  427. package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js.map +1 -1
  428. package/packages/ai/src/lib/deepEqual.js +32 -0
  429. package/packages/ai/src/lib/deepEqual.js.map +1 -0
  430. package/packages/ai/src/lib/generateChangesEntityScenarioData.js +62 -5
  431. package/packages/ai/src/lib/generateChangesEntityScenarioData.js.map +1 -1
  432. package/packages/ai/src/lib/generateChangesEntityScenarios.js +81 -90
  433. package/packages/ai/src/lib/generateChangesEntityScenarios.js.map +1 -1
  434. package/packages/ai/src/lib/generateEntityDataStructure.js +5 -0
  435. package/packages/ai/src/lib/generateEntityDataStructure.js.map +1 -1
  436. package/packages/ai/src/lib/generateEntityScenarioData.js +398 -81
  437. package/packages/ai/src/lib/generateEntityScenarioData.js.map +1 -1
  438. package/packages/ai/src/lib/generateEntityScenarios.js +168 -82
  439. package/packages/ai/src/lib/generateEntityScenarios.js.map +1 -1
  440. package/packages/ai/src/lib/generateExecutionFlows.js +123 -0
  441. package/packages/ai/src/lib/generateExecutionFlows.js.map +1 -0
  442. package/packages/ai/src/lib/generateExecutionFlowsFromConditionalEffects.js +380 -0
  443. package/packages/ai/src/lib/generateExecutionFlowsFromConditionalEffects.js.map +1 -0
  444. package/packages/ai/src/lib/generateExecutionFlowsFromConditionals.js +742 -0
  445. package/packages/ai/src/lib/generateExecutionFlowsFromConditionals.js.map +1 -0
  446. package/packages/ai/src/lib/getConditionalUsagesFromCode.js +84 -14
  447. package/packages/ai/src/lib/getConditionalUsagesFromCode.js.map +1 -1
  448. package/packages/ai/src/lib/guessScenarioDataFromDescription.js +2 -1
  449. package/packages/ai/src/lib/guessScenarioDataFromDescription.js.map +1 -1
  450. package/packages/ai/src/lib/isolateScopes.js +231 -4
  451. package/packages/ai/src/lib/isolateScopes.js.map +1 -1
  452. package/packages/ai/src/lib/mergeStatements.js +26 -3
  453. package/packages/ai/src/lib/mergeStatements.js.map +1 -1
  454. package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js +6 -0
  455. package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js.map +1 -1
  456. package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenarioDataGenerator.js +1 -1
  457. package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenarioDataGenerator.js.map +1 -1
  458. package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.js +21 -64
  459. package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.js.map +1 -1
  460. package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js +58 -4
  461. package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js.map +1 -1
  462. package/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.js +10 -34
  463. package/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.js.map +1 -1
  464. package/packages/ai/src/lib/promptGenerators/generateMissingKeysPrompt.js +45 -0
  465. package/packages/ai/src/lib/promptGenerators/generateMissingKeysPrompt.js.map +1 -0
  466. package/packages/ai/src/lib/promptGenerators/guessNewScenarioDataFromDescriptionGenerator.js +16 -3
  467. package/packages/ai/src/lib/promptGenerators/guessNewScenarioDataFromDescriptionGenerator.js.map +1 -1
  468. package/packages/ai/src/lib/resolvePathToControllable.js +563 -0
  469. package/packages/ai/src/lib/resolvePathToControllable.js.map +1 -0
  470. package/packages/ai/src/lib/splitOutsideParentheses.js +3 -1
  471. package/packages/ai/src/lib/splitOutsideParentheses.js.map +1 -1
  472. package/packages/ai/src/lib/worker/SerializableDataStructure.js +22 -0
  473. package/packages/ai/src/lib/worker/SerializableDataStructure.js.map +1 -1
  474. package/packages/ai/src/lib/worker/analyzeScopeWorker.js +4 -0
  475. package/packages/ai/src/lib/worker/analyzeScopeWorker.js.map +1 -1
  476. package/packages/analyze/src/lib/FileAnalyzer.js +15 -0
  477. package/packages/analyze/src/lib/FileAnalyzer.js.map +1 -1
  478. package/packages/analyze/src/lib/asts/nodes/index.js +1 -0
  479. package/packages/analyze/src/lib/asts/nodes/index.js.map +1 -1
  480. package/packages/analyze/src/lib/asts/nodes/isAsyncFunction.js +52 -0
  481. package/packages/analyze/src/lib/asts/nodes/isAsyncFunction.js.map +1 -0
  482. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +214 -50
  483. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
  484. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +10 -0
  485. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
  486. package/packages/analyze/src/lib/files/analyze/findOrCreateEntity.js +2 -0
  487. package/packages/analyze/src/lib/files/analyze/findOrCreateEntity.js.map +1 -1
  488. package/packages/analyze/src/lib/files/analyzeChange.js +21 -11
  489. package/packages/analyze/src/lib/files/analyzeChange.js.map +1 -1
  490. package/packages/analyze/src/lib/files/analyzeEntity.js +9 -8
  491. package/packages/analyze/src/lib/files/analyzeEntity.js.map +1 -1
  492. package/packages/analyze/src/lib/files/analyzeInitial.js +9 -10
  493. package/packages/analyze/src/lib/files/analyzeInitial.js.map +1 -1
  494. package/packages/analyze/src/lib/files/enums/steps.js +1 -1
  495. package/packages/analyze/src/lib/files/enums/steps.js.map +1 -1
  496. package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js +159 -0
  497. package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js.map +1 -0
  498. package/packages/analyze/src/lib/files/scenarios/enrichUnknownTypesFromSourceEquivalencies.js +85 -0
  499. package/packages/analyze/src/lib/files/scenarios/enrichUnknownTypesFromSourceEquivalencies.js.map +1 -0
  500. package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js +458 -48
  501. package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js.map +1 -1
  502. package/packages/analyze/src/lib/files/scenarios/generateChangesScenarioData.js +1 -1
  503. package/packages/analyze/src/lib/files/scenarios/generateChangesScenarioData.js.map +1 -1
  504. package/packages/analyze/src/lib/files/scenarios/generateChangesScenarios.js +29 -34
  505. package/packages/analyze/src/lib/files/scenarios/generateChangesScenarios.js.map +1 -1
  506. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +235 -81
  507. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
  508. package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js +96 -0
  509. package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js.map +1 -0
  510. package/packages/analyze/src/lib/files/scenarios/generateScenarioData.js +56 -69
  511. package/packages/analyze/src/lib/files/scenarios/generateScenarioData.js.map +1 -1
  512. package/packages/analyze/src/lib/files/scenarios/generateScenarios.js +4 -8
  513. package/packages/analyze/src/lib/files/scenarios/generateScenarios.js.map +1 -1
  514. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +307 -89
  515. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
  516. package/packages/aws/src/lib/ecs/ecsDefineContainer.js +2 -2
  517. package/packages/aws/src/lib/ecs/ecsDefineContainer.js.map +1 -1
  518. package/packages/aws/src/lib/ecs/ecsTaskFactory.js +17 -61
  519. package/packages/aws/src/lib/ecs/ecsTaskFactory.js.map +1 -1
  520. package/packages/database/src/lib/kysely/db.js +2 -2
  521. package/packages/database/src/lib/kysely/tables/debugReportsTable.js +9 -3
  522. package/packages/database/src/lib/kysely/tables/debugReportsTable.js.map +1 -1
  523. package/packages/database/src/lib/loadReadyToBeCapturedAnalyses.js +7 -4
  524. package/packages/database/src/lib/loadReadyToBeCapturedAnalyses.js.map +1 -1
  525. package/packages/generate/index.js +3 -0
  526. package/packages/generate/index.js.map +1 -1
  527. package/packages/generate/src/lib/componentScenarioPage/componentScenarioPageNext.js +16 -1
  528. package/packages/generate/src/lib/componentScenarioPage/componentScenarioPageNext.js.map +1 -1
  529. package/packages/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.js +189 -0
  530. package/packages/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.js.map +1 -0
  531. package/packages/generate/src/lib/componentScenarioPage/generateScenarioServerComponent.js +53 -0
  532. package/packages/generate/src/lib/componentScenarioPage/generateScenarioServerComponent.js.map +1 -0
  533. package/packages/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js +8 -4
  534. package/packages/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js.map +1 -1
  535. package/packages/generate/src/lib/deepMerge.js +27 -1
  536. package/packages/generate/src/lib/deepMerge.js.map +1 -1
  537. package/packages/generate/src/lib/scenarioComponentForServer.js +89 -0
  538. package/packages/generate/src/lib/scenarioComponentForServer.js.map +1 -0
  539. package/packages/github/src/lib/loadOrCreateCommit.js +10 -0
  540. package/packages/github/src/lib/loadOrCreateCommit.js.map +1 -1
  541. package/packages/github/src/lib/syncPrimaryBranch.js +3 -0
  542. package/packages/github/src/lib/syncPrimaryBranch.js.map +1 -1
  543. package/packages/process/index.js +3 -0
  544. package/packages/process/index.js.map +1 -0
  545. package/packages/process/src/GlobalProcessManager.js.map +1 -0
  546. package/{background/src/lib/process → packages/process/src}/ProcessManager.js +1 -1
  547. package/packages/process/src/ProcessManager.js.map +1 -0
  548. package/packages/process/src/index.js.map +1 -0
  549. package/packages/process/src/managedExecAsync.js.map +1 -0
  550. package/packages/types/index.js.map +1 -1
  551. package/scripts/finalize-analyzer.cjs +3 -1
  552. package/analyzer-template/packages/ai/src/lib/findMatchingAttribute.ts +0 -102
  553. package/analyzer-template/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.ts +0 -197
  554. package/analyzer-template/packages/ai/src/lib/generateChangesEntityKeyAttributes.ts +0 -271
  555. package/analyzer-template/packages/ai/src/lib/generateEntityKeyAttributes.ts +0 -294
  556. package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityKeyAttributesGenerator.ts +0 -67
  557. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.ts +0 -115
  558. package/analyzer-template/process/INTEGRATION_COMPLETE.md +0 -333
  559. package/analyzer-template/process/INTEGRATION_EXAMPLE.md +0 -525
  560. package/analyzer-template/process/README.md +0 -507
  561. package/background/src/lib/process/GlobalProcessManager.js.map +0 -1
  562. package/background/src/lib/process/ProcessManager.js.map +0 -1
  563. package/background/src/lib/process/index.js.map +0 -1
  564. package/background/src/lib/process/managedExecAsync.js.map +0 -1
  565. package/codeyam-cli/scripts/fixtures/cal.com/universal-mocks/packages/prisma/index.js +0 -238
  566. package/codeyam-cli/scripts/fixtures/cal.com/universal-mocks/packages/prisma/index.js.map +0 -1
  567. package/codeyam-cli/src/webserver/build/client/assets/EntityItem-D0VW1-W7.js +0 -1
  568. package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-BAk4S4pI.js +0 -1
  569. package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-Y756iZxZ.js +0 -25
  570. package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-zzrrjW1p.js +0 -3
  571. package/codeyam-cli/src/webserver/build/client/assets/LogViewer-QMn7bJg6.js +0 -3
  572. package/codeyam-cli/src/webserver/build/client/assets/ReportIssueModal-DmP5mRxX.js +0 -1
  573. package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-BXwvsbLw.js +0 -1
  574. package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-DAmUX_1y.js +0 -5
  575. package/codeyam-cli/src/webserver/build/client/assets/_index-Df-nk4J5.js +0 -1
  576. package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-_ZUyFdie.js +0 -7
  577. package/codeyam-cli/src/webserver/build/client/assets/chevron-down-Eoh0PhcW.js +0 -1
  578. package/codeyam-cli/src/webserver/build/client/assets/chunk-WWGJGFF6-CZgPLy5i.js +0 -26
  579. package/codeyam-cli/src/webserver/build/client/assets/circle-check-DI-p9ZLZ.js +0 -1
  580. package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-DvyV2x6y.js +0 -1
  581. package/codeyam-cli/src/webserver/build/client/assets/dev.empty-DURu2qlF.js +0 -1
  582. package/codeyam-cli/src/webserver/build/client/assets/entity._sha._-DDobn9Xh.js +0 -16
  583. package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-CGdWnLD_.js +0 -1
  584. package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-DgMmzrKs.js +0 -5
  585. package/codeyam-cli/src/webserver/build/client/assets/entry.client-DEVXuhkn.js +0 -13
  586. package/codeyam-cli/src/webserver/build/client/assets/fileTableUtils-WPRQyc68.js +0 -1
  587. package/codeyam-cli/src/webserver/build/client/assets/files-B9u3lJer.js +0 -1
  588. package/codeyam-cli/src/webserver/build/client/assets/git-YGnKIuHU.js +0 -11
  589. package/codeyam-cli/src/webserver/build/client/assets/globals-28lrWTTo.css +0 -1
  590. package/codeyam-cli/src/webserver/build/client/assets/html2canvas-pro.esm-XQCGvadH.js +0 -5
  591. package/codeyam-cli/src/webserver/build/client/assets/index-CJ0uPJjV.js +0 -1
  592. package/codeyam-cli/src/webserver/build/client/assets/index-CfqeA2XG.js +0 -3
  593. package/codeyam-cli/src/webserver/build/client/assets/loader-circle-DIjSvh6B.js +0 -1
  594. package/codeyam-cli/src/webserver/build/client/assets/manifest-8125c15c.js +0 -1
  595. package/codeyam-cli/src/webserver/build/client/assets/preload-helper-BXl3LOEh.js +0 -1
  596. package/codeyam-cli/src/webserver/build/client/assets/root-C-g286WP.js +0 -16
  597. package/codeyam-cli/src/webserver/build/client/assets/search-xBKWfOxd.js +0 -1
  598. package/codeyam-cli/src/webserver/build/client/assets/settings-DVY_wGOx.js +0 -1
  599. package/codeyam-cli/src/webserver/build/client/assets/simulations-Be1pJo5A.js +0 -1
  600. package/codeyam-cli/src/webserver/build/client/assets/triangle-alert-CR-FkSvx.js +0 -1
  601. package/codeyam-cli/src/webserver/build/client/assets/useReportContext-DABetnSj.js +0 -1
  602. package/codeyam-cli/src/webserver/build/server/assets/index-DcR7DH9q.js +0 -1
  603. package/codeyam-cli/src/webserver/build/server/assets/server-build-BDBrfp7e.js +0 -175
  604. package/codeyam-cli/templates/debug-codeyam.md +0 -527
  605. package/packages/ai/src/lib/findMatchingAttribute.js +0 -77
  606. package/packages/ai/src/lib/findMatchingAttribute.js.map +0 -1
  607. package/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.js +0 -136
  608. package/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.js.map +0 -1
  609. package/packages/ai/src/lib/generateChangesEntityKeyAttributes.js +0 -220
  610. package/packages/ai/src/lib/generateChangesEntityKeyAttributes.js.map +0 -1
  611. package/packages/ai/src/lib/generateEntityKeyAttributes.js +0 -241
  612. package/packages/ai/src/lib/generateEntityKeyAttributes.js.map +0 -1
  613. package/packages/ai/src/lib/isFrontend.js +0 -5
  614. package/packages/ai/src/lib/isFrontend.js.map +0 -1
  615. package/packages/ai/src/lib/promptGenerators/generateEntityKeyAttributesGenerator.js +0 -40
  616. package/packages/ai/src/lib/promptGenerators/generateEntityKeyAttributesGenerator.js.map +0 -1
  617. package/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.js +0 -72
  618. package/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.js.map +0 -1
  619. /package/analyzer-template/{process → packages/process/src}/GlobalProcessManager.ts +0 -0
  620. /package/analyzer-template/{process → packages/process/src}/ProcessManager.ts +0 -0
  621. /package/analyzer-template/{process → packages/process/src}/index.ts +0 -0
  622. /package/analyzer-template/{process → packages/process/src}/managedExecAsync.ts +0 -0
  623. /package/{background/src/lib/process → packages/process/src}/GlobalProcessManager.js +0 -0
  624. /package/{background/src/lib/process → packages/process/src}/index.js +0 -0
  625. /package/{background/src/lib/process → packages/process/src}/managedExecAsync.js +0 -0
@@ -1,9 +1,187 @@
1
1
  import ts from 'typescript';
2
+ import * as crypto from 'crypto';
2
3
  import { StructuredPath } from "./paths.js";
3
4
  import { nodeToSource } from "./nodeToSource.js";
4
5
  import { methodRegistry, ArrayPushSemantics } from "./methodSemantics.js";
5
6
  import { isArithmeticOperator, isAssignmentOperator, isBitwiseCompoundOperator, isComparisonOperator, isDefinedType, isNumericCompoundOperator, leftOrRightType, unwrapExpression, } from "./sharedPatterns.js";
6
7
  import { processBindingPattern } from "./processBindings.js";
8
+ import { extractConditionalEffectsFromTernary, findUseStateSetters, } from "./conditionalEffectsExtractor.js";
9
+ /**
10
+ * Extracts the component name from a JSX element.
11
+ * Returns null for intrinsic elements (div, span, etc.) since we only care about
12
+ * custom components for gating condition tracking.
13
+ *
14
+ * Examples:
15
+ * - <ChildViewer /> → "ChildViewer"
16
+ * - <ScenarioViewer scenario={...} /> → "ScenarioViewer"
17
+ * - <div> → null (intrinsic element)
18
+ */
19
+ function getComponentNameFromJsx(node) {
20
+ let tagName;
21
+ if (ts.isJsxElement(node)) {
22
+ tagName = node.openingElement.tagName;
23
+ }
24
+ else {
25
+ tagName = node.tagName;
26
+ }
27
+ // Get the text of the tag name
28
+ const name = tagName.getText();
29
+ // Check if it's a custom component (starts with uppercase) vs intrinsic element
30
+ // Custom components start with uppercase: <MyComponent />
31
+ // Intrinsic elements start with lowercase: <div />
32
+ if (name &&
33
+ name[0] === name[0].toUpperCase() &&
34
+ name[0] !== name[0].toLowerCase()) {
35
+ return name;
36
+ }
37
+ return null;
38
+ }
39
+ /**
40
+ * Extracts condition paths from a logical AND chain expression.
41
+ * Used for creating gating conditions for child components.
42
+ *
43
+ * Example: `hasData && isReady && <Component />` returns ['hasData', 'isReady']
44
+ */
45
+ function extractConditionPathsFromAndChain(expr, sourceFile) {
46
+ const paths = [];
47
+ const unwrapped = unwrapExpression(expr);
48
+ if (ts.isBinaryExpression(unwrapped) &&
49
+ unwrapped.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
50
+ // Recursively get conditions from left side
51
+ paths.push(...extractConditionPathsFromAndChain(unwrapped.left, sourceFile));
52
+ // Process right side if it's not JSX (JSX is the consequence, not a condition)
53
+ const rightUnwrapped = unwrapExpression(unwrapped.right);
54
+ if (!ts.isJsxElement(rightUnwrapped) &&
55
+ !ts.isJsxSelfClosingElement(rightUnwrapped) &&
56
+ !ts.isJsxFragment(rightUnwrapped)) {
57
+ paths.push(...extractConditionPathsFromAndChain(unwrapped.right, sourceFile));
58
+ }
59
+ }
60
+ else {
61
+ // Base case: extract path from this expression
62
+ const path = StructuredPath.fromNode(unwrapped, sourceFile);
63
+ if (path) {
64
+ paths.push(path.toString());
65
+ }
66
+ }
67
+ return paths;
68
+ }
69
+ /**
70
+ * Finds the rightmost JSX element in an && chain.
71
+ * Example: `a && b && <Component />` returns <Component />
72
+ */
73
+ function findJsxInAndChain(expr) {
74
+ const unwrapped = unwrapExpression(expr);
75
+ if (ts.isJsxElement(unwrapped) || ts.isJsxSelfClosingElement(unwrapped)) {
76
+ return unwrapped;
77
+ }
78
+ if (ts.isBinaryExpression(unwrapped) &&
79
+ unwrapped.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
80
+ // Check right side first (most common case: condition && <Jsx />)
81
+ const rightResult = findJsxInAndChain(unwrapped.right);
82
+ if (rightResult)
83
+ return rightResult;
84
+ // Also check left side for rare cases
85
+ return findJsxInAndChain(unwrapped.left);
86
+ }
87
+ return null;
88
+ }
89
+ /**
90
+ * Fix 32: Finds a JSX fragment in an && chain.
91
+ * Example: `activeTab && <><ChildA /><ChildB /></>` returns the fragment
92
+ * This is needed to propagate parent conditions through fragments.
93
+ */
94
+ function findJsxFragmentInAndChain(expr) {
95
+ const unwrapped = unwrapExpression(expr);
96
+ if (ts.isJsxFragment(unwrapped)) {
97
+ return unwrapped;
98
+ }
99
+ if (ts.isBinaryExpression(unwrapped) &&
100
+ unwrapped.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
101
+ // Check right side first (most common case: condition && <></>)
102
+ const rightResult = findJsxFragmentInAndChain(unwrapped.right);
103
+ if (rightResult)
104
+ return rightResult;
105
+ // Also check left side for rare cases
106
+ return findJsxFragmentInAndChain(unwrapped.left);
107
+ }
108
+ return null;
109
+ }
110
+ /**
111
+ * Detects if a property access looks like an environment variable store access.
112
+ * Matches patterns like `env.DATABASE_URL`, `env.IS_FORMBRICKS_CLOUD`, etc.
113
+ * where the object is named "env" and the property looks like an env var name.
114
+ */
115
+ function isEnvStoreAccess(fullText) {
116
+ // Match: env.SOME_VAR or env.someVar (but object must be exactly "env")
117
+ // This catches patterns from @t3-oss/env-nextjs and similar packages
118
+ const envStorePattern = /^env\.[A-Z_][A-Z0-9_]*$/;
119
+ return envStorePattern.test(fullText);
120
+ }
121
+ /**
122
+ * Converts a call expression argument to a StructuredPath.
123
+ *
124
+ * IMPORTANT: We always use the original source text for callbacks, never cyScope names.
125
+ * cyScope names are internal identifiers for child scopes and should NEVER appear
126
+ * in schema paths or call signatures. Using cyScope names causes data merge conflicts
127
+ * because the same callback gets different identifiers in different contexts.
128
+ */
129
+ function getArgPathForCallSignature(arg, context) {
130
+ // Always use the standard path conversion - never replace with cyScope names
131
+ return (StructuredPath.fromNode(arg, context.sourceFile) ||
132
+ nodeToSource(arg, context.sourceFile));
133
+ }
134
+ /**
135
+ * Builds a StructuredPath for a call expression using the original source text.
136
+ *
137
+ * IMPORTANT: This function ensures consistent call signatures by always using
138
+ * the original callback text, never cyScope names. This prevents schema path
139
+ * conflicts where the same call would have different paths.
140
+ */
141
+ function buildCallPathFromSource(node, context) {
142
+ const expression = node.expression;
143
+ // Convert arguments using original source text
144
+ const argPaths = node.arguments.map((arg) => getArgPathForCallSignature(arg, context));
145
+ // Handle type arguments if present
146
+ let typeArgs = undefined;
147
+ if (node.typeArguments && node.typeArguments.length > 0) {
148
+ typeArgs = node.typeArguments.map((typeArg) => typeArg.getText(context.sourceFile));
149
+ }
150
+ if (ts.isIdentifier(expression)) {
151
+ // Simple function call: func(arg1, arg2)
152
+ return StructuredPath.fromFunction(expression.text, argPaths, typeArgs);
153
+ }
154
+ else if (ts.isPropertyAccessExpression(expression)) {
155
+ // Method call: obj.method(arg1, arg2)
156
+ const objPath = StructuredPath.fromNode(expression.expression, context.sourceFile);
157
+ if (!objPath)
158
+ return null;
159
+ return objPath
160
+ .withProperty(expression.name.text)
161
+ .withFunctionCall(argPaths, typeArgs);
162
+ }
163
+ else if (ts.isCallExpression(expression)) {
164
+ // Chained call: func(arg1)(arg2)
165
+ const funcPath = buildCallPathFromSource(expression, context);
166
+ if (!funcPath)
167
+ return null;
168
+ return funcPath.withFunctionCall(argPaths, typeArgs);
169
+ }
170
+ else if (ts.isElementAccessExpression(expression)) {
171
+ // Element access call: obj[key](args)
172
+ const basePath = StructuredPath.fromNode(expression, context.sourceFile);
173
+ if (!basePath)
174
+ return null;
175
+ return basePath.withFunctionCall(argPaths, typeArgs);
176
+ }
177
+ else {
178
+ // Complex call expression
179
+ const basePath = StructuredPath.fromNode(expression, context.sourceFile);
180
+ if (!basePath)
181
+ return null;
182
+ return basePath.withFunctionCall(argPaths, typeArgs);
183
+ }
184
+ }
7
185
  /**
8
186
  * Checks if an expression is likely an array type.
9
187
  * Uses TypeScript's type checker when available, falls back to heuristics.
@@ -81,102 +259,508 @@ export function markConditionVariablesAsNullable(condition, context) {
81
259
  }
82
260
  }
83
261
  /**
84
- * Extracts conditional usages from a condition expression for key attribute detection.
85
- * This function identifies which attributes are used in conditionals and how they're used.
86
- *
87
- * @param condition The condition expression to analyze
88
- * @param context The analysis context
89
- * @param location Where this condition appears (if, ternary, logical-and, switch)
262
+ * Helper to extract source location from an AST node
90
263
  */
91
- export function extractConditionalUsage(condition, context, location) {
92
- const unwrapped = unwrapExpression(condition);
93
- // Handle binary expressions with && (logical AND chains)
94
- // Example: `a && b && <Component />` - both a and b are conditional checks
264
+ function getSourceLocation(node, sourceFile) {
265
+ const start = node.getStart(sourceFile);
266
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(start);
267
+ const codeSnippet = node.getText(sourceFile);
268
+ return {
269
+ lineNumber: line + 1, // Convert to 1-based
270
+ column: character,
271
+ codeSnippet: codeSnippet.length > 100
272
+ ? codeSnippet.slice(0, 100) + '...'
273
+ : codeSnippet,
274
+ };
275
+ }
276
+ /**
277
+ * Counts the number of conditions in an && chain (excluding JSX consequence)
278
+ */
279
+ function countConditionsInAndChain(expr) {
280
+ const unwrapped = unwrapExpression(expr);
95
281
  if (ts.isBinaryExpression(unwrapped) &&
96
282
  unwrapped.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
97
- // Recursively process left side
98
- extractConditionalUsage(unwrapped.left, context, location);
99
- // Process right side if it's not JSX (JSX is the consequence, not the condition)
283
+ const leftCount = countConditionsInAndChain(unwrapped.left);
100
284
  const rightUnwrapped = unwrapExpression(unwrapped.right);
101
285
  const isJsxConsequence = ts.isJsxElement(rightUnwrapped) ||
102
286
  ts.isJsxSelfClosingElement(rightUnwrapped) ||
103
287
  ts.isJsxFragment(rightUnwrapped);
104
- if (!isJsxConsequence) {
105
- extractConditionalUsage(unwrapped.right, context, location);
288
+ if (isJsxConsequence) {
289
+ return leftCount;
106
290
  }
107
- return;
291
+ return leftCount + countConditionsInAndChain(unwrapped.right);
108
292
  }
109
- // Handle binary expressions with || (logical OR)
110
- if (ts.isBinaryExpression(unwrapped) &&
111
- unwrapped.operatorToken.kind === ts.SyntaxKind.BarBarToken) {
112
- // Both sides of || are conditional checks
113
- extractConditionalUsage(unwrapped.left, context, location);
114
- extractConditionalUsage(unwrapped.right, context, location);
293
+ // Single condition (not an && chain)
294
+ return 1;
295
+ }
296
+ /**
297
+ * Extracts conditionals from JSX elements by recursively traversing children.
298
+ *
299
+ * This is CRITICAL for extracting compound conditionals from JSX expressions
300
+ * like `{hasNewerVersion && !isActive && <Banner />}`.
301
+ *
302
+ * This function is called BEFORE the child boundary check in processExpression
303
+ * because JSX elements are NOT scopes - their expressions use variables from
304
+ * the parent scope and should have their conditionals extracted regardless of
305
+ * whether the JSX is within a child boundary.
306
+ *
307
+ * Fix 32: Added parentConditions parameter to track gating conditions from
308
+ * parent && chains. When we find a component nested inside multiple conditionals
309
+ * like `{activeTab && <>{ternary ? ... : <Component />}</>}`, ALL parent
310
+ * conditions should be added as gating conditions for the component.
311
+ *
312
+ * @param node The JSX element, self-closing element, or fragment to traverse
313
+ * @param context The analysis context
314
+ * @param parentConditions Accumulated gating conditions from parent && chains
315
+ */
316
+ function extractConditionalsFromJsx(node, context, parentConditions = []) {
317
+ // Get children to process
318
+ let children;
319
+ if (ts.isJsxElement(node)) {
320
+ children = node.children;
321
+ }
322
+ else if (ts.isJsxFragment(node)) {
323
+ children = node.children;
324
+ }
325
+ // JsxSelfClosingElement has no children
326
+ if (!children) {
115
327
  return;
116
328
  }
117
- // Handle comparison operators (===, !==, <, >, <=, >=)
118
- // Example: `if (status === 'active')` - status is compared against 'active'
119
- if (ts.isBinaryExpression(unwrapped) &&
120
- isComparisonOperator(unwrapped.operatorToken.kind)) {
121
- // Try to extract the variable and the compared value
122
- const leftPath = StructuredPath.fromNode(unwrapped.left, context.sourceFile);
123
- const rightPath = StructuredPath.fromNode(unwrapped.right, context.sourceFile);
124
- // Check if left is a variable and right is a literal
125
- if (leftPath && isLiteralExpression(unwrapped.right)) {
126
- const literalValue = getLiteralValue(unwrapped.right, context);
127
- context.addConditionalUsage({
128
- path: leftPath.toLeftHandSideString(),
129
- conditionType: 'comparison',
130
- comparedValues: literalValue !== undefined ? [literalValue] : undefined,
131
- location,
132
- });
329
+ for (const child of children) {
330
+ // Process JSX expressions: {expr}
331
+ if (ts.isJsxExpression(child) && child.expression) {
332
+ const expr = unwrapExpression(child.expression);
333
+ // If the expression is an && chain, extract its conditional usages
334
+ if (ts.isBinaryExpression(expr) &&
335
+ expr.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
336
+ // Mark nullable variables
337
+ markConditionVariablesAsNullable(expr, context);
338
+ // Extract conditional usage (this handles compound conditionals)
339
+ // Pass controlsJsxRendering: true since this conditional controls JSX rendering
340
+ extractConditionalUsage(expr, context, 'logical-and', {
341
+ controlsJsxRendering: true,
342
+ });
343
+ // Extract all condition paths from the && chain for gating tracking
344
+ const conditionPaths = extractConditionPathsFromAndChain(expr, context.sourceFile);
345
+ const sourceLocation = getSourceLocation(expr, context.sourceFile);
346
+ // Fix 32: Build accumulated conditions including parent conditions
347
+ const accumulatedConditions = [
348
+ ...parentConditions,
349
+ ...conditionPaths.map((path) => ({
350
+ path,
351
+ sourceLocation,
352
+ isNegated: false,
353
+ })),
354
+ ];
355
+ // Track gating conditions for child components
356
+ // Example: {hasAnalysis && <ScenarioViewer />}
357
+ const jsxElement = findJsxInAndChain(expr);
358
+ if (jsxElement) {
359
+ const componentName = getComponentNameFromJsx(jsxElement);
360
+ if (componentName) {
361
+ // Fix 32: Add ALL accumulated conditions (parent + current) as gating conditions
362
+ for (const condition of accumulatedConditions) {
363
+ context.addChildBoundaryGatingCondition(componentName, {
364
+ path: condition.path,
365
+ conditionType: 'truthiness',
366
+ location: 'logical-and',
367
+ sourceLocation: condition.sourceLocation,
368
+ controlsJsxRendering: true,
369
+ isNegated: condition.isNegated,
370
+ });
371
+ }
372
+ }
373
+ // Fix 32: Recursively process nested JSX with accumulated conditions
374
+ if (ts.isJsxElement(jsxElement) ||
375
+ ts.isJsxSelfClosingElement(jsxElement)) {
376
+ extractConditionalsFromJsx(jsxElement, context, accumulatedConditions);
377
+ }
378
+ }
379
+ // Fix 32: Also check for nested JSX fragments
380
+ const jsxFragment = findJsxFragmentInAndChain(expr);
381
+ if (jsxFragment) {
382
+ extractConditionalsFromJsx(jsxFragment, context, accumulatedConditions);
383
+ }
384
+ }
385
+ // If the expression is a ternary, extract its conditional
386
+ else if (ts.isConditionalExpression(expr)) {
387
+ // Pass controlsJsxRendering: true since this conditional controls JSX rendering
388
+ extractConditionalUsage(expr.condition, context, 'ternary', {
389
+ controlsJsxRendering: true,
390
+ });
391
+ // Track gating conditions for components in both branches of the ternary
392
+ // Example: {isError ? <ErrorView /> : <SuccessView />}
393
+ const conditionPath = StructuredPath.fromNode(unwrapExpression(expr.condition), context.sourceFile);
394
+ const sourceLocation = getSourceLocation(expr, context.sourceFile);
395
+ // Recursively process the whenTrue and whenFalse branches for JSX
396
+ const whenTrue = unwrapExpression(expr.whenTrue);
397
+ const whenFalse = unwrapExpression(expr.whenFalse);
398
+ // Fix 32: Build conditions for whenTrue branch (parent conditions + ternary condition truthy)
399
+ const whenTrueConditions = [
400
+ ...parentConditions,
401
+ ...(conditionPath
402
+ ? [
403
+ {
404
+ path: conditionPath.toString(),
405
+ sourceLocation,
406
+ isNegated: false,
407
+ },
408
+ ]
409
+ : []),
410
+ ];
411
+ // Fix 32: Build conditions for whenFalse branch (parent conditions + ternary condition falsy)
412
+ const whenFalseConditions = [
413
+ ...parentConditions,
414
+ ...(conditionPath
415
+ ? [
416
+ {
417
+ path: conditionPath.toString(),
418
+ sourceLocation,
419
+ isNegated: true,
420
+ },
421
+ ]
422
+ : []),
423
+ ];
424
+ // Handle whenTrue branch (condition is truthy)
425
+ if (ts.isJsxElement(whenTrue) || ts.isJsxSelfClosingElement(whenTrue)) {
426
+ const componentName = getComponentNameFromJsx(whenTrue);
427
+ if (componentName) {
428
+ // Fix 32: Add ALL conditions (parent + ternary) as gating conditions
429
+ for (const condition of whenTrueConditions) {
430
+ context.addChildBoundaryGatingCondition(componentName, {
431
+ path: condition.path,
432
+ conditionType: 'truthiness',
433
+ location: 'ternary',
434
+ sourceLocation: condition.sourceLocation,
435
+ controlsJsxRendering: true,
436
+ isNegated: condition.isNegated,
437
+ });
438
+ }
439
+ }
440
+ }
441
+ if (ts.isJsxElement(whenTrue) ||
442
+ ts.isJsxSelfClosingElement(whenTrue) ||
443
+ ts.isJsxFragment(whenTrue)) {
444
+ extractConditionalsFromJsx(whenTrue, context, whenTrueConditions);
445
+ }
446
+ // Handle whenFalse branch (condition is falsy/negated)
447
+ if (ts.isJsxElement(whenFalse) ||
448
+ ts.isJsxSelfClosingElement(whenFalse)) {
449
+ const componentName = getComponentNameFromJsx(whenFalse);
450
+ if (componentName) {
451
+ // Fix 32: Add ALL conditions (parent + ternary) as gating conditions
452
+ for (const condition of whenFalseConditions) {
453
+ context.addChildBoundaryGatingCondition(componentName, {
454
+ path: condition.path,
455
+ conditionType: 'truthiness',
456
+ location: 'ternary',
457
+ sourceLocation: condition.sourceLocation,
458
+ controlsJsxRendering: true,
459
+ isNegated: condition.isNegated,
460
+ });
461
+ }
462
+ }
463
+ }
464
+ if (ts.isJsxElement(whenFalse) ||
465
+ ts.isJsxSelfClosingElement(whenFalse) ||
466
+ ts.isJsxFragment(whenFalse)) {
467
+ extractConditionalsFromJsx(whenFalse, context, whenFalseConditions);
468
+ }
469
+ // Handle chained ternaries: a ? <A/> : b ? <B/> : <C/>
470
+ // When whenFalse is another ConditionalExpression, recursively process it
471
+ else if (ts.isConditionalExpression(whenFalse)) {
472
+ // Extract conditional usage for the nested ternary's condition
473
+ extractConditionalUsage(whenFalse.condition, context, 'ternary', {
474
+ controlsJsxRendering: true,
475
+ });
476
+ // Get the nested condition path
477
+ const nestedConditionPath = StructuredPath.fromNode(unwrapExpression(whenFalse.condition), context.sourceFile);
478
+ const nestedSourceLocation = getSourceLocation(whenFalse, context.sourceFile);
479
+ const nestedWhenTrue = unwrapExpression(whenFalse.whenTrue);
480
+ const nestedWhenFalse = unwrapExpression(whenFalse.whenFalse);
481
+ // Fix 32: Build conditions for nested whenTrue (parent falsy + nested truthy)
482
+ const nestedWhenTrueConditions = [
483
+ ...whenFalseConditions, // Parent ternary was falsy to get here
484
+ ...(nestedConditionPath
485
+ ? [
486
+ {
487
+ path: nestedConditionPath.toString(),
488
+ sourceLocation: nestedSourceLocation,
489
+ isNegated: false,
490
+ },
491
+ ]
492
+ : []),
493
+ ];
494
+ // Fix 32: Build conditions for nested whenFalse (parent falsy + nested falsy)
495
+ const nestedWhenFalseConditions = [
496
+ ...whenFalseConditions, // Parent ternary was falsy to get here
497
+ ...(nestedConditionPath
498
+ ? [
499
+ {
500
+ path: nestedConditionPath.toString(),
501
+ sourceLocation: nestedSourceLocation,
502
+ isNegated: true,
503
+ },
504
+ ]
505
+ : []),
506
+ ];
507
+ // Handle nested whenTrue branch
508
+ if (ts.isJsxElement(nestedWhenTrue) ||
509
+ ts.isJsxSelfClosingElement(nestedWhenTrue)) {
510
+ const componentName = getComponentNameFromJsx(nestedWhenTrue);
511
+ if (componentName) {
512
+ // Fix 32: Add ALL accumulated conditions
513
+ for (const condition of nestedWhenTrueConditions) {
514
+ context.addChildBoundaryGatingCondition(componentName, {
515
+ path: condition.path,
516
+ conditionType: 'truthiness',
517
+ location: 'ternary',
518
+ sourceLocation: condition.sourceLocation,
519
+ controlsJsxRendering: true,
520
+ isNegated: condition.isNegated,
521
+ });
522
+ }
523
+ }
524
+ }
525
+ if (ts.isJsxElement(nestedWhenTrue) ||
526
+ ts.isJsxSelfClosingElement(nestedWhenTrue) ||
527
+ ts.isJsxFragment(nestedWhenTrue)) {
528
+ extractConditionalsFromJsx(nestedWhenTrue, context, nestedWhenTrueConditions);
529
+ }
530
+ // Handle nested whenFalse branch (this could be another chained ternary or JSX)
531
+ if (ts.isJsxElement(nestedWhenFalse) ||
532
+ ts.isJsxSelfClosingElement(nestedWhenFalse)) {
533
+ const componentName = getComponentNameFromJsx(nestedWhenFalse);
534
+ if (componentName) {
535
+ // Fix 32: Add ALL accumulated conditions
536
+ for (const condition of nestedWhenFalseConditions) {
537
+ context.addChildBoundaryGatingCondition(componentName, {
538
+ path: condition.path,
539
+ conditionType: 'truthiness',
540
+ location: 'ternary',
541
+ sourceLocation: condition.sourceLocation,
542
+ controlsJsxRendering: true,
543
+ isNegated: condition.isNegated,
544
+ });
545
+ }
546
+ }
547
+ }
548
+ if (ts.isJsxElement(nestedWhenFalse) ||
549
+ ts.isJsxSelfClosingElement(nestedWhenFalse) ||
550
+ ts.isJsxFragment(nestedWhenFalse)) {
551
+ extractConditionalsFromJsx(nestedWhenFalse, context, nestedWhenFalseConditions);
552
+ }
553
+ // If nestedWhenFalse is yet another ConditionalExpression, the recursion
554
+ // will handle it on the next iteration when this function processes it
555
+ else if (ts.isConditionalExpression(nestedWhenFalse)) {
556
+ // Recursively handle deeper nesting by wrapping in a synthetic process
557
+ // We create a fake JsxExpression context to reuse the same logic
558
+ const syntheticChild = {
559
+ kind: ts.SyntaxKind.JsxExpression,
560
+ expression: nestedWhenFalse,
561
+ };
562
+ // Process via the main JSX expression handler by recursing
563
+ // For now, just extract conditionals directly
564
+ extractConditionalUsage(nestedWhenFalse.condition, context, 'ternary', { controlsJsxRendering: true });
565
+ }
566
+ }
567
+ }
568
+ }
569
+ // Recursively process nested JSX elements - Fix 32: pass parent conditions
570
+ else if (ts.isJsxElement(child)) {
571
+ extractConditionalsFromJsx(child, context, parentConditions);
572
+ }
573
+ // Recursively process nested JSX fragments - Fix 32: pass parent conditions
574
+ else if (ts.isJsxFragment(child)) {
575
+ extractConditionalsFromJsx(child, context, parentConditions);
576
+ }
577
+ }
578
+ }
579
+ /**
580
+ * Extracts conditional usages from a condition expression for key attribute detection.
581
+ * This function identifies which attributes are used in conditionals and how they're used.
582
+ * It also tracks compound conditionals (&&-chains) where all conditions must be true together.
583
+ *
584
+ * @param condition The condition expression to analyze
585
+ * @param context The analysis context
586
+ * @param location Where this condition appears (if, ternary, logical-and, switch)
587
+ * @param options Additional options including controlsJsxRendering flag
588
+ */
589
+ export function extractConditionalUsage(condition, context, location, options = {}) {
590
+ const { controlsJsxRendering } = options;
591
+ // Internal recursive function with chain tracking
592
+ function extractWithChainTracking(expr, chainInfo, isNegated) {
593
+ const unwrapped = unwrapExpression(expr);
594
+ // Handle binary expressions with && (logical AND chains)
595
+ // Example: `a && b && <Component />` - both a and b are conditional checks
596
+ if (ts.isBinaryExpression(unwrapped) &&
597
+ unwrapped.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
598
+ // Track if we're creating the chain at this level (root of the chain)
599
+ const isChainRoot = !chainInfo;
600
+ // If no chainInfo, this is the root of a new chain
601
+ if (isChainRoot) {
602
+ const chainLength = countConditionsInAndChain(unwrapped);
603
+ // Only create chain tracking for chains with 2+ conditions
604
+ if (chainLength >= 2) {
605
+ const chainId = `chain_${crypto.randomUUID().slice(0, 8)}`;
606
+ const chainExpression = unwrapped.getText(context.sourceFile);
607
+ const compound = {
608
+ chainId,
609
+ expression: chainExpression.length > 200
610
+ ? chainExpression.slice(0, 200) + '...'
611
+ : chainExpression,
612
+ conditions: [],
613
+ location,
614
+ sourceLocation: getSourceLocation(unwrapped, context.sourceFile),
615
+ controlsJsxRendering,
616
+ };
617
+ chainInfo = {
618
+ chainId,
619
+ chainLength,
620
+ chainExpression: compound.expression,
621
+ currentPosition: 0,
622
+ compound,
623
+ };
624
+ }
625
+ }
626
+ // Recursively process left side
627
+ extractWithChainTracking(unwrapped.left, chainInfo, false);
628
+ // Process right side if it's not JSX (JSX is the consequence, not the condition)
629
+ const rightUnwrapped = unwrapExpression(unwrapped.right);
630
+ const isJsxConsequence = ts.isJsxElement(rightUnwrapped) ||
631
+ ts.isJsxSelfClosingElement(rightUnwrapped) ||
632
+ ts.isJsxFragment(rightUnwrapped);
633
+ if (!isJsxConsequence) {
634
+ extractWithChainTracking(unwrapped.right, chainInfo, false);
635
+ }
636
+ // If this is the root of the chain, register the compound conditional
637
+ if (isChainRoot && chainInfo) {
638
+ context.addCompoundConditional(chainInfo.compound);
639
+ }
133
640
  return;
134
641
  }
135
- // Check if right is a variable and left is a literal
136
- if (rightPath && isLiteralExpression(unwrapped.left)) {
137
- const literalValue = getLiteralValue(unwrapped.left, context);
138
- context.addConditionalUsage({
139
- path: rightPath.toLeftHandSideString(),
140
- conditionType: 'comparison',
141
- comparedValues: literalValue !== undefined ? [literalValue] : undefined,
142
- location,
143
- });
642
+ // Handle binary expressions with || (logical OR)
643
+ // OR breaks the chain - each side is independent
644
+ if (ts.isBinaryExpression(unwrapped) &&
645
+ unwrapped.operatorToken.kind === ts.SyntaxKind.BarBarToken) {
646
+ // Both sides of || are independent conditional checks (no chain tracking)
647
+ extractWithChainTracking(unwrapped.left, null, false);
648
+ extractWithChainTracking(unwrapped.right, null, false);
144
649
  return;
145
650
  }
146
- // Both sides are variables - record both as comparisons without specific values
147
- if (leftPath) {
148
- context.addConditionalUsage({
149
- path: leftPath.toLeftHandSideString(),
150
- conditionType: 'comparison',
151
- location,
152
- });
651
+ // Handle comparison operators (===, !==, <, >, <=, >=)
652
+ // Example: `if (status === 'active')` - status is compared against 'active'
653
+ if (ts.isBinaryExpression(unwrapped) &&
654
+ isComparisonOperator(unwrapped.operatorToken.kind)) {
655
+ // Try to extract the variable and the compared value
656
+ const leftPath = StructuredPath.fromNode(unwrapped.left, context.sourceFile);
657
+ const rightPath = StructuredPath.fromNode(unwrapped.right, context.sourceFile);
658
+ // Determine the compared value for computing requiredValue
659
+ const getRequiredValue = (literalValue, isNegatedComparison) => {
660
+ if (literalValue === undefined)
661
+ return undefined;
662
+ // For !== comparisons, the condition is true when NOT equal to the value
663
+ // For === comparisons, the condition is true when equal to the value
664
+ const isNotEqual = unwrapped.operatorToken.kind ===
665
+ ts.SyntaxKind.ExclamationEqualsEqualsToken ||
666
+ unwrapped.operatorToken.kind === ts.SyntaxKind.ExclamationEqualsToken;
667
+ if (isNotEqual) {
668
+ // !== 'value' means requiredValue is NOT 'value', but we express this as "not 'value'"
669
+ return `not ${literalValue}`;
670
+ }
671
+ return literalValue;
672
+ };
673
+ // Helper to add a condition
674
+ const addCondition = (path, conditionType, comparedValues, requiredValue) => {
675
+ const usage = {
676
+ path,
677
+ conditionType,
678
+ comparedValues,
679
+ location,
680
+ sourceLocation: getSourceLocation(unwrapped, context.sourceFile),
681
+ isNegated,
682
+ controlsJsxRendering,
683
+ };
684
+ // Add chain info if part of a compound conditional
685
+ if (chainInfo) {
686
+ usage.chainId = chainInfo.chainId;
687
+ usage.chainPosition = chainInfo.currentPosition;
688
+ usage.chainLength = chainInfo.chainLength;
689
+ usage.chainExpression = chainInfo.chainExpression;
690
+ chainInfo.currentPosition++;
691
+ // Add to compound conditional conditions
692
+ chainInfo.compound.conditions.push({
693
+ path,
694
+ conditionType,
695
+ comparedValues,
696
+ isNegated,
697
+ requiredValue,
698
+ });
699
+ }
700
+ context.addConditionalUsage(usage);
701
+ };
702
+ // Check if left is a variable and right is a literal
703
+ if (leftPath && isLiteralExpression(unwrapped.right)) {
704
+ const literalValue = getLiteralValue(unwrapped.right, context);
705
+ addCondition(leftPath.toLeftHandSideString(), 'comparison', literalValue !== undefined ? [literalValue] : undefined, getRequiredValue(literalValue, isNegated));
706
+ return;
707
+ }
708
+ // Check if right is a variable and left is a literal
709
+ if (rightPath && isLiteralExpression(unwrapped.left)) {
710
+ const literalValue = getLiteralValue(unwrapped.left, context);
711
+ addCondition(rightPath.toLeftHandSideString(), 'comparison', literalValue !== undefined ? [literalValue] : undefined, getRequiredValue(literalValue, isNegated));
712
+ return;
713
+ }
714
+ // Both sides are variables - record both as comparisons without specific values
715
+ if (leftPath) {
716
+ addCondition(leftPath.toLeftHandSideString(), 'comparison');
717
+ }
718
+ if (rightPath) {
719
+ addCondition(rightPath.toLeftHandSideString(), 'comparison');
720
+ }
721
+ return;
722
+ }
723
+ // Handle prefix unary NOT expression: !variable
724
+ // Example: `if (!isVisible)` - isVisible is a truthiness check (negated)
725
+ if (ts.isPrefixUnaryExpression(unwrapped) &&
726
+ unwrapped.operator === ts.SyntaxKind.ExclamationToken) {
727
+ extractWithChainTracking(unwrapped.operand, chainInfo, !isNegated);
728
+ return;
153
729
  }
154
- if (rightPath) {
155
- context.addConditionalUsage({
156
- path: rightPath.toLeftHandSideString(),
157
- conditionType: 'comparison',
730
+ // Handle simple identifiers or property accesses (truthiness checks)
731
+ // Example: `if (x)` or `x && <JSX />` - x is checked for truthiness
732
+ const path = StructuredPath.fromNode(unwrapped, context.sourceFile);
733
+ if (path && !path.isLiteral()) {
734
+ const pathStr = path.toLeftHandSideString();
735
+ const usage = {
736
+ path: pathStr,
737
+ conditionType: 'truthiness',
158
738
  location,
159
- });
739
+ sourceLocation: getSourceLocation(unwrapped, context.sourceFile),
740
+ isNegated,
741
+ controlsJsxRendering,
742
+ };
743
+ // Add chain info if part of a compound conditional
744
+ if (chainInfo) {
745
+ usage.chainId = chainInfo.chainId;
746
+ usage.chainPosition = chainInfo.currentPosition;
747
+ usage.chainLength = chainInfo.chainLength;
748
+ usage.chainExpression = chainInfo.chainExpression;
749
+ chainInfo.currentPosition++;
750
+ // Add to compound conditional conditions
751
+ // For truthiness, requiredValue is true if not negated, false if negated
752
+ chainInfo.compound.conditions.push({
753
+ path: pathStr,
754
+ conditionType: 'truthiness',
755
+ isNegated,
756
+ requiredValue: !isNegated,
757
+ });
758
+ }
759
+ context.addConditionalUsage(usage);
160
760
  }
161
- return;
162
- }
163
- // Handle prefix unary NOT expression: !variable
164
- // Example: `if (!isVisible)` - isVisible is a truthiness check
165
- if (ts.isPrefixUnaryExpression(unwrapped) &&
166
- unwrapped.operator === ts.SyntaxKind.ExclamationToken) {
167
- extractConditionalUsage(unwrapped.operand, context, location);
168
- return;
169
- }
170
- // Handle simple identifiers or property accesses (truthiness checks)
171
- // Example: `if (x)` or `x && <JSX />` - x is checked for truthiness
172
- const path = StructuredPath.fromNode(unwrapped, context.sourceFile);
173
- if (path && !path.isLiteral()) {
174
- context.addConditionalUsage({
175
- path: path.toLeftHandSideString(),
176
- conditionType: 'truthiness',
177
- location,
178
- });
179
761
  }
762
+ // Start extraction with no chain info
763
+ extractWithChainTracking(condition, null, false);
180
764
  }
181
765
  /**
182
766
  * Helper to check if an expression is a literal value
@@ -254,7 +838,24 @@ export function processExpression({ node, context, targetPath, typeHint, }) {
254
838
  unwrappedNode.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
255
839
  markConditionVariablesAsNullable(unwrappedNode, context);
256
840
  // Extract conditional usages for key attribute detection
257
- extractConditionalUsage(unwrappedNode, context, 'logical-and');
841
+ // Only call from the OUTERMOST && expression to avoid duplicates
842
+ // Check if parent is also a && (meaning we're nested)
843
+ const parent = unwrappedNode.parent;
844
+ const parentIsAndChain = parent &&
845
+ ts.isBinaryExpression(parent) &&
846
+ parent.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken;
847
+ if (!parentIsAndChain) {
848
+ extractConditionalUsage(unwrappedNode, context, 'logical-and');
849
+ }
850
+ }
851
+ // CRITICAL: Extract conditionals from JSX BEFORE checking child boundaries
852
+ // JSX elements are NOT scopes - their expressions use variables from the parent scope.
853
+ // Even if the JSX element is within a child boundary (e.g., because it contains callbacks),
854
+ // we must still extract conditionals from JSX expression children like {x && <div>...</div>}
855
+ if (ts.isJsxElement(unwrappedNode) ||
856
+ ts.isJsxSelfClosingElement(unwrappedNode) ||
857
+ ts.isJsxFragment(unwrappedNode)) {
858
+ extractConditionalsFromJsx(unwrappedNode, context);
258
859
  }
259
860
  // If the node falls within an excluded child scope, stop processing it.
260
861
  if (context.isChildBoundary(node)) {
@@ -386,7 +987,8 @@ export function processExpression({ node, context, targetPath, typeHint, }) {
386
987
  const propertyPath = objectPath.withProperty(unwrappedNode.name.text);
387
988
  // Check if this is an environment variable access
388
989
  const fullText = unwrappedNode.getText(context.sourceFile);
389
- if (fullText.includes('.env.') // simple heuristic for env var access but not great
990
+ if (fullText.includes('.env.') || // process.env.X, window.env.X
991
+ isEnvStoreAccess(fullText) // env.X where env is likely an env config object
390
992
  ) {
391
993
  context.addEnvironmentVariable(fullText);
392
994
  }
@@ -610,6 +1212,13 @@ export function processExpression({ node, context, targetPath, typeHint, }) {
610
1212
  // e.g., `const tab = segments[0] || 'default'` should trace tab back to segments[0]
611
1213
  if (operatorKind === ts.SyntaxKind.QuestionQuestionToken) {
612
1214
  // specifically for ?? we create an equivalence to the left side
1215
+ // IMPORTANT: Also process the left side recursively to apply method semantics
1216
+ // (e.g., for `const segments = splat?.split('/') ?? []`, we need split semantics)
1217
+ processExpression({
1218
+ node: unwrappedNode.left,
1219
+ context,
1220
+ // Don't pass targetPath here - we'll establish equivalence separately below
1221
+ });
613
1222
  if (targetPath) {
614
1223
  resultPath = StructuredPath.fromNode(unwrappedNode.left, context.sourceFile);
615
1224
  }
@@ -666,9 +1275,10 @@ export function processExpression({ node, context, targetPath, typeHint, }) {
666
1275
  context.markUnsupported(unwrappedNode.expression, `processExpression: Couldn't get path for called expression: ${ts.SyntaxKind[unwrappedNode.expression.kind]}`, false);
667
1276
  return false;
668
1277
  }
669
- // Construct empty arguments list just to get the call path
670
- // We'll process each argument with its parameter path as targetPath
671
- const callPath = StructuredPath.fromNode(unwrappedNode, context.sourceFile);
1278
+ // Build call path using original source text for consistent schema paths.
1279
+ // IMPORTANT: Never use cyScope names in call paths - they are internal identifiers
1280
+ // that should not appear in schema paths or call signatures.
1281
+ const callPath = buildCallPathFromSource(unwrappedNode, context);
672
1282
  // 2. Process all arguments recursively WITH targetPath for proper equivalence
673
1283
  for (let i = 0; i < unwrappedNode.arguments.length; i++) {
674
1284
  const arg = unwrappedNode.arguments[i];
@@ -798,6 +1408,12 @@ export function processExpression({ node, context, targetPath, typeHint, }) {
798
1408
  }
799
1409
  // Create a path for this property within the base
800
1410
  const propPath = targetPath.withProperty(propName);
1411
+ // Handle child boundaries (callback functions) in object properties
1412
+ // This establishes equivalency between the property path and the child scope
1413
+ // e.g., columns[0].renderCell → cyScope1()
1414
+ if (context.isChildBoundary(property.initializer)) {
1415
+ context.addChildBoundaryEquivalence(propPath, property.initializer);
1416
+ }
801
1417
  // Process the property value with propPath as targetPath
802
1418
  // This allows nested object literals to work correctly
803
1419
  processExpression({
@@ -1032,14 +1648,24 @@ export function processExpression({ node, context, targetPath, typeHint, }) {
1032
1648
  markConditionVariablesAsNullable(unwrappedNode.condition, context);
1033
1649
  // Extract conditional usages for key attribute detection
1034
1650
  extractConditionalUsage(unwrappedNode.condition, context, 'ternary');
1651
+ // Extract conditional effects (setter calls in ternary branches)
1652
+ const knownSetters = findUseStateSetters(context.sourceFile);
1653
+ const effects = extractConditionalEffectsFromTernary(unwrappedNode, context, knownSetters);
1654
+ for (const effect of effects) {
1655
+ context.addConditionalEffect(effect);
1656
+ }
1035
1657
  // Process all parts recursively
1036
1658
  processExpression({
1037
1659
  node: unwrappedNode.condition,
1038
1660
  context,
1039
1661
  typeHint: 'boolean | unknown',
1040
1662
  }); //TODO: could we capture that this is evidence of a boolean type?
1041
- processExpression({ node: unwrappedNode.whenTrue, context });
1042
- processExpression({ node: unwrappedNode.whenFalse, context });
1663
+ // Process both branches WITH targetPath to establish equivalencies
1664
+ // This is critical for tracing nested properties through ternary assignments
1665
+ // e.g., const items = condition ? arr1 : arr2; items.map(i => i.prop)
1666
+ // We need items to be equivalent to both arr1 AND arr2 for proper tracing
1667
+ processExpression({ node: unwrappedNode.whenTrue, context, targetPath });
1668
+ processExpression({ node: unwrappedNode.whenFalse, context, targetPath });
1043
1669
  // Create a path for the whole expression
1044
1670
  const expressionSourcePath = nodeToSource(unwrappedNode, context.sourceFile);
1045
1671
  // Infer type based on branches
@@ -1054,10 +1680,22 @@ export function processExpression({ node, context, targetPath, typeHint, }) {
1054
1680
  }
1055
1681
  // Register type for the expression
1056
1682
  context.addType(expressionSourcePath, resultType);
1057
- // If targetPath is provided, establish equivalence and register type
1683
+ // If targetPath is provided, only register type (don't overwrite branch equivalencies)
1684
+ // The equivalencies to individual branches (set above) are more useful for tracing
1685
+ // than an equivalency to the entire ternary expression text
1058
1686
  if (targetPath) {
1059
- context.addEquivalence(targetPath, expressionSourcePath);
1060
- context.addType(targetPath, resultType);
1687
+ // NOTE: We intentionally do NOT add equivalence here.
1688
+ // The branch processing above already added equivalencies:
1689
+ // targetPath -> whenTrue branch
1690
+ // targetPath -> whenFalse branch
1691
+ // Adding an equivalence to expressionSourcePath would overwrite those
1692
+ // with a useless equivalence to the ternary text itself.
1693
+ //
1694
+ // Use updateSchemaType instead of addType because:
1695
+ // 1. Branch processing may have already set a type on targetPath
1696
+ // 2. addType has a guard that prevents overwriting specific types with 'unknown'
1697
+ // 3. updateSchemaType bypasses this guard, ensuring the ternary's computed type is used
1698
+ context.updateSchemaType(targetPath, resultType);
1061
1699
  }
1062
1700
  return true;
1063
1701
  }
@@ -1618,6 +2256,9 @@ function processJsxAttribute(attr, context, componentPath, targetPath) {
1618
2256
  if (ts.isJsxExpression(attr.initializer) && attr.initializer.expression) {
1619
2257
  const expression = attr.initializer.expression;
1620
2258
  if (context.isChildBoundary(expression)) {
2259
+ // Create equivalency between attribute path and child scope
2260
+ // e.g., Grid().signature[0].renderRow → cyScope1()
2261
+ context.addChildBoundaryEquivalence(attributePath, expression);
1621
2262
  return true;
1622
2263
  }
1623
2264
  // Process the expression with attributePath as targetPath