@codeyam/codeyam-cli 0.1.0-staging.596f0eb → 0.1.0-staging.62d4615

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 (914) hide show
  1. package/analyzer-template/.build-info.json +8 -8
  2. package/analyzer-template/common/execAsync.ts +1 -1
  3. package/analyzer-template/log.txt +3 -3
  4. package/analyzer-template/package.json +16 -12
  5. package/analyzer-template/packages/ai/index.ts +20 -5
  6. package/analyzer-template/packages/ai/package.json +3 -3
  7. package/analyzer-template/packages/ai/src/lib/__mocks__/completionCall.ts +122 -0
  8. package/analyzer-template/packages/ai/src/lib/analyzeScope.ts +214 -24
  9. package/analyzer-template/packages/ai/src/lib/astScopes/arrayDerivationDetector.ts +199 -0
  10. package/analyzer-template/packages/ai/src/lib/astScopes/astScopeAnalyzer.ts +205 -10
  11. package/analyzer-template/packages/ai/src/lib/astScopes/conditionalEffectsExtractor.ts +644 -0
  12. package/analyzer-template/packages/ai/src/lib/astScopes/methodSemantics.ts +181 -23
  13. package/analyzer-template/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.ts +10 -17
  14. package/analyzer-template/packages/ai/src/lib/astScopes/patterns/ifStatementHandler.ts +18 -0
  15. package/analyzer-template/packages/ai/src/lib/astScopes/patterns/switchStatementHandler.ts +38 -1
  16. package/analyzer-template/packages/ai/src/lib/astScopes/patterns/variableDeclarationHandler.ts +181 -1
  17. package/analyzer-template/packages/ai/src/lib/astScopes/processExpression.ts +1518 -125
  18. package/analyzer-template/packages/ai/src/lib/astScopes/types.ts +318 -5
  19. package/analyzer-template/packages/ai/src/lib/checkAllAttributes.ts +29 -10
  20. package/analyzer-template/packages/ai/src/lib/completionCall.ts +216 -36
  21. package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +2301 -348
  22. package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.ts +7 -2
  23. package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/MuiManager.ts +976 -0
  24. package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.ts +243 -77
  25. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.ts +16 -3
  26. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.ts +6 -4
  27. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.ts +71 -2
  28. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.ts +161 -19
  29. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.ts +70 -0
  30. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.ts +93 -1
  31. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertNullToUndefinedBySchema.ts +98 -0
  32. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.ts +179 -0
  33. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/deduplicateFunctionSchemas.ts +40 -30
  34. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.ts +422 -86
  35. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/fixNullIdsBySchema.ts +129 -0
  36. package/analyzer-template/packages/ai/src/lib/dataStructureChunking.ts +156 -0
  37. package/analyzer-template/packages/ai/src/lib/deepEqual.ts +30 -0
  38. package/analyzer-template/packages/ai/src/lib/e2eDataTracking.ts +334 -0
  39. package/analyzer-template/packages/ai/src/lib/extractCriticalDataKeys.ts +120 -0
  40. package/analyzer-template/packages/ai/src/lib/generateChangesEntityScenarioData.ts +74 -7
  41. package/analyzer-template/packages/ai/src/lib/generateChangesEntityScenarios.ts +89 -112
  42. package/analyzer-template/packages/ai/src/lib/generateEntityDataStructure.ts +63 -2
  43. package/analyzer-template/packages/ai/src/lib/generateEntityScenarioData.ts +1394 -92
  44. package/analyzer-template/packages/ai/src/lib/generateEntityScenarios.ts +216 -109
  45. package/analyzer-template/packages/ai/src/lib/generateExecutionFlows.ts +578 -0
  46. package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromConditionalEffects.ts +528 -0
  47. package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromConditionals.ts +2267 -0
  48. package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromJsxUsages.ts +239 -0
  49. package/analyzer-template/packages/ai/src/lib/getConditionalUsagesFromCode.ts +143 -31
  50. package/analyzer-template/packages/ai/src/lib/guessScenarioDataFromDescription.ts +8 -2
  51. package/analyzer-template/packages/ai/src/lib/isolateScopes.ts +328 -7
  52. package/analyzer-template/packages/ai/src/lib/mergeStatements.ts +111 -87
  53. package/analyzer-template/packages/ai/src/lib/promptGenerators/gatherAttributesMap.ts +17 -7
  54. package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChangesEntityScenarioDataGenerator.ts +1 -1
  55. package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.ts +32 -102
  56. package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChunkPrompt.ts +82 -0
  57. package/analyzer-template/packages/ai/src/lib/promptGenerators/generateCriticalKeysPrompt.ts +103 -0
  58. package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.ts +90 -6
  59. package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.ts +14 -53
  60. package/analyzer-template/packages/ai/src/lib/promptGenerators/generateMissingKeysPrompt.ts +58 -0
  61. package/analyzer-template/packages/ai/src/lib/promptGenerators/guessNewScenarioDataFromDescriptionGenerator.ts +28 -2
  62. package/analyzer-template/packages/ai/src/lib/promptGenerators/simplifyKeysForLLM.ts +391 -0
  63. package/analyzer-template/packages/ai/src/lib/resolvePathToControllable.ts +824 -0
  64. package/analyzer-template/packages/ai/src/lib/splitOutsideParentheses.ts +5 -1
  65. package/analyzer-template/packages/ai/src/lib/validateExecutionFlowPaths.ts +531 -0
  66. package/analyzer-template/packages/ai/src/lib/worker/SerializableDataStructure.ts +127 -3
  67. package/analyzer-template/packages/ai/src/lib/worker/analyzeScopeWorker.ts +121 -2
  68. package/analyzer-template/packages/analyze/index.ts +2 -0
  69. package/analyzer-template/packages/analyze/src/lib/FileAnalyzer.ts +79 -59
  70. package/analyzer-template/packages/analyze/src/lib/ProjectAnalyzer.ts +113 -26
  71. package/analyzer-template/packages/analyze/src/lib/analysisContext.ts +44 -4
  72. package/analyzer-template/packages/analyze/src/lib/asts/nodes/index.ts +1 -0
  73. package/analyzer-template/packages/analyze/src/lib/asts/nodes/isAsyncFunction.ts +67 -0
  74. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllDeclaredEntityNodes.ts +19 -0
  75. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllEntityNodes.ts +19 -0
  76. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllExports.ts +11 -0
  77. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getImportsAnalysis.ts +8 -0
  78. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getResolvedModule.ts +49 -1
  79. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getSourceFilesForAllImports.ts +2 -1
  80. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +522 -272
  81. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +34 -1
  82. package/analyzer-template/packages/analyze/src/lib/files/analyze/dependencyResolver.ts +6 -0
  83. package/analyzer-template/packages/analyze/src/lib/files/analyze/findOrCreateEntity.ts +3 -0
  84. package/analyzer-template/packages/analyze/src/lib/files/analyze/gatherEntityMap.ts +4 -2
  85. package/analyzer-template/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.ts +33 -10
  86. package/analyzer-template/packages/analyze/src/lib/files/analyzeChange.ts +31 -15
  87. package/analyzer-template/packages/analyze/src/lib/files/analyzeEntity.ts +11 -7
  88. package/analyzer-template/packages/analyze/src/lib/files/analyzeInitial.ts +11 -12
  89. package/analyzer-template/packages/analyze/src/lib/files/analyzeRemixRoute.ts +4 -5
  90. package/analyzer-template/packages/analyze/src/lib/files/enums/steps.ts +1 -1
  91. package/analyzer-template/packages/analyze/src/lib/files/getImportedExports.ts +14 -12
  92. package/analyzer-template/packages/analyze/src/lib/files/scenarios/TransformationTracer.ts +1315 -0
  93. package/analyzer-template/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.ts +313 -0
  94. package/analyzer-template/packages/analyze/src/lib/files/scenarios/enrichUnknownTypesFromSourceEquivalencies.ts +102 -0
  95. package/analyzer-template/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.ts +625 -52
  96. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateChangesScenarioData.ts +1 -1
  97. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateChangesScenarios.ts +28 -62
  98. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +550 -137
  99. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.ts +264 -0
  100. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarioData.ts +78 -83
  101. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarios.ts +4 -8
  102. package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +917 -130
  103. package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeValidatedDataStructures.ts +56 -11
  104. package/analyzer-template/packages/analyze/src/lib/files/scenarios/propagateArrayItemSchemas.ts +474 -0
  105. package/analyzer-template/packages/analyze/src/lib/files/setImportedExports.ts +2 -1
  106. package/analyzer-template/packages/analyze/src/lib/index.ts +1 -0
  107. package/analyzer-template/packages/analyze/src/lib/utils/getFileByPath.ts +19 -0
  108. package/analyzer-template/packages/aws/codebuild/index.ts +1 -0
  109. package/analyzer-template/packages/aws/dist/src/lib/codebuild/waitForBuild.d.ts +11 -1
  110. package/analyzer-template/packages/aws/dist/src/lib/codebuild/waitForBuild.d.ts.map +1 -1
  111. package/analyzer-template/packages/aws/dist/src/lib/codebuild/waitForBuild.js +29 -18
  112. package/analyzer-template/packages/aws/dist/src/lib/codebuild/waitForBuild.js.map +1 -1
  113. package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsDefineContainer.d.ts +2 -2
  114. package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsDefineContainer.d.ts.map +1 -1
  115. package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsDefineContainer.js +2 -2
  116. package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsDefineContainer.js.map +1 -1
  117. package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsTaskFactory.d.ts +8 -18
  118. package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsTaskFactory.d.ts.map +1 -1
  119. package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsTaskFactory.js +17 -61
  120. package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsTaskFactory.js.map +1 -1
  121. package/analyzer-template/packages/aws/dist/src/lib/s3/checkS3ObjectExists.d.ts +15 -0
  122. package/analyzer-template/packages/aws/dist/src/lib/s3/checkS3ObjectExists.d.ts.map +1 -0
  123. package/analyzer-template/packages/aws/dist/src/lib/s3/checkS3ObjectExists.js +31 -0
  124. package/analyzer-template/packages/aws/dist/src/lib/s3/checkS3ObjectExists.js.map +1 -0
  125. package/analyzer-template/packages/aws/dist/src/lib/s3/uploadFileToS3.d.ts.map +1 -1
  126. package/analyzer-template/packages/aws/dist/src/lib/s3/uploadFileToS3.js +8 -1
  127. package/analyzer-template/packages/aws/dist/src/lib/s3/uploadFileToS3.js.map +1 -1
  128. package/analyzer-template/packages/aws/package.json +3 -3
  129. package/analyzer-template/packages/aws/s3/index.ts +1 -0
  130. package/analyzer-template/packages/aws/src/lib/codebuild/waitForBuild.ts +43 -19
  131. package/analyzer-template/packages/aws/src/lib/ecs/ecsDefineContainer.ts +3 -3
  132. package/analyzer-template/packages/aws/src/lib/ecs/ecsTaskFactory.ts +17 -69
  133. package/analyzer-template/packages/aws/src/lib/s3/checkS3ObjectExists.ts +47 -0
  134. package/analyzer-template/packages/aws/src/lib/s3/uploadFileToS3.ts +8 -1
  135. package/analyzer-template/packages/database/package.json +1 -1
  136. package/analyzer-template/packages/database/src/lib/kysely/db.ts +12 -5
  137. package/analyzer-template/packages/database/src/lib/kysely/tableRelations.ts +2 -2
  138. package/analyzer-template/packages/database/src/lib/kysely/tables/commitsTable.ts +6 -0
  139. package/analyzer-template/packages/database/src/lib/kysely/tables/debugReportsTable.ts +36 -9
  140. package/analyzer-template/packages/database/src/lib/loadAnalyses.ts +58 -1
  141. package/analyzer-template/packages/database/src/lib/loadAnalysis.ts +13 -0
  142. package/analyzer-template/packages/database/src/lib/loadBranch.ts +16 -1
  143. package/analyzer-template/packages/database/src/lib/loadCommit.ts +11 -0
  144. package/analyzer-template/packages/database/src/lib/loadCommits.ts +28 -0
  145. package/analyzer-template/packages/database/src/lib/loadEntities.ts +26 -3
  146. package/analyzer-template/packages/database/src/lib/loadEntityBranches.ts +12 -0
  147. package/analyzer-template/packages/database/src/lib/loadReadyToBeCapturedAnalyses.ts +7 -3
  148. package/analyzer-template/packages/database/src/lib/updateCommitMetadata.ts +7 -14
  149. package/analyzer-template/packages/generate/index.ts +3 -0
  150. package/analyzer-template/packages/generate/src/lib/componentScenarioPage/componentScenarioPageNext.ts +17 -1
  151. package/analyzer-template/packages/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.ts +193 -0
  152. package/analyzer-template/packages/generate/src/lib/componentScenarioPage/generateScenarioServerComponent.ts +73 -0
  153. package/analyzer-template/packages/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.ts +9 -4
  154. package/analyzer-template/packages/generate/src/lib/deepMerge.ts +26 -1
  155. package/analyzer-template/packages/generate/src/lib/scenarioComponentForServer.ts +114 -0
  156. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts +2 -2
  157. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts.map +1 -1
  158. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js +10 -3
  159. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js.map +1 -1
  160. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tableRelations.d.ts +2 -2
  161. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/analysesTable.d.ts +1 -11
  162. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/analysesTable.d.ts.map +1 -1
  163. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/commitsTable.d.ts +1 -0
  164. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/commitsTable.d.ts.map +1 -1
  165. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/commitsTable.js +3 -0
  166. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/commitsTable.js.map +1 -1
  167. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.d.ts +30 -7
  168. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.d.ts.map +1 -1
  169. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.js +9 -3
  170. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.js.map +1 -1
  171. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/entitiesTable.d.ts +1 -0
  172. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/entitiesTable.d.ts.map +1 -1
  173. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/scenariosTable.d.ts +2 -6
  174. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/scenariosTable.d.ts.map +1 -1
  175. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalyses.d.ts +2 -0
  176. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalyses.d.ts.map +1 -1
  177. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalyses.js +45 -2
  178. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalyses.js.map +1 -1
  179. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.d.ts.map +1 -1
  180. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.js +8 -0
  181. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.js.map +1 -1
  182. package/analyzer-template/packages/github/dist/database/src/lib/loadBranch.js +11 -1
  183. package/analyzer-template/packages/github/dist/database/src/lib/loadBranch.js.map +1 -1
  184. package/analyzer-template/packages/github/dist/database/src/lib/loadCommit.d.ts.map +1 -1
  185. package/analyzer-template/packages/github/dist/database/src/lib/loadCommit.js +7 -0
  186. package/analyzer-template/packages/github/dist/database/src/lib/loadCommit.js.map +1 -1
  187. package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.d.ts +3 -1
  188. package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.d.ts.map +1 -1
  189. package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.js +22 -1
  190. package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.js.map +1 -1
  191. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.d.ts +3 -1
  192. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.d.ts.map +1 -1
  193. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.js +23 -4
  194. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.js.map +1 -1
  195. package/analyzer-template/packages/github/dist/database/src/lib/loadEntityBranches.d.ts.map +1 -1
  196. package/analyzer-template/packages/github/dist/database/src/lib/loadEntityBranches.js +9 -0
  197. package/analyzer-template/packages/github/dist/database/src/lib/loadEntityBranches.js.map +1 -1
  198. package/analyzer-template/packages/github/dist/database/src/lib/loadReadyToBeCapturedAnalyses.d.ts.map +1 -1
  199. package/analyzer-template/packages/github/dist/database/src/lib/loadReadyToBeCapturedAnalyses.js +7 -4
  200. package/analyzer-template/packages/github/dist/database/src/lib/loadReadyToBeCapturedAnalyses.js.map +1 -1
  201. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.d.ts +2 -2
  202. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.d.ts.map +1 -1
  203. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.js +5 -4
  204. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.js.map +1 -1
  205. package/analyzer-template/packages/github/dist/generate/index.d.ts +3 -0
  206. package/analyzer-template/packages/github/dist/generate/index.d.ts.map +1 -1
  207. package/analyzer-template/packages/github/dist/generate/index.js +3 -0
  208. package/analyzer-template/packages/github/dist/generate/index.js.map +1 -1
  209. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageNext.d.ts.map +1 -1
  210. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageNext.js +16 -1
  211. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageNext.js.map +1 -1
  212. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.d.ts +9 -0
  213. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.d.ts.map +1 -0
  214. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.js +189 -0
  215. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.js.map +1 -0
  216. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioServerComponent.d.ts +20 -0
  217. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioServerComponent.d.ts.map +1 -0
  218. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioServerComponent.js +53 -0
  219. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioServerComponent.js.map +1 -0
  220. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.d.ts.map +1 -1
  221. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js +8 -4
  222. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js.map +1 -1
  223. package/analyzer-template/packages/github/dist/generate/src/lib/deepMerge.d.ts.map +1 -1
  224. package/analyzer-template/packages/github/dist/generate/src/lib/deepMerge.js +27 -1
  225. package/analyzer-template/packages/github/dist/generate/src/lib/deepMerge.js.map +1 -1
  226. package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponentForServer.d.ts +8 -0
  227. package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponentForServer.d.ts.map +1 -0
  228. package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponentForServer.js +89 -0
  229. package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponentForServer.js.map +1 -0
  230. package/analyzer-template/packages/github/dist/github/src/lib/loadOrCreateCommit.d.ts.map +1 -1
  231. package/analyzer-template/packages/github/dist/github/src/lib/loadOrCreateCommit.js +10 -0
  232. package/analyzer-template/packages/github/dist/github/src/lib/loadOrCreateCommit.js.map +1 -1
  233. package/analyzer-template/packages/github/dist/github/src/lib/syncPrimaryBranch.d.ts.map +1 -1
  234. package/analyzer-template/packages/github/dist/github/src/lib/syncPrimaryBranch.js +3 -0
  235. package/analyzer-template/packages/github/dist/github/src/lib/syncPrimaryBranch.js.map +1 -1
  236. package/analyzer-template/packages/github/dist/types/index.d.ts +2 -2
  237. package/analyzer-template/packages/github/dist/types/index.d.ts.map +1 -1
  238. package/analyzer-template/packages/github/dist/types/index.js.map +1 -1
  239. package/analyzer-template/packages/github/dist/types/src/types/Analysis.d.ts +87 -13
  240. package/analyzer-template/packages/github/dist/types/src/types/Analysis.d.ts.map +1 -1
  241. package/analyzer-template/packages/github/dist/types/src/types/Commit.d.ts +2 -0
  242. package/analyzer-template/packages/github/dist/types/src/types/Commit.d.ts.map +1 -1
  243. package/analyzer-template/packages/github/dist/types/src/types/Entity.d.ts +2 -0
  244. package/analyzer-template/packages/github/dist/types/src/types/Entity.d.ts.map +1 -1
  245. package/analyzer-template/packages/github/dist/types/src/types/ProjectMetadata.d.ts +3 -0
  246. package/analyzer-template/packages/github/dist/types/src/types/ProjectMetadata.d.ts.map +1 -1
  247. package/analyzer-template/packages/github/dist/types/src/types/Scenario.d.ts +11 -6
  248. package/analyzer-template/packages/github/dist/types/src/types/Scenario.d.ts.map +1 -1
  249. package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts +199 -3
  250. package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
  251. package/analyzer-template/packages/github/dist/types/src/types/ScopeAnalysis.d.ts +6 -1
  252. package/analyzer-template/packages/github/dist/types/src/types/ScopeAnalysis.d.ts.map +1 -1
  253. package/analyzer-template/packages/github/dist/types/src/types/StatementInfo.d.ts +2 -0
  254. package/analyzer-template/packages/github/dist/types/src/types/StatementInfo.d.ts.map +1 -1
  255. package/analyzer-template/packages/github/dist/utils/src/lib/lightweightEntityExtractor.d.ts.map +1 -1
  256. package/analyzer-template/packages/github/dist/utils/src/lib/lightweightEntityExtractor.js +25 -0
  257. package/analyzer-template/packages/github/dist/utils/src/lib/lightweightEntityExtractor.js.map +1 -1
  258. package/analyzer-template/packages/github/dist/utils/src/lib/safeFileName.d.ts +9 -1
  259. package/analyzer-template/packages/github/dist/utils/src/lib/safeFileName.d.ts.map +1 -1
  260. package/analyzer-template/packages/github/dist/utils/src/lib/safeFileName.js +29 -3
  261. package/analyzer-template/packages/github/dist/utils/src/lib/safeFileName.js.map +1 -1
  262. package/analyzer-template/packages/github/package.json +1 -1
  263. package/analyzer-template/packages/github/src/lib/loadOrCreateCommit.ts +14 -0
  264. package/analyzer-template/packages/github/src/lib/syncPrimaryBranch.ts +2 -0
  265. package/analyzer-template/packages/process/index.ts +2 -0
  266. package/analyzer-template/packages/process/package.json +12 -0
  267. package/analyzer-template/packages/process/tsconfig.json +8 -0
  268. package/analyzer-template/packages/types/index.ts +5 -0
  269. package/analyzer-template/packages/types/src/types/Analysis.ts +104 -13
  270. package/analyzer-template/packages/types/src/types/Commit.ts +2 -0
  271. package/analyzer-template/packages/types/src/types/Entity.ts +2 -0
  272. package/analyzer-template/packages/types/src/types/ProjectMetadata.ts +1 -0
  273. package/analyzer-template/packages/types/src/types/Scenario.ts +11 -10
  274. package/analyzer-template/packages/types/src/types/ScenariosDataStructure.ts +228 -3
  275. package/analyzer-template/packages/types/src/types/ScopeAnalysis.ts +6 -1
  276. package/analyzer-template/packages/types/src/types/StatementInfo.ts +2 -0
  277. package/analyzer-template/packages/ui-components/src/components/ScenarioDetailInteractiveView.tsx +23 -7
  278. package/analyzer-template/packages/utils/dist/types/index.d.ts +2 -2
  279. package/analyzer-template/packages/utils/dist/types/index.d.ts.map +1 -1
  280. package/analyzer-template/packages/utils/dist/types/index.js.map +1 -1
  281. package/analyzer-template/packages/utils/dist/types/src/types/Analysis.d.ts +87 -13
  282. package/analyzer-template/packages/utils/dist/types/src/types/Analysis.d.ts.map +1 -1
  283. package/analyzer-template/packages/utils/dist/types/src/types/Commit.d.ts +2 -0
  284. package/analyzer-template/packages/utils/dist/types/src/types/Commit.d.ts.map +1 -1
  285. package/analyzer-template/packages/utils/dist/types/src/types/Entity.d.ts +2 -0
  286. package/analyzer-template/packages/utils/dist/types/src/types/Entity.d.ts.map +1 -1
  287. package/analyzer-template/packages/utils/dist/types/src/types/ProjectMetadata.d.ts +3 -0
  288. package/analyzer-template/packages/utils/dist/types/src/types/ProjectMetadata.d.ts.map +1 -1
  289. package/analyzer-template/packages/utils/dist/types/src/types/Scenario.d.ts +11 -6
  290. package/analyzer-template/packages/utils/dist/types/src/types/Scenario.d.ts.map +1 -1
  291. package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts +199 -3
  292. package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
  293. package/analyzer-template/packages/utils/dist/types/src/types/ScopeAnalysis.d.ts +6 -1
  294. package/analyzer-template/packages/utils/dist/types/src/types/ScopeAnalysis.d.ts.map +1 -1
  295. package/analyzer-template/packages/utils/dist/types/src/types/StatementInfo.d.ts +2 -0
  296. package/analyzer-template/packages/utils/dist/types/src/types/StatementInfo.d.ts.map +1 -1
  297. package/analyzer-template/packages/utils/dist/utils/src/lib/lightweightEntityExtractor.d.ts.map +1 -1
  298. package/analyzer-template/packages/utils/dist/utils/src/lib/lightweightEntityExtractor.js +25 -0
  299. package/analyzer-template/packages/utils/dist/utils/src/lib/lightweightEntityExtractor.js.map +1 -1
  300. package/analyzer-template/packages/utils/dist/utils/src/lib/safeFileName.d.ts +9 -1
  301. package/analyzer-template/packages/utils/dist/utils/src/lib/safeFileName.d.ts.map +1 -1
  302. package/analyzer-template/packages/utils/dist/utils/src/lib/safeFileName.js +29 -3
  303. package/analyzer-template/packages/utils/dist/utils/src/lib/safeFileName.js.map +1 -1
  304. package/analyzer-template/packages/utils/src/lib/lightweightEntityExtractor.ts +27 -0
  305. package/analyzer-template/packages/utils/src/lib/safeFileName.ts +48 -3
  306. package/analyzer-template/playwright/capture.ts +57 -26
  307. package/analyzer-template/playwright/captureStatic.ts +1 -1
  308. package/analyzer-template/playwright/getCodeYamInfo.ts +12 -7
  309. package/analyzer-template/playwright/takeElementScreenshot.ts +26 -11
  310. package/analyzer-template/playwright/takeScreenshot.ts +9 -7
  311. package/analyzer-template/playwright/waitForServer.ts +21 -6
  312. package/analyzer-template/project/analyzeBaselineCommit.ts +9 -0
  313. package/analyzer-template/project/analyzeBranchCommit.ts +4 -0
  314. package/analyzer-template/project/analyzeFileEntities.ts +4 -0
  315. package/analyzer-template/project/analyzeRegularCommit.ts +9 -0
  316. package/analyzer-template/project/captureLibraryFunctionDirect.ts +29 -26
  317. package/analyzer-template/project/constructMockCode.ts +1268 -167
  318. package/analyzer-template/project/controller/startController.ts +16 -1
  319. package/analyzer-template/project/createEntitiesAndSortFiles.ts +83 -0
  320. package/analyzer-template/project/executeLibraryFunctionDirect.ts +7 -3
  321. package/analyzer-template/project/loadReadyToBeCaptured.ts +65 -41
  322. package/analyzer-template/project/mocks/analyzeFileMock.ts +8 -7
  323. package/analyzer-template/project/orchestrateCapture/AwsCaptureTaskRunner.ts +12 -4
  324. package/analyzer-template/project/orchestrateCapture/KyselyAnalysisLoader.ts +3 -6
  325. package/analyzer-template/project/orchestrateCapture/SequentialCaptureTaskRunner.ts +93 -42
  326. package/analyzer-template/project/orchestrateCapture/taskRunner.ts +4 -2
  327. package/analyzer-template/project/orchestrateCapture.ts +81 -9
  328. package/analyzer-template/project/reconcileMockDataKeys.ts +245 -2
  329. package/analyzer-template/project/runAnalysis.ts +11 -0
  330. package/analyzer-template/project/runMultiScenarioServer.ts +11 -10
  331. package/analyzer-template/project/serverOnlyModules.ts +194 -21
  332. package/analyzer-template/project/start.ts +61 -15
  333. package/analyzer-template/project/startScenarioCapture.ts +79 -41
  334. package/analyzer-template/project/writeMockDataTsx.ts +405 -65
  335. package/analyzer-template/project/writeScenarioClientWrapper.ts +21 -0
  336. package/analyzer-template/project/writeScenarioComponents.ts +862 -183
  337. package/analyzer-template/project/writeScenarioFiles.ts +26 -0
  338. package/analyzer-template/project/writeSimpleRoot.ts +31 -23
  339. package/analyzer-template/scripts/comboWorkerLoop.cjs +99 -50
  340. package/analyzer-template/scripts/defaultCmd.sh +9 -0
  341. package/analyzer-template/tsconfig.json +2 -1
  342. package/background/src/lib/local/createLocalAnalyzer.js +1 -29
  343. package/background/src/lib/local/createLocalAnalyzer.js.map +1 -1
  344. package/background/src/lib/local/execAsync.js +1 -1
  345. package/background/src/lib/local/execAsync.js.map +1 -1
  346. package/background/src/lib/virtualized/common/execAsync.js +1 -1
  347. package/background/src/lib/virtualized/common/execAsync.js.map +1 -1
  348. package/background/src/lib/virtualized/project/analyzeBaselineCommit.js +7 -1
  349. package/background/src/lib/virtualized/project/analyzeBaselineCommit.js.map +1 -1
  350. package/background/src/lib/virtualized/project/analyzeBranchCommit.js +2 -1
  351. package/background/src/lib/virtualized/project/analyzeBranchCommit.js.map +1 -1
  352. package/background/src/lib/virtualized/project/analyzeFileEntities.js +2 -1
  353. package/background/src/lib/virtualized/project/analyzeFileEntities.js.map +1 -1
  354. package/background/src/lib/virtualized/project/analyzeRegularCommit.js +7 -1
  355. package/background/src/lib/virtualized/project/analyzeRegularCommit.js.map +1 -1
  356. package/background/src/lib/virtualized/project/captureLibraryFunctionDirect.js +3 -3
  357. package/background/src/lib/virtualized/project/captureLibraryFunctionDirect.js.map +1 -1
  358. package/background/src/lib/virtualized/project/constructMockCode.js +1126 -126
  359. package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
  360. package/background/src/lib/virtualized/project/controller/startController.js +11 -1
  361. package/background/src/lib/virtualized/project/controller/startController.js.map +1 -1
  362. package/background/src/lib/virtualized/project/createEntitiesAndSortFiles.js +73 -1
  363. package/background/src/lib/virtualized/project/createEntitiesAndSortFiles.js.map +1 -1
  364. package/background/src/lib/virtualized/project/executeLibraryFunctionDirect.js +6 -3
  365. package/background/src/lib/virtualized/project/executeLibraryFunctionDirect.js.map +1 -1
  366. package/background/src/lib/virtualized/project/loadReadyToBeCaptured.js +19 -8
  367. package/background/src/lib/virtualized/project/loadReadyToBeCaptured.js.map +1 -1
  368. package/background/src/lib/virtualized/project/mocks/analyzeFileMock.js +7 -7
  369. package/background/src/lib/virtualized/project/mocks/analyzeFileMock.js.map +1 -1
  370. package/background/src/lib/virtualized/project/orchestrateCapture/AwsCaptureTaskRunner.js +2 -2
  371. package/background/src/lib/virtualized/project/orchestrateCapture/AwsCaptureTaskRunner.js.map +1 -1
  372. package/background/src/lib/virtualized/project/orchestrateCapture/KyselyAnalysisLoader.js +3 -2
  373. package/background/src/lib/virtualized/project/orchestrateCapture/KyselyAnalysisLoader.js.map +1 -1
  374. package/background/src/lib/virtualized/project/orchestrateCapture/SequentialCaptureTaskRunner.js +73 -36
  375. package/background/src/lib/virtualized/project/orchestrateCapture/SequentialCaptureTaskRunner.js.map +1 -1
  376. package/background/src/lib/virtualized/project/orchestrateCapture.js +65 -10
  377. package/background/src/lib/virtualized/project/orchestrateCapture.js.map +1 -1
  378. package/background/src/lib/virtualized/project/reconcileMockDataKeys.js +204 -2
  379. package/background/src/lib/virtualized/project/reconcileMockDataKeys.js.map +1 -1
  380. package/background/src/lib/virtualized/project/runAnalysis.js +9 -0
  381. package/background/src/lib/virtualized/project/runAnalysis.js.map +1 -1
  382. package/background/src/lib/virtualized/project/runMultiScenarioServer.js +11 -9
  383. package/background/src/lib/virtualized/project/runMultiScenarioServer.js.map +1 -1
  384. package/background/src/lib/virtualized/project/serverOnlyModules.js +163 -23
  385. package/background/src/lib/virtualized/project/serverOnlyModules.js.map +1 -1
  386. package/background/src/lib/virtualized/project/start.js +53 -15
  387. package/background/src/lib/virtualized/project/start.js.map +1 -1
  388. package/background/src/lib/virtualized/project/startScenarioCapture.js +61 -31
  389. package/background/src/lib/virtualized/project/startScenarioCapture.js.map +1 -1
  390. package/background/src/lib/virtualized/project/writeMockDataTsx.js +354 -54
  391. package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
  392. package/background/src/lib/virtualized/project/writeScenarioClientWrapper.js +15 -0
  393. package/background/src/lib/virtualized/project/writeScenarioClientWrapper.js.map +1 -0
  394. package/background/src/lib/virtualized/project/writeScenarioComponents.js +624 -127
  395. package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
  396. package/background/src/lib/virtualized/project/writeScenarioFiles.js +19 -0
  397. package/background/src/lib/virtualized/project/writeScenarioFiles.js.map +1 -1
  398. package/background/src/lib/virtualized/project/writeSimpleRoot.js +31 -21
  399. package/background/src/lib/virtualized/project/writeSimpleRoot.js.map +1 -1
  400. package/codeyam-cli/scripts/apply-setup.js +180 -0
  401. package/codeyam-cli/scripts/apply-setup.js.map +1 -1
  402. package/codeyam-cli/src/cli.js +9 -1
  403. package/codeyam-cli/src/cli.js.map +1 -1
  404. package/codeyam-cli/src/commands/analyze.js +1 -1
  405. package/codeyam-cli/src/commands/analyze.js.map +1 -1
  406. package/codeyam-cli/src/commands/baseline.js +174 -0
  407. package/codeyam-cli/src/commands/baseline.js.map +1 -0
  408. package/codeyam-cli/src/commands/debug.js +42 -18
  409. package/codeyam-cli/src/commands/debug.js.map +1 -1
  410. package/codeyam-cli/src/commands/default.js +0 -15
  411. package/codeyam-cli/src/commands/default.js.map +1 -1
  412. package/codeyam-cli/src/commands/memory.js +264 -0
  413. package/codeyam-cli/src/commands/memory.js.map +1 -0
  414. package/codeyam-cli/src/commands/recapture.js +226 -0
  415. package/codeyam-cli/src/commands/recapture.js.map +1 -0
  416. package/codeyam-cli/src/commands/report.js +72 -24
  417. package/codeyam-cli/src/commands/report.js.map +1 -1
  418. package/codeyam-cli/src/commands/start.js +8 -12
  419. package/codeyam-cli/src/commands/start.js.map +1 -1
  420. package/codeyam-cli/src/commands/status.js +23 -1
  421. package/codeyam-cli/src/commands/status.js.map +1 -1
  422. package/codeyam-cli/src/commands/test-startup.js +1 -1
  423. package/codeyam-cli/src/commands/test-startup.js.map +1 -1
  424. package/codeyam-cli/src/commands/wipe.js +108 -0
  425. package/codeyam-cli/src/commands/wipe.js.map +1 -0
  426. package/codeyam-cli/src/utils/__tests__/serverVersionStaleness.test.js +81 -0
  427. package/codeyam-cli/src/utils/__tests__/serverVersionStaleness.test.js.map +1 -0
  428. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js +31 -27
  429. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js.map +1 -1
  430. package/codeyam-cli/src/utils/analysisRunner.js +29 -15
  431. package/codeyam-cli/src/utils/analysisRunner.js.map +1 -1
  432. package/codeyam-cli/src/utils/backgroundServer.js +18 -4
  433. package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
  434. package/codeyam-cli/src/utils/database.js +91 -5
  435. package/codeyam-cli/src/utils/database.js.map +1 -1
  436. package/codeyam-cli/src/utils/generateReport.js +253 -106
  437. package/codeyam-cli/src/utils/generateReport.js.map +1 -1
  438. package/codeyam-cli/src/utils/git.js +79 -0
  439. package/codeyam-cli/src/utils/git.js.map +1 -0
  440. package/codeyam-cli/src/utils/install-skills.js +76 -17
  441. package/codeyam-cli/src/utils/install-skills.js.map +1 -1
  442. package/codeyam-cli/src/utils/queue/__tests__/manager.test.js +38 -0
  443. package/codeyam-cli/src/utils/queue/__tests__/manager.test.js.map +1 -1
  444. package/codeyam-cli/src/utils/queue/job.js +249 -16
  445. package/codeyam-cli/src/utils/queue/job.js.map +1 -1
  446. package/codeyam-cli/src/utils/queue/manager.js +25 -7
  447. package/codeyam-cli/src/utils/queue/manager.js.map +1 -1
  448. package/codeyam-cli/src/utils/queue/persistence.js.map +1 -1
  449. package/codeyam-cli/src/utils/ruleReflection/__tests__/confusionDetector.test.js +82 -0
  450. package/codeyam-cli/src/utils/ruleReflection/__tests__/confusionDetector.test.js.map +1 -0
  451. package/codeyam-cli/src/utils/ruleReflection/__tests__/contextBuilder.test.js +128 -0
  452. package/codeyam-cli/src/utils/ruleReflection/__tests__/contextBuilder.test.js.map +1 -0
  453. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/assertRules.js +67 -0
  454. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/assertRules.js.map +1 -0
  455. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/captureFixture.js +105 -0
  456. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/captureFixture.js.map +1 -0
  457. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/loadCapturedFixture.js +34 -0
  458. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/loadCapturedFixture.js.map +1 -0
  459. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/runClaude.js +162 -0
  460. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/runClaude.js.map +1 -0
  461. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js +75 -0
  462. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js.map +1 -0
  463. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js +285 -0
  464. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js.map +1 -0
  465. package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js +83 -0
  466. package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js.map +1 -0
  467. package/codeyam-cli/src/utils/ruleReflection/__tests__/transcriptParser.test.js +127 -0
  468. package/codeyam-cli/src/utils/ruleReflection/__tests__/transcriptParser.test.js.map +1 -0
  469. package/codeyam-cli/src/utils/ruleReflection/confusionDetector.js +50 -0
  470. package/codeyam-cli/src/utils/ruleReflection/confusionDetector.js.map +1 -0
  471. package/codeyam-cli/src/utils/ruleReflection/contextBuilder.js +96 -0
  472. package/codeyam-cli/src/utils/ruleReflection/contextBuilder.js.map +1 -0
  473. package/codeyam-cli/src/utils/ruleReflection/index.js +5 -0
  474. package/codeyam-cli/src/utils/ruleReflection/index.js.map +1 -0
  475. package/codeyam-cli/src/utils/ruleReflection/promptBuilder.js +33 -0
  476. package/codeyam-cli/src/utils/ruleReflection/promptBuilder.js.map +1 -0
  477. package/codeyam-cli/src/utils/ruleReflection/transcriptParser.js +85 -0
  478. package/codeyam-cli/src/utils/ruleReflection/transcriptParser.js.map +1 -0
  479. package/codeyam-cli/src/utils/ruleReflection/types.js +5 -0
  480. package/codeyam-cli/src/utils/ruleReflection/types.js.map +1 -0
  481. package/codeyam-cli/src/utils/rules/__tests__/ruleState.test.js +293 -0
  482. package/codeyam-cli/src/utils/rules/__tests__/ruleState.test.js.map +1 -0
  483. package/codeyam-cli/src/utils/rules/index.js +6 -0
  484. package/codeyam-cli/src/utils/rules/index.js.map +1 -0
  485. package/codeyam-cli/src/utils/rules/parser.js +78 -0
  486. package/codeyam-cli/src/utils/rules/parser.js.map +1 -0
  487. package/codeyam-cli/src/utils/rules/pathMatcher.js +18 -0
  488. package/codeyam-cli/src/utils/rules/pathMatcher.js.map +1 -0
  489. package/codeyam-cli/src/utils/rules/ruleState.js +150 -0
  490. package/codeyam-cli/src/utils/rules/ruleState.js.map +1 -0
  491. package/codeyam-cli/src/utils/rules/staleness.js +137 -0
  492. package/codeyam-cli/src/utils/rules/staleness.js.map +1 -0
  493. package/codeyam-cli/src/utils/serverState.js.map +1 -1
  494. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +7 -5
  495. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js.map +1 -1
  496. package/codeyam-cli/src/utils/versionInfo.js +25 -19
  497. package/codeyam-cli/src/utils/versionInfo.js.map +1 -1
  498. package/codeyam-cli/src/utils/wipe.js +128 -0
  499. package/codeyam-cli/src/utils/wipe.js.map +1 -0
  500. package/codeyam-cli/src/webserver/app/lib/database.js +104 -3
  501. package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
  502. package/codeyam-cli/src/webserver/app/lib/dbNotifier.js.map +1 -1
  503. package/codeyam-cli/src/webserver/backgroundServer.js +5 -10
  504. package/codeyam-cli/src/webserver/backgroundServer.js.map +1 -1
  505. package/codeyam-cli/src/webserver/bootstrap.js +49 -0
  506. package/codeyam-cli/src/webserver/bootstrap.js.map +1 -0
  507. package/codeyam-cli/src/webserver/build/client/assets/CopyButton-CA3JxPb7.js +1 -0
  508. package/codeyam-cli/src/webserver/build/client/assets/EntityItem-B86KKU7e.js +11 -0
  509. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeBadge-efWKDYMr.js → EntityTypeBadge-B5ctlSYt.js} +1 -1
  510. package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-BqY8gDAW.js +41 -0
  511. package/codeyam-cli/src/webserver/build/client/assets/InlineSpinner-ClaLpuOo.js +34 -0
  512. package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-BDhPilK7.js +25 -0
  513. package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-VeqEBv9v.js +3 -0
  514. package/codeyam-cli/src/webserver/build/client/assets/LoadingDots-Bs7Nn1Jr.js +6 -0
  515. package/codeyam-cli/src/webserver/build/client/assets/LogViewer-Bm3PmcCz.js +3 -0
  516. package/codeyam-cli/src/webserver/build/client/assets/ReportIssueModal-C6PKeMYR.js +11 -0
  517. package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-Gq3Ocjo6.js +1 -0
  518. package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-BNLaXBHR.js +10 -0
  519. package/codeyam-cli/src/webserver/build/client/assets/{TruncatedFilePath-COPstp9J.js → TruncatedFilePath-CiwXDxLh.js} +1 -1
  520. package/codeyam-cli/src/webserver/build/client/assets/_index-B3TDXxnk.js +11 -0
  521. package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-DD1r_QU0.js +27 -0
  522. package/codeyam-cli/src/webserver/build/client/assets/agent-transcripts-DfKzxuoe.js +11 -0
  523. package/codeyam-cli/src/webserver/build/client/assets/api.agent-transcripts-l0sNRNKZ.js +1 -0
  524. package/codeyam-cli/src/webserver/build/client/assets/api.health-l0sNRNKZ.js +1 -0
  525. package/codeyam-cli/src/webserver/build/client/assets/api.memory-profile-l0sNRNKZ.js +1 -0
  526. package/codeyam-cli/src/webserver/build/client/assets/api.restart-server-l0sNRNKZ.js +1 -0
  527. package/codeyam-cli/src/webserver/build/client/assets/api.save-fixture-l0sNRNKZ.js +1 -0
  528. package/codeyam-cli/src/webserver/build/client/assets/book-open-PttOB2SF.js +6 -0
  529. package/codeyam-cli/src/webserver/build/client/assets/chevron-down-TJp6ofnp.js +6 -0
  530. package/codeyam-cli/src/webserver/build/client/assets/chunk-JZWAC4HX-JE9ZIoBl.js +51 -0
  531. package/codeyam-cli/src/webserver/build/client/assets/circle-check-CXhHQYrI.js +6 -0
  532. package/codeyam-cli/src/webserver/build/client/assets/copy-6y9ALfGT.js +11 -0
  533. package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-Ca9fAY46.js +21 -0
  534. package/codeyam-cli/src/webserver/build/client/assets/{cy-logo-cli-C1gnJVOL.svg → cy-logo-cli-CCKUIm0S.svg} +2 -2
  535. package/codeyam-cli/src/webserver/build/client/assets/cy-logo-cli-DcX-ZS3p.js +1 -0
  536. package/codeyam-cli/src/webserver/build/client/assets/dev.empty-C5lqplTC.js +1 -0
  537. package/codeyam-cli/src/webserver/build/client/assets/entity._sha._-n38keI1k.js +23 -0
  538. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.fullscreen-CBoafmVs.js +6 -0
  539. package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-DGgZjdFg.js +6 -0
  540. package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-38yPijoD.js +5 -0
  541. package/codeyam-cli/src/webserver/build/client/assets/entry.client-BSHEfydn.js +29 -0
  542. package/codeyam-cli/src/webserver/build/client/assets/executionFlowCoverage-BWhdfn70.js +1 -0
  543. package/codeyam-cli/src/webserver/build/client/assets/fileTableUtils-DCPhhSMo.js +1 -0
  544. package/codeyam-cli/src/webserver/build/client/assets/files-Dk8wkAS7.js +1 -0
  545. package/codeyam-cli/src/webserver/build/client/assets/git-DXnyr8uP.js +15 -0
  546. package/codeyam-cli/src/webserver/build/client/assets/globals-Bh6jH0cL.css +1 -0
  547. package/codeyam-cli/src/webserver/build/client/assets/html2canvas-pro.esm-fmIEn3Bc.js +9 -0
  548. package/codeyam-cli/src/webserver/build/client/assets/index-CcsFv748.js +3 -0
  549. package/codeyam-cli/src/webserver/build/client/assets/index-ChN9-fAY.js +9 -0
  550. package/codeyam-cli/src/webserver/build/client/assets/labs-BUvfJMNR.js +1 -0
  551. package/codeyam-cli/src/webserver/build/client/assets/loader-circle-CTqLEAGU.js +6 -0
  552. package/codeyam-cli/src/webserver/build/client/assets/manifest-d4e77269.js +1 -0
  553. package/codeyam-cli/src/webserver/build/client/assets/memory-DCHBwHou.js +76 -0
  554. package/codeyam-cli/src/webserver/build/client/assets/pause-D6vreykR.js +11 -0
  555. package/codeyam-cli/src/webserver/build/client/assets/preload-helper-ckwbz45p.js +1 -0
  556. package/codeyam-cli/src/webserver/build/client/assets/root-D6oziHts.js +62 -0
  557. package/codeyam-cli/src/webserver/build/client/assets/scenarioStatus-B_8jpV3e.js +1 -0
  558. package/codeyam-cli/src/webserver/build/client/assets/search-B8VUL8nl.js +6 -0
  559. package/codeyam-cli/src/webserver/build/client/assets/settings-B2X7lJgQ.js +1 -0
  560. package/codeyam-cli/src/webserver/build/client/assets/simulations-CPoAg7Zo.js +1 -0
  561. package/codeyam-cli/src/webserver/build/client/assets/terminal-BrCP7uQo.js +11 -0
  562. package/codeyam-cli/src/webserver/build/client/assets/triangle-alert-BZz2NjYa.js +6 -0
  563. package/codeyam-cli/src/webserver/build/client/assets/useCustomSizes-DNwUduNu.js +1 -0
  564. package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-3pmpUQB-.js → useLastLogLine-COky1GVF.js} +1 -1
  565. package/codeyam-cli/src/webserver/build/client/assets/useReportContext-CpZgwliL.js +1 -0
  566. package/codeyam-cli/src/webserver/build/client/assets/{useToast-DEyawJ8r.js → useToast-Bv9JFvUO.js} +1 -1
  567. package/codeyam-cli/src/webserver/build/server/assets/index-C0KrUQp-.js +1 -0
  568. package/codeyam-cli/src/webserver/build/server/assets/server-build-C2h1v1XD.js +260 -0
  569. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  570. package/codeyam-cli/src/webserver/build-info.json +5 -5
  571. package/codeyam-cli/src/webserver/devServer.js +1 -3
  572. package/codeyam-cli/src/webserver/devServer.js.map +1 -1
  573. package/codeyam-cli/src/webserver/server.js +35 -25
  574. package/codeyam-cli/src/webserver/server.js.map +1 -1
  575. package/codeyam-cli/templates/codeyam-memory-hook.sh +199 -0
  576. package/codeyam-cli/templates/{codeyam-debug-skill.md → codeyam:debug.md} +48 -4
  577. package/codeyam-cli/templates/codeyam:diagnose.md +803 -0
  578. package/codeyam-cli/templates/codeyam:memory.md +404 -0
  579. package/codeyam-cli/templates/codeyam:new-rule.md +13 -0
  580. package/codeyam-cli/templates/{codeyam-setup-skill.md → codeyam:setup.md} +139 -4
  581. package/codeyam-cli/templates/{codeyam-sim-skill.md → codeyam:sim.md} +1 -1
  582. package/codeyam-cli/templates/{codeyam-test-skill.md → codeyam:test.md} +1 -1
  583. package/codeyam-cli/templates/{codeyam-verify-skill.md → codeyam:verify.md} +1 -1
  584. package/codeyam-cli/templates/rule-notification-hook.py +54 -0
  585. package/codeyam-cli/templates/rule-reflection-hook.py +428 -0
  586. package/codeyam-cli/templates/rules-instructions.md +123 -0
  587. package/package.json +22 -19
  588. package/packages/ai/index.js +8 -6
  589. package/packages/ai/index.js.map +1 -1
  590. package/packages/ai/src/lib/analyzeScope.js +167 -13
  591. package/packages/ai/src/lib/analyzeScope.js.map +1 -1
  592. package/packages/ai/src/lib/astScopes/arrayDerivationDetector.js +150 -0
  593. package/packages/ai/src/lib/astScopes/arrayDerivationDetector.js.map +1 -0
  594. package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js +154 -9
  595. package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js.map +1 -1
  596. package/packages/ai/src/lib/astScopes/conditionalEffectsExtractor.js +435 -0
  597. package/packages/ai/src/lib/astScopes/conditionalEffectsExtractor.js.map +1 -0
  598. package/packages/ai/src/lib/astScopes/methodSemantics.js +138 -23
  599. package/packages/ai/src/lib/astScopes/methodSemantics.js.map +1 -1
  600. package/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.js +10 -14
  601. package/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.js.map +1 -1
  602. package/packages/ai/src/lib/astScopes/patterns/ifStatementHandler.js +8 -0
  603. package/packages/ai/src/lib/astScopes/patterns/ifStatementHandler.js.map +1 -1
  604. package/packages/ai/src/lib/astScopes/patterns/switchStatementHandler.js +23 -0
  605. package/packages/ai/src/lib/astScopes/patterns/switchStatementHandler.js.map +1 -1
  606. package/packages/ai/src/lib/astScopes/patterns/variableDeclarationHandler.js +138 -1
  607. package/packages/ai/src/lib/astScopes/patterns/variableDeclarationHandler.js.map +1 -1
  608. package/packages/ai/src/lib/astScopes/processExpression.js +1157 -103
  609. package/packages/ai/src/lib/astScopes/processExpression.js.map +1 -1
  610. package/packages/ai/src/lib/checkAllAttributes.js +24 -9
  611. package/packages/ai/src/lib/checkAllAttributes.js.map +1 -1
  612. package/packages/ai/src/lib/completionCall.js +178 -31
  613. package/packages/ai/src/lib/completionCall.js.map +1 -1
  614. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +1816 -216
  615. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
  616. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js +7 -2
  617. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js.map +1 -1
  618. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/MuiManager.js +661 -0
  619. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/MuiManager.js.map +1 -0
  620. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.js +180 -56
  621. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.js.map +1 -1
  622. package/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.js +13 -3
  623. package/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.js.map +1 -1
  624. package/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.js +6 -4
  625. package/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.js.map +1 -1
  626. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js +66 -2
  627. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js.map +1 -1
  628. package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js +139 -13
  629. package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js.map +1 -1
  630. package/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.js +63 -0
  631. package/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.js.map +1 -0
  632. package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js +83 -1
  633. package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js.map +1 -1
  634. package/packages/ai/src/lib/dataStructure/helpers/convertNullToUndefinedBySchema.js +86 -0
  635. package/packages/ai/src/lib/dataStructure/helpers/convertNullToUndefinedBySchema.js.map +1 -0
  636. package/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.js +173 -0
  637. package/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.js.map +1 -0
  638. package/packages/ai/src/lib/dataStructure/helpers/deduplicateFunctionSchemas.js +37 -20
  639. package/packages/ai/src/lib/dataStructure/helpers/deduplicateFunctionSchemas.js.map +1 -1
  640. package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js +355 -77
  641. package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js.map +1 -1
  642. package/packages/ai/src/lib/dataStructure/helpers/fixNullIdsBySchema.js +107 -0
  643. package/packages/ai/src/lib/dataStructure/helpers/fixNullIdsBySchema.js.map +1 -0
  644. package/packages/ai/src/lib/dataStructureChunking.js +111 -0
  645. package/packages/ai/src/lib/dataStructureChunking.js.map +1 -0
  646. package/packages/ai/src/lib/deepEqual.js +32 -0
  647. package/packages/ai/src/lib/deepEqual.js.map +1 -0
  648. package/packages/ai/src/lib/e2eDataTracking.js +241 -0
  649. package/packages/ai/src/lib/e2eDataTracking.js.map +1 -0
  650. package/packages/ai/src/lib/extractCriticalDataKeys.js +96 -0
  651. package/packages/ai/src/lib/extractCriticalDataKeys.js.map +1 -0
  652. package/packages/ai/src/lib/generateChangesEntityScenarioData.js +62 -5
  653. package/packages/ai/src/lib/generateChangesEntityScenarioData.js.map +1 -1
  654. package/packages/ai/src/lib/generateChangesEntityScenarios.js +81 -90
  655. package/packages/ai/src/lib/generateChangesEntityScenarios.js.map +1 -1
  656. package/packages/ai/src/lib/generateEntityDataStructure.js +50 -1
  657. package/packages/ai/src/lib/generateEntityDataStructure.js.map +1 -1
  658. package/packages/ai/src/lib/generateEntityScenarioData.js +1109 -85
  659. package/packages/ai/src/lib/generateEntityScenarioData.js.map +1 -1
  660. package/packages/ai/src/lib/generateEntityScenarios.js +193 -83
  661. package/packages/ai/src/lib/generateEntityScenarios.js.map +1 -1
  662. package/packages/ai/src/lib/generateExecutionFlows.js +400 -0
  663. package/packages/ai/src/lib/generateExecutionFlows.js.map +1 -0
  664. package/packages/ai/src/lib/generateExecutionFlowsFromConditionalEffects.js +380 -0
  665. package/packages/ai/src/lib/generateExecutionFlowsFromConditionalEffects.js.map +1 -0
  666. package/packages/ai/src/lib/generateExecutionFlowsFromConditionals.js +1646 -0
  667. package/packages/ai/src/lib/generateExecutionFlowsFromConditionals.js.map +1 -0
  668. package/packages/ai/src/lib/generateExecutionFlowsFromJsxUsages.js +194 -0
  669. package/packages/ai/src/lib/generateExecutionFlowsFromJsxUsages.js.map +1 -0
  670. package/packages/ai/src/lib/getConditionalUsagesFromCode.js +84 -14
  671. package/packages/ai/src/lib/getConditionalUsagesFromCode.js.map +1 -1
  672. package/packages/ai/src/lib/guessScenarioDataFromDescription.js +2 -1
  673. package/packages/ai/src/lib/guessScenarioDataFromDescription.js.map +1 -1
  674. package/packages/ai/src/lib/isolateScopes.js +270 -7
  675. package/packages/ai/src/lib/isolateScopes.js.map +1 -1
  676. package/packages/ai/src/lib/mergeStatements.js +88 -46
  677. package/packages/ai/src/lib/mergeStatements.js.map +1 -1
  678. package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js +16 -4
  679. package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js.map +1 -1
  680. package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenarioDataGenerator.js +1 -1
  681. package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenarioDataGenerator.js.map +1 -1
  682. package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.js +21 -64
  683. package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.js.map +1 -1
  684. package/packages/ai/src/lib/promptGenerators/generateChunkPrompt.js +54 -0
  685. package/packages/ai/src/lib/promptGenerators/generateChunkPrompt.js.map +1 -0
  686. package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js +68 -6
  687. package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js.map +1 -1
  688. package/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.js +10 -34
  689. package/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.js.map +1 -1
  690. package/packages/ai/src/lib/promptGenerators/generateMissingKeysPrompt.js +45 -0
  691. package/packages/ai/src/lib/promptGenerators/generateMissingKeysPrompt.js.map +1 -0
  692. package/packages/ai/src/lib/promptGenerators/guessNewScenarioDataFromDescriptionGenerator.js +16 -3
  693. package/packages/ai/src/lib/promptGenerators/guessNewScenarioDataFromDescriptionGenerator.js.map +1 -1
  694. package/packages/ai/src/lib/promptGenerators/simplifyKeysForLLM.js +335 -0
  695. package/packages/ai/src/lib/promptGenerators/simplifyKeysForLLM.js.map +1 -0
  696. package/packages/ai/src/lib/resolvePathToControllable.js +677 -0
  697. package/packages/ai/src/lib/resolvePathToControllable.js.map +1 -0
  698. package/packages/ai/src/lib/splitOutsideParentheses.js +3 -1
  699. package/packages/ai/src/lib/splitOutsideParentheses.js.map +1 -1
  700. package/packages/ai/src/lib/worker/SerializableDataStructure.js +29 -0
  701. package/packages/ai/src/lib/worker/SerializableDataStructure.js.map +1 -1
  702. package/packages/ai/src/lib/worker/analyzeScopeWorker.js +98 -1
  703. package/packages/ai/src/lib/worker/analyzeScopeWorker.js.map +1 -1
  704. package/packages/analyze/index.js +1 -0
  705. package/packages/analyze/index.js.map +1 -1
  706. package/packages/analyze/src/lib/FileAnalyzer.js +75 -36
  707. package/packages/analyze/src/lib/FileAnalyzer.js.map +1 -1
  708. package/packages/analyze/src/lib/ProjectAnalyzer.js +96 -26
  709. package/packages/analyze/src/lib/ProjectAnalyzer.js.map +1 -1
  710. package/packages/analyze/src/lib/analysisContext.js +30 -5
  711. package/packages/analyze/src/lib/analysisContext.js.map +1 -1
  712. package/packages/analyze/src/lib/asts/nodes/index.js +1 -0
  713. package/packages/analyze/src/lib/asts/nodes/index.js.map +1 -1
  714. package/packages/analyze/src/lib/asts/nodes/isAsyncFunction.js +52 -0
  715. package/packages/analyze/src/lib/asts/nodes/isAsyncFunction.js.map +1 -0
  716. package/packages/analyze/src/lib/asts/sourceFiles/getAllDeclaredEntityNodes.js +14 -0
  717. package/packages/analyze/src/lib/asts/sourceFiles/getAllDeclaredEntityNodes.js.map +1 -1
  718. package/packages/analyze/src/lib/asts/sourceFiles/getAllEntityNodes.js +14 -0
  719. package/packages/analyze/src/lib/asts/sourceFiles/getAllEntityNodes.js.map +1 -1
  720. package/packages/analyze/src/lib/asts/sourceFiles/getAllExports.js +6 -0
  721. package/packages/analyze/src/lib/asts/sourceFiles/getAllExports.js.map +1 -1
  722. package/packages/analyze/src/lib/asts/sourceFiles/getImportsAnalysis.js +6 -0
  723. package/packages/analyze/src/lib/asts/sourceFiles/getImportsAnalysis.js.map +1 -1
  724. package/packages/analyze/src/lib/asts/sourceFiles/getResolvedModule.js +39 -1
  725. package/packages/analyze/src/lib/asts/sourceFiles/getResolvedModule.js.map +1 -1
  726. package/packages/analyze/src/lib/asts/sourceFiles/getSourceFilesForAllImports.js +2 -1
  727. package/packages/analyze/src/lib/asts/sourceFiles/getSourceFilesForAllImports.js.map +1 -1
  728. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +268 -52
  729. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
  730. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +24 -1
  731. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
  732. package/packages/analyze/src/lib/files/analyze/dependencyResolver.js +5 -0
  733. package/packages/analyze/src/lib/files/analyze/dependencyResolver.js.map +1 -1
  734. package/packages/analyze/src/lib/files/analyze/findOrCreateEntity.js +2 -0
  735. package/packages/analyze/src/lib/files/analyze/findOrCreateEntity.js.map +1 -1
  736. package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js +2 -1
  737. package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js.map +1 -1
  738. package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js +31 -10
  739. package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js.map +1 -1
  740. package/packages/analyze/src/lib/files/analyzeChange.js +21 -11
  741. package/packages/analyze/src/lib/files/analyzeChange.js.map +1 -1
  742. package/packages/analyze/src/lib/files/analyzeEntity.js +9 -8
  743. package/packages/analyze/src/lib/files/analyzeEntity.js.map +1 -1
  744. package/packages/analyze/src/lib/files/analyzeInitial.js +9 -10
  745. package/packages/analyze/src/lib/files/analyzeInitial.js.map +1 -1
  746. package/packages/analyze/src/lib/files/analyzeRemixRoute.js +3 -2
  747. package/packages/analyze/src/lib/files/analyzeRemixRoute.js.map +1 -1
  748. package/packages/analyze/src/lib/files/enums/steps.js +1 -1
  749. package/packages/analyze/src/lib/files/enums/steps.js.map +1 -1
  750. package/packages/analyze/src/lib/files/getImportedExports.js +11 -7
  751. package/packages/analyze/src/lib/files/getImportedExports.js.map +1 -1
  752. package/packages/analyze/src/lib/files/scenarios/TransformationTracer.js +880 -0
  753. package/packages/analyze/src/lib/files/scenarios/TransformationTracer.js.map +1 -0
  754. package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js +255 -0
  755. package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js.map +1 -0
  756. package/packages/analyze/src/lib/files/scenarios/enrichUnknownTypesFromSourceEquivalencies.js +85 -0
  757. package/packages/analyze/src/lib/files/scenarios/enrichUnknownTypesFromSourceEquivalencies.js.map +1 -0
  758. package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js +483 -48
  759. package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js.map +1 -1
  760. package/packages/analyze/src/lib/files/scenarios/generateChangesScenarioData.js +1 -1
  761. package/packages/analyze/src/lib/files/scenarios/generateChangesScenarioData.js.map +1 -1
  762. package/packages/analyze/src/lib/files/scenarios/generateChangesScenarios.js +29 -34
  763. package/packages/analyze/src/lib/files/scenarios/generateChangesScenarios.js.map +1 -1
  764. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +404 -85
  765. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
  766. package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js +144 -0
  767. package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js.map +1 -0
  768. package/packages/analyze/src/lib/files/scenarios/generateScenarioData.js +56 -69
  769. package/packages/analyze/src/lib/files/scenarios/generateScenarioData.js.map +1 -1
  770. package/packages/analyze/src/lib/files/scenarios/generateScenarios.js +4 -8
  771. package/packages/analyze/src/lib/files/scenarios/generateScenarios.js.map +1 -1
  772. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +768 -117
  773. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
  774. package/packages/analyze/src/lib/files/scenarios/mergeValidatedDataStructures.js +46 -9
  775. package/packages/analyze/src/lib/files/scenarios/mergeValidatedDataStructures.js.map +1 -1
  776. package/packages/analyze/src/lib/files/setImportedExports.js +2 -1
  777. package/packages/analyze/src/lib/files/setImportedExports.js.map +1 -1
  778. package/packages/analyze/src/lib/index.js +1 -0
  779. package/packages/analyze/src/lib/index.js.map +1 -1
  780. package/packages/analyze/src/lib/utils/getFileByPath.js +12 -0
  781. package/packages/analyze/src/lib/utils/getFileByPath.js.map +1 -0
  782. package/packages/aws/src/lib/ecs/ecsDefineContainer.js +2 -2
  783. package/packages/aws/src/lib/ecs/ecsDefineContainer.js.map +1 -1
  784. package/packages/aws/src/lib/ecs/ecsTaskFactory.js +17 -61
  785. package/packages/aws/src/lib/ecs/ecsTaskFactory.js.map +1 -1
  786. package/packages/database/src/lib/kysely/db.js +10 -3
  787. package/packages/database/src/lib/kysely/db.js.map +1 -1
  788. package/packages/database/src/lib/kysely/tables/commitsTable.js +3 -0
  789. package/packages/database/src/lib/kysely/tables/commitsTable.js.map +1 -1
  790. package/packages/database/src/lib/kysely/tables/debugReportsTable.js +9 -3
  791. package/packages/database/src/lib/kysely/tables/debugReportsTable.js.map +1 -1
  792. package/packages/database/src/lib/loadAnalyses.js +45 -2
  793. package/packages/database/src/lib/loadAnalyses.js.map +1 -1
  794. package/packages/database/src/lib/loadAnalysis.js +8 -0
  795. package/packages/database/src/lib/loadAnalysis.js.map +1 -1
  796. package/packages/database/src/lib/loadBranch.js +11 -1
  797. package/packages/database/src/lib/loadBranch.js.map +1 -1
  798. package/packages/database/src/lib/loadCommit.js +7 -0
  799. package/packages/database/src/lib/loadCommit.js.map +1 -1
  800. package/packages/database/src/lib/loadCommits.js +22 -1
  801. package/packages/database/src/lib/loadCommits.js.map +1 -1
  802. package/packages/database/src/lib/loadEntities.js +23 -4
  803. package/packages/database/src/lib/loadEntities.js.map +1 -1
  804. package/packages/database/src/lib/loadEntityBranches.js +9 -0
  805. package/packages/database/src/lib/loadEntityBranches.js.map +1 -1
  806. package/packages/database/src/lib/loadReadyToBeCapturedAnalyses.js +7 -4
  807. package/packages/database/src/lib/loadReadyToBeCapturedAnalyses.js.map +1 -1
  808. package/packages/database/src/lib/updateCommitMetadata.js +5 -4
  809. package/packages/database/src/lib/updateCommitMetadata.js.map +1 -1
  810. package/packages/generate/index.js +3 -0
  811. package/packages/generate/index.js.map +1 -1
  812. package/packages/generate/src/lib/componentScenarioPage/componentScenarioPageNext.js +16 -1
  813. package/packages/generate/src/lib/componentScenarioPage/componentScenarioPageNext.js.map +1 -1
  814. package/packages/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.js +189 -0
  815. package/packages/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.js.map +1 -0
  816. package/packages/generate/src/lib/componentScenarioPage/generateScenarioServerComponent.js +53 -0
  817. package/packages/generate/src/lib/componentScenarioPage/generateScenarioServerComponent.js.map +1 -0
  818. package/packages/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js +8 -4
  819. package/packages/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js.map +1 -1
  820. package/packages/generate/src/lib/deepMerge.js +27 -1
  821. package/packages/generate/src/lib/deepMerge.js.map +1 -1
  822. package/packages/generate/src/lib/scenarioComponentForServer.js +89 -0
  823. package/packages/generate/src/lib/scenarioComponentForServer.js.map +1 -0
  824. package/packages/github/src/lib/loadOrCreateCommit.js +10 -0
  825. package/packages/github/src/lib/loadOrCreateCommit.js.map +1 -1
  826. package/packages/github/src/lib/syncPrimaryBranch.js +3 -0
  827. package/packages/github/src/lib/syncPrimaryBranch.js.map +1 -1
  828. package/packages/process/index.js +3 -0
  829. package/packages/process/index.js.map +1 -0
  830. package/packages/process/src/GlobalProcessManager.js.map +1 -0
  831. package/{background/src/lib/process → packages/process/src}/ProcessManager.js +1 -1
  832. package/packages/process/src/ProcessManager.js.map +1 -0
  833. package/packages/process/src/index.js.map +1 -0
  834. package/packages/process/src/managedExecAsync.js.map +1 -0
  835. package/packages/types/index.js.map +1 -1
  836. package/packages/utils/src/lib/lightweightEntityExtractor.js +25 -0
  837. package/packages/utils/src/lib/lightweightEntityExtractor.js.map +1 -1
  838. package/packages/utils/src/lib/safeFileName.js +29 -3
  839. package/packages/utils/src/lib/safeFileName.js.map +1 -1
  840. package/scripts/finalize-analyzer.cjs +6 -4
  841. package/analyzer-template/packages/ai/src/lib/findMatchingAttribute.ts +0 -102
  842. package/analyzer-template/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.ts +0 -197
  843. package/analyzer-template/packages/ai/src/lib/generateChangesEntityKeyAttributes.ts +0 -271
  844. package/analyzer-template/packages/ai/src/lib/generateEntityKeyAttributes.ts +0 -294
  845. package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityKeyAttributesGenerator.ts +0 -67
  846. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.ts +0 -115
  847. package/analyzer-template/process/INTEGRATION_COMPLETE.md +0 -333
  848. package/analyzer-template/process/INTEGRATION_EXAMPLE.md +0 -525
  849. package/analyzer-template/process/README.md +0 -507
  850. package/background/src/lib/process/GlobalProcessManager.js.map +0 -1
  851. package/background/src/lib/process/ProcessManager.js.map +0 -1
  852. package/background/src/lib/process/index.js.map +0 -1
  853. package/background/src/lib/process/managedExecAsync.js.map +0 -1
  854. package/codeyam-cli/scripts/fixtures/cal.com/universal-mocks/packages/prisma/index.js +0 -238
  855. package/codeyam-cli/scripts/fixtures/cal.com/universal-mocks/packages/prisma/index.js.map +0 -1
  856. package/codeyam-cli/src/webserver/build/client/assets/EntityItem-CVbSvOjo.js +0 -1
  857. package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-DcwcHyl5.js +0 -1
  858. package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-WgwC1GfJ.js +0 -26
  859. package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-IEKom9O2.js +0 -3
  860. package/codeyam-cli/src/webserver/build/client/assets/LogViewer-BYnfxbUG.js +0 -3
  861. package/codeyam-cli/src/webserver/build/client/assets/ReportIssueModal-_lBPJCzG.js +0 -1
  862. package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-lHVhvsu_.js +0 -1
  863. package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-d_TBk4GQ.js +0 -5
  864. package/codeyam-cli/src/webserver/build/client/assets/_index-kGT7VUqj.js +0 -1
  865. package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-DDGmhu7P.js +0 -7
  866. package/codeyam-cli/src/webserver/build/client/assets/chevron-down-n_HPRfM_.js +0 -1
  867. package/codeyam-cli/src/webserver/build/client/assets/chunk-WWGJGFF6-CbVoyx1U.js +0 -26
  868. package/codeyam-cli/src/webserver/build/client/assets/circle-check-D1VOYveA.js +0 -1
  869. package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-YR8jjAlu.js +0 -1
  870. package/codeyam-cli/src/webserver/build/client/assets/dev.empty-B8vP3V_s.js +0 -1
  871. package/codeyam-cli/src/webserver/build/client/assets/entity._sha._-CN6aLCT1.js +0 -16
  872. package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-DA5Jeu2P.js +0 -1
  873. package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-BTeitalf.js +0 -5
  874. package/codeyam-cli/src/webserver/build/client/assets/entry.client-du6UEYD-.js +0 -13
  875. package/codeyam-cli/src/webserver/build/client/assets/fileTableUtils-BpjkhMoi.js +0 -1
  876. package/codeyam-cli/src/webserver/build/client/assets/files-BQGvk4lJ.js +0 -1
  877. package/codeyam-cli/src/webserver/build/client/assets/git-DVdYRT-I.js +0 -12
  878. package/codeyam-cli/src/webserver/build/client/assets/globals-CO-U8Bpo.css +0 -1
  879. package/codeyam-cli/src/webserver/build/client/assets/html2canvas-pro.esm-XQCGvadH.js +0 -5
  880. package/codeyam-cli/src/webserver/build/client/assets/index-DCG-vks0.js +0 -1
  881. package/codeyam-cli/src/webserver/build/client/assets/loader-circle-GazdNeLl.js +0 -1
  882. package/codeyam-cli/src/webserver/build/client/assets/manifest-0b694d28.js +0 -1
  883. package/codeyam-cli/src/webserver/build/client/assets/root-D3tQP7hx.js +0 -16
  884. package/codeyam-cli/src/webserver/build/client/assets/search-CIY6XmtE.js +0 -1
  885. package/codeyam-cli/src/webserver/build/client/assets/server-build-CMKNK2uU.css +0 -1
  886. package/codeyam-cli/src/webserver/build/client/assets/settings-CoMDgElu.js +0 -1
  887. package/codeyam-cli/src/webserver/build/client/assets/simulations-agkniXp2.js +0 -1
  888. package/codeyam-cli/src/webserver/build/client/assets/triangle-alert-B2VUcygF.js +0 -1
  889. package/codeyam-cli/src/webserver/build/client/assets/useReportContext-EvdK-zXP.js +0 -1
  890. package/codeyam-cli/src/webserver/build/server/assets/index-DGVHQEXD.js +0 -1
  891. package/codeyam-cli/src/webserver/build/server/assets/server-build-CghkTkIL.js +0 -166
  892. package/codeyam-cli/templates/debug-command.md +0 -303
  893. package/packages/ai/src/lib/findMatchingAttribute.js +0 -77
  894. package/packages/ai/src/lib/findMatchingAttribute.js.map +0 -1
  895. package/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.js +0 -136
  896. package/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.js.map +0 -1
  897. package/packages/ai/src/lib/generateChangesEntityKeyAttributes.js +0 -220
  898. package/packages/ai/src/lib/generateChangesEntityKeyAttributes.js.map +0 -1
  899. package/packages/ai/src/lib/generateEntityKeyAttributes.js +0 -241
  900. package/packages/ai/src/lib/generateEntityKeyAttributes.js.map +0 -1
  901. package/packages/ai/src/lib/isFrontend.js +0 -5
  902. package/packages/ai/src/lib/isFrontend.js.map +0 -1
  903. package/packages/ai/src/lib/promptGenerators/generateEntityKeyAttributesGenerator.js +0 -40
  904. package/packages/ai/src/lib/promptGenerators/generateEntityKeyAttributesGenerator.js.map +0 -1
  905. package/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.js +0 -72
  906. package/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.js.map +0 -1
  907. /package/analyzer-template/{process → packages/process/src}/GlobalProcessManager.ts +0 -0
  908. /package/analyzer-template/{process → packages/process/src}/ProcessManager.ts +0 -0
  909. /package/analyzer-template/{process → packages/process/src}/index.ts +0 -0
  910. /package/analyzer-template/{process → packages/process/src}/managedExecAsync.ts +0 -0
  911. /package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-CMKNK2uU.css → styles-CMKNK2uU.css} +0 -0
  912. /package/{background/src/lib/process → packages/process/src}/GlobalProcessManager.js +0 -0
  913. /package/{background/src/lib/process → packages/process/src}/index.js +0 -0
  914. /package/{background/src/lib/process → packages/process/src}/managedExecAsync.js +0 -0
@@ -0,0 +1,2267 @@
1
+ /**
2
+ * Generates execution flows from conditional usages using pure static analysis.
3
+ *
4
+ * This replaces LLM-driven flow generation with deterministic flow generation
5
+ * based on conditionalUsages extracted from the AST. Only paths that resolve
6
+ * to controllable data sources (exist in attributesMap) produce flows.
7
+ *
8
+ * Flow generation rules:
9
+ * - truthiness conditions → truthy flow + falsy flow
10
+ * - comparison conditions → one flow per compared value
11
+ * - switch conditions → one flow per case value
12
+ * - compound conditionals → one flow with all conditions (only if ALL paths controllable)
13
+ */
14
+
15
+ import type { ExecutionFlow } from '~codeyam/types';
16
+ import type {
17
+ ConditionalUsage,
18
+ CompoundConditional,
19
+ DerivedVariableOperation,
20
+ DerivedVariableInfo,
21
+ JsxRenderingUsage,
22
+ } from './astScopes/types';
23
+ import type { EnrichedConditionalUsage } from './worker/SerializableDataStructure';
24
+ import resolvePathToControllable from './resolvePathToControllable';
25
+ import cleanPathOfNonTransformingFunctions from './dataStructure/helpers/cleanPathOfNonTransformingFunctions';
26
+
27
+ /** Extended conditional usage type that may include sourceDataPath from enrichment */
28
+ type ExtendedConditionalUsage = ConditionalUsage &
29
+ Partial<EnrichedConditionalUsage>;
30
+
31
+ /** Child component conditional data for merging child flows into parent */
32
+ export interface ChildComponentConditionalData {
33
+ /** Child's conditional usages keyed by variable name (may include sourceDataPath from enrichment) */
34
+ conditionalUsages: Record<string, ExtendedConditionalUsage[]>;
35
+ /** Child's equivalent signature variables (maps internal paths to prop paths) */
36
+ equivalentSignatureVariables: Record<string, string | string[]>;
37
+ /** Child's compound conditionals */
38
+ compoundConditionals: CompoundConditional[];
39
+ /**
40
+ * Gating conditions - the parent's conditions required to render this child component.
41
+ * For example, if the parent has `{hasAnalysis && <ChildComponent />}`,
42
+ * then `hasAnalysis` is a gating condition for all of ChildComponent's flows.
43
+ */
44
+ gatingConditions?: ConditionalUsage[];
45
+ /**
46
+ * Child's JSX rendering usages (arrays rendered via .map(), text interpolation).
47
+ * These generate "variation flows" for different array lengths.
48
+ */
49
+ jsxRenderingUsages?: JsxRenderingUsage[];
50
+ }
51
+
52
+ export interface GenerateFlowsFromConditionalsArgs {
53
+ /** Record of attribute paths to their conditional usages (may include sourceDataPath) */
54
+ conditionalUsages: Record<string, ExtendedConditionalUsage[]>;
55
+ /** Compound conditionals (&&-chained conditions) */
56
+ compoundConditionals: CompoundConditional[];
57
+ /** Map of controllable paths to their types */
58
+ attributesMap: Record<string, string>;
59
+ /** Map from local variable names to data sources */
60
+ equivalentSignatureVariables: Record<string, string | string[]>;
61
+ /** Map from full paths to short paths */
62
+ fullToShortPathMap: Record<string, string>;
63
+ /**
64
+ * Optional child component conditional data.
65
+ * Maps child component name to its conditional data.
66
+ * Used to merge child execution flows into parent.
67
+ */
68
+ childComponentData?: Record<string, ChildComponentConditionalData>;
69
+ /**
70
+ * Optional map of derived variables to their derivation info.
71
+ * Used to trace intermediate derived variables that aren't directly
72
+ * used in conditionals but are sources for other derived variables.
73
+ *
74
+ * Example:
75
+ * - `isInCurrentRun = currentRun.entityShas.includes(sha)` → { sourcePath: 'currentRun.entityShas', operation: 'arrayIncludes' }
76
+ * - `isAnalyzing = isInCurrentRun || isInQueue` → { sourcePaths: ['isInCurrentRun', 'isInQueue'], operation: 'or' }
77
+ *
78
+ * Without this map, we can't trace from `isAnalyzing` through `isInCurrentRun`
79
+ * to `currentRun.entityShas` when `isInCurrentRun` isn't in conditionalUsages.
80
+ */
81
+ derivedVariables?: Record<string, DerivedVariableInfo>;
82
+ /**
83
+ * Optional map of child prop paths to their actual data sources.
84
+ * Used when child props flow through useState but ultimately come from
85
+ * mockable data sources (e.g., API calls, fetchers).
86
+ *
87
+ * Example:
88
+ * - "WorkoutsView().signature[0].workouts" → "createClient()...functionCallReturnValue.data"
89
+ *
90
+ * When a child path translates to a useState value, we check this map
91
+ * to find the real data source that can be mocked.
92
+ */
93
+ sourceEquivalencies?: Record<
94
+ string,
95
+ Array<{ scopeNodeName: string; schemaPath: string }>
96
+ >;
97
+ }
98
+
99
+ /**
100
+ * Resolved source info from expanding a derived variable.
101
+ * Contains the path and the operation that led to it.
102
+ */
103
+ interface ResolvedSourceInfo {
104
+ path: string;
105
+ operation?:
106
+ | 'notNull'
107
+ | 'isNull'
108
+ | 'equals'
109
+ | 'notEquals'
110
+ | 'or'
111
+ | 'and'
112
+ | 'arrayIncludes'
113
+ | 'arraySome'
114
+ | 'arrayEvery'
115
+ | 'arrayLength';
116
+ }
117
+
118
+ /**
119
+ * Recursively expands a derived variable to its leaf data sources.
120
+ *
121
+ * For OR expressions like `isAnalyzing = a || b || c`:
122
+ * - Returns all source paths [a, b, c] so they can all be set appropriately
123
+ *
124
+ * For nested derivations like `isAnalyzing = isInCurrentRun || isInQueue`:
125
+ * - Where `isInCurrentRun` is derived from `currentRun.entityShas.includes(x)`
126
+ * - Returns the final data sources: [currentRun.entityShas, queueState.jobs]
127
+ *
128
+ * @param path The variable path to expand
129
+ * @param conditionalUsages All conditional usages (to look up derivedFrom info)
130
+ * @param attributesMap Map of controllable paths
131
+ * @param equivalentSignatureVariables Variable-to-path mappings
132
+ * @param fullToShortPathMap Full-to-short path mappings
133
+ * @param visited Set of already-visited paths (prevents infinite recursion)
134
+ * @param derivedVariables Optional map of all derived variables (for intermediate tracing)
135
+ * @returns Array of resolved source paths that are controllable
136
+ */
137
+ function expandDerivedVariableToSources(
138
+ path: string,
139
+ conditionalUsages: Record<string, ConditionalUsage[]>,
140
+ attributesMap: Record<string, string>,
141
+ equivalentSignatureVariables: Record<string, string | string[]>,
142
+ fullToShortPathMap: Record<string, string>,
143
+ visited: Set<string> = new Set(),
144
+ derivedVariables?: Record<string, DerivedVariableInfo>,
145
+ ): ResolvedSourceInfo[] {
146
+ // Prevent infinite recursion
147
+ if (visited.has(path)) {
148
+ return [];
149
+ }
150
+ visited.add(path);
151
+
152
+ // First, check if this path is directly controllable
153
+ const directResolution = resolvePathToControllable(
154
+ path,
155
+ attributesMap,
156
+ equivalentSignatureVariables,
157
+ fullToShortPathMap,
158
+ );
159
+
160
+ if (directResolution.isControllable && directResolution.resolvedPath) {
161
+ return [{ path: directResolution.resolvedPath }];
162
+ }
163
+
164
+ // Look up derivedFrom info for this path
165
+ // First check conditionalUsages, then fall back to derivedVariables
166
+ const usage = conditionalUsages[path]?.[0];
167
+ let derivedFrom = usage?.derivedFrom;
168
+
169
+ // CRITICAL: If not found in conditionalUsages, check derivedVariables
170
+ // This handles intermediate derived variables like `isInCurrentRun` that aren't
171
+ // directly used in conditionals but ARE derived from data sources
172
+ if (!derivedFrom && derivedVariables?.[path]) {
173
+ derivedFrom = derivedVariables[path];
174
+ }
175
+
176
+ if (!derivedFrom) {
177
+ return [];
178
+ }
179
+
180
+ const { operation, sourcePath, sourcePaths } = derivedFrom;
181
+
182
+ // For OR/AND operations, recursively expand all source paths
183
+ if ((operation === 'or' || operation === 'and') && sourcePaths) {
184
+ const allSources: ResolvedSourceInfo[] = [];
185
+
186
+ for (const sp of sourcePaths) {
187
+ const expanded = expandDerivedVariableToSources(
188
+ sp,
189
+ conditionalUsages,
190
+ attributesMap,
191
+ equivalentSignatureVariables,
192
+ fullToShortPathMap,
193
+ visited,
194
+ derivedVariables,
195
+ );
196
+
197
+ // Add all expanded sources
198
+ for (const source of expanded) {
199
+ // Avoid duplicates
200
+ if (!allSources.some((s) => s.path === source.path)) {
201
+ allSources.push(source);
202
+ }
203
+ }
204
+ }
205
+
206
+ return allSources;
207
+ }
208
+
209
+ // For single-source operations (arrayIncludes, arraySome, notNull, etc.)
210
+ if (sourcePath) {
211
+ // Try to resolve the source path directly
212
+ const sourceResolution = resolvePathToControllable(
213
+ sourcePath,
214
+ attributesMap,
215
+ equivalentSignatureVariables,
216
+ fullToShortPathMap,
217
+ );
218
+
219
+ if (sourceResolution.isControllable && sourceResolution.resolvedPath) {
220
+ return [{ path: sourceResolution.resolvedPath, operation }];
221
+ }
222
+
223
+ // If not directly resolvable, recursively expand
224
+ return expandDerivedVariableToSources(
225
+ sourcePath,
226
+ conditionalUsages,
227
+ attributesMap,
228
+ equivalentSignatureVariables,
229
+ fullToShortPathMap,
230
+ visited,
231
+ derivedVariables,
232
+ );
233
+ }
234
+
235
+ return [];
236
+ }
237
+
238
+ /**
239
+ * Clean up sourceDataPath by removing redundant scope prefixes.
240
+ *
241
+ * This function ONLY handles the specific pattern where a scope name is
242
+ * duplicated before the hook call:
243
+ *
244
+ * Example:
245
+ * "useLoaderData<LoaderData>.useLoaderData<LoaderData>().functionCallReturnValue.entity.sha"
246
+ * → "useLoaderData<LoaderData>().functionCallReturnValue.entity.sha"
247
+ *
248
+ * For paths with multiple function calls (like fetch().json()), or paths
249
+ * that don't match the expected pattern, returns null to indicate the
250
+ * fallback resolution should be used.
251
+ */
252
+ function cleanSourceDataPath(sourceDataPath: string): string | null {
253
+ // Count function call patterns - both empty () and with content (...)
254
+ // We detect multiple function calls by counting:
255
+ // 1. Empty () patterns
256
+ // 2. Patterns like functionName(...) - closing paren followed by dot or end
257
+ const emptyFnCalls = (sourceDataPath.match(/\(\)/g) || []).length;
258
+ const fnCallReturnValues = (
259
+ sourceDataPath.match(/\.functionCallReturnValue/g) || []
260
+ ).length;
261
+
262
+ // If there are multiple functionCallReturnValue occurrences, this is a chained call
263
+ // (e.g., fetch(...).functionCallReturnValue.json().functionCallReturnValue.data)
264
+ if (fnCallReturnValues > 1 || emptyFnCalls !== 1) {
265
+ // Multiple function calls - return null to use fallback resolution
266
+ return null;
267
+ }
268
+
269
+ // Find the "()" which marks the function call
270
+ const fnCallIndex = sourceDataPath.indexOf('()');
271
+
272
+ // Find where the function name starts (go back to find the start of this segment)
273
+ const beforeFnCall = sourceDataPath.slice(0, fnCallIndex);
274
+ const lastDotBeforeFn = beforeFnCall.lastIndexOf('.');
275
+
276
+ if (lastDotBeforeFn === -1) {
277
+ return sourceDataPath;
278
+ }
279
+
280
+ // Extract the scope prefix and the actual path
281
+ const scopePrefix = sourceDataPath.slice(0, lastDotBeforeFn);
282
+ const actualPath = sourceDataPath.slice(lastDotBeforeFn + 1);
283
+
284
+ // Verify this is actually a redundant scope prefix pattern
285
+ // The actualPath should start with something that matches the scopePrefix
286
+ // e.g., scopePrefix="useLoaderData<LoaderData>" and actualPath starts with "useLoaderData<LoaderData>()..."
287
+ if (!actualPath.startsWith(scopePrefix.split('.').pop() || '')) {
288
+ // Not a redundant prefix pattern - return the original path
289
+ return sourceDataPath;
290
+ }
291
+
292
+ return actualPath;
293
+ }
294
+
295
+ /**
296
+ * Strip .length suffix from a path if present.
297
+ *
298
+ * When we have a path like "items.length", the controllable attribute is "items"
299
+ * (the array), not "items.length". The length is derived from the array contents.
300
+ *
301
+ * This ensures that execution flows reference the actual controllable attribute
302
+ * rather than the derived .length property.
303
+ */
304
+ function stripLengthSuffix(path: string): string {
305
+ if (path.endsWith('.length')) {
306
+ return path.slice(0, -7); // Remove ".length" (7 characters)
307
+ }
308
+ return path;
309
+ }
310
+
311
+ /**
312
+ * Extract the controllable base path from a path that may contain method calls.
313
+ *
314
+ * This handles complex expressions like:
315
+ * - `scenarios.filter((s) => s.active).length` → `scenarios`
316
+ * - `users.some((u) => u.role === 'admin')` → `users`
317
+ * - `items.map(x => x.name).join(', ')` → `items`
318
+ *
319
+ * The controllable base is the path that can be mocked - we can control
320
+ * what `scenarios` contains, but we can't control what `.filter()` returns.
321
+ *
322
+ * @param path - The path that may contain method calls
323
+ * @returns The controllable base path with method calls stripped
324
+ */
325
+ function extractControllableBase(path: string): string {
326
+ // First strip .length suffix if present
327
+ const pathWithoutLength = stripLengthSuffix(path);
328
+
329
+ // Use cleanPathOfNonTransformingFunctions to strip method calls like .filter(), .some()
330
+ const cleanedPath = cleanPathOfNonTransformingFunctions(pathWithoutLength);
331
+
332
+ // If the cleaned path is different, return it
333
+ if (cleanedPath !== pathWithoutLength) {
334
+ return cleanedPath;
335
+ }
336
+
337
+ // Otherwise, return the path with just .length stripped
338
+ return pathWithoutLength;
339
+ }
340
+
341
+ /**
342
+ * Find a path in attributesMap, using fullToShortPathMap to verify the path is controllable.
343
+ *
344
+ * IMPORTANT: Returns the FULL path (preserving data source context) when possible.
345
+ * This ensures execution flows can be traced back to specific data sources,
346
+ * which is critical when multiple data sources have the same property names
347
+ * (e.g., multiple useFetcher hooks all having 'state' and 'data').
348
+ *
349
+ * The attributesMap contains short relative paths (e.g., "entity.sha")
350
+ * The sourceDataPath contains full paths (e.g., "useLoaderData<LoaderData>().functionCallReturnValue.entity.sha")
351
+ * The fullToShortPathMap maps full paths to short paths
352
+ */
353
+ function findInAttributesMapForPath(
354
+ path: string,
355
+ attributesMap: Record<string, string>,
356
+ fullToShortPathMap: Record<string, string>,
357
+ ): string | null {
358
+ // Direct match in attributesMap (already a short path)
359
+ if (path in attributesMap) {
360
+ return path;
361
+ }
362
+
363
+ // Try looking up the path in fullToShortPathMap to verify it's controllable
364
+ // IMPORTANT: Return the FULL path, not the short path, to preserve data source context
365
+ if (path in fullToShortPathMap) {
366
+ const shortPath = fullToShortPathMap[path];
367
+ if (shortPath in attributesMap) {
368
+ return path; // Return FULL path to preserve data source context
369
+ }
370
+ }
371
+
372
+ // Normalized match (array indices [N] → [])
373
+ const normalizedPath = path.replace(/\[\d+\]/g, '[]');
374
+ if (normalizedPath !== path) {
375
+ if (normalizedPath in attributesMap) {
376
+ return normalizedPath;
377
+ }
378
+ if (normalizedPath in fullToShortPathMap) {
379
+ const shortPath = fullToShortPathMap[normalizedPath];
380
+ if (shortPath in attributesMap) {
381
+ return normalizedPath; // Return normalized FULL path
382
+ }
383
+ }
384
+ }
385
+
386
+ // Try prefix matching for child paths
387
+ // e.g., path is "entity.sha.something" and attributesMap has "entity.sha"
388
+ // OR path is a full path like "useLoaderData<...>().functionCallReturnValue.entity.sha"
389
+ // and we need to find matching short path prefix
390
+ for (const attrPath of Object.keys(attributesMap)) {
391
+ if (path.startsWith(attrPath + '.') || path.startsWith(attrPath + '[')) {
392
+ // The path is a child of a known attribute path
393
+ return path;
394
+ }
395
+ }
396
+
397
+ // Try suffix matching: if the path ends with ".X.Y.Z" and attributesMap has "X.Y.Z"
398
+ // Return the FULL input path to preserve data source context
399
+ for (const attrPath of Object.keys(attributesMap)) {
400
+ if (
401
+ path.endsWith('.' + attrPath) ||
402
+ path.endsWith('.' + attrPath.replace(/\[\d+\]/g, '[]'))
403
+ ) {
404
+ return path; // Return FULL path, not short attrPath
405
+ }
406
+ }
407
+
408
+ return null;
409
+ }
410
+
411
+ /**
412
+ * Generate a slug from a path for use in flow IDs and exclusive groups.
413
+ */
414
+ function pathToSlug(path: string): string {
415
+ return path
416
+ .replace(/\[\d+\]/g, '')
417
+ .replace(/\[\]/g, '')
418
+ .replace(/\(\)/g, '')
419
+ .replace(/\.functionCallReturnValue/g, '')
420
+ .replace(/[<>]/g, '')
421
+ .replace(/\./g, '-')
422
+ .toLowerCase();
423
+ }
424
+
425
+ /**
426
+ * Generate a human-readable name from a path.
427
+ * Extracts the last meaningful part of the path.
428
+ *
429
+ * Examples:
430
+ * - "useFetcher<...>().functionCallReturnValue.state" → "state"
431
+ * - "useLoaderData<...>().functionCallReturnValue.user.isActive" → "isActive"
432
+ */
433
+ function generateNameFromPath(path: string): string {
434
+ // Remove function call markers and get the last meaningful segment
435
+ const cleanPath = path
436
+ .replace(/\(\)/g, '')
437
+ .replace(/\.functionCallReturnValue/g, '');
438
+ const parts = cleanPath.split('.');
439
+ const lastPart = parts[parts.length - 1];
440
+
441
+ // Convert camelCase to Title Case with spaces
442
+ return lastPart
443
+ .replace(/([A-Z])/g, ' $1')
444
+ .replace(/^./, (str) => str.toUpperCase())
445
+ .trim();
446
+ }
447
+
448
+ /**
449
+ * Generate a flow ID from path and value.
450
+ * Creates a unique, URL-safe identifier.
451
+ */
452
+ function generateFlowId(path: string, value: string): string {
453
+ // Clean the path for use in ID
454
+ const cleanPath = path
455
+ .replace(/\(\)/g, '')
456
+ .replace(/\.functionCallReturnValue/g, '')
457
+ .replace(/[<>]/g, '')
458
+ .replace(/\./g, '-');
459
+
460
+ // Clean the value
461
+ const cleanValue = value
462
+ .toString()
463
+ .toLowerCase()
464
+ .replace(/[^a-z0-9]/g, '-')
465
+ .replace(/-+/g, '-')
466
+ .replace(/^-|-$/g, '');
467
+
468
+ return `${cleanPath}-${cleanValue}`.toLowerCase();
469
+ }
470
+
471
+ /**
472
+ * Infer value type from a string value.
473
+ */
474
+ function inferValueType(
475
+ value: string,
476
+ ): 'string' | 'number' | 'boolean' | 'null' {
477
+ if (value === 'true' || value === 'false') return 'boolean';
478
+ if (value === 'null' || value === 'undefined') return 'null';
479
+ if (!isNaN(Number(value)) && value !== '') return 'number';
480
+ return 'string';
481
+ }
482
+
483
+ /**
484
+ * Generate flows from a single conditional usage.
485
+ * Sets impact to 'high' if the conditional controls JSX rendering.
486
+ *
487
+ * When the usage has a `constraintExpression`, it represents a complex expression
488
+ * that can't be simply resolved (e.g., `scenarios.filter(x => x.active).length > 1`).
489
+ * In this case:
490
+ * - `attributePath` is set to the controllable base (e.g., `scenarios`)
491
+ * - `constraint` is set to the full expression for LLM reasoning
492
+ */
493
+ function generateFlowsFromUsage(
494
+ usage: ConditionalUsage,
495
+ resolvedPath: string,
496
+ ): ExecutionFlow[] {
497
+ const flows: ExecutionFlow[] = [];
498
+ const baseName = generateNameFromPath(resolvedPath);
499
+
500
+ // Determine impact based on whether this conditional controls JSX rendering
501
+ // Conditionals that control visual output are high-impact
502
+ const impact: ExecutionFlow['impact'] = usage.controlsJsxRendering
503
+ ? 'high'
504
+ : 'medium';
505
+
506
+ // When there's a constraintExpression, use the controllable base for attributePath
507
+ // and pass through the constraint for LLM reasoning
508
+ const hasConstraint = !!usage.constraintExpression;
509
+ const attributePath = hasConstraint
510
+ ? extractControllableBase(resolvedPath)
511
+ : stripLengthSuffix(resolvedPath);
512
+ const constraint = usage.constraintExpression;
513
+
514
+ if (usage.conditionType === 'truthiness') {
515
+ // Generate both truthy and falsy flows
516
+ const isNegated = usage.isNegated ?? false;
517
+
518
+ // Truthy flow (or falsy if negated)
519
+ flows.push({
520
+ id: generateFlowId(resolvedPath, isNegated ? 'falsy' : 'truthy'),
521
+ name: `${baseName} ${isNegated ? 'False' : 'True'}`,
522
+ description: `When ${baseName.toLowerCase()} is ${isNegated ? 'falsy' : 'truthy'}`,
523
+ requiredValues: [
524
+ {
525
+ attributePath,
526
+ value: isNegated ? 'falsy' : 'truthy',
527
+ comparison: isNegated ? 'falsy' : 'truthy',
528
+ valueType: 'boolean',
529
+ constraint,
530
+ },
531
+ ],
532
+ impact,
533
+ sourceLocation: usage.sourceLocation
534
+ ? {
535
+ lineNumber: usage.sourceLocation.lineNumber,
536
+ column: usage.sourceLocation.column,
537
+ }
538
+ : undefined,
539
+ codeSnippet: usage.sourceLocation?.codeSnippet,
540
+ });
541
+
542
+ // Falsy flow (or truthy if negated)
543
+ flows.push({
544
+ id: generateFlowId(resolvedPath, isNegated ? 'truthy' : 'falsy'),
545
+ name: `${baseName} ${isNegated ? 'True' : 'False'}`,
546
+ description: `When ${baseName.toLowerCase()} is ${isNegated ? 'truthy' : 'falsy'}`,
547
+ requiredValues: [
548
+ {
549
+ attributePath,
550
+ value: isNegated ? 'truthy' : 'falsy',
551
+ comparison: isNegated ? 'truthy' : 'falsy',
552
+ valueType: 'boolean',
553
+ constraint,
554
+ },
555
+ ],
556
+ impact,
557
+ sourceLocation: usage.sourceLocation
558
+ ? {
559
+ lineNumber: usage.sourceLocation.lineNumber,
560
+ column: usage.sourceLocation.column,
561
+ }
562
+ : undefined,
563
+ codeSnippet: usage.sourceLocation?.codeSnippet,
564
+ });
565
+ } else if (
566
+ usage.conditionType === 'comparison' ||
567
+ usage.conditionType === 'switch'
568
+ ) {
569
+ // Generate one flow per compared value
570
+ const values = usage.comparedValues ?? [];
571
+
572
+ for (const value of values) {
573
+ flows.push({
574
+ id: generateFlowId(resolvedPath, value),
575
+ name: `${baseName}: ${value}`,
576
+ description: `When ${baseName.toLowerCase()} equals "${value}"`,
577
+ requiredValues: [
578
+ {
579
+ attributePath,
580
+ value: value,
581
+ comparison: 'equals',
582
+ valueType: inferValueType(value),
583
+ constraint,
584
+ },
585
+ ],
586
+ impact,
587
+ sourceLocation: usage.sourceLocation
588
+ ? {
589
+ lineNumber: usage.sourceLocation.lineNumber,
590
+ column: usage.sourceLocation.column,
591
+ }
592
+ : undefined,
593
+ codeSnippet: usage.sourceLocation?.codeSnippet,
594
+ });
595
+ }
596
+ }
597
+
598
+ return flows;
599
+ }
600
+
601
+ /**
602
+ * Generate a flow from a compound conditional (all conditions must be satisfied).
603
+ * Sets impact to 'high' if the compound conditional controls JSX rendering.
604
+ */
605
+ function generateFlowFromCompound(
606
+ compound: CompoundConditional,
607
+ resolvedPaths: Map<string, string>,
608
+ ): ExecutionFlow | null {
609
+ // Determine impact based on whether this compound conditional controls JSX rendering
610
+ const impact: ExecutionFlow['impact'] = compound.controlsJsxRendering
611
+ ? 'high'
612
+ : 'medium';
613
+ const requiredValues: ExecutionFlow['requiredValues'] = [];
614
+
615
+ for (const condition of compound.conditions) {
616
+ const resolvedPath = resolvedPaths.get(condition.path);
617
+ if (!resolvedPath) {
618
+ // This shouldn't happen if we pre-filtered, but safety check
619
+ return null;
620
+ }
621
+
622
+ // Determine the required value based on condition type
623
+ let value: string;
624
+ let comparison: ExecutionFlow['requiredValues'][0]['comparison'];
625
+
626
+ if (condition.conditionType === 'truthiness') {
627
+ // If negated (!foo), we need falsy; otherwise truthy
628
+ value = condition.isNegated ? 'falsy' : 'truthy';
629
+ comparison = condition.isNegated ? 'falsy' : 'truthy';
630
+ } else {
631
+ // For comparison/switch, use the first compared value or required value
632
+ value =
633
+ condition.requiredValue?.toString() ??
634
+ condition.comparedValues?.[0] ??
635
+ 'truthy';
636
+ comparison = 'equals';
637
+ }
638
+
639
+ requiredValues.push({
640
+ attributePath: stripLengthSuffix(resolvedPath),
641
+ value,
642
+ comparison,
643
+ valueType: inferValueType(value),
644
+ });
645
+ }
646
+
647
+ // Generate a combined ID from all paths
648
+ const pathParts = requiredValues
649
+ .map((rv) => {
650
+ const name = generateNameFromPath(rv.attributePath);
651
+ return name.toLowerCase().replace(/\s+/g, '-');
652
+ })
653
+ .join('-and-');
654
+
655
+ return {
656
+ id: `compound-${pathParts}`,
657
+ name: requiredValues
658
+ .map((rv) => generateNameFromPath(rv.attributePath))
659
+ .join(' + '),
660
+ description: `When ${requiredValues.map((rv) => `${generateNameFromPath(rv.attributePath).toLowerCase()} is ${rv.value}`).join(' and ')}`,
661
+ requiredValues,
662
+ impact,
663
+ sourceLocation: {
664
+ lineNumber: compound.sourceLocation.lineNumber,
665
+ column: compound.sourceLocation.column,
666
+ },
667
+ codeSnippet: compound.sourceLocation.codeSnippet,
668
+ };
669
+ }
670
+
671
+ /**
672
+ * Expand a compound conditional with OR groups into multiple condition sets.
673
+ *
674
+ * For a compound like `A && (B || C)`:
675
+ * - Conditions: [{ path: 'A' }, { path: 'B', orGroupId: 'or_xxx' }, { path: 'C', orGroupId: 'or_xxx' }]
676
+ * - Returns: [[A, B], [A, C]] - two sets of conditions
677
+ *
678
+ * For multiple OR groups like `A && (B || C) && (D || E)`:
679
+ * - Returns: [[A, B, D], [A, B, E], [A, C, D], [A, C, E]]
680
+ */
681
+ function expandOrGroups(
682
+ conditions: CompoundConditional['conditions'],
683
+ ): CompoundConditional['conditions'][] {
684
+ // Separate conditions into mandatory (no orGroupId) and OR groups
685
+ const mandatory = conditions.filter((c) => !c.orGroupId);
686
+ const orGroups = new Map<string, typeof conditions>();
687
+
688
+ for (const condition of conditions) {
689
+ if (condition.orGroupId) {
690
+ const group = orGroups.get(condition.orGroupId) ?? [];
691
+ group.push(condition);
692
+ orGroups.set(condition.orGroupId, group);
693
+ }
694
+ }
695
+
696
+ // If no OR groups, return the original conditions
697
+ if (orGroups.size === 0) {
698
+ return [conditions];
699
+ }
700
+
701
+ // Generate all combinations by picking one condition from each OR group
702
+ const groupArrays = Array.from(orGroups.values());
703
+ const combinations: CompoundConditional['conditions'][] = [];
704
+
705
+ function generateCombinations(
706
+ index: number,
707
+ current: typeof conditions,
708
+ ): void {
709
+ if (index === groupArrays.length) {
710
+ // We've picked one from each OR group - combine with mandatory conditions
711
+ combinations.push([...mandatory, ...current]);
712
+ return;
713
+ }
714
+
715
+ // Pick each option from the current OR group
716
+ for (const option of groupArrays[index]) {
717
+ generateCombinations(index + 1, [...current, option]);
718
+ }
719
+ }
720
+
721
+ generateCombinations(0, []);
722
+ return combinations;
723
+ }
724
+
725
+ /**
726
+ * Generate execution flows from conditional usages using pure static analysis.
727
+ *
728
+ * Only generates flows where all paths resolve to controllable data sources.
729
+ * This ensures we never produce flows with invalid paths like useState variables.
730
+ */
731
+ /**
732
+ * Normalize a resolved path to a canonical form for deduplication.
733
+ * Uses fullToShortPathMap to convert full paths to short paths.
734
+ * This ensures that both "hasNewerVersion" and
735
+ * "useLoaderData<LoaderData>().functionCallReturnValue.hasNewerVersion"
736
+ * normalize to the same canonical path.
737
+ */
738
+ function normalizePathForDeduplication(
739
+ resolvedPath: string,
740
+ fullToShortPathMap: Record<string, string>,
741
+ ): string {
742
+ // If the path is in fullToShortPathMap, use the short path as canonical
743
+ if (resolvedPath in fullToShortPathMap) {
744
+ return fullToShortPathMap[resolvedPath];
745
+ }
746
+ // Otherwise, the path itself is canonical
747
+ return resolvedPath;
748
+ }
749
+
750
+ /**
751
+ * Translate a child component path to a parent path using prop mappings.
752
+ *
753
+ * Given:
754
+ * - childPath: "selectedScenario.metadata.screenshotPaths[0]" (path in child's context)
755
+ * - childEquiv: { selectedScenario: "signature[0].selectedScenario" } (child's internal-to-prop mapping)
756
+ * - parentEquiv: { "ChildName().signature[0].selectedScenario": "selectedScenario" } (parent's prop assignments)
757
+ * - childName: "ChildName"
758
+ *
759
+ * Returns: "selectedScenario.metadata.screenshotPaths[0]" (path in parent's context)
760
+ *
761
+ * The translation works by:
762
+ * 1. Finding the root variable in the child path (e.g., "selectedScenario")
763
+ * 2. Looking up the child's equivalence to find the prop path (e.g., "signature[0].selectedScenario")
764
+ * 3. Building the full child prop path (e.g., "ChildName().signature[0].selectedScenario")
765
+ * 4. Looking up the parent's equivalence to find the parent path (e.g., "selectedScenario")
766
+ * 5. Replacing the root with the parent path and preserving the suffix
767
+ */
768
+ function translateChildPathToParent(
769
+ childPath: string,
770
+ childEquivalentSignatureVariables: Record<string, string | string[]>,
771
+ parentEquivalentSignatureVariables: Record<string, string | string[]>,
772
+ childName: string,
773
+ ): string | null {
774
+ // Extract the root variable from the child path
775
+ // e.g., "selectedScenario.metadata.screenshotPaths[0]" → "selectedScenario"
776
+ const dotIndex = childPath.indexOf('.');
777
+ const bracketIndex = childPath.indexOf('[');
778
+ let rootVar: string;
779
+ let suffix: string;
780
+
781
+ if (dotIndex === -1 && bracketIndex === -1) {
782
+ rootVar = childPath;
783
+ suffix = '';
784
+ } else if (dotIndex === -1) {
785
+ rootVar = childPath.slice(0, bracketIndex);
786
+ suffix = childPath.slice(bracketIndex);
787
+ } else if (bracketIndex === -1) {
788
+ rootVar = childPath.slice(0, dotIndex);
789
+ suffix = childPath.slice(dotIndex);
790
+ } else {
791
+ const firstIndex = Math.min(dotIndex, bracketIndex);
792
+ rootVar = childPath.slice(0, firstIndex);
793
+ suffix = childPath.slice(firstIndex);
794
+ }
795
+
796
+ // Look up the child's equivalence for this root variable
797
+ // e.g., childEquiv[selectedScenario] = "signature[0].selectedScenario"
798
+ // Handle array case (OR expressions) - use first element if array
799
+ const rawChildPropPath = childEquivalentSignatureVariables[rootVar];
800
+ const childPropPath = Array.isArray(rawChildPropPath)
801
+ ? rawChildPropPath[0]
802
+ : rawChildPropPath;
803
+
804
+ if (!childPropPath) {
805
+ // No mapping found - this might be internal state, not a prop
806
+ return null;
807
+ }
808
+
809
+ // Build the full child prop path as seen from parent
810
+ // e.g., "ChildName().signature[0].selectedScenario"
811
+ const fullChildPropPath = `${childName}().${childPropPath}`;
812
+
813
+ // Look up parent's equivalence to find what value was passed to this prop
814
+ // e.g., parentEquiv["ChildName().signature[0].selectedScenario"] = "selectedScenario"
815
+ // Handle array case (OR expressions) - use first element if array
816
+ const rawParentValue = parentEquivalentSignatureVariables[fullChildPropPath];
817
+ const parentValue = Array.isArray(rawParentValue)
818
+ ? rawParentValue[0]
819
+ : rawParentValue;
820
+
821
+ if (!parentValue) {
822
+ // No parent mapping found - log ALL parent keys that contain the childName
823
+ const relevantParentKeys = Object.keys(
824
+ parentEquivalentSignatureVariables,
825
+ ).filter((k) => k.includes(childName));
826
+ return null;
827
+ }
828
+
829
+ // Build the translated path: parentValue + suffix
830
+ // e.g., "selectedScenario" + ".metadata.screenshotPaths[0]"
831
+ const result = parentValue + suffix;
832
+ return result;
833
+ }
834
+
835
+ export default function generateExecutionFlowsFromConditionals(
836
+ args: GenerateFlowsFromConditionalsArgs,
837
+ ): ExecutionFlow[] {
838
+ const {
839
+ conditionalUsages,
840
+ compoundConditionals,
841
+ attributesMap,
842
+ equivalentSignatureVariables,
843
+ fullToShortPathMap,
844
+ childComponentData,
845
+ derivedVariables,
846
+ sourceEquivalencies,
847
+ } = args;
848
+
849
+ const flows: ExecutionFlow[] = [];
850
+ const seenFlowIds = new Set<string>();
851
+
852
+ // Track normalized resolved paths to prevent duplicate flows
853
+ // This handles the case where we have usages for both:
854
+ // - "hasNewerVersion" (short path from destructured variable)
855
+ // - "useLoaderData<LoaderData>().functionCallReturnValue.hasNewerVersion" (full path)
856
+ // Both resolve to the same logical data source, so we only want ONE set of flows.
857
+ const seenNormalizedPaths = new Set<string>();
858
+
859
+ // Track which usages are part of compound conditionals (to avoid duplicates)
860
+ const compoundChainIds = new Set(
861
+ compoundConditionals.map((c) => c.chainId).filter(Boolean),
862
+ );
863
+
864
+ // Process individual conditional usages
865
+ for (const [_path, usages] of Object.entries(conditionalUsages)) {
866
+ for (const usage of usages) {
867
+ // Skip usages that are part of compound conditionals (handled separately)
868
+ if (usage.chainId && compoundChainIds.has(usage.chainId)) {
869
+ continue;
870
+ }
871
+
872
+ // First, try to use pre-computed sourceDataPath if available
873
+ let resolvedPath: string | null = null;
874
+
875
+ if (usage.sourceDataPath) {
876
+ // Clean up the sourceDataPath - it may have redundant scope prefixes
877
+ // e.g., "useLoaderData<LoaderData>.useLoaderData<LoaderData>().functionCallReturnValue.entity.sha"
878
+ // should become "useLoaderData<LoaderData>().functionCallReturnValue.entity.sha"
879
+ // Returns null for malformed paths (e.g., chained function calls like fetch().json())
880
+ const cleanedPath = cleanSourceDataPath(usage.sourceDataPath);
881
+
882
+ if (cleanedPath) {
883
+ // Verify the cleaned path exists in attributesMap
884
+ const pathMatch = findInAttributesMapForPath(
885
+ cleanedPath,
886
+ attributesMap,
887
+ fullToShortPathMap,
888
+ );
889
+ if (pathMatch) {
890
+ resolvedPath = pathMatch;
891
+ }
892
+ }
893
+ // If cleanedPath is null, fall through to use fallback resolution
894
+ }
895
+
896
+ // Fall back to resolution via equivalentSignatureVariables
897
+ if (!resolvedPath) {
898
+ const resolution = resolvePathToControllable(
899
+ usage.path,
900
+ attributesMap,
901
+ equivalentSignatureVariables,
902
+ fullToShortPathMap,
903
+ );
904
+
905
+ if (resolution.isControllable && resolution.resolvedPath) {
906
+ resolvedPath = resolution.resolvedPath;
907
+ }
908
+ }
909
+
910
+ // If still not resolved, try using derivedFrom info to find the source path
911
+ // This handles cases like: const hasAnalysis = analysis !== null
912
+ // where hasAnalysis is not in attributesMap but analysis is
913
+ if (!resolvedPath && usage.derivedFrom) {
914
+ const { operation, sourcePath, sourcePaths, comparedValue } =
915
+ usage.derivedFrom;
916
+
917
+ // For single-source derivations (notNull, equals, etc.)
918
+ if (sourcePath) {
919
+ const resolution = resolvePathToControllable(
920
+ sourcePath,
921
+ attributesMap,
922
+ equivalentSignatureVariables,
923
+ fullToShortPathMap,
924
+ );
925
+
926
+ if (resolution.isControllable && resolution.resolvedPath) {
927
+ resolvedPath = resolution.resolvedPath;
928
+ }
929
+ }
930
+
931
+ // For equals/notEquals derivations with comparedValue, generate comparison flows
932
+ // e.g., canEdit derived from user.role === 'admin'
933
+ // When canEdit is used in truthiness check, we need:
934
+ // - Truthy flow: user.role = 'admin' (comparison: 'equals')
935
+ // - Falsy flow: user.role != 'admin' (comparison: 'notEquals')
936
+ if (
937
+ (operation === 'equals' || operation === 'notEquals') &&
938
+ comparedValue !== undefined &&
939
+ resolvedPath &&
940
+ usage.conditionType === 'truthiness'
941
+ ) {
942
+ const baseName = generateNameFromPath(usage.path);
943
+ const impact: ExecutionFlow['impact'] = usage.controlsJsxRendering
944
+ ? 'high'
945
+ : 'medium';
946
+
947
+ const isNegated = usage.isNegated ?? false;
948
+
949
+ // For equals derivation:
950
+ // - Truthy check (!negated): needs value = comparedValue (equals)
951
+ // - Falsy check (negated): needs value != comparedValue (notEquals)
952
+ // For notEquals derivation: inverse of above
953
+ const isEqualsDerivation = operation === 'equals';
954
+ const truthyNeedsEquals = isEqualsDerivation !== isNegated;
955
+
956
+ // Generate truthy flow
957
+ const truthyFlow: ExecutionFlow = {
958
+ id: generateFlowId(usage.path, 'truthy'),
959
+ name: `${baseName} True`,
960
+ description: `When ${baseName.toLowerCase()} is truthy (${resolvedPath} ${truthyNeedsEquals ? '=' : '!='} ${comparedValue})`,
961
+ requiredValues: [
962
+ {
963
+ attributePath: stripLengthSuffix(resolvedPath),
964
+ value: comparedValue,
965
+ comparison: truthyNeedsEquals ? 'equals' : 'notEquals',
966
+ valueType: inferValueType(comparedValue),
967
+ },
968
+ ],
969
+ impact,
970
+ sourceLocation: usage.sourceLocation
971
+ ? {
972
+ lineNumber: usage.sourceLocation.lineNumber,
973
+ column: usage.sourceLocation.column,
974
+ }
975
+ : undefined,
976
+ codeSnippet: usage.sourceLocation?.codeSnippet,
977
+ };
978
+
979
+ // Generate falsy flow
980
+ const falsyFlow: ExecutionFlow = {
981
+ id: generateFlowId(usage.path, 'falsy'),
982
+ name: `${baseName} False`,
983
+ description: `When ${baseName.toLowerCase()} is falsy (${resolvedPath} ${truthyNeedsEquals ? '!=' : '='} ${comparedValue})`,
984
+ requiredValues: [
985
+ {
986
+ attributePath: stripLengthSuffix(resolvedPath),
987
+ value: comparedValue,
988
+ comparison: truthyNeedsEquals ? 'notEquals' : 'equals',
989
+ valueType: inferValueType(comparedValue),
990
+ },
991
+ ],
992
+ impact,
993
+ sourceLocation: usage.sourceLocation
994
+ ? {
995
+ lineNumber: usage.sourceLocation.lineNumber,
996
+ column: usage.sourceLocation.column,
997
+ }
998
+ : undefined,
999
+ codeSnippet: usage.sourceLocation?.codeSnippet,
1000
+ };
1001
+
1002
+ // Add flows and skip normal flow generation
1003
+ if (!seenFlowIds.has(truthyFlow.id)) {
1004
+ seenFlowIds.add(truthyFlow.id);
1005
+ flows.push(truthyFlow);
1006
+ }
1007
+ if (!seenFlowIds.has(falsyFlow.id)) {
1008
+ seenFlowIds.add(falsyFlow.id);
1009
+ flows.push(falsyFlow);
1010
+ }
1011
+
1012
+ continue;
1013
+ }
1014
+
1015
+ // For OR derivations with negation, we need ALL sources to be falsy
1016
+ // e.g., !isBusy where isBusy = isRunning || isQueued || isPending
1017
+ // For the falsy flow, ALL sources must be falsy
1018
+ if (
1019
+ operation === 'or' &&
1020
+ usage.conditionType === 'truthiness' &&
1021
+ usage.isNegated === true &&
1022
+ sourcePaths &&
1023
+ sourcePaths.length > 0
1024
+ ) {
1025
+ // Use expandDerivedVariableToSources to recursively resolve all sources
1026
+ const allSources = expandDerivedVariableToSources(
1027
+ usage.path,
1028
+ conditionalUsages,
1029
+ attributesMap,
1030
+ equivalentSignatureVariables,
1031
+ fullToShortPathMap,
1032
+ new Set(),
1033
+ derivedVariables,
1034
+ );
1035
+
1036
+ if (allSources.length > 0) {
1037
+ // Generate a compound-style flow with all sources set to falsy
1038
+ const baseName = generateNameFromPath(usage.path);
1039
+ const impact: ExecutionFlow['impact'] = usage.controlsJsxRendering
1040
+ ? 'high'
1041
+ : 'medium';
1042
+
1043
+ const requiredValues: ExecutionFlow['requiredValues'] =
1044
+ allSources.map((source) => ({
1045
+ attributePath: source.path,
1046
+ value: 'falsy',
1047
+ comparison: 'falsy' as const,
1048
+ valueType: 'boolean' as const,
1049
+ }));
1050
+
1051
+ // Create a single falsy flow with all sources
1052
+ const falsyFlow: ExecutionFlow = {
1053
+ id: generateFlowId(usage.path, 'falsy'),
1054
+ name: `${baseName} False`,
1055
+ description: `When ${baseName.toLowerCase()} is falsy (all sources are falsy)`,
1056
+ requiredValues,
1057
+ impact,
1058
+ sourceLocation: usage.sourceLocation
1059
+ ? {
1060
+ lineNumber: usage.sourceLocation.lineNumber,
1061
+ column: usage.sourceLocation.column,
1062
+ }
1063
+ : undefined,
1064
+ codeSnippet: usage.sourceLocation?.codeSnippet,
1065
+ };
1066
+
1067
+ // Create a truthy flow - for OR, ANY source being truthy is sufficient
1068
+ // We use the first resolvable source for the truthy flow
1069
+ const firstSource = allSources[0];
1070
+ const truthyFlow: ExecutionFlow = {
1071
+ id: generateFlowId(usage.path, 'truthy'),
1072
+ name: `${baseName} True`,
1073
+ description: `When ${baseName.toLowerCase()} is truthy`,
1074
+ requiredValues: [
1075
+ {
1076
+ attributePath: firstSource.path,
1077
+ value: 'truthy',
1078
+ comparison: 'truthy',
1079
+ valueType: 'boolean',
1080
+ },
1081
+ ],
1082
+ impact,
1083
+ sourceLocation: usage.sourceLocation
1084
+ ? {
1085
+ lineNumber: usage.sourceLocation.lineNumber,
1086
+ column: usage.sourceLocation.column,
1087
+ }
1088
+ : undefined,
1089
+ codeSnippet: usage.sourceLocation?.codeSnippet,
1090
+ };
1091
+
1092
+ // Add both flows (falsy needs all sources, truthy needs one)
1093
+ if (!seenFlowIds.has(falsyFlow.id)) {
1094
+ seenFlowIds.add(falsyFlow.id);
1095
+ flows.push(falsyFlow);
1096
+ }
1097
+ if (!seenFlowIds.has(truthyFlow.id)) {
1098
+ seenFlowIds.add(truthyFlow.id);
1099
+ flows.push(truthyFlow);
1100
+ }
1101
+
1102
+ // Skip the normal flow generation for this usage
1103
+ continue;
1104
+ }
1105
+ }
1106
+
1107
+ // For AND derivations without negation, we need ALL sources to be truthy
1108
+ // e.g., isReady where isReady = hasData && isLoaded && isValid
1109
+ // For the truthy flow, ALL sources must be truthy
1110
+ // For negated AND (!isReady), ANY source being falsy is sufficient (fallback behavior)
1111
+ if (
1112
+ operation === 'and' &&
1113
+ usage.conditionType === 'truthiness' &&
1114
+ usage.isNegated !== true &&
1115
+ sourcePaths &&
1116
+ sourcePaths.length > 0
1117
+ ) {
1118
+ // Use expandDerivedVariableToSources to recursively resolve all sources
1119
+ const allSources = expandDerivedVariableToSources(
1120
+ usage.path,
1121
+ conditionalUsages,
1122
+ attributesMap,
1123
+ equivalentSignatureVariables,
1124
+ fullToShortPathMap,
1125
+ new Set(),
1126
+ derivedVariables,
1127
+ );
1128
+
1129
+ if (allSources.length > 0) {
1130
+ // Generate a compound-style flow with all sources set to truthy
1131
+ const baseName = generateNameFromPath(usage.path);
1132
+ const impact: ExecutionFlow['impact'] = usage.controlsJsxRendering
1133
+ ? 'high'
1134
+ : 'medium';
1135
+
1136
+ const requiredValues: ExecutionFlow['requiredValues'] =
1137
+ allSources.map((source) => ({
1138
+ attributePath: source.path,
1139
+ value: 'truthy',
1140
+ comparison: 'truthy' as const,
1141
+ valueType: 'boolean' as const,
1142
+ }));
1143
+
1144
+ // Create a truthy flow with all sources
1145
+ const truthyFlow: ExecutionFlow = {
1146
+ id: generateFlowId(usage.path, 'truthy'),
1147
+ name: `${baseName} True`,
1148
+ description: `When ${baseName.toLowerCase()} is truthy (all sources are truthy)`,
1149
+ requiredValues,
1150
+ impact,
1151
+ sourceLocation: usage.sourceLocation
1152
+ ? {
1153
+ lineNumber: usage.sourceLocation.lineNumber,
1154
+ column: usage.sourceLocation.column,
1155
+ }
1156
+ : undefined,
1157
+ codeSnippet: usage.sourceLocation?.codeSnippet,
1158
+ };
1159
+
1160
+ // Create a falsy flow - for AND, ANY source being falsy is sufficient
1161
+ // We use the first resolvable source for the falsy flow
1162
+ const firstSource = allSources[0];
1163
+ const falsyFlow: ExecutionFlow = {
1164
+ id: generateFlowId(usage.path, 'falsy'),
1165
+ name: `${baseName} False`,
1166
+ description: `When ${baseName.toLowerCase()} is falsy`,
1167
+ requiredValues: [
1168
+ {
1169
+ attributePath: firstSource.path,
1170
+ value: 'falsy',
1171
+ comparison: 'falsy',
1172
+ valueType: 'boolean',
1173
+ },
1174
+ ],
1175
+ impact,
1176
+ sourceLocation: usage.sourceLocation
1177
+ ? {
1178
+ lineNumber: usage.sourceLocation.lineNumber,
1179
+ column: usage.sourceLocation.column,
1180
+ }
1181
+ : undefined,
1182
+ codeSnippet: usage.sourceLocation?.codeSnippet,
1183
+ };
1184
+
1185
+ // Add both flows (truthy needs all sources, falsy needs one)
1186
+ if (!seenFlowIds.has(truthyFlow.id)) {
1187
+ seenFlowIds.add(truthyFlow.id);
1188
+ flows.push(truthyFlow);
1189
+ }
1190
+ if (!seenFlowIds.has(falsyFlow.id)) {
1191
+ seenFlowIds.add(falsyFlow.id);
1192
+ flows.push(falsyFlow);
1193
+ }
1194
+
1195
+ // Skip the normal flow generation for this usage
1196
+ continue;
1197
+ }
1198
+ }
1199
+
1200
+ // For multi-source derivations (or, and) without special handling,
1201
+ // try the first resolvable path as a fallback
1202
+ if (!resolvedPath && sourcePaths && sourcePaths.length > 0) {
1203
+ for (const sp of sourcePaths) {
1204
+ const resolution = resolvePathToControllable(
1205
+ sp,
1206
+ attributesMap,
1207
+ equivalentSignatureVariables,
1208
+ fullToShortPathMap,
1209
+ );
1210
+
1211
+ if (resolution.isControllable && resolution.resolvedPath) {
1212
+ resolvedPath = resolution.resolvedPath;
1213
+ break;
1214
+ }
1215
+ }
1216
+ }
1217
+ }
1218
+
1219
+ if (!resolvedPath) {
1220
+ // Path is not controllable - skip (no invalid flows possible)
1221
+ continue;
1222
+ }
1223
+
1224
+ // Normalize the resolved path to detect duplicates
1225
+ // E.g., both "hasNewerVersion" and "useLoaderData<...>().hasNewerVersion"
1226
+ // should normalize to the same canonical path
1227
+ const normalizedPath = normalizePathForDeduplication(
1228
+ resolvedPath,
1229
+ fullToShortPathMap,
1230
+ );
1231
+
1232
+ // Skip if we've already generated flows for this normalized path
1233
+ // This prevents duplicate flows when we have usages for both short and full paths
1234
+ if (seenNormalizedPaths.has(normalizedPath)) {
1235
+ continue;
1236
+ }
1237
+ seenNormalizedPaths.add(normalizedPath);
1238
+
1239
+ // Generate flows for this controllable usage
1240
+ const usageFlows = generateFlowsFromUsage(usage, resolvedPath);
1241
+
1242
+ for (const flow of usageFlows) {
1243
+ // Deduplicate by flow ID
1244
+ if (!seenFlowIds.has(flow.id)) {
1245
+ seenFlowIds.add(flow.id);
1246
+ flows.push(flow);
1247
+ }
1248
+ }
1249
+ }
1250
+ }
1251
+
1252
+ // Process compound conditionals
1253
+ for (const compound of compoundConditionals) {
1254
+ // Expand OR groups into separate condition sets
1255
+ // For example, `A && (B || C)` becomes [[A, B], [A, C]]
1256
+ const expandedConditionSets = expandOrGroups(compound.conditions);
1257
+
1258
+ // Process each expanded condition set as a separate potential flow
1259
+ for (const conditionSet of expandedConditionSets) {
1260
+ // First, check if ALL paths in this condition set are controllable (or can be expanded to controllable sources)
1261
+ const resolvedPaths = new Map<string, string>();
1262
+ // Track expanded sources for derived variables (path -> array of expanded sources)
1263
+ const expandedSources = new Map<
1264
+ string,
1265
+ Array<{ path: string; operation?: DerivedVariableOperation }>
1266
+ >();
1267
+ let allControllable = true;
1268
+
1269
+ for (const condition of conditionSet) {
1270
+ // Check if this condition path has derivation info
1271
+ // First check conditionalUsages, then fall back to derivedVariables
1272
+ const usagesForPath = conditionalUsages[condition.path];
1273
+ let derivedFromInfo = usagesForPath?.find(
1274
+ (u) => u.derivedFrom?.operation,
1275
+ )?.derivedFrom;
1276
+
1277
+ // CRITICAL: Also check derivedVariables for intermediate derived variables
1278
+ if (!derivedFromInfo && derivedVariables?.[condition.path]) {
1279
+ derivedFromInfo = derivedVariables[condition.path];
1280
+ }
1281
+
1282
+ if (derivedFromInfo) {
1283
+ // This is a derived variable - expand to its sources
1284
+ const sources = expandDerivedVariableToSources(
1285
+ condition.path,
1286
+ conditionalUsages,
1287
+ attributesMap,
1288
+ equivalentSignatureVariables,
1289
+ fullToShortPathMap,
1290
+ new Set(),
1291
+ derivedVariables,
1292
+ );
1293
+
1294
+ if (sources.length > 0) {
1295
+ // Store the expanded sources for this condition
1296
+ expandedSources.set(condition.path, sources);
1297
+ // Use the first source's path for the resolvedPaths map (for ID generation)
1298
+ resolvedPaths.set(condition.path, sources[0].path);
1299
+ } else {
1300
+ // Derived variable but no controllable sources found
1301
+ allControllable = false;
1302
+ break;
1303
+ }
1304
+ } else {
1305
+ // Not a derived variable - resolve directly
1306
+ const resolution = resolvePathToControllable(
1307
+ condition.path,
1308
+ attributesMap,
1309
+ equivalentSignatureVariables,
1310
+ fullToShortPathMap,
1311
+ );
1312
+
1313
+ if (!resolution.isControllable || !resolution.resolvedPath) {
1314
+ allControllable = false;
1315
+ break;
1316
+ }
1317
+
1318
+ resolvedPaths.set(condition.path, resolution.resolvedPath);
1319
+ }
1320
+ }
1321
+
1322
+ // Only create a flow if ALL paths are controllable
1323
+ if (allControllable && resolvedPaths.size > 0) {
1324
+ // If any conditions were expanded from derived variables, we need to build a custom flow
1325
+ if (expandedSources.size > 0) {
1326
+ const requiredValues: ExecutionFlow['requiredValues'] = [];
1327
+
1328
+ for (const condition of conditionSet) {
1329
+ const sources = expandedSources.get(condition.path);
1330
+
1331
+ if (sources) {
1332
+ // This condition was expanded - add all its sources
1333
+ // Determine the required value based on condition type and derivation operation
1334
+ const usagesForPath = conditionalUsages[condition.path];
1335
+ let expandedDerivedFrom = usagesForPath?.find(
1336
+ (u) => u.derivedFrom?.operation,
1337
+ )?.derivedFrom;
1338
+
1339
+ // Also check derivedVariables for intermediate derived variables
1340
+ if (!expandedDerivedFrom && derivedVariables?.[condition.path]) {
1341
+ expandedDerivedFrom = derivedVariables[condition.path];
1342
+ }
1343
+ const operation = expandedDerivedFrom?.operation;
1344
+
1345
+ for (const source of sources) {
1346
+ // For OR-derived truthy: ANY source truthy
1347
+ // For AND-derived truthy: ALL sources truthy
1348
+ // For negated: inverse
1349
+ let value: string;
1350
+ let comparison: ExecutionFlow['requiredValues'][0]['comparison'];
1351
+
1352
+ if (condition.conditionType === 'truthiness') {
1353
+ const isNegated = condition.isNegated === true;
1354
+ // For OR: truthy needs ANY source truthy, falsy needs ALL sources falsy
1355
+ // For AND: truthy needs ALL sources truthy, falsy needs ANY source falsy
1356
+ // In compound conditionals, we generate the truthy path by default
1357
+ // (the compound expression must be truthy)
1358
+ if (operation === 'or') {
1359
+ // For OR-derived, truthy means we need at least one source truthy
1360
+ // We'll use the first source as truthy (simplification)
1361
+ value = isNegated ? 'falsy' : 'truthy';
1362
+ } else if (operation === 'and') {
1363
+ // For AND-derived, truthy means ALL sources truthy
1364
+ value = isNegated ? 'falsy' : 'truthy';
1365
+ } else {
1366
+ value = isNegated ? 'falsy' : 'truthy';
1367
+ }
1368
+ comparison = isNegated ? 'falsy' : 'truthy';
1369
+ } else {
1370
+ value = 'truthy';
1371
+ comparison = 'truthy';
1372
+ }
1373
+
1374
+ requiredValues.push({
1375
+ attributePath: source.path,
1376
+ value,
1377
+ comparison,
1378
+ valueType: 'boolean' as const,
1379
+ });
1380
+ }
1381
+ } else {
1382
+ // This condition was resolved directly
1383
+ const resolvedPath = resolvedPaths.get(condition.path);
1384
+ if (resolvedPath) {
1385
+ let value: string;
1386
+ let comparison: ExecutionFlow['requiredValues'][0]['comparison'];
1387
+
1388
+ if (condition.conditionType === 'truthiness') {
1389
+ value = condition.isNegated ? 'falsy' : 'truthy';
1390
+ comparison = condition.isNegated ? 'falsy' : 'truthy';
1391
+ } else {
1392
+ value =
1393
+ condition.requiredValue?.toString() ??
1394
+ condition.comparedValues?.[0] ??
1395
+ 'truthy';
1396
+ comparison = 'equals';
1397
+ }
1398
+
1399
+ requiredValues.push({
1400
+ attributePath: stripLengthSuffix(resolvedPath),
1401
+ value,
1402
+ comparison,
1403
+ valueType: inferValueType(value),
1404
+ });
1405
+ }
1406
+ }
1407
+ }
1408
+
1409
+ if (requiredValues.length > 0) {
1410
+ const impact: ExecutionFlow['impact'] =
1411
+ compound.controlsJsxRendering ? 'high' : 'medium';
1412
+
1413
+ // Generate a combined ID from all paths
1414
+ const pathParts = requiredValues
1415
+ .map((rv) => {
1416
+ const name = generateNameFromPath(rv.attributePath);
1417
+ return name.toLowerCase().replace(/\s+/g, '-');
1418
+ })
1419
+ .join('-and-');
1420
+
1421
+ const compoundFlow: ExecutionFlow = {
1422
+ id: `${pathParts}-${requiredValues.map((rv) => rv.value).join('-')}`,
1423
+ name: generateNameFromPath(requiredValues[0].attributePath),
1424
+ description: `When ${requiredValues.map((rv) => `${generateNameFromPath(rv.attributePath).toLowerCase()} is ${rv.value}`).join(' and ')}`,
1425
+ impact,
1426
+ requiredValues,
1427
+ sourceLocation: compound.sourceLocation,
1428
+ };
1429
+
1430
+ if (!seenFlowIds.has(compoundFlow.id)) {
1431
+ seenFlowIds.add(compoundFlow.id);
1432
+ flows.push(compoundFlow);
1433
+ }
1434
+ }
1435
+ } else {
1436
+ // No derived variables - use the original generateFlowFromCompound
1437
+ // Create a modified compound with just this condition set
1438
+ const modifiedCompound = {
1439
+ ...compound,
1440
+ conditions: conditionSet,
1441
+ };
1442
+ const compoundFlow = generateFlowFromCompound(
1443
+ modifiedCompound,
1444
+ resolvedPaths,
1445
+ );
1446
+ if (compoundFlow && !seenFlowIds.has(compoundFlow.id)) {
1447
+ seenFlowIds.add(compoundFlow.id);
1448
+ flows.push(compoundFlow);
1449
+ }
1450
+ }
1451
+ }
1452
+ }
1453
+ }
1454
+
1455
+ // Process child component conditional usages
1456
+ // Translate child paths to parent paths and merge flows
1457
+ if (childComponentData) {
1458
+ for (const [childName, childData] of Object.entries(childComponentData)) {
1459
+ // First, resolve gating conditions to get required values that must be added to all child flows
1460
+ const gatingRequiredValues: Array<{
1461
+ attributePath: string;
1462
+ value: string;
1463
+ comparison:
1464
+ | 'truthy'
1465
+ | 'falsy'
1466
+ | 'equals'
1467
+ | 'length>'
1468
+ | 'length<'
1469
+ | 'exists'
1470
+ | 'not-exists';
1471
+ }> = [];
1472
+
1473
+ if (childData.gatingConditions) {
1474
+ for (const gatingCondition of childData.gatingConditions) {
1475
+ // Try to resolve via derivedFrom first
1476
+ let gatingPath = gatingCondition.path;
1477
+ if (gatingCondition.derivedFrom?.sourcePath) {
1478
+ gatingPath = gatingCondition.derivedFrom.sourcePath;
1479
+ }
1480
+
1481
+ // Fix 32: Handle comparison expressions like "activeTab === 'scenarios'"
1482
+ // Extract the variable name and the compared value
1483
+ const comparisonMatch = gatingPath.match(
1484
+ /^([a-zA-Z_][a-zA-Z0-9_]*)\s*(===?|!==?)\s*['"]?([^'"]+)['"]?$/,
1485
+ );
1486
+ if (comparisonMatch) {
1487
+ const [, varName, operator, comparedValue] = comparisonMatch;
1488
+
1489
+ // Try to resolve the variable name
1490
+ const varResolution = resolvePathToControllable(
1491
+ varName,
1492
+ attributesMap,
1493
+ equivalentSignatureVariables,
1494
+ fullToShortPathMap,
1495
+ );
1496
+
1497
+ // Only use controllable paths for gating conditions (whitelist approach).
1498
+ // Do NOT fall back to equivalentSignatureVariables because those may contain
1499
+ // uncontrollable paths like useState that cannot be mocked.
1500
+ let resolvedVarPath: string | null = null;
1501
+ if (varResolution.isControllable && varResolution.resolvedPath) {
1502
+ resolvedVarPath = varResolution.resolvedPath;
1503
+ }
1504
+ // Note: We intentionally do NOT fall back to equivalentSignatureVariables here
1505
+ // because that would allow uncontrollable paths (like useState) to be added
1506
+ // as gating conditions.
1507
+
1508
+ if (resolvedVarPath) {
1509
+ const isNegated = (gatingCondition as any).isNegated === true;
1510
+ const isNotEquals = operator === '!=' || operator === '!==';
1511
+ // Determine the effective value for this gating condition
1512
+ // If condition is "activeTab === 'scenarios'" and NOT negated, flow needs activeTab = 'scenarios'
1513
+ // If condition is "activeTab === 'scenarios'" and IS negated, flow needs activeTab != 'scenarios' (falsy/other value)
1514
+ // If condition is "activeTab !== 'scenarios'" and NOT negated, flow needs activeTab != 'scenarios'
1515
+ // XOR logic: isNegated XOR isNotEquals
1516
+ const needsExactValue = isNegated !== isNotEquals;
1517
+
1518
+ gatingRequiredValues.push({
1519
+ attributePath: resolvedVarPath,
1520
+ value: needsExactValue ? 'falsy' : comparedValue,
1521
+ comparison: needsExactValue ? 'falsy' : 'equals',
1522
+ });
1523
+ continue; // Skip to next gating condition
1524
+ }
1525
+ }
1526
+
1527
+ // Fix 31: Handle compound gating conditions (containing && or ||)
1528
+ // e.g., "isEditMode && selectedScenario" should be parsed into individual paths
1529
+ const isAndExpression = gatingPath.includes(' && ');
1530
+ const isOrExpression = gatingPath.includes(' || ');
1531
+ const isCompoundExpression = isAndExpression || isOrExpression;
1532
+
1533
+ if (isCompoundExpression) {
1534
+ // Parse the compound expression into individual variable names
1535
+ // Split on && and || (with optional spaces)
1536
+ const parts = gatingPath.split(/\s*(?:&&|\|\|)\s*/);
1537
+ const isNegated = (gatingCondition as any).isNegated === true;
1538
+
1539
+ // Fix 37: Apply DeMorgan's law correctly for compound conditions
1540
+ // - !(A && B) = !A || !B: EITHER A is false OR B is false (can't know which)
1541
+ // - !(A || B) = !A && !B: BOTH must be false
1542
+ // - (A && B): BOTH must be true
1543
+ // - (A || B): EITHER is true (can't know which)
1544
+ //
1545
+ // We should only add gating requirements when we can definitively say
1546
+ // all parts must have the same value. This is true for:
1547
+ // - Non-negated &&: all parts must be truthy
1548
+ // - Negated ||: all parts must be falsy (DeMorgan: !(A || B) = !A && !B)
1549
+ //
1550
+ // We should NOT add gating requirements when either part could be true/false:
1551
+ // - Negated && (DeMorgan: !(A && B) = !A || !B): can't constrain both to falsy
1552
+ // - Non-negated ||: can't constrain both to truthy
1553
+ const shouldSkipGating =
1554
+ (isAndExpression && isNegated) || // !(A && B) - either could be falsy
1555
+ (isOrExpression && !isNegated); // (A || B) - either could be truthy
1556
+
1557
+ if (shouldSkipGating) {
1558
+ // Don't add gating requirements for this compound condition
1559
+ // The child flow's own requirements will determine what values are needed
1560
+ } else {
1561
+ for (const part of parts) {
1562
+ // Clean up the part (remove parentheses, negation, etc.)
1563
+ const cleanPart = part
1564
+ .replace(/^\(+|\)+$/g, '') // Remove leading/trailing parens
1565
+ .replace(/^!+/, '') // Remove leading negation
1566
+ .trim();
1567
+
1568
+ if (!cleanPart) continue;
1569
+
1570
+ // Try to resolve this individual path
1571
+ const partResolution = resolvePathToControllable(
1572
+ cleanPart,
1573
+ attributesMap,
1574
+ equivalentSignatureVariables,
1575
+ fullToShortPathMap,
1576
+ );
1577
+
1578
+ if (
1579
+ partResolution.isControllable &&
1580
+ partResolution.resolvedPath
1581
+ ) {
1582
+ // For non-negated &&: all parts must be truthy
1583
+ // For negated ||: all parts must be falsy (DeMorgan: !(A || B) = !A && !B)
1584
+ gatingRequiredValues.push({
1585
+ attributePath: stripLengthSuffix(
1586
+ partResolution.resolvedPath,
1587
+ ),
1588
+ value: isNegated ? 'falsy' : 'truthy',
1589
+ comparison: isNegated ? 'falsy' : 'truthy',
1590
+ });
1591
+ }
1592
+ }
1593
+ }
1594
+ } else {
1595
+ // Simple gating condition (single path)
1596
+ // Resolve the gating path in parent context
1597
+ const gatingResolution = resolvePathToControllable(
1598
+ gatingPath,
1599
+ attributesMap,
1600
+ equivalentSignatureVariables,
1601
+ fullToShortPathMap,
1602
+ );
1603
+
1604
+ // Only use controllable paths for gating conditions (whitelist approach).
1605
+ // Do NOT fall back to equivalentSignatureVariables because those may contain
1606
+ // uncontrollable paths like useState that cannot be mocked.
1607
+ let resolvedGatingPath: string | null = null;
1608
+ if (
1609
+ gatingResolution.isControllable &&
1610
+ gatingResolution.resolvedPath
1611
+ ) {
1612
+ resolvedGatingPath = gatingResolution.resolvedPath;
1613
+ }
1614
+ // Note: We intentionally do NOT fall back to equivalentSignatureVariables here
1615
+ // because that would allow uncontrollable paths (like useState) to be added
1616
+ // as gating conditions.
1617
+
1618
+ if (resolvedGatingPath) {
1619
+ // For truthiness conditions on gating, check if the condition is negated
1620
+ // e.g., ternary else branch: isError ? <ErrorView /> : <SuccessView />
1621
+ // SuccessView has isNegated: true, meaning it renders when isError is falsy
1622
+ const isNegated = (gatingCondition as any).isNegated === true;
1623
+ gatingRequiredValues.push({
1624
+ attributePath: resolvedGatingPath,
1625
+ value: isNegated ? 'falsy' : 'truthy',
1626
+ comparison: isNegated ? 'falsy' : 'truthy',
1627
+ });
1628
+ }
1629
+ }
1630
+ }
1631
+ }
1632
+
1633
+ // Track which child usages are part of compound conditionals (to avoid duplicates)
1634
+ // Fix 33: Only skip usages that are part of compound conditionals, not all usages with chainIds
1635
+ const childCompoundChainIds = new Set(
1636
+ childData.compoundConditionals.map((c) => c.chainId).filter(Boolean),
1637
+ );
1638
+
1639
+ for (const [_path, usages] of Object.entries(
1640
+ childData.conditionalUsages,
1641
+ )) {
1642
+ for (const usage of usages) {
1643
+ // Debug logging (disabled - set to true for troubleshooting child flow resolution)
1644
+ const shouldDebugChild = false;
1645
+
1646
+ // Skip usages that are part of compound conditionals (handled separately)
1647
+ // Fix 33: Only skip if the chainId is in the child's compound conditionals
1648
+ if (usage.chainId && childCompoundChainIds.has(usage.chainId)) {
1649
+ continue;
1650
+ }
1651
+
1652
+ // Determine the child path to translate
1653
+ let childPath = usage.path;
1654
+
1655
+ // If the usage has derivedFrom, use the source path instead
1656
+ if (usage.derivedFrom?.sourcePath) {
1657
+ childPath = usage.derivedFrom.sourcePath;
1658
+ }
1659
+
1660
+ if (shouldDebugChild) {
1661
+ console.log(
1662
+ `[DEBUG CHILD ${childName}] Processing usage path: ${usage.path}`,
1663
+ );
1664
+ console.log(
1665
+ `[DEBUG CHILD ${childName}] childPath (after derivedFrom): ${childPath}`,
1666
+ );
1667
+ console.log(
1668
+ `[DEBUG CHILD ${childName}] sourceDataPath: ${usage.sourceDataPath}`,
1669
+ );
1670
+ }
1671
+
1672
+ // Translate the child path to a parent path
1673
+ let translatedPath = translateChildPathToParent(
1674
+ childPath,
1675
+ childData.equivalentSignatureVariables,
1676
+ equivalentSignatureVariables,
1677
+ childName,
1678
+ );
1679
+
1680
+ if (shouldDebugChild) {
1681
+ console.log(
1682
+ `[DEBUG CHILD ${childName}] translatedPath (from translateChildPathToParent): ${translatedPath}`,
1683
+ );
1684
+ }
1685
+
1686
+ // If translation failed but we have sourceDataPath, try to extract the prop path from it
1687
+ // sourceDataPath format: "ChildName.signature[n].propPath.rest" → extract "propPath.rest"
1688
+ if (!translatedPath && usage.sourceDataPath) {
1689
+ const signatureMatch = usage.sourceDataPath.match(
1690
+ /\.signature\[\d+\]\.(.+)$/,
1691
+ );
1692
+ if (signatureMatch) {
1693
+ translatedPath = signatureMatch[1];
1694
+ if (shouldDebugChild) {
1695
+ console.log(
1696
+ `[DEBUG CHILD ${childName}] translatedPath (from sourceDataPath regex): ${translatedPath}`,
1697
+ );
1698
+ }
1699
+ }
1700
+ }
1701
+
1702
+ if (!translatedPath) {
1703
+ // Could not translate - skip this usage
1704
+ if (shouldDebugChild) {
1705
+ console.log(
1706
+ `[DEBUG CHILD ${childName}] SKIPPED - no translation found`,
1707
+ );
1708
+ }
1709
+ continue;
1710
+ }
1711
+
1712
+ // Now resolve the translated path in the parent context
1713
+ // First, try standard resolution
1714
+ const resolution = resolvePathToControllable(
1715
+ translatedPath,
1716
+ attributesMap,
1717
+ equivalentSignatureVariables,
1718
+ fullToShortPathMap,
1719
+ );
1720
+
1721
+ if (shouldDebugChild) {
1722
+ console.log(
1723
+ `[DEBUG CHILD ${childName}] resolvePathToControllable result:`,
1724
+ );
1725
+ console.log(
1726
+ `[DEBUG CHILD ${childName}] isControllable: ${resolution.isControllable}`,
1727
+ );
1728
+ console.log(
1729
+ `[DEBUG CHILD ${childName}] resolvedPath: ${resolution.resolvedPath}`,
1730
+ );
1731
+ console.log(
1732
+ `[DEBUG CHILD ${childName}] chain: ${resolution.resolutionChain.join(' -> ')}`,
1733
+ );
1734
+ }
1735
+
1736
+ // Only create flows for controllable paths (whitelist approach).
1737
+ // If the path doesn't resolve to something in attributesMap, skip it.
1738
+ // This prevents creating flows for useState values which are not
1739
+ // controllable via mock data injection.
1740
+ let resolvedPath = resolution.resolvedPath;
1741
+
1742
+ if (!resolution.isControllable || !resolvedPath) {
1743
+ // Path is not controllable via standard resolution.
1744
+ // Try fallback: For useState values (cyScope*().functionCallReturnValue),
1745
+ // look for a related URL parameter like "varNameFromUrl" that might
1746
+ // control the initial state.
1747
+ //
1748
+ // Example: viewMode → cyScope20().functionCallReturnValue (useState value)
1749
+ // Fallback: viewModeFromUrl → segments[2] (URL param that initializes the useState)
1750
+ const useStateMatch = translatedPath.match(
1751
+ /^cyScope\d+\(\)\.functionCallReturnValue$/,
1752
+ );
1753
+
1754
+ if (useStateMatch) {
1755
+ // Find what variable this useState value corresponds to by looking
1756
+ // for entries like "varName": "cyScope20()" in equivalentSignatureVariables
1757
+ const useStatePattern = translatedPath.replace(
1758
+ /\.functionCallReturnValue$/,
1759
+ '',
1760
+ ); // e.g., "cyScope20()"
1761
+
1762
+ // Find the variable name that maps to this useState
1763
+ let useStateVarName: string | null = null;
1764
+ for (const [varName, varPath] of Object.entries(
1765
+ equivalentSignatureVariables,
1766
+ )) {
1767
+ if (varPath === useStatePattern) {
1768
+ useStateVarName = varName;
1769
+ break;
1770
+ }
1771
+ }
1772
+
1773
+ if (shouldDebugChild) {
1774
+ console.log(
1775
+ `[DEBUG CHILD ${childName}] useState fallback: looking for URL param`,
1776
+ );
1777
+ console.log(
1778
+ `[DEBUG CHILD ${childName}] useStatePattern: ${useStatePattern}`,
1779
+ );
1780
+ console.log(
1781
+ `[DEBUG CHILD ${childName}] useStateVarName: ${useStateVarName}`,
1782
+ );
1783
+ }
1784
+
1785
+ if (useStateVarName) {
1786
+ // Look for a related URL param like "varNameFromUrl"
1787
+ const urlParamName = `${useStateVarName}FromUrl`;
1788
+ const urlParamPath = equivalentSignatureVariables[urlParamName];
1789
+
1790
+ if (shouldDebugChild) {
1791
+ console.log(
1792
+ `[DEBUG CHILD ${childName}] urlParamName: ${urlParamName}`,
1793
+ );
1794
+ console.log(
1795
+ `[DEBUG CHILD ${childName}] urlParamPath: ${urlParamPath}`,
1796
+ );
1797
+ }
1798
+
1799
+ if (urlParamPath) {
1800
+ // For useState values initialized from URL params, use the
1801
+ // URL param variable name directly (e.g., "viewModeFromUrl")
1802
+ // rather than fully resolving it. This keeps the path meaningful
1803
+ // for scenario generation and avoids overly generic paths like
1804
+ // "useParams().functionCallReturnValue.*".
1805
+ //
1806
+ // The flow will use the URL param name as the attributePath,
1807
+ // which gets properly resolved when generating mock data.
1808
+ resolvedPath = urlParamName;
1809
+ if (shouldDebugChild) {
1810
+ console.log(
1811
+ `[DEBUG CHILD ${childName}] useState fallback SUCCESS: using URL param name ${resolvedPath}`,
1812
+ );
1813
+ }
1814
+ }
1815
+ }
1816
+ }
1817
+
1818
+ // Fallback 2: Try sourceEquivalencies to find the actual data source
1819
+ // This handles the case where props flow through useState but originate
1820
+ // from a mockable data source (e.g., API call, fetcher).
1821
+ //
1822
+ // Example: WorkoutsView receives `workouts` prop which in parent is stored
1823
+ // in useState, but ultimately comes from a Supabase query.
1824
+ // sourceEquivalencies tells us: "WorkoutsView().signature[0].workouts" → "createClient()...data"
1825
+ if (!resolvedPath && sourceEquivalencies) {
1826
+ // Build the child prop path to look up in sourceEquivalencies
1827
+ // Format: "ChildName().signature[0].propName"
1828
+ // First, find what prop this child path maps to
1829
+ let childPropName: string | null = null;
1830
+ for (const [varName, varPath] of Object.entries(
1831
+ childData.equivalentSignatureVariables,
1832
+ )) {
1833
+ // Check if childPath starts with this variable name
1834
+ // e.g., childPath = "workouts.length", varName = "workouts", varPath = "signature[0].workouts"
1835
+ if (
1836
+ childPath === varName ||
1837
+ childPath.startsWith(`${varName}.`)
1838
+ ) {
1839
+ childPropName = varName;
1840
+ break;
1841
+ }
1842
+ }
1843
+
1844
+ if (childPropName) {
1845
+ // Build the full sourceEquivalencies key
1846
+ const sourceEquivKey = `${childName}().signature[0].${childPropName}`;
1847
+
1848
+ const sourceEquivEntry = sourceEquivalencies[sourceEquivKey];
1849
+ if (sourceEquivEntry && sourceEquivEntry.length > 0) {
1850
+ const dataSourcePath = sourceEquivEntry[0].schemaPath;
1851
+
1852
+ // Check if this data source path is controllable
1853
+ const dataSourceResolution = resolvePathToControllable(
1854
+ dataSourcePath,
1855
+ attributesMap,
1856
+ equivalentSignatureVariables,
1857
+ fullToShortPathMap,
1858
+ );
1859
+
1860
+ if (
1861
+ dataSourceResolution.isControllable &&
1862
+ dataSourceResolution.resolvedPath
1863
+ ) {
1864
+ // Preserve any suffix from the child path
1865
+ // e.g., childPath = "workouts.length" → suffix = ".length"
1866
+ const suffix = childPath.startsWith(`${childPropName}.`)
1867
+ ? childPath.slice(childPropName.length)
1868
+ : '';
1869
+ resolvedPath = dataSourceResolution.resolvedPath + suffix;
1870
+
1871
+ if (shouldDebugChild) {
1872
+ console.log(
1873
+ `[DEBUG CHILD ${childName}] sourceEquivalencies fallback SUCCESS: using data source ${resolvedPath}`,
1874
+ );
1875
+ }
1876
+ }
1877
+ }
1878
+ }
1879
+ }
1880
+
1881
+ // If still not resolved after fallback, skip
1882
+ if (!resolvedPath) {
1883
+ if (shouldDebugChild) {
1884
+ console.log(
1885
+ `[DEBUG CHILD ${childName}] SKIPPED - path not controllable`,
1886
+ );
1887
+ }
1888
+ continue;
1889
+ }
1890
+ }
1891
+
1892
+ // Check for duplicates
1893
+ const normalizedPath = normalizePathForDeduplication(
1894
+ resolvedPath,
1895
+ fullToShortPathMap,
1896
+ );
1897
+
1898
+ if (seenNormalizedPaths.has(normalizedPath)) {
1899
+ if (shouldDebugChild) {
1900
+ console.log(
1901
+ `[DEBUG CHILD ${childName}] SKIPPED - duplicate normalized path: ${normalizedPath}`,
1902
+ );
1903
+ }
1904
+ continue;
1905
+ }
1906
+ seenNormalizedPaths.add(normalizedPath);
1907
+
1908
+ // Generate flows for this translated usage
1909
+ // Create a modified usage with the translated path for flow generation
1910
+ const translatedUsage: ConditionalUsage = {
1911
+ ...usage,
1912
+ path: resolvedPath,
1913
+ };
1914
+
1915
+ const usageFlows = generateFlowsFromUsage(
1916
+ translatedUsage,
1917
+ resolvedPath,
1918
+ );
1919
+
1920
+ if (shouldDebugChild) {
1921
+ console.log(
1922
+ `[DEBUG CHILD ${childName}] GENERATING ${usageFlows.length} flows with resolvedPath: ${resolvedPath}`,
1923
+ );
1924
+ for (const f of usageFlows) {
1925
+ console.log(
1926
+ `[DEBUG CHILD ${childName}] - Flow ID: ${f.id}, path: ${f.requiredValues[0]?.attributePath}`,
1927
+ );
1928
+ }
1929
+ }
1930
+
1931
+ // Add gating conditions to each flow
1932
+ for (const flow of usageFlows) {
1933
+ // Add gating required values to the flow
1934
+ if (gatingRequiredValues.length > 0) {
1935
+ // Filter out any gating values that are already in the flow
1936
+ const existingPaths = new Set(
1937
+ flow.requiredValues.map((rv) => rv.attributePath),
1938
+ );
1939
+ const newGatingValues = gatingRequiredValues.filter(
1940
+ (gv) => !existingPaths.has(gv.attributePath),
1941
+ );
1942
+ flow.requiredValues = [
1943
+ ...flow.requiredValues,
1944
+ ...newGatingValues,
1945
+ ];
1946
+
1947
+ // Update the flow ID to include gating conditions
1948
+ if (newGatingValues.length > 0) {
1949
+ const gatingIdPart = newGatingValues
1950
+ .map((gv) => `${gv.attributePath}-${gv.value}`)
1951
+ .join('-');
1952
+ flow.id = `${flow.id}-gated-${gatingIdPart}`;
1953
+ }
1954
+ }
1955
+
1956
+ if (!seenFlowIds.has(flow.id)) {
1957
+ seenFlowIds.add(flow.id);
1958
+ flows.push(flow);
1959
+ }
1960
+ }
1961
+ }
1962
+ }
1963
+
1964
+ // Process child's compound conditionals
1965
+ for (const compound of childData.compoundConditionals) {
1966
+ const resolvedPaths = new Map<string, string>();
1967
+ let allResolvable = true;
1968
+
1969
+ for (const condition of compound.conditions) {
1970
+ // Determine the child path to translate
1971
+ const childPath = condition.path;
1972
+
1973
+ // Translate the child path to a parent path
1974
+ const translatedPath = translateChildPathToParent(
1975
+ childPath,
1976
+ childData.equivalentSignatureVariables,
1977
+ equivalentSignatureVariables,
1978
+ childName,
1979
+ );
1980
+
1981
+ if (!translatedPath) {
1982
+ allResolvable = false;
1983
+ break;
1984
+ }
1985
+
1986
+ const resolution = resolvePathToControllable(
1987
+ translatedPath,
1988
+ attributesMap,
1989
+ equivalentSignatureVariables,
1990
+ fullToShortPathMap,
1991
+ );
1992
+
1993
+ // Only create flows for controllable paths (whitelist approach).
1994
+ // If the path doesn't resolve to something in attributesMap, skip it.
1995
+ // This prevents creating flows for useState values which are not
1996
+ // controllable via mock data injection.
1997
+ let resolvedPath = resolution.resolvedPath;
1998
+
1999
+ if (!resolution.isControllable || !resolvedPath) {
2000
+ // Path is not controllable via standard resolution.
2001
+ // Try fallback: For useState values (cyScope*().functionCallReturnValue),
2002
+ // look for a related URL parameter like "varNameFromUrl" that might
2003
+ // control the initial state.
2004
+ const useStateMatch = translatedPath.match(
2005
+ /^cyScope\d+\(\)\.functionCallReturnValue$/,
2006
+ );
2007
+
2008
+ if (useStateMatch) {
2009
+ const useStatePattern = translatedPath.replace(
2010
+ /\.functionCallReturnValue$/,
2011
+ '',
2012
+ );
2013
+
2014
+ // Find the variable name that maps to this useState
2015
+ let useStateVarName: string | null = null;
2016
+ for (const [varName, varPath] of Object.entries(
2017
+ equivalentSignatureVariables,
2018
+ )) {
2019
+ if (varPath === useStatePattern) {
2020
+ useStateVarName = varName;
2021
+ break;
2022
+ }
2023
+ }
2024
+
2025
+ if (useStateVarName) {
2026
+ const urlParamName = `${useStateVarName}FromUrl`;
2027
+ const urlParamPath = equivalentSignatureVariables[urlParamName];
2028
+
2029
+ if (urlParamPath) {
2030
+ resolvedPath = urlParamName;
2031
+ }
2032
+ }
2033
+ }
2034
+ }
2035
+
2036
+ if (!resolvedPath) {
2037
+ allResolvable = false;
2038
+ break;
2039
+ }
2040
+
2041
+ resolvedPaths.set(condition.path, resolvedPath);
2042
+ }
2043
+
2044
+ if (allResolvable && resolvedPaths.size > 0) {
2045
+ const compoundFlow = generateFlowFromCompound(
2046
+ compound,
2047
+ resolvedPaths,
2048
+ );
2049
+ if (compoundFlow) {
2050
+ // Add gating conditions to compound flow (same as regular usage flows)
2051
+ if (gatingRequiredValues.length > 0) {
2052
+ // Filter out any gating values that are already in the flow
2053
+ const existingPaths = new Set(
2054
+ compoundFlow.requiredValues.map((rv) => rv.attributePath),
2055
+ );
2056
+ const newGatingValues = gatingRequiredValues.filter(
2057
+ (gv) => !existingPaths.has(gv.attributePath),
2058
+ );
2059
+ compoundFlow.requiredValues = [
2060
+ ...compoundFlow.requiredValues,
2061
+ ...newGatingValues,
2062
+ ];
2063
+
2064
+ // Update the flow ID to include gating conditions
2065
+ if (newGatingValues.length > 0) {
2066
+ const gatingIdPart = newGatingValues
2067
+ .map((gv) => `${gv.attributePath}-${gv.value}`)
2068
+ .join('-');
2069
+ compoundFlow.id = `${compoundFlow.id}-gated-${gatingIdPart}`;
2070
+ }
2071
+ }
2072
+
2073
+ if (!seenFlowIds.has(compoundFlow.id)) {
2074
+ seenFlowIds.add(compoundFlow.id);
2075
+ flows.push(compoundFlow);
2076
+ }
2077
+ }
2078
+ }
2079
+ }
2080
+
2081
+ // Process child's jsxRenderingUsages (array.map flows)
2082
+ // This generates array variation flows (empty, few, many) for arrays rendered in child
2083
+ if (childData.jsxRenderingUsages) {
2084
+ for (const jsxUsage of childData.jsxRenderingUsages) {
2085
+ // Translate the child path to a parent path
2086
+ const translatedPath = translateChildPathToParent(
2087
+ jsxUsage.path,
2088
+ childData.equivalentSignatureVariables,
2089
+ equivalentSignatureVariables,
2090
+ childName,
2091
+ );
2092
+
2093
+ if (!translatedPath) {
2094
+ continue;
2095
+ }
2096
+
2097
+ // Resolve to controllable path in parent context
2098
+ const resolution = resolvePathToControllable(
2099
+ translatedPath,
2100
+ attributesMap,
2101
+ equivalentSignatureVariables,
2102
+ fullToShortPathMap,
2103
+ );
2104
+
2105
+ let resolvedPath = resolution.resolvedPath;
2106
+
2107
+ // Try sourceEquivalencies fallback if not controllable
2108
+ if (!resolution.isControllable || !resolvedPath) {
2109
+ if (sourceEquivalencies) {
2110
+ // Build the sourceEquivalencies key
2111
+ // The child path (e.g., "workouts") maps to a prop path (e.g., "signature[0].workouts")
2112
+ let childPropName: string | null = null;
2113
+ for (const [varName, varPath] of Object.entries(
2114
+ childData.equivalentSignatureVariables,
2115
+ )) {
2116
+ if (
2117
+ jsxUsage.path === varName ||
2118
+ jsxUsage.path.startsWith(`${varName}.`)
2119
+ ) {
2120
+ childPropName = varName;
2121
+ break;
2122
+ }
2123
+ }
2124
+
2125
+ if (childPropName) {
2126
+ const sourceEquivKey = `${childName}().signature[0].${childPropName}`;
2127
+ const sourceEquivEntry = sourceEquivalencies[sourceEquivKey];
2128
+
2129
+ if (sourceEquivEntry && sourceEquivEntry.length > 0) {
2130
+ const dataSourcePath = sourceEquivEntry[0].schemaPath;
2131
+
2132
+ const dataSourceResolution = resolvePathToControllable(
2133
+ dataSourcePath,
2134
+ attributesMap,
2135
+ equivalentSignatureVariables,
2136
+ fullToShortPathMap,
2137
+ );
2138
+
2139
+ if (
2140
+ dataSourceResolution.isControllable &&
2141
+ dataSourceResolution.resolvedPath
2142
+ ) {
2143
+ resolvedPath = dataSourceResolution.resolvedPath;
2144
+ }
2145
+ }
2146
+ }
2147
+ }
2148
+ }
2149
+
2150
+ if (!resolvedPath) {
2151
+ continue;
2152
+ }
2153
+
2154
+ // Check for duplicates
2155
+ const normalizedPath = normalizePathForDeduplication(
2156
+ resolvedPath,
2157
+ fullToShortPathMap,
2158
+ );
2159
+ const dedupeKey = `${normalizedPath}:${jsxUsage.renderingType}`;
2160
+ if (seenNormalizedPaths.has(dedupeKey)) {
2161
+ continue;
2162
+ }
2163
+ seenNormalizedPaths.add(dedupeKey);
2164
+
2165
+ // Generate array variation flows for array-map rendering
2166
+ if (jsxUsage.renderingType === 'array-map') {
2167
+ const baseName = generateNameFromPath(resolvedPath);
2168
+ const pathSlug = pathToSlug(resolvedPath);
2169
+ const exclusiveGroup = `array-length-${pathSlug}`;
2170
+
2171
+ // Empty array flow
2172
+ const emptyFlow: ExecutionFlow = {
2173
+ id: `${pathSlug}-empty-array`,
2174
+ name: `${baseName} Empty`,
2175
+ description: `When ${baseName.toLowerCase()} array is empty`,
2176
+ requiredValues: [
2177
+ {
2178
+ attributePath: resolvedPath,
2179
+ value: '0',
2180
+ comparison: 'length<',
2181
+ valueType: 'array',
2182
+ },
2183
+ ...gatingRequiredValues,
2184
+ ],
2185
+ impact: 'medium',
2186
+ exclusiveGroup,
2187
+ sourceLocation: jsxUsage.sourceLocation
2188
+ ? {
2189
+ lineNumber: jsxUsage.sourceLocation.lineNumber,
2190
+ column: jsxUsage.sourceLocation.column,
2191
+ }
2192
+ : undefined,
2193
+ codeSnippet: jsxUsage.sourceLocation?.codeSnippet,
2194
+ };
2195
+
2196
+ if (!seenFlowIds.has(emptyFlow.id)) {
2197
+ seenFlowIds.add(emptyFlow.id);
2198
+ flows.push(emptyFlow);
2199
+ }
2200
+
2201
+ // Few items flow (1-3)
2202
+ const fewFlow: ExecutionFlow = {
2203
+ id: `${pathSlug}-few-items`,
2204
+ name: `${baseName} Few Items`,
2205
+ description: `When ${baseName.toLowerCase()} array has 1-3 items`,
2206
+ requiredValues: [
2207
+ {
2208
+ attributePath: resolvedPath,
2209
+ value: '3',
2210
+ comparison: 'length<',
2211
+ valueType: 'array',
2212
+ },
2213
+ ...gatingRequiredValues,
2214
+ ],
2215
+ impact: 'low',
2216
+ exclusiveGroup,
2217
+ sourceLocation: jsxUsage.sourceLocation
2218
+ ? {
2219
+ lineNumber: jsxUsage.sourceLocation.lineNumber,
2220
+ column: jsxUsage.sourceLocation.column,
2221
+ }
2222
+ : undefined,
2223
+ codeSnippet: jsxUsage.sourceLocation?.codeSnippet,
2224
+ };
2225
+
2226
+ if (!seenFlowIds.has(fewFlow.id)) {
2227
+ seenFlowIds.add(fewFlow.id);
2228
+ flows.push(fewFlow);
2229
+ }
2230
+
2231
+ // Many items flow (10+)
2232
+ const manyFlow: ExecutionFlow = {
2233
+ id: `${pathSlug}-many-items`,
2234
+ name: `${baseName} Many Items`,
2235
+ description: `When ${baseName.toLowerCase()} array has many items`,
2236
+ requiredValues: [
2237
+ {
2238
+ attributePath: resolvedPath,
2239
+ value: '10',
2240
+ comparison: 'length>',
2241
+ valueType: 'array',
2242
+ },
2243
+ ...gatingRequiredValues,
2244
+ ],
2245
+ impact: 'low',
2246
+ exclusiveGroup,
2247
+ sourceLocation: jsxUsage.sourceLocation
2248
+ ? {
2249
+ lineNumber: jsxUsage.sourceLocation.lineNumber,
2250
+ column: jsxUsage.sourceLocation.column,
2251
+ }
2252
+ : undefined,
2253
+ codeSnippet: jsxUsage.sourceLocation?.codeSnippet,
2254
+ };
2255
+
2256
+ if (!seenFlowIds.has(manyFlow.id)) {
2257
+ seenFlowIds.add(manyFlow.id);
2258
+ flows.push(manyFlow);
2259
+ }
2260
+ }
2261
+ }
2262
+ }
2263
+ }
2264
+ }
2265
+
2266
+ return flows;
2267
+ }