@codeyam/codeyam-cli 0.1.0-staging.1669d45 → 0.1.0-staging.323686

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 (362) hide show
  1. package/analyzer-template/.build-info.json +8 -8
  2. package/analyzer-template/log.txt +3 -3
  3. package/analyzer-template/package.json +3 -3
  4. package/analyzer-template/packages/ai/index.ts +9 -1
  5. package/analyzer-template/packages/ai/src/lib/analyzeScope.ts +48 -34
  6. package/analyzer-template/packages/ai/src/lib/astScopes/arrayDerivationDetector.ts +199 -0
  7. package/analyzer-template/packages/ai/src/lib/astScopes/astScopeAnalyzer.ts +31 -0
  8. package/analyzer-template/packages/ai/src/lib/astScopes/methodSemantics.ts +139 -23
  9. package/analyzer-template/packages/ai/src/lib/astScopes/patterns/variableDeclarationHandler.ts +6 -126
  10. package/analyzer-template/packages/ai/src/lib/astScopes/processExpression.ts +277 -8
  11. package/analyzer-template/packages/ai/src/lib/astScopes/types.ts +73 -1
  12. package/analyzer-template/packages/ai/src/lib/completionCall.ts +198 -34
  13. package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +108 -1
  14. package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/MuiManager.ts +205 -0
  15. package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.ts +10 -2
  16. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.ts +23 -0
  17. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.ts +87 -2
  18. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.ts +32 -7
  19. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/fixNullIdsBySchema.ts +129 -0
  20. package/analyzer-template/packages/ai/src/lib/dataStructureChunking.ts +156 -0
  21. package/analyzer-template/packages/ai/src/lib/e2eDataTracking.ts +334 -0
  22. package/analyzer-template/packages/ai/src/lib/extractCriticalDataKeys.ts +120 -0
  23. package/analyzer-template/packages/ai/src/lib/generateEntityScenarioData.ts +626 -6
  24. package/analyzer-template/packages/ai/src/lib/generateEntityScenarios.ts +26 -1
  25. package/analyzer-template/packages/ai/src/lib/generateExecutionFlows.ts +375 -6
  26. package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromConditionals.ts +1003 -45
  27. package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromJsxUsages.ts +239 -0
  28. package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChunkPrompt.ts +82 -0
  29. package/analyzer-template/packages/ai/src/lib/promptGenerators/generateCriticalKeysPrompt.ts +103 -0
  30. package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.ts +23 -6
  31. package/analyzer-template/packages/ai/src/lib/promptGenerators/simplifyKeysForLLM.ts +391 -0
  32. package/analyzer-template/packages/ai/src/lib/resolvePathToControllable.ts +154 -32
  33. package/analyzer-template/packages/ai/src/lib/worker/SerializableDataStructure.ts +22 -1
  34. package/analyzer-template/packages/ai/src/lib/worker/analyzeScopeWorker.ts +114 -2
  35. package/analyzer-template/packages/analyze/src/lib/analysisContext.ts +44 -4
  36. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +10 -13
  37. package/analyzer-template/packages/analyze/src/lib/files/analyze/dependencyResolver.ts +6 -0
  38. package/analyzer-template/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.ts +33 -7
  39. package/analyzer-template/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.ts +142 -73
  40. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +42 -5
  41. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.ts +1 -1
  42. package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +77 -0
  43. package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeValidatedDataStructures.ts +56 -11
  44. package/analyzer-template/packages/aws/package.json +1 -1
  45. package/analyzer-template/packages/database/src/lib/kysely/db.ts +8 -1
  46. package/analyzer-template/packages/database/src/lib/kysely/tables/commitsTable.ts +6 -0
  47. package/analyzer-template/packages/database/src/lib/loadAnalyses.ts +58 -1
  48. package/analyzer-template/packages/database/src/lib/loadAnalysis.ts +13 -0
  49. package/analyzer-template/packages/database/src/lib/loadBranch.ts +16 -1
  50. package/analyzer-template/packages/database/src/lib/loadCommit.ts +11 -0
  51. package/analyzer-template/packages/database/src/lib/loadCommits.ts +28 -0
  52. package/analyzer-template/packages/database/src/lib/loadEntities.ts +26 -3
  53. package/analyzer-template/packages/database/src/lib/loadEntityBranches.ts +12 -0
  54. package/analyzer-template/packages/database/src/lib/updateCommitMetadata.ts +7 -14
  55. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts.map +1 -1
  56. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js +8 -1
  57. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js.map +1 -1
  58. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/analysesTable.d.ts.map +1 -1
  59. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/commitsTable.d.ts +1 -0
  60. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/commitsTable.d.ts.map +1 -1
  61. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/commitsTable.js +3 -0
  62. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/commitsTable.js.map +1 -1
  63. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalyses.d.ts +2 -0
  64. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalyses.d.ts.map +1 -1
  65. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalyses.js +45 -2
  66. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalyses.js.map +1 -1
  67. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.d.ts.map +1 -1
  68. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.js +8 -0
  69. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.js.map +1 -1
  70. package/analyzer-template/packages/github/dist/database/src/lib/loadBranch.js +11 -1
  71. package/analyzer-template/packages/github/dist/database/src/lib/loadBranch.js.map +1 -1
  72. package/analyzer-template/packages/github/dist/database/src/lib/loadCommit.d.ts.map +1 -1
  73. package/analyzer-template/packages/github/dist/database/src/lib/loadCommit.js +7 -0
  74. package/analyzer-template/packages/github/dist/database/src/lib/loadCommit.js.map +1 -1
  75. package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.d.ts +3 -1
  76. package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.d.ts.map +1 -1
  77. package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.js +22 -1
  78. package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.js.map +1 -1
  79. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.d.ts +3 -1
  80. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.d.ts.map +1 -1
  81. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.js +23 -4
  82. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.js.map +1 -1
  83. package/analyzer-template/packages/github/dist/database/src/lib/loadEntityBranches.d.ts.map +1 -1
  84. package/analyzer-template/packages/github/dist/database/src/lib/loadEntityBranches.js +9 -0
  85. package/analyzer-template/packages/github/dist/database/src/lib/loadEntityBranches.js.map +1 -1
  86. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.d.ts +2 -2
  87. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.d.ts.map +1 -1
  88. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.js +5 -4
  89. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.js.map +1 -1
  90. package/analyzer-template/packages/github/dist/types/index.d.ts +1 -1
  91. package/analyzer-template/packages/github/dist/types/index.d.ts.map +1 -1
  92. package/analyzer-template/packages/github/dist/types/index.js.map +1 -1
  93. package/analyzer-template/packages/github/dist/types/src/types/Analysis.d.ts +25 -1
  94. package/analyzer-template/packages/github/dist/types/src/types/Analysis.d.ts.map +1 -1
  95. package/analyzer-template/packages/github/dist/types/src/types/Commit.d.ts +2 -0
  96. package/analyzer-template/packages/github/dist/types/src/types/Commit.d.ts.map +1 -1
  97. package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts +51 -1
  98. package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
  99. package/analyzer-template/packages/github/dist/utils/src/lib/safeFileName.d.ts +9 -1
  100. package/analyzer-template/packages/github/dist/utils/src/lib/safeFileName.d.ts.map +1 -1
  101. package/analyzer-template/packages/github/dist/utils/src/lib/safeFileName.js +29 -3
  102. package/analyzer-template/packages/github/dist/utils/src/lib/safeFileName.js.map +1 -1
  103. package/analyzer-template/packages/types/index.ts +1 -0
  104. package/analyzer-template/packages/types/src/types/Analysis.ts +25 -0
  105. package/analyzer-template/packages/types/src/types/Commit.ts +2 -0
  106. package/analyzer-template/packages/types/src/types/ScenariosDataStructure.ts +64 -1
  107. package/analyzer-template/packages/utils/dist/types/index.d.ts +1 -1
  108. package/analyzer-template/packages/utils/dist/types/index.d.ts.map +1 -1
  109. package/analyzer-template/packages/utils/dist/types/index.js.map +1 -1
  110. package/analyzer-template/packages/utils/dist/types/src/types/Analysis.d.ts +25 -1
  111. package/analyzer-template/packages/utils/dist/types/src/types/Analysis.d.ts.map +1 -1
  112. package/analyzer-template/packages/utils/dist/types/src/types/Commit.d.ts +2 -0
  113. package/analyzer-template/packages/utils/dist/types/src/types/Commit.d.ts.map +1 -1
  114. package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts +51 -1
  115. package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
  116. package/analyzer-template/packages/utils/dist/utils/src/lib/safeFileName.d.ts +9 -1
  117. package/analyzer-template/packages/utils/dist/utils/src/lib/safeFileName.d.ts.map +1 -1
  118. package/analyzer-template/packages/utils/dist/utils/src/lib/safeFileName.js +29 -3
  119. package/analyzer-template/packages/utils/dist/utils/src/lib/safeFileName.js.map +1 -1
  120. package/analyzer-template/packages/utils/src/lib/safeFileName.ts +48 -3
  121. package/analyzer-template/playwright/capture.ts +20 -8
  122. package/analyzer-template/playwright/captureStatic.ts +1 -1
  123. package/analyzer-template/project/analyzeBaselineCommit.ts +5 -0
  124. package/analyzer-template/project/analyzeRegularCommit.ts +5 -0
  125. package/analyzer-template/project/captureLibraryFunctionDirect.ts +29 -26
  126. package/analyzer-template/project/constructMockCode.ts +314 -29
  127. package/analyzer-template/project/createEntitiesAndSortFiles.ts +83 -0
  128. package/analyzer-template/project/loadReadyToBeCaptured.ts +65 -41
  129. package/analyzer-template/project/orchestrateCapture/AwsCaptureTaskRunner.ts +12 -4
  130. package/analyzer-template/project/orchestrateCapture/SequentialCaptureTaskRunner.ts +18 -7
  131. package/analyzer-template/project/orchestrateCapture/taskRunner.ts +4 -2
  132. package/analyzer-template/project/orchestrateCapture.ts +71 -6
  133. package/analyzer-template/project/reconcileMockDataKeys.ts +152 -9
  134. package/analyzer-template/project/runAnalysis.ts +4 -0
  135. package/analyzer-template/project/start.ts +35 -11
  136. package/analyzer-template/project/writeMockDataTsx.ts +114 -2
  137. package/analyzer-template/project/writeScenarioComponents.ts +101 -8
  138. package/analyzer-template/scripts/comboWorkerLoop.cjs +98 -50
  139. package/background/src/lib/virtualized/project/analyzeBaselineCommit.js +5 -0
  140. package/background/src/lib/virtualized/project/analyzeBaselineCommit.js.map +1 -1
  141. package/background/src/lib/virtualized/project/analyzeRegularCommit.js +5 -0
  142. package/background/src/lib/virtualized/project/analyzeRegularCommit.js.map +1 -1
  143. package/background/src/lib/virtualized/project/captureLibraryFunctionDirect.js +3 -3
  144. package/background/src/lib/virtualized/project/captureLibraryFunctionDirect.js.map +1 -1
  145. package/background/src/lib/virtualized/project/constructMockCode.js +255 -4
  146. package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
  147. package/background/src/lib/virtualized/project/createEntitiesAndSortFiles.js +73 -1
  148. package/background/src/lib/virtualized/project/createEntitiesAndSortFiles.js.map +1 -1
  149. package/background/src/lib/virtualized/project/loadReadyToBeCaptured.js +19 -8
  150. package/background/src/lib/virtualized/project/loadReadyToBeCaptured.js.map +1 -1
  151. package/background/src/lib/virtualized/project/orchestrateCapture/AwsCaptureTaskRunner.js +2 -2
  152. package/background/src/lib/virtualized/project/orchestrateCapture/AwsCaptureTaskRunner.js.map +1 -1
  153. package/background/src/lib/virtualized/project/orchestrateCapture/SequentialCaptureTaskRunner.js +7 -5
  154. package/background/src/lib/virtualized/project/orchestrateCapture/SequentialCaptureTaskRunner.js.map +1 -1
  155. package/background/src/lib/virtualized/project/orchestrateCapture.js +58 -6
  156. package/background/src/lib/virtualized/project/orchestrateCapture.js.map +1 -1
  157. package/background/src/lib/virtualized/project/reconcileMockDataKeys.js +126 -9
  158. package/background/src/lib/virtualized/project/reconcileMockDataKeys.js.map +1 -1
  159. package/background/src/lib/virtualized/project/runAnalysis.js +3 -0
  160. package/background/src/lib/virtualized/project/runAnalysis.js.map +1 -1
  161. package/background/src/lib/virtualized/project/start.js +32 -11
  162. package/background/src/lib/virtualized/project/start.js.map +1 -1
  163. package/background/src/lib/virtualized/project/writeMockDataTsx.js +89 -2
  164. package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
  165. package/background/src/lib/virtualized/project/writeScenarioComponents.js +57 -8
  166. package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
  167. package/codeyam-cli/src/cli.js +2 -0
  168. package/codeyam-cli/src/cli.js.map +1 -1
  169. package/codeyam-cli/src/commands/memory.js +273 -0
  170. package/codeyam-cli/src/commands/memory.js.map +1 -0
  171. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js +4 -0
  172. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js.map +1 -1
  173. package/codeyam-cli/src/utils/analysisRunner.js +21 -2
  174. package/codeyam-cli/src/utils/analysisRunner.js.map +1 -1
  175. package/codeyam-cli/src/utils/install-skills.js +20 -6
  176. package/codeyam-cli/src/utils/install-skills.js.map +1 -1
  177. package/codeyam-cli/src/utils/queue/job.js +1 -0
  178. package/codeyam-cli/src/utils/queue/job.js.map +1 -1
  179. package/codeyam-cli/src/utils/queue/manager.js +6 -0
  180. package/codeyam-cli/src/utils/queue/manager.js.map +1 -1
  181. package/codeyam-cli/src/utils/rules/index.js +5 -0
  182. package/codeyam-cli/src/utils/rules/index.js.map +1 -0
  183. package/codeyam-cli/src/utils/rules/parser.js +106 -0
  184. package/codeyam-cli/src/utils/rules/parser.js.map +1 -0
  185. package/codeyam-cli/src/utils/rules/pathMatcher.js +18 -0
  186. package/codeyam-cli/src/utils/rules/pathMatcher.js.map +1 -0
  187. package/codeyam-cli/src/utils/rules/staleness.js +132 -0
  188. package/codeyam-cli/src/utils/rules/staleness.js.map +1 -0
  189. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +2 -0
  190. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js.map +1 -1
  191. package/codeyam-cli/src/webserver/app/lib/database.js +7 -3
  192. package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
  193. package/codeyam-cli/src/webserver/bootstrap.js +40 -0
  194. package/codeyam-cli/src/webserver/bootstrap.js.map +1 -1
  195. package/codeyam-cli/src/webserver/build/client/assets/EntityItem-DsN1wKrm.js +11 -0
  196. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeBadge-COi5OvsN.js → EntityTypeBadge-DLqD3qNt.js} +1 -1
  197. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeIcon-BwdQv49w.js → EntityTypeIcon-Ba2JVPzP.js} +1 -1
  198. package/codeyam-cli/src/webserver/build/client/assets/{InlineSpinner-CEleMv_j.js → InlineSpinner-C8lyxW9k.js} +1 -1
  199. package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-D68KarMg.js → InteractivePreview-aht4aafF.js} +2 -2
  200. package/codeyam-cli/src/webserver/build/client/assets/{LibraryFunctionPreview-L75Wvqgw.js → LibraryFunctionPreview-CVtiBnY5.js} +1 -1
  201. package/codeyam-cli/src/webserver/build/client/assets/{LoadingDots-C53WM8qn.js → LoadingDots-B0GLXMsr.js} +1 -1
  202. package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-CrNkmy4i.js → LogViewer-xgeCVgSM.js} +1 -1
  203. package/codeyam-cli/src/webserver/build/client/assets/ReportIssueModal-OApQuNyq.js +16 -0
  204. package/codeyam-cli/src/webserver/build/client/assets/{SafeScreenshot-CQifa1n-.js → SafeScreenshot-DuDvi0jm.js} +1 -1
  205. package/codeyam-cli/src/webserver/build/client/assets/{ScenarioViewer-CyaBFX7l.js → ScenarioViewer-DzccYyI8.js} +3 -13
  206. package/codeyam-cli/src/webserver/build/client/assets/{TruncatedFilePath-D36O1rzU.js → TruncatedFilePath-DyFZkK0l.js} +1 -1
  207. package/codeyam-cli/src/webserver/build/client/assets/_index-BwqWJOgH.js +11 -0
  208. package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-BwavGCpm.js +32 -0
  209. package/codeyam-cli/src/webserver/build/client/assets/api.health-l0sNRNKZ.js +1 -0
  210. package/codeyam-cli/src/webserver/build/client/assets/api.memory-profile-l0sNRNKZ.js +1 -0
  211. package/codeyam-cli/src/webserver/build/client/assets/api.restart-server-l0sNRNKZ.js +1 -0
  212. package/codeyam-cli/src/webserver/build/client/assets/{chevron-down-DgTPh8H-.js → chevron-down-Cx24_aWc.js} +1 -1
  213. package/codeyam-cli/src/webserver/build/client/assets/{chunk-EPOLDU6W-DdQKK6on.js → chunk-EPOLDU6W-CXRTFQ3F.js} +1 -1
  214. package/codeyam-cli/src/webserver/build/client/assets/{circle-check-Dmr2bb1R.js → circle-check-BOARzkeR.js} +1 -1
  215. package/codeyam-cli/src/webserver/build/client/assets/copy-Bb-80kDT.js +6 -0
  216. package/codeyam-cli/src/webserver/build/client/assets/{createLucideIcon-Do4ZLUYa.js → createLucideIcon-BdhJEx6B.js} +1 -1
  217. package/codeyam-cli/src/webserver/build/client/assets/dev.empty-BBnGWYga.js +1 -0
  218. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-CbdFyxZh.js → entity._sha._-BJUiQqZF.js} +12 -12
  219. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.fullscreen-B4iCfs5M.js → entity._sha.scenarios._scenarioId.fullscreen-DavjRmOY.js} +1 -1
  220. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.create-scenario-wDWZZO1W.js → entity._sha_.create-scenario-D1T4TGjf.js} +1 -1
  221. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.edit._scenarioId-BMbl7MeQ.js → entity._sha_.edit._scenarioId-CTBG2mmz.js} +1 -1
  222. package/codeyam-cli/src/webserver/build/client/assets/{entry.client-5wRKRIH9.js → entry.client-CS2cb_eZ.js} +1 -1
  223. package/codeyam-cli/src/webserver/build/client/assets/file-code-Dhef1kWN.js +6 -0
  224. package/codeyam-cli/src/webserver/build/client/assets/{fileTableUtils-DD3SDH7t.js → fileTableUtils-DMJ7zii9.js} +1 -1
  225. package/codeyam-cli/src/webserver/build/client/assets/files-CJ6lTdTA.js +1 -0
  226. package/codeyam-cli/src/webserver/build/client/assets/{git-zXjT7J0G.js → git-CPTZZ-JZ.js} +8 -8
  227. package/codeyam-cli/src/webserver/build/client/assets/globals-D3yhhV8x.css +1 -0
  228. package/codeyam-cli/src/webserver/build/client/assets/{index-DLbXwndH.js → index-B1h680n5.js} +1 -1
  229. package/codeyam-cli/src/webserver/build/client/assets/{index-gPZ-lad1.js → index-lzqtyFU8.js} +1 -1
  230. package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-BsPXJ81F.js → loader-circle-B7B9V-bu.js} +1 -1
  231. package/codeyam-cli/src/webserver/build/client/assets/manifest-7522edd4.js +1 -0
  232. package/codeyam-cli/src/webserver/build/client/assets/memory-yxFcrxBX.js +92 -0
  233. package/codeyam-cli/src/webserver/build/client/assets/root-eVAaavTS.js +62 -0
  234. package/codeyam-cli/src/webserver/build/client/assets/{search-P2FKIUql.js → search-CxXUmBSd.js} +1 -1
  235. package/codeyam-cli/src/webserver/build/client/assets/{settings-B2eDuBj8.js → settings-CS5f3WzT.js} +1 -1
  236. package/codeyam-cli/src/webserver/build/client/assets/{simulations-L18M6-kN.js → simulations-DwFIBT09.js} +1 -1
  237. package/codeyam-cli/src/webserver/build/client/assets/{triangle-alert-BDz7kbVA.js → triangle-alert-B6LgvRJg.js} +1 -1
  238. package/codeyam-cli/src/webserver/build/client/assets/{useCustomSizes-29dDmbH8.js → useCustomSizes-C1v1PQzo.js} +1 -1
  239. package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-BUm0UVJm.js → useLastLogLine-aSv48UbS.js} +1 -1
  240. package/codeyam-cli/src/webserver/build/client/assets/{useReportContext-CkIOKTrZ.js → useReportContext-DYxHZQuP.js} +1 -1
  241. package/codeyam-cli/src/webserver/build/client/assets/{useToast-KKw5kTn-.js → useToast-mBRpZPiu.js} +1 -1
  242. package/codeyam-cli/src/webserver/build/server/assets/index-DVzYx8PN.js +1 -0
  243. package/codeyam-cli/src/webserver/build/server/assets/server-build-4Cr0uToj.js +257 -0
  244. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  245. package/codeyam-cli/src/webserver/build-info.json +5 -5
  246. package/codeyam-cli/templates/codeyam-memory-hook.sh +200 -0
  247. package/codeyam-cli/templates/codeyam:debug.md +47 -3
  248. package/codeyam-cli/templates/codeyam:diagnose.md +203 -25
  249. package/codeyam-cli/templates/codeyam:memory.md +462 -0
  250. package/codeyam-cli/templates/codeyam:new-rule.md +13 -0
  251. package/package.json +8 -5
  252. package/packages/ai/index.js +5 -2
  253. package/packages/ai/index.js.map +1 -1
  254. package/packages/ai/src/lib/analyzeScope.js +41 -17
  255. package/packages/ai/src/lib/analyzeScope.js.map +1 -1
  256. package/packages/ai/src/lib/astScopes/arrayDerivationDetector.js +150 -0
  257. package/packages/ai/src/lib/astScopes/arrayDerivationDetector.js.map +1 -0
  258. package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js +24 -0
  259. package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js.map +1 -1
  260. package/packages/ai/src/lib/astScopes/methodSemantics.js +109 -23
  261. package/packages/ai/src/lib/astScopes/methodSemantics.js.map +1 -1
  262. package/packages/ai/src/lib/astScopes/patterns/variableDeclarationHandler.js +1 -102
  263. package/packages/ai/src/lib/astScopes/patterns/variableDeclarationHandler.js.map +1 -1
  264. package/packages/ai/src/lib/astScopes/processExpression.js +228 -11
  265. package/packages/ai/src/lib/astScopes/processExpression.js.map +1 -1
  266. package/packages/ai/src/lib/completionCall.js +161 -30
  267. package/packages/ai/src/lib/completionCall.js.map +1 -1
  268. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +86 -1
  269. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
  270. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/MuiManager.js +179 -0
  271. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/MuiManager.js.map +1 -1
  272. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.js +7 -1
  273. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.js.map +1 -1
  274. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js +19 -0
  275. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js.map +1 -1
  276. package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js +70 -2
  277. package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js.map +1 -1
  278. package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js +29 -7
  279. package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js.map +1 -1
  280. package/packages/ai/src/lib/dataStructure/helpers/fixNullIdsBySchema.js +107 -0
  281. package/packages/ai/src/lib/dataStructure/helpers/fixNullIdsBySchema.js.map +1 -0
  282. package/packages/ai/src/lib/dataStructureChunking.js +111 -0
  283. package/packages/ai/src/lib/dataStructureChunking.js.map +1 -0
  284. package/packages/ai/src/lib/e2eDataTracking.js +241 -0
  285. package/packages/ai/src/lib/e2eDataTracking.js.map +1 -0
  286. package/packages/ai/src/lib/extractCriticalDataKeys.js +96 -0
  287. package/packages/ai/src/lib/extractCriticalDataKeys.js.map +1 -0
  288. package/packages/ai/src/lib/generateEntityScenarioData.js +510 -7
  289. package/packages/ai/src/lib/generateEntityScenarioData.js.map +1 -1
  290. package/packages/ai/src/lib/generateEntityScenarios.js +19 -1
  291. package/packages/ai/src/lib/generateEntityScenarios.js.map +1 -1
  292. package/packages/ai/src/lib/generateExecutionFlows.js +273 -4
  293. package/packages/ai/src/lib/generateExecutionFlows.js.map +1 -1
  294. package/packages/ai/src/lib/generateExecutionFlowsFromConditionals.js +738 -40
  295. package/packages/ai/src/lib/generateExecutionFlowsFromConditionals.js.map +1 -1
  296. package/packages/ai/src/lib/generateExecutionFlowsFromJsxUsages.js +194 -0
  297. package/packages/ai/src/lib/generateExecutionFlowsFromJsxUsages.js.map +1 -0
  298. package/packages/ai/src/lib/promptGenerators/generateChunkPrompt.js +54 -0
  299. package/packages/ai/src/lib/promptGenerators/generateChunkPrompt.js.map +1 -0
  300. package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js +15 -7
  301. package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js.map +1 -1
  302. package/packages/ai/src/lib/promptGenerators/simplifyKeysForLLM.js +335 -0
  303. package/packages/ai/src/lib/promptGenerators/simplifyKeysForLLM.js.map +1 -0
  304. package/packages/ai/src/lib/resolvePathToControllable.js +131 -27
  305. package/packages/ai/src/lib/resolvePathToControllable.js.map +1 -1
  306. package/packages/ai/src/lib/worker/SerializableDataStructure.js +7 -0
  307. package/packages/ai/src/lib/worker/SerializableDataStructure.js.map +1 -1
  308. package/packages/ai/src/lib/worker/analyzeScopeWorker.js +94 -1
  309. package/packages/ai/src/lib/worker/analyzeScopeWorker.js.map +1 -1
  310. package/packages/analyze/src/lib/analysisContext.js +30 -5
  311. package/packages/analyze/src/lib/analysisContext.js.map +1 -1
  312. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +8 -4
  313. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
  314. package/packages/analyze/src/lib/files/analyze/dependencyResolver.js +5 -0
  315. package/packages/analyze/src/lib/files/analyze/dependencyResolver.js.map +1 -1
  316. package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js +31 -7
  317. package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js.map +1 -1
  318. package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js +116 -66
  319. package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js.map +1 -1
  320. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +37 -5
  321. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
  322. package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js +1 -1
  323. package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js.map +1 -1
  324. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +65 -0
  325. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
  326. package/packages/analyze/src/lib/files/scenarios/mergeValidatedDataStructures.js +46 -9
  327. package/packages/analyze/src/lib/files/scenarios/mergeValidatedDataStructures.js.map +1 -1
  328. package/packages/database/src/lib/kysely/db.js +8 -1
  329. package/packages/database/src/lib/kysely/db.js.map +1 -1
  330. package/packages/database/src/lib/kysely/tables/commitsTable.js +3 -0
  331. package/packages/database/src/lib/kysely/tables/commitsTable.js.map +1 -1
  332. package/packages/database/src/lib/loadAnalyses.js +45 -2
  333. package/packages/database/src/lib/loadAnalyses.js.map +1 -1
  334. package/packages/database/src/lib/loadAnalysis.js +8 -0
  335. package/packages/database/src/lib/loadAnalysis.js.map +1 -1
  336. package/packages/database/src/lib/loadBranch.js +11 -1
  337. package/packages/database/src/lib/loadBranch.js.map +1 -1
  338. package/packages/database/src/lib/loadCommit.js +7 -0
  339. package/packages/database/src/lib/loadCommit.js.map +1 -1
  340. package/packages/database/src/lib/loadCommits.js +22 -1
  341. package/packages/database/src/lib/loadCommits.js.map +1 -1
  342. package/packages/database/src/lib/loadEntities.js +23 -4
  343. package/packages/database/src/lib/loadEntities.js.map +1 -1
  344. package/packages/database/src/lib/loadEntityBranches.js +9 -0
  345. package/packages/database/src/lib/loadEntityBranches.js.map +1 -1
  346. package/packages/database/src/lib/updateCommitMetadata.js +5 -4
  347. package/packages/database/src/lib/updateCommitMetadata.js.map +1 -1
  348. package/packages/types/index.js.map +1 -1
  349. package/packages/utils/src/lib/safeFileName.js +29 -3
  350. package/packages/utils/src/lib/safeFileName.js.map +1 -1
  351. package/scripts/finalize-analyzer.cjs +3 -3
  352. package/codeyam-cli/src/webserver/build/client/assets/EntityItem-vauWK972.js +0 -1
  353. package/codeyam-cli/src/webserver/build/client/assets/ReportIssueModal-DzJRkCkr.js +0 -11
  354. package/codeyam-cli/src/webserver/build/client/assets/_index-Be83mo_j.js +0 -11
  355. package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-BN6wu6Y-.js +0 -37
  356. package/codeyam-cli/src/webserver/build/client/assets/dev.empty-Bn6aCAy_.js +0 -1
  357. package/codeyam-cli/src/webserver/build/client/assets/files-DKyMFI90.js +0 -1
  358. package/codeyam-cli/src/webserver/build/client/assets/globals-DTTQ3gY7.css +0 -1
  359. package/codeyam-cli/src/webserver/build/client/assets/manifest-22590fcf.js +0 -1
  360. package/codeyam-cli/src/webserver/build/client/assets/root-BsAarjAM.js +0 -57
  361. package/codeyam-cli/src/webserver/build/server/assets/index-BND5I5fv.js +0 -1
  362. package/codeyam-cli/src/webserver/build/server/assets/server-build-CFXnd7MG.js +0 -228
@@ -9,13 +9,14 @@ import { Entity } from '~codeyam/types';
9
9
  import { FileAnalyzer, ProjectAnalyzer } from '~codeyam/analyze';
10
10
  import { analyzeScopeLocal } from '../analyzeScope';
11
11
  import {
12
- ScopeInfo,
13
12
  resetScopeDataStructureMetrics,
13
+ ScopeInfo,
14
14
  } from '../dataStructure/ScopeDataStructure';
15
15
  import { SerializableDataStructure } from './SerializableDataStructure';
16
16
  import { AI } from '~codeyam/ai';
17
17
  import { setThreadContext } from '~codeyam/utils';
18
18
  import { threadId } from 'worker_threads';
19
+ import v8 from 'v8';
19
20
 
20
21
  // Set thread context for logging
21
22
  setThreadContext(`<worker-${threadId}>`);
@@ -45,6 +46,80 @@ let projectAnalyzerKey: string | null = null;
45
46
  let fileAnalyzer: FileAnalyzer | null = null;
46
47
  let fileAnalyzerPath: string | null = null;
47
48
 
49
+ // Memory tracking
50
+ let entitiesProcessed = 0;
51
+ let lastMemoryLogAt = 0;
52
+ const MEMORY_LOG_INTERVAL = 100; // Log every N entities
53
+ const MEMORY_LOG_TIME_INTERVAL = 60_000; // Or every 60 seconds
54
+
55
+ /**
56
+ * Get memory stats for logging
57
+ */
58
+ function getWorkerMemoryStats() {
59
+ const mem = process.memoryUsage();
60
+ const heapStats = v8.getHeapStatistics();
61
+ return {
62
+ rss: `${Math.round(mem.rss / 1024 / 1024)}MB`,
63
+ heapUsed: `${Math.round(mem.heapUsed / 1024 / 1024)}MB`,
64
+ heapTotal: `${Math.round(mem.heapTotal / 1024 / 1024)}MB`,
65
+ external: `${Math.round(mem.external / 1024 / 1024)}MB`,
66
+ // V8 heap stats give more detail
67
+ v8TotalHeapSize: `${Math.round(heapStats.total_heap_size / 1024 / 1024)}MB`,
68
+ v8UsedHeapSize: `${Math.round(heapStats.used_heap_size / 1024 / 1024)}MB`,
69
+ v8HeapSizeLimit: `${Math.round(heapStats.heap_size_limit / 1024 / 1024)}MB`,
70
+ v8MallocedMemory: `${Math.round(heapStats.malloced_memory / 1024 / 1024)}MB`,
71
+ };
72
+ }
73
+
74
+ /**
75
+ * Get ts.Program stats for understanding TypeScript memory usage
76
+ */
77
+ function getTsProgramStats(pa: ProjectAnalyzer) {
78
+ const sourceFiles = pa.program.getSourceFiles();
79
+ const projectSourceFiles = sourceFiles.filter(
80
+ (sf) => !sf.fileName.includes('node_modules'),
81
+ );
82
+ const nodeModulesFiles = sourceFiles.filter((sf) =>
83
+ sf.fileName.includes('node_modules'),
84
+ );
85
+
86
+ // Estimate AST size by sampling text length (rough proxy)
87
+ let totalProjectTextLength = 0;
88
+ for (const sf of projectSourceFiles) {
89
+ totalProjectTextLength += sf.getFullText().length;
90
+ }
91
+
92
+ return {
93
+ totalSourceFiles: sourceFiles.length,
94
+ projectSourceFiles: projectSourceFiles.length,
95
+ nodeModulesFiles: nodeModulesFiles.length,
96
+ projectTextSizeMB: `${(totalProjectTextLength / 1024 / 1024).toFixed(1)}MB`,
97
+ // Note: Actual AST memory is typically 10-20x the source text size
98
+ estimatedAstSizeMB: `${((totalProjectTextLength * 15) / 1024 / 1024).toFixed(0)}MB`,
99
+ };
100
+ }
101
+
102
+ /**
103
+ * Write a heap snapshot for detailed profiling.
104
+ * The snapshot can be loaded in Chrome DevTools for analysis.
105
+ *
106
+ * TODO: Once we understand memory usage, change this back to env-var controlled
107
+ */
108
+ const HEAP_SNAPSHOT_MODE: 'off' | 'once' | 'periodic' = 'off';
109
+
110
+ function maybeWriteHeapSnapshot(label: string) {
111
+ if (HEAP_SNAPSHOT_MODE === 'off') return;
112
+
113
+ try {
114
+ const filename = v8.writeHeapSnapshot();
115
+ console.log(
116
+ `CodeYam Worker: Heap snapshot written (${label}): ${filename}`,
117
+ );
118
+ } catch (error) {
119
+ console.error('CodeYam Worker: Failed to write heap snapshot:', error);
120
+ }
121
+ }
122
+
48
123
  /**
49
124
  * Main worker function called by Piscina
50
125
  */
@@ -61,8 +136,25 @@ export default async function runAnalyzeScope(
61
136
  // Create or reuse ProjectAnalyzer
62
137
  const paKey = `${dirPath}`;
63
138
  if (!projectAnalyzer || projectAnalyzerKey !== paKey) {
64
- projectAnalyzer = await ProjectAnalyzer.from({ project, dirPath });
139
+ const memBefore = process.memoryUsage();
140
+ console.log('CodeYam Worker: Creating ProjectAnalyzer (ts.Program)...', {
141
+ memBefore: getWorkerMemoryStats(),
142
+ });
143
+
144
+ projectAnalyzer = ProjectAnalyzer.from({ project, dirPath });
65
145
  projectAnalyzerKey = paKey;
146
+
147
+ const memAfter = process.memoryUsage();
148
+ const tsProgramStats = getTsProgramStats(projectAnalyzer);
149
+ console.log('CodeYam Worker: ProjectAnalyzer created', {
150
+ memAfter: getWorkerMemoryStats(),
151
+ rssDelta: `+${Math.round((memAfter.rss - memBefore.rss) / 1024 / 1024)}MB`,
152
+ heapDelta: `+${Math.round((memAfter.heapUsed - memBefore.heapUsed) / 1024 / 1024)}MB`,
153
+ tsProgramStats,
154
+ });
155
+
156
+ // Optionally write heap snapshot after ts.Program creation
157
+ maybeWriteHeapSnapshot('after-ts-program');
66
158
  }
67
159
 
68
160
  // Create or reuse FileAnalyzer
@@ -95,6 +187,26 @@ export default async function runAnalyzeScope(
95
187
  );
96
188
  }
97
189
 
190
+ // Periodic memory logging
191
+ entitiesProcessed++;
192
+ const now = Date.now();
193
+ const shouldLogMemory =
194
+ entitiesProcessed % MEMORY_LOG_INTERVAL === 0 ||
195
+ now - lastMemoryLogAt > MEMORY_LOG_TIME_INTERVAL;
196
+
197
+ if (shouldLogMemory) {
198
+ lastMemoryLogAt = now;
199
+ console.log('CodeYam Worker: Memory stats', {
200
+ entitiesProcessed,
201
+ ...getWorkerMemoryStats(),
202
+ });
203
+
204
+ // Optionally write periodic heap snapshots
205
+ if (HEAP_SNAPSHOT_MODE === 'periodic' && entitiesProcessed % 500 === 0) {
206
+ maybeWriteHeapSnapshot(`after-${entitiesProcessed}-entities`);
207
+ }
208
+ }
209
+
98
210
  return { dataStructure: dataStructure.toSerializable() };
99
211
  } catch (error) {
100
212
  console.error(
@@ -48,6 +48,12 @@ export class AnalysisContext implements ImmutableAnalysisContext {
48
48
  public analysesAdded: Analysis[]; // TODO: Remove this when we switch to immutable maps
49
49
  private projectNodeModuleMocks: Mock[];
50
50
  private baselineMode: boolean = false;
51
+ /**
52
+ * Parent context for delegating lookups when not found locally.
53
+ * Used by private contexts created via forEntityAnalysis() to see analyses
54
+ * added to the main context after the fork.
55
+ */
56
+ private parentContext?: AnalysisContext;
51
57
 
52
58
  /**
53
59
  * Create a new AnalysisContext with optional initial maps and mocks
@@ -56,16 +62,19 @@ export class AnalysisContext implements ImmutableAnalysisContext {
56
62
  primaryEntity,
57
63
  initialEntityMap,
58
64
  initialAnalysisMap,
65
+ parentContext,
59
66
  }: {
60
67
  primaryEntity?: Entity;
61
68
  initialEntityMap?: EntityMap;
62
69
  initialAnalysisMap?: AnalysisMap;
70
+ parentContext?: AnalysisContext;
63
71
  } = {}) {
64
72
  this.primaryEntity = primaryEntity;
65
73
  this.entityMap = initialEntityMap || {};
66
74
  this.entitiesAdded = []; // TODO: Remove this when we switch to immutable maps
67
75
  this.analysisMap = initialAnalysisMap || {};
68
76
  this.analysesAdded = []; // TODO: Remove this when we switch to immutable maps
77
+ this.parentContext = parentContext;
69
78
  }
70
79
  setPrimaryAnalysis(analysis: Analysis): void {
71
80
  if (!this.primaryEntity) {
@@ -102,15 +111,22 @@ export class AnalysisContext implements ImmutableAnalysisContext {
102
111
  primaryEntity: entity,
103
112
  initialEntityMap: { ...this.entityMap },
104
113
  initialAnalysisMap: { ...this.analysisMap },
114
+ parentContext: this,
105
115
  });
106
116
  }
107
117
 
108
118
  /**
109
- * Get a read-only view of an entity by file path and entity name
119
+ * Get a read-only view of an entity by file path and entity name.
120
+ * Falls back to parent context if not found locally (for private contexts).
110
121
  * @returns The entity or undefined if not found
111
122
  */
112
123
  getEntity(filePath: string, entityName: string): ReadonlyEntity | undefined {
113
- return this.entityMap[filePath]?.[entityName];
124
+ const entity = this.entityMap[filePath]?.[entityName];
125
+ // Fall back to parent context if not found locally
126
+ if (!entity && this.parentContext) {
127
+ return this.parentContext.getEntity(filePath, entityName);
128
+ }
129
+ return entity;
114
130
  }
115
131
 
116
132
  /**
@@ -126,7 +142,8 @@ export class AnalysisContext implements ImmutableAnalysisContext {
126
142
  }
127
143
 
128
144
  /**
129
- * Get a read-only view of an analysis by file path and entity name
145
+ * Get a read-only view of an analysis by file path and entity name.
146
+ * Falls back to parent context if not found locally (for private contexts).
130
147
  * @returns The analysis or undefined if not found
131
148
  */
132
149
  getAnalysis(
@@ -134,7 +151,23 @@ export class AnalysisContext implements ImmutableAnalysisContext {
134
151
  entityName: string,
135
152
  withEntity = false,
136
153
  ): ReadonlyAnalysis | undefined {
137
- const analysis = this.analysisMap[filePath]?.[entityName];
154
+ let analysis = this.analysisMap[filePath]?.[entityName];
155
+
156
+ // Fall back to parent context if not found locally
157
+ // This allows private contexts (created via forEntityAnalysis) to see
158
+ // analyses added to the main context after the fork
159
+ if (!analysis && this.parentContext) {
160
+ analysis = this.parentContext.getAnalysis(
161
+ filePath,
162
+ entityName,
163
+ withEntity,
164
+ ) as Analysis | undefined;
165
+ // If found in parent and withEntity was already handled by parent, return directly
166
+ if (analysis) {
167
+ return analysis;
168
+ }
169
+ }
170
+
138
171
  if (withEntity && analysis) {
139
172
  analysis.entity ||= this.getMutableEntity(filePath, entityName);
140
173
  }
@@ -183,6 +216,13 @@ export class AnalysisContext implements ImmutableAnalysisContext {
183
216
  this.analysisMap[filePath] = {};
184
217
  }
185
218
  this.analysisMap[filePath][entityName] = analysis;
219
+
220
+ // Also add the entity if it's attached to the analysis.
221
+ // This ensures that when getAnalysis is called with withEntity=true,
222
+ // the entity will be available in the entity map.
223
+ if (analysis.entity) {
224
+ this.addEntity(analysis.entity);
225
+ }
186
226
  }
187
227
 
188
228
  /**
@@ -17,6 +17,7 @@ import {
17
17
  getConditionalEffects,
18
18
  getCompoundConditionals,
19
19
  getChildBoundaryGatingConditions,
20
+ getJsxRenderingUsages,
20
21
  } from '~codeyam/ai';
21
22
  import type { AnalysisOptions } from '../analyzeEntities';
22
23
 
@@ -134,6 +135,8 @@ export default async function prepareEntityDataStructures(
134
135
  // Include child boundary gating conditions for child component flow merging
135
136
  childBoundaryGatingConditions:
136
137
  isolatedDataStructure.childBoundaryGatingConditions,
138
+ // Include JSX rendering usages for array size and text length flow generation
139
+ jsxRenderingUsages: isolatedDataStructure.jsxRenderingUsages,
137
140
  };
138
141
 
139
142
  // Detect wrapper requirements (Context providers, etc.)
@@ -557,19 +560,6 @@ async function getEntityDataStructureAndFunctionCalls({
557
560
 
558
561
  // Get compound conditionals (grouped conditions that must all be true)
559
562
  const compoundConditionals = getCompoundConditionals(dataStructure);
560
-
561
- console.log(
562
- `[ConditionalEffects] prepareDataStructures for ${entity.name}:`,
563
- `dataStructure.conditionalEffects=${(dataStructure as any).conditionalEffects?.length ?? 0}`,
564
- `getConditionalEffects returned ${conditionalEffects.length} effects`,
565
- conditionalEffects
566
- .slice(0, 5)
567
- .map(
568
- (e: any) =>
569
- `${e.effect?.setterName}(${e.effect?.value?.slice?.(0, 20) ?? e.effect?.value})`,
570
- ),
571
- );
572
-
573
563
  const rawUsageEquivalencies = getUsageEquivalencies(dataStructure);
574
564
  const rawSourceEquivalencies = getSourceEquivalencies(dataStructure);
575
565
 
@@ -577,6 +567,9 @@ async function getEntityDataStructureAndFunctionCalls({
577
567
  const childBoundaryGatingConditions =
578
568
  getChildBoundaryGatingConditions(dataStructure);
579
569
 
570
+ // Get JSX rendering usages for array size and text length flow generation
571
+ const jsxRenderingUsages = getJsxRenderingUsages(dataStructure);
572
+
580
573
  const isolatedDataStructure = {
581
574
  signatureSchema: deduplicateFunctionSchemas(clonedRawSignature),
582
575
  returnValueSchema: deduplicateFunctionSchemas(clonedRawReturnValue),
@@ -604,6 +597,10 @@ async function getEntityDataStructureAndFunctionCalls({
604
597
  Object.keys(childBoundaryGatingConditions).length > 0
605
598
  ? childBoundaryGatingConditions
606
599
  : undefined,
600
+ // Include JSX rendering usages for array size and text length flow generation
601
+ // These track arrays rendered via .map() and strings interpolated in JSX
602
+ jsxRenderingUsages:
603
+ jsxRenderingUsages.length > 0 ? jsxRenderingUsages : undefined,
607
604
  };
608
605
 
609
606
  const functionCalls: Record<string, string[]> = {};
@@ -100,6 +100,12 @@ export function getCandidatesReadyForCapture(
100
100
  continue;
101
101
  }
102
102
 
103
+ // Skip notExported entities - they can't be imported into the simulation
104
+ // environment and will always fail capture. Don't mark them as ready.
105
+ if (candidate.entity?.metadata?.notExported) {
106
+ continue;
107
+ }
108
+
103
109
  // Get all transitive dependencies
104
110
  const candidateKey = `${candidate.filePath}:${candidate.entityName}`;
105
111
  const { missingDependencies } = getTransitiveDependencies(
@@ -1,5 +1,6 @@
1
1
  import type {
2
2
  Analysis,
3
+ Entity,
3
4
  ReadonlyAnalysisMap,
4
5
  ReadonlyAnalysis,
5
6
  ReadonlyEntity,
@@ -61,7 +62,10 @@ export default function validateDependencyAnalyses({
61
62
  for (const dependency of entity.metadata?.importedExports ?? []) {
62
63
  const dependencyFilePath =
63
64
  dependency.resolvedFilePath ?? dependency.filePath;
64
- const dependencyName = dependency.resolvedName ?? dependency.name;
65
+ // Use the entity/import name, not the export name (resolvedName).
66
+ // For default exports, resolvedName is 'default' but the entity is stored
67
+ // under its actual identifier name (e.g., 'QuoteDetailsDrawer').
68
+ const dependencyName = dependency.name;
65
69
 
66
70
  // if the entity has duplicate dependencies, handle gracefully
67
71
  if (dependentAnalyses[dependencyFilePath]?.[dependencyName]) {
@@ -103,6 +107,23 @@ export default function validateDependencyAnalyses({
103
107
  continue;
104
108
  }
105
109
 
110
+ // Ensure the entity is attached to the analysis.
111
+ // The entity might not be attached if the analysis was loaded from the database
112
+ // without its entity being in the context's entity map.
113
+ // This is critical for generateDataStructure to merge child component tRPC calls.
114
+ let dependentEntity: ReadonlyEntity | undefined = dependentAnalysis.entity;
115
+ if (!dependentEntity) {
116
+ // Try to get the entity from the context
117
+ dependentEntity = context.getEntity(dependencyFilePath, dependencyName);
118
+ if (dependentEntity) {
119
+ // Attach the entity to the analysis (mutating, but necessary for downstream use)
120
+ // We need the double cast because ReadonlyEntity has readonly arrays that aren't
121
+ // assignable to Entity's mutable arrays.
122
+ (dependentAnalysis as unknown as Analysis).entity =
123
+ dependentEntity as unknown as Entity;
124
+ }
125
+ }
126
+
106
127
  // Store the dependent analysis
107
128
  dependentAnalyses[dependencyFilePath] ||= {};
108
129
  dependentAnalyses[dependencyFilePath][dependencyName] = dependentAnalysis;
@@ -125,12 +146,17 @@ export default function validateDependencyAnalyses({
125
146
  }
126
147
  }
127
148
 
128
- validateDependencyAnalyses({
129
- readonlyAnalysis: dependentAnalysis,
130
- entity: dependentAnalysis.entity,
131
- context: context,
132
- dependentAnalyses,
133
- });
149
+ // Only recurse if we have the entity. Without the entity, we can't process
150
+ // the dependency's own dependencies, but we can still use this dependency's
151
+ // analysis data (mergedDataStructure, etc.)
152
+ if (dependentEntity) {
153
+ validateDependencyAnalyses({
154
+ readonlyAnalysis: dependentAnalysis,
155
+ entity: dependentEntity,
156
+ context: context,
157
+ dependentAnalyses,
158
+ });
159
+ }
134
160
  }
135
161
 
136
162
  return { dependentAnalyses };
@@ -9,8 +9,12 @@ import { DataStructure } from '~codeyam/types';
9
9
  * enriches the mocked dependency's returnValueSchema so the LLM knows what fields
10
10
  * to generate for array elements.
11
11
  *
12
+ * Uses usageEquivalencies to trace data flow and ONLY enrich arrays with fields
13
+ * from children that actually receive elements from that array.
14
+ *
12
15
  * Example:
13
16
  * - getSurveysAction returns { data: array }
17
+ * - usageEquivalencies shows: surveys[] -> SurveyCard().signature[0].survey
14
18
  * - SurveyCard expects signature[0].survey.updatedAt: date
15
19
  * - After enrichment: getSurveysAction().data[]: object, data[].updatedAt: date
16
20
  */
@@ -21,6 +25,7 @@ export default function enrichArrayTypesFromChildSignatures(
21
25
  isMocked?: boolean;
22
26
  }[],
23
27
  dependencySchemas: DataStructure['dependencySchemas'],
28
+ usageEquivalencies?: DataStructure['usageEquivalencies'],
24
29
  ): void {
25
30
  // Find all mocked dependencies with array return types
26
31
  const mockedArrayPaths: {
@@ -43,7 +48,8 @@ export default function enrichArrayTypesFromChildSignatures(
43
48
  // - wrapThrows().data.createdBy (deeply nested)
44
49
  // - getStatusOptions().functionCallReturnValue (direct array return - usually options/primitives)
45
50
  for (const [path, type] of Object.entries(schema)) {
46
- if (type !== 'array') continue;
51
+ // Check if type is array (including nullable/optional variants like 'array | undefined')
52
+ if (!type.startsWith('array')) continue;
47
53
 
48
54
  // Skip paths with computed property patterns like [key], [i], [0], etc.
49
55
  // These represent dynamic access patterns, not simple data arrays
@@ -81,88 +87,103 @@ export default function enrichArrayTypesFromChildSignatures(
81
87
 
82
88
  if (mockedArrayPaths.length === 0) return;
83
89
 
84
- // Find all non-mocked child components and extract their signature fields
85
- // We check both direct imports AND all schemas in dependencySchemas because
86
- // transitive dependencies (e.g., SurveyCard imported by SurveysList imported by SurveysPage)
87
- // may have signature schemas that we need to use for enrichment.
88
- const childSignatureFields: {
89
- filePath: string;
90
- entityName: string;
91
- // Map of prop paths to types, e.g., { "survey.id": "string", "survey.updatedAt": "date" }
92
- propFields: Record<string, string>;
93
- }[] = [];
90
+ // Build a map from child component signature paths to their prop fields
91
+ // e.g., "SurveyCard().signature[0].survey" -> { "id": "string", "updatedAt": "date" }
92
+ const childSignatureFieldsByPath: Map<
93
+ string,
94
+ { propName: string; fields: Record<string, string> }
95
+ > = new Map();
94
96
 
95
- // Helper to extract prop fields from a signature schema
96
- const extractPropFields = (
97
+ // Helper to extract prop name and fields from a signature schema
98
+ const extractSignatureInfo = (
99
+ entityName: string,
97
100
  schema: Record<string, string>,
98
- ): Record<string, string> => {
99
- const propFields: Record<string, string> = {};
101
+ ): void => {
102
+ // Group by prop name (e.g., signature[0].survey.id, signature[0].survey.name -> "survey")
103
+ const propGroups: Record<string, Record<string, string>> = {};
104
+
100
105
  for (const [path, type] of Object.entries(schema)) {
101
- // Match signature[0].propName.field patterns
102
- const match = path.match(/^signature\[0\]\.(\w+)\.(.+)$/);
106
+ // Match signature[0].propName.field or signature[0].propName[].field patterns
107
+ // The (?:\[\])? makes array props optional, handling both:
108
+ // - signature[0].survey.updatedAt (object prop)
109
+ // - signature[0].questionAnswers[].question.questionText (array prop)
110
+ const match = path.match(/^signature\[0\]\.(\w+)(?:\[\])?\.(.+)$/);
103
111
  if (match) {
104
- const [, , fieldPath] = match;
105
- // Store as "fieldPath" without the prop name prefix
106
- // e.g., signature[0].survey.updatedAt -> updatedAt
107
- propFields[fieldPath] = type;
112
+ const [, propName, fieldPath] = match;
113
+ propGroups[propName] ||= {};
114
+ propGroups[propName][fieldPath] = type;
108
115
  }
109
116
  }
110
- return propFields;
111
- };
112
-
113
- // First, check direct imports (non-mocked)
114
- const processedSchemas = new Set<string>();
115
- for (const importedExport of importedExports) {
116
- // Skip mocked dependencies - we want child components
117
- if (importedExport.isMocked || !importedExport.filePath) continue;
118
-
119
- const schemaKey = `${importedExport.filePath}::${importedExport.name}`;
120
- processedSchemas.add(schemaKey);
121
-
122
- const schema =
123
- dependencySchemas?.[importedExport.filePath]?.[importedExport.name]
124
- ?.signatureSchema;
125
- if (!schema) continue;
126
117
 
127
- const propFields = extractPropFields(schema);
128
- if (Object.keys(propFields).length > 0) {
129
- childSignatureFields.push({
130
- filePath: importedExport.filePath,
131
- entityName: importedExport.name,
132
- propFields,
133
- });
118
+ // Store with the full signature path as key
119
+ for (const [propName, fields] of Object.entries(propGroups)) {
120
+ if (Object.keys(fields).length > 0) {
121
+ const signaturePath = `${entityName}().signature[0].${propName}`;
122
+ childSignatureFieldsByPath.set(signaturePath, { propName, fields });
123
+ }
134
124
  }
135
- }
125
+ };
136
126
 
137
- // Also check all schemas in dependencySchemas for transitive child components
138
- // that may not be in importedExports but have signature schemas with prop fields
127
+ // Process all schemas in dependencySchemas
139
128
  if (dependencySchemas) {
140
- for (const [filePath, entities] of Object.entries(dependencySchemas)) {
129
+ for (const [, entities] of Object.entries(dependencySchemas)) {
141
130
  for (const [entityName, schemas] of Object.entries(entities)) {
142
- const schemaKey = `${filePath}::${entityName}`;
143
- // Skip already processed schemas
144
- if (processedSchemas.has(schemaKey)) continue;
145
-
146
131
  const signatureSchema = schemas?.signatureSchema;
147
- if (!signatureSchema) continue;
148
-
149
- const propFields = extractPropFields(signatureSchema);
150
- if (Object.keys(propFields).length > 0) {
151
- childSignatureFields.push({
152
- filePath,
153
- entityName,
154
- propFields,
155
- });
132
+ if (signatureSchema) {
133
+ extractSignatureInfo(entityName, signatureSchema);
156
134
  }
157
135
  }
158
136
  }
159
137
  }
160
138
 
161
- if (childSignatureFields.length === 0) return;
139
+ if (childSignatureFieldsByPath.size === 0) return;
140
+
141
+ // Helper to check if a local variable name could be derived from a mocked function name
142
+ // e.g., "getSurveys" -> "surveys", "fetchUsers" -> "users", "loadData" -> "data"
143
+ // e.g., "getSurveysAction" -> "surveys" (removes "Action" suffix too)
144
+ const couldBeDerivedFrom = (
145
+ localVarName: string,
146
+ mockedFunctionName: string,
147
+ ): boolean => {
148
+ const normalizedVar = localVarName.toLowerCase().replace(/\[\]$/, '');
149
+ let normalizedFunc = mockedFunctionName.toLowerCase();
150
+
151
+ // Direct match (e.g., "surveys" from function "surveys")
152
+ if (normalizedFunc === normalizedVar) return true;
162
153
 
163
- // Enrich mocked dependency arrays with child signature fields
164
- // Only enrich arrays that don't already have element types defined
165
- // A more sophisticated approach would trace the data flow to match specific arrays to specific children
154
+ // Remove common prefixes like "get", "fetch", "load", "use"
155
+ const prefixPattern = /^(get|fetch|load|use)/i;
156
+ normalizedFunc = normalizedFunc.replace(prefixPattern, '');
157
+
158
+ // Remove common suffixes like "Action", "Query", "Mutation", "Handler"
159
+ const suffixPattern = /(action|query|mutation|handler)$/i;
160
+ normalizedFunc = normalizedFunc.replace(suffixPattern, '');
161
+
162
+ // Check if function name (without prefix/suffix) matches the variable name
163
+ if (normalizedFunc === normalizedVar) return true;
164
+
165
+ // Check for singular/plural relationship
166
+ // e.g., "survey" from "getSurveys" or "surveys" from "getSurvey"
167
+ if (
168
+ normalizedFunc.endsWith('s') &&
169
+ normalizedFunc.slice(0, -1) === normalizedVar
170
+ )
171
+ return true;
172
+ if (
173
+ normalizedVar.endsWith('s') &&
174
+ normalizedVar.slice(0, -1) === normalizedFunc
175
+ )
176
+ return true;
177
+
178
+ // Check if the array property name (like "data") is in the variable
179
+ // This handles cases like "const { data: surveys } = getSurveys()" where
180
+ // the local var might be the renamed destructured property
181
+ // Skip this for now as it's too loose
182
+
183
+ return false;
184
+ };
185
+
186
+ // For each mocked array, find which child signatures it flows to via usageEquivalencies
166
187
  for (const { filePath, entityName, arrayPath } of mockedArrayPaths) {
167
188
  const schema = dependencySchemas[filePath][entityName].returnValueSchema;
168
189
 
@@ -179,17 +200,65 @@ export default function enrichArrayTypesFromChildSignatures(
179
200
  continue;
180
201
  }
181
202
 
182
- // Add array element type
203
+ // Find matching child signatures via usageEquivalencies
204
+ // Look for equivalencies where this array (or local variables derived from it)
205
+ // flows to a child component's signature
206
+ const matchedFields: Record<string, string> = {};
207
+
208
+ if (usageEquivalencies) {
209
+ // Check all equivalency entries for paths that could be derived from this array
210
+ for (const [sourcePath, targets] of Object.entries(usageEquivalencies)) {
211
+ // Check if this source path relates to our mocked array
212
+ // Direct match: "getSurveysAction().functionCallReturnValue.data[]"
213
+ // Indirect match: local variable like "surveys[]" that comes from the array
214
+ if (!sourcePath.endsWith('[]')) continue;
215
+
216
+ // Get the local variable name from the source path (e.g., "surveys[]" -> "surveys")
217
+ const localVarName = sourcePath.replace(/\[\]$/, '');
218
+
219
+ // Check if this local variable could have come from this mocked function
220
+ // Use heuristics: name matching (getSurveys -> surveys, getUsers -> users)
221
+ if (!couldBeDerivedFrom(localVarName, entityName)) {
222
+ continue;
223
+ }
224
+
225
+ for (const target of targets) {
226
+ // Target should be something like "SurveyCard().signature[0].survey"
227
+ // or "SurveyCard().signature[0].surveys[]"
228
+ const { schemaPath } = target;
229
+
230
+ // Look for signature fields that match this target
231
+ // Handle both singular (survey) and plural (surveys[]) forms
232
+ const normalizedTarget = schemaPath.replace(/\[\]$/, '');
233
+
234
+ for (const [signaturePath, info] of childSignatureFieldsByPath) {
235
+ if (normalizedTarget === signaturePath) {
236
+ // Found a match! Add all fields from this child signature
237
+ for (const [fieldPath, type] of Object.entries(info.fields)) {
238
+ if (!matchedFields[fieldPath]) {
239
+ matchedFields[fieldPath] = type;
240
+ }
241
+ }
242
+ }
243
+ }
244
+ }
245
+ }
246
+ }
247
+
248
+ // If no equivalencies matched, skip this array entirely
249
+ // This prevents the bug where ALL child signatures get merged into ALL arrays
250
+ if (Object.keys(matchedFields).length === 0) {
251
+ continue;
252
+ }
253
+
254
+ // Add array element type and matched fields
183
255
  const elementPath = `${arrayPath}[]`;
184
256
  schema[elementPath] = 'object';
185
257
 
186
- // Add fields from all child signatures to the array element
187
- for (const { propFields } of childSignatureFields) {
188
- for (const [fieldPath, type] of Object.entries(propFields)) {
189
- const fullPath = `${elementPath}.${fieldPath}`;
190
- if (!schema[fullPath]) {
191
- schema[fullPath] = type;
192
- }
258
+ for (const [fieldPath, type] of Object.entries(matchedFields)) {
259
+ const fullPath = `${elementPath}.${fieldPath}`;
260
+ if (!schema[fullPath]) {
261
+ schema[fullPath] = type;
193
262
  }
194
263
  }
195
264
  }