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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (444) hide show
  1. package/analyzer-template/.build-info.json +7 -7
  2. package/analyzer-template/log.txt +3 -3
  3. package/analyzer-template/package.json +5 -5
  4. package/analyzer-template/packages/ai/index.ts +7 -1
  5. package/analyzer-template/packages/ai/package.json +2 -2
  6. package/analyzer-template/packages/ai/src/lib/analyzeScope.ts +62 -18
  7. package/analyzer-template/packages/ai/src/lib/astScopes/astScopeAnalyzer.ts +67 -9
  8. package/analyzer-template/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.ts +10 -17
  9. package/analyzer-template/packages/ai/src/lib/astScopes/processExpression.ts +409 -50
  10. package/analyzer-template/packages/ai/src/lib/astScopes/sharedPatterns.ts +28 -0
  11. package/analyzer-template/packages/ai/src/lib/astScopes/types.ts +21 -6
  12. package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +992 -249
  13. package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.ts +5 -1
  14. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.ts +16 -3
  15. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.ts +6 -4
  16. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.ts +31 -3
  17. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.ts +37 -15
  18. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.ts +70 -0
  19. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.ts +126 -11
  20. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.ts +179 -0
  21. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/deduplicateFunctionSchemas.ts +40 -30
  22. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.ts +367 -96
  23. package/analyzer-template/packages/ai/src/lib/dataStructureChunking.ts +33 -15
  24. package/analyzer-template/packages/ai/src/lib/generateEntityDataStructure.ts +58 -3
  25. package/analyzer-template/packages/ai/src/lib/generateEntityScenarioData.ts +315 -6
  26. package/analyzer-template/packages/ai/src/lib/generateEntityScenarios.ts +9 -5
  27. package/analyzer-template/packages/ai/src/lib/generateExecutionFlows.ts +49 -5
  28. package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromConditionalEffects.ts +1 -1
  29. package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromConditionals.ts +649 -142
  30. package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromJsxUsages.ts +1 -1
  31. package/analyzer-template/packages/ai/src/lib/isolateScopes.ts +51 -3
  32. package/analyzer-template/packages/ai/src/lib/mergeJsonTypeDefinitions.ts +5 -0
  33. package/analyzer-template/packages/ai/src/lib/mergeStatements.ts +90 -96
  34. package/analyzer-template/packages/ai/src/lib/promptGenerators/collapseNullableObjects.ts +118 -0
  35. package/analyzer-template/packages/ai/src/lib/promptGenerators/gatherAttributesMap.ts +10 -7
  36. package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.ts +24 -4
  37. package/analyzer-template/packages/ai/src/lib/resolvePathToControllable.ts +25 -13
  38. package/analyzer-template/packages/ai/src/lib/worker/SerializableDataStructure.ts +4 -3
  39. package/analyzer-template/packages/analyze/index.ts +2 -0
  40. package/analyzer-template/packages/analyze/src/lib/FileAnalyzer.ts +65 -59
  41. package/analyzer-template/packages/analyze/src/lib/ProjectAnalyzer.ts +113 -26
  42. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllDeclaredEntityNodes.ts +19 -0
  43. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllEntityNodes.ts +19 -0
  44. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllExports.ts +11 -0
  45. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getImportsAnalysis.ts +8 -0
  46. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getResolvedModule.ts +49 -1
  47. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getSourceFilesForAllImports.ts +2 -1
  48. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +89 -9
  49. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +19 -4
  50. package/analyzer-template/packages/analyze/src/lib/files/analyze/gatherEntityMap.ts +4 -2
  51. package/analyzer-template/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.ts +0 -3
  52. package/analyzer-template/packages/analyze/src/lib/files/analyzeRemixRoute.ts +4 -5
  53. package/analyzer-template/packages/analyze/src/lib/files/getImportedExports.ts +14 -12
  54. package/analyzer-template/packages/analyze/src/lib/files/scenarios/TransformationTracer.ts +1315 -0
  55. package/analyzer-template/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.ts +61 -13
  56. package/analyzer-template/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.ts +37 -0
  57. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +229 -19
  58. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.ts +117 -9
  59. package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +459 -39
  60. package/analyzer-template/packages/analyze/src/lib/files/scenarios/propagateArrayItemSchemas.ts +474 -0
  61. package/analyzer-template/packages/analyze/src/lib/files/setImportedExports.ts +2 -1
  62. package/analyzer-template/packages/analyze/src/lib/index.ts +1 -0
  63. package/analyzer-template/packages/analyze/src/lib/utils/getFileByPath.ts +19 -0
  64. package/analyzer-template/packages/aws/package.json +1 -1
  65. package/analyzer-template/packages/database/package.json +1 -1
  66. package/analyzer-template/packages/database/src/lib/analysisBranchToDb.ts +1 -1
  67. package/analyzer-template/packages/database/src/lib/analysisToDb.ts +1 -1
  68. package/analyzer-template/packages/database/src/lib/branchToDb.ts +1 -1
  69. package/analyzer-template/packages/database/src/lib/commitBranchToDb.ts +1 -1
  70. package/analyzer-template/packages/database/src/lib/commitToDb.ts +1 -1
  71. package/analyzer-template/packages/database/src/lib/fileToDb.ts +1 -1
  72. package/analyzer-template/packages/database/src/lib/kysely/db.ts +6 -0
  73. package/analyzer-template/packages/database/src/lib/kysely/tables/debugReportsTable.ts +1 -1
  74. package/analyzer-template/packages/database/src/lib/kysely/tables/labsRequestsTable.ts +52 -0
  75. package/analyzer-template/packages/database/src/lib/projectToDb.ts +1 -1
  76. package/analyzer-template/packages/database/src/lib/saveFiles.ts +1 -1
  77. package/analyzer-template/packages/database/src/lib/scenarioToDb.ts +1 -1
  78. package/analyzer-template/packages/database/src/lib/userScenarioToDb.ts +1 -1
  79. package/analyzer-template/packages/github/dist/database/src/lib/analysisBranchToDb.js +1 -1
  80. package/analyzer-template/packages/github/dist/database/src/lib/analysisBranchToDb.js.map +1 -1
  81. package/analyzer-template/packages/github/dist/database/src/lib/analysisToDb.js +1 -1
  82. package/analyzer-template/packages/github/dist/database/src/lib/analysisToDb.js.map +1 -1
  83. package/analyzer-template/packages/github/dist/database/src/lib/branchToDb.js +1 -1
  84. package/analyzer-template/packages/github/dist/database/src/lib/branchToDb.js.map +1 -1
  85. package/analyzer-template/packages/github/dist/database/src/lib/commitBranchToDb.js +1 -1
  86. package/analyzer-template/packages/github/dist/database/src/lib/commitBranchToDb.js.map +1 -1
  87. package/analyzer-template/packages/github/dist/database/src/lib/commitToDb.js +1 -1
  88. package/analyzer-template/packages/github/dist/database/src/lib/commitToDb.js.map +1 -1
  89. package/analyzer-template/packages/github/dist/database/src/lib/fileToDb.js +1 -1
  90. package/analyzer-template/packages/github/dist/database/src/lib/fileToDb.js.map +1 -1
  91. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts +2 -0
  92. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts.map +1 -1
  93. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js +3 -0
  94. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js.map +1 -1
  95. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.d.ts +1 -1
  96. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/labsRequestsTable.d.ts +23 -0
  97. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/labsRequestsTable.d.ts.map +1 -0
  98. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/labsRequestsTable.js +35 -0
  99. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/labsRequestsTable.js.map +1 -0
  100. package/analyzer-template/packages/github/dist/database/src/lib/projectToDb.js +1 -1
  101. package/analyzer-template/packages/github/dist/database/src/lib/projectToDb.js.map +1 -1
  102. package/analyzer-template/packages/github/dist/database/src/lib/saveFiles.js +1 -1
  103. package/analyzer-template/packages/github/dist/database/src/lib/saveFiles.js.map +1 -1
  104. package/analyzer-template/packages/github/dist/database/src/lib/scenarioToDb.js +1 -1
  105. package/analyzer-template/packages/github/dist/database/src/lib/scenarioToDb.js.map +1 -1
  106. package/analyzer-template/packages/github/dist/types/src/types/ProjectMetadata.d.ts +7 -0
  107. package/analyzer-template/packages/github/dist/types/src/types/ProjectMetadata.d.ts.map +1 -1
  108. package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts +5 -5
  109. package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
  110. package/analyzer-template/packages/github/dist/types/src/types/ScopeAnalysis.d.ts +6 -1
  111. package/analyzer-template/packages/github/dist/types/src/types/ScopeAnalysis.d.ts.map +1 -1
  112. package/analyzer-template/packages/github/package.json +1 -1
  113. package/analyzer-template/packages/types/src/types/ProjectMetadata.ts +7 -0
  114. package/analyzer-template/packages/types/src/types/ScenariosDataStructure.ts +6 -5
  115. package/analyzer-template/packages/types/src/types/ScopeAnalysis.ts +6 -1
  116. package/analyzer-template/packages/utils/dist/types/src/types/ProjectMetadata.d.ts +7 -0
  117. package/analyzer-template/packages/utils/dist/types/src/types/ProjectMetadata.d.ts.map +1 -1
  118. package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts +5 -5
  119. package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
  120. package/analyzer-template/packages/utils/dist/types/src/types/ScopeAnalysis.d.ts +6 -1
  121. package/analyzer-template/packages/utils/dist/types/src/types/ScopeAnalysis.d.ts.map +1 -1
  122. package/analyzer-template/project/constructMockCode.ts +90 -10
  123. package/analyzer-template/project/writeMockDataTsx.ts +181 -8
  124. package/analyzer-template/project/writeScenarioComponents.ts +60 -12
  125. package/analyzer-template/project/writeSimpleRoot.ts +21 -11
  126. package/background/src/lib/local/createLocalAnalyzer.js +1 -1
  127. package/background/src/lib/local/createLocalAnalyzer.js.map +1 -1
  128. package/background/src/lib/virtualized/project/constructMockCode.js +75 -4
  129. package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
  130. package/background/src/lib/virtualized/project/writeMockDataTsx.js +162 -4
  131. package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
  132. package/background/src/lib/virtualized/project/writeScenarioComponents.js +60 -15
  133. package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
  134. package/background/src/lib/virtualized/project/writeSimpleRoot.js +21 -11
  135. package/background/src/lib/virtualized/project/writeSimpleRoot.js.map +1 -1
  136. package/codeyam-cli/scripts/apply-setup.js +180 -0
  137. package/codeyam-cli/scripts/apply-setup.js.map +1 -1
  138. package/codeyam-cli/src/cli.js +2 -0
  139. package/codeyam-cli/src/cli.js.map +1 -1
  140. package/codeyam-cli/src/codeyam-cli.js +18 -2
  141. package/codeyam-cli/src/codeyam-cli.js.map +1 -1
  142. package/codeyam-cli/src/commands/analyze.js +4 -2
  143. package/codeyam-cli/src/commands/analyze.js.map +1 -1
  144. package/codeyam-cli/src/commands/baseline.js +2 -0
  145. package/codeyam-cli/src/commands/baseline.js.map +1 -1
  146. package/codeyam-cli/src/commands/debug.js +9 -5
  147. package/codeyam-cli/src/commands/debug.js.map +1 -1
  148. package/codeyam-cli/src/commands/default.js +31 -20
  149. package/codeyam-cli/src/commands/default.js.map +1 -1
  150. package/codeyam-cli/src/commands/detect-universal-mocks.js +2 -0
  151. package/codeyam-cli/src/commands/detect-universal-mocks.js.map +1 -1
  152. package/codeyam-cli/src/commands/init.js +49 -257
  153. package/codeyam-cli/src/commands/init.js.map +1 -1
  154. package/codeyam-cli/src/commands/memory.js +17 -26
  155. package/codeyam-cli/src/commands/memory.js.map +1 -1
  156. package/codeyam-cli/src/commands/recapture.js +2 -0
  157. package/codeyam-cli/src/commands/recapture.js.map +1 -1
  158. package/codeyam-cli/src/commands/setup-sandbox.js +2 -0
  159. package/codeyam-cli/src/commands/setup-sandbox.js.map +1 -1
  160. package/codeyam-cli/src/commands/setup-simulations.js +284 -0
  161. package/codeyam-cli/src/commands/setup-simulations.js.map +1 -0
  162. package/codeyam-cli/src/commands/test-startup.js +2 -0
  163. package/codeyam-cli/src/commands/test-startup.js.map +1 -1
  164. package/codeyam-cli/src/commands/verify.js +14 -2
  165. package/codeyam-cli/src/commands/verify.js.map +1 -1
  166. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js +128 -86
  167. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js.map +1 -1
  168. package/codeyam-cli/src/utils/analyzer.js +7 -0
  169. package/codeyam-cli/src/utils/analyzer.js.map +1 -1
  170. package/codeyam-cli/src/utils/backgroundServer.js +5 -0
  171. package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
  172. package/codeyam-cli/src/utils/generateReport.js +2 -2
  173. package/codeyam-cli/src/utils/install-skills.js +70 -45
  174. package/codeyam-cli/src/utils/install-skills.js.map +1 -1
  175. package/codeyam-cli/src/utils/labsAutoCheck.js +19 -0
  176. package/codeyam-cli/src/utils/labsAutoCheck.js.map +1 -0
  177. package/codeyam-cli/src/utils/progress.js +7 -0
  178. package/codeyam-cli/src/utils/progress.js.map +1 -1
  179. package/codeyam-cli/src/utils/queue/job.js +4 -0
  180. package/codeyam-cli/src/utils/queue/job.js.map +1 -1
  181. package/codeyam-cli/src/utils/requireSimulations.js +10 -0
  182. package/codeyam-cli/src/utils/requireSimulations.js.map +1 -0
  183. package/codeyam-cli/src/utils/ruleReflection/__tests__/confusionDetector.test.js +82 -0
  184. package/codeyam-cli/src/utils/ruleReflection/__tests__/confusionDetector.test.js.map +1 -0
  185. package/codeyam-cli/src/utils/ruleReflection/__tests__/contextBuilder.test.js +230 -0
  186. package/codeyam-cli/src/utils/ruleReflection/__tests__/contextBuilder.test.js.map +1 -0
  187. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/assertRules.js +67 -0
  188. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/assertRules.js.map +1 -0
  189. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/captureFixture.js +105 -0
  190. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/captureFixture.js.map +1 -0
  191. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/loadCapturedFixture.js +34 -0
  192. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/loadCapturedFixture.js.map +1 -0
  193. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/runClaude.js +162 -0
  194. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/runClaude.js.map +1 -0
  195. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js +75 -0
  196. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js.map +1 -0
  197. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js +378 -0
  198. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js.map +1 -0
  199. package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js +115 -0
  200. package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js.map +1 -0
  201. package/codeyam-cli/src/utils/ruleReflection/__tests__/transcriptParser.test.js +127 -0
  202. package/codeyam-cli/src/utils/ruleReflection/__tests__/transcriptParser.test.js.map +1 -0
  203. package/codeyam-cli/src/utils/ruleReflection/confusionDetector.js +50 -0
  204. package/codeyam-cli/src/utils/ruleReflection/confusionDetector.js.map +1 -0
  205. package/codeyam-cli/src/utils/ruleReflection/contextBuilder.js +116 -0
  206. package/codeyam-cli/src/utils/ruleReflection/contextBuilder.js.map +1 -0
  207. package/codeyam-cli/src/utils/ruleReflection/index.js +5 -0
  208. package/codeyam-cli/src/utils/ruleReflection/index.js.map +1 -0
  209. package/codeyam-cli/src/utils/ruleReflection/promptBuilder.js +44 -0
  210. package/codeyam-cli/src/utils/ruleReflection/promptBuilder.js.map +1 -0
  211. package/codeyam-cli/src/utils/ruleReflection/transcriptParser.js +85 -0
  212. package/codeyam-cli/src/utils/ruleReflection/transcriptParser.js.map +1 -0
  213. package/codeyam-cli/src/utils/ruleReflection/types.js +5 -0
  214. package/codeyam-cli/src/utils/ruleReflection/types.js.map +1 -0
  215. package/codeyam-cli/src/utils/rules/__tests__/ruleState.test.js +293 -0
  216. package/codeyam-cli/src/utils/rules/__tests__/ruleState.test.js.map +1 -0
  217. package/codeyam-cli/src/utils/rules/index.js +1 -0
  218. package/codeyam-cli/src/utils/rules/index.js.map +1 -1
  219. package/codeyam-cli/src/utils/rules/parser.js +2 -25
  220. package/codeyam-cli/src/utils/rules/parser.js.map +1 -1
  221. package/codeyam-cli/src/utils/rules/ruleState.js +150 -0
  222. package/codeyam-cli/src/utils/rules/ruleState.js.map +1 -0
  223. package/codeyam-cli/src/utils/rules/staleness.js +16 -11
  224. package/codeyam-cli/src/utils/rules/staleness.js.map +1 -1
  225. package/codeyam-cli/src/utils/serverState.js +37 -10
  226. package/codeyam-cli/src/utils/serverState.js.map +1 -1
  227. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +21 -44
  228. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js.map +1 -1
  229. package/codeyam-cli/src/webserver/app/lib/database.js +15 -3
  230. package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
  231. package/codeyam-cli/src/webserver/backgroundServer.js +24 -0
  232. package/codeyam-cli/src/webserver/backgroundServer.js.map +1 -1
  233. package/codeyam-cli/src/webserver/build/client/assets/CopyButton-CA3JxPb7.js +1 -0
  234. package/codeyam-cli/src/webserver/build/client/assets/{EntityItem-DsN1wKrm.js → EntityItem-B86KKU7e.js} +1 -1
  235. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeBadge-DLqD3qNt.js → EntityTypeBadge-B5ctlSYt.js} +1 -1
  236. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeIcon-Ba2JVPzP.js → EntityTypeIcon-BqY8gDAW.js} +1 -1
  237. package/codeyam-cli/src/webserver/build/client/assets/{InlineSpinner-C8lyxW9k.js → InlineSpinner-ClaLpuOo.js} +1 -1
  238. package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-aht4aafF.js → InteractivePreview-BDhPilK7.js} +2 -2
  239. package/codeyam-cli/src/webserver/build/client/assets/{LibraryFunctionPreview-CVtiBnY5.js → LibraryFunctionPreview-VeqEBv9v.js} +1 -1
  240. package/codeyam-cli/src/webserver/build/client/assets/{LoadingDots-B0GLXMsr.js → LoadingDots-Bs7Nn1Jr.js} +1 -1
  241. package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-xgeCVgSM.js → LogViewer-Bm3PmcCz.js} +1 -1
  242. package/codeyam-cli/src/webserver/build/client/assets/{ReportIssueModal-OApQuNyq.js → ReportIssueModal-CgMEzchJ.js} +3 -8
  243. package/codeyam-cli/src/webserver/build/client/assets/{SafeScreenshot-DuDvi0jm.js → SafeScreenshot-Gq3Ocjo6.js} +1 -1
  244. package/codeyam-cli/src/webserver/build/client/assets/{ScenarioViewer-DzccYyI8.js → ScenarioViewer-CBui0id_.js} +2 -2
  245. package/codeyam-cli/src/webserver/build/client/assets/{TruncatedFilePath-DyFZkK0l.js → TruncatedFilePath-CiwXDxLh.js} +1 -1
  246. package/codeyam-cli/src/webserver/build/client/assets/{_index-BwqWJOgH.js → _index-B3TDXxnk.js} +1 -1
  247. package/codeyam-cli/src/webserver/build/client/assets/{activity.(_tab)-BwavGCpm.js → activity.(_tab)-BtBFH820.js} +6 -11
  248. package/codeyam-cli/src/webserver/build/client/assets/agent-transcripts-CN61MOMa.js +11 -0
  249. package/codeyam-cli/src/webserver/build/client/assets/api.agent-transcripts-l0sNRNKZ.js +1 -0
  250. package/codeyam-cli/src/webserver/build/client/assets/api.labs-unlock-l0sNRNKZ.js +1 -0
  251. package/codeyam-cli/src/webserver/build/client/assets/api.save-fixture-l0sNRNKZ.js +1 -0
  252. package/codeyam-cli/src/webserver/build/client/assets/book-open-PttOB2SF.js +6 -0
  253. package/codeyam-cli/src/webserver/build/client/assets/{chevron-down-Cx24_aWc.js → chevron-down-TJp6ofnp.js} +1 -1
  254. package/codeyam-cli/src/webserver/build/client/assets/{chunk-EPOLDU6W-CXRTFQ3F.js → chunk-JZWAC4HX-JE9ZIoBl.js} +12 -12
  255. package/codeyam-cli/src/webserver/build/client/assets/{circle-check-BOARzkeR.js → circle-check-CXhHQYrI.js} +1 -1
  256. package/codeyam-cli/src/webserver/build/client/assets/copy-6y9ALfGT.js +11 -0
  257. package/codeyam-cli/src/webserver/build/client/assets/{createLucideIcon-BdhJEx6B.js → createLucideIcon-Ca9fAY46.js} +1 -1
  258. package/codeyam-cli/src/webserver/build/client/assets/{dev.empty-BBnGWYga.js → dev.empty-C0epRiVn.js} +1 -1
  259. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-BJUiQqZF.js → entity._sha._-BVnB8a9L.js} +10 -10
  260. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.fullscreen-DavjRmOY.js → entity._sha.scenarios._scenarioId.fullscreen-CBoafmVs.js} +1 -1
  261. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.create-scenario-D1T4TGjf.js → entity._sha_.create-scenario-DGgZjdFg.js} +1 -1
  262. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.edit._scenarioId-CTBG2mmz.js → entity._sha_.edit._scenarioId-38yPijoD.js} +1 -1
  263. package/codeyam-cli/src/webserver/build/client/assets/{entry.client-CS2cb_eZ.js → entry.client-BSHEfydn.js} +1 -1
  264. package/codeyam-cli/src/webserver/build/client/assets/{fileTableUtils-DMJ7zii9.js → fileTableUtils-DCPhhSMo.js} +1 -1
  265. package/codeyam-cli/src/webserver/build/client/assets/{files-CJ6lTdTA.js → files-0N0YJQv7.js} +1 -1
  266. package/codeyam-cli/src/webserver/build/client/assets/{git-CPTZZ-JZ.js → git-DXnyr8uP.js} +1 -1
  267. package/codeyam-cli/src/webserver/build/client/assets/globals-CKT08Djd.css +1 -0
  268. package/codeyam-cli/src/webserver/build/client/assets/{index-lzqtyFU8.js → index-CcsFv748.js} +1 -1
  269. package/codeyam-cli/src/webserver/build/client/assets/{index-B1h680n5.js → index-ChN9-fAY.js} +1 -1
  270. package/codeyam-cli/src/webserver/build/client/assets/labs-BLJ7HxOC.js +1 -0
  271. package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-B7B9V-bu.js → loader-circle-CTqLEAGU.js} +1 -1
  272. package/codeyam-cli/src/webserver/build/client/assets/manifest-b171b9d3.js +1 -0
  273. package/codeyam-cli/src/webserver/build/client/assets/memory-CCQd4aZA.js +78 -0
  274. package/codeyam-cli/src/webserver/build/client/assets/pause-D6vreykR.js +11 -0
  275. package/codeyam-cli/src/webserver/build/client/assets/root-CHhiHoo_.js +62 -0
  276. package/codeyam-cli/src/webserver/build/client/assets/{search-CxXUmBSd.js → search-B8VUL8nl.js} +1 -1
  277. package/codeyam-cli/src/webserver/build/client/assets/settings-BejnUJ6R.js +1 -0
  278. package/codeyam-cli/src/webserver/build/client/assets/{simulations-DwFIBT09.js → simulations-CPoAg7Zo.js} +1 -1
  279. package/codeyam-cli/src/webserver/build/client/assets/terminal-BrCP7uQo.js +11 -0
  280. package/codeyam-cli/src/webserver/build/client/assets/{triangle-alert-B6LgvRJg.js → triangle-alert-BZz2NjYa.js} +1 -1
  281. package/codeyam-cli/src/webserver/build/client/assets/{useCustomSizes-C1v1PQzo.js → useCustomSizes-DNwUduNu.js} +1 -1
  282. package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-aSv48UbS.js → useLastLogLine-COky1GVF.js} +1 -1
  283. package/codeyam-cli/src/webserver/build/client/assets/{useReportContext-DYxHZQuP.js → useReportContext-CpZgwliL.js} +1 -1
  284. package/codeyam-cli/src/webserver/build/client/assets/{useToast-mBRpZPiu.js → useToast-Bv9JFvUO.js} +1 -1
  285. package/codeyam-cli/src/webserver/build/server/assets/{index-DVzYx8PN.js → index-8Fv-lH1-.js} +1 -1
  286. package/codeyam-cli/src/webserver/build/server/assets/server-build-Akn3iYFP.js +257 -0
  287. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  288. package/codeyam-cli/src/webserver/build-info.json +5 -5
  289. package/codeyam-cli/templates/{codeyam:debug.md → codeyam-debug.md} +1 -1
  290. package/codeyam-cli/templates/codeyam-diagnose.md +481 -0
  291. package/codeyam-cli/templates/codeyam-memory-hook.sh +19 -20
  292. package/codeyam-cli/templates/codeyam-memory.md +392 -0
  293. package/codeyam-cli/templates/codeyam-new-rule.md +13 -0
  294. package/codeyam-cli/templates/{codeyam:setup.md → codeyam-setup.md} +13 -1
  295. package/codeyam-cli/templates/{codeyam:sim.md → codeyam-sim.md} +1 -1
  296. package/codeyam-cli/templates/{codeyam:test.md → codeyam-test.md} +1 -1
  297. package/codeyam-cli/templates/{codeyam:verify.md → codeyam-verify.md} +1 -1
  298. package/codeyam-cli/templates/rule-notification-hook.py +56 -0
  299. package/codeyam-cli/templates/rule-reflection-hook.py +627 -0
  300. package/codeyam-cli/templates/rules-instructions.md +132 -0
  301. package/package.json +2 -2
  302. package/packages/ai/index.js +3 -2
  303. package/packages/ai/index.js.map +1 -1
  304. package/packages/ai/src/lib/analyzeScope.js +50 -13
  305. package/packages/ai/src/lib/analyzeScope.js.map +1 -1
  306. package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js +54 -8
  307. package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js.map +1 -1
  308. package/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.js +10 -14
  309. package/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.js.map +1 -1
  310. package/packages/ai/src/lib/astScopes/processExpression.js +317 -44
  311. package/packages/ai/src/lib/astScopes/processExpression.js.map +1 -1
  312. package/packages/ai/src/lib/astScopes/sharedPatterns.js +25 -0
  313. package/packages/ai/src/lib/astScopes/sharedPatterns.js.map +1 -1
  314. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +763 -171
  315. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
  316. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js +5 -1
  317. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js.map +1 -1
  318. package/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.js +13 -3
  319. package/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.js.map +1 -1
  320. package/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.js +6 -4
  321. package/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.js.map +1 -1
  322. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js +33 -3
  323. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js.map +1 -1
  324. package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js +36 -11
  325. package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js.map +1 -1
  326. package/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.js +63 -0
  327. package/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.js.map +1 -0
  328. package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js +113 -11
  329. package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js.map +1 -1
  330. package/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.js +173 -0
  331. package/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.js.map +1 -0
  332. package/packages/ai/src/lib/dataStructure/helpers/deduplicateFunctionSchemas.js +37 -20
  333. package/packages/ai/src/lib/dataStructure/helpers/deduplicateFunctionSchemas.js.map +1 -1
  334. package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js +309 -84
  335. package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js.map +1 -1
  336. package/packages/ai/src/lib/dataStructureChunking.js +26 -11
  337. package/packages/ai/src/lib/dataStructureChunking.js.map +1 -1
  338. package/packages/ai/src/lib/generateEntityDataStructure.js +46 -2
  339. package/packages/ai/src/lib/generateEntityDataStructure.js.map +1 -1
  340. package/packages/ai/src/lib/generateEntityScenarioData.js +227 -4
  341. package/packages/ai/src/lib/generateEntityScenarioData.js.map +1 -1
  342. package/packages/ai/src/lib/generateEntityScenarios.js +7 -1
  343. package/packages/ai/src/lib/generateEntityScenarios.js.map +1 -1
  344. package/packages/ai/src/lib/generateExecutionFlows.js +26 -4
  345. package/packages/ai/src/lib/generateExecutionFlows.js.map +1 -1
  346. package/packages/ai/src/lib/generateExecutionFlowsFromConditionals.js +447 -80
  347. package/packages/ai/src/lib/generateExecutionFlowsFromConditionals.js.map +1 -1
  348. package/packages/ai/src/lib/isolateScopes.js +39 -3
  349. package/packages/ai/src/lib/isolateScopes.js.map +1 -1
  350. package/packages/ai/src/lib/mergeJsonTypeDefinitions.js +5 -0
  351. package/packages/ai/src/lib/mergeJsonTypeDefinitions.js.map +1 -1
  352. package/packages/ai/src/lib/mergeStatements.js +70 -51
  353. package/packages/ai/src/lib/mergeStatements.js.map +1 -1
  354. package/packages/ai/src/lib/promptGenerators/collapseNullableObjects.js +97 -0
  355. package/packages/ai/src/lib/promptGenerators/collapseNullableObjects.js.map +1 -0
  356. package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js +10 -4
  357. package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js.map +1 -1
  358. package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js +17 -2
  359. package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js.map +1 -1
  360. package/packages/ai/src/lib/resolvePathToControllable.js +24 -14
  361. package/packages/ai/src/lib/resolvePathToControllable.js.map +1 -1
  362. package/packages/ai/src/lib/worker/SerializableDataStructure.js.map +1 -1
  363. package/packages/analyze/index.js +1 -0
  364. package/packages/analyze/index.js.map +1 -1
  365. package/packages/analyze/src/lib/FileAnalyzer.js +60 -36
  366. package/packages/analyze/src/lib/FileAnalyzer.js.map +1 -1
  367. package/packages/analyze/src/lib/ProjectAnalyzer.js +96 -26
  368. package/packages/analyze/src/lib/ProjectAnalyzer.js.map +1 -1
  369. package/packages/analyze/src/lib/asts/sourceFiles/getAllDeclaredEntityNodes.js +14 -0
  370. package/packages/analyze/src/lib/asts/sourceFiles/getAllDeclaredEntityNodes.js.map +1 -1
  371. package/packages/analyze/src/lib/asts/sourceFiles/getAllEntityNodes.js +14 -0
  372. package/packages/analyze/src/lib/asts/sourceFiles/getAllEntityNodes.js.map +1 -1
  373. package/packages/analyze/src/lib/asts/sourceFiles/getAllExports.js +6 -0
  374. package/packages/analyze/src/lib/asts/sourceFiles/getAllExports.js.map +1 -1
  375. package/packages/analyze/src/lib/asts/sourceFiles/getImportsAnalysis.js +6 -0
  376. package/packages/analyze/src/lib/asts/sourceFiles/getImportsAnalysis.js.map +1 -1
  377. package/packages/analyze/src/lib/asts/sourceFiles/getResolvedModule.js +39 -1
  378. package/packages/analyze/src/lib/asts/sourceFiles/getResolvedModule.js.map +1 -1
  379. package/packages/analyze/src/lib/asts/sourceFiles/getSourceFilesForAllImports.js +2 -1
  380. package/packages/analyze/src/lib/asts/sourceFiles/getSourceFilesForAllImports.js.map +1 -1
  381. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +65 -7
  382. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
  383. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +17 -4
  384. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
  385. package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js +2 -1
  386. package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js.map +1 -1
  387. package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js +0 -3
  388. package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js.map +1 -1
  389. package/packages/analyze/src/lib/files/analyzeRemixRoute.js +3 -2
  390. package/packages/analyze/src/lib/files/analyzeRemixRoute.js.map +1 -1
  391. package/packages/analyze/src/lib/files/getImportedExports.js +11 -7
  392. package/packages/analyze/src/lib/files/getImportedExports.js.map +1 -1
  393. package/packages/analyze/src/lib/files/scenarios/TransformationTracer.js +880 -0
  394. package/packages/analyze/src/lib/files/scenarios/TransformationTracer.js.map +1 -0
  395. package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js +56 -10
  396. package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js.map +1 -1
  397. package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js +33 -8
  398. package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js.map +1 -1
  399. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +150 -17
  400. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
  401. package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js +56 -8
  402. package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js.map +1 -1
  403. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +399 -31
  404. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
  405. package/packages/analyze/src/lib/files/setImportedExports.js +2 -1
  406. package/packages/analyze/src/lib/files/setImportedExports.js.map +1 -1
  407. package/packages/analyze/src/lib/index.js +1 -0
  408. package/packages/analyze/src/lib/index.js.map +1 -1
  409. package/packages/analyze/src/lib/utils/getFileByPath.js +12 -0
  410. package/packages/analyze/src/lib/utils/getFileByPath.js.map +1 -0
  411. package/packages/database/src/lib/analysisBranchToDb.js +1 -1
  412. package/packages/database/src/lib/analysisBranchToDb.js.map +1 -1
  413. package/packages/database/src/lib/analysisToDb.js +1 -1
  414. package/packages/database/src/lib/analysisToDb.js.map +1 -1
  415. package/packages/database/src/lib/branchToDb.js +1 -1
  416. package/packages/database/src/lib/branchToDb.js.map +1 -1
  417. package/packages/database/src/lib/commitBranchToDb.js +1 -1
  418. package/packages/database/src/lib/commitBranchToDb.js.map +1 -1
  419. package/packages/database/src/lib/commitToDb.js +1 -1
  420. package/packages/database/src/lib/commitToDb.js.map +1 -1
  421. package/packages/database/src/lib/fileToDb.js +1 -1
  422. package/packages/database/src/lib/fileToDb.js.map +1 -1
  423. package/packages/database/src/lib/kysely/db.js +3 -0
  424. package/packages/database/src/lib/kysely/db.js.map +1 -1
  425. package/packages/database/src/lib/kysely/tables/labsRequestsTable.js +35 -0
  426. package/packages/database/src/lib/kysely/tables/labsRequestsTable.js.map +1 -0
  427. package/packages/database/src/lib/projectToDb.js +1 -1
  428. package/packages/database/src/lib/projectToDb.js.map +1 -1
  429. package/packages/database/src/lib/saveFiles.js +1 -1
  430. package/packages/database/src/lib/saveFiles.js.map +1 -1
  431. package/packages/database/src/lib/scenarioToDb.js +1 -1
  432. package/packages/database/src/lib/scenarioToDb.js.map +1 -1
  433. package/scripts/finalize-analyzer.cjs +8 -76
  434. package/codeyam-cli/src/webserver/build/client/assets/copy-Bb-80kDT.js +0 -6
  435. package/codeyam-cli/src/webserver/build/client/assets/file-code-Dhef1kWN.js +0 -6
  436. package/codeyam-cli/src/webserver/build/client/assets/globals-D3yhhV8x.css +0 -1
  437. package/codeyam-cli/src/webserver/build/client/assets/manifest-7522edd4.js +0 -1
  438. package/codeyam-cli/src/webserver/build/client/assets/memory-yxFcrxBX.js +0 -92
  439. package/codeyam-cli/src/webserver/build/client/assets/root-eVAaavTS.js +0 -62
  440. package/codeyam-cli/src/webserver/build/client/assets/settings-CS5f3WzT.js +0 -1
  441. package/codeyam-cli/src/webserver/build/server/assets/server-build-4Cr0uToj.js +0 -257
  442. package/codeyam-cli/templates/codeyam:diagnose.md +0 -803
  443. package/codeyam-cli/templates/codeyam:memory.md +0 -462
  444. package/codeyam-cli/templates/codeyam:new-rule.md +0 -13
@@ -0,0 +1,880 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ // ============================================================================
4
+ // Utility Functions
5
+ // ============================================================================
6
+ /**
7
+ * Compute the diff between two schema objects.
8
+ */
9
+ export function computeSchemaDiff(before, after) {
10
+ const diff = {
11
+ added: {},
12
+ removed: {},
13
+ changed: {},
14
+ };
15
+ const beforeKeys = new Set(Object.keys(before ?? {}));
16
+ const afterKeys = new Set(Object.keys(after ?? {}));
17
+ // Find added keys
18
+ for (const key of afterKeys) {
19
+ if (!beforeKeys.has(key)) {
20
+ diff.added[key] = after[key];
21
+ }
22
+ }
23
+ // Find removed keys
24
+ for (const key of beforeKeys) {
25
+ if (!afterKeys.has(key)) {
26
+ diff.removed[key] = before[key];
27
+ }
28
+ }
29
+ // Find changed keys
30
+ for (const key of beforeKeys) {
31
+ if (afterKeys.has(key) && before[key] !== after[key]) {
32
+ diff.changed[key] = { from: before[key], to: after[key] };
33
+ }
34
+ }
35
+ return diff;
36
+ }
37
+ /**
38
+ * Check if a diff has any changes.
39
+ */
40
+ export function hasDiffChanges(diff) {
41
+ return (Object.keys(diff.added).length > 0 ||
42
+ Object.keys(diff.removed).length > 0 ||
43
+ Object.keys(diff.changed).length > 0);
44
+ }
45
+ /**
46
+ * Count total changes in a diff.
47
+ */
48
+ export function countDiffChanges(diff) {
49
+ return (Object.keys(diff.added).length +
50
+ Object.keys(diff.removed).length +
51
+ Object.keys(diff.changed).length);
52
+ }
53
+ // ============================================================================
54
+ // TransformationTracer Class
55
+ // ============================================================================
56
+ // Global counter to identify tracer instances
57
+ let tracerInstanceCounter = 0;
58
+ export class TransformationTracer {
59
+ constructor(options) {
60
+ this.traces = new Map();
61
+ this.currentEntity = null;
62
+ this.currentStage = null;
63
+ this.tracerId = ++tracerInstanceCounter;
64
+ this.enabled = options?.enabled ?? false;
65
+ this.outputPath =
66
+ options?.outputPath ?? '/tmp/codeyam/transform-trace.json';
67
+ if (this.enabled) {
68
+ console.log(`[Tracer] Initialized (id=${this.tracerId}, output=${this.outputPath})`);
69
+ }
70
+ }
71
+ /**
72
+ * Log a message (only when tracing is enabled).
73
+ */
74
+ log(message) {
75
+ if (this.isEnabled()) {
76
+ console.log(`[Tracer] ${message}`);
77
+ }
78
+ }
79
+ /**
80
+ * Check if tracing is enabled.
81
+ * Dynamically checks environment variable so it works even if set after module load.
82
+ */
83
+ isEnabled() {
84
+ // Check environment variable dynamically - allows setting after module load
85
+ const envValue = process.env.CODEYAM_TRACE_TRANSFORMS;
86
+ if (envValue === '1' || envValue === 'true') {
87
+ return true;
88
+ }
89
+ return this.enabled;
90
+ }
91
+ /**
92
+ * Enable tracing.
93
+ */
94
+ enable() {
95
+ this.enabled = true;
96
+ }
97
+ /**
98
+ * Disable tracing.
99
+ */
100
+ disable() {
101
+ this.enabled = false;
102
+ }
103
+ /**
104
+ * Set the output path for the trace file.
105
+ */
106
+ setOutputPath(outputPath) {
107
+ this.outputPath = outputPath;
108
+ }
109
+ /**
110
+ * Set the project slug for metadata.
111
+ */
112
+ setProjectSlug(slug) {
113
+ this.projectSlug = slug;
114
+ }
115
+ /**
116
+ * Start tracing a new entity.
117
+ * If the entity already exists, preserves its existing stages and operations.
118
+ */
119
+ startEntity(entity) {
120
+ if (!this.isEnabled())
121
+ return;
122
+ this.currentEntity = entity.name;
123
+ // Preserve existing trace data if entity was already started
124
+ // (e.g., early stages from generateEntityDataStructure.ts)
125
+ const existing = this.traces.get(entity.name);
126
+ if (existing) {
127
+ this.log(`startEntity: ${entity.name} already exists, preserving ${existing.stages.length} stages`);
128
+ return; // Keep existing trace data
129
+ }
130
+ this.log(`startEntity: ${entity.name}`);
131
+ this.traces.set(entity.name, {
132
+ entityName: entity.name,
133
+ entityType: entity.entityType,
134
+ filePath: entity.filePath,
135
+ stages: [],
136
+ operations: [],
137
+ });
138
+ }
139
+ /**
140
+ * Take a coarse-grained snapshot at a transformation stage.
141
+ */
142
+ snapshot(entityName, stage, data) {
143
+ if (!this.isEnabled())
144
+ return;
145
+ const trace = this.traces.get(entityName);
146
+ if (!trace) {
147
+ this.log(`snapshot: no trace for ${entityName}, creating one`);
148
+ this.startEntity({
149
+ name: entityName,
150
+ entityType: 'unknown',
151
+ filePath: 'unknown',
152
+ });
153
+ return this.snapshot(entityName, stage, data);
154
+ }
155
+ this.log(`snapshot: ${entityName} → ${stage}`);
156
+ this.currentStage = stage;
157
+ // Deep clone the data to avoid capturing references that change later
158
+ const clonedData = JSON.parse(JSON.stringify(data));
159
+ const snapshot = {
160
+ stage,
161
+ timestamp: Date.now(),
162
+ data: clonedData,
163
+ };
164
+ // Compute diff from previous stage if there is one
165
+ const previousSnapshot = trace.stages[trace.stages.length - 1];
166
+ if (previousSnapshot) {
167
+ snapshot.diffFromPrevious = {
168
+ signatureSchema: computeSchemaDiff(previousSnapshot.data.signatureSchema, clonedData.signatureSchema),
169
+ returnValueSchema: computeSchemaDiff(previousSnapshot.data.returnValueSchema, clonedData.returnValueSchema),
170
+ };
171
+ // Compute diffs for dependency schemas
172
+ if (clonedData.dependencySchemas ||
173
+ previousSnapshot.data.dependencySchemas) {
174
+ snapshot.diffFromPrevious.dependencySchemas = {};
175
+ const allDepKeys = new Set([
176
+ ...Object.keys(clonedData.dependencySchemas ?? {}),
177
+ ...Object.keys(previousSnapshot.data.dependencySchemas ?? {}),
178
+ ]);
179
+ for (const depKey of allDepKeys) {
180
+ const prevDep = previousSnapshot.data.dependencySchemas?.[depKey];
181
+ const currDep = clonedData.dependencySchemas?.[depKey];
182
+ // Compare returnValueSchema for each dependency
183
+ for (const entityKey of new Set([
184
+ ...Object.keys(prevDep ?? {}),
185
+ ...Object.keys(currDep ?? {}),
186
+ ])) {
187
+ const fullKey = `${depKey}::${entityKey}`;
188
+ const prevSchema = prevDep?.[entityKey]?.returnValueSchema;
189
+ const currSchema = currDep?.[entityKey]?.returnValueSchema;
190
+ const depDiff = computeSchemaDiff(prevSchema, currSchema);
191
+ if (hasDiffChanges(depDiff)) {
192
+ snapshot.diffFromPrevious.dependencySchemas[fullKey] = depDiff;
193
+ }
194
+ }
195
+ }
196
+ }
197
+ }
198
+ trace.stages.push(snapshot);
199
+ }
200
+ /**
201
+ * Log a fine-grained operation within the current stage.
202
+ */
203
+ operation(entityName, op) {
204
+ if (!this.isEnabled())
205
+ return;
206
+ const trace = this.traces.get(entityName);
207
+ if (!trace)
208
+ return;
209
+ trace.operations.push({
210
+ ...op,
211
+ stage: op.stage ?? this.currentStage ?? undefined,
212
+ timestamp: Date.now(),
213
+ });
214
+ }
215
+ /**
216
+ * Write the trace to the output file.
217
+ */
218
+ flush() {
219
+ if (!this.isEnabled())
220
+ return;
221
+ if (this.traces.size === 0) {
222
+ this.log('flush: no traces to write');
223
+ return;
224
+ }
225
+ const entities = Array.from(this.traces.keys());
226
+ const stageCounts = entities
227
+ .map((e) => `${e}(${this.traces.get(e).stages.length})`)
228
+ .join(', ');
229
+ this.log(`flush: writing ${entities.length} entities: ${stageCounts}`);
230
+ // Compute summary
231
+ const stageChangeCounts = {};
232
+ const entityChangeCounts = new Map();
233
+ for (const [entityName, trace] of this.traces) {
234
+ let entityTotal = 0;
235
+ for (const snapshot of trace.stages) {
236
+ if (!snapshot.diffFromPrevious)
237
+ continue;
238
+ const previousStage = trace.stages[trace.stages.indexOf(snapshot) - 1]?.stage ?? 'start';
239
+ const transitionKey = `${previousStage}→${snapshot.stage}`;
240
+ if (!stageChangeCounts[transitionKey]) {
241
+ stageChangeCounts[transitionKey] = {
242
+ added: 0,
243
+ removed: 0,
244
+ changed: 0,
245
+ };
246
+ }
247
+ // Count signature schema changes
248
+ if (snapshot.diffFromPrevious.signatureSchema) {
249
+ const diff = snapshot.diffFromPrevious.signatureSchema;
250
+ stageChangeCounts[transitionKey].added += Object.keys(diff.added).length;
251
+ stageChangeCounts[transitionKey].removed += Object.keys(diff.removed).length;
252
+ stageChangeCounts[transitionKey].changed += Object.keys(diff.changed).length;
253
+ entityTotal += countDiffChanges(diff);
254
+ }
255
+ // Count return value schema changes
256
+ if (snapshot.diffFromPrevious.returnValueSchema) {
257
+ const diff = snapshot.diffFromPrevious.returnValueSchema;
258
+ stageChangeCounts[transitionKey].added += Object.keys(diff.added).length;
259
+ stageChangeCounts[transitionKey].removed += Object.keys(diff.removed).length;
260
+ stageChangeCounts[transitionKey].changed += Object.keys(diff.changed).length;
261
+ entityTotal += countDiffChanges(diff);
262
+ }
263
+ }
264
+ entityChangeCounts.set(entityName, entityTotal);
265
+ }
266
+ // Get top 10 entities with most changes
267
+ const entitiesWithMostChanges = [...entityChangeCounts.entries()]
268
+ .sort((a, b) => b[1] - a[1])
269
+ .slice(0, 10)
270
+ .map(([name]) => name);
271
+ const traceFile = {
272
+ meta: {
273
+ timestamp: new Date().toISOString(),
274
+ projectSlug: this.projectSlug,
275
+ entityCount: this.traces.size,
276
+ },
277
+ summary: {
278
+ stageChangeCounts,
279
+ entitiesWithMostChanges,
280
+ },
281
+ entities: Object.fromEntries(this.traces),
282
+ };
283
+ // Ensure directory exists
284
+ const dir = path.dirname(this.outputPath);
285
+ if (!fs.existsSync(dir)) {
286
+ fs.mkdirSync(dir, { recursive: true });
287
+ }
288
+ fs.writeFileSync(this.outputPath, JSON.stringify(traceFile, null, 2));
289
+ this.log(`flush: wrote trace to ${this.outputPath}`);
290
+ }
291
+ /**
292
+ * Clear all traces (useful for testing).
293
+ */
294
+ clear() {
295
+ this.traces.clear();
296
+ this.currentEntity = null;
297
+ this.currentStage = null;
298
+ }
299
+ // ============================================================================
300
+ // Analysis Utilities
301
+ // ============================================================================
302
+ /**
303
+ * Load a trace from a file.
304
+ */
305
+ static loadTrace(tracePath) {
306
+ const content = fs.readFileSync(tracePath, 'utf-8');
307
+ const traceFile = JSON.parse(content);
308
+ const tracer = new TransformationTracer({ enabled: false });
309
+ tracer.projectSlug = traceFile.meta.projectSlug;
310
+ for (const [entityName, entityTrace] of Object.entries(traceFile.entities)) {
311
+ tracer.traces.set(entityName, entityTrace);
312
+ }
313
+ return tracer;
314
+ }
315
+ /**
316
+ * Get a high-level summary of the trace.
317
+ */
318
+ getSummary() {
319
+ const stageChangeCounts = {};
320
+ const entityChangeCounts = new Map();
321
+ for (const [entityName, trace] of this.traces) {
322
+ let entityTotal = 0;
323
+ for (let i = 1; i < trace.stages.length; i++) {
324
+ const snapshot = trace.stages[i];
325
+ const previousStage = trace.stages[i - 1]?.stage ?? 'start';
326
+ const transitionKey = `${previousStage}→${snapshot.stage}`;
327
+ if (!stageChangeCounts[transitionKey]) {
328
+ stageChangeCounts[transitionKey] = {
329
+ added: 0,
330
+ removed: 0,
331
+ changed: 0,
332
+ };
333
+ }
334
+ if (snapshot.diffFromPrevious?.signatureSchema) {
335
+ const diff = snapshot.diffFromPrevious.signatureSchema;
336
+ stageChangeCounts[transitionKey].added += Object.keys(diff.added).length;
337
+ stageChangeCounts[transitionKey].removed += Object.keys(diff.removed).length;
338
+ stageChangeCounts[transitionKey].changed += Object.keys(diff.changed).length;
339
+ entityTotal += countDiffChanges(diff);
340
+ }
341
+ if (snapshot.diffFromPrevious?.returnValueSchema) {
342
+ const diff = snapshot.diffFromPrevious.returnValueSchema;
343
+ stageChangeCounts[transitionKey].added += Object.keys(diff.added).length;
344
+ stageChangeCounts[transitionKey].removed += Object.keys(diff.removed).length;
345
+ stageChangeCounts[transitionKey].changed += Object.keys(diff.changed).length;
346
+ entityTotal += countDiffChanges(diff);
347
+ }
348
+ }
349
+ entityChangeCounts.set(entityName, entityTotal);
350
+ }
351
+ const entitiesWithMostChanges = [...entityChangeCounts.entries()]
352
+ .sort((a, b) => b[1] - a[1])
353
+ .slice(0, 10)
354
+ .map(([name, totalChanges]) => ({ name, totalChanges }));
355
+ return {
356
+ entityCount: this.traces.size,
357
+ stageChangeCounts,
358
+ entitiesWithMostChanges,
359
+ };
360
+ }
361
+ /**
362
+ * Get a summary of stages for a specific entity.
363
+ */
364
+ getEntitySummary(entityName) {
365
+ const trace = this.traces.get(entityName);
366
+ if (!trace)
367
+ return null;
368
+ return {
369
+ entityName,
370
+ stages: trace.stages.map((s) => ({
371
+ stage: s.stage,
372
+ diffFromPrevious: s.diffFromPrevious
373
+ ? {
374
+ signatureSchema: s.diffFromPrevious.signatureSchema,
375
+ returnValueSchema: s.diffFromPrevious.returnValueSchema,
376
+ }
377
+ : undefined,
378
+ })),
379
+ };
380
+ }
381
+ /**
382
+ * Get operations for an entity, optionally filtered by path pattern.
383
+ */
384
+ getOperations(entityName, pathPattern) {
385
+ const trace = this.traces.get(entityName);
386
+ if (!trace)
387
+ return [];
388
+ if (!pathPattern)
389
+ return trace.operations;
390
+ return trace.operations.filter((op) => op.path && pathPattern.test(op.path));
391
+ }
392
+ /**
393
+ * Trace the full history of a specific path through all transformations.
394
+ */
395
+ tracePath(entityName, targetPath) {
396
+ const trace = this.traces.get(entityName);
397
+ const history = [];
398
+ if (!trace) {
399
+ return { entityName, path: targetPath, history };
400
+ }
401
+ // Track value through stages
402
+ for (const snapshot of trace.stages) {
403
+ const sigValue = snapshot.data.signatureSchema?.[targetPath];
404
+ const retValue = snapshot.data.returnValueSchema?.[targetPath];
405
+ const value = sigValue ?? retValue;
406
+ if (value !== undefined) {
407
+ history.push({
408
+ stage: snapshot.stage,
409
+ value,
410
+ });
411
+ }
412
+ }
413
+ // Track value through operations
414
+ for (const op of trace.operations) {
415
+ if (op.path === targetPath) {
416
+ history.push({
417
+ operation: op.operation,
418
+ stage: op.stage,
419
+ value: op.after ?? op.before,
420
+ context: op.context,
421
+ });
422
+ }
423
+ }
424
+ return { entityName, path: targetPath, history };
425
+ }
426
+ /**
427
+ * Get the raw entity trace for direct inspection.
428
+ */
429
+ getEntityTrace(entityName) {
430
+ return this.traces.get(entityName);
431
+ }
432
+ /**
433
+ * Get all entity names in the trace.
434
+ */
435
+ getEntityNames() {
436
+ return [...this.traces.keys()];
437
+ }
438
+ // ============================================================================
439
+ // Debugging Utilities
440
+ // ============================================================================
441
+ /**
442
+ * Find all paths containing a property name across all stages.
443
+ * Useful for debugging: "where does 'analyses' appear in the schema?"
444
+ */
445
+ findProperty(entityName, propertyName) {
446
+ const trace = this.traces.get(entityName);
447
+ if (!trace)
448
+ return [];
449
+ const results = [];
450
+ const pattern = new RegExp(`(^|\\.)${propertyName}(\\.|\\[|$)`);
451
+ for (const snapshot of trace.stages) {
452
+ // Search signature schema
453
+ for (const [path, type] of Object.entries(snapshot.data.signatureSchema ?? {})) {
454
+ if (pattern.test(path)) {
455
+ results.push({
456
+ stage: snapshot.stage,
457
+ path,
458
+ type,
459
+ schemaType: 'signature',
460
+ });
461
+ }
462
+ }
463
+ // Search return value schema
464
+ for (const [path, type] of Object.entries(snapshot.data.returnValueSchema ?? {})) {
465
+ if (pattern.test(path)) {
466
+ results.push({
467
+ stage: snapshot.stage,
468
+ path,
469
+ type,
470
+ schemaType: 'returnValue',
471
+ });
472
+ }
473
+ }
474
+ // Search dependency schemas
475
+ for (const [depPath, depEntities] of Object.entries(snapshot.data.dependencySchemas ?? {})) {
476
+ for (const [depName, depData] of Object.entries(depEntities)) {
477
+ for (const [path, type] of Object.entries(depData.returnValueSchema ?? {})) {
478
+ if (pattern.test(path)) {
479
+ results.push({
480
+ stage: snapshot.stage,
481
+ path: `${depPath}/${depName}::${path}`,
482
+ type,
483
+ schemaType: 'dependency',
484
+ });
485
+ }
486
+ }
487
+ }
488
+ }
489
+ }
490
+ return results;
491
+ }
492
+ /**
493
+ * Find properties that have inconsistent types across different paths.
494
+ * Useful for debugging: "why does 'analyses' have different types?"
495
+ *
496
+ * Only compares paths that end with the same pattern (e.g., both end in `.analyses`
497
+ * or both end in `.analyses[]`). Ignores built-in properties like `.length`.
498
+ */
499
+ findTypeInconsistencies(entityName) {
500
+ const trace = this.traces.get(entityName);
501
+ if (!trace)
502
+ return [];
503
+ // Find the best stage for comparison (last one with dependency schemas)
504
+ let targetStage = trace.stages[trace.stages.length - 1];
505
+ for (let i = trace.stages.length - 1; i >= 0; i--) {
506
+ if (Object.keys(trace.stages[i].data.dependencySchemas ?? {}).length > 0) {
507
+ targetStage = trace.stages[i];
508
+ break;
509
+ }
510
+ }
511
+ if (!targetStage)
512
+ return [];
513
+ // Built-in properties to ignore
514
+ const builtIns = new Set(['length', 'toString', 'valueOf', 'constructor']);
515
+ // Group paths by their terminal pattern (e.g., ".analyses" or ".analyses[]")
516
+ const propertyGroups = new Map();
517
+ const addToGroup = (path, type) => {
518
+ // Extract terminal property pattern (e.g., "foo.bar.analyses[]" -> "analyses[]")
519
+ const match = path.match(/\.([a-zA-Z_][a-zA-Z0-9_]*)(\[\])?$/);
520
+ if (!match)
521
+ return;
522
+ const propName = match[1];
523
+ const isArray = match[2] === '[]';
524
+ // Skip built-in properties
525
+ if (builtIns.has(propName))
526
+ return;
527
+ // Use pattern as key (includes [] suffix)
528
+ const pattern = propName + (isArray ? '[]' : '');
529
+ if (!propertyGroups.has(pattern)) {
530
+ propertyGroups.set(pattern, []);
531
+ }
532
+ propertyGroups.get(pattern).push({ path, type });
533
+ };
534
+ // Collect from dependency schemas (where inconsistencies usually appear)
535
+ for (const [, depEntities] of Object.entries(targetStage.data.dependencySchemas ?? {})) {
536
+ for (const [, depData] of Object.entries(depEntities)) {
537
+ for (const [path, type] of Object.entries(depData.returnValueSchema ?? {})) {
538
+ addToGroup(path, type);
539
+ }
540
+ }
541
+ }
542
+ // Find inconsistencies (same terminal pattern, different types)
543
+ const inconsistencies = [];
544
+ for (const [pattern, paths] of propertyGroups) {
545
+ // Normalize types for comparison (treat "unknown | undefined" and "unknown" as similar)
546
+ const normalizedTypes = new Set(paths.map((p) => p.type.replace(/ \| undefined/g, '').replace(/ \| null/g, '')));
547
+ if (normalizedTypes.size > 1) {
548
+ inconsistencies.push({
549
+ propertyName: pattern,
550
+ paths: paths.map((p) => ({ ...p, stage: targetStage.stage })),
551
+ });
552
+ }
553
+ }
554
+ // Sort by number of different types (most inconsistent first)
555
+ inconsistencies.sort((a, b) => {
556
+ const aTypes = new Set(a.paths.map((p) => p.type)).size;
557
+ const bTypes = new Set(b.paths.map((p) => p.type)).size;
558
+ return bTypes - aTypes;
559
+ });
560
+ return inconsistencies;
561
+ }
562
+ /**
563
+ * Get a human-readable summary of changes between two stages.
564
+ */
565
+ getStageDiffSummary(entityName, fromStage, toStage) {
566
+ const trace = this.traces.get(entityName);
567
+ if (!trace)
568
+ return null;
569
+ const from = trace.stages.find((s) => s.stage === fromStage);
570
+ const to = trace.stages.find((s) => s.stage === toStage);
571
+ if (!from || !to)
572
+ return null;
573
+ const result = {
574
+ added: [],
575
+ removed: [],
576
+ typeChanged: [],
577
+ };
578
+ // Compare return value schemas (most common)
579
+ const fromSchema = from.data.returnValueSchema ?? {};
580
+ const toSchema = to.data.returnValueSchema ?? {};
581
+ const fromKeys = new Set(Object.keys(fromSchema));
582
+ const toKeys = new Set(Object.keys(toSchema));
583
+ for (const key of toKeys) {
584
+ if (!fromKeys.has(key)) {
585
+ result.added.push(`${key}: ${toSchema[key]}`);
586
+ }
587
+ else if (fromSchema[key] !== toSchema[key]) {
588
+ result.typeChanged.push({
589
+ path: key,
590
+ from: fromSchema[key],
591
+ to: toSchema[key],
592
+ });
593
+ }
594
+ }
595
+ for (const key of fromKeys) {
596
+ if (!toKeys.has(key)) {
597
+ result.removed.push(`${key}: ${fromSchema[key]}`);
598
+ }
599
+ }
600
+ return result;
601
+ }
602
+ /**
603
+ * Trace a schema transformation by capturing before/after and logging operations for all changes.
604
+ *
605
+ * This is a helper to wrap transformative functions like:
606
+ * - cleanKnownObjectFunctionsFromMapping
607
+ * - clearAttributesFromMapping
608
+ * - fillInDirectSchemaGapsAndUnknowns
609
+ * - deduplicateFunctionSchemas
610
+ *
611
+ * @param entityName - The entity being traced
612
+ * @param operationName - Name of the transformation (e.g., 'cleanKnownObjectFunctions')
613
+ * @param schema - The schema to transform (will be mutated)
614
+ * @param transformFn - The transformation function to run
615
+ * @param context - Optional context to include in operation logs
616
+ * @returns The schema (same reference, mutated)
617
+ */
618
+ traceSchemaTransform(entityName, operationName, schema, transformFn, context) {
619
+ if (!this.enabled) {
620
+ transformFn(schema);
621
+ return schema;
622
+ }
623
+ // Capture before state
624
+ const before = { ...schema };
625
+ // Run the transformation
626
+ transformFn(schema);
627
+ // Compute diff and log operations
628
+ const diff = computeSchemaDiff(before, schema);
629
+ // Log added paths
630
+ for (const [path, value] of Object.entries(diff.added)) {
631
+ this.operation(entityName, {
632
+ operation: operationName,
633
+ path,
634
+ before: undefined,
635
+ after: value,
636
+ context: { ...context, changeType: 'added' },
637
+ });
638
+ }
639
+ // Log removed paths
640
+ for (const [path, value] of Object.entries(diff.removed)) {
641
+ this.operation(entityName, {
642
+ operation: operationName,
643
+ path,
644
+ before: value,
645
+ after: undefined,
646
+ context: { ...context, changeType: 'removed' },
647
+ });
648
+ }
649
+ // Log changed paths
650
+ for (const [path, { from, to }] of Object.entries(diff.changed)) {
651
+ this.operation(entityName, {
652
+ operation: operationName,
653
+ path,
654
+ before: from,
655
+ after: to,
656
+ context: { ...context, changeType: 'changed' },
657
+ });
658
+ }
659
+ return schema;
660
+ }
661
+ /**
662
+ * Trace a schema transformation where the function returns a new schema (non-mutating).
663
+ *
664
+ * Use this for functions like deduplicateFunctionSchemas that return a new object
665
+ * rather than mutating the input.
666
+ *
667
+ * @param entityName - The entity being traced
668
+ * @param operationName - Name of the transformation
669
+ * @param before - The schema before transformation
670
+ * @param after - The schema after transformation
671
+ * @param context - Optional context to include in operation logs
672
+ */
673
+ traceSchemaTransformResult(entityName, operationName, before, after, context) {
674
+ if (!this.enabled)
675
+ return;
676
+ // Compute diff and log operations
677
+ const diff = computeSchemaDiff(before, after);
678
+ // Log added paths
679
+ for (const [path, value] of Object.entries(diff.added)) {
680
+ this.operation(entityName, {
681
+ operation: operationName,
682
+ path,
683
+ before: undefined,
684
+ after: value,
685
+ context: { ...context, changeType: 'added' },
686
+ });
687
+ }
688
+ // Log removed paths
689
+ for (const [path, value] of Object.entries(diff.removed)) {
690
+ this.operation(entityName, {
691
+ operation: operationName,
692
+ path,
693
+ before: value,
694
+ after: undefined,
695
+ context: { ...context, changeType: 'removed' },
696
+ });
697
+ }
698
+ // Log changed paths
699
+ for (const [path, { from, to }] of Object.entries(diff.changed)) {
700
+ this.operation(entityName, {
701
+ operation: operationName,
702
+ path,
703
+ before: from,
704
+ after: to,
705
+ context: { ...context, changeType: 'changed' },
706
+ });
707
+ }
708
+ }
709
+ /**
710
+ * Trace multiple schemas in a dependency schemas structure.
711
+ * Useful for tracing transformations that apply to all dependency schemas.
712
+ *
713
+ * @param entityName - The entity being traced
714
+ * @param operationName - Name of the transformation
715
+ * @param dependencySchemas - The dependency schemas structure
716
+ * @param transformFn - Function to apply to each schema (signature or returnValue)
717
+ * @param schemaType - Which schema to transform: 'signature', 'returnValue', or 'both'
718
+ */
719
+ traceDependencySchemaTransform(entityName, operationName, dependencySchemas, transformFn, schemaType = 'both') {
720
+ if (!this.enabled) {
721
+ // Still run the transform even if not tracing
722
+ for (const filePath in dependencySchemas) {
723
+ for (const depName in dependencySchemas[filePath]) {
724
+ const depSchema = dependencySchemas[filePath][depName];
725
+ if ((schemaType === 'signature' || schemaType === 'both') &&
726
+ depSchema.signatureSchema) {
727
+ transformFn(depSchema.signatureSchema);
728
+ }
729
+ if ((schemaType === 'returnValue' || schemaType === 'both') &&
730
+ depSchema.returnValueSchema) {
731
+ transformFn(depSchema.returnValueSchema);
732
+ }
733
+ }
734
+ }
735
+ return;
736
+ }
737
+ for (const filePath in dependencySchemas) {
738
+ for (const depName in dependencySchemas[filePath]) {
739
+ const depSchema = dependencySchemas[filePath][depName];
740
+ const depContext = { filePath, dependencyName: depName };
741
+ if ((schemaType === 'signature' || schemaType === 'both') &&
742
+ depSchema.signatureSchema) {
743
+ this.traceSchemaTransform(entityName, operationName, depSchema.signatureSchema, transformFn, { ...depContext, schemaType: 'signature' });
744
+ }
745
+ if ((schemaType === 'returnValue' || schemaType === 'both') &&
746
+ depSchema.returnValueSchema) {
747
+ this.traceSchemaTransform(entityName, operationName, depSchema.returnValueSchema, transformFn, { ...depContext, schemaType: 'returnValue' });
748
+ }
749
+ }
750
+ }
751
+ }
752
+ /**
753
+ * Trace changes to dependency schemas before/after a function call.
754
+ *
755
+ * Use this for functions like enrichArrayTypesFromChildSignatures or
756
+ * enrichUnknownTypesFromSourceEquivalencies that modify dependency schemas in place.
757
+ *
758
+ * @param entityName - The entity being traced
759
+ * @param operationName - Name of the transformation
760
+ * @param dependencySchemas - The dependency schemas to track
761
+ * @param transformFn - The function to run (should mutate dependencySchemas)
762
+ */
763
+ traceDependencySchemaChanges(entityName, operationName, dependencySchemas, transformFn) {
764
+ if (!this.enabled) {
765
+ transformFn();
766
+ return;
767
+ }
768
+ // Capture before state (deep copy of all schemas)
769
+ const beforeState = {};
770
+ for (const filePath in dependencySchemas) {
771
+ beforeState[filePath] = {};
772
+ for (const depName in dependencySchemas[filePath]) {
773
+ const depSchema = dependencySchemas[filePath][depName];
774
+ beforeState[filePath][depName] = {
775
+ sig: { ...(depSchema.signatureSchema || {}) },
776
+ rv: { ...(depSchema.returnValueSchema || {}) },
777
+ };
778
+ }
779
+ }
780
+ // Run the transformation
781
+ transformFn();
782
+ // Compare and log changes
783
+ for (const filePath in dependencySchemas) {
784
+ for (const depName in dependencySchemas[filePath]) {
785
+ const depSchema = dependencySchemas[filePath][depName];
786
+ const before = beforeState[filePath]?.[depName];
787
+ const context = { filePath, dependencyName: depName };
788
+ // Check signature schema changes
789
+ if (depSchema.signatureSchema) {
790
+ const sigBefore = before?.sig || {};
791
+ const diff = computeSchemaDiff(sigBefore, depSchema.signatureSchema);
792
+ for (const [path, value] of Object.entries(diff.added)) {
793
+ this.operation(entityName, {
794
+ operation: operationName,
795
+ path,
796
+ before: undefined,
797
+ after: value,
798
+ context: {
799
+ ...context,
800
+ schemaType: 'signature',
801
+ changeType: 'added',
802
+ },
803
+ });
804
+ }
805
+ for (const [path, { from, to }] of Object.entries(diff.changed)) {
806
+ this.operation(entityName, {
807
+ operation: operationName,
808
+ path,
809
+ before: from,
810
+ after: to,
811
+ context: {
812
+ ...context,
813
+ schemaType: 'signature',
814
+ changeType: 'changed',
815
+ },
816
+ });
817
+ }
818
+ }
819
+ // Check return value schema changes
820
+ if (depSchema.returnValueSchema) {
821
+ const rvBefore = before?.rv || {};
822
+ const diff = computeSchemaDiff(rvBefore, depSchema.returnValueSchema);
823
+ for (const [path, value] of Object.entries(diff.added)) {
824
+ this.operation(entityName, {
825
+ operation: operationName,
826
+ path,
827
+ before: undefined,
828
+ after: value,
829
+ context: {
830
+ ...context,
831
+ schemaType: 'returnValue',
832
+ changeType: 'added',
833
+ },
834
+ });
835
+ }
836
+ for (const [path, { from, to }] of Object.entries(diff.changed)) {
837
+ this.operation(entityName, {
838
+ operation: operationName,
839
+ path,
840
+ before: from,
841
+ after: to,
842
+ context: {
843
+ ...context,
844
+ schemaType: 'returnValue',
845
+ changeType: 'changed',
846
+ },
847
+ });
848
+ }
849
+ }
850
+ }
851
+ }
852
+ }
853
+ }
854
+ // ============================================================================
855
+ // Global Instance
856
+ // ============================================================================
857
+ /**
858
+ * Check if tracing is enabled via environment variable.
859
+ */
860
+ function isTracingEnabled() {
861
+ const envValue = process.env.CODEYAM_TRACE_TRANSFORMS;
862
+ return envValue === '1' || envValue === 'true';
863
+ }
864
+ /**
865
+ * Global tracer instance.
866
+ * Enabled via CODEYAM_TRACE_TRANSFORMS=1 environment variable.
867
+ * Output is always written to /tmp/codeyam/transform-trace.json
868
+ */
869
+ export const transformationTracer = new TransformationTracer({
870
+ enabled: isTracingEnabled(),
871
+ outputPath: '/tmp/codeyam/transform-trace.json',
872
+ });
873
+ // Auto-flush on process exit if tracing is enabled and there's data
874
+ process.on('beforeExit', () => {
875
+ if (transformationTracer.isEnabled()) {
876
+ transformationTracer.flush();
877
+ }
878
+ });
879
+ export default transformationTracer;
880
+ //# sourceMappingURL=TransformationTracer.js.map