@codeyam/codeyam-cli 0.1.0-staging.6e699e5 → 0.1.0-staging.79ef713

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 (437) 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 +7 -7
  4. package/analyzer-template/packages/ai/index.ts +10 -2
  5. package/analyzer-template/packages/ai/package.json +2 -2
  6. package/analyzer-template/packages/ai/src/lib/analyzeScope.ts +86 -18
  7. package/analyzer-template/packages/ai/src/lib/astScopes/astScopeAnalyzer.ts +67 -9
  8. package/analyzer-template/packages/ai/src/lib/astScopes/methodSemantics.ts +41 -17
  9. package/analyzer-template/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.ts +10 -17
  10. package/analyzer-template/packages/ai/src/lib/astScopes/processExpression.ts +308 -50
  11. package/analyzer-template/packages/ai/src/lib/astScopes/types.ts +15 -6
  12. package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +833 -243
  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 +54 -3
  17. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.ts +60 -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 +80 -5
  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 +393 -97
  23. package/analyzer-template/packages/ai/src/lib/generateEntityDataStructure.ts +58 -3
  24. package/analyzer-template/packages/ai/src/lib/generateEntityScenarioData.ts +283 -1
  25. package/analyzer-template/packages/ai/src/lib/generateEntityScenarios.ts +9 -5
  26. package/analyzer-template/packages/ai/src/lib/generateExecutionFlows.ts +11 -3
  27. package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromConditionalEffects.ts +1 -1
  28. package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromConditionals.ts +297 -7
  29. package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromJsxUsages.ts +1 -1
  30. package/analyzer-template/packages/ai/src/lib/isolateScopes.ts +51 -3
  31. package/analyzer-template/packages/ai/src/lib/mergeStatements.ts +90 -96
  32. package/analyzer-template/packages/ai/src/lib/promptGenerators/gatherAttributesMap.ts +10 -7
  33. package/analyzer-template/packages/ai/src/lib/resolvePathToControllable.ts +25 -13
  34. package/analyzer-template/packages/ai/src/lib/worker/SerializableDataStructure.ts +4 -3
  35. package/analyzer-template/packages/ai/src/lib/worker/analyzeScopeWorker.ts +114 -2
  36. package/analyzer-template/packages/analyze/index.ts +2 -0
  37. package/analyzer-template/packages/analyze/src/lib/FileAnalyzer.ts +65 -59
  38. package/analyzer-template/packages/analyze/src/lib/ProjectAnalyzer.ts +113 -26
  39. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllDeclaredEntityNodes.ts +19 -0
  40. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllEntityNodes.ts +19 -0
  41. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllExports.ts +11 -0
  42. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getImportsAnalysis.ts +8 -0
  43. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getResolvedModule.ts +49 -1
  44. package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getSourceFilesForAllImports.ts +2 -1
  45. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +71 -9
  46. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +19 -4
  47. package/analyzer-template/packages/analyze/src/lib/files/analyze/dependencyResolver.ts +6 -0
  48. package/analyzer-template/packages/analyze/src/lib/files/analyze/gatherEntityMap.ts +4 -2
  49. package/analyzer-template/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.ts +0 -3
  50. package/analyzer-template/packages/analyze/src/lib/files/analyzeRemixRoute.ts +4 -5
  51. package/analyzer-template/packages/analyze/src/lib/files/getImportedExports.ts +14 -12
  52. package/analyzer-template/packages/analyze/src/lib/files/scenarios/TransformationTracer.ts +1315 -0
  53. package/analyzer-template/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.ts +61 -13
  54. package/analyzer-template/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.ts +37 -0
  55. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +229 -19
  56. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.ts +117 -9
  57. package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +459 -39
  58. package/analyzer-template/packages/analyze/src/lib/files/scenarios/propagateArrayItemSchemas.ts +474 -0
  59. package/analyzer-template/packages/analyze/src/lib/files/setImportedExports.ts +2 -1
  60. package/analyzer-template/packages/analyze/src/lib/index.ts +1 -0
  61. package/analyzer-template/packages/analyze/src/lib/utils/getFileByPath.ts +19 -0
  62. package/analyzer-template/packages/aws/package.json +1 -1
  63. package/analyzer-template/packages/database/package.json +1 -1
  64. package/analyzer-template/packages/database/src/lib/kysely/db.ts +8 -1
  65. package/analyzer-template/packages/database/src/lib/kysely/tables/commitsTable.ts +6 -0
  66. package/analyzer-template/packages/database/src/lib/loadAnalyses.ts +58 -1
  67. package/analyzer-template/packages/database/src/lib/loadAnalysis.ts +13 -0
  68. package/analyzer-template/packages/database/src/lib/loadBranch.ts +16 -1
  69. package/analyzer-template/packages/database/src/lib/loadCommit.ts +11 -0
  70. package/analyzer-template/packages/database/src/lib/loadCommits.ts +28 -0
  71. package/analyzer-template/packages/database/src/lib/loadEntities.ts +26 -3
  72. package/analyzer-template/packages/database/src/lib/loadEntityBranches.ts +12 -0
  73. package/analyzer-template/packages/database/src/lib/updateCommitMetadata.ts +7 -14
  74. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts.map +1 -1
  75. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js +8 -1
  76. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js.map +1 -1
  77. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/commitsTable.d.ts +1 -0
  78. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/commitsTable.d.ts.map +1 -1
  79. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/commitsTable.js +3 -0
  80. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/commitsTable.js.map +1 -1
  81. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalyses.d.ts +2 -0
  82. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalyses.d.ts.map +1 -1
  83. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalyses.js +45 -2
  84. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalyses.js.map +1 -1
  85. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.d.ts.map +1 -1
  86. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.js +8 -0
  87. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.js.map +1 -1
  88. package/analyzer-template/packages/github/dist/database/src/lib/loadBranch.js +11 -1
  89. package/analyzer-template/packages/github/dist/database/src/lib/loadBranch.js.map +1 -1
  90. package/analyzer-template/packages/github/dist/database/src/lib/loadCommit.d.ts.map +1 -1
  91. package/analyzer-template/packages/github/dist/database/src/lib/loadCommit.js +7 -0
  92. package/analyzer-template/packages/github/dist/database/src/lib/loadCommit.js.map +1 -1
  93. package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.d.ts +3 -1
  94. package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.d.ts.map +1 -1
  95. package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.js +22 -1
  96. package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.js.map +1 -1
  97. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.d.ts +3 -1
  98. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.d.ts.map +1 -1
  99. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.js +23 -4
  100. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.js.map +1 -1
  101. package/analyzer-template/packages/github/dist/database/src/lib/loadEntityBranches.d.ts.map +1 -1
  102. package/analyzer-template/packages/github/dist/database/src/lib/loadEntityBranches.js +9 -0
  103. package/analyzer-template/packages/github/dist/database/src/lib/loadEntityBranches.js.map +1 -1
  104. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.d.ts +2 -2
  105. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.d.ts.map +1 -1
  106. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.js +5 -4
  107. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.js.map +1 -1
  108. package/analyzer-template/packages/github/dist/types/src/types/Commit.d.ts +2 -0
  109. package/analyzer-template/packages/github/dist/types/src/types/Commit.d.ts.map +1 -1
  110. package/analyzer-template/packages/github/dist/types/src/types/ProjectMetadata.d.ts +3 -0
  111. package/analyzer-template/packages/github/dist/types/src/types/ProjectMetadata.d.ts.map +1 -1
  112. package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts +5 -5
  113. package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
  114. package/analyzer-template/packages/github/dist/types/src/types/ScopeAnalysis.d.ts +6 -1
  115. package/analyzer-template/packages/github/dist/types/src/types/ScopeAnalysis.d.ts.map +1 -1
  116. package/analyzer-template/packages/github/package.json +1 -1
  117. package/analyzer-template/packages/types/src/types/Commit.ts +2 -0
  118. package/analyzer-template/packages/types/src/types/ProjectMetadata.ts +1 -0
  119. package/analyzer-template/packages/types/src/types/ScenariosDataStructure.ts +6 -5
  120. package/analyzer-template/packages/types/src/types/ScopeAnalysis.ts +6 -1
  121. package/analyzer-template/packages/utils/dist/types/src/types/Commit.d.ts +2 -0
  122. package/analyzer-template/packages/utils/dist/types/src/types/Commit.d.ts.map +1 -1
  123. package/analyzer-template/packages/utils/dist/types/src/types/ProjectMetadata.d.ts +3 -0
  124. package/analyzer-template/packages/utils/dist/types/src/types/ProjectMetadata.d.ts.map +1 -1
  125. package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts +5 -5
  126. package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
  127. package/analyzer-template/packages/utils/dist/types/src/types/ScopeAnalysis.d.ts +6 -1
  128. package/analyzer-template/packages/utils/dist/types/src/types/ScopeAnalysis.d.ts.map +1 -1
  129. package/analyzer-template/playwright/capture.ts +20 -8
  130. package/analyzer-template/playwright/captureStatic.ts +1 -1
  131. package/analyzer-template/project/analyzeBaselineCommit.ts +5 -0
  132. package/analyzer-template/project/analyzeRegularCommit.ts +5 -0
  133. package/analyzer-template/project/captureLibraryFunctionDirect.ts +29 -26
  134. package/analyzer-template/project/constructMockCode.ts +90 -10
  135. package/analyzer-template/project/createEntitiesAndSortFiles.ts +83 -0
  136. package/analyzer-template/project/loadReadyToBeCaptured.ts +65 -41
  137. package/analyzer-template/project/orchestrateCapture/AwsCaptureTaskRunner.ts +12 -4
  138. package/analyzer-template/project/orchestrateCapture/SequentialCaptureTaskRunner.ts +11 -6
  139. package/analyzer-template/project/orchestrateCapture/taskRunner.ts +4 -2
  140. package/analyzer-template/project/orchestrateCapture.ts +45 -6
  141. package/analyzer-template/project/start.ts +35 -11
  142. package/analyzer-template/project/writeMockDataTsx.ts +181 -8
  143. package/analyzer-template/project/writeScenarioComponents.ts +103 -12
  144. package/analyzer-template/project/writeSimpleRoot.ts +21 -11
  145. package/analyzer-template/scripts/comboWorkerLoop.cjs +98 -50
  146. package/background/src/lib/virtualized/project/analyzeBaselineCommit.js +5 -0
  147. package/background/src/lib/virtualized/project/analyzeBaselineCommit.js.map +1 -1
  148. package/background/src/lib/virtualized/project/analyzeRegularCommit.js +5 -0
  149. package/background/src/lib/virtualized/project/analyzeRegularCommit.js.map +1 -1
  150. package/background/src/lib/virtualized/project/captureLibraryFunctionDirect.js +3 -3
  151. package/background/src/lib/virtualized/project/captureLibraryFunctionDirect.js.map +1 -1
  152. package/background/src/lib/virtualized/project/constructMockCode.js +75 -4
  153. package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
  154. package/background/src/lib/virtualized/project/createEntitiesAndSortFiles.js +73 -1
  155. package/background/src/lib/virtualized/project/createEntitiesAndSortFiles.js.map +1 -1
  156. package/background/src/lib/virtualized/project/loadReadyToBeCaptured.js +19 -8
  157. package/background/src/lib/virtualized/project/loadReadyToBeCaptured.js.map +1 -1
  158. package/background/src/lib/virtualized/project/orchestrateCapture/AwsCaptureTaskRunner.js +2 -2
  159. package/background/src/lib/virtualized/project/orchestrateCapture/AwsCaptureTaskRunner.js.map +1 -1
  160. package/background/src/lib/virtualized/project/orchestrateCapture/SequentialCaptureTaskRunner.js +4 -4
  161. package/background/src/lib/virtualized/project/orchestrateCapture/SequentialCaptureTaskRunner.js.map +1 -1
  162. package/background/src/lib/virtualized/project/orchestrateCapture.js +38 -6
  163. package/background/src/lib/virtualized/project/orchestrateCapture.js.map +1 -1
  164. package/background/src/lib/virtualized/project/start.js +32 -11
  165. package/background/src/lib/virtualized/project/start.js.map +1 -1
  166. package/background/src/lib/virtualized/project/writeMockDataTsx.js +162 -4
  167. package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
  168. package/background/src/lib/virtualized/project/writeScenarioComponents.js +85 -15
  169. package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
  170. package/background/src/lib/virtualized/project/writeSimpleRoot.js +21 -11
  171. package/background/src/lib/virtualized/project/writeSimpleRoot.js.map +1 -1
  172. package/codeyam-cli/scripts/apply-setup.js +180 -0
  173. package/codeyam-cli/scripts/apply-setup.js.map +1 -1
  174. package/codeyam-cli/src/cli.js +2 -0
  175. package/codeyam-cli/src/cli.js.map +1 -1
  176. package/codeyam-cli/src/commands/debug.js +7 -5
  177. package/codeyam-cli/src/commands/debug.js.map +1 -1
  178. package/codeyam-cli/src/commands/memory.js +264 -0
  179. package/codeyam-cli/src/commands/memory.js.map +1 -0
  180. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js +2 -2
  181. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js.map +1 -1
  182. package/codeyam-cli/src/utils/analysisRunner.js +21 -2
  183. package/codeyam-cli/src/utils/analysisRunner.js.map +1 -1
  184. package/codeyam-cli/src/utils/backgroundServer.js +4 -0
  185. package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
  186. package/codeyam-cli/src/utils/install-skills.js +55 -10
  187. package/codeyam-cli/src/utils/install-skills.js.map +1 -1
  188. package/codeyam-cli/src/utils/queue/job.js +4 -0
  189. package/codeyam-cli/src/utils/queue/job.js.map +1 -1
  190. package/codeyam-cli/src/utils/ruleReflection/__tests__/confusionDetector.test.js +82 -0
  191. package/codeyam-cli/src/utils/ruleReflection/__tests__/confusionDetector.test.js.map +1 -0
  192. package/codeyam-cli/src/utils/ruleReflection/__tests__/contextBuilder.test.js +230 -0
  193. package/codeyam-cli/src/utils/ruleReflection/__tests__/contextBuilder.test.js.map +1 -0
  194. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/assertRules.js +67 -0
  195. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/assertRules.js.map +1 -0
  196. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/captureFixture.js +105 -0
  197. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/captureFixture.js.map +1 -0
  198. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/loadCapturedFixture.js +34 -0
  199. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/loadCapturedFixture.js.map +1 -0
  200. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/runClaude.js +162 -0
  201. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/runClaude.js.map +1 -0
  202. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js +75 -0
  203. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js.map +1 -0
  204. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js +285 -0
  205. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js.map +1 -0
  206. package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js +115 -0
  207. package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js.map +1 -0
  208. package/codeyam-cli/src/utils/ruleReflection/__tests__/transcriptParser.test.js +127 -0
  209. package/codeyam-cli/src/utils/ruleReflection/__tests__/transcriptParser.test.js.map +1 -0
  210. package/codeyam-cli/src/utils/ruleReflection/confusionDetector.js +50 -0
  211. package/codeyam-cli/src/utils/ruleReflection/confusionDetector.js.map +1 -0
  212. package/codeyam-cli/src/utils/ruleReflection/contextBuilder.js +116 -0
  213. package/codeyam-cli/src/utils/ruleReflection/contextBuilder.js.map +1 -0
  214. package/codeyam-cli/src/utils/ruleReflection/index.js +5 -0
  215. package/codeyam-cli/src/utils/ruleReflection/index.js.map +1 -0
  216. package/codeyam-cli/src/utils/ruleReflection/promptBuilder.js +44 -0
  217. package/codeyam-cli/src/utils/ruleReflection/promptBuilder.js.map +1 -0
  218. package/codeyam-cli/src/utils/ruleReflection/transcriptParser.js +85 -0
  219. package/codeyam-cli/src/utils/ruleReflection/transcriptParser.js.map +1 -0
  220. package/codeyam-cli/src/utils/ruleReflection/types.js +5 -0
  221. package/codeyam-cli/src/utils/ruleReflection/types.js.map +1 -0
  222. package/codeyam-cli/src/utils/rules/__tests__/ruleState.test.js +293 -0
  223. package/codeyam-cli/src/utils/rules/__tests__/ruleState.test.js.map +1 -0
  224. package/codeyam-cli/src/utils/rules/index.js +6 -0
  225. package/codeyam-cli/src/utils/rules/index.js.map +1 -0
  226. package/codeyam-cli/src/utils/rules/parser.js +78 -0
  227. package/codeyam-cli/src/utils/rules/parser.js.map +1 -0
  228. package/codeyam-cli/src/utils/rules/pathMatcher.js +18 -0
  229. package/codeyam-cli/src/utils/rules/pathMatcher.js.map +1 -0
  230. package/codeyam-cli/src/utils/rules/ruleState.js +150 -0
  231. package/codeyam-cli/src/utils/rules/ruleState.js.map +1 -0
  232. package/codeyam-cli/src/utils/rules/staleness.js +137 -0
  233. package/codeyam-cli/src/utils/rules/staleness.js.map +1 -0
  234. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +1 -1
  235. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js.map +1 -1
  236. package/codeyam-cli/src/webserver/app/lib/database.js +7 -3
  237. package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
  238. package/codeyam-cli/src/webserver/build/client/assets/CopyButton-CA3JxPb7.js +1 -0
  239. package/codeyam-cli/src/webserver/build/client/assets/EntityItem-B86KKU7e.js +11 -0
  240. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeBadge-DLqD3qNt.js → EntityTypeBadge-B5ctlSYt.js} +1 -1
  241. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeIcon-Ba2JVPzP.js → EntityTypeIcon-BqY8gDAW.js} +1 -1
  242. package/codeyam-cli/src/webserver/build/client/assets/{InlineSpinner-C8lyxW9k.js → InlineSpinner-ClaLpuOo.js} +1 -1
  243. package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-aht4aafF.js → InteractivePreview-BDhPilK7.js} +2 -2
  244. package/codeyam-cli/src/webserver/build/client/assets/{LibraryFunctionPreview-CVtiBnY5.js → LibraryFunctionPreview-VeqEBv9v.js} +1 -1
  245. package/codeyam-cli/src/webserver/build/client/assets/{LoadingDots-B0GLXMsr.js → LoadingDots-Bs7Nn1Jr.js} +1 -1
  246. package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-xgeCVgSM.js → LogViewer-Bm3PmcCz.js} +1 -1
  247. package/codeyam-cli/src/webserver/build/client/assets/{ReportIssueModal-D4TZhLuw.js → ReportIssueModal-C6PKeMYR.js} +3 -13
  248. package/codeyam-cli/src/webserver/build/client/assets/{SafeScreenshot-DuDvi0jm.js → SafeScreenshot-Gq3Ocjo6.js} +1 -1
  249. package/codeyam-cli/src/webserver/build/client/assets/{ScenarioViewer-DEx02QDa.js → ScenarioViewer-BNLaXBHR.js} +3 -3
  250. package/codeyam-cli/src/webserver/build/client/assets/{TruncatedFilePath-DyFZkK0l.js → TruncatedFilePath-CiwXDxLh.js} +1 -1
  251. package/codeyam-cli/src/webserver/build/client/assets/{_index-BwqWJOgH.js → _index-B3TDXxnk.js} +1 -1
  252. package/codeyam-cli/src/webserver/build/client/assets/{activity.(_tab)-DoLIqZX2.js → activity.(_tab)-BtBFH820.js} +6 -16
  253. package/codeyam-cli/src/webserver/build/client/assets/agent-transcripts-DfKzxuoe.js +11 -0
  254. package/codeyam-cli/src/webserver/build/client/assets/api.memory-profile-l0sNRNKZ.js +1 -0
  255. package/codeyam-cli/src/webserver/build/client/assets/api.save-fixture-l0sNRNKZ.js +1 -0
  256. package/codeyam-cli/src/webserver/build/client/assets/book-open-PttOB2SF.js +6 -0
  257. package/codeyam-cli/src/webserver/build/client/assets/{chevron-down-Cx24_aWc.js → chevron-down-TJp6ofnp.js} +1 -1
  258. package/codeyam-cli/src/webserver/build/client/assets/{chunk-EPOLDU6W-CXRTFQ3F.js → chunk-JZWAC4HX-JE9ZIoBl.js} +12 -12
  259. package/codeyam-cli/src/webserver/build/client/assets/{circle-check-BOARzkeR.js → circle-check-CXhHQYrI.js} +1 -1
  260. package/codeyam-cli/src/webserver/build/client/assets/copy-6y9ALfGT.js +11 -0
  261. package/codeyam-cli/src/webserver/build/client/assets/{createLucideIcon-BdhJEx6B.js → createLucideIcon-Ca9fAY46.js} +1 -1
  262. package/codeyam-cli/src/webserver/build/client/assets/dev.empty-C5lqplTC.js +1 -0
  263. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-C2N4Op8e.js → entity._sha._-n38keI1k.js} +10 -10
  264. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.fullscreen-DavjRmOY.js → entity._sha.scenarios._scenarioId.fullscreen-CBoafmVs.js} +1 -1
  265. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.create-scenario-D1T4TGjf.js → entity._sha_.create-scenario-DGgZjdFg.js} +1 -1
  266. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.edit._scenarioId-CTBG2mmz.js → entity._sha_.edit._scenarioId-38yPijoD.js} +1 -1
  267. package/codeyam-cli/src/webserver/build/client/assets/{entry.client-CS2cb_eZ.js → entry.client-BSHEfydn.js} +1 -1
  268. package/codeyam-cli/src/webserver/build/client/assets/{fileTableUtils-DMJ7zii9.js → fileTableUtils-DCPhhSMo.js} +1 -1
  269. package/codeyam-cli/src/webserver/build/client/assets/files-0N0YJQv7.js +1 -0
  270. package/codeyam-cli/src/webserver/build/client/assets/{git-B4RJRvYB.js → git-DXnyr8uP.js} +8 -8
  271. package/codeyam-cli/src/webserver/build/client/assets/globals-Bh6jH0cL.css +1 -0
  272. package/codeyam-cli/src/webserver/build/client/assets/{index-lzqtyFU8.js → index-CcsFv748.js} +1 -1
  273. package/codeyam-cli/src/webserver/build/client/assets/{index-B1h680n5.js → index-ChN9-fAY.js} +1 -1
  274. package/codeyam-cli/src/webserver/build/client/assets/labs-CdVUfvji.js +1 -0
  275. package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-B7B9V-bu.js → loader-circle-CTqLEAGU.js} +1 -1
  276. package/codeyam-cli/src/webserver/build/client/assets/manifest-87319d0f.js +1 -0
  277. package/codeyam-cli/src/webserver/build/client/assets/memory-CPIDnDEj.js +76 -0
  278. package/codeyam-cli/src/webserver/build/client/assets/pause-D6vreykR.js +11 -0
  279. package/codeyam-cli/src/webserver/build/client/assets/root-D6oziHts.js +62 -0
  280. package/codeyam-cli/src/webserver/build/client/assets/{search-CxXUmBSd.js → search-B8VUL8nl.js} +1 -1
  281. package/codeyam-cli/src/webserver/build/client/assets/{settings-CS5f3WzT.js → settings-eBI36Yv5.js} +1 -1
  282. package/codeyam-cli/src/webserver/build/client/assets/{simulations-DwFIBT09.js → simulations-CPoAg7Zo.js} +1 -1
  283. package/codeyam-cli/src/webserver/build/client/assets/terminal-BrCP7uQo.js +11 -0
  284. package/codeyam-cli/src/webserver/build/client/assets/{triangle-alert-B6LgvRJg.js → triangle-alert-BZz2NjYa.js} +1 -1
  285. package/codeyam-cli/src/webserver/build/client/assets/{useCustomSizes-C1v1PQzo.js → useCustomSizes-DNwUduNu.js} +1 -1
  286. package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-aSv48UbS.js → useLastLogLine-COky1GVF.js} +1 -1
  287. package/codeyam-cli/src/webserver/build/client/assets/{useReportContext-DYxHZQuP.js → useReportContext-CpZgwliL.js} +1 -1
  288. package/codeyam-cli/src/webserver/build/client/assets/{useToast-mBRpZPiu.js → useToast-Bv9JFvUO.js} +1 -1
  289. package/codeyam-cli/src/webserver/build/server/assets/index-9ox9LcrG.js +1 -0
  290. package/codeyam-cli/src/webserver/build/server/assets/server-build-Cq5Vqcob.js +260 -0
  291. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  292. package/codeyam-cli/src/webserver/build-info.json +5 -5
  293. package/codeyam-cli/templates/{codeyam-power-rules-hook.sh → codeyam-memory-hook.sh} +12 -13
  294. package/codeyam-cli/templates/codeyam:diagnose.md +178 -25
  295. package/codeyam-cli/templates/codeyam:memory.md +404 -0
  296. package/codeyam-cli/templates/codeyam:new-rule.md +2 -2
  297. package/codeyam-cli/templates/rule-notification-hook.py +56 -0
  298. package/codeyam-cli/templates/rule-reflection-hook.py +590 -0
  299. package/codeyam-cli/templates/rules-instructions.md +123 -0
  300. package/package.json +8 -6
  301. package/packages/ai/index.js +3 -2
  302. package/packages/ai/index.js.map +1 -1
  303. package/packages/ai/src/lib/analyzeScope.js +68 -13
  304. package/packages/ai/src/lib/analyzeScope.js.map +1 -1
  305. package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js +54 -8
  306. package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js.map +1 -1
  307. package/packages/ai/src/lib/astScopes/methodSemantics.js +41 -17
  308. package/packages/ai/src/lib/astScopes/methodSemantics.js.map +1 -1
  309. package/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.js +10 -14
  310. package/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.js.map +1 -1
  311. package/packages/ai/src/lib/astScopes/processExpression.js +239 -43
  312. package/packages/ai/src/lib/astScopes/processExpression.js.map +1 -1
  313. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +650 -166
  314. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
  315. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js +5 -1
  316. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js.map +1 -1
  317. package/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.js +13 -3
  318. package/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.js.map +1 -1
  319. package/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.js +6 -4
  320. package/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.js.map +1 -1
  321. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js +52 -3
  322. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js.map +1 -1
  323. package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js +55 -11
  324. package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js.map +1 -1
  325. package/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.js +63 -0
  326. package/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.js.map +1 -0
  327. package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js +73 -5
  328. package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js.map +1 -1
  329. package/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.js +173 -0
  330. package/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.js.map +1 -0
  331. package/packages/ai/src/lib/dataStructure/helpers/deduplicateFunctionSchemas.js +37 -20
  332. package/packages/ai/src/lib/dataStructure/helpers/deduplicateFunctionSchemas.js.map +1 -1
  333. package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js +333 -86
  334. package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js.map +1 -1
  335. package/packages/ai/src/lib/generateEntityDataStructure.js +46 -2
  336. package/packages/ai/src/lib/generateEntityDataStructure.js.map +1 -1
  337. package/packages/ai/src/lib/generateEntityScenarioData.js +205 -1
  338. package/packages/ai/src/lib/generateEntityScenarioData.js.map +1 -1
  339. package/packages/ai/src/lib/generateEntityScenarios.js +7 -1
  340. package/packages/ai/src/lib/generateEntityScenarios.js.map +1 -1
  341. package/packages/ai/src/lib/generateExecutionFlows.js +10 -2
  342. package/packages/ai/src/lib/generateExecutionFlows.js.map +1 -1
  343. package/packages/ai/src/lib/generateExecutionFlowsFromConditionals.js +209 -3
  344. package/packages/ai/src/lib/generateExecutionFlowsFromConditionals.js.map +1 -1
  345. package/packages/ai/src/lib/isolateScopes.js +39 -3
  346. package/packages/ai/src/lib/isolateScopes.js.map +1 -1
  347. package/packages/ai/src/lib/mergeStatements.js +70 -51
  348. package/packages/ai/src/lib/mergeStatements.js.map +1 -1
  349. package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js +10 -4
  350. package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js.map +1 -1
  351. package/packages/ai/src/lib/resolvePathToControllable.js +24 -14
  352. package/packages/ai/src/lib/resolvePathToControllable.js.map +1 -1
  353. package/packages/ai/src/lib/worker/SerializableDataStructure.js.map +1 -1
  354. package/packages/ai/src/lib/worker/analyzeScopeWorker.js +94 -1
  355. package/packages/ai/src/lib/worker/analyzeScopeWorker.js.map +1 -1
  356. package/packages/analyze/index.js +1 -0
  357. package/packages/analyze/index.js.map +1 -1
  358. package/packages/analyze/src/lib/FileAnalyzer.js +60 -36
  359. package/packages/analyze/src/lib/FileAnalyzer.js.map +1 -1
  360. package/packages/analyze/src/lib/ProjectAnalyzer.js +96 -26
  361. package/packages/analyze/src/lib/ProjectAnalyzer.js.map +1 -1
  362. package/packages/analyze/src/lib/asts/sourceFiles/getAllDeclaredEntityNodes.js +14 -0
  363. package/packages/analyze/src/lib/asts/sourceFiles/getAllDeclaredEntityNodes.js.map +1 -1
  364. package/packages/analyze/src/lib/asts/sourceFiles/getAllEntityNodes.js +14 -0
  365. package/packages/analyze/src/lib/asts/sourceFiles/getAllEntityNodes.js.map +1 -1
  366. package/packages/analyze/src/lib/asts/sourceFiles/getAllExports.js +6 -0
  367. package/packages/analyze/src/lib/asts/sourceFiles/getAllExports.js.map +1 -1
  368. package/packages/analyze/src/lib/asts/sourceFiles/getImportsAnalysis.js +6 -0
  369. package/packages/analyze/src/lib/asts/sourceFiles/getImportsAnalysis.js.map +1 -1
  370. package/packages/analyze/src/lib/asts/sourceFiles/getResolvedModule.js +39 -1
  371. package/packages/analyze/src/lib/asts/sourceFiles/getResolvedModule.js.map +1 -1
  372. package/packages/analyze/src/lib/asts/sourceFiles/getSourceFilesForAllImports.js +2 -1
  373. package/packages/analyze/src/lib/asts/sourceFiles/getSourceFilesForAllImports.js.map +1 -1
  374. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +54 -6
  375. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
  376. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +17 -4
  377. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
  378. package/packages/analyze/src/lib/files/analyze/dependencyResolver.js +5 -0
  379. package/packages/analyze/src/lib/files/analyze/dependencyResolver.js.map +1 -1
  380. package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js +2 -1
  381. package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js.map +1 -1
  382. package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js +0 -3
  383. package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js.map +1 -1
  384. package/packages/analyze/src/lib/files/analyzeRemixRoute.js +3 -2
  385. package/packages/analyze/src/lib/files/analyzeRemixRoute.js.map +1 -1
  386. package/packages/analyze/src/lib/files/getImportedExports.js +11 -7
  387. package/packages/analyze/src/lib/files/getImportedExports.js.map +1 -1
  388. package/packages/analyze/src/lib/files/scenarios/TransformationTracer.js +880 -0
  389. package/packages/analyze/src/lib/files/scenarios/TransformationTracer.js.map +1 -0
  390. package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js +56 -10
  391. package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js.map +1 -1
  392. package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js +33 -8
  393. package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js.map +1 -1
  394. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +150 -17
  395. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
  396. package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js +56 -8
  397. package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js.map +1 -1
  398. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +399 -31
  399. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
  400. package/packages/analyze/src/lib/files/setImportedExports.js +2 -1
  401. package/packages/analyze/src/lib/files/setImportedExports.js.map +1 -1
  402. package/packages/analyze/src/lib/index.js +1 -0
  403. package/packages/analyze/src/lib/index.js.map +1 -1
  404. package/packages/analyze/src/lib/utils/getFileByPath.js +12 -0
  405. package/packages/analyze/src/lib/utils/getFileByPath.js.map +1 -0
  406. package/packages/database/src/lib/kysely/db.js +8 -1
  407. package/packages/database/src/lib/kysely/db.js.map +1 -1
  408. package/packages/database/src/lib/kysely/tables/commitsTable.js +3 -0
  409. package/packages/database/src/lib/kysely/tables/commitsTable.js.map +1 -1
  410. package/packages/database/src/lib/loadAnalyses.js +45 -2
  411. package/packages/database/src/lib/loadAnalyses.js.map +1 -1
  412. package/packages/database/src/lib/loadAnalysis.js +8 -0
  413. package/packages/database/src/lib/loadAnalysis.js.map +1 -1
  414. package/packages/database/src/lib/loadBranch.js +11 -1
  415. package/packages/database/src/lib/loadBranch.js.map +1 -1
  416. package/packages/database/src/lib/loadCommit.js +7 -0
  417. package/packages/database/src/lib/loadCommit.js.map +1 -1
  418. package/packages/database/src/lib/loadCommits.js +22 -1
  419. package/packages/database/src/lib/loadCommits.js.map +1 -1
  420. package/packages/database/src/lib/loadEntities.js +23 -4
  421. package/packages/database/src/lib/loadEntities.js.map +1 -1
  422. package/packages/database/src/lib/loadEntityBranches.js +9 -0
  423. package/packages/database/src/lib/loadEntityBranches.js.map +1 -1
  424. package/packages/database/src/lib/updateCommitMetadata.js +5 -4
  425. package/packages/database/src/lib/updateCommitMetadata.js.map +1 -1
  426. package/codeyam-cli/src/webserver/build/client/assets/EntityItem-BXhEawa3.js +0 -1
  427. package/codeyam-cli/src/webserver/build/client/assets/dev.empty-BRb-0kQl.js +0 -1
  428. package/codeyam-cli/src/webserver/build/client/assets/files-Cs4MdYtv.js +0 -1
  429. package/codeyam-cli/src/webserver/build/client/assets/git-commit-horizontal-CysbcZxi.js +0 -6
  430. package/codeyam-cli/src/webserver/build/client/assets/globals-DMUaGAqV.css +0 -1
  431. package/codeyam-cli/src/webserver/build/client/assets/manifest-f874c610.js +0 -1
  432. package/codeyam-cli/src/webserver/build/client/assets/root-Bz5TunQg.js +0 -57
  433. package/codeyam-cli/src/webserver/build/client/assets/rules-hEkvVw2-.js +0 -97
  434. package/codeyam-cli/src/webserver/build/server/assets/index-967OuJoF.js +0 -1
  435. package/codeyam-cli/src/webserver/build/server/assets/server-build-DRTmerg9.js +0 -257
  436. package/codeyam-cli/templates/codeyam:power-rules.md +0 -447
  437. /package/codeyam-cli/src/webserver/build/client/assets/{api.rules-l0sNRNKZ.js → api.agent-transcripts-l0sNRNKZ.js} +0 -0
@@ -7,6 +7,28 @@ import {
7
7
  import { Analysis, Project } from '~codeyam/types';
8
8
  import { LazyFileStore } from './LazyFileStore';
9
9
 
10
+ const DB_CONCURRENCY = 1;
11
+
12
+ async function mapWithConcurrency<T, R>(
13
+ items: T[],
14
+ fn: (item: T) => Promise<R>,
15
+ concurrency: number,
16
+ ): Promise<R[]> {
17
+ const results: R[] = new Array(items.length);
18
+ let index = 0;
19
+ const workers = Array.from(
20
+ { length: Math.min(concurrency, items.length) },
21
+ async () => {
22
+ while (index < items.length) {
23
+ const i = index++;
24
+ results[i] = await fn(items[i]);
25
+ }
26
+ },
27
+ );
28
+ await Promise.all(workers);
29
+ return results;
30
+ }
31
+
10
32
  interface LoadReadyToBeCapturedArgs {
11
33
  project: Project;
12
34
  branchCommitSha?: string;
@@ -77,8 +99,9 @@ async function gatherAllReferencedEntities(
77
99
  byFilePath.get(filePath)!.push(name);
78
100
  }
79
101
 
80
- // Batch load entities by file path
81
- const loadPromises = Array.from(byFilePath.entries()).map(
102
+ // Batch load entities by file path (concurrency-limited to avoid exhausting DB connections)
103
+ const results = await mapWithConcurrency(
104
+ Array.from(byFilePath.entries()),
82
105
  async ([filePath, names]) => {
83
106
  const entities = await loadEntities({
84
107
  projectId: project.id,
@@ -106,9 +129,8 @@ async function gatherAllReferencedEntities(
106
129
  return false;
107
130
  });
108
131
  },
132
+ DB_CONCURRENCY,
109
133
  );
110
-
111
- const results = await Promise.all(loadPromises);
112
134
  const loadedEntities = results.flat();
113
135
 
114
136
  // Add loaded entities to context
@@ -198,48 +220,50 @@ export default async function loadReadyToBeCaptured({
198
220
  foundNewDependencies = false;
199
221
  const currentBatch = Array.from(stillNeeded);
200
222
 
201
- // Load analyses for current batch
202
- const loadPromises = currentBatch.map(async (keyString) => {
203
- const [filePath, entityName] = keyString.split(':');
204
-
205
- // Find the file ID for this file path - use fileStore for O(1) lookup when available
206
- const file = fileStore
207
- ? fileStore.getByPath(filePath)
208
- : project.files.find((f) => f.path === filePath);
209
- if (!file) {
210
- console.log(
211
- `CodeYam Warning: File not found in project: ${filePath} for key ${keyString}`,
212
- );
213
- return null;
214
- }
215
-
216
- try {
217
- const analysis = await loadAnalysis({
218
- projectId: project.id,
219
- fileId: file.id,
220
- entityName,
221
- includeScenarios: isFirstBatch, // Only include scenarios for the root analyses
222
- });
223
-
224
- if (analysis) {
225
- console.log(`CodeYam: Loaded analysis ${filePath}:${entityName}`);
226
- return { key: keyString, analysis };
227
- } else {
223
+ // Load analyses for current batch (concurrency-limited to avoid exhausting DB connections)
224
+ const results = await mapWithConcurrency(
225
+ currentBatch,
226
+ async (keyString) => {
227
+ const [filePath, entityName] = keyString.split(':');
228
+
229
+ // Find the file ID for this file path - use fileStore for O(1) lookup when available
230
+ const file = fileStore
231
+ ? fileStore.getByPath(filePath)
232
+ : project.files.find((f) => f.path === filePath);
233
+ if (!file) {
228
234
  console.log(
229
- `CodeYam Warning: Analysis not found: ${filePath}:${entityName}`,
235
+ `CodeYam Warning: File not found in project: ${filePath} for key ${keyString}`,
230
236
  );
231
237
  return null;
232
238
  }
233
- } catch (error) {
234
- console.log(
235
- `CodeYam Error loading analysis ${filePath}:${entityName}:`,
236
- error,
237
- );
238
- return null;
239
- }
240
- });
241
239
 
242
- const results = await Promise.all(loadPromises);
240
+ try {
241
+ const analysis = await loadAnalysis({
242
+ projectId: project.id,
243
+ fileId: file.id,
244
+ entityName,
245
+ includeScenarios: isFirstBatch, // Only include scenarios for the root analyses
246
+ });
247
+
248
+ if (analysis) {
249
+ console.log(`CodeYam: Loaded analysis ${filePath}:${entityName}`);
250
+ return { key: keyString, analysis };
251
+ } else {
252
+ console.log(
253
+ `CodeYam Warning: Analysis not found: ${filePath}:${entityName}`,
254
+ );
255
+ return null;
256
+ }
257
+ } catch (error) {
258
+ console.log(
259
+ `CodeYam Error loading analysis ${filePath}:${entityName}:`,
260
+ error,
261
+ );
262
+ return null;
263
+ }
264
+ },
265
+ DB_CONCURRENCY,
266
+ );
243
267
 
244
268
  // Process loaded analyses and find new dependencies
245
269
  for (const result of results) {
@@ -35,7 +35,10 @@ export default class AwsCaptureTaskRunner implements CaptureTaskRunner {
35
35
  private sqs: SQSClient;
36
36
  private queueInfo: QueueInfo;
37
37
  private taskArns: string[];
38
- private batchCompletedCallback?: (analysisIds: string[]) => void;
38
+ private batchCompletedCallback?: (
39
+ analysisIds: string[],
40
+ success: boolean,
41
+ ) => void;
39
42
  private controlPollingInterval?: NodeJS.Timeout;
40
43
  private lastTaskHealthCheck = Date.now();
41
44
  private isCleanedUp = false;
@@ -213,7 +216,9 @@ export default class AwsCaptureTaskRunner implements CaptureTaskRunner {
213
216
  }
214
217
  }
215
218
 
216
- onBatchCompleted(callback: (analysisIds: string[]) => void): void {
219
+ onBatchCompleted(
220
+ callback: (analysisIds: string[], success: boolean) => void,
221
+ ): void {
217
222
  this.batchCompletedCallback = callback;
218
223
  }
219
224
 
@@ -255,9 +260,12 @@ export default class AwsCaptureTaskRunner implements CaptureTaskRunner {
255
260
  body.analysisIds &&
256
261
  Array.isArray(body.analysisIds)
257
262
  ) {
258
- // Notify callback
263
+ // Notify callback with success status (default false for backwards compatibility)
259
264
  if (this.batchCompletedCallback) {
260
- this.batchCompletedCallback(body.analysisIds);
265
+ this.batchCompletedCallback(
266
+ body.analysisIds,
267
+ body.success ?? false,
268
+ );
261
269
  }
262
270
  }
263
271
 
@@ -49,7 +49,10 @@ export interface SequentialCaptureTaskRunnerContext {
49
49
 
50
50
  export default class SequentialCaptureTaskRunner implements CaptureTaskRunner {
51
51
  private queue: string[][] = [];
52
- private batchCompletedCallback?: (analysisIds: string[]) => void;
52
+ private batchCompletedCallback?: (
53
+ analysisIds: string[],
54
+ success: boolean,
55
+ ) => void;
53
56
  private isProcessing = false;
54
57
  private isCleanedUp = false;
55
58
  private processingLoop: Promise<void> | null = null;
@@ -197,15 +200,15 @@ export default class SequentialCaptureTaskRunner implements CaptureTaskRunner {
197
200
  try {
198
201
  await this.processBatch(batch);
199
202
 
200
- // Notify callback of completion
203
+ // Notify callback of successful completion
201
204
  if (this.batchCompletedCallback) {
202
- this.batchCompletedCallback(batch);
205
+ this.batchCompletedCallback(batch, true);
203
206
  }
204
207
  } catch (error) {
205
208
  console.error('CodeYam: Error processing batch:', error);
206
- // Still notify callback so orchestration can track failures
209
+ // Notify callback of failure so orchestration can track retries
207
210
  if (this.batchCompletedCallback) {
208
- this.batchCompletedCallback(batch);
211
+ this.batchCompletedCallback(batch, false);
209
212
  }
210
213
  } finally {
211
214
  this.isProcessing = false;
@@ -399,7 +402,9 @@ export default class SequentialCaptureTaskRunner implements CaptureTaskRunner {
399
402
  console.log('CodeYam: Sequential task runner cleanup complete');
400
403
  }
401
404
 
402
- onBatchCompleted(callback: (analysisIds: string[]) => void): void {
405
+ onBatchCompleted(
406
+ callback: (analysisIds: string[], success: boolean) => void,
407
+ ): void {
403
408
  this.batchCompletedCallback = callback;
404
409
  }
405
410
  }
@@ -115,7 +115,9 @@ export interface CaptureTaskRunner {
115
115
  * Register callback for when workers complete batch processing.
116
116
  *
117
117
  * Critical for retry logic and progress tracking in orchestration.
118
- * Callback receives the analysis IDs that were completed.
118
+ * Callback receives the analysis IDs and whether the batch succeeded.
119
119
  */
120
- onBatchCompleted(callback: (analysisIds: string[]) => void): void;
120
+ onBatchCompleted(
121
+ callback: (analysisIds: string[], success: boolean) => void,
122
+ ): void;
121
123
  }
@@ -99,15 +99,20 @@ export default async function orchestrateCapture({
99
99
  const attemptCount = new Map<string, number>();
100
100
  const maxAttempts = 2;
101
101
 
102
+ // Track which analyses had a worker report success — only these can be "captured"
103
+ const confirmedSuccessAnalyses = new Set<string>();
104
+
102
105
  // Register batch completion callback with task runner
103
- taskRunner.onBatchCompleted((analysisIds: string[]) => {
106
+ taskRunner.onBatchCompleted((analysisIds: string[], success: boolean) => {
104
107
  console.log(
105
- `CodeYam Capture: Received batch completion for ${analysisIds.length} analyses: ${analysisIds.join(', ')}`,
108
+ `CodeYam Capture: Received batch completion (success=${success}) for ${analysisIds.length} analyses: ${analysisIds.join(', ')}`,
106
109
  );
107
- // Remove from inFlight and increment attempt count for each analysis
108
110
  for (const analysisId of analysisIds) {
109
111
  inFlight.delete(analysisId);
110
112
  attemptCount.set(analysisId, (attemptCount.get(analysisId) || 0) + 1);
113
+ if (success) {
114
+ confirmedSuccessAnalyses.add(analysisId);
115
+ }
111
116
  }
112
117
  });
113
118
 
@@ -195,9 +200,13 @@ export default async function orchestrateCapture({
195
200
  knownAnalyses.add(id);
196
201
  }
197
202
 
198
- // an analysis we've seen, but is no longer "ready to be captured", is captured!
203
+ // An analysis is "captured" only if:
204
+ // 1. A worker reported success for its batch (in confirmedSuccessAnalyses)
205
+ // 2. It no longer appears in the ready-to-be-captured list (DB confirms)
206
+ // This prevents transient empty DB results from inflating the captured count.
199
207
  const capturedAnalysisIds = Array.from(knownAnalyses).filter(
200
- (id) => !allReadyAnalysisIds.includes(id),
208
+ (id) =>
209
+ confirmedSuccessAnalyses.has(id) && !allReadyAnalysisIds.includes(id),
201
210
  );
202
211
 
203
212
  // Remove captured analyses from inFlight tracking
@@ -397,7 +406,9 @@ export default async function orchestrateCapture({
397
406
  // check if all enqueued analyses have been either captured or abandoned
398
407
  const allAnalysesSettled = Array.from(enqueuedAnalyses).every(
399
408
  (id) => {
400
- const captured = !allReadyAnalysisIds.includes(id);
409
+ const captured =
410
+ confirmedSuccessAnalyses.has(id) &&
411
+ !allReadyAnalysisIds.includes(id);
401
412
  const abandoned = (attemptCount.get(id) || 0) >= maxAttempts;
402
413
  return captured || abandoned;
403
414
  },
@@ -437,5 +448,33 @@ export default async function orchestrateCapture({
437
448
  } finally {
438
449
  // Always clean up task runner resources in finally block
439
450
  await taskRunner.cleanup();
451
+
452
+ const trackingCommit = metadataCommit ?? commit;
453
+ if (trackingCommit?.id) {
454
+ const captureCompletedAt = new Date().toISOString();
455
+
456
+ await updateCommitMetadata({
457
+ commitId: trackingCommit.id,
458
+ runStatusUpdate: {
459
+ captureCompletedAt,
460
+ capturePid: undefined,
461
+ },
462
+ // completedAt = max(analysisCompletedAt, captureCompletedAt)
463
+ // Normally capture finishes after analysis, but using max means illogical
464
+ // orderings leave a detectable signal (completedAt !== captureCompletedAt).
465
+ updateCallback(metadata) {
466
+ const run = metadata.currentRun!;
467
+ run.completedAt =
468
+ run.analysisCompletedAt &&
469
+ run.analysisCompletedAt > captureCompletedAt
470
+ ? run.analysisCompletedAt
471
+ : captureCompletedAt;
472
+ },
473
+ }).catch((error) => {
474
+ console.log(
475
+ `Warning: Failed to update capture completion metadata: ${error}`,
476
+ );
477
+ });
478
+ }
440
479
  }
441
480
  }
@@ -17,7 +17,8 @@ import { startScenarioCapture } from './startScenarioCapture';
17
17
  import { createController } from './controller/startController';
18
18
  import { awsLog, awsLogDebugLevel } from '~codeyam/utils';
19
19
  import * as v8 from 'v8';
20
- import { initializeAIServiceMode } from '~codeyam/ai';
20
+ import * as os from 'os';
21
+ import { initializeAIServiceMode, destroyWorkerPool } from '~codeyam/ai';
21
22
  import runAnalysis, { EnvConfig, SharedContext } from './runAnalysis';
22
23
  import {
23
24
  loadOrCreateCommit,
@@ -119,28 +120,31 @@ async function main({
119
120
  // and attempted to access project/commit/branch data before it was loaded.
120
121
  const sharedContext = await loadSharedContext(envConfig);
121
122
 
122
- // Heap monitoring: pulse every 1s, log every 30s when normal, warn every 1s when high
123
+ // Memory monitoring: tracks both V8 heap and RSS (which includes worker threads)
124
+ const containerMemoryMB = process.env.ECS_CONTAINER_MEMORY_MB
125
+ ? parseInt(process.env.ECS_CONTAINER_MEMORY_MB, 10)
126
+ : Math.round(os.totalmem() / 1024 / 1024);
123
127
  let lastLogTime = 0;
124
128
  setInterval(() => {
125
129
  const mem = process.memoryUsage();
126
130
  const heap = v8.getHeapStatistics();
127
- const usagePercent = (mem.heapUsed / heap.heap_size_limit) * 100;
131
+ const heapMB = Math.round(mem.heapUsed / 1024 / 1024);
132
+ const rssMB = Math.round(mem.rss / 1024 / 1024);
133
+ const heapLimitMB = Math.round(heap.heap_size_limit / 1024 / 1024);
134
+ const rssPercent = (rssMB / containerMemoryMB) * 100;
128
135
  const now = Date.now();
129
136
 
130
- if (usagePercent >= 80) {
131
- // High usage: warn every second
137
+ if (rssPercent >= 80) {
132
138
  console.warn(
133
- `CodeYam Heap Warning: ${Math.round(mem.heapUsed / 1024 / 1024)}MB used / ${Math.round(heap.heap_size_limit / 1024 / 1024)}MB limit (${Math.round(usagePercent)}%) ⚠️ HIGH USAGE`,
139
+ `CodeYam Memory Warning: RSS ${rssMB}MB/${containerMemoryMB}MB (${Math.round(rssPercent)}%), heap ${heapMB}MB/${heapLimitMB}MB ⚠️ HIGH`,
134
140
  );
135
- } else if (usagePercent >= 50 && now - lastLogTime >= 5000) {
136
- // Elevated usage: log every 5 seconds
141
+ } else if (rssPercent >= 50 && now - lastLogTime >= 5000) {
137
142
  console.log(
138
- `CodeYam Heap Notice: ${Math.round(mem.heapUsed / 1024 / 1024)}MB used / ${Math.round(heap.heap_size_limit / 1024 / 1024)}MB limit (${Math.round(usagePercent)}%) ⚠️ Elevated`,
143
+ `CodeYam Memory Notice: RSS ${rssMB}MB/${containerMemoryMB}MB (${Math.round(rssPercent)}%), heap ${heapMB}MB/${heapLimitMB}MB ⚠️ Elevated`,
139
144
  );
140
145
  } else if (now - lastLogTime >= 30000) {
141
- // Normal usage: log every 30 seconds
142
146
  console.log(
143
- `CodeYam Heap Stats: ${Math.round(mem.heapUsed / 1024 / 1024)}MB used / ${Math.round(heap.heap_size_limit / 1024 / 1024)}MB limit (${Math.round(usagePercent)}%) 📊 OK`,
147
+ `CodeYam Memory Stats: RSS ${rssMB}MB/${containerMemoryMB}MB (${Math.round(rssPercent)}%), heap ${heapMB}MB/${heapLimitMB}MB 📊 OK`,
144
148
  );
145
149
  }
146
150
 
@@ -187,6 +191,11 @@ async function main({
187
191
  analyzerPid: undefined,
188
192
  capturePid: process.pid,
189
193
  },
194
+ updateCallback(metadata) {
195
+ if (metadata.currentRun?.captureCompletedAt) {
196
+ metadata.currentRun.completedAt = new Date().toISOString();
197
+ }
198
+ },
190
199
  }).catch((error) => {
191
200
  awsLog(`Warning: Failed to update commit metadata: ${error}`);
192
201
  });
@@ -219,6 +228,10 @@ async function main({
219
228
  }
220
229
  awsLog('CodeYam: Analysis producing, starting orchestration...');
221
230
 
231
+ // Worker pool is no longer needed after data structure prep phase.
232
+ // Freeing it reclaims ~2GB before capture workers ramp up.
233
+ await destroyWorkerPool();
234
+
222
235
  // Create task runner based on orchestration mode
223
236
  let taskRunner;
224
237
 
@@ -229,6 +242,17 @@ async function main({
229
242
  framework: framework,
230
243
  packageManager: packageManager,
231
244
  });
245
+
246
+ const captureCommit =
247
+ sharedContext.commit ?? sharedContext.branchCommit;
248
+ if (captureCommit) {
249
+ await updateCommitMetadata({
250
+ commitId: captureCommit.id,
251
+ runStatusUpdate: {
252
+ captureTaskArns: taskRunner.getTaskArns(),
253
+ },
254
+ });
255
+ }
232
256
  } else if (orchestrateCapture === 'local-sequential') {
233
257
  taskRunner = await SequentialCaptureTaskRunner.create(
234
258
  {
@@ -192,6 +192,36 @@ const safeString = (s: string, level: number) => {
192
192
  return s?.replace ? s.replace(/"/g, "'").replace(/\n/g, '\\n') : s;
193
193
  };
194
194
 
195
+ /**
196
+ * Clean up malformed LLM-generated function values.
197
+ * The LLM sometimes generates function values with an invalid "(function)" prefix like:
198
+ * - "(function)() => {}"
199
+ * - "(function)(event) => {}"
200
+ * - "(function)(id) => {}"
201
+ *
202
+ * This strips the prefix and adds TypeScript `any` type annotations to parameters.
203
+ * Returns null if the value doesn't match the malformed pattern.
204
+ */
205
+ const cleanMalformedFunctionValue = (value: string): string | null => {
206
+ // Match "(function)" followed by optional params in parens, then "=>"
207
+ const match = value.match(/^\(function\)(\([^)]*\))\s*=>\s*(.*)$/);
208
+ if (!match) return null;
209
+
210
+ const [, paramsWithParens, body] = match;
211
+
212
+ // Extract parameter names and add `: any` type annotation
213
+ // e.g., "(event)" -> "(event: any)", "()" -> "()"
214
+ const params = paramsWithParens.slice(1, -1).trim(); // Remove outer parens
215
+ const typedParams = params
216
+ ? params
217
+ .split(',')
218
+ .map((p) => `${p.trim()}: any`)
219
+ .join(', ')
220
+ : '';
221
+
222
+ return `(${typedParams}) => ${body}`;
223
+ };
224
+
195
225
  /**
196
226
  * Check if a mock key's schema indicates it should be instantiated as a Map.
197
227
  * A Map is indicated by:
@@ -310,6 +340,38 @@ function extractAllKeys(obj: JsonTypeDefinition | undefined): string[] {
310
340
  */
311
341
  const BARE_TYPE_MARKERS = ['function', 'async-function'];
312
342
 
343
+ /**
344
+ * Check if a string is a TypeScript arrow function type annotation rather than
345
+ * a valid JavaScript arrow function expression.
346
+ *
347
+ * TypeScript arrow types look like function expressions (they contain '=>') but
348
+ * their "body" is a type name, not a JS expression:
349
+ * - "() => void"
350
+ * - "(event: MouseEvent) => void"
351
+ * - "() => string"
352
+ * - "() => Promise<void>"
353
+ * - "(id: string, name: string) => boolean"
354
+ *
355
+ * Valid JS arrow functions have actual expression bodies:
356
+ * - "() => {}"
357
+ * - "() => 'hello'"
358
+ * - "(x) => x + 1"
359
+ * - "() => { console.log('hi'); }"
360
+ */
361
+ const ARROW_TYPE_RETURN_TYPES =
362
+ /^(void|string|number|boolean|any|unknown|never|null|undefined|object|Date|Promise<\w+>)$/i;
363
+
364
+ const isArrowFunctionTypeAnnotation = (value: string): boolean => {
365
+ const arrowIndex = value.indexOf('=>');
366
+ if (arrowIndex === -1) return false;
367
+
368
+ const body = value.slice(arrowIndex + 2).trim();
369
+
370
+ // A real JS function would have {}, an expression, a string literal, etc.
371
+ // A type annotation has a bare type keyword as the "body".
372
+ return ARROW_TYPE_RETURN_TYPES.test(body);
373
+ };
374
+
313
375
  /**
314
376
  * Check if a value is a bare function type marker that should be filtered out.
315
377
  * These markers indicate the LLM detected a function but couldn't generate meaningful mock data.
@@ -336,6 +398,59 @@ const isBareTypeMarker = (value: unknown): boolean => {
336
398
  return false;
337
399
  };
338
400
 
401
+ /**
402
+ * Escape newlines that appear inside string literals within a code string,
403
+ * while preserving structural newlines (those between statements/lines of code).
404
+ *
405
+ * This handles cases where LLM generates function bodies like:
406
+ * - "() => { console.log('line1\nline2'); }" - escape the \n inside the string
407
+ * - "() => {\n console.log('x');\n}" - preserve structural \n between statements
408
+ * - "() => Promise.resolve('a\nb')" - escape the \n inside the string argument
409
+ *
410
+ * The algorithm tracks whether we're inside a string literal (single, double, or
411
+ * backtick quotes) and only escapes newlines that appear within quotes.
412
+ */
413
+ const escapeNewlinesInStringLiterals = (code: string): string => {
414
+ let result = '';
415
+ let inString = false;
416
+ let stringChar = ''; // The quote character that started the current string
417
+
418
+ for (let i = 0; i < code.length; i++) {
419
+ const char = code[i];
420
+ const prevChar = i > 0 ? code[i - 1] : '';
421
+
422
+ // Check for string literal boundaries (single, double, or backtick quotes)
423
+ // Skip escaped quotes (preceded by backslash)
424
+ if ((char === '"' || char === "'" || char === '`') && prevChar !== '\\') {
425
+ if (!inString) {
426
+ // Starting a string literal
427
+ inString = true;
428
+ stringChar = char;
429
+ } else if (char === stringChar) {
430
+ // Ending the current string literal
431
+ inString = false;
432
+ stringChar = '';
433
+ }
434
+ // If char is a different quote type while in a string, it's just a character
435
+ }
436
+
437
+ // Escape newlines only when inside a string literal
438
+ if (char === '\n') {
439
+ if (inString) {
440
+ // Inside a string literal - escape the newline
441
+ result += '\\n';
442
+ } else {
443
+ // Outside string - keep the structural newline
444
+ result += char;
445
+ }
446
+ } else {
447
+ result += char;
448
+ }
449
+ }
450
+
451
+ return result;
452
+ };
453
+
339
454
  /**
340
455
  * Normalize mock data by merging entries that have the same normalized function name.
341
456
  * e.g., "useLastLogLine(projectSlug, !!simulatingEntitySha)" and
@@ -734,13 +849,19 @@ const jsonToCode = (
734
849
  stringValue.startsWith('Promise.') ||
735
850
  stringValue.startsWith('new Promise');
736
851
 
852
+ // Check if the string contains newlines (potential issue for string literals)
853
+ const hasNewlines = stringValue.includes('\n');
854
+
737
855
  // Handle special type indicators that need transformation
738
856
  let outputValue: string;
739
857
  if (stringValue === 'promise' || looksLikePromise) {
740
858
  // The key is a function call (e.g., "revalidate()"), so output a function
741
859
  // that returns a Promise, not the Promise itself
860
+ // Important: Escape newlines inside Promise expressions to avoid
861
+ // "unterminated string literal" errors when the Promise contains
862
+ // multi-line string arguments like Promise.resolve('line1\nline2')
742
863
  const promiseExpr = looksLikePromise
743
- ? stringValue
864
+ ? stringValue.replace(/\n/g, '\\n')
744
865
  : 'Promise.resolve()';
745
866
  outputValue = `() => ${promiseExpr}`;
746
867
  console.log(
@@ -752,10 +873,49 @@ const jsonToCode = (
752
873
  `CodeYam: Nested func transform (string->function): "${key}" -> "${funcName}": () => {}`,
753
874
  );
754
875
  } else if (looksLikeFunction) {
755
- outputValue = stringValue;
756
- console.log(
757
- `CodeYam: Nested func transform (string): "${key}" -> "${funcName}": ${stringValue.substring(0, 30)}...`,
758
- );
876
+ // Check for "[native code]" in function body — this is what
877
+ // Function.prototype.toString() returns for built-in functions.
878
+ // The LLM sometimes generates "function () { [native code] }" which
879
+ // is not valid JavaScript (the "[" is parsed as array destructuring).
880
+ if (stringValue.includes('[native code]')) {
881
+ outputValue = '() => {}';
882
+ console.log(
883
+ `CodeYam: Nested func transform (native-code->noop): "${key}" -> "${funcName}": () => {}`,
884
+ );
885
+ } else if (cleanMalformedFunctionValue(stringValue)) {
886
+ // Check for malformed LLM-generated function values like "(function)() => {}"
887
+ // These have an invalid "(function)" prefix that must be stripped
888
+ outputValue = cleanMalformedFunctionValue(stringValue)!;
889
+ console.log(
890
+ `CodeYam: Nested func transform (malformed->clean): "${key}" -> "${funcName}": ${outputValue}`,
891
+ );
892
+ } else if (isArrowFunctionTypeAnnotation(stringValue)) {
893
+ // TypeScript arrow function type annotations like "() => void",
894
+ // "(event: MouseEvent) => void", "() => Promise<void>" contain '=>'
895
+ // so they pass the looksLikeFunction check, but they are TYPE syntax,
896
+ // not valid JavaScript expressions. Convert to a no-op function.
897
+ outputValue = '() => {}';
898
+ console.log(
899
+ `CodeYam: Nested func transform (type-annotation->function): "${key}" -> "${funcName}": () => {}`,
900
+ );
901
+ } else {
902
+ // Handle newlines in function expressions:
903
+ // - Newlines inside string literals must be escaped to avoid
904
+ // "unterminated string literal" errors
905
+ // - Structural newlines (between statements) should be kept as-is
906
+ // to produce valid multi-line JavaScript
907
+ //
908
+ // We escape ONLY newlines that appear inside string literals (single,
909
+ // double, or template quotes). Structural newlines are preserved.
910
+ if (hasNewlines) {
911
+ outputValue = escapeNewlinesInStringLiterals(stringValue);
912
+ } else {
913
+ outputValue = stringValue;
914
+ }
915
+ console.log(
916
+ `CodeYam: Nested func transform (string): "${key}" -> "${funcName}": ${stringValue.substring(0, 30)}...`,
917
+ );
918
+ }
759
919
  } else {
760
920
  // Plain string value - must be quoted
761
921
  outputValue = `"${safeString(stringValue, level)}"`;
@@ -783,9 +943,22 @@ const jsonToCode = (
783
943
  if (isBareTypeMarker(stringValue)) {
784
944
  continue;
785
945
  }
786
- keyStrings.push(
787
- `${levelSpacing}"${safeString(key, level)}": "${safeString(stringValue, level)}"`,
788
- );
946
+ // Check for malformed LLM-generated function values like "(function)(id) => {}"
947
+ // These can appear on plain keys (e.g., "closeToast") and need to be output as
948
+ // actual functions, not quoted strings
949
+ const cleanedPlainKeyFn = cleanMalformedFunctionValue(stringValue);
950
+ if (cleanedPlainKeyFn) {
951
+ keyStrings.push(
952
+ `${levelSpacing}"${safeString(key, level)}": ${cleanedPlainKeyFn}`,
953
+ );
954
+ console.log(
955
+ `CodeYam: Plain key func transform (malformed->clean): "${key}": ${cleanedPlainKeyFn}`,
956
+ );
957
+ } else {
958
+ keyStrings.push(
959
+ `${levelSpacing}"${safeString(key, level)}": "${safeString(stringValue, level)}"`,
960
+ );
961
+ }
789
962
  }
790
963
  } else {
791
964
  // Skip plain keys that have function-call versions (at the same nesting level where