@codeyam/codeyam-cli 0.1.0-staging.2a88920 → 0.1.0-staging.4684848

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 (364) 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 +4 -4
  4. package/analyzer-template/packages/ai/index.ts +1 -0
  5. package/analyzer-template/packages/ai/package.json +2 -2
  6. package/analyzer-template/packages/ai/src/lib/analyzeScope.ts +23 -1
  7. package/analyzer-template/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.ts +10 -17
  8. package/analyzer-template/packages/ai/src/lib/astScopes/processExpression.ts +101 -0
  9. package/analyzer-template/packages/ai/src/lib/astScopes/sharedPatterns.ts +28 -0
  10. package/analyzer-template/packages/ai/src/lib/astScopes/types.ts +6 -0
  11. package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +330 -9
  12. package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.ts +5 -1
  13. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.ts +11 -2
  14. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.ts +2 -2
  15. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.ts +70 -0
  16. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.ts +140 -14
  17. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.ts +20 -1
  18. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.ts +84 -19
  19. package/analyzer-template/packages/ai/src/lib/dataStructureChunking.ts +33 -15
  20. package/analyzer-template/packages/ai/src/lib/generateEntityDataStructure.ts +58 -3
  21. package/analyzer-template/packages/ai/src/lib/generateEntityScenarioData.ts +299 -5
  22. package/analyzer-template/packages/ai/src/lib/generateExecutionFlows.ts +38 -2
  23. package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromConditionals.ts +359 -142
  24. package/analyzer-template/packages/ai/src/lib/isolateScopes.ts +51 -3
  25. package/analyzer-template/packages/ai/src/lib/mergeJsonTypeDefinitions.ts +5 -0
  26. package/analyzer-template/packages/ai/src/lib/promptGenerators/collapseNullableObjects.ts +118 -0
  27. package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.ts +24 -4
  28. package/analyzer-template/packages/analyze/index.ts +2 -0
  29. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +69 -3
  30. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +5 -0
  31. package/analyzer-template/packages/analyze/src/lib/files/scenarios/TransformationTracer.ts +1315 -0
  32. package/analyzer-template/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.ts +4 -0
  33. package/analyzer-template/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.ts +59 -26
  34. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +194 -15
  35. package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +372 -57
  36. package/analyzer-template/packages/analyze/src/lib/index.ts +1 -0
  37. package/analyzer-template/packages/database/package.json +1 -1
  38. package/analyzer-template/packages/database/src/lib/analysisBranchToDb.ts +1 -1
  39. package/analyzer-template/packages/database/src/lib/analysisToDb.ts +1 -1
  40. package/analyzer-template/packages/database/src/lib/branchToDb.ts +1 -1
  41. package/analyzer-template/packages/database/src/lib/commitBranchToDb.ts +1 -1
  42. package/analyzer-template/packages/database/src/lib/commitToDb.ts +1 -1
  43. package/analyzer-template/packages/database/src/lib/fileToDb.ts +1 -1
  44. package/analyzer-template/packages/database/src/lib/kysely/db.ts +6 -0
  45. package/analyzer-template/packages/database/src/lib/kysely/tables/debugReportsTable.ts +1 -1
  46. package/analyzer-template/packages/database/src/lib/kysely/tables/labsRequestsTable.ts +52 -0
  47. package/analyzer-template/packages/database/src/lib/projectToDb.ts +1 -1
  48. package/analyzer-template/packages/database/src/lib/saveFiles.ts +1 -1
  49. package/analyzer-template/packages/database/src/lib/scenarioToDb.ts +1 -1
  50. package/analyzer-template/packages/database/src/lib/userScenarioToDb.ts +1 -1
  51. package/analyzer-template/packages/github/dist/database/src/lib/analysisBranchToDb.js +1 -1
  52. package/analyzer-template/packages/github/dist/database/src/lib/analysisBranchToDb.js.map +1 -1
  53. package/analyzer-template/packages/github/dist/database/src/lib/analysisToDb.js +1 -1
  54. package/analyzer-template/packages/github/dist/database/src/lib/analysisToDb.js.map +1 -1
  55. package/analyzer-template/packages/github/dist/database/src/lib/branchToDb.js +1 -1
  56. package/analyzer-template/packages/github/dist/database/src/lib/branchToDb.js.map +1 -1
  57. package/analyzer-template/packages/github/dist/database/src/lib/commitBranchToDb.js +1 -1
  58. package/analyzer-template/packages/github/dist/database/src/lib/commitBranchToDb.js.map +1 -1
  59. package/analyzer-template/packages/github/dist/database/src/lib/commitToDb.js +1 -1
  60. package/analyzer-template/packages/github/dist/database/src/lib/commitToDb.js.map +1 -1
  61. package/analyzer-template/packages/github/dist/database/src/lib/fileToDb.js +1 -1
  62. package/analyzer-template/packages/github/dist/database/src/lib/fileToDb.js.map +1 -1
  63. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts +2 -0
  64. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts.map +1 -1
  65. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js +3 -0
  66. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js.map +1 -1
  67. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.d.ts +1 -1
  68. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/labsRequestsTable.d.ts +23 -0
  69. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/labsRequestsTable.d.ts.map +1 -0
  70. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/labsRequestsTable.js +35 -0
  71. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/labsRequestsTable.js.map +1 -0
  72. package/analyzer-template/packages/github/dist/database/src/lib/projectToDb.js +1 -1
  73. package/analyzer-template/packages/github/dist/database/src/lib/projectToDb.js.map +1 -1
  74. package/analyzer-template/packages/github/dist/database/src/lib/saveFiles.js +1 -1
  75. package/analyzer-template/packages/github/dist/database/src/lib/saveFiles.js.map +1 -1
  76. package/analyzer-template/packages/github/dist/database/src/lib/scenarioToDb.js +1 -1
  77. package/analyzer-template/packages/github/dist/database/src/lib/scenarioToDb.js.map +1 -1
  78. package/analyzer-template/packages/github/dist/types/src/types/ProjectMetadata.d.ts +7 -0
  79. package/analyzer-template/packages/github/dist/types/src/types/ProjectMetadata.d.ts.map +1 -1
  80. package/analyzer-template/packages/types/src/types/ProjectMetadata.ts +7 -0
  81. package/analyzer-template/packages/utils/dist/types/src/types/ProjectMetadata.d.ts +7 -0
  82. package/analyzer-template/packages/utils/dist/types/src/types/ProjectMetadata.d.ts.map +1 -1
  83. package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.d.ts.map +1 -1
  84. package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.js +93 -2
  85. package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.js.map +1 -1
  86. package/analyzer-template/packages/utils/src/lib/fs/rsyncCopy.ts +108 -2
  87. package/analyzer-template/project/constructMockCode.ts +36 -1
  88. package/analyzer-template/project/writeMockDataTsx.ts +174 -12
  89. package/analyzer-template/project/writeScenarioComponents.ts +60 -12
  90. package/analyzer-template/project/writeSimpleRoot.ts +21 -11
  91. package/background/src/lib/local/createLocalAnalyzer.js +1 -1
  92. package/background/src/lib/local/createLocalAnalyzer.js.map +1 -1
  93. package/background/src/lib/virtualized/project/constructMockCode.js +30 -1
  94. package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
  95. package/background/src/lib/virtualized/project/writeMockDataTsx.js +156 -8
  96. package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
  97. package/background/src/lib/virtualized/project/writeScenarioComponents.js +60 -15
  98. package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
  99. package/background/src/lib/virtualized/project/writeSimpleRoot.js +21 -11
  100. package/background/src/lib/virtualized/project/writeSimpleRoot.js.map +1 -1
  101. package/codeyam-cli/scripts/apply-setup.js +180 -0
  102. package/codeyam-cli/scripts/apply-setup.js.map +1 -1
  103. package/codeyam-cli/src/cli.js +2 -0
  104. package/codeyam-cli/src/cli.js.map +1 -1
  105. package/codeyam-cli/src/codeyam-cli.js +18 -2
  106. package/codeyam-cli/src/codeyam-cli.js.map +1 -1
  107. package/codeyam-cli/src/commands/analyze.js +4 -2
  108. package/codeyam-cli/src/commands/analyze.js.map +1 -1
  109. package/codeyam-cli/src/commands/baseline.js +2 -0
  110. package/codeyam-cli/src/commands/baseline.js.map +1 -1
  111. package/codeyam-cli/src/commands/debug.js +2 -0
  112. package/codeyam-cli/src/commands/debug.js.map +1 -1
  113. package/codeyam-cli/src/commands/default.js +31 -20
  114. package/codeyam-cli/src/commands/default.js.map +1 -1
  115. package/codeyam-cli/src/commands/detect-universal-mocks.js +2 -0
  116. package/codeyam-cli/src/commands/detect-universal-mocks.js.map +1 -1
  117. package/codeyam-cli/src/commands/init.js +49 -257
  118. package/codeyam-cli/src/commands/init.js.map +1 -1
  119. package/codeyam-cli/src/commands/memory.js +17 -26
  120. package/codeyam-cli/src/commands/memory.js.map +1 -1
  121. package/codeyam-cli/src/commands/recapture.js +2 -0
  122. package/codeyam-cli/src/commands/recapture.js.map +1 -1
  123. package/codeyam-cli/src/commands/setup-sandbox.js +2 -0
  124. package/codeyam-cli/src/commands/setup-sandbox.js.map +1 -1
  125. package/codeyam-cli/src/commands/setup-simulations.js +284 -0
  126. package/codeyam-cli/src/commands/setup-simulations.js.map +1 -0
  127. package/codeyam-cli/src/commands/test-startup.js +2 -0
  128. package/codeyam-cli/src/commands/test-startup.js.map +1 -1
  129. package/codeyam-cli/src/commands/verify.js +14 -2
  130. package/codeyam-cli/src/commands/verify.js.map +1 -1
  131. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js +128 -86
  132. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js.map +1 -1
  133. package/codeyam-cli/src/utils/analyzer.js +7 -0
  134. package/codeyam-cli/src/utils/analyzer.js.map +1 -1
  135. package/codeyam-cli/src/utils/backgroundServer.js +9 -0
  136. package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
  137. package/codeyam-cli/src/utils/generateReport.js +2 -2
  138. package/codeyam-cli/src/utils/install-skills.js +57 -54
  139. package/codeyam-cli/src/utils/install-skills.js.map +1 -1
  140. package/codeyam-cli/src/utils/labsAutoCheck.js +19 -0
  141. package/codeyam-cli/src/utils/labsAutoCheck.js.map +1 -0
  142. package/codeyam-cli/src/utils/progress.js +7 -0
  143. package/codeyam-cli/src/utils/progress.js.map +1 -1
  144. package/codeyam-cli/src/utils/queue/job.js +4 -0
  145. package/codeyam-cli/src/utils/queue/job.js.map +1 -1
  146. package/codeyam-cli/src/utils/requireSimulations.js +10 -0
  147. package/codeyam-cli/src/utils/requireSimulations.js.map +1 -0
  148. package/codeyam-cli/src/utils/ruleReflection/__tests__/confusionDetector.test.js +82 -0
  149. package/codeyam-cli/src/utils/ruleReflection/__tests__/confusionDetector.test.js.map +1 -0
  150. package/codeyam-cli/src/utils/ruleReflection/__tests__/contextBuilder.test.js +230 -0
  151. package/codeyam-cli/src/utils/ruleReflection/__tests__/contextBuilder.test.js.map +1 -0
  152. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/assertRules.js +67 -0
  153. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/assertRules.js.map +1 -0
  154. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/captureFixture.js +105 -0
  155. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/captureFixture.js.map +1 -0
  156. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/loadCapturedFixture.js +34 -0
  157. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/loadCapturedFixture.js.map +1 -0
  158. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/runClaude.js +162 -0
  159. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/runClaude.js.map +1 -0
  160. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js +75 -0
  161. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js.map +1 -0
  162. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js +378 -0
  163. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js.map +1 -0
  164. package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js +115 -0
  165. package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js.map +1 -0
  166. package/codeyam-cli/src/utils/ruleReflection/__tests__/transcriptParser.test.js +127 -0
  167. package/codeyam-cli/src/utils/ruleReflection/__tests__/transcriptParser.test.js.map +1 -0
  168. package/codeyam-cli/src/utils/ruleReflection/confusionDetector.js +50 -0
  169. package/codeyam-cli/src/utils/ruleReflection/confusionDetector.js.map +1 -0
  170. package/codeyam-cli/src/utils/ruleReflection/contextBuilder.js +116 -0
  171. package/codeyam-cli/src/utils/ruleReflection/contextBuilder.js.map +1 -0
  172. package/codeyam-cli/src/utils/ruleReflection/index.js +5 -0
  173. package/codeyam-cli/src/utils/ruleReflection/index.js.map +1 -0
  174. package/codeyam-cli/src/utils/ruleReflection/promptBuilder.js +44 -0
  175. package/codeyam-cli/src/utils/ruleReflection/promptBuilder.js.map +1 -0
  176. package/codeyam-cli/src/utils/ruleReflection/transcriptParser.js +85 -0
  177. package/codeyam-cli/src/utils/ruleReflection/transcriptParser.js.map +1 -0
  178. package/codeyam-cli/src/utils/ruleReflection/types.js +5 -0
  179. package/codeyam-cli/src/utils/ruleReflection/types.js.map +1 -0
  180. package/codeyam-cli/src/utils/rules/__tests__/ruleState.test.js +293 -0
  181. package/codeyam-cli/src/utils/rules/__tests__/ruleState.test.js.map +1 -0
  182. package/codeyam-cli/src/utils/rules/index.js +1 -0
  183. package/codeyam-cli/src/utils/rules/index.js.map +1 -1
  184. package/codeyam-cli/src/utils/rules/parser.js +2 -25
  185. package/codeyam-cli/src/utils/rules/parser.js.map +1 -1
  186. package/codeyam-cli/src/utils/rules/ruleState.js +150 -0
  187. package/codeyam-cli/src/utils/rules/ruleState.js.map +1 -0
  188. package/codeyam-cli/src/utils/rules/staleness.js +16 -11
  189. package/codeyam-cli/src/utils/rules/staleness.js.map +1 -1
  190. package/codeyam-cli/src/utils/serverState.js +37 -10
  191. package/codeyam-cli/src/utils/serverState.js.map +1 -1
  192. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +21 -44
  193. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js.map +1 -1
  194. package/codeyam-cli/src/webserver/app/lib/database.js +15 -3
  195. package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
  196. package/codeyam-cli/src/webserver/backgroundServer.js +24 -0
  197. package/codeyam-cli/src/webserver/backgroundServer.js.map +1 -1
  198. package/codeyam-cli/src/webserver/build/client/assets/CopyButton-CQ-wF3Tv.js +1 -0
  199. package/codeyam-cli/src/webserver/build/client/assets/{EntityItem-DsN1wKrm.js → EntityItem-HdckCi0m.js} +1 -1
  200. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeBadge-DLqD3qNt.js → EntityTypeBadge-Dh5RJMOE.js} +1 -1
  201. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeIcon-Ba2JVPzP.js → EntityTypeIcon-BnjjBHJu.js} +1 -1
  202. package/codeyam-cli/src/webserver/build/client/assets/{InlineSpinner-C8lyxW9k.js → InlineSpinner-CUSfu6W5.js} +1 -1
  203. package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-aht4aafF.js → InteractivePreview-Coll1aD6.js} +2 -2
  204. package/codeyam-cli/src/webserver/build/client/assets/{LibraryFunctionPreview-CVtiBnY5.js → LibraryFunctionPreview-lYMY8h-y.js} +1 -1
  205. package/codeyam-cli/src/webserver/build/client/assets/{LoadingDots-B0GLXMsr.js → LoadingDots-ay8XeA59.js} +1 -1
  206. package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-xgeCVgSM.js → LogViewer-Dpul1_ik.js} +1 -1
  207. package/codeyam-cli/src/webserver/build/client/assets/{ReportIssueModal-OApQuNyq.js → ReportIssueModal-CRBCfV2W.js} +3 -8
  208. package/codeyam-cli/src/webserver/build/client/assets/{SafeScreenshot-DuDvi0jm.js → SafeScreenshot-DRTFDNFt.js} +1 -1
  209. package/codeyam-cli/src/webserver/build/client/assets/{ScenarioViewer-DzccYyI8.js → ScenarioViewer-d6PSFxhS.js} +2 -2
  210. package/codeyam-cli/src/webserver/build/client/assets/{TruncatedFilePath-DyFZkK0l.js → TruncatedFilePath-DDEOQ6Iw.js} +1 -1
  211. package/codeyam-cli/src/webserver/build/client/assets/{_index-BwqWJOgH.js → _index-CkziGg5F.js} +1 -1
  212. package/codeyam-cli/src/webserver/build/client/assets/{activity.(_tab)-BwavGCpm.js → activity.(_tab)-B2v1pm9w.js} +6 -11
  213. package/codeyam-cli/src/webserver/build/client/assets/agent-transcripts-BXIaK8Md.js +11 -0
  214. package/codeyam-cli/src/webserver/build/client/assets/api.agent-transcripts-l0sNRNKZ.js +1 -0
  215. package/codeyam-cli/src/webserver/build/client/assets/api.labs-unlock-l0sNRNKZ.js +1 -0
  216. package/codeyam-cli/src/webserver/build/client/assets/api.save-fixture-l0sNRNKZ.js +1 -0
  217. package/codeyam-cli/src/webserver/build/client/assets/book-open-qbapxy6o.js +6 -0
  218. package/codeyam-cli/src/webserver/build/client/assets/{chevron-down-Cx24_aWc.js → chevron-down-C-mKrwr1.js} +1 -1
  219. package/codeyam-cli/src/webserver/build/client/assets/{chunk-EPOLDU6W-CXRTFQ3F.js → chunk-JZWAC4HX-BAvUl1nT.js} +12 -12
  220. package/codeyam-cli/src/webserver/build/client/assets/{circle-check-BOARzkeR.js → circle-check-DlrT-SzI.js} +1 -1
  221. package/codeyam-cli/src/webserver/build/client/assets/copy-clIxnCqQ.js +11 -0
  222. package/codeyam-cli/src/webserver/build/client/assets/{createLucideIcon-BdhJEx6B.js → createLucideIcon-B931Etud.js} +1 -1
  223. package/codeyam-cli/src/webserver/build/client/assets/{dev.empty-BBnGWYga.js → dev.empty-BoPM6KnE.js} +1 -1
  224. package/codeyam-cli/src/webserver/build/client/assets/entity._sha._-oVRMh9Hl.js +16 -0
  225. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.fullscreen-DavjRmOY.js → entity._sha.scenarios._scenarioId.fullscreen-BjyzwQ7H.js} +1 -1
  226. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.create-scenario-D1T4TGjf.js → entity._sha_.create-scenario-DxuyDmZA.js} +1 -1
  227. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.edit._scenarioId-CTBG2mmz.js → entity._sha_.edit._scenarioId-DESSZGQp.js} +1 -1
  228. package/codeyam-cli/src/webserver/build/client/assets/{entry.client-CS2cb_eZ.js → entry.client-D5Yb90Ad.js} +1 -1
  229. package/codeyam-cli/src/webserver/build/client/assets/{fileTableUtils-DMJ7zii9.js → fileTableUtils-DuObVYgh.js} +1 -1
  230. package/codeyam-cli/src/webserver/build/client/assets/{files-CJ6lTdTA.js → files-CDfz4Y-i.js} +1 -1
  231. package/codeyam-cli/src/webserver/build/client/assets/{git-CPTZZ-JZ.js → git-D6jOlDQw.js} +1 -1
  232. package/codeyam-cli/src/webserver/build/client/assets/globals-CKT08Djd.css +1 -0
  233. package/codeyam-cli/src/webserver/build/client/assets/{index-B1h680n5.js → index-DvOt1KIt.js} +1 -1
  234. package/codeyam-cli/src/webserver/build/client/assets/{index-lzqtyFU8.js → index-WfQFdoWK.js} +1 -1
  235. package/codeyam-cli/src/webserver/build/client/assets/labs-BbGyC1RY.js +1 -0
  236. package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-B7B9V-bu.js → loader-circle-Bb7Y9k5O.js} +1 -1
  237. package/codeyam-cli/src/webserver/build/client/assets/manifest-fd06e67a.js +1 -0
  238. package/codeyam-cli/src/webserver/build/client/assets/memory-BXebUPaL.js +78 -0
  239. package/codeyam-cli/src/webserver/build/client/assets/pause-DaAHX2on.js +11 -0
  240. package/codeyam-cli/src/webserver/build/client/assets/root-CvNE9MaT.js +62 -0
  241. package/codeyam-cli/src/webserver/build/client/assets/{search-CxXUmBSd.js → search-DIqAPIrO.js} +1 -1
  242. package/codeyam-cli/src/webserver/build/client/assets/settings-DCIzBZM9.js +1 -0
  243. package/codeyam-cli/src/webserver/build/client/assets/{simulations-DwFIBT09.js → simulations-C6n_fNQY.js} +1 -1
  244. package/codeyam-cli/src/webserver/build/client/assets/terminal-CmPsszJy.js +11 -0
  245. package/codeyam-cli/src/webserver/build/client/assets/{triangle-alert-B6LgvRJg.js → triangle-alert-Beg-oV50.js} +1 -1
  246. package/codeyam-cli/src/webserver/build/client/assets/{useCustomSizes-C1v1PQzo.js → useCustomSizes-D7TLbP3M.js} +1 -1
  247. package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-aSv48UbS.js → useLastLogLine-Ce5rnai3.js} +1 -1
  248. package/codeyam-cli/src/webserver/build/client/assets/{useReportContext-DYxHZQuP.js → useReportContext-B4D3wj27.js} +1 -1
  249. package/codeyam-cli/src/webserver/build/client/assets/{useToast-mBRpZPiu.js → useToast-BDt_-DnY.js} +1 -1
  250. package/codeyam-cli/src/webserver/build/server/assets/{index-BM6TDT1Y.js → index-DDr9Cp9M.js} +1 -1
  251. package/codeyam-cli/src/webserver/build/server/assets/server-build-DjwiujaU.js +257 -0
  252. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  253. package/codeyam-cli/src/webserver/build-info.json +5 -5
  254. package/codeyam-cli/templates/{codeyam:debug.md → codeyam-debug.md} +1 -1
  255. package/codeyam-cli/templates/codeyam-diagnose.md +481 -0
  256. package/codeyam-cli/templates/codeyam-memory-hook.sh +19 -20
  257. package/codeyam-cli/templates/codeyam-memory.md +392 -0
  258. package/codeyam-cli/templates/{codeyam:new-rule.md → codeyam-new-rule.md} +2 -2
  259. package/codeyam-cli/templates/{codeyam:setup.md → codeyam-setup.md} +13 -1
  260. package/codeyam-cli/templates/{codeyam:sim.md → codeyam-sim.md} +1 -1
  261. package/codeyam-cli/templates/{codeyam:test.md → codeyam-test.md} +1 -1
  262. package/codeyam-cli/templates/{codeyam:verify.md → codeyam-verify.md} +1 -1
  263. package/codeyam-cli/templates/rule-notification-hook.py +56 -0
  264. package/codeyam-cli/templates/rule-reflection-hook.py +554 -87
  265. package/codeyam-cli/templates/rules-instructions.md +63 -24
  266. package/package.json +10 -10
  267. package/packages/ai/index.js +1 -1
  268. package/packages/ai/index.js.map +1 -1
  269. package/packages/ai/src/lib/analyzeScope.js +21 -1
  270. package/packages/ai/src/lib/analyzeScope.js.map +1 -1
  271. package/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.js +10 -14
  272. package/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.js.map +1 -1
  273. package/packages/ai/src/lib/astScopes/processExpression.js +78 -1
  274. package/packages/ai/src/lib/astScopes/processExpression.js.map +1 -1
  275. package/packages/ai/src/lib/astScopes/sharedPatterns.js +25 -0
  276. package/packages/ai/src/lib/astScopes/sharedPatterns.js.map +1 -1
  277. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +262 -8
  278. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
  279. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js +5 -1
  280. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js.map +1 -1
  281. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js +11 -2
  282. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js.map +1 -1
  283. package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js +2 -2
  284. package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js.map +1 -1
  285. package/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.js +63 -0
  286. package/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.js.map +1 -0
  287. package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js +122 -12
  288. package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js.map +1 -1
  289. package/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.js +15 -1
  290. package/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.js.map +1 -1
  291. package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js +78 -17
  292. package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js.map +1 -1
  293. package/packages/ai/src/lib/dataStructureChunking.js +26 -11
  294. package/packages/ai/src/lib/dataStructureChunking.js.map +1 -1
  295. package/packages/ai/src/lib/generateEntityDataStructure.js +46 -2
  296. package/packages/ai/src/lib/generateEntityDataStructure.js.map +1 -1
  297. package/packages/ai/src/lib/generateEntityScenarioData.js +212 -3
  298. package/packages/ai/src/lib/generateEntityScenarioData.js.map +1 -1
  299. package/packages/ai/src/lib/generateExecutionFlows.js +16 -2
  300. package/packages/ai/src/lib/generateExecutionFlows.js.map +1 -1
  301. package/packages/ai/src/lib/generateExecutionFlowsFromConditionals.js +242 -81
  302. package/packages/ai/src/lib/generateExecutionFlowsFromConditionals.js.map +1 -1
  303. package/packages/ai/src/lib/isolateScopes.js +39 -3
  304. package/packages/ai/src/lib/isolateScopes.js.map +1 -1
  305. package/packages/ai/src/lib/mergeJsonTypeDefinitions.js +5 -0
  306. package/packages/ai/src/lib/mergeJsonTypeDefinitions.js.map +1 -1
  307. package/packages/ai/src/lib/promptGenerators/collapseNullableObjects.js +97 -0
  308. package/packages/ai/src/lib/promptGenerators/collapseNullableObjects.js.map +1 -0
  309. package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js +17 -2
  310. package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js.map +1 -1
  311. package/packages/analyze/index.js +1 -0
  312. package/packages/analyze/index.js.map +1 -1
  313. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +52 -2
  314. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
  315. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +3 -0
  316. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
  317. package/packages/analyze/src/lib/files/scenarios/TransformationTracer.js +880 -0
  318. package/packages/analyze/src/lib/files/scenarios/TransformationTracer.js.map +1 -0
  319. package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js +5 -1
  320. package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js.map +1 -1
  321. package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js +51 -14
  322. package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js.map +1 -1
  323. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +116 -13
  324. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
  325. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +310 -45
  326. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
  327. package/packages/analyze/src/lib/index.js +1 -0
  328. package/packages/analyze/src/lib/index.js.map +1 -1
  329. package/packages/database/src/lib/analysisBranchToDb.js +1 -1
  330. package/packages/database/src/lib/analysisBranchToDb.js.map +1 -1
  331. package/packages/database/src/lib/analysisToDb.js +1 -1
  332. package/packages/database/src/lib/analysisToDb.js.map +1 -1
  333. package/packages/database/src/lib/branchToDb.js +1 -1
  334. package/packages/database/src/lib/branchToDb.js.map +1 -1
  335. package/packages/database/src/lib/commitBranchToDb.js +1 -1
  336. package/packages/database/src/lib/commitBranchToDb.js.map +1 -1
  337. package/packages/database/src/lib/commitToDb.js +1 -1
  338. package/packages/database/src/lib/commitToDb.js.map +1 -1
  339. package/packages/database/src/lib/fileToDb.js +1 -1
  340. package/packages/database/src/lib/fileToDb.js.map +1 -1
  341. package/packages/database/src/lib/kysely/db.js +3 -0
  342. package/packages/database/src/lib/kysely/db.js.map +1 -1
  343. package/packages/database/src/lib/kysely/tables/labsRequestsTable.js +35 -0
  344. package/packages/database/src/lib/kysely/tables/labsRequestsTable.js.map +1 -0
  345. package/packages/database/src/lib/projectToDb.js +1 -1
  346. package/packages/database/src/lib/projectToDb.js.map +1 -1
  347. package/packages/database/src/lib/saveFiles.js +1 -1
  348. package/packages/database/src/lib/saveFiles.js.map +1 -1
  349. package/packages/database/src/lib/scenarioToDb.js +1 -1
  350. package/packages/database/src/lib/scenarioToDb.js.map +1 -1
  351. package/packages/utils/src/lib/fs/rsyncCopy.js +93 -2
  352. package/packages/utils/src/lib/fs/rsyncCopy.js.map +1 -1
  353. package/scripts/finalize-analyzer.cjs +8 -76
  354. package/codeyam-cli/src/webserver/build/client/assets/copy-Bb-80kDT.js +0 -6
  355. package/codeyam-cli/src/webserver/build/client/assets/entity._sha._-BJUiQqZF.js +0 -23
  356. package/codeyam-cli/src/webserver/build/client/assets/file-code-Dhef1kWN.js +0 -6
  357. package/codeyam-cli/src/webserver/build/client/assets/globals-D3yhhV8x.css +0 -1
  358. package/codeyam-cli/src/webserver/build/client/assets/manifest-a78b90a2.js +0 -1
  359. package/codeyam-cli/src/webserver/build/client/assets/memory--GCbFsBE.js +0 -92
  360. package/codeyam-cli/src/webserver/build/client/assets/root-eVAaavTS.js +0 -62
  361. package/codeyam-cli/src/webserver/build/client/assets/settings-CS5f3WzT.js +0 -1
  362. package/codeyam-cli/src/webserver/build/server/assets/server-build-dYC34MHw.js +0 -257
  363. package/codeyam-cli/templates/codeyam:diagnose.md +0 -803
  364. package/codeyam-cli/templates/codeyam:memory.md +0 -341
@@ -14,23 +14,112 @@ const isStandaloneIndex = (s?: string) => !!s && STANDALONE_INDEX_RE.test(s);
14
14
  // The regex matches any path ending with .length that has [] somewhere before it
15
15
  const DYNAMIC_LENGTH_RE = /\[\].*\.length$/;
16
16
 
17
+ // Cache for type string analysis to avoid repeated split/filter operations.
18
+ // These functions are called multiple times per path segment across thousands of paths.
19
+ const typeAnalysisCache = new Map<
20
+ string,
21
+ { isSkippable: boolean; baseType: string; isNullable: boolean }
22
+ >();
23
+
24
+ function getTypeAnalysis(t: string) {
25
+ const cached = typeAnalysisCache.get(t);
26
+ if (cached) return cached;
27
+ const parts = t.split('|').map((s) => s.trim());
28
+ const base = parts.filter((s) => s !== 'undefined' && s !== 'null');
29
+ const result = {
30
+ isSkippable:
31
+ base.length === 1 &&
32
+ (base[0] === 'object' ||
33
+ base[0] === 'array' ||
34
+ base[0] === 'function' ||
35
+ base[0] === 'unknown'),
36
+ baseType: base[0],
37
+ isNullable: parts.includes('undefined') || parts.includes('null'),
38
+ };
39
+ typeAnalysisCache.set(t, result);
40
+ return result;
41
+ }
42
+
17
43
  // Treat these as structural placeholders (don't commit them as concrete leaves)
18
44
  function isSkippableLeafType(t: string) {
19
- // 'unknown' by itself is a placeholder (but 'boolean | unknown' is not)
20
- return (
21
- t === 'object' ||
22
- t === 'array' ||
23
- t === 'function' ||
24
- t.trim() === 'unknown'
25
- );
45
+ return getTypeAnalysis(t).isSkippable;
46
+ }
47
+
48
+ // Extract the base structural type from a potentially nullable type string.
49
+ // e.g., 'object | undefined' → 'object', 'array | null' → 'array'
50
+ function getBaseSkippableType(t: string): string {
51
+ return getTypeAnalysis(t).baseType;
52
+ }
53
+
54
+ // Check if a type string has nullable annotations (| undefined or | null)
55
+ function isNullableType(t: string): boolean {
56
+ return getTypeAnalysis(t).isNullable;
57
+ }
58
+
59
+ // Matches paths containing [][] — e.g., "items[][]" or "items[][].text"
60
+ const DOUBLE_ARRAY_RE = /\[\]\[\]/;
61
+
62
+ // Matches a [].property segment — e.g., "items[].name" (but not "items[][]")
63
+ const ARRAY_OBJECT_PROPERTY_RE = /\[\]\.[^[\]]/;
64
+
65
+ /**
66
+ * When scope analysis produces both `prefix[].property` (array of objects) and
67
+ * `prefix[][]` (array of arrays) for the same prefix, there's a conflict about
68
+ * what the array elements are. Object-property paths are more specific and come
69
+ * from actual property access; double-array paths come from mixed iteration
70
+ * patterns in the scope analysis. Drop the double-array paths when both exist.
71
+ */
72
+ function resolveDoubleArrayConflicts(
73
+ schema: Record<string, string>,
74
+ ): Record<string, string> {
75
+ // Collect prefixes that end in [] and have object property children
76
+ const objectArrayPrefixes = new Set<string>();
77
+ for (const path of Object.keys(schema)) {
78
+ if (!ARRAY_OBJECT_PROPERTY_RE.test(path)) continue;
79
+ // Extract every "...[]" prefix that is followed by ".prop"
80
+ let idx = 0;
81
+ while ((idx = path.indexOf('[].', idx)) !== -1) {
82
+ objectArrayPrefixes.add(path.slice(0, idx + 2)); // includes the "[]"
83
+ idx += 3;
84
+ }
85
+ }
86
+
87
+ if (objectArrayPrefixes.size === 0) return schema;
88
+
89
+ // Check if any double-array paths actually conflict
90
+ let hasConflict = false;
91
+ for (const path of Object.keys(schema)) {
92
+ if (!DOUBLE_ARRAY_RE.test(path)) continue;
93
+ const idx = path.indexOf('[][]');
94
+ if (idx !== -1 && objectArrayPrefixes.has(path.slice(0, idx + 2))) {
95
+ hasConflict = true;
96
+ break;
97
+ }
98
+ }
99
+
100
+ if (!hasConflict) return schema;
101
+
102
+ // Filter out conflicting double-array paths
103
+ const resolved: Record<string, string> = {};
104
+ for (const [path, value] of Object.entries(schema)) {
105
+ if (DOUBLE_ARRAY_RE.test(path)) {
106
+ const idx = path.indexOf('[][]');
107
+ if (idx !== -1 && objectArrayPrefixes.has(path.slice(0, idx + 2))) {
108
+ continue; // drop this conflicting path
109
+ }
110
+ }
111
+ resolved[path] = value;
112
+ }
113
+ return resolved;
26
114
  }
27
115
 
28
116
  export default function convertDotNotation(
29
117
  schema: Record<string, string>,
30
118
  ): JsonTypeDefinition {
119
+ const resolved = resolveDoubleArrayConflicts(schema);
31
120
  const result: JsonTypeDefinition = {};
32
121
 
33
- for (const [rawPath, typ] of Object.entries(schema)) {
122
+ for (const [rawPath, typ] of Object.entries(resolved)) {
34
123
  // Skip paths with .length after array notation from dynamic iteration
35
124
  // e.g., metadata[].length, metadata[][].length
36
125
  if (DYNAMIC_LENGTH_RE.test(rawPath)) continue;
@@ -218,6 +307,17 @@ export default function convertDotNotation(
218
307
  // If the next segment after '[]' is another '[]' or a standalone index,
219
308
  // we need an array at cursor[key][0], not an object (for patterns like "key[][]" or "key[][0]")
220
309
  if (afterArray === '[]' || isStandaloneIndex(afterArray)) {
310
+ // But don't overwrite an existing populated object — object properties
311
+ // (from paths like key[].property) take precedence over double-array hints
312
+ // (from paths like key[][]) which come from mixed access patterns in scope analysis
313
+ if (
314
+ cursor[key][0] &&
315
+ typeof cursor[key][0] === 'object' &&
316
+ !Array.isArray(cursor[key][0]) &&
317
+ Object.keys(cursor[key][0]).length > 0
318
+ ) {
319
+ break;
320
+ }
221
321
  if (!Array.isArray(cursor[key][0])) cursor[key][0] = [];
222
322
  } else {
223
323
  // Default case: create an object
@@ -242,15 +342,41 @@ export default function convertDotNotation(
242
342
  cursor[key] = typ;
243
343
  } else {
244
344
  // Structural/placeholder terminal
245
- if (typ === 'array') {
345
+ const nullable = isNullableType(typ);
346
+ const baseType = getBaseSkippableType(typ);
347
+
348
+ if (baseType === 'array') {
246
349
  if (!Array.isArray(cursor[key])) cursor[key] = [];
350
+ if (nullable) {
351
+ (cursor[key] as any)._nullable = true;
352
+ }
247
353
  } else if (
248
- typ === 'object' ||
249
- typ === 'function' ||
250
- typ.trim() === 'unknown'
354
+ baseType === 'object' ||
355
+ baseType === 'function' ||
356
+ baseType === 'unknown'
251
357
  ) {
252
- if (cursor[key] === undefined) {
253
- cursor[key] = typ;
358
+ if (nullable) {
359
+ // Nullable object: ensure it's an actual object (not a string
360
+ // placeholder) so _nullable can be set and child paths can
361
+ // populate properties on it.
362
+ if (
363
+ cursor[key] === undefined ||
364
+ typeof cursor[key] === 'string'
365
+ ) {
366
+ cursor[key] = {};
367
+ }
368
+ if (
369
+ typeof cursor[key] === 'object' &&
370
+ cursor[key] !== null &&
371
+ !Array.isArray(cursor[key])
372
+ ) {
373
+ (cursor[key] as any)._nullable = true;
374
+ }
375
+ } else {
376
+ // Non-nullable: preserve existing behavior (string placeholder)
377
+ if (cursor[key] === undefined) {
378
+ cursor[key] = typ;
379
+ }
254
380
  }
255
381
  }
256
382
  }
@@ -81,7 +81,23 @@ function isTypeAnnotation(value: string): boolean {
81
81
  'string | number | undefined',
82
82
  ];
83
83
 
84
- return commonTypePatterns.includes(trimmed);
84
+ if (commonTypePatterns.includes(trimmed)) return true;
85
+
86
+ // Check for arrow function type annotations like "() => void", "(event: MouseEvent) => void"
87
+ // These contain '=>' but the body is a type keyword, not a JS expression
88
+ if (trimmed.includes('=>')) {
89
+ const arrowIndex = trimmed.indexOf('=>');
90
+ const body = trimmed.slice(arrowIndex + 2).trim();
91
+ if (
92
+ /^(void|string|number|boolean|any|unknown|never|null|undefined|object|Date|Promise<\w+>)$/i.test(
93
+ body,
94
+ )
95
+ ) {
96
+ return true;
97
+ }
98
+ }
99
+
100
+ return false;
85
101
  }
86
102
 
87
103
  /**
@@ -105,6 +121,9 @@ function typeAnnotationToValue(typeAnnotation: string): unknown {
105
121
  return [];
106
122
  }
107
123
 
124
+ // Handle arrow function type annotations like "() => void"
125
+ if (trimmed.includes('=>')) return () => {};
126
+
108
127
  // Handle primitive types
109
128
  if (trimmed === 'string') return '';
110
129
  if (trimmed === 'number') return 0;
@@ -152,8 +152,11 @@ export default function fillInSchemaGapsAndUnknowns(
152
152
  schema[previousSubPath],
153
153
  )
154
154
  ) {
155
- const newValue =
156
- checkIfKnownType(previousSubPath, functionKeysMapping) ?? 'object';
155
+ // When fillInUnknowns=false, add missing gaps as 'unknown' to preserve raw schema.
156
+ // When fillInUnknowns=true, infer the type using checkIfKnownType.
157
+ const newValue = fillInUnknowns
158
+ ? (checkIfKnownType(previousSubPath, functionKeysMapping) ?? 'object')
159
+ : 'unknown';
157
160
 
158
161
  if (
159
162
  !schema[previousSubPath] ||
@@ -166,10 +169,14 @@ export default function fillInSchemaGapsAndUnknowns(
166
169
 
167
170
  // Handle the wrong function chaining function().function()
168
171
  if (isFunction && !existingSchema(previousSubPath)) {
172
+ // When fillInUnknowns=false, use 'unknown' for non-function paths.
173
+ // When fillInUnknowns=true, infer the type.
169
174
  schema[previousSubPath] = previousSubPath.endsWith(')')
170
175
  ? 'function'
171
- : (checkIfKnownType(previousSubPath, functionKeysMapping) ??
172
- 'object');
176
+ : fillInUnknowns
177
+ ? (checkIfKnownType(previousSubPath, functionKeysMapping) ??
178
+ 'object')
179
+ : 'unknown';
173
180
  changeMade = true;
174
181
  }
175
182
 
@@ -458,7 +465,10 @@ export function fillInDirectSchemaGapsAndUnknowns({
458
465
  }
459
466
  } else if (schema[key] === 'unknown') {
460
467
  const newType = guessTypeForPath(key, 'string');
461
- if (newType && schema[key] !== newType) {
468
+ // Don't convert 'unknown' to 'object' — 'object' is just inferred from
469
+ // having child properties, which isn't more useful than 'unknown' and
470
+ // prevents enrichment from filling in the actual type later.
471
+ if (newType && newType !== 'object' && schema[key] !== newType) {
462
472
  schema[key] = newType;
463
473
  changeMade = true;
464
474
  }
@@ -481,12 +491,44 @@ export function fillInDirectSchemaGapsAndUnknowns({
481
491
  // This handles spurious [] paths from components like JsonNode that handle
482
492
  // both arrays and objects. When metadata is explicitly typed as 'object',
483
493
  // paths like metadata[] (from dynamic iteration) should not change it.
494
+ const existingType = schema[previousSubPath];
495
+ const baseType = existingType?.split(' | ')[0];
496
+
497
+ // Also check if this path has meaningful object property children (non-[] children).
498
+ // If it does, it's an object with mixed access patterns (e.g., agent.entries
499
+ // AND agent[].type), not a pure array. Don't infer 'array' in that case.
500
+ // Exclude .length since it exists on arrays too and is NOT evidence of object-ness.
501
+ let hasObjectPropertyChildren = false;
502
+ if (baseType !== 'array' && baseType !== 'object') {
503
+ const dotPrefix = previousSubPath + '.';
504
+ const lengthPath = previousSubPath + '.length';
505
+ for (const schemaKey in schema) {
506
+ if (
507
+ schemaKey.startsWith(dotPrefix) &&
508
+ schemaKey !== lengthPath
509
+ ) {
510
+ hasObjectPropertyChildren = true;
511
+ break;
512
+ }
513
+ }
514
+ }
515
+
484
516
  if (
485
- schema[previousSubPath] !== 'array' &&
486
- schema[previousSubPath] !== 'object'
517
+ baseType !== 'array' &&
518
+ baseType !== 'object' &&
519
+ !hasObjectPropertyChildren
487
520
  ) {
488
- schema[previousSubPath] = 'array';
489
- changeMade = true;
521
+ // Preserve nullability from existing type (e.g., 'unknown | undefined' -> 'array | undefined')
522
+ let newType = 'array';
523
+ if (existingType?.includes(' | undefined')) {
524
+ newType = 'array | undefined';
525
+ } else if (existingType?.includes(' | null')) {
526
+ newType = 'array | null';
527
+ }
528
+ if (schema[previousSubPath] !== newType) {
529
+ schema[previousSubPath] = newType;
530
+ changeMade = true;
531
+ }
490
532
  }
491
533
  }
492
534
  }
@@ -502,14 +544,36 @@ export function fillInDirectSchemaGapsAndUnknowns({
502
544
  schema[previousSubPath],
503
545
  )
504
546
  ) {
505
- const newValue = getKnownType(previousSubPath) ?? 'object';
506
-
547
+ const existingType = schema[previousSubPath];
548
+ const baseExistingType = existingType?.split(' | ')[0];
549
+ // Skip if the base type is already a structured type
507
550
  if (
508
- !schema[previousSubPath] ||
509
- schema[previousSubPath] !== newValue
551
+ !['object', 'array', 'function', 'async-function'].includes(
552
+ baseExistingType,
553
+ )
510
554
  ) {
511
- schema[previousSubPath] = newValue;
512
- changeMade = true;
555
+ let newValue = getKnownType(previousSubPath) ?? 'object';
556
+ // Don't overwrite 'unknown' with 'object' — 'object' is just
557
+ // inferred from child properties and isn't more useful than 'unknown'
558
+ if (
559
+ newValue === 'object' &&
560
+ existingType &&
561
+ existingType.split(' | ')[0] === 'unknown'
562
+ ) {
563
+ // preserve existing 'unknown' (possibly with nullability)
564
+ } else {
565
+ // Preserve nullability from existing type
566
+ if (existingType?.includes(' | undefined')) {
567
+ newValue = `${newValue} | undefined`;
568
+ } else if (existingType?.includes(' | null')) {
569
+ newValue = `${newValue} | null`;
570
+ }
571
+
572
+ if (!existingType || existingType !== newValue) {
573
+ schema[previousSubPath] = newValue;
574
+ changeMade = true;
575
+ }
576
+ }
513
577
  }
514
578
  }
515
579
 
@@ -778,10 +842,11 @@ function checkIfKnownType(
778
842
  return 'array';
779
843
  }
780
844
 
781
- // When .includes() or .indexOf() is called with a variable argument AND we have .length,
782
- // prefer array. This pattern (arr.length > 0 && arr.includes(item)) is common for arrays.
783
- // But str.includes('literal') is common for strings - that case is handled by hasStringLiteralArgument.
784
- if (isArray && hasLengthAccess && hasIncludesOrIndexOfWithVariable) {
845
+ // When .includes() or .indexOf() is called with a variable argument, prefer array.
846
+ // Pattern: arr.includes(item) -> likely array (checking if item exists in collection)
847
+ // String literals are already filtered by hasStringLiteralArgument, so if we get here
848
+ // with a variable argument, it's strong evidence of array membership testing.
849
+ if (isArray && hasIncludesOrIndexOfWithVariable) {
785
850
  return 'array';
786
851
  }
787
852
 
@@ -3,9 +3,11 @@ import type { ExecutionFlow, ScenariosDataStructure } from '~codeyam/types';
3
3
  // Type for a single required value from ExecutionFlow
4
4
  type RequiredValue = NonNullable<ExecutionFlow['requiredValues']>[number];
5
5
 
6
- const DEFAULT_MAX_KEYS_PER_CHUNK = 8;
6
+ const DEFAULT_MAX_CHUNK_SIZE = 10_000; // ~10K chars per chunk
7
7
 
8
8
  export interface ChunkOptions {
9
+ maxChunkSize?: number;
10
+ /** @deprecated Use maxChunkSize instead. Kept for backward compatibility in tests. */
9
11
  maxKeysPerChunk?: number;
10
12
  }
11
13
 
@@ -15,8 +17,12 @@ export interface ChunkOptions {
15
17
  * Large schemas overwhelm LLMs, causing them to make mistakes on some keys.
16
18
  * By processing smaller chunks, each key gets more focused attention.
17
19
  *
20
+ * Uses cumulative JSON size to decide chunk boundaries rather than a fixed
21
+ * key count, so a single oversized key gets its own chunk while many small
22
+ * keys are grouped together efficiently.
23
+ *
18
24
  * @param dataForMocks - The full data structure schema
19
- * @param options - Chunking options (maxKeysPerChunk defaults to 8)
25
+ * @param options - Chunking options (maxChunkSize defaults to 10_000)
20
26
  * @returns Array of smaller data structure chunks
21
27
  */
22
28
  export function chunkDataStructure(
@@ -27,27 +33,39 @@ export function chunkDataStructure(
27
33
  return [dataForMocks];
28
34
  }
29
35
 
30
- const { maxKeysPerChunk = DEFAULT_MAX_KEYS_PER_CHUNK } = options;
36
+ const { maxChunkSize = DEFAULT_MAX_CHUNK_SIZE } = options;
31
37
  const keys = Object.keys(dataForMocks);
32
38
 
33
- // Don't chunk if already small enough
34
- if (keys.length <= maxKeysPerChunk) {
39
+ // Calculate total size to see if chunking is needed
40
+ const totalSize = JSON.stringify(dataForMocks).length;
41
+ if (totalSize <= maxChunkSize) {
35
42
  return [dataForMocks];
36
43
  }
37
44
 
45
+ // Greedily pack keys into chunks by cumulative size
38
46
  const chunks: Array<ScenariosDataStructure['dataForMocks']> = [];
39
-
40
- for (let i = 0; i < keys.length; i += maxKeysPerChunk) {
41
- const chunkKeys = keys.slice(i, i + maxKeysPerChunk);
42
- const chunk: ScenariosDataStructure['dataForMocks'] = {};
43
-
44
- for (const key of chunkKeys) {
45
- (chunk as Record<string, unknown>)[key] = (
46
- dataForMocks as Record<string, unknown>
47
- )[key];
47
+ let currentChunk: Record<string, unknown> = {};
48
+ let currentSize = 0;
49
+
50
+ for (const key of keys) {
51
+ const keySize = JSON.stringify(
52
+ (dataForMocks as Record<string, unknown>)[key],
53
+ ).length;
54
+
55
+ // If adding this key would exceed the limit AND chunk isn't empty, start a new chunk
56
+ if (currentSize > 0 && currentSize + keySize > maxChunkSize) {
57
+ chunks.push(currentChunk as ScenariosDataStructure['dataForMocks']);
58
+ currentChunk = {};
59
+ currentSize = 0;
48
60
  }
49
61
 
50
- chunks.push(chunk);
62
+ currentChunk[key] = (dataForMocks as Record<string, unknown>)[key];
63
+ currentSize += keySize;
64
+ }
65
+
66
+ // Push the last chunk
67
+ if (Object.keys(currentChunk).length > 0) {
68
+ chunks.push(currentChunk as ScenariosDataStructure['dataForMocks']);
51
69
  }
52
70
 
53
71
  return chunks;
@@ -1,9 +1,12 @@
1
1
  import { Entity } from '~codeyam/types';
2
2
  import isolateScopes from './isolateScopes';
3
3
  import analyzeScope from './analyzeScope';
4
- import { FileAnalyzer } from '~codeyam/analyze';
4
+ import { FileAnalyzer, transformationTracer } from '~codeyam/analyze';
5
5
  import { AI, SerializableDataStructure } from '~codeyam/ai';
6
- import { resetScopeDataStructureMetrics } from './dataStructure/ScopeDataStructure';
6
+ import {
7
+ resetScopeDataStructureMetrics,
8
+ ScopeDataStructure,
9
+ } from './dataStructure/ScopeDataStructure';
7
10
 
8
11
  // import { awsLog } from '~codeyam/utils';
9
12
 
@@ -91,8 +94,60 @@ export default async function generateEntityDataStructure({
91
94
  }
92
95
 
93
96
  // Inspect the runtime type of dataStructure to see if it must be serialized
97
+ // Note: When worker threads are used, dataStructure is already serialized (no toSerializable).
98
+ // Workers are disabled when CODEYAM_TRACE_TRANSFORMS=1 to enable full tracing.
94
99
  if ('toSerializable' in entityScope.dataStructure) {
95
- return entityScope.dataStructure.toSerializable();
100
+ const scopeDataStructure =
101
+ entityScope.dataStructure as unknown as ScopeDataStructure;
102
+
103
+ // Trace the internal state BEFORE serialization - captures what methods return
104
+ if (transformationTracer.isEnabled()) {
105
+ transformationTracer.startEntity({
106
+ name: entity.name,
107
+ entityType: entity.entityType ?? 'unknown',
108
+ filePath: entity.filePath,
109
+ });
110
+
111
+ // Capture internal state - this is what getReturnValue/getFunctionSignature return
112
+ transformationTracer.snapshot(entity.name, 'scopeDataStructure', {
113
+ signatureSchema: scopeDataStructure.getFunctionSignature({
114
+ fillInUnknowns: true,
115
+ }),
116
+ returnValueSchema: scopeDataStructure.getReturnValue({
117
+ fillInUnknowns: true,
118
+ }),
119
+ });
120
+ }
121
+
122
+ const serialized = scopeDataStructure.toSerializable();
123
+
124
+ // Trace AFTER serialization - shows what gets output
125
+ if (transformationTracer.isEnabled()) {
126
+ // Build schema from external function calls for comparison
127
+ const externalSchemas: Record<string, string> = {};
128
+ for (const efc of serialized.externalFunctionCalls ?? []) {
129
+ for (const [path, type] of Object.entries(efc.schema ?? {})) {
130
+ externalSchemas[path] = type;
131
+ }
132
+ }
133
+
134
+ transformationTracer.snapshot(entity.name, 'serialized', {
135
+ signatureSchema:
136
+ serialized.functionResults?.[entity.name]?.signatureWithUnknowns,
137
+ returnValueSchema:
138
+ serialized.functionResults?.[entity.name]?.returnValueWithUnknowns,
139
+ // Include external function schemas to detect serialization gaps
140
+ dependencySchemas: {
141
+ externalFunctions: {
142
+ combined: {
143
+ returnValueSchema: externalSchemas,
144
+ },
145
+ },
146
+ },
147
+ });
148
+ }
149
+
150
+ return serialized;
96
151
  }
97
152
  return entityScope.dataStructure;
98
153
  }