@codeyam/codeyam-cli 0.1.0-staging.483fdc2 → 0.1.0-staging.62d4615

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (213) 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 +3 -3
  4. package/analyzer-template/packages/ai/package.json +2 -2
  5. package/analyzer-template/packages/ai/src/lib/analyzeScope.ts +9 -1
  6. package/analyzer-template/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.ts +10 -17
  7. package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +154 -1
  8. package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.ts +5 -1
  9. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.ts +11 -2
  10. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.ts +2 -2
  11. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.ts +70 -0
  12. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.ts +70 -1
  13. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.ts +20 -1
  14. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.ts +84 -19
  15. package/analyzer-template/packages/ai/src/lib/generateEntityDataStructure.ts +58 -3
  16. package/analyzer-template/packages/ai/src/lib/generateEntityScenarioData.ts +14 -0
  17. package/analyzer-template/packages/ai/src/lib/isolateScopes.ts +51 -3
  18. package/analyzer-template/packages/analyze/index.ts +2 -0
  19. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +51 -3
  20. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +5 -0
  21. package/analyzer-template/packages/analyze/src/lib/files/scenarios/TransformationTracer.ts +1315 -0
  22. package/analyzer-template/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.ts +4 -0
  23. package/analyzer-template/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.ts +9 -1
  24. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +194 -15
  25. package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +260 -22
  26. package/analyzer-template/packages/analyze/src/lib/index.ts +1 -0
  27. package/analyzer-template/packages/database/package.json +1 -1
  28. package/analyzer-template/packages/github/dist/types/src/types/ProjectMetadata.d.ts +3 -0
  29. package/analyzer-template/packages/github/dist/types/src/types/ProjectMetadata.d.ts.map +1 -1
  30. package/analyzer-template/packages/types/src/types/ProjectMetadata.ts +1 -0
  31. package/analyzer-template/packages/utils/dist/types/src/types/ProjectMetadata.d.ts +3 -0
  32. package/analyzer-template/packages/utils/dist/types/src/types/ProjectMetadata.d.ts.map +1 -1
  33. package/analyzer-template/project/constructMockCode.ts +36 -1
  34. package/analyzer-template/project/writeMockDataTsx.ts +111 -17
  35. package/analyzer-template/project/writeScenarioComponents.ts +60 -12
  36. package/analyzer-template/project/writeSimpleRoot.ts +21 -11
  37. package/background/src/lib/virtualized/project/constructMockCode.js +30 -1
  38. package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
  39. package/background/src/lib/virtualized/project/writeMockDataTsx.js +95 -13
  40. package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
  41. package/background/src/lib/virtualized/project/writeScenarioComponents.js +60 -15
  42. package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
  43. package/background/src/lib/virtualized/project/writeSimpleRoot.js +21 -11
  44. package/background/src/lib/virtualized/project/writeSimpleRoot.js.map +1 -1
  45. package/codeyam-cli/scripts/apply-setup.js +43 -9
  46. package/codeyam-cli/scripts/apply-setup.js.map +1 -1
  47. package/codeyam-cli/src/commands/memory.js +12 -21
  48. package/codeyam-cli/src/commands/memory.js.map +1 -1
  49. package/codeyam-cli/src/utils/backgroundServer.js +4 -0
  50. package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
  51. package/codeyam-cli/src/utils/install-skills.js +23 -0
  52. package/codeyam-cli/src/utils/install-skills.js.map +1 -1
  53. package/codeyam-cli/src/utils/queue/job.js +4 -0
  54. package/codeyam-cli/src/utils/queue/job.js.map +1 -1
  55. package/codeyam-cli/src/utils/ruleReflection/__tests__/confusionDetector.test.js +82 -0
  56. package/codeyam-cli/src/utils/ruleReflection/__tests__/confusionDetector.test.js.map +1 -0
  57. package/codeyam-cli/src/utils/ruleReflection/__tests__/contextBuilder.test.js +128 -0
  58. package/codeyam-cli/src/utils/ruleReflection/__tests__/contextBuilder.test.js.map +1 -0
  59. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/assertRules.js +67 -0
  60. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/assertRules.js.map +1 -0
  61. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/captureFixture.js +105 -0
  62. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/captureFixture.js.map +1 -0
  63. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/loadCapturedFixture.js +34 -0
  64. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/loadCapturedFixture.js.map +1 -0
  65. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/runClaude.js +162 -0
  66. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/runClaude.js.map +1 -0
  67. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js +75 -0
  68. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js.map +1 -0
  69. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js +285 -0
  70. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js.map +1 -0
  71. package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js +83 -0
  72. package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js.map +1 -0
  73. package/codeyam-cli/src/utils/ruleReflection/__tests__/transcriptParser.test.js +127 -0
  74. package/codeyam-cli/src/utils/ruleReflection/__tests__/transcriptParser.test.js.map +1 -0
  75. package/codeyam-cli/src/utils/ruleReflection/confusionDetector.js +50 -0
  76. package/codeyam-cli/src/utils/ruleReflection/confusionDetector.js.map +1 -0
  77. package/codeyam-cli/src/utils/ruleReflection/contextBuilder.js +96 -0
  78. package/codeyam-cli/src/utils/ruleReflection/contextBuilder.js.map +1 -0
  79. package/codeyam-cli/src/utils/ruleReflection/index.js +5 -0
  80. package/codeyam-cli/src/utils/ruleReflection/index.js.map +1 -0
  81. package/codeyam-cli/src/utils/ruleReflection/promptBuilder.js +33 -0
  82. package/codeyam-cli/src/utils/ruleReflection/promptBuilder.js.map +1 -0
  83. package/codeyam-cli/src/utils/ruleReflection/transcriptParser.js +85 -0
  84. package/codeyam-cli/src/utils/ruleReflection/transcriptParser.js.map +1 -0
  85. package/codeyam-cli/src/utils/ruleReflection/types.js +5 -0
  86. package/codeyam-cli/src/utils/ruleReflection/types.js.map +1 -0
  87. package/codeyam-cli/src/utils/rules/__tests__/ruleState.test.js +293 -0
  88. package/codeyam-cli/src/utils/rules/__tests__/ruleState.test.js.map +1 -0
  89. package/codeyam-cli/src/utils/rules/index.js +1 -0
  90. package/codeyam-cli/src/utils/rules/index.js.map +1 -1
  91. package/codeyam-cli/src/utils/rules/parser.js +0 -28
  92. package/codeyam-cli/src/utils/rules/parser.js.map +1 -1
  93. package/codeyam-cli/src/utils/rules/ruleState.js +150 -0
  94. package/codeyam-cli/src/utils/rules/ruleState.js.map +1 -0
  95. package/codeyam-cli/src/utils/rules/staleness.js +14 -9
  96. package/codeyam-cli/src/utils/rules/staleness.js.map +1 -1
  97. package/codeyam-cli/src/webserver/app/lib/database.js +1 -0
  98. package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
  99. package/codeyam-cli/src/webserver/build/client/assets/CopyButton-CA3JxPb7.js +1 -0
  100. package/codeyam-cli/src/webserver/build/client/assets/{EntityItem-DsN1wKrm.js → EntityItem-B86KKU7e.js} +1 -1
  101. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeBadge-DLqD3qNt.js → EntityTypeBadge-B5ctlSYt.js} +1 -1
  102. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeIcon-Ba2JVPzP.js → EntityTypeIcon-BqY8gDAW.js} +1 -1
  103. package/codeyam-cli/src/webserver/build/client/assets/{InlineSpinner-C8lyxW9k.js → InlineSpinner-ClaLpuOo.js} +1 -1
  104. package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-aht4aafF.js → InteractivePreview-BDhPilK7.js} +2 -2
  105. package/codeyam-cli/src/webserver/build/client/assets/{LibraryFunctionPreview-CVtiBnY5.js → LibraryFunctionPreview-VeqEBv9v.js} +1 -1
  106. package/codeyam-cli/src/webserver/build/client/assets/{LoadingDots-B0GLXMsr.js → LoadingDots-Bs7Nn1Jr.js} +1 -1
  107. package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-xgeCVgSM.js → LogViewer-Bm3PmcCz.js} +1 -1
  108. package/codeyam-cli/src/webserver/build/client/assets/{ReportIssueModal-OApQuNyq.js → ReportIssueModal-C6PKeMYR.js} +3 -8
  109. package/codeyam-cli/src/webserver/build/client/assets/{SafeScreenshot-DuDvi0jm.js → SafeScreenshot-Gq3Ocjo6.js} +1 -1
  110. package/codeyam-cli/src/webserver/build/client/assets/{ScenarioViewer-DzccYyI8.js → ScenarioViewer-BNLaXBHR.js} +2 -2
  111. package/codeyam-cli/src/webserver/build/client/assets/{TruncatedFilePath-DyFZkK0l.js → TruncatedFilePath-CiwXDxLh.js} +1 -1
  112. package/codeyam-cli/src/webserver/build/client/assets/{_index-BwqWJOgH.js → _index-B3TDXxnk.js} +1 -1
  113. package/codeyam-cli/src/webserver/build/client/assets/{activity.(_tab)-BwavGCpm.js → activity.(_tab)-DD1r_QU0.js} +6 -11
  114. package/codeyam-cli/src/webserver/build/client/assets/agent-transcripts-DfKzxuoe.js +11 -0
  115. package/codeyam-cli/src/webserver/build/client/assets/api.agent-transcripts-l0sNRNKZ.js +1 -0
  116. package/codeyam-cli/src/webserver/build/client/assets/api.save-fixture-l0sNRNKZ.js +1 -0
  117. package/codeyam-cli/src/webserver/build/client/assets/book-open-PttOB2SF.js +6 -0
  118. package/codeyam-cli/src/webserver/build/client/assets/{chevron-down-Cx24_aWc.js → chevron-down-TJp6ofnp.js} +1 -1
  119. package/codeyam-cli/src/webserver/build/client/assets/{chunk-EPOLDU6W-CXRTFQ3F.js → chunk-JZWAC4HX-JE9ZIoBl.js} +12 -12
  120. package/codeyam-cli/src/webserver/build/client/assets/{circle-check-BOARzkeR.js → circle-check-CXhHQYrI.js} +1 -1
  121. package/codeyam-cli/src/webserver/build/client/assets/copy-6y9ALfGT.js +11 -0
  122. package/codeyam-cli/src/webserver/build/client/assets/{createLucideIcon-BdhJEx6B.js → createLucideIcon-Ca9fAY46.js} +1 -1
  123. package/codeyam-cli/src/webserver/build/client/assets/{dev.empty-BBnGWYga.js → dev.empty-C5lqplTC.js} +1 -1
  124. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-BJUiQqZF.js → entity._sha._-n38keI1k.js} +10 -10
  125. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.fullscreen-DavjRmOY.js → entity._sha.scenarios._scenarioId.fullscreen-CBoafmVs.js} +1 -1
  126. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.create-scenario-D1T4TGjf.js → entity._sha_.create-scenario-DGgZjdFg.js} +1 -1
  127. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.edit._scenarioId-CTBG2mmz.js → entity._sha_.edit._scenarioId-38yPijoD.js} +1 -1
  128. package/codeyam-cli/src/webserver/build/client/assets/{entry.client-CS2cb_eZ.js → entry.client-BSHEfydn.js} +1 -1
  129. package/codeyam-cli/src/webserver/build/client/assets/{fileTableUtils-DMJ7zii9.js → fileTableUtils-DCPhhSMo.js} +1 -1
  130. package/codeyam-cli/src/webserver/build/client/assets/{files-CJ6lTdTA.js → files-Dk8wkAS7.js} +1 -1
  131. package/codeyam-cli/src/webserver/build/client/assets/{git-CPTZZ-JZ.js → git-DXnyr8uP.js} +1 -1
  132. package/codeyam-cli/src/webserver/build/client/assets/globals-Bh6jH0cL.css +1 -0
  133. package/codeyam-cli/src/webserver/build/client/assets/{index-lzqtyFU8.js → index-CcsFv748.js} +1 -1
  134. package/codeyam-cli/src/webserver/build/client/assets/{index-B1h680n5.js → index-ChN9-fAY.js} +1 -1
  135. package/codeyam-cli/src/webserver/build/client/assets/labs-BUvfJMNR.js +1 -0
  136. package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-B7B9V-bu.js → loader-circle-CTqLEAGU.js} +1 -1
  137. package/codeyam-cli/src/webserver/build/client/assets/manifest-d4e77269.js +1 -0
  138. package/codeyam-cli/src/webserver/build/client/assets/memory-DCHBwHou.js +76 -0
  139. package/codeyam-cli/src/webserver/build/client/assets/pause-D6vreykR.js +11 -0
  140. package/codeyam-cli/src/webserver/build/client/assets/root-D6oziHts.js +62 -0
  141. package/codeyam-cli/src/webserver/build/client/assets/{search-CxXUmBSd.js → search-B8VUL8nl.js} +1 -1
  142. package/codeyam-cli/src/webserver/build/client/assets/{settings-CS5f3WzT.js → settings-B2X7lJgQ.js} +1 -1
  143. package/codeyam-cli/src/webserver/build/client/assets/{simulations-DwFIBT09.js → simulations-CPoAg7Zo.js} +1 -1
  144. package/codeyam-cli/src/webserver/build/client/assets/terminal-BrCP7uQo.js +11 -0
  145. package/codeyam-cli/src/webserver/build/client/assets/{triangle-alert-B6LgvRJg.js → triangle-alert-BZz2NjYa.js} +1 -1
  146. package/codeyam-cli/src/webserver/build/client/assets/{useCustomSizes-C1v1PQzo.js → useCustomSizes-DNwUduNu.js} +1 -1
  147. package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-aSv48UbS.js → useLastLogLine-COky1GVF.js} +1 -1
  148. package/codeyam-cli/src/webserver/build/client/assets/{useReportContext-DYxHZQuP.js → useReportContext-CpZgwliL.js} +1 -1
  149. package/codeyam-cli/src/webserver/build/client/assets/{useToast-mBRpZPiu.js → useToast-Bv9JFvUO.js} +1 -1
  150. package/codeyam-cli/src/webserver/build/server/assets/{index-TD1f-DHV.js → index-C0KrUQp-.js} +1 -1
  151. package/codeyam-cli/src/webserver/build/server/assets/server-build-C2h1v1XD.js +260 -0
  152. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  153. package/codeyam-cli/src/webserver/build-info.json +5 -5
  154. package/codeyam-cli/templates/codeyam-memory-hook.sh +9 -10
  155. package/codeyam-cli/templates/codeyam:memory.md +10 -9
  156. package/codeyam-cli/templates/codeyam:new-rule.md +0 -39
  157. package/codeyam-cli/templates/rule-notification-hook.py +54 -0
  158. package/codeyam-cli/templates/rule-reflection-hook.py +356 -89
  159. package/codeyam-cli/templates/rules-instructions.md +19 -22
  160. package/package.json +2 -2
  161. package/packages/ai/src/lib/analyzeScope.js +7 -1
  162. package/packages/ai/src/lib/analyzeScope.js.map +1 -1
  163. package/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.js +10 -14
  164. package/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.js.map +1 -1
  165. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +134 -1
  166. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
  167. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js +5 -1
  168. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js.map +1 -1
  169. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js +11 -2
  170. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js.map +1 -1
  171. package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js +2 -2
  172. package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js.map +1 -1
  173. package/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.js +63 -0
  174. package/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.js.map +1 -0
  175. package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js +63 -1
  176. package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js.map +1 -1
  177. package/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.js +15 -1
  178. package/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.js.map +1 -1
  179. package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js +78 -17
  180. package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js.map +1 -1
  181. package/packages/ai/src/lib/generateEntityDataStructure.js +46 -2
  182. package/packages/ai/src/lib/generateEntityDataStructure.js.map +1 -1
  183. package/packages/ai/src/lib/generateEntityScenarioData.js +10 -0
  184. package/packages/ai/src/lib/generateEntityScenarioData.js.map +1 -1
  185. package/packages/ai/src/lib/isolateScopes.js +39 -3
  186. package/packages/ai/src/lib/isolateScopes.js.map +1 -1
  187. package/packages/analyze/index.js +1 -0
  188. package/packages/analyze/index.js.map +1 -1
  189. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +41 -1
  190. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
  191. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +3 -0
  192. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
  193. package/packages/analyze/src/lib/files/scenarios/TransformationTracer.js +880 -0
  194. package/packages/analyze/src/lib/files/scenarios/TransformationTracer.js.map +1 -0
  195. package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js +5 -1
  196. package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js.map +1 -1
  197. package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js +9 -1
  198. package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js.map +1 -1
  199. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +116 -13
  200. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
  201. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +231 -22
  202. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
  203. package/packages/analyze/src/lib/index.js +1 -0
  204. package/packages/analyze/src/lib/index.js.map +1 -1
  205. package/codeyam-cli/src/utils/reviewedRules.js +0 -92
  206. package/codeyam-cli/src/utils/reviewedRules.js.map +0 -1
  207. package/codeyam-cli/src/webserver/build/client/assets/copy-Bb-80kDT.js +0 -6
  208. package/codeyam-cli/src/webserver/build/client/assets/file-code-Dhef1kWN.js +0 -6
  209. package/codeyam-cli/src/webserver/build/client/assets/globals-CX9f-5xM.css +0 -1
  210. package/codeyam-cli/src/webserver/build/client/assets/manifest-bba56ec1.js +0 -1
  211. package/codeyam-cli/src/webserver/build/client/assets/memory-DuTFSyJ2.js +0 -92
  212. package/codeyam-cli/src/webserver/build/client/assets/root-DTfSQARG.js +0 -62
  213. package/codeyam-cli/src/webserver/build/server/assets/server-build-BQ-1XyEa.js +0 -258
@@ -1,10 +1,10 @@
1
1
  {
2
- "buildTimestamp": "2026-02-04T17:33:57.768Z",
3
- "buildTime": 1770226437768,
4
- "gitCommit": "483fdc20d9d24e266e9bca6a25b473ccb58957fd",
2
+ "buildTimestamp": "2026-02-09T18:13:24.937Z",
3
+ "buildTime": 1770660804937,
4
+ "gitCommit": "62d46157debb3cc4a12427c10951e3f6e656f734",
5
5
  "nodeVersion": "v20.20.0",
6
- "contentHash": "21dbd7d480c0c50901df9ce172ec9316ac759c210f7ad6216cdfbd7d9f65446e",
7
- "buildNumber": 563,
8
- "semanticVersion": "0.1.563",
9
- "version": "0.1.563 (2026-02-04T17:33+21dbd7d)"
6
+ "contentHash": "e793537596b5586bd9f78099350b6ee878c8092b4ddc8bf4b0e5243712634ad3",
7
+ "buildNumber": 596,
8
+ "semanticVersion": "0.1.596",
9
+ "version": "0.1.596 (2026-02-09T18:13+e793537)"
10
10
  }
@@ -1,7 +1,7 @@
1
1
 
2
- [2/4/2026, 5:33:57 PM] > codeyam-combo@1.0.0 mergeDependencies
3
- [2/4/2026, 5:33:57 PM] > node ./scripts/mergePackageJsonFiles.cjs
2
+ [2/9/2026, 6:13:24 PM] > codeyam-combo@1.0.0 mergeDependencies
3
+ [2/9/2026, 6:13:24 PM] > node ./scripts/mergePackageJsonFiles.cjs
4
4
 
5
5
 
6
- [2/4/2026, 5:33:57 PM] Merged dependencies into root package.json
6
+ [2/9/2026, 6:13:24 PM] Merged dependencies into root package.json
7
7
 
@@ -30,7 +30,7 @@
30
30
  "jest": "^30.2.0",
31
31
  "jsdom": "^27.4.0",
32
32
  "jsonc-parser": "^3.2.1",
33
- "lru-cache": "^11.2.4",
33
+ "lru-cache": "^11.2.5",
34
34
  "openai": "^6.16.0",
35
35
  "p-queue": "^8.1.0",
36
36
  "p-retry": "^7.1.1",
@@ -44,11 +44,11 @@
44
44
  "pluralize": "^8.0.0",
45
45
  "yargs": "^18.0.0",
46
46
  "json5": "^2.2.3",
47
- "@anthropic-ai/sdk": "^0.71.0",
47
+ "@anthropic-ai/sdk": "^0.74.0",
48
48
  "@aws-sdk/s3-request-presigner": "^3.940.0",
49
49
  "better-sqlite3": "^12.4.1",
50
50
  "fetch-retry": "^6.0.0",
51
- "kysely": "^0.28.5",
51
+ "kysely": "^0.28.11",
52
52
  "pg": "^8.16.3",
53
53
  "@octokit/request": "^10.0.3",
54
54
  "lucide-react": "^0.556.0",
@@ -9,12 +9,12 @@
9
9
  "author": "",
10
10
  "license": "ISC",
11
11
  "dependencies": {
12
- "@anthropic-ai/sdk": "^0.71.0",
12
+ "@anthropic-ai/sdk": "^0.74.0",
13
13
  "jsdom": "^27.4.0",
14
14
  "p-queue": "^8.1.0",
15
15
  "p-retry": "^7.1.1",
16
16
  "piscina": "^5.1.4",
17
- "lru-cache": "^11.2.4"
17
+ "lru-cache": "^11.2.5"
18
18
  },
19
19
  "devDependencies": {
20
20
  "@types/jsdom": "^27.0.0"
@@ -123,10 +123,17 @@ function ensureWorkerPool() {
123
123
  // Note: WORKER_PATH is null when __mocks__/analyzeScope.ts is active
124
124
  const { WORKER_PATH } = analyzeScopeWorkerPaths();
125
125
 
126
+ // Disable workers when tracing is enabled - we need access to ScopeDataStructure
127
+ // instance in the main thread to capture pre-serialization state
128
+ const tracingEnabled =
129
+ process.env.CODEYAM_TRACE_TRANSFORMS === '1' ||
130
+ process.env.CODEYAM_TRACE_TRANSFORMS === 'true';
131
+
126
132
  if (
127
133
  process.env.USE_WORKER_THREADS &&
128
134
  WORKER_PATH &&
129
- fs.existsSync(WORKER_PATH)
135
+ fs.existsSync(WORKER_PATH) &&
136
+ !tracingEnabled
130
137
  ) {
131
138
  console.log('CodeYam: Using worker threads for analyzeScope', {
132
139
  WORKER_PATH,
@@ -159,6 +166,7 @@ function ensureWorkerPool() {
159
166
  WORKER_PATH,
160
167
  workerExists: WORKER_PATH ? fs.existsSync(WORKER_PATH) : false,
161
168
  USE_WORKER_THREADS: process.env.USE_WORKER_THREADS,
169
+ tracingEnabled,
162
170
  });
163
171
  workerPool = null; // Explicitly set to indicate "no workers"
164
172
  }
@@ -22,11 +22,8 @@ export class ForInStatementHandler implements PatternHandler {
22
22
  // Process the expression being iterated over first (e.g., object)
23
23
  context.processExpression(node.expression);
24
24
 
25
- // Get the path of the object being iterated
26
- const expressionPath = context.getStructuralPath(node.expression);
27
-
28
- // If the initializer is a variable declaration with an identifier, establish equivalence
29
- // to indicate it's iterating over the keys of the expression
25
+ // If the initializer is a variable declaration with an identifier,
26
+ // type it as 'string' since for-in keys are always strings
30
27
  if (ts.isVariableDeclarationList(node.initializer)) {
31
28
  const declarations = node.initializer.declarations;
32
29
  if (
@@ -36,25 +33,21 @@ export class ForInStatementHandler implements PatternHandler {
36
33
  ) {
37
34
  const variableName = StructuredPath.fromBase(declarations[0].name.text);
38
35
 
39
- // Add type for the key variable (string for object keys)
36
+ // Type the key variable as 'string' for-in keys are always strings.
37
+ // Note: We intentionally do NOT equivalence the key variable to
38
+ // expressionPath[*key*]. The key variable is the KEY (a string),
39
+ // while [*key*] in the schema represents the VALUE at a dynamic key.
40
+ // Creating that equivalence would cause the 'string' type to propagate
41
+ // to the value path. The value access (e.g., obj[key]) is handled
42
+ // correctly by the element access handler in processExpression.
40
43
  context.addType(variableName, 'string');
41
-
42
- if (expressionPath) {
43
- // For for...in loops, the variable is equivalent to the keys of the object
44
- // We represent this with a *key* suffix to indicate it's a key, not a value
45
- context.addEquivalence(variableName, expressionPath.withKey('key'));
46
- }
47
44
  }
48
45
  } else if (ts.isIdentifier(node.initializer)) {
49
46
  // If the initializer is directly an identifier (rare but possible)
50
47
  const variableName = StructuredPath.fromBase(node.initializer.text);
51
48
 
52
- // Add type for the key variable
49
+ // See comment above — type as string but don't equivalence to value path
53
50
  context.addType(variableName, 'string');
54
-
55
- if (expressionPath) {
56
- context.addEquivalence(variableName, expressionPath.withKey('key'));
57
- }
58
51
  } else {
59
52
  context.processExpression(node.initializer);
60
53
  }
@@ -799,6 +799,11 @@ export class ScopeDataStructure {
799
799
  return;
800
800
  }
801
801
 
802
+ // PERF: Early exit for paths with repeated function-call signature patterns
803
+ if (this.hasExcessivePatternRepetition(path)) {
804
+ return;
805
+ }
806
+
802
807
  // Update chain metadata for database tracking
803
808
  if (equivalencyValueChain.length > 0) {
804
809
  equivalencyValueChain[equivalencyValueChain.length - 1].addToSchemaId =
@@ -1486,6 +1491,15 @@ export class ScopeDataStructure {
1486
1491
 
1487
1492
  const bestValue = selectBestValue(value1, value2);
1488
1493
 
1494
+ // PERF: Skip paths with repeated function-call signature patterns
1495
+ // to prevent recursive type expansion (e.g., string.localeCompare returns string)
1496
+ if (
1497
+ this.hasExcessivePatternRepetition(schemaPath) ||
1498
+ this.hasExcessivePatternRepetition(equivalentSchemaPath)
1499
+ ) {
1500
+ continue;
1501
+ }
1502
+
1489
1503
  scopeNode.schema[schemaPath] = bestValue;
1490
1504
  equivalentScopeNode.schema[equivalentSchemaPath] = bestValue;
1491
1505
  } else if (
@@ -1499,6 +1513,11 @@ export class ScopeDataStructure {
1499
1513
  ...remainingSchemaPathParts,
1500
1514
  ]);
1501
1515
 
1516
+ // PERF: Skip paths with repeated function-call signature patterns
1517
+ if (this.hasExcessivePatternRepetition(newEquivalentPath)) {
1518
+ continue;
1519
+ }
1520
+
1502
1521
  equivalentScopeNode.schema[newEquivalentPath] =
1503
1522
  scopeNode.schema[schemaPath];
1504
1523
  }
@@ -1618,6 +1637,23 @@ export class ScopeDataStructure {
1618
1637
  }
1619
1638
  }
1620
1639
 
1640
+ // Check for repeated function calls that indicate recursive type expansion.
1641
+ // E.g., localeCompare(b[])...localeCompare(b[]) means string.localeCompare
1642
+ // returns a type that again has localeCompare, causing infinite expansion.
1643
+ // We extract all function call patterns like "funcName(args)" and check if
1644
+ // the same normalized call appears more than once.
1645
+ const funcCallPattern = /(?:^|\.)[^.([]+\([^)]*\)/g;
1646
+ const funcCallMatches = path.match(funcCallPattern);
1647
+ if (funcCallMatches && funcCallMatches.length > 1) {
1648
+ const seen = new Set<string>();
1649
+ for (const match of funcCallMatches) {
1650
+ // Strip leading dot and normalize array indices
1651
+ const normalized = match.replace(/^\./, '').replace(/\[\d+\]/g, '[]');
1652
+ if (seen.has(normalized)) return true;
1653
+ seen.add(normalized);
1654
+ }
1655
+ }
1656
+
1621
1657
  // For longer paths, detect any repeated multi-part segments we haven't explicitly listed
1622
1658
  const pathParts = this.splitPath(path);
1623
1659
  if (pathParts.length <= 6) {
@@ -2574,6 +2610,7 @@ export class ScopeDataStructure {
2574
2610
  relevantSubPathParts.every((part, i) => part === schemaPathParts[i]) &&
2575
2611
  equivalentValue.scopeNodeName === scopeNode.name
2576
2612
  ) {
2613
+ // DEBUG
2577
2614
  continue;
2578
2615
  }
2579
2616
 
@@ -3291,6 +3328,14 @@ export class ScopeDataStructure {
3291
3328
  }
3292
3329
  }
3293
3330
 
3331
+ // Ensure parameter-to-signature equivalencies are fully propagated.
3332
+ // When a parameter variable (e.g., `node`) is equivalenced to `signature[N]`,
3333
+ // all sub-paths of that variable should also appear under `signature[N]`.
3334
+ // This handles cases where the sub-path was added to the schema via a propagation
3335
+ // chain that already included the variable↔signature equivalency, causing the
3336
+ // cycle detection to prevent the reverse mapping.
3337
+ this.propagateParameterToSignaturePaths(scopeNode);
3338
+
3294
3339
  fillInSchemaGapsAndUnknowns(scopeNode, fillInUnknowns);
3295
3340
 
3296
3341
  if (final) {
@@ -3305,6 +3350,50 @@ export class ScopeDataStructure {
3305
3350
  }
3306
3351
  }
3307
3352
 
3353
+ /**
3354
+ * For each equivalency where a simple variable maps to signature[N],
3355
+ * ensure all sub-paths of that variable are reflected under signature[N].
3356
+ */
3357
+ private propagateParameterToSignaturePaths(scopeNode: ScopeNode) {
3358
+ // Find variable → signature[N] equivalencies
3359
+ for (const [varName, equivalencies] of Object.entries(
3360
+ scopeNode.equivalencies,
3361
+ )) {
3362
+ // Only process simple variable names (no dots, brackets, or parens)
3363
+ if (
3364
+ varName.includes('.') ||
3365
+ varName.includes('[') ||
3366
+ varName.includes('(')
3367
+ ) {
3368
+ continue;
3369
+ }
3370
+
3371
+ for (const equiv of equivalencies) {
3372
+ if (
3373
+ equiv.scopeNodeName === scopeNode.name &&
3374
+ equiv.schemaPath.startsWith('signature[')
3375
+ ) {
3376
+ const signaturePath = equiv.schemaPath;
3377
+ const varPrefix = varName + '.';
3378
+ const varBracketPrefix = varName + '[';
3379
+
3380
+ // Find all schema keys starting with the variable
3381
+ for (const key in scopeNode.schema) {
3382
+ if (key.startsWith(varPrefix) || key.startsWith(varBracketPrefix)) {
3383
+ const suffix = key.slice(varName.length);
3384
+ const sigKey = signaturePath + suffix;
3385
+
3386
+ // Only add if the signature path doesn't already exist
3387
+ if (!scopeNode.schema[sigKey]) {
3388
+ scopeNode.schema[sigKey] = scopeNode.schema[key];
3389
+ }
3390
+ }
3391
+ }
3392
+ }
3393
+ }
3394
+ }
3395
+ }
3396
+
3308
3397
  private filterAndConvertSchema({
3309
3398
  filterPath,
3310
3399
  newPath,
@@ -3391,6 +3480,9 @@ export class ScopeDataStructure {
3391
3480
  equivalentValueSchemaPathParts.length,
3392
3481
  ),
3393
3482
  ]);
3483
+ // PERF: Skip keys with repeated function-call signature patterns
3484
+ // to prevent recursive type expansion (e.g., string.localeCompare returns string)
3485
+ if (this.hasExcessivePatternRepetition(newKey)) continue;
3394
3486
  resolvedSchema[newKey] = value;
3395
3487
  }
3396
3488
  }
@@ -3413,6 +3505,8 @@ export class ScopeDataStructure {
3413
3505
  if (!subSchema) continue;
3414
3506
 
3415
3507
  for (const resolvedKey in subSchema) {
3508
+ // PERF: Skip keys with repeated function-call signature patterns
3509
+ if (this.hasExcessivePatternRepetition(resolvedKey)) continue;
3416
3510
  if (
3417
3511
  !resolvedSchema[resolvedKey] ||
3418
3512
  subSchema[resolvedKey] === 'unknown'
@@ -3927,6 +4021,54 @@ export class ScopeDataStructure {
3927
4021
  }
3928
4022
  }
3929
4023
 
4024
+ // Enrich schema with deeply nested paths from internal function call scopes.
4025
+ // When a function call like traverse(tree) exists, and traverse's scope has
4026
+ // signature[0].children[path][entityName] (from propagateParameterToSignaturePaths),
4027
+ // we need to map those paths back to the argument variable (tree) in this scope.
4028
+ // This handles cases where cycle detection prevented the equivalency chain from
4029
+ // propagating deep paths during Phase 2 batch queue processing.
4030
+ for (const equivalenceKey in equivalencies ?? {}) {
4031
+ // Look for keys matching function call pattern: funcName(...).signature[N]
4032
+ const funcCallMatch = equivalenceKey.match(
4033
+ /^([^(]+)\(.*?\)\.(signature\[\d+\])$/,
4034
+ );
4035
+ if (!funcCallMatch) continue;
4036
+
4037
+ const calledFunctionName = funcCallMatch[1];
4038
+ const signatureParam = funcCallMatch[2]; // e.g., "signature[0]"
4039
+
4040
+ for (const equivalenceValue of equivalencies[equivalenceKey]) {
4041
+ if (equivalenceValue.scopeNodeName !== scopeName) continue;
4042
+
4043
+ const targetVariable = equivalenceValue.schemaPath;
4044
+
4045
+ // Get the called function's schema (includes propagated parameter paths)
4046
+ const childSchema = this.getSchema({
4047
+ scopeName: calledFunctionName,
4048
+ });
4049
+ if (!childSchema) continue;
4050
+
4051
+ // Map child function's signature paths to parent variable paths
4052
+ const sigPrefix = signatureParam + '.';
4053
+ const sigBracketPrefix = signatureParam + '[';
4054
+ for (const childKey in childSchema) {
4055
+ let suffix: string | null = null;
4056
+ if (childKey.startsWith(sigPrefix)) {
4057
+ suffix = childKey.slice(signatureParam.length);
4058
+ } else if (childKey.startsWith(sigBracketPrefix)) {
4059
+ suffix = childKey.slice(signatureParam.length);
4060
+ }
4061
+
4062
+ if (suffix !== null) {
4063
+ const parentKey = targetVariable + suffix;
4064
+ if (!schema[parentKey]) {
4065
+ schema[parentKey] = childSchema[childKey];
4066
+ }
4067
+ }
4068
+ }
4069
+ }
4070
+ }
4071
+
3930
4072
  // Propagate nested paths from variables to their signature equivalents
3931
4073
  // e.g., if workouts = signature[0].workouts, then workouts[].title becomes
3932
4074
  // signature[0].workouts[].title
@@ -5336,11 +5478,22 @@ export class ScopeDataStructure {
5336
5478
  }
5337
5479
  }
5338
5480
 
5481
+ // Enrich the schema with inferred types by applying fillInSchemaGapsAndUnknowns.
5482
+ // This ensures the serialized schema has the same type inference as getReturnValue().
5483
+ // Without this, evidence like "entities[].analyses: array" becomes "unknown".
5484
+ const enrichedSchema = { ...efc.schema };
5485
+ const tempScopeNode = {
5486
+ name: efc.name,
5487
+ schema: enrichedSchema,
5488
+ equivalencies: efc.equivalencies ?? {},
5489
+ };
5490
+ fillInSchemaGapsAndUnknowns(tempScopeNode, true);
5491
+
5339
5492
  return {
5340
5493
  name: efc.name,
5341
5494
  callSignature: efc.callSignature,
5342
5495
  callScope: efc.callScope,
5343
- schema: efc.schema,
5496
+ schema: enrichedSchema,
5344
5497
  equivalencies: efc.equivalencies
5345
5498
  ? Object.entries(efc.equivalencies).reduce(
5346
5499
  (acc, [key, vars]) => {
@@ -72,7 +72,11 @@ export class JavascriptFrameworkManager implements EquivalencyManager {
72
72
  }
73
73
 
74
74
  finalize(scopeNode: ScopeNode, scopeDataStructure: ScopeDataStructure) {
75
- cleanNonObjectFunctions(scopeNode, scopeDataStructure, true);
75
+ // Don't call cleanNonObjectFunctions with final=true here.
76
+ // The aggressive cleanup (transformKeyMapping, clearAttributes) removes method call
77
+ // evidence like .includes() before type inference can use it.
78
+ // Instead, defer final cleanup to toSerializable() when we're done with inference.
79
+ cleanNonObjectFunctions(scopeNode, scopeDataStructure, false);
76
80
  cleanKnownObjectFunctions(scopeNode, scopeDataStructure);
77
81
  this.handleUniformArrays(scopeNode, scopeDataStructure);
78
82
  }
@@ -172,9 +172,18 @@ function scrub(
172
172
  const rawMethod = rawToken.split('(')[0];
173
173
 
174
174
  // Check if it's a prototype method (e.g., map, filter, toString)
175
+ // Only match when the token is actually a method reference/call:
176
+ // - Has parentheses (explicit call like map(), filter(x => x))
177
+ // - OR is typed as "function" (method reference like .split)
178
+ // Bare property names that happen to match method names
179
+ // (like .entries = "array", .values = "object") are preserved.
175
180
  if (protoMethodSets[rootKind].has(rawMethod)) {
176
- onRemove(keyPath);
177
- break;
181
+ const isMethodCall = rawToken.includes('(');
182
+ const isMethodReference = mapping[keyPath] === 'function';
183
+ if (isMethodCall || isMethodReference) {
184
+ onRemove(keyPath);
185
+ break;
186
+ }
178
187
  }
179
188
 
180
189
  // Check if it's a built-in property (e.g., length on arrays/strings)
@@ -510,7 +510,7 @@ function removeNonTransformingArrayMethods(variablePath: string): string {
510
510
  const part = keyParts[i];
511
511
 
512
512
  const arrayMethod = getMethodName(part);
513
- if (isValidArrayMethod(arrayMethod)) {
513
+ if (isValidFunctionCall(part) && isValidArrayMethod(arrayMethod)) {
514
514
  const nextPart = keyParts[i + 1];
515
515
  if (
516
516
  !nonTransformingArrayMethodsSet.has(arrayMethod) ||
@@ -550,7 +550,7 @@ function removeIsolatingArrayMethods(
550
550
  const part = keyParts[i];
551
551
 
552
552
  const arrayMethod = getMethodName(part);
553
- if (isValidArrayMethod(arrayMethod)) {
553
+ if (isValidFunctionCall(part) && isValidArrayMethod(arrayMethod)) {
554
554
  const nextPart = keyParts[i + 1];
555
555
  const prevPart = i > 1 ? keyParts[i - 1] : undefined;
556
556
  if (
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Coerces object/array values to primitive types when the schema expects a primitive.
3
+ *
4
+ * The LLM sometimes generates an object or array where the schema expects a primitive
5
+ * type like "string", "number", or "boolean". For example:
6
+ * Schema: { body: "string" }
7
+ * LLM output: { body: { "env": "production" } }
8
+ *
9
+ * This causes runtime errors like `TypeError: body.match is not a function` because
10
+ * the code expects a string but gets an object.
11
+ *
12
+ * Coercion rules:
13
+ * - object/array → string: JSON.stringify
14
+ * - object/array → number: 0
15
+ * - object/array → boolean: false
16
+ *
17
+ * @param data The mock data object to coerce (mutated in place)
18
+ * @param schema The schema describing expected types
19
+ */
20
+ export default function coerceObjectsToPrimitivesBySchema<T>(
21
+ data: T,
22
+ schema: unknown,
23
+ ): T {
24
+ if (data === null || data === undefined) {
25
+ return data;
26
+ }
27
+
28
+ if (typeof data !== 'object') {
29
+ return data;
30
+ }
31
+
32
+ if (Array.isArray(data)) {
33
+ const itemSchema = Array.isArray(schema) ? schema[0] : undefined;
34
+ for (let i = 0; i < data.length; i++) {
35
+ data[i] = coerceObjectsToPrimitivesBySchema(data[i], itemSchema);
36
+ }
37
+ return data;
38
+ }
39
+
40
+ const dataObj = data as Record<string, unknown>;
41
+ const schemaObj = schema as Record<string, unknown> | undefined;
42
+
43
+ for (const key of Object.keys(dataObj)) {
44
+ const value = dataObj[key];
45
+ const fieldSchema = schemaObj?.[key];
46
+
47
+ if (value === null || value === undefined) {
48
+ continue;
49
+ }
50
+
51
+ if (typeof value === 'object' && typeof fieldSchema === 'string') {
52
+ // Schema expects a primitive but the value is an object/array.
53
+ // Coerce to the expected type.
54
+ const schemaType = fieldSchema.toLowerCase();
55
+
56
+ if (schemaType.includes('string')) {
57
+ dataObj[key] = JSON.stringify(value);
58
+ } else if (schemaType.includes('number')) {
59
+ dataObj[key] = 0;
60
+ } else if (schemaType.includes('boolean')) {
61
+ dataObj[key] = false;
62
+ }
63
+ } else if (typeof value === 'object' && value !== null) {
64
+ // Both value and schema are objects — recurse
65
+ coerceObjectsToPrimitivesBySchema(value, fieldSchema);
66
+ }
67
+ }
68
+
69
+ return data;
70
+ }
@@ -25,12 +25,70 @@ function isSkippableLeafType(t: string) {
25
25
  );
26
26
  }
27
27
 
28
+ // Matches paths containing [][] — e.g., "items[][]" or "items[][].text"
29
+ const DOUBLE_ARRAY_RE = /\[\]\[\]/;
30
+
31
+ // Matches a [].property segment — e.g., "items[].name" (but not "items[][]")
32
+ const ARRAY_OBJECT_PROPERTY_RE = /\[\]\.[^[\]]/;
33
+
34
+ /**
35
+ * When scope analysis produces both `prefix[].property` (array of objects) and
36
+ * `prefix[][]` (array of arrays) for the same prefix, there's a conflict about
37
+ * what the array elements are. Object-property paths are more specific and come
38
+ * from actual property access; double-array paths come from mixed iteration
39
+ * patterns in the scope analysis. Drop the double-array paths when both exist.
40
+ */
41
+ function resolveDoubleArrayConflicts(
42
+ schema: Record<string, string>,
43
+ ): Record<string, string> {
44
+ // Collect prefixes that end in [] and have object property children
45
+ const objectArrayPrefixes = new Set<string>();
46
+ for (const path of Object.keys(schema)) {
47
+ if (!ARRAY_OBJECT_PROPERTY_RE.test(path)) continue;
48
+ // Extract every "...[]" prefix that is followed by ".prop"
49
+ let idx = 0;
50
+ while ((idx = path.indexOf('[].', idx)) !== -1) {
51
+ objectArrayPrefixes.add(path.slice(0, idx + 2)); // includes the "[]"
52
+ idx += 3;
53
+ }
54
+ }
55
+
56
+ if (objectArrayPrefixes.size === 0) return schema;
57
+
58
+ // Check if any double-array paths actually conflict
59
+ let hasConflict = false;
60
+ for (const path of Object.keys(schema)) {
61
+ if (!DOUBLE_ARRAY_RE.test(path)) continue;
62
+ const idx = path.indexOf('[][]');
63
+ if (idx !== -1 && objectArrayPrefixes.has(path.slice(0, idx + 2))) {
64
+ hasConflict = true;
65
+ break;
66
+ }
67
+ }
68
+
69
+ if (!hasConflict) return schema;
70
+
71
+ // Filter out conflicting double-array paths
72
+ const resolved: Record<string, string> = {};
73
+ for (const [path, value] of Object.entries(schema)) {
74
+ if (DOUBLE_ARRAY_RE.test(path)) {
75
+ const idx = path.indexOf('[][]');
76
+ if (idx !== -1 && objectArrayPrefixes.has(path.slice(0, idx + 2))) {
77
+ continue; // drop this conflicting path
78
+ }
79
+ }
80
+ resolved[path] = value;
81
+ }
82
+ return resolved;
83
+ }
84
+
28
85
  export default function convertDotNotation(
29
86
  schema: Record<string, string>,
30
87
  ): JsonTypeDefinition {
88
+ const resolved = resolveDoubleArrayConflicts(schema);
31
89
  const result: JsonTypeDefinition = {};
32
90
 
33
- for (const [rawPath, typ] of Object.entries(schema)) {
91
+ for (const [rawPath, typ] of Object.entries(resolved)) {
34
92
  // Skip paths with .length after array notation from dynamic iteration
35
93
  // e.g., metadata[].length, metadata[][].length
36
94
  if (DYNAMIC_LENGTH_RE.test(rawPath)) continue;
@@ -218,6 +276,17 @@ export default function convertDotNotation(
218
276
  // If the next segment after '[]' is another '[]' or a standalone index,
219
277
  // we need an array at cursor[key][0], not an object (for patterns like "key[][]" or "key[][0]")
220
278
  if (afterArray === '[]' || isStandaloneIndex(afterArray)) {
279
+ // But don't overwrite an existing populated object — object properties
280
+ // (from paths like key[].property) take precedence over double-array hints
281
+ // (from paths like key[][]) which come from mixed access patterns in scope analysis
282
+ if (
283
+ cursor[key][0] &&
284
+ typeof cursor[key][0] === 'object' &&
285
+ !Array.isArray(cursor[key][0]) &&
286
+ Object.keys(cursor[key][0]).length > 0
287
+ ) {
288
+ break;
289
+ }
221
290
  if (!Array.isArray(cursor[key][0])) cursor[key][0] = [];
222
291
  } else {
223
292
  // Default case: create an object
@@ -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;