@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,5 +1,10 @@
1
1
  import ts from 'typescript';
2
- import { AnalysisContext, ConditionalUsage } from './types';
2
+ import * as crypto from 'crypto';
3
+ import {
4
+ AnalysisContext,
5
+ CompoundConditional,
6
+ ConditionalUsage,
7
+ } from './types';
3
8
  import { StructuredPath } from './paths';
4
9
  import { nodeToSource } from './nodeToSource';
5
10
  import { methodRegistry, ArrayPushSemantics } from './methodSemantics';
@@ -14,6 +19,235 @@ import {
14
19
  unwrapExpression,
15
20
  } from './sharedPatterns';
16
21
  import { processBindingPattern } from './processBindings';
22
+ import {
23
+ extractConditionalEffectsFromTernary,
24
+ findUseStateSetters,
25
+ } from './conditionalEffectsExtractor';
26
+
27
+ /**
28
+ * Extracts the component name from a JSX element.
29
+ * Returns null for intrinsic elements (div, span, etc.) since we only care about
30
+ * custom components for gating condition tracking.
31
+ *
32
+ * Examples:
33
+ * - <ChildViewer /> → "ChildViewer"
34
+ * - <ScenarioViewer scenario={...} /> → "ScenarioViewer"
35
+ * - <div> → null (intrinsic element)
36
+ */
37
+ function getComponentNameFromJsx(
38
+ node: ts.JsxElement | ts.JsxSelfClosingElement,
39
+ ): string | null {
40
+ let tagName: ts.JsxTagNameExpression;
41
+
42
+ if (ts.isJsxElement(node)) {
43
+ tagName = node.openingElement.tagName;
44
+ } else {
45
+ tagName = node.tagName;
46
+ }
47
+
48
+ // Get the text of the tag name
49
+ const name = tagName.getText();
50
+
51
+ // Check if it's a custom component (starts with uppercase) vs intrinsic element
52
+ // Custom components start with uppercase: <MyComponent />
53
+ // Intrinsic elements start with lowercase: <div />
54
+ if (
55
+ name &&
56
+ name[0] === name[0].toUpperCase() &&
57
+ name[0] !== name[0].toLowerCase()
58
+ ) {
59
+ return name;
60
+ }
61
+
62
+ return null;
63
+ }
64
+
65
+ /**
66
+ * Extracts condition paths from a logical AND chain expression.
67
+ * Used for creating gating conditions for child components.
68
+ *
69
+ * Example: `hasData && isReady && <Component />` returns ['hasData', 'isReady']
70
+ */
71
+ function extractConditionPathsFromAndChain(
72
+ expr: ts.Expression,
73
+ sourceFile: ts.SourceFile,
74
+ ): string[] {
75
+ const paths: string[] = [];
76
+ const unwrapped = unwrapExpression(expr);
77
+
78
+ if (
79
+ ts.isBinaryExpression(unwrapped) &&
80
+ unwrapped.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken
81
+ ) {
82
+ // Recursively get conditions from left side
83
+ paths.push(
84
+ ...extractConditionPathsFromAndChain(unwrapped.left, sourceFile),
85
+ );
86
+
87
+ // Process right side if it's not JSX (JSX is the consequence, not a condition)
88
+ const rightUnwrapped = unwrapExpression(unwrapped.right);
89
+ if (
90
+ !ts.isJsxElement(rightUnwrapped) &&
91
+ !ts.isJsxSelfClosingElement(rightUnwrapped) &&
92
+ !ts.isJsxFragment(rightUnwrapped)
93
+ ) {
94
+ paths.push(
95
+ ...extractConditionPathsFromAndChain(unwrapped.right, sourceFile),
96
+ );
97
+ }
98
+ } else {
99
+ // Base case: extract path from this expression
100
+ const path = StructuredPath.fromNode(unwrapped, sourceFile);
101
+ if (path) {
102
+ paths.push(path.toString());
103
+ }
104
+ }
105
+
106
+ return paths;
107
+ }
108
+
109
+ /**
110
+ * Finds the rightmost JSX element in an && chain.
111
+ * Example: `a && b && <Component />` returns <Component />
112
+ */
113
+ function findJsxInAndChain(
114
+ expr: ts.Expression,
115
+ ): ts.JsxElement | ts.JsxSelfClosingElement | null {
116
+ const unwrapped = unwrapExpression(expr);
117
+
118
+ if (ts.isJsxElement(unwrapped) || ts.isJsxSelfClosingElement(unwrapped)) {
119
+ return unwrapped;
120
+ }
121
+
122
+ if (
123
+ ts.isBinaryExpression(unwrapped) &&
124
+ unwrapped.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken
125
+ ) {
126
+ // Check right side first (most common case: condition && <Jsx />)
127
+ const rightResult = findJsxInAndChain(unwrapped.right);
128
+ if (rightResult) return rightResult;
129
+
130
+ // Also check left side for rare cases
131
+ return findJsxInAndChain(unwrapped.left);
132
+ }
133
+
134
+ return null;
135
+ }
136
+
137
+ /**
138
+ * Fix 32: Finds a JSX fragment in an && chain.
139
+ * Example: `activeTab && <><ChildA /><ChildB /></>` returns the fragment
140
+ * This is needed to propagate parent conditions through fragments.
141
+ */
142
+ function findJsxFragmentInAndChain(expr: ts.Expression): ts.JsxFragment | null {
143
+ const unwrapped = unwrapExpression(expr);
144
+
145
+ if (ts.isJsxFragment(unwrapped)) {
146
+ return unwrapped;
147
+ }
148
+
149
+ if (
150
+ ts.isBinaryExpression(unwrapped) &&
151
+ unwrapped.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken
152
+ ) {
153
+ // Check right side first (most common case: condition && <></>)
154
+ const rightResult = findJsxFragmentInAndChain(unwrapped.right);
155
+ if (rightResult) return rightResult;
156
+
157
+ // Also check left side for rare cases
158
+ return findJsxFragmentInAndChain(unwrapped.left);
159
+ }
160
+
161
+ return null;
162
+ }
163
+
164
+ /**
165
+ * Detects if a property access looks like an environment variable store access.
166
+ * Matches patterns like `env.DATABASE_URL`, `env.IS_FORMBRICKS_CLOUD`, etc.
167
+ * where the object is named "env" and the property looks like an env var name.
168
+ */
169
+ function isEnvStoreAccess(fullText: string): boolean {
170
+ // Match: env.SOME_VAR or env.someVar (but object must be exactly "env")
171
+ // This catches patterns from @t3-oss/env-nextjs and similar packages
172
+ const envStorePattern = /^env\.[A-Z_][A-Z0-9_]*$/;
173
+ return envStorePattern.test(fullText);
174
+ }
175
+
176
+ /**
177
+ * Converts a call expression argument to a StructuredPath.
178
+ *
179
+ * IMPORTANT: We always use the original source text for callbacks, never cyScope names.
180
+ * cyScope names are internal identifiers for child scopes and should NEVER appear
181
+ * in schema paths or call signatures. Using cyScope names causes data merge conflicts
182
+ * because the same callback gets different identifiers in different contexts.
183
+ */
184
+ function getArgPathForCallSignature(
185
+ arg: ts.Expression,
186
+ context: AnalysisContext,
187
+ ): StructuredPath {
188
+ // Always use the standard path conversion - never replace with cyScope names
189
+ return (
190
+ StructuredPath.fromNode(arg, context.sourceFile) ||
191
+ nodeToSource(arg, context.sourceFile)
192
+ );
193
+ }
194
+
195
+ /**
196
+ * Builds a StructuredPath for a call expression using the original source text.
197
+ *
198
+ * IMPORTANT: This function ensures consistent call signatures by always using
199
+ * the original callback text, never cyScope names. This prevents schema path
200
+ * conflicts where the same call would have different paths.
201
+ */
202
+ function buildCallPathFromSource(
203
+ node: ts.CallExpression,
204
+ context: AnalysisContext,
205
+ ): StructuredPath | null {
206
+ const expression = node.expression;
207
+
208
+ // Convert arguments using original source text
209
+ const argPaths = node.arguments.map((arg) =>
210
+ getArgPathForCallSignature(arg, context),
211
+ );
212
+
213
+ // Handle type arguments if present
214
+ let typeArgs: string[] | undefined = undefined;
215
+ if (node.typeArguments && node.typeArguments.length > 0) {
216
+ typeArgs = node.typeArguments.map((typeArg) =>
217
+ typeArg.getText(context.sourceFile),
218
+ );
219
+ }
220
+
221
+ if (ts.isIdentifier(expression)) {
222
+ // Simple function call: func(arg1, arg2)
223
+ return StructuredPath.fromFunction(expression.text, argPaths, typeArgs);
224
+ } else if (ts.isPropertyAccessExpression(expression)) {
225
+ // Method call: obj.method(arg1, arg2)
226
+ const objPath = StructuredPath.fromNode(
227
+ expression.expression,
228
+ context.sourceFile,
229
+ );
230
+ if (!objPath) return null;
231
+ return objPath
232
+ .withProperty(expression.name.text)
233
+ .withFunctionCall(argPaths, typeArgs);
234
+ } else if (ts.isCallExpression(expression)) {
235
+ // Chained call: func(arg1)(arg2)
236
+ const funcPath = buildCallPathFromSource(expression, context);
237
+ if (!funcPath) return null;
238
+ return funcPath.withFunctionCall(argPaths, typeArgs);
239
+ } else if (ts.isElementAccessExpression(expression)) {
240
+ // Element access call: obj[key](args)
241
+ const basePath = StructuredPath.fromNode(expression, context.sourceFile);
242
+ if (!basePath) return null;
243
+ return basePath.withFunctionCall(argPaths, typeArgs);
244
+ } else {
245
+ // Complex call expression
246
+ const basePath = StructuredPath.fromNode(expression, context.sourceFile);
247
+ if (!basePath) return null;
248
+ return basePath.withFunctionCall(argPaths, typeArgs);
249
+ }
250
+ }
17
251
 
18
252
  /**
19
253
  * Checks if an expression is likely an array type.
@@ -114,131 +348,694 @@ export function markConditionVariablesAsNullable(
114
348
  }
115
349
 
116
350
  /**
117
- * Extracts conditional usages from a condition expression for key attribute detection.
118
- * This function identifies which attributes are used in conditionals and how they're used.
119
- *
120
- * @param condition The condition expression to analyze
121
- * @param context The analysis context
122
- * @param location Where this condition appears (if, ternary, logical-and, switch)
351
+ * Helper to extract source location from an AST node
123
352
  */
124
- export function extractConditionalUsage(
125
- condition: ts.Expression,
126
- context: AnalysisContext,
127
- location: ConditionalUsage['location'],
128
- ): void {
129
- const unwrapped = unwrapExpression(condition);
353
+ function getSourceLocation(
354
+ node: ts.Node,
355
+ sourceFile: ts.SourceFile,
356
+ ): ConditionalUsage['sourceLocation'] {
357
+ const start = node.getStart(sourceFile);
358
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(start);
359
+ const codeSnippet = node.getText(sourceFile);
360
+
361
+ return {
362
+ lineNumber: line + 1, // Convert to 1-based
363
+ column: character,
364
+ codeSnippet:
365
+ codeSnippet.length > 100
366
+ ? codeSnippet.slice(0, 100) + '...'
367
+ : codeSnippet,
368
+ };
369
+ }
370
+
371
+ /**
372
+ * Counts the number of conditions in an && chain (excluding JSX consequence)
373
+ */
374
+ function countConditionsInAndChain(expr: ts.Expression): number {
375
+ const unwrapped = unwrapExpression(expr);
130
376
 
131
- // Handle binary expressions with && (logical AND chains)
132
- // Example: `a && b && <Component />` - both a and b are conditional checks
133
377
  if (
134
378
  ts.isBinaryExpression(unwrapped) &&
135
379
  unwrapped.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken
136
380
  ) {
137
- // Recursively process left side
138
- extractConditionalUsage(unwrapped.left, context, location);
139
-
140
- // Process right side if it's not JSX (JSX is the consequence, not the condition)
381
+ const leftCount = countConditionsInAndChain(unwrapped.left);
141
382
  const rightUnwrapped = unwrapExpression(unwrapped.right);
142
383
  const isJsxConsequence =
143
384
  ts.isJsxElement(rightUnwrapped) ||
144
385
  ts.isJsxSelfClosingElement(rightUnwrapped) ||
145
386
  ts.isJsxFragment(rightUnwrapped);
146
387
 
147
- if (!isJsxConsequence) {
148
- extractConditionalUsage(unwrapped.right, context, location);
388
+ if (isJsxConsequence) {
389
+ return leftCount;
149
390
  }
150
- return;
391
+ return leftCount + countConditionsInAndChain(unwrapped.right);
151
392
  }
152
393
 
153
- // Handle binary expressions with || (logical OR)
154
- if (
155
- ts.isBinaryExpression(unwrapped) &&
156
- unwrapped.operatorToken.kind === ts.SyntaxKind.BarBarToken
157
- ) {
158
- // Both sides of || are conditional checks
159
- extractConditionalUsage(unwrapped.left, context, location);
160
- extractConditionalUsage(unwrapped.right, context, location);
394
+ // Single condition (not an && chain)
395
+ return 1;
396
+ }
397
+
398
+ /**
399
+ * Chain tracking info for compound conditionals
400
+ */
401
+ interface ChainInfo {
402
+ chainId: string;
403
+ chainLength: number;
404
+ chainExpression: string;
405
+ currentPosition: number;
406
+ compound: CompoundConditional;
407
+ }
408
+
409
+ /**
410
+ * Parent gating condition accumulated during JSX traversal.
411
+ * Used to track conditions from parent && chains that gate child components.
412
+ */
413
+ interface ParentGatingCondition {
414
+ path: string;
415
+ sourceLocation: { lineNumber: number; column: number; codeSnippet: string };
416
+ isNegated?: boolean;
417
+ }
418
+
419
+ /**
420
+ * Extracts conditionals from JSX elements by recursively traversing children.
421
+ *
422
+ * This is CRITICAL for extracting compound conditionals from JSX expressions
423
+ * like `{hasNewerVersion && !isActive && <Banner />}`.
424
+ *
425
+ * This function is called BEFORE the child boundary check in processExpression
426
+ * because JSX elements are NOT scopes - their expressions use variables from
427
+ * the parent scope and should have their conditionals extracted regardless of
428
+ * whether the JSX is within a child boundary.
429
+ *
430
+ * Fix 32: Added parentConditions parameter to track gating conditions from
431
+ * parent && chains. When we find a component nested inside multiple conditionals
432
+ * like `{activeTab && <>{ternary ? ... : <Component />}</>}`, ALL parent
433
+ * conditions should be added as gating conditions for the component.
434
+ *
435
+ * @param node The JSX element, self-closing element, or fragment to traverse
436
+ * @param context The analysis context
437
+ * @param parentConditions Accumulated gating conditions from parent && chains
438
+ */
439
+ function extractConditionalsFromJsx(
440
+ node: ts.JsxElement | ts.JsxSelfClosingElement | ts.JsxFragment,
441
+ context: AnalysisContext,
442
+ parentConditions: ParentGatingCondition[] = [],
443
+ ): void {
444
+ // Get children to process
445
+ let children: ts.NodeArray<ts.JsxChild> | undefined;
446
+
447
+ if (ts.isJsxElement(node)) {
448
+ children = node.children;
449
+ } else if (ts.isJsxFragment(node)) {
450
+ children = node.children;
451
+ }
452
+ // JsxSelfClosingElement has no children
453
+
454
+ if (!children) {
161
455
  return;
162
456
  }
163
457
 
164
- // Handle comparison operators (===, !==, <, >, <=, >=)
165
- // Example: `if (status === 'active')` - status is compared against 'active'
166
- if (
167
- ts.isBinaryExpression(unwrapped) &&
168
- isComparisonOperator(unwrapped.operatorToken.kind)
169
- ) {
170
- // Try to extract the variable and the compared value
171
- const leftPath = StructuredPath.fromNode(
172
- unwrapped.left,
173
- context.sourceFile,
174
- );
175
- const rightPath = StructuredPath.fromNode(
176
- unwrapped.right,
177
- context.sourceFile,
178
- );
458
+ for (const child of children) {
459
+ // Process JSX expressions: {expr}
460
+ if (ts.isJsxExpression(child) && child.expression) {
461
+ const expr = unwrapExpression(child.expression);
179
462
 
180
- // Check if left is a variable and right is a literal
181
- if (leftPath && isLiteralExpression(unwrapped.right)) {
182
- const literalValue = getLiteralValue(unwrapped.right, context);
183
- context.addConditionalUsage({
184
- path: leftPath.toLeftHandSideString(),
185
- conditionType: 'comparison',
186
- comparedValues: literalValue !== undefined ? [literalValue] : undefined,
187
- location,
188
- });
463
+ // If the expression is an && chain, extract its conditional usages
464
+ if (
465
+ ts.isBinaryExpression(expr) &&
466
+ expr.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken
467
+ ) {
468
+ // Mark nullable variables
469
+ markConditionVariablesAsNullable(expr, context);
470
+ // Extract conditional usage (this handles compound conditionals)
471
+ // Pass controlsJsxRendering: true since this conditional controls JSX rendering
472
+ extractConditionalUsage(expr, context, 'logical-and', {
473
+ controlsJsxRendering: true,
474
+ });
475
+
476
+ // Extract all condition paths from the && chain for gating tracking
477
+ const conditionPaths = extractConditionPathsFromAndChain(
478
+ expr,
479
+ context.sourceFile,
480
+ );
481
+ const sourceLocation = getSourceLocation(expr, context.sourceFile);
482
+
483
+ // Fix 32: Build accumulated conditions including parent conditions
484
+ const accumulatedConditions: ParentGatingCondition[] = [
485
+ ...parentConditions,
486
+ ...conditionPaths.map((path) => ({
487
+ path,
488
+ sourceLocation,
489
+ isNegated: false,
490
+ })),
491
+ ];
492
+
493
+ // Track gating conditions for child components
494
+ // Example: {hasAnalysis && <ScenarioViewer />}
495
+ const jsxElement = findJsxInAndChain(expr);
496
+ if (jsxElement) {
497
+ const componentName = getComponentNameFromJsx(jsxElement);
498
+ if (componentName) {
499
+ // Fix 32: Add ALL accumulated conditions (parent + current) as gating conditions
500
+ for (const condition of accumulatedConditions) {
501
+ context.addChildBoundaryGatingCondition(componentName, {
502
+ path: condition.path,
503
+ conditionType: 'truthiness',
504
+ location: 'logical-and',
505
+ sourceLocation: condition.sourceLocation,
506
+ controlsJsxRendering: true,
507
+ isNegated: condition.isNegated,
508
+ });
509
+ }
510
+ }
511
+
512
+ // Fix 32: Recursively process nested JSX with accumulated conditions
513
+ if (
514
+ ts.isJsxElement(jsxElement) ||
515
+ ts.isJsxSelfClosingElement(jsxElement)
516
+ ) {
517
+ extractConditionalsFromJsx(
518
+ jsxElement,
519
+ context,
520
+ accumulatedConditions,
521
+ );
522
+ }
523
+ }
524
+
525
+ // Fix 32: Also check for nested JSX fragments
526
+ const jsxFragment = findJsxFragmentInAndChain(expr);
527
+ if (jsxFragment) {
528
+ extractConditionalsFromJsx(
529
+ jsxFragment,
530
+ context,
531
+ accumulatedConditions,
532
+ );
533
+ }
534
+ }
535
+ // If the expression is a ternary, extract its conditional
536
+ else if (ts.isConditionalExpression(expr)) {
537
+ // Pass controlsJsxRendering: true since this conditional controls JSX rendering
538
+ extractConditionalUsage(expr.condition, context, 'ternary', {
539
+ controlsJsxRendering: true,
540
+ });
541
+
542
+ // Track gating conditions for components in both branches of the ternary
543
+ // Example: {isError ? <ErrorView /> : <SuccessView />}
544
+ const conditionPath = StructuredPath.fromNode(
545
+ unwrapExpression(expr.condition),
546
+ context.sourceFile,
547
+ );
548
+ const sourceLocation = getSourceLocation(expr, context.sourceFile);
549
+
550
+ // Recursively process the whenTrue and whenFalse branches for JSX
551
+ const whenTrue = unwrapExpression(expr.whenTrue);
552
+ const whenFalse = unwrapExpression(expr.whenFalse);
553
+
554
+ // Fix 32: Build conditions for whenTrue branch (parent conditions + ternary condition truthy)
555
+ const whenTrueConditions: ParentGatingCondition[] = [
556
+ ...parentConditions,
557
+ ...(conditionPath
558
+ ? [
559
+ {
560
+ path: conditionPath.toString(),
561
+ sourceLocation,
562
+ isNegated: false,
563
+ },
564
+ ]
565
+ : []),
566
+ ];
567
+
568
+ // Fix 32: Build conditions for whenFalse branch (parent conditions + ternary condition falsy)
569
+ const whenFalseConditions: ParentGatingCondition[] = [
570
+ ...parentConditions,
571
+ ...(conditionPath
572
+ ? [
573
+ {
574
+ path: conditionPath.toString(),
575
+ sourceLocation,
576
+ isNegated: true,
577
+ },
578
+ ]
579
+ : []),
580
+ ];
581
+
582
+ // Handle whenTrue branch (condition is truthy)
583
+ if (ts.isJsxElement(whenTrue) || ts.isJsxSelfClosingElement(whenTrue)) {
584
+ const componentName = getComponentNameFromJsx(whenTrue);
585
+ if (componentName) {
586
+ // Fix 32: Add ALL conditions (parent + ternary) as gating conditions
587
+ for (const condition of whenTrueConditions) {
588
+ context.addChildBoundaryGatingCondition(componentName, {
589
+ path: condition.path,
590
+ conditionType: 'truthiness',
591
+ location: 'ternary',
592
+ sourceLocation: condition.sourceLocation,
593
+ controlsJsxRendering: true,
594
+ isNegated: condition.isNegated,
595
+ });
596
+ }
597
+ }
598
+ }
599
+ if (
600
+ ts.isJsxElement(whenTrue) ||
601
+ ts.isJsxSelfClosingElement(whenTrue) ||
602
+ ts.isJsxFragment(whenTrue)
603
+ ) {
604
+ extractConditionalsFromJsx(whenTrue, context, whenTrueConditions);
605
+ }
606
+
607
+ // Handle whenFalse branch (condition is falsy/negated)
608
+ if (
609
+ ts.isJsxElement(whenFalse) ||
610
+ ts.isJsxSelfClosingElement(whenFalse)
611
+ ) {
612
+ const componentName = getComponentNameFromJsx(whenFalse);
613
+ if (componentName) {
614
+ // Fix 32: Add ALL conditions (parent + ternary) as gating conditions
615
+ for (const condition of whenFalseConditions) {
616
+ context.addChildBoundaryGatingCondition(componentName, {
617
+ path: condition.path,
618
+ conditionType: 'truthiness',
619
+ location: 'ternary',
620
+ sourceLocation: condition.sourceLocation,
621
+ controlsJsxRendering: true,
622
+ isNegated: condition.isNegated,
623
+ });
624
+ }
625
+ }
626
+ }
627
+ if (
628
+ ts.isJsxElement(whenFalse) ||
629
+ ts.isJsxSelfClosingElement(whenFalse) ||
630
+ ts.isJsxFragment(whenFalse)
631
+ ) {
632
+ extractConditionalsFromJsx(whenFalse, context, whenFalseConditions);
633
+ }
634
+ // Handle chained ternaries: a ? <A/> : b ? <B/> : <C/>
635
+ // When whenFalse is another ConditionalExpression, recursively process it
636
+ else if (ts.isConditionalExpression(whenFalse)) {
637
+ // Extract conditional usage for the nested ternary's condition
638
+ extractConditionalUsage(whenFalse.condition, context, 'ternary', {
639
+ controlsJsxRendering: true,
640
+ });
641
+
642
+ // Get the nested condition path
643
+ const nestedConditionPath = StructuredPath.fromNode(
644
+ unwrapExpression(whenFalse.condition),
645
+ context.sourceFile,
646
+ );
647
+ const nestedSourceLocation = getSourceLocation(
648
+ whenFalse,
649
+ context.sourceFile,
650
+ );
651
+
652
+ const nestedWhenTrue = unwrapExpression(whenFalse.whenTrue);
653
+ const nestedWhenFalse = unwrapExpression(whenFalse.whenFalse);
654
+
655
+ // Fix 32: Build conditions for nested whenTrue (parent falsy + nested truthy)
656
+ const nestedWhenTrueConditions: ParentGatingCondition[] = [
657
+ ...whenFalseConditions, // Parent ternary was falsy to get here
658
+ ...(nestedConditionPath
659
+ ? [
660
+ {
661
+ path: nestedConditionPath.toString(),
662
+ sourceLocation: nestedSourceLocation,
663
+ isNegated: false,
664
+ },
665
+ ]
666
+ : []),
667
+ ];
668
+
669
+ // Fix 32: Build conditions for nested whenFalse (parent falsy + nested falsy)
670
+ const nestedWhenFalseConditions: ParentGatingCondition[] = [
671
+ ...whenFalseConditions, // Parent ternary was falsy to get here
672
+ ...(nestedConditionPath
673
+ ? [
674
+ {
675
+ path: nestedConditionPath.toString(),
676
+ sourceLocation: nestedSourceLocation,
677
+ isNegated: true,
678
+ },
679
+ ]
680
+ : []),
681
+ ];
682
+
683
+ // Handle nested whenTrue branch
684
+ if (
685
+ ts.isJsxElement(nestedWhenTrue) ||
686
+ ts.isJsxSelfClosingElement(nestedWhenTrue)
687
+ ) {
688
+ const componentName = getComponentNameFromJsx(nestedWhenTrue);
689
+ if (componentName) {
690
+ // Fix 32: Add ALL accumulated conditions
691
+ for (const condition of nestedWhenTrueConditions) {
692
+ context.addChildBoundaryGatingCondition(componentName, {
693
+ path: condition.path,
694
+ conditionType: 'truthiness',
695
+ location: 'ternary',
696
+ sourceLocation: condition.sourceLocation,
697
+ controlsJsxRendering: true,
698
+ isNegated: condition.isNegated,
699
+ });
700
+ }
701
+ }
702
+ }
703
+ if (
704
+ ts.isJsxElement(nestedWhenTrue) ||
705
+ ts.isJsxSelfClosingElement(nestedWhenTrue) ||
706
+ ts.isJsxFragment(nestedWhenTrue)
707
+ ) {
708
+ extractConditionalsFromJsx(
709
+ nestedWhenTrue,
710
+ context,
711
+ nestedWhenTrueConditions,
712
+ );
713
+ }
714
+
715
+ // Handle nested whenFalse branch (this could be another chained ternary or JSX)
716
+ if (
717
+ ts.isJsxElement(nestedWhenFalse) ||
718
+ ts.isJsxSelfClosingElement(nestedWhenFalse)
719
+ ) {
720
+ const componentName = getComponentNameFromJsx(nestedWhenFalse);
721
+ if (componentName) {
722
+ // Fix 32: Add ALL accumulated conditions
723
+ for (const condition of nestedWhenFalseConditions) {
724
+ context.addChildBoundaryGatingCondition(componentName, {
725
+ path: condition.path,
726
+ conditionType: 'truthiness',
727
+ location: 'ternary',
728
+ sourceLocation: condition.sourceLocation,
729
+ controlsJsxRendering: true,
730
+ isNegated: condition.isNegated,
731
+ });
732
+ }
733
+ }
734
+ }
735
+ if (
736
+ ts.isJsxElement(nestedWhenFalse) ||
737
+ ts.isJsxSelfClosingElement(nestedWhenFalse) ||
738
+ ts.isJsxFragment(nestedWhenFalse)
739
+ ) {
740
+ extractConditionalsFromJsx(
741
+ nestedWhenFalse,
742
+ context,
743
+ nestedWhenFalseConditions,
744
+ );
745
+ }
746
+ // If nestedWhenFalse is yet another ConditionalExpression, the recursion
747
+ // will handle it on the next iteration when this function processes it
748
+ else if (ts.isConditionalExpression(nestedWhenFalse)) {
749
+ // Recursively handle deeper nesting by wrapping in a synthetic process
750
+ // We create a fake JsxExpression context to reuse the same logic
751
+ const syntheticChild = {
752
+ kind: ts.SyntaxKind.JsxExpression,
753
+ expression: nestedWhenFalse,
754
+ } as unknown as ts.JsxExpression;
755
+ // Process via the main JSX expression handler by recursing
756
+ // For now, just extract conditionals directly
757
+ extractConditionalUsage(
758
+ nestedWhenFalse.condition,
759
+ context,
760
+ 'ternary',
761
+ { controlsJsxRendering: true },
762
+ );
763
+ }
764
+ }
765
+ }
766
+ }
767
+ // Recursively process nested JSX elements - Fix 32: pass parent conditions
768
+ else if (ts.isJsxElement(child)) {
769
+ extractConditionalsFromJsx(child, context, parentConditions);
770
+ }
771
+ // Recursively process nested JSX fragments - Fix 32: pass parent conditions
772
+ else if (ts.isJsxFragment(child)) {
773
+ extractConditionalsFromJsx(child, context, parentConditions);
774
+ }
775
+ }
776
+ }
777
+
778
+ /**
779
+ * Options for extractConditionalUsage
780
+ */
781
+ interface ExtractConditionalOptions {
782
+ /**
783
+ * Whether this conditional controls JSX rendering.
784
+ * Set to true when the conditional appears in a JSX expression like {cond && <Component />}
785
+ */
786
+ controlsJsxRendering?: boolean;
787
+ }
788
+
789
+ /**
790
+ * Extracts conditional usages from a condition expression for key attribute detection.
791
+ * This function identifies which attributes are used in conditionals and how they're used.
792
+ * It also tracks compound conditionals (&&-chains) where all conditions must be true together.
793
+ *
794
+ * @param condition The condition expression to analyze
795
+ * @param context The analysis context
796
+ * @param location Where this condition appears (if, ternary, logical-and, switch)
797
+ * @param options Additional options including controlsJsxRendering flag
798
+ */
799
+ export function extractConditionalUsage(
800
+ condition: ts.Expression,
801
+ context: AnalysisContext,
802
+ location: ConditionalUsage['location'],
803
+ options: ExtractConditionalOptions = {},
804
+ ): void {
805
+ const { controlsJsxRendering } = options;
806
+ // Internal recursive function with chain tracking
807
+ function extractWithChainTracking(
808
+ expr: ts.Expression,
809
+ chainInfo: ChainInfo | null,
810
+ isNegated: boolean,
811
+ ): void {
812
+ const unwrapped = unwrapExpression(expr);
813
+
814
+ // Handle binary expressions with && (logical AND chains)
815
+ // Example: `a && b && <Component />` - both a and b are conditional checks
816
+ if (
817
+ ts.isBinaryExpression(unwrapped) &&
818
+ unwrapped.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken
819
+ ) {
820
+ // Track if we're creating the chain at this level (root of the chain)
821
+ const isChainRoot = !chainInfo;
822
+
823
+ // If no chainInfo, this is the root of a new chain
824
+ if (isChainRoot) {
825
+ const chainLength = countConditionsInAndChain(unwrapped);
826
+ // Only create chain tracking for chains with 2+ conditions
827
+ if (chainLength >= 2) {
828
+ const chainId = `chain_${crypto.randomUUID().slice(0, 8)}`;
829
+ const chainExpression = unwrapped.getText(context.sourceFile);
830
+ const compound: CompoundConditional = {
831
+ chainId,
832
+ expression:
833
+ chainExpression.length > 200
834
+ ? chainExpression.slice(0, 200) + '...'
835
+ : chainExpression,
836
+ conditions: [],
837
+ location,
838
+ sourceLocation: getSourceLocation(unwrapped, context.sourceFile),
839
+ controlsJsxRendering,
840
+ };
841
+ chainInfo = {
842
+ chainId,
843
+ chainLength,
844
+ chainExpression: compound.expression,
845
+ currentPosition: 0,
846
+ compound,
847
+ };
848
+ }
849
+ }
850
+
851
+ // Recursively process left side
852
+ extractWithChainTracking(unwrapped.left, chainInfo, false);
853
+
854
+ // Process right side if it's not JSX (JSX is the consequence, not the condition)
855
+ const rightUnwrapped = unwrapExpression(unwrapped.right);
856
+ const isJsxConsequence =
857
+ ts.isJsxElement(rightUnwrapped) ||
858
+ ts.isJsxSelfClosingElement(rightUnwrapped) ||
859
+ ts.isJsxFragment(rightUnwrapped);
860
+
861
+ if (!isJsxConsequence) {
862
+ extractWithChainTracking(unwrapped.right, chainInfo, false);
863
+ }
864
+
865
+ // If this is the root of the chain, register the compound conditional
866
+ if (isChainRoot && chainInfo) {
867
+ context.addCompoundConditional(chainInfo.compound);
868
+ }
189
869
  return;
190
870
  }
191
871
 
192
- // Check if right is a variable and left is a literal
193
- if (rightPath && isLiteralExpression(unwrapped.left)) {
194
- const literalValue = getLiteralValue(unwrapped.left, context);
195
- context.addConditionalUsage({
196
- path: rightPath.toLeftHandSideString(),
197
- conditionType: 'comparison',
198
- comparedValues: literalValue !== undefined ? [literalValue] : undefined,
199
- location,
200
- });
872
+ // Handle binary expressions with || (logical OR)
873
+ // OR breaks the chain - each side is independent
874
+ if (
875
+ ts.isBinaryExpression(unwrapped) &&
876
+ unwrapped.operatorToken.kind === ts.SyntaxKind.BarBarToken
877
+ ) {
878
+ // Both sides of || are independent conditional checks (no chain tracking)
879
+ extractWithChainTracking(unwrapped.left, null, false);
880
+ extractWithChainTracking(unwrapped.right, null, false);
201
881
  return;
202
882
  }
203
883
 
204
- // Both sides are variables - record both as comparisons without specific values
205
- if (leftPath) {
206
- context.addConditionalUsage({
207
- path: leftPath.toLeftHandSideString(),
208
- conditionType: 'comparison',
209
- location,
210
- });
884
+ // Handle comparison operators (===, !==, <, >, <=, >=)
885
+ // Example: `if (status === 'active')` - status is compared against 'active'
886
+ if (
887
+ ts.isBinaryExpression(unwrapped) &&
888
+ isComparisonOperator(unwrapped.operatorToken.kind)
889
+ ) {
890
+ // Try to extract the variable and the compared value
891
+ const leftPath = StructuredPath.fromNode(
892
+ unwrapped.left,
893
+ context.sourceFile,
894
+ );
895
+ const rightPath = StructuredPath.fromNode(
896
+ unwrapped.right,
897
+ context.sourceFile,
898
+ );
899
+
900
+ // Determine the compared value for computing requiredValue
901
+ const getRequiredValue = (
902
+ literalValue: string | undefined,
903
+ isNegatedComparison: boolean,
904
+ ): string | boolean | undefined => {
905
+ if (literalValue === undefined) return undefined;
906
+ // For !== comparisons, the condition is true when NOT equal to the value
907
+ // For === comparisons, the condition is true when equal to the value
908
+ const isNotEqual =
909
+ unwrapped.operatorToken.kind ===
910
+ ts.SyntaxKind.ExclamationEqualsEqualsToken ||
911
+ unwrapped.operatorToken.kind === ts.SyntaxKind.ExclamationEqualsToken;
912
+ if (isNotEqual) {
913
+ // !== 'value' means requiredValue is NOT 'value', but we express this as "not 'value'"
914
+ return `not ${literalValue}`;
915
+ }
916
+ return literalValue;
917
+ };
918
+
919
+ // Helper to add a condition
920
+ const addCondition = (
921
+ path: string,
922
+ conditionType: 'comparison' | 'truthiness',
923
+ comparedValues?: string[],
924
+ requiredValue?: string | boolean,
925
+ ) => {
926
+ const usage: ConditionalUsage = {
927
+ path,
928
+ conditionType,
929
+ comparedValues,
930
+ location,
931
+ sourceLocation: getSourceLocation(unwrapped, context.sourceFile),
932
+ isNegated,
933
+ controlsJsxRendering,
934
+ };
935
+
936
+ // Add chain info if part of a compound conditional
937
+ if (chainInfo) {
938
+ usage.chainId = chainInfo.chainId;
939
+ usage.chainPosition = chainInfo.currentPosition;
940
+ usage.chainLength = chainInfo.chainLength;
941
+ usage.chainExpression = chainInfo.chainExpression;
942
+ chainInfo.currentPosition++;
943
+
944
+ // Add to compound conditional conditions
945
+ chainInfo.compound.conditions.push({
946
+ path,
947
+ conditionType,
948
+ comparedValues,
949
+ isNegated,
950
+ requiredValue,
951
+ });
952
+ }
953
+
954
+ context.addConditionalUsage(usage);
955
+ };
956
+
957
+ // Check if left is a variable and right is a literal
958
+ if (leftPath && isLiteralExpression(unwrapped.right)) {
959
+ const literalValue = getLiteralValue(unwrapped.right, context);
960
+ addCondition(
961
+ leftPath.toLeftHandSideString(),
962
+ 'comparison',
963
+ literalValue !== undefined ? [literalValue] : undefined,
964
+ getRequiredValue(literalValue, isNegated),
965
+ );
966
+ return;
967
+ }
968
+
969
+ // Check if right is a variable and left is a literal
970
+ if (rightPath && isLiteralExpression(unwrapped.left)) {
971
+ const literalValue = getLiteralValue(unwrapped.left, context);
972
+ addCondition(
973
+ rightPath.toLeftHandSideString(),
974
+ 'comparison',
975
+ literalValue !== undefined ? [literalValue] : undefined,
976
+ getRequiredValue(literalValue, isNegated),
977
+ );
978
+ return;
979
+ }
980
+
981
+ // Both sides are variables - record both as comparisons without specific values
982
+ if (leftPath) {
983
+ addCondition(leftPath.toLeftHandSideString(), 'comparison');
984
+ }
985
+ if (rightPath) {
986
+ addCondition(rightPath.toLeftHandSideString(), 'comparison');
987
+ }
988
+ return;
211
989
  }
212
- if (rightPath) {
213
- context.addConditionalUsage({
214
- path: rightPath.toLeftHandSideString(),
215
- conditionType: 'comparison',
216
- location,
217
- });
990
+
991
+ // Handle prefix unary NOT expression: !variable
992
+ // Example: `if (!isVisible)` - isVisible is a truthiness check (negated)
993
+ if (
994
+ ts.isPrefixUnaryExpression(unwrapped) &&
995
+ unwrapped.operator === ts.SyntaxKind.ExclamationToken
996
+ ) {
997
+ extractWithChainTracking(unwrapped.operand, chainInfo, !isNegated);
998
+ return;
218
999
  }
219
- return;
220
- }
221
1000
 
222
- // Handle prefix unary NOT expression: !variable
223
- // Example: `if (!isVisible)` - isVisible is a truthiness check
224
- if (
225
- ts.isPrefixUnaryExpression(unwrapped) &&
226
- unwrapped.operator === ts.SyntaxKind.ExclamationToken
227
- ) {
228
- extractConditionalUsage(unwrapped.operand, context, location);
229
- return;
230
- }
1001
+ // Handle simple identifiers or property accesses (truthiness checks)
1002
+ // Example: `if (x)` or `x && <JSX />` - x is checked for truthiness
1003
+ const path = StructuredPath.fromNode(unwrapped, context.sourceFile);
1004
+ if (path && !path.isLiteral()) {
1005
+ const pathStr = path.toLeftHandSideString();
1006
+ const usage: ConditionalUsage = {
1007
+ path: pathStr,
1008
+ conditionType: 'truthiness',
1009
+ location,
1010
+ sourceLocation: getSourceLocation(unwrapped, context.sourceFile),
1011
+ isNegated,
1012
+ controlsJsxRendering,
1013
+ };
1014
+
1015
+ // Add chain info if part of a compound conditional
1016
+ if (chainInfo) {
1017
+ usage.chainId = chainInfo.chainId;
1018
+ usage.chainPosition = chainInfo.currentPosition;
1019
+ usage.chainLength = chainInfo.chainLength;
1020
+ usage.chainExpression = chainInfo.chainExpression;
1021
+ chainInfo.currentPosition++;
1022
+
1023
+ // Add to compound conditional conditions
1024
+ // For truthiness, requiredValue is true if not negated, false if negated
1025
+ chainInfo.compound.conditions.push({
1026
+ path: pathStr,
1027
+ conditionType: 'truthiness',
1028
+ isNegated,
1029
+ requiredValue: !isNegated,
1030
+ });
1031
+ }
231
1032
 
232
- // Handle simple identifiers or property accesses (truthiness checks)
233
- // Example: `if (x)` or `x && <JSX />` - x is checked for truthiness
234
- const path = StructuredPath.fromNode(unwrapped, context.sourceFile);
235
- if (path && !path.isLiteral()) {
236
- context.addConditionalUsage({
237
- path: path.toLeftHandSideString(),
238
- conditionType: 'truthiness',
239
- location,
240
- });
1033
+ context.addConditionalUsage(usage);
1034
+ }
241
1035
  }
1036
+
1037
+ // Start extraction with no chain info
1038
+ extractWithChainTracking(condition, null, false);
242
1039
  }
243
1040
 
244
1041
  /**
@@ -341,7 +1138,28 @@ export function processExpression({
341
1138
  ) {
342
1139
  markConditionVariablesAsNullable(unwrappedNode, context);
343
1140
  // Extract conditional usages for key attribute detection
344
- extractConditionalUsage(unwrappedNode, context, 'logical-and');
1141
+ // Only call from the OUTERMOST && expression to avoid duplicates
1142
+ // Check if parent is also a && (meaning we're nested)
1143
+ const parent = unwrappedNode.parent;
1144
+ const parentIsAndChain =
1145
+ parent &&
1146
+ ts.isBinaryExpression(parent) &&
1147
+ parent.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken;
1148
+ if (!parentIsAndChain) {
1149
+ extractConditionalUsage(unwrappedNode, context, 'logical-and');
1150
+ }
1151
+ }
1152
+
1153
+ // CRITICAL: Extract conditionals from JSX BEFORE checking child boundaries
1154
+ // JSX elements are NOT scopes - their expressions use variables from the parent scope.
1155
+ // Even if the JSX element is within a child boundary (e.g., because it contains callbacks),
1156
+ // we must still extract conditionals from JSX expression children like {x && <div>...</div>}
1157
+ if (
1158
+ ts.isJsxElement(unwrappedNode) ||
1159
+ ts.isJsxSelfClosingElement(unwrappedNode) ||
1160
+ ts.isJsxFragment(unwrappedNode)
1161
+ ) {
1162
+ extractConditionalsFromJsx(unwrappedNode, context);
345
1163
  }
346
1164
 
347
1165
  // If the node falls within an excluded child scope, stop processing it.
@@ -535,7 +1353,8 @@ export function processExpression({
535
1353
  // Check if this is an environment variable access
536
1354
  const fullText = unwrappedNode.getText(context.sourceFile);
537
1355
  if (
538
- fullText.includes('.env.') // simple heuristic for env var access but not great
1356
+ fullText.includes('.env.') || // process.env.X, window.env.X
1357
+ isEnvStoreAccess(fullText) // env.X where env is likely an env config object
539
1358
  ) {
540
1359
  context.addEnvironmentVariable(fullText);
541
1360
  }
@@ -842,6 +1661,14 @@ export function processExpression({
842
1661
  // e.g., `const tab = segments[0] || 'default'` should trace tab back to segments[0]
843
1662
  if (operatorKind === ts.SyntaxKind.QuestionQuestionToken) {
844
1663
  // specifically for ?? we create an equivalence to the left side
1664
+ // IMPORTANT: Also process the left side recursively to apply method semantics
1665
+ // (e.g., for `const segments = splat?.split('/') ?? []`, we need split semantics)
1666
+ processExpression({
1667
+ node: unwrappedNode.left,
1668
+ context,
1669
+ // Don't pass targetPath here - we'll establish equivalence separately below
1670
+ });
1671
+
845
1672
  if (targetPath) {
846
1673
  resultPath = StructuredPath.fromNode(
847
1674
  unwrappedNode.left,
@@ -930,9 +1757,10 @@ export function processExpression({
930
1757
  return false;
931
1758
  }
932
1759
 
933
- // Construct empty arguments list just to get the call path
934
- // We'll process each argument with its parameter path as targetPath
935
- const callPath = StructuredPath.fromNode(unwrappedNode, context.sourceFile);
1760
+ // Build call path using original source text for consistent schema paths.
1761
+ // IMPORTANT: Never use cyScope names in call paths - they are internal identifiers
1762
+ // that should not appear in schema paths or call signatures.
1763
+ const callPath = buildCallPathFromSource(unwrappedNode, context);
936
1764
 
937
1765
  // 2. Process all arguments recursively WITH targetPath for proper equivalence
938
1766
  for (let i = 0; i < unwrappedNode.arguments.length; i++) {
@@ -1099,6 +1927,13 @@ export function processExpression({
1099
1927
  // Create a path for this property within the base
1100
1928
  const propPath = targetPath.withProperty(propName);
1101
1929
 
1930
+ // Handle child boundaries (callback functions) in object properties
1931
+ // This establishes equivalency between the property path and the child scope
1932
+ // e.g., columns[0].renderCell → cyScope1()
1933
+ if (context.isChildBoundary(property.initializer)) {
1934
+ context.addChildBoundaryEquivalence(propPath, property.initializer);
1935
+ }
1936
+
1102
1937
  // Process the property value with propPath as targetPath
1103
1938
  // This allows nested object literals to work correctly
1104
1939
  processExpression({
@@ -1398,14 +2233,30 @@ export function processExpression({
1398
2233
  // Extract conditional usages for key attribute detection
1399
2234
  extractConditionalUsage(unwrappedNode.condition, context, 'ternary');
1400
2235
 
2236
+ // Extract conditional effects (setter calls in ternary branches)
2237
+ const knownSetters = findUseStateSetters(context.sourceFile);
2238
+ const effects = extractConditionalEffectsFromTernary(
2239
+ unwrappedNode,
2240
+ context,
2241
+ knownSetters,
2242
+ );
2243
+ for (const effect of effects) {
2244
+ context.addConditionalEffect(effect);
2245
+ }
2246
+
1401
2247
  // Process all parts recursively
1402
2248
  processExpression({
1403
2249
  node: unwrappedNode.condition,
1404
2250
  context,
1405
2251
  typeHint: 'boolean | unknown',
1406
2252
  }); //TODO: could we capture that this is evidence of a boolean type?
1407
- processExpression({ node: unwrappedNode.whenTrue, context });
1408
- processExpression({ node: unwrappedNode.whenFalse, context });
2253
+
2254
+ // Process both branches WITH targetPath to establish equivalencies
2255
+ // This is critical for tracing nested properties through ternary assignments
2256
+ // e.g., const items = condition ? arr1 : arr2; items.map(i => i.prop)
2257
+ // We need items to be equivalent to both arr1 AND arr2 for proper tracing
2258
+ processExpression({ node: unwrappedNode.whenTrue, context, targetPath });
2259
+ processExpression({ node: unwrappedNode.whenFalse, context, targetPath });
1409
2260
 
1410
2261
  // Create a path for the whole expression
1411
2262
  const expressionSourcePath = nodeToSource(
@@ -1428,10 +2279,22 @@ export function processExpression({
1428
2279
  // Register type for the expression
1429
2280
  context.addType(expressionSourcePath, resultType);
1430
2281
 
1431
- // If targetPath is provided, establish equivalence and register type
2282
+ // If targetPath is provided, only register type (don't overwrite branch equivalencies)
2283
+ // The equivalencies to individual branches (set above) are more useful for tracing
2284
+ // than an equivalency to the entire ternary expression text
1432
2285
  if (targetPath) {
1433
- context.addEquivalence(targetPath, expressionSourcePath);
1434
- context.addType(targetPath, resultType);
2286
+ // NOTE: We intentionally do NOT add equivalence here.
2287
+ // The branch processing above already added equivalencies:
2288
+ // targetPath -> whenTrue branch
2289
+ // targetPath -> whenFalse branch
2290
+ // Adding an equivalence to expressionSourcePath would overwrite those
2291
+ // with a useless equivalence to the ternary text itself.
2292
+ //
2293
+ // Use updateSchemaType instead of addType because:
2294
+ // 1. Branch processing may have already set a type on targetPath
2295
+ // 2. addType has a guard that prevents overwriting specific types with 'unknown'
2296
+ // 3. updateSchemaType bypasses this guard, ensuring the ternary's computed type is used
2297
+ context.updateSchemaType(targetPath, resultType);
1435
2298
  }
1436
2299
 
1437
2300
  return true;
@@ -2232,6 +3095,9 @@ function processJsxAttribute(
2232
3095
  if (ts.isJsxExpression(attr.initializer) && attr.initializer.expression) {
2233
3096
  const expression = attr.initializer.expression;
2234
3097
  if (context.isChildBoundary(expression)) {
3098
+ // Create equivalency between attribute path and child scope
3099
+ // e.g., Grid().signature[0].renderRow → cyScope1()
3100
+ context.addChildBoundaryEquivalence(attributePath, expression);
2235
3101
  return true;
2236
3102
  }
2237
3103