@codeyam/codeyam-cli 0.1.0-staging.323686 → 0.1.0-staging.4813bf3

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 (444) hide show
  1. package/analyzer-template/.build-info.json +7 -7
  2. package/analyzer-template/log.txt +3 -3
  3. package/analyzer-template/package.json +5 -5
  4. package/analyzer-template/packages/ai/index.ts +7 -1
  5. package/analyzer-template/packages/ai/package.json +2 -2
  6. package/analyzer-template/packages/ai/src/lib/analyzeScope.ts +62 -18
  7. package/analyzer-template/packages/ai/src/lib/astScopes/astScopeAnalyzer.ts +67 -9
  8. package/analyzer-template/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.ts +10 -17
  9. package/analyzer-template/packages/ai/src/lib/astScopes/processExpression.ts +409 -50
  10. package/analyzer-template/packages/ai/src/lib/astScopes/sharedPatterns.ts +28 -0
  11. package/analyzer-template/packages/ai/src/lib/astScopes/types.ts +21 -6
  12. package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +992 -249
  13. package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.ts +5 -1
  14. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.ts +16 -3
  15. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.ts +6 -4
  16. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.ts +31 -3
  17. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.ts +37 -15
  18. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.ts +70 -0
  19. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.ts +126 -11
  20. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.ts +179 -0
  21. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/deduplicateFunctionSchemas.ts +40 -30
  22. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.ts +367 -96
  23. package/analyzer-template/packages/ai/src/lib/dataStructureChunking.ts +33 -15
  24. package/analyzer-template/packages/ai/src/lib/generateEntityDataStructure.ts +58 -3
  25. package/analyzer-template/packages/ai/src/lib/generateEntityScenarioData.ts +315 -6
  26. package/analyzer-template/packages/ai/src/lib/generateEntityScenarios.ts +9 -5
  27. package/analyzer-template/packages/ai/src/lib/generateExecutionFlows.ts +49 -5
  28. package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromConditionalEffects.ts +1 -1
  29. package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromConditionals.ts +649 -142
  30. package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromJsxUsages.ts +1 -1
  31. package/analyzer-template/packages/ai/src/lib/isolateScopes.ts +51 -3
  32. package/analyzer-template/packages/ai/src/lib/mergeJsonTypeDefinitions.ts +5 -0
  33. package/analyzer-template/packages/ai/src/lib/mergeStatements.ts +90 -96
  34. package/analyzer-template/packages/ai/src/lib/promptGenerators/collapseNullableObjects.ts +118 -0
  35. package/analyzer-template/packages/ai/src/lib/promptGenerators/gatherAttributesMap.ts +10 -7
  36. package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.ts +24 -4
  37. package/analyzer-template/packages/ai/src/lib/resolvePathToControllable.ts +25 -13
  38. package/analyzer-template/packages/ai/src/lib/worker/SerializableDataStructure.ts +4 -3
  39. package/analyzer-template/packages/analyze/index.ts +2 -0
  40. package/analyzer-template/packages/analyze/src/lib/FileAnalyzer.ts +65 -59
  41. package/analyzer-template/packages/analyze/src/lib/ProjectAnalyzer.ts +113 -26
  42. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllDeclaredEntityNodes.ts +19 -0
  43. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllEntityNodes.ts +19 -0
  44. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllExports.ts +11 -0
  45. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getImportsAnalysis.ts +8 -0
  46. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getResolvedModule.ts +49 -1
  47. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getSourceFilesForAllImports.ts +2 -1
  48. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +89 -9
  49. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +19 -4
  50. package/analyzer-template/packages/analyze/src/lib/files/analyze/gatherEntityMap.ts +4 -2
  51. package/analyzer-template/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.ts +0 -3
  52. package/analyzer-template/packages/analyze/src/lib/files/analyzeRemixRoute.ts +4 -5
  53. package/analyzer-template/packages/analyze/src/lib/files/getImportedExports.ts +14 -12
  54. package/analyzer-template/packages/analyze/src/lib/files/scenarios/TransformationTracer.ts +1315 -0
  55. package/analyzer-template/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.ts +61 -13
  56. package/analyzer-template/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.ts +37 -0
  57. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +229 -19
  58. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.ts +117 -9
  59. package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +459 -39
  60. package/analyzer-template/packages/analyze/src/lib/files/scenarios/propagateArrayItemSchemas.ts +474 -0
  61. package/analyzer-template/packages/analyze/src/lib/files/setImportedExports.ts +2 -1
  62. package/analyzer-template/packages/analyze/src/lib/index.ts +1 -0
  63. package/analyzer-template/packages/analyze/src/lib/utils/getFileByPath.ts +19 -0
  64. package/analyzer-template/packages/aws/package.json +1 -1
  65. package/analyzer-template/packages/database/package.json +1 -1
  66. package/analyzer-template/packages/database/src/lib/analysisBranchToDb.ts +1 -1
  67. package/analyzer-template/packages/database/src/lib/analysisToDb.ts +1 -1
  68. package/analyzer-template/packages/database/src/lib/branchToDb.ts +1 -1
  69. package/analyzer-template/packages/database/src/lib/commitBranchToDb.ts +1 -1
  70. package/analyzer-template/packages/database/src/lib/commitToDb.ts +1 -1
  71. package/analyzer-template/packages/database/src/lib/fileToDb.ts +1 -1
  72. package/analyzer-template/packages/database/src/lib/kysely/db.ts +6 -0
  73. package/analyzer-template/packages/database/src/lib/kysely/tables/debugReportsTable.ts +1 -1
  74. package/analyzer-template/packages/database/src/lib/kysely/tables/labsRequestsTable.ts +52 -0
  75. package/analyzer-template/packages/database/src/lib/projectToDb.ts +1 -1
  76. package/analyzer-template/packages/database/src/lib/saveFiles.ts +1 -1
  77. package/analyzer-template/packages/database/src/lib/scenarioToDb.ts +1 -1
  78. package/analyzer-template/packages/database/src/lib/userScenarioToDb.ts +1 -1
  79. package/analyzer-template/packages/github/dist/database/src/lib/analysisBranchToDb.js +1 -1
  80. package/analyzer-template/packages/github/dist/database/src/lib/analysisBranchToDb.js.map +1 -1
  81. package/analyzer-template/packages/github/dist/database/src/lib/analysisToDb.js +1 -1
  82. package/analyzer-template/packages/github/dist/database/src/lib/analysisToDb.js.map +1 -1
  83. package/analyzer-template/packages/github/dist/database/src/lib/branchToDb.js +1 -1
  84. package/analyzer-template/packages/github/dist/database/src/lib/branchToDb.js.map +1 -1
  85. package/analyzer-template/packages/github/dist/database/src/lib/commitBranchToDb.js +1 -1
  86. package/analyzer-template/packages/github/dist/database/src/lib/commitBranchToDb.js.map +1 -1
  87. package/analyzer-template/packages/github/dist/database/src/lib/commitToDb.js +1 -1
  88. package/analyzer-template/packages/github/dist/database/src/lib/commitToDb.js.map +1 -1
  89. package/analyzer-template/packages/github/dist/database/src/lib/fileToDb.js +1 -1
  90. package/analyzer-template/packages/github/dist/database/src/lib/fileToDb.js.map +1 -1
  91. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts +2 -0
  92. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts.map +1 -1
  93. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js +3 -0
  94. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js.map +1 -1
  95. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.d.ts +1 -1
  96. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/labsRequestsTable.d.ts +23 -0
  97. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/labsRequestsTable.d.ts.map +1 -0
  98. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/labsRequestsTable.js +35 -0
  99. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/labsRequestsTable.js.map +1 -0
  100. package/analyzer-template/packages/github/dist/database/src/lib/projectToDb.js +1 -1
  101. package/analyzer-template/packages/github/dist/database/src/lib/projectToDb.js.map +1 -1
  102. package/analyzer-template/packages/github/dist/database/src/lib/saveFiles.js +1 -1
  103. package/analyzer-template/packages/github/dist/database/src/lib/saveFiles.js.map +1 -1
  104. package/analyzer-template/packages/github/dist/database/src/lib/scenarioToDb.js +1 -1
  105. package/analyzer-template/packages/github/dist/database/src/lib/scenarioToDb.js.map +1 -1
  106. package/analyzer-template/packages/github/dist/types/src/types/ProjectMetadata.d.ts +7 -0
  107. package/analyzer-template/packages/github/dist/types/src/types/ProjectMetadata.d.ts.map +1 -1
  108. package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts +5 -5
  109. package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
  110. package/analyzer-template/packages/github/dist/types/src/types/ScopeAnalysis.d.ts +6 -1
  111. package/analyzer-template/packages/github/dist/types/src/types/ScopeAnalysis.d.ts.map +1 -1
  112. package/analyzer-template/packages/github/package.json +1 -1
  113. package/analyzer-template/packages/types/src/types/ProjectMetadata.ts +7 -0
  114. package/analyzer-template/packages/types/src/types/ScenariosDataStructure.ts +6 -5
  115. package/analyzer-template/packages/types/src/types/ScopeAnalysis.ts +6 -1
  116. package/analyzer-template/packages/utils/dist/types/src/types/ProjectMetadata.d.ts +7 -0
  117. package/analyzer-template/packages/utils/dist/types/src/types/ProjectMetadata.d.ts.map +1 -1
  118. package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts +5 -5
  119. package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
  120. package/analyzer-template/packages/utils/dist/types/src/types/ScopeAnalysis.d.ts +6 -1
  121. package/analyzer-template/packages/utils/dist/types/src/types/ScopeAnalysis.d.ts.map +1 -1
  122. package/analyzer-template/project/constructMockCode.ts +90 -10
  123. package/analyzer-template/project/writeMockDataTsx.ts +181 -8
  124. package/analyzer-template/project/writeScenarioComponents.ts +60 -12
  125. package/analyzer-template/project/writeSimpleRoot.ts +21 -11
  126. package/background/src/lib/local/createLocalAnalyzer.js +1 -1
  127. package/background/src/lib/local/createLocalAnalyzer.js.map +1 -1
  128. package/background/src/lib/virtualized/project/constructMockCode.js +75 -4
  129. package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
  130. package/background/src/lib/virtualized/project/writeMockDataTsx.js +162 -4
  131. package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
  132. package/background/src/lib/virtualized/project/writeScenarioComponents.js +60 -15
  133. package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
  134. package/background/src/lib/virtualized/project/writeSimpleRoot.js +21 -11
  135. package/background/src/lib/virtualized/project/writeSimpleRoot.js.map +1 -1
  136. package/codeyam-cli/scripts/apply-setup.js +180 -0
  137. package/codeyam-cli/scripts/apply-setup.js.map +1 -1
  138. package/codeyam-cli/src/cli.js +2 -0
  139. package/codeyam-cli/src/cli.js.map +1 -1
  140. package/codeyam-cli/src/codeyam-cli.js +18 -2
  141. package/codeyam-cli/src/codeyam-cli.js.map +1 -1
  142. package/codeyam-cli/src/commands/analyze.js +4 -2
  143. package/codeyam-cli/src/commands/analyze.js.map +1 -1
  144. package/codeyam-cli/src/commands/baseline.js +2 -0
  145. package/codeyam-cli/src/commands/baseline.js.map +1 -1
  146. package/codeyam-cli/src/commands/debug.js +9 -5
  147. package/codeyam-cli/src/commands/debug.js.map +1 -1
  148. package/codeyam-cli/src/commands/default.js +31 -20
  149. package/codeyam-cli/src/commands/default.js.map +1 -1
  150. package/codeyam-cli/src/commands/detect-universal-mocks.js +2 -0
  151. package/codeyam-cli/src/commands/detect-universal-mocks.js.map +1 -1
  152. package/codeyam-cli/src/commands/init.js +49 -257
  153. package/codeyam-cli/src/commands/init.js.map +1 -1
  154. package/codeyam-cli/src/commands/memory.js +17 -26
  155. package/codeyam-cli/src/commands/memory.js.map +1 -1
  156. package/codeyam-cli/src/commands/recapture.js +2 -0
  157. package/codeyam-cli/src/commands/recapture.js.map +1 -1
  158. package/codeyam-cli/src/commands/setup-sandbox.js +2 -0
  159. package/codeyam-cli/src/commands/setup-sandbox.js.map +1 -1
  160. package/codeyam-cli/src/commands/setup-simulations.js +284 -0
  161. package/codeyam-cli/src/commands/setup-simulations.js.map +1 -0
  162. package/codeyam-cli/src/commands/test-startup.js +2 -0
  163. package/codeyam-cli/src/commands/test-startup.js.map +1 -1
  164. package/codeyam-cli/src/commands/verify.js +14 -2
  165. package/codeyam-cli/src/commands/verify.js.map +1 -1
  166. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js +128 -86
  167. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js.map +1 -1
  168. package/codeyam-cli/src/utils/analyzer.js +7 -0
  169. package/codeyam-cli/src/utils/analyzer.js.map +1 -1
  170. package/codeyam-cli/src/utils/backgroundServer.js +5 -0
  171. package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
  172. package/codeyam-cli/src/utils/generateReport.js +2 -2
  173. package/codeyam-cli/src/utils/install-skills.js +70 -45
  174. package/codeyam-cli/src/utils/install-skills.js.map +1 -1
  175. package/codeyam-cli/src/utils/labsAutoCheck.js +19 -0
  176. package/codeyam-cli/src/utils/labsAutoCheck.js.map +1 -0
  177. package/codeyam-cli/src/utils/progress.js +7 -0
  178. package/codeyam-cli/src/utils/progress.js.map +1 -1
  179. package/codeyam-cli/src/utils/queue/job.js +4 -0
  180. package/codeyam-cli/src/utils/queue/job.js.map +1 -1
  181. package/codeyam-cli/src/utils/requireSimulations.js +10 -0
  182. package/codeyam-cli/src/utils/requireSimulations.js.map +1 -0
  183. package/codeyam-cli/src/utils/ruleReflection/__tests__/confusionDetector.test.js +82 -0
  184. package/codeyam-cli/src/utils/ruleReflection/__tests__/confusionDetector.test.js.map +1 -0
  185. package/codeyam-cli/src/utils/ruleReflection/__tests__/contextBuilder.test.js +230 -0
  186. package/codeyam-cli/src/utils/ruleReflection/__tests__/contextBuilder.test.js.map +1 -0
  187. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/assertRules.js +67 -0
  188. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/assertRules.js.map +1 -0
  189. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/captureFixture.js +105 -0
  190. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/captureFixture.js.map +1 -0
  191. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/loadCapturedFixture.js +34 -0
  192. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/loadCapturedFixture.js.map +1 -0
  193. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/runClaude.js +162 -0
  194. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/runClaude.js.map +1 -0
  195. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js +75 -0
  196. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js.map +1 -0
  197. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js +378 -0
  198. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js.map +1 -0
  199. package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js +115 -0
  200. package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js.map +1 -0
  201. package/codeyam-cli/src/utils/ruleReflection/__tests__/transcriptParser.test.js +127 -0
  202. package/codeyam-cli/src/utils/ruleReflection/__tests__/transcriptParser.test.js.map +1 -0
  203. package/codeyam-cli/src/utils/ruleReflection/confusionDetector.js +50 -0
  204. package/codeyam-cli/src/utils/ruleReflection/confusionDetector.js.map +1 -0
  205. package/codeyam-cli/src/utils/ruleReflection/contextBuilder.js +116 -0
  206. package/codeyam-cli/src/utils/ruleReflection/contextBuilder.js.map +1 -0
  207. package/codeyam-cli/src/utils/ruleReflection/index.js +5 -0
  208. package/codeyam-cli/src/utils/ruleReflection/index.js.map +1 -0
  209. package/codeyam-cli/src/utils/ruleReflection/promptBuilder.js +44 -0
  210. package/codeyam-cli/src/utils/ruleReflection/promptBuilder.js.map +1 -0
  211. package/codeyam-cli/src/utils/ruleReflection/transcriptParser.js +85 -0
  212. package/codeyam-cli/src/utils/ruleReflection/transcriptParser.js.map +1 -0
  213. package/codeyam-cli/src/utils/ruleReflection/types.js +5 -0
  214. package/codeyam-cli/src/utils/ruleReflection/types.js.map +1 -0
  215. package/codeyam-cli/src/utils/rules/__tests__/ruleState.test.js +293 -0
  216. package/codeyam-cli/src/utils/rules/__tests__/ruleState.test.js.map +1 -0
  217. package/codeyam-cli/src/utils/rules/index.js +1 -0
  218. package/codeyam-cli/src/utils/rules/index.js.map +1 -1
  219. package/codeyam-cli/src/utils/rules/parser.js +2 -25
  220. package/codeyam-cli/src/utils/rules/parser.js.map +1 -1
  221. package/codeyam-cli/src/utils/rules/ruleState.js +150 -0
  222. package/codeyam-cli/src/utils/rules/ruleState.js.map +1 -0
  223. package/codeyam-cli/src/utils/rules/staleness.js +16 -11
  224. package/codeyam-cli/src/utils/rules/staleness.js.map +1 -1
  225. package/codeyam-cli/src/utils/serverState.js +37 -10
  226. package/codeyam-cli/src/utils/serverState.js.map +1 -1
  227. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +21 -44
  228. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js.map +1 -1
  229. package/codeyam-cli/src/webserver/app/lib/database.js +15 -3
  230. package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
  231. package/codeyam-cli/src/webserver/backgroundServer.js +24 -0
  232. package/codeyam-cli/src/webserver/backgroundServer.js.map +1 -1
  233. package/codeyam-cli/src/webserver/build/client/assets/CopyButton-CA3JxPb7.js +1 -0
  234. package/codeyam-cli/src/webserver/build/client/assets/{EntityItem-DsN1wKrm.js → EntityItem-B86KKU7e.js} +1 -1
  235. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeBadge-DLqD3qNt.js → EntityTypeBadge-B5ctlSYt.js} +1 -1
  236. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeIcon-Ba2JVPzP.js → EntityTypeIcon-BqY8gDAW.js} +1 -1
  237. package/codeyam-cli/src/webserver/build/client/assets/{InlineSpinner-C8lyxW9k.js → InlineSpinner-ClaLpuOo.js} +1 -1
  238. package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-aht4aafF.js → InteractivePreview-BDhPilK7.js} +2 -2
  239. package/codeyam-cli/src/webserver/build/client/assets/{LibraryFunctionPreview-CVtiBnY5.js → LibraryFunctionPreview-VeqEBv9v.js} +1 -1
  240. package/codeyam-cli/src/webserver/build/client/assets/{LoadingDots-B0GLXMsr.js → LoadingDots-Bs7Nn1Jr.js} +1 -1
  241. package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-xgeCVgSM.js → LogViewer-Bm3PmcCz.js} +1 -1
  242. package/codeyam-cli/src/webserver/build/client/assets/{ReportIssueModal-OApQuNyq.js → ReportIssueModal-CgMEzchJ.js} +3 -8
  243. package/codeyam-cli/src/webserver/build/client/assets/{SafeScreenshot-DuDvi0jm.js → SafeScreenshot-Gq3Ocjo6.js} +1 -1
  244. package/codeyam-cli/src/webserver/build/client/assets/{ScenarioViewer-DzccYyI8.js → ScenarioViewer-CBui0id_.js} +2 -2
  245. package/codeyam-cli/src/webserver/build/client/assets/{TruncatedFilePath-DyFZkK0l.js → TruncatedFilePath-CiwXDxLh.js} +1 -1
  246. package/codeyam-cli/src/webserver/build/client/assets/{_index-BwqWJOgH.js → _index-B3TDXxnk.js} +1 -1
  247. package/codeyam-cli/src/webserver/build/client/assets/{activity.(_tab)-BwavGCpm.js → activity.(_tab)-BtBFH820.js} +6 -11
  248. package/codeyam-cli/src/webserver/build/client/assets/agent-transcripts-CN61MOMa.js +11 -0
  249. package/codeyam-cli/src/webserver/build/client/assets/api.agent-transcripts-l0sNRNKZ.js +1 -0
  250. package/codeyam-cli/src/webserver/build/client/assets/api.labs-unlock-l0sNRNKZ.js +1 -0
  251. package/codeyam-cli/src/webserver/build/client/assets/api.save-fixture-l0sNRNKZ.js +1 -0
  252. package/codeyam-cli/src/webserver/build/client/assets/book-open-PttOB2SF.js +6 -0
  253. package/codeyam-cli/src/webserver/build/client/assets/{chevron-down-Cx24_aWc.js → chevron-down-TJp6ofnp.js} +1 -1
  254. package/codeyam-cli/src/webserver/build/client/assets/{chunk-EPOLDU6W-CXRTFQ3F.js → chunk-JZWAC4HX-JE9ZIoBl.js} +12 -12
  255. package/codeyam-cli/src/webserver/build/client/assets/{circle-check-BOARzkeR.js → circle-check-CXhHQYrI.js} +1 -1
  256. package/codeyam-cli/src/webserver/build/client/assets/copy-6y9ALfGT.js +11 -0
  257. package/codeyam-cli/src/webserver/build/client/assets/{createLucideIcon-BdhJEx6B.js → createLucideIcon-Ca9fAY46.js} +1 -1
  258. package/codeyam-cli/src/webserver/build/client/assets/{dev.empty-BBnGWYga.js → dev.empty-C0epRiVn.js} +1 -1
  259. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-BJUiQqZF.js → entity._sha._-BVnB8a9L.js} +10 -10
  260. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.fullscreen-DavjRmOY.js → entity._sha.scenarios._scenarioId.fullscreen-CBoafmVs.js} +1 -1
  261. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.create-scenario-D1T4TGjf.js → entity._sha_.create-scenario-DGgZjdFg.js} +1 -1
  262. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.edit._scenarioId-CTBG2mmz.js → entity._sha_.edit._scenarioId-38yPijoD.js} +1 -1
  263. package/codeyam-cli/src/webserver/build/client/assets/{entry.client-CS2cb_eZ.js → entry.client-BSHEfydn.js} +1 -1
  264. package/codeyam-cli/src/webserver/build/client/assets/{fileTableUtils-DMJ7zii9.js → fileTableUtils-DCPhhSMo.js} +1 -1
  265. package/codeyam-cli/src/webserver/build/client/assets/{files-CJ6lTdTA.js → files-0N0YJQv7.js} +1 -1
  266. package/codeyam-cli/src/webserver/build/client/assets/{git-CPTZZ-JZ.js → git-DXnyr8uP.js} +1 -1
  267. package/codeyam-cli/src/webserver/build/client/assets/globals-CKT08Djd.css +1 -0
  268. package/codeyam-cli/src/webserver/build/client/assets/{index-lzqtyFU8.js → index-CcsFv748.js} +1 -1
  269. package/codeyam-cli/src/webserver/build/client/assets/{index-B1h680n5.js → index-ChN9-fAY.js} +1 -1
  270. package/codeyam-cli/src/webserver/build/client/assets/labs-BLJ7HxOC.js +1 -0
  271. package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-B7B9V-bu.js → loader-circle-CTqLEAGU.js} +1 -1
  272. package/codeyam-cli/src/webserver/build/client/assets/manifest-b171b9d3.js +1 -0
  273. package/codeyam-cli/src/webserver/build/client/assets/memory-CCQd4aZA.js +78 -0
  274. package/codeyam-cli/src/webserver/build/client/assets/pause-D6vreykR.js +11 -0
  275. package/codeyam-cli/src/webserver/build/client/assets/root-CHhiHoo_.js +62 -0
  276. package/codeyam-cli/src/webserver/build/client/assets/{search-CxXUmBSd.js → search-B8VUL8nl.js} +1 -1
  277. package/codeyam-cli/src/webserver/build/client/assets/settings-BejnUJ6R.js +1 -0
  278. package/codeyam-cli/src/webserver/build/client/assets/{simulations-DwFIBT09.js → simulations-CPoAg7Zo.js} +1 -1
  279. package/codeyam-cli/src/webserver/build/client/assets/terminal-BrCP7uQo.js +11 -0
  280. package/codeyam-cli/src/webserver/build/client/assets/{triangle-alert-B6LgvRJg.js → triangle-alert-BZz2NjYa.js} +1 -1
  281. package/codeyam-cli/src/webserver/build/client/assets/{useCustomSizes-C1v1PQzo.js → useCustomSizes-DNwUduNu.js} +1 -1
  282. package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-aSv48UbS.js → useLastLogLine-COky1GVF.js} +1 -1
  283. package/codeyam-cli/src/webserver/build/client/assets/{useReportContext-DYxHZQuP.js → useReportContext-CpZgwliL.js} +1 -1
  284. package/codeyam-cli/src/webserver/build/client/assets/{useToast-mBRpZPiu.js → useToast-Bv9JFvUO.js} +1 -1
  285. package/codeyam-cli/src/webserver/build/server/assets/{index-DVzYx8PN.js → index-8Fv-lH1-.js} +1 -1
  286. package/codeyam-cli/src/webserver/build/server/assets/server-build-Akn3iYFP.js +257 -0
  287. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  288. package/codeyam-cli/src/webserver/build-info.json +5 -5
  289. package/codeyam-cli/templates/{codeyam:debug.md → codeyam-debug.md} +1 -1
  290. package/codeyam-cli/templates/codeyam-diagnose.md +481 -0
  291. package/codeyam-cli/templates/codeyam-memory-hook.sh +19 -20
  292. package/codeyam-cli/templates/codeyam-memory.md +392 -0
  293. package/codeyam-cli/templates/codeyam-new-rule.md +13 -0
  294. package/codeyam-cli/templates/{codeyam:setup.md → codeyam-setup.md} +13 -1
  295. package/codeyam-cli/templates/{codeyam:sim.md → codeyam-sim.md} +1 -1
  296. package/codeyam-cli/templates/{codeyam:test.md → codeyam-test.md} +1 -1
  297. package/codeyam-cli/templates/{codeyam:verify.md → codeyam-verify.md} +1 -1
  298. package/codeyam-cli/templates/rule-notification-hook.py +56 -0
  299. package/codeyam-cli/templates/rule-reflection-hook.py +627 -0
  300. package/codeyam-cli/templates/rules-instructions.md +132 -0
  301. package/package.json +2 -2
  302. package/packages/ai/index.js +3 -2
  303. package/packages/ai/index.js.map +1 -1
  304. package/packages/ai/src/lib/analyzeScope.js +50 -13
  305. package/packages/ai/src/lib/analyzeScope.js.map +1 -1
  306. package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js +54 -8
  307. package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js.map +1 -1
  308. package/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.js +10 -14
  309. package/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.js.map +1 -1
  310. package/packages/ai/src/lib/astScopes/processExpression.js +317 -44
  311. package/packages/ai/src/lib/astScopes/processExpression.js.map +1 -1
  312. package/packages/ai/src/lib/astScopes/sharedPatterns.js +25 -0
  313. package/packages/ai/src/lib/astScopes/sharedPatterns.js.map +1 -1
  314. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +763 -171
  315. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
  316. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js +5 -1
  317. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js.map +1 -1
  318. package/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.js +13 -3
  319. package/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.js.map +1 -1
  320. package/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.js +6 -4
  321. package/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.js.map +1 -1
  322. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js +33 -3
  323. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js.map +1 -1
  324. package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js +36 -11
  325. package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js.map +1 -1
  326. package/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.js +63 -0
  327. package/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.js.map +1 -0
  328. package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js +113 -11
  329. package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js.map +1 -1
  330. package/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.js +173 -0
  331. package/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.js.map +1 -0
  332. package/packages/ai/src/lib/dataStructure/helpers/deduplicateFunctionSchemas.js +37 -20
  333. package/packages/ai/src/lib/dataStructure/helpers/deduplicateFunctionSchemas.js.map +1 -1
  334. package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js +309 -84
  335. package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js.map +1 -1
  336. package/packages/ai/src/lib/dataStructureChunking.js +26 -11
  337. package/packages/ai/src/lib/dataStructureChunking.js.map +1 -1
  338. package/packages/ai/src/lib/generateEntityDataStructure.js +46 -2
  339. package/packages/ai/src/lib/generateEntityDataStructure.js.map +1 -1
  340. package/packages/ai/src/lib/generateEntityScenarioData.js +227 -4
  341. package/packages/ai/src/lib/generateEntityScenarioData.js.map +1 -1
  342. package/packages/ai/src/lib/generateEntityScenarios.js +7 -1
  343. package/packages/ai/src/lib/generateEntityScenarios.js.map +1 -1
  344. package/packages/ai/src/lib/generateExecutionFlows.js +26 -4
  345. package/packages/ai/src/lib/generateExecutionFlows.js.map +1 -1
  346. package/packages/ai/src/lib/generateExecutionFlowsFromConditionals.js +447 -80
  347. package/packages/ai/src/lib/generateExecutionFlowsFromConditionals.js.map +1 -1
  348. package/packages/ai/src/lib/isolateScopes.js +39 -3
  349. package/packages/ai/src/lib/isolateScopes.js.map +1 -1
  350. package/packages/ai/src/lib/mergeJsonTypeDefinitions.js +5 -0
  351. package/packages/ai/src/lib/mergeJsonTypeDefinitions.js.map +1 -1
  352. package/packages/ai/src/lib/mergeStatements.js +70 -51
  353. package/packages/ai/src/lib/mergeStatements.js.map +1 -1
  354. package/packages/ai/src/lib/promptGenerators/collapseNullableObjects.js +97 -0
  355. package/packages/ai/src/lib/promptGenerators/collapseNullableObjects.js.map +1 -0
  356. package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js +10 -4
  357. package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js.map +1 -1
  358. package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js +17 -2
  359. package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js.map +1 -1
  360. package/packages/ai/src/lib/resolvePathToControllable.js +24 -14
  361. package/packages/ai/src/lib/resolvePathToControllable.js.map +1 -1
  362. package/packages/ai/src/lib/worker/SerializableDataStructure.js.map +1 -1
  363. package/packages/analyze/index.js +1 -0
  364. package/packages/analyze/index.js.map +1 -1
  365. package/packages/analyze/src/lib/FileAnalyzer.js +60 -36
  366. package/packages/analyze/src/lib/FileAnalyzer.js.map +1 -1
  367. package/packages/analyze/src/lib/ProjectAnalyzer.js +96 -26
  368. package/packages/analyze/src/lib/ProjectAnalyzer.js.map +1 -1
  369. package/packages/analyze/src/lib/asts/sourceFiles/getAllDeclaredEntityNodes.js +14 -0
  370. package/packages/analyze/src/lib/asts/sourceFiles/getAllDeclaredEntityNodes.js.map +1 -1
  371. package/packages/analyze/src/lib/asts/sourceFiles/getAllEntityNodes.js +14 -0
  372. package/packages/analyze/src/lib/asts/sourceFiles/getAllEntityNodes.js.map +1 -1
  373. package/packages/analyze/src/lib/asts/sourceFiles/getAllExports.js +6 -0
  374. package/packages/analyze/src/lib/asts/sourceFiles/getAllExports.js.map +1 -1
  375. package/packages/analyze/src/lib/asts/sourceFiles/getImportsAnalysis.js +6 -0
  376. package/packages/analyze/src/lib/asts/sourceFiles/getImportsAnalysis.js.map +1 -1
  377. package/packages/analyze/src/lib/asts/sourceFiles/getResolvedModule.js +39 -1
  378. package/packages/analyze/src/lib/asts/sourceFiles/getResolvedModule.js.map +1 -1
  379. package/packages/analyze/src/lib/asts/sourceFiles/getSourceFilesForAllImports.js +2 -1
  380. package/packages/analyze/src/lib/asts/sourceFiles/getSourceFilesForAllImports.js.map +1 -1
  381. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +65 -7
  382. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
  383. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +17 -4
  384. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
  385. package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js +2 -1
  386. package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js.map +1 -1
  387. package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js +0 -3
  388. package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js.map +1 -1
  389. package/packages/analyze/src/lib/files/analyzeRemixRoute.js +3 -2
  390. package/packages/analyze/src/lib/files/analyzeRemixRoute.js.map +1 -1
  391. package/packages/analyze/src/lib/files/getImportedExports.js +11 -7
  392. package/packages/analyze/src/lib/files/getImportedExports.js.map +1 -1
  393. package/packages/analyze/src/lib/files/scenarios/TransformationTracer.js +880 -0
  394. package/packages/analyze/src/lib/files/scenarios/TransformationTracer.js.map +1 -0
  395. package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js +56 -10
  396. package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js.map +1 -1
  397. package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js +33 -8
  398. package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js.map +1 -1
  399. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +150 -17
  400. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
  401. package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js +56 -8
  402. package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js.map +1 -1
  403. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +399 -31
  404. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
  405. package/packages/analyze/src/lib/files/setImportedExports.js +2 -1
  406. package/packages/analyze/src/lib/files/setImportedExports.js.map +1 -1
  407. package/packages/analyze/src/lib/index.js +1 -0
  408. package/packages/analyze/src/lib/index.js.map +1 -1
  409. package/packages/analyze/src/lib/utils/getFileByPath.js +12 -0
  410. package/packages/analyze/src/lib/utils/getFileByPath.js.map +1 -0
  411. package/packages/database/src/lib/analysisBranchToDb.js +1 -1
  412. package/packages/database/src/lib/analysisBranchToDb.js.map +1 -1
  413. package/packages/database/src/lib/analysisToDb.js +1 -1
  414. package/packages/database/src/lib/analysisToDb.js.map +1 -1
  415. package/packages/database/src/lib/branchToDb.js +1 -1
  416. package/packages/database/src/lib/branchToDb.js.map +1 -1
  417. package/packages/database/src/lib/commitBranchToDb.js +1 -1
  418. package/packages/database/src/lib/commitBranchToDb.js.map +1 -1
  419. package/packages/database/src/lib/commitToDb.js +1 -1
  420. package/packages/database/src/lib/commitToDb.js.map +1 -1
  421. package/packages/database/src/lib/fileToDb.js +1 -1
  422. package/packages/database/src/lib/fileToDb.js.map +1 -1
  423. package/packages/database/src/lib/kysely/db.js +3 -0
  424. package/packages/database/src/lib/kysely/db.js.map +1 -1
  425. package/packages/database/src/lib/kysely/tables/labsRequestsTable.js +35 -0
  426. package/packages/database/src/lib/kysely/tables/labsRequestsTable.js.map +1 -0
  427. package/packages/database/src/lib/projectToDb.js +1 -1
  428. package/packages/database/src/lib/projectToDb.js.map +1 -1
  429. package/packages/database/src/lib/saveFiles.js +1 -1
  430. package/packages/database/src/lib/saveFiles.js.map +1 -1
  431. package/packages/database/src/lib/scenarioToDb.js +1 -1
  432. package/packages/database/src/lib/scenarioToDb.js.map +1 -1
  433. package/scripts/finalize-analyzer.cjs +8 -76
  434. package/codeyam-cli/src/webserver/build/client/assets/copy-Bb-80kDT.js +0 -6
  435. package/codeyam-cli/src/webserver/build/client/assets/file-code-Dhef1kWN.js +0 -6
  436. package/codeyam-cli/src/webserver/build/client/assets/globals-D3yhhV8x.css +0 -1
  437. package/codeyam-cli/src/webserver/build/client/assets/manifest-7522edd4.js +0 -1
  438. package/codeyam-cli/src/webserver/build/client/assets/memory-yxFcrxBX.js +0 -92
  439. package/codeyam-cli/src/webserver/build/client/assets/root-eVAaavTS.js +0 -62
  440. package/codeyam-cli/src/webserver/build/client/assets/settings-CS5f3WzT.js +0 -1
  441. package/codeyam-cli/src/webserver/build/server/assets/server-build-4Cr0uToj.js +0 -257
  442. package/codeyam-cli/templates/codeyam:diagnose.md +0 -803
  443. package/codeyam-cli/templates/codeyam:memory.md +0 -462
  444. package/codeyam-cli/templates/codeyam:new-rule.md +0 -13
@@ -105,11 +105,13 @@ function cleanSourceDataPath(sourceDataPath) {
105
105
  // 2. Patterns like functionName(...) - closing paren followed by dot or end
106
106
  const emptyFnCalls = (sourceDataPath.match(/\(\)/g) || []).length;
107
107
  const fnCallReturnValues = (sourceDataPath.match(/\.functionCallReturnValue/g) || []).length;
108
- // If there are multiple functionCallReturnValue occurrences, this is a chained call
109
- // (e.g., fetch(...).functionCallReturnValue.json().functionCallReturnValue.data)
108
+ // For chained function calls (e.g., fetch().json()) or paths with non-standard
109
+ // fn call patterns, return the original path so findInAttributesMapForPath can
110
+ // try to look it up in fullToShortPathMap. If it doesn't match, the caller
111
+ // falls through to fallback resolution anyway.
110
112
  if (fnCallReturnValues > 1 || emptyFnCalls !== 1) {
111
- // Multiple function calls - return null to use fallback resolution
112
- return null;
113
+ console.log(`[cleanSourceDataPath] chained/non-standard path (fnCallRVs=${fnCallReturnValues}, emptyFnCalls=${emptyFnCalls}), returning original: "${sourceDataPath}"`);
114
+ return sourceDataPath;
113
115
  }
114
116
  // Find the "()" which marks the function call
115
117
  const fnCallIndex = sourceDataPath.indexOf('()');
@@ -146,6 +148,71 @@ function stripLengthSuffix(path) {
146
148
  }
147
149
  return path;
148
150
  }
151
+ /**
152
+ * Remove contradictory required values from a compound flow.
153
+ *
154
+ * When a lifecycle boolean (like isLoadingAuditData) is traced to a fetch call's
155
+ * return value, a negated condition (!isLoadingAuditData) produces "falsy" on
156
+ * the fetch path. But if another condition in the same compound requires data
157
+ * from a sub-path of that fetch (e.g., topPaths length > 0), the "falsy" on the
158
+ * parent path contradicts it — a null/falsy response has no .json() to call.
159
+ *
160
+ * This function removes "falsy" required values whose attributePath is a prefix
161
+ * of another required value's attributePath. The child data requirement already
162
+ * implies the parent (fetch) succeeded.
163
+ */
164
+ function removeContradictoryFalsyValues(requiredValues) {
165
+ return requiredValues.filter((rv) => {
166
+ if (rv.comparison === 'falsy') {
167
+ const hasChildRequirement = requiredValues.some((other) => other !== rv &&
168
+ other.attributePath.startsWith(rv.attributePath + '.'));
169
+ if (hasChildRequirement) {
170
+ return false;
171
+ }
172
+ }
173
+ return true;
174
+ });
175
+ }
176
+ /**
177
+ * Generate a human-readable description snippet for a required value,
178
+ * incorporating the comparison type so the LLM understands the intent.
179
+ */
180
+ function describeRequiredValue(rv) {
181
+ const name = generateNameFromPath(rv.attributePath).toLowerCase();
182
+ switch (rv.comparison) {
183
+ case 'truthy':
184
+ return `${name} is present`;
185
+ case 'falsy':
186
+ return `${name} is absent`;
187
+ case 'length>':
188
+ return rv.value === '0'
189
+ ? `${name} has items`
190
+ : `${name} has more than ${rv.value} items`;
191
+ case 'length<':
192
+ return `${name} has fewer than ${rv.value} items`;
193
+ case 'equals':
194
+ return `${name} is ${rv.value}`;
195
+ case 'exists':
196
+ return `${name} exists`;
197
+ case 'not-exists':
198
+ return `${name} does not exist`;
199
+ default:
200
+ return `${name} is ${rv.value}`;
201
+ }
202
+ }
203
+ /**
204
+ * Check whether a resolved path has child entries in the fullToShortPathMap.
205
+ *
206
+ * When a lifecycle boolean (e.g., isLoadingAuditData) resolves to a parent path
207
+ * like fetch(...).functionCallReturnValue, and that path has children (like
208
+ * .json().functionCallReturnValue.topPaths), individual truthy/falsy flows on
209
+ * the parent are misleading. Compound flows with specific child requirements
210
+ * provide better guidance for mock data generation.
211
+ */
212
+ function hasChildPathsInMap(resolvedPath, fullToShortPathMap) {
213
+ return Object.keys(fullToShortPathMap).some((fullPath) => fullPath.startsWith(resolvedPath + '.') ||
214
+ fullPath.startsWith(resolvedPath + '['));
215
+ }
149
216
  /**
150
217
  * Extract the controllable base path from a path that may contain method calls.
151
218
  *
@@ -184,9 +251,10 @@ function extractControllableBase(path) {
184
251
  * The sourceDataPath contains full paths (e.g., "useLoaderData<LoaderData>().functionCallReturnValue.entity.sha")
185
252
  * The fullToShortPathMap maps full paths to short paths
186
253
  */
187
- function findInAttributesMapForPath(path, attributesMap, fullToShortPathMap) {
254
+ export function findInAttributesMapForPath(path, attributesMap, fullToShortPathMap) {
188
255
  // Direct match in attributesMap (already a short path)
189
256
  if (path in attributesMap) {
257
+ console.log(`[findInAttributesMapForPath] "${path}" → DIRECT match in attributesMap`);
190
258
  return path;
191
259
  }
192
260
  // Try looking up the path in fullToShortPathMap to verify it's controllable
@@ -194,18 +262,22 @@ function findInAttributesMapForPath(path, attributesMap, fullToShortPathMap) {
194
262
  if (path in fullToShortPathMap) {
195
263
  const shortPath = fullToShortPathMap[path];
196
264
  if (shortPath in attributesMap) {
265
+ console.log(`[findInAttributesMapForPath] "${path}" → fullToShortPathMap match: shortPath="${shortPath}" found in attributesMap`);
197
266
  return path; // Return FULL path to preserve data source context
198
267
  }
268
+ console.log(`[findInAttributesMapForPath] "${path}" → fullToShortPathMap match shortPath="${shortPath}" but NOT in attributesMap`);
199
269
  }
200
270
  // Normalized match (array indices [N] → [])
201
271
  const normalizedPath = path.replace(/\[\d+\]/g, '[]');
202
272
  if (normalizedPath !== path) {
203
273
  if (normalizedPath in attributesMap) {
274
+ console.log(`[findInAttributesMapForPath] "${path}" → normalized "${normalizedPath}" DIRECT match in attributesMap`);
204
275
  return normalizedPath;
205
276
  }
206
277
  if (normalizedPath in fullToShortPathMap) {
207
278
  const shortPath = fullToShortPathMap[normalizedPath];
208
279
  if (shortPath in attributesMap) {
280
+ console.log(`[findInAttributesMapForPath] "${path}" → normalized "${normalizedPath}" fullToShortPathMap match: shortPath="${shortPath}"`);
209
281
  return normalizedPath; // Return normalized FULL path
210
282
  }
211
283
  }
@@ -216,20 +288,70 @@ function findInAttributesMapForPath(path, attributesMap, fullToShortPathMap) {
216
288
  // and we need to find matching short path prefix
217
289
  for (const attrPath of Object.keys(attributesMap)) {
218
290
  if (path.startsWith(attrPath + '.') || path.startsWith(attrPath + '[')) {
219
- // The path is a child of a known attribute path
291
+ console.log(`[findInAttributesMapForPath] "${path}" PREFIX match: starts with attributesMap key "${attrPath}"`);
220
292
  return path;
221
293
  }
222
294
  }
223
295
  // Try suffix matching: if the path ends with ".X.Y.Z" and attributesMap has "X.Y.Z"
224
296
  // Return the FULL input path to preserve data source context
225
- for (const attrPath of Object.keys(attributesMap)) {
226
- if (path.endsWith('.' + attrPath) ||
227
- path.endsWith('.' + attrPath.replace(/\[\d+\]/g, '[]'))) {
228
- return path; // Return FULL path, not short attrPath
297
+ // Skip suffix matching for chained function calls (multiple .functionCallReturnValue segments)
298
+ // to avoid false matches: e.g., fetch(...).json().functionCallReturnValue.data falsely matching
299
+ // "data" from a completely different data source like useFetcher
300
+ const fnCallReturnValueCount = (path.match(/\.functionCallReturnValue/g) || []).length;
301
+ if (fnCallReturnValueCount <= 1) {
302
+ for (const attrPath of Object.keys(attributesMap)) {
303
+ if (path.endsWith('.' + attrPath) ||
304
+ path.endsWith('.' + attrPath.replace(/\[\d+\]/g, '[]'))) {
305
+ console.log(`[findInAttributesMapForPath] "${path}" → SUFFIX match: ends with attributesMap key "${attrPath}"`);
306
+ return path; // Return FULL path, not short attrPath
307
+ }
308
+ }
309
+ }
310
+ // Try child path matching against fullToShortPathMap keys
311
+ // If the path starts with a known full path + '.' or '[', it's a child
312
+ // of a controllable path. Build the equivalent short child path.
313
+ // e.g., path = "fetch(...).fCRV.json().fCRV.topPaths.length"
314
+ // fullToShortPathMap has "fetch(...).fCRV.json().fCRV.topPaths" → "json().fCRV.topPaths"
315
+ // → check if "json().fCRV.topPaths.length" is in attributesMap
316
+ for (const [fullPath, shortPath] of Object.entries(fullToShortPathMap)) {
317
+ if (path.startsWith(fullPath + '.') || path.startsWith(fullPath + '[')) {
318
+ const suffix = path.slice(fullPath.length); // e.g., ".length"
319
+ const shortChildPath = shortPath + suffix;
320
+ if (shortChildPath in attributesMap) {
321
+ console.log(`[findInAttributesMapForPath] "${path}" → CHILD of fullToShortPathMap key "${fullPath}": shortChildPath="${shortChildPath}" found in attributesMap`);
322
+ return path; // Return full path to preserve data source context
323
+ }
324
+ // Also check if the base short path is an array and suffix is .length
325
+ if (suffix === '.length' && shortPath in attributesMap) {
326
+ console.log(`[findInAttributesMapForPath] "${path}" → CHILD .length of fullToShortPathMap key "${fullPath}": base shortPath="${shortPath}" is in attributesMap (array .length)`);
327
+ return path; // Array .length is controllable via the array
328
+ }
329
+ }
330
+ }
331
+ // Try parent matching: if the path is a prefix of any fullToShortPathMap key,
332
+ // it's a parent of controllable data and therefore controllable itself
333
+ for (const fullPath of Object.keys(fullToShortPathMap)) {
334
+ if (fullPath.startsWith(path + '.') || fullPath.startsWith(path + '[')) {
335
+ console.log(`[findInAttributesMapForPath] "${path}" → PARENT match: fullToShortPathMap key "${fullPath}" starts with this path`);
336
+ return path;
229
337
  }
230
338
  }
339
+ console.log(`[findInAttributesMapForPath] "${path}" → NO MATCH (checked ${Object.keys(attributesMap).length} attributesMap keys, ${Object.keys(fullToShortPathMap).length} fullToShortPathMap keys)`);
231
340
  return null;
232
341
  }
342
+ /**
343
+ * Generate a slug from a path for use in flow IDs and exclusive groups.
344
+ */
345
+ function pathToSlug(path) {
346
+ return path
347
+ .replace(/\[\d+\]/g, '')
348
+ .replace(/\[\]/g, '')
349
+ .replace(/\(\)/g, '')
350
+ .replace(/\.functionCallReturnValue/g, '')
351
+ .replace(/[<>]/g, '')
352
+ .replace(/\./g, '-')
353
+ .toLowerCase();
354
+ }
233
355
  /**
234
356
  * Generate a human-readable name from a path.
235
357
  * Extracts the last meaningful part of the path.
@@ -419,7 +541,17 @@ function generateFlowFromCompound(compound, resolvedPaths) {
419
541
  condition.requiredValue?.toString() ??
420
542
  condition.comparedValues?.[0] ??
421
543
  'truthy';
422
- comparison = 'equals';
544
+ // Map comparison operator to flow comparison type
545
+ const op = condition.comparisonOperator;
546
+ if (op === '>' || op === '>=') {
547
+ comparison = 'length>';
548
+ }
549
+ else if (op === '<' || op === '<=') {
550
+ comparison = 'length<';
551
+ }
552
+ else {
553
+ comparison = 'equals';
554
+ }
423
555
  }
424
556
  requiredValues.push({
425
557
  attributePath: stripLengthSuffix(resolvedPath),
@@ -428,20 +560,28 @@ function generateFlowFromCompound(compound, resolvedPaths) {
428
560
  valueType: inferValueType(value),
429
561
  });
430
562
  }
431
- // Generate a combined ID from all paths
432
- const pathParts = requiredValues
563
+ // Remove contradictory "falsy" values where a child path requires data
564
+ const cleanedValues = removeContradictoryFalsyValues(requiredValues);
565
+ if (cleanedValues.length === 0) {
566
+ return null;
567
+ }
568
+ // Generate a combined ID from all paths + values to distinguish different comparisons
569
+ const pathParts = cleanedValues
433
570
  .map((rv) => {
434
571
  const name = generateNameFromPath(rv.attributePath);
435
- return name.toLowerCase().replace(/\s+/g, '-');
572
+ const suffix = rv.comparison === 'truthy' || rv.comparison === 'falsy'
573
+ ? `-${rv.comparison}`
574
+ : `-${rv.comparison}-${rv.value}`;
575
+ return name.toLowerCase().replace(/\s+/g, '-') + suffix;
436
576
  })
437
577
  .join('-and-');
438
578
  return {
439
579
  id: `compound-${pathParts}`,
440
- name: requiredValues
580
+ name: cleanedValues
441
581
  .map((rv) => generateNameFromPath(rv.attributePath))
442
582
  .join(' + '),
443
- description: `When ${requiredValues.map((rv) => `${generateNameFromPath(rv.attributePath).toLowerCase()} is ${rv.value}`).join(' and ')}`,
444
- requiredValues,
583
+ description: `When ${cleanedValues.map((rv) => describeRequiredValue(rv)).join(' and ')}`,
584
+ requiredValues: cleanedValues,
445
585
  impact,
446
586
  sourceLocation: {
447
587
  lineNumber: compound.sourceLocation.lineNumber,
@@ -557,7 +697,11 @@ function translateChildPathToParent(childPath, childEquivalentSignatureVariables
557
697
  }
558
698
  // Look up the child's equivalence for this root variable
559
699
  // e.g., childEquiv[selectedScenario] = "signature[0].selectedScenario"
560
- const childPropPath = childEquivalentSignatureVariables[rootVar];
700
+ // Handle array case (OR expressions) - use first element if array
701
+ const rawChildPropPath = childEquivalentSignatureVariables[rootVar];
702
+ const childPropPath = Array.isArray(rawChildPropPath)
703
+ ? rawChildPropPath[0]
704
+ : rawChildPropPath;
561
705
  if (!childPropPath) {
562
706
  // No mapping found - this might be internal state, not a prop
563
707
  return null;
@@ -567,7 +711,11 @@ function translateChildPathToParent(childPath, childEquivalentSignatureVariables
567
711
  const fullChildPropPath = `${childName}().${childPropPath}`;
568
712
  // Look up parent's equivalence to find what value was passed to this prop
569
713
  // e.g., parentEquiv["ChildName().signature[0].selectedScenario"] = "selectedScenario"
570
- const parentValue = parentEquivalentSignatureVariables[fullChildPropPath];
714
+ // Handle array case (OR expressions) - use first element if array
715
+ const rawParentValue = parentEquivalentSignatureVariables[fullChildPropPath];
716
+ const parentValue = Array.isArray(rawParentValue)
717
+ ? rawParentValue[0]
718
+ : rawParentValue;
571
719
  if (!parentValue) {
572
720
  // No parent mapping found - log ALL parent keys that contain the childName
573
721
  const relevantParentKeys = Object.keys(parentEquivalentSignatureVariables).filter((k) => k.includes(childName));
@@ -579,9 +727,14 @@ function translateChildPathToParent(childPath, childEquivalentSignatureVariables
579
727
  return result;
580
728
  }
581
729
  export default function generateExecutionFlowsFromConditionals(args) {
582
- const { conditionalUsages, compoundConditionals, attributesMap, equivalentSignatureVariables, fullToShortPathMap, childComponentData, derivedVariables, } = args;
730
+ const { conditionalUsages, compoundConditionals, attributesMap, equivalentSignatureVariables, fullToShortPathMap, childComponentData, derivedVariables, sourceEquivalencies, } = args;
583
731
  const flows = [];
584
732
  const seenFlowIds = new Set();
733
+ console.log(`[genFlowsFromConditionals] INPUT: ${Object.keys(conditionalUsages).length} conditional paths, ${Object.keys(attributesMap).length} attributesMap entries, ${Object.keys(fullToShortPathMap).length} fullToShortPathMap entries, ${Object.keys(equivalentSignatureVariables).length} equivSigVars, ${compoundConditionals.length} compound conditionals`);
734
+ console.log(`[genFlowsFromConditionals] conditionalUsages keys: [${Object.keys(conditionalUsages).join(', ')}]`);
735
+ console.log(`[genFlowsFromConditionals] attributesMap keys: [${Object.keys(attributesMap).join(', ')}]`);
736
+ console.log(`[genFlowsFromConditionals] fullToShortPathMap: ${JSON.stringify(fullToShortPathMap)}`);
737
+ console.log(`[genFlowsFromConditionals] equivalentSignatureVariables: ${JSON.stringify(equivalentSignatureVariables)}`);
585
738
  // Track normalized resolved paths to prevent duplicate flows
586
739
  // This handles the case where we have usages for both:
587
740
  // - "hasNewerVersion" (short path from destructured variable)
@@ -595,8 +748,10 @@ export default function generateExecutionFlowsFromConditionals(args) {
595
748
  for (const usage of usages) {
596
749
  // Skip usages that are part of compound conditionals (handled separately)
597
750
  if (usage.chainId && compoundChainIds.has(usage.chainId)) {
751
+ console.log(`[genFlowsFromConditionals] "${usage.path}" SKIP: part of compound conditional chain=${usage.chainId}`);
598
752
  continue;
599
753
  }
754
+ console.log(`[genFlowsFromConditionals] --- Processing "${usage.path}" (type=${usage.conditionType}, negated=${usage.isNegated}, sourceDataPath="${usage.sourceDataPath ?? '(none)'}", derivedFrom=${usage.derivedFrom ? JSON.stringify(usage.derivedFrom) : 'none'})`);
600
755
  // First, try to use pre-computed sourceDataPath if available
601
756
  let resolvedPath = null;
602
757
  if (usage.sourceDataPath) {
@@ -605,9 +760,11 @@ export default function generateExecutionFlowsFromConditionals(args) {
605
760
  // should become "useLoaderData<LoaderData>().functionCallReturnValue.entity.sha"
606
761
  // Returns null for malformed paths (e.g., chained function calls like fetch().json())
607
762
  const cleanedPath = cleanSourceDataPath(usage.sourceDataPath);
763
+ console.log(`[genFlowsFromConditionals] "${usage.path}" cleanSourceDataPath("${usage.sourceDataPath}") → "${cleanedPath}"`);
608
764
  if (cleanedPath) {
609
765
  // Verify the cleaned path exists in attributesMap
610
766
  const pathMatch = findInAttributesMapForPath(cleanedPath, attributesMap, fullToShortPathMap);
767
+ console.log(`[genFlowsFromConditionals] "${usage.path}" findInAttributesMapForPath("${cleanedPath}") → ${pathMatch ? `"${pathMatch}"` : 'null (not found)'}`);
611
768
  if (pathMatch) {
612
769
  resolvedPath = pathMatch;
613
770
  }
@@ -616,7 +773,9 @@ export default function generateExecutionFlowsFromConditionals(args) {
616
773
  }
617
774
  // Fall back to resolution via equivalentSignatureVariables
618
775
  if (!resolvedPath) {
776
+ console.log(`[genFlowsFromConditionals] "${usage.path}" sourceDataPath resolution failed, trying resolvePathToControllable("${usage.path}")...`);
619
777
  const resolution = resolvePathToControllable(usage.path, attributesMap, equivalentSignatureVariables, fullToShortPathMap);
778
+ console.log(`[genFlowsFromConditionals] "${usage.path}" resolvePathToControllable → isControllable=${resolution.isControllable}, resolvedPath="${resolution.resolvedPath ?? '(none)'}"`);
620
779
  if (resolution.isControllable && resolution.resolvedPath) {
621
780
  resolvedPath = resolution.resolvedPath;
622
781
  }
@@ -626,6 +785,7 @@ export default function generateExecutionFlowsFromConditionals(args) {
626
785
  // where hasAnalysis is not in attributesMap but analysis is
627
786
  if (!resolvedPath && usage.derivedFrom) {
628
787
  const { operation, sourcePath, sourcePaths, comparedValue } = usage.derivedFrom;
788
+ console.log(`[genFlowsFromConditionals] "${usage.path}" trying derivedFrom: operation=${operation}, sourcePath="${sourcePath ?? '(none)'}", sourcePaths=${sourcePaths ? JSON.stringify(sourcePaths) : '(none)'}, comparedValue="${comparedValue ?? '(none)'}"`);
629
789
  // For single-source derivations (notNull, equals, etc.)
630
790
  if (sourcePath) {
631
791
  const resolution = resolvePathToControllable(sourcePath, attributesMap, equivalentSignatureVariables, fullToShortPathMap);
@@ -871,6 +1031,7 @@ export default function generateExecutionFlowsFromConditionals(args) {
871
1031
  }
872
1032
  if (!resolvedPath) {
873
1033
  // Path is not controllable - skip (no invalid flows possible)
1034
+ console.log(`[genFlowsFromConditionals] "${usage.path}" SKIP: not controllable (no resolvedPath after all attempts)`);
874
1035
  continue;
875
1036
  }
876
1037
  // Normalize the resolved path to detect duplicates
@@ -880,9 +1041,22 @@ export default function generateExecutionFlowsFromConditionals(args) {
880
1041
  // Skip if we've already generated flows for this normalized path
881
1042
  // This prevents duplicate flows when we have usages for both short and full paths
882
1043
  if (seenNormalizedPaths.has(normalizedPath)) {
1044
+ console.log(`[genFlowsFromConditionals] "${usage.path}" SKIP: duplicate normalizedPath="${normalizedPath}" (resolvedPath="${resolvedPath}")`);
883
1045
  continue;
884
1046
  }
885
1047
  seenNormalizedPaths.add(normalizedPath);
1048
+ // Skip individual truthy/falsy flows on parent paths that have child data entries.
1049
+ // Lifecycle booleans (like isLoadingAuditData) traced to fetch(...).functionCallReturnValue
1050
+ // produce misleading truthy/falsy flows: "truthy" can't show loading (mock resolves instantly),
1051
+ // "falsy" tells the LLM to return null (breaking .json()). Compound flows with specific child
1052
+ // data requirements provide the correct mock guidance.
1053
+ if (usage.conditionType === 'truthiness' &&
1054
+ resolvedPath &&
1055
+ hasChildPathsInMap(resolvedPath, fullToShortPathMap)) {
1056
+ console.log(`[genFlowsFromConditionals] "${usage.path}" SKIP: parent path "${resolvedPath}" has child data paths — compound flows will handle this`);
1057
+ continue;
1058
+ }
1059
+ console.log(`[genFlowsFromConditionals] "${usage.path}" RESOLVED → resolvedPath="${resolvedPath}", normalizedPath="${normalizedPath}" — generating flows`);
886
1060
  // Generate flows for this controllable usage
887
1061
  const usageFlows = generateFlowsFromUsage(usage, resolvedPath);
888
1062
  for (const flow of usageFlows) {
@@ -890,6 +1064,7 @@ export default function generateExecutionFlowsFromConditionals(args) {
890
1064
  if (!seenFlowIds.has(flow.id)) {
891
1065
  seenFlowIds.add(flow.id);
892
1066
  flows.push(flow);
1067
+ console.log(`[genFlowsFromConditionals] "${usage.path}" FLOW ADDED: id="${flow.id}", requiredValues=${JSON.stringify(flow.requiredValues.map((rv) => ({ attr: rv.attributePath, val: rv.value })))}`);
893
1068
  }
894
1069
  }
895
1070
  }
@@ -925,19 +1100,57 @@ export default function generateExecutionFlowsFromConditionals(args) {
925
1100
  resolvedPaths.set(condition.path, sources[0].path);
926
1101
  }
927
1102
  else {
928
- // Derived variable but no controllable sources found
929
- allControllable = false;
930
- break;
1103
+ // Derived variable expansion failed try sourceDataPath fallback
1104
+ // This handles cases where the derivation chain goes through useMemo/useState
1105
+ // but the enriched sourceDataPath already traced to the actual data source
1106
+ const usageWithSource = usagesForPath?.find((u) => u.sourceDataPath);
1107
+ let derivedFallbackPath = null;
1108
+ if (usageWithSource?.sourceDataPath) {
1109
+ const cleanedPath = cleanSourceDataPath(usageWithSource.sourceDataPath);
1110
+ if (cleanedPath) {
1111
+ const pathMatch = findInAttributesMapForPath(cleanedPath, attributesMap, fullToShortPathMap);
1112
+ if (pathMatch) {
1113
+ derivedFallbackPath = pathMatch;
1114
+ }
1115
+ }
1116
+ }
1117
+ if (derivedFallbackPath) {
1118
+ resolvedPaths.set(condition.path, derivedFallbackPath);
1119
+ console.log(`[genFlowsFromConditionals] COMPOUND "${condition.path}" derived expansion failed but sourceDataPath fallback resolved → "${derivedFallbackPath}"`);
1120
+ }
1121
+ else {
1122
+ // Truly not controllable
1123
+ console.log(`[genFlowsFromConditionals] COMPOUND "${condition.path}" derived but no controllable sources and no sourceDataPath fallback → NOT controllable`);
1124
+ allControllable = false;
1125
+ break;
1126
+ }
931
1127
  }
932
1128
  }
933
1129
  else {
934
1130
  // Not a derived variable - resolve directly
935
- const resolution = resolvePathToControllable(condition.path, attributesMap, equivalentSignatureVariables, fullToShortPathMap);
936
- if (!resolution.isControllable || !resolution.resolvedPath) {
1131
+ // First try sourceDataPath from the usage (same as individual processing)
1132
+ let compoundResolvedPath = null;
1133
+ const usageWithSource = usagesForPath?.find((u) => u.sourceDataPath);
1134
+ if (usageWithSource?.sourceDataPath) {
1135
+ const cleanedPath = cleanSourceDataPath(usageWithSource.sourceDataPath);
1136
+ if (cleanedPath) {
1137
+ const pathMatch = findInAttributesMapForPath(cleanedPath, attributesMap, fullToShortPathMap);
1138
+ if (pathMatch) {
1139
+ compoundResolvedPath = pathMatch;
1140
+ }
1141
+ }
1142
+ }
1143
+ if (!compoundResolvedPath) {
1144
+ const resolution = resolvePathToControllable(condition.path, attributesMap, equivalentSignatureVariables, fullToShortPathMap);
1145
+ if (resolution.isControllable && resolution.resolvedPath) {
1146
+ compoundResolvedPath = resolution.resolvedPath;
1147
+ }
1148
+ }
1149
+ if (!compoundResolvedPath) {
937
1150
  allControllable = false;
938
1151
  break;
939
1152
  }
940
- resolvedPaths.set(condition.path, resolution.resolvedPath);
1153
+ resolvedPaths.set(condition.path, compoundResolvedPath);
941
1154
  }
942
1155
  }
943
1156
  // Only create a flow if ALL paths are controllable
@@ -1010,7 +1223,16 @@ export default function generateExecutionFlowsFromConditionals(args) {
1010
1223
  condition.requiredValue?.toString() ??
1011
1224
  condition.comparedValues?.[0] ??
1012
1225
  'truthy';
1013
- comparison = 'equals';
1226
+ const op = condition.comparisonOperator;
1227
+ if (op === '>' || op === '>=') {
1228
+ comparison = 'length>';
1229
+ }
1230
+ else if (op === '<' || op === '<=') {
1231
+ comparison = 'length<';
1232
+ }
1233
+ else {
1234
+ comparison = 'equals';
1235
+ }
1014
1236
  }
1015
1237
  requiredValues.push({
1016
1238
  attributePath: stripLengthSuffix(resolvedPath),
@@ -1021,21 +1243,26 @@ export default function generateExecutionFlowsFromConditionals(args) {
1021
1243
  }
1022
1244
  }
1023
1245
  }
1024
- if (requiredValues.length > 0) {
1246
+ // Remove contradictory "falsy" values where a child path requires data
1247
+ const cleanedValues = removeContradictoryFalsyValues(requiredValues);
1248
+ if (cleanedValues.length > 0) {
1025
1249
  const impact = compound.controlsJsxRendering ? 'high' : 'medium';
1026
- // Generate a combined ID from all paths
1027
- const pathParts = requiredValues
1250
+ // Generate a combined ID from all paths + values
1251
+ const pathParts = cleanedValues
1028
1252
  .map((rv) => {
1029
1253
  const name = generateNameFromPath(rv.attributePath);
1030
- return name.toLowerCase().replace(/\s+/g, '-');
1254
+ const suffix = rv.comparison === 'truthy' || rv.comparison === 'falsy'
1255
+ ? `-${rv.comparison}`
1256
+ : `-${rv.comparison}-${rv.value}`;
1257
+ return name.toLowerCase().replace(/\s+/g, '-') + suffix;
1031
1258
  })
1032
1259
  .join('-and-');
1033
1260
  const compoundFlow = {
1034
- id: `${pathParts}-${requiredValues.map((rv) => rv.value).join('-')}`,
1035
- name: generateNameFromPath(requiredValues[0].attributePath),
1036
- description: `When ${requiredValues.map((rv) => `${generateNameFromPath(rv.attributePath).toLowerCase()} is ${rv.value}`).join(' and ')}`,
1261
+ id: `${pathParts}`,
1262
+ name: generateNameFromPath(cleanedValues[0].attributePath),
1263
+ description: `When ${cleanedValues.map((rv) => describeRequiredValue(rv)).join(' and ')}`,
1037
1264
  impact,
1038
- requiredValues,
1265
+ requiredValues: cleanedValues,
1039
1266
  sourceLocation: compound.sourceLocation,
1040
1267
  };
1041
1268
  if (!seenFlowIds.has(compoundFlow.id)) {
@@ -1195,8 +1422,6 @@ export default function generateExecutionFlowsFromConditionals(args) {
1195
1422
  const childCompoundChainIds = new Set(childData.compoundConditionals.map((c) => c.chainId).filter(Boolean));
1196
1423
  for (const [_path, usages] of Object.entries(childData.conditionalUsages)) {
1197
1424
  for (const usage of usages) {
1198
- // Debug logging (disabled - set to true for troubleshooting child flow resolution)
1199
- const shouldDebugChild = false;
1200
1425
  // Skip usages that are part of compound conditionals (handled separately)
1201
1426
  // Fix 33: Only skip if the chainId is in the child's compound conditionals
1202
1427
  if (usage.chainId && childCompoundChainIds.has(usage.chainId)) {
@@ -1208,43 +1433,23 @@ export default function generateExecutionFlowsFromConditionals(args) {
1208
1433
  if (usage.derivedFrom?.sourcePath) {
1209
1434
  childPath = usage.derivedFrom.sourcePath;
1210
1435
  }
1211
- if (shouldDebugChild) {
1212
- console.log(`[DEBUG CHILD ${childName}] Processing usage path: ${usage.path}`);
1213
- console.log(`[DEBUG CHILD ${childName}] childPath (after derivedFrom): ${childPath}`);
1214
- console.log(`[DEBUG CHILD ${childName}] sourceDataPath: ${usage.sourceDataPath}`);
1215
- }
1216
1436
  // Translate the child path to a parent path
1217
1437
  let translatedPath = translateChildPathToParent(childPath, childData.equivalentSignatureVariables, equivalentSignatureVariables, childName);
1218
- if (shouldDebugChild) {
1219
- console.log(`[DEBUG CHILD ${childName}] translatedPath (from translateChildPathToParent): ${translatedPath}`);
1220
- }
1221
1438
  // If translation failed but we have sourceDataPath, try to extract the prop path from it
1222
1439
  // sourceDataPath format: "ChildName.signature[n].propPath.rest" → extract "propPath.rest"
1223
1440
  if (!translatedPath && usage.sourceDataPath) {
1224
1441
  const signatureMatch = usage.sourceDataPath.match(/\.signature\[\d+\]\.(.+)$/);
1225
1442
  if (signatureMatch) {
1226
1443
  translatedPath = signatureMatch[1];
1227
- if (shouldDebugChild) {
1228
- console.log(`[DEBUG CHILD ${childName}] translatedPath (from sourceDataPath regex): ${translatedPath}`);
1229
- }
1230
1444
  }
1231
1445
  }
1232
1446
  if (!translatedPath) {
1233
1447
  // Could not translate - skip this usage
1234
- if (shouldDebugChild) {
1235
- console.log(`[DEBUG CHILD ${childName}] SKIPPED - no translation found`);
1236
- }
1237
1448
  continue;
1238
1449
  }
1239
1450
  // Now resolve the translated path in the parent context
1240
1451
  // First, try standard resolution
1241
1452
  const resolution = resolvePathToControllable(translatedPath, attributesMap, equivalentSignatureVariables, fullToShortPathMap);
1242
- if (shouldDebugChild) {
1243
- console.log(`[DEBUG CHILD ${childName}] resolvePathToControllable result:`);
1244
- console.log(`[DEBUG CHILD ${childName}] isControllable: ${resolution.isControllable}`);
1245
- console.log(`[DEBUG CHILD ${childName}] resolvedPath: ${resolution.resolvedPath}`);
1246
- console.log(`[DEBUG CHILD ${childName}] chain: ${resolution.resolutionChain.join(' -> ')}`);
1247
- }
1248
1453
  // Only create flows for controllable paths (whitelist approach).
1249
1454
  // If the path doesn't resolve to something in attributesMap, skip it.
1250
1455
  // This prevents creating flows for useState values which are not
@@ -1271,19 +1476,10 @@ export default function generateExecutionFlowsFromConditionals(args) {
1271
1476
  break;
1272
1477
  }
1273
1478
  }
1274
- if (shouldDebugChild) {
1275
- console.log(`[DEBUG CHILD ${childName}] useState fallback: looking for URL param`);
1276
- console.log(`[DEBUG CHILD ${childName}] useStatePattern: ${useStatePattern}`);
1277
- console.log(`[DEBUG CHILD ${childName}] useStateVarName: ${useStateVarName}`);
1278
- }
1279
1479
  if (useStateVarName) {
1280
1480
  // Look for a related URL param like "varNameFromUrl"
1281
1481
  const urlParamName = `${useStateVarName}FromUrl`;
1282
1482
  const urlParamPath = equivalentSignatureVariables[urlParamName];
1283
- if (shouldDebugChild) {
1284
- console.log(`[DEBUG CHILD ${childName}] urlParamName: ${urlParamName}`);
1285
- console.log(`[DEBUG CHILD ${childName}] urlParamPath: ${urlParamPath}`);
1286
- }
1287
1483
  if (urlParamPath) {
1288
1484
  // For useState values initialized from URL params, use the
1289
1485
  // URL param variable name directly (e.g., "viewModeFromUrl")
@@ -1294,26 +1490,58 @@ export default function generateExecutionFlowsFromConditionals(args) {
1294
1490
  // The flow will use the URL param name as the attributePath,
1295
1491
  // which gets properly resolved when generating mock data.
1296
1492
  resolvedPath = urlParamName;
1297
- if (shouldDebugChild) {
1298
- console.log(`[DEBUG CHILD ${childName}] useState fallback SUCCESS: using URL param name ${resolvedPath}`);
1493
+ }
1494
+ }
1495
+ }
1496
+ // Fallback 2: Try sourceEquivalencies to find the actual data source
1497
+ // This handles the case where props flow through useState but originate
1498
+ // from a mockable data source (e.g., API call, fetcher).
1499
+ //
1500
+ // Example: WorkoutsView receives `workouts` prop which in parent is stored
1501
+ // in useState, but ultimately comes from a Supabase query.
1502
+ // sourceEquivalencies tells us: "WorkoutsView().signature[0].workouts" → "createClient()...data"
1503
+ if (!resolvedPath && sourceEquivalencies) {
1504
+ // Build the child prop path to look up in sourceEquivalencies
1505
+ // Format: "ChildName().signature[0].propName"
1506
+ // First, find what prop this child path maps to
1507
+ let childPropName = null;
1508
+ for (const [varName, varPath] of Object.entries(childData.equivalentSignatureVariables)) {
1509
+ // Check if childPath starts with this variable name
1510
+ // e.g., childPath = "workouts.length", varName = "workouts", varPath = "signature[0].workouts"
1511
+ if (childPath === varName ||
1512
+ childPath.startsWith(`${varName}.`)) {
1513
+ childPropName = varName;
1514
+ break;
1515
+ }
1516
+ }
1517
+ if (childPropName) {
1518
+ // Build the full sourceEquivalencies key
1519
+ const sourceEquivKey = `${childName}().signature[0].${childPropName}`;
1520
+ const sourceEquivEntry = sourceEquivalencies[sourceEquivKey];
1521
+ if (sourceEquivEntry && sourceEquivEntry.length > 0) {
1522
+ const dataSourcePath = sourceEquivEntry[0].schemaPath;
1523
+ // Check if this data source path is controllable
1524
+ const dataSourceResolution = resolvePathToControllable(dataSourcePath, attributesMap, equivalentSignatureVariables, fullToShortPathMap);
1525
+ if (dataSourceResolution.isControllable &&
1526
+ dataSourceResolution.resolvedPath) {
1527
+ // Preserve any suffix from the child path
1528
+ // e.g., childPath = "workouts.length" → suffix = ".length"
1529
+ const suffix = childPath.startsWith(`${childPropName}.`)
1530
+ ? childPath.slice(childPropName.length)
1531
+ : '';
1532
+ resolvedPath = dataSourceResolution.resolvedPath + suffix;
1299
1533
  }
1300
1534
  }
1301
1535
  }
1302
1536
  }
1303
1537
  // If still not resolved after fallback, skip
1304
1538
  if (!resolvedPath) {
1305
- if (shouldDebugChild) {
1306
- console.log(`[DEBUG CHILD ${childName}] SKIPPED - path not controllable`);
1307
- }
1308
1539
  continue;
1309
1540
  }
1310
1541
  }
1311
1542
  // Check for duplicates
1312
1543
  const normalizedPath = normalizePathForDeduplication(resolvedPath, fullToShortPathMap);
1313
1544
  if (seenNormalizedPaths.has(normalizedPath)) {
1314
- if (shouldDebugChild) {
1315
- console.log(`[DEBUG CHILD ${childName}] SKIPPED - duplicate normalized path: ${normalizedPath}`);
1316
- }
1317
1545
  continue;
1318
1546
  }
1319
1547
  seenNormalizedPaths.add(normalizedPath);
@@ -1324,12 +1552,6 @@ export default function generateExecutionFlowsFromConditionals(args) {
1324
1552
  path: resolvedPath,
1325
1553
  };
1326
1554
  const usageFlows = generateFlowsFromUsage(translatedUsage, resolvedPath);
1327
- if (shouldDebugChild) {
1328
- console.log(`[DEBUG CHILD ${childName}] GENERATING ${usageFlows.length} flows with resolvedPath: ${resolvedPath}`);
1329
- for (const f of usageFlows) {
1330
- console.log(`[DEBUG CHILD ${childName}] - Flow ID: ${f.id}, path: ${f.requiredValues[0]?.attributePath}`);
1331
- }
1332
- }
1333
1555
  // Add gating conditions to each flow
1334
1556
  for (const flow of usageFlows) {
1335
1557
  // Add gating required values to the flow
@@ -1433,8 +1655,153 @@ export default function generateExecutionFlowsFromConditionals(args) {
1433
1655
  }
1434
1656
  }
1435
1657
  }
1658
+ // Process child's jsxRenderingUsages (array.map flows)
1659
+ // This generates array variation flows (empty, few, many) for arrays rendered in child
1660
+ if (childData.jsxRenderingUsages) {
1661
+ for (const jsxUsage of childData.jsxRenderingUsages) {
1662
+ // Translate the child path to a parent path
1663
+ const translatedPath = translateChildPathToParent(jsxUsage.path, childData.equivalentSignatureVariables, equivalentSignatureVariables, childName);
1664
+ if (!translatedPath) {
1665
+ continue;
1666
+ }
1667
+ // Resolve to controllable path in parent context
1668
+ const resolution = resolvePathToControllable(translatedPath, attributesMap, equivalentSignatureVariables, fullToShortPathMap);
1669
+ let resolvedPath = resolution.resolvedPath;
1670
+ // Try sourceEquivalencies fallback if not controllable
1671
+ if (!resolution.isControllable || !resolvedPath) {
1672
+ if (sourceEquivalencies) {
1673
+ // Build the sourceEquivalencies key
1674
+ // The child path (e.g., "workouts") maps to a prop path (e.g., "signature[0].workouts")
1675
+ let childPropName = null;
1676
+ for (const [varName, varPath] of Object.entries(childData.equivalentSignatureVariables)) {
1677
+ if (jsxUsage.path === varName ||
1678
+ jsxUsage.path.startsWith(`${varName}.`)) {
1679
+ childPropName = varName;
1680
+ break;
1681
+ }
1682
+ }
1683
+ if (childPropName) {
1684
+ const sourceEquivKey = `${childName}().signature[0].${childPropName}`;
1685
+ const sourceEquivEntry = sourceEquivalencies[sourceEquivKey];
1686
+ if (sourceEquivEntry && sourceEquivEntry.length > 0) {
1687
+ const dataSourcePath = sourceEquivEntry[0].schemaPath;
1688
+ const dataSourceResolution = resolvePathToControllable(dataSourcePath, attributesMap, equivalentSignatureVariables, fullToShortPathMap);
1689
+ if (dataSourceResolution.isControllable &&
1690
+ dataSourceResolution.resolvedPath) {
1691
+ resolvedPath = dataSourceResolution.resolvedPath;
1692
+ }
1693
+ }
1694
+ }
1695
+ }
1696
+ }
1697
+ if (!resolvedPath) {
1698
+ continue;
1699
+ }
1700
+ // Check for duplicates
1701
+ const normalizedPath = normalizePathForDeduplication(resolvedPath, fullToShortPathMap);
1702
+ const dedupeKey = `${normalizedPath}:${jsxUsage.renderingType}`;
1703
+ if (seenNormalizedPaths.has(dedupeKey)) {
1704
+ continue;
1705
+ }
1706
+ seenNormalizedPaths.add(dedupeKey);
1707
+ // Generate array variation flows for array-map rendering
1708
+ if (jsxUsage.renderingType === 'array-map') {
1709
+ const baseName = generateNameFromPath(resolvedPath);
1710
+ const pathSlug = pathToSlug(resolvedPath);
1711
+ const exclusiveGroup = `array-length-${pathSlug}`;
1712
+ // Empty array flow
1713
+ const emptyFlow = {
1714
+ id: `${pathSlug}-empty-array`,
1715
+ name: `${baseName} Empty`,
1716
+ description: `When ${baseName.toLowerCase()} array is empty`,
1717
+ requiredValues: [
1718
+ {
1719
+ attributePath: resolvedPath,
1720
+ value: '0',
1721
+ comparison: 'length<',
1722
+ valueType: 'array',
1723
+ },
1724
+ ...gatingRequiredValues,
1725
+ ],
1726
+ impact: 'medium',
1727
+ exclusiveGroup,
1728
+ sourceLocation: jsxUsage.sourceLocation
1729
+ ? {
1730
+ lineNumber: jsxUsage.sourceLocation.lineNumber,
1731
+ column: jsxUsage.sourceLocation.column,
1732
+ }
1733
+ : undefined,
1734
+ codeSnippet: jsxUsage.sourceLocation?.codeSnippet,
1735
+ };
1736
+ if (!seenFlowIds.has(emptyFlow.id)) {
1737
+ seenFlowIds.add(emptyFlow.id);
1738
+ flows.push(emptyFlow);
1739
+ }
1740
+ // Few items flow (1-3)
1741
+ const fewFlow = {
1742
+ id: `${pathSlug}-few-items`,
1743
+ name: `${baseName} Few Items`,
1744
+ description: `When ${baseName.toLowerCase()} array has 1-3 items`,
1745
+ requiredValues: [
1746
+ {
1747
+ attributePath: resolvedPath,
1748
+ value: '3',
1749
+ comparison: 'length<',
1750
+ valueType: 'array',
1751
+ },
1752
+ ...gatingRequiredValues,
1753
+ ],
1754
+ impact: 'low',
1755
+ exclusiveGroup,
1756
+ sourceLocation: jsxUsage.sourceLocation
1757
+ ? {
1758
+ lineNumber: jsxUsage.sourceLocation.lineNumber,
1759
+ column: jsxUsage.sourceLocation.column,
1760
+ }
1761
+ : undefined,
1762
+ codeSnippet: jsxUsage.sourceLocation?.codeSnippet,
1763
+ };
1764
+ if (!seenFlowIds.has(fewFlow.id)) {
1765
+ seenFlowIds.add(fewFlow.id);
1766
+ flows.push(fewFlow);
1767
+ }
1768
+ // Many items flow (10+)
1769
+ const manyFlow = {
1770
+ id: `${pathSlug}-many-items`,
1771
+ name: `${baseName} Many Items`,
1772
+ description: `When ${baseName.toLowerCase()} array has many items`,
1773
+ requiredValues: [
1774
+ {
1775
+ attributePath: resolvedPath,
1776
+ value: '10',
1777
+ comparison: 'length>',
1778
+ valueType: 'array',
1779
+ },
1780
+ ...gatingRequiredValues,
1781
+ ],
1782
+ impact: 'low',
1783
+ exclusiveGroup,
1784
+ sourceLocation: jsxUsage.sourceLocation
1785
+ ? {
1786
+ lineNumber: jsxUsage.sourceLocation.lineNumber,
1787
+ column: jsxUsage.sourceLocation.column,
1788
+ }
1789
+ : undefined,
1790
+ codeSnippet: jsxUsage.sourceLocation?.codeSnippet,
1791
+ };
1792
+ if (!seenFlowIds.has(manyFlow.id)) {
1793
+ seenFlowIds.add(manyFlow.id);
1794
+ flows.push(manyFlow);
1795
+ }
1796
+ }
1797
+ }
1798
+ }
1436
1799
  }
1437
1800
  }
1801
+ console.log(`[genFlowsFromConditionals] RESULT: ${flows.length} total flows generated`);
1802
+ for (const flow of flows) {
1803
+ console.log(`[genFlowsFromConditionals] FLOW: id="${flow.id}" requiredValues=[${flow.requiredValues.map((rv) => `${rv.attributePath}=${rv.value}`).join(', ')}]`);
1804
+ }
1438
1805
  return flows;
1439
1806
  }
1440
1807
  //# sourceMappingURL=generateExecutionFlowsFromConditionals.js.map